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
,
62 ASSERT(Status
== STATUS_SUCCESS
);
65 // Create the memory area to define the PTE base
67 BaseAddress
= (PVOID
)PTE_BASE
;
68 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
69 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
71 PTE_TOP
- PTE_BASE
+ 1,
76 ASSERT(Status
== STATUS_SUCCESS
);
79 // Create the memory area to define Hyperspace
81 BaseAddress
= (PVOID
)HYPER_SPACE
;
82 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
83 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
85 HYPER_SPACE_END
- HYPER_SPACE
+ 1,
90 ASSERT(Status
== STATUS_SUCCESS
);
93 // Protect the PFN database
95 BaseAddress
= MmPfnDatabase
;
96 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
97 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
99 (MxPfnAllocation
<< PAGE_SHIFT
),
104 ASSERT(Status
== STATUS_SUCCESS
);
107 // ReactOS requires a memory area to keep the initial NP area off-bounds
109 BaseAddress
= MmNonPagedPoolStart
;
110 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
111 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
113 MmSizeOfNonPagedPoolInBytes
,
118 ASSERT(Status
== STATUS_SUCCESS
);
121 // And we need one more for the system NP
123 BaseAddress
= MmNonPagedSystemStart
;
124 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
125 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
127 MiNonPagedSystemSize
,
132 ASSERT(Status
== STATUS_SUCCESS
);
135 // We also need one for system view space
137 BaseAddress
= MiSystemViewStart
;
138 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
139 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
146 ASSERT(Status
== STATUS_SUCCESS
);
149 // And another for session space
151 BaseAddress
= MmSessionBase
;
152 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
153 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
155 (ULONG_PTR
)MiSessionSpaceEnd
-
156 (ULONG_PTR
)MmSessionBase
,
161 ASSERT(Status
== STATUS_SUCCESS
);
164 // One more for ARM paged pool
166 BaseAddress
= MmPagedPoolStart
;
167 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
168 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
170 MmSizeOfPagedPoolInBytes
,
175 ASSERT(Status
== STATUS_SUCCESS
);
180 BaseAddress
= (PVOID
)PCR
;
181 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
182 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
184 PAGE_SIZE
* KeNumberProcessors
,
189 ASSERT(Status
== STATUS_SUCCESS
);
192 // Now the KUSER_SHARED_DATA
194 BaseAddress
= (PVOID
)KI_USER_SHARED_DATA
;
195 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
196 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
203 ASSERT(Status
== STATUS_SUCCESS
);
206 // And the debugger mapping
208 BaseAddress
= MI_DEBUG_MAPPING
;
209 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
210 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
217 ASSERT(Status
== STATUS_SUCCESS
);
221 // Finally, reserve the 2 pages we currently make use of for HAL mappings
223 BaseAddress
= (PVOID
)0xFFC00000;
224 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
225 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
232 ASSERT(Status
== STATUS_SUCCESS
);
239 MiDbgDumpAddressSpace(VOID
)
242 // Print the memory layout
244 DPRINT1(" 0x%p - 0x%p\t%s\n",
246 (ULONG_PTR
)KSEG0_BASE
+ MmBootImageSize
,
247 "Boot Loaded Image");
248 DPRINT1(" 0x%p - 0x%p\t%s\n",
250 (ULONG_PTR
)MmPfnDatabase
+ (MxPfnAllocation
<< PAGE_SHIFT
),
252 DPRINT1(" 0x%p - 0x%p\t%s\n",
254 (ULONG_PTR
)MmNonPagedPoolStart
+ MmSizeOfNonPagedPoolInBytes
,
255 "ARM3 Non Paged Pool");
256 DPRINT1(" 0x%p - 0x%p\t%s\n",
258 (ULONG_PTR
)MiSystemViewStart
+ MmSystemViewSize
,
259 "System View Space");
260 DPRINT1(" 0x%p - 0x%p\t%s\n",
264 DPRINT1(" 0x%p - 0x%p\t%s\n",
267 DPRINT1(" 0x%p - 0x%p\t%s\n",
270 DPRINT1(" 0x%p - 0x%p\t%s\n",
271 HYPER_SPACE
, HYPER_SPACE_END
,
273 DPRINT1(" 0x%p - 0x%p\t%s\n",
275 (ULONG_PTR
)MmPagedPoolStart
+ MmSizeOfPagedPoolInBytes
,
277 DPRINT1(" 0x%p - 0x%p\t%s\n",
278 MmNonPagedSystemStart
, MmNonPagedPoolExpansionStart
,
280 DPRINT1(" 0x%p - 0x%p\t%s\n",
281 MmNonPagedPoolExpansionStart
, MmNonPagedPoolEnd
,
282 "Non Paged Pool Expansion PTE Space");
287 MmMpwThreadMain(PVOID Parameter
)
293 LARGE_INTEGER Timeout
;
295 UNREFERENCED_PARAMETER(Parameter
);
297 Timeout
.QuadPart
= -50000000;
301 Status
= KeWaitForSingleObject(&MpwThreadEvent
,
306 if (!NT_SUCCESS(Status
))
308 DbgPrint("MpwThread: Wait failed\n");
309 KeBugCheck(MEMORY_MANAGEMENT
);
316 // XXX arty -- we flush when evicting pages or destorying cache
318 CcRosFlushDirtyPages(128, &PagesWritten
, FALSE
);
326 MmInitMpwThread(VOID
)
330 CLIENT_ID MpwThreadId
;
332 KeInitializeEvent(&MpwThreadEvent
, SynchronizationEvent
, FALSE
);
334 Status
= PsCreateSystemThread(&MpwThreadHandle
,
341 if (!NT_SUCCESS(Status
))
347 NtSetInformationThread(MpwThreadHandle
,
352 return(STATUS_SUCCESS
);
358 MmInitBsmThread(VOID
)
361 OBJECT_ATTRIBUTES ObjectAttributes
;
364 /* Create the thread */
365 InitializeObjectAttributes(&ObjectAttributes
, NULL
, 0, NULL
, NULL
);
366 Status
= PsCreateSystemThread(&ThreadHandle
,
374 /* Close the handle and return status */
375 ZwClose(ThreadHandle
);
382 MmInitSystem(IN ULONG Phase
,
383 IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
385 extern MMPTE ValidKernelPte
;
387 MMPTE TempPte
= ValidKernelPte
;
388 PFN_NUMBER PageFrameNumber
;
390 /* Initialize the kernel address space */
393 InitializeListHead(&MiSegmentList
);
394 ExInitializeFastMutex(&MiGlobalPageOperation
);
395 KeInitializeEvent(&MmWaitPageEvent
, SynchronizationEvent
, FALSE
);
396 // Until we're fully demand paged, we can do things the old way through
397 // the balance manager
398 MmInitializeMemoryConsumer(MC_CACHE
, MiRosTrimCache
);
400 MmKernelAddressSpace
= &PsIdleProcess
->Vm
;
402 /* Intialize system memory areas */
403 MiInitSystemMemoryAreas();
405 /* Dump the address space */
406 MiDbgDumpAddressSpace();
408 MmInitGlobalKernelPageDirectory();
409 MiInitializeUserPfnBitmap();
410 MmInitializeMemoryConsumer(MC_USER
, MmTrimUserMemory
);
411 MmInitializeRmapList();
412 MmInitSectionImplementation();
416 // Create a PTE to double-map the shared data section. We allocate it
417 // from paged pool so that we can't fault when trying to touch the PTE
418 // itself (to map it), since paged pool addresses will already be mapped
419 // by the fault handler.
421 MmSharedUserDataPte
= ExAllocatePoolWithTag(PagedPool
,
424 if (!MmSharedUserDataPte
) return FALSE
;
427 // Now get the PTE for shared data, and read the PFN that holds it
429 PointerPte
= MiAddressToPte((PVOID
)KI_USER_SHARED_DATA
);
430 ASSERT(PointerPte
->u
.Hard
.Valid
== 1);
431 PageFrameNumber
= PFN_FROM_PTE(PointerPte
);
433 /* Build the PTE and write it */
434 MI_MAKE_HARDWARE_PTE_KERNEL(&TempPte
,
438 *MmSharedUserDataPte
= TempPte
;
440 /* Initialize session working set support */
441 MiInitializeSessionWsSupport();
443 /* Setup session IDs */
444 MiInitializeSessionIds();
446 /* Setup the memory threshold events */
447 if (!MiInitializeMemoryEvents()) return FALSE
;
452 MiInitBalancerThread();
455 * Initialise the modified page writer.
459 /* Initialize the balance set manager */