[BOOTLIB]: Implement BlMmGetMemoryMap.
authorAlex Ionescu <aionescu@gmail.com>
Sun, 5 Feb 2017 01:54:52 +0000 (01:54 +0000)
committerAlex Ionescu <aionescu@gmail.com>
Sun, 5 Feb 2017 01:54:52 +0000 (01:54 +0000)
[BOOTLIB]: Implement MmMdCountList, MmMdInitializeList, MmMdCopyList
[BOOTLIB]: Bugfixes.

svn path=/trunk/; revision=73691

reactos/boot/environ/include/bl.h
reactos/boot/environ/lib/misc/image.c
reactos/boot/environ/lib/mm/descriptor.c
reactos/boot/environ/lib/mm/pagealloc.c

index d140b2e..70649db 100644 (file)
@@ -91,6 +91,7 @@ DEFINE_GUID(BadMemoryGuid, 0x54B8275B, 0xD431, 0x473F, 0xAC, 0xFB, 0xE5, 0x36, 0
 #define BL_MM_ADD_DESCRIPTOR_TRUNCATE_FLAG              0x02
 #define BL_MM_ADD_DESCRIPTOR_NEVER_COALESCE_FLAG        0x10
 #define BL_MM_ADD_DESCRIPTOR_NEVER_TRUNCATE_FLAG        0x20
+#define BL_MM_ADD_DESCRIPTOR_ALLOCATE_FLAG              0x1000
 #define BL_MM_ADD_DESCRIPTOR_UPDATE_LIST_POINTER_FLAG   0x2000
 
 #define BL_MM_INCLUDE_MAPPED_ALLOCATED                  0x01
@@ -101,7 +102,22 @@ DEFINE_GUID(BadMemoryGuid, 0x54B8275B, 0xD431, 0x473F, 0xAC, 0xFB, 0xE5, 0x36, 0
 #define BL_MM_INCLUDE_BAD_MEMORY                        0x20
 #define BL_MM_INCLUDE_FIRMWARE_MEMORY                   0x40
 #define BL_MM_INCLUDE_TRUNCATED_MEMORY                  0x80
-#define BL_MM_INCLUDE_PERSISTEND_MEMORY                 0x100
+#define BL_MM_INCLUDE_PERSISTENT_MEMORY                 0x100
+#define BL_MM_INCLUDE_FIRMWARE_MEMORY_2                 0x200
+
+#define BL_MM_INCLUDE_NO_FIRMWARE_MEMORY                (BL_MM_INCLUDE_PERSISTENT_MEMORY | \
+                                                         BL_MM_INCLUDE_TRUNCATED_MEMORY | \
+                                                         BL_MM_INCLUDE_BAD_MEMORY | \
+                                                         BL_MM_INCLUDE_RESERVED_ALLOCATED | \
+                                                         BL_MM_INCLUDE_UNMAPPED_UNALLOCATED | \
+                                                         BL_MM_INCLUDE_UNMAPPED_ALLOCATED | \
+                                                         BL_MM_INCLUDE_MAPPED_UNALLOCATED | \
+                                                         BL_MM_INCLUDE_MAPPED_ALLOCATED)
+C_ASSERT(BL_MM_INCLUDE_NO_FIRMWARE_MEMORY == 0x1BF);
+
+#define BL_MM_INCLUDE_ONLY_FIRMWARE_MEMORY              (BL_MM_INCLUDE_FIRMWARE_MEMORY_2 | \
+                                                         BL_MM_INCLUDE_FIRMWARE_MEMORY)
+C_ASSERT(BL_MM_INCLUDE_ONLY_FIRMWARE_MEMORY == 0x240);
 
 #define BL_MM_REQUEST_DEFAULT_TYPE                      1
 #define BL_MM_REQUEST_TOP_DOWN_TYPE                     2
@@ -1285,6 +1301,7 @@ MmMdInitializeListHead (
     InitializeListHead(&List->ListHead);
     List->First = &List->ListHead;
     List->This = NULL;
+    List->Type = 0;
 }
 
 /* INITIALIZATION ROUTINES ***************************************************/
