This is an automated email from Gerrit.

Tomas Vanek ([email protected]) just uploaded a new patch set to Gerrit, which you 
can find at http://openocd.zylin.com/4162

-- gerrit

commit 96e5444b2321358da0cfb5ed06a944563e86a2c2
Author: Tomas Vanek <[email protected]>
Date:   Thu Jun 15 08:59:01 2017 +0200

    arm_adi_v5: fix wrong addressing after change of CSW_ADDRINC
    
    Problem: If the same memory location is accessed alternatively
    by MEM-AP banked data registers without autoincrement and by standard
    autoincremented read/write, TAR register is not updated correctly.
    
    How to replicate: On a Cortex-M issue
        mdw 0xe000edf0
    multiple times. When poll is on (poll reads the same memory location)
    only the first read is correct.
    0xe000edf0: 01000000
    0xe000edf0: 00000000
    0xe000edf0: 20002640
    0xe000edf0: 01000000
    0xe000edf0: 00000000
    0xe000edf0: 00000000
    
    No problems with poll off.
    0xe000edf0: 01000000
    0xe000edf0: 01000000
    0xe000edf0: 01000000
    
    mem_ap_setup_tar() writes to MEM_AP_REG_TAR if requested TAR value
    changed or CSW_ADDRINC_... is currently active.
    However if an autoincremented access has been issued and autoinc
    switched off in CSW afterwards, TAR does not get updated.
    
    The change introduces mem_ap_increment_tar() which is called
    after queuing of any access to MEM_AP_REG_DRW. It invalidates
    cached tar_value if an autoincrement mode is active.
    Note that access to a banked data registers MEM_AP_REG_BD0..3
    does not increment TAR regardless to the current autoincrement mode.
    
    Change-Id: I815c2283d2989cffd6ea9a4100ce2f29dc3fb7b4
    Signed-off-by: Tomas Vanek <[email protected]>

diff --git a/src/target/arm_adi_v5.c b/src/target/arm_adi_v5.c
index eafc2dd..5b9536b 100644
--- a/src/target/arm_adi_v5.c
+++ b/src/target/arm_adi_v5.c
@@ -111,8 +111,7 @@ static int mem_ap_setup_csw(struct adiv5_ap *ap, uint32_t 
csw)
 
 static int mem_ap_setup_tar(struct adiv5_ap *ap, uint32_t tar)
 {
-       if (tar != ap->tar_value ||
-                       (ap->csw_value & CSW_ADDRINC_MASK)) {
+       if (tar != ap->tar_value) {
                /* LOG_DEBUG("DAP: Set TAR %x",tar); */
                int retval = dap_queue_ap_write(ap, MEM_AP_REG_TAR, tar);
                if (retval != ERROR_OK)
@@ -122,6 +121,16 @@ static int mem_ap_setup_tar(struct adiv5_ap *ap, uint32_t 
tar)
        return ERROR_OK;
 }
 
+/* mem_ap_increment_tar is called after an access to MEM_AP_REG_DRW
+ * Currently there is no real increment implementation,
+ * just cached tar_value is invalidated
+ */
+static void mem_ap_increment_tar(struct adiv5_ap *ap)
+{
+       if (ap->csw_value & CSW_ADDRINC_MASK)
+               ap->tar_value = -1;
+}
+
 /**
  * Queue transactions setting up transfer parameters for the
  * currently selected MEM-AP.
@@ -142,10 +151,13 @@ static int mem_ap_setup_tar(struct adiv5_ap *ap, uint32_t 
tar)
 static int mem_ap_setup_transfer(struct adiv5_ap *ap, uint32_t csw, uint32_t 
tar)
 {
        int retval;
-       retval = mem_ap_setup_csw(ap, csw);
+       /* mem_ap_setup_tar() should be called with the old csw state
+        * to prevent useless TAR update when autoinc is just switched on
+        */
+       retval = mem_ap_setup_tar(ap, tar);
        if (retval != ERROR_OK)
                return retval;
-       retval = mem_ap_setup_tar(ap, tar);
+       retval = mem_ap_setup_csw(ap, csw);
        if (retval != ERROR_OK)
                return retval;
        return ERROR_OK;
@@ -364,7 +376,8 @@ static int mem_ap_write(struct adiv5_ap *ap, const uint8_t 
*buffer, uint32_t siz
                        retval = mem_ap_setup_tar(ap, address ^ addr_xor);
                        if (retval != ERROR_OK)
                                break;
-               }
+               } else
+                       mem_ap_increment_tar(ap);
        }
 
        /* REVISIT: Might want to have a queued version of this function that 
does not run. */
@@ -469,7 +482,8 @@ static int mem_ap_read(struct adiv5_ap *ap, uint8_t 
*buffer, uint32_t size, uint
                        retval = mem_ap_setup_tar(ap, address);
                        if (retval != ERROR_OK)
                                break;
-               }
+               } else
+                       mem_ap_increment_tar(ap);
        }
 
        if (retval == ERROR_OK)

-- 

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
OpenOCD-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openocd-devel

Reply via email to