ReactOS 0.4.15-dev-7918-g2a2556c
winldr.c File Reference
#include <freeldr.h>
#include <ndk/asm.h>
#include <internal/amd64/intrin_i.h>
#include "../../winldr.h"
#include <debug.h>
Include dependency graph for winldr.c:

Go to the source code of this file.

Functions

 DBG_DEFAULT_CHANNEL (WINDOWS)
 
static BOOLEAN MempAllocatePageTables (VOID)
 
static PHARDWARE_PTE MempGetOrCreatePageDir (PHARDWARE_PTE PdeBase, ULONG Index)
 
static BOOLEAN MempMapSinglePage (ULONG64 VirtualAddress, ULONG64 PhysicalAddress)
 
BOOLEAN MempIsPageMapped (PVOID VirtualAddress)
 
static PFN_NUMBER MempMapRangeOfPages (ULONG64 VirtualAddress, ULONG64 PhysicalAddress, PFN_NUMBER cPages)
 
BOOLEAN MempSetupPaging (IN PFN_NUMBER StartPage, IN PFN_NUMBER NumberOfPages, IN BOOLEAN KernelMapping)
 
VOID MempUnmapPage (PFN_NUMBER Page)
 
static VOID WinLdrpMapApic (VOID)
 
static BOOLEAN WinLdrMapSpecialPages (VOID)
 
static VOID Amd64SetupGdt (PVOID GdtBase, ULONG64 TssBase)
 
static VOID Amd64SetupIdt (PVOID IdtBase)
 
VOID WinLdrSetProcessorContext (void)
 
void WinLdrSetupMachineDependent (PLOADER_PARAMETER_BLOCK LoaderBlock)
 
VOID MempDump (VOID)
 

Variables

PHARDWARE_PTE PxeBase
 
PVOID GdtIdt
 
ULONG_PTR PcrBasePage
 
ULONG_PTR TssBasePage
 

Function Documentation

◆ Amd64SetupGdt()

static VOID Amd64SetupGdt ( PVOID  GdtBase,
ULONG64  TssBase 
)
static

Definition at line 277 of file winldr.c.

278{
280 KDESCRIPTOR GdtDesc;
281 TRACE("Amd64SetupGdt(GdtBase = %p, TssBase = %p)\n", GdtBase, TssBase);
282
283 /* Setup KGDT64_NULL */
284 Entry = KiGetGdtEntry(GdtBase, KGDT64_NULL);
285 *(PULONG64)Entry = 0x0000000000000000ULL;
286
287 /* Setup KGDT64_R0_CODE */
289 *(PULONG64)Entry = 0x00209b0000000000ULL;
290
291 /* Setup KGDT64_R0_DATA */
293 *(PULONG64)Entry = 0x00cf93000000ffffULL;
294
295 /* Setup KGDT64_R3_CMCODE */
297 *(PULONG64)Entry = 0x00cffb000000ffffULL;
298
299 /* Setup KGDT64_R3_DATA */
301 *(PULONG64)Entry = 0x00cff3000000ffffULL;
302
303 /* Setup KGDT64_R3_CODE */
305 *(PULONG64)Entry = 0x0020fb0000000000ULL;
306
307 /* Setup KGDT64_R3_CMTEB */
309 *(PULONG64)Entry = 0xff40f3fd50003c00ULL;
310
311 /* Setup TSS entry */
313 KiInitGdtEntry(Entry, TssBase, sizeof(KTSS), I386_TSS, 0);
314
315 /* Setup GDT descriptor */
316 GdtDesc.Base = GdtBase;
317 GdtDesc.Limit = NUM_GDT * sizeof(KGDTENTRY) - 1;
318
319 /* Set the new Gdt */
320 __lgdt(&GdtDesc.Limit);
321 TRACE("Leave Amd64SetupGdt()\n");
322}
FORCEINLINE PKGDTENTRY64 KiGetGdtEntry(PVOID pGdt, USHORT Selector)
Definition: intrin_i.h:13
FORCEINLINE VOID KiInitGdtEntry(PKGDTENTRY64 Entry, ULONG64 Base, ULONG Size, UCHAR Type, UCHAR Dpl)
Definition: intrin_i.h:48
unsigned __int64 * PULONG64
Definition: imports.h:198
#define KGDT64_SYS_TSS
Definition: ketypes.h:138
#define KGDT64_R3_CODE
Definition: ketypes.h:137
#define KGDT64_NULL
Definition: ketypes.h:132
#define I386_TSS
Definition: ketypes.h:121
#define KGDT64_R0_CODE
Definition: ketypes.h:133
#define KGDT64_R3_DATA
Definition: ketypes.h:136
#define KGDT64_R3_CMCODE
Definition: ketypes.h:135
#define KGDT64_R3_CMTEB
Definition: ketypes.h:139
#define KGDTENTRY
Definition: ketypes.h:507
#define KGDT64_R0_DATA
Definition: ketypes.h:134
#define NUM_GDT
Definition: winldr.h:16
#define TRACE(s)
Definition: solgame.cpp:4
base of all file and directory entries
Definition: entries.h:83
PVOID Base
Definition: ketypes.h:556
USHORT Limit
Definition: ketypes.h:555
Definition: ketypes.h:844

