summaryrefslogtreecommitdiff
path: root/src/core/memory.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/memory.cpp')
-rw-r--r--src/core/memory.cpp50
1 files changed, 50 insertions, 0 deletions
diff --git a/src/core/memory.cpp b/src/core/memory.cpp
index e5ca78ef4..5b376b202 100644
--- a/src/core/memory.cpp
+++ b/src/core/memory.cpp
@@ -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]};
@@ -839,6 +884,11 @@ void Memory::UnmapRegion(Common::PageTable& page_table, Common::ProcessAddress b
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();