127Sjchu /* 227Sjchu * CDDL HEADER START 327Sjchu * 427Sjchu * The contents of this file are subject to the terms of the 527Sjchu * Common Development and Distribution License, Version 1.0 only 627Sjchu * (the "License"). You may not use this file except in compliance 727Sjchu * with the License. 827Sjchu * 927Sjchu * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 1027Sjchu * or http://www.opensolaris.org/os/licensing. 1127Sjchu * See the License for the specific language governing permissions 1227Sjchu * and limitations under the License. 1327Sjchu * 1427Sjchu * When distributing Covered Code, include this CDDL HEADER in each 1527Sjchu * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 1627Sjchu * If applicable, add the following below this CDDL HEADER, with the 1727Sjchu * fields enclosed by brackets "[]" replaced with your own identifying 1827Sjchu * information: Portions Copyright [yyyy] [name of copyright owner] 1927Sjchu * 2027Sjchu * CDDL HEADER END 2127Sjchu */ 2227Sjchu /* 2327Sjchu * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 2427Sjchu * Use is subject to license terms. 2527Sjchu */ 2627Sjchu 2727Sjchu #pragma ident "%Z%%M% %I% %E% SMI" 2827Sjchu 2927Sjchu /* 3027Sjchu * sun4u Fire Error Handling 3127Sjchu */ 3227Sjchu 3327Sjchu #include <sys/types.h> 3427Sjchu #include <sys/ddi.h> 3527Sjchu #include <sys/sunddi.h> 3627Sjchu #include <sys/fm/protocol.h> 3727Sjchu #include <sys/fm/util.h> 3827Sjchu #include <sys/pcie.h> 3927Sjchu #include <sys/pcie_impl.h> 4027Sjchu #include "px_obj.h" 4127Sjchu #include <px_regs.h> 4227Sjchu #include <px_csr.h> 4327Sjchu #include <sys/membar.h> 44118Sjchu #include "pcie_pwr.h" 4527Sjchu #include "px_lib4u.h" 4627Sjchu #include "px_err.h" 4727Sjchu #include "px_err_impl.h" 4827Sjchu 4927Sjchu /* 5027Sjchu * JBC error bit table 5127Sjchu */ 5227Sjchu #define JBC_BIT_DESC(bit, hdl, erpt) \ 5327Sjchu JBC_INTERRUPT_STATUS_ ## bit ## _P, \ 5427Sjchu 0, \ 5527Sjchu PX_ERR_BIT_HANDLE(hdl), \ 5627Sjchu PX_ERPT_SEND(erpt), \ 5727Sjchu PX_ERR_JBC_CLASS(bit) 5827Sjchu px_err_bit_desc_t px_err_cb_tbl[] = { 5927Sjchu /* JBC FATAL - see io erpt doc, section 1.1 */ 6027Sjchu { JBC_BIT_DESC(MB_PEA, fatal_hw, jbc_fatal) }, 6127Sjchu { JBC_BIT_DESC(CPE, fatal_hw, jbc_fatal) }, 6227Sjchu { JBC_BIT_DESC(APE, fatal_hw, jbc_fatal) }, 6327Sjchu { JBC_BIT_DESC(PIO_CPE, fatal_hw, jbc_fatal) }, 6427Sjchu { JBC_BIT_DESC(JTCEEW, fatal_hw, jbc_fatal) }, 6527Sjchu { JBC_BIT_DESC(JTCEEI, fatal_hw, jbc_fatal) }, 6627Sjchu { JBC_BIT_DESC(JTCEER, fatal_hw, jbc_fatal) }, 6727Sjchu 6827Sjchu /* JBC MERGE - see io erpt doc, section 1.2 */ 6927Sjchu { JBC_BIT_DESC(MB_PER, jbc_merge, jbc_merge) }, 7027Sjchu { JBC_BIT_DESC(MB_PEW, jbc_merge, jbc_merge) }, 7127Sjchu 7227Sjchu /* JBC Jbusint IN - see io erpt doc, section 1.3 */ 7327Sjchu { JBC_BIT_DESC(UE_ASYN, fatal_gos, jbc_in) }, 7427Sjchu { JBC_BIT_DESC(CE_ASYN, jbc_jbusint_in, jbc_in) }, 7527Sjchu { JBC_BIT_DESC(JTE, fatal_gos, jbc_in) }, 7627Sjchu { JBC_BIT_DESC(JBE, jbc_jbusint_in, jbc_in) }, 7727Sjchu { JBC_BIT_DESC(JUE, jbc_jbusint_in, jbc_in) }, 7827Sjchu { JBC_BIT_DESC(ICISE, fatal_gos, jbc_in) }, 7927Sjchu { JBC_BIT_DESC(WR_DPE, jbc_jbusint_in, jbc_in) }, 8027Sjchu { JBC_BIT_DESC(RD_DPE, jbc_jbusint_in, jbc_in) }, 8127Sjchu { JBC_BIT_DESC(ILL_BMW, jbc_jbusint_in, jbc_in) }, 8227Sjchu { JBC_BIT_DESC(ILL_BMR, jbc_jbusint_in, jbc_in) }, 8327Sjchu { JBC_BIT_DESC(BJC, jbc_jbusint_in, jbc_in) }, 8427Sjchu 8527Sjchu /* JBC Jbusint Out - see io erpt doc, section 1.4 */ 8627Sjchu { JBC_BIT_DESC(IJP, fatal_gos, jbc_out) }, 8727Sjchu 8827Sjchu /* JBC Dmcint ODCD - see io erpt doc, section 1.5 */ 8927Sjchu { JBC_BIT_DESC(PIO_UNMAP_RD, jbc_dmcint_odcd, jbc_odcd) }, 9027Sjchu { JBC_BIT_DESC(ILL_ACC_RD, jbc_dmcint_odcd, jbc_odcd) }, 9127Sjchu { JBC_BIT_DESC(PIO_UNMAP, jbc_dmcint_odcd, jbc_odcd) }, 9227Sjchu { JBC_BIT_DESC(PIO_DPE, jbc_dmcint_odcd, jbc_odcd) }, 9327Sjchu { JBC_BIT_DESC(PIO_CPE, non_fatal, jbc_odcd) }, 9427Sjchu { JBC_BIT_DESC(ILL_ACC, jbc_dmcint_odcd, jbc_odcd) }, 9527Sjchu 9627Sjchu /* JBC Dmcint IDC - see io erpt doc, section 1.6 */ 9727Sjchu { JBC_BIT_DESC(UNSOL_RD, non_fatal, jbc_idc) }, 9827Sjchu { JBC_BIT_DESC(UNSOL_INTR, non_fatal, jbc_idc) }, 9927Sjchu 10027Sjchu /* JBC CSR - see io erpt doc, section 1.7 */ 10127Sjchu { JBC_BIT_DESC(EBUS_TO, jbc_csr, jbc_csr) } 10227Sjchu }; 10327Sjchu 10427Sjchu #define px_err_cb_keys \ 10527Sjchu (sizeof (px_err_cb_tbl)) / (sizeof (px_err_bit_desc_t)) 10627Sjchu 10727Sjchu /* 10827Sjchu * DMC error bit tables 10927Sjchu */ 11027Sjchu #define IMU_BIT_DESC(bit, hdl, erpt) \ 11127Sjchu IMU_INTERRUPT_STATUS_ ## bit ## _P, \ 11227Sjchu 0, \ 11327Sjchu PX_ERR_BIT_HANDLE(hdl), \ 11427Sjchu PX_ERPT_SEND(erpt), \ 11527Sjchu PX_ERR_DMC_CLASS(bit) 11627Sjchu px_err_bit_desc_t px_err_imu_tbl[] = { 11727Sjchu /* DMC IMU RDS - see io erpt doc, section 2.1 */ 11827Sjchu { IMU_BIT_DESC(MSI_MAL_ERR, non_fatal, imu_rds) }, 11927Sjchu { IMU_BIT_DESC(MSI_PAR_ERR, fatal_stuck, imu_rds) }, 12027Sjchu { IMU_BIT_DESC(PMEACK_MES_NOT_EN, imu_rbne, imu_rds) }, 121118Sjchu { IMU_BIT_DESC(PMPME_MES_NOT_EN, imu_pme, imu_rds) }, 12227Sjchu { IMU_BIT_DESC(FATAL_MES_NOT_EN, imu_rbne, imu_rds) }, 12327Sjchu { IMU_BIT_DESC(NONFATAL_MES_NOT_EN, imu_rbne, imu_rds) }, 12427Sjchu { IMU_BIT_DESC(COR_MES_NOT_EN, imu_rbne, imu_rds) }, 12527Sjchu { IMU_BIT_DESC(MSI_NOT_EN, imu_rbne, imu_rds) }, 12627Sjchu 12727Sjchu /* DMC IMU SCS - see io erpt doc, section 2.2 */ 12827Sjchu { IMU_BIT_DESC(EQ_NOT_EN, imu_rbne, imu_rds) }, 12927Sjchu 13027Sjchu /* DMC IMU - see io erpt doc, section 2.3 */ 13127Sjchu { IMU_BIT_DESC(EQ_OVER, imu_eq_ovfl, imu) } 13227Sjchu }; 13327Sjchu 13427Sjchu #define px_err_imu_keys (sizeof (px_err_imu_tbl)) / (sizeof (px_err_bit_desc_t)) 13527Sjchu 13627Sjchu /* mmu errors */ 13727Sjchu #define MMU_BIT_DESC(bit, hdl, erpt) \ 13827Sjchu MMU_INTERRUPT_STATUS_ ## bit ## _P, \ 13927Sjchu 0, \ 14027Sjchu PX_ERR_BIT_HANDLE(hdl), \ 14127Sjchu PX_ERPT_SEND(erpt), \ 14227Sjchu PX_ERR_DMC_CLASS(bit) 14327Sjchu px_err_bit_desc_t px_err_mmu_tbl[] = { 14427Sjchu /* DMC MMU TFAR/TFSR - see io erpt doc, section 2.4 */ 14527Sjchu { MMU_BIT_DESC(BYP_ERR, mmu_rbne, mmu_tfar_tfsr) }, 14627Sjchu { MMU_BIT_DESC(BYP_OOR, mmu_tfa, mmu_tfar_tfsr) }, 14727Sjchu { MMU_BIT_DESC(TRN_ERR, mmu_rbne, mmu_tfar_tfsr) }, 14827Sjchu { MMU_BIT_DESC(TRN_OOR, mmu_tfa, mmu_tfar_tfsr) }, 14927Sjchu { MMU_BIT_DESC(TTE_INV, mmu_tfa, mmu_tfar_tfsr) }, 15027Sjchu { MMU_BIT_DESC(TTE_PRT, mmu_tfa, mmu_tfar_tfsr) }, 15127Sjchu { MMU_BIT_DESC(TTC_DPE, mmu_tfa, mmu_tfar_tfsr) }, 15227Sjchu { MMU_BIT_DESC(TBW_DME, mmu_tblwlk, mmu_tfar_tfsr) }, 15327Sjchu { MMU_BIT_DESC(TBW_UDE, mmu_tblwlk, mmu_tfar_tfsr) }, 15427Sjchu { MMU_BIT_DESC(TBW_ERR, mmu_tblwlk, mmu_tfar_tfsr) }, 15527Sjchu { MMU_BIT_DESC(TBW_DPE, mmu_tblwlk, mmu_tfar_tfsr) }, 15627Sjchu 15727Sjchu /* DMC MMU - see io erpt doc, section 2.5 */ 15827Sjchu { MMU_BIT_DESC(TTC_CAE, non_fatal, mmu) } 15927Sjchu }; 16027Sjchu #define px_err_mmu_keys (sizeof (px_err_mmu_tbl)) / (sizeof (px_err_bit_desc_t)) 16127Sjchu 16227Sjchu /* 16327Sjchu * PEC error bit tables 16427Sjchu */ 16527Sjchu #define ILU_BIT_DESC(bit, hdl, erpt) \ 16627Sjchu ILU_INTERRUPT_STATUS_ ## bit ## _P, \ 16727Sjchu 0, \ 16827Sjchu PX_ERR_BIT_HANDLE(hdl), \ 16927Sjchu PX_ERPT_SEND(erpt), \ 17027Sjchu PX_ERR_PEC_CLASS(bit) 17127Sjchu px_err_bit_desc_t px_err_ilu_tbl[] = { 17227Sjchu /* PEC ILU none - see io erpt doc, section 3.1 */ 17327Sjchu { ILU_BIT_DESC(IHB_PE, fatal_gos, pec_ilu) } 17427Sjchu }; 17527Sjchu #define px_err_ilu_keys \ 17627Sjchu (sizeof (px_err_ilu_tbl)) / (sizeof (px_err_bit_desc_t)) 17727Sjchu 17827Sjchu /* 17927Sjchu * PEC UE errors implementation is incomplete pending PCIE generic 180383Set142600 * fabric rules. Must handle both PRIMARY and SECONDARY errors. 18127Sjchu */ 18227Sjchu /* pec ue errors */ 18327Sjchu #define TLU_UC_BIT_DESC(bit, hdl, erpt) \ 18427Sjchu TLU_UNCORRECTABLE_ERROR_STATUS_CLEAR_ ## bit ## _P, \ 18527Sjchu 0, \ 186383Set142600 PX_ERR_BIT_HANDLE(hdl), \ 187383Set142600 PX_ERPT_SEND(erpt), \ 188383Set142600 PX_ERR_PEC_CLASS(bit) }, \ 189383Set142600 { TLU_UNCORRECTABLE_ERROR_STATUS_CLEAR_ ## bit ## _S, \ 190383Set142600 0, \ 191383Set142600 PX_ERR_BIT_HANDLE(hdl), \ 192383Set142600 PX_ERPT_SEND(erpt), \ 193383Set142600 PX_ERR_PEC_CLASS(bit) 19427Sjchu px_err_bit_desc_t px_err_tlu_ue_tbl[] = { 19527Sjchu /* PCI-E Receive Uncorrectable Errors - see io erpt doc, section 3.2 */ 196383Set142600 { TLU_UC_BIT_DESC(UR, pciex_ue, pciex_rx_ue) }, 197383Set142600 { TLU_UC_BIT_DESC(UC, pciex_ue, pciex_rx_ue) }, 19827Sjchu 19927Sjchu /* PCI-E Transmit Uncorrectable Errors - see io erpt doc, section 3.3 */ 200383Set142600 { TLU_UC_BIT_DESC(CTO, pciex_ue, pciex_tx_ue) }, 201383Set142600 { TLU_UC_BIT_DESC(ROF, pciex_ue, pciex_tx_ue) }, 20227Sjchu 20327Sjchu /* PCI-E Rx/Tx Uncorrectable Errors - see io erpt doc, section 3.4 */ 204383Set142600 { TLU_UC_BIT_DESC(MFP, pciex_ue, pciex_rx_tx_ue) }, 205383Set142600 { TLU_UC_BIT_DESC(PP, pciex_ue, pciex_rx_tx_ue) }, 20627Sjchu 20727Sjchu /* Other PCI-E Uncorrectable Errors - see io erpt doc, section 3.5 */ 208383Set142600 { TLU_UC_BIT_DESC(FCP, pciex_ue, pciex_ue) }, 209383Set142600 { TLU_UC_BIT_DESC(DLP, pciex_ue, pciex_ue) }, 210383Set142600 { TLU_UC_BIT_DESC(TE, pciex_ue, pciex_ue) }, 211383Set142600 212383Set142600 /* Not used */ 213383Set142600 { TLU_UC_BIT_DESC(CA, pciex_ue, do_not) } 21427Sjchu }; 21527Sjchu #define px_err_tlu_ue_keys \ 21627Sjchu (sizeof (px_err_tlu_ue_tbl)) / (sizeof (px_err_bit_desc_t)) 21727Sjchu 21827Sjchu /* 21927Sjchu * PEC CE errors implementation is incomplete pending PCIE generic 22027Sjchu * fabric rules. 22127Sjchu */ 22227Sjchu /* pec ce errors */ 22327Sjchu #define TLU_CE_BIT_DESC(bit, hdl, erpt) \ 22427Sjchu TLU_CORRECTABLE_ERROR_STATUS_CLEAR_ ## bit ## _P, \ 22527Sjchu 0, \ 226383Set142600 PX_ERR_BIT_HANDLE(hdl), \ 227383Set142600 PX_ERPT_SEND(erpt), \ 228383Set142600 PX_ERR_PEC_CLASS(bit) }, \ 229383Set142600 { TLU_CORRECTABLE_ERROR_STATUS_CLEAR_ ## bit ## _S, \ 230383Set142600 0, \ 231383Set142600 PX_ERR_BIT_HANDLE(hdl), \ 232383Set142600 PX_ERPT_SEND(erpt), \ 233383Set142600 PX_ERR_PEC_CLASS(bit) 23427Sjchu px_err_bit_desc_t px_err_tlu_ce_tbl[] = { 23527Sjchu /* PCI-E Correctable Errors - see io erpt doc, section 3.6 */ 236383Set142600 { TLU_CE_BIT_DESC(RTO, pciex_ce, pciex_ce) }, 237383Set142600 { TLU_CE_BIT_DESC(RNR, pciex_ce, pciex_ce) }, 238383Set142600 { TLU_CE_BIT_DESC(BDP, pciex_ce, pciex_ce) }, 239383Set142600 { TLU_CE_BIT_DESC(BTP, pciex_ce, pciex_ce) }, 240383Set142600 { TLU_CE_BIT_DESC(RE, pciex_ce, pciex_ce) } 24127Sjchu }; 24227Sjchu #define px_err_tlu_ce_keys \ 24327Sjchu (sizeof (px_err_tlu_ce_tbl)) / (sizeof (px_err_bit_desc_t)) 24427Sjchu 24527Sjchu /* pec oe errors */ 24627Sjchu #define TLU_OE_BIT_DESC(bit, hdl, erpt) \ 24727Sjchu TLU_OTHER_EVENT_STATUS_CLEAR_ ## bit ## _P, \ 24827Sjchu 0, \ 24927Sjchu PX_ERR_BIT_HANDLE(hdl), \ 25027Sjchu PX_ERPT_SEND(erpt), \ 25127Sjchu PX_ERR_PEC_CLASS(bit) 25227Sjchu px_err_bit_desc_t px_err_tlu_oe_tbl[] = { 25327Sjchu /* 25427Sjchu * TLU Other Event Status (receive only) - see io erpt doc, section 3.7 25527Sjchu */ 25627Sjchu { TLU_OE_BIT_DESC(MRC, fatal_hw, pciex_rx_oe) }, 25727Sjchu 25827Sjchu /* TLU Other Event Status (rx + tx) - see io erpt doc, section 3.8 */ 259383Set142600 { TLU_OE_BIT_DESC(WUC, non_fatal, pciex_rx_tx_oe) }, 260383Set142600 { TLU_OE_BIT_DESC(RUC, non_fatal, pciex_rx_tx_oe) }, 26127Sjchu { TLU_OE_BIT_DESC(CRS, non_fatal, pciex_rx_tx_oe) }, 26227Sjchu 26327Sjchu /* TLU Other Event - see io erpt doc, section 3.9 */ 26427Sjchu { TLU_OE_BIT_DESC(IIP, fatal_gos, pciex_oe) }, 26527Sjchu { TLU_OE_BIT_DESC(EDP, fatal_gos, pciex_oe) }, 26627Sjchu { TLU_OE_BIT_DESC(EHP, fatal_gos, pciex_oe) }, 26727Sjchu { TLU_OE_BIT_DESC(LIN, non_fatal, pciex_oe) }, 26827Sjchu { TLU_OE_BIT_DESC(LRS, non_fatal, pciex_oe) }, 269287Smg140465 { TLU_OE_BIT_DESC(LDN, non_fatal, pciex_ldn) }, 270287Smg140465 { TLU_OE_BIT_DESC(LUP, tlu_lup, pciex_lup) }, 27127Sjchu { TLU_OE_BIT_DESC(ERU, fatal_gos, pciex_oe) }, 27227Sjchu { TLU_OE_BIT_DESC(ERO, fatal_gos, pciex_oe) }, 27327Sjchu { TLU_OE_BIT_DESC(EMP, fatal_gos, pciex_oe) }, 27427Sjchu { TLU_OE_BIT_DESC(EPE, fatal_gos, pciex_oe) }, 27527Sjchu { TLU_OE_BIT_DESC(ERP, fatal_gos, pciex_oe) }, 27627Sjchu { TLU_OE_BIT_DESC(EIP, fatal_gos, pciex_oe) } 27727Sjchu }; 27827Sjchu 27927Sjchu #define px_err_tlu_oe_keys \ 28027Sjchu (sizeof (px_err_tlu_oe_tbl)) / (sizeof (px_err_bit_desc_t)) 28127Sjchu 28227Sjchu /* 28327Sjchu * All the following tables below are for LPU Interrupts. These interrupts 28427Sjchu * are *NOT* error interrupts, but event status interrupts. 28527Sjchu * 28627Sjchu * These events are probably of most interest to: 28727Sjchu * o Hotplug 28827Sjchu * o Power Management 28927Sjchu * o etc... 29027Sjchu * 29127Sjchu * There are also a few events that would be interresting for FMA. 29227Sjchu * Again none of the regiseters below state that an error has occured 29327Sjchu * or that data has been lost. If anything, they give status that an 29427Sjchu * error is *about* to occur. examples 29527Sjchu * o INT_SKP_ERR - indicates clock between fire and child is too far 29627Sjchu * off and is most unlikely able to compensate 29727Sjchu * o INT_TX_PAR_ERR - A parity error occured in ONE lane. This is 29827Sjchu * HW recoverable, but will like end up as a future 29927Sjchu * fabric error as well. 30027Sjchu * 30127Sjchu * For now, we don't care about any of these errors and should be ignore, 30227Sjchu * but cleared. 30327Sjchu */ 30427Sjchu 30527Sjchu /* LPU Link Interrupt Table */ 30627Sjchu #define LPUL_BIT_DESC(bit, hdl, erpt) \ 30727Sjchu LPU_LINK_LAYER_INTERRUPT_AND_STATUS_INT_ ## bit, \ 30827Sjchu 0, \ 30927Sjchu NULL, \ 31027Sjchu NULL, \ 31127Sjchu "" 31227Sjchu px_err_bit_desc_t px_err_lpul_tbl[] = { 31327Sjchu { LPUL_BIT_DESC(LINK_ERR_ACT, NULL, NULL) } 31427Sjchu }; 31527Sjchu #define px_err_lpul_keys \ 31627Sjchu (sizeof (px_err_lpul_tbl)) / (sizeof (px_err_bit_desc_t)) 31727Sjchu 31827Sjchu /* LPU Physical Interrupt Table */ 31927Sjchu #define LPUP_BIT_DESC(bit, hdl, erpt) \ 32027Sjchu LPU_PHY_LAYER_INTERRUPT_AND_STATUS_INT_ ## bit, \ 32127Sjchu 0, \ 32227Sjchu NULL, \ 32327Sjchu NULL, \ 32427Sjchu "" 32527Sjchu px_err_bit_desc_t px_err_lpup_tbl[] = { 32627Sjchu { LPUP_BIT_DESC(PHY_LAYER_ERR, NULL, NULL) } 32727Sjchu }; 32827Sjchu #define px_err_lpup_keys \ 32927Sjchu (sizeof (px_err_lpup_tbl)) / (sizeof (px_err_bit_desc_t)) 33027Sjchu 33127Sjchu /* LPU Receive Interrupt Table */ 33227Sjchu #define LPUR_BIT_DESC(bit, hdl, erpt) \ 33327Sjchu LPU_RECEIVE_PHY_INTERRUPT_AND_STATUS_INT_ ## bit, \ 33427Sjchu 0, \ 33527Sjchu NULL, \ 33627Sjchu NULL, \ 33727Sjchu "" 33827Sjchu px_err_bit_desc_t px_err_lpur_tbl[] = { 33927Sjchu { LPUR_BIT_DESC(RCV_PHY, NULL, NULL) } 34027Sjchu }; 34127Sjchu #define px_err_lpur_keys \ 34227Sjchu (sizeof (px_err_lpur_tbl)) / (sizeof (px_err_bit_desc_t)) 34327Sjchu 34427Sjchu /* LPU Transmit Interrupt Table */ 34527Sjchu #define LPUX_BIT_DESC(bit, hdl, erpt) \ 34627Sjchu LPU_TRANSMIT_PHY_INTERRUPT_AND_STATUS_INT_ ## bit, \ 34727Sjchu 0, \ 34827Sjchu NULL, \ 34927Sjchu NULL, \ 35027Sjchu "" 35127Sjchu px_err_bit_desc_t px_err_lpux_tbl[] = { 35227Sjchu { LPUX_BIT_DESC(UNMSK, NULL, NULL) } 35327Sjchu }; 35427Sjchu #define px_err_lpux_keys \ 35527Sjchu (sizeof (px_err_lpux_tbl)) / (sizeof (px_err_bit_desc_t)) 35627Sjchu 35727Sjchu /* LPU LTSSM Interrupt Table */ 35827Sjchu #define LPUS_BIT_DESC(bit, hdl, erpt) \ 35927Sjchu LPU_LTSSM_INTERRUPT_AND_STATUS_INT_ ## bit, \ 36027Sjchu 0, \ 36127Sjchu NULL, \ 36227Sjchu NULL, \ 36327Sjchu "" 36427Sjchu px_err_bit_desc_t px_err_lpus_tbl[] = { 36527Sjchu { LPUS_BIT_DESC(ANY, NULL, NULL) } 36627Sjchu }; 36727Sjchu #define px_err_lpus_keys \ 36827Sjchu (sizeof (px_err_lpus_tbl)) / (sizeof (px_err_bit_desc_t)) 36927Sjchu 37027Sjchu /* LPU Gigablaze Glue Interrupt Table */ 37127Sjchu #define LPUG_BIT_DESC(bit, hdl, erpt) \ 37227Sjchu LPU_GIGABLAZE_GLUE_INTERRUPT_AND_STATUS_INT_ ## bit, \ 37327Sjchu 0, \ 37427Sjchu NULL, \ 37527Sjchu NULL, \ 37627Sjchu "" 37727Sjchu px_err_bit_desc_t px_err_lpug_tbl[] = { 37827Sjchu { LPUG_BIT_DESC(GLOBL_UNMSK, NULL, NULL) } 37927Sjchu }; 38027Sjchu #define px_err_lpug_keys \ 38127Sjchu (sizeof (px_err_lpug_tbl)) / (sizeof (px_err_bit_desc_t)) 38227Sjchu 38327Sjchu 38427Sjchu /* Mask and Tables */ 38527Sjchu #define MnT6(pre) \ 38627Sjchu B_FALSE, \ 38727Sjchu &px_ ## pre ## _intr_mask, \ 38827Sjchu &px_ ## pre ## _log_mask, \ 38927Sjchu &px_ ## pre ## _count_mask, \ 39027Sjchu px_err_ ## pre ## _tbl, \ 39127Sjchu px_err_ ## pre ## _keys, \ 39227Sjchu 0 39327Sjchu 39427Sjchu /* LPU Registers Addresses */ 39527Sjchu #define LR4(pre) \ 39627Sjchu NULL, \ 39727Sjchu LPU_ ## pre ## _INTERRUPT_MASK, \ 39827Sjchu LPU_ ## pre ## _INTERRUPT_AND_STATUS, \ 39927Sjchu LPU_ ## pre ## _INTERRUPT_AND_STATUS 40027Sjchu 40127Sjchu /* LPU Registers Addresses with Irregularities */ 40227Sjchu #define LR4_FIXME(pre) \ 40327Sjchu NULL, \ 40427Sjchu LPU_ ## pre ## _INTERRUPT_MASK, \ 40527Sjchu LPU_ ## pre ## _LAYER_INTERRUPT_AND_STATUS, \ 40627Sjchu LPU_ ## pre ## _LAYER_INTERRUPT_AND_STATUS 40727Sjchu 40827Sjchu /* TLU Registers Addresses */ 40927Sjchu #define TR4(pre) \ 41027Sjchu TLU_ ## pre ## _LOG_ENABLE, \ 41127Sjchu TLU_ ## pre ## _INTERRUPT_ENABLE, \ 41227Sjchu TLU_ ## pre ## _INTERRUPT_STATUS, \ 41327Sjchu TLU_ ## pre ## _STATUS_CLEAR 41427Sjchu 41527Sjchu /* Registers Addresses for JBC, MMU, IMU and ILU */ 41627Sjchu #define R4(pre) \ 41727Sjchu pre ## _ERROR_LOG_ENABLE, \ 41827Sjchu pre ## _INTERRUPT_ENABLE, \ 41927Sjchu pre ## _INTERRUPT_STATUS, \ 42027Sjchu pre ## _ERROR_STATUS_CLEAR 42127Sjchu 42227Sjchu /* 42327Sjchu * Register error handling tables. 42427Sjchu * The ID Field (first field) is identified by an enum px_err_id_t. 42527Sjchu * It is located in px_err.h 42627Sjchu */ 42727Sjchu px_err_reg_desc_t px_err_reg_tbl[] = { 42827Sjchu { MnT6(cb), R4(JBC), "JBC Error"}, 429*435Sjchu { MnT6(mmu), R4(MMU), "MMU Error"}, 430*435Sjchu { MnT6(imu), R4(IMU), "IMU Error"}, 43127Sjchu { MnT6(tlu_ue), TR4(UNCORRECTABLE_ERROR), "TLU UE"}, 43227Sjchu { MnT6(tlu_ce), TR4(CORRECTABLE_ERROR), "TLU CE"}, 43327Sjchu { MnT6(tlu_oe), TR4(OTHER_EVENT), "TLU OE"}, 434*435Sjchu { MnT6(ilu), R4(ILU), "ILU Error"}, 43527Sjchu { MnT6(lpul), LR4(LINK_LAYER), "LPU Link Layer"}, 43627Sjchu { MnT6(lpup), LR4_FIXME(PHY), "LPU Phy Layer"}, 43727Sjchu { MnT6(lpur), LR4(RECEIVE_PHY), "LPU RX Phy Layer"}, 43827Sjchu { MnT6(lpux), LR4(TRANSMIT_PHY), "LPU TX Phy Layer"}, 43927Sjchu { MnT6(lpus), LR4(LTSSM), "LPU LTSSM"}, 44027Sjchu { MnT6(lpug), LR4(GIGABLAZE_GLUE), "LPU GigaBlaze Glue"} 44127Sjchu }; 44227Sjchu #define PX_ERR_REG_KEYS (sizeof (px_err_reg_tbl)) / (sizeof (px_err_reg_tbl[0])) 44327Sjchu 44427Sjchu typedef struct px_err_ss { 44527Sjchu uint64_t err_status[PX_ERR_REG_KEYS]; 44627Sjchu } px_err_ss_t; 44727Sjchu 44827Sjchu static void px_err_snapshot(px_t *px_p, px_err_ss_t *ss, boolean_t chkjbc); 44927Sjchu static int px_err_erpt_and_clr(px_t *px_p, ddi_fm_error_t *derr, 45027Sjchu px_err_ss_t *ss); 45127Sjchu static int px_err_check_severity(px_t *px_p, ddi_fm_error_t *derr, 45227Sjchu int err, int caller); 45327Sjchu 45427Sjchu /* 45527Sjchu * px_err_cb_intr: 45627Sjchu * Interrupt handler for the JBC block. 45727Sjchu * o lock 45827Sjchu * o create derr 45927Sjchu * o px_err_handle(leaf1, with jbc) 46027Sjchu * o px_err_handle(leaf2, without jbc) 46127Sjchu * o dispatch (leaf1) 46227Sjchu * o dispatch (leaf2) 46327Sjchu * o unlock 46427Sjchu * o handle error: fatal? fm_panic() : return INTR_CLAIMED) 46527Sjchu */ 46627Sjchu uint_t 46727Sjchu px_err_cb_intr(caddr_t arg) 46827Sjchu { 46927Sjchu px_fault_t *px_fault_p = (px_fault_t *)arg; 47027Sjchu dev_info_t *rpdip = px_fault_p->px_fh_dip; 47127Sjchu dev_info_t *leafdip; 47227Sjchu px_t *px_p = DIP_TO_STATE(rpdip); 47327Sjchu px_cb_t *cb_p = px_p->px_cb_p; 474118Sjchu int err = PX_OK; 475118Sjchu int ret = DDI_FM_OK; 47627Sjchu int fatal = 0; 47727Sjchu int nonfatal = 0; 47827Sjchu int unknown = 0; 47927Sjchu int i; 48027Sjchu boolean_t chkjbc = B_TRUE; 48127Sjchu ddi_fm_error_t derr; 48227Sjchu 48327Sjchu /* Create the derr */ 48427Sjchu bzero(&derr, sizeof (ddi_fm_error_t)); 48527Sjchu derr.fme_version = DDI_FME_VERSION; 48627Sjchu derr.fme_ena = fm_ena_generate(0, FM_ENA_FMT1); 48727Sjchu derr.fme_flag = DDI_FM_ERR_UNEXPECTED; 48827Sjchu 48927Sjchu mutex_enter(&cb_p->xbc_fm_mutex); 49027Sjchu 49127Sjchu /* send ereport/handle/clear for ALL fire leaves */ 49227Sjchu for (i = 0; i < PX_CB_MAX_LEAF; i++) { 49327Sjchu if ((px_p = cb_p->xbc_px_list[i]) == NULL) 49427Sjchu continue; 49527Sjchu 49627Sjchu err |= px_err_handle(px_p, &derr, PX_INTR_CALL, chkjbc); 49727Sjchu chkjbc = B_FALSE; 49827Sjchu } 49927Sjchu 50027Sjchu /* Check all child devices for errors on ALL fire leaves */ 50127Sjchu for (i = 0; i < PX_CB_MAX_LEAF; i++) { 50227Sjchu if ((px_p = cb_p->xbc_px_list[i]) != NULL) { 50327Sjchu leafdip = px_p->px_dip; 50427Sjchu ret = ndi_fm_handler_dispatch(leafdip, NULL, &derr); 50527Sjchu switch (ret) { 50627Sjchu case DDI_FM_FATAL: 50727Sjchu fatal++; 50827Sjchu break; 50927Sjchu case DDI_FM_NONFATAL: 51027Sjchu nonfatal++; 51127Sjchu break; 51227Sjchu case DDI_FM_UNKNOWN: 51327Sjchu unknown++; 51427Sjchu break; 51527Sjchu default: 51627Sjchu break; 51727Sjchu } 51827Sjchu } 51927Sjchu } 52027Sjchu 52127Sjchu /* Set the intr state to idle for the leaf that received the mondo */ 52227Sjchu (void) px_lib_intr_setstate(rpdip, px_fault_p->px_fh_sysino, 52327Sjchu INTR_IDLE_STATE); 52427Sjchu 52527Sjchu mutex_exit(&cb_p->xbc_fm_mutex); 52627Sjchu 52727Sjchu /* 52827Sjchu * PX_FATAL_HW error is diagnosed after system recovered from 52927Sjchu * HW initiated reset, therefore no furthur handling is required. 53027Sjchu */ 53127Sjchu if (fatal || err & (PX_FATAL_GOS | PX_FATAL_SW)) 53227Sjchu fm_panic("Fatal System Bus Error has occurred\n"); 53327Sjchu 53427Sjchu return (DDI_INTR_CLAIMED); 53527Sjchu } 53627Sjchu 53727Sjchu /* 53827Sjchu * px_err_dmc_pec_intr: 53927Sjchu * Interrupt handler for the DMC/PEC block. 54027Sjchu * o lock 54127Sjchu * o create derr 54227Sjchu * o px_err_handle(leaf, with jbc) 54327Sjchu * o dispatch (leaf) 54427Sjchu * o unlock 54527Sjchu * o handle error: fatal? fm_panic() : return INTR_CLAIMED) 54627Sjchu */ 54727Sjchu uint_t 54827Sjchu px_err_dmc_pec_intr(caddr_t arg) 54927Sjchu { 55027Sjchu px_fault_t *px_fault_p = (px_fault_t *)arg; 55127Sjchu dev_info_t *rpdip = px_fault_p->px_fh_dip; 55227Sjchu px_t *px_p = DIP_TO_STATE(rpdip); 55327Sjchu px_cb_t *cb_p = px_p->px_cb_p; 554118Sjchu int err = PX_OK; 555118Sjchu int ret = DDI_FM_OK; 55627Sjchu ddi_fm_error_t derr; 55727Sjchu 55827Sjchu /* Create the derr */ 55927Sjchu bzero(&derr, sizeof (ddi_fm_error_t)); 56027Sjchu derr.fme_version = DDI_FME_VERSION; 56127Sjchu derr.fme_ena = fm_ena_generate(0, FM_ENA_FMT1); 56227Sjchu derr.fme_flag = DDI_FM_ERR_UNEXPECTED; 56327Sjchu 56427Sjchu mutex_enter(&cb_p->xbc_fm_mutex); 56527Sjchu 56627Sjchu /* send ereport/handle/clear fire registers */ 56727Sjchu err |= px_err_handle(px_p, &derr, PX_INTR_CALL, B_TRUE); 56827Sjchu 56927Sjchu /* Check all child devices for errors */ 57027Sjchu ret = ndi_fm_handler_dispatch(rpdip, NULL, &derr); 57127Sjchu 57227Sjchu /* Set the interrupt state to idle */ 57327Sjchu (void) px_lib_intr_setstate(rpdip, px_fault_p->px_fh_sysino, 57427Sjchu INTR_IDLE_STATE); 57527Sjchu 57627Sjchu mutex_exit(&cb_p->xbc_fm_mutex); 57727Sjchu 57827Sjchu /* 57927Sjchu * PX_FATAL_HW indicates a condition recovered from Fatal-Reset, 58027Sjchu * therefore it does not cause panic. 58127Sjchu */ 58227Sjchu if ((err & (PX_FATAL_GOS | PX_FATAL_SW)) || (ret == DDI_FM_FATAL)) 58327Sjchu fm_panic("Fatal System Port Error has occurred\n"); 58427Sjchu 58527Sjchu return (DDI_INTR_CLAIMED); 58627Sjchu } 58727Sjchu 58827Sjchu /* 58927Sjchu * Error register are being handled by px_hlib xxx_init functions. 59027Sjchu * They are also called again by px_err_add_intr for mondo62 and 63 59127Sjchu * from px_cb_attach and px_attach 59227Sjchu */ 59327Sjchu void 59427Sjchu px_err_reg_enable(px_t *px_p, px_err_id_t id) 59527Sjchu { 59627Sjchu px_err_reg_desc_t *reg_desc = &px_err_reg_tbl[id]; 59727Sjchu uint64_t intr_mask = *reg_desc->intr_mask_p; 59827Sjchu uint64_t log_mask = *reg_desc->log_mask_p; 59927Sjchu caddr_t csr_base; 60027Sjchu pxu_t *pxu_p = (pxu_t *)px_p->px_plat_p; 60127Sjchu 60227Sjchu if (id == PX_ERR_JBC) 60327Sjchu csr_base = (caddr_t)pxu_p->px_address[PX_REG_XBC]; 60427Sjchu else 60527Sjchu csr_base = (caddr_t)pxu_p->px_address[PX_REG_CSR]; 60627Sjchu 60727Sjchu reg_desc->enabled = B_TRUE; 60827Sjchu 60927Sjchu /* Enable logs if it exists */ 61027Sjchu if (reg_desc->log_addr != NULL) 61127Sjchu CSR_XS(csr_base, reg_desc->log_addr, log_mask); 61227Sjchu 61327Sjchu /* 61427Sjchu * For readability you in code you set 1 to enable an interrupt. 61527Sjchu * But in Fire it's backwards. You set 1 to *disable* an intr. 61627Sjchu * Reverse the user tunable intr mask field. 61727Sjchu * 61827Sjchu * Disable All Errors 61927Sjchu * Clear All Errors 62027Sjchu * Enable Errors 62127Sjchu */ 62227Sjchu CSR_XS(csr_base, reg_desc->enable_addr, 0); 62327Sjchu CSR_XS(csr_base, reg_desc->clear_addr, -1); 62427Sjchu CSR_XS(csr_base, reg_desc->enable_addr, intr_mask); 62527Sjchu DBG(DBG_ATTACH, NULL, "%s Mask: 0x%llx\n", 62627Sjchu reg_desc->msg, CSR_XR(csr_base, reg_desc->enable_addr)); 62727Sjchu DBG(DBG_ATTACH, NULL, "%s Status: 0x%llx\n", 62827Sjchu reg_desc->msg, CSR_XR(csr_base, reg_desc->status_addr)); 62927Sjchu DBG(DBG_ATTACH, NULL, "%s Clear: 0x%llx\n", 63027Sjchu reg_desc->msg, CSR_XR(csr_base, reg_desc->clear_addr)); 63127Sjchu if (reg_desc->log_addr != NULL) { 63227Sjchu DBG(DBG_ATTACH, NULL, "%s Log: 0x%llx\n", 63327Sjchu reg_desc->msg, CSR_XR(csr_base, reg_desc->log_addr)); 63427Sjchu } 63527Sjchu } 63627Sjchu 63727Sjchu void 63827Sjchu px_err_reg_disable(px_t *px_p, px_err_id_t id) 63927Sjchu { 64027Sjchu px_err_reg_desc_t *reg_desc = &px_err_reg_tbl[id]; 64127Sjchu caddr_t csr_base; 64227Sjchu 64327Sjchu if (id == PX_ERR_JBC) 64427Sjchu csr_base = (caddr_t)px_p->px_inos[PX_INTR_XBC]; 64527Sjchu else 64627Sjchu csr_base = (caddr_t)px_p->px_inos[PX_INTR_PEC]; 64727Sjchu 64827Sjchu reg_desc->enabled = B_FALSE; 64927Sjchu 65027Sjchu switch (id) { 65127Sjchu case PX_ERR_JBC: 65227Sjchu case PX_ERR_MMU: 65327Sjchu case PX_ERR_IMU: 65427Sjchu case PX_ERR_TLU_UE: 65527Sjchu case PX_ERR_TLU_CE: 65627Sjchu case PX_ERR_TLU_OE: 65727Sjchu case PX_ERR_ILU: 65827Sjchu if (reg_desc->log_addr != NULL) { 65927Sjchu CSR_XS(csr_base, reg_desc->log_addr, 0); 66027Sjchu } 66127Sjchu CSR_XS(csr_base, reg_desc->enable_addr, 0); 66227Sjchu break; 66327Sjchu case PX_ERR_LPU_LINK: 66427Sjchu case PX_ERR_LPU_PHY: 66527Sjchu case PX_ERR_LPU_RX: 66627Sjchu case PX_ERR_LPU_TX: 66727Sjchu case PX_ERR_LPU_LTSSM: 66827Sjchu case PX_ERR_LPU_GIGABLZ: 66927Sjchu if (reg_desc->log_addr != NULL) { 67027Sjchu CSR_XS(csr_base, reg_desc->log_addr, -1); 67127Sjchu } 67227Sjchu CSR_XS(csr_base, reg_desc->enable_addr, -1); 67327Sjchu break; 67427Sjchu } 67527Sjchu } 67627Sjchu 67727Sjchu /* 67827Sjchu * px_err_handle: 67927Sjchu * Common function called by trap, mondo and fabric intr. 68027Sjchu * o Snap shot current fire registers 68127Sjchu * o check for safe access 68227Sjchu * o send ereport and clear snap shot registers 68327Sjchu * o check severity of snap shot registers 68427Sjchu * 68527Sjchu * @param px_p leaf in which to check access 68627Sjchu * @param derr fm err data structure to be updated 68727Sjchu * @param caller PX_TRAP_CALL | PX_INTR_CALL 68827Sjchu * @param chkjbc whether to handle jbc registers 68927Sjchu * @return err PX_OK | PX_NONFATAL | 69027Sjchu * PX_FATAL_GOS | PX_FATAL_HW | PX_STUCK_FATAL 69127Sjchu */ 69227Sjchu int 69327Sjchu px_err_handle(px_t *px_p, ddi_fm_error_t *derr, int caller, 69427Sjchu boolean_t chkjbc) 69527Sjchu { 69627Sjchu px_cb_t *cb_p = px_p->px_cb_p; /* for fm_mutex */ 69727Sjchu px_err_ss_t ss; 698118Sjchu int err = PX_OK; 69927Sjchu 70027Sjchu ASSERT(MUTEX_HELD(&cb_p->xbc_fm_mutex)); 70127Sjchu 70227Sjchu /* snap shot the current fire registers */ 70327Sjchu px_err_snapshot(px_p, &ss, chkjbc); 70427Sjchu 70527Sjchu /* check for safe access */ 70627Sjchu px_err_safeacc_check(px_p, derr); 70727Sjchu 70827Sjchu /* send ereports/handle/clear registers */ 70927Sjchu err = px_err_erpt_and_clr(px_p, derr, &ss); 71027Sjchu 71127Sjchu /* check for error severity */ 71227Sjchu err = px_err_check_severity(px_p, derr, err, caller); 71327Sjchu 71427Sjchu /* Mark the On Trap Handle if an error occured */ 71527Sjchu if (err != PX_OK) { 71627Sjchu px_pec_t *pec_p = px_p->px_pec_p; 71727Sjchu on_trap_data_t *otd = pec_p->pec_ontrap_data; 71827Sjchu 719118Sjchu if ((otd != NULL) && (otd->ot_prot & OT_DATA_ACCESS)) 72027Sjchu otd->ot_trap |= OT_DATA_ACCESS; 72127Sjchu } 72227Sjchu 72327Sjchu return (err); 72427Sjchu } 72527Sjchu 72627Sjchu /* 72727Sjchu * Static function 72827Sjchu */ 72927Sjchu 73027Sjchu /* 73127Sjchu * px_err_snapshot: 73227Sjchu * Take a current snap shot of all the fire error registers. This includes 73327Sjchu * JBC, DMC, and PEC, unless chkjbc == false; 73427Sjchu * 73527Sjchu * @param px_p leaf in which to take the snap shot. 73627Sjchu * @param ss pre-allocated memory to store the snap shot. 73727Sjchu * @param chkjbc boolean on whether to store jbc register. 73827Sjchu */ 73927Sjchu static void 74027Sjchu px_err_snapshot(px_t *px_p, px_err_ss_t *ss, boolean_t chkjbc) 74127Sjchu { 74227Sjchu pxu_t *pxu_p = (pxu_t *)px_p->px_plat_p; 74327Sjchu caddr_t xbc_csr_base = (caddr_t)pxu_p->px_address[PX_REG_XBC]; 74427Sjchu caddr_t pec_csr_base = (caddr_t)pxu_p->px_address[PX_REG_CSR]; 74527Sjchu px_err_reg_desc_t *reg_desc; 74627Sjchu int reg_id; 74727Sjchu 74827Sjchu /* snapshot JBC interrupt status */ 74927Sjchu reg_id = PX_ERR_JBC; 75027Sjchu if (chkjbc == B_TRUE) { 75127Sjchu reg_desc = &px_err_reg_tbl[reg_id]; 75227Sjchu ss->err_status[reg_id] = CSR_XR(xbc_csr_base, 75327Sjchu reg_desc->status_addr); 75427Sjchu } else { 75527Sjchu ss->err_status[reg_id] = 0; 75627Sjchu } 75727Sjchu 75827Sjchu /* snapshot DMC/PEC interrupt status */ 75927Sjchu for (reg_id = 1; reg_id < PX_ERR_REG_KEYS; reg_id += 1) { 76027Sjchu reg_desc = &px_err_reg_tbl[reg_id]; 76127Sjchu ss->err_status[reg_id] = CSR_XR(pec_csr_base, 76227Sjchu reg_desc->status_addr); 76327Sjchu } 76427Sjchu } 76527Sjchu 76627Sjchu /* 76727Sjchu * px_err_erpt_and_clr: 76827Sjchu * This function does the following thing to all the fire registers based 76927Sjchu * on an earlier snap shot. 77027Sjchu * o Send ereport 77127Sjchu * o Handle the error 77227Sjchu * o Clear the error 77327Sjchu * 77427Sjchu * @param px_p leaf in which to take the snap shot. 77527Sjchu * @param derr fm err in which the ereport is to be based on 77627Sjchu * @param ss pre-allocated memory to store the snap shot. 77727Sjchu */ 77827Sjchu static int 77927Sjchu px_err_erpt_and_clr(px_t *px_p, ddi_fm_error_t *derr, px_err_ss_t *ss) 78027Sjchu { 78127Sjchu dev_info_t *rpdip = px_p->px_dip; 78227Sjchu px_cb_t *cb_p = px_p->px_cb_p; /* for fm_mutex */ 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; 79727Sjchu 79827Sjchu ASSERT(MUTEX_HELD(&cb_p->xbc_fm_mutex)); 79927Sjchu 80027Sjchu /* send erport/handle/clear JBC errors */ 80127Sjchu for (reg_id = 0; reg_id < PX_ERR_REG_KEYS; reg_id += 1) { 80227Sjchu /* Get the correct register description table */ 80327Sjchu err_reg_tbl = &px_err_reg_tbl[reg_id]; 80427Sjchu 80527Sjchu /* Get the correct CSR BASE */ 80627Sjchu if (reg_id == PX_ERR_JBC) { 80727Sjchu csr_base = (caddr_t)pxu_p->px_address[PX_REG_XBC]; 80827Sjchu } else { 80927Sjchu csr_base = (caddr_t)pxu_p->px_address[PX_REG_CSR]; 81027Sjchu } 81127Sjchu 81227Sjchu /* Get pointers to masks and register addresses */ 81327Sjchu log_mask = err_reg_tbl->log_mask_p; 81427Sjchu count_mask = err_reg_tbl->count_mask_p; 81527Sjchu status_addr = err_reg_tbl->status_addr; 81627Sjchu clear_addr = err_reg_tbl->clear_addr; 81727Sjchu ss_reg = ss->err_status[reg_id]; 81827Sjchu 81927Sjchu /* Get the register BIT description table */ 82027Sjchu err_bit_tbl = err_reg_tbl->err_bit_tbl; 82127Sjchu 82227Sjchu /* For each known bit in the register send erpt and handle */ 82327Sjchu for (key = 0; key < err_reg_tbl->err_bit_keys; key += 1) { 82427Sjchu /* Get the bit description table for this register */ 82527Sjchu err_bit_desc = &err_bit_tbl[key]; 82627Sjchu 82727Sjchu /* 82827Sjchu * If the ss_reg is set for this bit, 82927Sjchu * send ereport and handle 83027Sjchu */ 83127Sjchu if (BIT_TST(ss_reg, err_bit_desc->bit)) { 83227Sjchu /* Increment the counter if necessary */ 83327Sjchu if (BIT_TST(*count_mask, err_bit_desc->bit)) { 83427Sjchu err_bit_desc->counter++; 83527Sjchu } 83627Sjchu 83727Sjchu /* Error Handle for this bit */ 83827Sjchu err_handler = err_bit_desc->err_handler; 83927Sjchu if (err_handler) 84027Sjchu err |= err_handler(rpdip, 84127Sjchu csr_base, 84227Sjchu derr, 84327Sjchu err_reg_tbl, 84427Sjchu err_bit_desc); 84527Sjchu 846383Set142600 /* Send the ereport if it's an UNEXPECTED err */ 84727Sjchu erpt_handler = err_bit_desc->erpt_handler; 848383Set142600 if (derr->fme_flag == DDI_FM_ERR_UNEXPECTED) { 849383Set142600 if (erpt_handler) 850383Set142600 (void) erpt_handler(rpdip, 851383Set142600 csr_base, 852383Set142600 ss_reg, 853383Set142600 derr, 854383Set142600 err_bit_desc->class_name); 855383Set142600 } 85627Sjchu } 857383Set142600 85827Sjchu } 859332Sjchu 860332Sjchu /* Print register status */ 861332Sjchu if (ss_reg & *log_mask) 862332Sjchu DBG(DBG_ERR_INTR, rpdip, "<%x>=%16llx %s\n", 86327Sjchu status_addr, ss_reg, err_reg_tbl->msg); 86427Sjchu 86527Sjchu /* Clear the register and error */ 86627Sjchu CSR_XS(csr_base, clear_addr, ss_reg); 86727Sjchu } 86827Sjchu 86927Sjchu return (err); 87027Sjchu } 87127Sjchu 87227Sjchu /* 87327Sjchu * px_err_check_severity: 87427Sjchu * Check the severity of the fire error based on an earlier snapshot 87527Sjchu * 87627Sjchu * @param px_p leaf in which to take the snap shot. 87727Sjchu * @param derr fm err in which the ereport is to be based on 87827Sjchu * @param ss pre-allocated memory to store the snap shot. 87927Sjchu */ 88027Sjchu static int 88127Sjchu px_err_check_severity(px_t *px_p, ddi_fm_error_t *derr, int err, int caller) 88227Sjchu { 88327Sjchu px_pec_t *pec_p = px_p->px_pec_p; 88427Sjchu boolean_t is_safeacc = B_FALSE; 885118Sjchu 886118Sjchu /* nothing to do if called with no error */ 887118Sjchu if (err == PX_OK) 888118Sjchu return (err); 88927Sjchu 89027Sjchu /* Cautious access error handling */ 89127Sjchu switch (derr->fme_flag) { 89227Sjchu case DDI_FM_ERR_EXPECTED: 89327Sjchu if (caller == PX_TRAP_CALL) { 89427Sjchu /* 89527Sjchu * for ddi_caut_get treat all events as nonfatal 89627Sjchu * The trampoline will set err_ena = 0, 89727Sjchu * err_status = NONFATAL. 89827Sjchu */ 89927Sjchu derr->fme_status = DDI_FM_NONFATAL; 90027Sjchu is_safeacc = B_TRUE; 90127Sjchu } else { 90227Sjchu /* 90327Sjchu * For ddi_caut_put treat all events as nonfatal. Here 90427Sjchu * we have the handle and can call ndi_fm_acc_err_set(). 90527Sjchu */ 90627Sjchu derr->fme_status = DDI_FM_NONFATAL; 90727Sjchu ndi_fm_acc_err_set(pec_p->pec_acc_hdl, derr); 90827Sjchu is_safeacc = B_TRUE; 90927Sjchu } 91027Sjchu break; 91127Sjchu case DDI_FM_ERR_PEEK: 91227Sjchu case DDI_FM_ERR_POKE: 91327Sjchu /* 91427Sjchu * For ddi_peek/poke treat all events as nonfatal. 91527Sjchu */ 91627Sjchu is_safeacc = B_TRUE; 91727Sjchu break; 91827Sjchu default: 91927Sjchu is_safeacc = B_FALSE; 92027Sjchu } 92127Sjchu 92227Sjchu /* 92327Sjchu * The third argument "err" is passed in as error status from checking 92427Sjchu * Fire register, re-adjust error status from safe access. 92527Sjchu */ 92627Sjchu if (is_safeacc && !(err & PX_FATAL_GOS)) 927118Sjchu return (PX_NONFATAL); 92827Sjchu 929118Sjchu return (err); 93027Sjchu } 93127Sjchu 93227Sjchu /* predefined convenience functions */ 93327Sjchu /* ARGSUSED */ 93427Sjchu int 93527Sjchu px_err_fatal_hw_handle(dev_info_t *rpdip, caddr_t csr_base, 93627Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 93727Sjchu px_err_bit_desc_t *err_bit_descr) 93827Sjchu { 93927Sjchu return (PX_FATAL_HW); 94027Sjchu } 94127Sjchu 94227Sjchu /* ARGSUSED */ 94327Sjchu int 94427Sjchu px_err_fatal_gos_handle(dev_info_t *rpdip, caddr_t csr_base, 94527Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 94627Sjchu px_err_bit_desc_t *err_bit_descr) 94727Sjchu { 94827Sjchu return (PX_FATAL_GOS); 94927Sjchu } 95027Sjchu 95127Sjchu /* ARGSUSED */ 95227Sjchu int 95327Sjchu px_err_fatal_stuck_handle(dev_info_t *rpdip, caddr_t csr_base, 95427Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 95527Sjchu px_err_bit_desc_t *err_bit_descr) 95627Sjchu { 95727Sjchu return (PX_STUCK_FATAL); 95827Sjchu } 95927Sjchu 96027Sjchu /* ARGSUSED */ 96127Sjchu int 96227Sjchu px_err_fatal_sw_handle(dev_info_t *rpdip, caddr_t csr_base, 96327Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 96427Sjchu px_err_bit_desc_t *err_bit_descr) 96527Sjchu { 96627Sjchu return (PX_FATAL_SW); 96727Sjchu } 96827Sjchu 96927Sjchu /* ARGSUSED */ 97027Sjchu int 97127Sjchu px_err_non_fatal_handle(dev_info_t *rpdip, caddr_t csr_base, 97227Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 97327Sjchu px_err_bit_desc_t *err_bit_descr) 97427Sjchu { 97527Sjchu return (PX_NONFATAL); 97627Sjchu } 97727Sjchu 97827Sjchu /* ARGSUSED */ 97927Sjchu int 98027Sjchu px_err_ok_handle(dev_info_t *rpdip, caddr_t csr_base, ddi_fm_error_t *derr, 98127Sjchu px_err_reg_desc_t *err_reg_descr, px_err_bit_desc_t *err_bit_descr) 98227Sjchu { 98327Sjchu return (PX_OK); 98427Sjchu } 98527Sjchu 98627Sjchu /* ARGSUSED */ 98727Sjchu int 98827Sjchu px_err_unknown_handle(dev_info_t *rpdip, caddr_t csr_base, ddi_fm_error_t *derr, 98927Sjchu px_err_reg_desc_t *err_reg_descr, px_err_bit_desc_t *err_bit_descr) 99027Sjchu { 99127Sjchu return (PX_ERR_UNKNOWN); 99227Sjchu } 99327Sjchu 994383Set142600 /* ARGSUSED */ 995383Set142600 PX_ERPT_SEND_DEC(do_not) 996383Set142600 { 997383Set142600 return (PX_OK); 998383Set142600 } 999383Set142600 1000383Set142600 100127Sjchu /* JBC FATAL - see io erpt doc, section 1.1 */ 100227Sjchu PX_ERPT_SEND_DEC(jbc_fatal) 100327Sjchu { 100427Sjchu char buf[FM_MAX_CLASS]; 100527Sjchu 100627Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 100727Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 100827Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 100927Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, B_TRUE, 101027Sjchu FIRE_JBC_ELE, DATA_TYPE_UINT64, 101127Sjchu CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE), 101227Sjchu FIRE_JBC_IE, DATA_TYPE_UINT64, 101327Sjchu CSR_XR(csr_base, JBC_INTERRUPT_ENABLE), 101427Sjchu FIRE_JBC_IS, DATA_TYPE_UINT64, 101527Sjchu ss_reg, 101627Sjchu FIRE_JBC_ESS, DATA_TYPE_UINT64, 101727Sjchu CSR_XR(csr_base, JBC_ERROR_STATUS_SET), 101827Sjchu FIRE_JBC_FEL1, DATA_TYPE_UINT64, 101927Sjchu CSR_XR(csr_base, FATAL_ERROR_LOG_1), 102027Sjchu FIRE_JBC_FEL2, DATA_TYPE_UINT64, 102127Sjchu CSR_XR(csr_base, FATAL_ERROR_LOG_2), 102227Sjchu NULL); 102327Sjchu 102427Sjchu return (PX_OK); 102527Sjchu } 102627Sjchu 102727Sjchu /* JBC MERGE - see io erpt doc, section 1.2 */ 102827Sjchu PX_ERPT_SEND_DEC(jbc_merge) 102927Sjchu { 103027Sjchu char buf[FM_MAX_CLASS]; 103127Sjchu 103227Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 103327Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 103427Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 103527Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, B_TRUE, 103627Sjchu FIRE_JBC_ELE, DATA_TYPE_UINT64, 103727Sjchu CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE), 103827Sjchu FIRE_JBC_IE, DATA_TYPE_UINT64, 103927Sjchu CSR_XR(csr_base, JBC_INTERRUPT_ENABLE), 104027Sjchu FIRE_JBC_IS, DATA_TYPE_UINT64, 104127Sjchu ss_reg, 104227Sjchu FIRE_JBC_ESS, DATA_TYPE_UINT64, 104327Sjchu CSR_XR(csr_base, JBC_ERROR_STATUS_SET), 104427Sjchu FIRE_JBC_MTEL, DATA_TYPE_UINT64, 104527Sjchu CSR_XR(csr_base, MERGE_TRANSACTION_ERROR_LOG), 104627Sjchu NULL); 104727Sjchu 104827Sjchu return (PX_OK); 104927Sjchu } 105027Sjchu 105127Sjchu /* 105227Sjchu * JBC Merge buffer nonfatal errors: 105327Sjchu * Merge buffer parity error (rd_buf): dma:read:M:nonfatal 105427Sjchu * Merge buffer parity error (wr_buf): dma:write:M:nonfatal 105527Sjchu */ 105627Sjchu /* ARGSUSED */ 105727Sjchu int 105827Sjchu px_err_jbc_merge_handle(dev_info_t *rpdip, caddr_t csr_base, 105927Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 106027Sjchu px_err_bit_desc_t *err_bit_descr) 106127Sjchu { 106227Sjchu uint64_t paddr; 106327Sjchu int ret; 106427Sjchu 106527Sjchu paddr = CSR_XR(csr_base, MERGE_TRANSACTION_ERROR_LOG); 106627Sjchu paddr &= MERGE_TRANSACTION_ERROR_LOG_ADDRESS_MASK; 106727Sjchu 106827Sjchu ret = px_handle_lookup( 106927Sjchu rpdip, DMA_HANDLE, derr->fme_ena, (void *)paddr); 107027Sjchu 107127Sjchu return ((ret == DDI_FM_FATAL) ? PX_FATAL_GOS : PX_NONFATAL); 107227Sjchu } 107327Sjchu 107427Sjchu /* JBC Jbusint IN - see io erpt doc, section 1.3 */ 107527Sjchu PX_ERPT_SEND_DEC(jbc_in) 107627Sjchu { 107727Sjchu char buf[FM_MAX_CLASS]; 107827Sjchu 107927Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 108027Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 108127Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 108227Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, B_TRUE, 108327Sjchu FIRE_JBC_ELE, DATA_TYPE_UINT64, 108427Sjchu CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE), 108527Sjchu FIRE_JBC_IE, DATA_TYPE_UINT64, 108627Sjchu CSR_XR(csr_base, JBC_INTERRUPT_ENABLE), 108727Sjchu FIRE_JBC_IS, DATA_TYPE_UINT64, 108827Sjchu ss_reg, 108927Sjchu FIRE_JBC_ESS, DATA_TYPE_UINT64, 109027Sjchu CSR_XR(csr_base, JBC_ERROR_STATUS_SET), 109127Sjchu FIRE_JBC_JITEL1, DATA_TYPE_UINT64, 109227Sjchu CSR_XR(csr_base, JBCINT_IN_TRANSACTION_ERROR_LOG), 109327Sjchu FIRE_JBC_JITEL2, DATA_TYPE_UINT64, 109427Sjchu CSR_XR(csr_base, JBCINT_IN_TRANSACTION_ERROR_LOG_2), 109527Sjchu NULL); 109627Sjchu 109727Sjchu return (PX_OK); 109827Sjchu } 109927Sjchu 110027Sjchu /* 110127Sjchu * JBC Jbusint IN nonfatal errors: PA logged in Jbusint In Transaction Error 110227Sjchu * Log Reg[42:0]. 110327Sjchu * CE async fault error: nonfatal 110427Sjchu * Jbus bus error: dma::nonfatal 110527Sjchu * Jbus unmapped error: pio|dma:rdwr:M:nonfatal 110627Sjchu * Write data parity error: pio/write:M:nonfatal 110727Sjchu * Read data parity error: pio/read:M:nonfatal 110827Sjchu * Illegal NCWR bytemask: pio:write:M:nonfatal 110927Sjchu * Illegal NCRD bytemask: pio:write:M:nonfatal 111027Sjchu * Invalid jbus transaction: nonfatal 111127Sjchu */ 111227Sjchu /* ARGSUSED */ 111327Sjchu int 111427Sjchu px_err_jbc_jbusint_in_handle(dev_info_t *rpdip, caddr_t csr_base, 111527Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 111627Sjchu px_err_bit_desc_t *err_bit_descr) 111727Sjchu { 111827Sjchu uint64_t paddr; 111927Sjchu int ret; 112027Sjchu 112127Sjchu paddr = CSR_XR(csr_base, JBCINT_IN_TRANSACTION_ERROR_LOG); 112227Sjchu paddr &= JBCINT_IN_TRANSACTION_ERROR_LOG_ADDRESS_MASK; 112327Sjchu 112427Sjchu ret = px_handle_lookup( 112527Sjchu rpdip, DMA_HANDLE, derr->fme_ena, (void *)paddr); 112627Sjchu 112727Sjchu return ((ret == DDI_FM_FATAL) ? PX_FATAL_GOS : PX_NONFATAL); 112827Sjchu } 112927Sjchu 113027Sjchu 113127Sjchu /* JBC Jbusint Out - see io erpt doc, section 1.4 */ 113227Sjchu PX_ERPT_SEND_DEC(jbc_out) 113327Sjchu { 113427Sjchu char buf[FM_MAX_CLASS]; 113527Sjchu 113627Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 113727Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 113827Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 113927Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, B_TRUE, 114027Sjchu FIRE_JBC_ELE, DATA_TYPE_UINT64, 114127Sjchu CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE), 114227Sjchu FIRE_JBC_IE, DATA_TYPE_UINT64, 114327Sjchu CSR_XR(csr_base, JBC_INTERRUPT_ENABLE), 114427Sjchu FIRE_JBC_IS, DATA_TYPE_UINT64, 114527Sjchu ss_reg, 114627Sjchu FIRE_JBC_ESS, DATA_TYPE_UINT64, 114727Sjchu CSR_XR(csr_base, JBC_ERROR_STATUS_SET), 114827Sjchu FIRE_JBC_JOTEL1, DATA_TYPE_UINT64, 114927Sjchu CSR_XR(csr_base, JBCINT_OUT_TRANSACTION_ERROR_LOG), 115027Sjchu FIRE_JBC_JOTEL2, DATA_TYPE_UINT64, 115127Sjchu CSR_XR(csr_base, JBCINT_OUT_TRANSACTION_ERROR_LOG_2), 115227Sjchu NULL); 115327Sjchu 115427Sjchu return (PX_OK); 115527Sjchu } 115627Sjchu 115727Sjchu /* JBC Dmcint ODCD - see io erpt doc, section 1.5 */ 115827Sjchu PX_ERPT_SEND_DEC(jbc_odcd) 115927Sjchu { 116027Sjchu char buf[FM_MAX_CLASS]; 116127Sjchu 116227Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 116327Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 116427Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 116527Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, B_TRUE, 116627Sjchu FIRE_JBC_ELE, DATA_TYPE_UINT64, 116727Sjchu CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE), 116827Sjchu FIRE_JBC_IE, DATA_TYPE_UINT64, 116927Sjchu CSR_XR(csr_base, JBC_INTERRUPT_ENABLE), 117027Sjchu FIRE_JBC_IS, DATA_TYPE_UINT64, 117127Sjchu ss_reg, 117227Sjchu FIRE_JBC_ESS, DATA_TYPE_UINT64, 117327Sjchu CSR_XR(csr_base, JBC_ERROR_STATUS_SET), 117427Sjchu FIRE_JBC_DMC_ODCD, DATA_TYPE_UINT64, 117527Sjchu CSR_XR(csr_base, DMCINT_ODCD_ERROR_LOG), 117627Sjchu NULL); 117727Sjchu 117827Sjchu return (PX_OK); 117927Sjchu } 118027Sjchu 118127Sjchu /* 118227Sjchu * JBC Dmcint ODCO nonfatal errer handling - 118327Sjchu * Unmapped PIO read error: pio:read:M:nonfatal 118427Sjchu * Unmapped PIO write error: pio:write:M:nonfatal 118527Sjchu * PIO data parity error: pio:write:M:nonfatal 118627Sjchu * Invalid PIO write to PCIe cfg/io, csr, ebus or i2c bus: pio:write:nonfatal 118727Sjchu * Invalid PIO read to PCIe cfg/io, csr, ebus or i2c bus: pio:read:nonfatal 118827Sjchu */ 118927Sjchu /* ARGSUSED */ 119027Sjchu int 119127Sjchu px_err_jbc_dmcint_odcd_handle(dev_info_t *rpdip, caddr_t csr_base, 119227Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 119327Sjchu px_err_bit_desc_t *err_bit_descr) 119427Sjchu { 119527Sjchu uint64_t paddr; 119627Sjchu int ret; 119727Sjchu 119827Sjchu paddr = CSR_XR(csr_base, DMCINT_ODCD_ERROR_LOG); 119927Sjchu paddr &= DMCINT_ODCD_ERROR_LOG_ADDRESS_MASK; 120027Sjchu 120127Sjchu ret = px_handle_lookup( 120227Sjchu rpdip, DMA_HANDLE, derr->fme_ena, (void *)paddr); 120327Sjchu 120427Sjchu return ((ret == DDI_FM_FATAL) ? PX_FATAL_GOS : PX_NONFATAL); 120527Sjchu } 120627Sjchu 120727Sjchu /* JBC Dmcint IDC - see io erpt doc, section 1.6 */ 120827Sjchu PX_ERPT_SEND_DEC(jbc_idc) 120927Sjchu { 121027Sjchu char buf[FM_MAX_CLASS]; 121127Sjchu 121227Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 121327Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 121427Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 121527Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, B_TRUE, 121627Sjchu FIRE_JBC_ELE, DATA_TYPE_UINT64, 121727Sjchu CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE), 121827Sjchu FIRE_JBC_IE, DATA_TYPE_UINT64, 121927Sjchu CSR_XR(csr_base, JBC_INTERRUPT_ENABLE), 122027Sjchu FIRE_JBC_IS, DATA_TYPE_UINT64, 122127Sjchu ss_reg, 122227Sjchu FIRE_JBC_ESS, DATA_TYPE_UINT64, 122327Sjchu CSR_XR(csr_base, JBC_ERROR_STATUS_SET), 122427Sjchu FIRE_JBC_DMC_IDC, DATA_TYPE_UINT64, 122527Sjchu CSR_XR(csr_base, DMCINT_IDC_ERROR_LOG), 122627Sjchu NULL); 122727Sjchu 122827Sjchu return (PX_OK); 122927Sjchu } 123027Sjchu 123127Sjchu /* JBC CSR - see io erpt doc, section 1.7 */ 123227Sjchu PX_ERPT_SEND_DEC(jbc_csr) 123327Sjchu { 123427Sjchu char buf[FM_MAX_CLASS]; 123527Sjchu 123627Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 123727Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 123827Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 123927Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, B_TRUE, 124027Sjchu FIRE_JBC_ELE, DATA_TYPE_UINT64, 124127Sjchu CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE), 124227Sjchu FIRE_JBC_IE, DATA_TYPE_UINT64, 124327Sjchu CSR_XR(csr_base, JBC_INTERRUPT_ENABLE), 124427Sjchu FIRE_JBC_IS, DATA_TYPE_UINT64, 124527Sjchu ss_reg, 124627Sjchu FIRE_JBC_ESS, DATA_TYPE_UINT64, 124727Sjchu CSR_XR(csr_base, JBC_ERROR_STATUS_SET), 124827Sjchu "jbc-error-reg", DATA_TYPE_UINT64, 124927Sjchu CSR_XR(csr_base, CSR_ERROR_LOG), 125027Sjchu NULL); 125127Sjchu 125227Sjchu return (PX_OK); 125327Sjchu } 125427Sjchu 125527Sjchu /* 125627Sjchu * JBC CSR errer handling - 125727Sjchu * Ebus ready timeout error: pio:rdwr:M:nonfatal 125827Sjchu */ 125927Sjchu /* ARGSUSED */ 126027Sjchu int 126127Sjchu px_err_jbc_csr_handle(dev_info_t *rpdip, caddr_t csr_base, 126227Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 126327Sjchu px_err_bit_desc_t *err_bit_descr) 126427Sjchu { 126527Sjchu uint64_t paddr; 126627Sjchu int ret; 126727Sjchu 126827Sjchu paddr = CSR_XR(csr_base, CSR_ERROR_LOG); 126927Sjchu paddr &= CSR_ERROR_LOG_ADDRESS_MASK; 127027Sjchu 127127Sjchu ret = px_handle_lookup( 127227Sjchu rpdip, DMA_HANDLE, derr->fme_ena, (void *)paddr); 127327Sjchu 127427Sjchu return ((ret == DDI_FM_FATAL) ? PX_FATAL_GOS : PX_NONFATAL); 127527Sjchu } 127627Sjchu 127727Sjchu /* JBC Dmcint IDC - see io erpt doc, section 1.6 */ 127827Sjchu 127927Sjchu /* DMC IMU RDS - see io erpt doc, section 2.1 */ 128027Sjchu PX_ERPT_SEND_DEC(imu_rds) 128127Sjchu { 128227Sjchu char buf[FM_MAX_CLASS]; 128327Sjchu 128427Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 128527Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 128627Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 128727Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, B_TRUE, 128827Sjchu FIRE_IMU_ELE, DATA_TYPE_UINT64, 128927Sjchu CSR_XR(csr_base, IMU_ERROR_LOG_ENABLE), 129027Sjchu FIRE_IMU_IE, DATA_TYPE_UINT64, 129127Sjchu CSR_XR(csr_base, IMU_INTERRUPT_ENABLE), 129227Sjchu FIRE_IMU_IS, DATA_TYPE_UINT64, 129327Sjchu ss_reg, 129427Sjchu FIRE_IMU_ESS, DATA_TYPE_UINT64, 129527Sjchu CSR_XR(csr_base, IMU_ERROR_STATUS_SET), 129627Sjchu FIRE_IMU_RDS, DATA_TYPE_UINT64, 129727Sjchu CSR_XR(csr_base, IMU_RDS_ERROR_LOG), 129827Sjchu NULL); 129927Sjchu 130027Sjchu return (PX_OK); 130127Sjchu } 130227Sjchu 130327Sjchu /* imu function to handle all Received but Not Enabled errors */ 130427Sjchu /* ARGSUSED */ 130527Sjchu int 130627Sjchu px_err_imu_rbne_handle(dev_info_t *rpdip, caddr_t csr_base, 130727Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 130827Sjchu px_err_bit_desc_t *err_bit_descr) 130927Sjchu { 131027Sjchu uint64_t imu_log_enable, imu_intr_enable; 131127Sjchu int mask = BITMASK(err_bit_descr->bit); 131227Sjchu int err = PX_NONFATAL; 131327Sjchu 131427Sjchu imu_log_enable = CSR_XR(csr_base, err_reg_descr->log_addr); 131527Sjchu imu_intr_enable = CSR_XR(csr_base, err_reg_descr->enable_addr); 131627Sjchu 1317*435Sjchu /* 1318*435Sjchu * If matching bit is not set, meaning corresponding rbne not 1319*435Sjchu * enabled, then receiving it indicates some sort of malfunction 1320*435Sjchu * possibly in hardware. 1321*435Sjchu * 1322*435Sjchu * Other wise, software may have intentionally disabled certain 1323*435Sjchu * errors for a period of time within which the occuring of the 1324*435Sjchu * disabled errors become rbne, that is non fatal. 1325*435Sjchu */ 1326*435Sjchu if (!(imu_log_enable & imu_intr_enable & mask)) 132727Sjchu err = PX_FATAL_SW; 132827Sjchu 132927Sjchu return (err); 133027Sjchu } 133127Sjchu 1332118Sjchu /* 1333118Sjchu * No platforms uses PME. Any PME received is simply logged 1334118Sjchu * for analysis. 1335118Sjchu */ 1336118Sjchu /* ARGSUSED */ 1337118Sjchu int 1338118Sjchu px_err_imu_pme_handle(dev_info_t *rpdip, caddr_t csr_base, 1339118Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 1340118Sjchu px_err_bit_desc_t *err_bit_descr) 1341118Sjchu { 1342118Sjchu px_t *px_p = DIP_TO_STATE(rpdip); 1343118Sjchu 1344118Sjchu px_p->px_pme_ignored++; 1345118Sjchu return (PX_NONFATAL); 1346118Sjchu } 1347118Sjchu 134827Sjchu /* handle EQ overflow */ 134927Sjchu /* ARGSUSED */ 135027Sjchu int 135127Sjchu px_err_imu_eq_ovfl_handle(dev_info_t *rpdip, caddr_t csr_base, 135227Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 135327Sjchu px_err_bit_desc_t *err_bit_descr) 135427Sjchu { 135527Sjchu px_t *px_p = DIP_TO_STATE(rpdip); 135627Sjchu px_msiq_state_t *msiq_state_p = &px_p->px_ib_p->ib_msiq_state; 135727Sjchu msiqid_t eqno; 135827Sjchu pci_msiq_state_t msiq_state; 135927Sjchu int err = PX_NONFATAL; 136027Sjchu int i; 136127Sjchu 136227Sjchu eqno = msiq_state_p->msiq_1st_msiq_id; 136327Sjchu for (i = 0; i < msiq_state_p->msiq_cnt; i++) { 136427Sjchu if (px_lib_msiq_getstate(rpdip, eqno, &msiq_state) == 136527Sjchu DDI_SUCCESS) { 136627Sjchu if (msiq_state == PCI_MSIQ_STATE_ERROR) { 136727Sjchu err = PX_FATAL_SW; 136827Sjchu } 136927Sjchu } 137027Sjchu } 137127Sjchu 137227Sjchu return (err); 137327Sjchu } 137427Sjchu 137527Sjchu /* DMC IMU SCS - see io erpt doc, section 2.2 */ 137627Sjchu PX_ERPT_SEND_DEC(imu_scs) 137727Sjchu { 137827Sjchu char buf[FM_MAX_CLASS]; 137927Sjchu 138027Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 138127Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 138227Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 138327Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, B_TRUE, 138427Sjchu FIRE_IMU_ELE, DATA_TYPE_UINT64, 138527Sjchu CSR_XR(csr_base, IMU_ERROR_LOG_ENABLE), 138627Sjchu FIRE_IMU_IE, DATA_TYPE_UINT64, 138727Sjchu CSR_XR(csr_base, IMU_INTERRUPT_ENABLE), 138827Sjchu FIRE_IMU_IS, DATA_TYPE_UINT64, 138927Sjchu ss_reg, 139027Sjchu FIRE_IMU_ESS, DATA_TYPE_UINT64, 139127Sjchu CSR_XR(csr_base, IMU_ERROR_STATUS_SET), 139227Sjchu FIRE_IMU_SCS, DATA_TYPE_UINT64, 139327Sjchu CSR_XR(csr_base, IMU_SCS_ERROR_LOG), 139427Sjchu NULL); 139527Sjchu 139627Sjchu return (PX_OK); 139727Sjchu } 139827Sjchu 139927Sjchu /* DMC IMU - see io erpt doc, section 2.3 */ 140027Sjchu PX_ERPT_SEND_DEC(imu) 140127Sjchu { 140227Sjchu char buf[FM_MAX_CLASS]; 140327Sjchu 140427Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 140527Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 140627Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 140727Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, B_TRUE, 140827Sjchu FIRE_IMU_ELE, DATA_TYPE_UINT64, 140927Sjchu CSR_XR(csr_base, IMU_ERROR_LOG_ENABLE), 141027Sjchu FIRE_IMU_IE, DATA_TYPE_UINT64, 141127Sjchu CSR_XR(csr_base, IMU_INTERRUPT_ENABLE), 141227Sjchu FIRE_IMU_IS, DATA_TYPE_UINT64, 141327Sjchu ss_reg, 141427Sjchu FIRE_IMU_ESS, DATA_TYPE_UINT64, 141527Sjchu CSR_XR(csr_base, IMU_ERROR_STATUS_SET), 141627Sjchu NULL); 141727Sjchu 141827Sjchu return (PX_OK); 141927Sjchu } 142027Sjchu 142127Sjchu /* DMC MMU TFAR/TFSR - see io erpt doc, section 2.4 */ 142227Sjchu PX_ERPT_SEND_DEC(mmu_tfar_tfsr) 142327Sjchu { 142427Sjchu char buf[FM_MAX_CLASS]; 142527Sjchu 142627Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 142727Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 142827Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 142927Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, B_TRUE, 143027Sjchu FIRE_MMU_ELE, DATA_TYPE_UINT64, 143127Sjchu CSR_XR(csr_base, MMU_ERROR_LOG_ENABLE), 143227Sjchu FIRE_MMU_IE, DATA_TYPE_UINT64, 143327Sjchu CSR_XR(csr_base, MMU_INTERRUPT_ENABLE), 143427Sjchu FIRE_MMU_IS, DATA_TYPE_UINT64, 143527Sjchu ss_reg, 143627Sjchu FIRE_MMU_ESS, DATA_TYPE_UINT64, 143727Sjchu CSR_XR(csr_base, MMU_ERROR_STATUS_SET), 143827Sjchu FIRE_MMU_TFAR, DATA_TYPE_UINT64, 143927Sjchu CSR_XR(csr_base, MMU_TRANSLATION_FAULT_ADDRESS), 144027Sjchu FIRE_MMU_TFSR, DATA_TYPE_UINT64, 144127Sjchu CSR_XR(csr_base, MMU_TRANSLATION_FAULT_STATUS), 144227Sjchu NULL); 144327Sjchu 144427Sjchu return (PX_OK); 144527Sjchu } 144627Sjchu 144727Sjchu /* DMC MMU - see io erpt doc, section 2.5 */ 144827Sjchu PX_ERPT_SEND_DEC(mmu) 144927Sjchu { 145027Sjchu char buf[FM_MAX_CLASS]; 145127Sjchu 145227Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 145327Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 145427Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 145527Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, B_TRUE, 145627Sjchu FIRE_MMU_ELE, DATA_TYPE_UINT64, 145727Sjchu CSR_XR(csr_base, MMU_ERROR_LOG_ENABLE), 145827Sjchu FIRE_MMU_IE, DATA_TYPE_UINT64, 145927Sjchu CSR_XR(csr_base, MMU_INTERRUPT_ENABLE), 146027Sjchu FIRE_MMU_IS, DATA_TYPE_UINT64, 146127Sjchu ss_reg, 146227Sjchu FIRE_MMU_ESS, DATA_TYPE_UINT64, 146327Sjchu CSR_XR(csr_base, MMU_ERROR_STATUS_SET), 146427Sjchu NULL); 146527Sjchu 146627Sjchu return (PX_OK); 146727Sjchu } 146827Sjchu 146927Sjchu /* imu function to handle all Received but Not Enabled errors */ 147027Sjchu int 147127Sjchu px_err_mmu_rbne_handle(dev_info_t *rpdip, caddr_t csr_base, 147227Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 147327Sjchu px_err_bit_desc_t *err_bit_descr) 147427Sjchu { 1475260Set142600 uint64_t mmu_log_enable, mmu_intr_enable; 147627Sjchu uint64_t mask = BITMASK(err_bit_descr->bit); 1477260Set142600 uint64_t mmu_tfa, mmu_ctrl; 1478260Set142600 uint64_t mmu_enable_bit = 0; 147927Sjchu int err = PX_NONFATAL; 148027Sjchu int ret; 148127Sjchu 148227Sjchu mmu_log_enable = CSR_XR(csr_base, err_reg_descr->log_addr); 148327Sjchu mmu_intr_enable = CSR_XR(csr_base, err_reg_descr->enable_addr); 148427Sjchu 148527Sjchu mmu_tfa = CSR_XR(csr_base, MMU_TRANSLATION_FAULT_ADDRESS); 1486260Set142600 mmu_ctrl = CSR_XR(csr_base, MMU_CONTROL_AND_STATUS); 148727Sjchu 1488260Set142600 switch (err_bit_descr->bit) { 1489260Set142600 case MMU_INTERRUPT_STATUS_BYP_ERR_P: 1490260Set142600 mmu_enable_bit = BITMASK(MMU_CONTROL_AND_STATUS_BE); 1491260Set142600 break; 1492260Set142600 case MMU_INTERRUPT_STATUS_TRN_ERR_P: 1493260Set142600 mmu_enable_bit = BITMASK(MMU_CONTROL_AND_STATUS_TE); 1494260Set142600 break; 1495260Set142600 default: 1496260Set142600 mmu_enable_bit = 0; 1497260Set142600 break; 1498260Set142600 } 1499260Set142600 1500260Set142600 /* 1501260Set142600 * If the interrupts are enabled and Translation/Bypass Enable bit 1502260Set142600 * was set, then panic. This error should not have occured. 1503260Set142600 */ 1504260Set142600 if (mmu_log_enable & mmu_intr_enable & 1505260Set142600 (mmu_ctrl & mmu_enable_bit)) { 150627Sjchu err = PX_FATAL_SW; 150727Sjchu } else { 150827Sjchu ret = px_handle_lookup( 150927Sjchu rpdip, DMA_HANDLE, derr->fme_ena, (void *)mmu_tfa); 151027Sjchu err = (ret == DDI_FM_FATAL) ? PX_FATAL_GOS : PX_NONFATAL; 151127Sjchu 151227Sjchu /* 151327Sjchu * S/W bug - this error should always be enabled 151427Sjchu */ 151527Sjchu 151627Sjchu /* enable error & intr reporting for this bit */ 151727Sjchu CSR_XS(csr_base, MMU_ERROR_LOG_ENABLE, mmu_log_enable | mask); 151827Sjchu CSR_XS(csr_base, MMU_INTERRUPT_ENABLE, mmu_intr_enable | mask); 1519260Set142600 1520260Set142600 /* enable translation access/bypass enable */ 1521260Set142600 CSR_XS(csr_base, MMU_CONTROL_AND_STATUS, 1522260Set142600 mmu_ctrl | mmu_enable_bit); 152327Sjchu } 152427Sjchu 152527Sjchu return (err); 152627Sjchu } 152727Sjchu 152827Sjchu /* Generic error handling functions that involve MMU Translation Fault Addr */ 152927Sjchu /* ARGSUSED */ 153027Sjchu int 153127Sjchu px_err_mmu_tfa_handle(dev_info_t *rpdip, caddr_t csr_base, 153227Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 153327Sjchu px_err_bit_desc_t *err_bit_descr) 153427Sjchu { 153527Sjchu uint64_t mmu_tfa; 153627Sjchu uint_t ret; 153727Sjchu 153827Sjchu mmu_tfa = CSR_XR(csr_base, MMU_TRANSLATION_FAULT_ADDRESS); 153927Sjchu ret = px_handle_lookup( 154027Sjchu rpdip, DMA_HANDLE, derr->fme_ena, (void *)mmu_tfa); 154127Sjchu 154227Sjchu return ((ret == DDI_FM_FATAL) ? PX_FATAL_GOS : PX_NONFATAL); 154327Sjchu } 154427Sjchu 154527Sjchu /* MMU Table walk errors */ 154627Sjchu /* ARGSUSED */ 154727Sjchu int 154827Sjchu px_err_mmu_tblwlk_handle(dev_info_t *rpdip, caddr_t csr_base, 154927Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 155027Sjchu px_err_bit_desc_t *err_bit_descr) 155127Sjchu { 155227Sjchu uint64_t mmu_tfa; 155327Sjchu uint_t ret; 155427Sjchu 155527Sjchu mmu_tfa = CSR_XR(csr_base, MMU_TRANSLATION_FAULT_ADDRESS); 155627Sjchu ret = px_handle_lookup( 155727Sjchu rpdip, DMA_HANDLE, derr->fme_ena, (void *)mmu_tfa); 155827Sjchu 155927Sjchu return ((ret == DDI_FM_FATAL) ? PX_FATAL_GOS : PX_NONFATAL); 156027Sjchu } 156127Sjchu 1562118Sjchu /* 1563118Sjchu * TLU LUP event - power management code is interested in this event. 1564118Sjchu */ 1565118Sjchu /* ARGSUSED */ 1566118Sjchu int 1567118Sjchu px_err_tlu_lup_handle(dev_info_t *rpdip, caddr_t csr_base, 1568118Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 1569118Sjchu px_err_bit_desc_t *err_bit_descr) 1570118Sjchu { 1571118Sjchu px_t *px_p = DIP_TO_STATE(rpdip); 1572118Sjchu 1573118Sjchu /* 1574118Sjchu * Existense of pm info indicates the power management 1575118Sjchu * is interested in this event. 1576118Sjchu */ 1577118Sjchu if (!PCIE_PMINFO(rpdip) || !PCIE_NEXUS_PMINFO(rpdip)) 1578118Sjchu return (PX_OK); 1579118Sjchu 1580118Sjchu mutex_enter(&px_p->px_lup_lock); 1581118Sjchu px_p->px_lupsoft_pending++; 1582118Sjchu mutex_exit(&px_p->px_lup_lock); 1583118Sjchu 1584118Sjchu /* 1585118Sjchu * Post a soft interrupt to wake up threads waiting for this. 1586118Sjchu */ 1587118Sjchu ddi_trigger_softintr(px_p->px_lupsoft_id); 1588118Sjchu 1589118Sjchu return (PX_OK); 1590118Sjchu } 1591118Sjchu 159227Sjchu /* PEC ILU none - see io erpt doc, section 3.1 */ 159327Sjchu PX_ERPT_SEND_DEC(pec_ilu) 159427Sjchu { 159527Sjchu char buf[FM_MAX_CLASS]; 159627Sjchu 159727Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 159827Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 159927Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 160027Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, B_TRUE, 160127Sjchu FIRE_ILU_ELE, DATA_TYPE_UINT64, 160227Sjchu CSR_XR(csr_base, ILU_ERROR_LOG_ENABLE), 160327Sjchu FIRE_ILU_IE, DATA_TYPE_UINT64, 160427Sjchu CSR_XR(csr_base, ILU_INTERRUPT_ENABLE), 160527Sjchu FIRE_ILU_IS, DATA_TYPE_UINT64, 160627Sjchu ss_reg, 160727Sjchu FIRE_ILU_ESS, DATA_TYPE_UINT64, 160827Sjchu CSR_XR(csr_base, ILU_ERROR_STATUS_SET), 160927Sjchu NULL); 161027Sjchu 161127Sjchu return (PX_OK); 161227Sjchu } 161327Sjchu 1614383Set142600 /* PCIEX UE Errors */ 1615383Set142600 /* ARGSUSED */ 1616383Set142600 px_err_pciex_ue_handle(dev_info_t *rpdip, caddr_t csr_base, 1617383Set142600 ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 1618383Set142600 px_err_bit_desc_t *err_bit_descr) 1619383Set142600 { 1620383Set142600 uint32_t mask = (uint32_t)BITMASK(err_bit_descr->bit); 1621383Set142600 1622383Set142600 return ((err_bit_descr->bit >= 32 && px_fabric_die_rc_ue_gos) ? 1623383Set142600 PX_FATAL_GOS : PX_FABRIC_ERR_SEV(mask, px_fabric_die_rc_ue, 1624383Set142600 px_fabric_die_rc_ue_gos)); 1625383Set142600 } 1626383Set142600 1627383Set142600 /* PCI-E Uncorrectable Errors - see io erpt doc, section 3.2 */ 1628383Set142600 PX_ERPT_SEND_DEC(pciex_rx_ue) 1629383Set142600 { 1630383Set142600 char buf[FM_MAX_CLASS]; 1631383Set142600 1632383Set142600 (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 1633383Set142600 ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 1634383Set142600 DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 1635383Set142600 FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, B_TRUE, 1636383Set142600 FIRE_TLU_UELE, DATA_TYPE_UINT64, 1637383Set142600 CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_LOG_ENABLE), 1638383Set142600 FIRE_TLU_UIE, DATA_TYPE_UINT64, 1639383Set142600 CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_INTERRUPT_ENABLE), 1640383Set142600 FIRE_TLU_UIS, DATA_TYPE_UINT64, 1641383Set142600 ss_reg, 1642383Set142600 FIRE_TLU_UESS, DATA_TYPE_UINT64, 1643383Set142600 CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_STATUS_SET), 1644383Set142600 FIRE_TLU_RUEH1L, DATA_TYPE_UINT64, 1645383Set142600 CSR_XR(csr_base, TLU_RECEIVE_UNCORRECTABLE_ERROR_HEADER1_LOG), 1646383Set142600 FIRE_TLU_RUEH2L, DATA_TYPE_UINT64, 1647383Set142600 CSR_XR(csr_base, TLU_RECEIVE_UNCORRECTABLE_ERROR_HEADER2_LOG), 1648383Set142600 NULL); 1649383Set142600 1650383Set142600 return (PX_OK); 1651383Set142600 } 1652383Set142600 1653383Set142600 /* PCI-E Uncorrectable Errors - see io erpt doc, section 3.3 */ 1654383Set142600 PX_ERPT_SEND_DEC(pciex_tx_ue) 1655383Set142600 { 1656383Set142600 char buf[FM_MAX_CLASS]; 1657383Set142600 1658383Set142600 (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 1659383Set142600 ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 1660383Set142600 DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 1661383Set142600 FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, B_TRUE, 1662383Set142600 FIRE_TLU_UELE, DATA_TYPE_UINT64, 1663383Set142600 CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_LOG_ENABLE), 1664383Set142600 FIRE_TLU_UIE, DATA_TYPE_UINT64, 1665383Set142600 CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_INTERRUPT_ENABLE), 1666383Set142600 FIRE_TLU_UIS, DATA_TYPE_UINT64, 1667383Set142600 ss_reg, 1668383Set142600 FIRE_TLU_UESS, DATA_TYPE_UINT64, 1669383Set142600 CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_STATUS_SET), 1670383Set142600 FIRE_TLU_TUEH1L, DATA_TYPE_UINT64, 1671383Set142600 CSR_XR(csr_base, TLU_TRANSMIT_UNCORRECTABLE_ERROR_HEADER1_LOG), 1672383Set142600 FIRE_TLU_TUEH2L, DATA_TYPE_UINT64, 1673383Set142600 CSR_XR(csr_base, TLU_TRANSMIT_UNCORRECTABLE_ERROR_HEADER2_LOG), 1674383Set142600 NULL); 1675383Set142600 1676383Set142600 return (PX_OK); 1677383Set142600 } 1678383Set142600 1679383Set142600 /* PCI-E Uncorrectable Errors - see io erpt doc, section 3.4 */ 1680383Set142600 PX_ERPT_SEND_DEC(pciex_rx_tx_ue) 1681383Set142600 { 1682383Set142600 char buf[FM_MAX_CLASS]; 1683383Set142600 1684383Set142600 (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 1685383Set142600 ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 1686383Set142600 DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 1687383Set142600 FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, B_TRUE, 1688383Set142600 FIRE_TLU_UELE, DATA_TYPE_UINT64, 1689383Set142600 CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_LOG_ENABLE), 1690383Set142600 FIRE_TLU_UIE, DATA_TYPE_UINT64, 1691383Set142600 CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_INTERRUPT_ENABLE), 1692383Set142600 FIRE_TLU_UIS, DATA_TYPE_UINT64, 1693383Set142600 ss_reg, 1694383Set142600 FIRE_TLU_UESS, DATA_TYPE_UINT64, 1695383Set142600 CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_STATUS_SET), 1696383Set142600 FIRE_TLU_RUEH1L, DATA_TYPE_UINT64, 1697383Set142600 CSR_XR(csr_base, TLU_RECEIVE_UNCORRECTABLE_ERROR_HEADER1_LOG), 1698383Set142600 FIRE_TLU_RUEH2L, DATA_TYPE_UINT64, 1699383Set142600 CSR_XR(csr_base, TLU_RECEIVE_UNCORRECTABLE_ERROR_HEADER2_LOG), 1700383Set142600 FIRE_TLU_TUEH1L, DATA_TYPE_UINT64, 1701383Set142600 CSR_XR(csr_base, TLU_TRANSMIT_UNCORRECTABLE_ERROR_HEADER1_LOG), 1702383Set142600 FIRE_TLU_TUEH2L, DATA_TYPE_UINT64, 1703383Set142600 CSR_XR(csr_base, TLU_TRANSMIT_UNCORRECTABLE_ERROR_HEADER2_LOG), 1704383Set142600 NULL); 1705383Set142600 1706383Set142600 return (PX_OK); 1707383Set142600 } 1708383Set142600 1709383Set142600 /* PCI-E Uncorrectable Errors - see io erpt doc, section 3.5 */ 1710383Set142600 PX_ERPT_SEND_DEC(pciex_ue) 1711383Set142600 { 1712383Set142600 char buf[FM_MAX_CLASS]; 1713383Set142600 1714383Set142600 (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 1715383Set142600 ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 1716383Set142600 DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 1717383Set142600 FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, B_TRUE, 1718383Set142600 FIRE_TLU_UELE, DATA_TYPE_UINT64, 1719383Set142600 CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_LOG_ENABLE), 1720383Set142600 FIRE_TLU_UIE, DATA_TYPE_UINT64, 1721383Set142600 CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_INTERRUPT_ENABLE), 1722383Set142600 FIRE_TLU_UIS, DATA_TYPE_UINT64, 1723383Set142600 ss_reg, 1724383Set142600 FIRE_TLU_UESS, DATA_TYPE_UINT64, 1725383Set142600 CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_STATUS_SET), 1726383Set142600 NULL); 1727383Set142600 1728383Set142600 return (PX_OK); 1729383Set142600 } 1730383Set142600 1731383Set142600 /* PCIEX UE Errors */ 1732383Set142600 /* ARGSUSED */ 1733383Set142600 px_err_pciex_ce_handle(dev_info_t *rpdip, caddr_t csr_base, 1734383Set142600 ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr, 1735383Set142600 px_err_bit_desc_t *err_bit_descr) 1736383Set142600 { 1737383Set142600 uint32_t mask = (uint32_t)BITMASK(err_bit_descr->bit); 1738383Set142600 1739383Set142600 return ((err_bit_descr->bit >= 32 && px_fabric_die_rc_ce_gos) ? 1740383Set142600 PX_FATAL_GOS : PX_FABRIC_ERR_SEV(mask, px_fabric_die_rc_ce, 1741383Set142600 px_fabric_die_rc_ce_gos)); 1742383Set142600 } 1743383Set142600 174427Sjchu /* PCI-E Correctable Errors - see io erpt doc, section 3.6 */ 174527Sjchu PX_ERPT_SEND_DEC(pciex_ce) 174627Sjchu { 174727Sjchu char buf[FM_MAX_CLASS]; 174827Sjchu 174927Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 175027Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 175127Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 175227Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, B_TRUE, 175327Sjchu FIRE_TLU_CELE, DATA_TYPE_UINT64, 175427Sjchu CSR_XR(csr_base, TLU_CORRECTABLE_ERROR_LOG_ENABLE), 175527Sjchu FIRE_TLU_CIE, DATA_TYPE_UINT64, 175627Sjchu CSR_XR(csr_base, TLU_CORRECTABLE_ERROR_INTERRUPT_ENABLE), 175727Sjchu FIRE_TLU_CIS, DATA_TYPE_UINT64, 175827Sjchu ss_reg, 175927Sjchu FIRE_TLU_CESS, DATA_TYPE_UINT64, 176027Sjchu CSR_XR(csr_base, TLU_CORRECTABLE_ERROR_STATUS_SET), 176127Sjchu NULL); 176227Sjchu 176327Sjchu return (PX_OK); 176427Sjchu } 176527Sjchu 176627Sjchu /* TLU Other Event Status (receive only) - see io erpt doc, section 3.7 */ 176727Sjchu PX_ERPT_SEND_DEC(pciex_rx_oe) 176827Sjchu { 176927Sjchu char buf[FM_MAX_CLASS]; 177027Sjchu 177127Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 177227Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 177327Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 177427Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, B_TRUE, 177527Sjchu FIRE_TLU_OEELE, DATA_TYPE_UINT64, 177627Sjchu CSR_XR(csr_base, TLU_OTHER_EVENT_LOG_ENABLE), 177727Sjchu FIRE_TLU_OEIE, DATA_TYPE_UINT64, 177827Sjchu CSR_XR(csr_base, TLU_OTHER_EVENT_INTERRUPT_ENABLE), 177927Sjchu FIRE_TLU_OEIS, DATA_TYPE_UINT64, 178027Sjchu ss_reg, 178127Sjchu FIRE_TLU_OEESS, DATA_TYPE_UINT64, 178227Sjchu CSR_XR(csr_base, TLU_OTHER_EVENT_STATUS_SET), 178327Sjchu FIRE_TLU_RUEH1L, DATA_TYPE_UINT64, 178427Sjchu CSR_XR(csr_base, TLU_RECEIVE_OTHER_EVENT_HEADER1_LOG), 1785260Set142600 FIRE_TLU_RUEH2L, DATA_TYPE_UINT64, 178627Sjchu CSR_XR(csr_base, TLU_RECEIVE_OTHER_EVENT_HEADER2_LOG), 178727Sjchu NULL); 178827Sjchu 178927Sjchu return (PX_OK); 179027Sjchu } 179127Sjchu 179227Sjchu /* TLU Other Event Status (rx + tx) - see io erpt doc, section 3.8 */ 179327Sjchu PX_ERPT_SEND_DEC(pciex_rx_tx_oe) 179427Sjchu { 179527Sjchu char buf[FM_MAX_CLASS]; 179627Sjchu 179727Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 179827Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 179927Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 180027Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, B_TRUE, 180127Sjchu FIRE_TLU_OEELE, DATA_TYPE_UINT64, 180227Sjchu CSR_XR(csr_base, TLU_OTHER_EVENT_LOG_ENABLE), 180327Sjchu FIRE_TLU_OEIE, DATA_TYPE_UINT64, 180427Sjchu CSR_XR(csr_base, TLU_OTHER_EVENT_INTERRUPT_ENABLE), 180527Sjchu FIRE_TLU_OEIS, DATA_TYPE_UINT64, 180627Sjchu ss_reg, 180727Sjchu FIRE_TLU_OEESS, DATA_TYPE_UINT64, 180827Sjchu CSR_XR(csr_base, TLU_OTHER_EVENT_STATUS_SET), 180927Sjchu FIRE_TLU_ROEEH1L, DATA_TYPE_UINT64, 181027Sjchu CSR_XR(csr_base, TLU_RECEIVE_OTHER_EVENT_HEADER1_LOG), 181127Sjchu FIRE_TLU_ROEEH2L, DATA_TYPE_UINT64, 181227Sjchu CSR_XR(csr_base, TLU_RECEIVE_OTHER_EVENT_HEADER2_LOG), 181327Sjchu FIRE_TLU_TOEEH1L, DATA_TYPE_UINT64, 181427Sjchu CSR_XR(csr_base, TLU_TRANSMIT_OTHER_EVENT_HEADER1_LOG), 1815260Set142600 FIRE_TLU_TOEEH2L, DATA_TYPE_UINT64, 181627Sjchu CSR_XR(csr_base, TLU_TRANSMIT_OTHER_EVENT_HEADER2_LOG), 181727Sjchu NULL); 181827Sjchu 181927Sjchu return (PX_OK); 182027Sjchu } 182127Sjchu 182227Sjchu /* TLU Other Event - see io erpt doc, section 3.9 */ 182327Sjchu PX_ERPT_SEND_DEC(pciex_oe) 182427Sjchu { 1825287Smg140465 char buf[FM_MAX_CLASS]; 182627Sjchu 182727Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name); 182827Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena, 182927Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, 183027Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, B_TRUE, 183127Sjchu FIRE_TLU_OEELE, DATA_TYPE_UINT64, 183227Sjchu CSR_XR(csr_base, TLU_OTHER_EVENT_LOG_ENABLE), 183327Sjchu FIRE_TLU_OEIE, DATA_TYPE_UINT64, 183427Sjchu CSR_XR(csr_base, TLU_OTHER_EVENT_INTERRUPT_ENABLE), 183527Sjchu FIRE_TLU_OEIS, DATA_TYPE_UINT64, 183627Sjchu ss_reg, 183727Sjchu FIRE_TLU_OEESS, DATA_TYPE_UINT64, 183827Sjchu CSR_XR(csr_base, TLU_OTHER_EVENT_STATUS_SET), 183927Sjchu NULL); 184027Sjchu 184127Sjchu return (PX_OK); 184227Sjchu } 1843287Smg140465 1844287Smg140465 /* TLU Other Event - Link Down see io erpt doc, section 3.9 */ 1845287Smg140465 PX_ERPT_SEND_DEC(pciex_ldn) 1846287Smg140465 { 1847287Smg140465 px_t *px_p = DIP_TO_STATE(rpdip); 1848287Smg140465 1849287Smg140465 /* 1850287Smg140465 * Don't post ereport, if ldn event is due to 1851287Smg140465 * power management. 1852287Smg140465 */ 1853287Smg140465 if (px_p->px_pm_flags & PX_LDN_EXPECTED) { 1854287Smg140465 px_p->px_pm_flags &= ~PX_LDN_EXPECTED; 1855287Smg140465 return (PX_OK); 1856287Smg140465 } 1857287Smg140465 return (PX_ERPT_SEND(pciex_oe)(rpdip, csr_base, ss_reg, derr, 1858287Smg140465 class_name)); 1859287Smg140465 1860287Smg140465 } 1861287Smg140465 1862287Smg140465 /* TLU Other Event - Link Up see io erpt doc, section 3.9 */ 1863287Smg140465 PX_ERPT_SEND_DEC(pciex_lup) 1864287Smg140465 { 1865287Smg140465 px_t *px_p = DIP_TO_STATE(rpdip); 1866287Smg140465 1867287Smg140465 /* 1868287Smg140465 * Don't post ereport, if lup event is due to 1869287Smg140465 * power management. 1870287Smg140465 */ 1871287Smg140465 if (px_p->px_pm_flags & PX_LUP_EXPECTED) { 1872287Smg140465 px_p->px_pm_flags &= ~PX_LUP_EXPECTED; 1873287Smg140465 return (PX_OK); 1874287Smg140465 } 1875287Smg140465 1876287Smg140465 return (PX_ERPT_SEND(pciex_oe)(rpdip, csr_base, ss_reg, derr, 1877287Smg140465 class_name)); 1878287Smg140465 } 1879