ReactOS 0.4.16-dev-178-g8ba6102
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 (_In_ USHORT OperatingSystemVersion)
 
void WinLdrSetupMachineDependent (PLOADER_PARAMETER_BLOCK LoaderBlock)
 
VOID MempDump (VOID)
 

Variables

PHARDWARE_PTE PxeBase
 
PVOID GdtIdt
 
PFN_NUMBER SharedUserDataPfn
 
ULONG_PTR TssBasePage
 

Function Documentation

◆ Amd64SetupGdt()

static VOID Amd64SetupGdt ( PVOID  GdtBase,
ULONG64  TssBase 
)
static

Definition at line 270 of file winldr.c.

271{
273 KDESCRIPTOR GdtDesc;
274 TRACE("Amd64SetupGdt(GdtBase = %p, TssBase = %p)\n", GdtBase, TssBase);
275
276 /* Setup KGDT64_NULL */
277 Entry = KiGetGdtEntry(GdtBase, KGDT64_NULL);
278 *(PULONG64)Entry = 0x0000000000000000ULL;
279
280 /* Setup KGDT64_R0_CODE */
282 *(PULONG64)Entry = 0x00209b0000000000ULL;
283
284 /* Setup KGDT64_R0_DATA */
286 *(PULONG64)Entry = 0x00cf93000000ffffULL;
287
288 /* Setup KGDT64_R3_CMCODE */
290 *(PULONG64)Entry = 0x00cffb000000ffffULL;
291
292 /* Setup KGDT64_R3_DATA */
294 *(PULONG64)Entry = 0x00cff3000000ffffULL;
295
296 /* Setup KGDT64_R3_CODE */
298 *(PULONG64)Entry = 0x0020fb0000000000ULL;
299
300 /* Setup KGDT64_R3_CMTEB */
302 *(PULONG64)Entry = 0xff40f3fd50003c00ULL;
303
304 /* Setup TSS entry */
306 KiInitGdtEntry(Entry, TssBase, sizeof(KTSS), I386_TSS, 0);
307
308 /* Setup GDT descriptor */
309 GdtDesc.Base = GdtBase;
310 GdtDesc.Limit = NUM_GDT * sizeof(KGDTENTRY) - 1;
311
312 /* Set the new Gdt */
313 __lgdt(&GdtDesc.Limit);
314 TRACE("Leave Amd64SetupGdt()\n");
315}
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:127
#define KGDT64_R3_CODE
Definition: ketypes.h:126
#define KGDT64_NULL
Definition: ketypes.h:121
#define I386_TSS
Definition: ketypes.h:110
#define KGDT64_R0_CODE
Definition: ketypes.h:122
#define KGDT64_R3_DATA
Definition: ketypes.h:125
#define KGDT64_R3_CMCODE
Definition: ketypes.h:124
#define KGDT64_R3_CMTEB
Definition: ketypes.h:128
#define KGDTENTRY
Definition: ketypes.h:511
#define KGDT64_R0_DATA
Definition: ketypes.h:123
#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:560
USHORT Limit
Definition: ketypes.h:559
Definition: ketypes.h:844

Referenced by WinLdrSetProcessorContext().

◆ Amd64SetupIdt()

static VOID Amd64SetupIdt ( PVOID  IdtBase)
static

Definition at line 319 of file winldr.c.

320{
321 KDESCRIPTOR IdtDesc, OldIdt;
322 //ULONG Size;
323 TRACE("Amd64SetupIdt(IdtBase = %p)\n", IdtBase);
324
325 /* Get old IDT */
326 __sidt(&OldIdt.Limit);
327
328 /* Copy the old IDT */
329 //Size = min(OldIdt.Limit + 1, NUM_IDT * sizeof(KIDTENTRY));
330 //RtlCopyMemory(IdtBase, (PVOID)OldIdt.Base, Size);
331
332 /* Setup the new IDT descriptor */
333 IdtDesc.Base = IdtBase;
334 IdtDesc.Limit = NUM_IDT * sizeof(KIDTENTRY) - 1;
335
336 /* Set the new IDT */
337 __lidt(&IdtDesc.Limit);
338 TRACE("Leave Amd64SetupIdt()\n");
339}
__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:553
#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:30
#define PtrToPfn(p)
Definition: amd64.h:27
PHARDWARE_PTE PxeBase
Definition: winldr.c:23
#define ERR(fmt,...)
Definition: precomp.h:57
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 424 of file winldr.c.

