Index: sys/arm64/coresight/coresight.h
===================================================================
--- sys/arm64/coresight/coresight.h
+++ sys/arm64/coresight/coresight.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2018-2020 Ruslan Bukin
+ * Copyright (c) 2018-2023 Ruslan Bukin
* All rights reserved.
*
* This software was developed by SRI International and the University of
@@ -60,7 +60,8 @@
enum cs_dev_type {
CORESIGHT_ETMV4,
- CORESIGHT_TMC,
+ CORESIGHT_TMC_ETF,
+ CORESIGHT_TMC_ETR,
CORESIGHT_DYNAMIC_REPLICATOR,
CORESIGHT_FUNNEL,
CORESIGHT_CPU_DEBUG,
Index: sys/arm64/coresight/coresight_fdt.c
===================================================================
--- sys/arm64/coresight/coresight_fdt.c
+++ sys/arm64/coresight/coresight_fdt.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2018-2020 Ruslan Bukin
+ * Copyright (c) 2018-2023 Ruslan Bukin
* All rights reserved.
*
* This software was developed by SRI International and the University of
@@ -47,10 +47,10 @@
#include
static int
-coresight_fdt_get_ports(phandle_t dev_node,
- struct coresight_platform_data *pdata)
+coresight_fdt_get_ports(phandle_t dev_node, phandle_t node,
+ struct coresight_platform_data *pdata, bool input)
{
- phandle_t node, child;
+ phandle_t child;
pcell_t port_reg;
phandle_t xref;
char *name;
@@ -58,12 +58,6 @@
phandle_t endpoint_child;
struct endpoint *endp;
- child = ofw_bus_find_child(dev_node, "ports");
- if (child)
- node = child;
- else
- node = dev_node;
-
for (child = OF_child(node); child != 0; child = OF_peer(child)) {
ret = OF_getprop_alloc(child, "name", (void **)&name);
if (ret == -1)
@@ -89,8 +83,8 @@
endp->their_node = OF_node_from_xref(xref);
endp->dev_node = dev_node;
endp->reg = port_reg;
- if (OF_getproplen(endpoint_child,
- "slave-mode") >= 0) {
+
+ if (input) {
pdata->in_ports++;
endp->input = 1;
} else
@@ -131,7 +125,7 @@
coresight_fdt_get_platform_data(device_t dev)
{
struct coresight_platform_data *pdata;
- phandle_t node;
+ phandle_t node, child;
node = ofw_bus_get_node(dev);
@@ -143,7 +137,14 @@
TAILQ_INIT(&pdata->endpoints);
coresight_fdt_get_cpu(node, pdata);
- coresight_fdt_get_ports(node, pdata);
+
+ child = ofw_bus_find_child(node, "in-ports");
+ if (child)
+ coresight_fdt_get_ports(node, child, pdata, true);
+
+ child = ofw_bus_find_child(node, "out-ports");
+ if (child)
+ coresight_fdt_get_ports(node, child, pdata, false);
if (bootverbose)
printf("Total ports: in %d out %d\n",
Index: sys/arm64/coresight/coresight_funnel_fdt.c
===================================================================
--- sys/arm64/coresight/coresight_funnel_fdt.c
+++ sys/arm64/coresight/coresight_funnel_fdt.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2018-2020 Ruslan Bukin
+ * Copyright (c) 2018-2023 Ruslan Bukin
* All rights reserved.
*
* This software was developed by BAE Systems, the University of Cambridge
@@ -49,7 +49,7 @@
#include "coresight_if.h"
static struct ofw_compat_data compat_data[] = {
- { "arm,coresight-funnel", HWTYPE_FUNNEL },
+ { "arm,coresight-dynamic-funnel", HWTYPE_FUNNEL },
{ "arm,coresight-static-funnel", HWTYPE_STATIC_FUNNEL },
{ NULL, HWTYPE_NONE }
};
Index: sys/arm64/coresight/coresight_tmc.h
===================================================================
--- sys/arm64/coresight/coresight_tmc.h
+++ sys/arm64/coresight/coresight_tmc.h
@@ -119,7 +119,7 @@
DECLARE_CLASS(tmc_driver);
struct tmc_softc {
- struct resource *res;
+ struct resource *res[2];
device_t dev;
uint64_t cycle;
struct coresight_platform_data *pdata;
@@ -130,6 +130,7 @@
uint32_t nev;
struct coresight_event *event;
boolean_t etf_configured;
+ void *intrhand;
};
int tmc_attach(device_t dev);
Index: sys/arm64/coresight/coresight_tmc.c
===================================================================
--- sys/arm64/coresight/coresight_tmc.c
+++ sys/arm64/coresight/coresight_tmc.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2018-2020 Ruslan Bukin
+ * Copyright (c) 2018-2023 Ruslan Bukin
* All rights reserved.
*
* This software was developed by SRI International and the University of
@@ -46,7 +46,7 @@
#define TMC_DEBUG
#undef TMC_DEBUG
-
+
#ifdef TMC_DEBUG
#define dprintf(fmt, ...) printf(fmt, ##__VA_ARGS__)
#else
@@ -55,6 +55,7 @@
static struct resource_spec tmc_spec[] = {
{ SYS_RES_MEMORY, 0, RF_ACTIVE },
+ { SYS_RES_IRQ, 0, RF_ACTIVE | RF_OPTIONAL },
{ -1, 0 }
};
@@ -66,19 +67,19 @@
sc = device_get_softc(dev);
- if (bus_read_4(sc->res, TMC_CTL) & CTL_TRACECAPTEN)
+ if (bus_read_4(sc->res[0], TMC_CTL) & CTL_TRACECAPTEN)
return (-1);
/* Enable TMC */
- bus_write_4(sc->res, TMC_CTL, CTL_TRACECAPTEN);
- if ((bus_read_4(sc->res, TMC_CTL) & CTL_TRACECAPTEN) == 0)
+ bus_write_4(sc->res[0], TMC_CTL, CTL_TRACECAPTEN);
+ if ((bus_read_4(sc->res[0], TMC_CTL) & CTL_TRACECAPTEN) == 0)
panic("Not enabled\n");
do {
- reg = bus_read_4(sc->res, TMC_STS);
+ reg = bus_read_4(sc->res[0], TMC_STS);
} while ((reg & STS_TMCREADY) == 1);
- if ((bus_read_4(sc->res, TMC_CTL) & CTL_TRACECAPTEN) == 0)
+ if ((bus_read_4(sc->res[0], TMC_CTL) & CTL_TRACECAPTEN) == 0)
panic("Not enabled\n");
return (0);
@@ -92,12 +93,12 @@
sc = device_get_softc(dev);
- reg = bus_read_4(sc->res, TMC_CTL);
+ reg = bus_read_4(sc->res[0], TMC_CTL);
reg &= ~CTL_TRACECAPTEN;
- bus_write_4(sc->res, TMC_CTL, reg);
+ bus_write_4(sc->res[0], TMC_CTL, reg);
do {
- reg = bus_read_4(sc->res, TMC_STS);
+ reg = bus_read_4(sc->res[0], TMC_STS);
} while ((reg & STS_TMCREADY) == 1);
return (0);
@@ -112,23 +113,23 @@
sc = device_get_softc(dev);
do {
- reg = bus_read_4(sc->res, TMC_STS);
+ reg = bus_read_4(sc->res[0], TMC_STS);
} while ((reg & STS_TMCREADY) == 0);
- bus_write_4(sc->res, TMC_MODE, MODE_HW_FIFO);
- bus_write_4(sc->res, TMC_FFCR, FFCR_EN_FMT | FFCR_EN_TI);
+ bus_write_4(sc->res[0], TMC_MODE, MODE_HW_FIFO);
+ bus_write_4(sc->res[0], TMC_FFCR, FFCR_EN_FMT | FFCR_EN_TI);
tmc_start(dev);
dprintf("%s: STS %x, CTL %x, RSZ %x, RRP %x, RWP %x, "
"LBUFLEVEL %x, CBUFLEVEL %x\n", __func__,
- bus_read_4(sc->res, TMC_STS),
- bus_read_4(sc->res, TMC_CTL),
- bus_read_4(sc->res, TMC_RSZ),
- bus_read_4(sc->res, TMC_RRP),
- bus_read_4(sc->res, TMC_RWP),
- bus_read_4(sc->res, TMC_CBUFLEVEL),
- bus_read_4(sc->res, TMC_LBUFLEVEL));
+ bus_read_4(sc->res[0], TMC_STS),
+ bus_read_4(sc->res[0], TMC_CTL),
+ bus_read_4(sc->res[0], TMC_RSZ),
+ bus_read_4(sc->res[0], TMC_RRP),
+ bus_read_4(sc->res[0], TMC_RWP),
+ bus_read_4(sc->res[0], TMC_CBUFLEVEL),
+ bus_read_4(sc->res[0], TMC_LBUFLEVEL));
return (0);
}
@@ -145,11 +146,11 @@
tmc_stop(dev);
do {
- reg = bus_read_4(sc->res, TMC_STS);
+ reg = bus_read_4(sc->res[0], TMC_STS);
} while ((reg & STS_TMCREADY) == 0);
/* Configure TMC */
- bus_write_4(sc->res, TMC_MODE, MODE_CIRCULAR_BUFFER);
+ bus_write_4(sc->res[0], TMC_MODE, MODE_CIRCULAR_BUFFER);
reg = AXICTL_PROT_CTRL_BIT1;
reg |= AXICTL_WRBURSTLEN_16;
@@ -160,24 +161,24 @@
*/
reg |= AXICTL_AXCACHE_OS;
- bus_write_4(sc->res, TMC_AXICTL, reg);
+ bus_write_4(sc->res[0], TMC_AXICTL, reg);
reg = FFCR_EN_FMT | FFCR_EN_TI | FFCR_FON_FLIN |
FFCR_FON_TRIG_EVT | FFCR_TRIGON_TRIGIN;
- bus_write_4(sc->res, TMC_FFCR, reg);
+ bus_write_4(sc->res[0], TMC_FFCR, reg);
- bus_write_4(sc->res, TMC_TRG, 8);
+ bus_write_4(sc->res[0], TMC_TRG, 8);
- bus_write_4(sc->res, TMC_DBALO, event->etr.low);
- bus_write_4(sc->res, TMC_DBAHI, event->etr.high);
- bus_write_4(sc->res, TMC_RSZ, event->etr.bufsize / 4);
+ bus_write_4(sc->res[0], TMC_DBALO, event->etr.low);
+ bus_write_4(sc->res[0], TMC_DBAHI, event->etr.high);
+ bus_write_4(sc->res[0], TMC_RSZ, event->etr.bufsize / 4);
- bus_write_4(sc->res, TMC_RRP, event->etr.low);
- bus_write_4(sc->res, TMC_RWP, event->etr.low);
+ bus_write_4(sc->res[0], TMC_RRP, event->etr.low);
+ bus_write_4(sc->res[0], TMC_RWP, event->etr.low);
- reg = bus_read_4(sc->res, TMC_STS);
+ reg = bus_read_4(sc->res[0], TMC_STS);
reg &= ~STS_FULL;
- bus_write_4(sc->res, TMC_STS, reg);
+ bus_write_4(sc->res[0], TMC_STS, reg);
tmc_start(dev);
@@ -193,12 +194,12 @@
sc = device_get_softc(dev);
/* Unlock Coresight */
- bus_write_4(sc->res, CORESIGHT_LAR, CORESIGHT_UNLOCK);
+ bus_write_4(sc->res[0], CORESIGHT_LAR, CORESIGHT_UNLOCK);
/* Unlock TMC */
- bus_write_4(sc->res, TMC_LAR, CORESIGHT_UNLOCK);
+ bus_write_4(sc->res[0], TMC_LAR, CORESIGHT_UNLOCK);
- reg = bus_read_4(sc->res, TMC_DEVID);
+ reg = bus_read_4(sc->res[0], TMC_DEVID);
reg &= DEVID_CONFIGTYPE_M;
switch (reg) {
case DEVID_CONFIGTYPE_ETR:
@@ -280,6 +281,15 @@
}
}
+static void
+tmc_intr(void *arg)
+{
+
+ /* TODO */
+
+ printf("%s\n", __func__);
+}
+
static int
tmc_read(device_t dev, struct endpoint *endp,
struct coresight_event *event)
@@ -299,13 +309,13 @@
if (sc->event != event)
return (0);
- if (bus_read_4(sc->res, TMC_STS) & STS_FULL) {
+ if (bus_read_4(sc->res[0], TMC_STS) & STS_FULL) {
event->etr.offset = 0;
event->etr.cycle++;
tmc_stop(dev);
tmc_start(dev);
} else {
- cur_ptr = bus_read_4(sc->res, TMC_RWP);
+ cur_ptr = bus_read_4(sc->res[0], TMC_RWP);
event->etr.offset = (cur_ptr - event->etr.low);
}
@@ -317,18 +327,36 @@
{
struct coresight_desc desc;
struct tmc_softc *sc;
+ uint32_t reg;
sc = device_get_softc(dev);
sc->dev = dev;
- if (bus_alloc_resources(dev, tmc_spec, &sc->res) != 0) {
+ if (bus_alloc_resources(dev, tmc_spec, sc->res) != 0) {
device_printf(dev, "cannot allocate resources for device\n");
return (ENXIO);
}
+ if (sc->res[1] != NULL) {
+ if (bus_setup_intr(dev, sc->res[1],
+ INTR_TYPE_MISC | INTR_MPSAFE, NULL, tmc_intr, sc,
+ &sc->intrhand)) {
+ bus_release_resources(dev, tmc_spec, sc->res);
+ device_printf(dev, "cannot setup interrupt handler\n");
+ return (ENXIO);
+ }
+ }
+
desc.pdata = sc->pdata;
desc.dev = dev;
- desc.dev_type = CORESIGHT_TMC;
+
+ reg = bus_read_4(sc->res[0], TMC_DEVID);
+ reg &= DEVID_CONFIGTYPE_M;
+ if (reg == DEVID_CONFIGTYPE_ETR)
+ desc.dev_type = CORESIGHT_TMC_ETR;
+ else
+ desc.dev_type = CORESIGHT_TMC_ETF;
+
coresight_register(&desc);
return (0);