Commit a2dd5da77f2cc9fc9ff11ea6b699556254e94a6c
Committed by
Benjamin Herrenschmidt
1 parent
bbad3e50e8
Exists in
master
and in
13 other branches
powerpc: Rename duplicate COMMAND_LINE_SIZE define
We have two definitions of COMMAND_LINE_SIZE, one for the kernel and one for the boot wrapper. I assume this is so the boot wrapper can be self sufficient and not rely on kernel headers. Having two defines with the same name is confusing, I just updated the wrong one when trying to bump it. Make the boot wrapper define unique by calling it BOOT_COMMAND_LINE_SIZE. Signed-off-by: Anton Blanchard <anton@samba.org> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Showing 3 changed files with 7 additions and 7 deletions Inline Diff
arch/powerpc/boot/main.c
1 | /* | 1 | /* |
2 | * Copyright (C) Paul Mackerras 1997. | 2 | * Copyright (C) Paul Mackerras 1997. |
3 | * | 3 | * |
4 | * Updates for PPC64 by Todd Inglett, Dave Engebretsen & Peter Bergner. | 4 | * Updates for PPC64 by Todd Inglett, Dave Engebretsen & Peter Bergner. |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or | 6 | * This program is free software; you can redistribute it and/or |
7 | * modify it under the terms of the GNU General Public License | 7 | * modify it under the terms of the GNU General Public License |
8 | * as published by the Free Software Foundation; either version | 8 | * as published by the Free Software Foundation; either version |
9 | * 2 of the License, or (at your option) any later version. | 9 | * 2 of the License, or (at your option) any later version. |
10 | */ | 10 | */ |
11 | #include <stdarg.h> | 11 | #include <stdarg.h> |
12 | #include <stddef.h> | 12 | #include <stddef.h> |
13 | #include "elf.h" | 13 | #include "elf.h" |
14 | #include "page.h" | 14 | #include "page.h" |
15 | #include "string.h" | 15 | #include "string.h" |
16 | #include "stdio.h" | 16 | #include "stdio.h" |
17 | #include "ops.h" | 17 | #include "ops.h" |
18 | #include "gunzip_util.h" | 18 | #include "gunzip_util.h" |
19 | #include "reg.h" | 19 | #include "reg.h" |
20 | 20 | ||
21 | static struct gunzip_state gzstate; | 21 | static struct gunzip_state gzstate; |
22 | 22 | ||
23 | struct addr_range { | 23 | struct addr_range { |
24 | void *addr; | 24 | void *addr; |
25 | unsigned long size; | 25 | unsigned long size; |
26 | }; | 26 | }; |
27 | 27 | ||
28 | #undef DEBUG | 28 | #undef DEBUG |
29 | 29 | ||
30 | static struct addr_range prep_kernel(void) | 30 | static struct addr_range prep_kernel(void) |
31 | { | 31 | { |
32 | char elfheader[256]; | 32 | char elfheader[256]; |
33 | void *vmlinuz_addr = _vmlinux_start; | 33 | void *vmlinuz_addr = _vmlinux_start; |
34 | unsigned long vmlinuz_size = _vmlinux_end - _vmlinux_start; | 34 | unsigned long vmlinuz_size = _vmlinux_end - _vmlinux_start; |
35 | void *addr = 0; | 35 | void *addr = 0; |
36 | struct elf_info ei; | 36 | struct elf_info ei; |
37 | int len; | 37 | int len; |
38 | 38 | ||
39 | /* gunzip the ELF header of the kernel */ | 39 | /* gunzip the ELF header of the kernel */ |
40 | gunzip_start(&gzstate, vmlinuz_addr, vmlinuz_size); | 40 | gunzip_start(&gzstate, vmlinuz_addr, vmlinuz_size); |
41 | gunzip_exactly(&gzstate, elfheader, sizeof(elfheader)); | 41 | gunzip_exactly(&gzstate, elfheader, sizeof(elfheader)); |
42 | 42 | ||
43 | if (!parse_elf64(elfheader, &ei) && !parse_elf32(elfheader, &ei)) | 43 | if (!parse_elf64(elfheader, &ei) && !parse_elf32(elfheader, &ei)) |
44 | fatal("Error: not a valid PPC32 or PPC64 ELF file!\n\r"); | 44 | fatal("Error: not a valid PPC32 or PPC64 ELF file!\n\r"); |
45 | 45 | ||
46 | if (platform_ops.image_hdr) | 46 | if (platform_ops.image_hdr) |
47 | platform_ops.image_hdr(elfheader); | 47 | platform_ops.image_hdr(elfheader); |
48 | 48 | ||
49 | /* We need to alloc the memsize: gzip will expand the kernel | 49 | /* We need to alloc the memsize: gzip will expand the kernel |
50 | * text/data, then possible rubbish we don't care about. But | 50 | * text/data, then possible rubbish we don't care about. But |
51 | * the kernel bss must be claimed (it will be zero'd by the | 51 | * the kernel bss must be claimed (it will be zero'd by the |
52 | * kernel itself) | 52 | * kernel itself) |
53 | */ | 53 | */ |
54 | printf("Allocating 0x%lx bytes for kernel ...\n\r", ei.memsize); | 54 | printf("Allocating 0x%lx bytes for kernel ...\n\r", ei.memsize); |
55 | 55 | ||
56 | if (platform_ops.vmlinux_alloc) { | 56 | if (platform_ops.vmlinux_alloc) { |
57 | addr = platform_ops.vmlinux_alloc(ei.memsize); | 57 | addr = platform_ops.vmlinux_alloc(ei.memsize); |
58 | } else { | 58 | } else { |
59 | /* | 59 | /* |
60 | * Check if the kernel image (without bss) would overwrite the | 60 | * Check if the kernel image (without bss) would overwrite the |
61 | * bootwrapper. The device tree has been moved in fdt_init() | 61 | * bootwrapper. The device tree has been moved in fdt_init() |
62 | * to an area allocated with malloc() (somewhere past _end). | 62 | * to an area allocated with malloc() (somewhere past _end). |
63 | */ | 63 | */ |
64 | if ((unsigned long)_start < ei.loadsize) | 64 | if ((unsigned long)_start < ei.loadsize) |
65 | fatal("Insufficient memory for kernel at address 0!" | 65 | fatal("Insufficient memory for kernel at address 0!" |
66 | " (_start=%p, uncompressed size=%08lx)\n\r", | 66 | " (_start=%p, uncompressed size=%08lx)\n\r", |
67 | _start, ei.loadsize); | 67 | _start, ei.loadsize); |
68 | 68 | ||
69 | if ((unsigned long)_end < ei.memsize) | 69 | if ((unsigned long)_end < ei.memsize) |
70 | fatal("The final kernel image would overwrite the " | 70 | fatal("The final kernel image would overwrite the " |
71 | "device tree\n\r"); | 71 | "device tree\n\r"); |
72 | } | 72 | } |
73 | 73 | ||
74 | /* Finally, gunzip the kernel */ | 74 | /* Finally, gunzip the kernel */ |
75 | printf("gunzipping (0x%p <- 0x%p:0x%p)...", addr, | 75 | printf("gunzipping (0x%p <- 0x%p:0x%p)...", addr, |
76 | vmlinuz_addr, vmlinuz_addr+vmlinuz_size); | 76 | vmlinuz_addr, vmlinuz_addr+vmlinuz_size); |
77 | /* discard up to the actual load data */ | 77 | /* discard up to the actual load data */ |
78 | gunzip_discard(&gzstate, ei.elfoffset - sizeof(elfheader)); | 78 | gunzip_discard(&gzstate, ei.elfoffset - sizeof(elfheader)); |
79 | len = gunzip_finish(&gzstate, addr, ei.loadsize); | 79 | len = gunzip_finish(&gzstate, addr, ei.loadsize); |
80 | if (len != ei.loadsize) | 80 | if (len != ei.loadsize) |
81 | fatal("ran out of data! only got 0x%x of 0x%lx bytes.\n\r", | 81 | fatal("ran out of data! only got 0x%x of 0x%lx bytes.\n\r", |
82 | len, ei.loadsize); | 82 | len, ei.loadsize); |
83 | printf("done 0x%x bytes\n\r", len); | 83 | printf("done 0x%x bytes\n\r", len); |
84 | 84 | ||
85 | flush_cache(addr, ei.loadsize); | 85 | flush_cache(addr, ei.loadsize); |
86 | 86 | ||
87 | return (struct addr_range){addr, ei.memsize}; | 87 | return (struct addr_range){addr, ei.memsize}; |
88 | } | 88 | } |
89 | 89 | ||
90 | static struct addr_range prep_initrd(struct addr_range vmlinux, void *chosen, | 90 | static struct addr_range prep_initrd(struct addr_range vmlinux, void *chosen, |
91 | unsigned long initrd_addr, | 91 | unsigned long initrd_addr, |
92 | unsigned long initrd_size) | 92 | unsigned long initrd_size) |
93 | { | 93 | { |
94 | /* If we have an image attached to us, it overrides anything | 94 | /* If we have an image attached to us, it overrides anything |
95 | * supplied by the loader. */ | 95 | * supplied by the loader. */ |
96 | if (_initrd_end > _initrd_start) { | 96 | if (_initrd_end > _initrd_start) { |
97 | printf("Attached initrd image at 0x%p-0x%p\n\r", | 97 | printf("Attached initrd image at 0x%p-0x%p\n\r", |
98 | _initrd_start, _initrd_end); | 98 | _initrd_start, _initrd_end); |
99 | initrd_addr = (unsigned long)_initrd_start; | 99 | initrd_addr = (unsigned long)_initrd_start; |
100 | initrd_size = _initrd_end - _initrd_start; | 100 | initrd_size = _initrd_end - _initrd_start; |
101 | } else if (initrd_size > 0) { | 101 | } else if (initrd_size > 0) { |
102 | printf("Using loader supplied ramdisk at 0x%lx-0x%lx\n\r", | 102 | printf("Using loader supplied ramdisk at 0x%lx-0x%lx\n\r", |
103 | initrd_addr, initrd_addr + initrd_size); | 103 | initrd_addr, initrd_addr + initrd_size); |
104 | } | 104 | } |
105 | 105 | ||
106 | /* If there's no initrd at all, we're done */ | 106 | /* If there's no initrd at all, we're done */ |
107 | if (! initrd_size) | 107 | if (! initrd_size) |
108 | return (struct addr_range){0, 0}; | 108 | return (struct addr_range){0, 0}; |
109 | 109 | ||
110 | /* | 110 | /* |
111 | * If the initrd is too low it will be clobbered when the | 111 | * If the initrd is too low it will be clobbered when the |
112 | * kernel relocates to its final location. In this case, | 112 | * kernel relocates to its final location. In this case, |
113 | * allocate a safer place and move it. | 113 | * allocate a safer place and move it. |
114 | */ | 114 | */ |
115 | if (initrd_addr < vmlinux.size) { | 115 | if (initrd_addr < vmlinux.size) { |
116 | void *old_addr = (void *)initrd_addr; | 116 | void *old_addr = (void *)initrd_addr; |
117 | 117 | ||
118 | printf("Allocating 0x%lx bytes for initrd ...\n\r", | 118 | printf("Allocating 0x%lx bytes for initrd ...\n\r", |
119 | initrd_size); | 119 | initrd_size); |
120 | initrd_addr = (unsigned long)malloc(initrd_size); | 120 | initrd_addr = (unsigned long)malloc(initrd_size); |
121 | if (! initrd_addr) | 121 | if (! initrd_addr) |
122 | fatal("Can't allocate memory for initial " | 122 | fatal("Can't allocate memory for initial " |
123 | "ramdisk !\n\r"); | 123 | "ramdisk !\n\r"); |
124 | printf("Relocating initrd 0x%lx <- 0x%p (0x%lx bytes)\n\r", | 124 | printf("Relocating initrd 0x%lx <- 0x%p (0x%lx bytes)\n\r", |
125 | initrd_addr, old_addr, initrd_size); | 125 | initrd_addr, old_addr, initrd_size); |
126 | memmove((void *)initrd_addr, old_addr, initrd_size); | 126 | memmove((void *)initrd_addr, old_addr, initrd_size); |
127 | } | 127 | } |
128 | 128 | ||
129 | printf("initrd head: 0x%lx\n\r", *((unsigned long *)initrd_addr)); | 129 | printf("initrd head: 0x%lx\n\r", *((unsigned long *)initrd_addr)); |
130 | 130 | ||
131 | /* Tell the kernel initrd address via device tree */ | 131 | /* Tell the kernel initrd address via device tree */ |
132 | setprop_val(chosen, "linux,initrd-start", (u32)(initrd_addr)); | 132 | setprop_val(chosen, "linux,initrd-start", (u32)(initrd_addr)); |
133 | setprop_val(chosen, "linux,initrd-end", (u32)(initrd_addr+initrd_size)); | 133 | setprop_val(chosen, "linux,initrd-end", (u32)(initrd_addr+initrd_size)); |
134 | 134 | ||
135 | return (struct addr_range){(void *)initrd_addr, initrd_size}; | 135 | return (struct addr_range){(void *)initrd_addr, initrd_size}; |
136 | } | 136 | } |
137 | 137 | ||
138 | /* A buffer that may be edited by tools operating on a zImage binary so as to | 138 | /* A buffer that may be edited by tools operating on a zImage binary so as to |
139 | * edit the command line passed to vmlinux (by setting /chosen/bootargs). | 139 | * edit the command line passed to vmlinux (by setting /chosen/bootargs). |
140 | * The buffer is put in it's own section so that tools may locate it easier. | 140 | * The buffer is put in it's own section so that tools may locate it easier. |
141 | */ | 141 | */ |
142 | static char cmdline[COMMAND_LINE_SIZE] | 142 | static char cmdline[BOOT_COMMAND_LINE_SIZE] |
143 | __attribute__((__section__("__builtin_cmdline"))); | 143 | __attribute__((__section__("__builtin_cmdline"))); |
144 | 144 | ||
145 | static void prep_cmdline(void *chosen) | 145 | static void prep_cmdline(void *chosen) |
146 | { | 146 | { |
147 | if (cmdline[0] == '\0') | 147 | if (cmdline[0] == '\0') |
148 | getprop(chosen, "bootargs", cmdline, COMMAND_LINE_SIZE-1); | 148 | getprop(chosen, "bootargs", cmdline, BOOT_COMMAND_LINE_SIZE-1); |
149 | 149 | ||
150 | printf("\n\rLinux/PowerPC load: %s", cmdline); | 150 | printf("\n\rLinux/PowerPC load: %s", cmdline); |
151 | /* If possible, edit the command line */ | 151 | /* If possible, edit the command line */ |
152 | if (console_ops.edit_cmdline) | 152 | if (console_ops.edit_cmdline) |
153 | console_ops.edit_cmdline(cmdline, COMMAND_LINE_SIZE); | 153 | console_ops.edit_cmdline(cmdline, BOOT_COMMAND_LINE_SIZE); |
154 | printf("\n\r"); | 154 | printf("\n\r"); |
155 | 155 | ||
156 | /* Put the command line back into the devtree for the kernel */ | 156 | /* Put the command line back into the devtree for the kernel */ |
157 | setprop_str(chosen, "bootargs", cmdline); | 157 | setprop_str(chosen, "bootargs", cmdline); |
158 | } | 158 | } |
159 | 159 | ||
160 | struct platform_ops platform_ops; | 160 | struct platform_ops platform_ops; |
161 | struct dt_ops dt_ops; | 161 | struct dt_ops dt_ops; |
162 | struct console_ops console_ops; | 162 | struct console_ops console_ops; |
163 | struct loader_info loader_info; | 163 | struct loader_info loader_info; |
164 | 164 | ||
165 | void start(void) | 165 | void start(void) |
166 | { | 166 | { |
167 | struct addr_range vmlinux, initrd; | 167 | struct addr_range vmlinux, initrd; |
168 | kernel_entry_t kentry; | 168 | kernel_entry_t kentry; |
169 | unsigned long ft_addr = 0; | 169 | unsigned long ft_addr = 0; |
170 | void *chosen; | 170 | void *chosen; |
171 | 171 | ||
172 | /* Do this first, because malloc() could clobber the loader's | 172 | /* Do this first, because malloc() could clobber the loader's |
173 | * command line. Only use the loader command line if a | 173 | * command line. Only use the loader command line if a |
174 | * built-in command line wasn't set by an external tool */ | 174 | * built-in command line wasn't set by an external tool */ |
175 | if ((loader_info.cmdline_len > 0) && (cmdline[0] == '\0')) | 175 | if ((loader_info.cmdline_len > 0) && (cmdline[0] == '\0')) |
176 | memmove(cmdline, loader_info.cmdline, | 176 | memmove(cmdline, loader_info.cmdline, |
177 | min(loader_info.cmdline_len, COMMAND_LINE_SIZE-1)); | 177 | min(loader_info.cmdline_len, BOOT_COMMAND_LINE_SIZE-1)); |
178 | 178 | ||
179 | if (console_ops.open && (console_ops.open() < 0)) | 179 | if (console_ops.open && (console_ops.open() < 0)) |
180 | exit(); | 180 | exit(); |
181 | if (platform_ops.fixups) | 181 | if (platform_ops.fixups) |
182 | platform_ops.fixups(); | 182 | platform_ops.fixups(); |
183 | 183 | ||
184 | printf("\n\rzImage starting: loaded at 0x%p (sp: 0x%p)\n\r", | 184 | printf("\n\rzImage starting: loaded at 0x%p (sp: 0x%p)\n\r", |
185 | _start, get_sp()); | 185 | _start, get_sp()); |
186 | 186 | ||
187 | /* Ensure that the device tree has a /chosen node */ | 187 | /* Ensure that the device tree has a /chosen node */ |
188 | chosen = finddevice("/chosen"); | 188 | chosen = finddevice("/chosen"); |
189 | if (!chosen) | 189 | if (!chosen) |
190 | chosen = create_node(NULL, "chosen"); | 190 | chosen = create_node(NULL, "chosen"); |
191 | 191 | ||
192 | vmlinux = prep_kernel(); | 192 | vmlinux = prep_kernel(); |
193 | initrd = prep_initrd(vmlinux, chosen, | 193 | initrd = prep_initrd(vmlinux, chosen, |
194 | loader_info.initrd_addr, loader_info.initrd_size); | 194 | loader_info.initrd_addr, loader_info.initrd_size); |
195 | prep_cmdline(chosen); | 195 | prep_cmdline(chosen); |
196 | 196 | ||
197 | printf("Finalizing device tree..."); | 197 | printf("Finalizing device tree..."); |
198 | if (dt_ops.finalize) | 198 | if (dt_ops.finalize) |
199 | ft_addr = dt_ops.finalize(); | 199 | ft_addr = dt_ops.finalize(); |
200 | if (ft_addr) | 200 | if (ft_addr) |
201 | printf(" flat tree at 0x%lx\n\r", ft_addr); | 201 | printf(" flat tree at 0x%lx\n\r", ft_addr); |
202 | else | 202 | else |
203 | printf(" using OF tree (promptr=%p)\n\r", loader_info.promptr); | 203 | printf(" using OF tree (promptr=%p)\n\r", loader_info.promptr); |
204 | 204 | ||
205 | if (console_ops.close) | 205 | if (console_ops.close) |
206 | console_ops.close(); | 206 | console_ops.close(); |
207 | 207 | ||
208 | kentry = (kernel_entry_t) vmlinux.addr; | 208 | kentry = (kernel_entry_t) vmlinux.addr; |
209 | if (ft_addr) | 209 | if (ft_addr) |
210 | kentry(ft_addr, 0, NULL); | 210 | kentry(ft_addr, 0, NULL); |
211 | else | 211 | else |
212 | kentry((unsigned long)initrd.addr, initrd.size, | 212 | kentry((unsigned long)initrd.addr, initrd.size, |
213 | loader_info.promptr); | 213 | loader_info.promptr); |
214 | 214 | ||
215 | /* console closed so printf in fatal below may not work */ | 215 | /* console closed so printf in fatal below may not work */ |
216 | fatal("Error: Linux kernel returned to zImage boot wrapper!\n\r"); | 216 | fatal("Error: Linux kernel returned to zImage boot wrapper!\n\r"); |
217 | } | 217 | } |
218 | 218 |
arch/powerpc/boot/ops.h
1 | /* | 1 | /* |
2 | * Global definition of all the bootwrapper operations. | 2 | * Global definition of all the bootwrapper operations. |
3 | * | 3 | * |
4 | * Author: Mark A. Greer <mgreer@mvista.com> | 4 | * Author: Mark A. Greer <mgreer@mvista.com> |
5 | * | 5 | * |
6 | * 2006 (c) MontaVista Software, Inc. This file is licensed under | 6 | * 2006 (c) MontaVista Software, Inc. This file is licensed under |
7 | * the terms of the GNU General Public License version 2. This program | 7 | * the terms of the GNU General Public License version 2. This program |
8 | * is licensed "as is" without any warranty of any kind, whether express | 8 | * is licensed "as is" without any warranty of any kind, whether express |
9 | * or implied. | 9 | * or implied. |
10 | */ | 10 | */ |
11 | #ifndef _PPC_BOOT_OPS_H_ | 11 | #ifndef _PPC_BOOT_OPS_H_ |
12 | #define _PPC_BOOT_OPS_H_ | 12 | #define _PPC_BOOT_OPS_H_ |
13 | 13 | ||
14 | #include <stddef.h> | 14 | #include <stddef.h> |
15 | #include "types.h" | 15 | #include "types.h" |
16 | #include "string.h" | 16 | #include "string.h" |
17 | 17 | ||
18 | #define COMMAND_LINE_SIZE 512 | 18 | #define BOOT_COMMAND_LINE_SIZE 512 |
19 | #define MAX_PATH_LEN 256 | 19 | #define MAX_PATH_LEN 256 |
20 | #define MAX_PROP_LEN 256 /* What should this be? */ | 20 | #define MAX_PROP_LEN 256 /* What should this be? */ |
21 | 21 | ||
22 | typedef void (*kernel_entry_t)(unsigned long r3, unsigned long r4, void *r5); | 22 | typedef void (*kernel_entry_t)(unsigned long r3, unsigned long r4, void *r5); |
23 | 23 | ||
24 | /* Platform specific operations */ | 24 | /* Platform specific operations */ |
25 | struct platform_ops { | 25 | struct platform_ops { |
26 | void (*fixups)(void); | 26 | void (*fixups)(void); |
27 | void (*image_hdr)(const void *); | 27 | void (*image_hdr)(const void *); |
28 | void * (*malloc)(unsigned long size); | 28 | void * (*malloc)(unsigned long size); |
29 | void (*free)(void *ptr); | 29 | void (*free)(void *ptr); |
30 | void * (*realloc)(void *ptr, unsigned long size); | 30 | void * (*realloc)(void *ptr, unsigned long size); |
31 | void (*exit)(void); | 31 | void (*exit)(void); |
32 | void * (*vmlinux_alloc)(unsigned long size); | 32 | void * (*vmlinux_alloc)(unsigned long size); |
33 | }; | 33 | }; |
34 | extern struct platform_ops platform_ops; | 34 | extern struct platform_ops platform_ops; |
35 | 35 | ||
36 | /* Device Tree operations */ | 36 | /* Device Tree operations */ |
37 | struct dt_ops { | 37 | struct dt_ops { |
38 | void * (*finddevice)(const char *name); | 38 | void * (*finddevice)(const char *name); |
39 | int (*getprop)(const void *phandle, const char *name, void *buf, | 39 | int (*getprop)(const void *phandle, const char *name, void *buf, |
40 | const int buflen); | 40 | const int buflen); |
41 | int (*setprop)(const void *phandle, const char *name, | 41 | int (*setprop)(const void *phandle, const char *name, |
42 | const void *buf, const int buflen); | 42 | const void *buf, const int buflen); |
43 | int (*del_node)(const void *phandle); | 43 | int (*del_node)(const void *phandle); |
44 | void *(*get_parent)(const void *phandle); | 44 | void *(*get_parent)(const void *phandle); |
45 | /* The node must not already exist. */ | 45 | /* The node must not already exist. */ |
46 | void *(*create_node)(const void *parent, const char *name); | 46 | void *(*create_node)(const void *parent, const char *name); |
47 | void *(*find_node_by_prop_value)(const void *prev, | 47 | void *(*find_node_by_prop_value)(const void *prev, |
48 | const char *propname, | 48 | const char *propname, |
49 | const char *propval, int proplen); | 49 | const char *propval, int proplen); |
50 | void *(*find_node_by_compatible)(const void *prev, | 50 | void *(*find_node_by_compatible)(const void *prev, |
51 | const char *compat); | 51 | const char *compat); |
52 | unsigned long (*finalize)(void); | 52 | unsigned long (*finalize)(void); |
53 | char *(*get_path)(const void *phandle, char *buf, int len); | 53 | char *(*get_path)(const void *phandle, char *buf, int len); |
54 | }; | 54 | }; |
55 | extern struct dt_ops dt_ops; | 55 | extern struct dt_ops dt_ops; |
56 | 56 | ||
57 | /* Console operations */ | 57 | /* Console operations */ |
58 | struct console_ops { | 58 | struct console_ops { |
59 | int (*open)(void); | 59 | int (*open)(void); |
60 | void (*write)(const char *buf, int len); | 60 | void (*write)(const char *buf, int len); |
61 | void (*edit_cmdline)(char *buf, int len); | 61 | void (*edit_cmdline)(char *buf, int len); |
62 | void (*close)(void); | 62 | void (*close)(void); |
63 | void *data; | 63 | void *data; |
64 | }; | 64 | }; |
65 | extern struct console_ops console_ops; | 65 | extern struct console_ops console_ops; |
66 | 66 | ||
67 | /* Serial console operations */ | 67 | /* Serial console operations */ |
68 | struct serial_console_data { | 68 | struct serial_console_data { |
69 | int (*open)(void); | 69 | int (*open)(void); |
70 | void (*putc)(unsigned char c); | 70 | void (*putc)(unsigned char c); |
71 | unsigned char (*getc)(void); | 71 | unsigned char (*getc)(void); |
72 | u8 (*tstc)(void); | 72 | u8 (*tstc)(void); |
73 | void (*close)(void); | 73 | void (*close)(void); |
74 | }; | 74 | }; |
75 | 75 | ||
76 | struct loader_info { | 76 | struct loader_info { |
77 | void *promptr; | 77 | void *promptr; |
78 | unsigned long initrd_addr, initrd_size; | 78 | unsigned long initrd_addr, initrd_size; |
79 | char *cmdline; | 79 | char *cmdline; |
80 | int cmdline_len; | 80 | int cmdline_len; |
81 | }; | 81 | }; |
82 | extern struct loader_info loader_info; | 82 | extern struct loader_info loader_info; |
83 | 83 | ||
84 | void start(void); | 84 | void start(void); |
85 | void fdt_init(void *blob); | 85 | void fdt_init(void *blob); |
86 | int serial_console_init(void); | 86 | int serial_console_init(void); |
87 | int ns16550_console_init(void *devp, struct serial_console_data *scdp); | 87 | int ns16550_console_init(void *devp, struct serial_console_data *scdp); |
88 | int mpsc_console_init(void *devp, struct serial_console_data *scdp); | 88 | int mpsc_console_init(void *devp, struct serial_console_data *scdp); |
89 | int cpm_console_init(void *devp, struct serial_console_data *scdp); | 89 | int cpm_console_init(void *devp, struct serial_console_data *scdp); |
90 | int mpc5200_psc_console_init(void *devp, struct serial_console_data *scdp); | 90 | int mpc5200_psc_console_init(void *devp, struct serial_console_data *scdp); |
91 | int uartlite_console_init(void *devp, struct serial_console_data *scdp); | 91 | int uartlite_console_init(void *devp, struct serial_console_data *scdp); |
92 | void *simple_alloc_init(char *base, unsigned long heap_size, | 92 | void *simple_alloc_init(char *base, unsigned long heap_size, |
93 | unsigned long granularity, unsigned long max_allocs); | 93 | unsigned long granularity, unsigned long max_allocs); |
94 | extern void flush_cache(void *, unsigned long); | 94 | extern void flush_cache(void *, unsigned long); |
95 | int dt_xlate_reg(void *node, int res, unsigned long *addr, unsigned long *size); | 95 | int dt_xlate_reg(void *node, int res, unsigned long *addr, unsigned long *size); |
96 | int dt_xlate_addr(void *node, u32 *buf, int buflen, unsigned long *xlated_addr); | 96 | int dt_xlate_addr(void *node, u32 *buf, int buflen, unsigned long *xlated_addr); |
97 | int dt_is_compatible(void *node, const char *compat); | 97 | int dt_is_compatible(void *node, const char *compat); |
98 | void dt_get_reg_format(void *node, u32 *naddr, u32 *nsize); | 98 | void dt_get_reg_format(void *node, u32 *naddr, u32 *nsize); |
99 | int dt_get_virtual_reg(void *node, void **addr, int nres); | 99 | int dt_get_virtual_reg(void *node, void **addr, int nres); |
100 | 100 | ||
101 | static inline void *finddevice(const char *name) | 101 | static inline void *finddevice(const char *name) |
102 | { | 102 | { |
103 | return (dt_ops.finddevice) ? dt_ops.finddevice(name) : NULL; | 103 | return (dt_ops.finddevice) ? dt_ops.finddevice(name) : NULL; |
104 | } | 104 | } |
105 | 105 | ||
106 | static inline int getprop(void *devp, const char *name, void *buf, int buflen) | 106 | static inline int getprop(void *devp, const char *name, void *buf, int buflen) |
107 | { | 107 | { |
108 | return (dt_ops.getprop) ? dt_ops.getprop(devp, name, buf, buflen) : -1; | 108 | return (dt_ops.getprop) ? dt_ops.getprop(devp, name, buf, buflen) : -1; |
109 | } | 109 | } |
110 | 110 | ||
111 | static inline int setprop(void *devp, const char *name, | 111 | static inline int setprop(void *devp, const char *name, |
112 | const void *buf, int buflen) | 112 | const void *buf, int buflen) |
113 | { | 113 | { |
114 | return (dt_ops.setprop) ? dt_ops.setprop(devp, name, buf, buflen) : -1; | 114 | return (dt_ops.setprop) ? dt_ops.setprop(devp, name, buf, buflen) : -1; |
115 | } | 115 | } |
116 | #define setprop_val(devp, name, val) \ | 116 | #define setprop_val(devp, name, val) \ |
117 | do { \ | 117 | do { \ |
118 | typeof(val) x = (val); \ | 118 | typeof(val) x = (val); \ |
119 | setprop((devp), (name), &x, sizeof(x)); \ | 119 | setprop((devp), (name), &x, sizeof(x)); \ |
120 | } while (0) | 120 | } while (0) |
121 | 121 | ||
122 | static inline int setprop_str(void *devp, const char *name, const char *buf) | 122 | static inline int setprop_str(void *devp, const char *name, const char *buf) |
123 | { | 123 | { |
124 | if (dt_ops.setprop) | 124 | if (dt_ops.setprop) |
125 | return dt_ops.setprop(devp, name, buf, strlen(buf) + 1); | 125 | return dt_ops.setprop(devp, name, buf, strlen(buf) + 1); |
126 | 126 | ||
127 | return -1; | 127 | return -1; |
128 | } | 128 | } |
129 | 129 | ||
130 | static inline int del_node(const void *devp) | 130 | static inline int del_node(const void *devp) |
131 | { | 131 | { |
132 | return dt_ops.del_node ? dt_ops.del_node(devp) : -1; | 132 | return dt_ops.del_node ? dt_ops.del_node(devp) : -1; |
133 | } | 133 | } |
134 | 134 | ||
135 | static inline void *get_parent(const char *devp) | 135 | static inline void *get_parent(const char *devp) |
136 | { | 136 | { |
137 | return dt_ops.get_parent ? dt_ops.get_parent(devp) : NULL; | 137 | return dt_ops.get_parent ? dt_ops.get_parent(devp) : NULL; |
138 | } | 138 | } |
139 | 139 | ||
140 | static inline void *create_node(const void *parent, const char *name) | 140 | static inline void *create_node(const void *parent, const char *name) |
141 | { | 141 | { |
142 | return dt_ops.create_node ? dt_ops.create_node(parent, name) : NULL; | 142 | return dt_ops.create_node ? dt_ops.create_node(parent, name) : NULL; |
143 | } | 143 | } |
144 | 144 | ||
145 | 145 | ||
146 | static inline void *find_node_by_prop_value(const void *prev, | 146 | static inline void *find_node_by_prop_value(const void *prev, |
147 | const char *propname, | 147 | const char *propname, |
148 | const char *propval, int proplen) | 148 | const char *propval, int proplen) |
149 | { | 149 | { |
150 | if (dt_ops.find_node_by_prop_value) | 150 | if (dt_ops.find_node_by_prop_value) |
151 | return dt_ops.find_node_by_prop_value(prev, propname, | 151 | return dt_ops.find_node_by_prop_value(prev, propname, |
152 | propval, proplen); | 152 | propval, proplen); |
153 | 153 | ||
154 | return NULL; | 154 | return NULL; |
155 | } | 155 | } |
156 | 156 | ||
157 | static inline void *find_node_by_prop_value_str(const void *prev, | 157 | static inline void *find_node_by_prop_value_str(const void *prev, |
158 | const char *propname, | 158 | const char *propname, |
159 | const char *propval) | 159 | const char *propval) |
160 | { | 160 | { |
161 | return find_node_by_prop_value(prev, propname, propval, | 161 | return find_node_by_prop_value(prev, propname, propval, |
162 | strlen(propval) + 1); | 162 | strlen(propval) + 1); |
163 | } | 163 | } |
164 | 164 | ||
165 | static inline void *find_node_by_devtype(const void *prev, | 165 | static inline void *find_node_by_devtype(const void *prev, |
166 | const char *type) | 166 | const char *type) |
167 | { | 167 | { |
168 | return find_node_by_prop_value_str(prev, "device_type", type); | 168 | return find_node_by_prop_value_str(prev, "device_type", type); |
169 | } | 169 | } |
170 | 170 | ||
171 | static inline void *find_node_by_alias(const char *alias) | 171 | static inline void *find_node_by_alias(const char *alias) |
172 | { | 172 | { |
173 | void *devp = finddevice("/aliases"); | 173 | void *devp = finddevice("/aliases"); |
174 | 174 | ||
175 | if (devp) { | 175 | if (devp) { |
176 | char path[MAX_PATH_LEN]; | 176 | char path[MAX_PATH_LEN]; |
177 | if (getprop(devp, alias, path, MAX_PATH_LEN) > 0) | 177 | if (getprop(devp, alias, path, MAX_PATH_LEN) > 0) |
178 | return finddevice(path); | 178 | return finddevice(path); |
179 | } | 179 | } |
180 | 180 | ||
181 | return NULL; | 181 | return NULL; |
182 | } | 182 | } |
183 | 183 | ||
184 | static inline void *find_node_by_compatible(const void *prev, | 184 | static inline void *find_node_by_compatible(const void *prev, |
185 | const char *compat) | 185 | const char *compat) |
186 | { | 186 | { |
187 | if (dt_ops.find_node_by_compatible) | 187 | if (dt_ops.find_node_by_compatible) |
188 | return dt_ops.find_node_by_compatible(prev, compat); | 188 | return dt_ops.find_node_by_compatible(prev, compat); |
189 | 189 | ||
190 | return NULL; | 190 | return NULL; |
191 | } | 191 | } |
192 | 192 | ||
193 | void dt_fixup_memory(u64 start, u64 size); | 193 | void dt_fixup_memory(u64 start, u64 size); |
194 | void dt_fixup_cpu_clocks(u32 cpufreq, u32 tbfreq, u32 busfreq); | 194 | void dt_fixup_cpu_clocks(u32 cpufreq, u32 tbfreq, u32 busfreq); |
195 | void dt_fixup_clock(const char *path, u32 freq); | 195 | void dt_fixup_clock(const char *path, u32 freq); |
196 | void dt_fixup_mac_address_by_alias(const char *alias, const u8 *addr); | 196 | void dt_fixup_mac_address_by_alias(const char *alias, const u8 *addr); |
197 | void dt_fixup_mac_address(u32 index, const u8 *addr); | 197 | void dt_fixup_mac_address(u32 index, const u8 *addr); |
198 | void __dt_fixup_mac_addresses(u32 startindex, ...); | 198 | void __dt_fixup_mac_addresses(u32 startindex, ...); |
199 | #define dt_fixup_mac_addresses(...) \ | 199 | #define dt_fixup_mac_addresses(...) \ |
200 | __dt_fixup_mac_addresses(0, __VA_ARGS__, NULL) | 200 | __dt_fixup_mac_addresses(0, __VA_ARGS__, NULL) |
201 | 201 | ||
202 | 202 | ||
203 | static inline void *find_node_by_linuxphandle(const u32 linuxphandle) | 203 | static inline void *find_node_by_linuxphandle(const u32 linuxphandle) |
204 | { | 204 | { |
205 | return find_node_by_prop_value(NULL, "linux,phandle", | 205 | return find_node_by_prop_value(NULL, "linux,phandle", |
206 | (char *)&linuxphandle, sizeof(u32)); | 206 | (char *)&linuxphandle, sizeof(u32)); |
207 | } | 207 | } |
208 | 208 | ||
209 | static inline char *get_path(const void *phandle, char *buf, int len) | 209 | static inline char *get_path(const void *phandle, char *buf, int len) |
210 | { | 210 | { |
211 | if (dt_ops.get_path) | 211 | if (dt_ops.get_path) |
212 | return dt_ops.get_path(phandle, buf, len); | 212 | return dt_ops.get_path(phandle, buf, len); |
213 | 213 | ||
214 | return NULL; | 214 | return NULL; |
215 | } | 215 | } |
216 | 216 | ||
217 | static inline void *malloc(unsigned long size) | 217 | static inline void *malloc(unsigned long size) |
218 | { | 218 | { |
219 | return (platform_ops.malloc) ? platform_ops.malloc(size) : NULL; | 219 | return (platform_ops.malloc) ? platform_ops.malloc(size) : NULL; |
220 | } | 220 | } |
221 | 221 | ||
222 | static inline void free(void *ptr) | 222 | static inline void free(void *ptr) |
223 | { | 223 | { |
224 | if (platform_ops.free) | 224 | if (platform_ops.free) |
225 | platform_ops.free(ptr); | 225 | platform_ops.free(ptr); |
226 | } | 226 | } |
227 | 227 | ||
228 | static inline void exit(void) | 228 | static inline void exit(void) |
229 | { | 229 | { |
230 | if (platform_ops.exit) | 230 | if (platform_ops.exit) |
231 | platform_ops.exit(); | 231 | platform_ops.exit(); |
232 | for(;;); | 232 | for(;;); |
233 | } | 233 | } |
234 | #define fatal(args...) { printf(args); exit(); } | 234 | #define fatal(args...) { printf(args); exit(); } |
235 | 235 | ||
236 | 236 | ||
237 | #define BSS_STACK(size) \ | 237 | #define BSS_STACK(size) \ |
238 | static char _bss_stack[size]; \ | 238 | static char _bss_stack[size]; \ |
239 | void *_platform_stack_top = _bss_stack + sizeof(_bss_stack); | 239 | void *_platform_stack_top = _bss_stack + sizeof(_bss_stack); |
240 | 240 | ||
241 | extern unsigned long timebase_period_ns; | 241 | extern unsigned long timebase_period_ns; |
242 | void udelay(long delay); | 242 | void udelay(long delay); |
243 | 243 | ||
244 | extern char _start[]; | 244 | extern char _start[]; |
245 | extern char __bss_start[]; | 245 | extern char __bss_start[]; |
246 | extern char _end[]; | 246 | extern char _end[]; |
247 | extern char _vmlinux_start[]; | 247 | extern char _vmlinux_start[]; |
248 | extern char _vmlinux_end[]; | 248 | extern char _vmlinux_end[]; |
249 | extern char _initrd_start[]; | 249 | extern char _initrd_start[]; |
250 | extern char _initrd_end[]; | 250 | extern char _initrd_end[]; |
251 | extern char _dtb_start[]; | 251 | extern char _dtb_start[]; |
252 | extern char _dtb_end[]; | 252 | extern char _dtb_end[]; |
253 | 253 | ||
254 | static inline __attribute__((const)) | 254 | static inline __attribute__((const)) |
255 | int __ilog2_u32(u32 n) | 255 | int __ilog2_u32(u32 n) |
256 | { | 256 | { |
257 | int bit; | 257 | int bit; |
258 | asm ("cntlzw %0,%1" : "=r" (bit) : "r" (n)); | 258 | asm ("cntlzw %0,%1" : "=r" (bit) : "r" (n)); |
259 | return 31 - bit; | 259 | return 31 - bit; |
260 | } | 260 | } |
261 | 261 | ||
262 | #endif /* _PPC_BOOT_OPS_H_ */ | 262 | #endif /* _PPC_BOOT_OPS_H_ */ |
263 | 263 |
arch/powerpc/boot/ps3.c
1 | /* | 1 | /* |
2 | * PS3 bootwrapper support. | 2 | * PS3 bootwrapper support. |
3 | * | 3 | * |
4 | * Copyright (C) 2007 Sony Computer Entertainment Inc. | 4 | * Copyright (C) 2007 Sony Computer Entertainment Inc. |
5 | * Copyright 2007 Sony Corp. | 5 | * Copyright 2007 Sony Corp. |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License as published by | 8 | * it under the terms of the GNU General Public License as published by |
9 | * the Free Software Foundation; version 2 of the License. | 9 | * the Free Software Foundation; version 2 of the License. |
10 | * | 10 | * |
11 | * This program is distributed in the hope that it will be useful, | 11 | * This program is distributed in the hope that it will be useful, |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | * GNU General Public License for more details. | 14 | * GNU General Public License for more details. |
15 | * | 15 | * |
16 | * You should have received a copy of the GNU General Public License | 16 | * You should have received a copy of the GNU General Public License |
17 | * along with this program; if not, write to the Free Software | 17 | * along with this program; if not, write to the Free Software |
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
19 | */ | 19 | */ |
20 | 20 | ||
21 | #include <stdarg.h> | 21 | #include <stdarg.h> |
22 | #include <stddef.h> | 22 | #include <stddef.h> |
23 | #include "types.h" | 23 | #include "types.h" |
24 | #include "elf.h" | 24 | #include "elf.h" |
25 | #include "string.h" | 25 | #include "string.h" |
26 | #include "stdio.h" | 26 | #include "stdio.h" |
27 | #include "page.h" | 27 | #include "page.h" |
28 | #include "ops.h" | 28 | #include "ops.h" |
29 | 29 | ||
30 | extern int lv1_panic(u64 in_1); | 30 | extern int lv1_panic(u64 in_1); |
31 | extern int lv1_get_logical_partition_id(u64 *out_1); | 31 | extern int lv1_get_logical_partition_id(u64 *out_1); |
32 | extern int lv1_get_logical_ppe_id(u64 *out_1); | 32 | extern int lv1_get_logical_ppe_id(u64 *out_1); |
33 | extern int lv1_get_repository_node_value(u64 in_1, u64 in_2, u64 in_3, | 33 | extern int lv1_get_repository_node_value(u64 in_1, u64 in_2, u64 in_3, |
34 | u64 in_4, u64 in_5, u64 *out_1, u64 *out_2); | 34 | u64 in_4, u64 in_5, u64 *out_1, u64 *out_2); |
35 | 35 | ||
36 | #ifdef DEBUG | 36 | #ifdef DEBUG |
37 | #define DBG(fmt...) printf(fmt) | 37 | #define DBG(fmt...) printf(fmt) |
38 | #else | 38 | #else |
39 | static inline int __attribute__ ((format (printf, 1, 2))) DBG( | 39 | static inline int __attribute__ ((format (printf, 1, 2))) DBG( |
40 | const char *fmt, ...) {return 0;} | 40 | const char *fmt, ...) {return 0;} |
41 | #endif | 41 | #endif |
42 | 42 | ||
43 | BSS_STACK(4096); | 43 | BSS_STACK(4096); |
44 | 44 | ||
45 | /* A buffer that may be edited by tools operating on a zImage binary so as to | 45 | /* A buffer that may be edited by tools operating on a zImage binary so as to |
46 | * edit the command line passed to vmlinux (by setting /chosen/bootargs). | 46 | * edit the command line passed to vmlinux (by setting /chosen/bootargs). |
47 | * The buffer is put in it's own section so that tools may locate it easier. | 47 | * The buffer is put in it's own section so that tools may locate it easier. |
48 | */ | 48 | */ |
49 | 49 | ||
50 | static char cmdline[COMMAND_LINE_SIZE] | 50 | static char cmdline[BOOT_COMMAND_LINE_SIZE] |
51 | __attribute__((__section__("__builtin_cmdline"))); | 51 | __attribute__((__section__("__builtin_cmdline"))); |
52 | 52 | ||
53 | static void prep_cmdline(void *chosen) | 53 | static void prep_cmdline(void *chosen) |
54 | { | 54 | { |
55 | if (cmdline[0] == '\0') | 55 | if (cmdline[0] == '\0') |
56 | getprop(chosen, "bootargs", cmdline, COMMAND_LINE_SIZE-1); | 56 | getprop(chosen, "bootargs", cmdline, BOOT_COMMAND_LINE_SIZE-1); |
57 | else | 57 | else |
58 | setprop_str(chosen, "bootargs", cmdline); | 58 | setprop_str(chosen, "bootargs", cmdline); |
59 | 59 | ||
60 | printf("cmdline: '%s'\n", cmdline); | 60 | printf("cmdline: '%s'\n", cmdline); |
61 | } | 61 | } |
62 | 62 | ||
63 | static void ps3_console_write(const char *buf, int len) | 63 | static void ps3_console_write(const char *buf, int len) |
64 | { | 64 | { |
65 | } | 65 | } |
66 | 66 | ||
67 | static void ps3_exit(void) | 67 | static void ps3_exit(void) |
68 | { | 68 | { |
69 | printf("ps3_exit\n"); | 69 | printf("ps3_exit\n"); |
70 | 70 | ||
71 | /* lv1_panic will shutdown the lpar. */ | 71 | /* lv1_panic will shutdown the lpar. */ |
72 | 72 | ||
73 | lv1_panic(0); /* zero = do not reboot */ | 73 | lv1_panic(0); /* zero = do not reboot */ |
74 | while (1); | 74 | while (1); |
75 | } | 75 | } |
76 | 76 | ||
77 | static int ps3_repository_read_rm_size(u64 *rm_size) | 77 | static int ps3_repository_read_rm_size(u64 *rm_size) |
78 | { | 78 | { |
79 | int result; | 79 | int result; |
80 | u64 lpar_id; | 80 | u64 lpar_id; |
81 | u64 ppe_id; | 81 | u64 ppe_id; |
82 | u64 v2; | 82 | u64 v2; |
83 | 83 | ||
84 | result = lv1_get_logical_partition_id(&lpar_id); | 84 | result = lv1_get_logical_partition_id(&lpar_id); |
85 | 85 | ||
86 | if (result) | 86 | if (result) |
87 | return -1; | 87 | return -1; |
88 | 88 | ||
89 | result = lv1_get_logical_ppe_id(&ppe_id); | 89 | result = lv1_get_logical_ppe_id(&ppe_id); |
90 | 90 | ||
91 | if (result) | 91 | if (result) |
92 | return -1; | 92 | return -1; |
93 | 93 | ||
94 | /* | 94 | /* |
95 | * n1: 0000000062690000 : ....bi.. | 95 | * n1: 0000000062690000 : ....bi.. |
96 | * n2: 7075000000000000 : pu...... | 96 | * n2: 7075000000000000 : pu...... |
97 | * n3: 0000000000000001 : ........ | 97 | * n3: 0000000000000001 : ........ |
98 | * n4: 726d5f73697a6500 : rm_size. | 98 | * n4: 726d5f73697a6500 : rm_size. |
99 | */ | 99 | */ |
100 | 100 | ||
101 | result = lv1_get_repository_node_value(lpar_id, 0x0000000062690000ULL, | 101 | result = lv1_get_repository_node_value(lpar_id, 0x0000000062690000ULL, |
102 | 0x7075000000000000ULL, ppe_id, 0x726d5f73697a6500ULL, rm_size, | 102 | 0x7075000000000000ULL, ppe_id, 0x726d5f73697a6500ULL, rm_size, |
103 | &v2); | 103 | &v2); |
104 | 104 | ||
105 | printf("%s:%d: ppe_id %lu \n", __func__, __LINE__, | 105 | printf("%s:%d: ppe_id %lu \n", __func__, __LINE__, |
106 | (unsigned long)ppe_id); | 106 | (unsigned long)ppe_id); |
107 | printf("%s:%d: lpar_id %lu \n", __func__, __LINE__, | 107 | printf("%s:%d: lpar_id %lu \n", __func__, __LINE__, |
108 | (unsigned long)lpar_id); | 108 | (unsigned long)lpar_id); |
109 | printf("%s:%d: rm_size %llxh \n", __func__, __LINE__, *rm_size); | 109 | printf("%s:%d: rm_size %llxh \n", __func__, __LINE__, *rm_size); |
110 | 110 | ||
111 | return result ? -1 : 0; | 111 | return result ? -1 : 0; |
112 | } | 112 | } |
113 | 113 | ||
114 | void ps3_copy_vectors(void) | 114 | void ps3_copy_vectors(void) |
115 | { | 115 | { |
116 | extern char __system_reset_kernel[]; | 116 | extern char __system_reset_kernel[]; |
117 | 117 | ||
118 | memcpy((void *)0x100, __system_reset_kernel, 512); | 118 | memcpy((void *)0x100, __system_reset_kernel, 512); |
119 | flush_cache((void *)0x100, 512); | 119 | flush_cache((void *)0x100, 512); |
120 | } | 120 | } |
121 | 121 | ||
122 | void platform_init(unsigned long null_check) | 122 | void platform_init(unsigned long null_check) |
123 | { | 123 | { |
124 | const u32 heapsize = 0x1000000 - (u32)_end; /* 16MiB */ | 124 | const u32 heapsize = 0x1000000 - (u32)_end; /* 16MiB */ |
125 | void *chosen; | 125 | void *chosen; |
126 | unsigned long ft_addr; | 126 | unsigned long ft_addr; |
127 | u64 rm_size; | 127 | u64 rm_size; |
128 | unsigned long val; | 128 | unsigned long val; |
129 | 129 | ||
130 | console_ops.write = ps3_console_write; | 130 | console_ops.write = ps3_console_write; |
131 | platform_ops.exit = ps3_exit; | 131 | platform_ops.exit = ps3_exit; |
132 | 132 | ||
133 | printf("\n-- PS3 bootwrapper --\n"); | 133 | printf("\n-- PS3 bootwrapper --\n"); |
134 | 134 | ||
135 | simple_alloc_init(_end, heapsize, 32, 64); | 135 | simple_alloc_init(_end, heapsize, 32, 64); |
136 | fdt_init(_dtb_start); | 136 | fdt_init(_dtb_start); |
137 | 137 | ||
138 | chosen = finddevice("/chosen"); | 138 | chosen = finddevice("/chosen"); |
139 | 139 | ||
140 | ps3_repository_read_rm_size(&rm_size); | 140 | ps3_repository_read_rm_size(&rm_size); |
141 | dt_fixup_memory(0, rm_size); | 141 | dt_fixup_memory(0, rm_size); |
142 | 142 | ||
143 | if (_initrd_end > _initrd_start) { | 143 | if (_initrd_end > _initrd_start) { |
144 | setprop_val(chosen, "linux,initrd-start", (u32)(_initrd_start)); | 144 | setprop_val(chosen, "linux,initrd-start", (u32)(_initrd_start)); |
145 | setprop_val(chosen, "linux,initrd-end", (u32)(_initrd_end)); | 145 | setprop_val(chosen, "linux,initrd-end", (u32)(_initrd_end)); |
146 | } | 146 | } |
147 | 147 | ||
148 | prep_cmdline(chosen); | 148 | prep_cmdline(chosen); |
149 | 149 | ||
150 | ft_addr = dt_ops.finalize(); | 150 | ft_addr = dt_ops.finalize(); |
151 | 151 | ||
152 | ps3_copy_vectors(); | 152 | ps3_copy_vectors(); |
153 | 153 | ||
154 | printf(" flat tree at 0x%lx\n\r", ft_addr); | 154 | printf(" flat tree at 0x%lx\n\r", ft_addr); |
155 | 155 | ||
156 | val = *(unsigned long *)0; | 156 | val = *(unsigned long *)0; |
157 | 157 | ||
158 | if (val != null_check) | 158 | if (val != null_check) |
159 | printf("null check failed: %lx != %lx\n\r", val, null_check); | 159 | printf("null check failed: %lx != %lx\n\r", val, null_check); |
160 | 160 | ||
161 | ((kernel_entry_t)0)(ft_addr, 0, NULL); | 161 | ((kernel_entry_t)0)(ft_addr, 0, NULL); |
162 | 162 | ||
163 | ps3_exit(); | 163 | ps3_exit(); |
164 | } | 164 | } |
165 | 165 |