- Add some simple code to handle paged pool page allocation and freeing in MiAllocatePoolPages and MiFreePoolPages.

- Allocation does not support paged pool expansion yet, so we're limited to the initial 4MB that are initialized on startup.
- This only tests the raw page allocation routines so touching memory will fail as we don't handle paged pool faults yet.
- Nothing excercises this code path other than some simple tests while booting.


svn path=/trunk/; revision=43503
This commit is contained in:
ReactOS Portable Systems Group
2009-10-15 21:23:24 +00:00
parent ac9e8c032c
commit 5ac42f871f
2 changed files with 187 additions and 1 deletions
+128 -1
View File
@@ -148,6 +148,83 @@ MiAllocatePoolPages(IN POOL_TYPE PoolType,
//
SizeInPages = BYTES_TO_PAGES(SizeInBytes);
//
// Handle paged pool
//
if (PoolType == PagedPool)
{
//
// Lock the paged pool mutex
//
KeAcquireGuardedMutex(&MmPagedPoolMutex);
//
// Find some empty allocation space
//
i = RtlFindClearBitsAndSet(MmPagedPoolInfo.PagedPoolAllocationMap,
SizeInPages,
MmPagedPoolInfo.PagedPoolHint);
if (i == 0xFFFFFFFF)
{
//
// Out of memory!
//
DPRINT1("OUT OF PAGED POOL!!!\n");
KeReleaseGuardedMutex(&MmPagedPoolMutex);
return NULL;
}
//
// Update the pool hint if the request was just one page
//
if (SizeInPages == 1) MmPagedPoolInfo.PagedPoolHint = i + 1;
//
// Update the end bitmap so we know the bounds of this allocation when
// the time comes to free it
//
RtlSetBit(MmPagedPoolInfo.EndOfPagedPoolBitmap, i + SizeInPages - 1);
//
// Now we can release the lock (it mainly protects the bitmap)
//
KeReleaseGuardedMutex(&MmPagedPoolMutex);
//
// Now figure out where this allocation starts
//
BaseVa = (PVOID)((ULONG_PTR)MmPagedPoolStart + (i << PAGE_SHIFT));
//
// Flush the TLB
//
KeFlushEntireTb(TRUE, TRUE);
//
// Setup a demand-zero writable PTE
//
TempPte.u.Long = 0;
MI_MAKE_WRITE_PAGE(&TempPte);
//
// Find the first and last PTE, then loop them all
//
PointerPte = MiAddressToPte(BaseVa);
StartPte = PointerPte + SizeInPages;
do
{
//
// Write the demand zero PTE and keep going
//
*PointerPte++ = TempPte;
} while (PointerPte < StartPte);
//
// Return the allocation address to the caller
//
return BaseVa;
}
//
// Allocations of less than 4 pages go into their individual buckets
//
@@ -346,7 +423,57 @@ MiFreePoolPages(IN PVOID StartingVa)
PFN_NUMBER FreePages, NumberOfPages;
KIRQL OldIrql;
PMMFREE_POOL_ENTRY FreeEntry, NextEntry, LastEntry;
ULONG i;
ULONG i, End;
//
// Handle paged pool
//
if ((StartingVa >= MmPagedPoolStart) && (StartingVa <= MmPagedPoolEnd))
{
//
// Calculate the offset from the beginning of paged pool, and convert it
// into pages
//
i = ((ULONG_PTR)StartingVa - (ULONG_PTR)MmPagedPoolStart) >> PAGE_SHIFT;
End = i;
//
// Now use the end bitmap to scan until we find a set bit, meaning that
// this allocation finishes here
//
while (!RtlTestBit(MmPagedPoolInfo.EndOfPagedPoolBitmap, End)) End++;
//
// Now calculate the total number of pages this allocation spans
//
NumberOfPages = End - i + 1;
//
// Acquire the paged pool lock
//
KeAcquireGuardedMutex(&MmPagedPoolMutex);
//
// Clear the allocation and free bits
//
RtlClearBit(MmPagedPoolInfo.EndOfPagedPoolBitmap, i);
RtlClearBits(MmPagedPoolInfo.PagedPoolAllocationMap, i, NumberOfPages);
//
// Update the hint if we need to
//
if (i < MmPagedPoolInfo.PagedPoolHint) MmPagedPoolInfo.PagedPoolHint = i;
//
// Release the lock protecting the bitmaps
//
KeReleaseGuardedMutex(&MmPagedPoolMutex);
//
// And finally return the number of pages freed
//
return NumberOfPages;
}
//
// Get the first PTE and its corresponding PFN entry
+59
View File
@@ -353,6 +353,65 @@ MmInitSystem(IN ULONG Phase,
/* Intialize system memory areas */
MiInitSystemMemoryAreas();
//
// STEP 1: Allocate and free a single page, repeatedly
// We should always get the same address back
//
if (1)
{
PULONG Test, OldTest;
ULONG i;
OldTest = Test = MiAllocatePoolPages(PagedPool, PAGE_SIZE);
ASSERT(Test);
for (i = 0; i < 16; i++)
{
MiFreePoolPages(Test);
Test = MiAllocatePoolPages(PagedPool, PAGE_SIZE);
ASSERT(OldTest == Test);
}
MiFreePoolPages(Test);
}
//
// STEP 2: Allocate 2048 pages without freeing them
// We should run out of space at 1024 pages, since we don't support
// expansion yet.
//
if (1)
{
PULONG Test[2048];
ULONG i;
for (i = 0; i < 2048; i++)
{
Test[i] = MiAllocatePoolPages(PagedPool, PAGE_SIZE);
if (!Test[i])
{
ASSERT(i == 1024);
break;
}
}
//
// Cleanup
//
while (--i) if (Test[i]) MiFreePoolPages(Test[i]);
}
//
// STEP 3: Allocate a page and touch it.
// We should get an ARM3 page fault and it should handle the fault
//
if (0) // NOT YET IMPLEMENTED
{
PULONG Test;
Test = MiAllocatePoolPages(PagedPool, PAGE_SIZE);
DPRINT1("Value: %lx", *Test);
MiFreePoolPages(Test);
}
/* Dump the address space */
MiDbgDumpAddressSpace();