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