if (retval != ERROR_OK)
return retval;
+ /* Disable cacheline fills and force cache write-through in debug state */
+ retval = mem_ap_sel_write_atomic_u32(swjdp, armv7a->debug_ap,
+ armv7a->debug_base + CPUDBG_DSCCR, 0);
+ if (retval != ERROR_OK)
+ return retval;
+
+ /* Disable TLB lookup and refill/eviction in debug state */
+ retval = mem_ap_sel_write_atomic_u32(swjdp, armv7a->debug_ap,
+ armv7a->debug_base + CPUDBG_DSMCR, 0);
+ if (retval != ERROR_OK)
+ return retval;
+
/* Enabling of instruction execution in debug mode is done in debug_entry code */
/* Resync breakpoint registers */
LOG_DEBUG("cp15_control_reg: %8.8" PRIx32, cortex_a->cp15_control_reg);
cortex_a->cp15_control_reg_curr = cortex_a->cp15_control_reg;
- if (armv7a->armv7a_mmu.armv7a_cache.ctype == -1)
+ if (armv7a->armv7a_mmu.armv7a_cache.info == -1)
armv7a_identify_cache(target);
if (armv7a->is_armv7r) {
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 */
}
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,
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;
if (retval != ERROR_OK)
return retval;
}
+
+ /* memory writes bypass the caches, must flush before writing */
+ armv7a_cache_auto_flush_on_write(target, address, size * count);
+
retval = cortex_a_write_apb_ab_memory(target, address, size, count, buffer);
return retval;