1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <sys/types.h> 30 #include <sys/regset.h> 31 #include <sys/privregs.h> 32 #include <sys/pci_impl.h> 33 #include <sys/cpuvar.h> 34 #include <sys/x86_archext.h> 35 #include <sys/cmn_err.h> 36 #include <sys/systm.h> 37 #include <sys/sysmacros.h> 38 #include <sys/chip.h> 39 #include <sys/cyclic.h> 40 #include <sys/cpu_module_impl.h> 41 #include <sys/pci_cfgspace_impl.h> 42 #include <sys/sysevent.h> 43 #include <sys/smbios.h> 44 #include <sys/mca_x86.h> 45 #include <sys/mca_amd.h> 46 #include <sys/mc.h> 47 #include <sys/psw.h> 48 #include <sys/ddi.h> 49 #include <sys/sunddi.h> 50 #include <sys/sdt.h> 51 #include <sys/fm/util.h> 52 #include <sys/fm/protocol.h> 53 #include <sys/fm/cpu/AMD.h> 54 #include <sys/acpi/acpi.h> 55 #include <sys/acpi/acpi_pci.h> 56 #include <sys/acpica.h> 57 58 #include "ao.h" 59 #include "ao_mca_disp.h" 60 61 errorq_t *ao_mca_queue; /* machine-check ereport queue */ 62 int ao_mca_stack_flag = 0; /* record stack trace in ereports */ 63 int ao_mca_smi_disable = 1; /* attempt to disable SMI polling */ 64 65 ao_bank_regs_t ao_bank_regs[AMD_MCA_BANK_COUNT] = { 66 { AMD_MSR_DC_STATUS, AMD_MSR_DC_ADDR }, 67 { AMD_MSR_IC_STATUS, AMD_MSR_IC_ADDR }, 68 { AMD_MSR_BU_STATUS, AMD_MSR_BU_ADDR }, 69 { AMD_MSR_LS_STATUS, AMD_MSR_LS_ADDR }, 70 { AMD_MSR_NB_STATUS, AMD_MSR_NB_ADDR } 71 }; 72 73 typedef struct ao_bank_cfg { 74 uint_t bank_ctl; 75 uint_t bank_ctl_mask; 76 uint64_t bank_ctl_init; 77 uint_t bank_status; 78 uint_t bank_addr; 79 } ao_bank_cfg_t; 80 81 static const ao_bank_cfg_t ao_bank_cfgs[] = { 82 { AMD_MSR_DC_CTL, AMD_MSR_DC_MASK, AMD_DC_CTL_INIT, AMD_MSR_DC_STATUS, 83 AMD_MSR_DC_ADDR }, 84 { AMD_MSR_IC_CTL, AMD_MSR_IC_MASK, AMD_IC_CTL_INIT, AMD_MSR_IC_STATUS, 85 AMD_MSR_IC_ADDR }, 86 { AMD_MSR_BU_CTL, AMD_MSR_BU_MASK, AMD_BU_CTL_INIT, AMD_MSR_BU_STATUS, 87 AMD_MSR_BU_ADDR }, 88 { AMD_MSR_LS_CTL, AMD_MSR_LS_MASK, AMD_LS_CTL_INIT, AMD_MSR_LS_STATUS, 89 AMD_MSR_LS_ADDR }, 90 { AMD_MSR_NB_CTL, AMD_MSR_NB_MASK, AMD_NB_CTL_INIT, AMD_MSR_NB_STATUS, 91 AMD_MSR_NB_ADDR } 92 }; 93 94 static const ao_error_disp_t ao_disp_unknown = { 95 FM_EREPORT_CPU_AMD_UNKNOWN, 96 FM_EREPORT_PAYLOAD_FLAGS_CPU_AMD_UNKNOWN 97 }; 98 99 /* 100 * This is quite awful but necessary to work around x86 system vendor's view of 101 * the world. Other operating systems (you know who you are) don't understand 102 * Opteron-specific error handling, so BIOS and system vendors often hide these 103 * conditions from them by using SMI polling to copy out any errors from the 104 * machine-check registers. When Solaris runs on a system with this feature, 105 * we want to disable the SMI polling so we can use FMA instead. Sadly, there 106 * isn't even a standard self-describing way to express the whole situation, 107 * so we have to resort to hard-coded values. This should all be changed to 108 * be a self-describing vendor-specific SMBIOS structure in the future. 109 */ 110 static const struct ao_smi_disable { 111 const char *asd_sys_vendor; /* SMB_TYPE_SYSTEM vendor prefix */ 112 const char *asd_bios_vendor; /* SMB_TYPE_BIOS vendor prefix */ 113 uint8_t asd_code; /* output code for SMI disable */ 114 } ao_smi_disable[] = { 115 { "Sun Microsystems", "American Megatrends", 0x59 }, 116 { NULL, NULL, 0 } 117 }; 118 119 static int 120 ao_disp_match_r4(uint16_t ref, uint8_t r4) 121 { 122 static const uint16_t ao_r4_map[] = { 123 AO_MCA_R4_BIT_GEN, /* AMD_ERRCODE_R4_GEN */ 124 AO_MCA_R4_BIT_RD, /* AMD_ERRCODE_R4_RD */ 125 AO_MCA_R4_BIT_WR, /* AMD_ERRCODE_R4_WR */ 126 AO_MCA_R4_BIT_DRD, /* AMD_ERRCODE_R4_DRD */ 127 AO_MCA_R4_BIT_DWR, /* AMD_ERRCODE_R4_DWR */ 128 AO_MCA_R4_BIT_IRD, /* AMD_ERRCODE_R4_IRD */ 129 AO_MCA_R4_BIT_PREFETCH, /* AMD_ERRCODE_R4_PREFETCH */ 130 AO_MCA_R4_BIT_EVICT, /* AMD_ERRCODE_R4_EVICT */ 131 AO_MCA_R4_BIT_SNOOP /* AMD_ERRCODE_R4_SNOOP */ 132 }; 133 134 ASSERT(r4 < sizeof (ao_r4_map) / sizeof (uint16_t)); 135 136 return ((ref & ao_r4_map[r4]) != 0); 137 } 138 139 static int 140 ao_disp_match_pp(uint8_t ref, uint8_t pp) 141 { 142 static const uint8_t ao_pp_map[] = { 143 AO_MCA_PP_BIT_SRC, /* AMD_ERRCODE_PP_SRC */ 144 AO_MCA_PP_BIT_RSP, /* AMD_ERRCODE_PP_RSP */ 145 AO_MCA_PP_BIT_OBS, /* AMD_ERRCODE_PP_OBS */ 146 AO_MCA_PP_BIT_GEN /* AMD_ERRCODE_PP_GEN */ 147 }; 148 149 ASSERT(pp < sizeof (ao_pp_map) / sizeof (uint8_t)); 150 151 return ((ref & ao_pp_map[pp]) != 0); 152 } 153 154 static int 155 ao_disp_match_ii(uint8_t ref, uint8_t ii) 156 { 157 static const uint8_t ao_ii_map[] = { 158 AO_MCA_II_BIT_MEM, /* AMD_ERRCODE_II_MEM */ 159 0, 160 AO_MCA_II_BIT_IO, /* AMD_ERRCODE_II_IO */ 161 AO_MCA_II_BIT_GEN /* AMD_ERRCODE_II_GEN */ 162 }; 163 164 ASSERT(ii < sizeof (ao_ii_map) / sizeof (uint8_t)); 165 166 return ((ref & ao_ii_map[ii]) != 0); 167 } 168 169 static uint8_t 170 bit_strip(uint16_t *codep, uint16_t mask, uint16_t shift) 171 { 172 uint8_t val = (*codep & mask) >> shift; 173 *codep &= ~mask; 174 return (val); 175 } 176 177 #define BIT_STRIP(codep, name) \ 178 bit_strip(codep, AMD_ERRCODE_##name##_MASK, AMD_ERRCODE_##name##_SHIFT) 179 180 static int 181 ao_disp_match_one(const ao_error_disp_t *aed, uint64_t status) 182 { 183 uint16_t code = status & AMD_ERRCODE_MASK; 184 uint8_t extcode = (status & AMD_ERREXT_MASK) >> AMD_ERREXT_SHIFT; 185 uint64_t stat_mask = aed->aed_stat_mask; 186 uint64_t stat_mask_res = aed->aed_stat_mask_res; 187 188 /* 189 * If the bank's status register indicates overflow, then we can no 190 * longer rely on the value of CECC: our experience with actual fault 191 * injection has shown that multiple CE's overwriting each other shows 192 * AMD_BANK_STAT_CECC and AMD_BANK_STAT_UECC both set to zero. This 193 * should be clarified in a future BKDG or by the Revision Guide. 194 */ 195 if (status & AMD_BANK_STAT_OVER) { 196 stat_mask &= ~AMD_BANK_STAT_CECC; 197 stat_mask_res &= ~AMD_BANK_STAT_CECC; 198 } 199 200 if ((status & stat_mask) != stat_mask_res) 201 return (0); 202 203 /* 204 * r4 and pp bits are stored separately, so we mask off and compare them 205 * for the code types that use them. Once we've taken the r4 and pp 206 * bits out of the equation, we can directly compare the resulting code 207 * with the one stored in the ao_error_disp_t. 208 */ 209 if (AMD_ERRCODE_ISMEM(code)) { 210 uint8_t r4 = BIT_STRIP(&code, R4); 211 212 if (!ao_disp_match_r4(aed->aed_stat_r4_bits, r4)) 213 return (0); 214 215 } else if (AMD_ERRCODE_ISBUS(code)) { 216 uint8_t r4 = BIT_STRIP(&code, R4); 217 uint8_t pp = BIT_STRIP(&code, PP); 218 uint8_t ii = BIT_STRIP(&code, II); 219 220 if (!ao_disp_match_r4(aed->aed_stat_r4_bits, r4) || 221 !ao_disp_match_pp(aed->aed_stat_pp_bits, pp) || 222 !ao_disp_match_ii(aed->aed_stat_ii_bits, ii)) 223 return (0); 224 } 225 226 return (code == aed->aed_stat_code && extcode == aed->aed_stat_extcode); 227 } 228 229 static const ao_error_disp_t * 230 ao_disp_match(uint_t bankno, uint64_t status) 231 { 232 const ao_error_disp_t *aed; 233 234 for (aed = ao_error_disp[bankno]; aed->aed_stat_mask != 0; aed++) { 235 if (ao_disp_match_one(aed, status)) 236 return (aed); 237 } 238 239 return (&ao_disp_unknown); 240 } 241 242 void 243 ao_pcicfg_write(uint_t chipid, uint_t func, uint_t reg, uint32_t val) 244 { 245 ASSERT(chipid + 24 <= 31); 246 ASSERT((func & 7) == func); 247 ASSERT((reg & 3) == 0 && reg < 256); 248 249 pci_mech1_putl(0, chipid + 24, func, reg, val); 250 } 251 252 uint32_t 253 ao_pcicfg_read(uint_t chipid, uint_t func, uint_t reg) 254 { 255 ASSERT(chipid + 24 <= 31); 256 ASSERT((func & 7) == func); 257 ASSERT((reg & 3) == 0 && reg < 256); 258 259 return (pci_mech1_getl(0, chipid + 24, func, reg)); 260 } 261 262 /* 263 * Setup individual bank detectors after stashing their bios settings. 264 */ 265 static void 266 ao_bank_cfg(ao_mca_t *mca) 267 { 268 ao_bios_cfg_t *bioscfg = &mca->ao_mca_bios_cfg; 269 const ao_bank_cfg_t *bankcfg = ao_bank_cfgs; 270 int i; 271 272 for (i = 0; i < AMD_MCA_BANK_COUNT; i++, bankcfg++) { 273 bioscfg->bcfg_bank_ctl[i] = rdmsr(bankcfg->bank_ctl); 274 bioscfg->bcfg_bank_mask[i] = rdmsr(bankcfg->bank_ctl_mask); 275 wrmsr(bankcfg->bank_ctl, bankcfg->bank_ctl_init); 276 } 277 } 278 279 /* 280 * Bits to be added to the NorthBridge (NB) configuration register. 281 * See BKDG 3.29 Section 3.6.4.2 for more information. 282 */ 283 uint32_t ao_nb_cfg_add = 284 AMD_NB_CFG_NBMCATOMSTCPUEN | 285 AMD_NB_CFG_DISPCICFGCPUERRRSP | 286 AMD_NB_CFG_SYNCONUCECCEN | 287 AMD_NB_CFG_CPUECCERREN; 288 289 /* 290 * Bits to be cleared from the NorthBridge (NB) configuration register. 291 * See BKDG 3.29 Section 3.6.4.2 for more information. 292 */ 293 uint32_t ao_nb_cfg_remove = 294 AMD_NB_CFG_IORDDATERREN | 295 AMD_NB_CFG_SYNCONANYERREN | 296 AMD_NB_CFG_SYNCONWDOGEN | 297 AMD_NB_CFG_IOERRDIS | 298 AMD_NB_CFG_IOMSTABORTDIS | 299 AMD_NB_CFG_SYNCPKTPROPDIS | 300 AMD_NB_CFG_SYNCPKTGENDIS; 301 302 /* 303 * Bits to be used if we configure the NorthBridge (NB) Watchdog. The watchdog 304 * triggers a machine check exception when no response to an NB system access 305 * occurs within a specified time interval. If the BIOS (i.e. platform design) 306 * has enabled the watchdog, we leave its rate alone. If the BIOS has not 307 * enabled the watchdog, we enable it and set the rate to one specified below. 308 * To disable the watchdog, add the AMD_NB_CFG_WDOGTMRDIS bit to ao_nb_cfg_add. 309 */ 310 uint32_t ao_nb_cfg_wdog = 311 AMD_NB_CFG_WDOGTMRCNTSEL_4095 | 312 AMD_NB_CFG_WDOGTMRBASESEL_1MS; 313 314 static void 315 ao_nb_cfg(ao_mca_t *mca) 316 { 317 uint_t chipid = chip_plat_get_chipid(CPU); 318 uint32_t val; 319 320 if (chip_plat_get_clogid(CPU) != 0) 321 return; /* only configure NB once per CPU */ 322 323 /* 324 * Read the NorthBridge (NB) configuration register in PCI space, 325 * modify the settings accordingly, and store the new value back. 326 */ 327 mca->ao_mca_bios_cfg.bcfg_nb_cfg = val = 328 ao_pcicfg_read(chipid, AMD_NB_FUNC, AMD_NB_REG_CFG); 329 330 /* 331 * If the watchdog was disabled, enable it according to the policy 332 * described above. Then apply the ao_nb_cfg_[add|remove] masks. 333 */ 334 if (val & AMD_NB_CFG_WDOGTMRDIS) { 335 val &= ~AMD_NB_CFG_WDOGTMRBASESEL_MASK; 336 val &= ~AMD_NB_CFG_WDOGTMRCNTSEL_MASK; 337 val &= ~AMD_NB_CFG_WDOGTMRDIS; 338 val |= ao_nb_cfg_wdog; 339 } 340 341 val &= ~ao_nb_cfg_remove; 342 val |= ao_nb_cfg_add; 343 344 ao_pcicfg_write(chipid, AMD_NB_FUNC, AMD_NB_REG_CFG, val); 345 } 346 347 /* 348 * Capture the machine-check exception state into our per-CPU logout area, and 349 * dispatch a copy of the logout area to our error queue for ereport creation. 350 * If 'rp' is non-NULL, we're being called from trap context; otherwise we're 351 * being polled or poked by the injector. We return the number of errors 352 * found through 'np', and a boolean indicating whether the error is fatal. 353 * The caller is expected to call fm_panic() if we return fatal (non-zero). 354 */ 355 int 356 ao_mca_logout(ao_cpu_logout_t *acl, struct regs *rp, int *np) 357 { 358 int i, fatal = 0, n = 0; 359 360 acl->acl_timestamp = gethrtime_waitfree(); 361 acl->acl_mcg_status = rdmsr(IA32_MSR_MCG_STATUS); 362 acl->acl_ip = rp ? rp->r_pc : 0; 363 acl->acl_flags = 0; 364 365 /* 366 * Iterate over the banks of machine-check registers, read the address 367 * and status registers into the logout area, and clear them as we go. 368 */ 369 for (i = 0; i < AMD_MCA_BANK_COUNT; i++) { 370 ao_bank_logout_t *abl = &acl->acl_banks[i]; 371 372 abl->abl_addr = rdmsr(ao_bank_regs[i].abr_addr); 373 abl->abl_status = rdmsr(ao_bank_regs[i].abr_status); 374 375 if (abl->abl_status & AMD_BANK_STAT_VALID) 376 wrmsr(ao_bank_regs[i].abr_status, 0); 377 } 378 379 if (rp == NULL || !USERMODE(rp->r_cs)) 380 acl->acl_flags |= AO_ACL_F_PRIV; 381 382 if (ao_mca_stack_flag) 383 acl->acl_stackdepth = getpcstack(acl->acl_stack, FM_STK_DEPTH); 384 else 385 acl->acl_stackdepth = 0; 386 387 /* 388 * Clear MCG_STATUS, indicating that machine-check trap processing is 389 * complete. Once we do this, another machine-check trap can occur. 390 */ 391 wrmsr(IA32_MSR_MCG_STATUS, 0); 392 393 /* 394 * If we took a machine-check trap, then the error is fatal if the 395 * return instruction pointer is not valid in the global register. 396 */ 397 if (rp != NULL && !(acl->acl_mcg_status & MCG_STATUS_RIPV)) 398 fatal++; 399 400 /* 401 * Now iterate over the saved logout area, determining whether the 402 * error that we saw is fatal or not based upon our dispositions 403 * and the hardware's indicators of whether or not we can resume. 404 */ 405 for (i = 0; i < AMD_MCA_BANK_COUNT; i++) { 406 ao_bank_logout_t *abl = &acl->acl_banks[i]; 407 const ao_error_disp_t *aed; 408 uint8_t when; 409 410 if (!(abl->abl_status & AMD_BANK_STAT_VALID)) 411 continue; 412 413 aed = ao_disp_match(i, abl->abl_status); 414 if ((when = aed->aed_panic_when) != AO_AED_PANIC_NEVER) { 415 if ((when & AO_AED_PANIC_ALWAYS) || 416 ((when & AO_AED_PANIC_IFMCE) && rp != NULL)) { 417 fatal++; 418 } 419 } 420 421 /* 422 * If we are taking a machine-check exception and the overflow 423 * bit is set or our context is corrupt, then we must die. 424 * NOTE: This code assumes that if the overflow bit is set and 425 * we didn't take a #mc exception (i.e. the poller found it), 426 * then multiple correctable errors overwrote each other. 427 * This will need to change if we eventually use the Opteron 428 * Rev E exception mechanism for detecting correctable errors. 429 */ 430 if (rp != NULL && (abl->abl_status & 431 (AMD_BANK_STAT_OVER | AMD_BANK_STAT_PCC))) 432 fatal++; 433 434 /* 435 * If we are taking a machine-check exception and we don't 436 * recognize the error case at all, then assume it's fatal. 437 * This will need to change if we eventually use the Opteron 438 * Rev E exception mechanism for detecting correctable errors. 439 */ 440 if (rp != NULL && aed == &ao_disp_unknown) 441 fatal++; 442 443 n++; 444 } 445 446 if (n > 0) { 447 errorq_dispatch(ao_mca_queue, acl, sizeof (ao_cpu_logout_t), 448 fatal && cmi_panic_on_uncorrectable_error ? 449 ERRORQ_SYNC : ERRORQ_ASYNC); 450 } 451 452 if (np != NULL) 453 *np = n; /* return number of errors found to caller */ 454 455 return (fatal != 0); 456 } 457 458 static uint_t 459 ao_ereport_synd(ao_mca_t *mca, 460 const ao_bank_logout_t *abl, uint_t *typep, int is_nb) 461 { 462 if (is_nb) { 463 if ((mca->ao_mca_bios_cfg.bcfg_nb_cfg & 464 AMD_NB_CFG_CHIPKILLECCEN) != 0) { 465 *typep = AMD_SYNDTYPE_CHIPKILL; 466 return (AMD_NB_STAT_CKSYND(abl->abl_status)); 467 } else { 468 *typep = AMD_SYNDTYPE_ECC; 469 return (AMD_BANK_SYND(abl->abl_status)); 470 } 471 } else { 472 *typep = AMD_SYNDTYPE_ECC; 473 return (AMD_BANK_SYND(abl->abl_status)); 474 } 475 } 476 477 static void 478 ao_ereport_create_resource_elem(nvlist_t **nvlp, nv_alloc_t *nva, 479 mc_unum_t *unump, int dimmnum) 480 { 481 nvlist_t *snvl; 482 *nvlp = fm_nvlist_create(nva); /* freed by caller */ 483 484 snvl = fm_nvlist_create(nva); 485 486 (void) nvlist_add_uint64(snvl, FM_FMRI_HC_SPECIFIC_OFFSET, 487 unump->unum_offset); 488 489 fm_fmri_hc_set(*nvlp, FM_HC_SCHEME_VERSION, NULL, snvl, 4, 490 "motherboard", unump->unum_board, 491 "chip", unump->unum_chip, 492 "memory-controller", unump->unum_mc, 493 "dimm", unump->unum_dimms[dimmnum]); 494 495 fm_nvlist_destroy(snvl, nva ? FM_NVA_RETAIN : FM_NVA_FREE); 496 } 497 498 static void 499 ao_ereport_add_resource(nvlist_t *payload, nv_alloc_t *nva, mc_unum_t *unump) 500 { 501 502 nvlist_t *elems[MC_UNUM_NDIMM]; 503 int nelems = 0; 504 int i; 505 506 for (i = 0; i < MC_UNUM_NDIMM; i++) { 507 if (unump->unum_dimms[i] == -1) 508 break; 509 ao_ereport_create_resource_elem(&elems[nelems++], nva, 510 unump, i); 511 } 512 513 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RESOURCE, 514 DATA_TYPE_NVLIST_ARRAY, nelems, elems, NULL); 515 516 for (i = 0; i < nelems; i++) 517 fm_nvlist_destroy(elems[i], nva ? FM_NVA_RETAIN : FM_NVA_FREE); 518 } 519 520 static void 521 ao_ereport_add_logout(ao_data_t *ao, nvlist_t *payload, nv_alloc_t *nva, 522 const ao_cpu_logout_t *acl, uint_t bankno, const ao_error_disp_t *aed) 523 { 524 uint64_t members = aed->aed_ereport_members; 525 ao_mca_t *mca = &ao->ao_mca; 526 const ao_bank_logout_t *abl = &acl->acl_banks[bankno]; 527 uint_t synd, syndtype; 528 529 synd = ao_ereport_synd(mca, abl, &syndtype, bankno == AMD_MCA_BANK_NB); 530 531 if (members & FM_EREPORT_PAYLOAD_FLAG_BANK_STAT) { 532 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_BANK_STAT, 533 DATA_TYPE_UINT64, abl->abl_status, NULL); 534 } 535 536 if (members & FM_EREPORT_PAYLOAD_FLAG_BANK_NUM) { 537 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_BANK_NUM, 538 DATA_TYPE_UINT8, bankno, NULL); 539 } 540 541 if (members & FM_EREPORT_PAYLOAD_FLAG_ADDR) { 542 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_ADDR, 543 DATA_TYPE_UINT64, abl->abl_addr, NULL); 544 } 545 546 if (members & FM_EREPORT_PAYLOAD_FLAG_ADDR_VALID) { 547 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_ADDR_VALID, 548 DATA_TYPE_BOOLEAN_VALUE, (abl->abl_status & 549 AMD_BANK_STAT_ADDRV) ? B_TRUE : B_FALSE, NULL); 550 } 551 552 if (members & FM_EREPORT_PAYLOAD_FLAG_SYND) { 553 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_SYND, 554 DATA_TYPE_UINT16, synd, NULL); 555 } 556 557 if (members & FM_EREPORT_PAYLOAD_FLAG_SYND_TYPE) { 558 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_SYND_TYPE, 559 DATA_TYPE_STRING, (syndtype == AMD_SYNDTYPE_CHIPKILL ? 560 "C" : "E"), NULL); 561 } 562 563 if (members & FM_EREPORT_PAYLOAD_FLAG_IP) { 564 uint64_t ip = (acl->acl_mcg_status & MCG_STATUS_EIPV) ? 565 acl->acl_ip : 0; 566 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_IP, 567 DATA_TYPE_UINT64, ip, NULL); 568 } 569 570 if (members & FM_EREPORT_PAYLOAD_FLAG_PRIV) { 571 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_PRIV, 572 DATA_TYPE_BOOLEAN_VALUE, (acl->acl_flags & AO_ACL_F_PRIV) ? 573 B_TRUE : B_FALSE, NULL); 574 } 575 576 if (members & FM_EREPORT_PAYLOAD_FLAG_RESOURCE) { 577 mc_unum_t unum; 578 int addrvalid; 579 580 addrvalid = (members & FM_EREPORT_PAYLOAD_FLAG_ADDR) && 581 (members & FM_EREPORT_PAYLOAD_FLAG_ADDR_VALID) && 582 (abl->abl_status & AMD_BANK_STAT_ADDRV); 583 584 if (addrvalid && ao_mc_patounum(ao, abl->abl_addr, synd, 585 syndtype, &unum)) 586 ao_ereport_add_resource(payload, nva, &unum); 587 } 588 589 if (ao_mca_stack_flag && members & FM_EREPORT_PAYLOAD_FLAG_STACK) { 590 fm_payload_stack_add(payload, acl->acl_stack, 591 acl->acl_stackdepth); 592 } 593 } 594 595 static void 596 ao_ereport_post(const ao_cpu_logout_t *acl, 597 int bankno, const ao_error_disp_t *aed) 598 { 599 ao_data_t *ao = acl->acl_ao; 600 errorq_elem_t *eqep, *scr_eqep; 601 nvlist_t *ereport, *detector; 602 nv_alloc_t *nva = NULL; 603 char buf[FM_MAX_CLASS]; 604 605 if (panicstr) { 606 if ((eqep = errorq_reserve(ereport_errorq)) == NULL) 607 return; 608 ereport = errorq_elem_nvl(ereport_errorq, eqep); 609 610 /* 611 * Now try to allocate another element for scratch space and 612 * use that for further scratch space (eg for constructing 613 * nvlists to add the main ereport). If we can't reserve 614 * a scratch element just fallback to working within the 615 * element we already have, and hope for the best. All this 616 * is necessary because the fixed buffer nv allocator does 617 * not reclaim freed space and nvlist construction is 618 * expensive. 619 */ 620 if ((scr_eqep = errorq_reserve(ereport_errorq)) != NULL) 621 nva = errorq_elem_nva(ereport_errorq, scr_eqep); 622 else 623 nva = errorq_elem_nva(ereport_errorq, eqep); 624 } else { 625 ereport = fm_nvlist_create(NULL); 626 } 627 628 /* 629 * Create the scheme "cpu" FMRI 630 */ 631 detector = ao_fmri_create(ao, nva); 632 633 /* 634 * Encode all the common data into the ereport. 635 */ 636 (void) snprintf(buf, FM_MAX_CLASS, "%s.%s.%s", 637 FM_ERROR_CPU, "amd", aed->aed_class); 638 639 fm_ereport_set(ereport, FM_EREPORT_VERSION, buf, 640 fm_ena_generate_cpu(acl->acl_timestamp, ao->ao_cpu->cpu_id, 641 FM_ENA_FMT1), detector, NULL); 642 643 /* 644 * We're done with 'detector' so reclaim the scratch space. 645 */ 646 if (panicstr) { 647 fm_nvlist_destroy(detector, FM_NVA_RETAIN); 648 nv_alloc_reset(nva); 649 } else { 650 fm_nvlist_destroy(detector, FM_NVA_FREE); 651 } 652 653 /* 654 * Encode the error-specific data that was saved in the logout area. 655 */ 656 ao_ereport_add_logout(ao, ereport, nva, acl, bankno, aed); 657 658 if (panicstr) { 659 errorq_commit(ereport_errorq, eqep, ERRORQ_SYNC); 660 if (scr_eqep) 661 errorq_cancel(ereport_errorq, scr_eqep); 662 } else { 663 (void) fm_ereport_post(ereport, EVCH_TRYHARD); 664 fm_nvlist_destroy(ereport, FM_NVA_FREE); 665 } 666 } 667 668 /*ARGSUSED*/ 669 void 670 ao_mca_drain(void *ignored, const void *data, const errorq_elem_t *eqe) 671 { 672 const ao_cpu_logout_t *acl = data; 673 int i; 674 675 for (i = 0; i < AMD_MCA_BANK_COUNT; i++) { 676 const ao_bank_logout_t *abl = &acl->acl_banks[i]; 677 const ao_error_disp_t *aed; 678 679 if (abl->abl_status & AMD_BANK_STAT_VALID) { 680 aed = ao_disp_match(i, abl->abl_status); 681 ao_ereport_post(acl, i, aed); 682 } 683 } 684 } 685 686 int 687 ao_mca_trap(void *data, struct regs *rp) 688 { 689 ao_data_t *ao = data; 690 ao_mca_t *mca = &ao->ao_mca; 691 ao_cpu_logout_t *acl = &mca->ao_mca_logout[AO_MCA_LOGOUT_EXCEPTION]; 692 return (ao_mca_logout(acl, rp, NULL)); 693 } 694 695 /*ARGSUSED*/ 696 int 697 ao_mca_inject(void *data, cmi_mca_regs_t *regs, uint_t nregs) 698 { 699 uint64_t hwcr, oldhwcr; 700 int i; 701 702 oldhwcr = rdmsr(MSR_AMD_HWCR); 703 hwcr = oldhwcr | AMD_HWCR_MCI_STATUS_WREN; 704 wrmsr(MSR_AMD_HWCR, hwcr); 705 706 for (i = 0; i < nregs; i++) 707 wrmsr(regs[i].cmr_msrnum, regs[i].cmr_msrval); 708 709 wrmsr(MSR_AMD_HWCR, oldhwcr); 710 return (0); 711 } 712 713 void 714 ao_mca_init(void *data) 715 { 716 ao_data_t *ao = data; 717 ao_mca_t *mca = &ao->ao_mca; 718 uint64_t cap; 719 int i; 720 721 ao_mca_poll_init(mca); 722 723 ASSERT(x86_feature & X86_MCA); 724 cap = rdmsr(IA32_MSR_MCG_CAP); 725 ASSERT(cap & MCG_CAP_CTL_P); 726 727 /* 728 * If the hardware's bank count is different than what we expect, then 729 * we're running on some Opteron variant that we don't understand yet. 730 */ 731 if ((cap & MCG_CAP_COUNT_MASK) != AMD_MCA_BANK_COUNT) { 732 cmn_err(CE_WARN, "CPU %d has %llu MCA banks; expected %u: " 733 "disabling MCA on this CPU", ao->ao_cpu->cpu_id, 734 (u_longlong_t)cap & MCG_CAP_COUNT_MASK, AMD_MCA_BANK_COUNT); 735 return; 736 } 737 738 /* 739 * Configure the logout areas. We preset every logout area's acl_ao 740 * pointer to refer back to our per-CPU state for errorq drain usage. 741 */ 742 for (i = 0; i < AO_MCA_LOGOUT_NUM; i++) 743 mca->ao_mca_logout[i].acl_ao = ao; 744 745 ao_bank_cfg(mca); 746 ao_nb_cfg(mca); 747 748 wrmsr(IA32_MSR_MCG_CTL, AMD_MCG_EN_ALL); 749 750 /* 751 * Throw away all existing bank state. We do this because some BIOSes, 752 * perhaps during POST, do things to the machine that cause MCA state 753 * to be updated. If we interpret this state as an actual error, we 754 * may end up indicting something that's not actually broken. 755 */ 756 for (i = 0; i < sizeof (ao_bank_cfgs) / sizeof (ao_bank_cfg_t); i++) 757 wrmsr(ao_bank_cfgs[i].bank_status, 0ULL); 758 759 wrmsr(IA32_MSR_MCG_STATUS, 0ULL); 760 membar_producer(); 761 762 setcr4(getcr4() | CR4_MCE); /* enable #mc exceptions */ 763 } 764 765 /* 766 * Note that although this cpu module is loaded before the PSMs are 767 * loaded (and hence before acpica is loaded), this function is 768 * called from post_startup(), after PSMs are initialized and acpica 769 * is loaded. 770 */ 771 static int 772 ao_acpi_find_smicmd(int *asd_port) 773 { 774 FADT_DESCRIPTOR *fadt = NULL; 775 776 /* 777 * AcpiGetFirmwareTable works even if ACPI is disabled, so a failure 778 * here means we weren't able to retreive a pointer to the FADT. 779 */ 780 if (AcpiGetFirmwareTable(FADT_SIG, 1, ACPI_LOGICAL_ADDRESSING, 781 (ACPI_TABLE_HEADER **)&fadt) != AE_OK) 782 return (-1); 783 784 ASSERT(fadt != NULL); 785 786 *asd_port = fadt->SmiCmd; 787 return (0); 788 } 789 790 /*ARGSUSED*/ 791 void 792 ao_mca_post_init(void *data) 793 { 794 const struct ao_smi_disable *asd; 795 id_t id; 796 int rv = -1, asd_port; 797 798 smbios_system_t sy; 799 smbios_bios_t sb; 800 smbios_info_t si; 801 802 /* 803 * Fetch the System and BIOS vendor strings from SMBIOS and see if they 804 * match a value in our table. If so, disable SMI error polling. This 805 * is grotesque and should be replaced by self-describing vendor- 806 * specific SMBIOS data or a specification enhancement instead. 807 */ 808 if (ao_mca_smi_disable && ksmbios != NULL && 809 smbios_info_bios(ksmbios, &sb) != SMB_ERR && 810 (id = smbios_info_system(ksmbios, &sy)) != SMB_ERR && 811 smbios_info_common(ksmbios, id, &si) != SMB_ERR) { 812 813 for (asd = ao_smi_disable; asd->asd_sys_vendor != NULL; asd++) { 814 if (strncmp(asd->asd_sys_vendor, si.smbi_manufacturer, 815 strlen(asd->asd_sys_vendor)) != 0 || 816 strncmp(asd->asd_bios_vendor, sb.smbb_vendor, 817 strlen(asd->asd_bios_vendor)) != 0) 818 continue; 819 820 /* 821 * Look for the SMI_CMD port in the ACPI FADT, 822 * if the port is 0, this platform doesn't support 823 * SMM, so there is no SMI error polling to disable. 824 */ 825 if ((rv = ao_acpi_find_smicmd(&asd_port)) == 0 && 826 asd_port != 0) { 827 cmn_err(CE_CONT, "?SMI polling disabled in " 828 "favor of Solaris Fault Management for " 829 "AMD Processors\n"); 830 831 outb(asd_port, asd->asd_code); 832 833 } else if (rv < 0) { 834 cmn_err(CE_CONT, "?Solaris Fault Management " 835 "for AMD Processors could not disable SMI " 836 "polling because an error occurred while " 837 "trying to determine the SMI command port " 838 "from the ACPI FADT table\n"); 839 } 840 break; 841 } 842 } 843 844 ao_mca_poll_start(); 845 } 846 847 /* 848 * Called after a CPU has been marked with CPU_FAULTED. Not called on the 849 * faulted CPU. cpu_lock is held. 850 */ 851 /*ARGSUSED*/ 852 void 853 ao_faulted_enter(void *data) 854 { 855 /* 856 * Nothing to do here. We'd like to turn off the faulted CPU's 857 * correctable error detectors, but that can only be done by the 858 * faulted CPU itself. cpu_get_state() will now return P_FAULTED, 859 * allowing the poller to skip this CPU until it is re-enabled. 860 */ 861 } 862 863 /* 864 * Called after the CPU_FAULTED bit has been cleared from a previously-faulted 865 * CPU. Not called on the faulted CPU. cpu_lock is held. 866 */ 867 void 868 ao_faulted_exit(void *data) 869 { 870 ao_data_t *ao = data; 871 872 /* 873 * We'd like to clear the faulted CPU's MCi_STATUS registers so as to 874 * avoid generating ereports for errors which occurred while the CPU was 875 * officially faulted. Unfortunately, those registers can only be 876 * cleared by the CPU itself, so we can't do it here. 877 * 878 * We're going to set the UNFAULTING bit on the formerly-faulted CPU's 879 * MCA state. This will tell the poller that the MCi_STATUS registers 880 * can't yet be trusted. The poller, which is the first thing we 881 * control that'll execute on that CPU, will clear the registers, and 882 * will then clear the bit. 883 */ 884 885 ao->ao_mca.ao_mca_flags |= AO_MCA_F_UNFAULTING; 886 } 887