aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/boot/crt0.S
diff options
context:
space:
mode:
authorCédric Le Goater <clg@fr.ibm.com>2014-04-24 03:23:36 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2014-04-28 03:36:08 -0400
commit93d3921042988317e94b1bcc2e19844efe0b7356 (patch)
tree66cf4989366fe198c1394d24f1f912e39ef0df31 /arch/powerpc/boot/crt0.S
parent002c39dba3fc47b953101790d798f69150366738 (diff)
powerpc/boot: Define a routine to enter prom
This patch defines a 'prom' routine similar to 'enter_prom' in the kernel. The difference is in the MSR which is built before entering prom. Big endian order is enforced as in the kernel but 32bit mode is not. It prepares ground for the next patches which will introduce Little endian order. 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/crt0.S')
-rw-r--r--arch/powerpc/boot/crt0.S71
1 files changed, 71 insertions, 0 deletions
diff --git a/arch/powerpc/boot/crt0.S b/arch/powerpc/boot/crt0.S
index 0f7428a37efb..dbd99d064828 100644
--- a/arch/powerpc/boot/crt0.S
+++ b/arch/powerpc/boot/crt0.S
@@ -126,3 +126,74 @@ RELACOUNT = 0x6ffffff9
126 126
127 /* Call start */ 127 /* Call start */
128 b start 128 b start
129
130#ifdef __powerpc64__
131
132#define PROM_FRAME_SIZE 512
133#define SAVE_GPR(n, base) std n,8*(n)(base)
134#define REST_GPR(n, base) ld n,8*(n)(base)
135#define SAVE_2GPRS(n, base) SAVE_GPR(n, base); SAVE_GPR(n+1, base)
136#define SAVE_4GPRS(n, base) SAVE_2GPRS(n, base); SAVE_2GPRS(n+2, base)
137#define SAVE_8GPRS(n, base) SAVE_4GPRS(n, base); SAVE_4GPRS(n+4, base)
138#define SAVE_10GPRS(n, base) SAVE_8GPRS(n, base); SAVE_2GPRS(n+8, base)
139#define REST_2GPRS(n, base) REST_GPR(n, base); REST_GPR(n+1, base)
140#define REST_4GPRS(n, base) REST_2GPRS(n, base); REST_2GPRS(n+2, base)
141#define REST_8GPRS(n, base) REST_4GPRS(n, base); REST_4GPRS(n+4, base)
142#define REST_10GPRS(n, base) REST_8GPRS(n, base); REST_2GPRS(n+8, base)
143
144/* prom handles the jump into and return from firmware. The prom args pointer
145 is loaded in r3. */
146.globl prom
147prom:
148 mflr r0
149 std r0,16(r1)
150 stdu r1,-PROM_FRAME_SIZE(r1) /* Save SP and create stack space */
151
152 SAVE_GPR(2, r1)
153 SAVE_GPR(13, r1)
154 SAVE_8GPRS(14, r1)
155 SAVE_10GPRS(22, r1)
156 mfcr r10
157 std r10,8*32(r1)
158 mfmsr r10
159 std r10,8*33(r1)
160
161 /* remove MSR_LE from msr but keep MSR_SF */
162 mfmsr r10
163 rldicr r10,r10,0,62
164 mtsrr1 r10
165
166 /* Load FW address, set LR to label 1, and jump to FW */
167 bl 0f
1680: mflr r10
169 addi r11,r10,(1f-0b)
170 mtlr r11
171
172 ld r10,(p_prom-0b)(r10)
173 mtsrr0 r10
174
175 rfid
176
1771: /* Return from OF */
178
179 /* Restore registers and return. */
180 rldicl r1,r1,0,32
181
182 /* Restore the MSR (back to 64 bits) */
183 ld r10,8*(33)(r1)
184 mtmsr r10
185 isync
186
187 /* Restore other registers */
188 REST_GPR(2, r1)
189 REST_GPR(13, r1)
190 REST_8GPRS(14, r1)
191 REST_10GPRS(22, r1)
192 ld r10,8*32(r1)
193 mtcr r10
194
195 addi r1,r1,PROM_FRAME_SIZE
196 ld r0,16(r1)
197 mtlr r0
198 blr
199#endif