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