summaryrefslogtreecommitdiffstats
path: root/sys/i386/isa/icu.s
diff options
context:
space:
mode:
Diffstat (limited to 'sys/i386/isa/icu.s')
-rw-r--r--sys/i386/isa/icu.s376
1 files changed, 376 insertions, 0 deletions
diff --git a/sys/i386/isa/icu.s b/sys/i386/isa/icu.s
new file mode 100644
index 0000000..1b93c65
--- /dev/null
+++ b/sys/i386/isa/icu.s
@@ -0,0 +1,376 @@
+/*-
+ * Copyright (c) 1989, 1990 William F. Jolitz.
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)icu.s 7.2 (Berkeley) 5/21/91
+ *
+ * PATCHES MAGIC LEVEL PATCH THAT GOT US HERE
+ * -------------------- ----- ----------------------
+ * CURRENT PATCH LEVEL: 5 00167
+ * -------------------- ----- ----------------------
+ *
+ * 28 Nov 92 Frank MacLachlan Aligned addresses and data
+ * on 32bit boundaries.
+ * 24 Mar 93 Rodney W. Grimes Added interrupt counters for vmstat
+ * also stray and false intr counters added
+ * 20 Apr 93 Bruce Evans New npx-0.5 code
+ * 25 Apr 93 Bruce Evans Support new interrupt code (intr-0.1)
+ * Rodney W. Grimes Reimplement above patches..
+ * 17 May 93 Rodney W. Grimes Redid the interrupt counter stuff
+ * moved the counters to vectors.s so
+ * they are next to the name tables.
+ * 04 Jun 93 Bruce Evans Fixed irq_num vs id_num for multiple
+ * devices configed on the same irq with
+ * respect to ipending. Restructured
+ * not to use BUILD_VECTORS.
+ * Rodney W. Grimes softsio1 only works if you have sio
+ * serial driver, added #include sio.h
+ * and #ifdef NSIO > 0 to protect it.
+ */
+
+/*
+ * AT/386
+ * Vector interrupt control section
+ */
+
+/*
+ * XXX - this file is now misnamed. All spls are now soft and the only thing
+ * related to the hardware icu is that the bit numbering is the same in the
+ * soft priority masks as in the hard ones.
+ */
+
+#include "sio.h"
+#define HIGHMASK 0xffff
+#define SOFTCLOCKMASK 0x8000
+
+ .data
+ .globl _cpl
+_cpl: .long 0xffff # current priority (all off)
+ .globl _imen
+_imen: .long 0xffff # interrupt mask enable (all off)
+# .globl _highmask
+_highmask: .long HIGHMASK
+ .globl _ttymask
+_ttymask: .long 0
+ .globl _biomask
+_biomask: .long 0
+ .globl _netmask
+_netmask: .long 0
+ .globl _ipending
+_ipending: .long 0
+vec:
+ .long vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7
+ .long vec8, vec9, vec10, vec11, vec12, vec13, vec14, vec15
+
+#define GENSPL(name, mask, event) \
+ .globl _spl/**/name ; \
+ ALIGN_TEXT ; \
+_spl/**/name: ; \
+ COUNT_EVENT(_intrcnt_spl, event) ; \
+ movl _cpl,%eax ; \
+ movl %eax,%edx ; \
+ orl mask,%edx ; \
+ movl %edx,_cpl ; \
+ SHOW_CPL ; \
+ ret
+
+#define FASTSPL(mask) \
+ movl mask,_cpl ; \
+ SHOW_CPL
+
+#define FASTSPL_VARMASK(varmask) \
+ movl varmask,%eax ; \
+ movl %eax,_cpl ; \
+ SHOW_CPL
+
+ .text
+
+ ALIGN_TEXT
+unpend_v:
+ COUNT_EVENT(_intrcnt_spl, 0)
+ bsfl %eax,%eax # slow, but not worth optimizing
+ btrl %eax,_ipending
+ jnc unpend_v_next # some intr cleared the in-memory bit
+ SHOW_IPENDING
+ movl Vresume(,%eax,4),%eax
+ testl %eax,%eax
+ je noresume
+ jmp %eax
+
+ ALIGN_TEXT
+/*
+ * XXX - must be some fastintr, need to register those too.
+ */
+noresume:
+#if NSIO > 0
+ call _softsio1
+#endif
+unpend_v_next:
+ movl _cpl,%eax
+ movl %eax,%edx
+ notl %eax
+ andl _ipending,%eax
+ je none_to_unpend
+ jmp unpend_v
+
+/*
+ * Handle return from interrupt after device handler finishes
+ */
+ ALIGN_TEXT
+doreti:
+ COUNT_EVENT(_intrcnt_spl, 1)
+ addl $4,%esp # discard unit arg
+ popl %eax # get previous priority
+/*
+ * Now interrupt frame is a trap frame!
+ *
+ * XXX - setting up the interrupt frame to be almost a stack frame is mostly
+ * a waste of time.
+ */
+ movl %eax,_cpl
+ SHOW_CPL
+ movl %eax,%edx
+ notl %eax
+ andl _ipending,%eax
+ jne unpend_v
+none_to_unpend:
+ testl %edx,%edx # returning to zero priority?
+ jne 1f # nope, going to non-zero priority
+ movl _netisr,%eax
+ testl %eax,%eax # check for softint s/traps
+ jne 2f # there are some
+ jmp test_resched # XXX - schedule jumps better
+ COUNT_EVENT(_intrcnt_spl, 2) # XXX
+
+ ALIGN_TEXT # XXX
+1: # XXX
+ COUNT_EVENT(_intrcnt_spl, 3)
+ popl %es
+ popl %ds
+ popal
+ addl $8,%esp
+ iret
+
+#include "../net/netisr.h"
+
+#define DONET(s, c, event) ; \
+ .globl c ; \
+ btrl $s,_netisr ; \
+ jnc 1f ; \
+ COUNT_EVENT(_intrcnt_spl, event) ; \
+ call c ; \
+1:
+
+ ALIGN_TEXT
+2:
+ COUNT_EVENT(_intrcnt_spl, 4)
+/*
+ * XXX - might need extra locking while testing reg copy of netisr, but
+ * interrupt routines setting it would not cause any new problems (since we
+ * don't loop, fresh bits will not be processed until the next doreti or spl0).
+ */
+ testl $~((1 << NETISR_SCLK) | (1 << NETISR_AST)),%eax
+ je test_ASTs # no net stuff, just temporary AST's
+ FASTSPL_VARMASK(_netmask)
+ DONET(NETISR_RAW, _rawintr, 5)
+#ifdef INET
+ DONET(NETISR_IP, _ipintr, 6)
+#endif
+#ifdef IMP
+ DONET(NETISR_IMP, _impintr, 7)
+#endif
+#ifdef NS
+ DONET(NETISR_NS, _nsintr, 8)
+#endif
+ FASTSPL($0)
+test_ASTs:
+ btrl $NETISR_SCLK,_netisr
+ jnc test_resched
+ COUNT_EVENT(_intrcnt_spl, 9)
+ FASTSPL($SOFTCLOCKMASK)
+/*
+ * Back to an interrupt frame for a moment.
+ */
+ pushl $0 # previous cpl (probably not used)
+ pushl $0x7f # dummy unit number
+ call _softclock
+ addl $8,%esp # discard dummies
+ FASTSPL($0)
+test_resched:
+#ifdef notused1
+ btrl $NETISR_AST,_netisr
+ jnc 2f
+#endif
+#ifdef notused2
+ cmpl $0,_want_resched
+ je 2f
+#endif
+ cmpl $0,_astpending # XXX - put it back in netisr to
+ je 2f # reduce the number of tests
+ testb $SEL_RPL_MASK,TRAPF_CS_OFF(%esp)
+ # to non-kernel (i.e., user)?
+ je 2f # nope, leave
+ COUNT_EVENT(_intrcnt_spl, 10)
+ movl $0,_astpending
+ call _trap
+2:
+ COUNT_EVENT(_intrcnt_spl, 11)
+ popl %es
+ popl %ds
+ popal
+ addl $8,%esp
+ iret
+
+/*
+ * Interrupt priority mechanism
+ * -- soft splXX masks with group mechanism (cpl)
+ * -- h/w masks for currently active or unused interrupts (imen)
+ * -- ipending = active interrupts currently masked by cpl
+ */
+
+ GENSPL(bio, _biomask, 12)
+ GENSPL(clock, $HIGHMASK, 13) /* splclock == splhigh ex for count */
+ GENSPL(high, $HIGHMASK, 14)
+ GENSPL(imp, _netmask, 15) /* splimp == splnet except for count */
+ GENSPL(net, _netmask, 16)
+ GENSPL(softclock, $SOFTCLOCKMASK, 17)
+ GENSPL(tty, _ttymask, 18)
+
+ .globl _splnone
+ .globl _spl0
+ ALIGN_TEXT
+_splnone:
+_spl0:
+ COUNT_EVENT(_intrcnt_spl, 19)
+in_spl0:
+ movl _cpl,%eax
+ pushl %eax # save old priority
+ testl $(1 << NETISR_RAW) | (1 << NETISR_IP),_netisr
+ je over_net_stuff_for_spl0
+ movl _netmask,%eax # mask off those network devices
+ movl %eax,_cpl # set new priority
+ SHOW_CPL
+/*
+ * XXX - what about other net intrs?
+ */
+ DONET(NETISR_RAW, _rawintr, 20)
+#ifdef INET
+ DONET(NETISR_IP, _ipintr, 21)
+#endif
+over_net_stuff_for_spl0:
+ movl $0,_cpl # set new priority
+ SHOW_CPL
+ movl _ipending,%eax
+ testl %eax,%eax
+ jne unpend_V
+ popl %eax # return old priority
+ ret
+
+ .globl _splx
+ ALIGN_TEXT
+_splx:
+ COUNT_EVENT(_intrcnt_spl, 22)
+ movl 4(%esp),%eax # new priority
+ testl %eax,%eax
+ je in_spl0 # going to "zero level" is special
+ COUNT_EVENT(_intrcnt_spl, 23)
+ movl _cpl,%edx # save old priority
+ movl %eax,_cpl # set new priority
+ SHOW_CPL
+ notl %eax
+ andl _ipending,%eax
+ jne unpend_V_result_edx
+ movl %edx,%eax # return old priority
+ ret
+
+ ALIGN_TEXT
+unpend_V_result_edx:
+ pushl %edx
+unpend_V:
+ COUNT_EVENT(_intrcnt_spl, 24)
+ bsfl %eax,%eax
+ btrl %eax,_ipending
+ jnc unpend_V_next
+ SHOW_IPENDING
+ movl Vresume(,%eax,4),%edx
+ testl %edx,%edx
+ je noresumeV
+/*
+ * We would prefer to call the intr handler directly here but that doesn't
+ * work for badly behaved handlers that want the interrupt frame. Also,
+ * there's a problem determining the unit number. We should change the
+ * interface so that the unit number is not determined at config time.
+ */
+ jmp *vec(,%eax,4)
+
+ ALIGN_TEXT
+/*
+ * XXX - must be some fastintr, need to register those too.
+ */
+noresumeV:
+#if NSIO > 0
+ call _softsio1
+#endif
+unpend_V_next:
+ movl _cpl,%eax
+ notl %eax
+ andl _ipending,%eax
+ jne unpend_V
+ popl %eax
+ ret
+
+#define BUILD_VEC(irq_num) \
+ ALIGN_TEXT ; \
+vec/**/irq_num: ; \
+ int $ICU_OFFSET + (irq_num) ; \
+ popl %eax ; \
+ ret
+
+ BUILD_VEC(0)
+ BUILD_VEC(1)
+ BUILD_VEC(2)
+ BUILD_VEC(3)
+ BUILD_VEC(4)
+ BUILD_VEC(5)
+ BUILD_VEC(6)
+ BUILD_VEC(7)
+ BUILD_VEC(8)
+ BUILD_VEC(9)
+ BUILD_VEC(10)
+ BUILD_VEC(11)
+ BUILD_VEC(12)
+ BUILD_VEC(13)
+ BUILD_VEC(14)
+ BUILD_VEC(15)
OpenPOWER on IntegriCloud