Referenced by WinLdrSetProcessorContext().

◆ Amd64SetupIdt()

static VOID Amd64SetupIdt ( PVOID  IdtBase)
static

Definition at line 326 of file winldr.c.

327{
328 KDESCRIPTOR IdtDesc, OldIdt;
329 //ULONG Size;
330 TRACE("Amd64SetupIdt(IdtBase = %p)\n", IdtBase);
331
332 /* Get old IDT */
333 __sidt(&OldIdt.Limit);
334
335 /* Copy the old IDT */
336 //Size = min(OldIdt.Limit + 1, NUM_IDT * sizeof(KIDTENTRY));
337 //RtlCopyMemory(IdtBase, (PVOID)OldIdt.Base, Size);
338
339 /* Setup the new IDT descriptor */
340 IdtDesc.Base = IdtBase;
341 IdtDesc.Limit = NUM_IDT * sizeof(KIDTENTRY) - 1;
342
343 /* Set the new IDT */
344 __lidt(&IdtDesc.Limit);
345 TRACE("Leave Amd64SetupIdt()\n");
346}
__INTRIN_INLINE void __lidt(void *Source)
Definition: intrin_x86.h:2018
__INTRIN_INLINE void __sidt(void *Destination)
Definition: intrin_x86.h:2023
#define KIDTENTRY
Definition: ketypes.h:549
#define NUM_IDT
Definition: winldr.h:17

Referenced by WinLdrSetProcessorContext().

◆ DBG_DEFAULT_CHANNEL()

DBG_DEFAULT_CHANNEL ( WINDOWS  )

◆ MempAllocatePageTables()

static BOOLEAN MempAllocatePageTables ( VOID  )
static

Definition at line 34 of file winldr.c.

35{
36 TRACE(">>> MempAllocatePageTables\n");
37
38 /* Allocate a page for the PML4 */
40 if (!PxeBase)
41 {
42 ERR("failed to allocate PML4\n");
43 return FALSE;
44 }
45
46 // FIXME: Physical PTEs = FirmwareTemporary ?
47
48 /* Zero the PML4 */
50
51 /* The page tables are located at 0xfffff68000000000
52 * We create a recursive self mapping through all 4 levels at
53 * virtual address 0xfffff6fb7dbedf68 */
57
58 // FIXME: map PDE's for hals memory mapping
59
60 TRACE(">>> leave MempAllocatePageTables\n");
61
62 return TRUE;
63}
#define VAtoPXI(va)
Definition: amd64.h:34
#define PtrToPfn(p)
Definition: amd64.h:31
PHARDWARE_PTE PxeBase
Definition: winldr.c:23
#define ERR(fmt,...)
Definition: debug.h:110
PVOID MmAllocateMemoryWithType(SIZE_T MemorySize, TYPE_OF_MEMORY MemoryType)
Definition: mm.c:31
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define PAGE_SIZE
Definition: env_spec_w32.h:49
@ LoaderMemoryData
Definition: arc.h:194
#define PXE_BASE
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

Referenced by WinLdrSetupMachineDependent().

◆ MempDump()

VOID MempDump ( VOID  )

Definition at line 430 of file winldr.c.

431{
432}

Referenced by WinLdrSetupMemoryLayout().

◆ MempGetOrCreatePageDir()

static PHARDWARE_PTE MempGetOrCreatePageDir ( PHARDWARE_PTE  PdeBase,
ULONG  Index 
)
static

Definition at line 67 of file winldr.c.

