summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Fernando Sahmkow2020-03-01 12:14:17 -0400
committerGravatar Fernando Sahmkow2020-06-27 11:35:58 -0400
commit1567824d2da8e9b49b433f3d1d753d8ad84e65f9 (patch)
treec9553bb3f1693e430054695737d2f87ba4b58955 /src
parentCore: Refactor ARM Interface. (diff)
downloadyuzu-1567824d2da8e9b49b433f3d1d753d8ad84e65f9.tar.gz
yuzu-1567824d2da8e9b49b433f3d1d753d8ad84e65f9.tar.xz
yuzu-1567824d2da8e9b49b433f3d1d753d8ad84e65f9.zip
General: Move ARM_Interface into Threads.
Diffstat (limited to 'src')
-rw-r--r--src/core/arm/arm_interface.h2
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_32.cpp4
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_32.h1
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_64.cpp4
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_64.h1
-rw-r--r--src/core/arm/unicorn/arm_unicorn.cpp4
-rw-r--r--src/core/arm/unicorn/arm_unicorn.h1
-rw-r--r--src/core/core.cpp34
-rw-r--r--src/core/core_manager.cpp18
-rw-r--r--src/core/cpu_manager.cpp30
-rw-r--r--src/core/hle/kernel/kernel.cpp59
-rw-r--r--src/core/hle/kernel/kernel.h8
-rw-r--r--src/core/hle/kernel/physical_core.cpp37
-rw-r--r--src/core/hle/kernel/physical_core.h37
-rw-r--r--src/core/hle/kernel/scheduler.cpp12
-rw-r--r--src/core/hle/kernel/svc.cpp11
-rw-r--r--src/core/hle/kernel/thread.cpp35
-rw-r--r--src/core/hle/kernel/thread.h8
18 files changed, 136 insertions, 170 deletions
diff --git a/src/core/arm/arm_interface.h b/src/core/arm/arm_interface.h
index dc9b2ff7b..e5c484336 100644
--- a/src/core/arm/arm_interface.h
+++ b/src/core/arm/arm_interface.h
@@ -148,6 +148,8 @@ public:
148 */ 148 */
149 virtual void SetTPIDR_EL0(u64 value) = 0; 149 virtual void SetTPIDR_EL0(u64 value) = 0;
150 150
151 virtual void ChangeProcessorId(std::size_t new_core_id) = 0;
152
151 virtual void SaveContext(ThreadContext32& ctx) = 0; 153 virtual void SaveContext(ThreadContext32& ctx) = 0;
152 virtual void SaveContext(ThreadContext64& ctx) = 0; 154 virtual void SaveContext(ThreadContext64& ctx) = 0;
153 virtual void LoadContext(const ThreadContext32& ctx) = 0; 155 virtual void LoadContext(const ThreadContext32& ctx) = 0;
diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp
index f36c5f401..9c47c133c 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp
@@ -165,6 +165,10 @@ void ARM_Dynarmic_32::SetTPIDR_EL0(u64 value) {
165 cp15->uprw = static_cast<u32>(value); 165 cp15->uprw = static_cast<u32>(value);
166} 166}
167 167
168void ARM_Dynarmic_32::ChangeProcessorId(std::size_t new_core_id) {
169 // jit->ChangeProcessorId(new_core_id);
170}
171
168void ARM_Dynarmic_32::SaveContext(ThreadContext32& ctx) { 172void ARM_Dynarmic_32::SaveContext(ThreadContext32& ctx) {
169 Dynarmic::A32::Context context; 173 Dynarmic::A32::Context context;
170 jit->SaveContext(context); 174 jit->SaveContext(context);
diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.h b/src/core/arm/dynarmic/arm_dynarmic_32.h
index 2dd9a4df0..bea4933c8 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_32.h
+++ b/src/core/arm/dynarmic/arm_dynarmic_32.h
@@ -47,6 +47,7 @@ public:
47 void SetTlsAddress(VAddr address) override; 47 void SetTlsAddress(VAddr address) override;
48 void SetTPIDR_EL0(u64 value) override; 48 void SetTPIDR_EL0(u64 value) override;
49 u64 GetTPIDR_EL0() const override; 49 u64 GetTPIDR_EL0() const override;
50 void ChangeProcessorId(std::size_t new_core_id) override;
50 51
51 void SaveContext(ThreadContext32& ctx) override; 52 void SaveContext(ThreadContext32& ctx) override;
52 void SaveContext(ThreadContext64& ctx) override {} 53 void SaveContext(ThreadContext64& ctx) override {}
diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp
index 8401ba631..03b3313cf 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp
@@ -258,6 +258,10 @@ void ARM_Dynarmic_64::SetTPIDR_EL0(u64 value) {
258 cb->tpidr_el0 = value; 258 cb->tpidr_el0 = value;
259} 259}
260 260
261void ARM_Dynarmic_64::ChangeProcessorId(std::size_t new_core_id) {
262 jit->ChangeProcessorId(new_core_id);
263}
264
261void ARM_Dynarmic_64::SaveContext(ThreadContext64& ctx) { 265void ARM_Dynarmic_64::SaveContext(ThreadContext64& ctx) {
262 ctx.cpu_registers = jit->GetRegisters(); 266 ctx.cpu_registers = jit->GetRegisters();
263 ctx.sp = jit->GetSP(); 267 ctx.sp = jit->GetSP();
diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.h b/src/core/arm/dynarmic/arm_dynarmic_64.h
index 1c6791d4e..c26b47249 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_64.h
+++ b/src/core/arm/dynarmic/arm_dynarmic_64.h
@@ -46,6 +46,7 @@ public:
46 void SetTlsAddress(VAddr address) override; 46 void SetTlsAddress(VAddr address) override;
47 void SetTPIDR_EL0(u64 value) override; 47 void SetTPIDR_EL0(u64 value) override;
48 u64 GetTPIDR_EL0() const override; 48 u64 GetTPIDR_EL0() const override;
49 void ChangeProcessorId(std::size_t new_core_id) override;
49 50
50 void SaveContext(ThreadContext32& ctx) override {} 51 void SaveContext(ThreadContext32& ctx) override {}
51 void SaveContext(ThreadContext64& ctx) override; 52 void SaveContext(ThreadContext64& ctx) override;
diff --git a/src/core/arm/unicorn/arm_unicorn.cpp b/src/core/arm/unicorn/arm_unicorn.cpp
index d81d1b5b0..099229c8d 100644
--- a/src/core/arm/unicorn/arm_unicorn.cpp
+++ b/src/core/arm/unicorn/arm_unicorn.cpp
@@ -159,6 +159,10 @@ void ARM_Unicorn::SetTPIDR_EL0(u64 value) {
159 CHECKED(uc_reg_write(uc, UC_ARM64_REG_TPIDR_EL0, &value)); 159 CHECKED(uc_reg_write(uc, UC_ARM64_REG_TPIDR_EL0, &value));
160} 160}
161 161
162void ARM_Unicorn::ChangeProcessorId(std::size_t new_core_id) {
163 core_index = new_core_id;
164}
165
162void ARM_Unicorn::Run() { 166void ARM_Unicorn::Run() {
163 if (GDBStub::IsServerEnabled()) { 167 if (GDBStub::IsServerEnabled()) {
164 ExecuteInstructions(std::max(4000000U, 0U)); 168 ExecuteInstructions(std::max(4000000U, 0U));
diff --git a/src/core/arm/unicorn/arm_unicorn.h b/src/core/arm/unicorn/arm_unicorn.h
index e3da368de..f09b24a85 100644
--- a/src/core/arm/unicorn/arm_unicorn.h
+++ b/src/core/arm/unicorn/arm_unicorn.h
@@ -36,6 +36,7 @@ public:
36 void SetTlsAddress(VAddr address) override; 36 void SetTlsAddress(VAddr address) override;
37 void SetTPIDR_EL0(u64 value) override; 37 void SetTPIDR_EL0(u64 value) override;
38 u64 GetTPIDR_EL0() const override; 38 u64 GetTPIDR_EL0() const override;
39 void ChangeProcessorId(std::size_t new_core_id) override;
39 void PrepareReschedule() override; 40 void PrepareReschedule() override;
40 void ClearExclusiveState() override; 41 void ClearExclusiveState() override;
41 void ExecuteInstructions(std::size_t num_instructions); 42 void ExecuteInstructions(std::size_t num_instructions);
diff --git a/src/core/core.cpp b/src/core/core.cpp
index 2ca9c0be5..40eea297e 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -119,14 +119,6 @@ struct System::Impl {
119 : kernel{system}, fs_controller{system}, memory{system}, 119 : kernel{system}, fs_controller{system}, memory{system},
120 cpu_manager{system}, reporter{system}, applet_manager{system} {} 120 cpu_manager{system}, reporter{system}, applet_manager{system} {}
121 121
122 Kernel::PhysicalCore& CurrentPhysicalCore() {
123 return kernel.CurrentPhysicalCore();
124 }
125
126 Kernel::PhysicalCore& GetPhysicalCore(std::size_t index) {
127 return kernel.PhysicalCore(index);
128 }
129
130 ResultStatus Run() { 122 ResultStatus Run() {
131 status = ResultStatus::Success; 123 status = ResultStatus::Success;
132 124
@@ -443,7 +435,7 @@ bool System::IsPoweredOn() const {
443} 435}
444 436
445void System::PrepareReschedule() { 437void System::PrepareReschedule() {
446 impl->CurrentPhysicalCore().Stop(); 438 //impl->CurrentPhysicalCore().Stop();
447} 439}
448 440
449void System::PrepareReschedule(const u32 core_index) { 441void System::PrepareReschedule(const u32 core_index) {
@@ -463,11 +455,11 @@ const TelemetrySession& System::TelemetrySession() const {
463} 455}
464 456
465ARM_Interface& System::CurrentArmInterface() { 457ARM_Interface& System::CurrentArmInterface() {
466 return impl->CurrentPhysicalCore().ArmInterface(); 458 return impl->kernel.CurrentScheduler().GetCurrentThread()->ArmInterface();
467} 459}
468 460
469const ARM_Interface& System::CurrentArmInterface() const { 461const ARM_Interface& System::CurrentArmInterface() const {
470 return impl->CurrentPhysicalCore().ArmInterface(); 462 return impl->kernel.CurrentScheduler().GetCurrentThread()->ArmInterface();
471} 463}
472 464
473std::size_t System::CurrentCoreIndex() const { 465std::size_t System::CurrentCoreIndex() const {
@@ -477,27 +469,27 @@ std::size_t System::CurrentCoreIndex() const {
477} 469}
478 470
479Kernel::Scheduler& System::CurrentScheduler() { 471Kernel::Scheduler& System::CurrentScheduler() {
480 return impl->CurrentPhysicalCore().Scheduler(); 472 return impl->kernel.CurrentScheduler();
481} 473}
482 474
483const Kernel::Scheduler& System::CurrentScheduler() const { 475const Kernel::Scheduler& System::CurrentScheduler() const {
484 return impl->CurrentPhysicalCore().Scheduler(); 476 return impl->kernel.CurrentScheduler();
485} 477}
486 478
487Kernel::PhysicalCore& System::CurrentPhysicalCore() { 479Kernel::PhysicalCore& System::CurrentPhysicalCore() {
488 return impl->CurrentPhysicalCore(); 480 return impl->kernel.CurrentPhysicalCore();
489} 481}
490 482
491const Kernel::PhysicalCore& System::CurrentPhysicalCore() const { 483const Kernel::PhysicalCore& System::CurrentPhysicalCore() const {
492 return impl->CurrentPhysicalCore(); 484 return impl->kernel.CurrentPhysicalCore();
493} 485}
494 486
495Kernel::Scheduler& System::Scheduler(std::size_t core_index) { 487Kernel::Scheduler& System::Scheduler(std::size_t core_index) {
496 return impl->GetPhysicalCore(core_index).Scheduler(); 488 return impl->kernel.Scheduler(core_index);
497} 489}
498 490
499const Kernel::Scheduler& System::Scheduler(std::size_t core_index) const { 491const Kernel::Scheduler& System::Scheduler(std::size_t core_index) const {
500 return impl->GetPhysicalCore(core_index).Scheduler(); 492 return impl->kernel.Scheduler(core_index);
501} 493}
502 494
503/// Gets the global scheduler 495/// Gets the global scheduler
@@ -527,11 +519,15 @@ const Kernel::Process* System::CurrentProcess() const {
527} 519}
528 520
529ARM_Interface& System::ArmInterface(std::size_t core_index) { 521ARM_Interface& System::ArmInterface(std::size_t core_index) {
530 return impl->GetPhysicalCore(core_index).ArmInterface(); 522 auto* thread = impl->kernel.Scheduler(core_index).GetCurrentThread();
523 ASSERT(thread && !thread->IsHLEThread());
524 return thread->ArmInterface();
531} 525}
532 526
533const ARM_Interface& System::ArmInterface(std::size_t core_index) const { 527const ARM_Interface& System::ArmInterface(std::size_t core_index) const {
534 return impl->GetPhysicalCore(core_index).ArmInterface(); 528 auto* thread = impl->kernel.Scheduler(core_index).GetCurrentThread();
529 ASSERT(thread && !thread->IsHLEThread());
530 return thread->ArmInterface();
535} 531}
536 532
537ExclusiveMonitor& System::Monitor() { 533ExclusiveMonitor& System::Monitor() {
diff --git a/src/core/core_manager.cpp b/src/core/core_manager.cpp
index 45f0bb547..82d7acb40 100644
--- a/src/core/core_manager.cpp
+++ b/src/core/core_manager.cpp
@@ -28,21 +28,7 @@ CoreManager::CoreManager(System& system, std::size_t core_index)
28CoreManager::~CoreManager() = default; 28CoreManager::~CoreManager() = default;
29 29
30void CoreManager::RunLoop(bool tight_loop) { 30void CoreManager::RunLoop(bool tight_loop) {
31 Reschedule(); 31 /// Deprecated
32
33 // If we don't have a currently active thread then don't execute instructions,
34 // instead advance to the next event and try to yield to the next thread
35 if (Kernel::GetCurrentThread() == nullptr) {
36 LOG_TRACE(Core, "Core-{} idling", core_index);
37 } else {
38 if (tight_loop) {
39 physical_core.Run();
40 } else {
41 physical_core.Step();
42 }
43 }
44
45 Reschedule();
46} 32}
47 33
48void CoreManager::SingleStep() { 34void CoreManager::SingleStep() {
@@ -50,7 +36,7 @@ void CoreManager::SingleStep() {
50} 36}
51 37
52void CoreManager::PrepareReschedule() { 38void CoreManager::PrepareReschedule() {
53 physical_core.Stop(); 39 //physical_core.Stop();
54} 40}
55 41
56void CoreManager::Reschedule() { 42void CoreManager::Reschedule() {
diff --git a/src/core/cpu_manager.cpp b/src/core/cpu_manager.cpp
index 2aea95a25..2e9dc9dc3 100644
--- a/src/core/cpu_manager.cpp
+++ b/src/core/cpu_manager.cpp
@@ -129,18 +129,17 @@ void CpuManager::MultiCoreRunGuestThread() {
129void CpuManager::MultiCoreRunGuestLoop() { 129void CpuManager::MultiCoreRunGuestLoop() {
130 auto& kernel = system.Kernel(); 130 auto& kernel = system.Kernel();
131 auto* thread = kernel.CurrentScheduler().GetCurrentThread(); 131 auto* thread = kernel.CurrentScheduler().GetCurrentThread();
132 auto host_context = thread->GetHostContext();
133 host_context->SetRewindPoint(std::function<void(void*)>(GuestRewindFunction), this);
134 host_context.reset();
135 while (true) { 132 while (true) {
136 auto& physical_core = kernel.CurrentPhysicalCore(); 133 auto* physical_core = &kernel.CurrentPhysicalCore();
134 auto& arm_interface = thread->ArmInterface();
137 system.EnterDynarmicProfile(); 135 system.EnterDynarmicProfile();
138 while (!physical_core.IsInterrupted()) { 136 while (!physical_core->IsInterrupted()) {
139 physical_core.Run(); 137 arm_interface.Run();
138 physical_core = &kernel.CurrentPhysicalCore();
140 } 139 }
141 system.ExitDynarmicProfile(); 140 system.ExitDynarmicProfile();
142 physical_core.ClearExclusive(); 141 arm_interface.ClearExclusiveState();
143 auto& scheduler = physical_core.Scheduler(); 142 auto& scheduler = kernel.CurrentScheduler();
144 scheduler.TryDoContextSwitch(); 143 scheduler.TryDoContextSwitch();
145 } 144 }
146} 145}
@@ -150,7 +149,7 @@ void CpuManager::MultiCoreRunIdleThread() {
150 while (true) { 149 while (true) {
151 auto& physical_core = kernel.CurrentPhysicalCore(); 150 auto& physical_core = kernel.CurrentPhysicalCore();
152 physical_core.Idle(); 151 physical_core.Idle();
153 auto& scheduler = physical_core.Scheduler(); 152 auto& scheduler = kernel.CurrentScheduler();
154 scheduler.TryDoContextSwitch(); 153 scheduler.TryDoContextSwitch();
155 } 154 }
156} 155}
@@ -229,14 +228,13 @@ void CpuManager::SingleCoreRunGuestThread() {
229void CpuManager::SingleCoreRunGuestLoop() { 228void CpuManager::SingleCoreRunGuestLoop() {
230 auto& kernel = system.Kernel(); 229 auto& kernel = system.Kernel();
231 auto* thread = kernel.CurrentScheduler().GetCurrentThread(); 230 auto* thread = kernel.CurrentScheduler().GetCurrentThread();
232 auto host_context = thread->GetHostContext();
233 host_context->SetRewindPoint(std::function<void(void*)>(GuestRewindFunction), this);
234 host_context.reset();
235 while (true) { 231 while (true) {
236 auto& physical_core = kernel.CurrentPhysicalCore(); 232 auto* physical_core = &kernel.CurrentPhysicalCore();
233 auto& arm_interface = thread->ArmInterface();
237 system.EnterDynarmicProfile(); 234 system.EnterDynarmicProfile();
238 while (!physical_core.IsInterrupted()) { 235 while (!physical_core->IsInterrupted()) {
239 physical_core.Run(); 236 arm_interface.Run();
237 physical_core = &kernel.CurrentPhysicalCore();
240 preemption_count++; 238 preemption_count++;
241 if (preemption_count % max_cycle_runs == 0) { 239 if (preemption_count % max_cycle_runs == 0) {
242 break; 240 break;
@@ -246,7 +244,7 @@ void CpuManager::SingleCoreRunGuestLoop() {
246 thread->SetPhantomMode(true); 244 thread->SetPhantomMode(true);
247 system.CoreTiming().Advance(); 245 system.CoreTiming().Advance();
248 thread->SetPhantomMode(false); 246 thread->SetPhantomMode(false);
249 physical_core.ClearExclusive(); 247 arm_interface.ClearExclusiveState();
250 PreemptSingleCore(); 248 PreemptSingleCore();
251 auto& scheduler = kernel.Scheduler(current_core); 249 auto& scheduler = kernel.Scheduler(current_core);
252 scheduler.TryDoContextSwitch(); 250 scheduler.TryDoContextSwitch();
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index e33ef5323..3feddd9ad 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -19,7 +19,6 @@
19#include "core/arm/arm_interface.h" 19#include "core/arm/arm_interface.h"
20#include "core/arm/cpu_interrupt_handler.h" 20#include "core/arm/cpu_interrupt_handler.h"
21#include "core/arm/exclusive_monitor.h" 21#include "core/arm/exclusive_monitor.h"
22#include "core/arm/unicorn/arm_unicorn.h"
23#include "core/core.h" 22#include "core/core.h"
24#include "core/core_timing.h" 23#include "core/core_timing.h"
25#include "core/core_timing_util.h" 24#include "core/core_timing_util.h"
@@ -45,11 +44,6 @@
45#include "core/hle/result.h" 44#include "core/hle/result.h"
46#include "core/memory.h" 45#include "core/memory.h"
47 46
48#ifdef ARCHITECTURE_x86_64
49#include "core/arm/dynarmic/arm_dynarmic_32.h"
50#include "core/arm/dynarmic/arm_dynarmic_64.h"
51#endif
52
53MICROPROFILE_DEFINE(Kernel_SVC, "Kernel", "SVC", MP_RGB(70, 200, 70)); 47MICROPROFILE_DEFINE(Kernel_SVC, "Kernel", "SVC", MP_RGB(70, 200, 70));
54 48
55namespace Kernel { 49namespace Kernel {
@@ -186,20 +180,8 @@ struct KernelCore::Impl {
186 exclusive_monitor = 180 exclusive_monitor =
187 Core::MakeExclusiveMonitor(system.Memory(), Core::Hardware::NUM_CPU_CORES); 181 Core::MakeExclusiveMonitor(system.Memory(), Core::Hardware::NUM_CPU_CORES);
188 for (std::size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) { 182 for (std::size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) {
189#ifdef ARCHITECTURE_x86_64 183 schedulers[i] = std::make_unique<Kernel::Scheduler>(system, i);
190 arm_interfaces_32[i] = 184 cores.emplace_back(system, i, *schedulers[i], interrupts[i]);
191 std::make_unique<Core::ARM_Dynarmic_32>(system, interrupts, *exclusive_monitor, i);
192 arm_interfaces_64[i] =
193 std::make_unique<Core::ARM_Dynarmic_64>(system, interrupts, *exclusive_monitor, i);
194#else
195 arm_interfaces_32[i] = std::make_shared<Core::ARM_Unicorn>(
196 system, interrupts, ARM_Unicorn::Arch::AArch32, i);
197 arm_interfaces_64[i] = std::make_shared<Core::ARM_Unicorn>(
198 system, interrupts, ARM_Unicorn::Arch::AArch64, i);
199 LOG_WARNING(Core, "CPU JIT requested, but Dynarmic not available");
200#endif
201 cores.emplace_back(system, i, *exclusive_monitor, interrupts[i], *arm_interfaces_32[i],
202 *arm_interfaces_64[i]);
203 } 185 }
204 } 186 }
205 187
@@ -268,10 +250,6 @@ struct KernelCore::Impl {
268 return; 250 return;
269 } 251 }
270 252
271 for (auto& core : cores) {
272 core.SetIs64Bit(process->Is64BitProcess());
273 }
274
275 u32 core_id = GetCurrentHostThreadID(); 253 u32 core_id = GetCurrentHostThreadID();
276 if (core_id < Core::Hardware::NUM_CPU_CORES) { 254 if (core_id < Core::Hardware::NUM_CPU_CORES) {
277 system.Memory().SetCurrentPageTable(*process, core_id); 255 system.Memory().SetCurrentPageTable(*process, core_id);
@@ -429,10 +407,7 @@ struct KernelCore::Impl {
429 407
430 std::array<std::shared_ptr<Thread>, Core::Hardware::NUM_CPU_CORES> suspend_threads{}; 408 std::array<std::shared_ptr<Thread>, Core::Hardware::NUM_CPU_CORES> suspend_threads{};
431 std::array<Core::CPUInterruptHandler, Core::Hardware::NUM_CPU_CORES> interrupts{}; 409 std::array<Core::CPUInterruptHandler, Core::Hardware::NUM_CPU_CORES> interrupts{};
432 std::array<std::unique_ptr<Core::ARM_Interface>, Core::Hardware::NUM_CPU_CORES> 410 std::array<std::unique_ptr<Kernel::Scheduler>, Core::Hardware::NUM_CPU_CORES> schedulers{};
433 arm_interfaces_32{};
434 std::array<std::unique_ptr<Core::ARM_Interface>, Core::Hardware::NUM_CPU_CORES>
435 arm_interfaces_64{};
436 411
437 bool is_multicore{}; 412 bool is_multicore{};
438 std::thread::id single_core_thread_id{}; 413 std::thread::id single_core_thread_id{};
@@ -497,11 +472,11 @@ const Kernel::GlobalScheduler& KernelCore::GlobalScheduler() const {
497} 472}
498 473
499Kernel::Scheduler& KernelCore::Scheduler(std::size_t id) { 474Kernel::Scheduler& KernelCore::Scheduler(std::size_t id) {
500 return impl->cores[id].Scheduler(); 475 return *impl->schedulers[id];
501} 476}
502 477
503const Kernel::Scheduler& KernelCore::Scheduler(std::size_t id) const { 478const Kernel::Scheduler& KernelCore::Scheduler(std::size_t id) const {
504 return impl->cores[id].Scheduler(); 479 return *impl->schedulers[id];
505} 480}
506 481
507Kernel::PhysicalCore& KernelCore::PhysicalCore(std::size_t id) { 482Kernel::PhysicalCore& KernelCore::PhysicalCore(std::size_t id) {
@@ -525,11 +500,23 @@ const Kernel::PhysicalCore& KernelCore::CurrentPhysicalCore() const {
525} 500}
526 501
527Kernel::Scheduler& KernelCore::CurrentScheduler() { 502Kernel::Scheduler& KernelCore::CurrentScheduler() {
528 return CurrentPhysicalCore().Scheduler(); 503 u32 core_id = impl->GetCurrentHostThreadID();
504 ASSERT(core_id < Core::Hardware::NUM_CPU_CORES);
505 return *impl->schedulers[core_id];
529} 506}
530 507
531const Kernel::Scheduler& KernelCore::CurrentScheduler() const { 508const Kernel::Scheduler& KernelCore::CurrentScheduler() const {
532 return CurrentPhysicalCore().Scheduler(); 509 u32 core_id = impl->GetCurrentHostThreadID();
510 ASSERT(core_id < Core::Hardware::NUM_CPU_CORES);
511 return *impl->schedulers[core_id];
512}
513
514std::array<Core::CPUInterruptHandler, Core::Hardware::NUM_CPU_CORES>& KernelCore::Interrupts() {
515 return impl->interrupts;
516}
517
518const std::array<Core::CPUInterruptHandler, Core::Hardware::NUM_CPU_CORES>& KernelCore::Interrupts() const {
519 return impl->interrupts;
533} 520}
534 521
535Kernel::Synchronization& KernelCore::Synchronization() { 522Kernel::Synchronization& KernelCore::Synchronization() {
@@ -557,15 +544,11 @@ const Core::ExclusiveMonitor& KernelCore::GetExclusiveMonitor() const {
557} 544}
558 545
559void KernelCore::InvalidateAllInstructionCaches() { 546void KernelCore::InvalidateAllInstructionCaches() {
560 for (std::size_t i = 0; i < impl->global_scheduler.CpuCoresCount(); i++) { 547 //TODO: Reimplement, this
561 PhysicalCore(i).ArmInterface().ClearInstructionCache();
562 }
563} 548}
564 549
565void KernelCore::PrepareReschedule(std::size_t id) { 550void KernelCore::PrepareReschedule(std::size_t id) {
566 if (id < impl->global_scheduler.CpuCoresCount()) { 551 // TODO: Reimplement, this
567 impl->cores[id].Stop();
568 }
569} 552}
570 553
571void KernelCore::AddNamedPort(std::string name, std::shared_ptr<ClientPort> port) { 554void KernelCore::AddNamedPort(std::string name, std::shared_ptr<ClientPort> port) {
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
index 1eb6ede73..846056b85 100644
--- a/src/core/hle/kernel/kernel.h
+++ b/src/core/hle/kernel/kernel.h
@@ -4,15 +4,17 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <array>
7#include <memory> 8#include <memory>
8#include <string> 9#include <string>
9#include <unordered_map> 10#include <unordered_map>
10#include <vector> 11#include <vector>
12#include "core/hardware_properties.h"
11#include "core/hle/kernel/memory/memory_types.h" 13#include "core/hle/kernel/memory/memory_types.h"
12#include "core/hle/kernel/object.h" 14#include "core/hle/kernel/object.h"
13 15
14namespace Core { 16namespace Core {
15struct EmuThreadHandle; 17class CPUInterruptHandler;
16class ExclusiveMonitor; 18class ExclusiveMonitor;
17class System; 19class System;
18} // namespace Core 20} // namespace Core
@@ -144,6 +146,10 @@ public:
144 146
145 const Core::ExclusiveMonitor& GetExclusiveMonitor() const; 147 const Core::ExclusiveMonitor& GetExclusiveMonitor() const;
146 148
149 std::array<Core::CPUInterruptHandler, Core::Hardware::NUM_CPU_CORES>& Interrupts();
150
151 const std::array<Core::CPUInterruptHandler, Core::Hardware::NUM_CPU_CORES>& Interrupts() const;
152
147 void InvalidateAllInstructionCaches(); 153 void InvalidateAllInstructionCaches();
148 154
149 /// Adds a port to the named port table 155 /// Adds a port to the named port table
diff --git a/src/core/hle/kernel/physical_core.cpp b/src/core/hle/kernel/physical_core.cpp
index 9146b331d..c82c60a16 100644
--- a/src/core/hle/kernel/physical_core.cpp
+++ b/src/core/hle/kernel/physical_core.cpp
@@ -20,50 +20,21 @@
20 20
21namespace Kernel { 21namespace Kernel {
22 22
23PhysicalCore::PhysicalCore(Core::System& system, std::size_t id, 23PhysicalCore::PhysicalCore(Core::System& system, std::size_t id, Kernel::Scheduler& scheduler,
24 Core::ExclusiveMonitor& exclusive_monitor, 24 Core::CPUInterruptHandler& interrupt_handler)
25 Core::CPUInterruptHandler& interrupt_handler, 25 : interrupt_handler{interrupt_handler}, core_index{id}, scheduler{scheduler} {
26 Core::ARM_Interface& arm_interface32,
27 Core::ARM_Interface& arm_interface64)
28 : interrupt_handler{interrupt_handler}, core_index{id}, arm_interface_32{arm_interface32},
29 arm_interface_64{arm_interface64} {
30 26
31 scheduler = std::make_unique<Kernel::Scheduler>(system, core_index);
32 guard = std::make_unique<Common::SpinLock>(); 27 guard = std::make_unique<Common::SpinLock>();
33} 28}
34 29
35PhysicalCore::~PhysicalCore() = default; 30PhysicalCore::~PhysicalCore() = default;
36 31
37void PhysicalCore::Run() {
38 arm_interface->Run();
39}
40
41void PhysicalCore::ClearExclusive() {
42 arm_interface->ClearExclusiveState();
43}
44
45void PhysicalCore::Step() {
46 arm_interface->Step();
47}
48
49void PhysicalCore::Idle() { 32void PhysicalCore::Idle() {
50 interrupt_handler.AwaitInterrupt(); 33 interrupt_handler.AwaitInterrupt();
51} 34}
52 35
53void PhysicalCore::Stop() {
54 arm_interface->PrepareReschedule();
55}
56
57void PhysicalCore::Shutdown() { 36void PhysicalCore::Shutdown() {
58 scheduler->Shutdown(); 37 scheduler.Shutdown();
59}
60
61void PhysicalCore::SetIs64Bit(bool is_64_bit) {
62 if (is_64_bit) {
63 arm_interface = &arm_interface_64;
64 } else {
65 arm_interface = &arm_interface_32;
66 }
67} 38}
68 39
69void PhysicalCore::Interrupt() { 40void PhysicalCore::Interrupt() {
diff --git a/src/core/hle/kernel/physical_core.h b/src/core/hle/kernel/physical_core.h
index 2673d90f2..751b994a7 100644
--- a/src/core/hle/kernel/physical_core.h
+++ b/src/core/hle/kernel/physical_core.h
@@ -10,7 +10,7 @@
10#include "core/arm/cpu_interrupt_handler.h" 10#include "core/arm/cpu_interrupt_handler.h"
11 11
12namespace Common { 12namespace Common {
13class SpinLock; 13 class SpinLock;
14} 14}
15 15
16namespace Kernel { 16namespace Kernel {
@@ -27,9 +27,9 @@ namespace Kernel {
27 27
28class PhysicalCore { 28class PhysicalCore {
29public: 29public:
30 PhysicalCore(Core::System& system, std::size_t id, Core::ExclusiveMonitor& exclusive_monitor, 30 PhysicalCore(Core::System& system, std::size_t id,
31 Core::CPUInterruptHandler& interrupt_handler, Core::ARM_Interface& arm_interface32, 31 Kernel::Scheduler& scheduler,
32 Core::ARM_Interface& arm_interface64); 32 Core::CPUInterruptHandler& interrupt_handler);
33 ~PhysicalCore(); 33 ~PhysicalCore();
34 34
35 PhysicalCore(const PhysicalCore&) = delete; 35 PhysicalCore(const PhysicalCore&) = delete;
@@ -38,17 +38,7 @@ public:
38 PhysicalCore(PhysicalCore&&) = default; 38 PhysicalCore(PhysicalCore&&) = default;
39 PhysicalCore& operator=(PhysicalCore&&) = default; 39 PhysicalCore& operator=(PhysicalCore&&) = default;
40 40
41 /// Execute current jit state
42 void Run();
43 /// Clear Exclusive state.
44 void ClearExclusive();
45 /// Set this core in IdleState.
46 void Idle(); 41 void Idle();
47 /// Execute a single instruction in current jit.
48 void Step();
49 /// Stop JIT execution/exit
50 void Stop();
51
52 /// Interrupt this physical core. 42 /// Interrupt this physical core.
53 void Interrupt(); 43 void Interrupt();
54 44
@@ -63,14 +53,6 @@ public:
63 // Shutdown this physical core. 53 // Shutdown this physical core.
64 void Shutdown(); 54 void Shutdown();
65 55
66 Core::ARM_Interface& ArmInterface() {
67 return *arm_interface;
68 }
69
70 const Core::ARM_Interface& ArmInterface() const {
71 return *arm_interface;
72 }
73
74 bool IsMainCore() const { 56 bool IsMainCore() const {
75 return core_index == 0; 57 return core_index == 0;
76 } 58 }
@@ -84,22 +66,17 @@ public:
84 } 66 }
85 67
86 Kernel::Scheduler& Scheduler() { 68 Kernel::Scheduler& Scheduler() {
87 return *scheduler; 69 return scheduler;
88 } 70 }
89 71
90 const Kernel::Scheduler& Scheduler() const { 72 const Kernel::Scheduler& Scheduler() const {
91 return *scheduler; 73 return scheduler;
92 } 74 }
93 75
94 void SetIs64Bit(bool is_64_bit);
95
96private: 76private:
97 Core::CPUInterruptHandler& interrupt_handler; 77 Core::CPUInterruptHandler& interrupt_handler;
98 std::size_t core_index; 78 std::size_t core_index;
99 Core::ARM_Interface& arm_interface_32; 79 Kernel::Scheduler& scheduler;
100 Core::ARM_Interface& arm_interface_64;
101 std::unique_ptr<Kernel::Scheduler> scheduler;
102 Core::ARM_Interface* arm_interface{};
103 std::unique_ptr<Common::SpinLock> guard; 80 std::unique_ptr<Common::SpinLock> guard;
104}; 81};
105 82
diff --git a/src/core/hle/kernel/scheduler.cpp b/src/core/hle/kernel/scheduler.cpp
index 8d56b49ce..a5083ae7c 100644
--- a/src/core/hle/kernel/scheduler.cpp
+++ b/src/core/hle/kernel/scheduler.cpp
@@ -681,15 +681,16 @@ void Scheduler::SwitchContextStep2() {
681 new_thread->SetWasRunning(false); 681 new_thread->SetWasRunning(false);
682 682
683 auto* const thread_owner_process = current_thread->GetOwnerProcess(); 683 auto* const thread_owner_process = current_thread->GetOwnerProcess();
684 if (previous_process != thread_owner_process && thread_owner_process != nullptr) { 684 if (thread_owner_process != nullptr) {
685 system.Kernel().MakeCurrentProcess(thread_owner_process); 685 system.Kernel().MakeCurrentProcess(thread_owner_process);
686 } 686 }
687 if (!new_thread->IsHLEThread()) { 687 if (!new_thread->IsHLEThread()) {
688 auto& cpu_core = system.ArmInterface(core_id); 688 Core::ARM_Interface& cpu_core = new_thread->ArmInterface();
689 cpu_core.LoadContext(new_thread->GetContext32()); 689 cpu_core.LoadContext(new_thread->GetContext32());
690 cpu_core.LoadContext(new_thread->GetContext64()); 690 cpu_core.LoadContext(new_thread->GetContext64());
691 cpu_core.SetTlsAddress(new_thread->GetTLSAddress()); 691 cpu_core.SetTlsAddress(new_thread->GetTLSAddress());
692 cpu_core.SetTPIDR_EL0(new_thread->GetTPIDR_EL0()); 692 cpu_core.SetTPIDR_EL0(new_thread->GetTPIDR_EL0());
693 cpu_core.ChangeProcessorId(this->core_id);
693 cpu_core.ClearExclusiveState(); 694 cpu_core.ClearExclusiveState();
694 } 695 }
695 } 696 }
@@ -722,18 +723,15 @@ void Scheduler::SwitchContext() {
722 } 723 }
723 previous_thread->SetContinuousOnSVC(false); 724 previous_thread->SetContinuousOnSVC(false);
724 previous_thread->last_running_ticks = system.CoreTiming().GetCPUTicks(); 725 previous_thread->last_running_ticks = system.CoreTiming().GetCPUTicks();
726 previous_thread->SetIsRunning(false);
725 if (!previous_thread->IsHLEThread()) { 727 if (!previous_thread->IsHLEThread()) {
726 auto& cpu_core = system.ArmInterface(core_id); 728 Core::ARM_Interface& cpu_core = previous_thread->ArmInterface();
727 cpu_core.SaveContext(previous_thread->GetContext32()); 729 cpu_core.SaveContext(previous_thread->GetContext32());
728 cpu_core.SaveContext(previous_thread->GetContext64()); 730 cpu_core.SaveContext(previous_thread->GetContext64());
729 // Save the TPIDR_EL0 system register in case it was modified. 731 // Save the TPIDR_EL0 system register in case it was modified.
730 previous_thread->SetTPIDR_EL0(cpu_core.GetTPIDR_EL0()); 732 previous_thread->SetTPIDR_EL0(cpu_core.GetTPIDR_EL0());
731 cpu_core.ClearExclusiveState(); 733 cpu_core.ClearExclusiveState();
732 } 734 }
733 if (previous_thread->GetStatus() == ThreadStatus::Running) {
734 previous_thread->SetStatus(ThreadStatus::Ready);
735 }
736 previous_thread->SetIsRunning(false);
737 previous_thread->context_guard.unlock(); 735 previous_thread->context_guard.unlock();
738 } 736 }
739 737
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index f08745226..599972211 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -1533,7 +1533,9 @@ static void SleepThread(Core::System& system, s64 nanoseconds) {
1533 } 1533 }
1534 1534
1535 if (is_redundant && !system.Kernel().IsMulticore()) { 1535 if (is_redundant && !system.Kernel().IsMulticore()) {
1536 system.Kernel().ExitSVCProfile();
1536 system.GetCpuManager().PreemptSingleCore(); 1537 system.GetCpuManager().PreemptSingleCore();
1538 system.Kernel().EnterSVCProfile();
1537 } 1539 }
1538} 1540}
1539 1541
@@ -2457,9 +2459,6 @@ void Call(Core::System& system, u32 immediate) {
2457 auto& kernel = system.Kernel(); 2459 auto& kernel = system.Kernel();
2458 kernel.EnterSVCProfile(); 2460 kernel.EnterSVCProfile();
2459 2461
2460 auto* thread = system.CurrentScheduler().GetCurrentThread();
2461 thread->SetContinuousOnSVC(true);
2462
2463 const FunctionDef* info = system.CurrentProcess()->Is64BitProcess() ? GetSVCInfo64(immediate) 2462 const FunctionDef* info = system.CurrentProcess()->Is64BitProcess() ? GetSVCInfo64(immediate)
2464 : GetSVCInfo32(immediate); 2463 : GetSVCInfo32(immediate);
2465 if (info) { 2464 if (info) {
@@ -2473,12 +2472,6 @@ void Call(Core::System& system, u32 immediate) {
2473 } 2472 }
2474 2473
2475 kernel.ExitSVCProfile(); 2474 kernel.ExitSVCProfile();
2476
2477 if (!thread->IsContinuousOnSVC()) {
2478 auto* host_context = thread->GetHostContext().get();
2479 host_context->Rewind();
2480 }
2481
2482 system.EnterDynarmicProfile(); 2475 system.EnterDynarmicProfile();
2483} 2476}
2484 2477
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index 6f8e7a070..58b06aa9e 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -13,6 +13,13 @@
13#include "common/logging/log.h" 13#include "common/logging/log.h"
14#include "common/thread_queue_list.h" 14#include "common/thread_queue_list.h"
15#include "core/arm/arm_interface.h" 15#include "core/arm/arm_interface.h"
16#ifdef ARCHITECTURE_x86_64
17#include "core/arm/dynarmic/arm_dynarmic_32.h"
18#include "core/arm/dynarmic/arm_dynarmic_64.h"
19#endif
20#include "core/arm/cpu_interrupt_handler.h"
21#include "core/arm/exclusive_monitor.h"
22#include "core/arm/unicorn/arm_unicorn.h"
16#include "core/core.h" 23#include "core/core.h"
17#include "core/core_timing.h" 24#include "core/core_timing.h"
18#include "core/core_timing_util.h" 25#include "core/core_timing_util.h"
@@ -232,7 +239,27 @@ ResultVal<std::shared_ptr<Thread>> Thread::Create(Core::System& system, ThreadTy
232 } 239 }
233 // TODO(peachum): move to ScheduleThread() when scheduler is added so selected core is used 240 // TODO(peachum): move to ScheduleThread() when scheduler is added so selected core is used
234 // to initialize the context 241 // to initialize the context
242 thread->arm_interface.reset();
235 if ((type_flags & THREADTYPE_HLE) == 0) { 243 if ((type_flags & THREADTYPE_HLE) == 0) {
244#ifdef ARCHITECTURE_x86_64
245 if (owner_process && !owner_process->Is64BitProcess()) {
246 thread->arm_interface = std::make_unique<Core::ARM_Dynarmic_32>(
247 system, kernel.Interrupts(), kernel.GetExclusiveMonitor(), processor_id);
248 } else {
249 thread->arm_interface = std::make_unique<Core::ARM_Dynarmic_64>(
250 system, kernel.Interrupts(), kernel.GetExclusiveMonitor(), processor_id);
251 }
252
253#else
254 if (owner_process && !owner_process->Is64BitProcess()) {
255 thread->arm_interface = std::make_shared<Core::ARM_Unicorn>(
256 system, kernel.Interrupts(), ARM_Unicorn::Arch::AArch32, processor_id);
257 } else {
258 thread->arm_interface = std::make_shared<Core::ARM_Unicorn>(
259 system, kernel.Interrupts(), ARM_Unicorn::Arch::AArch64, processor_id);
260 }
261 LOG_WARNING(Core, "CPU JIT requested, but Dynarmic not available");
262#endif
236 ResetThreadContext32(thread->context_32, static_cast<u32>(stack_top), 263 ResetThreadContext32(thread->context_32, static_cast<u32>(stack_top),
237 static_cast<u32>(entry_point), static_cast<u32>(arg)); 264 static_cast<u32>(entry_point), static_cast<u32>(arg));
238 ResetThreadContext64(thread->context_64, stack_top, entry_point, arg); 265 ResetThreadContext64(thread->context_64, stack_top, entry_point, arg);
@@ -276,6 +303,14 @@ VAddr Thread::GetCommandBufferAddress() const {
276 return GetTLSAddress() + command_header_offset; 303 return GetTLSAddress() + command_header_offset;
277} 304}
278 305
306Core::ARM_Interface& Thread::ArmInterface() {
307 return *arm_interface;
308}
309
310const Core::ARM_Interface& Thread::ArmInterface() const {
311 return *arm_interface;
312}
313
279void Thread::SetStatus(ThreadStatus new_status) { 314void Thread::SetStatus(ThreadStatus new_status) {
280 if (new_status == status) { 315 if (new_status == status) {
281 return; 316 return;
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h
index f998890c4..c08fc3a89 100644
--- a/src/core/hle/kernel/thread.h
+++ b/src/core/hle/kernel/thread.h
@@ -21,6 +21,7 @@ class Fiber;
21} 21}
22 22
23namespace Core { 23namespace Core {
24class ARM_Interface;
24class System; 25class System;
25} // namespace Core 26} // namespace Core
26 27
@@ -271,6 +272,10 @@ public:
271 272
272 void SetSynchronizationResults(SynchronizationObject* object, ResultCode result); 273 void SetSynchronizationResults(SynchronizationObject* object, ResultCode result);
273 274
275 Core::ARM_Interface& ArmInterface();
276
277 const Core::ARM_Interface& ArmInterface() const;
278
274 SynchronizationObject* GetSignalingObject() const { 279 SynchronizationObject* GetSignalingObject() const {
275 return signaling_object; 280 return signaling_object;
276 } 281 }
@@ -617,9 +622,10 @@ private:
617 622
618 void AdjustSchedulingOnAffinity(u64 old_affinity_mask, s32 old_core); 623 void AdjustSchedulingOnAffinity(u64 old_affinity_mask, s32 old_core);
619 624
625 Common::SpinLock context_guard{};
620 ThreadContext32 context_32{}; 626 ThreadContext32 context_32{};
621 ThreadContext64 context_64{}; 627 ThreadContext64 context_64{};
622 Common::SpinLock context_guard{}; 628 std::unique_ptr<Core::ARM_Interface> arm_interface{};
623 std::shared_ptr<Common::Fiber> host_context{}; 629 std::shared_ptr<Common::Fiber> host_context{};
624 630
625 u64 thread_id = 0; 631 u64 thread_id = 0;