diff options
| author | 2022-11-20 09:31:20 -0600 | |
|---|---|---|
| committer | 2022-11-20 09:31:20 -0600 | |
| commit | db7bcd51ae09c4ef25e08096de563903f61e2380 (patch) | |
| tree | 5ae9977b48e1aff118fae3ebffb215b0b4afa887 /src/core/memory.cpp | |
| parent | service: nfc: Implement nfc user (diff) | |
| parent | Merge pull request #9238 from german77/cabinet_applet (diff) | |
| download | yuzu-db7bcd51ae09c4ef25e08096de563903f61e2380.tar.gz yuzu-db7bcd51ae09c4ef25e08096de563903f61e2380.tar.xz yuzu-db7bcd51ae09c4ef25e08096de563903f61e2380.zip | |
Merge branch 'master' into nfc_impl
Diffstat (limited to 'src/core/memory.cpp')
| -rw-r--r-- | src/core/memory.cpp | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 3ca80c8ff..3141122f1 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp | |||
| @@ -6,6 +6,7 @@ | |||
| 6 | 6 | ||
| 7 | #include "common/assert.h" | 7 | #include "common/assert.h" |
| 8 | #include "common/atomic_ops.h" | 8 | #include "common/atomic_ops.h" |
| 9 | #include "common/cache_management.h" | ||
| 9 | #include "common/common_types.h" | 10 | #include "common/common_types.h" |
| 10 | #include "common/logging/log.h" | 11 | #include "common/logging/log.h" |
| 11 | #include "common/page_table.h" | 12 | #include "common/page_table.h" |
| @@ -329,6 +330,55 @@ struct Memory::Impl { | |||
| 329 | }); | 330 | }); |
| 330 | } | 331 | } |
| 331 | 332 | ||
| 333 | template <typename Callback> | ||
| 334 | Result PerformCacheOperation(const Kernel::KProcess& process, VAddr dest_addr, std::size_t size, | ||
| 335 | Callback&& cb) { | ||
| 336 | class InvalidMemoryException : public std::exception {}; | ||
| 337 | |||
| 338 | try { | ||
| 339 | WalkBlock( | ||
| 340 | process, dest_addr, size, | ||
| 341 | [&](const std::size_t block_size, const VAddr current_vaddr) { | ||
| 342 | LOG_ERROR(HW_Memory, "Unmapped cache maintenance @ {:#018X}", current_vaddr); | ||
| 343 | throw InvalidMemoryException(); | ||
| 344 | }, | ||
| 345 | [&](const std::size_t block_size, u8* const host_ptr) { cb(block_size, host_ptr); }, | ||
| 346 | [&](const VAddr current_vaddr, const std::size_t block_size, u8* const host_ptr) { | ||
| 347 | system.GPU().FlushRegion(current_vaddr, block_size); | ||
| 348 | cb(block_size, host_ptr); | ||
| 349 | }, | ||
| 350 | [](const std::size_t block_size) {}); | ||
| 351 | } catch (InvalidMemoryException&) { | ||
| 352 | return Kernel::ResultInvalidCurrentMemory; | ||
| 353 | } | ||
| 354 | |||
| 355 | return ResultSuccess; | ||
| 356 | } | ||
| 357 | |||
| 358 | Result InvalidateDataCache(const Kernel::KProcess& process, VAddr dest_addr, std::size_t size) { | ||
| 359 | auto perform = [&](const std::size_t block_size, u8* const host_ptr) { | ||
| 360 | // Do nothing; this operation (dc ivac) cannot be supported | ||
| 361 | // from EL0 | ||
| 362 | }; | ||
| 363 | return PerformCacheOperation(process, dest_addr, size, perform); | ||
| 364 | } | ||
| 365 | |||
| 366 | Result StoreDataCache(const Kernel::KProcess& process, VAddr dest_addr, std::size_t size) { | ||
| 367 | auto perform = [&](const std::size_t block_size, u8* const host_ptr) { | ||
| 368 | // dc cvac: Store to point of coherency | ||
| 369 | Common::DataCacheLineCleanByVAToPoC(host_ptr, block_size); | ||
| 370 | }; | ||
| 371 | return PerformCacheOperation(process, dest_addr, size, perform); | ||
| 372 | } | ||
| 373 | |||
| 374 | Result FlushDataCache(const Kernel::KProcess& process, VAddr dest_addr, std::size_t size) { | ||
| 375 | auto perform = [&](const std::size_t block_size, u8* const host_ptr) { | ||
| 376 | // dc civac: Store to point of coherency, and invalidate from cache | ||
| 377 | Common::DataCacheLineCleanAndInvalidateByVAToPoC(host_ptr, block_size); | ||
| 378 | }; | ||
| 379 | return PerformCacheOperation(process, dest_addr, size, perform); | ||
| 380 | } | ||
| 381 | |||
| 332 | void MarkRegionDebug(VAddr vaddr, u64 size, bool debug) { | 382 | void MarkRegionDebug(VAddr vaddr, u64 size, bool debug) { |
| 333 | if (vaddr == 0) { | 383 | if (vaddr == 0) { |
| 334 | return; | 384 | return; |
| @@ -786,6 +836,21 @@ void Memory::ZeroBlock(const Kernel::KProcess& process, VAddr dest_addr, const s | |||
| 786 | impl->ZeroBlock(process, dest_addr, size); | 836 | impl->ZeroBlock(process, dest_addr, size); |
| 787 | } | 837 | } |
| 788 | 838 | ||
| 839 | Result Memory::InvalidateDataCache(const Kernel::KProcess& process, VAddr dest_addr, | ||
| 840 | const std::size_t size) { | ||
| 841 | return impl->InvalidateDataCache(process, dest_addr, size); | ||
| 842 | } | ||
| 843 | |||
| 844 | Result Memory::StoreDataCache(const Kernel::KProcess& process, VAddr dest_addr, | ||
| 845 | const std::size_t size) { | ||
| 846 | return impl->StoreDataCache(process, dest_addr, size); | ||
| 847 | } | ||
| 848 | |||
| 849 | Result Memory::FlushDataCache(const Kernel::KProcess& process, VAddr dest_addr, | ||
| 850 | const std::size_t size) { | ||
| 851 | return impl->FlushDataCache(process, dest_addr, size); | ||
| 852 | } | ||
| 853 | |||
| 789 | void Memory::RasterizerMarkRegionCached(VAddr vaddr, u64 size, bool cached) { | 854 | void Memory::RasterizerMarkRegionCached(VAddr vaddr, u64 size, bool cached) { |
| 790 | impl->RasterizerMarkRegionCached(vaddr, size, cached); | 855 | impl->RasterizerMarkRegionCached(vaddr, size, cached); |
| 791 | } | 856 | } |