> Date: Sat, 9 Apr 2016 17:32:33 +0200
> From: Patrick Wildt <[email protected]>
> 
> 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?

I think this is going in the right direction.  But there is still some
weirdness going on.

> 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 {}

I'd probably call this fdtbus are perhaps simply fdt.

>  # 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");

Not sure if we want to keep printing that in the long run.  Printing
the "model" probably makes more sense.  But that can be changed later.

> +
> +     /* 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.

Isn't it actually the order they're listed in the kernel config file
that determines the order?

>   *
> - * probe and attach all children
> + * This means for every driver enabled, we go through the
> + * FDT and look for compatible nodes.
>   */

Is this just a temporary thing until the drivers are changed such that
they can be attached in tree order?

> +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 */

I think this comment is a ly; you're checking here whether the FDT
node matches the driver we're trying to attach.

> +     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;
> +};

Since mainbus and simplebus both use the same attach_args structure.

> +
> +#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
> 
> 

Reply via email to