diff options
Diffstat (limited to 'src/arch/x86/prefix/pxeprefix.S')
| -rw-r--r-- | src/arch/x86/prefix/pxeprefix.S | 85 |
1 files changed, 83 insertions, 2 deletions
diff --git a/src/arch/x86/prefix/pxeprefix.S b/src/arch/x86/prefix/pxeprefix.S index 5181ef618..067af99fa 100644 --- a/src/arch/x86/prefix/pxeprefix.S +++ b/src/arch/x86/prefix/pxeprefix.S @@ -1,6 +1,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ) #define PXENV_UNDI_SHUTDOWN 0x0005 +#define PXENV_UNDI_GET_INFORMATION 0x000c #define PXENV_UNDI_GET_NIC_TYPE 0x0012 #define PXENV_UNDI_GET_IFACE_INFO 0x0013 #define PXENV_STOP_UNDI 0x0015 @@ -325,18 +326,37 @@ print_structure_information: ***************************************************************************** */ get_physical_device: + /* Allow for devices that fail to set the physical device type */ + movb $0xeb, %al + movb %al, ( pxe_parameter_structure + 0x02 ) /* Issue PXENV_UNDI_GET_NIC_TYPE */ movw $PXENV_UNDI_GET_NIC_TYPE, %bx call pxe_call jnc 1f call print_pxe_error + movw $10f, %si + call print_message jmp no_physical_device 1: /* Determine physical device type */ + movw $10f, %si + call print_message movb ( pxe_parameter_structure + 0x02 ), %al cmpb $2, %al je pci_physical_device + cmpb $0xeb, %al + je probably_pci_physical_device jmp no_physical_device + .section ".prefix.data", "aw", @progbits +10: .asciz " UNDI device is " + .previous +probably_pci_physical_device: + /* Device did not write the type byte: assume PCI */ + movw $10f, %si + call print_message + .section ".prefix.data", "aw", @progbits +10: .asciz "probably " + .previous pci_physical_device: /* Record PCI bus:dev.fn and vendor/device IDs */ movl ( pxe_parameter_structure + 0x03 ), %eax @@ -346,9 +366,17 @@ pci_physical_device: movw $10f, %si call print_message call print_pci_busdevfn + movb $( ' ' ), %al + call print_character + movw pci_vendor, %ax + call print_hex_word + movb $( ':' ), %al + call print_character + movw pci_device, %ax + call print_hex_word jmp 99f .section ".prefix.data", "aw", @progbits -10: .asciz " UNDI device is PCI " +10: .asciz "PCI " .previous no_physical_device: @@ -356,12 +384,39 @@ no_physical_device: movw $10f, %si call print_message .section ".prefix.data", "aw", @progbits -10: .asciz " Unable to determine UNDI physical device" +10: .asciz "unknown" .previous 99: /***************************************************************************** + * Get IRQ number + ***************************************************************************** + */ +get_irq: + /* Issue PXENV_UNDI_GET_INFORMATION */ + movw $PXENV_UNDI_GET_INFORMATION, %bx + call pxe_call + jnc 1f + call print_pxe_error + jmp 99f +1: /* Check for a valid IRQ number */ + movw ( pxe_parameter_structure + 0x04 ), %ax + testw %ax, %ax + jz 99f + cmpw $15, %ax + ja 99f + /* Store IRQ number */ + movw %ax, undi_irq + movw $10f, %si + call print_message + call print_word + .section ".prefix.data", "aw", @progbits +10: .asciz ", IRQ " + .previous +99: + +/***************************************************************************** * Determine interface type ***************************************************************************** */ @@ -452,6 +507,30 @@ pxe_cmdline: .previous /***************************************************************************** + * Ensure NIC interrupt is disabled + ***************************************************************************** + */ +disable_irq: + /* Check for a recorded IRQ number */ + movw undi_irq, %cx + testw %cx, %cx + jz 99f + /* Calculate IMR */ + movw %cx, %dx + shlw $4, %dx + andb $0x80, %dl + orb $0x21, %dl + /* Calculate mask value */ + movb $0x01, %bl + andb $0x07, %cl + shlb %cl, %bl + /* Mask interrupt */ + inb %dx, %al + orb %bl, %al + outb %al, %dx +99: + +/***************************************************************************** * Leave NIC in a safe state ***************************************************************************** */ @@ -740,6 +819,8 @@ undi_data_segoff: undi_data_size: .word 0 undi_data_segment: .word 0 +undi_irq: .word 0 + pxe_hacks: .word 0 /* The following fields are part of a struct undi_device */ |
