aboutsummaryrefslogtreecommitdiff
path: root/src/target
diff options
context:
space:
mode:
authorDaniel Glöckner <daniel-gl@gmx.net>2014-11-20 23:57:26 +0100
committerPaul Fertser <fercerpav@gmail.com>2015-02-11 16:18:50 +0000
commitb2dc1af59a4cead2bd9446256ef31658b2a5de61 (patch)
treed990362369ed06d00e7e9f89e384a0c3d4829199 /src/target
parentfb9277191b715566c82b633a474a5c7c78fcfe1a (diff)
armv7a: fix interpretation of MMU table
On armv7 there no longer are 1kB pages. Instead the bit that in older architectures distinguished 1kB pages from 4kB pages is on armv7 used for as execute-never marker. There may now also be 16MB supersections with 40 bit physical address. Change-Id: I959bdb8012782a9d07d968907a21f50e3d9b356a Signed-off-by: Daniel Glöckner <daniel-gl@gmx.net> Reviewed-on: http://openocd.zylin.com/2386 Tested-by: jenkins Reviewed-by: Vladimir Svoboda <ze.vlad@gmail.com> Reviewed-by: Paul Fertser <fercerpav@gmail.com>
Diffstat (limited to 'src/target')
-rw-r--r--src/target/armv7a.c46
1 files changed, 17 insertions, 29 deletions
diff --git a/src/target/armv7a.c b/src/target/armv7a.c
index ca599eb6..170cfcc2 100644
--- a/src/target/armv7a.c
+++ b/src/target/armv7a.c
@@ -232,27 +232,26 @@ int armv7a_mmu_translate_va(struct target *target, uint32_t va, uint32_t *val)
}
- if ((first_lvl_descriptor & 0x3) == 2) {
+ if ((first_lvl_descriptor & 0x40002) == 2) {
/* section descriptor */
*val = (first_lvl_descriptor & 0xfff00000) | (va & 0x000fffff);
return ERROR_OK;
+ } else if ((first_lvl_descriptor & 0x40002) == 0x40002) {
+ /* supersection descriptor */
+ if (first_lvl_descriptor & 0x00f001e0) {
+ LOG_ERROR("Physical address does not fit into 32 bits");
+ return ERROR_TARGET_TRANSLATION_FAULT;
+ }
+ *val = (first_lvl_descriptor & 0xff000000) | (va & 0x00ffffff);
+ return ERROR_OK;
}
- if ((first_lvl_descriptor & 0x3) == 1) {
- /* coarse page table */
- retval = armv7a->armv7a_mmu.read_physical_memory(target,
- (first_lvl_descriptor & 0xfffffc00) | ((va & 0x000ff000) >> 10),
- 4, 1, (uint8_t *)&second_lvl_descriptor);
- if (retval != ERROR_OK)
- return retval;
- } else if ((first_lvl_descriptor & 0x3) == 3) {
- /* fine page table */
- retval = armv7a->armv7a_mmu.read_physical_memory(target,
- (first_lvl_descriptor & 0xfffff000) | ((va & 0x000ffc00) >> 8),
- 4, 1, (uint8_t *)&second_lvl_descriptor);
- if (retval != ERROR_OK)
- return retval;
- }
+ /* page table */
+ retval = armv7a->armv7a_mmu.read_physical_memory(target,
+ (first_lvl_descriptor & 0xfffffc00) | ((va & 0x000ff000) >> 10),
+ 4, 1, (uint8_t *)&second_lvl_descriptor);
+ if (retval != ERROR_OK)
+ return retval;
second_lvl_descriptor = target_buffer_get_u32(target, (uint8_t *)
&second_lvl_descriptor);
@@ -267,23 +266,12 @@ int armv7a_mmu_translate_va(struct target *target, uint32_t va, uint32_t *val)
if ((second_lvl_descriptor & 0x3) == 1) {
/* large page descriptor */
*val = (second_lvl_descriptor & 0xffff0000) | (va & 0x0000ffff);
- return ERROR_OK;
- }
-
- if ((second_lvl_descriptor & 0x3) == 2) {
+ } else {
/* small page descriptor */
*val = (second_lvl_descriptor & 0xfffff000) | (va & 0x00000fff);
- return ERROR_OK;
}
- if ((second_lvl_descriptor & 0x3) == 3) {
- *val = (second_lvl_descriptor & 0xfffffc00) | (va & 0x000003ff);
- return ERROR_OK;
- }
-
- /* should not happen */
- LOG_ERROR("Address translation failure");
- return ERROR_TARGET_TRANSLATION_FAULT;
+ return ERROR_OK;
done:
return retval;