This is an automated email from Gerrit.

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

-- gerrit

commit 0a470c344b87684cabd74fa5daff5063fb3844ff
Author: Matthias Welwarsky <[email protected]>
Date:   Wed Mar 1 16:22:07 2017 +0100

    arm_cti: add cti commands [WIP]
    
    Extend the CTI abstraction to be accessible from TCL and
    change the 'target' command to accept a cti 'object' instead of a
    base address. This also allows accessing CTI instances that are not
    related to a configured target.
    
    Change-Id: Iac9ed0edca6f1be00fe93783a35c26077f6bc80a
    Signed-off-by: Matthias Welwarsky <[email protected]>

diff --git a/src/openocd.c b/src/openocd.c
index 94fab3a..4d1040a 100644
--- a/src/openocd.c
+++ b/src/openocd.c
@@ -37,6 +37,7 @@
 #include <flash/nand/core.h>
 #include <pld/pld.h>
 #include <flash/mflash.h>
+#include <target/arm_cti.h>
 
 #include <server/server.h>
 #include <server/gdb_server.h>
@@ -252,6 +253,7 @@ struct command_context *setup_command_handler(Jim_Interp 
*interp)
                &nand_register_commands,
                &pld_register_commands,
                &mflash_register_commands,
+               &cti_register_commands,
                NULL
        };
        for (unsigned i = 0; NULL != command_registrants[i]; i++) {
diff --git a/src/target/aarch64.c b/src/target/aarch64.c
index d0f1c7c..8bc99f7 100644
--- a/src/target/aarch64.c
+++ b/src/target/aarch64.c
@@ -2096,7 +2096,6 @@ static int aarch64_examine_first(struct target *target)
        struct aarch64_common *aarch64 = target_to_aarch64(target);
        struct armv8_common *armv8 = &aarch64->armv8_common;
        struct adiv5_dap *swjdp = armv8->arm.dap;
-       uint32_t cti_base;
        int i;
        int retval = ERROR_OK;
        uint64_t debug, ttypr;
@@ -2207,17 +2206,11 @@ static int aarch64_examine_first(struct target *target)
        LOG_DEBUG("ttypr = 0x%08" PRIx64, ttypr);
        LOG_DEBUG("debug = 0x%08" PRIx64, debug);
 
-       if (target->ctibase == 0) {
-               /* assume a v8 rom table layout */
-               cti_base = armv8->debug_base + 0x10000;
-               LOG_INFO("Target ctibase is not set, assuming 0x%0" PRIx32, 
cti_base);
-       } else
-               cti_base = target->ctibase;
-
-       armv8->cti = arm_cti_create(armv8->debug_ap, cti_base);
-       if (armv8->cti == NULL)
+       if (target->cti == NULL)
                return ERROR_FAIL;
 
+       armv8->cti = target->cti;
+
        retval = aarch64_dpm_setup(aarch64, debug);
        if (retval != ERROR_OK)
                return retval;
diff --git a/src/target/arm_cti.c b/src/target/arm_cti.c
index 75169b2..3832da1 100644
--- a/src/target/arm_cti.c
+++ b/src/target/arm_cti.c
@@ -27,21 +27,53 @@
 #include "target/arm_cti.h"
 #include "target/target.h"
 #include "helper/time_support.h"
+#include "helper/list.h"
 
 struct arm_cti {
        uint32_t base;
        struct adiv5_ap *ap;
 };
 
-struct arm_cti *arm_cti_create(struct adiv5_ap *ap, uint32_t base)
+struct arm_cti_object {
+       struct list_head lh;
+       struct arm_cti cti;
+       int ap_num;
+       struct jtag_tap *tap;
+       char *name;
+};
+
+static LIST_HEAD(all_cti);
+
+void arm_cti_dump_info(struct arm_cti *self)
 {
-       struct arm_cti *self = calloc(1, sizeof(struct arm_cti));
-       if (!self)
-               return NULL;
+       LOG_DEBUG("cti.self %p", self);
+       LOG_DEBUG("cti.base 0x%08" PRIx32, self->base);
+}
 
-       self->base = base;
-       self->ap = ap;
-       return self;
+const char *arm_cti_name(struct arm_cti *self)
+{
+       struct arm_cti_object *obj = container_of(self, struct arm_cti_object, 
cti);
+       return obj->name;
+}
+
+struct arm_cti *cti_instance_by_jim_obj(Jim_Interp *interp, Jim_Obj *o)
+{
+       struct arm_cti_object *obj = NULL;
+       const char *name;
+       bool found = false;
+
+       name = Jim_GetString(o, NULL);
+
+       list_for_each_entry(obj, &all_cti, lh) {
+               if (!strcmp(name, obj->name)) {
+                       found = true;
+                       break;
+               }
+       }
+
+       if (found)
+               return &obj->cti;
+       return NULL;
 }
 
 static int arm_cti_mod_reg_bits(struct arm_cti *self, unsigned int reg, 
uint32_t mask, uint32_t value)
@@ -146,3 +178,294 @@ int arm_cti_clear_channel(struct arm_cti *self, uint32_t 
channel)
 
        return arm_cti_write_reg(self, CTI_APPCLEAR, CTI_CHNL(channel));
 }
