/*- * Copyright (c) 1989, 1990 William F. Jolitz. * Copyright (c) 1990 The Regents of the University of California. * All rights reserved. * * This code is derived from software contributed to Berkeley by * William Jolitz. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)icu.s 7.2 (Berkeley) 5/21/91 */ /* * AT/386 * Vector interrupt control section */ .data .globl _imen .globl _cpl _cpl: .long 0xffff # current priority level (all off) _imen: .long 0xffff # interrupt mask enable (all off) .globl _highmask _highmask: .long 0xffff .globl _ttymask _ttymask: .long 0 .globl _biomask _biomask: .long 0 .globl _netmask _netmask: .long 0 .globl _isa_intr _isa_intr: .space 16*4 .text /* * Handle return from interrupt after device handler finishes */ doreti: cli popl %ebx # remove intr number popl %eax # get previous priority # now interrupt frame is a trap frame! movw %ax,%cx movw %ax,_cpl orw _imen,%ax NOP outb %al,$ IO_ICU1+1 # re-enable intr? NOP movb %ah,%al NOP outb %al,$ IO_ICU2+1 NOP inb $0x84,%al andw $0xffff,%cx cmpw $0,%cx # returning to zero? je 1f pop %es # nope, going to non-zero level pop %ds popa addl $8,%esp iret 1: cmpl $0,_netisr # check for softint s/traps jne 1f pop %es # none, going back to base pri pop %ds popa addl $8,%esp iret #include "../net/netisr.h" 1: #define DONET(s, c) ; \ .globl c ; \ movl $ s ,%eax ; \ btrl %eax,_netisr ; \ jnb 1f ; \ call c ; \ 1: call _splnet pushl %eax DONET(NETISR_RAW,_rawintr) #ifdef INET DONET(NETISR_IP,_ipintr) #endif #ifdef IMP DONET(NETISR_IMP,_impintr) #endif #ifdef NS DONET(NETISR_NS,_nsintr) #endif popl %eax movw %ax,_cpl orw _imen,%ax NOP outb %al,$ IO_ICU1+1 # re-enable intr? NOP movb %ah,%al NOP outb %al,$ IO_ICU2+1 NOP inb $0x84,%al # btrl $ NETISR_SCLK,_netisr movl $ NETISR_SCLK,%eax # stupid assembler, as usual btrl %eax,_netisr jnb 1f # back to an interrupt frame for a moment call _splsoftclock pushl %eax pushl $0xff # dummy intr call _softclock popl %eax call _splx popl %eax jmp 2f /* 1: btrl $NETISR_AST,_netisr*/ 1: cmpw $0x1f,13*4(%esp) # to user? jne 2f # nope, leave movl $ NETISR_AST,%eax # stupid assembler, as usual btrl %eax,_netisr jnb 2f call _trap 2: pop %es pop %ds popal addl $8,%esp iret /* * Interrupt priority mechanism * * Two flavors -- imlXX masks relative to ISA noemenclature (for PC compat sw) * -- splXX masks with group mechanism for BSD purposes */ .globl _splhigh .globl _splclock _splhigh: _splclock: cli # disable interrupts movw $0xffff,%ax # set new priority level movw %ax,%dx # orw _imen,%ax # mask off those not enabled yet movw %ax,%cx NOP outb %al,$ IO_ICU1+1 /* update icu's */ NOP movb %ah,%al NOP outb %al,$ IO_ICU2+1 NOP inb $0x84,%al movzwl _cpl,%eax # return old priority movw %dx,_cpl # set new priority level sti # enable interrupts ret .globl _spltty # block clists _spltty: cli # disable interrupts movw _cpl,%ax orw _ttymask,%ax movw %ax,%dx orw _imen,%ax # mask off those not enabled yet movw %ax,%cx NOP outb %al,$ IO_ICU1+1 /* update icu's */ NOP movb %ah,%al NOP outb %al,$ IO_ICU2+1 NOP inb $0x84,%al movzwl _cpl,%eax # return old priority movw %dx,_cpl # set new priority level sti # enable interrupts ret .globl _splimp .globl _splnet _splimp: _splnet: cli # disable interrupts movw _cpl,%ax orw _netmask,%ax movw %ax,%dx orw _imen,%ax # mask off those not enabled yet movw %ax,%cx NOP outb %al,$ IO_ICU1+1 /* update icu's */ NOP movb %ah,%al NOP outb %al,$ IO_ICU2+1 NOP inb $0x84,%al movzwl _cpl,%eax # return old priority movw %dx,_cpl # set new priority level sti # enable interrupts ret .globl _splbio _splbio: cli # disable interrupts movw _cpl,%ax orw _biomask,%ax movw %ax,%dx orw _imen,%ax # mask off those not enabled yet movw %ax,%cx NOP outb %al,$ IO_ICU1+1 /* update icu's */ NOP movb %ah,%al NOP outb %al,$ IO_ICU2+1 NOP inb $0x84,%al movzwl _cpl,%eax # return old priority movw %dx,_cpl # set new priority level sti # enable interrupts ret .globl _splsoftclock _splsoftclock: cli # disable interrupts movw _cpl,%ax orw $0x8000,%ax # set new priority level movw %ax,%dx orw _imen,%ax # mask off those not enabled yet movw %ax,%cx NOP outb %al,$ IO_ICU1+1 /* update icu's */ NOP movb %ah,%al NOP outb %al,$ IO_ICU2+1 NOP inb $0x84,%al movzwl _cpl,%eax # return old priority movw %dx,_cpl # set new priority level sti # enable interrupts ret .globl _splnone .globl _spl0 _splnone: _spl0: cli # disable interrupts pushl _cpl # save old priority movw _cpl,%ax orw _netmask,%ax # mask off those network devices movw %ax,_cpl # set new priority level orw _imen,%ax # mask off those not enabled yet NOP outb %al,$ IO_ICU1+1 /* update icu's */ NOP movb %ah,%al NOP outb %al,$ IO_ICU2+1 NOP inb $0x84,%al sti # enable interrupts DONET(NETISR_RAW,_rawintr) #ifdef INET DONET(NETISR_IP,_ipintr) #endif cli # disable interrupts popl _cpl # save old priority movw $0,%ax # set new priority level movw %ax,%dx orw _imen,%ax # mask off those not enabled yet movw %ax,%cx NOP outb %al,$ IO_ICU1+1 /* update icu's */ NOP movb %ah,%al NOP outb %al,$ IO_ICU2+1 NOP inb $0x84,%al movzwl _cpl,%eax # return old priority movw %dx,_cpl # set new priority level sti # enable interrupts ret .globl _splx _splx: cli # disable interrupts movw 4(%esp),%ax # new priority level movw %ax,%dx cmpw $0,%dx je _spl0 # going to "zero level" is special orw _imen,%ax # mask off those not enabled yet movw %ax,%cx NOP outb %al,$ IO_ICU1+1 /* update icu's */ NOP movb %ah,%al NOP outb %al,$ IO_ICU2+1 NOP inb $0x84,%al movzwl _cpl,%eax # return old priority movw %dx,_cpl # set new priority level sti # enable interrupts ret #ifdef notyet .globl _iml8 # mask off all but irq0-1 _iml8: cli # disable interrupts movw $0xfffc,%ax # set new priority level movw %ax,%dx orw _imen,%ax # mask off those not enabled yet movw %ax,%cx NOP outb %al,$ IO_ICU1+1 /* update icu's */ NOP movb %ah,%al NOP outb %al,$ IO_ICU2+1 NOP movzwl _cpl,%eax # return old priority movw %dx,_cpl # set new priority level sti # enable interrupts ret .globl _iml10 # mask off all but irq0-1,8-9 _iml10: cli # disable interrupts movw $0xfcf8,%ax # set new priority level movw %ax,%dx orw _imen,%ax # mask off those not enabled yet movw %ax,%cx NOP outb %al,$ IO_ICU1+1 /* update icu's */ NOP movb %ah,%al NOP outb %al,$ IO_ICU2+1 NOP movzwl _cpl,%eax # return old priority movw %dx,_cpl # set new priority level sti # enable interrupts ret .globl _iml11 # mask off all but irq0-1,8-10 _iml11: cli # disable interrupts movw $0xf8f8,%ax # set new priority level movw %ax,%dx orw _imen,%ax # mask off those not enabled yet movw %ax,%cx NOP outb %al,$ IO_ICU1+1 /* update icu's */ NOP movb %ah,%al NOP outb %al,$ IO_ICU2+1 NOP movzwl _cpl,%eax # return old priority movw %dx,_cpl # set new priority level sti # enable interrupts ret .globl _iml12 # mask off all but irq0-1,8-11 _iml12: cli # disable interrupts movw $0xf0f8,%ax # set new priority level movw %ax,%dx orw _imen,%ax # mask off those not enabled yet movw %ax,%cx NOP outb %al,$ IO_ICU1+1 /* update icu's */ NOP movb %ah,%al NOP outb %al,$ IO_ICU2+1 NOP movzwl _cpl,%eax # return old priority movw %dx,_cpl # set new priority level sti # enable interrupts ret .globl _iml13 # mask off all but irq0-1,8-12 _iml13: cli # disable interrupts movw $0xe0f8,%ax # set new priority level movw %ax,%dx orw _imen,%ax # mask off those not enabled yet movw %ax,%cx NOP outb %al,$ IO_ICU1+1 /* update icu's */ NOP movb %ah,%al NOP outb %al,$ IO_ICU2+1 NOP movzwl _cpl,%eax # return old priority movw %dx,_cpl # set new priority level sti # enable interrupts ret .globl _iml15 # mask off all but irq0-1,8-14 _iml15: cli # disable interrupts movw $0x80f8,%ax # set new priority level movw %ax,%dx orw _imen,%ax # mask off those not enabled yet movw %ax,%cx NOP outb %al,$ IO_ICU1+1 /* update icu's */ NOP movb %ah,%al NOP outb %al,$ IO_ICU2+1 NOP movzwl _cpl,%eax # return old priority movw %dx,_cpl # set new priority level sti # enable interrupts ret .globl _iml3 # mask off all but irq0-1,8-15 _iml3: cli # disable interrupts movw $0x00f8,%ax # set new priority level movw %ax,%dx orw _imen,%ax # mask off those not enabled yet movw %ax,%cx NOP outb %al,$ IO_ICU1+1 /* update icu's */ NOP movb %ah,%al NOP outb %al,$ IO_ICU2+1 NOP movzwl _cpl,%eax # return old priority movw %dx,_cpl # set new priority level sti # enable interrupts ret .globl _iml4 # mask off all but irq0-1,8-15,3 _iml4: cli # disable interrupts movw $0x00f0,%ax # set new priority level movw %ax,%dx orw _imen,%ax # mask off those not enabled yet movw %ax,%cx NOP outb %al,$ IO_ICU1+1 /* update icu's */ NOP movb %ah,%al NOP outb %al,$ IO_ICU2+1 NOP movzwl _cpl,%eax # return old priority movw %dx,_cpl # set new priority level sti # enable interrupts ret .globl _iml5 # mask off all but irq0-1,8-15,3-4 _iml5: cli # disable interrupts movw $0x00e0,%ax # set new priority level movw %ax,%dx orw _imen,%ax # mask off those not enabled yet movw %ax,%cx NOP outb %al,$ IO_ICU1+1 /* update icu's */ NOP movb %ah,%al NOP outb %al,$ IO_ICU2+1 NOP movzwl _cpl,%eax # return old priority movw %dx,_cpl # set new priority level sti # enable interrupts ret .globl _iml6 # mask off all but irq0-1,8-15,3-5 _iml6: cli # disable interrupts movw $0x00c0,%ax # set new priority level movw %ax,%dx orw _imen,%ax # mask off those not enabled yet movw %ax,%cx NOP outb %al,$ IO_ICU1+1 /* update icu's */ NOP movb %ah,%al NOP outb %al,$ IO_ICU2+1 NOP movzwl _cpl,%eax # return old priority movw %dx,_cpl # set new priority level sti # enable interrupts ret #endif notyet /* hardware interrupt catcher (IDT 32 - 47) */ .globl _isa_strayintr IDTVEC(intr0) INTR(0, _highmask, 0) ; call _isa_strayintr ; INTREXIT1 IDTVEC(intr1) INTR(1, _highmask, 1) ; call _isa_strayintr ; INTREXIT1 IDTVEC(intr2) INTR(2, _highmask, 2) ; call _isa_strayintr ; INTREXIT1 IDTVEC(intr3) INTR(3, _highmask, 3) ; call _isa_strayintr ; INTREXIT1 IDTVEC(intr4) INTR(4, _highmask, 4) ; call _isa_strayintr ; INTREXIT1 IDTVEC(intr5) INTR(5, _highmask, 5) ; call _isa_strayintr ; INTREXIT1 IDTVEC(intr6) INTR(6, _highmask, 6) ; call _isa_strayintr ; INTREXIT1 IDTVEC(intr7) INTR(7, _highmask, 7) ; call _isa_strayintr ; INTREXIT1 IDTVEC(intr8) INTR(8, _highmask, 8) ; call _isa_strayintr ; INTREXIT2 IDTVEC(intr9) INTR(9, _highmask, 9) ; call _isa_strayintr ; INTREXIT2 IDTVEC(intr10) INTR(10, _highmask, 10) ; call _isa_strayintr ; INTREXIT2 IDTVEC(intr11) INTR(11, _highmask, 11) ; call _isa_strayintr ; INTREXIT2 IDTVEC(intr12) INTR(12, _highmask, 12) ; call _isa_strayintr ; INTREXIT2 IDTVEC(intr13) INTR(13, _highmask, 13) ; call _isa_strayintr ; INTREXIT2 IDTVEC(intr14) INTR(14, _highmask, 14) ; call _isa_strayintr ; INTREXIT2 IDTVEC(intr15) INTR(15, _highmask, 15) ; call _isa_strayintr ; INTREXIT2