Linux Perf
header.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: GPL-2.0
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 
23 static int
24 __get_cpuid(char *buffer, size_t sz, const char *fmt)
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  }
52  nb = scnprintf(buffer, sz, fmt, vendor, family, model, step);
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 }
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(struct perf_pmu *pmu __maybe_unused)
70 {
71  char *buf = malloc(128);
72 
73  if (buf && __get_cpuid(buf, 128, "%s-%u-%X$") < 0) {
74  free(buf);
75  return NULL;
76  }
77  return buf;
78 }
int get_cpuid(char *buffer, size_t sz)
Definition: header.c:20
char * get_cpuid_str(struct perf_pmu *pmu)
Definition: header.c:12
Definition: pmu.h:22
void * malloc(YYSIZE_T)
const char * fmt
Definition: dso.c:193
static int __get_cpuid(char *buffer, size_t sz, const char *fmt)
Definition: header.c:24
static void cpuid(unsigned int op, unsigned int *a, unsigned int *b, unsigned int *c, unsigned int *d)
Definition: header.c:11
void free(void *)