/* Setup the PFN for the PDE base of this process */
PointerPte = MiAddressToPte(PDE_BASE);
PageFrameNumber = PFN_FROM_PTE(PointerPte);
- //MiInitializePfn(PageFrameNumber, PointerPte, TRUE);
+ MiInitializePfn(PageFrameNumber, PointerPte, TRUE);
/* Do the same for hyperspace */
PointerPde = MiAddressToPde(HYPER_SPACE);
PageFrameNumber = PFN_FROM_PTE(PointerPde);
- //MiInitializePfn(PageFrameNumber, PointerPde, TRUE);
+ MiInitializePfn(PageFrameNumber, PointerPde, TRUE);
/* Release PFN lock */
KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
return STATUS_SUCCESS;
}
+/* FIXME: Evaluate ways to make this portable yet arch-specific */
+BOOLEAN
+NTAPI
+MmCreateProcessAddressSpace(IN ULONG MinWs,
+ IN PEPROCESS Process,
+ OUT PULONG_PTR DirectoryTableBase)
+{
+ KIRQL OldIrql;
+ PFN_NUMBER PdeIndex, HyperIndex;
+ PMMPTE PointerPte;
+ MMPTE TempPte, PdePte;
+ ULONG PdeOffset;
+ PMMPTE SystemTable;
+
+ /* No page colors yet */
+ Process->NextPageColor = 0;
+
+ /* Setup the hyperspace lock */
+ KeInitializeSpinLock(&Process->HyperSpaceLock);
+
+ /* Lock PFN database */
+ OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
+
+ /* Get a page for the PDE */
+ PdeIndex = MiRemoveAnyPage(0);
+ KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
+ MiZeroPhysicalPage(PdeIndex);
+ OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
+
+ /* Get a page for hyperspace */
+ HyperIndex = MiRemoveAnyPage(0);
+ KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
+ MiZeroPhysicalPage(HyperIndex);
+
+ /* Switch to phase 1 initialization */
+ ASSERT(Process->AddressSpaceInitialized == 0);
+ Process->AddressSpaceInitialized = 1;
+
+ /* Set the base directory pointers */
+ DirectoryTableBase[0] = PdeIndex << PAGE_SHIFT;
+ DirectoryTableBase[1] = HyperIndex << PAGE_SHIFT;
+
+ /* Make sure we don't already have a page directory setup */
+ ASSERT(Process->Pcb.DirectoryTableBase[0] == 0);
+
+ /* Insert us into the Mm process list */
+ InsertTailList(&MmProcessList, &Process->MmProcessLinks);
+
+ /* Get a PTE to map the page directory */
+ PointerPte = MiReserveSystemPtes(1, SystemPteSpace);
+ ASSERT(PointerPte != NULL);
+
+ /* Build it */
+ MI_MAKE_HARDWARE_PTE_KERNEL(&PdePte,
+ PointerPte,
+ MM_READWRITE,
+ PdeIndex);
+
+ /* Set it dirty and map it */
+ PdePte.u.Hard.Dirty = TRUE;
+ MI_WRITE_VALID_PTE(PointerPte, PdePte);
+
+ /* Now get the page directory (which we'll double map, so call it a page table */
+ SystemTable = MiPteToAddress(PointerPte);
+
+ /* Copy all the kernel mappings */
+ PdeOffset = MiGetPdeOffset(MmSystemRangeStart);
+
+ RtlCopyMemory(&SystemTable[PdeOffset],
+ MiAddressToPde(MmSystemRangeStart),
+ PAGE_SIZE - PdeOffset * sizeof(MMPTE));
+
+ /* Now write the PTE/PDE entry for hyperspace itself */
+ TempPte = ValidKernelPte;
+ TempPte.u.Hard.PageFrameNumber = HyperIndex;
+ PdeOffset = MiGetPdeOffset(HYPER_SPACE);
+ SystemTable[PdeOffset] = TempPte;
+
+ /* Sanity check */
+ PdeOffset++;
+ ASSERT(MiGetPdeOffset(MmHyperSpaceEnd) >= PdeOffset);
+
+ /* Now do the x86 trick of making the PDE a page table itself */
+ PdeOffset = MiGetPdeOffset(PTE_BASE);
+ TempPte.u.Hard.PageFrameNumber = PdeIndex;
+ SystemTable[PdeOffset] = TempPte;
+
+ /* Let go of the system PTE */
+ MiReleaseSystemPtes(PointerPte, 1, SystemPteSpace);
+ return TRUE;
+}
+
/* SYSTEM CALLS ***************************************************************/
NTSTATUS
return(Attributes);
}
-NTSTATUS
-NTAPI
-Mmi386ReleaseMmInfo(PEPROCESS Process)
-{
- PUSHORT LdtDescriptor;
- ULONG LdtBase;
- PULONG PageDir;
- ULONG i;
-
- DPRINT("Mmi386ReleaseMmInfo(Process %x)\n",Process);
-
- LdtDescriptor = (PUSHORT) &Process->Pcb.LdtDescriptor;
- LdtBase = LdtDescriptor[1] |
- ((LdtDescriptor[2] & 0xff) << 16) |
- ((LdtDescriptor[3] & ~0xff) << 16);
-
- DPRINT("LdtBase: %x\n", LdtBase);
-
- if (LdtBase)
- {
- ExFreePool((PVOID) LdtBase);
- }
-
- PageDir = MmCreateHyperspaceMapping(PTE_TO_PFN(Process->Pcb.DirectoryTableBase[0]));
- for (i = 0; i < ADDR_TO_PDE_OFFSET(MmSystemRangeStart); i++)
- {
- if (PageDir[i] != 0)
- {
- MiZeroPage(PTE_TO_PFN(PageDir[i]));
- MmReleasePageMemoryConsumer(MC_NPPOOL, PTE_TO_PFN(PageDir[i]));
- }
- }
- MmReleasePageMemoryConsumer(MC_NPPOOL, PTE_TO_PFN(PageDir[ADDR_TO_PDE_OFFSET(HYPERSPACE)]));
- MmDeleteHyperspaceMapping(PageDir);
- MmReleasePageMemoryConsumer(MC_NPPOOL, PTE_TO_PFN(Process->Pcb.DirectoryTableBase[0]));
-
- Process->Pcb.DirectoryTableBase[0] = 0;
- Process->Pcb.DirectoryTableBase[1] = 0;
-
- DPRINT("Finished Mmi386ReleaseMmInfo()\n");
- return(STATUS_SUCCESS);
-}
-
-BOOLEAN
-NTAPI
-MmCreateProcessAddressSpace(IN ULONG MinWs,
- IN PEPROCESS Process,
- IN PULONG DirectoryTableBase)
-{
- NTSTATUS Status;
- ULONG i, j;
- PFN_NUMBER Pfn[2];
- PULONG PageDirectory;
-
- DPRINT("MmCopyMmInfo(Src %x, Dest %x)\n", MinWs, Process);
-
- for (i = 0; i < 2; i++)
- {
- Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &Pfn[i]);
- if (!NT_SUCCESS(Status))
- {
- for (j = 0; j < i; j++)
- {
- MmReleasePageMemoryConsumer(MC_NPPOOL, Pfn[j]);
- }
-
- return FALSE;
- }
- }
-
- PageDirectory = MmCreateHyperspaceMapping(Pfn[0]);
-
- memcpy(PageDirectory + ADDR_TO_PDE_OFFSET(MmSystemRangeStart),
- MmGlobalKernelPageDirectory + ADDR_TO_PDE_OFFSET(MmSystemRangeStart),
- (1024 - ADDR_TO_PDE_OFFSET(MmSystemRangeStart)) * sizeof(ULONG));
-
- DPRINT("Addr %x\n",ADDR_TO_PDE_OFFSET(PAGETABLE_MAP));
- PageDirectory[ADDR_TO_PDE_OFFSET(PAGETABLE_MAP)] = PFN_TO_PTE(Pfn[0]) | PA_PRESENT | PA_READWRITE;
- PageDirectory[ADDR_TO_PDE_OFFSET(HYPERSPACE)] = PFN_TO_PTE(Pfn[1]) | PA_PRESENT | PA_READWRITE;
-
- MmDeleteHyperspaceMapping(PageDirectory);
-
- DirectoryTableBase[0] = PFN_TO_PTE(Pfn[0]);
- DirectoryTableBase[1] = 0;
- DPRINT("Finished MmCopyMmInfo(): 0x%x\n", DirectoryTableBase[0]);
- return TRUE;
-}
-
static PULONG
MmGetPageTableForProcess(PEPROCESS Process, PVOID Address, BOOLEAN Create)
{