aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorlizzie <lizzie@eden-emu.dev>2025-11-03 20:36:38 +0100
committercrueter <crueter@eden-emu.dev>2025-11-03 20:36:38 +0100
commit82eb5a03f4713c039a379cedef9b3f7628b177fb (patch)
tree2cc9f65ba94cc6d3714d2f91747d57209fdb53dd /src
parent0e6ea2d9d66bc7bd4019ab10324e75e73e96f517 (diff)
[core/arm] introduce vtable bouncing (#2943)
Basically this just makes functions that go into zero-page or invalid addresses "bounce" back (with a return err of 0) such that it emulates a subroutine returning appropriatedly... this is mainly inspired by [this particular commit](https://git.citron-emu.org/Citron/Emulator/commit/fbb4f5c015d778ed0c8e2d91b01dcdffd7da9681); with the key difference of accounting for the scheduler fucking up some random bs. I don't like this hack but anyways maybe it fixes something? Signed-off-by: lizzie lizzie@eden-emu.dev Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2943 Reviewed-by: Maufeat <sahyno1996@gmail.com> Reviewed-by: MaranBr <maranbr@eden-emu.dev> Co-authored-by: lizzie <lizzie@eden-emu.dev> Co-committed-by: lizzie <lizzie@eden-emu.dev>
Diffstat (limited to 'src')
-rw-r--r--src/common/settings.h2
-rw-r--r--src/core/hle/kernel/physical_core.cpp16
-rw-r--r--src/qt_common/config/shared_translation.cpp4
3 files changed, 20 insertions, 2 deletions
diff --git a/src/common/settings.h b/src/common/settings.h
index b5c8db5cec..2aef8ba85a 100644
--- a/src/common/settings.h
+++ b/src/common/settings.h
@@ -240,7 +240,7 @@ struct Values {
Category::Cpu};
SwitchableSetting<CpuAccuracy, true> cpu_accuracy{linkage, CpuAccuracy::Auto,
"cpu_accuracy", Category::Cpu};
-
+ SwitchableSetting<bool> vtable_bouncing{linkage, true, "vtable_bouncing", Category::Cpu};
SwitchableSetting<bool> use_fast_cpu_time{linkage,
false,
"use_fast_cpu_time",
diff --git a/src/core/hle/kernel/physical_core.cpp b/src/core/hle/kernel/physical_core.cpp
index 04f0010688..77cdab76d7 100644
--- a/src/core/hle/kernel/physical_core.cpp
+++ b/src/core/hle/kernel/physical_core.cpp
@@ -103,12 +103,26 @@ void PhysicalCore::RunThread(Kernel::KThread* thread) {
const bool data_abort = True(hr & Core::HaltReason::DataAbort);
const bool interrupt = True(hr & Core::HaltReason::BreakLoop);
+ bool may_abort = true; // Ignore aborting virtual functions (for debugging)
+ if (prefetch_abort && ::Settings::values.vtable_bouncing) {
+ auto& lock = m_kernel.GlobalSchedulerContext().SchedulerLock();
+ lock.Lock();
+ Kernel::Svc::ThreadContext ctx;
+ interface->GetContext(ctx);
+ LOG_WARNING(Core_ARM, "vtable bouncing {:016X}", ctx.lr);
+ ctx.pc = ctx.lr;
+ ctx.r[0] = 0;
+ interface->SetContext(ctx);
+ lock.Unlock();
+ may_abort = false;
+ }
+
// Since scheduling may occur here, we cannot use any cached
// state after returning from calls we make.
// Notify the debugger and go to sleep if a breakpoint was hit,
// or if the thread is unable to continue for any reason.
- if (breakpoint || prefetch_abort) {
+ if (breakpoint || (prefetch_abort && may_abort)) {
if (breakpoint) {
interface->RewindBreakpointInstruction();
}
diff --git a/src/qt_common/config/shared_translation.cpp b/src/qt_common/config/shared_translation.cpp
index 2d54fc2a30..b54211142c 100644
--- a/src/qt_common/config/shared_translation.cpp
+++ b/src/qt_common/config/shared_translation.cpp
@@ -109,6 +109,10 @@ std::unique_ptr<TranslationMap> InitializeTranslations(QObject* parent)
"cause deadlocks. A range of 77-21000 is recommended."));
INSERT(Settings, cpu_backend, tr("Backend:"), QString());
+ INSERT(Settings, vtable_bouncing,
+ tr("Virtual Table Bouncing"),
+ tr("Bounces (by emulating a 0-valued return) any functions that triggers a prefetch abort"));
+
// Cpu Debug
// Cpu Unsafe