diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2017-04-27 22:41:47 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2017-04-27 22:41:47 +0000 |
commit | a10bdbeff1033de44b37c9b030f9b39bbd008fa0 (patch) | |
tree | 729300affddec79fb520e1338f4740a93f0e317b /sys/arch/arm/mainbus | |
parent | af8ada589a2ecd07d021494e027795b3b1ae2454 (diff) |
Bring over the changes to mainbus(4) and simplebus(4) from arm64.
Diffstat (limited to 'sys/arch/arm/mainbus')
-rw-r--r-- | sys/arch/arm/mainbus/cpu_mainbus.c | 102 | ||||
-rw-r--r-- | sys/arch/arm/mainbus/mainbus.c | 132 |
2 files changed, 89 insertions, 145 deletions
diff --git a/sys/arch/arm/mainbus/cpu_mainbus.c b/sys/arch/arm/mainbus/cpu_mainbus.c deleted file mode 100644 index e6726605d70..00000000000 --- a/sys/arch/arm/mainbus/cpu_mainbus.c +++ /dev/null @@ -1,102 +0,0 @@ -/* $OpenBSD: cpu_mainbus.c,v 1.2 2016/05/02 08:15:55 patrick Exp $ */ -/* $NetBSD: cpu_mainbus.c,v 1.3 2002/01/05 22:41:48 chris Exp $ */ - -/* - * Copyright (c) 1995 Mark Brinicombe. - * Copyright (c) 1995 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 - * - * cpu.c - * - * Probing and configuration for the master cpu - * - * Created : 10/10/95 - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/malloc.h> -#include <sys/device.h> -#include <sys/proc.h> -#if 0 -#include <uvm/uvm_extern.h> -#include <machine/io.h> -#include <machine/conf.h> -#endif -#include <machine/cpu.h> -#if 0 -#include <arm/cpus.h> -#include <arm/undefined.h> -#endif -#include <arm/mainbus/mainbus.h> - -/* - * Prototypes - */ -static int cpu_mainbus_match (struct device *, void *, void *); -static void cpu_mainbus_attach (struct device *, struct device *, void *); - -/* - * int cpumatch(struct device *parent, struct cfdata *cf, void *aux) - */ - -static int -cpu_mainbus_match(struct device *parent, void *vcf, void *aux) -{ - union mainbus_attach_args *ma = aux; - struct cfdata *cf = (struct cfdata *)vcf; - - return (strcmp(cf->cf_driver->cd_name, ma->ma_name) == 0); -} - -/* - * void cpusattach(struct device *parent, struct device *dev, void *aux) - * - * Attach the main cpu - */ - -static void -cpu_mainbus_attach(parent, self, aux) - struct device *parent; - struct device *self; - void *aux; -{ - cpu_attach(self); -} - -struct cfattach cpu_mainbus_ca = { - sizeof(struct device), cpu_mainbus_match, cpu_mainbus_attach -}; - -struct cfdriver cpu_cd = { - NULL, "cpu", DV_DULL -}; diff --git a/sys/arch/arm/mainbus/mainbus.c b/sys/arch/arm/mainbus/mainbus.c index 80a5e508031..7f48666b9cd 100644 --- a/sys/arch/arm/mainbus/mainbus.c +++ b/sys/arch/arm/mainbus/mainbus.c @@ -1,6 +1,7 @@ -/* $OpenBSD: mainbus.c,v 1.15 2017/01/06 00:06:02 jsg Exp $ */ +/* $OpenBSD: mainbus.c,v 1.16 2017/04/27 22:41:46 kettenis Exp $ */ /* * Copyright (c) 2016 Patrick Wildt <patrick@blueri.se> + * Copyright (c) 2017 Mark Kettenis <kettenis@openbsd.org> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -29,11 +30,13 @@ int mainbus_match(struct device *, void *, void *); void mainbus_attach(struct device *, struct device *, void *); -void mainbus_attach_node(struct device *, int); +void mainbus_attach_node(struct device *, int, cfmatch_t); +int mainbus_match_status(struct device *, void *, void *); +void mainbus_attach_cpus(struct device *, cfmatch_t); +int mainbus_match_primary(struct device *, void *, void *); +int mainbus_match_secondary(struct device *, void *, void *); void mainbus_attach_framebuffer(struct device *); -int mainbus_legacy_search(struct device *, void *, void *); - struct mainbus_softc { struct device sc_dev; bus_space_tag_t sc_iot; @@ -90,14 +93,11 @@ void mainbus_attach(struct device *parent, struct device *self, void *aux) { struct mainbus_softc *sc = (struct mainbus_softc *)self; - char buffer[128]; + char model[128]; int node, len; - if ((node = OF_peer(0)) == 0) { - printf(": no device tree\n"); - config_search(mainbus_legacy_search, self, aux); - return; - } + if ((node = OF_peer(0)) == 0) + panic("mainbus: no device tree"); arm_intr_init_fdt(); @@ -106,19 +106,18 @@ mainbus_attach(struct device *parent, struct device *self, void *aux) sc->sc_acells = OF_getpropint(OF_peer(0), "#address-cells", 1); sc->sc_scells = OF_getpropint(OF_peer(0), "#size-cells", 1); - if ((len = OF_getprop(node, "model", buffer, sizeof(buffer))) > 0) { - printf(": %s\n", buffer); + if ((len = OF_getprop(node, "model", model, sizeof(model))) > 0) { + printf(": %s\n", model); hw_prod = malloc(len, M_DEVBUF, M_NOWAIT); if (hw_prod) - strlcpy(hw_prod, buffer, len); + strlcpy(hw_prod, model, len); } else printf(": unknown model\n"); - /* Attach CPU first. */ - mainbus_legacy_found(self, "cpu"); - platform_init_mainbus(self); + /* Attach primary CPU first. */ + mainbus_attach_cpus(self, mainbus_match_primary); - /* TODO: Scan for interrupt controllers and attach them first? */ + platform_init_mainbus(self); sc->sc_rangeslen = OF_getproplen(OF_peer(0), "ranges"); if (sc->sc_rangeslen > 0 && !(sc->sc_rangeslen % sizeof(uint32_t))) { @@ -129,30 +128,28 @@ mainbus_attach(struct device *parent, struct device *self, void *aux) /* Scan the whole tree. */ for (node = OF_child(node); node != 0; node = OF_peer(node)) - mainbus_attach_node(self, node); + mainbus_attach_node(self, node, NULL); mainbus_attach_framebuffer(self); + + /* Attach secondary CPUs. */ + mainbus_attach_cpus(self, mainbus_match_secondary); } /* * Look for a driver that wants to be attached to this node. */ void -mainbus_attach_node(struct device *self, int node) +mainbus_attach_node(struct device *self, int node, cfmatch_t submatch) { struct mainbus_softc *sc = (struct mainbus_softc *)self; struct fdt_attach_args fa; - char buffer[128]; int i, len, line; uint32_t *cell, *reg; - if (!OF_getprop(node, "compatible", buffer, sizeof(buffer))) + if (OF_getproplen(node, "compatible") <= 0) return; - if (OF_getprop(node, "status", buffer, sizeof(buffer))) - if (!strcmp(buffer, "disabled")) - return; - memset(&fa, 0, sizeof(fa)); fa.fa_name = ""; fa.fa_node = node; @@ -199,46 +196,95 @@ mainbus_attach_node(struct device *self, int node) OF_getpropintarray(node, "interrupts", fa.fa_intr, len); } - /* TODO: attach the device's clocks first? */ - - config_found(self, &fa, NULL); + if (submatch == NULL) + submatch = mainbus_match_status; + config_found_sm(self, &fa, NULL, submatch); free(fa.fa_reg, M_DEVBUF, fa.fa_nreg * sizeof(struct fdt_reg)); free(fa.fa_intr, M_DEVBUF, fa.fa_nintr * sizeof(uint32_t)); } +int +mainbus_match_status(struct device *parent, void *match, void *aux) +{ + struct fdt_attach_args *fa = aux; + struct cfdata *cf = match; + char buf[32]; + + if (OF_getprop(fa->fa_node, "status", buf, sizeof(buf)) > 0 && + strcmp(buf, "disabled") == 0) + return 0; + + return (*cf->cf_attach->ca_match)(parent, match, aux); +} + void -mainbus_attach_framebuffer(struct device *self) +mainbus_attach_cpus(struct device *self, cfmatch_t match) { - int node = OF_finddevice("/chosen"); + struct mainbus_softc *sc = (struct mainbus_softc *)self; + int node = OF_finddevice("/cpus"); + int acells, scells; if (node == 0) return; + acells = sc->sc_acells; + scells = sc->sc_scells; + sc->sc_acells = OF_getpropint(node, "#address-cells", 1); + sc->sc_scells = OF_getpropint(node, "#size-cells", 0); + for (node = OF_child(node); node != 0; node = OF_peer(node)) - mainbus_attach_node(self, node); + mainbus_attach_node(self, node, match); + + sc->sc_acells = acells; + sc->sc_scells = scells; } -/* - * Legacy support for SoCs that do not use FDT. - */ int -mainbus_legacy_search(struct device *parent, void *match, void *aux) +mainbus_match_primary(struct device *parent, void *match, void *aux) { - union mainbus_attach_args ma; - struct cfdata *cf = match; + struct fdt_attach_args *fa = aux; + struct cfdata *cf = match; + uint32_t mpidr; - memset(&ma, 0, sizeof(ma)); - ma.ma_name = cf->cf_driver->cd_name; + __asm volatile("mrc p15, 0, %0, c0, c0, 5" : "=r " (mpidr)); - /* allow for devices to be disabled in UKC */ - if ((*cf->cf_attach->ca_match)(parent, cf, &ma) == 0) + if (fa->fa_nreg < 1 || fa->fa_reg[0].addr != (mpidr & MPIDR_AFF)) return 0; - config_attach(parent, cf, &ma, NULL); - return 1; + return (*cf->cf_attach->ca_match)(parent, match, aux); +} + +int +mainbus_match_secondary(struct device *parent, void *match, void *aux) +{ + struct fdt_attach_args *fa = aux; + struct cfdata *cf = match; + uint32_t mpidr; + + __asm volatile("mrc p15, 0, %0, c0, c0, 5" : "=r " (mpidr)); + + if (fa->fa_nreg < 1 || fa->fa_reg[0].addr == (mpidr & MPIDR_AFF)) + return 0; + + return (*cf->cf_attach->ca_match)(parent, match, aux); +} + +void +mainbus_attach_framebuffer(struct device *self) +{ + int node = OF_finddevice("/chosen"); + + if (node == 0) + return; + + for (node = OF_child(node); node != 0; node = OF_peer(node)) + mainbus_attach_node(self, node, NULL); } +/* + * Legacy support for SoCs that do not fully use FDT. + */ void mainbus_legacy_found(struct device *self, char *name) { |