1*23589e9bSTimo Kreuzer /*
2c2c66affSColin Finck * PROJECT: ReactOS Kernel
3c2c66affSColin Finck * LICENSE: GPL - See COPYING in the top level directory
4c2c66affSColin Finck * FILE: ntoskrnl/mm/mminit.c
5c2c66affSColin Finck * PURPOSE: Memory Manager Initialization
6c2c66affSColin Finck * PROGRAMMERS:
7c2c66affSColin Finck */
8c2c66affSColin Finck
9c2c66affSColin Finck /* INCLUDES ******************************************************************/
10c2c66affSColin Finck
11c2c66affSColin Finck #include <ntoskrnl.h>
12c2c66affSColin Finck #define NDEBUG
13c2c66affSColin Finck #include <debug.h>
14c2c66affSColin Finck
15c2c66affSColin Finck #define MODULE_INVOLVED_IN_ARM3
16c2c66affSColin Finck #include "ARM3/miarm.h"
17c2c66affSColin Finck
18c2c66affSColin Finck /* GLOBALS *******************************************************************/
19c2c66affSColin Finck
20c2c66affSColin Finck BOOLEAN Mm64BitPhysicalAddress = FALSE;
21c2c66affSColin Finck ULONG MmReadClusterSize;
22c2c66affSColin Finck //
23c2c66affSColin Finck // 0 | 1 is on/off paging, 2 is undocumented
24c2c66affSColin Finck //
25c2c66affSColin Finck UCHAR MmDisablePagingExecutive = 1; // Forced to off
26c2c66affSColin Finck PMMPTE MmSharedUserDataPte;
27c2c66affSColin Finck PMMSUPPORT MmKernelAddressSpace;
28c2c66affSColin Finck
29c2c66affSColin Finck extern KEVENT MmWaitPageEvent;
30c2c66affSColin Finck extern FAST_MUTEX MiGlobalPageOperation;
31c2c66affSColin Finck extern LIST_ENTRY MiSegmentList;
32c2c66affSColin Finck extern NTSTATUS MiRosTrimCache(ULONG Target, ULONG Priority, PULONG NrFreed);
33c2c66affSColin Finck
34c2c66affSColin Finck /* PRIVATE FUNCTIONS *********************************************************/
35c2c66affSColin Finck
36c2c66affSColin Finck //
37c2c66affSColin Finck // Helper function to create initial memory areas.
38c2c66affSColin Finck // The created area is always read/write.
39c2c66affSColin Finck //
405c7ce447SVictor Perevertkin CODE_SEG("INIT")
4171fefa32STimo Kreuzer VOID
42c2c66affSColin Finck NTAPI
MiCreateArm3StaticMemoryArea(PVOID BaseAddress,SIZE_T Size,BOOLEAN Executable)434d35d59fSIvan Labutin MiCreateArm3StaticMemoryArea(PVOID BaseAddress, SIZE_T Size, BOOLEAN Executable)
44c2c66affSColin Finck {
45c2c66affSColin Finck const ULONG Protection = Executable ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE;
46c2c66affSColin Finck PVOID pBaseAddress = BaseAddress;
47c2c66affSColin Finck PMEMORY_AREA MArea;
48c2c66affSColin Finck NTSTATUS Status;
49c2c66affSColin Finck
50c2c66affSColin Finck Status = MmCreateMemoryArea(MmGetKernelAddressSpace(),
51c2c66affSColin Finck MEMORY_AREA_OWNED_BY_ARM3 | MEMORY_AREA_STATIC,
52c2c66affSColin Finck &pBaseAddress,
53c2c66affSColin Finck Size,
54c2c66affSColin Finck Protection,
55c2c66affSColin Finck &MArea,
56c2c66affSColin Finck 0,
57c2c66affSColin Finck PAGE_SIZE);
58c2c66affSColin Finck ASSERT(Status == STATUS_SUCCESS);
59c2c66affSColin Finck // TODO: Perhaps it would be prudent to bugcheck here, not only assert?
60c2c66affSColin Finck }
61c2c66affSColin Finck
625c7ce447SVictor Perevertkin CODE_SEG("INIT")
6371fefa32STimo Kreuzer VOID
64c2c66affSColin Finck NTAPI
MiInitSystemMemoryAreas(VOID)65c2c66affSColin Finck MiInitSystemMemoryAreas(VOID)
66c2c66affSColin Finck {
67c2c66affSColin Finck //
68c2c66affSColin Finck // Create all the static memory areas.
69c2c66affSColin Finck //
70c2c66affSColin Finck
71*23589e9bSTimo Kreuzer MmLockAddressSpace(MmGetKernelAddressSpace());
72*23589e9bSTimo Kreuzer
73a5d47ff7STimo Kreuzer #ifdef _M_AMD64
74a5d47ff7STimo Kreuzer // Reserved range FFFF800000000000 - FFFFF68000000000
75a5d47ff7STimo Kreuzer MiCreateArm3StaticMemoryArea((PVOID)MI_REAL_SYSTEM_RANGE_START, PTE_BASE - MI_REAL_SYSTEM_RANGE_START, FALSE);
76a5d47ff7STimo Kreuzer #endif /* _M_AMD64 */
77a5d47ff7STimo Kreuzer
78c2c66affSColin Finck // The loader mappings. The only Executable area.
79c2c66affSColin Finck MiCreateArm3StaticMemoryArea((PVOID)KSEG0_BASE, MmBootImageSize, TRUE);
80c2c66affSColin Finck
81c2c66affSColin Finck // The PTE base
82c2c66affSColin Finck MiCreateArm3StaticMemoryArea((PVOID)PTE_BASE, PTE_TOP - PTE_BASE + 1, FALSE);
83c2c66affSColin Finck
84c2c66affSColin Finck // Hyperspace
85c2c66affSColin Finck MiCreateArm3StaticMemoryArea((PVOID)HYPER_SPACE, HYPER_SPACE_END - HYPER_SPACE + 1, FALSE);
86c2c66affSColin Finck
87c2c66affSColin Finck // Protect the PFN database
88c2c66affSColin Finck MiCreateArm3StaticMemoryArea(MmPfnDatabase, (MxPfnAllocation << PAGE_SHIFT), FALSE);
89c2c66affSColin Finck
90c2c66affSColin Finck // ReactOS requires a memory area to keep the initial NP area off-bounds
91c2c66affSColin Finck MiCreateArm3StaticMemoryArea(MmNonPagedPoolStart, MmSizeOfNonPagedPoolInBytes, FALSE);
92c2c66affSColin Finck
93c2c66affSColin Finck // System PTE space
94c2c66affSColin Finck MiCreateArm3StaticMemoryArea(MmNonPagedSystemStart, (MmNumberOfSystemPtes + 1) * PAGE_SIZE, FALSE);
95c2c66affSColin Finck
96c2c66affSColin Finck // Nonpaged pool expansion space
97c2c66affSColin Finck MiCreateArm3StaticMemoryArea(MmNonPagedPoolExpansionStart, (ULONG_PTR)MmNonPagedPoolEnd - (ULONG_PTR)MmNonPagedPoolExpansionStart, FALSE);
98c2c66affSColin Finck
99c2c66affSColin Finck // System view space
100c2c66affSColin Finck MiCreateArm3StaticMemoryArea(MiSystemViewStart, MmSystemViewSize, FALSE);
101c2c66affSColin Finck
102c2c66affSColin Finck // Session space
103c2c66affSColin Finck MiCreateArm3StaticMemoryArea(MmSessionBase, (ULONG_PTR)MiSessionSpaceEnd - (ULONG_PTR)MmSessionBase, FALSE);
104c2c66affSColin Finck
105c2c66affSColin Finck // Paged pool
106c2c66affSColin Finck MiCreateArm3StaticMemoryArea(MmPagedPoolStart, MmSizeOfPagedPoolInBytes, FALSE);
107c2c66affSColin Finck
108c2c66affSColin Finck // Debugger mapping
109c2c66affSColin Finck MiCreateArm3StaticMemoryArea(MI_DEBUG_MAPPING, PAGE_SIZE, FALSE);
110c2c66affSColin Finck
111c2c66affSColin Finck #if defined(_X86_)
112c2c66affSColin Finck // Reserved HAL area (includes KUSER_SHARED_DATA and KPCR)
113c2c66affSColin Finck MiCreateArm3StaticMemoryArea((PVOID)MM_HAL_VA_START, MM_HAL_VA_END - MM_HAL_VA_START + 1, FALSE);
114c2c66affSColin Finck #else /* _X86_ */
115c2c66affSColin Finck #ifndef _M_AMD64
116c2c66affSColin Finck // KPCR, one page per CPU. Only for 32-bit kernel.
117c2c66affSColin Finck MiCreateArm3StaticMemoryArea(PCR, PAGE_SIZE * KeNumberProcessors, FALSE);
118c2c66affSColin Finck #endif /* _M_AMD64 */
119c2c66affSColin Finck
120c2c66affSColin Finck // KUSER_SHARED_DATA
121c2c66affSColin Finck MiCreateArm3StaticMemoryArea((PVOID)KI_USER_SHARED_DATA, PAGE_SIZE, FALSE);
122c2c66affSColin Finck #endif /* _X86_ */
123*23589e9bSTimo Kreuzer
124*23589e9bSTimo Kreuzer MmUnlockAddressSpace(MmGetKernelAddressSpace());
125c2c66affSColin Finck }
126c2c66affSColin Finck
1275c7ce447SVictor Perevertkin CODE_SEG("INIT")
128c2c66affSColin Finck VOID
129c2c66affSColin Finck NTAPI
MiDbgDumpAddressSpace(VOID)130c2c66affSColin Finck MiDbgDumpAddressSpace(VOID)
131c2c66affSColin Finck {
132c2c66affSColin Finck //
133c2c66affSColin Finck // Print the memory layout
134c2c66affSColin Finck //
135c2c66affSColin Finck DPRINT1(" 0x%p - 0x%p\t%s\n",
136c2c66affSColin Finck KSEG0_BASE,
137c2c66affSColin Finck (ULONG_PTR)KSEG0_BASE + MmBootImageSize,
138c2c66affSColin Finck "Boot Loaded Image");
139c2c66affSColin Finck DPRINT1(" 0x%p - 0x%p\t%s\n",
140c2c66affSColin Finck MmPfnDatabase,
141c2c66affSColin Finck (ULONG_PTR)MmPfnDatabase + (MxPfnAllocation << PAGE_SHIFT),
142c2c66affSColin Finck "PFN Database");
143c2c66affSColin Finck DPRINT1(" 0x%p - 0x%p\t%s\n",
144c2c66affSColin Finck MmNonPagedPoolStart,
145c2c66affSColin Finck (ULONG_PTR)MmNonPagedPoolStart + MmSizeOfNonPagedPoolInBytes,
146c2c66affSColin Finck "ARM3 Non Paged Pool");
147c2c66affSColin Finck DPRINT1(" 0x%p - 0x%p\t%s\n",
148c2c66affSColin Finck MiSystemViewStart,
149c2c66affSColin Finck (ULONG_PTR)MiSystemViewStart + MmSystemViewSize,
150c2c66affSColin Finck "System View Space");
151c2c66affSColin Finck DPRINT1(" 0x%p - 0x%p\t%s\n",
152c2c66affSColin Finck MmSessionBase,
153c2c66affSColin Finck MiSessionSpaceEnd,
154c2c66affSColin Finck "Session Space");
155c2c66affSColin Finck DPRINT1(" 0x%p - 0x%p\t%s\n",
156c2c66affSColin Finck PTE_BASE, PTE_TOP,
157c2c66affSColin Finck "Page Tables");
158c2c66affSColin Finck DPRINT1(" 0x%p - 0x%p\t%s\n",
159c2c66affSColin Finck PDE_BASE, PDE_TOP,
160c2c66affSColin Finck "Page Directories");
161c2c66affSColin Finck DPRINT1(" 0x%p - 0x%p\t%s\n",
162c2c66affSColin Finck HYPER_SPACE, HYPER_SPACE_END,
163c2c66affSColin Finck "Hyperspace");
164c2c66affSColin Finck DPRINT1(" 0x%p - 0x%p\t%s\n",
165d56a2490SPierre Schweitzer MmSystemCacheStart, MmSystemCacheEnd,
166d56a2490SPierre Schweitzer "System Cache");
167d56a2490SPierre Schweitzer DPRINT1(" 0x%p - 0x%p\t%s\n",
168c2c66affSColin Finck MmPagedPoolStart,
169c2c66affSColin Finck (ULONG_PTR)MmPagedPoolStart + MmSizeOfPagedPoolInBytes,
170c2c66affSColin Finck "ARM3 Paged Pool");
171c2c66affSColin Finck DPRINT1(" 0x%p - 0x%p\t%s\n",
172c2c66affSColin Finck MmNonPagedSystemStart, MmNonPagedPoolExpansionStart,
173c2c66affSColin Finck "System PTE Space");
174c2c66affSColin Finck DPRINT1(" 0x%p - 0x%p\t%s\n",
175c2c66affSColin Finck MmNonPagedPoolExpansionStart, MmNonPagedPoolEnd,
176c2c66affSColin Finck "Non Paged Pool Expansion PTE Space");
177c2c66affSColin Finck }
178c2c66affSColin Finck
1795c7ce447SVictor Perevertkin CODE_SEG("INIT")
180c2c66affSColin Finck NTSTATUS
181c2c66affSColin Finck NTAPI
MmInitBsmThread(VOID)182c2c66affSColin Finck MmInitBsmThread(VOID)
183c2c66affSColin Finck {
184c2c66affSColin Finck NTSTATUS Status;
185c2c66affSColin Finck OBJECT_ATTRIBUTES ObjectAttributes;
186c2c66affSColin Finck HANDLE ThreadHandle;
187c2c66affSColin Finck
188c2c66affSColin Finck /* Create the thread */
189c2c66affSColin Finck InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL);
190c2c66affSColin Finck Status = PsCreateSystemThread(&ThreadHandle,
191c2c66affSColin Finck THREAD_ALL_ACCESS,
192c2c66affSColin Finck &ObjectAttributes,
193c2c66affSColin Finck NULL,
194c2c66affSColin Finck NULL,
195c2c66affSColin Finck KeBalanceSetManager,
196c2c66affSColin Finck NULL);
197c2c66affSColin Finck
198c2c66affSColin Finck /* Close the handle and return status */
199c2c66affSColin Finck ZwClose(ThreadHandle);
200c2c66affSColin Finck return Status;
201c2c66affSColin Finck }
202c2c66affSColin Finck
2035c7ce447SVictor Perevertkin CODE_SEG("INIT")
204c2c66affSColin Finck BOOLEAN
205c2c66affSColin Finck NTAPI
MmInitSystem(IN ULONG Phase,IN PLOADER_PARAMETER_BLOCK LoaderBlock)206c2c66affSColin Finck MmInitSystem(IN ULONG Phase,
207c2c66affSColin Finck IN PLOADER_PARAMETER_BLOCK LoaderBlock)
208c2c66affSColin Finck {
209c2c66affSColin Finck extern MMPTE ValidKernelPte;
210c2c66affSColin Finck PMMPTE PointerPte;
211c2c66affSColin Finck MMPTE TempPte = ValidKernelPte;
212c2c66affSColin Finck PFN_NUMBER PageFrameNumber;
21365dbfc28STimo Kreuzer PLIST_ENTRY ListEntry;
21465dbfc28STimo Kreuzer PLDR_DATA_TABLE_ENTRY DataTableEntry;
215c2c66affSColin Finck
216c2c66affSColin Finck /* Initialize the kernel address space */
217c2c66affSColin Finck ASSERT(Phase == 1);
218c2c66affSColin Finck
219462d9a09SJérôme Gardou #ifdef NEWCC
220c2c66affSColin Finck InitializeListHead(&MiSegmentList);
221c2c66affSColin Finck ExInitializeFastMutex(&MiGlobalPageOperation);
222c2c66affSColin Finck KeInitializeEvent(&MmWaitPageEvent, SynchronizationEvent, FALSE);
223c2c66affSColin Finck // Until we're fully demand paged, we can do things the old way through
224c2c66affSColin Finck // the balance manager
225462d9a09SJérôme Gardou // CcInitView will override this...
226c2c66affSColin Finck MmInitializeMemoryConsumer(MC_CACHE, MiRosTrimCache);
227462d9a09SJérôme Gardou #else
228462d9a09SJérôme Gardou KeInitializeEvent(&MmWaitPageEvent, SynchronizationEvent, FALSE);
229462d9a09SJérôme Gardou #endif
230c2c66affSColin Finck
231c2c66affSColin Finck MmKernelAddressSpace = &PsIdleProcess->Vm;
232c2c66affSColin Finck
233c2c66affSColin Finck /* Intialize system memory areas */
234c2c66affSColin Finck MiInitSystemMemoryAreas();
235c2c66affSColin Finck
236c2c66affSColin Finck /* Dump the address space */
237c2c66affSColin Finck MiDbgDumpAddressSpace();
238c2c66affSColin Finck
239c2c66affSColin Finck MmInitGlobalKernelPageDirectory();
240c2c66affSColin Finck MmInitializeMemoryConsumer(MC_USER, MmTrimUserMemory);
241c2c66affSColin Finck MmInitializeRmapList();
242c2c66affSColin Finck MmInitSectionImplementation();
243c2c66affSColin Finck MmInitPagingFile();
244c2c66affSColin Finck
245c2c66affSColin Finck //
246c2c66affSColin Finck // Create a PTE to double-map the shared data section. We allocate it
247c2c66affSColin Finck // from paged pool so that we can't fault when trying to touch the PTE
248c2c66affSColin Finck // itself (to map it), since paged pool addresses will already be mapped
249c2c66affSColin Finck // by the fault handler.
250c2c66affSColin Finck //
251c2c66affSColin Finck MmSharedUserDataPte = ExAllocatePoolWithTag(PagedPool,
252c2c66affSColin Finck sizeof(MMPTE),
253c2c66affSColin Finck TAG_MM);
254c2c66affSColin Finck if (!MmSharedUserDataPte) return FALSE;
255c2c66affSColin Finck
256c2c66affSColin Finck //
257c2c66affSColin Finck // Now get the PTE for shared data, and read the PFN that holds it
258c2c66affSColin Finck //
259c2c66affSColin Finck PointerPte = MiAddressToPte((PVOID)KI_USER_SHARED_DATA);
260c2c66affSColin Finck ASSERT(PointerPte->u.Hard.Valid == 1);
261c2c66affSColin Finck PageFrameNumber = PFN_FROM_PTE(PointerPte);
262c2c66affSColin Finck
263c2c66affSColin Finck /* Build the PTE and write it */
264c2c66affSColin Finck MI_MAKE_HARDWARE_PTE_KERNEL(&TempPte,
265c2c66affSColin Finck PointerPte,
266c2c66affSColin Finck MM_READONLY,
267c2c66affSColin Finck PageFrameNumber);
268c2c66affSColin Finck *MmSharedUserDataPte = TempPte;
269c2c66affSColin Finck
270c2c66affSColin Finck /* Initialize session working set support */
271c2c66affSColin Finck MiInitializeSessionWsSupport();
272c2c66affSColin Finck
273c2c66affSColin Finck /* Setup session IDs */
274c2c66affSColin Finck MiInitializeSessionIds();
275c2c66affSColin Finck
276c2c66affSColin Finck /* Setup the memory threshold events */
277c2c66affSColin Finck if (!MiInitializeMemoryEvents()) return FALSE;
278c2c66affSColin Finck
279c2c66affSColin Finck /*
280c2c66affSColin Finck * Unmap low memory
281c2c66affSColin Finck */
282c2c66affSColin Finck MiInitBalancerThread();
283c2c66affSColin Finck
284c2c66affSColin Finck /* Initialize the balance set manager */
285c2c66affSColin Finck MmInitBsmThread();
286c2c66affSColin Finck
287ba9bf73dSThomas Faber /* Loop the boot loaded images (under lock) */
288ba9bf73dSThomas Faber ExAcquireResourceExclusiveLite(&PsLoadedModuleResource, TRUE);
28965dbfc28STimo Kreuzer for (ListEntry = PsLoadedModuleList.Flink;
29065dbfc28STimo Kreuzer ListEntry != &PsLoadedModuleList;
29165dbfc28STimo Kreuzer ListEntry = ListEntry->Flink)
29265dbfc28STimo Kreuzer {
29365dbfc28STimo Kreuzer /* Get the data table entry */
29465dbfc28STimo Kreuzer DataTableEntry = CONTAINING_RECORD(ListEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
29565dbfc28STimo Kreuzer
29665dbfc28STimo Kreuzer /* Set up the image protection */
29765dbfc28STimo Kreuzer MiWriteProtectSystemImage(DataTableEntry->DllBase);
29865dbfc28STimo Kreuzer }
299ba9bf73dSThomas Faber ExReleaseResourceLite(&PsLoadedModuleResource);
30065dbfc28STimo Kreuzer
301c2c66affSColin Finck return TRUE;
302c2c66affSColin Finck }
303c2c66affSColin Finck
304