Sync to trunk HEAD (r43416)
[reactos.git] / reactos / ntoskrnl / mm / mminit.c
1 /*
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
6 * PROGRAMMERS:
7 */
8
9 /* INCLUDES ******************************************************************/
10
11 #include <ntoskrnl.h>
12 #define NDEBUG
13 #include <debug.h>
14
15 /* GLOBALS *******************************************************************/
16
17 PCHAR
18 MemType[] =
19 {
20 "ExceptionBlock ",
21 "SystemBlock ",
22 "Free ",
23 "Bad ",
24 "LoadedProgram ",
25 "FirmwareTemporary ",
26 "FirmwarePermanent ",
27 "OsloaderHeap ",
28 "OsloaderStack ",
29 "SystemCode ",
30 "HalCode ",
31 "BootDriver ",
32 "ConsoleInDriver ",
33 "ConsoleOutDriver ",
34 "StartupDpcStack ",
35 "StartupKernelStack",
36 "StartupPanicStack ",
37 "StartupPcrPage ",
38 "StartupPdrPage ",
39 "RegistryData ",
40 "MemoryData ",
41 "NlsData ",
42 "SpecialMemory ",
43 "BBTMemory ",
44 "LoaderReserve ",
45 "LoaderXIPRom "
46 };
47
48 PBOOLEAN Mm64BitPhysicalAddress = FALSE;
49 ULONG MmReadClusterSize;
50 MM_STATS MmStats;
51 PMMPTE MmSharedUserDataPte;
52 PMMSUPPORT MmKernelAddressSpace;
53 extern KMUTANT MmSystemLoadLock;
54 extern ULONG MmBootImageSize;
55 BOOLEAN MiDbgEnableMdDump =
56 #ifdef _ARM_
57 TRUE;
58 #else
59 FALSE;
60 #endif
61
62 /* PRIVATE FUNCTIONS *********************************************************/
63
64 VOID
65 INIT_FUNCTION
66 NTAPI
67 MiInitSystemMemoryAreas()
68 {
69 PVOID BaseAddress;
70 PHYSICAL_ADDRESS BoundaryAddressMultiple;
71 PMEMORY_AREA MArea;
72 BoundaryAddressMultiple.QuadPart = 0;
73
74 //
75 // First initialize the page table and hyperspace memory areas
76 //
77 MiInitPageDirectoryMap();
78
79 //
80 // Next, the KPCR
81 //
82 BaseAddress = (PVOID)PCR;
83 MmCreateMemoryArea(MmGetKernelAddressSpace(),
84 MEMORY_AREA_SYSTEM | MEMORY_AREA_STATIC,
85 &BaseAddress,
86 PAGE_SIZE * KeNumberProcessors,
87 PAGE_READWRITE,
88 &MArea,
89 TRUE,
90 0,
91 BoundaryAddressMultiple);
92
93 //
94 // Now the KUSER_SHARED_DATA
95 //
96 BaseAddress = (PVOID)KI_USER_SHARED_DATA;
97 MmCreateMemoryArea(MmGetKernelAddressSpace(),
98 MEMORY_AREA_SYSTEM | MEMORY_AREA_STATIC,
99 &BaseAddress,
100 PAGE_SIZE,
101 PAGE_READWRITE,
102 &MArea,
103 TRUE,
104 0,
105 BoundaryAddressMultiple);
106 }
107
108 VOID
109 NTAPI
110 MiDbgDumpMemoryDescriptors(VOID)
111 {
112 PLIST_ENTRY NextEntry;
113 PMEMORY_ALLOCATION_DESCRIPTOR Md;
114 ULONG TotalPages = 0;
115
116 DPRINT1("Base\t\tLength\t\tType\n");
117 for (NextEntry = KeLoaderBlock->MemoryDescriptorListHead.Flink;
118 NextEntry != &KeLoaderBlock->MemoryDescriptorListHead;
119 NextEntry = NextEntry->Flink)
120 {
121 Md = CONTAINING_RECORD(NextEntry, MEMORY_ALLOCATION_DESCRIPTOR, ListEntry);
122 DPRINT1("%08lX\t%08lX\t%s\n", Md->BasePage, Md->PageCount, MemType[Md->MemoryType]);
123 TotalPages += Md->PageCount;
124 }
125
126 DPRINT1("Total: %08lX (%d MB)\n", TotalPages, (TotalPages * PAGE_SIZE) / 1024 / 1024);
127 }
128
129 NTSTATUS
130 NTAPI
131 MmArmInitSystem(IN ULONG Phase,
132 IN PLOADER_PARAMETER_BLOCK LoaderBlock);
133
134 VOID
135 INIT_FUNCTION
136 NTAPI
137 MmInit1(VOID)
138 {
139 /* Initialize the kernel address space */
140 KeInitializeGuardedMutex(&PsGetCurrentProcess()->AddressCreationLock);
141 MmKernelAddressSpace = MmGetCurrentAddressSpace();
142 MmInitGlobalKernelPageDirectory();
143
144 /* Dump memory descriptors */
145 if (MiDbgEnableMdDump) MiDbgDumpMemoryDescriptors();
146
147 //
148 // Initialize ARM³ in phase 0
149 //
150 MmArmInitSystem(0, KeLoaderBlock);
151
152 /* Intialize system memory areas */
153 MiInitSystemMemoryAreas();
154
155 /* Initialize the page list */
156 MmInitializePageList();
157
158 //
159 // Initialize ARM³ in phase 1
160 //
161 MmArmInitSystem(1, KeLoaderBlock);
162
163 /* Put the paged pool after the loaded modules */
164 MmPagedPoolBase = (PVOID)PAGE_ROUND_UP((ULONG_PTR)MmSystemRangeStart +
165 MmBootImageSize);
166 MmPagedPoolSize = MM_PAGED_POOL_SIZE;
167
168 //
169 // Initialize ARM³ in phase 2
170 //
171 MmArmInitSystem(2, KeLoaderBlock);
172
173 /* Initialize paged pool */
174 MmInitializePagedPool();
175
176 /* Initialize working sets */
177 MmInitializeMemoryConsumer(MC_USER, MmTrimUserMemory);
178 }
179
180 BOOLEAN
181 NTAPI
182 MmInitSystem(IN ULONG Phase,
183 IN PLOADER_PARAMETER_BLOCK LoaderBlock)
184 {
185 extern MMPTE HyperTemplatePte;
186 PMMPTE PointerPte;
187 MMPTE TempPte = HyperTemplatePte;
188 PFN_NUMBER PageFrameNumber;
189
190 if (Phase == 0)
191 {
192 /* Initialize Mm bootstrap */
193 MmInit1();
194
195 /* Initialize the Loader Lock */
196 KeInitializeMutant(&MmSystemLoadLock, FALSE);
197
198 /* Reload boot drivers */
199 MiReloadBootLoadedDrivers(LoaderBlock);
200
201 /* Initialize the loaded module list */
202 MiInitializeLoadedModuleList(LoaderBlock);
203
204 /* Setup shared user data settings that NT does as well */
205 ASSERT(SharedUserData->NumberOfPhysicalPages == 0);
206 SharedUserData->NumberOfPhysicalPages = MmStats.NrTotalPages;
207 SharedUserData->LargePageMinimum = 0;
208
209 /* For now, we assume that we're always Server */
210 SharedUserData->NtProductType = NtProductServer;
211 }
212 else if (Phase == 1)
213 {
214 MmInitializeRmapList();
215 MmInitializePageOp();
216 MmInitSectionImplementation();
217 MmInitPagingFile();
218
219 //
220 // Create a PTE to double-map the shared data section. We allocate it
221 // from paged pool so that we can't fault when trying to touch the PTE
222 // itself (to map it), since paged pool addresses will already be mapped
223 // by the fault handler.
224 //
225 MmSharedUserDataPte = ExAllocatePoolWithTag(PagedPool,
226 sizeof(MMPTE),
227 ' mM');
228 if (!MmSharedUserDataPte) return FALSE;
229
230 //
231 // Now get the PTE for shared data, and read the PFN that holds it
232 //
233 PointerPte = MiAddressToPte(KI_USER_SHARED_DATA);
234 ASSERT(PointerPte->u.Hard.Valid == 1);
235 PageFrameNumber = PFN_FROM_PTE(PointerPte);
236
237 //
238 // Now write a copy of it
239 //
240 TempPte.u.Hard.Owner = 1;
241 TempPte.u.Hard.PageFrameNumber = PageFrameNumber;
242 *MmSharedUserDataPte = TempPte;
243
244 /*
245 * Unmap low memory
246 */
247 MiInitBalancerThread();
248
249 /*
250 * Initialise the modified page writer.
251 */
252 MmInitMpwThread();
253
254 /* Initialize the balance set manager */
255 MmInitBsmThread();
256 }
257 else if (Phase == 2)
258 {
259
260 }
261
262 return TRUE;
263 }
264