ReactOS 0.4.16-dev-981-g80eb313
mm.h File Reference
#include <pshpack1.h>
#include <poppack.h>
Include dependency graph for mm.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  _FREELDR_MEMORY_DESCRIPTOR
 
struct  PAGE_LOOKUP_TABLE_ITEM
 

Macros

#define FREELDR_SECTION_COUNT   3
 
#define HEAP_PAGES   0x400
 
#define STACK_PAGES   0x00
 
#define DUMP_MEM_MAP_ON_VERIFY   0
 
#define DEFAULT_HEAP_SIZE   (1024 * 1024)
 
#define TEMP_HEAP_SIZE   (32 * 1024 * 1024)
 

Typedefs

typedef struct _FREELDR_MEMORY_DESCRIPTOR FREELDR_MEMORY_DESCRIPTOR
 
typedef struct _FREELDR_MEMORY_DESCRIPTORPFREELDR_MEMORY_DESCRIPTOR
 
typedef struct PAGE_LOOKUP_TABLE_ITEMPPAGE_LOOKUP_TABLE_ITEM
 

Functions

PFN_NUMBER MmGetPageNumberFromAddress (PVOID Address)
 
PFN_NUMBER MmGetAddressablePageCountIncludingHoles (VOID)
 
PVOID MmFindLocationForPageLookupTable (PFN_NUMBER TotalPageCount)
 
VOID MmInitPageLookupTable (PVOID PageLookupTable, PFN_NUMBER TotalPageCount)
 
VOID MmMarkPagesInLookupTable (PVOID PageLookupTable, PFN_NUMBER StartPage, PFN_NUMBER PageCount, TYPE_OF_MEMORY PageAllocated)
 
VOID MmAllocatePagesInLookupTable (PVOID PageLookupTable, PFN_NUMBER StartPage, PFN_NUMBER PageCount, TYPE_OF_MEMORY MemoryType)
 
PFN_NUMBER MmCountFreePagesInLookupTable (PVOID PageLookupTable, PFN_NUMBER TotalPageCount)
 
PFN_NUMBER MmFindAvailablePages (PVOID PageLookupTable, PFN_NUMBER TotalPageCount, PFN_NUMBER PagesNeeded, BOOLEAN FromEnd)
 
PFN_NUMBER MmFindAvailablePagesBeforePage (PVOID PageLookupTable, PFN_NUMBER TotalPageCount, PFN_NUMBER PagesNeeded, PFN_NUMBER LastPage)
 
VOID MmUpdateLastFreePageHint (PVOID PageLookupTable, PFN_NUMBER TotalPageCount)
 
BOOLEAN MmAreMemoryPagesAvailable (PVOID PageLookupTable, PFN_NUMBER TotalPageCount, PVOID PageAddress, PFN_NUMBER PageCount)
 
VOID MmSetMemoryType (PVOID MemoryAddress, SIZE_T MemorySize, TYPE_OF_MEMORY NewType)
 
PPAGE_LOOKUP_TABLE_ITEM MmGetMemoryMap (PFN_NUMBER *NoEntries)
 
PFN_NUMBER MmGetTotalPagesInLookupTable (VOID)
 
BOOLEAN MmInitializeMemoryManager (VOID)
 
VOID MmInitializeHeap (PVOID PageLookupTable)
 
PVOID MmAllocateMemory (SIZE_T MemorySize)
 
PVOID MmAllocateMemoryWithType (SIZE_T MemorySize, TYPE_OF_MEMORY MemoryType)
 
VOID MmFreeMemory (PVOID MemoryPointer)
 
PVOID MmAllocateMemoryAtAddress (SIZE_T MemorySize, PVOID DesiredAddress, TYPE_OF_MEMORY MemoryType)
 
PVOID MmAllocateHighestMemoryBelowAddress (SIZE_T MemorySize, PVOID DesiredAddress, TYPE_OF_MEMORY MemoryType)
 
PFN_NUMBER MmGetHighestPhysicalPage (VOID)
 
PFN_NUMBER MmGetLoaderPagesSpanned (VOID)
 
ULONG MmGetBiosMemoryMap (_Out_ PFREELDR_MEMORY_DESCRIPTOR *MemoryMap)
 
PVOID FrLdrHeapCreate (SIZE_T MaximumSize, TYPE_OF_MEMORY MemoryType)
 
VOID FrLdrHeapDestroy (PVOID HeapHandle)
 
VOID FrLdrHeapRelease (PVOID HeapHandle)
 
VOID FrLdrHeapVerify (PVOID HeapHandle)
 
VOID FrLdrHeapCleanupAll (VOID)
 
PVOID FrLdrHeapAllocateEx (PVOID HeapHandle, SIZE_T ByteSize, ULONG Tag)
 
VOID FrLdrHeapFreeEx (PVOID HeapHandle, PVOID Pointer, ULONG Tag)
 
PVOID FrLdrHeapAlloc (SIZE_T MemorySize, ULONG Tag)
 
VOID FrLdrHeapFree (PVOID MemoryPointer, ULONG Tag)
 
PVOID FrLdrTempAlloc (_In_ SIZE_T Size, _In_ ULONG Tag)
 
VOID FrLdrTempFree (PVOID Allocation, ULONG Tag)
 

Variables

char __ImageBase
 
PVOID PageLookupTableAddress
 
PFN_NUMBER TotalPagesInLookupTable
 
PFN_NUMBER FreePagesInLookupTable
 
PFN_NUMBER LastFreePageHint
 
SIZE_T FrLdrImageSize
 

Macro Definition Documentation

◆ DEFAULT_HEAP_SIZE

#define DEFAULT_HEAP_SIZE   (1024 * 1024)

Definition at line 137 of file mm.h.

◆ DUMP_MEM_MAP_ON_VERIFY

#define DUMP_MEM_MAP_ON_VERIFY   0

Definition at line 96 of file mm.h.

◆ FREELDR_SECTION_COUNT

#define FREELDR_SECTION_COUNT   3

Definition at line 37 of file mm.h.

◆ HEAP_PAGES

#define HEAP_PAGES   0x400

Definition at line 80 of file mm.h.

◆ STACK_PAGES

#define STACK_PAGES   0x00

Definition at line 81 of file mm.h.

◆ TEMP_HEAP_SIZE

#define TEMP_HEAP_SIZE   (32 * 1024 * 1024)

Definition at line 138 of file mm.h.

Typedef Documentation

◆ FREELDR_MEMORY_DESCRIPTOR

◆ PFREELDR_MEMORY_DESCRIPTOR

◆ PPAGE_LOOKUP_TABLE_ITEM

Function Documentation

◆ FrLdrHeapAlloc()

◆ FrLdrHeapAllocateEx()

PVOID FrLdrHeapAllocateEx ( PVOID  HeapHandle,
SIZE_T  ByteSize,
ULONG  Tag 
)

Definition at line 321 of file heap.c.

