cpu.c
Go to the documentation of this file.00001 #include <stdint.h>
00002 #include <string.h>
00003 #include <cpu.h>
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
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
00038
00039
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
00049 if ( ! flag_is_changeable ( X86_EFLAGS_ID ) ) {
00050 DBG ( "CPUID not supported\n" );
00051 return;
00052 }
00053
00054
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
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 }