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