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