325{
326 PHEAP Heap = HeapHandle;
327 PHEAP_BLOCK Block, NextBlock;
328 USHORT BlockSize, Remaining;
329#if DBG && !defined(_M_ARM)
331#endif
332
333#ifdef FREELDR_HEAP_VERIFIER
334 /* Verify the heap */
335 FrLdrHeapVerify(HeapHandle);
336
337 /* Add space for a size field and 2 redzones */
339#endif
340
341 /* Check if the allocation is too large */
342 if ((ByteSize + sizeof(HEAP_BLOCK)) > MAXUSHORT * sizeof(HEAP_BLOCK))
343 {
344 ERR("HEAP: Allocation of 0x%lx bytes too large\n", ByteSize);
345 return NULL;
346 }
347
348 /* We need a proper tag */
349 if (Tag == 0) Tag = 'enoN';
350
351 /* Calculate alloc size */
352 BlockSize = (USHORT)((ByteSize + sizeof(HEAP_BLOCK) - 1) / sizeof(HEAP_BLOCK));
353
354 /* Walk the free block list */
355 Block = &Heap->Blocks + Heap->TerminatingBlock;
356 for (Block = &Heap->Blocks + Block->Data[0].Flink;
357 Block->Size != 0;
358 Block = &Heap->Blocks + Block->Data[0].Flink)
359 {
360 ASSERT(Block->Tag == 0);
361
362 /* Continue, if its too small */
363 if (Block->Size < BlockSize) continue;
364
365 /* This block is just fine, use it */
366 Block->Tag = Tag;
367
368 /* Remove this entry from the free list */
369 FrLdrHeapRemoveFreeList(Heap, Block);
370
371 /* Calculate the remaining size */
372 Remaining = Block->Size - BlockSize;
373
374 /* Check if the remaining space is large enough for a new block */
375 if (Remaining > 1)
376 {
377 /* Make the allocated block as large as necessary */
378 Block->Size = BlockSize;
379
380 /* Get pointer to the new block */
381 NextBlock = Block + 1 + BlockSize;
382
383 /* Make it a free block */
384 NextBlock->Tag = 0;
385 NextBlock->Size = Remaining - 1;
386 NextBlock->PreviousSize = BlockSize;
387 BlockSize = NextBlock->Size;
389
390 /* Advance to the next block */
391 NextBlock = NextBlock + 1 + BlockSize;
392 }
393 else
394 {
395 /* Not enough left, use the full block */
396 BlockSize = Block->Size;
397
398 /* Get the next block */
399 NextBlock = Block + 1 + BlockSize;
400 }
401
402 /* Update the next blocks back link */
403 NextBlock->PreviousSize = BlockSize;
404
405 /* Update heap usage */
406 Heap->NumAllocs++;
407 Heap->CurrentAllocBytes += Block->Size * sizeof(HEAP_BLOCK);
408 Heap->MaxAllocBytes = max(Heap->MaxAllocBytes, Heap->CurrentAllocBytes);
410 Block->Size * sizeof(HEAP_BLOCK));
411#if DBG && !defined(_M_ARM)
412 Heap->AllocationTime += (__rdtsc() - Time);
413#endif
414 TRACE("HeapAllocate(%p, %ld, %.4s) -> return %p\n",
415 HeapHandle, ByteSize, &Tag, Block->Data);
416
417 /* HACK: zero out the allocation */
418 RtlZeroMemory(Block->Data, Block->Size * sizeof(HEAP_BLOCK));
419
420#ifdef FREELDR_HEAP_VERIFIER
421 /* Write size and redzones */
423 *REDZONE_LOW(Block) = REDZONE_MARK;
424 *REDZONE_HI(Block) = REDZONE_MARK;
425
426 /* Allocation starts after size field and redzone */
427 return (PUCHAR)Block->Data + REDZONE_LOW_OFFSET;
428#endif
429 /* Return pointer to the data */
430 return Block->Data;
431 }
432
433 /* We found nothing */
434 WARN("HEAP: nothing suitable found for 0x%lx bytes\n", ByteSize);
435 return NULL;
436}
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
struct _HEAP_BLOCK HEAP_BLOCK
#define REDZONE_SIZE(Block)
Definition: heap.c:30
#define REDZONE_ALLOCATION
Definition: heap.c:28
static VOID FrLdrHeapInsertFreeList(PHEAP Heap, PHEAP_BLOCK FreeBlock)
Definition: heap.c:299
#define REDZONE_LOW(Block)
Definition: heap.c:31
static VOID FrLdrHeapRemoveFreeList(PHEAP Heap, PHEAP_BLOCK Block)
Definition: heap.c:281
#define REDZONE_LOW_OFFSET
Definition: heap.c:29
VOID FrLdrHeapVerify(PVOID HeapHandle)
Definition: heap.c:157
#define REDZONE_MARK
Definition: heap.c:27
#define REDZONE_HI(Block)
Definition: heap.c:32
#define NULL
Definition: types.h:112
PPC_QUAL unsigned long long __rdtsc(void)
Definition: intrin_ppc.h:688
static LPDATABLOCK_HEADER NextBlock(LPDATABLOCK_HEADER pdbh)
Definition: lnktool.cpp:336
#define ASSERT(a)
Definition: mode.c:44
static PLARGE_INTEGER Time
Definition: time.c:105
unsigned short USHORT
Definition: pedump.c:61
#define TRACE(s)
Definition: solgame.cpp:4
ULONG_PTR Flink
Definition: heap.c:39
USHORT Size
Definition: heap.c:45
ULONG Tag
Definition: heap.c:47
BLOCK_DATA Data[]
Definition: heap.c:48
Definition: heap.c:52
SIZE_T LargestAllocation
Definition: heap.c:58
ULONG_PTR TerminatingBlock
Definition: heap.c:61
SIZE_T CurrentAllocBytes
Definition: heap.c:54
HEAP_BLOCK Blocks
Definition: heap.c:62
SIZE_T MaxAllocBytes
Definition: heap.c:55
ULONG NumAllocs
Definition: heap.c:56
ULONGLONG AllocationTime
Definition: heap.c:59
#define max(a, b)
Definition: svc.c:63
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define MAXUSHORT
Definition: typedefs.h:83
unsigned char * PUCHAR
Definition: typedefs.h:53
uint64_t ULONGLONG
Definition: typedefs.h:67
_IRQL_requires_same_ _In_ CLONG ByteSize
Definition: rtltypes.h:412

Referenced by ExAllocatePool(), ExAllocatePoolWithTag(), FrLdrHeapAlloc(), FrLdrTempAlloc(), and RtlAllocateHeap().

◆ FrLdrHeapCleanupAll()

VOID FrLdrHeapCleanupAll ( VOID  )

Definition at line 249 of file heap.c.

250{
251#if DBG
252 PHEAP Heap;
253
254 Heap = FrLdrDefaultHeap;
255 TRACE("Heap statistics for default heap:\n"
256 "CurrentAlloc=0x%lx, MaxAlloc=0x%lx, LargestAllocation=0x%lx\n"
257 "NumAllocs=%ld, NumFrees=%ld\n",
259 Heap->NumAllocs, Heap->NumFrees);
260 TRACE("AllocTime = %I64d, FreeTime = %I64d, sum = %I64d\n",
261 Heap->AllocationTime, Heap->FreeTime, Heap->AllocationTime + Heap->FreeTime);
262#endif
263
264 /* Release free pages from the default heap */
266
267#if DBG
268 Heap = FrLdrTempHeap;
269 TRACE("Heap statistics for temp heap:\n"
270 "CurrentAlloc=0x%lx, MaxAlloc=0x%lx, LargestAllocation=0x%lx\n"
271 "NumAllocs=%ld, NumFrees=%ld\n",
273 Heap->NumAllocs, Heap->NumFrees);
274#endif
275
276 /* Destroy the temp heap */
278}
VOID FrLdrHeapDestroy(PVOID HeapHandle)
Definition: heap.c:138
VOID FrLdrHeapRelease(PVOID HeapHandle)
Definition: heap.c:182
static PVOID FrLdrTempHeap
Definition: heap.c:35
ULONGLONG FreeTime
Definition: heap.c:60
ULONG NumFrees
Definition: heap.c:57

Referenced by WinLdrSetupMemoryLayout().

◆ FrLdrHeapCreate()

PVOID FrLdrHeapCreate ( SIZE_T  MaximumSize,
TYPE_OF_MEMORY  MemoryType 
)

Definition at line 66 of file heap.c.

