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 *********************************************************/
42 // Helper function to create initial memory areas.
43 // The created area is always read/write.
48 MiCreateArm3StaticMemoryArea(PVOID BaseAddress
, ULONG Size
, BOOLEAN Executable
)
50 const ULONG Protection
= Executable
? PAGE_EXECUTE_READWRITE
: PAGE_READWRITE
;
51 PVOID pBaseAddress
= BaseAddress
;
55 Status
= MmCreateMemoryArea(MmGetKernelAddressSpace(),
56 MEMORY_AREA_OWNED_BY_ARM3
| MEMORY_AREA_STATIC
,
63 ASSERT(Status
== STATUS_SUCCESS
);
64 // TODO: Perhaps it would be prudent to bugcheck here, not only assert?
70 MiInitSystemMemoryAreas(VOID
)
73 // Create all the static memory areas.
76 // The loader mappings. The only Executable area.
77 MiCreateArm3StaticMemoryArea((PVOID
)KSEG0_BASE
, MmBootImageSize
, TRUE
);
80 MiCreateArm3StaticMemoryArea((PVOID
)PTE_BASE
, PTE_TOP
- PTE_BASE
+ 1, FALSE
);
83 MiCreateArm3StaticMemoryArea((PVOID
)HYPER_SPACE
, HYPER_SPACE_END
- HYPER_SPACE
+ 1, FALSE
);
85 // Protect the PFN database
86 MiCreateArm3StaticMemoryArea(MmPfnDatabase
, (MxPfnAllocation
<< PAGE_SHIFT
), FALSE
);
88 // ReactOS requires a memory area to keep the initial NP area off-bounds
89 MiCreateArm3StaticMemoryArea(MmNonPagedPoolStart
, MmSizeOfNonPagedPoolInBytes
, FALSE
);
92 MiCreateArm3StaticMemoryArea(MmNonPagedSystemStart
, (MmNumberOfSystemPtes
+ 1) * PAGE_SIZE
, FALSE
);
94 // Nonpaged pool expansion space
95 MiCreateArm3StaticMemoryArea(MmNonPagedPoolExpansionStart
, (ULONG_PTR
)MmNonPagedPoolEnd
- (ULONG_PTR
)MmNonPagedPoolExpansionStart
, FALSE
);
98 MiCreateArm3StaticMemoryArea(MiSystemViewStart
, MmSystemViewSize
, FALSE
);
101 MiCreateArm3StaticMemoryArea(MmSessionBase
, (ULONG_PTR
)MiSessionSpaceEnd
- (ULONG_PTR
)MmSessionBase
, FALSE
);
104 MiCreateArm3StaticMemoryArea(MmPagedPoolStart
, MmSizeOfPagedPoolInBytes
, FALSE
);
107 MiCreateArm3StaticMemoryArea(MI_DEBUG_MAPPING
, PAGE_SIZE
, FALSE
);
110 // Reserved HAL area (includes KUSER_SHARED_DATA and KPCR)
111 MiCreateArm3StaticMemoryArea((PVOID
)MM_HAL_VA_START
, MM_HAL_VA_END
- MM_HAL_VA_START
+ 1, FALSE
);
114 // KPCR, one page per CPU. Only for 32-bit kernel.
115 MiCreateArm3StaticMemoryArea(PCR
, PAGE_SIZE
* KeNumberProcessors
, FALSE
);
116 #endif /* _M_AMD64 */
119 MiCreateArm3StaticMemoryArea((PVOID
)KI_USER_SHARED_DATA
, PAGE_SIZE
, FALSE
);
126 MiDbgDumpAddressSpace(VOID
)
129 // Print the memory layout
131 DPRINT1(" 0x%p - 0x%p\t%s\n",
133 (ULONG_PTR
)KSEG0_BASE
+ MmBootImageSize
,
134 "Boot Loaded Image");
135 DPRINT1(" 0x%p - 0x%p\t%s\n",
137 (ULONG_PTR
)MmPfnDatabase
+ (MxPfnAllocation
<< PAGE_SHIFT
),
139 DPRINT1(" 0x%p - 0x%p\t%s\n",
141 (ULONG_PTR
)MmNonPagedPoolStart
+ MmSizeOfNonPagedPoolInBytes
,
142 "ARM3 Non Paged Pool");
143 DPRINT1(" 0x%p - 0x%p\t%s\n",
145 (ULONG_PTR
)MiSystemViewStart
+ MmSystemViewSize
,
146 "System View Space");
147 DPRINT1(" 0x%p - 0x%p\t%s\n",
151 DPRINT1(" 0x%p - 0x%p\t%s\n",
154 DPRINT1(" 0x%p - 0x%p\t%s\n",
157 DPRINT1(" 0x%p - 0x%p\t%s\n",
158 HYPER_SPACE
, HYPER_SPACE_END
,
160 DPRINT1(" 0x%p - 0x%p\t%s\n",
162 (ULONG_PTR
)MmPagedPoolStart
+ MmSizeOfPagedPoolInBytes
,
164 DPRINT1(" 0x%p - 0x%p\t%s\n",
165 MmNonPagedSystemStart
, MmNonPagedPoolExpansionStart
,
167 DPRINT1(" 0x%p - 0x%p\t%s\n",
168 MmNonPagedPoolExpansionStart
, MmNonPagedPoolEnd
,
169 "Non Paged Pool Expansion PTE Space");
174 MmMpwThreadMain(PVOID Parameter
)
180 LARGE_INTEGER Timeout
;
182 UNREFERENCED_PARAMETER(Parameter
);
184 Timeout
.QuadPart
= -50000000;
188 Status
= KeWaitForSingleObject(&MpwThreadEvent
,
193 if (!NT_SUCCESS(Status
))
195 DbgPrint("MpwThread: Wait failed\n");
196 KeBugCheck(MEMORY_MANAGEMENT
);
203 // XXX arty -- we flush when evicting pages or destorying cache
205 CcRosFlushDirtyPages(128, &PagesWritten
, FALSE
);
213 MmInitMpwThread(VOID
)
217 CLIENT_ID MpwThreadId
;
219 KeInitializeEvent(&MpwThreadEvent
, SynchronizationEvent
, FALSE
);
221 Status
= PsCreateSystemThread(&MpwThreadHandle
,
228 if (!NT_SUCCESS(Status
))
234 NtSetInformationThread(MpwThreadHandle
,
239 return(STATUS_SUCCESS
);
245 MmInitBsmThread(VOID
)
248 OBJECT_ATTRIBUTES ObjectAttributes
;
251 /* Create the thread */
252 InitializeObjectAttributes(&ObjectAttributes
, NULL
, 0, NULL
, NULL
);
253 Status
= PsCreateSystemThread(&ThreadHandle
,
261 /* Close the handle and return status */
262 ZwClose(ThreadHandle
);
269 MmInitSystem(IN ULONG Phase
,
270 IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
272 extern MMPTE ValidKernelPte
;
274 MMPTE TempPte
= ValidKernelPte
;
275 PFN_NUMBER PageFrameNumber
;
277 /* Initialize the kernel address space */
280 InitializeListHead(&MiSegmentList
);
281 ExInitializeFastMutex(&MiGlobalPageOperation
);
282 KeInitializeEvent(&MmWaitPageEvent
, SynchronizationEvent
, FALSE
);
283 // Until we're fully demand paged, we can do things the old way through
284 // the balance manager
285 MmInitializeMemoryConsumer(MC_CACHE
, MiRosTrimCache
);
287 MmKernelAddressSpace
= &PsIdleProcess
->Vm
;
289 /* Intialize system memory areas */
290 MiInitSystemMemoryAreas();
292 /* Dump the address space */
293 MiDbgDumpAddressSpace();
295 MmInitGlobalKernelPageDirectory();
296 MiInitializeUserPfnBitmap();
297 MmInitializeMemoryConsumer(MC_USER
, MmTrimUserMemory
);
298 MmInitializeRmapList();
299 MmInitSectionImplementation();
303 // Create a PTE to double-map the shared data section. We allocate it
304 // from paged pool so that we can't fault when trying to touch the PTE
305 // itself (to map it), since paged pool addresses will already be mapped
306 // by the fault handler.
308 MmSharedUserDataPte
= ExAllocatePoolWithTag(PagedPool
,
311 if (!MmSharedUserDataPte
) return FALSE
;
314 // Now get the PTE for shared data, and read the PFN that holds it
316 PointerPte
= MiAddressToPte((PVOID
)KI_USER_SHARED_DATA
);
317 ASSERT(PointerPte
->u
.Hard
.Valid
== 1);
318 PageFrameNumber
= PFN_FROM_PTE(PointerPte
);
320 /* Build the PTE and write it */
321 MI_MAKE_HARDWARE_PTE_KERNEL(&TempPte
,
325 *MmSharedUserDataPte
= TempPte
;
327 /* Initialize session working set support */
328 MiInitializeSessionWsSupport();
330 /* Setup session IDs */
331 MiInitializeSessionIds();
333 /* Setup the memory threshold events */
334 if (!MiInitializeMemoryEvents()) return FALSE
;
339 MiInitBalancerThread();
342 * Initialise the modified page writer.
346 /* Initialize the balance set manager */