summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/kernel')
-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 {
186 return; 186 return;
187 } 187 }
188 188
189 for (auto& core : cores) {
190 core.SetIs64Bit(process->Is64BitProcess());
191 }
192
189 system.Memory().SetCurrentPageTable(*process); 193 system.Memory().SetCurrentPageTable(*process);
190 } 194 }
191 195
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 @@
5#include "common/logging/log.h" 5#include "common/logging/log.h"
6#include "core/arm/arm_interface.h" 6#include "core/arm/arm_interface.h"
7#ifdef ARCHITECTURE_x86_64 7#ifdef ARCHITECTURE_x86_64
8#include "core/arm/dynarmic/arm_dynarmic.h" 8#include "core/arm/dynarmic/arm_dynarmic_32.h"
9#include "core/arm/dynarmic/arm_dynarmic_64.h"
9#endif 10#endif
10#include "core/arm/exclusive_monitor.h" 11#include "core/arm/exclusive_monitor.h"
11#include "core/arm/unicorn/arm_unicorn.h" 12#include "core/arm/unicorn/arm_unicorn.h"
@@ -20,13 +21,17 @@ PhysicalCore::PhysicalCore(Core::System& system, std::size_t id,
20 Core::ExclusiveMonitor& exclusive_monitor) 21 Core::ExclusiveMonitor& exclusive_monitor)
21 : core_index{id} { 22 : core_index{id} {
22#ifdef ARCHITECTURE_x86_64 23#ifdef ARCHITECTURE_x86_64
23 arm_interface = std::make_unique<Core::ARM_Dynarmic>(system, exclusive_monitor, core_index); 24 arm_interface_32 =
25 std::make_unique<Core::ARM_Dynarmic_32>(system, exclusive_monitor, core_index);
26 arm_interface_64 =
27 std::make_unique<Core::ARM_Dynarmic_64>(system, exclusive_monitor, core_index);
28
24#else 29#else
25 arm_interface = std::make_shared<Core::ARM_Unicorn>(system); 30 arm_interface = std::make_shared<Core::ARM_Unicorn>(system);
26 LOG_WARNING(Core, "CPU JIT requested, but Dynarmic not available"); 31 LOG_WARNING(Core, "CPU JIT requested, but Dynarmic not available");
27#endif 32#endif
28 33
29 scheduler = std::make_unique<Kernel::Scheduler>(system, *arm_interface, core_index); 34 scheduler = std::make_unique<Kernel::Scheduler>(system, core_index);
30} 35}
31 36
32PhysicalCore::~PhysicalCore() = default; 37PhysicalCore::~PhysicalCore() = default;
@@ -48,4 +53,12 @@ void PhysicalCore::Shutdown() {
48 scheduler->Shutdown(); 53 scheduler->Shutdown();
49} 54}
50 55
56void PhysicalCore::SetIs64Bit(bool is_64_bit) {
57 if (is_64_bit) {
58 arm_interface = arm_interface_64.get();
59 } else {
60 arm_interface = arm_interface_32.get();
61 }
62}
63
51} // namespace Kernel 64} // 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:
68 return *scheduler; 68 return *scheduler;
69 } 69 }
70 70
71 void SetIs64Bit(bool is_64_bit);
72
71private: 73private:
72 std::size_t core_index; 74 std::size_t core_index;
73 std::unique_ptr<Core::ARM_Interface> arm_interface; 75 std::unique_ptr<Core::ARM_Interface> arm_interface_32;
76 std::unique_ptr<Core::ARM_Interface> arm_interface_64;
74 std::unique_ptr<Kernel::Scheduler> scheduler; 77 std::unique_ptr<Kernel::Scheduler> scheduler;
78 Core::ARM_Interface* arm_interface{};
75}; 79};
76 80
77} // namespace Kernel 81} // 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) {
42 42
43 // Register 1 must be a handle to the main thread 43 // Register 1 must be a handle to the main thread
44 const Handle thread_handle = owner_process.GetHandleTable().Create(thread).Unwrap(); 44 const Handle thread_handle = owner_process.GetHandleTable().Create(thread).Unwrap();
45 thread->GetContext().cpu_registers[1] = thread_handle; 45 thread->GetContext32().cpu_registers[1] = thread_handle;
46 thread->GetContext64().cpu_registers[1] = thread_handle;
46 47
47 // Threads by default are dormant, wake up the main thread so it runs when the scheduler fires 48 // Threads by default are dormant, wake up the main thread so it runs when the scheduler fires
48 thread->ResumeFromWait(); 49 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() {
383 // TODO(Blinkhawk): Setup the interrupts and change context on current core. 383 // TODO(Blinkhawk): Setup the interrupts and change context on current core.
384} 384}
385 385
386Scheduler::Scheduler(Core::System& system, Core::ARM_Interface& cpu_core, std::size_t core_id) 386Scheduler::Scheduler(Core::System& system, std::size_t core_id)
387 : system(system), cpu_core(cpu_core), core_id(core_id) {} 387 : system{system}, core_id{core_id} {}
388 388
389Scheduler::~Scheduler() = default; 389Scheduler::~Scheduler() = default;
390 390
@@ -422,9 +422,10 @@ void Scheduler::UnloadThread() {
422 422
423 // Save context for previous thread 423 // Save context for previous thread
424 if (previous_thread) { 424 if (previous_thread) {
425 cpu_core.SaveContext(previous_thread->GetContext()); 425 system.ArmInterface(core_id).SaveContext(previous_thread->GetContext32());
426 system.ArmInterface(core_id).SaveContext(previous_thread->GetContext64());
426 // Save the TPIDR_EL0 system register in case it was modified. 427 // Save the TPIDR_EL0 system register in case it was modified.
427 previous_thread->SetTPIDR_EL0(cpu_core.GetTPIDR_EL0()); 428 previous_thread->SetTPIDR_EL0(system.ArmInterface(core_id).GetTPIDR_EL0());
428 429
429 if (previous_thread->GetStatus() == ThreadStatus::Running) { 430 if (previous_thread->GetStatus() == ThreadStatus::Running) {
430 // This is only the case when a reschedule is triggered without the current thread 431 // This is only the case when a reschedule is triggered without the current thread
@@ -451,9 +452,10 @@ void Scheduler::SwitchContext() {
451 452
452 // Save context for previous thread 453 // Save context for previous thread
453 if (previous_thread) { 454 if (previous_thread) {
454 cpu_core.SaveContext(previous_thread->GetContext()); 455 system.ArmInterface(core_id).SaveContext(previous_thread->GetContext32());
456 system.ArmInterface(core_id).SaveContext(previous_thread->GetContext64());
455 // Save the TPIDR_EL0 system register in case it was modified. 457 // Save the TPIDR_EL0 system register in case it was modified.
456 previous_thread->SetTPIDR_EL0(cpu_core.GetTPIDR_EL0()); 458 previous_thread->SetTPIDR_EL0(system.ArmInterface(core_id).GetTPIDR_EL0());
457 459
458 if (previous_thread->GetStatus() == ThreadStatus::Running) { 460 if (previous_thread->GetStatus() == ThreadStatus::Running) {
459 // This is only the case when a reschedule is triggered without the current thread 461 // This is only the case when a reschedule is triggered without the current thread
@@ -481,9 +483,10 @@ void Scheduler::SwitchContext() {
481 system.Kernel().MakeCurrentProcess(thread_owner_process); 483 system.Kernel().MakeCurrentProcess(thread_owner_process);
482 } 484 }
483 485
484 cpu_core.LoadContext(new_thread->GetContext()); 486 system.ArmInterface(core_id).LoadContext(new_thread->GetContext32());
485 cpu_core.SetTlsAddress(new_thread->GetTLSAddress()); 487 system.ArmInterface(core_id).LoadContext(new_thread->GetContext64());
486 cpu_core.SetTPIDR_EL0(new_thread->GetTPIDR_EL0()); 488 system.ArmInterface(core_id).SetTlsAddress(new_thread->GetTLSAddress());
489 system.ArmInterface(core_id).SetTPIDR_EL0(new_thread->GetTPIDR_EL0());
487 } else { 490 } else {
488 current_thread = nullptr; 491 current_thread = nullptr;
489 // Note: We do not reset the current process and current page table when idling because 492 // 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:
181 181
182class Scheduler final { 182class Scheduler final {
183public: 183public:
184 explicit Scheduler(Core::System& system, Core::ARM_Interface& cpu_core, std::size_t core_id); 184 explicit Scheduler(Core::System& system, std::size_t core_id);
185 ~Scheduler(); 185 ~Scheduler();
186 186
187 /// Returns whether there are any threads that are ready to run. 187 /// Returns whether there are any threads that are ready to run.
@@ -235,7 +235,6 @@ private:
235 std::shared_ptr<Thread> selected_thread = nullptr; 235 std::shared_ptr<Thread> selected_thread = nullptr;
236 236
237 Core::System& system; 237 Core::System& system;
238 Core::ARM_Interface& cpu_core;
239 u64 last_context_switch_time = 0; 238 u64 last_context_switch_time = 0;
240 u64 idle_selection_count = 0; 239 u64 idle_selection_count = 0;
241 const std::size_t core_id; 240 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() {
133 ResumeFromWait(); 133 ResumeFromWait();
134} 134}
135 135
136/** 136static void ResetThreadContext32(Core::ARM_Interface::ThreadContext32& context, u32 stack_top,
137 * Resets a thread context, making it ready to be scheduled and run by the CPU 137 u32 entry_point, u32 arg) {
138 * @param context Thread context to reset 138 context = {};
139 * @param stack_top Address of the top of the stack 139 context.cpu_registers[0] = arg;
140 * @param entry_point Address of entry point for execution 140 context.cpu_registers[15] = entry_point;
141 * @param arg User argument for thread 141 context.cpu_registers[13] = stack_top;
142 */ 142}
143static void ResetThreadContext(Core::ARM_Interface::ThreadContext& context, VAddr stack_top, 143
144 VAddr entry_point, u64 arg) { 144static void ResetThreadContext64(Core::ARM_Interface::ThreadContext64& context, VAddr stack_top,
145 VAddr entry_point, u64 arg) {
145 context = {}; 146 context = {};
146 context.cpu_registers[0] = arg; 147 context.cpu_registers[0] = arg;
147 context.pc = entry_point; 148 context.pc = entry_point;
@@ -198,9 +199,9 @@ ResultVal<std::shared_ptr<Thread>> Thread::Create(KernelCore& kernel, std::strin
198 199
199 thread->owner_process->RegisterThread(thread.get()); 200 thread->owner_process->RegisterThread(thread.get());
200 201
201 // TODO(peachum): move to ScheduleThread() when scheduler is added so selected core is used 202 ResetThreadContext32(thread->context_32, static_cast<u32>(stack_top),
202 // to initialize the context 203 static_cast<u32>(entry_point), static_cast<u32>(arg));
203 ResetThreadContext(thread->context, stack_top, entry_point, arg); 204 ResetThreadContext64(thread->context_64, stack_top, entry_point, arg);
204 205
205 return MakeResult<std::shared_ptr<Thread>>(std::move(thread)); 206 return MakeResult<std::shared_ptr<Thread>>(std::move(thread));
206} 207}
@@ -213,11 +214,13 @@ void Thread::SetPriority(u32 priority) {
213} 214}
214 215
215void Thread::SetWaitSynchronizationResult(ResultCode result) { 216void Thread::SetWaitSynchronizationResult(ResultCode result) {
216 context.cpu_registers[0] = result.raw; 217 context_32.cpu_registers[0] = result.raw;
218 context_64.cpu_registers[0] = result.raw;
217} 219}
218 220
219void Thread::SetWaitSynchronizationOutput(s32 output) { 221void Thread::SetWaitSynchronizationOutput(s32 output) {
220 context.cpu_registers[1] = output; 222 context_32.cpu_registers[1] = output;
223 context_64.cpu_registers[1] = output;
221} 224}
222 225
223s32 Thread::GetSynchronizationObjectIndex(std::shared_ptr<SynchronizationObject> object) const { 226s32 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:
102 102
103 using MutexWaitingThreads = std::vector<std::shared_ptr<Thread>>; 103 using MutexWaitingThreads = std::vector<std::shared_ptr<Thread>>;
104 104
105 using ThreadContext = Core::ARM_Interface::ThreadContext; 105 using ThreadContext32 = Core::ARM_Interface::ThreadContext32;
106 using ThreadContext64 = Core::ARM_Interface::ThreadContext64;
106 107
107 using ThreadSynchronizationObjects = std::vector<std::shared_ptr<SynchronizationObject>>; 108 using ThreadSynchronizationObjects = std::vector<std::shared_ptr<SynchronizationObject>>;
108 109
@@ -273,12 +274,20 @@ public:
273 return status == ThreadStatus::WaitSynch; 274 return status == ThreadStatus::WaitSynch;
274 } 275 }
275 276
276 ThreadContext& GetContext() { 277 ThreadContext32& GetContext32() {
277 return context; 278 return context_32;
278 } 279 }
279 280
280 const ThreadContext& GetContext() const { 281 const ThreadContext32& GetContext32() const {
281 return context; 282 return context_32;
283 }
284
285 ThreadContext64& GetContext64() {
286 return context_64;
287 }
288
289 const ThreadContext64& GetContext64() const {
290 return context_64;
282 } 291 }
283 292
284 ThreadStatus GetStatus() const { 293 ThreadStatus GetStatus() const {
@@ -466,7 +475,8 @@ private:
466 void AdjustSchedulingOnPriority(u32 old_priority); 475 void AdjustSchedulingOnPriority(u32 old_priority);
467 void AdjustSchedulingOnAffinity(u64 old_affinity_mask, s32 old_core); 476 void AdjustSchedulingOnAffinity(u64 old_affinity_mask, s32 old_core);
468 477
469 Core::ARM_Interface::ThreadContext context{}; 478 ThreadContext32 context_32{};
479 ThreadContext64 context_64{};
470 480
471 u64 thread_id = 0; 481 u64 thread_id = 0;
472 482