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 pic_eoi(Registers* regs);
|
||||||
extern void setup_idt();
|
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
|
// Interrupt handling
|
||||||
|
|
||||||
#define FIXME_UNHANDLED_INTERRUPT(name) \
|
#define FIXME_UNHANDLED_INTERRUPT(name) \
|
||||||
|
@ -9,6 +9,16 @@ struct Registers // Saved CPU registers for x86-64
|
|||||||
u64 rip, cs, rflags, rsp, ss;
|
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
|
struct [[gnu::packed]] TSS
|
||||||
{
|
{
|
||||||
u32 reserved0;
|
u32 reserved0;
|
||||||
|
@ -219,10 +219,12 @@ namespace Scheduler
|
|||||||
if (old_thread != new_thread)
|
if (old_thread != new_thread)
|
||||||
{
|
{
|
||||||
switch_context(old_thread, new_thread, regs);
|
switch_context(old_thread, new_thread, regs);
|
||||||
|
if (!old_thread->is_kernel) old_thread->fp_data.save();
|
||||||
if (!new_thread->is_kernel)
|
if (!new_thread->is_kernel)
|
||||||
{
|
{
|
||||||
MMU::switch_page_directory(new_thread->directory);
|
MMU::switch_page_directory(new_thread->directory);
|
||||||
CPU::switch_kernel_stack(new_thread->kernel_stack.top());
|
CPU::switch_kernel_stack(new_thread->kernel_stack.top());
|
||||||
|
new_thread->fp_data.restore();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,8 +21,6 @@ enum class ThreadState
|
|||||||
Dying
|
Dying
|
||||||
};
|
};
|
||||||
|
|
||||||
// FIXME: Save floating point state. (SSE registers on x86_64 using FXSAVE and FXRSTOR)
|
|
||||||
|
|
||||||
struct Thread : public LinkedListNode<Thread>
|
struct Thread : public LinkedListNode<Thread>
|
||||||
{
|
{
|
||||||
Registers regs;
|
Registers regs;
|
||||||
@ -41,6 +39,8 @@ struct Thread : public LinkedListNode<Thread>
|
|||||||
|
|
||||||
OwnedPtr<UserVM> vm_allocator;
|
OwnedPtr<UserVM> vm_allocator;
|
||||||
|
|
||||||
|
FPData fp_data;
|
||||||
|
|
||||||
ThreadState state = ThreadState::Runnable;
|
ThreadState state = ThreadState::Runnable;
|
||||||
|
|
||||||
bool is_kernel { true };
|
bool is_kernel { true };
|
||||||
|
Loading…
Reference in New Issue
Block a user