Module Name:    src
Committed By:   thorpej
Date:           Thu Feb 18 16:29:12 UTC 2021

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

Log Message:
- Tidy up some comments.
- Use correct stack frame linkage everywhere so that if something goes
  wrong, we can get a meaningful back trace.
- Use an additional layer of indirection so that, when we're very
  early in bootstrap, we can just call OpenFirmware directly, rather
  than using our trampoline that saves/restores kernel state.
- Carve out a space for ofwinit() to call into C code to do additional
  initialization.  (This is not done yet.)


To generate a diff of this commit:
cvs rdiff -u -r1.13 -r1.14 src/sys/arch/powerpc/oea/ofw_subr.S

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.13 src/sys/arch/powerpc/oea/ofw_subr.S:1.14
--- src/sys/arch/powerpc/oea/ofw_subr.S:1.13	Sat Feb 13 01:48:33 2021
+++ src/sys/arch/powerpc/oea/ofw_subr.S	Thu Feb 18 16:29:12 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: ofw_subr.S,v 1.13 2021/02/13 01:48:33 thorpej Exp $	*/
+/*	$NetBSD: ofw_subr.S,v 1.14 2021/02/18 16:29:12 thorpej Exp $	*/
 
 /*
  * Copyright (C) 1995, 1996 Wolfgang Solfrank.
@@ -35,25 +35,43 @@
 #include "opt_ppcarch.h"
 #endif
 
-	.local	firmstk
-	.globl	openfirmware_entry
-	.globl	ofwmsr
-	.local	ofwsrsave
-	.local	OF_buffer
-
+	/* Stack used to call into OpenFirmware. */
 	.lcomm	firmstk,NBPG,16
+
+	/* Buffer used to pass data to/from OpenFirmware. */
 	.lcomm	OF_buffer,NBPG + 36,4
-	.comm	openfirmware_entry,4,4	/* openfirmware entry point */
-	.lcomm	ofwsrsave,64,4		/* openfirmware SR savearea */
-	.comm	ofwmsr,20,4		/* msr & sprg[0-3] used in OF */
-	.comm	ofwreal_incharge,4,4
+
+	/* The OpenFirmware entry point, provided by OpenFirmware. */
+	.lcomm	ofentry,4,4
+
+	/* Entry trampoline used by openfirmware(). */
+	.lcomm	oftramp,4,4
+
+	/* OpenFirmware SR save area */
+	.lcomm	ofwsrsave,64,4
+
+	/* MSR and SPRG[0-3] used in OpenFirmware */
+	.globl	ofwmsr
+	.comm	ofwmsr,20,4
 
 /*
  * Called by start to save the initial OFW state so we can restore it
  * when call back to OFW.
+ *
+ * We expect the registers to be as for the entry point into the kernel:
+ *
+ *	%r1	Stack provided by OpenFirmware / boot loader
+ *	%r5	OpenFirmware client entry point
+ *
+ * (others -- don't care)
  */
 ENTRY_NOPROFILE(ofwinit)
-#ifdef	FIRMWORKSBUGS
+	/* Save return address, Push a stack frame. */
+	mflr	%r0
+	stw	%r0,4(%r1)
+	stwu	%r1,-16(%r1)
+
+#ifdef FIRMWORKSBUGS
 	mfmsr	%r0
 	andi.	%r0,%r0,PSL_IR|PSL_DR
 	beq	1f
@@ -62,25 +80,24 @@ ENTRY_NOPROFILE(ofwinit)
 	lis	%r9,ofwreal_incharge@ha
 	stw	%r8,ofwreal_incharge@l(%r9)
 
-	mflr	%r30
 	bl	_C_LABEL(ofwr_init)
-	mtlr	%r30
 1:
 #endif
-	lis	%r8,openfirmware_entry@ha
-	stw	%r5,openfirmware_entry@l(%r8) /* save client interface handler*/
 
+	lis	%r8,ofentry@ha
+	stw	%r5,ofentry@l(%r8)	/* save client interface handler */
+
+	/*
+	 * Call directly into OpenFirmware until we're ready to use
+	 * the trampoline.
+	 */
+	lis	%r8,oftramp@ha
+	stw	%r5,oftramp@l(%r8)
+
+	/* Save the MSR that OpenFirmware is using. */
 	mfmsr	%r0
