ReactOS 0.4.15-dev-6656-gbbb33a6
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.

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 276 of file winldr.c.

277{
279 KDESCRIPTOR GdtDesc;
280 TRACE("Amd64SetupGdt(GdtBase = %p, TssBase = %p)\n", GdtBase, TssBase);
281
282 /* Setup KGDT64_NULL */
283 Entry = KiGetGdtEntry(GdtBase, KGDT64_NULL);
284 *(PULONG64)Entry = 0x0000000000000000ULL;
285
286 /* Setup KGDT64_R0_CODE */
288 *(PULONG64)Entry = 0x00209b0000000000ULL;
289
290 /* Setup KGDT64_R0_DATA */
292 *(PULONG64)Entry = 0x00cf93000000ffffULL;
293
294 /* Setup KGDT64_R3_CMCODE */
296 *(PULONG64)Entry = 0x00cffb000000ffffULL;
297
298 /* Setup KGDT64_R3_DATA */
300 *(PULONG64)Entry = 0x00cff3000000ffffULL;
301
302 /* Setup KGDT64_R3_CODE */
304 *(PULONG64)Entry = 0x0020fb0000000000ULL;
305
306 /* Setup KGDT64_R3_CMTEB */
308 *(PULONG64)Entry = 0xff40f3fd50003c00ULL;
309
310 /* Setup TSS entry */
312 KiInitGdtEntry(Entry, TssBase, sizeof(KTSS), I386_TSS, 0);
313
314 /* Setup GDT descriptor */
315 GdtDesc.Base = GdtBase;
316 GdtDesc.Limit = NUM_GDT * sizeof(KGDTENTRY) - 1;
317
318 /* Set the new Gdt */
319 __lgdt(&GdtDesc.Limit);
320 TRACE("Leave Amd64SetupGdt()\n");
321}
FORCEINLINE VOID KiInitGdtEntry(PKGDTENTRY64 Entry, ULONG64 Base, ULONG Size, UCHAR Type, UCHAR Dpl)
Definition: intrin_i.h:48
FORCEINLINE PKGDTENTRY KiGetGdtEntry(IN PVOID pGdt, IN USHORT Selector)
Definition: winldr.c:69
unsigned __int64 * PULONG64
Definition: imports.h:198
#define KGDT64_SYS_TSS
Definition: ketypes.h:77
#define KGDT64_R3_CODE
Definition: ketypes.h:76
#define KGDT64_NULL
Definition: ketypes.h:71
#define I386_TSS
Definition: ketypes.h:60
#define KGDT64_R0_CODE
Definition: ketypes.h:72
#define KGDT64_R3_DATA
Definition: ketypes.h:75
#define KGDT64_R3_CMCODE
Definition: ketypes.h:74
#define KGDT64_R3_CMTEB
Definition: ketypes.h:78
#define KGDTENTRY
Definition: ketypes.h:446
#define KGDT64_R0_DATA
Definition: ketypes.h:73
#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:495
USHORT Limit
Definition: ketypes.h:494
Definition: ketypes.h:791

Referenced by WinLdrSetProcessorContext().

◆ Amd64SetupIdt()

static VOID Amd64SetupIdt ( PVOID  IdtBase)
static

Definition at line 325 of file winldr.c.

326{
327 KDESCRIPTOR IdtDesc, OldIdt;
328 //ULONG Size;
329 TRACE("Amd64SetupIdt(IdtBase = %p)\n", IdtBase);
330
331 /* Get old IDT */
332 __sidt(&OldIdt.Limit);
333
334 /* Copy the old IDT */
335 //Size = min(OldIdt.Limit + 1, NUM_IDT * sizeof(KIDTENTRY));
336 //RtlCopyMemory(IdtBase, (PVOID)OldIdt.Base, Size);
337
338 /* Setup the new IDT descriptor */
339 IdtDesc.Base = IdtBase;
340 IdtDesc.Limit = NUM_IDT * sizeof(KIDTENTRY) - 1;
341
342 /* Set the new IDT */
343 __lidt(&IdtDesc.Limit);
344 TRACE("Leave Amd64SetupIdt()\n");
345}
__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:488
#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 33 of file winldr.c.

34{
35 TRACE(">>> MempAllocatePageTables\n");
36
37 /* Allocate a page for the PML4 */
39 if (!PxeBase)
40 {
41 ERR("failed to allocate PML4\n");
42 return FALSE;
43 }
44
45 // FIXME: Physical PTEs = FirmwareTemporary ?
46
47 /* Zero the PML4 */
49
50 /* The page tables are located at 0xfffff68000000000
51 * We create a recursive self mapping through all 4 levels at
52 * virtual address 0xfffff6fb7dbedf68 */
56
57 // FIXME: map PDE's for hals memory mapping
58
59 TRACE(">>> leave MempAllocatePageTables\n");
60
61 return TRUE;
62}
#define VAtoPXI(va)
Definition: amd64.h:34
#define PtrToPfn(p)
Definition: amd64.h:31
PHARDWARE_PTE PxeBase
Definition: winldr.c:22
#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 429 of file winldr.c.

