forked from Bananymous/banan-os
Kernel: store/load sse/mmx/fpu state on isr/irq/syscall
I haven't tested this yet but should be fine. This will be optimized to only save state from threads that are using it
This commit is contained in:
parent
e86e755c51
commit
8b1bccb79b
|
@ -138,6 +138,8 @@ namespace IDT
|
||||||
|
|
||||||
extern "C" void cpp_isr_handler(uint64_t isr, uint64_t error, Kernel::InterruptStack& interrupt_stack, const Registers* regs)
|
extern "C" void cpp_isr_handler(uint64_t isr, uint64_t error, Kernel::InterruptStack& interrupt_stack, const Registers* regs)
|
||||||
{
|
{
|
||||||
|
Kernel::Thread::current().save_sse();
|
||||||
|
|
||||||
pid_t tid = Kernel::Scheduler::current_tid();
|
pid_t tid = Kernel::Scheduler::current_tid();
|
||||||
pid_t pid = tid ? Kernel::Process::current().pid() : 0;
|
pid_t pid = tid ? Kernel::Process::current().pid() : 0;
|
||||||
|
|
||||||
|
@ -205,10 +207,14 @@ namespace IDT
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Kernel::Thread::current().load_sse();
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void cpp_irq_handler(uint64_t irq, Kernel::InterruptStack& interrupt_stack)
|
extern "C" void cpp_irq_handler(uint64_t irq, Kernel::InterruptStack& interrupt_stack)
|
||||||
{
|
{
|
||||||
|
Kernel::Thread::current().save_sse();
|
||||||
|
|
||||||
if (Kernel::Scheduler::current_tid())
|
if (Kernel::Scheduler::current_tid())
|
||||||
{
|
{
|
||||||
Kernel::Thread::current().set_return_rsp(interrupt_stack.rsp);
|
Kernel::Thread::current().set_return_rsp(interrupt_stack.rsp);
|
||||||
|
@ -242,6 +248,8 @@ namespace IDT
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Kernel::Thread::current().load_sse();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void flush_idt()
|
static void flush_idt()
|
||||||
|
|
|
@ -82,6 +82,9 @@ namespace Kernel
|
||||||
|
|
||||||
bool is_userspace() const { return m_is_userspace; }
|
bool is_userspace() const { return m_is_userspace; }
|
||||||
|
|
||||||
|
void save_sse() { asm volatile("fxsave %0" :: "m"(m_sse_storage)); }
|
||||||
|
void load_sse() { asm volatile("fxrstor %0" :: "m"(m_sse_storage)); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Thread(pid_t tid, Process*);
|
Thread(pid_t tid, Process*);
|
||||||
void on_exit();
|
void on_exit();
|
||||||
|
@ -111,6 +114,8 @@ namespace Kernel
|
||||||
|
|
||||||
uint64_t m_terminate_blockers { 0 };
|
uint64_t m_terminate_blockers { 0 };
|
||||||
|
|
||||||
|
alignas(16) uint8_t m_sse_storage[512];
|
||||||
|
|
||||||
friend class TerminateBlocker;
|
friend class TerminateBlocker;
|
||||||
friend class Scheduler;
|
friend class Scheduler;
|
||||||
};
|
};
|
||||||
|
|
|
@ -30,6 +30,8 @@ namespace Kernel
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Thread::current().save_sse();
|
||||||
|
|
||||||
asm volatile("sti");
|
asm volatile("sti");
|
||||||
|
|
||||||
(void)arg1;
|
(void)arg1;
|
||||||
|
@ -183,6 +185,8 @@ namespace Kernel
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Thread::current().load_sse();
|
||||||
|
|
||||||
if (ret.is_error())
|
if (ret.is_error())
|
||||||
return -ret.error().get_error_code();
|
return -ret.error().get_error_code();
|
||||||
return ret.value();
|
return ret.value();
|
||||||
|
|
Loading…
Reference in New Issue