PERFORCE change 150207 for review

Marius Strobl marius at FreeBSD.org
Sun Sep 21 14:10:50 UTC 2008


http://perforce.freebsd.org/chv.cgi?CH=150207

Change 150207 by marius at flak on 2008/09/21 14:10:24

	- Clear any possibly pending PCI error bits left by the firmware.
	  These could trigger an error interrupt that we can't actually to
	  do anything against as soon as enabling the error handlers.
	  While at it don't bother about writing only to the W1C bits when
	  clearing error bits.
	- Pre-calculate the value for the DMA write sync register and add
	  a flag for the additional Tomatillo DMA sync workaround as micro-
	  optimizations.

Affected files ...

.. //depot/projects/usiii/sparc64/pci/schizo.c#12 edit
.. //depot/projects/usiii/sparc64/pci/schizoreg.h#5 edit

Differences ...

==== //depot/projects/usiii/sparc64/pci/schizo.c#12 (text+ko) ====

@@ -1,7 +1,7 @@
 /*-
  * Copyright (c) 1999, 2000 Matthew R. Green
  * Copyright (c) 2001 - 2003 by Thomas Moestl <tmm at FreeBSD.org>
- * Copyright (c) 2005 by Marius Strobl <marius at FreeBSD.org>
+ * Copyright (c) 2005, 2008 by Marius Strobl <marius at FreeBSD.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -28,7 +28,7 @@
  * SUCH DAMAGE.
  *
  *	from: NetBSD: psycho.c,v 1.39 2001/10/07 20:30:41 eeh Exp
- *	from: FreeBSD: psycho.c,v 1.53 2005/01/07 02:29:22 imp Exp
+ *	from: FreeBSD: psycho.c 183152 2008-09-18 19:45:22Z marius
  */
 
 #include <sys/cdefs.h>
@@ -175,8 +175,9 @@
 	driver_filter_t		*sds_handler;
 	void			*sds_arg;
 	void			*sds_cookie;
-	uint64_t		sds_syncreg;
-	u_int			sds_ino;
+	bus_size_t		sds_syncreg;
+	uint64_t		sds_syncval;
+	u_int			sds_bswar;
 };
 
 #define	SCHIZO_PERF_CNT_QLTY	100
@@ -255,7 +256,7 @@
 	struct schizo_softc *asc, *sc, *osc;
 	struct timecounter *tc;
 	bus_addr_t intrclr, intrmap;
-	uint64_t reg;
+	uint64_t ino_bitmap, reg;
 	phandle_t node;
 	uint32_t prop, prop_array[2];
 	int i, mode, n, nrange, rid, tsbsize;
@@ -348,8 +349,7 @@
 	reg = SCHIZO_PCI_READ_8(sc, STX_PCI_CTRL);
 	reg |= STX_PCI_CTRL_MMU_IEN | STX_PCI_CTRL_SBH_IEN |
 	    STX_PCI_CTRL_ERR_IEN | STX_PCI_CTRL_ARB_MASK;
