Commit 35af89eb authored by David Gibson's avatar David Gibson Committed by Paul Mackerras

[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: default avatarDavid Gibson <dwg@au1.ibm.com>
Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
parent f79e083c
...@@ -33,13 +33,9 @@ static int ft_setprop(const void *phandle, const char *propname, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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 { ...@@ -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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment