diff options
Diffstat (limited to 'src/core/hle/kernel')
| -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 |
4 files changed, 34 insertions, 61 deletions
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 |