2 * Copyright (c) 1989, 1990 William F. Jolitz.
3 * Copyright (c) 1990 The Regents of the University of California.
6 * This code is derived from software contributed to Berkeley by
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed by the University of
20 * California, Berkeley and its contributors.
21 * 4. Neither the name of the University nor the names of its contributors
22 * may be used to endorse or promote products derived from this software
23 * without specific prior written permission.
25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
39 * $FreeBSD: src/sys/i386/isa/ipl.s,v 1.32.2.3 2002/05/16 16:03:56 bde Exp $
40 * $DragonFly: src/sys/i386/isa/Attic/ipl.s,v 1.3 2003/06/22 08:54:22 dillon Exp $
46 * Vector interrupt control section
48 * *_imask - Interrupt masks for various spl*() functions
49 * ipending - Pending interrupts (set when a masked interrupt occurs)
55 /* current priority (all off) */
58 _tty_imask: .long SWI_TTY_MASK
60 _bio_imask: .long SWI_CLOCK_MASK | SWI_CAMBIO_MASK
62 _net_imask: .long SWI_NET_MASK | SWI_CAMNET_MASK
64 _cam_imask: .long SWI_CAMBIO_MASK | SWI_CAMNET_MASK
66 _soft_imask: .long SWI_MASK
68 _softnet_imask: .long SWI_NET_MASK
70 _softtty_imask: .long SWI_TTY_MASK
72 /* pending interrupts blocked by splxxx() */
76 /* set with bits for which queue to service */
82 .long dummynetisr, dummynetisr, dummynetisr, dummynetisr
83 .long dummynetisr, dummynetisr, dummynetisr, dummynetisr
84 .long dummynetisr, dummynetisr, dummynetisr, dummynetisr
85 .long dummynetisr, dummynetisr, dummynetisr, dummynetisr
86 .long dummynetisr, dummynetisr, dummynetisr, dummynetisr
87 .long dummynetisr, dummynetisr, dummynetisr, dummynetisr
88 .long dummynetisr, dummynetisr, dummynetisr, dummynetisr
89 .long dummynetisr, dummynetisr, dummynetisr, dummynetisr
94 * Handle return from interrupts, traps and syscalls.
97 .type _doreti,@function
99 FAKE_MCOUNT(_bintr) /* init "from" _bintr -> _doreti */
100 addl $4,%esp /* discard unit number */
101 popl %eax /* cpl or cml to restore */
105 * Check for pending HWIs and SWIs atomically with restoring cpl
106 * and exiting. The check has to be atomic with exiting to stop
107 * (ipending & ~cpl) changing from zero to nonzero while we're
108 * looking at it (this wouldn't be fatal but it would increase
109 * interrupt latency). Restoring cpl has to be atomic with exiting
110 * so that the stack cannot pile up (the nesting level of interrupt
111 * handlers is limited by the number of bits in cpl).
114 cli /* early to prevent INT deadlock */
118 notl %ecx /* set bit = unmasked level */
122 andl _ipending,%ecx /* set bit = unmasked pending INT */
124 movl %eax,TD_MACH+MTD_CPL(%ebx)
125 decb _intr_nesting_level
127 /* Check for ASTs that can be handled now. */
128 testl $AST_PENDING,_astpending
130 testl $PSL_VM,TF_EFLAGS(%esp)
137 testb $SEL_RPL_MASK,TF_CS(%esp)
141 * doreti_exit - release MP lock, pop registers, iret.
143 * Note that the syscall trap shotcuts to doreti_syscall_ret.
144 * The segment register pop is a special case, since it may
145 * fault if (for example) a sigreturn specifies bad segment
146 * registers. The fault is handled in trap.c
153 /* release the kernel lock */
154 movl $_mp_lock, %edx /* GIANT_LOCK */
158 .globl doreti_popl_fs
159 .globl doreti_syscall_ret
163 .globl doreti_popl_es
166 .globl doreti_popl_ds
176 .globl doreti_iret_fault
181 .globl doreti_popl_ds_fault
182 doreti_popl_ds_fault:
184 .globl doreti_popl_es_fault
185 doreti_popl_es_fault:
187 .globl doreti_popl_fs_fault
188 doreti_popl_fs_fault:
189 movl $0,TF_ERR(%esp) /* XXX should be the error code */
190 movl $T_PROTFLT,TF_TRAPNO(%esp)
191 jmp alltraps_with_regs_pushed
196 * Enabling interrupts is safe because we haven't restored cpl yet.
197 * %ecx contains the next probable ready interrupt (~cpl & ipending)
200 bsfl %ecx, %ecx /* locate the next dispatchable int */
202 btrl %ecx, _ipending /* is it really still pending? */
203 jnc doreti_next2 /* some intr cleared memory copy */
204 sti /* late to prevent INT deadlock */
207 bsfl %ecx,%ecx /* slow, but not worth optimizing */
209 jnc doreti_next /* some intr cleared memory copy */
212 * Execute handleable interrupt
214 * Set up JUMP to _ihandlers[%ecx] for HWIs.
215 * Set up CALL of _ihandlers[%ecx] for SWIs.
216 * This is a bit early for the SMP case - we have to push %ecx and
217 * %edx, but could push only %ecx and load %edx later.
219 movl _ihandlers(,%ecx,4),%edx
221 jae doreti_swi /* software interrupt handling */
222 cli /* else hardware int handling */
223 movl %eax,TD_MACH+MTD_CPL(%ebx) /* same as non-smp case right now */
225 #ifdef APIC_INTR_DIAGNOSTIC
227 incl CNAME(apic_itrace_doreti)(,%ecx,4)
228 #ifdef APIC_INTR_DIAGNOSTIC_IRQ
229 cmpl $APIC_INTR_DIAGNOSTIC_IRQ,%ecx
234 pushl $APIC_ITRACE_DORETI
249 * At least the SWI_CLOCK handler has to run at a possibly strictly
250 * lower cpl, so we have to restore
251 * all the h/w bits in cpl now and have to worry about stack growth.
252 * The worst case is currently (30 Jan 1994) 2 SWI handlers nested
253 * in dying interrupt frames and about 12 HWIs nested in active
254 * interrupt frames. There are only 4 different SWIs and the HWI
255 * and SWI masks limit the nesting further.
257 * The SMP case is currently the same as the non-SMP case.
259 orl imasks(,%ecx,4), %eax /* or in imasks */
260 movl %eax,TD_MACH+MTD_CPL(%ebx) /* set cpl for call */
263 popl %eax /* cpl to restore */
268 andl $~AST_PENDING,_astpending
270 movl $T_ASTFLT,TF_TRAPNO(%esp)
272 subl %eax,%eax /* recover cpl|cml */
273 movb $1,_intr_nesting_level /* for doreti_next to decrement */
284 call *_netisrs(,%eax,4)
297 * The arg is in a nonstandard place, so swi_dispatcher() can't be called
298 * directly and swi_generic() can't use ENTRY() or MCOUNT.
302 .type _swi_generic,@function
314 #include "i386/isa/apic_ipl.s"
316 #include "i386/isa/icu_ipl.s"