diff options
author | 2020-06-07 13:17:24 +0000 | |
---|---|---|
committer | 2020-06-07 13:17:24 +0000 | |
commit | 8c07258a3b11c528c4ed3a63093815e7afb97ad6 (patch) | |
tree | 5fbc0a78d3307541f24874ce20e517171f6ccb24 | |
parent | Allocate a struct, not just a pointer. (diff) | |
download | wireguard-openbsd-8c07258a3b11c528c4ed3a63093815e7afb97ad6.tar.xz wireguard-openbsd-8c07258a3b11c528c4ed3a63093815e7afb97ad6.zip |
mainbus(4) and cpu(4).
-rw-r--r-- | sys/arch/powerpc64/conf/GENERIC | 3 | ||||
-rw-r--r-- | sys/arch/powerpc64/conf/files.powerpc64 | 29 | ||||
-rw-r--r-- | sys/arch/powerpc64/dev/mainbus.c | 348 | ||||
-rw-r--r-- | sys/arch/powerpc64/include/bus.h | 3 | ||||
-rw-r--r-- | sys/arch/powerpc64/include/cpufunc.h | 10 | ||||
-rw-r--r-- | sys/arch/powerpc64/powerpc64/autoconf.c | 23 | ||||
-rw-r--r-- | sys/arch/powerpc64/powerpc64/cpu.c | 52 |
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"); +} |