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);