diff options
author | David Gibson <david@gibson.dropbear.id.au> | 2006-11-20 19:37:37 -0500 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2006-12-04 04:39:34 -0500 |
commit | 35af89eb491a0741005e474626053266e6e635b7 (patch) | |
tree | 6813c0457dedacd221a2014bda37d0c892c328cd /arch | |
parent | f79e083c2fab601a1c382282344f5a251557dbac (diff) |
[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>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/powerpc/boot/flatdevtree_misc.c | 9 | ||||
-rw-r--r-- | arch/powerpc/boot/main.c | 15 | ||||
-rw-r--r-- | arch/powerpc/boot/ops.h | 3 |
3 files changed, 14 insertions, 13 deletions
diff --git a/arch/powerpc/boot/flatdevtree_misc.c b/arch/powerpc/boot/flatdevtree_misc.c index c7f9adbf827d..04da38fa477f 100644 --- a/arch/powerpc/boot/flatdevtree_misc.c +++ b/arch/powerpc/boot/flatdevtree_misc.c | |||
@@ -33,13 +33,9 @@ static int ft_setprop(const void *phandle, const char *propname, | |||
33 | return ft_set_prop(&cxt, phandle, propname, buf, buflen); | 33 | return ft_set_prop(&cxt, phandle, propname, buf, buflen); |
34 | } | 34 | } |
35 | 35 | ||
36 | static void ft_pack(void) | 36 | static unsigned long ft_finalize(void) |
37 | { | 37 | { |
38 | ft_end_tree(&cxt); | 38 | ft_end_tree(&cxt); |
39 | } | ||
40 | |||
41 | static unsigned long ft_addr(void) | ||
42 | { | ||
43 | return (unsigned long)cxt.bph; | 39 | return (unsigned long)cxt.bph; |
44 | } | 40 | } |
45 | 41 | ||
@@ -48,8 +44,7 @@ int ft_init(void *dt_blob, unsigned int max_size, unsigned int max_find_device) | |||
48 | dt_ops.finddevice = ft_finddevice; | 44 | dt_ops.finddevice = ft_finddevice; |
49 | dt_ops.getprop = ft_getprop; | 45 | dt_ops.getprop = ft_getprop; |
50 | dt_ops.setprop = ft_setprop; | 46 | dt_ops.setprop = ft_setprop; |
51 | dt_ops.ft_pack = ft_pack; | 47 | dt_ops.finalize = ft_finalize; |
52 | dt_ops.ft_addr = ft_addr; | ||
53 | 48 | ||
54 | return ft_open(&cxt, dt_blob, max_size, max_find_device, | 49 | return ft_open(&cxt, dt_blob, max_size, max_find_device, |
55 | platform_ops.realloc); | 50 | platform_ops.realloc); |
diff --git a/arch/powerpc/boot/main.c b/arch/powerpc/boot/main.c index 630a453e16fa..6f6b50d238b6 100644 --- a/arch/powerpc/boot/main.c +++ b/arch/powerpc/boot/main.c | |||
@@ -298,6 +298,7 @@ void start(unsigned long a1, unsigned long a2, void *promptr, void *sp) | |||
298 | { | 298 | { |
299 | kernel_entry_t kentry; | 299 | kernel_entry_t kentry; |
300 | char cmdline[COMMAND_LINE_SIZE]; | 300 | char cmdline[COMMAND_LINE_SIZE]; |
301 | unsigned long ft_addr = 0; | ||
301 | 302 | ||
302 | memset(__bss_start, 0, _end - __bss_start); | 303 | memset(__bss_start, 0, _end - __bss_start); |
303 | memset(&platform_ops, 0, sizeof(platform_ops)); | 304 | memset(&platform_ops, 0, sizeof(platform_ops)); |
@@ -328,14 +329,20 @@ void start(unsigned long a1, unsigned long a2, void *promptr, void *sp) | |||
328 | set_cmdline(cmdline); | 329 | set_cmdline(cmdline); |
329 | } | 330 | } |
330 | 331 | ||
332 | printf("Finalizing device tree..."); | ||
333 | if (dt_ops.finalize) | ||
334 | ft_addr = dt_ops.finalize(); | ||
335 | if (ft_addr) | ||
336 | printf(" flat tree at 0x%lx\n\r", ft_addr); | ||
337 | else | ||
338 | printf(" using OF tree (promptr=%p)\n\r", promptr); | ||
339 | |||
331 | if (console_ops.close) | 340 | if (console_ops.close) |
332 | console_ops.close(); | 341 | console_ops.close(); |
333 | 342 | ||
334 | kentry = (kernel_entry_t) vmlinux.addr; | 343 | kentry = (kernel_entry_t) vmlinux.addr; |
335 | if (_dtb_end > _dtb_start) { | 344 | if (ft_addr) |
336 | dt_ops.ft_pack(); | 345 | kentry(ft_addr, 0, NULL); |
337 | kentry(dt_ops.ft_addr(), 0, NULL); | ||
338 | } | ||
339 | else | 346 | else |
340 | /* XXX initrd addr/size should be passed in properties */ | 347 | /* XXX initrd addr/size should be passed in properties */ |
341 | kentry(initrd.addr, initrd.size, promptr); | 348 | kentry(initrd.addr, initrd.size, promptr); |
diff --git a/arch/powerpc/boot/ops.h b/arch/powerpc/boot/ops.h index 59832fb0f276..8abb6516bb7c 100644 --- a/arch/powerpc/boot/ops.h +++ b/arch/powerpc/boot/ops.h | |||
@@ -35,8 +35,7 @@ struct dt_ops { | |||
35 | const int buflen); | 35 | const int buflen); |
36 | int (*setprop)(const void *phandle, const char *name, | 36 | int (*setprop)(const void *phandle, const char *name, |
37 | const void *buf, const int buflen); | 37 | const void *buf, const int buflen); |
38 | void (*ft_pack)(void); | 38 | unsigned long (*finalize)(void); |
39 | unsigned long (*ft_addr)(void); | ||
40 | }; | 39 | }; |
41 | extern struct dt_ops dt_ops; | 40 | extern struct dt_ops dt_ops; |
42 | 41 | ||