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