[BOOTMGFW]:
authorAlex Ionescu <aionescu@gmail.com>
Sun, 6 Sep 2015 04:53:49 +0000 (04:53 +0000)
committerAlex Ionescu <aionescu@gmail.com>
Sun, 6 Sep 2015 04:53:49 +0000 (04:53 +0000)
- Start implementing the page allocator. Right now, we are able to obtain & dump the UEFI memory map.

svn path=/trunk/; revision=69045

reactos/boot/environ/include/bl.h
reactos/boot/environ/lib/bootlib.c
reactos/boot/environ/lib/firmware/efi/firmware.c
reactos/boot/environ/lib/mm/descriptor.c
reactos/boot/environ/lib/mm/pagealloc.c

index 7d2c93a..cf5d624 100644 (file)
@@ -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;
index e0be4dc..e15da5c 100644 (file)
@@ -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 */
index 2f62559..f29bee7 100644 (file)
@@ -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,
index 0616069..df59102 100644 (file)
 
 /* 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;
+    }
 }
index e2f0cad..42dd475 100644 (file)
 
 /* 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;
 }
+
+