svn commit: r221295 - projects/altix/sys/ia64/sgisn

Marcel Moolenaar marcel at FreeBSD.org
Sun May 1 05:36:59 UTC 2011


Author: marcel
Date: Sun May  1 05:36:59 2011
New Revision: 221295
URL: http://svn.freebsd.org/changeset/base/221295

Log:
  Each bus is in its own domain and each domain assigns resources
  independently to devices and from the same local address window.
  As such, we need the PCI host controller to manage the resources.

Modified:
  projects/altix/sys/ia64/sgisn/sgisn_pcib.c
  projects/altix/sys/ia64/sgisn/sgisn_shub.c

Modified: projects/altix/sys/ia64/sgisn/sgisn_pcib.c
==============================================================================
--- projects/altix/sys/ia64/sgisn/sgisn_pcib.c	Sun May  1 03:16:13 2011	(r221294)
+++ projects/altix/sys/ia64/sgisn/sgisn_pcib.c	Sun May  1 05:36:59 2011	(r221295)
@@ -31,6 +31,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/systm.h>
 #include <sys/kernel.h>
 #include <sys/module.h>
+#include <sys/malloc.h>
 #include <sys/bus.h>
 #include <sys/pcpu.h>
 #include <sys/rman.h>
@@ -63,6 +64,8 @@ struct sgisn_pcib_softc {
 	bus_space_handle_t sc_hndl;
 	u_int		sc_domain;
 	u_int		sc_busnr;
+	struct rman	sc_ioport;
+	struct rman	sc_iomem;
 };
 
 static int sgisn_pcib_attach(device_t);
@@ -70,6 +73,19 @@ static int sgisn_pcib_probe(device_t);
 
 static int sgisn_pcib_activate_resource(device_t, device_t, int, int,
     struct resource *);
+static struct resource *sgisn_pcib_alloc_resource(device_t, device_t, int,
+    int *, u_long, u_long, u_long, u_int);
+static int sgisn_pcib_deactivate_resource(device_t, device_t, int, int,
+    struct resource *);
+static void sgisn_pcib_delete_resource(device_t, device_t, int, int);
+static int sgisn_pcib_get_resource(device_t, device_t, int, int, u_long *,
+    u_long *);
+static struct resource_list *sgisn_pcib_get_resource_list(device_t, device_t);
+static int sgisn_pcib_release_resource(device_t, device_t, int, int,
+    struct resource *);
+static int sgisn_pcib_set_resource(device_t, device_t, int, int, u_long,
+    u_long);
+
 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);
 
@@ -78,10 +94,6 @@ static uint32_t sgisn_pcib_cfgread(devic
 static void sgisn_pcib_cfgwrite(device_t, u_int, u_int, u_int, u_int, uint32_t,
     int);
 
-#if 0
-static int sgisn_pcib_scan(struct sgisn_pcib_softc *, u_int, u_int);
-#endif
-
 /*
  * Bus interface definitions.
  */
@@ -91,13 +103,17 @@ static device_method_t sgisn_pcib_method
 	DEVMETHOD(device_attach,	sgisn_pcib_attach),
 
 	/* Bus interface */
-        DEVMETHOD(bus_read_ivar,	sgisn_pcib_read_ivar),
-        DEVMETHOD(bus_write_ivar,	sgisn_pcib_write_ivar),
+	DEVMETHOD(bus_read_ivar,	sgisn_pcib_read_ivar),
+	DEVMETHOD(bus_write_ivar,	sgisn_pcib_write_ivar),
 	DEVMETHOD(bus_print_child,	bus_generic_print_child),
-	DEVMETHOD(bus_alloc_resource,	bus_generic_alloc_resource),
-	DEVMETHOD(bus_release_resource,	bus_generic_release_resource),
 	DEVMETHOD(bus_activate_resource, sgisn_pcib_activate_resource),
-	DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
+	DEVMETHOD(bus_alloc_resource,	sgisn_pcib_alloc_resource),
+	DEVMETHOD(bus_deactivate_resource, sgisn_pcib_deactivate_resource),
+	DEVMETHOD(bus_delete_resource,	sgisn_pcib_delete_resource),
+	DEVMETHOD(bus_get_resource,	sgisn_pcib_get_resource),
+	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_teardown_intr,	bus_generic_teardown_intr),
 
