x86: Detect XSAVEOPT
authorBarret Rhoden <brho@cs.berkeley.edu>
Mon, 29 Feb 2016 20:49:24 +0000 (15:49 -0500)
committerBarret Rhoden <brho@cs.berkeley.edu>
Mon, 29 Feb 2016 21:59:02 +0000 (16:59 -0500)
This is an  examples of how the kernel can set and query CPU features.  For
the most part, we should do all of the cpu_set_feat() very early during
boot in cpuinfo.

XSAVEOPT implies XSAVE, so we have just CPU_FEAT_X86_XSAVEOPT.

With these changes, both the user and the kernel can check at runtime for
XSAVEOPT and adapt accordingly.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
kern/arch/x86/cpuinfo.c
kern/arch/x86/init.c

index 93efe02..95273e4 100644 (file)
@@ -13,6 +13,7 @@
 #include <pmap.h>
 #include <kdebug.h>
 #include <string.h>
+#include <cpu_feat.h>
 
 /* Check Intel's SDM 2a for Table 3-17 for the cpuid leaves */
 void print_cpuinfo(void)
@@ -165,6 +166,18 @@ void print_cpuinfo(void)
                printk("Always running APIC detected\n");
        else
                printk("Always running APIC *not* detected\n");
+
+       /* TODO: Eventually consolidate all of our "cpuid" stuff. */
+       #define CPUID_XSAVE_SUPPORT         (1 << 26)
+       #define CPUID_XSAVEOPT_SUPPORT      (1 << 0)
+
+       cpuid(0x0d, 0x01, &eax, 0, 0, 0);
+       if (CPUID_XSAVEOPT_SUPPORT & eax) {
+               cpuid(0x01, 0x00, 0, 0, &ecx, 0);
+               /* XSAVEOPT should imply XSAVE */
+               assert(CPUID_XSAVE_SUPPORT & ecx);
+               cpu_set_feat(CPU_FEAT_X86_XSAVEOPT);
+       }
 }
 
 #define BIT_SPACING "        "
index c97794f..6b88995 100644 (file)
@@ -11,6 +11,7 @@
 #include <monitor.h>
 #include <arch/usb.h>
 #include <assert.h>
+#include <cpu_feat.h>
 
 /*
  *     x86_default_xcr0 is the Akaros-wide
@@ -82,31 +83,15 @@ static void cons_irq_init(void)
 }
 
 /* Init x86 processor extended state */
-// TODO/XXX: Eventually consolidate all of our "cpu has" stuff.
-#define CPUID_XSAVE_SUPPORT         (1 << 26)
-#define CPUID_XSAVEOPT_SUPPORT      (1 << 0)
 void ancillary_state_init(void)
 {
        uint32_t eax, ebx, ecx, edx;
        uint64_t proc_supported_features; /* proc supported user state components */
 
-       /* Note: The cpuid function comes from arch/x86.h
-        * arg1 is eax input, arg2 is ecx input, then
-        * pointers to eax, ebx, ecx, edx output values.
-        */
-
-       // First check general XSAVE support. Die if not supported.
-       cpuid(0x01, 0x00, 0, 0, &ecx, 0);
-       if (!(CPUID_XSAVE_SUPPORT & ecx))
-               panic("No XSAVE support! Refusing to boot.\n");
-
-
-       // Next check XSAVEOPT support. Die if not supported.
-       cpuid(0x0d, 0x01, &eax, 0, 0, 0);
-       if (!(CPUID_XSAVEOPT_SUPPORT & eax))
+       /* TODO: switch between XSAVEOPT and pre-XSAVE FP ops */
+       if (!cpu_has_feat(CPU_FEAT_X86_XSAVEOPT))
                panic("No XSAVEOPT support! Refusing to boot.\n");
 
-
        // Next determine the user state components supported
        // by the processor and set x86_default_xcr0.
        cpuid(0x0d, 0x00, &eax, 0, 0, &edx);