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;
|
i387_fxsave_t fxsave;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline void save_fpu_state(union fpu_state* state) {
|
typedef void (*handle_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");
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void restore_fpu_state(union fpu_state* state) {
|
extern handle_fpu_state save_fpu_state;
|
||||||
if (has_fxsr())
|
extern handle_fpu_state restore_fpu_state;
|
||||||
asm volatile ("fxrstor %0" :: "m"(state->fxsave));
|
extern handle_fpu_state fpu_init;
|
||||||
else
|
|
||||||
asm volatile ("frstor %0" :: "m"(state->fsave));
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,13 +27,13 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <metalsvm/stdio.h>
|
#include <metalsvm/stdio.h>
|
||||||
#include <metalsvm/string.h>
|
|
||||||
#include <metalsvm/tasks.h>
|
#include <metalsvm/tasks.h>
|
||||||
#include <asm/irqflags.h>
|
#include <asm/irqflags.h>
|
||||||
#include <asm/isrs.h>
|
#include <asm/isrs.h>
|
||||||
#include <asm/irq.h>
|
#include <asm/irq.h>
|
||||||
#include <asm/apic.h>
|
#include <asm/apic.h>
|
||||||
#include <asm/idt.h>
|
#include <asm/idt.h>
|
||||||
|
#include <asm/io.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* These are function prototypes for all of the exception
|
* These are function prototypes for all of the exception
|
||||||
|
@ -165,27 +165,6 @@ void isrs_install(void)
|
||||||
irq_install_handler(7, fpu_handler);
|
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)
|
static void fpu_handler(struct state *s)
|
||||||
{
|
{
|
||||||
task_t* task = per_core(current_task);
|
task_t* task = per_core(current_task);
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
#include <metalsvm/stddef.h>
|
#include <metalsvm/stddef.h>
|
||||||
#include <metalsvm/stdio.h>
|
#include <metalsvm/stdio.h>
|
||||||
|
#include <metalsvm/string.h>
|
||||||
#include <metalsvm/time.h>
|
#include <metalsvm/time.h>
|
||||||
#include <metalsvm/processor.h>
|
#include <metalsvm/processor.h>
|
||||||
#include <metalsvm/tasks.h>
|
#include <metalsvm/tasks.h>
|
||||||
|
@ -26,16 +27,64 @@
|
||||||
#include <asm/RCCE_lib.h>
|
#include <asm/RCCE_lib.h>
|
||||||
#endif
|
#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 mb = default_mb;
|
||||||
func_memory_barrier rmb = default_mb;
|
func_memory_barrier rmb = default_mb;
|
||||||
func_memory_barrier wmb = 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 mfence(void) { asm volatile("mfence" ::: "memory"); }
|
||||||
static void lfence(void) { asm volatile("lfence" ::: "memory"); }
|
static void lfence(void) { asm volatile("lfence" ::: "memory"); }
|
||||||
static void sfence(void) { asm volatile("sfence" ::: "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 };
|
cpu_info_t cpu_info = { 0, 0 };
|
||||||
static uint32_t cpu_freq = 0;
|
static uint32_t cpu_freq = 0;
|
||||||
|
|
||||||
|
@ -72,6 +121,12 @@ int cpu_detection(void)
|
||||||
asm volatile ("fninit");
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue