xref: /haiku/src/system/boot/platform/pxe_ia32/pxe_bios.S (revision 578e3c26076a61e9ee5b2a4d0ce64f7b69a19d1b)
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