[FREELDR] Other enhancements.
[reactos.git] / boot / freeldr / freeldr / arch / i386 / entry.S
1 /*
2 * FreeLoader
3 * Copyright (C) 1998-2002 Brian Palmer <brianp@sginet.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #include <asm.inc>
21 #include <arch/pc/x86common.h>
22 #include <arch/pc/pcbios.h>
23
24 EXTERN _BootMain:PROC
25 EXTERN _InitIdt:PROC
26 EXTERN _i386Idt:DWORD
27 //EXTERN _i386idtptr:FWORD
28 EXTERN cmdline:DWORD
29
30 #ifdef _USE_ML
31 EXTERN __bss_start__:DWORD
32 EXTERN __bss_end__:DWORD
33 #endif
34
35 .code32
36
37 PUBLIC _RealEntryPoint
38 _RealEntryPoint:
39
40 /* Setup segment selectors */
41 mov ax, PMODE_DS
42 mov ds, ax
43 mov es, ax
44 mov fs, ax
45 mov gs, ax
46 mov ss, ax
47
48 /* Setup protected mode stack */
49 mov esp, dword ptr ds:[stack32]
50
51 /* Load the IDT */
52 #ifdef _USE_ML
53 lidt fword ptr ds:[i386idtptr]
54 #else
55 lidt i386idtptr
56 #endif
57
58 /* Continue execution */
59 jmp dword ptr ds:[ContinueAddress]
60
61 PUBLIC ContinueAddress
62 ContinueAddress:
63 .long _FrldrStartup
64
65 _FrldrStartup:
66
67 /* Store BootDrive and BootPartition */
68 mov byte ptr ds:[_FrldrBootDrive], dl
69 xor eax, eax
70 mov al, dh
71 mov dword ptr ds:[_FrldrBootPartition], eax
72
73 /* Patch long jump with real mode entry point */
74 mov eax, dword ptr ds:[BSS_RealModeEntry]
75 mov dword ptr ds:[SwitchToReal16Address], eax
76
77 /* Clean out BSS */
78 xor eax, eax
79 mov edi, offset __bss_start__
80 mov ecx, offset __bss_end__ + 3
81 sub ecx, edi
82 shr ecx, 2
83 rep stosd
84
85 /* Initialize the idt */
86 call _InitIdt
87
88 /* Pass the command line to BootMain */
89 mov eax, offset cmdline
90
91 /* GO! */
92 push eax
93 call _BootMain
94
95 /* We should never get here */
96 stop:
97 jmp short stop
98 nop
99 nop
100
101
102 PUBLIC _Reboot
103 _Reboot:
104 /* Set the function ID */
105 mov bx, FNID_Reboot
106
107 /* Switch to real mode (we don't return) */
108 jmp SwitchToReal
109
110
111 /*
112 * VOID __cdecl ChainLoadBiosBootSectorCode(
113 * IN UCHAR BootDrive OPTIONAL,
114 * IN ULONG BootPartition OPTIONAL);
115 *
116 * RETURNS: Nothing
117 */
118 PUBLIC _ChainLoadBiosBootSectorCode
119 _ChainLoadBiosBootSectorCode:
120 /* Set the boot drive */
121 mov dl, [esp + 4]
122 test dl, dl
123 jnz set_part
124 mov dl, byte ptr ds:[_FrldrBootDrive]
125
126 /* Set the boot partition */
127 set_part:
128 mov eax, [esp + 8]
129 test eax, eax
130 jnz continue
131 mov eax, dword ptr ds:[_FrldrBootPartition]
132 continue:
133 /* Store the 1-byte truncated partition number in DH */
134 mov dh, al
135
136 /* Set the function ID */
137 mov bx, FNID_ChainLoadBiosBootSectorCode
138
139 /* Switch to real mode (we don't return) */
140 jmp SwitchToReal
141
142
143 /*
144 * U16 PxeCallApi(U16 Segment, U16 Offset, U16 Service, VOID *Parameter);
145 *
146 * RETURNS:
147 */
148 PUBLIC _PxeCallApi
149 _PxeCallApi:
150 /* copy entry point */
151 mov eax, [esp + 4]
152 shl eax, 16
153 mov ax, [esp + 8]
154 mov dword ptr ds:[BSS_PxeEntryPoint], eax
155
156 /* copy function */
157 mov ax, [esp + 12]
158 mov word ptr ds:[BSS_PxeFunction], ax
159
160 /* convert pointer to data buffer to segment/offset */
161 mov eax, [esp + 16]
162 shr eax, 4
163 and eax, HEX(0f000)
164 mov word ptr ds:[BSS_PxeBufferSegment], ax
165 mov eax, [esp + 16]
166 and eax, HEX(0ffff)
167 mov word ptr ds:[BSS_PxeBufferOffset], ax
168
169 pusha
170
171 /* Set the function ID and call realmode */
172 mov bx, FNID_PxeCallApi
173 call i386CallRealMode
174
175 popa
176
177 mov ax, word ptr [BSS_PxeResult]
178
179 ret
180
181
182 PUBLIC i386CallRealMode
183 i386CallRealMode:
184 /* Set continue address and switch to real mode */
185 mov dword ptr ds:[ContinueAddress], offset i386CallRealMode_return
186 jmp SwitchToReal
187 i386CallRealMode_return:
188 ret
189
190
191 /* Entrypoint for realmode function calls
192 * ContinueAddress must be set to the return point from realmode
193 * bx must be set to the ID of the realmode function to call. */
194 PUBLIC SwitchToReal
195 SwitchToReal:
196 /* Set sane segments */
197 mov ax, PMODE_DS
198 mov ds, ax
199 mov es, ax
200 mov fs, ax
201 mov gs, ax
202 mov ss, ax
203
204 /* Save 32-bit stack pointer */
205 mov dword ptr ds:[stack32], esp
206
207 /* jmp to 16-bit segment to set the limit correctly */
208 .byte HEX(0ea) // jmp far RMODE_CS:switch_to_real16
209 SwitchToReal16Address:
210 .long 0 // receives address of switch_to_real16
211 .word RMODE_CS
212 nop
213
214
215 /* 16-bit stack pointer */
216 stack16:
217 .word STACK16ADDR
218
219 /* 32-bit stack pointer */
220 stack32:
221 .long STACKADDR
222
223 .align 4 /* force 4-byte alignment */
224 gdt:
225 /* NULL Descriptor */
226 .word HEX(0000)
227 .word HEX(0000)
228 .word HEX(0000)
229 .word HEX(0000)
230
231 /* 32-bit flat CS */
232 .word HEX(FFFF)
233 .word HEX(0000)
234 .word HEX(9A00)
235 .word HEX(00CF)
236
237 /* 32-bit flat DS */
238 .word HEX(FFFF)
239 .word HEX(0000)
240 .word HEX(9200)
241 .word HEX(00CF)
242
243 /* 16-bit real mode CS */
244 .word HEX(FFFF)
245 .word HEX(0000)
246 .word HEX(9E00)
247 .word HEX(0000)
248
249 /* 16-bit real mode DS */
250 .word HEX(FFFF)
251 .word HEX(0000)
252 .word HEX(9200)
253 .word HEX(0000)
254
255 /* GDT table pointer */
256 gdtptr:
257 .word HEX(27) /* Limit */
258 .long gdt /* Base Address */
259
260 // See _i386IdtDescriptor
261 PUBLIC i386idtptr
262 i386idtptr:
263 .word 255 /* Limit */
264 .long _i386Idt /* Base Address */
265
266 PUBLIC _FrldrBootDrive
267 _FrldrBootDrive:
268 .byte 0
269
270 PUBLIC _FrldrBootPartition
271 _FrldrBootPartition:
272 .long 0
273
274 END