aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/target/armv7a_cache.c35
-rw-r--r--src/target/armv7a_cache.h2
2 files changed, 37 insertions, 0 deletions
diff --git a/src/target/armv7a_cache.c b/src/target/armv7a_cache.c
index 94fa0970..98474ecb 100644
--- a/src/target/armv7a_cache.c
+++ b/src/target/armv7a_cache.c
@@ -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);
diff --git a/src/target/armv7a_cache.h b/src/target/armv7a_cache.h
index 0efdab74..81995ac3 100644
--- a/src/target/armv7a_cache.h
+++ b/src/target/armv7a_cache.h
@@ -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);