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
9 /* INCLUDES ******************************************************************/
15 #define MODULE_INVOLVED_IN_ARM3
16 #include "ARM3/miarm.h"
18 /* GLOBALS *******************************************************************/
51 BOOLEAN Mm64BitPhysicalAddress
= FALSE
;
52 ULONG MmReadClusterSize
;
54 // 0 | 1 is on/off paging, 2 is undocumented
56 UCHAR MmDisablePagingExecutive
= 1; // Forced to off
57 PMMPTE MmSharedUserDataPte
;
58 PMMSUPPORT MmKernelAddressSpace
;
59 BOOLEAN MiDbgEnableMdDump
=
66 /* PRIVATE FUNCTIONS *********************************************************/
71 MiInitSystemMemoryAreas()
74 PHYSICAL_ADDRESS BoundaryAddressMultiple
;
77 BoundaryAddressMultiple
.QuadPart
= 0;
80 // Create the memory area to define the PTE base
82 BaseAddress
= (PVOID
)PTE_BASE
;
83 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
84 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
91 BoundaryAddressMultiple
);
92 ASSERT(Status
== STATUS_SUCCESS
);
95 // Create the memory area to define Hyperspace
97 BaseAddress
= (PVOID
)HYPER_SPACE
;
98 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
99 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
106 BoundaryAddressMultiple
);
107 ASSERT(Status
== STATUS_SUCCESS
);
110 // Protect the PFN database
112 BaseAddress
= MmPfnDatabase
;
113 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
114 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
116 (MxPfnAllocation
<< PAGE_SHIFT
),
121 BoundaryAddressMultiple
);
122 ASSERT(Status
== STATUS_SUCCESS
);
125 // ReactOS requires a memory area to keep the initial NP area off-bounds
127 BaseAddress
= MmNonPagedPoolStart
;
128 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
129 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
131 MmSizeOfNonPagedPoolInBytes
,
136 BoundaryAddressMultiple
);
137 ASSERT(Status
== STATUS_SUCCESS
);
140 // And we need one more for the system NP
142 BaseAddress
= MmNonPagedSystemStart
;
143 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
144 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
146 (ULONG_PTR
)MmNonPagedPoolEnd
-
147 (ULONG_PTR
)MmNonPagedSystemStart
,
152 BoundaryAddressMultiple
);
153 ASSERT(Status
== STATUS_SUCCESS
);
156 // We also need one for system view space
158 BaseAddress
= MiSystemViewStart
;
159 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
160 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
167 BoundaryAddressMultiple
);
168 ASSERT(Status
== STATUS_SUCCESS
);
171 // And another for session space
173 BaseAddress
= MmSessionBase
;
174 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
175 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
177 (ULONG_PTR
)MiSessionSpaceEnd
-
178 (ULONG_PTR
)MmSessionBase
,
183 BoundaryAddressMultiple
);
184 ASSERT(Status
== STATUS_SUCCESS
);
187 // One more for ARM paged pool
189 BaseAddress
= MmPagedPoolStart
;
190 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
191 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
193 MmSizeOfPagedPoolInBytes
,
198 BoundaryAddressMultiple
);
199 ASSERT(Status
== STATUS_SUCCESS
);
202 // And now, ReactOS paged pool
204 BaseAddress
= MmPagedPoolBase
;
205 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
206 MEMORY_AREA_PAGED_POOL
| MEMORY_AREA_STATIC
,
213 BoundaryAddressMultiple
);
214 ASSERT(Status
== STATUS_SUCCESS
);
219 BaseAddress
= (PVOID
)PCR
;
220 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
221 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
223 PAGE_SIZE
* KeNumberProcessors
,
228 BoundaryAddressMultiple
);
229 ASSERT(Status
== STATUS_SUCCESS
);
232 // Now the KUSER_SHARED_DATA
234 BaseAddress
= (PVOID
)KI_USER_SHARED_DATA
;
235 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
236 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
243 BoundaryAddressMultiple
);
244 ASSERT(Status
== STATUS_SUCCESS
);
247 // And the debugger mapping
249 BaseAddress
= MI_DEBUG_MAPPING
;
250 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
251 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
258 BoundaryAddressMultiple
);
259 ASSERT(Status
== STATUS_SUCCESS
);
263 // Finally, reserve the 2 pages we currently make use of for HAL mappings
265 BaseAddress
= (PVOID
)0xFFC00000;
266 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
267 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
274 BoundaryAddressMultiple
);
275 ASSERT(Status
== STATUS_SUCCESS
);
281 MiDbgDumpAddressSpace(VOID
)
284 // Print the memory layout
286 DPRINT1(" 0x%p - 0x%p\t%s\n",
288 (ULONG_PTR
)MmSystemRangeStart
+ MmBootImageSize
,
289 "Boot Loaded Image");
290 DPRINT1(" 0x%p - 0x%p\t%s\n",
292 (ULONG_PTR
)MmPagedPoolBase
+ MmPagedPoolSize
,
294 DPRINT1(" 0x%p - 0x%p\t%s\n",
296 (ULONG_PTR
)MmPfnDatabase
+ (MxPfnAllocation
<< PAGE_SHIFT
),
298 DPRINT1(" 0x%p - 0x%p\t%s\n",
300 (ULONG_PTR
)MmNonPagedPoolStart
+ MmSizeOfNonPagedPoolInBytes
,
301 "ARM³ Non Paged Pool");
302 DPRINT1(" 0x%p - 0x%p\t%s\n",
304 (ULONG_PTR
)MiSystemViewStart
+ MmSystemViewSize
,
305 "System View Space");
306 DPRINT1(" 0x%p - 0x%p\t%s\n",
310 DPRINT1(" 0x%p - 0x%p\t%s\n",
313 DPRINT1(" 0x%p - 0x%p\t%s\n",
314 PDE_BASE
, HYPER_SPACE
,
316 DPRINT1(" 0x%p - 0x%p\t%s\n",
317 HYPER_SPACE
, HYPER_SPACE
+ (4 * 1024 * 1024),
319 DPRINT1(" 0x%p - 0x%p\t%s\n",
321 (ULONG_PTR
)MmPagedPoolStart
+ MmSizeOfPagedPoolInBytes
,
323 DPRINT1(" 0x%p - 0x%p\t%s\n",
324 MmNonPagedSystemStart
, MmNonPagedPoolExpansionStart
,
326 DPRINT1(" 0x%p - 0x%p\t%s\n",
327 MmNonPagedPoolExpansionStart
, MmNonPagedPoolEnd
,
328 "Non Paged Pool Expansion PTE Space");
333 MiDbgDumpMemoryDescriptors(VOID
)
335 PLIST_ENTRY NextEntry
;
336 PMEMORY_ALLOCATION_DESCRIPTOR Md
;
337 ULONG TotalPages
= 0;
339 DPRINT1("Base\t\tLength\t\tType\n");
340 for (NextEntry
= KeLoaderBlock
->MemoryDescriptorListHead
.Flink
;
341 NextEntry
!= &KeLoaderBlock
->MemoryDescriptorListHead
;
342 NextEntry
= NextEntry
->Flink
)
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
;
349 DPRINT1("Total: %08lX (%d MB)\n", TotalPages
, (TotalPages
* PAGE_SIZE
) / 1024 / 1024);
352 VOID NTAPI
MiInitializeUserPfnBitmap(VOID
);
356 MmInitSystem(IN ULONG Phase
,
357 IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
359 extern MMPTE ValidKernelPte
;
361 MMPTE TempPte
= ValidKernelPte
;
362 PFN_NUMBER PageFrameNumber
;
366 /* Initialize the kernel address space */
367 KeInitializeGuardedMutex(&PsGetCurrentProcess()->AddressCreationLock
);
368 MmKernelAddressSpace
= MmGetCurrentAddressSpace();
369 MmInitGlobalKernelPageDirectory();
371 /* Dump memory descriptors */
372 if (MiDbgEnableMdDump
) MiDbgDumpMemoryDescriptors();
374 /* Initialize ARM³ in phase 0 */
375 MmArmInitSystem(0, KeLoaderBlock
);
377 /* Put the paged pool after the loaded modules */
378 MmPagedPoolBase
= (PVOID
)PAGE_ROUND_UP((ULONG_PTR
)MmSystemRangeStart
+
380 MmPagedPoolSize
= MM_PAGED_POOL_SIZE
;
382 /* Intialize system memory areas */
383 MiInitSystemMemoryAreas();
385 /* Dump the address space */
386 MiDbgDumpAddressSpace();
390 MmInitializePagedPool();
391 MiInitializeUserPfnBitmap();
392 MmInitializeMemoryConsumer(MC_USER
, MmTrimUserMemory
);
393 MmInitializeRmapList();
394 MmInitializePageOp();
395 MmInitSectionImplementation();
399 // Create a PTE to double-map the shared data section. We allocate it
400 // from paged pool so that we can't fault when trying to touch the PTE
401 // itself (to map it), since paged pool addresses will already be mapped
402 // by the fault handler.
404 MmSharedUserDataPte
= ExAllocatePoolWithTag(PagedPool
,
407 if (!MmSharedUserDataPte
) return FALSE
;
410 // Now get the PTE for shared data, and read the PFN that holds it
412 PointerPte
= MiAddressToPte(KI_USER_SHARED_DATA
);
413 ASSERT(PointerPte
->u
.Hard
.Valid
== 1);
414 PageFrameNumber
= PFN_FROM_PTE(PointerPte
);
417 // Now write a copy of it
419 MI_MAKE_OWNER_PAGE(&TempPte
);
420 TempPte
.u
.Hard
.PageFrameNumber
= PageFrameNumber
;
421 *MmSharedUserDataPte
= TempPte
;
423 /* Setup the memory threshold events */
424 if (!MiInitializeMemoryEvents()) return FALSE
;
429 MiInitBalancerThread();
432 * Initialise the modified page writer.
436 /* Initialize the balance set manager */
441 /* Enough fun for now */
442 extern BOOLEAN AllowPagedPool
;
443 AllowPagedPool
= FALSE
;