summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkettenis <kettenis@openbsd.org>2020-06-07 13:17:24 +0000
committerkettenis <kettenis@openbsd.org>2020-06-07 13:17:24 +0000
commit8c07258a3b11c528c4ed3a63093815e7afb97ad6 (patch)
tree5fbc0a78d3307541f24874ce20e517171f6ccb24
parentAllocate a struct, not just a pointer. (diff)
downloadwireguard-openbsd-8c07258a3b11c528c4ed3a63093815e7afb97ad6.tar.xz
wireguard-openbsd-8c07258a3b11c528c4ed3a63093815e7afb97ad6.zip
mainbus(4) and cpu(4).
-rw-r--r--sys/arch/powerpc64/conf/GENERIC3
-rw-r--r--sys/arch/powerpc64/conf/files.powerpc6429
-rw-r--r--sys/arch/powerpc64/dev/mainbus.c348
-rw-r--r--sys/arch/powerpc64/include/bus.h3
-rw-r--r--sys/arch/powerpc64/include/cpufunc.h10
-rw-r--r--sys/arch/powerpc64/powerpc64/autoconf.c23
-rw-r--r--sys/arch/powerpc64/powerpc64/cpu.c52
7 files changed, 430 insertions, 38 deletions
diff --git a/sys/arch/powerpc64/conf/GENERIC b/sys/arch/powerpc64/conf/GENERIC
index c725e808f33..97af77c8ead 100644
--- a/sys/arch/powerpc64/conf/GENERIC
+++ b/sys/arch/powerpc64/conf/GENERIC
@@ -1,4 +1,4 @@
-# $OpenBSD: GENERIC,v 1.1 2020/05/16 17:11:14 kettenis Exp $
+# $OpenBSD: GENERIC,v 1.2 2020/06/07 13:17:24 kettenis Exp $
#
# For further information on compiling OpenBSD kernels, see the config(8)
# man page.
@@ -16,3 +16,4 @@ maxusers 80
config bsd swap generic
mainbus0 at root
+cpu0 at mainbus?
diff --git a/sys/arch/powerpc64/conf/files.powerpc64 b/sys/arch/powerpc64/conf/files.powerpc64
index 0140d746404..4aaa43e5dc7 100644
--- a/sys/arch/powerpc64/conf/files.powerpc64
+++ b/sys/arch/powerpc64/conf/files.powerpc64
@@ -1,19 +1,8 @@
-# $OpenBSD: files.powerpc64,v 1.4 2020/05/27 22:22:04 gkoehler Exp $
+# $OpenBSD: files.powerpc64,v 1.5 2020/06/07 13:17:24 kettenis Exp $
maxpartitions 16
maxusers 2 8 128
-define fdt {[early = 0]}
-
-define mainbus {}
-device mainbus: fdt
-attach mainbus at root
-
-# FDT support
-include "dev/ofw/files.ofw"
-
-include "scsi/files.scsi"
-
file arch/powerpc64/powerpc64/locore.S
file arch/powerpc64/powerpc64/autoconf.c
file arch/powerpc64/powerpc64/conf.c
@@ -36,3 +25,19 @@ file arch/powerpc64/powerpc64/vm_machdep.c
file netinet/in_cksum.c
file netinet/in4_cksum.c
+
+define fdt {[early = 0]}
+
+# mainbus files
+define mainbus {}
+device mainbus: fdt
+attach mainbus at root
+file arch/powerpc64/dev/mainbus.c mainbus
+
+device cpu {}
+attach cpu at mainbus
+
+# FDT support
+include "dev/ofw/files.ofw"
+
+include "scsi/files.scsi"
diff --git a/sys/arch/powerpc64/dev/mainbus.c b/sys/arch/powerpc64/dev/mainbus.c
new file mode 100644
index 00000000000..b6963ac7f0a
--- /dev/null
+++ b/sys/arch/powerpc64/dev/mainbus.c
@@ -0,0 +1,348 @@
+/* $OpenBSD: mainbus.c,v 1.1 2020/06/07 13:17:24 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
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/device.h>
+#include <sys/malloc.h>
+
+#include <machine/cpufunc.h>
+#include <machine/fdt.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/fdt.h>
+#include <dev/ofw/ofw_thermal.h>
+
+int mainbus_match(struct device *, void *, void *);
+void mainbus_attach(struct device *, struct device *, void *);
+
+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 *);
+
+struct mainbus_softc {
+ struct device sc_dev;
+ int sc_node;
+ bus_space_tag_t sc_iot;
+ bus_dma_tag_t sc_dmat;
+ int sc_acells;
+ int sc_scells;
+ int *sc_ranges;
+ int sc_rangeslen;
+ int sc_early;
+ int sc_early_nodes[64];
+};
+
+struct cfattach mainbus_ca = {
+ sizeof(struct mainbus_softc), mainbus_match, mainbus_attach, NULL,
+ config_activate_children
+};
+
+struct cfdriver mainbus_cd = {
+ NULL, "mainbus", DV_DULL
+};
+
+#if 0
+
+struct machine_bus_dma_tag mainbus_dma_tag = {
+ NULL,
+ 0,
+ _dmamap_create,
+ _dmamap_destroy,
+ _dmamap_load,
+ _dmamap_load_mbuf,
+ _dmamap_load_uio,
+ _dmamap_load_raw,
+ _dmamap_load_buffer,
+ _dmamap_unload,
+ _dmamap_sync,
+ _dmamem_alloc,
+ _dmamem_free,
+ _dmamem_map,
+ _dmamem_unmap,
+ _dmamem_mmap,
+};
+
+#endif
+
+/*
+ * Mainbus takes care of FDT and non-FDT machines, so we
+ * always attach.
+ */
+int
+mainbus_match(struct device *parent, void *cfdata, void *aux)
+{
+ return (1);
+}
+
+extern char *hw_prod;
+extern char *hw_serial;
+
+void
+mainbus_attach(struct device *parent, struct device *self, void *aux)
+{
+ struct mainbus_softc *sc = (struct mainbus_softc *)self;
+ char prop[128];
+ int node, len;
+
+ sc->sc_node = OF_peer(0);
+// sc->sc_iot = &arm64_bs_tag;
+// sc->sc_dmat = &mainbus_dma_tag;
+ sc->sc_acells = OF_getpropint(OF_peer(0), "#address-cells", 1);
+ sc->sc_scells = OF_getpropint(OF_peer(0), "#size-cells", 1);
+
+ len = OF_getprop(sc->sc_node, "model", prop, sizeof(prop));
+ if (len > 0) {
+ printf(": %s\n", prop);
+ hw_prod = malloc(len, M_DEVBUF, M_NOWAIT);
+ if (hw_prod)
+ strlcpy(hw_prod, prop, len);
+ } else
+ printf(": unknown model\n");
+
+ len = OF_getprop(sc->sc_node, "serial-number", prop, sizeof(prop));
+ if (len > 0) {
+ hw_serial = malloc(len, M_DEVBUF, M_NOWAIT);
+ if (hw_serial)
+ strlcpy(hw_serial, prop, len);
+ }
+
+ /* Attach primary CPU first. */
+ mainbus_attach_cpus(self, mainbus_match_primary);
+
+ sc->sc_rangeslen = OF_getproplen(OF_peer(0), "ranges");
+ if (sc->sc_rangeslen > 0 && !(sc->sc_rangeslen % sizeof(uint32_t))) {
+ sc->sc_ranges = malloc(sc->sc_rangeslen, M_TEMP, M_WAITOK);
+ OF_getpropintarray(OF_peer(0), "ranges", sc->sc_ranges,
+ sc->sc_rangeslen);
+ }
+
+ /* Scan the whole tree. */
+ sc->sc_early = 1;
+ for (node = OF_child(sc->sc_node); node != 0; node = OF_peer(node))
+ mainbus_attach_node(self, node, NULL);
+
+ sc->sc_early = 0;
+ for (node = OF_child(sc->sc_node); node != 0; node = OF_peer(node))
+ mainbus_attach_node(self, node, NULL);
+
+ /* Attach secondary CPUs. */
+ mainbus_attach_cpus(self, mainbus_match_secondary);
+}
+
+int
+mainbus_print(void *aux, const char *pnp)
+{
+ struct fdt_attach_args *fa = aux;
+ char buf[32];
+
+ if (!pnp)
+ return (QUIET);
+
+ if (OF_getprop(fa->fa_node, "status", buf, sizeof(buf)) > 0 &&
+ strcmp(buf, "disabled") == 0)
+ return (QUIET);
+
+ if (OF_getprop(fa->fa_node, "name", buf, sizeof(buf)) > 0) {
+ buf[sizeof(buf) - 1] = 0;
+ if (strcmp(buf, "aliases") == 0 ||
+ strcmp(buf, "chosen") == 0 ||
+ strcmp(buf, "cpus") == 0 ||
+ strcmp(buf, "memory") == 0 ||
+ strcmp(buf, "reserved-memory") == 0 ||
+ strcmp(buf, "thermal-zones") == 0 ||
+ strncmp(buf, "__", 2) == 0)
+ return (QUIET);
+ printf("\"%s\"", buf);
+ } else
+ printf("node %u", fa->fa_node);
+
+ printf(" at %s", pnp);
+
+ return (UNCONF);
+}
+
+/*
+ * Look for a driver that wants to be attached to this node.
+ */
+void
+mainbus_attach_node(struct device *self, int node, cfmatch_t submatch)
+{
+ struct mainbus_softc *sc = (struct mainbus_softc *)self;
+ struct fdt_attach_args fa;
+ int i, len, line;
+ uint32_t *cell, *reg;
+ struct device *child;
+ cfprint_t print = NULL;
+
+ /* Skip if already attached early. */
+ for (i = 0; i < nitems(sc->sc_early_nodes); i++) {
+ if (sc->sc_early_nodes[i] == node)
+ return;
+ if (sc->sc_early_nodes[i] == 0)
+ break;
+ }
+
+ memset(&fa, 0, sizeof(fa));
+ fa.fa_name = "";
+ fa.fa_node = node;
+ fa.fa_iot = sc->sc_iot;
+ fa.fa_dmat = sc->sc_dmat;
+ fa.fa_acells = sc->sc_acells;
+ fa.fa_scells = sc->sc_scells;
+
+ len = OF_getproplen(node, "reg");
+ line = (sc->sc_acells + sc->sc_scells) * sizeof(uint32_t);
+ if (len > 0 && (len % line) == 0) {
+ reg = malloc(len, M_TEMP, M_WAITOK);
+ OF_getpropintarray(node, "reg", reg, len);
+
+ fa.fa_reg = malloc((len / line) * sizeof(struct fdt_reg),
+ M_DEVBUF, M_WAITOK);
+ fa.fa_nreg = (len / line);
+
+ for (i = 0, cell = reg; i < len / line; i++) {
+ if (sc->sc_acells >= 1)
+ fa.fa_reg[i].addr = cell[0];
+ if (sc->sc_acells == 2) {
+ fa.fa_reg[i].addr <<= 32;
+ fa.fa_reg[i].addr |= cell[1];
+ }
+ cell += sc->sc_acells;
+ if (sc->sc_scells >= 1)
+ fa.fa_reg[i].size = cell[0];
+ if (sc->sc_scells == 2) {
+ fa.fa_reg[i].size <<= 32;
+ fa.fa_reg[i].size |= cell[1];
+ }
+ cell += sc->sc_scells;
+ }
+
+ free(reg, M_TEMP, len);
+ }
+
+ len = OF_getproplen(node, "interrupts");
+ if (len > 0 && (len % sizeof(uint32_t)) == 0) {
+ fa.fa_intr = malloc(len, M_DEVBUF, M_WAITOK);
+ fa.fa_nintr = len / sizeof(uint32_t);
+
+ OF_getpropintarray(node, "interrupts", fa.fa_intr, len);
+ }
+
+#ifdef notyet
+ if (OF_getproplen(node, "dma-coherent") >= 0) {
+ fa.fa_dmat = malloc(sizeof(*sc->sc_dmat),
+ M_DEVBUF, M_WAITOK | M_ZERO);
+ memcpy(fa.fa_dmat, sc->sc_dmat, sizeof(*sc->sc_dmat));
+ fa.fa_dmat->_flags |= BUS_DMA_COHERENT;
+ }
+#endif
+
+ if (submatch == NULL && sc->sc_early == 0)
+ print = mainbus_print;
+ if (submatch == NULL)
+ submatch = mainbus_match_status;
+
+ child = config_found_sm(self, &fa, print, submatch);
+
+ /* Record nodes that we attach early. */
+ if (child && sc->sc_early) {
+ for (i = 0; i < nitems(sc->sc_early_nodes); i++) {
+ if (sc->sc_early_nodes[i] != 0)
+ continue;
+ sc->sc_early_nodes[i] = node;
+ break;
+ }
+ }
+
+ 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 mainbus_softc *sc = (struct mainbus_softc *)parent;
+ 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;
+
+ if (cf->cf_loc[0] == sc->sc_early)
+ return (*cf->cf_attach->ca_match)(parent, match, aux);
+
+ return 0;
+}
+
+void
+mainbus_attach_cpus(struct device *self, cfmatch_t match)
+{
+ struct mainbus_softc *sc = (struct mainbus_softc *)self;
+ int node = OF_finddevice("/cpus");
+ int acells, scells;
+ char buf[32];
+
+ 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);
+
+ ncpusfound = 0;
+ for (node = OF_child(node); node != 0; node = OF_peer(node)) {
+ if (OF_getprop(node, "device_type", buf, sizeof(buf)) > 0 &&
+ strcmp(buf, "cpu") == 0)
+ ncpusfound++;
+
+ mainbus_attach_node(self, node, match);
+ }
+
+ sc->sc_acells = acells;
+ sc->sc_scells = scells;
+}
+
+int
+mainbus_match_primary(struct device *parent, void *match, void *aux)
+{
+ struct fdt_attach_args *fa = aux;
+ struct cfdata *cf = match;
+
+ if (fa->fa_nreg < 1 || fa->fa_reg[0].addr != mfpir())
+ return 0;
+
+ 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;
+
+ if (fa->fa_nreg < 1 || fa->fa_reg[0].addr == mfpir())
+ return 0;
+
+ return (*cf->cf_attach->ca_match)(parent, match, aux);
+}
diff --git a/sys/arch/powerpc64/include/bus.h b/sys/arch/powerpc64/include/bus.h
index 2ed5a1df9b1..abd61063a5f 100644
--- a/sys/arch/powerpc64/include/bus.h
+++ b/sys/arch/powerpc64/include/bus.h
@@ -10,4 +10,7 @@ typedef struct bus_space *bus_space_tag_t;
#define bus_space_write_4(t, h, o, v)
#define bus_space_read_4(t, h, o) 0xffffffff
+struct bus_dma_tag;
+typedef struct bus_dma_tag *bus_dma_tag_t;
+
#endif /* _MACHINE_BUS_H_ */
diff --git a/sys/arch/powerpc64/include/cpufunc.h b/sys/arch/powerpc64/include/cpufunc.h
index 69fe4fa6834..9568b018188 100644
--- a/sys/arch/powerpc64/include/cpufunc.h
+++ b/sys/arch/powerpc64/include/cpufunc.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: cpufunc.h,v 1.2 2020/06/06 22:36:22 kettenis Exp $ */
+/* $OpenBSD: cpufunc.h,v 1.3 2020/06/07 13:17:24 kettenis Exp $ */
/*
* Copyright (c) 2020 Mark Kettenis <kettenis@openbsd.org>
@@ -139,6 +139,14 @@ mtptcr(uint64_t value)
__asm volatile ("mtspr 464, %0" :: "r"(value));
}
+static inline uint32_t
+mfpir(void)
+{
+ uint32_t value;
+ __asm volatile ("mfspr %0, 1023" : "=r"(value));
+ return value;
+}
+
extern int cacheline_size;
void __syncicache(void *, size_t);
diff --git a/sys/arch/powerpc64/powerpc64/autoconf.c b/sys/arch/powerpc64/powerpc64/autoconf.c
index 4db1875d28f..be6b4420fef 100644
--- a/sys/arch/powerpc64/powerpc64/autoconf.c
+++ b/sys/arch/powerpc64/powerpc64/autoconf.c
@@ -22,26 +22,3 @@ device_register(struct device *dev, void *aux)
struct nam2blk nam2blk[] = {
{ NULL, -1 }
};
-
-int mainbus_match(struct device *, void *, void *);
-void mainbus_attach(struct device *, struct device *, void *);
-
-struct cfattach mainbus_ca = {
- sizeof(struct device), mainbus_match, mainbus_attach
-};
-
-struct cfdriver mainbus_cd = {
- NULL, "mainbus", DV_DULL
-};
-
-int
-mainbus_match(struct device *parent, void *cfdata, void *aux)
-{
- return 1;
-}
-
-void
-mainbus_attach(struct device *parent, struct device *self, void *aux)
-{
- printf("\n");
-}
diff --git a/sys/arch/powerpc64/powerpc64/cpu.c b/sys/arch/powerpc64/powerpc64/cpu.c
index 016570bff59..d8e5bc85228 100644
--- a/sys/arch/powerpc64/powerpc64/cpu.c
+++ b/sys/arch/powerpc64/powerpc64/cpu.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cpu.c,v 1.3 2020/06/07 12:14:08 kettenis Exp $ */
+/* $OpenBSD: cpu.c,v 1.4 2020/06/07 13:17:24 kettenis Exp $ */
/*
* Copyright (c) 2020 Mark Kettenis <kettenis@openbsd.org>
@@ -17,9 +17,59 @@
*/
#include <sys/param.h>
+#include <sys/device.h>
+#include <sys/systm.h>
#include <machine/cpu.h>
+#include <machine/cpufunc.h>
+#include <machine/fdt.h>
+
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/fdt.h>
char cpu_model[64];
struct cpu_info cpu_info_primary;
+
+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
+};
+
+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 0;
+
+ if (ncpus < MAXCPUS || faa->fa_reg[0].addr == mfpir())
+ return 1;
+
+ return 0;
+}
+
+void
+cpu_attach(struct device *parent, struct device *dev, void *aux)
+{
+ struct fdt_attach_args *faa = aux;
+ char name[64];
+
+ printf(" pir %llx:", faa->fa_reg[0].addr);
+
+ if (OF_getprop(faa->fa_node, "name", &name, sizeof(name)) > 0) {
+ name[sizeof(name) - 1] = 0;
+ printf(" %s", name);
+ }
+
+ printf("\n");
+}