//extern ULONG LoaderPagesSpanned;
-// This is needed because headers define wrong one for ReactOS
-#undef KIP0PCRADDRESS
-#define KIP0PCRADDRESS 0xffdff000
-
-#define HYPER_SPACE_ENTRY 0x300
-
-// This is needed only for SetProcessorContext routine
-#pragma pack(2)
- typedef struct
- {
- USHORT Limit;
- ULONG Base;
- } GDTIDT;
-#pragma pack(4)
+#define HYPER_SPACE_ENTRY 0x1EE
/* GLOBALS ***************************************************************/
-//PHARDWARE_PTE PDE;
+PHARDWARE_PTE PxeBase;
//PHARDWARE_PTE HalPageTable;
-PPAGE_DIRECTORY_AMD64 pPML4;
/* FUNCTIONS **************************************************************/
BOOLEAN
MempAllocatePageTables()
{
- ULONG KernelPages;
- PVOID UserSharedData;
-
DPRINTM(DPRINT_WINDOWS,">>> MempAllocatePageTables\n");
/* Allocate a page for the PML4 */
- pPML4 = MmAllocateMemoryWithType(PAGE_SIZE, LoaderMemoryData);
- if (!pPML4)
+ PxeBase = MmAllocateMemoryWithType(PAGE_SIZE, LoaderMemoryData);
+ if (!PxeBase)
{
DPRINTM(DPRINT_WINDOWS,"failed to allocate PML4\n");
return FALSE;
// FIXME: Physical PTEs = FirmwareTemporary ?
/* Zero the PML4 */
- RtlZeroMemory(pPML4, PAGE_SIZE);
+ RtlZeroMemory(PxeBase, PAGE_SIZE);
/* The page tables are located at 0xfffff68000000000
* We create a recursive self mapping through all 4 levels at
* virtual address 0xfffff6fb7dbedf68 */
- pPML4->Pde[VAtoPXI(PXE_BASE)].Valid = 1;
- pPML4->Pde[VAtoPXI(PXE_BASE)].Write = 1;
- pPML4->Pde[VAtoPXI(PXE_BASE)].PageFrameNumber = PtrToPfn(pPML4);
+ PxeBase[VAtoPXI(PXE_BASE)].Valid = 1;
+ PxeBase[VAtoPXI(PXE_BASE)].Write = 1;
+ PxeBase[VAtoPXI(PXE_BASE)].PageFrameNumber = PtrToPfn(PxeBase);
// FIXME: map PDE's for hals memory mapping
return TRUE;
}
-PPAGE_DIRECTORY_AMD64
-MempGetOrCreatePageDir(PPAGE_DIRECTORY_AMD64 pDir, ULONG Index)
+PHARDWARE_PTE
+MempGetOrCreatePageDir(PHARDWARE_PTE PdeBase, ULONG Index)
{
- PPAGE_DIRECTORY_AMD64 pSubDir;
+ PHARDWARE_PTE SubDir;
- if (!pDir)
+ if (!PdeBase)
return NULL;
- if (!pDir->Pde[Index].Valid)
+ if (!PdeBase[Index].Valid)
{
- pSubDir = MmAllocateMemoryWithType(PAGE_SIZE, LoaderSpecialMemory);
- if (!pSubDir)
+ SubDir = MmAllocateMemoryWithType(PAGE_SIZE, LoaderMemoryData);
+ if (!SubDir)
return NULL;
- RtlZeroMemory(pSubDir, PAGE_SIZE);
- pDir->Pde[Index].PageFrameNumber = PtrToPfn(pSubDir);
- pDir->Pde[Index].Valid = 1;
- pDir->Pde[Index].Write = 1;
+ RtlZeroMemory(SubDir, PAGE_SIZE);
+ PdeBase[Index].PageFrameNumber = PtrToPfn(SubDir);
+ PdeBase[Index].Valid = 1;
+ PdeBase[Index].Write = 1;
}
else
{
- pSubDir = (PPAGE_DIRECTORY_AMD64)((ULONGLONG)(pDir->Pde[Index].PageFrameNumber) * PAGE_SIZE);
+ SubDir = (PVOID)((ULONG64)(PdeBase[Index].PageFrameNumber) * PAGE_SIZE);
}
- return pSubDir;
+ return SubDir;
}
BOOLEAN
-MempMapSinglePage(ULONGLONG VirtualAddress, ULONGLONG PhysicalAddress)
+MempMapSinglePage(ULONG64 VirtualAddress, ULONG64 PhysicalAddress)
{
- PPAGE_DIRECTORY_AMD64 pDir3, pDir2, pDir1;
+ PHARDWARE_PTE PpeBase, PdeBase, PteBase;
ULONG Index;
- pDir3 = MempGetOrCreatePageDir(pPML4, VAtoPXI(VirtualAddress));
- pDir2 = MempGetOrCreatePageDir(pDir3, VAtoPPI(VirtualAddress));
- pDir1 = MempGetOrCreatePageDir(pDir2, VAtoPDI(VirtualAddress));
+ PpeBase = MempGetOrCreatePageDir(PxeBase, VAtoPXI(VirtualAddress));
+ PdeBase = MempGetOrCreatePageDir(PpeBase, VAtoPPI(VirtualAddress));
+ PteBase = MempGetOrCreatePageDir(PdeBase, VAtoPDI(VirtualAddress));
- if (!pDir1)
+ if (!PteBase)
+ {
+ DPRINTM(DPRINT_WINDOWS,"!!!No Dir %p, %p, %p, %p\n", PxeBase, PpeBase, PdeBase, PteBase);
return FALSE;
+ }
Index = VAtoPTI(VirtualAddress);
- if (pDir1->Pde[Index].Valid)
+ if (PteBase[Index].Valid)
{
+ DPRINTM(DPRINT_WINDOWS,"!!!Already mapped %ld\n", Index);
return FALSE;
}
- pDir1->Pde[Index].Valid = 1;
- pDir1->Pde[Index].Write = 1;
- pDir1->Pde[Index].PageFrameNumber = PhysicalAddress / PAGE_SIZE;
+ PteBase[Index].Valid = 1;
+ PteBase[Index].Write = 1;
+ PteBase[Index].PageFrameNumber = PhysicalAddress / PAGE_SIZE;
return TRUE;
}
+BOOLEAN
+MempIsPageMapped(PVOID VirtualAddress)
+{
+ PHARDWARE_PTE PpeBase, PdeBase, PteBase;
+ ULONG Index;
+
+ Index = VAtoPXI(VirtualAddress);
+ if (!PxeBase[Index].Valid)
+ return FALSE;
+
+ PpeBase = (PVOID)((ULONG64)(PxeBase[Index].PageFrameNumber) * PAGE_SIZE);
+ Index = VAtoPPI(VirtualAddress);
+ if (!PpeBase[Index].Valid)
+ return FALSE;
+
+ PdeBase = (PVOID)((ULONG64)(PpeBase[Index].PageFrameNumber) * PAGE_SIZE);
+ Index = VAtoPDI(VirtualAddress);
+ if (!PdeBase[Index].Valid)
+ return FALSE;
+
+ PteBase = (PVOID)((ULONG64)(PdeBase[Index].PageFrameNumber) * PAGE_SIZE);
+ Index = VAtoPTI(VirtualAddress);
+ if (!PteBase[Index].Valid)
+ return FALSE;
+
+ return TRUE;
+}
+
ULONG
-MempMapRangeOfPages(ULONGLONG VirtualAddress, ULONGLONG PhysicalAddress, ULONG cPages)
+MempMapRangeOfPages(ULONG64 VirtualAddress, ULONG64 PhysicalAddress, ULONG cPages)
{
ULONG i;
for (i = 0; i < cPages; i++)
{
- if (!FrLdrMapSinglePage(VirtualAddress, PhysicalAddress))
+ if (!MempMapSinglePage(VirtualAddress, PhysicalAddress))
{
return i;
}
MempSetupPaging(IN ULONG StartPage,
IN ULONG NumberOfPages)
{
- DPRINTM(DPRINT_WINDOWS,">>> MempSetupPaging(0x%lx, %ld)\n", StartPage, NumberOfPages);
+ DPRINTM(DPRINT_WINDOWS,">>> MempSetupPaging(0x%lx, %ld, %p)\n",
+ StartPage, NumberOfPages, StartPage * PAGE_SIZE + KSEG0_BASE);
+ /* Identity mapping */
if (MempMapRangeOfPages(StartPage * PAGE_SIZE,
StartPage * PAGE_SIZE,
NumberOfPages) != NumberOfPages)
{
- DPRINTM(DPRINT_WINDOWS,"Failed to map pages\n");
+ DPRINTM(DPRINT_WINDOWS,"Failed to map pages 1\n");
+ return FALSE;
+ }
+
+ /* Kernel mapping */
+ if (MempMapRangeOfPages(StartPage * PAGE_SIZE + KSEG0_BASE,
+ StartPage * PAGE_SIZE,
+ NumberOfPages) != NumberOfPages)
+ {
+ DPRINTM(DPRINT_WINDOWS,"Failed to map pages 2\n");
return FALSE;
}
WinLdrMapSpecialPages(ULONG PcrBasePage)
{
/* Map the PCR page */
- if (!MempMapSinglePage(PcrBasePage * PAGE_SIZE, KIP0PCRADDRESS))
+ if (!MempMapSinglePage(KIP0PCRADDRESS, PcrBasePage * PAGE_SIZE))
{
DPRINTM(DPRINT_WINDOWS, "Could not map PCR @ %lx\n", PcrBasePage);
return FALSE;
}
/* Map KI_USER_SHARED_DATA */
- if (!MempMapSinglePage((PcrBasePage+1) * PAGE_SIZE, KI_USER_SHARED_DATA))
+ if (!MempMapSinglePage(KI_USER_SHARED_DATA, (PcrBasePage+1) * PAGE_SIZE))
{
DPRINTM(DPRINT_WINDOWS, "Could not map KI_USER_SHARED_DATA\n");
return FALSE;
VOID
WinLdrSetProcessorContext(PVOID GdtIdt, IN ULONG64 Pcr, IN ULONG64 Tss)
{
+ DPRINTM(DPRINT_WINDOWS, "WinLdrSetProcessorContext %p\n", Pcr);
+
/* Disable Interrupts */
_disable();
__writeeflags(0);
/* Set the new PML4 */
- __writecr3((ULONGLONG)pPML4);
+ __writecr3((ULONG64)PxeBase);
- // Enable paging by modifying CR0
- __writecr0(__readcr0() | CR0_PG);
+ /* Get kernel mode address of gdt / idt */
+ GdtIdt = (PVOID)((ULONG64)GdtIdt + KSEG0_BASE);
- // Kernel expects the PCR to be zero-filled on startup
- // FIXME: Why zero it here when we can zero it right after allocation?
- RtlZeroMemory((PVOID)Pcr, MM_PAGE_SIZE); //FIXME: Why zero only 1 page when we allocate 2?
+ /* Create gdt entries and load gdtr */
+ WinLdrSetupGdt(GdtIdt, Tss);
- RtlZeroMemory(GdtIdt, PAGE_SIZE);
+ /* Copy old Idt and set idtr */
+ WinLdrSetupIdt((PVOID)((ULONG64)GdtIdt + 2048)); // HACK!
- WinLdrSetupGdt(GdtIdt, Tss);
+ /* LDT is unused */
+// __lldt(0);
+
+ /* Load selectors for DS/ES/FS/GS/SS */
+ Ke386SetDs(KGDT_64_DATA | RPL_MASK); // 0x2b
+ Ke386SetEs(KGDT_64_DATA | RPL_MASK); // 0x2b
+ Ke386SetFs(KGDT_32_R3_TEB | RPL_MASK); // 0x53
+ Ke386SetGs(KGDT_64_DATA | RPL_MASK); // 0x2b
+ Ke386SetSs(KGDT_64_R0_SS); // 0x18
- WinLdrSetupIdt(GdtIdt);
+ /* Load TSR */
+ __ltr(KGDT_TSS);
+ DPRINTM(DPRINT_WINDOWS, "leave WinLdrSetProcessorContext\n");
}
VOID