aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/conf/files.sparc642
-rw-r--r--sys/dev/fb/creator.c42
-rw-r--r--sys/sparc64/central/central.c10
-rw-r--r--sys/sparc64/fhc/fhc.c142
-rw-r--r--sys/sparc64/fhc/fhc_central.c132
-rw-r--r--sys/sparc64/fhc/fhc_nexus.c147
-rw-r--r--sys/sparc64/fhc/fhcvar.h59
-rw-r--r--sys/sparc64/include/bus_private.h7
-rw-r--r--sys/sparc64/include/iommureg.h8
-rw-r--r--sys/sparc64/include/nexusvar.h58
-rw-r--r--sys/sparc64/include/ofw_nexus.h28
-rw-r--r--sys/sparc64/include/ofw_upa.h54
-rw-r--r--sys/sparc64/pci/psycho.c154
-rw-r--r--sys/sparc64/pci/psychovar.h1
-rw-r--r--sys/sparc64/sbus/sbus.c82
-rw-r--r--sys/sparc64/sparc64/bus_machdep.c52
-rw-r--r--sys/sparc64/sparc64/iommu.c47
-rw-r--r--sys/sparc64/sparc64/nexus.c360
-rw-r--r--sys/sparc64/sparc64/sc_machdep.c5
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(&reg[2]);
- mlen = UPA_REG_SIZE(&reg[2]);
- sc->sc_pcictl = UPA_REG_PHYS(&reg[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(&reg[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 **)&reg);
+ 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(&reg[i]);
+ size = NEXUS_REG_SIZE(&reg[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);