ReactOS 0.4.15-dev-6661-gcc6e444
winldr.c File Reference
#include <freeldr.h>
#include <ndk/asm.h>
#include "../../winldr.h"
#include <debug.h>
Include dependency graph for winldr.c:

Go to the source code of this file.

Classes

struct  GDTIDT
 

Macros

#define KIP0PCRADDRESS   0xffdff000
 
#define SELFMAP_ENTRY   0x300
 
#define DPL_SYSTEM   0
 
#define DPL_USER   3
 
#define TYPE_TSS16A   0x01
 
#define TYPE_LDT   0x02
 
#define TYPE_TSS16B   0x03
 
#define TYPE_CALL16   0x04
 
#define TYPE_TASK   0x05
 
#define TYPE_INT16   0x06
 
#define TYPE_TRAP16   0x07
 
#define TYPE_TSS32A   0x09
 
#define TYPE_TSS32B   0x0B
 
#define TYPE_CALL32   0x0C
 
#define TYPE_INT32   0x0E
 
#define TYPE_TRAP32   0x0F
 
#define DESCRIPTOR_ACCESSED   0x1
 
#define DESCRIPTOR_READ_WRITE   0x2
 
#define DESCRIPTOR_EXECUTE_READ   0x2
 
#define DESCRIPTOR_EXPAND_DOWN   0x4
 
#define DESCRIPTOR_CONFORMING   0x4
 
#define DESCRIPTOR_CODE   0x8
 
#define TYPE_CODE   (0x10 | DESCRIPTOR_CODE | DESCRIPTOR_EXECUTE_READ)
 
#define TYPE_DATA   (0x10 | DESCRIPTOR_READ_WRITE)
 
#define ExtendedBIOSDataArea   ((PULONG)0x740)
 
#define ExtendedBIOSDataSize   ((PULONG)0x744)
 
#define RomFontPointers   ((PULONG)0x700)
 

Functions

 DBG_DEFAULT_CHANNEL (WINDOWS)
 
FORCEINLINE PKGDTENTRY KiGetGdtEntry (IN PVOID pGdt, IN USHORT Selector)
 
FORCEINLINE VOID KiSetGdtDescriptorBase (IN OUT PKGDTENTRY Entry, IN ULONG32 Base)
 
FORCEINLINE VOID KiSetGdtDescriptorLimit (IN OUT PKGDTENTRY Entry, IN ULONG Limit)
 
VOID KiSetGdtEntryEx (IN OUT PKGDTENTRY Entry, IN ULONG32 Base, IN ULONG Limit, IN UCHAR Type, IN UCHAR Dpl, IN BOOLEAN Granularity, IN UCHAR SegMode)
 
FORCEINLINE VOID KiSetGdtEntry (IN OUT PKGDTENTRY Entry, IN ULONG32 Base, IN ULONG Limit, IN UCHAR Type, IN UCHAR Dpl, IN UCHAR SegMode)
 
static BOOLEAN MempAllocatePageTables (VOID)
 
static VOID MempAllocatePTE (ULONG Entry, PHARDWARE_PTE *PhysicalPT, PHARDWARE_PTE *KernelPT)
 
BOOLEAN MempSetupPaging (IN PFN_NUMBER StartPage, IN PFN_COUNT NumberOfPages, IN BOOLEAN KernelMapping)
 
VOID MempUnmapPage (PFN_NUMBER Page)
 
static VOID WinLdrpMapApic (VOID)
 
static BOOLEAN WinLdrMapSpecialPages (void)
 
static void WinLdrSetupSpecialDataPointers (VOID)
 
void WinLdrSetupMachineDependent (PLOADER_PARAMETER_BLOCK LoaderBlock)
 
VOID WinLdrSetProcessorContext (void)
 

Variables

PHARDWARE_PTE PDE
 
PHARDWARE_PTE HalPageTable
 
PUCHAR PhysicalPageTablesBuffer
 
PUCHAR KernelPageTablesBuffer
 
ULONG PhysicalPageTables
 
ULONG KernelPageTables
 
ULONG PcrBasePage
 
ULONG TssBasePage
 
PVOID GdtIdt
 

Macro Definition Documentation

◆ DESCRIPTOR_ACCESSED

#define DESCRIPTOR_ACCESSED   0x1

Definition at line 57 of file winldr.c.

◆ DESCRIPTOR_CODE

#define DESCRIPTOR_CODE   0x8

Definition at line 62 of file winldr.c.

◆ DESCRIPTOR_CONFORMING

#define DESCRIPTOR_CONFORMING   0x4

Definition at line 61 of file winldr.c.

◆ DESCRIPTOR_EXECUTE_READ

#define DESCRIPTOR_EXECUTE_READ   0x2

Definition at line 59 of file winldr.c.

◆ DESCRIPTOR_EXPAND_DOWN

#define DESCRIPTOR_EXPAND_DOWN   0x4

Definition at line 60 of file winldr.c.

◆ DESCRIPTOR_READ_WRITE

#define DESCRIPTOR_READ_WRITE   0x2

Definition at line 58 of file winldr.c.

◆ DPL_SYSTEM

#define DPL_SYSTEM   0

Definition at line 38 of file winldr.c.

◆ DPL_USER

#define DPL_USER   3

Definition at line 39 of file winldr.c.

◆ ExtendedBIOSDataArea

#define ExtendedBIOSDataArea   ((PULONG)0x740)

Definition at line 420 of file winldr.c.

◆ ExtendedBIOSDataSize

#define ExtendedBIOSDataSize   ((PULONG)0x744)

