summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/conf/files.sparc645
-rw-r--r--sys/sparc64/central/central.c231
-rw-r--r--sys/sparc64/central/centralvar.h47
-rw-r--r--sys/sparc64/fhc/fhc.c299
-rw-r--r--sys/sparc64/fhc/fhc_central.c125
-rw-r--r--sys/sparc64/fhc/fhc_nexus.c125
-rw-r--r--sys/sparc64/fhc/fhcreg.h44
-rw-r--r--sys/sparc64/fhc/fhcvar.h71
-rw-r--r--sys/sparc64/sparc64/eeprom_fhc.c140
9 files changed, 1087 insertions, 0 deletions
diff --git a/sys/conf/files.sparc64 b/sys/conf/files.sparc64
index 681933b..8b16895 100644
--- a/sys/conf/files.sparc64
+++ b/sys/conf/files.sparc64
@@ -21,7 +21,11 @@ geom/geom_bsd.c standard
geom/geom_sunlabel.c standard
libkern/ffs.c standard
kern/syscalls.c optional ktr
+sparc64/central/central.c optional central
sparc64/ebus/ebus.c optional ebus
+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/ofw_isa.c optional ebus
sparc64/isa/ofw_isa.c optional isa
@@ -48,6 +52,7 @@ sparc64/sparc64/elf_machdep.c standard
# sparc64/sparc64/interrupt.S standard
sparc64/sparc64/eeprom.c optional eeprom
sparc64/sparc64/eeprom_ebus.c optional eeprom ebus
+sparc64/sparc64/eeprom_fhc.c optional eeprom fhc
sparc64/sparc64/eeprom_sbus.c optional eeprom sbus
sparc64/sparc64/identcpu.c standard
sparc64/sparc64/in_cksum.c optional inet
diff --git a/sys/sparc64/central/central.c b/sys/sparc64/central/central.c
new file mode 100644
index 0000000..e3f364d
--- /dev/null
+++ b/sys/sparc64/central/central.c
@@ -0,0 +1,231 @@
+/*-
+ * 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$
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+
+#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>
+
+#include <sparc64/central/centralvar.h>
+#include <sparc64/sbus/ofw_sbus.h>
+#include <sparc64/sbus/sbusreg.h>
+
+struct central_devinfo {
+ char *cdi_name;
+ char *cdi_type;
+ phandle_t cdi_node;
+};
+
+struct central_softc {
+ phandle_t sc_node;
+ int sc_nrange;
+ struct sbus_ranges *sc_ranges;
+};
+
+static int central_probe(device_t dev);
+static int central_attach(device_t dev);
+
+static void central_probe_nomatch(device_t dev, device_t child);
+static int central_read_ivar(device_t, device_t, int, uintptr_t *);
+static int central_write_ivar(device_t, device_t, int, uintptr_t);
+static struct resource *central_alloc_resource(device_t, device_t, int, int *,
+ u_long, u_long, u_long, u_int);
+
+static device_method_t central_methods[] = {
+ /* Device interface. */
+ DEVMETHOD(device_probe, central_probe),
+ DEVMETHOD(device_attach, central_attach),
+
+ /* Bus interface. */
+ DEVMETHOD(bus_print_child, bus_generic_print_child),
+ DEVMETHOD(bus_probe_nomatch, central_probe_nomatch),
+ DEVMETHOD(bus_read_ivar, central_read_ivar),
+ DEVMETHOD(bus_write_ivar, central_write_ivar),
+ DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
+ DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
+ DEVMETHOD(bus_alloc_resource, central_alloc_resource),
+ DEVMETHOD(bus_release_resource, bus_generic_release_resource),
+ DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
+ DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
+
+ { NULL, NULL }
+};
+
+static driver_t central_driver = {
+ "central",
+ central_methods,
+ sizeof(struct central_softc),
+};
+
+static devclass_t central_devclass;
+
+DRIVER_MODULE(central, nexus, central_driver, central_devclass, 0, 0);
+
+static int
+central_probe(device_t dev)
+{
+
+ if (strcmp(nexus_get_name(dev), "central") == 0) {
+ device_set_desc(dev, "central");
+ return (0);
+ }
+ return (ENXIO);
+}
+
+static int
+central_attach(device_t dev)
+{
+ struct central_devinfo *cdi;
+ struct central_softc *sc;
+ phandle_t child;
+ phandle_t node;
+ device_t cdev;
+ char *name;
+
+ sc = device_get_softc(dev);
+ node = nexus_get_node(dev);
+ sc->sc_node = node;
+
+ 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");
+ return (ENXIO);
+ }
+
+ for (child = OF_child(node); child != 0; child = OF_peer(child)) {
+ if ((OF_getprop_alloc(child, "name", 1, (void **)&name)) == -1)
+ continue;
+ cdev = device_add_child(dev, NULL, -1);
+ if (cdev != NULL) {
+ cdi = malloc(sizeof(*cdi), M_DEVBUF, M_ZERO);
+ cdi->cdi_name = name;
+ cdi->cdi_node = child;
+ OF_getprop_alloc(child, "device_type", 1,
+ (void **)&cdi->cdi_type);
+ device_set_ivars(cdev, cdi);
+ } else
+ free(name, M_OFWPROP);
+ }
+
+ return (bus_generic_attach(dev));
+}
+
+static void
+central_probe_nomatch(device_t dev, device_t child)
+{
+ struct central_devinfo *cdi;
+
+ cdi = device_get_ivars(child);
+ device_printf(dev, "<%s> type %s (no driver attached)\n",
+ cdi->cdi_name, cdi->cdi_type != NULL ? cdi->cdi_type : "unknown");
+}
+
+static int
+central_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
+{
+ struct central_devinfo *cdi;
+
+ if ((cdi = device_get_ivars(child)) == 0)
+ return (ENOENT);
+ switch (which) {
+ case CENTRAL_IVAR_NAME:
+ *result = (uintptr_t)cdi->cdi_name;
+ break;
+ case CENTRAL_IVAR_NODE:
+ *result = cdi->cdi_node;
+ break;
+ case CENTRAL_IVAR_TYPE:
+ *result = (uintptr_t)cdi->cdi_type;
+ break;
+ default:
+ return (ENOENT);
+ }
+ return (0);
+}
+
+static int
+central_write_ivar(device_t dev, device_t child, int which, uintptr_t value)
+{
+ struct central_devinfo *cdi;
+
+ if ((cdi = device_get_ivars(child)) == 0)
+ return (ENOENT);
+ switch (which) {
+ case CENTRAL_IVAR_NAME:
+ case CENTRAL_IVAR_NODE:
+ case CENTRAL_IVAR_TYPE:
+ return (EINVAL);
+ default:
+ return (ENOENT);
+ }
+ return (0);
+}
+
+static struct resource *
+central_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 central_softc *sc;
+ struct resource *res;
+ bus_addr_t coffset;
+ bus_addr_t cend;
+ bus_addr_t phys;
+ int i;
+
+ if (type != SYS_RES_MEMORY) {
+ return (bus_generic_alloc_resource(bus, child, type, rid,
+ start, end, count, flags));
+ }
+ res = NULL;
+ sc = device_get_softc(bus);
+ for (i = 0; i < sc->sc_nrange; i++) {
+ coffset = sc->sc_ranges[i].coffset;
+ cend = coffset + sc->sc_ranges[i].size - 1;
+ if (start >= coffset && end <= cend) {
+ start -= coffset;
+ end -= coffset;
+ phys = sc->sc_ranges[i].poffset |
+ ((bus_addr_t)sc->sc_ranges[i].pspace << 32);
+ res = bus_generic_alloc_resource(bus, child, type,
+ rid, phys + start, phys + end, count, flags);
+ break;
+ }
+ }
+ return (res);
+}
diff --git a/sys/sparc64/central/centralvar.h b/sys/sparc64/central/centralvar.h
new file mode 100644
index 0000000..a3b03c6
--- /dev/null
+++ b/sys/sparc64/central/centralvar.h
@@ -0,0 +1,47 @@
+/*-
+ * 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_CENTRAL_CENTRALVAR_H_
+#define _SPARC64_CENTRAL_CENTRALVAR_H_
+
+enum central_device_ivars {
+ CENTRAL_IVAR_NAME,
+ CENTRAL_IVAR_NODE,
+ CENTRAL_IVAR_TYPE
+};
+
+#define CENTRAL_ACCESSOR(var, ivar, type) \
+ __BUS_ACCESSOR(central, var, CENTRAL, ivar, type)
+
+CENTRAL_ACCESSOR(name, NAME, char *)
+CENTRAL_ACCESSOR(node, NODE, phandle_t)
+CENTRAL_ACCESSOR(type, TYPE, char *)
+
+#undef CENTRAL_ACCESSOR
+
+#endif
diff --git a/sys/sparc64/fhc/fhc.c b/sys/sparc64/fhc/fhc.c
new file mode 100644
index 0000000..829e21c
--- /dev/null
+++ b/sys/sparc64/fhc/fhc.c
@@ -0,0 +1,299 @@
+/*-
+ * 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$
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+
+#include <dev/ofw/openfirm.h>
+
+#include <machine/bus.h>
+#include <machine/bus_common.h>
+#include <machine/resource.h>
+
+#include <sys/rman.h>
+
+#include <sparc64/fhc/fhcreg.h>
+#include <sparc64/fhc/fhcvar.h>
+#include <sparc64/sbus/ofw_sbus.h>
+
+#define INTIGN(map) (((map) & INTMAP_IGN_MASK) >> INTMAP_IGN_SHIFT)
+
+struct fhc_devinfo {
+ char *fdi_name;
+ char *fdi_type;
+ phandle_t fdi_node;
+ struct resource_list fdi_rl;
+};
+
+int
+fhc_probe(device_t dev)
+{
+
+ return (0);
+}
+
+int
+fhc_attach(device_t dev)
+{
+ struct fhc_devinfo *fdi;
+ struct sbus_regs *reg;
+ struct fhc_softc *sc;
+ phandle_t child;
+ phandle_t node;
+ bus_addr_t size;
+ bus_addr_t off;
+ device_t cdev;
+ uint64_t map;
+ char *name;
+ int nreg;
+ int i;
+
+ sc = device_get_softc(dev);
+ node = sc->sc_node;
+
+ sc->sc_ign = bus_space_read_4(sc->sc_bt[FHC_IGN],
+ sc->sc_bh[FHC_IGN], 0x0);
+ for (i = FHC_FANFAIL; i <= FHC_TOD; i++) {
+ bus_space_write_4(sc->sc_bt[i], sc->sc_bh[i], FHC_ICLR, 0x0);
+ map = bus_space_read_4(sc->sc_bt[i], sc->sc_bh[i], FHC_IMAP);
+ bus_space_write_4(sc->sc_bt[i], sc->sc_bh[i], FHC_IMAP,
+ map & ~INTMAP_V);
+ if (INTIGN(map) != sc->sc_ign)
+ panic("fhc_attach: map has wrong ign %#lx != %#x",
+ INTIGN(map), sc->sc_ign);
+ }
+
+ 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");
+ return (ENXIO);
+ }
+
+ for (child = OF_child(node); child != 0; child = OF_peer(child)) {
+ if ((OF_getprop_alloc(child, "name", 1, (void **)&name)) == -1)
+ continue;
+ cdev = device_add_child(dev, NULL, -1);
+ if (cdev != NULL) {
+ fdi = malloc(sizeof(*fdi), M_DEVBUF, M_ZERO);
+ fdi->fdi_name = name;
+ fdi->fdi_node = child;
+ OF_getprop_alloc(child, "device_type", 1,
+ (void **)&fdi->fdi_type);
+ resource_list_init(&fdi->fdi_rl);
+ nreg = OF_getprop_alloc(child, "reg", sizeof(*reg),
+ (void **)&reg);
+ if (nreg != -1) {
+ for (i = 0; i < nreg; i++) {
+ off = reg[i].sbr_offset;
+ size = reg[i].sbr_size;
+ resource_list_add(&fdi->fdi_rl,
+ SYS_RES_MEMORY, i, off, off + size,
+ size);
+ }
+ free(reg, M_OFWPROP);
+ }
+ device_set_ivars(cdev, fdi);
+ } else
+ free(name, M_OFWPROP);
+ }
+
+ return (bus_generic_attach(dev));
+}
+
+int
+fhc_print_child(device_t dev, device_t child)
+{
+ struct fhc_devinfo *fdi;
+ int rv;
+
+ fdi = device_get_ivars(child);
+ rv = bus_print_child_header(dev, child);
+ rv += resource_list_print_type(&fdi->fdi_rl, "mem",
+ SYS_RES_MEMORY, "%#lx");
+ rv += bus_print_child_footer(dev, child);
+ return (rv);
+}
+
+void
+fhc_probe_nomatch(device_t dev, device_t child)
+{
+ struct fhc_devinfo *fdi;
+
+ fdi = device_get_ivars(child);
+ device_printf(dev, "<%s>", fdi->fdi_name);
+ resource_list_print_type(&fdi->fdi_rl, "mem", SYS_RES_MEMORY, "%#lx");
+ printf(" type %s (no driver attached)\n",
+ fdi->fdi_type != NULL ? fdi->fdi_type : "unknown");
+}
+
+int
+fhc_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
+{
+ struct fhc_devinfo *fdi;
+
+ if ((fdi = device_get_ivars(child)) == 0)
+ return (ENOENT);
+ switch (which) {
+ case FHC_IVAR_NAME:
+ *result = (uintptr_t)fdi->fdi_name;
+ break;
+ case FHC_IVAR_NODE:
+ *result = fdi->fdi_node;
+ break;
+ case FHC_IVAR_TYPE:
+ *result = (uintptr_t)fdi->fdi_type;
+ break;
+ default:
+ return (ENOENT);
+ }
+ return (0);
+}
+
+int
+fhc_write_ivar(device_t dev, device_t child, int which, uintptr_t value)
+{
+ struct fhc_devinfo *fdi;
+
+ if ((fdi = device_get_ivars(child)) == 0)
+ return (ENOENT);
+ switch (which) {
+ case FHC_IVAR_NAME:
+ case FHC_IVAR_NODE:
+ case FHC_IVAR_TYPE:
+ return (EINVAL);
+ default:
+ return (ENOENT);
+ }
+ return (0);
+}
+
+int
+fhc_setup_intr(device_t bus, device_t child, struct resource *r, int flags,
+ driver_intr_t intr, void *arg, void **cookiep)
+{
+
+ return (bus_generic_setup_intr(bus, child, r, flags, intr, arg,
+ cookiep));
+}
+
+int
+fhc_teardown_intr(device_t bus, device_t child, struct resource *r,
+ void *cookie)
+{
+
+ return (bus_generic_teardown_intr(bus, child, r, cookie));
+}
+
+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)
+{
+ struct resource_list_entry *rle;
+ struct fhc_devinfo *fdi;
+ struct fhc_softc *sc;
+ struct resource *res;
+ bus_addr_t coffset;
+ bus_addr_t cend;
+ bus_addr_t phys;
+ int isdefault;
+ uint64_t map;
+ int i;
+
+ isdefault = (start == 0UL && end == ~0UL);
+ res = NULL;
+ sc = device_get_softc(bus);
+ switch (type) {
+ case SYS_RES_IRQ:
+ if (!isdefault || count != 1 || *rid < FHC_FANFAIL ||
+ *rid > FHC_TOD)
+ break;
+ map = bus_space_read_4(sc->sc_bt[*rid], sc->sc_bh[*rid],
+ FHC_IMAP);
+ res = bus_generic_alloc_resource(bus, child, type, rid,
+ INTVEC(map), INTVEC(map), 1, flags);
+ if (res != NULL)
+ rman_set_rid(res, *rid);
+ break;
+ case SYS_RES_MEMORY:
+ fdi = device_get_ivars(child);
+ rle = resource_list_find(&fdi->fdi_rl, type, *rid);
+ if (rle == NULL)
+ return (NULL);
+ if (rle->res != NULL)
+ panic("fhc_alloc_resource: resource entry is busy");
+ if (isdefault) {
+ start = rle->start;
+ count = ulmax(count, rle->count);
+ end = ulmax(rle->end, start + count - 1);
+ }
+ for (i = 0; i < sc->sc_nrange; i++) {
+ coffset = sc->sc_ranges[i].coffset;
+ cend = coffset + sc->sc_ranges[i].size - 1;
+ if (start >= coffset && end <= cend) {
+ start -= coffset;
+ end -= coffset;
+ phys = sc->sc_ranges[i].poffset |
+ ((bus_addr_t)sc->sc_ranges[i].pspace << 32);
+ res = bus_generic_alloc_resource(bus, child,
+ type, rid, phys + start, phys + end,
+ count, flags);
+ rle->res = res;
+ break;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ return (res);
+}
+
+int
+fhc_release_resource(device_t bus, device_t child, int type, int rid,
+ struct resource *r)
+{
+ struct resource_list_entry *rle;
+ struct fhc_devinfo *fdi;
+ int error;
+
+ error = bus_generic_release_resource(bus, child, type, rid, r);
+ if (error != 0)
+ return (error);
+ fdi = device_get_ivars(child);
+ rle = resource_list_find(&fdi->fdi_rl, type, rid);
+ if (rle == NULL)
+ panic("fhc_release_resource: can't find resource");
+ if (rle->res == NULL)
+ panic("fhc_release_resource: resource entry is not busy");
+ rle->res = NULL;
+ return (error);
+}
diff --git a/sys/sparc64/fhc/fhc_central.c b/sys/sparc64/fhc/fhc_central.c
new file mode 100644
index 0000000..a1daee9
--- /dev/null
+++ b/sys/sparc64/fhc/fhc_central.c
@@ -0,0 +1,125 @@
+/*-
+ * 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$
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+
+#include <dev/ofw/openfirm.h>
+
+#include <machine/bus.h>
+#include <machine/resource.h>
+
+#include <sys/rman.h>
+
+#include <sparc64/central/centralvar.h>
+#include <sparc64/fhc/fhcreg.h>
+#include <sparc64/fhc/fhcvar.h>
+#include <sparc64/sbus/ofw_sbus.h>
+
+static int fhc_central_probe(device_t dev);
+static int fhc_central_attach(device_t dev);
+
+static device_method_t fhc_central_methods[] = {
+ /* Device interface. */
+ DEVMETHOD(device_probe, fhc_central_probe),
+ DEVMETHOD(device_attach, fhc_central_attach),
+
+ /* Bus interface. */
+ DEVMETHOD(bus_print_child, fhc_print_child),
+ DEVMETHOD(bus_probe_nomatch, fhc_probe_nomatch),
+ DEVMETHOD(bus_read_ivar, fhc_read_ivar),
+ DEVMETHOD(bus_write_ivar, fhc_write_ivar),
+ 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, fhc_release_resource),
+ DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
+ DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
+
+ { 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(central_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 sbus_regs *reg;
+ struct fhc_softc *sc;
+ bus_addr_t size;
+ bus_addr_t off;
+ phandle_t node;
+ int nreg;
+ int rid;
+ int i;
+
+ sc = device_get_softc(dev);
+ node = central_get_node(dev);
+ sc->sc_node = node;
+
+ nreg = OF_getprop_alloc(node, "reg", sizeof(*reg), (void **)&reg);
+ if (nreg != FHC_NREG) {
+ device_printf(dev, "can't get registers");
+ return (ENXIO);
+ }
+ for (i = 0; i < nreg; i++) {
+ off = reg[i].sbr_offset;
+ size = reg[i].sbr_size;
+ rid = 0;
+ sc->sc_memres[i] = bus_alloc_resource(dev, SYS_RES_MEMORY,
+ &rid, off, off + size - 1, size, RF_ACTIVE);
+ if (sc->sc_memres[i] == NULL)
+ panic("fhc_central_attach: can't allocate registers");
+ sc->sc_bt[i] = rman_get_bustag(sc->sc_memres[i]);
+ sc->sc_bh[i] = rman_get_bushandle(sc->sc_memres[i]);
+ }
+ free(reg, M_OFWPROP);
+ return (fhc_attach(dev));
+}
diff --git a/sys/sparc64/fhc/fhc_nexus.c b/sys/sparc64/fhc/fhc_nexus.c
new file mode 100644
index 0000000..e989b5c
--- /dev/null
+++ b/sys/sparc64/fhc/fhc_nexus.c
@@ -0,0 +1,125 @@
+/*-
+ * 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$
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/malloc.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 int fhc_nexus_probe(device_t dev);
+static int fhc_nexus_attach(device_t dev);
+
+static device_method_t fhc_nexus_methods[] = {
+ /* Device interface. */
+ DEVMETHOD(device_probe, fhc_nexus_probe),
+ DEVMETHOD(device_attach, fhc_nexus_attach),
+
+ /* Bus interface. */
+ DEVMETHOD(bus_print_child, fhc_print_child),
+ DEVMETHOD(bus_probe_nomatch, fhc_probe_nomatch),
+ DEVMETHOD(bus_read_ivar, fhc_read_ivar),
+ DEVMETHOD(bus_write_ivar, fhc_write_ivar),
+ 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, fhc_release_resource),
+ DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
+ DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
+
+ { 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");
+ 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("fhc_nexus_attach: can't allocate registers");
+ sc->sc_bt[i] = rman_get_bustag(sc->sc_memres[i]);
+ sc->sc_bh[i] = rman_get_bushandle(sc->sc_memres[i]);
+ }
+ return (fhc_attach(dev));
+}
diff --git a/sys/sparc64/fhc/fhcreg.h b/sys/sparc64/fhc/fhcreg.h
new file mode 100644
index 0000000..f8801e2
--- /dev/null
+++ b/sys/sparc64/fhc/fhcreg.h
@@ -0,0 +1,44 @@
+/*-
+ * 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_FHCREG_H_
+#define _SPARC64_FHC_FHCREG_H_
+
+#define FHC_NREG (6)
+
+#define FHC_INTERNAL (0)
+#define FHC_IGN (1)
+#define FHC_FANFAIL (2)
+#define FHC_SYSTEM (3)
+#define FHC_UART (4)
+#define FHC_TOD (5)
+
+#define FHC_IMAP 0x0
+#define FHC_ICLR 0x10
+
+#endif
diff --git a/sys/sparc64/fhc/fhcvar.h b/sys/sparc64/fhc/fhcvar.h
new file mode 100644
index 0000000..b8662df
--- /dev/null
+++ b/sys/sparc64/fhc/fhcvar.h
@@ -0,0 +1,71 @@
+/*-
+ * 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_
+
+enum fhc_device_ivars {
+ FHC_IVAR_NAME,
+ FHC_IVAR_NODE,
+ FHC_IVAR_TYPE
+};
+
+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_ign;
+};
+
+int fhc_probe(device_t dev);
+int fhc_attach(device_t dev);
+
+int fhc_print_child(device_t dev, device_t child);
+void fhc_probe_nomatch(device_t dev, device_t child);
+int fhc_read_ivar(device_t, device_t, int, uintptr_t *);
+int fhc_write_ivar(device_t, device_t, int, uintptr_t);
+int fhc_setup_intr(device_t, device_t, struct resource *, int, driver_intr_t,
+ void *, void **);
+int fhc_teardown_intr(device_t, device_t, struct resource *, void *);
+struct resource *fhc_alloc_resource(device_t, device_t, int, int *, u_long,
+ u_long, u_long, u_int);
+int fhc_release_resource(device_t, device_t, int, int, struct resource *);
+
+#define FHC_ACCESSOR(var, ivar, type) \
+ __BUS_ACCESSOR(fhc, var, FHC, ivar, type)
+
+FHC_ACCESSOR(name, NAME, char *)
+FHC_ACCESSOR(node, NODE, phandle_t)
+FHC_ACCESSOR(type, TYPE, char *)
+
+#undef FHC_ACCESSOR
+
+#endif
diff --git a/sys/sparc64/sparc64/eeprom_fhc.c b/sys/sparc64/sparc64/eeprom_fhc.c
new file mode 100644
index 0000000..2dffc9f
--- /dev/null
+++ b/sys/sparc64/sparc64/eeprom_fhc.c
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ * Copyright (c) 1994 Gordon W. Ross
+ * Copyright (c) 1993 Adam Glass
+ * Copyright (c) 1996 Paul Kranenburg
+ * Copyright (c) 1996
+ * The President and Fellows of Harvard College. All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Harvard University.
+ * This product includes software developed by the University of
+ * California, Lawrence Berkeley Laboratory.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * This product includes software developed by Paul Kranenburg.
+ * This product includes software developed by Harvard University.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ * from: @(#)clock.c 8.1 (Berkeley) 6/11/93
+ * from: NetBSD: clock.c,v 1.41 2001/07/24 19:29:25 eeh Exp
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/resource.h>
+
+#include <machine/bus.h>
+#include <machine/idprom.h>
+#include <machine/resource.h>
+
+#include <sys/rman.h>
+
+#include <ofw/openfirm.h>
+
+#include <machine/eeprom.h>
+
+#include <mk48txx/mk48txxreg.h>
+
+#include <sparc64/fhc/fhcreg.h>
+#include <sparc64/fhc/fhcvar.h>
+
+#include "clock_if.h"
+
+static int eeprom_fhc_probe(device_t);
+static int eeprom_fhc_attach(device_t);
+
+static device_method_t eeprom_fhc_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, eeprom_fhc_probe),
+ DEVMETHOD(device_attach, eeprom_fhc_attach),
+
+ /* clock interface */
+ DEVMETHOD(clock_gettime, mk48txx_gettime),
+ DEVMETHOD(clock_settime, mk48txx_settime),
+
+ { 0, 0 }
+};
+
+static driver_t eeprom_fhc_driver = {
+ "eeprom",
+ eeprom_fhc_methods,
+ 0,
+};
+
+DRIVER_MODULE(eeprom, fhc, eeprom_fhc_driver, eeprom_devclass, 0, 0);
+
+static int
+eeprom_fhc_probe(device_t dev)
+{
+
+ if (strcmp("eeprom", fhc_get_name(dev)) == 0) {
+ device_set_desc(dev, "FHC EEPROM/clock");
+ return (0);
+ }
+ return (ENXIO);
+}
+
+/*
+ * Attach a clock (really `eeprom') to the fhc.
+ *
+ * This is mapped read-only on NetBSD for safety, but this is not possible
+ * with the current FreeBSD bus code.
+ *
+ * the MK48T02 is 2K. the MK48T08 is 8K, and the MK48T59 is supposed to be
+ * identical to it.
+ */
+static int
+eeprom_fhc_attach(device_t dev)
+{
+ struct resource *res;
+ int rid, error;
+
+ rid = 0;
+ res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, 0UL, ~0UL, 1,
+ RF_ACTIVE);
+ if (res == NULL) {
+ device_printf(dev, "could not allocate resources\n");
+ return (ENXIO);
+ }
+ error = eeprom_attach(dev, fhc_get_node(dev), rman_get_bustag(res),
+ rman_get_bushandle(res));
+ return (error);
+}
OpenPOWER on IntegriCloud