target/arm_adi_v5: extend apcsw command to accept arbitrary bits 31/4431/6
authorTomas Vanek <vanekt@fbl.cz>
Thu, 22 Feb 2018 23:03:20 +0000 (00:03 +0100)
committerMatthias Welwarsky <matthias@welwarsky.de>
Sat, 7 Apr 2018 19:31:37 +0000 (20:31 +0100)
apcsw command was limited to SPROT bit only.

Now user can manipulate any bit except size and addrinc fields.
Can be used e.g. to set bus signal 'cacheable' on Cortex-M7

Change-Id: Ia1c22b208e46d1653136f6faa5a7aaab036de7aa
Signed-off-by: Tomas Vanek <vanekt@fbl.cz>
Reviewed-on: http://openocd.zylin.com/4431
Tested-by: jenkins
Reviewed-by: Matthias Welwarsky <matthias@welwarsky.de>
doc/openocd.texi
src/target/arm_adi_v5.c
src/target/arm_adi_v5.h
src/target/arm_dap.c

index 967c637ae7c565f81ae4eee3ab4e4082ba76999a..1243438a493d7b2881c209594be19e9f14865f5f 100644 (file)
@@ -4070,6 +4070,7 @@ defaulting to the currently selected AP.
 Displays ID register from AP @var{num}, defaulting to the currently selected AP.
 @end deffn
 
 Displays ID register from AP @var{num}, defaulting to the currently selected AP.
 @end deffn
 
+@anchor{DAP subcommand apreg}
 @deffn Command {$dap_name apreg} ap_num reg [value]
 Displays content of a register @var{reg} from AP @var{ap_num}
 or set a new value @var{value}.
 @deffn Command {$dap_name apreg} ap_num reg [value]
 Displays content of a register @var{reg} from AP @var{ap_num}
 or set a new value @var{value}.
@@ -4091,9 +4092,47 @@ memory bus access [0-255], giving additional time to respond to reads.
 If @var{value} is defined, first assigns that.
 @end deffn
 
 If @var{value} is defined, first assigns that.
 @end deffn
 
-@deffn Command {$dap_name apcsw} [0 / 1]
-fix CSW_SPROT from register AP_REG_CSW on selected dap.
-Defaulting to 0.
+@deffn Command {$dap_name apcsw} [value [mask]]
+Displays or changes CSW bit pattern for MEM-AP transfers.
+
+At the begin of each memory access the CSW pattern is extended (bitwise or-ed)
+by @dfn{Size} and @dfn{AddrInc} bit-fields according to transfer requirements
+and the result is written to the real CSW register. All bits except dynamically
+updated fields @dfn{Size} and @dfn{AddrInc} can be changed by changing
+the CSW pattern. Refer to ARM ADI v5 manual chapter 7.6.4 and appendix A
+for details.
+
+Use @var{value} only syntax if you want to set the new CSW pattern as a whole.
+The example sets HPROT1 bit (required by Cortex-M) and clears the rest of
+the pattern:
+@example
+kx.dap apcsw 0x2000000
+@end example
+
+If @var{mask} is also used, the CSW pattern is changed only on bit positions
+where the mask bit is 1. The following example sets HPROT3 (cacheable)
+and leaves the rest of the pattern intact. It configures memory access through
+DCache on Cortex-M7.
+@example
+set CSW_HPROT3_CACHEABLE [expr 1 << 27]
+samv.dap apcsw $CSW_HPROT3_CACHEABLE $CSW_HPROT3_CACHEABLE
+@end example
+
+Another example clears SPROT bit and leaves the rest of pattern intact:
+@example
+set CSW_SPROT [expr 1 << 30]
+samv.dap apcsw 0 $CSW_SPROT
+@end example
+
+@emph{Note:} If you want to check the real value of CSW, not CSW pattern, use
+@code{xxx.dap apreg 0}. @xref{DAP subcommand apreg,,}.
+
+@emph{Warning:} Some of the CSW bits are vital for working memory transfer.
+If you set a wrong CSW pattern and MEM-AP stopped working, use the following
+example with a proper dap name:
+@example
+xxx.dap apcsw default
+@end example
 @end deffn
 
 @deffn Command {$dap_name ti_be_32_quirks} [@option{enable}]
 @end deffn
 
 @deffn Command {$dap_name ti_be_32_quirks} [@option{enable}]
