diff options
| author | 2023-11-23 11:26:06 +0200 | |
|---|---|---|
| committer | 2023-11-25 00:47:43 -0500 | |
| commit | 9ff8d0f3e652fee83d9f4374d9f6e0aa1759dd88 (patch) | |
| tree | d3bf69c51eab1e4c56db1615ecf5193aa76badcc /src | |
| parent | loader: apply nso patch to offset program image (diff) | |
| download | yuzu-9ff8d0f3e652fee83d9f4374d9f6e0aa1759dd88.tar.gz yuzu-9ff8d0f3e652fee83d9f4374d9f6e0aa1759dd88.tar.xz yuzu-9ff8d0f3e652fee83d9f4374d9f6e0aa1759dd88.zip | |
Address more review comments
Diffstat (limited to 'src')
| -rw-r--r-- | src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt | 4 | ||||
| -rw-r--r-- | src/android/app/src/main/res/values/arrays.xml | 12 | ||||
| -rw-r--r-- | src/android/app/src/main/res/values/strings.xml | 2 | ||||
| -rw-r--r-- | src/core/arm/nce/patch.cpp | 12 | ||||
| -rw-r--r-- | src/core/arm/nce/patch.h | 1 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_page_table_base.cpp | 11 | ||||
| -rw-r--r-- | src/core/memory.cpp | 50 | ||||
| -rw-r--r-- | src/core/memory.h | 11 |
8 files changed, 84 insertions, 19 deletions
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt index 1f090424b..e198b18a0 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt | |||
| @@ -82,8 +82,8 @@ abstract class SettingsItem( | |||
| 82 | IntSetting.CPU_BACKEND, | 82 | IntSetting.CPU_BACKEND, |
| 83 | R.string.cpu_backend, | 83 | R.string.cpu_backend, |
| 84 | 0, | 84 | 0, |
| 85 | R.array.cpuBackendNames, | 85 | R.array.cpuBackendArm64Names, |
| 86 | R.array.cpuBackendValues | 86 | R.array.cpuBackendArm64Values |
| 87 | ) | 87 | ) |
| 88 | ) | 88 | ) |
| 89 | put( | 89 | put( |
diff --git a/src/android/app/src/main/res/values/arrays.xml b/src/android/app/src/main/res/values/arrays.xml index 2756e5cc9..ab435dce9 100644 --- a/src/android/app/src/main/res/values/arrays.xml +++ b/src/android/app/src/main/res/values/arrays.xml | |||
| @@ -175,16 +175,24 @@ | |||
| 175 | <item>2</item> | 175 | <item>2</item> |
| 176 | </integer-array> | 176 | </integer-array> |
| 177 | 177 | ||
| 178 | <string-array name="cpuBackendNames"> | 178 | <string-array name="cpuBackendArm64Names"> |
| 179 | <item>@string/cpu_backend_dynarmic</item> | 179 | <item>@string/cpu_backend_dynarmic</item> |
| 180 | <item>@string/cpu_backend_nce</item> | 180 | <item>@string/cpu_backend_nce</item> |
| 181 | </string-array> | 181 | </string-array> |
| 182 | 182 | ||
| 183 | <integer-array name="cpuBackendValues"> | 183 | <integer-array name="cpuBackendArm64Values"> |
| 184 | <item>0</item> | 184 | <item>0</item> |
| 185 | <item>1</item> | 185 | <item>1</item> |
| 186 | </integer-array> | 186 | </integer-array> |
| 187 | 187 | ||
| 188 | <string-array name="cpuBackendX86Names"> | ||
| 189 | <item>@string/cpu_backend_dynarmic</item> | ||
| 190 | </string-array> | ||
| 191 | |||
| 192 | <integer-array name="cpuBackendX86Values"> | ||
| 193 | <item>0</item> | ||
| 194 | </integer-array> | ||
| 195 | |||
| 188 | <string-array name="cpuAccuracyNames"> | 196 | <string-array name="cpuAccuracyNames"> |
| 189 | <item>@string/auto</item> | 197 | <item>@string/auto</item> |
| 190 | <item>@string/cpu_accuracy_accurate</item> | 198 | <item>@string/cpu_accuracy_accurate</item> |
diff --git a/src/android/app/src/main/res/values/strings.xml b/src/android/app/src/main/res/values/strings.xml index f07121f6a..95b90fd6d 100644 --- a/src/android/app/src/main/res/values/strings.xml +++ b/src/android/app/src/main/res/values/strings.xml | |||
| @@ -185,7 +185,7 @@ | |||
| 185 | <string name="frame_limit_enable_description">Limits emulation speed to a specified percentage of normal speed.</string> | 185 | <string name="frame_limit_enable_description">Limits emulation speed to a specified percentage of normal speed.</string> |
| 186 | <string name="frame_limit_slider">Limit speed percent</string> | 186 | <string name="frame_limit_slider">Limit speed percent</string> |
| 187 | <string name="frame_limit_slider_description">Specifies the percentage to limit emulation speed. 100% is the normal speed. Values higher or lower will increase or decrease the speed limit.</string> | 187 | <string name="frame_limit_slider_description">Specifies the percentage to limit emulation speed. 100% is the normal speed. Values higher or lower will increase or decrease the speed limit.</string> |
| 188 | <string name="cpu_backend">CPU Backend</string> | 188 | <string name="cpu_backend">CPU backend</string> |
| 189 | <string name="cpu_accuracy">CPU accuracy</string> | 189 | <string name="cpu_accuracy">CPU accuracy</string> |
| 190 | <string name="value_with_units">%1$s%2$s</string> | 190 | <string name="value_with_units">%1$s%2$s</string> |
| 191 | 191 | ||
diff --git a/src/core/arm/nce/patch.cpp b/src/core/arm/nce/patch.cpp index 30c3c6cdd..a08859d0b 100644 --- a/src/core/arm/nce/patch.cpp +++ b/src/core/arm/nce/patch.cpp | |||
| @@ -90,6 +90,10 @@ void Patcher::PatchText(const Kernel::PhysicalMemory& program_image, | |||
| 90 | WriteMsrHandler(AddRelocations(), oaknut::XReg{static_cast<int>(msr.GetRt())}); | 90 | WriteMsrHandler(AddRelocations(), oaknut::XReg{static_cast<int>(msr.GetRt())}); |
| 91 | continue; | 91 | continue; |
| 92 | } | 92 | } |
| 93 | |||
| 94 | if (auto exclusive = Exclusive{inst}; exclusive.Verify()) { | ||
| 95 | m_exclusives.push_back(i); | ||
| 96 | } | ||
| 93 | } | 97 | } |
| 94 | 98 | ||
| 95 | // Determine patching mode for the final relocation step | 99 | // Determine patching mode for the final relocation step |
| @@ -163,11 +167,9 @@ void Patcher::RelocateAndCopy(Common::ProcessAddress load_base, | |||
| 163 | 167 | ||
| 164 | // Cortex-A57 seems to treat all exclusives as ordered, but newer processors do not. | 168 | // Cortex-A57 seems to treat all exclusives as ordered, but newer processors do not. |
| 165 | // Convert to ordered to preserve this assumption. | 169 | // Convert to ordered to preserve this assumption. |
| 166 | for (u32 i = ModuleCodeIndex; i < static_cast<u32>(text_words.size()); i++) { | 170 | for (const ModuleTextAddress i : m_exclusives) { |
| 167 | const u32 inst = text_words[i]; | 171 | auto exclusive = Exclusive{text_words[i]}; |
| 168 | if (auto exclusive = Exclusive{inst}; exclusive.Verify()) { | 172 | text_words[i] = exclusive.AsOrdered(); |
| 169 | text_words[i] = exclusive.AsOrdered(); | ||
| 170 | } | ||
| 171 | } | 173 | } |
| 172 | 174 | ||
| 173 | // Copy to program image | 175 | // Copy to program image |
diff --git a/src/core/arm/nce/patch.h b/src/core/arm/nce/patch.h index dcce1bfc6..112f839a4 100644 --- a/src/core/arm/nce/patch.h +++ b/src/core/arm/nce/patch.h | |||
| @@ -93,6 +93,7 @@ private: | |||
| 93 | std::vector<Relocation> m_branch_to_patch_relocations{}; | 93 | std::vector<Relocation> m_branch_to_patch_relocations{}; |
| 94 | std::vector<Relocation> m_branch_to_module_relocations{}; | 94 | std::vector<Relocation> m_branch_to_module_relocations{}; |
| 95 | std::vector<Relocation> m_write_module_pc_relocations{}; | 95 | std::vector<Relocation> m_write_module_pc_relocations{}; |
| 96 | std::vector<ModuleTextAddress> m_exclusives{}; | ||
| 96 | oaknut::Label m_save_context{}; | 97 | oaknut::Label m_save_context{}; |
| 97 | oaknut::Label m_load_context{}; | 98 | oaknut::Label m_load_context{}; |
| 98 | PatchMode mode{PatchMode::None}; | 99 | PatchMode mode{PatchMode::None}; |
diff --git a/src/core/hle/kernel/k_page_table_base.cpp b/src/core/hle/kernel/k_page_table_base.cpp index 2b5e77ccf..6691586ed 100644 --- a/src/core/hle/kernel/k_page_table_base.cpp +++ b/src/core/hle/kernel/k_page_table_base.cpp | |||
| @@ -5678,15 +5678,8 @@ Result KPageTableBase::Operate(PageLinkedList* page_list, KProcessAddress virt_a | |||
| 5678 | case OperationType::ChangePermissions: | 5678 | case OperationType::ChangePermissions: |
| 5679 | case OperationType::ChangePermissionsAndRefresh: | 5679 | case OperationType::ChangePermissionsAndRefresh: |
| 5680 | case OperationType::ChangePermissionsAndRefreshAndFlush: { | 5680 | case OperationType::ChangePermissionsAndRefreshAndFlush: { |
| 5681 | const bool read = True(properties.perm & Kernel::KMemoryPermission::UserRead); | 5681 | m_memory->ProtectRegion(*m_impl, virt_addr, num_pages * PageSize, |
| 5682 | const bool write = True(properties.perm & Kernel::KMemoryPermission::UserWrite); | 5682 | ConvertToMemoryPermission(properties.perm)); |
| 5683 | // todo: this doesn't really belong here and should go into m_memory to handle rasterizer | ||
| 5684 | // access todo: ignore exec on non-direct-mapped case | ||
| 5685 | const bool exec = True(properties.perm & Kernel::KMemoryPermission::UserExecute); | ||
| 5686 | if (Settings::IsFastmemEnabled()) { | ||
| 5687 | m_system.DeviceMemory().buffer.Protect(GetInteger(virt_addr), num_pages * PageSize, | ||
| 5688 | read, write, exec); | ||
| 5689 | } | ||
| 5690 | R_SUCCEED(); | 5683 | R_SUCCEED(); |
| 5691 | } | 5684 | } |
| 5692 | default: | 5685 | default: |
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(); |
diff --git a/src/core/memory.h b/src/core/memory.h index e5fbc0025..ed8ebb5eb 100644 --- a/src/core/memory.h +++ b/src/core/memory.h | |||
| @@ -98,6 +98,17 @@ public: | |||
| 98 | void UnmapRegion(Common::PageTable& page_table, Common::ProcessAddress base, u64 size); | 98 | void UnmapRegion(Common::PageTable& page_table, Common::ProcessAddress base, u64 size); |
| 99 | 99 | ||
| 100 | /** | 100 | /** |
| 101 | * Protects a region of the emulated process address space with the new permissions. | ||
| 102 | * | ||
| 103 | * @param page_table The page table of the emulated process. | ||
| 104 | * @param base The start address to re-protect. Must be page-aligned. | ||
| 105 | * @param size The amount of bytes to protect. Must be page-aligned. | ||
| 106 | * @param perms The permissions the address range is mapped. | ||
| 107 | */ | ||
| 108 | void ProtectRegion(Common::PageTable& page_table, Common::ProcessAddress base, u64 size, | ||
| 109 | Common::MemoryPermission perms); | ||
| 110 | |||
| 111 | /** | ||
| 101 | * Checks whether or not the supplied address is a valid virtual | 112 | * Checks whether or not the supplied address is a valid virtual |
| 102 | * address for the current process. | 113 | * address for the current process. |
| 103 | * | 114 | * |