x86: initialize XMM registers along with x87
authorBarret Rhoden <brho@cs.berkeley.edu>
Fri, 19 Apr 2013 18:30:27 +0000 (11:30 -0700)
committerBarret Rhoden <brho@cs.berkeley.edu>
Wed, 24 Apr 2013 22:19:09 +0000 (15:19 -0700)
In the future (or in RISCV), someone might have an init_fp_state() that
is super-efficient.  If it turns out that manually zeroing the XMM
registers is faster, then we can change the code.  I haven't
microbenchmarked the new way or compared it to 0'ing the 15 XMM
registers + loading the MXCSR yet.

kern/arch/i686/init.c
kern/arch/i686/trap.h

index 9bcf67f..a14db9f 100644 (file)
@@ -17,6 +17,8 @@
 #include <arch/init.h>
 #include <console.h>
 
+struct ancillary_state x86_default_fpu;
+
 /* irq handler for the console (kb, serial, etc) */
 static void irq_console(struct hw_trapframe *hw_tf, void *data)
 {
@@ -55,6 +57,7 @@ static void cons_irq_init(void)
 
 void arch_init()
 {
+       save_fp_state(&x86_default_fpu); /* used in arch/trap.h for fpu init */
        pci_init();
 #ifdef __CONFIG_ENABLE_MPTABLES__
        mptables_parse();
index 000139b..b1d179e 100644 (file)
@@ -69,6 +69,9 @@
 extern gatedesc_t idt[];
 extern taskstate_t ts;
 
+/* Defined and set up in in arch/init.c, used for XMM initialization */
+extern struct ancillary_state x86_default_fpu;
+
 /* Determines if the given TF was in the kernel or not. */
 static inline bool in_kernel(struct hw_trapframe *hw_tf)
 {
@@ -87,9 +90,14 @@ static inline void restore_fp_state(struct ancillary_state *silly)
        asm volatile("fxrstor %0" : : "m"(*silly));
 }
 
+/* A regular fninit will only initialize the x87 part of the FPU, not the XMM
+ * registers and the MXCSR state.  So to init, we'll just keep around a copy of
+ * the default FPU state, which we grabbed during boot, and can copy that over
+ * Alternatively, we can fninit, ldmxcsr with the default value, and 0 out the
+ * XMM registers. */
 static inline void init_fp_state(void)
 {
-       asm volatile("fninit");
+       restore_fp_state(&x86_default_fpu);
 }
 
 static inline void __attribute__((always_inline))