pxe: force polling on if we receive no interrupts
[syslinux/sherbszt.git] / core / pxeisr.inc
blob93c73ed560e87a0ce8da5500310ec37e501d5603
2 ; Process a PXE interrupt
4                 section .text16
6 PXEIRQ_MAX      equ 100         ; Max spurious interrupts in a timer tick
8                 global pxe_isr
9 pxe_isr:
10                 cld
11                 pusha
12                 push ds
13                 push es
14                 push fs
15                 push gs
17                 xor ax,ax
18                 mov ds,ax       
19                 mov es,ax
21                 mov bx,PXENV_UNDI_ISR
22                 mov di,pxenv_undi_isr_buf
24                 mov cx,pxenv_undi_isr_buf.size/2
25                 push di
26                 rep stosw
27                 pop di
28                 
29                 mov byte [pxenv_undi_isr_buf.funcflag],PXENV_UNDI_ISR_IN_START
31                 call pxenv
32                 mov ax,[__jiffies]
33                 jc .notus
35                 cmp word [pxenv_undi_isr_buf.funcflag],PXENV_UNDI_ISR_OUT_OURS
36                 jne .notus
38                 ; Its ours - set the flag for the return to PM.
39                 ; We need to EOI this ourselves, so that the
40                 ; leftover BC doesn't get control.
41                 mov byte [pxe_irq_pending],1
42                 inc dword [pxe_irq_count]
44                 cmp byte [pxe_irq_vector], 8
45                 mov al,0x20             ; Non-specific EOI
46                 jb .pri_pic
48                 out 0xA0, al            ; Secondary PIC
49 .pri_pic:
50                 out 0x20,al             ; Primary PIC
52                 mov [pxeirq_last],ax
53                 mov word [pxeirq_deadman],PXEIRQ_MAX
55 .exit:
56                 pop gs
57                 pop fs
58                 pop es
59                 pop ds
60                 popa
61                 iret
63 .notus:
64                 cmp ax,[pxeirq_last]
65                 jne .reset_timeout
66                 dec word [pxeirq_deadman]
67                 jz .timeout
69 .chain:
70                 pop gs
71                 pop fs
72                 pop es
73                 pop ds
74                 popa
75                 jmp 0:0
76                 global pxe_irq_chain
77 pxe_irq_chain   equ $-4
79 .reset_timeout:
80                 mov [pxeirq_last],ax
81                 mov word [pxeirq_deadman],PXEIRQ_MAX
82                 jmp .chain
84                 ; Too many spurious interrupts, shut off the interrupts
85                 ; and go to polling mode
86 .timeout:
87                 mov al,[pxe_irq_vector]
88                 mov dx,21h
89                 movzx cx,al
90                 shl cx,7-3
91                 add dx,cx
92                 and al,7
93                 xchg ax,cx
94                 mov ch,1
95                 shl ch,cl
96                 in al,dx
97                 or al,ch
98                 out dx,al
99                 or byte [pxe_need_poll],1
100                 jmp .exit
103 ; Emulate a PXE interrupt from the polling thread
104                 global pxe_poll
105 pxe_poll:
106                 pushf
107                 cli
108                 cld
109                 pusha
110                 push ds
111                 push es
112                 push fs
113                 push gs
115                 mov bx,PXENV_UNDI_ISR
116                 mov di,pxenv_undi_isr_buf
118                 mov cx,pxenv_undi_isr_buf.size/2
119                 push di
120                 rep stosw
121                 pop di
122                 
123                 mov byte [pxenv_undi_isr_buf.funcflag],PXENV_UNDI_ISR_IN_START
125                 call pxenv
126                 jc .notus
128                 cmp word [pxenv_undi_isr_buf.funcflag],PXENV_UNDI_ISR_OUT_OURS
129                 jne .notus
131                 ; Its ours - set the flag for the return to PM.
132                 ; We need to EOI this ourselves, so that the
133                 ; leftover BC doesn't get control.
134                 mov byte [pxe_irq_pending],1
136 .notus:
137                 pop gs
138                 pop fs
139                 pop es
140                 pop ds
141                 popa
142                 popf
143                 ret
145                 section .bss16
146                 alignb 4
147 pxenv_undi_isr_buf:
148 .status:        resw 1
149 .funcflag:      resw 1
150 .bufferlength:  resw 1
151 .framelen:      resw 1
152 .framehdrlen:   resw 1
153 .frame:         resw 2
154 .prottype:      resb 1
155 .pkttype:       resb 1
156 .size           equ $-pxenv_undi_isr_buf
158                 alignb 4
159 pxeirq_last     resw 1
160 pxeirq_deadman  resw 1
162                 global pxe_irq_count
163 pxe_irq_count   resd 1                  ; PXE IRQ counter
164                 global pxe_irq_vector
165 pxe_irq_vector  resb 1                  ; PXE IRQ vector
166                 global pxe_irq_pending
167 pxe_irq_pending resb 1                  ; IRQ pending flag
168                 global pxe_need_poll
169 pxe_need_poll   resb 1                  ; Bit 0 = need polling
170                                         ; Bit 1 = polling active
172                 section .text16