diff --git a/sys/arch/sun3/sun3/interrupt.s b/sys/arch/sun3/sun3/interrupt.s index ca92821ff0d2..fb6e0201fa27 100644 --- a/sys/arch/sun3/sun3/interrupt.s +++ b/sys/arch/sun3/sun3/interrupt.s @@ -1,4 +1,4 @@ -/* $NetBSD: interrupt.s,v 1.16 1994/12/12 18:59:59 gwr Exp $ */ +/* $NetBSD: interrupt.s,v 1.17 1995/01/11 20:31:30 gwr Exp $ */ /* * Copyright (c) 1994 Gordon W. Ross @@ -57,8 +57,8 @@ timebomb: INTERRUPT_RESTORE ;\ jra rei /* XXX - Just do rte here? */ -.globl _level0intr, _level1intr, _level2intr, _level3intr, _level4intr -.globl _level5intr, _level6intr, _level7intr +.globl _level0intr, _level1intr, _level2intr, _level3intr +.globl _level4intr, _level5intr, _level6intr, _level7intr .align 4 /* @@ -167,6 +167,17 @@ Lstackok: INTERRUPT_RESTORE jra rei + .globl _isr_vectored + .globl _vect_intr +_vect_intr: + INTERRUPT_SAVEREG + movw sp@(22),sp@- | push exception vector info + clrw sp@- + jbsr _isr_vectored | C dispatcher + addql #4,sp | + INTERRUPT_RESTORE + jra rei | all done + #undef INTERRUPT_SAVEREG #undef INTERRUPT_BODY diff --git a/sys/arch/sun3/sun3/isr.c b/sys/arch/sun3/sun3/isr.c index a41fd03da833..30891abbbb60 100644 --- a/sys/arch/sun3/sun3/isr.c +++ b/sys/arch/sun3/sun3/isr.c @@ -1,4 +1,4 @@ -/* $NetBSD: isr.c,v 1.14 1994/12/12 19:00:00 gwr Exp $ */ +/* $NetBSD: isr.c,v 1.15 1995/01/11 20:31:32 gwr Exp $ */ /* * Copyright (c) 1994 Gordon W. Ross @@ -31,6 +31,11 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* + * This handles multiple attach of autovectored interrupts, + * and the handy software interrupt request register. + */ + #include #include #include @@ -48,44 +53,21 @@ extern int intrcnt[]; /* statistics */ -/* - * Justification: - * - * the reason the interrupts are not initialized earlier is because of - * concerns that if it was done earlier then this might screw up the monitor. - * this may just be lame. - * - */ +#define NISR 8 + +struct isr { + struct isr *isr_next; + int (*isr_intr)(); + void *isr_arg; + int isr_ipl; +}; + +static struct isr *isr_autovec_list[NISR]; volatile u_char *interrupt_reg; -extern void level0intr(), level1intr(), level2intr(), level3intr(), - level4intr(), level5intr(), level6intr(), level7intr(); - -struct level_intr { - void (*level_intr)(); - int used; -} level_intr_array[NISR] = { - { level0intr, 0 }, /* this is really the spurious interrupt */ - { level1intr, 0 }, - { level2intr, 0 }, - { level3intr, 0 }, - { level4intr, 0 }, - { level5intr, 0 }, - { level6intr, 0 }, - { level7intr, 0 } -}; - - -struct isr *isr_array[NISR]; - void isr_init() { - int i; - - for (i = 0; i < NISR; i++) - isr_array[i] = NULL; - interrupt_reg = obio_find_mapping(OBIO_INTERREG, 1); if (!interrupt_reg) mon_panic("interrupt reg VA not found\n"); @@ -95,57 +77,9 @@ void isr_add_custom(level, handler) /* XXX */ int level; void (*handler)(); { - level_intr_array[level].used++; set_vector_entry(AUTO_VECTOR_BASE + level, handler); } - -void isr_activate(level) - int level; -{ - level_intr_array[level].used++; - set_vector_entry(AUTO_VECTOR_BASE + level, - level_intr_array[level].level_intr); -} - -void isr_cleanup() -{ - int i; - - for (i = 0; i = NISR)) - panic("isr_add: attempt to add handler for bad level"); - new_isr = (struct isr *) - malloc(sizeof(struct isr), M_DEVBUF, M_NOWAIT); - if (!new_isr) - panic("isr_add: allocation of new 'isr' failed"); - - new_isr->isr_arg = arg; - new_isr->isr_ipl = level; - new_isr->isr_intr = handler; - new_isr->isr_back = NULL; - new_isr->isr_forw = isr_array[level]; - if (!isr_array[level]) - first_isr++; - isr_array[level] = new_isr; - if (first_isr) - isr_activate(level); -} - static int isr_soft_pending; void isr_soft_request(level) int level; @@ -171,6 +105,7 @@ void isr_soft_request(level) *interrupt_reg |= IREG_ALL_ENAB; splx(s); } + void isr_soft_clear(level) int level; { @@ -192,38 +127,6 @@ void isr_soft_clear(level) splx(s); } -/* - * This is called by the first-level assembly routines - * for handling auto-vectored interupts. - */ -void isr_autovec(ipl) - int ipl; -{ - struct isr *isr; - int found; - - intrcnt[ipl]++; - cnt.v_intr++; - - isr = isr_array[ipl]; - if (!isr) { - printf("intrhand: unexpected ipl %d\n", ipl); - return; - } - if (!ipl) { - printf("intrhand: spurious interrupt\n"); - return; - } - /* Give all the handlers a chance. */ - found = 0; - while (isr) { - found |= isr->isr_intr(isr->isr_arg); - isr = isr->isr_forw; - } - if (!found) - printf("intrhand: stray interrupt, ipl %d\n", ipl); -} - /* * XXX - This really belongs in some common file, like * src/sys/net/netisr.c -gwr @@ -307,3 +210,124 @@ int soft1intr(fp) } return(0); } + + +/* + * This is called by the assembly routines + * for handling auto-vectored interupts. + */ +void isr_autovec(ipl) + int ipl; +{ + struct isr *isr; + register int n; + + n = intrcnt[ipl]; + intrcnt[ipl] = n+1; + cnt.v_intr++; + + isr = isr_autovec_list[ipl]; + if ((isr == NULL) && (n == 0)) { + printf("isr_autovec: ipl %d unexpected\n", ipl); + return; + } + /* Give all the handlers a chance. */ + n = 0; + while (isr) { + n |= isr->isr_intr(isr->isr_arg); + isr = isr->isr_next; + } + if (!n) + printf("isr_autovec: ipl %d not claimed\n", ipl); +} + +/* + * Establish an interrupt handler. + * Called by driver attach functions. + */ +void isr_add_autovect(handler, arg, level) + int (*handler)(); + void *arg; + int level; +{ + struct isr *new_isr; + + if ((level < 0) || (level >= NISR)) + panic("isr_add: bad level=%d", level); + new_isr = (struct isr *) + malloc(sizeof(struct isr), M_DEVBUF, M_NOWAIT); + if (!new_isr) + panic("isr_add: malloc failed"); + + new_isr->isr_intr = handler; + new_isr->isr_arg = arg; + new_isr->isr_ipl = level; + new_isr->isr_next = isr_autovec_list[level]; + isr_autovec_list[level] = new_isr; +} + +extern void badtrap(); +struct vector_handler { + int (*func)(); + void *arg; +}; +static struct vector_handler isr_vector_handlers[192]; + +/* + * This is called by the assembly glue + * for handling vectored interupts. + */ +void +isr_vectored(evec) + u_short evec; +{ + int ipl, vec = evec >> 4; + struct vector_handler *vh; + + ipl = getsr(); + ipl = (ipl >> 8) & 7; + + intrcnt[ipl]++; + cnt.v_intr++; + + if (vec < 64 || vec >= 256) { + printf("isr_vectored: vector=0x%x (invalid)\n", vec); + return; + } + vh = &isr_vector_handlers[vec - 64]; + if (vh->func == NULL) { + printf("isr_vectored: vector=0x%x (nul func)\n", vec); + set_vector_entry(vec, badtrap); + return; + } + + /* OK, call the isr function. */ + if (vh->func(vh->arg) == 0) + printf("isr_vectored: vector=0x%x (not claimed)\n", vec); +} + +/* + * Establish an interrupt handler. + * Called by driver attach functions. + */ +extern void vect_intr(); +void isr_add_vectored(func, arg, level, vec) + int (*func)(); + void *arg; + int level, vec; +{ + struct vector_handler *vh; + + if (vec < 64 || vec >= 256) { + printf("isr_add_vectored: vect=0x%x (invalid)\n", vec); + return; + } + vh = &isr_vector_handlers[vec - 64]; + if (vh->func) { + printf("isr_add_vectored: vect=0x%x (in use)\n", vec); + return; + } + vh->func = func; + vh->arg = arg; + set_vector_entry(vec, vect_intr); +} diff --git a/sys/arch/sun3/sun3/vector.c b/sys/arch/sun3/sun3/vector.c index 450fbf1ec079..baf5e4cce15b 100644 --- a/sys/arch/sun3/sun3/vector.c +++ b/sys/arch/sun3/sun3/vector.c @@ -1,4 +1,4 @@ -/* $NetBSD: vector.c,v 1.10 1994/11/21 21:39:19 gwr Exp $ */ +/* $NetBSD: vector.c,v 1.11 1995/01/11 20:31:33 gwr Exp $ */ /* * Copyright (c) 1994 Gordon W. Ross @@ -37,10 +37,6 @@ #include "vector.h" -#define COPY_ENTRY16 COPY_ENTRY, COPY_ENTRY, COPY_ENTRY, COPY_ENTRY, \ - COPY_ENTRY, COPY_ENTRY, COPY_ENTRY, COPY_ENTRY, \ - COPY_ENTRY, COPY_ENTRY, COPY_ENTRY, COPY_ENTRY, \ - COPY_ENTRY, COPY_ENTRY, COPY_ENTRY, COPY_ENTRY #define BADTRAP16 badtrap, badtrap, badtrap, badtrap, \ badtrap, badtrap, badtrap, badtrap, \ badtrap, badtrap, badtrap, badtrap, \ @@ -50,6 +46,8 @@ void addrerr(), badtrap(), buserr(), chkinst(), coperr(), fmterr(), fpfline(), fpunsupp(), illinst(), privinst(), trace(), trap0(), trap1(), trap12(), trap15(), trap2(), trapvinst(), zerodiv(), fpfault(); +void level0intr(), level1intr(), level2intr(), level3intr(); +void level4intr(), level5intr(), level6intr(), level7intr(); #define fpbsun fpfault #define fpdz fpfault @@ -60,102 +58,93 @@ void addrerr(), badtrap(), buserr(), chkinst(), coperr(), fmterr(), #define fpunfl fpfault void (*vector_table[NVECTORS])() = { - COPY_ENTRY, /* 0: jmp 0x400:w (unused reset SSP)*/ - COPY_ENTRY, /* 1: NOT USED (reset PC) */ - buserr, /* 2: bus error */ - addrerr, /* 3: address error */ - illinst, /* 4: illegal instruction */ - zerodiv, /* 5: zero divide */ - chkinst, /* 6: CHK instruction */ - trapvinst, /* 7: TRAPV instruction */ - privinst, /* 8: privilege violation */ - trace, /* 9: trace */ - illinst, /* 10: line 1010 emulator */ - fpfline, /* 11: line 1111 emulator */ - badtrap, /* 12: unassigned, reserved */ - coperr, /* 13: coprocessor protocol violatio */ - fmterr, /* 14: format error */ - badtrap, /* 15: uninitialized interrupt vecto */ - badtrap, /* 16: unassigned, reserved */ - badtrap, /* 17: unassigned, reserved */ - badtrap, /* 18: unassigned, reserved */ - badtrap, /* 19: unassigned, reserved */ - badtrap, /* 20: unassigned, reserved */ - badtrap, /* 21: unassigned, reserved */ - badtrap, /* 22: unassigned, reserved */ - badtrap, /* 23: unassigned, reserved */ - COPY_ENTRY, /* 24: spurious interrupt */ - COPY_ENTRY, /* 25: level 1 interrupt autovector */ - COPY_ENTRY, /* 26: level 2 interrupt autovector */ - COPY_ENTRY, /* 27: level 3 interrupt autovector */ - COPY_ENTRY, /* 28: level 4 interrupt autovector */ - COPY_ENTRY, /* 29: level 5 interrupt autovector */ - COPY_ENTRY, /* 30: level 6 interrupt autovector */ - COPY_ENTRY, /* 31: level 7 interrupt autovector */ - trap0, /* 32: syscalls (at least on hp300) */ - trap1, /* 33: sigreturn syscall or breakpoi */ - trap2, /* 34: breakpoint or sigreturn sysca */ - illinst, /* 35: TRAP instruction vector */ - illinst, /* 36: TRAP instruction vector */ - illinst, /* 37: TRAP instruction vector */ - illinst, /* 38: TRAP instruction vector */ - illinst, /* 39: TRAP instruction vector */ - illinst, /* 40: TRAP instruction vector */ - illinst, /* 41: TRAP instruction vector */ - illinst, /* 42: TRAP instruction vector */ - illinst, /* 43: TRAP instruction vector */ - trap12, /* 44: TRAP instruction vector */ - illinst, /* 45: TRAP instruction vector */ - illinst, /* 46: TRAP instruction vector */ - trap15, /* 47: TRAP instruction vector */ - fpbsun, /* 48: FPCP branch/set on unordered */ - fpinex, /* 49: FPCP inexact result */ - fpdz, /* 50: FPCP divide by zero */ - fpunfl, /* 51: FPCP underflow */ - fpoperr, /* 52: FPCP operand error */ - fpovfl, /* 53: FPCP overflow */ - fpsnan, /* 54: FPCP signalling NAN */ - fpunsupp, /* 55: FPCP unimplemented data type */ - badtrap, /* 56: unassigned, reserved */ - badtrap, /* 57: unassigned, reserved */ - badtrap, /* 58: unassigned, reserved */ - badtrap, /* 59: unassigned, reserved */ - badtrap, /* 60: unassigned, reserved */ - badtrap, /* 61: unassigned, reserved */ - badtrap, /* 62: unassigned, reserved */ - badtrap, /* 63: unassigned, reserved */ + 0xfffe000, /* 0: NOT USED (reset SP) */ + 0xfef0000, /* 1: NOT USED (reset PC) */ + buserr, /* 2: bus error */ + addrerr, /* 3: address error */ + illinst, /* 4: illegal instruction */ + zerodiv, /* 5: zero divide */ + chkinst, /* 6: CHK instruction */ + trapvinst, /* 7: TRAPV instruction */ + privinst, /* 8: privilege violation */ + trace, /* 9: trace */ + illinst, /* 10: line 1010 emulator */ + fpfline, /* 11: line 1111 emulator */ + badtrap, /* 12: unassigned, reserved */ + coperr, /* 13: coprocessor protocol violatio */ + fmterr, /* 14: format error */ + badtrap, /* 15: uninitialized interrupt vecto */ + badtrap, /* 16: unassigned, reserved */ + badtrap, /* 17: unassigned, reserved */ + badtrap, /* 18: unassigned, reserved */ + badtrap, /* 19: unassigned, reserved */ + badtrap, /* 20: unassigned, reserved */ + badtrap, /* 21: unassigned, reserved */ + badtrap, /* 22: unassigned, reserved */ + badtrap, /* 23: unassigned, reserved */ + level0intr, /* 24: spurious interrupt */ + level1intr, /* 25: level 1 interrupt autovector */ + level2intr, /* 26: level 2 interrupt autovector */ + level3intr, /* 27: level 3 interrupt autovector */ + level4intr, /* 28: level 4 interrupt autovector */ + level5intr, /* 29: level 5 interrupt autovector */ + level6intr, /* 30: level 6 interrupt autovector */ + level7intr, /* 31: level 7 interrupt autovector */ + trap0, /* 32: syscalls (at least on hp300) */ + trap1, /* 33: sigreturn syscall or breakpoi */ + trap2, /* 34: breakpoint or sigreturn sysca */ + illinst, /* 35: TRAP instruction vector */ + illinst, /* 36: TRAP instruction vector */ + illinst, /* 37: TRAP instruction vector */ + illinst, /* 38: TRAP instruction vector */ + illinst, /* 39: TRAP instruction vector */ + illinst, /* 40: TRAP instruction vector */ + illinst, /* 41: TRAP instruction vector */ + illinst, /* 42: TRAP instruction vector */ + illinst, /* 43: TRAP instruction vector */ + trap12, /* 44: TRAP instruction vector */ + illinst, /* 45: TRAP instruction vector */ + illinst, /* 46: TRAP instruction vector */ + trap15, /* 47: TRAP instruction vector */ + fpbsun, /* 48: FPCP branch/set on unordered */ + fpinex, /* 49: FPCP inexact result */ + fpdz, /* 50: FPCP divide by zero */ + fpunfl, /* 51: FPCP underflow */ + fpoperr, /* 52: FPCP operand error */ + fpovfl, /* 53: FPCP overflow */ + fpsnan, /* 54: FPCP signalling NAN */ + fpunsupp, /* 55: FPCP unimplemented data type */ + badtrap, /* 56: unassigned, reserved */ + badtrap, /* 57: unassigned, reserved */ + badtrap, /* 58: unassigned, reserved */ + badtrap, /* 59: unassigned, reserved */ + badtrap, /* 60: unassigned, reserved */ + badtrap, /* 61: unassigned, reserved */ + badtrap, /* 62: unassigned, reserved */ + badtrap, /* 63: unassigned, reserved */ - BADTRAP16, /* 64-79 */ - BADTRAP16, /* 80-95 */ - BADTRAP16, /* 96-111 */ - BADTRAP16, /* 112-127 */ + /* 64-255: set later by isr_add_vectored() */ - BADTRAP16, /* 128-143 */ - BADTRAP16, /* 144-159 */ - BADTRAP16, /* 160-175 */ - BADTRAP16, /* 176-191 */ - - BADTRAP16, /* 192-207 */ - BADTRAP16, /* 208-223 */ - BADTRAP16, /* 224-239 */ - BADTRAP16 /* 240-255 */ - }; + BADTRAP16, BADTRAP16, BADTRAP16, BADTRAP16, + BADTRAP16, BADTRAP16, BADTRAP16, BADTRAP16, + BADTRAP16, BADTRAP16, BADTRAP16, BADTRAP16, +}; void set_vector_entry(entry, handler) - int entry; - void (*handler)(); + int entry; + void (*handler)(); { - if ((entry <0) || (entry >= NVECTORS)) + if ((entry <0) || (entry >= NVECTORS)) panic("set_vector_entry: setting vector too high or low\n"); - vector_table[entry] = handler; + vector_table[entry] = handler; } unsigned int get_vector_entry(entry) - int entry; + int entry; { - if ((entry <0) || (entry >= NVECTORS)) + if ((entry <0) || (entry >= NVECTORS)) panic("get_vector_entry: setting vector too high or low\n"); - return (unsigned int) vector_table[entry]; + return (unsigned int) vector_table[entry]; }