From owner-svn-src-all@FreeBSD.ORG Fri May 14 20:00:22 2010 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 51BA11065675; Fri, 14 May 2010 20:00:22 +0000 (UTC) (envelope-from marius@FreeBSD.org) Received: from svn.freebsd.org (unknown [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 404A58FC22; Fri, 14 May 2010 20:00:22 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o4EK0MPv055807; Fri, 14 May 2010 20:00:22 GMT (envelope-from marius@svn.freebsd.org) Received: (from marius@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o4EK0MCO055803; Fri, 14 May 2010 20:00:22 GMT (envelope-from marius@svn.freebsd.org) Message-Id: <201005142000.o4EK0MCO055803@svn.freebsd.org> From: Marius Strobl Date: Fri, 14 May 2010 20:00:22 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r208097 - head/sys/sparc64/pci X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 14 May 2010 20:00:22 -0000 Author: marius Date: Fri May 14 20:00:21 2010 New Revision: 208097 URL: http://svn.freebsd.org/changeset/base/208097 Log: - Enable DMA write parity error interrupts on Schizo with a working implementation. - Revert the Sun Fire V890 WAR of r205254. Instead let schizo_pci_bus() only panic in case of fatal errors as the interrupt triggered by the error the firmware of these and also Sun Fire 280R with version 7 Schizo caused may happen as late as using the HBA and not only prior to touching the PCI bus (in the former case the actual error still is fatal but we clear it before touching the PCI bus). While at it count and export non-fatal error interrupts via sysctl(9). - Remove unnecessary locking from schizo_ue(). Modified: head/sys/sparc64/pci/schizo.c head/sys/sparc64/pci/schizoreg.h head/sys/sparc64/pci/schizovar.h Modified: head/sys/sparc64/pci/schizo.c ============================================================================== --- head/sys/sparc64/pci/schizo.c Fri May 14 19:57:18 2010 (r208096) +++ head/sys/sparc64/pci/schizo.c Fri May 14 20:00:21 2010 (r208097) @@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -385,6 +386,21 @@ schizo_attach(device_t dev) SCHIZO_PCI_WRITE_8(sc, STX_PCI_DIAG, reg); /* + * Enable DMA write parity error interrupts of version >= 7 (i.e. + * revision >= 2.5) Schizo. + */ + if (mode == SCHIZO_MODE_SCZ && sc->sc_ver >= 7) { + reg = SCHIZO_PCI_READ_8(sc, SX_PCI_CFG_ICD); + reg |= SX_PCI_CFG_ICD_DMAW_PERR_IEN; +#ifdef SCHIZO_DEBUG + device_printf(dev, "PCI CFG/ICD 0x%016llx -> 0x%016llx\n", + (unsigned long long)SCHIZO_PCI_READ_8(sc, SX_PCI_CFG_ICD), + (unsigned long long)reg); +#endif + SCHIZO_PCI_WRITE_8(sc, SX_PCI_CFG_ICD, reg); + } + + /* * On Tomatillo clear the I/O prefetch lengths (workaround for a * Jalapeno bug). */ @@ -697,14 +713,18 @@ schizo_attach(device_t dev) ofw_bus_setup_iinfo(node, &sc->sc_pci_iinfo, sizeof(ofw_pci_intr_t)); - /* - * At least when booting Fire V890 from disk a Schizo comes up with - * a PCI bus error residing which triggers as soon as we register - * schizo_pci_bus() even when clearing it from all involved registers - * beforehand (but is quiet once it has fired). Thus we make PCI bus - * errors non-fatal until we actually touch the bus. - */ - sc->sc_flags |= SCHIZO_FLAGS_ARMED; +#define SCHIZO_SYSCTL_ADD_UINT(name, arg, desc) \ + SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev), \ + SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, \ + (name), CTLFLAG_RD, (arg), 0, (desc)) + + SCHIZO_SYSCTL_ADD_UINT("dma_ce", &sc->sc_stats_dma_ce, + "DMA correctable errors"); + SCHIZO_SYSCTL_ADD_UINT("pci_non_fatal", &sc->sc_stats_pci_non_fatal, + "PCI bus non-fatal errors"); + +#undef SCHIZO_SYSCTL_ADD_UINT + device_add_child(dev, "pci", -1); return (bus_generic_attach(dev)); } @@ -801,6 +821,11 @@ schizo_pci_bus(void *arg) struct schizo_softc *sc = arg; uint64_t afar, afsr, csr, iommu; uint32_t status; + u_int fatal; + + fatal = 0; + + mtx_lock_spin(sc->sc_mtx); afar = SCHIZO_PCI_READ_8(sc, STX_PCI_AFAR); afsr = SCHIZO_PCI_READ_8(sc, STX_PCI_AFSR); @@ -808,41 +833,51 @@ schizo_pci_bus(void *arg) iommu = SCHIZO_PCI_READ_8(sc, STX_PCI_IOMMU); status = PCIB_READ_CONFIG(sc->sc_dev, sc->sc_pci_secbus, STX_CS_DEVICE, STX_CS_FUNC, PCIR_STATUS, 2); - if ((sc->sc_flags & SCHIZO_FLAGS_ARMED) == 0) - goto clear_error; - if ((csr & STX_PCI_CTRL_MMU_ERR) != 0) { - if ((iommu & TOM_PCI_IOMMU_ERR) == 0) - goto clear_error; - - /* These are non-fatal if target abort was signaled. */ - if ((status & PCIM_STATUS_STABORT) != 0 && - ((iommu & TOM_PCI_IOMMU_ERRMASK) == - TOM_PCI_IOMMU_INVALID_ERR || - (iommu & TOM_PCI_IOMMU_ERR_ILLTSBTBW) != 0 || - (iommu & TOM_PCI_IOMMU_ERR_BAD_VA) != 0)) { - SCHIZO_PCI_WRITE_8(sc, STX_PCI_IOMMU, iommu); - goto clear_error; - } - } - panic("%s: PCI bus %c error AFAR %#llx AFSR %#llx PCI CSR %#llx " - "IOMMU %#llx STATUS %#llx", device_get_nameunit(sc->sc_dev), - 'A' + sc->sc_half, (unsigned long long)afar, - (unsigned long long)afsr, (unsigned long long)csr, - (unsigned long long)iommu, (unsigned long long)status); + /* + * IOMMU errors are only fatal on Tomatillo and there also only if + * target abort was not signaled. + */ + if ((csr & STX_PCI_CTRL_MMU_ERR) != 0 && + (iommu & TOM_PCI_IOMMU_ERR) != 0 && + ((status & PCIM_STATUS_STABORT) == 0 || + ((iommu & TOM_PCI_IOMMU_ERRMASK) != TOM_PCI_IOMMU_INVALID_ERR && + (iommu & TOM_PCI_IOMMU_ERR_ILLTSBTBW) == 0 && + (iommu & TOM_PCI_IOMMU_ERR_BAD_VA) == 0))) + fatal = 1; + else if ((status & PCIM_STATUS_STABORT) != 0) + fatal = 1; + if ((status & (PCIM_STATUS_PERR | PCIM_STATUS_SERR | + PCIM_STATUS_RMABORT | PCIM_STATUS_RTABORT | + PCIM_STATUS_PERRREPORT)) != 0 || + (csr & (SCZ_PCI_CTRL_BUS_UNUS | TOM_PCI_CTRL_DTO_ERR | + STX_PCI_CTRL_TTO_ERR | STX_PCI_CTRL_RTRY_ERR | + SCZ_PCI_CTRL_SBH_ERR | STX_PCI_CTRL_SERR)) != 0 || + (afsr & (STX_PCI_AFSR_P_MA | STX_PCI_AFSR_P_TA | + STX_PCI_AFSR_P_RTRY | STX_PCI_AFSR_P_PERR | STX_PCI_AFSR_P_TTO | + STX_PCI_AFSR_P_UNUS)) != 0) + fatal = 1; + if (fatal == 0) + sc->sc_stats_pci_non_fatal++; + + device_printf(sc->sc_dev, "PCI bus %c error AFAR %#llx AFSR %#llx " + "PCI CSR %#llx IOMMU %#llx STATUS %#llx\n", 'A' + sc->sc_half, + (unsigned long long)afar, (unsigned long long)afsr, + (unsigned long long)csr, (unsigned long long)iommu, + (unsigned long long)status); - clear_error: - if (bootverbose) - device_printf(sc->sc_dev, - "PCI bus %c error AFAR %#llx AFSR %#llx PCI CSR %#llx " - "STATUS %#llx", 'A' + sc->sc_half, - (unsigned long long)afar, (unsigned long long)afsr, - (unsigned long long)csr, (unsigned long long)status); /* Clear the error bits that we caught. */ PCIB_WRITE_CONFIG(sc->sc_dev, sc->sc_pci_secbus, STX_CS_DEVICE, STX_CS_FUNC, PCIR_STATUS, status, 2); SCHIZO_PCI_WRITE_8(sc, STX_PCI_CTRL, csr); SCHIZO_PCI_WRITE_8(sc, STX_PCI_AFSR, afsr); + SCHIZO_PCI_WRITE_8(sc, STX_PCI_IOMMU, iommu); + + mtx_unlock_spin(sc->sc_mtx); + + if (fatal != 0) + panic("%s: fatal PCI bus error", + device_get_nameunit(sc->sc_dev)); return (FILTER_HANDLED); } @@ -853,13 +888,11 @@ schizo_ue(void *arg) uint64_t afar, afsr; int i; - mtx_lock_spin(sc->sc_mtx); afar = SCHIZO_CTRL_READ_8(sc, STX_CTRL_UE_AFAR); for (i = 0; i < 1000; i++) if (((afsr = SCHIZO_CTRL_READ_8(sc, STX_CTRL_UE_AFSR)) & STX_CTRL_CE_AFSR_ERRPNDG) == 0) break; - mtx_unlock_spin(sc->sc_mtx); panic("%s: uncorrectable DMA error AFAR %#llx AFSR %#llx", device_get_nameunit(sc->sc_dev), (unsigned long long)afar, (unsigned long long)afsr); @@ -874,17 +907,22 @@ schizo_ce(void *arg) int i; mtx_lock_spin(sc->sc_mtx); + afar = SCHIZO_CTRL_READ_8(sc, STX_CTRL_CE_AFAR); for (i = 0; i < 1000; i++) if (((afsr = SCHIZO_CTRL_READ_8(sc, STX_CTRL_UE_AFSR)) & STX_CTRL_CE_AFSR_ERRPNDG) == 0) break; + sc->sc_stats_dma_ce++; device_printf(sc->sc_dev, "correctable DMA error AFAR %#llx AFSR %#llx\n", (unsigned long long)afar, (unsigned long long)afsr); + /* Clear the error bits that we caught. */ SCHIZO_CTRL_WRITE_8(sc, STX_CTRL_UE_AFSR, afsr); + mtx_unlock_spin(sc->sc_mtx); + return (FILTER_HANDLED); } Modified: head/sys/sparc64/pci/schizoreg.h ============================================================================== --- head/sys/sparc64/pci/schizoreg.h Fri May 14 19:57:18 2010 (r208096) +++ head/sys/sparc64/pci/schizoreg.h Fri May 14 20:00:21 2010 (r208097) @@ -42,6 +42,7 @@ #define STX_ICON 3 /* PCI configuration and status registers */ +#define SX_PCI_CFG_ICD 0x00110 #define STX_PCI_IOMMU 0x00200 #define STX_PCI_IOMMU_CTXFLUSH 0x00218 #define STX_PCI_IMAP_BASE 0x01000 @@ -67,6 +68,15 @@ #define STX_PCI_IOBIO_DIAG 0x0a808 #define STX_PCI_STRBUF_CTXMATCH 0x10000 +/* PCI configuration/idle check diagnostic registers */ +#define SX_PCI_CFG_ICD_PCI_2_0_COMPAT 0x0000000000008000ULL +#define SX_PCI_CFG_ICD_DMAW_PERR_IEN 0x0000000000004000ULL +#define SX_PCI_CFG_ICD_IFC_NOT_IDLE 0x0000000000000010ULL +#define SX_PCI_CFG_ICD_MDU_NOT_IDLE 0x0000000000000008ULL +#define SX_PCI_CFG_ICD_MMU_NOT_IDLE 0x0000000000000004ULL +#define SX_PCI_CFG_ICD_PBM_NOT_IDLE 0x0000000000000002ULL +#define SX_PCI_CFG_ICD_STC_NOT_IDLE 0x0000000000000001ULL + /* PCI IOMMU control registers */ #define TOM_PCI_IOMMU_ERR_BAD_VA 0x0000000010000000ULL #define TOM_PCI_IOMMU_ERR_ILLTSBTBW 0x0000000008000000ULL Modified: head/sys/sparc64/pci/schizovar.h ============================================================================== --- head/sys/sparc64/pci/schizovar.h Fri May 14 19:57:18 2010 (r208096) +++ head/sys/sparc64/pci/schizovar.h Fri May 14 20:00:21 2010 (r208097) @@ -44,9 +44,8 @@ struct schizo_softc { #define SCHIZO_MODE_XMS 2 u_int sc_flags; -#define SCHIZO_FLAGS_ARMED (1 << 0) -#define SCHIZO_FLAGS_BSWAR (1 << 1) -#define SCHIZO_FLAGS_CDMA (1 << 2) +#define SCHIZO_FLAGS_BSWAR (1 << 0) +#define SCHIZO_FLAGS_CDMA (1 << 1) bus_addr_t sc_cdma_clr; uint32_t sc_cdma_state; @@ -71,6 +70,9 @@ struct schizo_softc { bus_space_tag_t sc_pci_memt; bus_dma_tag_t sc_pci_dmat; + uint32_t sc_stats_dma_ce; + uint32_t sc_stats_pci_non_fatal; + uint8_t sc_pci_secbus; uint8_t sc_pci_subbus;