diff options
| author | 2020-01-25 18:55:32 -0400 | |
|---|---|---|
| committer | 2020-01-25 18:55:32 -0400 | |
| commit | 4d6a86b03fe6ae0d98838a21613b66d5196150af (patch) | |
| tree | 21f4b8e63e6435b2d816936af8b494882a3cdfb2 /src/core/hle/kernel/kernel.cpp | |
| parent | Kernel: Implement Physical Core. (diff) | |
| download | yuzu-4d6a86b03fe6ae0d98838a21613b66d5196150af.tar.gz yuzu-4d6a86b03fe6ae0d98838a21613b66d5196150af.tar.xz yuzu-4d6a86b03fe6ae0d98838a21613b66d5196150af.zip | |
Core: Refactor CPU Management.
This commit moves ARM Interface and Scheduler handling into the kernel.
Diffstat (limited to 'src/core/hle/kernel/kernel.cpp')
| -rw-r--r-- | src/core/hle/kernel/kernel.cpp | 64 |
1 files changed, 63 insertions, 1 deletions
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 1d0783bd3..b7fd480d1 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp | |||
| @@ -9,7 +9,11 @@ | |||
| 9 | 9 | ||
| 10 | #include "common/assert.h" | 10 | #include "common/assert.h" |
| 11 | #include "common/logging/log.h" | 11 | #include "common/logging/log.h" |
| 12 | 12 | #include "core/arm/arm_interface.h" | |
| 13 | #ifdef ARCHITECTURE_x86_64 | ||
| 14 | #include "core/arm/dynarmic/arm_dynarmic.h" | ||
| 15 | #endif | ||
| 16 | #include "core/arm/exclusive_monitor.h" | ||
| 13 | #include "core/core.h" | 17 | #include "core/core.h" |
| 14 | #include "core/core_timing.h" | 18 | #include "core/core_timing.h" |
| 15 | #include "core/core_timing_util.h" | 19 | #include "core/core_timing_util.h" |
| @@ -17,6 +21,7 @@ | |||
| 17 | #include "core/hle/kernel/errors.h" | 21 | #include "core/hle/kernel/errors.h" |
| 18 | #include "core/hle/kernel/handle_table.h" | 22 | #include "core/hle/kernel/handle_table.h" |
| 19 | #include "core/hle/kernel/kernel.h" | 23 | #include "core/hle/kernel/kernel.h" |
| 24 | #include "core/hle/kernel/physical_core.h" | ||
| 20 | #include "core/hle/kernel/process.h" | 25 | #include "core/hle/kernel/process.h" |
| 21 | #include "core/hle/kernel/resource_limit.h" | 26 | #include "core/hle/kernel/resource_limit.h" |
| 22 | #include "core/hle/kernel/scheduler.h" | 27 | #include "core/hle/kernel/scheduler.h" |
| @@ -98,6 +103,7 @@ struct KernelCore::Impl { | |||
| 98 | void Initialize(KernelCore& kernel) { | 103 | void Initialize(KernelCore& kernel) { |
| 99 | Shutdown(); | 104 | Shutdown(); |
| 100 | 105 | ||
| 106 | InitializePhysicalCores(kernel); | ||
| 101 | InitializeSystemResourceLimit(kernel); | 107 | InitializeSystemResourceLimit(kernel); |
| 102 | InitializeThreads(); | 108 | InitializeThreads(); |
| 103 | InitializePreemption(); | 109 | InitializePreemption(); |
| @@ -121,6 +127,20 @@ struct KernelCore::Impl { | |||
| 121 | global_scheduler.Shutdown(); | 127 | global_scheduler.Shutdown(); |
| 122 | 128 | ||
| 123 | named_ports.clear(); | 129 | named_ports.clear(); |
| 130 | |||
| 131 | for (auto& core : cores) { | ||
| 132 | core.Shutdown(); | ||
| 133 | } | ||
| 134 | cores.clear(); | ||
| 135 | |||
| 136 | exclusive_monitor.reset(nullptr); | ||
| 137 | } | ||
| 138 | |||
| 139 | void InitializePhysicalCores(KernelCore& kernel) { | ||
| 140 | exclusive_monitor = MakeExclusiveMonitor(); | ||
| 141 | for (std::size_t i = 0; i < global_scheduler.CpuCoresCount(); i++) { | ||
| 142 | cores.emplace_back(system, kernel, i, *exclusive_monitor); | ||
| 143 | } | ||
| 124 | } | 144 | } |
| 125 | 145 | ||
| 126 | // Creates the default system resource limit | 146 | // Creates the default system resource limit |
| @@ -136,6 +156,7 @@ struct KernelCore::Impl { | |||
| 136 | ASSERT(system_resource_limit->SetLimitValue(ResourceType::Sessions, 900).IsSuccess()); | 156 | ASSERT(system_resource_limit->SetLimitValue(ResourceType::Sessions, 900).IsSuccess()); |
| 137 | } | 157 | } |
| 138 | 158 | ||
| 159 | |||
| 139 | void InitializeThreads() { | 160 | void InitializeThreads() { |
| 140 | thread_wakeup_event_type = | 161 | thread_wakeup_event_type = |
| 141 | Core::Timing::CreateEvent("ThreadWakeupCallback", ThreadWakeupCallback); | 162 | Core::Timing::CreateEvent("ThreadWakeupCallback", ThreadWakeupCallback); |
| @@ -163,6 +184,16 @@ struct KernelCore::Impl { | |||
| 163 | system.Memory().SetCurrentPageTable(*process); | 184 | system.Memory().SetCurrentPageTable(*process); |
| 164 | } | 185 | } |
| 165 | 186 | ||
| 187 | std::unique_ptr<Core::ExclusiveMonitor> MakeExclusiveMonitor() { | ||
| 188 | #ifdef ARCHITECTURE_x86_64 | ||
| 189 | return std::make_unique<Core::DynarmicExclusiveMonitor>(system.Memory(), | ||
| 190 | global_scheduler.CpuCoresCount()); | ||
| 191 | #else | ||
| 192 | // TODO(merry): Passthrough exclusive monitor | ||
| 193 | return nullptr; | ||
| 194 | #endif | ||
| 195 | } | ||
| 196 | |||
| 166 | std::atomic<u32> next_object_id{0}; | 197 | std::atomic<u32> next_object_id{0}; |
| 167 | std::atomic<u64> next_kernel_process_id{Process::InitialKIPIDMin}; | 198 | std::atomic<u64> next_kernel_process_id{Process::InitialKIPIDMin}; |
| 168 | std::atomic<u64> next_user_process_id{Process::ProcessIDMin}; | 199 | std::atomic<u64> next_user_process_id{Process::ProcessIDMin}; |
| @@ -186,6 +217,9 @@ struct KernelCore::Impl { | |||
| 186 | /// the ConnectToPort SVC. | 217 | /// the ConnectToPort SVC. |
| 187 | NamedPortTable named_ports; | 218 | NamedPortTable named_ports; |
| 188 | 219 | ||
| 220 | std::unique_ptr<Core::ExclusiveMonitor> exclusive_monitor; | ||
| 221 | std::vector<Kernel::PhysicalCore> cores; | ||
| 222 | |||
| 189 | // System context | 223 | // System context |
| 190 | Core::System& system; | 224 | Core::System& system; |
| 191 | }; | 225 | }; |
| @@ -240,6 +274,34 @@ const Kernel::GlobalScheduler& KernelCore::GlobalScheduler() const { | |||
| 240 | return impl->global_scheduler; | 274 | return impl->global_scheduler; |
| 241 | } | 275 | } |
| 242 | 276 | ||
| 277 | Kernel::PhysicalCore& KernelCore::PhysicalCore(std::size_t id) { | ||
| 278 | return impl->cores[id]; | ||
| 279 | } | ||
| 280 | |||
| 281 | const Kernel::PhysicalCore& KernelCore::PhysicalCore(std::size_t id) const { | ||
| 282 | return impl->cores[id]; | ||
| 283 | } | ||
| 284 | |||
| 285 | Core::ExclusiveMonitor& KernelCore::GetExclusiveMonitor() { | ||
| 286 | return *impl->exclusive_monitor; | ||
| 287 | } | ||
| 288 | |||
| 289 | const Core::ExclusiveMonitor& KernelCore::GetExclusiveMonitor() const { | ||
| 290 | return *impl->exclusive_monitor; | ||
| 291 | } | ||
| 292 | |||
| 293 | void KernelCore::InvalidateAllInstructionCaches() { | ||
| 294 | for (std::size_t i = 0; i < impl->global_scheduler.CpuCoresCount(); i++) { | ||
| 295 | PhysicalCore(i).ArmInterface().ClearInstructionCache(); | ||
| 296 | } | ||
| 297 | } | ||
| 298 | |||
| 299 | void KernelCore::PrepareReschedule(std::size_t id) { | ||
| 300 | if (id >= 0 && id < impl->global_scheduler.CpuCoresCount()) { | ||
| 301 | impl->cores[id].Stop(); | ||
| 302 | } | ||
| 303 | } | ||
| 304 | |||
| 243 | void KernelCore::AddNamedPort(std::string name, std::shared_ptr<ClientPort> port) { | 305 | void KernelCore::AddNamedPort(std::string name, std::shared_ptr<ClientPort> port) { |
| 244 | impl->named_ports.emplace(std::move(name), std::move(port)); | 306 | impl->named_ports.emplace(std::move(name), std::move(port)); |
| 245 | } | 307 | } |