Author: ion
Date: Sun Feb 5 01:54:52 2017
New Revision: 73691
URL:
http://svn.reactos.org/svn/reactos?rev=73691&view=rev
Log:
[BOOTLIB]: Implement BlMmGetMemoryMap.
[BOOTLIB]: Implement MmMdCountList, MmMdInitializeList, MmMdCopyList
[BOOTLIB]: Bugfixes.
Modified:
trunk/reactos/boot/environ/include/bl.h
trunk/reactos/boot/environ/lib/misc/image.c
trunk/reactos/boot/environ/lib/mm/descriptor.c
trunk/reactos/boot/environ/lib/mm/pagealloc.c
Modified: trunk/reactos/boot/environ/include/bl.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/environ/include/bl.h?…
==============================================================================
--- trunk/reactos/boot/environ/include/bl.h [iso-8859-1] (original)
+++ trunk/reactos/boot/environ/include/bl.h [iso-8859-1] Sun Feb 5 01:54:52 2017
@@ -91,6 +91,7 @@
#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 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 @@
InitializeListHead(&List->ListHead);
List->First = &List->ListHead;
List->This = NULL;
+ List->Type = 0;
}
/* INITIALIZATION ROUTINES ***************************************************/
@@ -1961,6 +1978,28 @@
);
/* 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(
@@ -2074,6 +2113,14 @@
NTSTATUS
BlMmRemoveBadMemory (
VOID
+ );
+
+NTSTATUS
+BlMmGetMemoryMap (
+ _In_ PLIST_ENTRY MemoryMap,
+ _In_ PBL_IMAGE_PARAMETERS MemoryParameters,
+ _In_ ULONG WhichTypes,
+ _In_ ULONG Flags
);
/* VIRTUAL MEMORY ROUTINES ***************************************************/
@@ -2558,7 +2605,18 @@
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;
Modified: trunk/reactos/boot/environ/lib/misc/image.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/environ/lib/misc/imag…
==============================================================================
--- trunk/reactos/boot/environ/lib/misc/image.c [iso-8859-1] (original)
+++ trunk/reactos/boot/environ/lib/misc/image.c [iso-8859-1] Sun Feb 5 01:54:52 2017
@@ -1605,17 +1605,6 @@
}
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,
_In_ PBL_APPLICATION_ENTRY AppEntry,
@@ -1628,17 +1617,18 @@
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 @@
return Status;
}
+ EfiPrintf(L"Memory map needs %lx bytes\n", MemoryParameters.BufferSize);
return STATUS_SUCCESS;
}
Modified: trunk/reactos/boot/environ/lib/mm/descriptor.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/environ/lib/mm/descri…
==============================================================================
--- trunk/reactos/boot/environ/lib/mm/descriptor.c [iso-8859-1] (original)
+++ trunk/reactos/boot/environ/lib/mm/descriptor.c [iso-8859-1] Sun Feb 5 01:54:52 2017
@@ -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 @@
}
}
+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 @@
/* 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 @@
MmGlobalMemoryDescriptorCount = RTL_NUMBER_OF(MmStaticMemoryDescriptors);
MmGlobalMemoryDescriptors = MmStaticMemoryDescriptors;
RtlZeroMemory(MmStaticMemoryDescriptors, sizeof(MmStaticMemoryDescriptors));
- MmGlobalMemoryDescriptorsUsed = FALSE;
- }
-}
+ MmGlobalMemoryDescriptorsUsed = 0;
+ }
+}
Modified: trunk/reactos/boot/environ/lib/mm/pagealloc.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/environ/lib/mm/pageal…
==============================================================================
--- trunk/reactos/boot/environ/lib/mm/pagealloc.c [iso-8859-1] (original)
+++ trunk/reactos/boot/environ/lib/mm/pagealloc.c [iso-8859-1] Sun Feb 5 01:54:52 2017
@@ -621,3 +621,282 @@
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;
+}