stlink: check buffer size on 16 and 32 bit memory transfer

Both HLA and ADIv5 layers limit the memory transfer within blocks
whose boundaries are aligned at 1024 or 4096 bytes.
New stlink firmware handle the ADIv5 TAR autoincrement, making
possible to send memory transfers across the boundary of 1024 or
4096 byte. OpenOCD doesn't use this feature yet.

Use the correct buffer size in the code, even if it is not used.
While there, split SWIM buffer size from JTAG/SWD case; stlink has
a dedicated command to retrieve SWIM buffer size, but currently
not implemented in OpenOCD.

Change-Id: Id46c0356ef21cead08726c044a1cd9725fd4f923
Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com>
Reviewed-on: https://review.openocd.org/c/openocd/+/6600
Tested-by: jenkins
Reviewed-by: Tarek BOCHKATI <tarek.bouchkati@gmail.com>
This commit is contained in:
Antonio Borneo 2021-07-25 17:51:49 +02:00
parent 7901cf2124
commit fd0b4dd15f
1 changed files with 35 additions and 8 deletions

View File

@ -79,7 +79,7 @@
#define STLINK_V2_1_TRACE_EP (2|ENDPOINT_IN)
#define STLINK_SG_SIZE (31)
#define STLINK_DATA_SIZE (4096)
#define STLINK_DATA_SIZE (6144)
#define STLINK_CMD_SIZE_V2 (16)
#define STLINK_CMD_SIZE_V1 (10)
@ -97,9 +97,16 @@
* ST-Link/V1, ST-Link/V2 and ST-Link/V2.1 are full-speed USB devices and
* this limits the bulk packet size and the 8bit read/writes to max 64 bytes.
* STLINK-V3 is a high speed USB 2.0 and the limit is 512 bytes from FW V3J6.
*
* For 16 and 32bit read/writes stlink handles USB packet split and the limit
* is the internal buffer size of 6144 bytes.
* TODO: override ADIv5 layer's tar_autoincr_block that limits the transfer
* to 1024 or 4096 bytes
*/
#define STLINK_MAX_RW8 (64)
#define STLINKV3_MAX_RW8 (512)
#define STLINK_MAX_RW16_32 STLINK_DATA_SIZE
#define STLINK_SWIM_DATA_SIZE STLINK_DATA_SIZE
/* "WAIT" responses will be retried (with exponential backoff) at
* most this many times before failing to caller.
@ -1807,7 +1814,7 @@ static int stlink_swim_writebytes(void *handle, uint32_t addr, uint32_t len, con
unsigned int datalen = 0;
int cmdsize = STLINK_CMD_SIZE_V2;
if (len > STLINK_DATA_SIZE)
if (len > STLINK_SWIM_DATA_SIZE)
return ERROR_FAIL;
if (h->version.stlink == 1)
@ -1840,7 +1847,7 @@ static int stlink_swim_readbytes(void *handle, uint32_t addr, uint32_t len, uint
struct stlink_usb_handle_s *h = handle;
int res;
if (len > STLINK_DATA_SIZE)
if (len > STLINK_SWIM_DATA_SIZE)
return ERROR_FAIL;
stlink_usb_init_buffer(handle, h->rx_ep, 0);
@ -2411,6 +2418,11 @@ static int stlink_usb_read_mem16(void *handle, uint32_t addr, uint16_t len,
if (!(h->version.flags & STLINK_F_HAS_MEM_16BIT))
return ERROR_COMMAND_NOTFOUND;
if (len > STLINK_MAX_RW16_32) {
LOG_DEBUG("max buffer (%d) length exceeded", STLINK_MAX_RW16_32);
return ERROR_FAIL;
}
/* data must be a multiple of 2 and half-word aligned */
if (len % 2 || addr % 2) {
LOG_DEBUG("Invalid data alignment");
@ -2448,6 +2460,11 @@ static int stlink_usb_write_mem16(void *handle, uint32_t addr, uint16_t len,
if (!(h->version.flags & STLINK_F_HAS_MEM_16BIT))
return ERROR_COMMAND_NOTFOUND;
if (len > STLINK_MAX_RW16_32) {
LOG_DEBUG("max buffer (%d) length exceeded", STLINK_MAX_RW16_32);
return ERROR_FAIL;
}
/* data must be a multiple of 2 and half-word aligned */
if (len % 2 || addr % 2) {
LOG_DEBUG("Invalid data alignment");
@ -2480,6 +2497,11 @@ static int stlink_usb_read_mem32(void *handle, uint32_t addr, uint16_t len,
assert(handle);
if (len > STLINK_MAX_RW16_32) {
LOG_DEBUG("max buffer (%d) length exceeded", STLINK_MAX_RW16_32);
return ERROR_FAIL;
}
/* data must be a multiple of 4 and word aligned */
if (len % 4 || addr % 4) {
LOG_DEBUG("Invalid data alignment");
@ -2514,6 +2536,11 @@ static int stlink_usb_write_mem32(void *handle, uint32_t addr, uint16_t len,
assert(handle);
if (len > STLINK_MAX_RW16_32) {
LOG_DEBUG("max buffer (%d) length exceeded", STLINK_MAX_RW16_32);
return ERROR_FAIL;
}
/* data must be a multiple of 4 and word aligned */
if (len % 4 || addr % 4) {
LOG_DEBUG("Invalid data alignment");
@ -3482,7 +3509,7 @@ static int stlink_open(struct hl_interface_param_s *param, enum stlink_mode mode
goto error_open;
}
*fd = h;
h->max_mem_packet = STLINK_DATA_SIZE;
h->max_mem_packet = STLINK_SWIM_DATA_SIZE;
return ERROR_OK;
}
@ -4090,7 +4117,7 @@ static int stlink_swim_op_read_mem(uint32_t addr, uint32_t size,
count *= size;
while (count) {
bytes_remaining = (count > STLINK_DATA_SIZE) ? STLINK_DATA_SIZE : count;
bytes_remaining = (count > STLINK_SWIM_DATA_SIZE) ? STLINK_SWIM_DATA_SIZE : count;
retval = stlink_swim_readbytes(stlink_dap_handle, addr, bytes_remaining, buffer);
if (retval != ERROR_OK)
return retval;
@ -4113,7 +4140,7 @@ static int stlink_swim_op_write_mem(uint32_t addr, uint32_t size,
count *= size;
while (count) {
bytes_remaining = (count > STLINK_DATA_SIZE) ? STLINK_DATA_SIZE : count;
bytes_remaining = (count > STLINK_SWIM_DATA_SIZE) ? STLINK_SWIM_DATA_SIZE : count;
retval = stlink_swim_writebytes(stlink_dap_handle, addr, bytes_remaining, buffer);
if (retval != ERROR_OK)
return retval;