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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
FILE_LICENCE ( GPL2_OR_LATER )
#define PXENV_UNDI_ISR 0x0014
#define PXENV_UNDI_ISR_IN_START 1
#define PXENV_UNDI_ISR_OUT_OURS 0
#define PXENV_UNDI_ISR_OUT_NOT_OURS 1
#define IRQ_PIC_CUTOFF 8
#define ICR_EOI_NON_SPECIFIC 0x20
#define PIC1_ICR 0x20
#define PIC2_ICR 0xa0
.text
.arch i386
.code16
.section ".text16", "ax", @progbits
.globl undiisr
undiisr:
/* Preserve registers */
pushw %ds
pushw %es
pushw %fs
pushw %gs
pushfl
pushal
/* Set up our segment registers */
movw %cs:rm_ds, %ax
movw %ax, %ds
/* Check that we have an UNDI entry point */
cmpw $0, undinet_entry_point
je chain
/* Issue UNDI API call */
movw %ax, %es
movw $undinet_params, %di
movw $PXENV_UNDI_ISR, %bx
movw $PXENV_UNDI_ISR_IN_START, funcflag
pushw %es
pushw %di
pushw %bx
lcall *undinet_entry_point
cli /* Just in case */
addw $6, %sp
cmpw $PXENV_UNDI_ISR_OUT_OURS, funcflag
jne eoi
trig: /* Record interrupt occurence */
incb undiisr_trigger_count
eoi: /* Send EOI */
movb $ICR_EOI_NON_SPECIFIC, %al
cmpb $IRQ_PIC_CUTOFF, undiisr_irq
jb 1f
outb %al, $PIC2_ICR
1: outb %al, $PIC1_ICR
jmp exit
chain: /* Chain to next handler */
pushfw
lcall *undiisr_next_handler
exit: /* Restore registers and return */
cli
popal
movzwl %sp, %esp
addr32 movl -20(%esp), %esp /* %esp isn't restored by popal */
popfl
popw %gs
popw %fs
popw %es
popw %ds
iret
.section ".data16", "aw", @progbits
undinet_params:
status: .word 0
funcflag: .word 0
bufferlength: .word 0
framelength: .word 0
frameheaderlength: .word 0
frame: .word 0, 0
prottype: .byte 0
pkttype: .byte 0
|