qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH] PPC64: Make OpenBIOS interrupt handlers 64bit aware v2
@ 2009-02-28 16:45 Alexander Graf
  2009-02-28 18:41 ` [Qemu-devel] " Blue Swirl
  0 siblings, 1 reply; 2+ messages in thread
From: Alexander Graf @ 2009-02-28 16:45 UTC (permalink / raw)
  To: openbios; +Cc: Blue Swirl, qemu-devel, Laurent Vivier

[-- Attachment #1: Type: text/plain, Size: 756 bytes --]

While booting a 64bit kernel, there is a small timeframe where OF and  
the kernel communicate with each other. Within that timeframe, DSI/ISI  
interrupts may occur, because some memory is not mapped yet.

Right now in case that happens, we jump into the DSI/ISI interrupt  
handler which clobbers the high 32 bits of the kernel's registers. In  
order to circumvent that, let's save/restore all 64 bits of all kernel  
registers when we get a DSI/ISI interrupt.

This patch enables a PPC64 Linux kernel to boot up to the point where  
it tries to set up the SLB entries (slbmte), which is not yet  
implemented in qemu.

v2 implements handling for the HIOR register, bringing interrupt  
handlers to RAM.

Signed-off-by: Alexander Graf <alex@csgraf.de>


[-- Attachment #2.1: Type: text/html, Size: 972 bytes --]

[-- Attachment #2.2: ppc64-interrupt-handlers.patch --]
[-- Type: application/octet-stream, Size: 8545 bytes --]

Index: include/ppc/processor.h
===================================================================
--- include/ppc/processor.h	(revision 461)
+++ include/ppc/processor.h	(working copy)
@@ -92,6 +92,7 @@
 #define S_TBWL		284	/* Time base Upper/Lower (Writing) */
 #define S_TBWU		285
 #define S_PVR		287	/* Processor Version Register */
+#define S_HIOR		311	/* Hardware Interrupt Offset Register */
 #define S_IBAT0U	528
 #define S_IBAT0L	529
 #define S_IBAT1U	530
@@ -400,4 +401,10 @@
 
 #define SPRNUM_FLIP( v )	( (((v)>>5) & 0x1f) | (((v)<<5) & 0x3e0) )
 
+/* C helpers */
+
+#define __stringify_1(x)	#x
+#define __stringify(x)		__stringify_1(x)
+#define mtspr(rn, v)		asm volatile("mtspr " __stringify(rn) ",%0" : : "r" (v))
+
 #endif   /* _H_PROCESSOR */
Index: arch/ppc/qemu/init.c
===================================================================
--- arch/ppc/qemu/init.c	(revision 461)
+++ arch/ppc/qemu/init.c	(working copy)
@@ -32,6 +32,7 @@
 #include "libc/vsprintf.h"
 #define NO_QEMU_PROTOS
 #include "openbios/fw_cfg.h"
+#include "ppc/processor.h"
 
 #define UUID_FMT "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x"
 
@@ -238,7 +239,27 @@
     fword("finish-device");
 }
 
+/* In order to get 64 bit aware handlers that rescue all our
+   GPRs from getting truncated to 32 bits, we need to patch the
+   existing handlers so they jump to our 64 bit aware ones. */
 static void
+ppc64_patch_handlers(void)
+{
+    uint32_t *dsi = (uint32_t *)0x300UL;
+    uint32_t *isi = (uint32_t *)0x400UL;
+
+    // Patch the first DSI handler instruction to: ba 0x2000
+    *dsi = 0x48002002;
+
+    // Patch the first ISI handler instruction to: ba 0x2200
+    *isi = 0x48002202;
+
+    // Invalidate the cache lines
+    asm ( "icbi 0, %0" : : "r"(dsi) );
+    asm ( "icbi 0, %0" : : "r"(isi) );
+}
+
+static void
 cpu_970_init(const struct cpudef *cpu)
 {
     cpu_generic_init(cpu);
@@ -249,6 +270,15 @@
     fword("property");
 
     fword("finish-device");
+
+    /* The 970 is a PPC64 CPU, so we need to activate
+     * 64bit aware interrupt handlers */
+
+    ppc64_patch_handlers();
+
+    /* The 970 also implements the HIOR which we need to set to 0 */
+
+    mtspr(S_HIOR, 0);
 }
 
 static const struct cpudef ppc_defs[] = {
Index: arch/ppc/qemu/start.S
===================================================================
--- arch/ppc/qemu/start.S	(revision 461)
+++ arch/ppc/qemu/start.S	(working copy)
@@ -24,39 +24,155 @@
 #define ILLEGAL_VECTOR( v )	.org __vectors + v ; bl trap_error ;
 #define VECTOR( v, dummystr )	.org __vectors + v ; vector__##v
 
-#define EXCEPTION_PREAMBLE \
-	mtsprg1	r1 ;		/* scratch */ \
-	mfsprg0	r1 ;		/* exception stack in sprg0 */ \
-	addi	r1,r1,-80 ;	/* push exception frame */ \
+/* We're trying to use the same code for the ppc32 and ppc64 handlers here.
+ * On ppc32 we only save/restore the registers, C considers volatile.
+ *
+ * On ppc64 on the other hand, we have to save/restore all registers, because
+ * all OF code is 32 bits, which only saves/restores the low 32 bits of the
+ * registers it clobbers.
+ */
+
+#define EXCEPTION_PREAMBLE_TEMPLATE \
+	mtsprg1	r1 ;				/* scratch */ \
+	mfsprg0	r1 ;				/* exception stack in sprg0 */ \
+.ifc ULONG_SIZE, 8 ; \
+	addi	r1,r1,-(40 * ULONG_SIZE) ;	/* push exception frame */ \
+.else ; \
+	addi	r1,r1,-(20 * ULONG_SIZE) ;	/* push exception frame */ \
+.endif ; \
  \
-	stw	r0,0(r1) ;	/* save r0 */ \
+	stl	r0,(0 * ULONG_SIZE)(r1) ;	/* save r0 */ \
 	mfsprg1	r0 ; \
-	stw	r0,4(r1) ;	/* save r1 */ \
-	stw	r2,8(r1) ;	/* save r2 */ \
-	stw	r3,12(r1) ;	/* save r3 */ \
-	stw	r4,16(r1) ; \
-	stw	r5,20(r1) ; \
-	stw	r6,24(r1) ; \
-	stw	r7,28(r1) ; \
-	stw	r8,32(r1) ; \
-	stw	r9,36(r1) ; \
-	stw	r10,40(r1) ; \
-	stw	r11,44(r1) ; \
-	stw	r12,48(r1) ; \
+	stl	r0,(1 * ULONG_SIZE)(r1) ;	/* save r1 */ \
+	stl	r2,(2 * ULONG_SIZE)(r1) ;	/* save r2 */ \
+	stl	r3,(3 * ULONG_SIZE)(r1) ;	/* save r3 */ \
+	stl	r4,(4 * ULONG_SIZE)(r1) ; \
+	stl	r5,(5 * ULONG_SIZE)(r1) ; \
+	stl	r6,(6 * ULONG_SIZE)(r1) ; \
+	stl	r7,(7 * ULONG_SIZE)(r1) ; \
+	stl	r8,(8 * ULONG_SIZE)(r1) ; \
+	stl	r9,(9 * ULONG_SIZE)(r1) ; \
+	stl	r10,(10 * ULONG_SIZE)(r1) ; \
+	stl	r11,(11 * ULONG_SIZE)(r1) ; \
+	stl	r12,(12 * ULONG_SIZE)(r1) ; \
+.ifc ULONG_SIZE, 8 ; \
+	stl	r13,(17 * ULONG_SIZE)(r1) ; \
+	stl	r14,(18 * ULONG_SIZE)(r1) ; \
+	stl	r15,(19 * ULONG_SIZE)(r1) ; \
+	stl	r16,(20 * ULONG_SIZE)(r1) ; \
+	stl	r17,(21 * ULONG_SIZE)(r1) ; \
+	stl	r18,(22 * ULONG_SIZE)(r1) ; \
+	stl	r19,(23 * ULONG_SIZE)(r1) ; \
+	stl	r20,(24 * ULONG_SIZE)(r1) ; \
+	stl	r21,(25 * ULONG_SIZE)(r1) ; \
+	stl	r22,(26 * ULONG_SIZE)(r1) ; \
+	stl	r23,(27 * ULONG_SIZE)(r1) ; \
+	stl	r24,(28 * ULONG_SIZE)(r1) ; \
+	stl	r25,(29 * ULONG_SIZE)(r1) ; \
+	stl	r26,(30 * ULONG_SIZE)(r1) ; \
+	stl	r27,(31 * ULONG_SIZE)(r1) ; \
+	stl	r28,(32 * ULONG_SIZE)(r1) ; \
+	stl	r29,(33 * ULONG_SIZE)(r1) ; \
+	stl	r30,(34 * ULONG_SIZE)(r1) ; \
+	stl	r31,(35 * ULONG_SIZE)(r1) ; \
+.endif ; \
  \
 	mflr	r0 ; \
-	stw	r0,52(r1) ; \
+	stl	r0,(13 * ULONG_SIZE)(r1) ; \
 	mfcr	r0 ; \
-	stw	r0,56(r1) ; \
+	stl	r0,(14 * ULONG_SIZE)(r1) ; \
 	mfctr	r0 ; \
-	stw	r0,60(r1) ; \
+	stl	r0,(15 * ULONG_SIZE)(r1) ; \
 	mfxer	r0 ; \
-	stw	r0,64(r1) ; \
+	stl	r0,(16 * ULONG_SIZE)(r1) ; \
  \
 	/* 76(r1) unused */ \
-	addi	r1,r1,-16 ;	/* call conventions uses 0(r1) and 4(r1)... */
+	addi	r1,r1,-16 ;	/* C ABI uses 0(r1) and 4(r1)... */
 
+#define EXCEPTION_EPILOGUE_TEMPLATE \
+	addi	r1,r1,16 ;			/* pop ABI frame */ \
+\
+	ll	r0,(13 * ULONG_SIZE)(r1) ; \
+	mtlr	r0 ; \
+	ll	r0,(14 * ULONG_SIZE)(r1) ; \
+	mtcr	r0 ; \
+	ll	r0,(15 * ULONG_SIZE)(r1) ; \
+	mtctr	r0 ; \
+	ll	r0,(16 * ULONG_SIZE)(r1) ; \
+	mtxer	r0 ; \
+\
+	ll	r0,(0 * ULONG_SIZE)(r1) ; \
+	ll	r2,(2 * ULONG_SIZE)(r1) ; \
+	ll	r3,(3 * ULONG_SIZE)(r1) ; \
+	ll	r4,(4 * ULONG_SIZE)(r1) ; \
+	ll	r5,(5 * ULONG_SIZE)(r1) ; \
+	ll	r6,(6 * ULONG_SIZE)(r1) ; \
+	ll	r7,(7 * ULONG_SIZE)(r1) ; \
+	ll	r8,(8 * ULONG_SIZE)(r1) ; \
+	ll	r9,(9 * ULONG_SIZE)(r1) ; \
+	ll	r10,(10 * ULONG_SIZE)(r1) ; \
+	ll	r11,(11 * ULONG_SIZE)(r1) ; \
+	ll	r12,(12 * ULONG_SIZE)(r1) ; \
+.ifc ULONG_SIZE, 8 ; \
+	ll	r13,(17 * ULONG_SIZE)(r1) ; \
+	ll	r14,(18 * ULONG_SIZE)(r1) ; \
+	ll	r15,(19 * ULONG_SIZE)(r1) ; \
+	ll	r16,(20 * ULONG_SIZE)(r1) ; \
+	ll	r17,(21 * ULONG_SIZE)(r1) ; \
+	ll	r18,(22 * ULONG_SIZE)(r1) ; \
+	ll	r19,(23 * ULONG_SIZE)(r1) ; \
+	ll	r20,(24 * ULONG_SIZE)(r1) ; \
+	ll	r21,(25 * ULONG_SIZE)(r1) ; \
+	ll	r22,(26 * ULONG_SIZE)(r1) ; \
+	ll	r23,(27 * ULONG_SIZE)(r1) ; \
+	ll	r24,(28 * ULONG_SIZE)(r1) ; \
+	ll	r25,(29 * ULONG_SIZE)(r1) ; \
+	ll	r26,(30 * ULONG_SIZE)(r1) ; \
+	ll	r27,(31 * ULONG_SIZE)(r1) ; \
+	ll	r28,(32 * ULONG_SIZE)(r1) ; \
+	ll	r29,(33 * ULONG_SIZE)(r1) ; \
+	ll	r30,(34 * ULONG_SIZE)(r1) ; \
+	ll	r31,(35 * ULONG_SIZE)(r1) ; \
+.endif ; \
+	ll	r1,(1 * ULONG_SIZE)(r1) ;	/* restore stack at last */ \
+	rfi
 
+// PPC32
+
+#define ULONG_SIZE		4
+#define stl			stw
+#define ll			lwz
+
+.macro EXCEPTION_PREAMBLE
+	EXCEPTION_PREAMBLE_TEMPLATE
+.endm
+
+.macro EXCEPTION_EPILOGUE
+	EXCEPTION_EPILOGUE_TEMPLATE
+.endm
+
+#undef ULONG_SIZE
+#undef stl
+#undef ll
+
+// PPC64
+
+#define ULONG_SIZE		8
+#define stl			std
+#define ll			ld
+
+.macro EXCEPTION_PREAMBLE_64
+	EXCEPTION_PREAMBLE_TEMPLATE
+.endm
+
+.macro EXCEPTION_EPILOGUE_64
+	EXCEPTION_EPILOGUE_TEMPLATE
+.endm
+
+#undef ULONG_SIZE
+#undef stl
+#undef ll
+
 /************************************************************************/
 /*	vectors								*/
 /************************************************************************/
@@ -68,32 +184,8 @@
 	b	1b
 
 exception_return:
-	addi	r1,r1,16	// pop ABI frame
+	EXCEPTION_EPILOGUE
 
-	lwz	r0,52(r1)
-	mtlr	r0
-	lwz	r0,56(r1)
-	mtcr	r0
-	lwz	r0,60(r1)
-	mtctr	r0
-	lwz	r0,64(r1)
-	mtxer	r0
-
-	lwz	r0,0(r1)	// restore r0
-	lwz	r2,8(r1)	// restore r2
-	lwz	r3,12(r1)	// restore r3
-	lwz	r4,16(r1)
-	lwz	r5,20(r1)
-	lwz	r6,24(r1)
-	lwz	r7,28(r1)
-	lwz	r8,32(r1)
-	lwz	r9,36(r1)
-	lwz	r10,40(r1)
-	lwz	r11,44(r1)
-	lwz	r12,48(r1)
-	lwz	r1,4(r1)	// restore r1
-	rfi
-
 	.globl	__divide_error
 __divide_error:
 trap_error:
@@ -150,6 +242,22 @@
 ILLEGAL_VECTOR( 0x1600 )
 ILLEGAL_VECTOR( 0x1700 )
 
+VECTOR( 0x2000, "DSI_64" ):
+	EXCEPTION_PREAMBLE_64
+	lis	r3,HA(dsi_exception)
+	addi	r3,r3,LO(dsi_exception)
+	mtctr	r3
+	bctrl
+	EXCEPTION_EPILOGUE_64
+
+VECTOR( 0x2200, "ISI_64" ):
+	EXCEPTION_PREAMBLE_64
+	lis	r3,HA(isi_exception)
+	addi	r3,r3,LO(isi_exception)
+	mtctr	r3
+	bctrl
+	EXCEPTION_EPILOGUE_64
+
 GLOBL(__vectors_end):
 
 /************************************************************************/

[-- Attachment #2.3: Type: text/html, Size: 134 bytes --]

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2009-02-28 18:41 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-02-28 16:45 [Qemu-devel] [PATCH] PPC64: Make OpenBIOS interrupt handlers 64bit aware v2 Alexander Graf
2009-02-28 18:41 ` [Qemu-devel] " Blue Swirl

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).