X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Ftarget%2Farm_adi_v5.c;h=d0a58bda0b9a3ecad8c8f5069702bb4c09783c66;hp=a4ca9f12c86a79e55e93a0d5798fe8c34289ff28;hb=b50fa9a19d0b600d26b6cbca57cd94c7b89f941c;hpb=f7836bbc75586666d639edd1cf39a871c434d980 diff --git a/src/target/arm_adi_v5.c b/src/target/arm_adi_v5.c index a4ca9f12c8..d0a58bda0b 100644 --- a/src/target/arm_adi_v5.c +++ b/src/target/arm_adi_v5.c @@ -76,6 +76,7 @@ #include #include #include +#include /* ARM ADI Specification requires at least 10 bits used for TAR autoincrement */ @@ -96,8 +97,7 @@ static uint32_t max_tar_block_size(uint32_t tar_autoincr_block, uint32_t address static int mem_ap_setup_csw(struct adiv5_ap *ap, uint32_t csw) { - csw = csw | CSW_DBGSWENABLE | CSW_MASTER_DEBUG | CSW_HPROT | - ap->csw_default; + csw |= ap->csw_default; if (csw != ap->csw_value) { /* LOG_DEBUG("DAP: Set CSW %x",csw); */ @@ -152,6 +152,8 @@ static uint32_t mem_ap_get_tar_increment(struct adiv5_ap *ap) return 2; case CSW_32BIT: return 4; + default: + return 0; } case CSW_ADDRINC_PACKED: return 4; @@ -325,7 +327,7 @@ static int mem_ap_write(struct adiv5_ap *ap, const uint8_t *buffer, uint32_t siz const uint32_t csw_addrincr = addrinc ? CSW_ADDRINC_SINGLE : CSW_ADDRINC_OFF; uint32_t csw_size; uint32_t addr_xor; - int retval; + int retval = ERROR_OK; /* TI BE-32 Quirks mode: * Writes on big-endian TMS570 behave very strangely. Observed behavior: @@ -455,7 +457,7 @@ static int mem_ap_read(struct adiv5_ap *ap, uint8_t *buffer, uint32_t size, uint const uint32_t csw_addrincr = addrinc ? CSW_ADDRINC_SINGLE : CSW_ADDRINC_OFF; uint32_t csw_size; uint32_t address = adr; - int retval; + int retval = ERROR_OK; /* TI BE-32 Quirks mode: * Reads on big-endian TMS570 behave strangely differently than writes. @@ -479,7 +481,8 @@ static int mem_ap_read(struct adiv5_ap *ap, uint8_t *buffer, uint32_t size, uint /* Allocate buffer to hold the sequence of DRW reads that will be made. This is a significant * over-allocation if packed transfers are going to be used, but determining the real need at * this point would be messy. */ - uint32_t *read_buf = malloc(count * sizeof(uint32_t)); + uint32_t *read_buf = calloc(count, sizeof(uint32_t)); + /* Multiplication count * sizeof(uint32_t) may overflow, calloc() is safe */ uint32_t *read_ptr = read_buf; if (read_buf == NULL) { LOG_ERROR("Failed to allocate read buffer"); @@ -613,33 +616,8 @@ int mem_ap_write_buf_noincr(struct adiv5_ap *ap, #define DAP_POWER_DOMAIN_TIMEOUT (10) -/* FIXME don't import ... just initialize as - * part of DAP transport setup -*/ -extern const struct dap_ops jtag_dp_ops; - /*--------------------------------------------------------------------------*/ -/** - * Create a new DAP - */ -struct adiv5_dap *dap_init(void) -{ - struct adiv5_dap *dap = calloc(1, sizeof(struct adiv5_dap)); - int i; - /* Set up with safe defaults */ - for (i = 0; i <= 255; i++) { - dap->ap[i].dap = dap; - dap->ap[i].ap_num = i; - /* memaccess_tck max is 255 */ - dap->ap[i].memaccess_tck = 255; - /* Number of bits for tar autoincrement, impl. dep. at least 10 */ - dap->ap[i].tar_autoincr_block = (1<<10); - } - INIT_LIST_HEAD(&dap->cmd_journal); - return dap; -} - /** * Invalidate cached DP select and cached TAR and CSW of all APs */ @@ -666,14 +644,7 @@ int dap_dp_init(struct adiv5_dap *dap) { int retval; - LOG_DEBUG(" "); - /* JTAG-DP or SWJ-DP, in JTAG mode - * ... for SWD mode this is patched as part - * of link switchover - * FIXME: This should already be setup by the respective transport specific DAP creation. - */ - if (!dap->ops) - dap->ops = &jtag_dp_ops; + LOG_DEBUG("%s", adiv5_dap_name(dap)); dap_invalidate_cache(dap); @@ -706,12 +677,14 @@ int dap_dp_init(struct adiv5_dap *dap) if (retval != ERROR_OK) return retval; - LOG_DEBUG("DAP: wait CSYSPWRUPACK"); - retval = dap_dp_poll_register(dap, DP_CTRL_STAT, - CSYSPWRUPACK, CSYSPWRUPACK, - DAP_POWER_DOMAIN_TIMEOUT); - if (retval != ERROR_OK) - return retval; + if (!dap->ignore_syspwrupack) { + LOG_DEBUG("DAP: wait CSYSPWRUPACK"); + retval = dap_dp_poll_register(dap, DP_CTRL_STAT, + CSYSPWRUPACK, CSYSPWRUPACK, + DAP_POWER_DOMAIN_TIMEOUT); + if (retval != ERROR_OK) + return retval; + } retval = dap_queue_dp_read(dap, DP_CTRL_STAT, NULL); if (retval != ERROR_OK) @@ -1375,7 +1348,7 @@ static int dap_rom_display(struct command_context *cmd_ctx, return ERROR_OK; } -static int dap_info_command(struct command_context *cmd_ctx, +int dap_info_command(struct command_context *cmd_ctx, struct adiv5_ap *ap) { int retval; @@ -1433,46 +1406,131 @@ static int dap_info_command(struct command_context *cmd_ctx, return ERROR_OK; } +enum adiv5_cfg_param { + CFG_DAP, + CFG_AP_NUM +}; + +static const Jim_Nvp nvp_config_opts[] = { + { .name = "-dap", .value = CFG_DAP }, + { .name = "-ap-num", .value = CFG_AP_NUM }, + { .name = NULL, .value = -1 } +}; + int adiv5_jim_configure(struct target *target, Jim_GetOptInfo *goi) { struct adiv5_private_config *pc; - const char *arg; - jim_wide ap_num; int e; - /* check if argv[0] is for us */ - arg = Jim_GetString(goi->argv[0], NULL); - if (strcmp(arg, "-ap-num")) - return JIM_CONTINUE; + pc = (struct adiv5_private_config *)target->private_config; + if (pc == NULL) { + pc = calloc(1, sizeof(struct adiv5_private_config)); + pc->ap_num = -1; + target->private_config = pc; + } - e = Jim_GetOpt_String(goi, &arg, NULL); - if (e != JIM_OK) - return e; + target->has_dap = true; + + if (goi->argc > 0) { + Jim_Nvp *n; + + Jim_SetEmptyResult(goi->interp); + + /* check first if topmost item is for us */ + 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; + + switch (n->value) { + case CFG_DAP: + if (goi->isconfigure) { + Jim_Obj *o_t; + struct adiv5_dap *dap; + e = Jim_GetOpt_Obj(goi, &o_t); + if (e != JIM_OK) + return e; + dap = dap_instance_by_jim_obj(goi->interp, o_t); + if (dap == NULL) { + Jim_SetResultString(goi->interp, "DAP name invalid!", -1); + return JIM_ERR; + } + if (pc->dap != NULL && pc->dap != dap) { + Jim_SetResultString(goi->interp, + "DAP assignment cannot be changed after target was created!", -1); + return JIM_ERR; + } + if (target->tap_configured) { + Jim_SetResultString(goi->interp, + "-chain-position and -dap configparams are mutually exclusive!", -1); + return JIM_ERR; + } + pc->dap = dap; + target->tap = dap->tap; + target->dap_configured = true; + } else { + if (goi->argc != 0) { + Jim_WrongNumArgs(goi->interp, + goi->argc, goi->argv, + "NO PARAMS"); + return JIM_ERR; + } + + if (pc->dap == NULL) { + Jim_SetResultString(goi->interp, "DAP not configured", -1); + return JIM_ERR; + } + Jim_SetResultString(goi->interp, adiv5_dap_name(pc->dap), -1); + } + break; - if (goi->argc == 0) { - Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv, "-ap-num ?ap-number? ..."); - return JIM_ERR; + case CFG_AP_NUM: + if (goi->isconfigure) { + jim_wide ap_num; + e = Jim_GetOpt_Wide(goi, &ap_num); + if (e != JIM_OK) + return e; + pc->ap_num = ap_num; + } else { + if (goi->argc != 0) { + Jim_WrongNumArgs(goi->interp, + goi->argc, goi->argv, + "NO PARAMS"); + return JIM_ERR; + } + + if (pc->ap_num < 0) { + Jim_SetResultString(goi->interp, "AP number not configured", -1); + return JIM_ERR; + } + Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, (int)pc->ap_num)); + } + break; + } } - e = Jim_GetOpt_Wide(goi, &ap_num); - if (e != JIM_OK) - return e; + return JIM_OK; +} - if (target->private_config == NULL) { - pc = calloc(1, sizeof(struct adiv5_private_config)); - target->private_config = pc; - pc->ap_num = ap_num; - } +int adiv5_verify_config(struct adiv5_private_config *pc) +{ + if (pc == NULL) + return ERROR_FAIL; + if (pc->dap == NULL) + return ERROR_FAIL; - return JIM_OK; + return ERROR_OK; } + COMMAND_HANDLER(handle_dap_info_command) { - struct target *target = get_current_target(CMD_CTX); - struct arm *arm = target_to_arm(target); - struct adiv5_dap *dap = arm->dap; + struct adiv5_dap *dap = adiv5_get_dap(CMD_DATA); uint32_t apsel; switch (CMD_ARGC) { @@ -1493,10 +1551,7 @@ COMMAND_HANDLER(handle_dap_info_command) COMMAND_HANDLER(dap_baseaddr_command) { - struct target *target = get_current_target(CMD_CTX); - struct arm *arm = target_to_arm(target); - struct adiv5_dap *dap = arm->dap; - + struct adiv5_dap *dap = adiv5_get_dap(CMD_DATA); uint32_t apsel, baseaddr; int retval; @@ -1533,10 +1588,7 @@ COMMAND_HANDLER(dap_baseaddr_command) COMMAND_HANDLER(dap_memaccess_command) { - struct target *target = get_current_target(CMD_CTX); - struct arm *arm = target_to_arm(target); - struct adiv5_dap *dap = arm->dap; - + struct adiv5_dap *dap = adiv5_get_dap(CMD_DATA); uint32_t memaccess_tck; switch (CMD_ARGC) { @@ -1559,10 +1611,7 @@ COMMAND_HANDLER(dap_memaccess_command) COMMAND_HANDLER(dap_apsel_command) { - struct target *target = get_current_target(CMD_CTX); - struct arm *arm = target_to_arm(target); - struct adiv5_dap *dap = arm->dap; - + struct adiv5_dap *dap = adiv5_get_dap(CMD_DATA); uint32_t apsel, apid; int retval; @@ -1597,26 +1646,35 @@ COMMAND_HANDLER(dap_apsel_command) COMMAND_HANDLER(dap_apcsw_command) { - struct target *target = get_current_target(CMD_CTX); - struct arm *arm = target_to_arm(target); - struct adiv5_dap *dap = arm->dap; - - uint32_t apcsw = dap->ap[dap->apsel].csw_default, sprot = 0; + struct adiv5_dap *dap = adiv5_get_dap(CMD_DATA); + uint32_t apcsw = dap->ap[dap->apsel].csw_default; + uint32_t csw_val, csw_mask; switch (CMD_ARGC) { case 0: - command_print(CMD_CTX, "apsel %" PRIi32 " selected, csw 0x%8.8" PRIx32, - (dap->apsel), apcsw); - break; + command_print(CMD_CTX, "ap %" PRIi32 " selected, csw 0x%8.8" PRIx32, + dap->apsel, apcsw); + return ERROR_OK; case 1: - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], sprot); - /* AP address is in bits 31:24 of DP_SELECT */ - if (sprot > 1) - return ERROR_COMMAND_SYNTAX_ERROR; - if (sprot) - apcsw |= CSW_SPROT; + if (strcmp(CMD_ARGV[0], "default") == 0) + csw_val = CSW_DEFAULT; else - apcsw &= ~CSW_SPROT; + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], csw_val); + + if (csw_val & (CSW_SIZE_MASK | CSW_ADDRINC_MASK)) { + LOG_ERROR("CSW value cannot include 'Size' and 'AddrInc' bit-fields"); + return ERROR_COMMAND_SYNTAX_ERROR; + } + apcsw = csw_val; + break; + case 2: + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], csw_val); + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], csw_mask); + if (csw_mask & (CSW_SIZE_MASK | CSW_ADDRINC_MASK)) { + LOG_ERROR("CSW mask cannot include 'Size' and 'AddrInc' bit-fields"); + return ERROR_COMMAND_SYNTAX_ERROR; + } + apcsw = (apcsw & ~csw_mask) | (csw_val & csw_mask); break; default: return ERROR_COMMAND_SYNTAX_ERROR; @@ -1630,10 +1688,7 @@ COMMAND_HANDLER(dap_apcsw_command) COMMAND_HANDLER(dap_apid_command) { - struct target *target = get_current_target(CMD_CTX); - struct arm *arm = target_to_arm(target); - struct adiv5_dap *dap = arm->dap; - + struct adiv5_dap *dap = adiv5_get_dap(CMD_DATA); uint32_t apsel, apid; int retval; @@ -1665,10 +1720,7 @@ COMMAND_HANDLER(dap_apid_command) COMMAND_HANDLER(dap_apreg_command) { - struct target *target = get_current_target(CMD_CTX); - struct arm *arm = target_to_arm(target); - struct adiv5_dap *dap = arm->dap; - + struct adiv5_dap *dap = adiv5_get_dap(CMD_DATA); uint32_t apsel, reg, value; int retval; @@ -1704,10 +1756,7 @@ COMMAND_HANDLER(dap_apreg_command) COMMAND_HANDLER(dap_ti_be_32_quirks_command) { - struct target *target = get_current_target(CMD_CTX); - struct arm *arm = target_to_arm(target); - struct adiv5_dap *dap = arm->dap; - + struct adiv5_dap *dap = adiv5_get_dap(CMD_DATA); uint32_t enable = dap->ti_be_32_quirks; switch (CMD_ARGC) { @@ -1728,7 +1777,7 @@ COMMAND_HANDLER(dap_ti_be_32_quirks_command) return 0; } -static const struct command_registration dap_commands[] = { +const struct command_registration dap_instance_commands[] = { { .name = "info", .handler = handle_dap_info_command, @@ -1749,8 +1798,8 @@ static const struct command_registration dap_commands[] = { .name = "apcsw", .handler = dap_apcsw_command, .mode = COMMAND_EXEC, - .help = "Set csw access bit ", - .usage = "[sprot]", + .help = "Set CSW default bits", + .usage = "[value [mask]]", }, { @@ -1794,14 +1843,3 @@ static const struct command_registration dap_commands[] = { }, COMMAND_REGISTRATION_DONE }; - -const struct command_registration dap_command_handlers[] = { - { - .name = "dap", - .mode = COMMAND_EXEC, - .help = "DAP command group", - .usage = "", - .chain = dap_commands, - }, - COMMAND_REGISTRATION_DONE -};