[BOOTLIB]: Finish implementation of MmMdRemoveRegionFromMdlEx for other straddling scenarios.

[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
This commit is contained in:
Alex Ionescu 2017-02-06 22:11:21 +00:00
parent 6e89272bef
commit 4578326e06
5 changed files with 252 additions and 29 deletions

View 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,

View 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;

View 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 */

View 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;
}
}

View 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;
}