Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers...
[reactos.git] / reactos / boot / environ / lib / mm / i386 / mmx86.c
diff --git a/reactos/boot/environ/lib/mm/i386/mmx86.c b/reactos/boot/environ/lib/mm/i386/mmx86.c
deleted file mode 100644 (file)
index 38e52df..0000000
+++ /dev/null
@@ -1,1218 +0,0 @@
-/*
-* COPYRIGHT:       See COPYING.ARM in the top level directory
-* PROJECT:         ReactOS UEFI Boot Library
-* FILE:            boot/environ/lib/mm/i386/mmx86.c
-* PURPOSE:         Boot Library Memory Manager x86-Specific Code
-* PROGRAMMER:      Alex Ionescu (alex.ionescu@reactos.org)
-*/
-
-/* INCLUDES ******************************************************************/
-
-#include "bl.h"
-#include "bcd.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 ************************************************************/
-
-ULONG_PTR MmArchKsegBase;
-ULONG_PTR MmArchKsegBias;
-ULONG MmArchLargePageSize;
-BL_ADDRESS_RANGE MmArchKsegAddressRange;
-ULONG_PTR MmArchTopOfApplicationAddressSpace;
-PHYSICAL_ADDRESS Mmx86SelfMapBase;
-ULONG MmDeferredMappingCount;
-PMMPTE MmPdpt;
-PULONG MmArchReferencePage;
-PVOID MmPteBase;
-PVOID MmPdeBase;
-ULONG MmArchReferencePageSize;
-
-typedef VOID
-(*PBL_MM_FLUSH_TLB) (
-    VOID
-    );
-
-typedef VOID
-(*PBL_MM_RELOCATE_SELF_MAP) (
-    VOID
-    );
-
-typedef NTSTATUS
-(*PBL_MM_MOVE_VIRTUAL_ADDRESS_RANGE) (
-    _In_ PVOID DestinationAddress,
-    _In_ PVOID SourceAddress,
-    _In_ ULONGLONG Size
-    );
-
-typedef NTSTATUS
-(*PBL_MM_ZERO_VIRTUAL_ADDRESS_RANGE) (
-    _In_ PVOID DestinationAddress,
-    _In_ ULONGLONG Size
-    );
-
-typedef VOID
-(*PBL_MM_DESTROY_SELF_MAP) (
-    VOID
-    );
-
-typedef VOID
-(*PBL_MM_FLUSH_TLB_ENTRY) (
-    _In_ PVOID VirtualAddress
-    );
-
-typedef VOID
-(*PBL_MM_FLUSH_TLB) (
-    VOID
-    );
-
-typedef NTSTATUS
-(*PBL_MM_UNMAP_VIRTUAL_ADDRESS) (
-    _In_ PVOID VirtualAddress,
-    _In_ ULONG Size
-    );
-
-typedef NTSTATUS
-(*PBL_MM_REMAP_VIRTUAL_ADDRESS) (
-    _In_ PPHYSICAL_ADDRESS PhysicalAddress,
-    _Out_ PVOID VirtualAddress,
-    _In_ ULONG Size,
-    _In_ ULONG CacheAttributes
-    );
-
-typedef NTSTATUS
-(*PBL_MM_MAP_PHYSICAL_ADDRESS) (
-    _In_ PHYSICAL_ADDRESS PhysicalAddress,
-    _Out_ PVOID VirtualAddress,
-    _In_ ULONG Size,
-    _In_ ULONG CacheAttributes
-    );
-
-typedef BOOLEAN
-(*PBL_MM_TRANSLATE_VIRTUAL_ADDRESS) (
-    _In_ PVOID VirtualAddress,
-    _Out_ PPHYSICAL_ADDRESS PhysicalAddress,
-    _Out_opt_ PULONG CacheAttributes
-    );
-
-PBL_MM_TRANSLATE_VIRTUAL_ADDRESS Mmx86TranslateVirtualAddress;
-PBL_MM_MAP_PHYSICAL_ADDRESS Mmx86MapPhysicalAddress;
-PBL_MM_REMAP_VIRTUAL_ADDRESS Mmx86RemapVirtualAddress;
-PBL_MM_UNMAP_VIRTUAL_ADDRESS Mmx86UnmapVirtualAddress;
-PBL_MM_FLUSH_TLB Mmx86FlushTlb;
-PBL_MM_FLUSH_TLB_ENTRY Mmx86FlushTlbEntry;
-PBL_MM_DESTROY_SELF_MAP Mmx86DestroySelfMap;
-
-PBL_MM_RELOCATE_SELF_MAP BlMmRelocateSelfMap;
-PBL_MM_FLUSH_TLB BlMmFlushTlb;
-PBL_MM_MOVE_VIRTUAL_ADDRESS_RANGE BlMmMoveVirtualAddressRange;
-PBL_MM_ZERO_VIRTUAL_ADDRESS_RANGE BlMmZeroVirtualAddressRange;
-
-PBL_MM_FLUSH_TLB Mmx86FlushTlb;
-
-/* FUNCTIONS *****************************************************************/
-
-BOOLEAN
-BlMmIsTranslationEnabled (
-    VOID
-    )
-{
-    /* Return if paging is on */
-    return ((CurrentExecutionContext) &&
-            (CurrentExecutionContext->ContextFlags & BL_CONTEXT_PAGING_ON));
-}
-
-VOID
-MmArchNullFunction (
-    VOID
-    )
-{
-    /* Nothing to do */
-    return;
-}
-
-VOID
-MmDefRelocateSelfMap (
-    VOID
-    )
-{
-    if (MmPteBase != (PVOID)PTE_BASE)
-    {
-        EfiPrintf(L"Supposed to relocate CR3\r\n");
-    }
-}
-
-NTSTATUS
-MmDefMoveVirtualAddressRange (
-    _In_ PVOID DestinationAddress,
-    _In_ PVOID SourceAddress,
-    _In_ ULONGLONG Size
-    )
-{
-    EfiPrintf(L"Supposed to move shit\r\n");
-    return STATUS_NOT_IMPLEMENTED;
-}
-
-NTSTATUS
-MmDefZeroVirtualAddressRange (
-    _In_ PVOID DestinationAddress,
-    _In_ ULONGLONG Size
-    )
-{
-    EfiPrintf(L"Supposed to zero shit\r\n");
-    return STATUS_NOT_IMPLEMENTED;
-}
-
-BOOLEAN
-MmArchTranslateVirtualAddress (
-    _In_ PVOID VirtualAddress, 
-    _Out_opt_ PPHYSICAL_ADDRESS PhysicalAddress, 
-    _Out_opt_ PULONG CachingFlags
-    )
-{
-    PBL_MEMORY_DESCRIPTOR Descriptor;
-
-    /* Check if paging is on */
-    if ((CurrentExecutionContext) &&
-        (CurrentExecutionContext->ContextFlags & BL_CONTEXT_PAGING_ON))
-    {
-        /* Yes -- we have to translate this from virtual */
-        return Mmx86TranslateVirtualAddress(VirtualAddress,
-                                            PhysicalAddress,
-                                            CachingFlags);
-    }
-
-    /* Look in all descriptors except truncated and firmware ones */
-    Descriptor = MmMdFindDescriptor(BL_MM_INCLUDE_NO_FIRMWARE_MEMORY &
-                                    ~BL_MM_INCLUDE_TRUNCATED_MEMORY,
-                                    BL_MM_REMOVE_PHYSICAL_REGION_FLAG,
-                                    (ULONG_PTR)VirtualAddress >> PAGE_SHIFT);
-
-    /* Return the virtual address as the physical address */
-    if (PhysicalAddress)
-    {
-        PhysicalAddress->HighPart = 0;
-        PhysicalAddress->LowPart = (ULONG_PTR)VirtualAddress;
-    }
-
-    /* There's no caching on physical memory */
-    if (CachingFlags)
-    {
-        *CachingFlags = 0;
-    }
-
-    /* Success is if we found a descriptor */
-    return Descriptor != NULL;
-}
-
-VOID
-MmDefpDestroySelfMap (
-    VOID
-    )
-{
-    EfiPrintf(L"No destroy\r\n");
-}
-
-VOID
-MmDefpFlushTlbEntry (
-    _In_ PVOID VirtualAddress
-    )
-{
-    /* Flush the TLB */
-    __invlpg(VirtualAddress);
-}
-
-VOID
-MmDefpFlushTlb (
-    VOID
-    )
-{
-    /* Flush the TLB */
-    __writecr3(__readcr3());
-}
-
-NTSTATUS
-MmDefpUnmapVirtualAddress (
-    _In_ PVOID VirtualAddress,
-    _In_ ULONG Size
-    )
-{
-    EfiPrintf(L"No unmap\r\n");
-    return STATUS_NOT_IMPLEMENTED;
-}
-
-NTSTATUS
-MmDefpRemapVirtualAddress (
-    _In_ PPHYSICAL_ADDRESS PhysicalAddress,
-    _Out_ PVOID VirtualAddress,
-    _In_ ULONG Size,
-    _In_ ULONG CacheAttributes
-    )
-{
-    EfiPrintf(L"No remap\r\n");
-    return STATUS_NOT_IMPLEMENTED;
-}
-
-NTSTATUS
-MmDefpMapPhysicalAddress (
-    _In_ PHYSICAL_ADDRESS PhysicalAddress,
-    _In_ PVOID VirtualAddress,
-    _In_ ULONG Size,
-    _In_ ULONG CacheAttributes
-    )
-{
-    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))
-            {
-                EfiPrintf(L"PDE alloc failed!\r\n");
-                EfiStall(1000000);
-                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
-MmDefpTranslateVirtualAddress (
-    _In_ PVOID VirtualAddress,
-    _Out_ PPHYSICAL_ADDRESS PhysicalAddress,
-    _Out_opt_ PULONG CacheAttributes
-    )
-{
-    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
-MmMapPhysicalAddress (
-    _Inout_ PPHYSICAL_ADDRESS PhysicalAddressPtr,
-    _Inout_ PVOID* VirtualAddressPtr,
-    _Inout_ PULONGLONG SizePtr,
-    _In_ ULONG CacheAttributes
-    )
-{
-    ULONGLONG Size;
-    ULONGLONG PhysicalAddress;
-    PVOID VirtualAddress;
-    PHYSICAL_ADDRESS TranslatedAddress;
-    ULONG_PTR CurrentAddress, VirtualAddressEnd;
-    NTSTATUS Status;
-
-    /* Fail if any parameters are missing */
-    if (!(PhysicalAddressPtr) || !(VirtualAddressPtr) || !(SizePtr))
-    {
-        return STATUS_INVALID_PARAMETER;
-    }
-
-    /* Fail if the size is over 32-bits */
-    Size = *SizePtr;
-    if (Size > 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;
-    }
-
-    /* Capture the current virtual and physical addresses */
-    VirtualAddress = *VirtualAddressPtr;
-    PhysicalAddress = PhysicalAddressPtr->QuadPart;
-
-    /* Check if a physical address was requested */
-    if (PhysicalAddress != 0xFFFFFFFF)
-    {
-        /* Round down the base addresses */
-        PhysicalAddress = PAGE_ROUND_DOWN(PhysicalAddress);
-        VirtualAddress = (PVOID)PAGE_ROUND_DOWN(VirtualAddress);
-
-        /* Round up the size */
-        Size = ROUND_TO_PAGES(PhysicalAddressPtr->QuadPart -
-                              PhysicalAddress +
-                              Size);
-
-        /* Loop every virtual page */
-        CurrentAddress = (ULONG_PTR)VirtualAddress;
-        VirtualAddressEnd = CurrentAddress + Size - 1;
-        while (CurrentAddress < VirtualAddressEnd)
-        {
-            /* Get the physical page of this virtual page */
-            if (MmArchTranslateVirtualAddress((PVOID)CurrentAddress,
-                                              &TranslatedAddress,
-                                              &CacheAttributes))
-            {
-                /* Make sure the physical page of the virtual page, matches our page */
-                if (TranslatedAddress.QuadPart !=
-                    (PhysicalAddress +
-                     (CurrentAddress - (ULONG_PTR)VirtualAddress)))
-                {
-                    /* There is an existing virtual mapping for a different address */
-                    EfiPrintf(L"Existing mapping exists: %lx vs %lx\r\n",
-                              TranslatedAddress.QuadPart,
-                              PhysicalAddress + (CurrentAddress - (ULONG_PTR)VirtualAddress));
-                    EfiStall(10000000);
-                    return STATUS_INVALID_PARAMETER;
-                }
-            }
-
-            /* Try the next one */
-            CurrentAddress += PAGE_SIZE;
-        }
-    }
-
-    /* Aactually do the mapping */
-    TranslatedAddress.QuadPart = PhysicalAddress;
-    Status = Mmx86MapPhysicalAddress(TranslatedAddress,
-                                     VirtualAddress,
-                                     Size,
-                                     CacheAttributes);
-    if (!NT_SUCCESS(Status))
-    {
-        EfiPrintf(L"Failed to map!: %lx\r\n", Status);
-        EfiStall(1000000);
-        return Status;
-    }
-
-    /* Return aligned/fixed up output parameters */
-    PhysicalAddressPtr->QuadPart = PhysicalAddress;
-    *VirtualAddressPtr = VirtualAddress;
-    *SizePtr = Size;
-    
-    /* Flush the TLB if paging is enabled */
-    if (BlMmIsTranslationEnabled())
-    {
-        Mmx86FlushTlb();
-    }
-
-    /* All good! */
-    return STATUS_SUCCESS;
-}
-
-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;
-}
-
-VOID
-MmMdDbgDumpList (
-    _In_ PBL_MEMORY_DESCRIPTOR_LIST DescriptorList,
-    _In_opt_ ULONG MaxCount
-    )
-{
-    ULONGLONG EndPage, VirtualEndPage;
-    PBL_MEMORY_DESCRIPTOR MemoryDescriptor;
-    PLIST_ENTRY NextEntry;
-
-    /* If no maximum was provided, use essentially infinite */
-    if (MaxCount == 0)
-    {
-        MaxCount = 0xFFFFFFFF;
-    }
-
-    /* Loop the list as long as there's entries and max isn't reached */
-    NextEntry = DescriptorList->First->Flink;
-    while ((NextEntry != DescriptorList->First) && (MaxCount--))
-    {
-        /* Get the descriptor */
-        MemoryDescriptor = CONTAINING_RECORD(NextEntry,
-                                             BL_MEMORY_DESCRIPTOR,
-                                             ListEntry);
-
-        /* Get the descriptor end page, and see if it was virtually mapepd */
-        EndPage = MemoryDescriptor->BasePage + MemoryDescriptor->PageCount;
-        if (MemoryDescriptor->VirtualPage)
-        {
-            /* Get the virtual end page too, then */
-            VirtualEndPage = MemoryDescriptor->VirtualPage +
-                             MemoryDescriptor->PageCount;
-        }
-        else
-        {
-            VirtualEndPage = 0;
-        }
-
-        /* Print out the descriptor, physical range, virtual range, and type */
-        EfiPrintf(L"%p - [%08llx-%08llx @ %08llx-%08llx]:%x\r\n",
-                    MemoryDescriptor,
-                    MemoryDescriptor->BasePage << PAGE_SHIFT,
-                    (EndPage << PAGE_SHIFT) - 1,
-                    MemoryDescriptor->VirtualPage << PAGE_SHIFT,
-                    VirtualEndPage ? (VirtualEndPage << PAGE_SHIFT) - 1 : 0,
-                    (ULONG)MemoryDescriptor->Type);
-
-        /* Next entry */
-        NextEntry = NextEntry->Flink;
-    }
-}
-
-NTSTATUS
-Mmx86pMapMemoryRegions (
-    _In_ ULONG Phase,
-    _In_ PBL_MEMORY_DATA MemoryData
-    )
-{
-    BOOLEAN DoDeferred;
-    ULONG DescriptorCount;
-    PBL_MEMORY_DESCRIPTOR Descriptor;
-    ULONG FinalOffset;
-    PHYSICAL_ADDRESS PhysicalAddress;
-    ULONGLONG Size;
-    NTSTATUS Status;
-    PVOID VirtualAddress;
-    BL_MEMORY_DESCRIPTOR_LIST FirmwareMdl;
-    PLIST_ENTRY Head, NextEntry;
-
-    /* Check which phase this is */
-    if (Phase == 1)
-    {
-        /* In phase 1 we don't initialize deferred mappings */
-        DoDeferred = FALSE;
-    }
-    else
-    {
-        /* Don't do anything if there's nothing to initialize */
-        if (!MmDeferredMappingCount)
-        {
-            return STATUS_SUCCESS;
-        }
-
-        /* We'll do deferred descriptors in phase 2 */
-        DoDeferred = TRUE;
-    }
-
-    /*
-    * Because BL supports cross x86-x64 application launches and a LIST_ENTRY
-    * is of variable size, care must be taken here to ensure that we see a
-    * consistent view of descriptors. BL uses some offset magic to figure out
-    * where the data actually starts, since everything is ULONGLONG past the
-    * LIST_ENTRY itself
-    */
-    FinalOffset = MemoryData->MdListOffset + MemoryData->DescriptorOffset;
-    Descriptor = (PBL_MEMORY_DESCRIPTOR)((ULONG_PTR)MemoryData + FinalOffset -
-                                         FIELD_OFFSET(BL_MEMORY_DESCRIPTOR, BasePage));
-
-    /* Scan all of them */
-    DescriptorCount = MemoryData->DescriptorCount;
-    while (DescriptorCount != 0)
-    {
-        /* Ignore application data */
-        if (Descriptor->Type != BlApplicationData)
-        {
-            /* If this is a ramdisk, do it in phase 2 */
-            if ((Descriptor->Type == BlLoaderRamDisk) == DoDeferred)
-            {
-                /* Get the current physical address and size */
-                PhysicalAddress.QuadPart = Descriptor->BasePage << PAGE_SHIFT;
-                Size = Descriptor->PageCount << PAGE_SHIFT;
-
-                /* Check if it was already mapped */
-                if (Descriptor->VirtualPage)
-                {
-                    /* Use the existing address */
-                    VirtualAddress = (PVOID)(ULONG_PTR)(Descriptor->VirtualPage << PAGE_SHIFT);
-                }
-                else
-                {
-                    /* Use the physical address */
-                    VirtualAddress = (PVOID)(ULONG_PTR)PhysicalAddress.QuadPart;
-                }
-
-                /* Crete the mapping */
-                Status = Mmx86MapInitStructure(VirtualAddress,
-                                               Size,
-                                               PhysicalAddress);
-                if (!NT_SUCCESS(Status))
-                {
-                    return Status;
-                }
-            }
-
-            /* Check if we're in phase 1 and deferring RAM disk */
-            if ((Phase == 1) && (Descriptor->Type == BlLoaderRamDisk))
-            {
-                MmDeferredMappingCount++;
-            }
-        }
-
-        /* Move on to the next descriptor */
-        DescriptorCount--;
-        Descriptor = (PBL_MEMORY_DESCRIPTOR)((ULONG_PTR)Descriptor + MemoryData->DescriptorSize);
-    }
-
-    /* In phase 1, also do UEFI mappings */
-    if (Phase != 2)
-    {
-        /* Get the memory map */
-        MmMdInitializeListHead(&FirmwareMdl);
-        Status = MmFwGetMemoryMap(&FirmwareMdl, BL_MM_FLAG_REQUEST_COALESCING);
-        if (!NT_SUCCESS(Status))
-        {
-            return Status;
-        }
-
-        /* Iterate over it */
-        Head = FirmwareMdl.First;
-        NextEntry = Head->Flink;
-        while (NextEntry != Head)
-        {
-            /* Check if this is a UEFI-related descriptor, unless it's the self-map page */
-            Descriptor = CONTAINING_RECORD(NextEntry, BL_MEMORY_DESCRIPTOR, ListEntry);
-            if (((Descriptor->Type == BlEfiBootMemory) ||
-                 (Descriptor->Type == BlEfiRuntimeCodeMemory) ||
-                 (Descriptor->Type == BlEfiRuntimeDataMemory) || // WINBUG?
-                 (Descriptor->Type == BlLoaderMemory)) &&
-                ((Descriptor->BasePage << PAGE_SHIFT) != Mmx86SelfMapBase.QuadPart))
-            {
-                /* Identity-map it */
-                PhysicalAddress.QuadPart = Descriptor->BasePage << PAGE_SHIFT;
-                Status = Mmx86MapInitStructure((PVOID)((ULONG_PTR)Descriptor->BasePage << PAGE_SHIFT),
-                                               Descriptor->PageCount << PAGE_SHIFT,
-                                               PhysicalAddress);
-                if (!NT_SUCCESS(Status))
-                {
-                    return Status;
-                }
-            }
-
-            /* Move to the next descriptor */
-            NextEntry = NextEntry->Flink;
-        }
-
-        /* Reset */
-        NextEntry = Head->Flink;
-        while (NextEntry != Head)
-        {
-            /* Get the descriptor */
-            Descriptor = CONTAINING_RECORD(NextEntry, BL_MEMORY_DESCRIPTOR, ListEntry);
-
-            /* Skip to the next entry before we free */
-            NextEntry = NextEntry->Flink;
-
-            /* Remove and free it */
-            MmMdRemoveDescriptorFromList(&FirmwareMdl, Descriptor);
-            MmMdFreeDescriptor(Descriptor);
-        }
-    }
-
-    /* All library mappings identity mapped now */
-    return STATUS_SUCCESS;
-}
-
-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 */
-    return Mmx86pMapMemoryRegions(Phase, MemoryData);
-}
-
-NTSTATUS
-MmDefInitializeTranslation (
-    _In_ PBL_MEMORY_DATA MemoryData,
-    _In_ BL_TRANSLATION_TYPE TranslationType
-    )
-{
-    NTSTATUS Status;
-    PHYSICAL_ADDRESS PhysicalAddress;
-    ULONG PdeIndex;
-
-    /* Set the global function pointers for memory translation */
-    Mmx86TranslateVirtualAddress = MmDefpTranslateVirtualAddress;
-    Mmx86MapPhysicalAddress = MmDefpMapPhysicalAddress;
-    Mmx86UnmapVirtualAddress = MmDefpUnmapVirtualAddress;
-    Mmx86RemapVirtualAddress = MmDefpRemapVirtualAddress;
-    Mmx86FlushTlb = MmDefpFlushTlb;
-    Mmx86FlushTlbEntry = MmDefpFlushTlbEntry;
-    Mmx86DestroySelfMap = MmDefpDestroySelfMap;
-
-    /* Check what mode we're currently in */
-    if (TranslationType == BlVirtual)
-    {
-        EfiPrintf(L"Virtual->Virtual not yet supported\r\n");
-        return STATUS_NOT_IMPLEMENTED;
-    }
-    else if (TranslationType != BlNone)
-    {
-        /* Not even Windows supports PAE->Virtual downgrade */
-        return STATUS_NOT_IMPLEMENTED;
-    }
-
-    /* The None->Virtual case */
-    MmPdpt = NULL;
-    Mmx86SelfMapBase.QuadPart = 0;
-    MmArchReferencePage = NULL;
-
-    /* Truncate all memory above 4GB so that we don't use it */
-    Status = MmPaTruncateMemory(0x100000);
-    if (!NT_SUCCESS(Status))
-    {
-        goto Failure;
-    }
-
-    /* Allocate a page directory */
-    Status = MmPapAllocatePhysicalPagesInRange(&PhysicalAddress,
-                                               BlLoaderPageDirectory,
-                                               1,
-                                               0,
-                                               0,
-                                               &MmMdlUnmappedAllocated,
-                                               0,
-                                               0);
-    if (!NT_SUCCESS(Status))
-    {
-        goto Failure;
-    }
-
-    /* Zero out the page directory */
-    MmPdpt = (PVOID)PhysicalAddress.LowPart;
-    RtlZeroMemory(MmPdpt, PAGE_SIZE);
-
-    /* Set the page size */
-    MmArchReferencePageSize = PAGE_SIZE;
-
-    /* Allocate the self-map page */
-    Status = MmPapAllocatePhysicalPagesInRange(&PhysicalAddress,
-                                               BlLoaderReferencePage,
-                                               1,
-                                               0,
-                                               0,
-                                               &MmMdlUnmappedAllocated,
-                                               0,
-                                               0);
-    if (!NT_SUCCESS(Status))
-    {
-        goto Failure;
-    }
-
-    /* Set the reference page */
-    MmArchReferencePage = (PVOID)PhysicalAddress.LowPart;
-
-    /* Zero it out */
-    RtlZeroMemory(MmArchReferencePage, MmArchReferencePageSize);
-
-    /* Allocate 4MB worth of self-map pages */
-    Status = MmPaReserveSelfMapPages(&Mmx86SelfMapBase, 
-                                     (4 * 1024 * 1024) >> PAGE_SHIFT,
-                                     (4 * 1024 * 1024) >> PAGE_SHIFT);
-    if (!NT_SUCCESS(Status))
-    {
-        goto Failure;
-    }
-
-    /* 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);
-
-    /* Align PTE base to 4MB region */
-    MmPteBase = (PVOID)(Mmx86SelfMapBase.LowPart & ~0x3FFFFF);
-
-    /* The PDE is the PTE of the PTE base */
-    MmPdeBase = MiAddressToPte(MmPteBase);
-    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;
-    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 Failure;
-    }
-
-    /* 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 Failure;
-    }
-
-    /* Initialize the virtual->physical memory mappings */
-    Status = Mmx86InitializeMemoryMap(1, MemoryData);
-    if (!NT_SUCCESS(Status))
-    {
-        goto Failure;
-    }
-
-    /* Turn on paging with the new CR3 */
-    __writecr3((ULONG_PTR)MmPdpt);
-    BlpArchEnableTranslation();
-    EfiPrintf(L"Paging... %d\r\n", BlMmIsTranslationEnabled());
-
-    /* Return success */
-    return Status;
-
-Failure:
-    /* Free reference page if we allocated it */
-    if (MmArchReferencePage)
-    {
-        PhysicalAddress.QuadPart = (ULONG_PTR)MmArchReferencePage;
-        BlMmFreePhysicalPages(PhysicalAddress);
-    }
-
-    /* Free page directory if we allocated it */
-    if (MmPdpt)
-    {
-        PhysicalAddress.QuadPart = (ULONG_PTR)MmPdpt;
-        BlMmFreePhysicalPages(PhysicalAddress);
-    }
-
-    /* Free the self map if we allocated it */
-    if (Mmx86SelfMapBase.QuadPart)
-    {
-        MmPaReleaseSelfMapPages(Mmx86SelfMapBase);
-    }
-
-    /* All done */
-    return Status;
-}
-
-NTSTATUS
-MmArchInitialize (
-    _In_ ULONG Phase,
-    _In_ PBL_MEMORY_DATA MemoryData,
-    _In_ BL_TRANSLATION_TYPE TranslationType,
-    _In_ BL_TRANSLATION_TYPE RequestedTranslationType
-    )
-{
-    NTSTATUS Status;
-    ULONGLONG IncreaseUserVa, PerfCounter, CpuRandom;
-    INT CpuInfo[4];
-
-    /* For phase 2, just map deferred regions */
-    if (Phase != 1)
-    {
-        return Mmx86pMapMemoryRegions(2, MemoryData);
-    }
-
-    /* What translation type are we switching to? */
-    switch (RequestedTranslationType)
-    {
-        /* Physical memory */
-        case BlNone:
-
-            /* Initialize everything to default/null values */
-            MmArchLargePageSize = 1;
-            MmArchKsegBase = 0;
-            MmArchKsegBias = 0;
-            MmArchKsegAddressRange.Minimum = 0;
-            MmArchKsegAddressRange.Maximum = (ULONGLONG)~0;
-            MmArchTopOfApplicationAddressSpace = 0;
-            Mmx86SelfMapBase.QuadPart = 0;
-
-            /* Set stub functions */
-            BlMmRelocateSelfMap = MmArchNullFunction;
-            BlMmFlushTlb = MmArchNullFunction;
-
-            /* Set success */
-            Status = STATUS_SUCCESS;
-            break;
-
-        case BlVirtual:
-
-            /* Set the large page size to 1024 pages (4MB) */
-            MmArchLargePageSize = (4 * 1024 * 1024) / PAGE_SIZE;
-
-            /* Check if /USERVA option was used */
-            Status = BlGetBootOptionInteger(BlpApplicationEntry.BcdData,
-                                            BcdOSLoaderInteger_IncreaseUserVa,
-                                            &IncreaseUserVa);
-            if (NT_SUCCESS(Status) && (IncreaseUserVa))
-            {
-                /* Yes -- load the kernel at 0xE0000000 instead */
-                MmArchKsegBase = 0xE0000000;
-            }
-            else
-            {
-                /* Nope, load at the standard 2GB split */
-                MmArchKsegBase = 0x80000000;
-            }
-
-            /* Check if CPUID 01h is supported */
-            CpuRandom = 0;
-            if (BlArchIsCpuIdFunctionSupported(1))
-            {
-                /* Call it */
-                BlArchCpuId(1, 0, CpuInfo);
-
-                /* Check if RDRAND is supported */
-                if (CpuInfo[2] & 0x40000000)
-                {
-                    EfiPrintf(L"Your CPU can do RDRAND! Good for you!\r\n");
-                    CpuRandom = 0;
-                }
-            }
-
-            /* Read the TSC */
-            PerfCounter = BlArchGetPerformanceCounter();
-            PerfCounter >>= 4;
-            _rotl16(PerfCounter, 5);
-
-            /* Set the address range */
-            MmArchKsegAddressRange.Minimum = 0;
-            MmArchKsegAddressRange.Maximum = (ULONGLONG)~0;
-
-            /* Set the KASLR bias */
-            MmArchKsegBias = ((PerfCounter ^ CpuRandom) & 0xFFF) << 12;
-            MmArchKsegBias = 0;
-            MmArchKsegBase += MmArchKsegBias;
-
-            /* Set the kernel range */
-            MmArchKsegAddressRange.Minimum = MmArchKsegBase;
-            MmArchKsegAddressRange.Maximum = (ULONGLONG)~0;
-
-            /* Set the boot application top maximum */
-            MmArchTopOfApplicationAddressSpace = 0x70000000 - 1; // Windows bug
-
-            /* Initialize virtual address space translation */
-            Status = MmDefInitializeTranslation(MemoryData, TranslationType);
-            if (NT_SUCCESS(Status))
-            {
-                /* Set stub functions */
-                BlMmRelocateSelfMap = MmDefRelocateSelfMap;
-                BlMmFlushTlb = Mmx86FlushTlb;
-                BlMmMoveVirtualAddressRange = MmDefMoveVirtualAddressRange;
-                BlMmZeroVirtualAddressRange = MmDefZeroVirtualAddressRange;
-            }
-            break;
-
-        case BlPae:
-
-            /* We don't support PAE */
-            Status = STATUS_NOT_SUPPORTED;
-            break;
-
-        default:
-
-            /* Invalid architecture type*/
-            Status = STATUS_INVALID_PARAMETER;
-            break;
-    }
-
-    /* Back to caller */
-    return Status;
-}