diff options
Diffstat (limited to 'src/core/memory.cpp')
| -rw-r--r-- | src/core/memory.cpp | 54 |
1 files changed, 49 insertions, 5 deletions
diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 257406f09..805963178 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp | |||
| @@ -266,6 +266,22 @@ struct Memory::Impl { | |||
| 266 | ReadBlockImpl<true>(*system.ApplicationProcess(), src_addr, dest_buffer, size); | 266 | ReadBlockImpl<true>(*system.ApplicationProcess(), src_addr, dest_buffer, size); |
| 267 | } | 267 | } |
| 268 | 268 | ||
| 269 | const u8* GetSpan(const VAddr src_addr, const std::size_t size) const { | ||
| 270 | if (current_page_table->blocks[src_addr >> YUZU_PAGEBITS] == | ||
| 271 | current_page_table->blocks[(src_addr + size) >> YUZU_PAGEBITS]) { | ||
| 272 | return GetPointerSilent(src_addr); | ||
| 273 | } | ||
| 274 | return nullptr; | ||
| 275 | } | ||
| 276 | |||
| 277 | u8* GetSpan(const VAddr src_addr, const std::size_t size) { | ||
| 278 | if (current_page_table->blocks[src_addr >> YUZU_PAGEBITS] == | ||
| 279 | current_page_table->blocks[(src_addr + size) >> YUZU_PAGEBITS]) { | ||
| 280 | return GetPointerSilent(src_addr); | ||
| 281 | } | ||
| 282 | return nullptr; | ||
| 283 | } | ||
| 284 | |||
| 269 | template <bool UNSAFE> | 285 | template <bool UNSAFE> |
| 270 | void WriteBlockImpl(const Kernel::KProcess& process, const Common::ProcessAddress dest_addr, | 286 | void WriteBlockImpl(const Kernel::KProcess& process, const Common::ProcessAddress dest_addr, |
| 271 | const void* src_buffer, const std::size_t size) { | 287 | const void* src_buffer, const std::size_t size) { |
| @@ -559,7 +575,7 @@ struct Memory::Impl { | |||
| 559 | } | 575 | } |
| 560 | } | 576 | } |
| 561 | 577 | ||
| 562 | const Common::ProcessAddress end = base + size; | 578 | const auto end = base + size; |
| 563 | ASSERT_MSG(end <= page_table.pointers.size(), "out of range mapping at {:016X}", | 579 | ASSERT_MSG(end <= page_table.pointers.size(), "out of range mapping at {:016X}", |
| 564 | base + page_table.pointers.size()); | 580 | base + page_table.pointers.size()); |
| 565 | 581 | ||
| @@ -570,14 +586,18 @@ struct Memory::Impl { | |||
| 570 | while (base != end) { | 586 | while (base != end) { |
| 571 | page_table.pointers[base].Store(nullptr, type); | 587 | page_table.pointers[base].Store(nullptr, type); |
| 572 | page_table.backing_addr[base] = 0; | 588 | page_table.backing_addr[base] = 0; |
| 573 | 589 | page_table.blocks[base] = 0; | |
| 574 | base += 1; | 590 | base += 1; |
| 575 | } | 591 | } |
| 576 | } else { | 592 | } else { |
| 593 | auto orig_base = base; | ||
| 577 | while (base != end) { | 594 | while (base != end) { |
| 578 | page_table.pointers[base].Store( | 595 | auto host_ptr = |
| 579 | system.DeviceMemory().GetPointer<u8>(target) - (base << YUZU_PAGEBITS), type); | 596 | system.DeviceMemory().GetPointer<u8>(target) - (base << YUZU_PAGEBITS); |
| 580 | page_table.backing_addr[base] = GetInteger(target) - (base << YUZU_PAGEBITS); | 597 | auto backing = GetInteger(target) - (base << YUZU_PAGEBITS); |
| 598 | page_table.pointers[base].Store(host_ptr, type); | ||
| 599 | page_table.backing_addr[base] = backing; | ||
| 600 | page_table.blocks[base] = orig_base << YUZU_PAGEBITS; | ||
| 581 | 601 | ||
| 582 | ASSERT_MSG(page_table.pointers[base].Pointer(), | 602 | ASSERT_MSG(page_table.pointers[base].Pointer(), |
| 583 | "memory mapping base yield a nullptr within the table"); | 603 | "memory mapping base yield a nullptr within the table"); |
| @@ -747,6 +767,14 @@ struct Memory::Impl { | |||
| 747 | VAddr last_address; | 767 | VAddr last_address; |
| 748 | }; | 768 | }; |
| 749 | 769 | ||
| 770 | void InvalidateRegion(Common::ProcessAddress dest_addr, size_t size) { | ||
| 771 | system.GPU().InvalidateRegion(GetInteger(dest_addr), size); | ||
| 772 | } | ||
| 773 | |||
| 774 | void FlushRegion(Common::ProcessAddress dest_addr, size_t size) { | ||
| 775 | system.GPU().FlushRegion(GetInteger(dest_addr), size); | ||
| 776 | } | ||
| 777 | |||
| 750 | Core::System& system; | 778 | Core::System& system; |
| 751 | Common::PageTable* current_page_table = nullptr; | 779 | Common::PageTable* current_page_table = nullptr; |
| 752 | std::array<VideoCore::RasterizerDownloadArea, Core::Hardware::NUM_CPU_CORES> | 780 | std::array<VideoCore::RasterizerDownloadArea, Core::Hardware::NUM_CPU_CORES> |
| @@ -881,6 +909,14 @@ void Memory::ReadBlockUnsafe(const Common::ProcessAddress src_addr, void* dest_b | |||
| 881 | impl->ReadBlockUnsafe(src_addr, dest_buffer, size); | 909 | impl->ReadBlockUnsafe(src_addr, dest_buffer, size); |
| 882 | } | 910 | } |
| 883 | 911 | ||
| 912 | const u8* Memory::GetSpan(const VAddr src_addr, const std::size_t size) const { | ||
| 913 | return impl->GetSpan(src_addr, size); | ||
| 914 | } | ||
| 915 | |||
| 916 | u8* Memory::GetSpan(const VAddr src_addr, const std::size_t size) { | ||
| 917 | return impl->GetSpan(src_addr, size); | ||
| 918 | } | ||
| 919 | |||
| 884 | void Memory::WriteBlock(const Common::ProcessAddress dest_addr, const void* src_buffer, | 920 | void Memory::WriteBlock(const Common::ProcessAddress dest_addr, const void* src_buffer, |
| 885 | const std::size_t size) { | 921 | const std::size_t size) { |
| 886 | impl->WriteBlock(dest_addr, src_buffer, size); | 922 | impl->WriteBlock(dest_addr, src_buffer, size); |
| @@ -924,4 +960,12 @@ void Memory::MarkRegionDebug(Common::ProcessAddress vaddr, u64 size, bool debug) | |||
| 924 | impl->MarkRegionDebug(GetInteger(vaddr), size, debug); | 960 | impl->MarkRegionDebug(GetInteger(vaddr), size, debug); |
| 925 | } | 961 | } |
| 926 | 962 | ||
| 963 | void Memory::InvalidateRegion(Common::ProcessAddress dest_addr, size_t size) { | ||
| 964 | impl->InvalidateRegion(dest_addr, size); | ||
| 965 | } | ||
| 966 | |||
| 967 | void Memory::FlushRegion(Common::ProcessAddress dest_addr, size_t size) { | ||
| 968 | impl->FlushRegion(dest_addr, size); | ||
| 969 | } | ||
| 970 | |||
| 927 | } // namespace Core::Memory | 971 | } // namespace Core::Memory |