aboutsummaryrefslogtreecommitdiff
path: root/src/target/arm_adi_v5.c
diff options
context:
space:
mode:
authorAndreas Fritiofson <andreas.fritiofson@gmail.com>2013-09-22 23:14:17 +0200
committerSpencer Oliver <spen@spen-soft.co.uk>2013-10-02 21:53:59 +0000
commit23fb2986516f14e0889da6af3a918a3ce2c0117d (patch)
treea4198f412fe0fc54506043196f7969b72e88303d /src/target/arm_adi_v5.c
parent2ab5d672ea5ce48694c8c74d0efa234fb2a50fe8 (diff)
downloadriscv-openocd-23fb2986516f14e0889da6af3a918a3ce2c0117d.zip
riscv-openocd-23fb2986516f14e0889da6af3a918a3ce2c0117d.tar.gz
riscv-openocd-23fb2986516f14e0889da6af3a918a3ce2c0117d.tar.bz2
arm_adi_v5: Fix packed transfers crossing TAR auto-increment block
The word count returned from max_tar_block_size() was compared with the count of half-word/bytes in the u16 and u8 packed access functions, causing an infinite loop if the access actually crossed the boundary. Change max_tar_block_size() to return a byte count, and scale at the call site. Change-Id: I2fe9b5941eb485f3d8219cfdd29fb71e02006de4 Signed-off-by: Andreas Fritiofson <andreas.fritiofson@gmail.com> Reviewed-on: http://openocd.zylin.com/1649 Tested-by: jenkins Reviewed-by: Spencer Oliver <spen@spen-soft.co.uk>
Diffstat (limited to 'src/target/arm_adi_v5.c')
-rw-r--r--src/target/arm_adi_v5.c11
1 files changed, 5 insertions, 6 deletions
diff --git a/src/target/arm_adi_v5.c b/src/target/arm_adi_v5.c
index 309296a..67fb23b 100644
--- a/src/target/arm_adi_v5.c
+++ b/src/target/arm_adi_v5.c
@@ -82,7 +82,7 @@
*/
static uint32_t max_tar_block_size(uint32_t tar_autoincr_block, uint32_t address)
{
- return (tar_autoincr_block - ((tar_autoincr_block - 1) & address)) >> 2;
+ return tar_autoincr_block - ((tar_autoincr_block - 1) & address);
}
/***************************************************************************
@@ -271,7 +271,7 @@ int mem_ap_write_buf_u32(struct adiv5_dap *dap, const uint8_t *buffer, int count
while (wcount > 0) {
/* Adjust to write blocks within boundaries aligned to the TAR auto-increment size */
- blocksize = max_tar_block_size(dap->tar_autoincr_block, address);
+ blocksize = max_tar_block_size(dap->tar_autoincr_block, address) / 4;
if (wcount < blocksize)
blocksize = wcount;
@@ -324,7 +324,7 @@ static int mem_ap_write_buf_packed_u16(struct adiv5_dap *dap,
int nbytes;
/* Adjust to write blocks within boundaries aligned to the TAR auto-increment size */
- blocksize = max_tar_block_size(dap->tar_autoincr_block, address);
+ blocksize = max_tar_block_size(dap->tar_autoincr_block, address) / 2;
if (wcount < blocksize)
blocksize = wcount;
@@ -534,8 +534,7 @@ int mem_ap_read_buf_u32(struct adiv5_dap *dap, uint8_t *buffer,
* TAR autoincrement size (at least 2^10). Autoincrement
* mode avoids an extra per-word roundtrip to update TAR.
*/
- blocksize = max_tar_block_size(dap->tar_autoincr_block,
- address);
+ blocksize = max_tar_block_size(dap->tar_autoincr_block, address) / 4;
if (wcount < blocksize)
blocksize = wcount;
@@ -601,7 +600,7 @@ static int mem_ap_read_buf_packed_u16(struct adiv5_dap *dap,
int nbytes;
/* Adjust to read blocks within boundaries aligned to the TAR autoincremnent size*/
- blocksize = max_tar_block_size(dap->tar_autoincr_block, address);
+ blocksize = max_tar_block_size(dap->tar_autoincr_block, address) / 2;
if (wcount < blocksize)
blocksize = wcount;