summaryrefslogtreecommitdiffstats
path: root/src/core/hle/kernel/k_page_table.cpp
diff options
context:
space:
mode:
authorbunnei <bunneidev@gmail.com>2022-01-08 12:16:59 +0100
committerbunnei <bunneidev@gmail.com>2022-01-08 21:18:14 +0100
commitaf4696657c5401b3cf352d34e2515d45ead2144d (patch)
tree7a7d0a7849364668cb4083cccc9ecaee9e73b2a6 /src/core/hle/kernel/k_page_table.cpp
parentcore: hle: kernel: k_page_table: Update CheckMemoryState. (diff)
downloadyuzu-af4696657c5401b3cf352d34e2515d45ead2144d.tar
yuzu-af4696657c5401b3cf352d34e2515d45ead2144d.tar.gz
yuzu-af4696657c5401b3cf352d34e2515d45ead2144d.tar.bz2
yuzu-af4696657c5401b3cf352d34e2515d45ead2144d.tar.lz
yuzu-af4696657c5401b3cf352d34e2515d45ead2144d.tar.xz
yuzu-af4696657c5401b3cf352d34e2515d45ead2144d.tar.zst
yuzu-af4696657c5401b3cf352d34e2515d45ead2144d.zip
Diffstat (limited to 'src/core/hle/kernel/k_page_table.cpp')
-rw-r--r--src/core/hle/kernel/k_page_table.cpp38
1 files changed, 25 insertions, 13 deletions
diff --git a/src/core/hle/kernel/k_page_table.cpp b/src/core/hle/kernel/k_page_table.cpp
index e86ded58b..6077985b5 100644
--- a/src/core/hle/kernel/k_page_table.cpp
+++ b/src/core/hle/kernel/k_page_table.cpp
@@ -837,24 +837,36 @@ ResultCode KPageTable::SetMemoryPermission(VAddr addr, std::size_t size,
return ResultSuccess;
}
-ResultCode KPageTable::SetMemoryAttribute(VAddr addr, std::size_t size, KMemoryAttribute mask,
- KMemoryAttribute value) {
- std::lock_guard lock{page_table_lock};
+ResultCode KPageTable::SetMemoryAttribute(VAddr addr, std::size_t size, u32 mask, u32 attr) {
+ const size_t num_pages = size / PageSize;
+ ASSERT((static_cast<KMemoryAttribute>(mask) | KMemoryAttribute::SetMask) ==
+ KMemoryAttribute::SetMask);
- KMemoryState state{};
- KMemoryPermission perm{};
- KMemoryAttribute attribute{};
+ // Lock the table.
+ std::lock_guard lock{page_table_lock};
- CASCADE_CODE(CheckMemoryState(
- &state, &perm, &attribute, nullptr, addr, size, KMemoryState::FlagCanChangeAttribute,
+ // Verify we can change the memory attribute.
+ KMemoryState old_state;
+ KMemoryPermission old_perm;
+ KMemoryAttribute old_attr;
+ size_t num_allocator_blocks;
+ constexpr auto AttributeTestMask =
+ ~(KMemoryAttribute::SetMask | KMemoryAttribute::DeviceShared);
+ R_TRY(this->CheckMemoryState(
+ std::addressof(old_state), std::addressof(old_perm), std::addressof(old_attr),
+ std::addressof(num_allocator_blocks), addr, size, KMemoryState::FlagCanChangeAttribute,
KMemoryState::FlagCanChangeAttribute, KMemoryPermission::None, KMemoryPermission::None,
- KMemoryAttribute::LockedAndIpcLocked, KMemoryAttribute::None,
- KMemoryAttribute::DeviceSharedAndUncached));
+ AttributeTestMask, KMemoryAttribute::None, ~AttributeTestMask));
+
+ // Determine the new attribute.
+ const auto new_attr = ((old_attr & static_cast<KMemoryAttribute>(~mask)) |
+ static_cast<KMemoryAttribute>(attr & mask));
- attribute = attribute & ~mask;
- attribute = attribute | (mask & value);
+ // Perform operation.
+ this->Operate(addr, num_pages, old_perm, OperationType::ChangePermissionsAndRefresh);
- block_manager->Update(addr, size / PageSize, state, perm, attribute);
+ // Update the blocks.
+ block_manager->Update(addr, num_pages, old_state, old_perm, new_attr);
return ResultSuccess;
}