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 
60 typedef 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 
69 typedef 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 
77 static 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 
96 static const uint8_t x86_errata_set1[] = {
97 	SH_B3, SH_C0, SH_CG, DH_CG, CH_CG, OINK
98 };
99 
100 static 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 
104 static const uint8_t x86_errata_set3[] = {
105 	JH_E1, DH_E3, OINK
106 };
107 
108 static 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 
113 static const uint8_t x86_errata_set5[] = {
114 	SH_B3, OINK
115 };
116 
117 static const uint8_t x86_errata_set6[] = {
118 	SH_C0, SH_CG, DH_CG, CH_CG, OINK
119 };
120 
121 static const uint8_t x86_errata_set7[] = {
122 	SH_C0, SH_CG, DH_CG, CH_CG, SH_D0, DH_D0, CH_D0, OINK
123 };
124 
125 static 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 
132 static const uint8_t x86_errata_set9[] = {
133 	DR_BA, DR_B2, OINK
134 };
135 
136 static const uint8_t x86_errata_set10[] = {
137 	DR_BA, DR_B2, DR_B3, OINK
138 };
139 
140 static 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 
145 static bool x86_errata_setmsr(struct cpu_info *, errata_t *);
146 static bool x86_errata_testmsr(struct cpu_info *, errata_t *);
147 
148 static 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 
290 static bool
x86_errata_testmsr(struct cpu_info * ci,errata_t * e)291 x86_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 
305 static bool
x86_errata_setmsr(struct cpu_info * ci,errata_t * e)306 x86_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 
322 void
x86_errata(void)323 x86_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