Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 21 Jan 2015 19:07:46 +0000 (UTC)
From:      Nathan Whitehorn <nwhitehorn@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r277498 - in head/sys/powerpc: aim include
Message-ID:  <201501211907.t0LJ7kBl070713@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: nwhitehorn
Date: Wed Jan 21 19:07:45 2015
New Revision: 277498
URL: https://svnweb.freebsd.org/changeset/base/277498

Log:
  Make 64-bit AIM trap handlers relocatable by changing all absolute branch
  instructions to call through pointers instead. In general, these are set
  implicitly through relocation processing. One has to be set explicitly in
  machdep.c, however, to fit one handler in the tiny (8 instruction) space
  available.
  
  Reviewed by:	andreast
  Differential revision:	D1554
  Tested on:	UP and SMP G5, Cell, POWER5+

Modified:
  head/sys/powerpc/aim/machdep.c
  head/sys/powerpc/aim/trap_subr64.S
  head/sys/powerpc/include/trap.h

Modified: head/sys/powerpc/aim/machdep.c
==============================================================================
--- head/sys/powerpc/aim/machdep.c	Wed Jan 21 19:04:55 2015	(r277497)
+++ head/sys/powerpc/aim/machdep.c	Wed Jan 21 19:07:45 2015	(r277498)
@@ -238,7 +238,7 @@ extern void	*trapcode64;
 #endif
 
 extern void	*rstcode, *rstsize;
-extern void	*trapcode, *trapsize;
+extern void	*trapcode, *trapsize, *trapcode2;
 extern void	*slbtrap, *slbtrapsize;
 extern void	*alitrap, *alisize;
 extern void	*dsitrap, *dsisize;
