This is an automated email from Gerrit.

"Daniel Goehring <dgoeh...@os.amperecomputing.com>" just uploaded a new patch 
set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/7191

-- gerrit

commit d8de3ae0a830e88e22adae8adacd59f068d42f6b
Author: Daniel Goehring <dgoeh...@os.amperecomputing.com>
Date:   Fri Sep 10 22:18:16 2021 -0400

    target/adiv5: add MEM-AP mdd and mwd support
    
    Change-Id: Icb61639711d55b5642f20e2ef14e39e6a9c98937
    Signed-off-by: Daniel Goehring <dgoeh...@os.amperecomputing.com>

diff --git a/src/target/arm_adi_v5.c b/src/target/arm_adi_v5.c
index cc5f077750..44b30d3aa0 100644
--- a/src/target/arm_adi_v5.c
+++ b/src/target/arm_adi_v5.c
@@ -336,7 +336,7 @@ static int mem_ap_write(struct adiv5_ap *ap, const uint8_t 
*buffer, uint32_t siz
 {
        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_addrincr = addrinc ? CSW_ADDRINC_SINGLE : CSW_ADDRINC_OFF;
        uint32_t csw_size;
        target_addr_t addr_xor;
        int retval = ERROR_OK;
@@ -354,7 +354,11 @@ static int mem_ap_write(struct adiv5_ap *ap, const uint8_t 
*buffer, uint32_t siz
         * setting the TAP, and we set the TAP after every transfer rather then 
relying on
         * address increment. */
 
-       if (size == 4) {
+       if (size == 8) {
+               csw_size = CSW_64BIT;
+               addr_xor = 0;
+               csw_addrincr = CSW_ADDRINC_OFF;
+       } else if (size == 4) {
                csw_size = CSW_32BIT;
                addr_xor = 0;
        } else if (size == 2) {
@@ -374,7 +378,7 @@ static int mem_ap_write(struct adiv5_ap *ap, const uint8_t 
*buffer, uint32_t siz
                uint32_t this_size = size;
 
                /* Select packed transfer if possible */
-               if (addrinc && ap->packed_transfers && nbytes >= 4
+               if ((size <= 4) && addrinc && ap->packed_transfers && nbytes >= 
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);
@@ -392,6 +396,7 @@ 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 outlow = 0;
                uint32_t drw_byte_idx = address;
                if (dap->ti_be_32_quirks) {
                        switch (this_size) {
@@ -431,6 +436,12 @@ static int mem_ap_write(struct adiv5_ap *ap, const uint8_t 
*buffer, uint32_t siz
                        }
                } else {
                        switch (this_size) {
+                       case 8:
+                               outlow |= (uint32_t)*buffer++ << 8 * 
(drw_byte_idx++ & 3);
+                               outlow |= (uint32_t)*buffer++ << 8 * 
(drw_byte_idx++ & 3);
+                               outlow |= (uint32_t)*buffer++ << 8 * 
(drw_byte_idx++ & 3);
+                               outlow |= (uint32_t)*buffer++ << 8 * 
(drw_byte_idx++ & 3);
+                               /* fallthrough */
                        case 4:
                                outvalue |= (uint32_t)*buffer++ << 8 * 
(drw_byte_idx++ & 3);
                                outvalue |= (uint32_t)*buffer++ << 8 * 
(drw_byte_idx++ & 3);
@@ -445,6 +456,11 @@ static int mem_ap_write(struct adiv5_ap *ap, const uint8_t 
*buffer, uint32_t siz
 
                nbytes -= this_size;
 
+               if (this_size > 4) {
+                       retval = dap_queue_ap_write(ap, MEM_AP_REG_DRW(dap), 
outlow);
+                       if (retval != ERROR_OK)
+                               break;
+               }
                retval = dap_queue_ap_write(ap, MEM_AP_REG_DRW(dap), outvalue);
                if (retval != ERROR_OK)
                        break;
@@ -486,7 +502,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_addrincr = addrinc ? CSW_ADDRINC_SINGLE : CSW_ADDRINC_OFF;
        uint32_t csw_size;
        target_addr_t address = adr;
        int retval = ERROR_OK;
@@ -498,7 +514,10 @@ 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 == 8) {
+               csw_size = CSW_64BIT;
+               csw_addrincr = CSW_ADDRINC_OFF;
+       } else if (size == 4)
                csw_size = CSW_32BIT;
        else if (size == 2)
                csw_size = CSW_16BIT;
@@ -528,7 +547,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 ((size <= 4) && addrinc && ap->packed_transfers && nbytes >= 
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);
@@ -545,6 +564,11 @@ static int mem_ap_read(struct adiv5_ap *ap, uint8_t 
*buffer, uint32_t size, uint
                retval = dap_queue_ap_read(ap, MEM_AP_REG_DRW(dap), read_ptr++);
                if (retval != ERROR_OK)
                        break;
+               if (size > 4) {
+                       retval = dap_queue_ap_read(ap, MEM_AP_REG_DRW(dap), 
read_ptr++);
+                       if (retval != ERROR_OK)
+                               break;
+               }
 
                nbytes -= this_size;
                if (addrinc)
@@ -599,6 +623,13 @@ static int mem_ap_read(struct adiv5_ap *ap, uint8_t 
*buffer, uint32_t size, uint
                        }
                } else {
                        switch (this_size) {
+                       case 8:
+                               *buffer++ = *read_ptr >> 8 * (address++ & 3);
+                               *buffer++ = *read_ptr >> 8 * (address++ & 3);
+                               *buffer++ = *read_ptr >> 8 * (address++ & 3);
+                               *buffer++ = *read_ptr >> 8 * (address++ & 3);
+                               read_ptr++;
+                               /* fallthrough */
                        case 4:
                                *buffer++ = *read_ptr >> 8 * (address++ & 3);
                                *buffer++ = *read_ptr >> 8 * (address++ & 3);
diff --git a/src/target/arm_adi_v5.h b/src/target/arm_adi_v5.h
index 3eddbc0e2d..e46a7006a5 100644
--- a/src/target/arm_adi_v5.h
+++ b/src/target/arm_adi_v5.h
@@ -161,6 +161,7 @@
 #define CSW_8BIT               0
 #define CSW_16BIT              1
 #define CSW_32BIT              2
+#define CSW_64BIT              3
 #define CSW_ADDRINC_MASK    (3UL << 4)
 #define CSW_ADDRINC_OFF     0UL
 #define CSW_ADDRINC_SINGLE  (1UL << 4)

-- 

Reply via email to