diff options
author | Matthias Welwarsky <matthias.welwarsky@sysgo.com> | 2018-04-05 13:42:21 +0200 |
---|---|---|
committer | Matthias Welwarsky <matthias@welwarsky.de> | 2019-03-04 11:53:00 +0000 |
commit | db429c34d047ac40dadf0087f3b3434551c855d4 (patch) | |
tree | 75b8c06d64c3f9decec08aa9583195c8fb04e100 /src/target | |
parent | 21687eb983a4d5e30cd9c4050b9ebce2f3b280c7 (diff) | |
download | riscv-openocd-db429c34d047ac40dadf0087f3b3434551c855d4.zip riscv-openocd-db429c34d047ac40dadf0087f3b3434551c855d4.tar.gz riscv-openocd-db429c34d047ac40dadf0087f3b3434551c855d4.tar.bz2 |
armv8: allow halt on exception
add command 'catch_exc' to halt a core on entering any of Secure EL1 or
EL3 or Non-Secure EL1 or EL2.
Change-Id: I0c68e247af68dd96616855a9bc1063c277d222e5
Signed-off-by: Matthias Welwarsky <matthias.welwarsky@sysgo.com>
Reviewed-on: http://openocd.zylin.com/4479
Tested-by: jenkins
Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com>
Reviewed-by: Matthias Welwarsky <matthias@welwarsky.de>
Diffstat (limited to 'src/target')
-rw-r--r-- | src/target/armv8.c | 73 | ||||
-rw-r--r-- | src/target/armv8.h | 1 | ||||
-rw-r--r-- | src/target/armv8_dpm.c | 4 | ||||
-rw-r--r-- | src/target/target.c | 1 | ||||
-rw-r--r-- | src/target/target.h | 3 |
5 files changed, 80 insertions, 2 deletions
diff --git a/src/target/armv8.c b/src/target/armv8.c index cee837f..76a2d98 100644 --- a/src/target/armv8.c +++ b/src/target/armv8.c @@ -1013,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) { @@ -1675,6 +1741,13 @@ 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 }; diff --git a/src/target/armv8.h b/src/target/armv8.h index dfd54ed..af00e52 100644 --- a/src/target/armv8.h +++ b/src/target/armv8.h @@ -261,6 +261,7 @@ static inline bool is_armv8(struct armv8_common *armv8) #define CPUV8_DBG_WFAR1 0x34 #define CPUV8_DBG_DSCR 0x088 #define CPUV8_DBG_DRCR 0x090 +#define CPUV8_DBG_ECCR 0x098 #define CPUV8_DBG_PRCR 0x310 #define CPUV8_DBG_PRSR 0x314 diff --git a/src/target/armv8_dpm.c b/src/target/armv8_dpm.c index a5d7d11..081eed2 100644 --- a/src/target/armv8_dpm.c +++ b/src/target/armv8_dpm.c @@ -1381,13 +1381,15 @@ void armv8_dpm_report_dscr(struct arm_dpm *dpm, uint32_t dscr) case DSCRV8_ENTRY_BKPT: /* SW BKPT (?) */ case DSCRV8_ENTRY_RESET_CATCH: /* Reset catch */ case DSCRV8_ENTRY_OS_UNLOCK: /*OS unlock catch*/ - case DSCRV8_ENTRY_EXCEPTION_CATCH: /*exception catch*/ case DSCRV8_ENTRY_SW_ACCESS_DBG: /*SW access dbg register*/ target->debug_reason = DBG_REASON_BREAKPOINT; break; case DSCRV8_ENTRY_WATCHPOINT: /* asynch watchpoint */ target->debug_reason = DBG_REASON_WATCHPOINT; break; + case DSCRV8_ENTRY_EXCEPTION_CATCH: /*exception catch*/ + target->debug_reason = DBG_REASON_EXC_CATCH; + break; default: target->debug_reason = DBG_REASON_UNDEFINED; break; diff --git a/src/target/target.c b/src/target/target.c index 9955a56..1f8e0bf 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -251,6 +251,7 @@ static const Jim_Nvp nvp_target_debug_reason[] = { { .name = "single-step" , .value = DBG_REASON_SINGLESTEP }, { .name = "target-not-halted" , .value = DBG_REASON_NOTHALTED }, { .name = "program-exit" , .value = DBG_REASON_EXIT }, + { .name = "exception-catch" , .value = DBG_REASON_EXC_CATCH }, { .name = "undefined" , .value = DBG_REASON_UNDEFINED }, { .name = NULL, .value = -1 }, }; diff --git a/src/target/target.h b/src/target/target.h index 36b131a..794ee83 100644 --- a/src/target/target.h +++ b/src/target/target.h @@ -84,7 +84,8 @@ enum target_debug_reason { DBG_REASON_SINGLESTEP = 4, DBG_REASON_NOTHALTED = 5, DBG_REASON_EXIT = 6, - DBG_REASON_UNDEFINED = 7, + DBG_REASON_EXC_CATCH = 7, + DBG_REASON_UNDEFINED = 8, }; enum target_endianness { |