-	reg &= ~(TOM_PCI_CTRL_DTO_IEN | STX_PCI_CTRL_SERR |
-	    STX_PCI_CTRL_ARB_PARK);
+	reg &= ~(TOM_PCI_CTRL_DTO_IEN | STX_PCI_CTRL_ARB_PARK);
 	if (OF_getproplen(node, "no-bus-parking") < 0)
 		reg |= STX_PCI_CTRL_ARB_PARK;
 	if (mode == SCHIZO_MODE_TOM) {
@@ -366,9 +366,6 @@
 #endif
 	SCHIZO_PCI_WRITE_8(sc, STX_PCI_CTRL, reg);
 
-	/* Clear PCI AFSR. */
-	SCHIZO_PCI_WRITE_8(sc, STX_PCI_AFSR, STX_PCI_AFSR_ERRMASK);
-
 	/* Set up the PCI diagnostic register. */
 	reg = SCHIZO_PCI_READ_8(sc, STX_PCI_DIAG);
 	reg &= ~(SCZ_PCI_DIAG_RTRYARB_DIS | STX_PCI_DIAG_RETRY_DIS |
@@ -399,9 +396,9 @@
 	    sizeof(prop_array));
 	if (n == -1)
 		panic("%s: could not get ino-bitmap", __func__);
-	reg = ((uint64_t)prop_array[1] << 32) | prop_array[0];
+	ino_bitmap = ((uint64_t)prop_array[1] << 32) | prop_array[0];
 	for (n = 0; n <= STX_MAX_INO; n++) {
-		if ((reg & (1ULL << n)) == 0)
+		if ((ino_bitmap & (1ULL << n)) == 0)
 			continue;
 		if (n == STX_FB0_INO || n == STX_FB1_INO)
 			/* Leave for upa(4). */
@@ -427,69 +424,10 @@
 	}
 
 	/*
-	 * Someone at Sun clearly was smoking crack; with Schizos PCI
-	 * bus error interrupts for one PBM can be routed to the other
-	 * PBM though we obviously need to use the softc of the former
-	 * as the argument for the interrupt handler and the softc of
-	 * the latter as the argument for the interrupt controller.
-	 */
-	if (sc->sc_half == 0) {
-		if ((reg & (1ULL << STX_PCIERR_A_INO)) != 0 ||
-		    (osc != NULL && ((struct schizo_icarg *)intr_vectors[
-		    INTMAP_VEC(sc->sc_ign, STX_PCIERR_A_INO)].iv_icarg)->
-		    sica_sc == osc))
-			/*
-			 * We are the driver for PBM A and either also
-			 * registered the interrupt controller for us or
-			 * the driver for PBM B has probed first and
-			 * registered it for us.
-			 */
-			schizo_set_intr(sc, 0, STX_PCIERR_A_INO,
-			    schizo_pci_bus);
-		if ((reg & (1ULL << STX_PCIERR_B_INO)) != 0 && osc != NULL)
-			/*
-			 * We are the driver for PBM A but registered
-			 * the interrupt controller for PBM B, i.e. the
-			 * driver for PBM B attached first but couldn't
-			 * set up a handler for PBM B.
-			 */
-			schizo_set_intr(osc, 0, STX_PCIERR_B_INO,
-			    schizo_pci_bus);
-	} else {
-		if ((reg & (1ULL << STX_PCIERR_B_INO)) != 0 ||
-		    (osc != NULL && ((struct schizo_icarg *)intr_vectors[
-		    INTMAP_VEC(sc->sc_ign, STX_PCIERR_B_INO)].iv_icarg)->
-		    sica_sc == osc))
-			/*
-			 * We are the driver for PBM B and either also
-			 * registered the interrupt controller for us or
-			 * the driver for PBM A has probed first and
-			 * registered it for us.
-			 */
-			schizo_set_intr(sc, 0, STX_PCIERR_B_INO,
-			    schizo_pci_bus);
-		if ((reg & (1ULL << STX_PCIERR_A_INO)) != 0 && osc != NULL)
-			/*
-			 * We are the driver for PBM B but registered
-			 * the interrupt controller for PBM A, i.e. the
-			 * driver for PBM A attached first but couldn't
-			 * set up a handler for PBM A.
-			 */
-			schizo_set_intr(osc, 0, STX_PCIERR_A_INO,
-			    schizo_pci_bus);
-	}
-	if ((reg & (1ULL << STX_UE_INO)) != 0)
-		schizo_set_intr(sc, 1, STX_UE_INO, schizo_ue);
-	if ((reg & (1ULL << STX_CE_INO)) != 0)
-		schizo_set_intr(sc, 2, STX_CE_INO, schizo_ce);
-	if ((reg & (1ULL << STX_BUS_INO)) != 0)
-		schizo_set_intr(sc, 3, STX_BUS_INO, schizo_host_bus);
-
-	/*
 	 * Setup Safari/JBus performance counter 0 in bus cycle counting
 	 * mode as timecounter.  Unfortunately, this is broken with at
 	 * least the version 4 Tomatillos found in Fire V120 and Blade
-	 * 1500, which apprently actually count some different event at
+	 * 1500, which apparently actually count some different event at
 	 * ~0.5 and 3MHz respectively instead (also when running in full
 	 * power mode).  Besides, one counter seems to be shared by a
 	 * "pair" of Tomatillos, too.
@@ -617,11 +555,76 @@
 		    prop_array[0], prop_array[1], prop_array[0]);
 	sc->sc_pci_secbus = prop_array[0];
 
-	/* Clear PCI status error bits. */
+	/* Clear any pending PCI error bits. */
 	PCIB_WRITE_CONFIG(dev, sc->sc_pci_secbus, STX_CS_DEVICE, STX_CS_FUNC,
-	    PCIR_STATUS, PCIM_STATUS_PERR | PCIM_STATUS_RMABORT |
-	    PCIM_STATUS_RTABORT | PCIM_STATUS_STABORT |
-	    PCIM_STATUS_PERRREPORT, 2);
+	    PCIR_STATUS, PCIB_READ_CONFIG(dev, sc->sc_pci_secbus,
+	    STX_CS_DEVICE, STX_CS_FUNC, PCIR_STATUS, 2), 2);
+	SCHIZO_PCI_WRITE_8(sc, STX_PCI_CTRL,
+	    SCHIZO_PCI_READ_8(sc, STX_PCI_CTRL));
+	SCHIZO_PCI_WRITE_8(sc, STX_PCI_AFSR,
+	    SCHIZO_PCI_READ_8(sc, STX_PCI_AFSR));
+
+	/*
+	 * Establish handlers for interesting interrupts...
+	 * Someone at Sun clearly was smoking crack; with Schizos PCI
+	 * bus error interrupts for one PBM can be routed to the other
+	 * PBM though we obviously need to use the softc of the former
+	 * as the argument for the interrupt handler and the softc of
+	 * the latter as the argument for the interrupt controller.
+	 */
+	if (sc->sc_half == 0) {
+		if ((ino_bitmap & (1ULL << STX_PCIERR_A_INO)) != 0 ||
+		    (osc != NULL && ((struct schizo_icarg *)intr_vectors[
+		    INTMAP_VEC(sc->sc_ign, STX_PCIERR_A_INO)].iv_icarg)->
+		    sica_sc == osc))
+			/*
+			 * We are the driver for PBM A and either also
+			 * registered the interrupt controller for us or
+			 * the driver for PBM B has probed first and
+			 * registered it for us.
+			 */
+			schizo_set_intr(sc, 0, STX_PCIERR_A_INO,
+			    schizo_pci_bus);
+		if ((ino_bitmap & (1ULL << STX_PCIERR_B_INO)) != 0 &&
+		    osc != NULL)
+			/*
+			 * We are the driver for PBM A but registered
+			 * the interrupt controller for PBM B, i.e. the
+			 * driver for PBM B attached first but couldn't
+			 * set up a handler for PBM B.
+			 */
+			schizo_set_intr(osc, 0, STX_PCIERR_B_INO,
+			    schizo_pci_bus);
+	} else {
+		if ((ino_bitmap & (1ULL << STX_PCIERR_B_INO)) != 0 ||
+		    (osc != NULL && ((struct schizo_icarg *)intr_vectors[
+		    INTMAP_VEC(sc->sc_ign, STX_PCIERR_B_INO)].iv_icarg)->
+		    sica_sc == osc))
+			/*
+			 * We are the driver for PBM B and either also
+			 * registered the interrupt controller for us or
+			 * the driver for PBM A has probed first and
+			 * registered it for us.
+			 */
+			schizo_set_intr(sc, 0, STX_PCIERR_B_INO,
+			    schizo_pci_bus);
+		if ((ino_bitmap & (1ULL << STX_PCIERR_A_INO)) != 0 &&
+		    osc != NULL)
+			/*
+			 * We are the driver for PBM B but registered
+			 * the interrupt controller for PBM A, i.e. the
+			 * driver for PBM A attached first but couldn't
+			 * set up a handler for PBM A.
+			 */
+			schizo_set_intr(osc, 0, STX_PCIERR_A_INO,
+			    schizo_pci_bus);
+	}
+	if ((ino_bitmap & (1ULL << STX_UE_INO)) != 0)
+		schizo_set_intr(sc, 1, STX_UE_INO, schizo_ue);
+	if ((ino_bitmap & (1ULL << STX_CE_INO)) != 0)
+		schizo_set_intr(sc, 2, STX_CE_INO, schizo_ce);
+	if ((ino_bitmap & (1ULL << STX_BUS_INO)) != 0)
+		schizo_set_intr(sc, 3, STX_BUS_INO, schizo_host_bus);
 
 	/*
 	 * Set the latency timer register as this isn't always done by the
@@ -780,8 +783,7 @@
 	    "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 & STX_CTRL_CE_AFSR_ERRMASK);
+	SCHIZO_CTRL_WRITE_8(sc, STX_CTRL_UE_AFSR, afsr);
 	mtx_unlock_spin(sc->sc_mtx);
 	return (FILTER_HANDLED);
 }
@@ -956,18 +958,14 @@
 	uint64_t reg;
 	int timeout;
 
-	reg = 1ULL << sds->sds_ino;
-	SCHIZO_PCI_WRITE_8(sc, sds->sds_syncreg, reg);
+	SCHIZO_PCI_WRITE_8(sc, sds->sds_syncreg, sds->sds_syncval);
 	timeout = 1000000;
-	for (; SCHIZO_PCI_READ_8(sc, sds->sds_syncreg) & reg;)
+	for (; (SCHIZO_PCI_READ_8(sc, sds->sds_syncreg) &
+	    sds->sds_syncval) != 0;)
 		if (--timeout < 0)
 			panic("%s: DMA does not sync", __func__);
 
-	/*
-	 * Tomatillo revision <= 2.3 (i.e. version <= 4) bridges also
-	 *  need a block store as a workaround for a hardware bug.
-	 */
-	if (sc->sc_mode == SCHIZO_MODE_TOM && sc->sc_ver <= 4) {
+	if (sds->sds_bswar != 0) {
 		critical_enter();
 		reg = rd(fprs);
 		wr(fprs, reg | FPRS_FEF, 0);
@@ -1043,6 +1041,8 @@
 	/*
 	 * Schizo revision >= 2.3 (i.e. version >= 5) and Tomatillo bridges
 	 * need to be manually told to sync DMA writes.
+	 * Tomatillo revision <= 2.3 (i.e. version <= 4) bridges additionally
+	 * need a block store as a workaround for a hardware bug.
 	 * XXX setup of the wrapper and the contents of schizo_dmasync()
 	 * should be moved to schizo(4)-specific bus_dma_tag_create() and
 	 * bus_dmamap_sync() methods, respectively, once DMA tag creation
@@ -1058,7 +1058,9 @@
 		sds->sds_arg = arg;
 		sds->sds_syncreg = sc->sc_mode == SCHIZO_MODE_SCZ ?
 		    SCZ_PCI_DMA_SYNC : TOMXMS_PCI_DMA_SYNC_PEND;
-		sds->sds_ino = INTINO(vec);
+		sds->sds_syncval = 1ULL << INTINO(vec);
+		if (sc->sc_mode == SCHIZO_MODE_TOM && sc->sc_ver <= 4)
+			sds->sds_bswar = 1;
 		if (intr == NULL) {
 			sds->sds_handler = filt;
 			error = bus_generic_setup_intr(dev, child, ires,

==== //depot/projects/usiii/sparc64/pci/schizoreg.h#5 (text+ko) ====

@@ -122,11 +122,6 @@
 #define	STX_PCI_AFSR_MEM		0x0000000020000000ULL
 #define	STX_PCI_AFSR_IO			0x0000000010000000ULL
 
-#define	STX_PCI_AFSR_ERRMASK						\
-	(STX_PCI_AFSR_P_MA | STX_PCI_AFSR_P_TA | STX_PCI_AFSR_P_RTRY |	\
-	STX_PCI_AFSR_P_PERR | STX_PCI_AFSR_S_MA | STX_PCI_AFSR_S_TA |	\
-	STX_PCI_AFSR_S_RTRY | STX_PCI_AFSR_S_PERR)
-
 /* PCI diagnostic register */
 #define	SCZ_PCI_DIAG_BADECC_DIS		0x0000000000000400ULL
 #define	STX_PCI_DIAG_BYPASS_DIS		0x0000000000000200ULL
@@ -238,11 +233,6 @@
 #define	STX_CTRL_CE_AFSR_MTAG		0x000000000000e000ULL
 #define	STX_CTRL_CE_AFSR_ECCSYND	0x00000000000001ffULL
 
-#define	STX_CTRL_CE_AFSR_ERRMASK					\
-	(STX_CTRL_CE_AFSR_P_PIO | STX_CTRL_CE_AFSR_P_DRD |		\
-	STX_CTRL_CE_AFSR_P_DWR | STX_CTRL_CE_AFSR_S_PIO |		\
-	STX_CTRL_CE_AFSR_S_DRD | STX_CTRL_CE_AFSR_S_DWR)
-
 /*
  * Safari/JBus performance control register
  * NB: for Tomatillo only events 0x00 through 0x08 are documented as


More information about the p4-projects mailing list