summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/CMakeLists.txt2
-rw-r--r--src/core/core.cpp35
-rw-r--r--src/core/core_cpu.cpp76
-rw-r--r--src/core/core_cpu.h61
-rw-r--r--src/core/cpu_core_manager.cpp63
-rw-r--r--src/core/cpu_core_manager.h16
-rw-r--r--src/core/hle/kernel/kernel.cpp64
-rw-r--r--src/core/hle/kernel/kernel.h17
-rw-r--r--src/core/hle/kernel/physical_core.cpp36
-rw-r--r--src/core/hle/kernel/physical_core.h22
10 files changed, 168 insertions, 224 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 1a3647a67..d5b8091ae 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -158,6 +158,8 @@ add_library(core STATIC
hle/kernel/mutex.h
hle/kernel/object.cpp
hle/kernel/object.h
+ hle/kernel/physical_core.cpp
+ hle/kernel/physical_core.h
hle/kernel/process.cpp
hle/kernel/process.h
hle/kernel/process_capability.cpp
diff --git a/src/core/core.cpp b/src/core/core.cpp
index d697b80ef..27b8d3408 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -28,6 +28,7 @@
#include "core/hardware_interrupt_manager.h"
#include "core/hle/kernel/client_port.h"
#include "core/hle/kernel/kernel.h"
+#include "core/hle/kernel/physical_core.h"
#include "core/hle/kernel/process.h"
#include "core/hle/kernel/scheduler.h"
#include "core/hle/kernel/thread.h"
@@ -119,6 +120,15 @@ struct System::Impl {
return cpu_core_manager.GetCurrentCore();
}
+ Kernel::PhysicalCore& CurrentPhysicalCore() {
+ const auto i = cpu_core_manager.GetCurrentCoreIndex();
+ return kernel.PhysicalCore(i);
+ }
+
+ Kernel::PhysicalCore& GetPhysicalCore(std::size_t index) {
+ return kernel.PhysicalCore(index);
+ }
+
ResultStatus RunLoop(bool tight_loop) {
status = ResultStatus::Success;
@@ -131,8 +141,8 @@ struct System::Impl {
LOG_DEBUG(HW_Memory, "initialized OK");
core_timing.Initialize();
- cpu_core_manager.Initialize();
kernel.Initialize();
+ cpu_core_manager.Initialize();
const auto current_time = std::chrono::duration_cast<std::chrono::seconds>(
std::chrono::system_clock::now().time_since_epoch());
@@ -205,7 +215,6 @@ struct System::Impl {
// Main process has been loaded and been made current.
// Begin GPU and CPU execution.
gpu_core->Start();
- cpu_core_manager.StartThreads();
// Initialize cheat engine
if (cheat_engine) {
@@ -394,7 +403,7 @@ System::ResultStatus System::SingleStep() {
}
void System::InvalidateCpuInstructionCaches() {
- impl->cpu_core_manager.InvalidateAllInstructionCaches();
+ impl->kernel.InvalidateAllInstructionCaches();
}
System::ResultStatus System::Load(Frontend::EmuWindow& emu_window, const std::string& filepath) {
@@ -428,11 +437,11 @@ const TelemetrySession& System::TelemetrySession() const {
}
ARM_Interface& System::CurrentArmInterface() {
- return CurrentCpuCore().ArmInterface();
+ return impl->CurrentPhysicalCore().ArmInterface();
}
const ARM_Interface& System::CurrentArmInterface() const {
- return CurrentCpuCore().ArmInterface();
+ return impl->CurrentPhysicalCore().ArmInterface();
}
std::size_t System::CurrentCoreIndex() const {
@@ -440,19 +449,19 @@ std::size_t System::CurrentCoreIndex() const {
}
Kernel::Scheduler& System::CurrentScheduler() {
- return CurrentCpuCore().Scheduler();
+ return impl->CurrentPhysicalCore().Scheduler();
}
const Kernel::Scheduler& System::CurrentScheduler() const {
- return CurrentCpuCore().Scheduler();
+ return impl->CurrentPhysicalCore().Scheduler();
}
Kernel::Scheduler& System::Scheduler(std::size_t core_index) {
- return CpuCore(core_index).Scheduler();
+ return impl->GetPhysicalCore(core_index).Scheduler();
}
const Kernel::Scheduler& System::Scheduler(std::size_t core_index) const {
- return CpuCore(core_index).Scheduler();
+ return impl->GetPhysicalCore(core_index).Scheduler();
}
/// Gets the global scheduler
@@ -474,11 +483,11 @@ const Kernel::Process* System::CurrentProcess() const {
}
ARM_Interface& System::ArmInterface(std::size_t core_index) {
- return CpuCore(core_index).ArmInterface();
+ return impl->GetPhysicalCore(core_index).ArmInterface();
}
const ARM_Interface& System::ArmInterface(std::size_t core_index) const {
- return CpuCore(core_index).ArmInterface();
+ return impl->GetPhysicalCore(core_index).ArmInterface();
}
Cpu& System::CpuCore(std::size_t core_index) {
@@ -491,11 +500,11 @@ const Cpu& System::CpuCore(std::size_t core_index) const {
}
ExclusiveMonitor& System::Monitor() {
- return impl->cpu_core_manager.GetExclusiveMonitor();
+ return impl->kernel.GetExclusiveMonitor();
}
const ExclusiveMonitor& System::Monitor() const {
- return impl->cpu_core_manager.GetExclusiveMonitor();
+ return impl->kernel.GetExclusiveMonitor();
}
Memory::Memory& System::Memory() {
diff --git a/src/core/core_cpu.cpp b/src/core/core_cpu.cpp
index 630cd4feb..bcfdf0198 100644
--- a/src/core/core_cpu.cpp
+++ b/src/core/core_cpu.cpp
@@ -14,6 +14,8 @@
#include "core/core.h"
#include "core/core_cpu.h"
#include "core/core_timing.h"
+#include "core/hle/kernel/kernel.h"
+#include "core/hle/kernel/physical_core.h"
#include "core/hle/kernel/scheduler.h"
#include "core/hle/kernel/thread.h"
#include "core/hle/lock.h"
@@ -21,68 +23,15 @@
namespace Core {
-void CpuBarrier::NotifyEnd() {
- std::unique_lock lock{mutex};
- end = true;
- condition.notify_all();
-}
-
-bool CpuBarrier::Rendezvous() {
- if (!Settings::values.use_multi_core) {
- // Meaningless when running in single-core mode
- return true;
- }
-
- if (!end) {
- std::unique_lock lock{mutex};
-
- --cores_waiting;
- if (!cores_waiting) {
- cores_waiting = NUM_CPU_CORES;
- condition.notify_all();
- return true;
- }
-
- condition.wait(lock);
- return true;
- }
-
- return false;
-}
-
-Cpu::Cpu(System& system, ExclusiveMonitor& exclusive_monitor, CpuBarrier& cpu_barrier,
- std::size_t core_index)
- : cpu_barrier{cpu_barrier}, global_scheduler{system.GlobalScheduler()},
- core_timing{system.CoreTiming()}, core_index{core_index} {
-#ifdef ARCHITECTURE_x86_64
- arm_interface = std::make_unique<ARM_Dynarmic>(system, exclusive_monitor, core_index);
-#else
- arm_interface = std::make_unique<ARM_Unicorn>(system);
- LOG_WARNING(Core, "CPU JIT requested, but Dynarmic not available");
-#endif
-
- scheduler = std::make_unique<Kernel::Scheduler>(system, *arm_interface, core_index);
+Cpu::Cpu(System& system, std::size_t core_index)
+ : global_scheduler{system.GlobalScheduler()},
+ physical_core{system.Kernel().PhysicalCore(core_index)}, core_timing{system.CoreTiming()},
+ core_index{core_index} {
}
Cpu::~Cpu() = default;
-std::unique_ptr<ExclusiveMonitor> Cpu::MakeExclusiveMonitor(
- [[maybe_unused]] Memory::Memory& memory, [[maybe_unused]] std::size_t num_cores) {
-#ifdef ARCHITECTURE_x86_64
- return std::make_unique<DynarmicExclusiveMonitor>(memory, num_cores);
-#else
- // TODO(merry): Passthrough exclusive monitor
- return nullptr;
-#endif
-}
-
void Cpu::RunLoop(bool tight_loop) {
- // Wait for all other CPU cores to complete the previous slice, such that they run in lock-step
- if (!cpu_barrier.Rendezvous()) {
- // If rendezvous failed, session has been killed
- return;
- }
-
Reschedule();
// If we don't have a currently active thread then don't execute instructions,
@@ -92,12 +41,10 @@ void Cpu::RunLoop(bool tight_loop) {
core_timing.Idle();
} else {
if (tight_loop) {
- arm_interface->Run();
+ physical_core.Run();
} else {
- arm_interface->Step();
+ physical_core.Step();
}
- // We are stopping a run, exclusive state must be cleared
- arm_interface->ClearExclusiveState();
}
core_timing.Advance();
@@ -109,7 +56,7 @@ void Cpu::SingleStep() {
}
void Cpu::PrepareReschedule() {
- arm_interface->PrepareReschedule();
+ physical_core.Stop();
}
void Cpu::Reschedule() {
@@ -117,11 +64,8 @@ void Cpu::Reschedule() {
std::lock_guard lock(HLE::g_hle_lock);
global_scheduler.SelectThread(core_index);
- scheduler->TryDoContextSwitch();
-}
-void Cpu::Shutdown() {
- scheduler->Shutdown();
+ physical_core.Scheduler().TryDoContextSwitch();
}
} // namespace Core
diff --git a/src/core/core_cpu.h b/src/core/core_cpu.h
index 78f5021a2..6f7aec8f9 100644
--- a/src/core/core_cpu.h
+++ b/src/core/core_cpu.h
@@ -13,7 +13,7 @@
namespace Kernel {
class GlobalScheduler;
-class Scheduler;
+class PhysicalCore;
} // namespace Kernel
namespace Core {
@@ -30,32 +30,11 @@ class Memory;
namespace Core {
-class ARM_Interface;
-class ExclusiveMonitor;
-
constexpr unsigned NUM_CPU_CORES{4};
-class CpuBarrier {
-public:
- bool IsAlive() const {
- return !end;
- }
-
- void NotifyEnd();
-
- bool Rendezvous();
-
-private:
- unsigned cores_waiting{NUM_CPU_CORES};
- std::mutex mutex;
- std::condition_variable condition;
- std::atomic<bool> end{};
-};
-
class Cpu {
public:
- Cpu(System& system, ExclusiveMonitor& exclusive_monitor, CpuBarrier& cpu_barrier,
- std::size_t core_index);
+ Cpu(System& system, std::size_t core_index);
~Cpu();
void RunLoop(bool tight_loop = true);
@@ -64,22 +43,6 @@ public:
void PrepareReschedule();
- ARM_Interface& ArmInterface() {
- return *arm_interface;
- }
-
- const ARM_Interface& ArmInterface() const {
- return *arm_interface;
- }
-
- Kernel::Scheduler& Scheduler() {
- return *scheduler;
- }
-
- const Kernel::Scheduler& Scheduler() const {
- return *scheduler;
- }
-
bool IsMainCore() const {
return core_index == 0;
}
@@ -88,29 +51,11 @@ public:
return core_index;
}
- void Shutdown();
-
- /**
- * Creates an exclusive monitor to handle exclusive reads/writes.
- *
- * @param memory The current memory subsystem that the monitor may wish
- * to keep track of.
- *
- * @param num_cores The number of cores to assume about the CPU.
- *
- * @returns The constructed exclusive monitor instance, or nullptr if the current
- * CPU backend is unable to use an exclusive monitor.
- */
- static std::unique_ptr<ExclusiveMonitor> MakeExclusiveMonitor(Memory::Memory& memory,
- std::size_t num_cores);
-
private:
void Reschedule();
- std::unique_ptr<ARM_Interface> arm_interface;
- CpuBarrier& cpu_barrier;
Kernel::GlobalScheduler& global_scheduler;
- std::unique_ptr<Kernel::Scheduler> scheduler;
+ Kernel::PhysicalCore& physical_core;
Timing::CoreTiming& core_timing;
std::atomic<bool> reschedule_pending = false;
diff --git a/src/core/cpu_core_manager.cpp b/src/core/cpu_core_manager.cpp
index f04a34133..ab03e8fdf 100644
--- a/src/core/cpu_core_manager.cpp
+++ b/src/core/cpu_core_manager.cpp
@@ -24,46 +24,16 @@ CpuCoreManager::CpuCoreManager(System& system) : system{system} {}
CpuCoreManager::~CpuCoreManager() = default;
void CpuCoreManager::Initialize() {
- barrier = std::make_unique<CpuBarrier>();
- exclusive_monitor = Cpu::MakeExclusiveMonitor(system.Memory(), cores.size());
for (std::size_t index = 0; index < cores.size(); ++index) {
- cores[index] = std::make_unique<Cpu>(system, *exclusive_monitor, *barrier, index);
- }
-}
-
-void CpuCoreManager::StartThreads() {
- // Create threads for CPU cores 1-3, and build thread_to_cpu map
- // CPU core 0 is run on the main thread
- thread_to_cpu[std::this_thread::get_id()] = cores[0].get();
- if (!Settings::values.use_multi_core) {
- return;
- }
-
- for (std::size_t index = 0; index < core_threads.size(); ++index) {
- core_threads[index] = std::make_unique<std::thread>(RunCpuCore, std::cref(system),
- std::ref(*cores[index + 1]));
- thread_to_cpu[core_threads[index]->get_id()] = cores[index + 1].get();
+ cores[index] = std::make_unique<Cpu>(system, index);
}
}
void CpuCoreManager::Shutdown() {
- barrier->NotifyEnd();
- if (Settings::values.use_multi_core) {
- for (auto& thread : core_threads) {
- thread->join();
- thread.reset();
- }
- }
-
- thread_to_cpu.clear();
for (auto& cpu_core : cores) {
- cpu_core->Shutdown();
cpu_core.reset();
}
-
- exclusive_monitor.reset();
- barrier.reset();
}
Cpu& CpuCoreManager::GetCore(std::size_t index) {
@@ -74,42 +44,17 @@ const Cpu& CpuCoreManager::GetCore(std::size_t index) const {
return *cores.at(index);
}
-ExclusiveMonitor& CpuCoreManager::GetExclusiveMonitor() {
- return *exclusive_monitor;
-}
-
-const ExclusiveMonitor& CpuCoreManager::GetExclusiveMonitor() const {
- return *exclusive_monitor;
-}
-
Cpu& CpuCoreManager::GetCurrentCore() {
- if (Settings::values.use_multi_core) {
- const auto& search = thread_to_cpu.find(std::this_thread::get_id());
- ASSERT(search != thread_to_cpu.end());
- ASSERT(search->second);
- return *search->second;
- }
-
// Otherwise, use single-threaded mode active_core variable
return *cores[active_core];
}
const Cpu& CpuCoreManager::GetCurrentCore() const {
- if (Settings::values.use_multi_core) {
- const auto& search = thread_to_cpu.find(std::this_thread::get_id());
- ASSERT(search != thread_to_cpu.end());
- ASSERT(search->second);
- return *search->second;
- }
-
// Otherwise, use single-threaded mode active_core variable
return *cores[active_core];
}
void CpuCoreManager::RunLoop(bool tight_loop) {
- // Update thread_to_cpu in case Core 0 is run from a different host thread
- thread_to_cpu[std::this_thread::get_id()] = cores[0].get();
-
if (GDBStub::IsServerEnabled()) {
GDBStub::HandlePacket();
@@ -143,10 +88,4 @@ void CpuCoreManager::RunLoop(bool tight_loop) {
}
}
-void CpuCoreManager::InvalidateAllInstructionCaches() {
- for (auto& cpu : cores) {
- cpu->ArmInterface().ClearInstructionCache();
- }
-}
-
} // namespace Core
diff --git a/src/core/cpu_core_manager.h b/src/core/cpu_core_manager.h
index 2cbbf8216..2a7f84d5c 100644
--- a/src/core/cpu_core_manager.h
+++ b/src/core/cpu_core_manager.h
@@ -12,8 +12,6 @@
namespace Core {
class Cpu;
-class CpuBarrier;
-class ExclusiveMonitor;
class System;
class CpuCoreManager {
@@ -28,7 +26,6 @@ public:
CpuCoreManager& operator=(CpuCoreManager&&) = delete;
void Initialize();
- void StartThreads();
void Shutdown();
Cpu& GetCore(std::size_t index);
@@ -37,25 +34,18 @@ public:
Cpu& GetCurrentCore();
const Cpu& GetCurrentCore() const;
- ExclusiveMonitor& GetExclusiveMonitor();
- const ExclusiveMonitor& GetExclusiveMonitor() const;
+ std::size_t GetCurrentCoreIndex() const {
+ return active_core;
+ }
void RunLoop(bool tight_loop);
- void InvalidateAllInstructionCaches();
-
private:
static constexpr std::size_t NUM_CPU_CORES = 4;
- std::unique_ptr<ExclusiveMonitor> exclusive_monitor;
- std::unique_ptr<CpuBarrier> barrier;
std::array<std::unique_ptr<Cpu>, NUM_CPU_CORES> cores;
- std::array<std::unique_ptr<std::thread>, NUM_CPU_CORES - 1> core_threads;
std::size_t active_core{}; ///< Active core, only used in single thread mode
- /// Map of guest threads to CPU cores
- std::map<std::thread::id, Cpu*> thread_to_cpu;
-
System& system;
};
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 @@
#include "common/assert.h"
#include "common/logging/log.h"
-
+#include "core/arm/arm_interface.h"
+#ifdef ARCHITECTURE_x86_64
+#include "core/arm/dynarmic/arm_dynarmic.h"
+#endif
+#include "core/arm/exclusive_monitor.h"
#include "core/core.h"
#include "core/core_timing.h"
#include "core/core_timing_util.h"
@@ -17,6 +21,7 @@
#include "core/hle/kernel/errors.h"
#include "core/hle/kernel/handle_table.h"
#include "core/hle/kernel/kernel.h"
+#include "core/hle/kernel/physical_core.h"
#include "core/hle/kernel/process.h"
#include "core/hle/kernel/resource_limit.h"
#include "core/hle/kernel/scheduler.h"
@@ -98,6 +103,7 @@ struct KernelCore::Impl {
void Initialize(KernelCore& kernel) {
Shutdown();
+ InitializePhysicalCores(kernel);
InitializeSystemResourceLimit(kernel);
InitializeThreads();
InitializePreemption();
@@ -121,6 +127,20 @@ struct KernelCore::Impl {
global_scheduler.Shutdown();
named_ports.clear();
+
+ for (auto& core : cores) {
+ core.Shutdown();
+ }
+ cores.clear();
+
+ exclusive_monitor.reset(nullptr);
+ }
+
+ void InitializePhysicalCores(KernelCore& kernel) {
+ exclusive_monitor = MakeExclusiveMonitor();
+ for (std::size_t i = 0; i < global_scheduler.CpuCoresCount(); i++) {
+ cores.emplace_back(system, kernel, i, *exclusive_monitor);
+ }
}
// Creates the default system resource limit
@@ -136,6 +156,7 @@ struct KernelCore::Impl {
ASSERT(system_resource_limit->SetLimitValue(ResourceType::Sessions, 900).IsSuccess());
}
+
void InitializeThreads() {
thread_wakeup_event_type =
Core::Timing::CreateEvent("ThreadWakeupCallback", ThreadWakeupCallback);
@@ -163,6 +184,16 @@ struct KernelCore::Impl {
system.Memory().SetCurrentPageTable(*process);
}
+ std::unique_ptr<Core::ExclusiveMonitor> MakeExclusiveMonitor() {
+ #ifdef ARCHITECTURE_x86_64
+ return std::make_unique<Core::DynarmicExclusiveMonitor>(system.Memory(),
+ global_scheduler.CpuCoresCount());
+ #else
+ // TODO(merry): Passthrough exclusive monitor
+ return nullptr;
+ #endif
+ }
+
std::atomic<u32> next_object_id{0};
std::atomic<u64> next_kernel_process_id{Process::InitialKIPIDMin};
std::atomic<u64> next_user_process_id{Process::ProcessIDMin};
@@ -186,6 +217,9 @@ struct KernelCore::Impl {
/// the ConnectToPort SVC.
NamedPortTable named_ports;
+ std::unique_ptr<Core::ExclusiveMonitor> exclusive_monitor;
+ std::vector<Kernel::PhysicalCore> cores;
+
// System context
Core::System& system;
};
@@ -240,6 +274,34 @@ const Kernel::GlobalScheduler& KernelCore::GlobalScheduler() const {
return impl->global_scheduler;
}
+Kernel::PhysicalCore& KernelCore::PhysicalCore(std::size_t id) {
+ return impl->cores[id];
+}
+
+const Kernel::PhysicalCore& KernelCore::PhysicalCore(std::size_t id) const {
+ return impl->cores[id];
+}
+
+Core::ExclusiveMonitor& KernelCore::GetExclusiveMonitor() {
+ return *impl->exclusive_monitor;
+}
+
+const Core::ExclusiveMonitor& KernelCore::GetExclusiveMonitor() const {
+ return *impl->exclusive_monitor;
+}
+
+void KernelCore::InvalidateAllInstructionCaches() {
+ for (std::size_t i = 0; i < impl->global_scheduler.CpuCoresCount(); i++) {
+ PhysicalCore(i).ArmInterface().ClearInstructionCache();
+ }
+}
+
+void KernelCore::PrepareReschedule(std::size_t id) {
+ if (id >= 0 && id < impl->global_scheduler.CpuCoresCount()) {
+ impl->cores[id].Stop();
+ }
+}
+
void KernelCore::AddNamedPort(std::string name, std::shared_ptr<ClientPort> port) {
impl->named_ports.emplace(std::move(name), std::move(port));
}
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
index 3bf0068ed..536068f74 100644
--- a/src/core/hle/kernel/kernel.h
+++ b/src/core/hle/kernel/kernel.h
@@ -11,6 +11,7 @@
#include "core/hle/kernel/object.h"
namespace Core {
+class ExclusiveMonitor;
class System;
}
@@ -25,6 +26,7 @@ class AddressArbiter;
class ClientPort;
class GlobalScheduler;
class HandleTable;
+class PhysicalCore;
class Process;
class ResourceLimit;
class Thread;
@@ -84,6 +86,21 @@ public:
/// Gets the sole instance of the global scheduler
const Kernel::GlobalScheduler& GlobalScheduler() const;
+ /// Gets the an instance of the respective physical CPU core.
+ Kernel::PhysicalCore& PhysicalCore(std::size_t id);
+
+ /// Gets the an instance of the respective physical CPU core.
+ const Kernel::PhysicalCore& PhysicalCore(std::size_t id) const;
+
+ /// Stops execution of 'id' core, in order to reschedule a new thread.
+ void PrepareReschedule(std::size_t id);
+
+ Core::ExclusiveMonitor& GetExclusiveMonitor();
+
+ const Core::ExclusiveMonitor& GetExclusiveMonitor() const;
+
+ void InvalidateAllInstructionCaches();
+
/// Adds a port to the named port table
void AddNamedPort(std::string name, std::shared_ptr<ClientPort> port);
diff --git a/src/core/hle/kernel/physical_core.cpp b/src/core/hle/kernel/physical_core.cpp
index 17faef348..7d84e3d28 100644
--- a/src/core/hle/kernel/physical_core.cpp
+++ b/src/core/hle/kernel/physical_core.cpp
@@ -2,18 +2,48 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
+#include "common/logging/log.h"
+#include "core/arm/arm_interface.h"
+#ifdef ARCHITECTURE_x86_64
+#include "core/arm/dynarmic/arm_dynarmic.h"
+#endif
+#include "core/arm/exclusive_monitor.h"
+#include "core/arm/unicorn/arm_unicorn.h"
+#include "core/core.h"
+#include "core/hle/kernel/kernel.h"
+#include "core/hle/kernel/physical_core.h"
+#include "core/hle/kernel/scheduler.h"
+#include "core/hle/kernel/thread.h"
+
namespace Kernel {
-PhysicalCore::PhysicalCore(KernelCore& kernel, std::size_t id, ExclusiveMonitor& exclusive_monitor)
+PhysicalCore::PhysicalCore(Core::System& system, KernelCore& kernel, std::size_t id, Core::ExclusiveMonitor& exclusive_monitor)
: core_index{id}, kernel{kernel} {
#ifdef ARCHITECTURE_x86_64
- arm_interface = std::make_unique<ARM_Dynarmic>(system, exclusive_monitor, core_index);
+ arm_interface = std::make_unique<Core::ARM_Dynarmic>(system, exclusive_monitor, core_index);
#else
- arm_interface = std::make_unique<ARM_Unicorn>(system);
+ arm_interface = std::make_unique<Core::ARM_Unicorn>(system);
LOG_WARNING(Core, "CPU JIT requested, but Dynarmic not available");
#endif
scheduler = std::make_unique<Kernel::Scheduler>(system, *arm_interface, core_index);
}
+void PhysicalCore::Run() {
+ arm_interface->Run();
+ arm_interface->ClearExclusiveState();
+}
+
+void PhysicalCore::Step() {
+ arm_interface->Step();
+}
+
+void PhysicalCore::Stop() {
+ arm_interface->PrepareReschedule();
+}
+
+void PhysicalCore::Shutdown() {
+ scheduler->Shutdown();
+}
+
} // namespace Kernel
diff --git a/src/core/hle/kernel/physical_core.h b/src/core/hle/kernel/physical_core.h
index 225b31d3e..a7848e030 100644
--- a/src/core/hle/kernel/physical_core.h
+++ b/src/core/hle/kernel/physical_core.h
@@ -8,14 +8,17 @@ namespace Kernel {
class Scheduler;
} // namespace Kernel
+namespace Core {
class ARM_Interface;
class ExclusiveMonitor;
+class System;
+} // namespace Core
namespace Kernel {
class PhysicalCore {
public:
- PhysicalCore(KernelCore& kernel, std::size_t id, ExclusiveMonitor& exclusive_monitor);
+ PhysicalCore(Core::System& system, KernelCore& kernel, std::size_t id, Core::ExclusiveMonitor& exclusive_monitor);
/// Execute current jit state
void Run();
@@ -24,11 +27,14 @@ public:
/// Stop JIT execution/exit
void Stop();
- ARM_Interface& ArmInterface() {
+ // Shutdown this physical core.
+ void Shutdown();
+
+ Core::ARM_Interface& ArmInterface() {
return *arm_interface;
}
- const ARM_Interface& ArmInterface() const {
+ const Core::ARM_Interface& ArmInterface() const {
return *arm_interface;
}
@@ -44,19 +50,19 @@ public:
return core_index;
}
- Scheduler& Scheduler() {
+ Kernel::Scheduler& Scheduler() {
return *scheduler;
}
- const Scheduler& Scheduler() const {
+ const Kernel::Scheduler& Scheduler() const {
return *scheduler;
}
private:
std::size_t core_index;
- std::unique_ptr<ARM_Interface> arm_interface;
- std::unique_ptr<Kernel::Scheduler> scheduler;
KernelCore& kernel;
-}
+ std::unique_ptr<Core::ARM_Interface> arm_interface;
+ std::unique_ptr<Kernel::Scheduler> scheduler;
+};
} // namespace Kernel