| /* |
| * 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., 51 Franklin Street, Fifth Floor, Boston, MA |
| * 02110-1301, USA. |
| * |
| * You can also choose to distribute this program under the terms of |
| * the Unmodified Binary Distribution Licence (as given in the file |
| * COPYING.UBDL), provided that you have satisfied its requirements. |
| * |
| */ |
| |
| FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ) |
| |
| #include <librm.h> |
| |
| .section ".note.GNU-stack", "", @progbits |
| .code16 |
| .arch i386 |
| |
| /**************************************************************************** |
| * !PXE structure |
| **************************************************************************** |
| */ |
| .section ".text16.data", "aw", @progbits |
| .globl ppxe |
| .balign 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 |
| .balign 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: |
| virtcall pxe_api_call |
| 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 |
| pushw %bp |
| movw %sp, %bp |
| andb $~0x01, 8(%bp) /* Clear CF on return */ |
| popw %bp |
| popfw |
| iret |
| 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 |