aboutsummaryrefslogtreecommitdiff
path: root/src/target/armv7a.c
diff options
context:
space:
mode:
authorMatthias Welwarsky <matthias@welwarsky.de>2015-10-07 22:38:31 +0200
committerFreddie Chopin <freddie.chopin@gmail.com>2015-11-05 22:27:36 +0000
commit411ca773f01eac35c64d48dc396138c7a314fba9 (patch)
tree5191da76191217dbc58edff068783bb8c0ac8e05 /src/target/armv7a.c
parentfad64c618025ea96be585b0900bd70c2e5a8713a (diff)
downloadriscv-openocd-411ca773f01eac35c64d48dc396138c7a314fba9.zip
riscv-openocd-411ca773f01eac35c64d48dc396138c7a314fba9.tar.gz
riscv-openocd-411ca773f01eac35c64d48dc396138c7a314fba9.tar.bz2
armv7a: re-read ttb information if ttbcr changes
If ttbcr is changed after the debugger has examined a target for the first time, address translations may fail. This problem does not show up with Linux because it doesn't use ttbr1, but it shows with other OS that use this feature. If the debugger connects to the target while it's in u-boot, all address translations will fail after the OS has booted and the target can not be debugged. This patch reads the ttbcr in armv7a_mmu_translate_va() and compares it a cached value. If a difference is detected, armv7a_read_ttbcr() is called to re-parse the ttb configuration and update the cache. Change-Id: I1c3adf53ea9d748a0e1e3091d9581e5c43ed64e8 Signed-off-by: Matthias Welwarsky <matthias@welwarsky.de> Reviewed-on: http://openocd.zylin.com/3005 Tested-by: jenkins Reviewed-by: Freddie Chopin <freddie.chopin@gmail.com>
Diffstat (limited to 'src/target/armv7a.c')
-rw-r--r--src/target/armv7a.c23
1 files changed, 17 insertions, 6 deletions
diff --git a/src/target/armv7a.c b/src/target/armv7a.c
index 170cfcc..b787838 100644
--- a/src/target/armv7a.c
+++ b/src/target/armv7a.c
@@ -154,10 +154,11 @@ static int armv7a_read_ttbcr(struct target *target)
if (retval != ERROR_OK)
goto done;
- LOG_INFO("ttbcr %" PRIx32 "ttbr0 %" PRIx32 "ttbr1 %" PRIx32, ttbcr, ttbr0, ttbr1);
+ LOG_INFO("ttbcr %" PRIx32 " ttbr0 %" PRIx32 " ttbr1 %" PRIx32, ttbcr, ttbr0, ttbr1);
armv7a->armv7a_mmu.ttbr1_used = ((ttbcr & 0x7) != 0) ? 1 : 0;
armv7a->armv7a_mmu.ttbr0_mask = 0;
+ armv7a->armv7a_mmu.ttbcr = ttbcr;
retval = armv7a_read_midr(target);
if (retval != ERROR_OK)
@@ -199,17 +200,27 @@ int armv7a_mmu_translate_va(struct target *target, uint32_t va, uint32_t *val)
struct armv7a_common *armv7a = target_to_armv7a(target);
struct arm_dpm *dpm = armv7a->arm.dpm;
uint32_t ttb = 0; /* default ttb0 */
- if (armv7a->armv7a_mmu.ttbr1_used == -1)
+ uint32_t ttbcr;
+
+ retval = dpm->prepare(dpm);
+ if (retval != ERROR_OK)
+ goto done;
+
+ /* MRC p15,0,<Rt>,c2,c0,2 ; Read CP15 Translation Table Base Control Register*/
+ retval = dpm->instr_read_data_r0(dpm,
+ ARMV4_5_MRC(15, 0, 0, 2, 0, 2),
+ &ttbcr);
+ if (retval != ERROR_OK)
+ goto done;
+
+ /* if ttbcr has changed, re-read the information */
+ if (armv7a->armv7a_mmu.ttbcr != ttbcr)
armv7a_read_ttbcr(target);
if ((armv7a->armv7a_mmu.ttbr1_used) &&
(va > (0xffffffff & armv7a->armv7a_mmu.ttbr0_mask))) {
/* select ttb 1 */
ttb = 1;
}
- retval = dpm->prepare(dpm);
- if (retval != ERROR_OK)
- goto done;
-
/* MRC p15,0,<Rt>,c2,c0,ttb */
retval = dpm->instr_read_data_r0(dpm,
ARMV4_5_MRC(15, 0, 0, 2, 0, ttb),