@@ -1962,6 +1979,28 @@ Archx86TransferTo32BitApplicationAsm (
 
 /* MEMORY DESCRIPTOR ROUTINES ************************************************/
 
+VOID
+MmMdInitializeList (
+    _In_ PBL_MEMORY_DESCRIPTOR_LIST DescriptorList,
+    _In_ ULONG Type,
+    _In_ PLIST_ENTRY ListHead
+    );
+
+NTSTATUS
+MmMdCopyList (
+    _In_ PBL_MEMORY_DESCRIPTOR_LIST DestinationList,
+    _In_ PBL_MEMORY_DESCRIPTOR_LIST SourceList,
+    _In_opt_ PBL_MEMORY_DESCRIPTOR ListDescriptor,
+    _Out_ PULONG ActualCount,
+    _In_ ULONG Count,
+    _In_ ULONG Flags
+    );
+
+ULONG
+MmMdCountList (
+    _In_ PBL_MEMORY_DESCRIPTOR_LIST MdList
+    );
+
 VOID
 MmMdFreeList(
     _In_ PBL_MEMORY_DESCRIPTOR_LIST MdList
@@ -2076,6 +2115,14 @@ BlMmRemoveBadMemory (
     VOID
     );
 
+NTSTATUS
+BlMmGetMemoryMap (
+    _In_ PLIST_ENTRY MemoryMap,
+    _In_ PBL_IMAGE_PARAMETERS MemoryParameters,
+    _In_ ULONG WhichTypes,
+    _In_ ULONG Flags
+    );
+
 /* VIRTUAL MEMORY ROUTINES ***************************************************/
 
 NTSTATUS
@@ -2558,7 +2605,18 @@ extern ULONG ConsoleGraphicalResolutionListSize;
 extern PVOID DspRemoteInputConsole;
 extern PVOID DspLocalInputConsole;
 extern WCHAR BlScratchBuffer[8192];
+extern BL_MEMORY_DESCRIPTOR_LIST MmMdlMappedAllocated;
+extern BL_MEMORY_DESCRIPTOR_LIST MmMdlMappedUnallocated;
+extern BL_MEMORY_DESCRIPTOR_LIST MmMdlFwAllocationTracker;
 extern BL_MEMORY_DESCRIPTOR_LIST MmMdlUnmappedAllocated;
+extern BL_MEMORY_DESCRIPTOR_LIST MmMdlUnmappedUnallocated;
+extern BL_MEMORY_DESCRIPTOR_LIST MmMdlReservedAllocated;
+extern BL_MEMORY_DESCRIPTOR_LIST MmMdlBadMemory;
+extern BL_MEMORY_DESCRIPTOR_LIST MmMdlTruncatedMemory;
+extern BL_MEMORY_DESCRIPTOR_LIST MmMdlPersistentMemory;
+extern BL_MEMORY_DESCRIPTOR_LIST MmMdlCompleteBadMemory;
+extern BL_MEMORY_DESCRIPTOR_LIST MmMdlFreeVirtual;
+extern BL_MEMORY_DESCRIPTOR_LIST MmMdlMappingTrackers;
 extern ULONGLONG BlpTimePerformanceFrequency;
 extern LIST_ENTRY RegisteredFileSystems;
 
index 5af7931..be90108 100644 (file)
@@ -1604,17 +1604,6 @@ BlpPdParseReturnArguments (
     return STATUS_NOT_IMPLEMENTED;
 }
 
-NTSTATUS
-BlMmGetMemoryMap (
-    _In_ PLIST_ENTRY MemoryMap,
-    _In_ PBL_IMAGE_PARAMETERS ImageParameters,
-    _In_ ULONG WhichTypes,
-    _In_ ULONG Flags
-    )
-{
-    return STATUS_SUCCESS;
-}
-
 NTSTATUS
 ImgpInitializeBootApplicationParameters (
     _In_ PBL_IMAGE_PARAMETERS ImageParameters,
@@ -1628,17 +1617,18 @@ ImgpInitializeBootApplicationParameters (
     BL_IMAGE_PARAMETERS MemoryParameters;
     LIST_ENTRY MemoryList;
 
+    /* Get the image headers and validate it */
     Status = RtlImageNtHeaderEx(0, ImageBase, ImageSize, &NtHeaders);
     if (!NT_SUCCESS(Status))
     {
         return Status;
     }
 
+    /* Get the size of the entire non-firmware, allocated, memory map */
     MemoryParameters.BufferSize = 0;
-
     Status = BlMmGetMemoryMap(&MemoryList,
                               &MemoryParameters,
-                              BL_MM_INCLUDE_FIRMWARE_MEMORY |
+                              BL_MM_INCLUDE_PERSISTENT_MEMORY |
                               BL_MM_INCLUDE_MAPPED_ALLOCATED |
                               BL_MM_INCLUDE_MAPPED_UNALLOCATED |
                               BL_MM_INCLUDE_UNMAPPED_ALLOCATED |
@@ -1649,6 +1639,7 @@ ImgpInitializeBootApplicationParameters (
         return Status;
     }
 
+    EfiPrintf(L"Memory map needs %lx bytes\n", MemoryParameters.BufferSize);
     return STATUS_SUCCESS;
 }
 
index d5e0e7e..2c7d859 100644 (file)
@@ -15,7 +15,7 @@
 BL_MEMORY_DESCRIPTOR MmStaticMemoryDescriptors[512];
 ULONG MmGlobalMemoryDescriptorCount;
 PBL_MEMORY_DESCRIPTOR MmGlobalMemoryDescriptors;
-BOOLEAN MmGlobalMemoryDescriptorsUsed;
+ULONG MmGlobalMemoryDescriptorsUsed;
 PBL_MEMORY_DESCRIPTOR MmDynamicMemoryDescriptors;
 ULONG MmDynamicMemoryDescriptorCount;
 
@@ -197,6 +197,152 @@ MmMdpSaveCurrentListPointer (
     }
 }
 
+ULONG
+MmMdCountList (
+    _In_ PBL_MEMORY_DESCRIPTOR_LIST MdList
+    )
+{
+    PLIST_ENTRY First, NextEntry;
+    ULONG Count;
+    
+    /* Iterate the list */
+    for (Count = 0, First = MdList->First, NextEntry = First->Flink;
+         NextEntry != First;
+         NextEntry = NextEntry->Flink, Count++);
+
+    /* Return the count */
+    return Count;
+}
+
+VOID
+MmMdInitializeList (
+    _In_ PBL_MEMORY_DESCRIPTOR_LIST MdList, 
+    _In_ ULONG Type,
+    _In_ PLIST_ENTRY ListHead
+    )
+{
+    /* Check if a list was specified */
+    if (ListHead)
+    {
+        /* Use it */
+        MdList->First = ListHead;
+    }
+    else
+    {
+        /* Otherwise, use the internal, built-in list */
+        InitializeListHead(&MdList->ListHead);
+        MdList->First = &MdList->ListHead;
+    }
+
+    /* Set the type */
+    MdList->Type = Type;
+
+    /* Initialize current iterator to nothing */
+    MdList->This = NULL;
+}
+
+NTSTATUS
+MmMdCopyList (
+    _In_ PBL_MEMORY_DESCRIPTOR_LIST DestinationList, 
+    _In_ PBL_MEMORY_DESCRIPTOR_LIST SourceList,
+    _In_opt_ PBL_MEMORY_DESCRIPTOR ListDescriptor,
+    _Out_ PULONG ActualCount, 
+    _In_ ULONG Count,
+    _In_ ULONG Flags
+    )
+{
+    NTSTATUS Status;
+    PULONG Used;
+    BOOLEAN Finished;
+    PLIST_ENTRY First, NextEntry;
+    PBL_MEMORY_DESCRIPTOR Descriptor;
+
+    /* Both parameters must be present */
+    if (!(DestinationList) || !(SourceList))
+    {
+        return STATUS_INVALID_PARAMETER;
+    }
+
+    /* Assume success */
+    Status = STATUS_SUCCESS;
+
+    /* Check if a descriptor is being used to store the list */
+    if (ListDescriptor)
+    {
+        /* See how big it is */
+        Flags |= BL_MM_ADD_DESCRIPTOR_NEVER_COALESCE_FLAG;
+        Used = ActualCount;
+    }
+    else
+    {
+        /* We are using our internal descriptors instead */
+        Used = &MmGlobalMemoryDescriptorsUsed;
+        ++MmDescriptorCallTreeCount;
+
+        /* Use as many as are available */
+        Count = MmGlobalMemoryDescriptorCount;
+        ListDescriptor = MmGlobalMemoryDescriptors;
+    }
+    
+    /* Never truncate descriptors during a list copy */
+    Flags |= BL_MM_ADD_DESCRIPTOR_NEVER_TRUNCATE_FLAG;
+
+    /* Iterate through the list */
+    First = SourceList->First;
+    NextEntry = First->Flink;
+    if (First->Flink != First)
+    {
+        /* As long as we have success */
+        while (NT_SUCCESS(Status))
+        {
+            /* 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));
+
+            /* Add it to the list we have */
+            Status = MmMdAddDescriptorToList(DestinationList,
+                                             &ListDescriptor[*Used],
+                                             Flags);
+            ++*Used;
+
+            /* Before moving on, check if we're done */
+            Finished = NextEntry->Flink == SourceList->First;
+
+            /* Move to the next entry */
+            NextEntry = NextEntry->Flink;
+
+            if (Finished)
+            {
+                break;
+            }
+        }
+    }
+
+    /* Check if the global descriptors were used */
+    if (ListDescriptor == MmGlobalMemoryDescriptors)
+    {
+        /* Unwind our usage */
+        MmMdFreeGlobalDescriptors();
+        --MmDescriptorCallTreeCount;
+    }
+
+    /* Return back to caller */
+    return Status;
+}
+
 VOID
 MmMdRemoveDescriptorFromList (
     _In_ PBL_MEMORY_DESCRIPTOR_LIST MdList,
@@ -206,7 +352,7 @@ MmMdRemoveDescriptorFromList (
     /* Remove the entry */
     RemoveEntryList(&Entry->ListEntry);
 
-    /*  Check if this was the current link */
+    /* Check if this was the current link */
     if (MdList->This == &Entry->ListEntry)
     {
         /* Remove the current link and set the next one */
@@ -838,6 +984,6 @@ MmMdInitialize (
         MmGlobalMemoryDescriptorCount = RTL_NUMBER_OF(MmStaticMemoryDescriptors);
         MmGlobalMemoryDescriptors = MmStaticMemoryDescriptors;
         RtlZeroMemory(MmStaticMemoryDescriptors, sizeof(MmStaticMemoryDescriptors));
-        MmGlobalMemoryDescriptorsUsed = FALSE;
+        MmGlobalMemoryDescriptorsUsed = 0;
     }
 }
index 2b682a1..886532d 100644 (file)
@@ -621,3 +621,282 @@ BlMmFreePhysicalPages (
     return STATUS_SUCCESS;
     //return MmPapFreePhysicalPages(4, 0, Address);
 }
+
+NTSTATUS
+BlMmGetMemoryMap (
+    _In_ PLIST_ENTRY MemoryMap,
+    _In_ PBL_IMAGE_PARAMETERS MemoryParameters,
+    _In_ ULONG WhichTypes,
+    _In_ ULONG Flags
+    )
+{
+    BL_MEMORY_DESCRIPTOR_LIST FirmwareMdList, FullMdList;
+    BOOLEAN DoFirmware, DoPersistent, DoTruncated, DoBad;
+    BOOLEAN DoReserved, DoUnmapUnalloc, DoUnmapAlloc;
+    BOOLEAN DoMapAlloc, DoMapUnalloc, DoFirmware2;
+    ULONG LoopCount, MdListCount, MdListSize, Used;
+    NTSTATUS Status;
+
+    /* Initialize the firmware list if we use it */
+    MmMdInitializeListHead(&FirmwareMdList);
+
+    /* Make sure we got our input parameters */
+    if (!(MemoryMap) || !(MemoryParameters))
+    {
+        return STATUS_INVALID_PARAMETER;
+    }
+
+    /* Either ask for firmware memory, or don't. Not neither */
+    if ((WhichTypes & ~BL_MM_INCLUDE_NO_FIRMWARE_MEMORY) &&
+        (WhichTypes & ~BL_MM_INCLUDE_ONLY_FIRMWARE_MEMORY))
+    {
+        return STATUS_INVALID_PARAMETER;
+    }
+
+    /* Either ask for firmware memory, or don't. Not both */
+    if ((WhichTypes & BL_MM_INCLUDE_NO_FIRMWARE_MEMORY) &&
+        (WhichTypes & BL_MM_INCLUDE_ONLY_FIRMWARE_MEMORY))
+    {
+        return STATUS_INVALID_PARAMETER;
+    }
+
+    /* Check which types of memory to dump */
+    DoFirmware = WhichTypes & BL_MM_INCLUDE_FIRMWARE_MEMORY;
+    DoPersistent = WhichTypes & BL_MM_INCLUDE_PERSISTENT_MEMORY;
+    DoTruncated = WhichTypes & BL_MM_INCLUDE_TRUNCATED_MEMORY;
+    DoBad = WhichTypes & BL_MM_INCLUDE_BAD_MEMORY;
+    DoReserved = WhichTypes & BL_MM_INCLUDE_RESERVED_ALLOCATED;
+    DoUnmapUnalloc = WhichTypes & BL_MM_INCLUDE_UNMAPPED_UNALLOCATED;
+    DoUnmapAlloc = WhichTypes & BL_MM_INCLUDE_UNMAPPED_ALLOCATED;
+    DoMapAlloc = WhichTypes & BL_MM_INCLUDE_MAPPED_ALLOCATED;
+    DoMapUnalloc = WhichTypes & BL_MM_INCLUDE_MAPPED_UNALLOCATED;
+    DoFirmware2 = WhichTypes & BL_MM_INCLUDE_FIRMWARE_MEMORY_2;
+
+    /* Begin the attempt loop */
+    LoopCount = 0;
+    while (TRUE)
+    {
+        /* Count how many entries we will need */
+        MdListCount = 0;
+        if (DoMapAlloc) MdListCount = MmMdCountList(&MmMdlMappedAllocated);
+        if (DoMapUnalloc) MdListCount += MmMdCountList(&MmMdlMappedUnallocated);
+        if (DoUnmapAlloc) MdListCount += MmMdCountList(&MmMdlUnmappedAllocated);
+        if (DoUnmapUnalloc) MdListCount += MmMdCountList(&MmMdlUnmappedUnallocated);
+        if (DoReserved) MdListCount += MmMdCountList(&MmMdlReservedAllocated);
+        if (DoBad) MdListCount += MmMdCountList(&MmMdlBadMemory);
+        if (DoTruncated) MdListCount += MmMdCountList(&MmMdlTruncatedMemory);
+        if (DoPersistent) MdListCount += MmMdCountList(&MmMdlPersistentMemory);
+
+        /* Plus firmware entries */
+        if (DoFirmware)
+        {
+            /* Free the previous entries, if any */
+            MmMdFreeList(&FirmwareMdList);
+
+            /* Get the firmware map */
+            Status = MmFwGetMemoryMap(&FirmwareMdList, 2);
+            if (!NT_SUCCESS(Status))
+            {
+                goto Quickie;
+            }
+
+            /* We overwrite, since this type is exclusive */
+            MdListCount = MmMdCountList(&FirmwareMdList);
+        }
+
+        /* Plus firmware entries-2 */
+        if (DoFirmware2)
+        {
+            /* Free the previous entries, if any */
+            MmMdFreeList(&FirmwareMdList);
+
+            /* Get the firmware map */
+            Status = MmFwGetMemoryMap(&FirmwareMdList, 0);
+            if (!NT_SUCCESS(Status))
+            {
+                goto Quickie;
+            }
+
+            /* We overwrite, since this type is exclusive */
+            MdListCount = MmMdCountList(&FirmwareMdList);
+        }
+
+        /* If there's no descriptors, we're done */
+        if (!MdListCount)
+        {
+            Status = STATUS_SUCCESS;
+            goto Quickie;
+        }
+
+        /* Check if the buffer we have is big enough */
+        if (MemoryParameters->BufferSize >=
+            (sizeof(BL_MEMORY_DESCRIPTOR) * MdListCount))
+        {
+            break;
+        }
+
+        /* It's not, allocate it, with a slack of 4 extra descriptors */
+        MdListSize = sizeof(BL_MEMORY_DESCRIPTOR) * (MdListCount + 4);
+
+        /* Except if we weren't asked to */
+        if (!(Flags & BL_MM_ADD_DESCRIPTOR_ALLOCATE_FLAG))
+        {
+            MemoryParameters->BufferSize = MdListSize;
+            Status = STATUS_BUFFER_TOO_SMALL;
+            goto Quickie;
+        }
+
+        /* Has it been less than 4 times we've tried this? */
+        if (++LoopCount <= 4)
+        {
+            /* Free the previous attempt, if any */
+            if (MemoryParameters->BufferSize)
+            {
+                BlMmFreeHeap(MemoryParameters->Buffer);
+            }
+
+            /* Allocate a new buffer */
+            MemoryParameters->BufferSize = MdListSize;
+            MemoryParameters->Buffer = BlMmAllocateHeap(MdListSize);
+            if (MemoryParameters->Buffer)
+            {
+                /* Try again */
+                continue;
+            }
+        }
+
+        /* If we got here, we're out of memory after 4 attempts */
+        Status = STATUS_NO_MEMORY;
+        goto Quickie;
+    }
+
+    /* We should have a buffer by now... */
+    if (MemoryParameters->Buffer)
+    {
+        /* Zero it out */
+        RtlZeroMemory(MemoryParameters->Buffer,
+                      MdListCount * sizeof(BL_MEMORY_DESCRIPTOR));
+    }
+
+    /* Initialize our list of descriptors */
+    MmMdInitializeList(&FullMdList, 0, MemoryMap);
+    Used = 0;
+
+    /* Handle mapped, allocated */
+    if (DoMapAlloc)
+    {
+        Status = MmMdCopyList(&FullMdList,
+                              &MmMdlMappedAllocated,
+                              MemoryParameters->Buffer,
+                              &Used,
+                              MdListCount,
+                              Flags);
+    }
+
+    /* Handle mapped, unallocated */
+    if (DoMapUnalloc)
+    {
+        Status = MmMdCopyList(&FullMdList,
+                              &MmMdlMappedUnallocated,
+                              MemoryParameters->Buffer,
+                              &Used,
+                              MdListCount,
+                              Flags);
+    }
+
+    /* Handle unmapped, allocated */
+    if (DoUnmapAlloc)
+    {
+        Status = MmMdCopyList(&FullMdList,
+                              &MmMdlUnmappedAllocated,
+                              MemoryParameters->Buffer,
+                              &Used,
+                              MdListCount,
+                              Flags);
+    }
+
+    /* Handle unmapped, unallocated */
+    if (DoUnmapUnalloc)
+    {
+        Status = MmMdCopyList(&FullMdList,
+                              &MmMdlUnmappedUnallocated,
+                              MemoryParameters->Buffer,
+                              &Used,
+                              MdListCount,
+                              Flags);
+    }
+
+    /* Handle reserved, allocated */
+    if (DoReserved)
+    {
+        Status = MmMdCopyList(&FullMdList,
+                              &MmMdlReservedAllocated,
+                              MemoryParameters->Buffer,
+                              &Used,
+                              MdListCount,
+                              Flags);
+    }
+
+    /* Handle bad */
+    if (DoBad)
+    {
+        Status = MmMdCopyList(&FullMdList,
+                              &MmMdlBadMemory,
+                              MemoryParameters->Buffer,
+                              &Used,
+                              MdListCount,
+                              Flags);
+    }
+
+    /* Handle truncated */
+    if (DoTruncated)
+    {
+        Status = MmMdCopyList(&FullMdList,
+                              &MmMdlTruncatedMemory,
+                              MemoryParameters->Buffer,
+                              &Used,
+                              MdListCount,
+                              Flags);
+    }
+
+    /* Handle persistent */
+    if (DoPersistent)
+    {
+        Status = MmMdCopyList(&FullMdList,
+                              &MmMdlPersistentMemory,
+                              MemoryParameters->Buffer,
+                              &Used,
+                              MdListCount,
+                              Flags);
+    }
+
+    /* Handle firmware */
+    if (DoFirmware)
+    {
+        Status = MmMdCopyList(&FullMdList,
+                              &FirmwareMdList,
+                              MemoryParameters->Buffer,
+                              &Used,
+                              MdListCount,
+                              Flags);
+    }
+
+    /* Handle firmware2 */
+    if (DoFirmware2)
+    {
+        Status = MmMdCopyList(&FullMdList,
+                              &FirmwareMdList,
+                              MemoryParameters->Buffer,
+                              &Used,
+                              MdListCount,
+                              Flags);
+    }
+
+    /* Add up the final size */
+    Status = RtlULongLongToULong(Used * sizeof(BL_MEMORY_DESCRIPTOR),
+                                 &MemoryParameters->ActualSize);
+
+Quickie:
+    MmMdFreeList(&FirmwareMdList);
+    return Status;
+}