#define NDEBUG
#include <debug.h>
-#if defined (ALLOC_PRAGMA)
-#pragma alloc_text(INIT, MmInitializePageList)
-#endif
-
#define MODULE_INVOLVED_IN_ARM3
#include "ARM3/miarm.h"
-/* GLOBALS ****************************************************************/
+#define ASSERT_IS_ROS_PFN(x) ASSERT(MI_IS_ROS_PFN(x) == TRUE);
-// ReactOS to NT Physical Page Descriptor Entry Legacy Mapping Definitions
-#define PHYSICAL_PAGE MMPFN
-#define PPHYSICAL_PAGE PMMPFN
+/* GLOBALS ****************************************************************/
-PPHYSICAL_PAGE MmPfnDatabase;
+PMMPFN MmPfnDatabase;
PFN_NUMBER MmAvailablePages;
PFN_NUMBER MmResidentAvailablePages;
/* Allocate enough buffer for the PFN bitmap and align it on 32-bits */
Bitmap = ExAllocatePoolWithTag(NonPagedPool,
(((MmHighestPhysicalPage + 1) + 31) / 32) * 4,
- ' mM');
+ TAG_MM);
ASSERT(Bitmap);
/* Initialize it and clear all the bits to begin with */
KIRQL OldIrql;
/* Find the first user page */
- OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
+ OldIrql = MiAcquirePfnLock();
Position = RtlFindSetBits(&MiUserPfnBitMap, 1, 0);
- KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
+ MiReleasePfnLock(OldIrql);
if (Position == 0xFFFFFFFF) return 0;
/* Return it */
ASSERT(Pfn != 0);
ASSERT_IS_ROS_PFN(MiGetPfnEntry(Pfn));
ASSERT(!RtlCheckBit(&MiUserPfnBitMap, (ULONG)Pfn));
- OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
+ OldIrql = MiAcquirePfnLock();
RtlSetBit(&MiUserPfnBitMap, (ULONG)Pfn);
- KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
+ MiReleasePfnLock(OldIrql);
}
PFN_NUMBER
KIRQL OldIrql;
/* Find the next user page */
- OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
+ OldIrql = MiAcquirePfnLock();
Position = RtlFindSetBits(&MiUserPfnBitMap, 1, (ULONG)PreviousPfn + 1);
- KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
+ MiReleasePfnLock(OldIrql);
if (Position == 0xFFFFFFFF) return 0;
/* Return it */
ASSERT(Page != 0);
ASSERT_IS_ROS_PFN(MiGetPfnEntry(Page));
ASSERT(RtlCheckBit(&MiUserPfnBitMap, (ULONG)Page));
- OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
+ OldIrql = MiAcquirePfnLock();
RtlClearBit(&MiUserPfnBitMap, (ULONG)Page);
- KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
+ MiReleasePfnLock(OldIrql);
}
BOOLEAN
PFN_NUMBER PageCount, LowPage, HighPage, SkipPages, PagesFound = 0, Page;
PPFN_NUMBER MdlPage, LastMdlPage;
KIRQL OldIrql;
- PPHYSICAL_PAGE Pfn1;
+ PMMPFN Pfn1;
INT LookForZeroedPages;
ASSERT(KeGetCurrentIrql() <= APC_LEVEL);
+ DPRINT1("ARM3-DEBUG: Being called with %I64x %I64x %I64x %lx %d %lu\n", LowAddress, HighAddress, SkipBytes, TotalBytes, CacheAttribute, MdlFlags);
//
// Convert the low address into a PFN
//
// Lock the PFN database
//
- OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
+ OldIrql = MiAcquirePfnLock();
//
// Are we looking for any pages, without discriminating?
/* Grab a page */
MI_SET_USAGE(MI_USAGE_MDL);
MI_SET_PROCESS2("Kernel");
- Page = MiRemoveAnyPage(0);
+
+ /* FIXME: This check should be smarter */
+ Page = 0;
+ if (MmAvailablePages != 0)
+ Page = MiRemoveAnyPage(0);
+
if (Page == 0)
{
/* This is not good... hopefully we have at least SOME pages */
//
// Now release the PFN count
//
- KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
+ MiReleasePfnLock(OldIrql);
//
// We might've found less pages, but not more ;-)
// If we didn' tfind any pages at all, fail
//
DPRINT1("NO MDL PAGES!\n");
- ExFreePool(Mdl);
+ ExFreePoolWithTag(Mdl, TAG_MDL);
return NULL;
}
KIRQL oldIrql;
PMMPFN Pfn1;
- oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
+ oldIrql = MiAcquirePfnLock();
Pfn1 = MiGetPfnEntry(Pfn);
ASSERT(Pfn1);
ASSERT_IS_ROS_PFN(Pfn1);
ASSERT(MiIsPfnInUse(Pfn1) == TRUE);
/* Set the list head address */
- MI_GET_ROS_DATA(Pfn1)->RmapListHead = ListHead;
+ Pfn1->RmapListHead = ListHead;
}
else
{
ASSERT(MiIsPfnInUse(Pfn1) == TRUE);
/* In this case, the RMAP is actually being removed, so clear field */
- MI_GET_ROS_DATA(Pfn1)->RmapListHead = NULL;
+ Pfn1->RmapListHead = NULL;
/* ReactOS semantics will now release the page, which will make it free and enter a colored list */
}
- KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
+ MiReleasePfnLock(oldIrql);
}
PMM_RMAP_ENTRY
PMMPFN Pfn1;
/* Lock PFN database */
- oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
+ oldIrql = MiAcquirePfnLock();
/* Get the entry */
Pfn1 = MiGetPfnEntry(Pfn);
ASSERT_IS_ROS_PFN(Pfn1);
/* Get the list head */
- ListHead = MI_GET_ROS_DATA(Pfn1)->RmapListHead;
+ ListHead = Pfn1->RmapListHead;
/* Should not have an RMAP for a non-active page */
ASSERT(MiIsPfnInUse(Pfn1) == TRUE);
/* Release PFN database and return rmap list head */
- KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
+ MiReleasePfnLock(oldIrql);
return ListHead;
}
NTAPI
MmSetSavedSwapEntryPage(PFN_NUMBER Pfn, SWAPENTRY SwapEntry)
{
- KIRQL oldIrql;
- PPHYSICAL_PAGE Page;
+ KIRQL oldIrql;
+ PMMPFN Pfn1;
- Page = MiGetPfnEntry(Pfn);
- ASSERT(Page);
- ASSERT_IS_ROS_PFN(Page);
+ Pfn1 = MiGetPfnEntry(Pfn);
+ ASSERT(Pfn1);
+ ASSERT_IS_ROS_PFN(Pfn1);
- oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
- MI_GET_ROS_DATA(Page)->SwapEntry = SwapEntry;
- KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
+ oldIrql = MiAcquirePfnLock();
+ Pfn1->u1.SwapEntry = SwapEntry;
+ MiReleasePfnLock(oldIrql);
}
SWAPENTRY
NTAPI
MmGetSavedSwapEntryPage(PFN_NUMBER Pfn)
{
- SWAPENTRY SwapEntry;
- KIRQL oldIrql;
- PPHYSICAL_PAGE Page;
+ SWAPENTRY SwapEntry;
+ KIRQL oldIrql;
+ PMMPFN Pfn1;
- Page = MiGetPfnEntry(Pfn);
- ASSERT(Page);
- ASSERT_IS_ROS_PFN(Page);
+ Pfn1 = MiGetPfnEntry(Pfn);
+ ASSERT(Pfn1);
+ ASSERT_IS_ROS_PFN(Pfn1);
- oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
- SwapEntry = MI_GET_ROS_DATA(Page)->SwapEntry;
- KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
+ oldIrql = MiAcquirePfnLock();
+ SwapEntry = Pfn1->u1.SwapEntry;
+ MiReleasePfnLock(oldIrql);
- return(SwapEntry);
+ return(SwapEntry);
}
VOID
NTAPI
MmReferencePage(PFN_NUMBER Pfn)
{
- PPHYSICAL_PAGE Page;
+ PMMPFN Pfn1;
- DPRINT("MmReferencePage(PysicalAddress %x)\n", Pfn << PAGE_SHIFT);
+ DPRINT("MmReferencePage(PysicalAddress %x)\n", Pfn << PAGE_SHIFT);
- if (Pfn == 0 || Pfn > MmHighestPhysicalPage)
- {
- return;
- }
+ MI_ASSERT_PFN_LOCK_HELD();
+ ASSERT(Pfn != 0);
+ ASSERT(Pfn <= MmHighestPhysicalPage);
- Page = MiGetPfnEntry(Pfn);
- ASSERT(Page);
- ASSERT_IS_ROS_PFN(Page);
+ Pfn1 = MiGetPfnEntry(Pfn);
+ ASSERT(Pfn1);
+ ASSERT_IS_ROS_PFN(Pfn1);
- Page->u3.e2.ReferenceCount++;
+ ASSERT(Pfn1->u3.e2.ReferenceCount != 0);
+ Pfn1->u3.e2.ReferenceCount++;
}
ULONG
NTAPI
MmGetReferenceCountPage(PFN_NUMBER Pfn)
{
- KIRQL oldIrql;
- ULONG RCount;
- PPHYSICAL_PAGE Page;
+ KIRQL oldIrql;
+ ULONG RCount;
+ PMMPFN Pfn1;
- DPRINT("MmGetReferenceCountPage(PhysicalAddress %x)\n", Pfn << PAGE_SHIFT);
+ DPRINT("MmGetReferenceCountPage(PhysicalAddress %x)\n", Pfn << PAGE_SHIFT);
- oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
- Page = MiGetPfnEntry(Pfn);
- ASSERT(Page);
- ASSERT_IS_ROS_PFN(Page);
+ oldIrql = MiAcquirePfnLock();
+ Pfn1 = MiGetPfnEntry(Pfn);
+ ASSERT(Pfn1);
+ ASSERT_IS_ROS_PFN(Pfn1);
- RCount = Page->u3.e2.ReferenceCount;
+ RCount = Pfn1->u3.e2.ReferenceCount;
- KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
- return(RCount);
+ MiReleasePfnLock(oldIrql);
+ return(RCount);
}
BOOLEAN
NTAPI
MmDereferencePage(PFN_NUMBER Pfn)
{
- PPHYSICAL_PAGE Page;
- DPRINT("MmDereferencePage(PhysicalAddress %x)\n", Pfn << PAGE_SHIFT);
+ PMMPFN Pfn1;
+ KIRQL OldIrql;
+ DPRINT("MmDereferencePage(PhysicalAddress %x)\n", Pfn << PAGE_SHIFT);
- Page = MiGetPfnEntry(Pfn);
- ASSERT(Page);
- ASSERT_IS_ROS_PFN(Page);
+ OldIrql = MiAcquirePfnLock();
+
+ Pfn1 = MiGetPfnEntry(Pfn);
+ ASSERT(Pfn1);
+ ASSERT_IS_ROS_PFN(Pfn1);
- Page->u3.e2.ReferenceCount--;
- if (Page->u3.e2.ReferenceCount == 0)
- {
+ ASSERT(Pfn1->u3.e2.ReferenceCount != 0);
+ Pfn1->u3.e2.ReferenceCount--;
+ if (Pfn1->u3.e2.ReferenceCount == 0)
+ {
/* Mark the page temporarily as valid, we're going to make it free soon */
- Page->u3.e1.PageLocation = ActiveAndValid;
+ Pfn1->u3.e1.PageLocation = ActiveAndValid;
/* It's not a ROS PFN anymore */
- Page->u4.AweAllocation = FALSE;
- ExFreePool(MI_GET_ROS_DATA(Page));
- Page->RosMmData = 0;
+ Pfn1->u4.AweAllocation = FALSE;
/* Bring it back into the free list */
DPRINT("Legacy free: %lx\n", Pfn);
MiInsertPageInFreeList(Pfn);
- }
+ }
+
+ MiReleasePfnLock(OldIrql);
}
PFN_NUMBER
NTAPI
MmAllocPage(ULONG Type)
{
- PFN_NUMBER PfnOffset;
- PMMPFN Pfn1;
+ PFN_NUMBER PfnOffset;
+ PMMPFN Pfn1;
+ KIRQL OldIrql;
- PfnOffset = MiRemoveZeroPage(MI_GET_NEXT_COLOR());
+ OldIrql = MiAcquirePfnLock();
- if (!PfnOffset)
- {
- DPRINT1("MmAllocPage(): Out of memory\n");
- return 0;
- }
+ PfnOffset = MiRemoveZeroPage(MI_GET_NEXT_COLOR());
+ if (!PfnOffset)
+ {
+ KeBugCheck(NO_PAGES_AVAILABLE);
+ }
- DPRINT("Legacy allocate: %lx\n", PfnOffset);
- Pfn1 = MiGetPfnEntry(PfnOffset);
- Pfn1->u3.e2.ReferenceCount = 1;
- Pfn1->u3.e1.PageLocation = ActiveAndValid;
+ DPRINT("Legacy allocate: %lx\n", PfnOffset);
+ Pfn1 = MiGetPfnEntry(PfnOffset);
+ Pfn1->u3.e2.ReferenceCount = 1;
+ Pfn1->u3.e1.PageLocation = ActiveAndValid;
- /* This marks the PFN as a ReactOS PFN */
- Pfn1->u4.AweAllocation = TRUE;
+ /* This marks the PFN as a ReactOS PFN */
+ Pfn1->u4.AweAllocation = TRUE;
- /* Allocate the extra ReactOS Data and zero it out */
- Pfn1->RosMmData = (LONG)ExAllocatePoolWithTag(NonPagedPool, sizeof(MMROSPFN), 'RsPf');
- ASSERT(MI_GET_ROS_DATA(Pfn1) != NULL);
- ASSERT_IS_ROS_PFN(Pfn1);
- MI_GET_ROS_DATA(Pfn1)->SwapEntry = 0;
- MI_GET_ROS_DATA(Pfn1)->RmapListHead = NULL;
+ /* Allocate the extra ReactOS Data and zero it out */
+ Pfn1->u1.SwapEntry = 0;
+ Pfn1->RmapListHead = NULL;
- return PfnOffset;
+ MiReleasePfnLock(OldIrql);
+ return PfnOffset;
}
/* EOF */