diff options
author | bunnei <bunneidev@gmail.com> | 2022-01-08 12:16:59 +0100 |
---|---|---|
committer | bunnei <bunneidev@gmail.com> | 2022-01-08 21:18:14 +0100 |
commit | af4696657c5401b3cf352d34e2515d45ead2144d (patch) | |
tree | 7a7d0a7849364668cb4083cccc9ecaee9e73b2a6 /src/core/hle/kernel/k_page_table.cpp | |
parent | core: hle: kernel: k_page_table: Update CheckMemoryState. (diff) | |
download | yuzu-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.cpp | 38 |
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; } |