summaryrefslogtreecommitdiffstats
path: root/src/core/hle/kernel
diff options
context:
space:
mode:
authorbunnei <bunneidev@gmail.com>2020-03-02 05:46:10 +0100
committerbunnei <bunneidev@gmail.com>2020-03-03 03:51:57 +0100
commitc083ea7d7846ee40cfc889ed1d415f73ec78364c (patch)
treec58a597921953ad17f5b233c7e23996f78c2521b /src/core/hle/kernel
parentcore: loader: Remove check for 32-bit. (diff)
downloadyuzu-c083ea7d7846ee40cfc889ed1d415f73ec78364c.tar
yuzu-c083ea7d7846ee40cfc889ed1d415f73ec78364c.tar.gz
yuzu-c083ea7d7846ee40cfc889ed1d415f73ec78364c.tar.bz2
yuzu-c083ea7d7846ee40cfc889ed1d415f73ec78364c.tar.lz
yuzu-c083ea7d7846ee40cfc889ed1d415f73ec78364c.tar.xz
yuzu-c083ea7d7846ee40cfc889ed1d415f73ec78364c.tar.zst
yuzu-c083ea7d7846ee40cfc889ed1d415f73ec78364c.zip
Diffstat (limited to '')
-rw-r--r--src/core/hle/kernel/kernel.cpp4
-rw-r--r--src/core/hle/kernel/physical_core.cpp19
-rw-r--r--src/core/hle/kernel/physical_core.h6
-rw-r--r--src/core/hle/kernel/process.cpp3
-rw-r--r--src/core/hle/kernel/scheduler.cpp21
-rw-r--r--src/core/hle/kernel/scheduler.h3
-rw-r--r--src/core/hle/kernel/thread.cpp31
-rw-r--r--src/core/hle/kernel/thread.h22
8 files changed, 73 insertions, 36 deletions
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index 9232f4d7e..e47f1deed 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -186,6 +186,10 @@ struct KernelCore::Impl {
return;
}
+ for (auto& core : cores) {
+ core.SetIs64Bit(process->Is64BitProcess());
+ }
+
system.Memory().SetCurrentPageTable(*process);
}
diff --git a/src/core/hle/kernel/physical_core.cpp b/src/core/hle/kernel/physical_core.cpp
index 9303dd273..aa2787467 100644
--- a/src/core/hle/kernel/physical_core.cpp
+++ b/src/core/hle/kernel/physical_core.cpp
@@ -5,7 +5,8 @@
#include "common/logging/log.h"
#include "core/arm/arm_interface.h"
#ifdef ARCHITECTURE_x86_64
-#include "core/arm/dynarmic/arm_dynarmic.h"
+#include "core/arm/dynarmic/arm_dynarmic_32.h"
+#include "core/arm/dynarmic/arm_dynarmic_64.h"
#endif
#include "core/arm/exclusive_monitor.h"
#include "core/arm/unicorn/arm_unicorn.h"
@@ -20,13 +21,17 @@ PhysicalCore::PhysicalCore(Core::System& system, std::size_t id,
Core::ExclusiveMonitor& exclusive_monitor)
: core_index{id} {
#ifdef ARCHITECTURE_x86_64
- arm_interface = std::make_unique<Core::ARM_Dynarmic>(system, exclusive_monitor, core_index);
+ arm_interface_32 =
+ std::make_unique<Core::ARM_Dynarmic_32>(system, exclusive_monitor, core_index);
+ arm_interface_64 =
+ std::make_unique<Core::ARM_Dynarmic_64>(system, exclusive_monitor, core_index);
+
#else
arm_interface = std::make_shared<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);
+ scheduler = std::make_unique<Kernel::Scheduler>(system, core_index);
}
PhysicalCore::~PhysicalCore() = default;
@@ -48,4 +53,12 @@ void PhysicalCore::Shutdown() {
scheduler->Shutdown();
}
+void PhysicalCore::SetIs64Bit(bool is_64_bit) {
+ if (is_64_bit) {
+ arm_interface = arm_interface_64.get();
+ } else {
+ arm_interface = arm_interface_32.get();
+ }
+}
+
} // namespace Kernel
diff --git a/src/core/hle/kernel/physical_core.h b/src/core/hle/kernel/physical_core.h
index 4c32c0f1b..3269166be 100644
--- a/src/core/hle/kernel/physical_core.h
+++ b/src/core/hle/kernel/physical_core.h
@@ -68,10 +68,14 @@ public:
return *scheduler;
}
+ void SetIs64Bit(bool is_64_bit);
+
private:
std::size_t core_index;
- std::unique_ptr<Core::ARM_Interface> arm_interface;
+ std::unique_ptr<Core::ARM_Interface> arm_interface_32;
+ std::unique_ptr<Core::ARM_Interface> arm_interface_64;
std::unique_ptr<Kernel::Scheduler> scheduler;
+ Core::ARM_Interface* arm_interface{};
};
} // namespace Kernel
diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp
index 2fcb7326c..edc414d69 100644
--- a/src/core/hle/kernel/process.cpp
+++ b/src/core/hle/kernel/process.cpp
@@ -42,7 +42,8 @@ void SetupMainThread(Process& owner_process, KernelCore& kernel, u32 priority) {
// Register 1 must be a handle to the main thread
const Handle thread_handle = owner_process.GetHandleTable().Create(thread).Unwrap();
- thread->GetContext().cpu_registers[1] = thread_handle;
+ thread->GetContext32().cpu_registers[1] = thread_handle;
+ thread->GetContext64().cpu_registers[1] = thread_handle;
// Threads by default are dormant, wake up the main thread so it runs when the scheduler fires
thread->ResumeFromWait();
diff --git a/src/core/hle/kernel/scheduler.cpp b/src/core/hle/kernel/scheduler.cpp
index c65f82fb7..1140c72a3 100644
--- a/src/core/hle/kernel/scheduler.cpp
+++ b/src/core/hle/kernel/scheduler.cpp
@@ -383,8 +383,8 @@ void GlobalScheduler::Unlock() {
// TODO(Blinkhawk): Setup the interrupts and change context on current core.
}
-Scheduler::Scheduler(Core::System& system, Core::ARM_Interface& cpu_core, std::size_t core_id)
- : system(system), cpu_core(cpu_core), core_id(core_id) {}
+Scheduler::Scheduler(Core::System& system, std::size_t core_id)
+ : system{system}, core_id{core_id} {}
Scheduler::~Scheduler() = default;
@@ -422,9 +422,10 @@ void Scheduler::UnloadThread() {
// Save context for previous thread
if (previous_thread) {
- cpu_core.SaveContext(previous_thread->GetContext());
+ system.ArmInterface(core_id).SaveContext(previous_thread->GetContext32());
+ system.ArmInterface(core_id).SaveContext(previous_thread->GetContext64());
// Save the TPIDR_EL0 system register in case it was modified.
- previous_thread->SetTPIDR_EL0(cpu_core.GetTPIDR_EL0());
+ previous_thread->SetTPIDR_EL0(system.ArmInterface(core_id).GetTPIDR_EL0());
if (previous_thread->GetStatus() == ThreadStatus::Running) {
// This is only the case when a reschedule is triggered without the current thread
@@ -451,9 +452,10 @@ void Scheduler::SwitchContext() {
// Save context for previous thread
if (previous_thread) {
- cpu_core.SaveContext(previous_thread->GetContext());
+ system.ArmInterface(core_id).SaveContext(previous_thread->GetContext32());
+ system.ArmInterface(core_id).SaveContext(previous_thread->GetContext64());
// Save the TPIDR_EL0 system register in case it was modified.
- previous_thread->SetTPIDR_EL0(cpu_core.GetTPIDR_EL0());
+ previous_thread->SetTPIDR_EL0(system.ArmInterface(core_id).GetTPIDR_EL0());
if (previous_thread->GetStatus() == ThreadStatus::Running) {
// This is only the case when a reschedule is triggered without the current thread
@@ -481,9 +483,10 @@ void Scheduler::SwitchContext() {
system.Kernel().MakeCurrentProcess(thread_owner_process);
}
- cpu_core.LoadContext(new_thread->GetContext());
- cpu_core.SetTlsAddress(new_thread->GetTLSAddress());
- cpu_core.SetTPIDR_EL0(new_thread->GetTPIDR_EL0());
+ system.ArmInterface(core_id).LoadContext(new_thread->GetContext32());
+ system.ArmInterface(core_id).LoadContext(new_thread->GetContext64());
+ system.ArmInterface(core_id).SetTlsAddress(new_thread->GetTLSAddress());
+ system.ArmInterface(core_id).SetTPIDR_EL0(new_thread->GetTPIDR_EL0());
} else {
current_thread = nullptr;
// Note: We do not reset the current process and current page table when idling because
diff --git a/src/core/hle/kernel/scheduler.h b/src/core/hle/kernel/scheduler.h
index 1c93a838c..07df33f9c 100644
--- a/src/core/hle/kernel/scheduler.h
+++ b/src/core/hle/kernel/scheduler.h
@@ -181,7 +181,7 @@ private:
class Scheduler final {
public:
- explicit Scheduler(Core::System& system, Core::ARM_Interface& cpu_core, std::size_t core_id);
+ explicit Scheduler(Core::System& system, std::size_t core_id);
~Scheduler();
/// Returns whether there are any threads that are ready to run.
@@ -235,7 +235,6 @@ private:
std::shared_ptr<Thread> selected_thread = nullptr;
Core::System& system;
- Core::ARM_Interface& cpu_core;
u64 last_context_switch_time = 0;
u64 idle_selection_count = 0;
const std::size_t core_id;
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index bf850e0b2..83e956036 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -133,15 +133,16 @@ void Thread::CancelWait() {
ResumeFromWait();
}
-/**
- * Resets a thread context, making it ready to be scheduled and run by the CPU
- * @param context Thread context to reset
- * @param stack_top Address of the top of the stack
- * @param entry_point Address of entry point for execution
- * @param arg User argument for thread
- */
-static void ResetThreadContext(Core::ARM_Interface::ThreadContext& context, VAddr stack_top,
- VAddr entry_point, u64 arg) {
+static void ResetThreadContext32(Core::ARM_Interface::ThreadContext32& context, u32 stack_top,
+ u32 entry_point, u32 arg) {
+ context = {};
+ context.cpu_registers[0] = arg;
+ context.cpu_registers[15] = entry_point;
+ context.cpu_registers[13] = stack_top;
+}
+
+static void ResetThreadContext64(Core::ARM_Interface::ThreadContext64& context, VAddr stack_top,
+ VAddr entry_point, u64 arg) {
context = {};
context.cpu_registers[0] = arg;
context.pc = entry_point;
@@ -198,9 +199,9 @@ ResultVal<std::shared_ptr<Thread>> Thread::Create(KernelCore& kernel, std::strin
thread->owner_process->RegisterThread(thread.get());
- // TODO(peachum): move to ScheduleThread() when scheduler is added so selected core is used
- // to initialize the context
- ResetThreadContext(thread->context, stack_top, entry_point, arg);
+ ResetThreadContext32(thread->context_32, static_cast<u32>(stack_top),
+ static_cast<u32>(entry_point), static_cast<u32>(arg));
+ ResetThreadContext64(thread->context_64, stack_top, entry_point, arg);
return MakeResult<std::shared_ptr<Thread>>(std::move(thread));
}
@@ -213,11 +214,13 @@ void Thread::SetPriority(u32 priority) {
}
void Thread::SetWaitSynchronizationResult(ResultCode result) {
- context.cpu_registers[0] = result.raw;
+ context_32.cpu_registers[0] = result.raw;
+ context_64.cpu_registers[0] = result.raw;
}
void Thread::SetWaitSynchronizationOutput(s32 output) {
- context.cpu_registers[1] = output;
+ context_32.cpu_registers[1] = output;
+ context_64.cpu_registers[1] = output;
}
s32 Thread::GetSynchronizationObjectIndex(std::shared_ptr<SynchronizationObject> object) const {
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h
index 129e7858a..23fdef8a4 100644
--- a/src/core/hle/kernel/thread.h
+++ b/src/core/hle/kernel/thread.h
@@ -102,7 +102,8 @@ public:
using MutexWaitingThreads = std::vector<std::shared_ptr<Thread>>;
- using ThreadContext = Core::ARM_Interface::ThreadContext;
+ using ThreadContext32 = Core::ARM_Interface::ThreadContext32;
+ using ThreadContext64 = Core::ARM_Interface::ThreadContext64;
using ThreadSynchronizationObjects = std::vector<std::shared_ptr<SynchronizationObject>>;
@@ -273,12 +274,20 @@ public:
return status == ThreadStatus::WaitSynch;
}
- ThreadContext& GetContext() {
- return context;
+ ThreadContext32& GetContext32() {
+ return context_32;
}
- const ThreadContext& GetContext() const {
- return context;
+ const ThreadContext32& GetContext32() const {
+ return context_32;
+ }
+
+ ThreadContext64& GetContext64() {
+ return context_64;
+ }
+
+ const ThreadContext64& GetContext64() const {
+ return context_64;
}
ThreadStatus GetStatus() const {
@@ -466,7 +475,8 @@ private:
void AdjustSchedulingOnPriority(u32 old_priority);
void AdjustSchedulingOnAffinity(u64 old_affinity_mask, s32 old_core);
- Core::ARM_Interface::ThreadContext context{};
+ ThreadContext32 context_32{};
+ ThreadContext64 context_64{};
u64 thread_id = 0;