Subject: Interrupt stack
To: None <port-sh3@NetBSD.org>
From: Valeriy E. Ushakov <uwe@stderr.spb.ru>
List: port-sh3
Date: 11/18/2007 03:19:48
--tThc/1wpZn/ma/RB
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

SH3 doesn't currently use dedicated interrupt stack.  Attached is a
patch I've been running with for a while now that introduces separate
interrupt stack for sh3.

Comments?

SY, Uwe
-- 
uwe@stderr.spb.ru                       |       Zu Grunde kommen
http://snark.ptc.spbu.ru/~uwe/          |       Ist zu Grunde gehen

--tThc/1wpZn/ma/RB
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="sh3-intrstack.diff"

Index: include/cpu.h
===================================================================
RCS file: /cvsroot/src/sys/arch/sh3/include/cpu.h,v
retrieving revision 1.47
diff -u -r1.47 cpu.h
--- include/cpu.h	17 Oct 2007 19:57:07 -0000	1.47
+++ include/cpu.h	18 Nov 2007 00:14:28 -0000
@@ -87,9 +87,11 @@
 	int	ssp;	/* stack pointer at time of interrupt */
 };
 
+extern uint32_t intsp;
+
 #define	CLKF_USERMODE(cf)	(!KERNELMODE((cf)->ssr))
 #define	CLKF_PC(cf)		((cf)->spc)
-#define	CLKF_INTR(cf)		0	/* XXX */
+#define	CLKF_INTR(cf)		((uint32_t)(cf)->ssp <= intsp)
 
 /*
  * This is used during profiling to integrate system time.  It can safely
Index: sh3/sh3_machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sh3/sh3/sh3_machdep.c,v
retrieving revision 1.66
diff -u -r1.66 sh3_machdep.c
--- sh3/sh3_machdep.c	17 Oct 2007 19:57:09 -0000	1.66
+++ sh3/sh3_machdep.c	18 Nov 2007 00:14:30 -0000
@@ -201,6 +201,10 @@
 	uvm_setpagesize();
 }
 
+
+uint32_t intstack, intfp, intsp;
+const vsize_t intstacksize = 3 * NBPG;
+
 /*
  * void sh_proc0_init(void):
  *	Setup proc0 u-area.
@@ -211,6 +215,12 @@
 	struct switchframe *sf;
 	vaddr_t u;
 
+	/* Steal interrupt stack */
+	intstack = uvm_pageboot_alloc(intstacksize);
+	memset((void *)intstack, 0, intstacksize);
+	intsp = intstack + intstacksize;
+	intfp = intstack + NBPG;
+
 	/* Steal process0 u-area */
 	u = uvm_pageboot_alloc(USPACE);
 	memset((void *)u, 0, USPACE);
Index: sh3/exception_vector.S
===================================================================
RCS file: /cvsroot/src/sys/arch/sh3/sh3/exception_vector.S,v
retrieving revision 1.33
diff -u -r1.33 exception_vector.S
--- sh3/exception_vector.S	17 Oct 2007 19:57:08 -0000	1.33
+++ sh3/exception_vector.S	18 Nov 2007 00:14:28 -0000
@@ -444,6 +444,9 @@
 #endif /* SH4 */
 
 
+#ifndef __NO_SH3_INTRSTACK
+#define SH3_INTRSTACK 1
+#endif
 /*
  * LINTSTUB: Var: char sh_vector_interrupt[1];
  *
@@ -453,6 +456,24 @@
 NENTRY(sh_vector_interrupt)
 	__EXCEPTION_ENTRY
 	stc	r0_bank, r6		! ssp - 3rd arg to intc_intr()
+
+#ifdef SH3_INTRSTACK
+	mov.l	.Li_intfp, r8
+	mov.l	@r8, r8
+	cmp/hi	r8, r14		! r14 > intfp ?
+	bf	1f		! if (r14 <= intfp) already on intstack
+
+	!! else - switch to the interrupt stack
+	mov.l	.Li_intsp, r9
+	mov.l	@r9, r9
+
+	mov.l	r15, @-r9
+	stc.l	r6_bank, @-r9
+	mov	r9, r15
+	ldc	r8, r6_bank	! intfp
+1:
+#endif /* SH3_INTRSTACK */
+
 	__INTR_MASK(r0, r1)
 	__EXCEPTION_UNBLOCK(r0, r1)	! enable exceptions for P3 access
 
@@ -465,6 +486,29 @@
 	jsr	@r0			! intc_intr(ssr, spc, ssp)
 	 mov.l	r3, @r2
 
+#ifdef SH3_INTRSTACK	
+	!! AST check should be run on lwp's stack, so that if
+	!! interrupted lwp is preemtped, it is later resumed on its
+	!! own stack, not on the intterupt stack
+	stc	r6_bank, r0
+	cmp/eq	r0, r8		! r6_bank == intfp?
+	bf	1f
+
+	mov	#0x10, r10
+	stc	sr, r11
+	swap.b	r10, r10
+	mov	r11, r2
+	swap.w	r10, r10	! r10 = PSL_BL
+	or	r10, r2
+	ldc	r2, sr		! block exceptions
+
+	ldc.l	@r15+, r6_bank
+	mov.l	@r15+, r15
+
+	ldc	r11, sr		! unblock exceptions
+1:
+#endif /* SH3_INTRSTACK */
+
 	mov.l	@(TF_SSR, r14), r2
 	mov.l	.Li_PSL_MD, r1
 	tst	r1, r2			! tf->tf_ssr & PSL_MD == 0 ?
