184a31142SMarcus Overhagen/* 284a31142SMarcus Overhagen** Copyright 2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved. 384a31142SMarcus Overhagen** Copyright 2006, Marcus Overhagen, marcus@overhagen.de. All rights reserved. 484a31142SMarcus Overhagen** Distributed under the terms of the Haiku License. 584a31142SMarcus Overhagen*/ 684a31142SMarcus Overhagen 784a31142SMarcus Overhagen 884a31142SMarcus Overhagen/** This file contains code to call PXE BIOS functions out of a protected 984a31142SMarcus Overhagen * mode environment. It doesn't use the virtual86 mode - it switches 1084a31142SMarcus Overhagen * to real mode, make the BIOS call, and switch back to protected 1184a31142SMarcus Overhagen * mode again. It's meant to be used in a single-threaded boot loader, 1284a31142SMarcus Overhagen * not in a multi-tasking operating system. 1384a31142SMarcus Overhagen * It relies on the real mode segment descriptors found in pxe_stage1.S, 1484a31142SMarcus Overhagen * and uses support functions from ../bios_ia32/bios.S 1584a31142SMarcus Overhagen */ 1684a31142SMarcus Overhagen 1784a31142SMarcus Overhagen#define FUNCTION(x) .globl x ; x ## : 1884a31142SMarcus Overhagen 1984a31142SMarcus Overhagen#define REAL_MODE_STACK 0x9000 2084a31142SMarcus Overhagen // the location of the stack in real mode 2184a31142SMarcus Overhagen 22*578e3c26SMarcus Overhagen#define SAVED_EAX 0x10014 2384a31142SMarcus Overhagen // we're overwriting the start of our boot loader to hold some 2484a31142SMarcus Overhagen // temporary values - the first 1024 bytes of it are used at 2584a31142SMarcus Overhagen // startup only, and we avoid some linking issues this way 2684a31142SMarcus Overhagen 2784a31142SMarcus Overhagen 2884a31142SMarcus Overhagen.text 2984a31142SMarcus Overhagen.code32 3084a31142SMarcus Overhagen 3184a31142SMarcus Overhagen 32f7110a42SMarcus Overhagen/** uint16 call_pxe_bios(void *pxe, uint16 opcode, void *param) 3384a31142SMarcus Overhagen * Does a call to the PXE BIOS functions in real mode. 34*578e3c26SMarcus Overhagen * Both pxe and param must be as linear pointer into lower 1 MB, 35f7110a42SMarcus Overhagen * pxe is the pointer to the !PXE structure. 3684a31142SMarcus Overhagen */ 3784a31142SMarcus Overhagen 3884a31142SMarcus OverhagenFUNCTION(call_pxe_bios) 39f7110a42SMarcus Overhagen 4084a31142SMarcus Overhagen pushal 4184a31142SMarcus Overhagen pushfl 4284a31142SMarcus Overhagen 4384a31142SMarcus Overhagen // make sure the correct IDT is in place 4484a31142SMarcus Overhagen lidt idt_descriptor 4584a31142SMarcus Overhagen 46f7110a42SMarcus Overhagen // !PXE 47*578e3c26SMarcus Overhagen movl 40(%esp), %ebx 48*578e3c26SMarcus Overhagen // make %ebx a pointer to entry point SEG:OFS 49*578e3c26SMarcus Overhagen addl $0x10, %ebx 5084a31142SMarcus Overhagen 51f7110a42SMarcus Overhagen // opcode 52f7110a42SMarcus Overhagen movl 44(%esp), %ecx 5384a31142SMarcus Overhagen 54f7110a42SMarcus Overhagen // param 55f7110a42SMarcus Overhagen movl 48(%esp), %edx 5684a31142SMarcus Overhagen 57*578e3c26SMarcus Overhagen // enter real mode (clobbers %eax, %ds, %es, %fs, %gs, %ss, %sp) 5884a31142SMarcus Overhagen call switch_to_real_mode 5984a31142SMarcus Overhagen 6084a31142SMarcus Overhagen .code16 6184a31142SMarcus Overhagen 62*578e3c26SMarcus Overhagen // param (segment) 63f7110a42SMarcus Overhagen movl %edx, %eax 64f7110a42SMarcus Overhagen shrl $4, %eax 65f7110a42SMarcus Overhagen pushw %ax 6684a31142SMarcus Overhagen 67*578e3c26SMarcus Overhagen // param (offset) 68f7110a42SMarcus Overhagen andw $0xf, %dx 69f7110a42SMarcus Overhagen pushw %dx 7084a31142SMarcus Overhagen 71f7110a42SMarcus Overhagen // opcode 72f7110a42SMarcus Overhagen pushw %cx 7384a31142SMarcus Overhagen 74f7110a42SMarcus Overhagen // call PXE entry point 75*578e3c26SMarcus Overhagen movl %ebx, %eax 76*578e3c26SMarcus Overhagen shrl $4, %eax 77*578e3c26SMarcus Overhagen movw %ax, %es 78*578e3c26SMarcus Overhagen andw $0xf, %bx 79*578e3c26SMarcus Overhagen lcall * %es:(%bx) 8084a31142SMarcus Overhagen 81f7110a42SMarcus Overhagen addw $6, %sp 8284a31142SMarcus Overhagen 83*578e3c26SMarcus Overhagen // save %ax result 84f7110a42SMarcus Overhagen xorl %ebx, %ebx 85f7110a42SMarcus Overhagen movw %ax, %bx 86f7110a42SMarcus Overhagen movl %ebx, (SAVED_EAX - 0x10000) 8784a31142SMarcus Overhagen 88*578e3c26SMarcus Overhagen // back to protected mode (clobbers %eax) 8984a31142SMarcus Overhagen call switch_to_protected_mode 9084a31142SMarcus Overhagen .code32 9184a31142SMarcus Overhagen 9284a31142SMarcus Overhagen popfl 9384a31142SMarcus Overhagen popal 9484a31142SMarcus Overhagen 95f7110a42SMarcus Overhagen movl SAVED_EAX, %eax 96f7110a42SMarcus Overhagen 9784a31142SMarcus Overhagen ret 98