Module Name:    src
Committed By:   thorpej
Date:           Wed Feb 24 16:53:00 UTC 2021

Modified Files:
        src/sys/arch/powerpc/oea: ofw_subr.S ofwoea_machdep.c

Log Message:
Don't save the firmware's copy of SPRG[0-3], and don't fiddle with
SPRG[0-3] in the firmware trampoline.  Section 7.1 of the OpenFirmware
PowerPC CPU bindings says that firmware "client interface shall not modify"
when in virtual-mode, and "client interface shall preserve" in real-mode.

This is important because in vritual-mode, DSI exceptions will land in
the kernel's DSI exception handler, and that handler depends on the
kernel's SPRG0 value (it contains the pointer to the cpu_info for that
CPU).

Additionally, in the firmware trampoline, point curcpu at an empty
ofw_battable.  This ensures that the DSI exception handler won't
load a BAT register with a kernel block translation that clobbers
a segment translation owned by the firmware.  Eventually, this ofw_battable
might contain some of the larger translations owned by the firmware.


To generate a diff of this commit:
cvs rdiff -u -r1.17 -r1.18 src/sys/arch/powerpc/oea/ofw_subr.S
cvs rdiff -u -r1.53 -r1.54 src/sys/arch/powerpc/oea/ofwoea_machdep.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/powerpc/oea/ofw_subr.S
diff -u src/sys/arch/powerpc/oea/ofw_subr.S:1.17 src/sys/arch/powerpc/oea/ofw_subr.S:1.18
--- src/sys/arch/powerpc/oea/ofw_subr.S:1.17	Fri Feb 19 18:03:21 2021
+++ src/sys/arch/powerpc/oea/ofw_subr.S	Wed Feb 24 16:53:00 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: ofw_subr.S,v 1.17 2021/02/19 18:03:21 thorpej Exp $	*/
+/*	$NetBSD: ofw_subr.S,v 1.18 2021/02/24 16:53:00 thorpej Exp $	*/
 
 /*
  * Copyright (C) 1995, 1996 Wolfgang Solfrank.
@@ -52,7 +52,7 @@
 
 	/* MSR and SPRG[0-3] used in OpenFirmware */
 	.globl	ofwmsr
-	.comm	ofwmsr,20,4
+	.comm	ofwmsr,4,4
 
 #ifdef FIRMWORKSBUGS
 	.lcomm	ofwreal_incharge,4,4
@@ -101,16 +101,7 @@ ENTRY_NOPROFILE(ofwinit)
 	/* Save the MSR that OpenFirmware is using. */
 	mfmsr	%r0
 	lis	%r9,ofwmsr@ha
-	stwu	%r0,ofwmsr@l(%r9)
-
-	mfsprg0	%r0				/* save SPRGs */
-	stw	%r0,4(%r9)
-	mfsprg1	%r0
-	stw	%r0,8(%r9)
-	mfsprg2	%r0
-	stw	%r0,12(%r9)
-	mfsprg3	%r0
-	stw	%r0,16(%r9)
+	stw	%r0,ofwmsr@l(%r9)
 
 	lis	%r8,OF_buffer@ha
 	addi	%r8,%r8,OF_buffer@l
@@ -161,15 +152,6 @@ ENTRY_NOPROFILE(openfirmware_trampoline)
 	lwz	%r4,ofentry@l(%r4)
 	mtlr	%r4
 
-	mfsprg0	%r5			/* save current sprg0 (curcpu) */
-	stw	%r5,16(%r1)
-	mfsprg1	%r5			/* save current sprg1 */
-	stw	%r5,20(%r1)
-	mfsprg2	%r5			/* save current sprg1 */
-	stw	%r5,24(%r1)
-	mfsprg3	%r5			/* save current sprg3 */
-	stw	%r5,28(%r1)
-
 #ifdef FIRMWORKSBUGS
 	lis	%r4,ofwreal_incharge@ha
 	lwz	%r4,ofwreal_incharge@l(%r4)
@@ -214,21 +196,25 @@ ENTRY_NOPROFILE(openfirmware_trampoline)
 	cmpwi	%r5,0
 	bne	1b
 2:
