From 88a615dbeb839372707b48a527d25530dadf0d81 Mon Sep 17 00:00:00 2001 From: kettenis Date: Thu, 27 Apr 2017 22:41:46 +0000 Subject: [PATCH] Bring over the changes to mainbus(4) and simplebus(4) from arm64. --- sys/arch/arm/arm/cpu.c | 58 ++++++++++--- sys/arch/arm/conf/files.arm | 6 +- sys/arch/arm/include/armreg.h | 8 +- sys/arch/arm/include/cpu.h | 4 +- sys/arch/arm/mainbus/cpu_mainbus.c | 102 ---------------------- sys/arch/arm/mainbus/mainbus.c | 132 +++++++++++++++++++---------- sys/arch/arm/simplebus/simplebus.c | 16 ++-- 7 files changed, 151 insertions(+), 175 deletions(-) delete mode 100644 sys/arch/arm/mainbus/cpu_mainbus.c diff --git a/sys/arch/arm/arm/cpu.c b/sys/arch/arm/arm/cpu.c index 5c184417342..702433c1ecc 100644 --- a/sys/arch/arm/arm/cpu.c +++ b/sys/arch/arm/arm/cpu.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.c,v 1.37 2017/04/24 18:15:16 kettenis Exp $ */ +/* $OpenBSD: cpu.c,v 1.38 2017/04/27 22:41:46 kettenis Exp $ */ /* $NetBSD: cpu.c,v 1.56 2004/04/14 04:01:49 bsh Exp $ */ @@ -55,32 +55,62 @@ #include #include #include +#include #include #include +#include +#include + char cpu_model[256]; -/* Prototypes */ +int cpu_match(struct device *, void *, void *); +void cpu_attach(struct device *, struct device *, void *); + +struct cfattach cpu_ca = { + sizeof(struct device), cpu_match, cpu_attach +}; + +struct cfdriver cpu_cd = { + NULL, "cpu", DV_DULL +}; + void identify_arm_cpu(struct device *dv, struct cpu_info *); -/* - * Identify the master (boot) CPU - */ - +int +cpu_match(struct device *parent, void *cfdata, void *aux) +{ + struct fdt_attach_args *faa = aux; + char buf[32]; + + if (OF_getprop(faa->fa_node, "device_type", buf, sizeof(buf)) > 0 && + strcmp(buf, "cpu") == 0) + return 1; + + return 0; +} + void -cpu_attach(struct device *dv) +cpu_attach(struct device *parent, struct device *dev, void *aux) { - curcpu()->ci_dev = dv; + struct cpu_info *ci; - /* Get the CPU ID from coprocessor 15 */ + if (dev->dv_unit == 0) { + ci = curcpu(); + ci->ci_dev = dev; - curcpu()->ci_arm_cpuid = cpu_id(); - curcpu()->ci_arm_cputype = curcpu()->ci_arm_cpuid & CPU_ID_CPU_MASK; - curcpu()->ci_arm_cpurev = - curcpu()->ci_arm_cpuid & CPU_ID_REVISION_MASK; + /* Get the CPU ID from coprocessor 15 */ + ci->ci_arm_cpuid = cpu_id(); + ci->ci_arm_cputype = + ci->ci_arm_cpuid & CPU_ID_CPU_MASK; + ci->ci_arm_cpurev = + ci->ci_arm_cpuid & CPU_ID_REVISION_MASK; - identify_arm_cpu(dv, curcpu()); + identify_arm_cpu(dev, ci); + } else { + printf(": not configured"); + } } enum cpu_class { diff --git a/sys/arch/arm/conf/files.arm b/sys/arch/arm/conf/files.arm index 84feca7aef4..671bc3fbed6 100644 --- a/sys/arch/arm/conf/files.arm +++ b/sys/arch/arm/conf/files.arm @@ -1,4 +1,4 @@ -# $OpenBSD: files.arm,v 1.44 2017/01/21 10:58:15 reyk Exp $ +# $OpenBSD: files.arm,v 1.45 2017/04/27 22:41:46 kettenis Exp $ # $NetBSD: files.arm,v 1.76 2003/11/05 12:53:15 scw Exp $ # generic networking files @@ -34,9 +34,7 @@ file dev/ofw/fdt.c include "arch/arm/cortex/files.cortex" device cpu {} -attach cpu at fdt with cpu_mainbus -file arch/arm/mainbus/cpu_mainbus.c cpu_mainbus - +attach cpu at mainbus # bus_space(9) define bus_space_generic diff --git a/sys/arch/arm/include/armreg.h b/sys/arch/arm/include/armreg.h index 877eaf369c4..7e89418e57e 100644 --- a/sys/arch/arm/include/armreg.h +++ b/sys/arch/arm/include/armreg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: armreg.h,v 1.40 2017/04/24 18:15:16 kettenis Exp $ */ +/* $OpenBSD: armreg.h,v 1.41 2017/04/27 22:41:46 kettenis Exp $ */ /* $NetBSD: armreg.h,v 1.27 2003/09/06 08:43:02 rearnsha Exp $ */ /* @@ -274,6 +274,12 @@ #define CPU_CT_xSIZE_ASSOC(x) (((x) >> 3) & 0x7) /* associativity */ #define CPU_CT_xSIZE_SIZE(x) (((x) >> 6) & 0x7) /* size */ +/* MPIDR, Multiprocessor Affinity Register */ +#define MPIDR_AFF2 (0xffU << 16) +#define MPIDR_AFF1 (0xffU << 8) +#define MPIDR_AFF0 (0xffU << 0) +#define MPIDR_AFF (MPIDR_AFF2|MPIDR_AFF1|MPIDR_AFF0) + /* Fault status register definitions */ #define FAULT_USER 0x20 diff --git a/sys/arch/arm/include/cpu.h b/sys/arch/arm/include/cpu.h index 3219069f050..312c2f6c9c9 100644 --- a/sys/arch/arm/include/cpu.h +++ b/sys/arch/arm/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.45 2017/03/03 14:54:02 tom Exp $ */ +/* $OpenBSD: cpu.h,v 1.46 2017/04/27 22:41:46 kettenis Exp $ */ /* $NetBSD: cpu.h,v 1.34 2003/06/23 11:01:08 martin Exp $ */ /* @@ -281,8 +281,6 @@ extern int want_resched; /* resched() was called */ * cpu device glue (belongs in cpuvar.h) */ -struct device; -void cpu_attach(struct device *); int cpu_alloc_idle_pcb(struct cpu_info *); /* 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 -#include -#include -#include -#include -#if 0 -#include -#include -#include -#endif -#include -#if 0 -#include -#include -#endif -#include - -/* - * 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 + * Copyright (c) 2017 Mark Kettenis * * 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) { diff --git a/sys/arch/arm/simplebus/simplebus.c b/sys/arch/arm/simplebus/simplebus.c index 979a030df7f..9385954cc87 100644 --- a/sys/arch/arm/simplebus/simplebus.c +++ b/sys/arch/arm/simplebus/simplebus.c @@ -1,4 +1,4 @@ -/* $OpenBSD: simplebus.c,v 1.12 2017/01/23 06:13:34 kettenis Exp $ */ +/* $OpenBSD: simplebus.c,v 1.13 2017/04/27 22:41:46 kettenis Exp $ */ /* * Copyright (c) 2016 Patrick Wildt * @@ -96,11 +96,11 @@ simplebus_attach(struct device *parent, struct device *self, void *aux) /* Scan the whole tree. */ sc->sc_early = 1; - for (node = OF_child(sc->sc_node); node; node = OF_peer(node)) + for (node = OF_child(sc->sc_node); node; node = OF_peer(node)) simplebus_attach_node(self, node); sc->sc_early = 0; - for (node = OF_child(sc->sc_node); node; node = OF_peer(node)) + for (node = OF_child(sc->sc_node); node; node = OF_peer(node)) simplebus_attach_node(self, node); } @@ -123,16 +123,16 @@ simplebus_attach_node(struct device *self, int node) { struct simplebus_softc *sc = (struct simplebus_softc *)self; struct fdt_attach_args fa; - char buffer[128]; + char buf[32]; 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; + if (OF_getprop(node, "status", buf, sizeof(buf)) > 0 && + strcmp(buf, "disabled") == 0) + return; memset(&fa, 0, sizeof(fa)); fa.fa_name = ""; -- 2.20.1