2
0
mirror of https://github.com/xcat2/xNBA.git synced 2025-01-20 22:43:14 +00:00

[pxeprefix] Work around bug in Etherboot 5.4 when loading undionly.kpxe

Etherboot 5.4 erroneously treats PXENV_UNLOAD_STACK as the "final
shutdown" call, and unhooks INT15.  When using gPXE's undionly.kpxe,
this results in gPXE overwriting the portion of Etherboot located in
high memory, because it is no longer hidden from the system memory map
at the time that gPXE loads.

Work around this by explicitly testing for Etherboot as the underlying
PXE stack (as is already done in undinet.c) and skipping the call to
PXENV_UNLOAD_STACK if necessary.
This commit is contained in:
Michael Brown 2009-04-30 04:42:21 +01:00
parent 7c47ebd65c
commit 4188d51753

View File

@ -1,8 +1,11 @@
#define PXENV_UNDI_SHUTDOWN 0x0005
#define PXENV_UNDI_GET_NIC_TYPE 0x0012
#define PXENV_UNDI_GET_IFACE_INFO 0x0013
#define PXENV_STOP_UNDI 0x0015
#define PXENV_UNLOAD_STACK 0x0070
#define PXE_HACK_EB54 0x0001
.text
.arch i386
.org 0
@ -11,6 +14,8 @@
#include <undi.h>
#define STACK_MAGIC ( 'L' + ( 'R' << 8 ) + ( 'E' << 16 ) + ( 'T' << 24 ) )
#define EB_MAGIC_1 ( 'E' + ( 't' << 8 ) + ( 'h' << 16 ) + ( 'e' << 24 ) )
#define EB_MAGIC_2 ( 'r' + ( 'b' << 8 ) + ( 'o' << 16 ) + ( 'o' << 24 ) )
/*****************************************************************************
* Entry point: set operating context, print welcome message
@ -307,8 +312,6 @@ pci_physical_device:
movw $10f, %si
call print_message
call print_pci_busdevfn
movb $0x0a, %al
call print_character
jmp 99f
.section ".prefix.data", "aw", @progbits
10: .asciz " UNDI device is PCI "
@ -319,11 +322,46 @@ no_physical_device:
movw $10f, %si
call print_message
.section ".prefix.data", "aw", @progbits
10: .asciz " Unable to determine UNDI physical device\n"
10: .asciz " Unable to determine UNDI physical device"
.previous
99:
/*****************************************************************************
* Determine interface type
*****************************************************************************
*/
get_iface_type:
/* Issue PXENV_UNDI_GET_IFACE_INFO */
movw $PXENV_UNDI_GET_IFACE_INFO, %bx
call pxe_call
jnc 1f
call print_pxe_error
jmp 99f
1: /* Print interface type */
movw $10f, %si
call print_message
leaw ( pxe_parameter_structure + 0x02 ), %si
call print_message
.section ".prefix.data", "aw", @progbits
10: .asciz ", type "
.previous
/* Check for "Etherboot" interface type */
cmpl $EB_MAGIC_1, ( pxe_parameter_structure + 0x02 )
jne 99f
cmpl $EB_MAGIC_2, ( pxe_parameter_structure + 0x06 )
jne 99f
movw $10f, %si
call print_message
.section ".prefix.data", "aw", @progbits
10: .asciz " (workaround enabled)"
.previous
/* Flag Etherboot workarounds as required */
orw $PXE_HACK_EB54, pxe_hacks
99: movb $0x0a, %al
call print_character
/*****************************************************************************
* Leave NIC in a safe state
*****************************************************************************
@ -337,6 +375,14 @@ shutdown_nic:
call print_pxe_error
1:
unload_base_code:
/* Etherboot treats PXENV_UNLOAD_STACK as PXENV_STOP_UNDI, so
* we must not issue this call if the underlying stack is
* Etherboot and we were not intending to issue a PXENV_STOP_UNDI.
*/
#ifdef PXELOADER_KEEP_UNDI
testw $PXE_HACK_EB54, pxe_hacks
jnz 99f
#endif /* PXELOADER_KEEP_UNDI */
/* Issue PXENV_UNLOAD_STACK */
movw $PXENV_UNLOAD_STACK, %bx
call pxe_call
@ -549,7 +595,9 @@ pxe_call:
testw %ax, %ax
jz 1f
stc
1: /* Restore registers and return */
1: /* Clear direction flag, for the sake of sanity */
cld
/* Restore registers and return */
popw %es
popw %di
ret
@ -593,7 +641,7 @@ print_pxe_error:
pxe_esp: .long 0
pxe_ss: .word 0
pxe_parameter_structure: .fill 20
pxe_parameter_structure: .fill 64
undi_code_segoff:
undi_code_size: .word 0
@ -603,6 +651,8 @@ undi_data_segoff:
undi_data_size: .word 0
undi_data_segment: .word 0
pxe_hacks: .word 0
/* The following fields are part of a struct undi_device */
undi_device: