This is an automated email from Gerrit.

Austin Morton ([email protected]) just uploaded a new patch set to 
Gerrit, which you can find at http://openocd.zylin.com/4251

-- gerrit

commit 4d5672ff1cf8f11398f19ca558ca70b7a9ba3f96
Author: Austin Morton <[email protected]>
Date:   Mon Oct 9 06:28:51 2017 -0400

    target/armv7m_trace: implement itm config command
    
    Implement a tcl command which allows configuration
    of settings in the ITM_TCR register.
    
    Documentation is currently missing. I am submitting this
    patch now to get feedback on the implementation before
    writing the documentation.
    
    Change-Id: Ib41a3f5fd37e68a3a95d371565bb7e73b371a764
    Signed-off-by: Austin Morton <[email protected]>

diff --git a/src/target/armv7m.c b/src/target/armv7m.c
index e0911c3..b44f1c9 100644
--- a/src/target/armv7m.c
+++ b/src/target/armv7m.c
@@ -666,7 +666,9 @@ int armv7m_init_arch_info(struct target *target, struct 
armv7m_common *armv7m)
 
        armv7m->common_magic = ARMV7M_COMMON_MAGIC;
        armv7m->fp_feature = FP_NONE;
-       armv7m->trace_config.trace_bus_id = 1;
+       armv7m->trace_config.itm_tcr.itmena = true;
+       armv7m->trace_config.itm_tcr.txena = true;
+       armv7m->trace_config.itm_tcr.tracebusid = 1;
        /* Enable stimulus port #0 by default */
        armv7m->trace_config.itm_ter[0] = 1;
 
diff --git a/src/target/armv7m_trace.c b/src/target/armv7m_trace.c
index c1e4f5b..8781a26 100644
--- a/src/target/armv7m_trace.c
+++ b/src/target/armv7m_trace.c
@@ -127,19 +127,25 @@ int armv7m_trace_itm_config(struct target *target)
 {
        struct armv7m_common *armv7m = target_to_armv7m(target);
        struct armv7m_trace_config *trace_config = &armv7m->trace_config;
+       uint32_t tcr;
        int retval;
 
        retval = target_write_u32(target, ITM_LAR, ITM_LAR_KEY);
        if (retval != ERROR_OK)
                return retval;
 
-       /* Enable ITM, TXENA, set TraceBusID and other parameters */
-       retval = target_write_u32(target, ITM_TCR, (1 << 0) | (1 << 3) |
-                                 (trace_config->itm_diff_timestamps << 1) |
-                                 (trace_config->itm_synchro_packets << 2) |
-                                 (trace_config->itm_async_timestamps << 4) |
-                                 (trace_config->itm_ts_prescale << 8) |
-                                 (trace_config->trace_bus_id << 16));
+       /* build ITM_TCR register value according to trace config parameters */
+       tcr =
+               (trace_config->itm_tcr.itmena  * TCR_ITMENA)  |
+               (trace_config->itm_tcr.tsena   * TCR_TSENA)   |
+               (trace_config->itm_tcr.syncena * TCR_SYNCENA) |
+               (trace_config->itm_tcr.txena   * TCR_TXENA)   |
+               (trace_config->itm_tcr.swoena  * TCR_SWOENA)  |
+               ((trace_config->itm_tcr.tsprescale & TCR_TSPRESCALE_MSK) << 
TCR_TSPRESCALE_POS) |
+               ((trace_config->itm_tcr.gtsfreq    & TCR_GTSFREQ_MSK)    << 
TCR_GTSFREQ_POS)    |
+               ((trace_config->itm_tcr.tracebusid & TCR_TRACEBUSID_MSK) << 
TCR_TRACEBUSID_POS);
+
+       retval = target_write_u32(target, ITM_TCR, tcr);
        if (retval != ERROR_OK)
                return retval;
 
@@ -255,6 +261,168 @@ COMMAND_HANDLER(handle_tpiu_config_command)
        return ERROR_COMMAND_SYNTAX_ERROR;
 }
 
