cpu.c

Go to the documentation of this file.
00001 #include <stdint.h>
00002 #include <string.h>
00003 #include <cpu.h>
00004 
00005 /** @file
00006  *
00007  * CPU identification
00008  *
00009  */
00010 
00011 /**
00012  * Test to see if CPU flag is changeable
00013  *
00014  * @v flag              Flag to test
00015  * @ret can_change      Flag is changeable
00016  */
00017 static inline int flag_is_changeable ( unsigned int flag ) {
00018         uint32_t f1, f2;
00019 
00020         __asm__ ( "pushfl\n\t"
00021                   "pushfl\n\t"
00022                   "popl %0\n\t"
00023                   "movl %0,%1\n\t"
00024                   "xorl %2,%0\n\t"
00025                   "pushl %0\n\t"
00026                   "popfl\n\t"
00027                   "pushfl\n\t"
00028                   "popl %0\n\t"
00029                   "popfl\n\t"
00030                   : "=&r" ( f1 ), "=&r" ( f2 )
00031                   : "ir" ( flag ) );
00032 
00033         return ( ( ( f1 ^ f2 ) & flag ) != 0 );
00034 }
00035 
00036 /**
00037  * Get CPU information
00038  *
00039  * @v cpu               CPU information structure to fill in
00040  */
00041 void get_cpuinfo ( struct cpuinfo_x86 *cpu ) {
00042         unsigned int cpuid_level;
00043         unsigned int cpuid_extlevel;
00044         unsigned int discard_1, discard_2, discard_3;
00045 
00046         memset ( cpu, 0, sizeof ( *cpu ) );
00047 
00048         /* Check for CPUID instruction */
00049         if ( ! flag_is_changeable ( X86_EFLAGS_ID ) ) {
00050                 DBG ( "CPUID not supported\n" );
00051                 return;
00052         }
00053 
00054         /* Get features, if present */
00055         cpuid ( 0x00000000, &cpuid_level, &discard_1,
00056                 &discard_2, &discard_3 );
00057         if ( cpuid_level >= 0x00000001 ) {
00058                 cpuid ( 0x00000001, &discard_1, &discard_2,
00059                         &discard_3, &cpu->features );
00060         } else {
00061                 DBG ( "CPUID cannot return capabilities\n" );
00062         }
00063 
00064         /* Get 64-bit features, if present */
00065         cpuid ( 0x80000000, &cpuid_extlevel, &discard_1,
00066                 &discard_2, &discard_3 );
00067         if ( ( cpuid_extlevel & 0xffff0000 ) == 0x80000000 ) {
00068                 if ( cpuid_extlevel >= 0x80000001 ) {
00069                         cpuid ( 0x80000001, &discard_1, &discard_2,
00070                                 &discard_3, &cpu->amd_features );
00071                 }
00072         }
00073 }

Generated on Tue Apr 6 20:00:49 2010 for gPXE by  doxygen 1.5.7.1