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