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)

-- 

Reply via email to