From 23fb2986516f14e0889da6af3a918a3ce2c0117d Mon Sep 17 00:00:00 2001 From: Andreas Fritiofson Date: Sun, 22 Sep 2013 23:14:17 +0200 Subject: [PATCH] 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 Reviewed-on: http://openocd.zylin.com/1649 Tested-by: jenkins Reviewed-by: Spencer Oliver --- src/target/arm_adi_v5.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/target/arm_adi_v5.c b/src/target/arm_adi_v5.c index 309296ac..67fb23b2 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; -- 2.39.5