* of all registers that it saves. We therefore save those registers
* PROM might touch to the stack. (r0, r3-r13 are caller saved)
*/
- SAVE_8GPRS(2, r1) /* Save the TOC & incoming param(s) */
- SAVE_GPR(13, r1) /* Save paca */
- SAVE_8GPRS(14, r1) /* Save the non-volatiles */
- SAVE_10GPRS(22, r1) /* ditto */
-
+ SAVE_8GPRS(2, r1)
+ SAVE_GPR(13, r1)
+ SAVE_8GPRS(14, r1)
+ SAVE_10GPRS(22, r1)
mfcr r4
std r4,_CCR(r1)
mfctr r5
mfmsr r11
std r11,_MSR(r1)
- /* Unfortunatly, the stack pointer is also clobbered, so it is saved
- * in the SPRG2 which allows us to restore our original state after
- * PROM returns.
- */
- mtspr SPRG2,r1
-
- /* put a relocation offset into r3 */
+ /* Get the PROM entrypoint */
bl .reloc_offset
LOADADDR(r12,prom)
sub r12,r12,r3
- ld r12,PROMENTRY(r12) /* get the prom->entry value */
+ ld r12,PROMENTRY(r12)
mtlr r12
- mfmsr r11 /* grab the current MSR */
+ /* Switch MSR to 32 bits mode
+ */
+ mfmsr r11
li r12,1
rldicr r12,r12,MSR_SF_LG,(63-MSR_SF_LG)
andc r11,r11,r12
mtmsrd r11
isync
- REST_8GPRS(2, r1) /* Restore the TOC & param(s) */
- REST_GPR(13, r1) /* Restore paca */
- REST_8GPRS(14, r1) /* Restore the non-volatiles */
- REST_10GPRS(22, r1) /* ditto */
- blrl /* Entering PROM here... */
+ /* Restore arguments & enter PROM here... */
+ ld r3,GPR3(r1)
+ blrl
- mfspr r1,SPRG2 /* Restore the stack pointer */
- ld r6,_MSR(r1) /* Restore the MSR */
- mtmsrd r6
- isync
+ /* Just make sure that r1 top 32 bits didn't get
+ * corrupt by OF
+ */
+ rldicl r1,r1,0,32
- REST_GPR(2, r1) /* Restore the TOC */
- REST_GPR(13, r1) /* Restore paca */
- REST_8GPRS(14, r1) /* Restore the non-volatiles */
- REST_10GPRS(22, r1) /* ditto */
+ /* Restore the MSR (back to 64 bits) */
+ ld r0,_MSR(r1)
+ mtmsrd r0
+ isync
+ /* Restore other registers */
+ REST_GPR(2, r1)
+ REST_GPR(13, r1)
+ REST_8GPRS(14, r1)
+ REST_10GPRS(22, r1)
ld r4,_CCR(r1)
mtcr r4
ld r5,_CTR(r1)
mtsrr0 r9
ld r10,_SRR1(r1)
mtsrr1 r10
+
addi r1,r1,PROM_FRAME_SIZE
- ld r0,16(r1) /* get return address */
-
+ ld r0,16(r1)
mtlr r0
- blr /* return to caller */
+ blr
+
#endif /* defined(CONFIG_PPC_PSERIES) */