Commit | Line | Data |
---|---|---|
fbe96f29 SE |
1 | #include <sys/types.h> |
2 | #include <unistd.h> | |
3 | #include <stdio.h> | |
4 | #include <stdlib.h> | |
5 | #include <string.h> | |
6 | ||
7 | #include "../../util/header.h" | |
8 | ||
9 | static inline void | |
10 | cpuid(unsigned int op, unsigned int *a, unsigned int *b, unsigned int *c, | |
11 | unsigned int *d) | |
12 | { | |
13 | __asm__ __volatile__ (".byte 0x53\n\tcpuid\n\t" | |
14 | "movl %%ebx, %%esi\n\t.byte 0x5b" | |
15 | : "=a" (*a), | |
16 | "=S" (*b), | |
17 | "=c" (*c), | |
18 | "=d" (*d) | |
19 | : "a" (op)); | |
20 | } | |
21 | ||
22 | int | |
23 | get_cpuid(char *buffer, size_t sz) | |
24 | { | |
25 | unsigned int a, b, c, d, lvl; | |
26 | int family = -1, model = -1, step = -1; | |
27 | int nb; | |
28 | char vendor[16]; | |
29 | ||
30 | cpuid(0, &lvl, &b, &c, &d); | |
31 | strncpy(&vendor[0], (char *)(&b), 4); | |
32 | strncpy(&vendor[4], (char *)(&d), 4); | |
33 | strncpy(&vendor[8], (char *)(&c), 4); | |
34 | vendor[12] = '\0'; | |
35 | ||
36 | if (lvl >= 1) { | |
37 | cpuid(1, &a, &b, &c, &d); | |
38 | ||
39 | family = (a >> 8) & 0xf; /* bits 11 - 8 */ | |
40 | model = (a >> 4) & 0xf; /* Bits 7 - 4 */ | |
41 | step = a & 0xf; | |
42 | ||
43 | /* extended family */ | |
44 | if (family == 0xf) | |
45 | family += (a >> 20) & 0xff; | |
46 | ||
47 | /* extended model */ | |
48 | if (family >= 0x6) | |
49 | model += ((a >> 16) & 0xf) << 4; | |
50 | } | |
e7f01d1e | 51 | nb = scnprintf(buffer, sz, "%s,%u,%u,%u$", vendor, family, model, step); |
fbe96f29 SE |
52 | |
53 | /* look for end marker to ensure the entire data fit */ | |
54 | if (strchr(buffer, '$')) { | |
55 | buffer[nb-1] = '\0'; | |
56 | return 0; | |
57 | } | |
58 | return -1; | |
59 | } |