430{
431}

Referenced by WinLdrSetupMemoryLayout().

◆ MempGetOrCreatePageDir()

static PHARDWARE_PTE MempGetOrCreatePageDir ( PHARDWARE_PTE  PdeBase,
ULONG  Index 
)
static

Definition at line 66 of file winldr.c.

67{
69
70 if (!PdeBase)
71 return NULL;
72
73 if (!PdeBase[Index].Valid)
74 {
76 if (!SubDir)
77 return NULL;
80 PdeBase[Index].Valid = 1;
81 PdeBase[Index].Write = 1;
82 }
83 else
84 {
86 }
87 return SubDir;
88}
#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 122 of file winldr.c.

123{
124 PHARDWARE_PTE PpeBase, PdeBase, PteBase;
125 ULONG Index;
126
128 if (!PxeBase[Index].Valid)
129 return FALSE;
130
133 if (!PpeBase[Index].Valid)
134 return FALSE;
135
136 PdeBase = (PVOID)((ULONG64)(PpeBase[Index].PageFrameNumber) * PAGE_SIZE);
138 if (!PdeBase[Index].Valid)
139 return FALSE;
140
141 PteBase = (PVOID)((ULONG64)(PdeBase[Index].PageFrameNumber) * PAGE_SIZE);
143 if (!PteBase[Index].Valid)
144 return FALSE;
145
146 return TRUE;
147}
#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 151 of file winldr.c.

152{
154
155 for (i = 0; i < cPages; i++)
156 {
158 {
159 ERR("Failed to map page %ld from %p to %p\n",
161 return i;
162 }
165 }
166 return i;
167}
static BOOLEAN MempMapSinglePage(ULONG64 VirtualAddress, ULONG64 PhysicalAddress)
Definition: winldr.c:92
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 92 of file winldr.c.

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

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

◆ MempSetupPaging()

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

Definition at line 170 of file winldr.c.

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

Referenced by MempSetupPagingForRegion(), and WinLdrSetupMemoryLayout().

◆ MempUnmapPage()

VOID MempUnmapPage ( PFN_NUMBER  Page)

Definition at line 204 of file winldr.c.

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

◆ WinLdrMapSpecialPages()

static BOOLEAN WinLdrMapSpecialPages ( VOID  )
static

Definition at line 244 of file winldr.c.

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

◆ WinLdrpMapApic()

static VOID WinLdrpMapApic ( VOID  )
static

Definition at line 211 of file winldr.c.

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

Referenced by WinLdrMapSpecialPages().

◆ WinLdrSetProcessorContext()

VOID WinLdrSetProcessorContext ( void  )

Definition at line 348 of file winldr.c.

349{
350 TRACE("WinLdrSetProcessorContext\n");
351
352 /* Disable Interrupts */
353 _disable();
354
355 /* Re-initialize EFLAGS */
356 __writeeflags(0);
357
358 /* Set the new PML4 */
360
361 /* Get kernel mode address of gdt / idt */
363
364 /* Create gdt entries and load gdtr */
365 Amd64SetupGdt(GdtIdt, KSEG0_BASE | (TssBasePage << MM_PAGE_SHIFT));
366
367 /* Copy old Idt and set idtr */
369
370 /* LDT is unused */
371// __lldt(0);
372
373 /* Load TSR */
374 __ltr(KGDT64_SYS_TSS);
375
376 TRACE("leave WinLdrSetProcessorContext\n");
377}
PVOID GdtIdt
Definition: winldr.c:25
ULONG_PTR TssBasePage
Definition: winldr.c:27
static VOID Amd64SetupGdt(PVOID GdtBase, ULONG64 TssBase)
Definition: winldr.c:276
static VOID Amd64SetupIdt(PVOID IdtBase)
Definition: winldr.c:325
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 379 of file winldr.c.

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

Referenced by LoadAndBootWindowsCommon().

Variable Documentation

◆ GdtIdt

PVOID GdtIdt

Definition at line 25 of file winldr.c.

Referenced by WinLdrSetProcessorContext(), and WinLdrSetupMachineDependent().

◆ PcrBasePage

ULONG_PTR PcrBasePage

Definition at line 26 of file winldr.c.

Referenced by WinLdrMapSpecialPages(), and WinLdrSetupMachineDependent().

◆ PxeBase

◆ TssBasePage

ULONG_PTR TssBasePage

Definition at line 27 of file winldr.c.

Referenced by WinLdrSetProcessorContext(), and WinLdrSetupMachineDependent().