Annotation of sys/arch/i386/i386/apicvec.s, Revision 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