[NTOS]: Combine ARM3 phase 0 and 1 even it means calling back into TurdMM for one...
[reactos.git] / reactos / 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 PCHAR
21 MemType[] =
22 {
23 "ExceptionBlock ",
24 "SystemBlock ",
25 "Free ",
26 "Bad ",
27 "LoadedProgram ",
28 "FirmwareTemporary ",
29 "FirmwarePermanent ",
30 "OsloaderHeap ",
31 "OsloaderStack ",
32 "SystemCode ",
33 "HalCode ",
34 "BootDriver ",
35 "ConsoleInDriver ",
36 "ConsoleOutDriver ",
37 "StartupDpcStack ",
38 "StartupKernelStack",
39 "StartupPanicStack ",
40 "StartupPcrPage ",
41 "StartupPdrPage ",
42 "RegistryData ",
43 "MemoryData ",
44 "NlsData ",
45 "SpecialMemory ",
46 "BBTMemory ",
47 "LoaderReserve ",
48 "LoaderXIPRom "
49 };
50
51 PBOOLEAN Mm64BitPhysicalAddress = FALSE;
52 ULONG MmReadClusterSize;
53 //
54 // 0 | 1 is on/off paging, 2 is undocumented
55 //
56 UCHAR MmDisablePagingExecutive = 1; // Forced to off
57 PMMPTE MmSharedUserDataPte;
58 PMMSUPPORT MmKernelAddressSpace;
59 BOOLEAN MiDbgEnableMdDump =
60 #ifdef _ARM_
61 TRUE;
62 #else
63 FALSE;
64 #endif
65
66 /* PRIVATE FUNCTIONS *********************************************************/
67
68 VOID
69 INIT_FUNCTION
70 NTAPI
71 MiInitSystemMemoryAreas()
72 {
73 PVOID BaseAddress;
74 PHYSICAL_ADDRESS BoundaryAddressMultiple;
75 PMEMORY_AREA MArea;
76 NTSTATUS Status;
77 BoundaryAddressMultiple.QuadPart = 0;
78
79 //
80 // Create the memory area to define the PTE base
81 //
82 BaseAddress = (PVOID)PTE_BASE;
83 Status = MmCreateMemoryArea(MmGetKernelAddressSpace(),
84 MEMORY_AREA_OWNED_BY_ARM3 | MEMORY_AREA_STATIC,
85 &BaseAddress,
86 4 * 1024 * 1024,
87 PAGE_READWRITE,
88 &MArea,
89 TRUE,
90 0,
91 BoundaryAddressMultiple);
92 ASSERT(Status == STATUS_SUCCESS);
93
94 //
95 // Create the memory area to define Hyperspace
96 //
97 BaseAddress = (PVOID)HYPER_SPACE;
98 Status = MmCreateMemoryArea(MmGetKernelAddressSpace(),
99 MEMORY_AREA_OWNED_BY_ARM3 | MEMORY_AREA_STATIC,
100 &BaseAddress,
101 4 * 1024 * 1024,
102 PAGE_READWRITE,
103 &MArea,
104 TRUE,
105 0,
106 BoundaryAddressMultiple);
107 ASSERT(Status == STATUS_SUCCESS);
108
109 //
110 // Protect the PFN database
111 //
112 BaseAddress = MmPfnDatabase;
113 Status = MmCreateMemoryArea(MmGetKernelAddressSpace(),
114 MEMORY_AREA_OWNED_BY_ARM3 | MEMORY_AREA_STATIC,
115 &BaseAddress,
116 (MxPfnAllocation << PAGE_SHIFT),
117 PAGE_READWRITE,
118 &MArea,
119 TRUE,
120 0,
121 BoundaryAddressMultiple);
122 ASSERT(Status == STATUS_SUCCESS);
123
124 //
125 // ReactOS requires a memory area to keep the initial NP area off-bounds
126 //
127 BaseAddress = MmNonPagedPoolStart;
128 Status = MmCreateMemoryArea(MmGetKernelAddressSpace(),
129 MEMORY_AREA_OWNED_BY_ARM3 | MEMORY_AREA_STATIC,
130 &BaseAddress,
131 MmSizeOfNonPagedPoolInBytes,
132 PAGE_READWRITE,
133 &MArea,
134 TRUE,
135 0,
136 BoundaryAddressMultiple);
137 ASSERT(Status == STATUS_SUCCESS);
138
139 //
140 // And we need one more for the system NP
141 //
142 BaseAddress = MmNonPagedSystemStart;
143 Status = MmCreateMemoryArea(MmGetKernelAddressSpace(),
144 MEMORY_AREA_OWNED_BY_ARM3 | MEMORY_AREA_STATIC,
145 &BaseAddress,
146 (ULONG_PTR)MmNonPagedPoolEnd -
147 (ULONG_PTR)MmNonPagedSystemStart,
148 PAGE_READWRITE,
149 &MArea,
150 TRUE,
151 0,
152 BoundaryAddressMultiple);
153 ASSERT(Status == STATUS_SUCCESS);
154
155 //
156 // We also need one for system view space
157 //
158 BaseAddress = MiSystemViewStart;
159 Status = MmCreateMemoryArea(MmGetKernelAddressSpace(),
160 MEMORY_AREA_OWNED_BY_ARM3 | MEMORY_AREA_STATIC,
161 &BaseAddress,
162 MmSystemViewSize,
163 PAGE_READWRITE,
164 &MArea,
165 TRUE,
166 0,
167 BoundaryAddressMultiple);
168 ASSERT(Status == STATUS_SUCCESS);
169
170 //
171 // And another for session space
172 //
173 BaseAddress = MmSessionBase;
174 Status = MmCreateMemoryArea(MmGetKernelAddressSpace(),
175 MEMORY_AREA_OWNED_BY_ARM3 | MEMORY_AREA_STATIC,
176 &BaseAddress,
177 (ULONG_PTR)MiSessionSpaceEnd -
178 (ULONG_PTR)MmSessionBase,
179 PAGE_READWRITE,
180 &MArea,
181 TRUE,
182 0,
183 BoundaryAddressMultiple);
184 ASSERT(Status == STATUS_SUCCESS);
185
186 //
187 // One more for ARM paged pool
188 //
189 BaseAddress = MmPagedPoolStart;
190 Status = MmCreateMemoryArea(MmGetKernelAddressSpace(),
191 MEMORY_AREA_OWNED_BY_ARM3 | MEMORY_AREA_STATIC,
192 &BaseAddress,
193 MmSizeOfPagedPoolInBytes,
194 PAGE_READWRITE,
195 &MArea,
196 TRUE,
197 0,
198 BoundaryAddressMultiple);
199 ASSERT(Status == STATUS_SUCCESS);
200
201 //
202 // And now, ReactOS paged pool
203 //
204 BaseAddress = MmPagedPoolBase;
205 Status = MmCreateMemoryArea(MmGetKernelAddressSpace(),
206 MEMORY_AREA_PAGED_POOL | MEMORY_AREA_STATIC,
207 &BaseAddress,
208 MmPagedPoolSize,
209 PAGE_READWRITE,
210 &MArea,
211 TRUE,
212 0,
213 BoundaryAddressMultiple);
214 ASSERT(Status == STATUS_SUCCESS);
215
216 //
217 // Next, the KPCR
218 //
219 BaseAddress = (PVOID)PCR;
220 Status = MmCreateMemoryArea(MmGetKernelAddressSpace(),
221 MEMORY_AREA_OWNED_BY_ARM3 | MEMORY_AREA_STATIC,
222 &BaseAddress,
223 PAGE_SIZE * KeNumberProcessors,
224 PAGE_READWRITE,
225 &MArea,
226 TRUE,
227 0,
228 BoundaryAddressMultiple);
229 ASSERT(Status == STATUS_SUCCESS);
230
231 //
232 // Now the KUSER_SHARED_DATA
233 //
234 BaseAddress = (PVOID)KI_USER_SHARED_DATA;
235 Status = MmCreateMemoryArea(MmGetKernelAddressSpace(),
236 MEMORY_AREA_OWNED_BY_ARM3 | MEMORY_AREA_STATIC,
237 &BaseAddress,
238 PAGE_SIZE,
239 PAGE_READWRITE,
240 &MArea,
241 TRUE,
242 0,
243 BoundaryAddressMultiple);
244 ASSERT(Status == STATUS_SUCCESS);
245
246 //
247 // And the debugger mapping
248 //
249 BaseAddress = MI_DEBUG_MAPPING;
250 Status = MmCreateMemoryArea(MmGetKernelAddressSpace(),
251 MEMORY_AREA_OWNED_BY_ARM3 | MEMORY_AREA_STATIC,
252 &BaseAddress,
253 PAGE_SIZE,
254 PAGE_READWRITE,
255 &MArea,
256 TRUE,
257 0,
258 BoundaryAddressMultiple);
259 ASSERT(Status == STATUS_SUCCESS);
260
261 #if defined(_X86_)
262 //
263 // Finally, reserve the 2 pages we currently make use of for HAL mappings
264 //
265 BaseAddress = (PVOID)0xFFC00000;
266 Status = MmCreateMemoryArea(MmGetKernelAddressSpace(),
267 MEMORY_AREA_OWNED_BY_ARM3 | MEMORY_AREA_STATIC,
268 &BaseAddress,
269 PAGE_SIZE * 2,
270 PAGE_READWRITE,
271 &MArea,
272 TRUE,
273 0,
274 BoundaryAddressMultiple);
275 ASSERT(Status == STATUS_SUCCESS);
276 #endif
277 }
278
279 VOID
280 NTAPI
281 MiDbgDumpAddressSpace(VOID)
282 {
283 //
284 // Print the memory layout
285 //
286 DPRINT1(" 0x%p - 0x%p\t%s\n",
287 MmSystemRangeStart,
288 (ULONG_PTR)MmSystemRangeStart + MmBootImageSize,
289 "Boot Loaded Image");
290 DPRINT1(" 0x%p - 0x%p\t%s\n",
291 MmPagedPoolBase,
292 (ULONG_PTR)MmPagedPoolBase + MmPagedPoolSize,
293 "Paged Pool");
294 DPRINT1(" 0x%p - 0x%p\t%s\n",
295 MmPfnDatabase,
296 (ULONG_PTR)MmPfnDatabase + (MxPfnAllocation << PAGE_SHIFT),
297 "PFN Database");
298 DPRINT1(" 0x%p - 0x%p\t%s\n",
299 MmNonPagedPoolStart,
300 (ULONG_PTR)MmNonPagedPoolStart + MmSizeOfNonPagedPoolInBytes,
301 "ARM³ Non Paged Pool");
302 DPRINT1(" 0x%p - 0x%p\t%s\n",
303 MiSystemViewStart,
304 (ULONG_PTR)MiSystemViewStart + MmSystemViewSize,
305 "System View Space");
306 DPRINT1(" 0x%p - 0x%p\t%s\n",
307 MmSessionBase,
308 MiSessionSpaceEnd,
309 "Session Space");
310 DPRINT1(" 0x%p - 0x%p\t%s\n",
311 PTE_BASE, PDE_BASE,
312 "Page Tables");
313 DPRINT1(" 0x%p - 0x%p\t%s\n",
314 PDE_BASE, HYPER_SPACE,
315 "Page Directories");
316 DPRINT1(" 0x%p - 0x%p\t%s\n",
317 HYPER_SPACE, HYPER_SPACE + (4 * 1024 * 1024),
318 "Hyperspace");
319 DPRINT1(" 0x%p - 0x%p\t%s\n",
320 MmPagedPoolStart,
321 (ULONG_PTR)MmPagedPoolStart + MmSizeOfPagedPoolInBytes,
322 "ARM³ Paged Pool");
323 DPRINT1(" 0x%p - 0x%p\t%s\n",
324 MmNonPagedSystemStart, MmNonPagedPoolExpansionStart,
325 "System PTE Space");
326 DPRINT1(" 0x%p - 0x%p\t%s\n",
327 MmNonPagedPoolExpansionStart, MmNonPagedPoolEnd,
328 "Non Paged Pool Expansion PTE Space");
329 }
330
331 VOID
332 NTAPI
333 MiDbgDumpMemoryDescriptors(VOID)
334 {
335 PLIST_ENTRY NextEntry;
336 PMEMORY_ALLOCATION_DESCRIPTOR Md;
337 ULONG TotalPages = 0;
338
339 DPRINT1("Base\t\tLength\t\tType\n");
340 for (NextEntry = KeLoaderBlock->MemoryDescriptorListHead.Flink;
341 NextEntry != &KeLoaderBlock->MemoryDescriptorListHead;
342 NextEntry = NextEntry->Flink)
343 {
344 Md = CONTAINING_RECORD(NextEntry, MEMORY_ALLOCATION_DESCRIPTOR, ListEntry);
345 DPRINT1("%08lX\t%08lX\t%s\n", Md->BasePage, Md->PageCount, MemType[Md->MemoryType]);
346 TotalPages += Md->PageCount;
347 }
348
349 DPRINT1("Total: %08lX (%d MB)\n", TotalPages, (TotalPages * PAGE_SIZE) / 1024 / 1024);
350 }
351
352 BOOLEAN
353 NTAPI
354 MmInitSystem(IN ULONG Phase,
355 IN PLOADER_PARAMETER_BLOCK LoaderBlock)
356 {
357 extern MMPTE HyperTemplatePte;
358 PMMPTE PointerPte;
359 MMPTE TempPte = HyperTemplatePte;
360 PFN_NUMBER PageFrameNumber;
361
362 if (Phase == 0)
363 {
364 /* Initialize the kernel address space */
365 KeInitializeGuardedMutex(&PsGetCurrentProcess()->AddressCreationLock);
366 MmKernelAddressSpace = MmGetCurrentAddressSpace();
367 MmInitGlobalKernelPageDirectory();
368
369 /* Dump memory descriptors */
370 if (MiDbgEnableMdDump) MiDbgDumpMemoryDescriptors();
371
372 //
373 // Initialize ARM³ in phase 0
374 //
375 MmArmInitSystem(0, KeLoaderBlock);
376
377 #if defined(_WINKD_)
378 //
379 // Everything required for the debugger to read and write
380 // physical memory is now set up
381 //
382 MiDbgReadyForPhysical = TRUE;
383 #endif
384
385 /* Put the paged pool after the loaded modules */
386 MmPagedPoolBase = (PVOID)PAGE_ROUND_UP((ULONG_PTR)MmSystemRangeStart +
387 MmBootImageSize);
388 MmPagedPoolSize = MM_PAGED_POOL_SIZE;
389
390 /* Intialize system memory areas */
391 MiInitSystemMemoryAreas();
392
393 /* Dump the address space */
394 MiDbgDumpAddressSpace();
395
396 /* Initialize paged pool */
397 MmInitializePagedPool();
398
399 /* Initialize working sets */
400 MmInitializeMemoryConsumer(MC_USER, MmTrimUserMemory);
401
402 /* Initialize the user mode image list */
403 InitializeListHead(&MmLoadedUserImageList);
404
405 /* Initialize the Loader Lock */
406 KeInitializeMutant(&MmSystemLoadLock, FALSE);
407
408 /* Reload boot drivers */
409 MiReloadBootLoadedDrivers(LoaderBlock);
410
411 /* Initialize the loaded module list */
412 MiInitializeLoadedModuleList(LoaderBlock);
413
414 /* Setup shared user data settings that NT does as well */
415 ASSERT(SharedUserData->NumberOfPhysicalPages == 0);
416 SharedUserData->NumberOfPhysicalPages = MmNumberOfPhysicalPages;
417 SharedUserData->LargePageMinimum = 0;
418
419 /* For now, we assume that we're always Server */
420 SharedUserData->NtProductType = NtProductServer;
421 }
422 else if (Phase == 1)
423 {
424 MmInitializeRmapList();
425 MmInitializePageOp();
426 MmInitSectionImplementation();
427 MmInitPagingFile();
428
429 //
430 // Create a PTE to double-map the shared data section. We allocate it
431 // from paged pool so that we can't fault when trying to touch the PTE
432 // itself (to map it), since paged pool addresses will already be mapped
433 // by the fault handler.
434 //
435 MmSharedUserDataPte = ExAllocatePoolWithTag(PagedPool,
436 sizeof(MMPTE),
437 ' mM');
438 if (!MmSharedUserDataPte) return FALSE;
439
440 //
441 // Now get the PTE for shared data, and read the PFN that holds it
442 //
443 PointerPte = MiAddressToPte(KI_USER_SHARED_DATA);
444 ASSERT(PointerPte->u.Hard.Valid == 1);
445 PageFrameNumber = PFN_FROM_PTE(PointerPte);
446
447 //
448 // Now write a copy of it
449 //
450 MI_MAKE_OWNER_PAGE(&TempPte);
451 TempPte.u.Hard.PageFrameNumber = PageFrameNumber;
452 *MmSharedUserDataPte = TempPte;
453
454 /*
455 * Unmap low memory
456 */
457 MiInitBalancerThread();
458
459 /*
460 * Initialise the modified page writer.
461 */
462 MmInitMpwThread();
463
464 /* Initialize the balance set manager */
465 MmInitBsmThread();
466 }
467 else if (Phase == 2)
468 {
469
470 }
471
472 return TRUE;
473 }
474