Author: ion
Date: Mon Feb 6 23:13:47 2017
New Revision: 73738
URL:
http://svn.reactos.org/svn/reactos?rev=73738&view=rev
Log:
[BOOTLIB]: Implement BlMmIsTranslationEnabled and MmMapPhysicalAddress.
MmDefpMapPhysicalAddress is missing at this point.
Modified:
trunk/reactos/boot/environ/include/bl.h
trunk/reactos/boot/environ/lib/mm/i386/mmx86.c
Modified: trunk/reactos/boot/environ/include/bl.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/environ/include/bl.h?…
==============================================================================
--- trunk/reactos/boot/environ/include/bl.h [iso-8859-1] (original)
+++ trunk/reactos/boot/environ/include/bl.h [iso-8859-1] Mon Feb 6 23:13:47 2017
@@ -2192,9 +2192,18 @@
/* 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
);
Modified: trunk/reactos/boot/environ/lib/mm/i386/mmx86.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/environ/lib/mm/i386/m…
==============================================================================
--- trunk/reactos/boot/environ/lib/mm/i386/mmx86.c [iso-8859-1] (original)
+++ trunk/reactos/boot/environ/lib/mm/i386/mmx86.c [iso-8859-1] Mon Feb 6 23:13:47 2017
@@ -296,6 +296,152 @@
{
EfiPrintf(L"No translate\r\n");
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