aboutsummaryrefslogtreecommitdiff
path: root/src/target
diff options
context:
space:
mode:
authorPaul Fertser <fercerpav@gmail.com>2013-10-29 13:45:07 +0400
committerAndreas Fritiofson <andreas.fritiofson@gmail.com>2014-02-06 22:21:57 +0000
commitddef36905cc3e4493960ce0ad6bf6ac113148c29 (patch)
tree5b510365fa03a3794140f77d49f6edc788594346 /src/target
parente4125d136c72b1225c4547e670db102f88cf6efc (diff)
downloadriscv-openocd-ddef36905cc3e4493960ce0ad6bf6ac113148c29.zip
riscv-openocd-ddef36905cc3e4493960ce0ad6bf6ac113148c29.tar.gz
riscv-openocd-ddef36905cc3e4493960ce0ad6bf6ac113148c29.tar.bz2
cortex_a: do not try to use MMU for translation if it wasn't enabled on target stop
On a target where AHB AP memory access is unavailable, care should be taken to avoid treating addresses as virtual if the MMU was disabled at the time the target was stopped. Without this it's impossible to peek memory with Gdb when debugging e.g. a bootloader because cortex_a8_read_memory() unconditionally tried (and failed because of a sanity check in cortex_a8_mmu_modify) to enable MMU. Change-Id: Id7c63f4912920fb71a6104226ec6428d18c96a56 Reported-by: mbm@openwrt.org Signed-off-by: Paul Fertser <fercerpav@gmail.com> Reviewed-on: http://openocd.zylin.com/1787 Tested-by: jenkins Reviewed-by: Andreas Fritiofson <andreas.fritiofson@gmail.com>
Diffstat (limited to 'src/target')
-rw-r--r--src/target/cortex_a.c69
1 files changed, 36 insertions, 33 deletions
diff --git a/src/target/cortex_a.c b/src/target/cortex_a.c
index 13b8ca5..5e37e2a 100644
--- a/src/target/cortex_a.c
+++ b/src/target/cortex_a.c
@@ -2131,7 +2131,7 @@ static int cortex_a8_read_phys_memory(struct target *target,
static int cortex_a8_read_memory(struct target *target, uint32_t address,
uint32_t size, uint32_t count, uint8_t *buffer)
{
- int enabled = 0;
+ int mmu_enabled = 0;
uint32_t virt, phys;
int retval;
struct armv7a_common *armv7a = target_to_armv7a(target);
@@ -2141,31 +2141,32 @@ static int cortex_a8_read_memory(struct target *target, uint32_t address,
/* cortex_a8 handles unaligned memory access */
LOG_DEBUG("Reading memory at address 0x%" PRIx32 "; size %" PRId32 "; count %" PRId32, address,
size, count);
+
+ /* determine if MMU was enabled on target stop */
+ if (!armv7a->is_armv7r) {
+ retval = cortex_a8_mmu(target, &mmu_enabled);
+ if (retval != ERROR_OK)
+ return retval;
+ }
+
if (armv7a->memory_ap_available && (apsel == armv7a->memory_ap)) {
- if (!armv7a->is_armv7r) {
- retval = cortex_a8_mmu(target, &enabled);
+ if (mmu_enabled) {
+ virt = address;
+ retval = cortex_a8_virt2phys(target, virt, &phys);
if (retval != ERROR_OK)
return retval;
-
- if (enabled) {
- virt = address;
- retval = cortex_a8_virt2phys(target, virt, &phys);
- if (retval != ERROR_OK)
- return retval;
-
- LOG_DEBUG("Reading at virtual address. Translating v:0x%" PRIx32 " to r:0x%" PRIx32,
- virt, phys);
- address = phys;
- }
+ LOG_DEBUG("Reading at virtual address. Translating v:0x%" PRIx32 " to r:0x%" PRIx32,
+ virt, phys);
+ address = phys;
}
retval = cortex_a8_read_phys_memory(target, address, size, count, buffer);
} else {
- if (!armv7a->is_armv7r) {
+ if (mmu_enabled) {
retval = cortex_a8_check_address(target, address);
if (retval != ERROR_OK)
return retval;
- /* enable mmu */
+ /* enable MMU as we could have disabled it for phys access */
retval = cortex_a8_mmu_modify(target, 1);
if (retval != ERROR_OK)
return retval;
@@ -2266,44 +2267,46 @@ static int cortex_a8_write_phys_memory(struct target *target,
static int cortex_a8_write_memory(struct target *target, uint32_t address,
uint32_t size, uint32_t count, const uint8_t *buffer)
{
- int enabled = 0;
+ int mmu_enabled = 0;
uint32_t virt, phys;
int retval;
struct armv7a_common *armv7a = target_to_armv7a(target);
struct adiv5_dap *swjdp = armv7a->arm.dap;
uint8_t apsel = swjdp->apsel;
+
/* cortex_a8 handles unaligned memory access */
LOG_DEBUG("Writing memory at address 0x%" PRIx32 "; size %" PRId32 "; count %" PRId32, address,
size, count);
- if (armv7a->memory_ap_available && (apsel == armv7a->memory_ap)) {
+ /* determine if MMU was enabled on target stop */
+ if (!armv7a->is_armv7r) {
+ retval = cortex_a8_mmu(target, &mmu_enabled);
+ if (retval != ERROR_OK)
+ return retval;
+ }
+
+ if (armv7a->memory_ap_available && (apsel == armv7a->memory_ap)) {
LOG_DEBUG("Writing memory to address 0x%" PRIx32 "; size %" PRId32 "; count %" PRId32, address, size,
count);
- if (!armv7a->is_armv7r) {
- retval = cortex_a8_mmu(target, &enabled);
+ if (mmu_enabled) {
+ virt = address;
+ retval = cortex_a8_virt2phys(target, virt, &phys);
if (retval != ERROR_OK)
return retval;
- if (enabled) {
- virt = address;
- retval = cortex_a8_virt2phys(target, virt, &phys);
- if (retval != ERROR_OK)
- return retval;
- LOG_DEBUG("Writing to virtual address. Translating v:0x%" PRIx32 " to r:0x%" PRIx32,
- virt,
- phys);
- address = phys;
- }
+ LOG_DEBUG("Writing to virtual address. Translating v:0x%" PRIx32 " to r:0x%" PRIx32,
+ virt,
+ phys);
+ address = phys;
}
-
retval = cortex_a8_write_phys_memory(target, address, size,
count, buffer);
} else {
- if (!armv7a->is_armv7r) {
+ if (mmu_enabled) {
retval = cortex_a8_check_address(target, address);
if (retval != ERROR_OK)
return retval;
- /* enable mmu */
+ /* enable MMU as we could have disabled it for phys access */
retval = cortex_a8_mmu_modify(target, 1);
if (retval != ERROR_OK)
return retval;