aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/boot
diff options
context:
space:
mode:
authorCédric Le Goater <clg@fr.ibm.com>2014-04-24 03:23:37 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2014-04-28 03:36:12 -0400
commitf16e9684996188c12e1f460589003e99086ce36e (patch)
tree2072c5c57b07305fd06d2723ee41c2a4b46fea20 /arch/powerpc/boot
parent93d3921042988317e94b1bcc2e19844efe0b7356 (diff)
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>
Diffstat (limited to 'arch/powerpc/boot')
-rw-r--r--arch/powerpc/boot/crt0.S108
1 files changed, 104 insertions, 4 deletions
diff --git a/arch/powerpc/boot/crt0.S b/arch/powerpc/boot/crt0.S
index dbd99d064828..689290561e69 100644
--- a/arch/powerpc/boot/crt0.S
+++ b/arch/powerpc/boot/crt0.S
@@ -1,17 +1,20 @@
1/* 1/*
2 * Copyright (C) Paul Mackerras 1997. 2 * Copyright (C) Paul Mackerras 1997.
3 * 3 *
4 * Adapted for 64 bit LE PowerPC by Andrew Tauferner
5 *
4 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License 7 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 8 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version. 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#include "ppc_asm.h" 13#include "ppc_asm.h"
14 14
15RELA = 7
16RELACOUNT = 0x6ffffff9
17
15 .text 18 .text
16 /* A procedure descriptor used when booting this as a COFF file. 19 /* A procedure descriptor used when booting this as a COFF file.
17 * When making COFF, this comes first in the link and we're 20 * When making COFF, this comes first in the link and we're
@@ -21,6 +24,20 @@
21_zimage_start_opd: 24_zimage_start_opd:
22 .long 0x500000, 0, 0, 0 25 .long 0x500000, 0, 0, 0
23 26
27#ifdef __powerpc64__
28.balign 8
29p_start: .llong _start
30p_etext: .llong _etext
31p_bss_start: .llong __bss_start
32p_end: .llong _end
33
34p_toc: .llong __toc_start + 0x8000 - p_base
35p_dyn: .llong __dynamic_start - p_base
36p_rela: .llong __rela_dyn_start - p_base
37p_prom: .llong 0
38 .weak _platform_stack_top
39p_pstack: .llong _platform_stack_top
40#else
24p_start: .long _start 41p_start: .long _start
25p_etext: .long _etext 42p_etext: .long _etext
26p_bss_start: .long __bss_start 43p_bss_start: .long __bss_start
@@ -28,6 +45,7 @@ p_end: .long _end
28 45
29 .weak _platform_stack_top 46 .weak _platform_stack_top
30p_pstack: .long _platform_stack_top 47p_pstack: .long _platform_stack_top
48#endif
31 49
32 .weak _zimage_start 50 .weak _zimage_start
33 .globl _zimage_start 51 .globl _zimage_start
@@ -38,6 +56,7 @@ _zimage_start_lib:
38 and the address where we're running. */ 56 and the address where we're running. */
39 bl .+4 57 bl .+4
40p_base: mflr r10 /* r10 now points to runtime addr of p_base */ 58p_base: mflr r10 /* r10 now points to runtime addr of p_base */
59#ifndef __powerpc64__
41 /* grab the link address of the dynamic section in r11 */ 60 /* grab the link address of the dynamic section in r11 */
42 addis r11,r10,(_GLOBAL_OFFSET_TABLE_-p_base)@ha 61 addis r11,r10,(_GLOBAL_OFFSET_TABLE_-p_base)@ha
43 lwz r11,(_GLOBAL_OFFSET_TABLE_-p_base)@l(r11) 62 lwz r11,(_GLOBAL_OFFSET_TABLE_-p_base)@l(r11)
@@ -51,8 +70,6 @@ p_base: mflr r10 /* r10 now points to runtime addr of p_base */
51 70
52 /* The dynamic section contains a series of tagged entries. 71 /* The dynamic section contains a series of tagged entries.
53 * We need the RELA and RELACOUNT entries. */ 72 * We need the RELA and RELACOUNT entries. */
54RELA = 7
55RELACOUNT = 0x6ffffff9
56 li r9,0 73 li r9,0
57 li r0,0 74 li r0,0
589: lwz r8,0(r12) /* get tag */ 759: lwz r8,0(r12) /* get tag */
@@ -120,7 +137,90 @@ RELACOUNT = 0x6ffffff9
120 li r0,0 137 li r0,0
121 stwu r0,-16(r1) /* establish a stack frame */ 138 stwu r0,-16(r1) /* establish a stack frame */
1226: 1396:
140#else /* __powerpc64__ */
141 /* Save the prom pointer at p_prom. */
142 std r5,(p_prom-p_base)(r10)
143
144 /* Set r2 to the TOC. */
145 ld r2,(p_toc-p_base)(r10)
146 add r2,r2,r10
147
148 /* Grab the link address of the dynamic section in r11. */
149 ld r11,-32768(r2)
150 cmpwi r11,0
151 beq 3f /* if not linked -pie then no dynamic section */
152
153 ld r11,(p_dyn-p_base)(r10)
154 add r11,r11,r10
155 ld r9,(p_rela-p_base)(r10)
156 add r9,r9,r10
157
158 li r7,0
159 li r8,0
1609: ld r6,0(r11) /* get tag */
161 cmpdi r6,0
162 beq 12f /* end of list */
163 cmpdi r6,RELA
164 bne 10f
165 ld r7,8(r11) /* get RELA pointer in r7 */
166 b 11f
16710: addis r6,r6,(-RELACOUNT)@ha
168 cmpdi r6,RELACOUNT@l
169 bne 11f
170 ld r8,8(r11) /* get RELACOUNT value in r8 */
17111: addi r11,r11,16
172 b 9b
17312:
174 cmpdi r7,0 /* check we have both RELA and RELACOUNT */
175 cmpdi cr1,r8,0
176 beq 3f
177 beq cr1,3f
178
179 /* Calcuate the runtime offset. */
180 subf r7,r7,r9
123 181
182 /* Run through the list of relocations and process the
183 * R_PPC64_RELATIVE ones. */
184 mtctr r8
18513: ld r0,8(r9) /* ELF64_R_TYPE(reloc->r_info) */
186 cmpdi r0,22 /* R_PPC64_RELATIVE */
187 bne 3f
188 ld r6,0(r9) /* reloc->r_offset */
189 ld r0,16(r9) /* reloc->r_addend */
190 add r0,r0,r7
191 stdx r0,r7,r6
192 addi r9,r9,24
193 bdnz 13b
194
195 /* Do a cache flush for our text, in case the loader didn't */
1963: ld r9,p_start-p_base(r10) /* note: these are relocated now */
197 ld r8,p_etext-p_base(r10)
1984: dcbf r0,r9
199 icbi r0,r9
200 addi r9,r9,0x20
201 cmpld cr0,r9,r8
202 blt 4b
203 sync
204 isync
205
206 /* Clear the BSS */
207 ld r9,p_bss_start-p_base(r10)
208 ld r8,p_end-p_base(r10)
209 li r0,0
2105: std r0,0(r9)
211 addi r9,r9,8
212 cmpld cr0,r9,r8
213 blt 5b
214
215 /* Possibly set up a custom stack */
216 ld r8,p_pstack-p_base(r10)
217 cmpdi r8,0
218 beq 6f
219 ld r1,0(r8)
220 li r0,0
221 stdu r0,-16(r1) /* establish a stack frame */
2226:
223#endif /* __powerpc64__ */
124 /* Call platform_init() */ 224 /* Call platform_init() */
125 bl platform_init 225 bl platform_init
126 226