pxeprefix.S revision 677833bc953b6cb418c701facbdcf4aa18d6c44e
/* Offsets of words containing ROM's CS and size (in 512 byte blocks)
* from start of floppy boot block at 0x7c00
* Offsets must match those in etherboot.h
*/
#define FLOPPY_SEGMENT 0x7c0
#define PXENV_UNDI_CLEANUP 0x02
#define PXENV_UNDI_SHUTDOWN 0x05
#define PXENV_STOP_UNDI 0x15
#define PXENV_UNLOAD_STACK 0x70
#define PXENV_STOP_BASE 0x76
#define PUSHA_SIZE 16
.text
.org 0
/*****************************************************************************
* Entry point: set cs, ds, bp, print welcome message
*****************************************************************************
*/
pusha /* Preserve all registers */
* this after the pusha */
/*****************************************************************************
* Detect type of PXE available (!PXE, PXENV+ or none)
*****************************************************************************
*/
int $0x1a
detected_pxenv: /* es:bx points to PXENV+ structure */
detected_pxe: /* es:di points to !PXE structure */
/*****************************************************************************
* Print information about located structure
*****************************************************************************
*/
/*****************************************************************************
* Unload PXE base code and UNDI driver
*****************************************************************************
*/
#ifdef PXELOADER_KEEP_ALL
#endif /* PXELOADER_KEEP_ALL */
pushfw /* Ignore PXENV_UNDI_CLEANUP errors */
/* On exit, zero flag is set iff all calls were successful */
/*****************************************************************************
* Free base memory
*****************************************************************************
*/
jb 1f
/* Note that zero_mem_loop will also zero out our stack, so make
* sure the stack is empty at this point.
*/
/* Will exit here with zero flag set, so no need to set it explicitly
* in order to indicate success.
*/
pushf /* Save success (zero) flag status */
popf /* Restore success (zero) flag */
/*****************************************************************************
* Exit point
* Jump to finished with the zero flag set to indicate success, or to
* finished_with_error to always report an error
*****************************************************************************
*/
jz 1f
1:
jmp 99f
/* We place a stack here. It doesn't get used until after all
* the above code is finished, so we can happily write all
* over it. Putting the stack here ensures that it doesn't
* accidentally go over the 512 byte threshold, which would
* cause problems when returning via start32's prefix
* relocation mechanism.
*/
99:
/*****************************************************************************
* Run Etherboot main code
*****************************************************************************
*/
/* Very temporarily switch stacks to one internal to the
* prefix. Do this because the stack provided by the PXE ROM
* could be absolutely anywhere, including in an area of
* memory that the call to prelocate will vapourise...
*/
/* Relocate payload and stack to claimed base memory */
pushw $0 /* Indicate prefix exit mechanism */
call 1f
exit_via_pxe: /* Stack OK, return to PXE */
popa /* Restore PXE's other registers */
lret /* Return control to PXE ROM */
exit_via_int18: /* Stack damaged, do int 18 */
int $0x18
1: lodsb
je 2f
int $0x10
jmp 1b
2: ret
/*****************************************************************************
* Subroutine: print character in %al (with LF -> LF,CR translation)
*****************************************************************************
*/
jne 1f
int $0x10
1: int $0x10
/*****************************************************************************
* Subroutine: print a zero-terminated message starting at %si
*****************************************************************************
*/
1: lodsb
je 2f
jmp 1b
2: ret
/*****************************************************************************
* Subroutine: print hex word in %ax
*****************************************************************************
*/
1:
/* Courtesy of Norbert Juffa <norbert.juffa@amd.com> */
loop 1b
/*****************************************************************************
* Subroutine: print segment:offset address in %es:%di
*****************************************************************************
*/
/*****************************************************************************
* Make a PXE API call. Works with either !PXE or PXENV+ API.
* Opcode in %bx. pxe_parameter_structure always used.
* Returns status code (not exit code) in %bx and prints it.
* ORs status code with overall status code in pxe_overall_status, returns
* with zero flag set iff all PXE API calls have been successful.
*****************************************************************************
*/
/* Set up registers for PXENV+ API. %bx already set up */
/* Set up stack for !PXE API */
/* Make the API call */
/* Reset the stack */
/*****************************************************************************
* PXE data structures
*****************************************************************************
*/
pxe_entry_offset: .word 0
undi_code_size: .word 0
undi_data_size: .word 0
.word 0
.word 0,0,0,0,0
.balign 16, 0