some code cleanups
=> simplify the handling of FPU exceptions
This commit is contained in:
parent
dadc4ce7ed
commit
09ec6dcc3a
3 changed files with 61 additions and 35 deletions
|
@ -65,19 +65,11 @@ union fpu_state {
|
|||
i387_fxsave_t fxsave;
|
||||
};
|
||||
|
||||
static inline void save_fpu_state(union fpu_state* state) {
|
||||
if (has_fxsr())
|
||||
asm volatile ("fxsave %0; fnclex" : "=m"((*state).fxsave) :: "memory");
|
||||
else
|
||||
asm volatile ("fnsave %0; fwait" : "=m"((*state).fsave) :: "memory");
|
||||
}
|
||||
typedef void (*handle_fpu_state)(union fpu_state* state);
|
||||
|
||||
static inline void restore_fpu_state(union fpu_state* state) {
|
||||
if (has_fxsr())
|
||||
asm volatile ("fxrstor %0" :: "m"(state->fxsave));
|
||||
else
|
||||
asm volatile ("frstor %0" :: "m"(state->fsave));
|
||||
}
|
||||
extern handle_fpu_state save_fpu_state;
|
||||
extern handle_fpu_state restore_fpu_state;
|
||||
extern handle_fpu_state fpu_init;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -27,13 +27,13 @@
|
|||
*/
|
||||
|
||||
#include <metalsvm/stdio.h>
|
||||
#include <metalsvm/string.h>
|
||||
#include <metalsvm/tasks.h>
|
||||
#include <asm/irqflags.h>
|
||||
#include <asm/isrs.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/apic.h>
|
||||
#include <asm/idt.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
/*
|
||||
* These are function prototypes for all of the exception
|
||||
|
@ -165,27 +165,6 @@ void isrs_install(void)
|
|||
irq_install_handler(7, fpu_handler);
|
||||
}
|
||||
|
||||
static void fpu_init(union fpu_state* fpu)
|
||||
{
|
||||
if (has_fxsr()) {
|
||||
i387_fxsave_t* fx = &fpu->fxsave;
|
||||
|
||||
memset(fx, 0x00, sizeof(i387_fxsave_t));
|
||||
fx->cwd = 0x37f;
|
||||
if (has_sse())
|
||||
fx->mxcsr = 0x1f80;
|
||||
} else {
|
||||
i387_fsave_t *fp = &fpu->fsave;
|
||||
|
||||
memset(fp, 0x00, sizeof(i387_fsave_t));
|
||||
fp->cwd = 0xffff037fu;
|
||||
fp->swd = 0xffff0000u;
|
||||
fp->twd = 0xffffffffu;
|
||||
fp->fos = 0xffff0000u;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void fpu_handler(struct state *s)
|
||||
{
|
||||
task_t* task = per_core(current_task);
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include <metalsvm/stddef.h>
|
||||
#include <metalsvm/stdio.h>
|
||||
#include <metalsvm/string.h>
|
||||
#include <metalsvm/time.h>
|
||||
#include <metalsvm/processor.h>
|
||||
#include <metalsvm/tasks.h>
|
||||
|
@ -26,16 +27,64 @@
|
|||
#include <asm/RCCE_lib.h>
|
||||
#endif
|
||||
|
||||
static void default_mb(void) { asm volatile ("lock; addl $0,0(%%esp)" ::: "memory", "cc"); }
|
||||
static void default_mb(void)
|
||||
{
|
||||
asm volatile ("lock; addl $0,0(%%esp)" ::: "memory", "cc");
|
||||
}
|
||||
|
||||
static void default_save_fpu_state(union fpu_state* state)
|
||||
{
|
||||
asm volatile ("fnsave %0; fwait" : "=m"((*state).fsave) :: "memory");
|
||||
}
|
||||
|
||||
static void default_restore_fpu_state(union fpu_state* state)
|
||||
{
|
||||
asm volatile ("frstor %0" :: "m"(state->fsave));
|
||||
}
|
||||
|
||||
static void default_fpu_init(union fpu_state* fpu)
|
||||
{
|
||||
i387_fsave_t *fp = &fpu->fsave;
|
||||
|
||||
memset(fp, 0x00, sizeof(i387_fsave_t));
|
||||
fp->cwd = 0xffff037fu;
|
||||
fp->swd = 0xffff0000u;
|
||||
fp->twd = 0xffffffffu;
|
||||
fp->fos = 0xffff0000u;
|
||||
}
|
||||
|
||||
|
||||
func_memory_barrier mb = default_mb;
|
||||
func_memory_barrier rmb = default_mb;
|
||||
func_memory_barrier wmb = default_mb;
|
||||
handle_fpu_state save_fpu_state = default_save_fpu_state;
|
||||
handle_fpu_state restore_fpu_state = default_restore_fpu_state;
|
||||
handle_fpu_state fpu_init = default_fpu_init;
|
||||
|
||||
static void mfence(void) { asm volatile("mfence" ::: "memory"); }
|
||||
static void lfence(void) { asm volatile("lfence" ::: "memory"); }
|
||||
static void sfence(void) { asm volatile("sfence" ::: "memory"); }
|
||||
|
||||
static void save_fpu_state_fxsr(union fpu_state* state)
|
||||
{
|
||||
asm volatile ("fxsave %0; fnclex" : "=m"((*state).fxsave) :: "memory");
|
||||
}
|
||||
|
||||
static void restore_fpu_state_fxsr(union fpu_state* state)
|
||||
{
|
||||
asm volatile ("fxrstor %0" :: "m"(state->fxsave));
|
||||
}
|
||||
|
||||
static void fpu_init_fxsr(union fpu_state* fpu)
|
||||
{
|
||||
i387_fxsave_t* fx = &fpu->fxsave;
|
||||
|
||||
memset(fx, 0x00, sizeof(i387_fxsave_t));
|
||||
fx->cwd = 0x37f;
|
||||
if (BUILTIN_EXPECT(has_sse(), 1))
|
||||
fx->mxcsr = 0x1f80;
|
||||
}
|
||||
|
||||
cpu_info_t cpu_info = { 0, 0 };
|
||||
static uint32_t cpu_freq = 0;
|
||||
|
||||
|
@ -72,6 +121,12 @@ int cpu_detection(void)
|
|||
asm volatile ("fninit");
|
||||
}
|
||||
|
||||
if (has_fxsr()) {
|
||||
save_fpu_state = save_fpu_state_fxsr;
|
||||
restore_fpu_state = restore_fpu_state_fxsr;
|
||||
fpu_init = fpu_init_fxsr;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue