This is an automated email from Gerrit. "liangzhen <[email protected]>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9212
-- gerrit commit d003c5913c3707a7962995fbd874bfe29d11c00d Author: liangzhen <[email protected]> Date: Thu Oct 23 19:24:04 2025 +0800 target: cstrace: Add coresight tmc support Add support for the coresight tmc component. Change-Id: I726753dff7dfa604dc7634a50179039bcdf9422a Signed-off-by: liangzhen <[email protected]> diff --git a/doc/openocd.texi b/doc/openocd.texi index 931bbda429..1aec747d43 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -10332,6 +10332,7 @@ You must set the @option{-dap} @emph{dap_name} @option{-ap-num} @emph{apn} here. Lists all supported coresight component types. At this writing, the supported coresight component types are: @itemize @item @code{funnel} - this a coresight funnel component. +@item @code{tmc} - this a coresight tmc component. @end itemize @end deffn @@ -10396,6 +10397,19 @@ The commands specific to the @code{funnel} are: @item @command{component_name funnel disable} @var{port} - disable a funnel port. @end itemize +@subsection TMC Component +When the coresight component is a @code{tmc} type, the configure +configparams specific to the @code{tmc} are: +@itemize +@item @option{-tmc-type} @code{etb|etf|etr} - set the TMC type. +@item @option{-hwaddr} @emph{addr} - set the trace buffer address in system memory. +@item @option{-buf-size} @emph{size} - set the trace buffer size in system memory. +@end itemize +The commands specific to the @code{tmc} is: +@itemize +@item @command{component_name tmc dump} @var{filename} - dump trace data. +@end itemize + @anchor{armcrosstrigger} @section ARM Cross-Trigger Interface @cindex CTI diff --git a/src/target/Makefile.am b/src/target/Makefile.am index 10176ccba1..040c6223e2 100644 --- a/src/target/Makefile.am +++ b/src/target/Makefile.am @@ -113,7 +113,8 @@ ARM_DEBUG_SRC = \ %D%/arm_tpiu_swo.c \ %D%/arm_cti.c \ %D%/coresight_trace.c \ - %D%/coresight_funnel.c + %D%/coresight_funnel.c \ + %D%/coresight_tmc.c AVR32_SRC = \ %D%/avr32_ap7k.c \ diff --git a/src/target/coresight_tmc.c b/src/target/coresight_tmc.c new file mode 100644 index 0000000000..d420daf8aa --- /dev/null +++ b/src/target/coresight_tmc.c @@ -0,0 +1,641 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +/*************************************************************************** + * Copyright (C) 2025 by liangzhen * + * [email protected] * + ***************************************************************************/ + +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include <time.h> +#include <helper/log.h> +#include <helper/types.h> +#include <helper/command.h> +#include <helper/jim-nvp.h> +#include <helper/fileio.h> +#include <helper/time_support.h> +#include "coresight_trace.h" + +#define CS_TMC_RSZ 0x004 +#define CS_TMC_STS 0x00c +#define CS_TMC_RRD 0x010 +#define CS_TMC_RRP 0x014 +#define CS_TMC_RWP 0x018 +#define CS_TMC_TRG 0x01c +#define CS_TMC_CTL 0x020 +#define CS_TMC_RWD 0x024 +#define CS_TMC_MODE 0x028 +#define CS_TMC_LBUFLEVEL 0x02c +#define CS_TMC_CBUFLEVEL 0x030 +#define CS_TMC_BUFWM 0x034 +#define CS_TMC_RRPHI 0x038 +#define CS_TMC_RWPHI 0x03c +#define CS_TMC_AXICTL 0x110 +#define CS_TMC_DBALO 0x118 +#define CS_TMC_DBAHI 0x11c +#define CS_TMC_FFSR 0x300 +#define CS_TMC_FFCR 0x304 +#define CS_TMC_PSCR 0x308 +#define CS_TMC_ITMISCOP0 0xee0 +#define CS_TMC_ITTRFLIN 0xee8 +#define CS_TMC_ITATBDATA0 0xeec +#define CS_TMC_ITATBCTR2 0xef0 +#define CS_TMC_ITATBCTR1 0xef4 +#define CS_TMC_ITATBCTR0 0xef8 +#define CS_TMC_AUTHSTATUS 0xfb8 + +/* register description */ +/* CS_TMC_CTL - 0x020 */ +#define CS_TMC_CTL_CAPT_EN 1 +/* CS_TMC_STS - 0x00C */ +#define CS_TMC_STS_FULL 0x1 +#define CS_TMC_STS_TRIGGERED 0x2 +#define CS_TMC_STS_TMCREADY 0x4 +#define CS_TMC_STS_MEMERR 0x20 +/* CS_TMC_FFCR - 0x304 */ +#define CS_TMC_FFCR_EN_FMT 0x1 +#define CS_TMC_FFCR_EN_TI 0x2 +#define CS_TMC_FFCR_FON_FLIN 0x10 +#define CS_TMC_FFCR_FON_TRIG_EVT 0x20 +#define CS_TMC_FFCR_FLUSHMAN 0x40 +#define CS_TMC_FFCR_TRIGON_TRIGIN 0x100 +#define CS_TMC_FFCR_STOP_ON_FLUSH 0x1000 + +#define CS_TMC_ETR_BUF_SIZE_MIN 0x00100000 +#define CS_TMC_ETR_BUF_SIZE_MAX 0x100000000 + +enum cs_tmc_type { + CS_TMC_TYPE_ETB, + CS_TMC_TYPE_ETF, + CS_TMC_TYPE_ETR, +}; + +enum cs_tmc_mode { + CS_TMC_MODE_CIRCULAR_BUFFER, + CS_TMC_MODE_SOFTWARE_FIFO, + CS_TMC_MODE_HARDWARE_FIFO, +}; + +struct cs_tmc_private_config { + enum cs_tmc_type type; + target_addr_t hwaddr; + uint64_t buf_size; +}; + +static inline struct cs_tmc_private_config +*cs_tmc_private_config(struct cstrace_component *comp) +{ + assert(comp->private_config); + return comp->private_config; +} + +static struct cs_tmc_private_config *alloc_default_cs_tmc_private_config(void) +{ + struct cs_tmc_private_config *config = malloc(sizeof(struct cs_tmc_private_config)); + if (!config) { + LOG_ERROR("Out of memory!"); + return NULL; + } + + // default etr + config->type = CS_TMC_TYPE_ETR; + config->buf_size = CS_TMC_ETR_BUF_SIZE_MIN; + + return config; +} + +#define CS_TMC_CONFIG(T) struct cs_tmc_private_config *T = cs_tmc_private_config(comp); + +static const struct { + uint32_t offset; + const char *label; +} tmc_names[] = { + { CS_TMC_RSZ, "RSZ" }, + { CS_TMC_STS, "STS" }, + { CS_TMC_RRD, "RRD" }, + { CS_TMC_RRP, "RRP" }, + { CS_TMC_RWP, "RWP" }, + { CS_TMC_TRG, "TRG" }, + { CS_TMC_CTL, "CTL" }, + { CS_TMC_RWD, "RWD" }, + { CS_TMC_MODE, "MODE" }, + { CS_TMC_LBUFLEVEL, "LBUFLEVEL" }, + { CS_TMC_CBUFLEVEL, "CBUFLEVEL" }, + { CS_TMC_BUFWM, "BUFWM" }, + { CS_TMC_RRPHI, "RRPHI" }, + { CS_TMC_RWPHI, "RWPHI" }, + { CS_TMC_AXICTL, "AXICTL" }, + { CS_TMC_DBALO, "DBALO" }, + { CS_TMC_DBAHI, "DBAHI" }, + { CS_TMC_FFSR, "FFSR" }, + { CS_TMC_PSCR, "PSCR" }, + { CS_TMC_ITMISCOP0, "ITMISCOP0" }, + { CS_TMC_ITTRFLIN, "ITTRFLIN" }, + { CS_TMC_ITATBDATA0, "ITATBDATA0" }, + { CS_TMC_ITATBCTR2, "ITATBCTR2" }, + { CS_TMC_ITATBCTR1, "ITATBCTR1" }, + { CS_TMC_ITATBCTR0, "ITATBCTR0" }, + { CS_TMC_AUTHSTATUS, "AUTHSTATUS" }, +}; + +static int tmc_find_reg_offset(const char *name) +{ + for (size_t i = 0; i < ARRAY_SIZE(tmc_names); i++) { + if (!strcasecmp(name, tmc_names[i].label)) + return tmc_names[i].offset; + } + + LOG_ERROR("unknown coresight tmc register %s", name); + return -1; +} + +static int tmc_create(struct cstrace_component *comp) +{ + LOG_DEBUG("tmc_create()"); + struct cs_tmc_private_config *config = comp->private_config; + if (!config) { + config = alloc_default_cs_tmc_private_config(); + if (!config) + return ERROR_FAIL; + comp->private_config = config; + } + + return ERROR_OK; +} + +static struct jim_nvp nvp_type_opts[] = { + { .name = "etb", .value = CS_TMC_TYPE_ETB }, + { .name = "etf", .value = CS_TMC_TYPE_ETF }, + { .name = "etr", .value = CS_TMC_TYPE_ETR }, + { .name = NULL, .value = -1 } +}; + +enum tmc_cfg_opts { + CS_TMC_CFG_TYPE, + CS_TMC_CFG_HWADDR, + CS_TMC_CFG_BUFSIZE +}; + +static struct jim_nvp nvp_config_opts[] = { + { .name = "-tmc-type", .value = CS_TMC_CFG_TYPE }, + { .name = "-hwaddr", .value = CS_TMC_CFG_HWADDR }, + { .name = "-buf-size", .value = CS_TMC_CFG_BUFSIZE }, + { .name = NULL, .value = -1 } +}; + +static int tmc_jim_configure(struct cstrace_component *comp, struct jim_getopt_info *goi) +{ + struct cs_tmc_private_config *config = comp->private_config; + if (!config) { + config = alloc_default_cs_tmc_private_config(); + if (!config) + return JIM_ERR; + comp->private_config = config; + } + + if (!goi->argc) + return JIM_OK; + + struct jim_nvp *n; + int e = jim_nvp_name2value_obj(goi->interp, nvp_config_opts, goi->argv[0], &n); + + if (e != JIM_OK) + return JIM_CONTINUE; + + e = jim_getopt_obj(goi, NULL); + if (e != JIM_OK) + return e; + + if (!goi->is_configure && goi->argc > 0) { + /*no arguments */ + Jim_WrongNumArgs(goi->interp, 2, goi->argv - 2, ""); + return JIM_ERR; + } + + switch (n->value) { + case CS_TMC_CFG_TYPE: + if (goi->is_configure) { + struct jim_nvp *type_nvp; + e = jim_getopt_nvp(goi, nvp_type_opts, &type_nvp); + if (e != JIM_OK) { + jim_getopt_nvp_unknown(goi, nvp_type_opts, /*hadprefix*/ true); + return e; + } + config->type = type_nvp->value; + } else { + Jim_SetResultString(goi->interp, jim_nvp_value2name_simple(nvp_type_opts, config->type)->name, -1); + } + break; + case CS_TMC_CFG_HWADDR: + if (goi->is_configure) { + jim_wide w; + e = jim_getopt_wide(goi, &w); + if (e != JIM_OK) + return e; + config->hwaddr = (target_addr_t)w; + } else { + Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, config->hwaddr)); + } + break; + case CS_TMC_CFG_BUFSIZE: + if (goi->is_configure) { + jim_wide w; + e = jim_getopt_wide(goi, &w); + if (e != JIM_OK) + return e; + if (w < CS_TMC_ETR_BUF_SIZE_MIN && w > CS_TMC_ETR_BUF_SIZE_MAX) { + Jim_SetResultString(goi->interp, "Invalid TMC ETR bufsize (1M-4GB)!", -1); + return JIM_ERR; + } + config->buf_size = (uint64_t)w; + } else { + Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, config->buf_size)); + } + break; + } + return JIM_OK; +} + +static int tmc_write_rrp(struct cstrace_component *comp, uint64_t rrp) +{ + if (coresight_write_reg(comp, CS_TMC_RRP, rrp & 0xffffffff) != ERROR_OK) + return ERROR_FAIL; + + return coresight_write_reg(comp, CS_TMC_RRPHI, rrp >> 32); +} + +static int tmc_write_rwp(struct cstrace_component *comp, uint64_t rwp) +{ + if (coresight_write_reg(comp, CS_TMC_RWP, rwp & 0xffffffff) != ERROR_OK) + return ERROR_FAIL; + + return coresight_write_reg(comp, CS_TMC_RWPHI, rwp >> 32); +} + +static int tmc_read_rrp(struct cstrace_component *comp, uint64_t *rrp) +{ + uint32_t regval; + if (coresight_read_reg(comp, CS_TMC_RRP, ®val) != ERROR_OK) + return ERROR_FAIL; + *rrp = regval; + + if (coresight_read_reg(comp, CS_TMC_RRPHI, ®val) != ERROR_OK) + return ERROR_FAIL; + *rrp |= (uint64_t)regval << 32; + + return ERROR_OK; +} + +static int tmc_read_rwp(struct cstrace_component *comp, uint64_t *rwp) +{ + uint32_t regval; + if (coresight_read_reg(comp, CS_TMC_RWP, ®val) != ERROR_OK) + return ERROR_FAIL; + *rwp = regval; + + if (coresight_read_reg(comp, CS_TMC_RWPHI, ®val) != ERROR_OK) + *rwp |= (uint64_t)regval << 32; + + return ERROR_OK; +} + +static int tmc_wait_for_tmcready(struct cstrace_component *comp) +{ + return coresight_poll_register(comp, CS_TMC_STS, CS_TMC_STS_TMCREADY, + 1, CORESIGHT_TIMEOUT); +} + +static int tmc_flush_and_stop(struct cstrace_component *comp) +{ + uint32_t ffcr; + if (coresight_read_reg(comp, CS_TMC_FFCR, &ffcr) != ERROR_OK) + return ERROR_FAIL; + + ffcr |= CS_TMC_FFCR_STOP_ON_FLUSH; + if (coresight_write_reg(comp, CS_TMC_FFCR, ffcr) != ERROR_OK) + return ERROR_FAIL; + + ffcr |= CS_TMC_FFCR_FLUSHMAN; + if (coresight_write_reg(comp, CS_TMC_FFCR, ffcr) != ERROR_OK) + return ERROR_FAIL; + + /* Ensure flush completes */ + if (coresight_poll_register(comp, CS_TMC_FFCR, CS_TMC_FFCR_FLUSHMAN, + 0, CORESIGHT_TIMEOUT)) + return ERROR_FAIL; + + return tmc_wait_for_tmcready(comp); +} + +static int tmc_enable_hw(struct cstrace_component *comp) +{ + return coresight_write_reg(comp, CS_TMC_CTL, CS_TMC_CTL_CAPT_EN); +} + +static int tmc_disable_hw(struct cstrace_component *comp) +{ + if (tmc_flush_and_stop(comp) != ERROR_OK) + return ERROR_FAIL; + + return coresight_write_reg(comp, CS_TMC_CTL, 0x0); +} + +static int tmc_etb_enable(struct cstrace_component *comp) +{ + if (coresight_write_reg(comp, CS_TMC_MODE, CS_TMC_MODE_CIRCULAR_BUFFER) != ERROR_OK) + return ERROR_FAIL; + + if (coresight_write_reg(comp, CS_TMC_FFCR, CS_TMC_FFCR_EN_FMT | CS_TMC_FFCR_EN_TI | + CS_TMC_FFCR_FON_FLIN | CS_TMC_FFCR_FON_TRIG_EVT | + CS_TMC_FFCR_TRIGON_TRIGIN) != ERROR_OK) + return ERROR_FAIL; + + return tmc_enable_hw(comp); +} + +static int tmc_etf_enable(struct cstrace_component *comp) +{ + /* ETF are considered as a link component and use Hardware FIFO mode by default here, + * if you want to use a ETF as a sink, you can consider it as a ETB. + */ + if (coresight_write_reg(comp, CS_TMC_MODE, CS_TMC_MODE_HARDWARE_FIFO) != ERROR_OK) + return ERROR_FAIL; + + if (coresight_write_reg(comp, CS_TMC_FFCR, CS_TMC_FFCR_EN_FMT | CS_TMC_FFCR_EN_TI) != ERROR_OK) + return ERROR_FAIL; + + if (coresight_write_reg(comp, CS_TMC_BUFWM, 0x0) != ERROR_OK) + return ERROR_FAIL; + + return tmc_enable_hw(comp); +} + +static int tmc_etr_enable(struct cstrace_component *comp) +{ + CS_TMC_CONFIG(config); + + if (coresight_write_reg(comp, CS_TMC_RSZ, config->buf_size / 4) != ERROR_OK) + return ERROR_FAIL; + + if (coresight_write_reg(comp, CS_TMC_FFCR, CS_TMC_FFCR_EN_FMT | CS_TMC_FFCR_EN_TI | + CS_TMC_FFCR_FON_FLIN | CS_TMC_FFCR_FON_TRIG_EVT | + CS_TMC_FFCR_TRIGON_TRIGIN) != ERROR_OK) + return ERROR_FAIL; + + if (coresight_write_reg(comp, CS_TMC_DBALO, config->hwaddr & 0xffffffff) != ERROR_OK +) + return ERROR_FAIL; + + if (coresight_write_reg(comp, CS_TMC_DBAHI, config->hwaddr >> 32) != ERROR_OK) + return ERROR_FAIL; + + if (tmc_write_rrp(comp, config->hwaddr) != ERROR_OK) + return ERROR_FAIL; + + if (tmc_write_rwp(comp, config->hwaddr) != ERROR_OK) + return ERROR_FAIL; + + return tmc_enable_hw(comp); +} + +static int tmc_enable(struct cstrace_component *comp) +{ + CS_TMC_CONFIG(config); + + int retval = tmc_wait_for_tmcready(comp); + if (retval != ERROR_OK) + return retval; + + switch (config->type) { + case CS_TMC_TYPE_ETB: + retval = tmc_etb_enable(comp); + break; + case CS_TMC_TYPE_ETF: + retval = tmc_etf_enable(comp); + break; + case CS_TMC_TYPE_ETR: + retval = tmc_etr_enable(comp); + break; + default: + return ERROR_FAIL; + } + + return retval; +} + +static int tmc_disable(struct cstrace_component *comp) +{ + CS_TMC_CONFIG(config); + + int retval; + + switch (config->type) { + case CS_TMC_TYPE_ETB: + case CS_TMC_TYPE_ETF: + case CS_TMC_TYPE_ETR: + retval = tmc_disable_hw(comp); + break; + default: + return ERROR_FAIL; + } + + return retval; +} + +static int tmc_status(struct cstrace_component *comp, struct command_invocation *cmd) +{ + uint32_t rsz, sts, ctl, ffsr, ffcr; + uint64_t rrp, rwp; + + if (tmc_wait_for_tmcready(comp) != ERROR_OK) + return ERROR_FAIL; + + if (tmc_read_rrp(comp, &rrp) != ERROR_OK) + return ERROR_FAIL; + if (tmc_read_rwp(comp, &rwp) != ERROR_OK) + return ERROR_FAIL; + if (coresight_read_reg(comp, CS_TMC_RSZ, &rsz) != ERROR_OK) + return ERROR_FAIL; + if (coresight_read_reg(comp, CS_TMC_STS, &sts) != ERROR_OK) + return ERROR_FAIL; + if (coresight_read_reg(comp, CS_TMC_CTL, &ctl) != ERROR_OK) + return ERROR_FAIL; + if (coresight_read_reg(comp, CS_TMC_FFSR, &ffsr) != ERROR_OK) + return ERROR_FAIL; + if (coresight_read_reg(comp, CS_TMC_FFCR, &ffcr) != ERROR_OK) + return ERROR_FAIL; + + command_print(CMD, "Depth: 0x%" PRIx64, (uint64_t)rsz * 4); + command_print(CMD, "Status: 0x%x", sts); + command_print(CMD, "ARM read ptr: 0x%" PRIx64, rrp); + command_print(CMD, "ARM write ptr: 0x%" PRIx64, rwp); + command_print(CMD, "Control: 0x%x", ctl); + command_print(CMD, "Flush status: 0x%x", ffsr); + command_print(CMD, "Flush control: 0x%x", ffcr); + + return ERROR_OK; +} + +static int tmc_write(struct cstrace_component *comp, const char *reg_name, uint32_t value) +{ + int offset = tmc_find_reg_offset(reg_name); + if (offset < 0) + return ERROR_FAIL; + + return coresight_write_reg(comp, offset, value); +} + +static int tmc_read(struct cstrace_component *comp, const char *reg_name, uint32_t *value) +{ + int offset = tmc_find_reg_offset(reg_name); + if (offset < 0) + return ERROR_FAIL; + + return coresight_read_reg(comp, offset, value); +} + +static int tmc_etb_dump(struct cstrace_component *comp, struct fileio *fileio) +{ + uint32_t read_data; + + while (1) { + if (coresight_read_reg(comp, CS_TMC_RRD, &read_data) != ERROR_OK) + return ERROR_FAIL; + + if (read_data == 0xffffffff) + break; + + if (fileio_write_u32(fileio, read_data) != ERROR_OK) + return ERROR_FAIL; + } + + return ERROR_OK; +} + +static int tmc_etr_dump(struct cstrace_component *comp, struct fileio *fileio) +{ + CS_TMC_CONFIG(config); + + int retval; + uint8_t *buffer; + target_addr_t address; + uint64_t size; + uint64_t rrp, rwp; + + if (tmc_read_rrp(comp, &rrp) != ERROR_OK) + return ERROR_FAIL; + if (tmc_read_rwp(comp, &rwp) != ERROR_OK) + return ERROR_FAIL; + + address = config->hwaddr; + size = rwp - rrp; + + uint32_t buf_size = (size > 4096) ? 4096 : size; + buffer = malloc(buf_size); + if (!buffer) + return ERROR_FAIL; + + while (size > 0) { + size_t size_written; + uint32_t this_run_size = (size > buf_size) ? buf_size : size; + retval = coresight_read_buffer(comp, address, this_run_size, buffer); + if (retval != ERROR_OK) + break; + + retval = fileio_write(fileio, this_run_size, buffer, &size_written); + if (retval != ERROR_OK) + break; + + size -= this_run_size; + address += this_run_size; + } + + free(buffer); + + return retval; +} + +COMMAND_HANDLER(handle_tmc_dump) +{ + struct cstrace_component *comp = CMD_DATA; + struct fileio *fileio; + int retval, retvaltemp; + struct duration bench; + + if (CMD_ARGC != 1) + return ERROR_COMMAND_SYNTAX_ERROR; + + retval = fileio_open(&fileio, CMD_ARGV[0], FILEIO_WRITE, FILEIO_BINARY); + if (retval != ERROR_OK) + return retval; + + CS_TMC_CONFIG(config); + + duration_start(&bench); + + switch (config->type) { + case CS_TMC_TYPE_ETB: + retval = tmc_etb_dump(comp, fileio); + break; + case CS_TMC_TYPE_ETF: + break; + case CS_TMC_TYPE_ETR: + retval = tmc_etr_dump(comp, fileio); + break; + default: + return ERROR_FAIL; + } + + if ((retval == ERROR_OK) && (duration_measure(&bench) == ERROR_OK)) { + size_t filesize; + retval = fileio_size(fileio, &filesize); + if (retval != ERROR_OK) + return retval; + command_print(CMD, "dumped %zu bytes in %fs (%0.3f KiB/s)", filesize, + duration_elapsed(&bench), duration_kbps(&bench, filesize)); + } + + retvaltemp = fileio_close(fileio); + if (retvaltemp != ERROR_OK) + return retvaltemp; + + return retval; +} + +static const struct command_registration tmc_exec_command_handlers[] = { + { + .name = "dump", + .mode = COMMAND_EXEC, + .handler = handle_tmc_dump, + .help = "tmc dump trace", + .usage = "<filename>", + }, + COMMAND_REGISTRATION_DONE +}; + +static const struct command_registration tmc_command_handlers[] = { + { + .name = "tmc", + .mode = COMMAND_ANY, + .help = "TMC Command Group", + .usage = "", + .chain = tmc_exec_command_handlers + }, + COMMAND_REGISTRATION_DONE +}; + +struct coresight_type coresight_tmc = { + .name = "tmc", + + .coresight_create = tmc_create, + .coresight_jim_configure = tmc_jim_configure, + + .enable = tmc_enable, + .disable = tmc_disable, + .status = tmc_status, + .write = tmc_write, + .read = tmc_read, + + .commands = tmc_command_handlers, +}; diff --git a/src/target/coresight_trace.c b/src/target/coresight_trace.c index 9cbc7804ef..436754700c 100644 --- a/src/target/coresight_trace.c +++ b/src/target/coresight_trace.c @@ -24,6 +24,7 @@ static OOCD_LIST_HEAD(all_cstrace_component); static struct coresight_type *coresight_type[] = { &coresight_funnel, + &coresight_tmc, }; int coresight_write_reg(const struct cstrace_component *comp, unsigned int reg, uint32_t value) diff --git a/src/target/coresight_trace.h b/src/target/coresight_trace.h index 8bf33ba044..ecd7957824 100644 --- a/src/target/coresight_trace.h +++ b/src/target/coresight_trace.h @@ -69,5 +69,6 @@ int cstrace_cleanup_all(void); int cstrace_register_commands(struct command_context *cmd_ctx); extern struct coresight_type coresight_funnel; +extern struct coresight_type coresight_tmc; #endif /* OPENOCD_TARGET_CORESIGHT_TRACE_H */ --
