kernel: Save floating-point environment when switching in and out of userspace threads
This commit is contained in:
parent
7d045e45c1
commit
ca85a69442
@ -23,6 +23,18 @@ extern void pic_eoi(unsigned char irq);
|
||||
extern void pic_eoi(Registers* regs);
|
||||
extern void setup_idt();
|
||||
|
||||
void FPData::save()
|
||||
{
|
||||
asm volatile("fxsave (%0)" : : "r"(m_data));
|
||||
m_already_saved = true;
|
||||
}
|
||||
|
||||
void FPData::restore()
|
||||
{
|
||||
if(!m_already_saved) return;
|
||||
asm volatile("fxrstor (%0)" : : "r"(m_data));
|
||||
}
|
||||
|
||||
// Interrupt handling
|
||||
|
||||
#define FIXME_UNHANDLED_INTERRUPT(name) \
|
||||
|
@ -9,6 +9,16 @@ struct Registers // Saved CPU registers for x86-64
|
||||
u64 rip, cs, rflags, rsp, ss;
|
||||
};
|
||||
|
||||
struct FPData
|
||||
{
|
||||
void save();
|
||||
void restore();
|
||||
|
||||
private:
|
||||
char m_data[512] alignas(16);
|
||||
bool m_already_saved;
|
||||
};
|
||||
|
||||
struct [[gnu::packed]] TSS
|
||||
{
|
||||
u32 reserved0;
|
||||
|
@ -219,10 +219,12 @@ namespace Scheduler
|
||||
if (old_thread != new_thread)
|
||||
{
|
||||
switch_context(old_thread, new_thread, regs);
|
||||
if (!old_thread->is_kernel) old_thread->fp_data.save();
|
||||
if (!new_thread->is_kernel)
|
||||
{
|
||||
MMU::switch_page_directory(new_thread->directory);
|
||||
CPU::switch_kernel_stack(new_thread->kernel_stack.top());
|
||||
new_thread->fp_data.restore();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -21,8 +21,6 @@ enum class ThreadState
|
||||
Dying
|
||||
};
|
||||
|
||||
// FIXME: Save floating point state. (SSE registers on x86_64 using FXSAVE and FXRSTOR)
|
||||
|
||||
struct Thread : public LinkedListNode<Thread>
|
||||
{
|
||||
Registers regs;
|
||||
@ -41,6 +39,8 @@ struct Thread : public LinkedListNode<Thread>
|
||||
|
||||
OwnedPtr<UserVM> vm_allocator;
|
||||
|
||||
FPData fp_data;
|
||||
|
||||
ThreadState state = ThreadState::Runnable;
|
||||
|
||||
bool is_kernel { true };
|
||||
|
Loading…
Reference in New Issue
Block a user