{
NTSTATUS Status;
PULONG Used;
- BOOLEAN Finished;
PLIST_ENTRY First, NextEntry;
PBL_MEMORY_DESCRIPTOR Descriptor;
/* Iterate through the list */
First = SourceList->First;
NextEntry = First->Flink;
- if (First->Flink != First)
+ while ((NextEntry != First) && (NT_SUCCESS(Status)))
{
- /* As long as we have success */
- while (NT_SUCCESS(Status))
+ /* Make sure there's still space */
+ if (Count <= *Used)
{
- /* Check if there's still space */
- if (Count <= *Used)
- {
- Status = STATUS_NO_MEMORY;
- break;
- }
-
- /* Get the current descriptor */
- Descriptor = CONTAINING_RECORD(NextEntry,
- BL_MEMORY_DESCRIPTOR,
- ListEntry);
-
- /* Copy it into one of the descriptors we have */
- RtlCopyMemory(&ListDescriptor[*Used],
- Descriptor,
- sizeof(*Descriptor));
+ Status = STATUS_NO_MEMORY;
+ break;
+ }
- /* Add it to the list we have */
- Status = MmMdAddDescriptorToList(DestinationList,
- &ListDescriptor[*Used],
- Flags);
- ++*Used;
+ /* Get the current descriptor */
+ Descriptor = CONTAINING_RECORD(NextEntry,
+ BL_MEMORY_DESCRIPTOR,
+ ListEntry);
- /* Before moving on, check if we're done */
- Finished = NextEntry->Flink == SourceList->First;
+ /* Copy it into one of the descriptors we have */
+ RtlCopyMemory(&ListDescriptor[*Used],
+ Descriptor,
+ sizeof(*Descriptor));
- /* Move to the next entry */
- NextEntry = NextEntry->Flink;
+ /* Add it to the list we have */
+ Status = MmMdAddDescriptorToList(DestinationList,
+ &ListDescriptor[*Used],
+ Flags);
+ ++*Used;
- if (Finished)
- {
- break;
- }
- }
+ /* Move to the next entry */
+ NextEntry = NextEntry->Flink;
}
/* Check if the global descriptors were used */
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 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");
+ /* This descriptor doesn't cover any part of the range -- nothing to do */
+ NOTHING;
}
else
{
- /* This descriptor covers the head of the allocation */
- //EarlyPrint(L"Descriptor covers the head of the region\r\n");
+ /* This descriptor fully covers the entire allocation */
+ FoundBasePage = Descriptor->BasePage;
+ FoundPageCount = BasePage - FoundBasePage;
+
+ /* This is how many pages we will eat away from the descriptor */
+ RegionSize = FoundPageCount + PageCount;
+
+ /* Update the descriptor to account for the consumed pages */
+ Descriptor->BasePage += RegionSize;
+ Descriptor->PageCount -= RegionSize;
+ if (Descriptor->VirtualPage)
+ {
+ Descriptor->VirtualPage += RegionSize;
+ }
+
+ /* Initialize a descriptor for the start of the region */
+ Descriptor = MmMdInitByteGranularDescriptor(Descriptor->Flags,
+ Descriptor->Type,
+ FoundBasePage,
+ Descriptor->VirtualPage,
+ FoundPageCount);
+ if (!Descriptor)
+ {
+ Status = STATUS_NO_MEMORY;
+ goto Quickie;
+ }
+
+ /* Add it into the list */
+ Status = MmMdAddDescriptorToList(MdList, Descriptor, Flags);
+ if (!NT_SUCCESS(Status))
+ {
+ Status = STATUS_NO_MEMORY;
+ goto Quickie;
+ }
}
}
else
{
/* This descriptor contains the entire allocation */
- //EarlyPrint(L"Descriptor contains the entire region\r\n");
+ RegionSize = FoundEndPage - BasePage;
+ Descriptor->PageCount -= RegionSize;
}
/* Keep going */
*
* So first, figure out if we cover the entire end or not
*/
- if (EndPage > FoundEndPage)
+ if (EndPage < FoundEndPage)
{
/* The allocation goes past the end of this descriptor */
- EndPage = FoundEndPage;
+ FoundEndPage = EndPage;
}
/* This is how many pages we will eat away from the descriptor */
- RegionSize = EndPage - FoundBasePage;
+ RegionSize = FoundEndPage - FoundBasePage;
/* Update the descriptor to account for the consumed pages */
Descriptor->BasePage += RegionSize;
if (!Descriptor->PageCount)
{
/* Remove it */
- //EarlyPrint(L"Entire descriptor consumed\r\n");
MmMdRemoveDescriptorFromList(MdList, Descriptor);
MmMdFreeDescriptor(Descriptor);
return Status;
}
+PBL_MEMORY_DESCRIPTOR
+MmMdFindDescriptorFromMdl (
+ _In_ PBL_MEMORY_DESCRIPTOR_LIST MdList,
+ _In_ ULONG Flags,
+ _In_ ULONGLONG Page
+ )
+{
+ BOOLEAN IsVirtual;
+ PLIST_ENTRY NextEntry, ListHead;
+ PBL_MEMORY_DESCRIPTOR Current;
+ ULONGLONG BasePage;
+
+ /* Assume physical */
+ IsVirtual = FALSE;
+
+ /* Check if the caller wants physical memory */
+ if (!(Flags & BL_MM_REMOVE_VIRTUAL_REGION_FLAG))
+ {
+ /* Check if this is a virtual memory list */
+ if (MdList->Type == BlMdVirtual)
+ {
+ /* We won't find anything */
+ return NULL;
+ }
+ }
+ else if (MdList->Type == BlMdPhysical)
+ {
+ /* Otherwise, caller wants virtual, but this is a physical list */
+ IsVirtual = TRUE;
+ NextEntry = MdList->First->Flink;
+ }
+
+ /* Check if this is a physical search */
+ if (!IsVirtual)
+ {
+ /* Check if we can use the current pointer */
+ NextEntry = MdList->This;
+ if (!NextEntry)
+ {
+ /* We can't -- start at the beginning */
+ NextEntry = MdList->First->Flink;
+ }
+ else
+ {
+ /* If the page is below the current pointer, restart */
+ Current = CONTAINING_RECORD(NextEntry, BL_MEMORY_DESCRIPTOR, ListEntry);
+ if (Page < Current->BasePage)
+ {
+ NextEntry = MdList->First->Flink;
+ }
+ }
+ }
+
+ /* Loop the list of descriptors */
+ ListHead = MdList->First;
+ while (NextEntry != ListHead)
+ {
+ /* Get the current one */
+ Current = CONTAINING_RECORD(NextEntry, BL_MEMORY_DESCRIPTOR, ListEntry);
+
+ /* Check if we are looking for virtual memory */
+ if (IsVirtual)
+ {
+ /* Use the base address */
+ BasePage = Current->VirtualPage;
+ }
+ else
+ {
+ /* Use the page */
+ BasePage = Current->BasePage;
+ }
+
+ /* If this is a virtual descriptor, make sure it has a base address */
+ if ((!(IsVirtual) || (BasePage)) &&
+ (BasePage <= Page) &&
+ (Page < (BasePage + Current->PageCount)))
+ {
+ /* The descriptor fits the page being requested */
+ return Current;
+ }
+
+ /* Try the next one */
+ NextEntry = NextEntry->Flink;
+ }
+
+ /* Nothing found if we're here */
+ return NULL;
+}
+
+PBL_MEMORY_DESCRIPTOR
+MmMdFindDescriptor (
+ _In_ ULONG WhichList,
+ _In_ ULONG Flags,
+ _In_ ULONGLONG Page
+ )
+{
+ PBL_MEMORY_DESCRIPTOR FoundDescriptor;
+
+ /* Check if the caller is looking for mapped, allocated memory */
+ if (WhichList & BL_MM_INCLUDE_MAPPED_ALLOCATED)
+ {
+ /* Find a descriptor in that list */
+ FoundDescriptor = MmMdFindDescriptorFromMdl(&MmMdlMappedAllocated, Flags, Page);
+ if (FoundDescriptor)
+ {
+ /* Got it */
+ return FoundDescriptor;
+ }
+ }
+
+ /* Check if the caller is looking for mapped, unallocated memory */
+ if (WhichList & BL_MM_INCLUDE_MAPPED_UNALLOCATED)
+ {
+ /* Find a descriptor in that list */
+ FoundDescriptor = MmMdFindDescriptorFromMdl(&MmMdlMappedUnallocated, Flags, Page);
+ if (FoundDescriptor)
+ {
+ /* Got it */
+ return FoundDescriptor;
+ }
+ }
+
+ /* Check if the caller is looking for unmapped, allocated memory */
+ if (WhichList & BL_MM_INCLUDE_UNMAPPED_ALLOCATED)
+ {
+ /* Find a descriptor in that list */
+ FoundDescriptor = MmMdFindDescriptorFromMdl(&MmMdlUnmappedAllocated, Flags, Page);
+ if (FoundDescriptor)
+ {
+ /* Got it */
+ return FoundDescriptor;
+ }
+ }
+
+ /* Check if the caller is looking for unmapped, unallocated memory */
+ if (WhichList & BL_MM_INCLUDE_UNMAPPED_UNALLOCATED)
+ {
+ /* Find a descriptor in that list */
+ FoundDescriptor = MmMdFindDescriptorFromMdl(&MmMdlUnmappedUnallocated, Flags, Page);
+ if (FoundDescriptor)
+ {
+ /* Got it */
+ return FoundDescriptor;
+ }
+ }
+
+ /* Check if the caller is looking for reserved, allocated memory */
+ if (WhichList & BL_MM_INCLUDE_RESERVED_ALLOCATED)
+ {
+ /* Find a descriptor in that list */
+ FoundDescriptor = MmMdFindDescriptorFromMdl(&MmMdlReservedAllocated, Flags, Page);
+ if (FoundDescriptor)
+ {
+ /* Got it */
+ return FoundDescriptor;
+ }
+ }
+
+ /* Check if the caller is looking for bad memory */
+ if (WhichList & BL_MM_INCLUDE_BAD_MEMORY)
+ {
+ /* Find a descriptor in that list */
+ FoundDescriptor = MmMdFindDescriptorFromMdl(&MmMdlBadMemory, Flags, Page);
+ if (FoundDescriptor)
+ {
+ /* Got it */
+ return FoundDescriptor;
+ }
+ }
+
+ /* Check if the caller is looking for truncated memory */
+ if (WhichList & BL_MM_INCLUDE_TRUNCATED_MEMORY)
+ {
+ /* Find a descriptor in that list */
+ FoundDescriptor = MmMdFindDescriptorFromMdl(&MmMdlTruncatedMemory, Flags, Page);
+ if (FoundDescriptor)
+ {
+ /* Got it */
+ return FoundDescriptor;
+ }
+ }
+
+ /* Check if the caller is looking for persistent memory */
+ if (WhichList & BL_MM_INCLUDE_PERSISTENT_MEMORY)
+ {
+ /* Find a descriptor in that list */
+ FoundDescriptor = MmMdFindDescriptorFromMdl(&MmMdlPersistentMemory, Flags, Page);
+ if (FoundDescriptor)
+ {
+ /* Got it */
+ return FoundDescriptor;
+ }
+ }
+
+ /* Nothing if we got here */
+ return NULL;
+}
+
BOOLEAN
MmMdFindSatisfyingRegion (
_In_ PBL_MEMORY_DESCRIPTOR Descriptor,
}
/* Bail out if the allocation flags don't match */
- if (((Flags ^ Descriptor->Flags) & (BlMemoryRuntime | BlMemoryReserved | BlMemoryUnknown)))
+ if (((Flags ^ Descriptor->Flags) & (BlMemoryRuntime | BlMemoryBelow1MB | BlMemoryLargePages)))
{
//EfiPrintf(L"Incorrect memory allocation flags\r\n");
return FALSE;