CPUID
CPUID
is an assembler instruction to identify Intel compatible CPUs.
Calling that instruction with register EAX
set to 1
returns information about the CPU model in register EBX
.
Processor Info and Feature Bits
EAX | 31..28 | 15..14 | 13..12 | 27..20 | 11..8 | 19..16 | 7..4 | 3..0 | Model | Hosts |
---|---|---|---|---|---|---|---|---|---|---|
res. | res. | P.Type | Ext.Family | Family | Ext.Model | Model | Stepping | |||
000106a5 | 00000000 | 0110 | 0001 | 1010 | 0101 | Intel(R) Xeon(R) CPU E5504 | hejne, skepp | |||
000106a5 | 00000000 | 0110 | 0001 | 1010 | 0101 | Intel(R) Xeon(R) CPU E5506 | frosta, smarta | |||
000106a5 | 00000000 | 0110 | 0001 | 1010 | 0101 | Intel(R) Xeon(R) CPU E5520 | utby | |||
000206c2 | 00000000 | 0110 | 0010 | 1010 | 0010 | Intel(R) Xeon(R) CPU E5606 | xen1 | |||
000206d7 | 00000000 | 0110 | 0010 | 1101 | 0111 | Intel(R) Xeon(R) CPU E5-2620 | krus | |||
000306e4 | 00000000 | 0110 | 0011 | 1110 | 0100 | Intel(R) Xeon(R) CPU E5-2650 v2 | spoka | |||
000306f2 | 00000000 | 0110 | 0011 | 1111 | 0010 | Intel(R) Xeon(R) CPU E5-2620 | lattjo, sparka | |||
000806e9 | 00000000 | 0110 | 1000 | 1110 | 1001 | Intel(R) Core(TM) i5-7200U CPU | ivar |
Extended Family
is used instead of Family
only if the later one if 15.
Extended Model
provides 4 additional upper bits for Model
only if Family
is 6 or 15.
The Linux kernel shows this in /proc/cpuinfo
:
vendor_id : GenuineIntel
cpu family : 6
model : 142
model name : Intel(R) Core(TM) i5-7200U CPU @ 2.50GHz
stepping : 9
microcode : 0x8e
Here is some C example code to decode the CPUID
information on Linux:
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <cpuid.h>
static void proc(void) {
char buf[4 << 10];
int fd = open("/proc/cpuinfo", O_RDONLY);
if (fd < 0) {
perror("open() failed");
return;
}
while (1) {
ssize_t nread = read(fd, buf, sizeof buf);
if (nread == 0)
break;
if (nread < 0) {
perror("read() failed");
goto out;
}
char *begin, *end;
for (begin = end = buf; end < buf + nread && *end; end++) {
if (*end == '\n') {
*end = '\0';
if (!strncmp(begin, "model name : ", 13)) {
printf("%s\n", begin + 13);
goto out;
}
begin = end + 1;
}
}
}
out:
if (close(fd)) {
perror("close() failed");
return;
}
}
static void cpuid(void) {
union {
struct {
uint8_t step: 4;
uint8_t model: 4;
uint8_t family: 4;
uint8_t type: 2;
uint8_t pad1: 2;
uint8_t emodel: 4;
uint8_t efamily: 8;
uint8_t pad2: 4;
};
uint32_t reg;
} eax;
uint32_t ebx, ecx, edx;
if (!__get_cpuid (1 /* Processor Info and Feature Bits */, &eax.reg, &ebx, &ecx, &edx))
return;
printf("EAX: %08x\nEBX: %08x\nECX: %08x\nEDX: %08x\n", eax.reg, ebx, ecx, edx);
printf("stepping=%d model=%d|%d family=%d|%d ptype=%d\n", eax.step, eax.emodel, eax.model, eax.efamily, eax.family, eax.type);
int model = eax.model, family = eax.family;
if (eax.family >= 6)
model |= eax.emodel << 4;
if (eax.family == 15)
family += eax.efamily;
printf("model=%d family=%d\n", model, family);
}
int main(void) {
cpuid();
proc();
return EXIT_SUCCESS;
}
Written on October 24, 2018