kernel: clone fpu status on CreateThread
This commit is contained in:
parent
a7792e5ff8
commit
484641003c
|
@ -49,6 +49,7 @@ static void ResetThreadContext32(Core::ARM_Interface::ThreadContext32& context,
|
||||||
context.cpu_registers[0] = arg;
|
context.cpu_registers[0] = arg;
|
||||||
context.cpu_registers[15] = entry_point;
|
context.cpu_registers[15] = entry_point;
|
||||||
context.cpu_registers[13] = stack_top;
|
context.cpu_registers[13] = stack_top;
|
||||||
|
context.fpscr = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ResetThreadContext64(Core::ARM_Interface::ThreadContext64& context, VAddr stack_top,
|
static void ResetThreadContext64(Core::ARM_Interface::ThreadContext64& context, VAddr stack_top,
|
||||||
|
@ -58,8 +59,8 @@ static void ResetThreadContext64(Core::ARM_Interface::ThreadContext64& context,
|
||||||
context.cpu_registers[18] = Kernel::KSystemControl::GenerateRandomU64() | 1;
|
context.cpu_registers[18] = Kernel::KSystemControl::GenerateRandomU64() | 1;
|
||||||
context.pc = entry_point;
|
context.pc = entry_point;
|
||||||
context.sp = stack_top;
|
context.sp = stack_top;
|
||||||
// TODO(merry): Perform a hardware test to determine the below value.
|
|
||||||
context.fpcr = 0;
|
context.fpcr = 0;
|
||||||
|
context.fpsr = 0;
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
@ -815,6 +816,27 @@ void KThread::Continue() {
|
||||||
KScheduler::OnThreadStateChanged(kernel, this, old_state);
|
KScheduler::OnThreadStateChanged(kernel, this, old_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void KThread::CloneFpuStatus() {
|
||||||
|
// We shouldn't reach here when starting kernel threads.
|
||||||
|
ASSERT(this->GetOwnerProcess() != nullptr);
|
||||||
|
ASSERT(this->GetOwnerProcess() == GetCurrentProcessPointer(kernel));
|
||||||
|
|
||||||
|
if (this->GetOwnerProcess()->Is64BitProcess()) {
|
||||||
|
// Clone FPSR and FPCR.
|
||||||
|
ThreadContext64 cur_ctx{};
|
||||||
|
kernel.System().CurrentArmInterface().SaveContext(cur_ctx);
|
||||||
|
|
||||||
|
this->GetContext64().fpcr = cur_ctx.fpcr;
|
||||||
|
this->GetContext64().fpsr = cur_ctx.fpsr;
|
||||||
|
} else {
|
||||||
|
// Clone FPSCR.
|
||||||
|
ThreadContext32 cur_ctx{};
|
||||||
|
kernel.System().CurrentArmInterface().SaveContext(cur_ctx);
|
||||||
|
|
||||||
|
this->GetContext32().fpscr = cur_ctx.fpscr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Result KThread::SetActivity(Svc::ThreadActivity activity) {
|
Result KThread::SetActivity(Svc::ThreadActivity activity) {
|
||||||
// Lock ourselves.
|
// Lock ourselves.
|
||||||
KScopedLightLock lk(activity_pause_lock);
|
KScopedLightLock lk(activity_pause_lock);
|
||||||
|
|
|
@ -254,6 +254,8 @@ public:
|
||||||
thread_context_32.tpidr = static_cast<u32>(value);
|
thread_context_32.tpidr = static_cast<u32>(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CloneFpuStatus();
|
||||||
|
|
||||||
[[nodiscard]] ThreadContext32& GetContext32() {
|
[[nodiscard]] ThreadContext32& GetContext32() {
|
||||||
return thread_context_32;
|
return thread_context_32;
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,6 +82,9 @@ Result CreateThread(Core::System& system, Handle* out_handle, VAddr entry_point,
|
||||||
// Commit the thread reservation.
|
// Commit the thread reservation.
|
||||||
thread_reservation.Commit();
|
thread_reservation.Commit();
|
||||||
|
|
||||||
|
// Clone the current fpu status to the new thread.
|
||||||
|
thread->CloneFpuStatus();
|
||||||
|
|
||||||
// Register the new thread.
|
// Register the new thread.
|
||||||
KThread::Register(kernel, thread);
|
KThread::Register(kernel, thread);
|
||||||
|
|
||||||
|
|
Reference in New Issue