Annotation of sys/arch/i386/i386/apicvec.s, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: apicvec.s,v 1.10 2007/05/25 15:55:26 art Exp $ */
2: /* $NetBSD: apicvec.s,v 1.1.2.2 2000/02/21 21:54:01 sommerfeld Exp $ */
3:
4: /*-
5: * Copyright (c) 2000 The NetBSD Foundation, Inc.
6: * All rights reserved.
7: *
8: * This code is derived from software contributed to The NetBSD Foundation
9: * by RedBack Networks Inc.
10: *
11: * Author: Bill Sommerfeld
12: *
13: * Redistribution and use in source and binary forms, with or without
14: * modification, are permitted provided that the following conditions
15: * are met:
16: * 1. Redistributions of source code must retain the above copyright
17: * notice, this list of conditions and the following disclaimer.
18: * 2. Redistributions in binary form must reproduce the above copyright
19: * notice, this list of conditions and the following disclaimer in the
20: * documentation and/or other materials provided with the distribution.
21: * 3. All advertising materials mentioning features or use of this software
22: * must display the following acknowledgement:
23: * This product includes software developed by the NetBSD
24: * Foundation, Inc. and its contributors.
25: * 4. Neither the name of The NetBSD Foundation nor the names of its
26: * contributors may be used to endorse or promote products derived
27: * from this software without specific prior written permission.
28: *
29: * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
30: * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
31: * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
32: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
33: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
34: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
35: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
36: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
37: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39: * POSSIBILITY OF SUCH DAMAGE.
40: */
41:
42: #include <machine/i82093reg.h>
43: #include <machine/i82489reg.h>
44:
45: #ifdef __ELF__
46: #define XINTR(vec) Xintr/**/vec
47: #else
48: #define XINTR(vec) _Xintr/**/vec
49: #endif
50:
51: .globl _C_LABEL(apic_stray)
52:
53: #ifdef MULTIPROCESSOR
54: .globl XINTR(ipi)
55: XINTR(ipi):
56: pushl $0
57: pushl $T_ASTFLT
58: INTRENTRY
59: MAKE_FRAME
60: pushl CPL
61: movl _C_LABEL(lapic_ppr),%eax
62: movl %eax,CPL
63: ioapic_asm_ack()
64: sti /* safe to take interrupts.. */
65: call _C_LABEL(i386_ipi_handler)
66: cli
67: popl CPL
68: INTRFASTEXIT
69:
70: .globl XINTR(ipi_ast)
71: XINTR(ipi_ast):
72: pushl %eax
73: pushl %ds
74: movl $GSEL(GDATA_SEL, SEL_KPL), %eax
75: movl %eax, %ds
76:
77: ioapic_asm_ack()
78:
79: movl $IPL_SOFTAST, %eax
80: orl $(1 << SIR_AST), _C_LABEL(ipending)
81:
82: orl $(LAPIC_DLMODE_FIXED|LAPIC_LVL_ASSERT|LAPIC_DEST_SELF), %eax
83: movl %eax, _C_LABEL(local_apic) + LAPIC_ICRLO
84:
85: movl _C_LABEL(local_apic) + LAPIC_ID, %eax
86: popl %ds
87: popl %eax
88: iret
89:
90: .globl XINTR(ipi_invltlb)
91: .p2align 4,0x90
92: XINTR(ipi_invltlb):
93: pushl %eax
94: pushl %ds
95: movl $GSEL(GDATA_SEL, SEL_KPL), %eax
96: movl %eax, %ds
97:
98: ioapic_asm_ack()
99:
100: movl %cr3, %eax
101: movl %eax, %cr3
102:
103: lock
104: decl tlb_shoot_wait
105:
106: popl %ds
107: popl %eax
108: iret
109:
110: .globl XINTR(ipi_invlpg)
111: .p2align 4,0x90
112: XINTR(ipi_invlpg):
113: pushl %eax
114: pushl %ds
115: movl $GSEL(GDATA_SEL, SEL_KPL), %eax
116: movl %eax, %ds
117:
118: ioapic_asm_ack()
119:
120: movl tlb_shoot_addr1, %eax
121: invlpg (%eax)
122:
123: lock
124: decl tlb_shoot_wait
125:
126: popl %ds
127: popl %eax
128: iret
129:
130: .globl XINTR(ipi_invlrange)
131: .p2align 4,0x90
132: XINTR(ipi_invlrange):
133: pushl %eax
134: pushl %edx
135: pushl %ds
136: movl $GSEL(GDATA_SEL, SEL_KPL), %eax
137: movl %eax, %ds
138:
139: ioapic_asm_ack()
140:
141: movl tlb_shoot_addr1, %eax
142: movl tlb_shoot_addr2, %edx
143: 1: invlpg (%eax)
144: addl $PAGE_SIZE, %eax
145: cmpl %edx, %eax
146: jb 1b
147:
148: lock
149: decl tlb_shoot_wait
150:
151: popl %ds
152: popl %edx
153: popl %eax
154: iret
155:
156: #endif
157:
158: /*
159: * Interrupt from the local APIC timer.
160: */
161: .globl XINTR(ltimer)
162: XINTR(ltimer):
163: pushl $0
164: pushl $T_ASTFLT
165: INTRENTRY
166: MAKE_FRAME
167: pushl CPL
168: movl _C_LABEL(lapic_ppr),%eax
169: movl %eax,CPL
170: ioapic_asm_ack()
171: sti
172: #ifdef MULTIPROCESSOR
173: call _C_LABEL(i386_softintlock)
174: #endif
175: movl %esp,%eax
176: pushl %eax
177: call _C_LABEL(lapic_clockintr)
178: addl $4,%esp
179: #ifdef MULTIPROCESSOR
180: call _C_LABEL(i386_softintunlock)
181: #endif
182: jmp _C_LABEL(Xdoreti)
183:
184: .globl XINTR(softclock), XINTR(softnet), XINTR(softtty), XINTR(softast)
185: XINTR(softclock):
186: pushl $0
187: pushl $T_ASTFLT
188: INTRENTRY
189: MAKE_FRAME
190: pushl CPL
191: movl $IPL_SOFTCLOCK,CPL
192: andl $~(1<<SIR_CLOCK),_C_LABEL(ipending)
193: ioapic_asm_ack()
194: sti
195: #ifdef MULTIPROCESSOR
196: call _C_LABEL(i386_softintlock)
197: #endif
198: call _C_LABEL(softclock)
199: #ifdef MULTIPROCESSOR
200: call _C_LABEL(i386_softintunlock)
201: #endif
202: jmp _C_LABEL(Xdoreti)
203:
204: #define DONETISR(s, c) \
205: .globl _C_LABEL(c) ;\
206: testl $(1 << s),%edi ;\
207: jz 1f ;\
208: call _C_LABEL(c) ;\
209: 1:
210:
211: XINTR(softnet):
212: pushl $0
213: pushl $T_ASTFLT
214: INTRENTRY
215: MAKE_FRAME
216: pushl CPL
217: movl $IPL_SOFTNET,CPL
218: andl $~(1<<SIR_NET),_C_LABEL(ipending)
219: ioapic_asm_ack()
220: sti
221: #ifdef MULTIPROCESSOR
222: call _C_LABEL(i386_softintlock)
223: #endif
224: xorl %edi,%edi
225: xchgl _C_LABEL(netisr),%edi
226: #include <net/netisr_dispatch.h>
227: #ifdef MULTIPROCESSOR
228: call _C_LABEL(i386_softintunlock)
229: #endif
230: jmp _C_LABEL(Xdoreti)
231: #undef DONETISR
232:
233: XINTR(softtty):
234: pushl $0
235: pushl $T_ASTFLT
236: INTRENTRY
237: MAKE_FRAME
238: pushl CPL
239: movl $IPL_SOFTTTY,CPL
240: andl $~(1<<SIR_TTY),_C_LABEL(ipending)
241: ioapic_asm_ack()
242: sti
243: #ifdef MULTIPROCESSOR
244: call _C_LABEL(i386_softintlock)
245: #endif
246: call _C_LABEL(comsoft)
247: #ifdef MULTIPROCESSOR
248: call _C_LABEL(i386_softintunlock)
249: #endif
250: jmp _C_LABEL(Xdoreti)
251:
252: XINTR(softast):
253: pushl $0
254: pushl $T_ASTFLT
255: INTRENTRY
256: MAKE_FRAME
257: pushl CPL
258: movl $IPL_SOFTAST,CPL
259: andl $~(1<<SIR_AST),_C_LABEL(ipending)
260: ioapic_asm_ack()
261: sti
262: jmp _C_LABEL(Xdoreti)
263:
264: #if NIOAPIC > 0
265:
266: #define voidop(num)
267:
268: /*
269: * I/O APIC interrupt.
270: * We sort out which one is which based on the value of
271: * the processor priority register.
272: *
273: * XXX use cmove when appropriate.
274: */
275:
276: #define APICINTR(name, num, early_ack, late_ack, mask, unmask, level_mask) \
277: _C_LABEL(Xintr_/**/name/**/num): \
278: pushl $0 ;\
279: pushl $T_ASTFLT ;\
280: INTRENTRY ;\
281: MAKE_FRAME ;\
282: pushl CPL ;\
283: movl _C_LABEL(lapic_ppr),%eax ;\
284: orl $num,%eax ;\
285: movl _C_LABEL(apic_maxlevel)(,%eax,4),%ebx ;\
286: movl %ebx,CPL ;\
287: mask(num) /* mask it in hardware */ ;\
288: early_ack(num) /* and allow other intrs */ ;\
289: incl MY_COUNT+V_INTR /* statistical info */ ;\
290: sti ;\
291: incl _C_LABEL(apic_intrcount)(,%eax,4) ;\
292: movl _C_LABEL(apic_intrhand)(,%eax,4),%ebx /* chain head */ ;\
293: testl %ebx,%ebx ;\
294: jz _C_LABEL(Xstray_/**/name/**/num) ;\
295: APIC_STRAY_INIT /* nobody claimed it yet */ ;\
296: 7: \
297: LOCK_KERNEL(IF_PPL(%esp)) ;\
298: movl IH_ARG(%ebx),%eax /* get handler arg */ ;\
299: testl %eax,%eax ;\
300: jnz 6f ;\
301: movl %esp,%eax /* 0 means frame pointer */ ;\
302: 6: \
303: pushl %eax ;\
304: call *IH_FUN(%ebx) /* call it */ ;\
305: addl $4,%esp /* toss the arg */ ;\
306: APIC_STRAY_INTEGRATE /* maybe he claimed it */ ;\
307: orl %eax,%eax /* should it be counted? */ ;\
308: jz 4f ;\
309: addl $1,IH_COUNT(%ebx) /* count the intrs */ ;\
310: adcl $0,IH_COUNT+4(%ebx) ;\
311: 4: \
312: UNLOCK_KERNEL(IF_PPL(%esp)) ;\
313: movl IH_NEXT(%ebx),%ebx /* next handler in chain */ ;\
314: testl %ebx,%ebx ;\
315: jnz 7b ;\
316: APIC_STRAY_TEST(name,num) /* see if it's a stray */ ;\
317: 8: \
318: unmask(num) /* unmask it in hardware */ ;\
319: late_ack(num) ;\
320: jmp _C_LABEL(Xdoreti) ;\
321: _C_LABEL(Xstray_/**/name/**/num): \
322: pushl $num ;\
323: call _C_LABEL(apic_stray) ;\
324: addl $4,%esp ;\
325: jmp 8b ;\
326:
327: #if defined(DEBUG)
328: #define APIC_STRAY_INIT \
329: xorl %esi,%esi
330: #define APIC_STRAY_INTEGRATE \
331: orl %eax,%esi
332: #define APIC_STRAY_TEST(name,num) \
333: testl %esi,%esi ;\
334: jz _C_LABEL(Xstray_/**/name/**/num)
335: #else /* !DEBUG */
336: #define APIC_STRAY_INIT
337: #define APIC_STRAY_INTEGRATE
338: #define APIC_STRAY_TEST(name,num)
339: #endif /* DEBUG */
340:
341: APICINTR(ioapic,0, voidop, ioapic_asm_ack, voidop, voidop, voidop)
342: APICINTR(ioapic,1, voidop, ioapic_asm_ack, voidop, voidop, voidop)
343: APICINTR(ioapic,2, voidop, ioapic_asm_ack, voidop, voidop, voidop)
344: APICINTR(ioapic,3, voidop, ioapic_asm_ack, voidop, voidop, voidop)
345: APICINTR(ioapic,4, voidop, ioapic_asm_ack, voidop, voidop, voidop)
346: APICINTR(ioapic,5, voidop, ioapic_asm_ack, voidop, voidop, voidop)
347: APICINTR(ioapic,6, voidop, ioapic_asm_ack, voidop, voidop, voidop)
348: APICINTR(ioapic,7, voidop, ioapic_asm_ack, voidop, voidop, voidop)
349: APICINTR(ioapic,8, voidop, ioapic_asm_ack, voidop, voidop, voidop)
350: APICINTR(ioapic,9, voidop, ioapic_asm_ack, voidop, voidop, voidop)
351: APICINTR(ioapic,10, voidop, ioapic_asm_ack, voidop, voidop, voidop)
352: APICINTR(ioapic,11, voidop, ioapic_asm_ack, voidop, voidop, voidop)
353: APICINTR(ioapic,12, voidop, ioapic_asm_ack, voidop, voidop, voidop)
354: APICINTR(ioapic,13, voidop, ioapic_asm_ack, voidop, voidop, voidop)
355: APICINTR(ioapic,14, voidop, ioapic_asm_ack, voidop, voidop, voidop)
356: APICINTR(ioapic,15, voidop, ioapic_asm_ack, voidop, voidop, voidop)
357:
358: .globl _C_LABEL(Xintr_ioapic0),_C_LABEL(Xintr_ioapic1)
359: .globl _C_LABEL(Xintr_ioapic2),_C_LABEL(Xintr_ioapic3)
360: .globl _C_LABEL(Xintr_ioapic4),_C_LABEL(Xintr_ioapic5)
361: .globl _C_LABEL(Xintr_ioapic6),_C_LABEL(Xintr_ioapic7)
362: .globl _C_LABEL(Xintr_ioapic8),_C_LABEL(Xintr_ioapic9)
363: .globl _C_LABEL(Xintr_ioapic10),_C_LABEL(Xintr_ioapic11)
364: .globl _C_LABEL(Xintr_ioapic12),_C_LABEL(Xintr_ioapic13)
365: .globl _C_LABEL(Xintr_ioapic14),_C_LABEL(Xintr_ioapic15)
366: .globl _C_LABEL(apichandler)
367:
368: _C_LABEL(apichandler):
369: .long _C_LABEL(Xintr_ioapic0),_C_LABEL(Xintr_ioapic1)
370: .long _C_LABEL(Xintr_ioapic2),_C_LABEL(Xintr_ioapic3)
371: .long _C_LABEL(Xintr_ioapic4),_C_LABEL(Xintr_ioapic5)
372: .long _C_LABEL(Xintr_ioapic6),_C_LABEL(Xintr_ioapic7)
373: .long _C_LABEL(Xintr_ioapic8),_C_LABEL(Xintr_ioapic9)
374: .long _C_LABEL(Xintr_ioapic10),_C_LABEL(Xintr_ioapic11)
375: .long _C_LABEL(Xintr_ioapic12),_C_LABEL(Xintr_ioapic13)
376: .long _C_LABEL(Xintr_ioapic14),_C_LABEL(Xintr_ioapic15)
377:
378: #endif
379:
CVSweb