Added Intel MultiProcessor Specification support
[reactos.git] / reactos / ntoskrnl / mm / mminit.c
1 /* $Id: mminit.c,v 1.18 2001/04/13 16:12:26 chorns Exp $
2 *
3 * COPYRIGHT: See COPYING in the top directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/mm/mminit.c
6 * PURPOSE: kernel memory managment initialization functions
7 * PROGRAMMER: David Welch (welch@cwcom.net)
8 * UPDATE HISTORY:
9 * Created 9/4/98
10 */
11
12 /* INCLUDES *****************************************************************/
13
14 #include <ddk/ntddk.h>
15 #include <internal/config.h>
16 #include <internal/i386/segment.h>
17 #include <internal/mm.h>
18 #include <internal/ntoskrnl.h>
19 #include <internal/bitops.h>
20 #include <internal/io.h>
21 #include <internal/ps.h>
22 #include <napi/shared_data.h>
23
24 #define NDEBUG
25 #include <internal/debug.h>
26
27 /* GLOBALS *****************************************************************/
28
29 /*
30 * Size of extended memory (kb) (fixed for now)
31 */
32 #define EXTENDED_MEMORY_SIZE (3*1024*1024)
33
34 /*
35 * Compiler defined symbols
36 */
37 extern unsigned int _text_start__;
38 extern unsigned int _text_end__;
39
40 static BOOLEAN IsThisAnNtAsSystem = FALSE;
41 static MM_SYSTEM_SIZE MmSystemSize = MmSmallSystem;
42
43 extern unsigned int _bss_end__;
44
45 static MEMORY_AREA* kernel_text_desc = NULL;
46 static MEMORY_AREA* kernel_data_desc = NULL;
47 static MEMORY_AREA* kernel_param_desc = NULL;
48 static MEMORY_AREA* kernel_pool_desc = NULL;
49 static MEMORY_AREA* kernel_shared_data_desc = NULL;
50
51 PVOID MmSharedDataPagePhysicalAddress = NULL;
52
53 /* FUNCTIONS ****************************************************************/
54
55 BOOLEAN STDCALL MmIsThisAnNtAsSystem(VOID)
56 {
57 return(IsThisAnNtAsSystem);
58 }
59
60 MM_SYSTEM_SIZE STDCALL MmQuerySystemSize(VOID)
61 {
62 return(MmSystemSize);
63 }
64
65 VOID MiShutdownMemoryManager(VOID)
66 {
67 }
68
69 VOID MmInitVirtualMemory(ULONG LastKernelAddress,
70 ULONG KernelLength)
71 /*
72 * FUNCTION: Intialize the memory areas list
73 * ARGUMENTS:
74 * bp = Pointer to the boot parameters
75 * kernel_len = Length of the kernel
76 */
77 {
78 PVOID BaseAddress;
79 ULONG Length;
80 ULONG ParamLength = KernelLength;
81 NTSTATUS Status;
82
83 DPRINT("MmInitVirtualMemory(%x, %x)\n",LastKernelAddress, KernelLength);
84
85 LastKernelAddress = PAGE_ROUND_UP(LastKernelAddress);
86
87 MmInitMemoryAreas();
88 // ExInitNonPagedPool(KERNEL_BASE + PAGE_ROUND_UP(kernel_len) + PAGESIZE);
89 ExInitNonPagedPool(LastKernelAddress + PAGESIZE);
90
91
92 /*
93 * Setup the system area descriptor list
94 */
95 BaseAddress = (PVOID)KERNEL_BASE;
96 Length = PAGE_ROUND_UP(((ULONG)&_text_end__)) - KERNEL_BASE;
97 ParamLength = ParamLength - Length;
98 MmCreateMemoryArea(NULL,
99 MmGetKernelAddressSpace(),
100 MEMORY_AREA_SYSTEM,
101 &BaseAddress,
102 Length,
103 0,
104 &kernel_text_desc,
105 FALSE);
106 Length = PAGE_ROUND_UP(((ULONG)&_bss_end__)) -
107 PAGE_ROUND_UP(((ULONG)&_text_end__));
108 ParamLength = ParamLength - Length;
109 DPRINT("Length %x\n",Length);
110 BaseAddress = (PVOID)PAGE_ROUND_UP(((ULONG)&_text_end__));
111 DPRINT("BaseAddress %x\n",BaseAddress);
112 MmCreateMemoryArea(NULL,
113 MmGetKernelAddressSpace(),
114 MEMORY_AREA_SYSTEM,
115 &BaseAddress,
116 Length,
117 0,
118 &kernel_data_desc,
119 FALSE);
120
121 BaseAddress = (PVOID)PAGE_ROUND_UP(((ULONG)&_bss_end__));
122 // Length = ParamLength;
123 Length = LastKernelAddress - (ULONG)BaseAddress;
124 MmCreateMemoryArea(NULL,
125 MmGetKernelAddressSpace(),
126 MEMORY_AREA_SYSTEM,
127 &BaseAddress,
128 Length,
129 0,
130 &kernel_param_desc,
131 FALSE);
132
133 BaseAddress = (PVOID)(LastKernelAddress + PAGESIZE);
134 Length = NONPAGED_POOL_SIZE;
135 MmCreateMemoryArea(NULL,
136 MmGetKernelAddressSpace(),
137 MEMORY_AREA_SYSTEM,
138 &BaseAddress,
139 Length,
140 0,
141 &kernel_pool_desc,
142 FALSE);
143
144 BaseAddress = (PVOID)KERNEL_SHARED_DATA_BASE;
145 Length = PAGESIZE;
146 MmCreateMemoryArea(NULL,
147 MmGetKernelAddressSpace(),
148 MEMORY_AREA_SYSTEM,
149 &BaseAddress,
150 Length,
151 0,
152 &kernel_shared_data_desc,
153 FALSE);
154
155 MmSharedDataPagePhysicalAddress = MmAllocPage(0);
156 Status = MmCreateVirtualMapping(NULL,
157 (PVOID)KERNEL_SHARED_DATA_BASE,
158 PAGE_READWRITE,
159 (ULONG)MmSharedDataPagePhysicalAddress);
160 if (!NT_SUCCESS(Status))
161 {
162 DbgPrint("Unable to create virtual mapping\n");
163 KeBugCheck(0);
164 }
165 ((PKUSER_SHARED_DATA)KERNEL_SHARED_DATA_BASE)->TickCountLow = 0xdeadbeef;
166
167 // MmDumpMemoryAreas();
168 DPRINT("MmInitVirtualMemory() done\n");
169 }
170
171 VOID MmInit1(ULONG FirstKrnlPhysAddr,
172 ULONG LastKrnlPhysAddr,
173 ULONG LastKernelAddress)
174 /*
175 * FUNCTION: Initalize memory managment
176 */
177 {
178 ULONG i;
179 ULONG kernel_len;
180 #ifndef MP
181 extern unsigned int unmap_me, unmap_me2, unmap_me3;
182 #endif
183
184 DPRINT("MmInit1(FirstKrnlPhysAddr, %x, LastKrnlPhysAddr %x, LastKernelAddress %x)\n",
185 FirstKrnlPhysAddr,
186 LastKrnlPhysAddr,
187 LastKernelAddress);
188
189 /*
190 * FIXME: Set this based on the system command line
191 */
192 MmUserProbeAddress = (PVOID)0x7fff0000;
193 MmHighestUserAddress = (PVOID)0x7ffeffff;
194
195 /*
196 * Initialize memory managment statistics
197 */
198 MmStats.NrTotalPages = 0;
199 MmStats.NrSystemPages = 0;
200 MmStats.NrUserPages = 0;
201 MmStats.NrReservedPages = 0;
202 MmStats.NrUserPages = 0;
203 MmStats.NrFreePages = 0;
204 MmStats.NrLockedPages = 0;
205 MmStats.PagingRequestsInLastMinute = 0;
206 MmStats.PagingRequestsInLastFiveMinutes = 0;
207 MmStats.PagingRequestsInLastFifteenMinutes = 0;
208
209 /*
210 * Initialize the kernel address space
211 */
212 MmInitializeKernelAddressSpace();
213
214 /*
215 * Unmap low memory
216 */
217 #ifndef MP
218 /* FIXME: This is broken in SMP mode */
219 MmDeletePageTable(NULL, 0);
220 #endif
221 /*
222 * Free all pages not used for kernel memory
223 * (we assume the kernel occupies a continuous range of physical
224 * memory)
225 */
226 DPRINT("first krnl %x\nlast krnl %x\n",FirstKrnlPhysAddr,
227 LastKrnlPhysAddr);
228
229 /*
230 * Free physical memory not used by the kernel
231 */
232 MmStats.NrTotalPages = KeLoaderBlock.MemHigher/4;
233 if (!MmStats.NrTotalPages)
234 {
235 DbgPrint("Memory not detected, default to 8 MB\n");
236 MmStats.NrTotalPages = 2048;
237 }
238 else
239 {
240 /* add 1MB for standard memory (not extended) */
241 MmStats.NrTotalPages += 256;
242 }
243 DbgPrint("Used memory %dKb\n", (MmStats.NrTotalPages * PAGESIZE) / 1024);
244
245 LastKernelAddress = (ULONG)MmInitializePageList(
246 (PVOID)FirstKrnlPhysAddr,
247 (PVOID)LastKrnlPhysAddr,
248 MmStats.NrTotalPages,
249 PAGE_ROUND_UP(LastKernelAddress));
250 kernel_len = LastKrnlPhysAddr - FirstKrnlPhysAddr;
251
252 /*
253 * Create a trap for null pointer references and protect text
254 * segment
255 */
256 CHECKPOINT;
257 DPRINT("_text_start__ %x _text_end__ %x\n",(int)&_text_start__,(int)&_text_end__);
258 for (i=PAGE_ROUND_UP(((int)&_text_start__));
259 i<PAGE_ROUND_DOWN(((int)&_text_end__));i=i+PAGESIZE)
260 {
261 MmSetPageProtect(NULL,
262 (PVOID)i,
263 PAGE_EXECUTE_READ);
264 }
265
266 DPRINT("Invalidating between %x and %x\n",
267 LastKernelAddress,
268 KERNEL_BASE + PAGE_TABLE_SIZE);
269 for (i=(LastKernelAddress);
270 i<(KERNEL_BASE + PAGE_TABLE_SIZE);
271 i=i+PAGESIZE)
272 {
273 MmDeleteVirtualMapping(NULL, (PVOID)(i), FALSE, NULL, NULL);
274 }
275 DPRINT("Almost done MmInit()\n");
276 #ifndef MP
277 /* FIXME: This is broken in SMP mode */
278 MmDeleteVirtualMapping(NULL, (PVOID)&unmap_me, FALSE, NULL, NULL);
279 MmDeleteVirtualMapping(NULL, (PVOID)&unmap_me2, FALSE, NULL, NULL);
280 MmDeleteVirtualMapping(NULL, (PVOID)&unmap_me3, FALSE, NULL, NULL);
281 #endif
282 /*
283 * Intialize memory areas
284 */
285 MmInitVirtualMemory(LastKernelAddress, kernel_len);
286 }
287
288 VOID MmInit2(VOID)
289 {
290 MmInitSectionImplementation();
291 MmInitPagingFile();
292 }
293
294 VOID MmInit3(VOID)
295 {
296 MmInitPagerThread();
297 MmCreatePhysicalMemorySection();
298
299 /* FIXME: Read parameters from memory */
300 }
301