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