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()
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
, MiNonPagedSystemSize
, FALSE
);
95 MiCreateArm3StaticMemoryArea(MiSystemViewStart
, MmSystemViewSize
, FALSE
);
98 MiCreateArm3StaticMemoryArea(MmSessionBase
, (ULONG_PTR
)MiSessionSpaceEnd
- (ULONG_PTR
)MmSessionBase
, FALSE
);
101 MiCreateArm3StaticMemoryArea(MmPagedPoolStart
, MmSizeOfPagedPoolInBytes
, FALSE
);
104 // KPCR, one page per CPU. Only for 32-bit kernel.
105 MiCreateArm3StaticMemoryArea(PCR
, PAGE_SIZE
* KeNumberProcessors
, FALSE
);
109 MiCreateArm3StaticMemoryArea((PVOID
)KI_USER_SHARED_DATA
, PAGE_SIZE
, FALSE
);
112 MiCreateArm3StaticMemoryArea(MI_DEBUG_MAPPING
, PAGE_SIZE
, FALSE
);
115 // Reserve the 2 pages we currently make use of for HAL mappings.
116 // TODO: Remove hard-coded constant and replace with a define.
117 MiCreateArm3StaticMemoryArea((PVOID
)0xFFC00000, PAGE_SIZE
* 2, FALSE
);
124 MiDbgDumpAddressSpace(VOID
)
127 // Print the memory layout
129 DPRINT1(" 0x%p - 0x%p\t%s\n",
131 (ULONG_PTR
)KSEG0_BASE
+ MmBootImageSize
,
132 "Boot Loaded Image");
133 DPRINT1(" 0x%p - 0x%p\t%s\n",
135 (ULONG_PTR
)MmPfnDatabase
+ (MxPfnAllocation
<< PAGE_SHIFT
),
137 DPRINT1(" 0x%p - 0x%p\t%s\n",
139 (ULONG_PTR
)MmNonPagedPoolStart
+ MmSizeOfNonPagedPoolInBytes
,
140 "ARM3 Non Paged Pool");
141 DPRINT1(" 0x%p - 0x%p\t%s\n",
143 (ULONG_PTR
)MiSystemViewStart
+ MmSystemViewSize
,
144 "System View Space");
145 DPRINT1(" 0x%p - 0x%p\t%s\n",
149 DPRINT1(" 0x%p - 0x%p\t%s\n",
152 DPRINT1(" 0x%p - 0x%p\t%s\n",
155 DPRINT1(" 0x%p - 0x%p\t%s\n",
156 HYPER_SPACE
, HYPER_SPACE_END
,
158 DPRINT1(" 0x%p - 0x%p\t%s\n",
160 (ULONG_PTR
)MmPagedPoolStart
+ MmSizeOfPagedPoolInBytes
,
162 DPRINT1(" 0x%p - 0x%p\t%s\n",
163 MmNonPagedSystemStart
, MmNonPagedPoolExpansionStart
,
165 DPRINT1(" 0x%p - 0x%p\t%s\n",
166 MmNonPagedPoolExpansionStart
, MmNonPagedPoolEnd
,
167 "Non Paged Pool Expansion PTE Space");
172 MmMpwThreadMain(PVOID Parameter
)
178 LARGE_INTEGER Timeout
;
180 UNREFERENCED_PARAMETER(Parameter
);
182 Timeout
.QuadPart
= -50000000;
186 Status
= KeWaitForSingleObject(&MpwThreadEvent
,
191 if (!NT_SUCCESS(Status
))
193 DbgPrint("MpwThread: Wait failed\n");
194 KeBugCheck(MEMORY_MANAGEMENT
);
201 // XXX arty -- we flush when evicting pages or destorying cache
203 CcRosFlushDirtyPages(128, &PagesWritten
, FALSE
);
211 MmInitMpwThread(VOID
)
215 CLIENT_ID MpwThreadId
;
217 KeInitializeEvent(&MpwThreadEvent
, SynchronizationEvent
, FALSE
);
219 Status
= PsCreateSystemThread(&MpwThreadHandle
,
226 if (!NT_SUCCESS(Status
))
232 NtSetInformationThread(MpwThreadHandle
,
237 return(STATUS_SUCCESS
);
243 MmInitBsmThread(VOID
)
246 OBJECT_ATTRIBUTES ObjectAttributes
;
249 /* Create the thread */
250 InitializeObjectAttributes(&ObjectAttributes
, NULL
, 0, NULL
, NULL
);
251 Status
= PsCreateSystemThread(&ThreadHandle
,
259 /* Close the handle and return status */
260 ZwClose(ThreadHandle
);
267 MmInitSystem(IN ULONG Phase
,
268 IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
270 extern MMPTE ValidKernelPte
;
272 MMPTE TempPte
= ValidKernelPte
;
273 PFN_NUMBER PageFrameNumber
;
275 /* Initialize the kernel address space */
278 InitializeListHead(&MiSegmentList
);
279 ExInitializeFastMutex(&MiGlobalPageOperation
);
280 KeInitializeEvent(&MmWaitPageEvent
, SynchronizationEvent
, FALSE
);
281 // Until we're fully demand paged, we can do things the old way through
282 // the balance manager
283 MmInitializeMemoryConsumer(MC_CACHE
, MiRosTrimCache
);
285 MmKernelAddressSpace
= &PsIdleProcess
->Vm
;
287 /* Intialize system memory areas */
288 MiInitSystemMemoryAreas();
290 /* Dump the address space */
291 MiDbgDumpAddressSpace();
293 MmInitGlobalKernelPageDirectory();
294 MiInitializeUserPfnBitmap();
295 MmInitializeMemoryConsumer(MC_USER
, MmTrimUserMemory
);
296 MmInitializeRmapList();
297 MmInitSectionImplementation();
301 // Create a PTE to double-map the shared data section. We allocate it
302 // from paged pool so that we can't fault when trying to touch the PTE
303 // itself (to map it), since paged pool addresses will already be mapped
304 // by the fault handler.
306 MmSharedUserDataPte
= ExAllocatePoolWithTag(PagedPool
,
309 if (!MmSharedUserDataPte
) return FALSE
;
312 // Now get the PTE for shared data, and read the PFN that holds it
314 PointerPte
= MiAddressToPte((PVOID
)KI_USER_SHARED_DATA
);
315 ASSERT(PointerPte
->u
.Hard
.Valid
== 1);
316 PageFrameNumber
= PFN_FROM_PTE(PointerPte
);
318 /* Build the PTE and write it */
319 MI_MAKE_HARDWARE_PTE_KERNEL(&TempPte
,
323 *MmSharedUserDataPte
= TempPte
;
325 /* Initialize session working set support */
326 MiInitializeSessionWsSupport();
328 /* Setup session IDs */
329 MiInitializeSessionIds();
331 /* Setup the memory threshold events */
332 if (!MiInitializeMemoryEvents()) return FALSE
;
337 MiInitBalancerThread();
340 * Initialise the modified page writer.
344 /* Initialize the balance set manager */