mirror of
https://github.com/reactos/reactos.git
synced 2024-10-15 13:45:58 +00:00
[BOOTLIB]: Implement BlMmIsTranslationEnabled and MmMapPhysicalAddress. MmDefpMapPhysicalAddress is missing at this point.
svn path=/trunk/; revision=73738
This commit is contained in:
parent
6050891f74
commit
036af3b730
|
@ -2191,10 +2191,19 @@ BlMmGetMemoryMap (
|
|||
|
||||
/* VIRTUAL MEMORY ROUTINES ***************************************************/
|
||||
|
||||
NTSTATUS
|
||||
MmSelectMappingAddress (
|
||||
_Out_ PVOID* MappingAddress,
|
||||
_In_ ULONGLONG Size,
|
||||
_In_ ULONG AllocationAttributes,
|
||||
_In_ ULONG Flags,
|
||||
_In_ PHYSICAL_ADDRESS PhysicalAddress
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
MmMapPhysicalAddress (
|
||||
_Inout_ PPHYSICAL_ADDRESS PhysicalAddress,
|
||||
_Out_ PVOID VirtualAddress,
|
||||
_Out_ PVOID* VirtualAddress,
|
||||
_Inout_ PULONGLONG Size,
|
||||
_In_ ULONG CacheAttributes
|
||||
);
|
||||
|
|
|
@ -298,6 +298,152 @@ MmDefpTranslateVirtualAddress (
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
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 */
|
||||
#ifdef _MSC_VER // Fuck gcc.
|
||||
EfiPrintf(L"not yet implemented in " __FUNCTION__ "\r\n");
|
||||
EfiStall(1000000);
|
||||
#endif
|
||||
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,
|
||||
_Inout_ PVOID* VirtualAddressPtr,
|
||||
_Inout_ PULONGLONG SizePtr,
|
||||
_In_ ULONG CacheAttributes
|
||||
)
|
||||
{
|
||||
ULONGLONG Size, TotalSize;
|
||||
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 */
|
||||
TotalSize = ROUND_TO_PAGES(PhysicalAddressPtr->QuadPart -
|
||||
PhysicalAddress +
|
||||
Size);
|
||||
|
||||
/* Loop every virtual page */
|
||||
CurrentAddress = (ULONG_PTR)VirtualAddress;
|
||||
VirtualAddressEnd = CurrentAddress + TotalSize - 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));
|
||||
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);
|
||||
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,
|
||||
|
|
Loading…
Reference in a new issue