@@ -157,93 +173,123 @@ static int
 sgisn_pcib_activate_resource(device_t dev, device_t child, int type, int rid,
     struct resource *res)
 {
+	int error;
+
+	error = rman_activate_resource(res);
+	return (error);
+}
+
+static struct resource *
+sgisn_pcib_alloc_resource(device_t dev, device_t child, int type, int *rid,
+    u_long start, u_long end, u_long count, u_int flags)
+{
 	struct ia64_sal_result r;
+	struct rman *rm;
+	struct resource *rv;
 	struct sgisn_pcib_softc *sc;
 	device_t parent;
 	void *vaddr;
+	uint64_t base;
 	uintptr_t func, slot;
-	vm_paddr_t paddr;
-	u_long base;
 	int bar, error;
- 
-	parent = device_get_parent(child);
 
-	error = BUS_READ_IVAR(parent, child, PCI_IVAR_SLOT, &slot);
-	if (!error)
-		error = BUS_READ_IVAR(parent, child, PCI_IVAR_FUNCTION, &func);
-	if (error)
-		return (error);
+	if (type == SYS_RES_IRQ)
+		return (bus_generic_alloc_resource(dev, child, type, rid,
+		    start, end, count, flags));
+
+	bar = PCI_RID2BAR(*rid);
+	if (bar < 0 || bar > PCIR_MAX_BAR_0)
+		return (NULL);
 
 	sc = device_get_softc(dev);
+	rm = (type == SYS_RES_MEMORY) ? &sc->sc_iomem : &sc->sc_ioport;
+	rv = rman_reserve_resource(rm, start, end, count, flags, child);
+	if (rv == NULL)
+		return (NULL);
+
+	parent = device_get_parent(child);
+	error = BUS_READ_IVAR(parent, child, PCI_IVAR_SLOT, &slot);
+	if (error)
+		goto fail;
+	error = BUS_READ_IVAR(parent, child, PCI_IVAR_FUNCTION, &func);
+	if (error)
+		goto fail;
 
 	r = ia64_sal_entry(SAL_SGISN_IODEV_INFO, sc->sc_domain, sc->sc_busnr,
 	    (slot << 3) | func, ia64_tpa((uintptr_t)&sgisn_dev),
 	    ia64_tpa((uintptr_t)&sgisn_irq), 0, 0);
 	if (r.sal_status != 0)
-		return (ENXIO);
-
-	paddr = rman_get_start(res);
+		goto fail;
 
-	if (type == SYS_RES_IRQ) {
-		/* For now, only warn when there's a mismatch. */
-		if (paddr != sgisn_irq.irq_nr)
-			device_printf(dev, "interrupt mismatch: (actual=%u)\n",
-			    sgisn_irq.irq_nr);
-
-                printf("XXX: nasid=%u, slice=%u, cpuid=%u, irq=%u, pin=%u, "
-		    "xtaddr=%#lx\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);
-		printf("XXX: brt=%u, br=%p, dev=%p, last=%u, cookie=%#x, "
-		    "flags=%#x, refcnt=%u\n", 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);
-
-#if 0
-		intrs = bus_space_read_8(sc->sc_tag, sc->sc_hndl,
-		    PIC_REG_INT_ENABLE);
-		intrs |= 1 << sgisn_irq.irq_pin;
-		bus_space_write_8(sc->sc_tag, sc->sc_hndl, PIC_REG_INT_ENABLE,
-		    intrs);
-
-		bus_space_write_8(sc->sc_tag, sc->sc_hndl,
-		    PIC_REG_INT_PIN(sgisn_irq.irq_pin), 1);
-
-		sgisn_dev.dev_parent = sc->sc_fwbus;
-		sgisn_dev.dev_irq = &sgisn_irq;
-		sgisn_irq.irq_dev = &sgisn_dev;
-
-		r = ia64_sal_entry(SAL_SGISN_INTERRUPT, 1 /*alloc*/,
-		    sgisn_irq.irq_nasid, (sgisn_irq.irq_bridge >> 24) & 15,
-		    ia64_tpa((uintptr_t)&sgisn_irq),
-		    paddr,
-		    sgisn_irq.irq_nasid,
-		    sgisn_irq.irq_slice);
-		if (r.status != 0)
-			return (ENXIO);
-#endif
-
-		goto out;
-	}
-
-	bar = PCI_RID2BAR(rid);
-	if (bar < 0 || bar > PCIR_MAX_BAR_0)
-		return (EINVAL);
-	base = sgisn_dev.dev_bar[bar];
-	if (base != paddr)
+	base = sgisn_dev.dev_bar[bar] & 0x7fffffffffffffffL;
+	if (base != start)
 		device_printf(dev, "PCI bus address %#lx mapped to CPU "
-		    "address %#lx\n", paddr, base);
+		    "address %#lx\n", start, base);
 
 	/* I/O port space is presented as memory mapped I/O. */
-	rman_set_bustag(res, IA64_BUS_SPACE_MEM);
-	vaddr = pmap_mapdev(base, rman_get_size(res));
-	rman_set_bushandle(res, (bus_space_handle_t) vaddr);
+	rman_set_bustag(rv, IA64_BUS_SPACE_MEM);
+	vaddr = pmap_mapdev(base, count);
+	rman_set_bushandle(rv, (bus_space_handle_t)vaddr);
 	if (type == SYS_RES_MEMORY)
-		rman_set_virtual(res, vaddr);
+		rman_set_virtual(rv, vaddr);
+	return (rv);
+
+ fail:
+	rman_release_resource(rv);
+	return (NULL);
+}
+
+static int
+sgisn_pcib_deactivate_resource(device_t dev, device_t child, int type, int rid,
+    struct resource *res)
+{
+	int error;
+
+	error = rman_deactivate_resource(res);
+	return (error);
+}
+
+static void
+sgisn_pcib_delete_resource(device_t dev, device_t child, int type, int rid)
+{
+}
+
+static int
+sgisn_pcib_get_resource(device_t dev, device_t child, int type, int rid,
+    u_long *startp, u_long *countp)
+{
+
+	return (ENOENT);
+}
+
+static struct resource_list *
+sgisn_pcib_get_resource_list(device_t dev, device_t child)
+{
+
+	return (NULL);
+}
 
