[FREELDR/AMD64]
[reactos.git] / reactos / 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
29 .code32
30
31 PUBLIC _RealEntryPoint
32 _RealEntryPoint:
33
34 /* Setup segment selectors */
35 mov ax, PMODE_DS
36 mov ds, ax
37 mov es, ax
38 mov fs, ax
39 mov gs, ax
40 mov ss, ax
41
42 /* Setup protected mode stack */
43 mov esp, dword ptr ds:[stack32]
44
45 /* Load the IDT */
46 #ifdef _USE_ML
47 lidt fword ptr ds:[i386idtptr]
48 #else
49 lidt i386idtptr
50 #endif
51
52 /* Continue execution */
53 jmp dword ptr ds:[ContinueAddress]
54
55 ContinueAddress:
56 .long _FrldrStartup
57
58
59 _FrldrStartup:
60
61 /* Store BootDrive and BootPartition */
62 mov byte ptr ds:[_FrldrBootDrive], dl
63 xor eax, eax
64 mov al, dh
65 mov dword ptr ds:[_FrldrBootPartition], eax
66
67 /* Patch long jump with real mode entry point */
68 mov eax, dword ptr ds:[BSS_RealModeEntry]
69 mov dword ptr ds:[SwitchToReal16Address], eax
70
71 /* Initialize the idt */
72 call _InitIdt
73
74 #ifndef _USE_ML
75 /* Clean out bss */
76 xor eax, eax
77 mov edi, offset __bss_start__
78 mov ecx, offset __bss_end__ + 3
79 sub ecx, edi
80 shr ecx, 2
81 rep stosd
82
83 /* Pass the command line to BootMain */
84 mov eax, offset cmdline
85 #else
86 xor eax, eax
87 #endif
88
89 /* GO! */
90 push eax
91 call _BootMain
92
93 /* We should never get here */
94 stop:
95 jmp stop
96 nop
97 nop
98
99 Int386_regsin:
100 .long 0
101 Int386_regsout:
102 .long 0
103
104 /*
105 * int Int386(int ivec, REGS* in, REGS* out);
106 */
107 PUBLIC _Int386
108 _Int386:
109
110 /* Get the function parameters */
111 mov eax, dword ptr [esp + 4]
112 mov dword ptr ds:[BSS_IntVector], eax
113 mov eax, dword ptr [esp + 8]
114 mov dword ptr [Int386_regsin], eax
115 mov eax, dword ptr [esp + 12]
116 mov dword ptr [Int386_regsout], eax
117
118 /* Save all registers + segment registers */
119 push ds
120 push es
121 push fs
122 push gs
123 pusha
124
125 /* Copy input registers */
126 mov esi, dword ptr [Int386_regsin]
127 mov edi, BSS_RegisterSet
128 mov ecx, REGS_SIZE / 4
129 rep movsd
130
131 /* Set the function ID */
132 mov bx, FNID_Int386
133
134 /* Set continue address and switch to real mode */
135 mov dword ptr [ContinueAddress], offset Int386_return
136 jmp SwitchToReal
137
138 Int386_return:
139
140 /* Copy output registers */
141 mov esi, BSS_RegisterSet
142 mov edi, dword ptr [Int386_regsout]
143 mov ecx, REGS_SIZE / 4
144 rep movsd
145
146 popa
147 pop gs
148 pop fs
149 pop es
150 pop ds
151 ret
152
153
154 /*
155 * U16 PxeCallApi(U16 Segment, U16 Offset, U16 Service, VOID *Parameter);
156 *
157 * RETURNS:
158 */
159 PUBLIC _PxeCallApi
160 _PxeCallApi:
161 /* copy entry point */
162 mov eax, [esp + 4]
163 shl eax, 16
164 mov ax, [esp + 8]
165 mov dword ptr ds:[BSS_PxeEntryPoint], eax
166
167 /* copy function */
168 mov ax, [esp + 12]
169 mov word ptr ds:[BSS_PxeFunction], ax
170
171 /* convert pointer to data buffer to segment/offset */
172 mov eax, [esp + 16]
173 shr eax, 4
174 and eax, HEX(0f000)
175 mov word ptr ds:[BSS_PxeBufferSegment], ax
176 mov eax, [esp + 16]
177 and eax, HEX(0ffff)
178 mov word ptr ds:[BSS_PxeBufferOffset], ax
179
180 pusha
181
182 /* Set the function ID and call realmode */
183 mov bx, FNID_PxeCallApi
184 call i386CallRealMode
185
186 popa
187
188 mov ax, word ptr [BSS_PxeResult]
189
190 ret
191
192
193 PUBLIC _Reboot
194 _Reboot:
195 /* Set the function ID */
196 mov bx, FNID_Reboot
197
198 /*Switch to real mode (We don't return) */
199 jmp SwitchToReal
200
201
202 PUBLIC _ChainLoadBiosBootSectorCode
203 _ChainLoadBiosBootSectorCode:
204 /* Set the boot drive */
205 mov dl, byte ptr [_FrldrBootDrive]
206
207 /* Set the function ID */
208 mov bx, FNID_ChainLoadBiosBootSectorCode
209
210 /*Switch to real mode (We don't return) */
211 jmp SwitchToReal
212
213
214 PUBLIC i386CallRealMode
215 i386CallRealMode:
216 /* Set continue address and switch to real mode */
217 mov dword ptr [ContinueAddress], offset i386CallRealMode_return
218 jmp SwitchToReal
219 i386CallRealMode_return:
220 ret
221
222
223 /* Entrypoint for realmode function calls
224 * ContinueAddress must be set to the return point from realmode
225 * bx must be set to the ID of the realmode function to call. */
226 SwitchToReal:
227 /* Set sane segments */
228 mov ax, PMODE_DS
229 mov ds, ax
230 mov es, ax
231 mov fs, ax
232 mov gs, ax
233 mov ss, ax
234
235 /* Save 32-bit stack pointer */
236 mov dword ptr [stack32], esp
237
238 /* jmp to 16-bit segment to set the limit correctly */
239 .byte HEX(0ea) // jmp far RMODE_CS:switch_to_real16
240 SwitchToReal16Address:
241 .long 0 // receives address of switch_to_real16
242 .word RMODE_CS
243 nop
244
245
246 /* 16-bit stack pointer */
247 stack16:
248 .word STACK16ADDR
249
250 /* 32-bit stack pointer */
251 stack32:
252 .long STACKADDR
253
254 .align 4 /* force 4-byte alignment */
255 gdt:
256 /* NULL Descriptor */
257 .word HEX(0000)
258 .word HEX(0000)
259 .word HEX(0000)
260 .word HEX(0000)
261
262 /* 32-bit flat CS */
263 .word HEX(FFFF)
264 .word HEX(0000)
265 .word HEX(9A00)
266 .word HEX(00CF)
267
268 /* 32-bit flat DS */
269 .word HEX(FFFF)
270 .word HEX(0000)
271 .word HEX(9200)
272 .word HEX(00CF)
273
274 /* 16-bit real mode CS */
275 .word HEX(FFFF)
276 .word HEX(0000)
277 .word HEX(9E00)
278 .word HEX(0000)
279
280 /* 16-bit real mode DS */
281 .word HEX(FFFF)
282 .word HEX(0000)
283 .word HEX(9200)
284 .word HEX(0000)
285
286 /* GDT table pointer */
287 gdtptr:
288 .word HEX(27) /* Limit */
289 .long gdt /* Base Address */
290
291 /* Real-mode IDT pointer */
292 rmode_idtptr:
293 .word HEX(3ff) /* Limit */
294 .long 0 /* Base Address */
295
296 PUBLIC i386idtptr
297 i386idtptr:
298 .word 255 /* Limit */
299 .long _i386Idt /* Base Address */
300
301 PUBLIC _FrldrBootDrive
302 _FrldrBootDrive:
303 .byte 0
304
305 PUBLIC _FrldrBootPartition
306 _FrldrBootPartition:
307 .long 0
308
309 END