Created
December 8, 2012 07:26
-
-
Save YukiSakamoto/4239118 to your computer and use it in GitHub Desktop.
Using CPUID instruction, and survey functions of my computer's cpu.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdint.h> | |
#include <string.h> | |
#define CPUID_FLAG_BIT_CREATE(id) (0x01<<id) | |
struct instruction_type { | |
unsigned int flag_type; | |
char operation[32]; | |
char description[64]; | |
}; | |
#define RESERVED | |
/* --- EDX flags --- */ | |
#define FPU 0 | |
#define VME 1 | |
#define DE 2 | |
#define PSE 3 | |
#define TSC 4 | |
#define MSR 5 | |
#define PAE 6 | |
#define MCE 7 | |
#define CX8 8 | |
#define APIC 9 | |
/* Reserved 10 */ | |
#define SEP 11 | |
#define MTRR 12 | |
#define PGE 13 | |
#define MCA 14 | |
#define CMOV 15 | |
#define PAT 16 | |
#define PSE_36 17 | |
#define PSN 18 | |
#define CLFSH 19 | |
/* Reserved 20 */ | |
#define DTES 21 | |
#define ACPI 22 | |
#define MMX 23 | |
#define FXSR 24 | |
#define SSE 25 | |
#define SSE2 26 | |
#define SLFSNP 27 | |
const struct instruction_type edx_operatelist[] = { | |
{ FPU, "FPU", }, | |
{ VME, "VME", }, | |
{ DE, "DE", }, | |
{ PSE, "PSE", }, | |
{ TSC, "TSC", }, | |
{ MSR, "MSR", }, | |
{ PAE, "PAE", }, | |
{ MCE, "MCE", }, | |
{ CX8, "CX8", }, | |
{ APIC, "APIC", }, | |
{ SEP, "SEP", }, | |
{ MTRR, "MTRR", }, | |
{ PGE, "PGE", }, | |
{ MCA, "MCA", }, | |
{ CMOV, "CMOV", }, | |
{ PAT, "PAT", }, | |
{ PSE_36, "PSE_36", }, | |
{ PSN, "PSN", }, | |
{ CLFSH, "CLFSH" }, | |
{ DTES, "DTES", }, | |
{ ACPI, "ACPI", }, | |
{ MMX, "MMX", }, | |
{ FXSR, "FXSR", }, | |
{ SSE, "SSE", }, | |
{ SSE2, "SSE2", }, | |
{ SLFSNP, "SLFSNP", }, | |
}; | |
/* --- ECX flags --- */ | |
#define SSE3 0 | |
/* --- 2:1 reserved --- */ | |
#define MONITOR 3 | |
#define DS_CPL 4 | |
/* --- 6:5 reserved --- */ | |
#define EST 7 | |
#define TM2 8 | |
/* --- 9 reserved --- */ | |
#define CID 10 | |
/* --- 12:11 reserved --- */ | |
#define CX16 13 | |
#define xTPR 14 | |
/* --- 31:15 reserved --- */ | |
const struct instruction_type ecx_operatelist[] = { | |
{ SSE3, "SSE3" }, | |
{ MONITOR, "MONITOR", }, | |
{ DS_CPL, "DS_CPL", }, | |
{ EST, "EST", }, | |
{ TM2, "TM2", }, | |
{ CID, "CID", }, | |
{ CX16, "CX16", }, | |
{ xTPR, "xTPR", }, | |
}; | |
uint32_t getBasicProcesserInfo(char *vendor_id_str, size_t size) | |
{ | |
uint32_t basic_info = 0; | |
uint32_t r_eax, r_ebx, r_ecx, r_edx; | |
asm volatile("movl $0, %%eax" : : :"%eax"); | |
asm volatile("cpuid": "=a"(basic_info), "=b"(r_ebx), "=c"(r_ecx), "=d"(r_edx): :"%eax", "%ebx", "%ecx", "%edx"); | |
memset(vendor_id_str, 0x00, size); | |
memcpy(vendor_id_str, &r_ebx, sizeof(uint32_t)); | |
memcpy(vendor_id_str + sizeof(uint32_t), &r_edx, sizeof(uint32_t)); | |
memcpy(vendor_id_str + 2 * sizeof(uint32_t) , &r_ecx, sizeof(uint32_t)); | |
return basic_info; | |
} | |
int getCpuidFlags(uint32_t *edx, uint32_t *ecx) | |
{ | |
uint32_t r_edx = 0, r_ecx = 0; | |
asm volatile("movl $1, %%eax" : : :"%eax"); | |
asm volatile("cpuid": "=d"(r_edx), "=c"(r_ecx) : :"%edx", "%ecx"); | |
*edx = r_edx; | |
*ecx = r_ecx; | |
if (0 < r_edx || 0 < r_ecx) | |
return 0; | |
return -1; | |
} | |
void getCpuBrandString(char *buffer) | |
{ | |
uint32_t cpuid_flags = 0x00; | |
uint32_t r_eax, r_ebx, r_ecx, r_edx; | |
uint32_t acc; | |
uint32_t extend_eax_max; | |
char br_str[128]; | |
int i = 0; | |
int pos = 0; | |
memset(br_str, 0x00, sizeof(br_str)); | |
asm volatile("movl $0x80000000, %%eax" : : :"%eax"); | |
asm volatile("cpuid": "=a"(extend_eax_max): :"%eax", "%ebx", "%ecx", "%edx"); | |
if (0x80000002 < extend_eax_max) { | |
asm volatile("movl $0x80000002, %%eax" : : : "%eax"); | |
asm volatile("cpuid" : "=a"(r_eax), "=b"(r_ebx), "=c"(r_ecx), "=d"(r_edx) : : | |
"%eax", "%ebx", "%ecx", "%edx"); | |
memcpy(br_str + pos, &r_eax, sizeof(uint32_t)); | |
pos += sizeof(uint32_t); | |
memcpy(br_str + pos, &r_ebx, sizeof(uint32_t)); | |
pos += sizeof(uint32_t); | |
memcpy(br_str + pos, &r_ecx, sizeof(uint32_t)); | |
pos += sizeof(uint32_t); | |
memcpy(br_str + pos, &r_edx, sizeof(uint32_t)); | |
pos += sizeof(uint32_t); | |
} | |
if (0x80000003 < extend_eax_max) { | |
asm volatile("movl $0x80000003, %%eax" : : : "%eax"); | |
asm volatile("cpuid" : "=a"(r_eax), "=b"(r_ebx), "=c"(r_ecx), "=d"(r_edx) : : | |
"%eax", "%ebx", "%ecx", "%edx"); | |
memcpy(br_str + pos, &r_eax, sizeof(uint32_t)); | |
pos += sizeof(uint32_t); | |
memcpy(br_str + pos, &r_ebx, sizeof(uint32_t)); | |
pos += sizeof(uint32_t); | |
memcpy(br_str + pos, &r_ecx, sizeof(uint32_t)); | |
pos += sizeof(uint32_t); | |
memcpy(br_str + pos, &r_edx, sizeof(uint32_t)); | |
pos += sizeof(uint32_t); | |
} | |
if (0x80000004 < extend_eax_max) { | |
asm volatile("movl $0x80000004, %%eax" : : : "%eax"); | |
asm volatile("cpuid" : "=a"(r_eax), "=b"(r_ebx), "=c"(r_ecx), "=d"(r_edx) : : | |
"%eax", "%ebx", "%ecx", "%edx"); | |
memcpy(br_str + pos, &r_eax, sizeof(uint32_t)); | |
pos += sizeof(uint32_t); | |
memcpy(br_str + pos, &r_ebx, sizeof(uint32_t)); | |
pos += sizeof(uint32_t); | |
memcpy(br_str + pos, &r_ecx, sizeof(uint32_t)); | |
pos += sizeof(uint32_t); | |
memcpy(br_str + pos, &r_edx, sizeof(uint32_t)); | |
pos += sizeof(uint32_t); | |
} | |
strcpy(buffer, br_str); | |
} | |
int main(void) | |
{ | |
uint32_t cpuflag = 0; | |
char cpu_name[64]; | |
uint32_t edx_flags, ecx_flags; | |
char cpu_brand[128]; | |
if (0 < getBasicProcesserInfo(cpu_name, sizeof(cpu_name))) { | |
int i; | |
printf("cpu_name: %s \n", cpu_name); | |
getCpuidFlags(&edx_flags, &ecx_flags); | |
/* functions */ | |
for(i = 0; i < sizeof(edx_operatelist) / sizeof(struct instruction_type); i++) { | |
if (edx_flags & CPUID_FLAG_BIT_CREATE(edx_operatelist[i].flag_type)) { | |
printf("%6s\tyes\n", edx_operatelist[i].operation); | |
} else { | |
printf("%6s\tno\n", edx_operatelist[i].operation); | |
} | |
} | |
for(i = 0; i < sizeof(ecx_operatelist) / sizeof(struct instruction_type); i++) { | |
if (ecx_flags & CPUID_FLAG_BIT_CREATE(ecx_operatelist[i].flag_type)) { | |
printf("%6s\tyes\n", ecx_operatelist[i].operation); | |
} else { | |
printf("%6s\tno\n", ecx_operatelist[i].operation); | |
} | |
} | |
} | |
getCpuBrandString(cpu_brand); | |
printf("%s \n", cpu_brand); | |
return 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
cpu_name: GenuineIntel | |
FPU yes | |
VME yes | |
DE yes | |
PSE yes | |
TSC yes | |
MSR yes | |
PAE yes | |
MCE yes | |
CX8 yes | |
APIC yes | |
SEP yes | |
MTRR yes | |
PGE yes | |
MCA yes | |
CMOV yes | |
PAT yes | |
PSE_36 yes | |
PSN no | |
CLFSH yes | |
DTES yes | |
ACPI yes | |
MMX yes | |
FXSR yes | |
SSE yes | |
SSE2 yes | |
SLFSNP yes | |
SSE3 yes | |
MONITOR yes | |
DS_CPL yes | |
EST yes | |
TM2 yes | |
CID no | |
CX16 yes | |
xTPR yes | |
Intel(R) Core(TM) i5-3427U CPU @ 1.80GHz |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment