cortex_a: fix lockup when writing to high address
authorSeth LaForge <sethml@google.com>
Tue, 6 May 2014 23:02:23 +0000 (16:02 -0700)
committerAndreas Fritiofson <andreas.fritiofson@gmail.com>
Sun, 22 Jun 2014 08:23:53 +0000 (08:23 +0000)
On a processor with caches, when you write data to memory OpenOCD invalidates
the cache lines affected. If you write to an address within 64 bytes of
UINT32_MAX, then the for loop control variable wrapped around resulting in an
infinite loop. Change control variable to be an offset from the address
involved. We should never be asked to write 2^32 bytes, so wraparound should
not be a problem.

Change-Id: Ibfe654113eff71684862ff651e7a1cd05ccc6760
Signed-off-by: Seth LaForge <sethml@google.com>
Reviewed-on: http://openocd.zylin.com/2126
Tested-by: jenkins
Reviewed-by: Spencer Oliver <spen@spen-soft.co.uk>
src/target/cortex_a.c

index 50eb9d48aa8d2801202bd48ed3ba36d794540d2d..4418e9a300702379ea9835be8550565d5a8d7e03 100644 (file)
@@ -2232,12 +2232,12 @@ static int cortex_a8_write_phys_memory(struct target *target,
                         * with MVA to PoU
                         *      MCR p15, 0, r0, c7, c5, 1
                         */
-                       for (uint32_t cacheline = address;
-                               cacheline < address + size * count;
+                       for (uint32_t cacheline = 0;
+                               cacheline < size * count;
                                cacheline += 64) {
                                retval = dpm->instr_write_data_r0(dpm,
                                                ARMV4_5_MCR(15, 0, 0, 7, 5, 1),
-                                               cacheline);
+                                               address + cacheline);
                                if (retval != ERROR_OK)
                                        return retval;
                        }
@@ -2249,12 +2249,12 @@ static int cortex_a8_write_phys_memory(struct target *target,
                         * with MVA to PoC
                         *      MCR p15, 0, r0, c7, c6, 1
                         */
-                       for (uint32_t cacheline = address;
-                               cacheline < address + size * count;
+                       for (uint32_t cacheline = 0;
+                               cacheline < size * count;
                                cacheline += 64) {
                                retval = dpm->instr_write_data_r0(dpm,
                                                ARMV4_5_MCR(15, 0, 0, 7, 6, 1),
-                                               cacheline);
+                                               address + cacheline);
                                if (retval != ERROR_OK)
                                        return retval;
                        }