FreeBSD/Linux Kernel Cross Reference
sys/i386/spl.s
1 /*
2 * Mach Operating System
3 * Copyright (c) 1991,1990 Carnegie Mellon University
4 * All Rights Reserved.
5 *
6 * Permission to use, copy, modify and distribute this software and its
7 * documentation is hereby granted, provided that both the copyright
8 * notice and this permission notice appear in all copies of the
9 * software, derivative works or modified versions, and any portions
10 * thereof, and that both notices appear in supporting documentation.
11 *
12 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
13 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
14 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
15 *
16 * Carnegie Mellon requests users of this software to return to
17 *
18 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
19 * School of Computer Science
20 * Carnegie Mellon University
21 * Pittsburgh PA 15213-3890
22 *
23 * any improvements or extensions that they make and grant Carnegie Mellon
24 * the rights to redistribute these changes.
25 */
26 /*
27 * HISTORY
28 * $Log: spl.s,v $
29 * Revision 2.9 93/02/04 07:58:11 danner
30 * Convert asm comment "/" over to "/ *" "* /"
31 * [93/01/27 rvb]
32 *
33 * Revision 2.8 91/06/06 17:04:01 jsb
34 * Added spldcm for i386ipsc.
35 * [91/05/13 16:53:38 jsb]
36 *
37 * Revision 2.7 91/05/14 16:16:41 mrt
38 * Correcting copyright
39 *
40 * Revision 2.6 91/05/08 12:42:29 dbg
41 * Put parentheses around substituted immediate expressions, so
42 * that they will pass through the GNU preprocessor.
43 *
44 * Add set_spl_noi to reset PIC masks but leave interrupts disabled
45 * (IF clear).
46 * [91/04/26 14:38:31 dbg]
47 *
48 * Revision 2.5 91/02/05 17:14:45 mrt
49 * Changed to new Mach copyright
50 * [91/02/01 17:38:06 mrt]
51 *
52 * Revision 2.4 90/12/20 16:36:50 jeffreyh
53 * Changes for __STDC__
54 * [90/12/07 jeffreyh]
55 *
56 * Revision 2.3 90/11/26 14:48:50 rvb
57 * Change Prime copyright as per Peter J. Weyman authorization.
58 * [90/11/19 rvb]
59 *
60 * Revision 2.2 90/05/03 15:37:36 dbg
61 * Stole from Prime.
62 * [90/02/14 dbg]
63 *
64 */
65
66 /*
67 Copyright (c) 1988,1989 Prime Computer, Inc. Natick, MA 01760
68 All Rights Reserved.
69
70 Permission to use, copy, modify, and distribute this
71 software and its documentation for any purpose and
72 without fee is hereby granted, provided that the above
73 copyright notice appears in all copies and that both the
74 copyright notice and this permission notice appear in
75 supporting documentation, and that the name of Prime
76 Computer, Inc. not be used in advertising or publicity
77 pertaining to distribution of the software without
78 specific, written prior permission.
79
80 THIS SOFTWARE IS PROVIDED "AS IS", AND PRIME COMPUTER,
81 INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
82 SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
83 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN
84 NO EVENT SHALL PRIME COMPUTER, INC. BE LIABLE FOR ANY
85 SPECIAL, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
86 DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
87 PROFITS, WHETHER IN ACTION OF CONTRACT, NEGLIGENCE, OR
88 OTHER TORTIOUS ACTION, ARISING OUR OF OR IN CONNECTION
89 WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
90 */
91
92 #include <i386/asm.h>
93 #include <i386/ipl.h>
94 #include <i386/pic.h>
95
96 /* *****************************************************************************
97 SET_PIC_MASK : this routine is run to set the pic masks. It is
98 implemented as a macro for efficiency reasons.
99 ***************************************************************************** */
100
101 #define SET_PIC_MASK \
102 movl EXT(master_ocw),%edx ; \
103 OUTB ; \
104 addw $(SIZE_PIC),%dx ; \
105 movb %ah,%al ; \
106 OUTB
107
108 /* *****************************************************************************
109 SPLn : change interrupt priority level to that in %eax
110 SPLOFF : disable all interrupts, saving interrupt flag
111 SPLON: re-enable interrupt flag, undoes sploff()
112 Warning: SPLn and SPLOFF aren`t nestable. That is,
113 a = sploff();
114 ...
115 b = splmumble();
116 ...
117 splx(b);
118 ...
119 splon(a);
120 is going to do the wrong thing.
121 ***************************************************************************** */
122
123 ENTRY(spl0)
124 movl $(SPL0), %eax
125 jmp EXT(set_spl)
126
127 ENTRY(spl1)
128 ENTRY(splsoftclock)
129 movl $(SPL1), %eax
130 jmp EXT(set_spl)
131
132 ENTRY(spl2)
133 movl $(SPL2), %eax
134 jmp EXT(set_spl)
135
136 ENTRY(spl3)
137 movl $(SPL3), %eax
138 jmp EXT(set_spl)
139
140 ENTRY(splnet)
141 ENTRY(splhdw)
142 ENTRY(spl4)
143 movl $(SPL4), %eax
144 jmp EXT(set_spl)
145
146 ENTRY(splbio)
147 ENTRY(spldcm)
148 ENTRY(spl5)
149 movl $(SPL5), %eax
150 jmp EXT(set_spl)
151
152 ENTRY(spltty)
153 ENTRY(spl6)
154 movl $(SPL6), %eax
155 jmp EXT(set_spl)
156
157 ENTRY(splclock)
158 ENTRY(splimp)
159 ENTRY(splvm)
160 ENTRY(splsched)
161 ENTRY(splhigh)
162 ENTRY(splhi)
163 ENTRY(spl7)
164
165 cli /* 3 disable interrupts */
166 movl EXT(curr_ipl),%eax /* 4 */
167 movl $(IPLHI), EXT(curr_ipl) /* 2 */
168 ret /* 10 */
169 /* ------ */
170 /* 19 */
171
172 ENTRY(sploff) /* 7 */
173 pushf /* 2 Flags reg NOT accessable */
174 popl %eax /* 2 push onto stk, pop it into reg. */
175 cli /* 3 DISABLE ALL INTERRUPTS */
176 ret /* 7 */
177 /* ------ */
178 /* 21 */
179
180 ENTRY(splon) /* 7 */
181 pushl 4(%esp) /* 4 Flags regs not directly settable. */
182 popf /* 4 push value, pop into flags reg. */
183 /* IF ints were enabled before */
184 /* then they are re-enabled now. */
185 ret /* 7 */
186 /* ------ */
187 /* 22 */
188
189 /* ******************************************************************************
190 SPL : this routine sets the interrupt priority level, it is called from
191 one of the above spln subroutines ONLY, NO-ONE should EVER call set_spl
192 directly as it assumes that the parameters passed in are gospel.
193 SPLX : This routine is used to set the ipl BACK to a level it was at
194 before spln() was called, which in turn calls set_spl(), which returns
195 (via %eax) the value of the curr_ipl prior to spln() being called, this
196 routine is passed this level and so must check that it makes sense and
197 if so then simply calls set_spl() with the appropriate interrupt level.
198 ***************************************************************************** */
199
200 ENTRY(splx)
201 movl 0x04(%esp),%eax /* 4 get interrupt level from stack */
202
203 cmpl $0x00,%eax /* 2 check if < 0 */
204 jl splxpanic /* 3 */
205
206 cmpl $(SPLHI),%eax /* 2 check if too high */
207 ja splxpanic /* 3 */
208 /* ------ */
209 /* 14 */
210
211 /* *****************************************************************************
212 SET_SPL : This routine sets curr_spl, ipl, and the pic_mask as
213 appropriate, basically given an spl# to adopt, see if it is the same as
214 the old spl#, if so return. If the numbers are different, then set
215 curr_spl, now check the corresponding ipl for the spl requested, if they
216 are the same then return otherwise set the new ipl and set the pic masks
217 accordingly.
218 ***************************************************************************** */
219
220 .globl EXT(set_spl)
221 LEXT(set_spl)
222 pushl %ebp /* 2 */
223 movl %esp,%ebp /* 2 */
224 cli /* 3 disable interrupts */
225 movl EXT(curr_ipl), %edx /* 4 get OLD ipl level */
226 pushl %edx /* 2 save old level for return */
227 set_spl_recur:
228 movl %eax,EXT(curr_ipl) /* 4 set NEW ipl level */
229 cmpl $(SPLHI), %eax /* 2 if SPLHI */
230 je spl_intoff /* 3 return with interrupt off */
231 cmpl $(SPL0), %eax /* if SPL0 */
232 jne 0f /* and */
233 cmpl $0,EXT(dotimein) /* softclock request, */
234 jz 0f /* take a softclock interrupt first */
235 call do_soft_clock
236 jmp set_spl_recur
237 0:
238 movw EXT(pic_mask)(,%eax,2), %ax /* 5 */
239 cmpw EXT(curr_pic_mask),%ax /* 5 */
240 je spl_return /* 7 */
241 movw %ax, EXT(curr_pic_mask)
242 SET_PIC_MASK /*16 */
243 spl_return:
244 sti /* 3 */
245 spl_intoff:
246 popl %eax /* 2 return old level */
247 pop %ebp /* 2 */
248 ret /*10 */
249 /* ----- */
250 /* 79 */
251
252 splxpanic:
253 pushl EXT(curr_ipl) /* current level */
254 pushl %eax /* new level */
255 pushl $splxpanic2
256 call EXT(panic)
257 hlt
258
259 .data
260 splxpanic2:
261 String "splx(old %x, new %x): logic error in locore.s\n"
262 .byte 0
263 .text
264
265 /*
266 * Take a softclock interrupt request.
267 */
268 do_soft_clock:
269 movl $0,EXT(dotimein) /* clear softclock request */
270 movl $(SPL1),%eax
271 call EXT(set_spl) /* run at spl1 */
272 call EXT(softclock) /* run softclock interrupt */
273 movl $(SPL0),%eax /* return to spl0 */
274 cli /* disable interrupts */
275 ret
276
277 ENTRY(setsoftclock)
278 movl $1,EXT(dotimein) /* request soft-clock interrupt */
279 ret
280
281 .data
282 .globl EXT(dotimein)
283 LEXT(dotimein)
284 .long 0
285 .text
286
287 /*
288 * Set SPL, but leave interrupts disabled. Called when returning
289 * from interrupt. Interrupts are already disabled.
290 * New interrupt level is in %eax;
291 * can't be SPLHI.
292 */
293 .globl EXT(set_spl_noi)
294 LEXT(set_spl_noi)
295 movl %eax,EXT(curr_ipl) /* set new SPL level */
296 cmpl $(SPL0),%eax /* if SPL0 */
297 jne 0f /* and */
298 cmpl $0,EXT(dotimein) /* softclock request, */
299 jz 0f /* take a softclock interrupt first */
300 call do_soft_clock
301 jmp EXT(set_spl_noi)
302 0:
303 movw EXT(pic_mask)(,%eax,2), %ax /* get new pic mask */
304 cmpw EXT(curr_pic_mask),%ax /* if different, */
305 je 1f
306 movw %ax,EXT(curr_pic_mask) /* change it */
307 SET_PIC_MASK
308 1:
309 ret
310
Cache object: 431caacb01c599c0ace2a345a85bee9d
|