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