aboutsummaryrefslogtreecommitdiff
path: root/src/target/armv7a.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/target/armv7a.c')
-rw-r--r--src/target/armv7a.c169
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)
{