summaryrefslogtreecommitdiffstats
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 c0620066c..29b730cff 100644
--- a/src/common/settings.h
+++ b/src/common/settings.h
@@ -400,6 +400,7 @@ struct Values {
Setting<bool> cpuopt_fastmem{true, "cpuopt_fastmem"};
Setting<bool> cpuopt_fastmem_exclusives{true, "cpuopt_fastmem_exclusives"};
Setting<bool> cpuopt_recompile_exclusives{true, "cpuopt_recompile_exclusives"};
+ Setting<bool> cpuopt_ignore_memory_aborts{true, "cpuopt_ignore_memory_aborts"};
SwitchableSetting<bool> cpuopt_unsafe_unfuse_fma{true, "cpuopt_unsafe_unfuse_fma"};
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() {
// Notify the debugger and go to sleep if a breakpoint was hit,
// or if the thread is unable to continue for any reason.
if (Has(hr, breakpoint) || Has(hr, no_execute)) {
- RewindBreakpointInstruction();
+ if (!Has(hr, no_execute)) {
+ RewindBreakpointInstruction();
+ }
if (system.DebuggerEnabled()) {
system.GetDebugger().NotifyThreadStopped(current_thread);
+ } else {
+ LogBacktrace();
}
- current_thread->RequestSuspend(Kernel::SuspendType::Debug);
+ current_thread->RequestSuspend(SuspendType::Debug);
break;
}
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 {
public:
explicit DynarmicCallbacks32(ARM_Dynarmic_32& parent_)
: parent{parent_},
- memory(parent.system.Memory()), debugger_enabled{parent.system.DebuggerEnabled()} {}
+ memory(parent.system.Memory()), debugger_enabled{parent.system.DebuggerEnabled()},
+ check_memory_access{debugger_enabled ||
+ !Settings::values.cpuopt_ignore_memory_aborts.GetValue()} {}
u8 MemoryRead8(u32 vaddr) override {
CheckMemoryAccess(vaddr, 1, Kernel::DebugWatchpointType::Read);
@@ -154,6 +156,17 @@ public:
}
bool CheckMemoryAccess(VAddr addr, u64 size, Kernel::DebugWatchpointType type) {
+ if (!check_memory_access) {
+ return true;
+ }
+
+ if (!memory.IsValidVirtualAddressRange(addr, size)) {
+ LOG_CRITICAL(Core_ARM, "Stopping execution due to unmapped memory access at {:#x}",
+ addr);
+ parent.jit.load()->HaltExecution(ARM_Interface::no_execute);
+ return false;
+ }
+
if (!debugger_enabled) {
return true;
}
@@ -181,7 +194,8 @@ public:
ARM_Dynarmic_32& parent;
Core::Memory::Memory& memory;
std::size_t num_interpreted_instructions{};
- bool debugger_enabled{};
+ const bool debugger_enabled{};
+ const bool check_memory_access{};
static constexpr u64 minimum_run_cycles = 10000U;
};
@@ -264,6 +278,9 @@ std::shared_ptr<Dynarmic::A32::Jit> ARM_Dynarmic_32::MakeJit(Common::PageTable*
if (!Settings::values.cpuopt_recompile_exclusives) {
config.recompile_on_exclusive_fastmem_failure = false;
}
+ if (!Settings::values.cpuopt_ignore_memory_aborts) {
+ config.check_halt_on_memory_access = true;
+ }
} else {
// Unsafe optimizations
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 {
public:
explicit DynarmicCallbacks64(ARM_Dynarmic_64& parent_)
: parent{parent_},
- memory(parent.system.Memory()), debugger_enabled{parent.system.DebuggerEnabled()} {}
+ memory(parent.system.Memory()), debugger_enabled{parent.system.DebuggerEnabled()},
+ check_memory_access{debugger_enabled ||
+ !Settings::values.cpuopt_ignore_memory_aborts.GetValue()} {}
u8 MemoryRead8(u64 vaddr) override {
CheckMemoryAccess(vaddr, 1, Kernel::DebugWatchpointType::Read);
@@ -198,6 +200,17 @@ public:
}
bool CheckMemoryAccess(VAddr addr, u64 size, Kernel::DebugWatchpointType type) {
+ if (!check_memory_access) {
+ return true;
+ }
+
+ if (!memory.IsValidVirtualAddressRange(addr, size)) {
+ LOG_CRITICAL(Core_ARM, "Stopping execution due to unmapped memory access at {:#x}",
+ addr);
+ parent.jit.load()->HaltExecution(ARM_Interface::no_execute);
+ return false;
+ }
+
if (!debugger_enabled) {
return true;
}
@@ -226,7 +239,8 @@ public:
Core::Memory::Memory& memory;
u64 tpidrro_el0 = 0;
u64 tpidr_el0 = 0;
- bool debugger_enabled{};
+ const bool debugger_enabled{};
+ const bool check_memory_access{};
static constexpr u64 minimum_run_cycles = 10000U;
};
@@ -323,6 +337,9 @@ std::shared_ptr<Dynarmic::A64::Jit> ARM_Dynarmic_64::MakeJit(Common::PageTable*
if (!Settings::values.cpuopt_recompile_exclusives) {
config.recompile_on_exclusive_fastmem_failure = false;
}
+ if (!Settings::values.cpuopt_ignore_memory_aborts) {
+ config.check_halt_on_memory_access = true;
+ }
} else {
// Unsafe optimizations
if (Settings::values.cpu_accuracy.GetValue() == Settings::CPUAccuracy::Unsafe) {
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp
index c11d1c8b3..722fc708e 100644
--- a/src/yuzu/configuration/config.cpp
+++ b/src/yuzu/configuration/config.cpp
@@ -679,6 +679,7 @@ void Config::ReadCpuValues() {
ReadBasicSetting(Settings::values.cpuopt_fastmem);
ReadBasicSetting(Settings::values.cpuopt_fastmem_exclusives);
ReadBasicSetting(Settings::values.cpuopt_recompile_exclusives);
+ ReadBasicSetting(Settings::values.cpuopt_ignore_memory_aborts);
}
qt_config->endGroup();
@@ -1291,6 +1292,7 @@ void Config::SaveCpuValues() {
WriteBasicSetting(Settings::values.cpuopt_fastmem);
WriteBasicSetting(Settings::values.cpuopt_fastmem_exclusives);
WriteBasicSetting(Settings::values.cpuopt_recompile_exclusives);
+ WriteBasicSetting(Settings::values.cpuopt_ignore_memory_aborts);
}
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() {
ui->cpuopt_recompile_exclusives->setEnabled(runtime_lock);
ui->cpuopt_recompile_exclusives->setChecked(
Settings::values.cpuopt_recompile_exclusives.GetValue());
+ ui->cpuopt_ignore_memory_aborts->setEnabled(runtime_lock);
+ ui->cpuopt_ignore_memory_aborts->setChecked(
+ Settings::values.cpuopt_ignore_memory_aborts.GetValue());
}
void ConfigureCpuDebug::ApplyConfiguration() {
@@ -59,6 +62,7 @@ void ConfigureCpuDebug::ApplyConfiguration() {
Settings::values.cpuopt_fastmem = ui->cpuopt_fastmem->isChecked();
Settings::values.cpuopt_fastmem_exclusives = ui->cpuopt_fastmem_exclusives->isChecked();
Settings::values.cpuopt_recompile_exclusives = ui->cpuopt_recompile_exclusives->isChecked();
+ Settings::values.cpuopt_ignore_memory_aborts = ui->cpuopt_ignore_memory_aborts->isChecked();
}
void 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 @@
</property>
</widget>
</item>
+ <item>
+ <widget class="QCheckBox" name="cpuopt_ignore_memory_aborts">
+ <property name="toolTip">
+ <string>
+ &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;
+ &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;
+ </string>
+ </property>
+ <property name="text">
+ <string>Enable fallbacks for invalid memory accesses</string>
+ </property>
+ </widget>
+ </item>
</layout>
</widget>
</item>
diff --git a/src/yuzu_cmd/config.cpp b/src/yuzu_cmd/config.cpp
index 2c78e776c..de9b220da 100644
--- a/src/yuzu_cmd/config.cpp
+++ b/src/yuzu_cmd/config.cpp
@@ -286,6 +286,7 @@ void Config::ReadValues() {
ReadSetting("Cpu", Settings::values.cpuopt_fastmem);
ReadSetting("Cpu", Settings::values.cpuopt_fastmem_exclusives);
ReadSetting("Cpu", Settings::values.cpuopt_recompile_exclusives);
+ ReadSetting("Cpu", Settings::values.cpuopt_ignore_memory_aborts);
ReadSetting("Cpu", Settings::values.cpuopt_unsafe_unfuse_fma);
ReadSetting("Cpu", Settings::values.cpuopt_unsafe_reduce_fp_error);
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 =
# 0: Disabled, 1 (default): Enabled
cpuopt_recompile_exclusives =
+# Enable optimization to ignore invalid memory accesses (faster guest memory access)
+# 0: Disabled, 1 (default): Enabled
+cpuopt_ignore_memory_aborts =
+
# Enable unfuse FMA (improve performance on CPUs without FMA)
# Only enabled if cpu_accuracy is set to Unsafe. Automatically chosen with cpu_accuracy = Auto-select.
# 0: Disabled, 1 (default): Enabled