Author: ros-arm-bringup
Date: Thu Jul 31 02:09:28 2008
New Revision: 34976
URL:
http://svn.reactos.org/svn/reactos?rev=34976&view=rev
Log:
mmcreatevirtualmapping internal should accept process as input parameter, not assume
null.
implement a broken version of mmcreateprocessaddressspace.
commit current checkpoint of arm mmu manager virtual mapping rewrite to sync with i386
code. the kernel part works fine and the kernel boots as far as it did before, but the
code is still ugly.
Modified:
trunk/reactos/ntoskrnl/mm/arm/stubs.c
Modified: trunk/reactos/ntoskrnl/mm/arm/stubs.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/arm/stubs.c?re…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/arm/stubs.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/arm/stubs.c [iso-8859-1] Thu Jul 31 02:09:28 2008
@@ -66,9 +66,9 @@
IN PVOID Address,
IN BOOLEAN Create)
{
- ULONG PdeOffset;
- PMMPTE PointerPde;
- MMPTE Pte;
+ //ULONG PdeOffset;
+ PMMPTE PointerPde, PointerPte;
+ MMPTE TempPde, TempPte;
NTSTATUS Status;
PFN_NUMBER Pfn;
@@ -86,6 +86,12 @@
}
//
+ // Get our templates
+ //
+ TempPde = MiArmTemplatePde;
+ TempPte = MiArmTemplatePte;
+
+ //
// Get the PDE
//
PointerPde = MiGetPdeAddress(Address);
@@ -99,18 +105,16 @@
//
// Does it exist in the kernel page directory?
//
- PdeOffset = MiGetPdeOffset(Address);
- if (MmGlobalKernelPageDirectory[PdeOffset] == 0)
+ //PdeOffset = MiGetPdeOffset(Address);
+ //if (MmGlobalKernelPageDirectory[PdeOffset] == 0)
{
//
// It doesn't. Is this a create operation? If not, fail
//
if (Create == FALSE) return NULL;
-
- //
- // THIS WHOLE PATH IS TODO
- //
- ASSERT(FALSE);
+ kernelHack:
+ DPRINT1("Must create a page for: %p PDE: %p\n", // Offset:
%lx!\n",
+ Address, PointerPde);//, PdeOffset);
//
// Allocate a non paged pool page for the PDE
@@ -119,20 +123,51 @@
if (!NT_SUCCESS(Status)) return NULL;
//
- // Make the entry valid
- //
- Pte.u.Hard.AsUlong = 0xDEADBEEF;
+ // Setup the PFN
+ //
+ TempPde.u.Hard.L1.Coarse.BaseAddress = (Pfn << PAGE_SHIFT) >>
CPT_SHIFT;
//
+ // Write the PDE
+ //
+ ASSERT(PointerPde->u.Hard.L1.Fault.Type == FaultPte);
+ ASSERT(TempPde.u.Hard.L1.Coarse.Type == CoarsePte);
+ *PointerPde = TempPde;
+
+ //
// Save it
//
- MmGlobalKernelPageDirectory[PdeOffset] = Pte.u.Hard.AsUlong;
+ //MmGlobalKernelPageDirectory[PdeOffset] = TempPde.u.Hard.AsUlong;
+ //DPRINT1("KPD: %p PDEADDR: %p\n",
&MmGlobalKernelPageDirectory[PdeOffset], MiGetPdeAddress(Address));
+
+ //
+ // FIXFIX: Double check with Felix tomorrow
+ //
+/////
+ //
+ // Get the PTE for this 1MB region
+ //
+ PointerPte = MiGetPteAddress(MiGetPteAddress(Address));
+ DPRINT1("PointerPte: %p\n", PointerPte);
+
+ //
+ // Write the PFN of the PDE
+ //
+ TempPte.u.Hard.L2.Small.BaseAddress = Pfn;
+
+ //
+ // Write the PTE
+ //
+ ASSERT(PointerPte->u.Hard.L2.Fault.Type == FaultPte);
+ ASSERT(TempPte.u.Hard.L2.Small.Type == SmallPte);
+ *PointerPte = TempPte;
+/////
}
//
// Now set the actual PDE
//
- PointerPde = (PMMPTE)&MmGlobalKernelPageDirectory[PdeOffset];
+ //PointerPde = (PMMPTE)&MmGlobalKernelPageDirectory[PdeOffset];
}
else
{
@@ -144,6 +179,7 @@
//
// THIS WHOLE PATH IS TODO
//
+ goto kernelHack;
ASSERT(FALSE);
//
@@ -155,12 +191,12 @@
//
// Make the entry valid
//
- Pte.u.Hard.AsUlong = 0xDEADBEEF;
+ TempPte.u.Hard.AsUlong = 0xDEADBEEF;
//
// Set it
//
- *PointerPde = Pte;
+ *PointerPde = TempPte;
}
}
@@ -247,7 +283,7 @@
//
// Invalidate the TLB entry
//
- MiFlushTlb(PointerPde, MiAddressToPte(Address));
+ MiFlushTlb(PointerPde, MiGetPteAddress(Address));
}
BOOLEAN
@@ -256,12 +292,76 @@
IN PEPROCESS Process,
IN PLARGE_INTEGER DirectoryTableBase)
{
- //
- // FIXME-USER: Need to create address space
- //
- UNIMPLEMENTED;
- while (TRUE);
- return 0;
+ NTSTATUS Status;
+ ULONG i;
+ PFN_NUMBER Pfn[2];
+ PMMPTE PageDirectory, PointerPde;
+ MMPTE TempPde;
+ ASSERT(FALSE);
+
+ //
+ // Loop two tables (Hyperspace and TTB). Each one is 16KB
+ //
+ //
+ for (i = 0; i < 8; i++)
+ {
+ //
+ // Allocate a page
+ //
+ Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &Pfn[i]);
+ if (!NT_SUCCESS(Status)) ASSERT(FALSE);
+ }
+
+ //
+ // Map the base
+ //
+ PageDirectory = MmCreateHyperspaceMapping(Pfn[0]);
+
+ //
+ // Copy the PDEs for kernel-mode
+ //
+ RtlCopyMemory(PageDirectory + MiGetPdeOffset(MmSystemRangeStart),
+ MmGlobalKernelPageDirectory + MiGetPdeOffset(MmSystemRangeStart),
+ (1024 - MiGetPdeOffset(MmSystemRangeStart)) * sizeof(ULONG));
+
+
+ //
+ // Setup the PDE for the table base
+ //
+ TempPde = MiArmTemplatePde;
+ TempPde.u.Hard.L1.Coarse.BaseAddress = (Pfn[0] << PAGE_SHIFT) >>
CPT_SHIFT;
+ PointerPde = &PageDirectory[MiGetPdeOffset(PTE_BASE)];
+
+ //
+ // Write the PDE
+ //
+ ASSERT(PointerPde->u.Hard.L1.Fault.Type == FaultPte);
+ ASSERT(TempPde.u.Hard.L1.Coarse.Type == CoarsePte);
+ *PointerPde = TempPde;
+
+ //
+ // Setup the PDE for the hyperspace
+ //
+ TempPde.u.Hard.L1.Coarse.BaseAddress = (Pfn[1] << PAGE_SHIFT) >>
CPT_SHIFT;
+ PointerPde = &PageDirectory[MiGetPdeOffset(HYPER_SPACE)];
+
+ //
+ // Write the PDE
+ //
+ ASSERT(PointerPde->u.Hard.L1.Fault.Type == FaultPte);
+ ASSERT(TempPde.u.Hard.L1.Coarse.Type == CoarsePte);
+ *PointerPde = TempPde;
+
+ //
+ // Unmap the page directory
+ //
+ MmDeleteHyperspaceMapping(PageDirectory);
+
+ //
+ // Return the page table base
+ //
+ DirectoryTableBase->QuadPart = Pfn[0] << PAGE_SHIFT;
+ return TRUE;
}
VOID
@@ -349,86 +449,63 @@
NTSTATUS
NTAPI
-MmCreateVirtualMappingInternal(IN PVOID Address,
+MmCreateVirtualMappingInternal(IN PEPROCESS Process,
+ IN PVOID Address,
IN ULONG Protection,
IN PPFN_NUMBER Pages,
IN ULONG PageCount,
IN BOOLEAN MarkAsMapped)
{
- PMMPTE PointerPte, LastPte, PointerPde, LastPde;
- MMPTE TempPte, TempPde;
- NTSTATUS Status;
- PFN_NUMBER Pfn;
+ PMMPTE PointerPte = NULL;
+ MMPTE TempPte;
+ PVOID Addr;
+ ULONG OldPdeOffset, PdeOffset, i;
DPRINT("[KMAP]: %p %d\n", Address, PageCount);
//ASSERT(Address >= MmSystemRangeStart);
//
- // Get our templates
+ // Get our template PTE
//
TempPte = MiArmTemplatePte;
- TempPde = MiArmTemplatePde;
-
- //
- // Check if we have PDEs for this region
- //
- PointerPde = MiGetPdeAddress(Address);
- LastPde = PointerPde + (PageCount / 256);
- while (PointerPde <= LastPde)
- {
- //
- // Check if we need to allocate the PDE
- //
- if (PointerPde->u.Hard.L1.Fault.Type == FaultPte)
+
+ //
+ // Loop every page
+ //
+ Addr = Address;
+ OldPdeOffset = MiGetPdeOffset(Addr) + 1;
+ for (i = 0; i < PageCount; i++)
+ {
+ //
+ // Get the next PDE offset and check if it's a new one
+ //
+ PdeOffset = MiGetPdeOffset(Addr);
+ if (OldPdeOffset != PdeOffset)
{
//
- // Request a page
- //
- Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &Pfn);
- if (!NT_SUCCESS(Status)) return Status;
+ // Get rid of the old L2 Table, if this was the last PTE on it
+ //
+ MiUnmapPageTable(PointerPte);
//
- // Setup the PFN
- //
- TempPde.u.Hard.L1.Coarse.BaseAddress = (Pfn << PAGE_SHIFT) >>
CPT_SHIFT;
-
- //
- // Write the PDE
- //
- ASSERT(PointerPde->u.Hard.L1.Fault.Type == FaultPte);
- ASSERT(TempPde.u.Hard.L1.Coarse.Type == CoarsePte);
- *PointerPde = TempPde;
-
- //
- // Get the PTE for this 1MB region
- //
- PointerPte = MiGetPteAddress(MiGetPteAddress(Address));
-
- //
- // Write the PFN of the PDE
- //
- TempPte.u.Hard.L2.Small.BaseAddress = Pfn;
-
- //
- // Write the PTE
- //
- ASSERT(PointerPte->u.Hard.L2.Fault.Type == FaultPte);
- ASSERT(TempPte.u.Hard.L2.Small.Type == SmallPte);
- *PointerPte = TempPte;
+ // Get the PTE for this address, and create the PDE for it
+ //
+ PointerPte = MiGetPageTableForProcess(NULL, Addr, TRUE);
+ ASSERT(PointerPte);
+ }
+ else
+ {
+ //
+ // Go to the next PTE on this PDE
+ //
+ ASSERT(PointerPte);
+ PointerPte++;
}
//
- // Next
- //
- PointerPde++;
- }
-
- //
- // Get start and end address and loop each PTE
- //
- PointerPte = MiGetPteAddress(Address);
- LastPte = PointerPte + PageCount - 1;
- while (PointerPte <= LastPte)
- {
+ // Save the current PDE
+ //
+ OldPdeOffset = PdeOffset;
+
//
// Mark it as mapped
//
@@ -447,9 +524,9 @@
*PointerPte = TempPte;
//
- // Next
- //
- PointerPte++;
+ // Move to the next page
+ //
+ Addr = (PVOID)((ULONG_PTR)Addr + PAGE_SIZE);
}
//
@@ -468,7 +545,8 @@
//
// Call the internal version
//
- return MmCreateVirtualMappingInternal(Address,
+ return MmCreateVirtualMappingInternal(NULL,
+ Address,
Protection,
Pages,
PageCount,
@@ -491,7 +569,8 @@
//
// Call the internal version
//
- return MmCreateVirtualMappingInternal(Address,
+ return MmCreateVirtualMappingInternal(Process,
+ Address,
Protection,
Pages,
PageCount,