127Sjchu /*
227Sjchu * CDDL HEADER START
327Sjchu *
427Sjchu * The contents of this file are subject to the terms of the
51648Sjchu * Common Development and Distribution License (the "License").
61648Sjchu * You may not use this file except in compliance with the License.
727Sjchu *
827Sjchu * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
927Sjchu * or http://www.opensolaris.org/os/licensing.
1027Sjchu * See the License for the specific language governing permissions
1127Sjchu * and limitations under the License.
1227Sjchu *
1327Sjchu * When distributing Covered Code, include this CDDL HEADER in each
1427Sjchu * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1527Sjchu * If applicable, add the following below this CDDL HEADER, with the
1627Sjchu * fields enclosed by brackets "[]" replaced with your own identifying
1727Sjchu * information: Portions Copyright [yyyy] [name of copyright owner]
1827Sjchu *
1927Sjchu * CDDL HEADER END
2027Sjchu */
2111311SSurya.Prakki@Sun.COM
2227Sjchu /*
23*11654SKrishna.Elango@Sun.COM * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
2427Sjchu * Use is subject to license terms.
2527Sjchu */
2627Sjchu
2727Sjchu /*
2827Sjchu * sun4u Fire Error Handling
2927Sjchu */
3027Sjchu
3127Sjchu #include <sys/types.h>
3227Sjchu #include <sys/ddi.h>
3327Sjchu #include <sys/sunddi.h>
346313Skrishnae #include <sys/sunndi.h>
3527Sjchu #include <sys/fm/protocol.h>
3627Sjchu #include <sys/fm/util.h>
3727Sjchu #include <sys/pcie.h>
3827Sjchu #include <sys/pcie_impl.h>
3927Sjchu #include "px_obj.h"
4027Sjchu #include <px_regs.h>
4127Sjchu #include <px_csr.h>
4227Sjchu #include <sys/membar.h>
431772Sjl139090 #include <sys/machcpuvar.h>
441772Sjl139090 #include <sys/platform_module.h>
4527Sjchu #include "px_lib4u.h"
4627Sjchu #include "px_err.h"
4727Sjchu #include "px_err_impl.h"
481772Sjl139090 #include "oberon_regs.h"
491772Sjl139090
501772Sjl139090 uint64_t px_tlu_ue_intr_mask = PX_ERR_EN_ALL;
511772Sjl139090 uint64_t px_tlu_ue_log_mask = PX_ERR_EN_ALL;
521772Sjl139090 uint64_t px_tlu_ue_count_mask = PX_ERR_EN_ALL;
531772Sjl139090
541772Sjl139090 uint64_t px_tlu_ce_intr_mask = PX_ERR_MASK_NONE;
551772Sjl139090 uint64_t px_tlu_ce_log_mask = PX_ERR_MASK_NONE;
561772Sjl139090 uint64_t px_tlu_ce_count_mask = PX_ERR_MASK_NONE;
571772Sjl139090
581772Sjl139090 /*
591772Sjl139090 * Do not enable Link Interrupts
601772Sjl139090 */
611772Sjl139090 uint64_t px_tlu_oe_intr_mask = PX_ERR_EN_ALL & ~0x80000000800;
621772Sjl139090 uint64_t px_tlu_oe_log_mask = PX_ERR_EN_ALL & ~0x80000000800;
631772Sjl139090 uint64_t px_tlu_oe_count_mask = PX_ERR_EN_ALL;
641772Sjl139090
651772Sjl139090 uint64_t px_mmu_intr_mask = PX_ERR_EN_ALL;
661772Sjl139090 uint64_t px_mmu_log_mask = PX_ERR_EN_ALL;
671772Sjl139090 uint64_t px_mmu_count_mask = PX_ERR_EN_ALL;
681772Sjl139090
691772Sjl139090 uint64_t px_imu_intr_mask = PX_ERR_EN_ALL;
701772Sjl139090 uint64_t px_imu_log_mask = PX_ERR_EN_ALL;
711772Sjl139090 uint64_t px_imu_count_mask = PX_ERR_EN_ALL;
721772Sjl139090
731772Sjl139090 /*
741772Sjl139090 * (1ull << ILU_INTERRUPT_ENABLE_IHB_PE_S) |
751772Sjl139090 * (1ull << ILU_INTERRUPT_ENABLE_IHB_PE_P);
761772Sjl139090 */
771772Sjl139090 uint64_t px_ilu_intr_mask = (((uint64_t)0x10 << 32) | 0x10);
781772Sjl139090 uint64_t px_ilu_log_mask = (((uint64_t)0x10 << 32) | 0x10);
791772Sjl139090 uint64_t px_ilu_count_mask = PX_ERR_EN_ALL;
801772Sjl139090
811772Sjl139090 uint64_t px_ubc_intr_mask = PX_ERR_EN_ALL;
821772Sjl139090 uint64_t px_ubc_log_mask = PX_ERR_EN_ALL;
831772Sjl139090 uint64_t px_ubc_count_mask = PX_ERR_EN_ALL;
841772Sjl139090
851772Sjl139090 uint64_t px_jbc_intr_mask = PX_ERR_EN_ALL;
861772Sjl139090 uint64_t px_jbc_log_mask = PX_ERR_EN_ALL;
871772Sjl139090 uint64_t px_jbc_count_mask = PX_ERR_EN_ALL;
881772Sjl139090
891772Sjl139090 /*
901772Sjl139090 * LPU Intr Registers are reverse encoding from the registers above.
911772Sjl139090 * 1 = disable
921772Sjl139090 * 0 = enable
931772Sjl139090 *
941772Sjl139090 * Log and Count are however still the same.
951772Sjl139090 */
961772Sjl139090 uint64_t px_lpul_intr_mask = LPU_INTR_DISABLE;
971772Sjl139090 uint64_t px_lpul_log_mask = PX_ERR_EN_ALL;
981772Sjl139090 uint64_t px_lpul_count_mask = PX_ERR_EN_ALL;
991772Sjl139090
1001772Sjl139090 uint64_t px_lpup_intr_mask = LPU_INTR_DISABLE;
1011772Sjl139090 uint64_t px_lpup_log_mask = PX_ERR_EN_ALL;
1021772Sjl139090 uint64_t px_lpup_count_mask = PX_ERR_EN_ALL;
1031772Sjl139090
1041772Sjl139090 uint64_t px_lpur_intr_mask = LPU_INTR_DISABLE;
1051772Sjl139090 uint64_t px_lpur_log_mask = PX_ERR_EN_ALL;
1061772Sjl139090 uint64_t px_lpur_count_mask = PX_ERR_EN_ALL;
1071772Sjl139090
1081772Sjl139090 uint64_t px_lpux_intr_mask = LPU_INTR_DISABLE;
1091772Sjl139090 uint64_t px_lpux_log_mask = PX_ERR_EN_ALL;
1101772Sjl139090 uint64_t px_lpux_count_mask = PX_ERR_EN_ALL;
1111772Sjl139090
1121772Sjl139090 uint64_t px_lpus_intr_mask = LPU_INTR_DISABLE;
1131772Sjl139090 uint64_t px_lpus_log_mask = PX_ERR_EN_ALL;
1141772Sjl139090 uint64_t px_lpus_count_mask = PX_ERR_EN_ALL;
1151772Sjl139090
1161772Sjl139090 uint64_t px_lpug_intr_mask = LPU_INTR_DISABLE;
1171772Sjl139090 uint64_t px_lpug_log_mask = PX_ERR_EN_ALL;
1181772Sjl139090 uint64_t px_lpug_count_mask = PX_ERR_EN_ALL;
11927Sjchu
12027Sjchu /*
12127Sjchu * JBC error bit table
12227Sjchu */
12327Sjchu #define JBC_BIT_DESC(bit, hdl, erpt) \
12427Sjchu JBC_INTERRUPT_STATUS_ ## bit ## _P, \
12527Sjchu 0, \
12627Sjchu PX_ERR_BIT_HANDLE(hdl), \
12727Sjchu PX_ERPT_SEND(erpt), \
128739Sjchu PX_ERR_JBC_CLASS(bit) }, \
129739Sjchu { JBC_INTERRUPT_STATUS_ ## bit ## _S, \
130739Sjchu 0, \
131739Sjchu PX_ERR_BIT_HANDLE(hdl), \
132739Sjchu PX_ERPT_SEND(erpt), \
13327Sjchu PX_ERR_JBC_CLASS(bit)
1341772Sjl139090 px_err_bit_desc_t px_err_jbc_tbl[] = {
1353274Set142600 /* JBC FATAL */
1363274Set142600 { JBC_BIT_DESC(MB_PEA, hw_reset, jbc_fatal) },
1373274Set142600 { JBC_BIT_DESC(CPE, hw_reset, jbc_fatal) },
1383274Set142600 { JBC_BIT_DESC(APE, hw_reset, jbc_fatal) },
1393274Set142600 { JBC_BIT_DESC(PIO_CPE, hw_reset, jbc_fatal) },
1403274Set142600 { JBC_BIT_DESC(JTCEEW, hw_reset, jbc_fatal) },
1413274Set142600 { JBC_BIT_DESC(JTCEEI, hw_reset, jbc_fatal) },
1423274Set142600 { JBC_BIT_DESC(JTCEER, hw_reset, jbc_fatal) },
14327Sjchu
1443274Set142600 /* JBC MERGE */
14527Sjchu { JBC_BIT_DESC(MB_PER, jbc_merge, jbc_merge) },
14627Sjchu { JBC_BIT_DESC(MB_PEW, jbc_merge, jbc_merge) },
14727Sjchu
1483274Set142600 /* JBC Jbusint IN */
1493274Set142600 { JBC_BIT_DESC(UE_ASYN, panic, jbc_in) },
1503274Set142600 { JBC_BIT_DESC(CE_ASYN, no_error, jbc_in) },
1513274Set142600 { JBC_BIT_DESC(JTE, panic, jbc_in) },
1523274Set142600 { JBC_BIT_DESC(JBE, panic, jbc_in) },
1533274Set142600 { JBC_BIT_DESC(JUE, panic, jbc_in) },
1543274Set142600 { JBC_BIT_DESC(ICISE, panic, jbc_in) },
15527Sjchu { JBC_BIT_DESC(WR_DPE, jbc_jbusint_in, jbc_in) },
15627Sjchu { JBC_BIT_DESC(RD_DPE, jbc_jbusint_in, jbc_in) },
1573274Set142600 { JBC_BIT_DESC(ILL_BMW, panic, jbc_in) },
1583274Set142600 { JBC_BIT_DESC(ILL_BMR, panic, jbc_in) },
1593274Set142600 { JBC_BIT_DESC(BJC, panic, jbc_in) },
16027Sjchu
1613274Set142600 /* JBC Jbusint Out */
1623274Set142600 { JBC_BIT_DESC(IJP, panic, jbc_out) },
16327Sjchu
1642276Sschwartz /*
1653274Set142600 * JBC Dmcint ODCD
1662276Sschwartz *
1672276Sschwartz * Error bits which can be set via a bad PCItool access go through
1682276Sschwartz * jbc_safe_acc instead.
1692276Sschwartz */
1702276Sschwartz { JBC_BIT_DESC(PIO_UNMAP_RD, jbc_safe_acc, jbc_odcd) },
1712276Sschwartz { JBC_BIT_DESC(ILL_ACC_RD, jbc_safe_acc, jbc_odcd) },
1722276Sschwartz { JBC_BIT_DESC(PIO_UNMAP, jbc_safe_acc, jbc_odcd) },
17327Sjchu { JBC_BIT_DESC(PIO_DPE, jbc_dmcint_odcd, jbc_odcd) },
1743274Set142600 { JBC_BIT_DESC(PIO_CPE, hw_reset, jbc_odcd) },
1752276Sschwartz { JBC_BIT_DESC(ILL_ACC, jbc_safe_acc, jbc_odcd) },
17627Sjchu
1773274Set142600 /* JBC Dmcint IDC */
1783274Set142600 { JBC_BIT_DESC(UNSOL_RD, no_panic, jbc_idc) },
1793274Set142600 { JBC_BIT_DESC(UNSOL_INTR, no_panic, jbc_idc) },
18027Sjchu
1813274Set142600 /* JBC CSR */
1823274Set142600 { JBC_BIT_DESC(EBUS_TO, panic, jbc_csr) }
18327Sjchu };
18427Sjchu
1851772Sjl139090 #define px_err_jbc_keys \
1861772Sjl139090 (sizeof (px_err_jbc_tbl)) / (sizeof (px_err_bit_desc_t))
1871772Sjl139090
1881772Sjl139090 /*
1891772Sjl139090 * UBC error bit table
1901772Sjl139090 */
1911772Sjl139090 #define UBC_BIT_DESC(bit, hdl, erpt) \
1921772Sjl139090 UBC_INTERRUPT_STATUS_ ## bit ## _P, \
1931772Sjl139090 0, \
1941772Sjl139090 PX_ERR_BIT_HANDLE(hdl), \
1951772Sjl139090 PX_ERPT_SEND(erpt), \
1961772Sjl139090 PX_ERR_UBC_CLASS(bit) }, \
1971772Sjl139090 { UBC_INTERRUPT_STATUS_ ## bit ## _S, \
1981772Sjl139090 0, \
1991772Sjl139090 PX_ERR_BIT_HANDLE(hdl), \
2001772Sjl139090 PX_ERPT_SEND(erpt), \
2011772Sjl139090 PX_ERR_UBC_CLASS(bit)
2021772Sjl139090 px_err_bit_desc_t px_err_ubc_tbl[] = {
2031772Sjl139090 /* UBC FATAL */
2043274Set142600 { UBC_BIT_DESC(DMARDUEA, no_panic, ubc_fatal) },
2053274Set142600 { UBC_BIT_DESC(DMAWTUEA, panic, ubc_fatal) },
2063274Set142600 { UBC_BIT_DESC(MEMRDAXA, panic, ubc_fatal) },
2073274Set142600 { UBC_BIT_DESC(MEMWTAXA, panic, ubc_fatal) },
2083274Set142600 { UBC_BIT_DESC(DMARDUEB, no_panic, ubc_fatal) },
2093274Set142600 { UBC_BIT_DESC(DMAWTUEB, panic, ubc_fatal) },
2103274Set142600 { UBC_BIT_DESC(MEMRDAXB, panic, ubc_fatal) },
2113274Set142600 { UBC_BIT_DESC(MEMWTAXB, panic, ubc_fatal) },
2123274Set142600 { UBC_BIT_DESC(PIOWTUE, panic, ubc_fatal) },
2133274Set142600 { UBC_BIT_DESC(PIOWBEUE, panic, ubc_fatal) },
2143274Set142600 { UBC_BIT_DESC(PIORBEUE, panic, ubc_fatal) }
2151772Sjl139090 };
2161772Sjl139090
2171772Sjl139090 #define px_err_ubc_keys \
2181772Sjl139090 (sizeof (px_err_ubc_tbl)) / (sizeof (px_err_bit_desc_t))
2191772Sjl139090
2201772Sjl139090
2211772Sjl139090 char *ubc_class_eid_qualifier[] = {
2221772Sjl139090 "-mem",
2231772Sjl139090 "-channel",
2241772Sjl139090 "-cpu",
2251772Sjl139090 "-path"
2261772Sjl139090 };
2271772Sjl139090
22827Sjchu
22927Sjchu /*
23027Sjchu * DMC error bit tables
23127Sjchu */
23227Sjchu #define IMU_BIT_DESC(bit, hdl, erpt) \
23327Sjchu IMU_INTERRUPT_STATUS_ ## bit ## _P, \
23427Sjchu 0, \
23527Sjchu PX_ERR_BIT_HANDLE(hdl), \
23627Sjchu PX_ERPT_SEND(erpt), \
237739Sjchu PX_ERR_DMC_CLASS(bit) }, \
238739Sjchu { IMU_INTERRUPT_STATUS_ ## bit ## _S, \
239739Sjchu 0, \
240739Sjchu PX_ERR_BIT_HANDLE(hdl), \
241739Sjchu PX_ERPT_SEND(erpt), \
24227Sjchu PX_ERR_DMC_CLASS(bit)
24327Sjchu px_err_bit_desc_t px_err_imu_tbl[] = {
2443274Set142600 /* DMC IMU RDS */
2453274Set142600 { IMU_BIT_DESC(MSI_MAL_ERR, panic, imu_rds) },
2463274Set142600 { IMU_BIT_DESC(MSI_PAR_ERR, panic, imu_rds) },
2473274Set142600 { IMU_BIT_DESC(PMEACK_MES_NOT_EN, panic, imu_rds) },
2483274Set142600 { IMU_BIT_DESC(PMPME_MES_NOT_EN, panic, imu_rds) },
2493274Set142600 { IMU_BIT_DESC(FATAL_MES_NOT_EN, panic, imu_rds) },
2503274Set142600 { IMU_BIT_DESC(NONFATAL_MES_NOT_EN, panic, imu_rds) },
2513274Set142600 { IMU_BIT_DESC(COR_MES_NOT_EN, panic, imu_rds) },
2523274Set142600 { IMU_BIT_DESC(MSI_NOT_EN, panic, imu_rds) },
25327Sjchu
2543274Set142600 /* DMC IMU SCS */
2553421Sjchu { IMU_BIT_DESC(EQ_NOT_EN, panic, imu_scs) },
25627Sjchu
2573274Set142600 /* DMC IMU */
25827Sjchu { IMU_BIT_DESC(EQ_OVER, imu_eq_ovfl, imu) }
25927Sjchu };
26027Sjchu
26127Sjchu #define px_err_imu_keys (sizeof (px_err_imu_tbl)) / (sizeof (px_err_bit_desc_t))
26227Sjchu
26327Sjchu /* mmu errors */
26427Sjchu #define MMU_BIT_DESC(bit, hdl, erpt) \
26527Sjchu MMU_INTERRUPT_STATUS_ ## bit ## _P, \
26627Sjchu 0, \
26727Sjchu PX_ERR_BIT_HANDLE(hdl), \
26827Sjchu PX_ERPT_SEND(erpt), \
269739Sjchu PX_ERR_DMC_CLASS(bit) }, \
270739Sjchu { MMU_INTERRUPT_STATUS_ ## bit ## _S, \
271739Sjchu 0, \
272739Sjchu PX_ERR_BIT_HANDLE(hdl), \
273739Sjchu PX_ERPT_SEND(erpt), \
27427Sjchu PX_ERR_DMC_CLASS(bit)
27527Sjchu px_err_bit_desc_t px_err_mmu_tbl[] = {
2763274Set142600 /* DMC MMU TFAR/TFSR */
27727Sjchu { MMU_BIT_DESC(BYP_ERR, mmu_rbne, mmu_tfar_tfsr) },
27827Sjchu { MMU_BIT_DESC(BYP_OOR, mmu_tfa, mmu_tfar_tfsr) },
2793274Set142600 { MMU_BIT_DESC(TRN_ERR, panic, mmu_tfar_tfsr) },
28027Sjchu { MMU_BIT_DESC(TRN_OOR, mmu_tfa, mmu_tfar_tfsr) },
28127Sjchu { MMU_BIT_DESC(TTE_INV, mmu_tfa, mmu_tfar_tfsr) },
28227Sjchu { MMU_BIT_DESC(TTE_PRT, mmu_tfa, mmu_tfar_tfsr) },
2833274Set142600 { MMU_BIT_DESC(TTC_DPE, mmu_parity, mmu_tfar_tfsr) },
2843274Set142600 { MMU_BIT_DESC(TBW_DME, panic, mmu_tfar_tfsr) },
2853274Set142600 { MMU_BIT_DESC(TBW_UDE, panic, mmu_tfar_tfsr) },
2863274Set142600 { MMU_BIT_DESC(TBW_ERR, panic, mmu_tfar_tfsr) },
2873274Set142600 { MMU_BIT_DESC(TBW_DPE, mmu_parity, mmu_tfar_tfsr) },
28827Sjchu
2893274Set142600 /* DMC MMU */
2903274Set142600 { MMU_BIT_DESC(TTC_CAE, panic, mmu) }
29127Sjchu };
29227Sjchu #define px_err_mmu_keys (sizeof (px_err_mmu_tbl)) / (sizeof (px_err_bit_desc_t))
29327Sjchu
2941772Sjl139090
29527Sjchu /*
29627Sjchu * PEC error bit tables
29727Sjchu */
29827Sjchu #define ILU_BIT_DESC(bit, hdl, erpt) \
29927Sjchu ILU_INTERRUPT_STATUS_ ## bit ## _P, \
30027Sjchu 0, \
30127Sjchu PX_ERR_BIT_HANDLE(hdl), \
30227Sjchu PX_ERPT_SEND(erpt), \
303739Sjchu PX_ERR_PEC_CLASS(bit) }, \
304739Sjchu { ILU_INTERRUPT_STATUS_ ## bit ## _S, \
305739Sjchu 0, \
306739Sjchu PX_ERR_BIT_HANDLE(hdl), \
307739Sjchu PX_ERPT_SEND(erpt), \
30827Sjchu PX_ERR_PEC_CLASS(bit)
30927Sjchu px_err_bit_desc_t px_err_ilu_tbl[] = {
3103274Set142600 /* PEC ILU none */
3113274Set142600 { ILU_BIT_DESC(IHB_PE, panic, pec_ilu) }
31227Sjchu };
31327Sjchu #define px_err_ilu_keys \
31427Sjchu (sizeof (px_err_ilu_tbl)) / (sizeof (px_err_bit_desc_t))
31527Sjchu
31627Sjchu /*
31727Sjchu * PEC UE errors implementation is incomplete pending PCIE generic
318383Set142600 * fabric rules. Must handle both PRIMARY and SECONDARY errors.
31927Sjchu */
32027Sjchu /* pec ue errors */
32127Sjchu #define TLU_UC_BIT_DESC(bit, hdl, erpt) \
32227Sjchu TLU_UNCORRECTABLE_ERROR_STATUS_CLEAR_ ## bit ## _P, \
32327Sjchu 0, \
324383Set142600 PX_ERR_BIT_HANDLE(hdl), \
325383Set142600 PX_ERPT_SEND(erpt), \
326383Set142600 PX_ERR_PEC_CLASS(bit) }, \
327383Set142600 { TLU_UNCORRECTABLE_ERROR_STATUS_CLEAR_ ## bit ## _S, \
328383Set142600 0, \
329383Set142600 PX_ERR_BIT_HANDLE(hdl), \
330383Set142600 PX_ERPT_SEND(erpt), \
331383Set142600 PX_ERR_PEC_CLASS(bit)
3321772Sjl139090 #define TLU_UC_OB_BIT_DESC(bit, hdl, erpt) \
3331772Sjl139090 TLU_UNCORRECTABLE_ERROR_STATUS_CLEAR_ ## bit ## _P, \
3341772Sjl139090 0, \
3351772Sjl139090 PX_ERR_BIT_HANDLE(hdl), \
3361772Sjl139090 PX_ERPT_SEND(erpt), \
3371772Sjl139090 PX_ERR_PEC_OB_CLASS(bit) }, \
3381772Sjl139090 { TLU_UNCORRECTABLE_ERROR_STATUS_CLEAR_ ## bit ## _S, \
3391772Sjl139090 0, \
3401772Sjl139090 PX_ERR_BIT_HANDLE(hdl), \
3411772Sjl139090 PX_ERPT_SEND(erpt), \
3425654Sdanice PX_ERR_PEC_OB_CLASS(bit)
34327Sjchu px_err_bit_desc_t px_err_tlu_ue_tbl[] = {
3443274Set142600 /* PCI-E Receive Uncorrectable Errors */
345383Set142600 { TLU_UC_BIT_DESC(UR, pciex_ue, pciex_rx_ue) },
346383Set142600 { TLU_UC_BIT_DESC(UC, pciex_ue, pciex_rx_ue) },
34727Sjchu
3483274Set142600 /* PCI-E Transmit Uncorrectable Errors */
3491772Sjl139090 { TLU_UC_OB_BIT_DESC(ECRC, pciex_ue, pciex_rx_ue) },
350383Set142600 { TLU_UC_BIT_DESC(CTO, pciex_ue, pciex_tx_ue) },
351383Set142600 { TLU_UC_BIT_DESC(ROF, pciex_ue, pciex_tx_ue) },
35227Sjchu
3533274Set142600 /* PCI-E Rx/Tx Uncorrectable Errors */
354383Set142600 { TLU_UC_BIT_DESC(MFP, pciex_ue, pciex_rx_tx_ue) },
355383Set142600 { TLU_UC_BIT_DESC(PP, pciex_ue, pciex_rx_tx_ue) },
35627Sjchu
3573274Set142600 /* Other PCI-E Uncorrectable Errors */
358383Set142600 { TLU_UC_BIT_DESC(FCP, pciex_ue, pciex_ue) },
359383Set142600 { TLU_UC_BIT_DESC(DLP, pciex_ue, pciex_ue) },
360383Set142600 { TLU_UC_BIT_DESC(TE, pciex_ue, pciex_ue) },
361383Set142600
362383Set142600 /* Not used */
363383Set142600 { TLU_UC_BIT_DESC(CA, pciex_ue, do_not) }
36427Sjchu };
36527Sjchu #define px_err_tlu_ue_keys \
36627Sjchu (sizeof (px_err_tlu_ue_tbl)) / (sizeof (px_err_bit_desc_t))
36727Sjchu
3681772Sjl139090
36927Sjchu /*
37027Sjchu * PEC CE errors implementation is incomplete pending PCIE generic
37127Sjchu * fabric rules.
37227Sjchu */
37327Sjchu /* pec ce errors */
37427Sjchu #define TLU_CE_BIT_DESC(bit, hdl, erpt) \
37527Sjchu TLU_CORRECTABLE_ERROR_STATUS_CLEAR_ ## bit ## _P, \
37627Sjchu 0, \
377383Set142600 PX_ERR_BIT_HANDLE(hdl), \
378383Set142600 PX_ERPT_SEND(erpt), \
379383Set142600 PX_ERR_PEC_CLASS(bit) }, \
380383Set142600 { TLU_CORRECTABLE_ERROR_STATUS_CLEAR_ ## bit ## _S, \
381383Set142600 0, \
382383Set142600 PX_ERR_BIT_HANDLE(hdl), \
383383Set142600 PX_ERPT_SEND(erpt), \
384383Set142600 PX_ERR_PEC_CLASS(bit)
38527Sjchu px_err_bit_desc_t px_err_tlu_ce_tbl[] = {
3863274Set142600 /* PCI-E Correctable Errors */
387383Set142600 { TLU_CE_BIT_DESC(RTO, pciex_ce, pciex_ce) },
388383Set142600 { TLU_CE_BIT_DESC(RNR, pciex_ce, pciex_ce) },
389383Set142600 { TLU_CE_BIT_DESC(BDP, pciex_ce, pciex_ce) },
390383Set142600 { TLU_CE_BIT_DESC(BTP, pciex_ce, pciex_ce) },
391383Set142600 { TLU_CE_BIT_DESC(RE, pciex_ce, pciex_ce) }
39227Sjchu };
39327Sjchu #define px_err_tlu_ce_keys \
39427Sjchu (sizeof (px_err_tlu_ce_tbl)) / (sizeof (px_err_bit_desc_t))
39527Sjchu
3961772Sjl139090
39727Sjchu /* pec oe errors */
39827Sjchu #define TLU_OE_BIT_DESC(bit, hdl, erpt) \
39927Sjchu TLU_OTHER_EVENT_STATUS_CLEAR_ ## bit ## _P, \
40027Sjchu 0, \
40127Sjchu PX_ERR_BIT_HANDLE(hdl), \
40227Sjchu PX_ERPT_SEND(erpt), \
403739Sjchu PX_ERR_PEC_CLASS(bit) }, \
404739Sjchu { TLU_OTHER_EVENT_STATUS_CLEAR_ ## bit ## _S, \
405739Sjchu 0, \
406739Sjchu PX_ERR_BIT_HANDLE(hdl), \
407739Sjchu PX_ERPT_SEND(erpt), \
40827Sjchu PX_ERR_PEC_CLASS(bit)
4091772Sjl139090 #define TLU_OE_OB_BIT_DESC(bit, hdl, erpt) \
4101772Sjl139090 TLU_OTHER_EVENT_STATUS_CLEAR_ ## bit ## _P, \
4111772Sjl139090 0, \
4121772Sjl139090 PX_ERR_BIT_HANDLE(hdl), \
4131772Sjl139090 PX_ERPT_SEND(erpt), \
4141772Sjl139090 PX_ERR_PEC_OB_CLASS(bit) }, \
4151772Sjl139090 { TLU_OTHER_EVENT_STATUS_CLEAR_ ## bit ## _S, \
4161772Sjl139090 0, \
4171772Sjl139090 PX_ERR_BIT_HANDLE(hdl), \
4181772Sjl139090 PX_ERPT_SEND(erpt), \
4191772Sjl139090 PX_ERR_PEC_OB_CLASS(bit)
42027Sjchu px_err_bit_desc_t px_err_tlu_oe_tbl[] = {
4213274Set142600 /* TLU Other Event Status (receive only) */
4223274Set142600 { TLU_OE_BIT_DESC(MRC, hw_reset, pciex_rx_oe) },
4233274Set142600
4243274Set142600 /* TLU Other Event Status (rx + tx) */
4253274Set142600 { TLU_OE_BIT_DESC(WUC, wuc_ruc, pciex_rx_tx_oe) },
4263274Set142600 { TLU_OE_BIT_DESC(RUC, wuc_ruc, pciex_rx_tx_oe) },
4273274Set142600 { TLU_OE_BIT_DESC(CRS, no_panic, pciex_rx_tx_oe) },
42827Sjchu
4293274Set142600 /* TLU Other Event */
4303274Set142600 { TLU_OE_BIT_DESC(IIP, panic, pciex_oe) },
4313274Set142600 { TLU_OE_BIT_DESC(EDP, panic, pciex_oe) },
4323274Set142600 { TLU_OE_BIT_DESC(EHP, panic, pciex_oe) },
4333274Set142600 { TLU_OE_OB_BIT_DESC(TLUEITMO, panic, pciex_oe) },
4343274Set142600 { TLU_OE_BIT_DESC(LIN, no_panic, pciex_oe) },
4353274Set142600 { TLU_OE_BIT_DESC(LRS, no_panic, pciex_oe) },
4361147Sjchu { TLU_OE_BIT_DESC(LDN, tlu_ldn, pciex_oe) },
4371147Sjchu { TLU_OE_BIT_DESC(LUP, tlu_lup, pciex_oe) },
4383274Set142600 { TLU_OE_BIT_DESC(ERU, panic, pciex_oe) },
4393274Set142600 { TLU_OE_BIT_DESC(ERO, panic, pciex_oe) },
4403274Set142600 { TLU_OE_BIT_DESC(EMP, panic, pciex_oe) },
4413274Set142600 { TLU_OE_BIT_DESC(EPE, panic, pciex_oe) },
4423274Set142600 { TLU_OE_BIT_DESC(ERP, panic, pciex_oe) },
4433274Set142600 { TLU_OE_BIT_DESC(EIP, panic, pciex_oe) }
44427Sjchu };
44527Sjchu
44627Sjchu #define px_err_tlu_oe_keys \
44727Sjchu (sizeof (px_err_tlu_oe_tbl)) / (sizeof (px_err_bit_desc_t))
44827Sjchu
4491772Sjl139090
45027Sjchu /*
45127Sjchu * All the following tables below are for LPU Interrupts. These interrupts
45227Sjchu * are *NOT* error interrupts, but event status interrupts.
45327Sjchu *
45427Sjchu * These events are probably of most interest to:
45527Sjchu * o Hotplug
45627Sjchu * o Power Management
45727Sjchu * o etc...
45827Sjchu *
45927Sjchu * There are also a few events that would be interresting for FMA.
46027Sjchu * Again none of the regiseters below state that an error has occured
46127Sjchu * or that data has been lost. If anything, they give status that an
46227Sjchu * error is *about* to occur. examples
46327Sjchu * o INT_SKP_ERR - indicates clock between fire and child is too far
46427Sjchu * off and is most unlikely able to compensate
46527Sjchu * o INT_TX_PAR_ERR - A parity error occured in ONE lane. This is
46627Sjchu * HW recoverable, but will like end up as a future
46727Sjchu * fabric error as well.
46827Sjchu *
46927Sjchu * For now, we don't care about any of these errors and should be ignore,
47027Sjchu * but cleared.
47127Sjchu */
47227Sjchu
47327Sjchu /* LPU Link Interrupt Table */
47427Sjchu #define LPUL_BIT_DESC(bit, hdl, erpt) \
47527Sjchu LPU_LINK_LAYER_INTERRUPT_AND_STATUS_INT_ ## bit, \
47627Sjchu 0, \
47727Sjchu NULL, \
47827Sjchu NULL, \
47927Sjchu ""
48027Sjchu px_err_bit_desc_t px_err_lpul_tbl[] = {
48127Sjchu { LPUL_BIT_DESC(LINK_ERR_ACT, NULL, NULL) }
48227Sjchu };
48327Sjchu #define px_err_lpul_keys \
48427Sjchu (sizeof (px_err_lpul_tbl)) / (sizeof (px_err_bit_desc_t))
48527Sjchu
48627Sjchu /* LPU Physical Interrupt Table */
48727Sjchu #define LPUP_BIT_DESC(bit, hdl, erpt) \
48827Sjchu LPU_PHY_LAYER_INTERRUPT_AND_STATUS_INT_ ## bit, \
48927Sjchu 0, \
49027Sjchu NULL, \
49127Sjchu NULL, \
49227Sjchu ""
49327Sjchu px_err_bit_desc_t px_err_lpup_tbl[] = {
49427Sjchu { LPUP_BIT_DESC(PHY_LAYER_ERR, NULL, NULL) }
49527Sjchu };
49627Sjchu #define px_err_lpup_keys \
49727Sjchu (sizeof (px_err_lpup_tbl)) / (sizeof (px_err_bit_desc_t))
49827Sjchu
49927Sjchu /* LPU Receive Interrupt Table */
50027Sjchu #define LPUR_BIT_DESC(bit, hdl, erpt) \
50127Sjchu LPU_RECEIVE_PHY_INTERRUPT_AND_STATUS_INT_ ## bit, \
50227Sjchu 0, \
50327Sjchu NULL, \
50427Sjchu NULL, \
50527Sjchu ""
50627Sjchu px_err_bit_desc_t px_err_lpur_tbl[] = {
50727Sjchu { LPUR_BIT_DESC(RCV_PHY, NULL, NULL) }
50827Sjchu };
50927Sjchu #define px_err_lpur_keys \
51027Sjchu (sizeof (px_err_lpur_tbl)) / (sizeof (px_err_bit_desc_t))
51127Sjchu
51227Sjchu /* LPU Transmit Interrupt Table */
51327Sjchu #define LPUX_BIT_DESC(bit, hdl, erpt) \
51427Sjchu LPU_TRANSMIT_PHY_INTERRUPT_AND_STATUS_INT_ ## bit, \
51527Sjchu 0, \
51627Sjchu NULL, \
51727Sjchu NULL, \
51827Sjchu ""
51927Sjchu px_err_bit_desc_t px_err_lpux_tbl[] = {
52027Sjchu { LPUX_BIT_DESC(UNMSK, NULL, NULL) }
52127Sjchu };
52227Sjchu #define px_err_lpux_keys \
52327Sjchu (sizeof (px_err_lpux_tbl)) / (sizeof (px_err_bit_desc_t))
52427Sjchu
52527Sjchu /* LPU LTSSM Interrupt Table */
52627Sjchu #define LPUS_BIT_DESC(bit, hdl, erpt) \
52727Sjchu LPU_LTSSM_INTERRUPT_AND_STATUS_INT_ ## bit, \
52827Sjchu 0, \
52927Sjchu NULL, \
53027Sjchu NULL, \
53127Sjchu ""
53227Sjchu px_err_bit_desc_t px_err_lpus_tbl[] = {
53327Sjchu { LPUS_BIT_DESC(ANY, NULL, NULL) }
53427Sjchu };
53527Sjchu #define px_err_lpus_keys \
53627Sjchu (sizeof (px_err_lpus_tbl)) / (sizeof (px_err_bit_desc_t))
53727Sjchu
53827Sjchu /* LPU Gigablaze Glue Interrupt Table */
53927Sjchu #define LPUG_BIT_DESC(bit, hdl, erpt) \
54027Sjchu LPU_GIGABLAZE_GLUE_INTERRUPT_AND_STATUS_INT_ ## bit, \
54127Sjchu 0, \
54227Sjchu NULL, \
54327Sjchu NULL, \
54427Sjchu ""
54527Sjchu px_err_bit_desc_t px_err_lpug_tbl[] = {
54627Sjchu { LPUG_BIT_DESC(GLOBL_UNMSK, NULL, NULL) }
54727Sjchu };
54827Sjchu #define px_err_lpug_keys \
54927Sjchu (sizeof (px_err_lpug_tbl)) / (sizeof (px_err_bit_desc_t))
55027Sjchu
55127Sjchu
55227Sjchu /* Mask and Tables */
5532509Sschwartz #define MnT6X(pre) \
55427Sjchu &px_ ## pre ## _intr_mask, \
55527Sjchu &px_ ## pre ## _log_mask, \
55627Sjchu &px_ ## pre ## _count_mask, \
55727Sjchu px_err_ ## pre ## _tbl, \
55827Sjchu px_err_ ## pre ## _keys, \
5592509Sschwartz PX_REG_XBC, \
56027Sjchu 0
56127Sjchu
5622509Sschwartz #define MnT6(pre) \
5631772Sjl139090 &px_ ## pre ## _intr_mask, \
5641772Sjl139090 &px_ ## pre ## _log_mask, \
5651772Sjl139090 &px_ ## pre ## _count_mask, \
5662509Sschwartz px_err_ ## pre ## _tbl, \
5672509Sschwartz px_err_ ## pre ## _keys, \
5682509Sschwartz PX_REG_CSR, \
5691772Sjl139090 0
5701772Sjl139090
57127Sjchu /* LPU Registers Addresses */
57227Sjchu #define LR4(pre) \
57327Sjchu NULL, \
57427Sjchu LPU_ ## pre ## _INTERRUPT_MASK, \
57527Sjchu LPU_ ## pre ## _INTERRUPT_AND_STATUS, \
57627Sjchu LPU_ ## pre ## _INTERRUPT_AND_STATUS
57727Sjchu
57827Sjchu /* LPU Registers Addresses with Irregularities */
57927Sjchu #define LR4_FIXME(pre) \
58027Sjchu NULL, \
58127Sjchu LPU_ ## pre ## _INTERRUPT_MASK, \
58227Sjchu LPU_ ## pre ## _LAYER_INTERRUPT_AND_STATUS, \
58327Sjchu LPU_ ## pre ## _LAYER_INTERRUPT_AND_STATUS
58427Sjchu
58527Sjchu /* TLU Registers Addresses */
58627Sjchu #define TR4(pre) \
58727Sjchu TLU_ ## pre ## _LOG_ENABLE, \
58827Sjchu TLU_ ## pre ## _INTERRUPT_ENABLE, \
58927Sjchu TLU_ ## pre ## _INTERRUPT_STATUS, \
59027Sjchu TLU_ ## pre ## _STATUS_CLEAR
59127Sjchu
5921772Sjl139090 /* Registers Addresses for JBC, UBC, MMU, IMU and ILU */
59327Sjchu #define R4(pre) \
59427Sjchu pre ## _ERROR_LOG_ENABLE, \
59527Sjchu pre ## _INTERRUPT_ENABLE, \
59627Sjchu pre ## _INTERRUPT_STATUS, \
59727Sjchu pre ## _ERROR_STATUS_CLEAR
59827Sjchu
5992509Sschwartz /* Bits in chip_mask, set according to type. */
6002509Sschwartz #define CHP_O BITMASK(PX_CHIP_OBERON)
6012509Sschwartz #define CHP_F BITMASK(PX_CHIP_FIRE)
6022509Sschwartz #define CHP_FO (CHP_F | CHP_O)
6032509Sschwartz
60427Sjchu /*
60527Sjchu * Register error handling tables.
60627Sjchu * The ID Field (first field) is identified by an enum px_err_id_t.
60727Sjchu * It is located in px_err.h
60827Sjchu */
6092509Sschwartz static const
61027Sjchu px_err_reg_desc_t px_err_reg_tbl[] = {
6112509Sschwartz { CHP_F, MnT6X(jbc), R4(JBC), "JBC Error"},
6122509Sschwartz { CHP_O, MnT6X(ubc), R4(UBC), "UBC Error"},
6132509Sschwartz { CHP_FO, MnT6(mmu), R4(MMU), "MMU Error"},
6142509Sschwartz { CHP_FO, MnT6(imu), R4(IMU), "IMU Error"},
6152509Sschwartz { CHP_FO, MnT6(tlu_ue), TR4(UNCORRECTABLE_ERROR), "TLU UE"},
6162509Sschwartz { CHP_FO, MnT6(tlu_ce), TR4(CORRECTABLE_ERROR), "TLU CE"},
6172509Sschwartz { CHP_FO, MnT6(tlu_oe), TR4(OTHER_EVENT), "TLU OE"},
6182509Sschwartz { CHP_FO, MnT6(ilu), R4(ILU), "ILU Error"},
6192509Sschwartz { CHP_F, MnT6(lpul), LR4(LINK_LAYER), "LPU Link Layer"},
6202509Sschwartz { CHP_F, MnT6(lpup), LR4_FIXME(PHY), "LPU Phy Layer"},
6212509Sschwartz { CHP_F, MnT6(lpur), LR4(RECEIVE_PHY), "LPU RX Phy Layer"},
6222509Sschwartz { CHP_F, MnT6(lpux), LR4(TRANSMIT_PHY), "LPU TX Phy Layer"},
6232509Sschwartz { CHP_F, MnT6(lpus), LR4(LTSSM), "LPU LTSSM"},
6242509Sschwartz { CHP_F, MnT6(lpug), LR4(GIGABLAZE_GLUE), "LPU GigaBlaze Glue"},
62527Sjchu };
6262509Sschwartz
6272509Sschwartz #define PX_ERR_REG_KEYS (sizeof (px_err_reg_tbl)) / (sizeof (px_err_reg_tbl[0]))
62827Sjchu
62927Sjchu typedef struct px_err_ss {
63027Sjchu uint64_t err_status[PX_ERR_REG_KEYS];
63127Sjchu } px_err_ss_t;
63227Sjchu
6333274Set142600 static void px_err_snapshot(px_t *px_p, px_err_ss_t *ss, int block);
63427Sjchu static int px_err_erpt_and_clr(px_t *px_p, ddi_fm_error_t *derr,
63527Sjchu px_err_ss_t *ss);
63627Sjchu static int px_err_check_severity(px_t *px_p, ddi_fm_error_t *derr,
63727Sjchu int err, int caller);
63827Sjchu
63927Sjchu /*
64027Sjchu * px_err_cb_intr:
6411772Sjl139090 * Interrupt handler for the JBC/UBC block.
64227Sjchu * o lock
64327Sjchu * o create derr
6443274Set142600 * o px_err_cmn_intr
64527Sjchu * o unlock
64627Sjchu * o handle error: fatal? fm_panic() : return INTR_CLAIMED)
64727Sjchu */
64827Sjchu uint_t
px_err_cb_intr(caddr_t arg)64927Sjchu px_err_cb_intr(caddr_t arg)
65027Sjchu {
65127Sjchu px_fault_t *px_fault_p = (px_fault_t *)arg;
65227Sjchu dev_info_t *rpdip = px_fault_p->px_fh_dip;
65327Sjchu px_t *px_p = DIP_TO_STATE(rpdip);
6543274Set142600 int err;
65527Sjchu ddi_fm_error_t derr;
65627Sjchu
65727Sjchu /* Create the derr */
65827Sjchu bzero(&derr, sizeof (ddi_fm_error_t));
65927Sjchu derr.fme_version = DDI_FME_VERSION;
66027Sjchu derr.fme_ena = fm_ena_generate(0, FM_ENA_FMT1);
66127Sjchu derr.fme_flag = DDI_FM_ERR_UNEXPECTED;
66227Sjchu
6636313Skrishnae if (px_fm_enter(px_p) != DDI_SUCCESS)
6646313Skrishnae goto done;
66527Sjchu
6663274Set142600 err = px_err_cmn_intr(px_p, &derr, PX_INTR_CALL, PX_FM_BLOCK_HOST);
66727Sjchu (void) px_lib_intr_setstate(rpdip, px_fault_p->px_fh_sysino,
66827Sjchu INTR_IDLE_STATE);
66927Sjchu
6706313Skrishnae px_err_panic(err, PX_HB, PX_NO_ERROR, B_TRUE);
6716313Skrishnae px_fm_exit(px_p);
6726313Skrishnae px_err_panic(err, PX_HB, PX_NO_ERROR, B_FALSE);
67327Sjchu
6746313Skrishnae done:
67527Sjchu return (DDI_INTR_CLAIMED);
67627Sjchu }
67727Sjchu
67827Sjchu /*
67927Sjchu * px_err_dmc_pec_intr:
68027Sjchu * Interrupt handler for the DMC/PEC block.
68127Sjchu * o lock
68227Sjchu * o create derr
6833274Set142600 * o px_err_cmn_intr(leaf, with out cb)
6843274Set142600 * o pcie_scan_fabric (leaf)
68527Sjchu * o unlock
68627Sjchu * o handle error: fatal? fm_panic() : return INTR_CLAIMED)
68727Sjchu */
68827Sjchu uint_t
px_err_dmc_pec_intr(caddr_t arg)68927Sjchu px_err_dmc_pec_intr(caddr_t arg)
69027Sjchu {
69127Sjchu px_fault_t *px_fault_p = (px_fault_t *)arg;
69227Sjchu dev_info_t *rpdip = px_fault_p->px_fh_dip;
69327Sjchu px_t *px_p = DIP_TO_STATE(rpdip);
6946313Skrishnae int rc_err, fab_err;
69527Sjchu ddi_fm_error_t derr;
69627Sjchu
69727Sjchu /* Create the derr */
69827Sjchu bzero(&derr, sizeof (ddi_fm_error_t));
69927Sjchu derr.fme_version = DDI_FME_VERSION;
70027Sjchu derr.fme_ena = fm_ena_generate(0, FM_ENA_FMT1);
70127Sjchu derr.fme_flag = DDI_FM_ERR_UNEXPECTED;
70227Sjchu
7036313Skrishnae if (px_fm_enter(px_p) != DDI_SUCCESS)
7046313Skrishnae goto done;
70527Sjchu
70627Sjchu /* send ereport/handle/clear fire registers */
7073274Set142600 rc_err = px_err_cmn_intr(px_p, &derr, PX_INTR_CALL, PX_FM_BLOCK_PCIE);
70827Sjchu
70927Sjchu /* Check all child devices for errors */
7106313Skrishnae fab_err = px_scan_fabric(px_p, rpdip, &derr);
71127Sjchu
71227Sjchu /* Set the interrupt state to idle */
71327Sjchu (void) px_lib_intr_setstate(rpdip, px_fault_p->px_fh_sysino,
71427Sjchu INTR_IDLE_STATE);
71527Sjchu
7166313Skrishnae px_err_panic(rc_err, PX_RC, fab_err, B_TRUE);
7176313Skrishnae px_fm_exit(px_p);
7186313Skrishnae px_err_panic(rc_err, PX_RC, fab_err, B_FALSE);
71927Sjchu
7206313Skrishnae done:
72127Sjchu return (DDI_INTR_CLAIMED);
72227Sjchu }
72327Sjchu
72427Sjchu /*
7252509Sschwartz * Proper csr_base is responsibility of the caller. (Called from px_lib_dev_init
7262509Sschwartz * via px_err_reg_setup_all for pcie error registers; called from
7272509Sschwartz * px_cb_add_intr for jbc/ubc from px_cb_attach.)
7282509Sschwartz *
7292509Sschwartz * Note: reg_id is passed in instead of reg_desc since this function is called
7302509Sschwartz * from px_lib4u.c, which doesn't know about the structure of the table.
73127Sjchu */
73227Sjchu void
px_err_reg_enable(px_err_id_t reg_id,caddr_t csr_base)7332509Sschwartz px_err_reg_enable(px_err_id_t reg_id, caddr_t csr_base)
73427Sjchu {
7352509Sschwartz const px_err_reg_desc_t *reg_desc_p = &px_err_reg_tbl[reg_id];
7362509Sschwartz uint64_t intr_mask = *reg_desc_p->intr_mask_p;
7372509Sschwartz uint64_t log_mask = *reg_desc_p->log_mask_p;
73827Sjchu
73927Sjchu /* Enable logs if it exists */
7402509Sschwartz if (reg_desc_p->log_addr != NULL)
7412509Sschwartz CSR_XS(csr_base, reg_desc_p->log_addr, log_mask);
74227Sjchu
74327Sjchu /*
74427Sjchu * For readability you in code you set 1 to enable an interrupt.
74527Sjchu * But in Fire it's backwards. You set 1 to *disable* an intr.
74627Sjchu * Reverse the user tunable intr mask field.
74727Sjchu *
74827Sjchu * Disable All Errors
74927Sjchu * Clear All Errors
75027Sjchu * Enable Errors
75127Sjchu */
7522509Sschwartz CSR_XS(csr_base, reg_desc_p->enable_addr, 0);
7532509Sschwartz CSR_XS(csr_base, reg_desc_p->clear_addr, -1);
7542509Sschwartz CSR_XS(csr_base, reg_desc_p->enable_addr, intr_mask);
7552509Sschwartz DBG(DBG_ATTACH, NULL, "%s Mask: 0x%llx\n", reg_desc_p->msg,
7562509Sschwartz CSR_XR(csr_base, reg_desc_p->enable_addr));
7572509Sschwartz DBG(DBG_ATTACH, NULL, "%s Status: 0x%llx\n", reg_desc_p->msg,
7582509Sschwartz CSR_XR(csr_base, reg_desc_p->status_addr));
7592509Sschwartz DBG(DBG_ATTACH, NULL, "%s Clear: 0x%llx\n", reg_desc_p->msg,
7602509Sschwartz CSR_XR(csr_base, reg_desc_p->clear_addr));
7612509Sschwartz if (reg_desc_p->log_addr != NULL) {
7622509Sschwartz DBG(DBG_ATTACH, NULL, "%s Log: 0x%llx\n", reg_desc_p->msg,
7632509Sschwartz CSR_XR(csr_base, reg_desc_p->log_addr));
76427Sjchu }
76527Sjchu }
76627Sjchu
76727Sjchu void
px_err_reg_disable(px_err_id_t reg_id,caddr_t csr_base)7682509Sschwartz px_err_reg_disable(px_err_id_t reg_id, caddr_t csr_base)
76927Sjchu {
7702509Sschwartz const px_err_reg_desc_t *reg_desc_p = &px_err_reg_tbl[reg_id];
7712509Sschwartz uint64_t val = (reg_id >= PX_ERR_LPU_LINK) ? -1 : 0;
77227Sjchu
7732509Sschwartz if (reg_desc_p->log_addr != NULL)
7742509Sschwartz CSR_XS(csr_base, reg_desc_p->log_addr, val);
7752509Sschwartz CSR_XS(csr_base, reg_desc_p->enable_addr, val);
7762509Sschwartz }
77727Sjchu
7782509Sschwartz /*
7792509Sschwartz * Set up pcie error registers.
7802509Sschwartz */
7812509Sschwartz void
px_err_reg_setup_pcie(uint8_t chip_mask,caddr_t csr_base,boolean_t enable)7822509Sschwartz px_err_reg_setup_pcie(uint8_t chip_mask, caddr_t csr_base, boolean_t enable)
7832509Sschwartz {
7842509Sschwartz px_err_id_t reg_id;
7852509Sschwartz const px_err_reg_desc_t *reg_desc_p;
7862509Sschwartz void (*px_err_reg_func)(px_err_id_t, caddr_t);
7872509Sschwartz
7882509Sschwartz /*
7892509Sschwartz * JBC or XBC are enabled during adding of common block interrupts,
7902509Sschwartz * not done here.
7912509Sschwartz */
7922509Sschwartz px_err_reg_func = (enable ? px_err_reg_enable : px_err_reg_disable);
7932509Sschwartz for (reg_id = 0; reg_id < PX_ERR_REG_KEYS; reg_id++) {
7942509Sschwartz reg_desc_p = &px_err_reg_tbl[reg_id];
7952509Sschwartz if ((reg_desc_p->chip_mask & chip_mask) &&
7962509Sschwartz (reg_desc_p->reg_bank == PX_REG_CSR))
7972509Sschwartz px_err_reg_func(reg_id, csr_base);
79827Sjchu }
79927Sjchu }
80027Sjchu
80127Sjchu /*
8023274Set142600 * px_err_cmn_intr:
80327Sjchu * Common function called by trap, mondo and fabric intr.
80427Sjchu * o Snap shot current fire registers
80527Sjchu * o check for safe access
80627Sjchu * o send ereport and clear snap shot registers
8073274Set142600 * o create and queue RC info for later use in fabric scan.
8083274Set142600 * o RUC/WUC, PTLP, MMU Errors(CA), UR
80927Sjchu * o check severity of snap shot registers
81027Sjchu *
81127Sjchu * @param px_p leaf in which to check access
81227Sjchu * @param derr fm err data structure to be updated
81327Sjchu * @param caller PX_TRAP_CALL | PX_INTR_CALL
8143274Set142600 * @param block PX_FM_BLOCK_HOST | PX_FM_BLOCK_PCIE | PX_FM_BLOCK_ALL
8153274Set142600 * @return err PX_NO_PANIC | PX_PANIC | PX_HW_RESET | PX_PROTECTED
81627Sjchu */
81727Sjchu int
px_err_cmn_intr(px_t * px_p,ddi_fm_error_t * derr,int caller,int block)8183274Set142600 px_err_cmn_intr(px_t *px_p, ddi_fm_error_t *derr, int caller, int block)
81927Sjchu {
8202509Sschwartz px_err_ss_t ss = {0};
8213274Set142600 int err;
82227Sjchu
8231648Sjchu ASSERT(MUTEX_HELD(&px_p->px_fm_mutex));
82427Sjchu
8253613Set142600 /* check for safe access */
8263613Set142600 px_err_safeacc_check(px_p, derr);
8273613Set142600
82827Sjchu /* snap shot the current fire registers */
8293274Set142600 px_err_snapshot(px_p, &ss, block);
83027Sjchu
83127Sjchu /* send ereports/handle/clear registers */
83227Sjchu err = px_err_erpt_and_clr(px_p, derr, &ss);
83327Sjchu
83427Sjchu /* check for error severity */
83527Sjchu err = px_err_check_severity(px_p, derr, err, caller);
83627Sjchu
83727Sjchu /* Mark the On Trap Handle if an error occured */
8383274Set142600 if (err != PX_NO_ERROR) {
83927Sjchu px_pec_t *pec_p = px_p->px_pec_p;
84027Sjchu on_trap_data_t *otd = pec_p->pec_ontrap_data;
84127Sjchu
842118Sjchu if ((otd != NULL) && (otd->ot_prot & OT_DATA_ACCESS))
84327Sjchu otd->ot_trap |= OT_DATA_ACCESS;
84427Sjchu }
84527Sjchu
84627Sjchu return (err);
84727Sjchu }
84827Sjchu
84927Sjchu /*
85027Sjchu * Static function
85127Sjchu */
85227Sjchu
85327Sjchu /*
85427Sjchu * px_err_snapshot:
85527Sjchu * Take a current snap shot of all the fire error registers. This includes
8563274Set142600 * JBC/UBC, DMC, and PEC depending on the block flag
85727Sjchu *
85827Sjchu * @param px_p leaf in which to take the snap shot.
85927Sjchu * @param ss pre-allocated memory to store the snap shot.
8601772Sjl139090 * @param chk_cb boolean on whether to store jbc/ubc register.
86127Sjchu */
86227Sjchu static void
px_err_snapshot(px_t * px_p,px_err_ss_t * ss_p,int block)8633274Set142600 px_err_snapshot(px_t *px_p, px_err_ss_t *ss_p, int block)
86427Sjchu {
86527Sjchu pxu_t *pxu_p = (pxu_t *)px_p->px_plat_p;
86627Sjchu caddr_t xbc_csr_base = (caddr_t)pxu_p->px_address[PX_REG_XBC];
86727Sjchu caddr_t pec_csr_base = (caddr_t)pxu_p->px_address[PX_REG_CSR];
8683274Set142600 caddr_t csr_base;
8692509Sschwartz uint8_t chip_mask = 1 << PX_CHIP_TYPE(pxu_p);
8702509Sschwartz const px_err_reg_desc_t *reg_desc_p = px_err_reg_tbl;
8712509Sschwartz px_err_id_t reg_id;
8721772Sjl139090
8732509Sschwartz for (reg_id = 0; reg_id < PX_ERR_REG_KEYS; reg_id++, reg_desc_p++) {
8742509Sschwartz if (!(reg_desc_p->chip_mask & chip_mask))
8752509Sschwartz continue;
8763274Set142600
8773274Set142600 if ((block & PX_FM_BLOCK_HOST) &&
8783274Set142600 (reg_desc_p->reg_bank == PX_REG_XBC))
8793274Set142600 csr_base = xbc_csr_base;
8803274Set142600 else if ((block & PX_FM_BLOCK_PCIE) &&
8813274Set142600 (reg_desc_p->reg_bank == PX_REG_CSR))
8823274Set142600 csr_base = pec_csr_base;
8833274Set142600 else {
8843274Set142600 ss_p->err_status[reg_id] = 0;
8853274Set142600 continue;
8863274Set142600 }
8873274Set142600
8883274Set142600 ss_p->err_status[reg_id] = CSR_XR(csr_base,
8893274Set142600 reg_desc_p->status_addr);
89027Sjchu }
89127Sjchu }
89227Sjchu
89327Sjchu /*
89427Sjchu * px_err_erpt_and_clr:
89527Sjchu * This function does the following thing to all the fire registers based
89627Sjchu * on an earlier snap shot.
89727Sjchu * o Send ereport
89827Sjchu * o Handle the error
89927Sjchu * o Clear the error
90027Sjchu *
90127Sjchu * @param px_p leaf in which to take the snap shot.
90227Sjchu * @param derr fm err in which the ereport is to be based on
9032509Sschwartz * @param ss_p pre-allocated memory to store the snap shot.
90427Sjchu */
90527Sjchu static int
px_err_erpt_and_clr(px_t * px_p,ddi_fm_error_t * derr,px_err_ss_t * ss_p)9062509Sschwartz px_err_erpt_and_clr(px_t *px_p, ddi_fm_error_t *derr, px_err_ss_t *ss_p)
90727Sjchu {
90827Sjchu dev_info_t *rpdip = px_p->px_dip;
90927Sjchu pxu_t *pxu_p = (pxu_t *)px_p->px_plat_p;
91027Sjchu caddr_t csr_base;
9112509Sschwartz const px_err_reg_desc_t *err_reg_tbl;
91227Sjchu px_err_bit_desc_t *err_bit_tbl;
91327Sjchu px_err_bit_desc_t *err_bit_desc;
91427Sjchu
9153274Set142600 uint64_t *count_mask;
9163274Set142600 uint64_t clear_addr;
91727Sjchu uint64_t ss_reg;
91827Sjchu
91927Sjchu int (*err_handler)();
92027Sjchu int (*erpt_handler)();
9213274Set142600 int reg_id, key;
9223274Set142600 int err = PX_NO_ERROR;
9233274Set142600 int biterr = 0;
92427Sjchu
9251648Sjchu ASSERT(MUTEX_HELD(&px_p->px_fm_mutex));
92627Sjchu
92727Sjchu /* send erport/handle/clear JBC errors */
9282509Sschwartz for (reg_id = 0; reg_id < PX_ERR_REG_KEYS; reg_id++) {
92927Sjchu /* Get the correct register description table */
93027Sjchu err_reg_tbl = &px_err_reg_tbl[reg_id];
93127Sjchu
9321772Sjl139090 /* Only look at enabled groups. */
9332509Sschwartz if (!(BIT_TST(err_reg_tbl->chip_mask, PX_CHIP_TYPE(pxu_p))))
9341772Sjl139090 continue;
9351772Sjl139090
93627Sjchu /* Get the correct CSR BASE */
9372509Sschwartz csr_base = (caddr_t)pxu_p->px_address[err_reg_tbl->reg_bank];
93827Sjchu
9393274Set142600 /* If there are no errors in this register, continue */
9403274Set142600 ss_reg = ss_p->err_status[reg_id];
9413274Set142600 if (!ss_reg)
9423274Set142600 continue;
9433274Set142600
9443272Sdduvall /* Get pointers to masks and register addresses */
9453272Sdduvall count_mask = err_reg_tbl->count_mask_p;
9463272Sdduvall clear_addr = err_reg_tbl->clear_addr;
94727Sjchu
94827Sjchu /* Get the register BIT description table */
94927Sjchu err_bit_tbl = err_reg_tbl->err_bit_tbl;
95027Sjchu
95127Sjchu /* For each known bit in the register send erpt and handle */
9522509Sschwartz for (key = 0; key < err_reg_tbl->err_bit_keys; key++) {
95327Sjchu /*
95427Sjchu * If the ss_reg is set for this bit,
95527Sjchu * send ereport and handle
95627Sjchu */
9573274Set142600 err_bit_desc = &err_bit_tbl[key];
9583274Set142600 if (!BIT_TST(ss_reg, err_bit_desc->bit))
9593274Set142600 continue;
96027Sjchu
9613274Set142600 /* Increment the counter if necessary */
9623274Set142600 if (BIT_TST(*count_mask, err_bit_desc->bit)) {
9633274Set142600 err_bit_desc->counter++;
9643274Set142600 }
96527Sjchu
9663274Set142600 /* Error Handle for this bit */
9673274Set142600 err_handler = err_bit_desc->err_handler;
9683274Set142600 if (err_handler) {
9693274Set142600 biterr = err_handler(rpdip, csr_base, derr,
9703274Set142600 err_reg_tbl, err_bit_desc);
9713274Set142600 err |= biterr;
97227Sjchu }
9733274Set142600
9743274Set142600 /*
9753274Set142600 * Send the ereport if it's an UNEXPECTED err.
9763274Set142600 * This is the only place where PX_EXPECTED is utilized.
9773274Set142600 */
9783274Set142600 erpt_handler = err_bit_desc->erpt_handler;
9793274Set142600 if ((derr->fme_flag != DDI_FM_ERR_UNEXPECTED) ||
9803274Set142600 (biterr == PX_EXPECTED))
9813274Set142600 continue;
9823274Set142600
9833274Set142600 if (erpt_handler)
9843274Set142600 (void) erpt_handler(rpdip, csr_base, ss_reg,
9853274Set142600 derr, err_bit_desc->bit,
9863274Set142600 err_bit_desc->class_name);
98727Sjchu }
98827Sjchu
98927Sjchu /* Clear the register and error */
99027Sjchu CSR_XS(csr_base, clear_addr, ss_reg);
99127Sjchu }
99227Sjchu
99327Sjchu return (err);
99427Sjchu }
99527Sjchu
99627Sjchu /*
99727Sjchu * px_err_check_severity:
99827Sjchu * Check the severity of the fire error based on an earlier snapshot
99927Sjchu *
100027Sjchu * @param px_p leaf in which to take the snap shot.
100127Sjchu * @param derr fm err in which the ereport is to be based on
10022509Sschwartz * @param err fire register error status
10032509Sschwartz * @param caller PX_TRAP_CALL | PX_INTR_CALL | PX_LIB_CALL
100427Sjchu */
100527Sjchu static int
px_err_check_severity(px_t * px_p,ddi_fm_error_t * derr,int err,int caller)100627Sjchu px_err_check_severity(px_t *px_p, ddi_fm_error_t *derr, int err, int caller)
100727Sjchu {
100827Sjchu px_pec_t *pec_p = px_p->px_pec_p;
100927Sjchu boolean_t is_safeacc = B_FALSE;
1010118Sjchu
10113274Set142600 /*
10123274Set142600 * Nothing to do if called with no error.
10133274Set142600 * The err could have already been set to PX_NO_PANIC, which means the
10143274Set142600 * system doesn't need to panic, but PEEK/POKE still failed.
10153274Set142600 */
10163274Set142600 if (err == PX_NO_ERROR)
1017118Sjchu return (err);
101827Sjchu
101927Sjchu /* Cautious access error handling */
102027Sjchu switch (derr->fme_flag) {
102127Sjchu case DDI_FM_ERR_EXPECTED:
102227Sjchu if (caller == PX_TRAP_CALL) {
102327Sjchu /*
102427Sjchu * for ddi_caut_get treat all events as nonfatal
102527Sjchu * The trampoline will set err_ena = 0,
102627Sjchu * err_status = NONFATAL.
102727Sjchu */
102827Sjchu derr->fme_status = DDI_FM_NONFATAL;
102927Sjchu is_safeacc = B_TRUE;
103027Sjchu } else {
103127Sjchu /*
103227Sjchu * For ddi_caut_put treat all events as nonfatal. Here
103327Sjchu * we have the handle and can call ndi_fm_acc_err_set().
103427Sjchu */
103527Sjchu derr->fme_status = DDI_FM_NONFATAL;
103627Sjchu ndi_fm_acc_err_set(pec_p->pec_acc_hdl, derr);
103727Sjchu is_safeacc = B_TRUE;
103827Sjchu }
103927Sjchu break;
104027Sjchu case DDI_FM_ERR_PEEK:
104127Sjchu case DDI_FM_ERR_POKE:
104227Sjchu /*
104327Sjchu * For ddi_peek/poke treat all events as nonfatal.
104427Sjchu */
104527Sjchu is_safeacc = B_TRUE;
104627Sjchu break;
104727Sjchu default:
104827Sjchu is_safeacc = B_FALSE;
104927Sjchu }
105027Sjchu
10513274Set142600 /* re-adjust error status from safe access, forgive all errors */
10523274Set142600 if (is_safeacc)
10533274Set142600 return (PX_NO_PANIC);
105427Sjchu
1055118Sjchu return (err);
105627Sjchu }
105727Sjchu
105827Sjchu /* predefined convenience functions */
105927Sjchu /* ARGSUSED */
10603274Set142600 void
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)10613274Set142600 px_err_log_handle(dev_info_t *rpdip, px_err_reg_desc_t *err_reg_descr,
10623274Set142600 px_err_bit_desc_t *err_bit_descr, char *msg)
106327Sjchu {
10643274Set142600 DBG(DBG_ERR_INTR, rpdip,
10653274Set142600 "Bit %d, %s, at %s(0x%x) has occured %d times with a severity "
10663274Set142600 "of \"%s\"\n",
10673274Set142600 err_bit_descr->bit, err_bit_descr->class_name,
10683274Set142600 err_reg_descr->msg, err_reg_descr->status_addr,
10693274Set142600 err_bit_descr->counter, msg);
107027Sjchu }
107127Sjchu
107227Sjchu /* ARGSUSED */
107327Sjchu int
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)10743274Set142600 px_err_hw_reset_handle(dev_info_t *rpdip, caddr_t csr_base,
107527Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
107627Sjchu px_err_bit_desc_t *err_bit_descr)
107727Sjchu {
10783274Set142600 if (px_log & PX_HW_RESET) {
10793274Set142600 px_err_log_handle(rpdip, err_reg_descr, err_bit_descr,
10803274Set142600 "HW RESET");
10813274Set142600 }
108227Sjchu
10833274Set142600 return (PX_HW_RESET);
108427Sjchu }
108527Sjchu
108627Sjchu /* ARGSUSED */
108727Sjchu int
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)10883274Set142600 px_err_panic_handle(dev_info_t *rpdip, caddr_t csr_base,
108927Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
109027Sjchu px_err_bit_desc_t *err_bit_descr)
109127Sjchu {
10923274Set142600 if (px_log & PX_PANIC) {
10933274Set142600 px_err_log_handle(rpdip, err_reg_descr, err_bit_descr, "PANIC");
10943274Set142600 }
10953274Set142600
10963274Set142600 return (PX_PANIC);
109727Sjchu }
109827Sjchu
109927Sjchu /* ARGSUSED */
110027Sjchu int
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)11013274Set142600 px_err_protected_handle(dev_info_t *rpdip, caddr_t csr_base,
110227Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
110327Sjchu px_err_bit_desc_t *err_bit_descr)
110427Sjchu {
11053274Set142600 if (px_log & PX_PROTECTED) {
11063274Set142600 px_err_log_handle(rpdip, err_reg_descr, err_bit_descr,
11073274Set142600 "PROTECTED");
11083274Set142600 }
11093274Set142600
11103274Set142600 return (PX_PROTECTED);
111127Sjchu }
111227Sjchu
111327Sjchu /* ARGSUSED */
111427Sjchu int
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)11153274Set142600 px_err_no_panic_handle(dev_info_t *rpdip, caddr_t csr_base,
11163274Set142600 ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
11173274Set142600 px_err_bit_desc_t *err_bit_descr)
111827Sjchu {
11193274Set142600 if (px_log & PX_NO_PANIC) {
11203274Set142600 px_err_log_handle(rpdip, err_reg_descr, err_bit_descr,
11213274Set142600 "NO PANIC");
11223274Set142600 }
11233274Set142600
11243274Set142600 return (PX_NO_PANIC);
112527Sjchu }
112627Sjchu
112727Sjchu /* ARGSUSED */
112827Sjchu int
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)11293274Set142600 px_err_no_error_handle(dev_info_t *rpdip, caddr_t csr_base,
11303274Set142600 ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
11313274Set142600 px_err_bit_desc_t *err_bit_descr)
113227Sjchu {
11333274Set142600 if (px_log & PX_NO_ERROR) {
11343274Set142600 px_err_log_handle(rpdip, err_reg_descr, err_bit_descr,
11353274Set142600 "NO ERROR");
11363274Set142600 }
11373274Set142600
11383274Set142600 return (PX_NO_ERROR);
113927Sjchu }
114027Sjchu
1141383Set142600 /* ARGSUSED */
PX_ERPT_SEND_DEC(do_not)1142383Set142600 PX_ERPT_SEND_DEC(do_not)
1143383Set142600 {
11443274Set142600 return (PX_NO_ERROR);
1145383Set142600 }
1146383Set142600
11475168Sarutz /*
11485168Sarutz * Search the px_cb_list_t embedded in the px_cb_t for the
11495168Sarutz * px_t of the specified Leaf (leaf_id). Return its associated dip.
11505168Sarutz */
11515168Sarutz static dev_info_t *
px_err_search_cb(px_cb_t * px_cb_p,uint_t leaf_id)11525168Sarutz px_err_search_cb(px_cb_t *px_cb_p, uint_t leaf_id)
11535168Sarutz {
11545168Sarutz int i;
11555168Sarutz px_cb_list_t *pxl_elemp;
11565168Sarutz
11575168Sarutz for (i = px_cb_p->attachcnt, pxl_elemp = px_cb_p->pxl; i > 0;
11585168Sarutz i--, pxl_elemp = pxl_elemp->next) {
11595168Sarutz if ((((pxu_t *)pxl_elemp->pxp->px_plat_p)->portid &
11605168Sarutz OBERON_PORT_ID_LEAF_MASK) == leaf_id) {
11615168Sarutz return (pxl_elemp->pxp->px_dip);
11625168Sarutz }
11635168Sarutz }
11645168Sarutz return (NULL);
11655168Sarutz }
11663274Set142600
11671772Sjl139090 /* UBC FATAL - see io erpt doc, section 1.1 */
11681772Sjl139090 /* ARGSUSED */
PX_ERPT_SEND_DEC(ubc_fatal)11691772Sjl139090 PX_ERPT_SEND_DEC(ubc_fatal)
11701772Sjl139090 {
11711772Sjl139090 char buf[FM_MAX_CLASS];
11721772Sjl139090 uint64_t memory_ue_log, marked;
11731772Sjl139090 char unum[FM_MAX_CLASS];
11741772Sjl139090 int unum_length;
11751772Sjl139090 uint64_t device_id = 0;
11761772Sjl139090 uint8_t cpu_version = 0;
11771772Sjl139090 nvlist_t *resource = NULL;
11785168Sarutz uint64_t ubc_intr_status;
11795168Sarutz px_t *px_p;
11805168Sarutz px_cb_t *px_cb_p;
11815168Sarutz dev_info_t *actual_dip;
11821772Sjl139090
11831772Sjl139090 unum[0] = '\0';
11841772Sjl139090 (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
11851772Sjl139090
11861772Sjl139090 memory_ue_log = CSR_XR(csr_base, UBC_MEMORY_UE_LOG);
11871772Sjl139090 marked = (memory_ue_log >> UBC_MEMORY_UE_LOG_MARKED) &
11881772Sjl139090 UBC_MEMORY_UE_LOG_MARKED_MASK;
11891772Sjl139090
11901772Sjl139090 if ((strstr(class_name, "ubc.piowtue") != NULL) ||
11911772Sjl139090 (strstr(class_name, "ubc.piowbeue") != NULL) ||
11921772Sjl139090 (strstr(class_name, "ubc.piorbeue") != NULL) ||
11931772Sjl139090 (strstr(class_name, "ubc.dmarduea") != NULL) ||
11941772Sjl139090 (strstr(class_name, "ubc.dmardueb") != NULL)) {
11951772Sjl139090 int eid = (memory_ue_log >> UBC_MEMORY_UE_LOG_EID) &
11961772Sjl139090 UBC_MEMORY_UE_LOG_EID_MASK;
11971772Sjl139090 (void) strncat(buf, ubc_class_eid_qualifier[eid],
11981772Sjl139090 FM_MAX_CLASS);
11991772Sjl139090
12001772Sjl139090 if (eid == UBC_EID_MEM) {
12011772Sjl139090 uint64_t phys_addr = memory_ue_log &
12021772Sjl139090 MMU_OBERON_PADDR_MASK;
12031772Sjl139090 uint64_t offset = (uint64_t)-1;
12041772Sjl139090
12051772Sjl139090 resource = fm_nvlist_create(NULL);
12061772Sjl139090 if (&plat_get_mem_unum) {
12071772Sjl139090 if ((plat_get_mem_unum(0,
12081772Sjl139090 phys_addr, 0, B_TRUE, 0, unum,
12091772Sjl139090 FM_MAX_CLASS, &unum_length)) != 0)
12101772Sjl139090 unum[0] = '\0';
12111772Sjl139090 }
12121772Sjl139090 fm_fmri_mem_set(resource, FM_MEM_SCHEME_VERSION,
12134853Segillett NULL, unum, NULL, offset);
12141772Sjl139090
12151772Sjl139090 } else if (eid == UBC_EID_CPU) {
12161772Sjl139090 int cpuid = (marked & UBC_MARKED_MAX_CPUID_MASK);
12171772Sjl139090 char sbuf[21]; /* sizeof (UINT64_MAX) + '\0' */
12181772Sjl139090
12191772Sjl139090 resource = fm_nvlist_create(NULL);
12201772Sjl139090 cpu_version = cpunodes[cpuid].version;
12211772Sjl139090 device_id = cpunodes[cpuid].device_id;
12221772Sjl139090 (void) snprintf(sbuf, sizeof (sbuf), "%lX",
12231772Sjl139090 device_id);
12241772Sjl139090 (void) fm_fmri_cpu_set(resource,
12251772Sjl139090 FM_CPU_SCHEME_VERSION, NULL, cpuid,
12261772Sjl139090 &cpu_version, sbuf);
12271772Sjl139090 }
12281772Sjl139090 }
12291772Sjl139090
12305168Sarutz /*
12315168Sarutz * For most of the errors represented in the UBC Interrupt Status
12325168Sarutz * register, one can compute the dip of the actual Leaf that was
12335168Sarutz * involved in the error. To do this, find the px_cb_t structure
12345168Sarutz * that is shared between a pair of Leaves (eg, LeafA and LeafB).
12355168Sarutz *
12365168Sarutz * If any of the error bits for LeafA are set in the hardware
12375168Sarutz * register, search the list of px_t's rooted in the px_cb_t for
12385168Sarutz * the one corresponding to LeafA. If error bits for LeafB are set,
12395168Sarutz * search the list for LeafB's px_t. The px_t references its
12405168Sarutz * associated dip.
12415168Sarutz */
12425168Sarutz px_p = DIP_TO_STATE(rpdip);
12435168Sarutz px_cb_p = ((pxu_t *)px_p->px_plat_p)->px_cb_p;
12445168Sarutz
12455168Sarutz /* read hardware register */
12465168Sarutz ubc_intr_status = CSR_XR(csr_base, UBC_INTERRUPT_STATUS);
12475168Sarutz
12485168Sarutz if ((ubc_intr_status & UBC_INTERRUPT_STATUS_LEAFA) != 0) {
12495168Sarutz /* then Leaf A is involved in the error */
12505168Sarutz actual_dip = px_err_search_cb(px_cb_p, OBERON_PORT_ID_LEAF_A);
12515168Sarutz ASSERT(actual_dip != NULL);
12525168Sarutz rpdip = actual_dip;
12535168Sarutz } else if ((ubc_intr_status & UBC_INTERRUPT_STATUS_LEAFB) != 0) {
12545168Sarutz /* then Leaf B is involved in the error */
12555168Sarutz actual_dip = px_err_search_cb(px_cb_p, OBERON_PORT_ID_LEAF_B);
12565168Sarutz ASSERT(actual_dip != NULL);
12575168Sarutz rpdip = actual_dip;
12585168Sarutz } /* else error cannot be associated with a Leaf */
12595168Sarutz
12601772Sjl139090 if (resource) {
12611772Sjl139090 ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
12621772Sjl139090 DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
12631772Sjl139090 FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, B_TRUE,
12641772Sjl139090 OBERON_UBC_ELE, DATA_TYPE_UINT64,
12651772Sjl139090 CSR_XR(csr_base, UBC_ERROR_LOG_ENABLE),
12661772Sjl139090 OBERON_UBC_IE, DATA_TYPE_UINT64,
12671772Sjl139090 CSR_XR(csr_base, UBC_INTERRUPT_ENABLE),
12685168Sarutz OBERON_UBC_IS, DATA_TYPE_UINT64, ubc_intr_status,
12691772Sjl139090 OBERON_UBC_ESS, DATA_TYPE_UINT64,
12701772Sjl139090 CSR_XR(csr_base, UBC_ERROR_STATUS_SET),
12711772Sjl139090 OBERON_UBC_MUE, DATA_TYPE_UINT64, memory_ue_log,
12721772Sjl139090 OBERON_UBC_UNUM, DATA_TYPE_STRING, unum,
12731772Sjl139090 OBERON_UBC_DID, DATA_TYPE_UINT64, device_id,
12741772Sjl139090 OBERON_UBC_CPUV, DATA_TYPE_UINT32, cpu_version,
12751772Sjl139090 OBERON_UBC_RESOURCE, DATA_TYPE_NVLIST, resource,
12761772Sjl139090 NULL);
12771772Sjl139090 fm_nvlist_destroy(resource, FM_NVA_FREE);
12781772Sjl139090 } else {
12791772Sjl139090 ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
12801772Sjl139090 DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
12811772Sjl139090 FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, B_TRUE,
12821772Sjl139090 OBERON_UBC_ELE, DATA_TYPE_UINT64,
12831772Sjl139090 CSR_XR(csr_base, UBC_ERROR_LOG_ENABLE),
12841772Sjl139090 OBERON_UBC_IE, DATA_TYPE_UINT64,
12851772Sjl139090 CSR_XR(csr_base, UBC_INTERRUPT_ENABLE),
12865168Sarutz OBERON_UBC_IS, DATA_TYPE_UINT64, ubc_intr_status,
12871772Sjl139090 OBERON_UBC_ESS, DATA_TYPE_UINT64,
12881772Sjl139090 CSR_XR(csr_base, UBC_ERROR_STATUS_SET),
12891772Sjl139090 OBERON_UBC_MUE, DATA_TYPE_UINT64, memory_ue_log,
12901772Sjl139090 OBERON_UBC_UNUM, DATA_TYPE_STRING, unum,
12911772Sjl139090 OBERON_UBC_DID, DATA_TYPE_UINT64, device_id,
12921772Sjl139090 OBERON_UBC_CPUV, DATA_TYPE_UINT32, cpu_version,
12931772Sjl139090 NULL);
12941772Sjl139090 }
12951772Sjl139090
12963274Set142600 return (PX_NO_PANIC);
12971772Sjl139090 }
1298383Set142600
12993274Set142600 /* JBC FATAL */
PX_ERPT_SEND_DEC(jbc_fatal)130027Sjchu PX_ERPT_SEND_DEC(jbc_fatal)
130127Sjchu {
130227Sjchu char buf[FM_MAX_CLASS];
1303739Sjchu boolean_t pri = PX_ERR_IS_PRI(bit);
130427Sjchu
130527Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
130627Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
130727Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
1308739Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
130927Sjchu FIRE_JBC_ELE, DATA_TYPE_UINT64,
131027Sjchu CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE),
131127Sjchu FIRE_JBC_IE, DATA_TYPE_UINT64,
131227Sjchu CSR_XR(csr_base, JBC_INTERRUPT_ENABLE),
131327Sjchu FIRE_JBC_IS, DATA_TYPE_UINT64,
131427Sjchu ss_reg,
131527Sjchu FIRE_JBC_ESS, DATA_TYPE_UINT64,
131627Sjchu CSR_XR(csr_base, JBC_ERROR_STATUS_SET),
131727Sjchu FIRE_JBC_FEL1, DATA_TYPE_UINT64,
131827Sjchu CSR_XR(csr_base, FATAL_ERROR_LOG_1),
131927Sjchu FIRE_JBC_FEL2, DATA_TYPE_UINT64,
132027Sjchu CSR_XR(csr_base, FATAL_ERROR_LOG_2),
132127Sjchu NULL);
132227Sjchu
13233274Set142600 return (PX_NO_PANIC);
132427Sjchu }
132527Sjchu
13263274Set142600 /* JBC MERGE */
PX_ERPT_SEND_DEC(jbc_merge)132727Sjchu PX_ERPT_SEND_DEC(jbc_merge)
132827Sjchu {
132927Sjchu char buf[FM_MAX_CLASS];
1330739Sjchu boolean_t pri = PX_ERR_IS_PRI(bit);
133127Sjchu
133227Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
133327Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
133427Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
1335739Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
133627Sjchu FIRE_JBC_ELE, DATA_TYPE_UINT64,
133727Sjchu CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE),
133827Sjchu FIRE_JBC_IE, DATA_TYPE_UINT64,
133927Sjchu CSR_XR(csr_base, JBC_INTERRUPT_ENABLE),
134027Sjchu FIRE_JBC_IS, DATA_TYPE_UINT64,
134127Sjchu ss_reg,
134227Sjchu FIRE_JBC_ESS, DATA_TYPE_UINT64,
134327Sjchu CSR_XR(csr_base, JBC_ERROR_STATUS_SET),
134427Sjchu FIRE_JBC_MTEL, DATA_TYPE_UINT64,
134527Sjchu CSR_XR(csr_base, MERGE_TRANSACTION_ERROR_LOG),
134627Sjchu NULL);
134727Sjchu
13483274Set142600 return (PX_NO_PANIC);
134927Sjchu }
135027Sjchu
135127Sjchu /*
13523274Set142600 * JBC Merge buffer retryable errors:
13533274Set142600 * Merge buffer parity error (rd_buf): PIO or DMA
13543274Set142600 * Merge buffer parity error (wr_buf): PIO or DMA
135527Sjchu */
135627Sjchu /* ARGSUSED */
135727Sjchu 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)135827Sjchu px_err_jbc_merge_handle(dev_info_t *rpdip, caddr_t csr_base,
13593274Set142600 ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
13603274Set142600 px_err_bit_desc_t *err_bit_descr)
136127Sjchu {
13623274Set142600 /*
13633274Set142600 * Holder function to attempt error recovery. When the features
13643274Set142600 * are in place, look up the address of the transaction in:
13653274Set142600 *
13663274Set142600 * paddr = CSR_XR(csr_base, MERGE_TRANSACTION_ERROR_LOG);
13673274Set142600 * paddr &= MERGE_TRANSACTION_ERROR_LOG_ADDRESS_MASK;
13683274Set142600 *
13693274Set142600 * If the error is a secondary error, there is no log information
13703274Set142600 * just panic as it is unknown which address has been affected.
13713274Set142600 *
13723274Set142600 * Remember the address is pretranslation and might be hard to look
13733274Set142600 * up the appropriate driver based on the PA.
13743274Set142600 */
13753274Set142600 return (px_err_panic_handle(rpdip, csr_base, derr, err_reg_descr,
13764853Segillett err_bit_descr));
137727Sjchu }
137827Sjchu
13793274Set142600 /* JBC Jbusint IN */
PX_ERPT_SEND_DEC(jbc_in)138027Sjchu PX_ERPT_SEND_DEC(jbc_in)
138127Sjchu {
138227Sjchu char buf[FM_MAX_CLASS];
1383739Sjchu boolean_t pri = PX_ERR_IS_PRI(bit);
138427Sjchu
138527Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
138627Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
138727Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
1388739Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
138927Sjchu FIRE_JBC_ELE, DATA_TYPE_UINT64,
139027Sjchu CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE),
139127Sjchu FIRE_JBC_IE, DATA_TYPE_UINT64,
139227Sjchu CSR_XR(csr_base, JBC_INTERRUPT_ENABLE),
139327Sjchu FIRE_JBC_IS, DATA_TYPE_UINT64,
139427Sjchu ss_reg,
139527Sjchu FIRE_JBC_ESS, DATA_TYPE_UINT64,
139627Sjchu CSR_XR(csr_base, JBC_ERROR_STATUS_SET),
139727Sjchu FIRE_JBC_JITEL1, DATA_TYPE_UINT64,
139827Sjchu CSR_XR(csr_base, JBCINT_IN_TRANSACTION_ERROR_LOG),
139927Sjchu FIRE_JBC_JITEL2, DATA_TYPE_UINT64,
140027Sjchu CSR_XR(csr_base, JBCINT_IN_TRANSACTION_ERROR_LOG_2),
140127Sjchu NULL);
140227Sjchu
14033274Set142600 return (PX_NO_PANIC);
140427Sjchu }
140527Sjchu
140627Sjchu /*
14073274Set142600 * JBC Jbusint IN retryable errors
140827Sjchu * Log Reg[42:0].
14093274Set142600 * Write Data Parity Error: PIO Writes
14103274Set142600 * Read Data Parity Error: DMA Reads
141127Sjchu */
141227Sjchu 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)141327Sjchu px_err_jbc_jbusint_in_handle(dev_info_t *rpdip, caddr_t csr_base,
141427Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
141527Sjchu px_err_bit_desc_t *err_bit_descr)
141627Sjchu {
14173274Set142600 /*
14183274Set142600 * Holder function to attempt error recovery. When the features
14193274Set142600 * are in place, look up the address of the transaction in:
14203274Set142600 *
14213274Set142600 * paddr = CSR_XR(csr_base, JBCINT_IN_TRANSACTION_ERROR_LOG);
14223274Set142600 * paddr &= JBCINT_IN_TRANSACTION_ERROR_LOG_ADDRESS_MASK;
14233274Set142600 *
14243274Set142600 * If the error is a secondary error, there is no log information
14253274Set142600 * just panic as it is unknown which address has been affected.
14263274Set142600 *
14273274Set142600 * Remember the address is pretranslation and might be hard to look
14283274Set142600 * up the appropriate driver based on the PA.
14293274Set142600 */
14303274Set142600 return (px_err_panic_handle(rpdip, csr_base, derr, err_reg_descr,
14314853Segillett err_bit_descr));
143227Sjchu }
143327Sjchu
143427Sjchu
14353274Set142600 /* JBC Jbusint Out */
PX_ERPT_SEND_DEC(jbc_out)143627Sjchu PX_ERPT_SEND_DEC(jbc_out)
143727Sjchu {
143827Sjchu char buf[FM_MAX_CLASS];
1439739Sjchu boolean_t pri = PX_ERR_IS_PRI(bit);
144027Sjchu
144127Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
144227Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
144327Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
1444739Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
144527Sjchu FIRE_JBC_ELE, DATA_TYPE_UINT64,
144627Sjchu CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE),
144727Sjchu FIRE_JBC_IE, DATA_TYPE_UINT64,
144827Sjchu CSR_XR(csr_base, JBC_INTERRUPT_ENABLE),
144927Sjchu FIRE_JBC_IS, DATA_TYPE_UINT64,
145027Sjchu ss_reg,
145127Sjchu FIRE_JBC_ESS, DATA_TYPE_UINT64,
145227Sjchu CSR_XR(csr_base, JBC_ERROR_STATUS_SET),
145327Sjchu FIRE_JBC_JOTEL1, DATA_TYPE_UINT64,
145427Sjchu CSR_XR(csr_base, JBCINT_OUT_TRANSACTION_ERROR_LOG),
145527Sjchu FIRE_JBC_JOTEL2, DATA_TYPE_UINT64,
145627Sjchu CSR_XR(csr_base, JBCINT_OUT_TRANSACTION_ERROR_LOG_2),
145727Sjchu NULL);
145827Sjchu
14593274Set142600 return (PX_NO_PANIC);
146027Sjchu }
146127Sjchu
14623274Set142600 /* JBC Dmcint ODCD */
PX_ERPT_SEND_DEC(jbc_odcd)146327Sjchu PX_ERPT_SEND_DEC(jbc_odcd)
146427Sjchu {
146527Sjchu char buf[FM_MAX_CLASS];
1466739Sjchu boolean_t pri = PX_ERR_IS_PRI(bit);
146727Sjchu
146827Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
146927Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
147027Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
1471739Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
147227Sjchu FIRE_JBC_ELE, DATA_TYPE_UINT64,
147327Sjchu CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE),
147427Sjchu FIRE_JBC_IE, DATA_TYPE_UINT64,
147527Sjchu CSR_XR(csr_base, JBC_INTERRUPT_ENABLE),
147627Sjchu FIRE_JBC_IS, DATA_TYPE_UINT64,
147727Sjchu ss_reg,
147827Sjchu FIRE_JBC_ESS, DATA_TYPE_UINT64,
147927Sjchu CSR_XR(csr_base, JBC_ERROR_STATUS_SET),
148027Sjchu FIRE_JBC_DMC_ODCD, DATA_TYPE_UINT64,
148127Sjchu CSR_XR(csr_base, DMCINT_ODCD_ERROR_LOG),
148227Sjchu NULL);
148327Sjchu
14843274Set142600 return (PX_NO_PANIC);
148527Sjchu }
148627Sjchu
148727Sjchu /*
148827Sjchu * JBC Dmcint ODCO nonfatal errer handling -
14893274Set142600 * PIO data parity error: PIO
149027Sjchu */
149127Sjchu /* ARGSUSED */
149227Sjchu 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)149327Sjchu px_err_jbc_dmcint_odcd_handle(dev_info_t *rpdip, caddr_t csr_base,
149427Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
149527Sjchu px_err_bit_desc_t *err_bit_descr)
149627Sjchu {
14973274Set142600 /*
14983274Set142600 * Holder function to attempt error recovery. When the features
14993274Set142600 * are in place, look up the address of the transaction in:
15003274Set142600 *
15013274Set142600 * paddr = CSR_XR(csr_base, DMCINT_ODCD_ERROR_LOG);
15023274Set142600 * paddr &= DMCINT_ODCD_ERROR_LOG_ADDRESS_MASK;
15033274Set142600 *
15043274Set142600 * If the error is a secondary error, there is no log information
15053274Set142600 * just panic as it is unknown which address has been affected.
15063274Set142600 *
15073274Set142600 * Remember the address is pretranslation and might be hard to look
15083274Set142600 * up the appropriate driver based on the PA.
15093274Set142600 */
15103274Set142600 return (px_err_panic_handle(rpdip, csr_base, derr, err_reg_descr,
15114853Segillett err_bit_descr));
151227Sjchu }
151327Sjchu
15142276Sschwartz /* Does address in DMCINT error log register match address of pcitool access? */
15152276Sschwartz static boolean_t
px_jbc_pcitool_addr_match(dev_info_t * rpdip,caddr_t csr_base)15162276Sschwartz px_jbc_pcitool_addr_match(dev_info_t *rpdip, caddr_t csr_base)
15172276Sschwartz {
15182276Sschwartz px_t *px_p = DIP_TO_STATE(rpdip);
15192276Sschwartz pxu_t *pxu_p = (pxu_t *)px_p->px_plat_p;
15202276Sschwartz caddr_t pcitool_addr = pxu_p->pcitool_addr;
15212276Sschwartz caddr_t errlog_addr =
15222276Sschwartz (caddr_t)CSR_FR(csr_base, DMCINT_ODCD_ERROR_LOG, ADDRESS);
15232276Sschwartz
15242276Sschwartz return (pcitool_addr == errlog_addr);
15252276Sschwartz }
15262276Sschwartz
15272276Sschwartz /*
15282276Sschwartz * JBC Dmcint ODCD errer handling for errors which are forgivable during a safe
15292276Sschwartz * access. (This will be most likely be a PCItool access.) If not a safe
15302276Sschwartz * access context, treat like jbc_dmcint_odcd.
15312276Sschwartz * Unmapped PIO read error: pio:read:M:nonfatal
15322276Sschwartz * Unmapped PIO write error: pio:write:M:nonfatal
15332276Sschwartz * Invalid PIO write to PCIe cfg/io, csr, ebus or i2c bus: pio:write:nonfatal
15342276Sschwartz * Invalid PIO read to PCIe cfg/io, csr, ebus or i2c bus: pio:read:nonfatal
15352276Sschwartz */
15362276Sschwartz /* ARGSUSED */
15372276Sschwartz 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)15382276Sschwartz px_err_jbc_safe_acc_handle(dev_info_t *rpdip, caddr_t csr_base,
15392276Sschwartz ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
15402276Sschwartz px_err_bit_desc_t *err_bit_descr)
15412276Sschwartz {
15422276Sschwartz boolean_t pri = PX_ERR_IS_PRI(err_bit_descr->bit);
15432276Sschwartz
15442276Sschwartz if (!pri)
15453274Set142600 return (px_err_panic_handle(rpdip, csr_base, derr,
15464853Segillett err_reg_descr, err_bit_descr));
15472276Sschwartz /*
15482276Sschwartz * Got an error which is forgivable during a PCItool access.
15492276Sschwartz *
15502276Sschwartz * Don't do handler check since the error may otherwise be unfairly
15512276Sschwartz * attributed to a device. Just return.
15522276Sschwartz *
15532276Sschwartz * Note: There is a hole here in that a legitimate error can come in
15542276Sschwartz * while a PCItool access is in play and be forgiven. This is possible
15552276Sschwartz * though not likely.
15562276Sschwartz */
15572276Sschwartz if ((derr->fme_flag != DDI_FM_ERR_UNEXPECTED) &&
15582276Sschwartz (px_jbc_pcitool_addr_match(rpdip, csr_base)))
15593274Set142600 return (px_err_protected_handle(rpdip, csr_base, derr,
15604853Segillett err_reg_descr, err_bit_descr));
15612276Sschwartz
15622276Sschwartz return (px_err_jbc_dmcint_odcd_handle(rpdip, csr_base, derr,
15632276Sschwartz err_reg_descr, err_bit_descr));
15642276Sschwartz }
15652276Sschwartz
15663274Set142600 /* JBC Dmcint IDC */
PX_ERPT_SEND_DEC(jbc_idc)156727Sjchu PX_ERPT_SEND_DEC(jbc_idc)
156827Sjchu {
156927Sjchu char buf[FM_MAX_CLASS];
1570739Sjchu boolean_t pri = PX_ERR_IS_PRI(bit);
157127Sjchu
157227Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
157327Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
157427Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
1575739Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
157627Sjchu FIRE_JBC_ELE, DATA_TYPE_UINT64,
157727Sjchu CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE),
157827Sjchu FIRE_JBC_IE, DATA_TYPE_UINT64,
157927Sjchu CSR_XR(csr_base, JBC_INTERRUPT_ENABLE),
158027Sjchu FIRE_JBC_IS, DATA_TYPE_UINT64,
158127Sjchu ss_reg,
158227Sjchu FIRE_JBC_ESS, DATA_TYPE_UINT64,
158327Sjchu CSR_XR(csr_base, JBC_ERROR_STATUS_SET),
158427Sjchu FIRE_JBC_DMC_IDC, DATA_TYPE_UINT64,
158527Sjchu CSR_XR(csr_base, DMCINT_IDC_ERROR_LOG),
158627Sjchu NULL);
158727Sjchu
15883274Set142600 return (PX_NO_PANIC);
158927Sjchu }
159027Sjchu
15913274Set142600 /* JBC CSR */
PX_ERPT_SEND_DEC(jbc_csr)159227Sjchu PX_ERPT_SEND_DEC(jbc_csr)
159327Sjchu {
159427Sjchu char buf[FM_MAX_CLASS];
1595739Sjchu boolean_t pri = PX_ERR_IS_PRI(bit);
159627Sjchu
159727Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
159827Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
159927Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
1600739Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
160127Sjchu FIRE_JBC_ELE, DATA_TYPE_UINT64,
160227Sjchu CSR_XR(csr_base, JBC_ERROR_LOG_ENABLE),
160327Sjchu FIRE_JBC_IE, DATA_TYPE_UINT64,
160427Sjchu CSR_XR(csr_base, JBC_INTERRUPT_ENABLE),
160527Sjchu FIRE_JBC_IS, DATA_TYPE_UINT64,
160627Sjchu ss_reg,
160727Sjchu FIRE_JBC_ESS, DATA_TYPE_UINT64,
160827Sjchu CSR_XR(csr_base, JBC_ERROR_STATUS_SET),
160927Sjchu "jbc-error-reg", DATA_TYPE_UINT64,
161027Sjchu CSR_XR(csr_base, CSR_ERROR_LOG),
161127Sjchu NULL);
161227Sjchu
16133274Set142600 return (PX_NO_PANIC);
161427Sjchu }
161527Sjchu
16163274Set142600 /* DMC IMU RDS */
PX_ERPT_SEND_DEC(imu_rds)161727Sjchu PX_ERPT_SEND_DEC(imu_rds)
161827Sjchu {
161927Sjchu char buf[FM_MAX_CLASS];
1620739Sjchu boolean_t pri = PX_ERR_IS_PRI(bit);
162127Sjchu
162227Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
162327Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
162427Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
1625739Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
162627Sjchu FIRE_IMU_ELE, DATA_TYPE_UINT64,
162727Sjchu CSR_XR(csr_base, IMU_ERROR_LOG_ENABLE),
162827Sjchu FIRE_IMU_IE, DATA_TYPE_UINT64,
162927Sjchu CSR_XR(csr_base, IMU_INTERRUPT_ENABLE),
163027Sjchu FIRE_IMU_IS, DATA_TYPE_UINT64,
163127Sjchu ss_reg,
163227Sjchu FIRE_IMU_ESS, DATA_TYPE_UINT64,
163327Sjchu CSR_XR(csr_base, IMU_ERROR_STATUS_SET),
163427Sjchu FIRE_IMU_RDS, DATA_TYPE_UINT64,
163527Sjchu CSR_XR(csr_base, IMU_RDS_ERROR_LOG),
163627Sjchu NULL);
163727Sjchu
16383274Set142600 return (PX_NO_PANIC);
1639118Sjchu }
1640118Sjchu
164127Sjchu /* handle EQ overflow */
164227Sjchu /* ARGSUSED */
164327Sjchu 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)164427Sjchu px_err_imu_eq_ovfl_handle(dev_info_t *rpdip, caddr_t csr_base,
164527Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
164627Sjchu px_err_bit_desc_t *err_bit_descr)
164727Sjchu {
16483274Set142600 px_t *px_p = DIP_TO_STATE(rpdip);
16493274Set142600 pxu_t *pxu_p = (pxu_t *)px_p->px_plat_p;
16503274Set142600 int err = px_err_check_eq(rpdip);
165127Sjchu
16523274Set142600 if ((err == PX_PANIC) && (pxu_p->cpr_flag == PX_NOT_CPR)) {
16533274Set142600 return (px_err_panic_handle(rpdip, csr_base, derr,
16544853Segillett err_reg_descr, err_bit_descr));
16553274Set142600 } else {
16563274Set142600 return (px_err_no_panic_handle(rpdip, csr_base, derr,
16574853Segillett err_reg_descr, err_bit_descr));
165827Sjchu }
165927Sjchu }
166027Sjchu
16613274Set142600 /* DMC IMU SCS */
PX_ERPT_SEND_DEC(imu_scs)166227Sjchu PX_ERPT_SEND_DEC(imu_scs)
166327Sjchu {
166427Sjchu char buf[FM_MAX_CLASS];
1665739Sjchu boolean_t pri = PX_ERR_IS_PRI(bit);
166627Sjchu
166727Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
166827Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
166927Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
1670739Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
167127Sjchu FIRE_IMU_ELE, DATA_TYPE_UINT64,
167227Sjchu CSR_XR(csr_base, IMU_ERROR_LOG_ENABLE),
167327Sjchu FIRE_IMU_IE, DATA_TYPE_UINT64,
167427Sjchu CSR_XR(csr_base, IMU_INTERRUPT_ENABLE),
167527Sjchu FIRE_IMU_IS, DATA_TYPE_UINT64,
167627Sjchu ss_reg,
167727Sjchu FIRE_IMU_ESS, DATA_TYPE_UINT64,
167827Sjchu CSR_XR(csr_base, IMU_ERROR_STATUS_SET),
167927Sjchu FIRE_IMU_SCS, DATA_TYPE_UINT64,
168027Sjchu CSR_XR(csr_base, IMU_SCS_ERROR_LOG),
168127Sjchu NULL);
168227Sjchu
16833274Set142600 return (PX_NO_PANIC);
168427Sjchu }
168527Sjchu
16863274Set142600 /* DMC IMU */
PX_ERPT_SEND_DEC(imu)168727Sjchu PX_ERPT_SEND_DEC(imu)
168827Sjchu {
168927Sjchu char buf[FM_MAX_CLASS];
1690739Sjchu boolean_t pri = PX_ERR_IS_PRI(bit);
169127Sjchu
169227Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
169327Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
169427Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
1695739Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
169627Sjchu FIRE_IMU_ELE, DATA_TYPE_UINT64,
169727Sjchu CSR_XR(csr_base, IMU_ERROR_LOG_ENABLE),
169827Sjchu FIRE_IMU_IE, DATA_TYPE_UINT64,
169927Sjchu CSR_XR(csr_base, IMU_INTERRUPT_ENABLE),
170027Sjchu FIRE_IMU_IS, DATA_TYPE_UINT64,
170127Sjchu ss_reg,
170227Sjchu FIRE_IMU_ESS, DATA_TYPE_UINT64,
170327Sjchu CSR_XR(csr_base, IMU_ERROR_STATUS_SET),
170427Sjchu NULL);
170527Sjchu
17063274Set142600 return (PX_NO_PANIC);
170727Sjchu }
170827Sjchu
17093274Set142600 /* DMC MMU TFAR/TFSR */
PX_ERPT_SEND_DEC(mmu_tfar_tfsr)171027Sjchu PX_ERPT_SEND_DEC(mmu_tfar_tfsr)
171127Sjchu {
171227Sjchu char buf[FM_MAX_CLASS];
1713739Sjchu boolean_t pri = PX_ERR_IS_PRI(bit);
17143274Set142600 px_t *px_p = DIP_TO_STATE(rpdip);
17159921SKrishna.Elango@Sun.COM pcie_req_id_t fault_bdf = PCIE_INVALID_BDF;
17163274Set142600 uint16_t s_status = 0;
17173274Set142600
17183274Set142600 if (pri) {
17193274Set142600 fault_bdf = CSR_XR(csr_base, MMU_TRANSLATION_FAULT_STATUS)
17203274Set142600 & (MMU_TRANSLATION_FAULT_STATUS_ID_MASK <<
17213274Set142600 MMU_TRANSLATION_FAULT_STATUS_ID);
17223274Set142600 s_status = PCI_STAT_S_TARG_AB;
17233274Set142600
17243274Set142600 /* Only PIO Fault Addresses are valid, this is DMA */
17253274Set142600 (void) px_rp_en_q(px_p, fault_bdf, NULL, s_status);
17263274Set142600 }
172727Sjchu
172827Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
17291772Sjl139090
173027Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
173127Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
1732739Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
173327Sjchu FIRE_MMU_ELE, DATA_TYPE_UINT64,
173427Sjchu CSR_XR(csr_base, MMU_ERROR_LOG_ENABLE),
173527Sjchu FIRE_MMU_IE, DATA_TYPE_UINT64,
173627Sjchu CSR_XR(csr_base, MMU_INTERRUPT_ENABLE),
173727Sjchu FIRE_MMU_IS, DATA_TYPE_UINT64,
173827Sjchu ss_reg,
173927Sjchu FIRE_MMU_ESS, DATA_TYPE_UINT64,
174027Sjchu CSR_XR(csr_base, MMU_ERROR_STATUS_SET),
174127Sjchu FIRE_MMU_TFAR, DATA_TYPE_UINT64,
174227Sjchu CSR_XR(csr_base, MMU_TRANSLATION_FAULT_ADDRESS),
174327Sjchu FIRE_MMU_TFSR, DATA_TYPE_UINT64,
174427Sjchu CSR_XR(csr_base, MMU_TRANSLATION_FAULT_STATUS),
174527Sjchu NULL);
174627Sjchu
17473274Set142600 return (PX_NO_PANIC);
174827Sjchu }
174927Sjchu
17503274Set142600 /* DMC MMU */
PX_ERPT_SEND_DEC(mmu)175127Sjchu PX_ERPT_SEND_DEC(mmu)
175227Sjchu {
175327Sjchu char buf[FM_MAX_CLASS];
1754739Sjchu boolean_t pri = PX_ERR_IS_PRI(bit);
175527Sjchu
175627Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
175727Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
175827Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
1759739Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
176027Sjchu FIRE_MMU_ELE, DATA_TYPE_UINT64,
176127Sjchu CSR_XR(csr_base, MMU_ERROR_LOG_ENABLE),
176227Sjchu FIRE_MMU_IE, DATA_TYPE_UINT64,
176327Sjchu CSR_XR(csr_base, MMU_INTERRUPT_ENABLE),
176427Sjchu FIRE_MMU_IS, DATA_TYPE_UINT64,
176527Sjchu ss_reg,
176627Sjchu FIRE_MMU_ESS, DATA_TYPE_UINT64,
176727Sjchu CSR_XR(csr_base, MMU_ERROR_STATUS_SET),
176827Sjchu NULL);
176927Sjchu
17703274Set142600 return (PX_NO_PANIC);
177127Sjchu }
177227Sjchu
17733274Set142600 /*
17743274Set142600 * IMU function to handle all Received but Not Enabled errors.
17753274Set142600 *
17763274Set142600 * These errors are due to transactions modes in which the PX driver was not
17773274Set142600 * setup to be able to do. If possible, inform the driver that their DMA has
17783274Set142600 * failed by marking their DMA handle as failed, but do not panic the system.
17793274Set142600 * Most likely the address is not valid, as Fire wasn't setup to handle them in
17803274Set142600 * the first place.
17813274Set142600 *
17823274Set142600 * These errors are not retryable, unless the PX mode has changed, otherwise the
17833274Set142600 * same error will occur again.
17843274Set142600 */
178527Sjchu 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)178627Sjchu px_err_mmu_rbne_handle(dev_info_t *rpdip, caddr_t csr_base,
178727Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
178827Sjchu px_err_bit_desc_t *err_bit_descr)
178927Sjchu {
17903274Set142600 pcie_req_id_t bdf;
179127Sjchu
17923274Set142600 if (!PX_ERR_IS_PRI(err_bit_descr->bit))
17933274Set142600 goto done;
1794260Set142600
17953274Set142600 bdf = (pcie_req_id_t)CSR_FR(csr_base, MMU_TRANSLATION_FAULT_STATUS, ID);
17966313Skrishnae (void) pf_hdl_lookup(rpdip, derr->fme_ena, PF_ADDR_DMA, NULL,
17973274Set142600 bdf);
179827Sjchu
17993274Set142600 done:
18003274Set142600 return (px_err_no_panic_handle(rpdip, csr_base, derr, err_reg_descr,
18014853Segillett err_bit_descr));
180227Sjchu }
180327Sjchu
18043274Set142600 /*
18053274Set142600 * IMU function to handle all invalid address errors.
18063274Set142600 *
18073274Set142600 * These errors are due to transactions in which the address is not recognized.
18083274Set142600 * If possible, inform the driver that all DMAs have failed by marking their DMA
18093274Set142600 * handles. Fire should not panic the system, it'll be up to the driver to
18103274Set142600 * panic. The address logged is invalid.
18113274Set142600 *
18123274Set142600 * These errors are not retryable since retrying the same transaction with the
18133274Set142600 * same invalid address will result in the same error.
18143274Set142600 */
181527Sjchu /* ARGSUSED */
181627Sjchu 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)181727Sjchu px_err_mmu_tfa_handle(dev_info_t *rpdip, caddr_t csr_base,
181827Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
181927Sjchu px_err_bit_desc_t *err_bit_descr)
182027Sjchu {
18213274Set142600 pcie_req_id_t bdf;
18223274Set142600
18233274Set142600 if (!PX_ERR_IS_PRI(err_bit_descr->bit))
18243274Set142600 goto done;
182527Sjchu
18263274Set142600 bdf = (pcie_req_id_t)CSR_FR(csr_base, MMU_TRANSLATION_FAULT_STATUS, ID);
18276313Skrishnae (void) pf_hdl_lookup(rpdip, derr->fme_ena, PF_ADDR_DMA, NULL,
18283274Set142600 bdf);
1829739Sjchu
18303274Set142600 done:
18313274Set142600 return (px_err_no_panic_handle(rpdip, csr_base, derr, err_reg_descr,
18324853Segillett err_bit_descr));
183327Sjchu }
183427Sjchu
18353274Set142600 /*
18363274Set142600 * IMU function to handle normal transactions that encounter a parity error.
18373274Set142600 *
18383274Set142600 * These errors are due to transactions that enouter a parity error. If
18393274Set142600 * possible, inform the driver that their DMA have failed and that they should
18403274Set142600 * retry. If Fire is unable to contact the leaf driver, panic the system.
18413274Set142600 * Otherwise, it'll be up to the device to determine is this is a panicable
18423274Set142600 * error.
18433274Set142600 */
184427Sjchu /* ARGSUSED */
184527Sjchu 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)18463274Set142600 px_err_mmu_parity_handle(dev_info_t *rpdip, caddr_t csr_base,
184727Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
184827Sjchu px_err_bit_desc_t *err_bit_descr)
184927Sjchu {
18503274Set142600 uint64_t mmu_tfa;
18513274Set142600 pcie_req_id_t bdf;
18524853Segillett int status = PF_HDL_NOTFOUND;
185327Sjchu
18543274Set142600 if (!PX_ERR_IS_PRI(err_bit_descr->bit))
18553274Set142600 goto done;
1856739Sjchu
185727Sjchu mmu_tfa = CSR_XR(csr_base, MMU_TRANSLATION_FAULT_ADDRESS);
18583274Set142600 bdf = (pcie_req_id_t)CSR_FR(csr_base, MMU_TRANSLATION_FAULT_STATUS, ID);
18596313Skrishnae status = pf_hdl_lookup(rpdip, derr->fme_ena, PF_ADDR_DMA,
18603274Set142600 (uint32_t)mmu_tfa, bdf);
18613274Set142600
18623274Set142600 done:
18634853Segillett if (status == PF_HDL_NOTFOUND)
18643274Set142600 return (px_err_panic_handle(rpdip, csr_base, derr,
18654853Segillett err_reg_descr, err_bit_descr));
18663274Set142600 else
18673274Set142600 return (px_err_no_panic_handle(rpdip, csr_base, derr,
18684853Segillett err_reg_descr, err_bit_descr));
18693274Set142600 }
18703274Set142600
18713274Set142600 /*
18723274Set142600 * wuc/ruc event - Mark the handle of the failed PIO access. Return "no_panic"
18733274Set142600 */
18743274Set142600 /* ARGSUSED */
18753274Set142600 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)18763274Set142600 px_err_wuc_ruc_handle(dev_info_t *rpdip, caddr_t csr_base,
18773274Set142600 ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
18783274Set142600 px_err_bit_desc_t *err_bit_descr)
18793274Set142600 {
18803274Set142600 px_t *px_p = DIP_TO_STATE(rpdip);
18813274Set142600 pxu_t *pxu_p = (pxu_t *)px_p->px_plat_p;
18823274Set142600 uint64_t data;
18836313Skrishnae pf_pcie_adv_err_regs_t adv_reg;
18846313Skrishnae int sts;
188527Sjchu
18863274Set142600 if (!PX_ERR_IS_PRI(err_bit_descr->bit))
18873274Set142600 goto done;
18883274Set142600
18893274Set142600 data = CSR_XR(csr_base, TLU_TRANSMIT_OTHER_EVENT_HEADER1_LOG);
18906313Skrishnae adv_reg.pcie_ue_hdr[0] = (uint32_t)(data >> 32);
18916313Skrishnae adv_reg.pcie_ue_hdr[1] = (uint32_t)(data & 0xFFFFFFFF);
18923274Set142600 data = CSR_XR(csr_base, TLU_TRANSMIT_OTHER_EVENT_HEADER2_LOG);
18936313Skrishnae adv_reg.pcie_ue_hdr[2] = (uint32_t)(data >> 32);
18946313Skrishnae adv_reg.pcie_ue_hdr[3] = (uint32_t)(data & 0xFFFFFFFF);
18953274Set142600
189611311SSurya.Prakki@Sun.COM (void) pf_tlp_decode(PCIE_DIP2BUS(rpdip), &adv_reg);
18976313Skrishnae sts = pf_hdl_lookup(rpdip, derr->fme_ena, adv_reg.pcie_ue_tgt_trans,
18986313Skrishnae adv_reg.pcie_ue_tgt_addr, adv_reg.pcie_ue_tgt_bdf);
18993274Set142600 done:
19003274Set142600 if ((sts == PF_HDL_NOTFOUND) && (pxu_p->cpr_flag == PX_NOT_CPR))
19013274Set142600 return (px_err_protected_handle(rpdip, csr_base, derr,
19024853Segillett err_reg_descr, err_bit_descr));
19033274Set142600
19043274Set142600 return (px_err_no_panic_handle(rpdip, csr_base, derr,
19054853Segillett err_reg_descr, err_bit_descr));
190627Sjchu }
190727Sjchu
1908118Sjchu /*
19091147Sjchu * TLU LUP event - if caused by power management activity, then it is expected.
19101147Sjchu * In all other cases, it is an error.
1911118Sjchu */
1912118Sjchu /* ARGSUSED */
1913118Sjchu 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)1914118Sjchu px_err_tlu_lup_handle(dev_info_t *rpdip, caddr_t csr_base,
1915118Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
1916118Sjchu px_err_bit_desc_t *err_bit_descr)
1917118Sjchu {
1918118Sjchu px_t *px_p = DIP_TO_STATE(rpdip);
1919118Sjchu
1920118Sjchu /*
19211147Sjchu * power management code is currently the only segment that sets
19221147Sjchu * px_lup_pending to indicate its expectation for a healthy LUP
19231147Sjchu * event. For all other occasions, LUP event should be flaged as
19241147Sjchu * error condition.
1925118Sjchu */
19261147Sjchu return ((atomic_cas_32(&px_p->px_lup_pending, 1, 0) == 0) ?
19273274Set142600 PX_NO_PANIC : PX_EXPECTED);
19281147Sjchu }
1929118Sjchu
19301147Sjchu /*
19311147Sjchu * TLU LDN event - if caused by power management activity, then it is expected.
19321147Sjchu * In all other cases, it is an error.
19331147Sjchu */
19341147Sjchu /* ARGSUSED */
19351147Sjchu 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)19361147Sjchu px_err_tlu_ldn_handle(dev_info_t *rpdip, caddr_t csr_base,
19371147Sjchu ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
19381147Sjchu px_err_bit_desc_t *err_bit_descr)
19391147Sjchu {
19401147Sjchu px_t *px_p = DIP_TO_STATE(rpdip);
19413274Set142600 return ((px_p->px_pm_flags & PX_LDN_EXPECTED) ? PX_EXPECTED :
19423274Set142600 PX_NO_PANIC);
1943118Sjchu }
1944118Sjchu
194527Sjchu /* PEC ILU none - see io erpt doc, section 3.1 */
PX_ERPT_SEND_DEC(pec_ilu)194627Sjchu PX_ERPT_SEND_DEC(pec_ilu)
194727Sjchu {
194827Sjchu char buf[FM_MAX_CLASS];
1949739Sjchu boolean_t pri = PX_ERR_IS_PRI(bit);
195027Sjchu
195127Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
195227Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
195327Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
1954739Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
195527Sjchu FIRE_ILU_ELE, DATA_TYPE_UINT64,
195627Sjchu CSR_XR(csr_base, ILU_ERROR_LOG_ENABLE),
195727Sjchu FIRE_ILU_IE, DATA_TYPE_UINT64,
195827Sjchu CSR_XR(csr_base, ILU_INTERRUPT_ENABLE),
195927Sjchu FIRE_ILU_IS, DATA_TYPE_UINT64,
196027Sjchu ss_reg,
196127Sjchu FIRE_ILU_ESS, DATA_TYPE_UINT64,
196227Sjchu CSR_XR(csr_base, ILU_ERROR_STATUS_SET),
196327Sjchu NULL);
196427Sjchu
19653274Set142600 return (PX_NO_PANIC);
196627Sjchu }
196727Sjchu
1968383Set142600 /* PCIEX UE Errors */
1969383Set142600 /* ARGSUSED */
1970671Skrishnae 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)1971383Set142600 px_err_pciex_ue_handle(dev_info_t *rpdip, caddr_t csr_base,
1972383Set142600 ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
1973383Set142600 px_err_bit_desc_t *err_bit_descr)
1974383Set142600 {
19753274Set142600 px_err_pcie_t regs = {0};
19763274Set142600 uint32_t err_bit;
19773274Set142600 int err;
19783274Set142600 uint64_t log;
19793274Set142600
19803274Set142600 if (err_bit_descr->bit < 32) {
19813274Set142600 err_bit = (uint32_t)BITMASK(err_bit_descr->bit);
19823274Set142600 regs.ue_reg = err_bit;
19833274Set142600 regs.primary_ue = err_bit;
19843274Set142600
19853274Set142600 /*
19866313Skrishnae * Log the Received Log for PTLP, UR and UC.
19873274Set142600 */
19886313Skrishnae if ((PCIE_AER_UCE_PTLP | PCIE_AER_UCE_UR | PCIE_AER_UCE_UC) &
19896313Skrishnae err_bit) {
19903274Set142600 log = CSR_XR(csr_base,
19913274Set142600 TLU_RECEIVE_UNCORRECTABLE_ERROR_HEADER1_LOG);
19923274Set142600 regs.rx_hdr1 = (uint32_t)(log >> 32);
19936313Skrishnae regs.rx_hdr2 = (uint32_t)(log & 0xFFFFFFFF);
1994383Set142600
19953274Set142600 log = CSR_XR(csr_base,
19963274Set142600 TLU_RECEIVE_UNCORRECTABLE_ERROR_HEADER2_LOG);
19973274Set142600 regs.rx_hdr3 = (uint32_t)(log >> 32);
19986313Skrishnae regs.rx_hdr4 = (uint32_t)(log & 0xFFFFFFFF);
19993274Set142600 }
20003274Set142600 } else {
20013274Set142600 regs.ue_reg = (uint32_t)BITMASK(err_bit_descr->bit - 32);
20023274Set142600 }
20033274Set142600
2004*11654SKrishna.Elango@Sun.COM err = px_err_check_pcie(rpdip, derr, ®s, PF_INTR_TYPE_INTERNAL);
20053274Set142600
20064410Skrishnae if (err & PX_PANIC) {
20073274Set142600 return (px_err_panic_handle(rpdip, csr_base, derr,
20084853Segillett err_reg_descr, err_bit_descr));
20093274Set142600 } else {
20103274Set142600 return (px_err_no_panic_handle(rpdip, csr_base, derr,
20114853Segillett err_reg_descr, err_bit_descr));
20123274Set142600 }
2013383Set142600 }
2014383Set142600
20153274Set142600 /* PCI-E Uncorrectable Errors */
PX_ERPT_SEND_DEC(pciex_rx_ue)2016383Set142600 PX_ERPT_SEND_DEC(pciex_rx_ue)
2017383Set142600 {
2018383Set142600 char buf[FM_MAX_CLASS];
2019739Sjchu boolean_t pri = PX_ERR_IS_PRI(bit);
2020383Set142600
2021383Set142600 (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
2022383Set142600 ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
2023383Set142600 DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
2024739Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
2025383Set142600 FIRE_TLU_UELE, DATA_TYPE_UINT64,
2026383Set142600 CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_LOG_ENABLE),
2027383Set142600 FIRE_TLU_UIE, DATA_TYPE_UINT64,
2028383Set142600 CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_INTERRUPT_ENABLE),
2029383Set142600 FIRE_TLU_UIS, DATA_TYPE_UINT64,
2030383Set142600 ss_reg,
2031383Set142600 FIRE_TLU_UESS, DATA_TYPE_UINT64,
2032383Set142600 CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_STATUS_SET),
2033383Set142600 FIRE_TLU_RUEH1L, DATA_TYPE_UINT64,
2034383Set142600 CSR_XR(csr_base, TLU_RECEIVE_UNCORRECTABLE_ERROR_HEADER1_LOG),
2035383Set142600 FIRE_TLU_RUEH2L, DATA_TYPE_UINT64,
2036383Set142600 CSR_XR(csr_base, TLU_RECEIVE_UNCORRECTABLE_ERROR_HEADER2_LOG),
2037383Set142600 NULL);
2038383Set142600
20393274Set142600 return (PX_NO_PANIC);
2040383Set142600 }
2041383Set142600
20423274Set142600 /* PCI-E Uncorrectable Errors */
PX_ERPT_SEND_DEC(pciex_tx_ue)2043383Set142600 PX_ERPT_SEND_DEC(pciex_tx_ue)
2044383Set142600 {
2045383Set142600 char buf[FM_MAX_CLASS];
2046739Sjchu boolean_t pri = PX_ERR_IS_PRI(bit);
2047383Set142600
2048383Set142600 (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
2049383Set142600 ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
2050383Set142600 DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
2051739Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
2052383Set142600 FIRE_TLU_UELE, DATA_TYPE_UINT64,
2053383Set142600 CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_LOG_ENABLE),
2054383Set142600 FIRE_TLU_UIE, DATA_TYPE_UINT64,
2055383Set142600 CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_INTERRUPT_ENABLE),
2056383Set142600 FIRE_TLU_UIS, DATA_TYPE_UINT64,
2057383Set142600 ss_reg,
2058383Set142600 FIRE_TLU_UESS, DATA_TYPE_UINT64,
2059383Set142600 CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_STATUS_SET),
2060383Set142600 FIRE_TLU_TUEH1L, DATA_TYPE_UINT64,
2061383Set142600 CSR_XR(csr_base, TLU_TRANSMIT_UNCORRECTABLE_ERROR_HEADER1_LOG),
2062383Set142600 FIRE_TLU_TUEH2L, DATA_TYPE_UINT64,
2063383Set142600 CSR_XR(csr_base, TLU_TRANSMIT_UNCORRECTABLE_ERROR_HEADER2_LOG),
2064383Set142600 NULL);
2065383Set142600
20663274Set142600 return (PX_NO_PANIC);
2067383Set142600 }
2068383Set142600
20693274Set142600 /* PCI-E Uncorrectable Errors */
PX_ERPT_SEND_DEC(pciex_rx_tx_ue)2070383Set142600 PX_ERPT_SEND_DEC(pciex_rx_tx_ue)
2071383Set142600 {
2072383Set142600 char buf[FM_MAX_CLASS];
2073739Sjchu boolean_t pri = PX_ERR_IS_PRI(bit);
2074383Set142600
2075383Set142600 (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
2076383Set142600 ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
2077383Set142600 DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
2078739Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
2079383Set142600 FIRE_TLU_UELE, DATA_TYPE_UINT64,
2080383Set142600 CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_LOG_ENABLE),
2081383Set142600 FIRE_TLU_UIE, DATA_TYPE_UINT64,
2082383Set142600 CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_INTERRUPT_ENABLE),
2083383Set142600 FIRE_TLU_UIS, DATA_TYPE_UINT64,
2084383Set142600 ss_reg,
2085383Set142600 FIRE_TLU_UESS, DATA_TYPE_UINT64,
2086383Set142600 CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_STATUS_SET),
2087383Set142600 FIRE_TLU_RUEH1L, DATA_TYPE_UINT64,
2088383Set142600 CSR_XR(csr_base, TLU_RECEIVE_UNCORRECTABLE_ERROR_HEADER1_LOG),
2089383Set142600 FIRE_TLU_RUEH2L, DATA_TYPE_UINT64,
2090383Set142600 CSR_XR(csr_base, TLU_RECEIVE_UNCORRECTABLE_ERROR_HEADER2_LOG),
2091383Set142600 FIRE_TLU_TUEH1L, DATA_TYPE_UINT64,
2092383Set142600 CSR_XR(csr_base, TLU_TRANSMIT_UNCORRECTABLE_ERROR_HEADER1_LOG),
2093383Set142600 FIRE_TLU_TUEH2L, DATA_TYPE_UINT64,
2094383Set142600 CSR_XR(csr_base, TLU_TRANSMIT_UNCORRECTABLE_ERROR_HEADER2_LOG),
2095383Set142600 NULL);
2096383Set142600
20973274Set142600 return (PX_NO_PANIC);
2098383Set142600 }
2099383Set142600
21003274Set142600 /* PCI-E Uncorrectable Errors */
PX_ERPT_SEND_DEC(pciex_ue)2101383Set142600 PX_ERPT_SEND_DEC(pciex_ue)
2102383Set142600 {
2103383Set142600 char buf[FM_MAX_CLASS];
2104739Sjchu boolean_t pri = PX_ERR_IS_PRI(bit);
2105383Set142600
2106383Set142600 (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
2107383Set142600 ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
2108383Set142600 DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
2109739Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
2110383Set142600 FIRE_TLU_UELE, DATA_TYPE_UINT64,
2111383Set142600 CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_LOG_ENABLE),
2112383Set142600 FIRE_TLU_UIE, DATA_TYPE_UINT64,
2113383Set142600 CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_INTERRUPT_ENABLE),
2114383Set142600 FIRE_TLU_UIS, DATA_TYPE_UINT64,
2115383Set142600 ss_reg,
2116383Set142600 FIRE_TLU_UESS, DATA_TYPE_UINT64,
2117383Set142600 CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_STATUS_SET),
2118383Set142600 NULL);
2119383Set142600
21203274Set142600 return (PX_NO_PANIC);
2121383Set142600 }
2122383Set142600
2123383Set142600 /* PCIEX UE Errors */
2124383Set142600 /* ARGSUSED */
2125671Skrishnae 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)2126383Set142600 px_err_pciex_ce_handle(dev_info_t *rpdip, caddr_t csr_base,
2127383Set142600 ddi_fm_error_t *derr, px_err_reg_desc_t *err_reg_descr,
2128383Set142600 px_err_bit_desc_t *err_bit_descr)
2129383Set142600 {
21303274Set142600 px_err_pcie_t regs = {0};
21313274Set142600 int err;
21323274Set142600
21333274Set142600 if (err_bit_descr->bit < 32)
21343274Set142600 regs.ce_reg = (uint32_t)BITMASK(err_bit_descr->bit);
21353274Set142600 else
21363274Set142600 regs.ce_reg = (uint32_t)BITMASK(err_bit_descr->bit - 32);
2137383Set142600
2138*11654SKrishna.Elango@Sun.COM err = px_err_check_pcie(rpdip, derr, ®s, PF_INTR_TYPE_INTERNAL);
21393274Set142600
21404410Skrishnae if (err & PX_PANIC) {
21413274Set142600 return (px_err_panic_handle(rpdip, csr_base, derr,
21424853Segillett err_reg_descr, err_bit_descr));
21433274Set142600 } else {
21443274Set142600 return (px_err_no_panic_handle(rpdip, csr_base, derr,
21454853Segillett err_reg_descr, err_bit_descr));
21463274Set142600 }
2147383Set142600 }
2148383Set142600
214927Sjchu /* PCI-E Correctable Errors - see io erpt doc, section 3.6 */
PX_ERPT_SEND_DEC(pciex_ce)215027Sjchu PX_ERPT_SEND_DEC(pciex_ce)
215127Sjchu {
215227Sjchu char buf[FM_MAX_CLASS];
2153739Sjchu boolean_t pri = PX_ERR_IS_PRI(bit);
215427Sjchu
215527Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
215627Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
215727Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
2158739Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
215927Sjchu FIRE_TLU_CELE, DATA_TYPE_UINT64,
216027Sjchu CSR_XR(csr_base, TLU_CORRECTABLE_ERROR_LOG_ENABLE),
216127Sjchu FIRE_TLU_CIE, DATA_TYPE_UINT64,
216227Sjchu CSR_XR(csr_base, TLU_CORRECTABLE_ERROR_INTERRUPT_ENABLE),
216327Sjchu FIRE_TLU_CIS, DATA_TYPE_UINT64,
216427Sjchu ss_reg,
216527Sjchu FIRE_TLU_CESS, DATA_TYPE_UINT64,
216627Sjchu CSR_XR(csr_base, TLU_CORRECTABLE_ERROR_STATUS_SET),
216727Sjchu NULL);
216827Sjchu
21693274Set142600 return (PX_NO_PANIC);
217027Sjchu }
217127Sjchu
217227Sjchu /* TLU Other Event Status (receive only) - see io erpt doc, section 3.7 */
PX_ERPT_SEND_DEC(pciex_rx_oe)217327Sjchu PX_ERPT_SEND_DEC(pciex_rx_oe)
217427Sjchu {
217527Sjchu char buf[FM_MAX_CLASS];
2176739Sjchu boolean_t pri = PX_ERR_IS_PRI(bit);
217727Sjchu
217827Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
217927Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
218027Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
2181739Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
218227Sjchu FIRE_TLU_OEELE, DATA_TYPE_UINT64,
218327Sjchu CSR_XR(csr_base, TLU_OTHER_EVENT_LOG_ENABLE),
218427Sjchu FIRE_TLU_OEIE, DATA_TYPE_UINT64,
218527Sjchu CSR_XR(csr_base, TLU_OTHER_EVENT_INTERRUPT_ENABLE),
218627Sjchu FIRE_TLU_OEIS, DATA_TYPE_UINT64,
218727Sjchu ss_reg,
218827Sjchu FIRE_TLU_OEESS, DATA_TYPE_UINT64,
218927Sjchu CSR_XR(csr_base, TLU_OTHER_EVENT_STATUS_SET),
219027Sjchu FIRE_TLU_RUEH1L, DATA_TYPE_UINT64,
219127Sjchu CSR_XR(csr_base, TLU_RECEIVE_OTHER_EVENT_HEADER1_LOG),
2192260Set142600 FIRE_TLU_RUEH2L, DATA_TYPE_UINT64,
219327Sjchu CSR_XR(csr_base, TLU_RECEIVE_OTHER_EVENT_HEADER2_LOG),
219427Sjchu NULL);
219527Sjchu
21963274Set142600 return (PX_NO_PANIC);
219727Sjchu }
219827Sjchu
219927Sjchu /* TLU Other Event Status (rx + tx) - see io erpt doc, section 3.8 */
PX_ERPT_SEND_DEC(pciex_rx_tx_oe)220027Sjchu PX_ERPT_SEND_DEC(pciex_rx_tx_oe)
220127Sjchu {
220227Sjchu char buf[FM_MAX_CLASS];
2203739Sjchu boolean_t pri = PX_ERR_IS_PRI(bit);
22043274Set142600 px_t *px_p = DIP_TO_STATE(rpdip);
22053274Set142600 uint64_t rx_h1, rx_h2, tx_h1, tx_h2;
22063274Set142600 uint16_t s_status;
22073274Set142600 int sts;
22083274Set142600 pcie_cpl_t *cpl;
22096313Skrishnae pf_pcie_adv_err_regs_t adv_reg;
22103274Set142600
22113274Set142600 rx_h1 = CSR_XR(csr_base, TLU_RECEIVE_OTHER_EVENT_HEADER1_LOG);
22123274Set142600 rx_h2 = CSR_XR(csr_base, TLU_RECEIVE_OTHER_EVENT_HEADER2_LOG);
22133274Set142600 tx_h1 = CSR_XR(csr_base, TLU_TRANSMIT_OTHER_EVENT_HEADER1_LOG);
22143274Set142600 tx_h2 = CSR_XR(csr_base, TLU_TRANSMIT_OTHER_EVENT_HEADER2_LOG);
22153274Set142600
22163274Set142600 if ((bit == TLU_OTHER_EVENT_STATUS_SET_RUC_P) ||
22173274Set142600 (bit == TLU_OTHER_EVENT_STATUS_SET_WUC_P)) {
22186313Skrishnae adv_reg.pcie_ue_hdr[0] = (uint32_t)(rx_h1 >> 32);
22196313Skrishnae adv_reg.pcie_ue_hdr[1] = (uint32_t)rx_h1;
22206313Skrishnae adv_reg.pcie_ue_hdr[2] = (uint32_t)(rx_h2 >> 32);
22216313Skrishnae adv_reg.pcie_ue_hdr[3] = (uint32_t)rx_h2;
22223274Set142600
22233274Set142600 /* get completer bdf (fault bdf) from rx logs */
22246313Skrishnae cpl = (pcie_cpl_t *)&adv_reg.pcie_ue_hdr[1];
22253274Set142600
22263274Set142600 /* Figure out if UR/CA from rx logs */
22273274Set142600 if (cpl->status == PCIE_CPL_STS_UR)
22283274Set142600 s_status = PCI_STAT_R_MAST_AB;
22293274Set142600 else if (cpl->status == PCIE_CPL_STS_CA)
22303274Set142600 s_status = PCI_STAT_R_TARG_AB;
22313274Set142600
22326313Skrishnae adv_reg.pcie_ue_hdr[0] = (uint32_t)(tx_h1 >> 32);
22336313Skrishnae adv_reg.pcie_ue_hdr[1] = (uint32_t)tx_h1;
22346313Skrishnae adv_reg.pcie_ue_hdr[2] = (uint32_t)(tx_h2 >> 32);
22356313Skrishnae adv_reg.pcie_ue_hdr[3] = (uint32_t)tx_h2;
22363274Set142600
22373274Set142600 /* get fault addr from tx logs */
22386313Skrishnae sts = pf_tlp_decode(PCIE_DIP2BUS(rpdip), &adv_reg);
22393274Set142600
22403274Set142600 if (sts == DDI_SUCCESS)
22416313Skrishnae (void) px_rp_en_q(px_p, adv_reg.pcie_ue_tgt_bdf,
22426313Skrishnae adv_reg.pcie_ue_tgt_addr, s_status);
22433274Set142600 }
224427Sjchu
224527Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
224627Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
224727Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
2248739Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
224927Sjchu FIRE_TLU_OEELE, DATA_TYPE_UINT64,
225027Sjchu CSR_XR(csr_base, TLU_OTHER_EVENT_LOG_ENABLE),
225127Sjchu FIRE_TLU_OEIE, DATA_TYPE_UINT64,
225227Sjchu CSR_XR(csr_base, TLU_OTHER_EVENT_INTERRUPT_ENABLE),
225327Sjchu FIRE_TLU_OEIS, DATA_TYPE_UINT64,
225427Sjchu ss_reg,
225527Sjchu FIRE_TLU_OEESS, DATA_TYPE_UINT64,
225627Sjchu CSR_XR(csr_base, TLU_OTHER_EVENT_STATUS_SET),
22573274Set142600 FIRE_TLU_ROEEH1L, DATA_TYPE_UINT64, rx_h1,
22583274Set142600 FIRE_TLU_ROEEH2L, DATA_TYPE_UINT64, rx_h2,
22593274Set142600 FIRE_TLU_TOEEH1L, DATA_TYPE_UINT64, tx_h1,
22603274Set142600 FIRE_TLU_TOEEH2L, DATA_TYPE_UINT64, tx_h2,
226127Sjchu NULL);
226227Sjchu
22633274Set142600 return (PX_NO_PANIC);
226427Sjchu }
226527Sjchu
226627Sjchu /* TLU Other Event - see io erpt doc, section 3.9 */
PX_ERPT_SEND_DEC(pciex_oe)226727Sjchu PX_ERPT_SEND_DEC(pciex_oe)
226827Sjchu {
2269739Sjchu char buf[FM_MAX_CLASS];
2270739Sjchu boolean_t pri = PX_ERR_IS_PRI(bit);
227127Sjchu
227227Sjchu (void) snprintf(buf, FM_MAX_CLASS, "%s", class_name);
227327Sjchu ddi_fm_ereport_post(rpdip, buf, derr->fme_ena,
227427Sjchu DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
2275739Sjchu FIRE_PRIMARY, DATA_TYPE_BOOLEAN_VALUE, pri,
227627Sjchu FIRE_TLU_OEELE, DATA_TYPE_UINT64,
227727Sjchu CSR_XR(csr_base, TLU_OTHER_EVENT_LOG_ENABLE),
227827Sjchu FIRE_TLU_OEIE, DATA_TYPE_UINT64,
227927Sjchu CSR_XR(csr_base, TLU_OTHER_EVENT_INTERRUPT_ENABLE),
228027Sjchu FIRE_TLU_OEIS, DATA_TYPE_UINT64,
228127Sjchu ss_reg,
228227Sjchu FIRE_TLU_OEESS, DATA_TYPE_UINT64,
228327Sjchu CSR_XR(csr_base, TLU_OTHER_EVENT_STATUS_SET),
228427Sjchu NULL);
228527Sjchu
22863274Set142600 return (PX_NO_PANIC);
228727Sjchu }
2288