Cortex A/R : Allow interrupt disable during single-step
authorEvan Hunter <ehunter@broadcom.com>
Fri, 17 Jul 2015 11:41:12 +0000 (12:41 +0100)
committerFreddie Chopin <freddie.chopin@gmail.com>
Sat, 7 Nov 2015 20:36:13 +0000 (20:36 +0000)
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>
doc/openocd.texi
src/target/cortex_a.c
src/target/cortex_a.h

index eb4bd4eeefce2a571508253e0f060a8c8cb18d22..76c9766c15bd350949b429d972638d243b0f6d3b 100644 (file)
@@ -7615,6 +7615,10 @@ Initialize core debug
 Enables debug by unlocking the Software Lock and clearing sticky powerdown indications
 @end deffn
 
+@deffn Command {cortex_r maskisr} [@option{on}|@option{off}]
+Selects whether interrupts will be processed when single stepping
+@end deffn
+
 
 @subsection ARMv7-M specific commands
 @cindex tracing
index 207fb811627bd80317045233e03af1150dd8b79a..39a79ddff53bf35526a66949163ed9bbbd85d021 100644 (file)
@@ -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
 };
index ebf79b88c745fba4d244d025ca9d365e58d65431..e124a9e07ccaadb6998177d4b1f05a91ab8bd823 100644 (file)
 
 #define CORTEX_A_PADDRDBG_CPU_SHIFT 13
 
+enum cortex_a_isrmasking_mode {
+       CORTEX_A_ISRMASK_OFF,
+       CORTEX_A_ISRMASK_ON,
+};
+
 struct cortex_a_brp {
        int used;
        int type;
@@ -91,6 +96,8 @@ struct cortex_a_common {
        uint32_t ttypr;
        uint32_t didr;
 
+       enum cortex_a_isrmasking_mode isrmasking_mode;
+
        struct armv7a_common armv7a_common;
 
 };