1*c2c66affSColin Finck /* 2*c2c66affSColin Finck * PROJECT: ReactOS Kernel 3*c2c66affSColin Finck * LICENSE: BSD - See COPYING.ARM in the top level directory 4*c2c66affSColin Finck * FILE: ntoskrnl/mm/ARM3/zeropage.c 5*c2c66affSColin Finck * PURPOSE: ARM Memory Manager Zero Page Thread Support 6*c2c66affSColin Finck * PROGRAMMERS: ReactOS Portable Systems Group 7*c2c66affSColin Finck */ 8*c2c66affSColin Finck 9*c2c66affSColin Finck /* INCLUDES *******************************************************************/ 10*c2c66affSColin Finck 11*c2c66affSColin Finck #include <ntoskrnl.h> 12*c2c66affSColin Finck #define NDEBUG 13*c2c66affSColin Finck #include <debug.h> 14*c2c66affSColin Finck 15*c2c66affSColin Finck #define MODULE_INVOLVED_IN_ARM3 16*c2c66affSColin Finck #include <mm/ARM3/miarm.h> 17*c2c66affSColin Finck 18*c2c66affSColin Finck /* GLOBALS ********************************************************************/ 19*c2c66affSColin Finck 20*c2c66affSColin Finck BOOLEAN MmZeroingPageThreadActive; 21*c2c66affSColin Finck KEVENT MmZeroingPageEvent; 22*c2c66affSColin Finck 23*c2c66affSColin Finck /* PRIVATE FUNCTIONS **********************************************************/ 24*c2c66affSColin Finck 25*c2c66affSColin Finck VOID 26*c2c66affSColin Finck NTAPI 27*c2c66affSColin Finck MiFindInitializationCode(OUT PVOID *StartVa, 28*c2c66affSColin Finck OUT PVOID *EndVa); 29*c2c66affSColin Finck 30*c2c66affSColin Finck VOID 31*c2c66affSColin Finck NTAPI 32*c2c66affSColin Finck MiFreeInitializationCode(IN PVOID StartVa, 33*c2c66affSColin Finck IN PVOID EndVa); 34*c2c66affSColin Finck 35*c2c66affSColin Finck VOID 36*c2c66affSColin Finck NTAPI 37*c2c66affSColin Finck MmZeroPageThread(VOID) 38*c2c66affSColin Finck { 39*c2c66affSColin Finck PKTHREAD Thread = KeGetCurrentThread(); 40*c2c66affSColin Finck PVOID StartAddress, EndAddress; 41*c2c66affSColin Finck PVOID WaitObjects[2]; 42*c2c66affSColin Finck KIRQL OldIrql; 43*c2c66affSColin Finck PVOID ZeroAddress; 44*c2c66affSColin Finck PFN_NUMBER PageIndex, FreePage; 45*c2c66affSColin Finck PMMPFN Pfn1; 46*c2c66affSColin Finck 47*c2c66affSColin Finck /* Get the discardable sections to free them */ 48*c2c66affSColin Finck MiFindInitializationCode(&StartAddress, &EndAddress); 49*c2c66affSColin Finck if (StartAddress) MiFreeInitializationCode(StartAddress, EndAddress); 50*c2c66affSColin Finck DPRINT("Free non-cache pages: %lx\n", MmAvailablePages + MiMemoryConsumers[MC_CACHE].PagesUsed); 51*c2c66affSColin Finck 52*c2c66affSColin Finck /* Set our priority to 0 */ 53*c2c66affSColin Finck Thread->BasePriority = 0; 54*c2c66affSColin Finck KeSetPriorityThread(Thread, 0); 55*c2c66affSColin Finck 56*c2c66affSColin Finck /* Setup the wait objects */ 57*c2c66affSColin Finck WaitObjects[0] = &MmZeroingPageEvent; 58*c2c66affSColin Finck // WaitObjects[1] = &PoSystemIdleTimer; FIXME: Implement idle timer 59*c2c66affSColin Finck 60*c2c66affSColin Finck while (TRUE) 61*c2c66affSColin Finck { 62*c2c66affSColin Finck KeWaitForMultipleObjects(1, // 2 63*c2c66affSColin Finck WaitObjects, 64*c2c66affSColin Finck WaitAny, 65*c2c66affSColin Finck WrFreePage, 66*c2c66affSColin Finck KernelMode, 67*c2c66affSColin Finck FALSE, 68*c2c66affSColin Finck NULL, 69*c2c66affSColin Finck NULL); 70*c2c66affSColin Finck OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); 71*c2c66affSColin Finck MmZeroingPageThreadActive = TRUE; 72*c2c66affSColin Finck 73*c2c66affSColin Finck while (TRUE) 74*c2c66affSColin Finck { 75*c2c66affSColin Finck if (!MmFreePageListHead.Total) 76*c2c66affSColin Finck { 77*c2c66affSColin Finck MmZeroingPageThreadActive = FALSE; 78*c2c66affSColin Finck KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql); 79*c2c66affSColin Finck break; 80*c2c66affSColin Finck } 81*c2c66affSColin Finck 82*c2c66affSColin Finck PageIndex = MmFreePageListHead.Flink; 83*c2c66affSColin Finck ASSERT(PageIndex != LIST_HEAD); 84*c2c66affSColin Finck Pfn1 = MiGetPfnEntry(PageIndex); 85*c2c66affSColin Finck MI_SET_USAGE(MI_USAGE_ZERO_LOOP); 86*c2c66affSColin Finck MI_SET_PROCESS2("Kernel 0 Loop"); 87*c2c66affSColin Finck FreePage = MiRemoveAnyPage(MI_GET_PAGE_COLOR(PageIndex)); 88*c2c66affSColin Finck 89*c2c66affSColin Finck /* The first global free page should also be the first on its own list */ 90*c2c66affSColin Finck if (FreePage != PageIndex) 91*c2c66affSColin Finck { 92*c2c66affSColin Finck KeBugCheckEx(PFN_LIST_CORRUPT, 93*c2c66affSColin Finck 0x8F, 94*c2c66affSColin Finck FreePage, 95*c2c66affSColin Finck PageIndex, 96*c2c66affSColin Finck 0); 97*c2c66affSColin Finck } 98*c2c66affSColin Finck 99*c2c66affSColin Finck Pfn1->u1.Flink = LIST_HEAD; 100*c2c66affSColin Finck KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql); 101*c2c66affSColin Finck 102*c2c66affSColin Finck ZeroAddress = MiMapPagesInZeroSpace(Pfn1, 1); 103*c2c66affSColin Finck ASSERT(ZeroAddress); 104*c2c66affSColin Finck RtlZeroMemory(ZeroAddress, PAGE_SIZE); 105*c2c66affSColin Finck MiUnmapPagesInZeroSpace(ZeroAddress, 1); 106*c2c66affSColin Finck 107*c2c66affSColin Finck OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); 108*c2c66affSColin Finck 109*c2c66affSColin Finck MiInsertPageInList(&MmZeroedPageListHead, PageIndex); 110*c2c66affSColin Finck } 111*c2c66affSColin Finck } 112*c2c66affSColin Finck } 113*c2c66affSColin Finck 114*c2c66affSColin Finck /* EOF */ 115