From 8661a5ff71c9da30f9b89c10424a5b2a5828bc3f Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Tue, 9 Mar 2004 04:14:38 -0800 Subject: [PATCH] [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. --- arch/ppc64/kernel/entry.S | 59 +++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 30 deletions(-) diff --git a/arch/ppc64/kernel/entry.S b/arch/ppc64/kernel/entry.S index 84f41f686d6e..756bf61fcb26 100644 --- a/arch/ppc64/kernel/entry.S +++ b/arch/ppc64/kernel/entry.S @@ -570,11 +570,10 @@ _GLOBAL(enter_prom) * 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 @@ -592,20 +591,16 @@ _GLOBAL(enter_prom) 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 @@ -615,22 +610,25 @@ _GLOBAL(enter_prom) 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) @@ -645,9 +643,10 @@ _GLOBAL(enter_prom) 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) */ -- 2.39.5