]> git.sur5r.net Git - openocd/commitdiff
armv7a: fix interpretation of MMU table
authorDaniel Glöckner <daniel-gl@gmx.net>
Thu, 20 Nov 2014 22:57:26 +0000 (23:57 +0100)
committerPaul Fertser <fercerpav@gmail.com>
Wed, 11 Feb 2015 16:18:50 +0000 (16:18 +0000)
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>
src/target/armv7a.c

index ca599eb68ab01abcc4c46cea904d7faa14700ae9..170cfcc28db2dbee92f7361b6efb0135486a8908 100644 (file)
@@ -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;