summaryrefslogtreecommitdiff
path: root/src/core/memory.cpp
diff options
context:
space:
mode:
authorGravatar Ameer2020-07-04 00:59:40 -0400
committerGravatar Ameer2020-07-04 00:59:40 -0400
commitf829932ed191ad469df01342191bf2725e8a20bb (patch)
tree0ae185ce3ef43ef9b085aae7b9ad5abb04e3d239 /src/core/memory.cpp
parentFix for always firing triggers on some controllers, trigger threshold more un... (diff)
parentMerge pull request #4218 from ogniK5377/opus-external (diff)
downloadyuzu-f829932ed191ad469df01342191bf2725e8a20bb.tar.gz
yuzu-f829932ed191ad469df01342191bf2725e8a20bb.tar.xz
yuzu-f829932ed191ad469df01342191bf2725e8a20bb.zip
Fix merge conflicts?
Diffstat (limited to 'src/core/memory.cpp')
-rw-r--r--src/core/memory.cpp109
1 files changed, 102 insertions, 7 deletions
diff --git a/src/core/memory.cpp b/src/core/memory.cpp
index 9d87045a0..7def00768 100644
--- a/src/core/memory.cpp
+++ b/src/core/memory.cpp
@@ -8,6 +8,7 @@
8#include <utility> 8#include <utility>
9 9
10#include "common/assert.h" 10#include "common/assert.h"
11#include "common/atomic_ops.h"
11#include "common/common_types.h" 12#include "common/common_types.h"
12#include "common/logging/log.h" 13#include "common/logging/log.h"
13#include "common/page_table.h" 14#include "common/page_table.h"
@@ -29,15 +30,12 @@ namespace Core::Memory {
29struct Memory::Impl { 30struct Memory::Impl {
30 explicit Impl(Core::System& system_) : system{system_} {} 31 explicit Impl(Core::System& system_) : system{system_} {}
31 32
32 void SetCurrentPageTable(Kernel::Process& process) { 33 void SetCurrentPageTable(Kernel::Process& process, u32 core_id) {
33 current_page_table = &process.PageTable().PageTableImpl(); 34 current_page_table = &process.PageTable().PageTableImpl();
34 35
35 const std::size_t address_space_width = process.PageTable().GetAddressSpaceWidth(); 36 const std::size_t address_space_width = process.PageTable().GetAddressSpaceWidth();
36 37
37 system.ArmInterface(0).PageTableChanged(*current_page_table, address_space_width); 38 system.ArmInterface(core_id).PageTableChanged(*current_page_table, address_space_width);
38 system.ArmInterface(1).PageTableChanged(*current_page_table, address_space_width);
39 system.ArmInterface(2).PageTableChanged(*current_page_table, address_space_width);
40 system.ArmInterface(3).PageTableChanged(*current_page_table, address_space_width);
41 } 39 }
42 40
43 void MapMemoryRegion(Common::PageTable& page_table, VAddr base, u64 size, PAddr target) { 41 void MapMemoryRegion(Common::PageTable& page_table, VAddr base, u64 size, PAddr target) {
@@ -179,6 +177,22 @@ struct Memory::Impl {
179 } 177 }
180 } 178 }
181 179
180 bool WriteExclusive8(const VAddr addr, const u8 data, const u8 expected) {
181 return WriteExclusive<u8>(addr, data, expected);
182 }
183
184 bool WriteExclusive16(const VAddr addr, const u16 data, const u16 expected) {
185 return WriteExclusive<u16_le>(addr, data, expected);
186 }
187
188 bool WriteExclusive32(const VAddr addr, const u32 data, const u32 expected) {
189 return WriteExclusive<u32_le>(addr, data, expected);
190 }
191
192 bool WriteExclusive64(const VAddr addr, const u64 data, const u64 expected) {
193 return WriteExclusive<u64_le>(addr, data, expected);
194 }
195
182 std::string ReadCString(VAddr vaddr, std::size_t max_length) { 196 std::string ReadCString(VAddr vaddr, std::size_t max_length) {
183 std::string string; 197 std::string string;
184 string.reserve(max_length); 198 string.reserve(max_length);
@@ -682,6 +696,67 @@ struct Memory::Impl {
682 } 696 }
683 } 697 }
684 698
699 template <typename T>
700 bool WriteExclusive(const VAddr vaddr, const T data, const T expected) {
701 u8* page_pointer = current_page_table->pointers[vaddr >> PAGE_BITS];
702 if (page_pointer != nullptr) {
703 // NOTE: Avoid adding any extra logic to this fast-path block
704 T volatile* pointer = reinterpret_cast<T volatile*>(&page_pointer[vaddr]);
705 return Common::AtomicCompareAndSwap(pointer, data, expected);
706 }
707
708 const Common::PageType type = current_page_table->attributes[vaddr >> PAGE_BITS];
709 switch (type) {
710 case Common::PageType::Unmapped:
711 LOG_ERROR(HW_Memory, "Unmapped Write{} 0x{:08X} @ 0x{:016X}", sizeof(data) * 8,
712 static_cast<u32>(data), vaddr);
713 return true;
714 case Common::PageType::Memory:
715 ASSERT_MSG(false, "Mapped memory page without a pointer @ {:016X}", vaddr);
716 break;
717 case Common::PageType::RasterizerCachedMemory: {
718 u8* host_ptr{GetPointerFromRasterizerCachedMemory(vaddr)};
719 system.GPU().InvalidateRegion(vaddr, sizeof(T));
720 T volatile* pointer = reinterpret_cast<T volatile*>(&host_ptr);
721 return Common::AtomicCompareAndSwap(pointer, data, expected);
722 break;
723 }
724 default:
725 UNREACHABLE();
726 }
727 return true;
728 }
729
730 bool WriteExclusive128(const VAddr vaddr, const u128 data, const u128 expected) {
731 u8* const page_pointer = current_page_table->pointers[vaddr >> PAGE_BITS];
732 if (page_pointer != nullptr) {
733 // NOTE: Avoid adding any extra logic to this fast-path block
734 u64 volatile* pointer = reinterpret_cast<u64 volatile*>(&page_pointer[vaddr]);
735 return Common::AtomicCompareAndSwap(pointer, data, expected);
736 }
737
738 const Common::PageType type = current_page_table->attributes[vaddr >> PAGE_BITS];
739 switch (type) {
740 case Common::PageType::Unmapped:
741 LOG_ERROR(HW_Memory, "Unmapped Write{} 0x{:08X} @ 0x{:016X}{:016X}", sizeof(data) * 8,
742 static_cast<u64>(data[1]), static_cast<u64>(data[0]), vaddr);
743 return true;
744 case Common::PageType::Memory:
745 ASSERT_MSG(false, "Mapped memory page without a pointer @ {:016X}", vaddr);
746 break;
747 case Common::PageType::RasterizerCachedMemory: {
748 u8* host_ptr{GetPointerFromRasterizerCachedMemory(vaddr)};
749 system.GPU().InvalidateRegion(vaddr, sizeof(u128));
750 u64 volatile* pointer = reinterpret_cast<u64 volatile*>(&host_ptr);
751 return Common::AtomicCompareAndSwap(pointer, data, expected);
752 break;
753 }
754 default:
755 UNREACHABLE();
756 }
757 return true;
758 }
759
685 Common::PageTable* current_page_table = nullptr; 760 Common::PageTable* current_page_table = nullptr;
686 Core::System& system; 761 Core::System& system;
687}; 762};
@@ -689,8 +764,8 @@ struct Memory::Impl {
689Memory::Memory(Core::System& system) : impl{std::make_unique<Impl>(system)} {} 764Memory::Memory(Core::System& system) : impl{std::make_unique<Impl>(system)} {}
690Memory::~Memory() = default; 765Memory::~Memory() = default;
691 766
692void Memory::SetCurrentPageTable(Kernel::Process& process) { 767void Memory::SetCurrentPageTable(Kernel::Process& process, u32 core_id) {
693 impl->SetCurrentPageTable(process); 768 impl->SetCurrentPageTable(process, core_id);
694} 769}
695 770
696void Memory::MapMemoryRegion(Common::PageTable& page_table, VAddr base, u64 size, PAddr target) { 771void Memory::MapMemoryRegion(Common::PageTable& page_table, VAddr base, u64 size, PAddr target) {
@@ -764,6 +839,26 @@ void Memory::Write64(VAddr addr, u64 data) {
764 impl->Write64(addr, data); 839 impl->Write64(addr, data);
765} 840}
766 841
842bool Memory::WriteExclusive8(VAddr addr, u8 data, u8 expected) {
843 return impl->WriteExclusive8(addr, data, expected);
844}
845
846bool Memory::WriteExclusive16(VAddr addr, u16 data, u16 expected) {
847 return impl->WriteExclusive16(addr, data, expected);
848}
849
850bool Memory::WriteExclusive32(VAddr addr, u32 data, u32 expected) {
851 return impl->WriteExclusive32(addr, data, expected);
852}
853
854bool Memory::WriteExclusive64(VAddr addr, u64 data, u64 expected) {
855 return impl->WriteExclusive64(addr, data, expected);
856}
857
858bool Memory::WriteExclusive128(VAddr addr, u128 data, u128 expected) {
859 return impl->WriteExclusive128(addr, data, expected);
860}
861
767std::string Memory::ReadCString(VAddr vaddr, std::size_t max_length) { 862std::string Memory::ReadCString(VAddr vaddr, std::size_t max_length) {
768 return impl->ReadCString(vaddr, max_length); 863 return impl->ReadCString(vaddr, max_length);
769} 864}