[NTOSKRNL] Define the Mm global variables related to Cc on Mm init.
[reactos.git] / ntoskrnl / mm / mminit.c
1 /*
2 * PROJECT: ReactOS Kernel
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: ntoskrnl/mm/mminit.c
5 * PURPOSE: Memory Manager Initialization
6 * PROGRAMMERS:
7 */
8
9 /* INCLUDES ******************************************************************/
10
11 #include <ntoskrnl.h>
12 #define NDEBUG
13 #include <debug.h>
14
15 #define MODULE_INVOLVED_IN_ARM3
16 #include "ARM3/miarm.h"
17
18 /* GLOBALS *******************************************************************/
19
20 VOID NTAPI MiInitializeUserPfnBitmap(VOID);
21
22 BOOLEAN Mm64BitPhysicalAddress = FALSE;
23 ULONG MmReadClusterSize;
24 //
25 // 0 | 1 is on/off paging, 2 is undocumented
26 //
27 UCHAR MmDisablePagingExecutive = 1; // Forced to off
28 PMMPTE MmSharedUserDataPte;
29 PMMSUPPORT MmKernelAddressSpace;
30
31 extern KEVENT MmWaitPageEvent;
32 extern FAST_MUTEX MiGlobalPageOperation;
33 extern LIST_ENTRY MiSegmentList;
34 extern NTSTATUS MiRosTrimCache(ULONG Target, ULONG Priority, PULONG NrFreed);
35
36 /* PRIVATE FUNCTIONS *********************************************************/
37
38 //
39 // Helper function to create initial memory areas.
40 // The created area is always read/write.
41 //
42 VOID
43 INIT_FUNCTION
44 NTAPI
45 MiCreateArm3StaticMemoryArea(PVOID BaseAddress, SIZE_T Size, BOOLEAN Executable)
46 {
47 const ULONG Protection = Executable ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE;
48 PVOID pBaseAddress = BaseAddress;
49 PMEMORY_AREA MArea;
50 NTSTATUS Status;
51
52 Status = MmCreateMemoryArea(MmGetKernelAddressSpace(),
53 MEMORY_AREA_OWNED_BY_ARM3 | MEMORY_AREA_STATIC,
54 &pBaseAddress,
55 Size,
56 Protection,
57 &MArea,
58 0,
59 PAGE_SIZE);
60 ASSERT(Status == STATUS_SUCCESS);
61 // TODO: Perhaps it would be prudent to bugcheck here, not only assert?
62 }
63
64 VOID
65 INIT_FUNCTION
66 NTAPI
67 MiInitSystemMemoryAreas(VOID)
68 {
69 //
70 // Create all the static memory areas.
71 //
72
73 // The loader mappings. The only Executable area.
74 MiCreateArm3StaticMemoryArea((PVOID)KSEG0_BASE, MmBootImageSize, TRUE);
75
76 // The PTE base
77 MiCreateArm3StaticMemoryArea((PVOID)PTE_BASE, PTE_TOP - PTE_BASE + 1, FALSE);
78
79 // Hyperspace
80 MiCreateArm3StaticMemoryArea((PVOID)HYPER_SPACE, HYPER_SPACE_END - HYPER_SPACE + 1, FALSE);
81
82 // Protect the PFN database
83 MiCreateArm3StaticMemoryArea(MmPfnDatabase, (MxPfnAllocation << PAGE_SHIFT), FALSE);
84
85 // ReactOS requires a memory area to keep the initial NP area off-bounds
86 MiCreateArm3StaticMemoryArea(MmNonPagedPoolStart, MmSizeOfNonPagedPoolInBytes, FALSE);
87
88 // System PTE space
89 MiCreateArm3StaticMemoryArea(MmNonPagedSystemStart, (MmNumberOfSystemPtes + 1) * PAGE_SIZE, FALSE);
90
91 // Nonpaged pool expansion space
92 MiCreateArm3StaticMemoryArea(MmNonPagedPoolExpansionStart, (ULONG_PTR)MmNonPagedPoolEnd - (ULONG_PTR)MmNonPagedPoolExpansionStart, FALSE);
93
94 // System view space
95 MiCreateArm3StaticMemoryArea(MiSystemViewStart, MmSystemViewSize, FALSE);
96
97 // Session space
98 MiCreateArm3StaticMemoryArea(MmSessionBase, (ULONG_PTR)MiSessionSpaceEnd - (ULONG_PTR)MmSessionBase, FALSE);
99
100 // Paged pool
101 MiCreateArm3StaticMemoryArea(MmPagedPoolStart, MmSizeOfPagedPoolInBytes, FALSE);
102
103 // Debugger mapping
104 MiCreateArm3StaticMemoryArea(MI_DEBUG_MAPPING, PAGE_SIZE, FALSE);
105
106 #if defined(_X86_)
107 // Reserved HAL area (includes KUSER_SHARED_DATA and KPCR)
108 MiCreateArm3StaticMemoryArea((PVOID)MM_HAL_VA_START, MM_HAL_VA_END - MM_HAL_VA_START + 1, FALSE);
109 #else /* _X86_ */
110 #ifndef _M_AMD64
111 // KPCR, one page per CPU. Only for 32-bit kernel.
112 MiCreateArm3StaticMemoryArea(PCR, PAGE_SIZE * KeNumberProcessors, FALSE);
113 #endif /* _M_AMD64 */
114
115 // KUSER_SHARED_DATA
116 MiCreateArm3StaticMemoryArea((PVOID)KI_USER_SHARED_DATA, PAGE_SIZE, FALSE);
117 #endif /* _X86_ */
118 }
119
120 VOID
121 NTAPI
122 INIT_FUNCTION
123 MiDbgDumpAddressSpace(VOID)
124 {
125 //
126 // Print the memory layout
127 //
128 DPRINT1(" 0x%p - 0x%p\t%s\n",
129 KSEG0_BASE,
130 (ULONG_PTR)KSEG0_BASE + MmBootImageSize,
131 "Boot Loaded Image");
132 DPRINT1(" 0x%p - 0x%p\t%s\n",
133 MmPfnDatabase,
134 (ULONG_PTR)MmPfnDatabase + (MxPfnAllocation << PAGE_SHIFT),
135 "PFN Database");
136 DPRINT1(" 0x%p - 0x%p\t%s\n",
137 MmNonPagedPoolStart,
138 (ULONG_PTR)MmNonPagedPoolStart + MmSizeOfNonPagedPoolInBytes,
139 "ARM3 Non Paged Pool");
140 DPRINT1(" 0x%p - 0x%p\t%s\n",
141 MiSystemViewStart,
142 (ULONG_PTR)MiSystemViewStart + MmSystemViewSize,
143 "System View Space");
144 DPRINT1(" 0x%p - 0x%p\t%s\n",
145 MmSessionBase,
146 MiSessionSpaceEnd,
147 "Session Space");
148 DPRINT1(" 0x%p - 0x%p\t%s\n",
149 PTE_BASE, PTE_TOP,
150 "Page Tables");
151 DPRINT1(" 0x%p - 0x%p\t%s\n",
152 PDE_BASE, PDE_TOP,
153 "Page Directories");
154 DPRINT1(" 0x%p - 0x%p\t%s\n",
155 HYPER_SPACE, HYPER_SPACE_END,
156 "Hyperspace");
157 DPRINT1(" 0x%p - 0x%p\t%s\n",
158 MmSystemCacheStart, MmSystemCacheEnd,
159 "System Cache");
160 DPRINT1(" 0x%p - 0x%p\t%s\n",
161 MmPagedPoolStart,
162 (ULONG_PTR)MmPagedPoolStart + MmSizeOfPagedPoolInBytes,
163 "ARM3 Paged Pool");
164 DPRINT1(" 0x%p - 0x%p\t%s\n",
165 MmNonPagedSystemStart, MmNonPagedPoolExpansionStart,
166 "System PTE Space");
167 DPRINT1(" 0x%p - 0x%p\t%s\n",
168 MmNonPagedPoolExpansionStart, MmNonPagedPoolEnd,
169 "Non Paged Pool Expansion PTE Space");
170 }
171
172 NTSTATUS
173 NTAPI
174 INIT_FUNCTION
175 MmInitBsmThread(VOID)
176 {
177 NTSTATUS Status;
178 OBJECT_ATTRIBUTES ObjectAttributes;
179 HANDLE ThreadHandle;
180
181 /* Create the thread */
182 InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL);
183 Status = PsCreateSystemThread(&ThreadHandle,
184 THREAD_ALL_ACCESS,
185 &ObjectAttributes,
186 NULL,
187 NULL,
188 KeBalanceSetManager,
189 NULL);
190
191 /* Close the handle and return status */
192 ZwClose(ThreadHandle);
193 return Status;
194 }
195
196 BOOLEAN
197 NTAPI
198 INIT_FUNCTION
199 MmInitSystem(IN ULONG Phase,
200 IN PLOADER_PARAMETER_BLOCK LoaderBlock)
201 {
202 extern MMPTE ValidKernelPte;
203 PMMPTE PointerPte;
204 MMPTE TempPte = ValidKernelPte;
205 PFN_NUMBER PageFrameNumber;
206
207 /* Initialize the kernel address space */
208 ASSERT(Phase == 1);
209
210 InitializeListHead(&MiSegmentList);
211 ExInitializeFastMutex(&MiGlobalPageOperation);
212 KeInitializeEvent(&MmWaitPageEvent, SynchronizationEvent, FALSE);
213 // Until we're fully demand paged, we can do things the old way through
214 // the balance manager
215 MmInitializeMemoryConsumer(MC_CACHE, MiRosTrimCache);
216
217 MmKernelAddressSpace = &PsIdleProcess->Vm;
218
219 /* Intialize system memory areas */
220 MiInitSystemMemoryAreas();
221
222 /* Dump the address space */
223 MiDbgDumpAddressSpace();
224
225 MmInitGlobalKernelPageDirectory();
226 MiInitializeUserPfnBitmap();
227 MmInitializeMemoryConsumer(MC_USER, MmTrimUserMemory);
228 MmInitializeRmapList();
229 MmInitSectionImplementation();
230 MmInitPagingFile();
231
232 //
233 // Create a PTE to double-map the shared data section. We allocate it
234 // from paged pool so that we can't fault when trying to touch the PTE
235 // itself (to map it), since paged pool addresses will already be mapped
236 // by the fault handler.
237 //
238 MmSharedUserDataPte = ExAllocatePoolWithTag(PagedPool,
239 sizeof(MMPTE),
240 TAG_MM);
241 if (!MmSharedUserDataPte) return FALSE;
242
243 //
244 // Now get the PTE for shared data, and read the PFN that holds it
245 //
246 PointerPte = MiAddressToPte((PVOID)KI_USER_SHARED_DATA);
247 ASSERT(PointerPte->u.Hard.Valid == 1);
248 PageFrameNumber = PFN_FROM_PTE(PointerPte);
249
250 /* Build the PTE and write it */
251 MI_MAKE_HARDWARE_PTE_KERNEL(&TempPte,
252 PointerPte,
253 MM_READONLY,
254 PageFrameNumber);
255 *MmSharedUserDataPte = TempPte;
256
257 /* Initialize session working set support */
258 MiInitializeSessionWsSupport();
259
260 /* Setup session IDs */
261 MiInitializeSessionIds();
262
263 /* Setup the memory threshold events */
264 if (!MiInitializeMemoryEvents()) return FALSE;
265
266 /*
267 * Unmap low memory
268 */
269 MiInitBalancerThread();
270
271 /* Initialize the balance set manager */
272 MmInitBsmThread();
273
274 return TRUE;
275 }
276