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