#include <sys/types.h>
#include <sys/ddi.h>
#include <sys/sunddi.h>
#include <sys/sunndi.h>
#include <sys/fm/protocol.h>
#include <sys/fm/util.h>
#include <sys/pcie.h>
#include <sys/pcie_impl.h>
#include "px_obj.h"
#include <px_regs.h>
#include <px_csr.h>
#include <sys/membar.h>
#include <sys/machcpuvar.h>
#include <sys/platform_module.h>
#include "px_lib4u.h"
#include "px_err.h"
#include "px_err_impl.h"
#include "oberon_regs.h"
uint64_t px_tlu_ue_intr_mask = PX_ERR_EN_ALL;
uint64_t px_tlu_ue_log_mask = PX_ERR_EN_ALL;
uint64_t px_tlu_ue_count_mask = PX_ERR_EN_ALL;
uint64_t px_tlu_ce_intr_mask = PX_ERR_MASK_NONE;
uint64_t px_tlu_ce_log_mask = PX_ERR_MASK_NONE;
uint64_t px_tlu_ce_count_mask = PX_ERR_MASK_NONE;
uint64_t px_tlu_oe_intr_mask = PX_ERR_EN_ALL & ~0x80000000800;
uint64_t px_tlu_oe_log_mask = PX_ERR_EN_ALL & ~0x80000000800;
uint64_t px_tlu_oe_count_mask = PX_ERR_EN_ALL;
uint64_t px_mmu_intr_mask = PX_ERR_EN_ALL;
uint64_t px_mmu_log_mask = PX_ERR_EN_ALL;
uint64_t px_mmu_count_mask = PX_ERR_EN_ALL;
uint64_t px_imu_intr_mask = PX_ERR_EN_ALL;
uint64_t px_imu_log_mask = PX_ERR_EN_ALL;
uint64_t px_imu_count_mask = PX_ERR_EN_ALL;
uint64_t px_ilu_intr_mask = (((uint64_t)0x10 << 32) | 0x10);
uint64_t px_ilu_log_mask = (((uint64_t)0x10 << 32) | 0x10);
uint64_t px_ilu_count_mask = PX_ERR_EN_ALL;
uint64_t px_ubc_intr_mask = PX_ERR_EN_ALL;
uint64_t px_ubc_log_mask = PX_ERR_EN_ALL;
uint64_t px_ubc_count_mask = PX_ERR_EN_ALL;
uint64_t px_jbc_intr_mask = PX_ERR_EN_ALL;
uint64_t px_jbc_log_mask = PX_ERR_EN_ALL;
uint64_t px_jbc_count_mask = PX_ERR_EN_ALL;
uint64_t px_lpul_intr_mask = LPU_INTR_DISABLE;
uint64_t px_lpul_log_mask = PX_ERR_EN_ALL;
uint64_t px_lpul_count_mask = PX_ERR_EN_ALL;
uint64_t px_lpup_intr_mask = LPU_INTR_DISABLE;
uint64_t px_lpup_log_mask = PX_ERR_EN_ALL;
uint64_t px_lpup_count_mask = PX_ERR_EN_ALL;
uint64_t px_lpur_intr_mask = LPU_INTR_DISABLE;
uint64_t px_lpur_log_mask = PX_ERR_EN_ALL;
uint64_t px_lpur_count_mask = PX_ERR_EN_ALL;
uint64_t px_lpux_intr_mask = LPU_INTR_DISABLE;
uint64_t px_lpux_log_mask = PX_ERR_EN_ALL;
uint64_t px_lpux_count_mask = PX_ERR_EN_ALL;
uint64_t px_lpus_intr_mask = LPU_INTR_DISABLE;
uint64_t px_lpus_log_mask = PX_ERR_EN_ALL;
uint64_t px_lpus_count_mask = PX_ERR_EN_ALL;
uint64_t px_lpug_intr_mask = LPU_INTR_DISABLE;
uint64_t px_lpug_log_mask = PX_ERR_EN_ALL;
uint64_t px_lpug_count_mask = PX_ERR_EN_ALL;
#define JBC_BIT_DESC(bit, hdl, erpt) \
JBC_INTERRUPT_STATUS_ ## bit ## _P, \
0, \
PX_ERR_BIT_HANDLE(hdl), \
PX_ERPT_SEND(erpt), \
PX_ERR_JBC_CLASS(bit) }, \
{ JBC_INTERRUPT_STATUS_ ## bit ## _S, \
0, \
PX_ERR_BIT_HANDLE(hdl), \
PX_ERPT_SEND(erpt), \
PX_ERR_JBC_CLASS(bit)
px_err_bit_desc_t px_err_jbc_tbl[] = {
{ JBC_BIT_DESC(MB_PEA, hw_reset, jbc_fatal) },
{ JBC_BIT_DESC(CPE, hw_reset, jbc_fatal) },
{ JBC_BIT_DESC(APE, hw_reset, jbc_fatal) },
{ JBC_BIT_DESC(PIO_CPE, hw_reset, jbc_fatal) },
{ JBC_BIT_DESC(JTCEEW, hw_reset, jbc_fatal) },
{ JBC_BIT_DESC(JTCEEI, hw_reset, jbc_fatal) },
{ JBC_BIT_DESC(JTCEER, hw_reset, jbc_fatal) },
{ JBC_BIT_DESC(MB_PER, jbc_merge, jbc_merge) },
{ JBC_BIT_DESC(MB_PEW, jbc_merge, jbc_merge) },
{ JBC_BIT_DESC(UE_ASYN, panic, jbc_in) },
{ JBC_BIT_DESC(CE_ASYN, no_error, jbc_in) },
{ JBC_BIT_DESC(JTE, panic, jbc_in) },
{ JBC_BIT_DESC(JBE, panic, jbc_in) },
{ JBC_BIT_DESC(JUE, panic, jbc_in) },
{ JBC_BIT_DESC(ICISE, panic, jbc_in) },
{ JBC_BIT_DESC(WR_DPE, jbc_jbusint_in, jbc_in) },
{ JBC_BIT_DESC(RD_DPE, jbc_jbusint_in, jbc_in) },
{ JBC_BIT_DESC(ILL_BMW, panic, jbc_in) },
{ JBC_BIT_DESC(ILL_BMR, panic, jbc_in) },
{ JBC_BIT_DESC(BJC, panic, jbc_in) },
{ JBC_BIT_DESC(IJP, panic, jbc_out) },
{ JBC_BIT_DESC(PIO_UNMAP_RD, jbc_safe_acc, jbc_odcd) },
{ JBC_BIT_DESC(ILL_ACC_RD, jbc_safe_acc, jbc_odcd) },
{ JBC_BIT_DESC(PIO_UNMAP, jbc_safe_acc, jbc_odcd) },
{ JBC_BIT_DESC(PIO_DPE, jbc_dmcint_odcd, jbc_odcd) },
{ JBC_BIT_DESC(PIO_CPE, hw_reset, jbc_odcd) },
{ JBC_BIT_DESC(ILL_ACC, jbc_safe_acc, jbc_odcd) },
{ JBC_BIT_DESC(UNSOL_RD, no_panic, jbc_idc) },
{ JBC_BIT_DESC(UNSOL_INTR, no_panic, jbc_idc) },
{ JBC_BIT_DESC(EBUS_TO, panic, jbc_csr) }
};
#define px_err_jbc_keys \
(sizeof (px_err_jbc_tbl)) / (sizeof (px_err_bit_desc_t))
#define UBC_BIT_DESC(bit, hdl, erpt) \
UBC_INTERRUPT_STATUS_ ## bit ## _P, \
0, \
PX_ERR_BIT_HANDLE(hdl), \
PX_ERPT_SEND(erpt), \
PX_ERR_UBC_CLASS(bit) }, \
{ UBC_INTERRUPT_STATUS_ ## bit ## _S, \
0, \
PX_ERR_BIT_HANDLE(hdl), \
PX_ERPT_SEND(erpt), \
PX_ERR_UBC_CLASS(bit)
px_err_bit_desc_t px_err_ubc_tbl[] = {
{ UBC_BIT_DESC(DMARDUEA, no_panic, ubc_fatal) },
{ UBC_BIT_DESC(DMAWTUEA, panic, ubc_fatal) },
{ UBC_BIT_DESC(MEMRDAXA, panic, ubc_fatal) },
{ UBC_BIT_DESC(MEMWTAXA, panic, ubc_fatal) },
{ UBC_BIT_DESC(DMARDUEB, no_panic, ubc_fatal) },
{ UBC_BIT_DESC(DMAWTUEB, panic, ubc_fatal) },
{ UBC_BIT_DESC(MEMRDAXB, panic, ubc_fatal) },
{ UBC_BIT_DESC(MEMWTAXB, panic, ubc_fatal) },
{ UBC_BIT_DESC(PIOWTUE, panic, ubc_fatal) },
{ UBC_BIT_DESC(PIOWBEUE, panic, ubc_fatal) },
{ UBC_BIT_DESC(PIORBEUE, panic, ubc_fatal) }
};
#define px_err_ubc_keys \
(sizeof (px_err_ubc_tbl)) / (sizeof (px_err_bit_desc_t))
char *ubc_class_eid_qualifier[] = {
"-mem",
"-channel",
"-cpu",
"-path"
};
#define IMU_BIT_DESC(bit, hdl, erpt) \
IMU_INTERRUPT_STATUS_ ## bit ## _P, \
0, \
PX_ERR_BIT_HANDLE(hdl), \
PX_ERPT_SEND(erpt), \
PX_ERR_DMC_CLASS(bit) }, \
{ IMU_INTERRUPT_STATUS_ ## bit ## _S, \
0, \
PX_ERR_BIT_HANDLE(hdl), \
PX_ERPT_SEND(erpt), \
PX_ERR_DMC_CLASS(bit)
px_err_bit_desc_t px_err_imu_tbl[] = {
{ IMU_BIT_DESC(MSI_MAL_ERR, panic, imu_rds) },
{ IMU_BIT_DESC(MSI_PAR_ERR, panic, imu_rds) },
{ IMU_BIT_DESC(PMEACK_MES_NOT_EN, panic, imu_rds) },
{ IMU_BIT_DESC(PMPME_MES_NOT_EN, panic, imu_rds) },
{ IMU_BIT_DESC(FATAL_MES_NOT_EN, panic, imu_rds) },
{ IMU_BIT_DESC(NONFATAL_MES_NOT_EN, panic, imu_rds) },
{ IMU_BIT_DESC(COR_MES_NOT_EN, panic, imu_rds) },
{ IMU_BIT_DESC(MSI_NOT_EN, panic, imu_rds) },
{ IMU_BIT_DESC(EQ_NOT_EN, panic, imu_scs) },
{ IMU_BIT_DESC(EQ_OVER, imu_eq_ovfl, imu) }
};
#define px_err_imu_keys (sizeof (px_err_imu_tbl)) / (sizeof (px_err_bit_desc_t))
#define MMU_BIT_DESC(bit, hdl, erpt) \
MMU_INTERRUPT_STATUS_ ## bit ## _P, \
0, \
PX_ERR_BIT_HANDLE(hdl), \
PX_ERPT_SEND(erpt), \
PX_ERR_DMC_CLASS(bit) }, \
{ MMU_INTERRUPT_STATUS_ ## bit ## _S, \
0, \
PX_ERR_BIT_HANDLE(hdl), \
PX_ERPT_SEND(erpt), \
PX_ERR_DMC_CLASS(bit)
px_err_bit_desc_t px_err_mmu_tbl[] = {
{ MMU_BIT_DESC(BYP_ERR, mmu_rbne, mmu_tfar_tfsr) },
{ MMU_BIT_DESC(BYP_OOR, mmu_tfa, mmu_tfar_tfsr) },
{ MMU_BIT_DESC(TRN_ERR, panic, mmu_tfar_tfsr) },
{ MMU_BIT_DESC(TRN_OOR, mmu_tfa, mmu_tfar_tfsr) },
{ MMU_BIT_DESC(TTE_INV, mmu_tfa, mmu_tfar_tfsr) },
{ MMU_BIT_DESC(TTE_PRT, mmu_tfa, mmu_tfar_tfsr) },
{ MMU_BIT_DESC(TTC_DPE, mmu_parity, mmu_tfar_tfsr) },
{ MMU_BIT_DESC(TBW_DME, panic, mmu_tfar_tfsr) },
{ MMU_BIT_DESC(TBW_UDE, panic, mmu_tfar_tfsr) },
{ MMU_BIT_DESC(TBW_ERR, panic, mmu_tfar_tfsr) },
{ MMU_BIT_DESC(TBW_DPE, mmu_parity, mmu_tfar_tfsr) },
{ MMU_BIT_DESC(TTC_CAE, panic, mmu) }
};
#define px_err_mmu_keys (sizeof (px_err_mmu_tbl)) / (sizeof (px_err_bit_desc_t))
#define ILU_BIT_DESC(bit, hdl, erpt) \
ILU_INTERRUPT_STATUS_ ## bit ## _P, \
0, \
PX_ERR_BIT_HANDLE(hdl), \
PX_ERPT_SEND(erpt), \
PX_ERR_PEC_CLASS(bit) }, \
{ ILU_INTERRUPT_STATUS_ ## bit ## _S, \
0, \
PX_ERR_BIT_HANDLE(hdl), \
PX_ERPT_SEND(erpt), \
PX_ERR_PEC_CLASS(bit)
px_err_bit_desc_t px_err_ilu_tbl[] = {
{ ILU_BIT_DESC(IHB_PE, panic, pec_ilu) }
};
#define px_err_ilu_keys \
(sizeof (px_err_ilu_tbl)) / (sizeof (px_err_bit_desc_t))
#define TLU_UC_BIT_DESC(bit, hdl, erpt) \
TLU_UNCORRECTABLE_ERROR_STATUS_CLEAR_ ## bit ## _P, \
0, \
PX_ERR_BIT_HANDLE(hdl), \
PX_ERPT_SEND(erpt), \
PX_ERR_PEC_CLASS(bit) }, \
{ TLU_UNCORRECTABLE_ERROR_STATUS_CLEAR_ ## bit ## _S, \
0, \
PX_ERR_BIT_HANDLE(hdl), \
PX_ERPT_SEND(erpt), \
PX_ERR_PEC_CLASS(bit)
#define TLU_UC_OB_BIT_DESC(bit, hdl, erpt) \
TLU_UNCORRECTABLE_ERROR_STATUS_CLEAR_ ## bit ## _P, \
0, \
PX_ERR_BIT_HANDLE(hdl), \
PX_ERPT_SEND(erpt), \
PX_ERR_PEC_OB_CLASS(bit) }, \
{ TLU_UNCORRECTABLE_ERROR_STATUS_CLEAR_ ## bit ## _S, \
0, \
PX_ERR_BIT_HANDLE(hdl), \
PX_ERPT_SEND(erpt), \
PX_ERR_PEC_OB_CLASS(bit)
px_err_bit_desc_t px_err_tlu_ue_tbl[] = {
{ TLU_UC_BIT_DESC(UR, pciex_ue, pciex_rx_ue) },
{ TLU_UC_BIT_DESC(UC, pciex_ue, pciex_rx_ue) },
{ TLU_UC_OB_BIT_DESC(ECRC, pciex_ue, pciex_rx_ue) },
{ TLU_UC_BIT_DESC(CTO, pciex_ue, pciex_tx_ue) },
{ TLU_UC_BIT_DESC(ROF, pciex_ue, pciex_tx_ue) },
{ TLU_UC_BIT_DESC(MFP, pciex_ue, pciex_rx_tx_ue) },
{ TLU_UC_BIT_DESC(PP, pciex_ue, pciex_rx_tx_ue) },
{ TLU_UC_BIT_DESC(FCP, pciex_ue, pciex_ue) },
{ TLU_UC_BIT_DESC(DLP, pciex_ue, pciex_ue) },
{ TLU_UC_BIT_DESC(TE, pciex_ue, pciex_ue) },
{ TLU_UC_BIT_DESC(CA, pciex_ue, do_not) }
};
#define px_err_tlu_ue_keys \
(sizeof (px_err_tlu_ue_tbl)) / (sizeof (px_err_bit_desc_t))
#define TLU_CE_BIT_DESC(bit, hdl, erpt) \
TLU_CORRECTABLE_ERROR_STATUS_CLEAR_ ## bit ## _P, \
0, \
PX_ERR_BIT_HANDLE(hdl), \
PX_ERPT_SEND(erpt), \
PX_ERR_PEC_CLASS(bit) }, \
{ TLU_CORRECTABLE_ERROR_STATUS_CLEAR_ ## bit ## _S, \
0, \
PX_ERR_BIT_HANDLE(hdl), \
PX_ERPT_SEND(erpt), \
PX_ERR_PEC_CLASS(bit)
px_err_bit_desc_t px_err_tlu_ce_tbl[] = {
{ TLU_CE_BIT_DESC(RTO, pciex_ce, pciex_ce) },
{ TLU_CE_BIT_DESC(RNR, pciex_ce, pciex_ce) },
{ TLU_CE_BIT_DESC(BDP, pciex_ce, pciex_ce) },
{ TLU_CE_BIT_DESC(BTP, pciex_ce, pciex_ce) },
{ TLU_CE_BIT_DESC(RE, pciex_ce, pciex_ce) }
};
#define px_err_tlu_ce_keys \
(sizeof (px_err_tlu_ce_tbl)) / (sizeof (px_err_bit_desc_t))
#define TLU_OE_BIT_DESC(bit, hdl, erpt) \
TLU_OTHER_EVENT_STATUS_CLEAR_ ## bit ## _P, \
0, \
PX_ERR_BIT_HANDLE(hdl), \
PX_ERPT_SEND(erpt), \
PX_ERR_PEC_CLASS(bit) }, \
{ TLU_OTHER_EVENT_STATUS_CLEAR_ ## bit ## _S, \
0, \
PX_ERR_BIT_HANDLE(hdl), \
PX_ERPT_SEND(erpt), \
PX_ERR_PEC_CLASS(bit)
#define TLU_OE_OB_BIT_DESC(bit, hdl, erpt) \
TLU_OTHER_EVENT_STATUS_CLEAR_ ## bit ## _P, \
0, \
PX_ERR_BIT_HANDLE(hdl), \
PX_ERPT_SEND(erpt), \
PX_ERR_PEC_OB_CLASS(bit) }, \
{ TLU_OTHER_EVENT_STATUS_CLEAR_ ## bit ## _S, \
0, \
PX_ERR_BIT_HANDLE(hdl), \
PX_ERPT_SEND(erpt), \
PX_ERR_PEC_OB_CLASS(bit)
px_err_bit_desc_t px_err_tlu_oe_tbl[] = {
{ TLU_OE_BIT_DESC(MRC, hw_reset, pciex_rx_oe) },
{ TLU_OE_BIT_DESC(WUC, wuc_ruc, pciex_rx_tx_oe) },
{ TLU_OE_BIT_DESC(RUC, wuc_ruc, pciex_rx_tx_oe) },
{ TLU_OE_BIT_DESC(CRS, no_panic, pciex_rx_tx_oe) },
{ TLU_OE_BIT_DESC(IIP, panic, pciex_oe) },
{ TLU_OE_BIT_DESC(EDP, panic, pciex_oe) },
{ TLU_OE_BIT_DESC(EHP, panic, pciex_oe) },
{ TLU_OE_OB_BIT_DESC(TLUEITMO, panic, pciex_oe) },
{ TLU_OE_BIT_DESC(LIN, no_panic, pciex_oe) },
{ TLU_OE_BIT_DESC(LRS, no_panic, pciex_oe) },
{ TLU_OE_BIT_DESC(LDN, tlu_ldn, pciex_oe) },
{ TLU_OE_BIT_DESC(LUP, tlu_lup, pciex_oe) },
{ TLU_OE_BIT_DESC(ERU, panic, pciex_oe) },
{ TLU_OE_BIT_DESC(ERO, panic, pciex_oe) },
{ TLU_OE_BIT_DESC(EMP, panic, pciex_oe) },
{ TLU_OE_BIT_DESC(EPE, panic, pciex_oe) },
{ TLU_OE_BIT_DESC(ERP, panic, pciex_oe) },
{ TLU_OE_BIT_DESC(EIP, panic, pciex_oe) }
};
#define px_err_tlu_oe_keys \
(sizeof (px_err_tlu_oe_tbl)) / (sizeof (px_err_bit_desc_t))
#define LPUL_BIT_DESC(bit, hdl, erpt) \
LPU_LINK_LAYER_INTERRUPT_AND_STATUS_INT_ ## bit, \
0, \
NULL, \
NULL, \
""
px_err_bit_desc_t px_err_lpul_tbl[] = {
{ LPUL_BIT_DESC(LINK_ERR_ACT, NULL, NULL) }
};
#define px_err_lpul_keys \
(sizeof (px_err_lpul_tbl)) / (sizeof (px_err_bit_desc_t))
#define LPUP_BIT_DESC(bit, hdl, erpt) \
LPU_PHY_LAYER_INTERRUPT_AND_STATUS_INT_ ## bit, \
0, \
NULL, \
NULL, \
""
px_err_bit_desc_t px_err_lpup_tbl[] = {
{ LPUP_BIT_DESC(PHY_LAYER_ERR, NULL, NULL) }
};
#define px_err_lpup_keys \
(sizeof (px_err_lpup_tbl)) / (sizeof (px_err_bit_desc_t))
#define LPUR_BIT_DESC(bit, hdl, erpt) \
LPU_RECEIVE_PHY_INTERRUPT_AND_STATUS_INT_ ## bit, \
0, \
NULL, \
NULL, \
""
px_err_bit_desc_t px_err_lpur_tbl[] = {
{ LPUR_BIT_DESC(RCV_PHY, NULL, NULL) }
};
#define px_err_lpur_keys \
(sizeof (px_err_lpur_tbl)) / (sizeof (px_err_bit_desc_t))
#define LPUX_BIT_DESC(bit, hdl, erpt) \
LPU_TRANSMIT_PHY_INTERRUPT_AND_STATUS_INT_ ## bit, \
0, \
NULL, \
NULL, \
""
px_err_bit_desc_t px_err_lpux_tbl[] = {
{ LPUX_BIT_DESC(UNMSK, NULL, NULL) }
};
#define px_err_lpux_keys \
(sizeof (px_err_lpux_tbl)) / (sizeof (px_err_bit_desc_t))
#define LPUS_BIT_DESC(bit, hdl, erpt) \
LPU_LTSSM_INTERRUPT_AND_STATUS_INT_ ## bit, \
0, \
NULL, \
NULL, \
""
px_err_bit_desc_t px_err_lpus_tbl[] = {
{ LPUS_BIT_DESC(ANY, NULL, NULL) }
};
#define px_err_lpus_keys \
(sizeof (px_err_lpus_tbl)) / (sizeof (px_err_bit_desc_t))
#define LPUG_BIT_DESC(bit, hdl, erpt) \
LPU_GIGABLAZE_GLUE_INTERRUPT_AND_STATUS_INT_ ## bit, \
0, \
NULL, \
NULL, \
""
px_err_bit_desc_t px_err_lpug_tbl[] = {
{ LPUG_BIT_DESC(GLOBL_UNMSK, NULL, NULL) }
};
#define px_err_lpug_keys \
(sizeof (px_err_lpug_tbl)) / (sizeof (px_err_bit_desc_t))
#define MnT6X(pre) \
&px_ ## pre ## _intr_mask, \
&px_ ## pre ## _log_mask, \
&px_ ## pre ## _count_mask, \
px_err_ ## pre ## _tbl, \
px_err_ ## pre ## _keys, \
PX_REG_XBC, \
0
#define MnT6(pre) \
&px_ ## pre ## _intr_mask, \
&px_ ## pre ## _log_mask, \
&px_ ## pre ## _count_mask, \
px_err_ ## pre ## _tbl, \
px_err_ ## pre ## _keys, \
PX_REG_CSR, \
0
#define LR4(pre) \
0, \
LPU_ ## pre ## _INTERRUPT_MASK, \
LPU_ ## pre ## _INTERRUPT_AND_STATUS, \
LPU_ ## pre ## _INTERRUPT_AND_STATUS
#define LR4_FIXME(pre) \
0, \
LPU_ ## pre ## _INTERRUPT_MASK, \
LPU_ ## pre ## _LAYER_INTERRUPT_AND_STATUS, \
LPU_ ## pre ## _LAYER_INTERRUPT_AND_STATUS
#define TR4(pre) \
TLU_ ## pre ## _LOG_ENABLE, \
TLU_ ## pre ## _INTERRUPT_ENABLE, \
TLU_ ## pre ## _INTERRUPT_STATUS, \
TLU_ ## pre ## _STATUS_CLEAR
#define R4(pre) \
pre ## _ERROR_LOG_ENABLE, \
pre ## _INTERRUPT_ENABLE, \
pre ## _INTERRUPT_STATUS, \
pre ## _ERROR_STATUS_CLEAR
#define CHP_O BITMASK(PX_CHIP_OBERON)
#define CHP_F BITMASK(PX_CHIP_FIRE)
#define CHP_FO (CHP_F | CHP_O)
static const
px_err_reg_desc_t px_err_reg_tbl[] = {
{ CHP_F, MnT6X(jbc), R4(JBC), "JBC Error"},
{ CHP_O, MnT6X(ubc), R4(UBC), "UBC Error"},
{ CHP_FO, MnT6(mmu), R4(MMU), "MMU Error"},
{ CHP_FO, MnT6(imu), R4(IMU), "IMU Error"},
{ CHP_FO, MnT6(tlu_ue), TR4(UNCORRECTABLE_ERROR), "TLU UE"},
{ CHP_FO, MnT6(tlu_ce), TR4(CORRECTABLE_ERROR), "TLU CE"},
{ CHP_FO, MnT6(tlu_oe), TR4(OTHER_EVENT), "TLU OE"},
{ CHP_FO, MnT6(ilu), R4(ILU), "ILU Error"},
{ CHP_F, MnT6(lpul), LR4(LINK_LAYER), "LPU Link Layer"},
{ CHP_F, MnT6(lpup), LR4_FIXME(PHY), "LPU Phy Layer"},
{ CHP_F, MnT6(lpur), LR4(RECEIVE_PHY), "LPU RX Phy Layer"},
{ CHP_F, MnT6(lpux), LR4(TRANSMIT_PHY), "LPU TX Phy Layer"},
{ CHP_F, MnT6(lpus), LR4(LTSSM), "LPU LTSSM"},
{ CHP_F, MnT6(lpug), LR4(GIGABLAZE_GLUE), "LPU GigaBlaze Glue"},
};
#define PX_ERR_REG_KEYS (sizeof (px_err_reg_tbl)) / (sizeof (px_err_reg_tbl[0]))
typedef struct px_err_ss {
uint64_t err_status[PX_ERR_REG_KEYS];
} px_err_ss_t;
static void px_err_snapshot(px_t *px_p, px_err_ss_t *ss, int block);
static int px_err_erpt_and_clr(px_t *px_p, ddi_fm_error_t *derr,
px_err_ss_t *ss);
static int px_err_check_severity(px_t *px_p, ddi_fm_error_t *derr,
int err, int caller);
uint_t
px_err_cb_intr(caddr_t arg)
{
px_fault_t *px_fault_p = (px_fault_t *)arg;
dev_info_t *rpdip = px_fault_p->px_fh_dip;
px_t *px_p = DIP_TO_STATE(rpdip);
int err;
ddi_fm_error_t derr;
bzero(&derr, sizeof (ddi_fm_error_t));
derr.fme_version = DDI_FME_VERSION;
derr.fme_ena = fm_ena_generate(0, FM_ENA_FMT1);
derr.fme_flag = DDI_FM_ERR_UNEXPECTED;
if (px_fm_enter(px_p) != DDI_SUCCESS)
goto done;
err = px_err_cmn_intr(px_p, &derr, PX_INTR_CALL, PX_FM_BLOCK_HOST);
(void) px_lib_intr_setstate(rpdip, px_fault_p->px_fh_sysino,
INTR_IDLE_STATE);
px_err_panic(err, PX_HB, PX_NO_ERROR, B_TRUE);
px_fm_exit(px_p);
px_err_panic(err, PX_HB, PX_NO_ERROR, B_FALSE);
done:
return (DDI_INTR_CLAIMED);
}
uint_t
px_err_dmc_pec_intr(caddr_t arg)
{
px_fault_t *px_fault_p = (px_fault_t *)arg;
dev_info_t *rpdip = px_fault_p->px_fh_dip;
px_t *px_p = DIP_TO_STATE(rpdip);
int rc_err, fab_err;
ddi_fm_error_t derr;
bzero(&derr, sizeof (ddi_fm_error_t));
derr.fme_version = DDI_FME_VERSION;
derr.fme_ena = fm_ena_generate(0, FM_ENA_FMT1);
derr.fme_flag = DDI_FM_ERR_UNEXPECTED;
if (px_fm_enter(px_p) != DDI_SUCCESS)
goto done;
rc_err = px_err_cmn_intr(px_p, &derr, PX_INTR_CALL, PX_FM_BLOCK_PCIE);
fab_err = px_scan_fabric(px_p, rpdip, &derr);
(void) px_lib_intr_setstate(rpdip, px_fault_p->px_fh_sysino,
INTR_IDLE_STATE);
px_err_panic(rc_err, PX_RC, fab_err, B_TRUE);
px_fm_exit(px_p);
px_err_panic(rc_err, PX_RC, fab_err, B_FALSE);
done:
return (DDI_INTR_CLAIMED);
}
void
px_err_reg_enable(px_err_id_t reg_id, caddr_t csr_base)
{
const px_err_reg_desc_t *reg_desc_p = &px_err_reg_tbl[reg_id];
uint64_t intr_mask = *reg_desc_p->intr_mask_p;
uint64_t log_mask = *reg_desc_p->log_mask_p;
if (reg_desc_p->log_addr != 0)
CSR_XS(csr_base, reg_desc_p->log_addr, log_mask);
CSR_XS(csr_base, reg_desc_p->enable_addr, 0);
CSR_XS(csr_base, reg_desc_p->clear_addr, -1);
CSR_XS(csr_base, reg_desc_p->enable_addr, intr_mask);
DBG(DBG_ATTACH, NULL, "%s Mask: 0x%llx\n", reg_desc_p->msg,
CSR_XR(csr_base, reg_desc_p->enable_addr));
DBG(DBG_ATTACH, NULL, "%s Status: 0x%llx\n", reg_desc_p->msg,
CSR_XR(csr_base, reg_desc_p->status_addr));
DBG(DBG_ATTACH, NULL, "%s Clear: 0x%llx\n", reg_desc_p->msg,
CSR_XR(csr_base, reg_desc_p->clear_addr));
if (reg_desc_p->log_addr != 0) {
DBG(DBG_ATTACH, NULL, "%s Log: 0x%llx\n", reg_desc_p->msg,
CSR_XR(csr_base, reg_desc_p->log_addr));
}
}
void
px_err_reg_disable(px_err_id_t reg_id, caddr_t csr_base)
{
const px_err_reg_desc_t *reg_desc_p = &px_err_reg_tbl[reg_id];
uint64_t val = (reg_id >= PX_ERR_LPU_LINK) ? -1 : 0;
if (reg_desc_p->log_addr != 0)
CSR_XS(csr_base, reg_desc_p->log_addr, val);
CSR_XS(csr_base, reg_desc_p->enable_addr, val);
}
void
px_err_reg_setup_pcie(uint8_t chip_mask, caddr_t csr_base, boolean_t enable)
{
px_err_id_t reg_id;
const px_err_reg_desc_t *reg_desc_p;
void (*px_err_reg_func)(px_err_id_t, caddr_t);
px_err_reg_func = (enable ? px_err_reg_enable : px_err_reg_disable);
for (reg_id = 0; reg_id < PX_ERR_REG_KEYS; reg_id++) {
reg_desc_p = &px_err_reg_tbl[reg_id];
if ((reg_desc_p->chip_mask & chip_mask) &&
(reg_desc_p->reg_bank == PX_REG_CSR))
px_err_reg_func(reg_id, csr_base);
}
}
int
px_err_cmn_intr(px_t *px_p, ddi_fm_error_t *derr, int caller, int block)
{
px_err_ss_t ss = {0};
int err;
ASSERT(MUTEX_HELD(&px_p->px_fm_mutex));
px_err_safeacc_check(px_p, derr);
px_err_snapshot(px_p, &ss, block);
err = px_err_erpt_and_clr(px_p, derr, &ss);
err = px_err_check_severity(px_p, derr, err, caller);
if (err != PX_NO_ERROR) {
px_pec_t *pec_p = px_p->px_pec_p;
on_trap_data_t *otd = pec_p->pec_ontrap_data;
if ((otd != NULL) && (otd->ot_prot & OT_DATA_ACCESS))
otd->ot_trap |= OT_DATA_ACCESS;
}
return (err);
}
static void
px_err_snapshot(px_t *px_p, px_err_ss_t *ss_p, int block)
{
pxu_t *pxu_p = (pxu_t *)px_p->px_plat_p;
caddr_t xbc_csr_base = (caddr_t)pxu_p->px_address[PX_REG_XBC];
caddr_t pec_csr_base = (caddr_t)pxu_p->px_address[PX_REG_CSR];
caddr_t csr_base;
uint8_t chip_mask = 1 << PX_CHIP_TYPE(pxu_p);
const px_err_reg_desc_t *reg_desc_p = px_err_reg_tbl;
px_err_id_t reg_id;
for (reg_id = 0; reg_id < PX_ERR_REG_KEYS; reg_id++, reg_desc_p++) {
if (!(reg_desc_p->chip_mask & chip_mask))
continue;
if ((block & PX_FM_BLOCK_HOST) &&
(reg_desc_p->reg_bank == PX_REG_XBC))
csr_base = xbc_csr_base;
else if ((block & PX_FM_BLOCK_PCIE) &&
(reg_desc_p->reg_bank == PX_REG_CSR))
csr_base = pec_csr_base;
else {
ss_p->err_status[reg_id] = 0;
continue;
}
ss_p->err_status[reg_id] = CSR_XR(csr_base,
reg_desc_p->status_addr);
}
}
static int
px_err_erpt_and_clr(px_t *px_p, ddi_fm_error_t *derr, px_err_ss_t *ss_p)
{
dev_info_t *rpdip = px_p->px_dip;
pxu_t *pxu_p = (pxu_t *)px_p->px_plat_p;
caddr_t csr_base;
const px_err_reg_desc_t *err_reg_tbl;
px_err_bit_desc_t *err_bit_tbl;
px_err_bit_desc_t *err_bit_desc;
uint64_t *count_mask;
uint64_t clear_addr;
uint64_t ss_reg;
int (*err_handler)();
int (*erpt_handler)();
int reg_id, key;
int err = PX_NO_ERROR;
int biterr = 0;
ASSERT(MUTEX_HELD(&px_p->px_fm_mutex));
for (reg_id = 0; reg_id < PX_ERR_REG_KEYS; reg_id++) {
err_reg_tbl = &px_err_reg_tbl[reg_id];
if (!(BIT_TST(err_reg_tbl->chip_mask, PX_CHIP_TYPE(pxu_p))))
continue;
csr_base = (caddr_t)pxu_p->px_address[err_reg_tbl->reg_bank];
ss_reg = ss_p->err_status[reg_id];
if (!ss_reg)
continue;
count_mask = err_reg_tbl->count_mask_p;
clear_addr = err_reg_tbl->clear_addr;
err_bit_tbl = err_reg_tbl->err_bit_tbl;
for (key = 0; key < err_reg_tbl->err_bit_keys; key++) {
err_bit_desc = &err_bit_tbl[key];
if (!BIT_TST(ss_reg, err_bit_desc->bit))
continue;
if (BIT_TST(*count_mask, err_bit_desc->bit)) {
err_bit_desc->counter++;
}
err_handler = err_bit_desc->err_handler;
if (err_handler) {
biterr = err_handler(rpdip, csr_base, derr,
err_reg_tbl, err_bit_desc);
err |= biterr;
}
erpt_handler = err_bit_desc->erpt_handler;
if ((derr->fme_flag != DDI_FM_ERR_UNEXPECTED) ||
(biterr == PX_EXPECTED))
continue;
if (erpt_handler)
(void) erpt_handler(rpdip, csr_base, ss_reg,
derr, err_bit_desc->bit,
err_bit_desc->class_name);
}
CSR_XS(csr_base, clear_addr, ss_reg);
}
return (err);
}
static int
px_err_check_severity(px_t *px_p, ddi_fm_error_t *derr, int err, int caller)
{
px_pec_t *pec_p = px_p->px_pec_p;
boolean_t is_safeacc = B_FALSE;
if (err == PX_NO_ERROR)
return (err);
switch (derr->fme_flag) {
case DDI_FM_ERR_EXPECTED:
if (caller == PX_TRAP_CALL) {
derr->fme_status = DDI_FM_NONFATAL;
is_safeacc = B_TRUE;
} else {
derr->fme_status = DDI_FM_NONFATAL;
ndi_fm_acc_err_set(pec_p->pec_acc_hdl, derr);
is_safeacc = B_TRUE;
}
break;
case DDI_FM_ERR_PEEK:
case DDI_FM_ERR_POKE:
is_safeacc = B_TRUE;
break;
default:
is_safeacc = B_FALSE;
}
if (is_safeacc)
return (PX_NO_PANIC);
return (err);
}
void
px_err_log_handle(dev_info_t *rpdip, px_err_reg_desc_t *err_reg_descr,
px_err_bit_desc_t *err_bit_descr, char *msg)
{
DBG(DBG_ERR_INTR, rpdip,
"Bit %d, %s, at %s(0x%x) has occured %d times with a severity "
"of \"%s\"\n",
err_bit_descr->bit, err_bit_descr->class_name,
err_reg_descr->msg, err_reg_descr->status_addr,
err_bit_descr->counter, msg);
}
int
px_err_hw_reset_handle(dev_info_t *rpdip, caddr_t csr_base,
ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
px_err_bit_desc_t *err_bit_descr)
{
if (px_log & PX_HW_RESET) {
px_err_log_handle(rpdip, err_reg_descr, err_bit_descr,
"HW RESET");
}
return (PX_HW_RESET);
}
int
px_err_panic_handle(dev_info_t *rpdip, caddr_t csr_base,
ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
px_err_bit_desc_t *err_bit_descr)
{
if (px_log & PX_PANIC) {
px_err_log_handle(rpdip, err_reg_descr, err_bit_descr, "PANIC");
}
return (PX_PANIC);
}
int
px_err_protected_handle(dev_info_t *rpdip, caddr_t csr_base,
ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
px_err_bit_desc_t *err_bit_descr)
{
if (px_log & PX_PROTECTED) {
px_err_log_handle(rpdip, err_reg_descr, err_bit_descr,
"PROTECTED");
}
return (PX_PROTECTED);
}
int
px_err_no_panic_handle(dev_info_t *rpdip, caddr_t csr_base,
ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
px_err_bit_desc_t *err_bit_descr)
{
if (px_log & PX_NO_PANIC) {
px_err_log_handle(rpdip, err_reg_descr, err_bit_descr,
"NO PANIC");
}
return (PX_NO_PANIC);
}
int
px_err_no_error_handle(dev_info_t *rpdip, caddr_t csr_base,
ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
px_err_bit_desc_t *err_bit_descr)
{
if (px_log & PX_NO_ERROR) {
px_err_log_handle(rpdip, err_reg_descr, err_bit_descr,
"NO ERROR");
}
return (PX_NO_ERROR);
}
PX_ERPT_SEND_DEC(do_not)
{
return (PX_NO_ERROR);
}
static dev_info_t *
px_err_search_cb(px_cb_t *px_cb_p, uint_t leaf_id)
{
int i;
px_cb_list_t *pxl_elemp;
for (i = px_cb_p->attachcnt, pxl_elemp = px_cb_p->pxl; i > 0;
i--, pxl_elemp = pxl_elemp->next) {
if ((((pxu_t *)pxl_elemp->pxp->px_plat_p)->portid &
OBERON_PORT_ID_LEAF_MASK) == leaf_id) {
return (pxl_elemp->pxp->px_dip);
}
}
return (NULL);
}
PX_ERPT_SEND_DEC(ubc_fatal)
{
char buf[FM_MAX_CLASS];
uint64_t memory_ue_log, marked;
char unum[FM_MAX_CLASS];
int unum_length;
uint64_t device_id = 0;
uint8_t cpu_version = 0;
nvlist_t *resource = NULL;
uint64_t ubc_intr_status;
px_t *px_p;
px_cb_t *px_cb_p;
dev_info_t *actual_dip;
unum[0] = '\0';
(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
memory_ue_log = CSR_XR(csr_base, UBC_MEMORY_UE_LOG);
marked = (memory_ue_log >> UBC_MEMORY_UE_LOG_MARKED) &
UBC_MEMORY_UE_LOG_MARKED_MASK;
if ((strstr(class_name, "ubc.piowtue") != NULL) ||
(strstr(class_name, "ubc.piowbeue") != NULL) ||
(strstr(class_name, "ubc.piorbeue") != NULL) ||
(strstr(class_name, "ubc.dmarduea") != NULL) ||
(strstr(class_name, "ubc.dmardueb") != NULL)) {
int eid = (memory_ue_log >> UBC_MEMORY_UE_LOG_EID) &
UBC_MEMORY_UE_LOG_EID_MASK;
(void) strncat(buf, ubc_class_eid_qualifier[eid],
FM_MAX_CLASS);
if (eid == UBC_EID_MEM) {
uint64_t phys_addr = memory_ue_log &
MMU_OBERON_PADDR_MASK;
uint64_t offset = (uint64_t)-1;
resource = fm_nvlist_create(NULL);
if (&plat_get_mem_unum) {
if ((plat_get_mem_unum(0,
phys_addr, 0, B_TRUE, 0, unum,
FM_MAX_CLASS, &unum_length)) != 0)
unum[0] = '\0';
}
fm_fmri_mem_set(resource, FM_MEM_SCHEME_VERSION,
NULL, unum, NULL, offset);
} else if (eid == UBC_EID_CPU) {
int cpuid = (marked & UBC_MARKED_MAX_CPUID_MASK);
char sbuf[21];
resource = fm_nvlist_create(NULL);
cpu_version = cpunodes[cpuid].version;
device_id = cpunodes[cpuid].device_id;
(void) snprintf(sbuf, sizeof (sbuf), "%lX",
device_id);
(void) fm_fmri_cpu_set(resource,
FM_CPU_SCHEME_VERSION, NULL, cpuid,
&cpu_version, sbuf);
}
}
px_p = DIP_TO_STATE(rpdip);
px_cb_p = ((pxu_t *)px_p->px_plat_p)->px_cb_p;
ubc_intr_status = CSR_XR(csr_base, UBC_INTERRUPT_STATUS);
if ((ubc_intr_status & UBC_INTERRUPT_STATUS_LEAFA) != 0) {
actual_dip = px_err_search_cb(px_cb_p, OBERON_PORT_ID_LEAF_A);
ASSERT(actual_dip != NULL);
rpdip = actual_dip;
} else if ((ubc_intr_status & UBC_INTERRUPT_STATUS_LEAFB) != 0) {
actual_dip = px_err_search_cb(px_cb_p, OBERON_PORT_ID_LEAF_B);
ASSERT(actual_dip != NULL);
rpdip = actual_dip;
}
if (resource) {
ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, B_TRUE,
OBERON_UBC_ELE, DATA_TYPE_UINT64,
CSR_XR(csr_base, UBC_ERROR_LOG_ENABLE),
OBERON_UBC_IE, DATA_TYPE_UINT64,
CSR_XR(csr_base, UBC_INTERRUPT_ENABLE),
OBERON_UBC_IS, DATA_TYPE_UINT64, ubc_intr_status,
OBERON_UBC_ESS, DATA_TYPE_UINT64,
CSR_XR(csr_base, UBC_ERROR_STATUS_SET),
OBERON_UBC_MUE, DATA_TYPE_UINT64, memory_ue_log,
OBERON_UBC_UNUM, DATA_TYPE_STRING, unum,
OBERON_UBC_DID, DATA_TYPE_UINT64, device_id,
OBERON_UBC_CPUV, DATA_TYPE_UINT32, cpu_version,
OBERON_UBC_RESOURCE, DATA_TYPE_NVLIST, resource,
NULL);
fm_nvlist_destroy(resource, FM_NVA_FREE);
} else {
ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, B_TRUE,
OBERON_UBC_ELE, DATA_TYPE_UINT64,
CSR_XR(csr_base, UBC_ERROR_LOG_ENABLE),
OBERON_UBC_IE, DATA_TYPE_UINT64,
CSR_XR(csr_base, UBC_INTERRUPT_ENABLE),
OBERON_UBC_IS, DATA_TYPE_UINT64, ubc_intr_status,
OBERON_UBC_ESS, DATA_TYPE_UINT64,
CSR_XR(csr_base, UBC_ERROR_STATUS_SET),
OBERON_UBC_MUE, DATA_TYPE_UINT64, memory_ue_log,
OBERON_UBC_UNUM, DATA_TYPE_STRING, unum,
OBERON_UBC_DID, DATA_TYPE_UINT64, device_id,
OBERON_UBC_CPUV, DATA_TYPE_UINT32, cpu_version,
NULL);
}
return (PX_NO_PANIC);
}
PX_ERPT_SEND_DEC(jbc_fatal)
{
char buf[FM_MAX_CLASS];
boolean_t pri = PX_ERR_IS_PRI(bit);
(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
FIRE_JBC_ELE, DATA_TYPE_UINT64,
CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE),
FIRE_JBC_IE, DATA_TYPE_UINT64,
CSR_XR(csr_base, JBC_INTERRUPT_ENABLE),
FIRE_JBC_IS, DATA_TYPE_UINT64,
ss_reg,
FIRE_JBC_ESS, DATA_TYPE_UINT64,
CSR_XR(csr_base, JBC_ERROR_STATUS_SET),
FIRE_JBC_FEL1, DATA_TYPE_UINT64,
CSR_XR(csr_base, FATAL_ERROR_LOG_1),
FIRE_JBC_FEL2, DATA_TYPE_UINT64,
CSR_XR(csr_base, FATAL_ERROR_LOG_2),
NULL);
return (PX_NO_PANIC);
}
PX_ERPT_SEND_DEC(jbc_merge)
{
char buf[FM_MAX_CLASS];
boolean_t pri = PX_ERR_IS_PRI(bit);
(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
FIRE_JBC_ELE, DATA_TYPE_UINT64,
CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE),
FIRE_JBC_IE, DATA_TYPE_UINT64,
CSR_XR(csr_base, JBC_INTERRUPT_ENABLE),
FIRE_JBC_IS, DATA_TYPE_UINT64,
ss_reg,
FIRE_JBC_ESS, DATA_TYPE_UINT64,
CSR_XR(csr_base, JBC_ERROR_STATUS_SET),
FIRE_JBC_MTEL, DATA_TYPE_UINT64,
CSR_XR(csr_base, MERGE_TRANSACTION_ERROR_LOG),
NULL);
return (PX_NO_PANIC);
}
int
px_err_jbc_merge_handle(dev_info_t *rpdip, caddr_t csr_base,
ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
px_err_bit_desc_t *err_bit_descr)
{
return (px_err_panic_handle(rpdip, csr_base, derr, err_reg_descr,
err_bit_descr));
}
PX_ERPT_SEND_DEC(jbc_in)
{
char buf[FM_MAX_CLASS];
boolean_t pri = PX_ERR_IS_PRI(bit);
(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
FIRE_JBC_ELE, DATA_TYPE_UINT64,
CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE),
FIRE_JBC_IE, DATA_TYPE_UINT64,
CSR_XR(csr_base, JBC_INTERRUPT_ENABLE),
FIRE_JBC_IS, DATA_TYPE_UINT64,
ss_reg,
FIRE_JBC_ESS, DATA_TYPE_UINT64,
CSR_XR(csr_base, JBC_ERROR_STATUS_SET),
FIRE_JBC_JITEL1, DATA_TYPE_UINT64,
CSR_XR(csr_base, JBCINT_IN_TRANSACTION_ERROR_LOG),
FIRE_JBC_JITEL2, DATA_TYPE_UINT64,
CSR_XR(csr_base, JBCINT_IN_TRANSACTION_ERROR_LOG_2),
NULL);
return (PX_NO_PANIC);
}
int
px_err_jbc_jbusint_in_handle(dev_info_t *rpdip, caddr_t csr_base,
ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
px_err_bit_desc_t *err_bit_descr)
{
return (px_err_panic_handle(rpdip, csr_base, derr, err_reg_descr,
err_bit_descr));
}
PX_ERPT_SEND_DEC(jbc_out)
{
char buf[FM_MAX_CLASS];
boolean_t pri = PX_ERR_IS_PRI(bit);
(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
FIRE_JBC_ELE, DATA_TYPE_UINT64,
CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE),
FIRE_JBC_IE, DATA_TYPE_UINT64,
CSR_XR(csr_base, JBC_INTERRUPT_ENABLE),
FIRE_JBC_IS, DATA_TYPE_UINT64,
ss_reg,
FIRE_JBC_ESS, DATA_TYPE_UINT64,
CSR_XR(csr_base, JBC_ERROR_STATUS_SET),
FIRE_JBC_JOTEL1, DATA_TYPE_UINT64,
CSR_XR(csr_base, JBCINT_OUT_TRANSACTION_ERROR_LOG),
FIRE_JBC_JOTEL2, DATA_TYPE_UINT64,
CSR_XR(csr_base, JBCINT_OUT_TRANSACTION_ERROR_LOG_2),
NULL);
return (PX_NO_PANIC);
}
PX_ERPT_SEND_DEC(jbc_odcd)
{
char buf[FM_MAX_CLASS];
boolean_t pri = PX_ERR_IS_PRI(bit);
(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
FIRE_JBC_ELE, DATA_TYPE_UINT64,
CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE),
FIRE_JBC_IE, DATA_TYPE_UINT64,
CSR_XR(csr_base, JBC_INTERRUPT_ENABLE),
FIRE_JBC_IS, DATA_TYPE_UINT64,
ss_reg,
FIRE_JBC_ESS, DATA_TYPE_UINT64,
CSR_XR(csr_base, JBC_ERROR_STATUS_SET),
FIRE_JBC_DMC_ODCD, DATA_TYPE_UINT64,
CSR_XR(csr_base, DMCINT_ODCD_ERROR_LOG),
NULL);
return (PX_NO_PANIC);
}
int
px_err_jbc_dmcint_odcd_handle(dev_info_t *rpdip, caddr_t csr_base,
ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
px_err_bit_desc_t *err_bit_descr)
{
return (px_err_panic_handle(rpdip, csr_base, derr, err_reg_descr,
err_bit_descr));
}
static boolean_t
px_jbc_pcitool_addr_match(dev_info_t *rpdip, caddr_t csr_base)
{
px_t *px_p = DIP_TO_STATE(rpdip);
pxu_t *pxu_p = (pxu_t *)px_p->px_plat_p;
caddr_t pcitool_addr = pxu_p->pcitool_addr;
caddr_t errlog_addr =
(caddr_t)CSR_FR(csr_base, DMCINT_ODCD_ERROR_LOG, ADDRESS);
return (pcitool_addr == errlog_addr);
}
int
px_err_jbc_safe_acc_handle(dev_info_t *rpdip, caddr_t csr_base,
ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
px_err_bit_desc_t *err_bit_descr)
{
boolean_t pri = PX_ERR_IS_PRI(err_bit_descr->bit);
if (!pri)
return (px_err_panic_handle(rpdip, csr_base, derr,
err_reg_descr, err_bit_descr));
if ((derr->fme_flag != DDI_FM_ERR_UNEXPECTED) &&
(px_jbc_pcitool_addr_match(rpdip, csr_base)))
return (px_err_protected_handle(rpdip, csr_base, derr,
err_reg_descr, err_bit_descr));
return (px_err_jbc_dmcint_odcd_handle(rpdip, csr_base, derr,
err_reg_descr, err_bit_descr));
}
PX_ERPT_SEND_DEC(jbc_idc)
{
char buf[FM_MAX_CLASS];
boolean_t pri = PX_ERR_IS_PRI(bit);
(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
FIRE_JBC_ELE, DATA_TYPE_UINT64,
CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE),
FIRE_JBC_IE, DATA_TYPE_UINT64,
CSR_XR(csr_base, JBC_INTERRUPT_ENABLE),
FIRE_JBC_IS, DATA_TYPE_UINT64,
ss_reg,
FIRE_JBC_ESS, DATA_TYPE_UINT64,
CSR_XR(csr_base, JBC_ERROR_STATUS_SET),
FIRE_JBC_DMC_IDC, DATA_TYPE_UINT64,
CSR_XR(csr_base, DMCINT_IDC_ERROR_LOG),
NULL);
return (PX_NO_PANIC);
}
PX_ERPT_SEND_DEC(jbc_csr)
{
char buf[FM_MAX_CLASS];
boolean_t pri = PX_ERR_IS_PRI(bit);
(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
FIRE_JBC_ELE, DATA_TYPE_UINT64,
CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE),
FIRE_JBC_IE, DATA_TYPE_UINT64,
CSR_XR(csr_base, JBC_INTERRUPT_ENABLE),
FIRE_JBC_IS, DATA_TYPE_UINT64,
ss_reg,
FIRE_JBC_ESS, DATA_TYPE_UINT64,
CSR_XR(csr_base, JBC_ERROR_STATUS_SET),
"jbc-error-reg", DATA_TYPE_UINT64,
CSR_XR(csr_base, CSR_ERROR_LOG),
NULL);
return (PX_NO_PANIC);
}
PX_ERPT_SEND_DEC(imu_rds)
{
char buf[FM_MAX_CLASS];
boolean_t pri = PX_ERR_IS_PRI(bit);
(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
FIRE_IMU_ELE, DATA_TYPE_UINT64,
CSR_XR(csr_base, IMU_ERROR_LOG_ENABLE),
FIRE_IMU_IE, DATA_TYPE_UINT64,
CSR_XR(csr_base, IMU_INTERRUPT_ENABLE),
FIRE_IMU_IS, DATA_TYPE_UINT64,
ss_reg,
FIRE_IMU_ESS, DATA_TYPE_UINT64,
CSR_XR(csr_base, IMU_ERROR_STATUS_SET),
FIRE_IMU_RDS, DATA_TYPE_UINT64,
CSR_XR(csr_base, IMU_RDS_ERROR_LOG),
NULL);
return (PX_NO_PANIC);
}
int
px_err_imu_eq_ovfl_handle(dev_info_t *rpdip, caddr_t csr_base,
ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
px_err_bit_desc_t *err_bit_descr)
{
px_t *px_p = DIP_TO_STATE(rpdip);
pxu_t *pxu_p = (pxu_t *)px_p->px_plat_p;
int err = px_err_check_eq(rpdip);
if ((err == PX_PANIC) && (pxu_p->cpr_flag == PX_NOT_CPR)) {
return (px_err_panic_handle(rpdip, csr_base, derr,
err_reg_descr, err_bit_descr));
} else {
return (px_err_no_panic_handle(rpdip, csr_base, derr,
err_reg_descr, err_bit_descr));
}
}
PX_ERPT_SEND_DEC(imu_scs)
{
char buf[FM_MAX_CLASS];
boolean_t pri = PX_ERR_IS_PRI(bit);
(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
FIRE_IMU_ELE, DATA_TYPE_UINT64,
CSR_XR(csr_base, IMU_ERROR_LOG_ENABLE),
FIRE_IMU_IE, DATA_TYPE_UINT64,
CSR_XR(csr_base, IMU_INTERRUPT_ENABLE),
FIRE_IMU_IS, DATA_TYPE_UINT64,
ss_reg,
FIRE_IMU_ESS, DATA_TYPE_UINT64,
CSR_XR(csr_base, IMU_ERROR_STATUS_SET),
FIRE_IMU_SCS, DATA_TYPE_UINT64,
CSR_XR(csr_base, IMU_SCS_ERROR_LOG),
NULL);
return (PX_NO_PANIC);
}
PX_ERPT_SEND_DEC(imu)
{
char buf[FM_MAX_CLASS];
boolean_t pri = PX_ERR_IS_PRI(bit);
(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
FIRE_IMU_ELE, DATA_TYPE_UINT64,
CSR_XR(csr_base, IMU_ERROR_LOG_ENABLE),
FIRE_IMU_IE, DATA_TYPE_UINT64,
CSR_XR(csr_base, IMU_INTERRUPT_ENABLE),
FIRE_IMU_IS, DATA_TYPE_UINT64,
ss_reg,
FIRE_IMU_ESS, DATA_TYPE_UINT64,
CSR_XR(csr_base, IMU_ERROR_STATUS_SET),
NULL);
return (PX_NO_PANIC);
}
PX_ERPT_SEND_DEC(mmu_tfar_tfsr)
{
char buf[FM_MAX_CLASS];
boolean_t pri = PX_ERR_IS_PRI(bit);
px_t *px_p = DIP_TO_STATE(rpdip);
pcie_req_id_t fault_bdf = PCIE_INVALID_BDF;
uint16_t s_status = 0;
if (pri) {
fault_bdf = CSR_XR(csr_base, MMU_TRANSLATION_FAULT_STATUS)
& (MMU_TRANSLATION_FAULT_STATUS_ID_MASK <<
MMU_TRANSLATION_FAULT_STATUS_ID);
s_status = PCI_STAT_S_TARG_AB;
(void) px_rp_en_q(px_p, fault_bdf, 0, s_status);
}
(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
FIRE_MMU_ELE, DATA_TYPE_UINT64,
CSR_XR(csr_base, MMU_ERROR_LOG_ENABLE),
FIRE_MMU_IE, DATA_TYPE_UINT64,
CSR_XR(csr_base, MMU_INTERRUPT_ENABLE),
FIRE_MMU_IS, DATA_TYPE_UINT64,
ss_reg,
FIRE_MMU_ESS, DATA_TYPE_UINT64,
CSR_XR(csr_base, MMU_ERROR_STATUS_SET),
FIRE_MMU_TFAR, DATA_TYPE_UINT64,
CSR_XR(csr_base, MMU_TRANSLATION_FAULT_ADDRESS),
FIRE_MMU_TFSR, DATA_TYPE_UINT64,
CSR_XR(csr_base, MMU_TRANSLATION_FAULT_STATUS),
NULL);
return (PX_NO_PANIC);
}
PX_ERPT_SEND_DEC(mmu)
{
char buf[FM_MAX_CLASS];
boolean_t pri = PX_ERR_IS_PRI(bit);
(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
FIRE_MMU_ELE, DATA_TYPE_UINT64,
CSR_XR(csr_base, MMU_ERROR_LOG_ENABLE),
FIRE_MMU_IE, DATA_TYPE_UINT64,
CSR_XR(csr_base, MMU_INTERRUPT_ENABLE),
FIRE_MMU_IS, DATA_TYPE_UINT64,
ss_reg,
FIRE_MMU_ESS, DATA_TYPE_UINT64,
CSR_XR(csr_base, MMU_ERROR_STATUS_SET),
NULL);
return (PX_NO_PANIC);
}
int
px_err_mmu_rbne_handle(dev_info_t *rpdip, caddr_t csr_base,
ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
px_err_bit_desc_t *err_bit_descr)
{
pcie_req_id_t bdf;
if (!PX_ERR_IS_PRI(err_bit_descr->bit))
goto done;
bdf = (pcie_req_id_t)CSR_FR(csr_base, MMU_TRANSLATION_FAULT_STATUS, ID);
(void) pf_hdl_lookup(rpdip, derr->fme_ena, PF_ADDR_DMA, 0, bdf);
done:
return (px_err_no_panic_handle(rpdip, csr_base, derr, err_reg_descr,
err_bit_descr));
}
int
px_err_mmu_tfa_handle(dev_info_t *rpdip, caddr_t csr_base,
ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
px_err_bit_desc_t *err_bit_descr)
{
pcie_req_id_t bdf;
if (!PX_ERR_IS_PRI(err_bit_descr->bit))
goto done;
bdf = (pcie_req_id_t)CSR_FR(csr_base, MMU_TRANSLATION_FAULT_STATUS, ID);
(void) pf_hdl_lookup(rpdip, derr->fme_ena, PF_ADDR_DMA, 0, bdf);
done:
return (px_err_no_panic_handle(rpdip, csr_base, derr, err_reg_descr,
err_bit_descr));
}
int
px_err_mmu_parity_handle(dev_info_t *rpdip, caddr_t csr_base,
ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
px_err_bit_desc_t *err_bit_descr)
{
uint64_t mmu_tfa;
pcie_req_id_t bdf;
int status = PF_HDL_NOTFOUND;
if (!PX_ERR_IS_PRI(err_bit_descr->bit))
goto done;
mmu_tfa = CSR_XR(csr_base, MMU_TRANSLATION_FAULT_ADDRESS);
bdf = (pcie_req_id_t)CSR_FR(csr_base, MMU_TRANSLATION_FAULT_STATUS, ID);
status = pf_hdl_lookup(rpdip, derr->fme_ena, PF_ADDR_DMA,
(uint32_t)mmu_tfa, bdf);
done:
if (status == PF_HDL_NOTFOUND)
return (px_err_panic_handle(rpdip, csr_base, derr,
err_reg_descr, err_bit_descr));
else
return (px_err_no_panic_handle(rpdip, csr_base, derr,
err_reg_descr, err_bit_descr));
}
int
px_err_wuc_ruc_handle(dev_info_t *rpdip, caddr_t csr_base,
ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
px_err_bit_desc_t *err_bit_descr)
{
px_t *px_p = DIP_TO_STATE(rpdip);
pxu_t *pxu_p = (pxu_t *)px_p->px_plat_p;
uint64_t data;
pf_pcie_adv_err_regs_t adv_reg;
int sts;
if (!PX_ERR_IS_PRI(err_bit_descr->bit))
goto done;
data = CSR_XR(csr_base, TLU_TRANSMIT_OTHER_EVENT_HEADER1_LOG);
adv_reg.pcie_ue_hdr[0] = (uint32_t)(data >> 32);
adv_reg.pcie_ue_hdr[1] = (uint32_t)(data & 0xFFFFFFFF);
data = CSR_XR(csr_base, TLU_TRANSMIT_OTHER_EVENT_HEADER2_LOG);
adv_reg.pcie_ue_hdr[2] = (uint32_t)(data >> 32);
adv_reg.pcie_ue_hdr[3] = (uint32_t)(data & 0xFFFFFFFF);
(void) pf_tlp_decode(PCIE_DIP2BUS(rpdip), &adv_reg);
sts = pf_hdl_lookup(rpdip, derr->fme_ena, adv_reg.pcie_ue_tgt_trans,
adv_reg.pcie_ue_tgt_addr, adv_reg.pcie_ue_tgt_bdf);
done:
if ((sts == PF_HDL_NOTFOUND) && (pxu_p->cpr_flag == PX_NOT_CPR))
return (px_err_protected_handle(rpdip, csr_base, derr,
err_reg_descr, err_bit_descr));
return (px_err_no_panic_handle(rpdip, csr_base, derr,
err_reg_descr, err_bit_descr));
}
int
px_err_tlu_lup_handle(dev_info_t *rpdip, caddr_t csr_base,
ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
px_err_bit_desc_t *err_bit_descr)
{
px_t *px_p = DIP_TO_STATE(rpdip);
return ((atomic_cas_32(&px_p->px_lup_pending, 1, 0) == 0) ?
PX_NO_PANIC : PX_EXPECTED);
}
int
px_err_tlu_ldn_handle(dev_info_t *rpdip, caddr_t csr_base,
ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
px_err_bit_desc_t *err_bit_descr)
{
px_t *px_p = DIP_TO_STATE(rpdip);
return ((px_p->px_pm_flags & PX_LDN_EXPECTED) ? PX_EXPECTED :
PX_NO_PANIC);
}
PX_ERPT_SEND_DEC(pec_ilu)
{
char buf[FM_MAX_CLASS];
boolean_t pri = PX_ERR_IS_PRI(bit);
(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
FIRE_ILU_ELE, DATA_TYPE_UINT64,
CSR_XR(csr_base, ILU_ERROR_LOG_ENABLE),
FIRE_ILU_IE, DATA_TYPE_UINT64,
CSR_XR(csr_base, ILU_INTERRUPT_ENABLE),
FIRE_ILU_IS, DATA_TYPE_UINT64,
ss_reg,
FIRE_ILU_ESS, DATA_TYPE_UINT64,
CSR_XR(csr_base, ILU_ERROR_STATUS_SET),
NULL);
return (PX_NO_PANIC);
}
int
px_err_pciex_ue_handle(dev_info_t *rpdip, caddr_t csr_base,
ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
px_err_bit_desc_t *err_bit_descr)
{
px_err_pcie_t regs = {0};
uint32_t err_bit;
int err;
uint64_t log;
if (err_bit_descr->bit < 32) {
err_bit = (uint32_t)BITMASK(err_bit_descr->bit);
regs.ue_reg = err_bit;
regs.primary_ue = err_bit;
if ((PCIE_AER_UCE_PTLP | PCIE_AER_UCE_UR | PCIE_AER_UCE_UC) &
err_bit) {
log = CSR_XR(csr_base,
TLU_RECEIVE_UNCORRECTABLE_ERROR_HEADER1_LOG);
regs.rx_hdr1 = (uint32_t)(log >> 32);
regs.rx_hdr2 = (uint32_t)(log & 0xFFFFFFFF);
log = CSR_XR(csr_base,
TLU_RECEIVE_UNCORRECTABLE_ERROR_HEADER2_LOG);
regs.rx_hdr3 = (uint32_t)(log >> 32);
regs.rx_hdr4 = (uint32_t)(log & 0xFFFFFFFF);
}
} else {
regs.ue_reg = (uint32_t)BITMASK(err_bit_descr->bit - 32);
}
err = px_err_check_pcie(rpdip, derr, ®s, PF_INTR_TYPE_INTERNAL);
if (err & PX_PANIC) {
return (px_err_panic_handle(rpdip, csr_base, derr,
err_reg_descr, err_bit_descr));
} else {
return (px_err_no_panic_handle(rpdip, csr_base, derr,
err_reg_descr, err_bit_descr));
}
}
PX_ERPT_SEND_DEC(pciex_rx_ue)
{
char buf[FM_MAX_CLASS];
boolean_t pri = PX_ERR_IS_PRI(bit);
(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
FIRE_TLU_UELE, DATA_TYPE_UINT64,
CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_LOG_ENABLE),
FIRE_TLU_UIE, DATA_TYPE_UINT64,
CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_INTERRUPT_ENABLE),
FIRE_TLU_UIS, DATA_TYPE_UINT64,
ss_reg,
FIRE_TLU_UESS, DATA_TYPE_UINT64,
CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_STATUS_SET),
FIRE_TLU_RUEH1L, DATA_TYPE_UINT64,
CSR_XR(csr_base, TLU_RECEIVE_UNCORRECTABLE_ERROR_HEADER1_LOG),
FIRE_TLU_RUEH2L, DATA_TYPE_UINT64,
CSR_XR(csr_base, TLU_RECEIVE_UNCORRECTABLE_ERROR_HEADER2_LOG),
NULL);
return (PX_NO_PANIC);
}
PX_ERPT_SEND_DEC(pciex_tx_ue)
{
char buf[FM_MAX_CLASS];
boolean_t pri = PX_ERR_IS_PRI(bit);
(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
FIRE_TLU_UELE, DATA_TYPE_UINT64,
CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_LOG_ENABLE),
FIRE_TLU_UIE, DATA_TYPE_UINT64,
CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_INTERRUPT_ENABLE),
FIRE_TLU_UIS, DATA_TYPE_UINT64,
ss_reg,
FIRE_TLU_UESS, DATA_TYPE_UINT64,
CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_STATUS_SET),
FIRE_TLU_TUEH1L, DATA_TYPE_UINT64,
CSR_XR(csr_base, TLU_TRANSMIT_UNCORRECTABLE_ERROR_HEADER1_LOG),
FIRE_TLU_TUEH2L, DATA_TYPE_UINT64,
CSR_XR(csr_base, TLU_TRANSMIT_UNCORRECTABLE_ERROR_HEADER2_LOG),
NULL);
return (PX_NO_PANIC);
}
PX_ERPT_SEND_DEC(pciex_rx_tx_ue)
{
char buf[FM_MAX_CLASS];
boolean_t pri = PX_ERR_IS_PRI(bit);
(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
FIRE_TLU_UELE, DATA_TYPE_UINT64,
CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_LOG_ENABLE),
FIRE_TLU_UIE, DATA_TYPE_UINT64,
CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_INTERRUPT_ENABLE),
FIRE_TLU_UIS, DATA_TYPE_UINT64,
ss_reg,
FIRE_TLU_UESS, DATA_TYPE_UINT64,
CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_STATUS_SET),
FIRE_TLU_RUEH1L, DATA_TYPE_UINT64,
CSR_XR(csr_base, TLU_RECEIVE_UNCORRECTABLE_ERROR_HEADER1_LOG),
FIRE_TLU_RUEH2L, DATA_TYPE_UINT64,
CSR_XR(csr_base, TLU_RECEIVE_UNCORRECTABLE_ERROR_HEADER2_LOG),
FIRE_TLU_TUEH1L, DATA_TYPE_UINT64,
CSR_XR(csr_base, TLU_TRANSMIT_UNCORRECTABLE_ERROR_HEADER1_LOG),
FIRE_TLU_TUEH2L, DATA_TYPE_UINT64,
CSR_XR(csr_base, TLU_TRANSMIT_UNCORRECTABLE_ERROR_HEADER2_LOG),
NULL);
return (PX_NO_PANIC);
}
PX_ERPT_SEND_DEC(pciex_ue)
{
char buf[FM_MAX_CLASS];
boolean_t pri = PX_ERR_IS_PRI(bit);
(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
FIRE_TLU_UELE, DATA_TYPE_UINT64,
CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_LOG_ENABLE),
FIRE_TLU_UIE, DATA_TYPE_UINT64,
CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_INTERRUPT_ENABLE),
FIRE_TLU_UIS, DATA_TYPE_UINT64,
ss_reg,
FIRE_TLU_UESS, DATA_TYPE_UINT64,
CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_STATUS_SET),
NULL);
return (PX_NO_PANIC);
}
int
px_err_pciex_ce_handle(dev_info_t *rpdip, caddr_t csr_base,
ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
px_err_bit_desc_t *err_bit_descr)
{
px_err_pcie_t regs = {0};
int err;
if (err_bit_descr->bit < 32)
regs.ce_reg = (uint32_t)BITMASK(err_bit_descr->bit);
else
regs.ce_reg = (uint32_t)BITMASK(err_bit_descr->bit - 32);
err = px_err_check_pcie(rpdip, derr, ®s, PF_INTR_TYPE_INTERNAL);
if (err & PX_PANIC) {
return (px_err_panic_handle(rpdip, csr_base, derr,
err_reg_descr, err_bit_descr));
} else {
return (px_err_no_panic_handle(rpdip, csr_base, derr,
err_reg_descr, err_bit_descr));
}
}
PX_ERPT_SEND_DEC(pciex_ce)
{
char buf[FM_MAX_CLASS];
boolean_t pri = PX_ERR_IS_PRI(bit);
(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
FIRE_TLU_CELE, DATA_TYPE_UINT64,
CSR_XR(csr_base, TLU_CORRECTABLE_ERROR_LOG_ENABLE),
FIRE_TLU_CIE, DATA_TYPE_UINT64,
CSR_XR(csr_base, TLU_CORRECTABLE_ERROR_INTERRUPT_ENABLE),
FIRE_TLU_CIS, DATA_TYPE_UINT64,
ss_reg,
FIRE_TLU_CESS, DATA_TYPE_UINT64,
CSR_XR(csr_base, TLU_CORRECTABLE_ERROR_STATUS_SET),
NULL);
return (PX_NO_PANIC);
}
PX_ERPT_SEND_DEC(pciex_rx_oe)
{
char buf[FM_MAX_CLASS];
boolean_t pri = PX_ERR_IS_PRI(bit);
(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
FIRE_TLU_OEELE, DATA_TYPE_UINT64,
CSR_XR(csr_base, TLU_OTHER_EVENT_LOG_ENABLE),
FIRE_TLU_OEIE, DATA_TYPE_UINT64,
CSR_XR(csr_base, TLU_OTHER_EVENT_INTERRUPT_ENABLE),
FIRE_TLU_OEIS, DATA_TYPE_UINT64,
ss_reg,
FIRE_TLU_OEESS, DATA_TYPE_UINT64,
CSR_XR(csr_base, TLU_OTHER_EVENT_STATUS_SET),
FIRE_TLU_RUEH1L, DATA_TYPE_UINT64,
CSR_XR(csr_base, TLU_RECEIVE_OTHER_EVENT_HEADER1_LOG),
FIRE_TLU_RUEH2L, DATA_TYPE_UINT64,
CSR_XR(csr_base, TLU_RECEIVE_OTHER_EVENT_HEADER2_LOG),
NULL);
return (PX_NO_PANIC);
}
PX_ERPT_SEND_DEC(pciex_rx_tx_oe)
{
char buf[FM_MAX_CLASS];
boolean_t pri = PX_ERR_IS_PRI(bit);
px_t *px_p = DIP_TO_STATE(rpdip);
uint64_t rx_h1, rx_h2, tx_h1, tx_h2;
uint16_t s_status;
int sts;
pcie_cpl_t *cpl;
pf_pcie_adv_err_regs_t adv_reg;
rx_h1 = CSR_XR(csr_base, TLU_RECEIVE_OTHER_EVENT_HEADER1_LOG);
rx_h2 = CSR_XR(csr_base, TLU_RECEIVE_OTHER_EVENT_HEADER2_LOG);
tx_h1 = CSR_XR(csr_base, TLU_TRANSMIT_OTHER_EVENT_HEADER1_LOG);
tx_h2 = CSR_XR(csr_base, TLU_TRANSMIT_OTHER_EVENT_HEADER2_LOG);
if ((bit == TLU_OTHER_EVENT_STATUS_SET_RUC_P) ||
(bit == TLU_OTHER_EVENT_STATUS_SET_WUC_P)) {
adv_reg.pcie_ue_hdr[0] = (uint32_t)(rx_h1 >> 32);
adv_reg.pcie_ue_hdr[1] = (uint32_t)rx_h1;
adv_reg.pcie_ue_hdr[2] = (uint32_t)(rx_h2 >> 32);
adv_reg.pcie_ue_hdr[3] = (uint32_t)rx_h2;
cpl = (pcie_cpl_t *)&adv_reg.pcie_ue_hdr[1];
if (cpl->status == PCIE_CPL_STS_UR)
s_status = PCI_STAT_R_MAST_AB;
else if (cpl->status == PCIE_CPL_STS_CA)
s_status = PCI_STAT_R_TARG_AB;
adv_reg.pcie_ue_hdr[0] = (uint32_t)(tx_h1 >> 32);
adv_reg.pcie_ue_hdr[1] = (uint32_t)tx_h1;
adv_reg.pcie_ue_hdr[2] = (uint32_t)(tx_h2 >> 32);
adv_reg.pcie_ue_hdr[3] = (uint32_t)tx_h2;
sts = pf_tlp_decode(PCIE_DIP2BUS(rpdip), &adv_reg);
if (sts == DDI_SUCCESS)
(void) px_rp_en_q(px_p, adv_reg.pcie_ue_tgt_bdf,
adv_reg.pcie_ue_tgt_addr, s_status);
}
(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
FIRE_TLU_OEELE, DATA_TYPE_UINT64,
CSR_XR(csr_base, TLU_OTHER_EVENT_LOG_ENABLE),
FIRE_TLU_OEIE, DATA_TYPE_UINT64,
CSR_XR(csr_base, TLU_OTHER_EVENT_INTERRUPT_ENABLE),
FIRE_TLU_OEIS, DATA_TYPE_UINT64,
ss_reg,
FIRE_TLU_OEESS, DATA_TYPE_UINT64,
CSR_XR(csr_base, TLU_OTHER_EVENT_STATUS_SET),
FIRE_TLU_ROEEH1L, DATA_TYPE_UINT64, rx_h1,
FIRE_TLU_ROEEH2L, DATA_TYPE_UINT64, rx_h2,
FIRE_TLU_TOEEH1L, DATA_TYPE_UINT64, tx_h1,
FIRE_TLU_TOEEH2L, DATA_TYPE_UINT64, tx_h2,
NULL);
return (PX_NO_PANIC);
}
PX_ERPT_SEND_DEC(pciex_oe)
{
char buf[FM_MAX_CLASS];
boolean_t pri = PX_ERR_IS_PRI(bit);
(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
FIRE_TLU_OEELE, DATA_TYPE_UINT64,
CSR_XR(csr_base, TLU_OTHER_EVENT_LOG_ENABLE),
FIRE_TLU_OEIE, DATA_TYPE_UINT64,
CSR_XR(csr_base, TLU_OTHER_EVENT_INTERRUPT_ENABLE),
FIRE_TLU_OEIS, DATA_TYPE_UINT64,
ss_reg,
FIRE_TLU_OEESS, DATA_TYPE_UINT64,
CSR_XR(csr_base, TLU_OTHER_EVENT_STATUS_SET),
NULL);
return (PX_NO_PANIC);
}