From 45c87c7e6e841c11def43e5ab25160006dab6d77 Mon Sep 17 00:00:00 2001 From: Liam Date: Tue, 28 Nov 2023 14:30:39 -0500 Subject: core: refactor emulated cpu core activation --- src/core/hle/kernel/svc/svc_exception.cpp | 4 +- src/core/hle/kernel/svc/svc_light_ipc.cpp | 31 +++++++------- .../hle/kernel/svc/svc_secure_monitor_call.cpp | 22 +++++----- src/core/hle/kernel/svc/svc_thread.cpp | 50 +++++----------------- 4 files changed, 36 insertions(+), 71 deletions(-) (limited to 'src/core/hle/kernel/svc') diff --git a/src/core/hle/kernel/svc/svc_exception.cpp b/src/core/hle/kernel/svc/svc_exception.cpp index c581c086b..47b756828 100644 --- a/src/core/hle/kernel/svc/svc_exception.cpp +++ b/src/core/hle/kernel/svc/svc_exception.cpp @@ -103,9 +103,7 @@ void Break(Core::System& system, BreakReason reason, u64 info1, u64 info2) { handle_debug_buffer(info1, info2); - auto* const current_thread = GetCurrentThreadPointer(system.Kernel()); - const auto thread_processor_id = current_thread->GetActiveCore(); - system.ArmInterface(static_cast(thread_processor_id)).LogBacktrace(); + system.CurrentPhysicalCore().LogBacktrace(); } const bool is_hbl = GetCurrentProcess(system.Kernel()).IsHbl(); diff --git a/src/core/hle/kernel/svc/svc_light_ipc.cpp b/src/core/hle/kernel/svc/svc_light_ipc.cpp index b76ce984c..d757d5af2 100644 --- a/src/core/hle/kernel/svc/svc_light_ipc.cpp +++ b/src/core/hle/kernel/svc/svc_light_ipc.cpp @@ -37,37 +37,36 @@ Result ReplyAndReceiveLight64From32(Core::System& system, Handle session_handle, // Custom ABI implementation for light IPC. template -static void SvcWrap_LightIpc(Core::System& system, F&& cb) { - auto& core = system.CurrentArmInterface(); - std::array arguments{}; +static void SvcWrap_LightIpc(Core::System& system, std::span args, F&& cb) { + std::array ipc_args{}; - Handle session_handle = static_cast(core.GetReg(0)); + Handle session_handle = static_cast(args[0]); for (int i = 0; i < 7; i++) { - arguments[i] = static_cast(core.GetReg(i + 1)); + ipc_args[i] = static_cast(args[i + 1]); } - Result ret = cb(system, session_handle, arguments.data()); + Result ret = cb(system, session_handle, ipc_args.data()); - core.SetReg(0, ret.raw); + args[0] = ret.raw; for (int i = 0; i < 7; i++) { - core.SetReg(i + 1, arguments[i]); + args[i + 1] = ipc_args[i]; } } -void SvcWrap_SendSyncRequestLight64(Core::System& system) { - SvcWrap_LightIpc(system, SendSyncRequestLight64); +void SvcWrap_SendSyncRequestLight64(Core::System& system, std::span args) { + SvcWrap_LightIpc(system, args, SendSyncRequestLight64); } -void SvcWrap_ReplyAndReceiveLight64(Core::System& system) { - SvcWrap_LightIpc(system, ReplyAndReceiveLight64); +void SvcWrap_ReplyAndReceiveLight64(Core::System& system, std::span args) { + SvcWrap_LightIpc(system, args, ReplyAndReceiveLight64); } -void SvcWrap_SendSyncRequestLight64From32(Core::System& system) { - SvcWrap_LightIpc(system, SendSyncRequestLight64From32); +void SvcWrap_SendSyncRequestLight64From32(Core::System& system, std::span args) { + SvcWrap_LightIpc(system, args, SendSyncRequestLight64From32); } -void SvcWrap_ReplyAndReceiveLight64From32(Core::System& system) { - SvcWrap_LightIpc(system, ReplyAndReceiveLight64From32); +void SvcWrap_ReplyAndReceiveLight64From32(Core::System& system, std::span args) { + SvcWrap_LightIpc(system, args, ReplyAndReceiveLight64From32); } } // namespace Kernel::Svc diff --git a/src/core/hle/kernel/svc/svc_secure_monitor_call.cpp b/src/core/hle/kernel/svc/svc_secure_monitor_call.cpp index 62c781551..48b564ec8 100644 --- a/src/core/hle/kernel/svc/svc_secure_monitor_call.cpp +++ b/src/core/hle/kernel/svc/svc_secure_monitor_call.cpp @@ -22,31 +22,29 @@ void CallSecureMonitor64From32(Core::System& system, ilp32::SecureMonitorArgumen // Custom ABI for CallSecureMonitor. -void SvcWrap_CallSecureMonitor64(Core::System& system) { - auto& core = system.CurrentPhysicalCore().ArmInterface(); - lp64::SecureMonitorArguments args{}; +void SvcWrap_CallSecureMonitor64(Core::System& system, std::span args) { + lp64::SecureMonitorArguments smc_args{}; for (int i = 0; i < 8; i++) { - args.r[i] = core.GetReg(i); + smc_args.r[i] = args[i]; } - CallSecureMonitor64(system, std::addressof(args)); + CallSecureMonitor64(system, std::addressof(smc_args)); for (int i = 0; i < 8; i++) { - core.SetReg(i, args.r[i]); + args[i] = smc_args.r[i]; } } -void SvcWrap_CallSecureMonitor64From32(Core::System& system) { - auto& core = system.CurrentPhysicalCore().ArmInterface(); - ilp32::SecureMonitorArguments args{}; +void SvcWrap_CallSecureMonitor64From32(Core::System& system, std::span args) { + ilp32::SecureMonitorArguments smc_args{}; for (int i = 0; i < 8; i++) { - args.r[i] = static_cast(core.GetReg(i)); + smc_args.r[i] = static_cast(args[i]); } - CallSecureMonitor64From32(system, std::addressof(args)); + CallSecureMonitor64From32(system, std::addressof(smc_args)); for (int i = 0; i < 8; i++) { - core.SetReg(i, args.r[i]); + args[i] = smc_args.r[i]; } } diff --git a/src/core/hle/kernel/svc/svc_thread.cpp b/src/core/hle/kernel/svc/svc_thread.cpp index 755fd62b5..7681afa33 100644 --- a/src/core/hle/kernel/svc/svc_thread.cpp +++ b/src/core/hle/kernel/svc/svc_thread.cpp @@ -90,8 +90,6 @@ Result StartThread(Core::System& system, Handle thread_handle) { /// Called when a thread exits void ExitThread(Core::System& system) { - LOG_DEBUG(Kernel_SVC, "called, pc=0x{:08X}", system.CurrentArmInterface().GetPC()); - auto* const current_thread = GetCurrentThreadPointer(system.Kernel()); system.GlobalSchedulerContext().RemoveThread(current_thread); current_thread->Exit(); @@ -147,47 +145,19 @@ Result GetThreadContext3(Core::System& system, u64 out_context, Handle thread_ha R_UNLESS(thread.IsNotNull(), ResultInvalidHandle); // Require the handle be to a non-current thread in the current process. - const auto* current_process = GetCurrentProcessPointer(kernel); - R_UNLESS(current_process == thread->GetOwnerProcess(), ResultInvalidId); - - // Verify that the thread isn't terminated. - R_UNLESS(thread->GetState() != ThreadState::Terminated, ResultTerminationRequested); - - /// Check that the thread is not the current one. - /// NOTE: Nintendo does not check this, and thus the following loop will deadlock. - R_UNLESS(thread.GetPointerUnsafe() != GetCurrentThreadPointer(kernel), ResultInvalidId); - - // Try to get the thread context until the thread isn't current on any core. - while (true) { - KScopedSchedulerLock sl{kernel}; - - // TODO(bunnei): Enforce that thread is suspended for debug here. - - // If the thread's raw state isn't runnable, check if it's current on some core. - if (thread->GetRawState() != ThreadState::Runnable) { - bool current = false; - for (auto i = 0; i < static_cast(Core::Hardware::NUM_CPU_CORES); ++i) { - if (thread.GetPointerUnsafe() == kernel.Scheduler(i).GetSchedulerCurrentThread()) { - current = true; - break; - } - } + R_UNLESS(thread->GetOwnerProcess() == GetCurrentProcessPointer(kernel), ResultInvalidHandle); + R_UNLESS(thread.GetPointerUnsafe() != GetCurrentThreadPointer(kernel), ResultBusy); - // If the thread is current, retry until it isn't. - if (current) { - continue; - } - } + // Get the thread context. + Svc::ThreadContext context{}; + R_TRY(thread->GetThreadContext3(std::addressof(context))); - // Get the thread context. - static thread_local Common::ScratchBuffer context; - R_TRY(thread->GetThreadContext3(context)); + // Copy the thread context to user space. + R_UNLESS( + GetCurrentMemory(kernel).WriteBlock(out_context, std::addressof(context), sizeof(context)), + ResultInvalidPointer); - // Copy the thread context to user space. - GetCurrentMemory(kernel).WriteBlock(out_context, context.data(), context.size()); - - R_SUCCEED(); - } + R_SUCCEED(); } /// Gets the priority for the specified thread -- cgit v1.2.3