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 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;

View 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)