From 2da096022c5b097f854974f76dba8cc4f769513d Mon Sep 17 00:00:00 2001 From: ergo720 Date: Sat, 3 Mar 2018 23:53:19 +0100 Subject: [PATCH] MmUnmapIoSpace --- import/OpenXDK/include/xboxkrnl/mm.h | 2 +- src/CxbxKrnl/EmuKrnlMm.cpp | 12 ++----- src/CxbxKrnl/VMManager.cpp | 47 ++++++++++++++++++++++++++-- src/CxbxKrnl/VMManager.h | 2 ++ 4 files changed, 50 insertions(+), 13 deletions(-) diff --git a/import/OpenXDK/include/xboxkrnl/mm.h b/import/OpenXDK/include/xboxkrnl/mm.h index 2273f910d..d70315b7a 100644 --- a/import/OpenXDK/include/xboxkrnl/mm.h +++ b/import/OpenXDK/include/xboxkrnl/mm.h @@ -184,7 +184,7 @@ XBSYSAPI EXPORTNUM(182) VOID NTAPI MmSetAddressProtect // ****************************************************************** // * MmUnmapIoSpace // ****************************************************************** -XBSYSAPI EXPORTNUM(183) NTSTATUS NTAPI MmUnmapIoSpace +XBSYSAPI EXPORTNUM(183) VOID NTAPI MmUnmapIoSpace ( IN PVOID BaseAddress, IN ULONG NumberOfBytes diff --git a/src/CxbxKrnl/EmuKrnlMm.cpp b/src/CxbxKrnl/EmuKrnlMm.cpp index f1dd88f1e..09aef7d71 100644 --- a/src/CxbxKrnl/EmuKrnlMm.cpp +++ b/src/CxbxKrnl/EmuKrnlMm.cpp @@ -521,7 +521,7 @@ XBSYSAPI EXPORTNUM(182) xboxkrnl::VOID NTAPI xboxkrnl::MmSetAddressProtect // Unmaps a virtual address mapping made by MmMapIoSpace. // // Differences from NT: None. -XBSYSAPI EXPORTNUM(183) xboxkrnl::NTSTATUS NTAPI xboxkrnl::MmUnmapIoSpace +XBSYSAPI EXPORTNUM(183) xboxkrnl::VOID NTAPI xboxkrnl::MmUnmapIoSpace ( IN PVOID BaseAddress, IN ULONG NumberOfBytes @@ -532,15 +532,7 @@ XBSYSAPI EXPORTNUM(183) xboxkrnl::NTSTATUS NTAPI xboxkrnl::MmUnmapIoSpace LOG_FUNC_ARG(NumberOfBytes) LOG_FUNC_END; - if ((xbaddr)BaseAddress >= XBOX_WRITE_COMBINED_BASE) { // 0xF0000000 - // Don't free hardware devices (flash, NV2A, etc) - } - else { - g_VMManager.Deallocate((VAddr)BaseAddress); - LOG_INCOMPLETE(); - } - - RETURN(STATUS_SUCCESS); + g_VMManager.UnmapDeviceMemory((VAddr)BaseAddress, NumberOfBytes); } // ****************************************************************** diff --git a/src/CxbxKrnl/VMManager.cpp b/src/CxbxKrnl/VMManager.cpp index 111763307..941e5d917 100644 --- a/src/CxbxKrnl/VMManager.cpp +++ b/src/CxbxKrnl/VMManager.cpp @@ -665,7 +665,7 @@ void VMManager::DeAllocateContiguous(VAddr addr) PFN EndingPfn; VMAIter it; - assert(CHECK_ALIGNMENT(addr, PAGE_SIZE)); // all starting addresses from the contiguous region are page aligned + assert(CHECK_ALIGNMENT(addr, PAGE_SIZE)); // all starting addresses in the contiguous region are page aligned Lock(); @@ -706,7 +706,7 @@ PFN_COUNT VMManager::DeAllocateSystemMemory(PageType BusyType, VAddr addr, size_ PFN_COUNT PteNumber; VMAIter it; - assert(CHECK_ALIGNMENT(addr, PAGE_SIZE)); // all starting addresses from the system region are page aligned + assert(CHECK_ALIGNMENT(addr, PAGE_SIZE)); // all starting addresses in the system region are page aligned Lock(); @@ -744,6 +744,49 @@ PFN_COUNT VMManager::DeAllocateSystemMemory(PageType BusyType, VAddr addr, size_ RETURN(PteNumber); } +void VMManager::UnmapDeviceMemory(VAddr addr, size_t Size) +{ + LOG_FUNC_BEGIN + LOG_FUNC_ARG(addr); + LOG_FUNC_ARG(Size); + LOG_FUNC_END; + + if (addr >= SYSTEM_MEMORY_BASE && addr + Size <= SYSTEM_MEMORY_END) + { + // The allocation is inside the system region, so it must have been mapped by us. Unmap it + + MMPTE TempPte; + PMMPTE StartingPte; + PMMPTE EndingPte; + PFN_COUNT PteNumber; + VMAIter it; + + assert(CHECK_ALIGNMENT(addr, PAGE_SIZE)); // all starting addresses in the system region are page aligned + + Lock(); + + it = CheckExistenceVMA(addr, MemoryRegionType::System, ROUND_UP_4K(Size)); + + if (it == m_MemoryRegionArray[MemoryRegionType::System].RegionMap.end() || it->second.type == VMAType::Free) + { + Unlock(); + return; + } + + StartingPte = GetPteAddress(addr); + EndingPte = StartingPte + (it->second.size >> PAGE_SHIFT) - 1; + PteNumber = EndingPte - StartingPte + 1; + + WritePte(StartingPte, EndingPte, TempPte, 0, true); + DestructVMA(it, MemoryRegionType::System); + + Unlock(); + return; + } + + // Don't free hardware devices (flash, NV2A, etc) -> no operation +} + void VMManager::Protect(VAddr target, size_t size, DWORD new_perms) { LOG_FUNC_BEGIN diff --git a/src/CxbxKrnl/VMManager.h b/src/CxbxKrnl/VMManager.h index db0faf65b..15e328a8a 100644 --- a/src/CxbxKrnl/VMManager.h +++ b/src/CxbxKrnl/VMManager.h @@ -142,6 +142,8 @@ class VMManager : public PhysicalMemory PFN_COUNT DeAllocateSystemMemory(PageType BusyType, VAddr addr, size_t Size /*MemoryRegionType Type*/); // deallocates memory in the contiguous region void DeAllocateContiguous(VAddr addr); + // unmaps device memory in the system region + void UnmapDeviceMemory(VAddr addr, size_t Size); // deallocate a block of memory void Deallocate(VAddr addr); // changes the protections of a memory region