dee21cac0b898a0594152e79d7ec22361a5b2d85
[dragonfly.git] / sys / i386 / icu / icu_ipl.s
1 /*-
2  * Copyright (c) 1989, 1990 William F. Jolitz.
3  * Copyright (c) 1990 The Regents of the University of California.
4  * All rights reserved.
5  *
6  * This code is derived from software contributed to Berkeley by
7  * William Jolitz.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
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.
24  *
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
35  * SUCH DAMAGE.
36  *
37  * $FreeBSD: src/sys/i386/isa/icu_ipl.s,v 1.6 1999/08/28 00:44:42 peter Exp $
38  * $DragonFly: src/sys/i386/icu/Attic/icu_ipl.s,v 1.4 2003/06/22 08:54:22 dillon Exp $
39  */
40
41         .data
42         ALIGN_DATA
43 vec:
44         .long    vec0,  vec1,  vec2,  vec3,  vec4,  vec5,  vec6,  vec7
45         .long    vec8,  vec9, vec10, vec11, vec12, vec13, vec14, vec15
46
47 /* interrupt mask enable (all h/w off) */
48         .globl  _imen
49 _imen:  .long   HWI_MASK
50
51
52 /*
53  * 
54  */
55         .text
56         SUPERALIGN_TEXT
57
58 /*
59  * Interrupt priority mechanism
60  *      -- soft splXX masks with group mechanism (cpl)
61  *      -- h/w masks for currently active or unused interrupts (imen)
62  *      -- ipending = active interrupts currently masked by cpl
63  *      -- splz handles pending interrupts regardless of the critical
64  *         nesting state, it is only called synchronously.
65  */
66
67 ENTRY(splz)
68         /*
69          * The caller has restored cpl and checked that (ipending & ~cpl)
70          * is nonzero.  We have to repeat the check since if there is an
71          * interrupt while we're looking, _doreti processing for the
72          * interrupt will handle all the unmasked pending interrupts
73          * because we restored early.  We're repeating the calculation
74          * of (ipending & ~cpl) anyway so that the caller doesn't have
75          * to pass it, so this only costs one "jne".  "bsfl %ecx,%ecx"
76          * is undefined when %ecx is 0 so we can't rely on the secondary
77          * btrl tests.
78          */
79         pushl   %ebx
80         movl    _curthread,%ebx
81         movl    TD_MACH+MTD_CPL(%ebx),%eax
82 splz_next:
83         /*
84          * We don't need any locking here.  (ipending & ~cpl) cannot grow 
85          * while we're looking at it - any interrupt will shrink it to 0.
86          */
87         movl    $0,_reqpri
88         movl    %eax,%ecx
89         notl    %ecx
90         andl    _ipending,%ecx
91         jne     splz_unpend
92         popl    %ebx
93         ret
94
95         ALIGN_TEXT
96 splz_unpend:
97         bsfl    %ecx,%ecx
98         btrl    %ecx,_ipending
99         jnc     splz_next
100         cmpl    $NHWI,%ecx
101         jae     splz_swi
102         /*
103          * We would prefer to call the intr handler directly here but that
104          * doesn't work for badly behaved handlers that want the interrupt
105          * frame.  Also, there's a problem determining the unit number.
106          * We should change the interface so that the unit number is not
107          * determined at config time.
108          */
109         popl    %ebx
110         jmp     *vec(,%ecx,4)
111
112         ALIGN_TEXT
113 splz_swi:
114         pushl   %eax
115         orl     imasks(,%ecx,4),%eax
116         movl    %eax,TD_MACH+MTD_CPL(%ebx)
117         call    *_ihandlers(,%ecx,4)
118         popl    %eax
119         movl    %eax,TD_MACH+MTD_CPL(%ebx)
120         jmp     splz_next
121
122 /*
123  * Fake clock interrupt(s) so that they appear to come from our caller instead
124  * of from here, so that system profiling works.
125  * XXX do this more generally (for all vectors; look up the C entry point).
126  * XXX frame bogusness stops us from just jumping to the C entry point.
127  */
128         ALIGN_TEXT
129 vec0:
130         popl    %eax                    /* return address */
131         pushfl
132         pushl   $KCSEL
133         pushl   %eax
134         cli
135         MEXITCOUNT
136         jmp     _Xintr0                 /* XXX might need _Xfastintr0 */
137
138 #ifndef PC98
139         ALIGN_TEXT
140 vec8:
141         popl    %eax    
142         pushfl
143         pushl   $KCSEL
144         pushl   %eax
145         cli
146         MEXITCOUNT
147         jmp     _Xintr8                 /* XXX might need _Xfastintr8 */
148 #endif /* PC98 */
149
150 /*
151  * The 'generic' vector stubs.
152  */
153
154 #define BUILD_VEC(irq_num)                      \
155         ALIGN_TEXT ;                            \
156 __CONCAT(vec,irq_num): ;                        \
157         int     $ICU_OFFSET + (irq_num) ;       \
158         ret
159
160         BUILD_VEC(1)
161         BUILD_VEC(2)
162         BUILD_VEC(3)
163         BUILD_VEC(4)
164         BUILD_VEC(5)
165         BUILD_VEC(6)
166         BUILD_VEC(7)
167 #ifdef PC98
168         BUILD_VEC(8)
169 #endif
170         BUILD_VEC(9)
171         BUILD_VEC(10)
172         BUILD_VEC(11)
173         BUILD_VEC(12)
174         BUILD_VEC(13)
175         BUILD_VEC(14)
176         BUILD_VEC(15)