]> www.infradead.org Git - users/borneoa/openocd-next.git/commitdiff
target/xtensa: add maskisr command support for NX
authorHenrik Mau <henrik.mau@analog.com>
Wed, 13 Nov 2024 15:43:23 +0000 (15:43 +0000)
committerAntonio Borneo <borneo.antonio@gmail.com>
Sat, 23 Nov 2024 13:54:44 +0000 (13:54 +0000)
Add maskisr command support to Xtensa NX targets allowing masking
of interrupts during single stepping.

Change-Id: I3835479de8015f1a2842afd1aeab24829e385031
Signed-off-by: Henrik Mau <henrik.mau@analog.com>
Reviewed-on: https://review.openocd.org/c/openocd/+/8575
Reviewed-by: Ian Thompson <ianst@cadence.com>
Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com>
Tested-by: jenkins
src/target/xtensa/xtensa.c
src/target/xtensa/xtensa.h

index 284bfc9c624ffcb97252be9333528e4f9c0fcb2f..fe1b83bc3e863822edb28d0cd5d2a48ba62db436 100644 (file)
@@ -1727,7 +1727,7 @@ int xtensa_do_step(struct target *target, int current, target_addr_t address, in
        xtensa_reg_val_t dbreakc[XT_WATCHPOINTS_NUM_MAX];
        xtensa_reg_val_t icountlvl, cause;
        xtensa_reg_val_t oldps, oldpc, cur_pc;
-       bool ps_lowered = false;
+       bool ps_modified = false;
 
        LOG_TARGET_DEBUG(target, "current=%d, address=" TARGET_ADDR_FMT ", handle_breakpoints=%i",
                current, address, handle_breakpoints);
@@ -1783,14 +1783,23 @@ int xtensa_do_step(struct target *target, int current, target_addr_t address, in
         * RFI >= DBGLEVEL.
         */
        if (xtensa->stepping_isr_mode == XT_STEPPING_ISR_OFF) {
-               if (!xtensa->core_config->high_irq.enabled) {
-                       LOG_TARGET_WARNING(
-                               target,
-                               "disabling IRQs while stepping is not implemented w/o high prio IRQs option!");
-                       return ERROR_FAIL;
+               if (xtensa->core_config->core_type == XT_LX) {
+                       if (!xtensa->core_config->high_irq.enabled) {
+                               LOG_TARGET_WARNING(target,
+                                               "disabling IRQs while stepping is not implemented w/o high prio IRQs option!");
+                               return ERROR_FAIL;
+                       }
+                       /* Update ICOUNTLEVEL accordingly */
+                       icountlvl = MIN((oldps & 0xF) + 1, xtensa->core_config->debug.irq_level);
+               } else {
+                       /* Xtensa NX does not have the ICOUNTLEVEL feature present in Xtensa LX
+                        * and instead disable interrupts while stepping. This could change
+                        * the timing of the system while under debug */
+                       xtensa_reg_val_t newps = oldps | XT_PS_DI_MSK;
+                       xtensa_reg_set(target, XT_REG_IDX_PS, newps);
+                       icountlvl = xtensa->core_config->debug.irq_level;
+                       ps_modified = true;
                }
-               /* Update ICOUNTLEVEL accordingly */
-               icountlvl = MIN((oldps & 0xF) + 1, xtensa->core_config->debug.irq_level);
        } else {
                icountlvl = xtensa->core_config->debug.irq_level;
        }
@@ -1815,7 +1824,7 @@ int xtensa_do_step(struct target *target, int current, target_addr_t address, in
                xtensa_cause_clear(target);     /* so we don't recurse into the same routine */
        if (xtensa->core_config->core_type == XT_LX && ((oldps & 0xf) >= icountlvl)) {
                /* Lower interrupt level to allow stepping, but flag eps[dbglvl] to be restored */
-               ps_lowered = true;
+               ps_modified = true;
                uint32_t newps = (oldps & ~0xf) | (icountlvl - 1);
                xtensa_reg_set(target, xtensa->eps_dbglevel_idx, newps);
                LOG_TARGET_DEBUG(target,
@@ -1916,11 +1925,12 @@ int xtensa_do_step(struct target *target, int current, target_addr_t address, in
        }
 
        /* Restore int level */
-       if (ps_lowered) {
+       if (ps_modified) {
                LOG_DEBUG("Restoring %s after stepping: 0x%08" PRIx32,
-                       xtensa->core_cache->reg_list[xtensa->eps_dbglevel_idx].name,
-                       oldps);
-               xtensa_reg_set(target, xtensa->eps_dbglevel_idx, oldps);
+                       xtensa->core_cache->reg_list[(xtensa->core_config->core_type == XT_LX) ?
+                               xtensa->eps_dbglevel_idx : XT_REG_IDX_PS].name, oldps);
+               xtensa_reg_set(target, (xtensa->core_config->core_type == XT_LX) ?
+                       xtensa->eps_dbglevel_idx : XT_REG_IDX_PS, oldps);
        }
 
        /* write ICOUNTLEVEL back to zero */
@@ -4191,11 +4201,6 @@ COMMAND_HELPER(xtensa_cmd_mask_interrupts_do, struct xtensa *xtensa)
                return ERROR_OK;
        }
 
-       if (xtensa->core_config->core_type == XT_NX) {
-               command_print(CMD, "ERROR: ISR step mode only supported on Xtensa LX");
-               return ERROR_FAIL;
-       }
-
        /* Masking is ON -> interrupts during stepping are OFF, and vice versa */
        if (!strcasecmp(CMD_ARGV[0], "off"))
                state = XT_STEPPING_ISR_ON;
index 1d56f8368233a0f502fcaf5f18d2661375676c55..419277675c84aaef039c8e9c4f654ec7a302f932 100644 (file)
@@ -45,6 +45,7 @@
 
 /* PS register bits (NX) */
 #define XT_PS_DIEXC_MSK                         BIT(2)
+#define XT_PS_DI_MSK                            BIT(3)
 
 /* MS register bits (NX) */
 #define XT_MS_DE_MSK                            BIT(5)