+
+static uint32_t cti_regs[22];
+
+static const struct {
+       uint32_t offset;
+       const char *label;
+       uint32_t *p_val;
+} cti_names[] = {
+       { CTI_CTR,  "CTI_CTR", &cti_regs[0] },
+       { CTI_GATE, "CTI_GATE", &cti_regs[1] },
+       { CTI_INEN0, "CTI_INEN0", &cti_regs[2] },
+       { CTI_INEN1, "CTI_INEN1", &cti_regs[3] },
+       { CTI_INEN2, "CTI_INEN2", &cti_regs[4] },
+       { CTI_INEN3, "CTI_INEN3", &cti_regs[5] },
+       { CTI_INEN4, "CTI_INEN4", &cti_regs[6] },
+       { CTI_INEN5, "CTI_INEN5", &cti_regs[7] },
+       { CTI_INEN6, "CTI_INEN6", &cti_regs[8] },
+       { CTI_INEN7, "CTI_INEN7", &cti_regs[9] },
+       { CTI_OUTEN0, "CTI_OUTEN0", &cti_regs[10] },
+       { CTI_OUTEN1, "CTI_OUTEN1", &cti_regs[11] },
+       { CTI_OUTEN2, "CTI_OUTEN2", &cti_regs[12] },
+       { CTI_OUTEN3, "CTI_OUTEN3", &cti_regs[13] },
+       { CTI_OUTEN4, "CTI_OUTEN4", &cti_regs[14] },
+       { CTI_OUTEN5, "CTI_OUTEN5", &cti_regs[15] },
+       { CTI_OUTEN6, "CTI_OUTEN6", &cti_regs[16] },
+       { CTI_OUTEN7, "CTI_OUTEN7", &cti_regs[17] },
+       { CTI_TRIN_STATUS, "CTI_TRIN_STATUS", &cti_regs[18] },
+       { CTI_TROUT_STATUS, "CTI_TROUT_STATUS", &cti_regs[19] },
+       { CTI_CHIN_STATUS, "CTI_CHIN_STATUS", &cti_regs[20] },
+       { CTI_CHOU_STATUS, "CTI_CHOUT_STATUS", &cti_regs[21] },
+};
+
+static int jim_cti_dump(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+{
+       struct arm_cti_object *obj = Jim_CmdPrivData(interp);
+       struct command_context *cmd_ctx = current_command_context(interp);
+       struct arm_cti *cti = &obj->cti;
+
+       for (int i=0; i < (int)ARRAY_SIZE(cti_names); i++)
+               mem_ap_read_u32(cti->ap, cti->base + cti_names[i].offset, 
cti_names[i].p_val);
+
+       dap_run(cti->ap->dap);
+
+       for (int i=0; i < (int)ARRAY_SIZE(cti_names); i++)
+               command_print(cmd_ctx, "%16.16s 0x%08" PRIx32, 
cti_names[i].label, *cti_names[i].p_val);
+
+       return JIM_OK;
+}
+
+static const struct command_registration cti_instance_command_handlers[] = {
+       {
+               .name  = "dump",
+               .mode  = COMMAND_EXEC,
+               .jim_handler = jim_cti_dump,
+               .help  = "dump CTI registers",
+               .usage = "",
+       },
+       COMMAND_REGISTRATION_DONE
+};
+
+enum cti_cfg_param {
+       CFG_CHAIN_POSITION,
+       CFG_AP_NUM,
+       CFG_CTIBASE
+};
+
+static const Jim_Nvp nvp_config_opts[] = {
+       { .name = "-chain-position",   .value = CFG_CHAIN_POSITION },
+       { .name = "-ctibase",          .value = CFG_CTIBASE },
+       { .name = "-ap-num",           .value = CFG_AP_NUM },
+       { .name = NULL, .value = -1 }
+};
+
+static int cti_configure(Jim_GetOptInfo *goi, struct arm_cti_object *cti)
+{
+       struct jtag_tap *tap = NULL;
+       Jim_Nvp *n;
+       jim_wide w;
+       int e;
+
+       /* parse config or cget options ... */
+       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 CFG_CHAIN_POSITION:
+                       if (goi->isconfigure) {
+                               Jim_Obj *o_t;
+                               e = Jim_GetOpt_Obj(goi, &o_t);
+                               if (e != JIM_OK)
+                                       return e;
+                               tap = jtag_tap_by_jim_obj(goi->interp, o_t);
+                               if (tap == NULL)
+                                       return JIM_ERR;
+                               /* make this exactly 1 or 0 */
+                               cti->tap = tap;
+                       } else {
+                               if (goi->argc != 0)
+                                       goto no_params;
+                       }
+                       Jim_SetResultString(goi->interp, cti->tap->dotted_name, 
-1);
+                       /* loop for more e*/
+                       break;
+               case CFG_CTIBASE:
+                       if (goi->isconfigure) {
+                               e = Jim_GetOpt_Wide(goi, &w);
+                               if (e != JIM_OK)
+                                       return e;
+                               cti->cti.base = (uint32_t)w;
+                       } else {
+                               if (goi->argc != 0)
+                                       goto no_params;
+                       }
+                       Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, 
cti->cti.base));
+                       /* loop for more */
+                       break;
+               case CFG_AP_NUM:
+                       if (goi->isconfigure) {
+                               e = Jim_GetOpt_Wide(goi, &w);
+                               if (e != JIM_OK)
+                                       return e;
+                               cti->ap_num = (uint32_t)w;
+                       } else {
+                               if (goi->argc != 0)
+                                       goto no_params;
+                       }
+               }
+       }
+
+       if (tap == NULL)
+               goto no_params;
+
+       if (tap->dap == NULL) {
+               tap->dap = dap_init();
+               tap->dap->tap = tap;
+       }
+
+       cti->cti.ap = dap_ap(tap->dap, cti->ap_num);
+
+       return JIM_OK;
+
+no_params:
+       Jim_WrongNumArgs(goi->interp,
+                       goi->argc, goi->argv,
+                       "NO PARAMS");
+       return JIM_ERR;
+}
+
+static int cti_create(Jim_GetOptInfo *goi)
+{
+       struct command_context *cmd_ctx;
+       static struct arm_cti_object *cti;
+       Jim_Obj *new_cmd;
+       Jim_Cmd *cmd;
+       const char* cp;
+       int e;
+
+       cmd_ctx = current_command_context(goi->interp);
+       assert(cmd_ctx != NULL);
+
+       if (goi->argc < 3) {
+               Jim_WrongNumArgs(goi->interp, 1, goi->argv, "?name? 
..options...");
+               return JIM_ERR;
+       }
+       /* COMMAND */
+       Jim_GetOpt_Obj(goi, &new_cmd);
+       /* does this command exist? */
+       cmd = Jim_GetCommand(goi->interp, new_cmd, JIM_ERRMSG);
+       if (cmd) {
+               cp = Jim_GetString(new_cmd, NULL);
+               Jim_SetResultFormatted(goi->interp, "Command: %s Exists", cp);
+               return JIM_ERR;
+       }
+
+       /* Create it */
+       cti = calloc(1, sizeof(struct arm_cti_object));
+
+       /* Do the rest as "configure" options */
+       goi->isconfigure = 1;
+       e = cti_configure(goi, cti);
+
+       if (cti->tap == NULL) {
+               Jim_SetResultString(goi->interp, "-chain-position required when 
creating CTI", -1);
+               e = JIM_ERR;
+       }
+
+       if (e != JIM_OK) {
+               free(cti);
+               return e;
+       }
+
+       cp = Jim_GetString(new_cmd, NULL);
+       cti->name = strdup(cp);
+
+       /* now - create the new cti name command */
+       const struct command_registration cti_subcommands[] = {
+               {
+                       .chain = cti_instance_command_handlers,
+               },
+               COMMAND_REGISTRATION_DONE
+       };
+       const struct command_registration cti_commands[] = {
+               {
+                       .name = cp,
+                       .mode = COMMAND_ANY,
+                       .help = "cti instance command group",
+                       .usage = "",
+                       .chain = cti_subcommands,
+               },
+               COMMAND_REGISTRATION_DONE
+       };
+       e = register_commands(cmd_ctx, NULL, cti_commands);
+       if (ERROR_OK != e)
+               return JIM_ERR;
+
+       struct command *c = command_find_in_context(cmd_ctx, cp);
+       assert(c);
+       command_set_handler_data(c, cti);
+
+       list_add_tail(&cti->lh, &all_cti);
+
+       return (ERROR_OK == e) ? JIM_OK : JIM_ERR;
+}
+
+static int jim_cti_create(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+{
+       Jim_GetOptInfo goi;
+       Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1);
+       if (goi.argc < 2) {
+               Jim_WrongNumArgs(goi.interp, goi.argc, goi.argv,
+                       "<name> [<cti_options> ...]");
+               return JIM_ERR;
+       }
+       return cti_create(&goi);
+}
+
+static int jim_cti_names(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+{
+       struct arm_cti_object *obj;
+
+       if (argc != 1) {
+               Jim_WrongNumArgs(interp, 1, argv, "Too many parameters");
+               return JIM_ERR;
+       }
+       Jim_SetResult(interp, Jim_NewListObj(interp, NULL, 0));
+       list_for_each_entry(obj, &all_cti, lh) {
+               Jim_ListAppendElement(interp, Jim_GetResult(interp),
+                       Jim_NewStringObj(interp, obj->name, -1));
+       }
+       return JIM_OK;
+}
+
+
+static const struct command_registration cti_subcommand_handlers[] = {
+       {
+               .name = "create",
+               .mode = COMMAND_CONFIG,
+               .jim_handler = jim_cti_create,
+               .usage = "name '-chain-position' name [options ...]",
+               .help = "Creates a new CTI object",
+       },
+       {
+               .name = "names",
+               .mode = COMMAND_ANY,
+               .jim_handler = jim_cti_names,
+               .usage = "",
+               .help = "Lists all registered CTI objects by name",
+       },
+       COMMAND_REGISTRATION_DONE
+};
+
+static const struct command_registration cti_command_handlers[] = {
+       {
+               .name = "cti",
+               .mode = COMMAND_CONFIG,
+               .help = "CTI commands",
+               .chain = cti_subcommand_handlers,
+       },
+       COMMAND_REGISTRATION_DONE
+};
+
+int cti_register_commands(struct command_context *cmd_ctx)
+{
+       return register_commands(cmd_ctx, NULL, cti_command_handlers);
+}
+
diff --git a/src/target/arm_cti.h b/src/target/arm_cti.h
index 99724c4..e42829b 100644
--- a/src/target/arm_cti.h
+++ b/src/target/arm_cti.h
@@ -58,8 +58,11 @@
 
 /* forward-declare arm_cti struct */
 struct arm_cti;
+struct adiv5_ap;
 
-extern struct arm_cti *arm_cti_create(struct adiv5_ap *ap, uint32_t base);
+extern void arm_cti_dump_info(struct arm_cti *self);
+extern const char *arm_cti_name(struct arm_cti *self);
+extern struct arm_cti *cti_instance_by_jim_obj(Jim_Interp *interp, Jim_Obj *o);
 extern int arm_cti_enable(struct arm_cti *self, bool enable);
 extern int arm_cti_ack_events(struct arm_cti *self, uint32_t event);
 extern int arm_cti_gate_channel(struct arm_cti *self, uint32_t channel);
@@ -70,4 +73,6 @@ extern int arm_cti_pulse_channel(struct arm_cti *self, 
uint32_t channel);
 extern int arm_cti_set_channel(struct arm_cti *self, uint32_t channel);
 extern int arm_cti_clear_channel(struct arm_cti *self, uint32_t channel);
 
+extern int cti_register_commands(struct command_context *cmd_ctx);
+
 #endif /* OPENOCD_TARGET_ARM_CTI_H */
diff --git a/src/target/target.c b/src/target/target.c
index ee302ee..909482f 100644
--- a/src/target/target.c
+++ b/src/target/target.c
@@ -54,6 +54,7 @@
 #include "image.h"
 #include "rtos/rtos.h"
 #include "transport/transport.h"
+#include "arm_cti.h"
 
 /* default halt wait timeout (ms) */
 #define DEFAULT_HALT_TIMEOUT 5000
@@ -4445,7 +4446,7 @@ enum target_cfg_param {
        TCFG_COREID,
        TCFG_CHAIN_POSITION,
        TCFG_DBGBASE,
-       TCFG_CTIBASE,
+       TCFG_CTI,
        TCFG_RTOS,
        TCFG_DEFER_EXAMINE,
 };
@@ -4461,7 +4462,7 @@ static Jim_Nvp nvp_config_opts[] = {
        { .name = "-coreid",           .value = TCFG_COREID },
        { .name = "-chain-position",   .value = TCFG_CHAIN_POSITION },
        { .name = "-dbgbase",          .value = TCFG_DBGBASE },
-       { .name = "-ctibase",          .value = TCFG_CTIBASE },
+       { .name = "-cti",              .value = TCFG_CTI },
        { .name = "-rtos",             .value = TCFG_RTOS },
        { .name = "-defer-examine",    .value = TCFG_DEFER_EXAMINE },
        { .name = NULL, .value = -1 }
@@ -4728,18 +4729,23 @@ no_params:
                        Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, 
target->dbgbase));
                        /* loop for more */
                        break;
-               case TCFG_CTIBASE:
+               case TCFG_CTI:
                        if (goi->isconfigure) {
-                               e = Jim_GetOpt_Wide(goi, &w);
+                               Jim_Obj *o_cti;
+                               struct arm_cti *cti;
+                               e = Jim_GetOpt_Obj(goi, &o_cti);
                                if (e != JIM_OK)
                                        return e;
-                               target->ctibase = (uint32_t)w;
-                               target->ctibase_set = true;
+                               cti = cti_instance_by_jim_obj(goi->interp, 
o_cti);
+                               if (cti == NULL)
+                                       return JIM_ERR;
+                               /* make this exactly 1 or 0 */
+                               target->cti = cti;
                        } else {
                                if (goi->argc != 0)
                                        goto no_params;
                        }
-                       Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, 
target->ctibase));
+                       Jim_SetResultString(goi->interp, 
arm_cti_name(target->cti), -1);
                        /* loop for more */
                        break;
                case TCFG_RTOS:
