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 <ianst@cadence.com> Reviewed-on: https://review.openocd.org/c/openocd/+/8075 Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com> Reviewed-by: Erhan Kurubas <erhan.kurubas@espressif.com> Tested-by: jenkins
This commit is contained in:
parent
e680841fd2
commit
53811fc584
|
@ -2646,6 +2646,7 @@ int xtensa_start_algorithm(struct target *target,
|
||||||
struct xtensa_algorithm *algorithm_info = arch_info;
|
struct xtensa_algorithm *algorithm_info = arch_info;
|
||||||
int retval = ERROR_OK;
|
int retval = ERROR_OK;
|
||||||
bool usr_ps = false;
|
bool usr_ps = false;
|
||||||
|
uint32_t newps;
|
||||||
|
|
||||||
/* NOTE: xtensa_run_algorithm requires that each algorithm uses a software breakpoint
|
/* NOTE: xtensa_run_algorithm requires that each algorithm uses a software breakpoint
|
||||||
* at the exit point */
|
* 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);
|
buf_cpy(reg->value, xtensa->algo_context_backup[i], reg->size);
|
||||||
}
|
}
|
||||||
/* save debug reason, it will be changed */
|
/* 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;
|
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 */
|
/* write mem params */
|
||||||
for (int i = 0; i < num_mem_params; i++) {
|
for (int i = 0; i < num_mem_params; i++) {
|
||||||
if (mem_params[i].direction != PARAM_IN) {
|
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)) {
|
if (memcmp(reg_params[i].reg_name, "ps", 3)) {
|
||||||
usr_ps = true;
|
usr_ps = true;
|
||||||
} else {
|
} else if (xtensa->core_config->core_type == XT_LX) {
|
||||||
unsigned int reg_id = xtensa->eps_dbglevel_idx;
|
unsigned int reg_id = xtensa->eps_dbglevel_idx;
|
||||||
assert(reg_id < xtensa->core_cache->num_regs && "Attempt to access non-existing reg!");
|
assert(reg_id < xtensa->core_cache->num_regs && "Attempt to access non-existing reg!");
|
||||||
reg = &xtensa->core_cache->reg_list[reg_id];
|
reg = &xtensa->core_cache->reg_list[reg_id];
|
||||||
|
@ -2697,7 +2708,7 @@ int xtensa_start_algorithm(struct target *target,
|
||||||
reg->valid = 1;
|
reg->valid = 1;
|
||||||
}
|
}
|
||||||
/* ignore custom core mode if custom PS value is specified */
|
/* 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;
|
unsigned int eps_reg_idx = xtensa->eps_dbglevel_idx;
|
||||||
xtensa_reg_val_t ps = xtensa_reg_get(target, eps_reg_idx);
|
xtensa_reg_val_t ps = xtensa_reg_get(target, eps_reg_idx);
|
||||||
enum xtensa_mode core_mode = XT_PS_RING_GET(ps);
|
enum xtensa_mode core_mode = XT_PS_RING_GET(ps);
|
||||||
|
@ -2741,7 +2752,8 @@ int xtensa_wait_algorithm(struct target *target,
|
||||||
return retval;
|
return retval;
|
||||||
LOG_TARGET_ERROR(target, "not halted %d, pc 0x%" PRIx32 ", ps 0x%" PRIx32, 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, 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;
|
return ERROR_TARGET_TIMEOUT;
|
||||||
}
|
}
|
||||||
pc = xtensa_reg_get(target, XT_REG_IDX_PC);
|
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;
|
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);
|
retval = xtensa_write_dirty_registers(target);
|
||||||
if (retval != ERROR_OK)
|
if (retval != ERROR_OK)
|
||||||
|
|
|
@ -228,8 +228,9 @@ struct xtensa_sw_breakpoint {
|
||||||
struct xtensa_algorithm {
|
struct xtensa_algorithm {
|
||||||
/** User can set this to specify which core mode algorithm should be run in. */
|
/** User can set this to specify which core mode algorithm should be run in. */
|
||||||
enum xtensa_mode core_mode;
|
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;
|
enum target_debug_reason ctx_debug_reason;
|
||||||
|
xtensa_reg_val_t ctx_ps;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define XTENSA_COMMON_MAGIC 0x54E4E555U
|
#define XTENSA_COMMON_MAGIC 0x54E4E555U
|
||||||
|
|
|
@ -184,6 +184,10 @@ struct target_type xtensa_chip_target = {
|
||||||
|
|
||||||
.get_gdb_reg_list = xtensa_get_gdb_reg_list,
|
.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,
|
.add_breakpoint = xtensa_breakpoint_add,
|
||||||
.remove_breakpoint = xtensa_breakpoint_remove,
|
.remove_breakpoint = xtensa_breakpoint_remove,
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue