diff options
| author | 2020-03-01 12:14:17 -0400 | |
|---|---|---|
| committer | 2020-06-27 11:35:58 -0400 | |
| commit | 1567824d2da8e9b49b433f3d1d753d8ad84e65f9 (patch) | |
| tree | c9553bb3f1693e430054695737d2f87ba4b58955 /src | |
| parent | Core: Refactor ARM Interface. (diff) | |
| download | yuzu-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.h | 2 | ||||
| -rw-r--r-- | src/core/arm/dynarmic/arm_dynarmic_32.cpp | 4 | ||||
| -rw-r--r-- | src/core/arm/dynarmic/arm_dynarmic_32.h | 1 | ||||
| -rw-r--r-- | src/core/arm/dynarmic/arm_dynarmic_64.cpp | 4 | ||||
| -rw-r--r-- | src/core/arm/dynarmic/arm_dynarmic_64.h | 1 | ||||
| -rw-r--r-- | src/core/arm/unicorn/arm_unicorn.cpp | 4 | ||||
| -rw-r--r-- | src/core/arm/unicorn/arm_unicorn.h | 1 | ||||
| -rw-r--r-- | src/core/core.cpp | 34 | ||||
| -rw-r--r-- | src/core/core_manager.cpp | 18 | ||||
| -rw-r--r-- | src/core/cpu_manager.cpp | 30 | ||||
| -rw-r--r-- | src/core/hle/kernel/kernel.cpp | 59 | ||||
| -rw-r--r-- | src/core/hle/kernel/kernel.h | 8 | ||||
| -rw-r--r-- | src/core/hle/kernel/physical_core.cpp | 37 | ||||
| -rw-r--r-- | src/core/hle/kernel/physical_core.h | 37 | ||||
| -rw-r--r-- | src/core/hle/kernel/scheduler.cpp | 12 | ||||
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 11 | ||||
| -rw-r--r-- | src/core/hle/kernel/thread.cpp | 35 | ||||
| -rw-r--r-- | src/core/hle/kernel/thread.h | 8 |
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 | ||
| 168 | void ARM_Dynarmic_32::ChangeProcessorId(std::size_t new_core_id) { | ||
| 169 | // jit->ChangeProcessorId(new_core_id); | ||
| 170 | } | ||
| 171 | |||
| 168 | void ARM_Dynarmic_32::SaveContext(ThreadContext32& ctx) { | 172 | void 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 | ||
| 261 | void ARM_Dynarmic_64::ChangeProcessorId(std::size_t new_core_id) { | ||
| 262 | jit->ChangeProcessorId(new_core_id); | ||
| 263 | } | ||
| 264 | |||
| 261 | void ARM_Dynarmic_64::SaveContext(ThreadContext64& ctx) { | 265 | void 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 | ||
| 162 | void ARM_Unicorn::ChangeProcessorId(std::size_t new_core_id) { | ||
| 163 | core_index = new_core_id; | ||
| 164 | } | ||
| 165 | |||
| 162 | void ARM_Unicorn::Run() { | 166 | void 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 | ||
| 445 | void System::PrepareReschedule() { | 437 | void System::PrepareReschedule() { |
| 446 | impl->CurrentPhysicalCore().Stop(); | 438 | //impl->CurrentPhysicalCore().Stop(); |
| 447 | } | 439 | } |
| 448 | 440 | ||
| 449 | void System::PrepareReschedule(const u32 core_index) { | 441 | void System::PrepareReschedule(const u32 core_index) { |
| @@ -463,11 +455,11 @@ const TelemetrySession& System::TelemetrySession() const { | |||
| 463 | } | 455 | } |
| 464 | 456 | ||
| 465 | ARM_Interface& System::CurrentArmInterface() { | 457 | ARM_Interface& System::CurrentArmInterface() { |
| 466 | return impl->CurrentPhysicalCore().ArmInterface(); | 458 | return impl->kernel.CurrentScheduler().GetCurrentThread()->ArmInterface(); |
| 467 | } | 459 | } |
| 468 | 460 | ||
| 469 | const ARM_Interface& System::CurrentArmInterface() const { | 461 | const ARM_Interface& System::CurrentArmInterface() const { |
| 470 | return impl->CurrentPhysicalCore().ArmInterface(); | 462 | return impl->kernel.CurrentScheduler().GetCurrentThread()->ArmInterface(); |
| 471 | } | 463 | } |
| 472 | 464 | ||
| 473 | std::size_t System::CurrentCoreIndex() const { | 465 | std::size_t System::CurrentCoreIndex() const { |
| @@ -477,27 +469,27 @@ std::size_t System::CurrentCoreIndex() const { | |||
| 477 | } | 469 | } |
| 478 | 470 | ||
| 479 | Kernel::Scheduler& System::CurrentScheduler() { | 471 | Kernel::Scheduler& System::CurrentScheduler() { |
| 480 | return impl->CurrentPhysicalCore().Scheduler(); | 472 | return impl->kernel.CurrentScheduler(); |
| 481 | } | 473 | } |
| 482 | 474 | ||
| 483 | const Kernel::Scheduler& System::CurrentScheduler() const { | 475 | const Kernel::Scheduler& System::CurrentScheduler() const { |
| 484 | return impl->CurrentPhysicalCore().Scheduler(); | 476 | return impl->kernel.CurrentScheduler(); |
| 485 | } | 477 | } |
| 486 | 478 | ||
| 487 | Kernel::PhysicalCore& System::CurrentPhysicalCore() { | 479 | Kernel::PhysicalCore& System::CurrentPhysicalCore() { |
| 488 | return impl->CurrentPhysicalCore(); | 480 | return impl->kernel.CurrentPhysicalCore(); |
| 489 | } | 481 | } |
| 490 | 482 | ||
| 491 | const Kernel::PhysicalCore& System::CurrentPhysicalCore() const { | 483 | const Kernel::PhysicalCore& System::CurrentPhysicalCore() const { |
| 492 | return impl->CurrentPhysicalCore(); | 484 | return impl->kernel.CurrentPhysicalCore(); |
| 493 | } | 485 | } |
| 494 | 486 | ||
| 495 | Kernel::Scheduler& System::Scheduler(std::size_t core_index) { | 487 | Kernel::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 | ||
| 499 | const Kernel::Scheduler& System::Scheduler(std::size_t core_index) const { | 491 | const 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 | ||
| 529 | ARM_Interface& System::ArmInterface(std::size_t core_index) { | 521 | ARM_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 | ||
| 533 | const ARM_Interface& System::ArmInterface(std::size_t core_index) const { | 527 | const 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 | ||
| 537 | ExclusiveMonitor& System::Monitor() { | 533 | ExclusiveMonitor& 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) | |||
| 28 | CoreManager::~CoreManager() = default; | 28 | CoreManager::~CoreManager() = default; |
| 29 | 29 | ||
| 30 | void CoreManager::RunLoop(bool tight_loop) { | 30 | void 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 | ||
| 48 | void CoreManager::SingleStep() { | 34 | void CoreManager::SingleStep() { |
| @@ -50,7 +36,7 @@ void CoreManager::SingleStep() { | |||
| 50 | } | 36 | } |
| 51 | 37 | ||
| 52 | void CoreManager::PrepareReschedule() { | 38 | void CoreManager::PrepareReschedule() { |
| 53 | physical_core.Stop(); | 39 | //physical_core.Stop(); |
| 54 | } | 40 | } |
| 55 | 41 | ||
| 56 | void CoreManager::Reschedule() { | 42 | void 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() { | |||
| 129 | void CpuManager::MultiCoreRunGuestLoop() { | 129 | void 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() { | |||
| 229 | void CpuManager::SingleCoreRunGuestLoop() { | 228 | void 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 | |||
| 53 | MICROPROFILE_DEFINE(Kernel_SVC, "Kernel", "SVC", MP_RGB(70, 200, 70)); | 47 | MICROPROFILE_DEFINE(Kernel_SVC, "Kernel", "SVC", MP_RGB(70, 200, 70)); |
| 54 | 48 | ||
| 55 | namespace Kernel { | 49 | namespace 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 | ||
| 499 | Kernel::Scheduler& KernelCore::Scheduler(std::size_t id) { | 474 | Kernel::Scheduler& KernelCore::Scheduler(std::size_t id) { |
| 500 | return impl->cores[id].Scheduler(); | 475 | return *impl->schedulers[id]; |
| 501 | } | 476 | } |
| 502 | 477 | ||
| 503 | const Kernel::Scheduler& KernelCore::Scheduler(std::size_t id) const { | 478 | const Kernel::Scheduler& KernelCore::Scheduler(std::size_t id) const { |
| 504 | return impl->cores[id].Scheduler(); | 479 | return *impl->schedulers[id]; |
| 505 | } | 480 | } |
| 506 | 481 | ||
| 507 | Kernel::PhysicalCore& KernelCore::PhysicalCore(std::size_t id) { | 482 | Kernel::PhysicalCore& KernelCore::PhysicalCore(std::size_t id) { |
| @@ -525,11 +500,23 @@ const Kernel::PhysicalCore& KernelCore::CurrentPhysicalCore() const { | |||
| 525 | } | 500 | } |
| 526 | 501 | ||
| 527 | Kernel::Scheduler& KernelCore::CurrentScheduler() { | 502 | Kernel::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 | ||
| 531 | const Kernel::Scheduler& KernelCore::CurrentScheduler() const { | 508 | const 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 | |||
| 514 | std::array<Core::CPUInterruptHandler, Core::Hardware::NUM_CPU_CORES>& KernelCore::Interrupts() { | ||
| 515 | return impl->interrupts; | ||
| 516 | } | ||
| 517 | |||
| 518 | const std::array<Core::CPUInterruptHandler, Core::Hardware::NUM_CPU_CORES>& KernelCore::Interrupts() const { | ||
| 519 | return impl->interrupts; | ||
| 533 | } | 520 | } |
| 534 | 521 | ||
| 535 | Kernel::Synchronization& KernelCore::Synchronization() { | 522 | Kernel::Synchronization& KernelCore::Synchronization() { |
| @@ -557,15 +544,11 @@ const Core::ExclusiveMonitor& KernelCore::GetExclusiveMonitor() const { | |||
| 557 | } | 544 | } |
| 558 | 545 | ||
| 559 | void KernelCore::InvalidateAllInstructionCaches() { | 546 | void 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 | ||
| 565 | void KernelCore::PrepareReschedule(std::size_t id) { | 550 | void 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 | ||
| 571 | void KernelCore::AddNamedPort(std::string name, std::shared_ptr<ClientPort> port) { | 554 | void 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 | ||
| 14 | namespace Core { | 16 | namespace Core { |
| 15 | struct EmuThreadHandle; | 17 | class CPUInterruptHandler; |
| 16 | class ExclusiveMonitor; | 18 | class ExclusiveMonitor; |
| 17 | class System; | 19 | class 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 | ||
| 21 | namespace Kernel { | 21 | namespace Kernel { |
| 22 | 22 | ||
| 23 | PhysicalCore::PhysicalCore(Core::System& system, std::size_t id, | 23 | PhysicalCore::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 | ||
| 35 | PhysicalCore::~PhysicalCore() = default; | 30 | PhysicalCore::~PhysicalCore() = default; |
| 36 | 31 | ||
| 37 | void PhysicalCore::Run() { | ||
| 38 | arm_interface->Run(); | ||
| 39 | } | ||
| 40 | |||
| 41 | void PhysicalCore::ClearExclusive() { | ||
| 42 | arm_interface->ClearExclusiveState(); | ||
| 43 | } | ||
| 44 | |||
| 45 | void PhysicalCore::Step() { | ||
| 46 | arm_interface->Step(); | ||
| 47 | } | ||
| 48 | |||
| 49 | void PhysicalCore::Idle() { | 32 | void PhysicalCore::Idle() { |
| 50 | interrupt_handler.AwaitInterrupt(); | 33 | interrupt_handler.AwaitInterrupt(); |
| 51 | } | 34 | } |
| 52 | 35 | ||
| 53 | void PhysicalCore::Stop() { | ||
| 54 | arm_interface->PrepareReschedule(); | ||
| 55 | } | ||
| 56 | |||
| 57 | void PhysicalCore::Shutdown() { | 36 | void PhysicalCore::Shutdown() { |
| 58 | scheduler->Shutdown(); | 37 | scheduler.Shutdown(); |
| 59 | } | ||
| 60 | |||
| 61 | void 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 | ||
| 69 | void PhysicalCore::Interrupt() { | 40 | void 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 | ||
| 12 | namespace Common { | 12 | namespace Common { |
| 13 | class SpinLock; | 13 | class SpinLock; |
| 14 | } | 14 | } |
| 15 | 15 | ||
| 16 | namespace Kernel { | 16 | namespace Kernel { |
| @@ -27,9 +27,9 @@ namespace Kernel { | |||
| 27 | 27 | ||
| 28 | class PhysicalCore { | 28 | class PhysicalCore { |
| 29 | public: | 29 | public: |
| 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 | |||
| 96 | private: | 76 | private: |
| 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 | ||
| 306 | Core::ARM_Interface& Thread::ArmInterface() { | ||
| 307 | return *arm_interface; | ||
| 308 | } | ||
| 309 | |||
| 310 | const Core::ARM_Interface& Thread::ArmInterface() const { | ||
| 311 | return *arm_interface; | ||
| 312 | } | ||
| 313 | |||
| 279 | void Thread::SetStatus(ThreadStatus new_status) { | 314 | void 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 | ||
| 23 | namespace Core { | 23 | namespace Core { |
| 24 | class ARM_Interface; | ||
| 24 | class System; | 25 | class 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; |