summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/common/settings.h1
-rw-r--r--src/core/arm/arm_interface.cpp8
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_32.cpp21
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_64.cpp21
-rw-r--r--src/yuzu/configuration/config.cpp2
-rw-r--r--src/yuzu/configuration/configure_cpu_debug.cpp4
-rw-r--r--src/yuzu/configuration/configure_cpu_debug.ui13
-rw-r--r--src/yuzu_cmd/config.cpp1
-rw-r--r--src/yuzu_cmd/default_ini.h4
9 files changed, 69 insertions, 6 deletions
diff --git a/src/common/settings.h b/src/common/settings.h
index 00e4421f7..c29d6f98b 100644
--- a/src/common/settings.h
+++ b/src/common/settings.h
@@ -399,6 +399,7 @@ struct Values {
399 Setting<bool> cpuopt_fastmem{true, "cpuopt_fastmem"}; 399 Setting<bool> cpuopt_fastmem{true, "cpuopt_fastmem"};
400 Setting<bool> cpuopt_fastmem_exclusives{true, "cpuopt_fastmem_exclusives"}; 400 Setting<bool> cpuopt_fastmem_exclusives{true, "cpuopt_fastmem_exclusives"};
401 Setting<bool> cpuopt_recompile_exclusives{true, "cpuopt_recompile_exclusives"}; 401 Setting<bool> cpuopt_recompile_exclusives{true, "cpuopt_recompile_exclusives"};
402 Setting<bool> cpuopt_ignore_memory_aborts{true, "cpuopt_ignore_memory_aborts"};
402 403
403 SwitchableSetting<bool> cpuopt_unsafe_unfuse_fma{true, "cpuopt_unsafe_unfuse_fma"}; 404 SwitchableSetting<bool> cpuopt_unsafe_unfuse_fma{true, "cpuopt_unsafe_unfuse_fma"};
404 SwitchableSetting<bool> cpuopt_unsafe_reduce_fp_error{true, "cpuopt_unsafe_reduce_fp_error"}; 405 SwitchableSetting<bool> cpuopt_unsafe_reduce_fp_error{true, "cpuopt_unsafe_reduce_fp_error"};
diff --git a/src/core/arm/arm_interface.cpp b/src/core/arm/arm_interface.cpp
index 29ba562dc..2df7b0ee8 100644
--- a/src/core/arm/arm_interface.cpp
+++ b/src/core/arm/arm_interface.cpp
@@ -145,11 +145,15 @@ void ARM_Interface::Run() {
145 // Notify the debugger and go to sleep if a breakpoint was hit, 145 // Notify the debugger and go to sleep if a breakpoint was hit,
146 // or if the thread is unable to continue for any reason. 146 // or if the thread is unable to continue for any reason.
147 if (Has(hr, breakpoint) || Has(hr, no_execute)) { 147 if (Has(hr, breakpoint) || Has(hr, no_execute)) {
148 RewindBreakpointInstruction(); 148 if (!Has(hr, no_execute)) {
149 RewindBreakpointInstruction();
150 }
149 if (system.DebuggerEnabled()) { 151 if (system.DebuggerEnabled()) {
150 system.GetDebugger().NotifyThreadStopped(current_thread); 152 system.GetDebugger().NotifyThreadStopped(current_thread);
153 } else {
154 LogBacktrace();
151 } 155 }
152 current_thread->RequestSuspend(Kernel::SuspendType::Debug); 156 current_thread->RequestSuspend(SuspendType::Debug);
153 break; 157 break;
154 } 158 }
155 159
diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp
index 227e06ea1..947747d36 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp
@@ -29,7 +29,9 @@ class DynarmicCallbacks32 : public Dynarmic::A32::UserCallbacks {
29public: 29public:
30 explicit DynarmicCallbacks32(ARM_Dynarmic_32& parent_) 30 explicit DynarmicCallbacks32(ARM_Dynarmic_32& parent_)
31 : parent{parent_}, 31 : parent{parent_},
32 memory(parent.system.Memory()), debugger_enabled{parent.system.DebuggerEnabled()} {} 32 memory(parent.system.Memory()), debugger_enabled{parent.system.DebuggerEnabled()},
33 check_memory_access{debugger_enabled ||
34 !Settings::values.cpuopt_ignore_memory_aborts.GetValue()} {}
33 35
34 u8 MemoryRead8(u32 vaddr) override { 36 u8 MemoryRead8(u32 vaddr) override {
35 CheckMemoryAccess(vaddr, 1, Kernel::DebugWatchpointType::Read); 37 CheckMemoryAccess(vaddr, 1, Kernel::DebugWatchpointType::Read);
@@ -154,6 +156,17 @@ public:
154 } 156 }
155 157
156 bool CheckMemoryAccess(VAddr addr, u64 size, Kernel::DebugWatchpointType type) { 158 bool CheckMemoryAccess(VAddr addr, u64 size, Kernel::DebugWatchpointType type) {
159 if (!check_memory_access) {
160 return true;
161 }
162
163 if (!memory.IsValidVirtualAddressRange(addr, size)) {
164 LOG_CRITICAL(Core_ARM, "Stopping execution due to unmapped memory access at {:#x}",
165 addr);
166 parent.jit.load()->HaltExecution(ARM_Interface::no_execute);
167 return false;
168 }
169
157 if (!debugger_enabled) { 170 if (!debugger_enabled) {
158 return true; 171 return true;
159 } 172 }
@@ -181,7 +194,8 @@ public:
181 ARM_Dynarmic_32& parent; 194 ARM_Dynarmic_32& parent;
182 Core::Memory::Memory& memory; 195 Core::Memory::Memory& memory;
183 std::size_t num_interpreted_instructions{}; 196 std::size_t num_interpreted_instructions{};
184 bool debugger_enabled{}; 197 const bool debugger_enabled{};
198 const bool check_memory_access{};
185 static constexpr u64 minimum_run_cycles = 10000U; 199 static constexpr u64 minimum_run_cycles = 10000U;
186}; 200};
187 201
@@ -264,6 +278,9 @@ std::shared_ptr<Dynarmic::A32::Jit> ARM_Dynarmic_32::MakeJit(Common::PageTable*
264 if (!Settings::values.cpuopt_recompile_exclusives) { 278 if (!Settings::values.cpuopt_recompile_exclusives) {
265 config.recompile_on_exclusive_fastmem_failure = false; 279 config.recompile_on_exclusive_fastmem_failure = false;
266 } 280 }
281 if (!Settings::values.cpuopt_ignore_memory_aborts) {
282 config.check_halt_on_memory_access = true;
283 }
267 } else { 284 } else {
268 // Unsafe optimizations 285 // Unsafe optimizations
269 if (Settings::values.cpu_accuracy.GetValue() == Settings::CPUAccuracy::Unsafe) { 286 if (Settings::values.cpu_accuracy.GetValue() == Settings::CPUAccuracy::Unsafe) {
diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp
index cb53d64ba..3df943df7 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp
@@ -29,7 +29,9 @@ class DynarmicCallbacks64 : public Dynarmic::A64::UserCallbacks {
29public: 29public:
30 explicit DynarmicCallbacks64(ARM_Dynarmic_64& parent_) 30 explicit DynarmicCallbacks64(ARM_Dynarmic_64& parent_)
31 : parent{parent_}, 31 : parent{parent_},
32 memory(parent.system.Memory()), debugger_enabled{parent.system.DebuggerEnabled()} {} 32 memory(parent.system.Memory()), debugger_enabled{parent.system.DebuggerEnabled()},
33 check_memory_access{debugger_enabled ||
34 !Settings::values.cpuopt_ignore_memory_aborts.GetValue()} {}
33 35
34 u8 MemoryRead8(u64 vaddr) override { 36 u8 MemoryRead8(u64 vaddr) override {
35 CheckMemoryAccess(vaddr, 1, Kernel::DebugWatchpointType::Read); 37 CheckMemoryAccess(vaddr, 1, Kernel::DebugWatchpointType::Read);
@@ -198,6 +200,17 @@ public:
198 } 200 }
199 201
200 bool CheckMemoryAccess(VAddr addr, u64 size, Kernel::DebugWatchpointType type) { 202 bool CheckMemoryAccess(VAddr addr, u64 size, Kernel::DebugWatchpointType type) {
203 if (!check_memory_access) {
204 return true;
205 }
206
207 if (!memory.IsValidVirtualAddressRange(addr, size)) {
208 LOG_CRITICAL(Core_ARM, "Stopping execution due to unmapped memory access at {:#x}",
209 addr);
210 parent.jit.load()->HaltExecution(ARM_Interface::no_execute);
211 return false;
212 }
213
201 if (!debugger_enabled) { 214 if (!debugger_enabled) {
202 return true; 215 return true;
203 } 216 }
@@ -226,7 +239,8 @@ public:
226 Core::Memory::Memory& memory; 239 Core::Memory::Memory& memory;
227 u64 tpidrro_el0 = 0; 240 u64 tpidrro_el0 = 0;
228 u64 tpidr_el0 = 0; 241 u64 tpidr_el0 = 0;
229 bool debugger_enabled{}; 242 const bool debugger_enabled{};
243 const bool check_memory_access{};
230 static constexpr u64 minimum_run_cycles = 10000U; 244 static constexpr u64 minimum_run_cycles = 10000U;
231}; 245};
232 246
@@ -323,6 +337,9 @@ std::shared_ptr<Dynarmic::A64::Jit> ARM_Dynarmic_64::MakeJit(Common::PageTable*
323 if (!Settings::values.cpuopt_recompile_exclusives) { 337 if (!Settings::values.cpuopt_recompile_exclusives) {
324 config.recompile_on_exclusive_fastmem_failure = false; 338 config.recompile_on_exclusive_fastmem_failure = false;
325 } 339 }
340 if (!Settings::values.cpuopt_ignore_memory_aborts) {
341 config.check_halt_on_memory_access = true;
342 }
326 } else { 343 } else {
327 // Unsafe optimizations 344 // Unsafe optimizations
328 if (Settings::values.cpu_accuracy.GetValue() == Settings::CPUAccuracy::Unsafe) { 345 if (Settings::values.cpu_accuracy.GetValue() == Settings::CPUAccuracy::Unsafe) {
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp
index 0c93df428..750285478 100644
--- a/src/yuzu/configuration/config.cpp
+++ b/src/yuzu/configuration/config.cpp
@@ -658,6 +658,7 @@ void Config::ReadCpuValues() {
658 ReadBasicSetting(Settings::values.cpuopt_fastmem); 658 ReadBasicSetting(Settings::values.cpuopt_fastmem);
659 ReadBasicSetting(Settings::values.cpuopt_fastmem_exclusives); 659 ReadBasicSetting(Settings::values.cpuopt_fastmem_exclusives);
660 ReadBasicSetting(Settings::values.cpuopt_recompile_exclusives); 660 ReadBasicSetting(Settings::values.cpuopt_recompile_exclusives);
661 ReadBasicSetting(Settings::values.cpuopt_ignore_memory_aborts);
661 } 662 }
662 663
663 qt_config->endGroup(); 664 qt_config->endGroup();
@@ -1257,6 +1258,7 @@ void Config::SaveCpuValues() {
1257 WriteBasicSetting(Settings::values.cpuopt_fastmem); 1258 WriteBasicSetting(Settings::values.cpuopt_fastmem);
1258 WriteBasicSetting(Settings::values.cpuopt_fastmem_exclusives); 1259 WriteBasicSetting(Settings::values.cpuopt_fastmem_exclusives);
1259 WriteBasicSetting(Settings::values.cpuopt_recompile_exclusives); 1260 WriteBasicSetting(Settings::values.cpuopt_recompile_exclusives);
1261 WriteBasicSetting(Settings::values.cpuopt_ignore_memory_aborts);
1260 } 1262 }
1261 1263
1262 qt_config->endGroup(); 1264 qt_config->endGroup();
diff --git a/src/yuzu/configuration/configure_cpu_debug.cpp b/src/yuzu/configuration/configure_cpu_debug.cpp
index 3c302ec16..8cfef0cc1 100644
--- a/src/yuzu/configuration/configure_cpu_debug.cpp
+++ b/src/yuzu/configuration/configure_cpu_debug.cpp
@@ -45,6 +45,9 @@ void ConfigureCpuDebug::SetConfiguration() {
45 ui->cpuopt_recompile_exclusives->setEnabled(runtime_lock); 45 ui->cpuopt_recompile_exclusives->setEnabled(runtime_lock);
46 ui->cpuopt_recompile_exclusives->setChecked( 46 ui->cpuopt_recompile_exclusives->setChecked(
47 Settings::values.cpuopt_recompile_exclusives.GetValue()); 47 Settings::values.cpuopt_recompile_exclusives.GetValue());
48 ui->cpuopt_ignore_memory_aborts->setEnabled(runtime_lock);
49 ui->cpuopt_ignore_memory_aborts->setChecked(
50 Settings::values.cpuopt_ignore_memory_aborts.GetValue());
48} 51}
49 52
50void ConfigureCpuDebug::ApplyConfiguration() { 53void ConfigureCpuDebug::ApplyConfiguration() {
@@ -59,6 +62,7 @@ void ConfigureCpuDebug::ApplyConfiguration() {
59 Settings::values.cpuopt_fastmem = ui->cpuopt_fastmem->isChecked(); 62 Settings::values.cpuopt_fastmem = ui->cpuopt_fastmem->isChecked();
60 Settings::values.cpuopt_fastmem_exclusives = ui->cpuopt_fastmem_exclusives->isChecked(); 63 Settings::values.cpuopt_fastmem_exclusives = ui->cpuopt_fastmem_exclusives->isChecked();
61 Settings::values.cpuopt_recompile_exclusives = ui->cpuopt_recompile_exclusives->isChecked(); 64 Settings::values.cpuopt_recompile_exclusives = ui->cpuopt_recompile_exclusives->isChecked();
65 Settings::values.cpuopt_ignore_memory_aborts = ui->cpuopt_ignore_memory_aborts->isChecked();
62} 66}
63 67
64void ConfigureCpuDebug::changeEvent(QEvent* event) { 68void ConfigureCpuDebug::changeEvent(QEvent* event) {
diff --git a/src/yuzu/configuration/configure_cpu_debug.ui b/src/yuzu/configuration/configure_cpu_debug.ui
index 2bc268810..3010f7fad 100644
--- a/src/yuzu/configuration/configure_cpu_debug.ui
+++ b/src/yuzu/configuration/configure_cpu_debug.ui
@@ -175,6 +175,19 @@
175 </property> 175 </property>
176 </widget> 176 </widget>
177 </item> 177 </item>
178 <item>
179 <widget class="QCheckBox" name="cpuopt_ignore_memory_aborts">
180 <property name="toolTip">
181 <string>
182 &lt;div style=&quot;white-space: nowrap&quot;&gt;This optimization speeds up memory accesses by allowing invalid memory accesses to succeed.&lt;/div&gt;
183 &lt;div style=&quot;white-space: nowrap&quot;&gt;Enabling it reduces the overhead of all memory accesses and has no impact on programs that don't access invalid memory.&lt;/div&gt;
184 </string>
185 </property>
186 <property name="text">
187 <string>Enable fallbacks for invalid memory accesses</string>
188 </property>
189 </widget>
190 </item>
178 </layout> 191 </layout>
179 </widget> 192 </widget>
180 </item> 193 </item>
diff --git a/src/yuzu_cmd/config.cpp b/src/yuzu_cmd/config.cpp
index 59f9c8e09..767b0d0e3 100644
--- a/src/yuzu_cmd/config.cpp
+++ b/src/yuzu_cmd/config.cpp
@@ -286,6 +286,7 @@ void Config::ReadValues() {
286 ReadSetting("Cpu", Settings::values.cpuopt_fastmem); 286 ReadSetting("Cpu", Settings::values.cpuopt_fastmem);
287 ReadSetting("Cpu", Settings::values.cpuopt_fastmem_exclusives); 287 ReadSetting("Cpu", Settings::values.cpuopt_fastmem_exclusives);
288 ReadSetting("Cpu", Settings::values.cpuopt_recompile_exclusives); 288 ReadSetting("Cpu", Settings::values.cpuopt_recompile_exclusives);
289 ReadSetting("Cpu", Settings::values.cpuopt_ignore_memory_aborts);
289 ReadSetting("Cpu", Settings::values.cpuopt_unsafe_unfuse_fma); 290 ReadSetting("Cpu", Settings::values.cpuopt_unsafe_unfuse_fma);
290 ReadSetting("Cpu", Settings::values.cpuopt_unsafe_reduce_fp_error); 291 ReadSetting("Cpu", Settings::values.cpuopt_unsafe_reduce_fp_error);
291 ReadSetting("Cpu", Settings::values.cpuopt_unsafe_ignore_standard_fpcr); 292 ReadSetting("Cpu", Settings::values.cpuopt_unsafe_ignore_standard_fpcr);
diff --git a/src/yuzu_cmd/default_ini.h b/src/yuzu_cmd/default_ini.h
index 5bbc3f532..6fcf04e1b 100644
--- a/src/yuzu_cmd/default_ini.h
+++ b/src/yuzu_cmd/default_ini.h
@@ -208,6 +208,10 @@ cpuopt_fastmem_exclusives =
208# 0: Disabled, 1 (default): Enabled 208# 0: Disabled, 1 (default): Enabled
209cpuopt_recompile_exclusives = 209cpuopt_recompile_exclusives =
210 210
211# Enable optimization to ignore invalid memory accesses (faster guest memory access)
212# 0: Disabled, 1 (default): Enabled
213cpuopt_ignore_memory_aborts =
214
211# Enable unfuse FMA (improve performance on CPUs without FMA) 215# Enable unfuse FMA (improve performance on CPUs without FMA)
212# Only enabled if cpu_accuracy is set to Unsafe. Automatically chosen with cpu_accuracy = Auto-select. 216# Only enabled if cpu_accuracy is set to Unsafe. Automatically chosen with cpu_accuracy = Auto-select.
213# 0: Disabled, 1 (default): Enabled 217# 0: Disabled, 1 (default): Enabled