[OpenBIOS] [PATCH] ppc: fix mtmsr for SF setting

Alexander Graf agraf at suse.de
Fri Jun 17 00:14:54 CEST 2011


When running openbios-ppc32 on a ppc64 VM, we need to unset SF on every
interrupt to ensure that things still work.

So far we've been using mtmsr for this operation, but according to the
spec mtmsr doesn't set any bit above 32bit, so we were merely exploiting
a bug in qemu before.

This patch adds a runtime check on PVR to see if we're running on a 64-bit
capable CPU. If so, we use mtmsrd, which can set the high 32bits of MSR.

CC: Andreas Färber <andreas.faerber at web.de>
Signed-off-by: Alexander Graf <agraf at suse.de>
---
 arch/ppc/qemu/start.S |   50 +++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 42 insertions(+), 8 deletions(-)

diff --git a/arch/ppc/qemu/start.S b/arch/ppc/qemu/start.S
index 0d64568..70a4f92 100644
--- a/arch/ppc/qemu/start.S
+++ b/arch/ppc/qemu/start.S
@@ -37,9 +37,21 @@
 
 #define EXCEPTION_PREAMBLE_TEMPLATE \
 	mtsprg1	r1 ;				/* scratch */ \
+	mfcr	r1 ; \
+	mtsprg2	r1 ;				/* scratch */ \
+	mtsprg3	r2 ;				/* scratch */ \
+	mfpvr	r1 ; \
+	lis	r2, 0x330000 at h ;		/* lowest 64-bit PVR */ \
+	cmplw	r1, r2 ; \
+	blt	1f; \
+	oris    r2, r2, 0x70000000 at h ;		/* highest 64-bit PVR */ \
+	cmplw	r1, r2 ; \
+	bge	1f; \
+	\
 	mfmsr	r1 ;				/* unset MSR_SF */ \
 	clrlwi	r1,r1,0 ; \
-	mtmsr	r1 ; \
+	mtmsrd	r1 ; \
+1: \
 	mfsprg0	r1 ;				/* exception stack in sprg0 */ \
 .ifc ULONG_SIZE, 8 ; \
 	addi	r1,r1,-(40 * ULONG_SIZE) ;	/* push exception frame */ \
@@ -50,6 +62,7 @@
 	stl	r0,(0 * ULONG_SIZE)(r1) ;	/* save r0 */ \
 	mfsprg1	r0 ; \
 	stl	r0,(1 * ULONG_SIZE)(r1) ;	/* save r1 */ \
+	mfsprg3	r2 ; \
 	stl	r2,(2 * ULONG_SIZE)(r1) ;	/* save r2 */ \
 	stl	r3,(3 * ULONG_SIZE)(r1) ;	/* save r3 */ \
 	stl	r4,(4 * ULONG_SIZE)(r1) ; \
@@ -85,7 +98,7 @@
  \
 	mflr	r0 ; \
 	stl	r0,(13 * ULONG_SIZE)(r1) ; \
-	mfcr	r0 ; \
+	mfsprg2	r0 ; \
 	stl	r0,(14 * ULONG_SIZE)(r1) ; \
 	mfctr	r0 ; \
 	stl	r0,(15 * ULONG_SIZE)(r1) ; \
@@ -301,14 +314,12 @@ VECTOR( 0x100, "SRE" ):
 ILLEGAL_VECTOR( 0x200 )
 
 VECTOR( 0x300, "DSI" ):
-	EXCEPTION_PREAMBLE
-	b	call_dsi_exception
+	b	real_dsi
 
 ILLEGAL_VECTOR( 0x380 )
 
 VECTOR( 0x400, "ISI" ):
-	EXCEPTION_PREAMBLE
-	b	call_isi_exception
+	b	real_isi
 
 ILLEGAL_VECTOR( 0x480 )
 
@@ -359,6 +370,14 @@ VECTOR( 0x2200, "ISI_64" ):
 
 #endif
 
+real_dsi:
+	EXCEPTION_PREAMBLE
+	b	call_dsi_exception
+
+real_isi:
+	EXCEPTION_PREAMBLE
+	b	call_isi_exception
+
 GLOBL(__vectors_end):
 
 /************************************************************************/
@@ -368,10 +387,25 @@ GLOBL(__vectors_end):
 GLOBL(_entry):
 
 #ifdef CONFIG_PPC_64BITSUPPORT
-	/* clear MSR, disable MMU */
-
 	li	r0,0
+
+	mfpvr	r3
+	lis	r4, 0x330000 at h			/* lowest 64-bit PVR */
+	cmplw	r3, r4
+	blt	no_64bit
+	oris    r4, r4, 0x70000000 at h 		/* highest 64-bit PVR */
+	cmplw	r3, r4
+	bge	no_64bit
+
+	/* clear MSR, disable MMU, SF */
+	mtmsrd	r0
+	b	real_entry
+
+no_64bit:
+	/* clear MSR, disable MMU */
 	mtmsr	r0
+
+real_entry:
 #endif
 
 	/* copy exception vectors */
-- 
1.6.0.2




More information about the OpenBIOS mailing list