127Sjchu /* 227Sjchu * CDDL HEADER START 327Sjchu * 427Sjchu * The contents of this file are subject to the terms of the 51648Sjchu * Common Development and Distribution License (the "License"). 61648Sjchu * You may not use this file except in compliance with the License. 727Sjchu * 827Sjchu * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 927Sjchu * or http://www.opensolaris.org/os/licensing. 1027Sjchu * See the License for the specific language governing permissions 1127Sjchu * and limitations under the License. 1227Sjchu * 1327Sjchu * When distributing Covered Code, include this CDDL HEADER in each 1427Sjchu * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 1527Sjchu * If applicable, add the following below this CDDL HEADER, with the 1627Sjchu * fields enclosed by brackets "[]" replaced with your own identifying 1727Sjchu * information: Portions Copyright [yyyy] [name of copyright owner] 1827Sjchu * 1927Sjchu * CDDL HEADER END 2027Sjchu */ 2127Sjchu /* 221648Sjchu * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 2327Sjchu * Use is subject to license terms. 2427Sjchu */ 2527Sjchu 2627Sjchu #pragma ident "%Z%%M% %I% %E% SMI" 2727Sjchu 2827Sjchu /* 2927Sjchu * sun4u Fire Error Handling 3027Sjchu */ 3127Sjchu 3227Sjchu #include <sys/types.h> 3327Sjchu #include <sys/ddi.h> 3427Sjchu #include <sys/sunddi.h> 3527Sjchu #include <sys/fm/protocol.h> 3627Sjchu #include <sys/fm/util.h> 3727Sjchu #include <sys/pcie.h> 3827Sjchu #include <sys/pcie_impl.h> 3927Sjchu #include "px_obj.h" 4027Sjchu #include <px_regs.h> 4127Sjchu #include <px_csr.h> 4227Sjchu #include <sys/membar.h> 43*1772Sjl139090 #include <sys/machcpuvar.h> 44*1772Sjl139090 #include <sys/platform_module.h> 45118Sjchu #include "pcie_pwr.h" 4627Sjchu #include "px_lib4u.h" 4727Sjchu #include "px_err.h" 4827Sjchu #include "px_err_impl.h" 49*1772Sjl139090 #include "oberon_regs.h" 50*1772Sjl139090 51*1772Sjl139090 uint64_t px_tlu_ue_intr_mask = PX_ERR_EN_ALL; 52*1772Sjl139090 uint64_t px_tlu_ue_log_mask = PX_ERR_EN_ALL; 53*1772Sjl139090 uint64_t px_tlu_ue_count_mask = PX_ERR_EN_ALL; 54*1772Sjl139090 55*1772Sjl139090 uint64_t px_tlu_ce_intr_mask = PX_ERR_MASK_NONE; 56*1772Sjl139090 uint64_t px_tlu_ce_log_mask = PX_ERR_MASK_NONE; 57*1772Sjl139090 uint64_t px_tlu_ce_count_mask = PX_ERR_MASK_NONE; 58*1772Sjl139090 59*1772Sjl139090 /* 60*1772Sjl139090 * Do not enable Link Interrupts 61*1772Sjl139090 */ 62*1772Sjl139090 uint64_t px_tlu_oe_intr_mask = PX_ERR_EN_ALL & ~0x80000000800; 63*1772Sjl139090 uint64_t px_tlu_oe_log_mask = PX_ERR_EN_ALL & ~0x80000000800; 64*1772Sjl139090 uint64_t px_tlu_oe_count_mask = PX_ERR_EN_ALL; 65*1772Sjl139090 66*1772Sjl139090 uint64_t px_mmu_intr_mask = PX_ERR_EN_ALL; 67*1772Sjl139090 uint64_t px_mmu_log_mask = PX_ERR_EN_ALL; 68*1772Sjl139090 uint64_t px_mmu_count_mask = PX_ERR_EN_ALL; 69*1772Sjl139090 70*1772Sjl139090 uint64_t px_imu_intr_mask = PX_ERR_EN_ALL; 71*1772Sjl139090 uint64_t px_imu_log_mask = PX_ERR_EN_ALL; 72*1772Sjl139090 uint64_t px_imu_count_mask = PX_ERR_EN_ALL; 73*1772Sjl139090 74*1772Sjl139090 /* 75*1772Sjl139090 * (1ull << ILU_INTERRUPT_ENABLE_IHB_PE_S) | 76*1772Sjl139090 * (1ull << ILU_INTERRUPT_ENABLE_IHB_PE_P); 77*1772Sjl139090 */ 78*1772Sjl139090 uint64_t px_ilu_intr_mask = (((uint64_t)0x10 << 32) | 0x10); 79*1772Sjl139090 uint64_t px_ilu_log_mask = (((uint64_t)0x10 << 32) | 0x10); 80*1772Sjl139090 uint64_t px_ilu_count_mask = PX_ERR_EN_ALL; 81*1772Sjl139090 82*1772Sjl139090 uint64_t px_ubc_intr_mask = PX_ERR_EN_ALL; 83*1772Sjl139090 uint64_t px_ubc_log_mask = PX_ERR_EN_ALL; 84*1772Sjl139090 uint64_t px_ubc_count_mask = PX_ERR_EN_ALL; 85*1772Sjl139090 86*1772Sjl139090 uint64_t px_jbc_intr_mask = PX_ERR_EN_ALL; 87*1772Sjl139090 uint64_t px_jbc_log_mask = PX_ERR_EN_ALL; 88*1772Sjl139090 uint64_t px_jbc_count_mask = PX_ERR_EN_ALL; 89*1772Sjl139090 90*1772Sjl139090 /* 91*1772Sjl139090 * LPU Intr Registers are reverse encoding from the registers above. 92*1772Sjl139090 * 1 = disable 93*1772Sjl139090 * 0 = enable 94*1772Sjl139090 * 95*1772Sjl139090 * Log and Count are however still the same. 96*1772Sjl139090 */ 97*1772Sjl139090 uint64_t px_lpul_intr_mask = LPU_INTR_DISABLE; 98*1772Sjl139090 uint64_t px_lpul_log_mask = PX_ERR_EN_ALL; 99*1772Sjl139090 uint64_t px_lpul_count_mask = PX_ERR_EN_ALL; 100*1772Sjl139090 101*1772Sjl139090 uint64_t px_lpup_intr_mask = LPU_INTR_DISABLE; 102*1772Sjl139090 uint64_t px_lpup_log_mask = PX_ERR_EN_ALL; 103*1772Sjl139090 uint64_t px_lpup_count_mask = PX_ERR_EN_ALL; 104*1772Sjl139090 105*1772Sjl139090 uint64_t px_lpur_intr_mask = LPU_INTR_DISABLE; 106*1772Sjl139090 uint64_t px_lpur_log_mask = PX_ERR_EN_ALL; 107*1772Sjl139090 uint64_t px_lpur_count_mask = PX_ERR_EN_ALL; 108*1772Sjl139090 109*1772Sjl139090 uint64_t px_lpux_intr_mask = LPU_INTR_DISABLE; 110*1772Sjl139090 uint64_t px_lpux_log_mask = PX_ERR_EN_ALL; 111*1772Sjl139090 uint64_t px_lpux_count_mask = PX_ERR_EN_ALL; 112*1772Sjl139090 113*1772Sjl139090 uint64_t px_lpus_intr_mask = LPU_INTR_DISABLE; 114*1772Sjl139090 uint64_t px_lpus_log_mask = PX_ERR_EN_ALL; 115*1772Sjl139090 uint64_t px_lpus_count_mask = PX_ERR_EN_ALL; 116*1772Sjl139090 117*1772Sjl139090 uint64_t px_lpug_intr_mask = LPU_INTR_DISABLE; 118*1772Sjl139090 uint64_t px_lpug_log_mask = PX_ERR_EN_ALL; 119*1772Sjl139090 uint64_t px_lpug_count_mask = PX_ERR_EN_ALL; 12027Sjchu 12127Sjchu /* 12227Sjchu * JBC error bit table 12327Sjchu */ 12427Sjchu #define JBC_BIT_DESC(bit, hdl, erpt) \ 12527Sjchu JBC_INTERRUPT_STATUS_ ## bit ## _P, \ 12627Sjchu 0, \ 12727Sjchu PX_ERR_BIT_HANDLE(hdl), \ 12827Sjchu PX_ERPT_SEND(erpt), \ 129739Sjchu PX_ERR_JBC_CLASS(bit) }, \ 130739Sjchu { JBC_INTERRUPT_STATUS_ ## bit ## _S, \ 131739Sjchu 0, \ 132739Sjchu PX_ERR_BIT_HANDLE(hdl), \ 133739Sjchu PX_ERPT_SEND(erpt), \ 13427Sjchu PX_ERR_JBC_CLASS(bit) 135*1772Sjl139090 px_err_bit_desc_t px_err_jbc_tbl[] = { 13627Sjchu /* JBC FATAL - see io erpt doc, section 1.1 */ 13727Sjchu { JBC_BIT_DESC(MB_PEA, fatal_hw, jbc_fatal) }, 13827Sjchu { JBC_BIT_DESC(CPE, fatal_hw, jbc_fatal) }, 13927Sjchu { JBC_BIT_DESC(APE, fatal_hw, jbc_fatal) }, 14027Sjchu { JBC_BIT_DESC(PIO_CPE, fatal_hw, jbc_fatal) }, 14127Sjchu { JBC_BIT_DESC(JTCEEW, fatal_hw, jbc_fatal) }, 14227Sjchu { JBC_BIT_DESC(JTCEEI, fatal_hw, jbc_fatal) }, 14327Sjchu { JBC_BIT_DESC(JTCEER, fatal_hw, jbc_fatal) }, 14427Sjchu 14527Sjchu /* JBC MERGE - see io erpt doc, section 1.2 */ 14627Sjchu { JBC_BIT_DESC(MB_PER, jbc_merge, jbc_merge) }, 14727Sjchu { JBC_BIT_DESC(MB_PEW, jbc_merge, jbc_merge) }, 14827Sjchu 14927Sjchu /* JBC Jbusint IN - see io erpt doc, section 1.3 */ 15027Sjchu { JBC_BIT_DESC(UE_ASYN, fatal_gos, jbc_in) }, 1511648Sjchu { JBC_BIT_DESC(CE_ASYN, non_fatal, jbc_in) }, 15227Sjchu { JBC_BIT_DESC(JTE, fatal_gos, jbc_in) }, 15327Sjchu { JBC_BIT_DESC(JBE, jbc_jbusint_in, jbc_in) }, 15427Sjchu { JBC_BIT_DESC(JUE, jbc_jbusint_in, jbc_in) }, 15527Sjchu { JBC_BIT_DESC(ICISE, fatal_gos, jbc_in) }, 15627Sjchu { JBC_BIT_DESC(WR_DPE, jbc_jbusint_in, jbc_in) }, 15727Sjchu { JBC_BIT_DESC(RD_DPE, jbc_jbusint_in, jbc_in) }, 15827Sjchu { JBC_BIT_DESC(ILL_BMW, jbc_jbusint_in, jbc_in) }, 15927Sjchu { JBC_BIT_DESC(ILL_BMR, jbc_jbusint_in, jbc_in) }, 16027Sjchu { JBC_BIT_DESC(BJC, jbc_jbusint_in, jbc_in) }, 16127Sjchu 16227Sjchu /* JBC Jbusint Out - see io erpt doc, section 1.4 */ 16327Sjchu { JBC_BIT_DESC(IJP, fatal_gos, jbc_out) }, 16427Sjchu 16527Sjchu /* JBC Dmcint ODCD - see io erpt doc, section 1.5 */ 16627Sjchu { JBC_BIT_DESC(PIO_UNMAP_RD, jbc_dmcint_odcd, jbc_odcd) }, 16727Sjchu { JBC_BIT_DESC(ILL_ACC_RD, jbc_dmcint_odcd, jbc_odcd) }, 16827Sjchu { JBC_BIT_DESC(PIO_UNMAP, jbc_dmcint_odcd, jbc_odcd) }, 16927Sjchu { JBC_BIT_DESC(PIO_DPE, jbc_dmcint_odcd, jbc_odcd) }, 17027Sjchu { JBC_BIT_DESC(PIO_CPE, non_fatal, jbc_odcd) }, 17127Sjchu { JBC_BIT_DESC(ILL_ACC, jbc_dmcint_odcd, jbc_odcd) }, 17227Sjchu 17327Sjchu /* JBC Dmcint IDC - see io erpt doc, section 1.6 */ 17427Sjchu { JBC_BIT_DESC(UNSOL_RD, non_fatal, jbc_idc) }, 17527Sjchu { JBC_BIT_DESC(UNSOL_INTR, non_fatal, jbc_idc) }, 17627Sjchu 17727Sjchu /* JBC CSR - see io erpt doc, section 1.7 */ 17827Sjchu { JBC_BIT_DESC(EBUS_TO, jbc_csr, jbc_csr) } 17927Sjchu }; 18027Sjchu 181*1772Sjl139090 #define px_err_jbc_keys \ 182*1772Sjl139090 (sizeof (px_err_jbc_tbl)) / (sizeof (px_err_bit_desc_t)) 183*1772Sjl139090 184*1772Sjl139090 /* 185*1772Sjl139090 * UBC error bit table 186*1772Sjl139090 */ 187*1772Sjl139090 #define UBC_BIT_DESC(bit, hdl, erpt) \ 188*1772Sjl139090 UBC_INTERRUPT_STATUS_ ## bit ## _P, \ 189*1772Sjl139090 0, \ 190*1772Sjl139090 PX_ERR_BIT_HANDLE(hdl), \ 191*1772Sjl139090 PX_ERPT_SEND(erpt), \ 192*1772Sjl139090 PX_ERR_UBC_CLASS(bit) }, \ 193*1772Sjl139090 { UBC_INTERRUPT_STATUS_ ## bit ## _S, \ 194*1772Sjl139090 0, \ 195*1772Sjl139090 PX_ERR_BIT_HANDLE(hdl), \ 196*1772Sjl139090 PX_ERPT_SEND(erpt), \ 197*1772Sjl139090 PX_ERR_UBC_CLASS(bit) 198*1772Sjl139090 px_err_bit_desc_t px_err_ubc_tbl[] = { 199*1772Sjl139090 /* UBC FATAL */ 200*1772Sjl139090 { UBC_BIT_DESC(DMARDUEA, non_fatal, ubc_fatal) }, 201*1772Sjl139090 { UBC_BIT_DESC(DMAWTUEA, fatal_sw, ubc_fatal) }, 202*1772Sjl139090 { UBC_BIT_DESC(MEMRDAXA, fatal_sw, ubc_fatal) }, 203*1772Sjl139090 { UBC_BIT_DESC(MEMWTAXA, fatal_sw, ubc_fatal) }, 204*1772Sjl139090 { UBC_BIT_DESC(DMARDUEB, non_fatal, ubc_fatal) }, 205*1772Sjl139090 { UBC_BIT_DESC(DMAWTUEB, fatal_sw, ubc_fatal) }, 206*1772Sjl139090 { UBC_BIT_DESC(MEMRDAXB, fatal_sw, ubc_fatal) }, 207*1772Sjl139090 { UBC_BIT_DESC(MEMWTAXB, fatal_sw, ubc_fatal) }, 208*1772Sjl139090 { UBC_BIT_DESC(PIOWTUE, fatal_sw, ubc_fatal) }, 209*1772Sjl139090 { UBC_BIT_DESC(PIOWBEUE, fatal_sw, ubc_fatal) }, 210*1772Sjl139090 { UBC_BIT_DESC(PIORBEUE, fatal_sw, ubc_fatal) } 211*1772Sjl139090 }; 212*1772Sjl139090 213*1772Sjl139090 #define px_err_ubc_keys \ 214*1772Sjl139090 (sizeof (px_err_ubc_tbl)) / (sizeof (px_err_bit_desc_t)) 215*1772Sjl139090 216*1772Sjl139090 217*1772Sjl139090 char *ubc_class_eid_qualifier[] = { 218*1772Sjl139090 "-mem", 219*1772Sjl139090 "-channel", 220*1772Sjl139090 "-cpu", 221*1772Sjl139090 "-path" 222*1772Sjl139090 }; 223*1772Sjl139090 22427Sjchu 22527Sjchu /* 22627Sjchu * DMC error bit tables 22727Sjchu */ 22827Sjchu #define IMU_BIT_DESC(bit, hdl, erpt) \ 22927Sjchu IMU_INTERRUPT_STATUS_ ## bit ## _P, \ 23027Sjchu 0, \ 23127Sjchu PX_ERR_BIT_HANDLE(hdl), \ 23227Sjchu PX_ERPT_SEND(erpt), \ 233739Sjchu PX_ERR_DMC_CLASS(bit) }, \ 234739Sjchu { IMU_INTERRUPT_STATUS_ ## bit ## _S, \ 235739Sjchu 0, \ 236739Sjchu PX_ERR_BIT_HANDLE(hdl), \ 237739Sjchu PX_ERPT_SEND(erpt), \ 23827Sjchu PX_ERR_DMC_CLASS(bit) 23927Sjchu px_err_bit_desc_t px_err_imu_tbl[] = { 24027Sjchu /* DMC IMU RDS - see io erpt doc, section 2.1 */ 24127Sjchu { IMU_BIT_DESC(MSI_MAL_ERR, non_fatal, imu_rds) }, 24227Sjchu { IMU_BIT_DESC(MSI_PAR_ERR, fatal_stuck, imu_rds) }, 24327Sjchu { IMU_BIT_DESC(PMEACK_MES_NOT_EN, imu_rbne, imu_rds) }, 244118Sjchu { IMU_BIT_DESC(PMPME_MES_NOT_EN, imu_pme, imu_rds) }, 24527Sjchu { IMU_BIT_DESC(FATAL_MES_NOT_EN, imu_rbne, imu_rds) }, 24627Sjchu { IMU_BIT_DESC(NONFATAL_MES_NOT_EN, imu_rbne, imu_rds) }, 24727Sjchu { IMU_BIT_DESC(COR_MES_NOT_EN, imu_rbne, imu_rds) }, 24827Sjchu { IMU_BIT_DESC(MSI_NOT_EN, imu_rbne, imu_rds) }, 24927Sjchu 25027Sjchu /* DMC IMU SCS - see io erpt doc, section 2.2 */ 25127Sjchu { IMU_BIT_DESC(EQ_NOT_EN, imu_rbne, imu_rds) }, 25227Sjchu 25327Sjchu /* DMC IMU - see io erpt doc, section 2.3 */ 25427Sjchu { IMU_BIT_DESC(EQ_OVER, imu_eq_ovfl, imu) } 25527Sjchu }; 25627Sjchu 25727Sjchu #define px_err_imu_keys (sizeof (px_err_imu_tbl)) / (sizeof (px_err_bit_desc_t)) 25827Sjchu 25927Sjchu /* mmu errors */ 26027Sjchu #define MMU_BIT_DESC(bit, hdl, erpt) \ 26127Sjchu MMU_INTERRUPT_STATUS_ ## bit ## _P, \ 26227Sjchu 0, \ 26327Sjchu PX_ERR_BIT_HANDLE(hdl), \ 26427Sjchu PX_ERPT_SEND(erpt), \ 265739Sjchu PX_ERR_DMC_CLASS(bit) }, \ 266739Sjchu { MMU_INTERRUPT_STATUS_ ## bit ## _S, \ 267739Sjchu 0, \ 268739Sjchu PX_ERR_BIT_HANDLE(hdl), \ 269739Sjchu PX_ERPT_SEND(erpt), \ 27027Sjchu PX_ERR_DMC_CLASS(bit) 27127Sjchu px_err_bit_desc_t px_err_mmu_tbl[] = { 27227Sjchu /* DMC MMU TFAR/TFSR - see io erpt doc, section 2.4 */ 27327Sjchu { MMU_BIT_DESC(BYP_ERR, mmu_rbne, mmu_tfar_tfsr) }, 27427Sjchu { MMU_BIT_DESC(BYP_OOR, mmu_tfa, mmu_tfar_tfsr) }, 27527Sjchu { MMU_BIT_DESC(TRN_ERR, mmu_rbne, mmu_tfar_tfsr) }, 27627Sjchu { MMU_BIT_DESC(TRN_OOR, mmu_tfa, mmu_tfar_tfsr) }, 27727Sjchu { MMU_BIT_DESC(TTE_INV, mmu_tfa, mmu_tfar_tfsr) }, 27827Sjchu { MMU_BIT_DESC(TTE_PRT, mmu_tfa, mmu_tfar_tfsr) }, 27927Sjchu { MMU_BIT_DESC(TTC_DPE, mmu_tfa, mmu_tfar_tfsr) }, 28027Sjchu { MMU_BIT_DESC(TBW_DME, mmu_tblwlk, mmu_tfar_tfsr) }, 28127Sjchu { MMU_BIT_DESC(TBW_UDE, mmu_tblwlk, mmu_tfar_tfsr) }, 28227Sjchu { MMU_BIT_DESC(TBW_ERR, mmu_tblwlk, mmu_tfar_tfsr) }, 28327Sjchu { MMU_BIT_DESC(TBW_DPE, mmu_tblwlk, mmu_tfar_tfsr) }, 28427Sjchu 28527Sjchu /* DMC MMU - see io erpt doc, section 2.5 */ 28627Sjchu { MMU_BIT_DESC(TTC_CAE, non_fatal, mmu) } 28727Sjchu }; 28827Sjchu #define px_err_mmu_keys (sizeof (px_err_mmu_tbl)) / (sizeof (px_err_bit_desc_t)) 28927Sjchu 290*1772Sjl139090 29127Sjchu /* 29227Sjchu * PEC error bit tables 29327Sjchu */ 29427Sjchu #define ILU_BIT_DESC(bit, hdl, erpt) \ 29527Sjchu ILU_INTERRUPT_STATUS_ ## bit ## _P, \ 29627Sjchu 0, \ 29727Sjchu PX_ERR_BIT_HANDLE(hdl), \ 29827Sjchu PX_ERPT_SEND(erpt), \ 299739Sjchu PX_ERR_PEC_CLASS(bit) }, \ 300739Sjchu { ILU_INTERRUPT_STATUS_ ## bit ## _S, \ 301739Sjchu 0, \ 302739Sjchu PX_ERR_BIT_HANDLE(hdl), \ 303739Sjchu PX_ERPT_SEND(erpt), \ 30427Sjchu PX_ERR_PEC_CLASS(bit) 30527Sjchu px_err_bit_desc_t px_err_ilu_tbl[] = { 30627Sjchu /* PEC ILU none - see io erpt doc, section 3.1 */ 30727Sjchu { ILU_BIT_DESC(IHB_PE, fatal_gos, pec_ilu) } 30827Sjchu }; 30927Sjchu #define px_err_ilu_keys \ 31027Sjchu (sizeof (px_err_ilu_tbl)) / (sizeof (px_err_bit_desc_t)) 31127Sjchu 31227Sjchu /* 31327Sjchu * PEC UE errors implementation is incomplete pending PCIE generic 314383Set142600 * fabric rules. Must handle both PRIMARY and SECONDARY errors. 31527Sjchu */ 31627Sjchu /* pec ue errors */ 31727Sjchu #define TLU_UC_BIT_DESC(bit, hdl, erpt) \ 31827Sjchu TLU_UNCORRECTABLE_ERROR_STATUS_CLEAR_ ## bit ## _P, \ 31927Sjchu 0, \ 320383Set142600 PX_ERR_BIT_HANDLE(hdl), \ 321383Set142600 PX_ERPT_SEND(erpt), \ 322383Set142600 PX_ERR_PEC_CLASS(bit) }, \ 323383Set142600 { TLU_UNCORRECTABLE_ERROR_STATUS_CLEAR_ ## bit ## _S, \ 324383Set142600 0, \ 325383Set142600 PX_ERR_BIT_HANDLE(hdl), \ 326383Set142600 PX_ERPT_SEND(erpt), \ 327383Set142600 PX_ERR_PEC_CLASS(bit) 328*1772Sjl139090 #define TLU_UC_OB_BIT_DESC(bit, hdl, erpt) \ 329*1772Sjl139090 TLU_UNCORRECTABLE_ERROR_STATUS_CLEAR_ ## bit ## _P, \ 330*1772Sjl139090 0, \ 331*1772Sjl139090 PX_ERR_BIT_HANDLE(hdl), \ 332*1772Sjl139090 PX_ERPT_SEND(erpt), \ 333*1772Sjl139090 PX_ERR_PEC_OB_CLASS(bit) }, \ 334*1772Sjl139090 { TLU_UNCORRECTABLE_ERROR_STATUS_CLEAR_ ## bit ## _S, \ 335*1772Sjl139090 0, \ 336*1772Sjl139090 PX_ERR_BIT_HANDLE(hdl), \ 337*1772Sjl139090 PX_ERPT_SEND(erpt), \ 338*1772Sjl139090 PX_ERR_PEC_CLASS(bit) 33927Sjchu px_err_bit_desc_t px_err_tlu_ue_tbl[] = { 34027Sjchu /* PCI-E Receive Uncorrectable Errors - see io erpt doc, section 3.2 */ 341383Set142600 { TLU_UC_BIT_DESC(UR, pciex_ue, pciex_rx_ue) }, 342383Set142600 { TLU_UC_BIT_DESC(UC, pciex_ue, pciex_rx_ue) }, 34327Sjchu 34427Sjchu /* PCI-E Transmit Uncorrectable Errors - see io erpt doc, section 3.3 */ 345*1772Sjl139090 { TLU_UC_OB_BIT_DESC(ECRC, pciex_ue, pciex_rx_ue) }, 346383Set142600 { TLU_UC_BIT_DESC(CTO, pciex_ue, pciex_tx_ue) }, 347383Set142600 { TLU_UC_BIT_DESC(ROF, pciex_ue, pciex_tx_ue) }, 34827Sjchu 34927Sjchu /* PCI-E Rx/Tx Uncorrectable Errors - see io erpt doc, section 3.4 */ 350383Set142600 { TLU_UC_BIT_DESC(MFP, pciex_ue, pciex_rx_tx_ue) }, 351383Set142600 { TLU_UC_BIT_DESC(PP, pciex_ue, pciex_rx_tx_ue) }, 35227Sjchu 35327Sjchu /* Other PCI-E Uncorrectable Errors - see io erpt doc, section 3.5 */ 354383Set142600 { TLU_UC_BIT_DESC(FCP, pciex_ue, pciex_ue) }, 355383Set142600 { TLU_UC_BIT_DESC(DLP, pciex_ue, pciex_ue) }, 356383Set142600 { TLU_UC_BIT_DESC(TE, pciex_ue, pciex_ue) }, 357383Set142600 358383Set142600 /* Not used */ 359383Set142600 { TLU_UC_BIT_DESC(CA, pciex_ue, do_not) } 36027Sjchu }; 36127Sjchu #define px_err_tlu_ue_keys \ 36227Sjchu (sizeof (px_err_tlu_ue_tbl)) / (sizeof (px_err_bit_desc_t)) 36327Sjchu 364*1772Sjl139090 36527Sjchu /* 36627Sjchu * PEC CE errors implementation is incomplete pending PCIE generic 36727Sjchu * fabric rules. 36827Sjchu */ 36927Sjchu /* pec ce errors */ 37027Sjchu #define TLU_CE_BIT_DESC(bit, hdl, erpt) \ 37127Sjchu TLU_CORRECTABLE_ERROR_STATUS_CLEAR_ ## bit ## _P, \ 37227Sjchu 0, \ 373383Set142600 PX_ERR_BIT_HANDLE(hdl), \ 374383Set142600 PX_ERPT_SEND(erpt), \ 375383Set142600 PX_ERR_PEC_CLASS(bit) }, \ 376383Set142600 { TLU_CORRECTABLE_ERROR_STATUS_CLEAR_ ## bit ## _S, \ 377383Set142600 0, \ 378383Set142600 PX_ERR_BIT_HANDLE(hdl), \ 379383Set142600 PX_ERPT_SEND(erpt), \ 380383Set142600 PX_ERR_PEC_CLASS(bit) 38127Sjchu px_err_bit_desc_t px_err_tlu_ce_tbl[] = { 38227Sjchu /* PCI-E Correctable Errors - see io erpt doc, section 3.6 */ 383383Set142600 { TLU_CE_BIT_DESC(RTO, pciex_ce, pciex_ce) }, 384383Set142600 { TLU_CE_BIT_DESC(RNR, pciex_ce, pciex_ce) }, 385383Set142600 { TLU_CE_BIT_DESC(BDP, pciex_ce, pciex_ce) }, 386383Set142600 { TLU_CE_BIT_DESC(BTP, pciex_ce, pciex_ce) }, 387383Set142600 { TLU_CE_BIT_DESC(RE, pciex_ce, pciex_ce) } 38827Sjchu }; 38927Sjchu #define px_err_tlu_ce_keys \ 39027Sjchu (sizeof (px_err_tlu_ce_tbl)) / (sizeof (px_err_bit_desc_t)) 39127Sjchu 392*1772Sjl139090 39327Sjchu /* pec oe errors */ 39427Sjchu #define TLU_OE_BIT_DESC(bit, hdl, erpt) \ 39527Sjchu TLU_OTHER_EVENT_STATUS_CLEAR_ ## bit ## _P, \ 39627Sjchu 0, \ 39727Sjchu PX_ERR_BIT_HANDLE(hdl), \ 39827Sjchu PX_ERPT_SEND(erpt), \ 399739Sjchu PX_ERR_PEC_CLASS(bit) }, \ 400739Sjchu { TLU_OTHER_EVENT_STATUS_CLEAR_ ## bit ## _S, \ 401739Sjchu 0, \ 402739Sjchu PX_ERR_BIT_HANDLE(hdl), \ 403739Sjchu PX_ERPT_SEND(erpt), \ 40427Sjchu PX_ERR_PEC_CLASS(bit) 405*1772Sjl139090 #define TLU_OE_OB_BIT_DESC(bit, hdl, erpt) \ 406*1772Sjl139090 TLU_OTHER_EVENT_STATUS_CLEAR_ ## bit ## _P, \ 407*1772Sjl139090 0, \ 408*1772Sjl139090 PX_ERR_BIT_HANDLE(hdl), \ 409*1772Sjl139090 PX_ERPT_SEND(erpt), \ 410*1772Sjl139090 PX_ERR_PEC_OB_CLASS(bit) }, \ 411*1772Sjl139090 { TLU_OTHER_EVENT_STATUS_CLEAR_ ## bit ## _S, \ 412*1772Sjl139090 0, \ 413*1772Sjl139090 PX_ERR_BIT_HANDLE(hdl), \ 414*1772Sjl139090 PX_ERPT_SEND(erpt), \ 415*1772Sjl139090 PX_ERR_PEC_OB_CLASS(bit) 41627Sjchu px_err_bit_desc_t px_err_tlu_oe_tbl[] = { 41727Sjchu /* 41827Sjchu * TLU Other Event Status (receive only) - see io erpt doc, section 3.7 41927Sjchu */ 42027Sjchu { TLU_OE_BIT_DESC(MRC, fatal_hw, pciex_rx_oe) }, 42127Sjchu 42227Sjchu /* TLU Other Event Status (rx + tx) - see io erpt doc, section 3.8 */ 423383Set142600 { TLU_OE_BIT_DESC(WUC, non_fatal, pciex_rx_tx_oe) }, 424383Set142600 { TLU_OE_BIT_DESC(RUC, non_fatal, pciex_rx_tx_oe) }, 42527Sjchu { TLU_OE_BIT_DESC(CRS, non_fatal, pciex_rx_tx_oe) }, 42627Sjchu 42727Sjchu /* TLU Other Event - see io erpt doc, section 3.9 */ 42827Sjchu { TLU_OE_BIT_DESC(IIP, fatal_gos, pciex_oe) }, 42927Sjchu { TLU_OE_BIT_DESC(EDP, fatal_gos, pciex_oe) }, 43027Sjchu { TLU_OE_BIT_DESC(EHP, fatal_gos, pciex_oe) }, 431*1772Sjl139090 { TLU_OE_OB_BIT_DESC(TLUEITMO, fatal_gos, pciex_oe) }, 43227Sjchu { TLU_OE_BIT_DESC(LIN, non_fatal, pciex_oe) }, 43327Sjchu { TLU_OE_BIT_DESC(LRS, non_fatal, pciex_oe) }, 4341147Sjchu { TLU_OE_BIT_DESC(LDN, tlu_ldn, pciex_oe) }, 4351147Sjchu { TLU_OE_BIT_DESC(LUP, tlu_lup, pciex_oe) }, 43627Sjchu { TLU_OE_BIT_DESC(ERU, fatal_gos, pciex_oe) }, 43727Sjchu { TLU_OE_BIT_DESC(ERO, fatal_gos, pciex_oe) }, 43827Sjchu { TLU_OE_BIT_DESC(EMP, fatal_gos, pciex_oe) }, 43927Sjchu { TLU_OE_BIT_DESC(EPE, fatal_gos, pciex_oe) }, 44027Sjchu { TLU_OE_BIT_DESC(ERP, fatal_gos, pciex_oe) }, 44127Sjchu { TLU_OE_BIT_DESC(EIP, fatal_gos, pciex_oe) } 44227Sjchu }; 44327Sjchu 44427Sjchu #define px_err_tlu_oe_keys \ 44527Sjchu (sizeof (px_err_tlu_oe_tbl)) / (sizeof (px_err_bit_desc_t)) 44627Sjchu 447*1772Sjl139090 44827Sjchu /* 44927Sjchu * All the following tables below are for LPU Interrupts. These interrupts 45027Sjchu * are *NOT* error interrupts, but event status interrupts. 45127Sjchu * 45227Sjchu * These events are probably of most interest to: 45327Sjchu * o Hotplug 45427Sjchu * o Power Management 45527Sjchu * o etc... 45627Sjchu * 45727Sjchu * There are also a few events that would be interresting for FMA. 45827Sjchu * Again none of the regiseters below state that an error has occured 45927Sjchu * or that data has been lost. If anything, they give status that an 46027Sjchu * error is *about* to occur. examples 46127Sjchu * o INT_SKP_ERR - indicates clock between fire and child is too far 46227Sjchu * off and is most unlikely able to compensate 46327Sjchu * o INT_TX_PAR_ERR - A parity error occured in ONE lane. This is 46427Sjchu * HW recoverable, but will like end up as a future 46527Sjchu * fabric error as well. 46627Sjchu * 46727Sjchu * For now, we don't care about any of these errors and should be ignore, 46827Sjchu * but cleared. 46927Sjchu */ 47027Sjchu 47127Sjchu /* LPU Link Interrupt Table */ 47227Sjchu #define LPUL_BIT_DESC(bit, hdl, erpt) \ 47327Sjchu LPU_LINK_LAYER_INTERRUPT_AND_STATUS_INT_ ## bit, \ 47427Sjchu 0, \ 47527Sjchu NULL, \ 47627Sjchu NULL, \ 47727Sjchu "" 47827Sjchu px_err_bit_desc_t px_err_lpul_tbl[] = { 47927Sjchu { LPUL_BIT_DESC(LINK_ERR_ACT, NULL, NULL) } 48027Sjchu }; 48127Sjchu #define px_err_lpul_keys \ 48227Sjchu (sizeof (px_err_lpul_tbl)) / (sizeof (px_err_bit_desc_t)) 48327Sjchu 48427Sjchu /* LPU Physical Interrupt Table */ 48527Sjchu #define LPUP_BIT_DESC(bit, hdl, erpt) \ 48627Sjchu LPU_PHY_LAYER_INTERRUPT_AND_STATUS_INT_ ## bit, \ 48727Sjchu 0, \ 48827Sjchu NULL, \ 48927Sjchu NULL, \ 49027Sjchu "" 49127Sjchu px_err_bit_desc_t px_err_lpup_tbl[] = { 49227Sjchu { LPUP_BIT_DESC(PHY_LAYER_ERR, NULL, NULL) } 49327Sjchu }; 49427Sjchu #define px_err_lpup_keys \ 49527Sjchu (sizeof (px_err_lpup_tbl)) / (sizeof (px_err_bit_desc_t)) 49627Sjchu 49727Sjchu /* LPU Receive Interrupt Table */ 49827Sjchu #define LPUR_BIT_DESC(bit, hdl, erpt) \ 49927Sjchu LPU_RECEIVE_PHY_INTERRUPT_AND_STATUS_INT_ ## bit, \ 50027Sjchu 0, \ 50127Sjchu NULL, \ 50227Sjchu NULL, \ 50327Sjchu "" 50427Sjchu px_err_bit_desc_t px_err_lpur_tbl[] = { 50527Sjchu { LPUR_BIT_DESC(RCV_PHY, NULL, NULL) } 50627Sjchu }; 50727Sjchu #define px_err_lpur_keys \ 50827Sjchu (sizeof (px_err_lpur_tbl)) / (sizeof (px_err_bit_desc_t)) 50927Sjchu 51027Sjchu /* LPU Transmit Interrupt Table */ 51127Sjchu #define LPUX_BIT_DESC(bit, hdl, erpt) \ 51227Sjchu LPU_TRANSMIT_PHY_INTERRUPT_AND_STATUS_INT_ ## bit, \ 51327Sjchu 0, \ 51427Sjchu NULL, \ 51527Sjchu NULL, \ 51627Sjchu "" 51727Sjchu px_err_bit_desc_t px_err_lpux_tbl[] = { 51827Sjchu { LPUX_BIT_DESC(UNMSK, NULL, NULL) } 51927Sjchu }; 52027Sjchu #define px_err_lpux_keys \ 52127Sjchu (sizeof (px_err_lpux_tbl)) / (sizeof (px_err_bit_desc_t)) 52227Sjchu 52327Sjchu /* LPU LTSSM Interrupt Table */ 52427Sjchu #define LPUS_BIT_DESC(bit, hdl, erpt) \ 52527Sjchu LPU_LTSSM_INTERRUPT_AND_STATUS_INT_ ## bit, \ 52627Sjchu 0, \ 52727Sjchu NULL, \ 52827Sjchu NULL, \ 52927Sjchu "" 53027Sjchu px_err_bit_desc_t px_err_lpus_tbl[] = { 53127Sjchu { LPUS_BIT_DESC(ANY, NULL, NULL) } 53227Sjchu }; 53327Sjchu #define px_err_lpus_keys \ 53427Sjchu (sizeof (px_err_lpus_tbl)) / (sizeof (px_err_bit_desc_t)) 53527Sjchu 53627Sjchu /* LPU Gigablaze Glue Interrupt Table */ 53727Sjchu #define LPUG_BIT_DESC(bit, hdl, erpt) \ 53827Sjchu LPU_GIGABLAZE_GLUE_INTERRUPT_AND_STATUS_INT_ ## bit, \ 53927Sjchu 0, \ 54027Sjchu NULL, \ 54127Sjchu NULL, \ 54227Sjchu "" 54327Sjchu px_err_bit_desc_t px_err_lpug_tbl[] = { 54427Sjchu { LPUG_BIT_DESC(GLOBL_UNMSK, NULL, NULL) } 54527Sjchu }; 54627Sjchu #define px_err_lpug_keys \ 54727Sjchu (sizeof (px_err_lpug_tbl)) / (sizeof (px_err_bit_desc_t)) 54827Sjchu 54927Sjchu 55027Sjchu /* Mask and Tables */ 55127Sjchu #define MnT6(pre) \ 55227Sjchu B_FALSE, \ 55327Sjchu &px_ ## pre ## _intr_mask, \ 55427Sjchu &px_ ## pre ## _log_mask, \ 55527Sjchu &px_ ## pre ## _count_mask, \ 55627Sjchu px_err_ ## pre ## _tbl, \ 55727Sjchu px_err_ ## pre ## _keys, \ 55827Sjchu 0 55927Sjchu 560*1772Sjl139090 #define MnT6_ob(pre) \ 561*1772Sjl139090 B_FALSE, \ 562*1772Sjl139090 &px_ ## pre ## _intr_mask, \ 563*1772Sjl139090 &px_ ## pre ## _log_mask, \ 564*1772Sjl139090 &px_ ## pre ## _count_mask, \ 565*1772Sjl139090 px_err_ ## pre ## _ob_tbl, \ 566*1772Sjl139090 px_err_ ## pre ## _ob_keys, \ 567*1772Sjl139090 0 568*1772Sjl139090 56927Sjchu /* LPU Registers Addresses */ 57027Sjchu #define LR4(pre) \ 57127Sjchu NULL, \ 57227Sjchu LPU_ ## pre ## _INTERRUPT_MASK, \ 57327Sjchu LPU_ ## pre ## _INTERRUPT_AND_STATUS, \ 57427Sjchu LPU_ ## pre ## _INTERRUPT_AND_STATUS 57527Sjchu 57627Sjchu /* LPU Registers Addresses with Irregularities */ 57727Sjchu #define LR4_FIXME(pre) \ 57827Sjchu NULL, \ 57927Sjchu LPU_ ## pre ## _INTERRUPT_MASK, \ 58027Sjchu LPU_ ## pre ## _LAYER_INTERRUPT_AND_STATUS, \ 58127Sjchu LPU_ ## pre ## _LAYER_INTERRUPT_AND_STATUS 58227Sjchu 58327Sjchu /* TLU Registers Addresses */ 58427Sjchu #define TR4(pre) \ 58527Sjchu TLU_ ## pre ## _LOG_ENABLE, \ 58627Sjchu TLU_ ## pre ## _INTERRUPT_ENABLE, \ 58727Sjchu TLU_ ## pre ## _INTERRUPT_STATUS, \ 58827Sjchu TLU_ ## pre ## _STATUS_CLEAR 58927Sjchu 590*1772Sjl139090 /* Registers Addresses for JBC, UBC, MMU, IMU and ILU */ 59127Sjchu #define R4(pre) \ 59227Sjchu pre ## _ERROR_LOG_ENABLE, \ 59327Sjchu pre ## _INTERRUPT_ENABLE, \ 59427Sjchu pre ## _INTERRUPT_STATUS, \ 59527Sjchu pre ## _ERROR_STATUS_CLEAR 59627Sjchu 59727Sjchu /* 59827Sjchu * Register error handling tables. 59927Sjchu * The ID Field (first field) is identified by an enum px_err_id_t. 60027Sjchu * It is located in px_err.h 60127Sjchu */ 60227Sjchu px_err_reg_desc_t px_err_reg_tbl[] = { 603*1772Sjl139090 { MnT6(jbc), R4(JBC), "JBC Error"}, 604*1772Sjl139090 { MnT6(ubc), R4(UBC), "UBC Error"}, 605435Sjchu { MnT6(mmu), R4(MMU), "MMU Error"}, 606435Sjchu { MnT6(imu), R4(IMU), "IMU Error"}, 60727Sjchu { MnT6(tlu_ue), TR4(UNCORRECTABLE_ERROR), "TLU UE"}, 60827Sjchu { MnT6(tlu_ce), TR4(CORRECTABLE_ERROR), "TLU CE"}, 60927Sjchu { MnT6(tlu_oe), TR4(OTHER_EVENT), "TLU OE"}, 610435Sjchu { MnT6(ilu), R4(ILU), "ILU Error"}, 61127Sjchu { MnT6(lpul), LR4(LINK_LAYER), "LPU Link Layer"}, 61227Sjchu { MnT6(lpup), LR4_FIXME(PHY), "LPU Phy Layer"}, 61327Sjchu { MnT6(lpur), LR4(RECEIVE_PHY), "LPU RX Phy Layer"}, 61427Sjchu { MnT6(lpux), LR4(TRANSMIT_PHY), "LPU TX Phy Layer"}, 61527Sjchu { MnT6(lpus), LR4(LTSSM), "LPU LTSSM"}, 616*1772Sjl139090 { MnT6(lpug), LR4(GIGABLAZE_GLUE), "LPU GigaBlaze Glue"}, 61727Sjchu }; 61827Sjchu #define PX_ERR_REG_KEYS (sizeof (px_err_reg_tbl)) / (sizeof (px_err_reg_tbl[0])) 61927Sjchu 62027Sjchu typedef struct px_err_ss { 62127Sjchu uint64_t err_status[PX_ERR_REG_KEYS]; 62227Sjchu } px_err_ss_t; 62327Sjchu 624*1772Sjl139090 static void px_err_snapshot(px_t *px_p, px_err_ss_t *ss, boolean_t chk_cb); 62527Sjchu static int px_err_erpt_and_clr(px_t *px_p, ddi_fm_error_t *derr, 62627Sjchu px_err_ss_t *ss); 62727Sjchu static int px_err_check_severity(px_t *px_p, ddi_fm_error_t *derr, 62827Sjchu int err, int caller); 62927Sjchu 63027Sjchu /* 63127Sjchu * px_err_cb_intr: 632*1772Sjl139090 * Interrupt handler for the JBC/UBC block. 63327Sjchu * o lock 63427Sjchu * o create derr 635*1772Sjl139090 * o px_err_handle(leaf1, with cb) 636*1772Sjl139090 * o px_err_handle(leaf2, without cb) 63727Sjchu * o dispatch (leaf1) 63827Sjchu * o dispatch (leaf2) 63927Sjchu * o unlock 64027Sjchu * o handle error: fatal? fm_panic() : return INTR_CLAIMED) 64127Sjchu */ 64227Sjchu uint_t 64327Sjchu px_err_cb_intr(caddr_t arg) 64427Sjchu { 64527Sjchu px_fault_t *px_fault_p = (px_fault_t *)arg; 64627Sjchu dev_info_t *rpdip = px_fault_p->px_fh_dip; 64727Sjchu px_t *px_p = DIP_TO_STATE(rpdip); 648118Sjchu int err = PX_OK; 649118Sjchu int ret = DDI_FM_OK; 65027Sjchu int fatal = 0; 65127Sjchu ddi_fm_error_t derr; 65227Sjchu 65327Sjchu /* Create the derr */ 65427Sjchu bzero(&derr, sizeof (ddi_fm_error_t)); 65527Sjchu derr.fme_version = DDI_FME_VERSION; 65627Sjchu derr.fme_ena = fm_ena_generate(0, FM_ENA_FMT1); 65727Sjchu derr.fme_flag = DDI_FM_ERR_UNEXPECTED; 65827Sjchu 6591648Sjchu mutex_enter(&px_p->px_fm_mutex); 66027Sjchu 6611648Sjchu err |= px_err_handle(px_p, &derr, PX_INTR_CALL, B_TRUE); 66227Sjchu 6631648Sjchu ret = ndi_fm_handler_dispatch(rpdip, NULL, &derr); 6641648Sjchu switch (ret) { 6651648Sjchu case DDI_FM_FATAL: 6661648Sjchu fatal++; 6671648Sjchu break; 6681648Sjchu case DDI_FM_NONFATAL: 6691648Sjchu case DDI_FM_UNKNOWN: 6701648Sjchu default: 6711648Sjchu break; 67227Sjchu } 67327Sjchu 67427Sjchu /* Set the intr state to idle for the leaf that received the mondo */ 6751648Sjchu 67627Sjchu (void) px_lib_intr_setstate(rpdip, px_fault_p->px_fh_sysino, 67727Sjchu INTR_IDLE_STATE); 67827Sjchu 6791648Sjchu mutex_exit(&px_p->px_fm_mutex); 68027Sjchu 68127Sjchu /* 68227Sjchu * PX_FATAL_HW error is diagnosed after system recovered from 68327Sjchu * HW initiated reset, therefore no furthur handling is required. 68427Sjchu */ 68527Sjchu if (fatal || err & (PX_FATAL_GOS | PX_FATAL_SW)) 686677Sjchu PX_FM_PANIC("Fatal System Bus Error has occurred\n"); 68727Sjchu 68827Sjchu return (DDI_INTR_CLAIMED); 68927Sjchu } 69027Sjchu 69127Sjchu /* 69227Sjchu * px_err_dmc_pec_intr: 69327Sjchu * Interrupt handler for the DMC/PEC block. 69427Sjchu * o lock 69527Sjchu * o create derr 696*1772Sjl139090 * o px_err_handle(leaf, with cb) 69727Sjchu * o dispatch (leaf) 69827Sjchu * o unlock 69927Sjchu * o handle error: fatal? fm_panic() : return INTR_CLAIMED) 70027Sjchu */ 70127Sjchu uint_t 70227Sjchu px_err_dmc_pec_intr(caddr_t arg) 70327Sjchu { 70427Sjchu px_fault_t *px_fault_p = (px_fault_t *)arg; 70527Sjchu dev_info_t *rpdip = px_fault_p->px_fh_dip; 70627Sjchu px_t *px_p = DIP_TO_STATE(rpdip); 707118Sjchu int err = PX_OK; 708118Sjchu int ret = DDI_FM_OK; 70927Sjchu ddi_fm_error_t derr; 71027Sjchu 71127Sjchu /* Create the derr */ 71227Sjchu bzero(&derr, sizeof (ddi_fm_error_t)); 71327Sjchu derr.fme_version = DDI_FME_VERSION; 71427Sjchu derr.fme_ena = fm_ena_generate(0, FM_ENA_FMT1); 71527Sjchu derr.fme_flag = DDI_FM_ERR_UNEXPECTED; 71627Sjchu 7171648Sjchu mutex_enter(&px_p->px_fm_mutex); 71827Sjchu 71927Sjchu /* send ereport/handle/clear fire registers */ 72027Sjchu err |= px_err_handle(px_p, &derr, PX_INTR_CALL, B_TRUE); 72127Sjchu 72227Sjchu /* Check all child devices for errors */ 72327Sjchu ret = ndi_fm_handler_dispatch(rpdip, NULL, &derr); 72427Sjchu 72527Sjchu /* Set the interrupt state to idle */ 72627Sjchu (void) px_lib_intr_setstate(rpdip, px_fault_p->px_fh_sysino, 72727Sjchu INTR_IDLE_STATE); 72827Sjchu 7291648Sjchu mutex_exit(&px_p->px_fm_mutex); 73027Sjchu 73127Sjchu /* 73227Sjchu * PX_FATAL_HW indicates a condition recovered from Fatal-Reset, 73327Sjchu * therefore it does not cause panic. 73427Sjchu */ 73527Sjchu if ((err & (PX_FATAL_GOS | PX_FATAL_SW)) || (ret == DDI_FM_FATAL)) 736677Sjchu PX_FM_PANIC("Fatal System Port Error has occurred\n"); 73727Sjchu 73827Sjchu return (DDI_INTR_CLAIMED); 73927Sjchu } 74027Sjchu 74127Sjchu /* 74227Sjchu * Error register are being handled by px_hlib xxx_init functions. 74327Sjchu * They are also called again by px_err_add_intr for mondo62 and 63 74427Sjchu * from px_cb_attach and px_attach 74527Sjchu */ 74627Sjchu void 74727Sjchu px_err_reg_enable(px_t *px_p, px_err_id_t id) 74827Sjchu { 74927Sjchu px_err_reg_desc_t *reg_desc = &px_err_reg_tbl[id]; 75027Sjchu uint64_t intr_mask = *reg_desc->intr_mask_p; 75127Sjchu uint64_t log_mask = *reg_desc->log_mask_p; 75227Sjchu caddr_t csr_base; 75327Sjchu pxu_t *pxu_p = (pxu_t *)px_p->px_plat_p; 75427Sjchu 755*1772Sjl139090 /* Get the correct CSR BASE */ 756*1772Sjl139090 if (PX_ERR_XBC(id)) 75727Sjchu csr_base = (caddr_t)pxu_p->px_address[PX_REG_XBC]; 75827Sjchu else 75927Sjchu csr_base = (caddr_t)pxu_p->px_address[PX_REG_CSR]; 76027Sjchu 76127Sjchu reg_desc->enabled = B_TRUE; 76227Sjchu 76327Sjchu /* Enable logs if it exists */ 76427Sjchu if (reg_desc->log_addr != NULL) 76527Sjchu CSR_XS(csr_base, reg_desc->log_addr, log_mask); 76627Sjchu 76727Sjchu /* 76827Sjchu * For readability you in code you set 1 to enable an interrupt. 76927Sjchu * But in Fire it's backwards. You set 1 to *disable* an intr. 77027Sjchu * Reverse the user tunable intr mask field. 77127Sjchu * 77227Sjchu * Disable All Errors 77327Sjchu * Clear All Errors 77427Sjchu * Enable Errors 77527Sjchu */ 77627Sjchu CSR_XS(csr_base, reg_desc->enable_addr, 0); 77727Sjchu CSR_XS(csr_base, reg_desc->clear_addr, -1); 77827Sjchu CSR_XS(csr_base, reg_desc->enable_addr, intr_mask); 77927Sjchu DBG(DBG_ATTACH, NULL, "%s Mask: 0x%llx\n", 78027Sjchu reg_desc->msg, CSR_XR(csr_base, reg_desc->enable_addr)); 78127Sjchu DBG(DBG_ATTACH, NULL, "%s Status: 0x%llx\n", 78227Sjchu reg_desc->msg, CSR_XR(csr_base, reg_desc->status_addr)); 78327Sjchu DBG(DBG_ATTACH, NULL, "%s Clear: 0x%llx\n", 78427Sjchu reg_desc->msg, CSR_XR(csr_base, reg_desc->clear_addr)); 78527Sjchu if (reg_desc->log_addr != NULL) { 78627Sjchu DBG(DBG_ATTACH, NULL, "%s Log: 0x%llx\n", 78727Sjchu reg_desc->msg, CSR_XR(csr_base, reg_desc->log_addr)); 78827Sjchu } 78927Sjchu } 79027Sjchu 79127Sjchu void 79227Sjchu px_err_reg_disable(px_t *px_p, px_err_id_t id) 79327Sjchu { 79427Sjchu px_err_reg_desc_t *reg_desc = &px_err_reg_tbl[id]; 79527Sjchu caddr_t csr_base; 796693Sgovinda pxu_t *pxu_p = (pxu_t *)px_p->px_plat_p; 79727Sjchu 798*1772Sjl139090 /* Get the correct CSR BASE */ 799*1772Sjl139090 if (PX_ERR_XBC(id)) 800693Sgovinda csr_base = (caddr_t)(uintptr_t)pxu_p->px_address[PX_REG_XBC]; 80127Sjchu else 802693Sgovinda csr_base = (caddr_t)(uintptr_t)pxu_p->px_address[PX_REG_CSR]; 80327Sjchu 80427Sjchu reg_desc->enabled = B_FALSE; 80527Sjchu 80627Sjchu switch (id) { 80727Sjchu case PX_ERR_JBC: 808*1772Sjl139090 case PX_ERR_UBC: 80927Sjchu case PX_ERR_MMU: 81027Sjchu case PX_ERR_IMU: 81127Sjchu case PX_ERR_TLU_UE: 81227Sjchu case PX_ERR_TLU_CE: 81327Sjchu case PX_ERR_TLU_OE: 81427Sjchu case PX_ERR_ILU: 81527Sjchu if (reg_desc->log_addr != NULL) { 81627Sjchu CSR_XS(csr_base, reg_desc->log_addr, 0); 81727Sjchu } 81827Sjchu CSR_XS(csr_base, reg_desc->enable_addr, 0); 81927Sjchu break; 82027Sjchu case PX_ERR_LPU_LINK: 82127Sjchu case PX_ERR_LPU_PHY: 82227Sjchu case PX_ERR_LPU_RX: 82327Sjchu case PX_ERR_LPU_TX: 82427Sjchu case PX_ERR_LPU_LTSSM: 82527Sjchu case PX_ERR_LPU_GIGABLZ: 82627Sjchu if (reg_desc->log_addr != NULL) { 82727Sjchu CSR_XS(csr_base, reg_desc->log_addr, -1); 82827Sjchu } 82927Sjchu CSR_XS(csr_base, reg_desc->enable_addr, -1); 83027Sjchu break; 83127Sjchu } 83227Sjchu } 83327Sjchu 83427Sjchu /* 83527Sjchu * px_err_handle: 83627Sjchu * Common function called by trap, mondo and fabric intr. 83727Sjchu * o Snap shot current fire registers 83827Sjchu * o check for safe access 83927Sjchu * o send ereport and clear snap shot registers 84027Sjchu * o check severity of snap shot registers 84127Sjchu * 84227Sjchu * @param px_p leaf in which to check access 84327Sjchu * @param derr fm err data structure to be updated 84427Sjchu * @param caller PX_TRAP_CALL | PX_INTR_CALL 845*1772Sjl139090 * @param chk_cb whether to handle cb registers 84627Sjchu * @return err PX_OK | PX_NONFATAL | 84727Sjchu * PX_FATAL_GOS | PX_FATAL_HW | PX_STUCK_FATAL 84827Sjchu */ 84927Sjchu int 85027Sjchu px_err_handle(px_t *px_p, ddi_fm_error_t *derr, int caller, 851*1772Sjl139090 boolean_t chk_cb) 85227Sjchu { 85327Sjchu px_err_ss_t ss; 854118Sjchu int err = PX_OK; 85527Sjchu 8561648Sjchu ASSERT(MUTEX_HELD(&px_p->px_fm_mutex)); 85727Sjchu 85827Sjchu /* snap shot the current fire registers */ 859*1772Sjl139090 px_err_snapshot(px_p, &ss, chk_cb); 86027Sjchu 86127Sjchu /* check for safe access */ 86227Sjchu px_err_safeacc_check(px_p, derr); 86327Sjchu 86427Sjchu /* send ereports/handle/clear registers */ 86527Sjchu err = px_err_erpt_and_clr(px_p, derr, &ss); 86627Sjchu 86727Sjchu /* check for error severity */ 86827Sjchu err = px_err_check_severity(px_p, derr, err, caller); 86927Sjchu 87027Sjchu /* Mark the On Trap Handle if an error occured */ 87127Sjchu if (err != PX_OK) { 87227Sjchu px_pec_t *pec_p = px_p->px_pec_p; 87327Sjchu on_trap_data_t *otd = pec_p->pec_ontrap_data; 87427Sjchu 875118Sjchu if ((otd != NULL) && (otd->ot_prot & OT_DATA_ACCESS)) 87627Sjchu otd->ot_trap |= OT_DATA_ACCESS; 87727Sjchu } 87827Sjchu 87927Sjchu return (err); 88027Sjchu } 88127Sjchu 88227Sjchu /* 88327Sjchu * Static function 88427Sjchu */ 88527Sjchu 88627Sjchu /* 88727Sjchu * px_err_snapshot: 88827Sjchu * Take a current snap shot of all the fire error registers. This includes 889*1772Sjl139090 * JBC/UBC, DMC, and PEC, unless chk_cb == false; 89027Sjchu * 89127Sjchu * @param px_p leaf in which to take the snap shot. 89227Sjchu * @param ss pre-allocated memory to store the snap shot. 893*1772Sjl139090 * @param chk_cb boolean on whether to store jbc/ubc register. 89427Sjchu */ 89527Sjchu static void 896*1772Sjl139090 px_err_snapshot(px_t *px_p, px_err_ss_t *ss, boolean_t chk_cb) 89727Sjchu { 89827Sjchu pxu_t *pxu_p = (pxu_t *)px_p->px_plat_p; 89927Sjchu caddr_t xbc_csr_base = (caddr_t)pxu_p->px_address[PX_REG_XBC]; 90027Sjchu caddr_t pec_csr_base = (caddr_t)pxu_p->px_address[PX_REG_CSR]; 90127Sjchu px_err_reg_desc_t *reg_desc; 90227Sjchu int reg_id; 90327Sjchu 904*1772Sjl139090 switch (PX_CHIP_TYPE(pxu_p)) { 905*1772Sjl139090 case PX_CHIP_OBERON: 906*1772Sjl139090 reg_id = PX_ERR_UBC; 907*1772Sjl139090 break; 908*1772Sjl139090 case PX_CHIP_FIRE: 909*1772Sjl139090 reg_id = PX_ERR_JBC; 910*1772Sjl139090 break; 911*1772Sjl139090 default: 912*1772Sjl139090 DBG(DBG_ERR_INTR, NULL, "px_err_snapshot - " 913*1772Sjl139090 "unknown chip type: 0x%x\n", PX_CHIP_TYPE(pxu_p)); 914*1772Sjl139090 reg_id = 0; 915*1772Sjl139090 break; 916*1772Sjl139090 } 917*1772Sjl139090 918*1772Sjl139090 /* snapshot CB interrupt status */ 919*1772Sjl139090 if (chk_cb == B_TRUE) { 92027Sjchu reg_desc = &px_err_reg_tbl[reg_id]; 921*1772Sjl139090 /* Only look at enabled groups. */ 922*1772Sjl139090 if (reg_desc->enabled == B_TRUE) { 923*1772Sjl139090 ss->err_status[reg_id] = CSR_XR(xbc_csr_base, 924*1772Sjl139090 reg_desc->status_addr); 925*1772Sjl139090 } 92627Sjchu } else { 92727Sjchu ss->err_status[reg_id] = 0; 92827Sjchu } 92927Sjchu 93027Sjchu /* snapshot DMC/PEC interrupt status */ 931*1772Sjl139090 for (reg_id = 2; reg_id < PX_ERR_REG_KEYS; reg_id += 1) { 93227Sjchu reg_desc = &px_err_reg_tbl[reg_id]; 933*1772Sjl139090 /* Only look at enabled groups. */ 934*1772Sjl139090 if (reg_desc->enabled == B_TRUE) { 935*1772Sjl139090 ss->err_status[reg_id] = CSR_XR(pec_csr_base, 936*1772Sjl139090 reg_desc->status_addr); 937*1772Sjl139090 } 93827Sjchu } 93927Sjchu } 94027Sjchu 94127Sjchu /* 94227Sjchu * px_err_erpt_and_clr: 94327Sjchu * This function does the following thing to all the fire registers based 94427Sjchu * on an earlier snap shot. 94527Sjchu * o Send ereport 94627Sjchu * o Handle the error 94727Sjchu * o Clear the error 94827Sjchu * 94927Sjchu * @param px_p leaf in which to take the snap shot. 95027Sjchu * @param derr fm err in which the ereport is to be based on 95127Sjchu * @param ss pre-allocated memory to store the snap shot. 95227Sjchu */ 95327Sjchu static int 95427Sjchu px_err_erpt_and_clr(px_t *px_p, ddi_fm_error_t *derr, px_err_ss_t *ss) 95527Sjchu { 95627Sjchu dev_info_t *rpdip = px_p->px_dip; 95727Sjchu pxu_t *pxu_p = (pxu_t *)px_p->px_plat_p; 95827Sjchu caddr_t csr_base; 95927Sjchu px_err_reg_desc_t *err_reg_tbl; 96027Sjchu px_err_bit_desc_t *err_bit_tbl; 96127Sjchu px_err_bit_desc_t *err_bit_desc; 96227Sjchu 96327Sjchu uint64_t *log_mask, *count_mask; 96427Sjchu uint64_t status_addr, clear_addr; 96527Sjchu uint64_t ss_reg; 96627Sjchu 96727Sjchu int (*err_handler)(); 96827Sjchu int (*erpt_handler)(); 96927Sjchu int reg_id, key; 97027Sjchu int err = PX_OK; 9711147Sjchu int biterr; 97227Sjchu 9731648Sjchu ASSERT(MUTEX_HELD(&px_p->px_fm_mutex)); 97427Sjchu 97527Sjchu /* send erport/handle/clear JBC errors */ 97627Sjchu for (reg_id = 0; reg_id < PX_ERR_REG_KEYS; reg_id += 1) { 97727Sjchu /* Get the correct register description table */ 97827Sjchu err_reg_tbl = &px_err_reg_tbl[reg_id]; 97927Sjchu 980*1772Sjl139090 /* Only look at enabled groups. */ 981*1772Sjl139090 if (err_reg_tbl->enabled != B_TRUE) 982*1772Sjl139090 continue; 983*1772Sjl139090 98427Sjchu /* Get the correct CSR BASE */ 985*1772Sjl139090 if (PX_ERR_XBC(reg_id)) 98627Sjchu csr_base = (caddr_t)pxu_p->px_address[PX_REG_XBC]; 987*1772Sjl139090 else 98827Sjchu csr_base = (caddr_t)pxu_p->px_address[PX_REG_CSR]; 98927Sjchu 99027Sjchu /* Get pointers to masks and register addresses */ 99127Sjchu log_mask = err_reg_tbl->log_mask_p; 99227Sjchu count_mask = err_reg_tbl->count_mask_p; 99327Sjchu status_addr = err_reg_tbl->status_addr; 99427Sjchu clear_addr = err_reg_tbl->clear_addr; 99527Sjchu ss_reg = ss->err_status[reg_id]; 99627Sjchu 99727Sjchu /* Get the register BIT description table */ 99827Sjchu err_bit_tbl = err_reg_tbl->err_bit_tbl; 99927Sjchu 100027Sjchu /* For each known bit in the register send erpt and handle */ 100127Sjchu for (key = 0; key < err_reg_tbl->err_bit_keys; key += 1) { 100227Sjchu /* Get the bit description table for this register */ 100327Sjchu err_bit_desc = &err_bit_tbl[key]; 100427Sjchu 100527Sjchu /* 100627Sjchu * If the ss_reg is set for this bit, 100727Sjchu * send ereport and handle 100827Sjchu */ 100927Sjchu if (BIT_TST(ss_reg, err_bit_desc->bit)) { 101027Sjchu /* Increment the counter if necessary */ 101127Sjchu if (BIT_TST(*count_mask, err_bit_desc->bit)) { 101227Sjchu err_bit_desc->counter++; 101327Sjchu } 101427Sjchu 101527Sjchu /* Error Handle for this bit */ 101627Sjchu err_handler = err_bit_desc->err_handler; 10171147Sjchu if (err_handler) { 10181147Sjchu biterr = err_handler(rpdip, 101927Sjchu csr_base, 102027Sjchu derr, 102127Sjchu err_reg_tbl, 102227Sjchu err_bit_desc); 10231147Sjchu err |= biterr; 10241147Sjchu } 102527Sjchu 1026383Set142600 /* Send the ereport if it's an UNEXPECTED err */ 102727Sjchu erpt_handler = err_bit_desc->erpt_handler; 10281147Sjchu if ((derr->fme_flag == DDI_FM_ERR_UNEXPECTED) && 10291147Sjchu (biterr != PX_OK)) { 1030383Set142600 if (erpt_handler) 1031383Set142600 (void) erpt_handler(rpdip, 1032383Set142600 csr_base, 1033383Set142600 ss_reg, 1034383Set142600 derr, 1035739Sjchu err_bit_desc->bit, 1036383Set142600 err_bit_desc->class_name); 1037383Set142600 } 103827Sjchu } 103927Sjchu } 1040332Sjchu /* Print register status */ 1041332Sjchu if (ss_reg & *log_mask) 1042332Sjchu DBG(DBG_ERR_INTR, rpdip, "<%x>=%16llx %s\n", 104327Sjchu status_addr, ss_reg, err_reg_tbl->msg); 104427Sjchu 104527Sjchu /* Clear the register and error */ 104627Sjchu CSR_XS(csr_base, clear_addr, ss_reg); 104727Sjchu } 104827Sjchu 104927Sjchu return (err); 105027Sjchu } 105127Sjchu 105227Sjchu /* 105327Sjchu * px_err_check_severity: 105427Sjchu * Check the severity of the fire error based on an earlier snapshot 105527Sjchu * 105627Sjchu * @param px_p leaf in which to take the snap shot. 105727Sjchu * @param derr fm err in which the ereport is to be based on 105827Sjchu * @param ss pre-allocated memory to store the snap shot. 105927Sjchu */ 106027Sjchu static int 106127Sjchu px_err_check_severity(px_t *px_p, ddi_fm_error_t *derr, int err, int caller) 106227Sjchu { 106327Sjchu px_pec_t *pec_p = px_p->px_pec_p; 106427Sjchu boolean_t is_safeacc = B_FALSE; 1065118Sjchu 1066118Sjchu /* nothing to do if called with no error */ 1067118Sjchu if (err == PX_OK) 1068118Sjchu return (err); 106927Sjchu 107027Sjchu /* Cautious access error handling */ 107127Sjchu switch (derr->fme_flag) { 107227Sjchu case DDI_FM_ERR_EXPECTED: 107327Sjchu if (caller == PX_TRAP_CALL) { 107427Sjchu /* 107527Sjchu * for ddi_caut_get treat all events as nonfatal 107627Sjchu * The trampoline will set err_ena = 0, 107727Sjchu * err_status = NONFATAL. 107827Sjchu */ 107927Sjchu derr->fme_status = DDI_FM_NONFATAL; 108027Sjchu is_safeacc = B_TRUE; 108127Sjchu } else { 108227Sjchu /* 108327Sjchu * For ddi_caut_put treat all events as nonfatal. Here 108427Sjchu * we have the handle and can call ndi_fm_acc_err_set(). 108527Sjchu */ 108627Sjchu derr->fme_status = DDI_FM_NONFATAL; 108727Sjchu ndi_fm_acc_err_set(pec_p->pec_acc_hdl, derr); 108827Sjchu is_safeacc = B_TRUE; 108927Sjchu } 109027Sjchu break; 109127Sjchu case DDI_FM_ERR_PEEK: 109227Sjchu case DDI_FM_ERR_POKE: 109327Sjchu /* 109427Sjchu * For ddi_peek/poke treat all events as nonfatal. 109527Sjchu */ 109627Sjchu is_safeacc = B_TRUE; 109727Sjchu break; 109827Sjchu default: 109927Sjchu is_safeacc = B_FALSE; 110027Sjchu } 110127Sjchu 110227Sjchu /* 110327Sjchu * The third argument "err" is passed in as error status from checking 110427Sjchu * Fire register, re-adjust error status from safe access. 110527Sjchu */ 110627Sjchu if (is_safeacc && !(err & PX_FATAL_GOS)) 1107118Sjchu return (PX_NONFATAL); 110827Sjchu 1109118Sjchu return (err); 111027Sjchu } 111127Sjchu 111227Sjchu /* predefined convenience functions */ 111327Sjchu /* ARGSUSED */ 111427Sjchu int 111527Sjchu px_err_fatal_hw_handle(dev_info_t *rpdip, caddr_t csr_base, 111627Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 111727Sjchu px_err_bit_desc_t *err_bit_descr) 111827Sjchu { 111927Sjchu return (PX_FATAL_HW); 112027Sjchu } 112127Sjchu 112227Sjchu /* ARGSUSED */ 112327Sjchu int 112427Sjchu px_err_fatal_gos_handle(dev_info_t *rpdip, caddr_t csr_base, 112527Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 112627Sjchu px_err_bit_desc_t *err_bit_descr) 112727Sjchu { 112827Sjchu return (PX_FATAL_GOS); 112927Sjchu } 113027Sjchu 113127Sjchu /* ARGSUSED */ 113227Sjchu int 113327Sjchu px_err_fatal_stuck_handle(dev_info_t *rpdip, caddr_t csr_base, 113427Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 113527Sjchu px_err_bit_desc_t *err_bit_descr) 113627Sjchu { 113727Sjchu return (PX_STUCK_FATAL); 113827Sjchu } 113927Sjchu 114027Sjchu /* ARGSUSED */ 114127Sjchu int 114227Sjchu px_err_fatal_sw_handle(dev_info_t *rpdip, caddr_t csr_base, 114327Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 114427Sjchu px_err_bit_desc_t *err_bit_descr) 114527Sjchu { 114627Sjchu return (PX_FATAL_SW); 114727Sjchu } 114827Sjchu 114927Sjchu /* ARGSUSED */ 115027Sjchu int 115127Sjchu px_err_non_fatal_handle(dev_info_t *rpdip, caddr_t csr_base, 115227Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 115327Sjchu px_err_bit_desc_t *err_bit_descr) 115427Sjchu { 115527Sjchu return (PX_NONFATAL); 115627Sjchu } 115727Sjchu 115827Sjchu /* ARGSUSED */ 115927Sjchu int 116027Sjchu px_err_ok_handle(dev_info_t *rpdip, caddr_t csr_base, ddi_fm_error_t *derr, 116127Sjchu px_err_reg_desc_t *err_reg_descr, px_err_bit_desc_t *err_bit_descr) 116227Sjchu { 116327Sjchu return (PX_OK); 116427Sjchu } 116527Sjchu 116627Sjchu /* ARGSUSED */ 116727Sjchu int 116827Sjchu px_err_unknown_handle(dev_info_t *rpdip, caddr_t csr_base, ddi_fm_error_t *derr, 116927Sjchu px_err_reg_desc_t *err_reg_descr, px_err_bit_desc_t *err_bit_descr) 117027Sjchu { 117127Sjchu return (PX_ERR_UNKNOWN); 117227Sjchu } 117327Sjchu 1174383Set142600 /* ARGSUSED */ 1175383Set142600 PX_ERPT_SEND_DEC(do_not) 1176383Set142600 { 1177383Set142600 return (PX_OK); 1178383Set142600 } 1179383Set142600 1180*1772Sjl139090 /* UBC FATAL - see io erpt doc, section 1.1 */ 1181*1772Sjl139090 /* ARGSUSED */ 1182*1772Sjl139090 PX_ERPT_SEND_DEC(ubc_fatal) 1183*1772Sjl139090 { 1184*1772Sjl139090 char buf[FM_MAX_CLASS]; 1185*1772Sjl139090 uint64_t memory_ue_log, marked; 1186*1772Sjl139090 char unum[FM_MAX_CLASS]; 1187*1772Sjl139090 int unum_length; 1188*1772Sjl139090 uint64_t device_id = 0; 1189*1772Sjl139090 uint8_t cpu_version = 0; 1190*1772Sjl139090 nvlist_t *resource = NULL; 1191*1772Sjl139090 1192*1772Sjl139090 unum[0] = '\0'; 1193*1772Sjl139090 (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 1194*1772Sjl139090 1195*1772Sjl139090 memory_ue_log = CSR_XR(csr_base, UBC_MEMORY_UE_LOG); 1196*1772Sjl139090 marked = (memory_ue_log >> UBC_MEMORY_UE_LOG_MARKED) & 1197*1772Sjl139090 UBC_MEMORY_UE_LOG_MARKED_MASK; 1198*1772Sjl139090 1199*1772Sjl139090 if ((strstr(class_name, "ubc.piowtue") != NULL) || 1200*1772Sjl139090 (strstr(class_name, "ubc.piowbeue") != NULL) || 1201*1772Sjl139090 (strstr(class_name, "ubc.piorbeue") != NULL) || 1202*1772Sjl139090 (strstr(class_name, "ubc.dmarduea") != NULL) || 1203*1772Sjl139090 (strstr(class_name, "ubc.dmardueb") != NULL)) { 1204*1772Sjl139090 int eid = (memory_ue_log >> UBC_MEMORY_UE_LOG_EID) & 1205*1772Sjl139090 UBC_MEMORY_UE_LOG_EID_MASK; 1206*1772Sjl139090 (void) strncat(buf, ubc_class_eid_qualifier[eid], 1207*1772Sjl139090 FM_MAX_CLASS); 1208*1772Sjl139090 1209*1772Sjl139090 if (eid == UBC_EID_MEM) { 1210*1772Sjl139090 uint64_t phys_addr = memory_ue_log & 1211*1772Sjl139090 MMU_OBERON_PADDR_MASK; 1212*1772Sjl139090 uint64_t offset = (uint64_t)-1; 1213*1772Sjl139090 1214*1772Sjl139090 resource = fm_nvlist_create(NULL); 1215*1772Sjl139090 if (&plat_get_mem_unum) { 1216*1772Sjl139090 if ((plat_get_mem_unum(0, 1217*1772Sjl139090 phys_addr, 0, B_TRUE, 0, unum, 1218*1772Sjl139090 FM_MAX_CLASS, &unum_length)) != 0) 1219*1772Sjl139090 unum[0] = '\0'; 1220*1772Sjl139090 } 1221*1772Sjl139090 fm_fmri_mem_set(resource, FM_MEM_SCHEME_VERSION, 1222*1772Sjl139090 NULL, unum, NULL, offset); 1223*1772Sjl139090 1224*1772Sjl139090 } else if (eid == UBC_EID_CPU) { 1225*1772Sjl139090 int cpuid = (marked & UBC_MARKED_MAX_CPUID_MASK); 1226*1772Sjl139090 char sbuf[21]; /* sizeof (UINT64_MAX) + '\0' */ 1227*1772Sjl139090 1228*1772Sjl139090 resource = fm_nvlist_create(NULL); 1229*1772Sjl139090 cpu_version = cpunodes[cpuid].version; 1230*1772Sjl139090 device_id = cpunodes[cpuid].device_id; 1231*1772Sjl139090 (void) snprintf(sbuf, sizeof (sbuf), "%lX", 1232*1772Sjl139090 device_id); 1233*1772Sjl139090 (void) fm_fmri_cpu_set(resource, 1234*1772Sjl139090 FM_CPU_SCHEME_VERSION, NULL, cpuid, 1235*1772Sjl139090 &cpu_version, sbuf); 1236*1772Sjl139090 } 1237*1772Sjl139090 } 1238*1772Sjl139090 1239*1772Sjl139090 if (resource) { 1240*1772Sjl139090 ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 1241*1772Sjl139090 DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 1242*1772Sjl139090 FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, B_TRUE, 1243*1772Sjl139090 OBERON_UBC_ELE, DATA_TYPE_UINT64, 1244*1772Sjl139090 CSR_XR(csr_base, UBC_ERROR_LOG_ENABLE), 1245*1772Sjl139090 OBERON_UBC_IE, DATA_TYPE_UINT64, 1246*1772Sjl139090 CSR_XR(csr_base, UBC_INTERRUPT_ENABLE), 1247*1772Sjl139090 OBERON_UBC_IS, DATA_TYPE_UINT64, 1248*1772Sjl139090 CSR_XR(csr_base, UBC_INTERRUPT_STATUS), 1249*1772Sjl139090 OBERON_UBC_ESS, DATA_TYPE_UINT64, 1250*1772Sjl139090 CSR_XR(csr_base, UBC_ERROR_STATUS_SET), 1251*1772Sjl139090 OBERON_UBC_MUE, DATA_TYPE_UINT64, memory_ue_log, 1252*1772Sjl139090 OBERON_UBC_UNUM, DATA_TYPE_STRING, unum, 1253*1772Sjl139090 OBERON_UBC_DID, DATA_TYPE_UINT64, device_id, 1254*1772Sjl139090 OBERON_UBC_CPUV, DATA_TYPE_UINT32, cpu_version, 1255*1772Sjl139090 OBERON_UBC_RESOURCE, DATA_TYPE_NVLIST, resource, 1256*1772Sjl139090 NULL); 1257*1772Sjl139090 fm_nvlist_destroy(resource, FM_NVA_FREE); 1258*1772Sjl139090 } else { 1259*1772Sjl139090 ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 1260*1772Sjl139090 DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 1261*1772Sjl139090 FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, B_TRUE, 1262*1772Sjl139090 OBERON_UBC_ELE, DATA_TYPE_UINT64, 1263*1772Sjl139090 CSR_XR(csr_base, UBC_ERROR_LOG_ENABLE), 1264*1772Sjl139090 OBERON_UBC_IE, DATA_TYPE_UINT64, 1265*1772Sjl139090 CSR_XR(csr_base, UBC_INTERRUPT_ENABLE), 1266*1772Sjl139090 OBERON_UBC_IS, DATA_TYPE_UINT64, 1267*1772Sjl139090 CSR_XR(csr_base, UBC_INTERRUPT_STATUS), 1268*1772Sjl139090 OBERON_UBC_ESS, DATA_TYPE_UINT64, 1269*1772Sjl139090 CSR_XR(csr_base, UBC_ERROR_STATUS_SET), 1270*1772Sjl139090 OBERON_UBC_MUE, DATA_TYPE_UINT64, memory_ue_log, 1271*1772Sjl139090 OBERON_UBC_UNUM, DATA_TYPE_STRING, unum, 1272*1772Sjl139090 OBERON_UBC_DID, DATA_TYPE_UINT64, device_id, 1273*1772Sjl139090 OBERON_UBC_CPUV, DATA_TYPE_UINT32, cpu_version, 1274*1772Sjl139090 NULL); 1275*1772Sjl139090 } 1276*1772Sjl139090 1277*1772Sjl139090 return (PX_OK); 1278*1772Sjl139090 } 1279383Set142600 128027Sjchu /* JBC FATAL - see io erpt doc, section 1.1 */ 128127Sjchu PX_ERPT_SEND_DEC(jbc_fatal) 128227Sjchu { 128327Sjchu char buf[FM_MAX_CLASS]; 1284739Sjchu boolean_t pri = PX_ERR_IS_PRI(bit); 128527Sjchu 128627Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 128727Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 128827Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 1289739Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri, 129027Sjchu FIRE_JBC_ELE, DATA_TYPE_UINT64, 129127Sjchu CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE), 129227Sjchu FIRE_JBC_IE, DATA_TYPE_UINT64, 129327Sjchu CSR_XR(csr_base, JBC_INTERRUPT_ENABLE), 129427Sjchu FIRE_JBC_IS, DATA_TYPE_UINT64, 129527Sjchu ss_reg, 129627Sjchu FIRE_JBC_ESS, DATA_TYPE_UINT64, 129727Sjchu CSR_XR(csr_base, JBC_ERROR_STATUS_SET), 129827Sjchu FIRE_JBC_FEL1, DATA_TYPE_UINT64, 129927Sjchu CSR_XR(csr_base, FATAL_ERROR_LOG_1), 130027Sjchu FIRE_JBC_FEL2, DATA_TYPE_UINT64, 130127Sjchu CSR_XR(csr_base, FATAL_ERROR_LOG_2), 130227Sjchu NULL); 130327Sjchu 130427Sjchu return (PX_OK); 130527Sjchu } 130627Sjchu 130727Sjchu /* JBC MERGE - see io erpt doc, section 1.2 */ 130827Sjchu PX_ERPT_SEND_DEC(jbc_merge) 130927Sjchu { 131027Sjchu char buf[FM_MAX_CLASS]; 1311739Sjchu boolean_t pri = PX_ERR_IS_PRI(bit); 131227Sjchu 131327Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 131427Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 131527Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 1316739Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri, 131727Sjchu FIRE_JBC_ELE, DATA_TYPE_UINT64, 131827Sjchu CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE), 131927Sjchu FIRE_JBC_IE, DATA_TYPE_UINT64, 132027Sjchu CSR_XR(csr_base, JBC_INTERRUPT_ENABLE), 132127Sjchu FIRE_JBC_IS, DATA_TYPE_UINT64, 132227Sjchu ss_reg, 132327Sjchu FIRE_JBC_ESS, DATA_TYPE_UINT64, 132427Sjchu CSR_XR(csr_base, JBC_ERROR_STATUS_SET), 132527Sjchu FIRE_JBC_MTEL, DATA_TYPE_UINT64, 132627Sjchu CSR_XR(csr_base, MERGE_TRANSACTION_ERROR_LOG), 132727Sjchu NULL); 132827Sjchu 132927Sjchu return (PX_OK); 133027Sjchu } 133127Sjchu 133227Sjchu /* 133327Sjchu * JBC Merge buffer nonfatal errors: 133427Sjchu * Merge buffer parity error (rd_buf): dma:read:M:nonfatal 133527Sjchu * Merge buffer parity error (wr_buf): dma:write:M:nonfatal 133627Sjchu */ 133727Sjchu /* ARGSUSED */ 133827Sjchu int 133927Sjchu px_err_jbc_merge_handle(dev_info_t *rpdip, caddr_t csr_base, 134027Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 134127Sjchu px_err_bit_desc_t *err_bit_descr) 134227Sjchu { 1343739Sjchu boolean_t pri = PX_ERR_IS_PRI(err_bit_descr->bit); 134427Sjchu uint64_t paddr; 134527Sjchu int ret; 134627Sjchu 1347739Sjchu if (!pri) 1348739Sjchu return (PX_FATAL_GOS); 1349739Sjchu 135027Sjchu paddr = CSR_XR(csr_base, MERGE_TRANSACTION_ERROR_LOG); 135127Sjchu paddr &= MERGE_TRANSACTION_ERROR_LOG_ADDRESS_MASK; 135227Sjchu 135327Sjchu ret = px_handle_lookup( 135427Sjchu rpdip, DMA_HANDLE, derr->fme_ena, (void *)paddr); 135527Sjchu 135627Sjchu return ((ret == DDI_FM_FATAL) ? PX_FATAL_GOS : PX_NONFATAL); 135727Sjchu } 135827Sjchu 135927Sjchu /* JBC Jbusint IN - see io erpt doc, section 1.3 */ 136027Sjchu PX_ERPT_SEND_DEC(jbc_in) 136127Sjchu { 136227Sjchu char buf[FM_MAX_CLASS]; 1363739Sjchu boolean_t pri = PX_ERR_IS_PRI(bit); 136427Sjchu 136527Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 136627Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 136727Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 1368739Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri, 136927Sjchu FIRE_JBC_ELE, DATA_TYPE_UINT64, 137027Sjchu CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE), 137127Sjchu FIRE_JBC_IE, DATA_TYPE_UINT64, 137227Sjchu CSR_XR(csr_base, JBC_INTERRUPT_ENABLE), 137327Sjchu FIRE_JBC_IS, DATA_TYPE_UINT64, 137427Sjchu ss_reg, 137527Sjchu FIRE_JBC_ESS, DATA_TYPE_UINT64, 137627Sjchu CSR_XR(csr_base, JBC_ERROR_STATUS_SET), 137727Sjchu FIRE_JBC_JITEL1, DATA_TYPE_UINT64, 137827Sjchu CSR_XR(csr_base, JBCINT_IN_TRANSACTION_ERROR_LOG), 137927Sjchu FIRE_JBC_JITEL2, DATA_TYPE_UINT64, 138027Sjchu CSR_XR(csr_base, JBCINT_IN_TRANSACTION_ERROR_LOG_2), 138127Sjchu NULL); 138227Sjchu 138327Sjchu return (PX_OK); 138427Sjchu } 138527Sjchu 138627Sjchu /* 138727Sjchu * JBC Jbusint IN nonfatal errors: PA logged in Jbusint In Transaction Error 138827Sjchu * Log Reg[42:0]. 138927Sjchu * CE async fault error: nonfatal 139027Sjchu * Jbus bus error: dma::nonfatal 139127Sjchu * Jbus unmapped error: pio|dma:rdwr:M:nonfatal 139227Sjchu * Write data parity error: pio/write:M:nonfatal 139327Sjchu * Read data parity error: pio/read:M:nonfatal 139427Sjchu * Illegal NCWR bytemask: pio:write:M:nonfatal 139527Sjchu * Illegal NCRD bytemask: pio:write:M:nonfatal 139627Sjchu * Invalid jbus transaction: nonfatal 139727Sjchu */ 139827Sjchu /* ARGSUSED */ 139927Sjchu int 140027Sjchu px_err_jbc_jbusint_in_handle(dev_info_t *rpdip, caddr_t csr_base, 140127Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 140227Sjchu px_err_bit_desc_t *err_bit_descr) 140327Sjchu { 1404739Sjchu boolean_t pri = PX_ERR_IS_PRI(err_bit_descr->bit); 140527Sjchu uint64_t paddr; 140627Sjchu int ret; 140727Sjchu 1408739Sjchu if (!pri) 1409739Sjchu return (PX_FATAL_GOS); 1410739Sjchu 141127Sjchu paddr = CSR_XR(csr_base, JBCINT_IN_TRANSACTION_ERROR_LOG); 141227Sjchu paddr &= JBCINT_IN_TRANSACTION_ERROR_LOG_ADDRESS_MASK; 141327Sjchu 141427Sjchu ret = px_handle_lookup( 141527Sjchu rpdip, DMA_HANDLE, derr->fme_ena, (void *)paddr); 141627Sjchu 141727Sjchu return ((ret == DDI_FM_FATAL) ? PX_FATAL_GOS : PX_NONFATAL); 141827Sjchu } 141927Sjchu 142027Sjchu 142127Sjchu /* JBC Jbusint Out - see io erpt doc, section 1.4 */ 142227Sjchu PX_ERPT_SEND_DEC(jbc_out) 142327Sjchu { 142427Sjchu char buf[FM_MAX_CLASS]; 1425739Sjchu boolean_t pri = PX_ERR_IS_PRI(bit); 142627Sjchu 142727Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 142827Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 142927Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 1430739Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri, 143127Sjchu FIRE_JBC_ELE, DATA_TYPE_UINT64, 143227Sjchu CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE), 143327Sjchu FIRE_JBC_IE, DATA_TYPE_UINT64, 143427Sjchu CSR_XR(csr_base, JBC_INTERRUPT_ENABLE), 143527Sjchu FIRE_JBC_IS, DATA_TYPE_UINT64, 143627Sjchu ss_reg, 143727Sjchu FIRE_JBC_ESS, DATA_TYPE_UINT64, 143827Sjchu CSR_XR(csr_base, JBC_ERROR_STATUS_SET), 143927Sjchu FIRE_JBC_JOTEL1, DATA_TYPE_UINT64, 144027Sjchu CSR_XR(csr_base, JBCINT_OUT_TRANSACTION_ERROR_LOG), 144127Sjchu FIRE_JBC_JOTEL2, DATA_TYPE_UINT64, 144227Sjchu CSR_XR(csr_base, JBCINT_OUT_TRANSACTION_ERROR_LOG_2), 144327Sjchu NULL); 144427Sjchu 144527Sjchu return (PX_OK); 144627Sjchu } 144727Sjchu 144827Sjchu /* JBC Dmcint ODCD - see io erpt doc, section 1.5 */ 144927Sjchu PX_ERPT_SEND_DEC(jbc_odcd) 145027Sjchu { 145127Sjchu char buf[FM_MAX_CLASS]; 1452739Sjchu boolean_t pri = PX_ERR_IS_PRI(bit); 145327Sjchu 145427Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 145527Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 145627Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 1457739Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri, 145827Sjchu FIRE_JBC_ELE, DATA_TYPE_UINT64, 145927Sjchu CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE), 146027Sjchu FIRE_JBC_IE, DATA_TYPE_UINT64, 146127Sjchu CSR_XR(csr_base, JBC_INTERRUPT_ENABLE), 146227Sjchu FIRE_JBC_IS, DATA_TYPE_UINT64, 146327Sjchu ss_reg, 146427Sjchu FIRE_JBC_ESS, DATA_TYPE_UINT64, 146527Sjchu CSR_XR(csr_base, JBC_ERROR_STATUS_SET), 146627Sjchu FIRE_JBC_DMC_ODCD, DATA_TYPE_UINT64, 146727Sjchu CSR_XR(csr_base, DMCINT_ODCD_ERROR_LOG), 146827Sjchu NULL); 146927Sjchu 147027Sjchu return (PX_OK); 147127Sjchu } 147227Sjchu 147327Sjchu /* 147427Sjchu * JBC Dmcint ODCO nonfatal errer handling - 147527Sjchu * Unmapped PIO read error: pio:read:M:nonfatal 147627Sjchu * Unmapped PIO write error: pio:write:M:nonfatal 147727Sjchu * PIO data parity error: pio:write:M:nonfatal 147827Sjchu * Invalid PIO write to PCIe cfg/io, csr, ebus or i2c bus: pio:write:nonfatal 147927Sjchu * Invalid PIO read to PCIe cfg/io, csr, ebus or i2c bus: pio:read:nonfatal 148027Sjchu */ 148127Sjchu /* ARGSUSED */ 148227Sjchu int 148327Sjchu px_err_jbc_dmcint_odcd_handle(dev_info_t *rpdip, caddr_t csr_base, 148427Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 148527Sjchu px_err_bit_desc_t *err_bit_descr) 148627Sjchu { 1487739Sjchu boolean_t pri = PX_ERR_IS_PRI(err_bit_descr->bit); 148827Sjchu uint64_t paddr; 148927Sjchu int ret; 149027Sjchu 1491739Sjchu if (!pri) 1492739Sjchu return (PX_FATAL_GOS); 1493739Sjchu 149427Sjchu paddr = CSR_XR(csr_base, DMCINT_ODCD_ERROR_LOG); 149527Sjchu paddr &= DMCINT_ODCD_ERROR_LOG_ADDRESS_MASK; 149627Sjchu 149727Sjchu ret = px_handle_lookup( 149827Sjchu rpdip, DMA_HANDLE, derr->fme_ena, (void *)paddr); 149927Sjchu 150027Sjchu return ((ret == DDI_FM_FATAL) ? PX_FATAL_GOS : PX_NONFATAL); 150127Sjchu } 150227Sjchu 150327Sjchu /* JBC Dmcint IDC - see io erpt doc, section 1.6 */ 150427Sjchu PX_ERPT_SEND_DEC(jbc_idc) 150527Sjchu { 150627Sjchu char buf[FM_MAX_CLASS]; 1507739Sjchu boolean_t pri = PX_ERR_IS_PRI(bit); 150827Sjchu 150927Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 151027Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 151127Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 1512739Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri, 151327Sjchu FIRE_JBC_ELE, DATA_TYPE_UINT64, 151427Sjchu CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE), 151527Sjchu FIRE_JBC_IE, DATA_TYPE_UINT64, 151627Sjchu CSR_XR(csr_base, JBC_INTERRUPT_ENABLE), 151727Sjchu FIRE_JBC_IS, DATA_TYPE_UINT64, 151827Sjchu ss_reg, 151927Sjchu FIRE_JBC_ESS, DATA_TYPE_UINT64, 152027Sjchu CSR_XR(csr_base, JBC_ERROR_STATUS_SET), 152127Sjchu FIRE_JBC_DMC_IDC, DATA_TYPE_UINT64, 152227Sjchu CSR_XR(csr_base, DMCINT_IDC_ERROR_LOG), 152327Sjchu NULL); 152427Sjchu 152527Sjchu return (PX_OK); 152627Sjchu } 152727Sjchu 152827Sjchu /* JBC CSR - see io erpt doc, section 1.7 */ 152927Sjchu PX_ERPT_SEND_DEC(jbc_csr) 153027Sjchu { 153127Sjchu char buf[FM_MAX_CLASS]; 1532739Sjchu boolean_t pri = PX_ERR_IS_PRI(bit); 153327Sjchu 153427Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 153527Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 153627Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 1537739Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri, 153827Sjchu FIRE_JBC_ELE, DATA_TYPE_UINT64, 153927Sjchu CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE), 154027Sjchu FIRE_JBC_IE, DATA_TYPE_UINT64, 154127Sjchu CSR_XR(csr_base, JBC_INTERRUPT_ENABLE), 154227Sjchu FIRE_JBC_IS, DATA_TYPE_UINT64, 154327Sjchu ss_reg, 154427Sjchu FIRE_JBC_ESS, DATA_TYPE_UINT64, 154527Sjchu CSR_XR(csr_base, JBC_ERROR_STATUS_SET), 154627Sjchu "jbc-error-reg", DATA_TYPE_UINT64, 154727Sjchu CSR_XR(csr_base, CSR_ERROR_LOG), 154827Sjchu NULL); 154927Sjchu 155027Sjchu return (PX_OK); 155127Sjchu } 155227Sjchu 155327Sjchu /* 155427Sjchu * JBC CSR errer handling - 155527Sjchu * Ebus ready timeout error: pio:rdwr:M:nonfatal 155627Sjchu */ 155727Sjchu /* ARGSUSED */ 155827Sjchu int 155927Sjchu px_err_jbc_csr_handle(dev_info_t *rpdip, caddr_t csr_base, 156027Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 156127Sjchu px_err_bit_desc_t *err_bit_descr) 156227Sjchu { 1563739Sjchu boolean_t pri = PX_ERR_IS_PRI(err_bit_descr->bit); 156427Sjchu uint64_t paddr; 156527Sjchu int ret; 156627Sjchu 1567739Sjchu if (!pri) 1568739Sjchu return (PX_FATAL_GOS); 1569739Sjchu 157027Sjchu paddr = CSR_XR(csr_base, CSR_ERROR_LOG); 157127Sjchu paddr &= CSR_ERROR_LOG_ADDRESS_MASK; 157227Sjchu 157327Sjchu ret = px_handle_lookup( 157427Sjchu rpdip, DMA_HANDLE, derr->fme_ena, (void *)paddr); 157527Sjchu 157627Sjchu return ((ret == DDI_FM_FATAL) ? PX_FATAL_GOS : PX_NONFATAL); 157727Sjchu } 157827Sjchu 157927Sjchu /* JBC Dmcint IDC - see io erpt doc, section 1.6 */ 158027Sjchu 158127Sjchu /* DMC IMU RDS - see io erpt doc, section 2.1 */ 158227Sjchu PX_ERPT_SEND_DEC(imu_rds) 158327Sjchu { 158427Sjchu char buf[FM_MAX_CLASS]; 1585739Sjchu boolean_t pri = PX_ERR_IS_PRI(bit); 158627Sjchu 158727Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 158827Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 158927Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 1590739Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri, 159127Sjchu FIRE_IMU_ELE, DATA_TYPE_UINT64, 159227Sjchu CSR_XR(csr_base, IMU_ERROR_LOG_ENABLE), 159327Sjchu FIRE_IMU_IE, DATA_TYPE_UINT64, 159427Sjchu CSR_XR(csr_base, IMU_INTERRUPT_ENABLE), 159527Sjchu FIRE_IMU_IS, DATA_TYPE_UINT64, 159627Sjchu ss_reg, 159727Sjchu FIRE_IMU_ESS, DATA_TYPE_UINT64, 159827Sjchu CSR_XR(csr_base, IMU_ERROR_STATUS_SET), 159927Sjchu FIRE_IMU_RDS, DATA_TYPE_UINT64, 160027Sjchu CSR_XR(csr_base, IMU_RDS_ERROR_LOG), 160127Sjchu NULL); 160227Sjchu 160327Sjchu return (PX_OK); 160427Sjchu } 160527Sjchu 160627Sjchu /* imu function to handle all Received but Not Enabled errors */ 160727Sjchu /* ARGSUSED */ 160827Sjchu int 160927Sjchu px_err_imu_rbne_handle(dev_info_t *rpdip, caddr_t csr_base, 161027Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 161127Sjchu px_err_bit_desc_t *err_bit_descr) 161227Sjchu { 161327Sjchu uint64_t imu_log_enable, imu_intr_enable; 161427Sjchu int mask = BITMASK(err_bit_descr->bit); 161527Sjchu int err = PX_NONFATAL; 161627Sjchu 161727Sjchu imu_log_enable = CSR_XR(csr_base, err_reg_descr->log_addr); 161827Sjchu imu_intr_enable = CSR_XR(csr_base, err_reg_descr->enable_addr); 161927Sjchu 1620435Sjchu /* 1621435Sjchu * If matching bit is not set, meaning corresponding rbne not 1622435Sjchu * enabled, then receiving it indicates some sort of malfunction 1623435Sjchu * possibly in hardware. 1624435Sjchu * 1625435Sjchu * Other wise, software may have intentionally disabled certain 1626435Sjchu * errors for a period of time within which the occuring of the 1627435Sjchu * disabled errors become rbne, that is non fatal. 1628435Sjchu */ 1629*1772Sjl139090 1630435Sjchu if (!(imu_log_enable & imu_intr_enable & mask)) 163127Sjchu err = PX_FATAL_SW; 163227Sjchu 163327Sjchu return (err); 163427Sjchu } 163527Sjchu 1636118Sjchu /* 1637118Sjchu * No platforms uses PME. Any PME received is simply logged 1638118Sjchu * for analysis. 1639118Sjchu */ 1640118Sjchu /* ARGSUSED */ 1641118Sjchu int 1642118Sjchu px_err_imu_pme_handle(dev_info_t *rpdip, caddr_t csr_base, 1643118Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 1644118Sjchu px_err_bit_desc_t *err_bit_descr) 1645118Sjchu { 1646118Sjchu px_t *px_p = DIP_TO_STATE(rpdip); 1647118Sjchu 1648118Sjchu px_p->px_pme_ignored++; 1649118Sjchu return (PX_NONFATAL); 1650118Sjchu } 1651118Sjchu 165227Sjchu /* handle EQ overflow */ 165327Sjchu /* ARGSUSED */ 165427Sjchu int 165527Sjchu px_err_imu_eq_ovfl_handle(dev_info_t *rpdip, caddr_t csr_base, 165627Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 165727Sjchu px_err_bit_desc_t *err_bit_descr) 165827Sjchu { 165927Sjchu px_t *px_p = DIP_TO_STATE(rpdip); 166027Sjchu px_msiq_state_t *msiq_state_p = &px_p->px_ib_p->ib_msiq_state; 166127Sjchu msiqid_t eqno; 166227Sjchu pci_msiq_state_t msiq_state; 166327Sjchu int err = PX_NONFATAL; 166427Sjchu int i; 166527Sjchu 166627Sjchu eqno = msiq_state_p->msiq_1st_msiq_id; 166727Sjchu for (i = 0; i < msiq_state_p->msiq_cnt; i++) { 166827Sjchu if (px_lib_msiq_getstate(rpdip, eqno, &msiq_state) == 166927Sjchu DDI_SUCCESS) { 167027Sjchu if (msiq_state == PCI_MSIQ_STATE_ERROR) { 167127Sjchu err = PX_FATAL_SW; 167227Sjchu } 167327Sjchu } 167427Sjchu } 167527Sjchu 167627Sjchu return (err); 167727Sjchu } 167827Sjchu 167927Sjchu /* DMC IMU SCS - see io erpt doc, section 2.2 */ 168027Sjchu PX_ERPT_SEND_DEC(imu_scs) 168127Sjchu { 168227Sjchu char buf[FM_MAX_CLASS]; 1683739Sjchu boolean_t pri = PX_ERR_IS_PRI(bit); 168427Sjchu 168527Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 168627Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 168727Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 1688739Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri, 168927Sjchu FIRE_IMU_ELE, DATA_TYPE_UINT64, 169027Sjchu CSR_XR(csr_base, IMU_ERROR_LOG_ENABLE), 169127Sjchu FIRE_IMU_IE, DATA_TYPE_UINT64, 169227Sjchu CSR_XR(csr_base, IMU_INTERRUPT_ENABLE), 169327Sjchu FIRE_IMU_IS, DATA_TYPE_UINT64, 169427Sjchu ss_reg, 169527Sjchu FIRE_IMU_ESS, DATA_TYPE_UINT64, 169627Sjchu CSR_XR(csr_base, IMU_ERROR_STATUS_SET), 169727Sjchu FIRE_IMU_SCS, DATA_TYPE_UINT64, 169827Sjchu CSR_XR(csr_base, IMU_SCS_ERROR_LOG), 169927Sjchu NULL); 170027Sjchu 170127Sjchu return (PX_OK); 170227Sjchu } 170327Sjchu 170427Sjchu /* DMC IMU - see io erpt doc, section 2.3 */ 170527Sjchu PX_ERPT_SEND_DEC(imu) 170627Sjchu { 170727Sjchu char buf[FM_MAX_CLASS]; 1708739Sjchu boolean_t pri = PX_ERR_IS_PRI(bit); 170927Sjchu 171027Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 171127Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 171227Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 1713739Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri, 171427Sjchu FIRE_IMU_ELE, DATA_TYPE_UINT64, 171527Sjchu CSR_XR(csr_base, IMU_ERROR_LOG_ENABLE), 171627Sjchu FIRE_IMU_IE, DATA_TYPE_UINT64, 171727Sjchu CSR_XR(csr_base, IMU_INTERRUPT_ENABLE), 171827Sjchu FIRE_IMU_IS, DATA_TYPE_UINT64, 171927Sjchu ss_reg, 172027Sjchu FIRE_IMU_ESS, DATA_TYPE_UINT64, 172127Sjchu CSR_XR(csr_base, IMU_ERROR_STATUS_SET), 172227Sjchu NULL); 172327Sjchu 172427Sjchu return (PX_OK); 172527Sjchu } 172627Sjchu 172727Sjchu /* DMC MMU TFAR/TFSR - see io erpt doc, section 2.4 */ 172827Sjchu PX_ERPT_SEND_DEC(mmu_tfar_tfsr) 172927Sjchu { 173027Sjchu char buf[FM_MAX_CLASS]; 1731739Sjchu boolean_t pri = PX_ERR_IS_PRI(bit); 173227Sjchu 173327Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 1734*1772Sjl139090 173527Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 173627Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 1737739Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri, 173827Sjchu FIRE_MMU_ELE, DATA_TYPE_UINT64, 173927Sjchu CSR_XR(csr_base, MMU_ERROR_LOG_ENABLE), 174027Sjchu FIRE_MMU_IE, DATA_TYPE_UINT64, 174127Sjchu CSR_XR(csr_base, MMU_INTERRUPT_ENABLE), 174227Sjchu FIRE_MMU_IS, DATA_TYPE_UINT64, 174327Sjchu ss_reg, 174427Sjchu FIRE_MMU_ESS, DATA_TYPE_UINT64, 174527Sjchu CSR_XR(csr_base, MMU_ERROR_STATUS_SET), 174627Sjchu FIRE_MMU_TFAR, DATA_TYPE_UINT64, 174727Sjchu CSR_XR(csr_base, MMU_TRANSLATION_FAULT_ADDRESS), 174827Sjchu FIRE_MMU_TFSR, DATA_TYPE_UINT64, 174927Sjchu CSR_XR(csr_base, MMU_TRANSLATION_FAULT_STATUS), 175027Sjchu NULL); 175127Sjchu 175227Sjchu return (PX_OK); 175327Sjchu } 175427Sjchu 175527Sjchu /* DMC MMU - see io erpt doc, section 2.5 */ 175627Sjchu PX_ERPT_SEND_DEC(mmu) 175727Sjchu { 175827Sjchu char buf[FM_MAX_CLASS]; 1759739Sjchu boolean_t pri = PX_ERR_IS_PRI(bit); 176027Sjchu 176127Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 176227Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 176327Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 1764739Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri, 176527Sjchu FIRE_MMU_ELE, DATA_TYPE_UINT64, 176627Sjchu CSR_XR(csr_base, MMU_ERROR_LOG_ENABLE), 176727Sjchu FIRE_MMU_IE, DATA_TYPE_UINT64, 176827Sjchu CSR_XR(csr_base, MMU_INTERRUPT_ENABLE), 176927Sjchu FIRE_MMU_IS, DATA_TYPE_UINT64, 177027Sjchu ss_reg, 177127Sjchu FIRE_MMU_ESS, DATA_TYPE_UINT64, 177227Sjchu CSR_XR(csr_base, MMU_ERROR_STATUS_SET), 177327Sjchu NULL); 177427Sjchu 177527Sjchu return (PX_OK); 177627Sjchu } 177727Sjchu 177827Sjchu /* imu function to handle all Received but Not Enabled errors */ 177927Sjchu int 178027Sjchu px_err_mmu_rbne_handle(dev_info_t *rpdip, caddr_t csr_base, 178127Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 178227Sjchu px_err_bit_desc_t *err_bit_descr) 178327Sjchu { 1784739Sjchu boolean_t pri = PX_ERR_IS_PRI(err_bit_descr->bit); 1785260Set142600 uint64_t mmu_log_enable, mmu_intr_enable; 178627Sjchu uint64_t mask = BITMASK(err_bit_descr->bit); 1787260Set142600 uint64_t mmu_tfa, mmu_ctrl; 1788260Set142600 uint64_t mmu_enable_bit = 0; 178927Sjchu int err = PX_NONFATAL; 179027Sjchu int ret; 179127Sjchu 179227Sjchu mmu_log_enable = CSR_XR(csr_base, err_reg_descr->log_addr); 179327Sjchu mmu_intr_enable = CSR_XR(csr_base, err_reg_descr->enable_addr); 179427Sjchu 179527Sjchu mmu_tfa = CSR_XR(csr_base, MMU_TRANSLATION_FAULT_ADDRESS); 1796260Set142600 mmu_ctrl = CSR_XR(csr_base, MMU_CONTROL_AND_STATUS); 179727Sjchu 1798260Set142600 switch (err_bit_descr->bit) { 1799260Set142600 case MMU_INTERRUPT_STATUS_BYP_ERR_P: 1800260Set142600 mmu_enable_bit = BITMASK(MMU_CONTROL_AND_STATUS_BE); 1801260Set142600 break; 1802260Set142600 case MMU_INTERRUPT_STATUS_TRN_ERR_P: 1803260Set142600 mmu_enable_bit = BITMASK(MMU_CONTROL_AND_STATUS_TE); 1804260Set142600 break; 1805260Set142600 default: 1806260Set142600 mmu_enable_bit = 0; 1807260Set142600 break; 1808260Set142600 } 1809260Set142600 1810260Set142600 /* 1811260Set142600 * If the interrupts are enabled and Translation/Bypass Enable bit 1812260Set142600 * was set, then panic. This error should not have occured. 1813260Set142600 */ 1814260Set142600 if (mmu_log_enable & mmu_intr_enable & 1815260Set142600 (mmu_ctrl & mmu_enable_bit)) { 181627Sjchu err = PX_FATAL_SW; 181727Sjchu } else { 1818739Sjchu if (!pri) 1819739Sjchu return (PX_FATAL_GOS); 1820739Sjchu 182127Sjchu ret = px_handle_lookup( 182227Sjchu rpdip, DMA_HANDLE, derr->fme_ena, (void *)mmu_tfa); 182327Sjchu err = (ret == DDI_FM_FATAL) ? PX_FATAL_GOS : PX_NONFATAL; 182427Sjchu 182527Sjchu /* 182627Sjchu * S/W bug - this error should always be enabled 182727Sjchu */ 182827Sjchu 182927Sjchu /* enable error & intr reporting for this bit */ 183027Sjchu CSR_XS(csr_base, MMU_ERROR_LOG_ENABLE, mmu_log_enable | mask); 183127Sjchu CSR_XS(csr_base, MMU_INTERRUPT_ENABLE, mmu_intr_enable | mask); 1832260Set142600 1833260Set142600 /* enable translation access/bypass enable */ 1834260Set142600 CSR_XS(csr_base, MMU_CONTROL_AND_STATUS, 1835260Set142600 mmu_ctrl | mmu_enable_bit); 183627Sjchu } 183727Sjchu 183827Sjchu return (err); 183927Sjchu } 184027Sjchu 184127Sjchu /* Generic error handling functions that involve MMU Translation Fault Addr */ 184227Sjchu /* ARGSUSED */ 184327Sjchu int 184427Sjchu px_err_mmu_tfa_handle(dev_info_t *rpdip, caddr_t csr_base, 184527Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 184627Sjchu px_err_bit_desc_t *err_bit_descr) 184727Sjchu { 1848739Sjchu boolean_t pri = PX_ERR_IS_PRI(err_bit_descr->bit); 184927Sjchu uint64_t mmu_tfa; 185027Sjchu uint_t ret; 185127Sjchu 1852739Sjchu if (!pri) 1853739Sjchu return (PX_FATAL_GOS); 1854739Sjchu 185527Sjchu mmu_tfa = CSR_XR(csr_base, MMU_TRANSLATION_FAULT_ADDRESS); 185627Sjchu ret = px_handle_lookup( 185727Sjchu rpdip, DMA_HANDLE, derr->fme_ena, (void *)mmu_tfa); 185827Sjchu 185927Sjchu return ((ret == DDI_FM_FATAL) ? PX_FATAL_GOS : PX_NONFATAL); 186027Sjchu } 186127Sjchu 186227Sjchu /* MMU Table walk errors */ 186327Sjchu /* ARGSUSED */ 186427Sjchu int 186527Sjchu px_err_mmu_tblwlk_handle(dev_info_t *rpdip, caddr_t csr_base, 186627Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 186727Sjchu px_err_bit_desc_t *err_bit_descr) 186827Sjchu { 1869739Sjchu boolean_t pri = PX_ERR_IS_PRI(err_bit_descr->bit); 187027Sjchu uint64_t mmu_tfa; 187127Sjchu uint_t ret; 187227Sjchu 1873739Sjchu if (!pri) 1874739Sjchu return (PX_FATAL_GOS); 1875739Sjchu 187627Sjchu mmu_tfa = CSR_XR(csr_base, MMU_TRANSLATION_FAULT_ADDRESS); 187727Sjchu ret = px_handle_lookup( 187827Sjchu rpdip, DMA_HANDLE, derr->fme_ena, (void *)mmu_tfa); 187927Sjchu 188027Sjchu return ((ret == DDI_FM_FATAL) ? PX_FATAL_GOS : PX_NONFATAL); 188127Sjchu } 188227Sjchu 1883118Sjchu /* 18841147Sjchu * TLU LUP event - if caused by power management activity, then it is expected. 18851147Sjchu * In all other cases, it is an error. 1886118Sjchu */ 1887118Sjchu /* ARGSUSED */ 1888118Sjchu int 1889118Sjchu px_err_tlu_lup_handle(dev_info_t *rpdip, caddr_t csr_base, 1890118Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 1891118Sjchu px_err_bit_desc_t *err_bit_descr) 1892118Sjchu { 1893118Sjchu px_t *px_p = DIP_TO_STATE(rpdip); 1894118Sjchu 1895118Sjchu /* 18961147Sjchu * power management code is currently the only segment that sets 18971147Sjchu * px_lup_pending to indicate its expectation for a healthy LUP 18981147Sjchu * event. For all other occasions, LUP event should be flaged as 18991147Sjchu * error condition. 1900118Sjchu */ 19011147Sjchu return ((atomic_cas_32(&px_p->px_lup_pending, 1, 0) == 0) ? 19021147Sjchu PX_NONFATAL : PX_OK); 19031147Sjchu } 1904118Sjchu 19051147Sjchu /* 19061147Sjchu * TLU LDN event - if caused by power management activity, then it is expected. 19071147Sjchu * In all other cases, it is an error. 19081147Sjchu */ 19091147Sjchu /* ARGSUSED */ 19101147Sjchu int 19111147Sjchu px_err_tlu_ldn_handle(dev_info_t *rpdip, caddr_t csr_base, 19121147Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 19131147Sjchu px_err_bit_desc_t *err_bit_descr) 19141147Sjchu { 19151147Sjchu px_t *px_p = DIP_TO_STATE(rpdip); 19161147Sjchu return ((px_p->px_pm_flags & PX_LDN_EXPECTED) ? PX_OK : PX_NONFATAL); 1917118Sjchu } 1918118Sjchu 191927Sjchu /* PEC ILU none - see io erpt doc, section 3.1 */ 192027Sjchu PX_ERPT_SEND_DEC(pec_ilu) 192127Sjchu { 192227Sjchu char buf[FM_MAX_CLASS]; 1923739Sjchu boolean_t pri = PX_ERR_IS_PRI(bit); 192427Sjchu 192527Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 192627Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 192727Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 1928739Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri, 192927Sjchu FIRE_ILU_ELE, DATA_TYPE_UINT64, 193027Sjchu CSR_XR(csr_base, ILU_ERROR_LOG_ENABLE), 193127Sjchu FIRE_ILU_IE, DATA_TYPE_UINT64, 193227Sjchu CSR_XR(csr_base, ILU_INTERRUPT_ENABLE), 193327Sjchu FIRE_ILU_IS, DATA_TYPE_UINT64, 193427Sjchu ss_reg, 193527Sjchu FIRE_ILU_ESS, DATA_TYPE_UINT64, 193627Sjchu CSR_XR(csr_base, ILU_ERROR_STATUS_SET), 193727Sjchu NULL); 193827Sjchu 193927Sjchu return (PX_OK); 194027Sjchu } 194127Sjchu 1942383Set142600 /* PCIEX UE Errors */ 1943383Set142600 /* ARGSUSED */ 1944671Skrishnae int 1945383Set142600 px_err_pciex_ue_handle(dev_info_t *rpdip, caddr_t csr_base, 1946383Set142600 ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 1947383Set142600 px_err_bit_desc_t *err_bit_descr) 1948383Set142600 { 1949383Set142600 uint32_t mask = (uint32_t)BITMASK(err_bit_descr->bit); 1950383Set142600 1951383Set142600 return ((err_bit_descr->bit >= 32 && px_fabric_die_rc_ue_gos) ? 1952383Set142600 PX_FATAL_GOS : PX_FABRIC_ERR_SEV(mask, px_fabric_die_rc_ue, 1953383Set142600 px_fabric_die_rc_ue_gos)); 1954383Set142600 } 1955383Set142600 1956383Set142600 /* PCI-E Uncorrectable Errors - see io erpt doc, section 3.2 */ 1957383Set142600 PX_ERPT_SEND_DEC(pciex_rx_ue) 1958383Set142600 { 1959383Set142600 char buf[FM_MAX_CLASS]; 1960739Sjchu boolean_t pri = PX_ERR_IS_PRI(bit); 1961383Set142600 1962383Set142600 (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 1963383Set142600 ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 1964383Set142600 DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 1965739Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri, 1966383Set142600 FIRE_TLU_UELE, DATA_TYPE_UINT64, 1967383Set142600 CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_LOG_ENABLE), 1968383Set142600 FIRE_TLU_UIE, DATA_TYPE_UINT64, 1969383Set142600 CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_INTERRUPT_ENABLE), 1970383Set142600 FIRE_TLU_UIS, DATA_TYPE_UINT64, 1971383Set142600 ss_reg, 1972383Set142600 FIRE_TLU_UESS, DATA_TYPE_UINT64, 1973383Set142600 CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_STATUS_SET), 1974383Set142600 FIRE_TLU_RUEH1L, DATA_TYPE_UINT64, 1975383Set142600 CSR_XR(csr_base, TLU_RECEIVE_UNCORRECTABLE_ERROR_HEADER1_LOG), 1976383Set142600 FIRE_TLU_RUEH2L, DATA_TYPE_UINT64, 1977383Set142600 CSR_XR(csr_base, TLU_RECEIVE_UNCORRECTABLE_ERROR_HEADER2_LOG), 1978383Set142600 NULL); 1979383Set142600 1980383Set142600 return (PX_OK); 1981383Set142600 } 1982383Set142600 1983383Set142600 /* PCI-E Uncorrectable Errors - see io erpt doc, section 3.3 */ 1984383Set142600 PX_ERPT_SEND_DEC(pciex_tx_ue) 1985383Set142600 { 1986383Set142600 char buf[FM_MAX_CLASS]; 1987739Sjchu boolean_t pri = PX_ERR_IS_PRI(bit); 1988383Set142600 1989383Set142600 (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 1990383Set142600 ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 1991383Set142600 DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 1992739Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri, 1993383Set142600 FIRE_TLU_UELE, DATA_TYPE_UINT64, 1994383Set142600 CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_LOG_ENABLE), 1995383Set142600 FIRE_TLU_UIE, DATA_TYPE_UINT64, 1996383Set142600 CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_INTERRUPT_ENABLE), 1997383Set142600 FIRE_TLU_UIS, DATA_TYPE_UINT64, 1998383Set142600 ss_reg, 1999383Set142600 FIRE_TLU_UESS, DATA_TYPE_UINT64, 2000383Set142600 CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_STATUS_SET), 2001383Set142600 FIRE_TLU_TUEH1L, DATA_TYPE_UINT64, 2002383Set142600 CSR_XR(csr_base, TLU_TRANSMIT_UNCORRECTABLE_ERROR_HEADER1_LOG), 2003383Set142600 FIRE_TLU_TUEH2L, DATA_TYPE_UINT64, 2004383Set142600 CSR_XR(csr_base, TLU_TRANSMIT_UNCORRECTABLE_ERROR_HEADER2_LOG), 2005383Set142600 NULL); 2006383Set142600 2007383Set142600 return (PX_OK); 2008383Set142600 } 2009383Set142600 2010383Set142600 /* PCI-E Uncorrectable Errors - see io erpt doc, section 3.4 */ 2011383Set142600 PX_ERPT_SEND_DEC(pciex_rx_tx_ue) 2012383Set142600 { 2013383Set142600 char buf[FM_MAX_CLASS]; 2014739Sjchu boolean_t pri = PX_ERR_IS_PRI(bit); 2015383Set142600 2016383Set142600 (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 2017383Set142600 ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 2018383Set142600 DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 2019739Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri, 2020383Set142600 FIRE_TLU_UELE, DATA_TYPE_UINT64, 2021383Set142600 CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_LOG_ENABLE), 2022383Set142600 FIRE_TLU_UIE, DATA_TYPE_UINT64, 2023383Set142600 CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_INTERRUPT_ENABLE), 2024383Set142600 FIRE_TLU_UIS, DATA_TYPE_UINT64, 2025383Set142600 ss_reg, 2026383Set142600 FIRE_TLU_UESS, DATA_TYPE_UINT64, 2027383Set142600 CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_STATUS_SET), 2028383Set142600 FIRE_TLU_RUEH1L, DATA_TYPE_UINT64, 2029383Set142600 CSR_XR(csr_base, TLU_RECEIVE_UNCORRECTABLE_ERROR_HEADER1_LOG), 2030383Set142600 FIRE_TLU_RUEH2L, DATA_TYPE_UINT64, 2031383Set142600 CSR_XR(csr_base, TLU_RECEIVE_UNCORRECTABLE_ERROR_HEADER2_LOG), 2032383Set142600 FIRE_TLU_TUEH1L, DATA_TYPE_UINT64, 2033383Set142600 CSR_XR(csr_base, TLU_TRANSMIT_UNCORRECTABLE_ERROR_HEADER1_LOG), 2034383Set142600 FIRE_TLU_TUEH2L, DATA_TYPE_UINT64, 2035383Set142600 CSR_XR(csr_base, TLU_TRANSMIT_UNCORRECTABLE_ERROR_HEADER2_LOG), 2036383Set142600 NULL); 2037383Set142600 2038383Set142600 return (PX_OK); 2039383Set142600 } 2040383Set142600 2041383Set142600 /* PCI-E Uncorrectable Errors - see io erpt doc, section 3.5 */ 2042383Set142600 PX_ERPT_SEND_DEC(pciex_ue) 2043383Set142600 { 2044383Set142600 char buf[FM_MAX_CLASS]; 2045739Sjchu boolean_t pri = PX_ERR_IS_PRI(bit); 2046383Set142600 2047383Set142600 (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 2048383Set142600 ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 2049383Set142600 DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 2050739Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri, 2051383Set142600 FIRE_TLU_UELE, DATA_TYPE_UINT64, 2052383Set142600 CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_LOG_ENABLE), 2053383Set142600 FIRE_TLU_UIE, DATA_TYPE_UINT64, 2054383Set142600 CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_INTERRUPT_ENABLE), 2055383Set142600 FIRE_TLU_UIS, DATA_TYPE_UINT64, 2056383Set142600 ss_reg, 2057383Set142600 FIRE_TLU_UESS, DATA_TYPE_UINT64, 2058383Set142600 CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_STATUS_SET), 2059383Set142600 NULL); 2060383Set142600 2061383Set142600 return (PX_OK); 2062383Set142600 } 2063383Set142600 2064383Set142600 /* PCIEX UE Errors */ 2065383Set142600 /* ARGSUSED */ 2066671Skrishnae int 2067383Set142600 px_err_pciex_ce_handle(dev_info_t *rpdip, caddr_t csr_base, 2068383Set142600 ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 2069383Set142600 px_err_bit_desc_t *err_bit_descr) 2070383Set142600 { 2071383Set142600 uint32_t mask = (uint32_t)BITMASK(err_bit_descr->bit); 2072383Set142600 2073383Set142600 return ((err_bit_descr->bit >= 32 && px_fabric_die_rc_ce_gos) ? 2074383Set142600 PX_FATAL_GOS : PX_FABRIC_ERR_SEV(mask, px_fabric_die_rc_ce, 2075383Set142600 px_fabric_die_rc_ce_gos)); 2076383Set142600 } 2077383Set142600 207827Sjchu /* PCI-E Correctable Errors - see io erpt doc, section 3.6 */ 207927Sjchu PX_ERPT_SEND_DEC(pciex_ce) 208027Sjchu { 208127Sjchu char buf[FM_MAX_CLASS]; 2082739Sjchu boolean_t pri = PX_ERR_IS_PRI(bit); 208327Sjchu 208427Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 208527Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 208627Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 2087739Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri, 208827Sjchu FIRE_TLU_CELE, DATA_TYPE_UINT64, 208927Sjchu CSR_XR(csr_base, TLU_CORRECTABLE_ERROR_LOG_ENABLE), 209027Sjchu FIRE_TLU_CIE, DATA_TYPE_UINT64, 209127Sjchu CSR_XR(csr_base, TLU_CORRECTABLE_ERROR_INTERRUPT_ENABLE), 209227Sjchu FIRE_TLU_CIS, DATA_TYPE_UINT64, 209327Sjchu ss_reg, 209427Sjchu FIRE_TLU_CESS, DATA_TYPE_UINT64, 209527Sjchu CSR_XR(csr_base, TLU_CORRECTABLE_ERROR_STATUS_SET), 209627Sjchu NULL); 209727Sjchu 209827Sjchu return (PX_OK); 209927Sjchu } 210027Sjchu 210127Sjchu /* TLU Other Event Status (receive only) - see io erpt doc, section 3.7 */ 210227Sjchu PX_ERPT_SEND_DEC(pciex_rx_oe) 210327Sjchu { 210427Sjchu char buf[FM_MAX_CLASS]; 2105739Sjchu boolean_t pri = PX_ERR_IS_PRI(bit); 210627Sjchu 210727Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 210827Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 210927Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 2110739Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri, 211127Sjchu FIRE_TLU_OEELE, DATA_TYPE_UINT64, 211227Sjchu CSR_XR(csr_base, TLU_OTHER_EVENT_LOG_ENABLE), 211327Sjchu FIRE_TLU_OEIE, DATA_TYPE_UINT64, 211427Sjchu CSR_XR(csr_base, TLU_OTHER_EVENT_INTERRUPT_ENABLE), 211527Sjchu FIRE_TLU_OEIS, DATA_TYPE_UINT64, 211627Sjchu ss_reg, 211727Sjchu FIRE_TLU_OEESS, DATA_TYPE_UINT64, 211827Sjchu CSR_XR(csr_base, TLU_OTHER_EVENT_STATUS_SET), 211927Sjchu FIRE_TLU_RUEH1L, DATA_TYPE_UINT64, 212027Sjchu CSR_XR(csr_base, TLU_RECEIVE_OTHER_EVENT_HEADER1_LOG), 2121260Set142600 FIRE_TLU_RUEH2L, DATA_TYPE_UINT64, 212227Sjchu CSR_XR(csr_base, TLU_RECEIVE_OTHER_EVENT_HEADER2_LOG), 212327Sjchu NULL); 212427Sjchu 212527Sjchu return (PX_OK); 212627Sjchu } 212727Sjchu 212827Sjchu /* TLU Other Event Status (rx + tx) - see io erpt doc, section 3.8 */ 212927Sjchu PX_ERPT_SEND_DEC(pciex_rx_tx_oe) 213027Sjchu { 213127Sjchu char buf[FM_MAX_CLASS]; 2132739Sjchu boolean_t pri = PX_ERR_IS_PRI(bit); 213327Sjchu 213427Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 213527Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 213627Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 2137739Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri, 213827Sjchu FIRE_TLU_OEELE, DATA_TYPE_UINT64, 213927Sjchu CSR_XR(csr_base, TLU_OTHER_EVENT_LOG_ENABLE), 214027Sjchu FIRE_TLU_OEIE, DATA_TYPE_UINT64, 214127Sjchu CSR_XR(csr_base, TLU_OTHER_EVENT_INTERRUPT_ENABLE), 214227Sjchu FIRE_TLU_OEIS, DATA_TYPE_UINT64, 214327Sjchu ss_reg, 214427Sjchu FIRE_TLU_OEESS, DATA_TYPE_UINT64, 214527Sjchu CSR_XR(csr_base, TLU_OTHER_EVENT_STATUS_SET), 214627Sjchu FIRE_TLU_ROEEH1L, DATA_TYPE_UINT64, 214727Sjchu CSR_XR(csr_base, TLU_RECEIVE_OTHER_EVENT_HEADER1_LOG), 214827Sjchu FIRE_TLU_ROEEH2L, DATA_TYPE_UINT64, 214927Sjchu CSR_XR(csr_base, TLU_RECEIVE_OTHER_EVENT_HEADER2_LOG), 215027Sjchu FIRE_TLU_TOEEH1L, DATA_TYPE_UINT64, 215127Sjchu CSR_XR(csr_base, TLU_TRANSMIT_OTHER_EVENT_HEADER1_LOG), 2152260Set142600 FIRE_TLU_TOEEH2L, DATA_TYPE_UINT64, 215327Sjchu CSR_XR(csr_base, TLU_TRANSMIT_OTHER_EVENT_HEADER2_LOG), 215427Sjchu NULL); 215527Sjchu 215627Sjchu return (PX_OK); 215727Sjchu } 215827Sjchu 215927Sjchu /* TLU Other Event - see io erpt doc, section 3.9 */ 216027Sjchu PX_ERPT_SEND_DEC(pciex_oe) 216127Sjchu { 2162739Sjchu char buf[FM_MAX_CLASS]; 2163739Sjchu boolean_t pri = PX_ERR_IS_PRI(bit); 216427Sjchu 216527Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 216627Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 216727Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 2168739Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri, 216927Sjchu FIRE_TLU_OEELE, DATA_TYPE_UINT64, 217027Sjchu CSR_XR(csr_base, TLU_OTHER_EVENT_LOG_ENABLE), 217127Sjchu FIRE_TLU_OEIE, DATA_TYPE_UINT64, 217227Sjchu CSR_XR(csr_base, TLU_OTHER_EVENT_INTERRUPT_ENABLE), 217327Sjchu FIRE_TLU_OEIS, DATA_TYPE_UINT64, 217427Sjchu ss_reg, 217527Sjchu FIRE_TLU_OEESS, DATA_TYPE_UINT64, 217627Sjchu CSR_XR(csr_base, TLU_OTHER_EVENT_STATUS_SET), 217727Sjchu NULL); 217827Sjchu 217927Sjchu return (PX_OK); 218027Sjchu } 2181