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>reverse-resume-order
parent
21687eb983
commit
db429c34d0
|
@ -9345,6 +9345,14 @@ be copied to an in-memory buffer identified by the @option{address} and
|
||||||
@option{size} options using DMA.
|
@option{size} options using DMA.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
|
@deffn Command {$target_name catch_exc} [@option{off}|@option{sec_el1}|@option{sec_el3}|@option{nsec_el1}|@option{nsec_el2}]+
|
||||||
|
Cause @command{$target_name} to halt when an exception is taken. Any combination of
|
||||||
|
Secure (sec) EL1/EL3 or Non-Secure (nsec) EL1/EL2 is valid. The target
|
||||||
|
@command{$target_name} will halt before taking the exception. In order to resume
|
||||||
|
the target, the exception catch must be disabled again with @command{$target_name catch_exc off}.
|
||||||
|
Issuing the command without options prints the current configuration.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
@section Intel Architecture
|
@section Intel Architecture
|
||||||
|
|
||||||
Intel Quark X10xx is the first product in the Quark family of SoCs. It is an IA-32
|
Intel Quark X10xx is the first product in the Quark family of SoCs. It is an IA-32
|
||||||
|
|
|
@ -153,6 +153,8 @@ static int gdb_last_signal(struct target *target)
|
||||||
return 0x05; /* SIGTRAP */
|
return 0x05; /* SIGTRAP */
|
||||||
case DBG_REASON_SINGLESTEP:
|
case DBG_REASON_SINGLESTEP:
|
||||||
return 0x05; /* SIGTRAP */
|
return 0x05; /* SIGTRAP */
|
||||||
|
case DBG_REASON_EXC_CATCH:
|
||||||
|
return 0x05;
|
||||||
case DBG_REASON_NOTHALTED:
|
case DBG_REASON_NOTHALTED:
|
||||||
return 0x0; /* no signal... shouldn't happen */
|
return 0x0; /* no signal... shouldn't happen */
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -1013,6 +1013,72 @@ int armv8_mmu_translate_va_pa(struct target *target, target_addr_t va,
|
||||||
return retval;
|
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,
|
int armv8_handle_cache_info_command(struct command_context *cmd_ctx,
|
||||||
struct armv8_cache_common *armv8_cache)
|
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[] = {
|
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
|
COMMAND_REGISTRATION_DONE
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -261,6 +261,7 @@ static inline bool is_armv8(struct armv8_common *armv8)
|
||||||
#define CPUV8_DBG_WFAR1 0x34
|
#define CPUV8_DBG_WFAR1 0x34
|
||||||
#define CPUV8_DBG_DSCR 0x088
|
#define CPUV8_DBG_DSCR 0x088
|
||||||
#define CPUV8_DBG_DRCR 0x090
|
#define CPUV8_DBG_DRCR 0x090
|
||||||
|
#define CPUV8_DBG_ECCR 0x098
|
||||||
#define CPUV8_DBG_PRCR 0x310
|
#define CPUV8_DBG_PRCR 0x310
|
||||||
#define CPUV8_DBG_PRSR 0x314
|
#define CPUV8_DBG_PRSR 0x314
|
||||||
|
|
||||||
|
|
|
@ -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_BKPT: /* SW BKPT (?) */
|
||||||
case DSCRV8_ENTRY_RESET_CATCH: /* Reset catch */
|
case DSCRV8_ENTRY_RESET_CATCH: /* Reset catch */
|
||||||
case DSCRV8_ENTRY_OS_UNLOCK: /*OS unlock 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*/
|
case DSCRV8_ENTRY_SW_ACCESS_DBG: /*SW access dbg register*/
|
||||||
target->debug_reason = DBG_REASON_BREAKPOINT;
|
target->debug_reason = DBG_REASON_BREAKPOINT;
|
||||||
break;
|
break;
|
||||||
case DSCRV8_ENTRY_WATCHPOINT: /* asynch watchpoint */
|
case DSCRV8_ENTRY_WATCHPOINT: /* asynch watchpoint */
|
||||||
target->debug_reason = DBG_REASON_WATCHPOINT;
|
target->debug_reason = DBG_REASON_WATCHPOINT;
|
||||||
break;
|
break;
|
||||||
|
case DSCRV8_ENTRY_EXCEPTION_CATCH: /*exception catch*/
|
||||||
|
target->debug_reason = DBG_REASON_EXC_CATCH;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
target->debug_reason = DBG_REASON_UNDEFINED;
|
target->debug_reason = DBG_REASON_UNDEFINED;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -251,6 +251,7 @@ static const Jim_Nvp nvp_target_debug_reason[] = {
|
||||||
{ .name = "single-step" , .value = DBG_REASON_SINGLESTEP },
|
{ .name = "single-step" , .value = DBG_REASON_SINGLESTEP },
|
||||||
{ .name = "target-not-halted" , .value = DBG_REASON_NOTHALTED },
|
{ .name = "target-not-halted" , .value = DBG_REASON_NOTHALTED },
|
||||||
{ .name = "program-exit" , .value = DBG_REASON_EXIT },
|
{ .name = "program-exit" , .value = DBG_REASON_EXIT },
|
||||||
|
{ .name = "exception-catch" , .value = DBG_REASON_EXC_CATCH },
|
||||||
{ .name = "undefined" , .value = DBG_REASON_UNDEFINED },
|
{ .name = "undefined" , .value = DBG_REASON_UNDEFINED },
|
||||||
{ .name = NULL, .value = -1 },
|
{ .name = NULL, .value = -1 },
|
||||||
};
|
};
|
||||||
|
|
|
@ -84,7 +84,8 @@ enum target_debug_reason {
|
||||||
DBG_REASON_SINGLESTEP = 4,
|
DBG_REASON_SINGLESTEP = 4,
|
||||||
DBG_REASON_NOTHALTED = 5,
|
DBG_REASON_NOTHALTED = 5,
|
||||||
DBG_REASON_EXIT = 6,
|
DBG_REASON_EXIT = 6,
|
||||||
DBG_REASON_UNDEFINED = 7,
|
DBG_REASON_EXC_CATCH = 7,
|
||||||
|
DBG_REASON_UNDEFINED = 8,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum target_endianness {
|
enum target_endianness {
|
||||||
|
|
Loading…
Reference in New Issue