mirror of https://github.com/ipxe/ipxe.git
80 lines
1.4 KiB
ArmAsm
80 lines
1.4 KiB
ArmAsm
#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
|
|
.section ".text16", "ax", @progbits
|
|
.section ".data16", "aw", @progbits
|
|
.code16
|
|
|
|
.section ".text16"
|
|
.globl undiisr
|
|
undiisr:
|
|
|
|
/* Preserve registers */
|
|
pushw %ds
|
|
pushw %es
|
|
pusha
|
|
|
|
/* 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 */
|
|
pushw %ds
|
|
popw %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 */
|
|
popa
|
|
popw %es
|
|
popw %ds
|
|
iret
|
|
|
|
.section ".data16"
|
|
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
|