summaryrefslogtreecommitdiffstats
path: root/sys/i386/isa/vector.s
diff options
context:
space:
mode:
authordg <dg@FreeBSD.org>1994-08-18 05:09:36 +0000
committerdg <dg@FreeBSD.org>1994-08-18 05:09:36 +0000
commit7b3218c89f6c5e1d72625d3be9db3a221ea7f330 (patch)
tree1abd0f0dcf193ac24dd552de50221c9fb30b3610 /sys/i386/isa/vector.s
parentc87abe4536bb366a683e0f2b5fcaaa67d072ba75 (diff)
downloadFreeBSD-src-7b3218c89f6c5e1d72625d3be9db3a221ea7f330.zip
FreeBSD-src-7b3218c89f6c5e1d72625d3be9db3a221ea7f330.tar.gz
Bruce Evans' dynamic interrupt support.
/usr/src/sys/i386/isa/clock.c: o Garrett's statclock changes. o Wire xxxintr, not Vclk. o Wire using register_intr(), not setidt(). /usr/src/sys/i386/isa/icu.s: o Garrett's statclock changes. o Removed unused variable high_imask. o Fake int 8 for rtc as well as int 0 for clk. Required for kernel profiling with statclock, harmless otherwise. /usr/src/sys/i386/isa/isa.c: o Allow isdp->id_irq and other things in *isdp to be changed by probes. Changing interrupts later requires direct calls to register_intr() and unregister_intr() and more care. ALLOW_CONFLICT_* is brought over from 1.1.5, except ALLOW_CONFLICT_IRQ is not supported. IRQ conflict checking is delayed until after probing so that drivers can change the IRQ to a free one; real conflicts require more cooperation between drivers to handle. o Too many details to list. o This file requires splitting and a lot more work. /usr/src/sys/i386/isa/isa_device.h: o Declare more things more completely. /usr/src/sys/i386/isa/sio.c: o Prepare to register interrupt handlers as fast. /usr/src/sys/i386/isa/vector.s: o Generate entry code for 16 fast interrupt handlers and 16 normal interrupt handlers. Changed some constants to variables: # $unit is now intr_unit[intr]. Type is int. Someday it should be a cookie suitable for the handler (e.g., a struct com_s for sio). # $handler is now intr_handler[intr]. # intrcnt_actv[id_num] is now *intr_countp[intr]. The indirection is required to get a contiguous range of counters for vmstat and so that the drivers depend more in the driver than on the interrupt number (drivers could take turns using an interrupt and the counts would remain correct). There is a separate counter for each device and for each stray interrupt. In 1.1.5, stray interrupt 7 clobbers the count for device 7 or something worse if there is no device 7 :-(. # mask is now intr_mask[intr] (was already indirect). o Entry points are now _XintrI and _XfastintrI (I = intr = 0-15), not _VdevU (U = unit). o Removed BUILD_VECTORS stuff. There's a trace of it left for the string table for vmstat but config now generates the string in one piece because nothing more is required. o Removed old handling of stray interrupts and older comments about it. Submitted by: Bruce Evans
Diffstat (limited to 'sys/i386/isa/vector.s')
-rw-r--r--sys/i386/isa/vector.s238
1 files changed, 84 insertions, 154 deletions
diff --git a/sys/i386/isa/vector.s b/sys/i386/isa/vector.s
index 7135ae7..252bd95 100644
--- a/sys/i386/isa/vector.s
+++ b/sys/i386/isa/vector.s
@@ -1,6 +1,6 @@
/*
* from: vector.s, 386BSD 0.1 unknown origin
- * $Id: vector.s,v 1.6 1994/01/10 23:15:09 ache Exp $
+ * $Id: vector.s,v 1.7 1994/04/02 07:00:50 davidg Exp $
*/
#include "i386/isa/icu.h"
@@ -97,7 +97,10 @@
* loading segregs.
*/
-#define FAST_INTR(unit, irq_num, id_num, handler, enable_icus) \
+#define FAST_INTR(irq_num, enable_icus) \
+ .text ; \
+ SUPERALIGN_TEXT ; \
+IDTVEC(fastintr/**/irq_num) ; \
pushl %eax ; /* save only call-used registers */ \
pushl %ecx ; \
pushl %edx ; \
@@ -107,12 +110,13 @@
movl %ax,%ds ; \
MAYBE_MOVW_AX_ES ; \
FAKE_MCOUNT((4+ACTUALLY_PUSHED)*4(%esp)) ; \
- pushl $unit ; \
- call handler ; /* do the work ASAP */ \
+ pushl _intr_unit + (irq_num) * 4 ; \
+ call *_intr_handler + (irq_num) * 4 ; /* do the work ASAP */ \
enable_icus ; /* (re)enable ASAP (helps edge trigger?) */ \
addl $4,%esp ; \
incl _cnt+V_INTR ; /* book-keeping can wait */ \
- incl _intrcnt_actv + (id_num) * 4 ; \
+ movl _intr_countp + (irq_num) * 4,%eax ; \
+ incl (%eax) ; \
movl _cpl,%eax ; /* are we unmasking pending HWIs or SWIs? */ \
notl %eax ; \
andl _ipending,%eax ; \
@@ -147,7 +151,10 @@
MEXITCOUNT ; \
jmp _doreti
-#define INTR(unit, irq_num, id_num, mask, handler, icu, enable_icus, reg, stray) \
+#define INTR(irq_num, icu, enable_icus, reg) \
+ .text ; \
+ SUPERALIGN_TEXT ; \
+IDTVEC(intr/**/irq_num) ; \
pushl $0 ; /* dumby error code */ \
pushl $0 ; /* dumby trap type */ \
pushal ; \
@@ -167,15 +174,17 @@
testb $IRQ_BIT(irq_num),%reg ; \
jne 2f ; \
1: ; \
+Xresume/**/irq_num: ; \
FAKE_MCOUNT(12*4(%esp)) ; /* XXX late to avoid double count */ \
- incl _intrcnt_actv + (id_num) * 4 ; \
+ movl _intr_countp + (irq_num) * 4,%eax ; \
+ incl (%eax) ; \
movl _cpl,%eax ; \
pushl %eax ; \
- pushl $unit ; \
- orl mask,%eax ; \
+ pushl _intr_unit + (irq_num) * 4 ; \
+ orl _intr_mask + (irq_num) * 4,%eax ; \
movl %eax,_cpl ; \
sti ; \
- call handler ; \
+ call *_intr_handler + (irq_num) * 4 ; \
movb _imen + IRQ_BYTE(irq_num),%al ; \
andb $~IRQ_BIT(irq_num),%al ; \
movb %al,_imen + IRQ_BYTE(irq_num) ; \
@@ -189,9 +198,6 @@
ALIGN_TEXT ; \
2: ; \
/* XXX skip mcounting here to avoid double count */ \
- movl $1b,%eax ; /* register resume address */ \
- /* XXX - someday do it at attach time */ \
- movl %eax,ihandlers + (irq_num) * 4 ; \
orb $IRQ_BIT(irq_num),_ipending + IRQ_BYTE(irq_num) ; \
popl %es ; \
popl %ds ; \
@@ -199,118 +205,48 @@
addl $4+4,%esp ; \
iret
-/*
- * vector.h has defined a macro 'BUILD_VECTORS' containing a big list of info
- * about vectors, including a submacro 'BUILD_VECTOR' that operates on the
- * info about each vector. We redefine 'BUILD_VECTOR' to expand the info
- * in different ways. Here we expand it to a list of interrupt handlers.
- * This order is of course unimportant. Elsewhere we expand it to inline
- * linear search code for which the order is a little more important and
- * concatenating the code with no holes is very important.
- *
- * XXX - now there is BUILD_FAST_VECTOR as well as BUILD_VECTOR.
- *
- * The info consists of the following items for each vector:
- *
- * name (identifier): name of the vector; used to build labels
- * unit (expression): unit number to call the device driver with
- * irq_num (number): number of the IRQ to handled (0-15)
- * id_num (number): uniq numeric id for handler (assigned by config)
- * mask (blank-ident): priority mask used
- * handler (blank-ident): interrupt handler to call
- * icu_num (number): (1 + irq_num / 8) converted for label building
- * icu_enables (number): 1 for icu_num == 1, 1_AND_2 for icu_num == 2
- * reg (blank-ident): al for icu_num == 1, ah for icu_num == 2
- *
- * 'irq_num' is converted in several ways at config time to get around
- * limitations in cpp. The macros have blanks after commas iff they would
- * not mess up identifiers and numbers.
- */
-
-#undef BUILD_FAST_VECTOR
-#define BUILD_FAST_VECTOR(name, unit, irq_num, id_num, mask, handler, \
- icu_num, icu_enables, reg) \
- .globl handler ; \
- .text ; \
- .globl _V/**/name ; \
- SUPERALIGN_TEXT ; \
-_V/**/name: ; \
- FAST_INTR(unit, irq_num,id_num, handler, ENABLE_ICU/**/icu_enables)
-
-#undef BUILD_VECTOR
-#define BUILD_VECTOR(name, unit, irq_num, id_num, mask, handler, \
- icu_num, icu_enables, reg) \
- .globl handler ; \
- .text ; \
- .globl _V/**/name ; \
- SUPERALIGN_TEXT ; \
-_V/**/name: ; \
- INTR(unit,irq_num, id_num, mask, handler, IO_ICU/**/icu_num, \
- ENABLE_ICU/**/icu_enables, reg,)
-
MCOUNT_LABEL(bintr)
- BUILD_VECTORS
-
- /* hardware interrupt catcher (IDT 32 - 47) */
- .globl _isa_strayintr
-
-#define STRAYINTR(irq_num, icu_num, icu_enables, reg) \
-IDTVEC(intr/**/irq_num) ; \
- INTR(irq_num,irq_num,irq_num, _high_imask, _isa_strayintr, \
- IO_ICU/**/icu_num, ENABLE_ICU/**/icu_enables, reg,stray)
-
-/*
- * XXX - the mask (1 << 2) == IRQ_SLAVE will be generated for IRQ 2, instead
- * of the mask IRQ2 (defined as IRQ9 == (1 << 9)). But IRQ 2 "can't happen".
- * In fact, all stray interrupts "can't happen" except for bugs. The
- * "stray" IRQ 7 is documented behaviour of the 8259. It happens when there
- * is a glitch on any of its interrupt inputs. Does it really interrupt when
- * IRQ 7 is masked?
- *
- * XXX - unpend doesn't work for these, it sends them to the real handler.
- *
- * XXX - the race bug during initialization may be because I changed the
- * order of switching from the stray to the real interrupt handler to before
- * enabling interrupts. The old order looked unsafe but maybe it is OK with
- * the stray interrupt handler installed. But these handlers only reduce
- * the window of vulnerability - it is still open at the end of
- * isa_configure().
- *
- * XXX - many comments are stale.
- */
-
- STRAYINTR(0,1,1, al)
- STRAYINTR(1,1,1, al)
- STRAYINTR(2,1,1, al)
- STRAYINTR(3,1,1, al)
- STRAYINTR(4,1,1, al)
- STRAYINTR(5,1,1, al)
- STRAYINTR(6,1,1, al)
- STRAYINTR(7,1,1, al)
- STRAYINTR(8,2,1_AND_2, ah)
- STRAYINTR(9,2,1_AND_2, ah)
- STRAYINTR(10,2,1_AND_2, ah)
- STRAYINTR(11,2,1_AND_2, ah)
- STRAYINTR(12,2,1_AND_2, ah)
- STRAYINTR(13,2,1_AND_2, ah)
- STRAYINTR(14,2,1_AND_2, ah)
- STRAYINTR(15,2,1_AND_2, ah)
-#if 0
- INTRSTRAY(255, _highmask, 255) ; call _isa_strayintr ; INTREXIT2
-#endif
+ FAST_INTR(0, ENABLE_ICU1)
+ FAST_INTR(1, ENABLE_ICU1)
+ FAST_INTR(2, ENABLE_ICU1)
+ FAST_INTR(3, ENABLE_ICU1)
+ FAST_INTR(4, ENABLE_ICU1)
+ FAST_INTR(5, ENABLE_ICU1)
+ FAST_INTR(6, ENABLE_ICU1)
+ FAST_INTR(7, ENABLE_ICU1)
+ FAST_INTR(8, ENABLE_ICU1_AND_2)
+ FAST_INTR(9, ENABLE_ICU1_AND_2)
+ FAST_INTR(10, ENABLE_ICU1_AND_2)
+ FAST_INTR(11, ENABLE_ICU1_AND_2)
+ FAST_INTR(12, ENABLE_ICU1_AND_2)
+ FAST_INTR(13, ENABLE_ICU1_AND_2)
+ FAST_INTR(14, ENABLE_ICU1_AND_2)
+ FAST_INTR(15, ENABLE_ICU1_AND_2)
+ INTR(0, IO_ICU1, ENABLE_ICU1, al)
+ INTR(1, IO_ICU1, ENABLE_ICU1, al)
+ INTR(2, IO_ICU1, ENABLE_ICU1, al)
+ INTR(3, IO_ICU1, ENABLE_ICU1, al)
+ INTR(4, IO_ICU1, ENABLE_ICU1, al)
+ INTR(5, IO_ICU1, ENABLE_ICU1, al)
+ INTR(6, IO_ICU1, ENABLE_ICU1, al)
+ INTR(7, IO_ICU1, ENABLE_ICU1, al)
+ INTR(8, IO_ICU2, ENABLE_ICU1_AND_2, ah)
+ INTR(9, IO_ICU2, ENABLE_ICU1_AND_2, ah)
+ INTR(10, IO_ICU2, ENABLE_ICU1_AND_2, ah)
+ INTR(11, IO_ICU2, ENABLE_ICU1_AND_2, ah)
+ INTR(12, IO_ICU2, ENABLE_ICU1_AND_2, ah)
+ INTR(13, IO_ICU2, ENABLE_ICU1_AND_2, ah)
+ INTR(14, IO_ICU2, ENABLE_ICU1_AND_2, ah)
+ INTR(15, IO_ICU2, ENABLE_ICU1_AND_2, ah)
MCOUNT_LABEL(eintr)
-/*
- * These are the interrupt counters, I moved them here from icu.s so that
- * they are with the name table. rgrimes
- *
- * There are now lots of counters, this has been redone to work with
- * Bruce Evans intr-0.1 code, which I modified some more to make it all
- * work with vmstat.
- */
.data
ihandlers: /* addresses of interrupt handlers */
- .space NHWI*4 /* actually resumption addresses for HWI's */
+ /* actually resumption addresses for HWI's */
+ .long Xresume0, Xresume1, Xresume2, Xresume3
+ .long Xresume4, Xresume5, Xresume6, Xresume7
+ .long Xresume8, Xresume9, Xresume10, Xresume11
+ .long Xresume12, Xresume13, Xresume14, Xresume15
.long swi_tty, swi_net, 0, 0, 0, 0, 0, 0
.long 0, 0, 0, 0, 0, 0, swi_clock, swi_ast
imasks: /* masks for interrupt handlers */
@@ -318,43 +254,37 @@ imasks: /* masks for interrupt handlers */
.long SWI_TTY_MASK, SWI_NET_MASK, 0, 0, 0, 0, 0, 0
.long 0, 0, 0, 0, 0, 0, SWI_CLOCK_MASK, SWI_AST_MASK
- .globl _intrcnt
-_intrcnt: /* used by vmstat to calc size of table */
- .globl _intrcnt_bad7
-_intrcnt_bad7: .space 4 /* glitches on irq 7 */
- .globl _intrcnt_bad15
-_intrcnt_bad15: .space 4 /* glitches on irq 15 */
- .globl _intrcnt_stray
-_intrcnt_stray: .space 4 /* total count of stray interrupts */
- .globl _intrcnt_actv
-_intrcnt_actv: .space NR_REAL_INT_HANDLERS * 4 /* active interrupts */
- .globl _eintrcnt
-_eintrcnt: /* used by vmstat to calc size of table */
-
-/*
- * Build the interrupt name table for vmstat
- */
-
-#undef BUILD_FAST_VECTOR
-#define BUILD_FAST_VECTOR BUILD_VECTOR
-
-#undef BUILD_VECTOR
-#define BUILD_VECTOR(name, unit, irq_num, id_num, mask, handler, \
- icu_num, icu_enables, reg) \
- .ascii "name irq" ; \
- .asciz "irq_num"
/*
- * XXX - use the __STRING and __CONCAT macros from <sys/cdefs.h> to stringize
- * and concatenate names above and elsewhere. Note that __CONCAT doesn't
- * work when nested.
+ * Interrupt counters and names. The format of these and the label names
+ * must agree with what vmstat expects. The tables are indexed by device
+ * ids so that we don't have to move the names around as devices are
+ * attached.
*/
+#include "vector.h"
+ .globl _intrcnt, _eintrcnt
+_intrcnt:
+ .space (NR_DEVICES + ICU_LEN) * 4
+_eintrcnt:
- .text
.globl _intrnames, _eintrnames
_intrnames:
- BUILD_VECTOR(bad,,7,,,,,,)
- BUILD_VECTOR(bad,,15,,,,,,)
- BUILD_VECTOR(stray,,,,,,,,)
- BUILD_VECTORS
-
+ .ascii DEVICE_NAMES
+ .asciz "stray irq0"
+ .asciz "stray irq1"
+ .asciz "stray irq2"
+ .asciz "stray irq3"
+ .asciz "stray irq4"
+ .asciz "stray irq5"
+ .asciz "stray irq6"
+ .asciz "stray irq7"
+ .asciz "stray irq8"
+ .asciz "stray irq9"
+ .asciz "stray irq10"
+ .asciz "stray irq11"
+ .asciz "stray irq12"
+ .asciz "stray irq13"
+ .asciz "stray irq14"
+ .asciz "stray irq15"
_eintrnames:
+
+ .text
OpenPOWER on IntegriCloud