1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
/*
* Copyright (c) 1995 Shantanu Goel
* All Rights Reserved.
*
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
*
* THE AUTHOR ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
* CONDITION. THE AUTHOR DISCLAIMS ANY LIABILITY OF ANY KIND FOR
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
*/
#include <mach/machine/asm.h>
#include <i386/ipl.h>
#include <i386/pic.h>
#include <i386/i386asm.h>
#define READ_ISR (OCW_TEMPLATE|READ_NEXT_RD|READ_IS_ONRD)
/*
* Generic interrupt handler.
*
* On entry, %eax contains the irq number.
*/
ENTRY(interrupt)
movl %eax,%ecx /* save irq number */
movb $(NON_SPEC_EOI),%al /* non-specific EOI */
outb %al,$(PIC_MASTER_ICW) /* ack interrupt to master */
cmpl $8,%ecx /* do we need to ack slave? */
jl 1f /* no, skip it */
outb %al,$(PIC_SLAVE_ICW)
1:
shll $2,%ecx /* irq * 4 */
movl EXT(intpri)(%ecx),%edx /* get new ipl */
call spl /* set ipl */
movl EXT(iunit)(%ecx),%edx /* get device unit number */
pushl %eax /* push previous ipl */
pushl %edx /* push unit number */
call *EXT(ivect)(%ecx) /* call interrupt handler */
addl $4,%esp /* pop unit number */
call splx_cli /* restore previous ipl */
cli /* XXX no more nested interrupts */
addl $4,%esp /* pop previous ipl */
ret /* return */
|