index f9b51cdec1e3bb1dc1a66acfb8436a194d1b6594..e2d9b5e66873f2980f8aabbb44e6b15fe2b01555 100644 (file)
@@ -97,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)
 {
 
 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); */
 
        if (csw != ap->csw_value) {
                /* LOG_DEBUG("DAP: Set CSW %x",csw); */
@@ -1647,22 +1646,33 @@ COMMAND_HANDLER(dap_apcsw_command)
 {
        struct adiv5_dap *dap = adiv5_get_dap(CMD_DATA);
        uint32_t apcsw = dap->ap[dap->apsel].csw_default;
 {
        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:
 
        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:
        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
                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;
                break;
        default:
                return ERROR_COMMAND_SYNTAX_ERROR;
@@ -1786,8 +1796,8 @@ const struct command_registration dap_instance_commands[] = {
                .name = "apcsw",
                .handler = dap_apcsw_command,
                .mode = COMMAND_EXEC,
                .name = "apcsw",
                .handler = dap_apcsw_command,
                .mode = COMMAND_EXEC,
-               .help = "Set csw access bit ",
-               .usage = "[sprot]",
+               .help = "Set CSW default bits",
+               .usage = "[value [mask]]",
        },
 
        {
        },
 
        {
index bc5611650d92d1bc97d0bab08c6d9dff286fd4bb..22c316630691331d0e686f221eac26a8ef17bc1d 100644 (file)
 #define CSW_ADDRINC_PACKED  (2UL << 4)
 #define CSW_DEVICE_EN       (1UL << 6)
 #define CSW_TRIN_PROG       (1UL << 7)
 #define CSW_ADDRINC_PACKED  (2UL << 4)
 #define CSW_DEVICE_EN       (1UL << 6)
 #define CSW_TRIN_PROG       (1UL << 7)
+/* all fields in bits 12 and above are implementation-defined! */
 #define CSW_SPIDEN          (1UL << 23)
 #define CSW_SPIDEN          (1UL << 23)
-/* 30:24 - implementation-defined! */
-#define CSW_HPROT           (1UL << 25) /* ? */
-#define CSW_MASTER_DEBUG    (1UL << 29) /* ? */
+#define CSW_HPROT1          (1UL << 25) /* AHB: Privileged */
+#define CSW_MASTER_DEBUG    (1UL << 29) /* AHB: set HMASTER signals to AHB-AP ID */
 #define CSW_SPROT           (1UL << 30)
 #define CSW_DBGSWENABLE     (1UL << 31)
 
 #define CSW_SPROT           (1UL << 30)
 #define CSW_DBGSWENABLE     (1UL << 31)
 
+/* initial value of csw_default used for MEM-AP transfers */
+#define CSW_DEFAULT                    (CSW_HPROT1 | CSW_MASTER_DEBUG | CSW_DBGSWENABLE)
+
 /* Fields of the MEM-AP's IDR register */
 #define IDR_REV     (0xFUL << 28)
 #define IDR_JEP106  (0x7FFUL << 17)
 /* Fields of the MEM-AP's IDR register */
 #define IDR_REV     (0xFUL << 28)
 #define IDR_JEP106  (0x7FFUL << 17)
index 797feb5bafdf83dbe36ff5bf338fe52afafdd8bd..8c081800fcb37111a909955f261ff9c9560eca81 100644 (file)
@@ -55,6 +55,8 @@ static void dap_instance_init(struct adiv5_dap *dap)
                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);
                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);
+               /* default CSW value */
+               dap->ap[i].csw_default = CSW_DEFAULT;
        }
        INIT_LIST_HEAD(&dap->cmd_journal);
 }
        }
        INIT_LIST_HEAD(&dap->cmd_journal);
 }

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)