Stephane Eranian | fbe96f2 | 2011-09-30 15:40:40 +0200 | [diff] [blame] | 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 | |
Andi Kleen | f33d122 | 2016-09-15 15:24:42 -0700 | [diff] [blame] | 22 | static int |
| 23 | __get_cpuid(char *buffer, size_t sz, const char *fmt) |
Stephane Eranian | fbe96f2 | 2011-09-30 15:40:40 +0200 | [diff] [blame] | 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 | } |
Andi Kleen | f33d122 | 2016-09-15 15:24:42 -0700 | [diff] [blame] | 51 | nb = scnprintf(buffer, sz, fmt, vendor, family, model, step); |
Stephane Eranian | fbe96f2 | 2011-09-30 15:40:40 +0200 | [diff] [blame] | 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 | } |
Andi Kleen | f33d122 | 2016-09-15 15:24:42 -0700 | [diff] [blame] | 60 | |
| 61 | int |
| 62 | get_cpuid(char *buffer, size_t sz) |
| 63 | { |
| 64 | return __get_cpuid(buffer, sz, "%s,%u,%u,%u$"); |
| 65 | } |
| 66 | |
| 67 | char * |
| 68 | get_cpuid_str(void) |
| 69 | { |
| 70 | char *buf = malloc(128); |
| 71 | |
| 72 | if (__get_cpuid(buf, 128, "%s-%u-%X$") < 0) { |
| 73 | free(buf); |
| 74 | return NULL; |
| 75 | } |
| 76 | return buf; |
| 77 | } |