arm_adi_v5: fix for csw nonsecure access. 76/1276/3
authorMichel JAOUEN <michel.jaouen@stericsson.com>
Mon, 18 Mar 2013 15:45:40 +0000 (16:45 +0100)
committerSpencer Oliver <spen@spen-soft.co.uk>
Thu, 11 Apr 2013 16:06:31 +0000 (16:06 +0000)
Add command to fix CSW_SPROT in register AP_CSW.
This solves dap apmem access in non secure access.

Change-Id: I7cfcb6434d75f5cfd4a2630a059901cdeea010ce
Signed-off-by: Michel JAOUEN <michel.jaouen@stericsson.com>
Reviewed-on: http://openocd.zylin.com/1276
Tested-by: jenkins
Reviewed-by: mike brown
Reviewed-by: Spencer Oliver <spen@spen-soft.co.uk>
doc/openocd.texi
src/target/arm_adi_v5.c
src/target/arm_adi_v5.h

index 571faec..cb32998 100644 (file)
@@ -7325,6 +7325,11 @@ memory bus access [0-255], giving additional time to respond to reads.
 If @var{value} is defined, first assigns that.
 @end deffn
 
+@deffn Command {dap apcsw} [0 / 1]
+fix CSW_SPROT from register AP_REG_CSW on selected dap.
+Defaulting to 0.
+@end deffn
+
 @subsection Cortex-M3 specific commands
 @cindex Cortex-M3
 
index 28f4318..1018ede 100644 (file)
@@ -137,8 +137,9 @@ void dap_ap_select(struct adiv5_dap *dap, uint8_t ap)
 int dap_setup_accessport(struct adiv5_dap *dap, uint32_t csw, uint32_t tar)
 {
        int retval;
+       csw = csw | CSW_DBGSWENABLE | CSW_MASTER_DEBUG | CSW_HPROT |
+               dap->apcsw[dap->ap_current >> 24];
 
-       csw = csw | CSW_DBGSWENABLE | CSW_MASTER_DEBUG | CSW_HPROT;
        if (csw != dap->ap_csw_value) {
                /* LOG_DEBUG("DAP: Set CSW %x",csw); */
                retval = dap_queue_ap_write(dap, AP_REG_CSW, csw);
@@ -1847,6 +1848,39 @@ COMMAND_HANDLER(dap_apsel_command)
        return retval;
 }
 
+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->apcsw[dap->apsel], sprot = 0;
+
+       switch (CMD_ARGC) {
+       case 0:
+               command_print(CMD_CTX, "apsel %" PRIi32 " selected, csw 0x%8.8" PRIx32,
+                       (dap->apsel), apcsw);
+               break;
+       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;
+               else
+                       apcsw &= ~CSW_SPROT;
+               break;
+       default:
+               return ERROR_COMMAND_SYNTAX_ERROR;
+       }
+       dap->apcsw[dap->apsel] = apcsw;
+
+       return 0;
+}
+
+
+
 COMMAND_HANDLER(dap_apid_command)
 {
        struct target *target = get_current_target(CMD_CTX);
@@ -1902,6 +1936,14 @@ static const struct command_registration dap_commands[] = {
                .usage = "[ap_num]",
        },
        {
+               .name = "apcsw",
+               .handler = dap_apcsw_command,
+               .mode = COMMAND_EXEC,
+               .help = "Set csw access bit ",
+               .usage = "[sprot]",
+       },
+
+       {
                .name = "apid",
                .handler = dap_apid_command,
                .mode = COMMAND_EXEC,
index 301402e..638fc4e 100644 (file)
 /* 30:24 - implementation-defined! */
 #define CSW_HPROT                      (1 << 25)               /* ? */
 #define CSW_MASTER_DEBUG       (1 << 29)               /* ? */
+#define CSW_SPROT (1 << 30)
 #define CSW_DBGSWENABLE                (1 << 31)
 
 /**
@@ -141,6 +142,7 @@ struct adiv5_dap {
        /* Control config */
        uint32_t dp_ctrl_stat;
 
+       uint32_t apcsw[256];
        uint32_t apsel;
 
        /**