diff options
| author | 2023-06-13 09:45:09 -0700 | |
|---|---|---|
| committer | 2023-06-13 09:45:09 -0700 | |
| commit | 14d25e2c75454fbdcfa3408257d3b9092e284973 (patch) | |
| tree | ea205f4376325f5c31b62072bd57bf8ce27c1a28 /src/core/arm/arm_interface.cpp | |
| parent | Merge pull request #10746 from bunnei/update-android-settings (diff) | |
| parent | core: decouple ARM interface from Dynarmic (diff) | |
| download | yuzu-14d25e2c75454fbdcfa3408257d3b9092e284973.tar.gz yuzu-14d25e2c75454fbdcfa3408257d3b9092e284973.tar.xz yuzu-14d25e2c75454fbdcfa3408257d3b9092e284973.zip | |
Merge pull request #10747 from liamwhite/arm-interface-decouple
core: decouple ARM interface from Dynarmic
Diffstat (limited to 'src/core/arm/arm_interface.cpp')
| -rw-r--r-- | src/core/arm/arm_interface.cpp | 84 |
1 files changed, 69 insertions, 15 deletions
diff --git a/src/core/arm/arm_interface.cpp b/src/core/arm/arm_interface.cpp index d30914b7a..beaea64b3 100644 --- a/src/core/arm/arm_interface.cpp +++ b/src/core/arm/arm_interface.cpp | |||
| @@ -13,25 +13,68 @@ | |||
| 13 | #include "core/core.h" | 13 | #include "core/core.h" |
| 14 | #include "core/debugger/debugger.h" | 14 | #include "core/debugger/debugger.h" |
| 15 | #include "core/hle/kernel/k_process.h" | 15 | #include "core/hle/kernel/k_process.h" |
| 16 | #include "core/hle/kernel/k_thread.h" | ||
| 16 | #include "core/hle/kernel/svc.h" | 17 | #include "core/hle/kernel/svc.h" |
| 17 | #include "core/loader/loader.h" | 18 | #include "core/loader/loader.h" |
| 18 | #include "core/memory.h" | 19 | #include "core/memory.h" |
| 19 | 20 | ||
| 20 | #include "core/arm/dynarmic/arm_dynarmic_32.h" | ||
| 21 | #include "core/arm/dynarmic/arm_dynarmic_64.h" | ||
| 22 | |||
| 23 | namespace Core { | 21 | namespace Core { |
| 24 | 22 | ||
| 25 | constexpr u64 SEGMENT_BASE = 0x7100000000ull; | 23 | constexpr u64 SEGMENT_BASE = 0x7100000000ull; |
| 26 | 24 | ||
| 27 | std::vector<ARM_Interface::BacktraceEntry> ARM_Interface::GetBacktraceFromContext( | 25 | std::vector<ARM_Interface::BacktraceEntry> ARM_Interface::GetBacktraceFromContext( |
| 28 | Core::System& system, const ARM_Interface::ThreadContext32& ctx) { | 26 | Core::System& system, const ARM_Interface::ThreadContext32& ctx) { |
| 29 | return ARM_Dynarmic_32::GetBacktraceFromContext(system, ctx); | 27 | std::vector<BacktraceEntry> out; |
| 28 | auto& memory = system.ApplicationMemory(); | ||
| 29 | |||
| 30 | const auto& reg = ctx.cpu_registers; | ||
| 31 | u32 pc = reg[15], lr = reg[14], fp = reg[11]; | ||
| 32 | out.push_back({"", 0, pc, 0, ""}); | ||
| 33 | |||
| 34 | // fp (= r11) points to the last frame record. | ||
| 35 | // Frame records are two words long: | ||
| 36 | // fp+0 : pointer to previous frame record | ||
| 37 | // fp+4 : value of lr for frame | ||
| 38 | for (size_t i = 0; i < 256; i++) { | ||
| 39 | out.push_back({"", 0, lr, 0, ""}); | ||
| 40 | if (!fp || (fp % 4 != 0) || !memory.IsValidVirtualAddressRange(fp, 8)) { | ||
| 41 | break; | ||
| 42 | } | ||
| 43 | lr = memory.Read32(fp + 4); | ||
| 44 | fp = memory.Read32(fp); | ||
| 45 | } | ||
| 46 | |||
| 47 | SymbolicateBacktrace(system, out); | ||
| 48 | |||
| 49 | return out; | ||
| 30 | } | 50 | } |
| 31 | 51 | ||
| 32 | std::vector<ARM_Interface::BacktraceEntry> ARM_Interface::GetBacktraceFromContext( | 52 | std::vector<ARM_Interface::BacktraceEntry> ARM_Interface::GetBacktraceFromContext( |
| 33 | Core::System& system, const ARM_Interface::ThreadContext64& ctx) { | 53 | Core::System& system, const ARM_Interface::ThreadContext64& ctx) { |
| 34 | return ARM_Dynarmic_64::GetBacktraceFromContext(system, ctx); | 54 | std::vector<BacktraceEntry> out; |
| 55 | auto& memory = system.ApplicationMemory(); | ||
| 56 | |||
| 57 | const auto& reg = ctx.cpu_registers; | ||
| 58 | u64 pc = ctx.pc, lr = reg[30], fp = reg[29]; | ||
| 59 | |||
| 60 | out.push_back({"", 0, pc, 0, ""}); | ||
| 61 | |||
| 62 | // fp (= x29) points to the previous frame record. | ||
| 63 | // Frame records are two words long: | ||
| 64 | // fp+0 : pointer to previous frame record | ||
| 65 | // fp+8 : value of lr for frame | ||
| 66 | for (size_t i = 0; i < 256; i++) { | ||
| 67 | out.push_back({"", 0, lr, 0, ""}); | ||
| 68 | if (!fp || (fp % 4 != 0) || !memory.IsValidVirtualAddressRange(fp, 16)) { | ||
| 69 | break; | ||
| 70 | } | ||
| 71 | lr = memory.Read64(fp + 8); | ||
| 72 | fp = memory.Read64(fp); | ||
| 73 | } | ||
| 74 | |||
| 75 | SymbolicateBacktrace(system, out); | ||
| 76 | |||
| 77 | return out; | ||
| 35 | } | 78 | } |
| 36 | 79 | ||
| 37 | void ARM_Interface::SymbolicateBacktrace(Core::System& system, std::vector<BacktraceEntry>& out) { | 80 | void ARM_Interface::SymbolicateBacktrace(Core::System& system, std::vector<BacktraceEntry>& out) { |
| @@ -76,6 +119,18 @@ void ARM_Interface::SymbolicateBacktrace(Core::System& system, std::vector<Backt | |||
| 76 | } | 119 | } |
| 77 | } | 120 | } |
| 78 | 121 | ||
| 122 | std::vector<ARM_Interface::BacktraceEntry> ARM_Interface::GetBacktrace() const { | ||
| 123 | if (GetArchitecture() == Architecture::Aarch64) { | ||
| 124 | ThreadContext64 ctx; | ||
| 125 | SaveContext(ctx); | ||
| 126 | return GetBacktraceFromContext(system, ctx); | ||
| 127 | } else { | ||
| 128 | ThreadContext32 ctx; | ||
| 129 | SaveContext(ctx); | ||
| 130 | return GetBacktraceFromContext(system, ctx); | ||
| 131 | } | ||
| 132 | } | ||
| 133 | |||
| 79 | void ARM_Interface::LogBacktrace() const { | 134 | void ARM_Interface::LogBacktrace() const { |
| 80 | const VAddr sp = GetSP(); | 135 | const VAddr sp = GetSP(); |
| 81 | const VAddr pc = GetPC(); | 136 | const VAddr pc = GetPC(); |
| @@ -83,7 +138,6 @@ void ARM_Interface::LogBacktrace() const { | |||
| 83 | LOG_ERROR(Core_ARM, "{:20}{:20}{:20}{:20}{}", "Module Name", "Address", "Original Address", | 138 | LOG_ERROR(Core_ARM, "{:20}{:20}{:20}{:20}{}", "Module Name", "Address", "Original Address", |
| 84 | "Offset", "Symbol"); | 139 | "Offset", "Symbol"); |
| 85 | LOG_ERROR(Core_ARM, ""); | 140 | LOG_ERROR(Core_ARM, ""); |
| 86 | |||
| 87 | const auto backtrace = GetBacktrace(); | 141 | const auto backtrace = GetBacktrace(); |
| 88 | for (const auto& entry : backtrace) { | 142 | for (const auto& entry : backtrace) { |
| 89 | LOG_ERROR(Core_ARM, "{:20}{:016X} {:016X} {:016X} {}", entry.module, entry.address, | 143 | LOG_ERROR(Core_ARM, "{:20}{:016X} {:016X} {:016X} {}", entry.module, entry.address, |
| @@ -97,7 +151,7 @@ void ARM_Interface::Run() { | |||
| 97 | 151 | ||
| 98 | while (true) { | 152 | while (true) { |
| 99 | Kernel::KThread* current_thread{Kernel::GetCurrentThreadPointer(system.Kernel())}; | 153 | Kernel::KThread* current_thread{Kernel::GetCurrentThreadPointer(system.Kernel())}; |
| 100 | Dynarmic::HaltReason hr{}; | 154 | HaltReason hr{}; |
| 101 | 155 | ||
| 102 | // Notify the debugger and go to sleep if a step was performed | 156 | // Notify the debugger and go to sleep if a step was performed |
| 103 | // and this thread has been scheduled again. | 157 | // and this thread has been scheduled again. |
| @@ -108,17 +162,17 @@ void ARM_Interface::Run() { | |||
| 108 | } | 162 | } |
| 109 | 163 | ||
| 110 | // Otherwise, run the thread. | 164 | // Otherwise, run the thread. |
| 111 | system.EnterDynarmicProfile(); | 165 | system.EnterCPUProfile(); |
| 112 | if (current_thread->GetStepState() == StepState::StepPending) { | 166 | if (current_thread->GetStepState() == StepState::StepPending) { |
| 113 | hr = StepJit(); | 167 | hr = StepJit(); |
| 114 | 168 | ||
| 115 | if (Has(hr, step_thread)) { | 169 | if (True(hr & HaltReason::StepThread)) { |
| 116 | current_thread->SetStepState(StepState::StepPerformed); | 170 | current_thread->SetStepState(StepState::StepPerformed); |
| 117 | } | 171 | } |
| 118 | } else { | 172 | } else { |
| 119 | hr = RunJit(); | 173 | hr = RunJit(); |
| 120 | } | 174 | } |
| 121 | system.ExitDynarmicProfile(); | 175 | system.ExitCPUProfile(); |
| 122 | 176 | ||
| 123 | // If the thread is scheduled for termination, exit the thread. | 177 | // If the thread is scheduled for termination, exit the thread. |
| 124 | if (current_thread->HasDpc()) { | 178 | if (current_thread->HasDpc()) { |
| @@ -130,8 +184,8 @@ void ARM_Interface::Run() { | |||
| 130 | 184 | ||
| 131 | // Notify the debugger and go to sleep if a breakpoint was hit, | 185 | // Notify the debugger and go to sleep if a breakpoint was hit, |
| 132 | // or if the thread is unable to continue for any reason. | 186 | // or if the thread is unable to continue for any reason. |
| 133 | if (Has(hr, breakpoint) || Has(hr, no_execute)) { | 187 | if (True(hr & HaltReason::InstructionBreakpoint) || True(hr & HaltReason::PrefetchAbort)) { |
| 134 | if (!Has(hr, no_execute)) { | 188 | if (!True(hr & HaltReason::InstructionBreakpoint)) { |
| 135 | RewindBreakpointInstruction(); | 189 | RewindBreakpointInstruction(); |
| 136 | } | 190 | } |
| 137 | if (system.DebuggerEnabled()) { | 191 | if (system.DebuggerEnabled()) { |
| @@ -144,7 +198,7 @@ void ARM_Interface::Run() { | |||
| 144 | } | 198 | } |
| 145 | 199 | ||
| 146 | // Notify the debugger and go to sleep if a watchpoint was hit. | 200 | // Notify the debugger and go to sleep if a watchpoint was hit. |
| 147 | if (Has(hr, watchpoint)) { | 201 | if (True(hr & HaltReason::DataAbort)) { |
| 148 | if (system.DebuggerEnabled()) { | 202 | if (system.DebuggerEnabled()) { |
| 149 | system.GetDebugger().NotifyThreadWatchpoint(current_thread, *HaltedWatchpoint()); | 203 | system.GetDebugger().NotifyThreadWatchpoint(current_thread, *HaltedWatchpoint()); |
| 150 | } | 204 | } |
| @@ -153,11 +207,11 @@ void ARM_Interface::Run() { | |||
| 153 | } | 207 | } |
| 154 | 208 | ||
| 155 | // Handle syscalls and scheduling (this may change the current thread/core) | 209 | // Handle syscalls and scheduling (this may change the current thread/core) |
| 156 | if (Has(hr, svc_call)) { | 210 | if (True(hr & HaltReason::SupervisorCall)) { |
| 157 | Kernel::Svc::Call(system, GetSvcNumber()); | 211 | Kernel::Svc::Call(system, GetSvcNumber()); |
| 158 | break; | 212 | break; |
| 159 | } | 213 | } |
| 160 | if (Has(hr, break_loop) || !uses_wall_clock) { | 214 | if (True(hr & HaltReason::BreakLoop) || !uses_wall_clock) { |
| 161 | break; | 215 | break; |
| 162 | } | 216 | } |
| 163 | } | 217 | } |