[parisc-linux] parisc64 head.S patch

Grant Grundler grundler@cup.hp.com
Tue, 6 Feb 2001 22:55:14 -0800 (PST)


Hi folks,
This patch is another step towards enabling SMP.
Please review and comment.

NOTE: head.S are seperate files for parisc and parisc64.

The basic change here is PDC_PSW is called to set DEFAULT_PSW bit to wide.
This *must* happen before RFIing to virtual mode. The first
thing the RFI does is cause a trap where we need land with both
feet on the ground (ie in wide mode).

Currently, PALO does this when it loads an ELF64 binary.  But since
the PDC call only applies to the CPU making the call, under SMP, all
slave CPU's have to do this too.
Paul Bame and I agree it's reasonable for PALO to not make this PDC call
and the PDC call should be in the common path between Monarch (or !SMP)
and Slave (enabled CONFIG_SMP) CPU's. Eventually, Paul intends to remove
the call from PALO.

The rest of the changes are cleanup (eg use of load32 macro)
and drop the smp_callin_rtn() which will never get invoked.

I wasn't 100% sure of one thing: usage of "TASK_PT_GR26-TASK_SZ_ALGN"
and %sp usage. I think it is and also suspect it doesn't really matter
at this point.

This code was only tested on an A500 and CONFIG_SMP=n.
(and with the init_new_context() patch from matthew)
The kernel booted fine w/o new complaints.

thanks,
grant


Index: arch/parisc64/kernel/head.S
===================================================================
RCS file: /home/cvs/parisc/linux/arch/parisc64/kernel/head.S,v
retrieving revision 1.4
diff -u -p -r1.4 head.S
--- head.S	2001/01/28 13:39:15	1.4
+++ head.S	2001/02/07 06:21:11
@@ -21,6 +21,7 @@
 
 #include <asm/assembly.h>
 #include <asm/pgtable.h>
+#include <asm/pdc.h>		/* for PDC_PSW defines */
 
 
 	.level 2.0
@@ -88,14 +89,19 @@ $pgt_fill_loop:
 	bb,>=		%r3,8,$pgt_fill_loop
 	nop
 
-	/* Load the return address...er...crash 'n burn */
-	copy		%r0,%r2
-
 	/* And the RFI Target address too */
 	load32		start_parisc, %r11
 
 	/* And the stack pointer too */
-	load32		init_task_union+TASK_SZ_ALGN,%sp
+	load32		PA(init_task_union+TASK_SZ_ALGN),%sp
+
+	/* Act like PDC just called us - that's how slave CPUs enter */
+#define MEM_PDC_LO 0x388
+#define MEM_PDC_HI 0x35C
+	ldw		MEM_PDC_LO(%r0),%r6
+	ldw		MEM_PDC_HI(%r0),%r7
+	depd,z		%r7, 31, 32, %r3	/* move to upper word */
+	or		%r6, %r3, %r3		/* combine both parts */
 
 #ifdef CONFIG_SMP
 	/* Set the smp rendevous address into page zero.
@@ -114,21 +120,56 @@ $pgt_fill_loop:
 	/*
 	** Code Common to both Monarch and Slave processors.
 	** Entry:
-	**    %r11 must contain RFI target address.
-	**    %r25/%r26 args to pass to target function
-	**    %r2  in case rfi target decides it didn't like something
+	**    %r3	PDCE_PROC address
+	**    %r11	RFI target address.
+	**    %r26-%r23 args to pass to target function
 	**
 	** Caller must init: SR4-7, %sp, %r10, %cr24/25, 
 	*/
 common_stext:
 	.proc
 	.callinfo
-#else
+#else /* CONFIG_SMP */
 	/* Clear PDC's CPU handoff address - we won't use it */
 	stw		%r0,0x10(%r0)	/* MEM_RENDEZ */
 	stw		%r0,0x28(%r0)	/* MEM_RENDEZ_HI */
-#endif
+#endif /* CONFIG_SMP */
+
+	/* Save parameters from PALO/PDC */
+	std		%arg0, TASK_PT_GR26-TASK_SZ_ALGN(%sp)
+	std		%arg1, TASK_PT_GR25-TASK_SZ_ALGN(%sp)
+	std		%arg2, TASK_PT_GR24-TASK_SZ_ALGN(%sp)
+	std		%arg3, TASK_PT_GR23-TASK_SZ_ALGN(%sp)
+	std		%r11,  TASK_PT_GR11-TASK_SZ_ALGN(%sp)
+
+	/* Set Wide mode as the "Default" (eg for traps)
+	** First trap occurs *right* after (or part of) rfi for slave CPUs.
+	** Someday, palo might not do this for the Monarch either.
+	*/
 