69{
70 PHEAP Heap;
71 PHEAP_BLOCK Block;
72 SIZE_T Remaining;
73 USHORT PreviousSize;
74
75 TRACE("HeapCreate(MemoryType=%ld)\n", MemoryType);
76
77 /* Allocate some memory for the heap */
78 MaximumSize = ALIGN_UP_BY(MaximumSize, MM_PAGE_SIZE);
79 Heap = MmAllocateMemoryWithType(MaximumSize, MemoryType);
80 if (!Heap)
81 {
82 ERR("HEAP: Failed to allocate heap of size 0x%lx, Type %lu\n",
83 MaximumSize, MemoryType);
84 return NULL;
85 }
86
87 /* Initialize the heap header */
89 Heap->CurrentAllocBytes = 0;
90 Heap->MaxAllocBytes = 0;
91 Heap->NumAllocs = 0;
92 Heap->NumFrees = 0;
93 Heap->LargestAllocation = 0;
94
95 /* Calculate what's left to process */
96 Remaining = (MaximumSize - sizeof(HEAP)) / sizeof(HEAP_BLOCK);
97 TRACE("Remaining = %ld\n", Remaining);
98
99 /* Substract 2 for the terminating entry (header + free entry) */
100 Remaining -= 2;
101
102 Block = &Heap->Blocks;
103 PreviousSize = 0;
104
105 /* Create free blocks */
106 while (Remaining > 1)
107 {
108 /* Initialize this free block */
109 Block->Size = (USHORT)min(MAXUSHORT, Remaining - 1);
110 Block->PreviousSize = PreviousSize;
111 Block->Tag = 0;
112 Block->Data[0].Flink = (Block - &Heap->Blocks) + Block->Size + 1;
113 Block->Data[0].Blink = (Block - &Heap->Blocks) - 1 - PreviousSize;
114
115 /* Substract current block size from remainder */
116 Remaining -= (Block->Size + 1);
117
118 /* Go to next block */
119 PreviousSize = Block->Size;
120 Block = Block + Block->Size + 1;
121
122 TRACE("Remaining = %ld\n", Remaining);
123 }
124
125 /* Now finish with a terminating block */
126 Heap->TerminatingBlock = Block - &Heap->Blocks;
127 Block->Size = 0;
128 Block->PreviousSize = PreviousSize;
129 Block->Tag = 'dnE#';
130 Block->Data[0].Flink = 0;
131 Block->Data[0].Blink = (Block - &Heap->Blocks) - 1 - PreviousSize;
132 Heap->Blocks.Data[0].Blink = Heap->TerminatingBlock;
133
134 return Heap;
135}
#define ALIGN_UP_BY(size, align)
PVOID MmAllocateMemoryWithType(SIZE_T MemorySize, TYPE_OF_MEMORY MemoryType)
Definition: mm.c:31
struct _HEAP HEAP
#define min(a, b)
Definition: monoChain.cc:55
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_opt_ PLARGE_INTEGER MaximumSize
Definition: mmfuncs.h:362
ULONG_PTR Blink
Definition: heap.c:40
USHORT PreviousSize
Definition: heap.c:46
SIZE_T MaximumSize
Definition: heap.c:53
ULONG_PTR SIZE_T
Definition: typedefs.h:80

Referenced by MmInitializeHeap().

◆ FrLdrHeapDestroy()

VOID FrLdrHeapDestroy ( PVOID  HeapHandle)

Definition at line 138 of file heap.c.

140{
141 PHEAP Heap = HeapHandle;
142
143 /* Mark all pages as firmware temporary, so they are free for the kernel */
145 (ULONG_PTR)Heap / MM_PAGE_SIZE,
146 (PFN_COUNT)(Heap->MaximumSize / MM_PAGE_SIZE),
148
149#if DBG
150 /* Make sure everything is dead */
151 RtlFillMemory(Heap, Heap->MaximumSize, 0xCCCCCCCC);
152#endif
153}
PVOID PageLookupTableAddress
Definition: meminit.c:26
VOID MmMarkPagesInLookupTable(PVOID PageLookupTable, PFN_NUMBER StartPage, PFN_NUMBER PageCount, TYPE_OF_MEMORY PageAllocated)
Definition: meminit.c:527
#define RtlFillMemory(Dest, Length, Fill)
Definition: winternl.h:599
@ LoaderFirmwareTemporary
Definition: arc.h:179
uint32_t ULONG_PTR
Definition: typedefs.h:65
ULONG PFN_COUNT
Definition: mmtypes.h:102

Referenced by FrLdrHeapCleanupAll().

◆ FrLdrHeapFree()

VOID FrLdrHeapFree ( PVOID  MemoryPointer,
ULONG  Tag 
)

◆ FrLdrHeapFreeEx()

VOID FrLdrHeapFreeEx ( PVOID  HeapHandle,
PVOID  Pointer,
ULONG  Tag 
)

Definition at line 439 of file heap.c.

443{
444 PHEAP Heap = HeapHandle;
445 PHEAP_BLOCK Block, PrevBlock, NextBlock;
446#if DBG && !defined(_M_ARM)
448#endif
449
450 TRACE("HeapFree(%p, %p)\n", HeapHandle, Pointer);
451 ASSERT(Tag != 'dnE#');
452
453#ifdef FREELDR_HEAP_VERIFIER
454 /* Verify the heap */
455 FrLdrHeapVerify(HeapHandle);
456#endif
457
458 /* Check if the block is really inside this heap */
459 if ((Pointer < (PVOID)(Heap + 1)) ||
460 (Pointer > (PVOID)((PUCHAR)Heap + Heap->MaximumSize)))
461 {
462 ERR("HEAP: trying to free %p outside of heap %p\n", Pointer, Heap);
463 ASSERT(FALSE);
464 }
465
466 Block = ((PHEAP_BLOCK)Pointer) - 1;
467#ifdef FREELDR_HEAP_VERIFIER
468 Block = (PHEAP_BLOCK)((PUCHAR)Block - REDZONE_LOW_OFFSET);
469
470 /* Verify size and redzones */
471 ASSERT(*REDZONE_SIZE(Block) <= Block->Size * sizeof(HEAP_BLOCK));
472 ASSERT(*REDZONE_LOW(Block) == REDZONE_MARK);
473 ASSERT(*REDZONE_HI(Block) == REDZONE_MARK);
474#endif
475
476 /* Check if the tag matches */
477 if ((Tag && (Block->Tag != Tag)) || (Block->Tag == 0))
478 {
479 ERR("HEAP: Bad tag! Pointer=%p: block tag '%.4s', requested '%.4s', size=0x%lx\n",
480 Pointer, &Block->Tag, &Tag, Block->Size);
481 ASSERT(FALSE);
482 }
483
484 /* Mark as free */
485 Block->Tag = 0;
486
487#if DBG
488 /* Erase contents */
489 RtlFillMemory(Block->Data, Block->Size * sizeof(HEAP_BLOCK), 0xCCCCCCCC);
490#endif
491
492 /* Update heap usage */
493 Heap->NumFrees++;
494 Heap->CurrentAllocBytes -= Block->Size * sizeof(HEAP_BLOCK);
495
496 /* Get pointers to the next and previous block */
497 PrevBlock = Block - Block->PreviousSize - 1;
498 NextBlock = Block + Block->Size + 1;
499
500 /* Check if next block is free */
501 if ((NextBlock->Tag == 0) &&
502 ((Block->Size + NextBlock->Size + 1) <= MAXUSHORT))
503 {
504 /* Merge next block into current */
505 Block->Size += NextBlock->Size + 1;
507
508 NextBlock = Block + Block->Size + 1;
509 }
510
511 /* Check if there is a block before and it's free */
512 if ((Block->PreviousSize != 0) && (PrevBlock->Tag == 0) &&
513 ((PrevBlock->Size + Block->Size + 1) <= MAXUSHORT))
514 {
515 /* Merge current block into previous */
516 PrevBlock->Size += Block->Size + 1;
517 Block = PrevBlock;
518 }
519 else
520 {
521 /* Insert the entry into the free list */
522 FrLdrHeapInsertFreeList(Heap, Block);
523 }
524
525 /* Update the next block's back link */
526 NextBlock->PreviousSize = Block->Size;
527#if DBG && !defined(_M_ARM)
528 Heap->FreeTime += (__rdtsc() - Time);
529#endif
530}
struct _HEAP_BLOCK * PHEAP_BLOCK
#define FALSE
Definition: types.h:117

