3 * Copyright (C) 1998-2002 Brian Palmer <brianp@sginet.com>
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.
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.
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.
21 #include <arch/pc/x86common.h>
26 //EXTERN _i386idtptr:FWORD
30 PUBLIC _RealEntryPoint
33 /* Setup segment selectors */
41 /* Setup protected mode stack */
42 mov esp, dword ptr [stack32]
46 lidt fword ptr [i386idtptr]
51 /* Continue execution */
52 jmp dword ptr [ContinueAddress]
60 /* Store BootDrive and BootPartition */
63 mov dword ptr [_FrldrBootDrive], eax
65 mov dword ptr [_FrldrBootPartition], eax
67 /* Patch long jump with real mode entry point */
68 mov eax, dword ptr ds:[BSS_RealModeEntry]
69 mov dword ptr ds:[SwitchToReal16Address], eax
71 /* Initialize the idt */
79 /* We should never get here */
87 * Switches the processor to protected mode
90 EXTERN(switch_to_prot)
94 cli /* None of these */
96 /* We don't know what values are currently */
97 /* in the segment registers. So we are */
98 /* going to reload them with sane values. */
99 /* Of course CS has to already be valid. */
100 /* We are currently in real-mode so we */
101 /* need real-mode segment values. */
109 /* Get the return address off the stack */
110 pop word ptr ds:[code32ret]
112 /* Save 16-bit stack pointer */
113 mov word ptr ds:[stack16], sp
121 /* Enable Protected Mode */
126 /* Clear prefetch queue & correct CS */
127 //ljmp PMODE_CS, inpmode
128 jmp far ptr PMODE_CS:inpmode
133 /* Setup segment selectors */
140 mov esp, dword ptr [stack32]
142 /* Put the return address back onto the stack */
143 push dword ptr [code32ret]
145 /* Now return in p-mode! */
149 * Switches the processor back to real mode
152 EXTERN(switch_to_real)
156 /* We don't know what values are currently */
157 /* in the segment registers. So we are */
158 /* going to reload them with sane values. */
159 /* Of course CS has to already be valid. */
160 /* We are currently in protected-mode so we */
161 /* need protected-mode segment values. */
169 /* Get the return address off the stack */
170 pop dword ptr [code16ret]
172 /* Save 32-bit stack pointer */
173 mov dword ptr [stack32], esp
175 /* jmp to 16-bit segment to set the limit correctly */
176 ljmp RMODE_CS, switch_to_real16
181 /* Restore segment registers to correct limit */
189 /* Disable Protected Mode */
194 /* Clear prefetch queue & correct CS */
196 jmp far ptr 0:inrmode
206 /* Clear out the high 16-bits of ESP */
207 /* This is needed because I have one */
208 /* machine that hangs when booted to dos if */
209 /* anything other than 0x0000 is in the high */
210 /* 16-bits of ESP. Even though real-mode */
211 /* code should only use SP and not ESP. */
214 mov sp, word ptr ds:[stack16]
216 /* Put the return address back onto the stack */
217 push word ptr ds:[code16ret]
219 /* Load IDTR with real mode value */
222 sti /* These are ok now */
224 /* Now return in r-mode! */
236 * int Int386(int ivec, REGS* in, REGS* out);
241 /* Get the function parameters */
242 mov eax, dword ptr [esp + 4]
243 mov dword ptr ds:[BSS_IntVector], eax
244 mov eax, dword ptr [esp + 8]
245 mov dword ptr [Int386_regsin], eax
246 mov eax, dword ptr [esp + 12]
247 mov dword ptr [Int386_regsout], eax
249 /* Save all registers + segment registers */
256 /* Copy input registers */
257 mov esi, dword ptr [Int386_regsin]
258 mov edi, BSS_RegisterSet
262 /* Set the function ID */
265 /* Set continue address and switch to real mode */
266 mov dword ptr [ContinueAddress], offset Int386_return
271 /* Copy output registers */
272 mov esi, BSS_RegisterSet
273 mov edi, dword ptr [Int386_regsout]
286 * U16 PxeCallApi(U16 Segment, U16 Offset, U16 Service, VOID *Parameter);
298 /* copy entry point */
302 mov dword ptr ds:[BSS_PxeEntryPoint], eax
306 mov word ptr ds:[BSS_PxeFunction], ax
308 /* convert pointer to data buffer to segment/offset */
312 mov word ptr ds:[BSS_PxeBufferSegment], ax
315 mov word ptr ds:[BSS_PxeBufferOffset], ax
317 /* Set the function ID and call realmode */
318 mov bx, FNID_PxeCallApi
319 call i386CallRealMode
327 mov ax, word ptr [BSS_PxeResult]
334 /* Set the function ID */
335 mov bx, FNID_SoftReboot
337 /*Switch to real mode (We don't return) */
341 PUBLIC _ChainLoadBiosBootSectorCode
342 _ChainLoadBiosBootSectorCode:
343 /* Set the boot drive */
344 mov dl, byte ptr [_FrldrBootDrive]
346 /* Set the function ID */
347 mov bx, FNID_ChainLoadBiosBootSectorCode
349 /*Switch to real mode (We don't return) */
353 PUBLIC i386CallRealMode
355 /* Set continue address and switch to real mode */
356 mov dword ptr [ContinueAddress], offset i386CallRealMode_return
358 i386CallRealMode_return:
362 /* Entrypoint for realmode function calls
363 * ContinueAddress must be set to the return point from realmode
364 * bx must be set to the ID of the realmode function to call. */
366 /* Set sane segments */
374 /* Save 32-bit stack pointer */
375 mov dword ptr [stack32], esp
377 /* jmp to 16-bit segment to set the limit correctly */
378 .byte HEX(0ea) // jmp far RMODE_CS:switch_to_real16
379 SwitchToReal16Address:
380 .long 0 // receives address of switch_to_real16
385 /* 16-bit stack pointer */
389 /* 32-bit stack pointer */
393 /* 16-bit return address */
397 /* 32-bit return address */
402 .align 4 /* force 4-byte alignment */
404 /* NULL Descriptor */
422 /* 16-bit real mode CS */
428 /* 16-bit real mode DS */
434 /* GDT table pointer */
436 .word HEX(27) /* Limit */
437 .long gdt /* Base Address */
439 /* Real-mode IDT pointer */
441 .word HEX(3ff) /* Limit */
442 .long 0 /* Base Address */
446 .word 255 /* Limit */
447 .long _i386Idt /* Base Address */
449 PUBLIC _FrldrBootDrive
453 PUBLIC _FrldrBootPartition