diff options
Diffstat (limited to 'arch/powerpc/boot')
-rw-r--r-- | arch/powerpc/boot/Makefile | 6 | ||||
-rw-r--r-- | arch/powerpc/boot/crt0.S | 32 | ||||
-rw-r--r-- | arch/powerpc/boot/main.c | 18 | ||||
-rw-r--r-- | arch/powerpc/boot/of.c | 6 | ||||
-rw-r--r-- | arch/powerpc/boot/ops.h | 12 | ||||
-rwxr-xr-x | arch/powerpc/boot/wrapper | 6 | ||||
-rw-r--r-- | arch/powerpc/boot/zImage.coff.lds.S | 3 | ||||
-rw-r--r-- | arch/powerpc/boot/zImage.lds.S | 1 |
8 files changed, 61 insertions, 23 deletions
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile index 3628d8681844..b1fc029e5ea7 100644 --- a/arch/powerpc/boot/Makefile +++ b/arch/powerpc/boot/Makefile | |||
@@ -40,11 +40,11 @@ zliblinuxheader := zlib.h zconf.h zutil.h | |||
40 | $(addprefix $(obj)/,$(zlib) main.o): $(addprefix $(obj)/,$(zliblinuxheader)) \ | 40 | $(addprefix $(obj)/,$(zlib) main.o): $(addprefix $(obj)/,$(zliblinuxheader)) \ |
41 | $(addprefix $(obj)/,$(zlibheader)) | 41 | $(addprefix $(obj)/,$(zlibheader)) |
42 | 42 | ||
43 | src-wlib := string.S stdio.c main.c flatdevtree.c flatdevtree_misc.c \ | 43 | src-wlib := string.S crt0.S stdio.c main.c flatdevtree.c flatdevtree_misc.c \ |
44 | ns16550.c serial.c simple_alloc.c div64.S util.S \ | 44 | ns16550.c serial.c simple_alloc.c div64.S util.S \ |
45 | gunzip_util.c $(zlib) | 45 | gunzip_util.c $(zlib) |
46 | src-plat := of.c | 46 | src-plat := of.c |
47 | src-boot := crt0.S $(src-wlib) $(src-plat) empty.c | 47 | src-boot := $(src-wlib) $(src-plat) empty.c |
48 | 48 | ||
49 | src-boot := $(addprefix $(obj)/, $(src-boot)) | 49 | src-boot := $(addprefix $(obj)/, $(src-boot)) |
50 | obj-boot := $(addsuffix .o, $(basename $(src-boot))) | 50 | obj-boot := $(addsuffix .o, $(basename $(src-boot))) |
@@ -97,7 +97,7 @@ $(obj)/wrapper.a: $(obj-wlib) | |||
97 | 97 | ||
98 | hostprogs-y := addnote addRamDisk hack-coff mktree | 98 | hostprogs-y := addnote addRamDisk hack-coff mktree |
99 | 99 | ||
100 | extra-y := $(obj)/crt0.o $(obj)/wrapper.a $(obj-plat) $(obj)/empty.o \ | 100 | extra-y := $(obj)/wrapper.a $(obj-plat) $(obj)/empty.o \ |
101 | $(obj)/zImage.lds $(obj)/zImage.coff.lds | 101 | $(obj)/zImage.lds $(obj)/zImage.coff.lds |
102 | 102 | ||
103 | wrapper :=$(srctree)/$(src)/wrapper | 103 | wrapper :=$(srctree)/$(src)/wrapper |
diff --git a/arch/powerpc/boot/crt0.S b/arch/powerpc/boot/crt0.S index 70e65b13e033..3dc8d8f78499 100644 --- a/arch/powerpc/boot/crt0.S +++ b/arch/powerpc/boot/crt0.S | |||
@@ -16,6 +16,7 @@ | |||
16 | _zimage_start_opd: | 16 | _zimage_start_opd: |
17 | .long _zimage_start, 0, 0, 0 | 17 | .long _zimage_start, 0, 0, 0 |
18 | 18 | ||
19 | .weak _zimage_start | ||
19 | .globl _zimage_start | 20 | .globl _zimage_start |
20 | _zimage_start: | 21 | _zimage_start: |
21 | /* Work out the offset between the address we were linked at | 22 | /* Work out the offset between the address we were linked at |
@@ -44,7 +45,7 @@ _zimage_start: | |||
44 | addi r9,r9,4 | 45 | addi r9,r9,4 |
45 | bdnz 2b | 46 | bdnz 2b |
46 | 47 | ||
47 | /* Do a cache flush for our text, in case OF didn't */ | 48 | /* Do a cache flush for our text, in case the loader didn't */ |
48 | 3: lis r9,_start@ha | 49 | 3: lis r9,_start@ha |
49 | addi r9,r9,_start@l | 50 | addi r9,r9,_start@l |
50 | add r9,r0,r9 | 51 | add r9,r0,r9 |
@@ -59,6 +60,31 @@ _zimage_start: | |||
59 | sync | 60 | sync |
60 | isync | 61 | isync |
61 | 62 | ||
62 | mr r6,r1 | 63 | /* Clear the BSS */ |
63 | b start | 64 | lis r9,__bss_start@ha |
65 | addi r9,r9,__bss_start@l | ||
66 | lis r8,_end@ha | ||
67 | addi r8,r8,_end@l | ||
68 | li r0,0 | ||
69 | 5: stw r0,0(r9) | ||
70 | addi r9,r9,4 | ||
71 | cmplw cr0,r9,r8 | ||
72 | blt 5b | ||
64 | 73 | ||
74 | /* Possibly set up a custom stack */ | ||
75 | .weak _platform_stack_top | ||
76 | lis r8,_platform_stack_top@ha | ||
77 | addi r8,r8,_platform_stack_top@l | ||
78 | cmpwi r8,0 | ||
79 | beq 6f | ||
80 | lwz r1,0(r8) | ||
81 | li r0,0 | ||
82 | stwu r0,-16(r1) /* establish a stack frame */ | ||
83 | 6: | ||
84 | |||
85 | /* Call platform_init() */ | ||
86 | bl platform_init | ||
87 | |||
88 | /* Call start */ | ||
89 | mr r3,r1 | ||
90 | b start | ||
diff --git a/arch/powerpc/boot/main.c b/arch/powerpc/boot/main.c index 05de6cfafeeb..8a60e13777d7 100644 --- a/arch/powerpc/boot/main.c +++ b/arch/powerpc/boot/main.c | |||
@@ -254,21 +254,15 @@ static void set_cmdline(char *buf) | |||
254 | struct platform_ops platform_ops; | 254 | struct platform_ops platform_ops; |
255 | struct dt_ops dt_ops; | 255 | struct dt_ops dt_ops; |
256 | struct console_ops console_ops; | 256 | struct console_ops console_ops; |
257 | struct loader_info loader_info; | ||
257 | 258 | ||
258 | void start(unsigned long a1, unsigned long a2, void *promptr, void *sp) | 259 | void start(void *sp) |
259 | { | 260 | { |
260 | struct addr_range vmlinux, initrd; | 261 | struct addr_range vmlinux, initrd; |
261 | kernel_entry_t kentry; | 262 | kernel_entry_t kentry; |
262 | char cmdline[COMMAND_LINE_SIZE]; | 263 | char cmdline[COMMAND_LINE_SIZE]; |
263 | unsigned long ft_addr = 0; | 264 | unsigned long ft_addr = 0; |
264 | 265 | ||
265 | memset(__bss_start, 0, _end - __bss_start); | ||
266 | memset(&platform_ops, 0, sizeof(platform_ops)); | ||
267 | memset(&dt_ops, 0, sizeof(dt_ops)); | ||
268 | memset(&console_ops, 0, sizeof(console_ops)); | ||
269 | |||
270 | if (platform_init(promptr, _dtb_start, _dtb_end)) | ||
271 | exit(); | ||
272 | if (console_ops.open && (console_ops.open() < 0)) | 266 | if (console_ops.open && (console_ops.open() < 0)) |
273 | exit(); | 267 | exit(); |
274 | if (platform_ops.fixups) | 268 | if (platform_ops.fixups) |
@@ -278,7 +272,8 @@ void start(unsigned long a1, unsigned long a2, void *promptr, void *sp) | |||
278 | _start, sp); | 272 | _start, sp); |
279 | 273 | ||
280 | vmlinux = prep_kernel(); | 274 | vmlinux = prep_kernel(); |
281 | initrd = prep_initrd(vmlinux, a1, a2); | 275 | initrd = prep_initrd(vmlinux, loader_info.initrd_addr, |
276 | loader_info.initrd_size); | ||
282 | 277 | ||
283 | /* If cmdline came from zimage wrapper or if we can edit the one | 278 | /* If cmdline came from zimage wrapper or if we can edit the one |
284 | * in the dt, print it out and edit it, if possible. | 279 | * in the dt, print it out and edit it, if possible. |
@@ -298,7 +293,7 @@ void start(unsigned long a1, unsigned long a2, void *promptr, void *sp) | |||
298 | if (ft_addr) | 293 | if (ft_addr) |
299 | printf(" flat tree at 0x%lx\n\r", ft_addr); | 294 | printf(" flat tree at 0x%lx\n\r", ft_addr); |
300 | else | 295 | else |
301 | printf(" using OF tree (promptr=%p)\n\r", promptr); | 296 | printf(" using OF tree (promptr=%p)\n\r", loader_info.promptr); |
302 | 297 | ||
303 | if (console_ops.close) | 298 | if (console_ops.close) |
304 | console_ops.close(); | 299 | console_ops.close(); |
@@ -307,7 +302,8 @@ void start(unsigned long a1, unsigned long a2, void *promptr, void *sp) | |||
307 | if (ft_addr) | 302 | if (ft_addr) |
308 | kentry(ft_addr, 0, NULL); | 303 | kentry(ft_addr, 0, NULL); |
309 | else | 304 | else |
310 | kentry((unsigned long)initrd.addr, initrd.size, promptr); | 305 | kentry((unsigned long)initrd.addr, initrd.size, |
306 | loader_info.promptr); | ||
311 | 307 | ||
312 | /* console closed so printf below may not work */ | 308 | /* console closed so printf below may not work */ |
313 | printf("Error: Linux kernel returned to zImage boot wrapper!\n\r"); | 309 | printf("Error: Linux kernel returned to zImage boot wrapper!\n\r"); |
diff --git a/arch/powerpc/boot/of.c b/arch/powerpc/boot/of.c index 044f34770b96..c6f0d9701485 100644 --- a/arch/powerpc/boot/of.c +++ b/arch/powerpc/boot/of.c | |||
@@ -267,7 +267,7 @@ static void of_console_write(char *buf, int len) | |||
267 | call_prom("write", 3, 1, of_stdout_handle, buf, len); | 267 | call_prom("write", 3, 1, of_stdout_handle, buf, len); |
268 | } | 268 | } |
269 | 269 | ||
270 | int platform_init(void *promptr, char *dt_blob_start, char *dt_blob_end) | 270 | void platform_init(unsigned long a1, unsigned long a2, void *promptr) |
271 | { | 271 | { |
272 | platform_ops.image_hdr = of_image_hdr; | 272 | platform_ops.image_hdr = of_image_hdr; |
273 | platform_ops.malloc = of_try_claim; | 273 | platform_ops.malloc = of_try_claim; |
@@ -282,5 +282,7 @@ int platform_init(void *promptr, char *dt_blob_start, char *dt_blob_end) | |||
282 | console_ops.write = of_console_write; | 282 | console_ops.write = of_console_write; |
283 | 283 | ||
284 | prom = (int (*)(void *))promptr; | 284 | prom = (int (*)(void *))promptr; |
285 | return 0; | 285 | loader_info.promptr = promptr; |
286 | loader_info.initrd_addr = a1; | ||
287 | loader_info.initrd_size = a2; | ||
286 | } | 288 | } |
diff --git a/arch/powerpc/boot/ops.h b/arch/powerpc/boot/ops.h index fa62ff223e70..cad4eee599fb 100644 --- a/arch/powerpc/boot/ops.h +++ b/arch/powerpc/boot/ops.h | |||
@@ -59,7 +59,13 @@ struct serial_console_data { | |||
59 | void (*close)(void); | 59 | void (*close)(void); |
60 | }; | 60 | }; |
61 | 61 | ||
62 | int platform_init(void *promptr, char *dt_blob_start, char *dt_blob_end); | 62 | struct loader_info { |
63 | void *promptr; | ||
64 | unsigned long initrd_addr, initrd_size; | ||
65 | }; | ||
66 | extern struct loader_info loader_info; | ||
67 | |||
68 | void start(void *sp); | ||
63 | int ft_init(void *dt_blob, unsigned int max_size, unsigned int max_find_device); | 69 | int ft_init(void *dt_blob, unsigned int max_size, unsigned int max_find_device); |
64 | int serial_console_init(void); | 70 | int serial_console_init(void); |
65 | int ns16550_console_init(void *devp, struct serial_console_data *scdp); | 71 | int ns16550_console_init(void *devp, struct serial_console_data *scdp); |
@@ -100,4 +106,8 @@ static inline void exit(void) | |||
100 | for(;;); | 106 | for(;;); |
101 | } | 107 | } |
102 | 108 | ||
109 | #define BSS_STACK(size) \ | ||
110 | static char _bss_stack[size]; \ | ||
111 | void *_platform_stack_top = _bss_stack + sizeof(_bss_stack); | ||
112 | |||
103 | #endif /* _PPC_BOOT_OPS_H_ */ | 113 | #endif /* _PPC_BOOT_OPS_H_ */ |
diff --git a/arch/powerpc/boot/wrapper b/arch/powerpc/boot/wrapper index 024e4d425c59..157d8c89e138 100755 --- a/arch/powerpc/boot/wrapper +++ b/arch/powerpc/boot/wrapper | |||
@@ -191,7 +191,7 @@ fi | |||
191 | 191 | ||
192 | if [ "$platform" != "miboot" ]; then | 192 | if [ "$platform" != "miboot" ]; then |
193 | ${CROSS}ld -m elf32ppc -T $lds -o "$ofile" \ | 193 | ${CROSS}ld -m elf32ppc -T $lds -o "$ofile" \ |
194 | $object/crt0.o $platformo $tmp $object/wrapper.a | 194 | $platformo $tmp $object/wrapper.a |
195 | rm $tmp | 195 | rm $tmp |
196 | fi | 196 | fi |
197 | 197 | ||
@@ -201,7 +201,9 @@ pseries|chrp) | |||
201 | $object/addnote "$ofile" | 201 | $object/addnote "$ofile" |
202 | ;; | 202 | ;; |
203 | pmaccoff) | 203 | pmaccoff) |
204 | ${CROSS}objcopy -O aixcoff-rs6000 --set-start 0x500000 "$ofile" | 204 | entry=`objdump -f "$ofile" | grep '^start address ' | \ |
205 | cut -d' ' -f3` | ||
206 | ${CROSS}objcopy -O aixcoff-rs6000 --set-start "$entry" "$ofile" | ||
205 | $object/hack-coff "$ofile" | 207 | $object/hack-coff "$ofile" |
206 | ;; | 208 | ;; |
207 | esac | 209 | esac |
diff --git a/arch/powerpc/boot/zImage.coff.lds.S b/arch/powerpc/boot/zImage.coff.lds.S index a360905e5428..fe87a90ce7f1 100644 --- a/arch/powerpc/boot/zImage.coff.lds.S +++ b/arch/powerpc/boot/zImage.coff.lds.S | |||
@@ -1,5 +1,6 @@ | |||
1 | OUTPUT_ARCH(powerpc:common) | 1 | OUTPUT_ARCH(powerpc:common) |
2 | ENTRY(_start) | 2 | ENTRY(_zimage_start_opd) |
3 | EXTERN(_zimage_start_opd) | ||
3 | SECTIONS | 4 | SECTIONS |
4 | { | 5 | { |
5 | . = (5*1024*1024); | 6 | . = (5*1024*1024); |
diff --git a/arch/powerpc/boot/zImage.lds.S b/arch/powerpc/boot/zImage.lds.S index 4be3c6414b04..f6e380fdb388 100644 --- a/arch/powerpc/boot/zImage.lds.S +++ b/arch/powerpc/boot/zImage.lds.S | |||
@@ -1,5 +1,6 @@ | |||
1 | OUTPUT_ARCH(powerpc:common) | 1 | OUTPUT_ARCH(powerpc:common) |
2 | ENTRY(_zimage_start) | 2 | ENTRY(_zimage_start) |
3 | EXTERN(_zimage_start) | ||
3 | SECTIONS | 4 | SECTIONS |
4 | { | 5 | { |
5 | . = (4*1024*1024); | 6 | . = (4*1024*1024); |