From: Tomas Vanek Date: Wed, 10 Jan 2018 14:17:14 +0000 (+0100) Subject: arm_adi_v5: fix regression from 4553abf9064fe3c0e4ea2ed29a1d2217df74ff5f X-Git-Tag: v0.11.0-rc1~1296 X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=commitdiff_plain;h=779e95cc326e77f628d5feb7d72a064ffedfd820;hp=6f5e9941df0f92eac5fa955cc96221da907451b1 arm_adi_v5: fix regression from 4553abf9064fe3c0e4ea2ed29a1d2217df74ff5f Functions mem_ap_read() and mem_ap_write() incremented address even if addrinc=false. I overlooked this fact and moved mem_ap_setup_tar() set wrong addresses in no-incr mode. Fixed by preventing address increment in no-incr mode. Change-Id: I512e12a6a64e30cf6bc5bf77e3d57d35cc33e058 Signed-off-by: Tomas Vanek Suggested-by: Matthias Welwarsky Reviewed-on: http://openocd.zylin.com/4326 Tested-by: jenkins Reviewed-by: Christopher Head Reviewed-by: Andreas Fritiofson --- diff --git a/src/target/arm_adi_v5.c b/src/target/arm_adi_v5.c index ae6c2c629f..1ca8e4f004 100644 --- a/src/target/arm_adi_v5.c +++ b/src/target/arm_adi_v5.c @@ -378,33 +378,34 @@ static int mem_ap_write(struct adiv5_ap *ap, const uint8_t *buffer, uint32_t siz /* How many source bytes each transfer will consume, and their location in the DRW, * depends on the type of transfer and alignment. See ARM document IHI0031C. */ uint32_t outvalue = 0; + uint32_t drw_byte_idx = address; if (dap->ti_be_32_quirks) { switch (this_size) { case 4: - outvalue |= (uint32_t)*buffer++ << 8 * (3 ^ (address++ & 3) ^ addr_xor); - outvalue |= (uint32_t)*buffer++ << 8 * (3 ^ (address++ & 3) ^ addr_xor); - outvalue |= (uint32_t)*buffer++ << 8 * (3 ^ (address++ & 3) ^ addr_xor); - outvalue |= (uint32_t)*buffer++ << 8 * (3 ^ (address++ & 3) ^ addr_xor); + outvalue |= (uint32_t)*buffer++ << 8 * (3 ^ (drw_byte_idx++ & 3) ^ addr_xor); + outvalue |= (uint32_t)*buffer++ << 8 * (3 ^ (drw_byte_idx++ & 3) ^ addr_xor); + outvalue |= (uint32_t)*buffer++ << 8 * (3 ^ (drw_byte_idx++ & 3) ^ addr_xor); + outvalue |= (uint32_t)*buffer++ << 8 * (3 ^ (drw_byte_idx & 3) ^ addr_xor); break; case 2: - outvalue |= (uint32_t)*buffer++ << 8 * (1 ^ (address++ & 3) ^ addr_xor); - outvalue |= (uint32_t)*buffer++ << 8 * (1 ^ (address++ & 3) ^ addr_xor); + outvalue |= (uint32_t)*buffer++ << 8 * (1 ^ (drw_byte_idx++ & 3) ^ addr_xor); + outvalue |= (uint32_t)*buffer++ << 8 * (1 ^ (drw_byte_idx & 3) ^ addr_xor); break; case 1: - outvalue |= (uint32_t)*buffer++ << 8 * (0 ^ (address++ & 3) ^ addr_xor); + outvalue |= (uint32_t)*buffer++ << 8 * (0 ^ (drw_byte_idx & 3) ^ addr_xor); break; } } else { switch (this_size) { case 4: - outvalue |= (uint32_t)*buffer++ << 8 * (address++ & 3); - outvalue |= (uint32_t)*buffer++ << 8 * (address++ & 3); + outvalue |= (uint32_t)*buffer++ << 8 * (drw_byte_idx++ & 3); + outvalue |= (uint32_t)*buffer++ << 8 * (drw_byte_idx++ & 3); /* fallthrough */ case 2: - outvalue |= (uint32_t)*buffer++ << 8 * (address++ & 3); + outvalue |= (uint32_t)*buffer++ << 8 * (drw_byte_idx++ & 3); /* fallthrough */ case 1: - outvalue |= (uint32_t)*buffer++ << 8 * (address++ & 3); + outvalue |= (uint32_t)*buffer++ << 8 * (drw_byte_idx & 3); } } @@ -415,6 +416,8 @@ static int mem_ap_write(struct adiv5_ap *ap, const uint8_t *buffer, uint32_t siz break; mem_ap_update_tar_cache(ap); + if (addrinc) + address += this_size; } /* REVISIT: Might want to have a queued version of this function that does not run. */ @@ -509,7 +512,8 @@ static int mem_ap_read(struct adiv5_ap *ap, uint8_t *buffer, uint32_t size, uint break; nbytes -= this_size; - address += this_size; + if (addrinc) + address += this_size; mem_ap_update_tar_cache(ap); }