Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

powerpc/boot: Modify entry point for 64bit

This patch adds support a 64bit wrapper entry point. As in 32bit, the
entry point does its own relocation and can be loaded 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>

authored by

Cédric Le Goater and committed by
Benjamin Herrenschmidt
f16e9684 93d39210

+104 -4
+104 -4
arch/powerpc/boot/crt0.S
··· 1 1 /* 2 2 * Copyright (C) Paul Mackerras 1997. 3 3 * 4 + * Adapted for 64 bit LE PowerPC by Andrew Tauferner 5 + * 4 6 * This program is free software; you can redistribute it and/or 5 7 * modify it under the terms of the GNU General Public License 6 8 * as published by the Free Software Foundation; either version 7 9 * 2 of the License, or (at your option) any later version. 8 10 * 9 - * NOTE: this code runs in 32 bit mode, is position-independent, 10 - * and is packaged as ELF32. 11 11 */ 12 12 13 13 #include "ppc_asm.h" 14 + 15 + RELA = 7 16 + RELACOUNT = 0x6ffffff9 14 17 15 18 .text 16 19 /* A procedure descriptor used when booting this as a COFF file. ··· 24 21 _zimage_start_opd: 25 22 .long 0x500000, 0, 0, 0 26 23 24 + #ifdef __powerpc64__ 25 + .balign 8 26 + p_start: .llong _start 27 + p_etext: .llong _etext 28 + p_bss_start: .llong __bss_start 29 + p_end: .llong _end 30 + 31 + p_toc: .llong __toc_start + 0x8000 - p_base 32 + p_dyn: .llong __dynamic_start - p_base 33 + p_rela: .llong __rela_dyn_start - p_base 34 + p_prom: .llong 0 35 + .weak _platform_stack_top 36 + p_pstack: .llong _platform_stack_top 37 + #else 27 38 p_start: .long _start 28 39 p_etext: .long _etext 29 40 p_bss_start: .long __bss_start ··· 45 28 46 29 .weak _platform_stack_top 47 30 p_pstack: .long _platform_stack_top 31 + #endif 48 32 49 33 .weak _zimage_start 50 34 .globl _zimage_start ··· 56 38 and the address where we're running. */ 57 39 bl .+4 58 40 p_base: mflr r10 /* r10 now points to runtime addr of p_base */ 41 + #ifndef __powerpc64__ 59 42 /* grab the link address of the dynamic section in r11 */ 60 43 addis r11,r10,(_GLOBAL_OFFSET_TABLE_-p_base)@ha 61 44 lwz r11,(_GLOBAL_OFFSET_TABLE_-p_base)@l(r11) ··· 70 51 71 52 /* The dynamic section contains a series of tagged entries. 72 53 * We need the RELA and RELACOUNT entries. */ 73 - RELA = 7 74 - RELACOUNT = 0x6ffffff9 75 54 li r9,0 76 55 li r0,0 77 56 9: lwz r8,0(r12) /* get tag */ ··· 137 120 li r0,0 138 121 stwu r0,-16(r1) /* establish a stack frame */ 139 122 6: 123 + #else /* __powerpc64__ */ 124 + /* Save the prom pointer at p_prom. */ 125 + std r5,(p_prom-p_base)(r10) 140 126 127 + /* Set r2 to the TOC. */ 128 + ld r2,(p_toc-p_base)(r10) 129 + add r2,r2,r10 130 + 131 + /* Grab the link address of the dynamic section in r11. */ 132 + ld r11,-32768(r2) 133 + cmpwi r11,0 134 + beq 3f /* if not linked -pie then no dynamic section */ 135 + 136 + ld r11,(p_dyn-p_base)(r10) 137 + add r11,r11,r10 138 + ld r9,(p_rela-p_base)(r10) 139 + add r9,r9,r10 140 + 141 + li r7,0 142 + li r8,0 143 + 9: ld r6,0(r11) /* get tag */ 144 + cmpdi r6,0 145 + beq 12f /* end of list */ 146 + cmpdi r6,RELA 147 + bne 10f 148 + ld r7,8(r11) /* get RELA pointer in r7 */ 149 + b 11f 150 + 10: addis r6,r6,(-RELACOUNT)@ha 151 + cmpdi r6,RELACOUNT@l 152 + bne 11f 153 + ld r8,8(r11) /* get RELACOUNT value in r8 */ 154 + 11: addi r11,r11,16 155 + b 9b 156 + 12: 157 + cmpdi r7,0 /* check we have both RELA and RELACOUNT */ 158 + cmpdi cr1,r8,0 159 + beq 3f 160 + beq cr1,3f 161 + 162 + /* Calcuate the runtime offset. */ 163 + subf r7,r7,r9 164 + 165 + /* Run through the list of relocations and process the 166 + * R_PPC64_RELATIVE ones. */ 167 + mtctr r8 168 + 13: ld r0,8(r9) /* ELF64_R_TYPE(reloc->r_info) */ 169 + cmpdi r0,22 /* R_PPC64_RELATIVE */ 170 + bne 3f 171 + ld r6,0(r9) /* reloc->r_offset */ 172 + ld r0,16(r9) /* reloc->r_addend */ 173 + add r0,r0,r7 174 + stdx r0,r7,r6 175 + addi r9,r9,24 176 + bdnz 13b 177 + 178 + /* Do a cache flush for our text, in case the loader didn't */ 179 + 3: ld r9,p_start-p_base(r10) /* note: these are relocated now */ 180 + ld r8,p_etext-p_base(r10) 181 + 4: dcbf r0,r9 182 + icbi r0,r9 183 + addi r9,r9,0x20 184 + cmpld cr0,r9,r8 185 + blt 4b 186 + sync 187 + isync 188 + 189 + /* Clear the BSS */ 190 + ld r9,p_bss_start-p_base(r10) 191 + ld r8,p_end-p_base(r10) 192 + li r0,0 193 + 5: std r0,0(r9) 194 + addi r9,r9,8 195 + cmpld cr0,r9,r8 196 + blt 5b 197 + 198 + /* Possibly set up a custom stack */ 199 + ld r8,p_pstack-p_base(r10) 200 + cmpdi r8,0 201 + beq 6f 202 + ld r1,0(r8) 203 + li r0,0 204 + stdu r0,-16(r1) /* establish a stack frame */ 205 + 6: 206 + #endif /* __powerpc64__ */ 141 207 /* Call platform_init() */ 142 208 bl platform_init 143 209