.. | .. |
---|
5 | 5 | #include <stdio.h> |
---|
6 | 6 | #include <stdlib.h> |
---|
7 | 7 | #include <string.h> |
---|
| 8 | +#include <regex.h> |
---|
8 | 9 | |
---|
9 | | -#include "../../util/header.h" |
---|
| 10 | +#include "../../../util/debug.h" |
---|
| 11 | +#include "../../../util/header.h" |
---|
10 | 12 | |
---|
11 | 13 | static inline void |
---|
12 | 14 | cpuid(unsigned int op, unsigned int *a, unsigned int *b, unsigned int *c, |
---|
.. | .. |
---|
71 | 73 | { |
---|
72 | 74 | char *buf = malloc(128); |
---|
73 | 75 | |
---|
74 | | - if (buf && __get_cpuid(buf, 128, "%s-%u-%X$") < 0) { |
---|
| 76 | + if (buf && __get_cpuid(buf, 128, "%s-%u-%X-%X$") < 0) { |
---|
75 | 77 | free(buf); |
---|
76 | 78 | return NULL; |
---|
77 | 79 | } |
---|
78 | 80 | return buf; |
---|
79 | 81 | } |
---|
| 82 | + |
---|
| 83 | +/* Full CPUID format for x86 is vendor-family-model-stepping */ |
---|
| 84 | +static bool is_full_cpuid(const char *id) |
---|
| 85 | +{ |
---|
| 86 | + const char *tmp = id; |
---|
| 87 | + int count = 0; |
---|
| 88 | + |
---|
| 89 | + while ((tmp = strchr(tmp, '-')) != NULL) { |
---|
| 90 | + count++; |
---|
| 91 | + tmp++; |
---|
| 92 | + } |
---|
| 93 | + |
---|
| 94 | + if (count == 3) |
---|
| 95 | + return true; |
---|
| 96 | + |
---|
| 97 | + return false; |
---|
| 98 | +} |
---|
| 99 | + |
---|
| 100 | +int strcmp_cpuid_str(const char *mapcpuid, const char *id) |
---|
| 101 | +{ |
---|
| 102 | + regex_t re; |
---|
| 103 | + regmatch_t pmatch[1]; |
---|
| 104 | + int match; |
---|
| 105 | + bool full_mapcpuid = is_full_cpuid(mapcpuid); |
---|
| 106 | + bool full_cpuid = is_full_cpuid(id); |
---|
| 107 | + |
---|
| 108 | + /* |
---|
| 109 | + * Full CPUID format is required to identify a platform. |
---|
| 110 | + * Error out if the cpuid string is incomplete. |
---|
| 111 | + */ |
---|
| 112 | + if (full_mapcpuid && !full_cpuid) { |
---|
| 113 | + pr_info("Invalid CPUID %s. Full CPUID is required, " |
---|
| 114 | + "vendor-family-model-stepping\n", id); |
---|
| 115 | + return 1; |
---|
| 116 | + } |
---|
| 117 | + |
---|
| 118 | + if (regcomp(&re, mapcpuid, REG_EXTENDED) != 0) { |
---|
| 119 | + /* Warn unable to generate match particular string. */ |
---|
| 120 | + pr_info("Invalid regular expression %s\n", mapcpuid); |
---|
| 121 | + return 1; |
---|
| 122 | + } |
---|
| 123 | + |
---|
| 124 | + match = !regexec(&re, id, 1, pmatch, 0); |
---|
| 125 | + regfree(&re); |
---|
| 126 | + if (match) { |
---|
| 127 | + size_t match_len = (pmatch[0].rm_eo - pmatch[0].rm_so); |
---|
| 128 | + size_t cpuid_len; |
---|
| 129 | + |
---|
| 130 | + /* If the full CPUID format isn't required, |
---|
| 131 | + * ignoring the stepping. |
---|
| 132 | + */ |
---|
| 133 | + if (!full_mapcpuid && full_cpuid) |
---|
| 134 | + cpuid_len = strrchr(id, '-') - id; |
---|
| 135 | + else |
---|
| 136 | + cpuid_len = strlen(id); |
---|
| 137 | + |
---|
| 138 | + /* Verify the entire string matched. */ |
---|
| 139 | + if (match_len == cpuid_len) |
---|
| 140 | + return 0; |
---|
| 141 | + } |
---|
| 142 | + |
---|
| 143 | + return 1; |
---|
| 144 | +} |
---|