- Move ARM Pool to 0xB0000000 to avoid clashing with existing ReactOS address space components (shouldn't happen if things work right, but better safe than sorry).

- Implement System PTE allocator (MiReserveAlignedSystemPtes and MiReserveSystemPtes). Very simple yet functional, no optimizes for now.
- Allocate 32 zeoring PTEs from the System PTE pool.
  - Not used yet, only the allocation is made to test the current framework.
- Tested on VirtualBox, QEMU and VMWare with RAM sizes from 128MB to 1536MB with no problems.


svn path=/trunk/; revision=41575
This commit is contained in:
ReactOS Portable Systems Group 2009-06-23 07:49:39 +00:00
parent 12ed6254a7
commit 9730c51810
4 changed files with 155 additions and 2 deletions

View file

@ -64,6 +64,7 @@ typedef ULONG PFN_TYPE, *PPFN_TYPE;
#define HYPER_SPACE (0xC0400000)
#define MI_HYPERSPACE_PTES (256 - 1)
#define MI_ZERO_PTES (32)
#define MI_MAPPING_RANGE_START (ULONG)HYPER_SPACE
#define MI_MAPPING_RANGE_END (MI_MAPPING_RANGE_START + \
MI_HYPERSPACE_PTES * PAGE_SIZE)

View file

@ -52,7 +52,7 @@ ULONG MmMaxAdditionNonPagedPoolPerMb = 400 * 1024;
// immediately follows the PFN database, typically sharing the same PDE. It is
// a very small resource (32MB on a 1GB system), and capped at 128MB.
//
// Right now, we call this the "ARM Pool" and it begins at 0xA0000000 since we
// Right now, we call this the "ARM Pool" and it begins at 0xB0000000 since we
// don't want to interefere with the ReactOS memory manager PFN database (yet).
//
// The expansion nonpaged pool, on the other hand, can grow much bigger (400MB
@ -288,7 +288,7 @@ MmArmInitSystem(IN ULONG Phase,
DPRINT1("System PTE VA starts at: %p\n", MmNonPagedSystemStart);
DPRINT1("NP Expansion VA begins at: %p and ends at: %p\n",
MmNonPagedPoolStart, MmNonPagedPoolEnd);
MmNonPagedPoolStart = (PVOID)0xA0000000;
MmNonPagedPoolStart = (PVOID)0xB0000000;
//
// Now we actually need to get these many physical pages. Nonpaged pool
@ -477,6 +477,19 @@ MmArmInitSystem(IN ULONG Phase,
MmFirstReservedMappingPte = MiAddressToPte(MI_MAPPING_RANGE_START);
MmLastReservedMappingPte = MiAddressToPte(MI_MAPPING_RANGE_END);
MmFirstReservedMappingPte->u.Hard.PageFrameNumber = MI_HYPERSPACE_PTES;
//
// Reserve system PTEs for zeroing PTEs and clear them
//
MiFirstReservedZeroingPte = MiReserveSystemPtes(MI_ZERO_PTES,
SystemPteSpace);
DPRINT1("ZERO PTEs are at: %p\n", MiFirstReservedZeroingPte);
RtlZeroMemory(MiFirstReservedZeroingPte, MI_ZERO_PTES * sizeof(MMPTE));
//
// Set the counter to maximum to boot with
//
MiFirstReservedZeroingPte->u.Hard.PageFrameNumber = MI_ZERO_PTES - 1;
}
//

View file

@ -27,6 +27,7 @@ extern ULONG MmMaximumNonPagedPoolInBytes;
extern PVOID MmNonPagedPoolStart;
extern PVOID MmNonPagedPoolExpansionStart;
extern PMMPTE MmFirstReservedMappingPte, MmLastReservedMappingPte;
extern PMMPTE MiFirstReservedZeroingPte;
VOID
NTAPI
@ -42,4 +43,11 @@ MiInitializeSystemPtes(
IN MMSYSTEM_PTE_POOL_TYPE PoolType
);
PMMPTE
NTAPI
MiReserveSystemPtes(
IN ULONG NumberOfPtes,
IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType
);
/* EOF */

View file

@ -27,6 +27,137 @@ ULONG MmTotalSystemPtes;
/* PRIVATE FUNCTIONS **********************************************************/
PMMPTE
NTAPI
MiReserveAlignedSystemPtes(IN ULONG NumberOfPtes,
IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType,
IN ULONG Alignment)
{
PMMPTE PointerPte, NextPte, PreviousPte;
ULONG_PTR ClusterSize;
//
// Sanity check
//
ASSERT(Alignment <= PAGE_SIZE);
//
// Get the first free cluster and make sure we have PTEs available
//
PointerPte = &MmFirstFreeSystemPte[SystemPtePoolType];
if (PointerPte->u.List.NextEntry == -1) return NULL;
//
// Now move to the first free system PTE cluster
//
PreviousPte = PointerPte;
PointerPte = MmSystemPteBase + PointerPte->u.List.NextEntry;
//
// Loop each cluster
//
while (TRUE)
{
//
// Check if we're done to only one PTE left
//
if (!PointerPte->u.List.OneEntry)
{
//
// Keep track of the next cluster in case we have to relink
//
NextPte = PointerPte + 1;
//
// Can this cluster satisfy the request?
//
ClusterSize = (ULONG_PTR)NextPte->u.List.NextEntry;
if (NumberOfPtes < ClusterSize)
{
//
// It can, and it will leave just one PTE left
//
if ((ClusterSize - NumberOfPtes) == 1)
{
//
// This cluster becomes a single system PTE entry
//
PointerPte->u.List.OneEntry = 1;
}
else
{
//
// Otherwise, the next cluster aborbs what's left
//
NextPte->u.List.NextEntry = ClusterSize - NumberOfPtes;
}
//
// Decrement the free count and move to the next starting PTE
//
MmTotalFreeSystemPtes[SystemPtePoolType] -= NumberOfPtes;
PointerPte += (ClusterSize - NumberOfPtes);
break;
}
//
// Did we find exactly what you wanted?
//
if (NumberOfPtes == ClusterSize)
{
//
// Yes, fixup the cluster and decrease free system PTE count
//
PreviousPte->u.List.NextEntry = PointerPte->u.List.NextEntry;
MmTotalFreeSystemPtes[SystemPtePoolType] -= NumberOfPtes;
break;
}
}
else if (NumberOfPtes == 1)
{
//
// We have one PTE in this cluster, and it's all you want
//
PreviousPte->u.List.NextEntry = PointerPte->u.List.NextEntry;
MmTotalFreeSystemPtes[SystemPtePoolType]--;
break;
}
//
// We couldn't find what you wanted -- is this the last cluster?
//
if (PointerPte->u.List.NextEntry == -1) return NULL;
//
// Go to the next cluster
//
PreviousPte = PointerPte;
PointerPte = MmSystemPteBase + PointerPte->u.List.NextEntry;
ASSERT(PointerPte > PreviousPte);
}
//
// Flush the TLB and return the first PTE
//
KeFlushProcessTb();
return PointerPte;
}
PMMPTE
NTAPI
MiReserveSystemPtes(IN ULONG NumberOfPtes,
IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType)
{
PMMPTE PointerPte;
//
// Use the extended function
//
PointerPte = MiReserveAlignedSystemPtes(NumberOfPtes, SystemPtePoolType, 0);
ASSERT(PointerPte != NULL);
return PointerPte;
}
VOID
NTAPI
MiInitializeSystemPtes(IN PMMPTE StartingPte,