425{
426}

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:33
#define VAtoPPI(va)
Definition: amd64.h:31
#define VAtoPDI(va)
Definition: amd64.h:32
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:343
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 KI_USER_SHARED_DATA */
251 {
252 ERR("Could not map KI_USER_SHARED_DATA\n");
253 return FALSE;
254 }
255
256 /* Map the APIC page */
258
259 /* Map the page tables for 4 MB HAL address space. */
263 MempGetOrCreatePageDir(PdeBase, VAtoPDI(MM_HAL_VA_START + 2 * 1024 * 1024));
264
265 return TRUE;
266}
PFN_NUMBER SharedUserDataPfn
Definition: winldr.c:27
static VOID WinLdrpMapApic(VOID)
Definition: winldr.c:212
#define MM_HAL_VA_START
Definition: ketypes.h:326
#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: precomp.h:61
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:328
LONGLONG QuadPart
Definition: typedefs.h:114
ULONG LowPart
Definition: typedefs.h:106

Referenced by WinLdrMapSpecialPages().

◆ WinLdrSetProcessorContext()

VOID WinLdrSetProcessorContext ( _In_ USHORT  OperatingSystemVersion)

Definition at line 342 of file winldr.c.

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

375{
376 PVOID SharedUserDataAddress = NULL;
377 ULONG_PTR Tss = 0;
378 ULONG BlockSize, NumPages;
379
380 LoaderBlock->u.I386.CommonDataArea = (PVOID)DbgPrint; // HACK
381 LoaderBlock->u.I386.MachineType = MACHINE_TYPE_ISA;
382
383 /* Allocate 1 page for SharedUserData */
384 SharedUserDataAddress = MmAllocateMemoryWithType(MM_PAGE_SIZE, LoaderStartupPcrPage);
385 SharedUserDataPfn = (ULONG_PTR)SharedUserDataAddress >> MM_PAGE_SHIFT;
386 if (SharedUserDataAddress == NULL)
387 {
388 UiMessageBox("Can't allocate SharedUserData page.");
389 return;
390 }
391 RtlZeroMemory(SharedUserDataAddress, MM_PAGE_SIZE);
392
393 /* Allocate TSS */
394 BlockSize = (sizeof(KTSS) + MM_PAGE_SIZE) & ~(MM_PAGE_SIZE - 1);
396 TssBasePage = Tss >> MM_PAGE_SHIFT;
397
398 /* Allocate space for new GDT + IDT */
399 BlockSize = NUM_GDT * sizeof(KGDTENTRY) + NUM_IDT * sizeof(KIDTENTRY);
400 NumPages = (BlockSize + MM_PAGE_SIZE - 1) >> MM_PAGE_SHIFT;
401 GdtIdt = (PKGDTENTRY)MmAllocateMemoryWithType(NumPages * MM_PAGE_SIZE, LoaderMemoryData);
402 if (GdtIdt == NULL)
403 {
404 UiMessageBox("Can't allocate pages for GDT+IDT!");
405 return;
406 }
407
408 /* Zero newly prepared GDT+IDT */
409 RtlZeroMemory(GdtIdt, NumPages << MM_PAGE_SHIFT);
410
411 // Before we start mapping pages, create a block of memory, which will contain
412 // PDE and PTEs
414 {
415 // FIXME: bugcheck
416 }
417
418 /* Map KI_USER_SHARED_DATA, Apic and HAL space */
420}
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:995
#define PKGDTENTRY
Definition: ketypes.h:512
#define MACHINE_TYPE_ISA
Definition: ketypes.h:102
@ LoaderStartupPcrPage
Definition: arc.h:191
ULONG MachineType
Definition: arc.h:454
PVOID CommonDataArea
Definition: arc.h:453
union _LOADER_PARAMETER_BLOCK::@3369 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().

◆ PxeBase

◆ SharedUserDataPfn

PFN_NUMBER SharedUserDataPfn

Definition at line 27 of file winldr.c.

Referenced by WinLdrMapSpecialPages(), and WinLdrSetupMachineDependent().

◆ TssBasePage

ULONG_PTR TssBasePage

Definition at line 28 of file winldr.c.

Referenced by WinLdrSetProcessorContext(), and WinLdrSetupMachineDependent().