semihosting: add semihosting handlers to AArch64
[fw/openocd] / src / target / armv7a.c
index 183fde1bf6fcdb1706f022473a8dd7a0ca51bbf2..2be70b78b04c7d95553944b64aea9b5a67c079be 100644 (file)
@@ -24,6 +24,7 @@
 #include <helper/replacements.h>
 
 #include "armv7a.h"
+#include "armv7a_mmu.h"
 #include "arm_disassembler.h"
 
 #include "register.h"
@@ -124,7 +125,7 @@ done:
        return retval;
 }
 
-static int armv7a_read_ttbcr(struct target *target)
+int armv7a_read_ttbcr(struct target *target)
 {
        struct armv7a_common *armv7a = target_to_armv7a(target);
        struct arm_dpm *dpm = armv7a->arm.dpm;
@@ -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)
 {
@@ -396,7 +229,7 @@ COMMAND_HANDLER(handle_cache_l2x)
        if (CMD_ARGC != 2)
                return ERROR_COMMAND_SYNTAX_ERROR;
 
-       /* command_print(CMD_CTX, "%s %s", CMD_ARGV[0], CMD_ARGV[1]); */
+       /* command_print(CMD, "%s %s", CMD_ARGV[0], CMD_ARGV[1]); */
        COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], base);
        COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], way);
 
@@ -406,7 +239,7 @@ COMMAND_HANDLER(handle_cache_l2x)
        return ERROR_OK;
 }
 
-int armv7a_handle_cache_info_command(struct command_context *cmd_ctx,
+int armv7a_handle_cache_info_command(struct command_invocation *cmd,
        struct armv7a_cache_common *armv7a_cache)
 {
        struct armv7a_l2x_cache *l2x_cache = (struct armv7a_l2x_cache *)
@@ -415,7 +248,7 @@ int armv7a_handle_cache_info_command(struct command_context *cmd_ctx,
        int cl;
 
        if (armv7a_cache->info == -1) {
-               command_print(cmd_ctx, "cache not yet identified");
+               command_print(cmd, "cache not yet identified");
                return ERROR_OK;
        }
 
@@ -423,7 +256,7 @@ int armv7a_handle_cache_info_command(struct command_context *cmd_ctx,
                struct armv7a_arch_cache *arch = &(armv7a_cache->arch[cl]);
 
                if (arch->ctype & 1) {
-                       command_print(cmd_ctx,
+                       command_print(cmd,
                                "L%d I-Cache: linelen %" PRIi32
                                ", associativity %" PRIi32
                                ", nsets %" PRIi32
@@ -436,7 +269,7 @@ int armv7a_handle_cache_info_command(struct command_context *cmd_ctx,
                }
 
                if (arch->ctype >= 2) {
-                       command_print(cmd_ctx,
+                       command_print(cmd,
                                "L%d D-Cache: linelen %" PRIi32
                                ", associativity %" PRIi32
                                ", nsets %" PRIi32
@@ -450,7 +283,7 @@ int armv7a_handle_cache_info_command(struct command_context *cmd_ctx,
        }
 
        if (l2x_cache != NULL)
-               command_print(cmd_ctx, "Outer unified cache Base Address 0x%" PRIx32 ", %" PRId32 " ways",
+               command_print(cmd, "Outer unified cache Base Address 0x%" PRIx32 ", %" PRId32 " ways",
                        l2x_cache->base, l2x_cache->way);
 
        return ERROR_OK;
@@ -474,23 +307,21 @@ static int armv7a_read_mpidr(struct target *target)
        if (retval != ERROR_OK)
                goto done;
 
-       /* ARMv7R uses a different format for MPIDR.
-        * When configured uniprocessor (most R cores) it reads as 0.
-        * This will need to be implemented for multiprocessor ARMv7R cores. */
-       if (armv7a->is_armv7r) {
-               if (mpidr)
-                       LOG_ERROR("MPIDR nonzero in ARMv7-R target");
-               goto done;
-       }
-
-       if (mpidr & 1<<31) {
+       /* Is register in Multiprocessing Extensions register format? */
+       if (mpidr & MPIDR_MP_EXT) {
+               LOG_DEBUG("%s: MPIDR 0x%" PRIx32, target_name(target), mpidr);
                armv7a->multi_processor_system = (mpidr >> 30) & 1;
+               armv7a->multi_threading_processor = (mpidr >> 24) & 1;
+               armv7a->level2_id = (mpidr >> 16) & 0xf;
                armv7a->cluster_id = (mpidr >> 8) & 0xf;
-               armv7a->cpu_id = mpidr & 0x3;
-               LOG_INFO("%s cluster %x core %x %s", target_name(target),
+               armv7a->cpu_id = mpidr & 0xf;
+               LOG_INFO("%s: MPIDR level2 %x, cluster %x, core %x, %s, %s",
+                       target_name(target),
+                       armv7a->level2_id,
                        armv7a->cluster_id,
                        armv7a->cpu_id,
-                       armv7a->multi_processor_system == 0 ? "multi core" : "mono core");
+                       armv7a->multi_processor_system == 0 ? "multi core" : "mono core",
+                       armv7a->multi_threading_processor == 1 ? "SMT" : "no SMT");
 
        } else
                LOG_ERROR("MPIDR not in multiprocessor format");
@@ -554,9 +385,6 @@ int armv7a_identify_cache(struct target *target)
        struct armv7a_cache_common *cache =
                &(armv7a->armv7a_mmu.armv7a_cache);
 
-       if (!armv7a->is_armv7r)
-               armv7a_read_ttbcr(target);
-
        retval = dpm->prepare(dpm);
        if (retval != ERROR_OK)
                goto done;
@@ -729,8 +557,6 @@ int armv7a_arch_state(struct target *target)
 
        arm_arch_state(target);
 
-       armv7a_read_ttbcr(target);
-
        if (armv7a->is_armv7r) {
                LOG_USER("D-Cache: %s, I-Cache: %s",
                        state[armv7a->armv7a_mmu.armv7a_cache.d_u_cache_enabled],
@@ -756,8 +582,7 @@ static const struct command_registration l2_cache_commands[] = {
                .name = "l2x",
                .handler = handle_cache_l2x,
                .mode = COMMAND_EXEC,
-               .help = "configure l2x cache "
-                       "",
+               .help = "configure l2x cache",
                .usage = "[base_addr] [number_of_way]",
        },
        COMMAND_REGISTRATION_DONE
@@ -776,9 +601,6 @@ const struct command_registration l2x_cache_command_handlers[] = {
 };
 
 const struct command_registration armv7a_command_handlers[] = {
-       {
-               .chain = dap_command_handlers,
-       },
        {
                .chain = l2x_cache_command_handlers,
        },