diff options
author | Cédric Le Goater <clg@fr.ibm.com> | 2014-04-24 03:23:39 -0400 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2014-04-28 03:36:21 -0400 |
commit | 147c05168fc86e824ccd1c0a02b40843e3cbca88 (patch) | |
tree | b11fef2a92755918913b6c630d4fdb8f64af394a /arch/powerpc | |
parent | 2d9afb369bc069f11a3a8696c4bdf95d4ddf1281 (diff) |
powerpc/boot: Add support for 64bit little endian wrapper
The code is only slightly modified : entry points now use the
FIXUP_ENDIAN trampoline to switch endian order. The 32bit wrapper
is kept for big endian kernels and 64bit is enforced for little
endian kernels with a PPC64_BOOT_WRAPPER config option.
The linker script is generated using the kernel preprocessor flags
to make use of the CONFIG_* definitions and the wrapper script is
modified to take into account the new elf64ppc format.
Finally, the zImage file is compiled as a position independent
executable (-pie) which makes it loadable at any address by the
firmware.
Signed-off-by: Cédric Le Goater <clg@fr.ibm.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc')
-rw-r--r-- | arch/powerpc/boot/Makefile | 16 | ||||
-rw-r--r-- | arch/powerpc/boot/crt0.S | 1 | ||||
-rw-r--r-- | arch/powerpc/boot/ppc_asm.h | 12 | ||||
-rw-r--r-- | arch/powerpc/boot/pseries-head.S | 3 | ||||
-rwxr-xr-x | arch/powerpc/boot/wrapper | 15 | ||||
-rw-r--r-- | arch/powerpc/boot/zImage.lds.S | 25 | ||||
-rw-r--r-- | arch/powerpc/platforms/Kconfig.cputype | 5 |
7 files changed, 72 insertions, 5 deletions
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile index bed660ddf48c..a33c23308e97 100644 --- a/arch/powerpc/boot/Makefile +++ b/arch/powerpc/boot/Makefile | |||
@@ -22,8 +22,14 @@ all: $(obj)/zImage | |||
22 | BOOTCFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \ | 22 | BOOTCFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \ |
23 | -fno-strict-aliasing -Os -msoft-float -pipe \ | 23 | -fno-strict-aliasing -Os -msoft-float -pipe \ |
24 | -fomit-frame-pointer -fno-builtin -fPIC -nostdinc \ | 24 | -fomit-frame-pointer -fno-builtin -fPIC -nostdinc \ |
25 | -isystem $(shell $(CROSS32CC) -print-file-name=include) \ | 25 | -isystem $(shell $(CROSS32CC) -print-file-name=include) |
26 | -mbig-endian | 26 | ifdef CONFIG_PPC64_BOOT_WRAPPER |
27 | BOOTCFLAGS += -m64 | ||
28 | endif | ||
29 | ifdef CONFIG_CPU_BIG_ENDIAN | ||
30 | BOOTCFLAGS += -mbig-endian | ||
31 | endif | ||
32 | |||
27 | BOOTAFLAGS := -D__ASSEMBLY__ $(BOOTCFLAGS) -traditional -nostdinc | 33 | BOOTAFLAGS := -D__ASSEMBLY__ $(BOOTCFLAGS) -traditional -nostdinc |
28 | 34 | ||
29 | ifdef CONFIG_DEBUG_INFO | 35 | ifdef CONFIG_DEBUG_INFO |
@@ -142,7 +148,11 @@ $(addprefix $(obj)/,$(libfdt) $(libfdtheader)): $(obj)/%: $(srctree)/scripts/dtc | |||
142 | $(obj)/empty.c: | 148 | $(obj)/empty.c: |
143 | @touch $@ | 149 | @touch $@ |
144 | 150 | ||
145 | $(obj)/zImage.lds $(obj)/zImage.coff.lds $(obj)/zImage.ps3.lds: $(obj)/%: $(srctree)/$(src)/%.S | 151 | $(obj)/zImage.lds: $(obj)/%: $(srctree)/$(src)/%.S |
152 | $(CROSS32CC) $(cpp_flags) -E -Wp,-MD,$(depfile) -P -Upowerpc \ | ||
153 | -D__ASSEMBLY__ -DLINKER_SCRIPT -o $@ $< | ||
154 | |||
155 | $(obj)/zImage.coff.lds $(obj)/zImage.ps3.lds : $(obj)/%: $(srctree)/$(src)/%.S | ||
146 | @cp $< $@ | 156 | @cp $< $@ |
147 | 157 | ||
148 | clean-files := $(zlib) $(zlibheader) $(zliblinuxheader) \ | 158 | clean-files := $(zlib) $(zlibheader) $(zliblinuxheader) \ |
diff --git a/arch/powerpc/boot/crt0.S b/arch/powerpc/boot/crt0.S index 689290561e69..14de4f8778a7 100644 --- a/arch/powerpc/boot/crt0.S +++ b/arch/powerpc/boot/crt0.S | |||
@@ -275,6 +275,7 @@ prom: | |||
275 | rfid | 275 | rfid |
276 | 276 | ||
277 | 1: /* Return from OF */ | 277 | 1: /* Return from OF */ |
278 | FIXUP_ENDIAN | ||
278 | 279 | ||
279 | /* Restore registers and return. */ | 280 | /* Restore registers and return. */ |
280 | rldicl r1,r1,0,32 | 281 | rldicl r1,r1,0,32 |
diff --git a/arch/powerpc/boot/ppc_asm.h b/arch/powerpc/boot/ppc_asm.h index eb0e98be69e0..35ea60c1f070 100644 --- a/arch/powerpc/boot/ppc_asm.h +++ b/arch/powerpc/boot/ppc_asm.h | |||
@@ -62,4 +62,16 @@ | |||
62 | #define SPRN_TBRL 268 | 62 | #define SPRN_TBRL 268 |
63 | #define SPRN_TBRU 269 | 63 | #define SPRN_TBRU 269 |
64 | 64 | ||
65 | #define FIXUP_ENDIAN \ | ||
66 | tdi 0, 0, 0x48; /* Reverse endian of b . + 8 */ \ | ||
67 | b $+36; /* Skip trampoline if endian is good */ \ | ||
68 | .long 0x05009f42; /* bcl 20,31,$+4 */ \ | ||
69 | .long 0xa602487d; /* mflr r10 */ \ | ||
70 | .long 0x1c004a39; /* addi r10,r10,28 */ \ | ||
71 | .long 0xa600607d; /* mfmsr r11 */ \ | ||
72 | .long 0x01006b69; /* xori r11,r11,1 */ \ | ||
73 | .long 0xa6035a7d; /* mtsrr0 r10 */ \ | ||
74 | .long 0xa6037b7d; /* mtsrr1 r11 */ \ | ||
75 | .long 0x2400004c /* rfid */ | ||
76 | |||
65 | #endif /* _PPC64_PPC_ASM_H */ | 77 | #endif /* _PPC64_PPC_ASM_H */ |
diff --git a/arch/powerpc/boot/pseries-head.S b/arch/powerpc/boot/pseries-head.S index 655c3d2c321b..6ef6e02e80f9 100644 --- a/arch/powerpc/boot/pseries-head.S +++ b/arch/powerpc/boot/pseries-head.S | |||
@@ -1,5 +1,8 @@ | |||
1 | #include "ppc_asm.h" | ||
2 | |||
1 | .text | 3 | .text |
2 | 4 | ||
3 | .globl _zimage_start | 5 | .globl _zimage_start |
4 | _zimage_start: | 6 | _zimage_start: |
7 | FIXUP_ENDIAN | ||
5 | b _zimage_start_lib | 8 | b _zimage_start_lib |
diff --git a/arch/powerpc/boot/wrapper b/arch/powerpc/boot/wrapper index 5889c440a66a..1948cf8b8a40 100755 --- a/arch/powerpc/boot/wrapper +++ b/arch/powerpc/boot/wrapper | |||
@@ -40,6 +40,7 @@ cacheit= | |||
40 | binary= | 40 | binary= |
41 | gzip=.gz | 41 | gzip=.gz |
42 | pie= | 42 | pie= |
43 | format= | ||
43 | 44 | ||
44 | # cross-compilation prefix | 45 | # cross-compilation prefix |
45 | CROSS= | 46 | CROSS= |
@@ -136,6 +137,14 @@ if [ -z "$kernel" ]; then | |||
136 | kernel=vmlinux | 137 | kernel=vmlinux |
137 | fi | 138 | fi |
138 | 139 | ||
140 | elfformat="`${CROSS}objdump -p "$kernel" | grep 'file format' | awk '{print $4}'`" | ||
141 | case "$elfformat" in | ||
142 | elf64-powerpcle) format=elf64lppc ;; | ||
143 | elf64-powerpc) format=elf32ppc ;; | ||
144 | elf32-powerpc) format=elf32ppc ;; | ||
145 | esac | ||
146 | |||
147 | |||
139 | platformo=$object/"$platform".o | 148 | platformo=$object/"$platform".o |
140 | lds=$object/zImage.lds | 149 | lds=$object/zImage.lds |
141 | ext=strip | 150 | ext=strip |
@@ -154,6 +163,10 @@ of) | |||
154 | pseries) | 163 | pseries) |
155 | platformo="$object/pseries-head.o $object/of.o $object/epapr.o" | 164 | platformo="$object/pseries-head.o $object/of.o $object/epapr.o" |
156 | link_address='0x4000000' | 165 | link_address='0x4000000' |
166 | if [ "$format" != "elf32ppc" ]; then | ||
167 | link_address= | ||
168 | pie=-pie | ||
169 | fi | ||
157 | make_space=n | 170 | make_space=n |
158 | ;; | 171 | ;; |
159 | maple) | 172 | maple) |
@@ -379,7 +392,7 @@ if [ "$platform" != "miboot" ]; then | |||
379 | if [ -n "$link_address" ] ; then | 392 | if [ -n "$link_address" ] ; then |
380 | text_start="-Ttext $link_address" | 393 | text_start="-Ttext $link_address" |
381 | fi | 394 | fi |
382 | ${CROSS}ld -m elf32ppc -T $lds $text_start $pie -o "$ofile" \ | 395 | ${CROSS}ld -m $format -T $lds $text_start $pie -o "$ofile" \ |
383 | $platformo $tmp $object/wrapper.a | 396 | $platformo $tmp $object/wrapper.a |
384 | rm $tmp | 397 | rm $tmp |
385 | fi | 398 | fi |
diff --git a/arch/powerpc/boot/zImage.lds.S b/arch/powerpc/boot/zImage.lds.S index 2bd8731f1365..861e72109df2 100644 --- a/arch/powerpc/boot/zImage.lds.S +++ b/arch/powerpc/boot/zImage.lds.S | |||
@@ -1,4 +1,10 @@ | |||
1 | #include <asm-generic/vmlinux.lds.h> | ||
2 | |||
3 | #ifdef CONFIG_PPC64_BOOT_WRAPPER | ||
4 | OUTPUT_ARCH(powerpc:common64) | ||
5 | #else | ||
1 | OUTPUT_ARCH(powerpc:common) | 6 | OUTPUT_ARCH(powerpc:common) |
7 | #endif | ||
2 | ENTRY(_zimage_start) | 8 | ENTRY(_zimage_start) |
3 | EXTERN(_zimage_start) | 9 | EXTERN(_zimage_start) |
4 | SECTIONS | 10 | SECTIONS |
@@ -16,7 +22,9 @@ SECTIONS | |||
16 | *(.rodata*) | 22 | *(.rodata*) |
17 | *(.data*) | 23 | *(.data*) |
18 | *(.sdata*) | 24 | *(.sdata*) |
25 | #ifndef CONFIG_PPC64_BOOT_WRAPPER | ||
19 | *(.got2) | 26 | *(.got2) |
27 | #endif | ||
20 | } | 28 | } |
21 | .dynsym : { *(.dynsym) } | 29 | .dynsym : { *(.dynsym) } |
22 | .dynstr : { *(.dynstr) } | 30 | .dynstr : { *(.dynstr) } |
@@ -27,7 +35,13 @@ SECTIONS | |||
27 | } | 35 | } |
28 | .hash : { *(.hash) } | 36 | .hash : { *(.hash) } |
29 | .interp : { *(.interp) } | 37 | .interp : { *(.interp) } |
30 | .rela.dyn : { *(.rela*) } | 38 | .rela.dyn : |
39 | { | ||
40 | #ifdef CONFIG_PPC64_BOOT_WRAPPER | ||
41 | __rela_dyn_start = .; | ||
42 | #endif | ||
43 | *(.rela*) | ||
44 | } | ||
31 | 45 | ||
32 | . = ALIGN(8); | 46 | . = ALIGN(8); |
33 | .kernel:dtb : | 47 | .kernel:dtb : |
@@ -53,6 +67,15 @@ SECTIONS | |||
53 | _initrd_end = .; | 67 | _initrd_end = .; |
54 | } | 68 | } |
55 | 69 | ||
70 | #ifdef CONFIG_PPC64_BOOT_WRAPPER | ||
71 | .got : | ||
72 | { | ||
73 | __toc_start = .; | ||
74 | *(.got) | ||
75 | *(.toc) | ||
76 | } | ||
77 | #endif | ||
78 | |||
56 | . = ALIGN(4096); | 79 | . = ALIGN(4096); |
57 | .bss : | 80 | .bss : |
58 | { | 81 | { |
diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype index d9e2b19b7c8d..43b65ad1970a 100644 --- a/arch/powerpc/platforms/Kconfig.cputype +++ b/arch/powerpc/platforms/Kconfig.cputype | |||
@@ -422,6 +422,7 @@ config CPU_BIG_ENDIAN | |||
422 | 422 | ||
423 | config CPU_LITTLE_ENDIAN | 423 | config CPU_LITTLE_ENDIAN |
424 | bool "Build little endian kernel" | 424 | bool "Build little endian kernel" |
425 | select PPC64_BOOT_WRAPPER | ||
425 | help | 426 | help |
426 | Build a little endian kernel. | 427 | Build a little endian kernel. |
427 | 428 | ||
@@ -430,3 +431,7 @@ config CPU_LITTLE_ENDIAN | |||
430 | little endian powerpc. | 431 | little endian powerpc. |
431 | 432 | ||
432 | endchoice | 433 | endchoice |
434 | |||
435 | config PPC64_BOOT_WRAPPER | ||
436 | def_bool n | ||
437 | depends on CPU_LITTLE_ENDIAN | ||