Bring over the changes to mainbus(4) and simplebus(4) from arm64.
authorkettenis <kettenis@openbsd.org>
Thu, 27 Apr 2017 22:41:46 +0000 (22:41 +0000)
committerkettenis <kettenis@openbsd.org>
Thu, 27 Apr 2017 22:41:46 +0000 (22:41 +0000)
sys/arch/arm/arm/cpu.c
sys/arch/arm/conf/files.arm
sys/arch/arm/include/armreg.h
sys/arch/arm/include/cpu.h
sys/arch/arm/mainbus/cpu_mainbus.c [deleted file]
sys/arch/arm/mainbus/mainbus.c
sys/arch/arm/simplebus/simplebus.c

index 5c18441..702433c 100644 (file)
@@ -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 $     */
 
 
 #include <uvm/uvm_extern.h>
 #include <machine/cpu.h>
 #include <machine/intr.h>
+#include <machine/fdt.h>
 
 #include <arm/cpuconf.h>
 #include <arm/undefined.h>
 
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/fdt.h>
+
 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 {
index 84feca7..671bc3f 100644 (file)
@@ -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
index 877eaf3..7e89418 100644 (file)
@@ -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 $     */
 
 /*
 #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
index 3219069..312c2f6 100644 (file)
@@ -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 (file)
index e672660..0000000
+++ /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
-};
index 80a5e50..7f48666 100644 (file)
@@ -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
 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)
 {
index 979a030..9385954 100644 (file)
@@ -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 <patrick@blueri.se>
  *
@@ -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 = "";