1; 2; Process a PXE interrupt 3; 4 section .text16 5 6PXEIRQ_MAX equ 100 ; Max spurious interrupts in a timer tick 7 8 global pxe_isr 9pxe_isr: 10 cld 11 pusha 12 push ds 13 push es 14 push fs 15 push gs 16 17 xor ax,ax 18 mov ds,ax 19 mov es,ax 20 21 mov bx,PXENV_UNDI_ISR 22 mov di,pxenv_undi_isr_buf 23 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 30 31 call pxenv 32 mov ax,[__jiffies] 33 jc .notus 34 35 cmp word [pxenv_undi_isr_buf.funcflag],PXENV_UNDI_ISR_OUT_OURS 36 jne .notus 37 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] 43 44 cmp byte [pxe_irq_vector], 8 45 mov al,0x20 ; Non-specific EOI 46 jb .pri_pic 47 48 out 0xA0, al ; Secondary PIC 49.pri_pic: 50 out 0x20,al ; Primary PIC 51 52 mov [pxeirq_last],ax 53 mov word [pxeirq_deadman],PXEIRQ_MAX 54 55.exit: 56 pop gs 57 pop fs 58 pop es 59 pop ds 60 popa 61 iret 62 63.notus: 64 cmp ax,[pxeirq_last] 65 jne .reset_timeout 66 dec word [pxeirq_deadman] 67 jz .timeout 68 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 77pxe_irq_chain equ $-4 78 79.reset_timeout: 80 mov [pxeirq_last],ax 81 mov word [pxeirq_deadman],PXEIRQ_MAX 82 jmp .chain 83 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 101 102 103; Emulate a PXE interrupt from the polling thread 104 global pxe_poll 105pxe_poll: 106 pushf 107 cli 108 cld 109 pusha 110 push ds 111 push es 112 push fs 113 push gs 114 115 mov bx,PXENV_UNDI_ISR 116 mov di,pxenv_undi_isr_buf 117 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 124 125 call pxenv 126 jc .notus 127 128 cmp word [pxenv_undi_isr_buf.funcflag],PXENV_UNDI_ISR_OUT_OURS 129 jne .notus 130 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 135 136.notus: 137 pop gs 138 pop fs 139 pop es 140 pop ds 141 popa 142 popf 143 ret 144 145 section .bss16 146 alignb 4 147pxenv_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 157 158 alignb 4 159pxeirq_last resw 1 160pxeirq_deadman resw 1 161 162 global pxe_irq_count 163pxe_irq_count resd 1 ; PXE IRQ counter 164 global pxe_irq_vector 165pxe_irq_vector resb 1 ; PXE IRQ vector 166 global pxe_irq_pending 167pxe_irq_pending resb 1 ; IRQ pending flag 168 global pxe_need_poll 169pxe_need_poll resb 1 ; Bit 0 = need polling 170 ; Bit 1 = polling active 171 172 section .text16 173