|
27 | 27 |
|
28 | 28 | #include "cpu.h"
|
29 | 29 |
|
30 |
| -static const int amd_erratum_383[]; |
31 |
| -static const int amd_erratum_400[]; |
32 |
| -static const int amd_erratum_1054[]; |
33 |
| -static bool cpu_has_amd_erratum(struct cpuinfo_x86 *cpu, const int *erratum); |
34 |
| - |
35 | 30 | /*
|
36 | 31 | * nodes_per_socket: Stores the number of nodes per socket.
|
37 | 32 | * Refer to Fam15h Models 00-0fh BKDG - CPUID Fn8000_001E_ECX
|
38 | 33 | * Node Identifiers[10:8]
|
39 | 34 | */
|
40 | 35 | static u32 nodes_per_socket = 1;
|
41 | 36 |
|
| 37 | +/* |
| 38 | + * AMD errata checking |
| 39 | + * |
| 40 | + * Errata are defined as arrays of ints using the AMD_LEGACY_ERRATUM() or |
| 41 | + * AMD_OSVW_ERRATUM() macros. The latter is intended for newer errata that |
| 42 | + * have an OSVW id assigned, which it takes as first argument. Both take a |
| 43 | + * variable number of family-specific model-stepping ranges created by |
| 44 | + * AMD_MODEL_RANGE(). |
| 45 | + * |
| 46 | + * Example: |
| 47 | + * |
| 48 | + * const int amd_erratum_319[] = |
| 49 | + * AMD_LEGACY_ERRATUM(AMD_MODEL_RANGE(0x10, 0x2, 0x1, 0x4, 0x2), |
| 50 | + * AMD_MODEL_RANGE(0x10, 0x8, 0x0, 0x8, 0x0), |
| 51 | + * AMD_MODEL_RANGE(0x10, 0x9, 0x0, 0x9, 0x0)); |
| 52 | + */ |
| 53 | + |
| 54 | +#define AMD_LEGACY_ERRATUM(...) { -1, __VA_ARGS__, 0 } |
| 55 | +#define AMD_OSVW_ERRATUM(osvw_id, ...) { osvw_id, __VA_ARGS__, 0 } |
| 56 | +#define AMD_MODEL_RANGE(f, m_start, s_start, m_end, s_end) \ |
| 57 | + ((f << 24) | (m_start << 16) | (s_start << 12) | (m_end << 4) | (s_end)) |
| 58 | +#define AMD_MODEL_RANGE_FAMILY(range) (((range) >> 24) & 0xff) |
| 59 | +#define AMD_MODEL_RANGE_START(range) (((range) >> 12) & 0xfff) |
| 60 | +#define AMD_MODEL_RANGE_END(range) ((range) & 0xfff) |
| 61 | + |
| 62 | +static const int amd_erratum_400[] = |
| 63 | + AMD_OSVW_ERRATUM(1, AMD_MODEL_RANGE(0xf, 0x41, 0x2, 0xff, 0xf), |
| 64 | + AMD_MODEL_RANGE(0x10, 0x2, 0x1, 0xff, 0xf)); |
| 65 | + |
| 66 | +static const int amd_erratum_383[] = |
| 67 | + AMD_OSVW_ERRATUM(3, AMD_MODEL_RANGE(0x10, 0, 0, 0xff, 0xf)); |
| 68 | + |
| 69 | +/* #1054: Instructions Retired Performance Counter May Be Inaccurate */ |
| 70 | +static const int amd_erratum_1054[] = |
| 71 | + AMD_LEGACY_ERRATUM(AMD_MODEL_RANGE(0x17, 0, 0, 0x2f, 0xf)); |
| 72 | + |
| 73 | +static bool cpu_has_amd_erratum(struct cpuinfo_x86 *cpu, const int *erratum) |
| 74 | +{ |
| 75 | + int osvw_id = *erratum++; |
| 76 | + u32 range; |
| 77 | + u32 ms; |
| 78 | + |
| 79 | + if (osvw_id >= 0 && osvw_id < 65536 && |
| 80 | + cpu_has(cpu, X86_FEATURE_OSVW)) { |
| 81 | + u64 osvw_len; |
| 82 | + |
| 83 | + rdmsrl(MSR_AMD64_OSVW_ID_LENGTH, osvw_len); |
| 84 | + if (osvw_id < osvw_len) { |
| 85 | + u64 osvw_bits; |
| 86 | + |
| 87 | + rdmsrl(MSR_AMD64_OSVW_STATUS + (osvw_id >> 6), |
| 88 | + osvw_bits); |
| 89 | + return osvw_bits & (1ULL << (osvw_id & 0x3f)); |
| 90 | + } |
| 91 | + } |
| 92 | + |
| 93 | + /* OSVW unavailable or ID unknown, match family-model-stepping range */ |
| 94 | + ms = (cpu->x86_model << 4) | cpu->x86_stepping; |
| 95 | + while ((range = *erratum++)) |
| 96 | + if ((cpu->x86 == AMD_MODEL_RANGE_FAMILY(range)) && |
| 97 | + (ms >= AMD_MODEL_RANGE_START(range)) && |
| 98 | + (ms <= AMD_MODEL_RANGE_END(range))) |
| 99 | + return true; |
| 100 | + |
| 101 | + return false; |
| 102 | +} |
| 103 | + |
42 | 104 | static inline int rdmsrl_amd_safe(unsigned msr, unsigned long long *p)
|
43 | 105 | {
|
44 | 106 | u32 gprs[8] = { 0 };
|
@@ -1100,73 +1162,6 @@ static const struct cpu_dev amd_cpu_dev = {
|
1100 | 1162 |
|
1101 | 1163 | cpu_dev_register(amd_cpu_dev);
|
1102 | 1164 |
|
1103 |
| -/* |
1104 |
| - * AMD errata checking |
1105 |
| - * |
1106 |
| - * Errata are defined as arrays of ints using the AMD_LEGACY_ERRATUM() or |
1107 |
| - * AMD_OSVW_ERRATUM() macros. The latter is intended for newer errata that |
1108 |
| - * have an OSVW id assigned, which it takes as first argument. Both take a |
1109 |
| - * variable number of family-specific model-stepping ranges created by |
1110 |
| - * AMD_MODEL_RANGE(). |
1111 |
| - * |
1112 |
| - * Example: |
1113 |
| - * |
1114 |
| - * const int amd_erratum_319[] = |
1115 |
| - * AMD_LEGACY_ERRATUM(AMD_MODEL_RANGE(0x10, 0x2, 0x1, 0x4, 0x2), |
1116 |
| - * AMD_MODEL_RANGE(0x10, 0x8, 0x0, 0x8, 0x0), |
1117 |
| - * AMD_MODEL_RANGE(0x10, 0x9, 0x0, 0x9, 0x0)); |
1118 |
| - */ |
1119 |
| - |
1120 |
| -#define AMD_LEGACY_ERRATUM(...) { -1, __VA_ARGS__, 0 } |
1121 |
| -#define AMD_OSVW_ERRATUM(osvw_id, ...) { osvw_id, __VA_ARGS__, 0 } |
1122 |
| -#define AMD_MODEL_RANGE(f, m_start, s_start, m_end, s_end) \ |
1123 |
| - ((f << 24) | (m_start << 16) | (s_start << 12) | (m_end << 4) | (s_end)) |
1124 |
| -#define AMD_MODEL_RANGE_FAMILY(range) (((range) >> 24) & 0xff) |
1125 |
| -#define AMD_MODEL_RANGE_START(range) (((range) >> 12) & 0xfff) |
1126 |
| -#define AMD_MODEL_RANGE_END(range) ((range) & 0xfff) |
1127 |
| - |
1128 |
| -static const int amd_erratum_400[] = |
1129 |
| - AMD_OSVW_ERRATUM(1, AMD_MODEL_RANGE(0xf, 0x41, 0x2, 0xff, 0xf), |
1130 |
| - AMD_MODEL_RANGE(0x10, 0x2, 0x1, 0xff, 0xf)); |
1131 |
| - |
1132 |
| -static const int amd_erratum_383[] = |
1133 |
| - AMD_OSVW_ERRATUM(3, AMD_MODEL_RANGE(0x10, 0, 0, 0xff, 0xf)); |
1134 |
| - |
1135 |
| -/* #1054: Instructions Retired Performance Counter May Be Inaccurate */ |
1136 |
| -static const int amd_erratum_1054[] = |
1137 |
| - AMD_LEGACY_ERRATUM(AMD_MODEL_RANGE(0x17, 0, 0, 0x2f, 0xf)); |
1138 |
| - |
1139 |
| -static bool cpu_has_amd_erratum(struct cpuinfo_x86 *cpu, const int *erratum) |
1140 |
| -{ |
1141 |
| - int osvw_id = *erratum++; |
1142 |
| - u32 range; |
1143 |
| - u32 ms; |
1144 |
| - |
1145 |
| - if (osvw_id >= 0 && osvw_id < 65536 && |
1146 |
| - cpu_has(cpu, X86_FEATURE_OSVW)) { |
1147 |
| - u64 osvw_len; |
1148 |
| - |
1149 |
| - rdmsrl(MSR_AMD64_OSVW_ID_LENGTH, osvw_len); |
1150 |
| - if (osvw_id < osvw_len) { |
1151 |
| - u64 osvw_bits; |
1152 |
| - |
1153 |
| - rdmsrl(MSR_AMD64_OSVW_STATUS + (osvw_id >> 6), |
1154 |
| - osvw_bits); |
1155 |
| - return osvw_bits & (1ULL << (osvw_id & 0x3f)); |
1156 |
| - } |
1157 |
| - } |
1158 |
| - |
1159 |
| - /* OSVW unavailable or ID unknown, match family-model-stepping range */ |
1160 |
| - ms = (cpu->x86_model << 4) | cpu->x86_stepping; |
1161 |
| - while ((range = *erratum++)) |
1162 |
| - if ((cpu->x86 == AMD_MODEL_RANGE_FAMILY(range)) && |
1163 |
| - (ms >= AMD_MODEL_RANGE_START(range)) && |
1164 |
| - (ms <= AMD_MODEL_RANGE_END(range))) |
1165 |
| - return true; |
1166 |
| - |
1167 |
| - return false; |
1168 |
| -} |
1169 |
| - |
1170 | 1165 | void set_dr_addr_mask(unsigned long mask, int dr)
|
1171 | 1166 | {
|
1172 | 1167 | if (!boot_cpu_has(X86_FEATURE_BPEXT))
|
|
0 commit comments