diff --git a/src/target/target.h b/src/target/target.h
index 76630b9..4855f03 100644
--- a/src/target/target.h
+++ b/src/target/target.h
@@ -186,10 +186,7 @@ struct target {
                                                                                
 * system in place to support target specific options
                                                                                
 * currently. */
 
-        bool ctibase_set;                                       /* By default 
the debug base is not set */
-        uint32_t ctibase;                                       /* Really a 
Cortex-A specific option, but there is no
-                                                                               
  * system in place to support target specific options
-                                                                               
  * currently. */
+       struct arm_cti *cti;
        struct rtos *rtos;                                      /* Instance of 
Real Time Operating System support */
        bool rtos_auto_detect;                          /* A flag that 
indicates that the RTOS has been specified as "auto"
                                                                                
 * and must be detected when symbols are offered */
diff --git a/tcl/target/hi6220.cfg b/tcl/target/hi6220.cfg
index 7daa3c1..a4a3836 100644
--- a/tcl/target/hi6220.cfg
+++ b/tcl/target/hi6220.cfg
@@ -34,8 +34,10 @@ set $_TARGETNAME.cti(7) 0x801DB000
 set _cores 8
 for { set _core 0 } { $_core < $_cores } { incr _core 1 } {
 
+    cti create cti$_core -chain-position $_CHIPNAME.dap -ctibase [set 
$_TARGETNAME.cti($_core)] -ap-num 0
+
     set _command "target create ${_TARGETNAME}$_core aarch64 \
-                         -chain-position $_CHIPNAME.dap -coreid $_core 
-ctibase [set $_TARGETNAME.cti($_core)]"
+                         -chain-position $_CHIPNAME.dap -coreid $_core -cti 
cti$_core"
 
     if { $_core != 0 } {
         # non-boot core examination may fail
@@ -43,7 +45,7 @@ for { set _core 0 } { $_core < $_cores } { incr _core 1 } {
         set _smp_command "$_smp_command ${_TARGETNAME}$_core"
     } else {
         # uncomment when "hawt" rtos is merged
-        # set _command "$_command -rtos hawt"
+        set _command "$_command -rtos hawt"
         set _smp_command "target smp ${_TARGETNAME}$_core"
     }
 
@@ -52,5 +54,10 @@ for { set _core 0 } { $_core < $_cores } { incr _core 1 } {
 
 eval $_smp_command
 
+cti create cti.sys -chain-position hi6220.dap -ap-num 0 -ctibase 0x80003000
+
 # declare the auxiliary Cortex-M3 core on AP #2 (runs mcuimage.bin)
 target create ${_TARGETNAME}.m3 cortex_m -chain-position $_CHIPNAME.dap 
-ap-num 2 -defer-examine
+
+# declare the auxiliary Cortex-A7 core
+target create ${_TARGETNAME}.a7 cortex_a -chain-position $_CHIPNAME.dap 
-dbgbase 0x80210000 -defer-examine

-- 

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