aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
authorCédric Le Goater <clg@fr.ibm.com>2014-04-24 03:23:39 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2014-04-28 03:36:21 -0400
commit147c05168fc86e824ccd1c0a02b40843e3cbca88 (patch)
treeb11fef2a92755918913b6c630d4fdb8f64af394a /arch/powerpc
parent2d9afb369bc069f11a3a8696c4bdf95d4ddf1281 (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/Makefile16
-rw-r--r--arch/powerpc/boot/crt0.S1
-rw-r--r--arch/powerpc/boot/ppc_asm.h12
-rw-r--r--arch/powerpc/boot/pseries-head.S3
-rwxr-xr-xarch/powerpc/boot/wrapper15
-rw-r--r--arch/powerpc/boot/zImage.lds.S25
-rw-r--r--arch/powerpc/platforms/Kconfig.cputype5
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
22BOOTCFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \ 22BOOTCFLAGS := -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 26ifdef CONFIG_PPC64_BOOT_WRAPPER
27BOOTCFLAGS += -m64
28endif
29ifdef CONFIG_CPU_BIG_ENDIAN
30BOOTCFLAGS += -mbig-endian
31endif
32
27BOOTAFLAGS := -D__ASSEMBLY__ $(BOOTCFLAGS) -traditional -nostdinc 33BOOTAFLAGS := -D__ASSEMBLY__ $(BOOTCFLAGS) -traditional -nostdinc
28 34
29ifdef CONFIG_DEBUG_INFO 35ifdef 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
148clean-files := $(zlib) $(zlibheader) $(zliblinuxheader) \ 158clean-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
2771: /* Return from OF */ 2771: /* 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=
40binary= 40binary=
41gzip=.gz 41gzip=.gz
42pie= 42pie=
43format=
43 44
44# cross-compilation prefix 45# cross-compilation prefix
45CROSS= 46CROSS=
@@ -136,6 +137,14 @@ if [ -z "$kernel" ]; then
136 kernel=vmlinux 137 kernel=vmlinux
137fi 138fi
138 139
140elfformat="`${CROSS}objdump -p "$kernel" | grep 'file format' | awk '{print $4}'`"
141case "$elfformat" in
142 elf64-powerpcle) format=elf64lppc ;;
143 elf64-powerpc) format=elf32ppc ;;
144 elf32-powerpc) format=elf32ppc ;;
145esac
146
147
139platformo=$object/"$platform".o 148platformo=$object/"$platform".o
140lds=$object/zImage.lds 149lds=$object/zImage.lds
141ext=strip 150ext=strip
@@ -154,6 +163,10 @@ of)
154pseries) 163pseries)
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 ;;
159maple) 172maple)
@@ -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
385fi 398fi
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
4OUTPUT_ARCH(powerpc:common64)
5#else
1OUTPUT_ARCH(powerpc:common) 6OUTPUT_ARCH(powerpc:common)
7#endif
2ENTRY(_zimage_start) 8ENTRY(_zimage_start)
3EXTERN(_zimage_start) 9EXTERN(_zimage_start)
4SECTIONS 10SECTIONS
@@ -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
423config CPU_LITTLE_ENDIAN 423config 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
432endchoice 433endchoice
434
435config PPC64_BOOT_WRAPPER
436 def_bool n
437 depends on CPU_LITTLE_ENDIAN