[POWERPC] Cleanup zImage handling of kernel entry with flat device tree
This makes 2 changes to clean up the flat device tree handling logic in the zImage wrapper. First, there were two callbacks from the dt_ops structure used for producing a final flat tree to pass to the kerne: dt_ops.ft_pack() which packed the flat tree (possibly a no-op) and dt_ops.ft_addr() which retreived the address of the final blob. Since they were only ever called together, this patch combines the two into a single new callback, dt_ops.finalize(). This new callback does whatever platform-dependent things are necessary to produce a final flat device tree blob, and returns the blob's addres. Second, the current logic calls the kernel with a flat device tree if one is build into the zImage wrapper, otherwise it boots the kernel with a PROM pointer, expecting the kernel to copy the OF device tree itself. This approach precludes the possibility of the platform wrapper code building a flat device tree from whatever platform-specific information firmware provides. Thus, this patch takes the more sensible approach of invoking the kernel with a flat tree if the dt_ops.finalize callback provides one (by whatever means). So, the dt_ops.finalize callback can be NULL, or can be a function which returns NULL. In either case, the zImage wrapper logic assumes that this is a platform with OF and invokes the kernel accordingly. Signed-off-by: David Gibson <dwg@au1.ibm.com> Signed-off-by: Paul Mackerras <paulus@samba.org>
This commit is contained in:
committed by
Paul Mackerras
parent
f79e083c2f
commit
35af89eb49
@@ -33,13 +33,9 @@ static int ft_setprop(const void *phandle, const char *propname,
|
|||||||
return ft_set_prop(&cxt, phandle, propname, buf, buflen);
|
return ft_set_prop(&cxt, phandle, propname, buf, buflen);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ft_pack(void)
|
static unsigned long ft_finalize(void)
|
||||||
{
|
{
|
||||||
ft_end_tree(&cxt);
|
ft_end_tree(&cxt);
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned long ft_addr(void)
|
|
||||||
{
|
|
||||||
return (unsigned long)cxt.bph;
|
return (unsigned long)cxt.bph;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,8 +44,7 @@ int ft_init(void *dt_blob, unsigned int max_size, unsigned int max_find_device)
|
|||||||
dt_ops.finddevice = ft_finddevice;
|
dt_ops.finddevice = ft_finddevice;
|
||||||
dt_ops.getprop = ft_getprop;
|
dt_ops.getprop = ft_getprop;
|
||||||
dt_ops.setprop = ft_setprop;
|
dt_ops.setprop = ft_setprop;
|
||||||
dt_ops.ft_pack = ft_pack;
|
dt_ops.finalize = ft_finalize;
|
||||||
dt_ops.ft_addr = ft_addr;
|
|
||||||
|
|
||||||
return ft_open(&cxt, dt_blob, max_size, max_find_device,
|
return ft_open(&cxt, dt_blob, max_size, max_find_device,
|
||||||
platform_ops.realloc);
|
platform_ops.realloc);
|
||||||
|
@@ -298,6 +298,7 @@ void start(unsigned long a1, unsigned long a2, void *promptr, void *sp)
|
|||||||
{
|
{
|
||||||
kernel_entry_t kentry;
|
kernel_entry_t kentry;
|
||||||
char cmdline[COMMAND_LINE_SIZE];
|
char cmdline[COMMAND_LINE_SIZE];
|
||||||
|
unsigned long ft_addr = 0;
|
||||||
|
|
||||||
memset(__bss_start, 0, _end - __bss_start);
|
memset(__bss_start, 0, _end - __bss_start);
|
||||||
memset(&platform_ops, 0, sizeof(platform_ops));
|
memset(&platform_ops, 0, sizeof(platform_ops));
|
||||||
@@ -328,14 +329,20 @@ void start(unsigned long a1, unsigned long a2, void *promptr, void *sp)
|
|||||||
set_cmdline(cmdline);
|
set_cmdline(cmdline);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printf("Finalizing device tree...");
|
||||||
|
if (dt_ops.finalize)
|
||||||
|
ft_addr = dt_ops.finalize();
|
||||||
|
if (ft_addr)
|
||||||
|
printf(" flat tree at 0x%lx\n\r", ft_addr);
|
||||||
|
else
|
||||||
|
printf(" using OF tree (promptr=%p)\n\r", promptr);
|
||||||
|
|
||||||
if (console_ops.close)
|
if (console_ops.close)
|
||||||
console_ops.close();
|
console_ops.close();
|
||||||
|
|
||||||
kentry = (kernel_entry_t) vmlinux.addr;
|
kentry = (kernel_entry_t) vmlinux.addr;
|
||||||
if (_dtb_end > _dtb_start) {
|
if (ft_addr)
|
||||||
dt_ops.ft_pack();
|
kentry(ft_addr, 0, NULL);
|
||||||
kentry(dt_ops.ft_addr(), 0, NULL);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
/* XXX initrd addr/size should be passed in properties */
|
/* XXX initrd addr/size should be passed in properties */
|
||||||
kentry(initrd.addr, initrd.size, promptr);
|
kentry(initrd.addr, initrd.size, promptr);
|
||||||
|
@@ -35,8 +35,7 @@ struct dt_ops {
|
|||||||
const int buflen);
|
const int buflen);
|
||||||
int (*setprop)(const void *phandle, const char *name,
|
int (*setprop)(const void *phandle, const char *name,
|
||||||
const void *buf, const int buflen);
|
const void *buf, const int buflen);
|
||||||
void (*ft_pack)(void);
|
unsigned long (*finalize)(void);
|
||||||
unsigned long (*ft_addr)(void);
|
|
||||||
};
|
};
|
||||||
extern struct dt_ops dt_ops;
|
extern struct dt_ops dt_ops;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user