1 // SPDX-License-Identifier: GPL-2.0
10 #include "../../../util/debug.h"
11 #include "../../../util/header.h"
14 void get_cpuid_0(char *vendor
, unsigned int *lvl
)
18 cpuid(0, 0, lvl
, &b
, &c
, &d
);
19 strncpy(&vendor
[0], (char *)(&b
), 4);
20 strncpy(&vendor
[4], (char *)(&d
), 4);
21 strncpy(&vendor
[8], (char *)(&c
), 4);
26 __get_cpuid(char *buffer
, size_t sz
, const char *fmt
)
28 unsigned int a
, b
, c
, d
, lvl
;
29 int family
= -1, model
= -1, step
= -1;
33 get_cpuid_0(vendor
, &lvl
);
36 cpuid(1, 0, &a
, &b
, &c
, &d
);
38 family
= (a
>> 8) & 0xf; /* bits 11 - 8 */
39 model
= (a
>> 4) & 0xf; /* Bits 7 - 4 */
44 family
+= (a
>> 20) & 0xff;
48 model
+= ((a
>> 16) & 0xf) << 4;
50 nb
= scnprintf(buffer
, sz
, fmt
, vendor
, family
, model
, step
);
52 /* look for end marker to ensure the entire data fit */
53 if (strchr(buffer
, '$')) {
61 get_cpuid(char *buffer
, size_t sz
, struct perf_cpu cpu __maybe_unused
)
63 return __get_cpuid(buffer
, sz
, "%s,%u,%u,%u$");
66 char *get_cpuid_str(struct perf_cpu cpu __maybe_unused
)
68 char *buf
= malloc(128);
70 if (buf
&& __get_cpuid(buf
, 128, "%s-%u-%X-%X$") < 0) {
77 /* Full CPUID format for x86 is vendor-family-model-stepping */
78 static bool is_full_cpuid(const char *id
)
83 while ((tmp
= strchr(tmp
, '-')) != NULL
) {
94 int strcmp_cpuid_str(const char *mapcpuid
, const char *id
)
99 bool full_mapcpuid
= is_full_cpuid(mapcpuid
);
100 bool full_cpuid
= is_full_cpuid(id
);
103 * Full CPUID format is required to identify a platform.
104 * Error out if the cpuid string is incomplete.
106 if (full_mapcpuid
&& !full_cpuid
) {
107 pr_info("Invalid CPUID %s. Full CPUID is required, "
108 "vendor-family-model-stepping\n", id
);
112 if (regcomp(&re
, mapcpuid
, REG_EXTENDED
) != 0) {
113 /* Warn unable to generate match particular string. */
114 pr_info("Invalid regular expression %s\n", mapcpuid
);
118 match
= !regexec(&re
, id
, 1, pmatch
, 0);
121 size_t match_len
= (pmatch
[0].rm_eo
- pmatch
[0].rm_so
);
124 /* If the full CPUID format isn't required,
125 * ignoring the stepping.
127 if (!full_mapcpuid
&& full_cpuid
)
128 cpuid_len
= strrchr(id
, '-') - id
;
130 cpuid_len
= strlen(id
);
132 /* Verify the entire string matched. */
133 if (match_len
== cpuid_len
)