svn commit: r237934 - in projects/altix2/sys/ia64: ia64 sgisn

Marcel Moolenaar marcel at FreeBSD.org
Sun Jul 1 17:33:07 UTC 2012


Author: marcel
Date: Sun Jul  1 17:33:07 2012
New Revision: 237934
URL: http://svn.freebsd.org/changeset/base/237934

Log:
  Dump a WIP
  1.  Introduce the global shub_iack function that gets called to
      acknowledge interrupts. Remove the 1-off handling for sncon0.
      What this really means is that we need a PIC abstraction that
      works for both the Altix and DIG interrupt model.
  2.  Commit the iommu_map methods that make the busdma/mi code work
      that way it does right now.
  3.  Remove the callout code from the pcib driver. It didn't give
      me anything useful.
  4.  Add commented-out debugging printfs that I now need to change
      into KTR or other mechanisms.

Modified:
  projects/altix2/sys/ia64/ia64/interrupt.c
  projects/altix2/sys/ia64/sgisn/sgisn_console.c
  projects/altix2/sys/ia64/sgisn/sgisn_pcib.c
  projects/altix2/sys/ia64/sgisn/sgisn_pcib.h
  projects/altix2/sys/ia64/sgisn/sgisn_shub.c

Modified: projects/altix2/sys/ia64/ia64/interrupt.c
==============================================================================
--- projects/altix2/sys/ia64/ia64/interrupt.c	Sun Jul  1 17:15:50 2012	(r237933)
+++ projects/altix2/sys/ia64/ia64/interrupt.c	Sun Jul  1 17:33:07 2012	(r237934)
@@ -59,6 +59,8 @@ __FBSDID("$FreeBSD$");
 #include <ddb/ddb.h>
 #endif
 
+extern void shub_iack(const char *f, u_int xiv);
+
 struct ia64_intr {
 	struct intr_event *event;	/* interrupt event */
 	volatile long *cntp;		/* interrupt counter */
@@ -158,6 +160,8 @@ ia64_intr_eoi(void *arg)
 	KASSERT(i != NULL, ("%s", __func__));
 	if (i->sapic != NULL)
 		sapic_eoi(i->sapic, xiv);
+	else
+		shub_iack(__func__, xiv);
 }
 
 static void
@@ -171,7 +175,8 @@ ia64_intr_mask(void *arg)
 	if (i->sapic != NULL) {
 		sapic_mask(i->sapic, i->irq);
 		sapic_eoi(i->sapic, xiv);
-	}
+	} else
+		shub_iack(__func__, xiv);
 }
 
 static void

Modified: projects/altix2/sys/ia64/sgisn/sgisn_console.c
==============================================================================
--- projects/altix2/sys/ia64/sgisn/sgisn_console.c	Sun Jul  1 17:15:50 2012	(r237933)
+++ projects/altix2/sys/ia64/sgisn/sgisn_console.c	Sun Jul  1 17:33:07 2012	(r237934)
@@ -292,10 +292,6 @@ sncon_rx_intr(void *arg)
 	if (count > 0)
 		ttydisc_rint_done(tp);
 	tty_unlock(tp);
-
-	/* Acknowledge handling of Shub event. */
-	BUS_WRITE_IVAR(device_get_parent(sc->sc_dev), sc->sc_dev,
-	    SHUB_IVAR_EVENT, SHUB_EVENT_CONSOLE);
 }
 
 static void

