1/* $NetBSD: errata.c,v 1.23 2016/01/05 10:20:22 hannken Exp $ */
2
3/*-
4 * Copyright (c) 2007 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Andrew Doran.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32/*
33 * Detect, report on, and work around known errata with x86 CPUs.
34 *
35 * This currently only handles AMD CPUs, and is generalised because
36 * there are quite a few problems that the BIOS can patch via MSR,
37 * but it is not known if the OS can patch these yet. The list is
38 * expected to grow over time.
39 *
40 * The data here are from: Revision Guide for AMD Athlon 64 and
41 * AMD Opteron Processors, Publication #25759, Revision: 3.69,
42 * Issue Date: September 2006
43 *
44 * XXX This should perhaps be integrated with the identcpu code.
45 */
46
47#include <sys/cdefs.h>
48__KERNEL_RCSID(0, "$NetBSD: errata.c,v 1.23 2016/01/05 10:20:22 hannken Exp $");
49
50#include <sys/types.h>
51#include <sys/systm.h>
52
53#include <machine/cpu.h>
54#include <machine/cpufunc.h>
55#include <machine/specialreg.h>
56
57#include <x86/cpuvar.h>
58#include <x86/cputypes.h>
59
60typedef struct errata {
61 u_short e_num;
62 u_short e_reported;
63 u_int e_data1;
64 const uint8_t *e_set;
65 bool (*e_act)(struct cpu_info *, struct errata *);
66 uint64_t e_data2;
67} errata_t;
68
69typedef enum cpurev {
70 BH_E4, CH_CG, CH_D0, DH_CG, DH_D0, DH_E3, DH_E6, JH_E1,
71 JH_E6, SH_B0, SH_B3, SH_C0, SH_CG, SH_D0, SH_E4, SH_E5,
72 DR_BA, DR_B2, DR_B3, RB_C2, RB_C3, BL_C2, BL_C3, DA_C2,
73 DA_C3, HY_D0, HY_D1, HY_D1_G34R1, PH_E0, LN_B0,
74 OINK
75} cpurev_t;
76
77static const u_int cpurevs[] = {
78 BH_E4, 0x0020fb1, CH_CG, 0x0000f82, CH_CG, 0x0000fb2,
79 CH_D0, 0x0010f80, CH_D0, 0x0010fb0, DH_CG, 0x0000fc0,
80 DH_CG, 0x0000fe0, DH_CG, 0x0000ff0, DH_D0, 0x0010fc0,
81 DH_D0, 0x0010ff0, DH_E3, 0x0020fc0, DH_E3, 0x0020ff0,
82 DH_E6, 0x0020fc2, DH_E6, 0x0020ff2, JH_E1, 0x0020f10,
83 JH_E6, 0x0020f12, JH_E6, 0x0020f32, SH_B0, 0x0000f40,
84 SH_B3, 0x0000f51, SH_C0, 0x0000f48, SH_C0, 0x0000f58,
85 SH_CG, 0x0000f4a, SH_CG, 0x0000f5a, SH_CG, 0x0000f7a,
86 SH_D0, 0x0010f40, SH_D0, 0x0010f50, SH_D0, 0x0010f70,
87 SH_E4, 0x0020f51, SH_E4, 0x0020f71, SH_E5, 0x0020f42,
88 DR_BA, 0x0100f2a, DR_B2, 0x0100f22, DR_B3, 0x0100f23,
89 RB_C2, 0x0100f42, RB_C3, 0x0100f43, BL_C2, 0x0100f52,
90 BL_C3, 0x0100f53, DA_C2, 0x0100f62, DA_C3, 0x0100f63,
91 HY_D0, 0x0100f80, HY_D1, 0x0100f81, HY_D1_G34R1, 0x0100f91,
92 PH_E0, 0x0100fa0, LN_B0, 0x0300f10,
93 OINK
94};
95
96static const uint8_t x86_errata_set1[] = {
97 SH_B3, SH_C0, SH_CG, DH_CG, CH_CG, OINK
98};
99
100static const uint8_t x86_errata_set2[] = {
101 SH_B3, SH_C0, SH_CG, DH_CG, CH_CG, SH_D0, DH_D0, CH_D0, OINK
102};
103
104static const uint8_t x86_errata_set3[] = {
105 JH_E1, DH_E3, OINK
106};
107
108static const uint8_t x86_errata_set4[] = {
109 SH_C0, SH_CG, DH_CG, CH_CG, SH_D0, DH_D0, CH_D0, JH_E1,
110 DH_E3, SH_E4, BH_E4, SH_E5, DH_E6, JH_E6, OINK
111};
112
113static const uint8_t x86_errata_set5[] = {
114 SH_B3, OINK
115};
116
117static const uint8_t x86_errata_set6[] = {
118 SH_C0, SH_CG, DH_CG, CH_CG, OINK
119};
120
121static const uint8_t x86_errata_set7[] = {
122 SH_C0, SH_CG, DH_CG, CH_CG, SH_D0, DH_D0, CH_D0, OINK
123};
124
125static const uint8_t x86_errata_set8[] = {
126 BH_E4, CH_CG, CH_CG, CH_D0, CH_D0, DH_CG, DH_CG, DH_CG,
127 DH_D0, DH_D0, DH_E3, DH_E3, DH_E6, DH_E6, JH_E1, JH_E6,
128 JH_E6, SH_B0, SH_B3, SH_C0, SH_C0, SH_CG, SH_CG, SH_CG,
129 SH_D0, SH_D0, SH_D0, SH_E4, SH_E4, SH_E5, OINK
130};
131
132static const uint8_t x86_errata_set9[] = {
133 DR_BA, DR_B2, OINK
134};
135
136static const uint8_t x86_errata_set10[] = {
137 DR_BA, DR_B2, DR_B3, OINK
138};
139
140static const uint8_t x86_errata_set11[] = {
141 DR_BA, DR_B2, DR_B3, RB_C2, RB_C3, BL_C2, BL_C3, DA_C2,
142 DA_C3, HY_D0, HY_D1, HY_D1_G34R1, PH_E0, LN_B0, OINK
143};
144
145static bool x86_errata_setmsr(struct cpu_info *, errata_t *);
146static bool x86_errata_testmsr(struct cpu_info *, errata_t *);
147
148static errata_t errata[] = {
149 /*
150 * 81: Cache Coherency Problem with Hardware Prefetching
151 * and Streaming Stores
152 */
153 {
154 81, FALSE, MSR_DC_CFG, x86_errata_set5,
155 x86_errata_testmsr, DC_CFG_DIS_SMC_CHK_BUF
156 },
157 /*
158 * 86: DRAM Data Masking Feature Can Cause ECC Failures
159 */
160 {
161 86, FALSE, MSR_NB_CFG, x86_errata_set1,
162 x86_errata_testmsr, NB_CFG_DISDATMSK
163 },
164 /*
165 * 89: Potential Deadlock With Locked Transactions
166 */
167 {
168 89, FALSE, MSR_NB_CFG, x86_errata_set8,
169 x86_errata_testmsr, NB_CFG_DISIOREQLOCK
170 },
171 /*
172 * 94: Sequential Prefetch Feature May Cause Incorrect
173 * Processor Operation
174 */
175 {
176 94, FALSE, MSR_IC_CFG, x86_errata_set1,
177 x86_errata_testmsr, IC_CFG_DIS_SEQ_PREFETCH
178 },
179 /*
180 * 97: 128-Bit Streaming Stores May Cause Coherency
181 * Failure
182 *
183 * XXX "This workaround must not be applied to processors
184 * prior to revision C0." We don't apply it, but if it
185 * can't be applied, it shouldn't be reported.
186 */
187 {
188 97, FALSE, MSR_DC_CFG, x86_errata_set6,
189 x86_errata_testmsr, DC_CFG_DIS_CNV_WC_SSO
190 },
191 /*
192 * 104: DRAM Data Masking Feature Causes ChipKill ECC
193 * Failures When Enabled With x8/x16 DRAM Devices
194 */
195 {
196 104, FALSE, MSR_NB_CFG, x86_errata_set7,
197 x86_errata_testmsr, NB_CFG_DISDATMSK
198 },
199 /*
200 * 113: Enhanced Write-Combining Feature Causes System Hang
201 */
202 {
203 113, FALSE, MSR_BU_CFG, x86_errata_set3,
204 x86_errata_setmsr, BU_CFG_WBENHWSBDIS
205 },
206 /*
207 * 69: Multiprocessor Coherency Problem with Hardware
208 * Prefetch Mechanism
209 */
210 {
211 69, FALSE, MSR_BU_CFG, x86_errata_set5,
212 x86_errata_setmsr, BU_CFG_WBPFSMCCHKDIS
213 },
214 /*
215 * 101: DRAM Scrubber May Cause Data Corruption When Using
216 * Node-Interleaved Memory
217 */
218 {
219 101, FALSE, 0, x86_errata_set2,
220 NULL, 0
221 },
222 /*
223 * 106: Potential Deadlock with Tightly Coupled Semaphores
224 * in an MP System
225 */
226 {
227 106, FALSE, MSR_LS_CFG, x86_errata_set2,
228 x86_errata_testmsr, LS_CFG_DIS_LS2_SQUISH
229 },
230 /*
231 * 107: Possible Multiprocessor Coherency Problem with
232 * Setting Page Table A/D Bits
233 */
234 {
235 107, FALSE, MSR_BU_CFG, x86_errata_set2,
236 x86_errata_testmsr, BU_CFG_THRL2IDXCMPDIS
237 },
238 /*
239 * 122: TLB Flush Filter May Cause Coherency Problem in
240 * Multiprocessor Systems
241 */
242 {
243 122, FALSE, MSR_HWCR, x86_errata_set4,
244 x86_errata_setmsr, HWCR_FFDIS
245 },
246 /*
247 * 254: Internal Resource Livelock Involving Cached TLB Reload
248 */
249 {
250 254, FALSE, MSR_BU_CFG, x86_errata_set9,
251 x86_errata_testmsr, BU_CFG_ERRATA_254
252 },
253 /*
254 * 261: Processor May Stall Entering Stop-Grant Due to Pending Data
255 * Cache Scrub
256 */
257 {
258 261, FALSE, MSR_DC_CFG, x86_errata_set10,
259 x86_errata_testmsr, DC_CFG_ERRATA_261
260 },
261 /*
262 * 298: L2 Eviction May Occur During Processor Operation To Set
263 * Accessed or Dirty Bit
264 */
265 {
266 298, FALSE, MSR_HWCR, x86_errata_set9,
267 x86_errata_testmsr, HWCR_TLBCACHEDIS
268 },
269 {
270 298, FALSE, MSR_BU_CFG, x86_errata_set9,
271 x86_errata_testmsr, BU_CFG_ERRATA_298
272 },
273 /*
274 * 309: Processor Core May Execute Incorrect Instructions on
275 * Concurrent L2 and Northbridge Response
276 */
277 {
278 309, FALSE, MSR_BU_CFG, x86_errata_set9,
279 x86_errata_testmsr, BU_CFG_ERRATA_309
280 },
281 /*
282 * 721: Processor May Incorrectly Update Stack Pointer
283 */
284 {
285 721, FALSE, MSR_DE_CFG, x86_errata_set11,
286 x86_errata_setmsr, DE_CFG_ERRATA_721
287 },
288};
289
290static bool
291x86_errata_testmsr(struct cpu_info *ci, errata_t *e)
292{
293 uint64_t val;
294
295 (void)ci;
296
297 val = rdmsr_locked(e->e_data1);
298 if ((val & e->e_data2) != 0)
299 return FALSE;
300
301 e->e_reported = TRUE;
302 return TRUE;
303}
304
305static bool
306x86_errata_setmsr(struct cpu_info *ci, errata_t *e)
307{
308 uint64_t val;
309
310 (void)ci;
311
312 val = rdmsr_locked(e->e_data1);
313 if ((val & e->e_data2) != 0)
314 return FALSE;
315 wrmsr_locked(e->e_data1, val | e->e_data2);
316 aprint_debug_dev(ci->ci_dev, "erratum %d patched\n",
317 e->e_num);
318
319 return FALSE;
320}
321
322void
323x86_errata(void)
324{
325 struct cpu_info *ci;
326 uint32_t descs[4];
327 errata_t *e, *ex;
328 cpurev_t rev;
329 int i, j, upgrade;
330 static int again;
331
332 /* don't run if we are under a hypervisor */
333 if (cpu_feature[1] & CPUID2_RAZ)
334 return;
335
336 /* only for AMD */
337 if (cpu_vendor != CPUVENDOR_AMD)
338 return;
339
340 ci = curcpu();
341
342 x86_cpuid(0x80000001, descs);
343
344 for (i = 0;; i += 2) {
345 if ((rev = cpurevs[i]) == OINK)
346 return;
347 if (cpurevs[i + 1] == descs[0])
348 break;
349 }
350
351 ex = errata + __arraycount(errata);
352 for (upgrade = 0, e = errata; e < ex; e++) {
353 if (e->e_reported)
354 continue;
355 if (e->e_set != NULL) {
356 for (j = 0; e->e_set[j] != OINK; j++)
357 if (e->e_set[j] == rev)
358 break;
359 if (e->e_set[j] == OINK)
360 continue;
361 }
362
363 aprint_debug_dev(ci->ci_dev, "testing for erratum %d\n",
364 e->e_num);
365
366 if (e->e_act == NULL)
367 e->e_reported = TRUE;
368 else if ((*e->e_act)(ci, e) == FALSE)
369 continue;
370
371 aprint_verbose_dev(ci->ci_dev, "erratum %d present\n",
372 e->e_num);
373 upgrade = 1;
374 }
375
376 if (upgrade && !again) {
377 again = 1;
378 aprint_normal_dev(ci->ci_dev, "WARNING: errata present,"
379 " BIOS upgrade may be\n");
380 aprint_normal_dev(ci->ci_dev, "WARNING: necessary to ensure"
381 " reliable operation\n");
382 }
383}
384