-/*
- * XXX
- * doing this here instead of later on in ofwoea_initppc() after setting
- * up the console and such makes my PowerBook 3400c hang.
- * Probably just another OF 2.0 weirdness
- */
-	/*li	%r8,PSL_IP*/
-	/*andc	%r0,%r0,%r8*/			/* make sure PSL_IP is off */
 	lis	%r9,ofwmsr@ha
-	stwu	%r0,ofwmsr@l(%r9)		/* save initial MSR value */
+	stwu	%r0,ofwmsr@l(%r9)
 
 	mfsprg0	%r0				/* save SPRGs */
 	stw	%r0,4(%r9)
@@ -96,28 +113,42 @@ ENTRY_NOPROFILE(ofwinit)
 	lis	%r9,_C_LABEL(OF_buf)@ha
 	stw	%r8,_C_LABEL(OF_buf)@l(%r9)
 
+	/* XXX Do other stuff in C code. */
+
+	/*
+	 * Jump off the trampoline for all subsequent calls
+	 * into OpenFirmware.
+	 */
+	lis	%r5,_C_LABEL(openfirmware_trampoline)@ha
+	addi	%r5,%r5,_C_LABEL(openfirmware_trampoline)@l
+	lis	%r8,oftramp@ha
+	stw	%r5,oftramp@l(%r8)
+
+	/* Retrieve LR, pop stack frame. */
+	addi	%r1,%r1,16
+	lwz	%r0,4(%r1)
+	mtlr	%r0
+
 	blr
 
 /*
- * OpenFirmware entry point
+ * OpenFirmware trampoline.  We are already on the OpenFirmware stack.
  */
-	.text
-ENTRY(openfirmware)
+ENTRY_NOPROFILE(openfirmware_trampoline)
 	mflr	%r0
 	stw	%r0,4(%r1)		/* save return address */
 
 	/*
-	 * Switch to OpenFirmware stack.
+	 * Push stack frame and save area:
 	 *
-	 * -48 == -16 to stack old SP and align, -32 for save area
+	 * [SP+8 save area]
+	 * [SP+4 slot for saved LR in callee]
+	 * [SP+0 saved SP]
 	 */
-	lis	%r7,firmstk+NBPG-48@ha
-	addi	%r7,%r7,firmstk+NBPG-48@l
-	stw	%r1,32(%r7)		/* stash away prev stack pointer */
-	mr	%r1,%r7
+	stwu	%r1,-48(%r1)
 
-	lis	%r4,openfirmware_entry@ha	/* get firmware entry point */
-	lwz	%r4,openfirmware_entry@l(%r4)
+	lis	%r4,ofentry@ha		/* get firmware entry point */
+	lwz	%r4,ofentry@l(%r4)
 	mtlr	%r4
 
 	mfsprg0	%r5			/* save current sprg0 (curcpu) */
@@ -211,7 +242,31 @@ ENTRY(openfirmware)
 	lwz	%r5,28(%r1)
 	mtsprg3	%r5
 
-	lwz	%r1,32(%r1)		/* restore previous stack pointer */
+	addi	%r1,%r1,48		/* pop stack frame and save area */
+	lwz	%r0,4(%r1)		/* return address */
+	mtlr	%r0
+	blr
+
+/*
+ * Call into OpenFirmware.
+ */
+ENTRY_NOPROFILE(openfirmware)
+	mflr	%r0
+	stw	%r0,4(%r1)		/* save return address */
+
+	/* Switch to OpenFirmware stack. */
+	lis	%r7,firmstk+NBPG-16@ha
+	addi	%r7,%r7,firmstk+NBPG-16@l
+	stw	%r1,0(%r7)		/* stash away prev stack pointer */
+	mr	%r1,%r7
+
+	lis	%r4,oftramp@ha
+	lwz	%r4,oftramp@l(%r4)
+
+	mtctr	%r4
+	bctrl
+
+	lwz	%r1,0(%r1)		/* restore previous stack pointer */
 	lwz	%r0,4(%r1)		/* return address */
 	mtlr	%r0
 	blr

Reply via email to