diff options
Diffstat (limited to 'src/core/hle/kernel/svc')
| -rw-r--r-- | src/core/hle/kernel/svc/svc_exception.cpp | 4 | ||||
| -rw-r--r-- | src/core/hle/kernel/svc/svc_light_ipc.cpp | 31 | ||||
| -rw-r--r-- | src/core/hle/kernel/svc/svc_secure_monitor_call.cpp | 22 | ||||
| -rw-r--r-- | src/core/hle/kernel/svc/svc_thread.cpp | 50 |
4 files changed, 36 insertions, 71 deletions
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) { | |||
| 103 | 103 | ||
| 104 | handle_debug_buffer(info1, info2); | 104 | handle_debug_buffer(info1, info2); |
| 105 | 105 | ||
| 106 | auto* const current_thread = GetCurrentThreadPointer(system.Kernel()); | 106 | system.CurrentPhysicalCore().LogBacktrace(); |
| 107 | const auto thread_processor_id = current_thread->GetActiveCore(); | ||
| 108 | system.ArmInterface(static_cast<std::size_t>(thread_processor_id)).LogBacktrace(); | ||
| 109 | } | 107 | } |
| 110 | 108 | ||
| 111 | const bool is_hbl = GetCurrentProcess(system.Kernel()).IsHbl(); | 109 | 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, | |||
| 37 | // Custom ABI implementation for light IPC. | 37 | // Custom ABI implementation for light IPC. |
| 38 | 38 | ||
| 39 | template <typename F> | 39 | template <typename F> |
| 40 | static void SvcWrap_LightIpc(Core::System& system, F&& cb) { | 40 | static void SvcWrap_LightIpc(Core::System& system, std::span<uint64_t, 8> args, F&& cb) { |
| 41 | auto& core = system.CurrentArmInterface(); | 41 | std::array<u32, 7> ipc_args{}; |
| 42 | std::array<u32, 7> arguments{}; | ||
| 43 | 42 | ||
| 44 | Handle session_handle = static_cast<Handle>(core.GetReg(0)); | 43 | Handle session_handle = static_cast<Handle>(args[0]); |
| 45 | for (int i = 0; i < 7; i++) { | 44 | for (int i = 0; i < 7; i++) { |
| 46 | arguments[i] = static_cast<u32>(core.GetReg(i + 1)); | 45 | ipc_args[i] = static_cast<u32>(args[i + 1]); |
| 47 | } | 46 | } |
| 48 | 47 | ||
| 49 | Result ret = cb(system, session_handle, arguments.data()); | 48 | Result ret = cb(system, session_handle, ipc_args.data()); |
| 50 | 49 | ||
| 51 | core.SetReg(0, ret.raw); | 50 | args[0] = ret.raw; |
| 52 | for (int i = 0; i < 7; i++) { | 51 | for (int i = 0; i < 7; i++) { |
| 53 | core.SetReg(i + 1, arguments[i]); | 52 | args[i + 1] = ipc_args[i]; |
| 54 | } | 53 | } |
| 55 | } | 54 | } |
| 56 | 55 | ||
| 57 | void SvcWrap_SendSyncRequestLight64(Core::System& system) { | 56 | void SvcWrap_SendSyncRequestLight64(Core::System& system, std::span<uint64_t, 8> args) { |
| 58 | SvcWrap_LightIpc(system, SendSyncRequestLight64); | 57 | SvcWrap_LightIpc(system, args, SendSyncRequestLight64); |
| 59 | } | 58 | } |
| 60 | 59 | ||
| 61 | void SvcWrap_ReplyAndReceiveLight64(Core::System& system) { | 60 | void SvcWrap_ReplyAndReceiveLight64(Core::System& system, std::span<uint64_t, 8> args) { |
| 62 | SvcWrap_LightIpc(system, ReplyAndReceiveLight64); | 61 | SvcWrap_LightIpc(system, args, ReplyAndReceiveLight64); |
| 63 | } | 62 | } |
| 64 | 63 | ||
| 65 | void SvcWrap_SendSyncRequestLight64From32(Core::System& system) { | 64 | void SvcWrap_SendSyncRequestLight64From32(Core::System& system, std::span<uint64_t, 8> args) { |
| 66 | SvcWrap_LightIpc(system, SendSyncRequestLight64From32); | 65 | SvcWrap_LightIpc(system, args, SendSyncRequestLight64From32); |
| 67 | } | 66 | } |
| 68 | 67 | ||
| 69 | void SvcWrap_ReplyAndReceiveLight64From32(Core::System& system) { | 68 | void SvcWrap_ReplyAndReceiveLight64From32(Core::System& system, std::span<uint64_t, 8> args) { |
| 70 | SvcWrap_LightIpc(system, ReplyAndReceiveLight64From32); | 69 | SvcWrap_LightIpc(system, args, ReplyAndReceiveLight64From32); |
| 71 | } | 70 | } |
| 72 | 71 | ||
| 73 | } // namespace Kernel::Svc | 72 | } // 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 | |||
| 22 | 22 | ||
| 23 | // Custom ABI for CallSecureMonitor. | 23 | // Custom ABI for CallSecureMonitor. |
| 24 | 24 | ||
| 25 | void SvcWrap_CallSecureMonitor64(Core::System& system) { | 25 | void SvcWrap_CallSecureMonitor64(Core::System& system, std::span<uint64_t, 8> args) { |
| 26 | auto& core = system.CurrentPhysicalCore().ArmInterface(); | 26 | lp64::SecureMonitorArguments smc_args{}; |
| 27 | lp64::SecureMonitorArguments args{}; | ||
| 28 | for (int i = 0; i < 8; i++) { | 27 | for (int i = 0; i < 8; i++) { |
| 29 | args.r[i] = core.GetReg(i); | 28 | smc_args.r[i] = args[i]; |
| 30 | } | 29 | } |
| 31 | 30 | ||
| 32 | CallSecureMonitor64(system, std::addressof(args)); | 31 | CallSecureMonitor64(system, std::addressof(smc_args)); |
| 33 | 32 | ||
| 34 | for (int i = 0; i < 8; i++) { | 33 | for (int i = 0; i < 8; i++) { |
| 35 | core.SetReg(i, args.r[i]); | 34 | args[i] = smc_args.r[i]; |
| 36 | } | 35 | } |
| 37 | } | 36 | } |
| 38 | 37 | ||
| 39 | void SvcWrap_CallSecureMonitor64From32(Core::System& system) { | 38 | void SvcWrap_CallSecureMonitor64From32(Core::System& system, std::span<uint64_t, 8> args) { |
| 40 | auto& core = system.CurrentPhysicalCore().ArmInterface(); | 39 | ilp32::SecureMonitorArguments smc_args{}; |
| 41 | ilp32::SecureMonitorArguments args{}; | ||
| 42 | for (int i = 0; i < 8; i++) { | 40 | for (int i = 0; i < 8; i++) { |
| 43 | args.r[i] = static_cast<u32>(core.GetReg(i)); | 41 | smc_args.r[i] = static_cast<u32>(args[i]); |
| 44 | } | 42 | } |
| 45 | 43 | ||
| 46 | CallSecureMonitor64From32(system, std::addressof(args)); | 44 | CallSecureMonitor64From32(system, std::addressof(smc_args)); |
| 47 | 45 | ||
| 48 | for (int i = 0; i < 8; i++) { | 46 | for (int i = 0; i < 8; i++) { |
| 49 | core.SetReg(i, args.r[i]); | 47 | args[i] = smc_args.r[i]; |
| 50 | } | 48 | } |
| 51 | } | 49 | } |
| 52 | 50 | ||
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) { | |||
| 90 | 90 | ||
| 91 | /// Called when a thread exits | 91 | /// Called when a thread exits |
| 92 | void ExitThread(Core::System& system) { | 92 | void ExitThread(Core::System& system) { |
| 93 | LOG_DEBUG(Kernel_SVC, "called, pc=0x{:08X}", system.CurrentArmInterface().GetPC()); | ||
| 94 | |||
| 95 | auto* const current_thread = GetCurrentThreadPointer(system.Kernel()); | 93 | auto* const current_thread = GetCurrentThreadPointer(system.Kernel()); |
| 96 | system.GlobalSchedulerContext().RemoveThread(current_thread); | 94 | system.GlobalSchedulerContext().RemoveThread(current_thread); |
| 97 | current_thread->Exit(); | 95 | current_thread->Exit(); |
| @@ -147,47 +145,19 @@ Result GetThreadContext3(Core::System& system, u64 out_context, Handle thread_ha | |||
| 147 | R_UNLESS(thread.IsNotNull(), ResultInvalidHandle); | 145 | R_UNLESS(thread.IsNotNull(), ResultInvalidHandle); |
| 148 | 146 | ||
| 149 | // Require the handle be to a non-current thread in the current process. | 147 | // Require the handle be to a non-current thread in the current process. |
| 150 | const auto* current_process = GetCurrentProcessPointer(kernel); | 148 | R_UNLESS(thread->GetOwnerProcess() == GetCurrentProcessPointer(kernel), ResultInvalidHandle); |
| 151 | R_UNLESS(current_process == thread->GetOwnerProcess(), ResultInvalidId); | 149 | R_UNLESS(thread.GetPointerUnsafe() != GetCurrentThreadPointer(kernel), ResultBusy); |
| 152 | |||
| 153 | // Verify that the thread isn't terminated. | ||
| 154 | R_UNLESS(thread->GetState() != ThreadState::Terminated, ResultTerminationRequested); | ||
| 155 | |||
| 156 | /// Check that the thread is not the current one. | ||
| 157 | /// NOTE: Nintendo does not check this, and thus the following loop will deadlock. | ||
| 158 | R_UNLESS(thread.GetPointerUnsafe() != GetCurrentThreadPointer(kernel), ResultInvalidId); | ||
| 159 | |||
| 160 | // Try to get the thread context until the thread isn't current on any core. | ||
| 161 | while (true) { | ||
| 162 | KScopedSchedulerLock sl{kernel}; | ||
| 163 | |||
| 164 | // TODO(bunnei): Enforce that thread is suspended for debug here. | ||
| 165 | |||
| 166 | // If the thread's raw state isn't runnable, check if it's current on some core. | ||
| 167 | if (thread->GetRawState() != ThreadState::Runnable) { | ||
| 168 | bool current = false; | ||
| 169 | for (auto i = 0; i < static_cast<s32>(Core::Hardware::NUM_CPU_CORES); ++i) { | ||
| 170 | if (thread.GetPointerUnsafe() == kernel.Scheduler(i).GetSchedulerCurrentThread()) { | ||
| 171 | current = true; | ||
| 172 | break; | ||
| 173 | } | ||
| 174 | } | ||
| 175 | 150 | ||
| 176 | // If the thread is current, retry until it isn't. | 151 | // Get the thread context. |
| 177 | if (current) { | 152 | Svc::ThreadContext context{}; |
| 178 | continue; | 153 | R_TRY(thread->GetThreadContext3(std::addressof(context))); |
| 179 | } | ||
| 180 | } | ||
| 181 | 154 | ||
| 182 | // Get the thread context. | 155 | // Copy the thread context to user space. |
| 183 | static thread_local Common::ScratchBuffer<u8> context; | 156 | R_UNLESS( |
| 184 | R_TRY(thread->GetThreadContext3(context)); | 157 | GetCurrentMemory(kernel).WriteBlock(out_context, std::addressof(context), sizeof(context)), |
| 158 | ResultInvalidPointer); | ||
| 185 | 159 | ||
| 186 | // Copy the thread context to user space. | 160 | R_SUCCEED(); |
| 187 | GetCurrentMemory(kernel).WriteBlock(out_context, context.data(), context.size()); | ||
| 188 | |||
| 189 | R_SUCCEED(); | ||
| 190 | } | ||
| 191 | } | 161 | } |
| 192 | 162 | ||
| 193 | /// Gets the priority for the specified thread | 163 | /// Gets the priority for the specified thread |