ReactOS 0.4.15-dev-7958-gcd0bb1a
winldr.c
Go to the documentation of this file.
1/*
2 * PROJECT: EFI Windows Loader
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: boot/freeldr/freeldr/arch/i386/winldr.c
5 * PURPOSE: Memory related routines
6 * PROGRAMMERS: Aleksey Bragin (aleksey@reactos.org)
7 */
8
9/* INCLUDES ******************************************************************/
10
11#include <freeldr.h>
12#include <ndk/asm.h>
14#include "../../winldr.h"
15
16#include <debug.h>
18
19// This is needed because headers define wrong one for ReactOS
20#undef KIP0PCRADDRESS
21#define KIP0PCRADDRESS 0xffdff000
22
23#define SELFMAP_ENTRY 0x300
24
25// This is needed only for SetProcessorContext routine
26#pragma pack(2)
27typedef struct
28{
31} GDTIDT;
32#pragma pack(4)
33
34/*
35 * Consider adding these definitions into
36 * ntoskrnl/include/internal/i386/intrin_i.h and/or the NDK.
37 */
38
39#define DPL_SYSTEM 0
40#define DPL_USER 3
41
42#define TYPE_TSS16A 0x01 // 16-bit Task State Segment (Available)
43#define TYPE_LDT 0x02 // Local Descriptor Table
44#define TYPE_TSS16B 0x03 // 16-bit Task State Segment (Busy)
45#define TYPE_CALL16 0x04 // 16-bit Call Gate
46#define TYPE_TASK 0x05 // Task Gate (I386_TASK_GATE)
47#define TYPE_INT16 0x06 // 16-bit Interrupt Gate
48#define TYPE_TRAP16 0x07 // 16-bit Trap Gate
49// #define TYPE_RESERVED_1 0x08
50#define TYPE_TSS32A 0x09 // 32-bit Task State Segment (Available) (I386_TSS)
51// #define TYPE_RESERVED_2 0x0A
52#define TYPE_TSS32B 0x0B // 32-bit Task State Segment (Busy) (I386_ACTIVE_TSS)
53#define TYPE_CALL32 0x0C // 32-bit Call Gate (I386_CALL_GATE)
54// #define TYPE_RESERVED_3 0x0D
55#define TYPE_INT32 0x0E // 32-bit Interrupt Gate (I386_INTERRUPT_GATE)
56#define TYPE_TRAP32 0x0F // 32-bit Trap Gate (I386_TRAP_GATE)
57
58#define DESCRIPTOR_ACCESSED 0x1
59#define DESCRIPTOR_READ_WRITE 0x2
60#define DESCRIPTOR_EXECUTE_READ 0x2
61#define DESCRIPTOR_EXPAND_DOWN 0x4
62#define DESCRIPTOR_CONFORMING 0x4
63#define DESCRIPTOR_CODE 0x8
64
65#define TYPE_CODE (0x10 | DESCRIPTOR_CODE | DESCRIPTOR_EXECUTE_READ)
66#define TYPE_DATA (0x10 | DESCRIPTOR_READ_WRITE)
67
68#if 0
69VOID
70DumpGDTEntry(ULONG_PTR Base, ULONG Selector)
71{
72 PKGDTENTRY pGdt = (PKGDTENTRY)((ULONG_PTR)Base + Selector);
73
74 TRACE("\n"
75 "Selector 0x%04x\n"
76 "===============\n"
77 "LimitLow = 0x%04x\n"
78 "BaseLow = 0x%04x\n"
79 "HighWord.Bytes.BaseMid = 0x%02x\n"
80 "HighWord.Bytes.Flags1 = 0x%02x\n"
81 "HighWord.Bytes.Flags2 = 0x%02x\n"
82 "HighWord.Bytes.BaseHi = 0x%02x\n"
83 "\n",
84 Selector,
85 pGdt->LimitLow, pGdt->BaseLow,
86 pGdt->HighWord.Bytes.BaseMid,
87 pGdt->HighWord.Bytes.Flags1,
88 pGdt->HighWord.Bytes.Flags2,
89 pGdt->HighWord.Bytes.BaseHi);
90}
91#endif
92
93/* GLOBALS *******************************************************************/
94
97
102
106
107/* FUNCTIONS *****************************************************************/
108
109static
112{
113 ULONG NumPageTables, TotalSize;
115 // It's better to allocate PDE + PTEs contiguous
116
117 // Max number of entries = MaxPageNum >> 10
118 // FIXME: This is a number to describe ALL physical memory
119 // and windows doesn't expect ALL memory mapped...
120 NumPageTables = TotalPagesInLookupTable >> 10;
121
122 TRACE("NumPageTables = %d\n", NumPageTables);
123
124 // Allocate memory block for all these things:
125 // PDE, HAL mapping page table, physical mapping, kernel mapping
126 TotalSize = (1 + 1 + NumPageTables * 2) * MM_PAGE_SIZE;
127
128 // PDE+HAL+KernelPTEs == MemoryData
130
131 // Physical PTEs = FirmwareTemporary
132 PhysicalPageTablesBuffer = (PUCHAR)Buffer + TotalSize - NumPageTables*MM_PAGE_SIZE;
134 NumPageTables*MM_PAGE_SIZE,
136
137 // This check is now redundant
138 if (Buffer + (TotalSize - NumPageTables*MM_PAGE_SIZE) !=
140 {
141 TRACE("There was a problem allocating two adjacent blocks of memory!\n");
142 }
143
145 {
146 UiMessageBox("Impossible to allocate memory block for page tables!");
147 return FALSE;
148 }
149
150 // Zero all this memory block
151 RtlZeroMemory(Buffer, TotalSize);
152
153 // Set up pointers correctly now
155
156 // Map the page directory at 0xC0000000 (maps itself)
157 PDE[SELFMAP_ENTRY].PageFrameNumber = (ULONG)PDE >> MM_PAGE_SHIFT;
160
161 // The last PDE slot is allocated for HAL's memory mapping (Virtual Addresses 0xFFC00000 - 0xFFFFFFFF)
162 HalPageTable = (PHARDWARE_PTE)&Buffer[MM_PAGE_SIZE*1];
163
164 // Map it
165 PDE[1023].PageFrameNumber = (ULONG)HalPageTable >> MM_PAGE_SHIFT;
166 PDE[1023].Valid = 1;
167 PDE[1023].Write = 1;
168
169 // Store pointer to the table for easier access
170 KernelPageTablesBuffer = &Buffer[MM_PAGE_SIZE*2];
171
172 // Zero counters of page tables used
175
176 return TRUE;
177}
178
179static
180VOID
182{
183 //TRACE("Creating PDE Entry %X\n", Entry);
184
185 // Identity mapping
186 *PhysicalPT = (PHARDWARE_PTE)&PhysicalPageTablesBuffer[PhysicalPageTables*MM_PAGE_SIZE];
188
189 PDE[Entry].PageFrameNumber = (ULONG)*PhysicalPT >> MM_PAGE_SHIFT;
190 PDE[Entry].Valid = 1;
191 PDE[Entry].Write = 1;
192
193 if (Entry+(KSEG0_BASE >> 22) > 1023)
194 {
195 TRACE("WARNING! Entry: %X > 1023\n", Entry+(KSEG0_BASE >> 22));
196 }
197
198 // Kernel-mode mapping
199 *KernelPT = (PHARDWARE_PTE)&KernelPageTablesBuffer[KernelPageTables*MM_PAGE_SIZE];
201
202 PDE[Entry+(KSEG0_BASE >> 22)].PageFrameNumber = ((ULONG)*KernelPT >> MM_PAGE_SHIFT);
203 PDE[Entry+(KSEG0_BASE >> 22)].Valid = 1;
204 PDE[Entry+(KSEG0_BASE >> 22)].Write = 1;
205}
206
209 IN PFN_COUNT NumberOfPages,
210 IN BOOLEAN KernelMapping)
211{
212 PHARDWARE_PTE PhysicalPT;
213 PHARDWARE_PTE KernelPT;
215
216 TRACE("MempSetupPaging: SP 0x%X, Number: 0x%X, Kernel: %s\n",
217 StartPage, NumberOfPages, KernelMapping ? "yes" : "no");
218
219 // HACK
220 if (StartPage+NumberOfPages >= 0x80000)
221 {
222 //
223 // We cannot map this as it requires more than 1 PDE
224 // and in fact it's not possible at all ;)
225 //
226 //TRACE("skipping...\n");
227 return TRUE;
228 }
229
230 //
231 // Now actually set up the page tables for identity mapping
232 //
233 for (Page = StartPage; Page < StartPage + NumberOfPages; Page++)
234 {
235 Entry = Page >> 10;
236
237 if (((PULONG)PDE)[Entry] == 0)
238 {
239 MempAllocatePTE(Entry, &PhysicalPT, &KernelPT);
240 }
241 else
242 {
243 PhysicalPT = (PHARDWARE_PTE)(PDE[Entry].PageFrameNumber << MM_PAGE_SHIFT);
244 KernelPT = (PHARDWARE_PTE)(PDE[Entry+(KSEG0_BASE >> 22)].PageFrameNumber << MM_PAGE_SHIFT);
245 }
246
247 PhysicalPT[Page & 0x3ff].PageFrameNumber = Page;
248 PhysicalPT[Page & 0x3ff].Valid = 1;
249 PhysicalPT[Page & 0x3ff].Write = (Page != 0);
250
251 if (KernelMapping)
252 {
253 if (KernelPT[Page & 0x3ff].Valid) WARN("KernelPT already mapped\n");
254 KernelPT[Page & 0x3ff].PageFrameNumber = Page;
255 KernelPT[Page & 0x3ff].Valid = (Page != 0);
256 KernelPT[Page & 0x3ff].Write = (Page != 0);
257 }
258 }
259
260 return TRUE;
261}
262
263VOID
265{
266 PHARDWARE_PTE KernelPT;
267 PFN_NUMBER Entry = (Page >> 10) + (KSEG0_BASE >> 22);
268
269 /* Don't unmap page directory or HAL entries */
270 if (Entry == SELFMAP_ENTRY || Entry == 1023)
271 return;
272
273 if (PDE[Entry].Valid)
274 {
275 KernelPT = (PHARDWARE_PTE)(PDE[Entry].PageFrameNumber << MM_PAGE_SHIFT);
276
277 if (KernelPT)
278 {
279 KernelPT[Page & 0x3ff].PageFrameNumber = 0;
280 KernelPT[Page & 0x3ff].Valid = 0;
281 KernelPT[Page & 0x3ff].Write = 0;
282 }
283 }
284}
285
286static
287VOID
289{
290 BOOLEAN LocalAPIC;
291 LARGE_INTEGER MsrValue;
292 ULONG APICAddress, CpuInfo[4];
293
294 /* Check if we have a local APIC */
295 __cpuid((int*)CpuInfo, 1);
296 LocalAPIC = (((CpuInfo[3] >> 9) & 1) != 0);
297
298 /* If there is no APIC, just return */
299 if (!LocalAPIC)
300 return;
301
302 /* Read the APIC Address */
303 MsrValue.QuadPart = __readmsr(0x1B);
304 APICAddress = (MsrValue.LowPart & 0xFFFFF000);
305
306 TRACE("Local APIC detected at address 0x%x\n",
307 APICAddress);
308
309 /* Map it */
310 HalPageTable[(APIC_BASE - 0xFFC00000) >> MM_PAGE_SHIFT].PageFrameNumber
311 = APICAddress >> MM_PAGE_SHIFT;
312 HalPageTable[(APIC_BASE - 0xFFC00000) >> MM_PAGE_SHIFT].Valid = 1;
313 HalPageTable[(APIC_BASE - 0xFFC00000) >> MM_PAGE_SHIFT].Write = 1;
314 HalPageTable[(APIC_BASE - 0xFFC00000) >> MM_PAGE_SHIFT].WriteThrough = 1;
315 HalPageTable[(APIC_BASE - 0xFFC00000) >> MM_PAGE_SHIFT].CacheDisable = 1;
316}
317
318static
321{
322 TRACE("HalPageTable: 0x%X\n", HalPageTable);
323
324 /*
325 * The Page Tables have been setup, make special handling
326 * for the boot processor PCR and KI_USER_SHARED_DATA.
327 */
328 HalPageTable[(KI_USER_SHARED_DATA - 0xFFC00000) >> MM_PAGE_SHIFT].PageFrameNumber = PcrBasePage+1;
329 HalPageTable[(KI_USER_SHARED_DATA - 0xFFC00000) >> MM_PAGE_SHIFT].Valid = 1;
330 HalPageTable[(KI_USER_SHARED_DATA - 0xFFC00000) >> MM_PAGE_SHIFT].Write = 1;
331
332 HalPageTable[(KIP0PCRADDRESS - 0xFFC00000) >> MM_PAGE_SHIFT].PageFrameNumber = PcrBasePage;
333 HalPageTable[(KIP0PCRADDRESS - 0xFFC00000) >> MM_PAGE_SHIFT].Valid = 1;
334 HalPageTable[(KIP0PCRADDRESS - 0xFFC00000) >> MM_PAGE_SHIFT].Write = 1;
335
336 /* Map APIC */
338
339 /* Map VGA memory */
340 //VideoMemoryBase = MmMapIoSpace(0xb8000, 4000, MmNonCached);
341 //TRACE("VideoMemoryBase: 0x%X\n", VideoMemoryBase);
342
343 return TRUE;
344}
345
346#define ExtendedBIOSDataArea ((PULONG)0x740)
347#define ExtendedBIOSDataSize ((PULONG)0x744)
348#define RomFontPointers ((PULONG)0x700)
349
350static
352{
353 /* Get the address of the BIOS ROM fonts. Win 2003 videoprt reads these
354 values from address 0x700 .. 0x718 and store them in the registry
355 in HKLM\System\CurrentControlSet\Control\Wow\RomFontPointers */
357
358 /* Store address of the extended BIOS data area in 0x740 */
360
362 {
363 WARN("Couldn't get address of extended BIOS data area\n");
364 }
365 else
366 {
367 TRACE("*ExtendedBIOSDataArea = 0x%lx\n", *ExtendedBIOSDataArea);
368 }
369}
370
372{
373 ULONG TssSize;
374 //ULONG TssPages;
375 ULONG_PTR Pcr = 0;
376 ULONG_PTR Tss = 0;
377 ULONG BlockSize, NumPages;
378
379 LoaderBlock->u.I386.CommonDataArea = NULL; // Force No ABIOS support
380 LoaderBlock->u.I386.MachineType = MACHINE_TYPE_ISA;
381
382 /* Allocate 2 pages for PCR: one for the boot processor PCR and one for KI_USER_SHARED_DATA */
384 PcrBasePage = Pcr >> MM_PAGE_SHIFT;
385 if (Pcr == 0)
386 {
387 UiMessageBox("Could not allocate PCR.");
388 return;
389 }
390
391 /* Allocate TSS */
392 TssSize = (sizeof(KTSS) + MM_PAGE_SIZE) & ~(MM_PAGE_SIZE - 1);
393 //TssPages = TssSize / MM_PAGE_SIZE;
394
396 TssBasePage = Tss >> MM_PAGE_SHIFT;
397 if (Tss == 0)
398 {
399 UiMessageBox("Could not allocate TSS.");
400 return;
401 }
402
403 /* Allocate space for new GDT + IDT */
404 BlockSize = NUM_GDT*sizeof(KGDTENTRY) + NUM_IDT*sizeof(KIDTENTRY);//FIXME: Use GDT/IDT limits here?
405 NumPages = (BlockSize + MM_PAGE_SIZE - 1) >> MM_PAGE_SHIFT;
406 GdtIdt = (PKGDTENTRY)MmAllocateMemoryWithType(NumPages * MM_PAGE_SIZE, LoaderMemoryData);
407 if (GdtIdt == NULL)
408 {
409 UiMessageBox("Could not allocate pages for GDT+IDT!");
410 return;
411 }
412
413 /* Zero newly prepared GDT+IDT */
414 RtlZeroMemory(GdtIdt, NumPages << MM_PAGE_SHIFT);
415
416 // Before we start mapping pages, create a block of memory, which will contain
417 // PDE and PTEs
419 {
420 BugCheck("MempAllocatePageTables failed!\n");
421 }
422
423 /* Map stuff like PCR, KI_USER_SHARED_DATA and Apic */
425
426 /* Set some special fields */
428}
429
430
431VOID
433 _In_ USHORT OperatingSystemVersion)
434{
435 GDTIDT GdtDesc, IdtDesc, OldIdt;
436 PKGDTENTRY pGdt;
437 PKIDTENTRY pIdt;
438 USHORT Ldt = 0;
439 ULONG Pcr;
440 ULONG Tss;
441 //ULONG i;
442
443 Pcr = KIP0PCRADDRESS;
444 Tss = KSEG0_BASE | (TssBasePage << MM_PAGE_SHIFT);
445
446 TRACE("GdtIdt %p, Pcr %p, Tss 0x%08x\n",
447 GdtIdt, Pcr, Tss);
448
449 /* Enable paging */
450 //BS->ExitBootServices(ImageHandle,MapKey);
451
452 /* Disable Interrupts */
453 _disable();
454
455 /* Re-initialize EFLAGS */
456 __writeeflags(0);
457
458 /* Set the PDBR */
460
461 /* Enable paging by modifying CR0 */
463
464 /* The Kernel expects the boot processor PCR to be zero-filled on startup */
465 RtlZeroMemory((PVOID)Pcr, MM_PAGE_SIZE);
466
467 /* Get old values of GDT and IDT */
469 __sidt(&IdtDesc);
470
471 /* Save old IDT */
472 OldIdt.Base = IdtDesc.Base;
473 OldIdt.Limit = IdtDesc.Limit;
474
475 /* Prepare new IDT+GDT */
476 GdtDesc.Base = KSEG0_BASE | (ULONG_PTR)GdtIdt;
477 GdtDesc.Limit = NUM_GDT * sizeof(KGDTENTRY) - 1;
478 IdtDesc.Base = (ULONG)((PUCHAR)GdtDesc.Base + GdtDesc.Limit + 1);
479 IdtDesc.Limit = NUM_IDT * sizeof(KIDTENTRY) - 1;
480
481 // ========================
482 // Fill all descriptors now
483 // ========================
484
485 pGdt = (PKGDTENTRY)GdtDesc.Base;
486 pIdt = (PKIDTENTRY)IdtDesc.Base;
487
488 /* KGDT_NULL (0x00) Null Selector - Unused */
489 KiSetGdtEntry(KiGetGdtEntry(pGdt, KGDT_NULL), 0x0000, 0, 0, DPL_SYSTEM, 0);
490 // DumpGDTEntry(GdtDesc.Base, KGDT_NULL);
491
492 /* KGDT_R0_CODE (0x08) Ring 0 Code selector - Flat 4Gb */
493 KiSetGdtEntry(KiGetGdtEntry(pGdt, KGDT_R0_CODE), 0x0000, 0xFFFFFFFF,
495 // DumpGDTEntry(GdtDesc.Base, KGDT_R0_CODE);
496
497 /* KGDT_R0_DATA (0x10) Ring 0 Data selector - Flat 4Gb */
498 KiSetGdtEntry(KiGetGdtEntry(pGdt, KGDT_R0_DATA), 0x0000, 0xFFFFFFFF,
500 // DumpGDTEntry(GdtDesc.Base, KGDT_R0_DATA);
501
502 /* KGDT_R3_CODE (0x18) Ring 3 Code Selector - Flat 2Gb */
503 KiSetGdtEntry(KiGetGdtEntry(pGdt, KGDT_R3_CODE), 0x0000, 0xFFFFFFFF,
504 TYPE_CODE, DPL_USER, 2);
505 // DumpGDTEntry(GdtDesc.Base, KGDT_R3_CODE);
506
507 /* KGDT_R3_DATA (0x20) Ring 3 Data Selector - Flat 2Gb */
508 KiSetGdtEntry(KiGetGdtEntry(pGdt, KGDT_R3_DATA), 0x0000, 0xFFFFFFFF,
509 TYPE_DATA, DPL_USER, 2);
510 // DumpGDTEntry(GdtDesc.Base, KGDT_R3_DATA);
511
512 /* KGDT_TSS (0x28) TSS Selector (Ring 0) */
514 0x78-1 /* FIXME: Check this; would be sizeof(KTSS)-1 */,
516 // DumpGDTEntry(GdtDesc.Base, KGDT_TSS);
517
518 /*
519 * KGDT_R0_PCR (0x30) PCR Selector (Ring 0)
520 *
521 * IMPORTANT COMPATIBILITY NOTE:
522 * Windows <= Server 2003 sets a Base == KIP0PCRADDRESS (0xffdff000 on x86)
523 * with a Limit of 1 page (LimitLow == 1, Granularity == 1, that is interpreted
524 * as a "Limit" == 0x1fff but is incorrect, of course).
525 * On Windows Longhorn/Vista+ however, the Base is not hardcoded to KIP0PCRADDRESS
526 * and the limit is set in bytes (Granularity == 0):
527 * Longhorn/Vista reports LimitLow == 0x0fff == MM_PAGE_SIZE - 1, whereas
528 * Windows 7+ uses larger sizes there (not aligned on a page boundary).
529 */
530 if (OperatingSystemVersion < _WIN32_WINNT_VISTA)
531 {
532 /* Server 2003 way */
535 }
536 else
537 {
538 /* Vista+ way */
539 KiSetGdtEntry(KiGetGdtEntry(pGdt, KGDT_R0_PCR), (ULONG32)Pcr, MM_PAGE_SIZE - 1,
541 }
542
543 // DumpGDTEntry(GdtDesc.Base, KGDT_R0_PCR);
544
545 /* KGDT_R3_TEB (0x38) Thread Environment Block Selector (Ring 3) */
546 KiSetGdtEntry(KiGetGdtEntry(pGdt, KGDT_R3_TEB), 0x0000, 0x0FFF,
548 // DumpGDTEntry(GdtDesc.Base, KGDT_R3_TEB);
549
550 /* KGDT_VDM_TILE (0x40) VDM BIOS Data Area Selector (Ring 3) */
551 KiSetGdtEntry(KiGetGdtEntry(pGdt, KGDT_VDM_TILE), 0x0400, 0xFFFF,
552 TYPE_DATA, DPL_USER, 0);
553 // DumpGDTEntry(GdtDesc.Base, KGDT_VDM_TILE);
554
555 /* KGDT_LDT (0x48) LDT Selector (Reserved) */
556 KiSetGdtEntry(KiGetGdtEntry(pGdt, KGDT_LDT), 0x0000, 0, 0, DPL_SYSTEM, 0);
557 // DumpGDTEntry(GdtDesc.Base, KGDT_LDT);
558
559 /* KGDT_DF_TSS (0x50) Double-Fault Task Switch Selector (Ring 0) */
560 KiSetGdtEntry(KiGetGdtEntry(pGdt, KGDT_DF_TSS), 0x20000 /* FIXME: Not correct! */,
561 0xFFFF /* FIXME: Not correct! */,
563 // DumpGDTEntry(GdtDesc.Base, KGDT_DF_TSS);
564
565 /* KGDT_NMI_TSS (0x58) NMI Task Switch Selector (Ring 0) */
566 KiSetGdtEntry(KiGetGdtEntry(pGdt, KGDT_NMI_TSS), 0x20000, 0xFFFF,
568 // DumpGDTEntry(GdtDesc.Base, KGDT_NMI_TSS);
569
570 /* Selector (0x60) - Unused (Reserved) on Windows Longhorn/Vista+ */
571 KiSetGdtEntry(KiGetGdtEntry(pGdt, 0x60), 0x20000 /* FIXME: Maybe not correct, but noone cares */,
572 0xFFFF, TYPE_DATA, DPL_SYSTEM, 0);
573 // DumpGDTEntry(GdtDesc.Base, 0x60);
574
575 /* Video Display Buffer Selector (0x68) - Unused (Reserved) on Windows Longhorn/Vista+ */
576 KiSetGdtEntry(KiGetGdtEntry(pGdt, 0x68), 0xB8000, 0x3FFF,
578 // DumpGDTEntry(GdtDesc.Base, 0x68);
579
580 /*
581 * GDT Alias Selector (points to GDT) (0x70)
582 *
583 * IMPORTANT COMPATIBILITY NOTE:
584 * The Base is not fixed to 0xFFFF7000 on Windows Longhorn/Vista+.
585 */
586 KiSetGdtEntry(KiGetGdtEntry(pGdt, 0x70), 0xFFFF7000 /* GdtDesc.Base ?? */, GdtDesc.Limit,
588 // DumpGDTEntry(GdtDesc.Base, 0x70);
589
590 /*
591 * Windows <= Server 2003 defines three additional unused but valid
592 * descriptors there, possibly for debugging purposes only.
593 * They are not present on Windows Longhorn/Vista+.
594 */
595 // KiSetGdtEntry(KiGetGdtEntry(pGdt, 0x78), 0x80400000, 0xffff, TYPE_CODE, DPL_SYSTEM, 0);
596 // KiSetGdtEntry(KiGetGdtEntry(pGdt, 0x80), 0x80400000, 0xffff, TYPE_DATA, DPL_SYSTEM, 0);
597 // KiSetGdtEntry(KiGetGdtEntry(pGdt, 0x88), 0x0000, 0, TYPE_DATA, DPL_SYSTEM, 0);
598
599 /* Copy the old IDT */
600 RtlCopyMemory(pIdt, (PVOID)OldIdt.Base, OldIdt.Limit + 1);
601
602 /* Mask interrupts */
603 //asm("cli\n"); // they are already masked before enabling paged mode
604
605 /* Load GDT+IDT */
607 __lidt(&IdtDesc);
608
609 /* Jump to proper CS and clear prefetch queue */
610#if defined(__GNUC__) || defined(__clang__)
611 asm("ljmp $0x08, $1f\n"
612 "1:\n");
613#elif defined(_MSC_VER)
614 /* We cannot express the above in MASM so we use this far return instead */
615 __asm
616 {
617 push 8
618 push offset resume
619 retf
620 resume:
621 };
622#else
623#error
624#endif
625
626 /* Set SS selector */
627 Ke386SetSs(KGDT_R0_DATA);
628
629 /* Set DS and ES selectors */
630 Ke386SetDs(KGDT_R0_DATA);
631 Ke386SetEs(KGDT_R0_DATA); // This is vital for rep stosd
632
633 /* LDT = not used ever, thus set to 0 */
634 Ke386SetLocalDescriptorTable(Ldt);
635
636 /* Load TSR */
637 Ke386SetTr(KGDT_TSS);
638
639 /* Clear GS */
640 Ke386SetGs(0);
641
642 /* Set FS to PCR */
643 Ke386SetFs(KGDT_R0_PCR);
644
645 // Real end of the function, just for information
646 /* do not uncomment!
647 pop edi;
648 pop esi;
649 pop ebx;
650 mov esp, ebp;
651 pop ebp;
652 ret
653 */
654}
655
656#if DBG
657VOID
659{
660 PULONG PDE_Addr=(PULONG)PDE;//0xC0300000;
661 int i, j;
662
663 TRACE("\nPDE\n");
664
665 for (i=0; i<128; i++)
666 {
667 TRACE("0x%04X | ", i*8);
668
669 for (j=0; j<8; j++)
670 {
671 TRACE("0x%08X ", PDE_Addr[i*8+j]);
672 }
673
674 TRACE("\n");
675 }
676}
677#endif
unsigned char BOOLEAN
FORCEINLINE PKGDTENTRY64 KiGetGdtEntry(PVOID pGdt, USHORT Selector)
Definition: intrin_i.h:13
#define KIP0PCRADDRESS
Definition: amd64.h:27
PVOID GdtIdt
Definition: winldr.c:26
VOID WinLdrSetProcessorContext(_In_ USHORT OperatingSystemVersion)
Definition: winldr.c:349
BOOLEAN MempSetupPaging(IN PFN_NUMBER StartPage, IN PFN_NUMBER NumberOfPages, IN BOOLEAN KernelMapping)
Definition: winldr.c:171
static BOOLEAN MempAllocatePageTables(VOID)
Definition: winldr.c:34
ULONG_PTR TssBasePage
Definition: winldr.c:28
static VOID WinLdrpMapApic(VOID)
Definition: winldr.c:212
ULONG_PTR PcrBasePage
Definition: winldr.c:27
VOID MempUnmapPage(PFN_NUMBER Page)
Definition: winldr.c:205
VOID MempDump(VOID)
Definition: winldr.c:431
void WinLdrSetupMachineDependent(PLOADER_PARAMETER_BLOCK LoaderBlock)
Definition: winldr.c:381
#define TYPE_CODE
Definition: winldr.c:65
#define DPL_USER
Definition: winldr.c:40
PUCHAR KernelPageTablesBuffer
Definition: winldr.c:99
#define SELFMAP_ENTRY
Definition: winldr.c:23
#define TYPE_DATA
Definition: winldr.c:66
PHARDWARE_PTE PDE
Definition: winldr.c:95
#define DPL_SYSTEM
Definition: winldr.c:39
static void WinLdrSetupSpecialDataPointers(VOID)
Definition: winldr.c:351
#define RomFontPointers
Definition: winldr.c:348
ULONG KernelPageTables
Definition: winldr.c:101
#define DESCRIPTOR_ACCESSED
Definition: winldr.c:58
#define ExtendedBIOSDataArea
Definition: winldr.c:346
PUCHAR PhysicalPageTablesBuffer
Definition: winldr.c:98
static VOID MempAllocatePTE(ULONG Entry, PHARDWARE_PTE *PhysicalPT, PHARDWARE_PTE *KernelPT)
Definition: winldr.c:181
static BOOLEAN WinLdrMapSpecialPages(void)
Definition: winldr.c:320
#define ExtendedBIOSDataSize
Definition: winldr.c:347
PHARDWARE_PTE HalPageTable
Definition: winldr.c:96
ULONG PhysicalPageTables
Definition: winldr.c:100
#define TYPE_TSS32A
Definition: winldr.c:50
unsigned int ULONG32
Definition: basetsd.h:123
#define WARN(fmt,...)
Definition: debug.h:112
#define BugCheck(fmt,...)
Definition: debug.h:118
#define DBG_DEFAULT_CHANNEL(ch)
Definition: debug.h:103
#define MachGetExtendedBIOSData(ExtendedBIOSDataArea, ExtendedBIOSDataSize)
Definition: machine.h:122
#define MachVideoGetFontsFromFirmware(RomFontPointers)
Definition: machine.h:100
VOID MmSetMemoryType(PVOID MemoryAddress, SIZE_T MemorySize, TYPE_OF_MEMORY NewType)
Definition: mm.c:144
PVOID MmAllocateMemoryWithType(SIZE_T MemorySize, TYPE_OF_MEMORY MemoryType)
Definition: mm.c:31
PFN_NUMBER TotalPagesInLookupTable
Definition: meminit.c:27
VOID UiMessageBox(_In_ PCSTR Format,...)
Definition: ui.c:359
Definition: bufpool.h:45
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define ULONG_PTR
Definition: config.h:101
GLintptr offset
Definition: glext.h:5920
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
#define Ke386GetGlobalDescriptorTable
Definition: intrin_i.h:452
#define Ke386SetGlobalDescriptorTable
Definition: intrin_i.h:453
FORCEINLINE VOID KiSetGdtEntryEx(_Inout_ PKGDTENTRY Entry, _In_ ULONG32 Base, _In_ ULONG Limit, _In_ UCHAR Type, _In_ UCHAR Dpl, _In_ BOOLEAN Granularity, _In_ UCHAR SegMode)
Definition: intrin_i.h:50
FORCEINLINE VOID KiSetGdtEntry(_Inout_ PKGDTENTRY Entry, _In_ ULONG32 Base, _In_ ULONG Limit, _In_ UCHAR Type, _In_ UCHAR Dpl, _In_ UCHAR SegMode)
Definition: intrin_i.h:73
void __cdecl _disable(void)
Definition: intrin_arm.h:365
PPC_QUAL void __cpuid(int CPUInfo[], const int InfoType)
Definition: intrin_ppc.h:682
PPC_QUAL unsigned long long __readmsr()
Definition: intrin_ppc.h:741
__INTRIN_INLINE void __writeeflags(uintptr_t Value)
Definition: intrin_x86.h:1669
__INTRIN_INLINE void __lidt(void *Source)
Definition: intrin_x86.h:2018
__INTRIN_INLINE unsigned long __readcr0(void)
Definition: intrin_x86.h:1804
__INTRIN_INLINE void __writecr3(unsigned int Data)
Definition: intrin_x86.h:1794
__INTRIN_INLINE void __writecr0(unsigned int Data)
Definition: intrin_x86.h:1789
__INTRIN_INLINE void __sidt(void *Destination)
Definition: intrin_x86.h:2023
#define _In_
Definition: ms_sal.h:308
#define CR0_PG
Definition: asm.h:255
#define KIDTENTRY
Definition: ketypes.h:564
#define APIC_BASE
Definition: ketypes.h:339
#define KTSS
Definition: ketypes.h:1006
#define KSEG0_BASE
Definition: ketypes.h:354
#define PKGDTENTRY
Definition: ketypes.h:523
#define KGDTENTRY
Definition: ketypes.h:522
#define MACHINE_TYPE_ISA
Definition: ketypes.h:113
#define PHARDWARE_PTE
Definition: mmtypes.h:187
#define KGDT_R3_DATA
Definition: ketypes.h:126
#define KGDT_R3_CODE
Definition: ketypes.h:125
#define KGDT_NMI_TSS
Definition: ketypes.h:133
#define KGDT_R3_TEB
Definition: ketypes.h:129
#define KGDT_TSS
Definition: ketypes.h:127
#define KGDT_R0_PCR
Definition: ketypes.h:128
#define KGDT_LDT
Definition: ketypes.h:131
#define KGDT_DF_TSS
Definition: ketypes.h:132
#define KGDT_R0_CODE
Definition: ketypes.h:123
#define KGDT_VDM_TILE
Definition: ketypes.h:130
#define KGDT_R0_DATA
Definition: ketypes.h:124
#define KGDT_NULL
Definition: ketypes.h:122
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2439
#define NUM_IDT
Definition: winldr.h:17
#define NUM_GDT
Definition: winldr.h:16
_In_ PVOID _Out_opt_ BOOLEAN _Out_opt_ PPFN_NUMBER Page
Definition: mm.h:1306
unsigned short USHORT
Definition: pedump.c:61
static void push(calc_node_t *op)
Definition: rpn_ieee.c:113
@ LoaderMemoryData
Definition: arc.h:194
@ LoaderFirmwareTemporary
Definition: arc.h:179
@ LoaderStartupPcrPage
Definition: arc.h:191
#define KI_USER_SHARED_DATA
ULONG PFN_NUMBER
Definition: ke.h:9
#define _WIN32_WINNT_VISTA
Definition: sdkddkver.h:25
#define TRACE(s)
Definition: solgame.cpp:4
base of all file and directory entries
Definition: entries.h:83
Definition: winldr.c:28
USHORT Limit
Definition: winldr.c:29
ULONG Base
Definition: winldr.c:30
ULONG64 PageFrameNumber
Definition: mmtypes.h:78
ULONG64 Write
Definition: mmtypes.h:67
ULONG64 Valid
Definition: mmtypes.h:66
ULONG MachineType
Definition: arc.h:454
PVOID CommonDataArea
Definition: arc.h:453
union _KGDTENTRY::@2447 HighWord
USHORT BaseLow
Definition: ketypes.h:390
USHORT LimitLow
Definition: ketypes.h:389
struct _KGDTENTRY::@2447::@2448 Bytes
union _LOADER_PARAMETER_BLOCK::@3379 u
I386_LOADER_BLOCK I386
Definition: arc.h:562
uint32_t * PULONG
Definition: typedefs.h:59
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
LONGLONG QuadPart
Definition: typedefs.h:114
ULONG LowPart
Definition: typedefs.h:106
static BOOL Write(PBYTE Address, PBYTE Data, SIZE_T Size)
Definition: vmhorizon.c:15
int WINAPI StartPage(_In_ HDC)
ULONG PFN_COUNT
Definition: mmtypes.h:102