- Initialize nonpaged pool expansion system PTEs (MiInitializeSystemPtes):
[reactos.git] / reactos / ntoskrnl / mm / ARM3 / pool.c
1 /*
2 * PROJECT: ReactOS Kernel
3 * LICENSE: BSD - See COPYING.ARM in the top level directory
4 * FILE: ntoskrnl/mm/ARM3/pool.c
5 * PURPOSE: ARM Memory Manager Pool Allocator
6 * PROGRAMMERS: ReactOS Portable Systems Group
7 */
8
9 /* INCLUDES *******************************************************************/
10
11 #include <ntoskrnl.h>
12 #define NDEBUG
13 #include <debug.h>
14
15 #line 15 "ARMĀ³::POOL"
16 #define MODULE_INVOLVED_IN_ARM3
17 #include "../ARM3/miarm.h"
18
19 /* GLOBALS ********************************************************************/
20
21 LIST_ENTRY MmNonPagedPoolFreeListHead[MI_MAX_FREE_PAGE_LISTS];
22 PFN_NUMBER MmNumberOfFreeNonPagedPool, MiExpansionPoolPagesInitialCharge;
23 PVOID MmNonPagedPoolEnd0;
24 PFN_NUMBER MiStartOfInitialPoolFrame, MiEndOfInitialPoolFrame;
25
26 /* PRIVATE FUNCTIONS **********************************************************/
27
28 VOID
29 NTAPI
30 MiInitializeArmPool(VOID)
31 {
32 ULONG i;
33 PFN_NUMBER PoolPages;
34 PMMFREE_POOL_ENTRY FreeEntry, FirstEntry;
35 PMMPTE PointerPte;
36 PAGED_CODE();
37
38 //
39 // We keep 4 lists of free pages (4 lists help avoid contention)
40 //
41 for (i = 0; i < MI_MAX_FREE_PAGE_LISTS; i++)
42 {
43 //
44 // Initialize each of them
45 //
46 InitializeListHead(&MmNonPagedPoolFreeListHead[i]);
47 }
48
49 //
50 // Calculate how many pages the initial nonpaged pool has
51 //
52 PoolPages = BYTES_TO_PAGES(MmSizeOfNonPagedPoolInBytes);
53 MmNumberOfFreeNonPagedPool = PoolPages;
54
55 //
56 // Initialize the first free entry
57 //
58 FreeEntry = MmNonPagedPoolStart;
59 FirstEntry = FreeEntry;
60 FreeEntry->Size = PoolPages;
61 FreeEntry->Owner = FirstEntry;
62
63 //
64 // Insert it into the last list
65 //
66 InsertHeadList(&MmNonPagedPoolFreeListHead[MI_MAX_FREE_PAGE_LISTS - 1],
67 &FreeEntry->List);
68
69 //
70 // Now create free entries for every single other page
71 //
72 while (PoolPages-- > 1)
73 {
74 //
75 // Link them all back to the original entry
76 //
77 FreeEntry = (PMMFREE_POOL_ENTRY)((ULONG_PTR)FreeEntry + PAGE_SIZE);
78 FreeEntry->Owner = FirstEntry;
79 }
80
81 //
82 // Validate and remember first allocated pool page
83 //
84 PointerPte = MiAddressToPte(MmNonPagedPoolStart);
85 ASSERT(PointerPte->u.Hard.Valid == 1);
86 MiStartOfInitialPoolFrame = PFN_FROM_PTE(PointerPte);
87
88 //
89 // Keep track of where initial nonpaged pool ends
90 //
91 MmNonPagedPoolEnd0 = (PVOID)((ULONG_PTR)MmNonPagedPoolStart +
92 MmSizeOfNonPagedPoolInBytes);
93
94 //
95 // Validate and remember last allocated pool page
96 //
97 PointerPte = MiAddressToPte((PVOID)((ULONG_PTR)MmNonPagedPoolEnd0 - 1));
98 ASSERT(PointerPte->u.Hard.Valid == 1);
99 MiEndOfInitialPoolFrame = PFN_FROM_PTE(PointerPte);
100
101 //
102 // Validate the first nonpaged pool expansion page (which is a guard page)
103 //
104 PointerPte = MiAddressToPte(MmNonPagedPoolExpansionStart);
105 ASSERT(PointerPte->u.Hard.Valid == 0);
106
107 //
108 // Calculate the size of the expansion region alone
109 //
110 MiExpansionPoolPagesInitialCharge =
111 BYTES_TO_PAGES(MmMaximumNonPagedPoolInBytes - MmSizeOfNonPagedPoolInBytes);
112
113 //
114 // Remove 2 pages, since there's a guard page on top and on the bottom
115 //
116 MiExpansionPoolPagesInitialCharge -= 2;
117
118 //
119 // Now initialize the nonpaged pool expansion PTE space. Remember there's a
120 // guard page on top so make sure to skip it. The bottom guard page will be
121 // guaranteed by the fact our size is off by one.
122 //
123 MiInitializeSystemPtes(PointerPte + 1,
124 MiExpansionPoolPagesInitialCharge,
125 NonPagedPoolExpansion);
126 }
127
128 /* EOF */