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 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 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 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