diff --git a/sys/conf/files.sparc64 b/sys/conf/files.sparc64 index 681933b5c90d..8b16895812f0 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 000000000000..e3f364d6ee0b --- /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 +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include + +#include +#include +#include + +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 000000000000..a3b03c611e7e --- /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 000000000000..829e21ce5f00 --- /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 +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include + +#include +#include +#include + +#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 **)®); + 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 000000000000..a1daee9bbe49 --- /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 +#include +#include +#include +#include + +#include + +#include +#include + +#include + +#include +#include +#include +#include + +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 **)®); + 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 000000000000..e989b5c6419d --- /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 +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include + +#include +#include + +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 000000000000..f8801e2e7d5c --- /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 000000000000..b8662dfcf7b4 --- /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 000000000000..2dffc9f9c49c --- /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 +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include + +#include + +#include + +#include +#include + +#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); +}