Referenced by ExFreePool(), ExFreePoolWithTag(), FrLdrHeapFree(), FrLdrTempFree(), and RtlFreeHeap().

◆ FrLdrHeapRelease()

VOID FrLdrHeapRelease ( PVOID  HeapHandle)

Definition at line 182 of file heap.c.

184{
185 PHEAP Heap = HeapHandle;
186 PHEAP_BLOCK Block;
187 PUCHAR StartAddress, EndAddress;
188 PFN_COUNT FreePages, AllFreePages = 0;
189
190 TRACE("HeapRelease(%p)\n", HeapHandle);
191
192 /* Loop all heap chunks */
193 for (Block = &Heap->Blocks;
194 Block->Size != 0;
195 Block = Block + 1 + Block->Size)
196 {
197 /* Continue, if its not free */
198 if (Block->Tag != 0)
199 {
200#ifdef FREELDR_HEAP_VERIFIER
201 /* Verify size and redzones */
202 ASSERT(*REDZONE_SIZE(Block) <= Block->Size * sizeof(HEAP_BLOCK));
203 ASSERT(*REDZONE_LOW(Block) == REDZONE_MARK);
204 ASSERT(*REDZONE_HI(Block) == REDZONE_MARK);
205#endif
206 continue;
207 }
208
209 /* Calculate page aligned start address of the free region */
210 StartAddress = ALIGN_UP_POINTER_BY(Block->Data, PAGE_SIZE);
211
212 /* Walk over adjacent free blocks */
213 while (Block->Tag == 0) Block = Block + Block->Size + 1;
214
215 /* Check if this was the last block */
216 if (Block->Size == 0)
217 {
218 /* Align the end address up to cover the end of the heap */
219 EndAddress = ALIGN_UP_POINTER_BY(Block->Data, PAGE_SIZE);
220 }
221 else
222 {
223 /* Align the end address down to not cover any allocations */
224 EndAddress = ALIGN_DOWN_POINTER_BY(Block->Data, PAGE_SIZE);
225 }
226
227 /* Check if we have free pages */
228 if (EndAddress > StartAddress)
229 {
230 /* Calculate the size of the free region in pages */
231 FreePages = (PFN_COUNT)((EndAddress - StartAddress) / MM_PAGE_SIZE);
232 AllFreePages += FreePages;
233
234 /* Now mark the pages free */
236 (ULONG_PTR)StartAddress / MM_PAGE_SIZE,
237 FreePages,
238 LoaderFree);
239 }
240
241 /* bail out, if it was the last block */
242 if (Block->Size == 0) break;
243 }
244
245 TRACE("HeapRelease() done, freed %lu of %lu pages\n", AllFreePages, Heap->MaximumSize / MM_PAGE_SIZE);
246}
#define PAGE_SIZE
Definition: env_spec_w32.h:49
@ LoaderFree
Definition: arc.h:176
#define ALIGN_UP_POINTER_BY(ptr, align)
Definition: umtypes.h:85
#define ALIGN_DOWN_POINTER_BY(ptr, align)
Definition: umtypes.h:82

Referenced by FrLdrHeapCleanupAll().

◆ FrLdrHeapVerify()

VOID FrLdrHeapVerify ( PVOID  HeapHandle)

Definition at line 157 of file heap.c.

159{
160 PHEAP Heap = HeapHandle;
161 PHEAP_BLOCK Block;
162
163 /* Loop all heap chunks */
164 for (Block = &Heap->Blocks;
165 Block->Size != 0;
166 Block = Block + 1 + Block->Size)
167 {
168 /* Continue, if its not free */
169 if (Block->Tag != 0)
170 {
171 /* Verify size and redzones */
172 ASSERT(*REDZONE_SIZE(Block) <= Block->Size * sizeof(HEAP_BLOCK));
173 ASSERT(*REDZONE_LOW(Block) == REDZONE_MARK);
174 ASSERT(*REDZONE_HI(Block) == REDZONE_MARK);
175 continue;
176 }
177 }
178}

Referenced by FrLdrHeapAllocateEx(), and FrLdrHeapFreeEx().

◆ FrLdrTempAlloc()

◆ FrLdrTempFree()

◆ MmAllocateHighestMemoryBelowAddress()

PVOID MmAllocateHighestMemoryBelowAddress ( SIZE_T  MemorySize,
PVOID  DesiredAddress,
TYPE_OF_MEMORY  MemoryType 
)

Definition at line 160 of file mm.c.

161{
162 PFN_NUMBER PagesNeeded;
163 PFN_NUMBER FirstFreePageFromEnd;
164 PFN_NUMBER DesiredAddressPageNumber;
165 PVOID MemPointer;
166
167 if (MemorySize == 0)
168 {
169 WARN("MmAllocateHighestMemoryBelowAddress() called for 0 bytes. Returning NULL.\n");
170 UiMessageBoxCritical("Memory allocation failed: MmAllocateHighestMemoryBelowAddress() called for 0 bytes.");
171 return NULL;
172 }
173
174 // Find out how many blocks it will take to
175 // satisfy this allocation
176 PagesNeeded = ROUND_UP(MemorySize, MM_PAGE_SIZE) / MM_PAGE_SIZE;
177
178 // Get the page number for their desired address
179 DesiredAddressPageNumber = (ULONG_PTR)DesiredAddress / MM_PAGE_SIZE;
180
181 // If we don't have enough available mem
182 // then return NULL
183 if (FreePagesInLookupTable < PagesNeeded)
184 {
185 ERR("Memory allocation failed in MmAllocateHighestMemoryBelowAddress(). Not enough free memory to allocate %d bytes.\n", MemorySize);
186 UiMessageBoxCritical("Memory allocation failed: out of memory.");
187 return NULL;
188 }
189
190 FirstFreePageFromEnd = MmFindAvailablePagesBeforePage(PageLookupTableAddress, TotalPagesInLookupTable, PagesNeeded, DesiredAddressPageNumber);
191
192 if (FirstFreePageFromEnd == 0)
193 {
194 ERR("Memory allocation failed in MmAllocateHighestMemoryBelowAddress(). Not enough free memory to allocate %d bytes.\n", MemorySize);
195 UiMessageBoxCritical("Memory allocation failed: out of memory.");
196 return NULL;
197 }
198
199 MmAllocatePagesInLookupTable(PageLookupTableAddress, FirstFreePageFromEnd, PagesNeeded, MemoryType);
200
201 FreePagesInLookupTable -= PagesNeeded;
202 MemPointer = (PVOID)((ULONG_PTR)FirstFreePageFromEnd * MM_PAGE_SIZE);
203
204 TRACE("Allocated %d bytes (%d pages) of memory starting at page %d.\n", MemorySize, PagesNeeded, FirstFreePageFromEnd);
205 TRACE("Memory allocation pointer: 0x%x\n", MemPointer);
206
207 // Update LoaderPagesSpanned count
208 if ((((ULONG_PTR)MemPointer + MemorySize) >> PAGE_SHIFT) > LoaderPagesSpanned)
209 LoaderPagesSpanned = (((ULONG_PTR)MemPointer + MemorySize) >> PAGE_SHIFT);
210
211 // Now return the pointer
212 return MemPointer;
213}
ULONG_PTR PFN_NUMBER
PFN_NUMBER TotalPagesInLookupTable
Definition: meminit.c:27
PFN_NUMBER FreePagesInLookupTable
Definition: meminit.c:28
PFN_NUMBER MmFindAvailablePagesBeforePage(PVOID PageLookupTable, PFN_NUMBER TotalPageCount, PFN_NUMBER PagesNeeded, PFN_NUMBER LastPage)
Definition: meminit.c:647
VOID MmAllocatePagesInLookupTable(PVOID PageLookupTable, PFN_NUMBER StartPage, PFN_NUMBER PageCount, TYPE_OF_MEMORY MemoryType)
Definition: meminit.c:557
VOID UiMessageBoxCritical(_In_ PCSTR MessageText)
Definition: ui.c:372
#define ULONG_PTR
Definition: config.h:101
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#define ROUND_UP(n, align)
Definition: eventvwr.h:34
PFN_NUMBER LoaderPagesSpanned
Definition: mm.c:29
void * PVOID
Definition: typedefs.h:50

