aboutsummaryrefslogtreecommitdiff
path: root/src/target
diff options
context:
space:
mode:
Diffstat (limited to 'src/target')
-rw-r--r--src/target/armv8.c73
-rw-r--r--src/target/armv8.h1
-rw-r--r--src/target/armv8_dpm.c4
-rw-r--r--src/target/target.c1
-rw-r--r--src/target/target.h3
5 files changed, 80 insertions, 2 deletions
diff --git a/src/target/armv8.c b/src/target/armv8.c
index cee837f5..76a2d98a 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 dfd54edc..af00e52d 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 a5d7d11f..081eed21 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 9955a565..1f8e0bfc 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 36b131aa..794ee833 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 {