From 3683f8cef09f389ed840f2dbef5bd1749b60a16f Mon Sep 17 00:00:00 2001 From: Matthias Welwarsky Date: Thu, 19 Nov 2015 22:09:49 +0100 Subject: [PATCH] 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 Reviewed-on: http://openocd.zylin.com/3114 Tested-by: jenkins Reviewed-by: Paul Fertser --- src/target/cortex_a.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/target/cortex_a.c b/src/target/cortex_a.c index 61a5df389..3f00511c2 100644 --- a/src/target/cortex_a.c +++ b/src/target/cortex_a.c @@ -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; }