2 * PROJECT: EFI Windows Loader
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: freeldr/winldr/i386/wlmemory.c
5 * PURPOSE: Memory related routines
6 * PROGRAMMERS: Aleksey Bragin (aleksey@reactos.org)
9 /* INCLUDES ***************************************************************/
16 // This is needed because headers define wrong one for ReactOS
18 #define KIP0PCRADDRESS 0xffdff000
20 #define HYPER_SPACE_ENTRY 0x300
22 // This is needed only for SetProcessorContext routine
31 DBG_DEFAULT_CHANNEL(WINDOWS
);
33 /* GLOBALS ***************************************************************/
36 PHARDWARE_PTE HalPageTable
;
38 PUCHAR PhysicalPageTablesBuffer
;
39 PUCHAR KernelPageTablesBuffer
;
40 ULONG PhysicalPageTables
;
41 ULONG KernelPageTables
;
47 /* FUNCTIONS **************************************************************/
50 MempAllocatePageTables()
52 ULONG NumPageTables
, TotalSize
;
54 // It's better to allocate PDE + PTEs contigiuos
56 // Max number of entries = MaxPageNum >> 10
57 // FIXME: This is a number to describe ALL physical memory
58 // and windows doesn't expect ALL memory mapped...
59 NumPageTables
= TotalPagesInLookupTable
>> 10;
61 TRACE("NumPageTables = %d\n", NumPageTables
);
63 // Allocate memory block for all these things:
64 // PDE, HAL mapping page table, physical mapping, kernel mapping
65 TotalSize
= (1 + 1 + NumPageTables
* 2) * MM_PAGE_SIZE
;
67 // PDE+HAL+KernelPTEs == MemoryData
68 Buffer
= MmAllocateMemoryWithType(TotalSize
, LoaderMemoryData
);
70 // Physical PTEs = FirmwareTemporary
71 PhysicalPageTablesBuffer
= (PUCHAR
)Buffer
+ TotalSize
- NumPageTables
*MM_PAGE_SIZE
;
72 MmSetMemoryType(PhysicalPageTablesBuffer
,
73 NumPageTables
*MM_PAGE_SIZE
,
74 LoaderFirmwareTemporary
);
76 // This check is now redundant
77 if (Buffer
+ (TotalSize
- NumPageTables
*MM_PAGE_SIZE
) !=
78 PhysicalPageTablesBuffer
)
80 TRACE("There was a problem allocating two adjacent blocks of memory!");
83 if (Buffer
== NULL
|| PhysicalPageTablesBuffer
== NULL
)
85 UiMessageBox("Impossible to allocate memory block for page tables!");
89 // Zero all this memory block
90 RtlZeroMemory(Buffer
, TotalSize
);
92 // Set up pointers correctly now
93 PDE
= (PHARDWARE_PTE
)Buffer
;
95 // Map the page directory at 0xC0000000 (maps itself)
96 PDE
[HYPER_SPACE_ENTRY
].PageFrameNumber
= (ULONG
)PDE
>> MM_PAGE_SHIFT
;
97 PDE
[HYPER_SPACE_ENTRY
].Valid
= 1;
98 PDE
[HYPER_SPACE_ENTRY
].Write
= 1;
100 // The last PDE slot is allocated for HAL's memory mapping (Virtual Addresses 0xFFC00000 - 0xFFFFFFFF)
101 HalPageTable
= (PHARDWARE_PTE
)&Buffer
[MM_PAGE_SIZE
*1];
104 PDE
[1023].PageFrameNumber
= (ULONG
)HalPageTable
>> MM_PAGE_SHIFT
;
108 // Store pointer to the table for easier access
109 KernelPageTablesBuffer
= &Buffer
[MM_PAGE_SIZE
*2];
111 // Zero counters of page tables used
112 PhysicalPageTables
= 0;
113 KernelPageTables
= 0;
119 MempAllocatePTE(ULONG Entry
, PHARDWARE_PTE
*PhysicalPT
, PHARDWARE_PTE
*KernelPT
)
121 //Print(L"Creating PDE Entry %X\n", Entry);
124 *PhysicalPT
= (PHARDWARE_PTE
)&PhysicalPageTablesBuffer
[PhysicalPageTables
*MM_PAGE_SIZE
];
125 PhysicalPageTables
++;
127 PDE
[Entry
].PageFrameNumber
= (ULONG
)*PhysicalPT
>> MM_PAGE_SHIFT
;
128 PDE
[Entry
].Valid
= 1;
129 PDE
[Entry
].Write
= 1;
131 if (Entry
+(KSEG0_BASE
>> 22) > 1023)
133 TRACE("WARNING! Entry: %X > 1023\n", Entry
+(KSEG0_BASE
>> 22));
136 // Kernel-mode mapping
137 *KernelPT
= (PHARDWARE_PTE
)&KernelPageTablesBuffer
[KernelPageTables
*MM_PAGE_SIZE
];
140 PDE
[Entry
+(KSEG0_BASE
>> 22)].PageFrameNumber
= ((ULONG
)*KernelPT
>> MM_PAGE_SHIFT
);
141 PDE
[Entry
+(KSEG0_BASE
>> 22)].Valid
= 1;
142 PDE
[Entry
+(KSEG0_BASE
>> 22)].Write
= 1;
146 MempSetupPaging(IN PFN_NUMBER StartPage
,
147 IN PFN_COUNT NumberOfPages
,
148 IN BOOLEAN KernelMapping
)
150 PHARDWARE_PTE PhysicalPT
;
151 PHARDWARE_PTE KernelPT
;
152 PFN_COUNT Entry
, Page
;
154 TRACE("MempSetupPaging: SP 0x%X, Number: 0x%X, Kernel: %s\n",
155 StartPage
, NumberOfPages
, KernelMapping
? "yes" : "no");
158 if (StartPage
+NumberOfPages
>= 0x80000)
161 // We can't map this as it requires more than 1 PDE
162 // and in fact it's not possible at all ;)
164 //Print(L"skipping...\n");
169 // Now actually set up the page tables for identity mapping
171 for (Page
= StartPage
; Page
< StartPage
+ NumberOfPages
; Page
++)
175 if (((PULONG
)PDE
)[Entry
] == 0)
177 MempAllocatePTE(Entry
, &PhysicalPT
, &KernelPT
);
181 PhysicalPT
= (PHARDWARE_PTE
)(PDE
[Entry
].PageFrameNumber
<< MM_PAGE_SHIFT
);
182 KernelPT
= (PHARDWARE_PTE
)(PDE
[Entry
+(KSEG0_BASE
>> 22)].PageFrameNumber
<< MM_PAGE_SHIFT
);
185 PhysicalPT
[Page
& 0x3ff].PageFrameNumber
= Page
;
186 PhysicalPT
[Page
& 0x3ff].Valid
= (Page
!= 0);
187 PhysicalPT
[Page
& 0x3ff].Write
= (Page
!= 0);
191 if (KernelPT
[Page
& 0x3ff].Valid
) WARN("xxx already mapped \n");
192 KernelPT
[Page
& 0x3ff].PageFrameNumber
= Page
;
193 KernelPT
[Page
& 0x3ff].Valid
= (Page
!= 0);
194 KernelPT
[Page
& 0x3ff].Write
= (Page
!= 0);
202 MempUnmapPage(PFN_NUMBER Page
)
204 PHARDWARE_PTE KernelPT
;
205 PFN_NUMBER Entry
= (Page
>> 10) + (KSEG0_BASE
>> 22);
207 /* Don't unmap hyperspace or HAL entries */
208 if (Entry
== HYPER_SPACE_ENTRY
|| Entry
== 1023)
211 if (PDE
[Entry
].Valid
)
213 KernelPT
= (PHARDWARE_PTE
)(PDE
[Entry
].PageFrameNumber
<< MM_PAGE_SHIFT
);
217 KernelPT
[Page
& 0x3ff].PageFrameNumber
= 0;
218 KernelPT
[Page
& 0x3ff].Valid
= 0;
219 KernelPT
[Page
& 0x3ff].Write
= 0;
228 LARGE_INTEGER MsrValue
;
229 ULONG APICAddress
, CpuInfo
[4];
231 /* Check if we have a local APIC */
232 __cpuid((int*)CpuInfo
, 1);
233 LocalAPIC
= (((CpuInfo
[3] >> 9) & 1) != 0);
235 /* If there is no APIC, just return */
239 /* Read the APIC Address */
240 MsrValue
.QuadPart
= __readmsr(0x1B);
241 APICAddress
= (MsrValue
.LowPart
& 0xFFFFF000);
243 TRACE("Local APIC detected at address 0x%x\n",
247 HalPageTable
[(APIC_BASE
- 0xFFC00000) >> MM_PAGE_SHIFT
].PageFrameNumber
248 = APICAddress
>> MM_PAGE_SHIFT
;
249 HalPageTable
[(APIC_BASE
- 0xFFC00000) >> MM_PAGE_SHIFT
].Valid
= 1;
250 HalPageTable
[(APIC_BASE
- 0xFFC00000) >> MM_PAGE_SHIFT
].Write
= 1;
251 HalPageTable
[(APIC_BASE
- 0xFFC00000) >> MM_PAGE_SHIFT
].WriteThrough
= 1;
252 HalPageTable
[(APIC_BASE
- 0xFFC00000) >> MM_PAGE_SHIFT
].CacheDisable
= 1;
256 WinLdrMapSpecialPages(void)
259 //VideoDisplayString(L"Hello from VGA, going into the kernel\n");
260 TRACE("HalPageTable: 0x%X\n", HalPageTable
);
262 // Page Tables have been setup, make special handling for PCR and TSS
263 // (which is done in BlSetupFotNt in usual ntldr)
264 HalPageTable
[(KI_USER_SHARED_DATA
- 0xFFC00000) >> MM_PAGE_SHIFT
].PageFrameNumber
= PcrBasePage
+1;
265 HalPageTable
[(KI_USER_SHARED_DATA
- 0xFFC00000) >> MM_PAGE_SHIFT
].Valid
= 1;
266 HalPageTable
[(KI_USER_SHARED_DATA
- 0xFFC00000) >> MM_PAGE_SHIFT
].Write
= 1;
268 HalPageTable
[(KIP0PCRADDRESS
- 0xFFC00000) >> MM_PAGE_SHIFT
].PageFrameNumber
= PcrBasePage
;
269 HalPageTable
[(KIP0PCRADDRESS
- 0xFFC00000) >> MM_PAGE_SHIFT
].Valid
= 1;
270 HalPageTable
[(KIP0PCRADDRESS
- 0xFFC00000) >> MM_PAGE_SHIFT
].Write
= 1;
276 //VideoMemoryBase = MmMapIoSpace(0xb8000, 4000, MmNonCached);
277 //TRACE("VideoMemoryBase: 0x%X\n", VideoMemoryBase);
282 #define ExtendedBIOSDataArea ((PULONG)0x740)
283 #define ExtendedBIOSDataSize ((PULONG)0x744)
284 #define RomFontPointers ((PULONG)0x700)
290 ROM_8x14CharacterFont
= 0x02,
291 ROM_8x8DoubleDotFontLo
= 0x03,
292 ROM_8x8DoubleDotFontHi
= 0x04,
293 ROM_AlphaAlternate
= 0x05,
295 ROM_Alternate9x16Font
= 0x07,
296 UltraVision_8x20Font
= 0x11,
297 UltraVision_8x10Font
= 0x12,
300 void WinLdrSetupSpecialDataPointers()
304 /* Get the address of the bios rom fonts. Win 2003 videoprt reads these
305 values from address 0x700 .. 0x718 and store them in the registry
306 in HKLM\System\CurrentControlSet\Control\Wow\RomFontPointers
307 Int 10h, AX=1130h, BH = pointer specifier
308 returns: es:bp = address */
309 BiosRegs
.d
.eax
= 0x1130;
310 BiosRegs
.b
.bh
= ROM_8x14CharacterFont
;
311 Int386(0x10, &BiosRegs
, &BiosRegs
);
312 RomFontPointers
[0] = BiosRegs
.w
.es
<< 4 | BiosRegs
.w
.bp
;
314 BiosRegs
.b
.bh
= ROM_8x8DoubleDotFontLo
;
315 Int386(0x10, &BiosRegs
, &BiosRegs
);
316 RomFontPointers
[1] = BiosRegs
.w
.es
<< 16 | BiosRegs
.w
.bp
;
318 BiosRegs
.b
.bh
= ROM_8x8DoubleDotFontHi
;
319 Int386(0x10, &BiosRegs
, &BiosRegs
);
320 RomFontPointers
[2] = BiosRegs
.w
.es
<< 16 | BiosRegs
.w
.bp
;
322 BiosRegs
.b
.bh
= ROM_AlphaAlternate
;
323 Int386(0x10, &BiosRegs
, &BiosRegs
);
324 RomFontPointers
[3] = BiosRegs
.w
.es
<< 16 | BiosRegs
.w
.bp
;
326 BiosRegs
.b
.bh
= ROM_8x16Font
;
327 Int386(0x10, &BiosRegs
, &BiosRegs
);
328 RomFontPointers
[4] = BiosRegs
.w
.es
<< 16 | BiosRegs
.w
.bp
;
330 BiosRegs
.b
.bh
= ROM_Alternate9x16Font
;
331 Int386(0x10, &BiosRegs
, &BiosRegs
);
332 RomFontPointers
[5] = BiosRegs
.w
.es
<< 16 | BiosRegs
.w
.bp
;
334 /* Store address of the extended bios data area in 0x740 */
335 BiosRegs
.d
.eax
= 0xC100;
336 Int386(0x15, &BiosRegs
, &BiosRegs
);
337 if (INT386_SUCCESS(BiosRegs
))
339 *ExtendedBIOSDataArea
= BiosRegs
.w
.es
<< 4;
340 *ExtendedBIOSDataSize
= 1024;
341 TRACE("*ExtendedBIOSDataArea = 0x%lx\n", *ExtendedBIOSDataArea
);
345 WARN("Couldn't get address of extended BIOS data area\n");
346 *ExtendedBIOSDataArea
= 0;
347 *ExtendedBIOSDataSize
= 0;
351 void WinLdrSetupMachineDependent(PLOADER_PARAMETER_BLOCK LoaderBlock
)
357 ULONG BlockSize
, NumPages
;
359 LoaderBlock
->u
.I386
.CommonDataArea
= NULL
; // Force No ABIOS support
360 LoaderBlock
->u
.I386
.MachineType
= MACHINE_TYPE_ISA
;
362 /* Allocate 2 pages for PCR */
363 Pcr
= (ULONG_PTR
)MmAllocateMemoryWithType(2 * MM_PAGE_SIZE
, LoaderStartupPcrPage
);
364 PcrBasePage
= Pcr
>> MM_PAGE_SHIFT
;
368 UiMessageBox("Can't allocate PCR.");
373 TssSize
= (sizeof(KTSS
) + MM_PAGE_SIZE
) & ~(MM_PAGE_SIZE
- 1);
374 //TssPages = TssSize / MM_PAGE_SIZE;
376 Tss
= (ULONG_PTR
)MmAllocateMemoryWithType(TssSize
, LoaderMemoryData
);
378 TssBasePage
= Tss
>> MM_PAGE_SHIFT
;
380 /* Allocate space for new GDT + IDT */
381 BlockSize
= NUM_GDT
*sizeof(KGDTENTRY
) + NUM_IDT
*sizeof(KIDTENTRY
);//FIXME: Use GDT/IDT limits here?
382 NumPages
= (BlockSize
+ MM_PAGE_SIZE
- 1) >> MM_PAGE_SHIFT
;
383 GdtIdt
= (PKGDTENTRY
)MmAllocateMemoryWithType(NumPages
* MM_PAGE_SIZE
, LoaderMemoryData
);
387 UiMessageBox("Can't allocate pages for GDT+IDT!");
391 /* Zero newly prepared GDT+IDT */
392 RtlZeroMemory(GdtIdt
, NumPages
<< MM_PAGE_SHIFT
);
394 // Before we start mapping pages, create a block of memory, which will contain
396 if (MempAllocatePageTables() == FALSE
)
398 BugCheck("MempAllocatePageTables failed!\n");
401 /* Map stuff like PCR, KI_USER_SHARED_DATA and Apic */
402 WinLdrMapSpecialPages();
404 /* Set some special fields */
405 WinLdrSetupSpecialDataPointers();
410 WinLdrSetProcessorContext(void)
412 GDTIDT GdtDesc
, IdtDesc
, OldIdt
;
420 Pcr
= KIP0PCRADDRESS
;
421 Tss
= KSEG0_BASE
| (TssBasePage
<< MM_PAGE_SHIFT
);
423 TRACE("GDtIdt %p, Pcr %p, Tss 0x%08X\n",
427 //BS->ExitBootServices(ImageHandle,MapKey);
429 // Disable Interrupts
432 // Re-initialize EFLAGS
436 __writecr3((ULONG_PTR
)PDE
);
438 // Enable paging by modifying CR0
439 __writecr0(__readcr0() | CR0_PG
);
441 // Kernel expects the PCR to be zero-filled on startup
442 // FIXME: Why zero it here when we can zero it right after allocation?
443 RtlZeroMemory((PVOID
)Pcr
, MM_PAGE_SIZE
); //FIXME: Why zero only 1 page when we allocate 2?
445 // Get old values of GDT and IDT
446 Ke386GetGlobalDescriptorTable(&GdtDesc
);
450 OldIdt
.Base
= IdtDesc
.Base
;
451 OldIdt
.Limit
= IdtDesc
.Limit
;
453 // Prepare new IDT+GDT
454 GdtDesc
.Base
= KSEG0_BASE
| (ULONG_PTR
)GdtIdt
;
455 GdtDesc
.Limit
= NUM_GDT
* sizeof(KGDTENTRY
) - 1;
456 IdtDesc
.Base
= (ULONG
)((PUCHAR
)GdtDesc
.Base
+ GdtDesc
.Limit
+ 1);
457 IdtDesc
.Limit
= NUM_IDT
* sizeof(KIDTENTRY
) - 1;
459 // ========================
460 // Fill all descriptors now
461 // ========================
463 pGdt
= (PKGDTENTRY
)GdtDesc
.Base
;
464 pIdt
= (PKIDTENTRY
)IdtDesc
.Base
;
467 // Code selector (0x8)
470 pGdt
[1].LimitLow
= 0xFFFF;
472 pGdt
[1].HighWord
.Bytes
.BaseMid
= 0;
473 pGdt
[1].HighWord
.Bytes
.Flags1
= 0x9A;
474 pGdt
[1].HighWord
.Bytes
.Flags2
= 0xCF;
475 pGdt
[1].HighWord
.Bytes
.BaseHi
= 0;
478 // Data selector (0x10)
481 pGdt
[2].LimitLow
= 0xFFFF;
483 pGdt
[2].HighWord
.Bytes
.BaseMid
= 0;
484 pGdt
[2].HighWord
.Bytes
.Flags1
= 0x92;
485 pGdt
[2].HighWord
.Bytes
.Flags2
= 0xCF;
486 pGdt
[2].HighWord
.Bytes
.BaseHi
= 0;
492 pGdt
[3].LimitLow
= 0xFFFF;
494 pGdt
[3].HighWord
.Bytes
.BaseMid
= 0;
495 pGdt
[3].HighWord
.Bytes
.Flags1
= 0xFA;
496 pGdt
[3].HighWord
.Bytes
.Flags2
= 0xCF;
497 pGdt
[3].HighWord
.Bytes
.BaseHi
= 0;
503 pGdt
[4].LimitLow
= 0xFFFF;
505 pGdt
[4].HighWord
.Bytes
.BaseMid
= 0;
506 pGdt
[4].HighWord
.Bytes
.Flags1
= 0xF2;
507 pGdt
[4].HighWord
.Bytes
.Flags2
= 0xCF;
508 pGdt
[4].HighWord
.Bytes
.BaseHi
= 0;
511 // TSS Selector (0x28)
513 pGdt
[5].LimitLow
= 0x78-1; //FIXME: Check this
514 pGdt
[5].BaseLow
= (USHORT
)(Tss
& 0xffff);
515 pGdt
[5].HighWord
.Bytes
.BaseMid
= (UCHAR
)((Tss
>> 16) & 0xff);
516 pGdt
[5].HighWord
.Bytes
.Flags1
= 0x89;
517 pGdt
[5].HighWord
.Bytes
.Flags2
= 0x00;
518 pGdt
[5].HighWord
.Bytes
.BaseHi
= (UCHAR
)((Tss
>> 24) & 0xff);
521 // PCR Selector (0x30)
523 pGdt
[6].LimitLow
= 0x01;
524 pGdt
[6].BaseLow
= (USHORT
)(Pcr
& 0xffff);
525 pGdt
[6].HighWord
.Bytes
.BaseMid
= (UCHAR
)((Pcr
>> 16) & 0xff);
526 pGdt
[6].HighWord
.Bytes
.Flags1
= 0x92;
527 pGdt
[6].HighWord
.Bytes
.Flags2
= 0xC0;
528 pGdt
[6].HighWord
.Bytes
.BaseHi
= (UCHAR
)((Pcr
>> 24) & 0xff);
533 pGdt
[7].LimitLow
= 0xFFFF;
535 pGdt
[7].HighWord
.Bytes
.BaseMid
= 0;
536 pGdt
[7].HighWord
.Bytes
.Flags1
= 0xF3;
537 pGdt
[7].HighWord
.Bytes
.Flags2
= 0x40;
538 pGdt
[7].HighWord
.Bytes
.BaseHi
= 0;
541 // Some BIOS stuff (0x40)
543 pGdt
[8].LimitLow
= 0xFFFF;
544 pGdt
[8].BaseLow
= 0x400;
545 pGdt
[8].HighWord
.Bytes
.BaseMid
= 0;
546 pGdt
[8].HighWord
.Bytes
.Flags1
= 0xF2;
547 pGdt
[8].HighWord
.Bytes
.Flags2
= 0x0;
548 pGdt
[8].HighWord
.Bytes
.BaseHi
= 0;
553 pGdt
[9].LimitLow
= 0;
555 pGdt
[9].HighWord
.Bytes
.BaseMid
= 0;
556 pGdt
[9].HighWord
.Bytes
.Flags1
= 0;
557 pGdt
[9].HighWord
.Bytes
.Flags2
= 0;
558 pGdt
[9].HighWord
.Bytes
.BaseHi
= 0;
563 pGdt
[10].LimitLow
= 0xFFFF; //FIXME: Not correct!
564 pGdt
[10].BaseLow
= 0;
565 pGdt
[10].HighWord
.Bytes
.BaseMid
= 0x2;
566 pGdt
[10].HighWord
.Bytes
.Flags1
= 0x89;
567 pGdt
[10].HighWord
.Bytes
.Flags2
= 0;
568 pGdt
[10].HighWord
.Bytes
.BaseHi
= 0;
573 pGdt
[11].LimitLow
= 0xFFFF;
574 pGdt
[11].BaseLow
= 0;
575 pGdt
[11].HighWord
.Bytes
.BaseMid
= 0x2;
576 pGdt
[11].HighWord
.Bytes
.Flags1
= 0x9A;
577 pGdt
[11].HighWord
.Bytes
.Flags2
= 0;
578 pGdt
[11].HighWord
.Bytes
.BaseHi
= 0;
583 pGdt
[12].LimitLow
= 0xFFFF;
584 pGdt
[12].BaseLow
= 0; //FIXME: Maybe not correct, but noone cares
585 pGdt
[12].HighWord
.Bytes
.BaseMid
= 0x2;
586 pGdt
[12].HighWord
.Bytes
.Flags1
= 0x92;
587 pGdt
[12].HighWord
.Bytes
.Flags2
= 0;
588 pGdt
[12].HighWord
.Bytes
.BaseHi
= 0;
591 // Video buffer Selector (0x68)
593 pGdt
[13].LimitLow
= 0x3FFF;
594 pGdt
[13].BaseLow
= 0x8000;
595 pGdt
[13].HighWord
.Bytes
.BaseMid
= 0x0B;
596 pGdt
[13].HighWord
.Bytes
.Flags1
= 0x92;
597 pGdt
[13].HighWord
.Bytes
.Flags2
= 0;
598 pGdt
[13].HighWord
.Bytes
.BaseHi
= 0;
601 // Points to GDT (0x70)
603 pGdt
[14].LimitLow
= NUM_GDT
*sizeof(KGDTENTRY
) - 1;
604 pGdt
[14].BaseLow
= 0x7000;
605 pGdt
[14].HighWord
.Bytes
.BaseMid
= 0xFF;
606 pGdt
[14].HighWord
.Bytes
.Flags1
= 0x92;
607 pGdt
[14].HighWord
.Bytes
.Flags2
= 0;
608 pGdt
[14].HighWord
.Bytes
.BaseHi
= 0xFF;
611 // Some unused descriptors should go here
615 RtlCopyMemory(pIdt
, (PVOID
)OldIdt
.Base
, OldIdt
.Limit
+ 1);
618 //asm("cli\n"); // they are already masked before enabling paged mode
621 Ke386SetGlobalDescriptorTable(&GdtDesc
);
624 // Jump to proper CS and clear prefetch queue
625 #if defined(__GNUC__)
626 asm("ljmp $0x08, $1f\n"
628 #elif defined(_MSC_VER)
629 /* We can't express the above in MASM so we use this far return instead */
642 Ke386SetSs(0x10); // DataSelector=0x10
644 // Set DS and ES selectors
646 Ke386SetEs(0x10); // this is vital for rep stosd
648 // LDT = not used ever, thus set to 0
649 Ke386SetLocalDescriptorTable(Ldt
);
652 Ke386SetTr(KGDT_TSS
);
660 // Real end of the function, just for information
675 ULONG
*PDE_Addr
=(ULONG
*)PDE
;//0xC0300000;
680 for (i
=0; i
<128; i
++)
682 TRACE("0x%04X | ", i
*8);
686 TRACE("0x%08X ", PDE_Addr
[i
*8+j
]);