Commit 147c05168fc86e824ccd1c0a02b40843e3cbca88

Authored by Cédric Le Goater
Committed by Benjamin Herrenschmidt
1 parent 2d9afb369b

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>

Showing 7 changed files with 72 additions and 5 deletions Side-by-side Diff

arch/powerpc/boot/Makefile
... ... @@ -22,8 +22,14 @@
22 22 BOOTCFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
23 23 -fno-strict-aliasing -Os -msoft-float -pipe \
24 24 -fomit-frame-pointer -fno-builtin -fPIC -nostdinc \
25   - -isystem $(shell $(CROSS32CC) -print-file-name=include) \
26   - -mbig-endian
  25 + -isystem $(shell $(CROSS32CC) -print-file-name=include)
  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 33 BOOTAFLAGS := -D__ASSEMBLY__ $(BOOTCFLAGS) -traditional -nostdinc
28 34  
29 35 ifdef CONFIG_DEBUG_INFO
... ... @@ -142,7 +148,11 @@
142 148 $(obj)/empty.c:
143 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 156 @cp $< $@
147 157  
148 158 clean-files := $(zlib) $(zlibheader) $(zliblinuxheader) \
arch/powerpc/boot/crt0.S
... ... @@ -275,6 +275,7 @@
275 275 rfid
276 276  
277 277 1: /* Return from OF */
  278 + FIXUP_ENDIAN
278 279  
279 280 /* Restore registers and return. */
280 281 rldicl r1,r1,0,32
arch/powerpc/boot/ppc_asm.h
... ... @@ -62,5 +62,17 @@
62 62 #define SPRN_TBRL 268
63 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 77 #endif /* _PPC64_PPC_ASM_H */
arch/powerpc/boot/pseries-head.S
  1 +#include "ppc_asm.h"
  2 +
1 3 .text
2 4  
3 5 .globl _zimage_start
4 6 _zimage_start:
  7 + FIXUP_ENDIAN
5 8 b _zimage_start_lib
arch/powerpc/boot/wrapper
... ... @@ -40,6 +40,7 @@
40 40 binary=
41 41 gzip=.gz
42 42 pie=
  43 +format=
43 44  
44 45 # cross-compilation prefix
45 46 CROSS=
... ... @@ -136,6 +137,14 @@
136 137 kernel=vmlinux
137 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 148 platformo=$object/"$platform".o
140 149 lds=$object/zImage.lds
141 150 ext=strip
... ... @@ -154,6 +163,10 @@
154 163 pseries)
155 164 platformo="$object/pseries-head.o $object/of.o $object/epapr.o"
156 165 link_address='0x4000000'
  166 + if [ "$format" != "elf32ppc" ]; then
  167 + link_address=
  168 + pie=-pie
  169 + fi
157 170 make_space=n
158 171 ;;
159 172 maple)
... ... @@ -379,7 +392,7 @@
379 392 if [ -n "$link_address" ] ; then
380 393 text_start="-Ttext $link_address"
381 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 396 $platformo $tmp $object/wrapper.a
384 397 rm $tmp
385 398 fi
arch/powerpc/boot/zImage.lds.S
  1 +#include <asm-generic/vmlinux.lds.h>
  2 +
  3 +#ifdef CONFIG_PPC64_BOOT_WRAPPER
  4 +OUTPUT_ARCH(powerpc:common64)
  5 +#else
1 6 OUTPUT_ARCH(powerpc:common)
  7 +#endif
2 8 ENTRY(_zimage_start)
3 9 EXTERN(_zimage_start)
4 10 SECTIONS
5 11  
... ... @@ -16,7 +22,9 @@
16 22 *(.rodata*)
17 23 *(.data*)
18 24 *(.sdata*)
  25 +#ifndef CONFIG_PPC64_BOOT_WRAPPER
19 26 *(.got2)
  27 +#endif
20 28 }
21 29 .dynsym : { *(.dynsym) }
22 30 .dynstr : { *(.dynstr) }
... ... @@ -27,7 +35,13 @@
27 35 }
28 36 .hash : { *(.hash) }
29 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 46 . = ALIGN(8);
33 47 .kernel:dtb :
... ... @@ -52,6 +66,15 @@
52 66 *(.kernel:initrd)
53 67 _initrd_end = .;
54 68 }
  69 +
  70 +#ifdef CONFIG_PPC64_BOOT_WRAPPER
  71 + .got :
  72 + {
  73 + __toc_start = .;
  74 + *(.got)
  75 + *(.toc)
  76 + }
  77 +#endif
55 78  
56 79 . = ALIGN(4096);
57 80 .bss :
arch/powerpc/platforms/Kconfig.cputype
... ... @@ -422,6 +422,7 @@
422 422  
423 423 config CPU_LITTLE_ENDIAN
424 424 bool "Build little endian kernel"
  425 + select PPC64_BOOT_WRAPPER
425 426 help
426 427 Build a little endian kernel.
427 428  
... ... @@ -430,4 +431,8 @@
430 431 little endian powerpc.
431 432  
432 433 endchoice
  434 +
  435 +config PPC64_BOOT_WRAPPER
  436 + def_bool n
  437 + depends on CPU_LITTLE_ENDIAN