//kernel/trunk/arch/ia32/include/interrupt.h |
---|
84,6 → 84,7 |
extern void gp_fault(int n, istate_t *istate); |
extern void nm_fault(int n, istate_t *istate); |
extern void ss_fault(int n, istate_t *istate); |
extern void simd_fp_exception(int n, istate_t *istate); |
extern void page_fault(int n, istate_t *istate); |
extern void syscall(int n, istate_t *istate); |
extern void tlb_shootdown_ipi(int n, istate_t *istate); |
//kernel/trunk/arch/ia32/include/fpu_context.h |
---|
34,6 → 34,10 |
#define ARCH_HAS_FPU |
#define FPU_CONTEXT_ALIGN 16 |
void fpu_fxsr(void); |
void fpu_fsr(void); |
struct fpu_context { |
/* TODO: We need malloc that aligns structures on 16-byte boundary */ |
__u8 fpu[512]; /* FXSAVE & FXRSTOR storage area */ |
//kernel/trunk/arch/ia32/include/cpuid.h |
---|
38,6 → 38,34 |
__u32 cpuid_edx; |
} __attribute__ ((packed)); |
struct __cpuid_extended_feature_info { |
unsigned sse3 : 1; |
unsigned : 31; |
} __attribute__ ((packed)); |
typedef union cpuid_extended_feature_info |
{ |
struct __cpuid_extended_feature_info bits; |
__u32 word; |
}cpuid_extended_feature_info; |
struct __cpuid_feature_info { |
unsigned : 23; |
unsigned mmx : 1; |
unsigned fxsr : 1; |
unsigned sse : 1; |
unsigned sse2 : 1; |
unsigned : 5; |
} __attribute__ ((packed)); |
typedef union cpuid_feature_info |
{ |
struct __cpuid_feature_info bits; |
__u32 word ; |
}cpuid_feature_info; |
static inline __u32 has_cpuid(void) |
{ |
__u32 val, ret; |
//kernel/trunk/arch/ia32/include/cpu.h |
---|
41,4 → 41,7 |
struct tss *tss; |
}; |
#define CR4_OSFXSR_MASK (1<<9) |
#endif |
//kernel/trunk/arch/ia32/src/fpu_context.c |
---|
31,7 → 31,13 |
#include <arch.h> |
#include <cpu.h> |
void fpu_context_save(fpu_context_t *fctx) |
typedef void (*fpu_context_function)(fpu_context_t *fctx); |
static fpu_context_function fpu_save,fpu_restore; |
static void fpu_context_f_save(fpu_context_t *fctx) |
{ |
__asm__ volatile ( |
"fnsave %0" |
39,8 → 45,7 |
); |
} |
void fpu_context_restore(fpu_context_t *fctx) |
static void fpu_context_f_restore(fpu_context_t *fctx) |
{ |
__asm__ volatile ( |
"frstor %0" |
48,9 → 53,64 |
); |
} |
static void fpu_context_fx_save(fpu_context_t *fctx) |
{ |
__asm__ volatile ( |
"fxsave %0" |
: "=m"(*fctx) |
); |
} |
static void fpu_context_fx_restore(fpu_context_t *fctx) |
{ |
__asm__ volatile ( |
"fxrstor %0" |
: "=m"(*fctx) |
); |
} |
/* |
Setup using fxsr instruction |
*/ |
void fpu_fxsr(void) |
{ |
fpu_save=fpu_context_fx_save; |
fpu_restore=fpu_context_fx_restore; |
} |
/* |
Setup using not fxsr instruction |
*/ |
void fpu_fsr(void) |
{ |
fpu_save=fpu_context_f_save; |
fpu_restore=fpu_context_f_restore; |
} |
void fpu_context_save(fpu_context_t *fctx) |
{ |
fpu_save(fctx); |
} |
void fpu_context_restore(fpu_context_t *fctx) |
{ |
fpu_restore(fctx); |
} |
void fpu_init() |
{ |
__u32 help0=0,help1=0; |
__asm__ volatile ( |
"fninit;" |
"fninit;\n" |
"stmxcsr %0\n" |
"mov %0,%1;\n" |
"or %2,%1;\n" |
"mov %1,%0;\n" |
"ldmxcsr %0;\n" |
:"+m"(help0),"+r"(help1) |
:"i"(0x1f80) |
); |
} |
//kernel/trunk/arch/ia32/src/cpu/cpu.c |
---|
92,8 → 92,31 |
void cpu_arch_init(void) |
{ |
__u32 help=0; |
CPU->arch.tss = tss_p; |
CPU->fpu_owner=NULL; |
cpuid_feature_info fi; |
cpuid_extended_feature_info efi; |
cpu_info_t info; |
cpuid(1, &info); |
fi.word=info.cpuid_edx; |
efi.word=info.cpuid_ecx; |
if(fi.bits.fxsr) fpu_fxsr(); |
else fpu_fsr(); |
if(fi.bits.sse) asm volatile ( |
"mov %%cr4,%0;\n" |
"or %1,%0;\n" |
"mov %0,%%cr4;\n" |
:"+r"(help) |
:"i"(CR4_OSFXSR_MASK|(1<<10)) |
); |
} |
//kernel/trunk/arch/ia32/src/pm.c |
---|
130,6 → 130,7 |
exc_register(13, "gp_fault", (iroutine) gp_fault); |
exc_register( 7, "nm_fault", (iroutine) nm_fault); |
exc_register(12, "ss_fault", (iroutine) ss_fault); |
exc_register(19, "simd_fp", (iroutine) simd_fp_exception); |
} |
//kernel/trunk/arch/ia32/src/interrupt.c |
---|
88,6 → 88,20 |
panic("stack fault\n"); |
} |
void simd_fp_exception(int n, istate_t *istate) |
{ |
PRINT_INFO_ERRCODE(istate); |
__u32 mxcsr; |
asm |
( |
"stmxcsr %0;\n" |
:"=m"(mxcsr) |
); |
printf("MXCSR: %X\n",(__native)(mxcsr)); |
panic("SIMD FP exception(19)\n"); |
} |
void nm_fault(int n, istate_t *istate) |
{ |
#ifdef CONFIG_FPU_LAZY |