This is an automated email from Gerrit. "Peter Collingbourne <p...@google.com>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/7436
-- gerrit commit 301cdae375c742178716f9e6fb67afc661716c94 Author: Peter Collingbourne <p...@google.com> Date: Wed Jan 11 18:31:20 2023 -0800 arm_adi_v5: Support reads wider than 32 bits Change-Id: I01bc74dc5af37af95abe66992014d3fa459309fb Signed-off-by: Peter Collingbourne <p...@google.com> diff --git a/src/target/arm_adi_v5.c b/src/target/arm_adi_v5.c index da5da3197d..4f71e40522 100644 --- a/src/target/arm_adi_v5.c +++ b/src/target/arm_adi_v5.c @@ -164,6 +164,12 @@ static uint32_t mem_ap_get_tar_increment(struct adiv5_ap *ap) return 2; case CSW_32BIT: return 4; + case CSW_64BIT: + return 8; + case CSW_128BIT: + return 16; + case CSW_256BIT: + return 32; default: return 0; } @@ -487,7 +493,7 @@ static int mem_ap_read(struct adiv5_ap *ap, uint8_t *buffer, uint32_t size, uint struct adiv5_dap *dap = ap->dap; size_t nbytes = size * count; const uint32_t csw_addrincr = addrinc ? CSW_ADDRINC_SINGLE : CSW_ADDRINC_OFF; - uint32_t csw_size; + uint32_t csw_size, drw_reads; target_addr_t address = adr; int retval = ERROR_OK; @@ -498,7 +504,13 @@ static int mem_ap_read(struct adiv5_ap *ap, uint8_t *buffer, uint32_t size, uint * Also, packed 8-bit and 16-bit transfers seem to sometimes return garbage in some bytes, * so avoid them. */ - if (size == 4) + if (size == 32) + csw_size = CSW_256BIT; + else if (size == 16) + csw_size = CSW_128BIT; + else if (size == 8) + csw_size = CSW_64BIT; + else if (size == 4) csw_size = CSW_32BIT; else if (size == 2) csw_size = CSW_16BIT; @@ -510,10 +522,15 @@ static int mem_ap_read(struct adiv5_ap *ap, uint8_t *buffer, uint32_t size, uint if (ap->unaligned_access_bad && (adr % size != 0)) return ERROR_TARGET_UNALIGNED_ACCESS; + if (size > 4) + drw_reads = size / 4; + else + drw_reads = 1; + /* Allocate buffer to hold the sequence of DRW reads that will be made. This is a significant * over-allocation if packed transfers are going to be used, but determining the real need at * this point would be messy. */ - uint32_t *read_buf = calloc(count, sizeof(uint32_t)); + uint32_t *read_buf = calloc(count, drw_reads * sizeof(uint32_t)); /* Multiplication count * sizeof(uint32_t) may overflow, calloc() is safe */ uint32_t *read_ptr = read_buf; if (!read_buf) { @@ -528,7 +545,7 @@ static int mem_ap_read(struct adiv5_ap *ap, uint8_t *buffer, uint32_t size, uint uint32_t this_size = size; /* Select packed transfer if possible */ - if (addrinc && ap->packed_transfers && nbytes >= 4 + if (addrinc && ap->packed_transfers && nbytes >= 4 && size < 4 && max_tar_block_size(ap->tar_autoincr_block, address) >= 4) { this_size = 4; retval = mem_ap_setup_csw(ap, csw_size | CSW_ADDRINC_PACKED); @@ -542,7 +559,11 @@ static int mem_ap_read(struct adiv5_ap *ap, uint8_t *buffer, uint32_t size, uint if (retval != ERROR_OK) break; - retval = dap_queue_ap_read(ap, MEM_AP_REG_DRW(dap), read_ptr++); + for (uint32_t i = 0; i != drw_reads; ++i) { + retval = dap_queue_ap_read(ap, MEM_AP_REG_DRW(dap), read_ptr++); + if (retval != ERROR_OK) + break; + } if (retval != ERROR_OK) break; @@ -585,6 +606,9 @@ static int mem_ap_read(struct adiv5_ap *ap, uint8_t *buffer, uint32_t size, uint this_size = 4; } + if (this_size > 4) + this_size = 4; + if (dap->ti_be_32_quirks) { switch (this_size) { case 4: diff --git a/src/target/arm_adi_v5.h b/src/target/arm_adi_v5.h index 3eddbc0e2d..2347b97341 100644 --- a/src/target/arm_adi_v5.h +++ b/src/target/arm_adi_v5.h @@ -161,6 +161,9 @@ #define CSW_8BIT 0 #define CSW_16BIT 1 #define CSW_32BIT 2 +#define CSW_64BIT 3 +#define CSW_128BIT 4 +#define CSW_256BIT 5 #define CSW_ADDRINC_MASK (3UL << 4) #define CSW_ADDRINC_OFF 0UL #define CSW_ADDRINC_SINGLE (1UL << 4) --