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 * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved. 23 */ 24 25 /* 26 * PCI ECC support 27 */ 28 29 #include <sys/types.h> 30 #include <sys/systm.h> /* for strrchr */ 31 #include <sys/kmem.h> 32 #include <sys/sunddi.h> 33 #include <sys/intr.h> 34 #include <sys/async.h> /* struct async_flt */ 35 #include <sys/ddi_impldefs.h> 36 #include <sys/machsystm.h> 37 #include <sys/sysmacros.h> 38 #include <sys/fm/protocol.h> 39 #include <sys/fm/util.h> 40 #include <sys/fm/io/pci.h> 41 #include <sys/fm/io/sun4upci.h> 42 #include <sys/fm/io/ddi.h> 43 #include <sys/pci/pci_obj.h> /* ld/st physio */ 44 #include <sys/cpuvar.h> 45 #include <sys/errclassify.h> 46 #include <sys/cpu_module.h> 47 #include <sys/async.h> 48 49 /*LINTLIBRARY*/ 50 51 static void ecc_disable(ecc_t *, int); 52 static void ecc_delayed_ce(void *); 53 static uint64_t ecc_read_afsr(ecc_intr_info_t *); 54 static void ecc_ereport_post(dev_info_t *dip, ecc_errstate_t *ecc_err); 55 56 clock_t pci_ecc_panic_delay = 200; 57 int ecc_ce_delay_secs = 6; /* number of sec to delay reenabling of CEs */ 58 int ecc_ce_delayed = 1; /* global for enabling/disabling CE delay */ 59 60 void 61 ecc_create(pci_t *pci_p) 62 { 63 #ifdef DEBUG 64 dev_info_t *dip = pci_p->pci_dip; 65 #endif 66 uint64_t cb_base_pa = pci_p->pci_cb_p->cb_base_pa; 67 ecc_t *ecc_p; 68 69 ecc_p = (ecc_t *)kmem_zalloc(sizeof (ecc_t), KM_SLEEP); 70 ecc_p->ecc_pci_cmn_p = pci_p->pci_common_p; 71 pci_p->pci_ecc_p = ecc_p; 72 73 ecc_p->ecc_ue.ecc_p = ecc_p; 74 ecc_p->ecc_ue.ecc_type = CBNINTR_UE; 75 ecc_p->ecc_ce.ecc_p = ecc_p; 76 ecc_p->ecc_ce.ecc_type = CBNINTR_CE; 77 78 pci_ecc_setup(ecc_p); 79 80 /* 81 * Determine the virtual addresses of the streaming cache 82 * control/status and flush registers. 83 */ 84 ecc_p->ecc_csr_pa = cb_base_pa + COMMON_ECC_CSR_OFFSET; 85 ecc_p->ecc_ue.ecc_afsr_pa = cb_base_pa + COMMON_UE_AFSR_OFFSET; 86 ecc_p->ecc_ue.ecc_afar_pa = cb_base_pa + COMMON_UE_AFAR_OFFSET; 87 ecc_p->ecc_ce.ecc_afsr_pa = cb_base_pa + COMMON_CE_AFSR_OFFSET; 88 ecc_p->ecc_ce.ecc_afar_pa = cb_base_pa + COMMON_CE_AFAR_OFFSET; 89 90 DEBUG1(DBG_ATTACH, dip, "ecc_create: csr=%x\n", ecc_p->ecc_csr_pa); 91 DEBUG2(DBG_ATTACH, dip, "ecc_create: ue_afsr=%x, ue_afar=%x\n", 92 ecc_p->ecc_ue.ecc_afsr_pa, ecc_p->ecc_ue.ecc_afar_pa); 93 DEBUG2(DBG_ATTACH, dip, "ecc_create: ce_afsr=%x, ce_afar=%x\n", 94 ecc_p->ecc_ce.ecc_afsr_pa, ecc_p->ecc_ce.ecc_afar_pa); 95 96 ecc_configure(pci_p); 97 98 /* 99 * Register routines to be called from system error handling code. 100 */ 101 bus_func_register(BF_TYPE_ERRDIS, (busfunc_t)ecc_disable_nowait, ecc_p); 102 } 103 104 int 105 ecc_register_intr(pci_t *pci_p) 106 { 107 ecc_t *ecc_p = pci_p->pci_ecc_p; 108 int ret; 109 110 /* 111 * Install the UE and CE error interrupt handlers. 112 */ 113 if ((ret = pci_ecc_add_intr(pci_p, CBNINTR_UE, &ecc_p->ecc_ue)) != 114 DDI_SUCCESS) 115 return (ret); 116 if ((ret = pci_ecc_add_intr(pci_p, CBNINTR_CE, &ecc_p->ecc_ce)) != 117 DDI_SUCCESS) 118 return (ret); 119 120 return (DDI_SUCCESS); 121 } 122 123 void 124 ecc_destroy(pci_t *pci_p) 125 { 126 ecc_t *ecc_p = pci_p->pci_ecc_p; 127 128 DEBUG0(DBG_DETACH, pci_p->pci_dip, "ecc_destroy:\n"); 129 130 /* 131 * Disable UE and CE ECC error interrupts. 132 */ 133 ecc_disable_wait(ecc_p); 134 135 /* 136 * Remove the ECC interrupt handlers. 137 */ 138 pci_ecc_rem_intr(pci_p, CBNINTR_UE, &ecc_p->ecc_ue); 139 pci_ecc_rem_intr(pci_p, CBNINTR_CE, &ecc_p->ecc_ce); 140 141 /* 142 * Unregister our error handling functions. 143 */ 144 bus_func_unregister(BF_TYPE_ERRDIS, 145 (busfunc_t)ecc_disable_nowait, ecc_p); 146 /* 147 * If a timer has been set, unset it. 148 */ 149 (void) untimeout(ecc_p->ecc_to_id); 150 151 kmem_free(ecc_p, sizeof (ecc_t)); 152 pci_p->pci_ecc_p = NULL; 153 } 154 155 void 156 ecc_configure(pci_t *pci_p) 157 { 158 ecc_t *ecc_p = pci_p->pci_ecc_p; 159 dev_info_t *dip = pci_p->pci_dip; 160 uint64_t l; 161 162 /* 163 * Clear any pending ECC errors. 164 */ 165 DEBUG0(DBG_ATTACH, dip, "ecc_configure: clearing UE and CE errors\n"); 166 l = (COMMON_ECC_UE_AFSR_E_MASK << COMMON_ECC_UE_AFSR_PE_SHIFT) | 167 (COMMON_ECC_UE_AFSR_E_MASK << COMMON_ECC_UE_AFSR_SE_SHIFT); 168 stdphysio(ecc_p->ecc_ue.ecc_afsr_pa, l); 169 170 l = (COMMON_ECC_CE_AFSR_E_MASK << COMMON_ECC_CE_AFSR_PE_SHIFT) | 171 (COMMON_ECC_CE_AFSR_E_MASK << COMMON_ECC_CE_AFSR_SE_SHIFT); 172 stdphysio(ecc_p->ecc_ce.ecc_afsr_pa, l); 173 174 /* 175 * Enable ECC error detections via the control register. 176 */ 177 DEBUG0(DBG_ATTACH, dip, "ecc_configure: enabling UE CE detection\n"); 178 l = COMMON_ECC_CTRL_ECC_EN; 179 if (ecc_error_intr_enable) 180 l |= COMMON_ECC_CTRL_UE_INTEN | COMMON_ECC_CTRL_CE_INTEN; 181 stdphysio(ecc_p->ecc_csr_pa, l); 182 } 183 184 void 185 ecc_enable_intr(pci_t *pci_p) 186 { 187 cb_enable_nintr(pci_p, CBNINTR_UE); 188 cb_enable_nintr(pci_p, CBNINTR_CE); 189 } 190 191 void 192 ecc_disable_wait(ecc_t *ecc_p) 193 { 194 ecc_disable(ecc_p, IB_INTR_WAIT); 195 } 196 197 uint_t 198 ecc_disable_nowait(ecc_t *ecc_p) 199 { 200 ecc_disable(ecc_p, IB_INTR_NOWAIT); 201 return (BF_NONE); 202 } 203 204 static void 205 ecc_disable(ecc_t *ecc_p, int wait) 206 { 207 cb_t *cb_p = ecc_p->ecc_pci_cmn_p->pci_common_cb_p; 208 uint64_t csr_pa = ecc_p->ecc_csr_pa; 209 uint64_t csr = lddphysio(csr_pa); 210 211 csr &= ~(COMMON_ECC_CTRL_UE_INTEN | COMMON_ECC_CTRL_CE_INTEN); 212 stdphysio(csr_pa, csr); 213 214 cb_disable_nintr(cb_p, CBNINTR_UE, wait); 215 cb_disable_nintr(cb_p, CBNINTR_CE, wait); 216 } 217 218 /* 219 * I/O ECC error handling: 220 * 221 * Below are the generic functions that handle PCI(pcisch, pcipsy) detected 222 * ECC errors. 223 * 224 * The registered interrupt handler for both pcisch and pcipsy is ecc_intr(), 225 * it's function is to receive the error, capture some state, and pass that on 226 * to the ecc_err_handler() for reporting purposes. 227 * 228 * ecc_err_handler() gathers more state(via ecc_errstate_get) and attempts 229 * to handle and report the error. ecc_err_handler() must determine if we need 230 * to panic due to this error (via pci_ecc_classify, which also decodes the 231 * ECC afsr), and if any side effects exist that may have caused or are due 232 * to this error. PBM errors related to the ECC error may exist, to report 233 * them we call pci_pbm_err_handler() and call ndi_fm_handler_dispatch() so 234 * that the child devices can log their pci errors. 235 * 236 * To report the error we must also get the syndrome and unum, which can not 237 * be done in high level interrupted context. Therefore we have an error 238 * queue(pci_ecc_queue) which we dispatch errors to, to report the errors 239 * (ecc_err_drain()). 240 * 241 * ecc_err_drain() will be called when either the softint is triggered 242 * or the system is panicing. Either way it will gather more information 243 * about the error from the CPU(via ecc_cpu_call(), ecc.c), attempt to 244 * retire the faulty page(if error is a UE), and report the detected error. 245 * 246 * ecc_delayed_ce() is called via timeout from ecc_err_handler() following 247 * the receipt of a CE interrupt. It will be called after 6ms and check to 248 * see if any new CEs are present, if so we will log and another timeout will 249 * be set by(ecc_err_handler()). If no CEs are present then it will re-enable 250 * CEs by clearing the previous interrupt. This is to keep the system going 251 * in the event of a CE storm. 252 */ 253 254 /* 255 * Function used to get ECC AFSR register 256 */ 257 static uint64_t 258 ecc_read_afsr(ecc_intr_info_t *ecc_ii_p) 259 { 260 uint_t i; 261 uint64_t afsr = 0ull; 262 263 ASSERT((ecc_ii_p->ecc_type == CBNINTR_UE) || 264 (ecc_ii_p->ecc_type == CBNINTR_CE)); 265 if (!ecc_ii_p->ecc_errpndg_mask) 266 return (lddphysio(ecc_ii_p->ecc_afsr_pa)); 267 268 for (i = 0; i < pci_ecc_afsr_retries; i++) { 269 270 /* 271 * If we timeout, the logging routine will 272 * know because it will see the ERRPNDG bits 273 * set in the AFSR. 274 */ 275 afsr = lddphysio(ecc_ii_p->ecc_afsr_pa); 276 if ((afsr & ecc_ii_p->ecc_errpndg_mask) == 0) 277 break; 278 } 279 return (afsr); 280 } 281 282 /* 283 * IO detected ECC error interrupt handler, calls ecc_err_handler to post 284 * error reports and handle the interrupt. Re-entry into ecc_err_handler 285 * is protected by the per-chip mutex pci_fm_mutex. 286 */ 287 uint_t 288 ecc_intr(caddr_t a) 289 { 290 ecc_intr_info_t *ecc_ii_p = (ecc_intr_info_t *)a; 291 ecc_t *ecc_p = ecc_ii_p->ecc_p; 292 pci_common_t *cmn_p = ecc_p->ecc_pci_cmn_p; 293 ecc_errstate_t ecc_err; 294 int ret = DDI_FM_OK; 295 296 bzero(&ecc_err, sizeof (ecc_errstate_t)); 297 ecc_err.ecc_ena = fm_ena_generate(0, FM_ENA_FMT1); 298 ecc_err.ecc_ii_p = *ecc_ii_p; 299 ecc_err.ecc_p = ecc_p; 300 ecc_err.ecc_caller = PCI_ECC_CALL; 301 302 mutex_enter(&cmn_p->pci_fm_mutex); 303 ret = ecc_err_handler(&ecc_err); 304 mutex_exit(&cmn_p->pci_fm_mutex); 305 if (ret == DDI_FM_FATAL) { 306 /* 307 * Need delay here to allow CPUs to handle related traps, 308 * such as FRUs for USIIIi systems. 309 */ 310 DELAY(pci_ecc_panic_delay); 311 fm_panic("Fatal PCI UE Error"); 312 } 313 314 return (DDI_INTR_CLAIMED); 315 } 316 317 /* 318 * Function used to gather IO ECC error state. 319 */ 320 static void 321 ecc_errstate_get(ecc_errstate_t *ecc_err_p) 322 { 323 ecc_t *ecc_p; 324 uint_t bus_id; 325 326 ASSERT(ecc_err_p); 327 328 ecc_p = ecc_err_p->ecc_ii_p.ecc_p; 329 bus_id = ecc_p->ecc_pci_cmn_p->pci_common_id; 330 331 ASSERT(MUTEX_HELD(&ecc_p->ecc_pci_cmn_p->pci_fm_mutex)); 332 /* 333 * Read the fault registers. 334 */ 335 ecc_err_p->ecc_afsr = ecc_read_afsr(&ecc_err_p->ecc_ii_p); 336 ecc_err_p->ecc_afar = lddphysio(ecc_err_p->ecc_ii_p.ecc_afar_pa); 337 338 ecc_err_p->ecc_offset = ((ecc_err_p->ecc_afsr & 339 ecc_err_p->ecc_ii_p.ecc_offset_mask) >> 340 ecc_err_p->ecc_ii_p.ecc_offset_shift) << 341 ecc_err_p->ecc_ii_p.ecc_size_log2; 342 343 ecc_err_p->ecc_aflt.flt_id = gethrtime(); 344 ecc_err_p->ecc_aflt.flt_stat = ecc_err_p->ecc_afsr; 345 ecc_err_p->ecc_aflt.flt_addr = P2ALIGN(ecc_err_p->ecc_afar, 64) + 346 ecc_err_p->ecc_offset; 347 ecc_err_p->ecc_aflt.flt_bus_id = bus_id; 348 ecc_err_p->ecc_aflt.flt_inst = CPU->cpu_id; 349 ecc_err_p->ecc_aflt.flt_status = ECC_IOBUS; 350 ecc_err_p->ecc_aflt.flt_in_memory = 351 (pf_is_memory(ecc_err_p->ecc_afar >> MMU_PAGESHIFT))? 1: 0; 352 ecc_err_p->ecc_aflt.flt_class = BUS_FAULT; 353 } 354 355 /* 356 * ecc_pci_check: Called by ecc_err_handler() this function is responsible 357 * for calling pci_pbm_err_handler() for both sides of the schizo/psycho 358 * and calling their children error handlers(via ndi_fm_handler_dispatch()). 359 */ 360 static int 361 ecc_pci_check(ecc_t *ecc_p, uint64_t fme_ena) 362 { 363 ddi_fm_error_t derr; 364 int i; 365 int ret; 366 367 ASSERT(MUTEX_HELD(&ecc_p->ecc_pci_cmn_p->pci_fm_mutex)); 368 369 bzero(&derr, sizeof (ddi_fm_error_t)); 370 derr.fme_version = DDI_FME_VERSION; 371 derr.fme_ena = fme_ena; 372 ret = DDI_FM_NONFATAL; 373 374 /* 375 * Need to report any PBM errors which may have caused or 376 * resulted from this error. 377 * 378 * Each psycho or schizo is represented by a pair of pci nodes 379 * in the device tree. 380 */ 381 for (i = 0; i < 2; i++) { 382 dev_info_t *dip; 383 pci_t *pci_p; 384 385 /* Make sure PBM PCI node exists */ 386 pci_p = ecc_p->ecc_pci_cmn_p->pci_p[i]; 387 if (pci_p == NULL) 388 continue; 389 390 dip = pci_p->pci_dip; 391 if (pci_pbm_err_handler(dip, &derr, (void *)pci_p, 392 PCI_ECC_CALL) == DDI_FM_FATAL) 393 ret = DDI_FM_FATAL; 394 } 395 if (ret == DDI_FM_FATAL) 396 return (DDI_FM_FATAL); 397 else 398 return (DDI_FM_NONFATAL); 399 } 400 401 /* 402 * Function used to handle and log IO detected ECC errors, can be called by 403 * ecc_intr and pci_err_callback(trap callback). Protected by pci_fm_mutex. 404 */ 405 int 406 ecc_err_handler(ecc_errstate_t *ecc_err_p) 407 { 408 uint64_t pri_err, sec_err; 409 ecc_intr_info_t *ecc_ii_p = &ecc_err_p->ecc_ii_p; 410 ecc_t *ecc_p = ecc_ii_p->ecc_p; 411 pci_t *pci_p; 412 cb_t *cb_p; 413 int fatal = 0; 414 int nonfatal = 0; 415 ecc_errstate_t ecc_sec_err; 416 uint64_t sec_tmp; 417 int i; 418 uint64_t afsr_err[] = { COMMON_ECC_AFSR_E_PIO, 419 COMMON_ECC_AFSR_E_DRD, 420 COMMON_ECC_AFSR_E_DWR }; 421 422 423 ASSERT(MUTEX_HELD(&ecc_p->ecc_pci_cmn_p->pci_fm_mutex)); 424 425 pci_p = ecc_p->ecc_pci_cmn_p->pci_p[0]; 426 if (pci_p == NULL) 427 pci_p = ecc_p->ecc_pci_cmn_p->pci_p[1]; 428 429 cb_p = ecc_p->ecc_pci_cmn_p->pci_common_cb_p; 430 431 ecc_errstate_get(ecc_err_p); 432 pri_err = (ecc_err_p->ecc_afsr >> COMMON_ECC_UE_AFSR_PE_SHIFT) & 433 COMMON_ECC_UE_AFSR_E_MASK; 434 435 sec_err = (ecc_err_p->ecc_afsr >> COMMON_ECC_UE_AFSR_SE_SHIFT) & 436 COMMON_ECC_UE_AFSR_E_MASK; 437 438 switch (ecc_ii_p->ecc_type) { 439 case CBNINTR_UE: 440 if (pri_err) { 441 ecc_err_p->ecc_aflt.flt_synd = 442 pci_ecc_get_synd(ecc_err_p->ecc_afsr); 443 ecc_err_p->ecc_pri = 1; 444 pci_ecc_classify(pri_err, ecc_err_p); 445 errorq_dispatch(pci_ecc_queue, (void *)ecc_err_p, 446 sizeof (ecc_errstate_t), 447 ecc_err_p->ecc_aflt.flt_panic); 448 } 449 if (sec_err) { 450 ecc_sec_err = *ecc_err_p; 451 ecc_sec_err.ecc_pri = 0; 452 /* 453 * Secondary errors are cumulative so we need to loop 454 * through to capture them all. 455 */ 456 for (i = 0; i < 3; i++) { 457 sec_tmp = sec_err & afsr_err[i]; 458 if (sec_tmp) { 459 pci_ecc_classify(sec_tmp, &ecc_sec_err); 460 ecc_ereport_post(pci_p->pci_dip, 461 &ecc_sec_err); 462 } 463 } 464 } 465 /* 466 * Check for PCI bus errors that may have resulted from or 467 * caused this UE. 468 */ 469 if (ecc_err_p->ecc_caller == PCI_ECC_CALL && 470 ecc_pci_check(ecc_p, ecc_err_p->ecc_ena) == DDI_FM_FATAL) 471 ecc_err_p->ecc_aflt.flt_panic = 1; 472 473 if (ecc_err_p->ecc_aflt.flt_panic && 474 ecc_err_p->ecc_aflt.flt_in_memory) 475 panic_aflt = ecc_err_p->ecc_aflt; 476 477 if (ecc_err_p->ecc_aflt.flt_panic) { 478 /* 479 * Disable all further errors since this will be 480 * treated as a fatal error. 481 */ 482 (void) ecc_disable_nowait(ecc_p); 483 fatal++; 484 } 485 break; 486 487 case CBNINTR_CE: 488 if (pri_err) { 489 ecc_err_p->ecc_pri = 1; 490 pci_ecc_classify(pri_err, ecc_err_p); 491 ecc_err_p->ecc_aflt.flt_synd = 492 pci_ecc_get_synd(ecc_err_p->ecc_afsr); 493 ce_scrub(&ecc_err_p->ecc_aflt); 494 errorq_dispatch(pci_ecc_queue, (void *)ecc_err_p, 495 sizeof (ecc_errstate_t), ERRORQ_ASYNC); 496 nonfatal++; 497 } 498 if (sec_err) { 499 ecc_sec_err = *ecc_err_p; 500 ecc_sec_err.ecc_pri = 0; 501 /* 502 * Secondary errors are cumulative so we need to loop 503 * through to capture them all. 504 */ 505 for (i = 0; i < 3; i++) { 506 sec_tmp = sec_err & afsr_err[i]; 507 if (sec_tmp) { 508 pci_ecc_classify(sec_tmp, &ecc_sec_err); 509 ecc_ereport_post(pci_p->pci_dip, 510 &ecc_sec_err); 511 } 512 } 513 nonfatal++; 514 } 515 break; 516 517 default: 518 return (DDI_FM_OK); 519 } 520 /* Clear the errors */ 521 stdphysio(ecc_ii_p->ecc_afsr_pa, ecc_err_p->ecc_afsr); 522 /* 523 * Clear the interrupt if called by ecc_intr and UE error or if called 524 * by ecc_intr and CE error and delayed CE interrupt handling is 525 * turned off. 526 */ 527 if ((ecc_err_p->ecc_caller == PCI_ECC_CALL && 528 ecc_ii_p->ecc_type == CBNINTR_UE && !fatal) || 529 (ecc_err_p->ecc_caller == PCI_ECC_CALL && 530 ecc_ii_p->ecc_type == CBNINTR_CE && !ecc_ce_delayed)) 531 cb_clear_nintr(cb_p, ecc_ii_p->ecc_type); 532 if (!fatal && !nonfatal) 533 return (DDI_FM_OK); 534 else if (fatal) 535 return (DDI_FM_FATAL); 536 return (DDI_FM_NONFATAL); 537 } 538 539 /* 540 * Called from ecc_err_drain below for CBINTR_CE case. 541 */ 542 static int 543 ecc_err_cexdiag(ecc_errstate_t *ecc_err, errorq_elem_t *eqep) 544 { 545 struct async_flt *ecc = &ecc_err->ecc_aflt; 546 uint64_t errors; 547 548 if (page_retire_check(ecc->flt_addr, &errors) == EINVAL) { 549 CE_XDIAG_SETSKIPCODE(ecc->flt_disp, CE_XDIAG_SKIP_NOPP); 550 return (0); 551 } else if (errors != PR_OK) { 552 CE_XDIAG_SETSKIPCODE(ecc->flt_disp, CE_XDIAG_SKIP_PAGEDET); 553 return (0); 554 } else { 555 return (ce_scrub_xdiag_recirc(ecc, pci_ecc_queue, eqep, 556 offsetof(ecc_errstate_t, ecc_aflt))); 557 } 558 } 559 560 /* 561 * Function used to drain pci_ecc_queue, either during panic or after softint 562 * is generated, to log IO detected ECC errors. 563 */ 564 /*ARGSUSED*/ 565 void 566 ecc_err_drain(void *not_used, ecc_errstate_t *ecc_err, errorq_elem_t *eqep) 567 { 568 struct async_flt *ecc = &ecc_err->ecc_aflt; 569 pci_t *pci_p = ecc_err->ecc_p->ecc_pci_cmn_p->pci_p[0]; 570 int ecc_type = ecc_err->ecc_ii_p.ecc_type; 571 572 if (pci_p == NULL) 573 pci_p = ecc_err->ecc_p->ecc_pci_cmn_p->pci_p[1]; 574 575 if (ecc->flt_class == RECIRC_BUS_FAULT) { 576 /* 577 * Perform any additional actions that occur after the 578 * ecc_err_cexdiag below and post the ereport. 579 */ 580 ecc->flt_class = BUS_FAULT; 581 ecc_err->ecc_err_type = flt_to_error_type(ecc); 582 ecc_ereport_post(pci_p->pci_dip, ecc_err); 583 return; 584 } 585 586 ecc_cpu_call(ecc, ecc_err->ecc_unum, (ecc_type == CBNINTR_UE) ? 587 ECC_IO_UE : ECC_IO_CE); 588 589 switch (ecc_type) { 590 case CBNINTR_UE: 591 if (ecc_err->ecc_pg_ret == 1) { 592 (void) page_retire(ecc->flt_addr, PR_UE); 593 } 594 ecc_err->ecc_err_type = flt_to_error_type(ecc); 595 break; 596 597 case CBNINTR_CE: 598 /* 599 * Setup timeout (if CE detected via interrupt) to 600 * re-enable CE interrupts if no more CEs are detected. 601 * This is to protect against CE storms. 602 */ 603 if (ecc_ce_delayed && 604 ecc_err->ecc_caller == PCI_ECC_CALL && 605 ecc_err->ecc_p->ecc_to_id == 0) { 606 ecc_err->ecc_p->ecc_to_id = timeout(ecc_delayed_ce, 607 (void *)ecc_err->ecc_p, 608 drv_usectohz((clock_t)ecc_ce_delay_secs * 609 MICROSEC)); 610 } 611 612 /* ecc_err_cexdiag returns nonzero to recirculate */ 613 if (CE_XDIAG_EXT_ALG_APPLIED(ecc->flt_disp) && 614 ecc_err_cexdiag(ecc_err, eqep)) 615 return; 616 ecc_err->ecc_err_type = flt_to_error_type(ecc); 617 break; 618 } 619 620 ecc_ereport_post(pci_p->pci_dip, ecc_err); 621 } 622 623 static void 624 ecc_delayed_ce(void *arg) 625 { 626 ecc_t *ecc_p = (ecc_t *)arg; 627 pci_common_t *cmn_p; 628 cb_t *cb_p; 629 630 ASSERT(ecc_p); 631 632 cmn_p = ecc_p->ecc_pci_cmn_p; 633 cb_p = cmn_p->pci_common_cb_p; 634 /* 635 * If no more CE errors are found then enable interrupts(by 636 * clearing the previous interrupt), else send in for logging 637 * and the timeout should be set again. 638 */ 639 ecc_p->ecc_to_id = 0; 640 if (!((ecc_read_afsr(&ecc_p->ecc_ce) >> 641 COMMON_ECC_UE_AFSR_PE_SHIFT) & COMMON_ECC_UE_AFSR_E_MASK)) { 642 cb_clear_nintr(cb_p, ecc_p->ecc_ce.ecc_type); 643 } else { 644 ecc_errstate_t ecc_err; 645 646 bzero(&ecc_err, sizeof (ecc_errstate_t)); 647 ecc_err.ecc_ena = fm_ena_generate(0, FM_ENA_FMT1); 648 ecc_err.ecc_ii_p = ecc_p->ecc_ce; 649 ecc_err.ecc_p = ecc_p; 650 ecc_err.ecc_caller = PCI_ECC_CALL; 651 652 mutex_enter(&cmn_p->pci_fm_mutex); 653 (void) ecc_err_handler(&ecc_err); 654 mutex_exit(&cmn_p->pci_fm_mutex); 655 } 656 } 657 658 /* 659 * Function used to post IO detected ECC ereports. 660 */ 661 static void 662 ecc_ereport_post(dev_info_t *dip, ecc_errstate_t *ecc_err) 663 { 664 char buf[FM_MAX_CLASS], dev_path[MAXPATHLEN], *ptr; 665 struct i_ddi_fmhdl *fmhdl = DEVI(dip)->devi_fmhdl; 666 nvlist_t *ereport, *detector; 667 nv_alloc_t *nva; 668 errorq_elem_t *eqep; 669 670 /* 671 * We do not use ddi_fm_ereport_post because we need to set a 672 * special detector here. Since we do not have a device path for 673 * the bridge chip we use what we think it should be to aid in 674 * diagnosis. This path fmri is created by pci_fmri_create() 675 * during initialization. 676 */ 677 (void) snprintf(buf, FM_MAX_CLASS, "%s.%s.%s", DDI_IO_CLASS, 678 ecc_err->ecc_bridge_type, ecc_err->ecc_aflt.flt_erpt_class); 679 680 ecc_err->ecc_ena = ecc_err->ecc_ena ? ecc_err->ecc_ena : 681 fm_ena_generate(0, FM_ENA_FMT1); 682 683 eqep = errorq_reserve(fmhdl->fh_errorq); 684 if (eqep == NULL) 685 return; 686 687 ereport = errorq_elem_nvl(fmhdl->fh_errorq, eqep); 688 nva = errorq_elem_nva(fmhdl->fh_errorq, eqep); 689 detector = fm_nvlist_create(nva); 690 691 ASSERT(ereport); 692 ASSERT(nva); 693 ASSERT(detector); 694 695 ddi_pathname(dip, dev_path); 696 ptr = strrchr(dev_path, (int)','); 697 698 if (ptr) 699 *ptr = '\0'; 700 701 fm_fmri_dev_set(detector, FM_DEV_SCHEME_VERSION, NULL, dev_path, 702 NULL, NULL); 703 704 if (ecc_err->ecc_pri) { 705 if ((ecc_err->ecc_fmri = fm_nvlist_create(nva)) != NULL) { 706 char sid[DIMM_SERIAL_ID_LEN] = ""; 707 uint64_t offset = (uint64_t)-1; 708 int len; 709 int ret; 710 711 ret = cpu_get_mem_sid(ecc_err->ecc_unum, sid, 712 DIMM_SERIAL_ID_LEN, &len); 713 714 if (ret == 0) { 715 (void) cpu_get_mem_offset( 716 ecc_err->ecc_aflt.flt_addr, &offset); 717 } 718 719 fm_fmri_mem_set(ecc_err->ecc_fmri, 720 FM_MEM_SCHEME_VERSION, NULL, ecc_err->ecc_unum, 721 (ret == 0) ? sid : NULL, offset); 722 } 723 fm_ereport_set(ereport, FM_EREPORT_VERSION, buf, 724 ecc_err->ecc_ena, detector, 725 PCI_ECC_AFSR, DATA_TYPE_UINT64, ecc_err->ecc_afsr, 726 PCI_ECC_AFAR, DATA_TYPE_UINT64, ecc_err->ecc_aflt.flt_addr, 727 PCI_ECC_CTRL, DATA_TYPE_UINT64, ecc_err->ecc_ctrl, 728 PCI_ECC_SYND, DATA_TYPE_UINT16, ecc_err->ecc_aflt.flt_synd, 729 PCI_ECC_TYPE, DATA_TYPE_STRING, ecc_err->ecc_err_type, 730 PCI_ECC_DISP, DATA_TYPE_UINT64, ecc_err->ecc_aflt.flt_disp, 731 PCI_ECC_RESOURCE, DATA_TYPE_NVLIST, ecc_err->ecc_fmri, 732 NULL); 733 } else { 734 fm_ereport_set(ereport, FM_EREPORT_VERSION, buf, 735 ecc_err->ecc_ena, detector, 736 PCI_ECC_AFSR, DATA_TYPE_UINT64, ecc_err->ecc_afsr, 737 PCI_ECC_CTRL, DATA_TYPE_UINT64, ecc_err->ecc_ctrl, 738 NULL); 739 } 740 errorq_commit(fmhdl->fh_errorq, eqep, ERRORQ_ASYNC); 741 } 742