| 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 |