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/sunndi.h> 31 #include <sys/sysmacros.h> 32 #include <sys/ddifm_impl.h> 33 #include <sys/fm/util.h> 34 #include <sys/fm/protocol.h> 35 #include <sys/fm/io/pci.h> 36 #include <sys/fm/io/ddi.h> 37 #include <sys/pci.h> 38 #include <sys/pcie.h> 39 #include <sys/pci_impl.h> 40 #include <sys/epm.h> 41 #include <sys/pcifm.h> 42 43 #define PCIX_ECC_VER_CHECK(x) (((x) == PCI_PCIX_VER_1) ||\ 44 ((x) == PCI_PCIX_VER_2)) 45 46 /* 47 * Expected PCI Express error mask values 48 */ 49 uint32_t pcie_expected_ce_mask = PCIE_AER_CE_AD_NFE; 50 uint32_t pcie_expected_ue_mask = 0x0; 51 uint32_t pcie_expected_sue_mask = 0x0; 52 53 errorq_t *pci_target_queue = NULL; 54 55 pci_fm_err_t pci_err_tbl[] = { 56 PCI_DET_PERR, PCI_STAT_PERROR, NULL, DDI_FM_UNKNOWN, 57 PCI_MDPE, PCI_STAT_S_PERROR, PCI_TARG_MDPE, DDI_FM_UNKNOWN, 58 PCI_SIG_SERR, PCI_STAT_S_SYSERR, NULL, DDI_FM_FATAL, 59 PCI_MA, PCI_STAT_R_MAST_AB, PCI_TARG_MA, DDI_FM_UNKNOWN, 60 PCI_REC_TA, PCI_STAT_R_TARG_AB, PCI_TARG_REC_TA, DDI_FM_UNKNOWN, 61 PCI_SIG_TA, PCI_STAT_S_TARG_AB, NULL, DDI_FM_UNKNOWN, 62 NULL, NULL, NULL, NULL, 63 }; 64 65 pci_fm_err_t pci_bdg_err_tbl[] = { 66 PCI_DET_PERR, PCI_STAT_PERROR, NULL, DDI_FM_UNKNOWN, 67 PCI_MDPE, PCI_STAT_S_PERROR, PCI_TARG_MDPE, DDI_FM_UNKNOWN, 68 PCI_REC_SERR, PCI_STAT_S_SYSERR, NULL, DDI_FM_UNKNOWN, 69 PCI_MA, PCI_STAT_R_MAST_AB, PCI_TARG_MA, DDI_FM_UNKNOWN, 70 PCI_REC_TA, PCI_STAT_R_TARG_AB, PCI_TARG_REC_TA, DDI_FM_UNKNOWN, 71 PCI_SIG_TA, PCI_STAT_S_TARG_AB, NULL, DDI_FM_UNKNOWN, 72 NULL, NULL, NULL, NULL, 73 }; 74 75 static pci_fm_err_t pciex_ce_err_tbl[] = { 76 PCIEX_RE, PCIE_AER_CE_RECEIVER_ERR, NULL, DDI_FM_NONFATAL, 77 PCIEX_RNR, PCIE_AER_CE_REPLAY_ROLLOVER, NULL, DDI_FM_NONFATAL, 78 PCIEX_RTO, PCIE_AER_CE_REPLAY_TO, NULL, DDI_FM_NONFATAL, 79 PCIEX_BDP, PCIE_AER_CE_BAD_DLLP, NULL, DDI_FM_NONFATAL, 80 PCIEX_BTP, PCIE_AER_CE_BAD_TLP, NULL, DDI_FM_NONFATAL, 81 PCIEX_ANFE, PCIE_AER_CE_AD_NFE, NULL, DDI_FM_NONFATAL, 82 NULL, NULL, NULL, NULL, 83 }; 84 85 static pci_fm_err_t pciex_ue_err_tbl[] = { 86 PCIEX_TE, PCIE_AER_UCE_TRAINING, NULL, DDI_FM_FATAL, 87 PCIEX_DLP, PCIE_AER_UCE_DLP, NULL, DDI_FM_FATAL, 88 PCIEX_SD, PCIE_AER_UCE_SD, NULL, DDI_FM_FATAL, 89 PCIEX_ROF, PCIE_AER_UCE_RO, NULL, DDI_FM_FATAL, 90 PCIEX_FCP, PCIE_AER_UCE_FCP, NULL, DDI_FM_FATAL, 91 PCIEX_MFP, PCIE_AER_UCE_MTLP, NULL, DDI_FM_FATAL, 92 PCIEX_CTO, PCIE_AER_UCE_TO, NULL, DDI_FM_NONFATAL, 93 PCIEX_UC, PCIE_AER_UCE_UC, NULL, DDI_FM_NONFATAL, 94 PCIEX_ECRC, PCIE_AER_UCE_ECRC, NULL, DDI_FM_UNKNOWN, 95 PCIEX_CA, PCIE_AER_UCE_CA, NULL, DDI_FM_UNKNOWN, 96 PCIEX_UR, PCIE_AER_UCE_UR, NULL, DDI_FM_NONFATAL, 97 PCIEX_POIS, PCIE_AER_UCE_PTLP, NULL, DDI_FM_UNKNOWN, 98 NULL, NULL, NULL, NULL, 99 }; 100 101 static pci_fm_err_t pcie_sue_err_tbl[] = { 102 PCIEX_S_TA_SC, PCIE_AER_SUCE_TA_ON_SC, NULL, DDI_FM_UNKNOWN, 103 PCIEX_S_MA_SC, PCIE_AER_SUCE_MA_ON_SC, NULL, DDI_FM_UNKNOWN, 104 PCIEX_S_RTA, PCIE_AER_SUCE_RCVD_TA, NULL, DDI_FM_UNKNOWN, 105 PCIEX_S_RMA, PCIE_AER_SUCE_RCVD_MA, NULL, DDI_FM_UNKNOWN, 106 PCIEX_S_USC, PCIE_AER_SUCE_USC_ERR, NULL, DDI_FM_UNKNOWN, 107 PCIEX_S_USCMD, PCIE_AER_SUCE_USC_MSG_DATA_ERR, NULL, DDI_FM_FATAL, 108 PCIEX_S_UDE, PCIE_AER_SUCE_UC_DATA_ERR, NULL, DDI_FM_UNKNOWN, 109 PCIEX_S_UAT, PCIE_AER_SUCE_UC_ATTR_ERR, NULL, DDI_FM_FATAL, 110 PCIEX_S_UADR, PCIE_AER_SUCE_UC_ADDR_ERR, NULL, DDI_FM_FATAL, 111 PCIEX_S_TEX, PCIE_AER_SUCE_TIMER_EXPIRED, NULL, DDI_FM_FATAL, 112 PCIEX_S_PERR, PCIE_AER_SUCE_PERR_ASSERT, NULL, DDI_FM_UNKNOWN, 113 PCIEX_S_SERR, PCIE_AER_SUCE_SERR_ASSERT, NULL, DDI_FM_FATAL, 114 PCIEX_INTERR, PCIE_AER_SUCE_INTERNAL_ERR, NULL, DDI_FM_FATAL, 115 NULL, NULL, NULL, NULL, 116 }; 117 118 static pci_fm_err_t pcix_err_tbl[] = { 119 PCIX_SPL_DIS, PCI_PCIX_SPL_DSCD, NULL, DDI_FM_UNKNOWN, 120 PCIX_UNEX_SPL, PCI_PCIX_UNEX_SPL, NULL, DDI_FM_UNKNOWN, 121 PCIX_RX_SPL_MSG, PCI_PCIX_RX_SPL_MSG, NULL, DDI_FM_UNKNOWN, 122 NULL, NULL, NULL, NULL, 123 }; 124 125 static pci_fm_err_t pcix_sec_err_tbl[] = { 126 PCIX_SPL_DIS, PCI_PCIX_BSS_SPL_DSCD, NULL, DDI_FM_UNKNOWN, 127 PCIX_UNEX_SPL, PCI_PCIX_BSS_UNEX_SPL, NULL, DDI_FM_UNKNOWN, 128 PCIX_BSS_SPL_OR, PCI_PCIX_BSS_SPL_OR, NULL, DDI_FM_NONFATAL, 129 PCIX_BSS_SPL_DLY, PCI_PCIX_BSS_SPL_DLY, NULL, DDI_FM_NONFATAL, 130 NULL, NULL, NULL, NULL, 131 }; 132 133 static pci_fm_err_t pciex_nadv_err_tbl[] = { 134 PCIEX_UR, PCIE_DEVSTS_UR_DETECTED, NULL, DDI_FM_UNKNOWN, 135 PCIEX_FAT, PCIE_DEVSTS_FE_DETECTED, NULL, DDI_FM_FATAL, 136 PCIEX_NONFAT, PCIE_DEVSTS_NFE_DETECTED, NULL, DDI_FM_UNKNOWN, 137 PCIEX_CORR, PCIE_DEVSTS_CE_DETECTED, NULL, DDI_FM_NONFATAL, 138 NULL, NULL, NULL, NULL, 139 }; 140 141 static int 142 pci_config_check(ddi_acc_handle_t handle) 143 { 144 ddi_acc_hdl_t *hp = impl_acc_hdl_get(handle); 145 ddi_fm_error_t de; 146 147 if (!(DDI_FM_ACC_ERR_CAP(ddi_fm_capable(hp->ah_dip)))) 148 return (DDI_FM_OK); 149 150 de.fme_version = DDI_FME_VERSION; 151 152 ddi_fm_acc_err_get(handle, &de, de.fme_version); 153 if (de.fme_status != DDI_FM_OK) { 154 char buf[FM_MAX_CLASS]; 155 156 (void) snprintf(buf, FM_MAX_CLASS, "%s.%s", PCI_ERROR_SUBCLASS, 157 PCI_NR); 158 ddi_fm_ereport_post(hp->ah_dip, buf, de.fme_ena, DDI_NOSLEEP, 159 FM_VERSION, DATA_TYPE_UINT8, 0, NULL); 160 ddi_fm_acc_err_clear(handle, de.fme_version); 161 } 162 return (de.fme_status); 163 } 164 165 static void 166 pcix_ecc_regs_gather(pci_erpt_t *erpt_p, pcix_ecc_regs_t *pcix_ecc_regs, 167 uint8_t pcix_cap_ptr) 168 { 169 int bdg = erpt_p->pe_dflags & PCI_BRIDGE_DEV; 170 171 pcix_ecc_regs->pcix_ecc_ctlstat = pci_config_get32(erpt_p->pe_hdl, 172 (pcix_cap_ptr + (bdg ? PCI_PCIX_BDG_ECC_STATUS : 173 PCI_PCIX_ECC_STATUS))); 174 if (pci_config_check(erpt_p->pe_hdl) == DDI_FM_OK) 175 pcix_ecc_regs->pcix_ecc_vflags |= PCIX_ERR_ECC_STS_VALID; 176 else 177 return; 178 pcix_ecc_regs->pcix_ecc_fstaddr = pci_config_get32(erpt_p->pe_hdl, 179 (pcix_cap_ptr + (bdg ? PCI_PCIX_BDG_ECC_FST_AD : 180 PCI_PCIX_ECC_FST_AD))); 181 pcix_ecc_regs->pcix_ecc_secaddr = pci_config_get32(erpt_p->pe_hdl, 182 (pcix_cap_ptr + (bdg ? PCI_PCIX_BDG_ECC_SEC_AD : 183 PCI_PCIX_ECC_SEC_AD))); 184 pcix_ecc_regs->pcix_ecc_attr = pci_config_get32(( 185 ddi_acc_handle_t)erpt_p->pe_hdl, 186 (pcix_cap_ptr + (bdg ? PCI_PCIX_BDG_ECC_ATTR : PCI_PCIX_ECC_ATTR))); 187 } 188 189 static void 190 pcix_regs_gather(pci_erpt_t *erpt_p, void *pe_regs) 191 { 192 if (erpt_p->pe_dflags & PCI_BRIDGE_DEV) { 193 pcix_bdg_error_regs_t *pcix_bdg_regs = 194 (pcix_bdg_error_regs_t *)pe_regs; 195 uint8_t pcix_bdg_cap_ptr; 196 int i; 197 198 pcix_bdg_cap_ptr = pcix_bdg_regs->pcix_bdg_cap_ptr; 199 pcix_bdg_regs->pcix_bdg_sec_stat = pci_config_get16( 200 erpt_p->pe_hdl, (pcix_bdg_cap_ptr + PCI_PCIX_SEC_STATUS)); 201 if (pci_config_check(erpt_p->pe_hdl) == DDI_FM_OK) 202 pcix_bdg_regs->pcix_bdg_vflags |= 203 PCIX_BDG_SEC_STATUS_VALID; 204 else 205 return; 206 pcix_bdg_regs->pcix_bdg_stat = pci_config_get32(erpt_p->pe_hdl, 207 (pcix_bdg_cap_ptr + PCI_PCIX_BDG_STATUS)); 208 if (pci_config_check(erpt_p->pe_hdl) == DDI_FM_OK) 209 pcix_bdg_regs->pcix_bdg_vflags |= PCIX_BDG_STATUS_VALID; 210 else 211 return; 212 if (PCIX_ECC_VER_CHECK(pcix_bdg_regs->pcix_bdg_ver)) { 213 pcix_ecc_regs_t *pcix_bdg_ecc_regs; 214 /* 215 * PCI Express to PCI-X bridges only implement the 216 * secondary side of the PCI-X ECC registers, bit one is 217 * read-only so we make sure we do not write to it. 218 */ 219 if (erpt_p->pe_dflags & PCIEX_2PCI_DEV) { 220 pcix_bdg_ecc_regs = 221 pcix_bdg_regs->pcix_bdg_ecc_regs[1]; 222 pcix_ecc_regs_gather(erpt_p, pcix_bdg_ecc_regs, 223 pcix_bdg_cap_ptr); 224 } else { 225 for (i = 0; i < 2; i++) { 226 pcix_bdg_ecc_regs = 227 pcix_bdg_regs->pcix_bdg_ecc_regs[i]; 228 pci_config_put32(erpt_p->pe_hdl, 229 (pcix_bdg_cap_ptr + 230 PCI_PCIX_BDG_ECC_STATUS), i); 231 pcix_ecc_regs_gather(erpt_p, 232 pcix_bdg_ecc_regs, 233 pcix_bdg_cap_ptr); 234 } 235 } 236 } 237 } else { 238 pcix_error_regs_t *pcix_regs = (pcix_error_regs_t *)pe_regs; 239 uint8_t pcix_cap_ptr; 240 241 pcix_cap_ptr = pcix_regs->pcix_cap_ptr; 242 243 pcix_regs->pcix_command = pci_config_get16(erpt_p->pe_hdl, 244 (pcix_cap_ptr + PCI_PCIX_COMMAND)); 245 pcix_regs->pcix_status = pci_config_get32(erpt_p->pe_hdl, 246 (pcix_cap_ptr + PCI_PCIX_STATUS)); 247 if (pci_config_check(erpt_p->pe_hdl) == DDI_FM_OK) 248 pcix_regs->pcix_vflags |= PCIX_ERR_STATUS_VALID; 249 else 250 return; 251 if (PCIX_ECC_VER_CHECK(pcix_regs->pcix_ver)) { 252 pcix_ecc_regs_t *pcix_ecc_regs = 253 pcix_regs->pcix_ecc_regs; 254 255 pcix_ecc_regs_gather(erpt_p, pcix_ecc_regs, 256 pcix_cap_ptr); 257 } 258 } 259 } 260 261 static void 262 pcie_regs_gather(pci_erpt_t *erpt_p) 263 { 264 pcie_error_regs_t *pcie_regs = (pcie_error_regs_t *)erpt_p->pe_regs; 265 uint8_t pcie_cap_ptr; 266 pcie_adv_error_regs_t *pcie_adv_regs; 267 uint16_t pcie_ecap_ptr; 268 269 pcie_cap_ptr = pcie_regs->pcie_cap_ptr; 270 271 pcie_regs->pcie_err_status = pci_config_get16(erpt_p->pe_hdl, 272 pcie_cap_ptr + PCIE_DEVSTS); 273 if (pci_config_check(erpt_p->pe_hdl) == DDI_FM_OK) 274 pcie_regs->pcie_vflags |= PCIE_ERR_STATUS_VALID; 275 else 276 return; 277 278 pcie_regs->pcie_err_ctl = pci_config_get16(erpt_p->pe_hdl, 279 (pcie_cap_ptr + PCIE_DEVCTL)); 280 281 if ((erpt_p->pe_dflags & PCI_BRIDGE_DEV) && (erpt_p->pe_dflags & 282 PCIX_DEV)) 283 pcix_regs_gather(erpt_p, pcie_regs->pcix_bdg_regs); 284 285 if (erpt_p->pe_dflags & PCIEX_RC_DEV) { 286 pcie_rc_error_regs_t *pcie_rc_regs = pcie_regs->pcie_rc_regs; 287 288 pcie_rc_regs->pcie_rc_status = pci_config_get32(erpt_p->pe_hdl, 289 (pcie_cap_ptr + PCIE_ROOTSTS)); 290 pcie_rc_regs->pcie_rc_ctl = pci_config_get16(erpt_p->pe_hdl, 291 (pcie_cap_ptr + PCIE_ROOTCTL)); 292 } 293 294 if (!(erpt_p->pe_dflags & PCIEX_ADV_DEV)) 295 return; 296 297 pcie_adv_regs = pcie_regs->pcie_adv_regs; 298 299 pcie_ecap_ptr = pcie_adv_regs->pcie_adv_cap_ptr; 300 301 pcie_adv_regs->pcie_ue_status = pci_config_get32(erpt_p->pe_hdl, 302 pcie_ecap_ptr + PCIE_AER_UCE_STS); 303 if (pci_config_check(erpt_p->pe_hdl) == DDI_FM_OK) 304 pcie_adv_regs->pcie_adv_vflags |= PCIE_UE_STATUS_VALID; 305 306 pcie_adv_regs->pcie_ue_mask = pci_config_get32(erpt_p->pe_hdl, 307 pcie_ecap_ptr + PCIE_AER_UCE_MASK); 308 pcie_adv_regs->pcie_ue_sev = pci_config_get32(erpt_p->pe_hdl, 309 pcie_ecap_ptr + PCIE_AER_UCE_SERV); 310 pcie_adv_regs->pcie_adv_ctl = pci_config_get32(erpt_p->pe_hdl, 311 pcie_ecap_ptr + PCIE_AER_CTL); 312 pcie_adv_regs->pcie_ue_hdr0 = pci_config_get32(erpt_p->pe_hdl, 313 pcie_ecap_ptr + PCIE_AER_HDR_LOG); 314 if (pci_config_check(erpt_p->pe_hdl) == DDI_FM_OK) { 315 int i; 316 pcie_adv_regs->pcie_adv_vflags |= PCIE_UE_HDR_VALID; 317 318 for (i = 0; i < 3; i++) { 319 pcie_adv_regs->pcie_ue_hdr[i] = pci_config_get32( 320 erpt_p->pe_hdl, pcie_ecap_ptr + PCIE_AER_HDR_LOG + 321 (4 * (i + 1))); 322 } 323 } 324 325 pcie_adv_regs->pcie_ce_status = pci_config_get32(erpt_p->pe_hdl, 326 pcie_ecap_ptr + PCIE_AER_CE_STS); 327 if (pci_config_check(erpt_p->pe_hdl) == DDI_FM_OK) 328 pcie_adv_regs->pcie_adv_vflags |= PCIE_CE_STATUS_VALID; 329 330 pcie_adv_regs->pcie_ce_mask = pci_config_get32(erpt_p->pe_hdl, 331 pcie_ecap_ptr + PCIE_AER_CE_MASK); 332 333 /* 334 * If pci express to pci bridge then grab the bridge 335 * error registers. 336 */ 337 if (erpt_p->pe_dflags & PCIEX_2PCI_DEV) { 338 pcie_adv_bdg_error_regs_t *pcie_bdg_regs = 339 pcie_adv_regs->pcie_adv_bdg_regs; 340 341 pcie_bdg_regs->pcie_sue_status = 342 pci_config_get32(erpt_p->pe_hdl, 343 pcie_ecap_ptr + PCIE_AER_SUCE_STS); 344 if (pci_config_check(erpt_p->pe_hdl) == DDI_FM_OK) 345 pcie_adv_regs->pcie_adv_vflags |= PCIE_SUE_STATUS_VALID; 346 pcie_bdg_regs->pcie_sue_hdr0 = pci_config_get32(erpt_p->pe_hdl, 347 (pcie_ecap_ptr + PCIE_AER_SHDR_LOG)); 348 349 if (pci_config_check(erpt_p->pe_hdl) == DDI_FM_OK) { 350 int i; 351 352 pcie_adv_regs->pcie_adv_vflags |= PCIE_SUE_HDR_VALID; 353 354 for (i = 0; i < 3; i++) { 355 pcie_bdg_regs->pcie_sue_hdr[i] = 356 pci_config_get32(erpt_p->pe_hdl, 357 pcie_ecap_ptr + PCIE_AER_SHDR_LOG + 358 (4 * (i + 1))); 359 } 360 } 361 } 362 /* 363 * If PCI Express root complex then grab the root complex 364 * error registers. 365 */ 366 if (erpt_p->pe_dflags & PCIEX_RC_DEV) { 367 pcie_adv_rc_error_regs_t *pcie_rc_regs = 368 pcie_adv_regs->pcie_adv_rc_regs; 369 370 pcie_rc_regs->pcie_rc_err_cmd = pci_config_get32(erpt_p->pe_hdl, 371 (pcie_ecap_ptr + PCIE_AER_RE_CMD)); 372 pcie_rc_regs->pcie_rc_err_status = 373 pci_config_get32(erpt_p->pe_hdl, 374 (pcie_ecap_ptr + PCIE_AER_RE_STS)); 375 if (pci_config_check(erpt_p->pe_hdl) == DDI_FM_OK) 376 pcie_adv_regs->pcie_adv_vflags |= 377 PCIE_RC_ERR_STATUS_VALID; 378 pcie_rc_regs->pcie_rc_ce_src_id = 379 pci_config_get16(erpt_p->pe_hdl, 380 (pcie_ecap_ptr + PCIE_AER_CE_SRC_ID)); 381 pcie_rc_regs->pcie_rc_ue_src_id = 382 pci_config_get16(erpt_p->pe_hdl, 383 (pcie_ecap_ptr + PCIE_AER_ERR_SRC_ID)); 384 if (pci_config_check(erpt_p->pe_hdl) == DDI_FM_OK) 385 pcie_adv_regs->pcie_adv_vflags |= PCIE_SRC_ID_VALID; 386 } 387 } 388 389 /*ARGSUSED*/ 390 static void 391 pci_regs_gather(dev_info_t *dip, pci_erpt_t *erpt_p) 392 { 393 pci_error_regs_t *pci_regs = erpt_p->pe_pci_regs; 394 395 /* 396 * Start by reading all the error registers that are available for 397 * pci and pci express and for leaf devices and bridges/switches 398 */ 399 pci_regs->pci_err_status = pci_config_get16(erpt_p->pe_hdl, 400 PCI_CONF_STAT); 401 if (pci_config_check(erpt_p->pe_hdl) != DDI_FM_OK) 402 return; 403 pci_regs->pci_vflags |= PCI_ERR_STATUS_VALID; 404 pci_regs->pci_cfg_comm = pci_config_get16(erpt_p->pe_hdl, 405 PCI_CONF_COMM); 406 if (pci_config_check(erpt_p->pe_hdl) != DDI_FM_OK) 407 return; 408 409 /* 410 * If pci-pci bridge grab PCI bridge specific error registers. 411 */ 412 if (erpt_p->pe_dflags & PCI_BRIDGE_DEV) { 413 pci_regs->pci_bdg_regs->pci_bdg_sec_stat = 414 pci_config_get16(erpt_p->pe_hdl, PCI_BCNF_SEC_STATUS); 415 if (pci_config_check(erpt_p->pe_hdl) == DDI_FM_OK) 416 pci_regs->pci_bdg_regs->pci_bdg_vflags |= 417 PCI_BDG_SEC_STAT_VALID; 418 pci_regs->pci_bdg_regs->pci_bdg_ctrl = 419 pci_config_get16(erpt_p->pe_hdl, PCI_BCNF_BCNTRL); 420 if (pci_config_check(erpt_p->pe_hdl) == DDI_FM_OK) 421 pci_regs->pci_bdg_regs->pci_bdg_vflags |= 422 PCI_BDG_CTRL_VALID; 423 } 424 425 /* 426 * If pci express device grab pci express error registers and 427 * check for advanced error reporting features and grab them if 428 * available. 429 */ 430 if (erpt_p->pe_dflags & PCIEX_DEV) 431 pcie_regs_gather(erpt_p); 432 else if (erpt_p->pe_dflags & PCIX_DEV) 433 pcix_regs_gather(erpt_p, erpt_p->pe_regs); 434 435 } 436 437 static void 438 pcix_regs_clear(pci_erpt_t *erpt_p, void *pe_regs) 439 { 440 if (erpt_p->pe_dflags & PCI_BRIDGE_DEV) { 441 pcix_bdg_error_regs_t *pcix_bdg_regs = 442 (pcix_bdg_error_regs_t *)pe_regs; 443 uint8_t pcix_bdg_cap_ptr; 444 int i; 445 446 pcix_bdg_cap_ptr = pcix_bdg_regs->pcix_bdg_cap_ptr; 447 448 if (pcix_bdg_regs->pcix_bdg_vflags & PCIX_BDG_SEC_STATUS_VALID) 449 pci_config_put16(erpt_p->pe_hdl, 450 (pcix_bdg_cap_ptr + PCI_PCIX_SEC_STATUS), 451 pcix_bdg_regs->pcix_bdg_sec_stat); 452 453 if (pcix_bdg_regs->pcix_bdg_vflags & PCIX_BDG_STATUS_VALID) 454 pci_config_put32(erpt_p->pe_hdl, 455 (pcix_bdg_cap_ptr + PCI_PCIX_BDG_STATUS), 456 pcix_bdg_regs->pcix_bdg_stat); 457 458 pcix_bdg_regs->pcix_bdg_vflags = 0x0; 459 460 if (PCIX_ECC_VER_CHECK(pcix_bdg_regs->pcix_bdg_ver)) { 461 pcix_ecc_regs_t *pcix_bdg_ecc_regs; 462 /* 463 * PCI Express to PCI-X bridges only implement the 464 * secondary side of the PCI-X ECC registers, bit one is 465 * read-only so we make sure we do not write to it. 466 */ 467 if (erpt_p->pe_dflags & PCIEX_2PCI_DEV) { 468 pcix_bdg_ecc_regs = 469 pcix_bdg_regs->pcix_bdg_ecc_regs[1]; 470 471 if (pcix_bdg_ecc_regs->pcix_ecc_vflags & 472 PCIX_ERR_ECC_STS_VALID) { 473 474 pci_config_put32(erpt_p->pe_hdl, 475 (pcix_bdg_cap_ptr + 476 PCI_PCIX_BDG_ECC_STATUS), 477 pcix_bdg_ecc_regs-> 478 pcix_ecc_ctlstat); 479 } 480 pcix_bdg_ecc_regs->pcix_ecc_vflags = 0x0; 481 } else { 482 for (i = 0; i < 2; i++) { 483 pcix_bdg_ecc_regs = 484 pcix_bdg_regs->pcix_bdg_ecc_regs[i]; 485 486 487 if (pcix_bdg_ecc_regs->pcix_ecc_vflags & 488 PCIX_ERR_ECC_STS_VALID) { 489 pci_config_put32(erpt_p->pe_hdl, 490 (pcix_bdg_cap_ptr + 491 PCI_PCIX_BDG_ECC_STATUS), 492 i); 493 494 pci_config_put32(erpt_p->pe_hdl, 495 (pcix_bdg_cap_ptr + 496 PCI_PCIX_BDG_ECC_STATUS), 497 pcix_bdg_ecc_regs-> 498 pcix_ecc_ctlstat); 499 } 500 pcix_bdg_ecc_regs->pcix_ecc_vflags = 501 0x0; 502 } 503 } 504 } 505 } else { 506 pcix_error_regs_t *pcix_regs = (pcix_error_regs_t *)pe_regs; 507 uint8_t pcix_cap_ptr; 508 509 pcix_cap_ptr = pcix_regs->pcix_cap_ptr; 510 511 if (pcix_regs->pcix_vflags & PCIX_ERR_STATUS_VALID) 512 pci_config_put32(erpt_p->pe_hdl, 513 (pcix_cap_ptr + PCI_PCIX_STATUS), 514 pcix_regs->pcix_status); 515 516 pcix_regs->pcix_vflags = 0x0; 517 518 if (PCIX_ECC_VER_CHECK(pcix_regs->pcix_ver)) { 519 pcix_ecc_regs_t *pcix_ecc_regs = 520 pcix_regs->pcix_ecc_regs; 521 522 if (pcix_ecc_regs->pcix_ecc_vflags & 523 PCIX_ERR_ECC_STS_VALID) 524 pci_config_put32(erpt_p->pe_hdl, 525 (pcix_cap_ptr + PCI_PCIX_ECC_STATUS), 526 pcix_ecc_regs->pcix_ecc_ctlstat); 527 528 pcix_ecc_regs->pcix_ecc_vflags = 0x0; 529 } 530 } 531 } 532 533 static void 534 pcie_regs_clear(pci_erpt_t *erpt_p) 535 { 536 pcie_error_regs_t *pcie_regs = (pcie_error_regs_t *)erpt_p->pe_regs; 537 uint8_t pcie_cap_ptr; 538 pcie_adv_error_regs_t *pcie_adv_regs; 539 uint16_t pcie_ecap_ptr; 540 541 pcie_cap_ptr = pcie_regs->pcie_cap_ptr; 542 543 if (pcie_regs->pcie_vflags & PCIE_ERR_STATUS_VALID) 544 pci_config_put16(erpt_p->pe_hdl, pcie_cap_ptr + PCIE_DEVSTS, 545 pcie_regs->pcie_err_status); 546 547 pcie_regs->pcie_vflags = 0x0; 548 549 if ((erpt_p->pe_dflags & PCI_BRIDGE_DEV) && 550 (erpt_p->pe_dflags & PCIX_DEV)) 551 pcix_regs_clear(erpt_p, pcie_regs->pcix_bdg_regs); 552 553 if (!(erpt_p->pe_dflags & PCIEX_ADV_DEV)) 554 return; 555 556 pcie_adv_regs = pcie_regs->pcie_adv_regs; 557 558 pcie_ecap_ptr = pcie_adv_regs->pcie_adv_cap_ptr; 559 560 if (pcie_adv_regs->pcie_adv_vflags & PCIE_UE_STATUS_VALID) 561 pci_config_put32(erpt_p->pe_hdl, 562 pcie_ecap_ptr + PCIE_AER_UCE_STS, 563 pcie_adv_regs->pcie_ue_status); 564 565 if (pcie_adv_regs->pcie_adv_vflags & PCIE_CE_STATUS_VALID) 566 pci_config_put32(erpt_p->pe_hdl, 567 pcie_ecap_ptr + PCIE_AER_CE_STS, 568 pcie_adv_regs->pcie_ce_status); 569 570 571 if (erpt_p->pe_dflags & PCIEX_2PCI_DEV) { 572 pcie_adv_bdg_error_regs_t *pcie_bdg_regs = 573 pcie_adv_regs->pcie_adv_bdg_regs; 574 575 576 if (pcie_adv_regs->pcie_adv_vflags & PCIE_SUE_STATUS_VALID) 577 pci_config_put32(erpt_p->pe_hdl, 578 pcie_ecap_ptr + PCIE_AER_SUCE_STS, 579 pcie_bdg_regs->pcie_sue_status); 580 } 581 /* 582 * If PCI Express root complex then clear the root complex 583 * error registers. 584 */ 585 if (erpt_p->pe_dflags & PCIEX_RC_DEV) { 586 pcie_adv_rc_error_regs_t *pcie_rc_regs = 587 pcie_adv_regs->pcie_adv_rc_regs; 588 589 590 if (pcie_adv_regs->pcie_adv_vflags & PCIE_RC_ERR_STATUS_VALID) 591 pci_config_put32(erpt_p->pe_hdl, 592 (pcie_ecap_ptr + PCIE_AER_RE_STS), 593 pcie_rc_regs->pcie_rc_err_status); 594 } 595 pcie_adv_regs->pcie_adv_vflags = 0x0; 596 } 597 598 static void 599 pci_regs_clear(pci_erpt_t *erpt_p) 600 { 601 /* 602 * Finally clear the error bits 603 */ 604 if (erpt_p->pe_dflags & PCIEX_DEV) 605 pcie_regs_clear(erpt_p); 606 else if (erpt_p->pe_dflags & PCIX_DEV) 607 pcix_regs_clear(erpt_p, erpt_p->pe_regs); 608 609 if (erpt_p->pe_pci_regs->pci_vflags & PCI_ERR_STATUS_VALID) 610 pci_config_put16(erpt_p->pe_hdl, PCI_CONF_STAT, 611 erpt_p->pe_pci_regs->pci_err_status); 612 613 erpt_p->pe_pci_regs->pci_vflags = 0x0; 614 615 if (erpt_p->pe_dflags & PCI_BRIDGE_DEV) { 616 if (erpt_p->pe_pci_regs->pci_bdg_regs->pci_bdg_vflags & 617 PCI_BDG_SEC_STAT_VALID) 618 pci_config_put16(erpt_p->pe_hdl, PCI_BCNF_SEC_STATUS, 619 erpt_p->pe_pci_regs->pci_bdg_regs-> 620 pci_bdg_sec_stat); 621 if (erpt_p->pe_pci_regs->pci_bdg_regs->pci_bdg_vflags & 622 PCI_BDG_CTRL_VALID) 623 pci_config_put16(erpt_p->pe_hdl, PCI_BCNF_BCNTRL, 624 erpt_p->pe_pci_regs->pci_bdg_regs->pci_bdg_ctrl); 625 626 erpt_p->pe_pci_regs->pci_bdg_regs->pci_bdg_vflags = 0x0; 627 } 628 } 629 630 /* 631 * pcix_ereport_setup: Allocate structures for PCI-X error handling and ereport 632 * generation. 633 */ 634 /* ARGSUSED */ 635 static void 636 pcix_ereport_setup(dev_info_t *dip, pci_erpt_t *erpt_p) 637 { 638 uint8_t pcix_cap_ptr; 639 int i; 640 641 pcix_cap_ptr = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, 642 "pcix-capid-pointer", PCI_CAP_NEXT_PTR_NULL); 643 644 if (pcix_cap_ptr != PCI_CAP_NEXT_PTR_NULL) 645 erpt_p->pe_dflags |= PCIX_DEV; 646 else 647 return; 648 649 if (erpt_p->pe_dflags & PCI_BRIDGE_DEV) { 650 pcix_bdg_error_regs_t *pcix_bdg_regs; 651 652 erpt_p->pe_regs = kmem_zalloc(sizeof (pcix_bdg_error_regs_t), 653 KM_SLEEP); 654 pcix_bdg_regs = (pcix_bdg_error_regs_t *)erpt_p->pe_regs; 655 pcix_bdg_regs->pcix_bdg_cap_ptr = pcix_cap_ptr; 656 pcix_bdg_regs->pcix_bdg_ver = pci_config_get16(erpt_p->pe_hdl, 657 pcix_cap_ptr + PCI_PCIX_SEC_STATUS) & PCI_PCIX_VER_MASK; 658 if (PCIX_ECC_VER_CHECK(pcix_bdg_regs->pcix_bdg_ver)) { 659 for (i = 0; i < 2; i++) { 660 pcix_bdg_regs->pcix_bdg_ecc_regs[i] = 661 kmem_zalloc(sizeof (pcix_ecc_regs_t), 662 KM_SLEEP); 663 } 664 } 665 } else { 666 pcix_error_regs_t *pcix_regs; 667 668 erpt_p->pe_regs = kmem_zalloc(sizeof (pcix_error_regs_t), 669 KM_SLEEP); 670 pcix_regs = (pcix_error_regs_t *)erpt_p->pe_regs; 671 pcix_regs->pcix_cap_ptr = pcix_cap_ptr; 672 pcix_regs->pcix_ver = pci_config_get16(erpt_p->pe_hdl, 673 pcix_cap_ptr + PCI_PCIX_COMMAND) & PCI_PCIX_VER_MASK; 674 if (PCIX_ECC_VER_CHECK(pcix_regs->pcix_ver)) { 675 pcix_regs->pcix_ecc_regs = kmem_zalloc( 676 sizeof (pcix_ecc_regs_t), KM_SLEEP); 677 } 678 } 679 } 680 681 static void 682 pcie_ereport_setup(dev_info_t *dip, pci_erpt_t *erpt_p) 683 { 684 pcie_error_regs_t *pcie_regs; 685 pcie_adv_error_regs_t *pcie_adv_regs; 686 char buf[FM_MAX_CLASS]; 687 uint8_t pcix_cap_ptr; 688 uint8_t pcie_cap_ptr; 689 uint16_t pcie_ecap_ptr; 690 uint16_t dev_type = 0; 691 uint32_t mask = pcie_expected_ue_mask; 692 693 /* 694 * The following sparc specific code should be removed once the pci_cap 695 * interfaces create the necessary properties for us. 696 */ 697 #if defined(__sparc) 698 ushort_t status; 699 uint32_t slot_cap; 700 uint8_t cap_ptr = 0; 701 uint8_t cap_id = 0; 702 uint32_t hdr, hdr_next_ptr, hdr_cap_id; 703 uint16_t offset = P2ALIGN(PCIE_EXT_CAP, 4); 704 uint16_t aer_ptr = 0; 705 706 cap_ptr = pci_config_get8(erpt_p->pe_hdl, PCI_CONF_CAP_PTR); 707 if (pci_config_check(erpt_p->pe_hdl) == DDI_FM_OK) { 708 while ((cap_id = pci_config_get8(erpt_p->pe_hdl, cap_ptr)) != 709 0xff) { 710 if (cap_id == PCI_CAP_ID_PCIX) { 711 (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip, 712 "pcix-capid-pointer", cap_ptr); 713 } 714 if (cap_id == PCI_CAP_ID_PCI_E) { 715 status = pci_config_get16(erpt_p->pe_hdl, cap_ptr + 2); 716 if (status & PCIE_PCIECAP_SLOT_IMPL) { 717 /* offset 14h is Slot Cap Register */ 718 slot_cap = pci_config_get32(erpt_p->pe_hdl, 719 cap_ptr + PCIE_SLOTCAP); 720 (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip, 721 "pcie-slotcap-reg", slot_cap); 722 } 723 (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip, 724 "pcie-capid-reg", pci_config_get16(erpt_p->pe_hdl, 725 cap_ptr + PCIE_PCIECAP)); 726 (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip, 727 "pcie-capid-pointer", cap_ptr); 728 729 } 730 if ((cap_ptr = pci_config_get8(erpt_p->pe_hdl, 731 cap_ptr + 1)) == 0xff || cap_ptr == 0 || 732 (pci_config_check(erpt_p->pe_hdl) != DDI_FM_OK)) 733 break; 734 } 735 } 736 737 #endif 738 739 pcix_cap_ptr = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, 740 "pcix-capid-pointer", PCI_CAP_NEXT_PTR_NULL); 741 742 if (pcix_cap_ptr != PCI_CAP_NEXT_PTR_NULL) 743 erpt_p->pe_dflags |= PCIX_DEV; 744 745 pcie_cap_ptr = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 746 DDI_PROP_DONTPASS, "pcie-capid-pointer", PCI_CAP_NEXT_PTR_NULL); 747 748 if (pcie_cap_ptr != PCI_CAP_NEXT_PTR_NULL) { 749 erpt_p->pe_dflags |= PCIEX_DEV; 750 erpt_p->pe_regs = kmem_zalloc(sizeof (pcie_error_regs_t), 751 KM_SLEEP); 752 pcie_regs = (pcie_error_regs_t *)erpt_p->pe_regs; 753 pcie_regs->pcie_cap_ptr = pcie_cap_ptr; 754 } 755 756 if (!(erpt_p->pe_dflags & PCIEX_DEV)) 757 return; 758 759 /* 760 * Don't currently need to check for version here because we are 761 * compliant with PCIE 1.0a which is version 0 and is guaranteed 762 * software compatibility with future versions. We will need to 763 * add errors for new detectors/features which are added in newer 764 * revisions [sec 7.8.2]. 765 */ 766 pcie_regs->pcie_cap = pci_config_get16(erpt_p->pe_hdl, 767 pcie_regs->pcie_cap_ptr + PCIE_PCIECAP); 768 769 dev_type = pcie_regs->pcie_cap & PCIE_PCIECAP_DEV_TYPE_MASK; 770 771 if ((erpt_p->pe_dflags & PCI_BRIDGE_DEV) && 772 (erpt_p->pe_dflags & PCIX_DEV)) { 773 int i; 774 775 pcie_regs->pcix_bdg_regs = 776 kmem_zalloc(sizeof (pcix_bdg_error_regs_t), KM_SLEEP); 777 778 pcie_regs->pcix_bdg_regs->pcix_bdg_cap_ptr = pcix_cap_ptr; 779 pcie_regs->pcix_bdg_regs->pcix_bdg_ver = 780 pci_config_get16(erpt_p->pe_hdl, 781 pcix_cap_ptr + PCI_PCIX_SEC_STATUS) & PCI_PCIX_VER_MASK; 782 783 if (PCIX_ECC_VER_CHECK(pcie_regs->pcix_bdg_regs->pcix_bdg_ver)) 784 for (i = 0; i < 2; i++) 785 pcie_regs->pcix_bdg_regs->pcix_bdg_ecc_regs[i] = 786 kmem_zalloc(sizeof (pcix_ecc_regs_t), 787 KM_SLEEP); 788 } 789 790 if (dev_type == PCIE_PCIECAP_DEV_TYPE_ROOT) { 791 erpt_p->pe_dflags |= PCIEX_RC_DEV; 792 pcie_regs->pcie_rc_regs = kmem_zalloc( 793 sizeof (pcie_rc_error_regs_t), KM_SLEEP); 794 } 795 /* 796 * The following sparc specific code should be removed once the pci_cap 797 * interfaces create the necessary properties for us. 798 */ 799 #if defined(__sparc) 800 801 hdr = pci_config_get32(erpt_p->pe_hdl, offset); 802 hdr_next_ptr = (hdr >> PCIE_EXT_CAP_NEXT_PTR_SHIFT) & 803 PCIE_EXT_CAP_NEXT_PTR_MASK; 804 hdr_cap_id = (hdr >> PCIE_EXT_CAP_ID_SHIFT) & PCIE_EXT_CAP_ID_MASK; 805 806 while ((hdr_next_ptr != PCIE_EXT_CAP_NEXT_PTR_NULL) && 807 (hdr_cap_id != PCIE_EXT_CAP_ID_AER)) { 808 offset = P2ALIGN(hdr_next_ptr, 4); 809 hdr = pci_config_get32(erpt_p->pe_hdl, offset); 810 hdr_next_ptr = (hdr >> PCIE_EXT_CAP_NEXT_PTR_SHIFT) & 811 PCIE_EXT_CAP_NEXT_PTR_MASK; 812 hdr_cap_id = (hdr >> PCIE_EXT_CAP_ID_SHIFT) & 813 PCIE_EXT_CAP_ID_MASK; 814 } 815 816 if (hdr_cap_id == PCIE_EXT_CAP_ID_AER) 817 aer_ptr = P2ALIGN(offset, 4); 818 if (aer_ptr != PCI_CAP_NEXT_PTR_NULL) 819 (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip, 820 "pcie-aer-pointer", aer_ptr); 821 #endif 822 823 /* 824 * Find and store if this device is capable of pci express 825 * advanced errors, if not report an error against the device. 826 */ 827 pcie_ecap_ptr = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, 828 "pcie-aer-pointer", PCI_CAP_NEXT_PTR_NULL); 829 if (pcie_ecap_ptr != PCI_CAP_NEXT_PTR_NULL) { 830 erpt_p->pe_dflags |= PCIEX_ADV_DEV; 831 pcie_regs->pcie_adv_regs = kmem_zalloc( 832 sizeof (pcie_adv_error_regs_t), KM_SLEEP); 833 pcie_regs->pcie_adv_regs->pcie_adv_cap_ptr = pcie_ecap_ptr; 834 } 835 836 if (!(erpt_p->pe_dflags & PCIEX_ADV_DEV)) { 837 (void) snprintf(buf, FM_MAX_CLASS, "%s.%s", 838 PCIEX_ERROR_SUBCLASS, PCIEX_NADV); 839 ddi_fm_ereport_post(dip, buf, NULL, DDI_NOSLEEP, 840 FM_VERSION, DATA_TYPE_UINT8, 0, NULL); 841 return; 842 } 843 844 pcie_adv_regs = pcie_regs->pcie_adv_regs; 845 846 if (pcie_adv_regs == NULL) 847 return; 848 /* 849 * Initialize structures for advanced PCI Express devices. 850 */ 851 852 /* 853 * Advanced error registers exist for PCI Express to PCI(X) Bridges and 854 * may also exist for PCI(X) to PCI Express Bridges, the latter is not 855 * well explained in the PCI Express to PCI/PCI-X Bridge Specification 856 * 1.0 and will be left out of the current gathering of these registers. 857 */ 858 if (dev_type == PCIE_PCIECAP_DEV_TYPE_PCIE2PCI) { 859 erpt_p->pe_dflags |= PCIEX_2PCI_DEV; 860 pcie_adv_regs->pcie_adv_bdg_regs = kmem_zalloc( 861 sizeof (pcie_adv_bdg_error_regs_t), KM_SLEEP); 862 } 863 864 if (erpt_p->pe_dflags & PCIEX_RC_DEV) 865 pcie_adv_regs->pcie_adv_rc_regs = kmem_zalloc( 866 sizeof (pcie_adv_rc_error_regs_t), KM_SLEEP); 867 868 /* 869 * Check that mask values are as expected, if not 870 * change them to what we desire. 871 */ 872 pci_regs_gather(dip, erpt_p); 873 pcie_regs = (pcie_error_regs_t *)erpt_p->pe_regs; 874 if (pcie_regs->pcie_adv_regs->pcie_ce_mask != pcie_expected_ce_mask) { 875 pci_config_put32(erpt_p->pe_hdl, 876 pcie_ecap_ptr + PCIE_AER_CE_MASK, pcie_expected_ce_mask); 877 } 878 879 /* Disable PTLP/ECRC (or mask these two) for Switches */ 880 if (dev_type == PCIE_PCIECAP_DEV_TYPE_UP || 881 dev_type == PCIE_PCIECAP_DEV_TYPE_DOWN) 882 mask |= PCIE_AER_UCE_PTLP | PCIE_AER_UCE_ECRC; 883 884 if (pcie_regs->pcie_adv_regs->pcie_ue_mask != mask) { 885 pci_config_put32(erpt_p->pe_hdl, 886 pcie_ecap_ptr + PCIE_AER_UCE_MASK, mask); 887 } 888 if (erpt_p->pe_dflags & PCIEX_2PCI_DEV) { 889 if (pcie_regs->pcie_adv_regs->pcie_adv_bdg_regs->pcie_sue_mask 890 != pcie_expected_sue_mask) { 891 pci_config_put32(erpt_p->pe_hdl, 892 pcie_ecap_ptr + PCIE_AER_SUCE_MASK, 893 pcie_expected_sue_mask); 894 } 895 } 896 } 897 898 /* 899 * pci_ereport_setup: Detect PCI device type and initialize structures to be 900 * used to generate ereports based on detected generic device errors. 901 */ 902 void 903 pci_ereport_setup(dev_info_t *dip) 904 { 905 struct dev_info *devi = DEVI(dip); 906 struct i_ddi_fmhdl *fmhdl = devi->devi_fmhdl; 907 pci_erpt_t *erpt_p; 908 uint8_t pci_hdr_type; 909 uint16_t pci_status; 910 pci_regspec_t *pci_rp; 911 int32_t len; 912 uint32_t phys_hi; 913 914 /* 915 * If device is not ereport capbable then report an error against the 916 * driver for using this interface, 917 */ 918 if (!DDI_FM_EREPORT_CAP(ddi_fm_capable(dip)) && 919 !DDI_FM_ERRCB_CAP(ddi_fm_capable(dip))) { 920 i_ddi_drv_ereport_post(dip, DVR_EFMCAP, NULL, DDI_SLEEP); 921 return; 922 } 923 924 /* 925 * ASSERT fmhdl exists and fh_bus_specific is NULL. 926 */ 927 ASSERT(fmhdl && (fmhdl->fh_bus_specific == NULL)); 928 929 erpt_p = kmem_zalloc(sizeof (pci_erpt_t), KM_SLEEP); 930 931 if (pci_config_setup(dip, &erpt_p->pe_hdl) != DDI_SUCCESS) 932 goto error; 933 934 erpt_p->pe_pci_regs = kmem_zalloc(sizeof (pci_error_regs_t), KM_SLEEP); 935 936 pci_status = pci_config_get16(erpt_p->pe_hdl, PCI_CONF_STAT); 937 if (pci_config_check(erpt_p->pe_hdl) != DDI_FM_OK) 938 goto error; 939 940 /* 941 * Get header type and record if device is a bridge. 942 */ 943 pci_hdr_type = pci_config_get8(erpt_p->pe_hdl, PCI_CONF_HEADER); 944 if (pci_config_check(erpt_p->pe_hdl) != DDI_FM_OK) 945 goto error; 946 947 /* 948 * Check to see if PCI device is a bridge, if so allocate pci bridge 949 * error register structure. 950 */ 951 if ((pci_hdr_type & PCI_HEADER_TYPE_M) == PCI_HEADER_PPB) { 952 erpt_p->pe_dflags |= PCI_BRIDGE_DEV; 953 erpt_p->pe_pci_regs->pci_bdg_regs = kmem_zalloc( 954 sizeof (pci_bdg_error_regs_t), KM_SLEEP); 955 } 956 957 if (ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, "reg", 958 (caddr_t)&pci_rp, &len) == DDI_SUCCESS) { 959 phys_hi = pci_rp->pci_phys_hi; 960 kmem_free(pci_rp, len); 961 962 erpt_p->pe_bdf = (uint16_t)(PCI_REG_BDFR_G(phys_hi) >> 963 PCI_REG_FUNC_SHIFT); 964 } 965 966 967 if (!(pci_status & PCI_STAT_CAP)) { 968 goto done; 969 } 970 971 /* 972 * Initialize structures for PCI Express and PCI-X devices. 973 * Order matters below and pcie_ereport_setup should preceed 974 * pcix_ereport_setup. 975 */ 976 pcie_ereport_setup(dip, erpt_p); 977 978 if (!(erpt_p->pe_dflags & PCIEX_DEV)) { 979 pcix_ereport_setup(dip, erpt_p); 980 } 981 982 done: 983 pci_regs_gather(dip, erpt_p); 984 pci_regs_clear(erpt_p); 985 986 /* 987 * Before returning set fh_bus_specific to completed pci_erpt_t 988 * structure 989 */ 990 fmhdl->fh_bus_specific = (void *)erpt_p; 991 992 return; 993 error: 994 if (erpt_p->pe_pci_regs) 995 kmem_free(erpt_p->pe_pci_regs, sizeof (pci_error_regs_t)); 996 kmem_free(erpt_p, sizeof (pci_erpt_t)); 997 erpt_p = NULL; 998 } 999 1000 static void 1001 pcix_ereport_teardown(pci_erpt_t *erpt_p) 1002 { 1003 if (erpt_p->pe_dflags & PCI_BRIDGE_DEV) { 1004 pcix_bdg_error_regs_t *pcix_bdg_regs; 1005 uint16_t pcix_ver; 1006 1007 pcix_bdg_regs = (pcix_bdg_error_regs_t *)erpt_p->pe_regs; 1008 pcix_ver = pcix_bdg_regs->pcix_bdg_ver; 1009 if (PCIX_ECC_VER_CHECK(pcix_ver)) { 1010 int i; 1011 for (i = 0; i < 2; i++) 1012 kmem_free(pcix_bdg_regs->pcix_bdg_ecc_regs[i], 1013 sizeof (pcix_ecc_regs_t)); 1014 } 1015 kmem_free(erpt_p->pe_regs, sizeof (pcix_bdg_error_regs_t)); 1016 } else { 1017 pcix_error_regs_t *pcix_regs; 1018 uint16_t pcix_ver; 1019 1020 pcix_regs = (pcix_error_regs_t *)erpt_p->pe_regs; 1021 pcix_ver = pcix_regs->pcix_ver; 1022 if (PCIX_ECC_VER_CHECK(pcix_ver)) { 1023 kmem_free(pcix_regs->pcix_ecc_regs, 1024 sizeof (pcix_ecc_regs_t)); 1025 } 1026 kmem_free(erpt_p->pe_regs, sizeof (pcix_error_regs_t)); 1027 } 1028 } 1029 1030 static void 1031 pcie_ereport_teardown(pci_erpt_t *erpt_p) 1032 { 1033 pcie_error_regs_t *pcie_regs = (pcie_error_regs_t *)erpt_p->pe_regs; 1034 1035 if (erpt_p->pe_dflags & PCIEX_ADV_DEV) { 1036 pcie_adv_error_regs_t *pcie_adv = pcie_regs->pcie_adv_regs; 1037 1038 if (erpt_p->pe_dflags & PCIEX_2PCI_DEV) 1039 kmem_free(pcie_adv->pcie_adv_bdg_regs, 1040 sizeof (pcie_adv_bdg_error_regs_t)); 1041 if (erpt_p->pe_dflags & PCIEX_RC_DEV) 1042 kmem_free(pcie_adv->pcie_adv_rc_regs, 1043 sizeof (pcie_adv_rc_error_regs_t)); 1044 kmem_free(pcie_adv, sizeof (pcie_adv_error_regs_t)); 1045 } 1046 1047 if (erpt_p->pe_dflags & PCIEX_RC_DEV) 1048 kmem_free(pcie_regs->pcie_rc_regs, 1049 sizeof (pcie_rc_error_regs_t)); 1050 1051 if (erpt_p->pe_dflags & PCI_BRIDGE_DEV) { 1052 if (erpt_p->pe_dflags & PCIX_DEV) { 1053 uint16_t pcix_ver = pcie_regs->pcix_bdg_regs-> 1054 pcix_bdg_ver; 1055 1056 if (PCIX_ECC_VER_CHECK(pcix_ver)) { 1057 int i; 1058 for (i = 0; i < 2; i++) 1059 kmem_free(pcie_regs->pcix_bdg_regs-> 1060 pcix_bdg_ecc_regs[i], 1061 sizeof (pcix_ecc_regs_t)); 1062 } 1063 kmem_free(pcie_regs->pcix_bdg_regs, 1064 sizeof (pcix_bdg_error_regs_t)); 1065 } 1066 } 1067 kmem_free(erpt_p->pe_regs, sizeof (pcie_error_regs_t)); 1068 } 1069 1070 void 1071 pci_ereport_teardown(dev_info_t *dip) 1072 { 1073 struct i_ddi_fmhdl *fmhdl = DEVI(dip)->devi_fmhdl; 1074 pci_erpt_t *erpt_p; 1075 1076 if (!DDI_FM_EREPORT_CAP(ddi_fm_capable(dip)) && 1077 !DDI_FM_ERRCB_CAP(ddi_fm_capable(dip))) { 1078 i_ddi_drv_ereport_post(dip, DVR_EFMCAP, NULL, DDI_SLEEP); 1079 } 1080 1081 ASSERT(fmhdl); 1082 1083 erpt_p = (pci_erpt_t *)fmhdl->fh_bus_specific; 1084 if (erpt_p == NULL) 1085 return; 1086 1087 if (erpt_p->pe_dflags & PCIEX_DEV) 1088 pcie_ereport_teardown(erpt_p); 1089 else if (erpt_p->pe_dflags & PCIX_DEV) 1090 pcix_ereport_teardown(erpt_p); 1091 pci_config_teardown((ddi_acc_handle_t *)&erpt_p->pe_hdl); 1092 if (erpt_p->pe_dflags & PCI_BRIDGE_DEV) 1093 kmem_free(erpt_p->pe_pci_regs->pci_bdg_regs, 1094 sizeof (pci_bdg_error_regs_t)); 1095 kmem_free(erpt_p->pe_pci_regs, sizeof (pci_error_regs_t)); 1096 kmem_free(erpt_p, sizeof (pci_erpt_t)); 1097 fmhdl->fh_bus_specific = NULL; 1098 /* 1099 * The following sparc specific code should be removed once the pci_cap 1100 * interfaces create the necessary properties for us. 1101 */ 1102 #if defined(__sparc) 1103 (void) ndi_prop_remove(DDI_DEV_T_NONE, dip, "pcix-capid-pointer"); 1104 (void) ndi_prop_remove(DDI_DEV_T_NONE, dip, "pcie-slotcap-reg"); 1105 (void) ndi_prop_remove(DDI_DEV_T_NONE, dip, "pcie-capid-reg"); 1106 (void) ndi_prop_remove(DDI_DEV_T_NONE, dip, "pcie-capid-pointer"); 1107 (void) ndi_prop_remove(DDI_DEV_T_NONE, dip, "pcie-aer-pointer"); 1108 #endif 1109 } 1110 1111 /* 1112 * Function used by PCI device and nexus error handlers to check if a 1113 * captured address resides in their DMA or ACC handle caches or the caches of 1114 * their children devices, respectively. 1115 */ 1116 static int 1117 pci_dev_hdl_lookup(dev_info_t *dip, int type, ddi_fm_error_t *derr, 1118 void *addr) 1119 { 1120 struct i_ddi_fmhdl *fmhdl = DEVI(dip)->devi_fmhdl; 1121 pci_erpt_t *erpt_p = (pci_erpt_t *)fmhdl->fh_bus_specific; 1122 1123 if (erpt_p->pe_dflags & PCI_BRIDGE_DEV) 1124 return (ndi_fmc_error(dip, NULL, type, derr->fme_ena, addr)); 1125 else 1126 return (ndi_fmc_entry_error(dip, type, derr, addr)); 1127 } 1128 1129 static void 1130 pcie_ereport_post(dev_info_t *dip, ddi_fm_error_t *derr, pci_erpt_t *erpt_p, 1131 char *buf, int errtype) 1132 { 1133 pcie_error_regs_t *pcie_regs = (pcie_error_regs_t *)erpt_p->pe_regs; 1134 pcie_adv_error_regs_t *pcie_adv_regs = pcie_regs->pcie_adv_regs; 1135 pcie_adv_rc_error_regs_t *pcie_adv_rc_regs = 1136 pcie_adv_regs->pcie_adv_rc_regs; 1137 1138 switch (errtype) { 1139 case PCIEX_TYPE_CE: 1140 ddi_fm_ereport_post(dip, buf, derr->fme_ena, 1141 DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 1142 PCIEX_DEVSTS_REG, DATA_TYPE_UINT16, 1143 pcie_regs->pcie_err_status, 1144 PCIEX_CE_STATUS_REG, DATA_TYPE_UINT32, 1145 pcie_adv_regs->pcie_ce_status, NULL); 1146 break; 1147 case PCIEX_TYPE_UE: 1148 ddi_fm_ereport_post(dip, buf, derr->fme_ena, 1149 DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 1150 PCIEX_DEVSTS_REG, DATA_TYPE_UINT16, 1151 pcie_regs->pcie_err_status, 1152 PCIEX_UE_STATUS_REG, DATA_TYPE_UINT32, 1153 pcie_adv_regs->pcie_ue_status, PCIEX_UE_SEV_REG, 1154 DATA_TYPE_UINT32, pcie_adv_regs->pcie_ue_sev, 1155 PCIEX_ADV_CTL, DATA_TYPE_UINT32, 1156 pcie_adv_regs->pcie_adv_ctl, 1157 PCIEX_SRC_ID, DATA_TYPE_UINT16, 1158 pcie_adv_regs->pcie_adv_bdf, 1159 PCIEX_SRC_VALID, DATA_TYPE_BOOLEAN_VALUE, 1160 (pcie_adv_regs->pcie_adv_bdf != NULL) ? 1161 1 : NULL, 1162 #ifdef DEBUG 1163 PCIEX_UE_HDR0, DATA_TYPE_UINT32, 1164 pcie_adv_regs->pcie_ue_hdr0, 1165 PCIEX_UE_HDR1, DATA_TYPE_UINT32, 1166 pcie_adv_regs->pcie_ue_hdr[0], 1167 PCIEX_UE_HDR2, DATA_TYPE_UINT32, 1168 pcie_adv_regs->pcie_ue_hdr[1], 1169 PCIEX_UE_HDR3, DATA_TYPE_UINT32, 1170 pcie_adv_regs->pcie_ue_hdr[2], 1171 #endif 1172 NULL); 1173 break; 1174 case PCIEX_TYPE_GEN: 1175 ddi_fm_ereport_post(dip, buf, derr->fme_ena, 1176 DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 1177 0, PCIEX_DEVSTS_REG, DATA_TYPE_UINT16, 1178 pcie_regs->pcie_err_status, NULL); 1179 break; 1180 case PCIEX_TYPE_RC_UE_MSG: 1181 case PCIEX_TYPE_RC_CE_MSG: 1182 ddi_fm_ereport_post(dip, buf, derr->fme_ena, 1183 DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 1184 PCIEX_ROOT_ERRSTS_REG, DATA_TYPE_UINT32, 1185 pcie_adv_rc_regs->pcie_rc_err_status, 1186 PCIEX_SRC_ID, DATA_TYPE_UINT16, 1187 (errtype == PCIEX_TYPE_RC_UE_MSG) ? 1188 pcie_adv_rc_regs->pcie_rc_ue_src_id : 1189 pcie_adv_rc_regs->pcie_rc_ce_src_id, 1190 PCIEX_SRC_VALID, DATA_TYPE_BOOLEAN_VALUE, 1191 (errtype == PCIEX_TYPE_RC_UE_MSG) ? 1192 (pcie_adv_regs->pcie_adv_vflags & PCIE_SRC_ID_VALID && 1193 pcie_adv_rc_regs->pcie_rc_ue_src_id != 0) : 1194 (pcie_adv_regs->pcie_adv_vflags & PCIE_SRC_ID_VALID && 1195 pcie_adv_rc_regs->pcie_rc_ce_src_id != 0), NULL); 1196 break; 1197 case PCIEX_TYPE_RC_MULT_MSG: 1198 ddi_fm_ereport_post(dip, buf, derr->fme_ena, 1199 DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 1200 PCIEX_ROOT_ERRSTS_REG, DATA_TYPE_UINT32, 1201 pcie_adv_rc_regs->pcie_rc_err_status, NULL); 1202 break; 1203 default: 1204 break; 1205 } 1206 } 1207 1208 static void 1209 pcie_check_addr(dev_info_t *dip, ddi_fm_error_t *derr, pci_erpt_t *eprt_p) 1210 { 1211 pcie_error_regs_t *pcie_regs = (pcie_error_regs_t *)eprt_p->pe_regs; 1212 pcie_adv_error_regs_t *pcie_adv_regs = pcie_regs->pcie_adv_regs; 1213 pcie_tlp_hdr_t *ue_hdr0; 1214 uint32_t *ue_hdr; 1215 uint64_t addr = NULL; 1216 1217 if (!(pcie_adv_regs->pcie_adv_vflags & PCIE_UE_HDR_VALID)) { 1218 derr->fme_status = DDI_FM_UNKNOWN; 1219 return; 1220 } 1221 ue_hdr0 = (pcie_tlp_hdr_t *)&pcie_adv_regs->pcie_ue_hdr0; 1222 ue_hdr = pcie_adv_regs->pcie_ue_hdr; 1223 1224 switch (ue_hdr0->type) { 1225 case PCIE_TLP_TYPE_MEM: 1226 case PCIE_TLP_TYPE_MEMLK: 1227 if ((ue_hdr0->fmt & 0x1) == 0x1) { 1228 pcie_mem64_t *mem64_tlp = (pcie_mem64_t *)ue_hdr; 1229 1230 addr = (uint64_t)mem64_tlp->addr1 << 32 | 1231 (uint32_t)mem64_tlp->addr0 << 2; 1232 pcie_adv_regs->pcie_adv_bdf = mem64_tlp->rid; 1233 } else { 1234 pcie_memio32_t *memio32_tlp = (pcie_memio32_t *)ue_hdr; 1235 1236 addr = (uint32_t)memio32_tlp->addr0 << 2; 1237 pcie_adv_regs->pcie_adv_bdf = memio32_tlp->rid; 1238 } 1239 1240 derr->fme_status = pci_dev_hdl_lookup(dip, DMA_HANDLE, derr, 1241 (void *) &addr); 1242 /* 1243 * If DMA handle is not found error could have been a memory 1244 * mapped IO address so check in the access cache 1245 */ 1246 if (derr->fme_status == DDI_FM_UNKNOWN) 1247 derr->fme_status = pci_dev_hdl_lookup(dip, ACC_HANDLE, 1248 derr, (void *) &addr); 1249 break; 1250 1251 case PCIE_TLP_TYPE_IO: 1252 { 1253 pcie_memio32_t *memio32_tlp = (pcie_memio32_t *)ue_hdr; 1254 1255 addr = (uint32_t)memio32_tlp->addr0 << 2; 1256 pcie_adv_regs->pcie_adv_bdf = memio32_tlp->rid; 1257 derr->fme_status = pci_dev_hdl_lookup(dip, ACC_HANDLE, 1258 derr, (void *) &addr); 1259 break; 1260 } 1261 case PCIE_TLP_TYPE_CFG0: 1262 case PCIE_TLP_TYPE_CFG1: 1263 { 1264 pcie_cfg_t *cfg_tlp = (pcie_cfg_t *)ue_hdr; 1265 1266 pcie_adv_regs->pcie_adv_bdf = 1267 (uint16_t)cfg_tlp->bus << 8 | 1268 (uint16_t)cfg_tlp->dev << 3 | cfg_tlp->func; 1269 1270 derr->fme_status = DDI_FM_UNKNOWN; 1271 break; 1272 } 1273 case PCIE_TLP_TYPE_MSG: 1274 { 1275 pcie_msg_t *msg_tlp = (pcie_msg_t *)ue_hdr; 1276 1277 pcie_adv_regs->pcie_adv_bdf = msg_tlp->rid; 1278 derr->fme_status = DDI_FM_UNKNOWN; 1279 break; 1280 } 1281 case PCIE_TLP_TYPE_CPL: 1282 case PCIE_TLP_TYPE_CPLLK: 1283 { 1284 pcie_cpl_t *cpl_tlp = (pcie_cpl_t *)ue_hdr; 1285 1286 pcie_adv_regs->pcie_adv_bdf = cpl_tlp->cid; 1287 derr->fme_status = DDI_FM_UNKNOWN; 1288 break; 1289 } 1290 case PCIE_TLP_TYPE_MSI: 1291 default: 1292 derr->fme_status = DDI_FM_UNKNOWN; 1293 } 1294 1295 /* 1296 * If no handle was found in the children caches and their is no 1297 * address infomation already stored and we have a captured address 1298 * then we need to store it away so that intermediate bridges can 1299 * check if the address exists in their handle caches. 1300 */ 1301 if (derr->fme_status == DDI_FM_UNKNOWN && 1302 derr->fme_bus_specific == NULL && 1303 addr != NULL) 1304 derr->fme_bus_specific = (void *)(uintptr_t)addr; 1305 } 1306 1307 static void 1308 pcie_pci_check_addr(dev_info_t *dip, ddi_fm_error_t *derr, pci_erpt_t *eprt_p) 1309 { 1310 pcie_error_regs_t *pcie_regs = (pcie_error_regs_t *)eprt_p->pe_regs; 1311 pcie_adv_error_regs_t *pcie_adv_regs = pcie_regs->pcie_adv_regs; 1312 pcie_adv_bdg_error_regs_t *pcie_bdg_regs = 1313 pcie_adv_regs->pcie_adv_bdg_regs; 1314 uint64_t addr = NULL; 1315 pcix_attr_t *pcie_pci_sue_attr; 1316 int cmd; 1317 int dual_addr = 0; 1318 1319 if (!(pcie_adv_regs->pcie_adv_vflags & PCIE_SUE_HDR_VALID)) { 1320 derr->fme_status = DDI_FM_UNKNOWN; 1321 return; 1322 } 1323 1324 pcie_pci_sue_attr = (pcix_attr_t *)&pcie_bdg_regs->pcie_sue_hdr0; 1325 cmd = (pcie_bdg_regs->pcie_sue_hdr[0] >> 1326 PCIE_AER_SUCE_HDR_CMD_LWR_SHIFT) & PCIE_AER_SUCE_HDR_CMD_LWR_MASK; 1327 cmd_switch: 1328 switch (cmd) { 1329 case PCI_PCIX_CMD_IORD: 1330 case PCI_PCIX_CMD_IOWR: 1331 pcie_adv_regs->pcie_adv_bdf = pcie_pci_sue_attr->rid; 1332 1333 addr = pcie_bdg_regs->pcie_sue_hdr[2]; 1334 addr = (addr << PCIE_AER_SUCE_HDR_ADDR_SHIFT) | 1335 pcie_bdg_regs->pcie_sue_hdr[1]; 1336 1337 derr->fme_status = pci_dev_hdl_lookup(dip, ACC_HANDLE, 1338 derr, (void *) &addr); 1339 break; 1340 case PCI_PCIX_CMD_MEMRD_DW: 1341 case PCI_PCIX_CMD_MEMWR: 1342 case PCI_PCIX_CMD_MEMRD_BL: 1343 case PCI_PCIX_CMD_MEMWR_BL: 1344 case PCI_PCIX_CMD_MEMRDBL: 1345 case PCI_PCIX_CMD_MEMWRBL: 1346 pcie_adv_regs->pcie_adv_bdf = pcie_pci_sue_attr->rid; 1347 1348 addr = pcie_bdg_regs->pcie_sue_hdr[2]; 1349 addr = (addr << PCIE_AER_SUCE_HDR_ADDR_SHIFT) | 1350 pcie_bdg_regs->pcie_sue_hdr[1]; 1351 1352 derr->fme_status = pci_dev_hdl_lookup(dip, DMA_HANDLE, 1353 derr, (void *) &addr); 1354 if (derr->fme_status == DDI_FM_UNKNOWN) 1355 derr->fme_status = pci_dev_hdl_lookup(dip, ACC_HANDLE, 1356 derr, (void *) &addr); 1357 break; 1358 case PCI_PCIX_CMD_CFRD: 1359 case PCI_PCIX_CMD_CFWR: 1360 /* 1361 * If we want to store the bdf of the device being addressed we 1362 * will need to do some surgery 1363 */ 1364 derr->fme_status = DDI_FM_UNKNOWN; 1365 break; 1366 case PCI_PCIX_CMD_DADR: 1367 cmd = (pcie_bdg_regs->pcie_sue_hdr[0] >> 1368 PCIE_AER_SUCE_HDR_CMD_UP_SHIFT) & 1369 PCIE_AER_SUCE_HDR_CMD_UP_MASK; 1370 if (dual_addr) 1371 break; 1372 ++dual_addr; 1373 goto cmd_switch; 1374 default: 1375 derr->fme_status = DDI_FM_UNKNOWN; 1376 } 1377 1378 /* 1379 * If no handle was found in the children caches and their is no 1380 * address infomation already stored and we have a captured address 1381 * then we need to store it away so that intermediate bridges can 1382 * check if the address exists in their handle caches. 1383 */ 1384 if (derr->fme_status == DDI_FM_UNKNOWN && 1385 derr->fme_bus_specific == NULL && 1386 addr != NULL) 1387 derr->fme_bus_specific = (void *)(uintptr_t)addr; 1388 } 1389 1390 static int 1391 pcix_check_addr(dev_info_t *dip, ddi_fm_error_t *derr, 1392 pcix_ecc_regs_t *pcix_ecc_regs) 1393 { 1394 int cmd = (pcix_ecc_regs->pcix_ecc_ctlstat >> 16) & 0xf; 1395 uint64_t addr; 1396 1397 addr = pcix_ecc_regs->pcix_ecc_secaddr; 1398 addr = addr << 32; 1399 addr |= pcix_ecc_regs->pcix_ecc_fstaddr; 1400 1401 switch (cmd) { 1402 case PCI_PCIX_CMD_INTR: 1403 case PCI_PCIX_CMD_SPEC: 1404 return (DDI_FM_FATAL); 1405 case PCI_PCIX_CMD_IORD: 1406 case PCI_PCIX_CMD_IOWR: 1407 return (pci_dev_hdl_lookup(dip, ACC_HANDLE, derr, 1408 (void *) &addr)); 1409 case PCI_PCIX_CMD_DEVID: 1410 return (DDI_FM_FATAL); 1411 case PCI_PCIX_CMD_MEMRD_DW: 1412 case PCI_PCIX_CMD_MEMWR: 1413 case PCI_PCIX_CMD_MEMRD_BL: 1414 case PCI_PCIX_CMD_MEMWR_BL: 1415 return (pci_dev_hdl_lookup(dip, DMA_HANDLE, derr, 1416 (void *) &addr)); 1417 case PCI_PCIX_CMD_CFRD: 1418 case PCI_PCIX_CMD_CFWR: 1419 return (pci_dev_hdl_lookup(dip, ACC_HANDLE, derr, 1420 (void *) &addr)); 1421 case PCI_PCIX_CMD_SPL: 1422 case PCI_PCIX_CMD_DADR: 1423 return (DDI_FM_FATAL); 1424 case PCI_PCIX_CMD_MEMRDBL: 1425 case PCI_PCIX_CMD_MEMWRBL: 1426 return (pci_dev_hdl_lookup(dip, DMA_HANDLE, derr, 1427 (void *) &addr)); 1428 default: 1429 return (DDI_FM_FATAL); 1430 } 1431 } 1432 1433 /*ARGSUSED*/ 1434 static int 1435 pci_bdg_error_report(dev_info_t *dip, ddi_fm_error_t *derr, pci_erpt_t *erpt_p) 1436 { 1437 pci_bdg_error_regs_t *pci_bdg_regs = erpt_p->pe_pci_regs->pci_bdg_regs; 1438 int fatal = 0; 1439 int nonfatal = 0; 1440 int unknown = 0; 1441 int ok = 0; 1442 int ret = DDI_FM_OK; 1443 char buf[FM_MAX_CLASS]; 1444 int i; 1445 1446 if (derr->fme_flag != DDI_FM_ERR_UNEXPECTED) 1447 goto done; 1448 1449 if ((pci_bdg_regs->pci_bdg_vflags & PCI_BDG_CTRL_VALID) && 1450 (pci_bdg_regs->pci_bdg_ctrl & PCI_BCNF_BCNTRL_DTO_STAT)) { 1451 (void) snprintf(buf, FM_MAX_CLASS, "%s.%s", 1452 PCI_ERROR_SUBCLASS, PCI_DTO); 1453 ddi_fm_ereport_post(dip, buf, derr->fme_ena, 1454 DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 1455 PCI_SEC_CONFIG_STATUS, DATA_TYPE_UINT16, 1456 pci_bdg_regs->pci_bdg_sec_stat, PCI_BCNTRL, 1457 DATA_TYPE_UINT16, pci_bdg_regs->pci_bdg_ctrl, NULL); 1458 unknown++; 1459 } 1460 1461 if (pci_bdg_regs->pci_bdg_vflags & PCI_BDG_SEC_STAT_VALID) { 1462 for (i = 0; pci_bdg_err_tbl[i].err_class != NULL; i++) { 1463 if (pci_bdg_regs->pci_bdg_sec_stat & 1464 pci_bdg_err_tbl[i].reg_bit) { 1465 (void) snprintf(buf, FM_MAX_CLASS, "%s.%s-%s", 1466 PCI_ERROR_SUBCLASS, PCI_SEC_ERROR_SUBCLASS, 1467 pci_bdg_err_tbl[i].err_class); 1468 ddi_fm_ereport_post(dip, buf, derr->fme_ena, 1469 DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 1470 PCI_SEC_CONFIG_STATUS, DATA_TYPE_UINT16, 1471 pci_bdg_regs->pci_bdg_sec_stat, PCI_BCNTRL, 1472 DATA_TYPE_UINT16, 1473 pci_bdg_regs->pci_bdg_ctrl, NULL); 1474 /* 1475 * Increment severity based on flag if bridge 1476 * is PCI or PCI-X, if PCI Express and this is a 1477 * master abort then treat as nonfatal. 1478 * XXFM May need to check if all other errors 1479 * are related to MA? 1480 */ 1481 if (!(erpt_p->pe_dflags & PCIEX_DEV)) { 1482 PCI_FM_SEV_INC( 1483 pci_bdg_err_tbl[i].flags); 1484 } else if (pci_bdg_err_tbl[i].reg_bit == 1485 PCI_STAT_R_MAST_AB) { 1486 nonfatal++; 1487 } 1488 1489 if (derr->fme_bus_specific && 1490 pci_bdg_err_tbl[i].terr_class) 1491 pci_target_enqueue(derr->fme_ena, 1492 pci_bdg_err_tbl[i].terr_class, 1493 PCI_ERROR_SUBCLASS, 1494 (uintptr_t)derr->fme_bus_specific); 1495 } 1496 } 1497 } 1498 1499 done: 1500 1501 /* 1502 * Need to check for poke and cautious put. We already know peek 1503 * and cautious get errors occurred (as we got a trap) and we know 1504 * they are nonfatal. 1505 */ 1506 if (derr->fme_flag == DDI_FM_ERR_EXPECTED) { 1507 /* 1508 * for cautious puts we treat all errors as nonfatal. Actually 1509 * we set nonfatal for cautious gets as well - doesn't do any 1510 * harm 1511 */ 1512 if (pci_bdg_regs->pci_bdg_sec_stat & (PCI_STAT_R_TARG_AB | 1513 PCI_STAT_R_MAST_AB | PCI_STAT_S_PERROR | PCI_STAT_S_SYSERR)) 1514 nonfatal++; 1515 1516 /* 1517 * for cautious accesses we already have the acc_handle. Just 1518 * need to call children to clear their error bits 1519 */ 1520 ret = ndi_fm_handler_dispatch(dip, NULL, derr); 1521 PCI_FM_SEV_INC(ret); 1522 return (fatal ? DDI_FM_FATAL : (nonfatal ? DDI_FM_NONFATAL : 1523 (unknown ? DDI_FM_UNKNOWN : DDI_FM_OK))); 1524 } 1525 if (derr->fme_flag == DDI_FM_ERR_POKE) { 1526 /* 1527 * special case for pokes - we only consider master abort 1528 * and target abort as nonfatal. Sserr with no master abort is 1529 * fatal, but master/target abort can come in on separate 1530 * instance, so return unknown and parent will determine if 1531 * nonfatal (if another child returned nonfatal - ie master 1532 * or target abort) or fatal otherwise 1533 */ 1534 if (pci_bdg_regs->pci_bdg_sec_stat & (PCI_STAT_R_TARG_AB | 1535 PCI_STAT_R_MAST_AB)) 1536 nonfatal++; 1537 if (erpt_p->pe_pci_regs->pci_err_status & PCI_STAT_S_SYSERR) 1538 unknown++; 1539 } 1540 1541 /* 1542 * If errant address is passed in then attempt to find 1543 * ACC/DMA handle in caches. 1544 */ 1545 if (derr->fme_bus_specific) { 1546 int i; 1547 1548 for (i = 0; i < 2; i++) { 1549 ret = ndi_fmc_error(dip, NULL, i ? ACC_HANDLE : 1550 DMA_HANDLE, derr->fme_ena, 1551 (void *)&derr->fme_bus_specific); 1552 PCI_FM_SEV_INC(ret); 1553 } 1554 } 1555 1556 /* 1557 * now check children below the bridge, only if errant handle was not 1558 * found 1559 */ 1560 if (!derr->fme_acc_handle && !derr->fme_dma_handle) { 1561 ret = ndi_fm_handler_dispatch(dip, NULL, derr); 1562 PCI_FM_SEV_INC(ret); 1563 } 1564 1565 return (fatal ? DDI_FM_FATAL : (nonfatal ? DDI_FM_NONFATAL : 1566 (unknown ? DDI_FM_UNKNOWN : DDI_FM_OK))); 1567 } 1568 1569 static int 1570 pcix_ecc_error_report(dev_info_t *dip, ddi_fm_error_t *derr, pci_erpt_t *erpt_p, 1571 void *pe_regs) 1572 { 1573 pcix_error_regs_t *pcix_regs; 1574 pcix_bdg_error_regs_t *pcix_bdg_regs; 1575 pcix_ecc_regs_t *pcix_ecc_regs; 1576 int bridge; 1577 int i; 1578 int ecc_phase; 1579 int ecc_corr; 1580 int sec_ue; 1581 int sec_ce; 1582 int fatal = 0; 1583 int nonfatal = 0; 1584 int unknown = 0; 1585 int ok = 0; 1586 char buf[FM_MAX_CLASS]; 1587 1588 if (erpt_p->pe_dflags & PCI_BRIDGE_DEV) { 1589 pcix_bdg_regs = (pcix_bdg_error_regs_t *)pe_regs; 1590 bridge = 1; 1591 } else { 1592 pcix_regs = (pcix_error_regs_t *)pe_regs; 1593 bridge = 0; 1594 } 1595 1596 for (i = 0; i < (bridge ? 2 : 1); i++) { 1597 int ret = DDI_FM_OK; 1598 pcix_ecc_regs = bridge ? pcix_bdg_regs->pcix_bdg_ecc_regs[i] : 1599 pcix_regs->pcix_ecc_regs; 1600 if (pcix_ecc_regs->pcix_ecc_vflags & PCIX_ERR_ECC_STS_VALID) { 1601 ecc_phase = (pcix_ecc_regs->pcix_ecc_ctlstat & 1602 PCI_PCIX_ECC_PHASE) >> 0x4; 1603 ecc_corr = (pcix_ecc_regs->pcix_ecc_ctlstat & 1604 PCI_PCIX_ECC_CORR); 1605 sec_ue = (pcix_ecc_regs->pcix_ecc_ctlstat & 1606 PCI_PCIX_ECC_S_UE); 1607 sec_ce = (pcix_ecc_regs->pcix_ecc_ctlstat & 1608 PCI_PCIX_ECC_S_CE); 1609 1610 switch (ecc_phase) { 1611 case PCI_PCIX_ECC_PHASE_NOERR: 1612 break; 1613 case PCI_PCIX_ECC_PHASE_FADDR: 1614 case PCI_PCIX_ECC_PHASE_SADDR: 1615 PCI_FM_SEV_INC(ecc_corr ? DDI_FM_NONFATAL : 1616 DDI_FM_FATAL); 1617 (void) snprintf(buf, FM_MAX_CLASS, 1618 "%s.%s%s", PCIX_ERROR_SUBCLASS, 1619 i ? PCIX_SEC_ERROR_SUBCLASS : "", 1620 ecc_corr ? PCIX_ECC_CE_ADDR : 1621 PCIX_ECC_UE_ADDR); 1622 break; 1623 case PCI_PCIX_ECC_PHASE_ATTR: 1624 PCI_FM_SEV_INC(ecc_corr ? 1625 DDI_FM_NONFATAL : DDI_FM_FATAL); 1626 (void) snprintf(buf, FM_MAX_CLASS, 1627 "%s.%s%s", PCIX_ERROR_SUBCLASS, 1628 i ? PCIX_SEC_ERROR_SUBCLASS : "", 1629 ecc_corr ? PCIX_ECC_CE_ATTR : 1630 PCIX_ECC_UE_ATTR); 1631 break; 1632 case PCI_PCIX_ECC_PHASE_DATA32: 1633 case PCI_PCIX_ECC_PHASE_DATA64: 1634 if (ecc_corr) 1635 ret = DDI_FM_NONFATAL; 1636 else 1637 ret = pcix_check_addr(dip, derr, 1638 pcix_ecc_regs); 1639 PCI_FM_SEV_INC(ret); 1640 1641 (void) snprintf(buf, FM_MAX_CLASS, 1642 "%s.%s%s", PCIX_ERROR_SUBCLASS, 1643 i ? PCIX_SEC_ERROR_SUBCLASS : "", 1644 ecc_corr ? PCIX_ECC_CE_DATA : 1645 PCIX_ECC_UE_DATA); 1646 break; 1647 } 1648 if (ecc_phase) 1649 if (bridge) 1650 ddi_fm_ereport_post(dip, buf, 1651 derr->fme_ena, 1652 DDI_NOSLEEP, FM_VERSION, 1653 DATA_TYPE_UINT8, 0, 1654 PCIX_SEC_STATUS, DATA_TYPE_UINT16, 1655 pcix_bdg_regs->pcix_bdg_sec_stat, 1656 PCIX_BDG_STAT, DATA_TYPE_UINT32, 1657 pcix_bdg_regs->pcix_bdg_stat, 1658 PCIX_ECC_CTLSTAT, DATA_TYPE_UINT32, 1659 pcix_ecc_regs->pcix_ecc_ctlstat, 1660 PCIX_ECC_ATTR, DATA_TYPE_UINT32, 1661 pcix_ecc_regs->pcix_ecc_attr, NULL); 1662 else 1663 ddi_fm_ereport_post(dip, buf, 1664 derr->fme_ena, 1665 DDI_NOSLEEP, FM_VERSION, 1666 DATA_TYPE_UINT8, 0, 1667 PCIX_COMMAND, DATA_TYPE_UINT16, 1668 pcix_regs->pcix_command, 1669 PCIX_STATUS, DATA_TYPE_UINT32, 1670 pcix_regs->pcix_status, 1671 PCIX_ECC_CTLSTAT, DATA_TYPE_UINT32, 1672 pcix_ecc_regs->pcix_ecc_ctlstat, 1673 PCIX_ECC_ATTR, DATA_TYPE_UINT32, 1674 pcix_ecc_regs->pcix_ecc_attr, NULL); 1675 if (sec_ce || sec_ue) { 1676 (void) snprintf(buf, FM_MAX_CLASS, 1677 "%s.%s%s", PCIX_ERROR_SUBCLASS, 1678 i ? PCIX_SEC_ERROR_SUBCLASS : "", 1679 sec_ce ? PCIX_ECC_S_CE : PCIX_ECC_S_UE); 1680 if (bridge) 1681 ddi_fm_ereport_post(dip, buf, 1682 derr->fme_ena, 1683 DDI_NOSLEEP, FM_VERSION, 1684 DATA_TYPE_UINT8, 0, 1685 PCIX_SEC_STATUS, DATA_TYPE_UINT16, 1686 pcix_bdg_regs->pcix_bdg_sec_stat, 1687 PCIX_BDG_STAT, DATA_TYPE_UINT32, 1688 pcix_bdg_regs->pcix_bdg_stat, 1689 PCIX_ECC_CTLSTAT, DATA_TYPE_UINT32, 1690 pcix_ecc_regs->pcix_ecc_ctlstat, 1691 PCIX_ECC_ATTR, DATA_TYPE_UINT32, 1692 pcix_ecc_regs->pcix_ecc_attr, NULL); 1693 else 1694 ddi_fm_ereport_post(dip, buf, 1695 derr->fme_ena, 1696 DDI_NOSLEEP, FM_VERSION, 1697 DATA_TYPE_UINT8, 0, 1698 PCIX_COMMAND, DATA_TYPE_UINT16, 1699 pcix_regs->pcix_command, 1700 PCIX_STATUS, DATA_TYPE_UINT32, 1701 pcix_regs->pcix_status, 1702 PCIX_ECC_CTLSTAT, DATA_TYPE_UINT32, 1703 pcix_ecc_regs->pcix_ecc_ctlstat, 1704 PCIX_ECC_ATTR, DATA_TYPE_UINT32, 1705 pcix_ecc_regs->pcix_ecc_attr, NULL); 1706 PCI_FM_SEV_INC(sec_ue ? DDI_FM_FATAL : 1707 DDI_FM_NONFATAL); 1708 } 1709 } 1710 } 1711 return (fatal ? DDI_FM_FATAL : (nonfatal ? DDI_FM_NONFATAL : 1712 (unknown ? DDI_FM_UNKNOWN : DDI_FM_OK))); 1713 } 1714 1715 static int 1716 pcix_bdg_error_report(dev_info_t *dip, ddi_fm_error_t *derr, pci_erpt_t *erpt_p, 1717 void *pe_regs) 1718 { 1719 pcix_bdg_error_regs_t *pcix_bdg_regs = (pcix_bdg_error_regs_t *)pe_regs; 1720 int fatal = 0; 1721 int nonfatal = 0; 1722 int unknown = 0; 1723 int ok = 0; 1724 char buf[FM_MAX_CLASS]; 1725 int i; 1726 1727 if (pcix_bdg_regs->pcix_bdg_vflags & PCIX_BDG_STATUS_VALID) { 1728 for (i = 0; pcix_err_tbl[i].err_class != NULL; i++) { 1729 if ((pcix_bdg_regs->pcix_bdg_stat & 1730 pcix_err_tbl[i].reg_bit)) { 1731 (void) snprintf(buf, FM_MAX_CLASS, "%s.%s", 1732 PCIX_ERROR_SUBCLASS, 1733 pcix_err_tbl[i].err_class); 1734 ddi_fm_ereport_post(dip, buf, derr->fme_ena, 1735 DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 1736 PCIX_SEC_STATUS, DATA_TYPE_UINT16, 1737 pcix_bdg_regs->pcix_bdg_sec_stat, 1738 PCIX_BDG_STAT, DATA_TYPE_UINT32, 1739 pcix_bdg_regs->pcix_bdg_stat, NULL); 1740 PCI_FM_SEV_INC(pcix_err_tbl[i].flags); 1741 } 1742 } 1743 } 1744 1745 if (pcix_bdg_regs->pcix_bdg_vflags & PCIX_BDG_SEC_STATUS_VALID) { 1746 for (i = 0; pcix_sec_err_tbl[i].err_class != NULL; i++) { 1747 if ((pcix_bdg_regs->pcix_bdg_sec_stat & 1748 pcix_sec_err_tbl[i].reg_bit)) { 1749 (void) snprintf(buf, FM_MAX_CLASS, "%s.%s%s", 1750 PCIX_ERROR_SUBCLASS, 1751 PCIX_SEC_ERROR_SUBCLASS, 1752 pcix_sec_err_tbl[i].err_class); 1753 ddi_fm_ereport_post(dip, buf, derr->fme_ena, 1754 DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 1755 PCIX_SEC_STATUS, DATA_TYPE_UINT16, 1756 pcix_bdg_regs->pcix_bdg_sec_stat, 1757 PCIX_BDG_STAT, DATA_TYPE_UINT32, 1758 pcix_bdg_regs->pcix_bdg_stat, NULL); 1759 PCI_FM_SEV_INC(pcix_sec_err_tbl[i].flags); 1760 } 1761 } 1762 } 1763 1764 /* Log/Handle ECC errors */ 1765 if (PCIX_ECC_VER_CHECK(pcix_bdg_regs->pcix_bdg_ver)) { 1766 int ret; 1767 1768 ret = pcix_ecc_error_report(dip, derr, erpt_p, 1769 (void *)pcix_bdg_regs); 1770 PCI_FM_SEV_INC(ret); 1771 } 1772 return (fatal ? DDI_FM_FATAL : (nonfatal ? DDI_FM_NONFATAL : 1773 (unknown ? DDI_FM_UNKNOWN : DDI_FM_OK))); 1774 } 1775 1776 static int 1777 pcix_error_report(dev_info_t *dip, ddi_fm_error_t *derr, pci_erpt_t *erpt_p) 1778 { 1779 pcix_error_regs_t *pcix_regs = (pcix_error_regs_t *)erpt_p->pe_regs; 1780 int fatal = 0; 1781 int nonfatal = 0; 1782 int unknown = 0; 1783 int ok = 0; 1784 char buf[FM_MAX_CLASS]; 1785 int i; 1786 1787 if (pcix_regs->pcix_vflags & PCIX_ERR_STATUS_VALID) { 1788 for (i = 0; pcix_err_tbl[i].err_class != NULL; i++) { 1789 if (!(pcix_regs->pcix_status & pcix_err_tbl[i].reg_bit)) 1790 continue; 1791 1792 (void) snprintf(buf, FM_MAX_CLASS, "%s.%s", 1793 PCIX_ERROR_SUBCLASS, pcix_err_tbl[i].err_class); 1794 ddi_fm_ereport_post(dip, buf, derr->fme_ena, 1795 DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 1796 PCIX_COMMAND, DATA_TYPE_UINT16, 1797 pcix_regs->pcix_command, PCIX_STATUS, 1798 DATA_TYPE_UINT32, pcix_regs->pcix_status, 1799 NULL); 1800 PCI_FM_SEV_INC(pcix_err_tbl[i].flags); 1801 } 1802 } 1803 /* Log/Handle ECC errors */ 1804 if (PCIX_ECC_VER_CHECK(pcix_regs->pcix_ver)) { 1805 int ret = pcix_ecc_error_report(dip, derr, erpt_p, 1806 (void *)pcix_regs); 1807 PCI_FM_SEV_INC(ret); 1808 } 1809 1810 return (fatal ? DDI_FM_FATAL : (nonfatal ? DDI_FM_NONFATAL : 1811 (unknown ? DDI_FM_UNKNOWN : DDI_FM_OK))); 1812 } 1813 1814 static int 1815 pcie_rc_error_report(dev_info_t *dip, ddi_fm_error_t *derr, pci_erpt_t *erpt_p, 1816 void *pe_regs) 1817 { 1818 pcie_adv_error_regs_t *pcie_adv_regs = (pcie_adv_error_regs_t *)pe_regs; 1819 int fatal = 0; 1820 int nonfatal = 0; 1821 int unknown = 0; 1822 char buf[FM_MAX_CLASS]; 1823 1824 if (pcie_adv_regs->pcie_adv_vflags & PCIE_RC_ERR_STATUS_VALID) { 1825 pcie_adv_rc_error_regs_t *pcie_rc_regs = 1826 pcie_adv_regs->pcie_adv_rc_regs; 1827 int ce, ue, mult_ce, mult_ue, first_ue_fatal, nfe, fe; 1828 1829 ce = pcie_rc_regs->pcie_rc_err_status & 1830 PCIE_AER_RE_STS_CE_RCVD; 1831 ue = pcie_rc_regs->pcie_rc_err_status & 1832 PCIE_AER_RE_STS_FE_NFE_RCVD; 1833 mult_ce = pcie_rc_regs->pcie_rc_err_status & 1834 PCIE_AER_RE_STS_MUL_CE_RCVD; 1835 mult_ue = pcie_rc_regs->pcie_rc_err_status & 1836 PCIE_AER_RE_STS_MUL_FE_NFE_RCVD; 1837 first_ue_fatal = pcie_rc_regs->pcie_rc_err_status & 1838 PCIE_AER_RE_STS_FIRST_UC_FATAL; 1839 nfe = pcie_rc_regs->pcie_rc_err_status & 1840 PCIE_AER_RE_STS_NFE_MSGS_RCVD; 1841 fe = pcie_rc_regs->pcie_rc_err_status & 1842 PCIE_AER_RE_STS_FE_MSGS_RCVD; 1843 /* 1844 * log fatal/nonfatal/corrected messages 1845 * recieved by root complex 1846 */ 1847 if (ue && fe) 1848 fatal++; 1849 else if (ce && !ue) 1850 nonfatal++; 1851 1852 if (fe && first_ue_fatal) { 1853 (void) snprintf(buf, FM_MAX_CLASS, 1854 "%s.%s", PCIEX_ERROR_SUBCLASS, PCIEX_RC_FE_MSG); 1855 pcie_ereport_post(dip, derr, erpt_p, buf, 1856 PCIEX_TYPE_RC_UE_MSG); 1857 } 1858 if (nfe && !first_ue_fatal) { 1859 (void) snprintf(buf, FM_MAX_CLASS, 1860 "%s.%s", PCIEX_ERROR_SUBCLASS, PCIEX_RC_NFE_MSG); 1861 pcie_ereport_post(dip, derr, erpt_p, buf, 1862 PCIEX_TYPE_RC_UE_MSG); 1863 } 1864 if (ce) { 1865 (void) snprintf(buf, FM_MAX_CLASS, 1866 "%s.%s", PCIEX_ERROR_SUBCLASS, PCIEX_RC_CE_MSG); 1867 pcie_ereport_post(dip, derr, erpt_p, buf, 1868 PCIEX_TYPE_RC_CE_MSG); 1869 } 1870 if (mult_ce) { 1871 (void) snprintf(buf, FM_MAX_CLASS, 1872 "%s.%s", PCIEX_ERROR_SUBCLASS, PCIEX_RC_MCE_MSG); 1873 pcie_ereport_post(dip, derr, erpt_p, buf, 1874 PCIEX_TYPE_RC_MULT_MSG); 1875 } 1876 if (mult_ue) { 1877 (void) snprintf(buf, FM_MAX_CLASS, 1878 "%s.%s", PCIEX_ERROR_SUBCLASS, PCIEX_RC_MUE_MSG); 1879 pcie_ereport_post(dip, derr, erpt_p, buf, 1880 PCIEX_TYPE_RC_MULT_MSG); 1881 } 1882 } 1883 return (fatal ? DDI_FM_FATAL : (nonfatal ? DDI_FM_NONFATAL : 1884 (unknown ? DDI_FM_UNKNOWN : DDI_FM_OK))); 1885 } 1886 1887 static int 1888 pcie_error_report(dev_info_t *dip, ddi_fm_error_t *derr, pci_erpt_t *erpt_p) 1889 { 1890 int fatal = 0; 1891 int nonfatal = 0; 1892 int unknown = 0; 1893 int ok = 0; 1894 char buf[FM_MAX_CLASS]; 1895 int i; 1896 pcie_error_regs_t *pcie_regs = (pcie_error_regs_t *)erpt_p->pe_regs; 1897 pcie_adv_error_regs_t *pcie_adv_regs; 1898 pcie_adv_bdg_error_regs_t *pcie_bdg_regs; 1899 1900 if ((erpt_p->pe_dflags & PCI_BRIDGE_DEV) && 1901 (erpt_p->pe_dflags & PCIX_DEV)) { 1902 int ret = pcix_bdg_error_report(dip, derr, erpt_p, 1903 (void *)pcie_regs->pcix_bdg_regs); 1904 PCI_FM_SEV_INC(ret); 1905 } 1906 1907 if (!(erpt_p->pe_dflags & PCIEX_ADV_DEV)) { 1908 if (!(pcie_regs->pcie_vflags & PCIE_ERR_STATUS_VALID)) 1909 goto done; 1910 for (i = 0; pciex_nadv_err_tbl[i].err_class != NULL; i++) { 1911 if (!(pcie_regs->pcie_err_status & 1912 pciex_nadv_err_tbl[i].reg_bit)) 1913 continue; 1914 1915 (void) snprintf(buf, FM_MAX_CLASS, "%s.%s", 1916 PCIEX_ERROR_SUBCLASS, 1917 pciex_nadv_err_tbl[i].err_class); 1918 pcie_ereport_post(dip, derr, erpt_p, buf, 1919 PCIEX_TYPE_GEN); 1920 PCI_FM_SEV_INC(pciex_nadv_err_tbl[i].flags); 1921 } 1922 goto done; 1923 } 1924 1925 pcie_adv_regs = pcie_regs->pcie_adv_regs; 1926 1927 /* 1928 * Log PCI Express uncorrectable errors 1929 */ 1930 if (pcie_adv_regs->pcie_adv_vflags & PCIE_UE_STATUS_VALID) { 1931 for (i = 0; pciex_ue_err_tbl[i].err_class != NULL; i++) { 1932 if (!(pcie_adv_regs->pcie_ue_status & 1933 pciex_ue_err_tbl[i].reg_bit)) 1934 continue; 1935 1936 (void) snprintf(buf, FM_MAX_CLASS, 1937 "%s.%s", PCIEX_ERROR_SUBCLASS, 1938 pciex_ue_err_tbl[i].err_class); 1939 1940 pcie_adv_regs->pcie_adv_bdf = 0; 1941 if ((pcie_adv_regs->pcie_ue_status & 1942 PCIE_AER_UCE_LOG_BITS) != 1943 pciex_ue_err_tbl[i].reg_bit) { 1944 PCI_FM_SEV_INC(pciex_ue_err_tbl[i].flags); 1945 pcie_ereport_post(dip, derr, erpt_p, buf, 1946 PCIEX_TYPE_UE); 1947 } else { 1948 pcie_check_addr(dip, derr, erpt_p); 1949 /* 1950 * fatal/nonfatal errors are fatal/nonfatal 1951 * regardless of if we find a handle 1952 */ 1953 if (pciex_ue_err_tbl[i].flags == DDI_FM_FATAL) 1954 derr->fme_status = DDI_FM_FATAL; 1955 else if (pciex_ue_err_tbl[i].flags == 1956 DDI_FM_NONFATAL) 1957 derr->fme_status = DDI_FM_NONFATAL; 1958 pcie_ereport_post(dip, derr, erpt_p, buf, 1959 PCIEX_TYPE_UE); 1960 PCI_FM_SEV_INC(derr->fme_status); 1961 } 1962 } 1963 } 1964 1965 /* 1966 * Log PCI Express correctable errors 1967 */ 1968 if (pcie_adv_regs->pcie_adv_vflags & PCIE_CE_STATUS_VALID) { 1969 for (i = 0; pciex_ce_err_tbl[i].err_class != NULL; i++) { 1970 if (!(pcie_adv_regs->pcie_ce_status & 1971 pciex_ce_err_tbl[i].reg_bit)) 1972 continue; 1973 1974 (void) snprintf(buf, FM_MAX_CLASS, 1975 "%s.%s", PCIEX_ERROR_SUBCLASS, 1976 pciex_ce_err_tbl[i].err_class); 1977 pcie_ereport_post(dip, derr, erpt_p, buf, 1978 PCIEX_TYPE_CE); 1979 if (!fatal && !unknown) 1980 PCI_FM_SEV_INC(pciex_ce_err_tbl[i].flags); 1981 } 1982 } 1983 1984 if (!(erpt_p->pe_dflags & PCI_BRIDGE_DEV)) 1985 goto done; 1986 1987 if (erpt_p->pe_dflags & PCIEX_RC_DEV) { 1988 int ret = pcie_rc_error_report(dip, derr, erpt_p, 1989 (void *)pcie_adv_regs); 1990 PCI_FM_SEV_INC(ret); 1991 } 1992 1993 if (!((erpt_p->pe_dflags & PCIEX_2PCI_DEV) && 1994 (pcie_adv_regs->pcie_adv_vflags & PCIE_SUE_STATUS_VALID))) 1995 goto done; 1996 1997 pcie_bdg_regs = pcie_adv_regs->pcie_adv_bdg_regs; 1998 1999 for (i = 0; pcie_sue_err_tbl[i].err_class != NULL; i++) { 2000 if ((pcie_bdg_regs->pcie_sue_status & 2001 pcie_sue_err_tbl[i].reg_bit)) { 2002 (void) snprintf(buf, FM_MAX_CLASS, "%s.%s", 2003 PCIEX_ERROR_SUBCLASS, 2004 pcie_sue_err_tbl[i].err_class); 2005 2006 if ((pcie_bdg_regs->pcie_sue_status & 2007 PCIE_AER_SUCE_LOG_BITS) != 2008 pcie_sue_err_tbl[i].reg_bit) { 2009 PCI_FM_SEV_INC(pcie_sue_err_tbl[i].flags); 2010 ddi_fm_ereport_post(dip, buf, derr->fme_ena, 2011 DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 2012 PCIEX_SEC_UE_STATUS, DATA_TYPE_UINT32, 2013 pcie_bdg_regs->pcie_sue_status, 2014 #ifdef DEBUG 2015 PCIEX_SUE_HDR0, DATA_TYPE_UINT32, 2016 pcie_bdg_regs->pcie_sue_hdr0, 2017 PCIEX_SUE_HDR1, DATA_TYPE_UINT32, 2018 pcie_bdg_regs->pcie_sue_hdr[0], 2019 PCIEX_SUE_HDR2, DATA_TYPE_UINT32, 2020 pcie_bdg_regs->pcie_sue_hdr[1], 2021 PCIEX_SUE_HDR3, DATA_TYPE_UINT32, 2022 pcie_bdg_regs->pcie_sue_hdr[2], 2023 #endif 2024 NULL); 2025 } else { 2026 pcie_adv_regs->pcie_adv_bdf = 0; 2027 pcie_pci_check_addr(dip, derr, erpt_p); 2028 /* 2029 * fatal/nonfatal errors are fatal/nonfatal 2030 * regardless of if we find a handle 2031 */ 2032 if (pcie_sue_err_tbl[i].flags == DDI_FM_FATAL) 2033 derr->fme_status = DDI_FM_FATAL; 2034 else if (pcie_sue_err_tbl[i].flags == 2035 DDI_FM_NONFATAL) 2036 derr->fme_status = DDI_FM_NONFATAL; 2037 2038 ddi_fm_ereport_post(dip, buf, derr->fme_ena, 2039 DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 2040 PCIEX_SEC_UE_STATUS, DATA_TYPE_UINT32, 2041 pcie_bdg_regs->pcie_sue_status, 2042 PCIEX_SRC_ID, DATA_TYPE_UINT16, 2043 pcie_adv_regs->pcie_adv_bdf, 2044 PCIEX_SRC_VALID, DATA_TYPE_BOOLEAN_VALUE, 2045 (pcie_adv_regs->pcie_adv_bdf != NULL) ? 2046 1 : NULL, 2047 #ifdef DEBUG 2048 PCIEX_SUE_HDR0, DATA_TYPE_UINT32, 2049 pcie_bdg_regs->pcie_sue_hdr0, 2050 PCIEX_SUE_HDR1, DATA_TYPE_UINT32, 2051 pcie_bdg_regs->pcie_sue_hdr[0], 2052 PCIEX_SUE_HDR2, DATA_TYPE_UINT32, 2053 pcie_bdg_regs->pcie_sue_hdr[1], 2054 PCIEX_SUE_HDR3, DATA_TYPE_UINT32, 2055 pcie_bdg_regs->pcie_sue_hdr[2], 2056 #endif 2057 NULL); 2058 PCI_FM_SEV_INC(derr->fme_status); 2059 } 2060 } 2061 } 2062 done: 2063 return (fatal ? DDI_FM_FATAL : (nonfatal ? DDI_FM_NONFATAL : 2064 (unknown ? DDI_FM_UNKNOWN : DDI_FM_OK))); 2065 } 2066 2067 static void 2068 pci_error_report(dev_info_t *dip, ddi_fm_error_t *derr, pci_erpt_t *erpt_p) 2069 { 2070 int fatal = 0; 2071 int nonfatal = 0; 2072 int unknown = 0; 2073 int ok = 0; 2074 char buf[FM_MAX_CLASS]; 2075 int i; 2076 2077 if (derr->fme_flag == DDI_FM_ERR_UNEXPECTED) { 2078 /* 2079 * Log generic PCI errors. 2080 */ 2081 for (i = 0; pci_err_tbl[i].err_class != NULL; i++) { 2082 if (!(erpt_p->pe_pci_regs->pci_err_status & 2083 pci_err_tbl[i].reg_bit) || 2084 !(erpt_p->pe_pci_regs->pci_vflags & 2085 PCI_ERR_STATUS_VALID)) 2086 continue; 2087 /* 2088 * Generate an ereport for this error bit. 2089 */ 2090 (void) snprintf(buf, FM_MAX_CLASS, "%s.%s", 2091 PCI_ERROR_SUBCLASS, pci_err_tbl[i].err_class); 2092 ddi_fm_ereport_post(dip, buf, derr->fme_ena, 2093 DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 2094 PCI_CONFIG_STATUS, DATA_TYPE_UINT16, 2095 erpt_p->pe_pci_regs->pci_err_status, 2096 PCI_CONFIG_COMMAND, DATA_TYPE_UINT16, 2097 erpt_p->pe_pci_regs->pci_cfg_comm, NULL); 2098 2099 if (!(erpt_p->pe_dflags & PCIEX_DEV)) 2100 PCI_FM_SEV_INC(pci_err_tbl[i].flags); 2101 } 2102 if (erpt_p->pe_dflags & PCIEX_DEV) { 2103 int ret = pcie_error_report(dip, derr, erpt_p); 2104 PCI_FM_SEV_INC(ret); 2105 } else if (erpt_p->pe_dflags & PCIX_DEV) { 2106 if (erpt_p->pe_dflags & PCI_BRIDGE_DEV) { 2107 int ret = pcix_bdg_error_report(dip, derr, 2108 erpt_p, erpt_p->pe_regs); 2109 PCI_FM_SEV_INC(ret); 2110 } else { 2111 int ret = pcix_error_report(dip, derr, erpt_p); 2112 PCI_FM_SEV_INC(ret); 2113 } 2114 } 2115 } 2116 2117 if ((erpt_p->pe_dflags & PCI_BRIDGE_DEV)) { 2118 int ret = pci_bdg_error_report(dip, derr, erpt_p); 2119 PCI_FM_SEV_INC(ret); 2120 } 2121 2122 derr->fme_status = (fatal ? DDI_FM_FATAL : (nonfatal ? DDI_FM_NONFATAL : 2123 (unknown ? DDI_FM_UNKNOWN : DDI_FM_OK))); 2124 } 2125 2126 void 2127 pci_ereport_post(dev_info_t *dip, ddi_fm_error_t *derr, uint16_t *xx_status) 2128 { 2129 struct i_ddi_fmhdl *fmhdl; 2130 pci_erpt_t *erpt_p; 2131 2132 fmhdl = DEVI(dip)->devi_fmhdl; 2133 if (!DDI_FM_EREPORT_CAP(ddi_fm_capable(dip)) && 2134 !DDI_FM_ERRCB_CAP(ddi_fm_capable(dip))) { 2135 i_ddi_drv_ereport_post(dip, DVR_EFMCAP, NULL, DDI_NOSLEEP); 2136 return; 2137 } 2138 2139 ASSERT(fmhdl); 2140 2141 if (derr->fme_ena == NULL) 2142 derr->fme_ena = fm_ena_generate(0, FM_ENA_FMT1); 2143 2144 erpt_p = (pci_erpt_t *)fmhdl->fh_bus_specific; 2145 if (erpt_p == NULL) { 2146 i_ddi_drv_ereport_post(dip, DVR_EFMCAP, NULL, DDI_NOSLEEP); 2147 return; 2148 } 2149 2150 pci_regs_gather(dip, erpt_p); 2151 pci_error_report(dip, derr, erpt_p); 2152 pci_regs_clear(erpt_p); 2153 2154 if (xx_status != NULL) 2155 *xx_status = erpt_p->pe_pci_regs->pci_err_status; 2156 } 2157 2158 /* 2159 * private version of walk_devs() that can be used during panic. No 2160 * sleeping or locking required. 2161 */ 2162 static int 2163 pci_fm_walk_devs(dev_info_t *dip, int (*f)(dev_info_t *, void *), void *arg) 2164 { 2165 while (dip) { 2166 switch ((*f)(dip, arg)) { 2167 case DDI_WALK_TERMINATE: 2168 return (DDI_WALK_TERMINATE); 2169 case DDI_WALK_CONTINUE: 2170 if (pci_fm_walk_devs(ddi_get_child(dip), f, 2171 arg) == DDI_WALK_TERMINATE) 2172 return (DDI_WALK_TERMINATE); 2173 break; 2174 case DDI_WALK_PRUNECHILD: 2175 break; 2176 } 2177 dip = ddi_get_next_sibling(dip); 2178 } 2179 return (DDI_WALK_CONTINUE); 2180 } 2181 2182 /* 2183 * need special version of ddi_fm_ereport_post() as the leaf driver may 2184 * not be hardened. 2185 */ 2186 static void 2187 pci_fm_ereport_post(dev_info_t *dip, const char *error_class, uint64_t ena, 2188 uint8_t version, ...) 2189 { 2190 char *name; 2191 char device_path[MAXPATHLEN]; 2192 char ddi_error_class[FM_MAX_CLASS]; 2193 nvlist_t *ereport, *detector; 2194 nv_alloc_t *nva; 2195 errorq_elem_t *eqep; 2196 va_list ap; 2197 2198 if (panicstr) { 2199 eqep = errorq_reserve(ereport_errorq); 2200 if (eqep == NULL) 2201 return; 2202 ereport = errorq_elem_nvl(ereport_errorq, eqep); 2203 nva = errorq_elem_nva(ereport_errorq, eqep); 2204 detector = fm_nvlist_create(nva); 2205 } else { 2206 ereport = fm_nvlist_create(NULL); 2207 detector = fm_nvlist_create(NULL); 2208 } 2209 2210 (void) ddi_pathname(dip, device_path); 2211 fm_fmri_dev_set(detector, FM_DEV_SCHEME_VERSION, NULL, 2212 device_path, NULL); 2213 (void) snprintf(ddi_error_class, FM_MAX_CLASS, "%s.%s", 2214 DDI_IO_CLASS, error_class); 2215 fm_ereport_set(ereport, version, ddi_error_class, ena, detector, NULL); 2216 2217 va_start(ap, version); 2218 name = va_arg(ap, char *); 2219 (void) i_fm_payload_set(ereport, name, ap); 2220 va_end(ap); 2221 2222 if (panicstr) { 2223 errorq_commit(ereport_errorq, eqep, ERRORQ_SYNC); 2224 } else { 2225 (void) fm_ereport_post(ereport, EVCH_TRYHARD); 2226 fm_nvlist_destroy(ereport, FM_NVA_FREE); 2227 fm_nvlist_destroy(detector, FM_NVA_FREE); 2228 } 2229 } 2230 2231 static int 2232 pci_check_regs(dev_info_t *dip, void *arg) 2233 { 2234 int reglen; 2235 int rn; 2236 int totreg; 2237 pci_regspec_t *drv_regp; 2238 pci_target_err_t *tgt_err = (pci_target_err_t *)arg; 2239 2240 if (tgt_err->tgt_pci_space == PCI_REG_ADDR_G(PCI_ADDR_CONFIG)) { 2241 /* 2242 * for config space, we need to check if the given address 2243 * is a valid config space address for this device - based 2244 * on pci_phys_hi of the config space entry in reg property. 2245 */ 2246 if (ddi_getlongprop(DDI_DEV_T_NONE, dip, DDI_PROP_DONTPASS, 2247 "reg", (caddr_t)&drv_regp, ®len) != DDI_SUCCESS) 2248 return (DDI_WALK_CONTINUE); 2249 2250 totreg = reglen / sizeof (pci_regspec_t); 2251 for (rn = 0; rn < totreg; rn++) { 2252 if (tgt_err->tgt_pci_space == 2253 PCI_REG_ADDR_G(drv_regp[rn].pci_phys_hi) && 2254 (tgt_err->tgt_pci_addr & (PCI_REG_BUS_M | 2255 PCI_REG_DEV_M | PCI_REG_FUNC_M)) == 2256 (drv_regp[rn].pci_phys_hi & (PCI_REG_BUS_M | 2257 PCI_REG_DEV_M | PCI_REG_FUNC_M))) { 2258 tgt_err->tgt_dip = dip; 2259 kmem_free(drv_regp, reglen); 2260 return (DDI_WALK_TERMINATE); 2261 } 2262 } 2263 kmem_free(drv_regp, reglen); 2264 } else { 2265 /* 2266 * for non config space, need to check reg to look 2267 * for any non-relocable mapping, otherwise check 2268 * assigned-addresses. 2269 */ 2270 if (ddi_getlongprop(DDI_DEV_T_NONE, dip, DDI_PROP_DONTPASS, 2271 "reg", (caddr_t)&drv_regp, ®len) != DDI_SUCCESS) 2272 return (DDI_WALK_CONTINUE); 2273 2274 totreg = reglen / sizeof (pci_regspec_t); 2275 for (rn = 0; rn < totreg; rn++) { 2276 if ((drv_regp[rn].pci_phys_hi & PCI_RELOCAT_B) && 2277 (tgt_err->tgt_pci_space == TGT_PCI_SPACE_UNKNOWN || 2278 tgt_err->tgt_pci_space == 2279 PCI_REG_ADDR_G(drv_regp[rn].pci_phys_hi)) && 2280 (tgt_err->tgt_pci_addr >= 2281 (uint64_t)drv_regp[rn].pci_phys_low + 2282 ((uint64_t)drv_regp[rn].pci_phys_mid << 32)) && 2283 (tgt_err->tgt_pci_addr < 2284 (uint64_t)drv_regp[rn].pci_phys_low + 2285 ((uint64_t)drv_regp[rn].pci_phys_mid << 32) + 2286 (uint64_t)drv_regp[rn].pci_size_low + 2287 ((uint64_t)drv_regp[rn].pci_size_hi << 32))) { 2288 tgt_err->tgt_dip = dip; 2289 kmem_free(drv_regp, reglen); 2290 return (DDI_WALK_TERMINATE); 2291 } 2292 } 2293 kmem_free(drv_regp, reglen); 2294 2295 if (ddi_getlongprop(DDI_DEV_T_NONE, dip, DDI_PROP_DONTPASS, 2296 "assigned-addresses", (caddr_t)&drv_regp, ®len) != 2297 DDI_SUCCESS) 2298 return (DDI_WALK_CONTINUE); 2299 2300 totreg = reglen / sizeof (pci_regspec_t); 2301 for (rn = 0; rn < totreg; rn++) { 2302 if ((tgt_err->tgt_pci_space == TGT_PCI_SPACE_UNKNOWN || 2303 tgt_err->tgt_pci_space == 2304 PCI_REG_ADDR_G(drv_regp[rn].pci_phys_hi)) && 2305 (tgt_err->tgt_pci_addr >= 2306 (uint64_t)drv_regp[rn].pci_phys_low + 2307 ((uint64_t)drv_regp[rn].pci_phys_mid << 32)) && 2308 (tgt_err->tgt_pci_addr < 2309 (uint64_t)drv_regp[rn].pci_phys_low + 2310 ((uint64_t)drv_regp[rn].pci_phys_mid << 32) + 2311 (uint64_t)drv_regp[rn].pci_size_low + 2312 ((uint64_t)drv_regp[rn].pci_size_hi << 32))) { 2313 tgt_err->tgt_dip = dip; 2314 kmem_free(drv_regp, reglen); 2315 return (DDI_WALK_TERMINATE); 2316 } 2317 } 2318 kmem_free(drv_regp, reglen); 2319 } 2320 return (DDI_WALK_CONTINUE); 2321 } 2322 2323 /* 2324 * impl_fix_ranges - fixes the config space entry of the "ranges" 2325 * property on psycho+ platforms. (if changing this function please make sure 2326 * to change the pci_fix_ranges function in pcipsy.c) 2327 */ 2328 /*ARGSUSED*/ 2329 static void 2330 pci_fix_ranges(dev_info_t *dip, pci_ranges_t *pci_ranges, int nrange) 2331 { 2332 #if defined(__sparc) 2333 char *name = ddi_binding_name(dip); 2334 2335 if ((strcmp(name, "pci108e,8000") == 0) || 2336 (strcmp(name, "pci108e,a000") == 0) || 2337 (strcmp(name, "pci108e,a001") == 0)) { 2338 int i; 2339 for (i = 0; i < nrange; i++, pci_ranges++) 2340 if ((pci_ranges->child_high & PCI_REG_ADDR_M) == 2341 PCI_ADDR_CONFIG) 2342 pci_ranges->parent_low |= 2343 pci_ranges->child_high; 2344 } 2345 #endif 2346 } 2347 2348 static int 2349 pci_check_ranges(dev_info_t *dip, void *arg) 2350 { 2351 uint64_t range_parent_begin; 2352 uint64_t range_parent_size; 2353 uint64_t range_parent_end; 2354 uint32_t space_type; 2355 uint32_t bus_num; 2356 uint32_t range_offset; 2357 pci_ranges_t *pci_ranges, *rangep; 2358 pci_bus_range_t *pci_bus_rangep; 2359 int pci_ranges_length; 2360 int nrange; 2361 pci_target_err_t *tgt_err = (pci_target_err_t *)arg; 2362 int i, size; 2363 if (strcmp(ddi_node_name(dip), "pci") != 0 && 2364 strcmp(ddi_node_name(dip), "pciex") != 0) 2365 return (DDI_WALK_CONTINUE); 2366 2367 /* 2368 * Get the ranges property. Note we only look at the top level pci 2369 * node (hostbridge) which has a ranges property of type pci_ranges_t 2370 * not at pci-pci bridges. 2371 */ 2372 if (ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, "ranges", 2373 (caddr_t)&pci_ranges, &pci_ranges_length) != DDI_SUCCESS) { 2374 /* 2375 * no ranges property - no translation needed 2376 */ 2377 tgt_err->tgt_pci_addr = tgt_err->tgt_err_addr; 2378 tgt_err->tgt_pci_space = TGT_PCI_SPACE_UNKNOWN; 2379 if (panicstr) 2380 (void) pci_fm_walk_devs(ddi_get_child(dip), 2381 pci_check_regs, (void *)tgt_err); 2382 else { 2383 int circ = 0; 2384 ndi_devi_enter(dip, &circ); 2385 ddi_walk_devs(ddi_get_child(dip), pci_check_regs, 2386 (void *)tgt_err); 2387 ndi_devi_exit(dip, circ); 2388 } 2389 if (tgt_err->tgt_dip != NULL) 2390 return (DDI_WALK_TERMINATE); 2391 return (DDI_WALK_PRUNECHILD); 2392 } 2393 nrange = pci_ranges_length / sizeof (pci_ranges_t); 2394 rangep = pci_ranges; 2395 2396 /* Need to fix the pci ranges property for psycho based systems */ 2397 pci_fix_ranges(dip, pci_ranges, nrange); 2398 2399 for (i = 0; i < nrange; i++, rangep++) { 2400 range_parent_begin = ((uint64_t)rangep->parent_high << 32) + 2401 rangep->parent_low; 2402 range_parent_size = ((uint64_t)rangep->size_high << 32) + 2403 rangep->size_low; 2404 range_parent_end = range_parent_begin + range_parent_size - 1; 2405 2406 if ((tgt_err->tgt_err_addr < range_parent_begin) || 2407 (tgt_err->tgt_err_addr > range_parent_end)) { 2408 /* Not in range */ 2409 continue; 2410 } 2411 space_type = PCI_REG_ADDR_G(rangep->child_high); 2412 if (space_type == PCI_REG_ADDR_G(PCI_ADDR_CONFIG)) { 2413 /* Config space address - check bus range */ 2414 range_offset = tgt_err->tgt_err_addr - 2415 range_parent_begin; 2416 bus_num = PCI_REG_BUS_G(range_offset); 2417 if (ddi_getlongprop(DDI_DEV_T_ANY, dip, 2418 DDI_PROP_DONTPASS, "bus-range", 2419 (caddr_t)&pci_bus_rangep, &size) != DDI_SUCCESS) { 2420 continue; 2421 } 2422 if ((bus_num < pci_bus_rangep->lo) || 2423 (bus_num > pci_bus_rangep->hi)) { 2424 /* 2425 * Bus number not appropriate for this 2426 * pci nexus. 2427 */ 2428 kmem_free(pci_bus_rangep, size); 2429 continue; 2430 } 2431 kmem_free(pci_bus_rangep, size); 2432 } 2433 2434 /* We have a match if we get here - compute pci address */ 2435 tgt_err->tgt_pci_addr = tgt_err->tgt_err_addr - 2436 range_parent_begin; 2437 tgt_err->tgt_pci_addr += (((uint64_t)rangep->child_mid << 32) + 2438 rangep->child_low); 2439 tgt_err->tgt_pci_space = space_type; 2440 if (panicstr) 2441 (void) pci_fm_walk_devs(ddi_get_child(dip), 2442 pci_check_regs, (void *)tgt_err); 2443 else { 2444 int circ = 0; 2445 ndi_devi_enter(dip, &circ); 2446 ddi_walk_devs(ddi_get_child(dip), pci_check_regs, 2447 (void *)tgt_err); 2448 ndi_devi_exit(dip, circ); 2449 } 2450 if (tgt_err->tgt_dip != NULL) { 2451 kmem_free(pci_ranges, pci_ranges_length); 2452 return (DDI_WALK_TERMINATE); 2453 } 2454 } 2455 kmem_free(pci_ranges, pci_ranges_length); 2456 return (DDI_WALK_PRUNECHILD); 2457 } 2458 2459 /* 2460 * Function used to drain pci_target_queue, either during panic or after softint 2461 * is generated, to generate target device ereports based on captured physical 2462 * addresses 2463 */ 2464 /*ARGSUSED*/ 2465 static void 2466 pci_target_drain(void *private_p, pci_target_err_t *tgt_err) 2467 { 2468 char buf[FM_MAX_CLASS]; 2469 2470 /* 2471 * The following assumes that all pci_pci bridge devices 2472 * are configured as transparant. Find the top-level pci 2473 * nexus which has tgt_err_addr in one of its ranges, converting this 2474 * to a pci address in the process. Then starting at this node do 2475 * another tree walk to find a device with the pci address we've 2476 * found within range of one of it's assigned-addresses properties. 2477 */ 2478 tgt_err->tgt_dip = NULL; 2479 if (panicstr) 2480 (void) pci_fm_walk_devs(ddi_root_node(), pci_check_ranges, 2481 (void *)tgt_err); 2482 else 2483 ddi_walk_devs(ddi_root_node(), pci_check_ranges, 2484 (void *)tgt_err); 2485 if (tgt_err->tgt_dip == NULL) 2486 return; 2487 2488 (void) snprintf(buf, FM_MAX_CLASS, "%s.%s", tgt_err->tgt_bridge_type, 2489 tgt_err->tgt_err_class); 2490 pci_fm_ereport_post(tgt_err->tgt_dip, buf, tgt_err->tgt_err_ena, 0, 2491 PCI_PA, DATA_TYPE_UINT64, tgt_err->tgt_err_addr, NULL); 2492 } 2493 2494 void 2495 pci_target_enqueue(uint64_t ena, char *class, char *bridge_type, uint64_t addr) 2496 { 2497 pci_target_err_t tgt_err; 2498 2499 tgt_err.tgt_err_ena = ena; 2500 tgt_err.tgt_err_class = class; 2501 tgt_err.tgt_bridge_type = bridge_type; 2502 tgt_err.tgt_err_addr = addr; 2503 errorq_dispatch(pci_target_queue, (void *)&tgt_err, 2504 sizeof (pci_target_err_t), ERRORQ_ASYNC); 2505 } 2506 2507 void 2508 pci_targetq_init(void) 2509 { 2510 /* 2511 * PCI target errorq, to schedule async handling of generation of 2512 * target device ereports based on captured physical address. 2513 * The errorq is created here but destroyed when _fini is called 2514 * for the pci module. 2515 */ 2516 if (pci_target_queue == NULL) { 2517 pci_target_queue = errorq_create("pci_target_queue", 2518 (errorq_func_t)pci_target_drain, (void *)NULL, 2519 TARGET_MAX_ERRS, sizeof (pci_target_err_t), FM_ERR_PIL, 2520 ERRORQ_VITAL); 2521 if (pci_target_queue == NULL) 2522 panic("failed to create required system error queue"); 2523 } 2524 } 2525