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_OK, 77 PCIEX_RNR, PCIE_AER_CE_REPLAY_ROLLOVER, NULL, DDI_FM_OK, 78 PCIEX_RTO, PCIE_AER_CE_REPLAY_TO, NULL, DDI_FM_OK, 79 PCIEX_BDP, PCIE_AER_CE_BAD_DLLP, NULL, DDI_FM_OK, 80 PCIEX_BTP, PCIE_AER_CE_BAD_TLP, NULL, DDI_FM_OK, 81 PCIEX_ANFE, PCIE_AER_CE_AD_NFE, NULL, DDI_FM_OK, 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_UNKNOWN, 93 PCIEX_UC, PCIE_AER_UCE_UC, NULL, DDI_FM_OK, 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_UNKNOWN, 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_OK, 129 PCIX_BSS_SPL_DLY, PCI_PCIX_BSS_SPL_DLY, NULL, DDI_FM_OK, 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_OK, 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 1137 switch (errtype) { 1138 case PCIEX_TYPE_CE: 1139 ddi_fm_ereport_post(dip, buf, derr->fme_ena, 1140 DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 1141 PCIEX_DEVSTS_REG, DATA_TYPE_UINT16, 1142 pcie_regs->pcie_err_status, 1143 PCIEX_CE_STATUS_REG, DATA_TYPE_UINT32, 1144 pcie_adv_regs->pcie_ce_status, NULL); 1145 break; 1146 case PCIEX_TYPE_UE: 1147 ddi_fm_ereport_post(dip, buf, derr->fme_ena, 1148 DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 1149 PCIEX_DEVSTS_REG, DATA_TYPE_UINT16, 1150 pcie_regs->pcie_err_status, 1151 PCIEX_UE_STATUS_REG, DATA_TYPE_UINT32, 1152 pcie_adv_regs->pcie_ue_status, PCIEX_UE_SEV_REG, 1153 DATA_TYPE_UINT32, pcie_adv_regs->pcie_ue_sev, 1154 PCIEX_ADV_CTL, DATA_TYPE_UINT32, 1155 pcie_adv_regs->pcie_adv_ctl, 1156 PCIEX_SRC_ID, DATA_TYPE_UINT16, 1157 pcie_adv_regs->pcie_adv_bdf, 1158 PCIEX_SRC_VALID, DATA_TYPE_BOOLEAN_VALUE, 1159 (pcie_adv_regs->pcie_adv_bdf != NULL) ? 1160 1 : NULL, 1161 #ifdef DEBUG 1162 PCIEX_UE_HDR0, DATA_TYPE_UINT32, 1163 pcie_adv_regs->pcie_ue_hdr0, 1164 PCIEX_UE_HDR1, DATA_TYPE_UINT32, 1165 pcie_adv_regs->pcie_ue_hdr[0], 1166 PCIEX_UE_HDR2, DATA_TYPE_UINT32, 1167 pcie_adv_regs->pcie_ue_hdr[1], 1168 PCIEX_UE_HDR3, DATA_TYPE_UINT32, 1169 pcie_adv_regs->pcie_ue_hdr[2], 1170 #endif 1171 NULL); 1172 break; 1173 case PCIEX_TYPE_GEN: 1174 ddi_fm_ereport_post(dip, buf, derr->fme_ena, 1175 DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 1176 0, PCIEX_DEVSTS_REG, DATA_TYPE_UINT16, 1177 pcie_regs->pcie_err_status, NULL); 1178 break; 1179 case PCIEX_TYPE_RC_UE_MSG: 1180 case PCIEX_TYPE_RC_CE_MSG: 1181 pcie_adv_rc_regs = pcie_adv_regs->pcie_adv_rc_regs; 1182 1183 ddi_fm_ereport_post(dip, buf, derr->fme_ena, 1184 DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 1185 PCIEX_ROOT_ERRSTS_REG, DATA_TYPE_UINT32, 1186 pcie_adv_rc_regs->pcie_rc_err_status, 1187 PCIEX_SRC_ID, DATA_TYPE_UINT16, 1188 (errtype == PCIEX_TYPE_RC_UE_MSG) ? 1189 pcie_adv_rc_regs->pcie_rc_ue_src_id : 1190 pcie_adv_rc_regs->pcie_rc_ce_src_id, 1191 PCIEX_SRC_VALID, DATA_TYPE_BOOLEAN_VALUE, 1192 (errtype == PCIEX_TYPE_RC_UE_MSG) ? 1193 (pcie_adv_regs->pcie_adv_vflags & PCIE_SRC_ID_VALID && 1194 pcie_adv_rc_regs->pcie_rc_ue_src_id != 0) : 1195 (pcie_adv_regs->pcie_adv_vflags & PCIE_SRC_ID_VALID && 1196 pcie_adv_rc_regs->pcie_rc_ce_src_id != 0), NULL); 1197 break; 1198 case PCIEX_TYPE_RC_MULT_MSG: 1199 pcie_adv_rc_regs = pcie_adv_regs->pcie_adv_rc_regs; 1200 1201 ddi_fm_ereport_post(dip, buf, derr->fme_ena, 1202 DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 1203 PCIEX_ROOT_ERRSTS_REG, DATA_TYPE_UINT32, 1204 pcie_adv_rc_regs->pcie_rc_err_status, NULL); 1205 break; 1206 default: 1207 break; 1208 } 1209 } 1210 1211 static void 1212 pcie_check_addr(dev_info_t *dip, ddi_fm_error_t *derr, pci_erpt_t *eprt_p) 1213 { 1214 pcie_error_regs_t *pcie_regs = (pcie_error_regs_t *)eprt_p->pe_regs; 1215 pcie_adv_error_regs_t *pcie_adv_regs = pcie_regs->pcie_adv_regs; 1216 pcie_tlp_hdr_t *ue_hdr0; 1217 uint32_t *ue_hdr; 1218 uint64_t addr = NULL; 1219 1220 if (!(pcie_adv_regs->pcie_adv_vflags & PCIE_UE_HDR_VALID)) { 1221 derr->fme_status = DDI_FM_UNKNOWN; 1222 return; 1223 } 1224 ue_hdr0 = (pcie_tlp_hdr_t *)&pcie_adv_regs->pcie_ue_hdr0; 1225 ue_hdr = pcie_adv_regs->pcie_ue_hdr; 1226 1227 switch (ue_hdr0->type) { 1228 case PCIE_TLP_TYPE_MEM: 1229 case PCIE_TLP_TYPE_MEMLK: 1230 if ((ue_hdr0->fmt & 0x1) == 0x1) { 1231 pcie_mem64_t *mem64_tlp = (pcie_mem64_t *)ue_hdr; 1232 1233 addr = (uint64_t)mem64_tlp->addr1 << 32 | 1234 (uint32_t)mem64_tlp->addr0 << 2; 1235 pcie_adv_regs->pcie_adv_bdf = mem64_tlp->rid; 1236 } else { 1237 pcie_memio32_t *memio32_tlp = (pcie_memio32_t *)ue_hdr; 1238 1239 addr = (uint32_t)memio32_tlp->addr0 << 2; 1240 pcie_adv_regs->pcie_adv_bdf = memio32_tlp->rid; 1241 } 1242 1243 derr->fme_status = pci_dev_hdl_lookup(dip, DMA_HANDLE, derr, 1244 (void *) &addr); 1245 /* 1246 * If DMA handle is not found error could have been a memory 1247 * mapped IO address so check in the access cache 1248 */ 1249 if (derr->fme_status == DDI_FM_UNKNOWN) 1250 derr->fme_status = pci_dev_hdl_lookup(dip, ACC_HANDLE, 1251 derr, (void *) &addr); 1252 break; 1253 1254 case PCIE_TLP_TYPE_IO: 1255 { 1256 pcie_memio32_t *memio32_tlp = (pcie_memio32_t *)ue_hdr; 1257 1258 addr = (uint32_t)memio32_tlp->addr0 << 2; 1259 pcie_adv_regs->pcie_adv_bdf = memio32_tlp->rid; 1260 derr->fme_status = pci_dev_hdl_lookup(dip, ACC_HANDLE, 1261 derr, (void *) &addr); 1262 break; 1263 } 1264 case PCIE_TLP_TYPE_CFG0: 1265 case PCIE_TLP_TYPE_CFG1: 1266 { 1267 pcie_cfg_t *cfg_tlp = (pcie_cfg_t *)ue_hdr; 1268 1269 pcie_adv_regs->pcie_adv_bdf = cfg_tlp->rid; 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 pcie_adv_regs->pcie_adv_bdf = pcie_pci_sue_attr->rid; 1361 1362 derr->fme_status = DDI_FM_UNKNOWN; 1363 break; 1364 case PCI_PCIX_CMD_DADR: 1365 cmd = (pcie_bdg_regs->pcie_sue_hdr[0] >> 1366 PCIE_AER_SUCE_HDR_CMD_UP_SHIFT) & 1367 PCIE_AER_SUCE_HDR_CMD_UP_MASK; 1368 if (dual_addr) 1369 break; 1370 ++dual_addr; 1371 goto cmd_switch; 1372 default: 1373 derr->fme_status = DDI_FM_UNKNOWN; 1374 } 1375 1376 /* 1377 * If no handle was found in the children caches and their is no 1378 * address infomation already stored and we have a captured address 1379 * then we need to store it away so that intermediate bridges can 1380 * check if the address exists in their handle caches. 1381 */ 1382 if (derr->fme_status == DDI_FM_UNKNOWN && 1383 derr->fme_bus_specific == NULL && 1384 addr != NULL) 1385 derr->fme_bus_specific = (void *)(uintptr_t)addr; 1386 } 1387 1388 static int 1389 pcix_check_addr(dev_info_t *dip, ddi_fm_error_t *derr, 1390 pcix_ecc_regs_t *pcix_ecc_regs) 1391 { 1392 int cmd = (pcix_ecc_regs->pcix_ecc_ctlstat >> 16) & 0xf; 1393 uint64_t addr; 1394 1395 addr = pcix_ecc_regs->pcix_ecc_secaddr; 1396 addr = addr << 32; 1397 addr |= pcix_ecc_regs->pcix_ecc_fstaddr; 1398 1399 switch (cmd) { 1400 case PCI_PCIX_CMD_INTR: 1401 case PCI_PCIX_CMD_SPEC: 1402 return (DDI_FM_FATAL); 1403 case PCI_PCIX_CMD_IORD: 1404 case PCI_PCIX_CMD_IOWR: 1405 return (pci_dev_hdl_lookup(dip, ACC_HANDLE, derr, 1406 (void *) &addr)); 1407 case PCI_PCIX_CMD_DEVID: 1408 return (DDI_FM_FATAL); 1409 case PCI_PCIX_CMD_MEMRD_DW: 1410 case PCI_PCIX_CMD_MEMWR: 1411 case PCI_PCIX_CMD_MEMRD_BL: 1412 case PCI_PCIX_CMD_MEMWR_BL: 1413 return (pci_dev_hdl_lookup(dip, DMA_HANDLE, derr, 1414 (void *) &addr)); 1415 case PCI_PCIX_CMD_CFRD: 1416 case PCI_PCIX_CMD_CFWR: 1417 return (pci_dev_hdl_lookup(dip, ACC_HANDLE, derr, 1418 (void *) &addr)); 1419 case PCI_PCIX_CMD_SPL: 1420 case PCI_PCIX_CMD_DADR: 1421 return (DDI_FM_FATAL); 1422 case PCI_PCIX_CMD_MEMRDBL: 1423 case PCI_PCIX_CMD_MEMWRBL: 1424 return (pci_dev_hdl_lookup(dip, DMA_HANDLE, derr, 1425 (void *) &addr)); 1426 default: 1427 return (DDI_FM_FATAL); 1428 } 1429 } 1430 1431 /*ARGSUSED*/ 1432 static int 1433 pci_bdg_error_report(dev_info_t *dip, ddi_fm_error_t *derr, pci_erpt_t *erpt_p) 1434 { 1435 pci_bdg_error_regs_t *pci_bdg_regs = erpt_p->pe_pci_regs->pci_bdg_regs; 1436 int fatal = 0; 1437 int nonfatal = 0; 1438 int unknown = 0; 1439 int ok = 0; 1440 int ret = DDI_FM_OK; 1441 char buf[FM_MAX_CLASS]; 1442 int i; 1443 1444 if (derr->fme_flag != DDI_FM_ERR_UNEXPECTED) 1445 goto done; 1446 1447 if ((pci_bdg_regs->pci_bdg_vflags & PCI_BDG_CTRL_VALID) && 1448 (pci_bdg_regs->pci_bdg_ctrl & PCI_BCNF_BCNTRL_DTO_STAT)) { 1449 (void) snprintf(buf, FM_MAX_CLASS, "%s.%s", 1450 PCI_ERROR_SUBCLASS, PCI_DTO); 1451 ddi_fm_ereport_post(dip, buf, derr->fme_ena, 1452 DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 1453 PCI_SEC_CONFIG_STATUS, DATA_TYPE_UINT16, 1454 pci_bdg_regs->pci_bdg_sec_stat, PCI_BCNTRL, 1455 DATA_TYPE_UINT16, pci_bdg_regs->pci_bdg_ctrl, NULL); 1456 unknown++; 1457 } 1458 1459 if (pci_bdg_regs->pci_bdg_vflags & PCI_BDG_SEC_STAT_VALID) { 1460 for (i = 0; pci_bdg_err_tbl[i].err_class != NULL; i++) { 1461 if (pci_bdg_regs->pci_bdg_sec_stat & 1462 pci_bdg_err_tbl[i].reg_bit) { 1463 (void) snprintf(buf, FM_MAX_CLASS, "%s.%s-%s", 1464 PCI_ERROR_SUBCLASS, PCI_SEC_ERROR_SUBCLASS, 1465 pci_bdg_err_tbl[i].err_class); 1466 ddi_fm_ereport_post(dip, buf, derr->fme_ena, 1467 DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 1468 PCI_SEC_CONFIG_STATUS, DATA_TYPE_UINT16, 1469 pci_bdg_regs->pci_bdg_sec_stat, PCI_BCNTRL, 1470 DATA_TYPE_UINT16, 1471 pci_bdg_regs->pci_bdg_ctrl, NULL); 1472 PCI_FM_SEV_INC(pci_bdg_err_tbl[i].flags); 1473 if (derr->fme_bus_specific && 1474 pci_bdg_err_tbl[i].terr_class) 1475 pci_target_enqueue(derr->fme_ena, 1476 pci_bdg_err_tbl[i].terr_class, 1477 PCI_ERROR_SUBCLASS, 1478 (uintptr_t)derr->fme_bus_specific); 1479 } 1480 } 1481 #if !defined(__sparc) 1482 /* 1483 * For x86, many drivers and even user-level code currently get 1484 * away with accessing bad addresses, getting a UR and getting 1485 * -1 returned. Unfortunately, we have no control over this, so 1486 * we will have to treat all URs as nonfatal. Moreover, if the 1487 * leaf driver is non-hardened, then we don't actually see the 1488 * UR directly. All we see is a secondary bus master abort at 1489 * the root complex - so it's this condition that we actually 1490 * need to treat as nonfatal (providing no other unrelated nfe 1491 * conditions have also been seen by the root complex). 1492 */ 1493 if ((erpt_p->pe_dflags & PCIEX_RC_DEV) && 1494 (pci_bdg_regs->pci_bdg_sec_stat & PCI_STAT_R_MAST_AB) && 1495 !(pci_bdg_regs->pci_bdg_sec_stat & PCI_STAT_S_PERROR)) { 1496 pcie_error_regs_t *pcie_regs = 1497 (pcie_error_regs_t *)erpt_p->pe_regs; 1498 if ((pcie_regs->pcie_vflags & PCIE_ERR_STATUS_VALID) && 1499 !(pcie_regs->pcie_err_status & 1500 PCIE_DEVSTS_NFE_DETECTED)) 1501 nonfatal++; 1502 } 1503 #endif 1504 } 1505 1506 done: 1507 1508 /* 1509 * Need to check for poke and cautious put. We already know peek 1510 * and cautious get errors occurred (as we got a trap) and we know 1511 * they are nonfatal. 1512 */ 1513 if (derr->fme_flag == DDI_FM_ERR_EXPECTED) { 1514 /* 1515 * for cautious puts we treat all errors as nonfatal. Actually 1516 * we set nonfatal for cautious gets as well - doesn't do any 1517 * harm 1518 */ 1519 if (pci_bdg_regs->pci_bdg_sec_stat & (PCI_STAT_R_TARG_AB | 1520 PCI_STAT_R_MAST_AB | PCI_STAT_S_PERROR | PCI_STAT_S_SYSERR)) 1521 nonfatal++; 1522 1523 /* 1524 * for cautious accesses we already have the acc_handle. Just 1525 * need to call children to clear their error bits 1526 */ 1527 ret = ndi_fm_handler_dispatch(dip, NULL, derr); 1528 PCI_FM_SEV_INC(ret); 1529 return (fatal ? DDI_FM_FATAL : (nonfatal ? DDI_FM_NONFATAL : 1530 (unknown ? DDI_FM_UNKNOWN : DDI_FM_OK))); 1531 } 1532 if (derr->fme_flag == DDI_FM_ERR_POKE) { 1533 /* 1534 * special case for pokes - we only consider master abort 1535 * and target abort as nonfatal. Sserr with no master abort is 1536 * fatal, but master/target abort can come in on separate 1537 * instance, so return unknown and parent will determine if 1538 * nonfatal (if another child returned nonfatal - ie master 1539 * or target abort) or fatal otherwise 1540 */ 1541 if (pci_bdg_regs->pci_bdg_sec_stat & (PCI_STAT_R_TARG_AB | 1542 PCI_STAT_R_MAST_AB)) 1543 nonfatal++; 1544 if (erpt_p->pe_pci_regs->pci_err_status & PCI_STAT_S_SYSERR) 1545 unknown++; 1546 } 1547 1548 /* 1549 * If errant address is passed in then attempt to find 1550 * ACC/DMA handle in caches. 1551 */ 1552 if (derr->fme_bus_specific) { 1553 int i; 1554 1555 for (i = 0; i < 2; i++) { 1556 ret = ndi_fmc_error(dip, NULL, i ? ACC_HANDLE : 1557 DMA_HANDLE, derr->fme_ena, 1558 (void *)&derr->fme_bus_specific); 1559 PCI_FM_SEV_INC(ret); 1560 } 1561 } 1562 1563 /* 1564 * now check children below the bridge, only if errant handle was not 1565 * found 1566 */ 1567 if (!derr->fme_acc_handle && !derr->fme_dma_handle) { 1568 ret = ndi_fm_handler_dispatch(dip, NULL, derr); 1569 PCI_FM_SEV_INC(ret); 1570 } 1571 1572 return (fatal ? DDI_FM_FATAL : (nonfatal ? DDI_FM_NONFATAL : 1573 (unknown ? DDI_FM_UNKNOWN : DDI_FM_OK))); 1574 } 1575 1576 static int 1577 pcix_ecc_error_report(dev_info_t *dip, ddi_fm_error_t *derr, pci_erpt_t *erpt_p, 1578 void *pe_regs) 1579 { 1580 pcix_error_regs_t *pcix_regs; 1581 pcix_bdg_error_regs_t *pcix_bdg_regs; 1582 pcix_ecc_regs_t *pcix_ecc_regs; 1583 int bridge; 1584 int i; 1585 int ecc_phase; 1586 int ecc_corr; 1587 int sec_ue; 1588 int sec_ce; 1589 int fatal = 0; 1590 int nonfatal = 0; 1591 int unknown = 0; 1592 int ok = 0; 1593 char buf[FM_MAX_CLASS]; 1594 1595 if (erpt_p->pe_dflags & PCI_BRIDGE_DEV) { 1596 pcix_bdg_regs = (pcix_bdg_error_regs_t *)pe_regs; 1597 bridge = 1; 1598 } else { 1599 pcix_regs = (pcix_error_regs_t *)pe_regs; 1600 bridge = 0; 1601 } 1602 1603 for (i = 0; i < (bridge ? 2 : 1); i++) { 1604 int ret = DDI_FM_OK; 1605 pcix_ecc_regs = bridge ? pcix_bdg_regs->pcix_bdg_ecc_regs[i] : 1606 pcix_regs->pcix_ecc_regs; 1607 if (pcix_ecc_regs->pcix_ecc_vflags & PCIX_ERR_ECC_STS_VALID) { 1608 ecc_phase = (pcix_ecc_regs->pcix_ecc_ctlstat & 1609 PCI_PCIX_ECC_PHASE) >> 0x4; 1610 ecc_corr = (pcix_ecc_regs->pcix_ecc_ctlstat & 1611 PCI_PCIX_ECC_CORR); 1612 sec_ue = (pcix_ecc_regs->pcix_ecc_ctlstat & 1613 PCI_PCIX_ECC_S_UE); 1614 sec_ce = (pcix_ecc_regs->pcix_ecc_ctlstat & 1615 PCI_PCIX_ECC_S_CE); 1616 1617 switch (ecc_phase) { 1618 case PCI_PCIX_ECC_PHASE_NOERR: 1619 break; 1620 case PCI_PCIX_ECC_PHASE_FADDR: 1621 case PCI_PCIX_ECC_PHASE_SADDR: 1622 PCI_FM_SEV_INC(ecc_corr ? DDI_FM_OK : 1623 DDI_FM_FATAL); 1624 (void) snprintf(buf, FM_MAX_CLASS, 1625 "%s.%s%s", PCIX_ERROR_SUBCLASS, 1626 i ? PCIX_SEC_ERROR_SUBCLASS : "", 1627 ecc_corr ? PCIX_ECC_CE_ADDR : 1628 PCIX_ECC_UE_ADDR); 1629 break; 1630 case PCI_PCIX_ECC_PHASE_ATTR: 1631 PCI_FM_SEV_INC(ecc_corr ? 1632 DDI_FM_OK : DDI_FM_FATAL); 1633 (void) snprintf(buf, FM_MAX_CLASS, 1634 "%s.%s%s", PCIX_ERROR_SUBCLASS, 1635 i ? PCIX_SEC_ERROR_SUBCLASS : "", 1636 ecc_corr ? PCIX_ECC_CE_ATTR : 1637 PCIX_ECC_UE_ATTR); 1638 break; 1639 case PCI_PCIX_ECC_PHASE_DATA32: 1640 case PCI_PCIX_ECC_PHASE_DATA64: 1641 if (ecc_corr) 1642 ret = DDI_FM_OK; 1643 else 1644 ret = pcix_check_addr(dip, derr, 1645 pcix_ecc_regs); 1646 PCI_FM_SEV_INC(ret); 1647 1648 (void) snprintf(buf, FM_MAX_CLASS, 1649 "%s.%s%s", PCIX_ERROR_SUBCLASS, 1650 i ? PCIX_SEC_ERROR_SUBCLASS : "", 1651 ecc_corr ? PCIX_ECC_CE_DATA : 1652 PCIX_ECC_UE_DATA); 1653 break; 1654 } 1655 if (ecc_phase) 1656 if (bridge) 1657 ddi_fm_ereport_post(dip, buf, 1658 derr->fme_ena, 1659 DDI_NOSLEEP, FM_VERSION, 1660 DATA_TYPE_UINT8, 0, 1661 PCIX_SEC_STATUS, DATA_TYPE_UINT16, 1662 pcix_bdg_regs->pcix_bdg_sec_stat, 1663 PCIX_BDG_STAT, DATA_TYPE_UINT32, 1664 pcix_bdg_regs->pcix_bdg_stat, 1665 PCIX_ECC_CTLSTAT, DATA_TYPE_UINT32, 1666 pcix_ecc_regs->pcix_ecc_ctlstat, 1667 PCIX_ECC_ATTR, DATA_TYPE_UINT32, 1668 pcix_ecc_regs->pcix_ecc_attr, NULL); 1669 else 1670 ddi_fm_ereport_post(dip, buf, 1671 derr->fme_ena, 1672 DDI_NOSLEEP, FM_VERSION, 1673 DATA_TYPE_UINT8, 0, 1674 PCIX_COMMAND, DATA_TYPE_UINT16, 1675 pcix_regs->pcix_command, 1676 PCIX_STATUS, DATA_TYPE_UINT32, 1677 pcix_regs->pcix_status, 1678 PCIX_ECC_CTLSTAT, DATA_TYPE_UINT32, 1679 pcix_ecc_regs->pcix_ecc_ctlstat, 1680 PCIX_ECC_ATTR, DATA_TYPE_UINT32, 1681 pcix_ecc_regs->pcix_ecc_attr, NULL); 1682 if (sec_ce || sec_ue) { 1683 (void) snprintf(buf, FM_MAX_CLASS, 1684 "%s.%s%s", PCIX_ERROR_SUBCLASS, 1685 i ? PCIX_SEC_ERROR_SUBCLASS : "", 1686 sec_ce ? PCIX_ECC_S_CE : PCIX_ECC_S_UE); 1687 if (bridge) 1688 ddi_fm_ereport_post(dip, buf, 1689 derr->fme_ena, 1690 DDI_NOSLEEP, FM_VERSION, 1691 DATA_TYPE_UINT8, 0, 1692 PCIX_SEC_STATUS, DATA_TYPE_UINT16, 1693 pcix_bdg_regs->pcix_bdg_sec_stat, 1694 PCIX_BDG_STAT, DATA_TYPE_UINT32, 1695 pcix_bdg_regs->pcix_bdg_stat, 1696 PCIX_ECC_CTLSTAT, DATA_TYPE_UINT32, 1697 pcix_ecc_regs->pcix_ecc_ctlstat, 1698 PCIX_ECC_ATTR, DATA_TYPE_UINT32, 1699 pcix_ecc_regs->pcix_ecc_attr, NULL); 1700 else 1701 ddi_fm_ereport_post(dip, buf, 1702 derr->fme_ena, 1703 DDI_NOSLEEP, FM_VERSION, 1704 DATA_TYPE_UINT8, 0, 1705 PCIX_COMMAND, DATA_TYPE_UINT16, 1706 pcix_regs->pcix_command, 1707 PCIX_STATUS, DATA_TYPE_UINT32, 1708 pcix_regs->pcix_status, 1709 PCIX_ECC_CTLSTAT, DATA_TYPE_UINT32, 1710 pcix_ecc_regs->pcix_ecc_ctlstat, 1711 PCIX_ECC_ATTR, DATA_TYPE_UINT32, 1712 pcix_ecc_regs->pcix_ecc_attr, NULL); 1713 PCI_FM_SEV_INC(sec_ue ? DDI_FM_FATAL : 1714 DDI_FM_OK); 1715 } 1716 } 1717 } 1718 return (fatal ? DDI_FM_FATAL : (nonfatal ? DDI_FM_NONFATAL : 1719 (unknown ? DDI_FM_UNKNOWN : DDI_FM_OK))); 1720 } 1721 1722 static int 1723 pcix_bdg_error_report(dev_info_t *dip, ddi_fm_error_t *derr, pci_erpt_t *erpt_p, 1724 void *pe_regs) 1725 { 1726 pcix_bdg_error_regs_t *pcix_bdg_regs = (pcix_bdg_error_regs_t *)pe_regs; 1727 int fatal = 0; 1728 int nonfatal = 0; 1729 int unknown = 0; 1730 int ok = 0; 1731 char buf[FM_MAX_CLASS]; 1732 int i; 1733 1734 if (pcix_bdg_regs->pcix_bdg_vflags & PCIX_BDG_STATUS_VALID) { 1735 for (i = 0; pcix_err_tbl[i].err_class != NULL; i++) { 1736 if ((pcix_bdg_regs->pcix_bdg_stat & 1737 pcix_err_tbl[i].reg_bit)) { 1738 (void) snprintf(buf, FM_MAX_CLASS, "%s.%s", 1739 PCIX_ERROR_SUBCLASS, 1740 pcix_err_tbl[i].err_class); 1741 ddi_fm_ereport_post(dip, buf, derr->fme_ena, 1742 DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 1743 PCIX_SEC_STATUS, DATA_TYPE_UINT16, 1744 pcix_bdg_regs->pcix_bdg_sec_stat, 1745 PCIX_BDG_STAT, DATA_TYPE_UINT32, 1746 pcix_bdg_regs->pcix_bdg_stat, NULL); 1747 PCI_FM_SEV_INC(pcix_err_tbl[i].flags); 1748 } 1749 } 1750 } 1751 1752 if (pcix_bdg_regs->pcix_bdg_vflags & PCIX_BDG_SEC_STATUS_VALID) { 1753 for (i = 0; pcix_sec_err_tbl[i].err_class != NULL; i++) { 1754 if ((pcix_bdg_regs->pcix_bdg_sec_stat & 1755 pcix_sec_err_tbl[i].reg_bit)) { 1756 (void) snprintf(buf, FM_MAX_CLASS, "%s.%s%s", 1757 PCIX_ERROR_SUBCLASS, 1758 PCIX_SEC_ERROR_SUBCLASS, 1759 pcix_sec_err_tbl[i].err_class); 1760 ddi_fm_ereport_post(dip, buf, derr->fme_ena, 1761 DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 1762 PCIX_SEC_STATUS, DATA_TYPE_UINT16, 1763 pcix_bdg_regs->pcix_bdg_sec_stat, 1764 PCIX_BDG_STAT, DATA_TYPE_UINT32, 1765 pcix_bdg_regs->pcix_bdg_stat, NULL); 1766 PCI_FM_SEV_INC(pcix_sec_err_tbl[i].flags); 1767 } 1768 } 1769 } 1770 1771 /* Log/Handle ECC errors */ 1772 if (PCIX_ECC_VER_CHECK(pcix_bdg_regs->pcix_bdg_ver)) { 1773 int ret; 1774 1775 ret = pcix_ecc_error_report(dip, derr, erpt_p, 1776 (void *)pcix_bdg_regs); 1777 PCI_FM_SEV_INC(ret); 1778 } 1779 return (fatal ? DDI_FM_FATAL : (nonfatal ? DDI_FM_NONFATAL : 1780 (unknown ? DDI_FM_UNKNOWN : DDI_FM_OK))); 1781 } 1782 1783 static int 1784 pcix_error_report(dev_info_t *dip, ddi_fm_error_t *derr, pci_erpt_t *erpt_p) 1785 { 1786 pcix_error_regs_t *pcix_regs = (pcix_error_regs_t *)erpt_p->pe_regs; 1787 int fatal = 0; 1788 int nonfatal = 0; 1789 int unknown = 0; 1790 int ok = 0; 1791 char buf[FM_MAX_CLASS]; 1792 int i; 1793 1794 if (pcix_regs->pcix_vflags & PCIX_ERR_STATUS_VALID) { 1795 for (i = 0; pcix_err_tbl[i].err_class != NULL; i++) { 1796 if (!(pcix_regs->pcix_status & pcix_err_tbl[i].reg_bit)) 1797 continue; 1798 1799 (void) snprintf(buf, FM_MAX_CLASS, "%s.%s", 1800 PCIX_ERROR_SUBCLASS, pcix_err_tbl[i].err_class); 1801 ddi_fm_ereport_post(dip, buf, derr->fme_ena, 1802 DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 1803 PCIX_COMMAND, DATA_TYPE_UINT16, 1804 pcix_regs->pcix_command, PCIX_STATUS, 1805 DATA_TYPE_UINT32, pcix_regs->pcix_status, 1806 NULL); 1807 PCI_FM_SEV_INC(pcix_err_tbl[i].flags); 1808 } 1809 } 1810 /* Log/Handle ECC errors */ 1811 if (PCIX_ECC_VER_CHECK(pcix_regs->pcix_ver)) { 1812 int ret = pcix_ecc_error_report(dip, derr, erpt_p, 1813 (void *)pcix_regs); 1814 PCI_FM_SEV_INC(ret); 1815 } 1816 1817 return (fatal ? DDI_FM_FATAL : (nonfatal ? DDI_FM_NONFATAL : 1818 (unknown ? DDI_FM_UNKNOWN : DDI_FM_OK))); 1819 } 1820 1821 static int 1822 pcie_rc_error_report(dev_info_t *dip, ddi_fm_error_t *derr, pci_erpt_t *erpt_p, 1823 void *pe_regs) 1824 { 1825 pcie_adv_error_regs_t *pcie_adv_regs = (pcie_adv_error_regs_t *)pe_regs; 1826 int fatal = 0; 1827 int nonfatal = 0; 1828 int unknown = 0; 1829 char buf[FM_MAX_CLASS]; 1830 1831 if (pcie_adv_regs->pcie_adv_vflags & PCIE_RC_ERR_STATUS_VALID) { 1832 pcie_adv_rc_error_regs_t *pcie_rc_regs = 1833 pcie_adv_regs->pcie_adv_rc_regs; 1834 int ce, ue, mult_ce, mult_ue, first_ue_fatal, nfe, fe; 1835 1836 ce = pcie_rc_regs->pcie_rc_err_status & 1837 PCIE_AER_RE_STS_CE_RCVD; 1838 ue = pcie_rc_regs->pcie_rc_err_status & 1839 PCIE_AER_RE_STS_FE_NFE_RCVD; 1840 mult_ce = pcie_rc_regs->pcie_rc_err_status & 1841 PCIE_AER_RE_STS_MUL_CE_RCVD; 1842 mult_ue = pcie_rc_regs->pcie_rc_err_status & 1843 PCIE_AER_RE_STS_MUL_FE_NFE_RCVD; 1844 first_ue_fatal = pcie_rc_regs->pcie_rc_err_status & 1845 PCIE_AER_RE_STS_FIRST_UC_FATAL; 1846 nfe = pcie_rc_regs->pcie_rc_err_status & 1847 PCIE_AER_RE_STS_NFE_MSGS_RCVD; 1848 fe = pcie_rc_regs->pcie_rc_err_status & 1849 PCIE_AER_RE_STS_FE_MSGS_RCVD; 1850 /* 1851 * log fatal/nonfatal/corrected messages 1852 * recieved by root complex 1853 */ 1854 if (ue && fe) 1855 fatal++; 1856 1857 if (fe && first_ue_fatal) { 1858 (void) snprintf(buf, FM_MAX_CLASS, 1859 "%s.%s", PCIEX_ERROR_SUBCLASS, PCIEX_RC_FE_MSG); 1860 pcie_ereport_post(dip, derr, erpt_p, buf, 1861 PCIEX_TYPE_RC_UE_MSG); 1862 } 1863 if (nfe && !first_ue_fatal) { 1864 (void) snprintf(buf, FM_MAX_CLASS, 1865 "%s.%s", PCIEX_ERROR_SUBCLASS, PCIEX_RC_NFE_MSG); 1866 pcie_ereport_post(dip, derr, erpt_p, buf, 1867 PCIEX_TYPE_RC_UE_MSG); 1868 } 1869 if (ce) { 1870 (void) snprintf(buf, FM_MAX_CLASS, 1871 "%s.%s", PCIEX_ERROR_SUBCLASS, PCIEX_RC_CE_MSG); 1872 pcie_ereport_post(dip, derr, erpt_p, buf, 1873 PCIEX_TYPE_RC_CE_MSG); 1874 } 1875 if (mult_ce) { 1876 (void) snprintf(buf, FM_MAX_CLASS, 1877 "%s.%s", PCIEX_ERROR_SUBCLASS, PCIEX_RC_MCE_MSG); 1878 pcie_ereport_post(dip, derr, erpt_p, buf, 1879 PCIEX_TYPE_RC_MULT_MSG); 1880 } 1881 if (mult_ue) { 1882 (void) snprintf(buf, FM_MAX_CLASS, 1883 "%s.%s", PCIEX_ERROR_SUBCLASS, PCIEX_RC_MUE_MSG); 1884 pcie_ereport_post(dip, derr, erpt_p, buf, 1885 PCIEX_TYPE_RC_MULT_MSG); 1886 } 1887 } 1888 return (fatal ? DDI_FM_FATAL : (nonfatal ? DDI_FM_NONFATAL : 1889 (unknown ? DDI_FM_UNKNOWN : DDI_FM_OK))); 1890 } 1891 1892 static int 1893 pcie_error_report(dev_info_t *dip, ddi_fm_error_t *derr, pci_erpt_t *erpt_p) 1894 { 1895 int fatal = 0; 1896 int nonfatal = 0; 1897 int unknown = 0; 1898 int ok = 0; 1899 char buf[FM_MAX_CLASS]; 1900 int i; 1901 pcie_error_regs_t *pcie_regs = (pcie_error_regs_t *)erpt_p->pe_regs; 1902 pcie_adv_error_regs_t *pcie_adv_regs; 1903 pcie_adv_bdg_error_regs_t *pcie_bdg_regs; 1904 1905 if ((erpt_p->pe_dflags & PCI_BRIDGE_DEV) && 1906 (erpt_p->pe_dflags & PCIX_DEV)) { 1907 int ret = pcix_bdg_error_report(dip, derr, erpt_p, 1908 (void *)pcie_regs->pcix_bdg_regs); 1909 PCI_FM_SEV_INC(ret); 1910 } 1911 1912 if (!(erpt_p->pe_dflags & PCIEX_ADV_DEV)) { 1913 if (!(pcie_regs->pcie_vflags & PCIE_ERR_STATUS_VALID)) 1914 goto done; 1915 for (i = 0; pciex_nadv_err_tbl[i].err_class != NULL; i++) { 1916 if (!(pcie_regs->pcie_err_status & 1917 pciex_nadv_err_tbl[i].reg_bit)) 1918 continue; 1919 1920 (void) snprintf(buf, FM_MAX_CLASS, "%s.%s", 1921 PCIEX_ERROR_SUBCLASS, 1922 pciex_nadv_err_tbl[i].err_class); 1923 pcie_ereport_post(dip, derr, erpt_p, buf, 1924 PCIEX_TYPE_GEN); 1925 PCI_FM_SEV_INC(pciex_nadv_err_tbl[i].flags); 1926 } 1927 goto done; 1928 } 1929 1930 pcie_adv_regs = pcie_regs->pcie_adv_regs; 1931 1932 /* 1933 * Log PCI Express uncorrectable errors 1934 */ 1935 if (pcie_adv_regs->pcie_adv_vflags & PCIE_UE_STATUS_VALID) { 1936 for (i = 0; pciex_ue_err_tbl[i].err_class != NULL; i++) { 1937 if (!(pcie_adv_regs->pcie_ue_status & 1938 pciex_ue_err_tbl[i].reg_bit)) 1939 continue; 1940 1941 (void) snprintf(buf, FM_MAX_CLASS, 1942 "%s.%s", PCIEX_ERROR_SUBCLASS, 1943 pciex_ue_err_tbl[i].err_class); 1944 1945 pcie_adv_regs->pcie_adv_bdf = 0; 1946 if ((pcie_adv_regs->pcie_ue_status & 1947 PCIE_AER_UCE_LOG_BITS) != 1948 pciex_ue_err_tbl[i].reg_bit) { 1949 PCI_FM_SEV_INC(pciex_ue_err_tbl[i].flags); 1950 pcie_ereport_post(dip, derr, erpt_p, buf, 1951 PCIEX_TYPE_UE); 1952 } else { 1953 pcie_check_addr(dip, derr, erpt_p); 1954 /* 1955 * fatal/ok errors are fatal/ok 1956 * regardless of if we find a handle 1957 */ 1958 if (pciex_ue_err_tbl[i].flags == DDI_FM_FATAL) 1959 derr->fme_status = DDI_FM_FATAL; 1960 else if (pciex_ue_err_tbl[i].flags == DDI_FM_OK) 1961 derr->fme_status = DDI_FM_OK; 1962 pcie_ereport_post(dip, derr, erpt_p, buf, 1963 PCIEX_TYPE_UE); 1964 PCI_FM_SEV_INC(derr->fme_status); 1965 } 1966 } 1967 } 1968 1969 /* 1970 * Log PCI Express correctable errors 1971 */ 1972 if (pcie_adv_regs->pcie_adv_vflags & PCIE_CE_STATUS_VALID) { 1973 for (i = 0; pciex_ce_err_tbl[i].err_class != NULL; i++) { 1974 if (!(pcie_adv_regs->pcie_ce_status & 1975 pciex_ce_err_tbl[i].reg_bit)) 1976 continue; 1977 1978 (void) snprintf(buf, FM_MAX_CLASS, 1979 "%s.%s", PCIEX_ERROR_SUBCLASS, 1980 pciex_ce_err_tbl[i].err_class); 1981 pcie_ereport_post(dip, derr, erpt_p, buf, 1982 PCIEX_TYPE_CE); 1983 } 1984 } 1985 1986 if (!(erpt_p->pe_dflags & PCI_BRIDGE_DEV)) 1987 goto done; 1988 1989 if (erpt_p->pe_dflags & PCIEX_RC_DEV) { 1990 int ret = pcie_rc_error_report(dip, derr, erpt_p, 1991 (void *)pcie_adv_regs); 1992 PCI_FM_SEV_INC(ret); 1993 } 1994 1995 if (!((erpt_p->pe_dflags & PCIEX_2PCI_DEV) && 1996 (pcie_adv_regs->pcie_adv_vflags & PCIE_SUE_STATUS_VALID))) 1997 goto done; 1998 1999 pcie_bdg_regs = pcie_adv_regs->pcie_adv_bdg_regs; 2000 2001 for (i = 0; pcie_sue_err_tbl[i].err_class != NULL; i++) { 2002 if ((pcie_bdg_regs->pcie_sue_status & 2003 pcie_sue_err_tbl[i].reg_bit)) { 2004 (void) snprintf(buf, FM_MAX_CLASS, "%s.%s", 2005 PCIEX_ERROR_SUBCLASS, 2006 pcie_sue_err_tbl[i].err_class); 2007 2008 if ((pcie_bdg_regs->pcie_sue_status & 2009 PCIE_AER_SUCE_LOG_BITS) != 2010 pcie_sue_err_tbl[i].reg_bit) { 2011 PCI_FM_SEV_INC(pcie_sue_err_tbl[i].flags); 2012 ddi_fm_ereport_post(dip, buf, derr->fme_ena, 2013 DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 2014 PCIEX_SEC_UE_STATUS, DATA_TYPE_UINT32, 2015 pcie_bdg_regs->pcie_sue_status, 2016 #ifdef DEBUG 2017 PCIEX_SUE_HDR0, DATA_TYPE_UINT32, 2018 pcie_bdg_regs->pcie_sue_hdr0, 2019 PCIEX_SUE_HDR1, DATA_TYPE_UINT32, 2020 pcie_bdg_regs->pcie_sue_hdr[0], 2021 PCIEX_SUE_HDR2, DATA_TYPE_UINT32, 2022 pcie_bdg_regs->pcie_sue_hdr[1], 2023 PCIEX_SUE_HDR3, DATA_TYPE_UINT32, 2024 pcie_bdg_regs->pcie_sue_hdr[2], 2025 #endif 2026 NULL); 2027 } else { 2028 pcie_adv_regs->pcie_adv_bdf = 0; 2029 pcie_pci_check_addr(dip, derr, erpt_p); 2030 /* 2031 * fatal/nonfatal errors are fatal/nonfatal 2032 * regardless of if we find a handle 2033 */ 2034 if (pcie_sue_err_tbl[i].flags == DDI_FM_FATAL) 2035 derr->fme_status = DDI_FM_FATAL; 2036 else if (pcie_sue_err_tbl[i].flags == 2037 DDI_FM_NONFATAL) 2038 derr->fme_status = DDI_FM_NONFATAL; 2039 2040 ddi_fm_ereport_post(dip, buf, derr->fme_ena, 2041 DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 2042 PCIEX_SEC_UE_STATUS, DATA_TYPE_UINT32, 2043 pcie_bdg_regs->pcie_sue_status, 2044 PCIEX_SRC_ID, DATA_TYPE_UINT16, 2045 pcie_adv_regs->pcie_adv_bdf, 2046 PCIEX_SRC_VALID, DATA_TYPE_BOOLEAN_VALUE, 2047 (pcie_adv_regs->pcie_adv_bdf != NULL) ? 2048 1 : NULL, 2049 #ifdef DEBUG 2050 PCIEX_SUE_HDR0, DATA_TYPE_UINT32, 2051 pcie_bdg_regs->pcie_sue_hdr0, 2052 PCIEX_SUE_HDR1, DATA_TYPE_UINT32, 2053 pcie_bdg_regs->pcie_sue_hdr[0], 2054 PCIEX_SUE_HDR2, DATA_TYPE_UINT32, 2055 pcie_bdg_regs->pcie_sue_hdr[1], 2056 PCIEX_SUE_HDR3, DATA_TYPE_UINT32, 2057 pcie_bdg_regs->pcie_sue_hdr[2], 2058 #endif 2059 NULL); 2060 PCI_FM_SEV_INC(derr->fme_status); 2061 } 2062 } 2063 } 2064 done: 2065 return (fatal ? DDI_FM_FATAL : (nonfatal ? DDI_FM_NONFATAL : 2066 (unknown ? DDI_FM_UNKNOWN : DDI_FM_OK))); 2067 } 2068 2069 static void 2070 pci_error_report(dev_info_t *dip, ddi_fm_error_t *derr, pci_erpt_t *erpt_p) 2071 { 2072 int fatal = 0; 2073 int nonfatal = 0; 2074 int unknown = 0; 2075 int ok = 0; 2076 char buf[FM_MAX_CLASS]; 2077 int i; 2078 2079 if (derr->fme_flag == DDI_FM_ERR_UNEXPECTED) { 2080 /* 2081 * Log generic PCI errors. 2082 */ 2083 for (i = 0; pci_err_tbl[i].err_class != NULL; i++) { 2084 if (!(erpt_p->pe_pci_regs->pci_err_status & 2085 pci_err_tbl[i].reg_bit) || 2086 !(erpt_p->pe_pci_regs->pci_vflags & 2087 PCI_ERR_STATUS_VALID)) 2088 continue; 2089 /* 2090 * Generate an ereport for this error bit. 2091 */ 2092 (void) snprintf(buf, FM_MAX_CLASS, "%s.%s", 2093 PCI_ERROR_SUBCLASS, pci_err_tbl[i].err_class); 2094 ddi_fm_ereport_post(dip, buf, derr->fme_ena, 2095 DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 2096 PCI_CONFIG_STATUS, DATA_TYPE_UINT16, 2097 erpt_p->pe_pci_regs->pci_err_status, 2098 PCI_CONFIG_COMMAND, DATA_TYPE_UINT16, 2099 erpt_p->pe_pci_regs->pci_cfg_comm, NULL); 2100 2101 /* 2102 * The meaning of SERR is different for PCIEX (just 2103 * implies a message has been sent) so we don't want to 2104 * treat that one as fatal. 2105 */ 2106 if ((erpt_p->pe_dflags & PCIEX_DEV) && 2107 pci_err_tbl[i].reg_bit == PCI_STAT_S_SYSERR) { 2108 unknown++; 2109 } else { 2110 PCI_FM_SEV_INC(pci_err_tbl[i].flags); 2111 } 2112 } 2113 if (erpt_p->pe_dflags & PCIEX_DEV) { 2114 int ret = pcie_error_report(dip, derr, erpt_p); 2115 PCI_FM_SEV_INC(ret); 2116 } else if (erpt_p->pe_dflags & PCIX_DEV) { 2117 if (erpt_p->pe_dflags & PCI_BRIDGE_DEV) { 2118 int ret = pcix_bdg_error_report(dip, derr, 2119 erpt_p, erpt_p->pe_regs); 2120 PCI_FM_SEV_INC(ret); 2121 } else { 2122 int ret = pcix_error_report(dip, derr, erpt_p); 2123 PCI_FM_SEV_INC(ret); 2124 } 2125 } 2126 } 2127 2128 if ((erpt_p->pe_dflags & PCI_BRIDGE_DEV)) { 2129 int ret = pci_bdg_error_report(dip, derr, erpt_p); 2130 PCI_FM_SEV_INC(ret); 2131 } 2132 2133 derr->fme_status = (fatal ? DDI_FM_FATAL : (nonfatal ? DDI_FM_NONFATAL : 2134 (unknown ? DDI_FM_UNKNOWN : DDI_FM_OK))); 2135 } 2136 2137 void 2138 pci_ereport_post(dev_info_t *dip, ddi_fm_error_t *derr, uint16_t *xx_status) 2139 { 2140 struct i_ddi_fmhdl *fmhdl; 2141 pci_erpt_t *erpt_p; 2142 2143 fmhdl = DEVI(dip)->devi_fmhdl; 2144 if (!DDI_FM_EREPORT_CAP(ddi_fm_capable(dip)) && 2145 !DDI_FM_ERRCB_CAP(ddi_fm_capable(dip))) { 2146 i_ddi_drv_ereport_post(dip, DVR_EFMCAP, NULL, DDI_NOSLEEP); 2147 return; 2148 } 2149 2150 ASSERT(fmhdl); 2151 2152 if (derr->fme_ena == NULL) 2153 derr->fme_ena = fm_ena_generate(0, FM_ENA_FMT1); 2154 2155 erpt_p = (pci_erpt_t *)fmhdl->fh_bus_specific; 2156 if (erpt_p == NULL) 2157 return; 2158 2159 pci_regs_gather(dip, erpt_p); 2160 pci_error_report(dip, derr, erpt_p); 2161 pci_regs_clear(erpt_p); 2162 2163 if (xx_status != NULL) 2164 *xx_status = erpt_p->pe_pci_regs->pci_err_status; 2165 } 2166 2167 /* 2168 * private version of walk_devs() that can be used during panic. No 2169 * sleeping or locking required. 2170 */ 2171 static int 2172 pci_fm_walk_devs(dev_info_t *dip, int (*f)(dev_info_t *, void *), void *arg) 2173 { 2174 while (dip) { 2175 switch ((*f)(dip, arg)) { 2176 case DDI_WALK_TERMINATE: 2177 return (DDI_WALK_TERMINATE); 2178 case DDI_WALK_CONTINUE: 2179 if (pci_fm_walk_devs(ddi_get_child(dip), f, 2180 arg) == DDI_WALK_TERMINATE) 2181 return (DDI_WALK_TERMINATE); 2182 break; 2183 case DDI_WALK_PRUNECHILD: 2184 break; 2185 } 2186 dip = ddi_get_next_sibling(dip); 2187 } 2188 return (DDI_WALK_CONTINUE); 2189 } 2190 2191 /* 2192 * need special version of ddi_fm_ereport_post() as the leaf driver may 2193 * not be hardened. 2194 */ 2195 static void 2196 pci_fm_ereport_post(dev_info_t *dip, const char *error_class, uint64_t ena, 2197 uint8_t version, ...) 2198 { 2199 char *name; 2200 char device_path[MAXPATHLEN]; 2201 char ddi_error_class[FM_MAX_CLASS]; 2202 nvlist_t *ereport, *detector; 2203 nv_alloc_t *nva; 2204 errorq_elem_t *eqep; 2205 va_list ap; 2206 2207 if (panicstr) { 2208 eqep = errorq_reserve(ereport_errorq); 2209 if (eqep == NULL) 2210 return; 2211 ereport = errorq_elem_nvl(ereport_errorq, eqep); 2212 nva = errorq_elem_nva(ereport_errorq, eqep); 2213 detector = fm_nvlist_create(nva); 2214 } else { 2215 ereport = fm_nvlist_create(NULL); 2216 detector = fm_nvlist_create(NULL); 2217 } 2218 2219 (void) ddi_pathname(dip, device_path); 2220 fm_fmri_dev_set(detector, FM_DEV_SCHEME_VERSION, NULL, 2221 device_path, NULL); 2222 (void) snprintf(ddi_error_class, FM_MAX_CLASS, "%s.%s", 2223 DDI_IO_CLASS, error_class); 2224 fm_ereport_set(ereport, version, ddi_error_class, ena, detector, NULL); 2225 2226 va_start(ap, version); 2227 name = va_arg(ap, char *); 2228 (void) i_fm_payload_set(ereport, name, ap); 2229 va_end(ap); 2230 2231 if (panicstr) { 2232 errorq_commit(ereport_errorq, eqep, ERRORQ_SYNC); 2233 } else { 2234 (void) fm_ereport_post(ereport, EVCH_TRYHARD); 2235 fm_nvlist_destroy(ereport, FM_NVA_FREE); 2236 fm_nvlist_destroy(detector, FM_NVA_FREE); 2237 } 2238 } 2239 2240 static int 2241 pci_check_regs(dev_info_t *dip, void *arg) 2242 { 2243 int reglen; 2244 int rn; 2245 int totreg; 2246 pci_regspec_t *drv_regp; 2247 pci_target_err_t *tgt_err = (pci_target_err_t *)arg; 2248 2249 if (tgt_err->tgt_pci_space == PCI_REG_ADDR_G(PCI_ADDR_CONFIG)) { 2250 /* 2251 * for config space, we need to check if the given address 2252 * is a valid config space address for this device - based 2253 * on pci_phys_hi of the config space entry in reg property. 2254 */ 2255 if (ddi_getlongprop(DDI_DEV_T_NONE, dip, DDI_PROP_DONTPASS, 2256 "reg", (caddr_t)&drv_regp, ®len) != DDI_SUCCESS) 2257 return (DDI_WALK_CONTINUE); 2258 2259 totreg = reglen / sizeof (pci_regspec_t); 2260 for (rn = 0; rn < totreg; rn++) { 2261 if (tgt_err->tgt_pci_space == 2262 PCI_REG_ADDR_G(drv_regp[rn].pci_phys_hi) && 2263 (tgt_err->tgt_pci_addr & (PCI_REG_BUS_M | 2264 PCI_REG_DEV_M | PCI_REG_FUNC_M)) == 2265 (drv_regp[rn].pci_phys_hi & (PCI_REG_BUS_M | 2266 PCI_REG_DEV_M | PCI_REG_FUNC_M))) { 2267 tgt_err->tgt_dip = dip; 2268 kmem_free(drv_regp, reglen); 2269 return (DDI_WALK_TERMINATE); 2270 } 2271 } 2272 kmem_free(drv_regp, reglen); 2273 } else { 2274 /* 2275 * for non config space, need to check reg to look 2276 * for any non-relocable mapping, otherwise check 2277 * assigned-addresses. 2278 */ 2279 if (ddi_getlongprop(DDI_DEV_T_NONE, dip, DDI_PROP_DONTPASS, 2280 "reg", (caddr_t)&drv_regp, ®len) != DDI_SUCCESS) 2281 return (DDI_WALK_CONTINUE); 2282 2283 totreg = reglen / sizeof (pci_regspec_t); 2284 for (rn = 0; rn < totreg; rn++) { 2285 if ((drv_regp[rn].pci_phys_hi & PCI_RELOCAT_B) && 2286 (tgt_err->tgt_pci_space == TGT_PCI_SPACE_UNKNOWN || 2287 tgt_err->tgt_pci_space == 2288 PCI_REG_ADDR_G(drv_regp[rn].pci_phys_hi)) && 2289 (tgt_err->tgt_pci_addr >= 2290 (uint64_t)drv_regp[rn].pci_phys_low + 2291 ((uint64_t)drv_regp[rn].pci_phys_mid << 32)) && 2292 (tgt_err->tgt_pci_addr < 2293 (uint64_t)drv_regp[rn].pci_phys_low + 2294 ((uint64_t)drv_regp[rn].pci_phys_mid << 32) + 2295 (uint64_t)drv_regp[rn].pci_size_low + 2296 ((uint64_t)drv_regp[rn].pci_size_hi << 32))) { 2297 tgt_err->tgt_dip = dip; 2298 kmem_free(drv_regp, reglen); 2299 return (DDI_WALK_TERMINATE); 2300 } 2301 } 2302 kmem_free(drv_regp, reglen); 2303 2304 if (ddi_getlongprop(DDI_DEV_T_NONE, dip, DDI_PROP_DONTPASS, 2305 "assigned-addresses", (caddr_t)&drv_regp, ®len) != 2306 DDI_SUCCESS) 2307 return (DDI_WALK_CONTINUE); 2308 2309 totreg = reglen / sizeof (pci_regspec_t); 2310 for (rn = 0; rn < totreg; rn++) { 2311 if ((tgt_err->tgt_pci_space == TGT_PCI_SPACE_UNKNOWN || 2312 tgt_err->tgt_pci_space == 2313 PCI_REG_ADDR_G(drv_regp[rn].pci_phys_hi)) && 2314 (tgt_err->tgt_pci_addr >= 2315 (uint64_t)drv_regp[rn].pci_phys_low + 2316 ((uint64_t)drv_regp[rn].pci_phys_mid << 32)) && 2317 (tgt_err->tgt_pci_addr < 2318 (uint64_t)drv_regp[rn].pci_phys_low + 2319 ((uint64_t)drv_regp[rn].pci_phys_mid << 32) + 2320 (uint64_t)drv_regp[rn].pci_size_low + 2321 ((uint64_t)drv_regp[rn].pci_size_hi << 32))) { 2322 tgt_err->tgt_dip = dip; 2323 kmem_free(drv_regp, reglen); 2324 return (DDI_WALK_TERMINATE); 2325 } 2326 } 2327 kmem_free(drv_regp, reglen); 2328 } 2329 return (DDI_WALK_CONTINUE); 2330 } 2331 2332 /* 2333 * impl_fix_ranges - fixes the config space entry of the "ranges" 2334 * property on psycho+ platforms. (if changing this function please make sure 2335 * to change the pci_fix_ranges function in pcipsy.c) 2336 */ 2337 /*ARGSUSED*/ 2338 static void 2339 pci_fix_ranges(dev_info_t *dip, pci_ranges_t *pci_ranges, int nrange) 2340 { 2341 #if defined(__sparc) 2342 char *name = ddi_binding_name(dip); 2343 2344 if ((strcmp(name, "pci108e,8000") == 0) || 2345 (strcmp(name, "pci108e,a000") == 0) || 2346 (strcmp(name, "pci108e,a001") == 0)) { 2347 int i; 2348 for (i = 0; i < nrange; i++, pci_ranges++) 2349 if ((pci_ranges->child_high & PCI_REG_ADDR_M) == 2350 PCI_ADDR_CONFIG) 2351 pci_ranges->parent_low |= 2352 pci_ranges->child_high; 2353 } 2354 #endif 2355 } 2356 2357 static int 2358 pci_check_ranges(dev_info_t *dip, void *arg) 2359 { 2360 uint64_t range_parent_begin; 2361 uint64_t range_parent_size; 2362 uint64_t range_parent_end; 2363 uint32_t space_type; 2364 uint32_t bus_num; 2365 uint32_t range_offset; 2366 pci_ranges_t *pci_ranges, *rangep; 2367 pci_bus_range_t *pci_bus_rangep; 2368 int pci_ranges_length; 2369 int nrange; 2370 pci_target_err_t *tgt_err = (pci_target_err_t *)arg; 2371 int i, size; 2372 if (strcmp(ddi_node_name(dip), "pci") != 0 && 2373 strcmp(ddi_node_name(dip), "pciex") != 0) 2374 return (DDI_WALK_CONTINUE); 2375 2376 /* 2377 * Get the ranges property. Note we only look at the top level pci 2378 * node (hostbridge) which has a ranges property of type pci_ranges_t 2379 * not at pci-pci bridges. 2380 */ 2381 if (ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, "ranges", 2382 (caddr_t)&pci_ranges, &pci_ranges_length) != DDI_SUCCESS) { 2383 /* 2384 * no ranges property - no translation needed 2385 */ 2386 tgt_err->tgt_pci_addr = tgt_err->tgt_err_addr; 2387 tgt_err->tgt_pci_space = TGT_PCI_SPACE_UNKNOWN; 2388 if (panicstr) 2389 (void) pci_fm_walk_devs(ddi_get_child(dip), 2390 pci_check_regs, (void *)tgt_err); 2391 else { 2392 int circ = 0; 2393 ndi_devi_enter(dip, &circ); 2394 ddi_walk_devs(ddi_get_child(dip), pci_check_regs, 2395 (void *)tgt_err); 2396 ndi_devi_exit(dip, circ); 2397 } 2398 if (tgt_err->tgt_dip != NULL) 2399 return (DDI_WALK_TERMINATE); 2400 return (DDI_WALK_PRUNECHILD); 2401 } 2402 nrange = pci_ranges_length / sizeof (pci_ranges_t); 2403 rangep = pci_ranges; 2404 2405 /* Need to fix the pci ranges property for psycho based systems */ 2406 pci_fix_ranges(dip, pci_ranges, nrange); 2407 2408 for (i = 0; i < nrange; i++, rangep++) { 2409 range_parent_begin = ((uint64_t)rangep->parent_high << 32) + 2410 rangep->parent_low; 2411 range_parent_size = ((uint64_t)rangep->size_high << 32) + 2412 rangep->size_low; 2413 range_parent_end = range_parent_begin + range_parent_size - 1; 2414 2415 if ((tgt_err->tgt_err_addr < range_parent_begin) || 2416 (tgt_err->tgt_err_addr > range_parent_end)) { 2417 /* Not in range */ 2418 continue; 2419 } 2420 space_type = PCI_REG_ADDR_G(rangep->child_high); 2421 if (space_type == PCI_REG_ADDR_G(PCI_ADDR_CONFIG)) { 2422 /* Config space address - check bus range */ 2423 range_offset = tgt_err->tgt_err_addr - 2424 range_parent_begin; 2425 bus_num = PCI_REG_BUS_G(range_offset); 2426 if (ddi_getlongprop(DDI_DEV_T_ANY, dip, 2427 DDI_PROP_DONTPASS, "bus-range", 2428 (caddr_t)&pci_bus_rangep, &size) != DDI_SUCCESS) { 2429 continue; 2430 } 2431 if ((bus_num < pci_bus_rangep->lo) || 2432 (bus_num > pci_bus_rangep->hi)) { 2433 /* 2434 * Bus number not appropriate for this 2435 * pci nexus. 2436 */ 2437 kmem_free(pci_bus_rangep, size); 2438 continue; 2439 } 2440 kmem_free(pci_bus_rangep, size); 2441 } 2442 2443 /* We have a match if we get here - compute pci address */ 2444 tgt_err->tgt_pci_addr = tgt_err->tgt_err_addr - 2445 range_parent_begin; 2446 tgt_err->tgt_pci_addr += (((uint64_t)rangep->child_mid << 32) + 2447 rangep->child_low); 2448 tgt_err->tgt_pci_space = space_type; 2449 if (panicstr) 2450 (void) pci_fm_walk_devs(ddi_get_child(dip), 2451 pci_check_regs, (void *)tgt_err); 2452 else { 2453 int circ = 0; 2454 ndi_devi_enter(dip, &circ); 2455 ddi_walk_devs(ddi_get_child(dip), pci_check_regs, 2456 (void *)tgt_err); 2457 ndi_devi_exit(dip, circ); 2458 } 2459 if (tgt_err->tgt_dip != NULL) { 2460 kmem_free(pci_ranges, pci_ranges_length); 2461 return (DDI_WALK_TERMINATE); 2462 } 2463 } 2464 kmem_free(pci_ranges, pci_ranges_length); 2465 return (DDI_WALK_PRUNECHILD); 2466 } 2467 2468 /* 2469 * Function used to drain pci_target_queue, either during panic or after softint 2470 * is generated, to generate target device ereports based on captured physical 2471 * addresses 2472 */ 2473 /*ARGSUSED*/ 2474 static void 2475 pci_target_drain(void *private_p, pci_target_err_t *tgt_err) 2476 { 2477 char buf[FM_MAX_CLASS]; 2478 2479 /* 2480 * The following assumes that all pci_pci bridge devices 2481 * are configured as transparant. Find the top-level pci 2482 * nexus which has tgt_err_addr in one of its ranges, converting this 2483 * to a pci address in the process. Then starting at this node do 2484 * another tree walk to find a device with the pci address we've 2485 * found within range of one of it's assigned-addresses properties. 2486 */ 2487 tgt_err->tgt_dip = NULL; 2488 if (panicstr) 2489 (void) pci_fm_walk_devs(ddi_root_node(), pci_check_ranges, 2490 (void *)tgt_err); 2491 else 2492 ddi_walk_devs(ddi_root_node(), pci_check_ranges, 2493 (void *)tgt_err); 2494 if (tgt_err->tgt_dip == NULL) 2495 return; 2496 2497 (void) snprintf(buf, FM_MAX_CLASS, "%s.%s", tgt_err->tgt_bridge_type, 2498 tgt_err->tgt_err_class); 2499 pci_fm_ereport_post(tgt_err->tgt_dip, buf, tgt_err->tgt_err_ena, 0, 2500 PCI_PA, DATA_TYPE_UINT64, tgt_err->tgt_err_addr, NULL); 2501 } 2502 2503 void 2504 pci_target_enqueue(uint64_t ena, char *class, char *bridge_type, uint64_t addr) 2505 { 2506 pci_target_err_t tgt_err; 2507 2508 tgt_err.tgt_err_ena = ena; 2509 tgt_err.tgt_err_class = class; 2510 tgt_err.tgt_bridge_type = bridge_type; 2511 tgt_err.tgt_err_addr = addr; 2512 errorq_dispatch(pci_target_queue, (void *)&tgt_err, 2513 sizeof (pci_target_err_t), ERRORQ_ASYNC); 2514 } 2515 2516 void 2517 pci_targetq_init(void) 2518 { 2519 /* 2520 * PCI target errorq, to schedule async handling of generation of 2521 * target device ereports based on captured physical address. 2522 * The errorq is created here but destroyed when _fini is called 2523 * for the pci module. 2524 */ 2525 if (pci_target_queue == NULL) { 2526 pci_target_queue = errorq_create("pci_target_queue", 2527 (errorq_func_t)pci_target_drain, (void *)NULL, 2528 TARGET_MAX_ERRS, sizeof (pci_target_err_t), FM_ERR_PIL, 2529 ERRORQ_VITAL); 2530 if (pci_target_queue == NULL) 2531 panic("failed to create required system error queue"); 2532 } 2533 } 2534