summaryrefslogtreecommitdiff
path: root/src/core/memory.cpp
diff options
context:
space:
mode:
authorGravatar liamwhite2023-11-30 09:20:55 -0500
committerGravatar GitHub2023-11-30 09:20:55 -0500
commit57a391e71db13ade7a3d96f59d53781eff18d2ac (patch)
tree0b4223de40a2d77598ac9095b1374353c2e9da7c /src/core/memory.cpp
parentMerge pull request #12223 from liamwhite/fruit-company (diff)
parentcore: Rename patcher file (diff)
downloadyuzu-57a391e71db13ade7a3d96f59d53781eff18d2ac.tar.gz
yuzu-57a391e71db13ade7a3d96f59d53781eff18d2ac.tar.xz
yuzu-57a391e71db13ade7a3d96f59d53781eff18d2ac.zip
Merge pull request #12074 from GPUCode/yuwu-on-the-metal
Implement Native Code Execution (NCE)
Diffstat (limited to 'src/core/memory.cpp')
-rw-r--r--src/core/memory.cpp71
1 files changed, 67 insertions, 4 deletions
diff --git a/src/core/memory.cpp b/src/core/memory.cpp
index a3431772a..5b376b202 100644
--- a/src/core/memory.cpp
+++ b/src/core/memory.cpp
@@ -53,7 +53,7 @@ struct Memory::Impl {
53 } 53 }
54 54
55 void MapMemoryRegion(Common::PageTable& page_table, Common::ProcessAddress base, u64 size, 55 void MapMemoryRegion(Common::PageTable& page_table, Common::ProcessAddress base, u64 size,
56 Common::PhysicalAddress target) { 56 Common::PhysicalAddress target, Common::MemoryPermission perms) {
57 ASSERT_MSG((size & YUZU_PAGEMASK) == 0, "non-page aligned size: {:016X}", size); 57 ASSERT_MSG((size & YUZU_PAGEMASK) == 0, "non-page aligned size: {:016X}", size);
58 ASSERT_MSG((base & YUZU_PAGEMASK) == 0, "non-page aligned base: {:016X}", GetInteger(base)); 58 ASSERT_MSG((base & YUZU_PAGEMASK) == 0, "non-page aligned base: {:016X}", GetInteger(base));
59 ASSERT_MSG(target >= DramMemoryMap::Base, "Out of bounds target: {:016X}", 59 ASSERT_MSG(target >= DramMemoryMap::Base, "Out of bounds target: {:016X}",
@@ -63,7 +63,7 @@ struct Memory::Impl {
63 63
64 if (Settings::IsFastmemEnabled()) { 64 if (Settings::IsFastmemEnabled()) {
65 system.DeviceMemory().buffer.Map(GetInteger(base), 65 system.DeviceMemory().buffer.Map(GetInteger(base),
66 GetInteger(target) - DramMemoryMap::Base, size); 66 GetInteger(target) - DramMemoryMap::Base, size, perms);
67 } 67 }
68 } 68 }
69 69
@@ -78,6 +78,51 @@ struct Memory::Impl {
78 } 78 }
79 } 79 }
80 80
81 void ProtectRegion(Common::PageTable& page_table, VAddr vaddr, u64 size,
82 Common::MemoryPermission perms) {
83 ASSERT_MSG((size & YUZU_PAGEMASK) == 0, "non-page aligned size: {:016X}", size);
84 ASSERT_MSG((vaddr & YUZU_PAGEMASK) == 0, "non-page aligned base: {:016X}", vaddr);
85
86 if (!Settings::IsFastmemEnabled()) {
87 return;
88 }
89
90 const bool is_r = True(perms & Common::MemoryPermission::Read);
91 const bool is_w = True(perms & Common::MemoryPermission::Write);
92 const bool is_x =
93 True(perms & Common::MemoryPermission::Execute) && Settings::IsNceEnabled();
94
95 if (!current_page_table) {
96 system.DeviceMemory().buffer.Protect(vaddr, size, is_r, is_w, is_x);
97 return;
98 }
99
100 u64 protect_bytes{};
101 u64 protect_begin{};
102 for (u64 addr = vaddr; addr < vaddr + size; addr += YUZU_PAGESIZE) {
103 const Common::PageType page_type{
104 current_page_table->pointers[addr >> YUZU_PAGEBITS].Type()};
105 switch (page_type) {
106 case Common::PageType::RasterizerCachedMemory:
107 if (protect_bytes > 0) {
108 system.DeviceMemory().buffer.Protect(protect_begin, protect_bytes, is_r, is_w,
109 is_x);
110 protect_bytes = 0;
111 }
112 break;
113 default:
114 if (protect_bytes == 0) {
115 protect_begin = addr;
116 }
117 protect_bytes += YUZU_PAGESIZE;
118 }
119 }
120
121 if (protect_bytes > 0) {
122 system.DeviceMemory().buffer.Protect(protect_begin, protect_bytes, is_r, is_w, is_x);
123 }
124 }
125
81 [[nodiscard]] u8* GetPointerFromRasterizerCachedMemory(u64 vaddr) const { 126 [[nodiscard]] u8* GetPointerFromRasterizerCachedMemory(u64 vaddr) const {
82 const Common::PhysicalAddress paddr{ 127 const Common::PhysicalAddress paddr{
83 current_page_table->backing_addr[vaddr >> YUZU_PAGEBITS]}; 128 current_page_table->backing_addr[vaddr >> YUZU_PAGEBITS]};
@@ -831,14 +876,19 @@ void Memory::SetCurrentPageTable(Kernel::KProcess& process, u32 core_id) {
831} 876}
832 877
833void Memory::MapMemoryRegion(Common::PageTable& page_table, Common::ProcessAddress base, u64 size, 878void Memory::MapMemoryRegion(Common::PageTable& page_table, Common::ProcessAddress base, u64 size,
834 Common::PhysicalAddress target) { 879 Common::PhysicalAddress target, Common::MemoryPermission perms) {
835 impl->MapMemoryRegion(page_table, base, size, target); 880 impl->MapMemoryRegion(page_table, base, size, target, perms);
836} 881}
837 882
838void Memory::UnmapRegion(Common::PageTable& page_table, Common::ProcessAddress base, u64 size) { 883void Memory::UnmapRegion(Common::PageTable& page_table, Common::ProcessAddress base, u64 size) {
839 impl->UnmapRegion(page_table, base, size); 884 impl->UnmapRegion(page_table, base, size);
840} 885}
841 886
887void Memory::ProtectRegion(Common::PageTable& page_table, Common::ProcessAddress vaddr, u64 size,
888 Common::MemoryPermission perms) {
889 impl->ProtectRegion(page_table, GetInteger(vaddr), size, perms);
890}
891
842bool Memory::IsValidVirtualAddress(const Common::ProcessAddress vaddr) const { 892bool Memory::IsValidVirtualAddress(const Common::ProcessAddress vaddr) const {
843 const Kernel::KProcess& process = *system.ApplicationProcess(); 893 const Kernel::KProcess& process = *system.ApplicationProcess();
844 const auto& page_table = process.GetPageTable().GetImpl(); 894 const auto& page_table = process.GetPageTable().GetImpl();
@@ -1001,4 +1051,17 @@ void Memory::FlushRegion(Common::ProcessAddress dest_addr, size_t size) {
1001 impl->FlushRegion(dest_addr, size); 1051 impl->FlushRegion(dest_addr, size);
1002} 1052}
1003 1053
1054bool Memory::InvalidateNCE(Common::ProcessAddress vaddr, size_t size) {
1055 bool mapped = true;
1056 u8* const ptr = impl->GetPointerImpl(
1057 GetInteger(vaddr),
1058 [&] {
1059 LOG_ERROR(HW_Memory, "Unmapped InvalidateNCE for {} bytes @ {:#x}", size,
1060 GetInteger(vaddr));
1061 mapped = false;
1062 },
1063 [&] { impl->system.GPU().InvalidateRegion(GetInteger(vaddr), size); });
1064 return mapped && ptr != nullptr;
1065}
1066
1004} // namespace Core::Memory 1067} // namespace Core::Memory