1/* 2** Copyright 2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved. 3** Copyright 2006, Marcus Overhagen, marcus@overhagen.de. All rights reserved. 4** Distributed under the terms of the Haiku License. 5*/ 6 7 8/** This file contains code to call PXE BIOS functions out of a protected 9 * mode environment. It doesn't use the virtual86 mode - it switches 10 * to real mode, make the BIOS call, and switch back to protected 11 * mode again. It's meant to be used in a single-threaded boot loader, 12 * not in a multi-tasking operating system. 13 * It relies on the real mode segment descriptors found in pxe_stage1.S, 14 * and uses support functions from ../bios_ia32/bios.S 15 */ 16 17#define FUNCTION(x) .globl x ; x ## : 18 19#define REAL_MODE_STACK 0x9000 20 // the location of the stack in real mode 21 22#define SAVED_EAX 0x10014 23 // we're overwriting the start of our boot loader to hold some 24 // temporary values - the first 1024 bytes of it are used at 25 // startup only, and we avoid some linking issues this way 26 27 28.text 29.code32 30 31 32/** uint16 call_pxe_bios(void *pxe, uint16 opcode, void *param) 33 * Does a call to the PXE BIOS functions in real mode. 34 * Both pxe and param must be as linear pointer into lower 1 MB, 35 * pxe is the pointer to the !PXE structure. 36 */ 37 38FUNCTION(call_pxe_bios) 39 40 pushal 41 pushfl 42 43 // make sure the correct IDT is in place 44 lidt idt_descriptor 45 46 // !PXE 47 movl 40(%esp), %ebx 48 // make %ebx a pointer to entry point SEG:OFS 49 addl $0x10, %ebx 50 51 // opcode 52 movl 44(%esp), %ecx 53 54 // param 55 movl 48(%esp), %edx 56 57 // enter real mode (clobbers %eax, %ds, %es, %fs, %gs, %ss, %sp) 58 call switch_to_real_mode 59 60 .code16 61 62 // param (segment) 63 movl %edx, %eax 64 shrl $4, %eax 65 pushw %ax 66 67 // param (offset) 68 andw $0xf, %dx 69 pushw %dx 70 71 // opcode 72 pushw %cx 73 74 // call PXE entry point 75 movl %ebx, %eax 76 shrl $4, %eax 77 movw %ax, %es 78 andw $0xf, %bx 79 lcall * %es:(%bx) 80 81 addw $6, %sp 82 83 // save %ax result 84 xorl %ebx, %ebx 85 movw %ax, %bx 86 movl %ebx, (SAVED_EAX - 0x10000) 87 88 // back to protected mode (clobbers %eax) 89 call switch_to_protected_mode 90 .code32 91 92 popfl 93 popal 94 95 movl SAVED_EAX, %eax 96 97 ret 98