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 *******************************************************************/
20 VOID NTAPI
MiInitializeUserPfnBitmap(VOID
);
22 HANDLE MpwThreadHandle
;
23 KEVENT MpwThreadEvent
;
25 BOOLEAN Mm64BitPhysicalAddress
= FALSE
;
26 ULONG MmReadClusterSize
;
28 // 0 | 1 is on/off paging, 2 is undocumented
30 UCHAR MmDisablePagingExecutive
= 1; // Forced to off
31 PMMPTE MmSharedUserDataPte
;
32 PMMSUPPORT MmKernelAddressSpace
;
34 extern KEVENT MmWaitPageEvent
;
35 extern FAST_MUTEX MiGlobalPageOperation
;
36 extern LIST_ENTRY MiSegmentList
;
37 extern NTSTATUS
MiRosTrimCache(ULONG Target
, ULONG Priority
, PULONG NrFreed
);
39 /* PRIVATE FUNCTIONS *********************************************************/
44 MiInitSystemMemoryAreas()
51 // Create the memory area to define the loader mappings
53 BaseAddress
= (PVOID
)KSEG0_BASE
;
54 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
55 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
58 PAGE_EXECUTE_READWRITE
,
63 ASSERT(Status
== STATUS_SUCCESS
);
66 // Create the memory area to define the PTE base
68 BaseAddress
= (PVOID
)PTE_BASE
;
69 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
70 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
72 PTE_TOP
- PTE_BASE
+ 1,
78 ASSERT(Status
== STATUS_SUCCESS
);
81 // Create the memory area to define Hyperspace
83 BaseAddress
= (PVOID
)HYPER_SPACE
;
84 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
85 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
87 HYPER_SPACE_END
- HYPER_SPACE
+ 1,
93 ASSERT(Status
== STATUS_SUCCESS
);
96 // Protect the PFN database
98 BaseAddress
= MmPfnDatabase
;
99 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
100 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
102 (MxPfnAllocation
<< PAGE_SHIFT
),
108 ASSERT(Status
== STATUS_SUCCESS
);
111 // ReactOS requires a memory area to keep the initial NP area off-bounds
113 BaseAddress
= MmNonPagedPoolStart
;
114 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
115 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
117 MmSizeOfNonPagedPoolInBytes
,
123 ASSERT(Status
== STATUS_SUCCESS
);
126 // And we need one more for the system NP
128 BaseAddress
= MmNonPagedSystemStart
;
129 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
130 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
132 MiNonPagedSystemSize
,
138 ASSERT(Status
== STATUS_SUCCESS
);
141 // We also need one for system view space
143 BaseAddress
= MiSystemViewStart
;
144 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
145 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
153 ASSERT(Status
== STATUS_SUCCESS
);
156 // And another for session space
158 BaseAddress
= MmSessionBase
;
159 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
160 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
162 (ULONG_PTR
)MiSessionSpaceEnd
-
163 (ULONG_PTR
)MmSessionBase
,
169 ASSERT(Status
== STATUS_SUCCESS
);
172 // One more for ARM paged pool
174 BaseAddress
= MmPagedPoolStart
;
175 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
176 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
178 MmSizeOfPagedPoolInBytes
,
184 ASSERT(Status
== STATUS_SUCCESS
);
189 BaseAddress
= (PVOID
)PCR
;
190 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
191 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
193 PAGE_SIZE
* KeNumberProcessors
,
199 ASSERT(Status
== STATUS_SUCCESS
);
202 // Now the KUSER_SHARED_DATA
204 BaseAddress
= (PVOID
)KI_USER_SHARED_DATA
;
205 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
206 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
214 ASSERT(Status
== STATUS_SUCCESS
);
217 // And the debugger mapping
219 BaseAddress
= MI_DEBUG_MAPPING
;
220 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
221 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
229 ASSERT(Status
== STATUS_SUCCESS
);
233 // Finally, reserve the 2 pages we currently make use of for HAL mappings
235 BaseAddress
= (PVOID
)0xFFC00000;
236 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
237 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
245 ASSERT(Status
== STATUS_SUCCESS
);
252 MiDbgDumpAddressSpace(VOID
)
255 // Print the memory layout
257 DPRINT1(" 0x%p - 0x%p\t%s\n",
259 (ULONG_PTR
)KSEG0_BASE
+ MmBootImageSize
,
260 "Boot Loaded Image");
261 DPRINT1(" 0x%p - 0x%p\t%s\n",
263 (ULONG_PTR
)MmPfnDatabase
+ (MxPfnAllocation
<< PAGE_SHIFT
),
265 DPRINT1(" 0x%p - 0x%p\t%s\n",
267 (ULONG_PTR
)MmNonPagedPoolStart
+ MmSizeOfNonPagedPoolInBytes
,
268 "ARM3 Non Paged Pool");
269 DPRINT1(" 0x%p - 0x%p\t%s\n",
271 (ULONG_PTR
)MiSystemViewStart
+ MmSystemViewSize
,
272 "System View Space");
273 DPRINT1(" 0x%p - 0x%p\t%s\n",
277 DPRINT1(" 0x%p - 0x%p\t%s\n",
280 DPRINT1(" 0x%p - 0x%p\t%s\n",
283 DPRINT1(" 0x%p - 0x%p\t%s\n",
284 HYPER_SPACE
, HYPER_SPACE_END
,
286 DPRINT1(" 0x%p - 0x%p\t%s\n",
288 (ULONG_PTR
)MmPagedPoolStart
+ MmSizeOfPagedPoolInBytes
,
290 DPRINT1(" 0x%p - 0x%p\t%s\n",
291 MmNonPagedSystemStart
, MmNonPagedPoolExpansionStart
,
293 DPRINT1(" 0x%p - 0x%p\t%s\n",
294 MmNonPagedPoolExpansionStart
, MmNonPagedPoolEnd
,
295 "Non Paged Pool Expansion PTE Space");
300 MmMpwThreadMain(PVOID Parameter
)
304 LARGE_INTEGER Timeout
;
306 UNREFERENCED_PARAMETER(Parameter
);
308 Timeout
.QuadPart
= -50000000;
312 Status
= KeWaitForSingleObject(&MpwThreadEvent
,
317 if (!NT_SUCCESS(Status
))
319 DbgPrint("MpwThread: Wait failed\n");
320 KeBugCheck(MEMORY_MANAGEMENT
);
327 // XXX arty -- we flush when evicting pages or destorying cache
329 CcRosFlushDirtyPages(128, &PagesWritten
, FALSE
);
337 MmInitMpwThread(VOID
)
341 CLIENT_ID MpwThreadId
;
343 KeInitializeEvent(&MpwThreadEvent
, SynchronizationEvent
, FALSE
);
345 Status
= PsCreateSystemThread(&MpwThreadHandle
,
352 if (!NT_SUCCESS(Status
))
358 NtSetInformationThread(MpwThreadHandle
,
363 return(STATUS_SUCCESS
);
369 MmInitBsmThread(VOID
)
372 OBJECT_ATTRIBUTES ObjectAttributes
;
375 /* Create the thread */
376 InitializeObjectAttributes(&ObjectAttributes
, NULL
, 0, NULL
, NULL
);
377 Status
= PsCreateSystemThread(&ThreadHandle
,
385 /* Close the handle and return status */
386 ZwClose(ThreadHandle
);
393 MmInitSystem(IN ULONG Phase
,
394 IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
396 extern MMPTE ValidKernelPte
;
398 MMPTE TempPte
= ValidKernelPte
;
399 PFN_NUMBER PageFrameNumber
;
401 /* Initialize the kernel address space */
404 InitializeListHead(&MiSegmentList
);
405 ExInitializeFastMutex(&MiGlobalPageOperation
);
406 KeInitializeEvent(&MmWaitPageEvent
, SynchronizationEvent
, FALSE
);
407 // Until we're fully demand paged, we can do things the old way through
408 // the balance manager
409 MmInitializeMemoryConsumer(MC_CACHE
, MiRosTrimCache
);
411 MmKernelAddressSpace
= &PsIdleProcess
->Vm
;
413 /* Intialize system memory areas */
414 MiInitSystemMemoryAreas();
416 /* Dump the address space */
417 MiDbgDumpAddressSpace();
419 MmInitGlobalKernelPageDirectory();
420 MiInitializeUserPfnBitmap();
421 MmInitializeMemoryConsumer(MC_USER
, MmTrimUserMemory
);
422 MmInitializeRmapList();
423 MmInitSectionImplementation();
427 // Create a PTE to double-map the shared data section. We allocate it
428 // from paged pool so that we can't fault when trying to touch the PTE
429 // itself (to map it), since paged pool addresses will already be mapped
430 // by the fault handler.
432 MmSharedUserDataPte
= ExAllocatePoolWithTag(PagedPool
,
435 if (!MmSharedUserDataPte
) return FALSE
;
438 // Now get the PTE for shared data, and read the PFN that holds it
440 PointerPte
= MiAddressToPte((PVOID
)KI_USER_SHARED_DATA
);
441 ASSERT(PointerPte
->u
.Hard
.Valid
== 1);
442 PageFrameNumber
= PFN_FROM_PTE(PointerPte
);
444 /* Build the PTE and write it */
445 MI_MAKE_HARDWARE_PTE_KERNEL(&TempPte
,
449 *MmSharedUserDataPte
= TempPte
;
451 /* Initialize session working set support */
452 MiInitializeSessionWsSupport();
454 /* Setup session IDs */
455 MiInitializeSessionIds();
457 /* Setup the memory threshold events */
458 if (!MiInitializeMemoryEvents()) return FALSE
;
463 MiInitBalancerThread();
466 * Initialise the modified page writer.
470 /* Initialize the balance set manager */