target/xtensa: add maskisr command support for NX

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
This commit is contained in:
Henrik Mau 2024-11-13 15:43:23 +00:00 committed by Antonio Borneo
parent 76e228f733
commit 133dd9d669
2 changed files with 24 additions and 18 deletions

View 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 dbreakc[XT_WATCHPOINTS_NUM_MAX];
xtensa_reg_val_t icountlvl, cause; xtensa_reg_val_t icountlvl, cause;
xtensa_reg_val_t oldps, oldpc, cur_pc; 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", LOG_TARGET_DEBUG(target, "current=%d, address=" TARGET_ADDR_FMT ", handle_breakpoints=%i",
current, address, handle_breakpoints); current, address, handle_breakpoints);
@ -1783,14 +1783,23 @@ int xtensa_do_step(struct target *target, int current, target_addr_t address, in
* RFI >= DBGLEVEL. * RFI >= DBGLEVEL.
*/ */
if (xtensa->stepping_isr_mode == XT_STEPPING_ISR_OFF) { if (xtensa->stepping_isr_mode == XT_STEPPING_ISR_OFF) {
if (!xtensa->core_config->high_irq.enabled) { if (xtensa->core_config->core_type == XT_LX) {
LOG_TARGET_WARNING( if (!xtensa->core_config->high_irq.enabled) {
target, LOG_TARGET_WARNING(target,
"disabling IRQs while stepping is not implemented w/o high prio IRQs option!"); "disabling IRQs while stepping is not implemented w/o high prio IRQs option!");
return ERROR_FAIL; 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 { } else {
icountlvl = xtensa->core_config->debug.irq_level; 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 */ xtensa_cause_clear(target); /* so we don't recurse into the same routine */
if (xtensa->core_config->core_type == XT_LX && ((oldps & 0xf) >= icountlvl)) { if (xtensa->core_config->core_type == XT_LX && ((oldps & 0xf) >= icountlvl)) {
/* Lower interrupt level to allow stepping, but flag eps[dbglvl] to be restored */ /* 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); uint32_t newps = (oldps & ~0xf) | (icountlvl - 1);
xtensa_reg_set(target, xtensa->eps_dbglevel_idx, newps); xtensa_reg_set(target, xtensa->eps_dbglevel_idx, newps);
LOG_TARGET_DEBUG(target, 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 */ /* Restore int level */
if (ps_lowered) { if (ps_modified) {
LOG_DEBUG("Restoring %s after stepping: 0x%08" PRIx32, LOG_DEBUG("Restoring %s after stepping: 0x%08" PRIx32,
xtensa->core_cache->reg_list[xtensa->eps_dbglevel_idx].name, xtensa->core_cache->reg_list[(xtensa->core_config->core_type == XT_LX) ?
oldps); xtensa->eps_dbglevel_idx : XT_REG_IDX_PS].name, oldps);
xtensa_reg_set(target, xtensa->eps_dbglevel_idx, 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 */ /* write ICOUNTLEVEL back to zero */
@ -4191,11 +4201,6 @@ COMMAND_HELPER(xtensa_cmd_mask_interrupts_do, struct xtensa *xtensa)
return ERROR_OK; 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 */ /* Masking is ON -> interrupts during stepping are OFF, and vice versa */
if (!strcasecmp(CMD_ARGV[0], "off")) if (!strcasecmp(CMD_ARGV[0], "off"))
state = XT_STEPPING_ISR_ON; state = XT_STEPPING_ISR_ON;

View File

@ -45,6 +45,7 @@
/* PS register bits (NX) */ /* PS register bits (NX) */
#define XT_PS_DIEXC_MSK BIT(2) #define XT_PS_DIEXC_MSK BIT(2)
#define XT_PS_DI_MSK BIT(3)
/* MS register bits (NX) */ /* MS register bits (NX) */
#define XT_MS_DE_MSK BIT(5) #define XT_MS_DE_MSK BIT(5)