diff options
author | Evan Hunter <ehunter@broadcom.com> | 2015-07-17 12:41:12 +0100 |
---|---|---|
committer | Freddie Chopin <freddie.chopin@gmail.com> | 2015-11-07 20:36:13 +0000 |
commit | 987201c6dc4329c79057d6057a451e8e2c3568dc (patch) | |
tree | 6e2516cbdc27cdfcf3eff41051996379a7e3a315 /src/target/cortex_a.c | |
parent | 7ae5b45f75f0becea3bc8e165ddd19a84674fbed (diff) |
Cortex A/R : Allow interrupt disable during single-step
Example usage:
cortex_a maskisr on
cortex_a maskisr off
cortex_r maskisr on
cortex_r maskisr off
Change-Id: I799288d9b848a06f561ba29ec1eb8e5eeace5685
Signed-off-by: Evan Hunter <ehunter@broadcom.com>
Reviewed-on: http://openocd.zylin.com/2876
Tested-by: jenkins
Reviewed-by: Matthias Welwarsky <matthias@welwarsky.de>
Reviewed-by: Freddie Chopin <freddie.chopin@gmail.com>
Diffstat (limited to 'src/target/cortex_a.c')
-rw-r--r-- | src/target/cortex_a.c | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/src/target/cortex_a.c b/src/target/cortex_a.c index 207fb811..39a79ddf 100644 --- a/src/target/cortex_a.c +++ b/src/target/cortex_a.c @@ -1323,9 +1323,33 @@ static int cortex_a_post_debug_entry(struct target *target) return ERROR_OK; } +int cortex_a_set_dscr_bits(struct target *target, unsigned long bit_mask, unsigned long value) +{ + struct armv7a_common *armv7a = target_to_armv7a(target); + struct adiv5_dap *swjdp = armv7a->arm.dap; + uint32_t dscr; + + /* Read DSCR */ + int retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap, + armv7a->debug_base + CPUDBG_DSCR, &dscr); + if (ERROR_OK != retval) + return retval; + + /* clear bitfield */ + dscr &= ~bit_mask; + /* put new value */ + dscr |= value & bit_mask; + + /* write new DSCR */ + retval = mem_ap_sel_write_atomic_u32(swjdp, armv7a->debug_ap, + armv7a->debug_base + CPUDBG_DSCR, dscr); + return retval; +} + static int cortex_a_step(struct target *target, int current, uint32_t address, int handle_breakpoints) { + struct cortex_a_common *cortex_a = target_to_cortex_a(target); struct armv7a_common *armv7a = target_to_armv7a(target); struct arm *arm = &armv7a->arm; struct breakpoint *breakpoint = NULL; @@ -1363,6 +1387,13 @@ static int cortex_a_step(struct target *target, int current, uint32_t address, stepbreakpoint.type = BKPT_HARD; stepbreakpoint.set = 0; + /* Disable interrupts during single step if requested */ + if (cortex_a->isrmasking_mode == CORTEX_A_ISRMASK_ON) { + retval = cortex_a_set_dscr_bits(target, DSCR_INT_DIS, DSCR_INT_DIS); + if (ERROR_OK != retval) + return retval; + } + /* Break on IVA mismatch */ cortex_a_set_breakpoint(target, &stepbreakpoint, 0x04); @@ -1385,6 +1416,14 @@ static int cortex_a_step(struct target *target, int current, uint32_t address, cortex_a_unset_breakpoint(target, &stepbreakpoint); + /* Re-enable interrupts if they were disabled */ + if (cortex_a->isrmasking_mode == CORTEX_A_ISRMASK_ON) { + retval = cortex_a_set_dscr_bits(target, DSCR_INT_DIS, 0); + if (ERROR_OK != retval) + return retval; + } + + target->debug_reason = DBG_REASON_BREAKPOINT; if (breakpoint) @@ -3193,6 +3232,37 @@ COMMAND_HANDLER(cortex_a_handle_smp_gdb_command) return ERROR_OK; } +COMMAND_HANDLER(handle_cortex_a_mask_interrupts_command) +{ + struct target *target = get_current_target(CMD_CTX); + struct cortex_a_common *cortex_a = target_to_cortex_a(target); + + static const Jim_Nvp nvp_maskisr_modes[] = { + { .name = "off", .value = CORTEX_A_ISRMASK_OFF }, + { .name = "on", .value = CORTEX_A_ISRMASK_ON }, + { .name = NULL, .value = -1 }, + }; + const Jim_Nvp *n; + + if (target->state != TARGET_HALTED) { + command_print(CMD_CTX, "target must be stopped for \"%s\" command", CMD_NAME); + return ERROR_OK; + } + + if (CMD_ARGC > 0) { + n = Jim_Nvp_name2value_simple(nvp_maskisr_modes, CMD_ARGV[0]); + if (n->name == NULL) + return ERROR_COMMAND_SYNTAX_ERROR; + cortex_a->isrmasking_mode = n->value; + + } + + n = Jim_Nvp_value2name_simple(nvp_maskisr_modes, cortex_a->isrmasking_mode); + command_print(CMD_CTX, "cortex_a interrupt mask %s", n->name); + + return ERROR_OK; +} + static const struct command_registration cortex_a_exec_command_handlers[] = { { .name = "cache_info", @@ -3227,6 +3297,13 @@ static const struct command_registration cortex_a_exec_command_handlers[] = { .help = "display/fix current core played to gdb", .usage = "", }, + { + .name = "maskisr", + .handler = handle_cortex_a_mask_interrupts_command, + .mode = COMMAND_EXEC, + .help = "mask cortex_a interrupts", + .usage = "['on'|'off']", + }, COMMAND_REGISTRATION_DONE @@ -3306,6 +3383,13 @@ static const struct command_registration cortex_r4_exec_command_handlers[] = { .help = "Initialize core debug", .usage = "", }, + { + .name = "maskisr", + .handler = handle_cortex_a_mask_interrupts_command, + .mode = COMMAND_EXEC, + .help = "mask cortex_r4 interrupts", + .usage = "['on'|'off']", + }, COMMAND_REGISTRATION_DONE }; |