diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/hle/kernel/k_thread.cpp | 24 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_thread.h | 2 | ||||
| -rw-r--r-- | src/core/hle/kernel/svc/svc_thread.cpp | 3 |
3 files changed, 28 insertions, 1 deletions
diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp index 8c403f5fd..15ae652f9 100644 --- a/src/core/hle/kernel/k_thread.cpp +++ b/src/core/hle/kernel/k_thread.cpp | |||
| @@ -49,6 +49,7 @@ static void ResetThreadContext32(Core::ARM_Interface::ThreadContext32& context, | |||
| 49 | context.cpu_registers[0] = arg; | 49 | context.cpu_registers[0] = arg; |
| 50 | context.cpu_registers[15] = entry_point; | 50 | context.cpu_registers[15] = entry_point; |
| 51 | context.cpu_registers[13] = stack_top; | 51 | context.cpu_registers[13] = stack_top; |
| 52 | context.fpscr = 0; | ||
| 52 | } | 53 | } |
| 53 | 54 | ||
| 54 | static void ResetThreadContext64(Core::ARM_Interface::ThreadContext64& context, VAddr stack_top, | 55 | static void ResetThreadContext64(Core::ARM_Interface::ThreadContext64& context, VAddr stack_top, |
| @@ -58,8 +59,8 @@ static void ResetThreadContext64(Core::ARM_Interface::ThreadContext64& context, | |||
| 58 | context.cpu_registers[18] = Kernel::KSystemControl::GenerateRandomU64() | 1; | 59 | context.cpu_registers[18] = Kernel::KSystemControl::GenerateRandomU64() | 1; |
| 59 | context.pc = entry_point; | 60 | context.pc = entry_point; |
| 60 | context.sp = stack_top; | 61 | context.sp = stack_top; |
| 61 | // TODO(merry): Perform a hardware test to determine the below value. | ||
| 62 | context.fpcr = 0; | 62 | context.fpcr = 0; |
| 63 | context.fpsr = 0; | ||
| 63 | } | 64 | } |
| 64 | } // namespace | 65 | } // namespace |
| 65 | 66 | ||
| @@ -815,6 +816,27 @@ void KThread::Continue() { | |||
| 815 | KScheduler::OnThreadStateChanged(kernel, this, old_state); | 816 | KScheduler::OnThreadStateChanged(kernel, this, old_state); |
| 816 | } | 817 | } |
| 817 | 818 | ||
| 819 | void KThread::CloneFpuStatus() { | ||
| 820 | // We shouldn't reach here when starting kernel threads. | ||
| 821 | ASSERT(this->GetOwnerProcess() != nullptr); | ||
| 822 | ASSERT(this->GetOwnerProcess() == GetCurrentProcessPointer(kernel)); | ||
| 823 | |||
| 824 | if (this->GetOwnerProcess()->Is64BitProcess()) { | ||
| 825 | // Clone FPSR and FPCR. | ||
| 826 | ThreadContext64 cur_ctx{}; | ||
| 827 | kernel.System().CurrentArmInterface().SaveContext(cur_ctx); | ||
| 828 | |||
| 829 | this->GetContext64().fpcr = cur_ctx.fpcr; | ||
| 830 | this->GetContext64().fpsr = cur_ctx.fpsr; | ||
| 831 | } else { | ||
| 832 | // Clone FPSCR. | ||
| 833 | ThreadContext32 cur_ctx{}; | ||
| 834 | kernel.System().CurrentArmInterface().SaveContext(cur_ctx); | ||
| 835 | |||
| 836 | this->GetContext32().fpscr = cur_ctx.fpscr; | ||
| 837 | } | ||
| 838 | } | ||
| 839 | |||
| 818 | Result KThread::SetActivity(Svc::ThreadActivity activity) { | 840 | Result KThread::SetActivity(Svc::ThreadActivity activity) { |
| 819 | // Lock ourselves. | 841 | // Lock ourselves. |
| 820 | KScopedLightLock lk(activity_pause_lock); | 842 | KScopedLightLock lk(activity_pause_lock); |
diff --git a/src/core/hle/kernel/k_thread.h b/src/core/hle/kernel/k_thread.h index bd125f5f1..9423f08ca 100644 --- a/src/core/hle/kernel/k_thread.h +++ b/src/core/hle/kernel/k_thread.h | |||
| @@ -254,6 +254,8 @@ public: | |||
| 254 | thread_context_32.tpidr = static_cast<u32>(value); | 254 | thread_context_32.tpidr = static_cast<u32>(value); |
| 255 | } | 255 | } |
| 256 | 256 | ||
| 257 | void CloneFpuStatus(); | ||
| 258 | |||
| 257 | [[nodiscard]] ThreadContext32& GetContext32() { | 259 | [[nodiscard]] ThreadContext32& GetContext32() { |
| 258 | return thread_context_32; | 260 | return thread_context_32; |
| 259 | } | 261 | } |
diff --git a/src/core/hle/kernel/svc/svc_thread.cpp b/src/core/hle/kernel/svc/svc_thread.cpp index b39807841..9bc1ebe74 100644 --- a/src/core/hle/kernel/svc/svc_thread.cpp +++ b/src/core/hle/kernel/svc/svc_thread.cpp | |||
| @@ -82,6 +82,9 @@ Result CreateThread(Core::System& system, Handle* out_handle, VAddr entry_point, | |||
| 82 | // Commit the thread reservation. | 82 | // Commit the thread reservation. |
| 83 | thread_reservation.Commit(); | 83 | thread_reservation.Commit(); |
| 84 | 84 | ||
| 85 | // Clone the current fpu status to the new thread. | ||
| 86 | thread->CloneFpuStatus(); | ||
| 87 | |||
| 85 | // Register the new thread. | 88 | // Register the new thread. |
| 86 | KThread::Register(kernel, thread); | 89 | KThread::Register(kernel, thread); |
| 87 | 90 | ||