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 /* PRIVATE FUNCTIONS *********************************************************/
39 MiInitSystemMemoryAreas()
42 PHYSICAL_ADDRESS BoundaryAddressMultiple
;
45 BoundaryAddressMultiple
.QuadPart
= 0;
48 // Create the memory area to define the PTE base
50 BaseAddress
= (PVOID
)PTE_BASE
;
51 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
52 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
59 BoundaryAddressMultiple
);
60 ASSERT(Status
== STATUS_SUCCESS
);
63 // Create the memory area to define Hyperspace
65 BaseAddress
= (PVOID
)HYPER_SPACE
;
66 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
67 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
74 BoundaryAddressMultiple
);
75 ASSERT(Status
== STATUS_SUCCESS
);
78 // Protect the PFN database
80 BaseAddress
= MmPfnDatabase
;
81 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
82 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
84 (MxPfnAllocation
<< PAGE_SHIFT
),
89 BoundaryAddressMultiple
);
90 ASSERT(Status
== STATUS_SUCCESS
);
93 // ReactOS requires a memory area to keep the initial NP area off-bounds
95 BaseAddress
= MmNonPagedPoolStart
;
96 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
97 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
99 MmSizeOfNonPagedPoolInBytes
,
104 BoundaryAddressMultiple
);
105 ASSERT(Status
== STATUS_SUCCESS
);
108 // And we need one more for the system NP
110 BaseAddress
= MmNonPagedSystemStart
;
111 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
112 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
114 (ULONG_PTR
)MmNonPagedPoolEnd
-
115 (ULONG_PTR
)MmNonPagedSystemStart
,
120 BoundaryAddressMultiple
);
121 ASSERT(Status
== STATUS_SUCCESS
);
124 // We also need one for system view space
126 BaseAddress
= MiSystemViewStart
;
127 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
128 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
135 BoundaryAddressMultiple
);
136 ASSERT(Status
== STATUS_SUCCESS
);
139 // And another for session space
141 BaseAddress
= MmSessionBase
;
142 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
143 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
145 (ULONG_PTR
)MiSessionSpaceEnd
-
146 (ULONG_PTR
)MmSessionBase
,
151 BoundaryAddressMultiple
);
152 ASSERT(Status
== STATUS_SUCCESS
);
155 // One more for ARM paged pool
157 BaseAddress
= MmPagedPoolStart
;
158 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
159 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
161 MmSizeOfPagedPoolInBytes
,
166 BoundaryAddressMultiple
);
167 ASSERT(Status
== STATUS_SUCCESS
);
172 BaseAddress
= (PVOID
)PCR
;
173 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
174 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
176 PAGE_SIZE
* KeNumberProcessors
,
181 BoundaryAddressMultiple
);
182 ASSERT(Status
== STATUS_SUCCESS
);
185 // Now the KUSER_SHARED_DATA
187 BaseAddress
= (PVOID
)KI_USER_SHARED_DATA
;
188 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
189 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
196 BoundaryAddressMultiple
);
197 ASSERT(Status
== STATUS_SUCCESS
);
200 // And the debugger mapping
202 BaseAddress
= MI_DEBUG_MAPPING
;
203 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
204 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
211 BoundaryAddressMultiple
);
212 ASSERT(Status
== STATUS_SUCCESS
);
216 // Finally, reserve the 2 pages we currently make use of for HAL mappings
218 BaseAddress
= (PVOID
)0xFFC00000;
219 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
220 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
227 BoundaryAddressMultiple
);
228 ASSERT(Status
== STATUS_SUCCESS
);
235 MiDbgDumpAddressSpace(VOID
)
238 // Print the memory layout
240 DPRINT1(" 0x%p - 0x%p\t%s\n",
242 (ULONG_PTR
)MmSystemRangeStart
+ MmBootImageSize
,
243 "Boot Loaded Image");
244 DPRINT1(" 0x%p - 0x%p\t%s\n",
246 (ULONG_PTR
)MmPfnDatabase
+ (MxPfnAllocation
<< PAGE_SHIFT
),
248 DPRINT1(" 0x%p - 0x%p\t%s\n",
250 (ULONG_PTR
)MmNonPagedPoolStart
+ MmSizeOfNonPagedPoolInBytes
,
251 "ARMĀ³ Non Paged Pool");
252 DPRINT1(" 0x%p - 0x%p\t%s\n",
254 (ULONG_PTR
)MiSystemViewStart
+ MmSystemViewSize
,
255 "System View Space");
256 DPRINT1(" 0x%p - 0x%p\t%s\n",
260 DPRINT1(" 0x%p - 0x%p\t%s\n",
263 DPRINT1(" 0x%p - 0x%p\t%s\n",
264 PDE_BASE
, HYPER_SPACE
,
266 DPRINT1(" 0x%p - 0x%p\t%s\n",
267 HYPER_SPACE
, HYPER_SPACE
+ (4 * 1024 * 1024),
269 DPRINT1(" 0x%p - 0x%p\t%s\n",
271 (ULONG_PTR
)MmPagedPoolStart
+ MmSizeOfPagedPoolInBytes
,
273 DPRINT1(" 0x%p - 0x%p\t%s\n",
274 MmNonPagedSystemStart
, MmNonPagedPoolExpansionStart
,
276 DPRINT1(" 0x%p - 0x%p\t%s\n",
277 MmNonPagedPoolExpansionStart
, MmNonPagedPoolEnd
,
278 "Non Paged Pool Expansion PTE Space");
282 MmMpwThreadMain(PVOID Ignored
)
286 LARGE_INTEGER Timeout
;
288 Timeout
.QuadPart
= -50000000;
292 Status
= KeWaitForSingleObject(&MpwThreadEvent
,
297 if (!NT_SUCCESS(Status
))
299 DbgPrint("MpwThread: Wait failed\n");
300 KeBugCheck(MEMORY_MANAGEMENT
);
301 return(STATUS_UNSUCCESSFUL
);
307 // XXX arty -- we flush when evicting pages or destorying cache
309 CcRosFlushDirtyPages(128, &PagesWritten
, FALSE
);
317 MmInitMpwThread(VOID
)
321 CLIENT_ID MpwThreadId
;
323 KeInitializeEvent(&MpwThreadEvent
, SynchronizationEvent
, FALSE
);
325 Status
= PsCreateSystemThread(&MpwThreadHandle
,
330 (PKSTART_ROUTINE
) MmMpwThreadMain
,
332 if (!NT_SUCCESS(Status
))
338 NtSetInformationThread(MpwThreadHandle
,
343 return(STATUS_SUCCESS
);
349 MmInitBsmThread(VOID
)
352 OBJECT_ATTRIBUTES ObjectAttributes
;
355 /* Create the thread */
356 InitializeObjectAttributes(&ObjectAttributes
, NULL
, 0, NULL
, NULL
);
357 Status
= PsCreateSystemThread(&ThreadHandle
,
365 /* Close the handle and return status */
366 ZwClose(ThreadHandle
);
373 MmInitSystem(IN ULONG Phase
,
374 IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
376 extern MMPTE ValidKernelPte
;
378 MMPTE TempPte
= ValidKernelPte
;
379 PFN_NUMBER PageFrameNumber
;
381 /* Initialize the kernel address space */
383 KeInitializeGuardedMutex(&PsIdleProcess
->AddressCreationLock
);
384 MmKernelAddressSpace
= &PsIdleProcess
->Vm
;
386 /* Intialize system memory areas */
387 MiInitSystemMemoryAreas();
389 /* Dump the address space */
390 MiDbgDumpAddressSpace();
392 MmInitGlobalKernelPageDirectory();
393 MiInitializeUserPfnBitmap();
394 MmInitializeMemoryConsumer(MC_USER
, MmTrimUserMemory
);
395 MmInitializeRmapList();
396 MmInitializePageOp();
397 MmInitSectionImplementation();
401 // Create a PTE to double-map the shared data section. We allocate it
402 // from paged pool so that we can't fault when trying to touch the PTE
403 // itself (to map it), since paged pool addresses will already be mapped
404 // by the fault handler.
406 MmSharedUserDataPte
= ExAllocatePoolWithTag(PagedPool
,
409 if (!MmSharedUserDataPte
) return FALSE
;
412 // Now get the PTE for shared data, and read the PFN that holds it
414 PointerPte
= MiAddressToPte((PVOID
)KI_USER_SHARED_DATA
);
415 ASSERT(PointerPte
->u
.Hard
.Valid
== 1);
416 PageFrameNumber
= PFN_FROM_PTE(PointerPte
);
418 /* Build the PTE and write it */
419 MI_MAKE_HARDWARE_PTE_KERNEL(&TempPte
,
423 *MmSharedUserDataPte
= TempPte
;
425 /* Setup the memory threshold events */
426 if (!MiInitializeMemoryEvents()) return FALSE
;
431 MiInitBalancerThread();
434 * Initialise the modified page writer.
438 /* Initialize the balance set manager */