+	ldo		PDC_PSW(%r0),%arg0		/* 21 */
+	ldo		PDC_PSW_SET_DEFAULTS(%r0),%arg1	/* 2 */
+	ldo		PDC_PSW_WIDE_BIT(%r0),%arg2	/* 2 */
+
+	load32		PA(stext_pdc_ret), %rp
+
+	bv		(%r3)
+	copy		%r0,%arg3
+
+stext_pdc_ret:
+	/* restore PDC/PALO parameters */
+	ldd		TASK_PT_GR26-TASK_SZ_ALGN(%sp), %arg0
+	ldd		TASK_PT_GR25-TASK_SZ_ALGN(%sp), %arg1
+	ldd		TASK_PT_GR24-TASK_SZ_ALGN(%sp), %arg2
+	ldd		TASK_PT_GR23-TASK_SZ_ALGN(%sp), %arg3
+	ldd		TASK_PT_GR11-TASK_SZ_ALGN(%sp), %r11
+
+	std		%r0, TASK_PT_GR26-TASK_SZ_ALGN(%sp)
+	std		%r0, TASK_PT_GR25-TASK_SZ_ALGN(%sp)
+	std		%r0, TASK_PT_GR24-TASK_SZ_ALGN(%sp)
+	std		%r0, TASK_PT_GR23-TASK_SZ_ALGN(%sp)
+	std		%r0, TASK_PT_GR11-TASK_SZ_ALGN(%sp)
+
 	/* PARANOID: clear user scratch/user space SR's */
 	mtsp	%r0,%sr0
 	mtsp	%r0,%sr1
@@ -141,6 +182,9 @@ common_stext:
 	mtctl	%r0,%cr12
 	mtctl	%r0,%cr13
 
+	/* Prepare to RFI! Man all the cannons! */
+	tovirt		%sp
+
 	/* Initialize the global data pointer */
 	load32		__gp,%dp
 
@@ -208,14 +252,6 @@ aligned_rfi:
 	.import smp_init_current_idle_task,data
 	.import	smp_callin,code
 
-smp_callin_rtn:
-        .proc
-	.callinfo
-	break	1,1		/*  Break if returned from start_secondary */
-	nop
-	nop
-        .procend
-
 /***************************************************************************
 *
 * smp_slave_stext is executed by all non-monarch Processors when the Monarch
@@ -239,32 +275,19 @@ smp_slave_stext:
 	mtsp	   %r0,%sr6
 	mtsp	   %r0,%sr7
 
-	/* Initialize the global data pointer */
-	ldil		L%__gp,%dp
-	ldo		R%__gp(%dp),%dp
-	depi		0, 31, 32, %dp
-
 	/*  Initialize the SP - monarch sets up smp_init_current_idle_task */
-	ldil		L%PA(smp_init_current_idle_task),%sp
-	ldo		R%PA(smp_init_current_idle_task)(%sp),%sp
-	depdi		0, 31, 32, %sp
-#ifdef __LP64__
+	load32		PA(smp_init_current_idle_task),%sp
 	ldd		0(%sp),%sp	/* load task address */
-#else
-	ldw		0(%sp),%sp	/* load task address */
-#endif
 	addil		L%TASK_SZ_ALGN,%sp	/* Stack is above task */
 	ldo		R%TASK_SZ_ALGN(%r1),%sp
 
 	/* point CPU to kernel page tables */
-	ldil		L%PA(swapper_pg_dir),%r4
-	ldo		R%PA(swapper_pg_dir)(%r4),%r4
-	depdi		0, 31, 32, %r4
+	load32		PA(swapper_pg_dir),%r4
 	mtctl		%r4,%cr24	/* Initialize kernel root pointer */
 	mtctl		%r4,%cr25	/* Initialize user root pointer */
 
-	/* Load RFI *return* address in case smp_callin bails */
-	load32		smp_callin_rtn, %r2
+	/* Setup PDCE_PROC entry */
+	copy		%arg0,%r3
 
 	/* Load RFI target address.  */
 	load32		smp_callin, %r11