- out:
-	return (rman_activate_resource(res));
+static int
+sgisn_pcib_release_resource(device_t dev, device_t child, int type, int rid,
+    struct resource *res)
+{
+	int error;
+
+	if (rman_get_flags(res) & RF_ACTIVE) {
+		error = rman_deactivate_resource(res);
+		if (error)
+			return (error);
+	}
+	error = rman_release_resource(res);
+	return (error);
+}
+
+static int
+sgisn_pcib_set_resource(device_t dev, device_t child, int type, int rid,
+    u_long start, u_long count)
+{
+
+	return (ENXIO);
 }
 
 static int
@@ -283,12 +329,37 @@ sgisn_pcib_callout(void *arg)
 }
 
 static int
+sgisn_pcib_rm_init(struct sgisn_pcib_softc *sc, struct rman *rm,
+    const char *what)
+{
+	char descr[128];
+	int error;
+
+	rm->rm_start = 0UL;
+	rm->rm_end = 0x3ffffffffUL;		/* 16GB */
+	rm->rm_type = RMAN_ARRAY;
+	error = rman_init(rm);
+	if (error)
+		return (error);
+
+	snprintf(descr, sizeof(descr), "PCI %u:%u local I/O %s addresses",
+	    sc->sc_domain, sc->sc_busnr, what);
+	rm->rm_descr = strdup(descr, M_DEVBUF);
+
+	error = rman_manage_region(rm, rm->rm_start, rm->rm_end);
+	if (error)
+		rman_fini(rm);
+
+	return (error);
+}
+
+static int
 sgisn_pcib_attach(device_t dev)
 {
 	struct sgisn_pcib_softc *sc;
 	device_t parent;
 	uintptr_t addr, bus, seg;
-	u_int i;
+	int error;
 
 	sc = device_get_softc(dev);
 	sc->sc_dev = dev;
@@ -299,6 +370,15 @@ sgisn_pcib_attach(device_t dev)
 	BUS_READ_IVAR(parent, dev, SHUB_IVAR_PCISEG, &seg);
 	sc->sc_domain = seg;
 
+	error = sgisn_pcib_rm_init(sc, &sc->sc_ioport, "port");
+	if (error)
+		return (error);
+	error = sgisn_pcib_rm_init(sc, &sc->sc_iomem, "memory");
+	if (error) {
+		rman_fini(&sc->sc_ioport);
+		return (error);
+	}
+
 	(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);
@@ -307,22 +387,9 @@ sgisn_pcib_attach(device_t dev)
 	bus_space_map(sc->sc_tag, sc->sc_ioaddr, PIC_REG_SIZE, 0,
 	    &sc->sc_hndl);
 
-	device_printf(dev, "ASIC=%x, XID=%u\n", sc->sc_fwbus->bus_asic,
-	    sc->sc_fwbus->bus_xid);
-
-	device_printf(dev, "INTR status=%lx\n",
-	    bus_space_read_8(sc->sc_tag, sc->sc_hndl, PIC_REG_INT_STATUS));
-	device_printf(dev, "INTR enable=%lx\n",
-	    bus_space_read_8(sc->sc_tag, sc->sc_hndl, PIC_REG_INT_ENABLE));
-	device_printf(dev, "INTR addrs:");
-	for (i = 0; i < 8; i++)
-		printf(" %lx", bus_space_read_8(sc->sc_tag, sc->sc_hndl,
-		    PIC_REG_INT_ADDR(i)));
-	printf("\n");
-
-#if 0
-	sgisn_pcib_scan(sc, sc->sc_busnr, sgisn_pcib_maxslots(dev));
-#endif
+	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);
 
