From owner-dev-commits-src-main@freebsd.org Wed Dec 30 16:20:21 2020 Return-Path: Delivered-To: dev-commits-src-main@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 9FBFA4C810A; Wed, 30 Dec 2020 16:20:21 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4D5c2Y48nrz3rQx; Wed, 30 Dec 2020 16:20:21 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 81A2B20D67; Wed, 30 Dec 2020 16:20:21 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 0BUGKLIs061855; Wed, 30 Dec 2020 16:20:21 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 0BUGKLG4061854; Wed, 30 Dec 2020 16:20:21 GMT (envelope-from git) Date: Wed, 30 Dec 2020 16:20:21 GMT Message-Id: <202012301620.0BUGKLG4061854@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Andrew Turner Subject: git: 5e78bbb74a1f - main - Split out the FDT arm pmu attachment MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: andrew X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 5e78bbb74a1f55c6213f99eda0ec87e81731a369 Auto-Submitted: auto-generated X-BeenThere: dev-commits-src-main@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: "Commit messages for the main branch of the src repository." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 30 Dec 2020 16:20:21 -0000 The branch main has been updated by andrew: URL: https://cgit.FreeBSD.org/src/commit/?id=5e78bbb74a1f55c6213f99eda0ec87e81731a369 commit 5e78bbb74a1f55c6213f99eda0ec87e81731a369 Author: Andrew Turner AuthorDate: 2020-12-30 14:20:28 +0000 Commit: Andrew Turner CommitDate: 2020-12-30 16:11:02 +0000 Split out the FDT arm pmu attachment This will allow us to add an ACPI attachment. Submitted by: Greg V (earlier version) Sponsored by: Innovate UK --- sys/arm/arm/pmu.c | 209 +------------------------------------------ sys/arm/arm/pmu_fdt.c | 239 ++++++++++++++++++++++++++++++++++++++++++++++++++ sys/conf/files.arm | 3 +- sys/conf/files.arm64 | 1 + 4 files changed, 245 insertions(+), 207 deletions(-) diff --git a/sys/arm/arm/pmu.c b/sys/arm/arm/pmu.c index b16ffcafcfac..544962e9ab28 100644 --- a/sys/arm/arm/pmu.c +++ b/sys/arm/arm/pmu.c @@ -36,7 +36,6 @@ __FBSDID("$FreeBSD$"); #include "opt_hwpmc_hooks.h" -#include "opt_platform.h" #include #include @@ -50,31 +49,14 @@ __FBSDID("$FreeBSD$"); #include #include -#ifdef FDT -#include -#include -#include -#endif - #include #include #include -#define MAX_RLEN 8 - -struct pmu_intr { - struct resource *res; - void *ih; - int cpuid; -}; - -struct pmu_softc { - device_t dev; - struct pmu_intr irq[MAX_RLEN]; -}; +#include "pmu.h" /* CCNT */ -#if __ARM_ARCH > 6 +#if defined(__arm__) && (__ARM_ARCH > 6) int pmu_attched = 0; uint32_t ccnt_hi[MAXCPU]; #endif @@ -116,129 +98,7 @@ pmu_intr(void *arg) return (FILTER_HANDLED); } -static int -pmu_parse_affinity(struct pmu_softc *sc, struct pmu_intr *irq, phandle_t xref, - uint32_t mpidr) -{ - struct pcpu *pcpu; - int i, err; - - - if (xref != 0) { - err = OF_getencprop(OF_node_from_xref(xref), "reg", &mpidr, - sizeof(mpidr)); - if (err < 0) { - device_printf(sc->dev, "missing 'reg' property\n"); - return (ENXIO); - } - } - - for (i = 0; i < MAXCPU; i++) { - pcpu = pcpu_find(i); - if (pcpu != NULL && pcpu->pc_mpidr == mpidr) { - irq->cpuid = i; - return (0); - } - } - - device_printf(sc->dev, "Cannot find CPU with MPIDR: 0x%08X\n", mpidr); - return (ENXIO); -} - -static int -pmu_parse_intr(struct pmu_softc *sc) -{ - bool has_affinity; - phandle_t node, *cpus; - int rid, err, ncpus, i; - - - node = ofw_bus_get_node(sc->dev); - has_affinity = OF_hasprop(node, "interrupt-affinity"); - - for (i = 0; i < MAX_RLEN; i++) - sc->irq[i].cpuid = -1; - - cpus = NULL; - if (has_affinity) { - ncpus = OF_getencprop_alloc_multi(node, "interrupt-affinity", - sizeof(*cpus), (void **)&cpus); - if (ncpus < 0) { - device_printf(sc->dev, - "Cannot read interrupt affinity property\n"); - return (ENXIO); - } - } - - /* Process first interrupt */ - rid = 0; - sc->irq[0].res = bus_alloc_resource_any(sc->dev, SYS_RES_IRQ, &rid, - RF_ACTIVE | RF_SHAREABLE); - - if (sc->irq[0].res == NULL) { - device_printf(sc->dev, "Cannot get interrupt\n"); - err = ENXIO; - goto done; - } - - /* Check if PMU have one per-CPU interrupt */ - if (intr_is_per_cpu(sc->irq[0].res)) { - if (has_affinity) { - device_printf(sc->dev, - "Per CPU interupt have declared affinity\n"); - err = ENXIO; - goto done; - } - return (0); - } - - /* - * PMU with set of generic interrupts (one per core) - * Each one must be binded to exact core. - */ - err = pmu_parse_affinity(sc, sc->irq + 0, has_affinity ? cpus[0]: 0, - 0); - if (err != 0) { - device_printf(sc->dev, "Cannot parse affinity for CPUid: 0\n"); - goto done; - } - - for (i = 1; i < MAX_RLEN; i++) { - rid = i; - sc->irq[i].res = bus_alloc_resource_any(sc->dev, SYS_RES_IRQ, - &rid, RF_ACTIVE | RF_SHAREABLE); - if (sc->irq[i].res == NULL) - break; - - if (intr_is_per_cpu(sc->irq[i].res)) - { - device_printf(sc->dev, "Unexpected per CPU interupt\n"); - err = ENXIO; - goto done; - } - - if (has_affinity && i >= ncpus) { - device_printf(sc->dev, "Missing value in interrupt " - "affinity property\n"); - err = ENXIO; - goto done; - } - - err = pmu_parse_affinity(sc, sc->irq + i, - has_affinity ? cpus[i]: 0, i); - if (err != 0) { - device_printf(sc->dev, - "Cannot parse affinity for CPUid: %d.\n", i); - goto done; - } - } - err = 0; -done: - OF_prop_free(cpus); - return (err); -} - -static int +int pmu_attach(device_t dev) { struct pmu_softc *sc; @@ -250,10 +110,6 @@ pmu_attach(device_t dev) sc = device_get_softc(dev); sc->dev = dev; - err = pmu_parse_intr(sc); - if (err != 0) - return (err); - for (i = 0; i < MAX_RLEN; i++) { if (sc->irq[i].res == NULL) break; @@ -303,62 +159,3 @@ fail: return(err); } -#ifdef FDT -static struct ofw_compat_data compat_data[] = { - {"arm,armv8-pmuv3", 1}, - {"arm,cortex-a77-pmu", 1}, - {"arm,cortex-a76-pmu", 1}, - {"arm,cortex-a75-pmu", 1}, - {"arm,cortex-a73-pmu", 1}, - {"arm,cortex-a72-pmu", 1}, - {"arm,cortex-a65-pmu", 1}, - {"arm,cortex-a57-pmu", 1}, - {"arm,cortex-a55-pmu", 1}, - {"arm,cortex-a53-pmu", 1}, - {"arm,cortex-a34-pmu", 1}, - - {"arm,cortex-a17-pmu", 1}, - {"arm,cortex-a15-pmu", 1}, - {"arm,cortex-a12-pmu", 1}, - {"arm,cortex-a9-pmu", 1}, - {"arm,cortex-a8-pmu", 1}, - {"arm,cortex-a7-pmu", 1}, - {"arm,cortex-a5-pmu", 1}, - {"arm,arm11mpcore-pmu", 1}, - {"arm,arm1176-pmu", 1}, - {"arm,arm1136-pmu", 1}, - {"qcom,krait-pmu", 1}, - {NULL, 0} -}; - -static int -pmu_fdt_probe(device_t dev) -{ - - if (!ofw_bus_status_okay(dev)) - return (ENXIO); - - if (ofw_bus_search_compatible(dev, compat_data)->ocd_data != 0) { - device_set_desc(dev, "Performance Monitoring Unit"); - return (BUS_PROBE_DEFAULT); - } - - return (ENXIO); -} - -static device_method_t pmu_fdt_methods[] = { - DEVMETHOD(device_probe, pmu_fdt_probe), - DEVMETHOD(device_attach, pmu_attach), - { 0, 0 } -}; - -static driver_t pmu_fdt_driver = { - "pmu", - pmu_fdt_methods, - sizeof(struct pmu_softc), -}; - -static devclass_t pmu_fdt_devclass; - -DRIVER_MODULE(pmu, simplebus, pmu_fdt_driver, pmu_fdt_devclass, 0, 0); -#endif diff --git a/sys/arm/arm/pmu_fdt.c b/sys/arm/arm/pmu_fdt.c new file mode 100644 index 000000000000..2e03fc98bfe0 --- /dev/null +++ b/sys/arm/arm/pmu_fdt.c @@ -0,0 +1,239 @@ +/*- + * Copyright (c) 2015 Ruslan Bukin + * All rights reserved. + * + * This software was developed by SRI International and the University of + * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237) + * ("CTSRD"), as part of the DARPA CRASH research programme. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 THE AUTHOR 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. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "pmu.h" + +static struct ofw_compat_data compat_data[] = { + {"arm,armv8-pmuv3", 1}, + {"arm,cortex-a77-pmu", 1}, + {"arm,cortex-a76-pmu", 1}, + {"arm,cortex-a75-pmu", 1}, + {"arm,cortex-a73-pmu", 1}, + {"arm,cortex-a72-pmu", 1}, + {"arm,cortex-a65-pmu", 1}, + {"arm,cortex-a57-pmu", 1}, + {"arm,cortex-a55-pmu", 1}, + {"arm,cortex-a53-pmu", 1}, + {"arm,cortex-a34-pmu", 1}, + + {"arm,cortex-a17-pmu", 1}, + {"arm,cortex-a15-pmu", 1}, + {"arm,cortex-a12-pmu", 1}, + {"arm,cortex-a9-pmu", 1}, + {"arm,cortex-a8-pmu", 1}, + {"arm,cortex-a7-pmu", 1}, + {"arm,cortex-a5-pmu", 1}, + {"arm,arm11mpcore-pmu", 1}, + {"arm,arm1176-pmu", 1}, + {"arm,arm1136-pmu", 1}, + {"qcom,krait-pmu", 1}, + {NULL, 0} +}; + +static int +pmu_fdt_probe(device_t dev) +{ + + if (!ofw_bus_status_okay(dev)) + return (ENXIO); + + if (ofw_bus_search_compatible(dev, compat_data)->ocd_data != 0) { + device_set_desc(dev, "Performance Monitoring Unit"); + return (BUS_PROBE_DEFAULT); + } + + return (ENXIO); +} + +static int +pmu_parse_affinity(device_t dev, struct pmu_softc *sc, struct pmu_intr *irq, + phandle_t xref, uint32_t mpidr) +{ + struct pcpu *pcpu; + int i, err; + + + if (xref != 0) { + err = OF_getencprop(OF_node_from_xref(xref), "reg", &mpidr, + sizeof(mpidr)); + if (err < 0) { + device_printf(dev, "missing 'reg' property\n"); + return (ENXIO); + } + } + + for (i = 0; i < MAXCPU; i++) { + pcpu = pcpu_find(i); + if (pcpu != NULL && pcpu->pc_mpidr == mpidr) { + irq->cpuid = i; + return (0); + } + } + + device_printf(dev, "Cannot find CPU with MPIDR: 0x%08X\n", mpidr); + return (ENXIO); +} + +static int +pmu_parse_intr(device_t dev, struct pmu_softc *sc) +{ + bool has_affinity; + phandle_t node, *cpus; + int rid, err, ncpus, i; + + + node = ofw_bus_get_node(dev); + has_affinity = OF_hasprop(node, "interrupt-affinity"); + + for (i = 0; i < MAX_RLEN; i++) + sc->irq[i].cpuid = -1; + + cpus = NULL; + if (has_affinity) { + ncpus = OF_getencprop_alloc_multi(node, "interrupt-affinity", + sizeof(*cpus), (void **)&cpus); + if (ncpus < 0) { + device_printf(dev, + "Cannot read interrupt affinity property\n"); + return (ENXIO); + } + } + + /* Process first interrupt */ + rid = 0; + sc->irq[0].res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, + RF_ACTIVE | RF_SHAREABLE); + + if (sc->irq[0].res == NULL) { + device_printf(dev, "Cannot get interrupt\n"); + err = ENXIO; + goto done; + } + + /* Check if PMU have one per-CPU interrupt */ + if (intr_is_per_cpu(sc->irq[0].res)) { + if (has_affinity) { + device_printf(dev, + "Per CPU interupt have declared affinity\n"); + err = ENXIO; + goto done; + } + return (0); + } + + /* + * PMU with set of generic interrupts (one per core) + * Each one must be binded to exact core. + */ + err = pmu_parse_affinity(dev, sc, sc->irq + 0, + has_affinity ? cpus[0] : 0, 0); + if (err != 0) { + device_printf(dev, "Cannot parse affinity for CPUid: 0\n"); + goto done; + } + + for (i = 1; i < MAX_RLEN; i++) { + rid = i; + sc->irq[i].res = bus_alloc_resource_any(dev, SYS_RES_IRQ, + &rid, RF_ACTIVE | RF_SHAREABLE); + if (sc->irq[i].res == NULL) + break; + + if (intr_is_per_cpu(sc->irq[i].res)) + { + device_printf(dev, "Unexpected per CPU interupt\n"); + err = ENXIO; + goto done; + } + + if (has_affinity && i >= ncpus) { + device_printf(dev, "Missing value in interrupt " + "affinity property\n"); + err = ENXIO; + goto done; + } + + err = pmu_parse_affinity(dev, sc, sc->irq + i, + has_affinity ? cpus[i] : 0, i); + if (err != 0) { + device_printf(dev, + "Cannot parse affinity for CPUid: %d.\n", i); + goto done; + } + } + err = 0; +done: + OF_prop_free(cpus); + return (err); +} + +static int +pmu_fdt_attach(device_t dev) +{ + struct pmu_softc *sc; + int err; + + sc = device_get_softc(dev); + err = pmu_parse_intr(dev, sc); + if (err != 0) + return (err); + + return (pmu_attach(dev)); +} + +static device_method_t pmu_fdt_methods[] = { + DEVMETHOD(device_probe, pmu_fdt_probe), + DEVMETHOD(device_attach, pmu_fdt_attach), + { 0, 0 } +}; + +static driver_t pmu_fdt_driver = { + "pmu", + pmu_fdt_methods, + sizeof(struct pmu_softc), +}; + +static devclass_t pmu_fdt_devclass; + +DRIVER_MODULE(pmu, simplebus, pmu_fdt_driver, pmu_fdt_devclass, 0, 0); diff --git a/sys/conf/files.arm b/sys/conf/files.arm index 13a47e5b6f5a..eb3a23b5fc21 100644 --- a/sys/conf/files.arm +++ b/sys/conf/files.arm @@ -56,7 +56,8 @@ arm/arm/platform.c optional platform arm/arm/platform_if.m optional platform arm/arm/platform_pl310_if.m optional platform pl310 arm/arm/pmap-v6.c standard -arm/arm/pmu.c optional pmu | fdt hwpmc +arm/arm/pmu.c optional pmu | hwpmc +arm/arm/pmu_fdt.c optional fdt pmu | fdt hwpmc arm/arm/ptrace_machdep.c standard arm/arm/sc_machdep.c optional sc arm/arm/setcpsr.S standard diff --git a/sys/conf/files.arm64 b/sys/conf/files.arm64 index 439b37c12cd0..f421304b1903 100644 --- a/sys/conf/files.arm64 +++ b/sys/conf/files.arm64 @@ -85,6 +85,7 @@ arm/arm/gic.c standard arm/arm/gic_acpi.c optional acpi arm/arm/gic_fdt.c optional fdt arm/arm/pmu.c standard +arm/arm/pmu_fdt.c optional fdt arm/broadcom/bcm2835/bcm2835_audio.c optional sound vchiq fdt \ compile-with "${NORMAL_C} -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" arm/broadcom/bcm2835/bcm2835_bsc.c optional bcm2835_bsc fdt