From 53811fc584dc8837546be9ac17b77fdf8ad1e8bd Mon Sep 17 00:00:00 2001 From: ianst Date: Wed, 1 Nov 2023 16:41:43 -0700 Subject: [PATCH] target/xtensa: enable xtensa algo support - Add extra error checking - Cache PS; lower PS.INTLEVEL to allow breakpoint trigger (LX) - Xtensa algo support functional on LX per functional flash driver - Test on NX via manual algo validation Change-Id: Ie7cff4933979a0551308b382fa33c33c66376f25 Signed-off-by: ianst Reviewed-on: https://review.openocd.org/c/openocd/+/8075 Reviewed-by: Antonio Borneo Reviewed-by: Erhan Kurubas Tested-by: jenkins --- src/target/xtensa/xtensa.c | 20 +++++++++++++++++--- src/target/xtensa/xtensa.h | 3 ++- src/target/xtensa/xtensa_chip.c | 4 ++++ 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/target/xtensa/xtensa.c b/src/target/xtensa/xtensa.c index ab3bfbb097..1ec091c9f2 100644 --- a/src/target/xtensa/xtensa.c +++ b/src/target/xtensa/xtensa.c @@ -2646,6 +2646,7 @@ int xtensa_start_algorithm(struct target *target, struct xtensa_algorithm *algorithm_info = arch_info; int retval = ERROR_OK; bool usr_ps = false; + uint32_t newps; /* NOTE: xtensa_run_algorithm requires that each algorithm uses a software breakpoint * at the exit point */ @@ -2660,7 +2661,17 @@ int xtensa_start_algorithm(struct target *target, buf_cpy(reg->value, xtensa->algo_context_backup[i], reg->size); } /* save debug reason, it will be changed */ + if (!algorithm_info) { + LOG_ERROR("BUG: arch_info not specified"); + return ERROR_FAIL; + } algorithm_info->ctx_debug_reason = target->debug_reason; + if (xtensa->core_config->core_type == XT_LX) { + /* save PS and set to debug_level - 1 */ + algorithm_info->ctx_ps = xtensa_reg_get(target, xtensa->eps_dbglevel_idx); + newps = (algorithm_info->ctx_ps & ~0xf) | (xtensa->core_config->debug.irq_level - 1); + xtensa_reg_set(target, xtensa->eps_dbglevel_idx, newps); + } /* write mem params */ for (int i = 0; i < num_mem_params; i++) { if (mem_params[i].direction != PARAM_IN) { @@ -2688,7 +2699,7 @@ int xtensa_start_algorithm(struct target *target, } if (memcmp(reg_params[i].reg_name, "ps", 3)) { usr_ps = true; - } else { + } else if (xtensa->core_config->core_type == XT_LX) { unsigned int reg_id = xtensa->eps_dbglevel_idx; assert(reg_id < xtensa->core_cache->num_regs && "Attempt to access non-existing reg!"); reg = &xtensa->core_cache->reg_list[reg_id]; @@ -2697,7 +2708,7 @@ int xtensa_start_algorithm(struct target *target, reg->valid = 1; } /* ignore custom core mode if custom PS value is specified */ - if (!usr_ps) { + if (!usr_ps && xtensa->core_config->core_type == XT_LX) { unsigned int eps_reg_idx = xtensa->eps_dbglevel_idx; xtensa_reg_val_t ps = xtensa_reg_get(target, eps_reg_idx); enum xtensa_mode core_mode = XT_PS_RING_GET(ps); @@ -2741,7 +2752,8 @@ int xtensa_wait_algorithm(struct target *target, return retval; LOG_TARGET_ERROR(target, "not halted %d, pc 0x%" PRIx32 ", ps 0x%" PRIx32, retval, xtensa_reg_get(target, XT_REG_IDX_PC), - xtensa_reg_get(target, xtensa->eps_dbglevel_idx)); + xtensa_reg_get(target, (xtensa->core_config->core_type == XT_LX) ? + xtensa->eps_dbglevel_idx : XT_REG_IDX_PS)); return ERROR_TARGET_TIMEOUT; } pc = xtensa_reg_get(target, XT_REG_IDX_PC); @@ -2813,6 +2825,8 @@ int xtensa_wait_algorithm(struct target *target, } } target->debug_reason = algorithm_info->ctx_debug_reason; + if (xtensa->core_config->core_type == XT_LX) + xtensa_reg_set(target, xtensa->eps_dbglevel_idx, algorithm_info->ctx_ps); retval = xtensa_write_dirty_registers(target); if (retval != ERROR_OK) diff --git a/src/target/xtensa/xtensa.h b/src/target/xtensa/xtensa.h index 3b37122d6b..f799208f0b 100644 --- a/src/target/xtensa/xtensa.h +++ b/src/target/xtensa/xtensa.h @@ -228,8 +228,9 @@ struct xtensa_sw_breakpoint { struct xtensa_algorithm { /** User can set this to specify which core mode algorithm should be run in. */ enum xtensa_mode core_mode; - /** Used internally to backup and restore debug_reason. */ + /** Used internally to backup and restore core state. */ enum target_debug_reason ctx_debug_reason; + xtensa_reg_val_t ctx_ps; }; #define XTENSA_COMMON_MAGIC 0x54E4E555U diff --git a/src/target/xtensa/xtensa_chip.c b/src/target/xtensa/xtensa_chip.c index 668aa3acc7..ac758ed830 100644 --- a/src/target/xtensa/xtensa_chip.c +++ b/src/target/xtensa/xtensa_chip.c @@ -184,6 +184,10 @@ struct target_type xtensa_chip_target = { .get_gdb_reg_list = xtensa_get_gdb_reg_list, + .run_algorithm = xtensa_run_algorithm, + .start_algorithm = xtensa_start_algorithm, + .wait_algorithm = xtensa_wait_algorithm, + .add_breakpoint = xtensa_breakpoint_add, .remove_breakpoint = xtensa_breakpoint_remove,