diff options
| author | 2022-07-07 20:06:46 -0400 | |
|---|---|---|
| committer | 2022-07-25 12:14:15 -0400 | |
| commit | 6523854dd6ac2d202dacb2110bc83b8e61621e9a (patch) | |
| tree | d3d5c5d3048ef0d316692e5f74a78575666114de /src/core/arm | |
| parent | Merge pull request #8549 from liamwhite/kscheduler-sc (diff) | |
| download | yuzu-6523854dd6ac2d202dacb2110bc83b8e61621e9a.tar.gz yuzu-6523854dd6ac2d202dacb2110bc83b8e61621e9a.tar.xz yuzu-6523854dd6ac2d202dacb2110bc83b8e61621e9a.zip | |
kernel: unlayer CPU interrupt handling
Diffstat (limited to 'src/core/arm')
| -rw-r--r-- | src/core/arm/arm_interface.h | 11 | ||||
| -rw-r--r-- | src/core/arm/cpu_interrupt_handler.cpp | 24 | ||||
| -rw-r--r-- | src/core/arm/cpu_interrupt_handler.h | 39 | ||||
| -rw-r--r-- | src/core/arm/dynarmic/arm_dynarmic_32.cpp | 13 | ||||
| -rw-r--r-- | src/core/arm/dynarmic/arm_dynarmic_32.h | 5 | ||||
| -rw-r--r-- | src/core/arm/dynarmic/arm_dynarmic_64.cpp | 12 | ||||
| -rw-r--r-- | src/core/arm/dynarmic/arm_dynarmic_64.h | 6 |
7 files changed, 25 insertions, 85 deletions
diff --git a/src/core/arm/arm_interface.h b/src/core/arm/arm_interface.h index c092db9ff..d0c9f8857 100644 --- a/src/core/arm/arm_interface.h +++ b/src/core/arm/arm_interface.h | |||
| @@ -28,7 +28,6 @@ namespace Core { | |||
| 28 | class System; | 28 | class System; |
| 29 | class CPUInterruptHandler; | 29 | class CPUInterruptHandler; |
| 30 | 30 | ||
| 31 | using CPUInterrupts = std::array<CPUInterruptHandler, Core::Hardware::NUM_CPU_CORES>; | ||
| 32 | using WatchpointArray = std::array<Kernel::DebugWatchpoint, Core::Hardware::NUM_WATCHPOINTS>; | 31 | using WatchpointArray = std::array<Kernel::DebugWatchpoint, Core::Hardware::NUM_WATCHPOINTS>; |
| 33 | 32 | ||
| 34 | /// Generic ARMv8 CPU interface | 33 | /// Generic ARMv8 CPU interface |
| @@ -37,10 +36,8 @@ public: | |||
| 37 | YUZU_NON_COPYABLE(ARM_Interface); | 36 | YUZU_NON_COPYABLE(ARM_Interface); |
| 38 | YUZU_NON_MOVEABLE(ARM_Interface); | 37 | YUZU_NON_MOVEABLE(ARM_Interface); |
| 39 | 38 | ||
| 40 | explicit ARM_Interface(System& system_, CPUInterrupts& interrupt_handlers_, | 39 | explicit ARM_Interface(System& system_, bool uses_wall_clock_) |
| 41 | bool uses_wall_clock_) | 40 | : system{system_}, uses_wall_clock{uses_wall_clock_} {} |
| 42 | : system{system_}, interrupt_handlers{interrupt_handlers_}, uses_wall_clock{ | ||
| 43 | uses_wall_clock_} {} | ||
| 44 | virtual ~ARM_Interface() = default; | 41 | virtual ~ARM_Interface() = default; |
| 45 | 42 | ||
| 46 | struct ThreadContext32 { | 43 | struct ThreadContext32 { |
| @@ -182,6 +179,9 @@ public: | |||
| 182 | /// Signal an interrupt and ask the core to halt as soon as possible. | 179 | /// Signal an interrupt and ask the core to halt as soon as possible. |
| 183 | virtual void SignalInterrupt() = 0; | 180 | virtual void SignalInterrupt() = 0; |
| 184 | 181 | ||
| 182 | /// Clear a previous interrupt. | ||
| 183 | virtual void ClearInterrupt() = 0; | ||
| 184 | |||
| 185 | struct BacktraceEntry { | 185 | struct BacktraceEntry { |
| 186 | std::string module; | 186 | std::string module; |
| 187 | u64 address; | 187 | u64 address; |
| @@ -209,7 +209,6 @@ public: | |||
| 209 | protected: | 209 | protected: |
| 210 | /// System context that this ARM interface is running under. | 210 | /// System context that this ARM interface is running under. |
| 211 | System& system; | 211 | System& system; |
| 212 | CPUInterrupts& interrupt_handlers; | ||
| 213 | const WatchpointArray* watchpoints; | 212 | const WatchpointArray* watchpoints; |
| 214 | bool uses_wall_clock; | 213 | bool uses_wall_clock; |
| 215 | 214 | ||
diff --git a/src/core/arm/cpu_interrupt_handler.cpp b/src/core/arm/cpu_interrupt_handler.cpp deleted file mode 100644 index 77b6194d7..000000000 --- a/src/core/arm/cpu_interrupt_handler.cpp +++ /dev/null | |||
| @@ -1,24 +0,0 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "common/thread.h" | ||
| 5 | #include "core/arm/cpu_interrupt_handler.h" | ||
| 6 | |||
| 7 | namespace Core { | ||
| 8 | |||
| 9 | CPUInterruptHandler::CPUInterruptHandler() : interrupt_event{std::make_unique<Common::Event>()} {} | ||
| 10 | |||
| 11 | CPUInterruptHandler::~CPUInterruptHandler() = default; | ||
| 12 | |||
| 13 | void CPUInterruptHandler::SetInterrupt(bool is_interrupted_) { | ||
| 14 | if (is_interrupted_) { | ||
| 15 | interrupt_event->Set(); | ||
| 16 | } | ||
| 17 | is_interrupted = is_interrupted_; | ||
| 18 | } | ||
| 19 | |||
| 20 | void CPUInterruptHandler::AwaitInterrupt() { | ||
| 21 | interrupt_event->Wait(); | ||
| 22 | } | ||
| 23 | |||
| 24 | } // namespace Core | ||
diff --git a/src/core/arm/cpu_interrupt_handler.h b/src/core/arm/cpu_interrupt_handler.h deleted file mode 100644 index 286e12e53..000000000 --- a/src/core/arm/cpu_interrupt_handler.h +++ /dev/null | |||
| @@ -1,39 +0,0 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include <atomic> | ||
| 7 | #include <memory> | ||
| 8 | |||
| 9 | namespace Common { | ||
| 10 | class Event; | ||
| 11 | } | ||
| 12 | |||
| 13 | namespace Core { | ||
| 14 | |||
| 15 | class CPUInterruptHandler { | ||
| 16 | public: | ||
| 17 | CPUInterruptHandler(); | ||
| 18 | ~CPUInterruptHandler(); | ||
| 19 | |||
| 20 | CPUInterruptHandler(const CPUInterruptHandler&) = delete; | ||
| 21 | CPUInterruptHandler& operator=(const CPUInterruptHandler&) = delete; | ||
| 22 | |||
| 23 | CPUInterruptHandler(CPUInterruptHandler&&) = delete; | ||
| 24 | CPUInterruptHandler& operator=(CPUInterruptHandler&&) = delete; | ||
| 25 | |||
| 26 | bool IsInterrupted() const { | ||
| 27 | return is_interrupted; | ||
| 28 | } | ||
| 29 | |||
| 30 | void SetInterrupt(bool is_interrupted); | ||
| 31 | |||
| 32 | void AwaitInterrupt(); | ||
| 33 | |||
| 34 | private: | ||
| 35 | std::unique_ptr<Common::Event> interrupt_event; | ||
| 36 | std::atomic_bool is_interrupted{false}; | ||
| 37 | }; | ||
| 38 | |||
| 39 | } // namespace Core | ||
diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp index b8d2ce224..7b2a3b369 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp | |||
| @@ -11,7 +11,6 @@ | |||
| 11 | #include "common/logging/log.h" | 11 | #include "common/logging/log.h" |
| 12 | #include "common/page_table.h" | 12 | #include "common/page_table.h" |
| 13 | #include "common/settings.h" | 13 | #include "common/settings.h" |
| 14 | #include "core/arm/cpu_interrupt_handler.h" | ||
| 15 | #include "core/arm/dynarmic/arm_dynarmic_32.h" | 14 | #include "core/arm/dynarmic/arm_dynarmic_32.h" |
| 16 | #include "core/arm/dynarmic/arm_dynarmic_cp15.h" | 15 | #include "core/arm/dynarmic/arm_dynarmic_cp15.h" |
| 17 | #include "core/arm/dynarmic/arm_exclusive_monitor.h" | 16 | #include "core/arm/dynarmic/arm_exclusive_monitor.h" |
| @@ -311,11 +310,9 @@ void ARM_Dynarmic_32::RewindBreakpointInstruction() { | |||
| 311 | LoadContext(breakpoint_context); | 310 | LoadContext(breakpoint_context); |
| 312 | } | 311 | } |
| 313 | 312 | ||
| 314 | ARM_Dynarmic_32::ARM_Dynarmic_32(System& system_, CPUInterrupts& interrupt_handlers_, | 313 | ARM_Dynarmic_32::ARM_Dynarmic_32(System& system_, bool uses_wall_clock_, |
| 315 | bool uses_wall_clock_, ExclusiveMonitor& exclusive_monitor_, | 314 | ExclusiveMonitor& exclusive_monitor_, std::size_t core_index_) |
| 316 | std::size_t core_index_) | 315 | : ARM_Interface{system_, uses_wall_clock_}, cb(std::make_unique<DynarmicCallbacks32>(*this)), |
| 317 | : ARM_Interface{system_, interrupt_handlers_, uses_wall_clock_}, | ||
| 318 | cb(std::make_unique<DynarmicCallbacks32>(*this)), | ||
| 319 | cp15(std::make_shared<DynarmicCP15>(*this)), core_index{core_index_}, | 316 | cp15(std::make_shared<DynarmicCP15>(*this)), core_index{core_index_}, |
| 320 | exclusive_monitor{dynamic_cast<DynarmicExclusiveMonitor&>(exclusive_monitor_)}, | 317 | exclusive_monitor{dynamic_cast<DynarmicExclusiveMonitor&>(exclusive_monitor_)}, |
| 321 | null_jit{MakeJit(nullptr)}, jit{null_jit.get()} {} | 318 | null_jit{MakeJit(nullptr)}, jit{null_jit.get()} {} |
| @@ -394,6 +391,10 @@ void ARM_Dynarmic_32::SignalInterrupt() { | |||
| 394 | jit.load()->HaltExecution(break_loop); | 391 | jit.load()->HaltExecution(break_loop); |
| 395 | } | 392 | } |
| 396 | 393 | ||
| 394 | void ARM_Dynarmic_32::ClearInterrupt() { | ||
| 395 | jit.load()->ClearHalt(break_loop); | ||
| 396 | } | ||
| 397 | |||
| 397 | void ARM_Dynarmic_32::ClearInstructionCache() { | 398 | void ARM_Dynarmic_32::ClearInstructionCache() { |
| 398 | jit.load()->ClearCache(); | 399 | jit.load()->ClearCache(); |
| 399 | } | 400 | } |
diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.h b/src/core/arm/dynarmic/arm_dynarmic_32.h index 346e9abf8..d24ba2289 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_32.h +++ b/src/core/arm/dynarmic/arm_dynarmic_32.h | |||
| @@ -28,8 +28,8 @@ class System; | |||
| 28 | 28 | ||
| 29 | class ARM_Dynarmic_32 final : public ARM_Interface { | 29 | class ARM_Dynarmic_32 final : public ARM_Interface { |
| 30 | public: | 30 | public: |
| 31 | ARM_Dynarmic_32(System& system_, CPUInterrupts& interrupt_handlers_, bool uses_wall_clock_, | 31 | ARM_Dynarmic_32(System& system_, bool uses_wall_clock_, ExclusiveMonitor& exclusive_monitor_, |
| 32 | ExclusiveMonitor& exclusive_monitor_, std::size_t core_index_); | 32 | std::size_t core_index_); |
| 33 | ~ARM_Dynarmic_32() override; | 33 | ~ARM_Dynarmic_32() override; |
| 34 | 34 | ||
| 35 | void SetPC(u64 pc) override; | 35 | void SetPC(u64 pc) override; |
| @@ -56,6 +56,7 @@ public: | |||
| 56 | void LoadContext(const ThreadContext64& ctx) override {} | 56 | void LoadContext(const ThreadContext64& ctx) override {} |
| 57 | 57 | ||
| 58 | void SignalInterrupt() override; | 58 | void SignalInterrupt() override; |
| 59 | void ClearInterrupt() override; | ||
| 59 | void ClearExclusiveState() override; | 60 | void ClearExclusiveState() override; |
| 60 | 61 | ||
| 61 | void ClearInstructionCache() override; | 62 | void ClearInstructionCache() override; |
diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp index 1a4d37cbc..17d631b2e 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp | |||
| @@ -10,7 +10,6 @@ | |||
| 10 | #include "common/logging/log.h" | 10 | #include "common/logging/log.h" |
| 11 | #include "common/page_table.h" | 11 | #include "common/page_table.h" |
| 12 | #include "common/settings.h" | 12 | #include "common/settings.h" |
| 13 | #include "core/arm/cpu_interrupt_handler.h" | ||
| 14 | #include "core/arm/dynarmic/arm_dynarmic_64.h" | 13 | #include "core/arm/dynarmic/arm_dynarmic_64.h" |
| 15 | #include "core/arm/dynarmic/arm_exclusive_monitor.h" | 14 | #include "core/arm/dynarmic/arm_exclusive_monitor.h" |
| 16 | #include "core/core.h" | 15 | #include "core/core.h" |
| @@ -371,10 +370,9 @@ void ARM_Dynarmic_64::RewindBreakpointInstruction() { | |||
| 371 | LoadContext(breakpoint_context); | 370 | LoadContext(breakpoint_context); |
| 372 | } | 371 | } |
| 373 | 372 | ||
| 374 | ARM_Dynarmic_64::ARM_Dynarmic_64(System& system_, CPUInterrupts& interrupt_handlers_, | 373 | ARM_Dynarmic_64::ARM_Dynarmic_64(System& system_, bool uses_wall_clock_, |
| 375 | bool uses_wall_clock_, ExclusiveMonitor& exclusive_monitor_, | 374 | ExclusiveMonitor& exclusive_monitor_, std::size_t core_index_) |
| 376 | std::size_t core_index_) | 375 | : ARM_Interface{system_, uses_wall_clock_}, |
| 377 | : ARM_Interface{system_, interrupt_handlers_, uses_wall_clock_}, | ||
| 378 | cb(std::make_unique<DynarmicCallbacks64>(*this)), core_index{core_index_}, | 376 | cb(std::make_unique<DynarmicCallbacks64>(*this)), core_index{core_index_}, |
| 379 | exclusive_monitor{dynamic_cast<DynarmicExclusiveMonitor&>(exclusive_monitor_)}, | 377 | exclusive_monitor{dynamic_cast<DynarmicExclusiveMonitor&>(exclusive_monitor_)}, |
| 380 | null_jit{MakeJit(nullptr, 48)}, jit{null_jit.get()} {} | 378 | null_jit{MakeJit(nullptr, 48)}, jit{null_jit.get()} {} |
| @@ -461,6 +459,10 @@ void ARM_Dynarmic_64::SignalInterrupt() { | |||
| 461 | jit.load()->HaltExecution(break_loop); | 459 | jit.load()->HaltExecution(break_loop); |
| 462 | } | 460 | } |
| 463 | 461 | ||
| 462 | void ARM_Dynarmic_64::ClearInterrupt() { | ||
| 463 | jit.load()->ClearHalt(break_loop); | ||
| 464 | } | ||
| 465 | |||
| 464 | void ARM_Dynarmic_64::ClearInstructionCache() { | 466 | void ARM_Dynarmic_64::ClearInstructionCache() { |
| 465 | jit.load()->ClearCache(); | 467 | jit.load()->ClearCache(); |
| 466 | } | 468 | } |
diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.h b/src/core/arm/dynarmic/arm_dynarmic_64.h index c77a83ad7..ed1a5eb96 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_64.h +++ b/src/core/arm/dynarmic/arm_dynarmic_64.h | |||
| @@ -20,14 +20,13 @@ class Memory; | |||
| 20 | namespace Core { | 20 | namespace Core { |
| 21 | 21 | ||
| 22 | class DynarmicCallbacks64; | 22 | class DynarmicCallbacks64; |
| 23 | class CPUInterruptHandler; | ||
| 24 | class DynarmicExclusiveMonitor; | 23 | class DynarmicExclusiveMonitor; |
| 25 | class System; | 24 | class System; |
| 26 | 25 | ||
| 27 | class ARM_Dynarmic_64 final : public ARM_Interface { | 26 | class ARM_Dynarmic_64 final : public ARM_Interface { |
| 28 | public: | 27 | public: |
| 29 | ARM_Dynarmic_64(System& system_, CPUInterrupts& interrupt_handlers_, bool uses_wall_clock_, | 28 | ARM_Dynarmic_64(System& system_, bool uses_wall_clock_, ExclusiveMonitor& exclusive_monitor_, |
| 30 | ExclusiveMonitor& exclusive_monitor_, std::size_t core_index_); | 29 | std::size_t core_index_); |
| 31 | ~ARM_Dynarmic_64() override; | 30 | ~ARM_Dynarmic_64() override; |
| 32 | 31 | ||
| 33 | void SetPC(u64 pc) override; | 32 | void SetPC(u64 pc) override; |
| @@ -50,6 +49,7 @@ public: | |||
| 50 | void LoadContext(const ThreadContext64& ctx) override; | 49 | void LoadContext(const ThreadContext64& ctx) override; |
| 51 | 50 | ||
| 52 | void SignalInterrupt() override; | 51 | void SignalInterrupt() override; |
| 52 | void ClearInterrupt() override; | ||
| 53 | void ClearExclusiveState() override; | 53 | void ClearExclusiveState() override; |
| 54 | 54 | ||
| 55 | void ClearInstructionCache() override; | 55 | void ClearInstructionCache() override; |