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_ESP 0x10000 23#define SAVED_CR3 0x10004 24#define SAVED_EAX 0x10008 25#define SAVED_ES 0x1000c 26#define SAVED_FLAGS 0x10010 27 // we're overwriting the start of our boot loader to hold some 28 // temporary values - the first 1024 bytes of it are used at 29 // startup only, and we avoid some linking issues this way 30 31 32.text 33.code32 34 35 36/** void call_pxe_bios(...) 37 * Does a call to the PXE BIOS functions in real mode. 38 */ 39 40FUNCTION(call_pxe_bios) 41 pushal 42 pushfl 43 44 // make sure the correct IDT is in place 45 lidt idt_descriptor 46 47 // get the interrupt vector and patch the instruction at the target address 48 movl 40(%esp), %eax 49 50 // Fills registers from the passed in structure 51 // Since switch_to_real_mode() clobbers %eax, we have to handle 52 // it specially here (by temporarily storing it to an arbitrary 53 // memory location, SAVED_EAX) 54 movl 44(%esp), %ebp 55 56 movl (%ebp), %eax 57 movl %eax, SAVED_EAX 58 movl 4(%ebp), %ebx 59 movl 8(%ebp), %ecx 60 movl 12(%ebp), %edx 61 movl 16(%ebp), %esi 62 movl 20(%ebp), %edi 63 movw 24(%ebp), %ax 64 movw %ax, SAVED_ES 65 66 call switch_to_real_mode 67 68 .code16 69 70 // restore %eax and %es from saved location 71 movl (SAVED_EAX - 0x10000), %eax 72 movw (SAVED_ES - 0x10000), %es 73 74 // call the PXE hook 75 76 77 78 // we're interested in the flags state as well 79 pushf 80 81 // save %eax from the call 82 movl %eax, (SAVED_EAX - 0x10000) 83 84 // save flags from the call 85 pop %ax 86 movw %ax, (SAVED_FLAGS - 0x10000) 87 88 // back to protected mode 89 call switch_to_protected_mode 90 .code32 91 92 // store the register state into the structure that has been passed in 93 movl 44(%esp), %eax 94 95 movl %ebx, 4(%eax) 96 movl %ecx, 8(%eax) 97 movl %edx, 12(%eax) 98 movl %esi, 16(%eax) 99 movl %edi, 20(%eax) 100 movl SAVED_EAX, %ecx // special handling for %eax and flags 101 movl %ecx, (%eax) 102 movw SAVED_FLAGS, %cx 103 movw %cx, 26(%eax) 104 105 popfl 106 popal 107 108 ret 109