FreeBSD/Linux Kernel Cross Reference
sys/i386/interrupt.s
1 /*
2 * Mach Operating System
3 * Copyright (c) 1991,1990 Carnegie Mellon University
4 * Copyright (c) 1991 IBM Corporation
5 * All Rights Reserved.
6 *
7 * Permission to use, copy, modify and distribute this software and its
8 * documentation is hereby granted, provided that both the copyright
9 * notice and this permission notice appear in all copies of the
10 * software, derivative works or modified versions, and any portions
11 * thereof, and that both notices appear in supporting documentation,
12 * and that the name IBM not be used in advertising or publicity
13 * pertaining to distribution of the software without specific, written
14 * prior permission.
15 *
16 * CARNEGIE MELLON AND IBM ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS IS"
17 * CONDITION. CARNEGIE MELLON AND IBM DISCLAIM ANY LIABILITY OF ANY KIND FOR
18 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
19 *
20 * Carnegie Mellon requests users of this software to return to
21 *
22 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
23 * School of Computer Science
24 * Carnegie Mellon University
25 * Pittsburgh PA 15213-3890
26 *
27 * any improvements or extensions that they make and grant Carnegie Mellon
28 * the rights to redistribute these changes.
29 */
30
31
32 /*
33 * HISTORY
34 * $Log: interrupt.s,v $
35 * Revision 2.16 93/02/04 07:56:24 danner
36 * Convert asm comment "/" over to "/ *" "* /"
37 * [93/01/28 rvb]
38 *
39 * Integrate PS2 code from IBM.
40 * [93/01/18 prithvi]
41 *
42 * Revision 2.15 92/04/06 01:15:53 rpd
43 * Converted from #-style to /-style comments, for ANSI preprocessors.
44 * [92/04/05 rpd]
45 *
46 * Revision 2.14 91/10/07 17:24:48 af
47 * From mg32: testing for spurious interrupts is bogus.
48 * [91/09/23 rvb]
49 *
50 * Revision 2.13 91/08/28 21:31:06 jsb
51 * Check for out-of-range interrupts.
52 * [91/08/20 dbg]
53 *
54 * Revision 2.12 91/07/31 17:37:31 dbg
55 * Support separate interrupt stack. Interrupt handler may now be
56 * called from different places.
57 * [91/07/30 16:52:19 dbg]
58 *
59 * Revision 2.11 91/06/19 11:55:12 rvb
60 * cputypes.h->platforms.h
61 * [91/06/12 13:44:55 rvb]
62 *
63 * Revision 2.10 91/05/14 16:09:08 mrt
64 * Correcting copyright
65 *
66 * Revision 2.9 91/05/08 12:38:18 dbg
67 * Put parentheses around substituted immediate expressions, so
68 * that they will pass through the GNU preprocessor.
69 *
70 * Use platforms.h. Call version of set_spl that leaves interrupts
71 * disabled (IF clear) until iret.
72 * [91/04/26 14:35:53 dbg]
73 *
74 * Revision 2.8 91/02/05 17:12:22 mrt
75 * Changed to new Mach copyright
76 * [91/02/01 17:34:58 mrt]
77 *
78 * Revision 2.7 91/01/08 17:32:06 rpd
79 * Need special interrupt_return
80 * [90/12/21 14:36:12 rvb]
81 *
82 * Revision 2.6 90/12/20 16:35:58 jeffreyh
83 * Changes for __STDC__
84 * [90/12/07 15:43:38 jeffreyh]
85 *
86 * Revision 2.5 90/12/04 14:46:08 jsb
87 * iPSC2 -> iPSC386.
88 * [90/12/04 11:16:47 jsb]
89 *
90 * Revision 2.4 90/11/26 14:48:33 rvb
91 * Change Prime copyright as per Peter J. Weyman authorization.
92 * [90/11/19 rvb]
93 *
94 * Revision 2.3 90/09/23 17:45:14 jsb
95 * Added support for iPSC2.
96 * [90/09/21 16:40:09 jsb]
97 *
98 * Revision 2.2 90/05/03 15:27:54 dbg
99 * Stole from Prime.
100 * Pass new parameters to clock_interrupt (no longer called
101 * hardclock). Set curr_ipl correctly around call to clock_interrupt.
102 * Moved softclock logic to splx.
103 * Added kdb_kintr to find registers for kdb.
104 * [90/02/14 dbg]
105 *
106 */
107
108 /*
109 Copyright (c) 1988,1989 Prime Computer, Inc. Natick, MA 01760
110 All Rights Reserved.
111
112 Permission to use, copy, modify, and distribute this
113 software and its documentation for any purpose and
114 without fee is hereby granted, provided that the above
115 copyright notice appears in all copies and that both the
116 copyright notice and this permission notice appear in
117 supporting documentation, and that the name of Prime
118 Computer, Inc. not be used in advertising or publicity
119 pertaining to distribution of the software without
120 specific, written prior permission.
121
122 THIS SOFTWARE IS PROVIDED "AS IS", AND PRIME COMPUTER,
123 INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
124 SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
125 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN
126 NO EVENT SHALL PRIME COMPUTER, INC. BE LIABLE FOR ANY
127 SPECIAL, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
128 DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
129 PROFITS, WHETHER IN ACTION OF CONTRACT, NEGLIGENCE, OR
130 OTHER TORTIOUS ACTION, ARISING OUR OF OR IN CONNECTION
131 WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
132 */
133
134 #include <platforms.h>
135
136 #include <i386/asm.h>
137 #include <i386/ipl.h>
138 #include <i386/pic.h>
139 #include <assym.s>
140
141 /*
142 * Called from locore.s. The register save area is on top
143 * of the stack. %eax contains the interrupt number.
144 * Only %ecx and %edx have been saved.
145 */
146 ENTRY(interrupt)
147
148 movl %eax,%ecx /* stash interrupt vector number */
149 subl $0x40,%ecx /* interrupt vectors we use */
150 /* start at 0x40, not 0 */
151 jl int_range_err /* and are between 0x40 */
152 cmpl $15,%ecx /* and 0x4f */
153 jg int_range_err
154
155 #ifndef PS2
156 /*
157 * Now we must acknowledge the interrupt and issue an EOI command to
158 * the pics. We send a NON-SPECIFIC EOI, as we assume that the pic
159 * automatically interrupts us with only the highest priority interrupt.
160 */
161
162 movl _master_icw,%edx /* 2 EOI for master. */
163 movw _PICM_OCW2,%ax /* 2 */
164 outb %al,%dx /* 4 */
165
166 movw _PICS_OCW2,%ax /* 2 EOI for slave. */
167 addw $(SIZE_PIC),%dx /* 2 */
168 outb %al,%dx /* 4 */
169 #endif PS2
170
171 /*
172 * Now we must change the interrupt priority level, with interrupts
173 * turned off. First we get the interrupt number and get
174 * the interrupt level associated with it, then we call set_spl().
175 */
176
177 /*
178 * check for spurious interrupt
179 */
180
181 #ifndef AT386
182 /*
183 The code below seems to do nothing useful for ISA PC's
184 except to make them unable to take interrupts from a second
185 disk controller that would use interrupt level 15
186 */
187 movl _master_icw, %edx
188 #if defined(AT386) || defined(PS2)
189 cmpl $2, %ecx /* ATs slave the second pic on IRQ2 */
190 #else /* AT386 || PS2 */
191 cmpl $7, %ecx /* iPSCs slave the second pic on IRQ7 */
192 #endif /* AT386 || PS2 */
193 je int_check
194 cmpl $15, %ecx /* IRQ15 */
195 jne int_ok
196 addw $(SIZE_PIC),%dx /* 2 */
197 int_check:
198 inb %dx,%al /* read ISR */
199 testb $0x80, %al /* return if IS7 is off */
200 jz interrupt_return
201
202 int_ok:
203 #endif AT386
204 movzbl _intpri(%ecx), %eax /* 4 intpri[int#] */
205 call _set_spl /* interrupts are enabled */
206
207 /*
208 * Interrupts are now enabled. Call the relevant interrupt
209 * handler as per the ivect[] array set up in pic_init.
210 */
211
212 pushl %eax /* 2 save old IPL */
213 #ifdef PS2
214 pushl %ecx /* 2 save intr # */
215 #endif PS2
216 pushl _iunit(,%ecx,4) /* 2 push unit# as int handler arg */
217 call *_ivect(,%ecx,4) /* 4 *ivect[int#]() */
218 addl $4,%esp /* remove interrupt number from stack */
219 #ifdef PS2
220 popl %ecx /* 2 save intr # */
221 #endif PS2
222 cli /* 3 disable interrupts */
223
224 #ifdef PS2
225 /*
226 * Now we must acknowledge the interrupt and issue an EOI command to
227 * the pics, we send a SPECIFIC EOI.
228 */
229 mov %ecx,%eax
230 cmp $7,%ecx
231 jle do_master
232 movl _slaves_icw,%edx /* 2 EOI for slave. */
233 andb $7,%al
234 orb $0x60,%al
235 outb %al,%dx
236 movb $2,%al
237 do_master:
238 movl _master_icw,%edx /* 2 EOI for master. */
239 orb $0x60,%al
240 outb %al,%dx
241 #endif PS2
242
243 /*
244 * 5. Having dealt with the interrupt now we must return to the previous
245 * interrupt priority level. This is done with interrupts turned off.
246 */
247
248 popl %eax /* get old IPL from stack */
249 cmpl _curr_ipl, %eax /* if different from current IPL, */
250 je no_splx
251 call _set_spl_noi /* reset IPL to old value */
252 /* leaving IF off. */
253 no_splx:
254
255 /*
256 * Return to caller.
257 */
258
259 interrupt_return:
260 ret
261
262 /*
263 * Interrupt number out of range.
264 */
265 int_range_err:
266 addl $0x40,%ecx /* restore original interrupt number */
267 pushl %ecx /* push number */
268 pushl $int_range_message /* push message */
269 call _panic /* panic */
270 addl $8,%esp /* pop stack */
271 ret /* return to caller */
272
273 int_range_message:
274 .ascii "Bad interrupt number %#x"
275 .byte 0
276
Cache object: c4b48e61fb8a595b1e9f029fa3bd1287
|