X-Git-Url: https://review.openocd.org/gitweb?a=blobdiff_plain;f=src%2Ftarget%2Farmv8.c;h=c8cfcae2050bcb3d38edfd69b5a4a0481eb5d9a2;hb=6949b5393d9fb6511ddef13ce0bef1a147e7f962;hp=dfa2c67a5ccfa95a99a1291d5771b937acb76f84;hpb=b82ee0799f6e30d3f03bd707c6e9729de92248d2;p=openocd.git diff --git a/src/target/armv8.c b/src/target/armv8.c index dfa2c67a5c..c8cfcae205 100644 --- a/src/target/armv8.c +++ b/src/target/armv8.c @@ -73,6 +73,10 @@ static const struct { .name = "ABT", .psr = ARM_MODE_ABT, }, + { + .name = "SYS", + .psr = ARM_MODE_SYS, + }, { .name = "EL0T", .psr = ARMV8_64_EL0T, @@ -674,8 +678,8 @@ void armv8_set_cpsr(struct arm *arm, uint32_t cpsr) */ if (arm->cpsr) { buf_set_u32(arm->cpsr->value, 0, 32, cpsr); - arm->cpsr->valid = 1; - arm->cpsr->dirty = 0; + arm->cpsr->valid = true; + arm->cpsr->dirty = false; } /* Older ARMs won't have the J bit */ @@ -936,6 +940,11 @@ int armv8_mmu_translate_va_pa(struct target *target, target_addr_t va, "Secure", "Not Secure" }; + if (target->state != TARGET_HALTED) { + LOG_WARNING("target %s not halted", target_name(target)); + return ERROR_TARGET_NOT_HALTED; + } + retval = dpm->prepare(dpm); if (retval != ERROR_OK) return retval; @@ -1004,6 +1013,72 @@ int armv8_mmu_translate_va_pa(struct target *target, target_addr_t va, return retval; } +COMMAND_HANDLER(armv8_handle_exception_catch_command) +{ + struct target *target = get_current_target(CMD_CTX); + struct armv8_common *armv8 = target_to_armv8(target); + uint32_t edeccr = 0; + unsigned int argp = 0; + int retval; + + static const Jim_Nvp nvp_ecatch_modes[] = { + { .name = "off", .value = 0 }, + { .name = "nsec_el1", .value = (1 << 5) }, + { .name = "nsec_el2", .value = (2 << 5) }, + { .name = "nsec_el12", .value = (3 << 5) }, + { .name = "sec_el1", .value = (1 << 1) }, + { .name = "sec_el3", .value = (4 << 1) }, + { .name = "sec_el13", .value = (5 << 1) }, + { .name = NULL, .value = -1 }, + }; + const Jim_Nvp *n; + + if (CMD_ARGC == 0) { + const char *sec = NULL, *nsec = NULL; + + retval = mem_ap_read_atomic_u32(armv8->debug_ap, + armv8->debug_base + CPUV8_DBG_ECCR, &edeccr); + if (retval != ERROR_OK) + return retval; + + n = Jim_Nvp_value2name_simple(nvp_ecatch_modes, edeccr & 0x0f); + if (n->name != NULL) + sec = n->name; + + n = Jim_Nvp_value2name_simple(nvp_ecatch_modes, edeccr & 0xf0); + if (n->name != NULL) + nsec = n->name; + + if (sec == NULL || nsec == NULL) { + LOG_WARNING("Exception Catch: unknown exception catch configuration: EDECCR = %02x", edeccr & 0xff); + return ERROR_FAIL; + } + + command_print(CMD_CTX, "Exception Catch: Secure: %s, Non-Secure: %s", sec, nsec); + return ERROR_OK; + } + + while (CMD_ARGC > argp) { + n = Jim_Nvp_name2value_simple(nvp_ecatch_modes, CMD_ARGV[argp]); + if (n->name == NULL) { + LOG_ERROR("Unknown option: %s", CMD_ARGV[argp]); + return ERROR_FAIL; + } + + LOG_DEBUG("found: %s", n->name); + + edeccr |= n->value; + argp++; + } + + retval = mem_ap_write_atomic_u32(armv8->debug_ap, + armv8->debug_base + CPUV8_DBG_ECCR, edeccr); + if (retval != ERROR_OK) + return retval; + + return ERROR_OK; +} + int armv8_handle_cache_info_command(struct command_context *cmd_ctx, struct armv8_cache_common *armv8_cache) { @@ -1443,17 +1518,17 @@ static int armv8_set_core_reg(struct reg *reg, uint8_t *buf) armv8_set_cpsr(arm, (uint32_t)value); else { buf_set_u64(reg->value, 0, reg->size, value); - reg->valid = 1; + reg->valid = true; } } else if (reg->size <= 128) { uint64_t hvalue = buf_get_u64(buf + 8, 0, reg->size - 64); buf_set_u64(reg->value, 0, 64, value); buf_set_u64(reg->value + 8, 0, reg->size - 64, hvalue); - reg->valid = 1; + reg->valid = true; } - reg->dirty = 1; + reg->dirty = true; return ERROR_OK; } @@ -1472,6 +1547,9 @@ static int armv8_get_core_reg32(struct reg *reg) struct reg *reg64; int retval; + if (target->state != TARGET_HALTED) + return ERROR_TARGET_NOT_HALTED; + /* get the corresponding Aarch64 register */ reg64 = cache->reg_list + armv8_reg->num; if (reg64->valid) { @@ -1495,6 +1573,9 @@ static int armv8_set_core_reg32(struct reg *reg, uint8_t *buf) struct reg *reg64 = cache->reg_list + armv8_reg->num; uint32_t value = buf_get_u32(buf, 0, 32); + if (target->state != TARGET_HALTED) + return ERROR_TARGET_NOT_HALTED; + if (reg64 == arm->cpsr) { armv8_set_cpsr(arm, value); } else { @@ -1504,11 +1585,11 @@ static int armv8_set_core_reg32(struct reg *reg, uint8_t *buf) uint64_t value64 = buf_get_u64(buf, 0, 64); buf_set_u64(reg->value, 0, 64, value64); } - reg->valid = 1; - reg64->valid = 1; + reg->valid = true; + reg64->valid = true; } - reg64->dirty = 1; + reg64->dirty = true; return ERROR_OK; } @@ -1660,9 +1741,21 @@ void armv8_free_reg_cache(struct target *target) } const struct command_registration armv8_command_handlers[] = { + { + .name = "catch_exc", + .handler = armv8_handle_exception_catch_command, + .mode = COMMAND_EXEC, + .help = "configure exception catch", + .usage = "[(nsec_el1,nsec_el2,sec_el1,sec_el3)+,off]", + }, COMMAND_REGISTRATION_DONE }; +const char *armv8_get_gdb_arch(struct target *target) +{ + return "aarch64"; +} + int armv8_get_gdb_reg_list(struct target *target, struct reg **reg_list[], int *reg_list_size, enum target_register_class reg_class)