diff options
author | Alexander Osipenko <sipych@gmail.com> | 2012-07-31 03:50:09 +0400 |
---|---|---|
committer | Freddie Chopin <freddie.chopin@gmail.com> | 2012-08-01 21:16:37 +0000 |
commit | 9c9c06b8aee907c547e80b472be900d152dae490 (patch) | |
tree | e23fb1fe6a7995a6dbc690144860a0c4ee667ac6 | |
parent | ee8df96b2b064fd666e9a3aa8b8f03eb0f2bd75f (diff) |
arm946e: don't use global variables for context
Global variables 'dc' 'ic' had been used in the code
to keep target's state of D-cache and I-cache
on debug entry.
This may lead to incorrect operation in configurations
with multiple cores and unequal cache states.
Fix: move cache state to the appropriate bits of the
'cp15_control_reg' field (already present but unused).
Vaule of cp15 control register stored here on
arm946e_post_debug_entry(), and analyzed later
in arm946e_write_memory().
Change-Id: I71ef82be00c21d6fffb3726cec4974d1ece70dfe
Signed-off-by: Alexander Osipenko <sipych@gmail.com>
Reviewed-on: http://openocd.zylin.com/692
Tested-by: jenkins
Reviewed-by: Freddie Chopin <freddie.chopin@gmail.com>
-rw-r--r-- | src/target/arm946e.c | 51 |
1 files changed, 25 insertions, 26 deletions
diff --git a/src/target/arm946e.c b/src/target/arm946e.c index 4739237c..bd3eceb5 100644 --- a/src/target/arm946e.c +++ b/src/target/arm946e.c @@ -40,8 +40,9 @@ #define NB_CACHE_WAYS 4 -static uint32_t dc; -static uint32_t ic; +#define CP15_CTL 0x02 +#define CP15_CTL_DCACHE (1<<2) +#define CP15_CTL_ICACHE (1<<12) /** * flag to give info about cache manipulation during debug : @@ -294,32 +295,34 @@ int arm946e_post_debug_entry(struct target *target) { uint32_t ctr_reg = 0x0; uint32_t retval = ERROR_OK; + struct arm946e_common *arm946e = target_to_arm946(target); /* See if CACHES are enabled, and save that info - * in the global vars, so that arm946e_pre_restore_context() can use them */ - arm946e_read_cp15(target, 0x02, (uint32_t *) &ctr_reg); - dc = (ctr_reg >> 2) & 0x01; - ic = (ctr_reg >> 12) & 0x01; + * in the context bits, so that arm946e_pre_restore_context() can use them */ + arm946e_read_cp15(target, CP15_CTL, (uint32_t *) &ctr_reg); + + /* Save control reg in the context */ + arm946e->cp15_control_reg = ctr_reg; if (arm946e_preserve_cache) { - if (dc == 1) { + if (ctr_reg & CP15_CTL_DCACHE) { /* Clean and flush D$ */ arm946e_invalidate_whole_dcache(target); /* Disable D$ */ - ctr_reg &= ~(1 << 2); + ctr_reg &= ~CP15_CTL_DCACHE; } - if (ic == 1) { + if (ctr_reg & CP15_CTL_ICACHE) { /* Flush I$ */ arm946e_invalidate_whole_icache(target); /* Disable I$ */ - ctr_reg &= ~(1 << 12); + ctr_reg &= ~CP15_CTL_ICACHE; } /* Write the new configuration */ - retval = arm946e_write_cp15(target, 0x02, ctr_reg); + retval = arm946e_write_cp15(target, CP15_CTL, ctr_reg); if (retval != ERROR_OK) { LOG_DEBUG("ERROR disabling cache"); return retval; @@ -335,25 +338,20 @@ void arm946e_pre_restore_context(struct target *target) uint32_t retval; if (arm946e_preserve_cache) { + struct arm946e_common *arm946e = target_to_arm946(target); /* Get the contents of the CTR reg */ - arm946e_read_cp15(target, 0x02, (uint32_t *) &ctr_reg); + arm946e_read_cp15(target, CP15_CTL, (uint32_t *) &ctr_reg); /** - * Read-modify-write CP15 test state register - * to reenable I/D-cache linefills + * Read-modify-write CP15 control + * to reenable I/D-cache operation + * NOTE: It is not possible to disable cache by CP15. + * if arm946e_preserve_cache debugging flag enabled. */ - if (dc == 1) { - /* Enable D$ */ - ctr_reg |= 1 << 2; - } - - if (ic == 1) { - /* Enable I$ */ - ctr_reg |= 1 << 12; - } + ctr_reg |= arm946e->cp15_control_reg & (CP15_CTL_DCACHE|CP15_CTL_ICACHE); /* Write the new configuration */ - retval = arm946e_write_cp15(target, 0x02, ctr_reg); + retval = arm946e_write_cp15(target, CP15_CTL, ctr_reg); if (retval != ERROR_OK) LOG_DEBUG("ERROR enabling cache"); } /* if preserve_cache */ @@ -488,8 +486,9 @@ int arm946e_write_memory(struct target *target, uint32_t address, LOG_DEBUG("-"); + struct arm946e_common *arm946e = target_to_arm946(target); /* Invalidate D$ if it is ON */ - if (!arm946e_preserve_cache && dc == 1) + if (!arm946e_preserve_cache && (arm946e->cp15_control_reg & CP15_CTL_DCACHE)) arm946e_invalidate_dcache(target, address, size, count); /** @@ -521,7 +520,7 @@ int arm946e_write_memory(struct target *target, uint32_t address, * the cache write policy is write-through. * If the data is not in the cache, the controller writes to main memory only. */ - if (!arm946e_preserve_cache && ic == 1) + if (!arm946e_preserve_cache && (arm946e->cp15_control_reg & CP15_CTL_ICACHE)) arm946e_invalidate_icache(target, address, size, count); return ERROR_OK; |