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