68{
70
71 if (!PdeBase)
72 return NULL;
73
74 if (!PdeBase[Index].Valid)
75 {
77 if (!SubDir)
78 return NULL;
81 PdeBase[Index].Valid = 1;
82 PdeBase[Index].Write = 1;
83 }
84 else
85 {
87 }
88 return SubDir;
89}
#define NULL
Definition: types.h:112
static const WCHAR SubDir[]
Definition: install.c:49
unsigned __int64 ULONG64
Definition: imports.h:198
void * PVOID
Definition: typedefs.h:50
_In_ WDFCOLLECTION _In_ ULONG Index

Referenced by MempMapSinglePage(), and WinLdrMapSpecialPages().

◆ MempIsPageMapped()

BOOLEAN MempIsPageMapped ( PVOID  VirtualAddress)

Definition at line 123 of file winldr.c.

124{
125 PHARDWARE_PTE PpeBase, PdeBase, PteBase;
126 ULONG Index;
127
129 if (!PxeBase[Index].Valid)
130 return FALSE;
131
134 if (!PpeBase[Index].Valid)
135 return FALSE;
136
137 PdeBase = (PVOID)((ULONG64)(PpeBase[Index].PageFrameNumber) * PAGE_SIZE);
139 if (!PdeBase[Index].Valid)
140 return FALSE;
141
142 PteBase = (PVOID)((ULONG64)(PdeBase[Index].PageFrameNumber) * PAGE_SIZE);
144 if (!PteBase[Index].Valid)
145 return FALSE;
146
147 return TRUE;
148}
#define VAtoPTI(va)
Definition: amd64.h:37
#define VAtoPPI(va)
Definition: amd64.h:35
#define VAtoPDI(va)
Definition: amd64.h:36
uint32_t ULONG
Definition: typedefs.h:59
_Must_inspect_result_ _In_ WDFDMATRANSACTION _In_ PFN_WDF_PROGRAM_DMA _In_ WDF_DMA_DIRECTION _In_ PMDL _In_ PVOID VirtualAddress

◆ MempMapRangeOfPages()

static PFN_NUMBER MempMapRangeOfPages ( ULONG64  VirtualAddress,
ULONG64  PhysicalAddress,
PFN_NUMBER  cPages 
)
static

Definition at line 152 of file winldr.c.

153{
155
156 for (i = 0; i < cPages; i++)
157 {
159 {
160 ERR("Failed to map page %ld from %p to %p\n",
162 return i;
163 }
166 }
167 return i;
168}
static BOOLEAN MempMapSinglePage(ULONG64 VirtualAddress, ULONG64 PhysicalAddress)
Definition: winldr.c:93
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
ULONG PFN_NUMBER
Definition: ke.h:9
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS PhysicalAddress
Definition: iotypes.h:1098

Referenced by MempSetupPaging().

◆ MempMapSinglePage()

static BOOLEAN MempMapSinglePage ( ULONG64  VirtualAddress,
ULONG64  PhysicalAddress 
)
static

Definition at line 93 of file winldr.c.

94{
95 PHARDWARE_PTE PpeBase, PdeBase, PteBase;
97
100 PteBase = MempGetOrCreatePageDir(PdeBase, VAtoPDI(VirtualAddress));
101
102 if (!PteBase)
103 {
104 ERR("!!!No Dir %p, %p, %p, %p\n", PxeBase, PpeBase, PdeBase, PteBase);
105 return FALSE;
106 }
107
109 if (PteBase[Index].Valid)
110 {
111 ERR("!!!Already mapped %ld\n", Index);
112 return FALSE;
113 }
114
115 PteBase[Index].Valid = 1;
116 PteBase[Index].Write = 1;
118
119 return TRUE;
120}
static PHARDWARE_PTE MempGetOrCreatePageDir(PHARDWARE_PTE PdeBase, ULONG Index)
Definition: winldr.c:67

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

◆ MempSetupPaging()

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

Definition at line 171 of file winldr.c.

174{
175 TRACE(">>> MempSetupPaging(0x%lx, %ld, %p)\n",
176 StartPage, NumberOfPages, StartPage * PAGE_SIZE + KSEG0_BASE);
177
178 /* Identity mapping */
181 NumberOfPages) != NumberOfPages)
182 {
183 ERR("Failed to map pages %ld, %ld\n",
184 StartPage, NumberOfPages);
185 return FALSE;
186 }
187
188 /* Kernel mapping */
189 if (KernelMapping)
190 {
193 NumberOfPages) != NumberOfPages)
194 {
195 ERR("Failed to map pages %ld, %ld\n",
196 StartPage, NumberOfPages);
197 return FALSE;
198 }
199 }
200
201 return TRUE;
202}
static PFN_NUMBER MempMapRangeOfPages(ULONG64 VirtualAddress, ULONG64 PhysicalAddress, PFN_NUMBER cPages)
Definition: winldr.c:152
#define KSEG0_BASE
Definition: ketypes.h:339
int WINAPI StartPage(_In_ HDC)

