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);
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to