Author: ros-arm-bringup
Date: Sun Jan 3 06:10:09 2010
New Revision: 44903
URL:
http://svn.reactos.org/svn/reactos?rev=44903&view=rev
Log:
- Fix some pool calculations.
- Check for some untested pool calculations.
- Handle paging-in the page tables when needed.
- Setup paging colors based on L2 cache size/associativity.
- Setup system PTE size earlier.
Modified:
trunk/reactos/ntoskrnl/mm/ARM3/i386/init.c
trunk/reactos/ntoskrnl/mm/ARM3/miarm.h
trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c
Modified: trunk/reactos/ntoskrnl/mm/ARM3/i386/init.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/i386/init…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/i386/init.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/i386/init.c [iso-8859-1] Sun Jan 3 06:10:09 2010
@@ -152,6 +152,14 @@
PMMPTE MmSystemPagePtes;
//
+// The system cache starts right after hyperspace. The first few pages are for
+// keeping track of the system working set list.
+//
+// This should be 0xC0C00000 -- the cache itself starts at 0xC1000000
+//
+PMMWSL MmSystemCacheWorkingSetList = MI_SYSTEM_CACHE_WS_START;
+
+//
// Windows NT seems to choose between 7000, 11000 and 50000
// On systems with more than 32MB, this number is then doubled, and further
// aligned up to a PDE boundary (4MB).
@@ -222,6 +230,22 @@
PVOID MmSystemCacheStart;
PVOID MmSystemCacheEnd;
MMSUPPORT MmSystemCacheWs;
+
+//
+// This is where hyperspace ends (followed by the system cache working set)
+//
+PVOID MmHyperSpaceEnd;
+
+//
+// Page coloring algorithm data
+//
+ULONG MmSecondaryColors;
+ULONG MmSecondaryColorMask;
+
+//
+// Actual (registry-configurable) size of a GUI thread's stack
+//
+ULONG MmLargeStackSize;
/* PRIVATE FUNCTIONS **********************************************************/
@@ -276,6 +300,48 @@
MxFreeDescriptor->BasePage += PageCount;
MxFreeDescriptor->PageCount -= PageCount;
return Pfn;
+}
+
+PFN_NUMBER
+NTAPI
+MiPagesInLoaderBlock(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
+ IN PBOOLEAN IncludeType)
+{
+ PLIST_ENTRY NextEntry;
+ PFN_NUMBER PageCount = 0;
+ PMEMORY_ALLOCATION_DESCRIPTOR MdBlock;
+
+ //
+ // Now loop through the descriptors
+ //
+ NextEntry = LoaderBlock->MemoryDescriptorListHead.Flink;
+ while (NextEntry != &LoaderBlock->MemoryDescriptorListHead)
+ {
+ //
+ // Grab each one, and check if it's one we should include
+ //
+ MdBlock = CONTAINING_RECORD(NextEntry,
+ MEMORY_ALLOCATION_DESCRIPTOR,
+ ListEntry);
+ if ((MdBlock->MemoryType < LoaderMaximum) &&
+ (IncludeType[MdBlock->MemoryType]))
+ {
+ //
+ // Add this to our running total
+ //
+ PageCount += MdBlock->PageCount;
+ }
+
+ //
+ // Try the next descriptor
+ //
+ NextEntry = MdBlock->ListEntry.Flink;
+ }
+
+ //
+ // Return the total
+ //
+ return PageCount;
}
PPHYSICAL_MEMORY_DESCRIPTOR
@@ -606,17 +672,26 @@
PLIST_ENTRY NextEntry;
PMEMORY_ALLOCATION_DESCRIPTOR MdBlock;
ULONG FreePages = 0;
- PFN_NUMBER PageFrameIndex;
+ PFN_NUMBER PageFrameIndex, PoolPages;
PMMPTE StartPde, EndPde, PointerPte, LastPte;
MMPTE TempPde = HyperTemplatePte, TempPte = HyperTemplatePte;
PVOID NonPagedPoolExpansionVa;
- ULONG OldCount;
+ ULONG OldCount, i, L2Associativity;
BOOLEAN IncludeType[LoaderMaximum];
- ULONG i;
PVOID Bitmap;
PPHYSICAL_MEMORY_RUN Run;
PFN_NUMBER FreePage, FreePageCount, PagesLeft, BasePage, PageCount;
+ //
+ // Instantiate memory that we don't consider RAM/usable
+ // We use the same exclusions that Windows does, in order to try to be
+ // compatible with WinLDR-style booting
+ //
+ for (i = 0; i < LoaderMaximum; i++) IncludeType[i] = TRUE;
+ IncludeType[LoaderBad] = FALSE;
+ IncludeType[LoaderFirmwarePermanent] = FALSE;
+ IncludeType[LoaderSpecialMemory] = FALSE;
+ IncludeType[LoaderBBTMemory] = FALSE;
if (Phase == 0)
{
//
@@ -698,7 +773,61 @@
//
MiSystemViewStart = (PVOID)((ULONG_PTR)MmSessionBase -
MmSystemViewSize);
-
+
+ //
+ // Count physical pages on the system
+ //
+ PageCount = MiPagesInLoaderBlock(LoaderBlock, IncludeType);
+
+ //
+ // Check if this is a machine with less than 19MB of RAM
+ //
+ if (PageCount < MI_MIN_PAGES_FOR_SYSPTE_TUNING)
+ {
+ //
+ // Use the very minimum of system PTEs
+ //
+ MmNumberOfSystemPtes = 7000;
+ }
+ else
+ {
+ //
+ // Use the default, but check if we have more than 32MB of RAM
+ //
+ MmNumberOfSystemPtes = 11000;
+ if (PageCount > MI_MIN_PAGES_FOR_SYSPTE_BOOST)
+ {
+ //
+ // Double the amount of system PTEs
+ //
+ MmNumberOfSystemPtes <<= 1;
+ }
+ }
+
+ DPRINT("System PTE count has been tuned to %d (%d bytes)\n",
+ MmNumberOfSystemPtes, MmNumberOfSystemPtes * PAGE_SIZE);
+
+ //
+ //
+ // Start of Architecture Specific Initialization Code
+ //
+ //
+
+ //
+ // The large kernel stack is cutomizable, but use default value for now
+ //
+ MmLargeStackSize = KERNEL_LARGE_STACK_SIZE;
+
+ //
+ // Setup template
+ //
+ HyperTemplatePte.u.Long = 0;
+ HyperTemplatePte.u.Hard.Valid = 1;
+ HyperTemplatePte.u.Hard.Write = 1;
+ HyperTemplatePte.u.Hard.Dirty = 1;
+ HyperTemplatePte.u.Hard.Accessed = 1;
+ if (Ke386GlobalPagesEnabled) HyperTemplatePte.u.Hard.Global = 1;
+
//
// Set CR3 for the system process
//
@@ -784,9 +913,13 @@
//
// For now, it is
//
- FreePages = MdBlock->PageCount;
MxFreeDescriptor = MdBlock;
}
+
+ //
+ // More free pages
+ //
+ FreePages += MdBlock->PageCount;
}
}
@@ -803,34 +936,6 @@
MxOldFreeDescriptor = *MxFreeDescriptor;
//
- // Check if this is a machine with less than 19MB of RAM
- //
- if (MmNumberOfPhysicalPages < MI_MIN_PAGES_FOR_SYSPTE_TUNING)
- {
- //
- // Use the very minimum of system PTEs
- //
- MmNumberOfSystemPtes = 7000;
- }
- else
- {
- //
- // Use the default, but check if we have more than 32MB of RAM
- //
- MmNumberOfSystemPtes = 11000;
- if (MmNumberOfPhysicalPages > MI_MIN_PAGES_FOR_SYSPTE_BOOST)
- {
- //
- // Double the amount of system PTEs
- //
- MmNumberOfSystemPtes <<= 1;
- }
- }
-
- DPRINT("System PTE count has been tuned to %d (%d bytes)\n",
- MmNumberOfSystemPtes, MmNumberOfSystemPtes * PAGE_SIZE);
-
- //
// Check if this is a machine with less than 256MB of RAM, and no overide
//
if ((MmNumberOfPhysicalPages <= MI_MIN_PAGES_FOR_NONPAGED_POOL_TUNING)
&&
@@ -841,6 +946,11 @@
//
MmSizeOfNonPagedPoolInBytes = 2 * 1024 * 1024;
}
+
+ //
+ // Hyperspace ends here
+ //
+ MmHyperSpaceEnd = (PVOID)((ULONG_PTR)MmSystemCacheWorkingSetList - 1);
//
// Check if the user gave a ridicuously large nonpaged pool RAM size
@@ -900,26 +1010,86 @@
if (!MmMaximumNonPagedPoolInBytes)
{
//
- // Start with the default (1MB) and add 400 KB for each MB above 4
+ // Start with the default (1MB)
//
MmMaximumNonPagedPoolInBytes = MmDefaultMaximumNonPagedPool;
- MmMaximumNonPagedPoolInBytes += (MmNumberOfPhysicalPages - 1024) /
- 256 * MmMaxAdditionNonPagedPoolPerMb;
- }
+
+ //
+ // Add space for PFN database
+ //
+ MmMaximumNonPagedPoolInBytes += (ULONG)
+ PAGE_ALIGN((MmHighestPhysicalPage + 1) * sizeof(MMPFN));
+
+ //
+ // Add 400KB for each MB above 4
+ //
+ MmMaximumNonPagedPoolInBytes += (FreePages - 1024) / 256 *
+ MmMaxAdditionNonPagedPoolPerMb;
+ }
+
+ //
+ // Make sure there's at least 16 pages + the PFN available for expansion
+ //
+ PoolPages = MmSizeOfNonPagedPoolInBytes + (PAGE_SIZE * 16) +
+ ((ULONG)PAGE_ALIGN(MmHighestPhysicalPage + 1) *
+ sizeof(MMPFN));
+ if (MmMaximumNonPagedPoolInBytes < PoolPages)
+ {
+ //
+ // Set it to the minimum value for the maximum (yuck!)
+ //
+ MmMaximumNonPagedPoolInBytes = PoolPages;
+ }
+
+ //
+ // Systems with 2GB of kernel address space get double the size
+ //
+ PoolPages = MI_MAX_NONPAGED_POOL_SIZE * 2;
//
// Don't let the maximum go too high
//
+ if (MmMaximumNonPagedPoolInBytes > PoolPages)
+ {
+ //
+ // Set it to the upper limit
+ //
+ MmMaximumNonPagedPoolInBytes = PoolPages;
+ }
+
+ //
+ // Check if this is a system with > 128MB of non paged pool
+ //
if (MmMaximumNonPagedPoolInBytes > MI_MAX_NONPAGED_POOL_SIZE)
{
//
- // Set it to the upper limit
- //
- MmMaximumNonPagedPoolInBytes = MI_MAX_NONPAGED_POOL_SIZE;
- }
-
- //
- // Calculate the number of bytes, and then convert to pages
+ // FIXME: Unsure about additional checks needed
+ //
+ DPRINT1("Untested path\n");
+ }
+
+ //
+ // Get L2 cache information
+ //
+ L2Associativity = KeGetPcr()->SecondLevelCacheAssociativity;
+ MmSecondaryColors = KeGetPcr()->SecondLevelCacheSize;
+ if (L2Associativity) MmSecondaryColors /= L2Associativity;
+
+ //
+ // Compute final color mask and count
+ //
+ MmSecondaryColors >>= PAGE_SHIFT;
+ if (!MmSecondaryColors) MmSecondaryColors = 1;
+ MmSecondaryColorMask = MmSecondaryColors - 1;
+
+ //
+ // Store it
+ //
+ KeGetCurrentPrcb()->SecondaryColorMask = MmSecondaryColorMask;
+
+ //
+ // Calculate the number of bytes for the PFN database
+ // and then convert to pages
//
MxPfnAllocation = (MmHighestPhysicalPage + 1) * sizeof(MMPFN);
MxPfnAllocation >>= PAGE_SHIFT;
@@ -973,6 +1143,19 @@
PAGE_SHIFT;
MmNumberOfSystemPtes--;
ASSERT(MmNumberOfSystemPtes > 1000);
+ }
+
+ //
+ // Check if we are in a situation where the size of the paged pool
+ // is so large that it overflows into nonpaged pool
+ //
+ if (MmSizeOfPagedPoolInBytes >
+ ((ULONG_PTR)MmNonPagedSystemStart - (ULONG_PTR)MmPagedPoolStart))
+ {
+ //
+ // We need some recalculations here
+ //
+ DPRINT1("Paged pool is too big!\n");
}
//
@@ -1295,18 +1478,7 @@
MiSyncARM3WithROS(MmNonPagedSystemStart, (PVOID)((ULONG_PTR)MmNonPagedPoolEnd -
1));
MiSyncARM3WithROS(MmPfnDatabase, (PVOID)((ULONG_PTR)MmNonPagedPoolStart +
MmSizeOfNonPagedPoolInBytes - 1));
MiSyncARM3WithROS((PVOID)HYPER_SPACE, (PVOID)(HYPER_SPACE + PAGE_SIZE - 1));
-
- //
- // Instantiate memory that we don't consider RAM/usable
- // We use the same exclusions that Windows does, in order to try to be
- // compatible with WinLDR-style booting
- //
- for (i = 0; i < LoaderMaximum; i++) IncludeType[i] = TRUE;
- IncludeType[LoaderBad] = FALSE;
- IncludeType[LoaderFirmwarePermanent] = FALSE;
- IncludeType[LoaderSpecialMemory] = FALSE;
- IncludeType[LoaderBBTMemory] = FALSE;
-
+
//
// Build the physical memory block
//
Modified: trunk/reactos/ntoskrnl/mm/ARM3/miarm.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/miarm.h?r…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/miarm.h [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/miarm.h [iso-8859-1] Sun Jan 3 06:10:09 2010
@@ -26,6 +26,7 @@
#define MI_SYSTEM_VIEW_SIZE (16 * 1024 * 1024)
+#define MI_SYSTEM_CACHE_WS_START (PVOID)0xC0C00000
#define MI_PAGED_POOL_START (PVOID)0xE1000000
#define MI_NONPAGED_POOL_END (PVOID)0xFFBE0000
#define MI_DEBUG_MAPPING (PVOID)0xFFBFF000
@@ -166,6 +167,7 @@
extern SIZE_T MmAllocatedNonPagedPool;
extern ULONG_PTR MmSubsectionBase;
extern ULONG MmSpecialPoolTag;
+extern PVOID MmHyperSpaceEnd;
NTSTATUS
NTAPI
Modified: trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/pagfault.…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c [iso-8859-1] Sun Jan 3 06:10:09 2010
@@ -140,8 +140,8 @@
KIRQL OldIrql;
NTSTATUS Status;
DPRINT("ARM3 Page Fault Dispatcher for address: %p in process: %p\n",
- Address,
- Process);
+ Address,
+ Process);
//
// Make sure APCs are off and we're not at dispatch
@@ -297,14 +297,27 @@
//
// Check for a fault on the page table or hyperspace itself
- // FIXME: Use MmHyperSpaceEnd
- //
- if ((Address >= (PVOID)PTE_BASE) && (Address <=
(PVOID)0xC0800000))
+ //
+ if ((Address >= (PVOID)PTE_BASE) && (Address <= MmHyperSpaceEnd))
{
//
// This might happen...not sure yet
//
DPRINT1("FAULT ON PAGE TABLES!\n");
+
+ //
+ // Map in the page table
+ //
+ if (MiCheckPdeForPagedPool(Address) == STATUS_WAIT_1)
+ {
+ DPRINT1("PAGE TABLES FAULTED IN!\n");
+ return STATUS_SUCCESS;
+ }
+
+ //
+ // Otherwise the page table doesn't actually exist
+ //
+ DPRINT1("FAILING\n");
return STATUS_ACCESS_VIOLATION;
}