From 928202f744f32fd6ba69f8ef28c6e5bec190cddb Mon Sep 17 00:00:00 2001 From: Subv Date: Tue, 7 Nov 2017 13:38:33 -0500 Subject: [PATCH] Kernel/VMManager: Added a function to map a block of memory into the first available address after a given base. --- src/core/hle/kernel/vm_manager.cpp | 27 +++++++++++++++++++++++++++ src/core/hle/kernel/vm_manager.h | 12 ++++++++++++ 2 files changed, 39 insertions(+) diff --git a/src/core/hle/kernel/vm_manager.cpp b/src/core/hle/kernel/vm_manager.cpp index 7a007c0656..0eecb7e570 100644 --- a/src/core/hle/kernel/vm_manager.cpp +++ b/src/core/hle/kernel/vm_manager.cpp @@ -93,6 +93,33 @@ ResultVal VMManager::MapMemoryBlock(VAddr target, return MakeResult(MergeAdjacent(vma_handle)); } +ResultVal VMManager::MapMemoryBlockToBase(VAddr base, std::shared_ptr> block, + size_t offset, u32 size, MemoryState state) { + + // Find the first Free VMA. + VMAHandle vma_handle = std::find_if(vma_map.begin(), vma_map.end(), [&](const auto& vma) { + if (vma.second.type != VMAType::Free) + return false; + + VAddr vma_end = vma.second.base + vma.second.size; + return vma_end > base && vma_end >= base + size; + }); + + if (vma_handle == vma_map.end()) { + return ResultCode(ErrorDescription::OutOfMemory, ErrorModule::Kernel, + ErrorSummary::OutOfResource, ErrorLevel::Permanent); + } + + VAddr target = std::max(base, vma_handle->second.base); + + auto result = MapMemoryBlock(target, block, offset, size, state); + + if (result.Failed()) + return result.Code(); + + return MakeResult(target); +} + ResultVal VMManager::MapBackingMemory(VAddr target, u8* memory, u32 size, MemoryState state) { ASSERT(memory != nullptr); diff --git a/src/core/hle/kernel/vm_manager.h b/src/core/hle/kernel/vm_manager.h index 1302527bb9..3a13679780 100644 --- a/src/core/hle/kernel/vm_manager.h +++ b/src/core/hle/kernel/vm_manager.h @@ -144,6 +144,18 @@ public: ResultVal MapMemoryBlock(VAddr target, std::shared_ptr> block, size_t offset, u32 size, MemoryState state); + /** + * Maps part of a ref-counted block of memory at the first free address after the given base. + * + * @param base The base address to start the mapping at. + * @param block The block to be mapped. + * @param offset Offset into `block` to map from. + * @param size Size of the mapping. + * @param state MemoryState tag to attach to the VMA. + * @returns The address at which the memory was mapped. + */ + ResultVal MapMemoryBlockToBase(VAddr base, std::shared_ptr> block, + size_t offset, u32 size, MemoryState state); /** * Maps an unmanaged host memory pointer at a given address. *