diff options
-rw-r--r-- | sys/conf/files.sparc64 | 2 | ||||
-rw-r--r-- | sys/dev/fb/creator.c | 42 | ||||
-rw-r--r-- | sys/sparc64/central/central.c | 10 | ||||
-rw-r--r-- | sys/sparc64/fhc/fhc.c | 142 | ||||
-rw-r--r-- | sys/sparc64/fhc/fhc_central.c | 132 | ||||
-rw-r--r-- | sys/sparc64/fhc/fhc_nexus.c | 147 | ||||
-rw-r--r-- | sys/sparc64/fhc/fhcvar.h | 59 | ||||
-rw-r--r-- | sys/sparc64/include/bus_private.h | 7 | ||||
-rw-r--r-- | sys/sparc64/include/iommureg.h | 8 | ||||
-rw-r--r-- | sys/sparc64/include/nexusvar.h | 58 | ||||
-rw-r--r-- | sys/sparc64/include/ofw_nexus.h | 28 | ||||
-rw-r--r-- | sys/sparc64/include/ofw_upa.h | 54 | ||||
-rw-r--r-- | sys/sparc64/pci/psycho.c | 154 | ||||
-rw-r--r-- | sys/sparc64/pci/psychovar.h | 1 | ||||
-rw-r--r-- | sys/sparc64/sbus/sbus.c | 82 | ||||
-rw-r--r-- | sys/sparc64/sparc64/bus_machdep.c | 52 | ||||
-rw-r--r-- | sys/sparc64/sparc64/iommu.c | 47 | ||||
-rw-r--r-- | sys/sparc64/sparc64/nexus.c | 360 | ||||
-rw-r--r-- | sys/sparc64/sparc64/sc_machdep.c | 5 |
19 files changed, 551 insertions, 839 deletions
diff --git a/sys/conf/files.sparc64 b/sys/conf/files.sparc64 index a0ea02010889..d56a807f098d 100644 --- a/sys/conf/files.sparc64 +++ b/sys/conf/files.sparc64 @@ -80,8 +80,6 @@ sparc64/central/central.c optional central sparc64/ebus/ebus.c optional ebus sparc64/fhc/clkbrd.c optional clkbrd fhc sparc64/fhc/fhc.c optional fhc -sparc64/fhc/fhc_central.c optional fhc central -sparc64/fhc/fhc_nexus.c optional fhc sparc64/isa/isa.c optional isa sparc64/isa/isa_dma.c optional isa sparc64/isa/ofw_isa.c optional ebus | isa diff --git a/sys/dev/fb/creator.c b/sys/dev/fb/creator.c index f9f293c3ed3e..4fa88fa6aa3c 100644 --- a/sys/dev/fb/creator.c +++ b/sys/dev/fb/creator.c @@ -1,5 +1,6 @@ /*- * Copyright (c) 2003 Jake Burkholder. + * Copyright (c) 2005 - 2006 Marius Strobl <marius@FreeBSD.org> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -37,13 +38,12 @@ __FBSDID("$FreeBSD$"); #include <sys/module.h> #include <sys/resource.h> +#include <dev/ofw/ofw_bus.h> #include <dev/ofw/openfirm.h> #include <machine/bus.h> #include <machine/bus_private.h> -#include <machine/nexusvar.h> #include <machine/ofw_machdep.h> -#include <machine/ofw_upa.h> #include <machine/resource.h> #include <machine/sc_machdep.h> @@ -63,7 +63,6 @@ struct creator_softc { struct cdev *sc_si; - int sc_rid[FFB_NREG]; struct resource *sc_reg[FFB_NREG]; bus_space_tag_t sc_bt[FFB_NREG]; bus_space_handle_t sc_bh[FFB_NREG]; @@ -172,9 +171,7 @@ static devclass_t creator_devclass; DEFINE_CLASS_0(creator, creator_bus_driver, creator_bus_methods, sizeof(struct creator_softc)); DRIVER_MODULE(creator, nexus, creator_bus_driver, creator_devclass, 0, 0); -#if 0 DRIVER_MODULE(creator, upa, creator_bus_driver, creator_devclass, 0, 0); -#endif static d_open_t creator_fb_open; static d_close_t creator_fb_close; @@ -880,8 +877,8 @@ creator_bus_probe(device_t dev) phandle_t node; int type; - name = nexus_get_name(dev); - node = nexus_get_node(dev); + name = ofw_bus_get_name(dev); + node = ofw_bus_get_node(dev); if (strcmp(name, "SUNW,ffb") == 0) { if (OF_getprop(node, "board_type", &type, sizeof(type)) == -1) return (ENXIO); @@ -906,18 +903,15 @@ static int creator_bus_attach(device_t dev) { struct creator_softc *sc; - struct upa_regs *reg; video_adapter_t *adp; video_switch_t *sw; phandle_t node; - bus_addr_t phys; - bus_size_t size; int error; - int nreg; + int rid; int unit; int i; - node = nexus_get_node(dev); + node = ofw_bus_get_node(dev); if ((sc = (struct creator_softc *)vid_get_adapter(vid_find_adapter( CREATOR_DRIVER_NAME, 0))) != NULL && sc->sc_node == node) { device_printf(dev, "console\n"); @@ -940,20 +934,10 @@ creator_bus_attach(device_t dev) * allocate more than these two resources and just limit the * range accessible via creator_fb_mmap() accordingly. */ - reg = nexus_get_reg(dev); - nreg = nexus_get_nreg(dev); - if (nreg <= FFB_FBC) { - device_printf(dev, "not enough resources\n"); - error = ENXIO; - goto fail; - } - for (i = 0; i < nreg; i++) { - phys = UPA_REG_PHYS(reg + i); - size = UPA_REG_SIZE(reg + i); - sc->sc_rid[i] = i; - sc->sc_reg[i] = bus_alloc_resource(dev, SYS_RES_MEMORY, - &sc->sc_rid[i], phys, phys + size - 1, size, - RF_ACTIVE); + for (i = 0; i < FFB_NREG; i++) { + rid = i; + sc->sc_reg[i] = bus_alloc_resource_any(dev, SYS_RES_MEMORY, + &rid, RF_ACTIVE); if (sc->sc_reg[i] == NULL) { if (i <= FFB_FBC) { device_printf(dev, @@ -1000,7 +984,7 @@ creator_bus_attach(device_t dev) for (i = 0; i < devclass_get_maxunit(creator_devclass); i++) if (vid_find_adapter(CREATOR_DRIVER_NAME, i) < 0) break; - if (strcmp(nexus_get_name(dev), "SUNW,afb") == 0) + if (strcmp(ofw_bus_get_name(dev), "SUNW,afb") == 0) sc->sc_flags |= CREATOR_AFB; if ((error = sw->init(i, adp, 0)) != 0) { device_printf(dev, "cannot initialize adapter\n"); @@ -1031,8 +1015,8 @@ creator_bus_attach(device_t dev) fail: for (i = 0; i < FFB_NREG && sc->sc_reg[i] != NULL; i++) - bus_release_resource(dev, SYS_RES_MEMORY, sc->sc_rid[i], - sc->sc_reg[i]); + bus_release_resource(dev, SYS_RES_MEMORY, + rman_get_rid(sc->sc_reg[i]), sc->sc_reg[i]); return (error); } diff --git a/sys/sparc64/central/central.c b/sys/sparc64/central/central.c index 2d218b6c9a86..51b2a2216d5c 100644 --- a/sys/sparc64/central/central.c +++ b/sys/sparc64/central/central.c @@ -39,8 +39,6 @@ __FBSDID("$FreeBSD$"); #include <dev/ofw/openfirm.h> #include <machine/bus.h> -#include <machine/nexusvar.h> -#include <machine/ofw_upa.h> #include <machine/resource.h> #include <sys/rman.h> @@ -68,14 +66,14 @@ static ofw_bus_get_devinfo_t central_get_devinfo; static int central_print_res(struct central_devinfo *); static device_method_t central_methods[] = { - /* Device interface. */ + /* Device interface */ DEVMETHOD(device_probe, central_probe), DEVMETHOD(device_attach, central_attach), DEVMETHOD(device_shutdown, bus_generic_shutdown), DEVMETHOD(device_suspend, bus_generic_suspend), DEVMETHOD(device_resume, bus_generic_resume), - /* Bus interface. */ + /* Bus interface */ DEVMETHOD(bus_print_child, central_print_child), DEVMETHOD(bus_probe_nomatch, central_probe_nomatch), DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), @@ -112,7 +110,7 @@ static int central_probe(device_t dev) { - if (strcmp(nexus_get_name(dev), "central") == 0) { + if (strcmp(ofw_bus_get_name(dev), "central") == 0) { device_set_desc(dev, "central"); return (0); } @@ -132,7 +130,7 @@ central_attach(device_t dev) int i; sc = device_get_softc(dev); - node = nexus_get_node(dev); + node = ofw_bus_get_node(dev); sc->sc_nrange = OF_getprop_alloc(node, "ranges", sizeof(*sc->sc_ranges), (void **)&sc->sc_ranges); diff --git a/sys/sparc64/fhc/fhc.c b/sys/sparc64/fhc/fhc.c index a7972c8e8bec..d3c0e280156f 100644 --- a/sys/sparc64/fhc/fhc.c +++ b/sys/sparc64/fhc/fhc.c @@ -1,5 +1,6 @@ /*- * Copyright (c) 2003 Jake Burkholder. + * Copyright (c) 2005 Marius Strobl <marius@FreeBSD.org> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -32,6 +33,7 @@ __FBSDID("$FreeBSD$"); #include <sys/bus.h> #include <sys/kernel.h> #include <sys/malloc.h> +#include <sys/module.h> #include <sys/pcpu.h> #include <dev/led/led.h> @@ -46,7 +48,6 @@ __FBSDID("$FreeBSD$"); #include <sys/rman.h> #include <sparc64/fhc/fhcreg.h> -#include <sparc64/fhc/fhcvar.h> #include <sparc64/sbus/ofw_sbus.h> struct fhc_clr { @@ -62,18 +63,87 @@ struct fhc_devinfo { struct resource_list fdi_rl; }; -static int fhc_intr_stub(void *); +struct fhc_softc { + struct resource * sc_memres[FHC_NREG]; + bus_space_handle_t sc_bh[FHC_NREG]; + bus_space_tag_t sc_bt[FHC_NREG]; + int sc_nrange; + struct sbus_ranges *sc_ranges; + uint32_t sc_board; + int sc_ign; + struct cdev *sc_led_dev; + int sc_flags; +#define FHC_CENTRAL (1 << 0) +}; + +static device_probe_t fhc_probe; +static device_attach_t fhc_attach; +static bus_print_child_t fhc_print_child; +static bus_probe_nomatch_t fhc_probe_nomatch; +static bus_setup_intr_t fhc_setup_intr; +static bus_teardown_intr_t fhc_teardown_intr; +static bus_alloc_resource_t fhc_alloc_resource; +static bus_get_resource_list_t fhc_get_resource_list; +static ofw_bus_get_devinfo_t fhc_get_devinfo; + +static driver_filter_t fhc_intr_stub; static void fhc_led_func(void *, int); static int fhc_print_res(struct fhc_devinfo *); -int +static device_method_t fhc_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, fhc_probe), + DEVMETHOD(device_attach, fhc_attach), + DEVMETHOD(device_shutdown, bus_generic_shutdown), + DEVMETHOD(device_suspend, bus_generic_suspend), + DEVMETHOD(device_resume, bus_generic_resume), + + /* Bus interface */ + DEVMETHOD(bus_print_child, fhc_print_child), + DEVMETHOD(bus_probe_nomatch, fhc_probe_nomatch), + DEVMETHOD(bus_setup_intr, fhc_setup_intr), + DEVMETHOD(bus_teardown_intr, fhc_teardown_intr), + DEVMETHOD(bus_alloc_resource, fhc_alloc_resource), + DEVMETHOD(bus_release_resource, bus_generic_rl_release_resource), + DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), + DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), + DEVMETHOD(bus_get_resource_list, fhc_get_resource_list), + DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource), + + /* ofw_bus interface */ + DEVMETHOD(ofw_bus_get_devinfo, fhc_get_devinfo), + DEVMETHOD(ofw_bus_get_compat, ofw_bus_gen_get_compat), + DEVMETHOD(ofw_bus_get_model, ofw_bus_gen_get_model), + DEVMETHOD(ofw_bus_get_name, ofw_bus_gen_get_name), + DEVMETHOD(ofw_bus_get_node, ofw_bus_gen_get_node), + DEVMETHOD(ofw_bus_get_type, ofw_bus_gen_get_type), + + { NULL, NULL } +}; + +static driver_t fhc_driver = { + "fhc", + fhc_methods, + sizeof(struct fhc_softc), +}; + +static devclass_t fhc_devclass; + +DRIVER_MODULE(fhc, central, fhc_driver, fhc_devclass, 0, 0); +DRIVER_MODULE(fhc, nexus, fhc_driver, fhc_devclass, 0, 0); + +static int fhc_probe(device_t dev) { - return (0); + if (strcmp(ofw_bus_get_name(dev), "fhc") == 0) { + device_set_desc(dev, "fhc"); + return (0); + } + return (ENXIO); } -int +static int fhc_attach(device_t dev) { char ledname[sizeof("boardXX")]; @@ -83,16 +153,48 @@ fhc_attach(device_t dev) phandle_t child; phandle_t node; device_t cdev; + uint32_t board; uint32_t ctrl; uint32_t *intr; uint32_t iv; char *name; + int error; + int i; int nintr; int nreg; - int i; + int rid; sc = device_get_softc(dev); - node = sc->sc_node; + node = ofw_bus_get_node(dev); + + if (strcmp(device_get_name(device_get_parent(dev)), "central") == 0) + sc->sc_flags |= FHC_CENTRAL; + + for (i = 0; i < FHC_NREG; i++) { + rid = i; + sc->sc_memres[i] = bus_alloc_resource_any(dev, SYS_RES_MEMORY, + &rid, RF_ACTIVE); + if (sc->sc_memres[i] == NULL) { + device_printf(dev, "cannot allocate resource %d\n", i); + error = ENXIO; + goto fail_memres; + } + sc->sc_bt[i] = rman_get_bustag(sc->sc_memres[i]); + sc->sc_bh[i] = rman_get_bushandle(sc->sc_memres[i]); + } + + if ((sc->sc_flags & FHC_CENTRAL) != 0) { + board = bus_space_read_4(sc->sc_bt[FHC_INTERNAL], + sc->sc_bh[FHC_INTERNAL], FHC_BSR); + sc->sc_board = ((board >> 16) & 0x1) | ((board >> 12) & 0xe); + } else { + if (OF_getprop(node, "board#", &sc->sc_board, + sizeof(sc->sc_board)) == -1) { + device_printf(dev, "cannot get board number\n"); + error = ENXIO; + goto fail_memres; + } + } device_printf(dev, "board %d, ", sc->sc_board); if (OF_getprop_alloc(node, "board-model", 1, (void **)&name) != -1) { @@ -125,8 +227,9 @@ fhc_attach(device_t dev) sc->sc_nrange = OF_getprop_alloc(node, "ranges", sizeof(*sc->sc_ranges), (void **)&sc->sc_ranges); if (sc->sc_nrange == -1) { - device_printf(dev, "can't get ranges\n"); - return (ENXIO); + device_printf(dev, "cannot get ranges\n"); + error = ENXIO; + goto fail_memres; } if ((sc->sc_flags & FHC_CENTRAL) == 0) { @@ -179,9 +282,16 @@ fhc_attach(device_t dev) } return (bus_generic_attach(dev)); + + fail_memres: + for (i = 0; i < FHC_NREG; i++) + if (sc->sc_memres[i] != NULL) + bus_release_resource(dev, SYS_RES_MEMORY, + rman_get_rid(sc->sc_memres[i]), sc->sc_memres[i]); + return (error); } -int +static int fhc_print_child(device_t dev, device_t child) { int rv; @@ -192,7 +302,7 @@ fhc_print_child(device_t dev, device_t child) return (rv); } -void +static void fhc_probe_nomatch(device_t dev, device_t child) { const char *type; @@ -204,7 +314,7 @@ fhc_probe_nomatch(device_t dev, device_t child) type != NULL ? type : "unknown"); } -int +static int fhc_setup_intr(device_t bus, device_t child, struct resource *r, int flags, driver_filter_t *filt, driver_intr_t *func, void *arg, void **cookiep) { @@ -269,7 +379,7 @@ fhc_setup_intr(device_t bus, device_t child, struct resource *r, int flags, return (error); } -int +static int fhc_teardown_intr(device_t bus, device_t child, struct resource *r, void *cookie) { @@ -295,7 +405,7 @@ fhc_intr_stub(void *arg) return (FILTER_HANDLED); } -struct resource * +static struct resource * fhc_alloc_resource(device_t bus, device_t child, int type, int *rid, u_long start, u_long end, u_long count, u_int flags) { @@ -354,7 +464,7 @@ fhc_alloc_resource(device_t bus, device_t child, int type, int *rid, return (res); } -struct resource_list * +static struct resource_list * fhc_get_resource_list(device_t bus, device_t child) { struct fhc_devinfo *fdi; @@ -363,7 +473,7 @@ fhc_get_resource_list(device_t bus, device_t child) return (&fdi->fdi_rl); } -const struct ofw_bus_devinfo * +static const struct ofw_bus_devinfo * fhc_get_devinfo(device_t bus, device_t child) { struct fhc_devinfo *fdi; diff --git a/sys/sparc64/fhc/fhc_central.c b/sys/sparc64/fhc/fhc_central.c deleted file mode 100644 index dfde113b036d..000000000000 --- a/sys/sparc64/fhc/fhc_central.c +++ /dev/null @@ -1,132 +0,0 @@ -/*- - * Copyright (c) 2003 Jake Burkholder. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/bus.h> -#include <sys/kernel.h> -#include <sys/malloc.h> -#include <sys/module.h> - -#include <dev/ofw/ofw_bus.h> -#include <dev/ofw/ofw_bus_subr.h> - -#include <machine/bus.h> -#include <machine/resource.h> - -#include <sys/rman.h> - -#include <sparc64/fhc/fhcreg.h> -#include <sparc64/fhc/fhcvar.h> - -static device_probe_t fhc_central_probe; -static device_attach_t fhc_central_attach; - -static device_method_t fhc_central_methods[] = { - /* Device interface. */ - DEVMETHOD(device_probe, fhc_central_probe), - DEVMETHOD(device_attach, fhc_central_attach), - DEVMETHOD(device_shutdown, bus_generic_shutdown), - DEVMETHOD(device_suspend, bus_generic_suspend), - DEVMETHOD(device_resume, bus_generic_resume), - - /* Bus interface. */ - DEVMETHOD(bus_print_child, fhc_print_child), - DEVMETHOD(bus_probe_nomatch, fhc_probe_nomatch), - DEVMETHOD(bus_setup_intr, fhc_setup_intr), - DEVMETHOD(bus_teardown_intr, fhc_teardown_intr), - DEVMETHOD(bus_alloc_resource, fhc_alloc_resource), - DEVMETHOD(bus_release_resource, bus_generic_rl_release_resource), - DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), - DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), - DEVMETHOD(bus_get_resource_list, fhc_get_resource_list), - DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource), - - /* ofw_bus interface */ - DEVMETHOD(ofw_bus_get_devinfo, fhc_get_devinfo), - DEVMETHOD(ofw_bus_get_compat, ofw_bus_gen_get_compat), - DEVMETHOD(ofw_bus_get_model, ofw_bus_gen_get_model), - DEVMETHOD(ofw_bus_get_name, ofw_bus_gen_get_name), - DEVMETHOD(ofw_bus_get_node, ofw_bus_gen_get_node), - DEVMETHOD(ofw_bus_get_type, ofw_bus_gen_get_type), - - { NULL, NULL } -}; - -static driver_t fhc_central_driver = { - "fhc", - fhc_central_methods, - sizeof(struct fhc_softc), -}; - -static devclass_t fhc_central_devclass; - -DRIVER_MODULE(fhc, central, fhc_central_driver, fhc_central_devclass, 0, 0); - -static int -fhc_central_probe(device_t dev) -{ - - if (strcmp(ofw_bus_get_name(dev), "fhc") == 0) { - device_set_desc(dev, "fhc"); - return (fhc_probe(dev)); - } - return (ENXIO); -} - -static int -fhc_central_attach(device_t dev) -{ - struct fhc_softc *sc; - phandle_t node; - int board; - int rid; - int i; - - sc = device_get_softc(dev); - node = ofw_bus_get_node(dev); - sc->sc_node = node; - sc->sc_flags |= FHC_CENTRAL; - - for (i = 0; i < FHC_NREG; i++) { - rid = i; - sc->sc_memres[i] = bus_alloc_resource_any(dev, SYS_RES_MEMORY, - &rid, RF_ACTIVE); - if (sc->sc_memres[i] == NULL) - panic("%s: can't allocate registers", __func__); - sc->sc_bt[i] = rman_get_bustag(sc->sc_memres[i]); - sc->sc_bh[i] = rman_get_bushandle(sc->sc_memres[i]); - } - - board = bus_space_read_4(sc->sc_bt[FHC_INTERNAL], - sc->sc_bh[FHC_INTERNAL], FHC_BSR); - sc->sc_board = ((board >> 16) & 0x1) | ((board >> 12) & 0xe); - - return (fhc_attach(dev)); -} diff --git a/sys/sparc64/fhc/fhc_nexus.c b/sys/sparc64/fhc/fhc_nexus.c deleted file mode 100644 index 0a0406537ba9..000000000000 --- a/sys/sparc64/fhc/fhc_nexus.c +++ /dev/null @@ -1,147 +0,0 @@ -/*- - * Copyright (c) 2003 Jake Burkholder. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/bus.h> -#include <sys/kernel.h> -#include <sys/malloc.h> -#include <sys/module.h> - -#include <dev/ofw/ofw_bus.h> -#include <dev/ofw/ofw_bus_subr.h> -#include <dev/ofw/openfirm.h> - -#include <machine/bus.h> -#include <machine/ofw_upa.h> -#include <machine/nexusvar.h> -#include <machine/resource.h> - -#include <sys/rman.h> - -#include <sparc64/fhc/fhcreg.h> -#include <sparc64/fhc/fhcvar.h> - -static device_probe_t fhc_nexus_probe; -static device_attach_t fhc_nexus_attach; - -static device_method_t fhc_nexus_methods[] = { - /* Device interface. */ - DEVMETHOD(device_probe, fhc_nexus_probe), - DEVMETHOD(device_attach, fhc_nexus_attach), - DEVMETHOD(device_shutdown, bus_generic_shutdown), - DEVMETHOD(device_suspend, bus_generic_suspend), - DEVMETHOD(device_resume, bus_generic_resume), - - /* Bus interface. */ - DEVMETHOD(bus_print_child, fhc_print_child), - DEVMETHOD(bus_probe_nomatch, fhc_probe_nomatch), - DEVMETHOD(bus_setup_intr, fhc_setup_intr), - DEVMETHOD(bus_teardown_intr, fhc_teardown_intr), - DEVMETHOD(bus_alloc_resource, fhc_alloc_resource), - DEVMETHOD(bus_release_resource, bus_generic_rl_release_resource), - DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), - DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), - DEVMETHOD(bus_get_resource_list, fhc_get_resource_list), - DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource), - - /* ofw_bus interface */ - DEVMETHOD(ofw_bus_get_devinfo, fhc_get_devinfo), - DEVMETHOD(ofw_bus_get_compat, ofw_bus_gen_get_compat), - DEVMETHOD(ofw_bus_get_model, ofw_bus_gen_get_model), - DEVMETHOD(ofw_bus_get_name, ofw_bus_gen_get_name), - DEVMETHOD(ofw_bus_get_node, ofw_bus_gen_get_node), - DEVMETHOD(ofw_bus_get_type, ofw_bus_gen_get_type), - - { NULL, NULL } -}; - -static driver_t fhc_nexus_driver = { - "fhc", - fhc_nexus_methods, - sizeof(struct fhc_softc), -}; - -static devclass_t fhc_nexus_devclass; - -DRIVER_MODULE(fhc, nexus, fhc_nexus_driver, fhc_nexus_devclass, 0, 0); - -static int -fhc_nexus_probe(device_t dev) -{ - - if (strcmp(nexus_get_name(dev), "fhc") == 0) { - device_set_desc(dev, "fhc"); - return (fhc_probe(dev)); - } - return (ENXIO); -} - -static int -fhc_nexus_attach(device_t dev) -{ - struct fhc_softc *sc; - struct upa_regs *reg; - bus_addr_t phys; - bus_addr_t size; - phandle_t node; - int nreg; - int rid; - int i; - - sc = device_get_softc(dev); - node = nexus_get_node(dev); - sc->sc_node = node; - - reg = nexus_get_reg(dev); - nreg = nexus_get_nreg(dev); - if (nreg != FHC_NREG) { - device_printf(dev, "wrong number of regs\n"); - return (ENXIO); - } - for (i = 0; i < nreg; i++) { - phys = UPA_REG_PHYS(reg + i); - size = UPA_REG_SIZE(reg + i); - rid = 0; - sc->sc_memres[i] = bus_alloc_resource(dev, SYS_RES_MEMORY, - &rid, phys, phys + size - 1, size, RF_ACTIVE); - if (sc->sc_memres[i] == NULL) - panic("%s: can't allocate registers", __func__); - sc->sc_bt[i] = rman_get_bustag(sc->sc_memres[i]); - sc->sc_bh[i] = rman_get_bushandle(sc->sc_memres[i]); - } - - if (OF_getprop(node, "board#", &sc->sc_board, - sizeof(sc->sc_board)) == -1) { - device_printf(dev, "could not get board number\n"); - return (ENXIO); - } - - return (fhc_attach(dev)); -} diff --git a/sys/sparc64/fhc/fhcvar.h b/sys/sparc64/fhc/fhcvar.h deleted file mode 100644 index a79b8473f9a0..000000000000 --- a/sys/sparc64/fhc/fhcvar.h +++ /dev/null @@ -1,59 +0,0 @@ -/*- - * Copyright (c) 2003 Jake Burkholder. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#ifndef _SPARC64_FHC_FHCVAR_H_ -#define _SPARC64_FHC_FHCVAR_H_ - -#define FHC_CENTRAL (1<<0) - -struct fhc_softc { - phandle_t sc_node; - struct resource * sc_memres[FHC_NREG]; - bus_space_handle_t sc_bh[FHC_NREG]; - bus_space_tag_t sc_bt[FHC_NREG]; - int sc_nrange; - struct sbus_ranges *sc_ranges; - int sc_board; - int sc_ign; - int sc_flags; - struct cdev *sc_led_dev; -}; - -device_probe_t fhc_probe; -device_attach_t fhc_attach; - -bus_print_child_t fhc_print_child; -bus_probe_nomatch_t fhc_probe_nomatch; -bus_setup_intr_t fhc_setup_intr; -bus_teardown_intr_t fhc_teardown_intr; -bus_alloc_resource_t fhc_alloc_resource; -bus_get_resource_list_t fhc_get_resource_list; - -ofw_bus_get_devinfo_t fhc_get_devinfo; - -#endif /* !_SPARC64_FHC_FHCVAR_H_ */ diff --git a/sys/sparc64/include/bus_private.h b/sys/sparc64/include/bus_private.h index ba15cd908014..9e5ab082685e 100644 --- a/sys/sparc64/include/bus_private.h +++ b/sys/sparc64/include/bus_private.h @@ -73,11 +73,4 @@ struct bus_dmamap { int sparc64_dma_alloc_map(bus_dma_tag_t dmat, bus_dmamap_t *mapp); void sparc64_dma_free_map(bus_dma_tag_t dmat, bus_dmamap_t map); -/* - * XXX: This is a kluge. It would be better to handle dma tags in a hierarchical - * way, and have a BUS_GET_DMA_TAG(); however, since this is not currently the - * case, save a root tag in the relevant bus attach function and use that. - */ -extern bus_dma_tag_t sparc64_root_dma_tag; - #endif /* !_MACHINE_BUS_PRIVATE_H_ */ diff --git a/sys/sparc64/include/iommureg.h b/sys/sparc64/include/iommureg.h index e36d837f7a29..65d59ce54ed1 100644 --- a/sys/sparc64/include/iommureg.h +++ b/sys/sparc64/include/iommureg.h @@ -40,7 +40,7 @@ #define _MACHINE_IOMMUREG_H_ /* - * UltraSPARC IOMMU registers, common to both the sbus and PCI + * UltraSPARC IOMMU registers, common to both the PCI and SBus * controllers. */ @@ -65,7 +65,7 @@ #define STRBUF_D 0x0000000000000002UL #define IOMMU_BITS 34 -#define IOMMU_MAXADDR (1UL << IOMMU_BITS) +#define IOMMU_MAXADDR ((1UL << IOMMU_BITS) - 1) /* * control register bits @@ -140,7 +140,7 @@ #define STRBUF_FLUSHSYNC_NBYTES STRBUF_LINESZ /* - * On sun4u each bus controller has a separate IOMMU. The IOMMU has + * On sun4u each bus controller has a separate IOMMU. The IOMMU has * a TSB which must be page aligned and physically contiguous. Mappings * can be of 8K IOMMU pages or 64K IOMMU pages. We use 8K for compatibility * with the CPU's MMU. @@ -168,7 +168,7 @@ #define IOTSB_BASESZ (1024 << IOTTE_SHIFT) #define IOTSB_VEND (~IO_PAGE_MASK) -#define IOTSB_VSTART(sz) (u_int)(IOTSB_VEND << ((sz) + 10)) +#define IOTSB_VSTART(sz) (u_int)(IOTSB_VEND << ((sz) + 10)) #define MAKEIOTTE(pa,w,c,s) \ (((pa) & IOTTE_PAMASK) | ((w) ? IOTTE_W : 0) | \ diff --git a/sys/sparc64/include/nexusvar.h b/sys/sparc64/include/nexusvar.h deleted file mode 100644 index dd8ebfc73c3b..000000000000 --- a/sys/sparc64/include/nexusvar.h +++ /dev/null @@ -1,58 +0,0 @@ -/*- - * Copyright (c) 2001 by Thomas Moestl <tmm@FreeBSD.org>. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#ifndef _MACHINE_NEXUSVAR_H_ -#define _MACHINE_NEXUSVAR_H_ - -enum nexus_ivars { - NEXUS_IVAR_NODE, - NEXUS_IVAR_NAME, - NEXUS_IVAR_DEVICE_TYPE, - NEXUS_IVAR_MODEL, - NEXUS_IVAR_REG, - NEXUS_IVAR_NREG, - NEXUS_IVAR_INTERRUPTS, - NEXUS_IVAR_NINTERRUPTS, - NEXUS_IVAR_DMATAG, -}; - -#define NEXUS_ACCESSOR(var, ivar, type) \ - __BUS_ACCESSOR(nexus, var, NEXUS, ivar, type) - -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 upa_regs *) -NEXUS_ACCESSOR(nreg, NREG, int) -NEXUS_ACCESSOR(interrupts, INTERRUPTS, u_int *) -NEXUS_ACCESSOR(ninterrupts, NINTERRUPTS, int) -NEXUS_ACCESSOR(dmatag, DMATAG, bus_dma_tag_t) - -#undef NEXUS_ACCESSOR - -#endif /* _MACHINE_NEXUSVAR_H_ */ diff --git a/sys/sparc64/include/ofw_nexus.h b/sys/sparc64/include/ofw_nexus.h index fbe6d396cdc7..5de08b778c8a 100644 --- a/sys/sparc64/include/ofw_nexus.h +++ b/sys/sparc64/include/ofw_nexus.h @@ -31,24 +31,24 @@ * $FreeBSD$ */ -#ifndef _MACHINE_OFW_UPA_H_ -#define _MACHINE_OFW_UPA_H_ +#ifndef _MACHINE_OFW_NEXUS_H_ +#define _MACHINE_OFW_NEXUS_H_ /* - * These are the regs and ranges property the psycho uses. They should be - * applicable to all UPA devices. XXX: verify this. + * These are the regs used for devices on the nexus. They apply to all of + * Fireplane/Safari, JBus and UPA. */ -struct upa_regs { - u_int32_t phys_hi; - u_int32_t phys_lo; - u_int32_t size_hi; - u_int32_t size_lo; +struct nexus_regs { + uint32_t phys_hi; + uint32_t phys_lo; + uint32_t size_hi; + uint32_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 NEXUS_REG_PHYS(r) \ + (((uint64_t)(r)->phys_hi << 32) | (uint64_t)(r)->phys_lo) +#define NEXUS_REG_SIZE(r) \ + (((uint64_t)(r)->size_hi << 32) | (uint64_t)(r)->size_lo) -#endif /* !_MACHINE_OFW_UPA_H_ */ +#endif /* !_MACHINE_OFW_NEXUS_H_ */ diff --git a/sys/sparc64/include/ofw_upa.h b/sys/sparc64/include/ofw_upa.h deleted file mode 100644 index fbe6d396cdc7..000000000000 --- a/sys/sparc64/include/ofw_upa.h +++ /dev/null @@ -1,54 +0,0 @@ -/*- - * Copyright (c) 1998, 1999 Eduardo E. Horvath - * Copyright (c) 1999 Matthew R. Green - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * from: NetBSD: psychoreg.h,v 1.8 2001/09/10 16:17:06 eeh Exp - * - * $FreeBSD$ - */ - -#ifndef _MACHINE_OFW_UPA_H_ -#define _MACHINE_OFW_UPA_H_ - -/* - * These are the regs and ranges property the psycho uses. They should be - * applicable to all UPA devices. XXX: verify this. - */ - -struct upa_regs { - u_int32_t phys_hi; - u_int32_t phys_lo; - u_int32_t size_hi; - 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) - -#endif /* !_MACHINE_OFW_UPA_H_ */ diff --git a/sys/sparc64/pci/psycho.c b/sys/sparc64/pci/psycho.c index 8d5ae041aa1b..6a662dcadc43 100644 --- a/sys/sparc64/pci/psycho.c +++ b/sys/sparc64/pci/psycho.c @@ -1,6 +1,7 @@ /*- * Copyright (c) 1999, 2000 Matthew R. Green * Copyright (c) 2001 - 2003 by Thomas Moestl <tmm@FreeBSD.org> + * Copyright (c) 2005 - 2006 Marius Strobl <marius@FreeBSD.org> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -45,8 +46,8 @@ __FBSDID("$FreeBSD$"); #include <sys/bus.h> #include <sys/kdb.h> #include <sys/kernel.h> -#include <sys/module.h> #include <sys/malloc.h> +#include <sys/module.h> #include <sys/pcpu.h> #include <sys/reboot.h> @@ -55,19 +56,16 @@ __FBSDID("$FreeBSD$"); #include <dev/ofw/openfirm.h> #include <machine/bus.h> -#include <machine/bus_private.h> #include <machine/bus_common.h> +#include <machine/bus_private.h> #include <machine/iommureg.h> -#include <machine/nexusvar.h> +#include <machine/iommuvar.h> #include <machine/ofw_bus.h> -#include <machine/ofw_upa.h> #include <machine/resource.h> #include <machine/ver.h> #include <sys/rman.h> -#include <machine/iommuvar.h> - #include <dev/pci/pcireg.h> #include <dev/pci/pcivar.h> @@ -79,22 +77,22 @@ __FBSDID("$FreeBSD$"); static const struct psycho_desc *psycho_find_desc(const struct psycho_desc *, const char *); -static const struct psycho_desc *psycho_get_desc(phandle_t, const char *); +static const struct psycho_desc *psycho_get_desc(device_t); static void psycho_set_intr(struct psycho_softc *, int, bus_addr_t, int, driver_filter_t); static int psycho_find_intrmap(struct psycho_softc *, int, bus_addr_t *, bus_addr_t *, u_long *); -static int psycho_intr_stub(void *); +static driver_filter_t psycho_intr_stub; static bus_space_tag_t psycho_alloc_bus_tag(struct psycho_softc *, int); /* Interrupt handlers */ -static int psycho_ue(void *); -static int psycho_ce(void *); -static int psycho_pci_bus(void *); -static int psycho_powerfail(void *); -static int psycho_overtemp(void *); +static driver_filter_t psycho_ue; +static driver_filter_t psycho_ce; +static driver_filter_t psycho_pci_bus; +static driver_filter_t psycho_powerfail; +static driver_filter_t psycho_overtemp; #ifdef PSYCHO_MAP_WAKEUP -static int psycho_wakeup(void *); +static driver_filter_t psycho_wakeup; #endif /* IOMMU support */ @@ -112,6 +110,7 @@ static bus_alloc_resource_t psycho_alloc_resource; static bus_activate_resource_t psycho_activate_resource; static bus_deactivate_resource_t psycho_deactivate_resource; static bus_release_resource_t psycho_release_resource; +static bus_get_dma_tag_t psycho_get_dma_tag; static pcib_maxslots_t psycho_maxslots; static pcib_read_config_t psycho_read_config; static pcib_write_config_t psycho_write_config; @@ -137,6 +136,7 @@ static device_method_t psycho_methods[] = { DEVMETHOD(bus_activate_resource, psycho_activate_resource), DEVMETHOD(bus_deactivate_resource, psycho_deactivate_resource), DEVMETHOD(bus_release_resource, psycho_release_resource), + DEVMETHOD(bus_get_dma_tag, psycho_get_dma_tag), /* pcib interface */ DEVMETHOD(pcib_maxslots, psycho_maxslots), @@ -251,25 +251,22 @@ psycho_find_desc(const struct psycho_desc *table, const char *string) { const struct psycho_desc *desc; - for (desc = table; desc->pd_string != NULL; desc++) { + if (string == NULL) + return (NULL); + for (desc = table; desc->pd_string != NULL; desc++) if (strcmp(desc->pd_string, string) == 0) return (desc); - } return (NULL); } static const struct psycho_desc * -psycho_get_desc(phandle_t node, const char *model) +psycho_get_desc(device_t dev) { const struct psycho_desc *rv; - char compat[32]; - - rv = NULL; - if (model != NULL) - rv = psycho_find_desc(psycho_models, model); - if (rv == NULL && - OF_getprop(node, "compatible", compat, sizeof(compat)) != -1) - rv = psycho_find_desc(psycho_compats, compat); + + rv = psycho_find_desc(psycho_models, ofw_bus_get_model(dev)); + if (rv == NULL) + rv = psycho_find_desc(psycho_compats, ofw_bus_get_compat(dev)); return (rv); } @@ -278,11 +275,9 @@ psycho_probe(device_t dev) { const char *dtype; - dtype = nexus_get_device_type(dev); - if (nexus_get_reg(dev) != NULL && dtype != NULL && - strcmp(dtype, OFW_PCI_TYPE) == 0 && - psycho_get_desc(nexus_get_node(dev), - nexus_get_model(dev)) != NULL) { + dtype = ofw_bus_get_type(dev); + if (dtype != NULL && strcmp(dtype, OFW_PCI_TYPE) == 0 && + psycho_get_desc(dev) != NULL) { device_set_desc(dev, "U2P UPA-PCI bridge"); return (0); } @@ -296,23 +291,21 @@ psycho_attach(device_t dev) char name[sizeof("pci108e,1000")]; struct psycho_softc *asc, *sc, *osc; struct ofw_pci_ranges *range; - struct upa_regs *reg; const struct psycho_desc *desc; phandle_t child, node; uint64_t csr, dr; uint32_t dvmabase, psycho_br[2]; int32_t rev; - u_long mlen; u_int ver; - int n, i, nrange, nreg, rid; + int i, n, nrange, rid; #ifdef PSYCHO_DEBUG bus_addr_t map, clr; uint64_t mr; #endif - node = nexus_get_node(dev); + node = ofw_bus_get_node(dev); sc = device_get_softc(dev); - desc = psycho_get_desc(node, nexus_get_model(dev)); + desc = psycho_get_desc(dev); sc->sc_node = node; sc->sc_dev = dev; @@ -325,14 +318,11 @@ psycho_attach(device_t dev) * PBM 256-byte PCI header * (2) the shared Psycho configuration registers */ - reg = nexus_get_reg(dev); - nreg = nexus_get_nreg(dev); if (sc->sc_mode == PSYCHO_MODE_PSYCHO) { - if (nreg <= 2) - panic("%s: %d not enough registers", __func__, nreg); - sc->sc_basepaddr = (vm_paddr_t)UPA_REG_PHYS(®[2]); - mlen = UPA_REG_SIZE(®[2]); - sc->sc_pcictl = UPA_REG_PHYS(®[0]) - sc->sc_basepaddr; + rid = 2; + sc->sc_pcictl = + bus_get_resource_start(dev, SYS_RES_MEMORY, 0) - + bus_get_resource_start(dev, SYS_RES_MEMORY, 2); switch (sc->sc_pcictl) { case PSR_PCICTL0: sc->sc_half = 0; @@ -345,13 +335,17 @@ psycho_attach(device_t dev) __func__); } } else { - if (nreg <= 0) - panic("%s: %d not enough registers", __func__, nreg); - sc->sc_basepaddr = (vm_paddr_t)UPA_REG_PHYS(®[0]); - mlen = UPA_REG_SIZE(reg); + rid = 0; sc->sc_pcictl = PSR_PCICTL0; sc->sc_half = 0; } + sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, + (sc->sc_mode == PSYCHO_MODE_PSYCHO ? RF_SHAREABLE : 0) | + RF_ACTIVE); + if (sc->sc_mem_res == NULL) + panic("%s: could not allocate registers", __func__); + sc->sc_bustag = rman_get_bustag(sc->sc_mem_res); + sc->sc_bushandle = rman_get_bushandle(sc->sc_mem_res); /* * Match other Psycho's that are already configured against @@ -360,33 +354,14 @@ psycho_attach(device_t dev) */ osc = NULL; SLIST_FOREACH(asc, &psycho_softcs, sc_link) { - if (asc->sc_basepaddr == sc->sc_basepaddr) { + if (rman_get_start(asc->sc_mem_res) == + rman_get_start(sc->sc_mem_res)) { /* Found partner. */ osc = asc; break; } } - if (osc == NULL) { - 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("%s: could not allocate device memory", __func__); - sc->sc_bustag = rman_get_bustag(sc->sc_mem_res); - sc->sc_bushandle = rman_get_bushandle(sc->sc_mem_res); - } else { - /* - * There's another Psycho using the same register space. - * Copy the relevant stuff. - */ - sc->sc_mem_res = NULL; - sc->sc_bustag = osc->sc_bustag; - sc->sc_bushandle = osc->sc_bushandle; - } - /* Clear PCI AFSR. */ PCICTL_WRITE8(sc, PCR_AFS, PCIAFSR_ERRMASK); @@ -588,15 +563,13 @@ psycho_attach(device_t dev) sc->sc_pci_memt = psycho_alloc_bus_tag(sc, PCI_MEMORY_BUS_SPACE); sc->sc_pci_iot = psycho_alloc_bus_tag(sc, PCI_IO_BUS_SPACE); sc->sc_pci_cfgt = psycho_alloc_bus_tag(sc, PCI_CONFIG_BUS_SPACE); - if (bus_dma_tag_create(nexus_get_dmatag(dev), 8, 1, 0, 0x3ffffffff, - NULL, NULL, 0x3ffffffff, 0xff, 0xffffffff, 0, NULL, NULL, + if (bus_dma_tag_create(bus_get_dma_tag(dev), 8, 0, IOMMU_MAXADDR, ~0, + NULL, NULL, IOMMU_MAXADDR, 0xff, 0xffffffff, 0, NULL, NULL, &sc->sc_pci_dmat) != 0) panic("%s: bus_dma_tag_create failed", __func__); /* Customize the tag. */ sc->sc_pci_dmat->dt_cookie = sc->sc_is; sc->sc_pci_dmat->dt_mt = &iommu_dma_methods; - /* XXX: register as root DMA tag (kludge). */ - sparc64_root_dma_tag = sc->sc_pci_dmat; #ifdef PSYCHO_DEBUG /* @@ -604,7 +577,7 @@ psycho_attach(device_t dev) * This aids the debugging of interrupt routing problems. */ for (map = PSR_PCIA0_INT_MAP, clr = PSR_PCIA0_INT_CLR, n = 0; - map <= PSR_PCIB3_INT_MAP; map += 8, clr += 32, n++) { + map <= PSR_PCIB3_INT_MAP; map += 8, clr += 32, n++) { mr = PSYCHO_READ8(sc, map); device_printf(dev, "intr map (pci) %d: %#lx\n", n, (u_long)mr); PSYCHO_WRITE8(sc, map, mr & ~INTMAP_V); @@ -613,7 +586,7 @@ psycho_attach(device_t dev) PSYCHO_WRITE8(sc, map, INTMAP_ENABLE(mr, PCPU_GET(mid))); } for (map = PSR_SCSI_INT_MAP, clr = PSR_SCSI_INT_CLR, n = 0; - map <= PSR_SERIAL_INT_MAP; map += 8, clr += 8, n++) { + map <= PSR_SERIAL_INT_MAP; map += 8, clr += 8, n++) { mr = PSYCHO_READ8(sc, map); device_printf(dev, "intr map (obio) %d: %#lx, clr: %#lx\n", n, (u_long)mr, (u_long)clr); @@ -683,16 +656,16 @@ static void psycho_set_intr(struct psycho_softc *sc, int index, bus_addr_t map, int iflags, driver_filter_t handler) { - int rid, vec, res; uint64_t mr; + int res, rid; res = EINVAL; rid = index; mr = PSYCHO_READ8(sc, map); - vec = INTVEC(mr); - sc->sc_irq_res[index] = bus_alloc_resource(sc->sc_dev, SYS_RES_IRQ, - &rid, vec, vec, 1, RF_ACTIVE); - if (sc->sc_irq_res[index] != NULL) { + sc->sc_irq_res[index] = bus_alloc_resource_any(sc->sc_dev, SYS_RES_IRQ, + &rid, RF_ACTIVE); + if (sc->sc_irq_res[index] != NULL && + rman_get_start(sc->sc_irq_res[index]) == INTVEC(mr)) { if (iflags & FAST) { iflags &= ~FAST; res = bus_setup_intr(sc->sc_dev, sc->sc_irq_res[index], @@ -722,8 +695,8 @@ psycho_find_intrmap(struct psycho_softc *sc, int ino, bus_addr_t *intrmapptr, /* Hunt thru OBIO first. */ diag = PSYCHO_READ8(sc, PSR_OBIO_INT_DIAG); for (intrmap = PSR_SCSI_INT_MAP, intrclr = PSR_SCSI_INT_CLR; - intrmap <= PSR_SERIAL_INT_MAP; intrmap += 8, intrclr += 8, - diag >>= 2) { + intrmap <= PSR_SERIAL_INT_MAP; intrmap += 8, intrclr += 8, + diag >>= 2) { im = PSYCHO_READ8(sc, intrmap); if (INTINO(im) == ino) { diag &= 2; @@ -736,11 +709,11 @@ psycho_find_intrmap(struct psycho_softc *sc, int ino, bus_addr_t *intrmapptr, diag = PSYCHO_READ8(sc, PSR_PCI_INT_DIAG); /* Now do PCI interrupts. */ for (intrmap = PSR_PCIA0_INT_MAP, intrclr = PSR_PCIA0_INT_CLR; - intrmap <= PSR_PCIB3_INT_MAP; intrmap += 8, intrclr += 32, - diag >>= 8) { + intrmap <= PSR_PCIB3_INT_MAP; intrmap += 8, intrclr += 32, + diag >>= 8) { if (sc->sc_mode == PSYCHO_MODE_PSYCHO && (intrmap == PSR_PCIA2_INT_MAP || - intrmap == PSR_PCIA3_INT_MAP)) + intrmap == PSR_PCIA3_INT_MAP)) continue; im = PSYCHO_READ8(sc, intrmap); if (((im ^ ino) & 0x3c) == 0) { @@ -930,7 +903,7 @@ psycho_read_config(device_t dev, u_int bus, u_int slot, u_int func, u_int reg, static void psycho_write_config(device_t dev, u_int bus, u_int slot, u_int func, u_int reg, - uint32_t val, int width) + uint32_t val, int width) { struct psycho_softc *sc; bus_space_handle_t bh; @@ -1025,7 +998,7 @@ psycho_intr_stub(void *arg) static int psycho_setup_intr(device_t dev, device_t child, struct resource *ires, - int flags, driver_filter_t *filt, driver_intr_t *intr, void *arg, + int flags, driver_filter_t *filt, driver_intr_t *intr, void *arg, void **cookiep) { struct { @@ -1157,7 +1130,7 @@ psycho_setup_intr(device_t dev, device_t child, struct resource *ires, static int psycho_teardown_intr(device_t dev, device_t child, struct resource *vec, - void *cookie) + void *cookie) { struct psycho_clr *pc = cookie; int error; @@ -1290,6 +1263,15 @@ psycho_release_resource(device_t bus, device_t child, int type, int rid, return (rman_release_resource(r)); } +static bus_dma_tag_t +psycho_get_dma_tag(device_t bus, device_t child) +{ + struct psycho_softc *sc; + + sc = device_get_softc(bus); + return (sc->sc_pci_dmat); +} + static int psycho_intr_pending(device_t dev, ofw_pci_intr_t intr) { diff --git a/sys/sparc64/pci/psychovar.h b/sys/sparc64/pci/psychovar.h index 52f9f229f4d5..fe20fe672f1e 100644 --- a/sys/sparc64/pci/psychovar.h +++ b/sys/sparc64/pci/psychovar.h @@ -39,7 +39,6 @@ */ struct psycho_softc { device_t sc_dev; - vm_paddr_t sc_basepaddr; /* Interrupt Group Number for this device */ int sc_ign; diff --git a/sys/sparc64/sbus/sbus.c b/sys/sparc64/sbus/sbus.c index 5c96a3cb5af5..9d059f20d83f 100644 --- a/sys/sparc64/sbus/sbus.c +++ b/sys/sparc64/sbus/sbus.c @@ -73,6 +73,7 @@ /*- * Copyright (c) 1999 Eduardo Horvath * Copyright (c) 2002 by Thomas Moestl <tmm@FreeBSD.org>. + * Copyright (c) 2005 Marius Strobl <marius@FreeBSD.org> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -121,9 +122,6 @@ __FBSDID("$FreeBSD$"); #include <machine/bus_private.h> #include <machine/iommureg.h> #include <machine/bus_common.h> -#include <machine/intr_machdep.h> -#include <machine/nexusvar.h> -#include <machine/ofw_upa.h> #include <machine/resource.h> #include <sys/rman.h> @@ -158,12 +156,9 @@ struct sbus_rd { struct sbus_softc { bus_space_tag_t sc_bustag; bus_space_handle_t sc_bushandle; - bus_dma_tag_t sc_dmatag; bus_dma_tag_t sc_cdmatag; bus_space_tag_t sc_cbustag; int sc_clockfreq; /* clock frequency (in Hz) */ - struct upa_regs *sc_reg; - int sc_nreg; int sc_nrange; struct sbus_rd *sc_rd; int sc_burst; /* burst transfer sizes supp. */ @@ -203,16 +198,17 @@ static bus_alloc_resource_t sbus_alloc_resource; static bus_release_resource_t sbus_release_resource; static bus_activate_resource_t sbus_activate_resource; static bus_deactivate_resource_t sbus_deactivate_resource; +static bus_get_dma_tag_t sbus_get_dma_tag; static ofw_bus_get_devinfo_t sbus_get_devinfo; static int sbus_inlist(const char *, const char **); static struct sbus_devinfo * sbus_setup_dinfo(device_t, struct sbus_softc *, phandle_t); static void sbus_destroy_dinfo(struct sbus_devinfo *); -static int sbus_intr_stub(void *); +static driver_filter_t sbus_intr_stub; static bus_space_tag_t sbus_alloc_bustag(struct sbus_softc *); -static int sbus_overtemp(void *); -static int sbus_pwrfail(void *); +static driver_filter_t sbus_overtemp; +static driver_filter_t sbus_pwrfail; static int sbus_print_res(struct sbus_devinfo *); static device_method_t sbus_methods[] = { @@ -235,6 +231,7 @@ static device_method_t sbus_methods[] = { DEVMETHOD(bus_release_resource, sbus_release_resource), DEVMETHOD(bus_get_resource_list, sbus_get_resource_list), DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource), + DEVMETHOD(bus_get_dma_tag, sbus_get_dma_tag), /* ofw_bus interface */ DEVMETHOD(ofw_bus_get_devinfo, sbus_get_devinfo), @@ -283,11 +280,11 @@ sbus_inlist(const char *name, const char **list) static int sbus_probe(device_t dev) { - char *t; + const char *t; - t = nexus_get_device_type(dev); + t = ofw_bus_get_type(dev); if (((t == NULL || strcmp(t, OFW_SBUS_TYPE) != 0)) && - strcmp(nexus_get_name(dev), OFW_SBUS_NAME) != 0) + strcmp(ofw_bus_get_name(dev), OFW_SBUS_NAME) != 0) return (ENXIO); device_set_desc(dev, "U2S UPA-SBus bridge"); return (0); @@ -300,30 +297,22 @@ sbus_attach(device_t dev) struct sbus_devinfo *sdi; struct sbus_ranges *range; struct resource *res; + struct resource_list *rl; device_t cdev; bus_addr_t phys; bus_size_t size; char *name; phandle_t child, node; u_int64_t mr; - int intr, clock, rid, vec, i; + int clock, i, intr, rid; sc = device_get_softc(dev); - node = nexus_get_node(dev); + node = ofw_bus_get_node(dev); - if ((sc->sc_nreg = OF_getprop_alloc(node, "reg", sizeof(*sc->sc_reg), - (void **)&sc->sc_reg)) == -1) { - panic("%s: error getting reg property", __func__); - } - if (sc->sc_nreg < 1) - panic("%s: bogus properties", __func__); - phys = UPA_REG_PHYS(&sc->sc_reg[0]); - size = UPA_REG_SIZE(&sc->sc_reg[0]); rid = 0; - sc->sc_sysio_res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, phys, - phys + size - 1, size, RF_ACTIVE); - if (sc->sc_sysio_res == NULL || - rman_get_start(sc->sc_sysio_res) != phys) + sc->sc_sysio_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, + RF_ACTIVE); + if (sc->sc_sysio_res == NULL) panic("%s: cannot allocate device memory", __func__); sc->sc_bustag = rman_get_bustag(sc->sc_sysio_res); sc->sc_bushandle = rman_get_bushandle(sc->sc_sysio_res); @@ -358,15 +347,17 @@ sbus_attach(device_t dev) * Preallocate all space that the SBus bridge decodes, so that nothing * else gets in the way; set up rmans etc. */ + rl = BUS_GET_RESOURCE_LIST(device_get_parent(dev), dev); for (i = 0; i < sc->sc_nrange; i++) { phys = range[i].poffset | ((bus_addr_t)range[i].pspace << 32); size = range[i].size; sc->sc_rd[i].rd_slot = range[i].cspace; sc->sc_rd[i].rd_coffset = range[i].coffset; sc->sc_rd[i].rd_cend = sc->sc_rd[i].rd_coffset + size; - rid = 0; - if ((res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, phys, - phys + size - 1, size, RF_ACTIVE)) == NULL) + rid = resource_list_add_next(rl, SYS_RES_MEMORY, phys, + phys + size - 1, size); + if ((res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, + RF_ACTIVE)) == NULL) panic("%s: cannot allocate decoded range", __func__); sc->sc_rd[i].rd_bushandle = rman_get_bushandle(res); sc->sc_rd[i].rd_rman.rm_type = RMAN_ARRAY; @@ -416,33 +407,31 @@ sbus_attach(device_t dev) iommu_init(name, &sc->sc_is, 3, -1, 1); /* Create the DMA tag. */ - sc->sc_dmatag = nexus_get_dmatag(dev); - if (bus_dma_tag_create(sc->sc_dmatag, 8, 1, 0, 0x3ffffffff, NULL, NULL, - 0x3ffffffff, 0xff, 0xffffffff, 0, NULL, NULL, &sc->sc_cdmatag) != 0) + if (bus_dma_tag_create(bus_get_dma_tag(dev), 8, 0, IOMMU_MAXADDR, ~0, + NULL, NULL, IOMMU_MAXADDR, 0xff, 0xffffffff, 0, NULL, NULL, + &sc->sc_cdmatag) != 0) panic("%s: bus_dma_tag_create failed", __func__); /* Customize the tag. */ sc->sc_cdmatag->dt_cookie = &sc->sc_is; sc->sc_cdmatag->dt_mt = &iommu_dma_methods; - /* XXX: register as root dma tag (kludge). */ - sparc64_root_dma_tag = sc->sc_cdmatag; /* Enable the over-temperature and power-fail interrupts. */ - rid = 0; + rid = 4; mr = SYSIO_READ8(sc, SBR_THERM_INT_MAP); - vec = INTVEC(mr); - sc->sc_ot_ires = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, vec, - vec, 1, RF_ACTIVE); + sc->sc_ot_ires = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, + RF_ACTIVE); if (sc->sc_ot_ires == NULL || + rman_get_start(sc->sc_ot_ires) != INTVEC(mr) || bus_setup_intr(dev, sc->sc_ot_ires, INTR_TYPE_MISC, sbus_overtemp, NULL, sc, &sc->sc_ot_ihand) != 0) panic("%s: failed to set up temperature interrupt", __func__); SYSIO_WRITE8(sc, SBR_THERM_INT_MAP, INTMAP_ENABLE(mr, PCPU_GET(mid))); - rid = 0; + rid = 3; mr = SYSIO_READ8(sc, SBR_POWER_INT_MAP); - vec = INTVEC(mr); - sc->sc_pf_ires = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, vec, - vec, 1, RF_ACTIVE); + sc->sc_pf_ires = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, + RF_ACTIVE); if (sc->sc_pf_ires == NULL || + rman_get_start(sc->sc_pf_ires) != INTVEC(mr) || bus_setup_intr(dev, sc->sc_pf_ires, INTR_TYPE_MISC, sbus_pwrfail, NULL, sc, &sc->sc_pf_ihand) != 0) panic("%s: failed to set up power fail interrupt", __func__); @@ -904,6 +893,15 @@ sbus_release_resource(device_t bus, device_t child, int type, int rid, return (0); } +static bus_dma_tag_t +sbus_get_dma_tag(device_t bus, device_t child) +{ + struct sbus_softc *sc; + + sc = device_get_softc(bus); + return (sc->sc_cdmatag); +} + static const struct ofw_bus_devinfo * sbus_get_devinfo(device_t bus, device_t child) { diff --git a/sys/sparc64/sparc64/bus_machdep.c b/sys/sparc64/sparc64/bus_machdep.c index 67e20d5306f7..165e3507000e 100644 --- a/sys/sparc64/sparc64/bus_machdep.c +++ b/sys/sparc64/sparc64/bus_machdep.c @@ -190,14 +190,6 @@ dflt_lock(void *arg, bus_dma_lock_op_t op) } /* - * Since there is no way for a device to obtain a dma tag from its parent - * we use this kluge to handle different the different supported bus systems. - * The sparc64_root_dma_tag is used as parent for tags that have none, so that - * the correct methods will be used. - */ -bus_dma_tag_t sparc64_root_dma_tag; - -/* * Allocate a device specific dma_tag. */ int @@ -207,23 +199,25 @@ bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment, int nsegments, bus_size_t maxsegsz, int flags, bus_dma_lock_t *lockfunc, void *lockfuncarg, bus_dma_tag_t *dmat) { - bus_dma_tag_t impptag; bus_dma_tag_t newtag; /* Return a NULL tag on failure */ *dmat = NULL; + /* Enforce the usage of BUS_GET_DMA_TAG(). */ + if (parent == NULL) + panic("%s: parent DMA tag NULL", __func__); + newtag = (bus_dma_tag_t)malloc(sizeof(*newtag), M_DEVBUF, M_NOWAIT); if (newtag == NULL) return (ENOMEM); - impptag = parent != NULL ? parent : sparc64_root_dma_tag; /* * The method table pointer and the cookie need to be taken over from - * the parent or the root tag. + * the parent. */ - newtag->dt_cookie = impptag->dt_cookie; - newtag->dt_mt = impptag->dt_mt; + newtag->dt_cookie = parent->dt_cookie; + newtag->dt_mt = parent->dt_mt; newtag->dt_parent = parent; newtag->dt_alignment = alignment; @@ -251,18 +245,14 @@ bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment, newtag->dt_segments = NULL; /* Take into account any restrictions imposed by our parent tag */ - if (parent != NULL) { - newtag->dt_lowaddr = ulmin(parent->dt_lowaddr, - newtag->dt_lowaddr); - newtag->dt_highaddr = ulmax(parent->dt_highaddr, - newtag->dt_highaddr); - if (newtag->dt_boundary == 0) - newtag->dt_boundary = parent->dt_boundary; - else if (parent->dt_boundary != 0) - newtag->dt_boundary = ulmin(parent->dt_boundary, - newtag->dt_boundary); - atomic_add_int(&parent->dt_ref_count, 1); - } + newtag->dt_lowaddr = ulmin(parent->dt_lowaddr, newtag->dt_lowaddr); + newtag->dt_highaddr = ulmax(parent->dt_highaddr, newtag->dt_highaddr); + if (newtag->dt_boundary == 0) + newtag->dt_boundary = parent->dt_boundary; + else if (parent->dt_boundary != 0) + newtag->dt_boundary = ulmin(parent->dt_boundary, + newtag->dt_boundary); + atomic_add_int(&parent->dt_ref_count, 1); if (newtag->dt_boundary > 0) newtag->dt_maxsegsz = ulmin(newtag->dt_maxsegsz, @@ -696,15 +686,15 @@ struct bus_dma_methods nexus_dma_methods = { struct bus_dma_tag nexus_dmatag = { NULL, NULL, - 8, - 0, + 1, 0, - 0x3ffffffff, + ~0, + ~0, NULL, /* XXX */ NULL, - 0x3ffffffff, /* XXX */ - 0xff, /* XXX */ - 0xffffffff, /* XXX */ + ~0, + ~0, + ~0, 0, 0, 0, diff --git a/sys/sparc64/sparc64/iommu.c b/sys/sparc64/sparc64/iommu.c index 178ac4e2b49e..cc973f6a851c 100644 --- a/sys/sparc64/sparc64/iommu.c +++ b/sys/sparc64/sparc64/iommu.c @@ -96,12 +96,13 @@ * from: NetBSD: sbus.c,v 1.13 1999/05/23 07:24:02 mrg Exp * from: @(#)sbus.c 8.1 (Berkeley) 6/11/93 * from: NetBSD: iommu.c,v 1.42 2001/08/06 22:02:58 eeh Exp - * - * $FreeBSD$ */ +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + /* - * UltraSPARC IOMMU support; used by both the sbus and pci code. + * UltraSPARC IOMMU support; used by both the PCI and SBus code. * Currently, the IOTSBs are synchronized, because determining the bus the map * is to be loaded for is not possible with the current busdma code. * The code is structured so that the IOMMUs can be easily divorced when that @@ -328,7 +329,7 @@ iommu_map_remq(struct iommu_state *is, bus_dmamap_t map) } /* - * initialise the UltraSPARC IOMMU (SBus or PCI): + * initialise the UltraSPARC IOMMU (PCI or SBus): * - allocate and setup the iotsb. * - enable the IOMMU * - initialise the streaming buffers (if they exist) @@ -347,7 +348,7 @@ iommu_init(char *name, struct iommu_state *is, int tsbsize, u_int32_t iovabase, /* * Setup the iommu. * - * The sun4u iommu is part of the SBUS or PCI controller so we + * The sun4u iommu is part of the PCI or SBus controller so we * will deal with it here.. * * The IOMMU address space always ends at 0xffffe000, but the starting @@ -379,7 +380,7 @@ iommu_init(char *name, struct iommu_state *is, int tsbsize, u_int32_t iovabase, rman_manage_region(&iommu_dvma_rman, (is->is_dvmabase >> IO_PAGE_SHIFT) + resvpg, (end >> IO_PAGE_SHIFT) - 1) != 0) - panic("iommu_init: can't initialize dvma rman"); + panic("%s: could not initialize DVMA rman", __func__); /* * Allocate memory for I/O page tables. They need to be * physically contiguous. @@ -387,7 +388,7 @@ iommu_init(char *name, struct iommu_state *is, int tsbsize, u_int32_t iovabase, iommu_tsb = contigmalloc(size, M_DEVBUF, M_NOWAIT, 0, ~0UL, PAGE_SIZE, 0); if (iommu_tsb == 0) - panic("iommu_init: contigmalloc failed"); + panic("%s: contigmalloc failed", __func__); iommu_ptsb = pmap_kextract((vm_offset_t)iommu_tsb); bzero(iommu_tsb, size); } else { @@ -398,8 +399,8 @@ iommu_init(char *name, struct iommu_state *is, int tsbsize, u_int32_t iovabase, first = STAILQ_FIRST(&iommu_insts); if (is->is_tsbsize != first->is_tsbsize || is->is_dvmabase != first->is_dvmabase) { - panic("iommu_init: secondary IOMMU state does not " - "match primary"); + panic("%s: secondary IOMMU state does not " + "match primary", __func__); } } STAILQ_INSERT_TAIL(&iommu_insts, is, is_link); @@ -464,7 +465,7 @@ iommu_enter(struct iommu_state *is, vm_offset_t va, vm_paddr_t pa, KASSERT(va >= is->is_dvmabase, ("iommu_enter: va %#lx not in DVMA space", va)); - KASSERT(pa < IOMMU_MAXADDR, + KASSERT(pa <= IOMMU_MAXADDR, ("iommu_enter: XXX: physical address too large (%#lx)", pa)); tte = MAKEIOTTE(pa, !(flags & BUS_DMA_NOWRITE), @@ -579,7 +580,7 @@ iommu_strbuf_flush_sync(struct iommu_state *is) microuptime(&cur); if (!*is->is_flushva[0] || !*is->is_flushva[1]) { - panic("iommu_strbuf_flush_done: flush timeout %ld, %ld at %#lx", + panic("%s: flush timeout %ld, %ld at %#lx", __func__, *is->is_flushva[0], *is->is_flushva[1], is->is_flushpa[0]); } @@ -628,7 +629,7 @@ iommu_dvma_valloc(bus_dma_tag_t t, struct iommu_state *is, bus_dmamap_t map, align = (t->dt_alignment + IO_PAGE_MASK) >> IO_PAGE_SHIFT; sgsize = round_io_page(size) >> IO_PAGE_SHIFT; if (t->dt_boundary > 0 && t->dt_boundary < IO_PAGE_SIZE) - panic("iommu_dvmamap_load: illegal boundary specified"); + panic("%s: illegal boundary specified", __func__); res = rman_reserve_resource_bound(&iommu_dvma_rman, 0L, t->dt_lowaddr >> IO_PAGE_SHIFT, sgsize, t->dt_boundary >> IO_PAGE_SHIFT, @@ -849,7 +850,7 @@ iommu_dvmamap_create(bus_dma_tag_t dt, int flags, bus_dmamap_t *mapp) * Clamp preallocation to IOMMU_MAX_PRE. In some situations we can * handle more; that case is handled by reallocating at map load time. */ - totsz = ulmin(IOMMU_SIZE_ROUNDUP(dt->dt_maxsize), IOMMU_MAX_PRE); + totsz = ulmin(IOMMU_SIZE_ROUNDUP(dt->dt_maxsize), IOMMU_MAX_PRE); error = iommu_dvma_valloc(dt, is, *mapp, totsz); if (error != 0) return (0); @@ -886,7 +887,7 @@ iommu_dvmamap_destroy(bus_dma_tag_t dt, bus_dmamap_t map) } /* - * IOMMU DVMA operations, common to SBUS and PCI. + * IOMMU DVMA operations, common to PCI and SBus. */ static int iommu_dvmamap_load_buffer(bus_dma_tag_t dt, struct iommu_state *is, @@ -987,7 +988,7 @@ iommu_dvmamap_load(bus_dma_tag_t dt, bus_dmamap_t map, void *buf, if ((map->dm_flags & DMF_LOADED) != 0) { #ifdef DIAGNOSTIC - printf("iommu_dvmamap_load: map still in use\n"); + printf("%s: map still in use\n", __func__); #endif bus_dmamap_unload(dt, map); } @@ -1031,7 +1032,7 @@ iommu_dvmamap_load_mbuf(bus_dma_tag_t dt, bus_dmamap_t map, struct mbuf *m0, if ((map->dm_flags & DMF_LOADED) != 0) { #ifdef DIAGNOSTIC - printf("iommu_dvmamap_load_mbuf: map still in use\n"); + printf("%s: map still in use\n", __func__); #endif bus_dmamap_unload(dt, map); } @@ -1080,7 +1081,7 @@ iommu_dvmamap_load_mbuf_sg(bus_dma_tag_t dt, bus_dmamap_t map, struct mbuf *m0, *nsegs = -1; if ((map->dm_flags & DMF_LOADED) != 0) { #ifdef DIAGNOSTIC - printf("iommu_dvmamap_load_mbuf: map still in use\n"); + printf("%s: map still in use\n", __func__); #endif bus_dmamap_unload(dt, map); } @@ -1125,7 +1126,7 @@ iommu_dvmamap_load_uio(bus_dma_tag_t dt, bus_dmamap_t map, struct uio *uio, if ((map->dm_flags & DMF_LOADED) != 0) { #ifdef DIAGNOSTIC - printf("iommu_dvmamap_load_uio: map still in use\n"); + printf("%s: map still in use\n", __func__); #endif bus_dmamap_unload(dt, map); } @@ -1153,7 +1154,7 @@ iommu_dvmamap_load_uio(bus_dma_tag_t dt, bus_dmamap_t map, struct uio *uio, continue; error = iommu_dvmamap_load_buffer(dt, is, map, - iov[i].iov_base, minlen, td, flags, dt->dt_segments, + iov[i].iov_base, minlen, td, flags, dt->dt_segments, &nsegs, first); first = 0; @@ -1205,7 +1206,7 @@ iommu_dvmamap_sync(bus_dma_tag_t dt, bus_dmamap_t map, bus_dmasync_op_t op) membar(Sync); if (IOMMU_HAS_SB(is) && ((op & BUS_DMASYNC_POSTREAD) != 0 || - (op & BUS_DMASYNC_PREWRITE) != 0)) { + (op & BUS_DMASYNC_PREWRITE) != 0)) { IS_LOCK(is); SLIST_FOREACH(r, &map->dm_reslist, dr_link) { va = (vm_offset_t)BDR_START(r); @@ -1242,7 +1243,7 @@ iommu_diag(struct iommu_state *is, vm_offset_t va) IS_LOCK_ASSERT(is); IOMMU_WRITE8(is, is_dva, 0, trunc_io_page(va)); membar(StoreStore | StoreLoad); - printf("iommu_diag: tte entry %#lx", IOMMU_GET_TTE(is, va)); + printf("%s: tte entry %#lx", __func__, IOMMU_GET_TTE(is, va)); if (is->is_dtcmp != 0) { printf(", tag compare register is %#lx\n", IOMMU_READ8(is, is_dtcmp, 0)); @@ -1251,8 +1252,8 @@ iommu_diag(struct iommu_state *is, vm_offset_t va) for (i = 0; i < 16; i++) { tag = IOMMU_READ8(is, is_dtag, i * 8); data = IOMMU_READ8(is, is_ddram, i * 8); - printf("iommu_diag: tag %d: %#lx, vpn %#lx, err %lx; " - "data %#lx, pa %#lx, v %d, c %d\n", i, + printf("%s: tag %d: %#lx, vpn %#lx, err %lx; " + "data %#lx, pa %#lx, v %d, c %d\n", __func__, i, tag, (tag & IOMMU_DTAG_VPNMASK) << IOMMU_DTAG_VPNSHIFT, (tag & IOMMU_DTAG_ERRMASK) >> IOMMU_DTAG_ERRSHIFT, data, (data & IOMMU_DDATA_PGMASK) << IOMMU_DDATA_PGSHIFT, diff --git a/sys/sparc64/sparc64/nexus.c b/sys/sparc64/sparc64/nexus.c index d3dcb80f11e4..23314d86038d 100644 --- a/sys/sparc64/sparc64/nexus.c +++ b/sys/sparc64/sparc64/nexus.c @@ -1,6 +1,7 @@ /*- * Copyright 1998 Massachusetts Institute of Technology * Copyright 2001 by Thomas Moestl <tmm@FreeBSD.org>. + * Copyright 2006 by Marius Strobl <marius@FreeBSD.org>. * All rights reserved. * * Permission to use, copy, modify, and distribute this software and @@ -37,20 +38,20 @@ __FBSDID("$FreeBSD$"); #include <sys/param.h> #include <sys/systm.h> #include <sys/bus.h> -#include <sys/cons.h> #include <sys/kernel.h> #include <sys/malloc.h> #include <sys/module.h> +#include <dev/ofw/ofw_bus.h> +#include <dev/ofw/ofw_bus_subr.h> #include <dev/ofw/openfirm.h> #include <machine/bus.h> -#include <machine/frame.h> +#include <machine/bus_common.h> #include <machine/intr_machdep.h> -#include <machine/nexusvar.h> -#include <machine/ofw_upa.h> +#include <machine/ofw_nexus.h> #include <machine/resource.h> -#include <machine/upa.h> +#include <machine/ver.h> #include <sys/rman.h> @@ -67,18 +68,9 @@ __FBSDID("$FreeBSD$"); * work for all Open Firmware based machines... */ -static MALLOC_DEFINE(M_NEXUS, "nexus", "nexus device information"); - struct nexus_devinfo { - phandle_t ndi_node; - /* Some common properties. */ - char *ndi_name; - char *ndi_device_type; - char *ndi_model; - struct upa_regs *ndi_reg; - int ndi_nreg; - u_int *ndi_interrupts; - int ndi_ninterrupts; + struct ofw_bus_devinfo ndi_obdinfo; + struct resource_list ndi_rl; }; struct nexus_softc { @@ -88,15 +80,23 @@ struct nexus_softc { static device_probe_t nexus_probe; static device_attach_t nexus_attach; +static bus_print_child_t nexus_print_child; static bus_add_child_t nexus_add_child; static bus_probe_nomatch_t nexus_probe_nomatch; -static bus_read_ivar_t nexus_read_ivar; static bus_setup_intr_t nexus_setup_intr; static bus_teardown_intr_t nexus_teardown_intr; static bus_alloc_resource_t nexus_alloc_resource; static bus_activate_resource_t nexus_activate_resource; static bus_deactivate_resource_t nexus_deactivate_resource; static bus_release_resource_t nexus_release_resource; +static bus_get_resource_list_t nexus_get_resource_list; +static bus_get_dma_tag_t nexus_get_dma_tag; +static ofw_bus_get_devinfo_t nexus_get_devinfo; + +static int nexus_inlist(const char *, const char **); +static struct nexus_devinfo * nexus_setup_dinfo(device_t, phandle_t); +static void nexus_destroy_dinfo(struct nexus_devinfo *); +static int nexus_print_res(struct nexus_devinfo *); static device_method_t nexus_methods[] = { /* Device interface */ @@ -107,44 +107,53 @@ static device_method_t nexus_methods[] = { DEVMETHOD(device_suspend, bus_generic_suspend), DEVMETHOD(device_resume, bus_generic_resume), - /* Bus interface. */ - DEVMETHOD(bus_add_child, nexus_add_child), - DEVMETHOD(bus_print_child, bus_generic_print_child), + /* Bus interface */ + DEVMETHOD(bus_print_child, nexus_print_child), DEVMETHOD(bus_probe_nomatch, nexus_probe_nomatch), - DEVMETHOD(bus_read_ivar, nexus_read_ivar), - DEVMETHOD(bus_setup_intr, nexus_setup_intr), - DEVMETHOD(bus_teardown_intr, nexus_teardown_intr), + DEVMETHOD(bus_read_ivar, bus_generic_read_ivar), + DEVMETHOD(bus_write_ivar, bus_generic_write_ivar), + DEVMETHOD(bus_add_child, nexus_add_child), DEVMETHOD(bus_alloc_resource, nexus_alloc_resource), DEVMETHOD(bus_activate_resource, nexus_activate_resource), DEVMETHOD(bus_deactivate_resource, nexus_deactivate_resource), DEVMETHOD(bus_release_resource, nexus_release_resource), + DEVMETHOD(bus_setup_intr, nexus_setup_intr), + DEVMETHOD(bus_teardown_intr, nexus_teardown_intr), + DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource), + DEVMETHOD(bus_get_resource_list, nexus_get_resource_list), + DEVMETHOD(bus_get_dma_tag, nexus_get_dma_tag), + + /* ofw_bus interface */ + DEVMETHOD(ofw_bus_get_devinfo, nexus_get_devinfo), + DEVMETHOD(ofw_bus_get_compat, ofw_bus_gen_get_compat), + DEVMETHOD(ofw_bus_get_model, ofw_bus_gen_get_model), + DEVMETHOD(ofw_bus_get_name, ofw_bus_gen_get_name), + DEVMETHOD(ofw_bus_get_node, ofw_bus_gen_get_node), + DEVMETHOD(ofw_bus_get_type, ofw_bus_gen_get_type), { 0, 0 } }; -static driver_t nexus_driver = { - "nexus", - nexus_methods, - sizeof(struct nexus_softc), -}; - static devclass_t nexus_devclass; +DEFINE_CLASS_0(nexus, nexus_driver, nexus_methods, sizeof(struct nexus_softc)); DRIVER_MODULE(nexus, root, nexus_driver, nexus_devclass, 0, 0); -static char *nexus_excl_name[] = { +static const char *nexus_excl_name[] = { "aliases", + "associations", "chosen", "counter-timer", /* No separate device; handled by psycho/sbus */ "memory", "openprom", "options", "packages", + "rsc", "virtual-memory", NULL }; -static char *nexus_excl_type[] = { +static const char *nexus_excl_type[] = { "cpu", NULL }; @@ -153,10 +162,12 @@ extern struct bus_space_tag nexus_bustag; extern struct bus_dma_tag nexus_dmatag; static int -nexus_inlist(char *name, char *list[]) +nexus_inlist(const char *name, const char **list) { int i; + if (name == NULL) + return (0); for (i = 0; list[i] != NULL; i++) if (strcmp(name, list[i]) == 0) return (1); @@ -179,26 +190,25 @@ nexus_probe(device_t dev) static int nexus_attach(device_t dev) { - phandle_t root; - phandle_t child; - device_t cdev; - struct nexus_devinfo *dinfo; + struct nexus_devinfo *ndi; struct nexus_softc *sc; - char *name, *type; + device_t cdev; + phandle_t node; - if ((root = OF_peer(0)) == -1) - panic("nexus_probe: OF_peer failed."); + node = OF_peer(0); + if (node == -1) + panic("%s: OF_peer failed.", __func__); 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"; + sc->sc_mem_rman.rm_descr = "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, IV_MAX - 1) != 0 || - rman_manage_region(&sc->sc_mem_rman, UPA_MEMSTART, UPA_MEMEND) != 0) - panic("nexus_attach(): failed to set up rmans"); + rman_manage_region(&sc->sc_mem_rman, 0ULL, ~0ULL) != 0) + panic("%s: failed to set up rmans.", __func__); /* * Allow devices to identify. @@ -208,32 +218,17 @@ nexus_attach(device_t dev) /* * Now walk the OFW tree and attach top-level devices. */ - for (child = OF_child(root); child != 0; child = OF_peer(child)) { - if (child == -1) - panic("nexus_attach(): OF_child() failed."); - if (OF_getprop_alloc(child, "name", 1, (void **)&name) == -1) + for (node = OF_child(node); node > 0; node = OF_peer(node)) { + if ((ndi = nexus_setup_dinfo(dev, node)) == NULL) continue; - OF_getprop_alloc(child, "device_type", 1, (void **)&type); - if (NEXUS_EXCLUDED(name, type)) { - free(name, M_OFWPROP); - free(type, M_OFWPROP); + cdev = device_add_child(dev, NULL, -1); + if (cdev == NULL) { + device_printf(dev, "<%s>: device_add_child failed\n", + ndi->ndi_obdinfo.obd_name); + nexus_destroy_dinfo(ndi); continue; } - cdev = device_add_child(dev, NULL, -1); - if (cdev == NULL) - panic("nexus_attach(): device_add_child() failed."); - dinfo = malloc(sizeof(*dinfo), M_NEXUS, M_WAITOK); - dinfo->ndi_node = child; - dinfo->ndi_name = name; - dinfo->ndi_device_type = type; - OF_getprop_alloc(child, "model", 1, - (void **)&dinfo->ndi_model); - dinfo->ndi_nreg = OF_getprop_alloc(child, "reg", - sizeof(*dinfo->ndi_reg), (void **)&dinfo->ndi_reg); - dinfo->ndi_ninterrupts = OF_getprop_alloc(child, - "interrupts", sizeof(*dinfo->ndi_interrupts), - (void **)&dinfo->ndi_interrupts); - device_set_ivars(cdev, dinfo); + device_set_ivars(cdev, ndi); } return (bus_generic_attach(dev)); } @@ -242,73 +237,42 @@ static device_t nexus_add_child(device_t dev, int order, const char *name, int unit) { device_t cdev; - struct nexus_devinfo *dinfo; + struct nexus_devinfo *ndi; cdev = device_add_child_ordered(dev, order, name, unit); if (cdev == NULL) return (NULL); - dinfo = malloc(sizeof(*dinfo), M_NEXUS, M_NOWAIT | M_ZERO); - if (dinfo == NULL) - return (NULL); - - dinfo->ndi_node = -1; - dinfo->ndi_name = strdup(name, M_OFWPROP); - device_set_ivars(cdev, dinfo); + ndi = malloc(sizeof(*ndi), M_DEVBUF, M_WAITOK | M_ZERO); + ndi->ndi_obdinfo.obd_node = -1; + ndi->ndi_obdinfo.obd_name = strdup(name, M_OFWPROP); + resource_list_init(&ndi->ndi_rl); + device_set_ivars(cdev, ndi); return (cdev); } -static void -nexus_probe_nomatch(device_t dev, device_t child) +static int +nexus_print_child(device_t dev, device_t child) { - char *type; + int rv; - if ((type = nexus_get_device_type(child)) == NULL) - type = "(unknown)"; - device_printf(dev, "<%s>, type %s (no driver attached)\n", - nexus_get_name(child), type); + rv = bus_print_child_header(dev, child); + rv += nexus_print_res(device_get_ivars(child)); + rv += bus_print_child_footer(dev, child); + return (rv); } -static int -nexus_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) +static void +nexus_probe_nomatch(device_t dev, device_t child) { - struct nexus_devinfo *dinfo; + const char *type; - if ((dinfo = device_get_ivars(child)) == 0) - return (ENOENT); - switch (which) { - case NEXUS_IVAR_NODE: - *result = dinfo->ndi_node; - break; - case NEXUS_IVAR_NAME: - *result = (uintptr_t)dinfo->ndi_name; - break; - case NEXUS_IVAR_DEVICE_TYPE: - *result = (uintptr_t)dinfo->ndi_device_type; - break; - case NEXUS_IVAR_MODEL: - *result = (uintptr_t)dinfo->ndi_model; - break; - case NEXUS_IVAR_REG: - *result = (uintptr_t)dinfo->ndi_reg; - break; - case NEXUS_IVAR_NREG: - *result = dinfo->ndi_nreg; - break; - case NEXUS_IVAR_INTERRUPTS: - *result = (uintptr_t)dinfo->ndi_interrupts; - break; - case NEXUS_IVAR_NINTERRUPTS: - *result = dinfo->ndi_ninterrupts; - break; - case NEXUS_IVAR_DMATAG: - *result = (uintptr_t)&nexus_dmatag; - break; - default: - return (ENOENT); - } - return 0; + device_printf(dev, "<%s>", ofw_bus_get_name(child)); + nexus_print_res(device_get_ivars(child)); + type = ofw_bus_get_type(child); + printf(" type %s (no driver attached)\n", + type != NULL ? type : "unknown"); } static int @@ -318,7 +282,7 @@ nexus_setup_intr(device_t dev, device_t child, struct resource *res, int flags, int error; if (res == NULL) - panic("nexus_setup_intr: NULL interrupt resource!"); + panic("%s: NULL interrupt resource!", __func__); if ((rman_get_flags(res) & RF_SHAREABLE) == 0) flags |= INTR_EXCL; @@ -331,6 +295,11 @@ nexus_setup_intr(device_t dev, device_t child, struct resource *res, int flags, error = inthand_add(device_get_nameunit(child), rman_get_start(res), filt, intr, arg, flags, cookiep); + /* + * XXX in case of the AFB/FFB interrupt and a Psycho, Sabre or U2S + * bridge enable the interrupt in the respective bridge. + */ + return (error); } @@ -346,12 +315,31 @@ 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; - - flags &= ~RF_ACTIVE; + struct nexus_softc *sc; + struct rman *rm; + struct resource *rv; + struct resource_list_entry *rle; + int isdefault, needactivate, passthrough; + + isdefault = (start == 0UL && end == ~0UL); + needactivate = flags & RF_ACTIVE; + passthrough = (device_get_parent(child) != bus); + sc = device_get_softc(bus); + rle = NULL; + + if (!passthrough) { + rle = resource_list_find(BUS_GET_RESOURCE_LIST(bus, child), + type, *rid); + if (rle == NULL) + return (NULL); + if (rle->res != NULL) + panic("%s: resource entry is busy", __func__); + if (isdefault) { + start = rle->start; + count = ulmax(count, rle->count); + end = ulmax(rle->end, start + count - 1); + } + } switch (type) { case SYS_RES_IRQ: @@ -364,6 +352,7 @@ nexus_alloc_resource(device_t bus, device_t child, int type, int *rid, return (NULL); } + flags &= ~RF_ACTIVE; rv = rman_reserve_resource(rm, start, end, count, flags, child); if (rv == NULL) return (NULL); @@ -380,6 +369,13 @@ nexus_alloc_resource(device_t bus, device_t child, int type, int *rid, } } + if (!passthrough) { + rle->res = rv; + rle->start = rman_get_start(rv); + rle->end = rman_get_end(rv); + rle->count = rle->end - rle->start + 1; + } + return (rv); } @@ -403,7 +399,7 @@ nexus_deactivate_resource(device_t bus, device_t child, int type, int rid, static int nexus_release_resource(device_t bus, device_t child, int type, int rid, - struct resource *r) + struct resource *r) { int error; @@ -414,3 +410,117 @@ nexus_release_resource(device_t bus, device_t child, int type, int rid, } return (rman_release_resource(r)); } + +static struct resource_list * +nexus_get_resource_list(device_t dev, device_t child) +{ + struct nexus_devinfo *ndi; + + ndi = device_get_ivars(child); + return (&ndi->ndi_rl); +} + +static bus_dma_tag_t +nexus_get_dma_tag(device_t bus, device_t child) +{ + + return (&nexus_dmatag); +} + +static const struct ofw_bus_devinfo * +nexus_get_devinfo(device_t dev, device_t child) +{ + struct nexus_devinfo *ndi; + + ndi = device_get_ivars(child); + return (&ndi->ndi_obdinfo); +} + +static struct nexus_devinfo * +nexus_setup_dinfo(device_t dev, phandle_t node) +{ + struct nexus_devinfo *ndi; + struct nexus_regs *reg; + bus_addr_t phys; + bus_size_t size; + uint32_t ign; + uint32_t *intr; + int i; + int nintr; + int nreg; + + ndi = malloc(sizeof(*ndi), M_DEVBUF, M_WAITOK | M_ZERO); + if (ofw_bus_gen_setup_devinfo(&ndi->ndi_obdinfo, node) != 0) { + free(ndi, M_DEVBUF); + return (NULL); + } + if (NEXUS_EXCLUDED(ndi->ndi_obdinfo.obd_name, + ndi->ndi_obdinfo.obd_type)) { + ofw_bus_gen_destroy_devinfo(&ndi->ndi_obdinfo); + free(ndi, M_DEVBUF); + return (NULL); + } + resource_list_init(&ndi->ndi_rl); + nreg = OF_getprop_alloc(node, "reg", sizeof(*reg), (void **)®); + if (nreg == -1) { + device_printf(dev, "<%s>: incomplete\n", + ndi->ndi_obdinfo.obd_name); + goto fail; + } + for (i = 0; i < nreg; i++) { + phys = NEXUS_REG_PHYS(®[i]); + size = NEXUS_REG_SIZE(®[i]); + resource_list_add(&ndi->ndi_rl, SYS_RES_MEMORY, i, phys, + phys + size - 1, size); + } + free(reg, M_OFWPROP); + + nintr = OF_getprop_alloc(node, "interrupts", sizeof(*intr), + (void **)&intr); + if (nintr > 0) { + if (OF_getprop(node, cpu_impl < CPU_IMPL_ULTRASPARCIII ? + "upa-portid" : "portid", &ign, sizeof(ign)) <= 0) { + device_printf(dev, "<%s>: could not determine portid\n", + ndi->ndi_obdinfo.obd_name); + free(intr, M_OFWPROP); + goto fail; + } + + /* XXX 7-bit MID on Starfire */ + ign = (ign << INTMAP_IGN_SHIFT) & INTMAP_IGN_MASK; + for (i = 0; i < nintr; i++) { + intr[i] |= ign; + resource_list_add(&ndi->ndi_rl, SYS_RES_IRQ, i, intr[i], + intr[i], 1); + } + free(intr, M_OFWPROP); + } + + return (ndi); + + fail: + nexus_destroy_dinfo(ndi); + return (NULL); +} + +static void +nexus_destroy_dinfo(struct nexus_devinfo *ndi) +{ + + resource_list_free(&ndi->ndi_rl); + ofw_bus_gen_destroy_devinfo(&ndi->ndi_obdinfo); + free(ndi, M_DEVBUF); +} + +static int +nexus_print_res(struct nexus_devinfo *ndi) +{ + int rv; + + rv = 0; + rv += resource_list_print_type(&ndi->ndi_rl, "mem", SYS_RES_MEMORY, + "%#lx"); + rv += resource_list_print_type(&ndi->ndi_rl, "irq", SYS_RES_IRQ, + "%ld"); + return (rv); +} diff --git a/sys/sparc64/sparc64/sc_machdep.c b/sys/sparc64/sparc64/sc_machdep.c index 032f793b8b51..f56f669274f2 100644 --- a/sys/sparc64/sparc64/sc_machdep.c +++ b/sys/sparc64/sparc64/sc_machdep.c @@ -36,10 +36,9 @@ __FBSDID("$FreeBSD$"); #include <sys/limits.h> #include <sys/module.h> -#include <dev/ofw/openfirm.h> +#include <dev/ofw/ofw_bus.h> #include <machine/bus.h> -#include <machine/nexusvar.h> #include <dev/syscons/syscons.h> @@ -88,7 +87,7 @@ sc_probe(device_t dev) int unit; unit = device_get_unit(dev); - if (strcmp(nexus_get_name(dev), SC_DRIVER_NAME) != 0 || + if (strcmp(ofw_bus_get_name(dev), SC_DRIVER_NAME) != 0 || unit >= SC_MD_MAX) return (ENXIO); |