Definition at line 421 of file winldr.c.

◆ KIP0PCRADDRESS

#define KIP0PCRADDRESS   0xffdff000

Definition at line 20 of file winldr.c.

◆ RomFontPointers

#define RomFontPointers   ((PULONG)0x700)

Definition at line 422 of file winldr.c.

◆ SELFMAP_ENTRY

#define SELFMAP_ENTRY   0x300

Definition at line 22 of file winldr.c.

◆ TYPE_CALL16

#define TYPE_CALL16   0x04

Definition at line 44 of file winldr.c.

◆ TYPE_CALL32

#define TYPE_CALL32   0x0C

Definition at line 52 of file winldr.c.

◆ TYPE_CODE

#define TYPE_CODE   (0x10 | DESCRIPTOR_CODE | DESCRIPTOR_EXECUTE_READ)

Definition at line 64 of file winldr.c.

◆ TYPE_DATA

#define TYPE_DATA   (0x10 | DESCRIPTOR_READ_WRITE)

Definition at line 65 of file winldr.c.

◆ TYPE_INT16

#define TYPE_INT16   0x06

Definition at line 46 of file winldr.c.

◆ TYPE_INT32

#define TYPE_INT32   0x0E

Definition at line 54 of file winldr.c.

◆ TYPE_LDT

#define TYPE_LDT   0x02

Definition at line 42 of file winldr.c.

◆ TYPE_TASK

#define TYPE_TASK   0x05

Definition at line 45 of file winldr.c.

◆ TYPE_TRAP16

#define TYPE_TRAP16   0x07

Definition at line 47 of file winldr.c.

◆ TYPE_TRAP32

#define TYPE_TRAP32   0x0F

Definition at line 55 of file winldr.c.

◆ TYPE_TSS16A

#define TYPE_TSS16A   0x01

Definition at line 41 of file winldr.c.

◆ TYPE_TSS16B

#define TYPE_TSS16B   0x03

Definition at line 43 of file winldr.c.

◆ TYPE_TSS32A

#define TYPE_TSS32A   0x09

Definition at line 49 of file winldr.c.

◆ TYPE_TSS32B

#define TYPE_TSS32B   0x0B

Definition at line 51 of file winldr.c.

Function Documentation

◆ DBG_DEFAULT_CHANNEL()

DBG_DEFAULT_CHANNEL ( WINDOWS  )

◆ KiGetGdtEntry()

FORCEINLINE PKGDTENTRY KiGetGdtEntry ( IN PVOID  pGdt,
IN USHORT  Selector 
)

Definition at line 69 of file winldr.c.

72{
73 return (PKGDTENTRY)((ULONG_PTR)pGdt + (Selector & ~RPL_MASK));
74}
#define ULONG_PTR
Definition: config.h:101
#define RPL_MASK
Definition: ketypes.h:69

Referenced by Amd64SetupGdt(), KiInitializePcr(), KiInitializeTss(), and WinLdrSetProcessorContext().

◆ KiSetGdtDescriptorBase()

FORCEINLINE VOID KiSetGdtDescriptorBase ( IN OUT PKGDTENTRY  Entry,
IN ULONG32  Base 
)

Definition at line 78 of file winldr.c.

81{
82 Entry->BaseLow = (USHORT)(Base & 0xffff);
83 Entry->HighWord.Bytes.BaseMid = (UCHAR)((Base >> 16) & 0xff);
84 Entry->HighWord.Bytes.BaseHi = (UCHAR)((Base >> 24) & 0xff);
85 // Entry->BaseUpper = (ULONG)(Base >> 32);
86}
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2439
unsigned short USHORT
Definition: pedump.c:61
base of all file and directory entries
Definition: entries.h:83
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by KiSetGdtEntryEx().

◆ KiSetGdtDescriptorLimit()

FORCEINLINE VOID KiSetGdtDescriptorLimit ( IN OUT PKGDTENTRY  Entry,
IN ULONG  Limit 
)

Definition at line 90 of file winldr.c.

93{
94 if (Limit < 0x100000)
95 {
96 Entry->HighWord.Bits.Granularity = 0;
97 }
98 else
99 {
100 Limit >>= 12;
101 Entry->HighWord.Bits.Granularity = 1;
102 }
103 Entry->LimitLow = (USHORT)(Limit & 0xffff);
104 Entry->HighWord.Bits.LimitHi = ((Limit >> 16) & 0x0f);
105}
_In_ LONG _In_ LONG Limit
Definition: kefuncs.h:318

Referenced by KiSetGdtEntryEx().

◆ KiSetGdtEntry()

FORCEINLINE VOID KiSetGdtEntry ( IN OUT PKGDTENTRY  Entry,
IN ULONG32  Base,
IN ULONG  Limit,
IN UCHAR  Type,
IN UCHAR  Dpl,
IN UCHAR  SegMode 
)

Definition at line 131 of file winldr.c.

138{
139 KiSetGdtEntryEx(Entry, Base, Limit, Type, Dpl, FALSE, SegMode);
140}
Type
Definition: Type.h:7
VOID KiSetGdtEntryEx(IN OUT PKGDTENTRY Entry, IN ULONG32 Base, IN ULONG Limit, IN UCHAR Type, IN UCHAR Dpl, IN BOOLEAN Granularity, IN UCHAR SegMode)
Definition: winldr.c:108
#define FALSE
Definition: types.h:117

Referenced by WinLdrSetProcessorContext().

◆ KiSetGdtEntryEx()

