xref: /onnv-gate/usr/src/uts/sun4u/io/px/px_err.c (revision 3613:d3ad3e7455e2)
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 /*
223421Sjchu  * Copyright 2007 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[] = {
1363274Set142600 	/* JBC FATAL */
1373274Set142600 	{ JBC_BIT_DESC(MB_PEA,	hw_reset,	jbc_fatal) },
1383274Set142600 	{ JBC_BIT_DESC(CPE,	hw_reset,	jbc_fatal) },
1393274Set142600 	{ JBC_BIT_DESC(APE,	hw_reset,	jbc_fatal) },
1403274Set142600 	{ JBC_BIT_DESC(PIO_CPE,	hw_reset,	jbc_fatal) },
1413274Set142600 	{ JBC_BIT_DESC(JTCEEW,	hw_reset,	jbc_fatal) },
1423274Set142600 	{ JBC_BIT_DESC(JTCEEI,	hw_reset,	jbc_fatal) },
1433274Set142600 	{ JBC_BIT_DESC(JTCEER,	hw_reset,	jbc_fatal) },
14427Sjchu 
1453274Set142600 	/* JBC MERGE */
14627Sjchu 	{ JBC_BIT_DESC(MB_PER,	jbc_merge,	jbc_merge) },
14727Sjchu 	{ JBC_BIT_DESC(MB_PEW,	jbc_merge,	jbc_merge) },
14827Sjchu 
1493274Set142600 	/* JBC Jbusint IN */
1503274Set142600 	{ JBC_BIT_DESC(UE_ASYN,	panic,		jbc_in) },
1513274Set142600 	{ JBC_BIT_DESC(CE_ASYN,	no_error,	jbc_in) },
1523274Set142600 	{ JBC_BIT_DESC(JTE,	panic,		jbc_in) },
1533274Set142600 	{ JBC_BIT_DESC(JBE,	panic,		jbc_in) },
1543274Set142600 	{ JBC_BIT_DESC(JUE,	panic,		jbc_in) },
1553274Set142600 	{ JBC_BIT_DESC(ICISE,	panic,		jbc_in) },
15627Sjchu 	{ JBC_BIT_DESC(WR_DPE,	jbc_jbusint_in,	jbc_in) },
15727Sjchu 	{ JBC_BIT_DESC(RD_DPE,	jbc_jbusint_in,	jbc_in) },
1583274Set142600 	{ JBC_BIT_DESC(ILL_BMW,	panic,		jbc_in) },
1593274Set142600 	{ JBC_BIT_DESC(ILL_BMR,	panic,		jbc_in) },
1603274Set142600 	{ JBC_BIT_DESC(BJC,	panic,		jbc_in) },
16127Sjchu 
1623274Set142600 	/* JBC Jbusint Out */
1633274Set142600 	{ JBC_BIT_DESC(IJP,	panic,		jbc_out) },
16427Sjchu 
1652276Sschwartz 	/*
1663274Set142600 	 * JBC Dmcint ODCD
1672276Sschwartz 	 *
1682276Sschwartz 	 * Error bits which can be set via a bad PCItool access go through
1692276Sschwartz 	 * jbc_safe_acc instead.
1702276Sschwartz 	 */
1712276Sschwartz 	{ JBC_BIT_DESC(PIO_UNMAP_RD,	jbc_safe_acc,		jbc_odcd) },
1722276Sschwartz 	{ JBC_BIT_DESC(ILL_ACC_RD,	jbc_safe_acc,		jbc_odcd) },
1732276Sschwartz 	{ JBC_BIT_DESC(PIO_UNMAP,	jbc_safe_acc,		jbc_odcd) },
17427Sjchu 	{ JBC_BIT_DESC(PIO_DPE,		jbc_dmcint_odcd,	jbc_odcd) },
1753274Set142600 	{ JBC_BIT_DESC(PIO_CPE,		hw_reset,		jbc_odcd) },
1762276Sschwartz 	{ JBC_BIT_DESC(ILL_ACC,		jbc_safe_acc,		jbc_odcd) },
17727Sjchu 
1783274Set142600 	/* JBC Dmcint IDC */
1793274Set142600 	{ JBC_BIT_DESC(UNSOL_RD,	no_panic,	jbc_idc) },
1803274Set142600 	{ JBC_BIT_DESC(UNSOL_INTR,	no_panic,	jbc_idc) },
18127Sjchu 
1823274Set142600 	/* JBC CSR */
1833274Set142600 	{ JBC_BIT_DESC(EBUS_TO,		panic,		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  */
2053274Set142600 	{ UBC_BIT_DESC(DMARDUEA,	no_panic,	ubc_fatal) },
2063274Set142600 	{ UBC_BIT_DESC(DMAWTUEA,	panic,		ubc_fatal) },
2073274Set142600 	{ UBC_BIT_DESC(MEMRDAXA,	panic,		ubc_fatal) },
2083274Set142600 	{ UBC_BIT_DESC(MEMWTAXA,	panic,		ubc_fatal) },
2093274Set142600 	{ UBC_BIT_DESC(DMARDUEB,	no_panic,	ubc_fatal) },
2103274Set142600 	{ UBC_BIT_DESC(DMAWTUEB,	panic,		ubc_fatal) },
2113274Set142600 	{ UBC_BIT_DESC(MEMRDAXB,	panic,		ubc_fatal) },
2123274Set142600 	{ UBC_BIT_DESC(MEMWTAXB,	panic,		ubc_fatal) },
2133274Set142600 	{ UBC_BIT_DESC(PIOWTUE,		panic,		ubc_fatal) },
2143274Set142600 	{ UBC_BIT_DESC(PIOWBEUE,	panic,		ubc_fatal) },
2153274Set142600 	{ UBC_BIT_DESC(PIORBEUE,	panic,		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[] = {
2453274Set142600 	/* DMC IMU RDS */
2463274Set142600 	{ IMU_BIT_DESC(MSI_MAL_ERR,		panic,		imu_rds) },
2473274Set142600 	{ IMU_BIT_DESC(MSI_PAR_ERR,		panic,		imu_rds) },
2483274Set142600 	{ IMU_BIT_DESC(PMEACK_MES_NOT_EN,	panic,		imu_rds) },
2493274Set142600 	{ IMU_BIT_DESC(PMPME_MES_NOT_EN,	panic,		imu_rds) },
2503274Set142600 	{ IMU_BIT_DESC(FATAL_MES_NOT_EN,	panic,		imu_rds) },
2513274Set142600 	{ IMU_BIT_DESC(NONFATAL_MES_NOT_EN,	panic,		imu_rds) },
2523274Set142600 	{ IMU_BIT_DESC(COR_MES_NOT_EN,		panic,		imu_rds) },
2533274Set142600 	{ IMU_BIT_DESC(MSI_NOT_EN,		panic,		imu_rds) },
25427Sjchu 
2553274Set142600 	/* DMC IMU SCS */
2563421Sjchu 	{ IMU_BIT_DESC(EQ_NOT_EN,		panic,		imu_scs) },
25727Sjchu 
2583274Set142600 	/* DMC IMU */
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[] = {
2773274Set142600 	/* DMC MMU TFAR/TFSR */
27827Sjchu 	{ MMU_BIT_DESC(BYP_ERR,		mmu_rbne,	mmu_tfar_tfsr) },
27927Sjchu 	{ MMU_BIT_DESC(BYP_OOR,		mmu_tfa,	mmu_tfar_tfsr) },
2803274Set142600 	{ MMU_BIT_DESC(TRN_ERR,		panic,		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) },
2843274Set142600 	{ MMU_BIT_DESC(TTC_DPE,		mmu_parity,	mmu_tfar_tfsr) },
2853274Set142600 	{ MMU_BIT_DESC(TBW_DME,		panic,		mmu_tfar_tfsr) },
2863274Set142600 	{ MMU_BIT_DESC(TBW_UDE,		panic,		mmu_tfar_tfsr) },
2873274Set142600 	{ MMU_BIT_DESC(TBW_ERR,		panic,		mmu_tfar_tfsr) },
2883274Set142600 	{ MMU_BIT_DESC(TBW_DPE,		mmu_parity,	mmu_tfar_tfsr) },
28927Sjchu 
2903274Set142600 	/* DMC MMU */
2913274Set142600 	{ MMU_BIT_DESC(TTC_CAE,		panic,		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[] = {
3113274Set142600 	/* PEC ILU none */
3123274Set142600 	{ ILU_BIT_DESC(IHB_PE,		panic,		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[] = {
3453274Set142600 	/* PCI-E Receive Uncorrectable Errors */
346383Set142600 	{ TLU_UC_BIT_DESC(UR,		pciex_ue,	pciex_rx_ue) },
347383Set142600 	{ TLU_UC_BIT_DESC(UC,		pciex_ue,	pciex_rx_ue) },
34827Sjchu 
3493274Set142600 	/* PCI-E Transmit Uncorrectable Errors */
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 
3543274Set142600 	/* PCI-E Rx/Tx Uncorrectable Errors */
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 
3583274Set142600 	/* Other PCI-E Uncorrectable Errors */
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[] = {
3873274Set142600 	/* PCI-E Correctable Errors */
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[] = {
4223274Set142600 	/* TLU Other Event Status (receive only) */
4233274Set142600 	{ TLU_OE_BIT_DESC(MRC,		hw_reset,	pciex_rx_oe) },
4243274Set142600 
4253274Set142600 	/* TLU Other Event Status (rx + tx) */
4263274Set142600 	{ TLU_OE_BIT_DESC(WUC,		wuc_ruc,	pciex_rx_tx_oe) },
4273274Set142600 	{ TLU_OE_BIT_DESC(RUC,		wuc_ruc,	pciex_rx_tx_oe) },
4283274Set142600 	{ TLU_OE_BIT_DESC(CRS,		no_panic,	pciex_rx_tx_oe) },
42927Sjchu 
4303274Set142600 	/* TLU Other Event */
4313274Set142600 	{ TLU_OE_BIT_DESC(IIP,		panic,		pciex_oe) },
4323274Set142600 	{ TLU_OE_BIT_DESC(EDP,		panic,		pciex_oe) },
4333274Set142600 	{ TLU_OE_BIT_DESC(EHP,		panic,		pciex_oe) },
4343274Set142600 	{ TLU_OE_OB_BIT_DESC(TLUEITMO,	panic,		pciex_oe) },
4353274Set142600 	{ TLU_OE_BIT_DESC(LIN,		no_panic,	pciex_oe) },
4363274Set142600 	{ TLU_OE_BIT_DESC(LRS,		no_panic,	pciex_oe) },
4371147Sjchu 	{ TLU_OE_BIT_DESC(LDN,		tlu_ldn,	pciex_oe) },
4381147Sjchu 	{ TLU_OE_BIT_DESC(LUP,		tlu_lup,	pciex_oe) },
4393274Set142600 	{ TLU_OE_BIT_DESC(ERU,		panic,		pciex_oe) },
4403274Set142600 	{ TLU_OE_BIT_DESC(ERO,		panic,		pciex_oe) },
4413274Set142600 	{ TLU_OE_BIT_DESC(EMP,		panic,		pciex_oe) },
4423274Set142600 	{ TLU_OE_BIT_DESC(EPE,		panic,		pciex_oe) },
4433274Set142600 	{ TLU_OE_BIT_DESC(ERP,		panic,		pciex_oe) },
4443274Set142600 	{ TLU_OE_BIT_DESC(EIP,		panic,		pciex_oe) }
44527Sjchu };
44627Sjchu 
44727Sjchu #define	px_err_tlu_oe_keys \
44827Sjchu 	(sizeof (px_err_tlu_oe_tbl)) / (sizeof (px_err_bit_desc_t))
44927Sjchu 
4501772Sjl139090 
45127Sjchu /*
45227Sjchu  * All the following tables below are for LPU Interrupts.  These interrupts
45327Sjchu  * are *NOT* error interrupts, but event status interrupts.
45427Sjchu  *
45527Sjchu  * These events are probably of most interest to:
45627Sjchu  * o Hotplug
45727Sjchu  * o Power Management
45827Sjchu  * o etc...
45927Sjchu  *
46027Sjchu  * There are also a few events that would be interresting for FMA.
46127Sjchu  * Again none of the regiseters below state that an error has occured
46227Sjchu  * or that data has been lost.  If anything, they give status that an
46327Sjchu  * error is *about* to occur.  examples
46427Sjchu  * o INT_SKP_ERR - indicates clock between fire and child is too far
46527Sjchu  *		   off and is most unlikely able to compensate
46627Sjchu  * o INT_TX_PAR_ERR - A parity error occured in ONE lane.  This is
46727Sjchu  *		      HW recoverable, but will like end up as a future
46827Sjchu  *		      fabric error as well.
46927Sjchu  *
47027Sjchu  * For now, we don't care about any of these errors and should be ignore,
47127Sjchu  * but cleared.
47227Sjchu  */
47327Sjchu 
47427Sjchu /* LPU Link Interrupt Table */
47527Sjchu #define	LPUL_BIT_DESC(bit, hdl, erpt) \
47627Sjchu 	LPU_LINK_LAYER_INTERRUPT_AND_STATUS_INT_ ## bit, \
47727Sjchu 	0, \
47827Sjchu 	NULL, \
47927Sjchu 	NULL, \
48027Sjchu 	""
48127Sjchu px_err_bit_desc_t px_err_lpul_tbl[] = {
48227Sjchu 	{ LPUL_BIT_DESC(LINK_ERR_ACT,	NULL,		NULL) }
48327Sjchu };
48427Sjchu #define	px_err_lpul_keys \
48527Sjchu 	(sizeof (px_err_lpul_tbl)) / (sizeof (px_err_bit_desc_t))
48627Sjchu 
48727Sjchu /* LPU Physical Interrupt Table */
48827Sjchu #define	LPUP_BIT_DESC(bit, hdl, erpt) \
48927Sjchu 	LPU_PHY_LAYER_INTERRUPT_AND_STATUS_INT_ ## bit, \
49027Sjchu 	0, \
49127Sjchu 	NULL, \
49227Sjchu 	NULL, \
49327Sjchu 	""
49427Sjchu px_err_bit_desc_t px_err_lpup_tbl[] = {
49527Sjchu 	{ LPUP_BIT_DESC(PHY_LAYER_ERR,	NULL,		NULL) }
49627Sjchu };
49727Sjchu #define	px_err_lpup_keys \
49827Sjchu 	(sizeof (px_err_lpup_tbl)) / (sizeof (px_err_bit_desc_t))
49927Sjchu 
50027Sjchu /* LPU Receive Interrupt Table */
50127Sjchu #define	LPUR_BIT_DESC(bit, hdl, erpt) \
50227Sjchu 	LPU_RECEIVE_PHY_INTERRUPT_AND_STATUS_INT_ ## bit, \
50327Sjchu 	0, \
50427Sjchu 	NULL, \
50527Sjchu 	NULL, \
50627Sjchu 	""
50727Sjchu px_err_bit_desc_t px_err_lpur_tbl[] = {
50827Sjchu 	{ LPUR_BIT_DESC(RCV_PHY,	NULL,		NULL) }
50927Sjchu };
51027Sjchu #define	px_err_lpur_keys \
51127Sjchu 	(sizeof (px_err_lpur_tbl)) / (sizeof (px_err_bit_desc_t))
51227Sjchu 
51327Sjchu /* LPU Transmit Interrupt Table */
51427Sjchu #define	LPUX_BIT_DESC(bit, hdl, erpt) \
51527Sjchu 	LPU_TRANSMIT_PHY_INTERRUPT_AND_STATUS_INT_ ## bit, \
51627Sjchu 	0, \
51727Sjchu 	NULL, \
51827Sjchu 	NULL, \
51927Sjchu 	""
52027Sjchu px_err_bit_desc_t px_err_lpux_tbl[] = {
52127Sjchu 	{ LPUX_BIT_DESC(UNMSK,		NULL,		NULL) }
52227Sjchu };
52327Sjchu #define	px_err_lpux_keys \
52427Sjchu 	(sizeof (px_err_lpux_tbl)) / (sizeof (px_err_bit_desc_t))
52527Sjchu 
52627Sjchu /* LPU LTSSM Interrupt Table */
52727Sjchu #define	LPUS_BIT_DESC(bit, hdl, erpt) \
52827Sjchu 	LPU_LTSSM_INTERRUPT_AND_STATUS_INT_ ## bit, \
52927Sjchu 	0, \
53027Sjchu 	NULL, \
53127Sjchu 	NULL, \
53227Sjchu 	""
53327Sjchu px_err_bit_desc_t px_err_lpus_tbl[] = {
53427Sjchu 	{ LPUS_BIT_DESC(ANY,		NULL,		NULL) }
53527Sjchu };
53627Sjchu #define	px_err_lpus_keys \
53727Sjchu 	(sizeof (px_err_lpus_tbl)) / (sizeof (px_err_bit_desc_t))
53827Sjchu 
53927Sjchu /* LPU Gigablaze Glue Interrupt Table */
54027Sjchu #define	LPUG_BIT_DESC(bit, hdl, erpt) \
54127Sjchu 	LPU_GIGABLAZE_GLUE_INTERRUPT_AND_STATUS_INT_ ## bit, \
54227Sjchu 	0, \
54327Sjchu 	NULL, \
54427Sjchu 	NULL, \
54527Sjchu 	""
54627Sjchu px_err_bit_desc_t px_err_lpug_tbl[] = {
54727Sjchu 	{ LPUG_BIT_DESC(GLOBL_UNMSK,	NULL,		NULL) }
54827Sjchu };
54927Sjchu #define	px_err_lpug_keys \
55027Sjchu 	(sizeof (px_err_lpug_tbl)) / (sizeof (px_err_bit_desc_t))
55127Sjchu 
55227Sjchu 
55327Sjchu /* Mask and Tables */
5542509Sschwartz #define	MnT6X(pre) \
55527Sjchu 	&px_ ## pre ## _intr_mask, \
55627Sjchu 	&px_ ## pre ## _log_mask, \
55727Sjchu 	&px_ ## pre ## _count_mask, \
55827Sjchu 	px_err_ ## pre ## _tbl, \
55927Sjchu 	px_err_ ## pre ## _keys, \
5602509Sschwartz 	PX_REG_XBC, \
56127Sjchu 	0
56227Sjchu 
5632509Sschwartz #define	MnT6(pre) \
5641772Sjl139090 	&px_ ## pre ## _intr_mask, \
5651772Sjl139090 	&px_ ## pre ## _log_mask, \
5661772Sjl139090 	&px_ ## pre ## _count_mask, \
5672509Sschwartz 	px_err_ ## pre ## _tbl, \
5682509Sschwartz 	px_err_ ## pre ## _keys, \
5692509Sschwartz 	PX_REG_CSR, \
5701772Sjl139090 	0
5711772Sjl139090 
57227Sjchu /* LPU Registers Addresses */
57327Sjchu #define	LR4(pre) \
57427Sjchu 	NULL, \
57527Sjchu 	LPU_ ## pre ## _INTERRUPT_MASK, \
57627Sjchu 	LPU_ ## pre ## _INTERRUPT_AND_STATUS, \
57727Sjchu 	LPU_ ## pre ## _INTERRUPT_AND_STATUS
57827Sjchu 
57927Sjchu /* LPU Registers Addresses with Irregularities */
58027Sjchu #define	LR4_FIXME(pre) \
58127Sjchu 	NULL, \
58227Sjchu 	LPU_ ## pre ## _INTERRUPT_MASK, \
58327Sjchu 	LPU_ ## pre ## _LAYER_INTERRUPT_AND_STATUS, \
58427Sjchu 	LPU_ ## pre ## _LAYER_INTERRUPT_AND_STATUS
58527Sjchu 
58627Sjchu /* TLU Registers Addresses */
58727Sjchu #define	TR4(pre) \
58827Sjchu 	TLU_ ## pre ## _LOG_ENABLE, \
58927Sjchu 	TLU_ ## pre ## _INTERRUPT_ENABLE, \
59027Sjchu 	TLU_ ## pre ## _INTERRUPT_STATUS, \
59127Sjchu 	TLU_ ## pre ## _STATUS_CLEAR
59227Sjchu 
5931772Sjl139090 /* Registers Addresses for JBC, UBC, MMU, IMU and ILU */
59427Sjchu #define	R4(pre) \
59527Sjchu 	pre ## _ERROR_LOG_ENABLE, \
59627Sjchu 	pre ## _INTERRUPT_ENABLE, \
59727Sjchu 	pre ## _INTERRUPT_STATUS, \
59827Sjchu 	pre ## _ERROR_STATUS_CLEAR
59927Sjchu 
6002509Sschwartz /* Bits in chip_mask, set according to type. */
6012509Sschwartz #define	CHP_O	BITMASK(PX_CHIP_OBERON)
6022509Sschwartz #define	CHP_F	BITMASK(PX_CHIP_FIRE)
6032509Sschwartz #define	CHP_FO	(CHP_F | CHP_O)
6042509Sschwartz 
60527Sjchu /*
60627Sjchu  * Register error handling tables.
60727Sjchu  * The ID Field (first field) is identified by an enum px_err_id_t.
60827Sjchu  * It is located in px_err.h
60927Sjchu  */
6102509Sschwartz static const
61127Sjchu px_err_reg_desc_t px_err_reg_tbl[] = {
6122509Sschwartz 	{ CHP_F,  MnT6X(jbc),	R4(JBC),		  "JBC Error"},
6132509Sschwartz 	{ CHP_O,  MnT6X(ubc),	R4(UBC),		  "UBC Error"},
6142509Sschwartz 	{ CHP_FO, MnT6(mmu),	R4(MMU),		  "MMU Error"},
6152509Sschwartz 	{ CHP_FO, MnT6(imu),	R4(IMU),		  "IMU Error"},
6162509Sschwartz 	{ CHP_FO, MnT6(tlu_ue),	TR4(UNCORRECTABLE_ERROR), "TLU UE"},
6172509Sschwartz 	{ CHP_FO, MnT6(tlu_ce),	TR4(CORRECTABLE_ERROR),	  "TLU CE"},
6182509Sschwartz 	{ CHP_FO, MnT6(tlu_oe),	TR4(OTHER_EVENT),	  "TLU OE"},
6192509Sschwartz 	{ CHP_FO, MnT6(ilu),	R4(ILU),		  "ILU Error"},
6202509Sschwartz 	{ CHP_F,  MnT6(lpul),	LR4(LINK_LAYER),	  "LPU Link Layer"},
6212509Sschwartz 	{ CHP_F,  MnT6(lpup),	LR4_FIXME(PHY),		  "LPU Phy Layer"},
6222509Sschwartz 	{ CHP_F,  MnT6(lpur),	LR4(RECEIVE_PHY),	  "LPU RX Phy Layer"},
6232509Sschwartz 	{ CHP_F,  MnT6(lpux),	LR4(TRANSMIT_PHY),	  "LPU TX Phy Layer"},
6242509Sschwartz 	{ CHP_F,  MnT6(lpus),	LR4(LTSSM),		  "LPU LTSSM"},
6252509Sschwartz 	{ CHP_F,  MnT6(lpug),	LR4(GIGABLAZE_GLUE),	  "LPU GigaBlaze Glue"},
62627Sjchu };
6272509Sschwartz 
6282509Sschwartz #define	PX_ERR_REG_KEYS	(sizeof (px_err_reg_tbl)) / (sizeof (px_err_reg_tbl[0]))
62927Sjchu 
63027Sjchu typedef struct px_err_ss {
63127Sjchu 	uint64_t err_status[PX_ERR_REG_KEYS];
63227Sjchu } px_err_ss_t;
63327Sjchu 
6343274Set142600 static void px_err_snapshot(px_t *px_p, px_err_ss_t *ss, int block);
63527Sjchu static int  px_err_erpt_and_clr(px_t *px_p, ddi_fm_error_t *derr,
63627Sjchu     px_err_ss_t *ss);
63727Sjchu static int  px_err_check_severity(px_t *px_p, ddi_fm_error_t *derr,
63827Sjchu     int err, int caller);
63927Sjchu 
64027Sjchu /*
64127Sjchu  * px_err_cb_intr:
6421772Sjl139090  * Interrupt handler for the JBC/UBC block.
64327Sjchu  * o lock
64427Sjchu  * o create derr
6453274Set142600  * o px_err_cmn_intr
64627Sjchu  * o unlock
64727Sjchu  * o handle error: fatal? fm_panic() : return INTR_CLAIMED)
64827Sjchu  */
64927Sjchu uint_t
65027Sjchu px_err_cb_intr(caddr_t arg)
65127Sjchu {
65227Sjchu 	px_fault_t	*px_fault_p = (px_fault_t *)arg;
65327Sjchu 	dev_info_t	*rpdip = px_fault_p->px_fh_dip;
65427Sjchu 	px_t		*px_p = DIP_TO_STATE(rpdip);
6553274Set142600 	int		err;
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 
6663274Set142600 	err = px_err_cmn_intr(px_p, &derr, PX_INTR_CALL, PX_FM_BLOCK_HOST);
66727Sjchu 	(void) px_lib_intr_setstate(rpdip, px_fault_p->px_fh_sysino,
66827Sjchu 	    INTR_IDLE_STATE);
66927Sjchu 
6701648Sjchu 	mutex_exit(&px_p->px_fm_mutex);
67127Sjchu 
6723274Set142600 	px_err_panic(err, PX_HB, PX_NO_ERROR);
67327Sjchu 
67427Sjchu 	return (DDI_INTR_CLAIMED);
67527Sjchu }
67627Sjchu 
67727Sjchu /*
67827Sjchu  * px_err_dmc_pec_intr:
67927Sjchu  * Interrupt handler for the DMC/PEC block.
68027Sjchu  * o lock
68127Sjchu  * o create derr
6823274Set142600  * o px_err_cmn_intr(leaf, with out cb)
6833274Set142600  * o pcie_scan_fabric (leaf)
68427Sjchu  * o unlock
68527Sjchu  * o handle error: fatal? fm_panic() : return INTR_CLAIMED)
68627Sjchu  */
68727Sjchu uint_t
68827Sjchu px_err_dmc_pec_intr(caddr_t arg)
68927Sjchu {
69027Sjchu 	px_fault_t	*px_fault_p = (px_fault_t *)arg;
69127Sjchu 	dev_info_t	*rpdip = px_fault_p->px_fh_dip;
69227Sjchu 	px_t		*px_p = DIP_TO_STATE(rpdip);
6933274Set142600 	int		rc_err, fab_err = PF_NO_PANIC;
69427Sjchu 	ddi_fm_error_t	derr;
69527Sjchu 
69627Sjchu 	/* Create the derr */
69727Sjchu 	bzero(&derr, sizeof (ddi_fm_error_t));
69827Sjchu 	derr.fme_version = DDI_FME_VERSION;
69927Sjchu 	derr.fme_ena = fm_ena_generate(0, FM_ENA_FMT1);
70027Sjchu 	derr.fme_flag = DDI_FM_ERR_UNEXPECTED;
70127Sjchu 
7021648Sjchu 	mutex_enter(&px_p->px_fm_mutex);
70327Sjchu 
70427Sjchu 	/* send ereport/handle/clear fire registers */
7053274Set142600 	rc_err = px_err_cmn_intr(px_p, &derr, PX_INTR_CALL, PX_FM_BLOCK_PCIE);
70627Sjchu 
70727Sjchu 	/* Check all child devices for errors */
7082476Sdwoods 	if (!px_lib_is_in_drain_state(px_p)) {
7093274Set142600 		fab_err = pf_scan_fabric(rpdip, &derr, px_p->px_dq_p,
7103274Set142600 		    &px_p->px_dq_tail);
7112476Sdwoods 	}
71227Sjchu 
71327Sjchu 	/* Set the interrupt state to idle */
71427Sjchu 	(void) px_lib_intr_setstate(rpdip, px_fault_p->px_fh_sysino,
71527Sjchu 	    INTR_IDLE_STATE);
71627Sjchu 
7171648Sjchu 	mutex_exit(&px_p->px_fm_mutex);
71827Sjchu 
7193274Set142600 	px_err_panic(rc_err, PX_RC, fab_err);
72027Sjchu 
72127Sjchu 	return (DDI_INTR_CLAIMED);
72227Sjchu }
72327Sjchu 
72427Sjchu /*
7252509Sschwartz  * Proper csr_base is responsibility of the caller. (Called from px_lib_dev_init
7262509Sschwartz  * via px_err_reg_setup_all for pcie error registers;  called from
7272509Sschwartz  * px_cb_add_intr for jbc/ubc from px_cb_attach.)
7282509Sschwartz  *
7292509Sschwartz  * Note: reg_id is passed in instead of reg_desc since this function is called
7302509Sschwartz  * from px_lib4u.c, which doesn't know about the structure of the table.
73127Sjchu  */
73227Sjchu void
7332509Sschwartz px_err_reg_enable(px_err_id_t reg_id, caddr_t csr_base)
73427Sjchu {
7352509Sschwartz 	const px_err_reg_desc_t	*reg_desc_p = &px_err_reg_tbl[reg_id];
7362509Sschwartz 	uint64_t 		intr_mask = *reg_desc_p->intr_mask_p;
7372509Sschwartz 	uint64_t 		log_mask = *reg_desc_p->log_mask_p;
73827Sjchu 
73927Sjchu 	/* Enable logs if it exists */
7402509Sschwartz 	if (reg_desc_p->log_addr != NULL)
7412509Sschwartz 		CSR_XS(csr_base, reg_desc_p->log_addr, log_mask);
74227Sjchu 
74327Sjchu 	/*
74427Sjchu 	 * For readability you in code you set 1 to enable an interrupt.
74527Sjchu 	 * But in Fire it's backwards.  You set 1 to *disable* an intr.
74627Sjchu 	 * Reverse the user tunable intr mask field.
74727Sjchu 	 *
74827Sjchu 	 * Disable All Errors
74927Sjchu 	 * Clear All Errors
75027Sjchu 	 * Enable Errors
75127Sjchu 	 */
7522509Sschwartz 	CSR_XS(csr_base, reg_desc_p->enable_addr, 0);
7532509Sschwartz 	CSR_XS(csr_base, reg_desc_p->clear_addr, -1);
7542509Sschwartz 	CSR_XS(csr_base, reg_desc_p->enable_addr, intr_mask);
7552509Sschwartz 	DBG(DBG_ATTACH, NULL, "%s Mask: 0x%llx\n", reg_desc_p->msg,
7562509Sschwartz 	    CSR_XR(csr_base, reg_desc_p->enable_addr));
7572509Sschwartz 	DBG(DBG_ATTACH, NULL, "%s Status: 0x%llx\n", reg_desc_p->msg,
7582509Sschwartz 	    CSR_XR(csr_base, reg_desc_p->status_addr));
7592509Sschwartz 	DBG(DBG_ATTACH, NULL, "%s Clear: 0x%llx\n", reg_desc_p->msg,
7602509Sschwartz 	    CSR_XR(csr_base, reg_desc_p->clear_addr));
7612509Sschwartz 	if (reg_desc_p->log_addr != NULL) {
7622509Sschwartz 		DBG(DBG_ATTACH, NULL, "%s Log: 0x%llx\n", reg_desc_p->msg,
7632509Sschwartz 		    CSR_XR(csr_base, reg_desc_p->log_addr));
76427Sjchu 	}
76527Sjchu }
76627Sjchu 
76727Sjchu void
7682509Sschwartz px_err_reg_disable(px_err_id_t reg_id, caddr_t csr_base)
76927Sjchu {
7702509Sschwartz 	const px_err_reg_desc_t	*reg_desc_p = &px_err_reg_tbl[reg_id];
7712509Sschwartz 	uint64_t		val = (reg_id >= PX_ERR_LPU_LINK) ? -1 : 0;
77227Sjchu 
7732509Sschwartz 	if (reg_desc_p->log_addr != NULL)
7742509Sschwartz 		CSR_XS(csr_base, reg_desc_p->log_addr, val);
7752509Sschwartz 	CSR_XS(csr_base, reg_desc_p->enable_addr, val);
7762509Sschwartz }
77727Sjchu 
7782509Sschwartz /*
7792509Sschwartz  * Set up pcie error registers.
7802509Sschwartz  */
7812509Sschwartz void
7822509Sschwartz px_err_reg_setup_pcie(uint8_t chip_mask, caddr_t csr_base, boolean_t enable)
7832509Sschwartz {
7842509Sschwartz 	px_err_id_t		reg_id;
7852509Sschwartz 	const px_err_reg_desc_t	*reg_desc_p;
7862509Sschwartz 	void (*px_err_reg_func)(px_err_id_t, caddr_t);
7872509Sschwartz 
7882509Sschwartz 	/*
7892509Sschwartz 	 * JBC or XBC are enabled during adding of common block interrupts,
7902509Sschwartz 	 * not done here.
7912509Sschwartz 	 */
7922509Sschwartz 	px_err_reg_func = (enable ? px_err_reg_enable : px_err_reg_disable);
7932509Sschwartz 	for (reg_id = 0; reg_id < PX_ERR_REG_KEYS; reg_id++) {
7942509Sschwartz 		reg_desc_p = &px_err_reg_tbl[reg_id];
7952509Sschwartz 		if ((reg_desc_p->chip_mask & chip_mask) &&
7962509Sschwartz 		    (reg_desc_p->reg_bank == PX_REG_CSR))
7972509Sschwartz 			px_err_reg_func(reg_id, csr_base);
79827Sjchu 	}
79927Sjchu }
80027Sjchu 
80127Sjchu /*
8023274Set142600  * px_err_cmn_intr:
80327Sjchu  * Common function called by trap, mondo and fabric intr.
80427Sjchu  * o Snap shot current fire registers
80527Sjchu  * o check for safe access
80627Sjchu  * o send ereport and clear snap shot registers
8073274Set142600  * o create and queue RC info for later use in fabric scan.
8083274Set142600  *   o RUC/WUC, PTLP, MMU Errors(CA), UR
80927Sjchu  * o check severity of snap shot registers
81027Sjchu  *
81127Sjchu  * @param px_p		leaf in which to check access
81227Sjchu  * @param derr		fm err data structure to be updated
81327Sjchu  * @param caller	PX_TRAP_CALL | PX_INTR_CALL
8143274Set142600  * @param block		PX_FM_BLOCK_HOST | PX_FM_BLOCK_PCIE | PX_FM_BLOCK_ALL
8153274Set142600  * @return err		PX_NO_PANIC | PX_PANIC | PX_HW_RESET | PX_PROTECTED
81627Sjchu  */
81727Sjchu int
8183274Set142600 px_err_cmn_intr(px_t *px_p, ddi_fm_error_t *derr, int caller, int block)
81927Sjchu {
8202509Sschwartz 	px_err_ss_t		ss = {0};
8213274Set142600 	int			err;
82227Sjchu 
8231648Sjchu 	ASSERT(MUTEX_HELD(&px_p->px_fm_mutex));
82427Sjchu 
825*3613Set142600 	/* check for safe access */
826*3613Set142600 	px_err_safeacc_check(px_p, derr);
827*3613Set142600 
82827Sjchu 	/* snap shot the current fire registers */
8293274Set142600 	px_err_snapshot(px_p, &ss, block);
83027Sjchu 
83127Sjchu 	/* send ereports/handle/clear registers */
83227Sjchu 	err = px_err_erpt_and_clr(px_p, derr, &ss);
83327Sjchu 
83427Sjchu 	/* check for error severity */
83527Sjchu 	err = px_err_check_severity(px_p, derr, err, caller);
83627Sjchu 
83727Sjchu 	/* Mark the On Trap Handle if an error occured */
8383274Set142600 	if (err != PX_NO_ERROR) {
83927Sjchu 		px_pec_t	*pec_p = px_p->px_pec_p;
84027Sjchu 		on_trap_data_t	*otd = pec_p->pec_ontrap_data;
84127Sjchu 
842118Sjchu 		if ((otd != NULL) && (otd->ot_prot & OT_DATA_ACCESS))
84327Sjchu 			otd->ot_trap |= OT_DATA_ACCESS;
84427Sjchu 	}
84527Sjchu 
84627Sjchu 	return (err);
84727Sjchu }
84827Sjchu 
84927Sjchu /*
85027Sjchu  * Static function
85127Sjchu  */
85227Sjchu 
85327Sjchu /*
85427Sjchu  * px_err_snapshot:
85527Sjchu  * Take a current snap shot of all the fire error registers.  This includes
8563274Set142600  * JBC/UBC, DMC, and PEC depending on the block flag
85727Sjchu  *
85827Sjchu  * @param px_p		leaf in which to take the snap shot.
85927Sjchu  * @param ss		pre-allocated memory to store the snap shot.
8601772Sjl139090  * @param chk_cb	boolean on whether to store jbc/ubc register.
86127Sjchu  */
86227Sjchu static void
8633274Set142600 px_err_snapshot(px_t *px_p, px_err_ss_t *ss_p, int block)
86427Sjchu {
86527Sjchu 	pxu_t	*pxu_p = (pxu_t *)px_p->px_plat_p;
86627Sjchu 	caddr_t	xbc_csr_base = (caddr_t)pxu_p->px_address[PX_REG_XBC];
86727Sjchu 	caddr_t	pec_csr_base = (caddr_t)pxu_p->px_address[PX_REG_CSR];
8683274Set142600 	caddr_t	csr_base;
8692509Sschwartz 	uint8_t chip_mask = 1 << PX_CHIP_TYPE(pxu_p);
8702509Sschwartz 	const px_err_reg_desc_t *reg_desc_p = px_err_reg_tbl;
8712509Sschwartz 	px_err_id_t reg_id;
8721772Sjl139090 
8732509Sschwartz 	for (reg_id = 0; reg_id < PX_ERR_REG_KEYS; reg_id++, reg_desc_p++) {
8742509Sschwartz 		if (!(reg_desc_p->chip_mask & chip_mask))
8752509Sschwartz 			continue;
8763274Set142600 
8773274Set142600 		if ((block & PX_FM_BLOCK_HOST) &&
8783274Set142600 		    (reg_desc_p->reg_bank == PX_REG_XBC))
8793274Set142600 			csr_base = xbc_csr_base;
8803274Set142600 		else if ((block & PX_FM_BLOCK_PCIE) &&
8813274Set142600 		    (reg_desc_p->reg_bank == PX_REG_CSR))
8823274Set142600 			csr_base = pec_csr_base;
8833274Set142600 		else {
8843274Set142600 			ss_p->err_status[reg_id] = 0;
8853274Set142600 			continue;
8863274Set142600 		}
8873274Set142600 
8883274Set142600 		ss_p->err_status[reg_id] = CSR_XR(csr_base,
8893274Set142600 		    reg_desc_p->status_addr);
89027Sjchu 	}
89127Sjchu }
89227Sjchu 
89327Sjchu /*
89427Sjchu  * px_err_erpt_and_clr:
89527Sjchu  * This function does the following thing to all the fire registers based
89627Sjchu  * on an earlier snap shot.
89727Sjchu  * o Send ereport
89827Sjchu  * o Handle the error
89927Sjchu  * o Clear the error
90027Sjchu  *
90127Sjchu  * @param px_p		leaf in which to take the snap shot.
90227Sjchu  * @param derr		fm err in which the ereport is to be based on
9032509Sschwartz  * @param ss_p		pre-allocated memory to store the snap shot.
90427Sjchu  */
90527Sjchu static int
9062509Sschwartz px_err_erpt_and_clr(px_t *px_p, ddi_fm_error_t *derr, px_err_ss_t *ss_p)
90727Sjchu {
90827Sjchu 	dev_info_t		*rpdip = px_p->px_dip;
90927Sjchu 	pxu_t			*pxu_p = (pxu_t *)px_p->px_plat_p;
91027Sjchu 	caddr_t			csr_base;
9112509Sschwartz 	const px_err_reg_desc_t	*err_reg_tbl;
91227Sjchu 	px_err_bit_desc_t	*err_bit_tbl;
91327Sjchu 	px_err_bit_desc_t	*err_bit_desc;
91427Sjchu 
9153274Set142600 	uint64_t		*count_mask;
9163274Set142600 	uint64_t		clear_addr;
91727Sjchu 	uint64_t		ss_reg;
91827Sjchu 
91927Sjchu 	int			(*err_handler)();
92027Sjchu 	int			(*erpt_handler)();
9213274Set142600 	int			reg_id, key;
9223274Set142600 	int			err = PX_NO_ERROR;
9233274Set142600 	int			biterr = 0;
92427Sjchu 
9251648Sjchu 	ASSERT(MUTEX_HELD(&px_p->px_fm_mutex));
92627Sjchu 
92727Sjchu 	/* send erport/handle/clear JBC errors */
9282509Sschwartz 	for (reg_id = 0; reg_id < PX_ERR_REG_KEYS; reg_id++) {
92927Sjchu 		/* Get the correct register description table */
93027Sjchu 		err_reg_tbl = &px_err_reg_tbl[reg_id];
93127Sjchu 
9321772Sjl139090 		/* Only look at enabled groups. */
9332509Sschwartz 		if (!(BIT_TST(err_reg_tbl->chip_mask, PX_CHIP_TYPE(pxu_p))))
9341772Sjl139090 			continue;
9351772Sjl139090 
93627Sjchu 		/* Get the correct CSR BASE */
9372509Sschwartz 		csr_base = (caddr_t)pxu_p->px_address[err_reg_tbl->reg_bank];
93827Sjchu 
9393274Set142600 		/* If there are no errors in this register, continue */
9403274Set142600 		ss_reg = ss_p->err_status[reg_id];
9413274Set142600 		if (!ss_reg)
9423274Set142600 			continue;
9433274Set142600 
9443272Sdduvall 		/* Get pointers to masks and register addresses */
9453272Sdduvall 		count_mask = err_reg_tbl->count_mask_p;
9463272Sdduvall 		clear_addr = err_reg_tbl->clear_addr;
94727Sjchu 
94827Sjchu 		/* Get the register BIT description table */
94927Sjchu 		err_bit_tbl = err_reg_tbl->err_bit_tbl;
95027Sjchu 
95127Sjchu 		/* For each known bit in the register send erpt and handle */
9522509Sschwartz 		for (key = 0; key < err_reg_tbl->err_bit_keys; key++) {
95327Sjchu 			/*
95427Sjchu 			 * If the ss_reg is set for this bit,
95527Sjchu 			 * send ereport and handle
95627Sjchu 			 */
9573274Set142600 			err_bit_desc = &err_bit_tbl[key];
9583274Set142600 			if (!BIT_TST(ss_reg, err_bit_desc->bit))
9593274Set142600 				continue;
96027Sjchu 
9613274Set142600 			/* Increment the counter if necessary */
9623274Set142600 			if (BIT_TST(*count_mask, err_bit_desc->bit)) {
9633274Set142600 				err_bit_desc->counter++;
9643274Set142600 			}
96527Sjchu 
9663274Set142600 			/* Error Handle for this bit */
9673274Set142600 			err_handler = err_bit_desc->err_handler;
9683274Set142600 			if (err_handler) {
9693274Set142600 				biterr = err_handler(rpdip, csr_base, derr,
9703274Set142600 				    err_reg_tbl, err_bit_desc);
9713274Set142600 				err |= biterr;
97227Sjchu 			}
9733274Set142600 
9743274Set142600 			/*
9753274Set142600 			 * Send the ereport if it's an UNEXPECTED err.
9763274Set142600 			 * This is the only place where PX_EXPECTED is utilized.
9773274Set142600 			 */
9783274Set142600 			erpt_handler = err_bit_desc->erpt_handler;
9793274Set142600 			if ((derr->fme_flag != DDI_FM_ERR_UNEXPECTED) ||
9803274Set142600 			    (biterr == PX_EXPECTED))
9813274Set142600 				continue;
9823274Set142600 
9833274Set142600 			if (erpt_handler)
9843274Set142600 				(void) erpt_handler(rpdip, csr_base, ss_reg,
9853274Set142600 				    derr, err_bit_desc->bit,
9863274Set142600 				    err_bit_desc->class_name);
98727Sjchu 		}
98827Sjchu 
98927Sjchu 		/* Clear the register and error */
99027Sjchu 		CSR_XS(csr_base, clear_addr, ss_reg);
99127Sjchu 	}
99227Sjchu 
99327Sjchu 	return (err);
99427Sjchu }
99527Sjchu 
99627Sjchu /*
99727Sjchu  * px_err_check_severity:
99827Sjchu  * Check the severity of the fire error based on an earlier snapshot
99927Sjchu  *
100027Sjchu  * @param px_p		leaf in which to take the snap shot.
100127Sjchu  * @param derr		fm err in which the ereport is to be based on
10022509Sschwartz  * @param err		fire register error status
10032509Sschwartz  * @param caller	PX_TRAP_CALL | PX_INTR_CALL | PX_LIB_CALL
100427Sjchu  */
100527Sjchu static int
100627Sjchu px_err_check_severity(px_t *px_p, ddi_fm_error_t *derr, int err, int caller)
100727Sjchu {
100827Sjchu 	px_pec_t 	*pec_p = px_p->px_pec_p;
100927Sjchu 	boolean_t	is_safeacc = B_FALSE;
1010118Sjchu 
10113274Set142600 	/*
10123274Set142600 	 * Nothing to do if called with no error.
10133274Set142600 	 * The err could have already been set to PX_NO_PANIC, which means the
10143274Set142600 	 * system doesn't need to panic, but PEEK/POKE still failed.
10153274Set142600 	 */
10163274Set142600 	if (err == PX_NO_ERROR)
1017118Sjchu 		return (err);
101827Sjchu 
101927Sjchu 	/* Cautious access error handling  */
102027Sjchu 	switch (derr->fme_flag) {
102127Sjchu 	case DDI_FM_ERR_EXPECTED:
102227Sjchu 		if (caller == PX_TRAP_CALL) {
102327Sjchu 			/*
102427Sjchu 			 * for ddi_caut_get treat all events as nonfatal
102527Sjchu 			 * The trampoline will set err_ena = 0,
102627Sjchu 			 * err_status = NONFATAL.
102727Sjchu 			 */
102827Sjchu 			derr->fme_status = DDI_FM_NONFATAL;
102927Sjchu 			is_safeacc = B_TRUE;
103027Sjchu 		} else {
103127Sjchu 			/*
103227Sjchu 			 * For ddi_caut_put treat all events as nonfatal. Here
103327Sjchu 			 * we have the handle and can call ndi_fm_acc_err_set().
103427Sjchu 			 */
103527Sjchu 			derr->fme_status = DDI_FM_NONFATAL;
103627Sjchu 			ndi_fm_acc_err_set(pec_p->pec_acc_hdl, derr);
103727Sjchu 			is_safeacc = B_TRUE;
103827Sjchu 		}
103927Sjchu 		break;
104027Sjchu 	case DDI_FM_ERR_PEEK:
104127Sjchu 	case DDI_FM_ERR_POKE:
104227Sjchu 		/*
104327Sjchu 		 * For ddi_peek/poke treat all events as nonfatal.
104427Sjchu 		 */
104527Sjchu 		is_safeacc = B_TRUE;
104627Sjchu 		break;
104727Sjchu 	default:
104827Sjchu 		is_safeacc = B_FALSE;
104927Sjchu 	}
105027Sjchu 
10513274Set142600 	/* re-adjust error status from safe access, forgive all errors */
10523274Set142600 	if (is_safeacc)
10533274Set142600 		return (PX_NO_PANIC);
105427Sjchu 
1055118Sjchu 	return (err);
105627Sjchu }
105727Sjchu 
105827Sjchu /* predefined convenience functions */
105927Sjchu /* ARGSUSED */
10603274Set142600 void
10613274Set142600 px_err_log_handle(dev_info_t *rpdip, px_err_reg_desc_t *err_reg_descr,
10623274Set142600 	px_err_bit_desc_t *err_bit_descr, char *msg)
106327Sjchu {
10643274Set142600 	DBG(DBG_ERR_INTR, rpdip,
10653274Set142600 	    "Bit %d, %s, at %s(0x%x) has occured %d times with a severity "
10663274Set142600 	    "of \"%s\"\n",
10673274Set142600 	    err_bit_descr->bit, err_bit_descr->class_name,
10683274Set142600 	    err_reg_descr->msg, err_reg_descr->status_addr,
10693274Set142600 	    err_bit_descr->counter, msg);
107027Sjchu }
107127Sjchu 
107227Sjchu /* ARGSUSED */
107327Sjchu int
10743274Set142600 px_err_hw_reset_handle(dev_info_t *rpdip, caddr_t csr_base,
107527Sjchu 	ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
107627Sjchu 	px_err_bit_desc_t *err_bit_descr)
107727Sjchu {
10783274Set142600 	if (px_log & PX_HW_RESET) {
10793274Set142600 		px_err_log_handle(rpdip, err_reg_descr, err_bit_descr,
10803274Set142600 		    "HW RESET");
10813274Set142600 	}
108227Sjchu 
10833274Set142600 	return (PX_HW_RESET);
108427Sjchu }
108527Sjchu 
108627Sjchu /* ARGSUSED */
108727Sjchu int
10883274Set142600 px_err_panic_handle(dev_info_t *rpdip, caddr_t csr_base,
108927Sjchu 	ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
109027Sjchu 	px_err_bit_desc_t *err_bit_descr)
109127Sjchu {
10923274Set142600 	if (px_log & PX_PANIC) {
10933274Set142600 		px_err_log_handle(rpdip, err_reg_descr, err_bit_descr, "PANIC");
10943274Set142600 	}
10953274Set142600 
10963274Set142600 	return (PX_PANIC);
109727Sjchu }
109827Sjchu 
109927Sjchu /* ARGSUSED */
110027Sjchu int
11013274Set142600 px_err_protected_handle(dev_info_t *rpdip, caddr_t csr_base,
110227Sjchu 	ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
110327Sjchu 	px_err_bit_desc_t *err_bit_descr)
110427Sjchu {
11053274Set142600 	if (px_log & PX_PROTECTED) {
11063274Set142600 		px_err_log_handle(rpdip, err_reg_descr, err_bit_descr,
11073274Set142600 		    "PROTECTED");
11083274Set142600 	}
11093274Set142600 
11103274Set142600 	return (PX_PROTECTED);
111127Sjchu }
111227Sjchu 
111327Sjchu /* ARGSUSED */
111427Sjchu int
11153274Set142600 px_err_no_panic_handle(dev_info_t *rpdip, caddr_t csr_base,
11163274Set142600 	ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
11173274Set142600 	px_err_bit_desc_t *err_bit_descr)
111827Sjchu {
11193274Set142600 	if (px_log & PX_NO_PANIC) {
11203274Set142600 		px_err_log_handle(rpdip, err_reg_descr, err_bit_descr,
11213274Set142600 		    "NO PANIC");
11223274Set142600 	}
11233274Set142600 
11243274Set142600 	return (PX_NO_PANIC);
112527Sjchu }
112627Sjchu 
112727Sjchu /* ARGSUSED */
112827Sjchu int
11293274Set142600 px_err_no_error_handle(dev_info_t *rpdip, caddr_t csr_base,
11303274Set142600 	ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
11313274Set142600 	px_err_bit_desc_t *err_bit_descr)
113227Sjchu {
11333274Set142600 	if (px_log & PX_NO_ERROR) {
11343274Set142600 		px_err_log_handle(rpdip, err_reg_descr, err_bit_descr,
11353274Set142600 		    "NO ERROR");
11363274Set142600 	}
11373274Set142600 
11383274Set142600 	return (PX_NO_ERROR);
113927Sjchu }
114027Sjchu 
1141383Set142600 /* ARGSUSED */
1142383Set142600 PX_ERPT_SEND_DEC(do_not)
1143383Set142600 {
11443274Set142600 	return (PX_NO_ERROR);
1145383Set142600 }
1146383Set142600 
11473274Set142600 
11481772Sjl139090 /* UBC FATAL - see io erpt doc, section 1.1 */
11491772Sjl139090 /* ARGSUSED */
11501772Sjl139090 PX_ERPT_SEND_DEC(ubc_fatal)
11511772Sjl139090 {
11521772Sjl139090 	char		buf[FM_MAX_CLASS];
11531772Sjl139090 	uint64_t	memory_ue_log, marked;
11541772Sjl139090 	char		unum[FM_MAX_CLASS];
11551772Sjl139090 	int		unum_length;
11561772Sjl139090 	uint64_t	device_id = 0;
11571772Sjl139090 	uint8_t		cpu_version = 0;
11581772Sjl139090 	nvlist_t	*resource = NULL;
11591772Sjl139090 
11601772Sjl139090 	unum[0] = '\0';
11611772Sjl139090 	(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
11621772Sjl139090 
11631772Sjl139090 	memory_ue_log = CSR_XR(csr_base, UBC_MEMORY_UE_LOG);
11641772Sjl139090 	marked = (memory_ue_log >> UBC_MEMORY_UE_LOG_MARKED) &
11651772Sjl139090 	    UBC_MEMORY_UE_LOG_MARKED_MASK;
11661772Sjl139090 
11671772Sjl139090 	if ((strstr(class_name, "ubc.piowtue") != NULL) ||
11681772Sjl139090 	    (strstr(class_name, "ubc.piowbeue") != NULL) ||
11691772Sjl139090 	    (strstr(class_name, "ubc.piorbeue") != NULL) ||
11701772Sjl139090 	    (strstr(class_name, "ubc.dmarduea") != NULL) ||
11711772Sjl139090 	    (strstr(class_name, "ubc.dmardueb") != NULL)) {
11721772Sjl139090 		int eid = (memory_ue_log >> UBC_MEMORY_UE_LOG_EID) &
11731772Sjl139090 		    UBC_MEMORY_UE_LOG_EID_MASK;
11741772Sjl139090 		(void) strncat(buf, ubc_class_eid_qualifier[eid],
11751772Sjl139090 		    FM_MAX_CLASS);
11761772Sjl139090 
11771772Sjl139090 		if (eid == UBC_EID_MEM) {
11781772Sjl139090 			uint64_t phys_addr = memory_ue_log &
11791772Sjl139090 			    MMU_OBERON_PADDR_MASK;
11801772Sjl139090 			uint64_t offset = (uint64_t)-1;
11811772Sjl139090 
11821772Sjl139090 			resource = fm_nvlist_create(NULL);
11831772Sjl139090 			if (&plat_get_mem_unum) {
11841772Sjl139090 				if ((plat_get_mem_unum(0,
11851772Sjl139090 				    phys_addr, 0, B_TRUE, 0, unum,
11861772Sjl139090 				    FM_MAX_CLASS, &unum_length)) != 0)
11871772Sjl139090 					unum[0] = '\0';
11881772Sjl139090 			}
11891772Sjl139090 			fm_fmri_mem_set(resource, FM_MEM_SCHEME_VERSION,
11901772Sjl139090 					NULL, unum, NULL, offset);
11911772Sjl139090 
11921772Sjl139090 		} else if (eid == UBC_EID_CPU) {
11931772Sjl139090 			int cpuid = (marked & UBC_MARKED_MAX_CPUID_MASK);
11941772Sjl139090 			char sbuf[21]; /* sizeof (UINT64_MAX) + '\0' */
11951772Sjl139090 
11961772Sjl139090 			resource = fm_nvlist_create(NULL);
11971772Sjl139090 			cpu_version = cpunodes[cpuid].version;
11981772Sjl139090 			device_id = cpunodes[cpuid].device_id;
11991772Sjl139090 			(void) snprintf(sbuf, sizeof (sbuf), "%lX",
12001772Sjl139090 			    device_id);
12011772Sjl139090 			(void) fm_fmri_cpu_set(resource,
12021772Sjl139090 			    FM_CPU_SCHEME_VERSION, NULL, cpuid,
12031772Sjl139090 			    &cpu_version, sbuf);
12041772Sjl139090 		}
12051772Sjl139090 	}
12061772Sjl139090 
12071772Sjl139090 	if (resource) {
12081772Sjl139090 		ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
12091772Sjl139090 		    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
12101772Sjl139090 		    FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, B_TRUE,
12111772Sjl139090 		    OBERON_UBC_ELE, DATA_TYPE_UINT64,
12121772Sjl139090 		    CSR_XR(csr_base, UBC_ERROR_LOG_ENABLE),
12131772Sjl139090 		    OBERON_UBC_IE, DATA_TYPE_UINT64,
12141772Sjl139090 		    CSR_XR(csr_base, UBC_INTERRUPT_ENABLE),
12151772Sjl139090 		    OBERON_UBC_IS, DATA_TYPE_UINT64,
12161772Sjl139090 		    CSR_XR(csr_base, UBC_INTERRUPT_STATUS),
12171772Sjl139090 		    OBERON_UBC_ESS, DATA_TYPE_UINT64,
12181772Sjl139090 		    CSR_XR(csr_base, UBC_ERROR_STATUS_SET),
12191772Sjl139090 		    OBERON_UBC_MUE, DATA_TYPE_UINT64, memory_ue_log,
12201772Sjl139090 		    OBERON_UBC_UNUM, DATA_TYPE_STRING, unum,
12211772Sjl139090 		    OBERON_UBC_DID, DATA_TYPE_UINT64, device_id,
12221772Sjl139090 		    OBERON_UBC_CPUV, DATA_TYPE_UINT32, cpu_version,
12231772Sjl139090 		    OBERON_UBC_RESOURCE, DATA_TYPE_NVLIST, resource,
12241772Sjl139090 		    NULL);
12251772Sjl139090 		fm_nvlist_destroy(resource, FM_NVA_FREE);
12261772Sjl139090 	} else {
12271772Sjl139090 		ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
12281772Sjl139090 		    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
12291772Sjl139090 		    FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, B_TRUE,
12301772Sjl139090 		    OBERON_UBC_ELE, DATA_TYPE_UINT64,
12311772Sjl139090 		    CSR_XR(csr_base, UBC_ERROR_LOG_ENABLE),
12321772Sjl139090 		    OBERON_UBC_IE, DATA_TYPE_UINT64,
12331772Sjl139090 		    CSR_XR(csr_base, UBC_INTERRUPT_ENABLE),
12341772Sjl139090 		    OBERON_UBC_IS, DATA_TYPE_UINT64,
12351772Sjl139090 		    CSR_XR(csr_base, UBC_INTERRUPT_STATUS),
12361772Sjl139090 		    OBERON_UBC_ESS, DATA_TYPE_UINT64,
12371772Sjl139090 		    CSR_XR(csr_base, UBC_ERROR_STATUS_SET),
12381772Sjl139090 		    OBERON_UBC_MUE, DATA_TYPE_UINT64, memory_ue_log,
12391772Sjl139090 		    OBERON_UBC_UNUM, DATA_TYPE_STRING, unum,
12401772Sjl139090 		    OBERON_UBC_DID, DATA_TYPE_UINT64, device_id,
12411772Sjl139090 		    OBERON_UBC_CPUV, DATA_TYPE_UINT32, cpu_version,
12421772Sjl139090 		    NULL);
12431772Sjl139090 	}
12441772Sjl139090 
12453274Set142600 	return (PX_NO_PANIC);
12461772Sjl139090 }
1247383Set142600 
12483274Set142600 /* JBC FATAL */
124927Sjchu PX_ERPT_SEND_DEC(jbc_fatal)
125027Sjchu {
125127Sjchu 	char		buf[FM_MAX_CLASS];
1252739Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(bit);
125327Sjchu 
125427Sjchu 	(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
125527Sjchu 	ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
125627Sjchu 	    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
1257739Sjchu 	    FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
125827Sjchu 	    FIRE_JBC_ELE, DATA_TYPE_UINT64,
125927Sjchu 	    CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE),
126027Sjchu 	    FIRE_JBC_IE, DATA_TYPE_UINT64,
126127Sjchu 	    CSR_XR(csr_base, JBC_INTERRUPT_ENABLE),
126227Sjchu 	    FIRE_JBC_IS, DATA_TYPE_UINT64,
126327Sjchu 	    ss_reg,
126427Sjchu 	    FIRE_JBC_ESS, DATA_TYPE_UINT64,
126527Sjchu 	    CSR_XR(csr_base, JBC_ERROR_STATUS_SET),
126627Sjchu 	    FIRE_JBC_FEL1, DATA_TYPE_UINT64,
126727Sjchu 	    CSR_XR(csr_base, FATAL_ERROR_LOG_1),
126827Sjchu 	    FIRE_JBC_FEL2, DATA_TYPE_UINT64,
126927Sjchu 	    CSR_XR(csr_base, FATAL_ERROR_LOG_2),
127027Sjchu 	    NULL);
127127Sjchu 
12723274Set142600 	return (PX_NO_PANIC);
127327Sjchu }
127427Sjchu 
12753274Set142600 /* JBC MERGE */
127627Sjchu PX_ERPT_SEND_DEC(jbc_merge)
127727Sjchu {
127827Sjchu 	char		buf[FM_MAX_CLASS];
1279739Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(bit);
128027Sjchu 
128127Sjchu 	(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
128227Sjchu 	ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
128327Sjchu 	    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
1284739Sjchu 	    FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
128527Sjchu 	    FIRE_JBC_ELE, DATA_TYPE_UINT64,
128627Sjchu 	    CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE),
128727Sjchu 	    FIRE_JBC_IE, DATA_TYPE_UINT64,
128827Sjchu 	    CSR_XR(csr_base, JBC_INTERRUPT_ENABLE),
128927Sjchu 	    FIRE_JBC_IS, DATA_TYPE_UINT64,
129027Sjchu 	    ss_reg,
129127Sjchu 	    FIRE_JBC_ESS, DATA_TYPE_UINT64,
129227Sjchu 	    CSR_XR(csr_base, JBC_ERROR_STATUS_SET),
129327Sjchu 	    FIRE_JBC_MTEL, DATA_TYPE_UINT64,
129427Sjchu 	    CSR_XR(csr_base, MERGE_TRANSACTION_ERROR_LOG),
129527Sjchu 	    NULL);
129627Sjchu 
12973274Set142600 	return (PX_NO_PANIC);
129827Sjchu }
129927Sjchu 
130027Sjchu /*
13013274Set142600  * JBC Merge buffer retryable errors:
13023274Set142600  *    Merge buffer parity error (rd_buf): PIO or DMA
13033274Set142600  *    Merge buffer parity error (wr_buf): PIO or DMA
130427Sjchu  */
130527Sjchu /* ARGSUSED */
130627Sjchu int
130727Sjchu px_err_jbc_merge_handle(dev_info_t *rpdip, caddr_t csr_base,
13083274Set142600     ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
13093274Set142600     px_err_bit_desc_t *err_bit_descr)
131027Sjchu {
13113274Set142600 	/*
13123274Set142600 	 * Holder function to attempt error recovery.  When the features
13133274Set142600 	 * are in place, look up the address of the transaction in:
13143274Set142600 	 *
13153274Set142600 	 * paddr = CSR_XR(csr_base, MERGE_TRANSACTION_ERROR_LOG);
13163274Set142600 	 * paddr &= MERGE_TRANSACTION_ERROR_LOG_ADDRESS_MASK;
13173274Set142600 	 *
13183274Set142600 	 * If the error is a secondary error, there is no log information
13193274Set142600 	 * just panic as it is unknown which address has been affected.
13203274Set142600 	 *
13213274Set142600 	 * Remember the address is pretranslation and might be hard to look
13223274Set142600 	 * up the appropriate driver based on the PA.
13233274Set142600 	 */
13243274Set142600 	return (px_err_panic_handle(rpdip, csr_base, derr, err_reg_descr,
13253274Set142600 		    err_bit_descr));
132627Sjchu }
132727Sjchu 
13283274Set142600 /* JBC Jbusint IN */
132927Sjchu PX_ERPT_SEND_DEC(jbc_in)
133027Sjchu {
133127Sjchu 	char		buf[FM_MAX_CLASS];
1332739Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(bit);
133327Sjchu 
133427Sjchu 	(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
133527Sjchu 	ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
133627Sjchu 	    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
1337739Sjchu 	    FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
133827Sjchu 	    FIRE_JBC_ELE, DATA_TYPE_UINT64,
133927Sjchu 	    CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE),
134027Sjchu 	    FIRE_JBC_IE, DATA_TYPE_UINT64,
134127Sjchu 	    CSR_XR(csr_base, JBC_INTERRUPT_ENABLE),
134227Sjchu 	    FIRE_JBC_IS, DATA_TYPE_UINT64,
134327Sjchu 	    ss_reg,
134427Sjchu 	    FIRE_JBC_ESS, DATA_TYPE_UINT64,
134527Sjchu 	    CSR_XR(csr_base, JBC_ERROR_STATUS_SET),
134627Sjchu 	    FIRE_JBC_JITEL1, DATA_TYPE_UINT64,
134727Sjchu 	    CSR_XR(csr_base, JBCINT_IN_TRANSACTION_ERROR_LOG),
134827Sjchu 	    FIRE_JBC_JITEL2, DATA_TYPE_UINT64,
134927Sjchu 	    CSR_XR(csr_base, JBCINT_IN_TRANSACTION_ERROR_LOG_2),
135027Sjchu 	    NULL);
135127Sjchu 
13523274Set142600 	return (PX_NO_PANIC);
135327Sjchu }
135427Sjchu 
135527Sjchu /*
13563274Set142600  * JBC Jbusint IN retryable errors
135727Sjchu  * Log Reg[42:0].
13583274Set142600  *    Write Data Parity Error: PIO Writes
13593274Set142600  *    Read Data Parity Error: DMA Reads
136027Sjchu  */
136127Sjchu int
136227Sjchu px_err_jbc_jbusint_in_handle(dev_info_t *rpdip, caddr_t csr_base,
136327Sjchu 	ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
136427Sjchu 	px_err_bit_desc_t *err_bit_descr)
136527Sjchu {
13663274Set142600 	/*
13673274Set142600 	 * Holder function to attempt error recovery.  When the features
13683274Set142600 	 * are in place, look up the address of the transaction in:
13693274Set142600 	 *
13703274Set142600 	 * paddr = CSR_XR(csr_base, JBCINT_IN_TRANSACTION_ERROR_LOG);
13713274Set142600 	 * paddr &= JBCINT_IN_TRANSACTION_ERROR_LOG_ADDRESS_MASK;
13723274Set142600 	 *
13733274Set142600 	 * If the error is a secondary error, there is no log information
13743274Set142600 	 * just panic as it is unknown which address has been affected.
13753274Set142600 	 *
13763274Set142600 	 * Remember the address is pretranslation and might be hard to look
13773274Set142600 	 * up the appropriate driver based on the PA.
13783274Set142600 	 */
13793274Set142600 	return (px_err_panic_handle(rpdip, csr_base, derr, err_reg_descr,
13803274Set142600 		    err_bit_descr));
138127Sjchu }
138227Sjchu 
138327Sjchu 
13843274Set142600 /* JBC Jbusint Out */
138527Sjchu PX_ERPT_SEND_DEC(jbc_out)
138627Sjchu {
138727Sjchu 	char		buf[FM_MAX_CLASS];
1388739Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(bit);
138927Sjchu 
139027Sjchu 	(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
139127Sjchu 	ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
139227Sjchu 	    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
1393739Sjchu 	    FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
139427Sjchu 	    FIRE_JBC_ELE, DATA_TYPE_UINT64,
139527Sjchu 	    CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE),
139627Sjchu 	    FIRE_JBC_IE, DATA_TYPE_UINT64,
139727Sjchu 	    CSR_XR(csr_base, JBC_INTERRUPT_ENABLE),
139827Sjchu 	    FIRE_JBC_IS, DATA_TYPE_UINT64,
139927Sjchu 	    ss_reg,
140027Sjchu 	    FIRE_JBC_ESS, DATA_TYPE_UINT64,
140127Sjchu 	    CSR_XR(csr_base, JBC_ERROR_STATUS_SET),
140227Sjchu 	    FIRE_JBC_JOTEL1, DATA_TYPE_UINT64,
140327Sjchu 	    CSR_XR(csr_base, JBCINT_OUT_TRANSACTION_ERROR_LOG),
140427Sjchu 	    FIRE_JBC_JOTEL2, DATA_TYPE_UINT64,
140527Sjchu 	    CSR_XR(csr_base, JBCINT_OUT_TRANSACTION_ERROR_LOG_2),
140627Sjchu 	    NULL);
140727Sjchu 
14083274Set142600 	return (PX_NO_PANIC);
140927Sjchu }
141027Sjchu 
14113274Set142600 /* JBC Dmcint ODCD */
141227Sjchu PX_ERPT_SEND_DEC(jbc_odcd)
141327Sjchu {
141427Sjchu 	char		buf[FM_MAX_CLASS];
1415739Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(bit);
141627Sjchu 
141727Sjchu 	(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
141827Sjchu 	ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
141927Sjchu 	    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
1420739Sjchu 	    FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
142127Sjchu 	    FIRE_JBC_ELE, DATA_TYPE_UINT64,
142227Sjchu 	    CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE),
142327Sjchu 	    FIRE_JBC_IE, DATA_TYPE_UINT64,
142427Sjchu 	    CSR_XR(csr_base, JBC_INTERRUPT_ENABLE),
142527Sjchu 	    FIRE_JBC_IS, DATA_TYPE_UINT64,
142627Sjchu 	    ss_reg,
142727Sjchu 	    FIRE_JBC_ESS, DATA_TYPE_UINT64,
142827Sjchu 	    CSR_XR(csr_base, JBC_ERROR_STATUS_SET),
142927Sjchu 	    FIRE_JBC_DMC_ODCD, DATA_TYPE_UINT64,
143027Sjchu 	    CSR_XR(csr_base, DMCINT_ODCD_ERROR_LOG),
143127Sjchu 	    NULL);
143227Sjchu 
14333274Set142600 	return (PX_NO_PANIC);
143427Sjchu }
143527Sjchu 
143627Sjchu /*
143727Sjchu  * JBC Dmcint ODCO nonfatal errer handling -
14383274Set142600  *    PIO data parity error: PIO
143927Sjchu  */
144027Sjchu /* ARGSUSED */
144127Sjchu int
144227Sjchu px_err_jbc_dmcint_odcd_handle(dev_info_t *rpdip, caddr_t csr_base,
144327Sjchu 	ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
144427Sjchu 	px_err_bit_desc_t *err_bit_descr)
144527Sjchu {
14463274Set142600 	/*
14473274Set142600 	 * Holder function to attempt error recovery.  When the features
14483274Set142600 	 * are in place, look up the address of the transaction in:
14493274Set142600 	 *
14503274Set142600 	 * paddr = CSR_XR(csr_base, DMCINT_ODCD_ERROR_LOG);
14513274Set142600 	 * paddr &= DMCINT_ODCD_ERROR_LOG_ADDRESS_MASK;
14523274Set142600 	 *
14533274Set142600 	 * If the error is a secondary error, there is no log information
14543274Set142600 	 * just panic as it is unknown which address has been affected.
14553274Set142600 	 *
14563274Set142600 	 * Remember the address is pretranslation and might be hard to look
14573274Set142600 	 * up the appropriate driver based on the PA.
14583274Set142600 	 */
14593274Set142600 	return (px_err_panic_handle(rpdip, csr_base, derr, err_reg_descr,
14603274Set142600 		    err_bit_descr));
146127Sjchu }
146227Sjchu 
14632276Sschwartz /* Does address in DMCINT error log register match address of pcitool access? */
14642276Sschwartz static boolean_t
14652276Sschwartz px_jbc_pcitool_addr_match(dev_info_t *rpdip, caddr_t csr_base)
14662276Sschwartz {
14672276Sschwartz 	px_t	*px_p = DIP_TO_STATE(rpdip);
14682276Sschwartz 	pxu_t	*pxu_p = (pxu_t *)px_p->px_plat_p;
14692276Sschwartz 	caddr_t	pcitool_addr = pxu_p->pcitool_addr;
14702276Sschwartz 	caddr_t errlog_addr =
14712276Sschwartz 	    (caddr_t)CSR_FR(csr_base, DMCINT_ODCD_ERROR_LOG, ADDRESS);
14722276Sschwartz 
14732276Sschwartz 	return (pcitool_addr == errlog_addr);
14742276Sschwartz }
14752276Sschwartz 
14762276Sschwartz /*
14772276Sschwartz  * JBC Dmcint ODCD errer handling for errors which are forgivable during a safe
14782276Sschwartz  * access.  (This will be most likely be a PCItool access.)  If not a safe
14792276Sschwartz  * access context, treat like jbc_dmcint_odcd.
14802276Sschwartz  *    Unmapped PIO read error: pio:read:M:nonfatal
14812276Sschwartz  *    Unmapped PIO write error: pio:write:M:nonfatal
14822276Sschwartz  *    Invalid PIO write to PCIe cfg/io, csr, ebus or i2c bus: pio:write:nonfatal
14832276Sschwartz  *    Invalid PIO read to PCIe cfg/io, csr, ebus or i2c bus: pio:read:nonfatal
14842276Sschwartz  */
14852276Sschwartz /* ARGSUSED */
14862276Sschwartz int
14872276Sschwartz px_err_jbc_safe_acc_handle(dev_info_t *rpdip, caddr_t csr_base,
14882276Sschwartz 	ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
14892276Sschwartz 	px_err_bit_desc_t *err_bit_descr)
14902276Sschwartz {
14912276Sschwartz 	boolean_t	pri = PX_ERR_IS_PRI(err_bit_descr->bit);
14922276Sschwartz 
14932276Sschwartz 	if (!pri)
14943274Set142600 		return (px_err_panic_handle(rpdip, csr_base, derr,
14953274Set142600 			    err_reg_descr, err_bit_descr));
14962276Sschwartz 	/*
14972276Sschwartz 	 * Got an error which is forgivable during a PCItool access.
14982276Sschwartz 	 *
14992276Sschwartz 	 * Don't do handler check since the error may otherwise be unfairly
15002276Sschwartz 	 * attributed to a device.  Just return.
15012276Sschwartz 	 *
15022276Sschwartz 	 * Note: There is a hole here in that a legitimate error can come in
15032276Sschwartz 	 * while a PCItool access is in play and be forgiven.  This is possible
15042276Sschwartz 	 * though not likely.
15052276Sschwartz 	 */
15062276Sschwartz 	if ((derr->fme_flag != DDI_FM_ERR_UNEXPECTED) &&
15072276Sschwartz 	    (px_jbc_pcitool_addr_match(rpdip, csr_base)))
15083274Set142600 		return (px_err_protected_handle(rpdip, csr_base, derr,
15093274Set142600 			    err_reg_descr, err_bit_descr));
15102276Sschwartz 
15112276Sschwartz 	return (px_err_jbc_dmcint_odcd_handle(rpdip, csr_base, derr,
15122276Sschwartz 	    err_reg_descr, err_bit_descr));
15132276Sschwartz }
15142276Sschwartz 
15153274Set142600 /* JBC Dmcint IDC */
151627Sjchu PX_ERPT_SEND_DEC(jbc_idc)
151727Sjchu {
151827Sjchu 	char		buf[FM_MAX_CLASS];
1519739Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(bit);
152027Sjchu 
152127Sjchu 	(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
152227Sjchu 	ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
152327Sjchu 	    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
1524739Sjchu 	    FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
152527Sjchu 	    FIRE_JBC_ELE, DATA_TYPE_UINT64,
152627Sjchu 	    CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE),
152727Sjchu 	    FIRE_JBC_IE, DATA_TYPE_UINT64,
152827Sjchu 	    CSR_XR(csr_base, JBC_INTERRUPT_ENABLE),
152927Sjchu 	    FIRE_JBC_IS, DATA_TYPE_UINT64,
153027Sjchu 	    ss_reg,
153127Sjchu 	    FIRE_JBC_ESS, DATA_TYPE_UINT64,
153227Sjchu 	    CSR_XR(csr_base, JBC_ERROR_STATUS_SET),
153327Sjchu 	    FIRE_JBC_DMC_IDC, DATA_TYPE_UINT64,
153427Sjchu 	    CSR_XR(csr_base, DMCINT_IDC_ERROR_LOG),
153527Sjchu 	    NULL);
153627Sjchu 
15373274Set142600 	return (PX_NO_PANIC);
153827Sjchu }
153927Sjchu 
15403274Set142600 /* JBC CSR */
154127Sjchu PX_ERPT_SEND_DEC(jbc_csr)
154227Sjchu {
154327Sjchu 	char		buf[FM_MAX_CLASS];
1544739Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(bit);
154527Sjchu 
154627Sjchu 	(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
154727Sjchu 	ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
154827Sjchu 	    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
1549739Sjchu 	    FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
155027Sjchu 	    FIRE_JBC_ELE, DATA_TYPE_UINT64,
155127Sjchu 	    CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE),
155227Sjchu 	    FIRE_JBC_IE, DATA_TYPE_UINT64,
155327Sjchu 	    CSR_XR(csr_base, JBC_INTERRUPT_ENABLE),
155427Sjchu 	    FIRE_JBC_IS, DATA_TYPE_UINT64,
155527Sjchu 	    ss_reg,
155627Sjchu 	    FIRE_JBC_ESS, DATA_TYPE_UINT64,
155727Sjchu 	    CSR_XR(csr_base, JBC_ERROR_STATUS_SET),
155827Sjchu 	    "jbc-error-reg", DATA_TYPE_UINT64,
155927Sjchu 	    CSR_XR(csr_base, CSR_ERROR_LOG),
156027Sjchu 	    NULL);
156127Sjchu 
15623274Set142600 	return (PX_NO_PANIC);
156327Sjchu }
156427Sjchu 
15653274Set142600 /* DMC IMU RDS */
156627Sjchu PX_ERPT_SEND_DEC(imu_rds)
156727Sjchu {
156827Sjchu 	char		buf[FM_MAX_CLASS];
1569739Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(bit);
157027Sjchu 
157127Sjchu 	(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
157227Sjchu 	ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
157327Sjchu 	    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
1574739Sjchu 	    FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
157527Sjchu 	    FIRE_IMU_ELE, DATA_TYPE_UINT64,
157627Sjchu 	    CSR_XR(csr_base, IMU_ERROR_LOG_ENABLE),
157727Sjchu 	    FIRE_IMU_IE, DATA_TYPE_UINT64,
157827Sjchu 	    CSR_XR(csr_base, IMU_INTERRUPT_ENABLE),
157927Sjchu 	    FIRE_IMU_IS, DATA_TYPE_UINT64,
158027Sjchu 	    ss_reg,
158127Sjchu 	    FIRE_IMU_ESS, DATA_TYPE_UINT64,
158227Sjchu 	    CSR_XR(csr_base, IMU_ERROR_STATUS_SET),
158327Sjchu 	    FIRE_IMU_RDS, DATA_TYPE_UINT64,
158427Sjchu 	    CSR_XR(csr_base, IMU_RDS_ERROR_LOG),
158527Sjchu 	    NULL);
158627Sjchu 
15873274Set142600 	return (PX_NO_PANIC);
1588118Sjchu }
1589118Sjchu 
159027Sjchu /* handle EQ overflow */
159127Sjchu /* ARGSUSED */
159227Sjchu int
159327Sjchu px_err_imu_eq_ovfl_handle(dev_info_t *rpdip, caddr_t csr_base,
159427Sjchu 	ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
159527Sjchu 	px_err_bit_desc_t *err_bit_descr)
159627Sjchu {
15973274Set142600 	px_t	*px_p = DIP_TO_STATE(rpdip);
15983274Set142600 	pxu_t	*pxu_p = (pxu_t *)px_p->px_plat_p;
15993274Set142600 	int	err = px_err_check_eq(rpdip);
160027Sjchu 
16013274Set142600 	if ((err == PX_PANIC) && (pxu_p->cpr_flag == PX_NOT_CPR)) {
16023274Set142600 		return (px_err_panic_handle(rpdip, csr_base, derr,
16033274Set142600 			    err_reg_descr, err_bit_descr));
16043274Set142600 	} else {
16053274Set142600 		return (px_err_no_panic_handle(rpdip, csr_base, derr,
16063274Set142600 			    err_reg_descr, err_bit_descr));
160727Sjchu 	}
160827Sjchu }
160927Sjchu 
16103274Set142600 /* DMC IMU SCS */
161127Sjchu PX_ERPT_SEND_DEC(imu_scs)
161227Sjchu {
161327Sjchu 	char		buf[FM_MAX_CLASS];
1614739Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(bit);
161527Sjchu 
161627Sjchu 	(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
161727Sjchu 	ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
161827Sjchu 	    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
1619739Sjchu 	    FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
162027Sjchu 	    FIRE_IMU_ELE, DATA_TYPE_UINT64,
162127Sjchu 	    CSR_XR(csr_base, IMU_ERROR_LOG_ENABLE),
162227Sjchu 	    FIRE_IMU_IE, DATA_TYPE_UINT64,
162327Sjchu 	    CSR_XR(csr_base, IMU_INTERRUPT_ENABLE),
162427Sjchu 	    FIRE_IMU_IS, DATA_TYPE_UINT64,
162527Sjchu 	    ss_reg,
162627Sjchu 	    FIRE_IMU_ESS, DATA_TYPE_UINT64,
162727Sjchu 	    CSR_XR(csr_base, IMU_ERROR_STATUS_SET),
162827Sjchu 	    FIRE_IMU_SCS, DATA_TYPE_UINT64,
162927Sjchu 	    CSR_XR(csr_base, IMU_SCS_ERROR_LOG),
163027Sjchu 	    NULL);
163127Sjchu 
16323274Set142600 	return (PX_NO_PANIC);
163327Sjchu }
163427Sjchu 
16353274Set142600 /* DMC IMU */
163627Sjchu PX_ERPT_SEND_DEC(imu)
163727Sjchu {
163827Sjchu 	char		buf[FM_MAX_CLASS];
1639739Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(bit);
164027Sjchu 
164127Sjchu 	(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
164227Sjchu 	ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
164327Sjchu 	    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
1644739Sjchu 	    FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
164527Sjchu 	    FIRE_IMU_ELE, DATA_TYPE_UINT64,
164627Sjchu 	    CSR_XR(csr_base, IMU_ERROR_LOG_ENABLE),
164727Sjchu 	    FIRE_IMU_IE, DATA_TYPE_UINT64,
164827Sjchu 	    CSR_XR(csr_base, IMU_INTERRUPT_ENABLE),
164927Sjchu 	    FIRE_IMU_IS, DATA_TYPE_UINT64,
165027Sjchu 	    ss_reg,
165127Sjchu 	    FIRE_IMU_ESS, DATA_TYPE_UINT64,
165227Sjchu 	    CSR_XR(csr_base, IMU_ERROR_STATUS_SET),
165327Sjchu 	    NULL);
165427Sjchu 
16553274Set142600 	return (PX_NO_PANIC);
165627Sjchu }
165727Sjchu 
16583274Set142600 /* DMC MMU TFAR/TFSR */
165927Sjchu PX_ERPT_SEND_DEC(mmu_tfar_tfsr)
166027Sjchu {
166127Sjchu 	char		buf[FM_MAX_CLASS];
1662739Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(bit);
16633274Set142600 	px_t		*px_p = DIP_TO_STATE(rpdip);
16643274Set142600 	pcie_req_id_t	fault_bdf = 0;
16653274Set142600 	uint16_t	s_status = 0;
16663274Set142600 
16673274Set142600 	if (pri) {
16683274Set142600 		fault_bdf = CSR_XR(csr_base, MMU_TRANSLATION_FAULT_STATUS)
16693274Set142600 		    & (MMU_TRANSLATION_FAULT_STATUS_ID_MASK <<
16703274Set142600 		    MMU_TRANSLATION_FAULT_STATUS_ID);
16713274Set142600 		s_status = PCI_STAT_S_TARG_AB;
16723274Set142600 
16733274Set142600 		/* Only PIO Fault Addresses are valid, this is DMA */
16743274Set142600 		(void) px_rp_en_q(px_p, fault_bdf, NULL, s_status);
16753274Set142600 	}
167627Sjchu 
167727Sjchu 	(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
16781772Sjl139090 
167927Sjchu 	ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
168027Sjchu 	    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
1681739Sjchu 	    FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
168227Sjchu 	    FIRE_MMU_ELE, DATA_TYPE_UINT64,
168327Sjchu 	    CSR_XR(csr_base, MMU_ERROR_LOG_ENABLE),
168427Sjchu 	    FIRE_MMU_IE, DATA_TYPE_UINT64,
168527Sjchu 	    CSR_XR(csr_base, MMU_INTERRUPT_ENABLE),
168627Sjchu 	    FIRE_MMU_IS, DATA_TYPE_UINT64,
168727Sjchu 	    ss_reg,
168827Sjchu 	    FIRE_MMU_ESS, DATA_TYPE_UINT64,
168927Sjchu 	    CSR_XR(csr_base, MMU_ERROR_STATUS_SET),
169027Sjchu 	    FIRE_MMU_TFAR, DATA_TYPE_UINT64,
169127Sjchu 	    CSR_XR(csr_base, MMU_TRANSLATION_FAULT_ADDRESS),
169227Sjchu 	    FIRE_MMU_TFSR, DATA_TYPE_UINT64,
169327Sjchu 	    CSR_XR(csr_base, MMU_TRANSLATION_FAULT_STATUS),
169427Sjchu 	    NULL);
169527Sjchu 
16963274Set142600 	return (PX_NO_PANIC);
169727Sjchu }
169827Sjchu 
16993274Set142600 /* DMC MMU */
170027Sjchu PX_ERPT_SEND_DEC(mmu)
170127Sjchu {
170227Sjchu 	char		buf[FM_MAX_CLASS];
1703739Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(bit);
170427Sjchu 
170527Sjchu 	(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
170627Sjchu 	ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
170727Sjchu 	    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
1708739Sjchu 	    FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
170927Sjchu 	    FIRE_MMU_ELE, DATA_TYPE_UINT64,
171027Sjchu 	    CSR_XR(csr_base, MMU_ERROR_LOG_ENABLE),
171127Sjchu 	    FIRE_MMU_IE, DATA_TYPE_UINT64,
171227Sjchu 	    CSR_XR(csr_base, MMU_INTERRUPT_ENABLE),
171327Sjchu 	    FIRE_MMU_IS, DATA_TYPE_UINT64,
171427Sjchu 	    ss_reg,
171527Sjchu 	    FIRE_MMU_ESS, DATA_TYPE_UINT64,
171627Sjchu 	    CSR_XR(csr_base, MMU_ERROR_STATUS_SET),
171727Sjchu 	    NULL);
171827Sjchu 
17193274Set142600 	return (PX_NO_PANIC);
172027Sjchu }
172127Sjchu 
17223274Set142600 /*
17233274Set142600  * IMU function to handle all Received but Not Enabled errors.
17243274Set142600  *
17253274Set142600  * These errors are due to transactions modes in which the PX driver was not
17263274Set142600  * setup to be able to do.  If possible, inform the driver that their DMA has
17273274Set142600  * failed by marking their DMA handle as failed, but do not panic the system.
17283274Set142600  * Most likely the address is not valid, as Fire wasn't setup to handle them in
17293274Set142600  * the first place.
17303274Set142600  *
17313274Set142600  * These errors are not retryable, unless the PX mode has changed, otherwise the
17323274Set142600  * same error will occur again.
17333274Set142600  */
173427Sjchu int
173527Sjchu px_err_mmu_rbne_handle(dev_info_t *rpdip, caddr_t csr_base,
173627Sjchu 	ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
173727Sjchu 	px_err_bit_desc_t *err_bit_descr)
173827Sjchu {
17393274Set142600 	pcie_req_id_t bdf;
174027Sjchu 
17413274Set142600 	if (!PX_ERR_IS_PRI(err_bit_descr->bit))
17423274Set142600 		goto done;
1743260Set142600 
17443274Set142600 	bdf = (pcie_req_id_t)CSR_FR(csr_base, MMU_TRANSLATION_FAULT_STATUS, ID);
17453274Set142600 	(void) pf_hdl_lookup(rpdip, derr->fme_ena, PF_DMA_ADDR, NULL,
17463274Set142600 	    bdf);
174727Sjchu 
17483274Set142600 done:
17493274Set142600 	return (px_err_no_panic_handle(rpdip, csr_base, derr, err_reg_descr,
17503274Set142600 		    err_bit_descr));
175127Sjchu }
175227Sjchu 
17533274Set142600 /*
17543274Set142600  * IMU function to handle all invalid address errors.
17553274Set142600  *
17563274Set142600  * These errors are due to transactions in which the address is not recognized.
17573274Set142600  * If possible, inform the driver that all DMAs have failed by marking their DMA
17583274Set142600  * handles.  Fire should not panic the system, it'll be up to the driver to
17593274Set142600  * panic.  The address logged is invalid.
17603274Set142600  *
17613274Set142600  * These errors are not retryable since retrying the same transaction with the
17623274Set142600  * same invalid address will result in the same error.
17633274Set142600  */
176427Sjchu /* ARGSUSED */
176527Sjchu int
176627Sjchu px_err_mmu_tfa_handle(dev_info_t *rpdip, caddr_t csr_base,
176727Sjchu 	ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
176827Sjchu 	px_err_bit_desc_t *err_bit_descr)
176927Sjchu {
17703274Set142600 	pcie_req_id_t bdf;
17713274Set142600 
17723274Set142600 	if (!PX_ERR_IS_PRI(err_bit_descr->bit))
17733274Set142600 		goto done;
177427Sjchu 
17753274Set142600 	bdf = (pcie_req_id_t)CSR_FR(csr_base, MMU_TRANSLATION_FAULT_STATUS, ID);
17763274Set142600 	(void) pf_hdl_lookup(rpdip, derr->fme_ena, PF_DMA_ADDR, NULL,
17773274Set142600 	    bdf);
1778739Sjchu 
17793274Set142600 done:
17803274Set142600 	return (px_err_no_panic_handle(rpdip, csr_base, derr, err_reg_descr,
17813274Set142600 		    err_bit_descr));
178227Sjchu }
178327Sjchu 
17843274Set142600 /*
17853274Set142600  * IMU function to handle normal transactions that encounter a parity error.
17863274Set142600  *
17873274Set142600  * These errors are due to transactions that enouter a parity error. If
17883274Set142600  * possible, inform the driver that their DMA have failed and that they should
17893274Set142600  * retry.  If Fire is unable to contact the leaf driver, panic the system.
17903274Set142600  * Otherwise, it'll be up to the device to determine is this is a panicable
17913274Set142600  * error.
17923274Set142600  */
179327Sjchu /* ARGSUSED */
179427Sjchu int
17953274Set142600 px_err_mmu_parity_handle(dev_info_t *rpdip, caddr_t csr_base,
179627Sjchu 	ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
179727Sjchu 	px_err_bit_desc_t *err_bit_descr)
179827Sjchu {
17993274Set142600 	uint64_t mmu_tfa;
18003274Set142600 	pcie_req_id_t bdf;
18013274Set142600 	int status = DDI_FM_UNKNOWN;
180227Sjchu 
18033274Set142600 	if (!PX_ERR_IS_PRI(err_bit_descr->bit))
18043274Set142600 		goto done;
1805739Sjchu 
180627Sjchu 	mmu_tfa = CSR_XR(csr_base, MMU_TRANSLATION_FAULT_ADDRESS);
18073274Set142600 	bdf = (pcie_req_id_t)CSR_FR(csr_base, MMU_TRANSLATION_FAULT_STATUS, ID);
18083274Set142600 	status = pf_hdl_lookup(rpdip, derr->fme_ena, PF_DMA_ADDR,
18093274Set142600 	    (uint32_t)mmu_tfa, bdf);
18103274Set142600 
18113274Set142600 done:
18123274Set142600 	if (status == DDI_FM_UNKNOWN)
18133274Set142600 		return (px_err_panic_handle(rpdip, csr_base, derr,
18143274Set142600 			    err_reg_descr, err_bit_descr));
18153274Set142600 	else
18163274Set142600 		return (px_err_no_panic_handle(rpdip, csr_base, derr,
18173274Set142600 			    err_reg_descr, err_bit_descr));
18183274Set142600 }
18193274Set142600 
18203274Set142600 /*
18213274Set142600  * wuc/ruc event - Mark the handle of the failed PIO access.  Return "no_panic"
18223274Set142600  */
18233274Set142600 /* ARGSUSED */
18243274Set142600 int
18253274Set142600 px_err_wuc_ruc_handle(dev_info_t *rpdip, caddr_t csr_base,
18263274Set142600 	ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
18273274Set142600 	px_err_bit_desc_t *err_bit_descr)
18283274Set142600 {
18293274Set142600 	px_t		*px_p = DIP_TO_STATE(rpdip);
18303274Set142600 	pxu_t		*pxu_p = (pxu_t *)px_p->px_plat_p;
18313274Set142600 	uint64_t 	data;
18323274Set142600 	uint32_t	addr, hdr;
18333274Set142600 	pcie_tlp_hdr_t	*tlp;
18343274Set142600 	int		sts = PF_HDL_NOTFOUND;
183527Sjchu 
18363274Set142600 	if (!PX_ERR_IS_PRI(err_bit_descr->bit))
18373274Set142600 		goto done;
18383274Set142600 
18393274Set142600 	data = CSR_XR(csr_base, TLU_TRANSMIT_OTHER_EVENT_HEADER1_LOG);
18403274Set142600 	hdr = (uint32_t)(data >> 32);
18413274Set142600 	tlp = (pcie_tlp_hdr_t *)&hdr;
18423274Set142600 	data = CSR_XR(csr_base, TLU_TRANSMIT_OTHER_EVENT_HEADER2_LOG);
18433274Set142600 	addr = (uint32_t)(data >> 32);
18443274Set142600 
18453274Set142600 	switch (tlp->type) {
18463274Set142600 	case PCIE_TLP_TYPE_IO:
18473274Set142600 	case PCIE_TLP_TYPE_MEM:
18483274Set142600 	case PCIE_TLP_TYPE_MEMLK:
18493274Set142600 		sts = pf_hdl_lookup(rpdip, derr->fme_ena, PF_PIO_ADDR,
18503274Set142600 		    addr, NULL);
18513274Set142600 		break;
18523274Set142600 	case PCIE_TLP_TYPE_CFG0:
18533274Set142600 	case PCIE_TLP_TYPE_CFG1:
18543274Set142600 		sts = pf_hdl_lookup(rpdip, derr->fme_ena, PF_CFG_ADDR,
18553274Set142600 		    addr, (addr >> 16));
18563274Set142600 		break;
18573274Set142600 	}
18583274Set142600 
18593274Set142600 done:
18603274Set142600 	if ((sts == PF_HDL_NOTFOUND) && (pxu_p->cpr_flag == PX_NOT_CPR))
18613274Set142600 		return (px_err_protected_handle(rpdip, csr_base, derr,
18623274Set142600 			    err_reg_descr, err_bit_descr));
18633274Set142600 
18643274Set142600 	return (px_err_no_panic_handle(rpdip, csr_base, derr,
18653274Set142600 		    err_reg_descr, err_bit_descr));
186627Sjchu }
186727Sjchu 
1868118Sjchu /*
18691147Sjchu  * TLU LUP event - if caused by power management activity, then it is expected.
18701147Sjchu  * In all other cases, it is an error.
1871118Sjchu  */
1872118Sjchu /* ARGSUSED */
1873118Sjchu int
1874118Sjchu px_err_tlu_lup_handle(dev_info_t *rpdip, caddr_t csr_base,
1875118Sjchu 	ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
1876118Sjchu 	px_err_bit_desc_t *err_bit_descr)
1877118Sjchu {
1878118Sjchu 	px_t	*px_p = DIP_TO_STATE(rpdip);
1879118Sjchu 
1880118Sjchu 	/*
18811147Sjchu 	 * power management code is currently the only segment that sets
18821147Sjchu 	 * px_lup_pending to indicate its expectation for a healthy LUP
18831147Sjchu 	 * event.  For all other occasions, LUP event should be flaged as
18841147Sjchu 	 * error condition.
1885118Sjchu 	 */
18861147Sjchu 	return ((atomic_cas_32(&px_p->px_lup_pending, 1, 0) == 0) ?
18873274Set142600 	    PX_NO_PANIC : PX_EXPECTED);
18881147Sjchu }
1889118Sjchu 
18901147Sjchu /*
18911147Sjchu  * TLU LDN event - if caused by power management activity, then it is expected.
18921147Sjchu  * In all other cases, it is an error.
18931147Sjchu  */
18941147Sjchu /* ARGSUSED */
18951147Sjchu int
18961147Sjchu px_err_tlu_ldn_handle(dev_info_t *rpdip, caddr_t csr_base,
18971147Sjchu 	ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
18981147Sjchu 	px_err_bit_desc_t *err_bit_descr)
18991147Sjchu {
19001147Sjchu 	px_t    *px_p = DIP_TO_STATE(rpdip);
19013274Set142600 	return ((px_p->px_pm_flags & PX_LDN_EXPECTED) ? PX_EXPECTED :
19023274Set142600 	    PX_NO_PANIC);
1903118Sjchu }
1904118Sjchu 
190527Sjchu /* PEC ILU none - see io erpt doc, section 3.1 */
190627Sjchu PX_ERPT_SEND_DEC(pec_ilu)
190727Sjchu {
190827Sjchu 	char		buf[FM_MAX_CLASS];
1909739Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(bit);
191027Sjchu 
191127Sjchu 	(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
191227Sjchu 	ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
191327Sjchu 	    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
1914739Sjchu 	    FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
191527Sjchu 	    FIRE_ILU_ELE, DATA_TYPE_UINT64,
191627Sjchu 	    CSR_XR(csr_base, ILU_ERROR_LOG_ENABLE),
191727Sjchu 	    FIRE_ILU_IE, DATA_TYPE_UINT64,
191827Sjchu 	    CSR_XR(csr_base, ILU_INTERRUPT_ENABLE),
191927Sjchu 	    FIRE_ILU_IS, DATA_TYPE_UINT64,
192027Sjchu 	    ss_reg,
192127Sjchu 	    FIRE_ILU_ESS, DATA_TYPE_UINT64,
192227Sjchu 	    CSR_XR(csr_base, ILU_ERROR_STATUS_SET),
192327Sjchu 	    NULL);
192427Sjchu 
19253274Set142600 	return (PX_NO_PANIC);
192627Sjchu }
192727Sjchu 
1928383Set142600 /* PCIEX UE Errors */
1929383Set142600 /* ARGSUSED */
1930671Skrishnae int
1931383Set142600 px_err_pciex_ue_handle(dev_info_t *rpdip, caddr_t csr_base,
1932383Set142600 	ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
1933383Set142600 	px_err_bit_desc_t *err_bit_descr)
1934383Set142600 {
19353274Set142600 	px_err_pcie_t	regs = {0};
19363274Set142600 	uint32_t	err_bit;
19373274Set142600 	int		err;
19383274Set142600 	uint64_t	log;
19393274Set142600 
19403274Set142600 	if (err_bit_descr->bit < 32) {
19413274Set142600 		err_bit = (uint32_t)BITMASK(err_bit_descr->bit);
19423274Set142600 		regs.ue_reg = err_bit;
19433274Set142600 		regs.primary_ue = err_bit;
19443274Set142600 
19453274Set142600 		/*
19463274Set142600 		 * Log the Received Log for PTLP and UR.  The PTLP most likely
19473274Set142600 		 * is a poisoned completion.  The original transaction will be
19483274Set142600 		 * logged inthe Transmit Log.
19493274Set142600 		 */
19503274Set142600 		if (err_bit & (PCIE_AER_UCE_PTLP | PCIE_AER_UCE_UR)) {
19513274Set142600 			log = CSR_XR(csr_base,
19523274Set142600 			    TLU_RECEIVE_UNCORRECTABLE_ERROR_HEADER1_LOG);
19533274Set142600 			regs.rx_hdr1 = (uint32_t)(log >> 32);
19543274Set142600 			regs.rx_hdr2 = (uint32_t)(log && 0xFFFFFFFF);
1955383Set142600 
19563274Set142600 			log = CSR_XR(csr_base,
19573274Set142600 			    TLU_RECEIVE_UNCORRECTABLE_ERROR_HEADER2_LOG);
19583274Set142600 			regs.rx_hdr3 = (uint32_t)(log >> 32);
19593274Set142600 			regs.rx_hdr4 = (uint32_t)(log && 0xFFFFFFFF);
19603274Set142600 		}
19613274Set142600 
19623274Set142600 		if (err_bit & (PCIE_AER_UCE_PTLP)) {
19633274Set142600 			log = CSR_XR(csr_base,
19643274Set142600 			    TLU_TRANSMIT_UNCORRECTABLE_ERROR_HEADER1_LOG);
19653274Set142600 			regs.tx_hdr1 = (uint32_t)(log >> 32);
19663274Set142600 			regs.tx_hdr2 = (uint32_t)(log && 0xFFFFFFFF);
19673274Set142600 
19683274Set142600 			log = CSR_XR(csr_base,
19693274Set142600 			    TLU_TRANSMIT_UNCORRECTABLE_ERROR_HEADER2_LOG);
19703274Set142600 			regs.tx_hdr3 = (uint32_t)(log >> 32);
19713274Set142600 			regs.tx_hdr4 = (uint32_t)(log && 0xFFFFFFFF);
19723274Set142600 		}
19733274Set142600 	} else {
19743274Set142600 		regs.ue_reg = (uint32_t)BITMASK(err_bit_descr->bit - 32);
19753274Set142600 	}
19763274Set142600 
19773274Set142600 	err = px_err_check_pcie(rpdip, derr, &regs);
19783274Set142600 
19793274Set142600 	if (err == PX_PANIC) {
19803274Set142600 		return (px_err_panic_handle(rpdip, csr_base, derr,
19813274Set142600 			    err_reg_descr, err_bit_descr));
19823274Set142600 	} else {
19833274Set142600 		return (px_err_no_panic_handle(rpdip, csr_base, derr,
19843274Set142600 			    err_reg_descr, err_bit_descr));
19853274Set142600 	}
1986383Set142600 }
1987383Set142600 
19883274Set142600 /* PCI-E Uncorrectable Errors */
1989383Set142600 PX_ERPT_SEND_DEC(pciex_rx_ue)
1990383Set142600 {
1991383Set142600 	char		buf[FM_MAX_CLASS];
1992739Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(bit);
1993383Set142600 
1994383Set142600 	(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
1995383Set142600 	ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
1996383Set142600 	    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
1997739Sjchu 	    FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
1998383Set142600 	    FIRE_TLU_UELE, DATA_TYPE_UINT64,
1999383Set142600 	    CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_LOG_ENABLE),
2000383Set142600 	    FIRE_TLU_UIE, DATA_TYPE_UINT64,
2001383Set142600 	    CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_INTERRUPT_ENABLE),
2002383Set142600 	    FIRE_TLU_UIS, DATA_TYPE_UINT64,
2003383Set142600 	    ss_reg,
2004383Set142600 	    FIRE_TLU_UESS, DATA_TYPE_UINT64,
2005383Set142600 	    CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_STATUS_SET),
2006383Set142600 	    FIRE_TLU_RUEH1L, DATA_TYPE_UINT64,
2007383Set142600 	    CSR_XR(csr_base, TLU_RECEIVE_UNCORRECTABLE_ERROR_HEADER1_LOG),
2008383Set142600 	    FIRE_TLU_RUEH2L, DATA_TYPE_UINT64,
2009383Set142600 	    CSR_XR(csr_base, TLU_RECEIVE_UNCORRECTABLE_ERROR_HEADER2_LOG),
2010383Set142600 	    NULL);
2011383Set142600 
20123274Set142600 	return (PX_NO_PANIC);
2013383Set142600 }
2014383Set142600 
20153274Set142600 /* PCI-E Uncorrectable Errors */
2016383Set142600 PX_ERPT_SEND_DEC(pciex_tx_ue)
2017383Set142600 {
2018383Set142600 	char		buf[FM_MAX_CLASS];
2019739Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(bit);
2020383Set142600 
2021383Set142600 	(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
2022383Set142600 	ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
2023383Set142600 	    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
2024739Sjchu 	    FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
2025383Set142600 	    FIRE_TLU_UELE, DATA_TYPE_UINT64,
2026383Set142600 	    CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_LOG_ENABLE),
2027383Set142600 	    FIRE_TLU_UIE, DATA_TYPE_UINT64,
2028383Set142600 	    CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_INTERRUPT_ENABLE),
2029383Set142600 	    FIRE_TLU_UIS, DATA_TYPE_UINT64,
2030383Set142600 	    ss_reg,
2031383Set142600 	    FIRE_TLU_UESS, DATA_TYPE_UINT64,
2032383Set142600 	    CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_STATUS_SET),
2033383Set142600 	    FIRE_TLU_TUEH1L, DATA_TYPE_UINT64,
2034383Set142600 	    CSR_XR(csr_base, TLU_TRANSMIT_UNCORRECTABLE_ERROR_HEADER1_LOG),
2035383Set142600 	    FIRE_TLU_TUEH2L, DATA_TYPE_UINT64,
2036383Set142600 	    CSR_XR(csr_base, TLU_TRANSMIT_UNCORRECTABLE_ERROR_HEADER2_LOG),
2037383Set142600 	    NULL);
2038383Set142600 
20393274Set142600 	return (PX_NO_PANIC);
2040383Set142600 }
2041383Set142600 
20423274Set142600 /* PCI-E Uncorrectable Errors */
2043383Set142600 PX_ERPT_SEND_DEC(pciex_rx_tx_ue)
2044383Set142600 {
2045383Set142600 	char		buf[FM_MAX_CLASS];
2046739Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(bit);
2047383Set142600 
2048383Set142600 	(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
2049383Set142600 	ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
2050383Set142600 	    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
2051739Sjchu 	    FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
2052383Set142600 	    FIRE_TLU_UELE, DATA_TYPE_UINT64,
2053383Set142600 	    CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_LOG_ENABLE),
2054383Set142600 	    FIRE_TLU_UIE, DATA_TYPE_UINT64,
2055383Set142600 	    CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_INTERRUPT_ENABLE),
2056383Set142600 	    FIRE_TLU_UIS, DATA_TYPE_UINT64,
2057383Set142600 	    ss_reg,
2058383Set142600 	    FIRE_TLU_UESS, DATA_TYPE_UINT64,
2059383Set142600 	    CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_STATUS_SET),
2060383Set142600 	    FIRE_TLU_RUEH1L, DATA_TYPE_UINT64,
2061383Set142600 	    CSR_XR(csr_base, TLU_RECEIVE_UNCORRECTABLE_ERROR_HEADER1_LOG),
2062383Set142600 	    FIRE_TLU_RUEH2L, DATA_TYPE_UINT64,
2063383Set142600 	    CSR_XR(csr_base, TLU_RECEIVE_UNCORRECTABLE_ERROR_HEADER2_LOG),
2064383Set142600 	    FIRE_TLU_TUEH1L, DATA_TYPE_UINT64,
2065383Set142600 	    CSR_XR(csr_base, TLU_TRANSMIT_UNCORRECTABLE_ERROR_HEADER1_LOG),
2066383Set142600 	    FIRE_TLU_TUEH2L, DATA_TYPE_UINT64,
2067383Set142600 	    CSR_XR(csr_base, TLU_TRANSMIT_UNCORRECTABLE_ERROR_HEADER2_LOG),
2068383Set142600 	    NULL);
2069383Set142600 
20703274Set142600 	return (PX_NO_PANIC);
2071383Set142600 }
2072383Set142600 
20733274Set142600 /* PCI-E Uncorrectable Errors */
2074383Set142600 PX_ERPT_SEND_DEC(pciex_ue)
2075383Set142600 {
2076383Set142600 	char		buf[FM_MAX_CLASS];
2077739Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(bit);
2078383Set142600 
2079383Set142600 	(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
2080383Set142600 	ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
2081383Set142600 	    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
2082739Sjchu 	    FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
2083383Set142600 	    FIRE_TLU_UELE, DATA_TYPE_UINT64,
2084383Set142600 	    CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_LOG_ENABLE),
2085383Set142600 	    FIRE_TLU_UIE, DATA_TYPE_UINT64,
2086383Set142600 	    CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_INTERRUPT_ENABLE),
2087383Set142600 	    FIRE_TLU_UIS, DATA_TYPE_UINT64,
2088383Set142600 	    ss_reg,
2089383Set142600 	    FIRE_TLU_UESS, DATA_TYPE_UINT64,
2090383Set142600 	    CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_STATUS_SET),
2091383Set142600 	    NULL);
2092383Set142600 
20933274Set142600 	return (PX_NO_PANIC);
2094383Set142600 }
2095383Set142600 
2096383Set142600 /* PCIEX UE Errors */
2097383Set142600 /* ARGSUSED */
2098671Skrishnae int
2099383Set142600 px_err_pciex_ce_handle(dev_info_t *rpdip, caddr_t csr_base,
2100383Set142600 	ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
2101383Set142600 	px_err_bit_desc_t *err_bit_descr)
2102383Set142600 {
21033274Set142600 	px_err_pcie_t	regs = {0};
21043274Set142600 	int		err;
21053274Set142600 
21063274Set142600 	if (err_bit_descr->bit < 32)
21073274Set142600 		regs.ce_reg = (uint32_t)BITMASK(err_bit_descr->bit);
21083274Set142600 	else
21093274Set142600 		regs.ce_reg = (uint32_t)BITMASK(err_bit_descr->bit - 32);
2110383Set142600 
21113274Set142600 	err = px_err_check_pcie(rpdip, derr, &regs);
21123274Set142600 
21133274Set142600 	if (err == PX_PANIC) {
21143274Set142600 		return (px_err_panic_handle(rpdip, csr_base, derr,
21153274Set142600 			    err_reg_descr, err_bit_descr));
21163274Set142600 	} else {
21173274Set142600 		return (px_err_no_panic_handle(rpdip, csr_base, derr,
21183274Set142600 			    err_reg_descr, err_bit_descr));
21193274Set142600 	}
2120383Set142600 }
2121383Set142600 
212227Sjchu /* PCI-E Correctable Errors - see io erpt doc, section 3.6 */
212327Sjchu PX_ERPT_SEND_DEC(pciex_ce)
212427Sjchu {
212527Sjchu 	char		buf[FM_MAX_CLASS];
2126739Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(bit);
212727Sjchu 
212827Sjchu 	(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
212927Sjchu 	ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
213027Sjchu 	    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
2131739Sjchu 	    FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
213227Sjchu 	    FIRE_TLU_CELE, DATA_TYPE_UINT64,
213327Sjchu 	    CSR_XR(csr_base, TLU_CORRECTABLE_ERROR_LOG_ENABLE),
213427Sjchu 	    FIRE_TLU_CIE, DATA_TYPE_UINT64,
213527Sjchu 	    CSR_XR(csr_base, TLU_CORRECTABLE_ERROR_INTERRUPT_ENABLE),
213627Sjchu 	    FIRE_TLU_CIS, DATA_TYPE_UINT64,
213727Sjchu 	    ss_reg,
213827Sjchu 	    FIRE_TLU_CESS, DATA_TYPE_UINT64,
213927Sjchu 	    CSR_XR(csr_base, TLU_CORRECTABLE_ERROR_STATUS_SET),
214027Sjchu 	    NULL);
214127Sjchu 
21423274Set142600 	return (PX_NO_PANIC);
214327Sjchu }
214427Sjchu 
214527Sjchu /* TLU Other Event Status (receive only) - see io erpt doc, section 3.7 */
214627Sjchu PX_ERPT_SEND_DEC(pciex_rx_oe)
214727Sjchu {
214827Sjchu 	char		buf[FM_MAX_CLASS];
2149739Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(bit);
215027Sjchu 
215127Sjchu 	(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
215227Sjchu 	ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
215327Sjchu 	    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
2154739Sjchu 	    FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
215527Sjchu 	    FIRE_TLU_OEELE, DATA_TYPE_UINT64,
215627Sjchu 	    CSR_XR(csr_base, TLU_OTHER_EVENT_LOG_ENABLE),
215727Sjchu 	    FIRE_TLU_OEIE, DATA_TYPE_UINT64,
215827Sjchu 	    CSR_XR(csr_base, TLU_OTHER_EVENT_INTERRUPT_ENABLE),
215927Sjchu 	    FIRE_TLU_OEIS, DATA_TYPE_UINT64,
216027Sjchu 	    ss_reg,
216127Sjchu 	    FIRE_TLU_OEESS, DATA_TYPE_UINT64,
216227Sjchu 	    CSR_XR(csr_base, TLU_OTHER_EVENT_STATUS_SET),
216327Sjchu 	    FIRE_TLU_RUEH1L, DATA_TYPE_UINT64,
216427Sjchu 	    CSR_XR(csr_base, TLU_RECEIVE_OTHER_EVENT_HEADER1_LOG),
2165260Set142600 	    FIRE_TLU_RUEH2L, DATA_TYPE_UINT64,
216627Sjchu 	    CSR_XR(csr_base, TLU_RECEIVE_OTHER_EVENT_HEADER2_LOG),
216727Sjchu 	    NULL);
216827Sjchu 
21693274Set142600 	return (PX_NO_PANIC);
217027Sjchu }
217127Sjchu 
217227Sjchu /* TLU Other Event Status (rx + tx) - see io erpt doc, section 3.8 */
217327Sjchu PX_ERPT_SEND_DEC(pciex_rx_tx_oe)
217427Sjchu {
217527Sjchu 	char		buf[FM_MAX_CLASS];
2176739Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(bit);
21773274Set142600 	px_t		*px_p = DIP_TO_STATE(rpdip);
21783274Set142600 	uint32_t	trans_type, fault_addr = 0;
21793274Set142600 	uint64_t	rx_h1, rx_h2, tx_h1, tx_h2;
21803274Set142600 	uint16_t	s_status;
21813274Set142600 	int		sts;
21823274Set142600 	pcie_req_id_t	fault_bdf = 0;
21833274Set142600 	pcie_cpl_t	*cpl;
21843274Set142600 	pf_data_t	pf_data = {0};
21853274Set142600 
21863274Set142600 	rx_h1 = CSR_XR(csr_base, TLU_RECEIVE_OTHER_EVENT_HEADER1_LOG);
21873274Set142600 	rx_h2 = CSR_XR(csr_base, TLU_RECEIVE_OTHER_EVENT_HEADER2_LOG);
21883274Set142600 	tx_h1 = CSR_XR(csr_base, TLU_TRANSMIT_OTHER_EVENT_HEADER1_LOG);
21893274Set142600 	tx_h2 = CSR_XR(csr_base, TLU_TRANSMIT_OTHER_EVENT_HEADER2_LOG);
21903274Set142600 
21913274Set142600 	if ((bit == TLU_OTHER_EVENT_STATUS_SET_RUC_P) ||
21923274Set142600 	    (bit == TLU_OTHER_EVENT_STATUS_SET_WUC_P)) {
21933274Set142600 		pf_data.aer_h0 = (uint32_t)(rx_h1 >> 32);
21943274Set142600 		pf_data.aer_h1 = (uint32_t)rx_h1;
21953274Set142600 		pf_data.aer_h2 = (uint32_t)(rx_h2 >> 32);
21963274Set142600 		pf_data.aer_h3 = (uint32_t)rx_h2;
21973274Set142600 
21983274Set142600 		/* get completer bdf (fault bdf) from rx logs */
21993274Set142600 		cpl = (pcie_cpl_t *)&pf_data.aer_h1;
22003274Set142600 		fault_bdf = cpl->cid;
22013274Set142600 
22023274Set142600 		/* Figure out if UR/CA from rx logs */
22033274Set142600 		if (cpl->status == PCIE_CPL_STS_UR)
22043274Set142600 			s_status = PCI_STAT_R_MAST_AB;
22053274Set142600 		else if (cpl->status == PCIE_CPL_STS_CA)
22063274Set142600 			s_status = PCI_STAT_R_TARG_AB;
22073274Set142600 
22083274Set142600 
22093274Set142600 		pf_data.aer_h0 = (uint32_t)(tx_h1 >> 32);
22103274Set142600 		pf_data.aer_h1 = (uint32_t)tx_h1;
22113274Set142600 		pf_data.aer_h2 = (uint32_t)(tx_h2 >> 32);
22123274Set142600 		pf_data.aer_h3 = (uint32_t)tx_h2;
22133274Set142600 
22143274Set142600 		/* get fault addr from tx logs */
22153274Set142600 		sts = pf_tlp_decode(rpdip, &pf_data, 0, &fault_addr,
22163274Set142600 		    &trans_type);
22173274Set142600 
22183274Set142600 		if (sts == DDI_SUCCESS)
22193274Set142600 			(void) px_rp_en_q(px_p, fault_bdf, fault_addr,
22203274Set142600 			    s_status);
22213274Set142600 	}
222227Sjchu 
222327Sjchu 	(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
222427Sjchu 	ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
222527Sjchu 	    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
2226739Sjchu 	    FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
222727Sjchu 	    FIRE_TLU_OEELE, DATA_TYPE_UINT64,
222827Sjchu 	    CSR_XR(csr_base, TLU_OTHER_EVENT_LOG_ENABLE),
222927Sjchu 	    FIRE_TLU_OEIE, DATA_TYPE_UINT64,
223027Sjchu 	    CSR_XR(csr_base, TLU_OTHER_EVENT_INTERRUPT_ENABLE),
223127Sjchu 	    FIRE_TLU_OEIS, DATA_TYPE_UINT64,
223227Sjchu 	    ss_reg,
223327Sjchu 	    FIRE_TLU_OEESS, DATA_TYPE_UINT64,
223427Sjchu 	    CSR_XR(csr_base, TLU_OTHER_EVENT_STATUS_SET),
22353274Set142600 	    FIRE_TLU_ROEEH1L, DATA_TYPE_UINT64, rx_h1,
22363274Set142600 	    FIRE_TLU_ROEEH2L, DATA_TYPE_UINT64, rx_h2,
22373274Set142600 	    FIRE_TLU_TOEEH1L, DATA_TYPE_UINT64, tx_h1,
22383274Set142600 	    FIRE_TLU_TOEEH2L, DATA_TYPE_UINT64, tx_h2,
223927Sjchu 	    NULL);
224027Sjchu 
22413274Set142600 	return (PX_NO_PANIC);
224227Sjchu }
224327Sjchu 
224427Sjchu /* TLU Other Event - see io erpt doc, section 3.9 */
224527Sjchu PX_ERPT_SEND_DEC(pciex_oe)
224627Sjchu {
2247739Sjchu 	char		buf[FM_MAX_CLASS];
2248739Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(bit);
224927Sjchu 
225027Sjchu 	(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
225127Sjchu 	ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
225227Sjchu 	    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
2253739Sjchu 	    FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
225427Sjchu 	    FIRE_TLU_OEELE, DATA_TYPE_UINT64,
225527Sjchu 	    CSR_XR(csr_base, TLU_OTHER_EVENT_LOG_ENABLE),
225627Sjchu 	    FIRE_TLU_OEIE, DATA_TYPE_UINT64,
225727Sjchu 	    CSR_XR(csr_base, TLU_OTHER_EVENT_INTERRUPT_ENABLE),
225827Sjchu 	    FIRE_TLU_OEIS, DATA_TYPE_UINT64,
225927Sjchu 	    ss_reg,
226027Sjchu 	    FIRE_TLU_OEESS, DATA_TYPE_UINT64,
226127Sjchu 	    CSR_XR(csr_base, TLU_OTHER_EVENT_STATUS_SET),
226227Sjchu 	    NULL);
226327Sjchu 
22643274Set142600 	return (PX_NO_PANIC);
226527Sjchu }
2266