Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F157790659
D24423.id72701.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
15 KB
Referenced Files
None
Subscribers
None
D24423.id72701.diff
View Options
Index: sys/arm/arm/pmu.h
===================================================================
--- /dev/null
+++ sys/arm/arm/pmu.h
@@ -0,0 +1,67 @@
+/*-
+ * Copyright (c) 2015 Ruslan Bukin <br@bsdpad.com>
+ * 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.
+ */
+
+#ifndef _ARM_PMU_H_
+#define _ARM_PMU_H_
+
+#include <sys/rman.h>
+
+#ifdef notyet
+#define MAX_RLEN 8
+#else
+#define MAX_RLEN 1
+#endif
+
+struct pmu_softc {
+ struct resource *res[MAX_RLEN];
+ device_t dev;
+ void *ih[MAX_RLEN];
+ bool intr_per_core;
+};
+
+int pmu_attach(device_t dev);
+int pmu_intr(void *arg);
+
+static struct resource_spec pmu_spec[] = {
+ { SYS_RES_IRQ, 0, RF_ACTIVE },
+ /* We don't currently handle pmu events, other than on cpu 0 */
+#ifdef notyet
+ { SYS_RES_IRQ, 1, RF_ACTIVE | RF_OPTIONAL },
+ { SYS_RES_IRQ, 2, RF_ACTIVE | RF_OPTIONAL },
+ { SYS_RES_IRQ, 3, RF_ACTIVE | RF_OPTIONAL },
+ { SYS_RES_IRQ, 4, RF_ACTIVE | RF_OPTIONAL },
+ { SYS_RES_IRQ, 5, RF_ACTIVE | RF_OPTIONAL },
+ { SYS_RES_IRQ, 6, RF_ACTIVE | RF_OPTIONAL },
+ { SYS_RES_IRQ, 7, RF_ACTIVE | RF_OPTIONAL },
+#endif
+ { -1, 0 }
+};
+
+#endif
Index: sys/arm/arm/pmu.c
===================================================================
--- sys/arm/arm/pmu.c
+++ sys/arm/arm/pmu.c
@@ -50,42 +50,11 @@
#include <sys/pmc.h>
#include <sys/pmckern.h>
-#ifdef FDT
-#include <dev/ofw/openfirm.h>
-#include <dev/ofw/ofw_bus.h>
-#include <dev/ofw/ofw_bus_subr.h>
-#endif
-
#include <machine/bus.h>
#include <machine/cpu.h>
#include <machine/intr.h>
-#ifdef notyet
-#define MAX_RLEN 8
-#else
-#define MAX_RLEN 1
-#endif
-
-struct pmu_softc {
- struct resource *res[MAX_RLEN];
- device_t dev;
- void *ih[MAX_RLEN];
-};
-
-static struct resource_spec pmu_spec[] = {
- { SYS_RES_IRQ, 0, RF_ACTIVE },
- /* We don't currently handle pmu events, other than on cpu 0 */
-#ifdef notyet
- { SYS_RES_IRQ, 1, RF_ACTIVE | RF_OPTIONAL },
- { SYS_RES_IRQ, 2, RF_ACTIVE | RF_OPTIONAL },
- { SYS_RES_IRQ, 3, RF_ACTIVE | RF_OPTIONAL },
- { SYS_RES_IRQ, 4, RF_ACTIVE | RF_OPTIONAL },
- { SYS_RES_IRQ, 5, RF_ACTIVE | RF_OPTIONAL },
- { SYS_RES_IRQ, 6, RF_ACTIVE | RF_OPTIONAL },
- { SYS_RES_IRQ, 7, RF_ACTIVE | RF_OPTIONAL },
-#endif
- { -1, 0 }
-};
+#include "pmu.h"
/* CCNT */
#if __ARM_ARCH > 6
@@ -96,7 +65,7 @@
#define PMU_OVSR_C 0x80000000 /* Cycle Counter */
#define PMU_IESR_C 0x80000000 /* Cycle Counter */
-static int
+int
pmu_intr(void *arg)
{
#ifdef HWPMC_HOOKS
@@ -130,36 +99,12 @@
return (FILTER_HANDLED);
}
-static int
+int
pmu_attach(device_t dev)
{
- struct pmu_softc *sc;
#if defined(__arm__) && (__ARM_ARCH > 6)
uint32_t iesr;
#endif
- int err;
- int i;
-
- sc = device_get_softc(dev);
- sc->dev = dev;
-
- if (bus_alloc_resources(dev, pmu_spec, sc->res)) {
- device_printf(dev, "could not allocate resources\n");
- return (ENXIO);
- }
-
- /* Setup interrupt handler */
- for (i = 0; i < MAX_RLEN; i++) {
- if (sc->res[i] == NULL)
- break;
-
- err = bus_setup_intr(dev, sc->res[i], INTR_MPSAFE | INTR_TYPE_MISC,
- pmu_intr, NULL, NULL, &sc->ih[i]);
- if (err) {
- device_printf(dev, "Unable to setup interrupt handler.\n");
- return (ENXIO);
- }
- }
#if defined(__arm__) && (__ARM_ARCH > 6)
/* Initialize to 0. */
@@ -177,52 +122,3 @@
return (0);
}
-
-#ifdef FDT
-static struct ofw_compat_data compat_data[] = {
- {"arm,armv8-pmuv3", 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
Index: sys/arm/arm/pmu_acpi.c
===================================================================
--- /dev/null
+++ sys/arm/arm/pmu_acpi.c
@@ -0,0 +1,208 @@
+/*-
+ * Copyright (c) 2020 Greg V <greg@unrelenting.technology>
+ *
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+
+#include <contrib/dev/acpica/include/acpi.h>
+#include <dev/acpica/acpivar.h>
+
+#include <arm/arm/gic_common.h>
+
+#include "acpi_bus_if.h"
+#include "pmu.h"
+
+struct madt_ctx {
+ device_t parent;
+ device_t dev;
+
+ int32_t cpuid;
+ bool is_per_core;
+};
+
+static void
+madt_handler(ACPI_SUBTABLE_HEADER *entry, void *arg)
+{
+ ACPI_MADT_GENERIC_INTERRUPT *intr;
+ struct madt_ctx *ctx = arg;
+ struct acpi_device *ad;
+ rman_res_t irq;
+
+ if (entry->Type != ACPI_MADT_TYPE_GENERIC_INTERRUPT)
+ return;
+
+ intr = (ACPI_MADT_GENERIC_INTERRUPT *)entry;
+
+ if (bootverbose)
+ device_printf(ctx->dev, "MADT: cpu/rid %d irq %d %s-triggered\n",
+ ctx->cpuid,
+ intr->PerformanceInterrupt,
+ (intr->Flags & ACPI_MADT_PERFORMANCE_IRQ_MODE) ? "edge" : "level");
+
+ if (ctx->cpuid > MAX_RLEN)
+ return;
+
+ /*
+ * BUS_CONFIG_INTR does nothing on arm64, so we manually register an IRQ
+ * resource with correct trigger mode instead of doing BUS_SET_RESOURCE.
+ */
+ irq = (rman_res_t)ACPI_BUS_MAP_INTR(ctx->parent, ctx->dev,
+ intr->PerformanceInterrupt,
+ (intr->Flags & ACPI_MADT_PERFORMANCE_IRQ_MODE) ?
+ INTR_TRIGGER_EDGE : INTR_TRIGGER_LEVEL,
+ INTR_POLARITY_HIGH);
+ ad = device_get_ivars(ctx->dev);
+ resource_list_add(&ad->ad_rl, SYS_RES_IRQ,
+ ctx->cpuid++, irq, irq, 1);
+
+ /*
+ * We have to bind the interrupts to CPUs if the PMU uses multiple
+ * per-core SPIs, but not if it uses a single PPI.
+ *
+ * AArch64 ACPI systems always use the GIC, so this check is correct.
+ */
+ if (intr->PerformanceInterrupt >= GIC_FIRST_SPI)
+ ctx->is_per_core = true;
+}
+
+static void
+pmu_acpi_identify(driver_t *driver, device_t parent)
+{
+ ACPI_TABLE_MADT *madt;
+ vm_paddr_t physaddr;
+ device_t dev;
+ struct madt_ctx ctx;
+
+ physaddr = acpi_find_table(ACPI_SIG_MADT);
+ if (physaddr == 0)
+ return;
+
+ madt = acpi_map_table(physaddr, ACPI_SIG_MADT);
+ if (madt == NULL) {
+ device_printf(parent, "pmu: Unable to map the MADT table\n");
+ return;
+ }
+
+ dev = BUS_ADD_CHILD(parent, BUS_PASS_INTERRUPT + BUS_PASS_ORDER_LAST,
+ "pmu", -1);
+ if (dev == NULL) {
+ device_printf(parent, "pmu: Unable to add pmu child\n");
+ goto out;
+ }
+
+ /*
+ * CPUs are attached in MADT order (sys/arm64/arm64/mp_machdep.c),
+ * with cpuid incremented for each ACPI_MADT_GENERIC_INTERRUPT, so
+ * we are getting the right cpuids by walking the same way.
+ */
+ ctx.parent = parent;
+ ctx.dev = dev;
+ ctx.cpuid = 0;
+ ctx.is_per_core = false;
+ acpi_walk_subtables(madt + 1, (char *)madt + madt->Header.Length,
+ madt_handler, &ctx);
+ acpi_set_private(dev, (void *)ctx.is_per_core);
+
+out:
+ acpi_unmap_table(madt);
+}
+
+static int
+pmu_acpi_probe(device_t dev)
+{
+ struct pmu_softc *sc;
+
+ device_set_desc(dev, "Performance Monitoring Unit");
+ sc = device_get_softc(dev);
+ sc->intr_per_core = (bool)acpi_get_private(dev);
+
+ return (BUS_PROBE_NOWILDCARD);
+}
+
+static int
+pmu_acpi_attach(device_t dev)
+{
+ struct pmu_softc *sc;
+ int err;
+ int i;
+
+ sc = device_get_softc(dev);
+ sc->dev = dev;
+
+ if (bus_alloc_resources(dev, pmu_spec, sc->res)) {
+ device_printf(dev, "could not allocate resources\n");
+ return (ENXIO);
+ }
+
+ device_printf(dev, sc->intr_per_core
+ ? "using per-core SPIs\n" : "using a single PPI\n");
+
+ /* Setup interrupt handler */
+ for (i = 0; i < MAX_RLEN; i++) {
+ if (sc->res[i] == NULL)
+ break;
+
+ err = bus_setup_intr(dev, sc->res[i], INTR_MPSAFE | INTR_TYPE_MISC,
+ pmu_intr, NULL, NULL, &sc->ih[i]);
+ if (err) {
+ device_printf(dev, "Unable to setup interrupt handler.\n");
+ return (ENXIO);
+ }
+
+ if (sc->intr_per_core) {
+ /* Above, we set resource IDs to match CPUs by walking MADT in order */
+ err = bus_bind_intr(dev, sc->res[i], i);
+ if (err) {
+ device_printf(dev, "Unable to bind interrupt handler to CPU.\n");
+ return (ENXIO);
+ }
+ }
+ }
+
+ return (pmu_attach(dev));
+}
+
+static device_method_t pmu_acpi_methods[] = {
+ DEVMETHOD(device_identify, pmu_acpi_identify),
+ DEVMETHOD(device_probe, pmu_acpi_probe),
+ DEVMETHOD(device_attach, pmu_acpi_attach),
+ DEVMETHOD_END,
+};
+
+static driver_t pmu_acpi_driver = {
+ "pmu",
+ pmu_acpi_methods,
+ sizeof(struct pmu_softc),
+};
+
+static devclass_t pmu_acpi_devclass;
+
+DRIVER_MODULE(pmu, acpi, pmu_acpi_driver, pmu_acpi_devclass, 0, 0);
Index: sys/arm/arm/pmu_fdt.c
===================================================================
--- /dev/null
+++ sys/arm/arm/pmu_fdt.c
@@ -0,0 +1,125 @@
+/*-
+ * Copyright (c) 2015 Ruslan Bukin <br@bsdpad.com>
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include "pmu.h"
+
+static struct ofw_compat_data compat_data[] = {
+ {"arm,armv8-pmuv3", 1},
+ {"arm,cortex-a73-pmu", 1},
+ {"arm,cortex-a72-pmu", 1},
+ {"arm,cortex-a57-pmu", 1},
+ {"arm,cortex-a53-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_fdt_attach(device_t dev)
+{
+ struct pmu_softc *sc;
+ int err;
+ int i;
+
+ sc = device_get_softc(dev);
+ sc->dev = dev;
+
+ if (bus_alloc_resources(dev, pmu_spec, sc->res)) {
+ device_printf(dev, "could not allocate resources\n");
+ return (ENXIO);
+ }
+
+ /* Setup interrupt handler */
+ for (i = 0; i < MAX_RLEN; i++) {
+ if (sc->res[i] == NULL)
+ break;
+
+ err = bus_setup_intr(dev, sc->res[i], INTR_MPSAFE | INTR_TYPE_MISC,
+ pmu_intr, NULL, NULL, &sc->ih[i]);
+ if (err) {
+ device_printf(dev, "Unable to setup interrupt handler.\n");
+ return (ENXIO);
+ }
+ }
+
+ 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);
Index: sys/conf/files.arm64
===================================================================
--- sys/conf/files.arm64
+++ sys/conf/files.arm64
@@ -85,6 +85,8 @@
arm/arm/gic_acpi.c optional acpi
arm/arm/gic_fdt.c optional fdt
arm/arm/pmu.c standard
+arm/arm/pmu_acpi.c optional acpi
+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
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, May 26, 5:42 AM (14 h, 47 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33525030
Default Alt Text
D24423.id72701.diff (15 KB)
Attached To
Mode
D24423: arm/pmu: add ACPI attachment
Attached
Detach File
Event Timeline
Log In to Comment