-	lis	%r4,ofwmsr+16@ha	/* Open Firmware msr + sprg[0-3] */
-	lwzu	%r5,ofwmsr+16@l(%r4)
-	mtsprg3	%r5
-	lwz	%r5,-4(%r4)
-	mtsprg2	%r5
-	lwz	%r5,-8(%r4)
-	mtsprg1	%r5
-	lwz	%r5,-12(%r4)
-	mtsprg0	%r5
-	lwz	%r5,-16(%r4)
+	/* curcpu()->ci_battable = &ofw_battable */
+	GET_CPUINFO(%r4)
+	lis	%r5,_C_LABEL(ofw_battable)@ha
+	addi	%r5,%r5,_C_LABEL(ofw_battable)@l
+	stw	%r5,CI_BATTABLE(%r4)
+
+	lis	%r4,ofwmsr@ha		/* Open Firmware msr */
+	lwz	%r5,ofwmsr@l(%r4)
 	mtmsr	%r5
 	isync
 
 	blrl				/* call Open Firmware */
 
+	/* curcpu()->ci_battable = &battable */
+	GET_CPUINFO(%r4)
+	lis	%r5,_C_LABEL(battable)@ha
+	addi	%r5,%r5,_C_LABEL(battable)@l
+	stw	%r5,CI_BATTABLE(%r4)
+
 	lis	%r4,ofwsrsave@ha	/* restore saved SRs */
 	addi	%r4,%r4,ofwsrsave@l
 	li	%r5,0
@@ -243,15 +229,6 @@ ENTRY_NOPROFILE(openfirmware_trampoline)
 	mtmsr	%r4
 	isync
 4:	
-	lwz	%r5,16(%r1)		/* restore saved sprgs (curcpu) */
-	mtsprg0	%r5
-	lwz	%r5,20(%r1)
-	mtsprg1	%r5
-	lwz	%r5,24(%r1)
-	mtsprg2	%r5
-	lwz	%r5,28(%r1)
-	mtsprg3	%r5
-
 	addi	%r1,%r1,48		/* pop stack frame and save area */
 	lwz	%r0,4(%r1)		/* return address */
 	mtlr	%r0

Index: src/sys/arch/powerpc/oea/ofwoea_machdep.c
diff -u src/sys/arch/powerpc/oea/ofwoea_machdep.c:1.53 src/sys/arch/powerpc/oea/ofwoea_machdep.c:1.54
--- src/sys/arch/powerpc/oea/ofwoea_machdep.c:1.53	Fri Feb 19 18:10:51 2021
+++ src/sys/arch/powerpc/oea/ofwoea_machdep.c	Wed Feb 24 16:53:00 2021
@@ -1,4 +1,4 @@
-/* $NetBSD: ofwoea_machdep.c,v 1.53 2021/02/19 18:10:51 thorpej Exp $ */
+/* $NetBSD: ofwoea_machdep.c,v 1.54 2021/02/24 16:53:00 thorpej Exp $ */
 
 /*-
  * Copyright (c) 2007 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ofwoea_machdep.c,v 1.53 2021/02/19 18:10:51 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ofwoea_machdep.c,v 1.54 2021/02/24 16:53:00 thorpej Exp $");
 
 #include "ksyms.h"
 #include "wsdisplay.h"
@@ -100,7 +100,19 @@ typedef struct _rangemap {
 
 struct OF_translation ofw_translations[OFW_MAX_TRANSLATIONS];
 
+/*
+ * Data structures holding OpenFirmware's translations when running
+ * in virtual-mode.
+ *
+ * When we call into OpenFirmware, we point the calling CPU's
+ * cpu_info::ci_battable at ofw_battable[].  For now, this table
+ * is empty, which will ensure that any DSI exceptions that occur
+ * during the firmware call will not erroneously load kernel BAT
+ * mappings that could clobber the firmware's translations.
+ */
 struct pmap ofw_pmap;
+struct bat ofw_battable[BAT_VA2IDX(0xffffffff)+1];
+
 char bootpath[256];
 char model_name[64];
 #if NKSYMS || defined(DDB) || defined(MODULAR)

Reply via email to