Files
ipxe/src/arch/i386/interface/pxe/pxe_entry.S
H. Peter Anvin aaa26f3bd3 [pxe] Initialize EDX on PXE NBP entry and INT 1Ah
The PXE 1.x spec specifies that on NBP entry or on return from INT
1Ah AX=5650h, EDX shall point to the physical address of the PXENV+
structure.  The PXE 2.x spec drops this requirement, simply stating
that EDX is clobbered.  Given the principle "be conservative in what
you send, liberal in what you accept", however, we should implement
this anyway.
2009-02-18 18:13:20 +00:00

212 lines
5.6 KiB
ArmAsm

/*
* Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
.arch i386
/****************************************************************************
* !PXE structure
****************************************************************************
*/
.section ".text16.data", "aw", @progbits
.globl ppxe
.align 16
ppxe:
.ascii "!PXE" /* Signature */
.byte pxe_length /* StructLength */
.byte 0 /* StructCksum */
.byte 0 /* StructRev */
.byte 0 /* reserved_1 */
.word undiheader, 0 /* UNDIROMID */
.word 0, 0 /* BaseROMID */
.word pxe_entry_sp, 0 /* EntryPointSP */
.word pxe_entry_esp, 0 /* EntryPointESP */
.word -1, -1 /* StatusCallout */
.byte 0 /* reserved_2 */
.byte SegDescCnt /* SegDescCnt */
.word 0 /* FirstSelector */
pxe_segments:
.word 0, 0, 0, _data16_memsz /* Stack */
.word 0, 0, 0, _data16_memsz /* UNDIData */
.word 0, 0, 0, _text16_memsz /* UNDICode */
.word 0, 0, 0, _text16_memsz /* UNDICodeWrite */
.word 0, 0, 0, 0 /* BC_Data */
.word 0, 0, 0, 0 /* BC_Code */
.word 0, 0, 0, 0 /* BC_CodeWrite */
.equ SegDescCnt, ( ( . - pxe_segments ) / 8 )
.equ pxe_length, . - ppxe
.size ppxe, . - ppxe
/* Define undiheader=0 as a weak symbol for non-ROM builds */
.section ".weak", "a", @nobits
.weak undiheader
undiheader:
/****************************************************************************
* PXENV+ structure
****************************************************************************
*/
.section ".text16.data", "aw", @progbits
.globl pxenv
.align 16
pxenv:
.ascii "PXENV+" /* Signature */
.word 0x0201 /* Version */
.byte pxenv_length /* Length */
.byte 0 /* Checksum */
.word pxenv_entry, 0 /* RMEntry */
.long 0 /* PMEntry */
.word 0 /* PMSelector */
.word 0 /* StackSeg */
.word _data16_memsz /* StackSize */
.word 0 /* BC_CodeSeg */
.word 0 /* BC_CodeSize */
.word 0 /* BC_DataSeg */
.word 0 /* BC_DataSize */
.word 0 /* UNDIDataSeg */
.word _data16_memsz /* UNDIDataSize */
.word 0 /* UNDICodeSeg */
.word _text16_memsz /* UNDICodeSize */
.word ppxe, 0 /* PXEPtr */
.equ pxenv_length, . - pxenv
.size pxenv, . - pxenv
/****************************************************************************
* pxenv_entry (16-bit far call)
*
* PXE API call PXENV+ entry point
*
* Parameters:
* %es:di : Far pointer to PXE parameter structure
* %bx : PXE API call
* Returns:
* %ax : PXE exit status
* Corrupts:
* none
****************************************************************************
*/
/* Wyse Streaming Manager server (WLDRM13.BIN) assumes that
* the PXENV+ entry point is at UNDI_CS:0000; apparently,
* somebody at Wyse has difficulty distinguishing between the
* words "may" and "must"...
*/
.section ".text16.null", "ax", @progbits
.code16
pxenv_null_entry:
jmp pxenv_entry
.section ".text16", "ax", @progbits
.code16
pxenv_entry:
pushl $pxe_api_call
pushw %cs
call prot_call
addl $4, %esp
lret
.size pxenv_entry, . - pxenv_entry
/****************************************************************************
* pxe_entry
*
* PXE API call !PXE entry point
*
* Parameters:
* stack : Far pointer to PXE parameter structure
* stack : PXE API call
* Returns:
* %ax : PXE exit status
* Corrupts:
* none
****************************************************************************
*/
.section ".text16", "ax", @progbits
.code16
pxe_entry:
pxe_entry_sp:
/* Preserve original %esp */
pushl %esp
/* Zero high word of %esp to allow use of common code */
movzwl %sp, %esp
jmp pxe_entry_common
pxe_entry_esp:
/* Preserve %esp to match behaviour of pxe_entry_sp */
pushl %esp
pxe_entry_common:
/* Save PXENV+ API call registers */
pushw %es
pushw %di
pushw %bx
/* Load !PXE parameters from stack into PXENV+ registers */
addr32 movw 18(%esp), %bx
movw %bx, %es
addr32 movw 16(%esp), %di
addr32 movw 14(%esp), %bx
/* Make call as for PXENV+ */
pushw %cs
call pxenv_entry
/* Restore PXENV+ registers */
popw %bx
popw %di
popw %es
/* Restore original %esp and return */
popl %esp
lret
.size pxe_entry, . - pxe_entry
/****************************************************************************
* pxe_int_1a
*
* PXE INT 1A handler
*
* Parameters:
* %ax : 0x5650
* Returns:
* %ax : 0x564e
* %es:bx : Far pointer to the PXENV+ structure
* %edx : Physical address of the PXENV+ structure
* CF cleared
* Corrupts:
* none
****************************************************************************
*/
.section ".text16", "ax", @progbits
.code16
.globl pxe_int_1a
pxe_int_1a:
pushfw
cmpw $0x5650, %ax
jne 1f
/* INT 1A,5650 - PXE installation check */
xorl %edx, %edx
movw %cs, %dx
movw %dx, %es
movw $pxenv, %bx
shll $4, %edx
addl $pxenv, %edx
movw $0x564e, %ax
popfw
clc
lret $2
1: /* INT 1A,other - pass through */
popfw
ljmp *%cs:pxe_int_1a_vector
.section ".text16.data", "aw", @progbits
.globl pxe_int_1a_vector
pxe_int_1a_vector: .long 0