diff options
Diffstat (limited to 'src/core/memory.cpp')
| -rw-r--r-- | src/core/memory.cpp | 50 |
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 | ||
| 887 | void 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 | |||
| 842 | bool Memory::IsValidVirtualAddress(const Common::ProcessAddress vaddr) const { | 892 | bool 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(); |