#define _1KB (1024)
#define _1MB (1024 * _1KB)
-/* Are mapped by a PDE */
+/* Area mapped by a PDE */
#define PDE_MAPPED_VA (PTE_COUNT * PAGE_SIZE)
/* Size of a PDE directory, and size of a page table */
#define MM_DECOMMIT 0x10
#define MM_NOACCESS (MM_DECOMMIT | MM_NOCACHE)
+//
+// Assertions for session images, addresses, and PTEs
+//
+#define MI_IS_SESSION_IMAGE_ADDRESS(Address) \
+ (((Address) >= MiSessionImageStart) && ((Address) < MiSessionImageEnd))
+
+#define MI_IS_SESSION_ADDRESS(Address) \
+ (((Address) >= MmSessionBase) && ((Address) < MiSessionSpaceEnd))
+
+#define MI_IS_SESSION_PTE(Pte) \
+ ((((PMMPTE)Pte) >= MiSessionBasePte) && (((PMMPTE)Pte) < MiSessionLastPte))
+
//
// Corresponds to MMPTE_SOFTWARE.Protection
//
//
#define LIST_HEAD 0xFFFFFFFF
+//
+// Special IRQL value (found in assertions)
+//
+#define MM_NOIRQL (KIRQL)0xFFFFFFFF
+
//
// FIXFIX: These should go in ex.h after the pool merge
//
extern ULONG MmSystemViewSize;
extern PVOID MmSessionBase;
extern PVOID MiSessionSpaceEnd;
+extern PMMPTE MiSessionImagePteStart;
+extern PMMPTE MiSessionImagePteEnd;
+extern PMMPTE MiSessionBasePte;
+extern PMMPTE MiSessionLastPte;
extern ULONG MmSizeOfPagedPoolInBytes;
extern PMMPTE MmSystemPagePtes;
extern PVOID MmSystemCacheStart;
extern PFN_NUMBER MmTotalSystemDriverPages;
extern PVOID MiSessionImageStart;
extern PVOID MiSessionImageEnd;
+extern PMMPTE MiHighestUserPte;
+extern PMMPDE MiHighestUserPde;
+extern PFN_NUMBER MmSystemPageDirectory[PD_COUNT];
#define MI_PFN_TO_PFNENTRY(x) (&MmPfnDatabase[1][x])
#define MI_PFNENTRY_TO_PFN(x) (x - MmPfnDatabase[1])
-#define MI_IS_SESSION_IMAGE_ADDRESS(Address) \
- (((Address) >= MiSessionImageStart) && ((Address) < MiSessionImageEnd))
-
-#define MI_IS_SESSION_ADDRESS(Address) \
- (((Address) >= MmSessionBase) && ((Address) < MiSessionSpaceEnd))
-
+//
+// Returns if the page is physically resident (ie: a large page)
+// FIXFIX: CISC/x86 only?
+//
FORCEINLINE
BOOLEAN
MI_IS_PHYSICAL_ADDRESS(IN PVOID Address)
PMMPDE PointerPde;
NTSTATUS Status = STATUS_SUCCESS;
+ /* No session support in ReactOS yet */
+ ASSERT(MI_IS_SESSION_ADDRESS(Address) == FALSE);
+ ASSERT(MI_IS_SESSION_PTE(Address) == FALSE);
+
//
// Check if this is a fault while trying to access the page table itself
//
//
if (PointerPde->u.Hard.Valid == 0)
{
+ /* This seems to be making the assumption that one PDE is one page long */
+ ASSERT(PAGE_SIZE == (PD_COUNT * (sizeof(MMPTE) * PDE_COUNT)));
+
//
// Copy it from our double-mapped system page directory
//
Address,
Process);
+ /* Must currently only be called by paging path, for system addresses only */
+ ASSERT(OldIrql == MM_NOIRQL);
+ ASSERT(Process == NULL);
+
//
// Lock the PFN database
//
//
InterlockedIncrement(&KeGetCurrentPrcb()->MmDemandZeroCount);
+ /* Shouldn't see faults for user PTEs yet */
+ ASSERT(PointerPte > MiHighestUserPte);
+
//
// Build the PTE
//
TempPte = ValidKernelPte;
TempPte.u.Hard.PageFrameNumber = PageFrameNumber;
+ ASSERT(TempPte.u.Hard.Valid == 1);
+ ASSERT(PointerPte->u.Hard.Valid == 0);
*PointerPte = TempPte;
ASSERT(PointerPte->u.Hard.Valid == 1);
//
TempPte = *PointerPte;
+ /* No prototype */
+ ASSERT(PrototypePte == NULL);
+
//
// The PTE must be invalid, but not totally blank
//
Status = MiResolveDemandZeroFault(Address,
PointerPte,
Process,
- -1);
+ MM_NOIRQL);
+ ASSERT(KeAreAllApcsDisabled () == TRUE);
if (NT_SUCCESS(Status))
{
//
//
// Save it into our double-buffered system page directory
//
+ /* This seems to be making the assumption that one PDE is one page long */
+ ASSERT(PAGE_SIZE == (PD_COUNT * (sizeof(MMPTE) * PDE_COUNT)));
MmSystemPagePtes[(ULONG_PTR)PointerPte & (PAGE_SIZE - 1) /
sizeof(MMPTE)] = TempPte;
- //
- // Write the actual PTE now
- //
+ /* Write the actual PTE now */
+ ASSERT(TempPte.u.Hard.Valid == 1);
*PointerPte++ = TempPte;
//
//
// Write the demand zero PTE and keep going
//
+ ASSERT(PointerPte->u.Hard.Valid == 0);
*PointerPte++ = TempPte;
} while (PointerPte < StartPte);