diff options
Diffstat (limited to '')
-rw-r--r-- | src/core/arm/arm_interface.cpp | 58 |
1 files changed, 53 insertions, 5 deletions
diff --git a/src/core/arm/arm_interface.cpp b/src/core/arm/arm_interface.cpp index 9b5a5ca57..0efc3732f 100644 --- a/src/core/arm/arm_interface.cpp +++ b/src/core/arm/arm_interface.cpp @@ -95,7 +95,7 @@ void ARM_Interface::Run() { using Kernel::SuspendType; while (true) { - Kernel::KThread* current_thread{system.Kernel().CurrentScheduler()->GetCurrentThread()}; + Kernel::KThread* current_thread{Kernel::GetCurrentThreadPointer(system.Kernel())}; Dynarmic::HaltReason hr{}; // Notify the debugger and go to sleep if a step was performed @@ -107,6 +107,7 @@ void ARM_Interface::Run() { } // Otherwise, run the thread. + system.EnterDynarmicProfile(); if (current_thread->GetStepState() == StepState::StepPending) { hr = StepJit(); @@ -116,14 +117,29 @@ void ARM_Interface::Run() { } else { hr = RunJit(); } - - // Notify the debugger and go to sleep if a breakpoint was hit. - if (Has(hr, breakpoint)) { - system.GetDebugger().NotifyThreadStopped(current_thread); + system.ExitDynarmicProfile(); + + // 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 (system.DebuggerEnabled()) { + system.GetDebugger().NotifyThreadStopped(current_thread); + } current_thread->RequestSuspend(Kernel::SuspendType::Debug); break; } + // Notify the debugger and go to sleep if a watchpoint was hit. + if (Has(hr, watchpoint)) { + RewindBreakpointInstruction(); + if (system.DebuggerEnabled()) { + system.GetDebugger().NotifyThreadWatchpoint(current_thread, *HaltedWatchpoint()); + } + current_thread->RequestSuspend(SuspendType::Debug); + break; + } + // Handle syscalls and scheduling (this may change the current thread) if (Has(hr, svc_call)) { Kernel::Svc::Call(system, GetSvcNumber()); @@ -134,4 +150,36 @@ void ARM_Interface::Run() { } } +void ARM_Interface::LoadWatchpointArray(const WatchpointArray& wp) { + watchpoints = ℘ +} + +const Kernel::DebugWatchpoint* ARM_Interface::MatchingWatchpoint( + VAddr addr, u64 size, Kernel::DebugWatchpointType access_type) const { + if (!watchpoints) { + return nullptr; + } + + const VAddr start_address{addr}; + const VAddr end_address{addr + size}; + + for (size_t i = 0; i < Core::Hardware::NUM_WATCHPOINTS; i++) { + const auto& watch{(*watchpoints)[i]}; + + if (end_address <= watch.start_address) { + continue; + } + if (start_address >= watch.end_address) { + continue; + } + if ((access_type & watch.type) == Kernel::DebugWatchpointType::None) { + continue; + } + + return &watch; + } + + return nullptr; +} + } // namespace Core |