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--