summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2017-04-27 22:41:47 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2017-04-27 22:41:47 +0000
commita10bdbeff1033de44b37c9b030f9b39bbd008fa0 (patch)
tree729300affddec79fb520e1338f4740a93f0e317b /sys/arch
parentaf8ada589a2ecd07d021494e027795b3b1ae2454 (diff)
Bring over the changes to mainbus(4) and simplebus(4) from arm64.
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/arm/arm/cpu.c58
-rw-r--r--sys/arch/arm/conf/files.arm6
-rw-r--r--sys/arch/arm/include/armreg.h8
-rw-r--r--sys/arch/arm/include/cpu.h4
-rw-r--r--sys/arch/arm/mainbus/cpu_mainbus.c102
-rw-r--r--sys/arch/arm/mainbus/mainbus.c132
-rw-r--r--sys/arch/arm/simplebus/simplebus.c16
7 files changed, 151 insertions, 175 deletions
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 <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 {
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 <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)
{
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 <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 = "";