◆ MmAllocateMemory()

PVOID MmAllocateMemory ( SIZE_T  MemorySize)

◆ MmAllocateMemoryAtAddress()

PVOID MmAllocateMemoryAtAddress ( SIZE_T  MemorySize,
PVOID  DesiredAddress,
TYPE_OF_MEMORY  MemoryType 
)

Definition at line 85 of file mm.c.

86{
87 PFN_NUMBER PagesNeeded;
88 PFN_NUMBER StartPageNumber;
89 PVOID MemPointer;
90
91 if (MemorySize == 0)
92 {
93 WARN("MmAllocateMemoryAtAddress() called for 0 bytes. Returning NULL.\n");
94 UiMessageBoxCritical("Memory allocation failed: MmAllocateMemoryAtAddress() called for 0 bytes.");
95 return NULL;
96 }
97
98 // Find out how many blocks it will take to
99 // satisfy this allocation
100 PagesNeeded = ROUND_UP(MemorySize, MM_PAGE_SIZE) / MM_PAGE_SIZE;
101
102 // Get the starting page number
103 StartPageNumber = MmGetPageNumberFromAddress(DesiredAddress);
104
105 // If we don't have enough available mem
106 // then return NULL
107 if (FreePagesInLookupTable < PagesNeeded)
108 {
109 ERR("Memory allocation failed in MmAllocateMemoryAtAddress(). "
110 "Not enough free memory to allocate %d bytes (requesting %d pages but have only %d). "
111 "\n", MemorySize, PagesNeeded, FreePagesInLookupTable);
112 UiMessageBoxCritical("Memory allocation failed: out of memory.");
113 return NULL;
114 }
115
117 {
118 WARN("Memory allocation failed in MmAllocateMemoryAtAddress(). "
119 "Not enough free memory to allocate %d bytes at address %p.\n",
120 MemorySize, DesiredAddress);
121
122 // Don't tell this to user since caller should try to alloc this memory
123 // at a different address
124 //UiMessageBoxCritical("Memory allocation failed: out of memory.");
125 return NULL;
126 }
127
128 MmAllocatePagesInLookupTable(PageLookupTableAddress, StartPageNumber, PagesNeeded, MemoryType);
129
130 FreePagesInLookupTable -= PagesNeeded;
131 MemPointer = (PVOID)((ULONG_PTR)StartPageNumber * MM_PAGE_SIZE);
132
133 TRACE("Allocated %d bytes (%d pages) of memory starting at page %d.\n", MemorySize, PagesNeeded, StartPageNumber);
134 TRACE("Memory allocation pointer: 0x%x\n", MemPointer);
135
136 // Update LoaderPagesSpanned count
137 if ((((ULONG_PTR)MemPointer + MemorySize + PAGE_SIZE - 1) >> PAGE_SHIFT) > LoaderPagesSpanned)
138 LoaderPagesSpanned = (((ULONG_PTR)MemPointer + MemorySize + PAGE_SIZE - 1) >> PAGE_SHIFT);
139
140 // Now return the pointer
141 return MemPointer;
142}
PFN_NUMBER MmGetPageNumberFromAddress(PVOID Address)
Definition: meminit.c:392
BOOLEAN MmAreMemoryPagesAvailable(PVOID PageLookupTable, PFN_NUMBER TotalPageCount, PVOID PageAddress, PFN_NUMBER PageCount)
Definition: meminit.c:695

Referenced by MempAllocatePageTables(), and PeLdrLoadImageEx().

◆ MmAllocateMemoryWithType()

PVOID MmAllocateMemoryWithType ( SIZE_T  MemorySize,
TYPE_OF_MEMORY  MemoryType 
)

Definition at line 31 of file mm.c.

32{
33 PFN_NUMBER PagesNeeded;
34 PFN_NUMBER FirstFreePageFromEnd;
35 PVOID MemPointer;
36
37 if (MemorySize == 0)
38 {
39 WARN("MmAllocateMemory() called for 0 bytes. Returning NULL.\n");
40 UiMessageBoxCritical("Memory allocation failed: MmAllocateMemory() called for 0 bytes.");
41 return NULL;
42 }
43
45
46 // Find out how many blocks it will take to
47 // satisfy this allocation
48 PagesNeeded = ROUND_UP(MemorySize, MM_PAGE_SIZE) / MM_PAGE_SIZE;
49
50 // If we don't have enough available mem
51 // then return NULL
52 if (FreePagesInLookupTable < PagesNeeded)
53 {
54 ERR("Memory allocation failed in MmAllocateMemory(). Not enough free memory to allocate %d bytes.\n", MemorySize);
55 UiMessageBoxCritical("Memory allocation failed: out of memory.");
56 return NULL;
57 }
58
59 FirstFreePageFromEnd = MmFindAvailablePages(PageLookupTableAddress, TotalPagesInLookupTable, PagesNeeded, FALSE);
60
61 if (FirstFreePageFromEnd == 0)
62 {
63 ERR("Memory allocation failed in MmAllocateMemory(). Not enough free memory to allocate %d bytes.\n", MemorySize);
64 UiMessageBoxCritical("Memory allocation failed: out of memory.");
65 return NULL;
66 }
67
68 MmAllocatePagesInLookupTable(PageLookupTableAddress, FirstFreePageFromEnd, PagesNeeded, MemoryType);
69
70 FreePagesInLookupTable -= PagesNeeded;
71 MemPointer = (PVOID)((ULONG_PTR)FirstFreePageFromEnd * MM_PAGE_SIZE);
72
73 TRACE("Allocated %d bytes (%d pages) of memory (type %ld) starting at page 0x%lx.\n",
74 MemorySize, PagesNeeded, MemoryType, FirstFreePageFromEnd);
75 TRACE("Memory allocation pointer: 0x%x\n", MemPointer);
76
77 // Update LoaderPagesSpanned count
78 if ((((ULONG_PTR)MemPointer + MemorySize + PAGE_SIZE - 1) >> PAGE_SHIFT) > LoaderPagesSpanned)
79 LoaderPagesSpanned = (((ULONG_PTR)MemPointer + MemorySize + PAGE_SIZE - 1) >> PAGE_SHIFT);
80
81 // Now return the pointer
82 return MemPointer;
83}
PFN_NUMBER MmFindAvailablePages(PVOID PageLookupTable, PFN_NUMBER TotalPageCount, PFN_NUMBER PagesNeeded, BOOLEAN FromEnd)
Definition: meminit.c:588

