Commit 8661a5ff authored by Benjamin Herrenschmidt's avatar Benjamin Herrenschmidt Committed by Linus Torvalds

[PATCH] ppc64: Fix occasional crash at boot in OF interface

The assembly code used to callback into Open Firmware client
interface in 32 bits mode used to backup the stack pointer in
the SPRG2 register.

That upsets Apple's implementation of Open Firmware significantly
and maybe others, causing them to crash in _some_ operations,
apparently the trigger is to cause a segment or hash table
fault, typically happens when letting that code initialize the
second display.

This patch fixes it, along with other cleanups of that asm code,
it did unnecessary register restores and backing up the stack
pointer is actually useless anyway.
parent 6fb338db
...@@ -570,11 +570,10 @@ _GLOBAL(enter_prom) ...@@ -570,11 +570,10 @@ _GLOBAL(enter_prom)
* of all registers that it saves. We therefore save those registers * of all registers that it saves. We therefore save those registers
* PROM might touch to the stack. (r0, r3-r13 are caller saved) * PROM might touch to the stack. (r0, r3-r13 are caller saved)
*/ */
SAVE_8GPRS(2, r1) /* Save the TOC & incoming param(s) */ SAVE_8GPRS(2, r1)
SAVE_GPR(13, r1) /* Save paca */ SAVE_GPR(13, r1)
SAVE_8GPRS(14, r1) /* Save the non-volatiles */ SAVE_8GPRS(14, r1)
SAVE_10GPRS(22, r1) /* ditto */ SAVE_10GPRS(22, r1)
mfcr r4 mfcr r4
std r4,_CCR(r1) std r4,_CCR(r1)
mfctr r5 mfctr r5
...@@ -592,20 +591,16 @@ _GLOBAL(enter_prom) ...@@ -592,20 +591,16 @@ _GLOBAL(enter_prom)
mfmsr r11 mfmsr r11
std r11,_MSR(r1) std r11,_MSR(r1)
/* Unfortunatly, the stack pointer is also clobbered, so it is saved /* Get the PROM entrypoint */
* in the SPRG2 which allows us to restore our original state after
* PROM returns.
*/
mtspr SPRG2,r1
/* put a relocation offset into r3 */
bl .reloc_offset bl .reloc_offset
LOADADDR(r12,prom) LOADADDR(r12,prom)
sub r12,r12,r3 sub r12,r12,r3
ld r12,PROMENTRY(r12) /* get the prom->entry value */ ld r12,PROMENTRY(r12)
mtlr r12 mtlr r12
mfmsr r11 /* grab the current MSR */ /* Switch MSR to 32 bits mode
*/
mfmsr r11
li r12,1 li r12,1
rldicr r12,r12,MSR_SF_LG,(63-MSR_SF_LG) rldicr r12,r12,MSR_SF_LG,(63-MSR_SF_LG)
andc r11,r11,r12 andc r11,r11,r12
...@@ -615,22 +610,25 @@ _GLOBAL(enter_prom) ...@@ -615,22 +610,25 @@ _GLOBAL(enter_prom)
mtmsrd r11 mtmsrd r11
isync isync
REST_8GPRS(2, r1) /* Restore the TOC & param(s) */ /* Restore arguments & enter PROM here... */
REST_GPR(13, r1) /* Restore paca */ ld r3,GPR3(r1)
REST_8GPRS(14, r1) /* Restore the non-volatiles */ blrl
REST_10GPRS(22, r1) /* ditto */
blrl /* Entering PROM here... */
mfspr r1,SPRG2 /* Restore the stack pointer */ /* Just make sure that r1 top 32 bits didn't get
ld r6,_MSR(r1) /* Restore the MSR */ * corrupt by OF
mtmsrd r6 */
isync rldicl r1,r1,0,32
REST_GPR(2, r1) /* Restore the TOC */ /* Restore the MSR (back to 64 bits) */
REST_GPR(13, r1) /* Restore paca */ ld r0,_MSR(r1)
REST_8GPRS(14, r1) /* Restore the non-volatiles */ mtmsrd r0
REST_10GPRS(22, r1) /* ditto */ isync
/* Restore other registers */
REST_GPR(2, r1)
REST_GPR(13, r1)
REST_8GPRS(14, r1)
REST_10GPRS(22, r1)
ld r4,_CCR(r1) ld r4,_CCR(r1)
mtcr r4 mtcr r4
ld r5,_CTR(r1) ld r5,_CTR(r1)
...@@ -645,9 +643,10 @@ _GLOBAL(enter_prom) ...@@ -645,9 +643,10 @@ _GLOBAL(enter_prom)
mtsrr0 r9 mtsrr0 r9
ld r10,_SRR1(r1) ld r10,_SRR1(r1)
mtsrr1 r10 mtsrr1 r10
addi r1,r1,PROM_FRAME_SIZE
ld r0,16(r1) /* get return address */
addi r1,r1,PROM_FRAME_SIZE
ld r0,16(r1)
mtlr r0 mtlr r0
blr /* return to caller */ blr
#endif /* defined(CONFIG_PPC_PSERIES) */ #endif /* defined(CONFIG_PPC_PSERIES) */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment