xref: /reactos/ntoskrnl/mm/mminit.c (revision 23589e9b)
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