X-Git-Url: https://review.openocd.org/gitweb?a=blobdiff_plain;f=src%2Ftarget%2Farm_adi_v5.c;h=dc5c803936ddb7238fb734f2f64b7135338978e4;hb=c04a59286ea2ba014fbd6f02b8c1072c8b29b924;hp=f9b51cdec1e3bb1dc1a66acfb8436a194d1b6594;hpb=0dba1815e6362cc08e983f8f09af0224ad5ae693;p=openocd.git diff --git a/src/target/arm_adi_v5.c b/src/target/arm_adi_v5.c index f9b51cdec1..dc5c803936 100644 --- a/src/target/arm_adi_v5.c +++ b/src/target/arm_adi_v5.c @@ -97,14 +97,15 @@ 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); */ int retval = dap_queue_ap_write(ap, MEM_AP_REG_CSW, csw); - if (retval != ERROR_OK) + if (retval != ERROR_OK) { + ap->csw_value = 0; return retval; + } ap->csw_value = csw; } return ERROR_OK; @@ -115,8 +116,10 @@ static int mem_ap_setup_tar(struct adiv5_ap *ap, uint32_t tar) if (!ap->tar_valid || tar != ap->tar_value) { /* LOG_DEBUG("DAP: Set TAR %x",tar); */ int retval = dap_queue_ap_write(ap, MEM_AP_REG_TAR, tar); - if (retval != ERROR_OK) + if (retval != ERROR_OK) { + ap->tar_valid = false; return retval; + } ap->tar_value = tar; ap->tar_valid = true; } @@ -153,6 +156,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; @@ -1647,22 +1652,33 @@ COMMAND_HANDLER(dap_apcsw_command) { struct adiv5_dap *dap = adiv5_get_dap(CMD_DATA); uint32_t apcsw = dap->ap[dap->apsel].csw_default; - uint32_t sprot = 0; + 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; @@ -1710,6 +1726,7 @@ COMMAND_HANDLER(dap_apreg_command) { struct adiv5_dap *dap = adiv5_get_dap(CMD_DATA); uint32_t apsel, reg, value; + struct adiv5_ap *ap; int retval; if (CMD_ARGC < 2 || CMD_ARGC > 3) @@ -1719,6 +1736,7 @@ COMMAND_HANDLER(dap_apreg_command) /* AP address is in bits 31:24 of DP_SELECT */ if (apsel >= 256) return ERROR_COMMAND_SYNTAX_ERROR; + ap = dap_ap(dap, apsel); COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], reg); if (reg >= 256 || (reg & 3)) @@ -1726,9 +1744,21 @@ COMMAND_HANDLER(dap_apreg_command) if (CMD_ARGC == 3) { COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], value); - retval = dap_queue_ap_write(dap_ap(dap, apsel), reg, value); + switch (reg) { + case MEM_AP_REG_CSW: + ap->csw_default = 0; /* invalid, force write */ + retval = mem_ap_setup_csw(ap, value); + break; + case MEM_AP_REG_TAR: + ap->tar_valid = false; /* invalid, force write */ + retval = mem_ap_setup_tar(ap, value); + break; + default: + retval = dap_queue_ap_write(ap, reg, value); + break; + } } else { - retval = dap_queue_ap_read(dap_ap(dap, apsel), reg, &value); + retval = dap_queue_ap_read(ap, reg, &value); } if (retval == ERROR_OK) retval = dap_run(dap); @@ -1742,6 +1772,37 @@ COMMAND_HANDLER(dap_apreg_command) return retval; } +COMMAND_HANDLER(dap_dpreg_command) +{ + struct adiv5_dap *dap = adiv5_get_dap(CMD_DATA); + uint32_t reg, value; + int retval; + + if (CMD_ARGC < 1 || CMD_ARGC > 2) + return ERROR_COMMAND_SYNTAX_ERROR; + + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], reg); + if (reg >= 256 || (reg & 3)) + return ERROR_COMMAND_SYNTAX_ERROR; + + if (CMD_ARGC == 2) { + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], value); + retval = dap_queue_dp_write(dap, reg, value); + } else { + retval = dap_queue_dp_read(dap, reg, &value); + } + if (retval == ERROR_OK) + retval = dap_run(dap); + + if (retval != ERROR_OK) + return retval; + + if (CMD_ARGC == 1) + command_print(CMD_CTX, "0x%08" PRIx32, value); + + return retval; +} + COMMAND_HANDLER(dap_ti_be_32_quirks_command) { struct adiv5_dap *dap = adiv5_get_dap(CMD_DATA); @@ -1786,8 +1847,8 @@ const struct command_registration dap_instance_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]]", }, { @@ -1806,6 +1867,14 @@ const struct command_registration dap_instance_commands[] = { "(reg is byte address of a word register, like 0 4 8...)", .usage = "ap_num reg [value]", }, + { + .name = "dpreg", + .handler = dap_dpreg_command, + .mode = COMMAND_EXEC, + .help = "read/write a register from DP " + "(reg is byte address (bank << 4 | reg) of a word register, like 0 4 8...)", + .usage = "reg [value]", + }, { .name = "baseaddr", .handler = dap_baseaddr_command,