diff options
author | Matthias Welwarsky <matthias.welwarsky@sysgo.com> | 2016-07-14 21:00:59 +0200 |
---|---|---|
committer | Matthias Welwarsky <matthias@welwarsky.de> | 2018-11-08 09:10:09 +0000 |
commit | 010b09121ca08f955921654c6a3d405be80afef1 (patch) | |
tree | ffdcd7106d871df2467454a0e9976434e9029661 /src/target/armv7a.c | |
parent | 29c81a80510aa82b1842b15a9b091a3062cb51dc (diff) | |
download | riscv-openocd-010b09121ca08f955921654c6a3d405be80afef1.zip riscv-openocd-010b09121ca08f955921654c6a3d405be80afef1.tar.gz riscv-openocd-010b09121ca08f955921654c6a3d405be80afef1.tar.bz2 |
armv7a: ARMv7-A MMU tools
factor out mmu-related code from armv7a.c, add a 'dump' command for
page tables.
Change-Id: Ic1ac3c645d7fd097e9d625c7c8302e7065875dd4
Signed-off-by: Matthias Welwarsky <matthias.welwarsky@sysgo.com>
Reviewed-on: http://openocd.zylin.com/4327
Tested-by: jenkins
Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com>
Reviewed-by: Matthias Welwarsky <matthias@welwarsky.de>
Diffstat (limited to 'src/target/armv7a.c')
-rw-r--r-- | src/target/armv7a.c | 169 |
1 files changed, 1 insertions, 168 deletions
diff --git a/src/target/armv7a.c b/src/target/armv7a.c index eecfa70..f9594c9 100644 --- a/src/target/armv7a.c +++ b/src/target/armv7a.c @@ -24,6 +24,7 @@ #include <helper/replacements.h> #include "armv7a.h" +#include "armv7a_mmu.h" #include "arm_disassembler.h" #include "register.h" @@ -188,174 +189,6 @@ done: return retval; } -/* method adapted to Cortex-A : reused ARM v4 v5 method */ -int armv7a_mmu_translate_va(struct target *target, uint32_t va, uint32_t *val) -{ - uint32_t first_lvl_descriptor = 0x0; - uint32_t second_lvl_descriptor = 0x0; - int retval; - struct armv7a_common *armv7a = target_to_armv7a(target); - uint32_t ttbidx = 0; /* default to ttbr0 */ - uint32_t ttb_mask; - uint32_t va_mask; - uint32_t ttb; - - if (target->state != TARGET_HALTED) - LOG_INFO("target not halted, using cached values for translation table!"); - - /* if va is above the range handled by ttbr0, select ttbr1 */ - if (va > armv7a->armv7a_mmu.ttbr_range[0]) { - /* select ttb 1 */ - ttbidx = 1; - } - - ttb = armv7a->armv7a_mmu.ttbr[ttbidx]; - ttb_mask = armv7a->armv7a_mmu.ttbr_mask[ttbidx]; - va_mask = 0xfff00000 & armv7a->armv7a_mmu.ttbr_range[ttbidx]; - - LOG_DEBUG("ttb_mask %" PRIx32 " va_mask %" PRIx32 " ttbidx %i", - ttb_mask, va_mask, ttbidx); - retval = armv7a->armv7a_mmu.read_physical_memory(target, - (ttb & ttb_mask) | ((va & va_mask) >> 18), - 4, 1, (uint8_t *)&first_lvl_descriptor); - if (retval != ERROR_OK) - return retval; - first_lvl_descriptor = target_buffer_get_u32(target, (uint8_t *) - &first_lvl_descriptor); - /* reuse armv4_5 piece of code, specific armv7a changes may come later */ - LOG_DEBUG("1st lvl desc: %8.8" PRIx32 "", first_lvl_descriptor); - - if ((first_lvl_descriptor & 0x3) == 0) { - LOG_ERROR("Address translation failure"); - return ERROR_TARGET_TRANSLATION_FAULT; - } - - - 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; - } - - /* 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); - - LOG_DEBUG("2nd lvl desc: %8.8" PRIx32 "", second_lvl_descriptor); - - if ((second_lvl_descriptor & 0x3) == 0) { - LOG_ERROR("Address translation failure"); - return ERROR_TARGET_TRANSLATION_FAULT; - } - - if ((second_lvl_descriptor & 0x3) == 1) { - /* large page descriptor */ - *val = (second_lvl_descriptor & 0xffff0000) | (va & 0x0000ffff); - } else { - /* small page descriptor */ - *val = (second_lvl_descriptor & 0xfffff000) | (va & 0x00000fff); - } - - return ERROR_OK; -} - -/* V7 method VA TO PA */ -int armv7a_mmu_translate_va_pa(struct target *target, uint32_t va, - uint32_t *val, int meminfo) -{ - int retval = ERROR_FAIL; - struct armv7a_common *armv7a = target_to_armv7a(target); - struct arm_dpm *dpm = armv7a->arm.dpm; - uint32_t virt = va & ~0xfff; - uint32_t NOS, NS, INNER, OUTER; - *val = 0xdeadbeef; - retval = dpm->prepare(dpm); - if (retval != ERROR_OK) - goto done; - /* mmu must be enable in order to get a correct translation - * use VA to PA CP15 register for conversion */ - retval = dpm->instr_write_data_r0(dpm, - ARMV4_5_MCR(15, 0, 0, 7, 8, 0), - virt); - if (retval != ERROR_OK) - goto done; - retval = dpm->instr_read_data_r0(dpm, - ARMV4_5_MRC(15, 0, 0, 7, 4, 0), - val); - /* decode memory attribute */ - NOS = (*val >> 10) & 1; /* Not Outer shareable */ - NS = (*val >> 9) & 1; /* Non secure */ - INNER = (*val >> 4) & 0x7; - OUTER = (*val >> 2) & 0x3; - - if (retval != ERROR_OK) - goto done; - *val = (*val & ~0xfff) + (va & 0xfff); - if (*val == va) - LOG_WARNING("virt = phys : MMU disable !!"); - if (meminfo) { - LOG_INFO("%" PRIx32 " : %" PRIx32 " %s outer shareable %s secured", - va, *val, - NOS == 1 ? "not" : " ", - NS == 1 ? "not" : ""); - switch (OUTER) { - case 0: - LOG_INFO("outer: Non-Cacheable"); - break; - case 1: - LOG_INFO("outer: Write-Back, Write-Allocate"); - break; - case 2: - LOG_INFO("outer: Write-Through, No Write-Allocate"); - break; - case 3: - LOG_INFO("outer: Write-Back, no Write-Allocate"); - break; - } - switch (INNER) { - case 0: - LOG_INFO("inner: Non-Cacheable"); - break; - case 1: - LOG_INFO("inner: Strongly-ordered"); - break; - case 3: - LOG_INFO("inner: Device"); - break; - case 5: - LOG_INFO("inner: Write-Back, Write-Allocate"); - break; - case 6: - LOG_INFO("inner: Write-Through"); - break; - case 7: - LOG_INFO("inner: Write-Back, no Write-Allocate"); - break; - default: - LOG_INFO("inner: %" PRIx32 " ???", INNER); - } - } - -done: - dpm->finish(dpm); - - return retval; -} - /* FIXME: remove it */ static int armv7a_l2x_cache_init(struct target *target, uint32_t base, uint32_t way) { |