xref: /reactos/ntoskrnl/mm/ARM3/zeropage.c (revision c2c66aff)
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