Add VME interrupt attach.

This commit is contained in:
gwr 1995-01-11 20:31:30 +00:00
parent a64c43edd8
commit a9a78b9b76
3 changed files with 231 additions and 207 deletions

View File

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

View File

@ -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 <sys/param.h>
#include <sys/systm.h>
#include <sys/malloc.h>
@ -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; i++) {
if (level_intr_array[i].used) continue;
isr_activate(i);
}
}
void isr_add_autovect(handler, arg, level)
int (*handler)();
void *arg;
int level;
{
struct isr *new_isr;
int first_isr;
first_isr = 0;
if ((level < 0) || (level >= 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);
}

View File

@ -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];
}