From ca8712b098b36464d11a7dd20e2d0459121a2ace Mon Sep 17 00:00:00 2001 From: Thomas Moestl Date: Wed, 2 Jan 2002 18:27:13 +0000 Subject: Correct the defintion of struct ofw_upa_regs, and use it instead of struct ofw_nexus_reg. Implement UPA device memory management in the nexus driver. Adapt the psycho driver to these changes, and do some minor cleanup work while being there. --- sys/sparc64/include/nexusvar.h | 10 +------ sys/sparc64/include/ofw_nexus.h | 6 ++++- sys/sparc64/include/ofw_upa.h | 6 ++++- sys/sparc64/pci/psycho.c | 60 ++++++++++++++++++++++------------------- sys/sparc64/pci/psychovar.h | 8 +++--- sys/sparc64/sparc64/nexus.c | 53 +++++++++++++++++++++++------------- 6 files changed, 82 insertions(+), 61 deletions(-) diff --git a/sys/sparc64/include/nexusvar.h b/sys/sparc64/include/nexusvar.h index 5ad396b3fd19..f62ebcdceb75 100644 --- a/sys/sparc64/include/nexusvar.h +++ b/sys/sparc64/include/nexusvar.h @@ -37,16 +37,9 @@ enum nexus_ivars { NEXUS_IVAR_NREG, NEXUS_IVAR_INTERRUPTS, NEXUS_IVAR_NINTERRUPTS, - NEXUS_IVAR_BUSTAG, NEXUS_IVAR_DMATAG, }; -/* XXX: these are the UPA registers and should probably go elsewhere */ -struct ofw_nexus_reg { - int64_t or_paddr; - int64_t or_len; -}; - /* * Simplified accessors for nexus devices * XXX: These should be made specializations of generic bus accessor macros @@ -59,11 +52,10 @@ NEXUS_ACCESSOR(node, NODE, phandle_t) NEXUS_ACCESSOR(name, NAME, char *) NEXUS_ACCESSOR(device_type, DEVICE_TYPE, char *) NEXUS_ACCESSOR(model, MODEL, char *) -NEXUS_ACCESSOR(reg, REG, struct ofw_nexus_reg *) +NEXUS_ACCESSOR(reg, REG, struct upa_regs *) NEXUS_ACCESSOR(nreg, NREG, int) NEXUS_ACCESSOR(interrupts, INTERRUPTS, u_int *) NEXUS_ACCESSOR(ninterrupts, NINTERRUPTS, int) -NEXUS_ACCESSOR(bustag, BUSTAG, bus_space_tag_t) NEXUS_ACCESSOR(dmatag, DMATAG, bus_dma_tag_t) #undef NEXUS_ACCESSOR diff --git a/sys/sparc64/include/ofw_nexus.h b/sys/sparc64/include/ofw_nexus.h index c920a9cfc833..7ee0c401910e 100644 --- a/sys/sparc64/include/ofw_nexus.h +++ b/sys/sparc64/include/ofw_nexus.h @@ -41,7 +41,6 @@ struct upa_regs { u_int32_t phys_hi; - u_int32_t phys_mid; u_int32_t phys_lo; u_int32_t size_hi; u_int32_t size_lo; @@ -57,6 +56,11 @@ struct upa_ranges { u_int32_t size_lo; }; +#define UPA_REG_PHYS(r) \ + (((u_int64_t)(r)->phys_hi << 32) | (u_int64_t)(r)->phys_lo) +#define UPA_REG_SIZE(r) \ + (((u_int64_t)(r)->size_hi << 32) | (u_int64_t)(r)->size_lo) + #define UPA_RANGE_CHILD(r) \ (((u_int64_t)(r)->child_hi << 32) | (u_int64_t)(r)->child_lo) #define UPA_RANGE_PHYS(r) \ diff --git a/sys/sparc64/include/ofw_upa.h b/sys/sparc64/include/ofw_upa.h index c920a9cfc833..7ee0c401910e 100644 --- a/sys/sparc64/include/ofw_upa.h +++ b/sys/sparc64/include/ofw_upa.h @@ -41,7 +41,6 @@ struct upa_regs { u_int32_t phys_hi; - u_int32_t phys_mid; u_int32_t phys_lo; u_int32_t size_hi; u_int32_t size_lo; @@ -57,6 +56,11 @@ struct upa_ranges { u_int32_t size_lo; }; +#define UPA_REG_PHYS(r) \ + (((u_int64_t)(r)->phys_hi << 32) | (u_int64_t)(r)->phys_lo) +#define UPA_REG_SIZE(r) \ + (((u_int64_t)(r)->size_hi << 32) | (u_int64_t)(r)->size_lo) + #define UPA_RANGE_CHILD(r) \ (((u_int64_t)(r)->child_hi << 32) | (u_int64_t)(r)->child_lo) #define UPA_RANGE_PHYS(r) \ diff --git a/sys/sparc64/pci/psycho.c b/sys/sparc64/pci/psycho.c index ff62dfdfc7cd..cff534ade443 100644 --- a/sys/sparc64/pci/psycho.c +++ b/sys/sparc64/pci/psycho.c @@ -267,14 +267,14 @@ psycho_attach(device_t dev) struct psycho_softc *sc; struct psycho_softc *osc = NULL; struct psycho_softc *asc; - struct ofw_nexus_reg *reg; + struct upa_regs *reg; char compat[32]; char *model; phandle_t node; u_int64_t csr; - u_long pci_ctl; + u_long pci_ctl, mlen; int psycho_br[2]; - int n, i, nreg; + int n, i, nreg, rid; #if defined(PSYCHO_DEBUG) || defined(PSYCHO_STRAY) u_long *map, *clr; #endif @@ -287,7 +287,6 @@ psycho_attach(device_t dev) sc->sc_node = node; sc->sc_dev = dev; - sc->sc_bustag = nexus_get_bustag(dev); sc->sc_dmatag = nexus_get_dmatag(dev); /* @@ -319,28 +318,34 @@ psycho_attach(device_t dev) nreg = nexus_get_nreg(dev); /* Register layouts are different. stuupid. */ if (sc->sc_mode == PSYCHO_MODE_PSYCHO) { - sc->sc_basepaddr = (vm_offset_t)reg[2].or_paddr; - - if (nreg <= 2) { + if (nreg <= 2) panic("psycho_attach: %d not enough registers", nreg); - } - if (sparc64_bus_mem_map(UPA_BUS_SPACE, reg[2].or_paddr, - reg[2].or_len, 0, NULL, (void **)&sc->sc_regs)) - panic("psycho_attach: cannot map regs"); - pci_ctl = reg[0].or_paddr; + sc->sc_basepaddr = (vm_offset_t)UPA_REG_PHYS(®[2]); + mlen = UPA_REG_SIZE(®[2]); + pci_ctl = UPA_REG_PHYS(®[0]); } else { - sc->sc_basepaddr = (vm_offset_t)reg[0].or_paddr; - - if (nreg <= 0) { + if (nreg <= 0) panic("psycho_attach: %d not enough registers", nreg); - } - if (sparc64_bus_mem_map(UPA_BUS_SPACE, reg[0].or_paddr, - reg[0].or_len, 0, NULL, (void **)&sc->sc_regs)) - panic("psycho_attach: cannot map regs"); - pci_ctl = reg[0].or_paddr + + sc->sc_basepaddr = (vm_offset_t)UPA_REG_PHYS(®[0]); + mlen = UPA_REG_SIZE(reg); + pci_ctl = sc->sc_basepaddr + offsetof(struct psychoreg, psy_pcictl[0]); } + if (pci_ctl < sc->sc_basepaddr) + panic("psycho_attach: bogus pci control register location"); + pci_ctl -= sc->sc_basepaddr; + rid = 0; + sc->sc_mem_res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, + sc->sc_basepaddr, sc->sc_basepaddr + mlen - 1, mlen, RF_ACTIVE); + if (sc->sc_mem_res == NULL || + rman_get_start(sc->sc_mem_res) != sc->sc_basepaddr) + panic("psycho_attach: could not allocate device memory"); + sc->sc_bustag = rman_get_bustag(sc->sc_mem_res); + sc->sc_bushandle = rman_get_bushandle(sc->sc_mem_res); + if (sparc64_bus_mem_map(UPA_BUS_SPACE, sc->sc_basepaddr, mlen, 0, NULL, + (void **)&sc->sc_regs)) + panic("psycho_attach: cannot map regs"); csr = sc->sc_regs->psy_csr; sc->sc_ign = 0x7c0; /* APB IGN is always 0x7c */ if (sc->sc_mode == PSYCHO_MODE_PSYCHO) @@ -375,8 +380,8 @@ psycho_attach(device_t dev) /* * Setup the PCI control register */ - csr = bus_space_read_8(sc->sc_bustag, - (bus_space_handle_t)pci_ctl, offsetof(struct pci_ctl, pci_csr)); + csr = bus_space_read_8(sc->sc_bustag, sc->sc_bushandle, + pci_ctl + offsetof(struct pci_ctl, pci_csr)); csr |= PCICTL_MRLM | PCICTL_ARB_PARK | PCICTL_ERRINTEN | @@ -385,9 +390,8 @@ psycho_attach(device_t dev) PCICTL_CPU_PRIO | PCICTL_ARB_PRIO | PCICTL_RTRYWAIT); - bus_space_write_8(sc->sc_bustag, - (bus_space_handle_t)pci_ctl, offsetof(struct pci_ctl, pci_csr), - csr); + bus_space_write_8(sc->sc_bustag, sc->sc_bushandle, + pci_ctl + offsetof(struct pci_ctl, pci_csr), csr); /* grab the psycho ranges */ psycho_get_ranges(sc->sc_node, &sc->sc_range, &sc->sc_nrange); @@ -590,11 +594,11 @@ psycho_set_intr(struct psycho_softc *sc, int index, { int rid; - sc->sc_irq[index] = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, + sc->sc_irq_res[index] = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, INTVEC(*map), INTVEC(*map), 1, RF_ACTIVE); - if (sc->sc_irq[index] == NULL) + if (sc->sc_irq_res[index] == NULL) panic("psycho_set_intr: failed to get interupt"); - bus_setup_intr(dev, sc->sc_irq[index], INTR_TYPE_MISC | iflags, + bus_setup_intr(dev, sc->sc_irq_res[index], INTR_TYPE_MISC | iflags, handler, sc, &sc->sc_ihand[index]); *map |= INTMAP_V; } diff --git a/sys/sparc64/pci/psychovar.h b/sys/sparc64/pci/psychovar.h index 790f3614f9df..0093d07fd326 100644 --- a/sys/sparc64/pci/psychovar.h +++ b/sys/sparc64/pci/psychovar.h @@ -40,7 +40,7 @@ struct psycho_softc { device_t sc_dev; /* - * PSYCHO register. we record the base physical address of these + * PSYCHO register. we record the base physical address of these * also as it is the base of the entire PSYCHO */ struct psychoreg *sc_regs; @@ -51,7 +51,8 @@ struct psycho_softc { /* our tags (from parent) */ bus_space_tag_t sc_bustag; - bus_dma_tag_t sc_dmatag; + bus_space_handle_t sc_bushandle; + bus_dma_tag_t sc_dmatag; int sc_clockfreq; phandle_t sc_node; /* prom node */ @@ -61,7 +62,8 @@ struct psycho_softc { struct iommu_state *sc_is; - struct resource *sc_irq[6]; + struct resource *sc_mem_res; + struct resource *sc_irq_res[6]; void *sc_ihand[6]; /* diff --git a/sys/sparc64/sparc64/nexus.c b/sys/sparc64/sparc64/nexus.c index 6fd462b50760..93f3d2fc2851 100644 --- a/sys/sparc64/sparc64/nexus.c +++ b/sys/sparc64/sparc64/nexus.c @@ -68,7 +68,9 @@ #include #include #include +#include #include +#include #include @@ -96,7 +98,7 @@ struct nexus_devinfo { char *ndi_name; char *ndi_device_type; char *ndi_model; - struct ofw_nexus_reg *ndi_reg; + struct upa_regs *ndi_reg; int ndi_nreg; u_int *ndi_interrupts; int ndi_ninterrupts; @@ -104,6 +106,11 @@ struct nexus_devinfo { bus_dma_tag_t ndi_dmatag; }; +struct nexus_softc { + struct rman sc_intr_rman; + struct rman sc_mem_rman; +}; + static int nexus_probe(device_t); static void nexus_probe_nomatch(device_t, device_t); static int nexus_read_ivar(device_t, device_t, int, uintptr_t *); @@ -148,7 +155,7 @@ static device_method_t nexus_methods[] = { static driver_t nexus_driver = { "nexus", nexus_methods, - 1, /* no softc */ + sizeof(struct nexus_softc), }; static devclass_t nexus_devclass; @@ -171,7 +178,6 @@ static char *nexus_excl_type[] = { NULL }; -struct rman intr_rman; extern struct bus_space_tag nexus_bustag; extern struct bus_dma_tag nexus_dmatag; @@ -197,16 +203,22 @@ nexus_probe(device_t dev) phandle_t child; device_t cdev; struct nexus_devinfo *dinfo; + struct nexus_softc *sc; char *name, *type; if ((root = OF_peer(0)) == -1) panic("nexus_probe: OF_peer failed."); - intr_rman.rm_type = RMAN_ARRAY; - intr_rman.rm_descr = "Interrupts"; - if (rman_init(&intr_rman) != 0 || - rman_manage_region(&intr_rman, 0, NIV - 1) != 0) - panic("nexus_probe: failed to set up rman"); + sc = device_get_softc(dev); + sc->sc_intr_rman.rm_type = RMAN_ARRAY; + sc->sc_intr_rman.rm_descr = "Interrupts"; + sc->sc_mem_rman.rm_type = RMAN_ARRAY; + sc->sc_mem_rman.rm_descr = "UPA Device Memory"; + if (rman_init(&sc->sc_intr_rman) != 0 || + rman_init(&sc->sc_mem_rman) != 0 || + rman_manage_region(&sc->sc_intr_rman, 0, NIV - 1) != 0 || + rman_manage_region(&sc->sc_mem_rman, UPA_MEMSTART, UPA_MEMEND) != 0) + panic("nexus_probe: failed to set up rmans"); for (child = OF_child(root); child != 0; child = OF_peer(child)) { if (child == -1) panic("nexus_probe(): OF_child failed."); @@ -218,7 +230,7 @@ nexus_probe(device_t dev) if (type != NULL) free(type, M_OFWPROP); continue; - } + } cdev = device_add_child(dev, NULL, -1); if (cdev != NULL) { dinfo = malloc(sizeof(*dinfo), M_NEXUS, M_WAITOK); @@ -254,7 +266,7 @@ nexus_probe_nomatch(device_t dev, device_t child) BUS_READ_IVAR(dev, child, NEXUS_IVAR_DEVICE_TYPE, (uintptr_t *)&type) != 0) return; - + if (type == NULL) type = "(unknown)"; device_printf(dev, "<%s>, type %s (no driver attached)\n", @@ -293,9 +305,6 @@ nexus_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) case NEXUS_IVAR_NINTERRUPTS: *result = dinfo->ndi_ninterrupts; break; - case NEXUS_IVAR_BUSTAG: - *result = (uintptr_t)dinfo->ndi_bustag; - break; case NEXUS_IVAR_DMATAG: *result = (uintptr_t)dinfo->ndi_dmatag; break; @@ -322,7 +331,6 @@ nexus_write_ivar(device_t dev, device_t child, int which, uintptr_t value) case NEXUS_IVAR_NREG: case NEXUS_IVAR_INTERRUPTS: case NEXUS_IVAR_NINTERRUPTS: - case NEXUS_IVAR_BUSTAG: case NEXUS_IVAR_DMATAG: return (EINVAL); default: @@ -336,7 +344,7 @@ nexus_setup_intr(device_t dev, device_t child, struct resource *res, int flags, driver_intr_t *intr, void *arg, void **cookiep) { int error; - + if (res == NULL) panic("nexus_setup_intr: NULL interrupt resource!"); @@ -372,6 +380,7 @@ static struct resource * nexus_alloc_resource(device_t bus, device_t child, int type, int *rid, u_long start, u_long end, u_long count, u_int flags) { + struct nexus_softc *sc = device_get_softc(bus); struct resource *rv; struct rman *rm; int needactivate = flags & RF_ACTIVE; @@ -380,7 +389,10 @@ nexus_alloc_resource(device_t bus, device_t child, int type, int *rid, switch (type) { case SYS_RES_IRQ: - rm = &intr_rman; + rm = &sc->sc_intr_rman; + break; + case SYS_RES_MEMORY: + rm = &sc->sc_mem_rman; break; default: return (NULL); @@ -389,7 +401,10 @@ nexus_alloc_resource(device_t bus, device_t child, int type, int *rid, rv = rman_reserve_resource(rm, start, end, count, flags, child); if (rv == NULL) return (NULL); - /* XXX: no bus_space_tag/bus_handle yet... */ + if (type == SYS_RES_MEMORY) { + rman_set_bustag(rv, &nexus_bustag); + rman_set_bushandle(rv, rman_get_start(rv)); + } if (needactivate) { if (bus_activate_resource(child, type, *rid, rv)) { @@ -397,7 +412,7 @@ nexus_alloc_resource(device_t bus, device_t child, int type, int *rid, return (NULL); } } - + return (rv); } @@ -414,7 +429,7 @@ static int nexus_deactivate_resource(device_t bus, device_t child, int type, int rid, struct resource *r) { - + /* Not much to be done yet... */ return (rman_deactivate_resource(r)); } -- cgit v1.2.3