Problem with OF entry point

Benjamin Herrenschmidt benh at kernel.crashing.org
Tue Mar 9 21:10:26 EST 2004


Hi !

I've been chasing a problem where the G5 would die inside OF in some
weird ways when trying to open all displays on the system.

I finally found out that OF is fairly unhappy that we clobber SPRG2
in enter_prom() (entry.S). We do that to save our stack pointer which
is supposed to be "clobbered" by OF. We were also "restoring" more
registers than necessary in that code.

I made the assumption that since we are running in OF runtime env.,
our stack pointer is already a 32 bits value, so we don't bother
if it's top 32 bits are clobbered (cleared actually) by OF. So this
saving/restoring of SP looks completely useless to me. If this was
wrong, then we would be broken anyway since we pass to OF pointers
to things on the stack...

I've cleaned up the code a bit and produced that patch, which appear
to work fine on the G5. I'd appreciate some tests on other machines
along with comments in case I overlooked something. If things are
fine by tomorrow, I'll send this patch to Andrew/Linus.

(Dan: that will fix your dual screen boot bug)

Ben.

===== arch/ppc64/kernel/entry.S 1.30 vs edited =====
--- 1.30/arch/ppc64/kernel/entry.S	Mon Jan 19 17:28:26 2004
+++ edited/arch/ppc64/kernel/entry.S	Tue Mar  9 21:00:33 2004
@@ -570,11 +570,10 @@
 	 * 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 @@
 	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,20 @@
         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... */
-
-	mfspr	r1,SPRG2		/* Restore the stack pointer */
-	ld	r6,_MSR(r1)		/* Restore the MSR */
-	mtmsrd	r6
+	/* Restore arguments & enter PROM here... */
+	ld	r3,GPR3(r1)
+	blrl
+
+	/* Restore the MSR (back to 64 bits) */
+	ld	r0,_MSR(r1)
+	mtmsrd	r0
         isync

-	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 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 +638,10 @@
 	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) */


** Sent via the linuxppc64-dev mail list. See http://lists.linuxppc.org/





More information about the Linuxppc64-dev mailing list