Referenced by MempSetupPagingForRegion(), and WinLdrSetupMemoryLayout().

◆ MempUnmapPage()

VOID MempUnmapPage ( PFN_NUMBER  Page)

Definition at line 205 of file winldr.c.

206{
207 // TRACE(">>> MempUnmapPage\n");
208}

◆ WinLdrMapSpecialPages()

static BOOLEAN WinLdrMapSpecialPages ( VOID  )
static

Definition at line 245 of file winldr.c.

246{
247 PHARDWARE_PTE PpeBase, PdeBase;
248
249 /* Map the PCR page */
251 {
252 ERR("Could not map PCR @ %lx\n", PcrBasePage);
253 return FALSE;
254 }
255
256 /* Map KI_USER_SHARED_DATA */
258 {
259 ERR("Could not map KI_USER_SHARED_DATA\n");
260 return FALSE;
261 }
262
263 /* Map the APIC page */
265
266 /* Map the page tables for 4 MB HAL address space. */
270 MempGetOrCreatePageDir(PdeBase, VAtoPDI(MM_HAL_VA_START + 2 * 1024 * 1024));
271
272 return TRUE;
273}
#define KIP0PCRADDRESS
Definition: amd64.h:27
static VOID WinLdrpMapApic(VOID)
Definition: winldr.c:212
ULONG_PTR PcrBasePage
Definition: winldr.c:27
#define MM_HAL_VA_START
Definition: ketypes.h:322
#define KI_USER_SHARED_DATA

◆ WinLdrpMapApic()

static VOID WinLdrpMapApic ( VOID  )
static

Definition at line 212 of file winldr.c.

213{
214 BOOLEAN LocalAPIC;
215 LARGE_INTEGER MsrValue;
216 ULONG CpuInfo[4];
217 ULONG64 APICAddress;
218
219 TRACE(">>> WinLdrpMapApic\n");
220
221 /* Check if we have a local APIC */
222 __cpuid((int*)CpuInfo, 1);
223 LocalAPIC = (((CpuInfo[3] >> 9) & 1) != 0);
224
225 /* If there is no APIC, just return */
226 if (!LocalAPIC)
227 {
228 WARN("No APIC found.\n");
229 return;
230 }
231
232 /* Read the APIC Address */
233 MsrValue.QuadPart = __readmsr(0x1B);
234 APICAddress = (MsrValue.LowPart & 0xFFFFF000);
235
236 TRACE("Local APIC detected at address 0x%x\n",
237 APICAddress);
238
239 /* Map it */
240 MempMapSinglePage(APIC_BASE, APICAddress);
241}
unsigned char BOOLEAN
#define WARN(fmt,...)
Definition: debug.h:112
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:324
LONGLONG QuadPart
Definition: typedefs.h:114
ULONG LowPart
Definition: typedefs.h:106

Referenced by WinLdrMapSpecialPages().

◆ WinLdrSetProcessorContext()

VOID WinLdrSetProcessorContext ( void  )

Definition at line 349 of file winldr.c.

350{
351 TRACE("WinLdrSetProcessorContext\n");
352
353 /* Disable Interrupts */
354 _disable();
355
356 /* Re-initialize EFLAGS */
357 __writeeflags(0);
358
359 /* Set the new PML4 */
361
362 /* Get kernel mode address of gdt / idt */
364
365 /* Create gdt entries and load gdtr */
366 Amd64SetupGdt(GdtIdt, KSEG0_BASE | (TssBasePage << MM_PAGE_SHIFT));
367
368 /* Copy old Idt and set idtr */
370
371 /* LDT is unused */
372// __lldt(0);
373
374 /* Load TSR */
375 __ltr(KGDT64_SYS_TSS);
376
377 TRACE("leave WinLdrSetProcessorContext\n");
378}
PVOID GdtIdt
Definition: winldr.c:26
ULONG_PTR TssBasePage
Definition: winldr.c:28
static VOID Amd64SetupGdt(PVOID GdtBase, ULONG64 TssBase)
Definition: winldr.c:277
static VOID Amd64SetupIdt(PVOID IdtBase)
Definition: winldr.c:326
void __cdecl _disable(void)
Definition: intrin_arm.h:365
__INTRIN_INLINE void __writeeflags(uintptr_t Value)
Definition: intrin_x86.h:1669
__INTRIN_INLINE void __writecr3(unsigned int Data)
Definition: intrin_x86.h:1794

