[BOOTLIB]: Don't use PTE_BASE/PDE_BASE in bootlib. Use MmPteBase and MmPdeBase instead.
authorAlex Ionescu <aionescu@gmail.com>
Tue, 7 Feb 2017 01:35:11 +0000 (01:35 +0000)
committerAlex Ionescu <aionescu@gmail.com>
Tue, 7 Feb 2017 01:35:11 +0000 (01:35 +0000)
[BOOTLIB]: Implement MmDefpMapPhysicalAddress, MmDefpTranslateVirtualAddress. Fix definition of Mmx86MapPhysicalAddress.

svn path=/trunk/; revision=73739

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

index e26ef18..7eeb1ff 100644 (file)
@@ -1446,7 +1446,6 @@ MmFwGetMemoryMap (
     /* Add 4 more descriptors just in case things changed */
     EfiMemoryMapSize += (4 * DescriptorSize);
     Pages = BYTES_TO_PAGES(EfiMemoryMapSize);
-    EfiPrintf(L"Memory map size: %lx bytes, %d pages\r\n", EfiMemoryMapSize, Pages);
 
     /* Should we use EFI to grab memory? */
     if (UseEfiBuffer)
index 5e1a68b..630e9b2 100644 (file)
 
 #include "bl.h"
 #include "bcd.h"
-#include "../../../../../ntoskrnl/include/internal/i386/mm.h"
+
+#define PTE_BASE                0xC0000000
+
+//
+// Specific PDE/PTE macros to be used inside the boot library environment
+//
+#define MiAddressToPte(x)       ((PMMPTE)(((((ULONG)(x)) >> 12) << 2) + (ULONG_PTR)MmPteBase))
+#define MiAddressToPde(x)       ((PMMPDE)(((((ULONG)(x)) >> 22) << 2) + (ULONG_PTR)MmPdeBase))
+#define MiAddressToPteOffset(x) ((((ULONG)(x)) << 10) >> 22)
+#define MiAddressToPdeOffset(x) (((ULONG)(x)) / (1024 * PAGE_SIZE))
 
 /* DATA VARIABLES ************************************************************/
 
@@ -81,7 +90,7 @@ typedef NTSTATUS
 
 typedef NTSTATUS
 (*PBL_MM_MAP_PHYSICAL_ADDRESS) (
-    _In_ PPHYSICAL_ADDRESS PhysicalAddress,
+    _In_ PHYSICAL_ADDRESS PhysicalAddress,
     _Out_ PVOID VirtualAddress,
     _In_ ULONG Size,
     _In_ ULONG CacheAttributes
@@ -111,6 +120,16 @@ PBL_MM_FLUSH_TLB Mmx86FlushTlb;
 
 /* FUNCTIONS *****************************************************************/
 
+BOOLEAN
+BlMmIsTranslationEnabled (
+    VOID
+    )
+{
+    /* Return if paging is on */
+    return ((CurrentExecutionContext) &&
+            (CurrentExecutionContext->Mode & BL_CONTEXT_PAGING_ON));
+}
+
 VOID
 MmArchNullFunction (
     VOID
@@ -277,14 +296,152 @@ MmDefpRemapVirtualAddress (
 
 NTSTATUS
 MmDefpMapPhysicalAddress (
-    _In_ PPHYSICAL_ADDRESS PhysicalAddress,
-    _Out_ PVOID VirtualAddress,
+    _In_ PHYSICAL_ADDRESS PhysicalAddress,
+    _In_ PVOID VirtualAddress,
     _In_ ULONG Size,
     _In_ ULONG CacheAttributes
     )
 {
-    EfiPrintf(L"No map\r\n");
-    return STATUS_NOT_IMPLEMENTED;
+    BOOLEAN Enabled;
+    ULONG i, PageCount, PdeOffset;
+    ULONGLONG CurrentAddress;
+    PMMPDE Pde;
+    PMMPTE Pte;
+    PMMPTE PageTable;
+    PHYSICAL_ADDRESS PageTableAddress;
+    NTSTATUS Status;
+
+    /* Check if paging is on yet */
+    Enabled = BlMmIsTranslationEnabled();
+
+    /* Get the physical address aligned */
+    CurrentAddress = (PhysicalAddress.QuadPart >> PAGE_SHIFT) << PAGE_SHIFT;
+
+    /* Get the number of pages and loop through each one */
+    PageCount = Size >> PAGE_SHIFT;
+    for (i = 0; i < PageCount; i++)
+    {
+        /* Check if translation already exists for this page */
+        if (Mmx86TranslateVirtualAddress(VirtualAddress, NULL, NULL))
+        {
+            /* Ignore it and move to the next one */
+            VirtualAddress = (PVOID)((ULONG_PTR)VirtualAddress + PAGE_SIZE);
+            CurrentAddress += PAGE_SIZE;
+            continue;
+        }
+
+        /* Get the PDE offset */
+        PdeOffset = MiAddressToPdeOffset(VirtualAddress);
+
+        /* Check if paging is actually turned on */
+        if (Enabled)
+        {
+            /* Get the PDE entry using the self-map */
+            Pde = MiAddressToPde(VirtualAddress);
+        }
+        else
+        {
+            /* Get it using our physical mappings */
+            Pde = &MmPdpt[PdeOffset];
+            PageTable = (PMMPDE)(Pde->u.Hard.PageFrameNumber << PAGE_SHIFT);
+        }
+
+        /* Check if we don't yet have a PDE */
+        if (!Pde->u.Hard.Valid)
+        {
+            /* Allocate a page table */
+            Status = MmPapAllocatePhysicalPagesInRange(&PageTableAddress,
+                                                       BlLoaderPageDirectory,
+                                                       1,
+                                                       0,
+                                                       0,
+                                                       &MmMdlUnmappedAllocated,
+                                                       0,
+                                                       0);
+            if (!NT_SUCCESS(Status))
+            {
+                return STATUS_NO_MEMORY;
+            }
+
+            /* This is our page table */
+            PageTable = (PVOID)(ULONG_PTR)PageTableAddress.QuadPart;
+
+            /* Build the PDE for it */
+            Pde->u.Hard.PageFrameNumber = PageTableAddress.QuadPart >> PAGE_SHIFT;
+            Pde->u.Hard.Write = 1;
+            Pde->u.Hard.CacheDisable = 1;
+            Pde->u.Hard.WriteThrough = 1;
+            Pde->u.Hard.Valid = 1;
+
+            /* Check if paging is enabled */
+            if (Enabled)
+            {
+                /* Then actually, get the page table's virtual address */
+                PageTable = (PVOID)PAGE_ROUND_DOWN(MiAddressToPte(VirtualAddress));
+
+                /* Flush the TLB */
+                Mmx86FlushTlb();
+            }
+
+            /* Zero out the page table */
+            RtlZeroMemory(PageTable, PAGE_SIZE);
+
+            /* Reset caching attributes now */
+            Pde->u.Hard.CacheDisable = 0;
+            Pde->u.Hard.WriteThrough = 0;
+
+            /* Check for paging again */
+            if (Enabled)
+            {
+                /* Flush the TLB entry for the page table only */
+                Mmx86FlushTlbEntry(PageTable);
+            }
+        }
+
+        /* Add a reference to this page table */
+        MmArchReferencePage[PdeOffset]++;
+
+        /* Check if a physical address was given */
+        if (PhysicalAddress.QuadPart != -1)
+        {
+            /* Check if paging is turned on */
+            if (Enabled)
+            {
+                /* Get the PTE using the self-map */
+                Pte = MiAddressToPte(VirtualAddress);
+            }
+            else
+            {
+                /* Get the PTE using physical addressing */
+                Pte = &PageTable[MiAddressToPteOffset(VirtualAddress)];
+            }
+
+            /* Build a valid PTE for it */
+            Pte->u.Hard.PageFrameNumber = CurrentAddress >> PAGE_SHIFT;
+            Pte->u.Hard.Write = 1;
+            Pte->u.Hard.Valid = 1;
+
+            /* Check if this is uncached */
+            if (CacheAttributes == BlMemoryUncached)
+            {
+                /* Set the flags */
+                Pte->u.Hard.CacheDisable = 1;
+                Pte->u.Hard.WriteThrough = 1;
+            }
+            else if (CacheAttributes == BlMemoryWriteThrough)
+            {
+                /* It's write-through, set the flag */
+                Pte->u.Hard.WriteThrough = 1;
+            }
+        }
+
+        /* Move to the next physical/virtual address */
+        VirtualAddress = (PVOID)((ULONG_PTR)VirtualAddress + PAGE_SIZE);
+        CurrentAddress += PAGE_SIZE;
+    }
+
+    /* All done! */
+    return STATUS_SUCCESS;
 }
 
 BOOLEAN
@@ -294,8 +451,75 @@ MmDefpTranslateVirtualAddress (
     _Out_opt_ PULONG CacheAttributes
     )
 {
-    EfiPrintf(L"No translate\r\n");
-    return FALSE;
+    PMMPDE Pde;
+    PMMPTE Pte;
+    PMMPTE PageTable;
+    BOOLEAN Enabled;
+
+    /* Is there no page directory yet? */
+    if (!MmPdpt)
+    {
+        return FALSE;
+    }
+
+    /* Is paging enabled? */
+    Enabled = BlMmIsTranslationEnabled();
+
+    /* Check if paging is actually turned on */
+    if (Enabled)
+    {
+        /* Get the PDE entry using the self-map */
+        Pde = MiAddressToPde(VirtualAddress);
+    }
+    else
+    {
+        /* Get it using our physical mappings */
+        Pde = &MmPdpt[MiAddressToPdeOffset(VirtualAddress)];
+    }
+
+    /* Is the PDE valid? */
+    if (!Pde->u.Hard.Valid)
+    {
+        return FALSE;
+    }
+
+    /* Check if paging is turned on */
+    if (Enabled)
+    {
+        /* Get the PTE using the self-map */
+        Pte = MiAddressToPte(VirtualAddress);
+    }
+    else
+    {
+        /* Get the PTE using physical addressing */
+        PageTable = (PMMPTE)(Pde->u.Hard.PageFrameNumber << PAGE_SHIFT);
+        Pte = &PageTable[MiAddressToPteOffset(VirtualAddress)];
+    }
+
+    /* Is the PTE valid? */
+    if (!Pte->u.Hard.Valid)
+    {
+        return FALSE;
+    }
+
+    /* Does caller want the physical address?  */
+    if (PhysicalAddress)
+    {
+        /* Return it */
+        PhysicalAddress->QuadPart = (Pte->u.Hard.PageFrameNumber << PAGE_SHIFT) +
+                                     BYTE_OFFSET(VirtualAddress);
+    }
+
+    /* Does caller want cache attributes? */
+    if (CacheAttributes)
+    {
+        /* Not yet -- lie and say it's cached */
+        EfiPrintf(L"Cache checking not yet enabled\r\n");
+        *CacheAttributes = BlMemoryWriteBack;
+    }
+
+    /* It exists! */
+    return TRUE;
 }
 
 NTSTATUS
@@ -323,16 +547,6 @@ MmSelectMappingAddress (
     return STATUS_NOT_IMPLEMENTED;
 }
 
-BOOLEAN
-BlMmIsTranslationEnabled (
-    VOID
-    )
-{
-    /* Return if paging is on */
-    return ((CurrentExecutionContext) &&
-            (CurrentExecutionContext->Mode & BL_CONTEXT_PAGING_ON));
-}
-
 NTSTATUS
 MmMapPhysicalAddress (
     _Inout_ PPHYSICAL_ADDRESS PhysicalAddressPtr,
@@ -419,7 +633,7 @@ MmMapPhysicalAddress (
 
     /* Aactually do the mapping */
     TranslatedAddress.QuadPart = PhysicalAddress;
-    Status = Mmx86MapPhysicalAddress(&TranslatedAddress,
+    Status = Mmx86MapPhysicalAddress(TranslatedAddress,
                                      VirtualAddress,
                                      Size,
                                      CacheAttributes);
@@ -661,7 +875,7 @@ MmDefInitializeTranslation (
 
     /* The PDE is the PTE of the PTE base */
     MmPdeBase = MiAddressToPte(MmPteBase);
-    PdeIndex = MiGetPdeOffset(MmPdeBase);
+    PdeIndex = MiAddressToPdeOffset(MmPdeBase);
     MmPdpt[PdeIndex].u.Hard.Valid = 1;
     MmPdpt[PdeIndex].u.Hard.Write = 1;
     MmPdpt[PdeIndex].u.Hard.PageFrameNumber = (ULONG_PTR)MmPdpt >> PAGE_SHIFT;
index 688ed8f..832750b 100644 (file)
@@ -128,70 +128,6 @@ BlMmRemoveBadMemory (
     return STATUS_SUCCESS;
 }
 
-NTSTATUS
-MmSelectMappingAddress (
-    _Out_ PVOID* MappingAddress,
-    _In_ ULONGLONG Size,
-    _In_ ULONG AllocationAttributes,
-    _In_ ULONG Flags,
-    _In_ PHYSICAL_ADDRESS PhysicalAddress
-    )
-{
-    /* Are we in physical mode? */
-    if (MmTranslationType == BlNone)
-    {
-        /* Just return the physical address as the mapping address */
-        *MappingAddress = (PVOID)PhysicalAddress.LowPart;
-        return STATUS_SUCCESS;
-    }
-
-    /* We don't support virtual memory yet @TODO */
-    EfiPrintf(L"not yet implemented in %S\r\n", __FUNCTION__);
-    EfiStall(1000000);
-    return STATUS_NOT_IMPLEMENTED;
-}
-
-NTSTATUS
-MmMapPhysicalAddress (
-    _Inout_ PPHYSICAL_ADDRESS PhysicalAddress,
-    _Out_ PVOID VirtualAddress,
-    _Inout_ PULONGLONG Size,
-    _In_ ULONG CacheAttributes
-    )
-{
-    ULONGLONG MappingSize;
-
-    /* Fail if any parameters are missing */
-    if (!(PhysicalAddress) || !(VirtualAddress) || !(Size))
-    {
-        return STATUS_INVALID_PARAMETER;
-    }
-
-    /* Fail if the size is over 32-bits */
-    MappingSize = *Size;
-    if (MappingSize > 0xFFFFFFFF)
-    {
-        return STATUS_INVALID_PARAMETER;
-    }
-
-    /* Nothing to do if we're in physical mode */
-    if (MmTranslationType == BlNone)
-    {
-        return STATUS_SUCCESS;
-    }
-
-    /* Can't use virtual memory in real mode */
-    if (CurrentExecutionContext->Mode == BlRealMode)
-    {
-        return STATUS_UNSUCCESSFUL;
-    }
-
-    /* We don't support virtual memory yet @TODO */
-    EfiPrintf(L"not yet implemented in %S\r\n", __FUNCTION__);
-    EfiStall(1000000);
-    return STATUS_NOT_IMPLEMENTED;
-}
-
 NTSTATUS
 BlMmMapPhysicalAddressEx (
     _In_ PVOID* VirtualAddress,
index 5644f11..16675b2 100644 (file)
@@ -545,6 +545,7 @@ MmPaInitialize (
         while (ExistingDescriptors != 0)
         {
             /* Remove this region from our free memory MDL */
+            //EfiPrintf(L"Handling existing descriptor: %llx %llx\r\n", Descriptor->BasePage, Descriptor->PageCount);
             Status = MmMdRemoveRegionFromMdlEx(&MmMdlUnmappedUnallocated,
                                                BL_MM_REMOVE_PHYSICAL_REGION_FLAG,
                                                Descriptor->BasePage,
@@ -743,7 +744,7 @@ MmPapFreePhysicalPages (
         Flags |= BL_MM_ADD_DESCRIPTOR_NEVER_COALESCE_FLAG;
     }
 
-    /* Check if the entire allocation is being free*/
+    /* Check if the entire allocation is being free*/
     if (PageCount == Descriptor->PageCount)
     {
         /* Remove the descriptor from the allocated list */