Преглед изворни кода

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.
Lioncash пре 7 година
родитељ
комит
622242e345
2 измењених фајлова са 41 додато и 0 уклоњено
  1. 28 0
      src/core/hle/kernel/vm_manager.cpp
  2. 13 0
      src/core/hle/kernel/vm_manager.h

+ 28 - 0
src/core/hle/kernel/vm_manager.cpp

@@ -322,6 +322,34 @@ MemoryInfo VMManager::QueryMemory(VAddr address) const {
     return memory_info;
     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) {
 ResultCode VMManager::MirrorMemory(VAddr dst_addr, VAddr src_addr, u64 size, MemoryState state) {
     const auto vma = FindVMA(src_addr);
     const auto vma = FindVMA(src_addr);
 
 

+ 13 - 0
src/core/hle/kernel/vm_manager.h

@@ -392,6 +392,19 @@ public:
     ///
     ///
     MemoryInfo QueryMemory(VAddr address) const;
     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
      * 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.
      * memory. This should be called after any operation that causes reallocation of the vector.