]> git.sur5r.net Git - openocd/commitdiff
armv7a: add d-cache virtual address range flush function
authorMatthias Welwarsky <matthias@welwarsky.de>
Fri, 16 Oct 2015 07:57:19 +0000 (09:57 +0200)
committerPaul Fertser <fercerpav@gmail.com>
Mon, 30 Nov 2015 05:41:35 +0000 (05:41 +0000)
This patch adds a function for cleaning & invalidating a virtual
address range from the architecture caches down to the point of
coherence.

Change-Id: I4061ab023a3797fabc967f3a34498034841d52c6
Signed-off-by: Matthias Welwarsky <matthias@welwarsky.de>
Reviewed-on: http://openocd.zylin.com/3026
Reviewed-by: Paul Fertser <fercerpav@gmail.com>
Tested-by: jenkins
src/target/armv7a_cache.c
src/target/armv7a_cache.h

index 94fa09703c8164436c8663000ab3ea6cc456fd7c..98474ecb4f97640249dc2d56b5d0f21250db3401 100644 (file)
@@ -223,6 +223,41 @@ done:
        return retval;
 }
 
+int armv7a_l1_d_cache_flush_virt(struct target *target, uint32_t virt,
+                                       unsigned int size)
+{
+       struct armv7a_common *armv7a = target_to_armv7a(target);
+       struct arm_dpm *dpm = armv7a->arm.dpm;
+       struct armv7a_cache_common *armv7a_cache = &armv7a->armv7a_mmu.armv7a_cache;
+       uint32_t i, linelen = armv7a_cache->dminline;
+       int retval;
+
+       retval = armv7a_l1_d_cache_sanity_check(target);
+       if (retval != ERROR_OK)
+               return retval;
+
+       retval = dpm->prepare(dpm);
+       if (retval != ERROR_OK)
+               goto done;
+
+       for (i = 0; i < size; i += linelen) {
+               uint32_t offs = virt + i;
+
+               /* DCCIMVAC */
+               retval = dpm->instr_write_data_r0(dpm,
+                               ARMV4_5_MCR(15, 0, 0, 7, 14, 1), offs);
+               if (retval != ERROR_OK)
+                       goto done;
+       }
+       return retval;
+
+done:
+       LOG_ERROR("d-cache invalidate failed");
+       dpm->finish(dpm);
+
+       return retval;
+}
+
 int armv7a_l1_i_cache_inval_all(struct target *target)
 {
        struct armv7a_common *armv7a = target_to_armv7a(target);
index 0efdab74a78f998182faa65b8e112a34f511153b..81995ac3a67383e192444c69b3850ae1d29cdcc7 100644 (file)
@@ -21,6 +21,8 @@
 
 int armv7a_l1_d_cache_clean_virt(struct target *target, uint32_t virt,
                                        unsigned int size);
+int armv7a_l1_d_cache_flush_virt(struct target *target, uint32_t virt,
+                                       unsigned int size);
 int armv7a_l1_i_cache_inval_all(struct target *target);
 int armv7a_l1_i_cache_inval_virt(struct target *target, uint32_t virt,
                                        uint32_t size);