Skip to content

Instantly share code, notes, and snippets.

@YukiSakamoto
Created December 8, 2012 07:26
Show Gist options
  • Save YukiSakamoto/4239118 to your computer and use it in GitHub Desktop.
Save YukiSakamoto/4239118 to your computer and use it in GitHub Desktop.
Using CPUID instruction, and survey functions of my computer's cpu.
#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;
}
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