Referenced by AllocateAndInitLPB(), EfiEntry(), FrLdrHeapCreate(), MempAllocatePageTables(), MempGetOrCreatePageDir(), PeLdrLoadImageEx(), RamDiskLoadVirtualFile(), RegLoadHiveLog(), UefiInitializeBootDevices(), UefiSetupBlockDevices(), VideoAllocateOffScreenBuffer(), WinLdrLoadModule(), WinLdrLoadNLSData(), WinLdrLoadSystemHive(), WinLdrSetupMachineDependent(), and WinLdrSetupMemoryLayout().

◆ MmAllocatePagesInLookupTable()

VOID MmAllocatePagesInLookupTable ( PVOID  PageLookupTable,
PFN_NUMBER  StartPage,
PFN_NUMBER  PageCount,
TYPE_OF_MEMORY  MemoryType 
)

Definition at line 557 of file meminit.c.

558{
559 PPAGE_LOOKUP_TABLE_ITEM RealPageLookupTable = (PPAGE_LOOKUP_TABLE_ITEM)PageLookupTable;
561
563 for (Index=StartPage; Index<(StartPage+PageCount); Index++)
564 {
565 RealPageLookupTable[Index].PageAllocated = MemoryType;
566 RealPageLookupTable[Index].PageAllocationLength = (Index == StartPage) ? PageCount : 0;
567 }
568}
struct PAGE_LOOKUP_TABLE_ITEM * PPAGE_LOOKUP_TABLE_ITEM
PFN_NUMBER MmLowestPhysicalPage
Definition: meminit.c:30
PFN_NUMBER PageAllocationLength
Definition: mm.h:87
TYPE_OF_MEMORY PageAllocated
Definition: mm.h:86
_In_ WDFCOLLECTION _In_ ULONG Index
int WINAPI StartPage(_In_ HDC)

Referenced by MmAllocateHighestMemoryBelowAddress(), MmAllocateMemoryAtAddress(), MmAllocateMemoryWithType(), and MmSetMemoryType().

◆ MmAreMemoryPagesAvailable()

BOOLEAN MmAreMemoryPagesAvailable ( PVOID  PageLookupTable,
PFN_NUMBER  TotalPageCount,
PVOID  PageAddress,
PFN_NUMBER  PageCount 
)

Definition at line 695 of file meminit.c.

696{
697 PPAGE_LOOKUP_TABLE_ITEM RealPageLookupTable = (PPAGE_LOOKUP_TABLE_ITEM)PageLookupTable;
700
702
704
706
707 // Make sure they aren't trying to go past the
708 // end of available memory
709 if ((StartPage + PageCount) > TotalPageCount)
710 {
711 return FALSE;
712 }
713
714 for (Index = StartPage; Index < (StartPage + PageCount); Index++)
715 {
716 // If this page is allocated then there obviously isn't
717 // memory available so return FALSE
718 if (RealPageLookupTable[Index].PageAllocated != LoaderFree)
719 {
720 return FALSE;
721 }
722 }
723
724 return TRUE;
725}
#define TRUE
Definition: types.h:120
PFN_NUMBER MmGetPageNumberFromAddress(PVOID Address)
Definition: meminit.c:392
_Must_inspect_result_ _In_ SIZE_T _In_ PVOID PageAddress
Definition: mmfuncs.h:472

Referenced by MmAllocateMemoryAtAddress().

◆ MmCountFreePagesInLookupTable()

PFN_NUMBER MmCountFreePagesInLookupTable ( PVOID  PageLookupTable,
PFN_NUMBER  TotalPageCount 
)

Definition at line 570 of file meminit.c.

571{
572 PPAGE_LOOKUP_TABLE_ITEM RealPageLookupTable = (PPAGE_LOOKUP_TABLE_ITEM)PageLookupTable;
574 PFN_NUMBER FreePageCount;
575
576 FreePageCount = 0;
577 for (Index=0; Index<TotalPageCount; Index++)
578 {
579 if (RealPageLookupTable[Index].PageAllocated == LoaderFree)
580 {
581 FreePageCount++;
582 }
583 }
584
585 return FreePageCount;
586}

Referenced by MmInitializeMemoryManager().

◆ MmFindAvailablePages()

PFN_NUMBER MmFindAvailablePages ( PVOID  PageLookupTable,
PFN_NUMBER  TotalPageCount,
PFN_NUMBER  PagesNeeded,
BOOLEAN  FromEnd 
)

Definition at line 588 of file meminit.c.

589{
590 PPAGE_LOOKUP_TABLE_ITEM RealPageLookupTable = (PPAGE_LOOKUP_TABLE_ITEM)PageLookupTable;
591 PFN_NUMBER AvailablePagesSoFar;
593
594 if (LastFreePageHint > TotalPageCount)
595 {
596 LastFreePageHint = TotalPageCount;
597 }
598
599 AvailablePagesSoFar = 0;
600 if (FromEnd)
601 {
602 /* Allocate "high" (from end) pages */
603 for (Index=LastFreePageHint-1; Index>0; Index--)
604 {
605 if (RealPageLookupTable[Index].PageAllocated != LoaderFree)
606 {
607 AvailablePagesSoFar = 0;
608 continue;
609 }
610 else
611 {
612 AvailablePagesSoFar++;
613 }
614
615 if (AvailablePagesSoFar >= PagesNeeded)
616 {
618 }
619 }
620 }
621 else
622 {
623 TRACE("Alloc low memory, LastFreePageHint 0x%x, TPC 0x%x\n", LastFreePageHint, TotalPageCount);
624 /* Allocate "low" pages */
625 for (Index=1; Index < LastFreePageHint; Index++)
626 {
627 if (RealPageLookupTable[Index].PageAllocated != LoaderFree)
628 {
629 AvailablePagesSoFar = 0;
630 continue;
631 }
632 else
633 {
634 AvailablePagesSoFar++;
635 }
636
637 if (AvailablePagesSoFar >= PagesNeeded)
638 {
639 return Index - AvailablePagesSoFar + 1 + MmLowestPhysicalPage;
640 }
641 }
642 }
643
644 return 0;
645}
PFN_NUMBER LastFreePageHint
Definition: meminit.c:29

Referenced by MmAllocateMemoryWithType(), and MmFindAvailablePagesBeforePage().

◆ MmFindAvailablePagesBeforePage()

PFN_NUMBER MmFindAvailablePagesBeforePage ( PVOID  PageLookupTable,
PFN_NUMBER  TotalPageCount,
PFN_NUMBER  PagesNeeded,
PFN_NUMBER  LastPage 
)

Definition at line 647 of file meminit.c.

648{
649 PPAGE_LOOKUP_TABLE_ITEM RealPageLookupTable = (PPAGE_LOOKUP_TABLE_ITEM)PageLookupTable;
650 PFN_NUMBER AvailablePagesSoFar;
652
653 if (LastPage > TotalPageCount)
654 {
655 return MmFindAvailablePages(PageLookupTable, TotalPageCount, PagesNeeded, TRUE);
656 }
657
658 AvailablePagesSoFar = 0;
659 for (Index=LastPage-1; Index>0; Index--)
660 {
661 if (RealPageLookupTable[Index].PageAllocated != LoaderFree)
662 {
663 AvailablePagesSoFar = 0;
664 continue;
665 }
666 else
667 {
668 AvailablePagesSoFar++;
669 }
670
671 if (AvailablePagesSoFar >= PagesNeeded)
672 {
674 }
675 }
676
677 return 0;
678}
PFN_NUMBER MmFindAvailablePages(PVOID PageLookupTable, PFN_NUMBER TotalPageCount, PFN_NUMBER PagesNeeded, BOOLEAN FromEnd)
Definition: meminit.c:588

Referenced by MmAllocateHighestMemoryBelowAddress().

◆ MmFindLocationForPageLookupTable()

PVOID MmFindLocationForPageLookupTable ( PFN_NUMBER  TotalPageCount)

