Shrink cpu.c and render it useful for our purposes.
[people/andreif/gpxe.git] / src / arch / i386 / core / cpu.c
index cbef6a1..c24fa4e 100644 (file)
@@ -1,88 +1,73 @@
-#ifdef CONFIG_X86_64
-#include "stdint.h"
-#include "string.h"
-#include "bits/cpu.h"
-#include <gpxe/init.h>
+#include <stdint.h>
+#include <string.h>
+#include <cpu.h>
 
+/** @file
+ *
+ * CPU identification
+ *
+ */
 
-/* Standard macro to see if a specific flag is changeable */
-static inline int flag_is_changeable_p(uint32_t flag)
-{
+/**
+ * Test to see if CPU flag is changeable
+ *
+ * @v flag             Flag to test
+ * @ret can_change     Flag is changeable
+ */
+static inline int flag_is_changeable ( unsigned int flag ) {
        uint32_t f1, f2;
 
-       asm("pushfl\n\t"
-           "pushfl\n\t"
-           "popl %0\n\t"
-           "movl %0,%1\n\t"
-           "xorl %2,%0\n\t"
-           "pushl %0\n\t"
-           "popfl\n\t"
-           "pushfl\n\t"
-           "popl %0\n\t"
-           "popfl\n\t"
-           : "=&r" (f1), "=&r" (f2)
-           : "ir" (flag));
+       __asm__ ( "pushfl\n\t"
+                 "pushfl\n\t"
+                 "popl %0\n\t"
+                 "movl %0,%1\n\t"
+                 "xorl %2,%0\n\t"
+                 "pushl %0\n\t"
+                 "popfl\n\t"
+                 "pushfl\n\t"
+                 "popl %0\n\t"
+                 "popfl\n\t"
+                 : "=&r" ( f1 ), "=&r" ( f2 )
+                 : "ir" ( flag ) );
 
-       return ((f1^f2) & flag) != 0;
+       return ( ( ( f1 ^ f2 ) & flag ) != 0 );
 }
 
+/**
+ * Get CPU information
+ *
+ * @v cpu              CPU information structure to fill in
+ */
+void get_cpuinfo ( struct cpuinfo_x86 *cpu ) {
+       unsigned int cpuid_level;
+       unsigned int cpuid_extlevel;
+       unsigned int discard_1, discard_2, discard_3;
 
-/* Probe for the CPUID instruction */
-static inline int have_cpuid_p(void)
-{
-       return flag_is_changeable_p(X86_EFLAGS_ID);
-}
-
-static void identify_cpu(struct cpuinfo_x86 *c)
-{
-       unsigned xlvl;
-
-       c->cpuid_level = -1;            /* CPUID not detected */
-       c->x86_model = c->x86_mask = 0; /* So far unknown... */
-       c->x86_vendor_id[0] = '\0';     /* Unset */
-       memset(&c->x86_capability, 0, sizeof c->x86_capability);
-       
-       if (!have_cpuid_p()) {
-               /* CPU doesn'thave CPUID */
+       memset ( cpu, 0, sizeof ( *cpu ) );
 
-               /* If there are any capabilities, they'r vendor-specific */
-               /* enable_cpuid() would have set c->x86 for us. */
+       /* Check for CPUID instruction */
+       if ( ! flag_is_changeable ( X86_EFLAGS_ID ) ) {
+               DBG ( "CPUID not supported\n" );
+               return;
        }
-       else {
-               /* CPU does have CPUID */
 
-               /* Get vendor name */
-               cpuid(0x00000000, &c->cpuid_level,
-                     (int *)&c->x86_vendor_id[0],
-                     (int *)&c->x86_vendor_id[8],
-                     (int *)&c->x86_vendor_id[4]);
-               
-               /* Initialize the standard set of capabilities */
-               /* Note that the vendor-specific code below might override */
-
-               /* Intel-defined flags: level 0x00000001 */
-               if ( c->cpuid_level >= 0x00000001 ) {
-                       unsigned tfms, junk;
-                       cpuid(0x00000001, &tfms, &junk, &junk,
-                             &c->x86_capability[0]);
-                       c->x86 = (tfms >> 8) & 15;
-                       c->x86_model = (tfms >> 4) & 15;
-                       c->x86_mask = tfms & 15;
-               }
+       /* Get features, if present */
+       cpuid ( 0x00000000, &cpuid_level, &discard_1,
+               &discard_2, &discard_3 );
+       if ( cpuid_level >= 0x00000001 ) {
+               cpuid ( 0x00000001, &discard_1, &discard_2,
+                       &discard_3, &cpu->features );
+       } else {
+               DBG ( "CPUID cannot return capabilities\n" );
+       }
 
-               /* AMD-defined flags: level 0x80000001 */
-               xlvl = cpuid_eax(0x80000000);
-               if ( (xlvl & 0xffff0000) == 0x80000000 ) {
-                       if ( xlvl >= 0x80000001 )
-                               c->x86_capability[1] = cpuid_edx(0x80000001);
+       /* Get 64-bit features, if present */
+       cpuid ( 0x80000000, &cpuid_extlevel, &discard_1,
+               &discard_2, &discard_3 );
+       if ( ( cpuid_extlevel & 0xffff0000 ) == 0x80000000 ) {
+               if ( cpuid_extlevel >= 0x80000001 ) {
+                       cpuid ( 0x80000001, &discard_1, &discard_2,
+                               &discard_3, &cpu->amd_features );
                }
        }
 }
-
-struct cpuinfo_x86 cpu_info;
-void cpu_setup(void)
-{
-       identify_cpu(&cpu_info);
-}
-
-#endif /* CONFIG_X86_64 */