@@ -358,55 +425,3 @@ sgisn_pcib_write_ivar(device_t dev, devi
 	}
 	return (ENOENT);
 }
-
-#if 0
-static int
-sgisn_pcib_scan(struct sgisn_pcib_softc *sc, u_int bus, u_int maxslot)
-{
-	static struct sgisn_fwdev dev;
-	static struct sgisn_fwirq irq;
-	struct ia64_sal_result r;
-	u_int devfn, func, maxfunc, slot;
-	uint8_t hdrtype;
-
-	for (slot = 0; slot <= maxslot; slot++) {
-		maxfunc = 0;
-		for (func = 0; func <= maxfunc; func++) {
-			hdrtype = sgisn_pcib_cfgread(sc->sc_dev, bus, slot,
-			    func, PCIR_HDRTYPE, 1);
-
-			if ((hdrtype & PCIM_HDRTYPE) > PCI_MAXHDRTYPE)
-				continue;
-
-			if (func == 0 && (hdrtype & PCIM_MFDEV))
-				maxfunc = PCI_FUNCMAX;
-
-			printf("XXX: %s: %u:%u:%u:%u: ", __func__,
-			    sc->sc_domain, bus, slot, func);
-
-			devfn = (slot << 3) | func;
-			r = ia64_sal_entry(SAL_SGISN_IODEV_INFO, sc->sc_domain,
-			    bus, devfn, ia64_tpa((uintptr_t)&dev),
-			    ia64_tpa((uintptr_t)&irq), 0, 0);
-
-			if (r.sal_status != 0) {
-				printf("status %#lx\n", r.sal_status);
-				continue;
-			}
-
-			printf("handle=%#lx\n", dev.dev_handle);
-			printf("  BAR: %#lx, %#lx, %#lx, %#lx, %#lx, %#lx\n",
-			    dev.dev_bar[0], dev.dev_bar[1], dev.dev_bar[2],
-			    dev.dev_bar[3], dev.dev_bar[4], dev.dev_bar[5]);
-			printf("  ROM: %#lx\n", dev.dev_rom);
-
-			printf("  IRT: nodeid=%#x, slice=%#x, cpuid=%#x\n",
-			    irq.irq_nasid, irq.irq_slice, irq.irq_cpuid);
-			printf("  IRQ: nr=%#x, pin=%#x, xtaddr=%#lx\n",
-			    irq.irq_no, irq.irq_pin, irq.irq_xtaddr);
-		}
-	}
-
-	return (0);
-}
-#endif

