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