From 0e5b3ab00ea7515ec75976c9ea2bcf2a2af737f9 Mon Sep 17 00:00:00 2001 From: Nick Downing Date: Fri, 14 Jul 2017 20:45:54 +1000 Subject: [PATCH] Make Cortex M driver write DCCIMVAC (Data cache clean and invalidate by address to the PoC=Point of Coherency) prior to reading or writing each 32 bytes of RAM --- src/target/cortexm.c | 32 ++++++++++++++++++++++++++++++++ src/target/cortexm.h | 3 +++ 2 files changed, 35 insertions(+) diff --git a/src/target/cortexm.c b/src/target/cortexm.c index 4e941060..380f2fcc 100644 --- a/src/target/cortexm.c +++ b/src/target/cortexm.c @@ -181,11 +181,43 @@ ADIv5_AP_t *cortexm_ap(target *t) static void cortexm_mem_read(target *t, void *dest, target_addr src, size_t len) { + /* flush data cache for RAM regions that intersect requested region */ + target_addr src_end = src + len; /* following code is NOP if wraparound */ + /* requested region is [src, src_end) */ + for (struct target_ram *r = t->ram; r; r = r->next) { + target_addr ram = r->start; + target_addr ram_end = r->start + r->length; + /* RAM region is [ram, ram_end) */ + if (src > ram) + ram = src; + if (src_end < ram_end) + ram_end = src_end; + /* intersection is [ram, ram_end) */ + for (ram &= ~0x1f; ram < ram_end; ram += 0x20) + adiv5_mem_write(cortexm_ap(t), CORTEXM_DCCIMVAC, &ram, 4); + } + adiv5_mem_read(cortexm_ap(t), dest, src, len); } static void cortexm_mem_write(target *t, target_addr dest, const void *src, size_t len) { + /* flush data cache for RAM regions that intersect requested region */ + target_addr dest_end = dest + len; /* following code is NOP if wraparound */ + /* requested region is [dest, dest_end) */ + for (struct target_ram *r = t->ram; r; r = r->next) { + target_addr ram = r->start; + target_addr ram_end = r->start + r->length; + /* RAM region is [ram, ram_end) */ + if (dest > ram) + ram = dest; + if (dest_end < ram_end) + ram_end = dest_end; + /* intersection is [ram, ram_end) */ + for (ram &= ~0x1f; ram < ram_end; ram += 0x20) + adiv5_mem_write(cortexm_ap(t), CORTEXM_DCCIMVAC, &ram, 4); + } + adiv5_mem_write(cortexm_ap(t), dest, src, len); } diff --git a/src/target/cortexm.h b/src/target/cortexm.h index bf1d821d..ca5e10b3 100644 --- a/src/target/cortexm.h +++ b/src/target/cortexm.h @@ -37,6 +37,9 @@ #define CORTEXM_DCRDR (CORTEXM_SCS_BASE + 0xDF8) #define CORTEXM_DEMCR (CORTEXM_SCS_BASE + 0xDFC) +/* Data cache clean and invalidate by address to the PoC=Point of Coherency */ +#define CORTEXM_DCCIMVAC (CORTEXM_SCS_BASE + 0xF70) + #define CORTEXM_FPB_BASE (CORTEXM_PPB_BASE + 0x2000) /* ARM Literature uses FP_*, we use CORTEXM_FPB_* consistently */