@@ -495,6 +539,10 @@
 	__EXCEPTION_RETURN
 
 	.align	5
+#ifdef SH3_INTRSTACK
+.Li_intfp:		.long	_C_LABEL(intfp)
+.Li_intsp:		.long	_C_LABEL(intsp)
+#endif /* SH3_INTRSTACK */
 .Li_uvmexp_intrs:	.long	_C_LABEL(uvmexp) + UVMEXP_INTRS
 .Li_intc_intr:		.long	_C_LABEL(intc_intr)
 .Li_PSL_MD:		.long	0x40000000 /* PSL_MD */
Index: sh3/db_interface.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sh3/sh3/db_interface.c,v
retrieving revision 1.45
diff -u -r1.45 db_interface.c
--- sh3/db_interface.c	17 Oct 2007 19:57:07 -0000	1.45
+++ sh3/db_interface.c	18 Nov 2007 00:14:28 -0000
@@ -83,6 +83,7 @@
 
 static void db_frame_cmd(db_expr_t, bool, db_expr_t, const char *);
 static void __db_print_symbol(db_expr_t);
+static void __db_print_tfstack(struct trapframe *, struct trapframe *);
 
 #ifdef KSTACK_DEBUG
 static void db_stackcheck_cmd(db_expr_t, bool, db_expr_t, const char *);
@@ -533,6 +534,7 @@
 {
 	struct switchframe *sf = &curpcb->pcb_sf;
 	struct trapframe *tf, *tftop;
+	extern uint32_t intfp, intsp;	/* XXX */
 
 	/* Print switch frame */
 	db_printf("[switch frame]\n");
@@ -541,24 +543,41 @@
 		__db_print_symbol(sf->sf_ ## x)
 
 	SF(sr);
-	SF(r15);
-	SF(r14);
-	SF(r13);
-	SF(r12);
-	SF(r11);
-	SF(r10);
-	SF(r9);
-	SF(r8);
 	SF(pr);
+	SF(r8);
+	SF(r9);
+	SF(r10);
+	SF(r11);
+	SF(r12);
+	SF(r13);
+	SF(r14);
+	SF(r15);
 	db_printf("sf_r6_bank\t0x%08x\n", sf->sf_r6_bank);
 	db_printf("sf_r7_bank\t0x%08x\n", sf->sf_r7_bank);
+#undef	SF
 
 
 	/* Print trap frame stack */
-	db_printf("[trap frame]\n");
+	tftop = (struct trapframe *)((vaddr_t)curpcb + PAGE_SIZE);
 
 	__asm("stc r6_bank, %0" : "=r"(tf));
-	tftop = (struct trapframe *)((vaddr_t)curpcb + PAGE_SIZE);
+	if ((uint32_t)tf < intfp) {
+	    db_printf("[trap frames on interrupt stack]\n");
+	    __db_print_tfstack(tf, (void *)intfp);
+
+	    tf = *(struct trapframe **)((uint32_t *)intsp - 2);
+	}
+
+	db_printf("[trap frames]\n");
+	__db_print_tfstack(tf, tftop);
+}
+
+
+static void
+__db_print_tfstack(struct trapframe *tf, struct trapframe *tftop)
+{
+	db_printf("[[-- dumping frames from 0x%08x to 0x%08x --]]\n",
+		  (uint32_t)tf, (uint32_t)tftop);
 
 	for (; tf != tftop; tf++) {
 		db_printf("-- %p-%p --\n", tf, tf + 1);
@@ -568,32 +587,32 @@
 		__db_print_symbol(tf->tf_ ## x)
 
 		TF(ubc);
-		TF(spc);
 		TF(ssr);
+		TF(spc);
+		TF(pr);
 		TF(macl);
 		TF(mach);
-		TF(pr);
-		TF(r13);
-		TF(r12);
-		TF(r11);
-		TF(r10);
-		TF(r9);
-		TF(r8);
-		TF(r7);
-		TF(r6);
-		TF(r5);
-		TF(r4);
-		TF(r3);
-		TF(r2);
-		TF(r1);
 		TF(r0);
-		TF(r15);
+		TF(r1);
+		TF(r2);
+		TF(r3);
+		TF(r4);
+		TF(r5);
+		TF(r6);
+		TF(r7);
+		TF(r8);
+		TF(r9);
+		TF(r10);
+		TF(r11);
+		TF(r12);
+		TF(r13);
 		TF(r14);
-	}
-#undef	SF
+		TF(r15);
 #undef	TF
+	}
 }
 
+
 static void
 __db_print_symbol(db_expr_t value)
 {

--tThc/1wpZn/ma/RB--