Modified: projects/altix/sys/ia64/sgisn/sgisn_shub.c
==============================================================================
--- projects/altix/sys/ia64/sgisn/sgisn_shub.c	Sun May  1 03:16:13 2011	(r221294)
+++ projects/altix/sys/ia64/sgisn/sgisn_shub.c	Sun May  1 05:36:59 2011	(r221295)
@@ -126,81 +126,10 @@ static int
 sgisn_shub_activate_resource(device_t dev, device_t child, int type, int rid,
     struct resource *res)
 {
-#if 0
-	struct ia64_sal_result r;
-	struct sgisn_shub_softc *sc;
-	device_t parent;
-	void *vaddr;
-	uintptr_t func, slot;
-	vm_paddr_t paddr;
-	u_long base;
-	int bar, error;
- 
-	parent = device_get_parent(child);
-
-	error = BUS_READ_IVAR(parent, child, PCI_IVAR_SLOT, &slot);
-	if (!error)
-		error = BUS_READ_IVAR(parent, child, PCI_IVAR_FUNCTION, &func);
-	if (error)
-		return (error);
-
-	sc = device_get_softc(dev);
-
-	r = ia64_sal_entry(SAL_SGISN_IODEV_INFO, sc->sc_domain, sc->sc_busnr,
-	    (slot << 3) | func, ia64_tpa((uintptr_t)&sgisn_dev),
-	    ia64_tpa((uintptr_t)&sgisn_irq), 0, 0);
-	if (r.sal_status != 0)
-		return (ENXIO);
-
-	paddr = rman_get_start(res);
-
-	if (type == SYS_RES_IRQ) {
-		/* For now, only warn when there's a mismatch. */
-		if (paddr != sgisn_irq.irq_nr)
-			device_printf(dev, "interrupt mismatch: (actual=%u)\n",
-			    sgisn_irq.irq_nr);
-
-	printf("XXX: %s: %u, %u, %u, %u, %u, %#lx\n", __func__,
-	    sgisn_irq.irq_tgt_nasid, sgisn_irq.irq_tgt_slice,
-	    sgisn_irq.irq_cpuid, sgisn_irq.irq_nr, sgisn_irq.irq_pin,
-	    sgisn_irq.irq_tgt_xtaddr);
-	printf("\t%u, %p, %p, %u, %#x, %#x, %u\n", sgisn_irq.irq_br_type,
-	    sgisn_irq.irq_bridge, sgisn_irq.irq_io_info, sgisn_irq.irq_last,
-	    sgisn_irq.irq_cookie, sgisn_irq.irq_flags, sgisn_irq.irq_refcnt);
-
-		r = ia64_sal_entry(SAL_SGISN_INTERRUPT, 1 /*alloc*/,
-		    sgisn_irq.irq_tgt_nasid,
-		    (sgisn_irq.irq_bridge >> 24) & 15
-		    ia64_tpa((uintptr_t)&sgisn_irq),
-		    paddr,
-		    sgisn_irq.irq_tgt_nasid,
-		    sgisn_irq.irq_tgt_slice);
-		if (r.status != 0)
-			return (ENXIO);
-
-		goto out;
-	}
-
-	bar = PCI_RID2BAR(rid);
-	if (bar < 0 || bar > PCIR_MAX_BAR_0)
-		return (EINVAL);
-	base = sgisn_dev.dev_bar[bar];
-	if (base != paddr)
-		device_printf(dev, "PCI bus address %#lx mapped to CPU "
-		    "address %#lx\n", paddr, base);
-
-	/* I/O port space is presented as memory mapped I/O. */
-	rman_set_bustag(res, IA64_BUS_SPACE_MEM);
-	vaddr = pmap_mapdev(base, rman_get_size(res));
-	rman_set_bushandle(res, (bus_space_handle_t) vaddr);
-	if (type == SYS_RES_MEMORY)
-		rman_set_virtual(res, vaddr);
-
- out:
-	return (rman_activate_resource(res));
-#endif
+	int error;
 
-	return (EDOOFUS);
+	error = bus_activate_resource(dev, type, rid, res);
+	return (error);
 }
 
 static struct resource *


More information about the svn-src-projects mailing list