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>
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}.
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}]
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); */
{
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;
.name = "apcsw",
.handler = dap_apcsw_command,
.mode = COMMAND_EXEC,
- .help = "Set csw access bit ",
- .usage = "[sprot]",
+ .help = "Set CSW default bits",
+ .usage = "[value [mask]]",
},
{
#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)
-/* 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)
+/* 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)
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);
}