VOID KiSetGdtEntryEx ( IN OUT PKGDTENTRY  Entry,
IN ULONG32  Base,
IN ULONG  Limit,
IN UCHAR  Type,
IN UCHAR  Dpl,
IN BOOLEAN  Granularity,
IN UCHAR  SegMode 
)

Definition at line 108 of file winldr.c.

116{
119 Entry->HighWord.Bits.Type = (Type & 0x1f);
120 Entry->HighWord.Bits.Dpl = (Dpl & 0x3);
121 Entry->HighWord.Bits.Pres = (Type != 0); // Present, must be 1 when the GDT entry is valid.
122 Entry->HighWord.Bits.Sys = 0; // System
123 Entry->HighWord.Bits.Reserved_0 = 0; // LongMode = !!(SegMode & 1);
124 Entry->HighWord.Bits.Default_Big = !!(SegMode & 2);
125 Entry->HighWord.Bits.Granularity |= !!Granularity; // The flag may have been already set by KiSetGdtDescriptorLimit().
126 // Entry->MustBeZero = 0;
127}
FORCEINLINE VOID KiSetGdtDescriptorBase(IN OUT PKGDTENTRY Entry, IN ULONG32 Base)
Definition: winldr.c:78
FORCEINLINE VOID KiSetGdtDescriptorLimit(IN OUT PKGDTENTRY Entry, IN ULONG Limit)
Definition: winldr.c:90

Referenced by KiSetGdtEntry(), and WinLdrSetProcessorContext().

◆ MempAllocatePageTables()

static BOOLEAN MempAllocatePageTables ( VOID  )
static

Definition at line 185 of file winldr.c.

