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 2007 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/pghw.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/mc_amd.h> 48 #include <sys/psw.h> 49 #include <sys/ddi.h> 50 #include <sys/sunddi.h> 51 #include <sys/sdt.h> 52 #include <sys/fm/util.h> 53 #include <sys/fm/protocol.h> 54 #include <sys/fm/cpu/AMD.h> 55 #include <sys/acpi/acpi.h> 56 #include <sys/acpi/acpi_pci.h> 57 #include <sys/acpica.h> 58 59 #include "ao.h" 60 #include "ao_mca_disp.h" 61 62 #define AO_REVS_FG (X86_CHIPREV_AMD_F_REV_F | X86_CHIPREV_AMD_F_REV_G) 63 64 errorq_t *ao_mca_queue; /* machine-check ereport queue */ 65 int ao_mca_stack_flag = 0; /* record stack trace in ereports */ 66 int ao_mca_smi_disable = 1; /* attempt to disable SMI polling */ 67 68 ao_bank_regs_t ao_bank_regs[AMD_MCA_BANK_COUNT] = { 69 { AMD_MSR_DC_STATUS, AMD_MSR_DC_ADDR, AMD_MSR_DC_MISC }, 70 { AMD_MSR_IC_STATUS, AMD_MSR_IC_ADDR, AMD_MSR_IC_MISC }, 71 { AMD_MSR_BU_STATUS, AMD_MSR_BU_ADDR, AMD_MSR_BU_MISC }, 72 { AMD_MSR_LS_STATUS, AMD_MSR_LS_ADDR, AMD_MSR_LS_MISC }, 73 { AMD_MSR_NB_STATUS, AMD_MSR_NB_ADDR, AMD_MSR_NB_MISC } 74 }; 75 76 struct ao_ctl_init { 77 uint32_t ctl_revmask; /* rev(s) to which this applies */ 78 uint64_t ctl_bits; /* mca ctl reg bitmask to set */ 79 }; 80 81 /* 82 * Additional NB MCA ctl initialization for revs F and G 83 */ 84 static const struct ao_ctl_init ao_nb_ctl_init[] = { 85 { AO_REVS_FG, AMD_NB_CTL_INIT_REV_FG }, 86 { X86_CHIPREV_UNKNOWN, 0 } 87 }; 88 89 typedef struct ao_bank_cfg { 90 uint_t bank_ctl; 91 uint_t bank_ctl_mask; 92 uint64_t bank_ctl_init_cmn; /* Common init value */ 93 const struct ao_ctl_init *bank_ctl_init_extra; /* Extra for each rev */ 94 void (*bank_misc_initfunc)(ao_data_t *, uint32_t); 95 uint_t bank_status; 96 uint_t bank_addr; 97 } ao_bank_cfg_t; 98 99 static void nb_mcamisc_init(ao_data_t *, uint32_t); 100 101 static const ao_bank_cfg_t ao_bank_cfgs[] = { 102 { AMD_MSR_DC_CTL, AMD_MSR_DC_MASK, AMD_DC_CTL_INIT_CMN, 103 NULL, NULL, AMD_MSR_DC_STATUS, AMD_MSR_DC_ADDR }, 104 { AMD_MSR_IC_CTL, AMD_MSR_IC_MASK, AMD_IC_CTL_INIT_CMN, 105 NULL, NULL, AMD_MSR_IC_STATUS, AMD_MSR_IC_ADDR }, 106 { AMD_MSR_BU_CTL, AMD_MSR_BU_MASK, AMD_BU_CTL_INIT_CMN, 107 NULL, NULL, AMD_MSR_BU_STATUS, AMD_MSR_BU_ADDR }, 108 { AMD_MSR_LS_CTL, AMD_MSR_LS_MASK, AMD_LS_CTL_INIT_CMN, 109 NULL, NULL, AMD_MSR_LS_STATUS, AMD_MSR_LS_ADDR }, 110 { AMD_MSR_NB_CTL, AMD_MSR_NB_MASK, AMD_NB_CTL_INIT_CMN, 111 &ao_nb_ctl_init[0], nb_mcamisc_init, 112 AMD_MSR_NB_STATUS, AMD_MSR_NB_ADDR } 113 }; 114 115 static const ao_error_disp_t ao_disp_unknown = { 116 FM_EREPORT_CPU_AMD_UNKNOWN, 117 FM_EREPORT_PAYLOAD_FLAGS_CPU_AMD_UNKNOWN 118 }; 119 120 /* 121 * This is quite awful but necessary to work around x86 system vendor's view of 122 * the world. Other operating systems (you know who you are) don't understand 123 * Opteron-specific error handling, so BIOS and system vendors often hide these 124 * conditions from them by using SMI polling to copy out any errors from the 125 * machine-check registers. When Solaris runs on a system with this feature, 126 * we want to disable the SMI polling so we can use FMA instead. Sadly, there 127 * isn't even a standard self-describing way to express the whole situation, 128 * so we have to resort to hard-coded values. This should all be changed to 129 * be a self-describing vendor-specific SMBIOS structure in the future. 130 */ 131 static const struct ao_smi_disable { 132 const char *asd_sys_vendor; /* SMB_TYPE_SYSTEM vendor prefix */ 133 const char *asd_sys_product; /* SMB_TYPE_SYSTEM product prefix */ 134 const char *asd_bios_vendor; /* SMB_TYPE_BIOS vendor prefix */ 135 uint8_t asd_code; /* output code for SMI disable */ 136 } ao_smi_disable[] = { 137 { "Sun Microsystems", "Galaxy12", 138 "American Megatrends", 0x59 }, 139 { "Sun Microsystems", "Sun Fire X4100 Server", 140 "American Megatrends", 0x59 }, 141 { "Sun Microsystems", "Sun Fire X4200 Server", 142 "American Megatrends", 0x59 }, 143 { NULL, NULL, NULL, 0 } 144 }; 145 146 static int 147 ao_disp_match_r4(uint16_t ref, uint8_t r4) 148 { 149 static const uint16_t ao_r4_map[] = { 150 AO_MCA_R4_BIT_GEN, /* AMD_ERRCODE_R4_GEN */ 151 AO_MCA_R4_BIT_RD, /* AMD_ERRCODE_R4_RD */ 152 AO_MCA_R4_BIT_WR, /* AMD_ERRCODE_R4_WR */ 153 AO_MCA_R4_BIT_DRD, /* AMD_ERRCODE_R4_DRD */ 154 AO_MCA_R4_BIT_DWR, /* AMD_ERRCODE_R4_DWR */ 155 AO_MCA_R4_BIT_IRD, /* AMD_ERRCODE_R4_IRD */ 156 AO_MCA_R4_BIT_PREFETCH, /* AMD_ERRCODE_R4_PREFETCH */ 157 AO_MCA_R4_BIT_EVICT, /* AMD_ERRCODE_R4_EVICT */ 158 AO_MCA_R4_BIT_SNOOP /* AMD_ERRCODE_R4_SNOOP */ 159 }; 160 161 ASSERT(r4 < sizeof (ao_r4_map) / sizeof (uint16_t)); 162 163 return ((ref & ao_r4_map[r4]) != 0); 164 } 165 166 static int 167 ao_disp_match_pp(uint8_t ref, uint8_t pp) 168 { 169 static const uint8_t ao_pp_map[] = { 170 AO_MCA_PP_BIT_SRC, /* AMD_ERRCODE_PP_SRC */ 171 AO_MCA_PP_BIT_RSP, /* AMD_ERRCODE_PP_RSP */ 172 AO_MCA_PP_BIT_OBS, /* AMD_ERRCODE_PP_OBS */ 173 AO_MCA_PP_BIT_GEN /* AMD_ERRCODE_PP_GEN */ 174 }; 175 176 ASSERT(pp < sizeof (ao_pp_map) / sizeof (uint8_t)); 177 178 return ((ref & ao_pp_map[pp]) != 0); 179 } 180 181 static int 182 ao_disp_match_ii(uint8_t ref, uint8_t ii) 183 { 184 static const uint8_t ao_ii_map[] = { 185 AO_MCA_II_BIT_MEM, /* AMD_ERRCODE_II_MEM */ 186 0, 187 AO_MCA_II_BIT_IO, /* AMD_ERRCODE_II_IO */ 188 AO_MCA_II_BIT_GEN /* AMD_ERRCODE_II_GEN */ 189 }; 190 191 ASSERT(ii < sizeof (ao_ii_map) / sizeof (uint8_t)); 192 193 return ((ref & ao_ii_map[ii]) != 0); 194 } 195 196 static uint8_t 197 bit_strip(uint16_t *codep, uint16_t mask, uint16_t shift) 198 { 199 uint8_t val = (*codep & mask) >> shift; 200 *codep &= ~mask; 201 return (val); 202 } 203 204 #define BIT_STRIP(codep, name) \ 205 bit_strip(codep, AMD_ERRCODE_##name##_MASK, AMD_ERRCODE_##name##_SHIFT) 206 207 static int 208 ao_disp_match_one(const ao_error_disp_t *aed, uint64_t status, uint32_t rev, 209 int bankno) 210 { 211 uint16_t code = status & AMD_ERRCODE_MASK; 212 uint8_t extcode = (status & AMD_ERREXT_MASK) >> AMD_ERREXT_SHIFT; 213 uint64_t stat_mask = aed->aed_stat_mask; 214 uint64_t stat_mask_res = aed->aed_stat_mask_res; 215 216 /* 217 * If the bank's status register indicates overflow, then we can no 218 * longer rely on the value of CECC: our experience with actual fault 219 * injection has shown that multiple CE's overwriting each other shows 220 * AMD_BANK_STAT_CECC and AMD_BANK_STAT_UECC both set to zero. This 221 * should be clarified in a future BKDG or by the Revision Guide. 222 * This behaviour is fixed in revision F. 223 */ 224 if (bankno == AMD_MCA_BANK_NB && 225 !X86_CHIPREV_ATLEAST(rev, X86_CHIPREV_AMD_F_REV_F) && 226 status & AMD_BANK_STAT_OVER) { 227 stat_mask &= ~AMD_BANK_STAT_CECC; 228 stat_mask_res &= ~AMD_BANK_STAT_CECC; 229 } 230 231 if ((status & stat_mask) != stat_mask_res) 232 return (0); 233 234 /* 235 * r4 and pp bits are stored separately, so we mask off and compare them 236 * for the code types that use them. Once we've taken the r4 and pp 237 * bits out of the equation, we can directly compare the resulting code 238 * with the one stored in the ao_error_disp_t. 239 */ 240 if (AMD_ERRCODE_ISMEM(code)) { 241 uint8_t r4 = BIT_STRIP(&code, R4); 242 243 if (!ao_disp_match_r4(aed->aed_stat_r4_bits, r4)) 244 return (0); 245 246 } else if (AMD_ERRCODE_ISBUS(code)) { 247 uint8_t r4 = BIT_STRIP(&code, R4); 248 uint8_t pp = BIT_STRIP(&code, PP); 249 uint8_t ii = BIT_STRIP(&code, II); 250 251 if (!ao_disp_match_r4(aed->aed_stat_r4_bits, r4) || 252 !ao_disp_match_pp(aed->aed_stat_pp_bits, pp) || 253 !ao_disp_match_ii(aed->aed_stat_ii_bits, ii)) 254 return (0); 255 } 256 257 return (code == aed->aed_stat_code && extcode == aed->aed_stat_extcode); 258 } 259 260 static const ao_error_disp_t * 261 ao_disp_match(uint_t bankno, uint64_t status, uint32_t rev) 262 { 263 const ao_error_disp_t *aed; 264 265 for (aed = ao_error_disp[bankno]; aed->aed_stat_mask != 0; aed++) { 266 if (ao_disp_match_one(aed, status, rev, bankno)) 267 return (aed); 268 } 269 270 return (&ao_disp_unknown); 271 } 272 273 void 274 ao_pcicfg_write(uint_t chipid, uint_t func, uint_t reg, uint32_t val) 275 { 276 ASSERT(chipid + 24 <= 31); 277 ASSERT((func & 7) == func); 278 ASSERT((reg & 3) == 0 && reg < 256); 279 280 pci_mech1_putl(0, chipid + 24, func, reg, val); 281 } 282 283 uint32_t 284 ao_pcicfg_read(uint_t chipid, uint_t func, uint_t reg) 285 { 286 ASSERT(chipid + 24 <= 31); 287 ASSERT((func & 7) == func); 288 ASSERT((reg & 3) == 0 && reg < 256); 289 290 return (pci_mech1_getl(0, chipid + 24, func, reg)); 291 } 292 293 /* 294 * ao_chip_once returns 1 if the caller should perform the operation for 295 * this chip, or 0 if some other core has already performed the operation. 296 */ 297 298 int 299 ao_chip_once(ao_data_t *ao, enum ao_cfgonce_bitnum what) 300 { 301 return (atomic_set_long_excl(&ao->ao_shared->aos_cfgonce, what) == 0 ? 302 1 : 0); 303 } 304 305 /* 306 * Setup individual bank detectors after stashing their bios settings. 307 * The 'donb' argument indicates whether this core should configured 308 * the shared NorthBridhe MSRs. 309 */ 310 static void 311 ao_bank_cfg(ao_data_t *ao, uint32_t rev, int donb) 312 { 313 ao_mca_t *mca = &ao->ao_mca; 314 struct ao_chipshared *aos = ao->ao_shared; 315 ao_bios_cfg_t *bcfg = &mca->ao_mca_bios_cfg; 316 const ao_bank_cfg_t *bankcfg = ao_bank_cfgs; 317 const struct ao_ctl_init *extrap; 318 uint64_t mcictl; 319 int i; 320 321 for (i = 0; i < AMD_MCA_BANK_COUNT; i++, bankcfg++) { 322 if (i == AMD_MCA_BANK_NB && donb == 0) { 323 bcfg->bcfg_bank_ctl[i] = 0xbaddcafe; 324 bcfg->bcfg_bank_mask[i] = 0xbaddcafe; 325 continue; 326 } else if (i == AMD_MCA_BANK_NB) { 327 aos->aos_bcfg_nb_ctl = rdmsr(bankcfg->bank_ctl); 328 aos->aos_bcfg_nb_mask = rdmsr(bankcfg->bank_ctl_mask); 329 } else { 330 bcfg->bcfg_bank_ctl[i] = rdmsr(bankcfg->bank_ctl); 331 bcfg->bcfg_bank_mask[i] = rdmsr(bankcfg->bank_ctl_mask); 332 } 333 334 /* Initialize MCi_CTL register for this bank */ 335 mcictl = bankcfg->bank_ctl_init_cmn; 336 if ((extrap = bankcfg->bank_ctl_init_extra) != NULL) { 337 while (extrap->ctl_revmask != X86_CHIPREV_UNKNOWN) { 338 if (X86_CHIPREV_MATCH(rev, extrap->ctl_revmask)) 339 mcictl |= extrap->ctl_bits; 340 extrap++; 341 } 342 } 343 wrmsr(bankcfg->bank_ctl, mcictl); 344 345 /* Initialize the MCi_MISC register for this bank */ 346 if (bankcfg->bank_misc_initfunc != NULL) 347 (bankcfg->bank_misc_initfunc)(ao, rev); 348 } 349 } 350 351 /* 352 * This knob exists in case any platform has a problem with our default 353 * policy of disabling any interrupt registered in the NB MC4_MISC 354 * register. Setting this may cause Solaris and external entities 355 * who also have an interest in this register to argue over available 356 * telemetry (so setting it is generally not recommended). 357 */ 358 int ao_nb_cfg_mc4misc_noseize = 0; 359 360 /* 361 * The BIOS may have setup to receive SMI on counter overflow. It may also 362 * have locked various fields or made them read-only. We will clear any 363 * SMI request and leave the register locked. We will also clear the 364 * counter and enable counting - while we don't use the counter it is nice 365 * to have it enabled for verification and debug work. 366 */ 367 static void 368 nb_mcamisc_init(ao_data_t *ao, uint32_t rev) 369 { 370 uint64_t hwcr, oldhwcr; 371 uint64_t val; 372 int locked; 373 374 if (!X86_CHIPREV_MATCH(rev, AO_REVS_FG)) 375 return; 376 377 ao->ao_shared->aos_bcfg_nb_misc = val = rdmsr(AMD_MSR_NB_MISC); 378 379 if (ao_nb_cfg_mc4misc_noseize) 380 return; /* stash BIOS value, but no changes */ 381 382 locked = val & AMD_NB_MISC_LOCKED; 383 384 /* 385 * The Valid bit tells us whether the CtrP bit is defined; if it 386 * is the CtrP bit tells us whether an ErrCount field is present. 387 * If not then there is nothing for us to do. 388 */ 389 if (!(val & AMD_NB_MISC_VALID) || !(val & AMD_NB_MISC_CTRP)) 390 return; 391 392 if (locked) { 393 oldhwcr = rdmsr(MSR_AMD_HWCR); 394 hwcr = oldhwcr | AMD_HWCR_MCI_STATUS_WREN; 395 wrmsr(MSR_AMD_HWCR, hwcr); 396 } 397 398 val |= AMD_NB_MISC_CNTEN; /* enable ECC error counting */ 399 val &= ~AMD_NB_MISC_ERRCOUNT_MASK; /* clear ErrCount */ 400 val &= ~AMD_NB_MISC_OVRFLW; /* clear Ovrflw */ 401 val &= ~AMD_NB_MISC_INTTYPE_MASK; /* no interrupt on overflow */ 402 val |= AMD_NB_MISC_LOCKED; 403 404 wrmsr(AMD_MSR_NB_MISC, val); 405 406 if (locked) 407 wrmsr(MSR_AMD_HWCR, oldhwcr); 408 } 409 410 /* 411 * NorthBridge (NB) MCA Configuration. 412 * 413 * We add and remove bits from the BIOS-configured value, rather than 414 * writing an absolute value. The variables ao_nb_cfg_{add,remove}_cmn and 415 * ap_nb_cfg_{add,remove}_revFG are available for modification via kmdb 416 * and /etc/system. The revision-specific adds and removes are applied 417 * after the common changes, and one write is made to the config register. 418 * These are not intended for watchdog configuration via these variables - 419 * use the watchdog policy below. 420 */ 421 422 /* 423 * Bits to be added to the NB configuration register - all revs. 424 */ 425 uint32_t ao_nb_cfg_add_cmn = AMD_NB_CFG_ADD_CMN; 426 427 /* 428 * Bits to be cleared from the NB configuration register - all revs. 429 */ 430 uint32_t ao_nb_cfg_remove_cmn = AMD_NB_CFG_REMOVE_CMN; 431 432 /* 433 * Bits to be added to the NB configuration register - revs F and G. 434 */ 435 uint32_t ao_nb_cfg_add_revFG = AMD_NB_CFG_ADD_REV_FG; 436 437 /* 438 * Bits to be cleared from the NB configuration register - revs F and G. 439 */ 440 uint32_t ao_nb_cfg_remove_revFG = AMD_NB_CFG_REMOVE_REV_FG; 441 442 struct ao_nb_cfg { 443 uint32_t cfg_revmask; 444 uint32_t *cfg_add_p; 445 uint32_t *cfg_remove_p; 446 }; 447 448 static const struct ao_nb_cfg ao_cfg_extra[] = { 449 { AO_REVS_FG, &ao_nb_cfg_add_revFG, &ao_nb_cfg_remove_revFG }, 450 { X86_CHIPREV_UNKNOWN, NULL, NULL } 451 }; 452 453 /* 454 * Bits to be used if we configure the NorthBridge (NB) Watchdog. The watchdog 455 * triggers a machine check exception when no response to an NB system access 456 * occurs within a specified time interval. 457 */ 458 uint32_t ao_nb_cfg_wdog = 459 AMD_NB_CFG_WDOGTMRCNTSEL_4095 | 460 AMD_NB_CFG_WDOGTMRBASESEL_1MS; 461 462 /* 463 * The default watchdog policy is to enable it (at the above rate) if it 464 * is disabled; if it is enabled then we leave it enabled at the rate 465 * chosen by the BIOS. 466 */ 467 enum { 468 AO_NB_WDOG_LEAVEALONE, /* Don't touch watchdog config */ 469 AO_NB_WDOG_DISABLE, /* Always disable watchdog */ 470 AO_NB_WDOG_ENABLE_IF_DISABLED, /* If disabled, enable at our rate */ 471 AO_NB_WDOG_ENABLE_FORCE_RATE /* Enable and set our rate */ 472 } ao_nb_watchdog_policy = AO_NB_WDOG_ENABLE_IF_DISABLED; 473 474 static void 475 ao_nb_cfg(ao_data_t *ao, uint32_t rev) 476 { 477 const struct ao_nb_cfg *nbcp = &ao_cfg_extra[0]; 478 uint_t chipid = pg_plat_hw_instance_id(CPU, PGHW_CHIP); 479 uint32_t val; 480 481 /* 482 * Read the NorthBridge (NB) configuration register in PCI space, 483 * modify the settings accordingly, and store the new value back. 484 */ 485 ao->ao_shared->aos_bcfg_nb_cfg = val = 486 ao_pcicfg_read(chipid, MC_FUNC_MISCCTL, MC_CTL_REG_NBCFG); 487 488 switch (ao_nb_watchdog_policy) { 489 case AO_NB_WDOG_LEAVEALONE: 490 break; 491 492 case AO_NB_WDOG_DISABLE: 493 val &= ~AMD_NB_CFG_WDOGTMRBASESEL_MASK; 494 val &= ~AMD_NB_CFG_WDOGTMRCNTSEL_MASK; 495 val |= AMD_NB_CFG_WDOGTMRDIS; 496 break; 497 498 default: 499 cmn_err(CE_NOTE, "ao_nb_watchdog_policy=%d unrecognised, " 500 "using default policy", ao_nb_watchdog_policy); 501 /*FALLTHRU*/ 502 503 case AO_NB_WDOG_ENABLE_IF_DISABLED: 504 if (val & AMD_NB_CFG_WDOGTMRDIS) 505 break; /* if enabled leave rate intact */ 506 /*FALLTHRU*/ 507 508 case AO_NB_WDOG_ENABLE_FORCE_RATE: 509 val &= ~AMD_NB_CFG_WDOGTMRBASESEL_MASK; 510 val &= ~AMD_NB_CFG_WDOGTMRCNTSEL_MASK; 511 val &= ~AMD_NB_CFG_WDOGTMRDIS; 512 val |= ao_nb_cfg_wdog; 513 break; 514 } 515 516 /* 517 * Now apply bit adds and removes, first those common to all revs 518 * and then the revision-specific ones. 519 */ 520 val &= ~ao_nb_cfg_remove_cmn; 521 val |= ao_nb_cfg_add_cmn; 522 523 while (nbcp->cfg_revmask != X86_CHIPREV_UNKNOWN) { 524 if (X86_CHIPREV_MATCH(rev, nbcp->cfg_revmask)) { 525 val &= ~(*nbcp->cfg_remove_p); 526 val |= *nbcp->cfg_add_p; 527 } 528 nbcp++; 529 } 530 531 ao_pcicfg_write(chipid, MC_FUNC_MISCCTL, MC_CTL_REG_NBCFG, val); 532 } 533 534 static void 535 ao_dram_cfg(ao_data_t *ao, uint32_t rev) 536 { 537 uint_t chipid = pg_plat_hw_instance_id(CPU, PGHW_CHIP); 538 union mcreg_dramcfg_lo dcfglo; 539 540 ao->ao_shared->aos_bcfg_dcfg_lo = MCREG_VAL32(&dcfglo) = 541 ao_pcicfg_read(chipid, MC_FUNC_DRAMCTL, MC_DC_REG_DRAMCFGLO); 542 ao->ao_shared->aos_bcfg_dcfg_hi = 543 ao_pcicfg_read(chipid, MC_FUNC_DRAMCTL, MC_DC_REG_DRAMCFGHI); 544 545 #ifdef OPTERON_ERRATUM_172 546 if (X86_CHIPREV_MATCH(rev, AO_REVS_FG) && 547 MCREG_FIELD_revFG(&dcfglo, ParEn)) { 548 MCREG_FIELD_revFG(&dcfglo, ParEn) = 0; 549 ao_pcicfg_write(chipid, MC_FUNC_DRAMCTL, MC_DC_REG_DRAMCFGLO, 550 MCREG_VAL32(&dcfglo)); 551 } 552 #endif 553 } 554 555 /* 556 * This knob exists in case any platform has a problem with our default 557 * policy of disabling any interrupt registered in the online spare 558 * control register. Setting this may cause Solaris and external entities 559 * who also have an interest in this register to argue over available 560 * telemetry (so setting it is generally not recommended). 561 */ 562 int ao_nb_cfg_sparectl_noseize = 0; 563 564 /* 565 * Setup the online spare control register (revs F and G). We disable 566 * any interrupt registered by the BIOS and zero all error counts. 567 */ 568 static void 569 ao_sparectl_cfg(ao_data_t *ao) 570 { 571 uint_t chipid = pg_plat_hw_instance_id(CPU, PGHW_CHIP); 572 union mcreg_sparectl sparectl; 573 int chan, cs; 574 575 ao->ao_shared->aos_bcfg_nb_sparectl = MCREG_VAL32(&sparectl) = 576 ao_pcicfg_read(chipid, MC_FUNC_MISCCTL, MC_CTL_REG_SPARECTL); 577 578 if (ao_nb_cfg_sparectl_noseize) 579 return; /* stash BIOS value, but no changes */ 580 581 /* 582 * If the BIOS has requested SMI interrupt type for ECC count 583 * overflow for a chip-select or channel force those off. 584 */ 585 MCREG_FIELD_revFG(&sparectl, EccErrInt) = 0; 586 MCREG_FIELD_revFG(&sparectl, SwapDoneInt) = 0; 587 588 /* Enable writing to the EccErrCnt field */ 589 MCREG_FIELD_revFG(&sparectl, EccErrCntWrEn) = 1; 590 591 /* First write, preparing for writes to EccErrCnt */ 592 ao_pcicfg_write(chipid, MC_FUNC_MISCCTL, MC_CTL_REG_SPARECTL, 593 MCREG_VAL32(&sparectl)); 594 595 /* 596 * Zero EccErrCnt and write this back to all chan/cs combinations. 597 */ 598 MCREG_FIELD_revFG(&sparectl, EccErrCnt) = 0; 599 for (chan = 0; chan < MC_CHIP_NDRAMCHAN; chan++) { 600 MCREG_FIELD_revFG(&sparectl, EccErrCntDramChan) = chan; 601 602 for (cs = 0; cs < MC_CHIP_NCS; cs++) { 603 MCREG_FIELD_revFG(&sparectl, EccErrCntDramCs) = cs; 604 ao_pcicfg_write(chipid, MC_FUNC_MISCCTL, 605 MC_CTL_REG_SPARECTL, MCREG_VAL32(&sparectl)); 606 } 607 } 608 } 609 610 /* 611 * Capture the machine-check exception state into our per-CPU logout area, and 612 * dispatch a copy of the logout area to our error queue for ereport creation. 613 * If 'rp' is non-NULL, we're being called from trap context; otherwise we're 614 * being polled or poked by the injector. We return the number of errors 615 * found through 'np', and a boolean indicating whether the error is fatal. 616 * The caller is expected to call fm_panic() if we return fatal (non-zero). 617 */ 618 int 619 ao_mca_logout(ao_cpu_logout_t *acl, struct regs *rp, int *np, int skipnb, 620 uint32_t rev) 621 { 622 uint64_t mcg_status = rdmsr(IA32_MSR_MCG_STATUS); 623 int i, fatal = 0, n = 0; 624 625 acl->acl_timestamp = gethrtime_waitfree(); 626 acl->acl_mcg_status = mcg_status; 627 acl->acl_ip = rp ? rp->r_pc : 0; 628 acl->acl_flags = 0; 629 630 /* 631 * Iterate over the banks of machine-check registers, read the address 632 * and status registers into the logout area, and clear status as we go. 633 * Also read the MCi_MISC register if MCi_STATUS.MISCV indicates that 634 * there is valid info there (as it will in revisions F and G for 635 * NorthBridge ECC errors). 636 */ 637 for (i = 0; i < AMD_MCA_BANK_COUNT; i++) { 638 ao_bank_logout_t *abl = &acl->acl_banks[i]; 639 640 if (i == AMD_MCA_BANK_NB && skipnb) { 641 abl->abl_status = 0; 642 continue; 643 } 644 645 abl->abl_addr = rdmsr(ao_bank_regs[i].abr_addr); 646 abl->abl_status = rdmsr(ao_bank_regs[i].abr_status); 647 648 if (abl->abl_status & AMD_BANK_STAT_MISCV) 649 abl->abl_misc = rdmsr(ao_bank_regs[i].abr_misc); 650 else 651 abl->abl_misc = 0; 652 653 if (abl->abl_status & AMD_BANK_STAT_VALID) 654 wrmsr(ao_bank_regs[i].abr_status, 0); 655 } 656 657 if (rp == NULL || !USERMODE(rp->r_cs)) 658 acl->acl_flags |= AO_ACL_F_PRIV; 659 660 if (ao_mca_stack_flag) 661 acl->acl_stackdepth = getpcstack(acl->acl_stack, FM_STK_DEPTH); 662 else 663 acl->acl_stackdepth = 0; 664 665 /* 666 * Clear MCG_STATUS, indicating that machine-check trap processing is 667 * complete. Once we do this, another machine-check trap can occur 668 * (if another occurs up to this point then the system will reset). 669 */ 670 if (mcg_status & MCG_STATUS_MCIP) 671 wrmsr(IA32_MSR_MCG_STATUS, 0); 672 673 /* 674 * If we took a machine-check trap, then the error is fatal if the 675 * return instruction pointer is not valid in the global register. 676 */ 677 if (rp != NULL && !(acl->acl_mcg_status & MCG_STATUS_RIPV)) 678 fatal++; 679 680 /* 681 * Now iterate over the saved logout area, determining whether the 682 * error that we saw is fatal or not based upon our dispositions 683 * and the hardware's indicators of whether or not we can resume. 684 */ 685 for (i = 0; i < AMD_MCA_BANK_COUNT; i++) { 686 ao_bank_logout_t *abl = &acl->acl_banks[i]; 687 const ao_error_disp_t *aed; 688 uint8_t when; 689 690 if (!(abl->abl_status & AMD_BANK_STAT_VALID)) 691 continue; 692 693 aed = ao_disp_match(i, abl->abl_status, rev); 694 if ((when = aed->aed_panic_when) != AO_AED_PANIC_NEVER) { 695 if ((when & AO_AED_PANIC_ALWAYS) || 696 ((when & AO_AED_PANIC_IFMCE) && rp != NULL)) { 697 fatal++; 698 } 699 } 700 701 /* 702 * If we are taking a machine-check exception and our context 703 * is corrupt, then we must die. 704 */ 705 if (rp != NULL && abl->abl_status & AMD_BANK_STAT_PCC) 706 fatal++; 707 708 /* 709 * The overflow bit is set if the bank detects an error but 710 * the valid bit of its status register is already set 711 * (software has not yet read and cleared it). Enabled 712 * (for mc# reporting) errors overwrite disabled errors, 713 * uncorrectable errors overwrite correctable errors, 714 * uncorrectable errors are not overwritten. 715 * 716 * For the NB detector bank the overflow bit will not be 717 * set for repeated correctable errors on revisions D and 718 * earlier; it will be set on revisions E and later. 719 * On revision E, however, the CorrECC bit does appear 720 * to clear in these circumstances. Since we can enable 721 * machine-check exception on NB correctables we need to 722 * be careful here; we never enable mc# for correctable from 723 * other banks. 724 * 725 * Our solution will be to declare a machine-check exception 726 * fatal if the overflow bit is set except in the case of 727 * revision F on the NB detector bank for which CorrECC 728 * is indicated. Machine-check exception for NB correctables 729 * on rev E is explicitly not supported. 730 */ 731 if (rp != NULL && abl->abl_status & AMD_BANK_STAT_OVER && 732 !(i == AMD_MCA_BANK_NB && 733 X86_CHIPREV_ATLEAST(rev, X86_CHIPREV_AMD_F_REV_F) && 734 abl->abl_status & AMD_BANK_STAT_CECC)) 735 fatal++; 736 737 /* 738 * If we are taking a machine-check exception and we don't 739 * recognize the error case at all, then assume it's fatal. 740 * This will need to change if we eventually use the Opteron 741 * Rev E exception mechanism for detecting correctable errors. 742 */ 743 if (rp != NULL && aed == &ao_disp_unknown) 744 fatal++; 745 746 abl->abl_addr_type = aed->aed_flags & AO_AED_FLAGS_ADDRTYPE; 747 abl->abl_addr_valid_hi = aed->aed_addrvalid_hi; 748 abl->abl_addr_valid_lo = aed->aed_addrvalid_lo; 749 n++; 750 } 751 752 if (n > 0) { 753 errorq_dispatch(ao_mca_queue, acl, sizeof (ao_cpu_logout_t), 754 fatal && cmi_panic_on_uncorrectable_error ? 755 ERRORQ_SYNC : ERRORQ_ASYNC); 756 } 757 758 if (np != NULL) 759 *np = n; /* return number of errors found to caller */ 760 761 return (fatal != 0); 762 } 763 764 static uint_t 765 ao_ereport_synd(ao_data_t *ao, const ao_bank_logout_t *abl, uint_t *typep, 766 int is_nb) 767 { 768 if (is_nb) { 769 if (ao->ao_shared->aos_bcfg_nb_cfg & AMD_NB_CFG_CHIPKILLECCEN) { 770 *typep = AMD_SYNDTYPE_CHIPKILL; 771 return (AMD_NB_STAT_CKSYND(abl->abl_status)); 772 } else { 773 *typep = AMD_SYNDTYPE_ECC; 774 return (AMD_BANK_SYND(abl->abl_status)); 775 } 776 } else { 777 *typep = AMD_SYNDTYPE_ECC; 778 return (AMD_BANK_SYND(abl->abl_status)); 779 } 780 } 781 782 static void 783 ao_ereport_create_resource_elem(nvlist_t **nvlp, nv_alloc_t *nva, 784 mc_unum_t *unump, int dimmnum) 785 { 786 nvlist_t *snvl; 787 *nvlp = fm_nvlist_create(nva); /* freed by caller */ 788 789 snvl = fm_nvlist_create(nva); 790 791 (void) nvlist_add_uint64(snvl, FM_FMRI_HC_SPECIFIC_OFFSET, 792 unump->unum_offset); 793 794 fm_fmri_hc_set(*nvlp, FM_HC_SCHEME_VERSION, NULL, snvl, 5, 795 "motherboard", unump->unum_board, 796 "chip", unump->unum_chip, 797 "memory-controller", unump->unum_mc, 798 "dimm", unump->unum_dimms[dimmnum], 799 "rank", unump->unum_rank); 800 801 fm_nvlist_destroy(snvl, nva ? FM_NVA_RETAIN : FM_NVA_FREE); 802 } 803 804 static void 805 ao_ereport_add_resource(nvlist_t *payload, nv_alloc_t *nva, mc_unum_t *unump) 806 { 807 808 nvlist_t *elems[MC_UNUM_NDIMM]; 809 int nelems = 0; 810 int i; 811 812 for (i = 0; i < MC_UNUM_NDIMM; i++) { 813 if (unump->unum_dimms[i] == MC_INVALNUM) 814 break; 815 ao_ereport_create_resource_elem(&elems[nelems++], nva, 816 unump, i); 817 } 818 819 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RESOURCE, 820 DATA_TYPE_NVLIST_ARRAY, nelems, elems, NULL); 821 822 for (i = 0; i < nelems; i++) 823 fm_nvlist_destroy(elems[i], nva ? FM_NVA_RETAIN : FM_NVA_FREE); 824 } 825 826 static void 827 ao_ereport_add_logout(ao_data_t *ao, nvlist_t *payload, nv_alloc_t *nva, 828 const ao_cpu_logout_t *acl, uint_t bankno, const ao_error_disp_t *aed) 829 { 830 uint64_t members = aed->aed_ereport_members; 831 const ao_bank_logout_t *abl = &acl->acl_banks[bankno]; 832 uint_t synd, syndtype; 833 834 synd = ao_ereport_synd(ao, abl, &syndtype, bankno == AMD_MCA_BANK_NB); 835 836 if (members & FM_EREPORT_PAYLOAD_FLAG_BANK_STAT) { 837 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_BANK_STAT, 838 DATA_TYPE_UINT64, abl->abl_status, NULL); 839 } 840 841 if (members & FM_EREPORT_PAYLOAD_FLAG_BANK_NUM) { 842 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_BANK_NUM, 843 DATA_TYPE_UINT8, bankno, NULL); 844 } 845 846 if (members & FM_EREPORT_PAYLOAD_FLAG_ADDR) { 847 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_ADDR, 848 DATA_TYPE_UINT64, abl->abl_addr, NULL); 849 } 850 851 if (members & FM_EREPORT_PAYLOAD_FLAG_ADDR_VALID) { 852 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_ADDR_VALID, 853 DATA_TYPE_BOOLEAN_VALUE, (abl->abl_status & 854 AMD_BANK_STAT_ADDRV) ? B_TRUE : B_FALSE, NULL); 855 } 856 857 if (members & FM_EREPORT_PAYLOAD_FLAG_BANK_MISC) { 858 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_BANK_MISC, 859 DATA_TYPE_UINT64, abl->abl_misc, NULL); 860 } 861 862 if (members & FM_EREPORT_PAYLOAD_FLAG_SYND) { 863 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_SYND, 864 DATA_TYPE_UINT16, synd, NULL); 865 } 866 867 if (members & FM_EREPORT_PAYLOAD_FLAG_SYND_TYPE) { 868 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_SYND_TYPE, 869 DATA_TYPE_STRING, (syndtype == AMD_SYNDTYPE_CHIPKILL ? 870 "C" : "E"), NULL); 871 } 872 873 if (members & FM_EREPORT_PAYLOAD_FLAG_IP) { 874 uint64_t ip = (acl->acl_mcg_status & MCG_STATUS_EIPV) ? 875 acl->acl_ip : 0; 876 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_IP, 877 DATA_TYPE_UINT64, ip, NULL); 878 } 879 880 if (members & FM_EREPORT_PAYLOAD_FLAG_PRIV) { 881 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_PRIV, 882 DATA_TYPE_BOOLEAN_VALUE, (acl->acl_flags & AO_ACL_F_PRIV) ? 883 B_TRUE : B_FALSE, NULL); 884 } 885 886 if (members & FM_EREPORT_PAYLOAD_FLAG_RESOURCE) { 887 mc_unum_t unum; 888 int addrvalid = 0; 889 890 if (abl->abl_addr_type & AO_AED_F_PHYSICAL) { 891 addrvalid = (members & FM_EREPORT_PAYLOAD_FLAG_ADDR) && 892 (members & FM_EREPORT_PAYLOAD_FLAG_ADDR_VALID) && 893 (abl->abl_status & AMD_BANK_STAT_ADDRV); 894 } 895 896 if (addrvalid && ao_mc_patounum(ao, abl->abl_addr, 897 abl->abl_addr_valid_hi, abl->abl_addr_valid_lo, 898 synd, syndtype, &unum)) 899 ao_ereport_add_resource(payload, nva, &unum); 900 } 901 902 if (ao_mca_stack_flag && members & FM_EREPORT_PAYLOAD_FLAG_STACK) { 903 fm_payload_stack_add(payload, acl->acl_stack, 904 acl->acl_stackdepth); 905 } 906 } 907 908 static void 909 ao_ereport_post(const ao_cpu_logout_t *acl, 910 int bankno, const ao_error_disp_t *aed) 911 { 912 ao_data_t *ao = acl->acl_ao; 913 errorq_elem_t *eqep, *scr_eqep; 914 nvlist_t *ereport, *detector; 915 nv_alloc_t *nva = NULL; 916 char buf[FM_MAX_CLASS]; 917 918 if (panicstr) { 919 if ((eqep = errorq_reserve(ereport_errorq)) == NULL) 920 return; 921 ereport = errorq_elem_nvl(ereport_errorq, eqep); 922 923 /* 924 * Now try to allocate another element for scratch space and 925 * use that for further scratch space (eg for constructing 926 * nvlists to add the main ereport). If we can't reserve 927 * a scratch element just fallback to working within the 928 * element we already have, and hope for the best. All this 929 * is necessary because the fixed buffer nv allocator does 930 * not reclaim freed space and nvlist construction is 931 * expensive. 932 */ 933 if ((scr_eqep = errorq_reserve(ereport_errorq)) != NULL) 934 nva = errorq_elem_nva(ereport_errorq, scr_eqep); 935 else 936 nva = errorq_elem_nva(ereport_errorq, eqep); 937 } else { 938 ereport = fm_nvlist_create(NULL); 939 } 940 941 /* 942 * Create the "hc" scheme detector FMRI identifying this cpu 943 */ 944 detector = ao_fmri_create(ao, nva); 945 946 /* 947 * Encode all the common data into the ereport. 948 */ 949 (void) snprintf(buf, FM_MAX_CLASS, "%s.%s.%s", 950 FM_ERROR_CPU, "amd", aed->aed_class); 951 952 fm_ereport_set(ereport, FM_EREPORT_VERSION, buf, 953 fm_ena_generate_cpu(acl->acl_timestamp, ao->ao_cpu->cpu_id, 954 FM_ENA_FMT1), detector, NULL); 955 956 /* 957 * We're done with 'detector' so reclaim the scratch space. 958 */ 959 if (panicstr) { 960 fm_nvlist_destroy(detector, FM_NVA_RETAIN); 961 nv_alloc_reset(nva); 962 } else { 963 fm_nvlist_destroy(detector, FM_NVA_FREE); 964 } 965 966 /* 967 * Encode the error-specific data that was saved in the logout area. 968 */ 969 ao_ereport_add_logout(ao, ereport, nva, acl, bankno, aed); 970 971 if (panicstr) { 972 errorq_commit(ereport_errorq, eqep, ERRORQ_SYNC); 973 if (scr_eqep) 974 errorq_cancel(ereport_errorq, scr_eqep); 975 } else { 976 (void) fm_ereport_post(ereport, EVCH_TRYHARD); 977 fm_nvlist_destroy(ereport, FM_NVA_FREE); 978 } 979 } 980 981 /*ARGSUSED*/ 982 void 983 ao_mca_drain(void *ignored, const void *data, const errorq_elem_t *eqe) 984 { 985 const ao_cpu_logout_t *acl = data; 986 uint32_t rev = acl->acl_ao->ao_shared->aos_chiprev; 987 int i; 988 989 for (i = 0; i < AMD_MCA_BANK_COUNT; i++) { 990 const ao_bank_logout_t *abl = &acl->acl_banks[i]; 991 const ao_error_disp_t *aed; 992 993 if (abl->abl_status & AMD_BANK_STAT_VALID) { 994 aed = ao_disp_match(i, abl->abl_status, rev); 995 ao_ereport_post(acl, i, aed); 996 } 997 } 998 } 999 1000 /* 1001 * Machine check interrupt handler - we jump here from mcetrap. 1002 * 1003 * A sibling core may attempt to poll the NorthBridge during the 1004 * time we are performing the logout. So we coordinate NB access 1005 * of all cores of the same chip via a per-chip lock. If the lock 1006 * is held on a sibling core then we spin for it here; if the 1007 * lock is held by the thread we have interrupted then we do 1008 * not acquire the lock but can proceed safe in the knowledge that 1009 * the lock owner can't actually perform any NB accesses. This 1010 * requires that threads that take the aos_nb_poll_lock do not 1011 * block and that they disable preemption while they hold the lock. 1012 * It also requires that the lock be adaptive since mutex_owner does 1013 * not work for spin locks. 1014 */ 1015 static int ao_mca_path1, ao_mca_path2; 1016 int 1017 ao_mca_trap(void *data, struct regs *rp) 1018 { 1019 ao_data_t *ao = data; 1020 ao_mca_t *mca = &ao->ao_mca; 1021 ao_cpu_logout_t *acl = &mca->ao_mca_logout[AO_MCA_LOGOUT_EXCEPTION]; 1022 kmutex_t *nblock = NULL; 1023 int tooklock = 0; 1024 int rv; 1025 1026 if (ao->ao_shared != NULL) 1027 nblock = &ao->ao_shared->aos_nb_poll_lock; 1028 1029 if (nblock && !mutex_owned(nblock)) { 1030 /* 1031 * The mutex is not owned by the thread we have interrupted 1032 * (since the holder may not block or be preempted once the 1033 * lock is acquired). We will spin for this adaptive lock. 1034 */ 1035 ++ao_mca_path1; 1036 while (!mutex_tryenter(nblock)) { 1037 while (mutex_owner(nblock) != NULL) 1038 ; 1039 } 1040 tooklock = 1; 1041 } else { 1042 ++ao_mca_path2; 1043 } 1044 1045 rv = ao_mca_logout(acl, rp, NULL, 0, ao->ao_shared->aos_chiprev); 1046 1047 if (tooklock) 1048 mutex_exit(&ao->ao_shared->aos_nb_poll_lock); 1049 1050 return (rv); 1051 } 1052 1053 /*ARGSUSED*/ 1054 int 1055 ao_mca_inject(void *data, cmi_mca_regs_t *regs, uint_t nregs) 1056 { 1057 uint64_t hwcr, oldhwcr; 1058 int i; 1059 1060 oldhwcr = rdmsr(MSR_AMD_HWCR); 1061 hwcr = oldhwcr | AMD_HWCR_MCI_STATUS_WREN; 1062 wrmsr(MSR_AMD_HWCR, hwcr); 1063 1064 for (i = 0; i < nregs; i++) 1065 wrmsr(regs[i].cmr_msrnum, regs[i].cmr_msrval); 1066 1067 wrmsr(MSR_AMD_HWCR, oldhwcr); 1068 return (0); 1069 } 1070 1071 void 1072 ao_mca_init(void *data) 1073 { 1074 ao_data_t *ao = data; 1075 ao_mca_t *mca = &ao->ao_mca; 1076 uint64_t cap = rdmsr(IA32_MSR_MCG_CAP); 1077 uint32_t rev; 1078 int donb, dodcfg; 1079 int i; 1080 1081 /* 1082 * cmi_mca_init is only called during cpu startup if features include 1083 * X86_MCA (defined as both MCA and MCE support indicated by CPUID). 1084 * Furthermore, our ao_init function returns ENOTSUP if features 1085 * lacked X86_MCA, IA32_MSR_MCG_CAP lacks MCG_CAP_CTL_P, or the 1086 * cpu has an unexpected number of detector banks. 1087 */ 1088 ASSERT(x86_feature & X86_MCA); 1089 ASSERT(cap & MCG_CAP_CTL_P); 1090 ASSERT((cap & MCG_CAP_COUNT_MASK) == AMD_MCA_BANK_COUNT); 1091 1092 /* 1093 * Configure the logout areas. We preset every logout area's acl_ao 1094 * pointer to refer back to our per-CPU state for errorq drain usage. 1095 */ 1096 for (i = 0; i < AO_MCA_LOGOUT_NUM; i++) 1097 mca->ao_mca_logout[i].acl_ao = ao; 1098 1099 /* LINTED: logical expression always true */ 1100 ASSERT(sizeof (ao_bank_cfgs) / sizeof (ao_bank_cfg_t) == 1101 AMD_MCA_BANK_COUNT); 1102 1103 rev = ao->ao_shared->aos_chiprev = cpuid_getchiprev(ao->ao_cpu); 1104 1105 /* 1106 * Must this core perform NB MCA or DRAM configuration? This must be 1107 * done by just one core. 1108 */ 1109 donb = ao_chip_once(ao, AO_CFGONCE_NBMCA); 1110 dodcfg = ao_chip_once(ao, AO_CFGONCE_DRAMCFG); 1111 1112 /* 1113 * Initialize poller data, but don't start polling yet. 1114 */ 1115 ao_mca_poll_init(ao, donb); 1116 1117 /* 1118 * Configure the bank MCi_CTL register to nominate which error 1119 * types for each bank will produce a machine-check (we'll poll 1120 * for others). Correctable error types mentioned in these MCi_CTL 1121 * settings won't actually produce an exception unless an additional 1122 * (and undocumented) bit is set elsewhere - the poller must still 1123 * handle these. 1124 */ 1125 ao_bank_cfg(ao, rev, donb); 1126 1127 /* 1128 * Modify the MCA NB Configuration and Dram Configuration Registers. 1129 */ 1130 if (donb) 1131 ao_nb_cfg(ao, rev); 1132 if (dodcfg) 1133 ao_dram_cfg(ao, rev); 1134 1135 /* 1136 * Setup the Online Spare Control Register 1137 */ 1138 if (donb && X86_CHIPREV_MATCH(rev, AO_REVS_FG)) { 1139 ao_sparectl_cfg(ao); 1140 } 1141 1142 /* 1143 * Enable all error reporting banks (icache, dcache, ...). This 1144 * enables error detection, as opposed to error reporting above. 1145 */ 1146 wrmsr(IA32_MSR_MCG_CTL, AMD_MCG_EN_ALL); 1147 1148 /* 1149 * Throw away all existing bank state. We do this because some BIOSes, 1150 * perhaps during POST, do things to the machine that cause MCA state 1151 * to be updated. If we interpret this state as an actual error, we 1152 * may end up indicting something that's not actually broken. 1153 */ 1154 for (i = 0; i < AMD_MCA_BANK_COUNT; i++) { 1155 if (!donb) 1156 continue; 1157 1158 wrmsr(ao_bank_cfgs[i].bank_status, 0ULL); 1159 } 1160 1161 wrmsr(IA32_MSR_MCG_STATUS, 0ULL); 1162 membar_producer(); 1163 1164 setcr4(getcr4() | CR4_MCE); /* enable #mc exceptions */ 1165 } 1166 1167 /* 1168 * Note that although this cpu module is loaded before the PSMs are 1169 * loaded (and hence before acpica is loaded), this function is 1170 * called from post_startup(), after PSMs are initialized and acpica 1171 * is loaded. 1172 */ 1173 static int 1174 ao_acpi_find_smicmd(int *asd_port) 1175 { 1176 FADT_DESCRIPTOR *fadt = NULL; 1177 1178 /* 1179 * AcpiGetFirmwareTable works even if ACPI is disabled, so a failure 1180 * here means we weren't able to retreive a pointer to the FADT. 1181 */ 1182 if (AcpiGetFirmwareTable(FADT_SIG, 1, ACPI_LOGICAL_ADDRESSING, 1183 (ACPI_TABLE_HEADER **)&fadt) != AE_OK) 1184 return (-1); 1185 1186 ASSERT(fadt != NULL); 1187 1188 *asd_port = fadt->SmiCmd; 1189 return (0); 1190 } 1191 1192 /*ARGSUSED*/ 1193 void 1194 ao_mca_post_init(void *data) 1195 { 1196 const struct ao_smi_disable *asd; 1197 id_t id; 1198 int rv = -1, asd_port; 1199 1200 smbios_system_t sy; 1201 smbios_bios_t sb; 1202 smbios_info_t si; 1203 1204 /* 1205 * Fetch the System and BIOS vendor strings from SMBIOS and see if they 1206 * match a value in our table. If so, disable SMI error polling. This 1207 * is grotesque and should be replaced by self-describing vendor- 1208 * specific SMBIOS data or a specification enhancement instead. 1209 */ 1210 if (ao_mca_smi_disable && ksmbios != NULL && 1211 smbios_info_bios(ksmbios, &sb) != SMB_ERR && 1212 (id = smbios_info_system(ksmbios, &sy)) != SMB_ERR && 1213 smbios_info_common(ksmbios, id, &si) != SMB_ERR) { 1214 1215 for (asd = ao_smi_disable; asd->asd_sys_vendor != NULL; asd++) { 1216 if (strncmp(asd->asd_sys_vendor, si.smbi_manufacturer, 1217 strlen(asd->asd_sys_vendor)) != 0 || 1218 strncmp(asd->asd_sys_product, si.smbi_product, 1219 strlen(asd->asd_sys_product)) != 0 || 1220 strncmp(asd->asd_bios_vendor, sb.smbb_vendor, 1221 strlen(asd->asd_bios_vendor)) != 0) 1222 continue; 1223 1224 /* 1225 * Look for the SMI_CMD port in the ACPI FADT, 1226 * if the port is 0, this platform doesn't support 1227 * SMM, so there is no SMI error polling to disable. 1228 */ 1229 if ((rv = ao_acpi_find_smicmd(&asd_port)) == 0 && 1230 asd_port != 0) { 1231 cmn_err(CE_CONT, "?SMI polling disabled in " 1232 "favor of Solaris Fault Management for " 1233 "AMD Processors\n"); 1234 1235 outb(asd_port, asd->asd_code); 1236 1237 } else if (rv < 0) { 1238 cmn_err(CE_CONT, "?Solaris Fault Management " 1239 "for AMD Processors could not disable SMI " 1240 "polling because an error occurred while " 1241 "trying to determine the SMI command port " 1242 "from the ACPI FADT table\n"); 1243 } 1244 break; 1245 } 1246 } 1247 1248 ao_mca_poll_start(); 1249 } 1250 1251 /* 1252 * Called after a CPU has been marked with CPU_FAULTED. Not called on the 1253 * faulted CPU. cpu_lock is held. 1254 */ 1255 /*ARGSUSED*/ 1256 void 1257 ao_faulted_enter(void *data) 1258 { 1259 /* 1260 * Nothing to do here. We'd like to turn off the faulted CPU's 1261 * correctable error detectors, but that can only be done by the 1262 * faulted CPU itself. cpu_get_state() will now return P_FAULTED, 1263 * allowing the poller to skip this CPU until it is re-enabled. 1264 */ 1265 } 1266 1267 /* 1268 * Called after the CPU_FAULTED bit has been cleared from a previously-faulted 1269 * CPU. Not called on the faulted CPU. cpu_lock is held. 1270 */ 1271 void 1272 ao_faulted_exit(void *data) 1273 { 1274 ao_data_t *ao = data; 1275 1276 /* 1277 * We'd like to clear the faulted CPU's MCi_STATUS registers so as to 1278 * avoid generating ereports for errors which occurred while the CPU was 1279 * officially faulted. Unfortunately, those registers can only be 1280 * cleared by the CPU itself, so we can't do it here. 1281 * 1282 * We're going to set the UNFAULTING bit on the formerly-faulted CPU's 1283 * MCA state. This will tell the poller that the MCi_STATUS registers 1284 * can't yet be trusted. The poller, which is the first thing we 1285 * control that'll execute on that CPU, will clear the registers, and 1286 * will then clear the bit. 1287 */ 1288 1289 ao->ao_mca.ao_mca_flags |= AO_MCA_F_UNFAULTING; 1290 } 1291