Modified: projects/altix2/sys/ia64/sgisn/sgisn_pcib.c
==============================================================================
--- projects/altix2/sys/ia64/sgisn/sgisn_pcib.c	Sun Jul  1 17:15:50 2012	(r237933)
+++ projects/altix2/sys/ia64/sgisn/sgisn_pcib.c	Sun Jul  1 17:33:07 2012	(r237934)
@@ -60,7 +60,7 @@ static struct sgisn_fwirq sgisn_irq;
 
 struct sgisn_pcib_softc {
 	device_t	sc_dev;
-	struct sgisn_fwbus *sc_fwbus;
+	struct sgisn_fwpcib *sc_fwbus;
 	bus_addr_t	sc_ioaddr;
 	bus_space_tag_t	sc_tag;
 	bus_space_handle_t sc_hndl;
@@ -88,6 +88,9 @@ static int sgisn_pcib_release_resource(d
 static int sgisn_pcib_set_resource(device_t, device_t, int, int, u_long,
     u_long);
 
+static int sgisn_pcib_setup_intr(device_t, device_t, struct resource *, int,
+    driver_filter_t *, driver_intr_t *, void *, void **);
+
 static int sgisn_pcib_read_ivar(device_t, device_t, int, uintptr_t *);
 static int sgisn_pcib_write_ivar(device_t, device_t, int, uintptr_t);
 
@@ -97,6 +100,7 @@ static void sgisn_pcib_cfgwrite(device_t
     int);
 
 static int sgisn_pcib_iommu_xlate(device_t, busdma_mtag_t);
+static int sgisn_pcib_iommu_map(device_t, busdma_md_t, u_int, bus_addr_t *);
 
 /*
  * Bus interface definitions.
@@ -118,7 +122,7 @@ static device_method_t sgisn_pcib_method
 	DEVMETHOD(bus_get_resource_list, sgisn_pcib_get_resource_list),
 	DEVMETHOD(bus_release_resource,	sgisn_pcib_release_resource),
 	DEVMETHOD(bus_set_resource,	sgisn_pcib_set_resource),
-	DEVMETHOD(bus_setup_intr,	bus_generic_setup_intr),
+	DEVMETHOD(bus_setup_intr,	sgisn_pcib_setup_intr),
 	DEVMETHOD(bus_teardown_intr,	bus_generic_teardown_intr),
 
 	/* pcib interface */
@@ -129,6 +133,7 @@ static device_method_t sgisn_pcib_method
 
 	/* busdma interface */
 	DEVMETHOD(busdma_iommu_xlate,	sgisn_pcib_iommu_xlate),
+	DEVMETHOD(busdma_iommu_map,	sgisn_pcib_iommu_map),
 
 	{ 0, 0 }
 };
@@ -182,6 +187,11 @@ sgisn_pcib_activate_resource(device_t de
 {
 	int error;
 
+	// device_printf(dev, "%s(dev=%s, child=%s, type=%u, rid=%u, res=%p"
+	//     "[%#lx-%#lx])\n", __func__, device_get_nameunit(dev),
+	//     device_get_nameunit(child), type, rid, res, rman_get_start(res),
+	//     rman_get_end(res));
+
 	error = rman_activate_resource(res);
 	return (error);
 }
@@ -200,6 +210,11 @@ sgisn_pcib_alloc_resource(device_t dev, 
 	uintptr_t func, slot;
 	int bar, error;
 
+	// device_printf(dev, "%s(dev=%s, child=%s, type=%u, rid=%u, "
+	//     "start=%#lx, end=%#lx, count=%#lx, flags=%x)\n", __func__,
+	//     device_get_nameunit(dev), device_get_nameunit(child), type,
+	//     *rid, start, end, count, flags);
+
 	if (type == SYS_RES_IRQ)
 		return (bus_generic_alloc_resource(dev, child, type, rid,
 		    start, end, count, flags));
@@ -233,6 +248,15 @@ sgisn_pcib_alloc_resource(device_t dev, 
 		device_printf(dev, "PCI bus address %#lx mapped to CPU "
 		    "address %#lx\n", start, base);
 
+	// device_printf(child, "nas=%#x, slice=%#x, cpuid=%#x, nr=%#x, "
+	//     "pin=%#x, xtaddr=%#lx, br_type=%#x, bridge=%p, dev=%p, "
+	//     "last=%#x, cookie=%#x, flags=%#x, refcnt=%#x\n",
+	//     sgisn_irq.irq_nasid, sgisn_irq.irq_slice, sgisn_irq.irq_cpuid,
+	//     sgisn_irq.irq_nr, sgisn_irq.irq_pin, sgisn_irq.irq_xtaddr,
+	//     sgisn_irq.irq_br_type, sgisn_irq.irq_bridge, sgisn_irq.irq_dev,
+	//     sgisn_irq.irq_last, sgisn_irq.irq_cookie, sgisn_irq.irq_flags,
+	//     sgisn_irq.irq_refcnt);
+
 	/* I/O port space is presented as memory mapped I/O. */
 	rman_set_bustag(rv, IA64_BUS_SPACE_MEM);
 	vaddr = pmap_mapdev(base, count);
@@ -252,6 +276,11 @@ sgisn_pcib_deactivate_resource(device_t 
 {
 	int error;
 
+	// device_printf(dev, "%s(dev=%s, child=%s, type=%u, rid=%u, res=%p"
+	//     "[%#lx-%#lx])\n", __func__, device_get_nameunit(dev),
+	//     device_get_nameunit(child), type, rid, res, rman_get_start(res),
+	//     rman_get_end(res));
+
 	error = rman_deactivate_resource(res);
 	return (error);
 }
@@ -259,6 +288,10 @@ sgisn_pcib_deactivate_resource(device_t 
 static void
 sgisn_pcib_delete_resource(device_t dev, device_t child, int type, int rid)
 {
+
+	// device_printf(dev, "%s(dev=%s, child=%s, type=%u, rid=%u)\n",
+	//     __func__, device_get_nameunit(dev), device_get_nameunit(child),
+	//     type, rid);
 }
 
 static int
@@ -266,6 +299,9 @@ sgisn_pcib_get_resource(device_t dev, de
     u_long *startp, u_long *countp)
 {
 
+	// device_printf(dev, "%s(dev=%s, child=%s, type=%u, rid=%u, "
+	//     "startp=%p, countp=%p)\n", __func__, device_get_nameunit(dev),
+	//     device_get_nameunit(child), type, rid, startp, countp);
 	return (ENOENT);
 }
 
@@ -273,6 +309,8 @@ static struct resource_list *
 sgisn_pcib_get_resource_list(device_t dev, device_t child)
 {
 
+	// device_printf(dev, "%s(dev=%s, child=%s)\n", __func__,
+	//     device_get_nameunit(dev), device_get_nameunit(child));
 	return (NULL);
 }
 
@@ -282,6 +320,11 @@ sgisn_pcib_release_resource(device_t dev
 {
 	int error;
 
+	// device_printf(dev, "%s(dev=%s, child=%s, type=%u, rid=%u, res=%p"
+	//     "[%#lx-%#lx])\n", __func__, device_get_nameunit(dev),
+	//     device_get_nameunit(child), type, rid, res, rman_get_start(res),
+	//     rman_get_end(res));
+
 	if (rman_get_flags(res) & RF_ACTIVE) {
 		error = rman_deactivate_resource(res);
 		if (error)
@@ -296,10 +339,36 @@ sgisn_pcib_set_resource(device_t dev, de
     u_long start, u_long count)
 {
 
+	// device_printf(dev, "%s(dev=%s, child=%s, type=%u, rid=%u, "
+	//     "start=%#lx, count=%#lx)\n", __func__, device_get_nameunit(dev),
+	//     device_get_nameunit(child), type, rid, start, count);
 	return (ENXIO);
 }
 
 static int
+sgisn_pcib_setup_intr(device_t dev, device_t child, struct resource *irq,
+    int flags, driver_filter_t *ifltr, driver_intr_t *ihdlr, void *arg,
+    void **cookiep)
+{
+	struct sgisn_pcib_softc *sc;
+	uint64_t ie;
+	int error;
+
+	// device_printf(dev, "%s(dev=%s, child=%s, irq=%lu, flags=%#x, "
+	//     "ifltr=%p, ihdlr=%p, arg=%p, cookiep=%p)\n", __func__,
+	//     device_get_nameunit(dev), device_get_nameunit(child),
+	//     rman_get_start(irq), flags, ifltr, ihdlr, arg, cookiep);
+
+	sc = device_get_softc(dev);
+	ie = bus_space_read_8(sc->sc_tag, sc->sc_hndl, PIC_REG_INT_ENABLE);
+	// device_printf(dev, "INT_ENABLE=%#lx\n", ie);
+
+	error = bus_generic_setup_intr(dev, child, irq, flags, ifltr, ihdlr,
+	    arg, cookiep);
+	return (error);
+}
+
+static int
 sgisn_pcib_probe(device_t dev)
 {
 	device_t parent;
@@ -317,24 +386,6 @@ sgisn_pcib_probe(device_t dev)
 	return (BUS_PROBE_DEFAULT);
 }
 
-static void
-sgisn_pcib_callout(void *arg)
-{
-	static u_long islast = ~0UL;
-	struct sgisn_pcib_softc *sc = arg;
-	u_long is;
-
-	is = bus_space_read_8(sc->sc_tag, sc->sc_hndl, PIC_REG_INT_STATUS);
-	if (is != islast) {
-		islast = is;
-		printf("XXX: %s: INTR status = %lu, IRR=%#lx:%#lx:%#lx:%#lx\n",
-		    __func__, is, ia64_get_irr0(), ia64_get_irr1(),
-		    ia64_get_irr2(), ia64_get_irr3());
-	}
-
-	timeout(sgisn_pcib_callout, sc, hz);
-}
-
 static int
 sgisn_pcib_rm_init(struct sgisn_pcib_softc *sc, struct rman *rm,
     const char *what)
@@ -389,19 +440,19 @@ sgisn_pcib_attach(device_t dev)
 	(void)ia64_sal_entry(SAL_SGISN_IOBUS_INFO, seg, bus,
 	    ia64_tpa((uintptr_t)&addr), 0, 0, 0, 0);
 	sc->sc_fwbus = (void *)IA64_PHYS_TO_RR7(addr);
-	sc->sc_ioaddr = IA64_RR_MASK(sc->sc_fwbus->bus_base);
+	sc->sc_ioaddr = IA64_RR_MASK(sc->sc_fwbus->fw_common.bus_base);
 	sc->sc_tag = IA64_BUS_SPACE_MEM;
 	bus_space_map(sc->sc_tag, sc->sc_ioaddr, PIC_REG_SIZE, 0,
 	    &sc->sc_hndl);
 
 	if (bootverbose)
-		device_printf(dev, "ASIC=%x, XID=%u\n", sc->sc_fwbus->bus_asic,
-		    sc->sc_fwbus->bus_xid);
-
-	timeout(sgisn_pcib_callout, sc, hz);
+		device_printf(dev, "ASIC=%x, XID=%u\n",
+		    sc->sc_fwbus->fw_common.bus_asic,
+		    sc->sc_fwbus->fw_common.bus_xid);
 
 	device_add_child(dev, "pci", -1);
-	return (bus_generic_attach(dev));
+	error = bus_generic_attach(dev);
+	return (error);
 }
 
 static int
@@ -436,12 +487,34 @@ sgisn_pcib_write_ivar(device_t dev, devi
 static int
 sgisn_pcib_iommu_xlate(device_t dev, busdma_mtag_t mtag)
 {
+	vm_paddr_t bndry = 0x80000000UL;
 
 	/*
 	 * Use a 31-bit direct-mapped window for PCI devices that are not
-	 * 64-bit capable.
+	 * 64-bit capable. In that case we also make sure allocations do
+	 * not cross the 2G boundary so that the whole segment can be
+	 * direct mapped.
 	 */
-	if (mtag->dmt_maxaddr < ~0UL)
-		mtag->dmt_maxaddr &= 0x7fffffffUL;
+	if (mtag->dmt_maxaddr < ~0UL) {
+		mtag->dmt_maxaddr &= (bndry - 1);
+		if (mtag->dmt_bndry == 0 || mtag->dmt_bndry > bndry)
+			mtag->dmt_bndry = bndry;
+	}
 	return (0);
 }
+
+static int
+sgisn_pcib_iommu_map(device_t dev, busdma_md_t md, u_int idx, bus_addr_t *ba_p)
+{
+	bus_addr_t bndry = 0x80000000UL;
+	bus_addr_t ba;
+
+	ba = *ba_p;
+	if (ba < bndry) {
+		ba |= bndry;
+		*ba_p = ba;
+		return (0);
+	}
+
+	return (ENXIO);
+}

Modified: projects/altix2/sys/ia64/sgisn/sgisn_pcib.h
==============================================================================
--- projects/altix2/sys/ia64/sgisn/sgisn_pcib.h	Sun Jul  1 17:15:50 2012	(r237933)
+++ projects/altix2/sys/ia64/sgisn/sgisn_pcib.h	Sun Jul  1 17:33:07 2012	(r237934)
@@ -73,4 +73,20 @@
 #define	PIC_REG_WR_REQ(x)	(0x00240 + (x << 3))
 #define	PIC_REG_RRB_MAP(x)	(0x00280 + (x << 3))
 
+struct sgisn_fwpcib {
+	struct sgisn_fwbus	fw_common;
+	uint32_t		fw_modid;
+	uint16_t		fw_type;
+	uint16_t		fw_mode;
+	uint64_t		*fw_ate_base;
+	uint64_t		fw_ate_count;
+	uint64_t		fw_ate_idx;
+	uint64_t		fw_ate_size;
+	uint64_t		fw_xbase;
+	uint8_t			fw_hub_xid;
+	uint64_t		fw_regs[8];
+	uint32_t		fw_dev_valid;
+	uint32_t		fw_dev_enabled;
+};
+
 #endif /* _IA64_SGISN_PCIB_H_ */

Modified: projects/altix2/sys/ia64/sgisn/sgisn_shub.c
==============================================================================
--- projects/altix2/sys/ia64/sgisn/sgisn_shub.c	Sun Jul  1 17:15:50 2012	(r237933)
+++ projects/altix2/sys/ia64/sgisn/sgisn_shub.c	Sun Jul  1 17:33:07 2012	(r237934)
@@ -55,6 +55,8 @@ __FBSDID("$FreeBSD$");
 
 #include <ia64/sgisn/sgisn_shub.h>
 
+void shub_iack(const char *f, u_int xiv);
+
 struct sgisn_shub_softc {
 	struct sgisn_fwhub *sc_fwhub;
 	device_t	sc_dev;
@@ -90,6 +92,7 @@ static int sgisn_shub_set_resource(devic
 static int sgisn_shub_write_ivar(device_t, device_t, int, uintptr_t);
 
 static int sgisn_shub_iommu_xlate(device_t, busdma_mtag_t);
+static int sgisn_shub_iommu_map(device_t, busdma_md_t, u_int, bus_addr_t *);
 
 /*
  * Bus interface definitions.
@@ -116,6 +119,7 @@ static device_method_t sgisn_shub_method
 
 	/* busdma interface */
 	DEVMETHOD(busdma_iommu_xlate,	sgisn_shub_iommu_xlate),
+	DEVMETHOD(busdma_iommu_map,	sgisn_shub_iommu_map),
 
 	{ 0, 0 }
 };
@@ -123,6 +127,8 @@ static device_method_t sgisn_shub_method
 static devclass_t sgisn_shub_devclass;
 static char sgisn_shub_name[] = "shub";
 
+static device_t shub_dev;
+
 static driver_t sgisn_shub_driver = {
 	sgisn_shub_name,
 	sgisn_shub_methods,
@@ -377,6 +383,8 @@ sgisn_shub_attach(device_t dev)
 	sc->sc_dev = dev;
 	sc->sc_domain = device_get_unit(dev);
 
+	shub_dev = dev;
+
 	/*
 	 * Get the physical memory region that is connected to the MD I/F
 	 * of this SHub. It allows us to allocate memory that's close to
@@ -534,3 +542,39 @@ sgisn_shub_iommu_xlate(device_t dev, bus
 	mtag->dmt_maxaddr += sc->sc_membase;
 	return (0);
 }
+
+static int
+sgisn_shub_iommu_map(device_t dev, busdma_md_t md, u_int idx, bus_addr_t *ba_p)
+{
+	struct sgisn_shub_softc *sc;
+	bus_addr_t ba;
+
+	sc = device_get_softc(dev);
+	ba = *ba_p;
+	if (ba >= sc->sc_membase && ba < sc->sc_membase + sc->sc_memsize) {
+		ba -= sc->sc_membase;
+		*ba_p = ba;
+	}
+	return (0);
+}
+
+void
+shub_iack(const char *f, u_int xiv)
+{
+	uintptr_t mask;
+
+	printf("%s(%u) -- ", f, xiv);
+	mask = (xiv == 0xe9) ? SHUB_EVENT_CONSOLE : 0x670000000;
+	sgisn_shub_write_ivar(shub_dev, NULL, SHUB_IVAR_EVENT, mask);
+}
+
+static void
+shub_conf_final(void *arg)
+{
+
+	if (shub_dev != NULL)
+		sgisn_shub_write_ivar(shub_dev, NULL, SHUB_IVAR_EVENT,
+		    0x670000000);
+}
+SYSINIT(shub_configure, SI_SUB_CONFIGURE, SI_ORDER_ANY, shub_conf_final, NULL);
+


More information about the svn-src-projects mailing list