ReactOS 0.4.15-dev-6068-g8061a6f
wlmemory.c
Go to the documentation of this file.
1/*
2 * PROJECT: EFI Windows Loader
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: boot/freeldr/freeldr/windows/wlmemory.c
5 * PURPOSE: Memory related routines
6 * PROGRAMMERS: Aleksey Bragin (aleksey@reactos.org)
7 */
8
9/* INCLUDES ***************************************************************/
10
11#include <freeldr.h>
12#include "winldr.h"
13
14#include <debug.h>
16
18
19static const PCSTR MemTypeDesc[] = {
20 "ExceptionBlock ", // ?
21 "SystemBlock ", // ?
22 "Free ",
23 "Bad ", // used
24 "LoadedProgram ", // == Free
25 "FirmwareTemporary ", // == Free
26 "FirmwarePermanent ", // == Bad
27 "OsloaderHeap ", // used
28 "OsloaderStack ", // == Free
29 "SystemCode ",
30 "HalCode ",
31 "BootDriver ", // not used
32 "ConsoleInDriver ", // ?
33 "ConsoleOutDriver ", // ?
34 "StartupDpcStack ", // ?
35 "StartupKernelStack", // ?
36 "StartupPanicStack ", // ?
37 "StartupPcrPage ", // ?
38 "StartupPdrPage ", // ?
39 "RegistryData ", // used
40 "MemoryData ", // not used
41 "NlsData ", // used
42 "SpecialMemory ", // == Bad
43 "BBTMemory " // == Bad
44 };
45
46static VOID
49
54
55/* GLOBALS ***************************************************************/
56
59/* 200 MADs fit into 1 page, that should really be enough! */
60#define MAX_MAD_COUNT 200
61
62/* FUNCTIONS **************************************************************/
63
64VOID
66 PFN_NUMBER BasePage,
67 PFN_NUMBER PageCount,
68 ULONG Type)
69{
70 TRACE("MempAddMemoryBlock(BasePage=0x%lx, PageCount=0x%lx, Type=%ld)\n",
71 BasePage, PageCount, Type);
72
73 /* Check for memory block after 4GB - we don't support it yet
74 Note: Even last page before 4GB limit is not supported */
75 if (BasePage >= MM_MAX_PAGE)
76 {
77 /* Just skip this, without even adding to MAD list */
78 return;
79 }
80
81 /* Check if last page is after 4GB limit and shorten this block if needed */
82 if (BasePage + PageCount > MM_MAX_PAGE)
83 {
84 /* Shorten this block */
85 PageCount = MM_MAX_PAGE - BasePage;
86 }
87
88 /* Check if we have slots left */
90 {
91 ERR("Error: no MAD slots left!\n");
92 return;
93 }
94
95 /* Set Base page, page count and type */
96 Mad[MadCount].BasePage = BasePage;
97 Mad[MadCount].PageCount = PageCount;
99
100 /* Add descriptor */
101 WinLdrInsertDescriptor(LoaderBlock, &Mad[MadCount]);
102 MadCount++;
103}
104
105VOID
107 PFN_NUMBER BasePage,
108 PFN_NUMBER PageCount,
109 ULONG Type)
110{
112
113 TRACE("MempSetupPagingForRegion(BasePage=0x%lx, PageCount=0x%lx, Type=%ld)\n",
114 BasePage, PageCount, Type);
115
116 /* Make sure we don't map too high */
117 if (BasePage + PageCount > LoaderPagesSpanned) return;
118
119 switch (Type)
120 {
121 /* Pages used by the loader */
125 /* Map these pages into user mode */
126 Status = MempSetupPaging(BasePage, PageCount, FALSE);
127 break;
128
129 /* Pages used by the kernel */
133 case LoaderSystemCode:
134 case LoaderHalCode:
135 case LoaderBootDriver:
144 case LoaderMemoryData:
145 case LoaderNlsData:
146 case LoaderXIPRom:
147 case LoaderOsloaderHeap: // FIXME
148 /* Map these pages into kernel mode */
149 Status = MempSetupPaging(BasePage, PageCount, TRUE);
150 break;
151
152 /* Pages not in use */
153 case LoaderFree:
154 case LoaderBad:
155 break;
156
157 /* Invisible to kernel */
160 case LoaderBBTMemory:
161 break;
162
163 // FIXME: not known (not used anyway)
164 case LoaderReserve:
167 break;
168 }
169
170 if (!Status)
171 {
172 ERR("Error during MempSetupPaging\n");
173 }
174}
175
176#ifdef _M_ARM
177#define PKTSS PVOID
178#endif
179
182{
183 PFN_NUMBER i, PagesCount, MemoryMapSizeInPages, NoEntries;
184 PFN_NUMBER LastPageIndex, MemoryMapStartPage;
186 ULONG LastPageType;
187 //PKTSS Tss;
188 //BOOLEAN Status;
189
190 /* Cleanup heap */
192
193 //
194 // Creating a suitable memory map for Windows can be tricky, so let's
195 // give a few advices:
196 // 1) One must not map the whole available memory pages to PDE!
197 // Map only what's needed - 16Mb, 24Mb, 32Mb max I think,
198 // thus occupying 4, 6 or 8 PDE entries for identical mapping,
199 // the same quantity for KSEG0_BASE mapping, one more entry for
200 // hyperspace and one more entry for HAL physical pages mapping.
201 // 2) Memory descriptors must map *the whole* physical memory
202 // showing any memory above 16/24/32 as FirmwareTemporary
203 //
204 // 3) Overall memory blocks count must not exceed 30 (?? why?)
205 //
206
207 //
208 // During MmInitMachineDependent, the kernel zeroes PDE at the following address
209 // 0xC0300000 - 0xC03007FC
210 //
211 // Then it finds the best place for non-paged pool:
212 // StartPde C0300F70, EndPde C0300FF8, NumberOfPages C13, NextPhysPage 3AD
213 //
214
215 // Allocate memory for memory allocation descriptors
218
219 // Setup an entry for each descriptor
220 MemoryMap = MmGetMemoryMap(&NoEntries);
221 if (MemoryMap == NULL)
222 {
223 UiMessageBox("Can not retrieve the current memory map.");
224 return FALSE;
225 }
226
227 // Calculate parameters of the memory map
228 MemoryMapStartPage = (ULONG_PTR)MemoryMap >> MM_PAGE_SHIFT;
229 MemoryMapSizeInPages = (NoEntries * sizeof(PAGE_LOOKUP_TABLE_ITEM) + MM_PAGE_SIZE - 1) / MM_PAGE_SIZE;
230
231 TRACE("Got memory map with %d entries\n", NoEntries);
232#if 0
233 // Always contiguously map low 1Mb of memory
234 Status = MempSetupPaging(0, 0x100, FALSE);
235 if (!Status)
236 {
237 ERR("Error during MempSetupPaging of low 1Mb\n");
238 return FALSE;
239 }
240#endif
241
242 /* Before creating the map, we need to map pages to kernel mode */
243 LastPageIndex = 1;
244 LastPageType = MemoryMap[1].PageAllocated;
245 for (i = 2; i < NoEntries; i++)
246 {
247 if ((MemoryMap[i].PageAllocated != LastPageType) ||
248 (i == NoEntries - 1))
249 {
250 MempSetupPagingForRegion(LastPageIndex, i - LastPageIndex, LastPageType);
251 LastPageIndex = i;
252 LastPageType = MemoryMap[i].PageAllocated;
253 }
254 }
255
256 // Construct a good memory map from what we've got,
257 // but mark entries which the memory allocation bitmap takes
258 // as free entries (this is done in order to have the ability
259 // to place mem alloc bitmap outside lower 16Mb zone)
260 PagesCount = 1;
261 LastPageIndex = 0;
262 LastPageType = MemoryMap[0].PageAllocated;
263 for (i = 1; i < NoEntries; i++)
264 {
265 // Check if its memory map itself
266 if (i >= MemoryMapStartPage &&
267 i < (MemoryMapStartPage+MemoryMapSizeInPages))
268 {
269 // Exclude it if current page belongs to the memory map
270 MemoryMap[i].PageAllocated = LoaderFree;
271 }
272
273 // Process entry
274 if (MemoryMap[i].PageAllocated == LastPageType &&
275 (i != NoEntries-1) )
276 {
277 PagesCount++;
278 }
279 else
280 {
281 // Add the resulting region
282 MempAddMemoryBlock(LoaderBlock, LastPageIndex, PagesCount, LastPageType);
283
284 // Reset our counter vars
285 LastPageIndex = i;
286 LastPageType = MemoryMap[i].PageAllocated;
287 PagesCount = 1;
288 }
289 }
290
291 // TEMP, DEBUG!
292 // adding special reserved memory zones for vmware workstation
293#if 0
294 {
295 Mad[MadCount].BasePage = 0xfec00;
296 Mad[MadCount].PageCount = 0x10;
298 WinLdrInsertDescriptor(LoaderBlock, &Mad[MadCount]);
299 MadCount++;
300
301 Mad[MadCount].BasePage = 0xfee00;
302 Mad[MadCount].PageCount = 0x1;
304 WinLdrInsertDescriptor(LoaderBlock, &Mad[MadCount]);
305 MadCount++;
306
307 Mad[MadCount].BasePage = 0xfffe0;
308 Mad[MadCount].PageCount = 0x20;
310 WinLdrInsertDescriptor(LoaderBlock, &Mad[MadCount]);
311 MadCount++;
312 }
313#endif
314
315 /* Now we need to add high descriptors from the bios memory map */
316 for (i = 0; i < BiosMemoryMapEntryCount; i++)
317 {
318 /* Check if its higher than the lookup table */
320 {
321 /* Copy this descriptor */
322 MempAddMemoryBlock(LoaderBlock,
326 }
327 }
328
329 TRACE("MadCount: %d\n", MadCount);
330
331 WinLdrpDumpMemoryDescriptors(LoaderBlock); //FIXME: Delete!
332
333 // Map our loader image, so we can continue running
334 /*Status = MempSetupPaging(OsLoaderBase >> MM_PAGE_SHIFT, OsLoaderSize >> MM_PAGE_SHIFT);
335 if (!Status)
336 {
337 UiMessageBox("Error during MempSetupPaging.");
338 return;
339 }*/
340
341 // Fill the memory descriptor list and
342 //PrepareMemoryDescriptorList();
343 TRACE("Memory Descriptor List prepared, printing PDE\n");
344 List_PaToVa(&LoaderBlock->MemoryDescriptorListHead);
345
346#if DBG
347 MempDump();
348#endif
349
350 return TRUE;
351}
352
353// Two special things this func does: it sorts descriptors,
354// and it merges free ones
355static VOID
358{
359 PLIST_ENTRY ListHead = &LoaderBlock->MemoryDescriptorListHead;
360 PLIST_ENTRY PreviousEntry, NextEntry;
361 PMEMORY_ALLOCATION_DESCRIPTOR PreviousDescriptor = NULL, NextDescriptor = NULL;
362
363 TRACE("BP=0x%X PC=0x%X %s\n", NewDescriptor->BasePage,
364 NewDescriptor->PageCount, MemTypeDesc[NewDescriptor->MemoryType]);
365
366 /* Find a place where to insert the new descriptor to */
367 PreviousEntry = ListHead;
368 NextEntry = ListHead->Flink;
369 while (NextEntry != ListHead)
370 {
371 NextDescriptor = CONTAINING_RECORD(NextEntry,
373 ListEntry);
374 if (NewDescriptor->BasePage < NextDescriptor->BasePage)
375 break;
376
377 PreviousEntry = NextEntry;
378 PreviousDescriptor = NextDescriptor;
379 NextEntry = NextEntry->Flink;
380 }
381
382 /* Don't forget about merging free areas */
383 if (NewDescriptor->MemoryType != LoaderFree)
384 {
385 /* Just insert, nothing to merge */
386 InsertHeadList(PreviousEntry, &NewDescriptor->ListEntry);
387 }
388 else
389 {
390 /* Previous block also free? */
391 if ((PreviousEntry != ListHead) && (PreviousDescriptor->MemoryType == LoaderFree) &&
392 ((PreviousDescriptor->BasePage + PreviousDescriptor->PageCount) ==
393 NewDescriptor->BasePage))
394 {
395 /* Just enlarge previous descriptor's PageCount */
396 PreviousDescriptor->PageCount += NewDescriptor->PageCount;
397 NewDescriptor = PreviousDescriptor;
398 }
399 else
400 {
401 /* Nope, just insert */
402 InsertHeadList(PreviousEntry, &NewDescriptor->ListEntry);
403 }
404
405 /* Next block is free ?*/
406 if ((NextEntry != ListHead) &&
407 (NextDescriptor->MemoryType == LoaderFree) &&
408 ((NewDescriptor->BasePage + NewDescriptor->PageCount) == NextDescriptor->BasePage))
409 {
410 /* Enlarge next descriptor's PageCount */
411 NewDescriptor->PageCount += NextDescriptor->PageCount;
412 RemoveEntryList(&NextDescriptor->ListEntry);
413 }
414 }
415
416 return;
417}
unsigned char BOOLEAN
Type
Definition: Type.h:7
BOOLEAN MempSetupPaging(IN PFN_NUMBER StartPage, IN PFN_NUMBER NumberOfPages, IN BOOLEAN KernelMapping)
Definition: winldr.c:170
VOID MempDump(VOID)
Definition: winldr.c:429
BIOS_MEMORY_MAP MemoryMap[32]
Definition: loader.c:11
#define ERR(fmt,...)
Definition: debug.h:110
#define DBG_DEFAULT_CHANNEL(ch)
Definition: debug.h:103
PVOID MmAllocateMemoryWithType(SIZE_T MemorySize, TYPE_OF_MEMORY MemoryType)
Definition: mm.c:31
PPAGE_LOOKUP_TABLE_ITEM MmGetMemoryMap(PFN_NUMBER *NoEntries)
Definition: mm.c:297
VOID FrLdrHeapCleanupAll(VOID)
Definition: heap.c:248
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define ULONG_PTR
Definition: config.h:101
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define InsertHeadList(ListHead, Entry)
Status
Definition: gdiplustypes.h:25
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
VOID List_PaToVa(_In_ LIST_ENTRY *ListEntry)
@ LoaderBad
Definition: arc.h:177
@ LoaderMemoryData
Definition: arc.h:194
@ LoaderReserve
Definition: arc.h:198
@ LoaderBootDriver
Definition: arc.h:185
@ LoaderOsloaderHeap
Definition: arc.h:181
@ LoaderFree
Definition: arc.h:176
@ LoaderConsoleInDriver
Definition: arc.h:186
@ LoaderFirmwareTemporary
Definition: arc.h:179
@ LoaderLoadedProgram
Definition: arc.h:178
@ LoaderSystemCode
Definition: arc.h:183
@ LoaderNlsData
Definition: arc.h:195
@ LoaderLargePageFiller
Definition: arc.h:201
@ LoaderStartupDpcStack
Definition: arc.h:188
@ LoaderHALCachedMemory
Definition: arc.h:200
@ LoaderRegistryData
Definition: arc.h:193
@ LoaderHalCode
Definition: arc.h:184
@ LoaderFirmwarePermanent
Definition: arc.h:180
@ LoaderErrorLogMemory
Definition: arc.h:202
@ LoaderStartupPcrPage
Definition: arc.h:191
@ LoaderOsloaderStack
Definition: arc.h:182
@ LoaderSpecialMemory
Definition: arc.h:196
@ LoaderSystemBlock
Definition: arc.h:175
@ LoaderStartupPdrPage
Definition: arc.h:192
@ LoaderExceptionBlock
Definition: arc.h:174
@ LoaderXIPRom
Definition: arc.h:199
@ LoaderStartupKernelStack
Definition: arc.h:189
@ LoaderStartupPanicStack
Definition: arc.h:190
@ LoaderConsoleOutDriver
Definition: arc.h:187
@ LoaderBBTMemory
Definition: arc.h:197
ULONG PFN_NUMBER
Definition: ke.h:9
#define TRACE(s)
Definition: solgame.cpp:4
TYPE_OF_MEMORY MemoryType
Definition: mm.h:43
PFN_NUMBER PageCount
Definition: mm.h:45
PFN_NUMBER BasePage
Definition: mm.h:44
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
TYPE_OF_MEMORY MemoryType
Definition: arc.h:240
const char * PCSTR
Definition: typedefs.h:52
#define IN
Definition: typedefs.h:39
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
VOID UiMessageBox(PCSTR Format,...)
Definition: ui.c:357
VOID WinLdrpDumpMemoryDescriptors(PLOADER_PARAMETER_BLOCK LoaderBlock)
Definition: winldr.c:1266
#define MAX_MAD_COUNT
Definition: wlmemory.c:60
MEMORY_ALLOCATION_DESCRIPTOR * Mad
Definition: wlmemory.c:57
PFREELDR_MEMORY_DESCRIPTOR BiosMemoryMap
Definition: meminit.c:33
BOOLEAN WinLdrSetupMemoryLayout(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock)
Definition: wlmemory.c:181
static const PCSTR MemTypeDesc[]
Definition: wlmemory.c:19
PFN_NUMBER MmLowestPhysicalPage
Definition: meminit.c:30
PFN_NUMBER MmHighestPhysicalPage
Definition: meminit.c:31
static VOID WinLdrInsertDescriptor(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, IN PMEMORY_ALLOCATION_DESCRIPTOR NewDescriptor)
Definition: wlmemory.c:356
VOID MempSetupPagingForRegion(PFN_NUMBER BasePage, PFN_NUMBER PageCount, ULONG Type)
Definition: wlmemory.c:106
VOID MempAddMemoryBlock(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, PFN_NUMBER BasePage, PFN_NUMBER PageCount, ULONG Type)
Definition: wlmemory.c:65
ULONG LoaderPagesSpanned
Definition: mm.c:29
ULONG BiosMemoryMapEntryCount
Definition: meminit.c:34
ULONG MadCount
Definition: wlmemory.c:58
_In_opt_ PSECURITY_DESCRIPTOR _Out_ PSECURITY_DESCRIPTOR * NewDescriptor
Definition: sefuncs.h:30