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