186{
187 ULONG NumPageTables, TotalSize;
189 // It's better to allocate PDE + PTEs contiguous
190
191 // Max number of entries = MaxPageNum >> 10
192 // FIXME: This is a number to describe ALL physical memory
193 // and windows doesn't expect ALL memory mapped...
194 NumPageTables = TotalPagesInLookupTable >> 10;
195
196 TRACE("NumPageTables = %d\n", NumPageTables);
197
198 // Allocate memory block for all these things:
199 // PDE, HAL mapping page table, physical mapping, kernel mapping
200 TotalSize = (1 + 1 + NumPageTables * 2) * MM_PAGE_SIZE;
201
202 // PDE+HAL+KernelPTEs == MemoryData
204
205 // Physical PTEs = FirmwareTemporary
206 PhysicalPageTablesBuffer = (PUCHAR)Buffer + TotalSize - NumPageTables*MM_PAGE_SIZE;
208 NumPageTables*MM_PAGE_SIZE,
210
211 // This check is now redundant
212 if (Buffer + (TotalSize - NumPageTables*MM_PAGE_SIZE) !=
214 {
215 TRACE("There was a problem allocating two adjacent blocks of memory!\n");
216 }
217
219 {
220 UiMessageBox("Impossible to allocate memory block for page tables!");
221 return FALSE;
222 }
223
224 // Zero all this memory block
225 RtlZeroMemory(Buffer, TotalSize);
226
227 // Set up pointers correctly now
229
230 // Map the page directory at 0xC0000000 (maps itself)
231 PDE[SELFMAP_ENTRY].PageFrameNumber = (ULONG)PDE >> MM_PAGE_SHIFT;
234
235 // The last PDE slot is allocated for HAL's memory mapping (Virtual Addresses 0xFFC00000 - 0xFFFFFFFF)
236 HalPageTable = (PHARDWARE_PTE)&Buffer[MM_PAGE_SIZE*1];
237
238 // Map it
239 PDE[1023].PageFrameNumber = (ULONG)HalPageTable >> MM_PAGE_SHIFT;
240 PDE[1023].Valid = 1;
241 PDE[1023].Write = 1;
242
243 // Store pointer to the table for easier access
244 KernelPageTablesBuffer = &Buffer[MM_PAGE_SIZE*2];
245
246 // Zero counters of page tables used
249
250 return TRUE;
251}
PUCHAR KernelPageTablesBuffer
Definition: winldr.c:173
#define SELFMAP_ENTRY
Definition: winldr.c:22
PHARDWARE_PTE PDE
Definition: winldr.c:169
ULONG KernelPageTables
Definition: winldr.c:175
PUCHAR PhysicalPageTablesBuffer
Definition: winldr.c:172
PHARDWARE_PTE HalPageTable
Definition: winldr.c:170
ULONG PhysicalPageTables
Definition: winldr.c:174
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 PHARDWARE_PTE
Definition: mmtypes.h:187
@ LoaderMemoryData
Definition: arc.h:194
@ LoaderFirmwareTemporary
Definition: arc.h:179
#define TRACE(s)
Definition: solgame.cpp:4
ULONG64 PageFrameNumber
Definition: mmtypes.h:78
ULONG64 Write
Definition: mmtypes.h:67
ULONG64 Valid
Definition: mmtypes.h:66
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
VOID UiMessageBox(PCSTR Format,...)
Definition: ui.c:357

◆ MempAllocatePTE()

static VOID MempAllocatePTE ( ULONG  Entry,
PHARDWARE_PTE PhysicalPT,
PHARDWARE_PTE KernelPT 
)
static

Definition at line 255 of file winldr.c.

256{
257 //TRACE("Creating PDE Entry %X\n", Entry);
258
259 // Identity mapping
260 *PhysicalPT = (PHARDWARE_PTE)&PhysicalPageTablesBuffer[PhysicalPageTables*MM_PAGE_SIZE];
262
263 PDE[Entry].PageFrameNumber = (ULONG)*PhysicalPT >> MM_PAGE_SHIFT;
264 PDE[Entry].Valid = 1;
265 PDE[Entry].Write = 1;
266
267 if (Entry+(KSEG0_BASE >> 22) > 1023)
268 {
269 TRACE("WARNING! Entry: %X > 1023\n", Entry+(KSEG0_BASE >> 22));
270 }
271
272 // Kernel-mode mapping
273 *KernelPT = (PHARDWARE_PTE)&KernelPageTablesBuffer[KernelPageTables*MM_PAGE_SIZE];
275
276 PDE[Entry+(KSEG0_BASE >> 22)].PageFrameNumber = ((ULONG)*KernelPT >> MM_PAGE_SHIFT);
277 PDE[Entry+(KSEG0_BASE >> 22)].Valid = 1;
278 PDE[Entry+(KSEG0_BASE >> 22)].Write = 1;
279}
#define KSEG0_BASE
Definition: ketypes.h:278
static BOOL Write(PBYTE Address, PBYTE Data, SIZE_T Size)
Definition: vmhorizon.c:15

Referenced by MempSetupPaging().

◆ MempSetupPaging()

BOOLEAN MempSetupPaging ( IN PFN_NUMBER  StartPage,
IN PFN_COUNT  NumberOfPages,
IN BOOLEAN  KernelMapping 
)

Definition at line 282 of file winldr.c.

285{
286 PHARDWARE_PTE PhysicalPT;
287 PHARDWARE_PTE KernelPT;
289
290 TRACE("MempSetupPaging: SP 0x%X, Number: 0x%X, Kernel: %s\n",
291 StartPage, NumberOfPages, KernelMapping ? "yes" : "no");
292
293 // HACK
294 if (StartPage+NumberOfPages >= 0x80000)
295 {
296 //
297 // We cannot map this as it requires more than 1 PDE
298 // and in fact it's not possible at all ;)
299 //
300 //TRACE("skipping...\n");
301 return TRUE;
302 }
303
304 //
305 // Now actually set up the page tables for identity mapping
306 //
307 for (Page = StartPage; Page < StartPage + NumberOfPages; Page++)
308 {
309 Entry = Page >> 10;
310
311 if (((PULONG)PDE)[Entry] == 0)
312 {
313 MempAllocatePTE(Entry, &PhysicalPT, &KernelPT);
314 }
315 else
316 {
317 PhysicalPT = (PHARDWARE_PTE)(PDE[Entry].PageFrameNumber << MM_PAGE_SHIFT);
318 KernelPT = (PHARDWARE_PTE)(PDE[Entry+(KSEG0_BASE >> 22)].PageFrameNumber << MM_PAGE_SHIFT);
319 }
320
321 PhysicalPT[Page & 0x3ff].PageFrameNumber = Page;
322 PhysicalPT[Page & 0x3ff].Valid = (Page != 0);
323 PhysicalPT[Page & 0x3ff].Write = (Page != 0);
324
325 if (KernelMapping)
326 {
327 if (KernelPT[Page & 0x3ff].Valid) WARN("KernelPT already mapped\n");
328 KernelPT[Page & 0x3ff].PageFrameNumber = Page;
329 KernelPT[Page & 0x3ff].Valid = (Page != 0);
330 KernelPT[Page & 0x3ff].Write = (Page != 0);
331 }
332 }
333
334 return TRUE;
335}
static VOID MempAllocatePTE(ULONG Entry, PHARDWARE_PTE *PhysicalPT, PHARDWARE_PTE *KernelPT)
Definition: winldr.c:255
#define WARN(fmt,...)
Definition: debug.h:112
_In_ PVOID _Out_opt_ BOOLEAN _Out_opt_ PPFN_NUMBER Page
Definition: mm.h:1306
uint32_t * PULONG
Definition: typedefs.h:59
int WINAPI StartPage(_In_ HDC)
ULONG PFN_COUNT
Definition: mmtypes.h:102

◆ MempUnmapPage()

VOID MempUnmapPage ( PFN_NUMBER  Page)

Definition at line 338 of file winldr.c.

339{
340 PHARDWARE_PTE KernelPT;
341 PFN_NUMBER Entry = (Page >> 10) + (KSEG0_BASE >> 22);
342
343 /* Don't unmap page directory or HAL entries */
344 if (Entry == SELFMAP_ENTRY || Entry == 1023)
345 return;
346
347 if (PDE[Entry].Valid)
348 {
349 KernelPT = (PHARDWARE_PTE)(PDE[Entry].PageFrameNumber << MM_PAGE_SHIFT);
350
351 if (KernelPT)
352 {
353 KernelPT[Page & 0x3ff].PageFrameNumber = 0;
354 KernelPT[Page & 0x3ff].Valid = 0;
355 KernelPT[Page & 0x3ff].Write = 0;
356 }
357 }
358}
ULONG PFN_NUMBER
Definition: ke.h:9

◆ WinLdrMapSpecialPages()

static BOOLEAN WinLdrMapSpecialPages ( void  )
static

Definition at line 394 of file winldr.c.

395{
396 TRACE("HalPageTable: 0x%X\n", HalPageTable);
397
398 /*
399 * The Page Tables have been setup, make special handling
400 * for the boot processor PCR and KI_USER_SHARED_DATA.
401 */
402 HalPageTable[(KI_USER_SHARED_DATA - 0xFFC00000) >> MM_PAGE_SHIFT].PageFrameNumber = PcrBasePage+1;
403 HalPageTable[(KI_USER_SHARED_DATA - 0xFFC00000) >> MM_PAGE_SHIFT].Valid = 1;
404 HalPageTable[(KI_USER_SHARED_DATA - 0xFFC00000) >> MM_PAGE_SHIFT].Write = 1;
405
406 HalPageTable[(KIP0PCRADDRESS - 0xFFC00000) >> MM_PAGE_SHIFT].PageFrameNumber = PcrBasePage;
407 HalPageTable[(KIP0PCRADDRESS - 0xFFC00000) >> MM_PAGE_SHIFT].Valid = 1;
408 HalPageTable[(KIP0PCRADDRESS - 0xFFC00000) >> MM_PAGE_SHIFT].Write = 1;
409
410 /* Map APIC */
412
413 /* Map VGA memory */
414 //VideoMemoryBase = MmMapIoSpace(0xb8000, 4000, MmNonCached);
415 //TRACE("VideoMemoryBase: 0x%X\n", VideoMemoryBase);
416
417 return TRUE;
418}
#define KIP0PCRADDRESS
Definition: amd64.h:27
static VOID WinLdrpMapApic(VOID)
Definition: winldr.c:211
ULONG_PTR PcrBasePage
Definition: winldr.c:26
#define KI_USER_SHARED_DATA

Referenced by WinLdrSetupMachineDependent().

◆ WinLdrpMapApic()

static VOID WinLdrpMapApic ( VOID  )
static

Definition at line 362 of file winldr.c.

363{
364 BOOLEAN LocalAPIC;
365 LARGE_INTEGER MsrValue;
366 ULONG APICAddress, CpuInfo[4];
367
368 /* Check if we have a local APIC */
369 __cpuid((int*)CpuInfo, 1);
370 LocalAPIC = (((CpuInfo[3] >> 9) & 1) != 0);
371
372 /* If there is no APIC, just return */
373 if (!LocalAPIC)
374 return;
375
376 /* Read the APIC Address */
377 MsrValue.QuadPart = __readmsr(0x1B);
378 APICAddress = (MsrValue.LowPart & 0xFFFFF000);
379
380 TRACE("Local APIC detected at address 0x%x\n",
381 APICAddress);
382
383 /* Map it */
384 HalPageTable[(APIC_BASE - 0xFFC00000) >> MM_PAGE_SHIFT].PageFrameNumber
385 = APICAddress >> MM_PAGE_SHIFT;
386 HalPageTable[(APIC_BASE - 0xFFC00000) >> MM_PAGE_SHIFT].Valid = 1;
387 HalPageTable[(APIC_BASE - 0xFFC00000) >> MM_PAGE_SHIFT].Write = 1;
388 HalPageTable[(APIC_BASE - 0xFFC00000) >> MM_PAGE_SHIFT].WriteThrough = 1;
389 HalPageTable[(APIC_BASE - 0xFFC00000) >> MM_PAGE_SHIFT].CacheDisable = 1;
390}
unsigned char BOOLEAN
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
#define APIC_BASE
Definition: ketypes.h:263
LONGLONG QuadPart
Definition: typedefs.h:114
ULONG LowPart
Definition: typedefs.h:106

◆ WinLdrSetProcessorContext()

VOID WinLdrSetProcessorContext ( void  )

Definition at line 506 of file winldr.c.

507{
508 GDTIDT GdtDesc, IdtDesc, OldIdt;
509 PKGDTENTRY pGdt;
510 PKIDTENTRY pIdt;
511 USHORT Ldt = 0;
512 ULONG Pcr;
513 ULONG Tss;
514 //ULONG i;
515
516 Pcr = KIP0PCRADDRESS;
517 Tss = KSEG0_BASE | (TssBasePage << MM_PAGE_SHIFT);
518
519 TRACE("GdtIdt %p, Pcr %p, Tss 0x%08x\n",
520 GdtIdt, Pcr, Tss);
521
522 /* Enable paging */
523 //BS->ExitBootServices(ImageHandle,MapKey);
524
525 /* Disable Interrupts */
526 _disable();
527
528 /* Re-initialize EFLAGS */
529 __writeeflags(0);
530
531 /* Set the PDBR */
533
534 /* Enable paging by modifying CR0 */
536
537 /* The Kernel expects the boot processor PCR to be zero-filled on startup */
538 RtlZeroMemory((PVOID)Pcr, MM_PAGE_SIZE);
539
540 /* Get old values of GDT and IDT */
542 __sidt(&IdtDesc);
543
544 /* Save old IDT */
545 OldIdt.Base = IdtDesc.Base;
546 OldIdt.Limit = IdtDesc.Limit;
547
548 /* Prepare new IDT+GDT */
549 GdtDesc.Base = KSEG0_BASE | (ULONG_PTR)GdtIdt;
550 GdtDesc.Limit = NUM_GDT * sizeof(KGDTENTRY) - 1;
551 IdtDesc.Base = (ULONG)((PUCHAR)GdtDesc.Base + GdtDesc.Limit + 1);
552 IdtDesc.Limit = NUM_IDT * sizeof(KIDTENTRY) - 1;
553
554 // ========================
555 // Fill all descriptors now
556 // ========================
557
558 pGdt = (PKGDTENTRY)GdtDesc.Base;
559 pIdt = (PKIDTENTRY)IdtDesc.Base;
560
561 /* KGDT_NULL (0x00) Null Selector - Unused */
562 KiSetGdtEntry(KiGetGdtEntry(pGdt, KGDT_NULL), 0x0000, 0, 0, DPL_SYSTEM, 0);
563 // DumpGDTEntry(GdtDesc.Base, KGDT_NULL);
564
565 /* KGDT_R0_CODE (0x08) Ring 0 Code selector - Flat 4Gb */
566 KiSetGdtEntry(KiGetGdtEntry(pGdt, KGDT_R0_CODE), 0x0000, 0xFFFFFFFF,
568 // DumpGDTEntry(GdtDesc.Base, KGDT_R0_CODE);
569
570 /* KGDT_R0_DATA (0x10) Ring 0 Data selector - Flat 4Gb */
571 KiSetGdtEntry(KiGetGdtEntry(pGdt, KGDT_R0_DATA), 0x0000, 0xFFFFFFFF,
573 // DumpGDTEntry(GdtDesc.Base, KGDT_R0_DATA);
574
575 /* KGDT_R3_CODE (0x18) Ring 3 Code Selector - Flat 2Gb */
576 KiSetGdtEntry(KiGetGdtEntry(pGdt, KGDT_R3_CODE), 0x0000, 0xFFFFFFFF,
577 TYPE_CODE, DPL_USER, 2);
578 // DumpGDTEntry(GdtDesc.Base, KGDT_R3_CODE);
579
580 /* KGDT_R3_DATA (0x20) Ring 3 Data Selector - Flat 2Gb */
581 KiSetGdtEntry(KiGetGdtEntry(pGdt, KGDT_R3_DATA), 0x0000, 0xFFFFFFFF,
582 TYPE_DATA, DPL_USER, 2);
583 // DumpGDTEntry(GdtDesc.Base, KGDT_R3_DATA);
584
585 /* KGDT_TSS (0x28) TSS Selector (Ring 0) */
587 0x78-1 /* FIXME: Check this; would be sizeof(KTSS)-1 */,
589 // DumpGDTEntry(GdtDesc.Base, KGDT_TSS);
590
591 /*
592 * KGDT_R0_PCR (0x30) PCR Selector (Ring 0)
593 *
594 * IMPORTANT COMPATIBILITY NOTE:
595 * Windows <= Server 2003 sets a Base == KIP0PCRADDRESS (0xffdff000 on x86)
596 * with a Limit of 1 page (LimitLow == 1, Granularity == 1, that is interpreted
597 * as a "Limit" == 0x1fff but is incorrect, of course).
598 * On Windows Longhorn/Vista+ however, the Base is not hardcoded to KIP0PCRADDRESS
599 * and the limit is set in bytes (Granularity == 0):
600 * Longhorn/Vista reports LimitLow == 0x0fff == MM_PAGE_SIZE - 1, whereas
601 * Windows 7+ uses larger sizes there (not aligned on a page boundary).
602 */
603#if 1
604 /* Server 2003 way */
607#else
608 /* Vista+ way */
609 KiSetGdtEntry(KiGetGdtEntry(pGdt, KGDT_R0_PCR), (ULONG32)Pcr, MM_PAGE_SIZE - 1,
611#endif
612 // DumpGDTEntry(GdtDesc.Base, KGDT_R0_PCR);
613
614 /* KGDT_R3_TEB (0x38) Thread Environment Block Selector (Ring 3) */
615 KiSetGdtEntry(KiGetGdtEntry(pGdt, KGDT_R3_TEB), 0x0000, 0x0FFF,
617 // DumpGDTEntry(GdtDesc.Base, KGDT_R3_TEB);
618
619 /* KGDT_VDM_TILE (0x40) VDM BIOS Data Area Selector (Ring 3) */
620 KiSetGdtEntry(KiGetGdtEntry(pGdt, KGDT_VDM_TILE), 0x0400, 0xFFFF,
621 TYPE_DATA, DPL_USER, 0);
622 // DumpGDTEntry(GdtDesc.Base, KGDT_VDM_TILE);
623
624 /* KGDT_LDT (0x48) LDT Selector (Reserved) */
625 KiSetGdtEntry(KiGetGdtEntry(pGdt, KGDT_LDT), 0x0000, 0, 0, DPL_SYSTEM, 0);
626 // DumpGDTEntry(GdtDesc.Base, KGDT_LDT);
627
628 /* KGDT_DF_TSS (0x50) Double-Fault Task Switch Selector (Ring 0) */
629 KiSetGdtEntry(KiGetGdtEntry(pGdt, KGDT_DF_TSS), 0x20000 /* FIXME: Not correct! */,
630 0xFFFF /* FIXME: Not correct! */,
632 // DumpGDTEntry(GdtDesc.Base, KGDT_DF_TSS);
633
634 /* KGDT_NMI_TSS (0x58) NMI Task Switch Selector (Ring 0) */
635 KiSetGdtEntry(KiGetGdtEntry(pGdt, KGDT_NMI_TSS), 0x20000, 0xFFFF,
637 // DumpGDTEntry(GdtDesc.Base, KGDT_NMI_TSS);
638
639 /* Selector (0x60) - Unused (Reserved) on Windows Longhorn/Vista+ */
640 KiSetGdtEntry(KiGetGdtEntry(pGdt, 0x60), 0x20000 /* FIXME: Maybe not correct, but noone cares */,
641 0xFFFF, TYPE_DATA, DPL_SYSTEM, 0);
642 // DumpGDTEntry(GdtDesc.Base, 0x60);
643
644 /* Video Display Buffer Selector (0x68) - Unused (Reserved) on Windows Longhorn/Vista+ */
645 KiSetGdtEntry(KiGetGdtEntry(pGdt, 0x68), 0xB8000, 0x3FFF,
647 // DumpGDTEntry(GdtDesc.Base, 0x68);
648
649 /*
650 * GDT Alias Selector (points to GDT) (0x70)
651 *
652 * IMPORTANT COMPATIBILITY NOTE:
653 * The Base is not fixed to 0xFFFF7000 on Windows Longhorn/Vista+.
654 */
655 KiSetGdtEntry(KiGetGdtEntry(pGdt, 0x70), 0xFFFF7000 /* GdtDesc.Base ?? */, GdtDesc.Limit,
657 // DumpGDTEntry(GdtDesc.Base, 0x70);
658
659 /*
660 * Windows <= Server 2003 defines three additional unused but valid
661 * descriptors there, possibly for debugging purposes only.
662 * They are not present on Windows Longhorn/Vista+.
663 */
664 // KiSetGdtEntry(KiGetGdtEntry(pGdt, 0x78), 0x80400000, 0xffff, TYPE_CODE, DPL_SYSTEM, 0);
665 // KiSetGdtEntry(KiGetGdtEntry(pGdt, 0x80), 0x80400000, 0xffff, TYPE_DATA, DPL_SYSTEM, 0);
666 // KiSetGdtEntry(KiGetGdtEntry(pGdt, 0x88), 0x0000, 0, TYPE_DATA, DPL_SYSTEM, 0);
667
668 /* Copy the old IDT */
669 RtlCopyMemory(pIdt, (PVOID)OldIdt.Base, OldIdt.Limit + 1);
670
671 /* Mask interrupts */
672 //asm("cli\n"); // they are already masked before enabling paged mode
673
674 /* Load GDT+IDT */
676 __lidt(&IdtDesc);
677
678 /* Jump to proper CS and clear prefetch queue */
679#if defined(__GNUC__) || defined(__clang__)
680 asm("ljmp $0x08, $1f\n"
681 "1:\n");
682#elif defined(_MSC_VER)
683 /* We cannot express the above in MASM so we use this far return instead */
684 __asm
685 {
686 push 8
687 push offset resume
688 retf
689 resume:
690 };
691#else
692#error
693#endif
694
695 /* Set SS selector */
696 Ke386SetSs(KGDT_R0_DATA);
697
698 /* Set DS and ES selectors */
699 Ke386SetDs(KGDT_R0_DATA);
700 Ke386SetEs(KGDT_R0_DATA); // This is vital for rep stosd
701
702 /* LDT = not used ever, thus set to 0 */
703 Ke386SetLocalDescriptorTable(Ldt);
704
705 /* Load TSR */
706 Ke386SetTr(KGDT_TSS);
707
708 /* Clear GS */
709 Ke386SetGs(0);
710
711 /* Set FS to PCR */
712 Ke386SetFs(KGDT_R0_PCR);
713
714 // Real end of the function, just for information
715 /* do not uncomment!
716 pop edi;
717 pop esi;
718 pop ebx;
719 mov esp, ebp;
720 pop ebp;
721 ret
722 */
723}
PVOID GdtIdt
Definition: winldr.c:25
ULONG_PTR TssBasePage
Definition: winldr.c:27
#define TYPE_CODE
Definition: winldr.c:64
#define DPL_USER
Definition: winldr.c:39
FORCEINLINE VOID KiSetGdtEntry(IN OUT PKGDTENTRY Entry, IN ULONG32 Base, IN ULONG Limit, IN UCHAR Type, IN UCHAR Dpl, IN UCHAR SegMode)
Definition: winldr.c:131
#define TYPE_DATA
Definition: winldr.c:65
FORCEINLINE PKGDTENTRY KiGetGdtEntry(IN PVOID pGdt, IN USHORT Selector)
Definition: winldr.c:69
#define DPL_SYSTEM
Definition: winldr.c:38
#define DESCRIPTOR_ACCESSED
Definition: winldr.c:57
#define TYPE_TSS32A
Definition: winldr.c:49
unsigned int ULONG32
Definition: basetsd.h:125
GLintptr offset
Definition: glext.h:5920
#define Ke386GetGlobalDescriptorTable
Definition: intrin_i.h:376
#define Ke386SetGlobalDescriptorTable
Definition: intrin_i.h:377
void __cdecl _disable(void)
Definition: intrin_arm.h:365
__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:488
#define PKGDTENTRY
Definition: ketypes.h:447
#define KGDTENTRY
Definition: ketypes.h:446
#define KGDT_R3_DATA
Definition: ketypes.h:78
#define KGDT_R3_CODE
Definition: ketypes.h:77
#define KGDT_NMI_TSS
Definition: ketypes.h:85
#define KGDT_R3_TEB
Definition: ketypes.h:81
#define KGDT_TSS
Definition: ketypes.h:79
#define KGDT_R0_PCR
Definition: ketypes.h:80
#define KGDT_LDT
Definition: ketypes.h:83
#define KGDT_DF_TSS
Definition: ketypes.h:84
#define KGDT_R0_CODE
Definition: ketypes.h:75
#define KGDT_VDM_TILE
Definition: ketypes.h:82
#define KGDT_R0_DATA
Definition: ketypes.h:76
#define KGDT_NULL
Definition: ketypes.h:74
#define NUM_IDT
Definition: winldr.h:17
#define NUM_GDT
Definition: winldr.h:16
static void push(calc_node_t *op)
Definition: rpn_ieee.c:113
Definition: winldr.c:27
USHORT Limit
Definition: winldr.c:28
ULONG Base
Definition: winldr.c:29
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
uint32_t ULONG_PTR
Definition: typedefs.h:65

◆ WinLdrSetupMachineDependent()

void WinLdrSetupMachineDependent ( PLOADER_PARAMETER_BLOCK  LoaderBlock)

Definition at line 445 of file winldr.c.

446{
447 ULONG TssSize;
448 //ULONG TssPages;
449 ULONG_PTR Pcr = 0;
450 ULONG_PTR Tss = 0;
451 ULONG BlockSize, NumPages;
452
453 LoaderBlock->u.I386.CommonDataArea = NULL; // Force No ABIOS support
454 LoaderBlock->u.I386.MachineType = MACHINE_TYPE_ISA;
455
456 /* Allocate 2 pages for PCR: one for the boot processor PCR and one for KI_USER_SHARED_DATA */
458 PcrBasePage = Pcr >> MM_PAGE_SHIFT;
459 if (Pcr == 0)
460 {
461 UiMessageBox("Could not allocate PCR.");
462 return;
463 }
464
465 /* Allocate TSS */
466 TssSize = (sizeof(KTSS) + MM_PAGE_SIZE) & ~(MM_PAGE_SIZE - 1);
467 //TssPages = TssSize / MM_PAGE_SIZE;
468
470 TssBasePage = Tss >> MM_PAGE_SHIFT;
471 if (Tss == 0)
472 {
473 UiMessageBox("Could not allocate TSS.");
474 return;
475 }
476
477 /* Allocate space for new GDT + IDT */
478 BlockSize = NUM_GDT*sizeof(KGDTENTRY) + NUM_IDT*sizeof(KIDTENTRY);//FIXME: Use GDT/IDT limits here?
479 NumPages = (BlockSize + MM_PAGE_SIZE - 1) >> MM_PAGE_SHIFT;
480 GdtIdt = (PKGDTENTRY)MmAllocateMemoryWithType(NumPages * MM_PAGE_SIZE, LoaderMemoryData);
481 if (GdtIdt == NULL)
482 {
483 UiMessageBox("Could not allocate pages for GDT+IDT!");
484 return;
485 }
486
487 /* Zero newly prepared GDT+IDT */
488 RtlZeroMemory(GdtIdt, NumPages << MM_PAGE_SHIFT);
489
490 // Before we start mapping pages, create a block of memory, which will contain
491 // PDE and PTEs
493 {
494 BugCheck("MempAllocatePageTables failed!\n");
495 }
496
497 /* Map stuff like PCR, KI_USER_SHARED_DATA and Apic */
499
500 /* Set some special fields */
502}
static BOOLEAN MempAllocatePageTables(VOID)
Definition: winldr.c:33
static void WinLdrSetupSpecialDataPointers(VOID)
Definition: winldr.c:425
static BOOLEAN WinLdrMapSpecialPages(void)
Definition: winldr.c:394
#define BugCheck(fmt,...)
Definition: debug.h:118
#define KTSS
Definition: ketypes.h:929
#define MACHINE_TYPE_ISA
Definition: ketypes.h:52
@ LoaderStartupPcrPage
Definition: arc.h:191
ULONG MachineType
Definition: arc.h:454
PVOID CommonDataArea
Definition: arc.h:453
union _LOADER_PARAMETER_BLOCK::@3356 u
I386_LOADER_BLOCK I386
Definition: arc.h:562

◆ WinLdrSetupSpecialDataPointers()

static void WinLdrSetupSpecialDataPointers ( VOID  )
static

Definition at line 425 of file winldr.c.

426{
427 /* Get the address of the BIOS ROM fonts. Win 2003 videoprt reads these
428 values from address 0x700 .. 0x718 and store them in the registry
429 in HKLM\System\CurrentControlSet\Control\Wow\RomFontPointers */
431
432 /* Store address of the extended BIOS data area in 0x740 */
434
436 {
437 WARN("Couldn't get address of extended BIOS data area\n");
438 }
439 else
440 {
441 TRACE("*ExtendedBIOSDataArea = 0x%lx\n", *ExtendedBIOSDataArea);
442 }
443}
#define RomFontPointers
Definition: winldr.c:422
#define ExtendedBIOSDataArea
Definition: winldr.c:420
#define ExtendedBIOSDataSize
Definition: winldr.c:421
#define MachGetExtendedBIOSData(ExtendedBIOSDataArea, ExtendedBIOSDataSize)
Definition: machine.h:122
#define MachVideoGetFontsFromFirmware(RomFontPointers)
Definition: machine.h:100

Referenced by WinLdrSetupMachineDependent().

Variable Documentation

◆ GdtIdt

PVOID GdtIdt

Definition at line 179 of file winldr.c.

◆ HalPageTable

PHARDWARE_PTE HalPageTable

Definition at line 170 of file winldr.c.

Referenced by MempAllocatePageTables(), WinLdrMapSpecialPages(), and WinLdrpMapApic().

◆ KernelPageTables

ULONG KernelPageTables

Definition at line 175 of file winldr.c.

Referenced by MempAllocatePageTables(), and MempAllocatePTE().

◆ KernelPageTablesBuffer

PUCHAR KernelPageTablesBuffer

Definition at line 173 of file winldr.c.

Referenced by MempAllocatePageTables(), and MempAllocatePTE().

◆ PcrBasePage

ULONG PcrBasePage

Definition at line 177 of file winldr.c.

◆ PDE

◆ PhysicalPageTables

ULONG PhysicalPageTables

Definition at line 174 of file winldr.c.

Referenced by MempAllocatePageTables(), and MempAllocatePTE().

◆ PhysicalPageTablesBuffer

PUCHAR PhysicalPageTablesBuffer

Definition at line 172 of file winldr.c.

Referenced by MempAllocatePageTables(), and MempAllocatePTE().

◆ TssBasePage

ULONG TssBasePage

Definition at line 178 of file winldr.c.