+static int Jim_GetOpt_Bool(Jim_GetOptInfo *goi, bool *val)
+{
+       static const Jim_Nvp nvp_bool_opts[] = {
+               { .name = "on",      .value = true },
+               { .name = "enable",  .value = true },
+               { .name = "1",       .value = true },
+               { .name = "off",     .value = false },
+               { .name = "disable", .value = false },
+               { .name = "0",       .value = false },
+               { .name = NULL, .value = -1 }
+       };
+
+       int e;
+       Jim_Nvp *n;
+
+       e = Jim_GetOpt_Nvp(goi, nvp_bool_opts, &n);
+       if (e != JIM_OK) {
+               Jim_GetOpt_NvpUnknown(goi, nvp_bool_opts, 0);
+               return e;
+       }
+
+       *val = n->value;
+       return e;
+}
+
+enum itm_cfg_param {
+       ICFG_ITM_ENABLE,
+       ICFG_ITM_DISABLE,
+       ICFG_LTS,
+       ICFG_SYNC,
+       ICFG_TX,
+       ICFG_SWO,
+       ICFG_GTS,
+       ICFG_TRACEBUSID,
+};
+
+static Jim_Nvp nvp_config_opts[] = {
+       { .name = "-enable",             .value = ICFG_ITM_ENABLE },
+       { .name = "-disable",            .value = ICFG_ITM_DISABLE },
+       { .name = "-lts",                .value = ICFG_LTS },
+       { .name = "-sync",               .value = ICFG_SYNC },
+       { .name = "-tx",                 .value = ICFG_TX },
+       { .name = "-swo",                .value = ICFG_SWO },
+       { .name = "-gts",                .value = ICFG_GTS },
+       { .name = "-trace-bus-id",       .value = ICFG_TRACEBUSID },
+       { .name = NULL, .value = -1 }
+};
+
+static const Jim_Nvp nvp_lts_opts[] = {
+       { .name = "0",         .value = -1 },
+       { .name = "off",       .value = -1 },
+       { .name = "disable",   .value = -1 },
+       { .name = "1",         .value = ITM_TS_PRESCALE1 },
+       { .name = "on",        .value = ITM_TS_PRESCALE1 },
+       { .name = "enable",    .value = ITM_TS_PRESCALE1 },
+       { .name = "div1",      .value = ITM_TS_PRESCALE1 },
+       { .name = "div4",      .value = ITM_TS_PRESCALE4 },
+       { .name = "div16",     .value = ITM_TS_PRESCALE16 },
+       { .name = "div64",     .value = ITM_TS_PRESCALE64 },
+       { .name = NULL, .value = -1 }
+};
+
+static const Jim_Nvp nvp_gts_opts[] = {
+       { .name = "0",         .value = ITM_GTS_DISABLE },
+       { .name = "off",       .value = ITM_GTS_DISABLE },
+       { .name = "disable",   .value = ITM_GTS_DISABLE },
+       { .name = "fast",      .value = ITM_GTS_128CYCLE },
+       { .name = "slow",      .value = ITM_GTS_8192CYCLE },
+       { .name = "always",    .value = ITM_GTS_FIFOEMPTY },
+       { .name = NULL, .value = -1 }
+};
+
+static int itm_config(Jim_GetOptInfo *goi, struct command_context *ctx)
+{
+       Jim_Nvp *n;
+       jim_wide w;
+       int e;
+       struct target *target = get_current_target(ctx);
+       struct armv7m_common *armv7m = target_to_armv7m(target);
+
+       while (goi->argc > 0) {
+               Jim_SetEmptyResult(goi->interp);
+
+               e = Jim_GetOpt_Nvp(goi, nvp_config_opts, &n);
+               if (e != JIM_OK) {
+                       Jim_GetOpt_NvpUnknown(goi, nvp_config_opts, 0);
+                       return e;
+               }
+               switch (n->value) {
+               case ICFG_ITM_ENABLE:
+                       armv7m->trace_config.itm_tcr.itmena = true;
+                       break;
+               case ICFG_ITM_DISABLE:
+                       armv7m->trace_config.itm_tcr.itmena = false;
+                       break;
+               case ICFG_LTS:
+                       e = Jim_GetOpt_Nvp(goi, nvp_lts_opts, &n);
+                       if (e != JIM_OK) {
+                               Jim_GetOpt_NvpUnknown(goi, nvp_lts_opts, 0);
+                               return e;
+                       }
+
+                       if (n->value < 0) {
+                               armv7m->trace_config.itm_tcr.tsena = false;
+                       } else {
+                               armv7m->trace_config.itm_tcr.tsena = true;
+                               armv7m->trace_config.itm_tcr.tsprescale = 
n->value;
+                       }
+                       break;
+               case ICFG_SYNC:
+                       e = Jim_GetOpt_Bool(goi, 
&armv7m->trace_config.itm_tcr.syncena);
+                       if (e != JIM_OK)
+                               return e;
+                       break;
+               case ICFG_TX:
+                       e = Jim_GetOpt_Bool(goi, 
&armv7m->trace_config.itm_tcr.txena);
+                       if (e != JIM_OK)
+                               return e;
+                       break;
+               case ICFG_SWO:
+                       e = Jim_GetOpt_Bool(goi, 
&armv7m->trace_config.itm_tcr.swoena);
+                       if (e != JIM_OK)
+                               return e;
+                       break;
+               case ICFG_GTS:
+                       e = Jim_GetOpt_Nvp(goi, nvp_gts_opts, &n);
+                       if (e != JIM_OK) {
+                               Jim_GetOpt_NvpUnknown(goi, nvp_gts_opts, 0);
+                               return e;
+                       }
+                       armv7m->trace_config.itm_tcr.gtsfreq = n->value;
+                       break;
+               case ICFG_TRACEBUSID:
+                       e = Jim_GetOpt_Wide(goi, &w);
+                       if (e != JIM_OK)
+                               return e;
+                       armv7m->trace_config.itm_tcr.tracebusid = w;
+                       break;
+               }
+       }
+
+       if (ctx->mode == COMMAND_EXEC)
+               if (armv7m_trace_itm_config(target) != ERROR_OK)
+                       return JIM_ERR;
+
+       return JIM_OK;
+}
+
+static int jim_itm_config(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
+{
+       Jim_GetOptInfo goi;
+
+       Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1);
+       /* goi.isconfigure = !strcmp(Jim_GetString(argv[0], NULL), 
"configure"); */
+       if (goi.argc < 1) {
+               Jim_WrongNumArgs(goi.interp, goi.argc, goi.argv, "missing: 
-option ...");
+               return JIM_ERR;
+       }
+
+       return itm_config(&goi, current_command_context(interp));
+}
+
 COMMAND_HANDLER(handle_itm_port_command)
 {
        struct target *target = get_current_target(CMD_CTX);
@@ -316,6 +484,13 @@ static const struct command_registration 
tpiu_command_handlers[] = {
 
 static const struct command_registration itm_command_handlers[] = {
        {
+               .name = "config",
+               .jim_handler = jim_itm_config,
+               .mode = COMMAND_ANY,
+               .help = "Configure ITM features",
+               .usage = "todo",
+       },
+       {
                .name = "port",
                .handler = handle_itm_port_command,
                .mode = COMMAND_ANY,
diff --git a/src/target/armv7m_trace.h b/src/target/armv7m_trace.h
index 4f99394..d28c03a 100644
--- a/src/target/armv7m_trace.h
+++ b/src/target/armv7m_trace.h
@@ -45,6 +45,13 @@ enum itm_ts_prescaler {
        ITM_TS_PRESCALE64,      /**< refclock divided by 64 for the timestamp 
counter */
 };
 
+enum itm_gts_freq {
+       ITM_GTS_DISABLE,
+       ITM_GTS_128CYCLE,
+       ITM_GTS_8192CYCLE,
+       ITM_GTS_FIFOEMPTY,
+};
+
 struct armv7m_trace_config {
        /** Currently active trace capture mode */
        enum trace_config_type config_type;
@@ -58,16 +65,28 @@ struct armv7m_trace_config {
 
        /** Bitmask of currenty enabled ITM stimuli */
        uint32_t itm_ter[8];
-       /** Identifier for multi-source trace stream formatting */
-       unsigned int trace_bus_id;
-       /** Prescaler for the timestamp counter */
-       enum itm_ts_prescaler itm_ts_prescale;
-       /** Enable differential timestamps */
-       bool itm_diff_timestamps;
+
+       struct {
+               /** Enables the ITM */
+               bool itmena;
+               /** Enables Local timestamp generation */
+               bool tsena;
+               /** Enables Synchronization packet transmission for a 
synchronous TPIU */
+               bool syncena;
+               /** Enables forwarding of hardware event packet from the DWT 
unit to the ITM for output to the TPIU */
+               bool txena;
+               /** Enables asynchronous clocking of the timestamp counter */
+               bool swoena;
+               /** Local timestamp prescaler, used with the trace packet 
reference clock */
+               enum itm_ts_prescaler tsprescale;
+               /* Global timestamp frequency */
+               enum itm_gts_freq gtsfreq;
+               /** Identifier for multi-source trace stream formatting */
+               unsigned int tracebusid;
+       } itm_tcr;
+
        /** Enable async timestamps model */
        bool itm_async_timestamps;
-       /** Enable synchronisation packet transmission (for sync port only) */
-       bool itm_synchro_packets;
 
        /** Current frequency of TRACECLKIN (usually matches HCLK) */
        unsigned int traceclkin_freq;
diff --git a/src/target/cortex_m.h b/src/target/cortex_m.h
index 3d9714b..e8b7023 100644
--- a/src/target/cortex_m.h
+++ b/src/target/cortex_m.h
@@ -37,6 +37,20 @@
 #define ITM_LAR                0xE0000FB0
 #define ITM_LAR_KEY    0xC5ACCE55
 
+#define TCR_ITMENA     (1 << 0)
+#define TCR_TSENA      (1 << 1)
+#define TCR_SYNCENA    (1 << 2)
+#define TCR_TXENA      (1 << 3)
+#define TCR_SWOENA     (1 << 4)
+#define TCR_BUSY       (1 << 23)
+
+#define TCR_TSPRESCALE_POS     8
+#define TCR_TSPRESCALE_MSK     0x03
+#define TCR_GTSFREQ_POS                10
+#define TCR_GTSFREQ_MSK                0x03
+#define TCR_TRACEBUSID_POS     16
+#define TCR_TRACEBUSID_MSK     0x7F
+
 #define CPUID          0xE000ED00
 /* Debug Control Block */
 #define DCB_DHCSR      0xE000EDF0

-- 

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
OpenOCD-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openocd-devel

Reply via email to