On Fri, Apr 08, 2016 at 02:00:54PM +0200, Patrick Wildt wrote: > Hi, > > this diff replaces the ARM mainbus with a new implementation. This > implementation works like the old version if there's no device tree. > > But if there is a device tree, this tree will be used to enumerate > and attach all device drivers. > > Currently drivers kind of depend on each other. This means one > driver might expect the GPIO driver to already be attached. Until > there are proper ways to establish interrupts, establish and set GPIOs, > set pinmuxes and attach clocks, we need to keep this attachment order. > > To cope with that this code goes through the list of drivers on mainbus, > and for every driver looks through the whole device tree and calls > the driver's match function per node. So that we don't attach nodes > multiple times, we need to keep a list of nodes that we already > attached. > > For now we need to manually attach the cpu and cortex bus. Soon I hope > that the cortex bus will not be needed for FDT, so that the devices > can attach directly to mainbus and don't need this extra step. > > Thoughts? ok? > > Patrick > > diff --git sys/arch/arm/conf/files.arm sys/arch/arm/conf/files.arm > index cb11960..3436e8e 100644 > --- sys/arch/arm/conf/files.arm > +++ sys/arch/arm/conf/files.arm > @@ -21,6 +21,9 @@ device mainbus {} > attach mainbus at root > file arch/arm/mainbus/mainbus.c mainbus > > +# FDT support > +file dev/ofw/fdt.c > + > include "arch/arm/cortex/files.cortex" > > device cpu {} > diff --git sys/arch/arm/cortex/cortex.c sys/arch/arm/cortex/cortex.c > index 73aa315..db878b7 100644 > --- sys/arch/arm/cortex/cortex.c > +++ sys/arch/arm/cortex/cortex.c > @@ -51,6 +51,7 @@ > #include <arm/cpufunc.h> > #include <arm/armv7/armv7var.h> > #include <arm/cortex/cortex.h> > +#include <arm/mainbus/mainbus.h> > > struct arm32_bus_dma_tag cortex_bus_dma_tag = { > 0, > @@ -94,10 +95,15 @@ struct cfdriver cortex_cd = { > */ > > int > -cortexmatch(struct device *parent, void *cf, void *aux) > +cortexmatch(struct device *parent, void *cfdata, void *aux) > { > + struct mainbus_attach_args *ma = aux; > + struct cfdata *cf = (struct cfdata *)cfdata; > int cputype = cpufunc_id(); > > + if (strcmp(cf->cf_driver->cd_name, ma->ma_name) != 0) > + return (0); > + > if ((cputype & CPU_ID_CORTEX_A7_MASK) == CPU_ID_CORTEX_A7 || > (cputype & CPU_ID_CORTEX_A9_MASK) == CPU_ID_CORTEX_A9 || > (cputype & CPU_ID_CORTEX_A15_MASK) == CPU_ID_CORTEX_A15 || > diff --git sys/arch/arm/mainbus/mainbus.c sys/arch/arm/mainbus/mainbus.c > index 6ad3e8f..02062a6 100644 > --- sys/arch/arm/mainbus/mainbus.c > +++ sys/arch/arm/mainbus/mainbus.c > @@ -1,124 +1,255 @@ > -/* $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) 2014-2016 Patrick Wildt <patr...@blueri.se> > * > - * 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/fdt.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(void *); > +void mainbus_dev_list_insert(void *, struct device *); > + > +void mainbus_find_match(struct device *, void *); > +void mainbus_iterate(struct device *, struct device *, void *); > +void mainbus_attach_node(struct device *, void *, void *); > + > +int mainbus_legacy_search(struct device *, void *, void *); > +void mainbus_legacy_found(struct device *, char *); > + > +struct mainbus_softc { > + struct device sc_dev; > + 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; > + void *me_node; > + struct device *me_dev; > +}; > + > +struct device * > +mainbus_is_attached(void *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(void *node, struct device *child) > +{ > + struct mainbus_entry *me; > + > + if (child == NULL) > + return; > > -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 *); > + me = malloc(sizeof(*me), M_DEVBUF, M_NOWAIT|M_ZERO); > + if (me == NULL) > + panic("%s: cannot allocate memory", __func__); > > -/* attach and device structures for the device */ > + 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 *compatible; > + void *node; > + > + if ((node = fdt_next_node(0)) == NULL) { > + printf(": running without device tree\n"); > + config_search(mainbus_legacy_search, self, aux); > + return; > + } > + > +#ifdef CPU_ARMv7 > + extern struct bus_space armv7_bs_tag; > + sc->sc_iot = &armv7_bs_tag; > +#endif > + sc->sc_dmat = &mainbus_dma_tag; > + > + if (fdt_node_property(node, "compatible", &compatible)) > + printf(": %s compatible\n", compatible); > + 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) > +{ > + mainbus_iterate(self, match, fdt_next_node(0)); > +} > + > +void > +mainbus_iterate(struct device *self, struct device *match, void *node) > +{ > + for (; > + node != NULL; > + node = fdt_next_node(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, fdt_child_node(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, void *node) > { > - printf("\n"); > + struct mainbus_softc *sc = (struct mainbus_softc *)self; > + struct mainbus_attach_args ma; > + struct cfdata *cf = match; > + struct device *child; > + char *status; > + > + if (!fdt_node_property(node, "compatible", NULL)) > + return; > + > + if (fdt_node_property(node, "status", &status)) > + if (!strcmp(status, "disabled")) > + return; > + > + memset(&ma, 0, sizeof(ma)); > + ma.ma_name = ""; > + ma.ma_node = node; > + ma.ma_iot = sc->sc_iot; > + ma.ma_dmat = sc->sc_dmat; > > - config_search(mainbussearch, self, aux); > + /* 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..188bc5a 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 <patr...@blueri.se> > * > - * 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; > + void *ma_node; > + bus_space_tag_t ma_iot; > + bus_dma_tag_t ma_dmat; > }; > + > +#endif /* __MAINBUS_H__ */ > 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/dev/ofw/fdt.c sys/dev/ofw/fdt.c > index cdb588b..4cf7248 100644 > --- sys/dev/ofw/fdt.c > +++ sys/dev/ofw/fdt.c > @@ -160,6 +160,7 @@ skip_node_name(u_int32_t *ptr) > /* > * Retrieves node property, the returned pointer is inside the fdt tree, > * so we should not modify content pointed by it directly. > + * A NULL out parameter will cause this function to only return the size. > */ > int > fdt_node_property(void *node, char *name, char **out) > @@ -182,7 +183,8 @@ fdt_node_property(void *node, char *name, char **out) > nameid = betoh32(*(ptr + 2)); /* id of name in strings table */ > tmp = fdt_get_str(nameid); > if (!strcmp(name, tmp)) { > - *out = (char *)(ptr + 3); /* beginning of the value */ > + if (out != NULL) > + *out = (char *)(ptr + 3); /* beginning of the > value */ > return betoh32(*(ptr + 1)); /* size of value */ > } > ptr = skip_property(ptr); >
After some feedback and discussion with mpi@ I have modified this code to use the OF_* API instead. diff --git sys/arch/arm/conf/files.arm sys/arch/arm/conf/files.arm index cb11960..3436e8e 100644 --- sys/arch/arm/conf/files.arm +++ sys/arch/arm/conf/files.arm @@ -21,6 +21,9 @@ device mainbus {} attach mainbus at root file arch/arm/mainbus/mainbus.c mainbus +# FDT support +file dev/ofw/fdt.c + include "arch/arm/cortex/files.cortex" device cpu {} diff --git sys/arch/arm/mainbus/mainbus.c sys/arch/arm/mainbus/mainbus.c index 6ad3e8f..614ab15 100644 --- sys/arch/arm/mainbus/mainbus.c +++ sys/arch/arm/mainbus/mainbus.c @@ -1,124 +1,255 @@ -/* $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) 2014-2016 Patrick Wildt <patr...@blueri.se> * - * 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 *); + +void mainbus_find_match(struct device *, void *); +void mainbus_iterate(struct device *, struct device *, int); +void mainbus_attach_node(struct device *, void *, int); + +int mainbus_legacy_search(struct device *, void *, void *); +void mainbus_legacy_found(struct device *, char *); + +struct mainbus_softc { + struct device sc_dev; + 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; -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 *); + me = malloc(sizeof(*me), M_DEVBUF, M_NOWAIT|M_ZERO); + if (me == NULL) + panic("%s: cannot allocate memory", __func__); -/* attach and device structures for the device */ + 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; + } + +#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) +{ + mainbus_iterate(self, match, OF_peer(0)); +} + +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)); + } +} +/* + * 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", NULL, 0)) + return; + + if (OF_getprop(node, "status", buffer, sizeof(buffer))) + if (!strcmp(buffer, "disabled")) + return; + + memset(&ma, 0, sizeof(ma)); + ma.ma_name = ""; + ma.ma_node = node; + ma.ma_iot = sc->sc_iot; + ma.ma_dmat = sc->sc_dmat; - config_search(mainbussearch, self, aux); + /* 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 <patr...@blueri.se> * - * 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/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