xref: /illumos-gate/usr/src/uts/sun4u/io/px/px_err.c (revision e214b19e)
1f8d2de6bSjchu /*
2f8d2de6bSjchu  * CDDL HEADER START
3f8d2de6bSjchu  *
4f8d2de6bSjchu  * The contents of this file are subject to the terms of the
501689544Sjchu  * Common Development and Distribution License (the "License").
601689544Sjchu  * You may not use this file except in compliance with the License.
7f8d2de6bSjchu  *
8f8d2de6bSjchu  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9f8d2de6bSjchu  * or http://www.opensolaris.org/os/licensing.
10f8d2de6bSjchu  * See the License for the specific language governing permissions
11f8d2de6bSjchu  * and limitations under the License.
12f8d2de6bSjchu  *
13f8d2de6bSjchu  * When distributing Covered Code, include this CDDL HEADER in each
14f8d2de6bSjchu  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15f8d2de6bSjchu  * If applicable, add the following below this CDDL HEADER, with the
16f8d2de6bSjchu  * fields enclosed by brackets "[]" replaced with your own identifying
17f8d2de6bSjchu  * information: Portions Copyright [yyyy] [name of copyright owner]
18f8d2de6bSjchu  *
19f8d2de6bSjchu  * CDDL HEADER END
20f8d2de6bSjchu  */
2107d06da5SSurya Prakki 
22f8d2de6bSjchu /*
235613d828SKrishna Elango  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
24f8d2de6bSjchu  * Use is subject to license terms.
25f8d2de6bSjchu  */
26f8d2de6bSjchu 
27f8d2de6bSjchu /*
28f8d2de6bSjchu  * sun4u Fire Error Handling
29f8d2de6bSjchu  */
30f8d2de6bSjchu 
31f8d2de6bSjchu #include <sys/types.h>
32f8d2de6bSjchu #include <sys/ddi.h>
33f8d2de6bSjchu #include <sys/sunddi.h>
34eae2e508Skrishnae #include <sys/sunndi.h>
35f8d2de6bSjchu #include <sys/fm/protocol.h>
36f8d2de6bSjchu #include <sys/fm/util.h>
37f8d2de6bSjchu #include <sys/pcie.h>
38f8d2de6bSjchu #include <sys/pcie_impl.h>
39f8d2de6bSjchu #include "px_obj.h"
40f8d2de6bSjchu #include <px_regs.h>
41f8d2de6bSjchu #include <px_csr.h>
42f8d2de6bSjchu #include <sys/membar.h>
4325cf1a30Sjl #include <sys/machcpuvar.h>
4425cf1a30Sjl #include <sys/platform_module.h>
45f8d2de6bSjchu #include "px_lib4u.h"
46f8d2de6bSjchu #include "px_err.h"
47f8d2de6bSjchu #include "px_err_impl.h"
4825cf1a30Sjl #include "oberon_regs.h"
4925cf1a30Sjl 
5025cf1a30Sjl uint64_t px_tlu_ue_intr_mask	= PX_ERR_EN_ALL;
5125cf1a30Sjl uint64_t px_tlu_ue_log_mask	= PX_ERR_EN_ALL;
5225cf1a30Sjl uint64_t px_tlu_ue_count_mask	= PX_ERR_EN_ALL;
5325cf1a30Sjl 
5425cf1a30Sjl uint64_t px_tlu_ce_intr_mask	= PX_ERR_MASK_NONE;
5525cf1a30Sjl uint64_t px_tlu_ce_log_mask	= PX_ERR_MASK_NONE;
5625cf1a30Sjl uint64_t px_tlu_ce_count_mask	= PX_ERR_MASK_NONE;
5725cf1a30Sjl 
5825cf1a30Sjl /*
5925cf1a30Sjl  * Do not enable Link Interrupts
6025cf1a30Sjl  */
6125cf1a30Sjl uint64_t px_tlu_oe_intr_mask	= PX_ERR_EN_ALL & ~0x80000000800;
6225cf1a30Sjl uint64_t px_tlu_oe_log_mask	= PX_ERR_EN_ALL & ~0x80000000800;
6325cf1a30Sjl uint64_t px_tlu_oe_count_mask	= PX_ERR_EN_ALL;
6425cf1a30Sjl 
6525cf1a30Sjl uint64_t px_mmu_intr_mask	= PX_ERR_EN_ALL;
6625cf1a30Sjl uint64_t px_mmu_log_mask	= PX_ERR_EN_ALL;
6725cf1a30Sjl uint64_t px_mmu_count_mask	= PX_ERR_EN_ALL;
6825cf1a30Sjl 
6925cf1a30Sjl uint64_t px_imu_intr_mask	= PX_ERR_EN_ALL;
7025cf1a30Sjl uint64_t px_imu_log_mask	= PX_ERR_EN_ALL;
7125cf1a30Sjl uint64_t px_imu_count_mask	= PX_ERR_EN_ALL;
7225cf1a30Sjl 
7325cf1a30Sjl /*
7425cf1a30Sjl  * (1ull << ILU_INTERRUPT_ENABLE_IHB_PE_S) |
7525cf1a30Sjl  * (1ull << ILU_INTERRUPT_ENABLE_IHB_PE_P);
7625cf1a30Sjl  */
7725cf1a30Sjl uint64_t px_ilu_intr_mask	= (((uint64_t)0x10 << 32) | 0x10);
7825cf1a30Sjl uint64_t px_ilu_log_mask	= (((uint64_t)0x10 << 32) | 0x10);
7925cf1a30Sjl uint64_t px_ilu_count_mask	= PX_ERR_EN_ALL;
8025cf1a30Sjl 
8125cf1a30Sjl uint64_t px_ubc_intr_mask	= PX_ERR_EN_ALL;
8225cf1a30Sjl uint64_t px_ubc_log_mask		= PX_ERR_EN_ALL;
8325cf1a30Sjl uint64_t px_ubc_count_mask	= PX_ERR_EN_ALL;
8425cf1a30Sjl 
8525cf1a30Sjl uint64_t px_jbc_intr_mask	= PX_ERR_EN_ALL;
8625cf1a30Sjl uint64_t px_jbc_log_mask		= PX_ERR_EN_ALL;
8725cf1a30Sjl uint64_t px_jbc_count_mask	= PX_ERR_EN_ALL;
8825cf1a30Sjl 
8925cf1a30Sjl /*
9025cf1a30Sjl  * LPU Intr Registers are reverse encoding from the registers above.
9125cf1a30Sjl  * 1 = disable
9225cf1a30Sjl  * 0 = enable
9325cf1a30Sjl  *
9425cf1a30Sjl  * Log and Count are however still the same.
9525cf1a30Sjl  */
9625cf1a30Sjl uint64_t px_lpul_intr_mask	= LPU_INTR_DISABLE;
9725cf1a30Sjl uint64_t px_lpul_log_mask	= PX_ERR_EN_ALL;
9825cf1a30Sjl uint64_t px_lpul_count_mask	= PX_ERR_EN_ALL;
9925cf1a30Sjl 
10025cf1a30Sjl uint64_t px_lpup_intr_mask	= LPU_INTR_DISABLE;
10125cf1a30Sjl uint64_t px_lpup_log_mask	= PX_ERR_EN_ALL;
10225cf1a30Sjl uint64_t px_lpup_count_mask	= PX_ERR_EN_ALL;
10325cf1a30Sjl 
10425cf1a30Sjl uint64_t px_lpur_intr_mask	= LPU_INTR_DISABLE;
10525cf1a30Sjl uint64_t px_lpur_log_mask	= PX_ERR_EN_ALL;
10625cf1a30Sjl uint64_t px_lpur_count_mask	= PX_ERR_EN_ALL;
10725cf1a30Sjl 
10825cf1a30Sjl uint64_t px_lpux_intr_mask	= LPU_INTR_DISABLE;
10925cf1a30Sjl uint64_t px_lpux_log_mask	= PX_ERR_EN_ALL;
11025cf1a30Sjl uint64_t px_lpux_count_mask	= PX_ERR_EN_ALL;
11125cf1a30Sjl 
11225cf1a30Sjl uint64_t px_lpus_intr_mask	= LPU_INTR_DISABLE;
11325cf1a30Sjl uint64_t px_lpus_log_mask	= PX_ERR_EN_ALL;
11425cf1a30Sjl uint64_t px_lpus_count_mask	= PX_ERR_EN_ALL;
11525cf1a30Sjl 
11625cf1a30Sjl uint64_t px_lpug_intr_mask	= LPU_INTR_DISABLE;
11725cf1a30Sjl uint64_t px_lpug_log_mask	= PX_ERR_EN_ALL;
11825cf1a30Sjl uint64_t px_lpug_count_mask	= PX_ERR_EN_ALL;
119f8d2de6bSjchu 
120f8d2de6bSjchu /*
121f8d2de6bSjchu  * JBC error bit table
122f8d2de6bSjchu  */
123f8d2de6bSjchu #define	JBC_BIT_DESC(bit, hdl, erpt) \
124f8d2de6bSjchu 	JBC_INTERRUPT_STATUS_ ## bit ## _P, \
125f8d2de6bSjchu 	0, \
126f8d2de6bSjchu 	PX_ERR_BIT_HANDLE(hdl), \
127f8d2de6bSjchu 	PX_ERPT_SEND(erpt), \
1288c334881Sjchu 	PX_ERR_JBC_CLASS(bit) }, \
1298c334881Sjchu 	{ JBC_INTERRUPT_STATUS_ ## bit ## _S, \
1308c334881Sjchu 	0, \
1318c334881Sjchu 	PX_ERR_BIT_HANDLE(hdl), \
1328c334881Sjchu 	PX_ERPT_SEND(erpt), \
133f8d2de6bSjchu 	PX_ERR_JBC_CLASS(bit)
13425cf1a30Sjl px_err_bit_desc_t px_err_jbc_tbl[] = {
135bf8fc234Set 	/* JBC FATAL */
136bf8fc234Set 	{ JBC_BIT_DESC(MB_PEA,	hw_reset,	jbc_fatal) },
137bf8fc234Set 	{ JBC_BIT_DESC(CPE,	hw_reset,	jbc_fatal) },
138bf8fc234Set 	{ JBC_BIT_DESC(APE,	hw_reset,	jbc_fatal) },
139bf8fc234Set 	{ JBC_BIT_DESC(PIO_CPE,	hw_reset,	jbc_fatal) },
140bf8fc234Set 	{ JBC_BIT_DESC(JTCEEW,	hw_reset,	jbc_fatal) },
141bf8fc234Set 	{ JBC_BIT_DESC(JTCEEI,	hw_reset,	jbc_fatal) },
142bf8fc234Set 	{ JBC_BIT_DESC(JTCEER,	hw_reset,	jbc_fatal) },
143bf8fc234Set 
144bf8fc234Set 	/* JBC MERGE */
145f8d2de6bSjchu 	{ JBC_BIT_DESC(MB_PER,	jbc_merge,	jbc_merge) },
146f8d2de6bSjchu 	{ JBC_BIT_DESC(MB_PEW,	jbc_merge,	jbc_merge) },
147f8d2de6bSjchu 
148bf8fc234Set 	/* JBC Jbusint IN */
149bf8fc234Set 	{ JBC_BIT_DESC(UE_ASYN,	panic,		jbc_in) },
150bf8fc234Set 	{ JBC_BIT_DESC(CE_ASYN,	no_error,	jbc_in) },
151bf8fc234Set 	{ JBC_BIT_DESC(JTE,	panic,		jbc_in) },
152bf8fc234Set 	{ JBC_BIT_DESC(JBE,	panic,		jbc_in) },
153bf8fc234Set 	{ JBC_BIT_DESC(JUE,	panic,		jbc_in) },
154bf8fc234Set 	{ JBC_BIT_DESC(ICISE,	panic,		jbc_in) },
155f8d2de6bSjchu 	{ JBC_BIT_DESC(WR_DPE,	jbc_jbusint_in,	jbc_in) },
156f8d2de6bSjchu 	{ JBC_BIT_DESC(RD_DPE,	jbc_jbusint_in,	jbc_in) },
157bf8fc234Set 	{ JBC_BIT_DESC(ILL_BMW,	panic,		jbc_in) },
158bf8fc234Set 	{ JBC_BIT_DESC(ILL_BMR,	panic,		jbc_in) },
159bf8fc234Set 	{ JBC_BIT_DESC(BJC,	panic,		jbc_in) },
160f8d2de6bSjchu 
161bf8fc234Set 	/* JBC Jbusint Out */
162bf8fc234Set 	{ JBC_BIT_DESC(IJP,	panic,		jbc_out) },
163f8d2de6bSjchu 
164f0a73f04Sschwartz 	/*
165bf8fc234Set 	 * JBC Dmcint ODCD
166f0a73f04Sschwartz 	 *
167f0a73f04Sschwartz 	 * Error bits which can be set via a bad PCItool access go through
168f0a73f04Sschwartz 	 * jbc_safe_acc instead.
169f0a73f04Sschwartz 	 */
170f0a73f04Sschwartz 	{ JBC_BIT_DESC(PIO_UNMAP_RD,	jbc_safe_acc,		jbc_odcd) },
171f0a73f04Sschwartz 	{ JBC_BIT_DESC(ILL_ACC_RD,	jbc_safe_acc,		jbc_odcd) },
172f0a73f04Sschwartz 	{ JBC_BIT_DESC(PIO_UNMAP,	jbc_safe_acc,		jbc_odcd) },
173f8d2de6bSjchu 	{ JBC_BIT_DESC(PIO_DPE,		jbc_dmcint_odcd,	jbc_odcd) },
174bf8fc234Set 	{ JBC_BIT_DESC(PIO_CPE,		hw_reset,		jbc_odcd) },
175f0a73f04Sschwartz 	{ JBC_BIT_DESC(ILL_ACC,		jbc_safe_acc,		jbc_odcd) },
176f8d2de6bSjchu 
177bf8fc234Set 	/* JBC Dmcint IDC */
178bf8fc234Set 	{ JBC_BIT_DESC(UNSOL_RD,	no_panic,	jbc_idc) },
179bf8fc234Set 	{ JBC_BIT_DESC(UNSOL_INTR,	no_panic,	jbc_idc) },
180f8d2de6bSjchu 
181bf8fc234Set 	/* JBC CSR */
182bf8fc234Set 	{ JBC_BIT_DESC(EBUS_TO,		panic,		jbc_csr) }
183f8d2de6bSjchu };
184f8d2de6bSjchu 
18525cf1a30Sjl #define	px_err_jbc_keys \
18625cf1a30Sjl 	(sizeof (px_err_jbc_tbl)) / (sizeof (px_err_bit_desc_t))
18725cf1a30Sjl 
18825cf1a30Sjl /*
18925cf1a30Sjl  * UBC error bit table
19025cf1a30Sjl  */
19125cf1a30Sjl #define	UBC_BIT_DESC(bit, hdl, erpt) \
19225cf1a30Sjl 	UBC_INTERRUPT_STATUS_ ## bit ## _P, \
19325cf1a30Sjl 	0, \
19425cf1a30Sjl 	PX_ERR_BIT_HANDLE(hdl), \
19525cf1a30Sjl 	PX_ERPT_SEND(erpt), \
19625cf1a30Sjl 	PX_ERR_UBC_CLASS(bit) }, \
19725cf1a30Sjl 	{ UBC_INTERRUPT_STATUS_ ## bit ## _S, \
19825cf1a30Sjl 	0, \
19925cf1a30Sjl 	PX_ERR_BIT_HANDLE(hdl), \
20025cf1a30Sjl 	PX_ERPT_SEND(erpt), \
20125cf1a30Sjl 	PX_ERR_UBC_CLASS(bit)
20225cf1a30Sjl px_err_bit_desc_t px_err_ubc_tbl[] = {
20325cf1a30Sjl 	/* UBC FATAL  */
204bf8fc234Set 	{ UBC_BIT_DESC(DMARDUEA,	no_panic,	ubc_fatal) },
205bf8fc234Set 	{ UBC_BIT_DESC(DMAWTUEA,	panic,		ubc_fatal) },
206bf8fc234Set 	{ UBC_BIT_DESC(MEMRDAXA,	panic,		ubc_fatal) },
207bf8fc234Set 	{ UBC_BIT_DESC(MEMWTAXA,	panic,		ubc_fatal) },
208bf8fc234Set 	{ UBC_BIT_DESC(DMARDUEB,	no_panic,	ubc_fatal) },
209bf8fc234Set 	{ UBC_BIT_DESC(DMAWTUEB,	panic,		ubc_fatal) },
210bf8fc234Set 	{ UBC_BIT_DESC(MEMRDAXB,	panic,		ubc_fatal) },
211bf8fc234Set 	{ UBC_BIT_DESC(MEMWTAXB,	panic,		ubc_fatal) },
212bf8fc234Set 	{ UBC_BIT_DESC(PIOWTUE,		panic,		ubc_fatal) },
213bf8fc234Set 	{ UBC_BIT_DESC(PIOWBEUE,	panic,		ubc_fatal) },
214bf8fc234Set 	{ UBC_BIT_DESC(PIORBEUE,	panic,		ubc_fatal) }
21525cf1a30Sjl };
21625cf1a30Sjl 
21725cf1a30Sjl #define	px_err_ubc_keys \
21825cf1a30Sjl 	(sizeof (px_err_ubc_tbl)) / (sizeof (px_err_bit_desc_t))
21925cf1a30Sjl 
22025cf1a30Sjl 
22125cf1a30Sjl char *ubc_class_eid_qualifier[] = {
22225cf1a30Sjl 	"-mem",
22325cf1a30Sjl 	"-channel",
22425cf1a30Sjl 	"-cpu",
22525cf1a30Sjl 	"-path"
22625cf1a30Sjl };
22725cf1a30Sjl 
228f8d2de6bSjchu 
229f8d2de6bSjchu /*
230f8d2de6bSjchu  * DMC error bit tables
231f8d2de6bSjchu  */
232f8d2de6bSjchu #define	IMU_BIT_DESC(bit, hdl, erpt) \
233f8d2de6bSjchu 	IMU_INTERRUPT_STATUS_ ## bit ## _P, \
234f8d2de6bSjchu 	0, \
235f8d2de6bSjchu 	PX_ERR_BIT_HANDLE(hdl), \
236f8d2de6bSjchu 	PX_ERPT_SEND(erpt), \
2378c334881Sjchu 	PX_ERR_DMC_CLASS(bit) }, \
2388c334881Sjchu 	{ IMU_INTERRUPT_STATUS_ ## bit ## _S, \
2398c334881Sjchu 	0, \
2408c334881Sjchu 	PX_ERR_BIT_HANDLE(hdl), \
2418c334881Sjchu 	PX_ERPT_SEND(erpt), \
242f8d2de6bSjchu 	PX_ERR_DMC_CLASS(bit)
243f8d2de6bSjchu px_err_bit_desc_t px_err_imu_tbl[] = {
244bf8fc234Set 	/* DMC IMU RDS */
245bf8fc234Set 	{ IMU_BIT_DESC(MSI_MAL_ERR,		panic,		imu_rds) },
246bf8fc234Set 	{ IMU_BIT_DESC(MSI_PAR_ERR,		panic,		imu_rds) },
247bf8fc234Set 	{ IMU_BIT_DESC(PMEACK_MES_NOT_EN,	panic,		imu_rds) },
248bf8fc234Set 	{ IMU_BIT_DESC(PMPME_MES_NOT_EN,	panic,		imu_rds) },
249bf8fc234Set 	{ IMU_BIT_DESC(FATAL_MES_NOT_EN,	panic,		imu_rds) },
250bf8fc234Set 	{ IMU_BIT_DESC(NONFATAL_MES_NOT_EN,	panic,		imu_rds) },
251bf8fc234Set 	{ IMU_BIT_DESC(COR_MES_NOT_EN,		panic,		imu_rds) },
252bf8fc234Set 	{ IMU_BIT_DESC(MSI_NOT_EN,		panic,		imu_rds) },
253bf8fc234Set 
254bf8fc234Set 	/* DMC IMU SCS */
2556e8a7b44Sjchu 	{ IMU_BIT_DESC(EQ_NOT_EN,		panic,		imu_scs) },
256bf8fc234Set 
257bf8fc234Set 	/* DMC IMU */
258f8d2de6bSjchu 	{ IMU_BIT_DESC(EQ_OVER,			imu_eq_ovfl,	imu) }
259f8d2de6bSjchu };
260f8d2de6bSjchu 
261f8d2de6bSjchu #define	px_err_imu_keys (sizeof (px_err_imu_tbl)) / (sizeof (px_err_bit_desc_t))
262f8d2de6bSjchu 
263f8d2de6bSjchu /* mmu errors */
264f8d2de6bSjchu #define	MMU_BIT_DESC(bit, hdl, erpt) \
265f8d2de6bSjchu 	MMU_INTERRUPT_STATUS_ ## bit ## _P, \
266f8d2de6bSjchu 	0, \
267f8d2de6bSjchu 	PX_ERR_BIT_HANDLE(hdl), \
268f8d2de6bSjchu 	PX_ERPT_SEND(erpt), \
2698c334881Sjchu 	PX_ERR_DMC_CLASS(bit) }, \
2708c334881Sjchu 	{ MMU_INTERRUPT_STATUS_ ## bit ## _S, \
2718c334881Sjchu 	0, \
2728c334881Sjchu 	PX_ERR_BIT_HANDLE(hdl), \
2738c334881Sjchu 	PX_ERPT_SEND(erpt), \
274f8d2de6bSjchu 	PX_ERR_DMC_CLASS(bit)
275f8d2de6bSjchu px_err_bit_desc_t px_err_mmu_tbl[] = {
276bf8fc234Set 	/* DMC MMU TFAR/TFSR */
277f8d2de6bSjchu 	{ MMU_BIT_DESC(BYP_ERR,		mmu_rbne,	mmu_tfar_tfsr) },
278f8d2de6bSjchu 	{ MMU_BIT_DESC(BYP_OOR,		mmu_tfa,	mmu_tfar_tfsr) },
279bf8fc234Set 	{ MMU_BIT_DESC(TRN_ERR,		panic,		mmu_tfar_tfsr) },
280f8d2de6bSjchu 	{ MMU_BIT_DESC(TRN_OOR,		mmu_tfa,	mmu_tfar_tfsr) },
281f8d2de6bSjchu 	{ MMU_BIT_DESC(TTE_INV,		mmu_tfa,	mmu_tfar_tfsr) },
282f8d2de6bSjchu 	{ MMU_BIT_DESC(TTE_PRT,		mmu_tfa,	mmu_tfar_tfsr) },
283bf8fc234Set 	{ MMU_BIT_DESC(TTC_DPE,		mmu_parity,	mmu_tfar_tfsr) },
284bf8fc234Set 	{ MMU_BIT_DESC(TBW_DME,		panic,		mmu_tfar_tfsr) },
285bf8fc234Set 	{ MMU_BIT_DESC(TBW_UDE,		panic,		mmu_tfar_tfsr) },
286bf8fc234Set 	{ MMU_BIT_DESC(TBW_ERR,		panic,		mmu_tfar_tfsr) },
287bf8fc234Set 	{ MMU_BIT_DESC(TBW_DPE,		mmu_parity,	mmu_tfar_tfsr) },
288bf8fc234Set 
289bf8fc234Set 	/* DMC MMU */
290bf8fc234Set 	{ MMU_BIT_DESC(TTC_CAE,		panic,		mmu) }
291f8d2de6bSjchu };
292f8d2de6bSjchu #define	px_err_mmu_keys (sizeof (px_err_mmu_tbl)) / (sizeof (px_err_bit_desc_t))
293f8d2de6bSjchu 
29425cf1a30Sjl 
295f8d2de6bSjchu /*
296f8d2de6bSjchu  * PEC error bit tables
297f8d2de6bSjchu  */
298f8d2de6bSjchu #define	ILU_BIT_DESC(bit, hdl, erpt) \
299f8d2de6bSjchu 	ILU_INTERRUPT_STATUS_ ## bit ## _P, \
300f8d2de6bSjchu 	0, \
301f8d2de6bSjchu 	PX_ERR_BIT_HANDLE(hdl), \
302f8d2de6bSjchu 	PX_ERPT_SEND(erpt), \
3038c334881Sjchu 	PX_ERR_PEC_CLASS(bit) }, \
3048c334881Sjchu 	{ ILU_INTERRUPT_STATUS_ ## bit ## _S, \
3058c334881Sjchu 	0, \
3068c334881Sjchu 	PX_ERR_BIT_HANDLE(hdl), \
3078c334881Sjchu 	PX_ERPT_SEND(erpt), \
308f8d2de6bSjchu 	PX_ERR_PEC_CLASS(bit)
309f8d2de6bSjchu px_err_bit_desc_t px_err_ilu_tbl[] = {
310bf8fc234Set 	/* PEC ILU none */
311bf8fc234Set 	{ ILU_BIT_DESC(IHB_PE,		panic,		pec_ilu) }
312f8d2de6bSjchu };
313f8d2de6bSjchu #define	px_err_ilu_keys \
314f8d2de6bSjchu 	(sizeof (px_err_ilu_tbl)) / (sizeof (px_err_bit_desc_t))
315f8d2de6bSjchu 
316f8d2de6bSjchu /*
317f8d2de6bSjchu  * PEC UE errors implementation is incomplete pending PCIE generic
3188bc7d88aSet  * fabric rules.  Must handle both PRIMARY and SECONDARY errors.
319f8d2de6bSjchu  */
320f8d2de6bSjchu /* pec ue errors */
321f8d2de6bSjchu #define	TLU_UC_BIT_DESC(bit, hdl, erpt) \
322f8d2de6bSjchu 	TLU_UNCORRECTABLE_ERROR_STATUS_CLEAR_ ## bit ## _P, \
323f8d2de6bSjchu 	0, \
3248bc7d88aSet 	PX_ERR_BIT_HANDLE(hdl), \
3258bc7d88aSet 	PX_ERPT_SEND(erpt), \
3268bc7d88aSet 	PX_ERR_PEC_CLASS(bit) }, \
3278bc7d88aSet 	{ TLU_UNCORRECTABLE_ERROR_STATUS_CLEAR_ ## bit ## _S, \
3288bc7d88aSet 	0, \
3298bc7d88aSet 	PX_ERR_BIT_HANDLE(hdl), \
3308bc7d88aSet 	PX_ERPT_SEND(erpt), \
3318bc7d88aSet 	PX_ERR_PEC_CLASS(bit)
33225cf1a30Sjl #define	TLU_UC_OB_BIT_DESC(bit, hdl, erpt) \
33325cf1a30Sjl 	TLU_UNCORRECTABLE_ERROR_STATUS_CLEAR_ ## bit ## _P, \
33425cf1a30Sjl 	0, \
33525cf1a30Sjl 	PX_ERR_BIT_HANDLE(hdl), \
33625cf1a30Sjl 	PX_ERPT_SEND(erpt), \
33725cf1a30Sjl 	PX_ERR_PEC_OB_CLASS(bit) }, \
33825cf1a30Sjl 	{ TLU_UNCORRECTABLE_ERROR_STATUS_CLEAR_ ## bit ## _S, \
33925cf1a30Sjl 	0, \
34025cf1a30Sjl 	PX_ERR_BIT_HANDLE(hdl), \
34125cf1a30Sjl 	PX_ERPT_SEND(erpt), \
342197d4443Sdanice 	PX_ERR_PEC_OB_CLASS(bit)
343f8d2de6bSjchu px_err_bit_desc_t px_err_tlu_ue_tbl[] = {
344bf8fc234Set 	/* PCI-E Receive Uncorrectable Errors */
3458bc7d88aSet 	{ TLU_UC_BIT_DESC(UR,		pciex_ue,	pciex_rx_ue) },
3468bc7d88aSet 	{ TLU_UC_BIT_DESC(UC,		pciex_ue,	pciex_rx_ue) },
347f8d2de6bSjchu 
348bf8fc234Set 	/* PCI-E Transmit Uncorrectable Errors */
34925cf1a30Sjl 	{ TLU_UC_OB_BIT_DESC(ECRC,	pciex_ue,	pciex_rx_ue) },
3508bc7d88aSet 	{ TLU_UC_BIT_DESC(CTO,		pciex_ue,	pciex_tx_ue) },
3518bc7d88aSet 	{ TLU_UC_BIT_DESC(ROF,		pciex_ue,	pciex_tx_ue) },
352f8d2de6bSjchu 
353bf8fc234Set 	/* PCI-E Rx/Tx Uncorrectable Errors */
3548bc7d88aSet 	{ TLU_UC_BIT_DESC(MFP,		pciex_ue,	pciex_rx_tx_ue) },
3558bc7d88aSet 	{ TLU_UC_BIT_DESC(PP,		pciex_ue,	pciex_rx_tx_ue) },
356f8d2de6bSjchu 
357bf8fc234Set 	/* Other PCI-E Uncorrectable Errors */
3588bc7d88aSet 	{ TLU_UC_BIT_DESC(FCP,		pciex_ue,	pciex_ue) },
3598bc7d88aSet 	{ TLU_UC_BIT_DESC(DLP,		pciex_ue,	pciex_ue) },
3608bc7d88aSet 	{ TLU_UC_BIT_DESC(TE,		pciex_ue,	pciex_ue) },
3618bc7d88aSet 
3628bc7d88aSet 	/* Not used */
3638bc7d88aSet 	{ TLU_UC_BIT_DESC(CA,		pciex_ue,	do_not) }
364f8d2de6bSjchu };
365f8d2de6bSjchu #define	px_err_tlu_ue_keys \
366f8d2de6bSjchu 	(sizeof (px_err_tlu_ue_tbl)) / (sizeof (px_err_bit_desc_t))
367f8d2de6bSjchu 
36825cf1a30Sjl 
369f8d2de6bSjchu /*
370f8d2de6bSjchu  * PEC CE errors implementation is incomplete pending PCIE generic
371f8d2de6bSjchu  * fabric rules.
372f8d2de6bSjchu  */
373f8d2de6bSjchu /* pec ce errors */
374f8d2de6bSjchu #define	TLU_CE_BIT_DESC(bit, hdl, erpt) \
375f8d2de6bSjchu 	TLU_CORRECTABLE_ERROR_STATUS_CLEAR_ ## bit ## _P, \
376f8d2de6bSjchu 	0, \
3778bc7d88aSet 	PX_ERR_BIT_HANDLE(hdl), \
3788bc7d88aSet 	PX_ERPT_SEND(erpt), \
3798bc7d88aSet 	PX_ERR_PEC_CLASS(bit) }, \
3808bc7d88aSet 	{ TLU_CORRECTABLE_ERROR_STATUS_CLEAR_ ## bit ## _S, \
3818bc7d88aSet 	0, \
3828bc7d88aSet 	PX_ERR_BIT_HANDLE(hdl), \
3838bc7d88aSet 	PX_ERPT_SEND(erpt), \
3848bc7d88aSet 	PX_ERR_PEC_CLASS(bit)
385f8d2de6bSjchu px_err_bit_desc_t px_err_tlu_ce_tbl[] = {
386bf8fc234Set 	/* PCI-E Correctable Errors */
3878bc7d88aSet 	{ TLU_CE_BIT_DESC(RTO,		pciex_ce,	pciex_ce) },
3888bc7d88aSet 	{ TLU_CE_BIT_DESC(RNR,		pciex_ce,	pciex_ce) },
3898bc7d88aSet 	{ TLU_CE_BIT_DESC(BDP,		pciex_ce,	pciex_ce) },
3908bc7d88aSet 	{ TLU_CE_BIT_DESC(BTP,		pciex_ce,	pciex_ce) },
3918bc7d88aSet 	{ TLU_CE_BIT_DESC(RE,		pciex_ce,	pciex_ce) }
392f8d2de6bSjchu };
393f8d2de6bSjchu #define	px_err_tlu_ce_keys \
394f8d2de6bSjchu 	(sizeof (px_err_tlu_ce_tbl)) / (sizeof (px_err_bit_desc_t))
395f8d2de6bSjchu 
39625cf1a30Sjl 
397f8d2de6bSjchu /* pec oe errors */
398f8d2de6bSjchu #define	TLU_OE_BIT_DESC(bit, hdl, erpt) \
399f8d2de6bSjchu 	TLU_OTHER_EVENT_STATUS_CLEAR_ ## bit ## _P, \
400f8d2de6bSjchu 	0, \
401f8d2de6bSjchu 	PX_ERR_BIT_HANDLE(hdl), \
402f8d2de6bSjchu 	PX_ERPT_SEND(erpt), \
4038c334881Sjchu 	PX_ERR_PEC_CLASS(bit) }, \
4048c334881Sjchu 	{ TLU_OTHER_EVENT_STATUS_CLEAR_ ## bit ## _S, \
4058c334881Sjchu 	0, \
4068c334881Sjchu 	PX_ERR_BIT_HANDLE(hdl), \
4078c334881Sjchu 	PX_ERPT_SEND(erpt), \
408f8d2de6bSjchu 	PX_ERR_PEC_CLASS(bit)
40925cf1a30Sjl #define	TLU_OE_OB_BIT_DESC(bit, hdl, erpt) \
41025cf1a30Sjl 	TLU_OTHER_EVENT_STATUS_CLEAR_ ## bit ## _P, \
41125cf1a30Sjl 	0, \
41225cf1a30Sjl 	PX_ERR_BIT_HANDLE(hdl), \
41325cf1a30Sjl 	PX_ERPT_SEND(erpt), \
41425cf1a30Sjl 	PX_ERR_PEC_OB_CLASS(bit) }, \
41525cf1a30Sjl 	{ TLU_OTHER_EVENT_STATUS_CLEAR_ ## bit ## _S, \
41625cf1a30Sjl 	0, \
41725cf1a30Sjl 	PX_ERR_BIT_HANDLE(hdl), \
41825cf1a30Sjl 	PX_ERPT_SEND(erpt), \
41925cf1a30Sjl 	PX_ERR_PEC_OB_CLASS(bit)
420f8d2de6bSjchu px_err_bit_desc_t px_err_tlu_oe_tbl[] = {
421bf8fc234Set 	/* TLU Other Event Status (receive only) */
422bf8fc234Set 	{ TLU_OE_BIT_DESC(MRC,		hw_reset,	pciex_rx_oe) },
423bf8fc234Set 
424bf8fc234Set 	/* TLU Other Event Status (rx + tx) */
425bf8fc234Set 	{ TLU_OE_BIT_DESC(WUC,		wuc_ruc,	pciex_rx_tx_oe) },
426bf8fc234Set 	{ TLU_OE_BIT_DESC(RUC,		wuc_ruc,	pciex_rx_tx_oe) },
427bf8fc234Set 	{ TLU_OE_BIT_DESC(CRS,		no_panic,	pciex_rx_tx_oe) },
428bf8fc234Set 
429bf8fc234Set 	/* TLU Other Event */
430bf8fc234Set 	{ TLU_OE_BIT_DESC(IIP,		panic,		pciex_oe) },
431bf8fc234Set 	{ TLU_OE_BIT_DESC(EDP,		panic,		pciex_oe) },
432bf8fc234Set 	{ TLU_OE_BIT_DESC(EHP,		panic,		pciex_oe) },
433bf8fc234Set 	{ TLU_OE_OB_BIT_DESC(TLUEITMO,	panic,		pciex_oe) },
434bf8fc234Set 	{ TLU_OE_BIT_DESC(LIN,		no_panic,	pciex_oe) },
435bf8fc234Set 	{ TLU_OE_BIT_DESC(LRS,		no_panic,	pciex_oe) },
436f9721e07Sjchu 	{ TLU_OE_BIT_DESC(LDN,		tlu_ldn,	pciex_oe) },
437f9721e07Sjchu 	{ TLU_OE_BIT_DESC(LUP,		tlu_lup,	pciex_oe) },
438bf8fc234Set 	{ TLU_OE_BIT_DESC(ERU,		panic,		pciex_oe) },
439bf8fc234Set 	{ TLU_OE_BIT_DESC(ERO,		panic,		pciex_oe) },
440bf8fc234Set 	{ TLU_OE_BIT_DESC(EMP,		panic,		pciex_oe) },
441bf8fc234Set 	{ TLU_OE_BIT_DESC(EPE,		panic,		pciex_oe) },
442bf8fc234Set 	{ TLU_OE_BIT_DESC(ERP,		panic,		pciex_oe) },
443bf8fc234Set 	{ TLU_OE_BIT_DESC(EIP,		panic,		pciex_oe) }
444f8d2de6bSjchu };
445f8d2de6bSjchu 
446f8d2de6bSjchu #define	px_err_tlu_oe_keys \
447f8d2de6bSjchu 	(sizeof (px_err_tlu_oe_tbl)) / (sizeof (px_err_bit_desc_t))
448f8d2de6bSjchu 
44925cf1a30Sjl 
450f8d2de6bSjchu /*
451f8d2de6bSjchu  * All the following tables below are for LPU Interrupts.  These interrupts
452f8d2de6bSjchu  * are *NOT* error interrupts, but event status interrupts.
453f8d2de6bSjchu  *
454f8d2de6bSjchu  * These events are probably of most interest to:
455f8d2de6bSjchu  * o Hotplug
456f8d2de6bSjchu  * o Power Management
457f8d2de6bSjchu  * o etc...
458f8d2de6bSjchu  *
459f8d2de6bSjchu  * There are also a few events that would be interresting for FMA.
460f8d2de6bSjchu  * Again none of the regiseters below state that an error has occured
461f8d2de6bSjchu  * or that data has been lost.  If anything, they give status that an
462f8d2de6bSjchu  * error is *about* to occur.  examples
463f8d2de6bSjchu  * o INT_SKP_ERR - indicates clock between fire and child is too far
464f8d2de6bSjchu  *		   off and is most unlikely able to compensate
465f8d2de6bSjchu  * o INT_TX_PAR_ERR - A parity error occured in ONE lane.  This is
466f8d2de6bSjchu  *		      HW recoverable, but will like end up as a future
467f8d2de6bSjchu  *		      fabric error as well.
468f8d2de6bSjchu  *
469f8d2de6bSjchu  * For now, we don't care about any of these errors and should be ignore,
470f8d2de6bSjchu  * but cleared.
471f8d2de6bSjchu  */
472f8d2de6bSjchu 
473f8d2de6bSjchu /* LPU Link Interrupt Table */
474f8d2de6bSjchu #define	LPUL_BIT_DESC(bit, hdl, erpt) \
475f8d2de6bSjchu 	LPU_LINK_LAYER_INTERRUPT_AND_STATUS_INT_ ## bit, \
476f8d2de6bSjchu 	0, \
477f8d2de6bSjchu 	NULL, \
478f8d2de6bSjchu 	NULL, \
479f8d2de6bSjchu 	""
480f8d2de6bSjchu px_err_bit_desc_t px_err_lpul_tbl[] = {
481f8d2de6bSjchu 	{ LPUL_BIT_DESC(LINK_ERR_ACT,	NULL,		NULL) }
482f8d2de6bSjchu };
483f8d2de6bSjchu #define	px_err_lpul_keys \
484f8d2de6bSjchu 	(sizeof (px_err_lpul_tbl)) / (sizeof (px_err_bit_desc_t))
485f8d2de6bSjchu 
486f8d2de6bSjchu /* LPU Physical Interrupt Table */
487f8d2de6bSjchu #define	LPUP_BIT_DESC(bit, hdl, erpt) \
488f8d2de6bSjchu 	LPU_PHY_LAYER_INTERRUPT_AND_STATUS_INT_ ## bit, \
489f8d2de6bSjchu 	0, \
490f8d2de6bSjchu 	NULL, \
491f8d2de6bSjchu 	NULL, \
492f8d2de6bSjchu 	""
493f8d2de6bSjchu px_err_bit_desc_t px_err_lpup_tbl[] = {
494f8d2de6bSjchu 	{ LPUP_BIT_DESC(PHY_LAYER_ERR,	NULL,		NULL) }
495f8d2de6bSjchu };
496f8d2de6bSjchu #define	px_err_lpup_keys \
497f8d2de6bSjchu 	(sizeof (px_err_lpup_tbl)) / (sizeof (px_err_bit_desc_t))
498f8d2de6bSjchu 
499f8d2de6bSjchu /* LPU Receive Interrupt Table */
500f8d2de6bSjchu #define	LPUR_BIT_DESC(bit, hdl, erpt) \
501f8d2de6bSjchu 	LPU_RECEIVE_PHY_INTERRUPT_AND_STATUS_INT_ ## bit, \
502f8d2de6bSjchu 	0, \
503f8d2de6bSjchu 	NULL, \
504f8d2de6bSjchu 	NULL, \
505f8d2de6bSjchu 	""
506f8d2de6bSjchu px_err_bit_desc_t px_err_lpur_tbl[] = {
507f8d2de6bSjchu 	{ LPUR_BIT_DESC(RCV_PHY,	NULL,		NULL) }
508f8d2de6bSjchu };
509f8d2de6bSjchu #define	px_err_lpur_keys \
510f8d2de6bSjchu 	(sizeof (px_err_lpur_tbl)) / (sizeof (px_err_bit_desc_t))
511f8d2de6bSjchu 
512f8d2de6bSjchu /* LPU Transmit Interrupt Table */
513f8d2de6bSjchu #define	LPUX_BIT_DESC(bit, hdl, erpt) \
514f8d2de6bSjchu 	LPU_TRANSMIT_PHY_INTERRUPT_AND_STATUS_INT_ ## bit, \
515f8d2de6bSjchu 	0, \
516f8d2de6bSjchu 	NULL, \
517f8d2de6bSjchu 	NULL, \
518f8d2de6bSjchu 	""
519f8d2de6bSjchu px_err_bit_desc_t px_err_lpux_tbl[] = {
520f8d2de6bSjchu 	{ LPUX_BIT_DESC(UNMSK,		NULL,		NULL) }
521f8d2de6bSjchu };
522f8d2de6bSjchu #define	px_err_lpux_keys \
523f8d2de6bSjchu 	(sizeof (px_err_lpux_tbl)) / (sizeof (px_err_bit_desc_t))
524f8d2de6bSjchu 
525f8d2de6bSjchu /* LPU LTSSM Interrupt Table */
526f8d2de6bSjchu #define	LPUS_BIT_DESC(bit, hdl, erpt) \
527f8d2de6bSjchu 	LPU_LTSSM_INTERRUPT_AND_STATUS_INT_ ## bit, \
528f8d2de6bSjchu 	0, \
529f8d2de6bSjchu 	NULL, \
530f8d2de6bSjchu 	NULL, \
531f8d2de6bSjchu 	""
532f8d2de6bSjchu px_err_bit_desc_t px_err_lpus_tbl[] = {
533f8d2de6bSjchu 	{ LPUS_BIT_DESC(ANY,		NULL,		NULL) }
534f8d2de6bSjchu };
535f8d2de6bSjchu #define	px_err_lpus_keys \
536f8d2de6bSjchu 	(sizeof (px_err_lpus_tbl)) / (sizeof (px_err_bit_desc_t))
537f8d2de6bSjchu 
538f8d2de6bSjchu /* LPU Gigablaze Glue Interrupt Table */
539f8d2de6bSjchu #define	LPUG_BIT_DESC(bit, hdl, erpt) \
540f8d2de6bSjchu 	LPU_GIGABLAZE_GLUE_INTERRUPT_AND_STATUS_INT_ ## bit, \
541f8d2de6bSjchu 	0, \
542f8d2de6bSjchu 	NULL, \
543f8d2de6bSjchu 	NULL, \
544f8d2de6bSjchu 	""
545f8d2de6bSjchu px_err_bit_desc_t px_err_lpug_tbl[] = {
546f8d2de6bSjchu 	{ LPUG_BIT_DESC(GLOBL_UNMSK,	NULL,		NULL) }
547f8d2de6bSjchu };
548f8d2de6bSjchu #define	px_err_lpug_keys \
549f8d2de6bSjchu 	(sizeof (px_err_lpug_tbl)) / (sizeof (px_err_bit_desc_t))
550f8d2de6bSjchu 
551f8d2de6bSjchu 
552f8d2de6bSjchu /* Mask and Tables */
55308a74c0dSschwartz #define	MnT6X(pre) \
554f8d2de6bSjchu 	&px_ ## pre ## _intr_mask, \
555f8d2de6bSjchu 	&px_ ## pre ## _log_mask, \
556f8d2de6bSjchu 	&px_ ## pre ## _count_mask, \
557f8d2de6bSjchu 	px_err_ ## pre ## _tbl, \
558f8d2de6bSjchu 	px_err_ ## pre ## _keys, \
55908a74c0dSschwartz 	PX_REG_XBC, \
560f8d2de6bSjchu 	0
561f8d2de6bSjchu 
56208a74c0dSschwartz #define	MnT6(pre) \
56325cf1a30Sjl 	&px_ ## pre ## _intr_mask, \
56425cf1a30Sjl 	&px_ ## pre ## _log_mask, \
56525cf1a30Sjl 	&px_ ## pre ## _count_mask, \
56608a74c0dSschwartz 	px_err_ ## pre ## _tbl, \
56708a74c0dSschwartz 	px_err_ ## pre ## _keys, \
56808a74c0dSschwartz 	PX_REG_CSR, \
56925cf1a30Sjl 	0
57025cf1a30Sjl 
571f8d2de6bSjchu /* LPU Registers Addresses */
572f8d2de6bSjchu #define	LR4(pre) \
573*e214b19eSToomas Soome 	0, \
574f8d2de6bSjchu 	LPU_ ## pre ## _INTERRUPT_MASK, \
575f8d2de6bSjchu 	LPU_ ## pre ## _INTERRUPT_AND_STATUS, \
576f8d2de6bSjchu 	LPU_ ## pre ## _INTERRUPT_AND_STATUS
577f8d2de6bSjchu 
578f8d2de6bSjchu /* LPU Registers Addresses with Irregularities */
579f8d2de6bSjchu #define	LR4_FIXME(pre) \
580*e214b19eSToomas Soome 	0, \
581f8d2de6bSjchu 	LPU_ ## pre ## _INTERRUPT_MASK, \
582f8d2de6bSjchu 	LPU_ ## pre ## _LAYER_INTERRUPT_AND_STATUS, \
583f8d2de6bSjchu 	LPU_ ## pre ## _LAYER_INTERRUPT_AND_STATUS
584f8d2de6bSjchu 
585f8d2de6bSjchu /* TLU Registers Addresses */
586f8d2de6bSjchu #define	TR4(pre) \
587f8d2de6bSjchu 	TLU_ ## pre ## _LOG_ENABLE, \
588f8d2de6bSjchu 	TLU_ ## pre ## _INTERRUPT_ENABLE, \
589f8d2de6bSjchu 	TLU_ ## pre ## _INTERRUPT_STATUS, \
590f8d2de6bSjchu 	TLU_ ## pre ## _STATUS_CLEAR
591f8d2de6bSjchu 
59225cf1a30Sjl /* Registers Addresses for JBC, UBC, MMU, IMU and ILU */
593f8d2de6bSjchu #define	R4(pre) \
594f8d2de6bSjchu 	pre ## _ERROR_LOG_ENABLE, \
595f8d2de6bSjchu 	pre ## _INTERRUPT_ENABLE, \
596f8d2de6bSjchu 	pre ## _INTERRUPT_STATUS, \
597f8d2de6bSjchu 	pre ## _ERROR_STATUS_CLEAR
598f8d2de6bSjchu 
59908a74c0dSschwartz /* Bits in chip_mask, set according to type. */
60008a74c0dSschwartz #define	CHP_O	BITMASK(PX_CHIP_OBERON)
60108a74c0dSschwartz #define	CHP_F	BITMASK(PX_CHIP_FIRE)
60208a74c0dSschwartz #define	CHP_FO	(CHP_F | CHP_O)
60308a74c0dSschwartz 
604f8d2de6bSjchu /*
605f8d2de6bSjchu  * Register error handling tables.
606f8d2de6bSjchu  * The ID Field (first field) is identified by an enum px_err_id_t.
607f8d2de6bSjchu  * It is located in px_err.h
608f8d2de6bSjchu  */
60908a74c0dSschwartz static const
610f8d2de6bSjchu px_err_reg_desc_t px_err_reg_tbl[] = {
61108a74c0dSschwartz 	{ CHP_F,  MnT6X(jbc),	R4(JBC),		  "JBC Error"},
61208a74c0dSschwartz 	{ CHP_O,  MnT6X(ubc),	R4(UBC),		  "UBC Error"},
61308a74c0dSschwartz 	{ CHP_FO, MnT6(mmu),	R4(MMU),		  "MMU Error"},
61408a74c0dSschwartz 	{ CHP_FO, MnT6(imu),	R4(IMU),		  "IMU Error"},
61508a74c0dSschwartz 	{ CHP_FO, MnT6(tlu_ue),	TR4(UNCORRECTABLE_ERROR), "TLU UE"},
61608a74c0dSschwartz 	{ CHP_FO, MnT6(tlu_ce),	TR4(CORRECTABLE_ERROR),	  "TLU CE"},
61708a74c0dSschwartz 	{ CHP_FO, MnT6(tlu_oe),	TR4(OTHER_EVENT),	  "TLU OE"},
61808a74c0dSschwartz 	{ CHP_FO, MnT6(ilu),	R4(ILU),		  "ILU Error"},
61908a74c0dSschwartz 	{ CHP_F,  MnT6(lpul),	LR4(LINK_LAYER),	  "LPU Link Layer"},
62008a74c0dSschwartz 	{ CHP_F,  MnT6(lpup),	LR4_FIXME(PHY),		  "LPU Phy Layer"},
62108a74c0dSschwartz 	{ CHP_F,  MnT6(lpur),	LR4(RECEIVE_PHY),	  "LPU RX Phy Layer"},
62208a74c0dSschwartz 	{ CHP_F,  MnT6(lpux),	LR4(TRANSMIT_PHY),	  "LPU TX Phy Layer"},
62308a74c0dSschwartz 	{ CHP_F,  MnT6(lpus),	LR4(LTSSM),		  "LPU LTSSM"},
62408a74c0dSschwartz 	{ CHP_F,  MnT6(lpug),	LR4(GIGABLAZE_GLUE),	  "LPU GigaBlaze Glue"},
625f8d2de6bSjchu };
62608a74c0dSschwartz 
62708a74c0dSschwartz #define	PX_ERR_REG_KEYS	(sizeof (px_err_reg_tbl)) / (sizeof (px_err_reg_tbl[0]))
628f8d2de6bSjchu 
629f8d2de6bSjchu typedef struct px_err_ss {
630f8d2de6bSjchu 	uint64_t err_status[PX_ERR_REG_KEYS];
631f8d2de6bSjchu } px_err_ss_t;
632f8d2de6bSjchu 
633bf8fc234Set static void px_err_snapshot(px_t *px_p, px_err_ss_t *ss, int block);
634f8d2de6bSjchu static int  px_err_erpt_and_clr(px_t *px_p, ddi_fm_error_t *derr,
635f8d2de6bSjchu     px_err_ss_t *ss);
636f8d2de6bSjchu static int  px_err_check_severity(px_t *px_p, ddi_fm_error_t *derr,
637f8d2de6bSjchu     int err, int caller);
638f8d2de6bSjchu 
639f8d2de6bSjchu /*
640f8d2de6bSjchu  * px_err_cb_intr:
64125cf1a30Sjl  * Interrupt handler for the JBC/UBC block.
642f8d2de6bSjchu  * o lock
643f8d2de6bSjchu  * o create derr
644bf8fc234Set  * o px_err_cmn_intr
645f8d2de6bSjchu  * o unlock
646f8d2de6bSjchu  * o handle error: fatal? fm_panic() : return INTR_CLAIMED)
647f8d2de6bSjchu  */
648f8d2de6bSjchu uint_t
px_err_cb_intr(caddr_t arg)649f8d2de6bSjchu px_err_cb_intr(caddr_t arg)
650f8d2de6bSjchu {
651f8d2de6bSjchu 	px_fault_t	*px_fault_p = (px_fault_t *)arg;
652f8d2de6bSjchu 	dev_info_t	*rpdip = px_fault_p->px_fh_dip;
653f8d2de6bSjchu 	px_t		*px_p = DIP_TO_STATE(rpdip);
654bf8fc234Set 	int		err;
655f8d2de6bSjchu 	ddi_fm_error_t	derr;
656f8d2de6bSjchu 
657f8d2de6bSjchu 	/* Create the derr */
658f8d2de6bSjchu 	bzero(&derr, sizeof (ddi_fm_error_t));
659f8d2de6bSjchu 	derr.fme_version = DDI_FME_VERSION;
660f8d2de6bSjchu 	derr.fme_ena = fm_ena_generate(0, FM_ENA_FMT1);
661f8d2de6bSjchu 	derr.fme_flag = DDI_FM_ERR_UNEXPECTED;
662f8d2de6bSjchu 
663eae2e508Skrishnae 	if (px_fm_enter(px_p) != DDI_SUCCESS)
664eae2e508Skrishnae 		goto done;
665f8d2de6bSjchu 
666bf8fc234Set 	err = px_err_cmn_intr(px_p, &derr, PX_INTR_CALL, PX_FM_BLOCK_HOST);
667f8d2de6bSjchu 	(void) px_lib_intr_setstate(rpdip, px_fault_p->px_fh_sysino,
668f8d2de6bSjchu 	    INTR_IDLE_STATE);
669f8d2de6bSjchu 
670eae2e508Skrishnae 	px_err_panic(err, PX_HB, PX_NO_ERROR, B_TRUE);
671eae2e508Skrishnae 	px_fm_exit(px_p);
672eae2e508Skrishnae 	px_err_panic(err, PX_HB, PX_NO_ERROR, B_FALSE);
673f8d2de6bSjchu 
674eae2e508Skrishnae done:
675f8d2de6bSjchu 	return (DDI_INTR_CLAIMED);
676f8d2de6bSjchu }
677f8d2de6bSjchu 
678f8d2de6bSjchu /*
679f8d2de6bSjchu  * px_err_dmc_pec_intr:
680f8d2de6bSjchu  * Interrupt handler for the DMC/PEC block.
681f8d2de6bSjchu  * o lock
682f8d2de6bSjchu  * o create derr
683bf8fc234Set  * o px_err_cmn_intr(leaf, with out cb)
684bf8fc234Set  * o pcie_scan_fabric (leaf)
685f8d2de6bSjchu  * o unlock
686f8d2de6bSjchu  * o handle error: fatal? fm_panic() : return INTR_CLAIMED)
687f8d2de6bSjchu  */
688f8d2de6bSjchu uint_t
px_err_dmc_pec_intr(caddr_t arg)689f8d2de6bSjchu px_err_dmc_pec_intr(caddr_t arg)
690f8d2de6bSjchu {
691f8d2de6bSjchu 	px_fault_t	*px_fault_p = (px_fault_t *)arg;
692f8d2de6bSjchu 	dev_info_t	*rpdip = px_fault_p->px_fh_dip;
693f8d2de6bSjchu 	px_t		*px_p = DIP_TO_STATE(rpdip);
694eae2e508Skrishnae 	int		rc_err, fab_err;
695f8d2de6bSjchu 	ddi_fm_error_t	derr;
696f8d2de6bSjchu 
697f8d2de6bSjchu 	/* Create the derr */
698f8d2de6bSjchu 	bzero(&derr, sizeof (ddi_fm_error_t));
699f8d2de6bSjchu 	derr.fme_version = DDI_FME_VERSION;
700f8d2de6bSjchu 	derr.fme_ena = fm_ena_generate(0, FM_ENA_FMT1);
701f8d2de6bSjchu 	derr.fme_flag = DDI_FM_ERR_UNEXPECTED;
702f8d2de6bSjchu 
703eae2e508Skrishnae 	if (px_fm_enter(px_p) != DDI_SUCCESS)
704eae2e508Skrishnae 		goto done;
705f8d2de6bSjchu 
706f8d2de6bSjchu 	/* send ereport/handle/clear fire registers */
707bf8fc234Set 	rc_err = px_err_cmn_intr(px_p, &derr, PX_INTR_CALL, PX_FM_BLOCK_PCIE);
708f8d2de6bSjchu 
709f8d2de6bSjchu 	/* Check all child devices for errors */
710eae2e508Skrishnae 	fab_err = px_scan_fabric(px_p, rpdip, &derr);
711f8d2de6bSjchu 
712f8d2de6bSjchu 	/* Set the interrupt state to idle */
713f8d2de6bSjchu 	(void) px_lib_intr_setstate(rpdip, px_fault_p->px_fh_sysino,
714f8d2de6bSjchu 	    INTR_IDLE_STATE);
715f8d2de6bSjchu 
716eae2e508Skrishnae 	px_err_panic(rc_err, PX_RC, fab_err, B_TRUE);
717eae2e508Skrishnae 	px_fm_exit(px_p);
718eae2e508Skrishnae 	px_err_panic(rc_err, PX_RC, fab_err, B_FALSE);
719f8d2de6bSjchu 
720eae2e508Skrishnae done:
721f8d2de6bSjchu 	return (DDI_INTR_CLAIMED);
722f8d2de6bSjchu }
723f8d2de6bSjchu 
724f8d2de6bSjchu /*
72508a74c0dSschwartz  * Proper csr_base is responsibility of the caller. (Called from px_lib_dev_init
72608a74c0dSschwartz  * via px_err_reg_setup_all for pcie error registers;  called from
72708a74c0dSschwartz  * px_cb_add_intr for jbc/ubc from px_cb_attach.)
72808a74c0dSschwartz  *
72908a74c0dSschwartz  * Note: reg_id is passed in instead of reg_desc since this function is called
73008a74c0dSschwartz  * from px_lib4u.c, which doesn't know about the structure of the table.
731f8d2de6bSjchu  */
732f8d2de6bSjchu void
px_err_reg_enable(px_err_id_t reg_id,caddr_t csr_base)73308a74c0dSschwartz px_err_reg_enable(px_err_id_t reg_id, caddr_t csr_base)
734f8d2de6bSjchu {
73508a74c0dSschwartz 	const px_err_reg_desc_t	*reg_desc_p = &px_err_reg_tbl[reg_id];
73608a74c0dSschwartz 	uint64_t 		intr_mask = *reg_desc_p->intr_mask_p;
73708a74c0dSschwartz 	uint64_t 		log_mask = *reg_desc_p->log_mask_p;
738f8d2de6bSjchu 
739f8d2de6bSjchu 	/* Enable logs if it exists */
740*e214b19eSToomas Soome 	if (reg_desc_p->log_addr != 0)
74108a74c0dSschwartz 		CSR_XS(csr_base, reg_desc_p->log_addr, log_mask);
742f8d2de6bSjchu 
743f8d2de6bSjchu 	/*
744f8d2de6bSjchu 	 * For readability you in code you set 1 to enable an interrupt.
745f8d2de6bSjchu 	 * But in Fire it's backwards.  You set 1 to *disable* an intr.
746f8d2de6bSjchu 	 * Reverse the user tunable intr mask field.
747f8d2de6bSjchu 	 *
748f8d2de6bSjchu 	 * Disable All Errors
749f8d2de6bSjchu 	 * Clear All Errors
750f8d2de6bSjchu 	 * Enable Errors
751f8d2de6bSjchu 	 */
75208a74c0dSschwartz 	CSR_XS(csr_base, reg_desc_p->enable_addr, 0);
75308a74c0dSschwartz 	CSR_XS(csr_base, reg_desc_p->clear_addr, -1);
75408a74c0dSschwartz 	CSR_XS(csr_base, reg_desc_p->enable_addr, intr_mask);
75508a74c0dSschwartz 	DBG(DBG_ATTACH, NULL, "%s Mask: 0x%llx\n", reg_desc_p->msg,
75608a74c0dSschwartz 	    CSR_XR(csr_base, reg_desc_p->enable_addr));
75708a74c0dSschwartz 	DBG(DBG_ATTACH, NULL, "%s Status: 0x%llx\n", reg_desc_p->msg,
75808a74c0dSschwartz 	    CSR_XR(csr_base, reg_desc_p->status_addr));
75908a74c0dSschwartz 	DBG(DBG_ATTACH, NULL, "%s Clear: 0x%llx\n", reg_desc_p->msg,
76008a74c0dSschwartz 	    CSR_XR(csr_base, reg_desc_p->clear_addr));
761*e214b19eSToomas Soome 	if (reg_desc_p->log_addr != 0) {
76208a74c0dSschwartz 		DBG(DBG_ATTACH, NULL, "%s Log: 0x%llx\n", reg_desc_p->msg,
76308a74c0dSschwartz 		    CSR_XR(csr_base, reg_desc_p->log_addr));
764f8d2de6bSjchu 	}
765f8d2de6bSjchu }
766f8d2de6bSjchu 
767f8d2de6bSjchu void
px_err_reg_disable(px_err_id_t reg_id,caddr_t csr_base)76808a74c0dSschwartz px_err_reg_disable(px_err_id_t reg_id, caddr_t csr_base)
769f8d2de6bSjchu {
77008a74c0dSschwartz 	const px_err_reg_desc_t	*reg_desc_p = &px_err_reg_tbl[reg_id];
77108a74c0dSschwartz 	uint64_t		val = (reg_id >= PX_ERR_LPU_LINK) ? -1 : 0;
772f8d2de6bSjchu 
773*e214b19eSToomas Soome 	if (reg_desc_p->log_addr != 0)
77408a74c0dSschwartz 		CSR_XS(csr_base, reg_desc_p->log_addr, val);
77508a74c0dSschwartz 	CSR_XS(csr_base, reg_desc_p->enable_addr, val);
77608a74c0dSschwartz }
77708a74c0dSschwartz 
77808a74c0dSschwartz /*
77908a74c0dSschwartz  * Set up pcie error registers.
78008a74c0dSschwartz  */
78108a74c0dSschwartz void
px_err_reg_setup_pcie(uint8_t chip_mask,caddr_t csr_base,boolean_t enable)78208a74c0dSschwartz px_err_reg_setup_pcie(uint8_t chip_mask, caddr_t csr_base, boolean_t enable)
78308a74c0dSschwartz {
78408a74c0dSschwartz 	px_err_id_t		reg_id;
78508a74c0dSschwartz 	const px_err_reg_desc_t	*reg_desc_p;
78608a74c0dSschwartz 	void (*px_err_reg_func)(px_err_id_t, caddr_t);
78708a74c0dSschwartz 
78808a74c0dSschwartz 	/*
78908a74c0dSschwartz 	 * JBC or XBC are enabled during adding of common block interrupts,
79008a74c0dSschwartz 	 * not done here.
79108a74c0dSschwartz 	 */
79208a74c0dSschwartz 	px_err_reg_func = (enable ? px_err_reg_enable : px_err_reg_disable);
79308a74c0dSschwartz 	for (reg_id = 0; reg_id < PX_ERR_REG_KEYS; reg_id++) {
79408a74c0dSschwartz 		reg_desc_p = &px_err_reg_tbl[reg_id];
79508a74c0dSschwartz 		if ((reg_desc_p->chip_mask & chip_mask) &&
79608a74c0dSschwartz 		    (reg_desc_p->reg_bank == PX_REG_CSR))
79708a74c0dSschwartz 			px_err_reg_func(reg_id, csr_base);
798f8d2de6bSjchu 	}
799f8d2de6bSjchu }
800f8d2de6bSjchu 
801f8d2de6bSjchu /*
802bf8fc234Set  * px_err_cmn_intr:
803f8d2de6bSjchu  * Common function called by trap, mondo and fabric intr.
804f8d2de6bSjchu  * o Snap shot current fire registers
805f8d2de6bSjchu  * o check for safe access
806f8d2de6bSjchu  * o send ereport and clear snap shot registers
807bf8fc234Set  * o create and queue RC info for later use in fabric scan.
808bf8fc234Set  *   o RUC/WUC, PTLP, MMU Errors(CA), UR
809f8d2de6bSjchu  * o check severity of snap shot registers
810f8d2de6bSjchu  *
811f8d2de6bSjchu  * @param px_p		leaf in which to check access
812f8d2de6bSjchu  * @param derr		fm err data structure to be updated
813f8d2de6bSjchu  * @param caller	PX_TRAP_CALL | PX_INTR_CALL
814bf8fc234Set  * @param block		PX_FM_BLOCK_HOST | PX_FM_BLOCK_PCIE | PX_FM_BLOCK_ALL
815bf8fc234Set  * @return err		PX_NO_PANIC | PX_PANIC | PX_HW_RESET | PX_PROTECTED
816f8d2de6bSjchu  */
817f8d2de6bSjchu int
px_err_cmn_intr(px_t * px_p,ddi_fm_error_t * derr,int caller,int block)818bf8fc234Set px_err_cmn_intr(px_t *px_p, ddi_fm_error_t *derr, int caller, int block)
819f8d2de6bSjchu {
82008a74c0dSschwartz 	px_err_ss_t		ss = {0};
821bf8fc234Set 	int			err;
822f8d2de6bSjchu 
82301689544Sjchu 	ASSERT(MUTEX_HELD(&px_p->px_fm_mutex));
824f8d2de6bSjchu 
825f8d2de6bSjchu 	/* check for safe access */
826f8d2de6bSjchu 	px_err_safeacc_check(px_p, derr);
827f8d2de6bSjchu 
8287ea9b230Set 	/* snap shot the current fire registers */
8297ea9b230Set 	px_err_snapshot(px_p, &ss, block);
8307ea9b230Set 
831f8d2de6bSjchu 	/* send ereports/handle/clear registers */
832f8d2de6bSjchu 	err = px_err_erpt_and_clr(px_p, derr, &ss);
833f8d2de6bSjchu 
834f8d2de6bSjchu 	/* check for error severity */
835f8d2de6bSjchu 	err = px_err_check_severity(px_p, derr, err, caller);
836f8d2de6bSjchu 
837f8d2de6bSjchu 	/* Mark the On Trap Handle if an error occured */
838bf8fc234Set 	if (err != PX_NO_ERROR) {
839f8d2de6bSjchu 		px_pec_t	*pec_p = px_p->px_pec_p;
840f8d2de6bSjchu 		on_trap_data_t	*otd = pec_p->pec_ontrap_data;
841f8d2de6bSjchu 
8421a887b2eSjchu 		if ((otd != NULL) && (otd->ot_prot & OT_DATA_ACCESS))
843f8d2de6bSjchu 			otd->ot_trap |= OT_DATA_ACCESS;
844f8d2de6bSjchu 	}
845f8d2de6bSjchu 
846f8d2de6bSjchu 	return (err);
847f8d2de6bSjchu }
848f8d2de6bSjchu 
849f8d2de6bSjchu /*
850f8d2de6bSjchu  * Static function
851f8d2de6bSjchu  */
852f8d2de6bSjchu 
853f8d2de6bSjchu /*
854f8d2de6bSjchu  * px_err_snapshot:
855f8d2de6bSjchu  * Take a current snap shot of all the fire error registers.  This includes
856bf8fc234Set  * JBC/UBC, DMC, and PEC depending on the block flag
857f8d2de6bSjchu  *
858f8d2de6bSjchu  * @param px_p		leaf in which to take the snap shot.
859f8d2de6bSjchu  * @param ss		pre-allocated memory to store the snap shot.
86025cf1a30Sjl  * @param chk_cb	boolean on whether to store jbc/ubc register.
861f8d2de6bSjchu  */
862f8d2de6bSjchu static void
px_err_snapshot(px_t * px_p,px_err_ss_t * ss_p,int block)863bf8fc234Set px_err_snapshot(px_t *px_p, px_err_ss_t *ss_p, int block)
864f8d2de6bSjchu {
865f8d2de6bSjchu 	pxu_t	*pxu_p = (pxu_t *)px_p->px_plat_p;
866f8d2de6bSjchu 	caddr_t	xbc_csr_base = (caddr_t)pxu_p->px_address[PX_REG_XBC];
867f8d2de6bSjchu 	caddr_t	pec_csr_base = (caddr_t)pxu_p->px_address[PX_REG_CSR];
868bf8fc234Set 	caddr_t	csr_base;
86908a74c0dSschwartz 	uint8_t chip_mask = 1 << PX_CHIP_TYPE(pxu_p);
87008a74c0dSschwartz 	const px_err_reg_desc_t *reg_desc_p = px_err_reg_tbl;
87108a74c0dSschwartz 	px_err_id_t reg_id;
872f8d2de6bSjchu 
87308a74c0dSschwartz 	for (reg_id = 0; reg_id < PX_ERR_REG_KEYS; reg_id++, reg_desc_p++) {
87408a74c0dSschwartz 		if (!(reg_desc_p->chip_mask & chip_mask))
87508a74c0dSschwartz 			continue;
876bf8fc234Set 
877bf8fc234Set 		if ((block & PX_FM_BLOCK_HOST) &&
878bf8fc234Set 		    (reg_desc_p->reg_bank == PX_REG_XBC))
879bf8fc234Set 			csr_base = xbc_csr_base;
880bf8fc234Set 		else if ((block & PX_FM_BLOCK_PCIE) &&
881bf8fc234Set 		    (reg_desc_p->reg_bank == PX_REG_CSR))
882bf8fc234Set 			csr_base = pec_csr_base;
883bf8fc234Set 		else {
884bf8fc234Set 			ss_p->err_status[reg_id] = 0;
885bf8fc234Set 			continue;
886bf8fc234Set 		}
887bf8fc234Set 
888bf8fc234Set 		ss_p->err_status[reg_id] = CSR_XR(csr_base,
889bf8fc234Set 		    reg_desc_p->status_addr);
890f8d2de6bSjchu 	}
891f8d2de6bSjchu }
892f8d2de6bSjchu 
893f8d2de6bSjchu /*
894f8d2de6bSjchu  * px_err_erpt_and_clr:
895f8d2de6bSjchu  * This function does the following thing to all the fire registers based
896f8d2de6bSjchu  * on an earlier snap shot.
897f8d2de6bSjchu  * o Send ereport
898f8d2de6bSjchu  * o Handle the error
899f8d2de6bSjchu  * o Clear the error
900f8d2de6bSjchu  *
901f8d2de6bSjchu  * @param px_p		leaf in which to take the snap shot.
902f8d2de6bSjchu  * @param derr		fm err in which the ereport is to be based on
90308a74c0dSschwartz  * @param ss_p		pre-allocated memory to store the snap shot.
904f8d2de6bSjchu  */
905f8d2de6bSjchu static int
px_err_erpt_and_clr(px_t * px_p,ddi_fm_error_t * derr,px_err_ss_t * ss_p)90608a74c0dSschwartz px_err_erpt_and_clr(px_t *px_p, ddi_fm_error_t *derr, px_err_ss_t *ss_p)
907f8d2de6bSjchu {
908f8d2de6bSjchu 	dev_info_t		*rpdip = px_p->px_dip;
909f8d2de6bSjchu 	pxu_t			*pxu_p = (pxu_t *)px_p->px_plat_p;
910f8d2de6bSjchu 	caddr_t			csr_base;
91108a74c0dSschwartz 	const px_err_reg_desc_t	*err_reg_tbl;
912f8d2de6bSjchu 	px_err_bit_desc_t	*err_bit_tbl;
913f8d2de6bSjchu 	px_err_bit_desc_t	*err_bit_desc;
914f8d2de6bSjchu 
915bf8fc234Set 	uint64_t		*count_mask;
916bf8fc234Set 	uint64_t		clear_addr;
917f8d2de6bSjchu 	uint64_t		ss_reg;
918f8d2de6bSjchu 
919f8d2de6bSjchu 	int			(*err_handler)();
920f8d2de6bSjchu 	int			(*erpt_handler)();
921bf8fc234Set 	int			reg_id, key;
922bf8fc234Set 	int			err = PX_NO_ERROR;
923bf8fc234Set 	int			biterr = 0;
924f8d2de6bSjchu 
92501689544Sjchu 	ASSERT(MUTEX_HELD(&px_p->px_fm_mutex));
926f8d2de6bSjchu 
927f8d2de6bSjchu 	/* send erport/handle/clear JBC errors */
92808a74c0dSschwartz 	for (reg_id = 0; reg_id < PX_ERR_REG_KEYS; reg_id++) {
929f8d2de6bSjchu 		/* Get the correct register description table */
930f8d2de6bSjchu 		err_reg_tbl = &px_err_reg_tbl[reg_id];
931f8d2de6bSjchu 
93225cf1a30Sjl 		/* Only look at enabled groups. */
93308a74c0dSschwartz 		if (!(BIT_TST(err_reg_tbl->chip_mask, PX_CHIP_TYPE(pxu_p))))
93425cf1a30Sjl 			continue;
93525cf1a30Sjl 
936f8d2de6bSjchu 		/* Get the correct CSR BASE */
93708a74c0dSschwartz 		csr_base = (caddr_t)pxu_p->px_address[err_reg_tbl->reg_bank];
938f8d2de6bSjchu 
939bf8fc234Set 		/* If there are no errors in this register, continue */
940bf8fc234Set 		ss_reg = ss_p->err_status[reg_id];
941bf8fc234Set 		if (!ss_reg)
942bf8fc234Set 			continue;
943bf8fc234Set 
944f8d2de6bSjchu 		/* Get pointers to masks and register addresses */
945f8d2de6bSjchu 		count_mask = err_reg_tbl->count_mask_p;
946f8d2de6bSjchu 		clear_addr = err_reg_tbl->clear_addr;
947f8d2de6bSjchu 
948f8d2de6bSjchu 		/* Get the register BIT description table */
949f8d2de6bSjchu 		err_bit_tbl = err_reg_tbl->err_bit_tbl;
950f8d2de6bSjchu 
951f8d2de6bSjchu 		/* For each known bit in the register send erpt and handle */
95208a74c0dSschwartz 		for (key = 0; key < err_reg_tbl->err_bit_keys; key++) {
953f8d2de6bSjchu 			/*
954f8d2de6bSjchu 			 * If the ss_reg is set for this bit,
955f8d2de6bSjchu 			 * send ereport and handle
956f8d2de6bSjchu 			 */
957bf8fc234Set 			err_bit_desc = &err_bit_tbl[key];
958bf8fc234Set 			if (!BIT_TST(ss_reg, err_bit_desc->bit))
959bf8fc234Set 				continue;
960bf8fc234Set 
961bf8fc234Set 			/* Increment the counter if necessary */
962bf8fc234Set 			if (BIT_TST(*count_mask, err_bit_desc->bit)) {
963bf8fc234Set 				err_bit_desc->counter++;
964f8d2de6bSjchu 			}
965bf8fc234Set 
966bf8fc234Set 			/* Error Handle for this bit */
967bf8fc234Set 			err_handler = err_bit_desc->err_handler;
968bf8fc234Set 			if (err_handler) {
969bf8fc234Set 				biterr = err_handler(rpdip, csr_base, derr,
970bf8fc234Set 				    err_reg_tbl, err_bit_desc);
971bf8fc234Set 				err |= biterr;
972bf8fc234Set 			}
973bf8fc234Set 
974bf8fc234Set 			/*
975bf8fc234Set 			 * Send the ereport if it's an UNEXPECTED err.
976bf8fc234Set 			 * This is the only place where PX_EXPECTED is utilized.
977bf8fc234Set 			 */
978bf8fc234Set 			erpt_handler = err_bit_desc->erpt_handler;
979bf8fc234Set 			if ((derr->fme_flag != DDI_FM_ERR_UNEXPECTED) ||
980bf8fc234Set 			    (biterr == PX_EXPECTED))
981bf8fc234Set 				continue;
982bf8fc234Set 
983bf8fc234Set 			if (erpt_handler)
984bf8fc234Set 				(void) erpt_handler(rpdip, csr_base, ss_reg,
985bf8fc234Set 				    derr, err_bit_desc->bit,
986bf8fc234Set 				    err_bit_desc->class_name);
987f8d2de6bSjchu 		}
988f8d2de6bSjchu 
989f8d2de6bSjchu 		/* Clear the register and error */
990f8d2de6bSjchu 		CSR_XS(csr_base, clear_addr, ss_reg);
991f8d2de6bSjchu 	}
992f8d2de6bSjchu 
993f8d2de6bSjchu 	return (err);
994f8d2de6bSjchu }
995f8d2de6bSjchu 
996f8d2de6bSjchu /*
997f8d2de6bSjchu  * px_err_check_severity:
998f8d2de6bSjchu  * Check the severity of the fire error based on an earlier snapshot
999f8d2de6bSjchu  *
1000f8d2de6bSjchu  * @param px_p		leaf in which to take the snap shot.
1001f8d2de6bSjchu  * @param derr		fm err in which the ereport is to be based on
100208a74c0dSschwartz  * @param err		fire register error status
100308a74c0dSschwartz  * @param caller	PX_TRAP_CALL | PX_INTR_CALL | PX_LIB_CALL
1004f8d2de6bSjchu  */
1005f8d2de6bSjchu static int
px_err_check_severity(px_t * px_p,ddi_fm_error_t * derr,int err,int caller)1006f8d2de6bSjchu px_err_check_severity(px_t *px_p, ddi_fm_error_t *derr, int err, int caller)
1007f8d2de6bSjchu {
1008f8d2de6bSjchu 	px_pec_t 	*pec_p = px_p->px_pec_p;
1009f8d2de6bSjchu 	boolean_t	is_safeacc = B_FALSE;
10101a887b2eSjchu 
1011bf8fc234Set 	/*
1012bf8fc234Set 	 * Nothing to do if called with no error.
1013bf8fc234Set 	 * The err could have already been set to PX_NO_PANIC, which means the
1014bf8fc234Set 	 * system doesn't need to panic, but PEEK/POKE still failed.
1015bf8fc234Set 	 */
1016bf8fc234Set 	if (err == PX_NO_ERROR)
10171a887b2eSjchu 		return (err);
1018f8d2de6bSjchu 
1019f8d2de6bSjchu 	/* Cautious access error handling  */
1020f8d2de6bSjchu 	switch (derr->fme_flag) {
1021f8d2de6bSjchu 	case DDI_FM_ERR_EXPECTED:
1022f8d2de6bSjchu 		if (caller == PX_TRAP_CALL) {
1023f8d2de6bSjchu 			/*
1024f8d2de6bSjchu 			 * for ddi_caut_get treat all events as nonfatal
1025f8d2de6bSjchu 			 * The trampoline will set err_ena = 0,
1026f8d2de6bSjchu 			 * err_status = NONFATAL.
1027f8d2de6bSjchu 			 */
1028f8d2de6bSjchu 			derr->fme_status = DDI_FM_NONFATAL;
1029f8d2de6bSjchu 			is_safeacc = B_TRUE;
1030f8d2de6bSjchu 		} else {
1031f8d2de6bSjchu 			/*
1032f8d2de6bSjchu 			 * For ddi_caut_put treat all events as nonfatal. Here
1033f8d2de6bSjchu 			 * we have the handle and can call ndi_fm_acc_err_set().
1034f8d2de6bSjchu 			 */
1035f8d2de6bSjchu 			derr->fme_status = DDI_FM_NONFATAL;
1036f8d2de6bSjchu 			ndi_fm_acc_err_set(pec_p->pec_acc_hdl, derr);
1037f8d2de6bSjchu 			is_safeacc = B_TRUE;
1038f8d2de6bSjchu 		}
1039f8d2de6bSjchu 		break;
1040f8d2de6bSjchu 	case DDI_FM_ERR_PEEK:
1041f8d2de6bSjchu 	case DDI_FM_ERR_POKE:
1042f8d2de6bSjchu 		/*
1043f8d2de6bSjchu 		 * For ddi_peek/poke treat all events as nonfatal.
1044f8d2de6bSjchu 		 */
1045f8d2de6bSjchu 		is_safeacc = B_TRUE;
1046f8d2de6bSjchu 		break;
1047f8d2de6bSjchu 	default:
1048f8d2de6bSjchu 		is_safeacc = B_FALSE;
1049f8d2de6bSjchu 	}
1050f8d2de6bSjchu 
1051bf8fc234Set 	/* re-adjust error status from safe access, forgive all errors */
1052bf8fc234Set 	if (is_safeacc)
1053bf8fc234Set 		return (PX_NO_PANIC);
1054f8d2de6bSjchu 
10551a887b2eSjchu 	return (err);
1056f8d2de6bSjchu }
1057f8d2de6bSjchu 
1058f8d2de6bSjchu /* predefined convenience functions */
1059f8d2de6bSjchu /* ARGSUSED */
1060bf8fc234Set void
px_err_log_handle(dev_info_t * rpdip,px_err_reg_desc_t * err_reg_descr,px_err_bit_desc_t * err_bit_descr,char * msg)1061bf8fc234Set px_err_log_handle(dev_info_t *rpdip, px_err_reg_desc_t *err_reg_descr,
1062bf8fc234Set 	px_err_bit_desc_t *err_bit_descr, char *msg)
1063f8d2de6bSjchu {
1064bf8fc234Set 	DBG(DBG_ERR_INTR, rpdip,
1065bf8fc234Set 	    "Bit %d, %s, at %s(0x%x) has occured %d times with a severity "
1066bf8fc234Set 	    "of \"%s\"\n",
1067bf8fc234Set 	    err_bit_descr->bit, err_bit_descr->class_name,
1068bf8fc234Set 	    err_reg_descr->msg, err_reg_descr->status_addr,
1069bf8fc234Set 	    err_bit_descr->counter, msg);
1070f8d2de6bSjchu }
1071f8d2de6bSjchu 
1072f8d2de6bSjchu /* ARGSUSED */
1073f8d2de6bSjchu int
px_err_hw_reset_handle(dev_info_t * rpdip,caddr_t csr_base,ddi_fm_error_t * derr,px_err_reg_desc_t * err_reg_descr,px_err_bit_desc_t * err_bit_descr)1074bf8fc234Set px_err_hw_reset_handle(dev_info_t *rpdip, caddr_t csr_base,
1075f8d2de6bSjchu 	ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
1076f8d2de6bSjchu 	px_err_bit_desc_t *err_bit_descr)
1077f8d2de6bSjchu {
1078bf8fc234Set 	if (px_log & PX_HW_RESET) {
1079bf8fc234Set 		px_err_log_handle(rpdip, err_reg_descr, err_bit_descr,
1080bf8fc234Set 		    "HW RESET");
1081bf8fc234Set 	}
1082bf8fc234Set 
1083bf8fc234Set 	return (PX_HW_RESET);
1084f8d2de6bSjchu }
1085f8d2de6bSjchu 
1086f8d2de6bSjchu /* ARGSUSED */
1087f8d2de6bSjchu int
px_err_panic_handle(dev_info_t * rpdip,caddr_t csr_base,ddi_fm_error_t * derr,px_err_reg_desc_t * err_reg_descr,px_err_bit_desc_t * err_bit_descr)1088bf8fc234Set px_err_panic_handle(dev_info_t *rpdip, caddr_t csr_base,
1089f8d2de6bSjchu 	ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
1090f8d2de6bSjchu 	px_err_bit_desc_t *err_bit_descr)
1091f8d2de6bSjchu {
1092bf8fc234Set 	if (px_log & PX_PANIC) {
1093bf8fc234Set 		px_err_log_handle(rpdip, err_reg_descr, err_bit_descr, "PANIC");
1094bf8fc234Set 	}
1095bf8fc234Set 
1096bf8fc234Set 	return (PX_PANIC);
1097f8d2de6bSjchu }
1098f8d2de6bSjchu 
1099f8d2de6bSjchu /* ARGSUSED */
1100f8d2de6bSjchu int
px_err_protected_handle(dev_info_t * rpdip,caddr_t csr_base,ddi_fm_error_t * derr,px_err_reg_desc_t * err_reg_descr,px_err_bit_desc_t * err_bit_descr)1101bf8fc234Set px_err_protected_handle(dev_info_t *rpdip, caddr_t csr_base,
1102f8d2de6bSjchu 	ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
1103f8d2de6bSjchu 	px_err_bit_desc_t *err_bit_descr)
1104f8d2de6bSjchu {
1105bf8fc234Set 	if (px_log & PX_PROTECTED) {
1106bf8fc234Set 		px_err_log_handle(rpdip, err_reg_descr, err_bit_descr,
1107bf8fc234Set 		    "PROTECTED");
1108bf8fc234Set 	}
1109bf8fc234Set 
1110bf8fc234Set 	return (PX_PROTECTED);
1111f8d2de6bSjchu }
1112f8d2de6bSjchu 
1113f8d2de6bSjchu /* ARGSUSED */
1114f8d2de6bSjchu int
px_err_no_panic_handle(dev_info_t * rpdip,caddr_t csr_base,ddi_fm_error_t * derr,px_err_reg_desc_t * err_reg_descr,px_err_bit_desc_t * err_bit_descr)1115bf8fc234Set px_err_no_panic_handle(dev_info_t *rpdip, caddr_t csr_base,
1116f8d2de6bSjchu 	ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
1117f8d2de6bSjchu 	px_err_bit_desc_t *err_bit_descr)
1118f8d2de6bSjchu {
1119bf8fc234Set 	if (px_log & PX_NO_PANIC) {
1120bf8fc234Set 		px_err_log_handle(rpdip, err_reg_descr, err_bit_descr,
1121bf8fc234Set 		    "NO PANIC");
1122bf8fc234Set 	}
1123f8d2de6bSjchu 
1124bf8fc234Set 	return (PX_NO_PANIC);
1125e51949e6Sdduvall }
11263d9c56a1Set 
1127e51949e6Sdduvall /* ARGSUSED */
1128e51949e6Sdduvall int
px_err_no_error_handle(dev_info_t * rpdip,caddr_t csr_base,ddi_fm_error_t * derr,px_err_reg_desc_t * err_reg_descr,px_err_bit_desc_t * err_bit_descr)1129bf8fc234Set px_err_no_error_handle(dev_info_t *rpdip, caddr_t csr_base,
1130bf8fc234Set 	ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
1131bf8fc234Set 	px_err_bit_desc_t *err_bit_descr)
1132e51949e6Sdduvall {
1133bf8fc234Set 	if (px_log & PX_NO_ERROR) {
1134bf8fc234Set 		px_err_log_handle(rpdip, err_reg_descr, err_bit_descr,
1135bf8fc234Set 		    "NO ERROR");
1136bf8fc234Set 	}
1137bf8fc234Set 
1138bf8fc234Set 	return (PX_NO_ERROR);
1139f8d2de6bSjchu }
1140f8d2de6bSjchu 
11418bc7d88aSet /* ARGSUSED */
PX_ERPT_SEND_DEC(do_not)11428bc7d88aSet PX_ERPT_SEND_DEC(do_not)
11438bc7d88aSet {
1144bf8fc234Set 	return (PX_NO_ERROR);
11458bc7d88aSet }
11468bc7d88aSet 
114781f63062Sarutz /*
114881f63062Sarutz  * Search the px_cb_list_t embedded in the px_cb_t for the
114981f63062Sarutz  * px_t of the specified Leaf (leaf_id).  Return its associated dip.
115081f63062Sarutz  */
115181f63062Sarutz static dev_info_t *
px_err_search_cb(px_cb_t * px_cb_p,uint_t leaf_id)115281f63062Sarutz px_err_search_cb(px_cb_t *px_cb_p, uint_t leaf_id)
115381f63062Sarutz {
115481f63062Sarutz 	int		i;
115581f63062Sarutz 	px_cb_list_t	*pxl_elemp;
115681f63062Sarutz 
115781f63062Sarutz 	for (i = px_cb_p->attachcnt, pxl_elemp = px_cb_p->pxl; i > 0;
115881f63062Sarutz 	    i--, pxl_elemp = pxl_elemp->next) {
115981f63062Sarutz 		if ((((pxu_t *)pxl_elemp->pxp->px_plat_p)->portid &
116081f63062Sarutz 		    OBERON_PORT_ID_LEAF_MASK) == leaf_id) {
116181f63062Sarutz 			return (pxl_elemp->pxp->px_dip);
116281f63062Sarutz 		}
116381f63062Sarutz 	}
116481f63062Sarutz 	return (NULL);
116581f63062Sarutz }
1166bf8fc234Set 
116725cf1a30Sjl /* UBC FATAL - see io erpt doc, section 1.1 */
116825cf1a30Sjl /* ARGSUSED */
PX_ERPT_SEND_DEC(ubc_fatal)116925cf1a30Sjl PX_ERPT_SEND_DEC(ubc_fatal)
117025cf1a30Sjl {
117125cf1a30Sjl 	char		buf[FM_MAX_CLASS];
117225cf1a30Sjl 	uint64_t	memory_ue_log, marked;
117325cf1a30Sjl 	char		unum[FM_MAX_CLASS];
117425cf1a30Sjl 	int		unum_length;
117525cf1a30Sjl 	uint64_t	device_id = 0;
117625cf1a30Sjl 	uint8_t		cpu_version = 0;
117725cf1a30Sjl 	nvlist_t	*resource = NULL;
117881f63062Sarutz 	uint64_t	ubc_intr_status;
117981f63062Sarutz 	px_t		*px_p;
118081f63062Sarutz 	px_cb_t		*px_cb_p;
118181f63062Sarutz 	dev_info_t	*actual_dip;
118225cf1a30Sjl 
118325cf1a30Sjl 	unum[0] = '\0';
118425cf1a30Sjl 	(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
118525cf1a30Sjl 
118625cf1a30Sjl 	memory_ue_log = CSR_XR(csr_base, UBC_MEMORY_UE_LOG);
118725cf1a30Sjl 	marked = (memory_ue_log >> UBC_MEMORY_UE_LOG_MARKED) &
118825cf1a30Sjl 	    UBC_MEMORY_UE_LOG_MARKED_MASK;
118925cf1a30Sjl 
119025cf1a30Sjl 	if ((strstr(class_name, "ubc.piowtue") != NULL) ||
119125cf1a30Sjl 	    (strstr(class_name, "ubc.piowbeue") != NULL) ||
119225cf1a30Sjl 	    (strstr(class_name, "ubc.piorbeue") != NULL) ||
119325cf1a30Sjl 	    (strstr(class_name, "ubc.dmarduea") != NULL) ||
119425cf1a30Sjl 	    (strstr(class_name, "ubc.dmardueb") != NULL)) {
119525cf1a30Sjl 		int eid = (memory_ue_log >> UBC_MEMORY_UE_LOG_EID) &
119625cf1a30Sjl 		    UBC_MEMORY_UE_LOG_EID_MASK;
119725cf1a30Sjl 		(void) strncat(buf, ubc_class_eid_qualifier[eid],
119825cf1a30Sjl 		    FM_MAX_CLASS);
119925cf1a30Sjl 
120025cf1a30Sjl 		if (eid == UBC_EID_MEM) {
120125cf1a30Sjl 			uint64_t phys_addr = memory_ue_log &
120225cf1a30Sjl 			    MMU_OBERON_PADDR_MASK;
120325cf1a30Sjl 			uint64_t offset = (uint64_t)-1;
120425cf1a30Sjl 
120525cf1a30Sjl 			resource = fm_nvlist_create(NULL);
120625cf1a30Sjl 			if (&plat_get_mem_unum) {
120725cf1a30Sjl 				if ((plat_get_mem_unum(0,
120825cf1a30Sjl 				    phys_addr, 0, B_TRUE, 0, unum,
120925cf1a30Sjl 				    FM_MAX_CLASS, &unum_length)) != 0)
121025cf1a30Sjl 					unum[0] = '\0';
121125cf1a30Sjl 			}
121225cf1a30Sjl 			fm_fmri_mem_set(resource, FM_MEM_SCHEME_VERSION,
12131ff65112Segillett 			    NULL, unum, NULL, offset);
121425cf1a30Sjl 
121525cf1a30Sjl 		} else if (eid == UBC_EID_CPU) {
121625cf1a30Sjl 			int cpuid = (marked & UBC_MARKED_MAX_CPUID_MASK);
121725cf1a30Sjl 			char sbuf[21]; /* sizeof (UINT64_MAX) + '\0' */
121825cf1a30Sjl 
121925cf1a30Sjl 			resource = fm_nvlist_create(NULL);
122025cf1a30Sjl 			cpu_version = cpunodes[cpuid].version;
122125cf1a30Sjl 			device_id = cpunodes[cpuid].device_id;
122225cf1a30Sjl 			(void) snprintf(sbuf, sizeof (sbuf), "%lX",
122325cf1a30Sjl 			    device_id);
122425cf1a30Sjl 			(void) fm_fmri_cpu_set(resource,
122525cf1a30Sjl 			    FM_CPU_SCHEME_VERSION, NULL, cpuid,
122625cf1a30Sjl 			    &cpu_version, sbuf);
122725cf1a30Sjl 		}
122825cf1a30Sjl 	}
122925cf1a30Sjl 
123081f63062Sarutz 	/*
123181f63062Sarutz 	 * For most of the errors represented in the UBC Interrupt Status
123281f63062Sarutz 	 * register, one can compute the dip of the actual Leaf that was
123381f63062Sarutz 	 * involved in the error.  To do this, find the px_cb_t structure
123481f63062Sarutz 	 * that is shared between a pair of Leaves (eg, LeafA and LeafB).
123581f63062Sarutz 	 *
123681f63062Sarutz 	 * If any of the error bits for LeafA are set in the hardware
123781f63062Sarutz 	 * register, search the list of px_t's rooted in the px_cb_t for
123881f63062Sarutz 	 * the one corresponding to LeafA.  If error bits for LeafB are set,
123981f63062Sarutz 	 * search the list for LeafB's px_t.  The px_t references its
124081f63062Sarutz 	 * associated dip.
124181f63062Sarutz 	 */
124281f63062Sarutz 	px_p = DIP_TO_STATE(rpdip);
124381f63062Sarutz 	px_cb_p = ((pxu_t *)px_p->px_plat_p)->px_cb_p;
124481f63062Sarutz 
124581f63062Sarutz 	/* read hardware register */
124681f63062Sarutz 	ubc_intr_status = CSR_XR(csr_base, UBC_INTERRUPT_STATUS);
124781f63062Sarutz 
124881f63062Sarutz 	if ((ubc_intr_status & UBC_INTERRUPT_STATUS_LEAFA) != 0) {
124981f63062Sarutz 		/* then Leaf A is involved in the error */
125081f63062Sarutz 		actual_dip = px_err_search_cb(px_cb_p, OBERON_PORT_ID_LEAF_A);
125181f63062Sarutz 		ASSERT(actual_dip != NULL);
125281f63062Sarutz 		rpdip = actual_dip;
125381f63062Sarutz 	} else if ((ubc_intr_status & UBC_INTERRUPT_STATUS_LEAFB) != 0) {
125481f63062Sarutz 		/* then Leaf B is involved in the error */
125581f63062Sarutz 		actual_dip = px_err_search_cb(px_cb_p, OBERON_PORT_ID_LEAF_B);
125681f63062Sarutz 		ASSERT(actual_dip != NULL);
125781f63062Sarutz 		rpdip = actual_dip;
125881f63062Sarutz 	} /* else error cannot be associated with a Leaf */
125981f63062Sarutz 
126025cf1a30Sjl 	if (resource) {
126125cf1a30Sjl 		ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
126225cf1a30Sjl 		    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
126325cf1a30Sjl 		    FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, B_TRUE,
126425cf1a30Sjl 		    OBERON_UBC_ELE, DATA_TYPE_UINT64,
126525cf1a30Sjl 		    CSR_XR(csr_base, UBC_ERROR_LOG_ENABLE),
126625cf1a30Sjl 		    OBERON_UBC_IE, DATA_TYPE_UINT64,
126725cf1a30Sjl 		    CSR_XR(csr_base, UBC_INTERRUPT_ENABLE),
126881f63062Sarutz 		    OBERON_UBC_IS, DATA_TYPE_UINT64, ubc_intr_status,
126925cf1a30Sjl 		    OBERON_UBC_ESS, DATA_TYPE_UINT64,
127025cf1a30Sjl 		    CSR_XR(csr_base, UBC_ERROR_STATUS_SET),
127125cf1a30Sjl 		    OBERON_UBC_MUE, DATA_TYPE_UINT64, memory_ue_log,
127225cf1a30Sjl 		    OBERON_UBC_UNUM, DATA_TYPE_STRING, unum,
127325cf1a30Sjl 		    OBERON_UBC_DID, DATA_TYPE_UINT64, device_id,
127425cf1a30Sjl 		    OBERON_UBC_CPUV, DATA_TYPE_UINT32, cpu_version,
127525cf1a30Sjl 		    OBERON_UBC_RESOURCE, DATA_TYPE_NVLIST, resource,
127625cf1a30Sjl 		    NULL);
127725cf1a30Sjl 		fm_nvlist_destroy(resource, FM_NVA_FREE);
127825cf1a30Sjl 	} else {
127925cf1a30Sjl 		ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
128025cf1a30Sjl 		    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
128125cf1a30Sjl 		    FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, B_TRUE,
128225cf1a30Sjl 		    OBERON_UBC_ELE, DATA_TYPE_UINT64,
128325cf1a30Sjl 		    CSR_XR(csr_base, UBC_ERROR_LOG_ENABLE),
128425cf1a30Sjl 		    OBERON_UBC_IE, DATA_TYPE_UINT64,
128525cf1a30Sjl 		    CSR_XR(csr_base, UBC_INTERRUPT_ENABLE),
128681f63062Sarutz 		    OBERON_UBC_IS, DATA_TYPE_UINT64, ubc_intr_status,
128725cf1a30Sjl 		    OBERON_UBC_ESS, DATA_TYPE_UINT64,
128825cf1a30Sjl 		    CSR_XR(csr_base, UBC_ERROR_STATUS_SET),
128925cf1a30Sjl 		    OBERON_UBC_MUE, DATA_TYPE_UINT64, memory_ue_log,
129025cf1a30Sjl 		    OBERON_UBC_UNUM, DATA_TYPE_STRING, unum,
129125cf1a30Sjl 		    OBERON_UBC_DID, DATA_TYPE_UINT64, device_id,
129225cf1a30Sjl 		    OBERON_UBC_CPUV, DATA_TYPE_UINT32, cpu_version,
129325cf1a30Sjl 		    NULL);
129425cf1a30Sjl 	}
129525cf1a30Sjl 
1296bf8fc234Set 	return (PX_NO_PANIC);
129725cf1a30Sjl }
12988bc7d88aSet 
1299bf8fc234Set /* JBC FATAL */
PX_ERPT_SEND_DEC(jbc_fatal)1300f8d2de6bSjchu PX_ERPT_SEND_DEC(jbc_fatal)
1301f8d2de6bSjchu {
1302f8d2de6bSjchu 	char		buf[FM_MAX_CLASS];
13038c334881Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(bit);
1304f8d2de6bSjchu 
1305f8d2de6bSjchu 	(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
1306f8d2de6bSjchu 	ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
1307f8d2de6bSjchu 	    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
13088c334881Sjchu 	    FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
1309f8d2de6bSjchu 	    FIRE_JBC_ELE, DATA_TYPE_UINT64,
1310f8d2de6bSjchu 	    CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE),
1311f8d2de6bSjchu 	    FIRE_JBC_IE, DATA_TYPE_UINT64,
1312f8d2de6bSjchu 	    CSR_XR(csr_base, JBC_INTERRUPT_ENABLE),
1313f8d2de6bSjchu 	    FIRE_JBC_IS, DATA_TYPE_UINT64,
1314f8d2de6bSjchu 	    ss_reg,
1315f8d2de6bSjchu 	    FIRE_JBC_ESS, DATA_TYPE_UINT64,
1316f8d2de6bSjchu 	    CSR_XR(csr_base, JBC_ERROR_STATUS_SET),
1317f8d2de6bSjchu 	    FIRE_JBC_FEL1, DATA_TYPE_UINT64,
1318f8d2de6bSjchu 	    CSR_XR(csr_base, FATAL_ERROR_LOG_1),
1319f8d2de6bSjchu 	    FIRE_JBC_FEL2, DATA_TYPE_UINT64,
1320f8d2de6bSjchu 	    CSR_XR(csr_base, FATAL_ERROR_LOG_2),
1321f8d2de6bSjchu 	    NULL);
1322f8d2de6bSjchu 
1323bf8fc234Set 	return (PX_NO_PANIC);
1324f8d2de6bSjchu }
1325f8d2de6bSjchu 
1326bf8fc234Set /* JBC MERGE */
PX_ERPT_SEND_DEC(jbc_merge)1327f8d2de6bSjchu PX_ERPT_SEND_DEC(jbc_merge)
1328f8d2de6bSjchu {
1329f8d2de6bSjchu 	char		buf[FM_MAX_CLASS];
13308c334881Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(bit);
1331f8d2de6bSjchu 
1332f8d2de6bSjchu 	(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
1333f8d2de6bSjchu 	ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
1334f8d2de6bSjchu 	    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
13358c334881Sjchu 	    FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
1336f8d2de6bSjchu 	    FIRE_JBC_ELE, DATA_TYPE_UINT64,
1337f8d2de6bSjchu 	    CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE),
1338f8d2de6bSjchu 	    FIRE_JBC_IE, DATA_TYPE_UINT64,
1339f8d2de6bSjchu 	    CSR_XR(csr_base, JBC_INTERRUPT_ENABLE),
1340f8d2de6bSjchu 	    FIRE_JBC_IS, DATA_TYPE_UINT64,
1341f8d2de6bSjchu 	    ss_reg,
1342f8d2de6bSjchu 	    FIRE_JBC_ESS, DATA_TYPE_UINT64,
1343f8d2de6bSjchu 	    CSR_XR(csr_base, JBC_ERROR_STATUS_SET),
1344f8d2de6bSjchu 	    FIRE_JBC_MTEL, DATA_TYPE_UINT64,
1345f8d2de6bSjchu 	    CSR_XR(csr_base, MERGE_TRANSACTION_ERROR_LOG),
1346f8d2de6bSjchu 	    NULL);
1347f8d2de6bSjchu 
1348bf8fc234Set 	return (PX_NO_PANIC);
1349f8d2de6bSjchu }
1350f8d2de6bSjchu 
1351f8d2de6bSjchu /*
1352bf8fc234Set  * JBC Merge buffer retryable errors:
1353bf8fc234Set  *    Merge buffer parity error (rd_buf): PIO or DMA
1354bf8fc234Set  *    Merge buffer parity error (wr_buf): PIO or DMA
1355f8d2de6bSjchu  */
1356f8d2de6bSjchu /* ARGSUSED */
1357f8d2de6bSjchu int
px_err_jbc_merge_handle(dev_info_t * rpdip,caddr_t csr_base,ddi_fm_error_t * derr,px_err_reg_desc_t * err_reg_descr,px_err_bit_desc_t * err_bit_descr)1358f8d2de6bSjchu px_err_jbc_merge_handle(dev_info_t *rpdip, caddr_t csr_base,
1359bf8fc234Set     ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
1360bf8fc234Set     px_err_bit_desc_t *err_bit_descr)
1361f8d2de6bSjchu {
1362bf8fc234Set 	/*
1363bf8fc234Set 	 * Holder function to attempt error recovery.  When the features
1364bf8fc234Set 	 * are in place, look up the address of the transaction in:
1365bf8fc234Set 	 *
1366bf8fc234Set 	 * paddr = CSR_XR(csr_base, MERGE_TRANSACTION_ERROR_LOG);
1367bf8fc234Set 	 * paddr &= MERGE_TRANSACTION_ERROR_LOG_ADDRESS_MASK;
1368bf8fc234Set 	 *
1369bf8fc234Set 	 * If the error is a secondary error, there is no log information
1370bf8fc234Set 	 * just panic as it is unknown which address has been affected.
1371bf8fc234Set 	 *
1372bf8fc234Set 	 * Remember the address is pretranslation and might be hard to look
1373bf8fc234Set 	 * up the appropriate driver based on the PA.
1374bf8fc234Set 	 */
1375bf8fc234Set 	return (px_err_panic_handle(rpdip, csr_base, derr, err_reg_descr,
13761ff65112Segillett 	    err_bit_descr));
1377f8d2de6bSjchu }
1378f8d2de6bSjchu 
1379bf8fc234Set /* JBC Jbusint IN */
PX_ERPT_SEND_DEC(jbc_in)1380f8d2de6bSjchu PX_ERPT_SEND_DEC(jbc_in)
1381f8d2de6bSjchu {
1382f8d2de6bSjchu 	char		buf[FM_MAX_CLASS];
13838c334881Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(bit);
1384f8d2de6bSjchu 
1385f8d2de6bSjchu 	(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
1386f8d2de6bSjchu 	ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
1387f8d2de6bSjchu 	    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
13888c334881Sjchu 	    FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
1389f8d2de6bSjchu 	    FIRE_JBC_ELE, DATA_TYPE_UINT64,
1390f8d2de6bSjchu 	    CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE),
1391f8d2de6bSjchu 	    FIRE_JBC_IE, DATA_TYPE_UINT64,
1392f8d2de6bSjchu 	    CSR_XR(csr_base, JBC_INTERRUPT_ENABLE),
1393f8d2de6bSjchu 	    FIRE_JBC_IS, DATA_TYPE_UINT64,
1394f8d2de6bSjchu 	    ss_reg,
1395f8d2de6bSjchu 	    FIRE_JBC_ESS, DATA_TYPE_UINT64,
1396f8d2de6bSjchu 	    CSR_XR(csr_base, JBC_ERROR_STATUS_SET),
1397f8d2de6bSjchu 	    FIRE_JBC_JITEL1, DATA_TYPE_UINT64,
1398f8d2de6bSjchu 	    CSR_XR(csr_base, JBCINT_IN_TRANSACTION_ERROR_LOG),
1399f8d2de6bSjchu 	    FIRE_JBC_JITEL2, DATA_TYPE_UINT64,
1400f8d2de6bSjchu 	    CSR_XR(csr_base, JBCINT_IN_TRANSACTION_ERROR_LOG_2),
1401f8d2de6bSjchu 	    NULL);
1402f8d2de6bSjchu 
1403bf8fc234Set 	return (PX_NO_PANIC);
1404f8d2de6bSjchu }
1405f8d2de6bSjchu 
1406f8d2de6bSjchu /*
1407bf8fc234Set  * JBC Jbusint IN retryable errors
1408f8d2de6bSjchu  * Log Reg[42:0].
1409bf8fc234Set  *    Write Data Parity Error: PIO Writes
1410bf8fc234Set  *    Read Data Parity Error: DMA Reads
1411f8d2de6bSjchu  */
1412f8d2de6bSjchu int
px_err_jbc_jbusint_in_handle(dev_info_t * rpdip,caddr_t csr_base,ddi_fm_error_t * derr,px_err_reg_desc_t * err_reg_descr,px_err_bit_desc_t * err_bit_descr)1413f8d2de6bSjchu px_err_jbc_jbusint_in_handle(dev_info_t *rpdip, caddr_t csr_base,
1414f8d2de6bSjchu 	ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
1415f8d2de6bSjchu 	px_err_bit_desc_t *err_bit_descr)
1416f8d2de6bSjchu {
1417bf8fc234Set 	/*
1418bf8fc234Set 	 * Holder function to attempt error recovery.  When the features
1419bf8fc234Set 	 * are in place, look up the address of the transaction in:
1420bf8fc234Set 	 *
1421bf8fc234Set 	 * paddr = CSR_XR(csr_base, JBCINT_IN_TRANSACTION_ERROR_LOG);
1422bf8fc234Set 	 * paddr &= JBCINT_IN_TRANSACTION_ERROR_LOG_ADDRESS_MASK;
1423bf8fc234Set 	 *
1424bf8fc234Set 	 * If the error is a secondary error, there is no log information
1425bf8fc234Set 	 * just panic as it is unknown which address has been affected.
1426bf8fc234Set 	 *
1427bf8fc234Set 	 * Remember the address is pretranslation and might be hard to look
1428bf8fc234Set 	 * up the appropriate driver based on the PA.
1429bf8fc234Set 	 */
1430bf8fc234Set 	return (px_err_panic_handle(rpdip, csr_base, derr, err_reg_descr,
14311ff65112Segillett 	    err_bit_descr));
1432f8d2de6bSjchu }
1433f8d2de6bSjchu 
1434f8d2de6bSjchu 
1435bf8fc234Set /* JBC Jbusint Out */
PX_ERPT_SEND_DEC(jbc_out)1436f8d2de6bSjchu PX_ERPT_SEND_DEC(jbc_out)
1437f8d2de6bSjchu {
1438f8d2de6bSjchu 	char		buf[FM_MAX_CLASS];
14398c334881Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(bit);
1440f8d2de6bSjchu 
1441f8d2de6bSjchu 	(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
1442f8d2de6bSjchu 	ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
1443f8d2de6bSjchu 	    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
14448c334881Sjchu 	    FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
1445f8d2de6bSjchu 	    FIRE_JBC_ELE, DATA_TYPE_UINT64,
1446f8d2de6bSjchu 	    CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE),
1447f8d2de6bSjchu 	    FIRE_JBC_IE, DATA_TYPE_UINT64,
1448f8d2de6bSjchu 	    CSR_XR(csr_base, JBC_INTERRUPT_ENABLE),
1449f8d2de6bSjchu 	    FIRE_JBC_IS, DATA_TYPE_UINT64,
1450f8d2de6bSjchu 	    ss_reg,
1451f8d2de6bSjchu 	    FIRE_JBC_ESS, DATA_TYPE_UINT64,
1452f8d2de6bSjchu 	    CSR_XR(csr_base, JBC_ERROR_STATUS_SET),
1453f8d2de6bSjchu 	    FIRE_JBC_JOTEL1, DATA_TYPE_UINT64,
1454f8d2de6bSjchu 	    CSR_XR(csr_base, JBCINT_OUT_TRANSACTION_ERROR_LOG),
1455f8d2de6bSjchu 	    FIRE_JBC_JOTEL2, DATA_TYPE_UINT64,
1456f8d2de6bSjchu 	    CSR_XR(csr_base, JBCINT_OUT_TRANSACTION_ERROR_LOG_2),
1457f8d2de6bSjchu 	    NULL);
1458f8d2de6bSjchu 
1459bf8fc234Set 	return (PX_NO_PANIC);
1460f8d2de6bSjchu }
1461f8d2de6bSjchu 
1462bf8fc234Set /* JBC Dmcint ODCD */
PX_ERPT_SEND_DEC(jbc_odcd)1463f8d2de6bSjchu PX_ERPT_SEND_DEC(jbc_odcd)
1464f8d2de6bSjchu {
1465f8d2de6bSjchu 	char		buf[FM_MAX_CLASS];
14668c334881Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(bit);
1467f8d2de6bSjchu 
1468f8d2de6bSjchu 	(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
1469f8d2de6bSjchu 	ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
1470f8d2de6bSjchu 	    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
14718c334881Sjchu 	    FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
1472f8d2de6bSjchu 	    FIRE_JBC_ELE, DATA_TYPE_UINT64,
1473f8d2de6bSjchu 	    CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE),
1474f8d2de6bSjchu 	    FIRE_JBC_IE, DATA_TYPE_UINT64,
1475f8d2de6bSjchu 	    CSR_XR(csr_base, JBC_INTERRUPT_ENABLE),
1476f8d2de6bSjchu 	    FIRE_JBC_IS, DATA_TYPE_UINT64,
1477f8d2de6bSjchu 	    ss_reg,
1478f8d2de6bSjchu 	    FIRE_JBC_ESS, DATA_TYPE_UINT64,
1479f8d2de6bSjchu 	    CSR_XR(csr_base, JBC_ERROR_STATUS_SET),
1480f8d2de6bSjchu 	    FIRE_JBC_DMC_ODCD, DATA_TYPE_UINT64,
1481f8d2de6bSjchu 	    CSR_XR(csr_base, DMCINT_ODCD_ERROR_LOG),
1482f8d2de6bSjchu 	    NULL);
1483f8d2de6bSjchu 
1484bf8fc234Set 	return (PX_NO_PANIC);
1485f8d2de6bSjchu }
1486f8d2de6bSjchu 
1487f8d2de6bSjchu /*
1488f8d2de6bSjchu  * JBC Dmcint ODCO nonfatal errer handling -
1489bf8fc234Set  *    PIO data parity error: PIO
1490f8d2de6bSjchu  */
1491f8d2de6bSjchu /* ARGSUSED */
1492f8d2de6bSjchu int
px_err_jbc_dmcint_odcd_handle(dev_info_t * rpdip,caddr_t csr_base,ddi_fm_error_t * derr,px_err_reg_desc_t * err_reg_descr,px_err_bit_desc_t * err_bit_descr)1493f8d2de6bSjchu px_err_jbc_dmcint_odcd_handle(dev_info_t *rpdip, caddr_t csr_base,
1494f8d2de6bSjchu 	ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
1495f8d2de6bSjchu 	px_err_bit_desc_t *err_bit_descr)
1496f8d2de6bSjchu {
1497bf8fc234Set 	/*
1498bf8fc234Set 	 * Holder function to attempt error recovery.  When the features
1499bf8fc234Set 	 * are in place, look up the address of the transaction in:
1500bf8fc234Set 	 *
1501bf8fc234Set 	 * paddr = CSR_XR(csr_base, DMCINT_ODCD_ERROR_LOG);
1502bf8fc234Set 	 * paddr &= DMCINT_ODCD_ERROR_LOG_ADDRESS_MASK;
1503bf8fc234Set 	 *
1504bf8fc234Set 	 * If the error is a secondary error, there is no log information
1505bf8fc234Set 	 * just panic as it is unknown which address has been affected.
1506bf8fc234Set 	 *
1507bf8fc234Set 	 * Remember the address is pretranslation and might be hard to look
1508bf8fc234Set 	 * up the appropriate driver based on the PA.
1509bf8fc234Set 	 */
1510bf8fc234Set 	return (px_err_panic_handle(rpdip, csr_base, derr, err_reg_descr,
15111ff65112Segillett 	    err_bit_descr));
1512f8d2de6bSjchu }
1513f8d2de6bSjchu 
1514f0a73f04Sschwartz /* Does address in DMCINT error log register match address of pcitool access? */
1515f0a73f04Sschwartz static boolean_t
px_jbc_pcitool_addr_match(dev_info_t * rpdip,caddr_t csr_base)1516f0a73f04Sschwartz px_jbc_pcitool_addr_match(dev_info_t *rpdip, caddr_t csr_base)
1517f0a73f04Sschwartz {
1518f0a73f04Sschwartz 	px_t	*px_p = DIP_TO_STATE(rpdip);
1519f0a73f04Sschwartz 	pxu_t	*pxu_p = (pxu_t *)px_p->px_plat_p;
1520f0a73f04Sschwartz 	caddr_t	pcitool_addr = pxu_p->pcitool_addr;
1521f0a73f04Sschwartz 	caddr_t errlog_addr =
1522f0a73f04Sschwartz 	    (caddr_t)CSR_FR(csr_base, DMCINT_ODCD_ERROR_LOG, ADDRESS);
1523f0a73f04Sschwartz 
1524f0a73f04Sschwartz 	return (pcitool_addr == errlog_addr);
1525f0a73f04Sschwartz }
1526f0a73f04Sschwartz 
1527f0a73f04Sschwartz /*
1528f0a73f04Sschwartz  * JBC Dmcint ODCD errer handling for errors which are forgivable during a safe
1529f0a73f04Sschwartz  * access.  (This will be most likely be a PCItool access.)  If not a safe
1530f0a73f04Sschwartz  * access context, treat like jbc_dmcint_odcd.
1531f0a73f04Sschwartz  *    Unmapped PIO read error: pio:read:M:nonfatal
1532f0a73f04Sschwartz  *    Unmapped PIO write error: pio:write:M:nonfatal
1533f0a73f04Sschwartz  *    Invalid PIO write to PCIe cfg/io, csr, ebus or i2c bus: pio:write:nonfatal
1534f0a73f04Sschwartz  *    Invalid PIO read to PCIe cfg/io, csr, ebus or i2c bus: pio:read:nonfatal
1535f0a73f04Sschwartz  */
1536f0a73f04Sschwartz /* ARGSUSED */
1537f0a73f04Sschwartz int
px_err_jbc_safe_acc_handle(dev_info_t * rpdip,caddr_t csr_base,ddi_fm_error_t * derr,px_err_reg_desc_t * err_reg_descr,px_err_bit_desc_t * err_bit_descr)1538f0a73f04Sschwartz px_err_jbc_safe_acc_handle(dev_info_t *rpdip, caddr_t csr_base,
1539f0a73f04Sschwartz 	ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
1540f0a73f04Sschwartz 	px_err_bit_desc_t *err_bit_descr)
1541f0a73f04Sschwartz {
1542f0a73f04Sschwartz 	boolean_t	pri = PX_ERR_IS_PRI(err_bit_descr->bit);
1543f0a73f04Sschwartz 
1544f0a73f04Sschwartz 	if (!pri)
1545bf8fc234Set 		return (px_err_panic_handle(rpdip, csr_base, derr,
15461ff65112Segillett 		    err_reg_descr, err_bit_descr));
1547f0a73f04Sschwartz 	/*
1548f0a73f04Sschwartz 	 * Got an error which is forgivable during a PCItool access.
1549f0a73f04Sschwartz 	 *
1550f0a73f04Sschwartz 	 * Don't do handler check since the error may otherwise be unfairly
1551f0a73f04Sschwartz 	 * attributed to a device.  Just return.
1552f0a73f04Sschwartz 	 *
1553f0a73f04Sschwartz 	 * Note: There is a hole here in that a legitimate error can come in
1554f0a73f04Sschwartz 	 * while a PCItool access is in play and be forgiven.  This is possible
1555f0a73f04Sschwartz 	 * though not likely.
1556f0a73f04Sschwartz 	 */
1557f0a73f04Sschwartz 	if ((derr->fme_flag != DDI_FM_ERR_UNEXPECTED) &&
1558f0a73f04Sschwartz 	    (px_jbc_pcitool_addr_match(rpdip, csr_base)))
1559bf8fc234Set 		return (px_err_protected_handle(rpdip, csr_base, derr,
15601ff65112Segillett 		    err_reg_descr, err_bit_descr));
1561f0a73f04Sschwartz 
1562f0a73f04Sschwartz 	return (px_err_jbc_dmcint_odcd_handle(rpdip, csr_base, derr,
1563f0a73f04Sschwartz 	    err_reg_descr, err_bit_descr));
1564f0a73f04Sschwartz }
1565f0a73f04Sschwartz 
1566bf8fc234Set /* JBC Dmcint IDC */
PX_ERPT_SEND_DEC(jbc_idc)1567f8d2de6bSjchu PX_ERPT_SEND_DEC(jbc_idc)
1568f8d2de6bSjchu {
1569f8d2de6bSjchu 	char		buf[FM_MAX_CLASS];
15708c334881Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(bit);
1571f8d2de6bSjchu 
1572f8d2de6bSjchu 	(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
1573f8d2de6bSjchu 	ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
1574f8d2de6bSjchu 	    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
15758c334881Sjchu 	    FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
1576f8d2de6bSjchu 	    FIRE_JBC_ELE, DATA_TYPE_UINT64,
1577f8d2de6bSjchu 	    CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE),
1578f8d2de6bSjchu 	    FIRE_JBC_IE, DATA_TYPE_UINT64,
1579f8d2de6bSjchu 	    CSR_XR(csr_base, JBC_INTERRUPT_ENABLE),
1580f8d2de6bSjchu 	    FIRE_JBC_IS, DATA_TYPE_UINT64,
1581f8d2de6bSjchu 	    ss_reg,
1582f8d2de6bSjchu 	    FIRE_JBC_ESS, DATA_TYPE_UINT64,
1583f8d2de6bSjchu 	    CSR_XR(csr_base, JBC_ERROR_STATUS_SET),
1584f8d2de6bSjchu 	    FIRE_JBC_DMC_IDC, DATA_TYPE_UINT64,
1585f8d2de6bSjchu 	    CSR_XR(csr_base, DMCINT_IDC_ERROR_LOG),
1586f8d2de6bSjchu 	    NULL);
1587f8d2de6bSjchu 
1588bf8fc234Set 	return (PX_NO_PANIC);
1589f8d2de6bSjchu }
1590f8d2de6bSjchu 
1591bf8fc234Set /* JBC CSR */
PX_ERPT_SEND_DEC(jbc_csr)1592f8d2de6bSjchu PX_ERPT_SEND_DEC(jbc_csr)
1593f8d2de6bSjchu {
1594f8d2de6bSjchu 	char		buf[FM_MAX_CLASS];
15958c334881Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(bit);
1596f8d2de6bSjchu 
1597f8d2de6bSjchu 	(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
1598f8d2de6bSjchu 	ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
1599f8d2de6bSjchu 	    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
16008c334881Sjchu 	    FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
1601f8d2de6bSjchu 	    FIRE_JBC_ELE, DATA_TYPE_UINT64,
1602f8d2de6bSjchu 	    CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE),
1603f8d2de6bSjchu 	    FIRE_JBC_IE, DATA_TYPE_UINT64,
1604f8d2de6bSjchu 	    CSR_XR(csr_base, JBC_INTERRUPT_ENABLE),
1605f8d2de6bSjchu 	    FIRE_JBC_IS, DATA_TYPE_UINT64,
1606f8d2de6bSjchu 	    ss_reg,
1607f8d2de6bSjchu 	    FIRE_JBC_ESS, DATA_TYPE_UINT64,
1608f8d2de6bSjchu 	    CSR_XR(csr_base, JBC_ERROR_STATUS_SET),
1609f8d2de6bSjchu 	    "jbc-error-reg", DATA_TYPE_UINT64,
1610f8d2de6bSjchu 	    CSR_XR(csr_base, CSR_ERROR_LOG),
1611f8d2de6bSjchu 	    NULL);
1612f8d2de6bSjchu 
1613bf8fc234Set 	return (PX_NO_PANIC);
1614f8d2de6bSjchu }
1615f8d2de6bSjchu 
1616bf8fc234Set /* DMC IMU RDS */
PX_ERPT_SEND_DEC(imu_rds)1617f8d2de6bSjchu PX_ERPT_SEND_DEC(imu_rds)
1618f8d2de6bSjchu {
1619f8d2de6bSjchu 	char		buf[FM_MAX_CLASS];
16208c334881Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(bit);
1621f8d2de6bSjchu 
1622f8d2de6bSjchu 	(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
1623f8d2de6bSjchu 	ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
1624f8d2de6bSjchu 	    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
16258c334881Sjchu 	    FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
1626f8d2de6bSjchu 	    FIRE_IMU_ELE, DATA_TYPE_UINT64,
1627f8d2de6bSjchu 	    CSR_XR(csr_base, IMU_ERROR_LOG_ENABLE),
1628f8d2de6bSjchu 	    FIRE_IMU_IE, DATA_TYPE_UINT64,
1629f8d2de6bSjchu 	    CSR_XR(csr_base, IMU_INTERRUPT_ENABLE),
1630f8d2de6bSjchu 	    FIRE_IMU_IS, DATA_TYPE_UINT64,
1631f8d2de6bSjchu 	    ss_reg,
1632f8d2de6bSjchu 	    FIRE_IMU_ESS, DATA_TYPE_UINT64,
1633f8d2de6bSjchu 	    CSR_XR(csr_base, IMU_ERROR_STATUS_SET),
1634f8d2de6bSjchu 	    FIRE_IMU_RDS, DATA_TYPE_UINT64,
1635f8d2de6bSjchu 	    CSR_XR(csr_base, IMU_RDS_ERROR_LOG),
1636f8d2de6bSjchu 	    NULL);
1637f8d2de6bSjchu 
1638bf8fc234Set 	return (PX_NO_PANIC);
16391a887b2eSjchu }
16401a887b2eSjchu 
1641f8d2de6bSjchu /* handle EQ overflow */
1642f8d2de6bSjchu /* ARGSUSED */
1643f8d2de6bSjchu int
px_err_imu_eq_ovfl_handle(dev_info_t * rpdip,caddr_t csr_base,ddi_fm_error_t * derr,px_err_reg_desc_t * err_reg_descr,px_err_bit_desc_t * err_bit_descr)1644f8d2de6bSjchu px_err_imu_eq_ovfl_handle(dev_info_t *rpdip, caddr_t csr_base,
1645f8d2de6bSjchu 	ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
1646f8d2de6bSjchu 	px_err_bit_desc_t *err_bit_descr)
1647f8d2de6bSjchu {
1648bf8fc234Set 	px_t	*px_p = DIP_TO_STATE(rpdip);
1649bf8fc234Set 	pxu_t	*pxu_p = (pxu_t *)px_p->px_plat_p;
1650bf8fc234Set 	int	err = px_err_check_eq(rpdip);
1651e51949e6Sdduvall 
1652bf8fc234Set 	if ((err == PX_PANIC) && (pxu_p->cpr_flag == PX_NOT_CPR)) {
1653bf8fc234Set 		return (px_err_panic_handle(rpdip, csr_base, derr,
16541ff65112Segillett 		    err_reg_descr, err_bit_descr));
1655bf8fc234Set 	} else {
1656bf8fc234Set 		return (px_err_no_panic_handle(rpdip, csr_base, derr,
16571ff65112Segillett 		    err_reg_descr, err_bit_descr));
1658bf8fc234Set 	}
1659f8d2de6bSjchu }
1660f8d2de6bSjchu 
1661bf8fc234Set /* DMC IMU SCS */
PX_ERPT_SEND_DEC(imu_scs)1662f8d2de6bSjchu PX_ERPT_SEND_DEC(imu_scs)
1663f8d2de6bSjchu {
1664f8d2de6bSjchu 	char		buf[FM_MAX_CLASS];
16658c334881Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(bit);
1666f8d2de6bSjchu 
1667f8d2de6bSjchu 	(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
1668f8d2de6bSjchu 	ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
1669f8d2de6bSjchu 	    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
16708c334881Sjchu 	    FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
1671f8d2de6bSjchu 	    FIRE_IMU_ELE, DATA_TYPE_UINT64,
1672f8d2de6bSjchu 	    CSR_XR(csr_base, IMU_ERROR_LOG_ENABLE),
1673f8d2de6bSjchu 	    FIRE_IMU_IE, DATA_TYPE_UINT64,
1674f8d2de6bSjchu 	    CSR_XR(csr_base, IMU_INTERRUPT_ENABLE),
1675f8d2de6bSjchu 	    FIRE_IMU_IS, DATA_TYPE_UINT64,
1676f8d2de6bSjchu 	    ss_reg,
1677f8d2de6bSjchu 	    FIRE_IMU_ESS, DATA_TYPE_UINT64,
1678f8d2de6bSjchu 	    CSR_XR(csr_base, IMU_ERROR_STATUS_SET),
1679f8d2de6bSjchu 	    FIRE_IMU_SCS, DATA_TYPE_UINT64,
1680f8d2de6bSjchu 	    CSR_XR(csr_base, IMU_SCS_ERROR_LOG),
1681f8d2de6bSjchu 	    NULL);
1682f8d2de6bSjchu 
1683bf8fc234Set 	return (PX_NO_PANIC);
1684f8d2de6bSjchu }
1685f8d2de6bSjchu 
1686bf8fc234Set /* DMC IMU */
PX_ERPT_SEND_DEC(imu)1687f8d2de6bSjchu PX_ERPT_SEND_DEC(imu)
1688f8d2de6bSjchu {
1689f8d2de6bSjchu 	char		buf[FM_MAX_CLASS];
16908c334881Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(bit);
1691f8d2de6bSjchu 
1692f8d2de6bSjchu 	(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
1693f8d2de6bSjchu 	ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
1694f8d2de6bSjchu 	    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
16958c334881Sjchu 	    FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
1696f8d2de6bSjchu 	    FIRE_IMU_ELE, DATA_TYPE_UINT64,
1697f8d2de6bSjchu 	    CSR_XR(csr_base, IMU_ERROR_LOG_ENABLE),
1698f8d2de6bSjchu 	    FIRE_IMU_IE, DATA_TYPE_UINT64,
1699f8d2de6bSjchu 	    CSR_XR(csr_base, IMU_INTERRUPT_ENABLE),
1700f8d2de6bSjchu 	    FIRE_IMU_IS, DATA_TYPE_UINT64,
1701f8d2de6bSjchu 	    ss_reg,
1702f8d2de6bSjchu 	    FIRE_IMU_ESS, DATA_TYPE_UINT64,
1703f8d2de6bSjchu 	    CSR_XR(csr_base, IMU_ERROR_STATUS_SET),
1704f8d2de6bSjchu 	    NULL);
1705f8d2de6bSjchu 
1706bf8fc234Set 	return (PX_NO_PANIC);
1707f8d2de6bSjchu }
1708f8d2de6bSjchu 
1709bf8fc234Set /* DMC MMU TFAR/TFSR */
PX_ERPT_SEND_DEC(mmu_tfar_tfsr)1710f8d2de6bSjchu PX_ERPT_SEND_DEC(mmu_tfar_tfsr)
1711f8d2de6bSjchu {
1712f8d2de6bSjchu 	char		buf[FM_MAX_CLASS];
17138c334881Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(bit);
1714bf8fc234Set 	px_t		*px_p = DIP_TO_STATE(rpdip);
1715c85864d8SKrishna Elango 	pcie_req_id_t	fault_bdf = PCIE_INVALID_BDF;
1716bf8fc234Set 	uint16_t	s_status = 0;
1717bf8fc234Set 
1718bf8fc234Set 	if (pri) {
1719bf8fc234Set 		fault_bdf = CSR_XR(csr_base, MMU_TRANSLATION_FAULT_STATUS)
1720bf8fc234Set 		    & (MMU_TRANSLATION_FAULT_STATUS_ID_MASK <<
1721bf8fc234Set 		    MMU_TRANSLATION_FAULT_STATUS_ID);
1722bf8fc234Set 		s_status = PCI_STAT_S_TARG_AB;
1723bf8fc234Set 
1724bf8fc234Set 		/* Only PIO Fault Addresses are valid, this is DMA */
1725*e214b19eSToomas Soome 		(void) px_rp_en_q(px_p, fault_bdf, 0, s_status);
1726bf8fc234Set 	}
1727f8d2de6bSjchu 
1728f8d2de6bSjchu 	(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
172925cf1a30Sjl 
1730f8d2de6bSjchu 	ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
1731f8d2de6bSjchu 	    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
17328c334881Sjchu 	    FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
1733f8d2de6bSjchu 	    FIRE_MMU_ELE, DATA_TYPE_UINT64,
1734f8d2de6bSjchu 	    CSR_XR(csr_base, MMU_ERROR_LOG_ENABLE),
1735f8d2de6bSjchu 	    FIRE_MMU_IE, DATA_TYPE_UINT64,
1736f8d2de6bSjchu 	    CSR_XR(csr_base, MMU_INTERRUPT_ENABLE),
1737f8d2de6bSjchu 	    FIRE_MMU_IS, DATA_TYPE_UINT64,
1738f8d2de6bSjchu 	    ss_reg,
1739f8d2de6bSjchu 	    FIRE_MMU_ESS, DATA_TYPE_UINT64,
1740f8d2de6bSjchu 	    CSR_XR(csr_base, MMU_ERROR_STATUS_SET),
1741f8d2de6bSjchu 	    FIRE_MMU_TFAR, DATA_TYPE_UINT64,
1742f8d2de6bSjchu 	    CSR_XR(csr_base, MMU_TRANSLATION_FAULT_ADDRESS),
1743f8d2de6bSjchu 	    FIRE_MMU_TFSR, DATA_TYPE_UINT64,
1744f8d2de6bSjchu 	    CSR_XR(csr_base, MMU_TRANSLATION_FAULT_STATUS),
1745f8d2de6bSjchu 	    NULL);
1746f8d2de6bSjchu 
1747bf8fc234Set 	return (PX_NO_PANIC);
1748f8d2de6bSjchu }
1749f8d2de6bSjchu 
1750bf8fc234Set /* DMC MMU */
PX_ERPT_SEND_DEC(mmu)1751f8d2de6bSjchu PX_ERPT_SEND_DEC(mmu)
1752f8d2de6bSjchu {
1753f8d2de6bSjchu 	char		buf[FM_MAX_CLASS];
17548c334881Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(bit);
1755f8d2de6bSjchu 
1756f8d2de6bSjchu 	(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
1757f8d2de6bSjchu 	ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
1758f8d2de6bSjchu 	    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
17598c334881Sjchu 	    FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
1760f8d2de6bSjchu 	    FIRE_MMU_ELE, DATA_TYPE_UINT64,
1761f8d2de6bSjchu 	    CSR_XR(csr_base, MMU_ERROR_LOG_ENABLE),
1762f8d2de6bSjchu 	    FIRE_MMU_IE, DATA_TYPE_UINT64,
1763f8d2de6bSjchu 	    CSR_XR(csr_base, MMU_INTERRUPT_ENABLE),
1764f8d2de6bSjchu 	    FIRE_MMU_IS, DATA_TYPE_UINT64,
1765f8d2de6bSjchu 	    ss_reg,
1766f8d2de6bSjchu 	    FIRE_MMU_ESS, DATA_TYPE_UINT64,
1767f8d2de6bSjchu 	    CSR_XR(csr_base, MMU_ERROR_STATUS_SET),
1768f8d2de6bSjchu 	    NULL);
1769f8d2de6bSjchu 
1770bf8fc234Set 	return (PX_NO_PANIC);
1771f8d2de6bSjchu }
1772f8d2de6bSjchu 
1773bf8fc234Set /*
1774bf8fc234Set  * IMU function to handle all Received but Not Enabled errors.
1775bf8fc234Set  *
1776bf8fc234Set  * These errors are due to transactions modes in which the PX driver was not
1777bf8fc234Set  * setup to be able to do.  If possible, inform the driver that their DMA has
1778bf8fc234Set  * failed by marking their DMA handle as failed, but do not panic the system.
1779bf8fc234Set  * Most likely the address is not valid, as Fire wasn't setup to handle them in
1780bf8fc234Set  * the first place.
1781bf8fc234Set  *
1782bf8fc234Set  * These errors are not retryable, unless the PX mode has changed, otherwise the
1783bf8fc234Set  * same error will occur again.
1784bf8fc234Set  */
1785f8d2de6bSjchu int
px_err_mmu_rbne_handle(dev_info_t * rpdip,caddr_t csr_base,ddi_fm_error_t * derr,px_err_reg_desc_t * err_reg_descr,px_err_bit_desc_t * err_bit_descr)1786f8d2de6bSjchu px_err_mmu_rbne_handle(dev_info_t *rpdip, caddr_t csr_base,
1787f8d2de6bSjchu 	ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
1788f8d2de6bSjchu 	px_err_bit_desc_t *err_bit_descr)
1789f8d2de6bSjchu {
1790bf8fc234Set 	pcie_req_id_t bdf;
1791f8d2de6bSjchu 
1792bf8fc234Set 	if (!PX_ERR_IS_PRI(err_bit_descr->bit))
1793bf8fc234Set 		goto done;
17948c334881Sjchu 
1795bf8fc234Set 	bdf = (pcie_req_id_t)CSR_FR(csr_base, MMU_TRANSLATION_FAULT_STATUS, ID);
1796*e214b19eSToomas Soome 	(void) pf_hdl_lookup(rpdip, derr->fme_ena, PF_ADDR_DMA, 0, bdf);
1797f8d2de6bSjchu 
1798bf8fc234Set done:
1799bf8fc234Set 	return (px_err_no_panic_handle(rpdip, csr_base, derr, err_reg_descr,
18001ff65112Segillett 	    err_bit_descr));
1801bf8fc234Set }
18023677cad4Set 
1803bf8fc234Set /*
1804bf8fc234Set  * IMU function to handle all invalid address errors.
1805bf8fc234Set  *
1806bf8fc234Set  * These errors are due to transactions in which the address is not recognized.
1807bf8fc234Set  * If possible, inform the driver that all DMAs have failed by marking their DMA
1808bf8fc234Set  * handles.  Fire should not panic the system, it'll be up to the driver to
1809bf8fc234Set  * panic.  The address logged is invalid.
1810bf8fc234Set  *
1811bf8fc234Set  * These errors are not retryable since retrying the same transaction with the
1812bf8fc234Set  * same invalid address will result in the same error.
1813bf8fc234Set  */
1814bf8fc234Set /* ARGSUSED */
1815bf8fc234Set int
px_err_mmu_tfa_handle(dev_info_t * rpdip,caddr_t csr_base,ddi_fm_error_t * derr,px_err_reg_desc_t * err_reg_descr,px_err_bit_desc_t * err_bit_descr)1816bf8fc234Set px_err_mmu_tfa_handle(dev_info_t *rpdip, caddr_t csr_base,
1817bf8fc234Set 	ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
1818bf8fc234Set 	px_err_bit_desc_t *err_bit_descr)
1819bf8fc234Set {
1820bf8fc234Set 	pcie_req_id_t bdf;
1821e51949e6Sdduvall 
1822bf8fc234Set 	if (!PX_ERR_IS_PRI(err_bit_descr->bit))
1823bf8fc234Set 		goto done;
1824e51949e6Sdduvall 
1825bf8fc234Set 	bdf = (pcie_req_id_t)CSR_FR(csr_base, MMU_TRANSLATION_FAULT_STATUS, ID);
1826*e214b19eSToomas Soome 	(void) pf_hdl_lookup(rpdip, derr->fme_ena, PF_ADDR_DMA, 0, bdf);
1827f8d2de6bSjchu 
1828bf8fc234Set done:
1829bf8fc234Set 	return (px_err_no_panic_handle(rpdip, csr_base, derr, err_reg_descr,
18301ff65112Segillett 	    err_bit_descr));
1831f8d2de6bSjchu }
1832f8d2de6bSjchu 
1833bf8fc234Set /*
1834bf8fc234Set  * IMU function to handle normal transactions that encounter a parity error.
1835bf8fc234Set  *
1836bf8fc234Set  * These errors are due to transactions that enouter a parity error. If
1837bf8fc234Set  * possible, inform the driver that their DMA have failed and that they should
1838bf8fc234Set  * retry.  If Fire is unable to contact the leaf driver, panic the system.
1839bf8fc234Set  * Otherwise, it'll be up to the device to determine is this is a panicable
1840bf8fc234Set  * error.
1841bf8fc234Set  */
1842f8d2de6bSjchu /* ARGSUSED */
1843f8d2de6bSjchu int
px_err_mmu_parity_handle(dev_info_t * rpdip,caddr_t csr_base,ddi_fm_error_t * derr,px_err_reg_desc_t * err_reg_descr,px_err_bit_desc_t * err_bit_descr)1844bf8fc234Set px_err_mmu_parity_handle(dev_info_t *rpdip, caddr_t csr_base,
1845f8d2de6bSjchu 	ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
1846f8d2de6bSjchu 	px_err_bit_desc_t *err_bit_descr)
1847f8d2de6bSjchu {
1848bf8fc234Set 	uint64_t mmu_tfa;
1849bf8fc234Set 	pcie_req_id_t bdf;
18501ff65112Segillett 	int status = PF_HDL_NOTFOUND;
1851f8d2de6bSjchu 
1852bf8fc234Set 	if (!PX_ERR_IS_PRI(err_bit_descr->bit))
1853bf8fc234Set 		goto done;
18548c334881Sjchu 
1855f8d2de6bSjchu 	mmu_tfa = CSR_XR(csr_base, MMU_TRANSLATION_FAULT_ADDRESS);
1856bf8fc234Set 	bdf = (pcie_req_id_t)CSR_FR(csr_base, MMU_TRANSLATION_FAULT_STATUS, ID);
1857eae2e508Skrishnae 	status = pf_hdl_lookup(rpdip, derr->fme_ena, PF_ADDR_DMA,
1858bf8fc234Set 	    (uint32_t)mmu_tfa, bdf);
1859bf8fc234Set 
1860bf8fc234Set done:
18611ff65112Segillett 	if (status == PF_HDL_NOTFOUND)
1862bf8fc234Set 		return (px_err_panic_handle(rpdip, csr_base, derr,
18631ff65112Segillett 		    err_reg_descr, err_bit_descr));
1864bf8fc234Set 	else
1865bf8fc234Set 		return (px_err_no_panic_handle(rpdip, csr_base, derr,
18661ff65112Segillett 		    err_reg_descr, err_bit_descr));
1867f8d2de6bSjchu }
1868f8d2de6bSjchu 
1869bf8fc234Set /*
1870bf8fc234Set  * wuc/ruc event - Mark the handle of the failed PIO access.  Return "no_panic"
1871bf8fc234Set  */
1872f8d2de6bSjchu /* ARGSUSED */
1873f8d2de6bSjchu int
px_err_wuc_ruc_handle(dev_info_t * rpdip,caddr_t csr_base,ddi_fm_error_t * derr,px_err_reg_desc_t * err_reg_descr,px_err_bit_desc_t * err_bit_descr)1874bf8fc234Set px_err_wuc_ruc_handle(dev_info_t *rpdip, caddr_t csr_base,
1875f8d2de6bSjchu 	ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
1876f8d2de6bSjchu 	px_err_bit_desc_t *err_bit_descr)
1877f8d2de6bSjchu {
1878bf8fc234Set 	px_t		*px_p = DIP_TO_STATE(rpdip);
1879bf8fc234Set 	pxu_t		*pxu_p = (pxu_t *)px_p->px_plat_p;
1880bf8fc234Set 	uint64_t 	data;
1881eae2e508Skrishnae 	pf_pcie_adv_err_regs_t adv_reg;
1882eae2e508Skrishnae 	int		sts;
1883bf8fc234Set 
1884bf8fc234Set 	if (!PX_ERR_IS_PRI(err_bit_descr->bit))
1885bf8fc234Set 		goto done;
1886bf8fc234Set 
1887bf8fc234Set 	data = CSR_XR(csr_base, TLU_TRANSMIT_OTHER_EVENT_HEADER1_LOG);
1888eae2e508Skrishnae 	adv_reg.pcie_ue_hdr[0] = (uint32_t)(data >> 32);
1889eae2e508Skrishnae 	adv_reg.pcie_ue_hdr[1] = (uint32_t)(data & 0xFFFFFFFF);
1890bf8fc234Set 	data = CSR_XR(csr_base, TLU_TRANSMIT_OTHER_EVENT_HEADER2_LOG);
1891eae2e508Skrishnae 	adv_reg.pcie_ue_hdr[2] = (uint32_t)(data >> 32);
1892eae2e508Skrishnae 	adv_reg.pcie_ue_hdr[3] = (uint32_t)(data & 0xFFFFFFFF);
1893f8d2de6bSjchu 
189407d06da5SSurya Prakki 	(void) pf_tlp_decode(PCIE_DIP2BUS(rpdip), &adv_reg);
1895eae2e508Skrishnae 	sts = pf_hdl_lookup(rpdip, derr->fme_ena, adv_reg.pcie_ue_tgt_trans,
1896eae2e508Skrishnae 	    adv_reg.pcie_ue_tgt_addr, adv_reg.pcie_ue_tgt_bdf);
1897bf8fc234Set done:
1898bf8fc234Set 	if ((sts == PF_HDL_NOTFOUND) && (pxu_p->cpr_flag == PX_NOT_CPR))
1899bf8fc234Set 		return (px_err_protected_handle(rpdip, csr_base, derr,
19001ff65112Segillett 		    err_reg_descr, err_bit_descr));
1901e51949e6Sdduvall 
1902bf8fc234Set 	return (px_err_no_panic_handle(rpdip, csr_base, derr,
19031ff65112Segillett 	    err_reg_descr, err_bit_descr));
1904f8d2de6bSjchu }
1905f8d2de6bSjchu 
19061a887b2eSjchu /*
1907f9721e07Sjchu  * TLU LUP event - if caused by power management activity, then it is expected.
1908f9721e07Sjchu  * In all other cases, it is an error.
19091a887b2eSjchu  */
19101a887b2eSjchu /* ARGSUSED */
19111a887b2eSjchu int
px_err_tlu_lup_handle(dev_info_t * rpdip,caddr_t csr_base,ddi_fm_error_t * derr,px_err_reg_desc_t * err_reg_descr,px_err_bit_desc_t * err_bit_descr)19121a887b2eSjchu px_err_tlu_lup_handle(dev_info_t *rpdip, caddr_t csr_base,
19131a887b2eSjchu 	ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
19141a887b2eSjchu 	px_err_bit_desc_t *err_bit_descr)
19151a887b2eSjchu {
19161a887b2eSjchu 	px_t	*px_p = DIP_TO_STATE(rpdip);
19171a887b2eSjchu 
19181a887b2eSjchu 	/*
1919f9721e07Sjchu 	 * power management code is currently the only segment that sets
1920f9721e07Sjchu 	 * px_lup_pending to indicate its expectation for a healthy LUP
1921f9721e07Sjchu 	 * event.  For all other occasions, LUP event should be flaged as
1922f9721e07Sjchu 	 * error condition.
19231a887b2eSjchu 	 */
1924f9721e07Sjchu 	return ((atomic_cas_32(&px_p->px_lup_pending, 1, 0) == 0) ?
1925bf8fc234Set 	    PX_NO_PANIC : PX_EXPECTED);
1926f9721e07Sjchu }
19271a887b2eSjchu 
1928f9721e07Sjchu /*
1929f9721e07Sjchu  * TLU LDN event - if caused by power management activity, then it is expected.
1930f9721e07Sjchu  * In all other cases, it is an error.
1931f9721e07Sjchu  */
1932f9721e07Sjchu /* ARGSUSED */
1933f9721e07Sjchu int
px_err_tlu_ldn_handle(dev_info_t * rpdip,caddr_t csr_base,ddi_fm_error_t * derr,px_err_reg_desc_t * err_reg_descr,px_err_bit_desc_t * err_bit_descr)1934f9721e07Sjchu px_err_tlu_ldn_handle(dev_info_t *rpdip, caddr_t csr_base,
1935f9721e07Sjchu 	ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
1936f9721e07Sjchu 	px_err_bit_desc_t *err_bit_descr)
1937f9721e07Sjchu {
1938f9721e07Sjchu 	px_t    *px_p = DIP_TO_STATE(rpdip);
1939bf8fc234Set 	return ((px_p->px_pm_flags & PX_LDN_EXPECTED) ? PX_EXPECTED :
1940bf8fc234Set 	    PX_NO_PANIC);
19411a887b2eSjchu }
19421a887b2eSjchu 
1943f8d2de6bSjchu /* PEC ILU none - see io erpt doc, section 3.1 */
PX_ERPT_SEND_DEC(pec_ilu)1944f8d2de6bSjchu PX_ERPT_SEND_DEC(pec_ilu)
1945f8d2de6bSjchu {
1946f8d2de6bSjchu 	char		buf[FM_MAX_CLASS];
19478c334881Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(bit);
1948f8d2de6bSjchu 
1949f8d2de6bSjchu 	(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
1950f8d2de6bSjchu 	ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
1951f8d2de6bSjchu 	    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
19528c334881Sjchu 	    FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
1953f8d2de6bSjchu 	    FIRE_ILU_ELE, DATA_TYPE_UINT64,
1954f8d2de6bSjchu 	    CSR_XR(csr_base, ILU_ERROR_LOG_ENABLE),
1955f8d2de6bSjchu 	    FIRE_ILU_IE, DATA_TYPE_UINT64,
1956f8d2de6bSjchu 	    CSR_XR(csr_base, ILU_INTERRUPT_ENABLE),
1957f8d2de6bSjchu 	    FIRE_ILU_IS, DATA_TYPE_UINT64,
1958f8d2de6bSjchu 	    ss_reg,
1959f8d2de6bSjchu 	    FIRE_ILU_ESS, DATA_TYPE_UINT64,
1960f8d2de6bSjchu 	    CSR_XR(csr_base, ILU_ERROR_STATUS_SET),
1961f8d2de6bSjchu 	    NULL);
1962f8d2de6bSjchu 
1963bf8fc234Set 	return (PX_NO_PANIC);
1964f8d2de6bSjchu }
1965f8d2de6bSjchu 
19668bc7d88aSet /* PCIEX UE Errors */
19678bc7d88aSet /* ARGSUSED */
1968b40cec45Skrishnae int
px_err_pciex_ue_handle(dev_info_t * rpdip,caddr_t csr_base,ddi_fm_error_t * derr,px_err_reg_desc_t * err_reg_descr,px_err_bit_desc_t * err_bit_descr)19698bc7d88aSet px_err_pciex_ue_handle(dev_info_t *rpdip, caddr_t csr_base,
19708bc7d88aSet 	ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
19718bc7d88aSet 	px_err_bit_desc_t *err_bit_descr)
19728bc7d88aSet {
1973bf8fc234Set 	px_err_pcie_t	regs = {0};
1974bf8fc234Set 	uint32_t	err_bit;
1975bf8fc234Set 	int		err;
1976bf8fc234Set 	uint64_t	log;
1977bf8fc234Set 
1978bf8fc234Set 	if (err_bit_descr->bit < 32) {
1979bf8fc234Set 		err_bit = (uint32_t)BITMASK(err_bit_descr->bit);
1980bf8fc234Set 		regs.ue_reg = err_bit;
1981bf8fc234Set 		regs.primary_ue = err_bit;
1982bf8fc234Set 
1983bf8fc234Set 		/*
1984eae2e508Skrishnae 		 * Log the Received Log for PTLP, UR and UC.
1985bf8fc234Set 		 */
1986eae2e508Skrishnae 		if ((PCIE_AER_UCE_PTLP | PCIE_AER_UCE_UR | PCIE_AER_UCE_UC) &
1987eae2e508Skrishnae 		    err_bit) {
1988bf8fc234Set 			log = CSR_XR(csr_base,
1989bf8fc234Set 			    TLU_RECEIVE_UNCORRECTABLE_ERROR_HEADER1_LOG);
1990bf8fc234Set 			regs.rx_hdr1 = (uint32_t)(log >> 32);
1991eae2e508Skrishnae 			regs.rx_hdr2 = (uint32_t)(log & 0xFFFFFFFF);
1992bf8fc234Set 
1993bf8fc234Set 			log = CSR_XR(csr_base,
1994bf8fc234Set 			    TLU_RECEIVE_UNCORRECTABLE_ERROR_HEADER2_LOG);
1995bf8fc234Set 			regs.rx_hdr3 = (uint32_t)(log >> 32);
1996eae2e508Skrishnae 			regs.rx_hdr4 = (uint32_t)(log & 0xFFFFFFFF);
1997bf8fc234Set 		}
1998bf8fc234Set 	} else {
1999bf8fc234Set 		regs.ue_reg = (uint32_t)BITMASK(err_bit_descr->bit - 32);
2000bf8fc234Set 	}
20018bc7d88aSet 
20025613d828SKrishna Elango 	err = px_err_check_pcie(rpdip, derr, &regs, PF_INTR_TYPE_INTERNAL);
2003bf8fc234Set 
2004455c9860Skrishnae 	if (err & PX_PANIC) {
2005bf8fc234Set 		return (px_err_panic_handle(rpdip, csr_base, derr,
20061ff65112Segillett 		    err_reg_descr, err_bit_descr));
2007bf8fc234Set 	} else {
2008bf8fc234Set 		return (px_err_no_panic_handle(rpdip, csr_base, derr,
20091ff65112Segillett 		    err_reg_descr, err_bit_descr));
2010bf8fc234Set 	}
20118bc7d88aSet }
20128bc7d88aSet 
2013bf8fc234Set /* PCI-E Uncorrectable Errors */
PX_ERPT_SEND_DEC(pciex_rx_ue)20148bc7d88aSet PX_ERPT_SEND_DEC(pciex_rx_ue)
20158bc7d88aSet {
20168bc7d88aSet 	char		buf[FM_MAX_CLASS];
20178c334881Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(bit);
20188bc7d88aSet 
20198bc7d88aSet 	(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
20208bc7d88aSet 	ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
20218bc7d88aSet 	    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
20228c334881Sjchu 	    FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
20238bc7d88aSet 	    FIRE_TLU_UELE, DATA_TYPE_UINT64,
20248bc7d88aSet 	    CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_LOG_ENABLE),
20258bc7d88aSet 	    FIRE_TLU_UIE, DATA_TYPE_UINT64,
20268bc7d88aSet 	    CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_INTERRUPT_ENABLE),
20278bc7d88aSet 	    FIRE_TLU_UIS, DATA_TYPE_UINT64,
20288bc7d88aSet 	    ss_reg,
20298bc7d88aSet 	    FIRE_TLU_UESS, DATA_TYPE_UINT64,
20308bc7d88aSet 	    CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_STATUS_SET),
20318bc7d88aSet 	    FIRE_TLU_RUEH1L, DATA_TYPE_UINT64,
20328bc7d88aSet 	    CSR_XR(csr_base, TLU_RECEIVE_UNCORRECTABLE_ERROR_HEADER1_LOG),
20338bc7d88aSet 	    FIRE_TLU_RUEH2L, DATA_TYPE_UINT64,
20348bc7d88aSet 	    CSR_XR(csr_base, TLU_RECEIVE_UNCORRECTABLE_ERROR_HEADER2_LOG),
20358bc7d88aSet 	    NULL);
20368bc7d88aSet 
2037bf8fc234Set 	return (PX_NO_PANIC);
20388bc7d88aSet }
20398bc7d88aSet 
2040bf8fc234Set /* PCI-E Uncorrectable Errors */
PX_ERPT_SEND_DEC(pciex_tx_ue)20418bc7d88aSet PX_ERPT_SEND_DEC(pciex_tx_ue)
20428bc7d88aSet {
20438bc7d88aSet 	char		buf[FM_MAX_CLASS];
20448c334881Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(bit);
20458bc7d88aSet 
20468bc7d88aSet 	(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
20478bc7d88aSet 	ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
20488bc7d88aSet 	    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
20498c334881Sjchu 	    FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
20508bc7d88aSet 	    FIRE_TLU_UELE, DATA_TYPE_UINT64,
20518bc7d88aSet 	    CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_LOG_ENABLE),
20528bc7d88aSet 	    FIRE_TLU_UIE, DATA_TYPE_UINT64,
20538bc7d88aSet 	    CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_INTERRUPT_ENABLE),
20548bc7d88aSet 	    FIRE_TLU_UIS, DATA_TYPE_UINT64,
20558bc7d88aSet 	    ss_reg,
20568bc7d88aSet 	    FIRE_TLU_UESS, DATA_TYPE_UINT64,
20578bc7d88aSet 	    CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_STATUS_SET),
20588bc7d88aSet 	    FIRE_TLU_TUEH1L, DATA_TYPE_UINT64,
20598bc7d88aSet 	    CSR_XR(csr_base, TLU_TRANSMIT_UNCORRECTABLE_ERROR_HEADER1_LOG),
20608bc7d88aSet 	    FIRE_TLU_TUEH2L, DATA_TYPE_UINT64,
20618bc7d88aSet 	    CSR_XR(csr_base, TLU_TRANSMIT_UNCORRECTABLE_ERROR_HEADER2_LOG),
20628bc7d88aSet 	    NULL);
20638bc7d88aSet 
2064bf8fc234Set 	return (PX_NO_PANIC);
20658bc7d88aSet }
20668bc7d88aSet 
2067bf8fc234Set /* PCI-E Uncorrectable Errors */
PX_ERPT_SEND_DEC(pciex_rx_tx_ue)20688bc7d88aSet PX_ERPT_SEND_DEC(pciex_rx_tx_ue)
20698bc7d88aSet {
20708bc7d88aSet 	char		buf[FM_MAX_CLASS];
20718c334881Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(bit);
20728bc7d88aSet 
20738bc7d88aSet 	(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
20748bc7d88aSet 	ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
20758bc7d88aSet 	    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
20768c334881Sjchu 	    FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
20778bc7d88aSet 	    FIRE_TLU_UELE, DATA_TYPE_UINT64,
20788bc7d88aSet 	    CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_LOG_ENABLE),
20798bc7d88aSet 	    FIRE_TLU_UIE, DATA_TYPE_UINT64,
20808bc7d88aSet 	    CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_INTERRUPT_ENABLE),
20818bc7d88aSet 	    FIRE_TLU_UIS, DATA_TYPE_UINT64,
20828bc7d88aSet 	    ss_reg,
20838bc7d88aSet 	    FIRE_TLU_UESS, DATA_TYPE_UINT64,
20848bc7d88aSet 	    CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_STATUS_SET),
20858bc7d88aSet 	    FIRE_TLU_RUEH1L, DATA_TYPE_UINT64,
20868bc7d88aSet 	    CSR_XR(csr_base, TLU_RECEIVE_UNCORRECTABLE_ERROR_HEADER1_LOG),
20878bc7d88aSet 	    FIRE_TLU_RUEH2L, DATA_TYPE_UINT64,
20888bc7d88aSet 	    CSR_XR(csr_base, TLU_RECEIVE_UNCORRECTABLE_ERROR_HEADER2_LOG),
20898bc7d88aSet 	    FIRE_TLU_TUEH1L, DATA_TYPE_UINT64,
20908bc7d88aSet 	    CSR_XR(csr_base, TLU_TRANSMIT_UNCORRECTABLE_ERROR_HEADER1_LOG),
20918bc7d88aSet 	    FIRE_TLU_TUEH2L, DATA_TYPE_UINT64,
20928bc7d88aSet 	    CSR_XR(csr_base, TLU_TRANSMIT_UNCORRECTABLE_ERROR_HEADER2_LOG),
20938bc7d88aSet 	    NULL);
20948bc7d88aSet 
2095bf8fc234Set 	return (PX_NO_PANIC);
20968bc7d88aSet }
20978bc7d88aSet 
2098bf8fc234Set /* PCI-E Uncorrectable Errors */
PX_ERPT_SEND_DEC(pciex_ue)20998bc7d88aSet PX_ERPT_SEND_DEC(pciex_ue)
21008bc7d88aSet {
21018bc7d88aSet 	char		buf[FM_MAX_CLASS];
21028c334881Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(bit);
21038bc7d88aSet 
21048bc7d88aSet 	(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
21058bc7d88aSet 	ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
21068bc7d88aSet 	    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
21078c334881Sjchu 	    FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
21088bc7d88aSet 	    FIRE_TLU_UELE, DATA_TYPE_UINT64,
21098bc7d88aSet 	    CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_LOG_ENABLE),
21108bc7d88aSet 	    FIRE_TLU_UIE, DATA_TYPE_UINT64,
21118bc7d88aSet 	    CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_INTERRUPT_ENABLE),
21128bc7d88aSet 	    FIRE_TLU_UIS, DATA_TYPE_UINT64,
21138bc7d88aSet 	    ss_reg,
21148bc7d88aSet 	    FIRE_TLU_UESS, DATA_TYPE_UINT64,
21158bc7d88aSet 	    CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_STATUS_SET),
21168bc7d88aSet 	    NULL);
21178bc7d88aSet 
2118bf8fc234Set 	return (PX_NO_PANIC);
21198bc7d88aSet }
21208bc7d88aSet 
21218bc7d88aSet /* PCIEX UE Errors */
21228bc7d88aSet /* ARGSUSED */
2123b40cec45Skrishnae int
px_err_pciex_ce_handle(dev_info_t * rpdip,caddr_t csr_base,ddi_fm_error_t * derr,px_err_reg_desc_t * err_reg_descr,px_err_bit_desc_t * err_bit_descr)21248bc7d88aSet px_err_pciex_ce_handle(dev_info_t *rpdip, caddr_t csr_base,
21258bc7d88aSet 	ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
21268bc7d88aSet 	px_err_bit_desc_t *err_bit_descr)
21278bc7d88aSet {
2128bf8fc234Set 	px_err_pcie_t	regs = {0};
2129bf8fc234Set 	int		err;
2130bf8fc234Set 
2131bf8fc234Set 	if (err_bit_descr->bit < 32)
2132bf8fc234Set 		regs.ce_reg = (uint32_t)BITMASK(err_bit_descr->bit);
2133bf8fc234Set 	else
2134bf8fc234Set 		regs.ce_reg = (uint32_t)BITMASK(err_bit_descr->bit - 32);
2135bf8fc234Set 
21365613d828SKrishna Elango 	err = px_err_check_pcie(rpdip, derr, &regs, PF_INTR_TYPE_INTERNAL);
21378bc7d88aSet 
2138455c9860Skrishnae 	if (err & PX_PANIC) {
2139bf8fc234Set 		return (px_err_panic_handle(rpdip, csr_base, derr,
21401ff65112Segillett 		    err_reg_descr, err_bit_descr));
2141bf8fc234Set 	} else {
2142bf8fc234Set 		return (px_err_no_panic_handle(rpdip, csr_base, derr,
21431ff65112Segillett 		    err_reg_descr, err_bit_descr));
2144bf8fc234Set 	}
21458bc7d88aSet }
21468bc7d88aSet 
2147f8d2de6bSjchu /* PCI-E Correctable Errors - see io erpt doc, section 3.6 */
PX_ERPT_SEND_DEC(pciex_ce)2148f8d2de6bSjchu PX_ERPT_SEND_DEC(pciex_ce)
2149f8d2de6bSjchu {
2150f8d2de6bSjchu 	char		buf[FM_MAX_CLASS];
21518c334881Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(bit);
2152f8d2de6bSjchu 
2153f8d2de6bSjchu 	(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
2154f8d2de6bSjchu 	ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
2155f8d2de6bSjchu 	    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
21568c334881Sjchu 	    FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
2157f8d2de6bSjchu 	    FIRE_TLU_CELE, DATA_TYPE_UINT64,
2158f8d2de6bSjchu 	    CSR_XR(csr_base, TLU_CORRECTABLE_ERROR_LOG_ENABLE),
2159f8d2de6bSjchu 	    FIRE_TLU_CIE, DATA_TYPE_UINT64,
2160f8d2de6bSjchu 	    CSR_XR(csr_base, TLU_CORRECTABLE_ERROR_INTERRUPT_ENABLE),
2161f8d2de6bSjchu 	    FIRE_TLU_CIS, DATA_TYPE_UINT64,
2162f8d2de6bSjchu 	    ss_reg,
2163f8d2de6bSjchu 	    FIRE_TLU_CESS, DATA_TYPE_UINT64,
2164f8d2de6bSjchu 	    CSR_XR(csr_base, TLU_CORRECTABLE_ERROR_STATUS_SET),
2165f8d2de6bSjchu 	    NULL);
2166f8d2de6bSjchu 
2167bf8fc234Set 	return (PX_NO_PANIC);
2168f8d2de6bSjchu }
2169f8d2de6bSjchu 
2170f8d2de6bSjchu /* TLU Other Event Status (receive only) - see io erpt doc, section 3.7 */
PX_ERPT_SEND_DEC(pciex_rx_oe)2171f8d2de6bSjchu PX_ERPT_SEND_DEC(pciex_rx_oe)
2172f8d2de6bSjchu {
2173f8d2de6bSjchu 	char		buf[FM_MAX_CLASS];
21748c334881Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(bit);
2175f8d2de6bSjchu 
2176f8d2de6bSjchu 	(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
2177f8d2de6bSjchu 	ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
2178f8d2de6bSjchu 	    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
21798c334881Sjchu 	    FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
2180f8d2de6bSjchu 	    FIRE_TLU_OEELE, DATA_TYPE_UINT64,
2181f8d2de6bSjchu 	    CSR_XR(csr_base, TLU_OTHER_EVENT_LOG_ENABLE),
2182f8d2de6bSjchu 	    FIRE_TLU_OEIE, DATA_TYPE_UINT64,
2183f8d2de6bSjchu 	    CSR_XR(csr_base, TLU_OTHER_EVENT_INTERRUPT_ENABLE),
2184f8d2de6bSjchu 	    FIRE_TLU_OEIS, DATA_TYPE_UINT64,
2185f8d2de6bSjchu 	    ss_reg,
2186f8d2de6bSjchu 	    FIRE_TLU_OEESS, DATA_TYPE_UINT64,
2187f8d2de6bSjchu 	    CSR_XR(csr_base, TLU_OTHER_EVENT_STATUS_SET),
2188f8d2de6bSjchu 	    FIRE_TLU_RUEH1L, DATA_TYPE_UINT64,
2189f8d2de6bSjchu 	    CSR_XR(csr_base, TLU_RECEIVE_OTHER_EVENT_HEADER1_LOG),
21903677cad4Set 	    FIRE_TLU_RUEH2L, DATA_TYPE_UINT64,
2191f8d2de6bSjchu 	    CSR_XR(csr_base, TLU_RECEIVE_OTHER_EVENT_HEADER2_LOG),
2192f8d2de6bSjchu 	    NULL);
2193f8d2de6bSjchu 
2194bf8fc234Set 	return (PX_NO_PANIC);
2195f8d2de6bSjchu }
2196f8d2de6bSjchu 
2197f8d2de6bSjchu /* TLU Other Event Status (rx + tx) - see io erpt doc, section 3.8 */
PX_ERPT_SEND_DEC(pciex_rx_tx_oe)2198f8d2de6bSjchu PX_ERPT_SEND_DEC(pciex_rx_tx_oe)
2199f8d2de6bSjchu {
2200f8d2de6bSjchu 	char		buf[FM_MAX_CLASS];
22018c334881Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(bit);
2202bf8fc234Set 	px_t		*px_p = DIP_TO_STATE(rpdip);
2203bf8fc234Set 	uint64_t	rx_h1, rx_h2, tx_h1, tx_h2;
2204bf8fc234Set 	uint16_t	s_status;
2205bf8fc234Set 	int		sts;
2206bf8fc234Set 	pcie_cpl_t	*cpl;
2207eae2e508Skrishnae 	pf_pcie_adv_err_regs_t adv_reg;
2208bf8fc234Set 
2209bf8fc234Set 	rx_h1 = CSR_XR(csr_base, TLU_RECEIVE_OTHER_EVENT_HEADER1_LOG);
2210bf8fc234Set 	rx_h2 = CSR_XR(csr_base, TLU_RECEIVE_OTHER_EVENT_HEADER2_LOG);
2211bf8fc234Set 	tx_h1 = CSR_XR(csr_base, TLU_TRANSMIT_OTHER_EVENT_HEADER1_LOG);
2212bf8fc234Set 	tx_h2 = CSR_XR(csr_base, TLU_TRANSMIT_OTHER_EVENT_HEADER2_LOG);
2213bf8fc234Set 
2214bf8fc234Set 	if ((bit == TLU_OTHER_EVENT_STATUS_SET_RUC_P) ||
2215bf8fc234Set 	    (bit == TLU_OTHER_EVENT_STATUS_SET_WUC_P)) {
2216eae2e508Skrishnae 		adv_reg.pcie_ue_hdr[0] = (uint32_t)(rx_h1 >> 32);
2217eae2e508Skrishnae 		adv_reg.pcie_ue_hdr[1] = (uint32_t)rx_h1;
2218eae2e508Skrishnae 		adv_reg.pcie_ue_hdr[2] = (uint32_t)(rx_h2 >> 32);
2219eae2e508Skrishnae 		adv_reg.pcie_ue_hdr[3] = (uint32_t)rx_h2;
2220bf8fc234Set 
2221bf8fc234Set 		/* get completer bdf (fault bdf) from rx logs */
2222eae2e508Skrishnae 		cpl = (pcie_cpl_t *)&adv_reg.pcie_ue_hdr[1];
2223bf8fc234Set 
2224bf8fc234Set 		/* Figure out if UR/CA from rx logs */
2225bf8fc234Set 		if (cpl->status == PCIE_CPL_STS_UR)
2226bf8fc234Set 			s_status = PCI_STAT_R_MAST_AB;
2227bf8fc234Set 		else if (cpl->status == PCIE_CPL_STS_CA)
2228bf8fc234Set 			s_status = PCI_STAT_R_TARG_AB;
2229bf8fc234Set 
2230eae2e508Skrishnae 		adv_reg.pcie_ue_hdr[0] = (uint32_t)(tx_h1 >> 32);
2231eae2e508Skrishnae 		adv_reg.pcie_ue_hdr[1] = (uint32_t)tx_h1;
2232eae2e508Skrishnae 		adv_reg.pcie_ue_hdr[2] = (uint32_t)(tx_h2 >> 32);
2233eae2e508Skrishnae 		adv_reg.pcie_ue_hdr[3] = (uint32_t)tx_h2;
2234bf8fc234Set 
2235bf8fc234Set 		/* get fault addr from tx logs */
2236eae2e508Skrishnae 		sts = pf_tlp_decode(PCIE_DIP2BUS(rpdip), &adv_reg);
2237bf8fc234Set 
2238bf8fc234Set 		if (sts == DDI_SUCCESS)
2239eae2e508Skrishnae 			(void) px_rp_en_q(px_p, adv_reg.pcie_ue_tgt_bdf,
2240eae2e508Skrishnae 			    adv_reg.pcie_ue_tgt_addr, s_status);
2241bf8fc234Set 	}
2242f8d2de6bSjchu 
2243f8d2de6bSjchu 	(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
2244f8d2de6bSjchu 	ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
2245f8d2de6bSjchu 	    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
22468c334881Sjchu 	    FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
2247f8d2de6bSjchu 	    FIRE_TLU_OEELE, DATA_TYPE_UINT64,
2248f8d2de6bSjchu 	    CSR_XR(csr_base, TLU_OTHER_EVENT_LOG_ENABLE),
2249f8d2de6bSjchu 	    FIRE_TLU_OEIE, DATA_TYPE_UINT64,
2250f8d2de6bSjchu 	    CSR_XR(csr_base, TLU_OTHER_EVENT_INTERRUPT_ENABLE),
2251f8d2de6bSjchu 	    FIRE_TLU_OEIS, DATA_TYPE_UINT64,
2252f8d2de6bSjchu 	    ss_reg,
2253f8d2de6bSjchu 	    FIRE_TLU_OEESS, DATA_TYPE_UINT64,
2254f8d2de6bSjchu 	    CSR_XR(csr_base, TLU_OTHER_EVENT_STATUS_SET),
2255bf8fc234Set 	    FIRE_TLU_ROEEH1L, DATA_TYPE_UINT64, rx_h1,
2256bf8fc234Set 	    FIRE_TLU_ROEEH2L, DATA_TYPE_UINT64, rx_h2,
2257bf8fc234Set 	    FIRE_TLU_TOEEH1L, DATA_TYPE_UINT64, tx_h1,
2258bf8fc234Set 	    FIRE_TLU_TOEEH2L, DATA_TYPE_UINT64, tx_h2,
2259f8d2de6bSjchu 	    NULL);
2260f8d2de6bSjchu 
2261bf8fc234Set 	return (PX_NO_PANIC);
2262f8d2de6bSjchu }
2263f8d2de6bSjchu 
2264f8d2de6bSjchu /* TLU Other Event - see io erpt doc, section 3.9 */
PX_ERPT_SEND_DEC(pciex_oe)2265f8d2de6bSjchu PX_ERPT_SEND_DEC(pciex_oe)
2266f8d2de6bSjchu {
22678c334881Sjchu 	char		buf[FM_MAX_CLASS];
22688c334881Sjchu 	boolean_t	pri = PX_ERR_IS_PRI(bit);
2269f8d2de6bSjchu 
2270f8d2de6bSjchu 	(void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
2271f8d2de6bSjchu 	ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
2272f8d2de6bSjchu 	    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
22738c334881Sjchu 	    FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
2274f8d2de6bSjchu 	    FIRE_TLU_OEELE, DATA_TYPE_UINT64,
2275f8d2de6bSjchu 	    CSR_XR(csr_base, TLU_OTHER_EVENT_LOG_ENABLE),
2276f8d2de6bSjchu 	    FIRE_TLU_OEIE, DATA_TYPE_UINT64,
2277f8d2de6bSjchu 	    CSR_XR(csr_base, TLU_OTHER_EVENT_INTERRUPT_ENABLE),
2278f8d2de6bSjchu 	    FIRE_TLU_OEIS, DATA_TYPE_UINT64,
2279f8d2de6bSjchu 	    ss_reg,
2280f8d2de6bSjchu 	    FIRE_TLU_OEESS, DATA_TYPE_UINT64,
2281f8d2de6bSjchu 	    CSR_XR(csr_base, TLU_OTHER_EVENT_STATUS_SET),
2282f8d2de6bSjchu 	    NULL);
2283f8d2de6bSjchu 
2284bf8fc234Set 	return (PX_NO_PANIC);
2285f8d2de6bSjchu }
2286