mirror of
https://github.com/reactos/reactos.git
synced 2025-05-20 17:45:06 +00:00
Fully working x86 paging support!
[BOOTLIB]: Fix a critical bug in BlpArchSwitchContext which was not switching to Firmware mode once paging was enabled. [BOOTLIB]: Fix a critical bug in OslMain which was incorrectly setting BL_LIBRARY_INITIALIZATION_COMPLETED instead of BL_LIBRARY_FLAG_REINITIALIZE_ALL and causing all sorts of failure paths. [BOOTLIB]: MmDefInitializeTranslation now turns on paging. [BOOTLIB]: Implement TrpGenerateMappingTracker and BlpArchEnableTranslation [BOOTLIB]: BlMmMapPhysicalAddressEx now works with paging enabled, and correctly finds mapped memory to use from the virtual MDLs. [BOOTLIB]: MmPapAllocateRegionFromMdl now handles virtual allocations from MmMdlMappedUnallocated. [BOOTLIB]: MmPapAllocatePagesInRange now handles BlMemoryKernelRange (KSEG0) allocations. [BOOTLIB]: MmMdFindSatisfyingRegion now handles virtual descriptors as well, and handles alignment better. svn path=/trunk/; revision=74519
This commit is contained in:
parent
a366e71f50
commit
676adf3c06
7 changed files with 382 additions and 44 deletions
|
@ -39,10 +39,11 @@ OslMain (
|
||||||
/* Setup the boot library parameters for this application */
|
/* Setup the boot library parameters for this application */
|
||||||
BlSetupDefaultParameters(&LibraryParameters);
|
BlSetupDefaultParameters(&LibraryParameters);
|
||||||
LibraryParameters.TranslationType = BlVirtual;
|
LibraryParameters.TranslationType = BlVirtual;
|
||||||
LibraryParameters.LibraryFlags = BL_LIBRARY_FLAG_INITIALIZATION_COMPLETED;
|
LibraryParameters.LibraryFlags = BL_LIBRARY_FLAG_ZERO_HEAP_ALLOCATIONS_ON_FREE |
|
||||||
|
BL_LIBRARY_FLAG_REINITIALIZE_ALL;
|
||||||
LibraryParameters.MinimumAllocationCount = 1024;
|
LibraryParameters.MinimumAllocationCount = 1024;
|
||||||
LibraryParameters.MinimumHeapSize = 2 * 1024 * 1024;
|
LibraryParameters.MinimumHeapSize = 2 * 1024 * 1024;
|
||||||
LibraryParameters.HeapAllocationAttributes = 0x20000;
|
LibraryParameters.HeapAllocationAttributes = BlMemoryKernelRange;
|
||||||
LibraryParameters.FontBaseDirectory = L"\\Reactos\\Boot\\Fonts";
|
LibraryParameters.FontBaseDirectory = L"\\Reactos\\Boot\\Fonts";
|
||||||
LibraryParameters.DescriptorCount = 512;
|
LibraryParameters.DescriptorCount = 512;
|
||||||
Status = BlInitializeLibrary(BootParameters, &LibraryParameters);
|
Status = BlInitializeLibrary(BootParameters, &LibraryParameters);
|
||||||
|
|
|
@ -2007,6 +2007,11 @@ BlpArchSwitchContext (
|
||||||
_In_ BL_ARCH_MODE NewMode
|
_In_ BL_ARCH_MODE NewMode
|
||||||
);
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
BlpArchEnableTranslation (
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
Archx86TransferTo32BitApplicationAsm (
|
Archx86TransferTo32BitApplicationAsm (
|
||||||
VOID
|
VOID
|
||||||
|
|
|
@ -171,7 +171,10 @@ BlpArchSwitchContext (
|
||||||
|
|
||||||
/* In real mode, use EFI, otherwise, use the application mode */
|
/* In real mode, use EFI, otherwise, use the application mode */
|
||||||
Context = &FirmwareExecutionContext;
|
Context = &FirmwareExecutionContext;
|
||||||
if (NewMode != BlProtectedMode) Context = &ApplicationExecutionContext;
|
if (NewMode != BlRealMode)
|
||||||
|
{
|
||||||
|
Context = &ApplicationExecutionContext;
|
||||||
|
}
|
||||||
|
|
||||||
/* Are we in a different mode? */
|
/* Are we in a different mode? */
|
||||||
if (CurrentExecutionContext->Mode != NewMode)
|
if (CurrentExecutionContext->Mode != NewMode)
|
||||||
|
@ -182,6 +185,40 @@ BlpArchSwitchContext (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
BlpArchEnableTranslation (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PBL_ARCH_CONTEXT Context;
|
||||||
|
|
||||||
|
/* Does the current execution context already have paging enabled? */
|
||||||
|
Context = CurrentExecutionContext;
|
||||||
|
if (!(Context->ContextFlags & BL_CONTEXT_PAGING_ON))
|
||||||
|
{
|
||||||
|
/* No -- does it have interrupts enabled? */
|
||||||
|
if (Context->ContextFlags & BL_CONTEXT_INTERRUPTS_ON)
|
||||||
|
{
|
||||||
|
/* Disable them */
|
||||||
|
_disable();
|
||||||
|
Context->ContextFlags &= ~BL_CONTEXT_INTERRUPTS_ON;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Are we enabling PAE? */
|
||||||
|
if (Context->TranslationType == BlPae)
|
||||||
|
{
|
||||||
|
/* Make sure CR4 reflects this */
|
||||||
|
__writecr4(__readcr4() | CR4_PAE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Enable paging in the CPU */
|
||||||
|
__writecr0(__readcr0() | CR0_PG);
|
||||||
|
|
||||||
|
/* Reflect that paging is enabled */
|
||||||
|
Context->ContextFlags |= BL_CONTEXT_PAGING_ON;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*++
|
/*++
|
||||||
* @name BlpArchInitialize
|
* @name BlpArchInitialize
|
||||||
*
|
*
|
||||||
|
|
|
@ -1022,8 +1022,10 @@ MmMdFindSatisfyingRegion (
|
||||||
_In_ ULONG Alignment
|
_In_ ULONG Alignment
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
ULONGLONG BaseMin, BaseMax;
|
ULONGLONG BaseMin, BaseMax, AlignedMin;
|
||||||
ULONGLONG VirtualPage, BasePage;
|
ULONGLONG VirtualPage, BasePage;
|
||||||
|
ULONGLONG BaseDelta, AlignedBase;
|
||||||
|
ULONGLONG VirtualMin, VirtualMax;
|
||||||
|
|
||||||
/* Extract the minimum and maximum range */
|
/* Extract the minimum and maximum range */
|
||||||
BaseMin = BaseRange->Minimum;
|
BaseMin = BaseRange->Minimum;
|
||||||
|
@ -1050,11 +1052,15 @@ MmMdFindSatisfyingRegion (
|
||||||
/* Align the base as required */
|
/* Align the base as required */
|
||||||
if (Alignment != 1)
|
if (Alignment != 1)
|
||||||
{
|
{
|
||||||
BaseMin = ALIGN_UP_BY(BaseMin, Alignment);
|
AlignedMin = ALIGN_UP_BY(BaseMin, Alignment);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AlignedMin = BaseMin;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check for range overflow */
|
/* Check for range overflow */
|
||||||
if (((BaseMin + Pages - 1) < BaseMin) || ((BaseMin + Pages - 1) > BaseMax))
|
if (((AlignedMin + Pages - 1) < AlignedMin) || ((AlignedMin + Pages - 1) > BaseMax))
|
||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -1067,13 +1073,22 @@ MmMdFindSatisfyingRegion (
|
||||||
if (Alignment != 1)
|
if (Alignment != 1)
|
||||||
{
|
{
|
||||||
/* Align it as needed */
|
/* Align it as needed */
|
||||||
BasePage = ALIGN_DOWN_BY(BasePage, Alignment);
|
AlignedBase = ALIGN_DOWN_BY(BasePage, Alignment);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AlignedBase = BasePage;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Calculate the delta between max address and our aligned base */
|
||||||
|
BaseDelta = BasePage - AlignedBase;
|
||||||
|
BasePage -= BaseDelta;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Otherwise, get the lowest page possible */
|
/* Otherwise, get the lowest page possible */
|
||||||
BasePage = BaseMin;
|
BasePage = AlignedMin;
|
||||||
|
BaseDelta = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If a virtual address range was passed in, this must be a virtual descriptor */
|
/* If a virtual address range was passed in, this must be a virtual descriptor */
|
||||||
|
@ -1086,8 +1101,49 @@ MmMdFindSatisfyingRegion (
|
||||||
/* Any mapped page already? */
|
/* Any mapped page already? */
|
||||||
if (Descriptor->VirtualPage)
|
if (Descriptor->VirtualPage)
|
||||||
{
|
{
|
||||||
EfiPrintf(L"Virtual memory not yet supported\r\n");
|
/* Get virtual min/max */
|
||||||
return FALSE;
|
VirtualMin = VirtualRange->Minimum;
|
||||||
|
VirtualMax = VirtualRange->Maximum;
|
||||||
|
|
||||||
|
/* Don't go below where the descriptor maps */
|
||||||
|
if (VirtualMin <= Descriptor->VirtualPage)
|
||||||
|
{
|
||||||
|
VirtualMin = Descriptor->VirtualPage;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Don't go above where the descriptor maps */
|
||||||
|
if (VirtualMax >= (Descriptor->VirtualPage + Descriptor->PageCount - 1))
|
||||||
|
{
|
||||||
|
VirtualMax = Descriptor->VirtualPage + Descriptor->PageCount - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Don't let the base overflow */
|
||||||
|
if (VirtualMin > VirtualMax)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Adjust the base by the alignment delta */
|
||||||
|
VirtualMin += AlignedMin - BaseMin;
|
||||||
|
|
||||||
|
/* Check that the bounds don't overflow or underflow */
|
||||||
|
if (((VirtualMin + Pages - 1) < VirtualMin) ||
|
||||||
|
((VirtualMin + Pages - 1) > VirtualMax))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Finally, pick the correct address based on direction */
|
||||||
|
if (TopDown)
|
||||||
|
{
|
||||||
|
/* Highest possible base address, aligned */
|
||||||
|
VirtualPage = VirtualMax - Pages + 1 - BaseDelta;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Lowest possible base address, aligned */
|
||||||
|
VirtualPage = VirtualMin;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -1042,8 +1042,10 @@ MmDefInitializeTranslation (
|
||||||
goto Quickie;
|
goto Quickie;
|
||||||
}
|
}
|
||||||
|
|
||||||
EfiPrintf(L"Ready to turn on motherfucking paging, brah!\r\n");
|
/* Turn on paging with the new CR3 */
|
||||||
Status = STATUS_NOT_IMPLEMENTED;
|
__writecr3((ULONG_PTR)MmPdpt);
|
||||||
|
BlpArchEnableTranslation();
|
||||||
|
EfiPrintf(L"Paging... ON\r\n");
|
||||||
|
|
||||||
Quickie:
|
Quickie:
|
||||||
/* Free reference page if we allocated it */
|
/* Free reference page if we allocated it */
|
||||||
|
|
|
@ -20,6 +20,66 @@ ULONG MmDescriptorCallTreeCount;
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
TrpGenerateMappingTracker (
|
||||||
|
_In_ PVOID VirtualAddress,
|
||||||
|
_In_ ULONG Flags,
|
||||||
|
_In_ LARGE_INTEGER PhysicalAddress,
|
||||||
|
_In_ ULONGLONG Size
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PBL_MEMORY_DESCRIPTOR Descriptor, NextDescriptor;
|
||||||
|
PLIST_ENTRY ListHead, NextEntry;
|
||||||
|
|
||||||
|
/* Increment descriptor call count */
|
||||||
|
MmDescriptorCallTreeCount++;
|
||||||
|
|
||||||
|
/* Initialize a descriptor for this allocation */
|
||||||
|
Descriptor = MmMdInitByteGranularDescriptor(Flags,
|
||||||
|
0,
|
||||||
|
PhysicalAddress.QuadPart,
|
||||||
|
(ULONG_PTR)VirtualAddress,
|
||||||
|
Size);
|
||||||
|
|
||||||
|
/* Loop the current tracker list */
|
||||||
|
ListHead = MmMdlMappingTrackers.First;
|
||||||
|
NextEntry = ListHead->Flink;
|
||||||
|
if (IsListEmpty(ListHead))
|
||||||
|
{
|
||||||
|
/* If it's empty, just add the descriptor at the end */
|
||||||
|
InsertTailList(ListHead, &Descriptor->ListEntry);
|
||||||
|
goto Quickie;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Otherwise, go to the last descriptor */
|
||||||
|
NextDescriptor = CONTAINING_RECORD(NextEntry,
|
||||||
|
BL_MEMORY_DESCRIPTOR,
|
||||||
|
ListEntry);
|
||||||
|
while (NextDescriptor->VirtualPage < Descriptor->VirtualPage)
|
||||||
|
{
|
||||||
|
/* Keep going... */
|
||||||
|
NextEntry = NextEntry->Flink;
|
||||||
|
NextDescriptor = CONTAINING_RECORD(NextEntry,
|
||||||
|
BL_MEMORY_DESCRIPTOR,
|
||||||
|
ListEntry);
|
||||||
|
|
||||||
|
/* If we hit the end of the list, just add it at the end */
|
||||||
|
if (NextEntry == ListHead)
|
||||||
|
{
|
||||||
|
goto Quickie;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Otherwise, add it right after this descriptor */
|
||||||
|
InsertTailList(&NextDescriptor->ListEntry, &Descriptor->ListEntry);
|
||||||
|
}
|
||||||
|
|
||||||
|
Quickie:
|
||||||
|
/* Release any global descriptors allocated */
|
||||||
|
MmMdFreeGlobalDescriptors();
|
||||||
|
--MmDescriptorCallTreeCount;
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
MmTrInitialize (
|
MmTrInitialize (
|
||||||
VOID
|
VOID
|
||||||
|
@ -142,6 +202,11 @@ BlMmMapPhysicalAddressEx (
|
||||||
PVOID MappedBase;
|
PVOID MappedBase;
|
||||||
ULONGLONG MapSize;
|
ULONGLONG MapSize;
|
||||||
UCHAR CacheAttributes;
|
UCHAR CacheAttributes;
|
||||||
|
ULONGLONG BasePage, EndPage, MappedPage, FoundBasePage;
|
||||||
|
ULONGLONG PageOffset, FoundPageCount;
|
||||||
|
PBL_MEMORY_DESCRIPTOR Descriptor, NewDescriptor;
|
||||||
|
PBL_MEMORY_DESCRIPTOR_LIST List;
|
||||||
|
ULONG AddPages;
|
||||||
|
|
||||||
/* Increase call depth */
|
/* Increase call depth */
|
||||||
++MmDescriptorCallTreeCount;
|
++MmDescriptorCallTreeCount;
|
||||||
|
@ -206,21 +271,174 @@ BlMmMapPhysicalAddressEx (
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Compute the final address where the mapping was made */
|
/* Compute the final address where the mapping was made */
|
||||||
MappedBase = (PVOID)((ULONG_PTR)MappingAddress +
|
MappedBase = (PVOID)(ULONG_PTR)((ULONG_PTR)MappingAddress +
|
||||||
PhysicalAddress.LowPart -
|
PhysicalAddress.QuadPart -
|
||||||
MappedAddress.LowPart);
|
MappedAddress.QuadPart);
|
||||||
|
MappedAddress.QuadPart = (ULONG_PTR)MappedBase;
|
||||||
|
|
||||||
/* Check if we're in physical or virtual mode */
|
/* Check if we're in physical or virtual mode */
|
||||||
if (MmTranslationType != BlNone)
|
if (MmTranslationType == BlNone)
|
||||||
{
|
{
|
||||||
/* We don't support virtual memory yet @TODO */
|
/* We are in physical mode -- just return this address directly */
|
||||||
EfiPrintf(L"not yet implemented in BlMmMapPhysicalAddressEx\r\n");
|
Status = STATUS_SUCCESS;
|
||||||
EfiStall(1000000);
|
*VirtualAddress = MappedBase;
|
||||||
Status = STATUS_NOT_IMPLEMENTED;
|
|
||||||
goto Quickie;
|
goto Quickie;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the mapped virtual address */
|
/* Remove the mapping address from the list of free virtual memory */
|
||||||
|
Status = MmMdRemoveRegionFromMdlEx(&MmMdlFreeVirtual,
|
||||||
|
BL_MM_REMOVE_VIRTUAL_REGION_FLAG,
|
||||||
|
(ULONG_PTR)MappingAddress >> PAGE_SHIFT,
|
||||||
|
MapSize >> PAGE_SHIFT,
|
||||||
|
NULL);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* And then add an entry for the fact we mapped it */
|
||||||
|
Status = TrpGenerateMappingTracker(MappedBase,
|
||||||
|
CacheAttributes,
|
||||||
|
PhysicalAddress,
|
||||||
|
MapSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Abandon if we didn't update the memory map successfully */
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* Unmap the virtual address so it can be used later */
|
||||||
|
MmUnmapVirtualAddress(MappingAddress, &MapSize);
|
||||||
|
goto Quickie;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if no real mapping into RAM was made */
|
||||||
|
if (PhysicalAddress.QuadPart == -1)
|
||||||
|
{
|
||||||
|
/* Then we're done here */
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
*VirtualAddress = MappedBase;
|
||||||
|
goto Quickie;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Loop over the entire allocation */
|
||||||
|
BasePage = MappedAddress.QuadPart >> PAGE_SHIFT;
|
||||||
|
EndPage = (MappedAddress.QuadPart + MapSize) >> PAGE_SHIFT;
|
||||||
|
MappedPage = (ULONG_PTR)MappingAddress >> PAGE_SHIFT;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
/* Start with the unmapped allocated list */
|
||||||
|
List = &MmMdlUnmappedAllocated;
|
||||||
|
Descriptor = MmMdFindDescriptor(BL_MM_INCLUDE_UNMAPPED_ALLOCATED,
|
||||||
|
BL_MM_REMOVE_PHYSICAL_REGION_FLAG,
|
||||||
|
BasePage);
|
||||||
|
if (!Descriptor)
|
||||||
|
{
|
||||||
|
/* Try persistent next */
|
||||||
|
List = &MmMdlPersistentMemory;
|
||||||
|
Descriptor = MmMdFindDescriptor(BL_MM_INCLUDE_PERSISTENT_MEMORY,
|
||||||
|
BL_MM_REMOVE_PHYSICAL_REGION_FLAG,
|
||||||
|
BasePage);
|
||||||
|
}
|
||||||
|
if (!Descriptor)
|
||||||
|
{
|
||||||
|
/* Try unmapped, unallocated, next */
|
||||||
|
List = &MmMdlUnmappedUnallocated;
|
||||||
|
Descriptor = MmMdFindDescriptor(BL_MM_INCLUDE_UNMAPPED_UNALLOCATED,
|
||||||
|
BL_MM_REMOVE_PHYSICAL_REGION_FLAG,
|
||||||
|
BasePage);
|
||||||
|
}
|
||||||
|
if (!Descriptor)
|
||||||
|
{
|
||||||
|
/* Try reserved next */
|
||||||
|
List = &MmMdlReservedAllocated;
|
||||||
|
Descriptor = MmMdFindDescriptor(BL_MM_INCLUDE_RESERVED_ALLOCATED,
|
||||||
|
BL_MM_REMOVE_PHYSICAL_REGION_FLAG,
|
||||||
|
BasePage);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if we have a descriptor */
|
||||||
|
if (Descriptor)
|
||||||
|
{
|
||||||
|
/* Remove it from its list */
|
||||||
|
MmMdRemoveDescriptorFromList(List, Descriptor);
|
||||||
|
|
||||||
|
/* Check if it starts before our allocation */
|
||||||
|
FoundBasePage = Descriptor->BasePage;
|
||||||
|
if (FoundBasePage < BasePage)
|
||||||
|
{
|
||||||
|
/* Create a new descriptor to cover the gap before our allocation */
|
||||||
|
PageOffset = BasePage - FoundBasePage;
|
||||||
|
NewDescriptor = MmMdInitByteGranularDescriptor(Descriptor->Flags,
|
||||||
|
Descriptor->Type,
|
||||||
|
FoundBasePage,
|
||||||
|
0,
|
||||||
|
PageOffset);
|
||||||
|
|
||||||
|
/* Insert it */
|
||||||
|
MmMdAddDescriptorToList(List, NewDescriptor, 0);
|
||||||
|
|
||||||
|
/* Adjust ours to ignore that piece */
|
||||||
|
Descriptor->PageCount -= PageOffset;
|
||||||
|
Descriptor->BasePage = BasePage;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if it goes beyond our allocation */
|
||||||
|
FoundPageCount = Descriptor->PageCount;
|
||||||
|
if (EndPage < (FoundPageCount + Descriptor->BasePage))
|
||||||
|
{
|
||||||
|
/* Create a new descriptor to cover the range after our allocation */
|
||||||
|
PageOffset = EndPage - BasePage;
|
||||||
|
NewDescriptor = MmMdInitByteGranularDescriptor(Descriptor->Flags,
|
||||||
|
Descriptor->Type,
|
||||||
|
EndPage,
|
||||||
|
0,
|
||||||
|
FoundPageCount -
|
||||||
|
PageOffset);
|
||||||
|
|
||||||
|
/* Insert it */
|
||||||
|
MmMdAddDescriptorToList(List, NewDescriptor, 0);
|
||||||
|
|
||||||
|
/* Adjust ours to ignore that piece */
|
||||||
|
Descriptor->PageCount = PageOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update the descriptor to be mapepd at this virtual page */
|
||||||
|
Descriptor->VirtualPage = MappedPage;
|
||||||
|
|
||||||
|
/* Check if this was one of the regular lists */
|
||||||
|
if ((List != &MmMdlReservedAllocated) &&
|
||||||
|
(List != &MmMdlPersistentMemory))
|
||||||
|
{
|
||||||
|
/* Was it allocated, or unallocated? */
|
||||||
|
if (List != &MmMdlUnmappedAllocated)
|
||||||
|
{
|
||||||
|
/* In which case use the unallocated mapped list */
|
||||||
|
List = &MmMdlMappedUnallocated;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Insert it into the mapped list */
|
||||||
|
List = &MmMdlMappedAllocated;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add the descriptor that was removed, into the right list */
|
||||||
|
MmMdAddDescriptorToList(List, Descriptor, 0);
|
||||||
|
|
||||||
|
/* Add the pages this descriptor had */
|
||||||
|
AddPages = Descriptor->PageCount;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Nope, so just add one page */
|
||||||
|
AddPages = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Increment the number of pages the descriptor had */
|
||||||
|
MappedPage += AddPages;
|
||||||
|
BasePage += AddPages;
|
||||||
|
}
|
||||||
|
while (BasePage < EndPage);
|
||||||
|
|
||||||
|
/* We're done -- returned the address */
|
||||||
Status = STATUS_SUCCESS;
|
Status = STATUS_SUCCESS;
|
||||||
*VirtualAddress = MappedBase;
|
*VirtualAddress = MappedBase;
|
||||||
|
|
||||||
|
@ -250,7 +468,7 @@ MmUnmapVirtualAddress (
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* We don't support virtual memory yet @TODO */
|
/* We don't support virtual memory yet @TODO */
|
||||||
EfiPrintf(L"not yet implemented in %S\r\n", __FUNCTION__);
|
EfiPrintf(L"unmap not yet implemented in %S\r\n", __FUNCTION__);
|
||||||
EfiStall(1000000);
|
EfiStall(1000000);
|
||||||
Status = STATUS_NOT_IMPLEMENTED;
|
Status = STATUS_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
|
@ -187,12 +187,34 @@ MmPapAllocateRegionFromMdl (
|
||||||
/* Remove the descriptor from the original list it was on */
|
/* Remove the descriptor from the original list it was on */
|
||||||
MmMdRemoveDescriptorFromList(CurrentList, FoundDescriptor);
|
MmMdRemoveDescriptorFromList(CurrentList, FoundDescriptor);
|
||||||
|
|
||||||
|
/* Get the end pages */
|
||||||
|
LocalEndPage = LocalDescriptor.PageCount + LocalDescriptor.BasePage;
|
||||||
|
FoundEndPage = FoundDescriptor->PageCount + FoundDescriptor->BasePage;
|
||||||
|
|
||||||
/* Are we allocating from the virtual memory list? */
|
/* Are we allocating from the virtual memory list? */
|
||||||
if (CurrentList == &MmMdlMappedUnallocated)
|
if (CurrentList == &MmMdlMappedUnallocated)
|
||||||
{
|
{
|
||||||
EfiPrintf(L"not yet implemented in %S\r\n", __FUNCTION__);
|
/* Check if the region matches perfectly */
|
||||||
EfiStall(1000000);
|
if ((LocalDescriptor.BasePage == FoundDescriptor->BasePage) &&
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
(LocalEndPage == FoundEndPage))
|
||||||
|
{
|
||||||
|
/* Check if the original descriptor had the flag set */
|
||||||
|
if ((FoundDescriptor->Flags & 0x40000000) && (Descriptor))
|
||||||
|
{
|
||||||
|
/* Make our local one have it too, even if not needed */
|
||||||
|
LocalDescriptor.Flags |= 0x40000000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Write the 'incomplete mapping' flag */
|
||||||
|
FoundDescriptor->Flags |= 0x40000000;
|
||||||
|
if (Descriptor)
|
||||||
|
{
|
||||||
|
/* Including on the local one if there's one passed in */
|
||||||
|
LocalDescriptor.Flags |= 0x40000000;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Does the memory we received not exactly fall onto the beginning of its descriptor? */
|
/* Does the memory we received not exactly fall onto the beginning of its descriptor? */
|
||||||
|
@ -212,8 +234,6 @@ MmPapAllocateRegionFromMdl (
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Does the memory we received not exactly fall onto the end of its descriptor? */
|
/* Does the memory we received not exactly fall onto the end of its descriptor? */
|
||||||
LocalEndPage = LocalDescriptor.PageCount + LocalDescriptor.BasePage;
|
|
||||||
FoundEndPage = FoundDescriptor->PageCount + FoundDescriptor->BasePage;
|
|
||||||
LocalVirtualEndPage = LocalDescriptor.VirtualPage ?
|
LocalVirtualEndPage = LocalDescriptor.VirtualPage ?
|
||||||
LocalDescriptor.VirtualPage + LocalDescriptor.PageCount : 0;
|
LocalDescriptor.VirtualPage + LocalDescriptor.PageCount : 0;
|
||||||
if (LocalEndPage != FoundEndPage)
|
if (LocalEndPage != FoundEndPage)
|
||||||
|
@ -303,7 +323,7 @@ MmPaAllocatePages (
|
||||||
/* Are we failing due to some attributes? */
|
/* Are we failing due to some attributes? */
|
||||||
if (Request->Flags & BlMemoryValidAllocationAttributeMask)
|
if (Request->Flags & BlMemoryValidAllocationAttributeMask)
|
||||||
{
|
{
|
||||||
EfiPrintf(L"not yet implemented in %S\r\n", __FUNCTION__);
|
EfiPrintf(L"alloc fail not yet implemented %lx in %S\r\n", Status, __FUNCTION__);
|
||||||
EfiStall(1000000);
|
EfiStall(1000000);
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
return STATUS_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
@ -532,7 +552,6 @@ MmPapPageAllocatorExtend (
|
||||||
AllocationFlags | CacheAttributes,
|
AllocationFlags | CacheAttributes,
|
||||||
NewDescriptor.PageCount << PAGE_SHIFT,
|
NewDescriptor.PageCount << PAGE_SHIFT,
|
||||||
PhysicalAddress);
|
PhysicalAddress);
|
||||||
EfiPrintf(L"MAP status: %lx\r\n", Status);
|
|
||||||
if (Status == STATUS_SUCCESS)
|
if (Status == STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
/* Add the cache attributes now that the mapping worked */
|
/* Add the cache attributes now that the mapping worked */
|
||||||
|
@ -627,7 +646,7 @@ MmPapAllocatePagesInRange (
|
||||||
if (Range)
|
if (Range)
|
||||||
{
|
{
|
||||||
/* We don't support virtual memory yet @TODO */
|
/* We don't support virtual memory yet @TODO */
|
||||||
EfiPrintf(L"not yet implemented in %S\r\n", __FUNCTION__);
|
EfiPrintf(L"virt range not yet implemented in %S\r\n", __FUNCTION__);
|
||||||
EfiStall(1000000);
|
EfiStall(1000000);
|
||||||
Status = STATUS_NOT_IMPLEMENTED;
|
Status = STATUS_NOT_IMPLEMENTED;
|
||||||
goto Exit;
|
goto Exit;
|
||||||
|
@ -643,26 +662,26 @@ MmPapAllocatePagesInRange (
|
||||||
if (Attributes & BlMemoryFixed)
|
if (Attributes & BlMemoryFixed)
|
||||||
{
|
{
|
||||||
/* We don't support virtual memory yet @TODO */
|
/* We don't support virtual memory yet @TODO */
|
||||||
EfiPrintf(L"not yet implemented in %S\r\n", __FUNCTION__);
|
EfiPrintf(L"fixed not yet implemented in %S\r\n", __FUNCTION__);
|
||||||
EfiStall(1000000);
|
EfiStall(1000000);
|
||||||
Status = STATUS_NOT_IMPLEMENTED;
|
Status = STATUS_NOT_IMPLEMENTED;
|
||||||
goto Exit;
|
goto Exit;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Check if non-fixed was specifically requested */
|
/* Check if kernel range was specifically requested */
|
||||||
if (Attributes & BlMemoryKernelRange)
|
if (Attributes & BlMemoryKernelRange)
|
||||||
{
|
{
|
||||||
/* We don't support virtual memory yet @TODO */
|
/* Use the kernel range */
|
||||||
EfiPrintf(L"not yet implemented in %S\r\n", __FUNCTION__);
|
Request.VirtualRange.Minimum = MmArchKsegAddressRange.Minimum >> PAGE_SHIFT;
|
||||||
EfiStall(1000000);
|
Request.VirtualRange.Maximum = MmArchKsegAddressRange.Maximum >> PAGE_SHIFT;
|
||||||
Status = STATUS_NOT_IMPLEMENTED;
|
}
|
||||||
goto Exit;
|
else
|
||||||
|
{
|
||||||
|
/* Set the virtual address range */
|
||||||
|
Request.VirtualRange.Minimum = 0;
|
||||||
|
Request.VirtualRange.Maximum = 0xFFFFFFFF >> PAGE_SHIFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the virtual address range */
|
|
||||||
Request.VirtualRange.Minimum = 0;
|
|
||||||
Request.VirtualRange.Maximum = 0xFFFFFFFF >> PAGE_SHIFT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check what type of allocation was requested */
|
/* Check what type of allocation was requested */
|
||||||
|
@ -702,7 +721,7 @@ MmPapAllocatePagesInRange (
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
/* Fail since we're out of memory */
|
/* Fail since we're out of memory */
|
||||||
EfiPrintf(L"OUT OF MEMORY: %lx\r\n", Status);
|
EfiPrintf(L"EXTEND OUT OF MEMORY: %lx\r\n", Status);
|
||||||
Status = STATUS_NO_MEMORY;
|
Status = STATUS_NO_MEMORY;
|
||||||
goto Exit;
|
goto Exit;
|
||||||
}
|
}
|
||||||
|
@ -716,7 +735,7 @@ MmPapAllocatePagesInRange (
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
/* Fail since we're out of memory */
|
/* Fail since we're out of memory */
|
||||||
EfiPrintf(L"OUT OF MEMORY: %lx\r\n", Status);
|
EfiPrintf(L"PALLOC OUT OF MEMORY: %lx\r\n", Status);
|
||||||
goto Exit;
|
goto Exit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1082,7 +1101,7 @@ MmPapFreePages (
|
||||||
/* Handle virtual memory scenario */
|
/* Handle virtual memory scenario */
|
||||||
if (MmTranslationType != BlNone)
|
if (MmTranslationType != BlNone)
|
||||||
{
|
{
|
||||||
EfiPrintf(L"Unimplemented free virtual path\r\n");
|
EfiPrintf(L"Unimplemented free virtual path: %p %lx\r\n", Address, WhichList);
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue