summaryrefslogtreecommitdiff
path: root/sys/arch/arm/mainbus
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/arm/mainbus
parentaf8ada589a2ecd07d021494e027795b3b1ae2454 (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.c102
-rw-r--r--sys/arch/arm/mainbus/mainbus.c132
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)
{