svn commit: r367214 - stable/12/sys/arm64/arm64
Michal Meloun
mmel at FreeBSD.org
Sat Oct 31 15:40:53 UTC 2020
Author: mmel
Date: Sat Oct 31 15:40:52 2020
New Revision: 367214
URL: https://svnweb.freebsd.org/changeset/base/367214
Log:
MFC r360466:
Export tracing facility of GIC500 ITS block. Possibility of tracing of
processing message based interrupts is very useful for debugging of PCIe
driver, mainly for its MSI part.
Modified:
stable/12/sys/arm64/arm64/gic_v3_reg.h
stable/12/sys/arm64/arm64/gicv3_its.c
Directory Properties:
stable/12/ (props changed)
Modified: stable/12/sys/arm64/arm64/gic_v3_reg.h
==============================================================================
--- stable/12/sys/arm64/arm64/gic_v3_reg.h Sat Oct 31 15:38:41 2020 (r367213)
+++ stable/12/sys/arm64/arm64/gic_v3_reg.h Sat Oct 31 15:40:52 2020 (r367214)
@@ -220,6 +220,8 @@
(rev) << GITS_IIDR_REVISION_SHIFT | \
(impl) << GITS_IIDR_IMPLEMENTOR_SHIFT)
+#define GITS_IIDR_IMPL_ARM (0x43B)
+#define GITS_IIDR_PROD_GIC500 (0x0)
#define GITS_IIDR_IMPL_CAVIUM (0x34c)
#define GITS_IIDR_PROD_THUNDER (0xa1)
#define GITS_IIDR_VAR_THUNDER_1 (0x0)
@@ -359,6 +361,18 @@
#define LPI_CONF_PRIO_MASK (0xFC)
#define LPI_CONF_GROUP1 (1 << 1)
#define LPI_CONF_ENABLE (1 << 0)
+
+/*
+ * GIC 500 ITS tracking facility
+ */
+#define GITS_TRKCTLR 0xC000
+#define GITS_TRKR 0xC004
+#define GITS_TRKDIDR 0xC008
+#define GITS_TRKPIDR 0xC00C
+#define GITS_TRKVIDR 0xC010
+#define GITS_TRKTGTR 0xC014
+#define GITS_TRKICR 0xC018
+#define GITS_TRKLCR 0xC018
/*
* CPU interface
Modified: stable/12/sys/arm64/arm64/gicv3_its.c
==============================================================================
--- stable/12/sys/arm64/arm64/gicv3_its.c Sat Oct 31 15:38:41 2020 (r367213)
+++ stable/12/sys/arm64/arm64/gicv3_its.c Sat Oct 31 15:40:52 2020 (r367214)
@@ -47,7 +47,9 @@ __FBSDID("$FreeBSD$");
#include <sys/proc.h>
#include <sys/queue.h>
#include <sys/rman.h>
+#include <sys/sbuf.h>
#include <sys/smp.h>
+#include <sys/sysctl.h>
#include <sys/vmem.h>
#include <vm/vm.h>
@@ -226,6 +228,7 @@ struct gicv3_its_irqsrc {
};
struct gicv3_its_softc {
+ device_t dev;
struct intr_pic *sc_pic;
struct resource *sc_its_res;
@@ -259,6 +262,7 @@ struct gicv3_its_softc {
#define ITS_FLAGS_LPI_CONF_FLUSH 0x00000002
#define ITS_FLAGS_ERRATA_CAVIUM_22375 0x00000004
u_int sc_its_flags;
+ bool trace_enable;
};
typedef void (its_quirk_func_t)(device_t);
@@ -696,6 +700,86 @@ its_init_cpu(device_t dev, struct gicv3_its_softc *sc)
}
static int
+gicv3_its_sysctl_trace_enable(SYSCTL_HANDLER_ARGS)
+{
+ struct gicv3_its_softc *sc;
+ int rv;
+
+ sc = arg1;
+
+ rv = sysctl_handle_bool(oidp, &sc->trace_enable, 0, req);
+ if (rv != 0 || req->newptr == NULL)
+ return (rv);
+ if (sc->trace_enable)
+ gic_its_write_8(sc, GITS_TRKCTLR, 3);
+ else
+ gic_its_write_8(sc, GITS_TRKCTLR, 0);
+
+ return (0);
+}
+
+static int
+gicv3_its_sysctl_trace_regs(SYSCTL_HANDLER_ARGS)
+{
+ struct gicv3_its_softc *sc;
+ struct sbuf *sb;
+ int err;
+
+ sc = arg1;
+ sb = sbuf_new_for_sysctl(NULL, NULL, 128, req);
+ if (sb == NULL) {
+ device_printf(sc->dev, "Could not allocate sbuf for output.\n");
+ return (ENOMEM);
+ }
+ sbuf_cat(sb, "\n");
+ sbuf_printf(sb, "GITS_TRKCTLR: 0x%08X\n",
+ gic_its_read_4(sc, GITS_TRKCTLR));
+ sbuf_printf(sb, "GITS_TRKR: 0x%08X\n",
+ gic_its_read_4(sc, GITS_TRKR));
+ sbuf_printf(sb, "GITS_TRKDIDR: 0x%08X\n",
+ gic_its_read_4(sc, GITS_TRKDIDR));
+ sbuf_printf(sb, "GITS_TRKPIDR: 0x%08X\n",
+ gic_its_read_4(sc, GITS_TRKPIDR));
+ sbuf_printf(sb, "GITS_TRKVIDR: 0x%08X\n",
+ gic_its_read_4(sc, GITS_TRKVIDR));
+ sbuf_printf(sb, "GITS_TRKTGTR: 0x%08X\n",
+ gic_its_read_4(sc, GITS_TRKTGTR));
+
+ err = sbuf_finish(sb);
+ if (err)
+ device_printf(sc->dev, "Error finishing sbuf: %d\n", err);
+ sbuf_delete(sb);
+ return(err);
+}
+
+static int
+gicv3_its_init_sysctl(struct gicv3_its_softc *sc)
+{
+ struct sysctl_oid *oid, *child;
+ struct sysctl_ctx_list *ctx_list;
+
+ ctx_list = device_get_sysctl_ctx(sc->dev);
+ child = device_get_sysctl_tree(sc->dev);
+ oid = SYSCTL_ADD_NODE(ctx_list,
+ SYSCTL_CHILDREN(child), OID_AUTO, "tracing",
+ CTLFLAG_RD| CTLFLAG_MPSAFE, NULL, "Messages tracing");
+ if (oid == NULL)
+ return (ENXIO);
+
+ /* Add registers */
+ SYSCTL_ADD_PROC(ctx_list,
+ SYSCTL_CHILDREN(oid), OID_AUTO, "enable",
+ CTLTYPE_U8 | CTLFLAG_RW | CTLFLAG_MPSAFE, sc, 0,
+ gicv3_its_sysctl_trace_enable, "CU", "Enable tracing");
+ SYSCTL_ADD_PROC(ctx_list,
+ SYSCTL_CHILDREN(oid), OID_AUTO, "capture",
+ CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_MPSAFE, sc, 0,
+ gicv3_its_sysctl_trace_regs, "", "Captured tracing registers.");
+
+ return (0);
+}
+
+static int
gicv3_its_attach(device_t dev)
{
struct gicv3_its_softc *sc;
@@ -793,6 +877,11 @@ gicv3_its_attach(device_t dev)
"%s,%u", name, i);
}
+ /* For GIC-500 install tracking sysctls. */
+ if ((iidr & (GITS_IIDR_PRODUCT_MASK | GITS_IIDR_IMPLEMENTOR_MASK)) ==
+ GITS_IIDR_RAW(GITS_IIDR_IMPL_ARM, GITS_IIDR_PROD_GIC500, 0, 0))
+ gicv3_its_init_sysctl(sc);
+
return (0);
}
@@ -1681,6 +1770,7 @@ gicv3_its_fdt_attach(device_t dev)
int err;
sc = device_get_softc(dev);
+ sc->dev = dev;
err = gicv3_its_attach(dev);
if (err != 0)
return (err);
@@ -1742,6 +1832,7 @@ gicv3_its_acpi_attach(device_t dev)
int err;
sc = device_get_softc(dev);
+ sc->dev = dev;
err = gicv3_its_attach(dev);
if (err != 0)
return (err);
More information about the svn-src-stable-12
mailing list