On Fri, Apr 08, 2016 at 09:38:25PM +0200, Mark Kettenis wrote:
> > Date: Fri, 8 Apr 2016 20:26:14 +0200
> > From: Patrick Wildt <[email protected]>
> >
> > +void
> > +mainbus_iterate(struct device *self, struct device *match, int node)
> > +{
> > + for (;
> > + node != 0;
> > + node = OF_peer(node))
> > + {
> > + /* skip nodes that are already handled by some driver */
> > + if (!mainbus_is_attached(node))
> > + mainbus_attach_node(self, match, node);
> > +
> > + mainbus_iterate(self, match, OF_child(node));
> > + }
> > +}
>
> Sorry, but this really is wrong. You're completely ignoring the tree
> aspect if the FDT. That is not going to work for more complex designs
> with i2c busses or pci busses. And it is going to be essential if you
> want to support suspend/resume.
>
> The autoconf framework is really quite clever and flexible. It is
> possible to re-use glue code quite easily. As files.conf(5)
> documents, device don't directly attach to parents, but to attributes.
> You can re-use those attributes, and parents can define multiple
> attributes.
>
> You could for example define a generic fdt attribute. Simple devices
> can then attach directly to that attribute. And you could also have
> some soc-specific attributes, that you then use to attach devices that
> need some additional glue.
>
> It'll take a bit of time to figure out the best way to define your
> attributes. But the end result will be worth it. And don't be afraid
> to make mistakes. As long as you drivers use the same "attach_args"
> structure, we can move around attributes without the need to change
> the code. So it will be easy to adjust the design as we learn more.
>
> Cheers,
>
> Mark
>
I have created an attribute called ofwbus and made mainbus depend on
that tag. Now devices can attach to mainbus or ofwbus. I added a
simplebus which does about the same as mainbus. Using simplebus* at
ofwbus? it should allow attaching a simplebus to a simplebus, thus
creating tree-like-attachment. I guess this is more like the approach
you had in mind?
diff --git sys/arch/arm/conf/files.arm sys/arch/arm/conf/files.arm
index cb11960..7ecdd06 100644
--- sys/arch/arm/conf/files.arm
+++ sys/arch/arm/conf/files.arm
@@ -16,15 +16,24 @@ file arch/arm/arm/disassem.c ddb
file arch/arm/arm/fiq.c fiq
file arch/arm/arm/fiq_subr.S fiq
+define ofwbus {}
+
# mainbus files
-device mainbus {}
+device mainbus: ofwbus
attach mainbus at root
file arch/arm/mainbus/mainbus.c mainbus
+device simplebus: ofwbus
+attach simplebus at ofwbus
+file arch/arm/simplebus/simplebus.c simplebus
+
+# FDT support
+file dev/ofw/fdt.c
+
include "arch/arm/cortex/files.cortex"
device cpu {}
-attach cpu at mainbus with cpu_mainbus
+attach cpu at ofwbus with cpu_mainbus
file arch/arm/mainbus/cpu_mainbus.c cpu_mainbus
diff --git sys/arch/arm/cortex/files.cortex sys/arch/arm/cortex/files.cortex
index c0f4359..f6f1852 100644
--- sys/arch/arm/cortex/files.cortex
+++ sys/arch/arm/cortex/files.cortex
@@ -2,7 +2,7 @@
# ARM core
device cortex {}
-attach cortex at mainbus
+attach cortex at ofwbus
file arch/arm/cortex/cortex.c cortex
device ampintc
diff --git sys/arch/arm/mainbus/mainbus.c sys/arch/arm/mainbus/mainbus.c
index 6ad3e8f..2c083fc 100644
--- sys/arch/arm/mainbus/mainbus.c
+++ sys/arch/arm/mainbus/mainbus.c
@@ -1,124 +1,251 @@
-/* $OpenBSD: mainbus.c,v 1.7 2013/05/30 16:15:01 deraadt Exp $ */
-/* $NetBSD: mainbus.c,v 1.3 2001/06/13 17:52:43 nathanw Exp $ */
-
+/* $OpenBSD$ */
/*
- * Copyright (c) 1994,1995 Mark Brinicombe.
- * Copyright (c) 1994 Brini.
- * 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. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Brini.
- * 4. The name of the company nor the name of the author may be used to
- * endorse or promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY BRINI ``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 BRINI 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.
- *
- * RiscBSD kernel project
+ * Copyright (c) 2016 Patrick Wildt <[email protected]>
*
- * mainbus.c
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
*
- * mainbus configuration
- *
- * Created : 15/12/94
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/param.h>
#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/device.h>
+#include <sys/malloc.h>
+#include <sys/queue.h>
+
+#include <dev/ofw/openfirm.h>
#include <arm/mainbus/mainbus.h>
-/* Prototypes for functions provided */
+int mainbus_match(struct device *, void *, void *);
+void mainbus_attach(struct device *, struct device *, void *);
+
+struct device *mainbus_is_attached(int);
+void mainbus_dev_list_insert(int, struct device *);
-int mainbusmatch(struct device *, void *, void *);
-void mainbusattach(struct device *, struct device *, void *);
-int mainbusprint(void *aux, const char *mainbus);
-int mainbussearch(struct device *, void *, void *);
+void mainbus_find_match(struct device *, void *);
+void mainbus_attach_node(struct device *, void *, int);
-/* attach and device structures for the device */
+int mainbus_legacy_search(struct device *, void *, void *);
+void mainbus_legacy_found(struct device *, char *);
+
+struct mainbus_softc {
+ struct device sc_dev;
+ int sc_node;
+ bus_space_tag_t sc_iot;
+ bus_dma_tag_t sc_dmat;
+};
+
+/*
+ * We need to look through the tree at least twice. To make sure we
+ * do not attach node multiple times, keep a list of nodes that are
+ * already handled by any kind of driver.
+ */
+SLIST_HEAD(, mainbus_entry) mainbus_dev_list =
SLIST_HEAD_INITIALIZER(mainbus_dev_list);
+struct mainbus_entry {
+ SLIST_ENTRY(mainbus_entry) me_list;
+ int me_node;
+ struct device *me_dev;
+};
+
+struct device *
+mainbus_is_attached(int node)
+{
+ struct mainbus_entry *me;
+
+ SLIST_FOREACH(me, &mainbus_dev_list, me_list)
+ if (me->me_node == node)
+ return me->me_dev;
+
+ return NULL;
+}
+
+void
+mainbus_dev_list_insert(int node, struct device *child)
+{
+ struct mainbus_entry *me;
+
+ if (child == NULL)
+ return;
+
+ me = malloc(sizeof(*me), M_DEVBUF, M_NOWAIT|M_ZERO);
+ if (me == NULL)
+ panic("%s: cannot allocate memory", __func__);
+
+ me->me_node = node;
+ me->me_dev = child;
+ SLIST_INSERT_HEAD(&mainbus_dev_list, me, me_list);
+}
struct cfattach mainbus_ca = {
- sizeof(struct device), mainbusmatch, mainbusattach
+ sizeof(struct mainbus_softc), mainbus_match, mainbus_attach, NULL,
+ config_activate_children
};
struct cfdriver mainbus_cd = {
NULL, "mainbus", DV_DULL
};
+struct arm32_bus_dma_tag mainbus_dma_tag = {
+ 0,
+ 0,
+ NULL,
+ _bus_dmamap_create,
+ _bus_dmamap_destroy,
+ _bus_dmamap_load,
+ _bus_dmamap_load_mbuf,
+ _bus_dmamap_load_uio,
+ _bus_dmamap_load_raw,
+ _bus_dmamap_unload,
+ _bus_dmamap_sync,
+ _bus_dmamem_alloc,
+ _bus_dmamem_free,
+ _bus_dmamem_map,
+ _bus_dmamem_unmap,
+ _bus_dmamem_mmap,
+};
+
/*
- * int mainbusmatch(struct device *parent, struct cfdata *cf, void *aux)
+ * Mainbus takes care of FDT and non-FDT machines, so we
+ * always attach.
*/
-
int
-mainbusmatch(struct device *parent, void *cf, void *aux)
+mainbus_match(struct device *parent, void *cfdata, void *aux)
{
return (1);
}
+void
+mainbus_attach(struct device *parent, struct device *self, void *aux)
+{
+ struct mainbus_softc *sc = (struct mainbus_softc *)self;
+ char buffer[128];
+ int node;
+
+ if ((node = OF_peer(0)) == 0) {
+ printf(": running without device tree\n");
+ config_search(mainbus_legacy_search, self, aux);
+ return;
+ }
+
+ sc->sc_node = OF_peer(0);
+#ifdef CPU_ARMv7
+ extern struct bus_space armv7_bs_tag;
+ sc->sc_iot = &armv7_bs_tag;
+#endif
+ sc->sc_dmat = &mainbus_dma_tag;
+
+ if (OF_getprop(node, "compatible", buffer, sizeof(buffer)))
+ printf(": %s compatible\n", buffer);
+ else
+ printf(": unknown\n");
+
+ /* Attach CPU first. */
+ mainbus_legacy_found(self, "cpu");
+
+ /* TODO: Cortex clients should connect to FDT. */
+ mainbus_legacy_found(self, "cortex");
+
+ /* TODO: Scan for interrupt controllers and attach them first? */
+
+ /* Scan the whole tree. */
+ config_scan(mainbus_find_match, self);
+}
+
/*
- * void mainbusattach(struct device *parent, struct device *self, void *aux)
+ * Usually you should be able to attach devices in the order
+ * specified in the device tree. Due to how a few drivers
+ * are written we need to make sure we attach them in the
+ * order stated in files.xxx.
*
- * probe and attach all children
+ * This means for every driver enabled, we go through the
+ * FDT and look for compatible nodes.
*/
+void
+mainbus_find_match(struct device *self, void *match)
+{
+ struct mainbus_softc *sc = (struct mainbus_softc *)self;
+ int node;
+
+ for (node = OF_child(sc->sc_node);
+ node != 0;
+ node = OF_peer(node))
+ {
+ /* skip nodes that are already handled by some driver */
+ if (!mainbus_is_attached(node))
+ mainbus_attach_node(self, match, node);
+ }
+}
+/*
+ * Try to attach a node to a known driver.
+ */
void
-mainbusattach(struct device *parent, struct device *self, void *aux)
+mainbus_attach_node(struct device *self, void *match, int node)
{
- printf("\n");
+ struct mainbus_softc *sc = (struct mainbus_softc *)self;
+ struct mainbus_attach_args ma;
+ struct cfdata *cf = match;
+ struct device *child;
+ char buffer[128];
+
+ if (!OF_getprop(node, "compatible", buffer, sizeof(buffer)))
+ return;
+
+ if (OF_getprop(node, "status", buffer, sizeof(buffer)))
+ if (!strcmp(buffer, "disabled"))
+ return;
- config_search(mainbussearch, self, aux);
+ memset(&ma, 0, sizeof(ma));
+ ma.ma_name = "";
+ ma.ma_node = node;
+ ma.ma_iot = sc->sc_iot;
+ ma.ma_dmat = sc->sc_dmat;
+
+ /* allow for devices to be disabled in UKC */
+ if ((*cf->cf_attach->ca_match)(self, cf, &ma) == 0)
+ return;
+
+ /* TODO: attach the device's clocks first? */
+
+ child = config_attach(self, cf, &ma, NULL);
+ mainbus_dev_list_insert(node, child);
}
+/*
+ * Legacy support for SoCs that do not use FDT.
+ */
int
-mainbussearch(struct device *parent, void *vcf, void *aux)
+mainbus_legacy_search(struct device *parent, void *match, void *aux)
{
struct mainbus_attach_args ma;
- struct cfdata *cf = vcf;
+ struct cfdata *cf = match;
+ memset(&ma, 0, sizeof(ma));
ma.ma_name = cf->cf_driver->cd_name;
/* allow for devices to be disabled in UKC */
if ((*cf->cf_attach->ca_match)(parent, cf, &ma) == 0)
return 0;
- config_attach(parent, cf, &ma, mainbusprint);
+ config_attach(parent, cf, &ma, NULL);
return 1;
}
-/*
- * int mainbusprint(void *aux, const char *mainbus)
- *
- * print routine used during config of children
- */
-
-int
-mainbusprint(void *aux, const char *mainbus)
+void
+mainbus_legacy_found(struct device *self, char *name)
{
- struct mainbus_attach_args *ma = aux;
+ struct mainbus_attach_args ma;
- if (mainbus != NULL)
- printf("%s at %s", ma->ma_name, mainbus);
+ memset(&ma, 0, sizeof(ma));
+ ma.ma_name = name;
- return (UNCONF);
+ config_found(self, &ma, NULL);
}
diff --git sys/arch/arm/mainbus/mainbus.h sys/arch/arm/mainbus/mainbus.h
index 3e17996..b2dfbcc 100644
--- sys/arch/arm/mainbus/mainbus.h
+++ sys/arch/arm/mainbus/mainbus.h
@@ -1,51 +1,32 @@
-/* $OpenBSD: mainbus.h,v 1.2 2011/09/22 17:45:59 miod Exp $ */
-/* $NetBSD: mainbus.h,v 1.1 2001/02/24 19:38:02 reinoud Exp $ */
-
+/* $OpenBSD$ */
/*
- * Copyright (c) 1994,1995 Mark Brinicombe.
- * Copyright (c) 1994 Brini.
- * 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. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Brini.
- * 4. The name of the company nor the name of the author may be used to
- * endorse or promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY BRINI ``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 BRINI 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.
- *
- * RiscBSD kernel project
- *
- * mainbus.h
+ * Copyright (c) 2016 Patrick Wildt <[email protected]>
*
- * mainbus configuration
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
*
- * Created : 15/12/94
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/*
- * mainbus driver attach arguments
- */
+#ifndef __MAINBUS_H__
+#define __MAINBUS_H__
+#define _ARM32_BUS_DMA_PRIVATE
+#include <machine/bus.h>
+
+/* Passed as third arg to attach functions. */
struct mainbus_attach_args {
- const char *ma_name;
+ const char *ma_name;
+ int ma_node;
+ bus_space_tag_t ma_iot;
+ bus_dma_tag_t ma_dmat;
};
+
+#endif /* __MAINBUS_H__ */
diff --git sys/arch/arm/simplebus/simplebus.c sys/arch/arm/simplebus/simplebus.c
new file mode 100644
index 0000000..5de9d7d
--- /dev/null
+++ sys/arch/arm/simplebus/simplebus.c
@@ -0,0 +1,196 @@
+/* $OpenBSD$ */
+/*
+ * Copyright (c) 2016 Patrick Wildt <[email protected]>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/queue.h>
+
+#include <dev/ofw/openfirm.h>
+
+#include <arm/mainbus/mainbus.h>
+#include <arm/simplebus/simplebus.h>
+
+int simplebus_match(struct device *, void *, void *);
+void simplebus_attach(struct device *, struct device *, void *);
+
+struct device *simplebus_is_attached(int);
+void simplebus_dev_list_insert(int, struct device *);
+
+void simplebus_find_match(struct device *, void *);
+void simplebus_attach_node(struct device *, void *, int);
+
+struct simplebus_softc {
+ struct device sc_dev;
+ int sc_node;
+ bus_space_tag_t sc_iot;
+ bus_dma_tag_t sc_dmat;
+};
+
+/*
+ * We need to look through the tree at least twice. To make sure we
+ * do not attach node multiple times, keep a list of nodes that are
+ * already handled by any kind of driver.
+ */
+SLIST_HEAD(, simplebus_entry) simplebus_dev_list =
SLIST_HEAD_INITIALIZER(simplebus_dev_list);
+struct simplebus_entry {
+ SLIST_ENTRY(simplebus_entry) se_list;
+ int se_node;
+ struct device *se_dev;
+};
+
+struct device *
+simplebus_is_attached(int node)
+{
+ struct simplebus_entry *se;
+
+ SLIST_FOREACH(se, &simplebus_dev_list, se_list)
+ if (se->se_node == node)
+ return se->se_dev;
+
+ return NULL;
+}
+
+void
+simplebus_dev_list_insert(int node, struct device *child)
+{
+ struct simplebus_entry *se;
+
+ if (child == NULL)
+ return;
+
+ se = malloc(sizeof(*se), M_DEVBUF, M_NOWAIT|M_ZERO);
+ if (se == NULL)
+ panic("%s: cannot allocate memory", __func__);
+
+ se->se_node = node;
+ se->se_dev = child;
+ SLIST_INSERT_HEAD(&simplebus_dev_list, se, se_list);
+}
+
+struct cfattach simplebus_ca = {
+ sizeof(struct simplebus_softc), simplebus_match, simplebus_attach, NULL,
+ config_activate_children
+};
+
+struct cfdriver simplebus_cd = {
+ NULL, "simplebus", DV_DULL
+};
+
+/*
+ * Mainbus takes care of FDT and non-FDT machines, so we
+ * always attach.
+ */
+int
+simplebus_match(struct device *parent, void *cfdata, void *aux)
+{
+ struct mainbus_attach_args *ma = (struct mainbus_attach_args *)aux;
+ char buffer[128];
+
+ if (ma->ma_node == 0)
+ return (0);
+
+ if (!OF_getprop(ma->ma_node, "compatible", buffer,
+ sizeof(buffer)))
+ return (0);
+
+ if (strcmp(buffer, "simple-bus"))
+ return (0);
+
+ return (1);
+}
+
+void
+simplebus_attach(struct device *parent, struct device *self, void *aux)
+{
+ struct simplebus_softc *sc = (struct simplebus_softc *)self;
+ struct mainbus_attach_args *ma = (struct mainbus_attach_args *)aux;
+ char buffer[128];
+
+ sc->sc_node = ma->ma_node;
+ sc->sc_iot = ma->ma_iot;
+ sc->sc_dmat = ma->ma_dmat;
+
+ if (OF_getprop(sc->sc_node, "compatible", buffer,
+ sizeof(buffer)))
+ printf(": %s compatible\n", buffer);
+ else
+ printf(": unknown\n");
+
+ /* Scan the whole tree. */
+ config_scan(simplebus_find_match, self);
+}
+
+/*
+ * Usually you should be able to attach devices in the order
+ * specified in the device tree. Due to how a few drivers
+ * are written we need to make sure we attach them in the
+ * order stated in files.xxx.
+ *
+ * This means for every driver enabled, we go through the
+ * FDT and look for compatible nodes.
+ */
+void
+simplebus_find_match(struct device *self, void *match)
+{
+ struct simplebus_softc *sc = (struct simplebus_softc *)self;
+ int node;
+
+ for (node = OF_child(sc->sc_node);
+ node != 0;
+ node = OF_peer(node))
+ {
+ /* skip nodes that are already handled by some driver */
+ if (!simplebus_is_attached(node))
+ simplebus_attach_node(self, match, node);
+ }
+}
+
+/*
+ * Try to attach a node to a known driver.
+ */
+void
+simplebus_attach_node(struct device *self, void *match, int node)
+{
+ struct simplebus_softc *sc = (struct simplebus_softc *)self;
+ struct simplebus_attach_args sa;
+ struct cfdata *cf = match;
+ struct device *child;
+ char buffer[128];
+
+ if (!OF_getprop(node, "compatible", buffer, sizeof(buffer)))
+ return;
+
+ if (OF_getprop(node, "status", buffer, sizeof(buffer)))
+ if (!strcmp(buffer, "disabled"))
+ return;
+
+ memset(&sa, 0, sizeof(sa));
+ sa.sa_name = "";
+ sa.sa_node = node;
+ sa.sa_iot = sc->sc_iot;
+ sa.sa_dmat = sc->sc_dmat;
+
+ /* allow for devices to be disabled in UKC */
+ if ((*cf->cf_attach->ca_match)(self, cf, &sa) == 0)
+ return;
+
+ /* TODO: attach the device's clocks first? */
+
+ child = config_attach(self, cf, &sa, NULL);
+ simplebus_dev_list_insert(node, child);
+}
diff --git sys/arch/arm/simplebus/simplebus.h sys/arch/arm/simplebus/simplebus.h
new file mode 100644
index 0000000..fcbc789
--- /dev/null
+++ sys/arch/arm/simplebus/simplebus.h
@@ -0,0 +1,32 @@
+/* $OpenBSD$ */
+/*
+ * Copyright (c) 2016 Patrick Wildt <[email protected]>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef __SIMPLEBUS_H__
+#define __SIMPLEBUS_H__
+
+#define _ARM32_BUS_DMA_PRIVATE
+#include <machine/bus.h>
+
+/* Passed as third arg to attach functions. */
+struct simplebus_attach_args {
+ const char *sa_name;
+ int sa_node;
+ bus_space_tag_t sa_iot;
+ bus_dma_tag_t sa_dmat;
+};
+
+#endif /* __SIMPLEBUS_H__ */
diff --git sys/arch/armv7/conf/GENERIC sys/arch/armv7/conf/GENERIC
index b55771d..dfe5f67 100644
--- sys/arch/armv7/conf/GENERIC
+++ sys/arch/armv7/conf/GENERIC
@@ -29,6 +29,7 @@ config bsd swap generic
# The main bus device
mainbus0 at root
+simplebus* at ofwbus?
cpu0 at mainbus?
# Cortex-A9
diff --git sys/arch/armv7/conf/RAMDISK sys/arch/armv7/conf/RAMDISK
index 8c0c22b..4e958af 100644
--- sys/arch/armv7/conf/RAMDISK
+++ sys/arch/armv7/conf/RAMDISK
@@ -27,6 +27,7 @@ config bsd root on rd0a swap on rd0b
# The main bus device
mainbus0 at root
+simplebus* at ofwbus?
cpu0 at mainbus?
# Cortex-A9
diff --git sys/arch/armv7/conf/files.armv7 sys/arch/armv7/conf/files.armv7
index c5d022c..ae40f36 100644
--- sys/arch/armv7/conf/files.armv7
+++ sys/arch/armv7/conf/files.armv7
@@ -10,7 +10,6 @@ major {rd = 18}
define fdt {}
file arch/armv7/fdt/fdt_machdep.c fdt needs-flag
-file dev/ofw/fdt.c
file arch/arm/arm/conf.c
diff --git sys/arch/armv7/exynos/files.exynos sys/arch/armv7/exynos/files.exynos
index ef53213..e20edcc 100644
--- sys/arch/armv7/exynos/files.exynos
+++ sys/arch/armv7/exynos/files.exynos
@@ -2,7 +2,7 @@
define exynos {}
device exynos: exynos
-attach exynos at mainbus
+attach exynos at ofwbus
file arch/armv7/exynos/exynos_machdep.c exynos needs-flag
file arch/armv7/exynos/exynos.c exynos
file arch/armv7/exynos/exynos4.c exynos
diff --git sys/arch/armv7/imx/files.imx sys/arch/armv7/imx/files.imx
index 3e7ec33..4f38154 100644
--- sys/arch/armv7/imx/files.imx
+++ sys/arch/armv7/imx/files.imx
@@ -2,7 +2,7 @@
define imx {}
device imx: imx
-attach imx at mainbus
+attach imx at ofwbus
file arch/armv7/imx/imx_machdep.c imx needs-flag
file arch/armv7/imx/imx.c imx
file arch/armv7/imx/imx6.c
diff --git sys/arch/armv7/omap/files.omap sys/arch/armv7/omap/files.omap
index 8fd446f..06fa47d 100644
--- sys/arch/armv7/omap/files.omap
+++ sys/arch/armv7/omap/files.omap
@@ -2,7 +2,7 @@
define omap {}
device omap: omap
-attach omap at mainbus
+attach omap at ofwbus
file arch/armv7/omap/omap_machdep.c omap needs-flag
file arch/armv7/omap/omap.c omap
file arch/armv7/omap/omap3.c
diff --git sys/arch/armv7/sunxi/files.sunxi sys/arch/armv7/sunxi/files.sunxi
index 80c4ba4..09a4934 100644
--- sys/arch/armv7/sunxi/files.sunxi
+++ sys/arch/armv7/sunxi/files.sunxi
@@ -2,7 +2,7 @@
define sunxi {}
device sunxi: sunxi
-attach sunxi at mainbus
+attach sunxi at ofwbus
file arch/armv7/sunxi/sunxi_machdep.c sunxi needs-flag
file arch/armv7/sunxi/sunxi.c sunxi
file arch/armv7/sunxi/sun4i.c
diff --git sys/arch/armv7/vexpress/files.vexpress
sys/arch/armv7/vexpress/files.vexpress
index dd7db10..075164b 100644
--- sys/arch/armv7/vexpress/files.vexpress
+++ sys/arch/armv7/vexpress/files.vexpress
@@ -2,7 +2,7 @@
define vexpress {}
device vexpress: vexpress
-attach vexpress at mainbus
+attach vexpress at ofwbus
file arch/armv7/vexpress/vexpress_machdep.c vexpress needs-flag
file arch/armv7/vexpress/vexpress.c vexpress
file arch/armv7/vexpress/vexpress_a9.c vexpress