From 622242e3451fd562425f67317f3f0d7855eb5741 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Sat, 15 Dec 2018 14:29:39 -0500 Subject: vm_manager: Add member function for setting memory attributes across an address range This puts the backing functionality for svcSetMemoryAttribute in place, which will be utilized in a following change. --- src/core/hle/kernel/vm_manager.cpp | 28 ++++++++++++++++++++++++++++ src/core/hle/kernel/vm_manager.h | 13 +++++++++++++ 2 files changed, 41 insertions(+) (limited to 'src/core/hle/kernel') diff --git a/src/core/hle/kernel/vm_manager.cpp b/src/core/hle/kernel/vm_manager.cpp index 02504d750..f39e096ca 100644 --- a/src/core/hle/kernel/vm_manager.cpp +++ b/src/core/hle/kernel/vm_manager.cpp @@ -322,6 +322,34 @@ MemoryInfo VMManager::QueryMemory(VAddr address) const { return memory_info; } +ResultCode VMManager::SetMemoryAttribute(VAddr address, u64 size, MemoryAttribute mask, + MemoryAttribute attribute) { + constexpr auto ignore_mask = MemoryAttribute::Uncached | MemoryAttribute::DeviceMapped; + constexpr auto attribute_mask = ~ignore_mask; + + const auto result = CheckRangeState( + address, size, MemoryState::FlagUncached, MemoryState::FlagUncached, VMAPermission::None, + VMAPermission::None, attribute_mask, MemoryAttribute::None, ignore_mask); + + if (result.Failed()) { + return result.Code(); + } + + const auto [prev_state, prev_permissions, prev_attributes] = *result; + const auto new_attribute = (prev_attributes & ~mask) | (mask & attribute); + + const auto carve_result = CarveVMARange(address, size); + if (carve_result.Failed()) { + return carve_result.Code(); + } + + auto vma_iter = *carve_result; + vma_iter->second.attribute = new_attribute; + + MergeAdjacent(vma_iter); + return RESULT_SUCCESS; +} + ResultCode VMManager::MirrorMemory(VAddr dst_addr, VAddr src_addr, u64 size, MemoryState state) { const auto vma = FindVMA(src_addr); diff --git a/src/core/hle/kernel/vm_manager.h b/src/core/hle/kernel/vm_manager.h index 9fa9a18fb..6091533bc 100644 --- a/src/core/hle/kernel/vm_manager.h +++ b/src/core/hle/kernel/vm_manager.h @@ -392,6 +392,19 @@ public: /// MemoryInfo QueryMemory(VAddr address) const; + /// Sets an attribute across the given address range. + /// + /// @param address The starting address + /// @param size The size of the range to set the attribute on. + /// @param mask The attribute mask + /// @param attribute The attribute to set across the given address range + /// + /// @returns RESULT_SUCCESS if successful + /// @returns ERR_INVALID_ADDRESS_STATE if the attribute could not be set. + /// + ResultCode SetMemoryAttribute(VAddr address, u64 size, MemoryAttribute mask, + MemoryAttribute attribute); + /** * Scans all VMAs and updates the page table range of any that use the given vector as backing * memory. This should be called after any operation that causes reallocation of the vector. -- cgit v1.2.3