@@ -506,6 +506,7 @@ powerpc_init(vm_offset_t fdt, vm_offset_
 	generictrap = &trapcode;
 
 	/* Set TOC base so that the interrupt code can get at it */
+	*((void **)TRAP_GENTRAP) = &trapcode2;
 	*((register_t *)TRAP_TOCBASE) = toc;
 	#endif
 

Modified: head/sys/powerpc/aim/trap_subr64.S
==============================================================================
--- head/sys/powerpc/aim/trap_subr64.S	Wed Jan 21 19:04:55 2015	(r277497)
+++ head/sys/powerpc/aim/trap_subr64.S	Wed Jan 21 19:07:45 2015	(r277498)
@@ -302,8 +302,13 @@ CNAME(rstcode):
 	insrdi	%r9,%r8,1,0
 	mtmsrd	%r9
 	isync
+	bl	1f
+	.llong	cpu_reset
+1:	mflr	%r9
+	ld	%r9,0(%r9)
+	mtlr	%r9
 
-	ba	cpu_reset
+	blr
 CNAME(rstsize) = . - CNAME(rstcode)
 
 cpu_reset:
@@ -342,16 +347,20 @@ cpu_reset:
 
 /*
  * This code gets copied to all the trap vectors
- * (except ISI/DSI, ALI, and the interrupts)
+ * (except ISI/DSI, ALI, and the interrupts). Has to fit in 8 instructions!
  */
 
 	.globl	CNAME(trapcode),CNAME(trapsize)
+	.p2align 3
 CNAME(trapcode):
 	mtsprg1	%r1			/* save SP */
 	mflr	%r1			/* Save the old LR in r1 */
 	mtsprg2 %r1			/* And then in SPRG2 */
+	li	%r1,TRAP_GENTRAP
+	ld	%r1,0(%r1)
+	mtlr	%r1
 	li	%r1, 0xA0		/* How to get the vector from LR */
-	bla	generictrap		/* LR & SPRG3 is exception # */
+	blrl				/* Branch to generictrap */
 CNAME(trapsize) = .-CNAME(trapcode)
 
 /*
@@ -361,6 +370,7 @@ CNAME(trapsize) = .-CNAME(trapcode)
  * the only time this can be called.
  */
 	.globl	CNAME(slbtrap),CNAME(slbtrapsize)
+	.p2align 3
 CNAME(slbtrap):
 	mtsprg1	%r1			/* save SP */
 	GET_CPUINFO(%r1)
@@ -369,17 +379,31 @@ CNAME(slbtrap):
 	std	%r2,(PC_SLBSAVE+104)(%r1)
 	mfsrr1	%r2			/* test kernel mode */
 	mtcr	%r2
-	bf	17,1f			/* branch if PSL_PR is false */
+	bf	17,2f			/* branch if PSL_PR is false */
 	/* User mode */
 	ld	%r2,(PC_SLBSAVE+104)(%r1) /* Restore CR */
 	mtcr	%r2
 	ld	%r2,(PC_SLBSAVE+16)(%r1) /* Restore R2 */
 	mflr	%r1			/* Save the old LR in r1 */
 	mtsprg2 %r1			/* And then in SPRG2 */
+					/* 52 bytes so far */
+	bl	1f
+	.llong	generictrap
+1:	mflr	%r1
+	ld	%r1,0(%r1)
+	mtlr	%r1
 	li	%r1, 0x80		/* How to get the vector from LR */
-	bla	generictrap		/* LR & SPRG3 is exception # */
-1:	mflr	%r2			/* Save the old LR in r2 */
-	bla	kern_slbtrap
+	blrl				/* Branch to generictrap */
+					/* 84 bytes */
+2:	mflr	%r2			/* Save the old LR in r2 */
+	nop
+	bl	3f			/* Begin dance to jump to kern_slbtrap*/
+	.llong	kern_slbtrap
+3:	mflr	%r1
+	ld	%r1,0(%r1)
+	mtlr	%r1
+	GET_CPUINFO(%r1)
+	blrl				/* 124 bytes -- 4 to spare */
 CNAME(slbtrapsize) = .-CNAME(slbtrap)
 
 kern_slbtrap:
@@ -518,6 +542,16 @@ CNAME(alitrap):
 	mflr	%r28			/* save LR */
 	mfcr	%r29			/* save CR */
 
+	/* Begin dance to branch to s_trap in a bit */
+	b	1f
+	.p2align 3
+1:	nop
+	bl	1f
+	.llong	s_trap
+1:	mflr	%r31
+	ld	%r31,0(%r31)
+	mtlr	%r31
+
 	/* Put our exception vector in SPRG3 */
 	li	%r31, EXC_ALI
 	mtsprg3	%r31
@@ -525,13 +559,12 @@ CNAME(alitrap):
 	/* Test whether we already had PR set */
 	mfsrr1	%r31
 	mtcr	%r31
-	bla	s_trap
+	blrl
 CNAME(alisize) = .-CNAME(alitrap)
 
 /*
  * Similar to the above for DSI
- * Has to handle BAT spills
- * and standard pagetable spills
+ * Has to handle standard pagetable spills
  */
 	.globl	CNAME(dsitrap),CNAME(dsisize)
 CNAME(dsitrap):
@@ -542,14 +575,18 @@ CNAME(dsitrap):
 	std	%r29,(PC_DISISAVE+CPUSAVE_R29)(%r1)
 	std	%r30,(PC_DISISAVE+CPUSAVE_R30)(%r1)
 	std	%r31,(PC_DISISAVE+CPUSAVE_R31)(%r1)
-	mfsprg1	%r1			/* restore SP */
 	mfcr	%r29			/* save CR */
 	mfxer	%r30			/* save XER */
 	mtsprg2	%r30			/* in SPRG2 */
 	mfsrr1	%r31			/* test kernel mode */
 	mtcr	%r31
 	mflr	%r28			/* save LR (SP already saved) */
-	bla	disitrap
+	bl	1f			/* Begin branching to disitrap */
+	.llong	disitrap
+1:	mflr	%r1
+	ld	%r1,0(%r1)
+	mtlr	%r1
+	blrl				/* Branch to generictrap */
 CNAME(dsisize) = .-CNAME(dsitrap)
 
 /*
@@ -624,7 +661,7 @@ realtrap:
 	bl	restore_kernsrs		/* enable kernel mapping */
 	mfsprg2	%r29
 	mr	%r28,%r27
-	ba s_trap
+	b	s_trap
 
 /*
  * generictrap does some standard setup for trap handling to minimize
@@ -636,6 +673,8 @@ realtrap:
  * SPRG2 - Original LR
  */
 
+	.globl	CNAME(trapcode2)
+trapcode2:
 generictrap:
 	/* Save R1 for computing the exception vector */
 	mtsprg3 %r1
@@ -657,6 +696,7 @@ generictrap:
 	mfsprg3 %r31
 	ori	%r31,%r31,0xff00
 	mflr	%r30
+	addi	%r30,%r30,-4 /* The branch instruction, not the next */
 	and	%r30,%r30,%r31
 	mtsprg3	%r30
 
@@ -804,9 +844,16 @@ CNAME(dblow):
         mfsprg2	%r29			/* ... and r29 */
         mflr	%r1			/* save LR */
 	mtsprg2 %r1			/* And then in SPRG2 */
+
+	nop				/* Begin branching to generictrap */
+	bl	9f
+	.llong	generictrap
+9:	mflr	%r1
+	ld	%r1,0(%r1)
+	mtlr	%r1
 	li	%r1, 0	 		/* How to get the vector from LR */
+	blrl				/* Branch to generictrap */
 
-        bla     generictrap		/* and we look like a generic trap */
 1:
 	GET_CPUINFO(%r1)
 	std	%r27,(PC_DBSAVE+CPUSAVE_R27)(%r1)	/* free r27 */
@@ -816,6 +863,11 @@ CNAME(dblow):
         std	%r30,(PC_DBSAVE+CPUSAVE_R30)(%r1)	/* free r30 */
         std	%r31,(PC_DBSAVE+CPUSAVE_R31)(%r1)	/* free r31 */
         mflr	%r28					/* save LR */
-	bla	dbtrap
+	bl	9f					/* Begin branch */
+	.llong	dbtrap
+9:	mflr	%r1
+	ld	%r1,0(%r1)
+	mtlr	%r1
+	blrl				/* Branch to generictrap */
 CNAME(dbsize) = .-CNAME(dblow)
 #endif /* KDB */

Modified: head/sys/powerpc/include/trap.h
==============================================================================
--- head/sys/powerpc/include/trap.h	Wed Jan 21 19:04:55 2015	(r277497)
+++ head/sys/powerpc/include/trap.h	Wed Jan 21 19:07:45 2015	(r277498)
@@ -123,7 +123,8 @@
 /* DTrace trap opcode. */
 #define EXC_DTRACE	0x7c810808
 
-/* Magic pointer to store TOC base for trap handlers on ppc64 */
+/* Magic pointer to store TOC base and other info for trap handlers on ppc64 */
+#define TRAP_GENTRAP	0x1f0
 #define TRAP_TOCBASE	0x1f8
 
 #ifndef LOCORE



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201501211907.t0LJ7kBl070713>