Definition at line 437 of file meminit.c.

438{
440 SIZE_T PageLookupTableSize;
441 PFN_NUMBER RequiredPages;
442 PFN_NUMBER CandidateBasePage = 0;
443 PFN_NUMBER CandidatePageCount = 0;
444 PFN_NUMBER PageLookupTableEndPage;
445 PVOID PageLookupTableMemAddress;
446
447 // Calculate how much pages we need to keep the page lookup table
448 PageLookupTableSize = TotalPageCount * sizeof(PAGE_LOOKUP_TABLE_ITEM);
449 RequiredPages = PageLookupTableSize / MM_PAGE_SIZE;
450
451 // Search the highest memory block big enough to contain lookup table
453 {
454 // Continue, if memory is not free
455 if (MemoryDescriptor->MemoryType != LoaderFree) continue;
456
457 // Continue, if the block is not big enough
458 if (MemoryDescriptor->PageCount < RequiredPages) continue;
459
460 // Continue, if it is not at a higher address than previous address
461 if (MemoryDescriptor->BasePage < CandidateBasePage) continue;
462
463 // Continue, if the address is too high
464 if (MemoryDescriptor->BasePage + RequiredPages >= MM_MAX_PAGE_LOADER) continue;
465
466 // Memory block is more suitable than the previous one
467 CandidateBasePage = MemoryDescriptor->BasePage;
468 CandidatePageCount = MemoryDescriptor->PageCount;
469 }
470
471 // Calculate the end address for the lookup table
472 PageLookupTableEndPage = min(CandidateBasePage + CandidatePageCount,
473 MM_MAX_PAGE_LOADER);
474
475 // Calculate the virtual address
476 PageLookupTableMemAddress = (PVOID)((PageLookupTableEndPage * PAGE_SIZE)
477 - PageLookupTableSize);
478
479 TRACE("MmFindLocationForPageLookupTable() returning 0x%x\n", PageLookupTableMemAddress);
480
481 return PageLookupTableMemAddress;
482}
const FREELDR_MEMORY_DESCRIPTOR * ArcGetMemoryDescriptor(const FREELDR_MEMORY_DESCRIPTOR *Current)
Definition: meminit.c:244
_Must_inspect_result_ _In_ WDFUSBDEVICE _In_opt_ WDFREQUEST _In_opt_ PWDF_REQUEST_SEND_OPTIONS _In_ PWDF_USB_CONTROL_SETUP_PACKET _In_opt_ PWDF_MEMORY_DESCRIPTOR MemoryDescriptor
Definition: wdfusb.h:1339

Referenced by MmInitializeMemoryManager().

◆ MmFreeMemory()

◆ MmGetAddressablePageCountIncludingHoles()

PFN_NUMBER MmGetAddressablePageCountIncludingHoles ( VOID  )

Definition at line 397 of file meminit.c.

398{
400 PFN_NUMBER PageCount;
401
402 //
403 // Go through the whole memory map to get max address
404 //
406 {
407 //
408 // Check if we got a higher end page address
409 //
410 if (MemoryDescriptor->BasePage + MemoryDescriptor->PageCount > MmHighestPhysicalPage)
411 {
412 //
413 // Yes, remember it if this is real memory
414 //
415 if (MemoryDescriptor->MemoryType == LoaderFree)
417 }
418
419 //
420 // Check if we got a higher (usable) start page address
421 //
423 {
424 //
425 // Yes, remember it if this is real memory
426 //
428 }
429 }
430
433 TRACE("MmGetAddressablePageCountIncludingHoles() returning 0x%x\n", PageCount);
434 return PageCount;
435}
PFN_NUMBER MmHighestPhysicalPage
Definition: meminit.c:31

Referenced by MmInitializeMemoryManager().

◆ MmGetBiosMemoryMap()

ULONG MmGetBiosMemoryMap ( _Out_ PFREELDR_MEMORY_DESCRIPTOR MemoryMap)

Definition at line 38 of file meminit.c.

39{
42}
BIOS_MEMORY_MAP MemoryMap[32]
Definition: loader.c:11
PFREELDR_MEMORY_DESCRIPTOR BiosMemoryMap
Definition: meminit.c:33
ULONG BiosMemoryMapEntryCount
Definition: meminit.c:34

Referenced by WinLdrSetupMemoryLayout().

◆ MmGetHighestPhysicalPage()

PFN_NUMBER MmGetHighestPhysicalPage ( VOID  )

Definition at line 728 of file meminit.c.

729{
731}

Referenced by WinLdrSetupMemoryLayout().

◆ MmGetLoaderPagesSpanned()

PFN_NUMBER MmGetLoaderPagesSpanned ( VOID  )

Definition at line 307 of file mm.c.

308{
309 return LoaderPagesSpanned;
310}

Referenced by LoadAndBootWindowsCommon(), and MempSetupPagingForRegion().

◆ MmGetMemoryMap()

PPAGE_LOOKUP_TABLE_ITEM MmGetMemoryMap ( PFN_NUMBER NoEntries)

Definition at line 297 of file mm.c.

298{
300
301 *NoEntries = TotalPagesInLookupTable;
302
303 return RealPageLookupTable;
304}

Referenced by WinLdrSetupMemoryLayout().

◆ MmGetPageNumberFromAddress()

PFN_NUMBER MmGetPageNumberFromAddress ( PVOID  Address)

Definition at line 392 of file meminit.c.

393{
394 return ((ULONG_PTR)Address) / MM_PAGE_SIZE;
395}
static WCHAR Address[46]
Definition: ping.c:68

Referenced by MmAllocateMemoryAtAddress(), MmAreMemoryPagesAvailable(), MmInitPageLookupTable(), and MmSetMemoryType().

◆ MmGetTotalPagesInLookupTable()

PFN_NUMBER MmGetTotalPagesInLookupTable ( VOID  )

Definition at line 45 of file meminit.c.

46{
48}
PFN_NUMBER TotalPagesInLookupTable
Definition: meminit.c:27

Referenced by MempAllocatePageTables().

◆ MmInitializeHeap()

VOID MmInitializeHeap ( PVOID  PageLookupTable)

Definition at line 562 of file heap.c.

