127Sjchu /* 227Sjchu * CDDL HEADER START 327Sjchu * 427Sjchu * The contents of this file are subject to the terms of the 5*1648Sjchu * Common Development and Distribution License (the "License"). 6*1648Sjchu * 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 /* 22*1648Sjchu * 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> 43118Sjchu #include "pcie_pwr.h" 4427Sjchu #include "px_lib4u.h" 4527Sjchu #include "px_err.h" 4627Sjchu #include "px_err_impl.h" 4727Sjchu 4827Sjchu /* 4927Sjchu * JBC error bit table 5027Sjchu */ 5127Sjchu #define JBC_BIT_DESC(bit, hdl, erpt) \ 5227Sjchu JBC_INTERRUPT_STATUS_ ## bit ## _P, \ 5327Sjchu 0, \ 5427Sjchu PX_ERR_BIT_HANDLE(hdl), \ 5527Sjchu PX_ERPT_SEND(erpt), \ 56739Sjchu PX_ERR_JBC_CLASS(bit) }, \ 57739Sjchu { JBC_INTERRUPT_STATUS_ ## bit ## _S, \ 58739Sjchu 0, \ 59739Sjchu PX_ERR_BIT_HANDLE(hdl), \ 60739Sjchu PX_ERPT_SEND(erpt), \ 6127Sjchu PX_ERR_JBC_CLASS(bit) 6227Sjchu px_err_bit_desc_t px_err_cb_tbl[] = { 6327Sjchu /* JBC FATAL - see io erpt doc, section 1.1 */ 6427Sjchu { JBC_BIT_DESC(MB_PEA, fatal_hw, jbc_fatal) }, 6527Sjchu { JBC_BIT_DESC(CPE, fatal_hw, jbc_fatal) }, 6627Sjchu { JBC_BIT_DESC(APE, fatal_hw, jbc_fatal) }, 6727Sjchu { JBC_BIT_DESC(PIO_CPE, fatal_hw, jbc_fatal) }, 6827Sjchu { JBC_BIT_DESC(JTCEEW, fatal_hw, jbc_fatal) }, 6927Sjchu { JBC_BIT_DESC(JTCEEI, fatal_hw, jbc_fatal) }, 7027Sjchu { JBC_BIT_DESC(JTCEER, fatal_hw, jbc_fatal) }, 7127Sjchu 7227Sjchu /* JBC MERGE - see io erpt doc, section 1.2 */ 7327Sjchu { JBC_BIT_DESC(MB_PER, jbc_merge, jbc_merge) }, 7427Sjchu { JBC_BIT_DESC(MB_PEW, jbc_merge, jbc_merge) }, 7527Sjchu 7627Sjchu /* JBC Jbusint IN - see io erpt doc, section 1.3 */ 7727Sjchu { JBC_BIT_DESC(UE_ASYN, fatal_gos, jbc_in) }, 78*1648Sjchu { JBC_BIT_DESC(CE_ASYN, non_fatal, jbc_in) }, 7927Sjchu { JBC_BIT_DESC(JTE, fatal_gos, jbc_in) }, 8027Sjchu { JBC_BIT_DESC(JBE, jbc_jbusint_in, jbc_in) }, 8127Sjchu { JBC_BIT_DESC(JUE, jbc_jbusint_in, jbc_in) }, 8227Sjchu { JBC_BIT_DESC(ICISE, fatal_gos, jbc_in) }, 8327Sjchu { JBC_BIT_DESC(WR_DPE, jbc_jbusint_in, jbc_in) }, 8427Sjchu { JBC_BIT_DESC(RD_DPE, jbc_jbusint_in, jbc_in) }, 8527Sjchu { JBC_BIT_DESC(ILL_BMW, jbc_jbusint_in, jbc_in) }, 8627Sjchu { JBC_BIT_DESC(ILL_BMR, jbc_jbusint_in, jbc_in) }, 8727Sjchu { JBC_BIT_DESC(BJC, jbc_jbusint_in, jbc_in) }, 8827Sjchu 8927Sjchu /* JBC Jbusint Out - see io erpt doc, section 1.4 */ 9027Sjchu { JBC_BIT_DESC(IJP, fatal_gos, jbc_out) }, 9127Sjchu 9227Sjchu /* JBC Dmcint ODCD - see io erpt doc, section 1.5 */ 9327Sjchu { JBC_BIT_DESC(PIO_UNMAP_RD, jbc_dmcint_odcd, jbc_odcd) }, 9427Sjchu { JBC_BIT_DESC(ILL_ACC_RD, jbc_dmcint_odcd, jbc_odcd) }, 9527Sjchu { JBC_BIT_DESC(PIO_UNMAP, jbc_dmcint_odcd, jbc_odcd) }, 9627Sjchu { JBC_BIT_DESC(PIO_DPE, jbc_dmcint_odcd, jbc_odcd) }, 9727Sjchu { JBC_BIT_DESC(PIO_CPE, non_fatal, jbc_odcd) }, 9827Sjchu { JBC_BIT_DESC(ILL_ACC, jbc_dmcint_odcd, jbc_odcd) }, 9927Sjchu 10027Sjchu /* JBC Dmcint IDC - see io erpt doc, section 1.6 */ 10127Sjchu { JBC_BIT_DESC(UNSOL_RD, non_fatal, jbc_idc) }, 10227Sjchu { JBC_BIT_DESC(UNSOL_INTR, non_fatal, jbc_idc) }, 10327Sjchu 10427Sjchu /* JBC CSR - see io erpt doc, section 1.7 */ 10527Sjchu { JBC_BIT_DESC(EBUS_TO, jbc_csr, jbc_csr) } 10627Sjchu }; 10727Sjchu 10827Sjchu #define px_err_cb_keys \ 10927Sjchu (sizeof (px_err_cb_tbl)) / (sizeof (px_err_bit_desc_t)) 11027Sjchu 11127Sjchu /* 11227Sjchu * DMC error bit tables 11327Sjchu */ 11427Sjchu #define IMU_BIT_DESC(bit, hdl, erpt) \ 11527Sjchu IMU_INTERRUPT_STATUS_ ## bit ## _P, \ 11627Sjchu 0, \ 11727Sjchu PX_ERR_BIT_HANDLE(hdl), \ 11827Sjchu PX_ERPT_SEND(erpt), \ 119739Sjchu PX_ERR_DMC_CLASS(bit) }, \ 120739Sjchu { IMU_INTERRUPT_STATUS_ ## bit ## _S, \ 121739Sjchu 0, \ 122739Sjchu PX_ERR_BIT_HANDLE(hdl), \ 123739Sjchu PX_ERPT_SEND(erpt), \ 12427Sjchu PX_ERR_DMC_CLASS(bit) 12527Sjchu px_err_bit_desc_t px_err_imu_tbl[] = { 12627Sjchu /* DMC IMU RDS - see io erpt doc, section 2.1 */ 12727Sjchu { IMU_BIT_DESC(MSI_MAL_ERR, non_fatal, imu_rds) }, 12827Sjchu { IMU_BIT_DESC(MSI_PAR_ERR, fatal_stuck, imu_rds) }, 12927Sjchu { IMU_BIT_DESC(PMEACK_MES_NOT_EN, imu_rbne, imu_rds) }, 130118Sjchu { IMU_BIT_DESC(PMPME_MES_NOT_EN, imu_pme, imu_rds) }, 13127Sjchu { IMU_BIT_DESC(FATAL_MES_NOT_EN, imu_rbne, imu_rds) }, 13227Sjchu { IMU_BIT_DESC(NONFATAL_MES_NOT_EN, imu_rbne, imu_rds) }, 13327Sjchu { IMU_BIT_DESC(COR_MES_NOT_EN, imu_rbne, imu_rds) }, 13427Sjchu { IMU_BIT_DESC(MSI_NOT_EN, imu_rbne, imu_rds) }, 13527Sjchu 13627Sjchu /* DMC IMU SCS - see io erpt doc, section 2.2 */ 13727Sjchu { IMU_BIT_DESC(EQ_NOT_EN, imu_rbne, imu_rds) }, 13827Sjchu 13927Sjchu /* DMC IMU - see io erpt doc, section 2.3 */ 14027Sjchu { IMU_BIT_DESC(EQ_OVER, imu_eq_ovfl, imu) } 14127Sjchu }; 14227Sjchu 14327Sjchu #define px_err_imu_keys (sizeof (px_err_imu_tbl)) / (sizeof (px_err_bit_desc_t)) 14427Sjchu 14527Sjchu /* mmu errors */ 14627Sjchu #define MMU_BIT_DESC(bit, hdl, erpt) \ 14727Sjchu MMU_INTERRUPT_STATUS_ ## bit ## _P, \ 14827Sjchu 0, \ 14927Sjchu PX_ERR_BIT_HANDLE(hdl), \ 15027Sjchu PX_ERPT_SEND(erpt), \ 151739Sjchu PX_ERR_DMC_CLASS(bit) }, \ 152739Sjchu { MMU_INTERRUPT_STATUS_ ## bit ## _S, \ 153739Sjchu 0, \ 154739Sjchu PX_ERR_BIT_HANDLE(hdl), \ 155739Sjchu PX_ERPT_SEND(erpt), \ 15627Sjchu PX_ERR_DMC_CLASS(bit) 15727Sjchu px_err_bit_desc_t px_err_mmu_tbl[] = { 15827Sjchu /* DMC MMU TFAR/TFSR - see io erpt doc, section 2.4 */ 15927Sjchu { MMU_BIT_DESC(BYP_ERR, mmu_rbne, mmu_tfar_tfsr) }, 16027Sjchu { MMU_BIT_DESC(BYP_OOR, mmu_tfa, mmu_tfar_tfsr) }, 16127Sjchu { MMU_BIT_DESC(TRN_ERR, mmu_rbne, mmu_tfar_tfsr) }, 16227Sjchu { MMU_BIT_DESC(TRN_OOR, mmu_tfa, mmu_tfar_tfsr) }, 16327Sjchu { MMU_BIT_DESC(TTE_INV, mmu_tfa, mmu_tfar_tfsr) }, 16427Sjchu { MMU_BIT_DESC(TTE_PRT, mmu_tfa, mmu_tfar_tfsr) }, 16527Sjchu { MMU_BIT_DESC(TTC_DPE, mmu_tfa, mmu_tfar_tfsr) }, 16627Sjchu { MMU_BIT_DESC(TBW_DME, mmu_tblwlk, mmu_tfar_tfsr) }, 16727Sjchu { MMU_BIT_DESC(TBW_UDE, mmu_tblwlk, mmu_tfar_tfsr) }, 16827Sjchu { MMU_BIT_DESC(TBW_ERR, mmu_tblwlk, mmu_tfar_tfsr) }, 16927Sjchu { MMU_BIT_DESC(TBW_DPE, mmu_tblwlk, mmu_tfar_tfsr) }, 17027Sjchu 17127Sjchu /* DMC MMU - see io erpt doc, section 2.5 */ 17227Sjchu { MMU_BIT_DESC(TTC_CAE, non_fatal, mmu) } 17327Sjchu }; 17427Sjchu #define px_err_mmu_keys (sizeof (px_err_mmu_tbl)) / (sizeof (px_err_bit_desc_t)) 17527Sjchu 17627Sjchu /* 17727Sjchu * PEC error bit tables 17827Sjchu */ 17927Sjchu #define ILU_BIT_DESC(bit, hdl, erpt) \ 18027Sjchu ILU_INTERRUPT_STATUS_ ## bit ## _P, \ 18127Sjchu 0, \ 18227Sjchu PX_ERR_BIT_HANDLE(hdl), \ 18327Sjchu PX_ERPT_SEND(erpt), \ 184739Sjchu PX_ERR_PEC_CLASS(bit) }, \ 185739Sjchu { ILU_INTERRUPT_STATUS_ ## bit ## _S, \ 186739Sjchu 0, \ 187739Sjchu PX_ERR_BIT_HANDLE(hdl), \ 188739Sjchu PX_ERPT_SEND(erpt), \ 18927Sjchu PX_ERR_PEC_CLASS(bit) 19027Sjchu px_err_bit_desc_t px_err_ilu_tbl[] = { 19127Sjchu /* PEC ILU none - see io erpt doc, section 3.1 */ 19227Sjchu { ILU_BIT_DESC(IHB_PE, fatal_gos, pec_ilu) } 19327Sjchu }; 19427Sjchu #define px_err_ilu_keys \ 19527Sjchu (sizeof (px_err_ilu_tbl)) / (sizeof (px_err_bit_desc_t)) 19627Sjchu 19727Sjchu /* 19827Sjchu * PEC UE errors implementation is incomplete pending PCIE generic 199383Set142600 * fabric rules. Must handle both PRIMARY and SECONDARY errors. 20027Sjchu */ 20127Sjchu /* pec ue errors */ 20227Sjchu #define TLU_UC_BIT_DESC(bit, hdl, erpt) \ 20327Sjchu TLU_UNCORRECTABLE_ERROR_STATUS_CLEAR_ ## bit ## _P, \ 20427Sjchu 0, \ 205383Set142600 PX_ERR_BIT_HANDLE(hdl), \ 206383Set142600 PX_ERPT_SEND(erpt), \ 207383Set142600 PX_ERR_PEC_CLASS(bit) }, \ 208383Set142600 { TLU_UNCORRECTABLE_ERROR_STATUS_CLEAR_ ## bit ## _S, \ 209383Set142600 0, \ 210383Set142600 PX_ERR_BIT_HANDLE(hdl), \ 211383Set142600 PX_ERPT_SEND(erpt), \ 212383Set142600 PX_ERR_PEC_CLASS(bit) 21327Sjchu px_err_bit_desc_t px_err_tlu_ue_tbl[] = { 21427Sjchu /* PCI-E Receive Uncorrectable Errors - see io erpt doc, section 3.2 */ 215383Set142600 { TLU_UC_BIT_DESC(UR, pciex_ue, pciex_rx_ue) }, 216383Set142600 { TLU_UC_BIT_DESC(UC, pciex_ue, pciex_rx_ue) }, 21727Sjchu 21827Sjchu /* PCI-E Transmit Uncorrectable Errors - see io erpt doc, section 3.3 */ 219383Set142600 { TLU_UC_BIT_DESC(CTO, pciex_ue, pciex_tx_ue) }, 220383Set142600 { TLU_UC_BIT_DESC(ROF, pciex_ue, pciex_tx_ue) }, 22127Sjchu 22227Sjchu /* PCI-E Rx/Tx Uncorrectable Errors - see io erpt doc, section 3.4 */ 223383Set142600 { TLU_UC_BIT_DESC(MFP, pciex_ue, pciex_rx_tx_ue) }, 224383Set142600 { TLU_UC_BIT_DESC(PP, pciex_ue, pciex_rx_tx_ue) }, 22527Sjchu 22627Sjchu /* Other PCI-E Uncorrectable Errors - see io erpt doc, section 3.5 */ 227383Set142600 { TLU_UC_BIT_DESC(FCP, pciex_ue, pciex_ue) }, 228383Set142600 { TLU_UC_BIT_DESC(DLP, pciex_ue, pciex_ue) }, 229383Set142600 { TLU_UC_BIT_DESC(TE, pciex_ue, pciex_ue) }, 230383Set142600 231383Set142600 /* Not used */ 232383Set142600 { TLU_UC_BIT_DESC(CA, pciex_ue, do_not) } 23327Sjchu }; 23427Sjchu #define px_err_tlu_ue_keys \ 23527Sjchu (sizeof (px_err_tlu_ue_tbl)) / (sizeof (px_err_bit_desc_t)) 23627Sjchu 23727Sjchu /* 23827Sjchu * PEC CE errors implementation is incomplete pending PCIE generic 23927Sjchu * fabric rules. 24027Sjchu */ 24127Sjchu /* pec ce errors */ 24227Sjchu #define TLU_CE_BIT_DESC(bit, hdl, erpt) \ 24327Sjchu TLU_CORRECTABLE_ERROR_STATUS_CLEAR_ ## bit ## _P, \ 24427Sjchu 0, \ 245383Set142600 PX_ERR_BIT_HANDLE(hdl), \ 246383Set142600 PX_ERPT_SEND(erpt), \ 247383Set142600 PX_ERR_PEC_CLASS(bit) }, \ 248383Set142600 { TLU_CORRECTABLE_ERROR_STATUS_CLEAR_ ## bit ## _S, \ 249383Set142600 0, \ 250383Set142600 PX_ERR_BIT_HANDLE(hdl), \ 251383Set142600 PX_ERPT_SEND(erpt), \ 252383Set142600 PX_ERR_PEC_CLASS(bit) 25327Sjchu px_err_bit_desc_t px_err_tlu_ce_tbl[] = { 25427Sjchu /* PCI-E Correctable Errors - see io erpt doc, section 3.6 */ 255383Set142600 { TLU_CE_BIT_DESC(RTO, pciex_ce, pciex_ce) }, 256383Set142600 { TLU_CE_BIT_DESC(RNR, pciex_ce, pciex_ce) }, 257383Set142600 { TLU_CE_BIT_DESC(BDP, pciex_ce, pciex_ce) }, 258383Set142600 { TLU_CE_BIT_DESC(BTP, pciex_ce, pciex_ce) }, 259383Set142600 { TLU_CE_BIT_DESC(RE, pciex_ce, pciex_ce) } 26027Sjchu }; 26127Sjchu #define px_err_tlu_ce_keys \ 26227Sjchu (sizeof (px_err_tlu_ce_tbl)) / (sizeof (px_err_bit_desc_t)) 26327Sjchu 26427Sjchu /* pec oe errors */ 26527Sjchu #define TLU_OE_BIT_DESC(bit, hdl, erpt) \ 26627Sjchu TLU_OTHER_EVENT_STATUS_CLEAR_ ## bit ## _P, \ 26727Sjchu 0, \ 26827Sjchu PX_ERR_BIT_HANDLE(hdl), \ 26927Sjchu PX_ERPT_SEND(erpt), \ 270739Sjchu PX_ERR_PEC_CLASS(bit) }, \ 271739Sjchu { TLU_OTHER_EVENT_STATUS_CLEAR_ ## bit ## _S, \ 272739Sjchu 0, \ 273739Sjchu PX_ERR_BIT_HANDLE(hdl), \ 274739Sjchu PX_ERPT_SEND(erpt), \ 27527Sjchu PX_ERR_PEC_CLASS(bit) 27627Sjchu px_err_bit_desc_t px_err_tlu_oe_tbl[] = { 27727Sjchu /* 27827Sjchu * TLU Other Event Status (receive only) - see io erpt doc, section 3.7 27927Sjchu */ 28027Sjchu { TLU_OE_BIT_DESC(MRC, fatal_hw, pciex_rx_oe) }, 28127Sjchu 28227Sjchu /* TLU Other Event Status (rx + tx) - see io erpt doc, section 3.8 */ 283383Set142600 { TLU_OE_BIT_DESC(WUC, non_fatal, pciex_rx_tx_oe) }, 284383Set142600 { TLU_OE_BIT_DESC(RUC, non_fatal, pciex_rx_tx_oe) }, 28527Sjchu { TLU_OE_BIT_DESC(CRS, non_fatal, pciex_rx_tx_oe) }, 28627Sjchu 28727Sjchu /* TLU Other Event - see io erpt doc, section 3.9 */ 28827Sjchu { TLU_OE_BIT_DESC(IIP, fatal_gos, pciex_oe) }, 28927Sjchu { TLU_OE_BIT_DESC(EDP, fatal_gos, pciex_oe) }, 29027Sjchu { TLU_OE_BIT_DESC(EHP, fatal_gos, pciex_oe) }, 29127Sjchu { TLU_OE_BIT_DESC(LIN, non_fatal, pciex_oe) }, 29227Sjchu { TLU_OE_BIT_DESC(LRS, non_fatal, pciex_oe) }, 2931147Sjchu { TLU_OE_BIT_DESC(LDN, tlu_ldn, pciex_oe) }, 2941147Sjchu { TLU_OE_BIT_DESC(LUP, tlu_lup, pciex_oe) }, 29527Sjchu { TLU_OE_BIT_DESC(ERU, fatal_gos, pciex_oe) }, 29627Sjchu { TLU_OE_BIT_DESC(ERO, fatal_gos, pciex_oe) }, 29727Sjchu { TLU_OE_BIT_DESC(EMP, fatal_gos, pciex_oe) }, 29827Sjchu { TLU_OE_BIT_DESC(EPE, fatal_gos, pciex_oe) }, 29927Sjchu { TLU_OE_BIT_DESC(ERP, fatal_gos, pciex_oe) }, 30027Sjchu { TLU_OE_BIT_DESC(EIP, fatal_gos, pciex_oe) } 30127Sjchu }; 30227Sjchu 30327Sjchu #define px_err_tlu_oe_keys \ 30427Sjchu (sizeof (px_err_tlu_oe_tbl)) / (sizeof (px_err_bit_desc_t)) 30527Sjchu 30627Sjchu /* 30727Sjchu * All the following tables below are for LPU Interrupts. These interrupts 30827Sjchu * are *NOT* error interrupts, but event status interrupts. 30927Sjchu * 31027Sjchu * These events are probably of most interest to: 31127Sjchu * o Hotplug 31227Sjchu * o Power Management 31327Sjchu * o etc... 31427Sjchu * 31527Sjchu * There are also a few events that would be interresting for FMA. 31627Sjchu * Again none of the regiseters below state that an error has occured 31727Sjchu * or that data has been lost. If anything, they give status that an 31827Sjchu * error is *about* to occur. examples 31927Sjchu * o INT_SKP_ERR - indicates clock between fire and child is too far 32027Sjchu * off and is most unlikely able to compensate 32127Sjchu * o INT_TX_PAR_ERR - A parity error occured in ONE lane. This is 32227Sjchu * HW recoverable, but will like end up as a future 32327Sjchu * fabric error as well. 32427Sjchu * 32527Sjchu * For now, we don't care about any of these errors and should be ignore, 32627Sjchu * but cleared. 32727Sjchu */ 32827Sjchu 32927Sjchu /* LPU Link Interrupt Table */ 33027Sjchu #define LPUL_BIT_DESC(bit, hdl, erpt) \ 33127Sjchu LPU_LINK_LAYER_INTERRUPT_AND_STATUS_INT_ ## bit, \ 33227Sjchu 0, \ 33327Sjchu NULL, \ 33427Sjchu NULL, \ 33527Sjchu "" 33627Sjchu px_err_bit_desc_t px_err_lpul_tbl[] = { 33727Sjchu { LPUL_BIT_DESC(LINK_ERR_ACT, NULL, NULL) } 33827Sjchu }; 33927Sjchu #define px_err_lpul_keys \ 34027Sjchu (sizeof (px_err_lpul_tbl)) / (sizeof (px_err_bit_desc_t)) 34127Sjchu 34227Sjchu /* LPU Physical Interrupt Table */ 34327Sjchu #define LPUP_BIT_DESC(bit, hdl, erpt) \ 34427Sjchu LPU_PHY_LAYER_INTERRUPT_AND_STATUS_INT_ ## bit, \ 34527Sjchu 0, \ 34627Sjchu NULL, \ 34727Sjchu NULL, \ 34827Sjchu "" 34927Sjchu px_err_bit_desc_t px_err_lpup_tbl[] = { 35027Sjchu { LPUP_BIT_DESC(PHY_LAYER_ERR, NULL, NULL) } 35127Sjchu }; 35227Sjchu #define px_err_lpup_keys \ 35327Sjchu (sizeof (px_err_lpup_tbl)) / (sizeof (px_err_bit_desc_t)) 35427Sjchu 35527Sjchu /* LPU Receive Interrupt Table */ 35627Sjchu #define LPUR_BIT_DESC(bit, hdl, erpt) \ 35727Sjchu LPU_RECEIVE_PHY_INTERRUPT_AND_STATUS_INT_ ## bit, \ 35827Sjchu 0, \ 35927Sjchu NULL, \ 36027Sjchu NULL, \ 36127Sjchu "" 36227Sjchu px_err_bit_desc_t px_err_lpur_tbl[] = { 36327Sjchu { LPUR_BIT_DESC(RCV_PHY, NULL, NULL) } 36427Sjchu }; 36527Sjchu #define px_err_lpur_keys \ 36627Sjchu (sizeof (px_err_lpur_tbl)) / (sizeof (px_err_bit_desc_t)) 36727Sjchu 36827Sjchu /* LPU Transmit Interrupt Table */ 36927Sjchu #define LPUX_BIT_DESC(bit, hdl, erpt) \ 37027Sjchu LPU_TRANSMIT_PHY_INTERRUPT_AND_STATUS_INT_ ## bit, \ 37127Sjchu 0, \ 37227Sjchu NULL, \ 37327Sjchu NULL, \ 37427Sjchu "" 37527Sjchu px_err_bit_desc_t px_err_lpux_tbl[] = { 37627Sjchu { LPUX_BIT_DESC(UNMSK, NULL, NULL) } 37727Sjchu }; 37827Sjchu #define px_err_lpux_keys \ 37927Sjchu (sizeof (px_err_lpux_tbl)) / (sizeof (px_err_bit_desc_t)) 38027Sjchu 38127Sjchu /* LPU LTSSM Interrupt Table */ 38227Sjchu #define LPUS_BIT_DESC(bit, hdl, erpt) \ 38327Sjchu LPU_LTSSM_INTERRUPT_AND_STATUS_INT_ ## bit, \ 38427Sjchu 0, \ 38527Sjchu NULL, \ 38627Sjchu NULL, \ 38727Sjchu "" 38827Sjchu px_err_bit_desc_t px_err_lpus_tbl[] = { 38927Sjchu { LPUS_BIT_DESC(ANY, NULL, NULL) } 39027Sjchu }; 39127Sjchu #define px_err_lpus_keys \ 39227Sjchu (sizeof (px_err_lpus_tbl)) / (sizeof (px_err_bit_desc_t)) 39327Sjchu 39427Sjchu /* LPU Gigablaze Glue Interrupt Table */ 39527Sjchu #define LPUG_BIT_DESC(bit, hdl, erpt) \ 39627Sjchu LPU_GIGABLAZE_GLUE_INTERRUPT_AND_STATUS_INT_ ## bit, \ 39727Sjchu 0, \ 39827Sjchu NULL, \ 39927Sjchu NULL, \ 40027Sjchu "" 40127Sjchu px_err_bit_desc_t px_err_lpug_tbl[] = { 40227Sjchu { LPUG_BIT_DESC(GLOBL_UNMSK, NULL, NULL) } 40327Sjchu }; 40427Sjchu #define px_err_lpug_keys \ 40527Sjchu (sizeof (px_err_lpug_tbl)) / (sizeof (px_err_bit_desc_t)) 40627Sjchu 40727Sjchu 40827Sjchu /* Mask and Tables */ 40927Sjchu #define MnT6(pre) \ 41027Sjchu B_FALSE, \ 41127Sjchu &px_ ## pre ## _intr_mask, \ 41227Sjchu &px_ ## pre ## _log_mask, \ 41327Sjchu &px_ ## pre ## _count_mask, \ 41427Sjchu px_err_ ## pre ## _tbl, \ 41527Sjchu px_err_ ## pre ## _keys, \ 41627Sjchu 0 41727Sjchu 41827Sjchu /* LPU Registers Addresses */ 41927Sjchu #define LR4(pre) \ 42027Sjchu NULL, \ 42127Sjchu LPU_ ## pre ## _INTERRUPT_MASK, \ 42227Sjchu LPU_ ## pre ## _INTERRUPT_AND_STATUS, \ 42327Sjchu LPU_ ## pre ## _INTERRUPT_AND_STATUS 42427Sjchu 42527Sjchu /* LPU Registers Addresses with Irregularities */ 42627Sjchu #define LR4_FIXME(pre) \ 42727Sjchu NULL, \ 42827Sjchu LPU_ ## pre ## _INTERRUPT_MASK, \ 42927Sjchu LPU_ ## pre ## _LAYER_INTERRUPT_AND_STATUS, \ 43027Sjchu LPU_ ## pre ## _LAYER_INTERRUPT_AND_STATUS 43127Sjchu 43227Sjchu /* TLU Registers Addresses */ 43327Sjchu #define TR4(pre) \ 43427Sjchu TLU_ ## pre ## _LOG_ENABLE, \ 43527Sjchu TLU_ ## pre ## _INTERRUPT_ENABLE, \ 43627Sjchu TLU_ ## pre ## _INTERRUPT_STATUS, \ 43727Sjchu TLU_ ## pre ## _STATUS_CLEAR 43827Sjchu 43927Sjchu /* Registers Addresses for JBC, MMU, IMU and ILU */ 44027Sjchu #define R4(pre) \ 44127Sjchu pre ## _ERROR_LOG_ENABLE, \ 44227Sjchu pre ## _INTERRUPT_ENABLE, \ 44327Sjchu pre ## _INTERRUPT_STATUS, \ 44427Sjchu pre ## _ERROR_STATUS_CLEAR 44527Sjchu 44627Sjchu /* 44727Sjchu * Register error handling tables. 44827Sjchu * The ID Field (first field) is identified by an enum px_err_id_t. 44927Sjchu * It is located in px_err.h 45027Sjchu */ 45127Sjchu px_err_reg_desc_t px_err_reg_tbl[] = { 45227Sjchu { MnT6(cb), R4(JBC), "JBC Error"}, 453435Sjchu { MnT6(mmu), R4(MMU), "MMU Error"}, 454435Sjchu { MnT6(imu), R4(IMU), "IMU Error"}, 45527Sjchu { MnT6(tlu_ue), TR4(UNCORRECTABLE_ERROR), "TLU UE"}, 45627Sjchu { MnT6(tlu_ce), TR4(CORRECTABLE_ERROR), "TLU CE"}, 45727Sjchu { MnT6(tlu_oe), TR4(OTHER_EVENT), "TLU OE"}, 458435Sjchu { MnT6(ilu), R4(ILU), "ILU Error"}, 45927Sjchu { MnT6(lpul), LR4(LINK_LAYER), "LPU Link Layer"}, 46027Sjchu { MnT6(lpup), LR4_FIXME(PHY), "LPU Phy Layer"}, 46127Sjchu { MnT6(lpur), LR4(RECEIVE_PHY), "LPU RX Phy Layer"}, 46227Sjchu { MnT6(lpux), LR4(TRANSMIT_PHY), "LPU TX Phy Layer"}, 46327Sjchu { MnT6(lpus), LR4(LTSSM), "LPU LTSSM"}, 46427Sjchu { MnT6(lpug), LR4(GIGABLAZE_GLUE), "LPU GigaBlaze Glue"} 46527Sjchu }; 46627Sjchu #define PX_ERR_REG_KEYS (sizeof (px_err_reg_tbl)) / (sizeof (px_err_reg_tbl[0])) 46727Sjchu 46827Sjchu typedef struct px_err_ss { 46927Sjchu uint64_t err_status[PX_ERR_REG_KEYS]; 47027Sjchu } px_err_ss_t; 47127Sjchu 47227Sjchu static void px_err_snapshot(px_t *px_p, px_err_ss_t *ss, boolean_t chkjbc); 47327Sjchu static int px_err_erpt_and_clr(px_t *px_p, ddi_fm_error_t *derr, 47427Sjchu px_err_ss_t *ss); 47527Sjchu static int px_err_check_severity(px_t *px_p, ddi_fm_error_t *derr, 47627Sjchu int err, int caller); 47727Sjchu 47827Sjchu /* 47927Sjchu * px_err_cb_intr: 48027Sjchu * Interrupt handler for the JBC block. 48127Sjchu * o lock 48227Sjchu * o create derr 48327Sjchu * o px_err_handle(leaf1, with jbc) 48427Sjchu * o px_err_handle(leaf2, without jbc) 48527Sjchu * o dispatch (leaf1) 48627Sjchu * o dispatch (leaf2) 48727Sjchu * o unlock 48827Sjchu * o handle error: fatal? fm_panic() : return INTR_CLAIMED) 48927Sjchu */ 49027Sjchu uint_t 49127Sjchu px_err_cb_intr(caddr_t arg) 49227Sjchu { 49327Sjchu px_fault_t *px_fault_p = (px_fault_t *)arg; 49427Sjchu dev_info_t *rpdip = px_fault_p->px_fh_dip; 49527Sjchu px_t *px_p = DIP_TO_STATE(rpdip); 496118Sjchu int err = PX_OK; 497118Sjchu int ret = DDI_FM_OK; 49827Sjchu int fatal = 0; 49927Sjchu ddi_fm_error_t derr; 50027Sjchu 50127Sjchu /* Create the derr */ 50227Sjchu bzero(&derr, sizeof (ddi_fm_error_t)); 50327Sjchu derr.fme_version = DDI_FME_VERSION; 50427Sjchu derr.fme_ena = fm_ena_generate(0, FM_ENA_FMT1); 50527Sjchu derr.fme_flag = DDI_FM_ERR_UNEXPECTED; 50627Sjchu 507*1648Sjchu mutex_enter(&px_p->px_fm_mutex); 50827Sjchu 509*1648Sjchu err |= px_err_handle(px_p, &derr, PX_INTR_CALL, B_TRUE); 51027Sjchu 511*1648Sjchu ret = ndi_fm_handler_dispatch(rpdip, NULL, &derr); 512*1648Sjchu switch (ret) { 513*1648Sjchu case DDI_FM_FATAL: 514*1648Sjchu fatal++; 515*1648Sjchu break; 516*1648Sjchu case DDI_FM_NONFATAL: 517*1648Sjchu case DDI_FM_UNKNOWN: 518*1648Sjchu default: 519*1648Sjchu break; 52027Sjchu } 52127Sjchu 52227Sjchu /* Set the intr state to idle for the leaf that received the mondo */ 523*1648Sjchu 52427Sjchu (void) px_lib_intr_setstate(rpdip, px_fault_p->px_fh_sysino, 52527Sjchu INTR_IDLE_STATE); 52627Sjchu 527*1648Sjchu mutex_exit(&px_p->px_fm_mutex); 52827Sjchu 52927Sjchu /* 53027Sjchu * PX_FATAL_HW error is diagnosed after system recovered from 53127Sjchu * HW initiated reset, therefore no furthur handling is required. 53227Sjchu */ 53327Sjchu if (fatal || err & (PX_FATAL_GOS | PX_FATAL_SW)) 534677Sjchu PX_FM_PANIC("Fatal System Bus Error has occurred\n"); 53527Sjchu 53627Sjchu return (DDI_INTR_CLAIMED); 53727Sjchu } 53827Sjchu 53927Sjchu /* 54027Sjchu * px_err_dmc_pec_intr: 54127Sjchu * Interrupt handler for the DMC/PEC block. 54227Sjchu * o lock 54327Sjchu * o create derr 54427Sjchu * o px_err_handle(leaf, with jbc) 54527Sjchu * o dispatch (leaf) 54627Sjchu * o unlock 54727Sjchu * o handle error: fatal? fm_panic() : return INTR_CLAIMED) 54827Sjchu */ 54927Sjchu uint_t 55027Sjchu px_err_dmc_pec_intr(caddr_t arg) 55127Sjchu { 55227Sjchu px_fault_t *px_fault_p = (px_fault_t *)arg; 55327Sjchu dev_info_t *rpdip = px_fault_p->px_fh_dip; 55427Sjchu px_t *px_p = DIP_TO_STATE(rpdip); 555118Sjchu int err = PX_OK; 556118Sjchu int ret = DDI_FM_OK; 55727Sjchu ddi_fm_error_t derr; 55827Sjchu 55927Sjchu /* Create the derr */ 56027Sjchu bzero(&derr, sizeof (ddi_fm_error_t)); 56127Sjchu derr.fme_version = DDI_FME_VERSION; 56227Sjchu derr.fme_ena = fm_ena_generate(0, FM_ENA_FMT1); 56327Sjchu derr.fme_flag = DDI_FM_ERR_UNEXPECTED; 56427Sjchu 565*1648Sjchu mutex_enter(&px_p->px_fm_mutex); 56627Sjchu 56727Sjchu /* send ereport/handle/clear fire registers */ 56827Sjchu err |= px_err_handle(px_p, &derr, PX_INTR_CALL, B_TRUE); 56927Sjchu 57027Sjchu /* Check all child devices for errors */ 57127Sjchu ret = ndi_fm_handler_dispatch(rpdip, NULL, &derr); 57227Sjchu 57327Sjchu /* Set the interrupt state to idle */ 57427Sjchu (void) px_lib_intr_setstate(rpdip, px_fault_p->px_fh_sysino, 57527Sjchu INTR_IDLE_STATE); 57627Sjchu 577*1648Sjchu mutex_exit(&px_p->px_fm_mutex); 57827Sjchu 57927Sjchu /* 58027Sjchu * PX_FATAL_HW indicates a condition recovered from Fatal-Reset, 58127Sjchu * therefore it does not cause panic. 58227Sjchu */ 58327Sjchu if ((err & (PX_FATAL_GOS | PX_FATAL_SW)) || (ret == DDI_FM_FATAL)) 584677Sjchu PX_FM_PANIC("Fatal System Port Error has occurred\n"); 58527Sjchu 58627Sjchu return (DDI_INTR_CLAIMED); 58727Sjchu } 58827Sjchu 58927Sjchu /* 59027Sjchu * Error register are being handled by px_hlib xxx_init functions. 59127Sjchu * They are also called again by px_err_add_intr for mondo62 and 63 59227Sjchu * from px_cb_attach and px_attach 59327Sjchu */ 59427Sjchu void 59527Sjchu px_err_reg_enable(px_t *px_p, px_err_id_t id) 59627Sjchu { 59727Sjchu px_err_reg_desc_t *reg_desc = &px_err_reg_tbl[id]; 59827Sjchu uint64_t intr_mask = *reg_desc->intr_mask_p; 59927Sjchu uint64_t log_mask = *reg_desc->log_mask_p; 60027Sjchu caddr_t csr_base; 60127Sjchu pxu_t *pxu_p = (pxu_t *)px_p->px_plat_p; 60227Sjchu 60327Sjchu if (id == PX_ERR_JBC) 60427Sjchu csr_base = (caddr_t)pxu_p->px_address[PX_REG_XBC]; 60527Sjchu else 60627Sjchu csr_base = (caddr_t)pxu_p->px_address[PX_REG_CSR]; 60727Sjchu 60827Sjchu reg_desc->enabled = B_TRUE; 60927Sjchu 61027Sjchu /* Enable logs if it exists */ 61127Sjchu if (reg_desc->log_addr != NULL) 61227Sjchu CSR_XS(csr_base, reg_desc->log_addr, log_mask); 61327Sjchu 61427Sjchu /* 61527Sjchu * For readability you in code you set 1 to enable an interrupt. 61627Sjchu * But in Fire it's backwards. You set 1 to *disable* an intr. 61727Sjchu * Reverse the user tunable intr mask field. 61827Sjchu * 61927Sjchu * Disable All Errors 62027Sjchu * Clear All Errors 62127Sjchu * Enable Errors 62227Sjchu */ 62327Sjchu CSR_XS(csr_base, reg_desc->enable_addr, 0); 62427Sjchu CSR_XS(csr_base, reg_desc->clear_addr, -1); 62527Sjchu CSR_XS(csr_base, reg_desc->enable_addr, intr_mask); 62627Sjchu DBG(DBG_ATTACH, NULL, "%s Mask: 0x%llx\n", 62727Sjchu reg_desc->msg, CSR_XR(csr_base, reg_desc->enable_addr)); 62827Sjchu DBG(DBG_ATTACH, NULL, "%s Status: 0x%llx\n", 62927Sjchu reg_desc->msg, CSR_XR(csr_base, reg_desc->status_addr)); 63027Sjchu DBG(DBG_ATTACH, NULL, "%s Clear: 0x%llx\n", 63127Sjchu reg_desc->msg, CSR_XR(csr_base, reg_desc->clear_addr)); 63227Sjchu if (reg_desc->log_addr != NULL) { 63327Sjchu DBG(DBG_ATTACH, NULL, "%s Log: 0x%llx\n", 63427Sjchu reg_desc->msg, CSR_XR(csr_base, reg_desc->log_addr)); 63527Sjchu } 63627Sjchu } 63727Sjchu 63827Sjchu void 63927Sjchu px_err_reg_disable(px_t *px_p, px_err_id_t id) 64027Sjchu { 64127Sjchu px_err_reg_desc_t *reg_desc = &px_err_reg_tbl[id]; 64227Sjchu caddr_t csr_base; 643693Sgovinda pxu_t *pxu_p = (pxu_t *)px_p->px_plat_p; 64427Sjchu 64527Sjchu if (id == PX_ERR_JBC) 646693Sgovinda csr_base = (caddr_t)(uintptr_t)pxu_p->px_address[PX_REG_XBC]; 64727Sjchu else 648693Sgovinda csr_base = (caddr_t)(uintptr_t)pxu_p->px_address[PX_REG_CSR]; 64927Sjchu 65027Sjchu reg_desc->enabled = B_FALSE; 65127Sjchu 65227Sjchu switch (id) { 65327Sjchu case PX_ERR_JBC: 65427Sjchu case PX_ERR_MMU: 65527Sjchu case PX_ERR_IMU: 65627Sjchu case PX_ERR_TLU_UE: 65727Sjchu case PX_ERR_TLU_CE: 65827Sjchu case PX_ERR_TLU_OE: 65927Sjchu case PX_ERR_ILU: 66027Sjchu if (reg_desc->log_addr != NULL) { 66127Sjchu CSR_XS(csr_base, reg_desc->log_addr, 0); 66227Sjchu } 66327Sjchu CSR_XS(csr_base, reg_desc->enable_addr, 0); 66427Sjchu break; 66527Sjchu case PX_ERR_LPU_LINK: 66627Sjchu case PX_ERR_LPU_PHY: 66727Sjchu case PX_ERR_LPU_RX: 66827Sjchu case PX_ERR_LPU_TX: 66927Sjchu case PX_ERR_LPU_LTSSM: 67027Sjchu case PX_ERR_LPU_GIGABLZ: 67127Sjchu if (reg_desc->log_addr != NULL) { 67227Sjchu CSR_XS(csr_base, reg_desc->log_addr, -1); 67327Sjchu } 67427Sjchu CSR_XS(csr_base, reg_desc->enable_addr, -1); 67527Sjchu break; 67627Sjchu } 67727Sjchu } 67827Sjchu 67927Sjchu /* 68027Sjchu * px_err_handle: 68127Sjchu * Common function called by trap, mondo and fabric intr. 68227Sjchu * o Snap shot current fire registers 68327Sjchu * o check for safe access 68427Sjchu * o send ereport and clear snap shot registers 68527Sjchu * o check severity of snap shot registers 68627Sjchu * 68727Sjchu * @param px_p leaf in which to check access 68827Sjchu * @param derr fm err data structure to be updated 68927Sjchu * @param caller PX_TRAP_CALL | PX_INTR_CALL 69027Sjchu * @param chkjbc whether to handle jbc registers 69127Sjchu * @return err PX_OK | PX_NONFATAL | 69227Sjchu * PX_FATAL_GOS | PX_FATAL_HW | PX_STUCK_FATAL 69327Sjchu */ 69427Sjchu int 69527Sjchu px_err_handle(px_t *px_p, ddi_fm_error_t *derr, int caller, 69627Sjchu boolean_t chkjbc) 69727Sjchu { 69827Sjchu px_err_ss_t ss; 699118Sjchu int err = PX_OK; 70027Sjchu 701*1648Sjchu ASSERT(MUTEX_HELD(&px_p->px_fm_mutex)); 70227Sjchu 70327Sjchu /* snap shot the current fire registers */ 70427Sjchu px_err_snapshot(px_p, &ss, chkjbc); 70527Sjchu 70627Sjchu /* check for safe access */ 70727Sjchu px_err_safeacc_check(px_p, derr); 70827Sjchu 70927Sjchu /* send ereports/handle/clear registers */ 71027Sjchu err = px_err_erpt_and_clr(px_p, derr, &ss); 71127Sjchu 71227Sjchu /* check for error severity */ 71327Sjchu err = px_err_check_severity(px_p, derr, err, caller); 71427Sjchu 71527Sjchu /* Mark the On Trap Handle if an error occured */ 71627Sjchu if (err != PX_OK) { 71727Sjchu px_pec_t *pec_p = px_p->px_pec_p; 71827Sjchu on_trap_data_t *otd = pec_p->pec_ontrap_data; 71927Sjchu 720118Sjchu if ((otd != NULL) && (otd->ot_prot & OT_DATA_ACCESS)) 72127Sjchu otd->ot_trap |= OT_DATA_ACCESS; 72227Sjchu } 72327Sjchu 72427Sjchu return (err); 72527Sjchu } 72627Sjchu 72727Sjchu /* 72827Sjchu * Static function 72927Sjchu */ 73027Sjchu 73127Sjchu /* 73227Sjchu * px_err_snapshot: 73327Sjchu * Take a current snap shot of all the fire error registers. This includes 73427Sjchu * JBC, DMC, and PEC, unless chkjbc == false; 73527Sjchu * 73627Sjchu * @param px_p leaf in which to take the snap shot. 73727Sjchu * @param ss pre-allocated memory to store the snap shot. 73827Sjchu * @param chkjbc boolean on whether to store jbc register. 73927Sjchu */ 74027Sjchu static void 74127Sjchu px_err_snapshot(px_t *px_p, px_err_ss_t *ss, boolean_t chkjbc) 74227Sjchu { 74327Sjchu pxu_t *pxu_p = (pxu_t *)px_p->px_plat_p; 74427Sjchu caddr_t xbc_csr_base = (caddr_t)pxu_p->px_address[PX_REG_XBC]; 74527Sjchu caddr_t pec_csr_base = (caddr_t)pxu_p->px_address[PX_REG_CSR]; 74627Sjchu px_err_reg_desc_t *reg_desc; 74727Sjchu int reg_id; 74827Sjchu 74927Sjchu /* snapshot JBC interrupt status */ 75027Sjchu reg_id = PX_ERR_JBC; 75127Sjchu if (chkjbc == B_TRUE) { 75227Sjchu reg_desc = &px_err_reg_tbl[reg_id]; 75327Sjchu ss->err_status[reg_id] = CSR_XR(xbc_csr_base, 75427Sjchu reg_desc->status_addr); 75527Sjchu } else { 75627Sjchu ss->err_status[reg_id] = 0; 75727Sjchu } 75827Sjchu 75927Sjchu /* snapshot DMC/PEC interrupt status */ 76027Sjchu for (reg_id = 1; reg_id < PX_ERR_REG_KEYS; reg_id += 1) { 76127Sjchu reg_desc = &px_err_reg_tbl[reg_id]; 76227Sjchu ss->err_status[reg_id] = CSR_XR(pec_csr_base, 76327Sjchu reg_desc->status_addr); 76427Sjchu } 76527Sjchu } 76627Sjchu 76727Sjchu /* 76827Sjchu * px_err_erpt_and_clr: 76927Sjchu * This function does the following thing to all the fire registers based 77027Sjchu * on an earlier snap shot. 77127Sjchu * o Send ereport 77227Sjchu * o Handle the error 77327Sjchu * o Clear the error 77427Sjchu * 77527Sjchu * @param px_p leaf in which to take the snap shot. 77627Sjchu * @param derr fm err in which the ereport is to be based on 77727Sjchu * @param ss pre-allocated memory to store the snap shot. 77827Sjchu */ 77927Sjchu static int 78027Sjchu px_err_erpt_and_clr(px_t *px_p, ddi_fm_error_t *derr, px_err_ss_t *ss) 78127Sjchu { 78227Sjchu dev_info_t *rpdip = px_p->px_dip; 78327Sjchu pxu_t *pxu_p = (pxu_t *)px_p->px_plat_p; 78427Sjchu caddr_t csr_base; 78527Sjchu px_err_reg_desc_t *err_reg_tbl; 78627Sjchu px_err_bit_desc_t *err_bit_tbl; 78727Sjchu px_err_bit_desc_t *err_bit_desc; 78827Sjchu 78927Sjchu uint64_t *log_mask, *count_mask; 79027Sjchu uint64_t status_addr, clear_addr; 79127Sjchu uint64_t ss_reg; 79227Sjchu 79327Sjchu int (*err_handler)(); 79427Sjchu int (*erpt_handler)(); 79527Sjchu int reg_id, key; 79627Sjchu int err = PX_OK; 7971147Sjchu int biterr; 79827Sjchu 799*1648Sjchu ASSERT(MUTEX_HELD(&px_p->px_fm_mutex)); 80027Sjchu 80127Sjchu /* send erport/handle/clear JBC errors */ 80227Sjchu for (reg_id = 0; reg_id < PX_ERR_REG_KEYS; reg_id += 1) { 80327Sjchu /* Get the correct register description table */ 80427Sjchu err_reg_tbl = &px_err_reg_tbl[reg_id]; 80527Sjchu 80627Sjchu /* Get the correct CSR BASE */ 80727Sjchu if (reg_id == PX_ERR_JBC) { 80827Sjchu csr_base = (caddr_t)pxu_p->px_address[PX_REG_XBC]; 80927Sjchu } else { 81027Sjchu csr_base = (caddr_t)pxu_p->px_address[PX_REG_CSR]; 81127Sjchu } 81227Sjchu 81327Sjchu /* Get pointers to masks and register addresses */ 81427Sjchu log_mask = err_reg_tbl->log_mask_p; 81527Sjchu count_mask = err_reg_tbl->count_mask_p; 81627Sjchu status_addr = err_reg_tbl->status_addr; 81727Sjchu clear_addr = err_reg_tbl->clear_addr; 81827Sjchu ss_reg = ss->err_status[reg_id]; 81927Sjchu 82027Sjchu /* Get the register BIT description table */ 82127Sjchu err_bit_tbl = err_reg_tbl->err_bit_tbl; 82227Sjchu 82327Sjchu /* For each known bit in the register send erpt and handle */ 82427Sjchu for (key = 0; key < err_reg_tbl->err_bit_keys; key += 1) { 82527Sjchu /* Get the bit description table for this register */ 82627Sjchu err_bit_desc = &err_bit_tbl[key]; 82727Sjchu 82827Sjchu /* 82927Sjchu * If the ss_reg is set for this bit, 83027Sjchu * send ereport and handle 83127Sjchu */ 83227Sjchu if (BIT_TST(ss_reg, err_bit_desc->bit)) { 83327Sjchu /* Increment the counter if necessary */ 83427Sjchu if (BIT_TST(*count_mask, err_bit_desc->bit)) { 83527Sjchu err_bit_desc->counter++; 83627Sjchu } 83727Sjchu 83827Sjchu /* Error Handle for this bit */ 83927Sjchu err_handler = err_bit_desc->err_handler; 8401147Sjchu if (err_handler) { 8411147Sjchu biterr = err_handler(rpdip, 84227Sjchu csr_base, 84327Sjchu derr, 84427Sjchu err_reg_tbl, 84527Sjchu err_bit_desc); 8461147Sjchu err |= biterr; 8471147Sjchu } 84827Sjchu 849383Set142600 /* Send the ereport if it's an UNEXPECTED err */ 85027Sjchu erpt_handler = err_bit_desc->erpt_handler; 8511147Sjchu if ((derr->fme_flag == DDI_FM_ERR_UNEXPECTED) && 8521147Sjchu (biterr != PX_OK)) { 853383Set142600 if (erpt_handler) 854383Set142600 (void) erpt_handler(rpdip, 855383Set142600 csr_base, 856383Set142600 ss_reg, 857383Set142600 derr, 858739Sjchu err_bit_desc->bit, 859383Set142600 err_bit_desc->class_name); 860383Set142600 } 86127Sjchu } 862383Set142600 86327Sjchu } 864332Sjchu 865332Sjchu /* Print register status */ 866332Sjchu if (ss_reg & *log_mask) 867332Sjchu DBG(DBG_ERR_INTR, rpdip, "<%x>=%16llx %s\n", 86827Sjchu status_addr, ss_reg, err_reg_tbl->msg); 86927Sjchu 87027Sjchu /* Clear the register and error */ 87127Sjchu CSR_XS(csr_base, clear_addr, ss_reg); 87227Sjchu } 87327Sjchu 87427Sjchu return (err); 87527Sjchu } 87627Sjchu 87727Sjchu /* 87827Sjchu * px_err_check_severity: 87927Sjchu * Check the severity of the fire error based on an earlier snapshot 88027Sjchu * 88127Sjchu * @param px_p leaf in which to take the snap shot. 88227Sjchu * @param derr fm err in which the ereport is to be based on 88327Sjchu * @param ss pre-allocated memory to store the snap shot. 88427Sjchu */ 88527Sjchu static int 88627Sjchu px_err_check_severity(px_t *px_p, ddi_fm_error_t *derr, int err, int caller) 88727Sjchu { 88827Sjchu px_pec_t *pec_p = px_p->px_pec_p; 88927Sjchu boolean_t is_safeacc = B_FALSE; 890118Sjchu 891118Sjchu /* nothing to do if called with no error */ 892118Sjchu if (err == PX_OK) 893118Sjchu return (err); 89427Sjchu 89527Sjchu /* Cautious access error handling */ 89627Sjchu switch (derr->fme_flag) { 89727Sjchu case DDI_FM_ERR_EXPECTED: 89827Sjchu if (caller == PX_TRAP_CALL) { 89927Sjchu /* 90027Sjchu * for ddi_caut_get treat all events as nonfatal 90127Sjchu * The trampoline will set err_ena = 0, 90227Sjchu * err_status = NONFATAL. 90327Sjchu */ 90427Sjchu derr->fme_status = DDI_FM_NONFATAL; 90527Sjchu is_safeacc = B_TRUE; 90627Sjchu } else { 90727Sjchu /* 90827Sjchu * For ddi_caut_put treat all events as nonfatal. Here 90927Sjchu * we have the handle and can call ndi_fm_acc_err_set(). 91027Sjchu */ 91127Sjchu derr->fme_status = DDI_FM_NONFATAL; 91227Sjchu ndi_fm_acc_err_set(pec_p->pec_acc_hdl, derr); 91327Sjchu is_safeacc = B_TRUE; 91427Sjchu } 91527Sjchu break; 91627Sjchu case DDI_FM_ERR_PEEK: 91727Sjchu case DDI_FM_ERR_POKE: 91827Sjchu /* 91927Sjchu * For ddi_peek/poke treat all events as nonfatal. 92027Sjchu */ 92127Sjchu is_safeacc = B_TRUE; 92227Sjchu break; 92327Sjchu default: 92427Sjchu is_safeacc = B_FALSE; 92527Sjchu } 92627Sjchu 92727Sjchu /* 92827Sjchu * The third argument "err" is passed in as error status from checking 92927Sjchu * Fire register, re-adjust error status from safe access. 93027Sjchu */ 93127Sjchu if (is_safeacc && !(err & PX_FATAL_GOS)) 932118Sjchu return (PX_NONFATAL); 93327Sjchu 934118Sjchu return (err); 93527Sjchu } 93627Sjchu 93727Sjchu /* predefined convenience functions */ 93827Sjchu /* ARGSUSED */ 93927Sjchu int 94027Sjchu px_err_fatal_hw_handle(dev_info_t *rpdip, caddr_t csr_base, 94127Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 94227Sjchu px_err_bit_desc_t *err_bit_descr) 94327Sjchu { 94427Sjchu return (PX_FATAL_HW); 94527Sjchu } 94627Sjchu 94727Sjchu /* ARGSUSED */ 94827Sjchu int 94927Sjchu px_err_fatal_gos_handle(dev_info_t *rpdip, caddr_t csr_base, 95027Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 95127Sjchu px_err_bit_desc_t *err_bit_descr) 95227Sjchu { 95327Sjchu return (PX_FATAL_GOS); 95427Sjchu } 95527Sjchu 95627Sjchu /* ARGSUSED */ 95727Sjchu int 95827Sjchu px_err_fatal_stuck_handle(dev_info_t *rpdip, caddr_t csr_base, 95927Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 96027Sjchu px_err_bit_desc_t *err_bit_descr) 96127Sjchu { 96227Sjchu return (PX_STUCK_FATAL); 96327Sjchu } 96427Sjchu 96527Sjchu /* ARGSUSED */ 96627Sjchu int 96727Sjchu px_err_fatal_sw_handle(dev_info_t *rpdip, caddr_t csr_base, 96827Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 96927Sjchu px_err_bit_desc_t *err_bit_descr) 97027Sjchu { 97127Sjchu return (PX_FATAL_SW); 97227Sjchu } 97327Sjchu 97427Sjchu /* ARGSUSED */ 97527Sjchu int 97627Sjchu px_err_non_fatal_handle(dev_info_t *rpdip, caddr_t csr_base, 97727Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 97827Sjchu px_err_bit_desc_t *err_bit_descr) 97927Sjchu { 98027Sjchu return (PX_NONFATAL); 98127Sjchu } 98227Sjchu 98327Sjchu /* ARGSUSED */ 98427Sjchu int 98527Sjchu px_err_ok_handle(dev_info_t *rpdip, caddr_t csr_base, ddi_fm_error_t *derr, 98627Sjchu px_err_reg_desc_t *err_reg_descr, px_err_bit_desc_t *err_bit_descr) 98727Sjchu { 98827Sjchu return (PX_OK); 98927Sjchu } 99027Sjchu 99127Sjchu /* ARGSUSED */ 99227Sjchu int 99327Sjchu px_err_unknown_handle(dev_info_t *rpdip, caddr_t csr_base, ddi_fm_error_t *derr, 99427Sjchu px_err_reg_desc_t *err_reg_descr, px_err_bit_desc_t *err_bit_descr) 99527Sjchu { 99627Sjchu return (PX_ERR_UNKNOWN); 99727Sjchu } 99827Sjchu 999383Set142600 /* ARGSUSED */ 1000383Set142600 PX_ERPT_SEND_DEC(do_not) 1001383Set142600 { 1002383Set142600 return (PX_OK); 1003383Set142600 } 1004383Set142600 1005383Set142600 100627Sjchu /* JBC FATAL - see io erpt doc, section 1.1 */ 100727Sjchu PX_ERPT_SEND_DEC(jbc_fatal) 100827Sjchu { 100927Sjchu char buf[FM_MAX_CLASS]; 1010739Sjchu boolean_t pri = PX_ERR_IS_PRI(bit); 101127Sjchu 101227Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 101327Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 101427Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 1015739Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri, 101627Sjchu FIRE_JBC_ELE, DATA_TYPE_UINT64, 101727Sjchu CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE), 101827Sjchu FIRE_JBC_IE, DATA_TYPE_UINT64, 101927Sjchu CSR_XR(csr_base, JBC_INTERRUPT_ENABLE), 102027Sjchu FIRE_JBC_IS, DATA_TYPE_UINT64, 102127Sjchu ss_reg, 102227Sjchu FIRE_JBC_ESS, DATA_TYPE_UINT64, 102327Sjchu CSR_XR(csr_base, JBC_ERROR_STATUS_SET), 102427Sjchu FIRE_JBC_FEL1, DATA_TYPE_UINT64, 102527Sjchu CSR_XR(csr_base, FATAL_ERROR_LOG_1), 102627Sjchu FIRE_JBC_FEL2, DATA_TYPE_UINT64, 102727Sjchu CSR_XR(csr_base, FATAL_ERROR_LOG_2), 102827Sjchu NULL); 102927Sjchu 103027Sjchu return (PX_OK); 103127Sjchu } 103227Sjchu 103327Sjchu /* JBC MERGE - see io erpt doc, section 1.2 */ 103427Sjchu PX_ERPT_SEND_DEC(jbc_merge) 103527Sjchu { 103627Sjchu char buf[FM_MAX_CLASS]; 1037739Sjchu boolean_t pri = PX_ERR_IS_PRI(bit); 103827Sjchu 103927Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 104027Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 104127Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 1042739Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri, 104327Sjchu FIRE_JBC_ELE, DATA_TYPE_UINT64, 104427Sjchu CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE), 104527Sjchu FIRE_JBC_IE, DATA_TYPE_UINT64, 104627Sjchu CSR_XR(csr_base, JBC_INTERRUPT_ENABLE), 104727Sjchu FIRE_JBC_IS, DATA_TYPE_UINT64, 104827Sjchu ss_reg, 104927Sjchu FIRE_JBC_ESS, DATA_TYPE_UINT64, 105027Sjchu CSR_XR(csr_base, JBC_ERROR_STATUS_SET), 105127Sjchu FIRE_JBC_MTEL, DATA_TYPE_UINT64, 105227Sjchu CSR_XR(csr_base, MERGE_TRANSACTION_ERROR_LOG), 105327Sjchu NULL); 105427Sjchu 105527Sjchu return (PX_OK); 105627Sjchu } 105727Sjchu 105827Sjchu /* 105927Sjchu * JBC Merge buffer nonfatal errors: 106027Sjchu * Merge buffer parity error (rd_buf): dma:read:M:nonfatal 106127Sjchu * Merge buffer parity error (wr_buf): dma:write:M:nonfatal 106227Sjchu */ 106327Sjchu /* ARGSUSED */ 106427Sjchu int 106527Sjchu px_err_jbc_merge_handle(dev_info_t *rpdip, caddr_t csr_base, 106627Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 106727Sjchu px_err_bit_desc_t *err_bit_descr) 106827Sjchu { 1069739Sjchu boolean_t pri = PX_ERR_IS_PRI(err_bit_descr->bit); 107027Sjchu uint64_t paddr; 107127Sjchu int ret; 107227Sjchu 1073739Sjchu if (!pri) 1074739Sjchu return (PX_FATAL_GOS); 1075739Sjchu 107627Sjchu paddr = CSR_XR(csr_base, MERGE_TRANSACTION_ERROR_LOG); 107727Sjchu paddr &= MERGE_TRANSACTION_ERROR_LOG_ADDRESS_MASK; 107827Sjchu 107927Sjchu ret = px_handle_lookup( 108027Sjchu rpdip, DMA_HANDLE, derr->fme_ena, (void *)paddr); 108127Sjchu 108227Sjchu return ((ret == DDI_FM_FATAL) ? PX_FATAL_GOS : PX_NONFATAL); 108327Sjchu } 108427Sjchu 108527Sjchu /* JBC Jbusint IN - see io erpt doc, section 1.3 */ 108627Sjchu PX_ERPT_SEND_DEC(jbc_in) 108727Sjchu { 108827Sjchu char buf[FM_MAX_CLASS]; 1089739Sjchu boolean_t pri = PX_ERR_IS_PRI(bit); 109027Sjchu 109127Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 109227Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 109327Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 1094739Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri, 109527Sjchu FIRE_JBC_ELE, DATA_TYPE_UINT64, 109627Sjchu CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE), 109727Sjchu FIRE_JBC_IE, DATA_TYPE_UINT64, 109827Sjchu CSR_XR(csr_base, JBC_INTERRUPT_ENABLE), 109927Sjchu FIRE_JBC_IS, DATA_TYPE_UINT64, 110027Sjchu ss_reg, 110127Sjchu FIRE_JBC_ESS, DATA_TYPE_UINT64, 110227Sjchu CSR_XR(csr_base, JBC_ERROR_STATUS_SET), 110327Sjchu FIRE_JBC_JITEL1, DATA_TYPE_UINT64, 110427Sjchu CSR_XR(csr_base, JBCINT_IN_TRANSACTION_ERROR_LOG), 110527Sjchu FIRE_JBC_JITEL2, DATA_TYPE_UINT64, 110627Sjchu CSR_XR(csr_base, JBCINT_IN_TRANSACTION_ERROR_LOG_2), 110727Sjchu NULL); 110827Sjchu 110927Sjchu return (PX_OK); 111027Sjchu } 111127Sjchu 111227Sjchu /* 111327Sjchu * JBC Jbusint IN nonfatal errors: PA logged in Jbusint In Transaction Error 111427Sjchu * Log Reg[42:0]. 111527Sjchu * CE async fault error: nonfatal 111627Sjchu * Jbus bus error: dma::nonfatal 111727Sjchu * Jbus unmapped error: pio|dma:rdwr:M:nonfatal 111827Sjchu * Write data parity error: pio/write:M:nonfatal 111927Sjchu * Read data parity error: pio/read:M:nonfatal 112027Sjchu * Illegal NCWR bytemask: pio:write:M:nonfatal 112127Sjchu * Illegal NCRD bytemask: pio:write:M:nonfatal 112227Sjchu * Invalid jbus transaction: nonfatal 112327Sjchu */ 112427Sjchu /* ARGSUSED */ 112527Sjchu int 112627Sjchu px_err_jbc_jbusint_in_handle(dev_info_t *rpdip, caddr_t csr_base, 112727Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 112827Sjchu px_err_bit_desc_t *err_bit_descr) 112927Sjchu { 1130739Sjchu boolean_t pri = PX_ERR_IS_PRI(err_bit_descr->bit); 113127Sjchu uint64_t paddr; 113227Sjchu int ret; 113327Sjchu 1134739Sjchu if (!pri) 1135739Sjchu return (PX_FATAL_GOS); 1136739Sjchu 113727Sjchu paddr = CSR_XR(csr_base, JBCINT_IN_TRANSACTION_ERROR_LOG); 113827Sjchu paddr &= JBCINT_IN_TRANSACTION_ERROR_LOG_ADDRESS_MASK; 113927Sjchu 114027Sjchu ret = px_handle_lookup( 114127Sjchu rpdip, DMA_HANDLE, derr->fme_ena, (void *)paddr); 114227Sjchu 114327Sjchu return ((ret == DDI_FM_FATAL) ? PX_FATAL_GOS : PX_NONFATAL); 114427Sjchu } 114527Sjchu 114627Sjchu 114727Sjchu /* JBC Jbusint Out - see io erpt doc, section 1.4 */ 114827Sjchu PX_ERPT_SEND_DEC(jbc_out) 114927Sjchu { 115027Sjchu char buf[FM_MAX_CLASS]; 1151739Sjchu boolean_t pri = PX_ERR_IS_PRI(bit); 115227Sjchu 115327Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 115427Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 115527Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 1156739Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri, 115727Sjchu FIRE_JBC_ELE, DATA_TYPE_UINT64, 115827Sjchu CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE), 115927Sjchu FIRE_JBC_IE, DATA_TYPE_UINT64, 116027Sjchu CSR_XR(csr_base, JBC_INTERRUPT_ENABLE), 116127Sjchu FIRE_JBC_IS, DATA_TYPE_UINT64, 116227Sjchu ss_reg, 116327Sjchu FIRE_JBC_ESS, DATA_TYPE_UINT64, 116427Sjchu CSR_XR(csr_base, JBC_ERROR_STATUS_SET), 116527Sjchu FIRE_JBC_JOTEL1, DATA_TYPE_UINT64, 116627Sjchu CSR_XR(csr_base, JBCINT_OUT_TRANSACTION_ERROR_LOG), 116727Sjchu FIRE_JBC_JOTEL2, DATA_TYPE_UINT64, 116827Sjchu CSR_XR(csr_base, JBCINT_OUT_TRANSACTION_ERROR_LOG_2), 116927Sjchu NULL); 117027Sjchu 117127Sjchu return (PX_OK); 117227Sjchu } 117327Sjchu 117427Sjchu /* JBC Dmcint ODCD - see io erpt doc, section 1.5 */ 117527Sjchu PX_ERPT_SEND_DEC(jbc_odcd) 117627Sjchu { 117727Sjchu char buf[FM_MAX_CLASS]; 1178739Sjchu boolean_t pri = PX_ERR_IS_PRI(bit); 117927Sjchu 118027Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 118127Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 118227Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 1183739Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri, 118427Sjchu FIRE_JBC_ELE, DATA_TYPE_UINT64, 118527Sjchu CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE), 118627Sjchu FIRE_JBC_IE, DATA_TYPE_UINT64, 118727Sjchu CSR_XR(csr_base, JBC_INTERRUPT_ENABLE), 118827Sjchu FIRE_JBC_IS, DATA_TYPE_UINT64, 118927Sjchu ss_reg, 119027Sjchu FIRE_JBC_ESS, DATA_TYPE_UINT64, 119127Sjchu CSR_XR(csr_base, JBC_ERROR_STATUS_SET), 119227Sjchu FIRE_JBC_DMC_ODCD, DATA_TYPE_UINT64, 119327Sjchu CSR_XR(csr_base, DMCINT_ODCD_ERROR_LOG), 119427Sjchu NULL); 119527Sjchu 119627Sjchu return (PX_OK); 119727Sjchu } 119827Sjchu 119927Sjchu /* 120027Sjchu * JBC Dmcint ODCO nonfatal errer handling - 120127Sjchu * Unmapped PIO read error: pio:read:M:nonfatal 120227Sjchu * Unmapped PIO write error: pio:write:M:nonfatal 120327Sjchu * PIO data parity error: pio:write:M:nonfatal 120427Sjchu * Invalid PIO write to PCIe cfg/io, csr, ebus or i2c bus: pio:write:nonfatal 120527Sjchu * Invalid PIO read to PCIe cfg/io, csr, ebus or i2c bus: pio:read:nonfatal 120627Sjchu */ 120727Sjchu /* ARGSUSED */ 120827Sjchu int 120927Sjchu px_err_jbc_dmcint_odcd_handle(dev_info_t *rpdip, caddr_t csr_base, 121027Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 121127Sjchu px_err_bit_desc_t *err_bit_descr) 121227Sjchu { 1213739Sjchu boolean_t pri = PX_ERR_IS_PRI(err_bit_descr->bit); 121427Sjchu uint64_t paddr; 121527Sjchu int ret; 121627Sjchu 1217739Sjchu if (!pri) 1218739Sjchu return (PX_FATAL_GOS); 1219739Sjchu 122027Sjchu paddr = CSR_XR(csr_base, DMCINT_ODCD_ERROR_LOG); 122127Sjchu paddr &= DMCINT_ODCD_ERROR_LOG_ADDRESS_MASK; 122227Sjchu 122327Sjchu ret = px_handle_lookup( 122427Sjchu rpdip, DMA_HANDLE, derr->fme_ena, (void *)paddr); 122527Sjchu 122627Sjchu return ((ret == DDI_FM_FATAL) ? PX_FATAL_GOS : PX_NONFATAL); 122727Sjchu } 122827Sjchu 122927Sjchu /* JBC Dmcint IDC - see io erpt doc, section 1.6 */ 123027Sjchu PX_ERPT_SEND_DEC(jbc_idc) 123127Sjchu { 123227Sjchu char buf[FM_MAX_CLASS]; 1233739Sjchu boolean_t pri = PX_ERR_IS_PRI(bit); 123427Sjchu 123527Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 123627Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 123727Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 1238739Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri, 123927Sjchu FIRE_JBC_ELE, DATA_TYPE_UINT64, 124027Sjchu CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE), 124127Sjchu FIRE_JBC_IE, DATA_TYPE_UINT64, 124227Sjchu CSR_XR(csr_base, JBC_INTERRUPT_ENABLE), 124327Sjchu FIRE_JBC_IS, DATA_TYPE_UINT64, 124427Sjchu ss_reg, 124527Sjchu FIRE_JBC_ESS, DATA_TYPE_UINT64, 124627Sjchu CSR_XR(csr_base, JBC_ERROR_STATUS_SET), 124727Sjchu FIRE_JBC_DMC_IDC, DATA_TYPE_UINT64, 124827Sjchu CSR_XR(csr_base, DMCINT_IDC_ERROR_LOG), 124927Sjchu NULL); 125027Sjchu 125127Sjchu return (PX_OK); 125227Sjchu } 125327Sjchu 125427Sjchu /* JBC CSR - see io erpt doc, section 1.7 */ 125527Sjchu PX_ERPT_SEND_DEC(jbc_csr) 125627Sjchu { 125727Sjchu char buf[FM_MAX_CLASS]; 1258739Sjchu boolean_t pri = PX_ERR_IS_PRI(bit); 125927Sjchu 126027Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 126127Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 126227Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 1263739Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri, 126427Sjchu FIRE_JBC_ELE, DATA_TYPE_UINT64, 126527Sjchu CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE), 126627Sjchu FIRE_JBC_IE, DATA_TYPE_UINT64, 126727Sjchu CSR_XR(csr_base, JBC_INTERRUPT_ENABLE), 126827Sjchu FIRE_JBC_IS, DATA_TYPE_UINT64, 126927Sjchu ss_reg, 127027Sjchu FIRE_JBC_ESS, DATA_TYPE_UINT64, 127127Sjchu CSR_XR(csr_base, JBC_ERROR_STATUS_SET), 127227Sjchu "jbc-error-reg", DATA_TYPE_UINT64, 127327Sjchu CSR_XR(csr_base, CSR_ERROR_LOG), 127427Sjchu NULL); 127527Sjchu 127627Sjchu return (PX_OK); 127727Sjchu } 127827Sjchu 127927Sjchu /* 128027Sjchu * JBC CSR errer handling - 128127Sjchu * Ebus ready timeout error: pio:rdwr:M:nonfatal 128227Sjchu */ 128327Sjchu /* ARGSUSED */ 128427Sjchu int 128527Sjchu px_err_jbc_csr_handle(dev_info_t *rpdip, caddr_t csr_base, 128627Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 128727Sjchu px_err_bit_desc_t *err_bit_descr) 128827Sjchu { 1289739Sjchu boolean_t pri = PX_ERR_IS_PRI(err_bit_descr->bit); 129027Sjchu uint64_t paddr; 129127Sjchu int ret; 129227Sjchu 1293739Sjchu if (!pri) 1294739Sjchu return (PX_FATAL_GOS); 1295739Sjchu 129627Sjchu paddr = CSR_XR(csr_base, CSR_ERROR_LOG); 129727Sjchu paddr &= CSR_ERROR_LOG_ADDRESS_MASK; 129827Sjchu 129927Sjchu ret = px_handle_lookup( 130027Sjchu rpdip, DMA_HANDLE, derr->fme_ena, (void *)paddr); 130127Sjchu 130227Sjchu return ((ret == DDI_FM_FATAL) ? PX_FATAL_GOS : PX_NONFATAL); 130327Sjchu } 130427Sjchu 130527Sjchu /* JBC Dmcint IDC - see io erpt doc, section 1.6 */ 130627Sjchu 130727Sjchu /* DMC IMU RDS - see io erpt doc, section 2.1 */ 130827Sjchu PX_ERPT_SEND_DEC(imu_rds) 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_IMU_ELE, DATA_TYPE_UINT64, 131827Sjchu CSR_XR(csr_base, IMU_ERROR_LOG_ENABLE), 131927Sjchu FIRE_IMU_IE, DATA_TYPE_UINT64, 132027Sjchu CSR_XR(csr_base, IMU_INTERRUPT_ENABLE), 132127Sjchu FIRE_IMU_IS, DATA_TYPE_UINT64, 132227Sjchu ss_reg, 132327Sjchu FIRE_IMU_ESS, DATA_TYPE_UINT64, 132427Sjchu CSR_XR(csr_base, IMU_ERROR_STATUS_SET), 132527Sjchu FIRE_IMU_RDS, DATA_TYPE_UINT64, 132627Sjchu CSR_XR(csr_base, IMU_RDS_ERROR_LOG), 132727Sjchu NULL); 132827Sjchu 132927Sjchu return (PX_OK); 133027Sjchu } 133127Sjchu 133227Sjchu /* imu function to handle all Received but Not Enabled errors */ 133327Sjchu /* ARGSUSED */ 133427Sjchu int 133527Sjchu px_err_imu_rbne_handle(dev_info_t *rpdip, caddr_t csr_base, 133627Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 133727Sjchu px_err_bit_desc_t *err_bit_descr) 133827Sjchu { 133927Sjchu uint64_t imu_log_enable, imu_intr_enable; 134027Sjchu int mask = BITMASK(err_bit_descr->bit); 134127Sjchu int err = PX_NONFATAL; 134227Sjchu 134327Sjchu imu_log_enable = CSR_XR(csr_base, err_reg_descr->log_addr); 134427Sjchu imu_intr_enable = CSR_XR(csr_base, err_reg_descr->enable_addr); 134527Sjchu 1346435Sjchu /* 1347435Sjchu * If matching bit is not set, meaning corresponding rbne not 1348435Sjchu * enabled, then receiving it indicates some sort of malfunction 1349435Sjchu * possibly in hardware. 1350435Sjchu * 1351435Sjchu * Other wise, software may have intentionally disabled certain 1352435Sjchu * errors for a period of time within which the occuring of the 1353435Sjchu * disabled errors become rbne, that is non fatal. 1354435Sjchu */ 1355435Sjchu if (!(imu_log_enable & imu_intr_enable & mask)) 135627Sjchu err = PX_FATAL_SW; 135727Sjchu 135827Sjchu return (err); 135927Sjchu } 136027Sjchu 1361118Sjchu /* 1362118Sjchu * No platforms uses PME. Any PME received is simply logged 1363118Sjchu * for analysis. 1364118Sjchu */ 1365118Sjchu /* ARGSUSED */ 1366118Sjchu int 1367118Sjchu px_err_imu_pme_handle(dev_info_t *rpdip, caddr_t csr_base, 1368118Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 1369118Sjchu px_err_bit_desc_t *err_bit_descr) 1370118Sjchu { 1371118Sjchu px_t *px_p = DIP_TO_STATE(rpdip); 1372118Sjchu 1373118Sjchu px_p->px_pme_ignored++; 1374118Sjchu return (PX_NONFATAL); 1375118Sjchu } 1376118Sjchu 137727Sjchu /* handle EQ overflow */ 137827Sjchu /* ARGSUSED */ 137927Sjchu int 138027Sjchu px_err_imu_eq_ovfl_handle(dev_info_t *rpdip, caddr_t csr_base, 138127Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 138227Sjchu px_err_bit_desc_t *err_bit_descr) 138327Sjchu { 138427Sjchu px_t *px_p = DIP_TO_STATE(rpdip); 138527Sjchu px_msiq_state_t *msiq_state_p = &px_p->px_ib_p->ib_msiq_state; 138627Sjchu msiqid_t eqno; 138727Sjchu pci_msiq_state_t msiq_state; 138827Sjchu int err = PX_NONFATAL; 138927Sjchu int i; 139027Sjchu 139127Sjchu eqno = msiq_state_p->msiq_1st_msiq_id; 139227Sjchu for (i = 0; i < msiq_state_p->msiq_cnt; i++) { 139327Sjchu if (px_lib_msiq_getstate(rpdip, eqno, &msiq_state) == 139427Sjchu DDI_SUCCESS) { 139527Sjchu if (msiq_state == PCI_MSIQ_STATE_ERROR) { 139627Sjchu err = PX_FATAL_SW; 139727Sjchu } 139827Sjchu } 139927Sjchu } 140027Sjchu 140127Sjchu return (err); 140227Sjchu } 140327Sjchu 140427Sjchu /* DMC IMU SCS - see io erpt doc, section 2.2 */ 140527Sjchu PX_ERPT_SEND_DEC(imu_scs) 140627Sjchu { 140727Sjchu char buf[FM_MAX_CLASS]; 1408739Sjchu boolean_t pri = PX_ERR_IS_PRI(bit); 140927Sjchu 141027Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 141127Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 141227Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 1413739Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri, 141427Sjchu FIRE_IMU_ELE, DATA_TYPE_UINT64, 141527Sjchu CSR_XR(csr_base, IMU_ERROR_LOG_ENABLE), 141627Sjchu FIRE_IMU_IE, DATA_TYPE_UINT64, 141727Sjchu CSR_XR(csr_base, IMU_INTERRUPT_ENABLE), 141827Sjchu FIRE_IMU_IS, DATA_TYPE_UINT64, 141927Sjchu ss_reg, 142027Sjchu FIRE_IMU_ESS, DATA_TYPE_UINT64, 142127Sjchu CSR_XR(csr_base, IMU_ERROR_STATUS_SET), 142227Sjchu FIRE_IMU_SCS, DATA_TYPE_UINT64, 142327Sjchu CSR_XR(csr_base, IMU_SCS_ERROR_LOG), 142427Sjchu NULL); 142527Sjchu 142627Sjchu return (PX_OK); 142727Sjchu } 142827Sjchu 142927Sjchu /* DMC IMU - see io erpt doc, section 2.3 */ 143027Sjchu PX_ERPT_SEND_DEC(imu) 143127Sjchu { 143227Sjchu char buf[FM_MAX_CLASS]; 1433739Sjchu boolean_t pri = PX_ERR_IS_PRI(bit); 143427Sjchu 143527Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 143627Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 143727Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 1438739Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri, 143927Sjchu FIRE_IMU_ELE, DATA_TYPE_UINT64, 144027Sjchu CSR_XR(csr_base, IMU_ERROR_LOG_ENABLE), 144127Sjchu FIRE_IMU_IE, DATA_TYPE_UINT64, 144227Sjchu CSR_XR(csr_base, IMU_INTERRUPT_ENABLE), 144327Sjchu FIRE_IMU_IS, DATA_TYPE_UINT64, 144427Sjchu ss_reg, 144527Sjchu FIRE_IMU_ESS, DATA_TYPE_UINT64, 144627Sjchu CSR_XR(csr_base, IMU_ERROR_STATUS_SET), 144727Sjchu NULL); 144827Sjchu 144927Sjchu return (PX_OK); 145027Sjchu } 145127Sjchu 145227Sjchu /* DMC MMU TFAR/TFSR - see io erpt doc, section 2.4 */ 145327Sjchu PX_ERPT_SEND_DEC(mmu_tfar_tfsr) 145427Sjchu { 145527Sjchu char buf[FM_MAX_CLASS]; 1456739Sjchu boolean_t pri = PX_ERR_IS_PRI(bit); 145727Sjchu 145827Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 145927Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 146027Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 1461739Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri, 146227Sjchu FIRE_MMU_ELE, DATA_TYPE_UINT64, 146327Sjchu CSR_XR(csr_base, MMU_ERROR_LOG_ENABLE), 146427Sjchu FIRE_MMU_IE, DATA_TYPE_UINT64, 146527Sjchu CSR_XR(csr_base, MMU_INTERRUPT_ENABLE), 146627Sjchu FIRE_MMU_IS, DATA_TYPE_UINT64, 146727Sjchu ss_reg, 146827Sjchu FIRE_MMU_ESS, DATA_TYPE_UINT64, 146927Sjchu CSR_XR(csr_base, MMU_ERROR_STATUS_SET), 147027Sjchu FIRE_MMU_TFAR, DATA_TYPE_UINT64, 147127Sjchu CSR_XR(csr_base, MMU_TRANSLATION_FAULT_ADDRESS), 147227Sjchu FIRE_MMU_TFSR, DATA_TYPE_UINT64, 147327Sjchu CSR_XR(csr_base, MMU_TRANSLATION_FAULT_STATUS), 147427Sjchu NULL); 147527Sjchu 147627Sjchu return (PX_OK); 147727Sjchu } 147827Sjchu 147927Sjchu /* DMC MMU - see io erpt doc, section 2.5 */ 148027Sjchu PX_ERPT_SEND_DEC(mmu) 148127Sjchu { 148227Sjchu char buf[FM_MAX_CLASS]; 1483739Sjchu boolean_t pri = PX_ERR_IS_PRI(bit); 148427Sjchu 148527Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 148627Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 148727Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 1488739Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri, 148927Sjchu FIRE_MMU_ELE, DATA_TYPE_UINT64, 149027Sjchu CSR_XR(csr_base, MMU_ERROR_LOG_ENABLE), 149127Sjchu FIRE_MMU_IE, DATA_TYPE_UINT64, 149227Sjchu CSR_XR(csr_base, MMU_INTERRUPT_ENABLE), 149327Sjchu FIRE_MMU_IS, DATA_TYPE_UINT64, 149427Sjchu ss_reg, 149527Sjchu FIRE_MMU_ESS, DATA_TYPE_UINT64, 149627Sjchu CSR_XR(csr_base, MMU_ERROR_STATUS_SET), 149727Sjchu NULL); 149827Sjchu 149927Sjchu return (PX_OK); 150027Sjchu } 150127Sjchu 150227Sjchu /* imu function to handle all Received but Not Enabled errors */ 150327Sjchu int 150427Sjchu px_err_mmu_rbne_handle(dev_info_t *rpdip, caddr_t csr_base, 150527Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 150627Sjchu px_err_bit_desc_t *err_bit_descr) 150727Sjchu { 1508739Sjchu boolean_t pri = PX_ERR_IS_PRI(err_bit_descr->bit); 1509260Set142600 uint64_t mmu_log_enable, mmu_intr_enable; 151027Sjchu uint64_t mask = BITMASK(err_bit_descr->bit); 1511260Set142600 uint64_t mmu_tfa, mmu_ctrl; 1512260Set142600 uint64_t mmu_enable_bit = 0; 151327Sjchu int err = PX_NONFATAL; 151427Sjchu int ret; 151527Sjchu 151627Sjchu mmu_log_enable = CSR_XR(csr_base, err_reg_descr->log_addr); 151727Sjchu mmu_intr_enable = CSR_XR(csr_base, err_reg_descr->enable_addr); 151827Sjchu 151927Sjchu mmu_tfa = CSR_XR(csr_base, MMU_TRANSLATION_FAULT_ADDRESS); 1520260Set142600 mmu_ctrl = CSR_XR(csr_base, MMU_CONTROL_AND_STATUS); 152127Sjchu 1522260Set142600 switch (err_bit_descr->bit) { 1523260Set142600 case MMU_INTERRUPT_STATUS_BYP_ERR_P: 1524260Set142600 mmu_enable_bit = BITMASK(MMU_CONTROL_AND_STATUS_BE); 1525260Set142600 break; 1526260Set142600 case MMU_INTERRUPT_STATUS_TRN_ERR_P: 1527260Set142600 mmu_enable_bit = BITMASK(MMU_CONTROL_AND_STATUS_TE); 1528260Set142600 break; 1529260Set142600 default: 1530260Set142600 mmu_enable_bit = 0; 1531260Set142600 break; 1532260Set142600 } 1533260Set142600 1534260Set142600 /* 1535260Set142600 * If the interrupts are enabled and Translation/Bypass Enable bit 1536260Set142600 * was set, then panic. This error should not have occured. 1537260Set142600 */ 1538260Set142600 if (mmu_log_enable & mmu_intr_enable & 1539260Set142600 (mmu_ctrl & mmu_enable_bit)) { 154027Sjchu err = PX_FATAL_SW; 154127Sjchu } else { 1542739Sjchu if (!pri) 1543739Sjchu return (PX_FATAL_GOS); 1544739Sjchu 154527Sjchu ret = px_handle_lookup( 154627Sjchu rpdip, DMA_HANDLE, derr->fme_ena, (void *)mmu_tfa); 154727Sjchu err = (ret == DDI_FM_FATAL) ? PX_FATAL_GOS : PX_NONFATAL; 154827Sjchu 154927Sjchu /* 155027Sjchu * S/W bug - this error should always be enabled 155127Sjchu */ 155227Sjchu 155327Sjchu /* enable error & intr reporting for this bit */ 155427Sjchu CSR_XS(csr_base, MMU_ERROR_LOG_ENABLE, mmu_log_enable | mask); 155527Sjchu CSR_XS(csr_base, MMU_INTERRUPT_ENABLE, mmu_intr_enable | mask); 1556260Set142600 1557260Set142600 /* enable translation access/bypass enable */ 1558260Set142600 CSR_XS(csr_base, MMU_CONTROL_AND_STATUS, 1559260Set142600 mmu_ctrl | mmu_enable_bit); 156027Sjchu } 156127Sjchu 156227Sjchu return (err); 156327Sjchu } 156427Sjchu 156527Sjchu /* Generic error handling functions that involve MMU Translation Fault Addr */ 156627Sjchu /* ARGSUSED */ 156727Sjchu int 156827Sjchu px_err_mmu_tfa_handle(dev_info_t *rpdip, caddr_t csr_base, 156927Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 157027Sjchu px_err_bit_desc_t *err_bit_descr) 157127Sjchu { 1572739Sjchu boolean_t pri = PX_ERR_IS_PRI(err_bit_descr->bit); 157327Sjchu uint64_t mmu_tfa; 157427Sjchu uint_t ret; 157527Sjchu 1576739Sjchu if (!pri) 1577739Sjchu return (PX_FATAL_GOS); 1578739Sjchu 157927Sjchu mmu_tfa = CSR_XR(csr_base, MMU_TRANSLATION_FAULT_ADDRESS); 158027Sjchu ret = px_handle_lookup( 158127Sjchu rpdip, DMA_HANDLE, derr->fme_ena, (void *)mmu_tfa); 158227Sjchu 158327Sjchu return ((ret == DDI_FM_FATAL) ? PX_FATAL_GOS : PX_NONFATAL); 158427Sjchu } 158527Sjchu 158627Sjchu /* MMU Table walk errors */ 158727Sjchu /* ARGSUSED */ 158827Sjchu int 158927Sjchu px_err_mmu_tblwlk_handle(dev_info_t *rpdip, caddr_t csr_base, 159027Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 159127Sjchu px_err_bit_desc_t *err_bit_descr) 159227Sjchu { 1593739Sjchu boolean_t pri = PX_ERR_IS_PRI(err_bit_descr->bit); 159427Sjchu uint64_t mmu_tfa; 159527Sjchu uint_t ret; 159627Sjchu 1597739Sjchu if (!pri) 1598739Sjchu return (PX_FATAL_GOS); 1599739Sjchu 160027Sjchu mmu_tfa = CSR_XR(csr_base, MMU_TRANSLATION_FAULT_ADDRESS); 160127Sjchu ret = px_handle_lookup( 160227Sjchu rpdip, DMA_HANDLE, derr->fme_ena, (void *)mmu_tfa); 160327Sjchu 160427Sjchu return ((ret == DDI_FM_FATAL) ? PX_FATAL_GOS : PX_NONFATAL); 160527Sjchu } 160627Sjchu 1607118Sjchu /* 16081147Sjchu * TLU LUP event - if caused by power management activity, then it is expected. 16091147Sjchu * In all other cases, it is an error. 1610118Sjchu */ 1611118Sjchu /* ARGSUSED */ 1612118Sjchu int 1613118Sjchu px_err_tlu_lup_handle(dev_info_t *rpdip, caddr_t csr_base, 1614118Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 1615118Sjchu px_err_bit_desc_t *err_bit_descr) 1616118Sjchu { 1617118Sjchu px_t *px_p = DIP_TO_STATE(rpdip); 1618118Sjchu 1619118Sjchu /* 16201147Sjchu * power management code is currently the only segment that sets 16211147Sjchu * px_lup_pending to indicate its expectation for a healthy LUP 16221147Sjchu * event. For all other occasions, LUP event should be flaged as 16231147Sjchu * error condition. 1624118Sjchu */ 16251147Sjchu return ((atomic_cas_32(&px_p->px_lup_pending, 1, 0) == 0) ? 16261147Sjchu PX_NONFATAL : PX_OK); 16271147Sjchu } 1628118Sjchu 16291147Sjchu /* 16301147Sjchu * TLU LDN event - if caused by power management activity, then it is expected. 16311147Sjchu * In all other cases, it is an error. 16321147Sjchu */ 16331147Sjchu /* ARGSUSED */ 16341147Sjchu int 16351147Sjchu px_err_tlu_ldn_handle(dev_info_t *rpdip, caddr_t csr_base, 16361147Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 16371147Sjchu px_err_bit_desc_t *err_bit_descr) 16381147Sjchu { 16391147Sjchu px_t *px_p = DIP_TO_STATE(rpdip); 16401147Sjchu return ((px_p->px_pm_flags & PX_LDN_EXPECTED) ? PX_OK : PX_NONFATAL); 1641118Sjchu } 1642118Sjchu 164327Sjchu /* PEC ILU none - see io erpt doc, section 3.1 */ 164427Sjchu PX_ERPT_SEND_DEC(pec_ilu) 164527Sjchu { 164627Sjchu char buf[FM_MAX_CLASS]; 1647739Sjchu boolean_t pri = PX_ERR_IS_PRI(bit); 164827Sjchu 164927Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 165027Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 165127Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 1652739Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri, 165327Sjchu FIRE_ILU_ELE, DATA_TYPE_UINT64, 165427Sjchu CSR_XR(csr_base, ILU_ERROR_LOG_ENABLE), 165527Sjchu FIRE_ILU_IE, DATA_TYPE_UINT64, 165627Sjchu CSR_XR(csr_base, ILU_INTERRUPT_ENABLE), 165727Sjchu FIRE_ILU_IS, DATA_TYPE_UINT64, 165827Sjchu ss_reg, 165927Sjchu FIRE_ILU_ESS, DATA_TYPE_UINT64, 166027Sjchu CSR_XR(csr_base, ILU_ERROR_STATUS_SET), 166127Sjchu NULL); 166227Sjchu 166327Sjchu return (PX_OK); 166427Sjchu } 166527Sjchu 1666383Set142600 /* PCIEX UE Errors */ 1667383Set142600 /* ARGSUSED */ 1668671Skrishnae int 1669383Set142600 px_err_pciex_ue_handle(dev_info_t *rpdip, caddr_t csr_base, 1670383Set142600 ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 1671383Set142600 px_err_bit_desc_t *err_bit_descr) 1672383Set142600 { 1673383Set142600 uint32_t mask = (uint32_t)BITMASK(err_bit_descr->bit); 1674383Set142600 1675383Set142600 return ((err_bit_descr->bit >= 32 && px_fabric_die_rc_ue_gos) ? 1676383Set142600 PX_FATAL_GOS : PX_FABRIC_ERR_SEV(mask, px_fabric_die_rc_ue, 1677383Set142600 px_fabric_die_rc_ue_gos)); 1678383Set142600 } 1679383Set142600 1680383Set142600 /* PCI-E Uncorrectable Errors - see io erpt doc, section 3.2 */ 1681383Set142600 PX_ERPT_SEND_DEC(pciex_rx_ue) 1682383Set142600 { 1683383Set142600 char buf[FM_MAX_CLASS]; 1684739Sjchu boolean_t pri = PX_ERR_IS_PRI(bit); 1685383Set142600 1686383Set142600 (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 1687383Set142600 ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 1688383Set142600 DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 1689739Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri, 1690383Set142600 FIRE_TLU_UELE, DATA_TYPE_UINT64, 1691383Set142600 CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_LOG_ENABLE), 1692383Set142600 FIRE_TLU_UIE, DATA_TYPE_UINT64, 1693383Set142600 CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_INTERRUPT_ENABLE), 1694383Set142600 FIRE_TLU_UIS, DATA_TYPE_UINT64, 1695383Set142600 ss_reg, 1696383Set142600 FIRE_TLU_UESS, DATA_TYPE_UINT64, 1697383Set142600 CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_STATUS_SET), 1698383Set142600 FIRE_TLU_RUEH1L, DATA_TYPE_UINT64, 1699383Set142600 CSR_XR(csr_base, TLU_RECEIVE_UNCORRECTABLE_ERROR_HEADER1_LOG), 1700383Set142600 FIRE_TLU_RUEH2L, DATA_TYPE_UINT64, 1701383Set142600 CSR_XR(csr_base, TLU_RECEIVE_UNCORRECTABLE_ERROR_HEADER2_LOG), 1702383Set142600 NULL); 1703383Set142600 1704383Set142600 return (PX_OK); 1705383Set142600 } 1706383Set142600 1707383Set142600 /* PCI-E Uncorrectable Errors - see io erpt doc, section 3.3 */ 1708383Set142600 PX_ERPT_SEND_DEC(pciex_tx_ue) 1709383Set142600 { 1710383Set142600 char buf[FM_MAX_CLASS]; 1711739Sjchu boolean_t pri = PX_ERR_IS_PRI(bit); 1712383Set142600 1713383Set142600 (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 1714383Set142600 ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 1715383Set142600 DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 1716739Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri, 1717383Set142600 FIRE_TLU_UELE, DATA_TYPE_UINT64, 1718383Set142600 CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_LOG_ENABLE), 1719383Set142600 FIRE_TLU_UIE, DATA_TYPE_UINT64, 1720383Set142600 CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_INTERRUPT_ENABLE), 1721383Set142600 FIRE_TLU_UIS, DATA_TYPE_UINT64, 1722383Set142600 ss_reg, 1723383Set142600 FIRE_TLU_UESS, DATA_TYPE_UINT64, 1724383Set142600 CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_STATUS_SET), 1725383Set142600 FIRE_TLU_TUEH1L, DATA_TYPE_UINT64, 1726383Set142600 CSR_XR(csr_base, TLU_TRANSMIT_UNCORRECTABLE_ERROR_HEADER1_LOG), 1727383Set142600 FIRE_TLU_TUEH2L, DATA_TYPE_UINT64, 1728383Set142600 CSR_XR(csr_base, TLU_TRANSMIT_UNCORRECTABLE_ERROR_HEADER2_LOG), 1729383Set142600 NULL); 1730383Set142600 1731383Set142600 return (PX_OK); 1732383Set142600 } 1733383Set142600 1734383Set142600 /* PCI-E Uncorrectable Errors - see io erpt doc, section 3.4 */ 1735383Set142600 PX_ERPT_SEND_DEC(pciex_rx_tx_ue) 1736383Set142600 { 1737383Set142600 char buf[FM_MAX_CLASS]; 1738739Sjchu boolean_t pri = PX_ERR_IS_PRI(bit); 1739383Set142600 1740383Set142600 (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 1741383Set142600 ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 1742383Set142600 DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 1743739Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri, 1744383Set142600 FIRE_TLU_UELE, DATA_TYPE_UINT64, 1745383Set142600 CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_LOG_ENABLE), 1746383Set142600 FIRE_TLU_UIE, DATA_TYPE_UINT64, 1747383Set142600 CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_INTERRUPT_ENABLE), 1748383Set142600 FIRE_TLU_UIS, DATA_TYPE_UINT64, 1749383Set142600 ss_reg, 1750383Set142600 FIRE_TLU_UESS, DATA_TYPE_UINT64, 1751383Set142600 CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_STATUS_SET), 1752383Set142600 FIRE_TLU_RUEH1L, DATA_TYPE_UINT64, 1753383Set142600 CSR_XR(csr_base, TLU_RECEIVE_UNCORRECTABLE_ERROR_HEADER1_LOG), 1754383Set142600 FIRE_TLU_RUEH2L, DATA_TYPE_UINT64, 1755383Set142600 CSR_XR(csr_base, TLU_RECEIVE_UNCORRECTABLE_ERROR_HEADER2_LOG), 1756383Set142600 FIRE_TLU_TUEH1L, DATA_TYPE_UINT64, 1757383Set142600 CSR_XR(csr_base, TLU_TRANSMIT_UNCORRECTABLE_ERROR_HEADER1_LOG), 1758383Set142600 FIRE_TLU_TUEH2L, DATA_TYPE_UINT64, 1759383Set142600 CSR_XR(csr_base, TLU_TRANSMIT_UNCORRECTABLE_ERROR_HEADER2_LOG), 1760383Set142600 NULL); 1761383Set142600 1762383Set142600 return (PX_OK); 1763383Set142600 } 1764383Set142600 1765383Set142600 /* PCI-E Uncorrectable Errors - see io erpt doc, section 3.5 */ 1766383Set142600 PX_ERPT_SEND_DEC(pciex_ue) 1767383Set142600 { 1768383Set142600 char buf[FM_MAX_CLASS]; 1769739Sjchu boolean_t pri = PX_ERR_IS_PRI(bit); 1770383Set142600 1771383Set142600 (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 1772383Set142600 ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 1773383Set142600 DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 1774739Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri, 1775383Set142600 FIRE_TLU_UELE, DATA_TYPE_UINT64, 1776383Set142600 CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_LOG_ENABLE), 1777383Set142600 FIRE_TLU_UIE, DATA_TYPE_UINT64, 1778383Set142600 CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_INTERRUPT_ENABLE), 1779383Set142600 FIRE_TLU_UIS, DATA_TYPE_UINT64, 1780383Set142600 ss_reg, 1781383Set142600 FIRE_TLU_UESS, DATA_TYPE_UINT64, 1782383Set142600 CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_STATUS_SET), 1783383Set142600 NULL); 1784383Set142600 1785383Set142600 return (PX_OK); 1786383Set142600 } 1787383Set142600 1788383Set142600 /* PCIEX UE Errors */ 1789383Set142600 /* ARGSUSED */ 1790671Skrishnae int 1791383Set142600 px_err_pciex_ce_handle(dev_info_t *rpdip, caddr_t csr_base, 1792383Set142600 ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 1793383Set142600 px_err_bit_desc_t *err_bit_descr) 1794383Set142600 { 1795383Set142600 uint32_t mask = (uint32_t)BITMASK(err_bit_descr->bit); 1796383Set142600 1797383Set142600 return ((err_bit_descr->bit >= 32 && px_fabric_die_rc_ce_gos) ? 1798383Set142600 PX_FATAL_GOS : PX_FABRIC_ERR_SEV(mask, px_fabric_die_rc_ce, 1799383Set142600 px_fabric_die_rc_ce_gos)); 1800383Set142600 } 1801383Set142600 180227Sjchu /* PCI-E Correctable Errors - see io erpt doc, section 3.6 */ 180327Sjchu PX_ERPT_SEND_DEC(pciex_ce) 180427Sjchu { 180527Sjchu char buf[FM_MAX_CLASS]; 1806739Sjchu boolean_t pri = PX_ERR_IS_PRI(bit); 180727Sjchu 180827Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 180927Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 181027Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 1811739Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri, 181227Sjchu FIRE_TLU_CELE, DATA_TYPE_UINT64, 181327Sjchu CSR_XR(csr_base, TLU_CORRECTABLE_ERROR_LOG_ENABLE), 181427Sjchu FIRE_TLU_CIE, DATA_TYPE_UINT64, 181527Sjchu CSR_XR(csr_base, TLU_CORRECTABLE_ERROR_INTERRUPT_ENABLE), 181627Sjchu FIRE_TLU_CIS, DATA_TYPE_UINT64, 181727Sjchu ss_reg, 181827Sjchu FIRE_TLU_CESS, DATA_TYPE_UINT64, 181927Sjchu CSR_XR(csr_base, TLU_CORRECTABLE_ERROR_STATUS_SET), 182027Sjchu NULL); 182127Sjchu 182227Sjchu return (PX_OK); 182327Sjchu } 182427Sjchu 182527Sjchu /* TLU Other Event Status (receive only) - see io erpt doc, section 3.7 */ 182627Sjchu PX_ERPT_SEND_DEC(pciex_rx_oe) 182727Sjchu { 182827Sjchu char buf[FM_MAX_CLASS]; 1829739Sjchu boolean_t pri = PX_ERR_IS_PRI(bit); 183027Sjchu 183127Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 183227Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 183327Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 1834739Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri, 183527Sjchu FIRE_TLU_OEELE, DATA_TYPE_UINT64, 183627Sjchu CSR_XR(csr_base, TLU_OTHER_EVENT_LOG_ENABLE), 183727Sjchu FIRE_TLU_OEIE, DATA_TYPE_UINT64, 183827Sjchu CSR_XR(csr_base, TLU_OTHER_EVENT_INTERRUPT_ENABLE), 183927Sjchu FIRE_TLU_OEIS, DATA_TYPE_UINT64, 184027Sjchu ss_reg, 184127Sjchu FIRE_TLU_OEESS, DATA_TYPE_UINT64, 184227Sjchu CSR_XR(csr_base, TLU_OTHER_EVENT_STATUS_SET), 184327Sjchu FIRE_TLU_RUEH1L, DATA_TYPE_UINT64, 184427Sjchu CSR_XR(csr_base, TLU_RECEIVE_OTHER_EVENT_HEADER1_LOG), 1845260Set142600 FIRE_TLU_RUEH2L, DATA_TYPE_UINT64, 184627Sjchu CSR_XR(csr_base, TLU_RECEIVE_OTHER_EVENT_HEADER2_LOG), 184727Sjchu NULL); 184827Sjchu 184927Sjchu return (PX_OK); 185027Sjchu } 185127Sjchu 185227Sjchu /* TLU Other Event Status (rx + tx) - see io erpt doc, section 3.8 */ 185327Sjchu PX_ERPT_SEND_DEC(pciex_rx_tx_oe) 185427Sjchu { 185527Sjchu char buf[FM_MAX_CLASS]; 1856739Sjchu boolean_t pri = PX_ERR_IS_PRI(bit); 185727Sjchu 185827Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 185927Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 186027Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 1861739Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri, 186227Sjchu FIRE_TLU_OEELE, DATA_TYPE_UINT64, 186327Sjchu CSR_XR(csr_base, TLU_OTHER_EVENT_LOG_ENABLE), 186427Sjchu FIRE_TLU_OEIE, DATA_TYPE_UINT64, 186527Sjchu CSR_XR(csr_base, TLU_OTHER_EVENT_INTERRUPT_ENABLE), 186627Sjchu FIRE_TLU_OEIS, DATA_TYPE_UINT64, 186727Sjchu ss_reg, 186827Sjchu FIRE_TLU_OEESS, DATA_TYPE_UINT64, 186927Sjchu CSR_XR(csr_base, TLU_OTHER_EVENT_STATUS_SET), 187027Sjchu FIRE_TLU_ROEEH1L, DATA_TYPE_UINT64, 187127Sjchu CSR_XR(csr_base, TLU_RECEIVE_OTHER_EVENT_HEADER1_LOG), 187227Sjchu FIRE_TLU_ROEEH2L, DATA_TYPE_UINT64, 187327Sjchu CSR_XR(csr_base, TLU_RECEIVE_OTHER_EVENT_HEADER2_LOG), 187427Sjchu FIRE_TLU_TOEEH1L, DATA_TYPE_UINT64, 187527Sjchu CSR_XR(csr_base, TLU_TRANSMIT_OTHER_EVENT_HEADER1_LOG), 1876260Set142600 FIRE_TLU_TOEEH2L, DATA_TYPE_UINT64, 187727Sjchu CSR_XR(csr_base, TLU_TRANSMIT_OTHER_EVENT_HEADER2_LOG), 187827Sjchu NULL); 187927Sjchu 188027Sjchu return (PX_OK); 188127Sjchu } 188227Sjchu 188327Sjchu /* TLU Other Event - see io erpt doc, section 3.9 */ 188427Sjchu PX_ERPT_SEND_DEC(pciex_oe) 188527Sjchu { 1886739Sjchu char buf[FM_MAX_CLASS]; 1887739Sjchu boolean_t pri = PX_ERR_IS_PRI(bit); 188827Sjchu 188927Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 189027Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 189127Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 1892739Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri, 189327Sjchu FIRE_TLU_OEELE, DATA_TYPE_UINT64, 189427Sjchu CSR_XR(csr_base, TLU_OTHER_EVENT_LOG_ENABLE), 189527Sjchu FIRE_TLU_OEIE, DATA_TYPE_UINT64, 189627Sjchu CSR_XR(csr_base, TLU_OTHER_EVENT_INTERRUPT_ENABLE), 189727Sjchu FIRE_TLU_OEIS, DATA_TYPE_UINT64, 189827Sjchu ss_reg, 189927Sjchu FIRE_TLU_OEESS, DATA_TYPE_UINT64, 190027Sjchu CSR_XR(csr_base, TLU_OTHER_EVENT_STATUS_SET), 190127Sjchu NULL); 190227Sjchu 190327Sjchu return (PX_OK); 190427Sjchu } 1905