xref: /onnv-gate/usr/src/uts/sun4u/io/px/px_err.c (revision 2276:11778235cccd)
127Sjchu /*
227Sjchu  * CDDL HEADER START
327Sjchu  *
427Sjchu  * The contents of this file are subject to the terms of the
51648Sjchu  * Common Development and Distribution License (the "License").
61648Sjchu  * 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 /*
221648Sjchu  * 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>
431772Sjl139090 #include <sys/machcpuvar.h>
441772Sjl139090 #include <sys/platform_module.h>
45118Sjchu #include "pcie_pwr.h"
4627Sjchu #include "px_lib4u.h"
4727Sjchu #include "px_err.h"
4827Sjchu #include "px_err_impl.h"
491772Sjl139090 #include "oberon_regs.h"
501772Sjl139090 
511772Sjl139090 uint64_t px_tlu_ue_intr_mask	= PX_ERR_EN_ALL;
521772Sjl139090 uint64_t px_tlu_ue_log_mask	= PX_ERR_EN_ALL;
531772Sjl139090 uint64_t px_tlu_ue_count_mask	= PX_ERR_EN_ALL;
541772Sjl139090 
551772Sjl139090 uint64_t px_tlu_ce_intr_mask	= PX_ERR_MASK_NONE;
561772Sjl139090 uint64_t px_tlu_ce_log_mask	= PX_ERR_MASK_NONE;
571772Sjl139090 uint64_t px_tlu_ce_count_mask	= PX_ERR_MASK_NONE;
581772Sjl139090 
591772Sjl139090 /*
601772Sjl139090  * Do not enable Link Interrupts
611772Sjl139090  */
621772Sjl139090 uint64_t px_tlu_oe_intr_mask	= PX_ERR_EN_ALL & ~0x80000000800;
631772Sjl139090 uint64_t px_tlu_oe_log_mask	= PX_ERR_EN_ALL & ~0x80000000800;
641772Sjl139090 uint64_t px_tlu_oe_count_mask	= PX_ERR_EN_ALL;
651772Sjl139090 
661772Sjl139090 uint64_t px_mmu_intr_mask	= PX_ERR_EN_ALL;
671772Sjl139090 uint64_t px_mmu_log_mask	= PX_ERR_EN_ALL;
681772Sjl139090 uint64_t px_mmu_count_mask	= PX_ERR_EN_ALL;
691772Sjl139090 
701772Sjl139090 uint64_t px_imu_intr_mask	= PX_ERR_EN_ALL;
711772Sjl139090 uint64_t px_imu_log_mask	= PX_ERR_EN_ALL;
721772Sjl139090 uint64_t px_imu_count_mask	= PX_ERR_EN_ALL;
731772Sjl139090 
741772Sjl139090 /*
751772Sjl139090  * (1ull << ILU_INTERRUPT_ENABLE_IHB_PE_S) |
761772Sjl139090  * (1ull << ILU_INTERRUPT_ENABLE_IHB_PE_P);
771772Sjl139090  */
781772Sjl139090 uint64_t px_ilu_intr_mask	= (((uint64_t)0x10 << 32) | 0x10);
791772Sjl139090 uint64_t px_ilu_log_mask	= (((uint64_t)0x10 << 32) | 0x10);
801772Sjl139090 uint64_t px_ilu_count_mask	= PX_ERR_EN_ALL;
811772Sjl139090 
821772Sjl139090 uint64_t px_ubc_intr_mask	= PX_ERR_EN_ALL;
831772Sjl139090 uint64_t px_ubc_log_mask		= PX_ERR_EN_ALL;
841772Sjl139090 uint64_t px_ubc_count_mask	= PX_ERR_EN_ALL;
851772Sjl139090 
861772Sjl139090 uint64_t px_jbc_intr_mask	= PX_ERR_EN_ALL;
871772Sjl139090 uint64_t px_jbc_log_mask		= PX_ERR_EN_ALL;
881772Sjl139090 uint64_t px_jbc_count_mask	= PX_ERR_EN_ALL;
891772Sjl139090 
901772Sjl139090 /*
911772Sjl139090  * LPU Intr Registers are reverse encoding from the registers above.
921772Sjl139090  * 1 = disable
931772Sjl139090  * 0 = enable
941772Sjl139090  *
951772Sjl139090  * Log and Count are however still the same.
961772Sjl139090  */
971772Sjl139090 uint64_t px_lpul_intr_mask	= LPU_INTR_DISABLE;
981772Sjl139090 uint64_t px_lpul_log_mask	= PX_ERR_EN_ALL;
991772Sjl139090 uint64_t px_lpul_count_mask	= PX_ERR_EN_ALL;
1001772Sjl139090 
1011772Sjl139090 uint64_t px_lpup_intr_mask	= LPU_INTR_DISABLE;
1021772Sjl139090 uint64_t px_lpup_log_mask	= PX_ERR_EN_ALL;
1031772Sjl139090 uint64_t px_lpup_count_mask	= PX_ERR_EN_ALL;
1041772Sjl139090 
1051772Sjl139090 uint64_t px_lpur_intr_mask	= LPU_INTR_DISABLE;
1061772Sjl139090 uint64_t px_lpur_log_mask	= PX_ERR_EN_ALL;
1071772Sjl139090 uint64_t px_lpur_count_mask	= PX_ERR_EN_ALL;
1081772Sjl139090 
1091772Sjl139090 uint64_t px_lpux_intr_mask	= LPU_INTR_DISABLE;
1101772Sjl139090 uint64_t px_lpux_log_mask	= PX_ERR_EN_ALL;
1111772Sjl139090 uint64_t px_lpux_count_mask	= PX_ERR_EN_ALL;
1121772Sjl139090 
1131772Sjl139090 uint64_t px_lpus_intr_mask	= LPU_INTR_DISABLE;
1141772Sjl139090 uint64_t px_lpus_log_mask	= PX_ERR_EN_ALL;
1151772Sjl139090 uint64_t px_lpus_count_mask	= PX_ERR_EN_ALL;
1161772Sjl139090 
1171772Sjl139090 uint64_t px_lpug_intr_mask	= LPU_INTR_DISABLE;
1181772Sjl139090 uint64_t px_lpug_log_mask	= PX_ERR_EN_ALL;
1191772Sjl139090 uint64_t px_lpug_count_mask	= PX_ERR_EN_ALL;
12027Sjchu 
12127Sjchu /*
12227Sjchu  * JBC error bit table
12327Sjchu  */
12427Sjchu #define	JBC_BIT_DESC(bit, hdl, erpt) \
12527Sjchu 	JBC_INTERRUPT_STATUS_ ## bit ## _P, \
12627Sjchu 	0, \
12727Sjchu 	PX_ERR_BIT_HANDLE(hdl), \
12827Sjchu 	PX_ERPT_SEND(erpt), \
129739Sjchu 	PX_ERR_JBC_CLASS(bit) }, \
130739Sjchu 	{ JBC_INTERRUPT_STATUS_ ## bit ## _S, \
131739Sjchu 	0, \
132739Sjchu 	PX_ERR_BIT_HANDLE(hdl), \
133739Sjchu 	PX_ERPT_SEND(erpt), \
13427Sjchu 	PX_ERR_JBC_CLASS(bit)
1351772Sjl139090 px_err_bit_desc_t px_err_jbc_tbl[] = {
13627Sjchu 	/* JBC FATAL - see io erpt doc, section 1.1 */
13727Sjchu 	{ JBC_BIT_DESC(MB_PEA,	fatal_hw,	jbc_fatal) },
13827Sjchu 	{ JBC_BIT_DESC(CPE,	fatal_hw,	jbc_fatal) },
13927Sjchu 	{ JBC_BIT_DESC(APE,	fatal_hw,	jbc_fatal) },
14027Sjchu 	{ JBC_BIT_DESC(PIO_CPE,	fatal_hw,	jbc_fatal) },
14127Sjchu 	{ JBC_BIT_DESC(JTCEEW,	fatal_hw,	jbc_fatal) },
14227Sjchu 	{ JBC_BIT_DESC(JTCEEI,	fatal_hw,	jbc_fatal) },
14327Sjchu 	{ JBC_BIT_DESC(JTCEER,	fatal_hw,	jbc_fatal) },
14427Sjchu 
14527Sjchu 	/* JBC MERGE - see io erpt doc, section 1.2 */
14627Sjchu 	{ JBC_BIT_DESC(MB_PER,	jbc_merge,	jbc_merge) },
14727Sjchu 	{ JBC_BIT_DESC(MB_PEW,	jbc_merge,	jbc_merge) },
14827Sjchu 
14927Sjchu 	/* JBC Jbusint IN - see io erpt doc, section 1.3 */
15027Sjchu 	{ JBC_BIT_DESC(UE_ASYN,	fatal_gos,	jbc_in) },
1511648Sjchu 	{ JBC_BIT_DESC(CE_ASYN,	non_fatal,	jbc_in) },
15227Sjchu 	{ JBC_BIT_DESC(JTE,	fatal_gos,	jbc_in) },
15327Sjchu 	{ JBC_BIT_DESC(JBE,	jbc_jbusint_in,	jbc_in) },
15427Sjchu 	{ JBC_BIT_DESC(JUE,	jbc_jbusint_in,	jbc_in) },
15527Sjchu 	{ JBC_BIT_DESC(ICISE,	fatal_gos,	jbc_in) },
15627Sjchu 	{ JBC_BIT_DESC(WR_DPE,	jbc_jbusint_in,	jbc_in) },
15727Sjchu 	{ JBC_BIT_DESC(RD_DPE,	jbc_jbusint_in,	jbc_in) },
15827Sjchu 	{ JBC_BIT_DESC(ILL_BMW,	jbc_jbusint_in,	jbc_in) },
15927Sjchu 	{ JBC_BIT_DESC(ILL_BMR,	jbc_jbusint_in,	jbc_in) },
16027Sjchu 	{ JBC_BIT_DESC(BJC,	jbc_jbusint_in,	jbc_in) },
16127Sjchu 
16227Sjchu 	/* JBC Jbusint Out - see io erpt doc, section 1.4 */
16327Sjchu 	{ JBC_BIT_DESC(IJP,	fatal_gos,	jbc_out) },
16427Sjchu 
165*2276Sschwartz 	/*
166*2276Sschwartz 	 * JBC Dmcint ODCD - see io erpt doc, section 1.5
167*2276Sschwartz 	 *
168*2276Sschwartz 	 * Error bits which can be set via a bad PCItool access go through
169*2276Sschwartz 	 * jbc_safe_acc instead.
170*2276Sschwartz 	 */
171*2276Sschwartz 	{ JBC_BIT_DESC(PIO_UNMAP_RD,	jbc_safe_acc,		jbc_odcd) },
172*2276Sschwartz 	{ JBC_BIT_DESC(ILL_ACC_RD,	jbc_safe_acc,		jbc_odcd) },
173*2276Sschwartz 	{ JBC_BIT_DESC(PIO_UNMAP,	jbc_safe_acc,		jbc_odcd) },
17427Sjchu 	{ JBC_BIT_DESC(PIO_DPE,		jbc_dmcint_odcd,	jbc_odcd) },
17527Sjchu 	{ JBC_BIT_DESC(PIO_CPE,		non_fatal,		jbc_odcd) },
176*2276Sschwartz 	{ JBC_BIT_DESC(ILL_ACC,		jbc_safe_acc,		jbc_odcd) },
17727Sjchu 
17827Sjchu 	/* JBC Dmcint IDC - see io erpt doc, section 1.6 */
17927Sjchu 	{ JBC_BIT_DESC(UNSOL_RD,	non_fatal,	jbc_idc) },
18027Sjchu 	{ JBC_BIT_DESC(UNSOL_INTR,	non_fatal,	jbc_idc) },
18127Sjchu 
18227Sjchu 	/* JBC CSR - see io erpt doc, section 1.7 */
18327Sjchu 	{ JBC_BIT_DESC(EBUS_TO,	jbc_csr,	jbc_csr) }
18427Sjchu };
18527Sjchu 
1861772Sjl139090 #define	px_err_jbc_keys \
1871772Sjl139090 	(sizeof (px_err_jbc_tbl)) / (sizeof (px_err_bit_desc_t))
1881772Sjl139090 
1891772Sjl139090 /*
1901772Sjl139090  * UBC error bit table
1911772Sjl139090  */
1921772Sjl139090 #define	UBC_BIT_DESC(bit, hdl, erpt) \
1931772Sjl139090 	UBC_INTERRUPT_STATUS_ ## bit ## _P, \
1941772Sjl139090 	0, \
1951772Sjl139090 	PX_ERR_BIT_HANDLE(hdl), \
1961772Sjl139090 	PX_ERPT_SEND(erpt), \
1971772Sjl139090 	PX_ERR_UBC_CLASS(bit) }, \
1981772Sjl139090 	{ UBC_INTERRUPT_STATUS_ ## bit ## _S, \
1991772Sjl139090 	0, \
2001772Sjl139090 	PX_ERR_BIT_HANDLE(hdl), \
2011772Sjl139090 	PX_ERPT_SEND(erpt), \
2021772Sjl139090 	PX_ERR_UBC_CLASS(bit)
2031772Sjl139090 px_err_bit_desc_t px_err_ubc_tbl[] = {
2041772Sjl139090 	/* UBC FATAL  */
2051772Sjl139090 	{ UBC_BIT_DESC(DMARDUEA,	non_fatal,	ubc_fatal) },
2061772Sjl139090 	{ UBC_BIT_DESC(DMAWTUEA,	fatal_sw,	ubc_fatal) },
2071772Sjl139090 	{ UBC_BIT_DESC(MEMRDAXA,	fatal_sw,	ubc_fatal) },
2081772Sjl139090 	{ UBC_BIT_DESC(MEMWTAXA,	fatal_sw,	ubc_fatal) },
2091772Sjl139090 	{ UBC_BIT_DESC(DMARDUEB,	non_fatal,	ubc_fatal) },
2101772Sjl139090 	{ UBC_BIT_DESC(DMAWTUEB,	fatal_sw,	ubc_fatal) },
2111772Sjl139090 	{ UBC_BIT_DESC(MEMRDAXB,	fatal_sw,	ubc_fatal) },
2121772Sjl139090 	{ UBC_BIT_DESC(MEMWTAXB,	fatal_sw,	ubc_fatal) },
2131772Sjl139090 	{ UBC_BIT_DESC(PIOWTUE,		fatal_sw,	ubc_fatal) },
2141772Sjl139090 	{ UBC_BIT_DESC(PIOWBEUE,	fatal_sw,	ubc_fatal) },
2151772Sjl139090 	{ UBC_BIT_DESC(PIORBEUE,	fatal_sw,	ubc_fatal) }
2161772Sjl139090 };
2171772Sjl139090 
2181772Sjl139090 #define	px_err_ubc_keys \
2191772Sjl139090 	(sizeof (px_err_ubc_tbl)) / (sizeof (px_err_bit_desc_t))
2201772Sjl139090 
2211772Sjl139090 
2221772Sjl139090 char *ubc_class_eid_qualifier[] = {
2231772Sjl139090 	"-mem",
2241772Sjl139090 	"-channel",
2251772Sjl139090 	"-cpu",
2261772Sjl139090 	"-path"
2271772Sjl139090 };
2281772Sjl139090 
22927Sjchu 
23027Sjchu /*
23127Sjchu  * DMC error bit tables
23227Sjchu  */
23327Sjchu #define	IMU_BIT_DESC(bit, hdl, erpt) \
23427Sjchu 	IMU_INTERRUPT_STATUS_ ## bit ## _P, \
23527Sjchu 	0, \
23627Sjchu 	PX_ERR_BIT_HANDLE(hdl), \
23727Sjchu 	PX_ERPT_SEND(erpt), \
238739Sjchu 	PX_ERR_DMC_CLASS(bit) }, \
239739Sjchu 	{ IMU_INTERRUPT_STATUS_ ## bit ## _S, \
240739Sjchu 	0, \
241739Sjchu 	PX_ERR_BIT_HANDLE(hdl), \
242739Sjchu 	PX_ERPT_SEND(erpt), \
24327Sjchu 	PX_ERR_DMC_CLASS(bit)
24427Sjchu px_err_bit_desc_t px_err_imu_tbl[] = {
24527Sjchu 	/* DMC IMU RDS - see io erpt doc, section 2.1 */
24627Sjchu 	{ IMU_BIT_DESC(MSI_MAL_ERR,		non_fatal,	imu_rds) },
24727Sjchu 	{ IMU_BIT_DESC(MSI_PAR_ERR,		fatal_stuck,	imu_rds) },
24827Sjchu 	{ IMU_BIT_DESC(PMEACK_MES_NOT_EN,	imu_rbne,	imu_rds) },
249118Sjchu 	{ IMU_BIT_DESC(PMPME_MES_NOT_EN,	imu_pme,	imu_rds) },
25027Sjchu 	{ IMU_BIT_DESC(FATAL_MES_NOT_EN,	imu_rbne,	imu_rds) },
25127Sjchu 	{ IMU_BIT_DESC(NONFATAL_MES_NOT_EN,	imu_rbne,	imu_rds) },
25227Sjchu 	{ IMU_BIT_DESC(COR_MES_NOT_EN,		imu_rbne,	imu_rds) },
25327Sjchu 	{ IMU_BIT_DESC(MSI_NOT_EN,		imu_rbne,	imu_rds) },
25427Sjchu 
25527Sjchu 	/* DMC IMU SCS - see io erpt doc, section 2.2 */
25627Sjchu 	{ IMU_BIT_DESC(EQ_NOT_EN,		imu_rbne,	imu_rds) },
25727Sjchu 
25827Sjchu 	/* DMC IMU - see io erpt doc, section 2.3 */
25927Sjchu 	{ IMU_BIT_DESC(EQ_OVER,			imu_eq_ovfl,	imu) }
26027Sjchu };
26127Sjchu 
26227Sjchu #define	px_err_imu_keys (sizeof (px_err_imu_tbl)) / (sizeof (px_err_bit_desc_t))
26327Sjchu 
26427Sjchu /* mmu errors */
26527Sjchu #define	MMU_BIT_DESC(bit, hdl, erpt) \
26627Sjchu 	MMU_INTERRUPT_STATUS_ ## bit ## _P, \
26727Sjchu 	0, \
26827Sjchu 	PX_ERR_BIT_HANDLE(hdl), \
26927Sjchu 	PX_ERPT_SEND(erpt), \
270739Sjchu 	PX_ERR_DMC_CLASS(bit) }, \
271739Sjchu 	{ MMU_INTERRUPT_STATUS_ ## bit ## _S, \
272739Sjchu 	0, \
273739Sjchu 	PX_ERR_BIT_HANDLE(hdl), \
274739Sjchu 	PX_ERPT_SEND(erpt), \
27527Sjchu 	PX_ERR_DMC_CLASS(bit)
27627Sjchu px_err_bit_desc_t px_err_mmu_tbl[] = {
27727Sjchu 	/* DMC MMU TFAR/TFSR - see io erpt doc, section 2.4 */
27827Sjchu 	{ MMU_BIT_DESC(BYP_ERR,		mmu_rbne,	mmu_tfar_tfsr) },
27927Sjchu 	{ MMU_BIT_DESC(BYP_OOR,		mmu_tfa,	mmu_tfar_tfsr) },
28027Sjchu 	{ MMU_BIT_DESC(TRN_ERR,		mmu_rbne,	mmu_tfar_tfsr) },
28127Sjchu 	{ MMU_BIT_DESC(TRN_OOR,		mmu_tfa,	mmu_tfar_tfsr) },
28227Sjchu 	{ MMU_BIT_DESC(TTE_INV,		mmu_tfa,	mmu_tfar_tfsr) },
28327Sjchu 	{ MMU_BIT_DESC(TTE_PRT,		mmu_tfa,	mmu_tfar_tfsr) },
28427Sjchu 	{ MMU_BIT_DESC(TTC_DPE,		mmu_tfa,	mmu_tfar_tfsr) },
28527Sjchu 	{ MMU_BIT_DESC(TBW_DME,		mmu_tblwlk,	mmu_tfar_tfsr) },
28627Sjchu 	{ MMU_BIT_DESC(TBW_UDE,		mmu_tblwlk,	mmu_tfar_tfsr) },
28727Sjchu 	{ MMU_BIT_DESC(TBW_ERR,		mmu_tblwlk,	mmu_tfar_tfsr) },
28827Sjchu 	{ MMU_BIT_DESC(TBW_DPE,		mmu_tblwlk,	mmu_tfar_tfsr) },
28927Sjchu 
29027Sjchu 	/* DMC MMU - see io erpt doc, section 2.5 */
29127Sjchu 	{ MMU_BIT_DESC(TTC_CAE,		non_fatal,	mmu) }
29227Sjchu };
29327Sjchu #define	px_err_mmu_keys (sizeof (px_err_mmu_tbl)) / (sizeof (px_err_bit_desc_t))
29427Sjchu 
2951772Sjl139090 
29627Sjchu /*
29727Sjchu  * PEC error bit tables
29827Sjchu  */
29927Sjchu #define	ILU_BIT_DESC(bit, hdl, erpt) \
30027Sjchu 	ILU_INTERRUPT_STATUS_ ## bit ## _P, \
30127Sjchu 	0, \
30227Sjchu 	PX_ERR_BIT_HANDLE(hdl), \
30327Sjchu 	PX_ERPT_SEND(erpt), \
304739Sjchu 	PX_ERR_PEC_CLASS(bit) }, \
305739Sjchu 	{ ILU_INTERRUPT_STATUS_ ## bit ## _S, \
306739Sjchu 	0, \
307739Sjchu 	PX_ERR_BIT_HANDLE(hdl), \
308739Sjchu 	PX_ERPT_SEND(erpt), \
30927Sjchu 	PX_ERR_PEC_CLASS(bit)
31027Sjchu px_err_bit_desc_t px_err_ilu_tbl[] = {
31127Sjchu 	/* PEC ILU none - see io erpt doc, section 3.1 */
31227Sjchu 	{ ILU_BIT_DESC(IHB_PE,		fatal_gos,	pec_ilu) }
31327Sjchu };
31427Sjchu #define	px_err_ilu_keys \
31527Sjchu 	(sizeof (px_err_ilu_tbl)) / (sizeof (px_err_bit_desc_t))
31627Sjchu 
31727Sjchu /*
31827Sjchu  * PEC UE errors implementation is incomplete pending PCIE generic
319383Set142600  * fabric rules.  Must handle both PRIMARY and SECONDARY errors.
32027Sjchu  */
32127Sjchu /* pec ue errors */
32227Sjchu #define	TLU_UC_BIT_DESC(bit, hdl, erpt) \
32327Sjchu 	TLU_UNCORRECTABLE_ERROR_STATUS_CLEAR_ ## bit ## _P, \
32427Sjchu 	0, \
325383Set142600 	PX_ERR_BIT_HANDLE(hdl), \
326383Set142600 	PX_ERPT_SEND(erpt), \
327383Set142600 	PX_ERR_PEC_CLASS(bit) }, \
328383Set142600 	{ TLU_UNCORRECTABLE_ERROR_STATUS_CLEAR_ ## bit ## _S, \
329383Set142600 	0, \
330383Set142600 	PX_ERR_BIT_HANDLE(hdl), \
331383Set142600 	PX_ERPT_SEND(erpt), \
332383Set142600 	PX_ERR_PEC_CLASS(bit)
3331772Sjl139090 #define	TLU_UC_OB_BIT_DESC(bit, hdl, erpt) \
3341772Sjl139090 	TLU_UNCORRECTABLE_ERROR_STATUS_CLEAR_ ## bit ## _P, \
3351772Sjl139090 	0, \
3361772Sjl139090 	PX_ERR_BIT_HANDLE(hdl), \
3371772Sjl139090 	PX_ERPT_SEND(erpt), \
3381772Sjl139090 	PX_ERR_PEC_OB_CLASS(bit) }, \
3391772Sjl139090 	{ TLU_UNCORRECTABLE_ERROR_STATUS_CLEAR_ ## bit ## _S, \
3401772Sjl139090 	0, \
3411772Sjl139090 	PX_ERR_BIT_HANDLE(hdl), \
3421772Sjl139090 	PX_ERPT_SEND(erpt), \
3431772Sjl139090 	PX_ERR_PEC_CLASS(bit)
34427Sjchu px_err_bit_desc_t px_err_tlu_ue_tbl[] = {
34527Sjchu 	/* PCI-E Receive Uncorrectable Errors - see io erpt doc, section 3.2 */
346383Set142600 	{ TLU_UC_BIT_DESC(UR,		pciex_ue,	pciex_rx_ue) },
347383Set142600 	{ TLU_UC_BIT_DESC(UC,		pciex_ue,	pciex_rx_ue) },
34827Sjchu 
34927Sjchu 	/* PCI-E Transmit Uncorrectable Errors - see io erpt doc, section 3.3 */
3501772Sjl139090 	{ TLU_UC_OB_BIT_DESC(ECRC,	pciex_ue,	pciex_rx_ue) },
351383Set142600 	{ TLU_UC_BIT_DESC(CTO,		pciex_ue,	pciex_tx_ue) },
352383Set142600 	{ TLU_UC_BIT_DESC(ROF,		pciex_ue,	pciex_tx_ue) },
35327Sjchu 
35427Sjchu 	/* PCI-E Rx/Tx Uncorrectable Errors - see io erpt doc, section 3.4 */
355383Set142600 	{ TLU_UC_BIT_DESC(MFP,		pciex_ue,	pciex_rx_tx_ue) },
356383Set142600 	{ TLU_UC_BIT_DESC(PP,		pciex_ue,	pciex_rx_tx_ue) },
35727Sjchu 
35827Sjchu 	/* Other PCI-E Uncorrectable Errors - see io erpt doc, section 3.5 */
359383Set142600 	{ TLU_UC_BIT_DESC(FCP,		pciex_ue,	pciex_ue) },
360383Set142600 	{ TLU_UC_BIT_DESC(DLP,		pciex_ue,	pciex_ue) },
361383Set142600 	{ TLU_UC_BIT_DESC(TE,		pciex_ue,	pciex_ue) },
362383Set142600 
363383Set142600 	/* Not used */
364383Set142600 	{ TLU_UC_BIT_DESC(CA,		pciex_ue,	do_not) }
36527Sjchu };
36627Sjchu #define	px_err_tlu_ue_keys \
36727Sjchu 	(sizeof (px_err_tlu_ue_tbl)) / (sizeof (px_err_bit_desc_t))
36827Sjchu 
3691772Sjl139090 
37027Sjchu /*
37127Sjchu  * PEC CE errors implementation is incomplete pending PCIE generic
37227Sjchu  * fabric rules.
37327Sjchu  */
37427Sjchu /* pec ce errors */
37527Sjchu #define	TLU_CE_BIT_DESC(bit, hdl, erpt) \
37627Sjchu 	TLU_CORRECTABLE_ERROR_STATUS_CLEAR_ ## bit ## _P, \
37727Sjchu 	0, \
378383Set142600 	PX_ERR_BIT_HANDLE(hdl), \
379383Set142600 	PX_ERPT_SEND(erpt), \
380383Set142600 	PX_ERR_PEC_CLASS(bit) }, \
381383Set142600 	{ TLU_CORRECTABLE_ERROR_STATUS_CLEAR_ ## bit ## _S, \
382383Set142600 	0, \
383383Set142600 	PX_ERR_BIT_HANDLE(hdl), \
384383Set142600 	PX_ERPT_SEND(erpt), \
385383Set142600 	PX_ERR_PEC_CLASS(bit)
38627Sjchu px_err_bit_desc_t px_err_tlu_ce_tbl[] = {
38727Sjchu 	/* PCI-E Correctable Errors - see io erpt doc, section 3.6 */
388383Set142600 	{ TLU_CE_BIT_DESC(RTO,		pciex_ce,	pciex_ce) },
389383Set142600 	{ TLU_CE_BIT_DESC(RNR,		pciex_ce,	pciex_ce) },
390383Set142600 	{ TLU_CE_BIT_DESC(BDP,		pciex_ce,	pciex_ce) },
391383Set142600 	{ TLU_CE_BIT_DESC(BTP,		pciex_ce,	pciex_ce) },
392383Set142600 	{ TLU_CE_BIT_DESC(RE,		pciex_ce,	pciex_ce) }
39327Sjchu };
39427Sjchu #define	px_err_tlu_ce_keys \
39527Sjchu 	(sizeof (px_err_tlu_ce_tbl)) / (sizeof (px_err_bit_desc_t))
39627Sjchu 
3971772Sjl139090 
39827Sjchu /* pec oe errors */
39927Sjchu #define	TLU_OE_BIT_DESC(bit, hdl, erpt) \
40027Sjchu 	TLU_OTHER_EVENT_STATUS_CLEAR_ ## bit ## _P, \
40127Sjchu 	0, \
40227Sjchu 	PX_ERR_BIT_HANDLE(hdl), \
40327Sjchu 	PX_ERPT_SEND(erpt), \
404739Sjchu 	PX_ERR_PEC_CLASS(bit) }, \
405739Sjchu 	{ TLU_OTHER_EVENT_STATUS_CLEAR_ ## bit ## _S, \
406739Sjchu 	0, \
407739Sjchu 	PX_ERR_BIT_HANDLE(hdl), \
408739Sjchu 	PX_ERPT_SEND(erpt), \
40927Sjchu 	PX_ERR_PEC_CLASS(bit)
4101772Sjl139090 #define	TLU_OE_OB_BIT_DESC(bit, hdl, erpt) \
4111772Sjl139090 	TLU_OTHER_EVENT_STATUS_CLEAR_ ## bit ## _P, \
4121772Sjl139090 	0, \
4131772Sjl139090 	PX_ERR_BIT_HANDLE(hdl), \
4141772Sjl139090 	PX_ERPT_SEND(erpt), \
4151772Sjl139090 	PX_ERR_PEC_OB_CLASS(bit) }, \
4161772Sjl139090 	{ TLU_OTHER_EVENT_STATUS_CLEAR_ ## bit ## _S, \
4171772Sjl139090 	0, \
4181772Sjl139090 	PX_ERR_BIT_HANDLE(hdl), \
4191772Sjl139090 	PX_ERPT_SEND(erpt), \
4201772Sjl139090 	PX_ERR_PEC_OB_CLASS(bit)
42127Sjchu px_err_bit_desc_t px_err_tlu_oe_tbl[] = {
42227Sjchu 	/*
42327Sjchu 	 * TLU Other Event Status (receive only) - see io erpt doc, section 3.7
42427Sjchu 	 */
42527Sjchu 	{ TLU_OE_BIT_DESC(MRC,		fatal_hw,	pciex_rx_oe) },
42627Sjchu 
42727Sjchu 	/* TLU Other Event Status (rx + tx) - see io erpt doc, section 3.8 */
428383Set142600 	{ TLU_OE_BIT_DESC(WUC,		non_fatal,	pciex_rx_tx_oe) },
429383Set142600 	{ TLU_OE_BIT_DESC(RUC,		non_fatal,	pciex_rx_tx_oe) },
43027Sjchu 	{ TLU_OE_BIT_DESC(CRS,		non_fatal,	pciex_rx_tx_oe) },
43127Sjchu 
43227Sjchu 	/* TLU Other Event - see io erpt doc, section 3.9 */
43327Sjchu 	{ TLU_OE_BIT_DESC(IIP,		fatal_gos,	pciex_oe) },
43427Sjchu 	{ TLU_OE_BIT_DESC(EDP,		fatal_gos,	pciex_oe) },
43527Sjchu 	{ TLU_OE_BIT_DESC(EHP,		fatal_gos,	pciex_oe) },
4361772Sjl139090 	{ TLU_OE_OB_BIT_DESC(TLUEITMO,	fatal_gos,	pciex_oe) },
43727Sjchu 	{ TLU_OE_BIT_DESC(LIN,		non_fatal,	pciex_oe) },
43827Sjchu 	{ TLU_OE_BIT_DESC(LRS,		non_fatal,	pciex_oe) },
4391147Sjchu 	{ TLU_OE_BIT_DESC(LDN,		tlu_ldn,	pciex_oe) },
4401147Sjchu 	{ TLU_OE_BIT_DESC(LUP,		tlu_lup,	pciex_oe) },
44127Sjchu 	{ TLU_OE_BIT_DESC(ERU,		fatal_gos,	pciex_oe) },
44227Sjchu 	{ TLU_OE_BIT_DESC(ERO,		fatal_gos,	pciex_oe) },
44327Sjchu 	{ TLU_OE_BIT_DESC(EMP,		fatal_gos,	pciex_oe) },
44427Sjchu 	{ TLU_OE_BIT_DESC(EPE,		fatal_gos,	pciex_oe) },
44527Sjchu 	{ TLU_OE_BIT_DESC(ERP,		fatal_gos,	pciex_oe) },
44627Sjchu 	{ TLU_OE_BIT_DESC(EIP,		fatal_gos,	pciex_oe) }
44727Sjchu };
44827Sjchu 
44927Sjchu #define	px_err_tlu_oe_keys \
45027Sjchu 	(sizeof (px_err_tlu_oe_tbl)) / (sizeof (px_err_bit_desc_t))
45127Sjchu 
4521772Sjl139090 
45327Sjchu /*
45427Sjchu  * All the following tables below are for LPU Interrupts.  These interrupts
45527Sjchu  * are *NOT* error interrupts, but event status interrupts.
45627Sjchu  *
45727Sjchu  * These events are probably of most interest to:
45827Sjchu  * o Hotplug
45927Sjchu  * o Power Management
46027Sjchu  * o etc...
46127Sjchu  *
46227Sjchu  * There are also a few events that would be interresting for FMA.
46327Sjchu  * Again none of the regiseters below state that an error has occured
46427Sjchu  * or that data has been lost.  If anything, they give status that an
46527Sjchu  * error is *about* to occur.  examples
46627Sjchu  * o INT_SKP_ERR - indicates clock between fire and child is too far
46727Sjchu  *		   off and is most unlikely able to compensate
46827Sjchu  * o INT_TX_PAR_ERR - A parity error occured in ONE lane.  This is
46927Sjchu  *		      HW recoverable, but will like end up as a future
47027Sjchu  *		      fabric error as well.
47127Sjchu  *
47227Sjchu  * For now, we don't care about any of these errors and should be ignore,
47327Sjchu  * but cleared.
47427Sjchu  */
47527Sjchu 
47627Sjchu /* LPU Link Interrupt Table */
47727Sjchu #define	LPUL_BIT_DESC(bit, hdl, erpt) \
47827Sjchu 	LPU_LINK_LAYER_INTERRUPT_AND_STATUS_INT_ ## bit, \
47927Sjchu 	0, \
48027Sjchu 	NULL, \
48127Sjchu 	NULL, \
48227Sjchu 	""
48327Sjchu px_err_bit_desc_t px_err_lpul_tbl[] = {
48427Sjchu 	{ LPUL_BIT_DESC(LINK_ERR_ACT,	NULL,		NULL) }
48527Sjchu };
48627Sjchu #define	px_err_lpul_keys \
48727Sjchu 	(sizeof (px_err_lpul_tbl)) / (sizeof (px_err_bit_desc_t))
48827Sjchu 
48927Sjchu /* LPU Physical Interrupt Table */
49027Sjchu #define	LPUP_BIT_DESC(bit, hdl, erpt) \
49127Sjchu 	LPU_PHY_LAYER_INTERRUPT_AND_STATUS_INT_ ## bit, \
49227Sjchu 	0, \
49327Sjchu 	NULL, \
49427Sjchu 	NULL, \
49527Sjchu 	""
49627Sjchu px_err_bit_desc_t px_err_lpup_tbl[] = {
49727Sjchu 	{ LPUP_BIT_DESC(PHY_LAYER_ERR,	NULL,		NULL) }
49827Sjchu };
49927Sjchu #define	px_err_lpup_keys \
50027Sjchu 	(sizeof (px_err_lpup_tbl)) / (sizeof (px_err_bit_desc_t))
50127Sjchu 
50227Sjchu /* LPU Receive Interrupt Table */
50327Sjchu #define	LPUR_BIT_DESC(bit, hdl, erpt) \
50427Sjchu 	LPU_RECEIVE_PHY_INTERRUPT_AND_STATUS_INT_ ## bit, \
50527Sjchu 	0, \
50627Sjchu 	NULL, \
50727Sjchu 	NULL, \
50827Sjchu 	""
50927Sjchu px_err_bit_desc_t px_err_lpur_tbl[] = {
51027Sjchu 	{ LPUR_BIT_DESC(RCV_PHY,	NULL,		NULL) }
51127Sjchu };
51227Sjchu #define	px_err_lpur_keys \
51327Sjchu 	(sizeof (px_err_lpur_tbl)) / (sizeof (px_err_bit_desc_t))
51427Sjchu 
51527Sjchu /* LPU Transmit Interrupt Table */
51627Sjchu #define	LPUX_BIT_DESC(bit, hdl, erpt) \
51727Sjchu 	LPU_TRANSMIT_PHY_INTERRUPT_AND_STATUS_INT_ ## bit, \
51827Sjchu 	0, \
51927Sjchu 	NULL, \
52027Sjchu 	NULL, \
52127Sjchu 	""
52227Sjchu px_err_bit_desc_t px_err_lpux_tbl[] = {
52327Sjchu 	{ LPUX_BIT_DESC(UNMSK,		NULL,		NULL) }
52427Sjchu };
52527Sjchu #define	px_err_lpux_keys \
52627Sjchu 	(sizeof (px_err_lpux_tbl)) / (sizeof (px_err_bit_desc_t))
52727Sjchu 
52827Sjchu /* LPU LTSSM Interrupt Table */
52927Sjchu #define	LPUS_BIT_DESC(bit, hdl, erpt) \
53027Sjchu 	LPU_LTSSM_INTERRUPT_AND_STATUS_INT_ ## bit, \
53127Sjchu 	0, \
53227Sjchu 	NULL, \
53327Sjchu 	NULL, \
53427Sjchu 	""
53527Sjchu px_err_bit_desc_t px_err_lpus_tbl[] = {
53627Sjchu 	{ LPUS_BIT_DESC(ANY,		NULL,		NULL) }
53727Sjchu };
53827Sjchu #define	px_err_lpus_keys \
53927Sjchu 	(sizeof (px_err_lpus_tbl)) / (sizeof (px_err_bit_desc_t))
54027Sjchu 
54127Sjchu /* LPU Gigablaze Glue Interrupt Table */
54227Sjchu #define	LPUG_BIT_DESC(bit, hdl, erpt) \
54327Sjchu 	LPU_GIGABLAZE_GLUE_INTERRUPT_AND_STATUS_INT_ ## bit, \
54427Sjchu 	0, \
54527Sjchu 	NULL, \
54627Sjchu 	NULL, \
54727Sjchu 	""
54827Sjchu px_err_bit_desc_t px_err_lpug_tbl[] = {
54927Sjchu 	{ LPUG_BIT_DESC(GLOBL_UNMSK,	NULL,		NULL) }
55027Sjchu };
55127Sjchu #define	px_err_lpug_keys \
55227Sjchu 	(sizeof (px_err_lpug_tbl)) / (sizeof (px_err_bit_desc_t))
55327Sjchu 
55427Sjchu 
55527Sjchu /* Mask and Tables */
55627Sjchu #define	MnT6(pre) \
55727Sjchu 	B_FALSE, \
55827Sjchu 	&px_ ## pre ## _intr_mask, \
55927Sjchu 	&px_ ## pre ## _log_mask, \
56027Sjchu 	&px_ ## pre ## _count_mask, \
56127Sjchu 	px_err_ ## pre ## _tbl, \
56227Sjchu 	px_err_ ## pre ## _keys, \
56327Sjchu 	0
56427Sjchu 
5651772Sjl139090 #define	MnT6_ob(pre) \
5661772Sjl139090 	B_FALSE, \
5671772Sjl139090 	&px_ ## pre ## _intr_mask, \
5681772Sjl139090 	&px_ ## pre ## _log_mask, \
5691772Sjl139090 	&px_ ## pre ## _count_mask, \
5701772Sjl139090 	px_err_ ## pre ## _ob_tbl, \
5711772Sjl139090 	px_err_ ## pre ## _ob_keys, \
5721772Sjl139090 	0
5731772Sjl139090 
57427Sjchu /* LPU Registers Addresses */
57527Sjchu #define	LR4(pre) \
57627Sjchu 	NULL, \
57727Sjchu 	LPU_ ## pre ## _INTERRUPT_MASK, \
57827Sjchu 	LPU_ ## pre ## _INTERRUPT_AND_STATUS, \
57927Sjchu 	LPU_ ## pre ## _INTERRUPT_AND_STATUS
58027Sjchu 
58127Sjchu /* LPU Registers Addresses with Irregularities */
58227Sjchu #define	LR4_FIXME(pre) \
58327Sjchu 	NULL, \
58427Sjchu 	LPU_ ## pre ## _INTERRUPT_MASK, \
58527Sjchu 	LPU_ ## pre ## _LAYER_INTERRUPT_AND_STATUS, \
58627Sjchu 	LPU_ ## pre ## _LAYER_INTERRUPT_AND_STATUS
58727Sjchu 
58827Sjchu /* TLU Registers Addresses */
58927Sjchu #define	TR4(pre) \
59027Sjchu 	TLU_ ## pre ## _LOG_ENABLE, \
59127Sjchu 	TLU_ ## pre ## _INTERRUPT_ENABLE, \
59227Sjchu 	TLU_ ## pre ## _INTERRUPT_STATUS, \
59327Sjchu 	TLU_ ## pre ## _STATUS_CLEAR
59427Sjchu 
5951772Sjl139090 /* Registers Addresses for JBC, UBC, MMU, IMU and ILU */
59627Sjchu #define	R4(pre) \
59727Sjchu 	pre ## _ERROR_LOG_ENABLE, \
59827Sjchu 	pre ## _INTERRUPT_ENABLE, \
59927Sjchu 	pre ## _INTERRUPT_STATUS, \
60027Sjchu 	pre ## _ERROR_STATUS_CLEAR
60127Sjchu 
60227Sjchu /*
60327Sjchu  * Register error handling tables.
60427Sjchu  * The ID Field (first field) is identified by an enum px_err_id_t.
60527Sjchu  * It is located in px_err.h
60627Sjchu  */
60727Sjchu px_err_reg_desc_t px_err_reg_tbl[] = {
6081772Sjl139090 	{ MnT6(jbc),	R4(JBC),		  "JBC Error"},
6091772Sjl139090 	{ MnT6(ubc),	R4(UBC),		  "UBC Error"},
610435Sjchu 	{ MnT6(mmu),	R4(MMU),		  "MMU Error"},
611435Sjchu 	{ MnT6(imu),	R4(IMU),		  "IMU Error"},
61227Sjchu 	{ MnT6(tlu_ue),	TR4(UNCORRECTABLE_ERROR), "TLU UE"},
61327Sjchu 	{ MnT6(tlu_ce), TR4(CORRECTABLE_ERROR),	  "TLU CE"},
61427Sjchu 	{ MnT6(tlu_oe), TR4(OTHER_EVENT),	  "TLU OE"},
615435Sjchu 	{ MnT6(ilu),	R4(ILU),		  "ILU Error"},
61627Sjchu 	{ MnT6(lpul),	LR4(LINK_LAYER),	  "LPU Link Layer"},
61727Sjchu 	{ MnT6(lpup),	LR4_FIXME(PHY),		  "LPU Phy Layer"},
61827Sjchu 	{ MnT6(lpur),	LR4(RECEIVE_PHY),	  "LPU RX Phy Layer"},
61927Sjchu 	{ MnT6(lpux),	LR4(TRANSMIT_PHY),	  "LPU TX Phy Layer"},
62027Sjchu 	{ MnT6(lpus),	LR4(LTSSM),		  "LPU LTSSM"},
6211772Sjl139090 	{ MnT6(lpug),	LR4(GIGABLAZE_GLUE),	  "LPU GigaBlaze Glue"},
62227Sjchu };
62327Sjchu #define	PX_ERR_REG_KEYS (sizeof (px_err_reg_tbl)) / (sizeof (px_err_reg_tbl[0]))
62427Sjchu 
62527Sjchu typedef struct px_err_ss {
62627Sjchu 	uint64_t err_status[PX_ERR_REG_KEYS];
62727Sjchu } px_err_ss_t;
62827Sjchu 
6291772Sjl139090 static void px_err_snapshot(px_t *px_p, px_err_ss_t *ss, boolean_t chk_cb);
63027Sjchu static int  px_err_erpt_and_clr(px_t *px_p, ddi_fm_error_t *derr,
63127Sjchu     px_err_ss_t *ss);
63227Sjchu static int  px_err_check_severity(px_t *px_p, ddi_fm_error_t *derr,
63327Sjchu     int err, int caller);
63427Sjchu 
63527Sjchu /*
63627Sjchu  * px_err_cb_intr:
6371772Sjl139090  * Interrupt handler for the JBC/UBC block.
63827Sjchu  * o lock
63927Sjchu  * o create derr
6401772Sjl139090  * o px_err_handle(leaf1, with cb)
6411772Sjl139090  * o px_err_handle(leaf2, without cb)
64227Sjchu  * o dispatch (leaf1)
64327Sjchu  * o dispatch (leaf2)
64427Sjchu  * o unlock
64527Sjchu  * o handle error: fatal? fm_panic() : return INTR_CLAIMED)
64627Sjchu  */
64727Sjchu uint_t
64827Sjchu px_err_cb_intr(caddr_t arg)
64927Sjchu {
65027Sjchu 	px_fault_t	*px_fault_p = (px_fault_t *)arg;
65127Sjchu 	dev_info_t	*rpdip = px_fault_p->px_fh_dip;
65227Sjchu 	px_t		*px_p = DIP_TO_STATE(rpdip);
653118Sjchu 	int		err = PX_OK;
654118Sjchu 	int		ret = DDI_FM_OK;
65527Sjchu 	int		fatal = 0;
65627Sjchu 	ddi_fm_error_t	derr;
65727Sjchu 
65827Sjchu 	/* Create the derr */
65927Sjchu 	bzero(&derr, sizeof (ddi_fm_error_t));
66027Sjchu 	derr.fme_version = DDI_FME_VERSION;
66127Sjchu 	derr.fme_ena = fm_ena_generate(0, FM_ENA_FMT1);
66227Sjchu 	derr.fme_flag = DDI_FM_ERR_UNEXPECTED;
66327Sjchu 
6641648Sjchu 	mutex_enter(&px_p->px_fm_mutex);
66527Sjchu 
6661648Sjchu 	err |= px_err_handle(px_p, &derr, PX_INTR_CALL, B_TRUE);
66727Sjchu 
6681648Sjchu 	ret = ndi_fm_handler_dispatch(rpdip, NULL, &derr);
6691648Sjchu 	switch (ret) {
6701648Sjchu 	case DDI_FM_FATAL:
6711648Sjchu 		fatal++;
6721648Sjchu 		break;
6731648Sjchu 	case DDI_FM_NONFATAL:
6741648Sjchu 	case DDI_FM_UNKNOWN:
6751648Sjchu 	default:
6761648Sjchu 		break;
67727Sjchu 	}
67827Sjchu 
67927Sjchu 	/* Set the intr state to idle for the leaf that received the mondo */
6801648Sjchu 
68127Sjchu 	(void) px_lib_intr_setstate(rpdip, px_fault_p->px_fh_sysino,
68227Sjchu 	    INTR_IDLE_STATE);
68327Sjchu 
6841648Sjchu 	mutex_exit(&px_p->px_fm_mutex);
68527Sjchu 
68627Sjchu 	/*
68727Sjchu 	 * PX_FATAL_HW error is diagnosed after system recovered from
68827Sjchu 	 * HW initiated reset, therefore no furthur handling is required.
68927Sjchu 	 */
69027Sjchu 	if (fatal || err & (PX_FATAL_GOS | PX_FATAL_SW))
691677Sjchu 		PX_FM_PANIC("Fatal System Bus Error has occurred\n");
69227Sjchu 
69327Sjchu 	return (DDI_INTR_CLAIMED);
69427Sjchu }
69527Sjchu 
69627Sjchu /*
69727Sjchu  * px_err_dmc_pec_intr:
69827Sjchu  * Interrupt handler for the DMC/PEC block.
69927Sjchu  * o lock
70027Sjchu  * o create derr
7011772Sjl139090  * o px_err_handle(leaf, with cb)
70227Sjchu  * o dispatch (leaf)
70327Sjchu  * o unlock
70427Sjchu  * o handle error: fatal? fm_panic() : return INTR_CLAIMED)
70527Sjchu  */
70627Sjchu uint_t
70727Sjchu px_err_dmc_pec_intr(caddr_t arg)
70827Sjchu {
70927Sjchu 	px_fault_t	*px_fault_p = (px_fault_t *)arg;
71027Sjchu 	dev_info_t	*rpdip = px_fault_p->px_fh_dip;
71127Sjchu 	px_t		*px_p = DIP_TO_STATE(rpdip);
712118Sjchu 	int		err = PX_OK;
713118Sjchu 	int		ret = DDI_FM_OK;
71427Sjchu 	ddi_fm_error_t	derr;
71527Sjchu 
71627Sjchu 	/* Create the derr */
71727Sjchu 	bzero(&derr, sizeof (ddi_fm_error_t));
71827Sjchu 	derr.fme_version = DDI_FME_VERSION;
71927Sjchu 	derr.fme_ena = fm_ena_generate(0, FM_ENA_FMT1);
72027Sjchu 	derr.fme_flag = DDI_FM_ERR_UNEXPECTED;
72127Sjchu 
7221648Sjchu 	mutex_enter(&px_p->px_fm_mutex);
72327Sjchu 
72427Sjchu 	/* send ereport/handle/clear fire registers */
72527Sjchu 	err |= px_err_handle(px_p, &derr, PX_INTR_CALL, B_TRUE);
72627Sjchu 
72727Sjchu 	/* Check all child devices for errors */
72827Sjchu 	ret = ndi_fm_handler_dispatch(rpdip, NULL, &derr);
72927Sjchu 
73027Sjchu 	/* Set the interrupt state to idle */
73127Sjchu 	(void) px_lib_intr_setstate(rpdip, px_fault_p->px_fh_sysino,
73227Sjchu 	    INTR_IDLE_STATE);
73327Sjchu 
7341648Sjchu 	mutex_exit(&px_p->px_fm_mutex);
73527Sjchu 
73627Sjchu 	/*
73727Sjchu 	 * PX_FATAL_HW indicates a condition recovered from Fatal-Reset,
73827Sjchu 	 * therefore it does not cause panic.
73927Sjchu 	 */
74027Sjchu 	if ((err & (PX_FATAL_GOS | PX_FATAL_SW)) || (ret == DDI_FM_FATAL))
741677Sjchu 		PX_FM_PANIC("Fatal System Port Error has occurred\n");
74227Sjchu 
74327Sjchu 	return (DDI_INTR_CLAIMED);
74427Sjchu }
74527Sjchu 
74627Sjchu /*
74727Sjchu  * Error register are being handled by px_hlib xxx_init functions.
74827Sjchu  * They are also called again by px_err_add_intr for mondo62 and 63
74927Sjchu  * from px_cb_attach and px_attach
75027Sjchu  */
75127Sjchu void
75227Sjchu px_err_reg_enable(px_t *px_p, px_err_id_t id)
75327Sjchu {
75427Sjchu 	px_err_reg_desc_t	*reg_desc = &px_err_reg_tbl[id];
75527Sjchu 	uint64_t 		intr_mask = *reg_desc->intr_mask_p;
75627Sjchu 	uint64_t 		log_mask = *reg_desc->log_mask_p;
75727Sjchu 	caddr_t			csr_base;
75827Sjchu 	pxu_t			*pxu_p = (pxu_t *)px_p->px_plat_p;
75927Sjchu 
7601772Sjl139090 	/* Get the correct CSR BASE */
7611772Sjl139090 	if (PX_ERR_XBC(id))
76227Sjchu 		csr_base = (caddr_t)pxu_p->px_address[PX_REG_XBC];
76327Sjchu 	else
76427Sjchu 		csr_base = (caddr_t)pxu_p->px_address[PX_REG_CSR];
76527Sjchu 
76627Sjchu 	reg_desc->enabled = B_TRUE;
76727Sjchu 
76827Sjchu 	/* Enable logs if it exists */
76927Sjchu 	if (reg_desc->log_addr != NULL)
77027Sjchu 		CSR_XS(csr_base, reg_desc->log_addr, log_mask);
77127Sjchu 
77227Sjchu 	/*
77327Sjchu 	 * For readability you in code you set 1 to enable an interrupt.
77427Sjchu 	 * But in Fire it's backwards.  You set 1 to *disable* an intr.
77527Sjchu 	 * Reverse the user tunable intr mask field.
77627Sjchu 	 *
77727Sjchu 	 * Disable All Errors
77827Sjchu 	 * Clear All Errors
77927Sjchu 	 * Enable Errors
78027Sjchu 	 */
78127Sjchu 	CSR_XS(csr_base, reg_desc->enable_addr, 0);
78227Sjchu 	CSR_XS(csr_base, reg_desc->clear_addr, -1);
78327Sjchu 	CSR_XS(csr_base, reg_desc->enable_addr, intr_mask);
78427Sjchu 	DBG(DBG_ATTACH, NULL, "%s Mask: 0x%llx\n",
78527Sjchu 	    reg_desc->msg, CSR_XR(csr_base, reg_desc->enable_addr));
78627Sjchu 	DBG(DBG_ATTACH, NULL, "%s Status: 0x%llx\n",
78727Sjchu 	    reg_desc->msg, CSR_XR(csr_base, reg_desc->status_addr));
78827Sjchu 	DBG(DBG_ATTACH, NULL, "%s Clear: 0x%llx\n",
78927Sjchu 	    reg_desc->msg, CSR_XR(csr_base, reg_desc->clear_addr));
79027Sjchu 	if (reg_desc->log_addr != NULL) {
79127Sjchu 		DBG(DBG_ATTACH, NULL, "%s Log: 0x%llx\n",
79227Sjchu 		    reg_desc->msg, CSR_XR(csr_base, reg_desc->log_addr));
79327Sjchu 	}
79427Sjchu }
79527Sjchu 
79627Sjchu void
79727Sjchu px_err_reg_disable(px_t *px_p, px_err_id_t id)
79827Sjchu {
79927Sjchu 	px_err_reg_desc_t	*reg_desc = &px_err_reg_tbl[id];
80027Sjchu 	caddr_t			csr_base;
801693Sgovinda 	pxu_t			*pxu_p = (pxu_t *)px_p->px_plat_p;
80227Sjchu 
8031772Sjl139090 	/* Get the correct CSR BASE */
8041772Sjl139090 	if (PX_ERR_XBC(id))
805693Sgovinda 		csr_base = (caddr_t)(uintptr_t)pxu_p->px_address[PX_REG_XBC];
80627Sjchu 	else
807693Sgovinda 		csr_base = (caddr_t)(uintptr_t)pxu_p->px_address[PX_REG_CSR];
80827Sjchu 
80927Sjchu 	reg_desc->enabled = B_FALSE;
81027Sjchu 
81127Sjchu 	switch (id) {
81227Sjchu 	case PX_ERR_JBC:
8131772Sjl139090 	case PX_ERR_UBC:
81427Sjchu 	case PX_ERR_MMU:
81527Sjchu 	case PX_ERR_IMU:
81627Sjchu 	case PX_ERR_TLU_UE:
81727Sjchu 	case PX_ERR_TLU_CE:
81827Sjchu 	case PX_ERR_TLU_OE:
81927Sjchu 	case PX_ERR_ILU:
82027Sjchu 		if (reg_desc->log_addr != NULL) {
82127Sjchu 			CSR_XS(csr_base, reg_desc->log_addr, 0);
82227Sjchu 		}
82327Sjchu 		CSR_XS(csr_base, reg_desc->enable_addr, 0);
82427Sjchu 		break;
82527Sjchu 	case PX_ERR_LPU_LINK:
82627Sjchu 	case PX_ERR_LPU_PHY:
82727Sjchu 	case PX_ERR_LPU_RX:
82827Sjchu 	case PX_ERR_LPU_TX:
82927Sjchu 	case PX_ERR_LPU_LTSSM:
83027Sjchu 	case PX_ERR_LPU_GIGABLZ:
83127Sjchu 		if (reg_desc->log_addr != NULL) {
83227Sjchu 			CSR_XS(csr_base, reg_desc->log_addr, -1);
83327Sjchu 		}
83427Sjchu 		CSR_XS(csr_base, reg_desc->enable_addr, -1);
83527Sjchu 		break;
83627Sjchu 	}
83727Sjchu }
83827Sjchu 
83927Sjchu /*
84027Sjchu  * px_err_handle:
84127Sjchu  * Common function called by trap, mondo and fabric intr.
84227Sjchu  * o Snap shot current fire registers
84327Sjchu  * o check for safe access
84427Sjchu  * o send ereport and clear snap shot registers
84527Sjchu  * o check severity of snap shot registers
84627Sjchu  *
84727Sjchu  * @param px_p		leaf in which to check access
84827Sjchu  * @param derr		fm err data structure to be updated
84927Sjchu  * @param caller	PX_TRAP_CALL | PX_INTR_CALL
8501772Sjl139090  * @param chk_cb	whether to handle cb registers
85127Sjchu  * @return err		PX_OK | PX_NONFATAL |
85227Sjchu  *                      PX_FATAL_GOS | PX_FATAL_HW | PX_STUCK_FATAL
85327Sjchu  */
85427Sjchu int
85527Sjchu px_err_handle(px_t *px_p, ddi_fm_error_t *derr, int caller,
8561772Sjl139090     boolean_t chk_cb)
85727Sjchu {
85827Sjchu 	px_err_ss_t		ss;
859118Sjchu 	int			err = PX_OK;
86027Sjchu 
8611648Sjchu 	ASSERT(MUTEX_HELD(&px_p->px_fm_mutex));
86227Sjchu 
86327Sjchu 	/* snap shot the current fire registers */
8641772Sjl139090 	px_err_snapshot(px_p, &ss, chk_cb);
86527Sjchu 
86627Sjchu 	/* check for safe access */
86727Sjchu 	px_err_safeacc_check(px_p, derr);
86827Sjchu 
86927Sjchu 	/* send ereports/handle/clear registers */
87027Sjchu 	err = px_err_erpt_and_clr(px_p, derr, &ss);
87127Sjchu 
87227Sjchu 	/* check for error severity */
87327Sjchu 	err = px_err_check_severity(px_p, derr, err, caller);
87427Sjchu 
87527Sjchu 	/* Mark the On Trap Handle if an error occured */
87627Sjchu 	if (err != PX_OK) {
87727Sjchu 		px_pec_t	*pec_p = px_p->px_pec_p;
87827Sjchu 		on_trap_data_t	*otd = pec_p->pec_ontrap_data;
87927Sjchu 
880118Sjchu 		if ((otd != NULL) && (otd->ot_prot & OT_DATA_ACCESS))
88127Sjchu 			otd->ot_trap |= OT_DATA_ACCESS;
88227Sjchu 	}
88327Sjchu 
88427Sjchu 	return (err);
88527Sjchu }
88627Sjchu 
88727Sjchu /*
88827Sjchu  * Static function
88927Sjchu  */
89027Sjchu 
89127Sjchu /*
89227Sjchu  * px_err_snapshot:
89327Sjchu  * Take a current snap shot of all the fire error registers.  This includes
8941772Sjl139090  * JBC/UBC, DMC, and PEC, unless chk_cb == false;
89527Sjchu  *
89627Sjchu  * @param px_p		leaf in which to take the snap shot.
89727Sjchu  * @param ss		pre-allocated memory to store the snap shot.
8981772Sjl139090  * @param chk_cb	boolean on whether to store jbc/ubc register.
89927Sjchu  */
90027Sjchu static void
9011772Sjl139090 px_err_snapshot(px_t *px_p, px_err_ss_t *ss, boolean_t chk_cb)
90227Sjchu {
90327Sjchu 	pxu_t	*pxu_p = (pxu_t *)px_p->px_plat_p;
90427Sjchu 	caddr_t	xbc_csr_base = (caddr_t)pxu_p->px_address[PX_REG_XBC];
90527Sjchu 	caddr_t	pec_csr_base = (caddr_t)pxu_p->px_address[PX_REG_CSR];
90627Sjchu 	px_err_reg_desc_t *reg_desc;
90727Sjchu 	int reg_id;
90827Sjchu 
9091772Sjl139090 	switch (PX_CHIP_TYPE(pxu_p)) {
9101772Sjl139090 	case PX_CHIP_OBERON:
9111772Sjl139090 		reg_id = PX_ERR_UBC;
9121772Sjl139090 		break;
9131772Sjl139090 	case PX_CHIP_FIRE:
9141772Sjl139090 		reg_id = PX_ERR_JBC;
9151772Sjl139090 		break;
9161772Sjl139090 	default:
9171772Sjl139090 		DBG(DBG_ERR_INTR, NULL, "px_err_snapshot - "
9181772Sjl139090 		    "unknown chip type: 0x%x\n", PX_CHIP_TYPE(pxu_p));
9191772Sjl139090 		reg_id = 0;
9201772Sjl139090 		break;
9211772Sjl139090 	}
9221772Sjl139090 
9231772Sjl139090 	/* snapshot CB interrupt status */
9241772Sjl139090 	if (chk_cb == B_TRUE) {
92527Sjchu 		reg_desc = &px_err_reg_tbl[reg_id];
9261772Sjl139090 		/* Only look at enabled groups. */
9271772Sjl139090 		if (reg_desc->enabled == B_TRUE)	{
9281772Sjl139090 			ss->err_status[reg_id] = CSR_XR(xbc_csr_base,
9291772Sjl139090 			    reg_desc->status_addr);
9301772Sjl139090 		}
93127Sjchu 	} else {
93227Sjchu 		ss->err_status[reg_id] = 0;
93327Sjchu 	}
93427Sjchu 
93527Sjchu 	/* snapshot DMC/PEC interrupt status */
9361772Sjl139090 	for (reg_id = 2; reg_id < PX_ERR_REG_KEYS; reg_id += 1) {
93727Sjchu 		reg_desc = &px_err_reg_tbl[reg_id];
9381772Sjl139090 		/* Only look at enabled groups. */
9391772Sjl139090 		if (reg_desc->enabled == B_TRUE)	{
9401772Sjl139090 			ss->err_status[reg_id] = CSR_XR(pec_csr_base,
9411772Sjl139090 			    reg_desc->status_addr);
9421772Sjl139090 		}
94327Sjchu 	}
94427Sjchu }
94527Sjchu 
94627Sjchu /*
94727Sjchu  * px_err_erpt_and_clr:
94827Sjchu  * This function does the following thing to all the fire registers based
94927Sjchu  * on an earlier snap shot.
95027Sjchu  * o Send ereport
95127Sjchu  * o Handle the error
95227Sjchu  * o Clear the error
95327Sjchu  *
95427Sjchu  * @param px_p		leaf in which to take the snap shot.
95527Sjchu  * @param derr		fm err in which the ereport is to be based on
95627Sjchu  * @param ss		pre-allocated memory to store the snap shot.
95727Sjchu  */
95827Sjchu static int
95927Sjchu px_err_erpt_and_clr(px_t *px_p, ddi_fm_error_t *derr, px_err_ss_t *ss)
96027Sjchu {
96127Sjchu 	dev_info_t		*rpdip = px_p->px_dip;
96227Sjchu 	pxu_t			*pxu_p = (pxu_t *)px_p->px_plat_p;
96327Sjchu 	caddr_t			csr_base;
96427Sjchu 	px_err_reg_desc_t	*err_reg_tbl;
96527Sjchu 	px_err_bit_desc_t	*err_bit_tbl;
96627Sjchu 	px_err_bit_desc_t	*err_bit_desc;
96727Sjchu 
96827Sjchu 	uint64_t		*log_mask, *count_mask;
96927Sjchu 	uint64_t		status_addr, clear_addr;
97027Sjchu 	uint64_t		ss_reg;
97127Sjchu 
97227Sjchu 	int			(*err_handler)();
97327Sjchu 	int			(*erpt_handler)();
97427Sjchu 	int			reg_id, key;
97527Sjchu 	int			err = PX_OK;
9761147Sjchu 	int			biterr;
97727Sjchu 
9781648Sjchu 	ASSERT(MUTEX_HELD(&px_p->px_fm_mutex));
97927Sjchu 
98027Sjchu 	/* send erport/handle/clear JBC errors */
98127Sjchu 	for (reg_id = 0; reg_id < PX_ERR_REG_KEYS; reg_id += 1) {
98227Sjchu 		/* Get the correct register description table */
98327Sjchu 		err_reg_tbl = &px_err_reg_tbl[reg_id];
98427Sjchu 
9851772Sjl139090 		/* Only look at enabled groups. */
9861772Sjl139090 		if (err_reg_tbl->enabled != B_TRUE)
9871772Sjl139090 			continue;
9881772Sjl139090 
98927Sjchu 		/* Get the correct CSR BASE */
9901772Sjl139090 		if (PX_ERR_XBC(reg_id))
99127Sjchu 			csr_base = (caddr_t)pxu_p->px_address[PX_REG_XBC];
9921772Sjl139090 		else
99327Sjchu 			csr_base = (caddr_t)pxu_p->px_address[PX_REG_CSR];
99427Sjchu 
99527Sjchu 		/* Get pointers to masks and register addresses */
99627Sjchu 		log_mask = err_reg_tbl->log_mask_p;
99727Sjchu 		count_mask = err_reg_tbl->count_mask_p;
99827Sjchu 		status_addr = err_reg_tbl->status_addr;
99927Sjchu 		clear_addr = err_reg_tbl->clear_addr;
100027Sjchu 		ss_reg = ss->err_status[reg_id];
100127Sjchu 
100227Sjchu 		/* Get the register BIT description table */
100327Sjchu 		err_bit_tbl = err_reg_tbl->err_bit_tbl;
100427Sjchu 
100527Sjchu 		/* For each known bit in the register send erpt and handle */
100627Sjchu 		for (key = 0; key < err_reg_tbl->err_bit_keys; key += 1) {
100727Sjchu 			/* Get the bit description table for this register */
100827Sjchu 			err_bit_desc = &err_bit_tbl[key];
100927Sjchu 
101027Sjchu 			/*
101127Sjchu 			 * If the ss_reg is set for this bit,
101227Sjchu 			 * send ereport and handle
101327Sjchu 			 */
101427Sjchu 			if (BIT_TST(ss_reg, err_bit_desc->bit)) {
101527Sjchu 				/* Increment the counter if necessary */
101627Sjchu 				if (BIT_TST(*count_mask, err_bit_desc->bit)) {
101727Sjchu 					err_bit_desc->counter++;
101827Sjchu 				}
101927Sjchu 
102027Sjchu 				/* Error Handle for this bit */
102127Sjchu 				err_handler = err_bit_desc->err_handler;
10221147Sjchu 				if (err_handler) {
10231147Sjchu 					biterr = err_handler(rpdip,
102427Sjchu 					    csr_base,
102527Sjchu 					    derr,
102627Sjchu 					    err_reg_tbl,
102727Sjchu 					    err_bit_desc);
10281147Sjchu 					err |= biterr;
10291147Sjchu 				}
103027Sjchu 
1031383Set142600 				/* Send the ereport if it's an UNEXPECTED err */
103227Sjchu 				erpt_handler = err_bit_desc->erpt_handler;
10331147Sjchu 				if ((derr->fme_flag == DDI_FM_ERR_UNEXPECTED) &&
10341147Sjchu 				    (biterr != PX_OK)) {
1035383Set142600 					if (erpt_handler)
1036383Set142600 						(void) erpt_handler(rpdip,
1037383Set142600 						    csr_base,
1038383Set142600 						    ss_reg,
1039383Set142600 						    derr,
1040739Sjchu 						    err_bit_desc->bit,
1041383Set142600 						    err_bit_desc->class_name);
1042383Set142600 				}
104327Sjchu 			}
104427Sjchu 		}
1045332Sjchu 		/* Print register status */
1046332Sjchu 		if (ss_reg & *log_mask)
1047332Sjchu 			DBG(DBG_ERR_INTR, rpdip, "<%x>=%16llx %s\n",
104827Sjchu 			    status_addr, ss_reg, err_reg_tbl->msg);
104927Sjchu 
105027Sjchu 		/* Clear the register and error */
105127Sjchu 		CSR_XS(csr_base, clear_addr, ss_reg);
105227Sjchu 	}
105327Sjchu 
105427Sjchu 	return (err);
105527Sjchu }
105627Sjchu 
105727Sjchu /*
105827Sjchu  * px_err_check_severity:
105927Sjchu  * Check the severity of the fire error based on an earlier snapshot
106027Sjchu  *
106127Sjchu  * @param px_p		leaf in which to take the snap shot.
106227Sjchu  * @param derr		fm err in which the ereport is to be based on
106327Sjchu  * @param ss		pre-allocated memory to store the snap shot.
106427Sjchu  */
106527Sjchu static int
106627Sjchu px_err_check_severity(px_t *px_p, ddi_fm_error_t *derr, int err, int caller)
106727Sjchu {
106827Sjchu 	px_pec_t 	*pec_p = px_p->px_pec_p;
106927Sjchu 	boolean_t	is_safeacc = B_FALSE;
1070118Sjchu 
1071118Sjchu 	/* nothing to do if called with no error */
1072118Sjchu 	if (err == PX_OK)
1073118Sjchu 		return (err);
107427Sjchu 
107527Sjchu 	/* Cautious access error handling  */
107627Sjchu 	switch (derr->fme_flag) {
107727Sjchu 	case DDI_FM_ERR_EXPECTED:
107827Sjchu 		if (caller == PX_TRAP_CALL) {
107927Sjchu 			/*
108027Sjchu 			 * for ddi_caut_get treat all events as nonfatal
108127Sjchu 			 * The trampoline will set err_ena = 0,
108227Sjchu 			 * err_status = NONFATAL.
108327Sjchu 			 */
108427Sjchu 			derr->fme_status = DDI_FM_NONFATAL;
108527Sjchu 			is_safeacc = B_TRUE;
108627Sjchu 		} else {
108727Sjchu 			/*
108827Sjchu 			 * For ddi_caut_put treat all events as nonfatal. Here
108927Sjchu 			 * we have the handle and can call ndi_fm_acc_err_set().
109027Sjchu 			 */
109127Sjchu 			derr->fme_status = DDI_FM_NONFATAL;
109227Sjchu 			ndi_fm_acc_err_set(pec_p->pec_acc_hdl, derr);
109327Sjchu 			is_safeacc = B_TRUE;
109427Sjchu 		}
109527Sjchu 		break;
109627Sjchu 	case DDI_FM_ERR_PEEK:
109727Sjchu 	case DDI_FM_ERR_POKE:
109827Sjchu 		/*
109927Sjchu 		 * For ddi_peek/poke treat all events as nonfatal.
110027Sjchu 		 */
110127Sjchu 		is_safeacc = B_TRUE;
110227Sjchu 		break;
110327Sjchu 	default:
110427Sjchu 		is_safeacc = B_FALSE;
110527Sjchu 	}
110627Sjchu 
110727Sjchu 	/*
110827Sjchu 	 * The third argument "err" is passed in as error status from checking
110927Sjchu 	 * Fire register, re-adjust error status from safe access.
111027Sjchu 	 */
111127Sjchu 	if (is_safeacc && !(err & PX_FATAL_GOS))
1112118Sjchu 		return (PX_NONFATAL);
111327Sjchu 
1114118Sjchu 	return (err);
111527Sjchu }
111627Sjchu 
111727Sjchu /* predefined convenience functions */
111827Sjchu /* ARGSUSED */
111927Sjchu int
112027Sjchu px_err_fatal_hw_handle(dev_info_t *rpdip, caddr_t csr_base,
112127Sjchu 	ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
112227Sjchu 	px_err_bit_desc_t *err_bit_descr)
112327Sjchu {
112427Sjchu 	return (PX_FATAL_HW);
112527Sjchu }
112627Sjchu 
112727Sjchu /* ARGSUSED */
112827Sjchu int
112927Sjchu px_err_fatal_gos_handle(dev_info_t *rpdip, caddr_t csr_base,
113027Sjchu 	ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
113127Sjchu 	px_err_bit_desc_t *err_bit_descr)
113227Sjchu {
113327Sjchu 	return (PX_FATAL_GOS);
113427Sjchu }
113527Sjchu 
113627Sjchu /* ARGSUSED */
113727Sjchu int
113827Sjchu px_err_fatal_stuck_handle(dev_info_t *rpdip, caddr_t csr_base,
113927Sjchu 	ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
114027Sjchu 	px_err_bit_desc_t *err_bit_descr)
114127Sjchu {
114227Sjchu 	return (PX_STUCK_FATAL);
114327Sjchu }
114427Sjchu 
114527Sjchu /* ARGSUSED */
114627Sjchu int
114727Sjchu px_err_fatal_sw_handle(dev_info_t *rpdip, caddr_t csr_base,
114827Sjchu 	ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
114927Sjchu 	px_err_bit_desc_t *err_bit_descr)
115027Sjchu {
115127Sjchu 	return (PX_FATAL_SW);
115227Sjchu }
115327Sjchu 
115427Sjchu /* ARGSUSED */
115527Sjchu int
115627Sjchu px_err_non_fatal_handle(dev_info_t *rpdip, caddr_t csr_base,
115727Sjchu 	ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
115827Sjchu 	px_err_bit_desc_t *err_bit_descr)
115927Sjchu {
116027Sjchu 	return (PX_NONFATAL);
116127Sjchu }
116227Sjchu 
116327Sjchu /* ARGSUSED */
116427Sjchu int
116527Sjchu px_err_ok_handle(dev_info_t *rpdip, caddr_t csr_base, ddi_fm_error_t *derr,
116627Sjchu 	px_err_reg_desc_t *err_reg_descr, px_err_bit_desc_t *err_bit_descr)
116727Sjchu {
116827Sjchu 	return (PX_OK);
116927Sjchu }
117027Sjchu 
117127Sjchu /* ARGSUSED */
117227Sjchu int
117327Sjchu px_err_unknown_handle(dev_info_t *rpdip, caddr_t csr_base, ddi_fm_error_t *derr,
117427Sjchu 	px_err_reg_desc_t *err_reg_descr, px_err_bit_desc_t *err_bit_descr)
117527Sjchu {
117627Sjchu 	return (PX_ERR_UNKNOWN);
117727Sjchu }
117827Sjchu 
1179383Set142600 /* ARGSUSED */
1180383Set142600 PX_ERPT_SEND_DEC(do_not)
1181383Set142600 {
1182383Set142600 	return (PX_OK);
1183383Set142600 }
1184383Set142600 
11851772Sjl139090 /* UBC FATAL - see io erpt doc, section 1.1 */
11861772Sjl139090 /* ARGSUSED */
11871772Sjl139090 PX_ERPT_SEND_DEC(ubc_fatal)
11881772Sjl139090 {
11891772Sjl139090 	char		buf[FM_MAX_CLASS];
11901772Sjl139090 	uint64_t	memory_ue_log, marked;
11911772Sjl139090 	char		unum[FM_MAX_CLASS];
11921772Sjl139090 	int		unum_length;
11931772Sjl139090 	uint64_t	device_id = 0;
11941772Sjl139090 	uint8_t		cpu_version = 0;
11951772Sjl139090 	nvlist_t	*resource = NULL;
11961772Sjl139090 
11971772Sjl139090 	unum[0] = '\0';
11981772Sjl139090 	(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
11991772Sjl139090 
12001772Sjl139090 	memory_ue_log = CSR_XR(csr_base, UBC_MEMORY_UE_LOG);
12011772Sjl139090 	marked = (memory_ue_log >> UBC_MEMORY_UE_LOG_MARKED) &
12021772Sjl139090 	    UBC_MEMORY_UE_LOG_MARKED_MASK;
12031772Sjl139090 
12041772Sjl139090 	if ((strstr(class_name, "ubc.piowtue") != NULL) ||
12051772Sjl139090 	    (strstr(class_name, "ubc.piowbeue") != NULL) ||
12061772Sjl139090 	    (strstr(class_name, "ubc.piorbeue") != NULL) ||
12071772Sjl139090 	    (strstr(class_name, "ubc.dmarduea") != NULL) ||
12081772Sjl139090 	    (strstr(class_name, "ubc.dmardueb") != NULL)) {
12091772Sjl139090 		int eid = (memory_ue_log >> UBC_MEMORY_UE_LOG_EID) &
12101772Sjl139090 		    UBC_MEMORY_UE_LOG_EID_MASK;
12111772Sjl139090 		(void) strncat(buf, ubc_class_eid_qualifier[eid],
12121772Sjl139090 		    FM_MAX_CLASS);
12131772Sjl139090 
12141772Sjl139090 		if (eid == UBC_EID_MEM) {
12151772Sjl139090 			uint64_t phys_addr = memory_ue_log &
12161772Sjl139090 			    MMU_OBERON_PADDR_MASK;
12171772Sjl139090 			uint64_t offset = (uint64_t)-1;
12181772Sjl139090 
12191772Sjl139090 			resource = fm_nvlist_create(NULL);
12201772Sjl139090 			if (&plat_get_mem_unum) {
12211772Sjl139090 				if ((plat_get_mem_unum(0,
12221772Sjl139090 				    phys_addr, 0, B_TRUE, 0, unum,
12231772Sjl139090 				    FM_MAX_CLASS, &unum_length)) != 0)
12241772Sjl139090 					unum[0] = '\0';
12251772Sjl139090 			}
12261772Sjl139090 			fm_fmri_mem_set(resource, FM_MEM_SCHEME_VERSION,
12271772Sjl139090 					NULL, unum, NULL, offset);
12281772Sjl139090 
12291772Sjl139090 		} else if (eid == UBC_EID_CPU) {
12301772Sjl139090 			int cpuid = (marked & UBC_MARKED_MAX_CPUID_MASK);
12311772Sjl139090 			char sbuf[21]; /* sizeof (UINT64_MAX) + '\0' */
12321772Sjl139090 
12331772Sjl139090 			resource = fm_nvlist_create(NULL);
12341772Sjl139090 			cpu_version = cpunodes[cpuid].version;
12351772Sjl139090 			device_id = cpunodes[cpuid].device_id;
12361772Sjl139090 			(void) snprintf(sbuf, sizeof (sbuf), "%lX",
12371772Sjl139090 			    device_id);
12381772Sjl139090 			(void) fm_fmri_cpu_set(resource,
12391772Sjl139090 			    FM_CPU_SCHEME_VERSION, NULL, cpuid,
12401772Sjl139090 			    &cpu_version, sbuf);
12411772Sjl139090 		}
12421772Sjl139090 	}
12431772Sjl139090 
12441772Sjl139090 	if (resource) {
12451772Sjl139090 		ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
12461772Sjl139090 		    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
12471772Sjl139090 		    FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, B_TRUE,
12481772Sjl139090 		    OBERON_UBC_ELE, DATA_TYPE_UINT64,
12491772Sjl139090 		    CSR_XR(csr_base, UBC_ERROR_LOG_ENABLE),
12501772Sjl139090 		    OBERON_UBC_IE, DATA_TYPE_UINT64,
12511772Sjl139090 		    CSR_XR(csr_base, UBC_INTERRUPT_ENABLE),
12521772Sjl139090 		    OBERON_UBC_IS, DATA_TYPE_UINT64,
12531772Sjl139090 		    CSR_XR(csr_base, UBC_INTERRUPT_STATUS),
12541772Sjl139090 		    OBERON_UBC_ESS, DATA_TYPE_UINT64,
12551772Sjl139090 		    CSR_XR(csr_base, UBC_ERROR_STATUS_SET),
12561772Sjl139090 		    OBERON_UBC_MUE, DATA_TYPE_UINT64, memory_ue_log,
12571772Sjl139090 		    OBERON_UBC_UNUM, DATA_TYPE_STRING, unum,
12581772Sjl139090 		    OBERON_UBC_DID, DATA_TYPE_UINT64, device_id,
12591772Sjl139090 		    OBERON_UBC_CPUV, DATA_TYPE_UINT32, cpu_version,
12601772Sjl139090 		    OBERON_UBC_RESOURCE, DATA_TYPE_NVLIST, resource,
12611772Sjl139090 		    NULL);
12621772Sjl139090 		fm_nvlist_destroy(resource, FM_NVA_FREE);
12631772Sjl139090 	} else {
12641772Sjl139090 		ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
12651772Sjl139090 		    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
12661772Sjl139090 		    FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, B_TRUE,
12671772Sjl139090 		    OBERON_UBC_ELE, DATA_TYPE_UINT64,
12681772Sjl139090 		    CSR_XR(csr_base, UBC_ERROR_LOG_ENABLE),
12691772Sjl139090 		    OBERON_UBC_IE, DATA_TYPE_UINT64,
12701772Sjl139090 		    CSR_XR(csr_base, UBC_INTERRUPT_ENABLE),
12711772Sjl139090 		    OBERON_UBC_IS, DATA_TYPE_UINT64,
12721772Sjl139090 		    CSR_XR(csr_base, UBC_INTERRUPT_STATUS),
12731772Sjl139090 		    OBERON_UBC_ESS, DATA_TYPE_UINT64,
12741772Sjl139090 		    CSR_XR(csr_base, UBC_ERROR_STATUS_SET),
12751772Sjl139090 		    OBERON_UBC_MUE, DATA_TYPE_UINT64, memory_ue_log,
12761772Sjl139090 		    OBERON_UBC_UNUM, DATA_TYPE_STRING, unum,
12771772Sjl139090 		    OBERON_UBC_DID, DATA_TYPE_UINT64, device_id,
12781772Sjl139090 		    OBERON_UBC_CPUV, DATA_TYPE_UINT32, cpu_version,
12791772Sjl139090 		    NULL);
12801772Sjl139090 	}
12811772Sjl139090 
12821772Sjl139090 	return (PX_OK);
12831772Sjl139090 }
1284383Set142600 
128527Sjchu /* JBC FATAL - see io erpt doc, section 1.1 */
128627Sjchu PX_ERPT_SEND_DEC(jbc_fatal)
128727Sjchu {
128827Sjchu 	char		buf[FM_MAX_CLASS];
1289739Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(bit);
129027Sjchu 
129127Sjchu 	(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
129227Sjchu 	ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
129327Sjchu 	    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
1294739Sjchu 	    FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
129527Sjchu 	    FIRE_JBC_ELE, DATA_TYPE_UINT64,
129627Sjchu 	    CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE),
129727Sjchu 	    FIRE_JBC_IE, DATA_TYPE_UINT64,
129827Sjchu 	    CSR_XR(csr_base, JBC_INTERRUPT_ENABLE),
129927Sjchu 	    FIRE_JBC_IS, DATA_TYPE_UINT64,
130027Sjchu 	    ss_reg,
130127Sjchu 	    FIRE_JBC_ESS, DATA_TYPE_UINT64,
130227Sjchu 	    CSR_XR(csr_base, JBC_ERROR_STATUS_SET),
130327Sjchu 	    FIRE_JBC_FEL1, DATA_TYPE_UINT64,
130427Sjchu 	    CSR_XR(csr_base, FATAL_ERROR_LOG_1),
130527Sjchu 	    FIRE_JBC_FEL2, DATA_TYPE_UINT64,
130627Sjchu 	    CSR_XR(csr_base, FATAL_ERROR_LOG_2),
130727Sjchu 	    NULL);
130827Sjchu 
130927Sjchu 	return (PX_OK);
131027Sjchu }
131127Sjchu 
131227Sjchu /* JBC MERGE - see io erpt doc, section 1.2 */
131327Sjchu PX_ERPT_SEND_DEC(jbc_merge)
131427Sjchu {
131527Sjchu 	char		buf[FM_MAX_CLASS];
1316739Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(bit);
131727Sjchu 
131827Sjchu 	(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
131927Sjchu 	ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
132027Sjchu 	    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
1321739Sjchu 	    FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
132227Sjchu 	    FIRE_JBC_ELE, DATA_TYPE_UINT64,
132327Sjchu 	    CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE),
132427Sjchu 	    FIRE_JBC_IE, DATA_TYPE_UINT64,
132527Sjchu 	    CSR_XR(csr_base, JBC_INTERRUPT_ENABLE),
132627Sjchu 	    FIRE_JBC_IS, DATA_TYPE_UINT64,
132727Sjchu 	    ss_reg,
132827Sjchu 	    FIRE_JBC_ESS, DATA_TYPE_UINT64,
132927Sjchu 	    CSR_XR(csr_base, JBC_ERROR_STATUS_SET),
133027Sjchu 	    FIRE_JBC_MTEL, DATA_TYPE_UINT64,
133127Sjchu 	    CSR_XR(csr_base, MERGE_TRANSACTION_ERROR_LOG),
133227Sjchu 	    NULL);
133327Sjchu 
133427Sjchu 	return (PX_OK);
133527Sjchu }
133627Sjchu 
133727Sjchu /*
133827Sjchu  * JBC Merge buffer nonfatal errors:
133927Sjchu  *    Merge buffer parity error (rd_buf): dma:read:M:nonfatal
134027Sjchu  *    Merge buffer parity error (wr_buf): dma:write:M:nonfatal
134127Sjchu  */
134227Sjchu /* ARGSUSED */
134327Sjchu int
134427Sjchu px_err_jbc_merge_handle(dev_info_t *rpdip, caddr_t csr_base,
134527Sjchu 	ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
134627Sjchu 	px_err_bit_desc_t *err_bit_descr)
134727Sjchu {
1348739Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(err_bit_descr->bit);
134927Sjchu 	uint64_t	paddr;
135027Sjchu 	int		ret;
135127Sjchu 
1352739Sjchu 	if (!pri)
1353739Sjchu 		return (PX_FATAL_GOS);
1354739Sjchu 
135527Sjchu 	paddr = CSR_XR(csr_base, MERGE_TRANSACTION_ERROR_LOG);
135627Sjchu 	paddr &= MERGE_TRANSACTION_ERROR_LOG_ADDRESS_MASK;
135727Sjchu 
135827Sjchu 	ret = px_handle_lookup(
135927Sjchu 		rpdip, DMA_HANDLE, derr->fme_ena, (void *)paddr);
136027Sjchu 
136127Sjchu 	return ((ret == DDI_FM_FATAL) ? PX_FATAL_GOS : PX_NONFATAL);
136227Sjchu }
136327Sjchu 
136427Sjchu /* JBC Jbusint IN - see io erpt doc, section 1.3 */
136527Sjchu PX_ERPT_SEND_DEC(jbc_in)
136627Sjchu {
136727Sjchu 	char		buf[FM_MAX_CLASS];
1368739Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(bit);
136927Sjchu 
137027Sjchu 	(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
137127Sjchu 	ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
137227Sjchu 	    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
1373739Sjchu 	    FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
137427Sjchu 	    FIRE_JBC_ELE, DATA_TYPE_UINT64,
137527Sjchu 	    CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE),
137627Sjchu 	    FIRE_JBC_IE, DATA_TYPE_UINT64,
137727Sjchu 	    CSR_XR(csr_base, JBC_INTERRUPT_ENABLE),
137827Sjchu 	    FIRE_JBC_IS, DATA_TYPE_UINT64,
137927Sjchu 	    ss_reg,
138027Sjchu 	    FIRE_JBC_ESS, DATA_TYPE_UINT64,
138127Sjchu 	    CSR_XR(csr_base, JBC_ERROR_STATUS_SET),
138227Sjchu 	    FIRE_JBC_JITEL1, DATA_TYPE_UINT64,
138327Sjchu 	    CSR_XR(csr_base, JBCINT_IN_TRANSACTION_ERROR_LOG),
138427Sjchu 	    FIRE_JBC_JITEL2, DATA_TYPE_UINT64,
138527Sjchu 	    CSR_XR(csr_base, JBCINT_IN_TRANSACTION_ERROR_LOG_2),
138627Sjchu 	    NULL);
138727Sjchu 
138827Sjchu 	return (PX_OK);
138927Sjchu }
139027Sjchu 
139127Sjchu /*
139227Sjchu  * JBC Jbusint IN nonfatal errors: PA logged in Jbusint In Transaction Error
139327Sjchu  * Log Reg[42:0].
139427Sjchu  *     CE async fault error: nonfatal
139527Sjchu  *     Jbus bus error: dma::nonfatal
139627Sjchu  *     Jbus unmapped error: pio|dma:rdwr:M:nonfatal
139727Sjchu  *     Write data parity error: pio/write:M:nonfatal
139827Sjchu  *     Read data parity error: pio/read:M:nonfatal
139927Sjchu  *     Illegal NCWR bytemask: pio:write:M:nonfatal
140027Sjchu  *     Illegal NCRD bytemask: pio:write:M:nonfatal
140127Sjchu  *     Invalid jbus transaction: nonfatal
140227Sjchu  */
140327Sjchu /* ARGSUSED */
140427Sjchu int
140527Sjchu px_err_jbc_jbusint_in_handle(dev_info_t *rpdip, caddr_t csr_base,
140627Sjchu 	ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
140727Sjchu 	px_err_bit_desc_t *err_bit_descr)
140827Sjchu {
1409739Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(err_bit_descr->bit);
141027Sjchu 	uint64_t	paddr;
141127Sjchu 	int		ret;
141227Sjchu 
1413739Sjchu 	if (!pri)
1414739Sjchu 		return (PX_FATAL_GOS);
1415739Sjchu 
141627Sjchu 	paddr = CSR_XR(csr_base, JBCINT_IN_TRANSACTION_ERROR_LOG);
141727Sjchu 	paddr &= JBCINT_IN_TRANSACTION_ERROR_LOG_ADDRESS_MASK;
141827Sjchu 
141927Sjchu 	ret = px_handle_lookup(
142027Sjchu 		rpdip, DMA_HANDLE, derr->fme_ena, (void *)paddr);
142127Sjchu 
142227Sjchu 	return ((ret == DDI_FM_FATAL) ? PX_FATAL_GOS : PX_NONFATAL);
142327Sjchu }
142427Sjchu 
142527Sjchu 
142627Sjchu /* JBC Jbusint Out - see io erpt doc, section 1.4 */
142727Sjchu PX_ERPT_SEND_DEC(jbc_out)
142827Sjchu {
142927Sjchu 	char		buf[FM_MAX_CLASS];
1430739Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(bit);
143127Sjchu 
143227Sjchu 	(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
143327Sjchu 	ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
143427Sjchu 	    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
1435739Sjchu 	    FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
143627Sjchu 	    FIRE_JBC_ELE, DATA_TYPE_UINT64,
143727Sjchu 	    CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE),
143827Sjchu 	    FIRE_JBC_IE, DATA_TYPE_UINT64,
143927Sjchu 	    CSR_XR(csr_base, JBC_INTERRUPT_ENABLE),
144027Sjchu 	    FIRE_JBC_IS, DATA_TYPE_UINT64,
144127Sjchu 	    ss_reg,
144227Sjchu 	    FIRE_JBC_ESS, DATA_TYPE_UINT64,
144327Sjchu 	    CSR_XR(csr_base, JBC_ERROR_STATUS_SET),
144427Sjchu 	    FIRE_JBC_JOTEL1, DATA_TYPE_UINT64,
144527Sjchu 	    CSR_XR(csr_base, JBCINT_OUT_TRANSACTION_ERROR_LOG),
144627Sjchu 	    FIRE_JBC_JOTEL2, DATA_TYPE_UINT64,
144727Sjchu 	    CSR_XR(csr_base, JBCINT_OUT_TRANSACTION_ERROR_LOG_2),
144827Sjchu 	    NULL);
144927Sjchu 
145027Sjchu 	return (PX_OK);
145127Sjchu }
145227Sjchu 
145327Sjchu /* JBC Dmcint ODCD - see io erpt doc, section 1.5 */
145427Sjchu PX_ERPT_SEND_DEC(jbc_odcd)
145527Sjchu {
145627Sjchu 	char		buf[FM_MAX_CLASS];
1457739Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(bit);
145827Sjchu 
145927Sjchu 	(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
146027Sjchu 	ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
146127Sjchu 	    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
1462739Sjchu 	    FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
146327Sjchu 	    FIRE_JBC_ELE, DATA_TYPE_UINT64,
146427Sjchu 	    CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE),
146527Sjchu 	    FIRE_JBC_IE, DATA_TYPE_UINT64,
146627Sjchu 	    CSR_XR(csr_base, JBC_INTERRUPT_ENABLE),
146727Sjchu 	    FIRE_JBC_IS, DATA_TYPE_UINT64,
146827Sjchu 	    ss_reg,
146927Sjchu 	    FIRE_JBC_ESS, DATA_TYPE_UINT64,
147027Sjchu 	    CSR_XR(csr_base, JBC_ERROR_STATUS_SET),
147127Sjchu 	    FIRE_JBC_DMC_ODCD, DATA_TYPE_UINT64,
147227Sjchu 	    CSR_XR(csr_base, DMCINT_ODCD_ERROR_LOG),
147327Sjchu 	    NULL);
147427Sjchu 
147527Sjchu 	return (PX_OK);
147627Sjchu }
147727Sjchu 
147827Sjchu /*
147927Sjchu  * JBC Dmcint ODCO nonfatal errer handling -
148027Sjchu  *    PIO data parity error: pio:write:M:nonfatal
148127Sjchu  */
148227Sjchu /* ARGSUSED */
148327Sjchu int
148427Sjchu px_err_jbc_dmcint_odcd_handle(dev_info_t *rpdip, caddr_t csr_base,
148527Sjchu 	ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
148627Sjchu 	px_err_bit_desc_t *err_bit_descr)
148727Sjchu {
1488739Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(err_bit_descr->bit);
148927Sjchu 	uint64_t	paddr;
149027Sjchu 	int		ret;
149127Sjchu 
1492739Sjchu 	if (!pri)
1493739Sjchu 		return (PX_FATAL_GOS);
1494739Sjchu 
149527Sjchu 	paddr = CSR_XR(csr_base, DMCINT_ODCD_ERROR_LOG);
149627Sjchu 	paddr &= DMCINT_ODCD_ERROR_LOG_ADDRESS_MASK;
149727Sjchu 
149827Sjchu 	ret = px_handle_lookup(
149927Sjchu 		rpdip, DMA_HANDLE, derr->fme_ena, (void *)paddr);
150027Sjchu 
150127Sjchu 	return ((ret == DDI_FM_FATAL) ? PX_FATAL_GOS : PX_NONFATAL);
150227Sjchu }
150327Sjchu 
1504*2276Sschwartz /* Does address in DMCINT error log register match address of pcitool access? */
1505*2276Sschwartz static boolean_t
1506*2276Sschwartz px_jbc_pcitool_addr_match(dev_info_t *rpdip, caddr_t csr_base)
1507*2276Sschwartz {
1508*2276Sschwartz 	px_t	*px_p = DIP_TO_STATE(rpdip);
1509*2276Sschwartz 	pxu_t	*pxu_p = (pxu_t *)px_p->px_plat_p;
1510*2276Sschwartz 	caddr_t	pcitool_addr = pxu_p->pcitool_addr;
1511*2276Sschwartz 	caddr_t errlog_addr =
1512*2276Sschwartz 	    (caddr_t)CSR_FR(csr_base, DMCINT_ODCD_ERROR_LOG, ADDRESS);
1513*2276Sschwartz 
1514*2276Sschwartz 	return (pcitool_addr == errlog_addr);
1515*2276Sschwartz }
1516*2276Sschwartz 
1517*2276Sschwartz /*
1518*2276Sschwartz  * JBC Dmcint ODCD errer handling for errors which are forgivable during a safe
1519*2276Sschwartz  * access.  (This will be most likely be a PCItool access.)  If not a safe
1520*2276Sschwartz  * access context, treat like jbc_dmcint_odcd.
1521*2276Sschwartz  *    Unmapped PIO read error: pio:read:M:nonfatal
1522*2276Sschwartz  *    Unmapped PIO write error: pio:write:M:nonfatal
1523*2276Sschwartz  *    Invalid PIO write to PCIe cfg/io, csr, ebus or i2c bus: pio:write:nonfatal
1524*2276Sschwartz  *    Invalid PIO read to PCIe cfg/io, csr, ebus or i2c bus: pio:read:nonfatal
1525*2276Sschwartz  */
1526*2276Sschwartz /* ARGSUSED */
1527*2276Sschwartz int
1528*2276Sschwartz px_err_jbc_safe_acc_handle(dev_info_t *rpdip, caddr_t csr_base,
1529*2276Sschwartz 	ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
1530*2276Sschwartz 	px_err_bit_desc_t *err_bit_descr)
1531*2276Sschwartz {
1532*2276Sschwartz 	boolean_t	pri = PX_ERR_IS_PRI(err_bit_descr->bit);
1533*2276Sschwartz 
1534*2276Sschwartz 	if (!pri)
1535*2276Sschwartz 		return (PX_FATAL_GOS);
1536*2276Sschwartz 	/*
1537*2276Sschwartz 	 * Got an error which is forgivable during a PCItool access.
1538*2276Sschwartz 	 *
1539*2276Sschwartz 	 * Don't do handler check since the error may otherwise be unfairly
1540*2276Sschwartz 	 * attributed to a device.  Just return.
1541*2276Sschwartz 	 *
1542*2276Sschwartz 	 * Note: There is a hole here in that a legitimate error can come in
1543*2276Sschwartz 	 * while a PCItool access is in play and be forgiven.  This is possible
1544*2276Sschwartz 	 * though not likely.
1545*2276Sschwartz 	 */
1546*2276Sschwartz 	if ((derr->fme_flag != DDI_FM_ERR_UNEXPECTED) &&
1547*2276Sschwartz 	    (px_jbc_pcitool_addr_match(rpdip, csr_base)))
1548*2276Sschwartz 		return (PX_FATAL_SW);
1549*2276Sschwartz 
1550*2276Sschwartz 	return (px_err_jbc_dmcint_odcd_handle(rpdip, csr_base, derr,
1551*2276Sschwartz 	    err_reg_descr, err_bit_descr));
1552*2276Sschwartz }
1553*2276Sschwartz 
155427Sjchu /* JBC Dmcint IDC - see io erpt doc, section 1.6 */
155527Sjchu PX_ERPT_SEND_DEC(jbc_idc)
155627Sjchu {
155727Sjchu 	char		buf[FM_MAX_CLASS];
1558739Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(bit);
155927Sjchu 
156027Sjchu 	(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
156127Sjchu 	ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
156227Sjchu 	    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
1563739Sjchu 	    FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
156427Sjchu 	    FIRE_JBC_ELE, DATA_TYPE_UINT64,
156527Sjchu 	    CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE),
156627Sjchu 	    FIRE_JBC_IE, DATA_TYPE_UINT64,
156727Sjchu 	    CSR_XR(csr_base, JBC_INTERRUPT_ENABLE),
156827Sjchu 	    FIRE_JBC_IS, DATA_TYPE_UINT64,
156927Sjchu 	    ss_reg,
157027Sjchu 	    FIRE_JBC_ESS, DATA_TYPE_UINT64,
157127Sjchu 	    CSR_XR(csr_base, JBC_ERROR_STATUS_SET),
157227Sjchu 	    FIRE_JBC_DMC_IDC, DATA_TYPE_UINT64,
157327Sjchu 	    CSR_XR(csr_base, DMCINT_IDC_ERROR_LOG),
157427Sjchu 	    NULL);
157527Sjchu 
157627Sjchu 	return (PX_OK);
157727Sjchu }
157827Sjchu 
157927Sjchu /* JBC CSR - see io erpt doc, section 1.7 */
158027Sjchu PX_ERPT_SEND_DEC(jbc_csr)
158127Sjchu {
158227Sjchu 	char		buf[FM_MAX_CLASS];
1583739Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(bit);
158427Sjchu 
158527Sjchu 	(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
158627Sjchu 	ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
158727Sjchu 	    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
1588739Sjchu 	    FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
158927Sjchu 	    FIRE_JBC_ELE, DATA_TYPE_UINT64,
159027Sjchu 	    CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE),
159127Sjchu 	    FIRE_JBC_IE, DATA_TYPE_UINT64,
159227Sjchu 	    CSR_XR(csr_base, JBC_INTERRUPT_ENABLE),
159327Sjchu 	    FIRE_JBC_IS, DATA_TYPE_UINT64,
159427Sjchu 	    ss_reg,
159527Sjchu 	    FIRE_JBC_ESS, DATA_TYPE_UINT64,
159627Sjchu 	    CSR_XR(csr_base, JBC_ERROR_STATUS_SET),
159727Sjchu 	    "jbc-error-reg", DATA_TYPE_UINT64,
159827Sjchu 	    CSR_XR(csr_base, CSR_ERROR_LOG),
159927Sjchu 	    NULL);
160027Sjchu 
160127Sjchu 	return (PX_OK);
160227Sjchu }
160327Sjchu 
160427Sjchu /*
160527Sjchu  * JBC CSR errer handling -
160627Sjchu  * Ebus ready timeout error: pio:rdwr:M:nonfatal
160727Sjchu  */
160827Sjchu /* ARGSUSED */
160927Sjchu int
161027Sjchu px_err_jbc_csr_handle(dev_info_t *rpdip, caddr_t csr_base,
161127Sjchu 	ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
161227Sjchu 	px_err_bit_desc_t *err_bit_descr)
161327Sjchu {
1614739Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(err_bit_descr->bit);
161527Sjchu 	uint64_t	paddr;
161627Sjchu 	int		ret;
161727Sjchu 
1618739Sjchu 	if (!pri)
1619739Sjchu 		return (PX_FATAL_GOS);
1620739Sjchu 
162127Sjchu 	paddr = CSR_XR(csr_base, CSR_ERROR_LOG);
162227Sjchu 	paddr &= CSR_ERROR_LOG_ADDRESS_MASK;
162327Sjchu 
162427Sjchu 	ret = px_handle_lookup(
162527Sjchu 		rpdip, DMA_HANDLE, derr->fme_ena, (void *)paddr);
162627Sjchu 
162727Sjchu 	return ((ret == DDI_FM_FATAL) ? PX_FATAL_GOS : PX_NONFATAL);
162827Sjchu }
162927Sjchu 
163027Sjchu /* JBC Dmcint IDC - see io erpt doc, section 1.6 */
163127Sjchu 
163227Sjchu /* DMC IMU RDS - see io erpt doc, section 2.1 */
163327Sjchu PX_ERPT_SEND_DEC(imu_rds)
163427Sjchu {
163527Sjchu 	char		buf[FM_MAX_CLASS];
1636739Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(bit);
163727Sjchu 
163827Sjchu 	(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
163927Sjchu 	ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
164027Sjchu 	    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
1641739Sjchu 	    FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
164227Sjchu 	    FIRE_IMU_ELE, DATA_TYPE_UINT64,
164327Sjchu 	    CSR_XR(csr_base, IMU_ERROR_LOG_ENABLE),
164427Sjchu 	    FIRE_IMU_IE, DATA_TYPE_UINT64,
164527Sjchu 	    CSR_XR(csr_base, IMU_INTERRUPT_ENABLE),
164627Sjchu 	    FIRE_IMU_IS, DATA_TYPE_UINT64,
164727Sjchu 	    ss_reg,
164827Sjchu 	    FIRE_IMU_ESS, DATA_TYPE_UINT64,
164927Sjchu 	    CSR_XR(csr_base, IMU_ERROR_STATUS_SET),
165027Sjchu 	    FIRE_IMU_RDS, DATA_TYPE_UINT64,
165127Sjchu 	    CSR_XR(csr_base, IMU_RDS_ERROR_LOG),
165227Sjchu 	    NULL);
165327Sjchu 
165427Sjchu 	return (PX_OK);
165527Sjchu }
165627Sjchu 
165727Sjchu /* imu function to handle all Received but Not Enabled errors */
165827Sjchu /* ARGSUSED */
165927Sjchu int
166027Sjchu px_err_imu_rbne_handle(dev_info_t *rpdip, caddr_t csr_base,
166127Sjchu 	ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
166227Sjchu 	px_err_bit_desc_t *err_bit_descr)
166327Sjchu {
166427Sjchu 	uint64_t	imu_log_enable, imu_intr_enable;
166527Sjchu 	int		mask = BITMASK(err_bit_descr->bit);
166627Sjchu 	int		err = PX_NONFATAL;
166727Sjchu 
166827Sjchu 	imu_log_enable = CSR_XR(csr_base, err_reg_descr->log_addr);
166927Sjchu 	imu_intr_enable = CSR_XR(csr_base, err_reg_descr->enable_addr);
167027Sjchu 
1671435Sjchu 	/*
1672435Sjchu 	 * If matching bit is not set, meaning corresponding rbne not
1673435Sjchu 	 * enabled, then receiving it indicates some sort of malfunction
1674435Sjchu 	 * possibly in hardware.
1675435Sjchu 	 *
1676435Sjchu 	 * Other wise, software may have intentionally disabled certain
1677435Sjchu 	 * errors for a period of time within which the occuring of the
1678435Sjchu 	 * disabled errors become rbne, that is non fatal.
1679435Sjchu 	 */
16801772Sjl139090 
1681435Sjchu 	if (!(imu_log_enable & imu_intr_enable & mask))
1682*2276Sschwartz 		err = PX_FATAL_GOS;
168327Sjchu 
168427Sjchu 	return (err);
168527Sjchu }
168627Sjchu 
1687118Sjchu /*
1688118Sjchu  * No platforms uses PME. Any PME received is simply logged
1689118Sjchu  * for analysis.
1690118Sjchu  */
1691118Sjchu /* ARGSUSED */
1692118Sjchu int
1693118Sjchu px_err_imu_pme_handle(dev_info_t *rpdip, caddr_t csr_base,
1694118Sjchu 	ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
1695118Sjchu 	px_err_bit_desc_t *err_bit_descr)
1696118Sjchu {
1697118Sjchu 	px_t		*px_p = DIP_TO_STATE(rpdip);
1698118Sjchu 
1699118Sjchu 	px_p->px_pme_ignored++;
1700118Sjchu 	return (PX_NONFATAL);
1701118Sjchu }
1702118Sjchu 
170327Sjchu /* handle EQ overflow */
170427Sjchu /* ARGSUSED */
170527Sjchu int
170627Sjchu px_err_imu_eq_ovfl_handle(dev_info_t *rpdip, caddr_t csr_base,
170727Sjchu 	ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
170827Sjchu 	px_err_bit_desc_t *err_bit_descr)
170927Sjchu {
171027Sjchu 	px_t			*px_p = DIP_TO_STATE(rpdip);
171127Sjchu 	px_msiq_state_t 	*msiq_state_p = &px_p->px_ib_p->ib_msiq_state;
171227Sjchu 	msiqid_t		eqno;
171327Sjchu 	pci_msiq_state_t	msiq_state;
171427Sjchu 	int			err = PX_NONFATAL;
171527Sjchu 	int			i;
171627Sjchu 
171727Sjchu 	eqno = msiq_state_p->msiq_1st_msiq_id;
171827Sjchu 	for (i = 0; i < msiq_state_p->msiq_cnt; i++) {
171927Sjchu 		if (px_lib_msiq_getstate(rpdip, eqno, &msiq_state) ==
172027Sjchu 			DDI_SUCCESS) {
172127Sjchu 			if (msiq_state == PCI_MSIQ_STATE_ERROR) {
1722*2276Sschwartz 				err = PX_FATAL_GOS;
172327Sjchu 			}
172427Sjchu 		}
172527Sjchu 	}
172627Sjchu 
172727Sjchu 	return (err);
172827Sjchu }
172927Sjchu 
173027Sjchu /* DMC IMU SCS - see io erpt doc, section 2.2 */
173127Sjchu PX_ERPT_SEND_DEC(imu_scs)
173227Sjchu {
173327Sjchu 	char		buf[FM_MAX_CLASS];
1734739Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(bit);
173527Sjchu 
173627Sjchu 	(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
173727Sjchu 	ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
173827Sjchu 	    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
1739739Sjchu 	    FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
174027Sjchu 	    FIRE_IMU_ELE, DATA_TYPE_UINT64,
174127Sjchu 	    CSR_XR(csr_base, IMU_ERROR_LOG_ENABLE),
174227Sjchu 	    FIRE_IMU_IE, DATA_TYPE_UINT64,
174327Sjchu 	    CSR_XR(csr_base, IMU_INTERRUPT_ENABLE),
174427Sjchu 	    FIRE_IMU_IS, DATA_TYPE_UINT64,
174527Sjchu 	    ss_reg,
174627Sjchu 	    FIRE_IMU_ESS, DATA_TYPE_UINT64,
174727Sjchu 	    CSR_XR(csr_base, IMU_ERROR_STATUS_SET),
174827Sjchu 	    FIRE_IMU_SCS, DATA_TYPE_UINT64,
174927Sjchu 	    CSR_XR(csr_base, IMU_SCS_ERROR_LOG),
175027Sjchu 	    NULL);
175127Sjchu 
175227Sjchu 	return (PX_OK);
175327Sjchu }
175427Sjchu 
175527Sjchu /* DMC IMU - see io erpt doc, section 2.3 */
175627Sjchu PX_ERPT_SEND_DEC(imu)
175727Sjchu {
175827Sjchu 	char		buf[FM_MAX_CLASS];
1759739Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(bit);
176027Sjchu 
176127Sjchu 	(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
176227Sjchu 	ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
176327Sjchu 	    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
1764739Sjchu 	    FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
176527Sjchu 	    FIRE_IMU_ELE, DATA_TYPE_UINT64,
176627Sjchu 	    CSR_XR(csr_base, IMU_ERROR_LOG_ENABLE),
176727Sjchu 	    FIRE_IMU_IE, DATA_TYPE_UINT64,
176827Sjchu 	    CSR_XR(csr_base, IMU_INTERRUPT_ENABLE),
176927Sjchu 	    FIRE_IMU_IS, DATA_TYPE_UINT64,
177027Sjchu 	    ss_reg,
177127Sjchu 	    FIRE_IMU_ESS, DATA_TYPE_UINT64,
177227Sjchu 	    CSR_XR(csr_base, IMU_ERROR_STATUS_SET),
177327Sjchu 	    NULL);
177427Sjchu 
177527Sjchu 	return (PX_OK);
177627Sjchu }
177727Sjchu 
177827Sjchu /* DMC MMU TFAR/TFSR - see io erpt doc, section 2.4 */
177927Sjchu PX_ERPT_SEND_DEC(mmu_tfar_tfsr)
178027Sjchu {
178127Sjchu 	char		buf[FM_MAX_CLASS];
1782739Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(bit);
178327Sjchu 
178427Sjchu 	(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
17851772Sjl139090 
178627Sjchu 	ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
178727Sjchu 	    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
1788739Sjchu 	    FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
178927Sjchu 	    FIRE_MMU_ELE, DATA_TYPE_UINT64,
179027Sjchu 	    CSR_XR(csr_base, MMU_ERROR_LOG_ENABLE),
179127Sjchu 	    FIRE_MMU_IE, DATA_TYPE_UINT64,
179227Sjchu 	    CSR_XR(csr_base, MMU_INTERRUPT_ENABLE),
179327Sjchu 	    FIRE_MMU_IS, DATA_TYPE_UINT64,
179427Sjchu 	    ss_reg,
179527Sjchu 	    FIRE_MMU_ESS, DATA_TYPE_UINT64,
179627Sjchu 	    CSR_XR(csr_base, MMU_ERROR_STATUS_SET),
179727Sjchu 	    FIRE_MMU_TFAR, DATA_TYPE_UINT64,
179827Sjchu 	    CSR_XR(csr_base, MMU_TRANSLATION_FAULT_ADDRESS),
179927Sjchu 	    FIRE_MMU_TFSR, DATA_TYPE_UINT64,
180027Sjchu 	    CSR_XR(csr_base, MMU_TRANSLATION_FAULT_STATUS),
180127Sjchu 	    NULL);
180227Sjchu 
180327Sjchu 	return (PX_OK);
180427Sjchu }
180527Sjchu 
180627Sjchu /* DMC MMU - see io erpt doc, section 2.5 */
180727Sjchu PX_ERPT_SEND_DEC(mmu)
180827Sjchu {
180927Sjchu 	char		buf[FM_MAX_CLASS];
1810739Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(bit);
181127Sjchu 
181227Sjchu 	(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
181327Sjchu 	ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
181427Sjchu 	    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
1815739Sjchu 	    FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
181627Sjchu 	    FIRE_MMU_ELE, DATA_TYPE_UINT64,
181727Sjchu 	    CSR_XR(csr_base, MMU_ERROR_LOG_ENABLE),
181827Sjchu 	    FIRE_MMU_IE, DATA_TYPE_UINT64,
181927Sjchu 	    CSR_XR(csr_base, MMU_INTERRUPT_ENABLE),
182027Sjchu 	    FIRE_MMU_IS, DATA_TYPE_UINT64,
182127Sjchu 	    ss_reg,
182227Sjchu 	    FIRE_MMU_ESS, DATA_TYPE_UINT64,
182327Sjchu 	    CSR_XR(csr_base, MMU_ERROR_STATUS_SET),
182427Sjchu 	    NULL);
182527Sjchu 
182627Sjchu 	return (PX_OK);
182727Sjchu }
182827Sjchu 
182927Sjchu /* imu function to handle all Received but Not Enabled errors */
183027Sjchu int
183127Sjchu px_err_mmu_rbne_handle(dev_info_t *rpdip, caddr_t csr_base,
183227Sjchu 	ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
183327Sjchu 	px_err_bit_desc_t *err_bit_descr)
183427Sjchu {
1835739Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(err_bit_descr->bit);
1836260Set142600 	uint64_t	mmu_log_enable, mmu_intr_enable;
183727Sjchu 	uint64_t	mask = BITMASK(err_bit_descr->bit);
1838260Set142600 	uint64_t	mmu_tfa, mmu_ctrl;
1839260Set142600 	uint64_t	mmu_enable_bit = 0;
184027Sjchu 	int		err = PX_NONFATAL;
184127Sjchu 	int		ret;
184227Sjchu 
184327Sjchu 	mmu_log_enable = CSR_XR(csr_base, err_reg_descr->log_addr);
184427Sjchu 	mmu_intr_enable = CSR_XR(csr_base, err_reg_descr->enable_addr);
184527Sjchu 
184627Sjchu 	mmu_tfa = CSR_XR(csr_base, MMU_TRANSLATION_FAULT_ADDRESS);
1847260Set142600 	mmu_ctrl = CSR_XR(csr_base, MMU_CONTROL_AND_STATUS);
184827Sjchu 
1849260Set142600 	switch (err_bit_descr->bit) {
1850260Set142600 	case MMU_INTERRUPT_STATUS_BYP_ERR_P:
1851260Set142600 		mmu_enable_bit = BITMASK(MMU_CONTROL_AND_STATUS_BE);
1852260Set142600 		break;
1853260Set142600 	case MMU_INTERRUPT_STATUS_TRN_ERR_P:
1854260Set142600 		mmu_enable_bit = BITMASK(MMU_CONTROL_AND_STATUS_TE);
1855260Set142600 		break;
1856260Set142600 	default:
1857260Set142600 		mmu_enable_bit = 0;
1858260Set142600 		break;
1859260Set142600 	}
1860260Set142600 
1861260Set142600 	/*
1862260Set142600 	 * If the interrupts are enabled and Translation/Bypass Enable bit
1863260Set142600 	 * was set, then panic.  This error should not have occured.
1864260Set142600 	 */
1865260Set142600 	if (mmu_log_enable & mmu_intr_enable &
1866260Set142600 	    (mmu_ctrl & mmu_enable_bit)) {
1867*2276Sschwartz 		err = PX_FATAL_GOS;
186827Sjchu 	} else {
1869739Sjchu 		if (!pri)
1870739Sjchu 			return (PX_FATAL_GOS);
1871739Sjchu 
187227Sjchu 		ret = px_handle_lookup(
187327Sjchu 			rpdip, DMA_HANDLE, derr->fme_ena, (void *)mmu_tfa);
187427Sjchu 		err = (ret == DDI_FM_FATAL) ? PX_FATAL_GOS : PX_NONFATAL;
187527Sjchu 
187627Sjchu 		/*
187727Sjchu 		 * S/W bug - this error should always be enabled
187827Sjchu 		 */
187927Sjchu 
188027Sjchu 		/* enable error & intr reporting for this bit */
188127Sjchu 		CSR_XS(csr_base, MMU_ERROR_LOG_ENABLE, mmu_log_enable | mask);
188227Sjchu 		CSR_XS(csr_base, MMU_INTERRUPT_ENABLE, mmu_intr_enable | mask);
1883260Set142600 
1884260Set142600 		/* enable translation access/bypass enable */
1885260Set142600 		CSR_XS(csr_base, MMU_CONTROL_AND_STATUS,
1886260Set142600 		    mmu_ctrl | mmu_enable_bit);
188727Sjchu 	}
188827Sjchu 
188927Sjchu 	return (err);
189027Sjchu }
189127Sjchu 
189227Sjchu /* Generic error handling functions that involve MMU Translation Fault Addr */
189327Sjchu /* ARGSUSED */
189427Sjchu int
189527Sjchu px_err_mmu_tfa_handle(dev_info_t *rpdip, caddr_t csr_base,
189627Sjchu 	ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
189727Sjchu 	px_err_bit_desc_t *err_bit_descr)
189827Sjchu {
1899739Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(err_bit_descr->bit);
190027Sjchu 	uint64_t	mmu_tfa;
190127Sjchu 	uint_t		ret;
190227Sjchu 
1903739Sjchu 	if (!pri)
1904739Sjchu 		return (PX_FATAL_GOS);
1905739Sjchu 
190627Sjchu 	mmu_tfa = CSR_XR(csr_base, MMU_TRANSLATION_FAULT_ADDRESS);
190727Sjchu 	ret = px_handle_lookup(
190827Sjchu 		rpdip, DMA_HANDLE, derr->fme_ena, (void *)mmu_tfa);
190927Sjchu 
191027Sjchu 	return ((ret == DDI_FM_FATAL) ? PX_FATAL_GOS : PX_NONFATAL);
191127Sjchu }
191227Sjchu 
191327Sjchu /* MMU Table walk errors */
191427Sjchu /* ARGSUSED */
191527Sjchu int
191627Sjchu px_err_mmu_tblwlk_handle(dev_info_t *rpdip, caddr_t csr_base,
191727Sjchu 	ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
191827Sjchu 	px_err_bit_desc_t *err_bit_descr)
191927Sjchu {
1920739Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(err_bit_descr->bit);
192127Sjchu 	uint64_t	mmu_tfa;
192227Sjchu 	uint_t		ret;
192327Sjchu 
1924739Sjchu 	if (!pri)
1925739Sjchu 		return (PX_FATAL_GOS);
1926739Sjchu 
192727Sjchu 	mmu_tfa = CSR_XR(csr_base, MMU_TRANSLATION_FAULT_ADDRESS);
192827Sjchu 	ret = px_handle_lookup(
192927Sjchu 		rpdip, DMA_HANDLE, derr->fme_ena, (void *)mmu_tfa);
193027Sjchu 
193127Sjchu 	return ((ret == DDI_FM_FATAL) ? PX_FATAL_GOS : PX_NONFATAL);
193227Sjchu }
193327Sjchu 
1934118Sjchu /*
19351147Sjchu  * TLU LUP event - if caused by power management activity, then it is expected.
19361147Sjchu  * In all other cases, it is an error.
1937118Sjchu  */
1938118Sjchu /* ARGSUSED */
1939118Sjchu int
1940118Sjchu px_err_tlu_lup_handle(dev_info_t *rpdip, caddr_t csr_base,
1941118Sjchu 	ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
1942118Sjchu 	px_err_bit_desc_t *err_bit_descr)
1943118Sjchu {
1944118Sjchu 	px_t	*px_p = DIP_TO_STATE(rpdip);
1945118Sjchu 
1946118Sjchu 	/*
19471147Sjchu 	 * power management code is currently the only segment that sets
19481147Sjchu 	 * px_lup_pending to indicate its expectation for a healthy LUP
19491147Sjchu 	 * event.  For all other occasions, LUP event should be flaged as
19501147Sjchu 	 * error condition.
1951118Sjchu 	 */
19521147Sjchu 	return ((atomic_cas_32(&px_p->px_lup_pending, 1, 0) == 0) ?
19531147Sjchu 	    PX_NONFATAL : PX_OK);
19541147Sjchu }
1955118Sjchu 
19561147Sjchu /*
19571147Sjchu  * TLU LDN event - if caused by power management activity, then it is expected.
19581147Sjchu  * In all other cases, it is an error.
19591147Sjchu  */
19601147Sjchu /* ARGSUSED */
19611147Sjchu int
19621147Sjchu px_err_tlu_ldn_handle(dev_info_t *rpdip, caddr_t csr_base,
19631147Sjchu 	ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
19641147Sjchu 	px_err_bit_desc_t *err_bit_descr)
19651147Sjchu {
19661147Sjchu 	px_t    *px_p = DIP_TO_STATE(rpdip);
19671147Sjchu 	return ((px_p->px_pm_flags & PX_LDN_EXPECTED) ? PX_OK : PX_NONFATAL);
1968118Sjchu }
1969118Sjchu 
197027Sjchu /* PEC ILU none - see io erpt doc, section 3.1 */
197127Sjchu PX_ERPT_SEND_DEC(pec_ilu)
197227Sjchu {
197327Sjchu 	char		buf[FM_MAX_CLASS];
1974739Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(bit);
197527Sjchu 
197627Sjchu 	(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
197727Sjchu 	ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
197827Sjchu 	    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
1979739Sjchu 	    FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
198027Sjchu 	    FIRE_ILU_ELE, DATA_TYPE_UINT64,
198127Sjchu 	    CSR_XR(csr_base, ILU_ERROR_LOG_ENABLE),
198227Sjchu 	    FIRE_ILU_IE, DATA_TYPE_UINT64,
198327Sjchu 	    CSR_XR(csr_base, ILU_INTERRUPT_ENABLE),
198427Sjchu 	    FIRE_ILU_IS, DATA_TYPE_UINT64,
198527Sjchu 	    ss_reg,
198627Sjchu 	    FIRE_ILU_ESS, DATA_TYPE_UINT64,
198727Sjchu 	    CSR_XR(csr_base, ILU_ERROR_STATUS_SET),
198827Sjchu 	    NULL);
198927Sjchu 
199027Sjchu 	return (PX_OK);
199127Sjchu }
199227Sjchu 
1993383Set142600 /* PCIEX UE Errors */
1994383Set142600 /* ARGSUSED */
1995671Skrishnae int
1996383Set142600 px_err_pciex_ue_handle(dev_info_t *rpdip, caddr_t csr_base,
1997383Set142600 	ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
1998383Set142600 	px_err_bit_desc_t *err_bit_descr)
1999383Set142600 {
2000383Set142600 	uint32_t	mask = (uint32_t)BITMASK(err_bit_descr->bit);
2001383Set142600 
2002383Set142600 	return ((err_bit_descr->bit >= 32 && px_fabric_die_rc_ue_gos) ?
2003383Set142600 	    PX_FATAL_GOS : PX_FABRIC_ERR_SEV(mask, px_fabric_die_rc_ue,
2004383Set142600 		px_fabric_die_rc_ue_gos));
2005383Set142600 }
2006383Set142600 
2007383Set142600 /* PCI-E Uncorrectable Errors - see io erpt doc, section 3.2 */
2008383Set142600 PX_ERPT_SEND_DEC(pciex_rx_ue)
2009383Set142600 {
2010383Set142600 	char		buf[FM_MAX_CLASS];
2011739Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(bit);
2012383Set142600 
2013383Set142600 	(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
2014383Set142600 	ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
2015383Set142600 	    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
2016739Sjchu 	    FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
2017383Set142600 	    FIRE_TLU_UELE, DATA_TYPE_UINT64,
2018383Set142600 	    CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_LOG_ENABLE),
2019383Set142600 	    FIRE_TLU_UIE, DATA_TYPE_UINT64,
2020383Set142600 	    CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_INTERRUPT_ENABLE),
2021383Set142600 	    FIRE_TLU_UIS, DATA_TYPE_UINT64,
2022383Set142600 	    ss_reg,
2023383Set142600 	    FIRE_TLU_UESS, DATA_TYPE_UINT64,
2024383Set142600 	    CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_STATUS_SET),
2025383Set142600 	    FIRE_TLU_RUEH1L, DATA_TYPE_UINT64,
2026383Set142600 	    CSR_XR(csr_base, TLU_RECEIVE_UNCORRECTABLE_ERROR_HEADER1_LOG),
2027383Set142600 	    FIRE_TLU_RUEH2L, DATA_TYPE_UINT64,
2028383Set142600 	    CSR_XR(csr_base, TLU_RECEIVE_UNCORRECTABLE_ERROR_HEADER2_LOG),
2029383Set142600 	    NULL);
2030383Set142600 
2031383Set142600 	return (PX_OK);
2032383Set142600 }
2033383Set142600 
2034383Set142600 /* PCI-E Uncorrectable Errors - see io erpt doc, section 3.3 */
2035383Set142600 PX_ERPT_SEND_DEC(pciex_tx_ue)
2036383Set142600 {
2037383Set142600 	char		buf[FM_MAX_CLASS];
2038739Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(bit);
2039383Set142600 
2040383Set142600 	(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
2041383Set142600 	ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
2042383Set142600 	    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
2043739Sjchu 	    FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
2044383Set142600 	    FIRE_TLU_UELE, DATA_TYPE_UINT64,
2045383Set142600 	    CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_LOG_ENABLE),
2046383Set142600 	    FIRE_TLU_UIE, DATA_TYPE_UINT64,
2047383Set142600 	    CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_INTERRUPT_ENABLE),
2048383Set142600 	    FIRE_TLU_UIS, DATA_TYPE_UINT64,
2049383Set142600 	    ss_reg,
2050383Set142600 	    FIRE_TLU_UESS, DATA_TYPE_UINT64,
2051383Set142600 	    CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_STATUS_SET),
2052383Set142600 	    FIRE_TLU_TUEH1L, DATA_TYPE_UINT64,
2053383Set142600 	    CSR_XR(csr_base, TLU_TRANSMIT_UNCORRECTABLE_ERROR_HEADER1_LOG),
2054383Set142600 	    FIRE_TLU_TUEH2L, DATA_TYPE_UINT64,
2055383Set142600 	    CSR_XR(csr_base, TLU_TRANSMIT_UNCORRECTABLE_ERROR_HEADER2_LOG),
2056383Set142600 	    NULL);
2057383Set142600 
2058383Set142600 	return (PX_OK);
2059383Set142600 }
2060383Set142600 
2061383Set142600 /* PCI-E Uncorrectable Errors - see io erpt doc, section 3.4 */
2062383Set142600 PX_ERPT_SEND_DEC(pciex_rx_tx_ue)
2063383Set142600 {
2064383Set142600 	char		buf[FM_MAX_CLASS];
2065739Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(bit);
2066383Set142600 
2067383Set142600 	(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
2068383Set142600 	ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
2069383Set142600 	    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
2070739Sjchu 	    FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
2071383Set142600 	    FIRE_TLU_UELE, DATA_TYPE_UINT64,
2072383Set142600 	    CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_LOG_ENABLE),
2073383Set142600 	    FIRE_TLU_UIE, DATA_TYPE_UINT64,
2074383Set142600 	    CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_INTERRUPT_ENABLE),
2075383Set142600 	    FIRE_TLU_UIS, DATA_TYPE_UINT64,
2076383Set142600 	    ss_reg,
2077383Set142600 	    FIRE_TLU_UESS, DATA_TYPE_UINT64,
2078383Set142600 	    CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_STATUS_SET),
2079383Set142600 	    FIRE_TLU_RUEH1L, DATA_TYPE_UINT64,
2080383Set142600 	    CSR_XR(csr_base, TLU_RECEIVE_UNCORRECTABLE_ERROR_HEADER1_LOG),
2081383Set142600 	    FIRE_TLU_RUEH2L, DATA_TYPE_UINT64,
2082383Set142600 	    CSR_XR(csr_base, TLU_RECEIVE_UNCORRECTABLE_ERROR_HEADER2_LOG),
2083383Set142600 	    FIRE_TLU_TUEH1L, DATA_TYPE_UINT64,
2084383Set142600 	    CSR_XR(csr_base, TLU_TRANSMIT_UNCORRECTABLE_ERROR_HEADER1_LOG),
2085383Set142600 	    FIRE_TLU_TUEH2L, DATA_TYPE_UINT64,
2086383Set142600 	    CSR_XR(csr_base, TLU_TRANSMIT_UNCORRECTABLE_ERROR_HEADER2_LOG),
2087383Set142600 	    NULL);
2088383Set142600 
2089383Set142600 	return (PX_OK);
2090383Set142600 }
2091383Set142600 
2092383Set142600 /* PCI-E Uncorrectable Errors - see io erpt doc, section 3.5 */
2093383Set142600 PX_ERPT_SEND_DEC(pciex_ue)
2094383Set142600 {
2095383Set142600 	char		buf[FM_MAX_CLASS];
2096739Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(bit);
2097383Set142600 
2098383Set142600 	(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
2099383Set142600 	ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
2100383Set142600 	    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
2101739Sjchu 	    FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
2102383Set142600 	    FIRE_TLU_UELE, DATA_TYPE_UINT64,
2103383Set142600 	    CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_LOG_ENABLE),
2104383Set142600 	    FIRE_TLU_UIE, DATA_TYPE_UINT64,
2105383Set142600 	    CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_INTERRUPT_ENABLE),
2106383Set142600 	    FIRE_TLU_UIS, DATA_TYPE_UINT64,
2107383Set142600 	    ss_reg,
2108383Set142600 	    FIRE_TLU_UESS, DATA_TYPE_UINT64,
2109383Set142600 	    CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_STATUS_SET),
2110383Set142600 	    NULL);
2111383Set142600 
2112383Set142600 	return (PX_OK);
2113383Set142600 }
2114383Set142600 
2115383Set142600 /* PCIEX UE Errors */
2116383Set142600 /* ARGSUSED */
2117671Skrishnae int
2118383Set142600 px_err_pciex_ce_handle(dev_info_t *rpdip, caddr_t csr_base,
2119383Set142600 	ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
2120383Set142600 	px_err_bit_desc_t *err_bit_descr)
2121383Set142600 {
2122383Set142600 	uint32_t	mask = (uint32_t)BITMASK(err_bit_descr->bit);
2123383Set142600 
2124383Set142600 	return ((err_bit_descr->bit >= 32 && px_fabric_die_rc_ce_gos) ?
2125383Set142600 	    PX_FATAL_GOS : PX_FABRIC_ERR_SEV(mask, px_fabric_die_rc_ce,
2126383Set142600 		px_fabric_die_rc_ce_gos));
2127383Set142600 }
2128383Set142600 
212927Sjchu /* PCI-E Correctable Errors - see io erpt doc, section 3.6 */
213027Sjchu PX_ERPT_SEND_DEC(pciex_ce)
213127Sjchu {
213227Sjchu 	char		buf[FM_MAX_CLASS];
2133739Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(bit);
213427Sjchu 
213527Sjchu 	(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
213627Sjchu 	ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
213727Sjchu 	    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
2138739Sjchu 	    FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
213927Sjchu 	    FIRE_TLU_CELE, DATA_TYPE_UINT64,
214027Sjchu 	    CSR_XR(csr_base, TLU_CORRECTABLE_ERROR_LOG_ENABLE),
214127Sjchu 	    FIRE_TLU_CIE, DATA_TYPE_UINT64,
214227Sjchu 	    CSR_XR(csr_base, TLU_CORRECTABLE_ERROR_INTERRUPT_ENABLE),
214327Sjchu 	    FIRE_TLU_CIS, DATA_TYPE_UINT64,
214427Sjchu 	    ss_reg,
214527Sjchu 	    FIRE_TLU_CESS, DATA_TYPE_UINT64,
214627Sjchu 	    CSR_XR(csr_base, TLU_CORRECTABLE_ERROR_STATUS_SET),
214727Sjchu 	    NULL);
214827Sjchu 
214927Sjchu 	return (PX_OK);
215027Sjchu }
215127Sjchu 
215227Sjchu /* TLU Other Event Status (receive only) - see io erpt doc, section 3.7 */
215327Sjchu PX_ERPT_SEND_DEC(pciex_rx_oe)
215427Sjchu {
215527Sjchu 	char		buf[FM_MAX_CLASS];
2156739Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(bit);
215727Sjchu 
215827Sjchu 	(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
215927Sjchu 	ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
216027Sjchu 	    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
2161739Sjchu 	    FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
216227Sjchu 	    FIRE_TLU_OEELE, DATA_TYPE_UINT64,
216327Sjchu 	    CSR_XR(csr_base, TLU_OTHER_EVENT_LOG_ENABLE),
216427Sjchu 	    FIRE_TLU_OEIE, DATA_TYPE_UINT64,
216527Sjchu 	    CSR_XR(csr_base, TLU_OTHER_EVENT_INTERRUPT_ENABLE),
216627Sjchu 	    FIRE_TLU_OEIS, DATA_TYPE_UINT64,
216727Sjchu 	    ss_reg,
216827Sjchu 	    FIRE_TLU_OEESS, DATA_TYPE_UINT64,
216927Sjchu 	    CSR_XR(csr_base, TLU_OTHER_EVENT_STATUS_SET),
217027Sjchu 	    FIRE_TLU_RUEH1L, DATA_TYPE_UINT64,
217127Sjchu 	    CSR_XR(csr_base, TLU_RECEIVE_OTHER_EVENT_HEADER1_LOG),
2172260Set142600 	    FIRE_TLU_RUEH2L, DATA_TYPE_UINT64,
217327Sjchu 	    CSR_XR(csr_base, TLU_RECEIVE_OTHER_EVENT_HEADER2_LOG),
217427Sjchu 	    NULL);
217527Sjchu 
217627Sjchu 	return (PX_OK);
217727Sjchu }
217827Sjchu 
217927Sjchu /* TLU Other Event Status (rx + tx) - see io erpt doc, section 3.8 */
218027Sjchu PX_ERPT_SEND_DEC(pciex_rx_tx_oe)
218127Sjchu {
218227Sjchu 	char		buf[FM_MAX_CLASS];
2183739Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(bit);
218427Sjchu 
218527Sjchu 	(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
218627Sjchu 	ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
218727Sjchu 	    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
2188739Sjchu 	    FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
218927Sjchu 	    FIRE_TLU_OEELE, DATA_TYPE_UINT64,
219027Sjchu 	    CSR_XR(csr_base, TLU_OTHER_EVENT_LOG_ENABLE),
219127Sjchu 	    FIRE_TLU_OEIE, DATA_TYPE_UINT64,
219227Sjchu 	    CSR_XR(csr_base, TLU_OTHER_EVENT_INTERRUPT_ENABLE),
219327Sjchu 	    FIRE_TLU_OEIS, DATA_TYPE_UINT64,
219427Sjchu 	    ss_reg,
219527Sjchu 	    FIRE_TLU_OEESS, DATA_TYPE_UINT64,
219627Sjchu 	    CSR_XR(csr_base, TLU_OTHER_EVENT_STATUS_SET),
219727Sjchu 	    FIRE_TLU_ROEEH1L, DATA_TYPE_UINT64,
219827Sjchu 	    CSR_XR(csr_base, TLU_RECEIVE_OTHER_EVENT_HEADER1_LOG),
219927Sjchu 	    FIRE_TLU_ROEEH2L, DATA_TYPE_UINT64,
220027Sjchu 	    CSR_XR(csr_base, TLU_RECEIVE_OTHER_EVENT_HEADER2_LOG),
220127Sjchu 	    FIRE_TLU_TOEEH1L, DATA_TYPE_UINT64,
220227Sjchu 	    CSR_XR(csr_base, TLU_TRANSMIT_OTHER_EVENT_HEADER1_LOG),
2203260Set142600 	    FIRE_TLU_TOEEH2L, DATA_TYPE_UINT64,
220427Sjchu 	    CSR_XR(csr_base, TLU_TRANSMIT_OTHER_EVENT_HEADER2_LOG),
220527Sjchu 	    NULL);
220627Sjchu 
220727Sjchu 	return (PX_OK);
220827Sjchu }
220927Sjchu 
221027Sjchu /* TLU Other Event - see io erpt doc, section 3.9 */
221127Sjchu PX_ERPT_SEND_DEC(pciex_oe)
221227Sjchu {
2213739Sjchu 	char		buf[FM_MAX_CLASS];
2214739Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(bit);
221527Sjchu 
221627Sjchu 	(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
221727Sjchu 	ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
221827Sjchu 	    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
2219739Sjchu 	    FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
222027Sjchu 	    FIRE_TLU_OEELE, DATA_TYPE_UINT64,
222127Sjchu 	    CSR_XR(csr_base, TLU_OTHER_EVENT_LOG_ENABLE),
222227Sjchu 	    FIRE_TLU_OEIE, DATA_TYPE_UINT64,
222327Sjchu 	    CSR_XR(csr_base, TLU_OTHER_EVENT_INTERRUPT_ENABLE),
222427Sjchu 	    FIRE_TLU_OEIS, DATA_TYPE_UINT64,
222527Sjchu 	    ss_reg,
222627Sjchu 	    FIRE_TLU_OEESS, DATA_TYPE_UINT64,
222727Sjchu 	    CSR_XR(csr_base, TLU_OTHER_EVENT_STATUS_SET),
222827Sjchu 	    NULL);
222927Sjchu 
223027Sjchu 	return (PX_OK);
223127Sjchu }
2232