diff options
Diffstat (limited to 'src/target/cortex_a.c')
-rw-r--r-- | src/target/cortex_a.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/src/target/cortex_a.c b/src/target/cortex_a.c index 39e59ae7..5268cf21 100644 --- a/src/target/cortex_a.c +++ b/src/target/cortex_a.c @@ -1509,11 +1509,25 @@ static int cortex_a_set_breakpoint(struct target *target, breakpoint->orig_instr); if (retval != ERROR_OK) return retval; + + /* make sure data cache is cleaned & invalidated down to PoC */ + if (!armv7a->armv7a_mmu.armv7a_cache.auto_cache_enabled) { + armv7a_cache_flush_virt(target, breakpoint->address, + breakpoint->length); + } + retval = target_write_memory(target, breakpoint->address & 0xFFFFFFFE, breakpoint->length, 1, code); if (retval != ERROR_OK) return retval; + + /* update i-cache at breakpoint location */ + armv7a_l1_d_cache_inval_virt(target, breakpoint->address, + breakpoint->length); + armv7a_l1_i_cache_inval_virt(target, breakpoint->address, + breakpoint->length); + breakpoint->set = 0x11; /* Any nice value but 0 */ } @@ -1733,6 +1747,13 @@ static int cortex_a_unset_breakpoint(struct target *target, struct breakpoint *b return ERROR_OK; } } else { + + /* make sure data cache is cleaned & invalidated down to PoC */ + if (!armv7a->armv7a_mmu.armv7a_cache.auto_cache_enabled) { + armv7a_cache_flush_virt(target, breakpoint->address, + breakpoint->length); + } + /* restore original instruction (kept in target endianness) */ if (breakpoint->length == 4) { retval = target_write_memory(target, @@ -1747,6 +1768,12 @@ static int cortex_a_unset_breakpoint(struct target *target, struct breakpoint *b if (retval != ERROR_OK) return retval; } + + /* update i-cache at breakpoint location */ + armv7a_l1_d_cache_inval_virt(target, breakpoint->address, + breakpoint->length); + armv7a_l1_i_cache_inval_virt(target, breakpoint->address, + breakpoint->length); } breakpoint->set = 0; |