summaryrefslogtreecommitdiffstats
path: root/src/core/hle
diff options
context:
space:
mode:
authorFernando Sahmkow <fsahmkow27@gmail.com>2020-01-25 23:55:32 +0100
committerFernando Sahmkow <fsahmkow27@gmail.com>2020-01-25 23:55:32 +0100
commit4d6a86b03fe6ae0d98838a21613b66d5196150af (patch)
tree21f4b8e63e6435b2d816936af8b494882a3cdfb2 /src/core/hle
parentKernel: Implement Physical Core. (diff)
downloadyuzu-4d6a86b03fe6ae0d98838a21613b66d5196150af.tar
yuzu-4d6a86b03fe6ae0d98838a21613b66d5196150af.tar.gz
yuzu-4d6a86b03fe6ae0d98838a21613b66d5196150af.tar.bz2
yuzu-4d6a86b03fe6ae0d98838a21613b66d5196150af.tar.lz
yuzu-4d6a86b03fe6ae0d98838a21613b66d5196150af.tar.xz
yuzu-4d6a86b03fe6ae0d98838a21613b66d5196150af.tar.zst
yuzu-4d6a86b03fe6ae0d98838a21613b66d5196150af.zip
Diffstat (limited to 'src/core/hle')
-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
4 files changed, 127 insertions, 12 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 @@
#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