[BOOTLIB]: Implement MmFwGetMemoryMap when virtual memory is being enabled.
authorAlex Ionescu <aionescu@gmail.com>
Tue, 7 Feb 2017 04:26:21 +0000 (04:26 +0000)
committerAlex Ionescu <aionescu@gmail.com>
Tue, 7 Feb 2017 04:26:21 +0000 (04:26 +0000)
[BOOTLIB]: Implement MmPapAllocatePagesInRange when virtual memory is being enabled.
What's left now is implementing extension for the PA allocator when VM is enabled.

svn path=/trunk/; revision=73742

reactos/boot/environ/lib/firmware/efi/firmware.c
reactos/boot/environ/lib/mm/i386/mmx86.c
reactos/boot/environ/lib/mm/pagealloc.c

index 7eeb1ff..a064124 100644 (file)
@@ -1402,6 +1402,7 @@ MmFwGetMemoryMap (
     BL_MEMORY_TYPE MemoryType;
     PBL_MEMORY_DESCRIPTOR Descriptor;
     BL_MEMORY_ATTR Attribute;
+    PVOID LibraryBuffer;
 
     /* Initialize EFI memory map attributes */
     EfiMemoryMapSize = MapKey = DescriptorSize = DescriptorVersion = 0;
@@ -1435,7 +1436,6 @@ MmFwGetMemoryMap (
     if (Status != STATUS_BUFFER_TOO_SMALL)
     {
         /* This should've failed because our buffer was too small, nothing else */
-        EfiPrintf(L"Got strange EFI status for memory map: %lx\r\n", Status);
         if (NT_SUCCESS(Status))
         {
             Status = STATUS_UNSUCCESSFUL;
@@ -1512,8 +1512,30 @@ MmFwGetMemoryMap (
     }
     else
     {
-        /* We don't support this path yet */
-        Status = STATUS_NOT_IMPLEMENTED;
+        /* Round the map to pages */
+        Pages = BYTES_TO_PAGES(EfiMemoryMapSize);
+
+        /* Allocate a large enough buffer */
+        Status = MmPapAllocatePagesInRange(&LibraryBuffer,
+                                           BlLoaderData,
+                                           Pages,
+                                           0,
+                                           0,
+                                           0,
+                                           0);
+        if (!NT_SUCCESS(Status))
+        {
+            EfiPrintf(L"Failed to allocate mapped VM for EFI map: %lx\r\n", Status);
+            goto Quickie;
+        }
+
+        /* Call EFI to get the memory map */
+        EfiMemoryMap = LibraryBuffer;
+        Status = EfiGetMemoryMap(&EfiMemoryMapSize,
+                                 LibraryBuffer,
+                                 &MapKey,
+                                 &DescriptorSize,
+                                 &DescriptorVersion);
     }
 
     /* So far so good? */
@@ -1788,6 +1810,12 @@ Quickie:
         EfiFreePages(Pages, EfiBuffer);
     }
 
+    /* Free the library-allocated buffer, if we had one */
+    if (LibraryBuffer != 0)
+    {
+        MmPapFreePages(LibraryBuffer, BL_MM_INCLUDE_MAPPED_ALLOCATED);
+    }
+
     /* On failure, free the memory map if one was passed in */
     if (!NT_SUCCESS(Status) && (MemoryMap != NULL))
     {
index 51c6273..4d36f98 100644 (file)
@@ -680,9 +680,10 @@ Mmx86pMapMemoryRegions (
     BL_MEMORY_DESCRIPTOR_LIST FirmwareMdl;
     PLIST_ENTRY Head, NextEntry;
 
-    /* In phase 1 we don't initialize deferred mappings*/
+    /* Check which phase this is */
     if (Phase == 1)
     {
+        /* In phase 1 we don't initialize deferred mappings */
         DoDeferred = FALSE;
     }
     else
@@ -693,6 +694,7 @@ Mmx86pMapMemoryRegions (
             return STATUS_SUCCESS;
         }
 
+        /* We'll do deferred descriptors in phase 2 */
         DoDeferred = TRUE;
     }
 
index 16675b2..5066c0b 100644 (file)
@@ -95,7 +95,7 @@ MmPapAllocateRegionFromMdl (
     ULONGLONG LocalEndPage, FoundEndPage, LocalVirtualEndPage;
 
     /* Check if any parameters were not passed in correctly */
-    if ( !(CurrentList) || !(Request) || (!(NewList) && !(Descriptor)))
+    if (!(CurrentList) || !(Request) || (!(NewList) && !(Descriptor)))
     {
         return STATUS_INVALID_PARAMETER;
     }
@@ -298,8 +298,15 @@ MmPaAllocatePages (
         return Status;
     }
 
-    /* Nope, we have to hunt for it elsewhere */
-    EfiPrintf(L"TODO\r\n");
+    /* Are we failing due to some attributes? */
+    if (Request->Flags & BlMemoryValidAllocationAttributeMask)
+    {
+        EfiPrintf(L"not yet implemented in %S\r\n", __FUNCTION__);
+        EfiStall(1000000);
+        return STATUS_NOT_IMPLEMENTED;
+    }
+
+    /* Nope, just fail the entire call */
     return Status;
 }
 
@@ -424,10 +431,16 @@ MmPapAllocatePagesInRange (
 {
     NTSTATUS Status;
     PHYSICAL_ADDRESS BaseAddress;
+    BL_PA_REQUEST Request;
+    PBL_MEMORY_DESCRIPTOR_LIST List;
+    BL_MEMORY_DESCRIPTOR Descriptor;
 
     /* Increment nesting depth */
     ++MmDescriptorCallTreeCount;
 
+    /* Default list */
+    List = &MmMdlMappedAllocated;
+
     /* Check for missing parameters or invalid range */
     if (!(PhysicalAddress) ||
         !(Pages) ||
@@ -440,11 +453,93 @@ MmPapAllocatePagesInRange (
     /* What translation mode are we using? */
     if (MmTranslationType != BlNone)
     {
-        /* We don't support virtual memory yet @TODO */
-        EfiPrintf(L"not yet implemented in %S\r\n", __FUNCTION__);
-        EfiStall(1000000);
-        Status = STATUS_NOT_IMPLEMENTED;
-        goto Exit;
+        /* Use 1 page alignment if none was requested */
+        if (!Alignment)
+        {
+            Alignment = 1;
+        }
+
+        /* Check if we got a range */
+        if (Range)
+        {
+            /* We don't support virtual memory yet @TODO */
+            EfiPrintf(L"not yet implemented in %S\r\n", __FUNCTION__);
+            EfiStall(1000000);
+            Status = STATUS_NOT_IMPLEMENTED;
+            goto Exit;
+        }
+        else
+        {
+            Request.BaseRange.Minimum = PapMinimumPhysicalPage;
+            Request.BaseRange.Maximum = (4 * 1024 * 1024) >> PAGE_SHIFT;
+        }
+
+        /* Check if a fixed allocation was requested */
+        if (Attributes & BlMemoryFixed)
+        {
+            /* We don't support virtual memory yet @TODO */
+            EfiPrintf(L"not yet implemented in %S\r\n", __FUNCTION__);
+            EfiStall(1000000);
+            Status = STATUS_NOT_IMPLEMENTED;
+            goto Exit;
+        }
+        else
+        {
+            /* Check if non-fixed was specifically requested */
+            if (Attributes & BlMemoryNonFixed)
+            {
+                /* We don't support virtual memory yet @TODO */
+                EfiPrintf(L"not yet implemented in %S\r\n", __FUNCTION__);
+                EfiStall(1000000);
+                Status = STATUS_NOT_IMPLEMENTED;
+                goto Exit;
+            }
+
+            /* Set the virtual address range */
+            Request.VirtualRange.Minimum = 0;
+            Request.VirtualRange.Maximum = (4 * 1024 * 1024) >> PAGE_SHIFT;
+        }
+
+        /* Check what type of allocation was requested */
+        if (Type)
+        {
+            /* Save it */
+            Request.Type = Type;
+
+            /* If it was invalid, set the default */
+            if (Type & ~(BL_MM_REQUEST_DEFAULT_TYPE | BL_MM_REQUEST_TOP_DOWN_TYPE))
+            {
+                Request.Type = BL_MM_REQUEST_DEFAULT_TYPE;
+            }
+        }
+        else
+        {
+            /* Set the default */
+            Request.Type = BL_MM_REQUEST_DEFAULT_TYPE;
+        }
+
+        /* Fill out the request of the request */
+        Request.Flags = Attributes;
+        Request.Alignment = Alignment;
+        Request.Pages = Pages;
+
+        /* Try to allocate the pages */
+        Status = MmPaAllocatePages(List,
+                                   &Descriptor,
+                                   &MmMdlMappedUnallocated,
+                                   &Request,
+                                   MemoryType);
+        if (!NT_SUCCESS(Status))
+        {
+            /* We don't support virtual memory yet @TODO */
+            EfiPrintf(L"Need to extend PA allocator\r\n");
+            EfiStall(1000000);
+            Status = STATUS_NOT_IMPLEMENTED;
+            goto Exit;
+        }
+
+        /* Return the allocated address */
+        *PhysicalAddress = (PVOID)((ULONG_PTR)Descriptor.VirtualPage << PAGE_SHIFT);
     }
     else
     {