563{
564 TRACE("MmInitializeHeap()\n");
565
566 /* Create the default heap */
569
570 /* Create a temporary heap */
573
574 TRACE("MmInitializeHeap() done, default heap %p, temp heap %p\n",
576}
#define DEFAULT_HEAP_SIZE
Definition: mm.h:137
#define TEMP_HEAP_SIZE
Definition: mm.h:138
PVOID FrLdrHeapCreate(SIZE_T MaximumSize, TYPE_OF_MEMORY MemoryType)
Definition: heap.c:66
@ LoaderOsloaderHeap
Definition: arc.h:181

Referenced by MmInitializeMemoryManager().

◆ MmInitializeMemoryManager()

BOOLEAN MmInitializeMemoryManager ( VOID  )

Definition at line 336 of file meminit.c.

337{
338#if DBG
340#endif
341
342 TRACE("Initializing Memory Manager.\n");
343
344 /* Check the freeldr binary */
346
348
349#if DBG
350 // Dump the system memory map
351 TRACE("System Memory Map (Base Address, Length, Type):\n");
353 {
354 TRACE("%x\t %x\t %s\n",
355 MemoryDescriptor->BasePage * MM_PAGE_SIZE,
356 MemoryDescriptor->PageCount * MM_PAGE_SIZE,
358 }
359#endif
360
361 // Find address for the page lookup table
365
366 if (PageLookupTableAddress == 0)
367 {
368 // If we get here then we probably couldn't
369 // find a contiguous chunk of memory big
370 // enough to hold the page lookup table
371 printf("Error initializing memory manager!\n");
372 return FALSE;
373 }
374
375 // Initialize the page lookup table
377
379
382
384
385 TRACE("Memory Manager initialized. 0x%x pages available.\n", FreePagesInLookupTable);
386
387
388 return TRUE;
389}
MACHVTBL MachVtbl
Definition: arcemul.c:21
VOID MmInitializeHeap(PVOID PageLookupTable)
Definition: heap.c:562
#define printf
Definition: freeldr.h:97
PVOID PageLookupTableAddress
Definition: meminit.c:26
PFN_NUMBER MmGetAddressablePageCountIncludingHoles(VOID)
Definition: meminit.c:397
static VOID MmCheckFreeldrImageFile(VOID)
Definition: meminit.c:260
VOID MmInitPageLookupTable(PVOID PageLookupTable, PFN_NUMBER TotalPageCount)
Definition: meminit.c:484
PFN_NUMBER MmCountFreePagesInLookupTable(PVOID PageLookupTable, PFN_NUMBER TotalPageCount)
Definition: meminit.c:570
PCSTR MmGetSystemMemoryMapTypeString(TYPE_OF_MEMORY Type)
Definition: meminit.c:115
PFN_NUMBER FreePagesInLookupTable
Definition: meminit.c:28
VOID MmUpdateLastFreePageHint(PVOID PageLookupTable, PFN_NUMBER TotalPageCount)
Definition: meminit.c:680
PVOID MmFindLocationForPageLookupTable(PFN_NUMBER TotalPageCount)
Definition: meminit.c:437
PFREELDR_MEMORY_DESCRIPTOR(* GetMemoryMap)(PULONG MaxMemoryMapSize)
Definition: machine.h:63

Referenced by BootMain(), and EfiEntry().

◆ MmInitPageLookupTable()

VOID MmInitPageLookupTable ( PVOID  PageLookupTable,
PFN_NUMBER  TotalPageCount 
)

Definition at line 484 of file meminit.c.

485{
487 PFN_NUMBER PageLookupTableStartPage;
488 PFN_NUMBER PageLookupTablePageCount;
489
490 TRACE("MmInitPageLookupTable()\n");
491
492 // Mark every page as allocated initially
493 // We will go through and mark pages again according to the memory map
494 // But this will mark any holes not described in the map as allocated
496
497 // Parse the whole memory map
499 {
500 // Mark used pages in the lookup table
501
502 if (MemoryDescriptor->BasePage + MemoryDescriptor->PageCount <= TotalPageCount)
503 {
504 TRACE("Marking pages 0x%lx-0x%lx as type %s\n",
505 MemoryDescriptor->BasePage,
506 MemoryDescriptor->BasePage + MemoryDescriptor->PageCount,
508 MmMarkPagesInLookupTable(PageLookupTable,
509 MemoryDescriptor->BasePage,
510 MemoryDescriptor->PageCount,
511 MemoryDescriptor->MemoryType);
512 }
513 else
514 TRACE("Ignoring pages 0x%lx-0x%lx (%s)\n",
515 MemoryDescriptor->BasePage,
516 MemoryDescriptor->BasePage + MemoryDescriptor->PageCount,
518 }
519
520 // Mark the pages that the lookup table occupies as reserved
521 PageLookupTableStartPage = MmGetPageNumberFromAddress(PageLookupTable);
522 PageLookupTablePageCount = MmGetPageNumberFromAddress((PVOID)((ULONG_PTR)PageLookupTable + ROUND_UP(TotalPageCount * sizeof(PAGE_LOOKUP_TABLE_ITEM), MM_PAGE_SIZE))) - PageLookupTableStartPage;
523 TRACE("Marking the page lookup table pages as reserved StartPage: 0x%x PageCount: 0x%x\n", PageLookupTableStartPage, PageLookupTablePageCount);
524 MmMarkPagesInLookupTable(PageLookupTable, PageLookupTableStartPage, PageLookupTablePageCount, LoaderFirmwareTemporary);
525}
VOID MmMarkPagesInLookupTable(PVOID PageLookupTable, PFN_NUMBER StartPage, PFN_NUMBER PageCount, TYPE_OF_MEMORY PageAllocated)
Definition: meminit.c:527
@ LoaderFirmwarePermanent
Definition: arc.h:180

Referenced by MmInitializeMemoryManager().

◆ MmMarkPagesInLookupTable()

VOID MmMarkPagesInLookupTable ( PVOID  PageLookupTable,
PFN_NUMBER  StartPage,
PFN_NUMBER  PageCount,
TYPE_OF_MEMORY  PageAllocated 
)

Definition at line 527 of file meminit.c.

528{
529 PPAGE_LOOKUP_TABLE_ITEM RealPageLookupTable = (PPAGE_LOOKUP_TABLE_ITEM)PageLookupTable;
531 TRACE("MmMarkPagesInLookupTable()\n");
532
533 /* Validate the range */
535 ((StartPage + PageCount - 1) > MmHighestPhysicalPage))
536 {
537 ERR("Memory (0x%lx:0x%lx) outside of lookup table! Valid range: 0x%lx-0x%lx.\n",
539 return;
540 }
541
543 for (Index=StartPage; Index<(StartPage+PageCount); Index++)
544 {
545#if 0
546 if ((Index <= (StartPage + 16)) || (Index >= (StartPage+PageCount-16)))
547 {
548 TRACE("Index = 0x%x StartPage = 0x%x PageCount = 0x%x\n", Index, StartPage, PageCount);
549 }
550#endif
551 RealPageLookupTable[Index].PageAllocated = PageAllocated;
552 RealPageLookupTable[Index].PageAllocationLength = (PageAllocated != LoaderFree) ? 1 : 0;
553 }
554 TRACE("MmMarkPagesInLookupTable() Done\n");
555}

Referenced by FrLdrHeapDestroy(), FrLdrHeapRelease(), and MmInitPageLookupTable().

◆ MmSetMemoryType()

VOID MmSetMemoryType ( PVOID  MemoryAddress,
SIZE_T  MemorySize,
TYPE_OF_MEMORY  NewType 
)

Definition at line 144 of file mm.c.

145{
146 PFN_NUMBER PagesNeeded;
147 PFN_NUMBER StartPageNumber;
148
149 // Find out how many blocks it will take to
150 // satisfy this allocation
151 PagesNeeded = ROUND_UP(MemorySize, MM_PAGE_SIZE) / MM_PAGE_SIZE;
152
153 // Get the starting page number
154 StartPageNumber = MmGetPageNumberFromAddress(MemoryAddress);
155
156 // Set new type for these pages
157 MmAllocatePagesInLookupTable(PageLookupTableAddress, StartPageNumber, PagesNeeded, NewType);
158}

Referenced by MempAllocatePageTables().

◆ MmUpdateLastFreePageHint()

VOID MmUpdateLastFreePageHint ( PVOID  PageLookupTable,
PFN_NUMBER  TotalPageCount 
)

Definition at line 680 of file meminit.c.

681{
682 PPAGE_LOOKUP_TABLE_ITEM RealPageLookupTable = (PPAGE_LOOKUP_TABLE_ITEM)PageLookupTable;
684
685 for (Index=TotalPageCount-1; Index>0; Index--)
686 {
687 if (RealPageLookupTable[Index].PageAllocated == LoaderFree)
688 {
690 break;
691 }
692 }
693}

Referenced by MmInitializeMemoryManager().

Variable Documentation

◆ __ImageBase

char __ImageBase
extern

◆ FreePagesInLookupTable

◆ FrLdrImageSize

SIZE_T FrLdrImageSize
extern

◆ LastFreePageHint

PFN_NUMBER LastFreePageHint
extern

◆ PageLookupTableAddress

◆ TotalPagesInLookupTable