]> git.sur5r.net Git - openocd/blobdiff - src/target/arm_adi_v5.c
target/arm_adi_v5: add command "dpreg"
[openocd] / src / target / arm_adi_v5.c
index d0a58bda0b9a3ecad8c8f5069702bb4c09783c66..dc5c803936ddb7238fb734f2f64b7135338978e4 100644 (file)
@@ -102,8 +102,10 @@ static int mem_ap_setup_csw(struct adiv5_ap *ap, uint32_t csw)
        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;
@@ -114,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;
        }
@@ -1722,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)
@@ -1731,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))
@@ -1738,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);
@@ -1754,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);
@@ -1818,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,