cortex_a: rework mmu manipulation

when disabling the mmu to access physical addresses, normally the d-cache
must be disabled as well. Disabling the d-cache also requires a full
clean&invalidate. However, since all memory writes are treated as write-
through no-allocate and memory reads do not allocate cache lines,
effectively the d-cache state does not change at all. We can therefore
save the the d-cache disabling and flushing.

This patch also simplifies the function a bit.

Change-Id: Ia17c56a28f432156429cd4596107e3652b788e63
Signed-off-by: Matthias Welwarsky <matthias@welwarsky.de>
Reviewed-on: http://openocd.zylin.com/3114
Tested-by: jenkins
Reviewed-by: Paul Fertser <fercerpav@gmail.com>
This commit is contained in:
Matthias Welwarsky 2015-11-19 22:09:49 +01:00 committed by Paul Fertser
parent 442e2506b1
commit 3683f8cef0
1 changed files with 17 additions and 17 deletions

View File

@ -132,35 +132,35 @@ static int cortex_a_mmu_modify(struct target *target, int enable)
struct cortex_a_common *cortex_a = target_to_cortex_a(target);
struct armv7a_common *armv7a = target_to_armv7a(target);
int retval = ERROR_OK;
int need_write = 0;
if (enable) {
/* if mmu enabled at target stop and mmu not enable */
if (!(cortex_a->cp15_control_reg & 0x1U)) {
LOG_ERROR("trying to enable mmu on target stopped with mmu disable");
return ERROR_FAIL;
}
if (!(cortex_a->cp15_control_reg_curr & 0x1U)) {
if ((cortex_a->cp15_control_reg_curr & 0x1U) == 0) {
cortex_a->cp15_control_reg_curr |= 0x1U;
retval = armv7a->arm.mcr(target, 15,
0, 0, /* op1, op2 */
1, 0, /* CRn, CRm */
cortex_a->cp15_control_reg_curr);
need_write = 1;
}
} else {
if ((cortex_a->cp15_control_reg_curr & 0x1U)) {
if (cortex_a->cp15_control_reg_curr & 0x4U) {
/* data cache is active */
cortex_a->cp15_control_reg_curr &= ~0x4U;
/* flush data cache armv7 function to be called */
if (armv7a->armv7a_mmu.armv7a_cache.flush_all_data_cache)
armv7a->armv7a_mmu.armv7a_cache.flush_all_data_cache(target);
}
if ((cortex_a->cp15_control_reg_curr & 0x1U) == 0x1U) {
cortex_a->cp15_control_reg_curr &= ~0x1U;
retval = armv7a->arm.mcr(target, 15,
0, 0, /* op1, op2 */
1, 0, /* CRn, CRm */
cortex_a->cp15_control_reg_curr);
need_write = 1;
}
}
if (need_write) {
LOG_DEBUG("%s, writing cp15 ctrl: %" PRIx32,
enable ? "enable mmu" : "disable mmu",
cortex_a->cp15_control_reg_curr);
retval = armv7a->arm.mcr(target, 15,
0, 0, /* op1, op2 */
1, 0, /* CRn, CRm */
cortex_a->cp15_control_reg_curr);
}
return retval;
}