diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/CMakeLists.txt | 2 | ||||
| -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 | ||||
| -rw-r--r-- | src/core/debugger/debugger.cpp | 9 | ||||
| -rw-r--r-- | src/core/hle/kernel/kernel.cpp | 41 | ||||
| -rw-r--r-- | src/core/hle/kernel/kernel.h | 8 | ||||
| -rw-r--r-- | src/core/hle/kernel/physical_core.cpp | 29 | ||||
| -rw-r--r-- | src/core/hle/kernel/physical_core.h | 17 |
13 files changed, 64 insertions, 152 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 32cc2f392..83d819938 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt | |||
| @@ -1,8 +1,6 @@ | |||
| 1 | add_library(core STATIC | 1 | add_library(core STATIC |
| 2 | arm/arm_interface.h | 2 | arm/arm_interface.h |
| 3 | arm/arm_interface.cpp | 3 | arm/arm_interface.cpp |
| 4 | arm/cpu_interrupt_handler.cpp | ||
| 5 | arm/cpu_interrupt_handler.h | ||
| 6 | arm/dynarmic/arm_dynarmic_32.cpp | 4 | arm/dynarmic/arm_dynarmic_32.cpp |
| 7 | arm/dynarmic/arm_dynarmic_32.h | 5 | arm/dynarmic/arm_dynarmic_32.h |
| 8 | arm/dynarmic/arm_dynarmic_64.cpp | 6 | arm/dynarmic/arm_dynarmic_64.cpp |
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; |
diff --git a/src/core/debugger/debugger.cpp b/src/core/debugger/debugger.cpp index ac64d2f9d..e42bdd17d 100644 --- a/src/core/debugger/debugger.cpp +++ b/src/core/debugger/debugger.cpp | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | #include "core/debugger/debugger_interface.h" | 15 | #include "core/debugger/debugger_interface.h" |
| 16 | #include "core/debugger/gdbstub.h" | 16 | #include "core/debugger/gdbstub.h" |
| 17 | #include "core/hle/kernel/global_scheduler_context.h" | 17 | #include "core/hle/kernel/global_scheduler_context.h" |
| 18 | #include "core/hle/kernel/k_scheduler.h" | ||
| 18 | 19 | ||
| 19 | template <typename Readable, typename Buffer, typename Callback> | 20 | template <typename Readable, typename Buffer, typename Callback> |
| 20 | static void AsyncReceiveInto(Readable& r, Buffer& buffer, Callback&& c) { | 21 | static void AsyncReceiveInto(Readable& r, Buffer& buffer, Callback&& c) { |
| @@ -230,13 +231,12 @@ private: | |||
| 230 | } | 231 | } |
| 231 | 232 | ||
| 232 | void PauseEmulation() { | 233 | void PauseEmulation() { |
| 234 | Kernel::KScopedSchedulerLock sl{system.Kernel()}; | ||
| 235 | |||
| 233 | // Put all threads to sleep on next scheduler round. | 236 | // Put all threads to sleep on next scheduler round. |
| 234 | for (auto* thread : ThreadList()) { | 237 | for (auto* thread : ThreadList()) { |
| 235 | thread->RequestSuspend(Kernel::SuspendType::Debug); | 238 | thread->RequestSuspend(Kernel::SuspendType::Debug); |
| 236 | } | 239 | } |
| 237 | |||
| 238 | // Signal an interrupt so that scheduler will fire. | ||
| 239 | system.Kernel().InterruptAllPhysicalCores(); | ||
| 240 | } | 240 | } |
| 241 | 241 | ||
| 242 | void ResumeEmulation(Kernel::KThread* except = nullptr) { | 242 | void ResumeEmulation(Kernel::KThread* except = nullptr) { |
| @@ -253,7 +253,8 @@ private: | |||
| 253 | 253 | ||
| 254 | template <typename Callback> | 254 | template <typename Callback> |
| 255 | void MarkResumed(Callback&& cb) { | 255 | void MarkResumed(Callback&& cb) { |
| 256 | std::scoped_lock lk{connection_lock}; | 256 | Kernel::KScopedSchedulerLock sl{system.Kernel()}; |
| 257 | std::scoped_lock cl{connection_lock}; | ||
| 257 | stopped = false; | 258 | stopped = false; |
| 258 | cb(); | 259 | cb(); |
| 259 | } | 260 | } |
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index f4072e1c3..ce7fa8275 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp | |||
| @@ -17,7 +17,6 @@ | |||
| 17 | #include "common/thread.h" | 17 | #include "common/thread.h" |
| 18 | #include "common/thread_worker.h" | 18 | #include "common/thread_worker.h" |
| 19 | #include "core/arm/arm_interface.h" | 19 | #include "core/arm/arm_interface.h" |
| 20 | #include "core/arm/cpu_interrupt_handler.h" | ||
| 21 | #include "core/arm/exclusive_monitor.h" | 20 | #include "core/arm/exclusive_monitor.h" |
| 22 | #include "core/core.h" | 21 | #include "core/core.h" |
| 23 | #include "core/core_timing.h" | 22 | #include "core/core_timing.h" |
| @@ -82,7 +81,7 @@ struct KernelCore::Impl { | |||
| 82 | 81 | ||
| 83 | void InitializeCores() { | 82 | void InitializeCores() { |
| 84 | for (u32 core_id = 0; core_id < Core::Hardware::NUM_CPU_CORES; core_id++) { | 83 | for (u32 core_id = 0; core_id < Core::Hardware::NUM_CPU_CORES; core_id++) { |
| 85 | cores[core_id].Initialize((*current_process).Is64BitProcess()); | 84 | cores[core_id]->Initialize((*current_process).Is64BitProcess()); |
| 86 | system.Memory().SetCurrentPageTable(*current_process, core_id); | 85 | system.Memory().SetCurrentPageTable(*current_process, core_id); |
| 87 | } | 86 | } |
| 88 | } | 87 | } |
| @@ -100,7 +99,9 @@ struct KernelCore::Impl { | |||
| 100 | next_user_process_id = KProcess::ProcessIDMin; | 99 | next_user_process_id = KProcess::ProcessIDMin; |
| 101 | next_thread_id = 1; | 100 | next_thread_id = 1; |
| 102 | 101 | ||
| 103 | cores.clear(); | 102 | for (auto& core : cores) { |
| 103 | core = nullptr; | ||
| 104 | } | ||
| 104 | 105 | ||
| 105 | global_handle_table->Finalize(); | 106 | global_handle_table->Finalize(); |
| 106 | global_handle_table.reset(); | 107 | global_handle_table.reset(); |
| @@ -199,7 +200,7 @@ struct KernelCore::Impl { | |||
| 199 | const s32 core{static_cast<s32>(i)}; | 200 | const s32 core{static_cast<s32>(i)}; |
| 200 | 201 | ||
| 201 | schedulers[i] = std::make_unique<Kernel::KScheduler>(system.Kernel()); | 202 | schedulers[i] = std::make_unique<Kernel::KScheduler>(system.Kernel()); |
| 202 | cores.emplace_back(i, system, *schedulers[i], interrupts); | 203 | cores[i] = std::make_unique<Kernel::PhysicalCore>(i, system, *schedulers[i]); |
| 203 | 204 | ||
| 204 | auto* main_thread{Kernel::KThread::Create(system.Kernel())}; | 205 | auto* main_thread{Kernel::KThread::Create(system.Kernel())}; |
| 205 | main_thread->SetName(fmt::format("MainThread:{}", core)); | 206 | main_thread->SetName(fmt::format("MainThread:{}", core)); |
| @@ -761,7 +762,7 @@ struct KernelCore::Impl { | |||
| 761 | std::unordered_set<KAutoObject*> registered_in_use_objects; | 762 | std::unordered_set<KAutoObject*> registered_in_use_objects; |
| 762 | 763 | ||
| 763 | std::unique_ptr<Core::ExclusiveMonitor> exclusive_monitor; | 764 | std::unique_ptr<Core::ExclusiveMonitor> exclusive_monitor; |
| 764 | std::vector<Kernel::PhysicalCore> cores; | 765 | std::array<std::unique_ptr<Kernel::PhysicalCore>, Core::Hardware::NUM_CPU_CORES> cores; |
| 765 | 766 | ||
| 766 | // Next host thead ID to use, 0-3 IDs represent core threads, >3 represent others | 767 | // Next host thead ID to use, 0-3 IDs represent core threads, >3 represent others |
| 767 | std::atomic<u32> next_host_thread_id{Core::Hardware::NUM_CPU_CORES}; | 768 | std::atomic<u32> next_host_thread_id{Core::Hardware::NUM_CPU_CORES}; |
| @@ -785,7 +786,6 @@ struct KernelCore::Impl { | |||
| 785 | Common::ThreadWorker service_threads_manager; | 786 | Common::ThreadWorker service_threads_manager; |
| 786 | 787 | ||
| 787 | std::array<KThread*, Core::Hardware::NUM_CPU_CORES> shutdown_threads; | 788 | std::array<KThread*, Core::Hardware::NUM_CPU_CORES> shutdown_threads; |
| 788 | std::array<Core::CPUInterruptHandler, Core::Hardware::NUM_CPU_CORES> interrupts{}; | ||
| 789 | std::array<std::unique_ptr<Kernel::KScheduler>, Core::Hardware::NUM_CPU_CORES> schedulers{}; | 789 | std::array<std::unique_ptr<Kernel::KScheduler>, Core::Hardware::NUM_CPU_CORES> schedulers{}; |
| 790 | 790 | ||
| 791 | bool is_multicore{}; | 791 | bool is_multicore{}; |
| @@ -874,11 +874,11 @@ const Kernel::KScheduler& KernelCore::Scheduler(std::size_t id) const { | |||
| 874 | } | 874 | } |
| 875 | 875 | ||
| 876 | Kernel::PhysicalCore& KernelCore::PhysicalCore(std::size_t id) { | 876 | Kernel::PhysicalCore& KernelCore::PhysicalCore(std::size_t id) { |
| 877 | return impl->cores[id]; | 877 | return *impl->cores[id]; |
| 878 | } | 878 | } |
| 879 | 879 | ||
| 880 | const Kernel::PhysicalCore& KernelCore::PhysicalCore(std::size_t id) const { | 880 | const Kernel::PhysicalCore& KernelCore::PhysicalCore(std::size_t id) const { |
| 881 | return impl->cores[id]; | 881 | return *impl->cores[id]; |
| 882 | } | 882 | } |
| 883 | 883 | ||
| 884 | size_t KernelCore::CurrentPhysicalCoreIndex() const { | 884 | size_t KernelCore::CurrentPhysicalCoreIndex() const { |
| @@ -890,11 +890,11 @@ size_t KernelCore::CurrentPhysicalCoreIndex() const { | |||
| 890 | } | 890 | } |
| 891 | 891 | ||
| 892 | Kernel::PhysicalCore& KernelCore::CurrentPhysicalCore() { | 892 | Kernel::PhysicalCore& KernelCore::CurrentPhysicalCore() { |
| 893 | return impl->cores[CurrentPhysicalCoreIndex()]; | 893 | return *impl->cores[CurrentPhysicalCoreIndex()]; |
| 894 | } | 894 | } |
| 895 | 895 | ||
| 896 | const Kernel::PhysicalCore& KernelCore::CurrentPhysicalCore() const { | 896 | const Kernel::PhysicalCore& KernelCore::CurrentPhysicalCore() const { |
| 897 | return impl->cores[CurrentPhysicalCoreIndex()]; | 897 | return *impl->cores[CurrentPhysicalCoreIndex()]; |
| 898 | } | 898 | } |
| 899 | 899 | ||
| 900 | Kernel::KScheduler* KernelCore::CurrentScheduler() { | 900 | Kernel::KScheduler* KernelCore::CurrentScheduler() { |
| @@ -906,15 +906,6 @@ Kernel::KScheduler* KernelCore::CurrentScheduler() { | |||
| 906 | return impl->schedulers[core_id].get(); | 906 | return impl->schedulers[core_id].get(); |
| 907 | } | 907 | } |
| 908 | 908 | ||
| 909 | std::array<Core::CPUInterruptHandler, Core::Hardware::NUM_CPU_CORES>& KernelCore::Interrupts() { | ||
| 910 | return impl->interrupts; | ||
| 911 | } | ||
| 912 | |||
| 913 | const std::array<Core::CPUInterruptHandler, Core::Hardware::NUM_CPU_CORES>& KernelCore::Interrupts() | ||
| 914 | const { | ||
| 915 | return impl->interrupts; | ||
| 916 | } | ||
| 917 | |||
| 918 | Kernel::TimeManager& KernelCore::TimeManager() { | 909 | Kernel::TimeManager& KernelCore::TimeManager() { |
| 919 | return impl->time_manager; | 910 | return impl->time_manager; |
| 920 | } | 911 | } |
| @@ -939,24 +930,18 @@ const KAutoObjectWithListContainer& KernelCore::ObjectListContainer() const { | |||
| 939 | return *impl->global_object_list_container; | 930 | return *impl->global_object_list_container; |
| 940 | } | 931 | } |
| 941 | 932 | ||
| 942 | void KernelCore::InterruptAllPhysicalCores() { | ||
| 943 | for (auto& physical_core : impl->cores) { | ||
| 944 | physical_core.Interrupt(); | ||
| 945 | } | ||
| 946 | } | ||
| 947 | |||
| 948 | void KernelCore::InvalidateAllInstructionCaches() { | 933 | void KernelCore::InvalidateAllInstructionCaches() { |
| 949 | for (auto& physical_core : impl->cores) { | 934 | for (auto& physical_core : impl->cores) { |
| 950 | physical_core.ArmInterface().ClearInstructionCache(); | 935 | physical_core->ArmInterface().ClearInstructionCache(); |
| 951 | } | 936 | } |
| 952 | } | 937 | } |
| 953 | 938 | ||
| 954 | void KernelCore::InvalidateCpuInstructionCacheRange(VAddr addr, std::size_t size) { | 939 | void KernelCore::InvalidateCpuInstructionCacheRange(VAddr addr, std::size_t size) { |
| 955 | for (auto& physical_core : impl->cores) { | 940 | for (auto& physical_core : impl->cores) { |
| 956 | if (!physical_core.IsInitialized()) { | 941 | if (!physical_core->IsInitialized()) { |
| 957 | continue; | 942 | continue; |
| 958 | } | 943 | } |
| 959 | physical_core.ArmInterface().InvalidateCacheRange(addr, size); | 944 | physical_core->ArmInterface().InvalidateCacheRange(addr, size); |
| 960 | } | 945 | } |
| 961 | } | 946 | } |
| 962 | 947 | ||
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 6c7cf6af2..bcf016a97 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h | |||
| @@ -9,14 +9,12 @@ | |||
| 9 | #include <string> | 9 | #include <string> |
| 10 | #include <unordered_map> | 10 | #include <unordered_map> |
| 11 | #include <vector> | 11 | #include <vector> |
| 12 | #include "core/arm/cpu_interrupt_handler.h" | ||
| 13 | #include "core/hardware_properties.h" | 12 | #include "core/hardware_properties.h" |
| 14 | #include "core/hle/kernel/k_auto_object.h" | 13 | #include "core/hle/kernel/k_auto_object.h" |
| 15 | #include "core/hle/kernel/k_slab_heap.h" | 14 | #include "core/hle/kernel/k_slab_heap.h" |
| 16 | #include "core/hle/kernel/svc_common.h" | 15 | #include "core/hle/kernel/svc_common.h" |
| 17 | 16 | ||
| 18 | namespace Core { | 17 | namespace Core { |
| 19 | class CPUInterruptHandler; | ||
| 20 | class ExclusiveMonitor; | 18 | class ExclusiveMonitor; |
| 21 | class System; | 19 | class System; |
| 22 | } // namespace Core | 20 | } // namespace Core |
| @@ -183,12 +181,6 @@ public: | |||
| 183 | 181 | ||
| 184 | const KAutoObjectWithListContainer& ObjectListContainer() const; | 182 | const KAutoObjectWithListContainer& ObjectListContainer() const; |
| 185 | 183 | ||
| 186 | std::array<Core::CPUInterruptHandler, Core::Hardware::NUM_CPU_CORES>& Interrupts(); | ||
| 187 | |||
| 188 | const std::array<Core::CPUInterruptHandler, Core::Hardware::NUM_CPU_CORES>& Interrupts() const; | ||
| 189 | |||
| 190 | void InterruptAllPhysicalCores(); | ||
| 191 | |||
| 192 | void InvalidateAllInstructionCaches(); | 184 | void InvalidateAllInstructionCaches(); |
| 193 | 185 | ||
| 194 | void InvalidateCpuInstructionCacheRange(VAddr addr, std::size_t size); | 186 | void InvalidateCpuInstructionCacheRange(VAddr addr, std::size_t size); |
diff --git a/src/core/hle/kernel/physical_core.cpp b/src/core/hle/kernel/physical_core.cpp index 6e7dacf97..d4375962f 100644 --- a/src/core/hle/kernel/physical_core.cpp +++ b/src/core/hle/kernel/physical_core.cpp | |||
| @@ -1,7 +1,6 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project | 1 | // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project |
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | 2 | // SPDX-License-Identifier: GPL-2.0-or-later |
| 3 | 3 | ||
| 4 | #include "core/arm/cpu_interrupt_handler.h" | ||
| 5 | #include "core/arm/dynarmic/arm_dynarmic_32.h" | 4 | #include "core/arm/dynarmic/arm_dynarmic_32.h" |
| 6 | #include "core/arm/dynarmic/arm_dynarmic_64.h" | 5 | #include "core/arm/dynarmic/arm_dynarmic_64.h" |
| 7 | #include "core/core.h" | 6 | #include "core/core.h" |
| @@ -11,16 +10,14 @@ | |||
| 11 | 10 | ||
| 12 | namespace Kernel { | 11 | namespace Kernel { |
| 13 | 12 | ||
| 14 | PhysicalCore::PhysicalCore(std::size_t core_index_, Core::System& system_, KScheduler& scheduler_, | 13 | PhysicalCore::PhysicalCore(std::size_t core_index_, Core::System& system_, KScheduler& scheduler_) |
| 15 | Core::CPUInterrupts& interrupts_) | 14 | : core_index{core_index_}, system{system_}, scheduler{scheduler_} { |
| 16 | : core_index{core_index_}, system{system_}, scheduler{scheduler_}, | ||
| 17 | interrupts{interrupts_}, guard{std::make_unique<std::mutex>()} { | ||
| 18 | #ifdef ARCHITECTURE_x86_64 | 15 | #ifdef ARCHITECTURE_x86_64 |
| 19 | // TODO(bunnei): Initialization relies on a core being available. We may later replace this with | 16 | // TODO(bunnei): Initialization relies on a core being available. We may later replace this with |
| 20 | // a 32-bit instance of Dynarmic. This should be abstracted out to a CPU manager. | 17 | // a 32-bit instance of Dynarmic. This should be abstracted out to a CPU manager. |
| 21 | auto& kernel = system.Kernel(); | 18 | auto& kernel = system.Kernel(); |
| 22 | arm_interface = std::make_unique<Core::ARM_Dynarmic_64>( | 19 | arm_interface = std::make_unique<Core::ARM_Dynarmic_64>( |
| 23 | system, interrupts, kernel.IsMulticore(), kernel.GetExclusiveMonitor(), core_index); | 20 | system, kernel.IsMulticore(), kernel.GetExclusiveMonitor(), core_index); |
| 24 | #else | 21 | #else |
| 25 | #error Platform not supported yet. | 22 | #error Platform not supported yet. |
| 26 | #endif | 23 | #endif |
| @@ -34,7 +31,7 @@ void PhysicalCore::Initialize([[maybe_unused]] bool is_64_bit) { | |||
| 34 | if (!is_64_bit) { | 31 | if (!is_64_bit) { |
| 35 | // We already initialized a 64-bit core, replace with a 32-bit one. | 32 | // We already initialized a 64-bit core, replace with a 32-bit one. |
| 36 | arm_interface = std::make_unique<Core::ARM_Dynarmic_32>( | 33 | arm_interface = std::make_unique<Core::ARM_Dynarmic_32>( |
| 37 | system, interrupts, kernel.IsMulticore(), kernel.GetExclusiveMonitor(), core_index); | 34 | system, kernel.IsMulticore(), kernel.GetExclusiveMonitor(), core_index); |
| 38 | } | 35 | } |
| 39 | #else | 36 | #else |
| 40 | #error Platform not supported yet. | 37 | #error Platform not supported yet. |
| @@ -47,24 +44,26 @@ void PhysicalCore::Run() { | |||
| 47 | } | 44 | } |
| 48 | 45 | ||
| 49 | void PhysicalCore::Idle() { | 46 | void PhysicalCore::Idle() { |
| 50 | interrupts[core_index].AwaitInterrupt(); | 47 | std::unique_lock lk{guard}; |
| 48 | on_interrupt.wait(lk, [this] { return is_interrupted; }); | ||
| 51 | } | 49 | } |
| 52 | 50 | ||
| 53 | bool PhysicalCore::IsInterrupted() const { | 51 | bool PhysicalCore::IsInterrupted() const { |
| 54 | return interrupts[core_index].IsInterrupted(); | 52 | return is_interrupted; |
| 55 | } | 53 | } |
| 56 | 54 | ||
| 57 | void PhysicalCore::Interrupt() { | 55 | void PhysicalCore::Interrupt() { |
| 58 | guard->lock(); | 56 | std::unique_lock lk{guard}; |
| 59 | interrupts[core_index].SetInterrupt(true); | 57 | is_interrupted = true; |
| 60 | arm_interface->SignalInterrupt(); | 58 | arm_interface->SignalInterrupt(); |
| 61 | guard->unlock(); | 59 | on_interrupt.notify_all(); |
| 62 | } | 60 | } |
| 63 | 61 | ||
| 64 | void PhysicalCore::ClearInterrupt() { | 62 | void PhysicalCore::ClearInterrupt() { |
| 65 | guard->lock(); | 63 | std::unique_lock lk{guard}; |
| 66 | interrupts[core_index].SetInterrupt(false); | 64 | is_interrupted = false; |
| 67 | guard->unlock(); | 65 | arm_interface->ClearInterrupt(); |
| 66 | on_interrupt.notify_all(); | ||
| 68 | } | 67 | } |
| 69 | 68 | ||
| 70 | } // namespace Kernel | 69 | } // namespace Kernel |
diff --git a/src/core/hle/kernel/physical_core.h b/src/core/hle/kernel/physical_core.h index 898d1e5db..2fc8d4be2 100644 --- a/src/core/hle/kernel/physical_core.h +++ b/src/core/hle/kernel/physical_core.h | |||
| @@ -14,7 +14,6 @@ class KScheduler; | |||
| 14 | } // namespace Kernel | 14 | } // namespace Kernel |
| 15 | 15 | ||
| 16 | namespace Core { | 16 | namespace Core { |
| 17 | class CPUInterruptHandler; | ||
| 18 | class ExclusiveMonitor; | 17 | class ExclusiveMonitor; |
| 19 | class System; | 18 | class System; |
| 20 | } // namespace Core | 19 | } // namespace Core |
| @@ -23,15 +22,11 @@ namespace Kernel { | |||
| 23 | 22 | ||
| 24 | class PhysicalCore { | 23 | class PhysicalCore { |
| 25 | public: | 24 | public: |
| 26 | PhysicalCore(std::size_t core_index_, Core::System& system_, KScheduler& scheduler_, | 25 | PhysicalCore(std::size_t core_index_, Core::System& system_, KScheduler& scheduler_); |
| 27 | Core::CPUInterrupts& interrupts_); | ||
| 28 | ~PhysicalCore(); | 26 | ~PhysicalCore(); |
| 29 | 27 | ||
| 30 | PhysicalCore(const PhysicalCore&) = delete; | 28 | YUZU_NON_COPYABLE(PhysicalCore); |
| 31 | PhysicalCore& operator=(const PhysicalCore&) = delete; | 29 | YUZU_NON_MOVEABLE(PhysicalCore); |
| 32 | |||
| 33 | PhysicalCore(PhysicalCore&&) = default; | ||
| 34 | PhysicalCore& operator=(PhysicalCore&&) = delete; | ||
| 35 | 30 | ||
| 36 | /// Initialize the core for the specified parameters. | 31 | /// Initialize the core for the specified parameters. |
| 37 | void Initialize(bool is_64_bit); | 32 | void Initialize(bool is_64_bit); |
| @@ -86,9 +81,11 @@ private: | |||
| 86 | const std::size_t core_index; | 81 | const std::size_t core_index; |
| 87 | Core::System& system; | 82 | Core::System& system; |
| 88 | Kernel::KScheduler& scheduler; | 83 | Kernel::KScheduler& scheduler; |
| 89 | Core::CPUInterrupts& interrupts; | 84 | |
| 90 | std::unique_ptr<std::mutex> guard; | 85 | std::mutex guard; |
| 86 | std::condition_variable on_interrupt; | ||
| 91 | std::unique_ptr<Core::ARM_Interface> arm_interface; | 87 | std::unique_ptr<Core::ARM_Interface> arm_interface; |
| 88 | bool is_interrupted; | ||
| 92 | }; | 89 | }; |
| 93 | 90 | ||
| 94 | } // namespace Kernel | 91 | } // namespace Kernel |