summaryrefslogtreecommitdiffstats
path: root/sys/powerpc/psim
diff options
context:
space:
mode:
authorgrehan <grehan@FreeBSD.org>2002-09-19 04:57:10 +0000
committergrehan <grehan@FreeBSD.org>2002-09-19 04:57:10 +0000
commit22d2979d2dd5d80d32a308dc412a86747ca1ecee (patch)
treed8d9590f9f64d7806c566b3381c82a1bf3b3ba02 /sys/powerpc/psim
parentb9926b1f0b93d56ded1b08d95336ddc0886e1403 (diff)
downloadFreeBSD-src-22d2979d2dd5d80d32a308dc412a86747ca1ecee.zip
FreeBSD-src-22d2979d2dd5d80d32a308dc412a86747ca1ecee.tar.gz
Support files and a h/w tree description for the PSIM ppc simulator
Approved by: benno
Diffstat (limited to 'sys/powerpc/psim')
-rw-r--r--sys/powerpc/psim/ata_iobus.c244
-rw-r--r--sys/powerpc/psim/iobus.c409
-rw-r--r--sys/powerpc/psim/iobusvar.h73
-rw-r--r--sys/powerpc/psim/psim-tree74
-rw-r--r--sys/powerpc/psim/sio_iobus.c109
-rw-r--r--sys/powerpc/psim/uart_iobus.c109
6 files changed, 1018 insertions, 0 deletions
diff --git a/sys/powerpc/psim/ata_iobus.c b/sys/powerpc/psim/ata_iobus.c
new file mode 100644
index 0000000..692f618
--- /dev/null
+++ b/sys/powerpc/psim/ata_iobus.c
@@ -0,0 +1,244 @@
+/*
+ * Copyright 2002 by Peter Grehan. 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.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * PSIM local bus ATA controller
+ */
+#include "opt_ata.h"
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/disk.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <sys/bio.h>
+#include <sys/malloc.h>
+#include <sys/devicestat.h>
+#include <sys/sysctl.h>
+#include <machine/stdarg.h>
+#include <machine/resource.h>
+#include <machine/bus.h>
+#include <sys/rman.h>
+#include <dev/ata/ata-all.h>
+
+#include <dev/ofw/openfirm.h>
+#include <powerpc/psim/iobusvar.h>
+
+/*
+ * Define the iobus ata bus attachment. This creates a pseudo-bus that
+ * the ATA device can be attached to
+ */
+static int ata_iobus_attach(device_t dev);
+static int ata_iobus_probe(device_t dev);
+static int ata_iobus_print_child(device_t dev, device_t child);
+struct resource *ata_iobus_alloc_resource(device_t, device_t, int, int *,
+ u_long, u_long, u_long, u_int);
+static int ata_iobus_release_resource(device_t, device_t, int, int,
+ struct resource *);
+
+static device_method_t ata_iobus_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, ata_iobus_probe),
+ DEVMETHOD(device_attach, ata_iobus_attach),
+ DEVMETHOD(device_shutdown, bus_generic_shutdown),
+ DEVMETHOD(device_suspend, bus_generic_suspend),
+ DEVMETHOD(device_resume, bus_generic_resume),
+
+ /* Bus methods */
+ DEVMETHOD(bus_print_child, ata_iobus_print_child),
+ DEVMETHOD(bus_alloc_resource, ata_iobus_alloc_resource),
+ DEVMETHOD(bus_release_resource, ata_iobus_release_resource),
+ DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
+ DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
+ DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
+ DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
+
+ { 0, 0 }
+};
+
+static driver_t ata_iobus_driver = {
+ "ataiobus",
+ ata_iobus_methods,
+ 0,
+};
+
+static devclass_t ata_iobus_devclass;
+
+DRIVER_MODULE(ataiobus, iobus, ata_iobus_driver, ata_iobus_devclass, 0, 0);
+
+
+static int
+ata_iobus_probe(device_t dev)
+{
+ char *type = iobus_get_name(dev);
+
+ if (strncmp(type, "ata", 3) != 0)
+ return (ENXIO);
+
+ device_set_desc(dev, "PSIM ATA Controller");
+ return (0);
+}
+
+
+static int
+ata_iobus_attach(device_t dev)
+{
+ /*
+ * Add a single child per controller. Should be able
+ * to add two
+ */
+ device_add_child(dev, "ata",
+ devclass_find_free_unit(ata_devclass, 0));
+
+ return (bus_generic_attach(dev));
+}
+
+
+static int
+ata_iobus_print_child(device_t dev, device_t child)
+{
+ struct ata_channel *ch = device_get_softc(child);
+ int retval = 0;
+
+ retval += bus_print_child_header(dev, child);
+ retval += printf(": at 0x%lx", rman_get_start(ch->r_io));
+ /* irq ? */
+ retval += bus_print_child_footer(dev, child);
+
+ return (retval);
+}
+
+
+struct resource *
+ata_iobus_alloc_resource(device_t dev, device_t child, int type, int *rid,
+ u_long start, u_long end, u_long count, u_int flags)
+{
+ struct resource *res = NULL;
+ int myrid;
+ u_int *ofw_regs;
+
+ ofw_regs = iobus_get_regs(dev);
+
+ /*
+ * The reg array for the PSIM ata device has 6 start/size entries:
+ * 0 - unused
+ * 1/2/3 - unused
+ * 4/5/6 - primary command
+ * 7/8/9 - secondary command
+ * 10/11/12 - primary control
+ * 13/14/15 - secondary control
+ * 16/17/18 - primary/secondary dma registers, unimplemented
+ *
+ * The resource values are calculated from these registers
+ */
+ if (type == SYS_RES_IOPORT) {
+ switch (*rid) {
+ case ATA_IOADDR_RID:
+ myrid = 0;
+ start = ofw_regs[4];
+ end = start + ATA_IOSIZE - 1;
+ count = ATA_IOSIZE;
+ res = BUS_ALLOC_RESOURCE(device_get_parent(dev), child,
+ SYS_RES_MEMORY, &myrid,
+ start, end, count, flags);
+ break;
+
+ case ATA_ALTADDR_RID:
+ myrid = 0;
+ start = ofw_regs[10];
+ end = start + ATA_ALTIOSIZE - 1;
+ count = ATA_ALTIOSIZE;
+ res = BUS_ALLOC_RESOURCE(device_get_parent(dev), child,
+ SYS_RES_MEMORY, &myrid,
+ start, end, count, flags);
+ break;
+
+ case ATA_BMADDR_RID:
+ /* DMA not properly supported by psim */
+ break;
+ }
+ return (res);
+
+ } else if (type == SYS_RES_IRQ && *rid == ATA_IRQ_RID) {
+ /*
+ * Pass this on to the parent
+ */
+ return (BUS_ALLOC_RESOURCE(device_get_parent(dev), dev,
+ SYS_RES_IRQ, rid, 0, ~0, 1, flags));
+
+ } else {
+ return (NULL);
+ }
+}
+
+
+static int
+ata_iobus_release_resource(device_t dev, device_t child, int type, int rid,
+ struct resource *r)
+{
+ /* no hotplug... */
+ return (0);
+}
+
+
+/*
+ * Define the actual ATA device. This is a sub-bus to the ata-iobus layer
+ * to allow the higher layer bus to massage the resource allocation.
+ */
+
+static int ata_iobus_sub_probe(device_t dev);
+
+static device_method_t ata_iobus_sub_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, ata_iobus_sub_probe),
+ DEVMETHOD(device_attach, ata_attach),
+ DEVMETHOD(device_detach, ata_detach),
+ DEVMETHOD(device_resume, ata_resume),
+
+ { 0, 0 }
+};
+
+static driver_t ata_iobus_sub_driver = {
+ "ata",
+ ata_iobus_sub_methods,
+ sizeof(struct ata_channel),
+};
+
+DRIVER_MODULE(ata, ataiobus, ata_iobus_sub_driver, ata_devclass, 0, 0);
+
+static int
+ata_iobus_sub_probe(device_t dev)
+{
+ struct ata_channel *ch = device_get_softc(dev);
+
+ /* Only a single unit per controller thus far */
+ ch->unit = 0;
+
+ return ata_probe(dev);
+}
diff --git a/sys/powerpc/psim/iobus.c b/sys/powerpc/psim/iobus.c
new file mode 100644
index 0000000..3428125
--- /dev/null
+++ b/sys/powerpc/psim/iobus.c
@@ -0,0 +1,409 @@
+/*
+ * Copyright 2002 by Peter Grehan. 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.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * PSIM 'iobus' local bus. Should be set up in the device tree like:
+ *
+ * /iobus@0x80000000/name psim-iobus
+ *
+ * Code borrowed from various nexus.c and uninorth.c :-)
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/bus.h>
+#include <machine/bus.h>
+#include <sys/rman.h>
+
+#include <dev/ofw/openfirm.h>
+
+#include <machine/vmparam.h>
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <machine/pmap.h>
+
+#include <machine/resource.h>
+#include <machine/nexusvar.h>
+
+#include <powerpc/psim/iobusvar.h>
+
+static MALLOC_DEFINE(M_IOBUS, "iobus", "iobus device information");
+
+static int iobus_probe(device_t);
+static int iobus_attach(device_t);
+static int iobus_print_child(device_t dev, device_t child);
+static void iobus_probe_nomatch(device_t, device_t);
+static int iobus_read_ivar(device_t, device_t, int, uintptr_t *);
+static int iobus_write_ivar(device_t, device_t, int, uintptr_t);
+static struct resource *iobus_alloc_resource(device_t, device_t, int, int *,
+ u_long, u_long, u_long, u_int);
+static int iobus_activate_resource(device_t, device_t, int, int,
+ struct resource *);
+static int iobus_deactivate_resource(device_t, device_t, int, int,
+ struct resource *);
+static int iobus_release_resource(device_t, device_t, int, int,
+ struct resource *);
+
+/*
+ * Bus interface definition
+ */
+static device_method_t iobus_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, iobus_probe),
+ DEVMETHOD(device_attach, iobus_attach),
+ DEVMETHOD(device_detach, bus_generic_detach),
+ DEVMETHOD(device_shutdown, bus_generic_shutdown),
+ DEVMETHOD(device_suspend, bus_generic_suspend),
+ DEVMETHOD(device_resume, bus_generic_resume),
+
+ /* Bus interface */
+ DEVMETHOD(bus_print_child, iobus_print_child),
+ DEVMETHOD(bus_probe_nomatch, iobus_probe_nomatch),
+ DEVMETHOD(bus_read_ivar, iobus_read_ivar),
+ DEVMETHOD(bus_write_ivar, iobus_write_ivar),
+ DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
+ DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
+
+ DEVMETHOD(bus_alloc_resource, iobus_alloc_resource),
+ DEVMETHOD(bus_release_resource, iobus_release_resource),
+ DEVMETHOD(bus_activate_resource, iobus_activate_resource),
+ DEVMETHOD(bus_deactivate_resource, iobus_deactivate_resource),
+
+ { 0, 0 }
+};
+
+static driver_t iobus_driver = {
+ "iobus",
+ iobus_methods,
+ sizeof(struct iobus_softc)
+};
+
+devclass_t iobus_devclass;
+
+DRIVER_MODULE(iobus, nexus, iobus_driver, iobus_devclass, 0, 0);
+
+static int
+iobus_probe(device_t dev)
+{
+ char *type = nexus_get_name(dev);
+
+ if (strcmp(type, "psim-iobus") != 0)
+ return (ENXIO);
+
+ device_set_desc(dev, "PSIM local bus");
+ return (0);
+}
+
+/*
+ * Add interrupt/addr range to the dev's resource list if present
+ */
+static void
+iobus_add_intr(phandle_t devnode, struct iobus_devinfo *dinfo)
+{
+ u_int intr = -1;
+
+ if (OF_getprop(devnode, "interrupt", &intr, sizeof(intr)) != -1) {
+ resource_list_add(&dinfo->id_resources,
+ SYS_RES_IRQ, 0, intr, intr, 1);
+ }
+ dinfo->id_interrupt = intr;
+}
+
+
+static void
+iobus_add_reg(phandle_t devnode, struct iobus_devinfo *dinfo,
+ vm_offset_t iobus_off)
+{
+ u_int size;
+ int i;
+
+ size = OF_getprop(devnode, "reg", dinfo->id_reg,sizeof(dinfo->id_reg));
+
+ if (size != -1) {
+ dinfo->id_nregs = size / (sizeof(dinfo->id_reg[0]));
+
+ for (i = 0; i < dinfo->id_nregs; i+= 3) {
+ /*
+ * Scale the absolute addresses back to iobus
+ * relative offsets. This is to better simulate
+ * macio
+ */
+ dinfo->id_reg[i+1] -= iobus_off;
+
+ resource_list_add(&dinfo->id_resources,
+ SYS_RES_MEMORY, 0,
+ dinfo->id_reg[i+1],
+ dinfo->id_reg[i+1] +
+ dinfo->id_reg[i+2],
+ dinfo->id_reg[i+2]);
+ }
+ }
+}
+
+
+static int
+iobus_attach(device_t dev)
+{
+ struct iobus_softc *sc;
+ struct iobus_devinfo *dinfo;
+ phandle_t root;
+ phandle_t child;
+ device_t cdev;
+ char *name;
+ u_int reg[2];
+ int size;
+
+ sc = device_get_softc(dev);
+ sc->sc_node = nexus_get_node(dev);
+
+ /*
+ * Find the base addr/size of the iobus, and initialize the
+ * resource manager
+ */
+ size = OF_getprop(sc->sc_node, "reg", reg, sizeof(reg));
+ if (size == sizeof(reg)) {
+ sc->sc_addr = reg[0];
+ sc->sc_size = reg[1];
+ } else {
+ return (ENXIO);
+ }
+
+ sc->sc_mem_rman.rm_type = RMAN_ARRAY;
+ sc->sc_mem_rman.rm_descr = "IOBus Device Memory";
+ if (rman_init(&sc->sc_mem_rman) != 0) {
+ device_printf(dev,
+ "failed to init mem range resources\n");
+ return (ENXIO);
+ }
+ rman_manage_region(&sc->sc_mem_rman, 0, sc->sc_size);
+
+ /*
+ * Iterate through the sub-devices
+ */
+ root = sc->sc_node;
+
+ for (child = OF_child(root); child != 0; child = OF_peer(child)) {
+ OF_getprop_alloc(child, "name", 1, (void **)&name);
+
+ cdev = device_add_child(dev, NULL, -1);
+ if (cdev != NULL) {
+ dinfo = malloc(sizeof(*dinfo), M_IOBUS, M_WAITOK);
+ memset(dinfo, 0, sizeof(*dinfo));
+ resource_list_init(&dinfo->id_resources);
+ dinfo->id_node = child;
+ dinfo->id_name = name;
+ iobus_add_intr(child, dinfo);
+ iobus_add_reg(child, dinfo, sc->sc_addr);
+ device_set_ivars(cdev, dinfo);
+ } else {
+ free(name, M_OFWPROP);
+ }
+ }
+
+ return (bus_generic_attach(dev));
+}
+
+
+static int
+iobus_print_child(device_t dev, device_t child)
+{
+ struct iobus_devinfo *dinfo;
+ struct resource_list *rl;
+ int retval = 0;
+
+ dinfo = device_get_ivars(child);
+ rl = &dinfo->id_resources;
+
+ retval += bus_print_child_header(dev, child);
+
+ retval += printf(" offset 0x%x", dinfo->id_reg[1]);
+ retval += resource_list_print_type(rl, "irq", SYS_RES_IRQ, "%ld");
+
+ retval += bus_print_child_footer(dev, child);
+
+ return (retval);
+}
+
+
+static void
+iobus_probe_nomatch(device_t dev, device_t child)
+{
+}
+
+
+static int
+iobus_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
+{
+ struct iobus_devinfo *dinfo;
+
+ if ((dinfo = device_get_ivars(child)) == 0)
+ return (ENOENT);
+
+ switch (which) {
+ case IOBUS_IVAR_NODE:
+ *result = dinfo->id_node;
+ break;
+ case IOBUS_IVAR_NAME:
+ *result = (uintptr_t)dinfo->id_name;
+ break;
+ case IOBUS_IVAR_NREGS:
+ *result = dinfo->id_nregs;
+ break;
+ case IOBUS_IVAR_REGS:
+ *result = (uintptr_t)dinfo->id_reg;
+ break;
+ default:
+ return (ENOENT);
+ }
+
+ return (0);
+}
+
+
+static int
+iobus_write_ivar(device_t dev, device_t child, int which, uintptr_t value)
+{
+ return (EINVAL);
+}
+
+
+static struct resource *
+iobus_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 iobus_softc *sc;
+ int needactivate;
+ struct resource *rv;
+ struct rman *rm;
+ bus_space_tag_t tagval;
+
+ sc = device_get_softc(bus);
+
+ needactivate = flags & RF_ACTIVE;
+ flags &= ~RF_ACTIVE;
+
+ switch (type) {
+ case SYS_RES_MEMORY:
+ case SYS_RES_IOPORT:
+ rm = &sc->sc_mem_rman;
+ tagval = PPC_BUS_SPACE_MEM;
+ if (flags & PPC_BUS_SPARSE4)
+ tagval |= 4;
+ break;
+ case SYS_RES_IRQ:
+ return (bus_alloc_resource(bus, type, rid, start, end, count,
+ flags));
+ break;
+ default:
+ device_printf(bus, "unknown resource request from %s\n",
+ device_get_nameunit(child));
+ return (NULL);
+ }
+
+ rv = rman_reserve_resource(rm, start, end, count, flags, child);
+ if (rv == NULL) {
+ device_printf(bus, "failed to reserve resource for %s\n",
+ device_get_nameunit(child));
+ return (NULL);
+ }
+
+ rman_set_bustag(rv, tagval);
+ rman_set_bushandle(rv, rman_get_start(rv));
+
+ if (needactivate) {
+ if (bus_activate_resource(child, type, *rid, rv) != 0) {
+ device_printf(bus,
+ "failed to activate resource for %s\n",
+ device_get_nameunit(child));
+ rman_release_resource(rv);
+ return (NULL);
+ }
+ }
+
+ return (rv);
+}
+
+
+static int
+iobus_release_resource(device_t bus, device_t child, int type, int rid,
+ struct resource *res)
+{
+ if (rman_get_flags(res) & RF_ACTIVE) {
+ int error = bus_deactivate_resource(child, type, rid, res);
+ if (error)
+ return error;
+ }
+
+ return (rman_release_resource(res));
+}
+
+
+static int
+iobus_activate_resource(device_t bus, device_t child, int type, int rid,
+ struct resource *res)
+{
+ struct iobus_softc *sc;
+ void *p;
+
+ sc = device_get_softc(bus);
+
+ if (type == SYS_RES_IRQ)
+ return (bus_activate_resource(bus, type, rid, res));
+
+ if ((type == SYS_RES_MEMORY) || (type == SYS_RES_IOPORT)) {
+ p = pmap_mapdev((vm_offset_t)rman_get_start(res) + sc->sc_addr,
+ (vm_size_t)rman_get_size(res));
+ if (p == NULL)
+ return (ENOMEM);
+ rman_set_virtual(res, p);
+ rman_set_bushandle(res, (u_long)p);
+ }
+
+ return (rman_activate_resource(res));
+}
+
+
+static int
+iobus_deactivate_resource(device_t bus, device_t child, int type, int rid,
+ struct resource *res)
+{
+ /*
+ * If this is a memory resource, unmap it.
+ */
+ if ((type == SYS_RES_MEMORY) || (type == SYS_RES_IOPORT)) {
+ u_int32_t psize;
+
+ psize = rman_get_size(res);
+ pmap_unmapdev((vm_offset_t)rman_get_virtual(res), psize);
+ }
+
+ return (rman_deactivate_resource(res));
+}
diff --git a/sys/powerpc/psim/iobusvar.h b/sys/powerpc/psim/iobusvar.h
new file mode 100644
index 0000000..3862c64
--- /dev/null
+++ b/sys/powerpc/psim/iobusvar.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2002 by Peter Grehan. 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.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _PSIM_IOBUSVAR_H_
+#define _PSIM_IOBUSVAR_H_
+
+/*
+ * Accessors for iobus devices
+ */
+
+enum iobus_ivars {
+ IOBUS_IVAR_NODE,
+ IOBUS_IVAR_NAME,
+ IOBUS_IVAR_NREGS,
+ IOBUS_IVAR_REGS,
+};
+
+#define IOBUS_ACCESSOR(var, ivar, type) \
+ __BUS_ACCESSOR(iobus, var, IOBUS, ivar, type)
+
+IOBUS_ACCESSOR(node, NODE, phandle_t)
+IOBUS_ACCESSOR(name, NAME, char *)
+IOBUS_ACCESSOR(nregs, NREGS, u_int)
+IOBUS_ACCESSOR(regs, REGS, u_int *)
+
+#undef IOBUS_ACCESSOR
+
+/*
+ * Per-device structure.
+ */
+struct iobus_devinfo {
+ phandle_t id_node;
+ char *id_name;
+ int id_interrupt;
+ u_int id_nregs;
+ u_int id_reg[24];
+ struct resource_list id_resources;
+};
+
+struct iobus_softc {
+ phandle_t sc_node;
+ vm_offset_t sc_addr;
+ vm_offset_t sc_size;
+ struct rman sc_mem_rman;
+};
+
+#endif /* _PSIM_IOBUSVAR_H_ */
diff --git a/sys/powerpc/psim/psim-tree b/sys/powerpc/psim/psim-tree
new file mode 100644
index 0000000..6e038d4
--- /dev/null
+++ b/sys/powerpc/psim/psim-tree
@@ -0,0 +1,74 @@
+# $FreeBSD$
+#
+# Simple psim h/w description
+#
+
+/#address-cells 1
+/openprom/options/use-stdio? false
+#/openprom/options/strict-alignment? true
+
+#
+# CPU definition. The phandle property is to help nexus.c locate the
+# interrupt controller.
+#
+/cpus/cpu@0
+
+#
+# disk file, done via phb crap. maybe there's a better way.
+#
+/phb@0x70000000
+ ./device_type "pci
+ ./name "pci
+ ./#address-cells 3
+ ./#size-cells 2
+ ./ranges ni0,0,0,0 0xc0000000 0x10000
+
+/phb@0x70000000/ide@1
+ ./device_type "ide
+ ./name "ide
+ ./assigned-addresses \
+ ni0,0,10,1f0 8 \
+ ni0,0,14,3f8 8 \
+ ni0,0,18,170 8 \
+ ni0,0,1c,378 8 \
+ ni0,0,20,200 8
+ ./reg \
+ 1 0 \
+ i0,0,10,0 8 \
+ i0,0,18,0 8 \
+ i0,0,14,6 1 \
+ i0,0,1c,6 1 \
+ i0,0,20,0 8
+ ./ready-delay 1000
+
+/phb@0x70000000/ide@1/disk@0/file "PPC.IMG
+
+#
+# I/O Bus
+#
+/iobus@0x80000000
+ ./name psim-iobus
+ ./reg 0x80000000 0x20000000
+
+#
+# OpenPIC
+#
+/iobus@0x80000000/opic@0x80000000
+ ./name interrupt-controller
+ ./device_type open-pic
+ ./compatible psim,open-pic
+ ./reg 0x80000000 0x40000
+ ./interrupt-ranges 0 256
+
+/iobus/opic > intr0 int /cpus/cpu@0x0
+
+#
+# IDE1
+#
+#/iobus@0x80000000/ide@0x80052000
+# ./name ata-4
+# ./ioport 1
+# ./device_type ata
+# ./interrupt 12
+# ./reg 0x80052000 8 0x80052010 8 0x80052020 8 0x80052030 1 0x80052040 1 0x80052050 8
+#/iobus@0x80000000/ide@0x80052000 > a irq12 /iobus/opic
diff --git a/sys/powerpc/psim/sio_iobus.c b/sys/powerpc/psim/sio_iobus.c
new file mode 100644
index 0000000..f2174ae
--- /dev/null
+++ b/sys/powerpc/psim/sio_iobus.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2002 by Peter Grehan. 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.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * PSIM local bus 16550
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/conf.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/mutex.h>
+#include <sys/module.h>
+#include <sys/tty.h>
+#include <machine/bus_pio.h>
+#include <machine/bus.h>
+#include <sys/timepps.h>
+
+#include <dev/ofw/openfirm.h>
+#include <powerpc/psim/iobusvar.h>
+
+#include <dev/sio/sioreg.h>
+#include <dev/sio/siovar.h>
+
+#include <isa/isavar.h> /* for isa_irq_pending() prototype */
+
+static int sio_iobus_attach(device_t dev);
+static int sio_iobus_probe(device_t dev);
+
+static device_method_t sio_iobus_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, sio_iobus_probe),
+ DEVMETHOD(device_attach, sio_iobus_attach),
+
+ { 0, 0 }
+};
+
+static driver_t sio_iobus_driver = {
+ sio_driver_name,
+ sio_iobus_methods,
+ 0,
+};
+
+static int
+sio_iobus_attach(device_t dev)
+{
+ return (sioattach(dev, 0, DEFAULT_RCLK));
+}
+
+static int
+sio_iobus_probe(device_t dev)
+{
+ char *type = iobus_get_name(dev);
+
+ if (strncmp(type, "com", 3) != 0)
+ return (ENXIO);
+
+
+ device_set_desc(dev, "PSIM serial port");
+
+ /*
+ * Call sioprobe with noprobe=1, to avoid hitting a psim bug
+ */
+ return (sioprobe(dev, 0, 0, 1));
+}
+
+DRIVER_MODULE(sio, iobus, sio_iobus_driver, sio_devclass, 0, 0);
+
+/*
+ * Stub function. Perhaps a way to get this to work correctly would
+ * be for child devices to set a field in the dev structure to
+ * inform the parent that they are isa devices, and then use a
+ * intr_pending() call which would propagate up to nexus to see
+ * if the interrupt controller had any intrs in the isa group set
+ */
+intrmask_t
+isa_irq_pending(void)
+{
+ return (0);
+}
diff --git a/sys/powerpc/psim/uart_iobus.c b/sys/powerpc/psim/uart_iobus.c
new file mode 100644
index 0000000..f2174ae
--- /dev/null
+++ b/sys/powerpc/psim/uart_iobus.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2002 by Peter Grehan. 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.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * PSIM local bus 16550
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/conf.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/mutex.h>
+#include <sys/module.h>
+#include <sys/tty.h>
+#include <machine/bus_pio.h>
+#include <machine/bus.h>
+#include <sys/timepps.h>
+
+#include <dev/ofw/openfirm.h>
+#include <powerpc/psim/iobusvar.h>
+
+#include <dev/sio/sioreg.h>
+#include <dev/sio/siovar.h>
+
+#include <isa/isavar.h> /* for isa_irq_pending() prototype */
+
+static int sio_iobus_attach(device_t dev);
+static int sio_iobus_probe(device_t dev);
+
+static device_method_t sio_iobus_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, sio_iobus_probe),
+ DEVMETHOD(device_attach, sio_iobus_attach),
+
+ { 0, 0 }
+};
+
+static driver_t sio_iobus_driver = {
+ sio_driver_name,
+ sio_iobus_methods,
+ 0,
+};
+
+static int
+sio_iobus_attach(device_t dev)
+{
+ return (sioattach(dev, 0, DEFAULT_RCLK));
+}
+
+static int
+sio_iobus_probe(device_t dev)
+{
+ char *type = iobus_get_name(dev);
+
+ if (strncmp(type, "com", 3) != 0)
+ return (ENXIO);
+
+
+ device_set_desc(dev, "PSIM serial port");
+
+ /*
+ * Call sioprobe with noprobe=1, to avoid hitting a psim bug
+ */
+ return (sioprobe(dev, 0, 0, 1));
+}
+
+DRIVER_MODULE(sio, iobus, sio_iobus_driver, sio_devclass, 0, 0);
+
+/*
+ * Stub function. Perhaps a way to get this to work correctly would
+ * be for child devices to set a field in the dev structure to
+ * inform the parent that they are isa devices, and then use a
+ * intr_pending() call which would propagate up to nexus to see
+ * if the interrupt controller had any intrs in the isa group set
+ */
+intrmask_t
+isa_irq_pending(void)
+{
+ return (0);
+}
OpenPOWER on IntegriCloud