NetBSD/sys/arch/i386/isa/icu.s
cgd 9dc3975ffe from Rodney W. Grimes (rgrimes@agora.rain.com) (patchkit patch 117):
This patch adds the symbol names to icu.s that vmstat expects
the interrupt counters to be called.  It also adds code to config
so that the names of the interrupts are written at the end of vectors.s
so vmstat can report real device names.  It also cleans up and enables
the logging of stray interrupts.  The counters for false interrupts
are added but the fix for them is not (the fix I have is not done
very good.) A false interrupt is when a device asserts it's interrupt
signal, then removes it before the 8259 can latch it.  This is the number
one cause of stray IRQ7's and IRQ15's.

	Additional device probe information is now printed.  This includes
ending I/O address (many drivers do not return the correct value from a
probe this still needs to be fixed), memory address and size, driver
flags passed in by config.
1993-04-09 13:27:46 +00:00

410 lines
9.2 KiB
ArmAsm

/*-
* 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
ALIGN32
.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
/*
* This is the names of the counters for vmstat added by
* rgrimes@agora.rain.com (Rodney W. Grimes) 10/30/1992
* Added false and stray counters 3/25/1993 rgrimes
*/
.globl _intrcnt, _eintrcnt /* Added to make vmstat happy */
.globl _isa_false7_intrcnt, _isa_false15_intrcnt, _isa_stray_intrcnt
_intrcnt: /* Added to make vmstat happy */
_isa_false7_intrcnt:
.space 4 /* false IRQ7's */
_isa_false15_intrcnt:
.space 4 /* false IRQ15's */
_isa_stray_intrcnt:
.space 4 /* stray interrupts */
_isa_intr: .space 16*4
_eintrcnt: /* Added to make vmstat happy */
.text
/*
* Handle return from interrupt after device handler finishes
*/
ALIGN32
doreti:
cli
popl %ebx # remove intr number
NOP
popl %eax # get previous priority
# now interrupt frame is a trap frame!
movw %ax,%cx
movw %ax,_cpl
orw _imen,%ax
outb %al,$ IO_ICU1+1 # re-enable intr?
NOP
movb %ah,%al
outb %al,$ IO_ICU2+1
NOP
cmpw $0x1f,13*4(%esp) # to user?
je 1f # nope, leave
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
ALIGN32
1: cmpl $0,_netisr # check for softint s/traps
jne 1f
cmpl $0,_want_resched
jne 1f
pop %es # none, going back to base pri
pop %ds
popa
addl $8,%esp
iret
#include "../net/netisr.h"
ALIGN32
1:
#define DONET(s, c) ; \
.globl c ; \
btrl $ s ,_netisr ; \
jnb 1f ; \
call c ; \
1:
call _splnet
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
#ifdef notdef
NOP
popl %eax
movw %ax,_cpl
orw _imen,%ax
outb %al,$ IO_ICU1+1 # re-enable intr?
NOP
movb %ah,%al
outb %al,$ IO_ICU2+1
NOP
#else
call _spl0
#endif
btrl $ NETISR_SCLK,_netisr
jnb 1f
# back to an interrupt frame for a moment
call _splsoftclock
pushl $0xff # dummy intr
call _softclock
popl %eax
call _spl0
# jmp 2f
1:
cmpw $0x1f,13*4(%esp) # to user?
jne 2f # nope, leave
cmpl $0,_want_resched
je 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
ALIGN32
_splhigh:
_splclock:
cli # disable interrupts
NOP
movw $0xffff,%ax # set new priority level
movw %ax,%dx
# orw _imen,%ax # mask off those not enabled yet
movw %ax,%cx
outb %al,$ IO_ICU1+1 /* update icu's */
NOP
movb %ah,%al
outb %al,$ IO_ICU2+1
NOP
movzwl _cpl,%eax # return old priority
movw %dx,_cpl # set new priority level
sti # enable interrupts
ret
.globl _spltty # block clists
ALIGN32
_spltty:
cli # disable interrupts
NOP
movw _cpl,%ax
orw _ttymask,%ax
movw %ax,%dx
orw _imen,%ax # mask off those not enabled yet
movw %ax,%cx
outb %al,$ IO_ICU1+1 /* update icu's */
NOP
movb %ah,%al
outb %al,$ IO_ICU2+1
NOP
movzwl _cpl,%eax # return old priority
movw %dx,_cpl # set new priority level
sti # enable interrupts
ret
.globl _splimp
.globl _splnet
ALIGN32
_splimp:
_splnet:
cli # disable interrupts
NOP
movw _cpl,%ax
orw _netmask,%ax
movw %ax,%dx
orw _imen,%ax # mask off those not enabled yet
movw %ax,%cx
outb %al,$ IO_ICU1+1 /* update icu's */
NOP
movb %ah,%al
outb %al,$ IO_ICU2+1
NOP
movzwl _cpl,%eax # return old priority
movw %dx,_cpl # set new priority level
sti # enable interrupts
ret
.globl _splbio
ALIGN32
_splbio:
cli # disable interrupts
NOP
movw _cpl,%ax
orw _biomask,%ax
movw %ax,%dx
orw _imen,%ax # mask off those not enabled yet
movw %ax,%cx
outb %al,$ IO_ICU1+1 /* update icu's */
NOP
movb %ah,%al
outb %al,$ IO_ICU2+1
NOP
movzwl _cpl,%eax # return old priority
movw %dx,_cpl # set new priority level
sti # enable interrupts
ret
.globl _splsoftclock
ALIGN32
_splsoftclock:
cli # disable interrupts
NOP
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
outb %al,$ IO_ICU1+1 /* update icu's */
NOP
movb %ah,%al
outb %al,$ IO_ICU2+1
NOP
movzwl _cpl,%eax # return old priority
movw %dx,_cpl # set new priority level
sti # enable interrupts
ret
.globl _splnone
.globl _spl0
ALIGN32
_splnone:
_spl0:
cli # disable interrupts
NOP
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
outb %al,$ IO_ICU1+1 /* update icu's */
NOP
movb %ah,%al
outb %al,$ IO_ICU2+1
NOP
sti # enable interrupts
DONET(NETISR_RAW,_rawintr)
#ifdef INET
DONET(NETISR_IP,_ipintr)
#endif
cli # disable interrupts
popl _cpl # save old priority
NOP
movw $0,%ax # set new priority level
movw %ax,%dx
orw _imen,%ax # mask off those not enabled yet
movw %ax,%cx
outb %al,$ IO_ICU1+1 /* update icu's */
NOP
movb %ah,%al
outb %al,$ IO_ICU2+1
NOP
movzwl _cpl,%eax # return old priority
movw %dx,_cpl # set new priority level
sti # enable interrupts
ret
.globl _splx
ALIGN32
_splx:
cli # disable interrupts
NOP
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
outb %al,$ IO_ICU1+1 /* update icu's */
NOP
movb %ah,%al
outb %al,$ IO_ICU2+1
NOP
movzwl _cpl,%eax # return old priority
movw %dx,_cpl # set new priority level
sti # enable interrupts
ret
/* hardware interrupt catcher (IDT 32 - 47) */
.globl _isa_strayintr
IDTVEC(intr0)
INTRSTRAY(0, _highmask, 0) ; call _isa_strayintr ; INTREXIT1
IDTVEC(intr1)
INTRSTRAY(1, _highmask, 1) ; call _isa_strayintr ; INTREXIT1
IDTVEC(intr2)
INTRSTRAY(2, _highmask, 2) ; call _isa_strayintr ; INTREXIT1
IDTVEC(intr3)
INTRSTRAY(3, _highmask, 3) ; call _isa_strayintr ; INTREXIT1
IDTVEC(intr4)
INTRSTRAY(4, _highmask, 4) ; call _isa_strayintr ; INTREXIT1
IDTVEC(intr5)
INTRSTRAY(5, _highmask, 5) ; call _isa_strayintr ; INTREXIT1
IDTVEC(intr6)
INTRSTRAY(6, _highmask, 6) ; call _isa_strayintr ; INTREXIT1
IDTVEC(intr7)
INTRSTRAY(7, _highmask, 7) ; call _isa_strayintr ; INTREXIT1
IDTVEC(intr8)
INTRSTRAY(8, _highmask, 8) ; call _isa_strayintr ; INTREXIT2
IDTVEC(intr9)
INTRSTRAY(9, _highmask, 9) ; call _isa_strayintr ; INTREXIT2
IDTVEC(intr10)
INTRSTRAY(10, _highmask, 10) ; call _isa_strayintr ; INTREXIT2
IDTVEC(intr11)
INTRSTRAY(11, _highmask, 11) ; call _isa_strayintr ; INTREXIT2
IDTVEC(intr12)
INTRSTRAY(12, _highmask, 12) ; call _isa_strayintr ; INTREXIT2
IDTVEC(intr13)
INTRSTRAY(13, _highmask, 13) ; call _isa_strayintr ; INTREXIT2
IDTVEC(intr14)
INTRSTRAY(14, _highmask, 14) ; call _isa_strayintr ; INTREXIT2
IDTVEC(intr15)
INTRSTRAY(15, _highmask, 15) ; call _isa_strayintr ; INTREXIT2
IDTVEC(intrdefault)
INTRSTRAY(255, _highmask, 255) ; call _isa_strayintr ; INTREXIT2