aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/boot/main.c27
-rw-r--r--arch/powerpc/boot/of.c8
-rw-r--r--arch/powerpc/boot/ops.h25
-rw-r--r--arch/powerpc/boot/stdio.c3
-rwxr-xr-xarch/powerpc/boot/wrapper4
-rw-r--r--arch/powerpc/boot/zImage.coff.lds.S4
-rw-r--r--arch/powerpc/boot/zImage.lds.S5
7 files changed, 34 insertions, 42 deletions
diff --git a/arch/powerpc/boot/main.c b/arch/powerpc/boot/main.c
index d719bb9333d1..418497482b6e 100644
--- a/arch/powerpc/boot/main.c
+++ b/arch/powerpc/boot/main.c
@@ -27,6 +27,8 @@ extern char _vmlinux_start[];
27extern char _vmlinux_end[]; 27extern char _vmlinux_end[];
28extern char _initrd_start[]; 28extern char _initrd_start[];
29extern char _initrd_end[]; 29extern char _initrd_end[];
30extern char _dtb_start[];
31extern char _dtb_end[];
30 32
31struct addr_range { 33struct addr_range {
32 unsigned long addr; 34 unsigned long addr;
@@ -250,10 +252,6 @@ static void prep_kernel(unsigned long *a1, unsigned long *a2)
250 flush_cache((void *)vmlinux.addr, vmlinux.size); 252 flush_cache((void *)vmlinux.addr, vmlinux.size);
251} 253}
252 254
253void __attribute__ ((weak)) ft_init(void *dt_blob)
254{
255}
256
257/* A buffer that may be edited by tools operating on a zImage binary so as to 255/* A buffer that may be edited by tools operating on a zImage binary so as to
258 * edit the command line passed to vmlinux (by setting /chosen/bootargs). 256 * edit the command line passed to vmlinux (by setting /chosen/bootargs).
259 * The buffer is put in it's own section so that tools may locate it easier. 257 * The buffer is put in it's own section so that tools may locate it easier.
@@ -285,19 +283,12 @@ static void set_cmdline(char *buf)
285 setprop(devp, "bootargs", buf, strlen(buf) + 1); 283 setprop(devp, "bootargs", buf, strlen(buf) + 1);
286} 284}
287 285
288/* Section where ft can be tacked on after zImage is built */
289union blobspace {
290 struct boot_param_header hdr;
291 char space[8*1024];
292} dt_blob __attribute__((__section__("__builtin_ft")));
293
294struct platform_ops platform_ops; 286struct platform_ops platform_ops;
295struct dt_ops dt_ops; 287struct dt_ops dt_ops;
296struct console_ops console_ops; 288struct console_ops console_ops;
297 289
298void start(unsigned long a1, unsigned long a2, void *promptr, void *sp) 290void start(unsigned long a1, unsigned long a2, void *promptr, void *sp)
299{ 291{
300 int have_dt = 0;
301 kernel_entry_t kentry; 292 kernel_entry_t kentry;
302 char cmdline[COMMAND_LINE_SIZE]; 293 char cmdline[COMMAND_LINE_SIZE];
303 294
@@ -306,15 +297,7 @@ void start(unsigned long a1, unsigned long a2, void *promptr, void *sp)
306 memset(&dt_ops, 0, sizeof(dt_ops)); 297 memset(&dt_ops, 0, sizeof(dt_ops));
307 memset(&console_ops, 0, sizeof(console_ops)); 298 memset(&console_ops, 0, sizeof(console_ops));
308 299
309 /* Override the dt_ops and device tree if there was an flat dev 300 if (platform_init(promptr, _dtb_start, _dtb_end))
310 * tree attached to the zImage.
311 */
312 if (dt_blob.hdr.magic == OF_DT_HEADER) {
313 have_dt = 1;
314 ft_init(&dt_blob);
315 }
316
317 if (platform_init(promptr))
318 exit(); 301 exit();
319 if (console_ops.open && (console_ops.open() < 0)) 302 if (console_ops.open && (console_ops.open() < 0))
320 exit(); 303 exit();
@@ -342,8 +325,10 @@ void start(unsigned long a1, unsigned long a2, void *promptr, void *sp)
342 console_ops.close(); 325 console_ops.close();
343 326
344 kentry = (kernel_entry_t) vmlinux.addr; 327 kentry = (kernel_entry_t) vmlinux.addr;
345 if (have_dt) 328 if (_dtb_end > _dtb_start) {
329 dt_ops.ft_pack();
346 kentry(dt_ops.ft_addr(), 0, NULL); 330 kentry(dt_ops.ft_addr(), 0, NULL);
331 }
347 else 332 else
348 /* XXX initrd addr/size should be passed in properties */ 333 /* XXX initrd addr/size should be passed in properties */
349 kentry(a1, a2, promptr); 334 kentry(a1, a2, promptr);
diff --git a/arch/powerpc/boot/of.c b/arch/powerpc/boot/of.c
index 3a71845afc6c..0182f384f3e6 100644
--- a/arch/powerpc/boot/of.c
+++ b/arch/powerpc/boot/of.c
@@ -256,24 +256,18 @@ static void of_console_write(char *buf, int len)
256 call_prom("write", 3, 1, of_stdout_handle, buf, len); 256 call_prom("write", 3, 1, of_stdout_handle, buf, len);
257} 257}
258 258
259int platform_init(void *promptr) 259int platform_init(void *promptr, char *dt_blob_start, char *dt_blob_end)
260{ 260{
261 platform_ops.fixups = NULL;
262 platform_ops.image_hdr = of_image_hdr; 261 platform_ops.image_hdr = of_image_hdr;
263 platform_ops.malloc = of_try_claim; 262 platform_ops.malloc = of_try_claim;
264 platform_ops.free = NULL;
265 platform_ops.exit = of_exit; 263 platform_ops.exit = of_exit;
266 264
267 dt_ops.finddevice = of_finddevice; 265 dt_ops.finddevice = of_finddevice;
268 dt_ops.getprop = of_getprop; 266 dt_ops.getprop = of_getprop;
269 dt_ops.setprop = of_setprop; 267 dt_ops.setprop = of_setprop;
270 dt_ops.translate_addr = NULL;
271 268
272 console_ops.open = of_console_open; 269 console_ops.open = of_console_open;
273 console_ops.write = of_console_write; 270 console_ops.write = of_console_write;
274 console_ops.edit_cmdline = NULL;
275 console_ops.close = NULL;
276 console_ops.data = NULL;
277 271
278 prom = (int (*)(void *))promptr; 272 prom = (int (*)(void *))promptr;
279 return 0; 273 return 0;
diff --git a/arch/powerpc/boot/ops.h b/arch/powerpc/boot/ops.h
index 135eb4bb03b4..59832fb0f276 100644
--- a/arch/powerpc/boot/ops.h
+++ b/arch/powerpc/boot/ops.h
@@ -22,7 +22,8 @@ struct platform_ops {
22 void (*fixups)(void); 22 void (*fixups)(void);
23 void (*image_hdr)(const void *); 23 void (*image_hdr)(const void *);
24 void * (*malloc)(u32 size); 24 void * (*malloc)(u32 size);
25 void (*free)(void *ptr, u32 size); 25 void (*free)(void *ptr);
26 void * (*realloc)(void *ptr, unsigned long size);
26 void (*exit)(void); 27 void (*exit)(void);
27}; 28};
28extern struct platform_ops platform_ops; 29extern struct platform_ops platform_ops;
@@ -30,12 +31,11 @@ extern struct platform_ops platform_ops;
30/* Device Tree operations */ 31/* Device Tree operations */
31struct dt_ops { 32struct dt_ops {
32 void * (*finddevice)(const char *name); 33 void * (*finddevice)(const char *name);
33 int (*getprop)(const void *node, const char *name, void *buf, 34 int (*getprop)(const void *phandle, const char *name, void *buf,
34 const int buflen); 35 const int buflen);
35 int (*setprop)(const void *node, const char *name, 36 int (*setprop)(const void *phandle, const char *name,
36 const void *buf, const int buflen); 37 const void *buf, const int buflen);
37 u64 (*translate_addr)(const char *path, const u32 *in_addr, 38 void (*ft_pack)(void);
38 const u32 addr_len);
39 unsigned long (*ft_addr)(void); 39 unsigned long (*ft_addr)(void);
40}; 40};
41extern struct dt_ops dt_ops; 41extern struct dt_ops dt_ops;
@@ -59,10 +59,13 @@ struct serial_console_data {
59 void (*close)(void); 59 void (*close)(void);
60}; 60};
61 61
62extern int platform_init(void *promptr); 62int platform_init(void *promptr, char *dt_blob_start, char *dt_blob_end);
63extern void simple_alloc_init(void); 63int ft_init(void *dt_blob, unsigned int max_size, unsigned int max_find_device);
64extern void ft_init(void *dt_blob); 64int serial_console_init(void);
65extern int serial_console_init(void); 65int ns16550_console_init(void *devp, struct serial_console_data *scdp);
66void *simple_alloc_init(char *base, u32 heap_size, u32 granularity,
67 u32 max_allocs);
68
66 69
67static inline void *finddevice(const char *name) 70static inline void *finddevice(const char *name)
68{ 71{
@@ -84,10 +87,10 @@ static inline void *malloc(u32 size)
84 return (platform_ops.malloc) ? platform_ops.malloc(size) : NULL; 87 return (platform_ops.malloc) ? platform_ops.malloc(size) : NULL;
85} 88}
86 89
87static inline void free(void *ptr, u32 size) 90static inline void free(void *ptr)
88{ 91{
89 if (platform_ops.free) 92 if (platform_ops.free)
90 platform_ops.free(ptr, size); 93 platform_ops.free(ptr);
91} 94}
92 95
93static inline void exit(void) 96static inline void exit(void)
diff --git a/arch/powerpc/boot/stdio.c b/arch/powerpc/boot/stdio.c
index 6d5f6382e1ce..0a9feeb98342 100644
--- a/arch/powerpc/boot/stdio.c
+++ b/arch/powerpc/boot/stdio.c
@@ -320,6 +320,7 @@ printf(const char *fmt, ...)
320 va_start(args, fmt); 320 va_start(args, fmt);
321 n = vsprintf(sprint_buf, fmt, args); 321 n = vsprintf(sprint_buf, fmt, args);
322 va_end(args); 322 va_end(args);
323 console_ops.write(sprint_buf, n); 323 if (console_ops.write)
324 console_ops.write(sprint_buf, n);
324 return n; 325 return n;
325} 326}
diff --git a/arch/powerpc/boot/wrapper b/arch/powerpc/boot/wrapper
index eab7318729e9..b5fb1fee76f8 100755
--- a/arch/powerpc/boot/wrapper
+++ b/arch/powerpc/boot/wrapper
@@ -179,11 +179,11 @@ if [ -z "$cacheit" ]; then
179fi 179fi
180 180
181if [ -n "$initrd" ]; then 181if [ -n "$initrd" ]; then
182 addsec $tmp "$initrd" initrd 182 addsec $tmp "$initrd" $isection
183fi 183fi
184 184
185if [ -n "$dtb" ]; then 185if [ -n "$dtb" ]; then
186 addsec $tmp "$dtb" dtb 186 addsec $tmp "$dtb" .kernel:dtb
187fi 187fi
188 188
189if [ "$platform" != "miboot" ]; then 189if [ "$platform" != "miboot" ]; then
diff --git a/arch/powerpc/boot/zImage.coff.lds.S b/arch/powerpc/boot/zImage.coff.lds.S
index 05f32388b953..a360905e5428 100644
--- a/arch/powerpc/boot/zImage.coff.lds.S
+++ b/arch/powerpc/boot/zImage.coff.lds.S
@@ -21,6 +21,10 @@ SECTIONS
21 *(.got2) 21 *(.got2)
22 __got2_end = .; 22 __got2_end = .;
23 23
24 _dtb_start = .;
25 *(.kernel:dtb)
26 _dtb_end = .;
27
24 _vmlinux_start = .; 28 _vmlinux_start = .;
25 *(.kernel:vmlinux.strip) 29 *(.kernel:vmlinux.strip)
26 _vmlinux_end = .; 30 _vmlinux_end = .;
diff --git a/arch/powerpc/boot/zImage.lds.S b/arch/powerpc/boot/zImage.lds.S
index 4b6bb3ffe3dc..4be3c6414b04 100644
--- a/arch/powerpc/boot/zImage.lds.S
+++ b/arch/powerpc/boot/zImage.lds.S
@@ -21,6 +21,11 @@ SECTIONS
21 __got2_end = .; 21 __got2_end = .;
22 } 22 }
23 23
24 . = ALIGN(8);
25 _dtb_start = .;
26 .kernel:dtb : { *(.kernel:dtb) }
27 _dtb_end = .;
28
24 . = ALIGN(4096); 29 . = ALIGN(4096);
25 _vmlinux_start = .; 30 _vmlinux_start = .;
26 .kernel:vmlinux.strip : { *(.kernel:vmlinux.strip) } 31 .kernel:vmlinux.strip : { *(.kernel:vmlinux.strip) }