/* Real-mode interface: assembly-language portions. * * Initial version by Michael Brown , January 2004. */ #include "realmode.h" #if 1 /* CODE16 */ #define BOCHSBP xchgw %bx,%bx #define NUM_PUSHA_REGS (8) #define NUM_SEG_REGS (6) .text .arch i386 .section ".text16.nocompress", "ax", @progbits .code16 .equ CR0_PE,1 #ifdef GAS291 #define DATA32 data32; #define ADDR32 addr32; #define LJMPI(x) ljmp x #else #define DATA32 data32 #define ADDR32 addr32 /* newer GAS295 require #define LJMPI(x) ljmp *x */ #define LJMPI(x) ljmp x #endif #ifdef PXE_EXPORT /**************************************************************************** * PXE CALLBACK INTERFACE * * Prepend this to rm_callback_interface to create a real-mode PXE * callback interface. **************************************************************************** */ .section ".text16", "ax", @progbits .globl pxe_callback_interface .code16 pxe_callback_interface: /* Macro to calculate offset of labels within code segment in * installed copy of code. */ #define INSTALLED(x) ( (x) - pxe_callback_interface ) /**************************************************************************** * PXE entry points (!PXE and PXENV+ APIs) **************************************************************************** */ /* in_call mechanism for !PXE API calls */ .globl _pxe_in_call_far _pxe_in_call_far: /* Prepend "PXE API call" and "API version 0x201" to stack */ pushl $0x201 jmp 1f /* in_call mechanism for PXENV+ API calls */ .globl _pxenv_in_call_far _pxenv_in_call_far: /* Prepend "PXE API call" and "API version 0x200" to stack */ pushl $0x200 1: pushl $EB_OPCODE_PXE /* Perform real-mode in_call */ call pxe_rm_in_call /* Return */ addw $8, %sp lret /**************************************************************************** * PXE installation check (INT 1A) code **************************************************************************** */ .globl _pxe_intercept_int1a _pxe_intercept_int1a: pushfw cmpw $0x5650, %ax jne 2f 1: /* INT 1A,5650 - Intercept */ popfw /* Set up return values according to PXE spec: */ movw $0x564e, %ax /* AX := 564Eh (VN) */ pushw %cs:INSTALLED(_pxe_pxenv_segment) popw %es /* ES:BX := &(PXENV+ structure) */ movw %cs:INSTALLED(_pxe_pxenv_offset), %bx clc /* CF is cleared */ lret $2 /* 'iret' without reloading flags */ 2: /* INT 1A,other - Do not intercept */ popfw ljmp %cs:*INSTALLED(_pxe_intercepted_int1a) .globl _pxe_intercepted_int1a _pxe_intercepted_int1a: .word 0,0 .globl _pxe_pxenv_location _pxe_pxenv_location: _pxe_pxenv_offset: .word 0 _pxe_pxenv_segment: .word 0 pxe_rm_in_call: pxe_attach_rm: /* rm_callback_interface must be appended here */ pxe_callback_interface_end: .globl _pxe_callback_interface_size .equ _pxe_callback_interface_size, pxe_callback_interface_end - pxe_callback_interface .globl pxe_callback_interface_size pxe_callback_interface_size: .word _pxe_callback_interface_size #else /* PXE_EXPORT */ /* Define symbols used by the linker scripts, to prevent link errors */ .globl _pxe_callback_interface_size .equ _pxe_callback_interface_size, 0 #endif /* PXE_EXPORT */ #else /* CODE16 */ /* Define symbols used by the linker scripts, to prevent link errors */ .globl _rm_callback_interface_size .equ _rm_callback_interface_size, 0 .globl _pxe_callback_interface_size .equ _pxe_callback_interface_size, 0 #endif /* CODE16 */