diff --git a/reactos/boot/environ/include/bl.h b/reactos/boot/environ/include/bl.h index 7d2c93ad93f..cf5d6244ac0 100644 --- a/reactos/boot/environ/include/bl.h +++ b/reactos/boot/environ/include/bl.h @@ -52,6 +52,13 @@ EarlyPrint(_In_ PWCHAR Format, ...); #define BL_CONTEXT_PAGING_ON 1 #define BL_CONTEXT_INTERRUPTS_ON 2 +#define BL_MM_FLAG_USE_FIRMWARE_FOR_MEMORY_MAP_BUFFERS 0x01 +#define BL_MM_FLAG_UNKNOWN 0x02 + +#define BL_LIBRARY_FLAG_REINITIALIZE 0x02 +#define BL_LIBRARY_FLAG_REINITIALIZE_ALL 0x04 +#define BL_LIBRARY_FLAG_INITIALIZATION_COMPLETED 0x20 + /* ENUMERATIONS **************************************************************/ typedef enum _BL_TRANSLATION_TYPE @@ -152,6 +159,19 @@ typedef enum _BL_MEMORY_TYPE BlPalMemory = 0xF000000C, } BL_MEMORY_TYPE; +typedef enum _BL_MEMORY_ATTR +{ + BlMemoryUncached = 1, + BlMemoryWriteCombined = 2, + BlMemoryWriteThrough = 4, + BlMemoryWriteBack = 8, + BlMemoryUncachedExported = 0x10, + BlMemoryWriteProtected = 0x100, + BlMemoryReadProtected = 0x200, + BlMemoryExecuteProtected = 0x400, + BlMemoryRuntime = 0x1000000 +} BL_MEMORY_ATTR; + /* DATA STRUCTURES ***********************************************************/ typedef struct _BL_LIBRARY_PARAMETERS @@ -358,6 +378,14 @@ typedef struct _BL_ARCH_CONTEXT ULONG ContextFlags; } BL_ARCH_CONTEXT, *PBL_ARCH_CONTEXT; +typedef struct _BL_MEMORY_DESCRIPTOR_LIST +{ + LIST_ENTRY ListHead; + PLIST_ENTRY First; + PLIST_ENTRY This; + ULONG Type; +} BL_MEMORY_DESCRIPTOR_LIST, *PBL_MEMORY_DESCRIPTOR_LIST; + /* INLINE ROUTINES ***********************************************************/ FORCEINLINE @@ -382,6 +410,18 @@ BlSetupDefaultParameters ( RtlCopyMemory(LibraryParameters, &DefaultParameters, sizeof(*LibraryParameters)); } +FORCEINLINE +VOID +MmMdInitializeListHead ( + _In_ PBL_MEMORY_DESCRIPTOR_LIST List + ) +{ + /* Initialize the list */ + InitializeListHead(&List->ListHead); + List->First = &List->ListHead; + List->This = NULL; +} + /* INITIALIZATION ROUTINES ***************************************************/ NTSTATUS @@ -461,12 +501,24 @@ MmHaInitialize ( _In_ ULONG HeapAttributes ); -NTSTATUS +VOID MmMdInitialize ( _In_ ULONG Phase, _In_ PBL_LIBRARY_PARAMETERS LibraryParameters ); +NTSTATUS +MmFwGetMemoryMap ( + _Out_ PBL_MEMORY_DESCRIPTOR_LIST MemoryMap, + _In_ ULONG Flags + ); + +VOID +MmMdFreeList( + _In_ PBL_MEMORY_DESCRIPTOR_LIST MdList + ); + +extern ULONG MmDescriptorCallTreeCount; extern ULONG BlpApplicationFlags; extern BL_LIBRARY_PARAMETERS BlpLibraryParameters; extern BL_TRANSLATION_TYPE MmTranslationType; diff --git a/reactos/boot/environ/lib/bootlib.c b/reactos/boot/environ/lib/bootlib.c index e0be4dca872..e15da5ce33f 100644 --- a/reactos/boot/environ/lib/bootlib.c +++ b/reactos/boot/environ/lib/bootlib.c @@ -165,11 +165,11 @@ BlInitializeLibrary( NTSTATUS Status; /* Are we re-initializing the library? */ - if (LibraryParameters->LibraryFlags & 2) + if (LibraryParameters->LibraryFlags & BL_LIBRARY_FLAG_REINITIALIZE) { /* From scratch? */ BlpLibraryParameters = *LibraryParameters; - if (LibraryParameters->LibraryFlags & 4) + if (LibraryParameters->LibraryFlags & BL_LIBRARY_FLAG_REINITIALIZE_ALL) { #if 0 /* Initialize all the core modules again */ diff --git a/reactos/boot/environ/lib/firmware/efi/firmware.c b/reactos/boot/environ/lib/firmware/efi/firmware.c index 2f625599e3b..f29bee7a8a5 100644 --- a/reactos/boot/environ/lib/firmware/efi/firmware.c +++ b/reactos/boot/environ/lib/firmware/efi/firmware.c @@ -151,6 +151,437 @@ EfiSetWatchdogTimer ( return EfiGetNtStatusCode(EfiStatus); } +NTSTATUS +EfiGetMemoryMap ( + _Out_ UINTN* MemoryMapSize, + _Inout_ EFI_MEMORY_DESCRIPTOR *MemoryMap, + _Out_ UINTN* MapKey, + _Out_ UINTN* DescriptorSize, + _Out_ UINTN* DescriptorVersion + ) +{ + BL_ARCH_MODE OldMode; + EFI_STATUS EfiStatus; + + /* Are we in protected mode? */ + OldMode = CurrentExecutionContext->Mode; + if (OldMode != BlRealMode) + { + /* FIXME: Not yet implemented */ + return STATUS_NOT_IMPLEMENTED; + } + + /* Make the EFI call */ + EfiStatus = EfiBS->GetMemoryMap(MemoryMapSize, + MemoryMap, + MapKey, + DescriptorSize, + DescriptorVersion); + + /* Switch back to protected mode if we came from there */ + if (OldMode != BlRealMode) + { + BlpArchSwitchContext(OldMode); + } + + /* Convert the error to an NTSTATUS */ + return EfiGetNtStatusCode(EfiStatus); +} + +NTSTATUS +EfiFreePages ( + _In_ ULONG Pages, + _In_ EFI_PHYSICAL_ADDRESS PhysicalAddress + ) +{ + BL_ARCH_MODE OldMode; + EFI_STATUS EfiStatus; + + /* Are we in protected mode? */ + OldMode = CurrentExecutionContext->Mode; + if (OldMode != BlRealMode) + { + /* FIXME: Not yet implemented */ + return STATUS_NOT_IMPLEMENTED; + } + + /* Make the EFI call */ + EfiStatus = EfiBS->FreePages(PhysicalAddress, Pages); + + /* Switch back to protected mode if we came from there */ + if (OldMode != BlRealMode) + { + BlpArchSwitchContext(OldMode); + } + + /* Convert the error to an NTSTATUS */ + return EfiGetNtStatusCode(EfiStatus); +} + +NTSTATUS +EfiAllocatePages ( + _In_ ULONG Type, + _In_ ULONG Pages, + _Inout_ EFI_PHYSICAL_ADDRESS* Memory + ) +{ + BL_ARCH_MODE OldMode; + EFI_STATUS EfiStatus; + + /* Are we in protected mode? */ + OldMode = CurrentExecutionContext->Mode; + if (OldMode != BlRealMode) + { + /* FIXME: Not yet implemented */ + return STATUS_NOT_IMPLEMENTED; + } + + /* Make the EFI call */ + EfiStatus = EfiBS->AllocatePages(Type, EfiLoaderData, Pages, Memory); + + /* Switch back to protected mode if we came from there */ + if (OldMode != BlRealMode) + { + BlpArchSwitchContext(OldMode); + } + + /* Convert the error to an NTSTATUS */ + return EfiGetNtStatusCode(EfiStatus); +} + +BL_MEMORY_ATTR +MmFwpGetOsAttributeType ( + _In_ ULONGLONG Attribute + ) +{ + BL_MEMORY_ATTR OsAttribute = 0; + + if (Attribute & EFI_MEMORY_UC) + { + OsAttribute = BlMemoryUncached; + } + + if (Attribute & EFI_MEMORY_WC) + { + OsAttribute |= BlMemoryWriteCombined; + } + + if (Attribute & EFI_MEMORY_WT) + { + OsAttribute |= BlMemoryWriteThrough; + } + + if (Attribute & EFI_MEMORY_WB) + { + OsAttribute |= BlMemoryWriteBack; + } + + if (Attribute & EFI_MEMORY_UCE) + { + OsAttribute |= BlMemoryUncachedExported; + } + + if (Attribute & EFI_MEMORY_WP) + { + OsAttribute |= BlMemoryWriteProtected; + } + + if (Attribute & EFI_MEMORY_RP) + { + OsAttribute |= BlMemoryReadProtected; + } + + if (Attribute & EFI_MEMORY_XP) + { + OsAttribute |= BlMemoryExecuteProtected; + } + + if (Attribute & EFI_MEMORY_RUNTIME) + { + OsAttribute |= BlMemoryRuntime; + } + + return OsAttribute; +} + +BL_MEMORY_TYPE +MmFwpGetOsMemoryType ( + _In_ EFI_MEMORY_TYPE MemoryType + ) +{ + BL_MEMORY_TYPE OsType; + + switch (MemoryType) + { + case EfiLoaderCode: + case EfiLoaderData: + OsType = BlLoaderMemory; + break; + + case EfiBootServicesCode: + case EfiBootServicesData: + OsType = BlEfiBootMemory; + break; + + case EfiRuntimeServicesCode: + case EfiRuntimeServicesData: + OsType = BlEfiRuntimeMemory; + break; + + case EfiConventionalMemory: + OsType = BlConventionalMemory; + break; + + case EfiUnusableMemory: + OsType = BlUnusableMemory; + break; + + case EfiACPIReclaimMemory: + OsType = BlAcpiReclaimMemory; + break; + + case EfiACPIMemoryNVS: + OsType = BlAcpiNvsMemory; + break; + + case EfiMemoryMappedIO: + OsType = BlDeviceIoMemory; + break; + + case EfiMemoryMappedIOPortSpace: + OsType = BlDevicePortMemory; + break; + + case EfiPalCode: + OsType = BlPalMemory; + break; + + default: + OsType = BlReservedMemory; + break; + } + + return OsType; +} + +NTSTATUS +MmFwGetMemoryMap ( + _Out_ PBL_MEMORY_DESCRIPTOR_LIST MemoryMap, + _In_ ULONG Flags + ) +{ + BL_LIBRARY_PARAMETERS LibraryParameters = BlpLibraryParameters; + BOOLEAN UseEfiBuffer; + NTSTATUS Status; + ULONGLONG Pages, StartPage, EndPage; + UINTN EfiMemoryMapSize, MapKey, DescriptorSize, DescriptorVersion; + EFI_PHYSICAL_ADDRESS EfiBuffer; + EFI_MEMORY_DESCRIPTOR* EfiMemoryMap; + EFI_STATUS EfiStatus; + BL_ARCH_MODE OldMode; + EFI_MEMORY_DESCRIPTOR EfiDescriptor; + BL_MEMORY_TYPE MemoryType; + + /* Increment the nesting depth */ + MmDescriptorCallTreeCount++; + + /* Determine if we should use EFI or our own allocator at this point */ + UseEfiBuffer = Flags & BL_MM_FLAG_USE_FIRMWARE_FOR_MEMORY_MAP_BUFFERS; + if (!(LibraryParameters.LibraryFlags & BL_LIBRARY_FLAG_INITIALIZATION_COMPLETED)) + { + UseEfiBuffer = TRUE; + } + + /* Bail out if we don't have a list to use */ + if (MemoryMap == NULL) + { + Status = STATUS_INVALID_PARAMETER; + goto Quickie; + } + + /* Free the current descriptor list */ + MmMdFreeList(MemoryMap); + + /* Call into EFI to get the size of the memory map */ + Status = EfiGetMemoryMap(&EfiMemoryMapSize, + NULL, + &MapKey, + &DescriptorSize, + &DescriptorVersion); + if (Status != STATUS_BUFFER_TOO_SMALL) + { + /* This should've failed because our buffer was too small, nothing else */ + EarlyPrint(L"Got strange EFI status for memory map: %lx\n", Status); + if (NT_SUCCESS(Status)) + { + Status = STATUS_UNSUCCESSFUL; + } + goto Quickie; + } + + /* Add 4 more descriptors just in case things changed */ + EfiMemoryMapSize += (4 * DescriptorSize); + Pages = BYTES_TO_PAGES(EfiMemoryMapSize); + EarlyPrint(L"Memory map size: %lx bytes, %d pages\n", EfiMemoryMapSize, Pages); + + /* Should we use EFI to grab memory? */ + if (UseEfiBuffer) + { + /* Yes -- request one more page to align up correctly */ + Pages++; + + /* Grab the required pages */ + Status = EfiAllocatePages(AllocateAnyPages, + Pages, + &EfiBuffer); + if (!NT_SUCCESS(Status)) + { + EarlyPrint(L"EFI allocation failed: %lx\n", Status); + goto Quickie; + } + + /* Free the pages for now */ + Status = EfiFreePages(Pages, EfiBuffer); + if (!NT_SUCCESS(Status)) + { + EfiBuffer = 0; + goto Quickie; + } + + /* Now round to the actual buffer size, removing the extra page */ + EfiBuffer = ROUND_TO_PAGES(EfiBuffer); + Pages--; + Status = EfiAllocatePages(AllocateAddress, + Pages, + &EfiBuffer); + if (!NT_SUCCESS(Status)) + { + EfiBuffer = 0; + goto Quickie; + } + + /* Get the final aligned size and proper buffer */ + EfiMemoryMapSize = EFI_PAGES_TO_SIZE(Pages); + EfiMemoryMap = (EFI_MEMORY_DESCRIPTOR*)(ULONG_PTR)EfiBuffer; + + /* Switch to real mode if not already in it */ + OldMode = CurrentExecutionContext->Mode; + if (OldMode != BlRealMode) + { + BlpArchSwitchContext(BlRealMode); + } + + /* Call EFI to get the memory map */ + EfiStatus = EfiBS->GetMemoryMap(&EfiMemoryMapSize, + EfiMemoryMap, + &MapKey, + &DescriptorSize, + &DescriptorVersion); + + /* Switch back into the previous mode */ + if (OldMode != BlRealMode) + { + BlpArchSwitchContext(OldMode); + } + + /* Convert the result code */ + Status = EfiGetNtStatusCode(EfiStatus); + } + else + { + /* We don't support this path yet */ + Status = STATUS_NOT_IMPLEMENTED; + } + + /* So far so good? */ + if (!NT_SUCCESS(Status)) + { + EarlyPrint(L"Failed to get EFI memory map: %lx\n", Status); + goto Quickie; + } + + /* Did we get correct data from firmware? */ + if (((EfiMemoryMapSize % DescriptorSize)) || + (DescriptorSize < sizeof(EFI_MEMORY_DESCRIPTOR))) + { + EarlyPrint(L"Incorrect descriptor size\n"); + Status = STATUS_UNSUCCESSFUL; + goto Quickie; + } + + /* Loop the EFI memory map */ + EarlyPrint(L"UEFI MEMORY MAP\n\n"); + EarlyPrint(L"TYPE START END ATTRIBUTES\n"); + EarlyPrint(L"===============================================================\n"); + while (EfiMemoryMapSize != 0) + { + /* Check if this is an EFI buffer, but we're not in real mode */ + if ((UseEfiBuffer) && (OldMode != BlRealMode)) + { + BlpArchSwitchContext(BlRealMode); + } + + /* Capture it so we can go back to protected mode (if possible) */ + EfiDescriptor = *EfiMemoryMap; + + /* Go back to protected mode, if we had switched */ + if ((UseEfiBuffer) && (OldMode != BlRealMode)) + { + BlpArchSwitchContext(OldMode); + } + + /* Convert to OS memory type */ + MemoryType = MmFwpGetOsMemoryType(EfiDescriptor.Type); + + /* Round up or round down depending on where the memory is coming from */ + if (MemoryType == BlConventionalMemory) + { + StartPage = BYTES_TO_PAGES(EfiDescriptor.PhysicalStart); + } + else + { + StartPage = EfiDescriptor.PhysicalStart >> PAGE_SHIFT; + } + + /* Calculate the ending page */ + EndPage = StartPage + EfiDescriptor.NumberOfPages; + + /* If after rounding, we ended up with 0 pages, skip this */ + if (StartPage == EndPage) + { + goto LoopAgain; + } + + EarlyPrint(L"%08X 0x%016I64X-0x%016I64X 0x%X\n", + MemoryType, + StartPage << PAGE_SHIFT, + EndPage << PAGE_SHIFT, + EfiDescriptor.Attribute); + + /* Consume this descriptor, and move to the next one */ +LoopAgain: + EfiMemoryMapSize -= DescriptorSize; + EfiMemoryMap = (PVOID)((ULONG_PTR)EfiMemoryMap + DescriptorSize); + } + +Quickie: + /* Free the EFI buffer, if we had one */ + if (EfiBuffer != 0) + { + EfiFreePages(Pages, EfiBuffer); + } + + /* On failure, free the memory map if one was passed in */ + if (!NT_SUCCESS(Status) && (MemoryMap != NULL)) + { + MmMdFreeList(MemoryMap); + } + + /* Decrement the nesting depth and return */ + MmDescriptorCallTreeCount--; + return Status; +} + NTSTATUS BlpFwInitialize ( _In_ ULONG Phase, diff --git a/reactos/boot/environ/lib/mm/descriptor.c b/reactos/boot/environ/lib/mm/descriptor.c index 061606918f5..df59102f589 100644 --- a/reactos/boot/environ/lib/mm/descriptor.c +++ b/reactos/boot/environ/lib/mm/descriptor.c @@ -12,15 +12,128 @@ /* DATA VARIABLES ************************************************************/ +BL_MEMORY_DESCRIPTOR MmStaticMemoryDescriptors[512]; +ULONG MmGlobalMemoryDescriptorCount; +PBL_MEMORY_DESCRIPTOR MmGlobalMemoryDescriptors; +BOOLEAN MmGlobalMemoryDescriptorsUsed; +PBL_MEMORY_DESCRIPTOR MmDynamicMemoryDescriptors; +ULONG MmDynamicMemoryDescriptorCount; /* FUNCTIONS *****************************************************************/ +VOID +MmMdpSwitchToDynamicDescriptors ( + _In_ ULONG Count + ) +{ + EarlyPrint(L"NOT SUPPORTED!!!\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 */ + EarlyPrint(L"Dynamic descriptors not yet supported\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); + } +} + +VOID MmMdInitialize ( _In_ ULONG Phase, _In_ PBL_LIBRARY_PARAMETERS LibraryParameters ) { - EarlyPrint(L"Md init\n"); - return STATUS_NOT_IMPLEMENTED; + /* 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; + } } diff --git a/reactos/boot/environ/lib/mm/pagealloc.c b/reactos/boot/environ/lib/mm/pagealloc.c index e2f0cad8dbb..42dd47557fe 100644 --- a/reactos/boot/environ/lib/mm/pagealloc.c +++ b/reactos/boot/environ/lib/mm/pagealloc.c @@ -12,14 +12,61 @@ /* DATA VARIABLES ************************************************************/ +ULONGLONG PapMaximumPhysicalPage, PapMinimumPhysicalPage; + +ULONG PapMinimumAllocationCount; + +BL_MEMORY_DESCRIPTOR_LIST MmMdlMappedAllocated; +BL_MEMORY_DESCRIPTOR_LIST MmMdlMappedUnallocated; +BL_MEMORY_DESCRIPTOR_LIST MmMdlFwAllocationTracker; +BL_MEMORY_DESCRIPTOR_LIST MmMdlUnmappedAllocated; +BL_MEMORY_DESCRIPTOR_LIST MmMdlUnmappedUnallocated; +BL_MEMORY_DESCRIPTOR_LIST MmMdlReservedAllocated; +BL_MEMORY_DESCRIPTOR_LIST MmMdlBadMemory; +BL_MEMORY_DESCRIPTOR_LIST MmMdlTruncatedMemory; +BL_MEMORY_DESCRIPTOR_LIST MmMdlPersistentMemory; +BL_MEMORY_DESCRIPTOR_LIST MmMdlCompleteBadMemory; +BL_MEMORY_DESCRIPTOR_LIST MmMdlFreeVirtual; +BL_MEMORY_DESCRIPTOR_LIST MmMdlMappingTrackers; /* FUNCTIONS *****************************************************************/ NTSTATUS MmPaInitialize ( - _In_ PBL_MEMORY_DATA MemoryData, - _In_ ULONG MinimumPages + __in PBL_MEMORY_DATA BootMemoryData, + __in ULONG MinimumAllocationCount ) { - return STATUS_NOT_IMPLEMENTED; + NTSTATUS Status; + + /* Initialize physical allocator variables */ + PapMaximumPhysicalPage = 0xFFFFFFFFFFFFF; + PapMinimumAllocationCount = MinimumAllocationCount; + PapMinimumPhysicalPage = 0; + + /* Initialize all the lists */ + MmMdInitializeListHead(&MmMdlMappedAllocated); + MmMdInitializeListHead(&MmMdlMappedUnallocated); + MmMdInitializeListHead(&MmMdlFwAllocationTracker); + MmMdInitializeListHead(&MmMdlUnmappedAllocated); + MmMdInitializeListHead(&MmMdlReservedAllocated); + MmMdInitializeListHead(&MmMdlBadMemory); + MmMdInitializeListHead(&MmMdlTruncatedMemory); + MmMdInitializeListHead(&MmMdlPersistentMemory); + MmMdInitializeListHead(&MmMdlUnmappedUnallocated); + MmMdInitializeListHead(&MmMdlCompleteBadMemory); + + /* Get the BIOS memory map */ + Status = MmFwGetMemoryMap(&MmMdlUnmappedUnallocated, + BL_MM_FLAG_USE_FIRMWARE_FOR_MEMORY_MAP_BUFFERS | + BL_MM_FLAG_UNKNOWN); + if (NT_SUCCESS(Status)) + { + Status = STATUS_NOT_IMPLEMENTED; + } + + /* Return status */ + return Status; } + +