[BOOTLIB]: Finish implementation of MmMdRemoveRegionFromMdlEx for other straddling...
authorAlex Ionescu <aionescu@gmail.com>
Mon, 6 Feb 2017 22:11:21 +0000 (22:11 +0000)
committerAlex Ionescu <aionescu@gmail.com>
Mon, 6 Feb 2017 22:11:21 +0000 (22:11 +0000)
[BOOTLIB]: Implement Mmx86MapInitStructure and most of Mmx86InitializeMemoryMap.
[BOOTLIB]: Continue implementation of MmDefInitializeTranslation.
[BOOTLIB]: More explicitly mark paths which are not yet implemented for paging mode yet (but only on compilers that don't give compiler errors when trying to use __FUNCTION__.

svn path=/trunk/; revision=73734

reactos/boot/environ/include/bl.h
reactos/boot/environ/lib/mm/descriptor.c
reactos/boot/environ/lib/mm/i386/mmx86.c
reactos/boot/environ/lib/mm/mm.c
reactos/boot/environ/lib/mm/pagealloc.c

index 517a280..b4174d1 100644 (file)
@@ -2191,6 +2191,20 @@ BlMmGetMemoryMap (
 
 /* VIRTUAL MEMORY ROUTINES ***************************************************/
 
+NTSTATUS
+MmMapPhysicalAddress (
+    _Inout_ PPHYSICAL_ADDRESS PhysicalAddress,
+    _Out_ PVOID VirtualAddress,
+    _Inout_ PULONGLONG Size,
+    _In_ ULONG CacheAttributes
+    );
+
+NTSTATUS
+MmUnmapVirtualAddress (
+    _Inout_ PVOID* VirtualAddress,
+    _Inout_ PULONGLONG Size
+    );
+
 NTSTATUS
 BlMmMapPhysicalAddressEx (
     _In_ PVOID* VirtualAddress,
index 4f95a29..d821218 100644 (file)
@@ -698,16 +698,47 @@ MmMdRemoveRegionFromMdlEx (
                 }
                 else
                 {
-                    /* This descriptor covers the head of the allocation @TODO: FIXME */
-                    EfiPrintf(L"FIXME: Descriptor covers the head of the region\r\n");
-                    EfiStall(1000000);
+                    /* This descriptor fully covers the entire allocation */
+                    FoundBasePage = Descriptor->BasePage;
+                    FoundPageCount = BasePage - FoundBasePage;
+
+                    /* This is how many pages we will eat away from the descriptor */
+                    RegionSize = FoundPageCount + PageCount;
+
+                    /* Update the descriptor to account for the consumed pages */
+                    Descriptor->BasePage += RegionSize;
+                    Descriptor->PageCount -= RegionSize;
+                    if (Descriptor->VirtualPage)
+                    {
+                        Descriptor->VirtualPage += RegionSize;
+                    }
+                    
+                    /* Initialize a descriptor for the start of the region */
+                    Descriptor = MmMdInitByteGranularDescriptor(Descriptor->Flags,
+                                                                Descriptor->Type,
+                                                                FoundBasePage,
+                                                                Descriptor->VirtualPage,
+                                                                FoundPageCount);
+                    if (!Descriptor)
+                    {
+                        Status = STATUS_NO_MEMORY;
+                        goto Quickie;
+                    }
+
+                    /* Add it into the list */
+                    Status = MmMdAddDescriptorToList(MdList, Descriptor, Flags);
+                    if (!NT_SUCCESS(Status))
+                    {
+                        Status = STATUS_NO_MEMORY;
+                        goto Quickie;
+                    }
                 }
             }
             else
             {
-                /* This descriptor contains the entire allocation @TODO: FIXME */
-                EfiPrintf(L"FIXME: Descriptor contains the entire region\r\n");
-                EfiStall(1000000);
+                /* This descriptor contains the entire allocation */
+                RegionSize = FoundEndPage - BasePage;
+                Descriptor->PageCount -= RegionSize;
             }
 
             /* Keep going */
@@ -724,14 +755,14 @@ MmMdRemoveRegionFromMdlEx (
              *
              * So first, figure out if we cover the entire end or not
              */
-            if (EndPage > FoundEndPage)
+            if (EndPage < FoundEndPage)
             {
                 /* The allocation goes past the end of this descriptor */
-                EndPage = FoundEndPage;
+                FoundEndPage = EndPage;
             }
 
             /* This is how many pages we will eat away from the descriptor */
-            RegionSize = EndPage - FoundBasePage;
+            RegionSize = FoundEndPage - FoundBasePage;
 
             /* Update the descriptor to account for the consumed pages */
             Descriptor->BasePage += RegionSize;
index 65ecc1c..925c698 100644 (file)
@@ -10,6 +10,7 @@
 
 #include "bl.h"
 #include "bcd.h"
+#include "../../../../../ntoskrnl/include/internal/i386/mm.h"
 
 /* DATA VARIABLES ************************************************************/
 
@@ -20,9 +21,10 @@ BL_ADDRESS_RANGE MmArchKsegAddressRange;
 ULONG_PTR MmArchTopOfApplicationAddressSpace;
 PHYSICAL_ADDRESS Mmx86SelfMapBase;
 ULONG MmDeferredMappingCount;
-PVOID MmPdpt;
-PVOID MmArchReferencePage;
+PMMPTE MmPdpt;
+PULONG MmArchReferencePage;
 PVOID MmPteBase;
+PVOID MmPdeBase;
 ULONG MmArchReferencePageSize;
 
 typedef VOID
@@ -107,8 +109,6 @@ PBL_MM_ZERO_VIRTUAL_ADDRESS_RANGE BlMmZeroVirtualAddressRange;
 
 PBL_MM_FLUSH_TLB Mmx86FlushTlb;
 
-#define PTE_BASE (PVOID)0xC0000000
-
 /* FUNCTIONS *****************************************************************/
 
 VOID
@@ -125,7 +125,7 @@ MmDefRelocateSelfMap (
     VOID
     )
 {
-    if (MmPteBase != PTE_BASE)
+    if (MmPteBase != (PVOID)PTE_BASE)
     {
         EfiPrintf(L"Supposed to relocate CR3\r\n");
     }
@@ -298,6 +298,118 @@ MmDefpTranslateVirtualAddress (
     return FALSE;
 }
 
+NTSTATUS
+Mmx86MapInitStructure (
+    _In_ PVOID VirtualAddress,
+    _In_ ULONGLONG Size,
+    _In_ PHYSICAL_ADDRESS PhysicalAddress
+    )
+{
+    NTSTATUS Status;
+    
+    /* Make a virtual mapping for this physical address */
+    Status = MmMapPhysicalAddress(&PhysicalAddress, &VirtualAddress, &Size, 0);
+    if (!NT_SUCCESS(Status))
+    {
+        return Status;
+    }
+
+    /* Nothing else to do if we're not in paging mode */
+    if (MmTranslationType == BlNone)
+    {
+        return STATUS_SUCCESS;
+    }
+
+    /* Otherwise, remove this region from the list of free virtual ranges */
+    Status = MmMdRemoveRegionFromMdlEx(&MmMdlFreeVirtual,
+                                       BL_MM_REMOVE_VIRTUAL_REGION_FLAG,
+                                       (ULONG_PTR)VirtualAddress >> PAGE_SHIFT,
+                                       Size >> PAGE_SHIFT,
+                                       0);
+    if (!NT_SUCCESS(Status))
+    {
+        /* Unmap the address if that failed */
+        MmUnmapVirtualAddress(&VirtualAddress, &Size);
+    }
+
+    /* Return back to caller */
+    return Status;
+}
+
+NTSTATUS
+Mmx86InitializeMemoryMap (
+    _In_ ULONG Phase,
+    _In_ PBL_MEMORY_DATA MemoryData
+    )
+{
+    ULONG ImageSize;
+    PVOID ImageBase;
+    KDESCRIPTOR Gdt, Idt;
+    NTSTATUS Status;
+    PHYSICAL_ADDRESS PhysicalAddress;
+
+    /* If this is phase 2, map the memory regions */
+    if (Phase != 1)
+    {
+        return Mmx86pMapMemoryRegions(Phase, MemoryData);
+    }
+
+    /* Get the application image base/size */
+    Status = BlGetApplicationBaseAndSize(&ImageBase, &ImageSize);
+    if (!NT_SUCCESS(Status))
+    {
+        return Status;
+    }
+
+    /* Map the image back at the same place */
+    PhysicalAddress.QuadPart = (ULONG_PTR)ImageBase;
+    Status = Mmx86MapInitStructure(ImageBase, ImageSize, PhysicalAddress);
+    if (!NT_SUCCESS(Status))
+    {
+        return Status;
+    }
+
+    /* Map the first 4MB of memory */
+    PhysicalAddress.QuadPart = 0;
+    Status = Mmx86MapInitStructure(NULL, 4 * 1024 * 1024, PhysicalAddress);
+    if (!NT_SUCCESS(Status))
+    {
+        return Status;
+    }
+
+    /* Map the GDT */
+    _sgdt(&Gdt.Limit);
+    PhysicalAddress.QuadPart = Gdt.Base;
+    Status = Mmx86MapInitStructure((PVOID)Gdt.Base, Gdt.Limit + 1, PhysicalAddress);
+    if (!NT_SUCCESS(Status))
+    {
+        return Status;
+    }
+
+    /* Map the IDT */
+    __sidt(&Idt.Limit);
+    PhysicalAddress.QuadPart = Idt.Base;
+    Status = Mmx86MapInitStructure((PVOID)Idt.Base, Idt.Limit + 1, PhysicalAddress);
+    if (!NT_SUCCESS(Status))
+    {
+        return Status;
+    }
+
+    /* Map the reference page */
+    PhysicalAddress.QuadPart = (ULONG_PTR)MmArchReferencePage;
+    Status = Mmx86MapInitStructure(MmArchReferencePage,
+                                   MmArchReferencePageSize,
+                                   PhysicalAddress);
+    if (!NT_SUCCESS(Status))
+    {
+        return Status;
+    }
+
+    /* More to do */
+    EfiPrintf(L"VM more work\r\n");
+    return STATUS_NOT_IMPLEMENTED;
+}
+
 NTSTATUS
 MmDefInitializeTranslation (
     _In_ PBL_MEMORY_DATA MemoryData,
@@ -306,6 +418,7 @@ MmDefInitializeTranslation (
 {
     NTSTATUS Status;
     PHYSICAL_ADDRESS PhysicalAddress;
+    ULONG PdeIndex;
 
     /* Set the global function pointers for memory translation */
     Mmx86TranslateVirtualAddress = MmDefpTranslateVirtualAddress;
@@ -394,12 +507,51 @@ MmDefInitializeTranslation (
 
     /* Zero them out */
     RtlZeroMemory((PVOID)Mmx86SelfMapBase.LowPart, 4 * 1024 * 1024);
-    
     EfiPrintf(L"PDPT at 0x%p Reference Page at 0x%p Self-map at 0x%p\r\n",
               MmPdpt, MmArchReferencePage, Mmx86SelfMapBase.LowPart);
-    Status = STATUS_NOT_IMPLEMENTED;
 
-    //MmPteBase = Mmx86SelfMapBase.LowPart & 0xFFC00000;
+    /* Align PTE base to 4MB region */
+    MmPteBase = (PVOID)(Mmx86SelfMapBase.LowPart & ~0x3FFFFF);
+
+    /* The PDE is the PTE of the PTE base */
+    MmPdeBase = MiAddressToPte(MmPteBase);
+    PdeIndex = MiGetPdeOffset(MmPdeBase);
+    MmPdpt[PdeIndex].u.Hard.Valid = 1;
+    MmPdpt[PdeIndex].u.Hard.Write = 1;
+    MmPdpt[PdeIndex].u.Hard.PageFrameNumber = (ULONG_PTR)MmPdpt >> PAGE_SHIFT;
+    MmArchReferencePage[PdeIndex]++;
+
+    /* Remove PTE_BASE from free virtual memory */
+    Status = MmMdRemoveRegionFromMdlEx(&MmMdlFreeVirtual,
+                                       BL_MM_REMOVE_VIRTUAL_REGION_FLAG,
+                                       PTE_BASE >> PAGE_SHIFT,
+                                       (4 * 1024 * 1024) >> PAGE_SHIFT,
+                                       0);
+    if (!NT_SUCCESS(Status))
+    {
+        goto Quickie;
+    }
+
+    /* Remove HAL_HEAP from free virtual memory */
+    Status = MmMdRemoveRegionFromMdlEx(&MmMdlFreeVirtual,
+                                       BL_MM_REMOVE_VIRTUAL_REGION_FLAG,
+                                       MM_HAL_VA_START >> PAGE_SHIFT,
+                                       (4 * 1024 * 1024) >> PAGE_SHIFT,
+                                       0);
+    if (!NT_SUCCESS(Status))
+    {
+        goto Quickie;
+    }
+
+    /* Initialize the virtual->physical memory mappings */
+    Status = Mmx86InitializeMemoryMap(1, MemoryData);
+    if (!NT_SUCCESS(Status))
+    {
+        goto Quickie;
+    }
+
+    EfiPrintf(L"Ready to turn on motherfucking paging, brah!\r\n");
+    Status = STATUS_NOT_IMPLEMENTED;
 
 Quickie:
     /* Free reference page if we allocated it */
index e574f4d..b3a25dd 100644 (file)
@@ -145,8 +145,11 @@ MmSelectMappingAddress (
         return STATUS_SUCCESS;
     }
 
-    /* Have to allocate physical pages */
-    EfiPrintf(L"VM Todo\r\n");
+    /* We don't support virtual memory yet @TODO */
+#ifdef _MSC_VER // Fuck gcc.
+    EfiPrintf(L"not yet implemented in " __FUNCTION__ "\r\n");
+    EfiStall(1000000);
+#endif
     return STATUS_NOT_IMPLEMENTED;
 }
 
@@ -185,7 +188,11 @@ MmMapPhysicalAddress (
         return STATUS_UNSUCCESSFUL;
     }
 
-    EfiPrintf(L"VM todo\r\n");
+    /* We don't support virtual memory yet @TODO */
+#ifdef _MSC_VER // Fuck gcc.
+    EfiPrintf(L"not yet implemented in " __FUNCTION__ "\r\n");
+    EfiStall(1000000);
+#endif
     return STATUS_NOT_IMPLEMENTED;
 }
 
@@ -273,8 +280,11 @@ BlMmMapPhysicalAddressEx (
     /* Check if we're in physical or virtual mode */
     if (MmTranslationType != BlNone)
     {
-        /* For virtual memory, there's more to do */
-        EfiPrintf(L"VM not supported for mapping\r\n");
+        /* We don't support virtual memory yet @TODO */
+#ifdef _MSC_VER // Fuck gcc.
+        EfiPrintf(L"not yet implemented in " __FUNCTION__ "\r\n");
+        EfiStall(1000000);
+#endif
         Status = STATUS_NOT_IMPLEMENTED;
         goto Quickie;
     }
@@ -306,9 +316,15 @@ MmUnmapVirtualAddress (
         {
             Status = STATUS_SUCCESS;
         }
-
-        /* TODO */
-        Status = STATUS_NOT_IMPLEMENTED;
+        else
+        {
+            /* We don't support virtual memory yet @TODO */
+#ifdef _MSC_VER // Fuck gcc.
+            EfiPrintf(L"not yet implemented in " __FUNCTION__ "\r\n");
+            EfiStall(1000000);
+#endif
+            Status = STATUS_NOT_IMPLEMENTED;
+        }
     }
     else
     {
@@ -340,8 +356,11 @@ BlMmUnmapVirtualAddressEx (
         /* Check if we actually had a virtual mapping active */
         if ((NT_SUCCESS(Status)) && (MmTranslationType != BlNone))
         {
-            /* TODO */
-            EfiPrintf(L"unhandled virtual path\r\n");
+            /* We don't support virtual memory yet @TODO */
+#ifdef _MSC_VER // Fuck gcc.
+            EfiPrintf(L"not yet implemented in " __FUNCTION__ "\r\n");
+            EfiStall(1000000);
+#endif
             Status = STATUS_NOT_IMPLEMENTED;
         }
     }
index 2bb9f02..9912b40 100644 (file)
@@ -188,7 +188,10 @@ MmPapAllocateRegionFromMdl (
     /* Are we allocating from the virtual memory list? */
     if (CurrentList == &MmMdlMappedUnallocated)
     {
-        EfiPrintf(L"Virtual memory not yet supported\r\n");
+#ifdef _MSC_VER // Fuck gcc.
+        EfiPrintf(L"not yet implemented in " __FUNCTION__ "\r\n");
+        EfiStall(1000000);
+#endif
         return STATUS_NOT_IMPLEMENTED;
     }
 
@@ -439,7 +442,11 @@ MmPapAllocatePagesInRange (
     /* What translation mode are we using? */
     if (MmTranslationType != BlNone)
     {
-        /* We don't support virtual memory yet */
+        /* We don't support virtual memory yet @TODO */
+#ifdef _MSC_VER // Fuck gcc.
+        EfiPrintf(L"not yet implemented in " __FUNCTION__ "\r\n");
+        EfiStall(1000000);
+#endif
         Status = STATUS_NOT_IMPLEMENTED;
         goto Exit;
     }