Referenced by LoadAndBootWindowsCommon().

◆ WinLdrSetupMachineDependent()

void WinLdrSetupMachineDependent ( PLOADER_PARAMETER_BLOCK  LoaderBlock)

Definition at line 380 of file winldr.c.

381{
382 ULONG_PTR Pcr = 0;
383 ULONG_PTR Tss = 0;
384 ULONG BlockSize, NumPages;
385
386 LoaderBlock->u.I386.CommonDataArea = (PVOID)DbgPrint; // HACK
387 LoaderBlock->u.I386.MachineType = MACHINE_TYPE_ISA;
388
389 /* Allocate 2 pages for PCR */
391 PcrBasePage = Pcr >> MM_PAGE_SHIFT;
392 if (Pcr == 0)
393 {
394 UiMessageBox("Can't allocate PCR.");
395 return;
396 }
397 RtlZeroMemory((PVOID)Pcr, 2 * MM_PAGE_SIZE);
398
399 /* Allocate TSS */
400 BlockSize = (sizeof(KTSS) + MM_PAGE_SIZE) & ~(MM_PAGE_SIZE - 1);
402 TssBasePage = Tss >> MM_PAGE_SHIFT;
403
404 /* Allocate space for new GDT + IDT */
405 BlockSize = NUM_GDT * sizeof(KGDTENTRY) + NUM_IDT * sizeof(KIDTENTRY);
406 NumPages = (BlockSize + MM_PAGE_SIZE - 1) >> MM_PAGE_SHIFT;
407 GdtIdt = (PKGDTENTRY)MmAllocateMemoryWithType(NumPages * MM_PAGE_SIZE, LoaderMemoryData);
408 if (GdtIdt == NULL)
409 {
410 UiMessageBox("Can't allocate pages for GDT+IDT!");
411 return;
412 }
413
414 /* Zero newly prepared GDT+IDT */
415 RtlZeroMemory(GdtIdt, NumPages << MM_PAGE_SHIFT);
416
417 // Before we start mapping pages, create a block of memory, which will contain
418 // PDE and PTEs
420 {
421 // FIXME: bugcheck
422 }
423
424 /* Map stuff like PCR, KI_USER_SHARED_DATA and Apic */
426}
static BOOLEAN MempAllocatePageTables(VOID)
Definition: winldr.c:34
static BOOLEAN WinLdrMapSpecialPages(void)
Definition: winldr.c:320
VOID UiMessageBox(_In_ PCSTR Format,...)
Definition: ui.c:359
#define ULONG_PTR
Definition: config.h:101
#define DbgPrint
Definition: hal.h:12
#define KTSS
Definition: ketypes.h:991
#define PKGDTENTRY
Definition: ketypes.h:508
#define MACHINE_TYPE_ISA
Definition: ketypes.h:113
@ LoaderStartupPcrPage
Definition: arc.h:191
ULONG MachineType
Definition: arc.h:454
PVOID CommonDataArea
Definition: arc.h:453
union _LOADER_PARAMETER_BLOCK::@3379 u
I386_LOADER_BLOCK I386
Definition: arc.h:562
uint32_t ULONG_PTR
Definition: typedefs.h:65

Referenced by LoadAndBootWindowsCommon().

Variable Documentation

◆ GdtIdt

PVOID GdtIdt

Definition at line 26 of file winldr.c.

Referenced by WinLdrSetProcessorContext(), and WinLdrSetupMachineDependent().

◆ PcrBasePage

ULONG_PTR PcrBasePage

Definition at line 27 of file winldr.c.

Referenced by WinLdrMapSpecialPages(), and WinLdrSetupMachineDependent().

◆ PxeBase

◆ TssBasePage

ULONG_PTR TssBasePage

Definition at line 28 of file winldr.c.

Referenced by WinLdrSetProcessorContext(), and WinLdrSetupMachineDependent().