2 * COPYRIGHT: See COPYING.ARM in the top level directory
3 * PROJECT: ReactOS UEFI Boot Library
4 * FILE: boot/environ/lib/mm/descriptor.c
5 * PURPOSE: Boot Library Memory Manager Descriptor Manager
6 * PROGRAMMER: Alex Ionescu (alex.ionescu@reactos.org)
9 /* INCLUDES ******************************************************************/
13 /* DATA VARIABLES ************************************************************/
15 BL_MEMORY_DESCRIPTOR MmStaticMemoryDescriptors
[512];
16 ULONG MmGlobalMemoryDescriptorCount
;
17 PBL_MEMORY_DESCRIPTOR MmGlobalMemoryDescriptors
;
18 BOOLEAN MmGlobalMemoryDescriptorsUsed
;
19 PBL_MEMORY_DESCRIPTOR MmDynamicMemoryDescriptors
;
20 ULONG MmDynamicMemoryDescriptorCount
;
22 BL_MEMORY_TYPE MmPlatformMemoryTypePrecedence
[] =
35 /* FUNCTIONS *****************************************************************/
37 /* The order is Conventional > Other > System > Loader > Application */
40 _In_ BL_MEMORY_TYPE Type1
,
41 _In_ BL_MEMORY_TYPE Type2
44 BL_MEMORY_CLASS Class1
, Class2
;
47 /* Descriptor is free RAM -- it precedes */
48 if (Type1
== BlConventionalMemory
)
53 /* It isn't free RAM, but the comparator is -- it succeeds it */
54 if (Type2
== BlConventionalMemory
)
59 /* Descriptor is not system, application, or loader class -- it precedes */
60 Class1
= Type1
>> BL_MEMORY_CLASS_SHIFT
;
61 if ((Class1
!= BlSystemClass
) &&
62 (Class1
!= BlApplicationClass
) &&
63 (Class1
!= BlLoaderClass
))
68 /* It isn't one of those classes, but the comparator it -- it succeeds it */
69 Class2
= Type2
>> BL_MEMORY_CLASS_SHIFT
;
70 if ((Class2
!= BlSystemClass
) &&
71 (Class2
!= BlApplicationClass
) &&
72 (Class2
!= BlLoaderClass
))
77 /* Descriptor is system class */
78 if (Class1
== BlSystemClass
)
80 /* And so is the other guy... */
81 if (Class2
== BlSystemClass
)
86 /* Scan for the descriptor's system precedence index */
89 if (MmPlatformMemoryTypePrecedence
[j
] == Type1
)
93 } while (++j
< RTL_NUMBER_OF(MmPlatformMemoryTypePrecedence
));
95 /* Use an invalid index if one wasn't found */
96 if (j
== RTL_NUMBER_OF(MmPlatformMemoryTypePrecedence
))
101 /* Now scan for the comparator's system precedence index */
102 while (MmPlatformMemoryTypePrecedence
[i
] != Type2
)
104 /* Use an invalid index if one wasn't found */
105 if (++i
>= RTL_NUMBER_OF(MmPlatformMemoryTypePrecedence
))
112 /* Does the current have a valid index? */
115 /* Yes, what about the comparator? */
118 /* Let the indexes fight! */
122 /* Succeed the comparator, its index is unknown */
127 /* The comparator isn't system, so it precedes it */
131 /* Descriptor is not system class, but comparator is -- it succeeds it */
132 if (Class2
== BlSystemClass
)
137 /* Descriptor is loader class -- it precedes */
138 if (Class1
== BlLoaderClass
)
143 /* It isn't loader class -- if the other guy is, succeed it */
144 return Class2
!= BlLoaderClass
;
148 MmMdpSwitchToDynamicDescriptors (
152 EfiPrintf(L
"dynamic switch NOT SUPPORTED!!!\r\n");
158 _In_ PBL_MEMORY_DESCRIPTOR MemoryDescriptor
163 /* Check if this is a valid static descriptor */
164 if (((MmDynamicMemoryDescriptors
) &&
165 (MemoryDescriptor
>= MmDynamicMemoryDescriptors
) &&
166 (MemoryDescriptor
< (MmDynamicMemoryDescriptors
+ MmDynamicMemoryDescriptorCount
))) ||
167 ((MemoryDescriptor
>= MmStaticMemoryDescriptors
) && (MemoryDescriptor
< &MmStaticMemoryDescriptors
[511])))
169 /* It's a global/static descriptor, so just zero it */
170 RtlZeroMemory(MemoryDescriptor
, sizeof(BL_MEMORY_DESCRIPTOR
));
171 Status
= STATUS_SUCCESS
;
175 /* It's a dynamic descriptor, so free it */
176 EfiPrintf(L
"Dynamic descriptors not yet supported\r\n");
177 Status
= STATUS_NOT_IMPLEMENTED
;
185 MmMdpSaveCurrentListPointer (
186 _In_ PBL_MEMORY_DESCRIPTOR_LIST MdList
,
187 _In_ PLIST_ENTRY Current
190 /* Make sure that this is not a global descriptor and not the first one */
191 if (((Current
< &MmGlobalMemoryDescriptors
->ListEntry
) ||
192 (Current
>= &MmGlobalMemoryDescriptors
[MmGlobalMemoryDescriptorCount
].ListEntry
)) &&
193 (Current
!= MdList
->First
))
195 /* Save this as the current pointer */
196 MdList
->This
= Current
;
201 MmMdRemoveDescriptorFromList (
202 _In_ PBL_MEMORY_DESCRIPTOR_LIST MdList
,
203 _In_ PBL_MEMORY_DESCRIPTOR Entry
206 /* Remove the entry */
207 RemoveEntryList(&Entry
->ListEntry
);
209 /* Check if this was the current link */
210 if (MdList
->This
== &Entry
->ListEntry
)
212 /* Remove the current link and set the next one */
214 MmMdpSaveCurrentListPointer(MdList
, Entry
->ListEntry
.Blink
);
220 _In_ PBL_MEMORY_DESCRIPTOR_LIST MdList
223 PLIST_ENTRY FirstEntry
, NextEntry
;
224 PBL_MEMORY_DESCRIPTOR Entry
;
226 /* Go over every descriptor from the top */
227 FirstEntry
= MdList
->First
;
228 NextEntry
= FirstEntry
->Flink
;
229 while (NextEntry
!= FirstEntry
)
231 /* Remove and free each one */
232 Entry
= CONTAINING_RECORD(NextEntry
, BL_MEMORY_DESCRIPTOR
, ListEntry
);
233 NextEntry
= NextEntry
->Flink
;
234 MmMdRemoveDescriptorFromList(MdList
, Entry
);
235 MmMdFreeDescriptor(Entry
);
239 PBL_MEMORY_DESCRIPTOR
240 MmMdInitByteGranularDescriptor (
242 _In_ BL_MEMORY_TYPE Type
,
243 _In_ ULONGLONG BasePage
,
244 _In_ ULONGLONG VirtualPage
,
245 _In_ ULONGLONG PageCount
248 PBL_MEMORY_DESCRIPTOR MemoryDescriptor
;
250 /* If we're out of descriptors, bail out */
251 if (MmGlobalMemoryDescriptorsUsed
>= MmGlobalMemoryDescriptorCount
)
253 EfiPrintf(L
"Out of descriptors!\r\n");
257 /* Take one of the available descriptors and fill it out */
258 MemoryDescriptor
= &MmGlobalMemoryDescriptors
[MmGlobalMemoryDescriptorsUsed
];
259 MemoryDescriptor
->BaseAddress
= BasePage
;
260 MemoryDescriptor
->VirtualPage
= VirtualPage
;
261 MemoryDescriptor
->PageCount
= PageCount
;
262 MemoryDescriptor
->Flags
= Flags
;
263 MemoryDescriptor
->Type
= Type
;
264 InitializeListHead(&MemoryDescriptor
->ListEntry
);
266 /* Increment the count and return the descriptor */
267 MmGlobalMemoryDescriptorsUsed
++;
268 return MemoryDescriptor
;
272 MmMdpTruncateDescriptor (
273 __in PBL_MEMORY_DESCRIPTOR_LIST MdList
,
274 __in PBL_MEMORY_DESCRIPTOR MemoryDescriptor
,
278 PBL_MEMORY_DESCRIPTOR NextDescriptor
, PreviousDescriptor
;
279 PLIST_ENTRY NextEntry
, PreviousEntry
;
280 ULONGLONG EndPage
, PreviousEndPage
;// , NextEndPage;
282 /* Get the next descriptor */
283 NextEntry
= MemoryDescriptor
->ListEntry
.Flink
;
284 NextDescriptor
= CONTAINING_RECORD(NextEntry
, BL_MEMORY_DESCRIPTOR
, ListEntry
);
286 /* Get the previous descriptor */
287 PreviousEntry
= MemoryDescriptor
->ListEntry
.Blink
;
288 PreviousDescriptor
= CONTAINING_RECORD(PreviousEntry
, BL_MEMORY_DESCRIPTOR
, ListEntry
);
290 /* Calculate end pages */
291 EndPage
= MemoryDescriptor
->BasePage
+ MemoryDescriptor
->PageCount
;
292 //NextEndPage = NextDescriptor->BasePage + NextDescriptor->PageCount;
293 PreviousEndPage
= PreviousDescriptor
->BasePage
+ PreviousDescriptor
->PageCount
;
295 /* Check for backward overlap */
296 if ((PreviousEntry
!= MdList
->First
) && (MemoryDescriptor
->BasePage
< PreviousEndPage
))
298 EfiPrintf(L
"Overlap detected -- this is unexpected on x86/x64 platforms\r\n");
301 /* Check for forward overlap */
302 if ((NextEntry
!= MdList
->First
) && (NextDescriptor
->BasePage
< EndPage
))
304 EfiPrintf(L
"Overlap detected -- this is unexpected on x86/x64 platforms\r\n");
312 MmMdpCoalesceDescriptor (
313 __in PBL_MEMORY_DESCRIPTOR_LIST MdList
,
314 __in PBL_MEMORY_DESCRIPTOR MemoryDescriptor
,
318 PBL_MEMORY_DESCRIPTOR NextDescriptor
, PreviousDescriptor
;
319 PLIST_ENTRY NextEntry
, PreviousEntry
;
320 ULONGLONG EndPage
, PreviousEndPage
, PreviousMappedEndPage
, MappedEndPage
;
322 /* Get the next descriptor */
323 NextEntry
= MemoryDescriptor
->ListEntry
.Flink
;
324 NextDescriptor
= CONTAINING_RECORD(NextEntry
, BL_MEMORY_DESCRIPTOR
, ListEntry
);
326 /* Get the previous descriptor */
327 PreviousEntry
= MemoryDescriptor
->ListEntry
.Blink
;
328 PreviousDescriptor
= CONTAINING_RECORD(PreviousEntry
, BL_MEMORY_DESCRIPTOR
, ListEntry
);
330 /* Calculate end pages */
331 EndPage
= MemoryDescriptor
->BasePage
+ MemoryDescriptor
->PageCount
;
332 MappedEndPage
= MemoryDescriptor
->BasePage
+ MemoryDescriptor
->PageCount
;
333 PreviousMappedEndPage
= PreviousDescriptor
->VirtualPage
+ PreviousDescriptor
->PageCount
;
334 PreviousEndPage
= PreviousDescriptor
->BasePage
+ PreviousDescriptor
->PageCount
;
335 PreviousMappedEndPage
= PreviousDescriptor
->VirtualPage
+ PreviousDescriptor
->PageCount
;
337 /* Check if the previous entry touches the current entry, and is compatible */
338 if ((PreviousEntry
!= MdList
->First
) &&
339 (PreviousDescriptor
->Type
== MemoryDescriptor
->Type
) &&
340 ((PreviousDescriptor
->Flags
^ MemoryDescriptor
->Flags
) & 0x1B19FFFF) &&
341 (PreviousEndPage
== MemoryDescriptor
->BasePage
) &&
342 ((!(MemoryDescriptor
->VirtualPage
) && !(PreviousDescriptor
->VirtualPage
)) ||
343 ((MemoryDescriptor
->VirtualPage
) && (PreviousDescriptor
->VirtualPage
) &&
344 (PreviousMappedEndPage
== MemoryDescriptor
->VirtualPage
))))
346 EfiPrintf(L
"Previous descriptor coalescable!\r\n");
349 /* CHeck if the current entry touches the next entry, and is compatible */
350 if ((NextEntry
!= MdList
->First
) &&
351 (NextDescriptor
->Type
== MemoryDescriptor
->Type
) &&
352 ((NextDescriptor
->Flags
^ MemoryDescriptor
->Flags
) & 0x1B19FFFF) &&
353 (EndPage
== NextDescriptor
->BasePage
) &&
354 ((!(MemoryDescriptor
->VirtualPage
) && !(PreviousDescriptor
->VirtualPage
)) ||
355 ((MemoryDescriptor
->VirtualPage
) && (PreviousDescriptor
->VirtualPage
) &&
356 (MappedEndPage
== NextDescriptor
->VirtualPage
))))
358 EfiPrintf(L
"Next descriptor coalescable!\r\n");
366 MmMdAddDescriptorToList (
367 _In_ PBL_MEMORY_DESCRIPTOR_LIST MdList
,
368 _In_ PBL_MEMORY_DESCRIPTOR MemoryDescriptor
,
372 PLIST_ENTRY ThisEntry
, FirstEntry
;
373 PBL_MEMORY_DESCRIPTOR ThisDescriptor
;
375 /* Arguments must be present */
376 if (!(MdList
) || !(MemoryDescriptor
))
378 return STATUS_INVALID_PARAMETER
;
381 /* Check if coalescing is forcefully disabled */
382 if (Flags
& BL_MM_ADD_DESCRIPTOR_NEVER_COALESCE_FLAG
)
384 /* Then we won't be coalescing */
385 Flags
&= BL_MM_ADD_DESCRIPTOR_COALESCE_FLAG
;
389 /* Coalesce if the descriptor requires it */
390 if (MemoryDescriptor
->Flags
& BlMemoryCoalesced
)
392 Flags
|= BL_MM_ADD_DESCRIPTOR_COALESCE_FLAG
;
396 /* Check if truncation is forcefully disabled */
397 if (Flags
& BL_MM_ADD_DESCRIPTOR_NEVER_TRUNCATE_FLAG
)
399 Flags
&= ~BL_MM_ADD_DESCRIPTOR_TRUNCATE_FLAG
;
402 /* Update the current list pointer if the descriptor requires it */
403 if (MemoryDescriptor
->Flags
& BlMemoryUpdate
)
405 Flags
|= BL_MM_ADD_DESCRIPTOR_UPDATE_LIST_POINTER_FLAG
;
408 /* Get the current descriptor */
409 ThisEntry
= MdList
->This
;
410 ThisDescriptor
= CONTAINING_RECORD(ThisEntry
, BL_MEMORY_DESCRIPTOR
, ListEntry
);
412 /* Also get the first descriptor */
413 FirstEntry
= MdList
->First
;
415 /* Check if there's no current pointer, or if it's higher than the new one */
417 (MemoryDescriptor
->BaseAddress
<= ThisDescriptor
->BaseAddress
))
419 /* Start at the first descriptor instead, since current is past us */
420 ThisEntry
= FirstEntry
->Flink
;
421 ThisDescriptor
= CONTAINING_RECORD(ThisEntry
, BL_MEMORY_DESCRIPTOR
, ListEntry
);
424 /* Loop until we find the right location to insert */
427 /* Have we gotten back to the first entry? */
428 if (ThisEntry
== FirstEntry
)
430 /* Then we didn't find a good match, so insert it right here */
431 InsertTailList(FirstEntry
, &MemoryDescriptor
->ListEntry
);
433 /* Do we have to truncate? */
434 if (Flags
& BL_MM_ADD_DESCRIPTOR_TRUNCATE_FLAG
)
436 /* Do it and then exit */
437 if (MmMdpTruncateDescriptor(MdList
, MemoryDescriptor
, Flags
))
439 return STATUS_SUCCESS
;
443 /* Do we have to coalesce? */
444 if (Flags
& BL_MM_ADD_DESCRIPTOR_COALESCE_FLAG
)
446 /* Do it and then exit */
447 if (MmMdpCoalesceDescriptor(MdList
, MemoryDescriptor
, Flags
))
449 return STATUS_SUCCESS
;
453 /* Do we have to update the current pointer? */
454 if (Flags
& BL_MM_ADD_DESCRIPTOR_UPDATE_LIST_POINTER_FLAG
)
457 MmMdpSaveCurrentListPointer(MdList
, &MemoryDescriptor
->ListEntry
);
461 return STATUS_SUCCESS
;
464 /* Is the new descriptor below this address, and has precedence over it? */
465 if ((MemoryDescriptor
->BaseAddress
< ThisDescriptor
->BaseAddress
) &&
466 (MmMdpHasPrecedence(MemoryDescriptor
->Type
, ThisDescriptor
->Type
)))
468 /* Then insert right here */
469 InsertTailList(ThisEntry
, &MemoryDescriptor
->ListEntry
);
470 return STATUS_SUCCESS
;
473 /* Try the next descriptor */
474 ThisEntry
= ThisEntry
->Flink
;
475 ThisDescriptor
= CONTAINING_RECORD(ThisEntry
, BL_MEMORY_DESCRIPTOR
, ListEntry
);
480 MmMdRemoveRegionFromMdlEx (
481 __in PBL_MEMORY_DESCRIPTOR_LIST MdList
,
483 __in ULONGLONG BasePage
,
484 __in ULONGLONG PageCount
,
485 __in PBL_MEMORY_DESCRIPTOR_LIST NewMdList
488 BOOLEAN HaveNewList
, UseVirtualPage
;
490 PLIST_ENTRY ListHead
, NextEntry
;
491 PBL_MEMORY_DESCRIPTOR Descriptor
;
492 BL_MEMORY_DESCRIPTOR NewDescriptor
;
493 ULONGLONG RegionSize
;
494 ULONGLONG FoundBasePage
, FoundEndPage
, FoundPageCount
, EndPage
;
496 /* Set initial status */
497 Status
= STATUS_SUCCESS
;
499 /* Check if removed descriptors should go into a new list */
500 if (NewMdList
!= NULL
)
503 MmMdInitializeListHead(NewMdList
);
504 NewMdList
->Type
= MdList
->Type
;
506 /* Remember for later */
515 /* Is the region being removed physical? */
516 UseVirtualPage
= FALSE
;
517 if (!(Flags
& BL_MM_REMOVE_VIRTUAL_REGION_FLAG
))
519 /* Is this a list of virtual descriptors? */
520 if (MdList
->Type
== BlMdVirtual
)
522 /* Request is nonsensical, fail */
523 Status
= STATUS_INVALID_PARAMETER
;
529 /* Is this a list of physical descriptors? */
530 if (MdList
->Type
== BlMdPhysical
)
532 /* We'll have to use the virtual page instead */
533 UseVirtualPage
= TRUE
;
538 ListHead
= MdList
->First
;
539 NextEntry
= ListHead
->Flink
;
540 while (NextEntry
!= ListHead
)
542 /* Get the descriptor */
543 Descriptor
= CONTAINING_RECORD(NextEntry
, BL_MEMORY_DESCRIPTOR
, ListEntry
);
545 /* Extract range details */
546 FoundBasePage
= UseVirtualPage
? Descriptor
->VirtualPage
: Descriptor
->BasePage
;
547 FoundPageCount
= Descriptor
->PageCount
;
548 FoundEndPage
= FoundBasePage
+ FoundPageCount
;
549 EndPage
= PageCount
+ BasePage
;
550 //EarlyPrint(L"Looking for Region 0x%08I64X-0x%08I64X in 0x%08I64X-0x%08I64X\r\n", BasePage, EndPage, FoundBasePage, FoundEndPage);
552 /* Make a copy of the original descriptor */
553 RtlCopyMemory(&NewDescriptor
, NextEntry
, sizeof(NewDescriptor
));
555 /* Check if the region to be removed starts after the found region starts */
556 if ((BasePage
> FoundBasePage
) || (FoundBasePage
>= EndPage
))
558 /* Check if the region ends after the found region */
559 if ((BasePage
>= FoundEndPage
) || (FoundEndPage
> EndPage
))
561 /* Check if the found region starts after the region or ends before the region */
562 if ((FoundBasePage
>= BasePage
) || (EndPage
>= FoundEndPage
))
564 /* This descriptor doesn't cover any part of the range */
565 //EarlyPrint(L"No part of this descriptor contains the region\r\n");
569 /* This descriptor covers the head of the allocation */
570 //EarlyPrint(L"Descriptor covers the head of the region\r\n");
575 /* This descriptor contains the entire allocation */
576 //EarlyPrint(L"Descriptor contains the entire region\r\n");
580 NextEntry
= NextEntry
->Flink
;
585 * This descriptor contains the end of the allocation. It may:
587 * - Contain the full allocation (i.e.: the start is aligned)
588 * - Contain parts of the end of the allocation (i.e.: the end is beyond)
589 * - Contain the entire tail end of the allocation (i..e:the end is within)
591 * So first, figure out if we cover the entire end or not
593 if (EndPage
> FoundEndPage
)
595 /* The allocation goes past the end of this descriptor */
596 EndPage
= FoundEndPage
;
599 /* This is how many pages we will eat away from the descriptor */
600 RegionSize
= EndPage
- FoundBasePage
;
602 /* Update the descriptor to account for the consumed pages */
603 Descriptor
->BasePage
+= RegionSize
;
604 Descriptor
->PageCount
-= RegionSize
;
605 if (Descriptor
->VirtualPage
)
607 Descriptor
->VirtualPage
+= RegionSize
;
610 /* Go to the next entry */
611 NextEntry
= NextEntry
->Flink
;
613 /* Check if the descriptor is now empty */
614 if (!Descriptor
->PageCount
)
617 //EarlyPrint(L"Entire descriptor consumed\r\n");
618 MmMdRemoveDescriptorFromList(MdList
, Descriptor
);
619 MmMdFreeDescriptor(Descriptor
);
621 /* Check if we're supposed to insert it into a new list */
624 EfiPrintf(L
"Not yet implemented\r\n");
625 Status
= STATUS_NOT_IMPLEMENTED
;
633 /* Check for failure cleanup */
634 if (!NT_SUCCESS(Status
))
636 /* Did we have to build a new list? */
639 /* Free and re-initialize it */
640 MmMdFreeList(NewMdList
);
641 MmMdInitializeListHead(NewMdList
);
642 NewMdList
->Type
= MdList
->Type
;
650 MmMdFindSatisfyingRegion (
651 _In_ PBL_MEMORY_DESCRIPTOR Descriptor
,
652 _Out_ PBL_MEMORY_DESCRIPTOR NewDescriptor
,
653 _In_ ULONGLONG Pages
,
654 _In_ PBL_ADDRESS_RANGE BaseRange
,
655 _In_ PBL_ADDRESS_RANGE VirtualRange
,
656 _In_ BOOLEAN TopDown
,
657 _In_ BL_MEMORY_TYPE MemoryType
,
662 ULONGLONG BaseMin
, BaseMax
;
663 ULONGLONG VirtualPage
, BasePage
;
665 /* Extract the minimum and maximum range */
666 BaseMin
= BaseRange
->Minimum
;
667 BaseMax
= BaseRange
->Maximum
;
669 /* Don't go below where the descriptor starts */
670 if (BaseMin
< Descriptor
->BasePage
)
672 BaseMin
= Descriptor
->BasePage
;
675 /* Don't go beyond where the descriptor ends */
676 if (BaseMax
> (Descriptor
->BasePage
+ Descriptor
->PageCount
- 1))
678 BaseMax
= (Descriptor
->BasePage
+ Descriptor
->PageCount
- 1);
681 /* Check for start overflow */
682 if (BaseMin
> BaseMax
)
684 EfiPrintf(L
"Descriptor overflow\r\n");
688 /* Align the base as required */
691 BaseMin
= ALIGN_UP_BY(BaseMin
, Alignment
);
694 /* Check for range overflow */
695 if (((BaseMin
+ Pages
- 1) < BaseMin
) || ((BaseMin
+ Pages
- 1) > BaseMax
))
700 /* Check if this was a top-down request */
703 /* Then get the highest page possible */
704 BasePage
= BaseMax
- Pages
+ 1;
707 /* Align it as needed */
708 BasePage
= ALIGN_DOWN_BY(BasePage
, Alignment
);
713 /* Otherwise, get the lowest page possible */
717 /* If a virtual address range was passed in, this must be a virtual descriptor */
718 if (((VirtualRange
->Minimum
) || (VirtualRange
->Maximum
)) &&
719 !(Descriptor
->VirtualPage
))
724 /* Any mapped page already? */
725 if (Descriptor
->VirtualPage
)
727 EfiPrintf(L
"Virtual memory not yet supported\r\n");
732 /* Nothing to worry about */
736 /* Bail out if the memory type attributes don't match */
737 if ((((Flags
& 0xFF) & (Descriptor
->Flags
& 0xFF)) != (Flags
& 0xFF)) ||
738 (((Flags
& 0xFF00) & (Descriptor
->Flags
& 0xFF00)) != (Flags
& 0xFF00)))
740 EfiPrintf(L
"Incorrect memory attributes\r\n");
744 /* Bail out if the allocation flags don't match */
745 if (((Flags
^ Descriptor
->Flags
) & (BlMemoryRuntime
| BlMemoryReserved
| BlMemoryUnknown
)))
747 //EfiPrintf(L"Incorrect memory allocation flags\r\n");
751 /* Bail out if the type doesn't match */
752 if (Descriptor
->Type
!= MemoryType
)
754 //EfiPrintf(L"Incorrect descriptor type: %lx %lx\r\n", Descriptor->Type, MemoryType);
758 /* We have a matching region, fill out the descriptor for it */
759 NewDescriptor
->BasePage
= BasePage
;
760 NewDescriptor
->PageCount
= Pages
;
761 NewDescriptor
->Type
= Descriptor
->Type
;
762 NewDescriptor
->VirtualPage
= VirtualPage
;
763 NewDescriptor
->Flags
= Descriptor
->Flags
;
764 //EfiPrintf(L"Found a matching descriptor: %08I64X with %08I64X pages\r\n", BasePage, Pages);
769 MmMdFreeGlobalDescriptors (
773 PBL_MEMORY_DESCRIPTOR Descriptor
, OldDescriptor
;
775 PLIST_ENTRY OldFlink
, OldBlink
;
777 /* Make sure we're not int middle of a call using a descriptor */
778 if (MmDescriptorCallTreeCount
!= 1)
783 /* Loop every current global descriptor */
784 while (Index
< MmGlobalMemoryDescriptorsUsed
)
786 /* Does it have any valid pageS? */
787 OldDescriptor
= &MmGlobalMemoryDescriptors
[Index
];
788 if (OldDescriptor
->PageCount
)
790 /* Allocate a copy of it */
791 Descriptor
= BlMmAllocateHeap(sizeof(*Descriptor
));
798 OldBlink
= OldDescriptor
->ListEntry
.Blink
;
799 OldFlink
= OldDescriptor
->ListEntry
.Flink
;
802 *Descriptor
= *OldDescriptor
;
805 OldBlink
->Flink
= &Descriptor
->ListEntry
;
806 OldFlink
->Blink
= &Descriptor
->ListEntry
;
808 /* Zero the descriptor */
809 RtlZeroMemory(OldDescriptor
, sizeof(*OldDescriptor
));
816 /* All global descriptors freed */
817 MmGlobalMemoryDescriptorsUsed
= 0;
823 _In_ PBL_LIBRARY_PARAMETERS LibraryParameters
826 /* Are we in phase 1? */
829 /* Switch to dynamic descriptors if we have too many */
830 if (LibraryParameters
->DescriptorCount
> RTL_NUMBER_OF(MmStaticMemoryDescriptors
))
832 MmMdpSwitchToDynamicDescriptors(LibraryParameters
->DescriptorCount
);
837 /* In phase 0, start with a pool of 512 static descriptors */
838 MmGlobalMemoryDescriptorCount
= RTL_NUMBER_OF(MmStaticMemoryDescriptors
);
839 MmGlobalMemoryDescriptors
= MmStaticMemoryDescriptors
;
840 RtlZeroMemory(MmStaticMemoryDescriptors
, sizeof(MmStaticMemoryDescriptors
));
841 MmGlobalMemoryDescriptorsUsed
= FALSE
;