summaryrefslogtreecommitdiffstats
path: root/src/core/arm/arm_interface.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/core/arm/arm_interface.cpp58
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