reactos/boot/environ/lib/mm/descriptor.c
Amine Khaldi 0ee830d7a4 * Create a branch for USB experiments.
svn path=/branches/usb-experiments/; revision=72629
2016-09-09 15:11:19 +00:00

843 lines
26 KiB
C

/*
* COPYRIGHT: See COPYING.ARM in the top level directory
* PROJECT: ReactOS UEFI Boot Library
* FILE: boot/environ/lib/mm/descriptor.c
* PURPOSE: Boot Library Memory Manager Descriptor Manager
* PROGRAMMER: Alex Ionescu (alex.ionescu@reactos.org)
*/
/* INCLUDES ******************************************************************/
#include "bl.h"
/* DATA VARIABLES ************************************************************/
BL_MEMORY_DESCRIPTOR MmStaticMemoryDescriptors[512];
ULONG MmGlobalMemoryDescriptorCount;
PBL_MEMORY_DESCRIPTOR MmGlobalMemoryDescriptors;
BOOLEAN MmGlobalMemoryDescriptorsUsed;
PBL_MEMORY_DESCRIPTOR MmDynamicMemoryDescriptors;
ULONG MmDynamicMemoryDescriptorCount;
BL_MEMORY_TYPE MmPlatformMemoryTypePrecedence[] =
{
BlReservedMemory,
BlUnusableMemory,
BlDeviceIoMemory,
BlDevicePortMemory,
BlPalMemory,
BlEfiRuntimeMemory,
BlAcpiNvsMemory,
BlAcpiReclaimMemory,
BlEfiBootMemory
};
/* FUNCTIONS *****************************************************************/
/* The order is Conventional > Other > System > Loader > Application */
BOOLEAN
MmMdpHasPrecedence (
_In_ BL_MEMORY_TYPE Type1,
_In_ BL_MEMORY_TYPE Type2
)
{
BL_MEMORY_CLASS Class1, Class2;
ULONG i, j;
/* Descriptor is free RAM -- it preceeds */
if (Type1 == BlConventionalMemory)
{
return TRUE;
}
/* It isn't free RAM, but the comparator is -- it suceeds it */
if (Type2 == BlConventionalMemory)
{
return FALSE;
}
/* Descriptor is not system, application, or loader class -- it preceeds */
Class1 = Type1 >> BL_MEMORY_CLASS_SHIFT;
if ((Class1 != BlSystemClass) &&
(Class1 != BlApplicationClass) &&
(Class1 != BlLoaderClass))
{
return TRUE;
}
/* It isn't one of those classes, but the comparator it -- it suceeds it */
Class2 = Type2 >> BL_MEMORY_CLASS_SHIFT;
if ((Class2 != BlSystemClass) &&
(Class2 != BlApplicationClass) &&
(Class2 != BlLoaderClass))
{
return FALSE;
}
/* Descriptor is system class */
if (Class1 == BlSystemClass)
{
/* And so is the other guy... */
if (Class2 == BlSystemClass)
{
i = 0;
j = 0;
/* Scan for the descriptor's system precedence index */
do
{
if (MmPlatformMemoryTypePrecedence[j] == Type1)
{
break;
}
} while (++j < RTL_NUMBER_OF(MmPlatformMemoryTypePrecedence));
/* Use an invalid index if one wasn't found */
if (j == RTL_NUMBER_OF(MmPlatformMemoryTypePrecedence))
{
j = 0xFFFFFFFF;
}
/* Now scan for the comparator's system precedence index */
while (MmPlatformMemoryTypePrecedence[i] != Type2)
{
/* Use an invalid index if one wasn't found */
if (++i >= RTL_NUMBER_OF(MmPlatformMemoryTypePrecedence))
{
i = 0xFFFFFFFF;
break;
}
}
/* Does the current have a valid index? */
if (j != 0xFFFFFFFF)
{
/* Yes, what about the comparator? */
if (i != 0xFFFFFFFF)
{
/* Let the indexes fight! */
return i >= j;
}
/* Succeed the comparator, its index is unknown */
return FALSE;
}
}
/* The comparator isn't system, so it preceeds it */
return TRUE;
}
/* Descriptor is not system class, but comparator is -- it suceeds it */
if (Class2 == BlSystemClass)
{
return FALSE;
}
/* Descriptor is loader class -- it preceeds */
if (Class1 == BlLoaderClass)
{
return TRUE;
}
/* It isn't loader class -- if the other guy is, suceed it */
return Class2 != BlLoaderClass;
}
VOID
MmMdpSwitchToDynamicDescriptors (
_In_ ULONG Count
)
{
EfiPrintf(L"dynamic switch NOT SUPPORTED!!!\r\n");
while (1);
}
NTSTATUS
MmMdFreeDescriptor (
_In_ PBL_MEMORY_DESCRIPTOR MemoryDescriptor
)
{
NTSTATUS Status;
/* Check if this is a valid static descriptor */
if (((MmDynamicMemoryDescriptors) &&
(MemoryDescriptor >= MmDynamicMemoryDescriptors) &&
(MemoryDescriptor < (MmDynamicMemoryDescriptors + MmDynamicMemoryDescriptorCount))) ||
((MemoryDescriptor >= MmStaticMemoryDescriptors) && (MemoryDescriptor < &MmStaticMemoryDescriptors[511])))
{
/* It's a global/static descriptor, so just zero it */
RtlZeroMemory(MemoryDescriptor, sizeof(BL_MEMORY_DESCRIPTOR));
Status = STATUS_SUCCESS;
}
else
{
/* It's a dynamic descriptor, so free it */
EfiPrintf(L"Dynamic descriptors not yet supported\r\n");
Status = STATUS_NOT_IMPLEMENTED;
}
/* Done */
return Status;
}
VOID
MmMdpSaveCurrentListPointer (
_In_ PBL_MEMORY_DESCRIPTOR_LIST MdList,
_In_ PLIST_ENTRY Current
)
{
/* Make sure that this is not a global descriptor and not the first one */
if (((Current < &MmGlobalMemoryDescriptors->ListEntry) ||
(Current >= &MmGlobalMemoryDescriptors[MmGlobalMemoryDescriptorCount].ListEntry)) &&
(Current != MdList->First))
{
/* Save this as the current pointer */
MdList->This = Current;
}
}
VOID
MmMdRemoveDescriptorFromList (
_In_ PBL_MEMORY_DESCRIPTOR_LIST MdList,
_In_ PBL_MEMORY_DESCRIPTOR Entry
)
{
/* Remove the entry */
RemoveEntryList(&Entry->ListEntry);
/* Check if this was the current link */
if (MdList->This == &Entry->ListEntry)
{
/* Remove the current link and set the next one */
MdList->This = NULL;
MmMdpSaveCurrentListPointer(MdList, Entry->ListEntry.Blink);
}
}
VOID
MmMdFreeList(
_In_ PBL_MEMORY_DESCRIPTOR_LIST MdList
)
{
PLIST_ENTRY FirstEntry, NextEntry;
PBL_MEMORY_DESCRIPTOR Entry;
/* Go over every descriptor from the top */
FirstEntry = MdList->First;
NextEntry = FirstEntry->Flink;
while (NextEntry != FirstEntry)
{
/* Remove and free each one */
Entry = CONTAINING_RECORD(NextEntry, BL_MEMORY_DESCRIPTOR, ListEntry);
NextEntry = NextEntry->Flink;
MmMdRemoveDescriptorFromList(MdList, Entry);
MmMdFreeDescriptor(Entry);
}
}
PBL_MEMORY_DESCRIPTOR
MmMdInitByteGranularDescriptor (
_In_ ULONG Flags,
_In_ BL_MEMORY_TYPE Type,
_In_ ULONGLONG BasePage,
_In_ ULONGLONG VirtualPage,
_In_ ULONGLONG PageCount
)
{
PBL_MEMORY_DESCRIPTOR MemoryDescriptor;
/* If we're out of descriptors, bail out */
if (MmGlobalMemoryDescriptorsUsed >= MmGlobalMemoryDescriptorCount)
{
EfiPrintf(L"Out of descriptors!\r\n");
return NULL;
}
/* Take one of the available descriptors and fill it out */
MemoryDescriptor = &MmGlobalMemoryDescriptors[MmGlobalMemoryDescriptorsUsed];
MemoryDescriptor->BaseAddress = BasePage;
MemoryDescriptor->VirtualPage = VirtualPage;
MemoryDescriptor->PageCount = PageCount;
MemoryDescriptor->Flags = Flags;
MemoryDescriptor->Type = Type;
InitializeListHead(&MemoryDescriptor->ListEntry);
/* Increment the count and return the descriptor */
MmGlobalMemoryDescriptorsUsed++;
return MemoryDescriptor;
}
BOOLEAN
MmMdpTruncateDescriptor (
__in PBL_MEMORY_DESCRIPTOR_LIST MdList,
__in PBL_MEMORY_DESCRIPTOR MemoryDescriptor,
__in ULONG Flags
)
{
PBL_MEMORY_DESCRIPTOR NextDescriptor, PreviousDescriptor;
PLIST_ENTRY NextEntry, PreviousEntry;
ULONGLONG EndPage, PreviousEndPage;// , NextEndPage;
/* Get the next descriptor */
NextEntry = MemoryDescriptor->ListEntry.Flink;
NextDescriptor = CONTAINING_RECORD(NextEntry, BL_MEMORY_DESCRIPTOR, ListEntry);
/* Get the previous descriptor */
PreviousEntry = MemoryDescriptor->ListEntry.Blink;
PreviousDescriptor = CONTAINING_RECORD(PreviousEntry, BL_MEMORY_DESCRIPTOR, ListEntry);
/* Calculate end pages */
EndPage = MemoryDescriptor->BasePage + MemoryDescriptor->PageCount;
//NextEndPage = NextDescriptor->BasePage + NextDescriptor->PageCount;
PreviousEndPage = PreviousDescriptor->BasePage + PreviousDescriptor->PageCount;
/* Check for backward overlap */
if ((PreviousEntry != MdList->First) && (MemoryDescriptor->BasePage < PreviousEndPage))
{
EfiPrintf(L"Overlap detected -- this is unexpected on x86/x64 platforms\r\n");
}
/* Check for forward overlap */
if ((NextEntry != MdList->First) && (NextDescriptor->BasePage < EndPage))
{
EfiPrintf(L"Overlap detected -- this is unexpected on x86/x64 platforms\r\n");
}
/* Nothing to do */
return FALSE;
}
BOOLEAN
MmMdpCoalesceDescriptor (
__in PBL_MEMORY_DESCRIPTOR_LIST MdList,
__in PBL_MEMORY_DESCRIPTOR MemoryDescriptor,
__in ULONG Flags
)
{
PBL_MEMORY_DESCRIPTOR NextDescriptor, PreviousDescriptor;
PLIST_ENTRY NextEntry, PreviousEntry;
ULONGLONG EndPage, PreviousEndPage, PreviousMappedEndPage, MappedEndPage;
/* Get the next descriptor */
NextEntry = MemoryDescriptor->ListEntry.Flink;
NextDescriptor = CONTAINING_RECORD(NextEntry, BL_MEMORY_DESCRIPTOR, ListEntry);
/* Get the previous descriptor */
PreviousEntry = MemoryDescriptor->ListEntry.Blink;
PreviousDescriptor = CONTAINING_RECORD(PreviousEntry, BL_MEMORY_DESCRIPTOR, ListEntry);
/* Calculate end pages */
EndPage = MemoryDescriptor->BasePage + MemoryDescriptor->PageCount;
MappedEndPage = MemoryDescriptor->BasePage + MemoryDescriptor->PageCount;
PreviousMappedEndPage = PreviousDescriptor->VirtualPage + PreviousDescriptor->PageCount;
PreviousEndPage = PreviousDescriptor->BasePage + PreviousDescriptor->PageCount;
PreviousMappedEndPage = PreviousDescriptor->VirtualPage + PreviousDescriptor->PageCount;
/* Check if the previous entry touches the current entry, and is compatible */
if ((PreviousEntry != MdList->First) &&
(PreviousDescriptor->Type == MemoryDescriptor->Type) &&
((PreviousDescriptor->Flags ^ MemoryDescriptor->Flags) & 0x1B19FFFF) &&
(PreviousEndPage == MemoryDescriptor->BasePage) &&
((!(MemoryDescriptor->VirtualPage) && !(PreviousDescriptor->VirtualPage)) ||
((MemoryDescriptor->VirtualPage) && (PreviousDescriptor->VirtualPage) &&
(PreviousMappedEndPage == MemoryDescriptor->VirtualPage))))
{
EfiPrintf(L"Previous descriptor coalescible!\r\n");
}
/* CHeck if the current entry touches the next entry, and is compatible */
if ((NextEntry != MdList->First) &&
(NextDescriptor->Type == MemoryDescriptor->Type) &&
((NextDescriptor->Flags ^ MemoryDescriptor->Flags) & 0x1B19FFFF) &&
(EndPage == NextDescriptor->BasePage) &&
((!(MemoryDescriptor->VirtualPage) && !(PreviousDescriptor->VirtualPage)) ||
((MemoryDescriptor->VirtualPage) && (PreviousDescriptor->VirtualPage) &&
(MappedEndPage == NextDescriptor->VirtualPage))))
{
EfiPrintf(L"Next descriptor coalescible!\r\n");
}
/* Nothing to do */
return FALSE;
}
NTSTATUS
MmMdAddDescriptorToList (
_In_ PBL_MEMORY_DESCRIPTOR_LIST MdList,
_In_ PBL_MEMORY_DESCRIPTOR MemoryDescriptor,
_In_ ULONG Flags
)
{
PLIST_ENTRY ThisEntry, FirstEntry;
PBL_MEMORY_DESCRIPTOR ThisDescriptor;
/* Arguments must be present */
if (!(MdList) || !(MemoryDescriptor))
{
return STATUS_INVALID_PARAMETER;
}
/* Check if coalescing is forcefully disabled */
if (Flags & BL_MM_ADD_DESCRIPTOR_NEVER_COALESCE_FLAG)
{
/* Then we won't be coalescing */
Flags &= BL_MM_ADD_DESCRIPTOR_COALESCE_FLAG;
}
else
{
/* Coalesce if the descriptor requires it */
if (MemoryDescriptor->Flags & BlMemoryCoalesced)
{
Flags |= BL_MM_ADD_DESCRIPTOR_COALESCE_FLAG;
}
}
/* Check if truncation is forcefully disabled */
if (Flags & BL_MM_ADD_DESCRIPTOR_NEVER_TRUNCATE_FLAG)
{
Flags &= ~BL_MM_ADD_DESCRIPTOR_TRUNCATE_FLAG;
}
/* Update the current list pointer if the descriptor requires it */
if (MemoryDescriptor->Flags & BlMemoryUpdate)
{
Flags |= BL_MM_ADD_DESCRIPTOR_UPDATE_LIST_POINTER_FLAG;
}
/* Get the current descriptor */
ThisEntry = MdList->This;
ThisDescriptor = CONTAINING_RECORD(ThisEntry, BL_MEMORY_DESCRIPTOR, ListEntry);
/* Also get the first descriptor */
FirstEntry = MdList->First;
/* Check if there's no current pointer, or if it's higher than the new one */
if (!(ThisEntry) ||
(MemoryDescriptor->BaseAddress <= ThisDescriptor->BaseAddress))
{
/* Start at the first descriptor instead, since current is past us */
ThisEntry = FirstEntry->Flink;
ThisDescriptor = CONTAINING_RECORD(ThisEntry, BL_MEMORY_DESCRIPTOR, ListEntry);
}
/* Loop until we find the right location to insert */
while (1)
{
/* Have we gotten back to the first entry? */
if (ThisEntry == FirstEntry)
{
/* Then we didn't find a good match, so insert it right here */
InsertTailList(FirstEntry, &MemoryDescriptor->ListEntry);
/* Do we have to truncate? */
if (Flags & BL_MM_ADD_DESCRIPTOR_TRUNCATE_FLAG)
{
/* Do it and then exit */
if (MmMdpTruncateDescriptor(MdList, MemoryDescriptor, Flags))
{
return STATUS_SUCCESS;
}
}
/* Do we have to coalesce? */
if (Flags & BL_MM_ADD_DESCRIPTOR_COALESCE_FLAG)
{
/* Do it and then exit */
if (MmMdpCoalesceDescriptor(MdList, MemoryDescriptor, Flags))
{
return STATUS_SUCCESS;
}
}
/* Do we have to update the current pointer? */
if (Flags & BL_MM_ADD_DESCRIPTOR_UPDATE_LIST_POINTER_FLAG)
{
/* Do it */
MmMdpSaveCurrentListPointer(MdList, &MemoryDescriptor->ListEntry);
}
/* We're done */
return STATUS_SUCCESS;
}
/* Is the new descriptor below this address, and has precedence over it? */
if ((MemoryDescriptor->BaseAddress < ThisDescriptor->BaseAddress) &&
(MmMdpHasPrecedence(MemoryDescriptor->Type, ThisDescriptor->Type)))
{
/* Then insert right here */
InsertTailList(ThisEntry, &MemoryDescriptor->ListEntry);
return STATUS_SUCCESS;
}
/* Try the next descriptor */
ThisEntry = ThisEntry->Flink;
ThisDescriptor = CONTAINING_RECORD(ThisEntry, BL_MEMORY_DESCRIPTOR, ListEntry);
}
}
NTSTATUS
MmMdRemoveRegionFromMdlEx (
__in PBL_MEMORY_DESCRIPTOR_LIST MdList,
__in ULONG Flags,
__in ULONGLONG BasePage,
__in ULONGLONG PageCount,
__in PBL_MEMORY_DESCRIPTOR_LIST NewMdList
)
{
BOOLEAN HaveNewList, UseVirtualPage;
NTSTATUS Status;
PLIST_ENTRY ListHead, NextEntry;
PBL_MEMORY_DESCRIPTOR Descriptor;
BL_MEMORY_DESCRIPTOR NewDescriptor;
ULONGLONG RegionSize;
ULONGLONG FoundBasePage, FoundEndPage, FoundPageCount, EndPage;
/* Set initial status */
Status = STATUS_SUCCESS;
/* Check if removed descriptors should go into a new list */
if (NewMdList != NULL)
{
/* Initialize it */
MmMdInitializeListHead(NewMdList);
NewMdList->Type = MdList->Type;
/* Remember for later */
HaveNewList = TRUE;
}
else
{
/* For later */
HaveNewList = FALSE;
}
/* Is the region being removed physical? */
UseVirtualPage = FALSE;
if (!(Flags & BL_MM_REMOVE_VIRTUAL_REGION_FLAG))
{
/* Is this a list of virtual descriptors? */
if (MdList->Type == BlMdVirtual)
{
/* Request is nonsensical, fail */
Status = STATUS_INVALID_PARAMETER;
goto Quickie;
}
}
else
{
/* Is this a list of physical descriptors? */
if (MdList->Type == BlMdPhysical)
{
/* We'll have to use the virtual page instead */
UseVirtualPage = TRUE;
}
}
/* Loop the list*/
ListHead = MdList->First;
NextEntry = ListHead->Flink;
while (NextEntry != ListHead)
{
/* Get the descriptor */
Descriptor = CONTAINING_RECORD(NextEntry, BL_MEMORY_DESCRIPTOR, ListEntry);
/* Extract range details */
FoundBasePage = UseVirtualPage ? Descriptor->VirtualPage : Descriptor->BasePage;
FoundPageCount = Descriptor->PageCount;
FoundEndPage = FoundBasePage + FoundPageCount;
EndPage = PageCount + BasePage;
//EarlyPrint(L"Looking for Region 0x%08I64X-0x%08I64X in 0x%08I64X-0x%08I64X\r\n", BasePage, EndPage, FoundBasePage, FoundEndPage);
/* Make a copy of the original descriptor */
RtlCopyMemory(&NewDescriptor, NextEntry, sizeof(NewDescriptor));
/* Check if the region to be removed starts after the found region starts */
if ((BasePage > FoundBasePage) || (FoundBasePage >= EndPage))
{
/* Check if the region ends after the found region */
if ((BasePage >= FoundEndPage) || (FoundEndPage > EndPage))
{
/* Check if the found region starts after the region or ends before the region */
if ((FoundBasePage >= BasePage) || (EndPage >= FoundEndPage))
{
/* This descriptor doesn't cover any part of the range */
//EarlyPrint(L"No part of this descriptor contains the region\r\n");
}
else
{
/* This descriptor covers the head of the allocation */
//EarlyPrint(L"Descriptor covers the head of the region\r\n");
}
}
else
{
/* This descriptor contains the entire allocation */
//EarlyPrint(L"Descriptor contains the entire region\r\n");
}
/* Keep going */
NextEntry = NextEntry->Flink;
}
else
{
/*
* This descriptor contains the end of the allocation. It may:
*
* - Contain the full allocation (i.e.: the start is aligned)
* - Contain parts of the end of the allocation (i.e.: the end is beyond)
* - Contain the entire tail end of the allocation (i..e:the end is within)
*
* So first, figure out if we cover the entire end or not
*/
if (EndPage > FoundEndPage)
{
/* The allocation goes past the end of this descriptor */
EndPage = FoundEndPage;
}
/* This is how many pages we will eat away from the descriptor */
RegionSize = EndPage - FoundBasePage;
/* Update the descriptor to account for the consumed pages */
Descriptor->BasePage += RegionSize;
Descriptor->PageCount -= RegionSize;
if (Descriptor->VirtualPage)
{
Descriptor->VirtualPage += RegionSize;
}
/* Go to the next entry */
NextEntry = NextEntry->Flink;
/* Check if the descriptor is now empty */
if (!Descriptor->PageCount)
{
/* Remove it */
//EarlyPrint(L"Entire descriptor consumed\r\n");
MmMdRemoveDescriptorFromList(MdList, Descriptor);
MmMdFreeDescriptor(Descriptor);
/* Check if we're supposed to insert it into a new list */
if (HaveNewList)
{
EfiPrintf(L"Not yet implemented\r\n");
Status = STATUS_NOT_IMPLEMENTED;
goto Quickie;
}
}
}
}
Quickie:
/* Check for failure cleanup */
if (!NT_SUCCESS(Status))
{
/* Did we have to build a new list? */
if (HaveNewList)
{
/* Free and re-initialize it */
MmMdFreeList(NewMdList);
MmMdInitializeListHead(NewMdList);
NewMdList->Type = MdList->Type;
}
}
return Status;
}
BOOLEAN
MmMdFindSatisfyingRegion (
_In_ PBL_MEMORY_DESCRIPTOR Descriptor,
_Out_ PBL_MEMORY_DESCRIPTOR NewDescriptor,
_In_ ULONGLONG Pages,
_In_ PBL_ADDRESS_RANGE BaseRange,
_In_ PBL_ADDRESS_RANGE VirtualRange,
_In_ BOOLEAN TopDown,
_In_ BL_MEMORY_TYPE MemoryType,
_In_ ULONG Flags,
_In_ ULONG Alignment
)
{
ULONGLONG BaseMin, BaseMax;
ULONGLONG VirtualPage, BasePage;
/* Extract the minimum and maximum range */
BaseMin = BaseRange->Minimum;
BaseMax = BaseRange->Maximum;
/* Don't go below where the descriptor starts */
if (BaseMin < Descriptor->BasePage)
{
BaseMin = Descriptor->BasePage;
}
/* Don't go beyond where the descriptor ends */
if (BaseMax > (Descriptor->BasePage + Descriptor->PageCount - 1))
{
BaseMax = (Descriptor->BasePage + Descriptor->PageCount - 1);
}
/* Check for start overflow */
if (BaseMin > BaseMax)
{
EfiPrintf(L"Descriptor overflow\r\n");
return FALSE;
}
/* Align the base as required */
if (Alignment != 1)
{
BaseMin = ALIGN_UP_BY(BaseMin, Alignment);
}
/* Check for range overflow */
if (((BaseMin + Pages - 1) < BaseMin) || ((BaseMin + Pages - 1) > BaseMax))
{
return FALSE;
}
/* Check if this was a top-down request */
if (TopDown)
{
/* Then get the highest page possible */
BasePage = BaseMax - Pages + 1;
if (Alignment != 1)
{
/* Align it as needed */
BasePage = ALIGN_DOWN_BY(BasePage, Alignment);
}
}
else
{
/* Otherwise, get the lowest page possible */
BasePage = BaseMin;
}
/* If a virtual address range was passed in, this must be a virtual descriptor */
if (((VirtualRange->Minimum) || (VirtualRange->Maximum)) &&
!(Descriptor->VirtualPage))
{
return FALSE;
}
/* Any mapped page already? */
if (Descriptor->VirtualPage)
{
EfiPrintf(L"Virtual memory not yet supported\r\n");
return FALSE;
}
else
{
/* Nothing to worry about */
VirtualPage = 0;
}
/* Bail out if the memory type attributes don't match */
if ((((Flags & 0xFF) & (Descriptor->Flags & 0xFF)) != (Flags & 0xFF)) ||
(((Flags & 0xFF00) & (Descriptor->Flags & 0xFF00)) != (Flags & 0xFF00)))
{
EfiPrintf(L"Incorrect memory attributes\r\n");
return FALSE;
}
/* Bail out if the allocation flags don't match */
if (((Flags ^ Descriptor->Flags) & (BlMemoryRuntime | BlMemoryReserved | BlMemoryUnknown)))
{
//EfiPrintf(L"Incorrect memory allocation flags\r\n");
return FALSE;
}
/* Bail out if the type doesn't match */
if (Descriptor->Type != MemoryType)
{
//EfiPrintf(L"Incorrect descriptor type: %lx %lx\r\n", Descriptor->Type, MemoryType);
return FALSE;
}
/* We have a matching region, fill out the descriptor for it */
NewDescriptor->BasePage = BasePage;
NewDescriptor->PageCount = Pages;
NewDescriptor->Type = Descriptor->Type;
NewDescriptor->VirtualPage = VirtualPage;
NewDescriptor->Flags = Descriptor->Flags;
//EfiPrintf(L"Found a matching descriptor: %08I64X with %08I64X pages\r\n", BasePage, Pages);
return TRUE;
}
VOID
MmMdFreeGlobalDescriptors (
VOID
)
{
PBL_MEMORY_DESCRIPTOR Descriptor, OldDescriptor;
ULONG Index = 0;
PLIST_ENTRY OldFlink, OldBlink;
/* Make sure we're not int middle of a call using a descriptor */
if (MmDescriptorCallTreeCount != 1)
{
return;
}
/* Loop every current global descriptor */
while (Index < MmGlobalMemoryDescriptorsUsed)
{
/* Does it have any valid pageS? */
OldDescriptor = &MmGlobalMemoryDescriptors[Index];
if (OldDescriptor->PageCount)
{
/* Allocate a copy of it */
Descriptor = BlMmAllocateHeap(sizeof(*Descriptor));
if (!Descriptor)
{
return;
}
/* Save the links */
OldBlink = OldDescriptor->ListEntry.Blink;
OldFlink = OldDescriptor->ListEntry.Flink;
/* Make the copy */
*Descriptor = *OldDescriptor;
/* Fix the links */
OldBlink->Flink = &Descriptor->ListEntry;
OldFlink->Blink = &Descriptor->ListEntry;
/* Zero the descriptor */
RtlZeroMemory(OldDescriptor, sizeof(*OldDescriptor));
}
/* Keep going */
Index++;
}
/* All global descriptors freed */
MmGlobalMemoryDescriptorsUsed = 0;
}
VOID
MmMdInitialize (
_In_ ULONG Phase,
_In_ PBL_LIBRARY_PARAMETERS LibraryParameters
)
{
/* Are we in phase 1? */
if (Phase != 0)
{
/* Switch to dynamic descriptors if we have too many */
if (LibraryParameters->DescriptorCount > RTL_NUMBER_OF(MmStaticMemoryDescriptors))
{
MmMdpSwitchToDynamicDescriptors(LibraryParameters->DescriptorCount);
}
}
else
{
/* In phase 0, start with a pool of 512 static descriptors */
MmGlobalMemoryDescriptorCount = RTL_NUMBER_OF(MmStaticMemoryDescriptors);
MmGlobalMemoryDescriptors = MmStaticMemoryDescriptors;
RtlZeroMemory(MmStaticMemoryDescriptors, sizeof(MmStaticMemoryDescriptors));
MmGlobalMemoryDescriptorsUsed = FALSE;
}
}