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