Use indirect enum IDs to access XDM registers in preparation for supporting both NAR (JTAG) and APB (DAP). No new clang static analysis warnings.
Signed-off-by: Ian Thompson <ianst@cadence.com>
Change-Id: I0b742fe4661ff3cf609454b8650493d141a1e1ff
Reviewed-on: https://review.openocd.org/c/openocd/+/7143
Tested-by: jenkins
Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com>
static void xtensa_queue_exec_ins(struct xtensa *xtensa, uint32_t ins)
{
- xtensa_queue_dbg_reg_write(xtensa, NARADR_DIR0EXEC, ins);
+ xtensa_queue_dbg_reg_write(xtensa, XDMREG_DIR0EXEC, ins);
}
static void xtensa_queue_exec_ins_wide(struct xtensa *xtensa, uint8_t *ops, uint8_t oplen)
else
memcpy(opsw, ops, oplen);
for (int32_t i = oplenw - 1; i > 0; i--)
- xtensa_queue_dbg_reg_write(xtensa, NARADR_DIR0 + i, opsw[i]);
+ xtensa_queue_dbg_reg_write(xtensa, XDMREG_DIR0 + i, opsw[i]);
/* Write DIR0EXEC last */
- xtensa_queue_dbg_reg_write(xtensa, NARADR_DIR0EXEC, opsw[0]);
+ xtensa_queue_dbg_reg_write(xtensa, XDMREG_DIR0EXEC, opsw[0]);
}
}
/* Save PS (LX) and disable window overflow exceptions prior to AR save */
xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_PS, XT_REG_A3));
xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, XT_SR_DDR, XT_REG_A3));
- xtensa_queue_dbg_reg_read(xtensa, NARADR_DDR, woe_buf);
- int res = jtag_execute_queue();
+ xtensa_queue_dbg_reg_read(xtensa, XDMREG_DDR, woe_buf);
+ int res = xtensa_dm_queue_execute(&xtensa->dbg_mod);
if (res != ERROR_OK) {
LOG_ERROR("Failed to read PS (%d)!", res);
return res;
*woe = buf_get_u32(woe_buf, 0, 32);
woe_dis = *woe & ~XT_PS_WOE_MSK;
LOG_DEBUG("Clearing PS.WOE (0x%08" PRIx32 " -> 0x%08" PRIx32 ")", *woe, woe_dis);
- xtensa_queue_dbg_reg_write(xtensa, NARADR_DDR, woe_dis);
+ xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, woe_dis);
xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));
xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, XT_SR_PS, XT_REG_A3));
}
struct xtensa *xtensa = target_to_xtensa(target);
if (xtensa->core_config->windowed) {
/* Restore window overflow exception state */
- xtensa_queue_dbg_reg_write(xtensa, NARADR_DDR, woe);
+ xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, woe);
xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));
xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, XT_SR_PS, XT_REG_A3));
LOG_DEBUG("Restored PS.WOE (0x%08" PRIx32 ")", woe);
reg_list[i].name,
rlist[ridx].reg_num,
regval);
- xtensa_queue_dbg_reg_write(xtensa, NARADR_DDR, regval);
+ xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, regval);
xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));
if (reg_list[i].exist) {
unsigned int reg_num = rlist[ridx].reg_num;
if (delay_cpenable) {
regval = xtensa_reg_get(target, XT_REG_IDX_CPENABLE);
LOG_TARGET_DEBUG(target, "Writing back reg cpenable (224) val %08" PRIX32, regval);
- xtensa_queue_dbg_reg_write(xtensa, NARADR_DDR, regval);
+ xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, regval);
xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));
xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa,
xtensa_regs[XT_REG_IDX_CPENABLE].reg_num,
if (preserve_a3) {
/* Save (windowed) A3 for scratch use */
xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, XT_SR_DDR, XT_REG_A3));
- xtensa_queue_dbg_reg_read(xtensa, NARADR_DDR, a3_buf);
- res = jtag_execute_queue();
+ xtensa_queue_dbg_reg_read(xtensa, XDMREG_DDR, a3_buf);
+ res = xtensa_dm_queue_execute(&xtensa->dbg_mod);
if (res != ERROR_OK)
return res;
xtensa_core_status_check(target);
xtensa_regs[XT_REG_IDX_A0 + i].name,
regval,
xtensa_regs[XT_REG_IDX_A0 + i].reg_num);
- xtensa_queue_dbg_reg_write(xtensa, NARADR_DDR, regval);
+ xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, regval);
xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, i));
reg_list[XT_REG_IDX_A0 + i].dirty = false;
if (i == 3) {
xtensa_regs[realadr].name,
regval,
xtensa_regs[realadr].reg_num);
- xtensa_queue_dbg_reg_write(xtensa, NARADR_DDR, regval);
+ xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, regval);
xtensa_queue_exec_ins(xtensa,
XT_INS_RSR(xtensa, XT_SR_DDR,
xtensa_regs[XT_REG_IDX_AR0 + i].reg_num));
}
if (preserve_a3) {
- xtensa_queue_dbg_reg_write(xtensa, NARADR_DDR, a3);
+ xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, a3);
xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));
}
- res = jtag_execute_queue();
+ res = xtensa_dm_queue_execute(&xtensa->dbg_mod);
xtensa_core_status_check(target);
return res;
return ERROR_FAIL;
}
- xtensa_queue_pwr_reg_write(xtensa, DMREG_PWRCTL, cmd);
- xtensa_queue_pwr_reg_write(xtensa, DMREG_PWRCTL, cmd | PWRCTL_JTAGDEBUGUSE);
+ xtensa_queue_pwr_reg_write(xtensa, XDMREG_PWRCTL, cmd);
+ xtensa_queue_pwr_reg_write(xtensa, XDMREG_PWRCTL, cmd | PWRCTL_JTAGDEBUGUSE);
xtensa_dm_queue_enable(&xtensa->dbg_mod);
xtensa_dm_queue_tdi_idle(&xtensa->dbg_mod);
- int res = jtag_execute_queue();
+ int res = xtensa_dm_queue_execute(&xtensa->dbg_mod);
if (res != ERROR_OK)
return res;
if (!xtensa_dm_is_online(&xtensa->dbg_mod)) {
if (xtensa->reset_asserted)
cmd |= PWRCTL_CORERESET;
- xtensa_queue_pwr_reg_write(xtensa, DMREG_PWRCTL, cmd);
+ xtensa_queue_pwr_reg_write(xtensa, XDMREG_PWRCTL, cmd);
/* TODO: can we join this with the write above? */
- xtensa_queue_pwr_reg_write(xtensa, DMREG_PWRCTL, cmd | PWRCTL_JTAGDEBUGUSE);
+ xtensa_queue_pwr_reg_write(xtensa, XDMREG_PWRCTL, cmd | PWRCTL_JTAGDEBUGUSE);
xtensa_dm_queue_tdi_idle(&xtensa->dbg_mod);
- return jtag_execute_queue();
+ return xtensa_dm_queue_execute(&xtensa->dbg_mod);
}
int xtensa_smpbreak_write(struct xtensa *xtensa, uint32_t set)
OCDDCR_DEBUGMODEOUTEN | OCDDCR_ENABLEOCD);
LOG_TARGET_DEBUG(xtensa->target, "write smpbreak set=0x%" PRIx32 " clear=0x%" PRIx32, set, clear);
- xtensa_queue_dbg_reg_write(xtensa, NARADR_DCRSET, set | OCDDCR_ENABLEOCD);
- xtensa_queue_dbg_reg_write(xtensa, NARADR_DCRCLR, clear);
- xtensa_queue_dbg_reg_write(xtensa, NARADR_DSR, dsr_data);
+ xtensa_queue_dbg_reg_write(xtensa, XDMREG_DCRSET, set | OCDDCR_ENABLEOCD);
+ xtensa_queue_dbg_reg_write(xtensa, XDMREG_DCRCLR, clear);
+ xtensa_queue_dbg_reg_write(xtensa, XDMREG_DSR, dsr_data);
xtensa_dm_queue_tdi_idle(&xtensa->dbg_mod);
- return jtag_execute_queue();
+ return xtensa_dm_queue_execute(&xtensa->dbg_mod);
}
int xtensa_smpbreak_set(struct target *target, uint32_t set)
{
uint8_t dcr_buf[sizeof(uint32_t)];
- xtensa_queue_dbg_reg_read(xtensa, NARADR_DCRSET, dcr_buf);
+ xtensa_queue_dbg_reg_read(xtensa, XDMREG_DCRSET, dcr_buf);
xtensa_dm_queue_tdi_idle(&xtensa->dbg_mod);
- int res = jtag_execute_queue();
+ int res = xtensa_dm_queue_execute(&xtensa->dbg_mod);
*val = buf_get_u32(dcr_buf, 0, 32);
return res;
LOG_TARGET_DEBUG(target, "target_number=%i, begin", target->target_number);
target->state = TARGET_RESET;
xtensa_queue_pwr_reg_write(xtensa,
- DMREG_PWRCTL,
- PWRCTL_JTAGDEBUGUSE | PWRCTL_DEBUGWAKEUP | PWRCTL_MEMWAKEUP | PWRCTL_COREWAKEUP |
- PWRCTL_CORERESET);
+ XDMREG_PWRCTL,
+ PWRCTL_JTAGDEBUGUSE | PWRCTL_DEBUGWAKEUP | PWRCTL_MEMWAKEUP |
+ PWRCTL_COREWAKEUP | PWRCTL_CORERESET);
xtensa_dm_queue_tdi_idle(&xtensa->dbg_mod);
- int res = jtag_execute_queue();
+ int res = xtensa_dm_queue_execute(&xtensa->dbg_mod);
if (res != ERROR_OK)
return res;
xtensa->reset_asserted = true;
LOG_TARGET_DEBUG(target, "halt=%d", target->reset_halt);
if (target->reset_halt)
xtensa_queue_dbg_reg_write(xtensa,
- NARADR_DCRSET,
+ XDMREG_DCRSET,
OCDDCR_ENABLEOCD | OCDDCR_DEBUGINTERRUPT);
xtensa_queue_pwr_reg_write(xtensa,
- DMREG_PWRCTL,
- PWRCTL_JTAGDEBUGUSE | PWRCTL_DEBUGWAKEUP | PWRCTL_MEMWAKEUP | PWRCTL_COREWAKEUP);
+ XDMREG_PWRCTL,
+ PWRCTL_JTAGDEBUGUSE | PWRCTL_DEBUGWAKEUP | PWRCTL_MEMWAKEUP |
+ PWRCTL_COREWAKEUP);
xtensa_dm_queue_tdi_idle(&xtensa->dbg_mod);
- int res = jtag_execute_queue();
+ int res = xtensa_dm_queue_execute(&xtensa->dbg_mod);
if (res != ERROR_OK)
return res;
target->state = TARGET_RUNNING;
/* Save (windowed) A3 so cache matches physical AR3; A3 usable as scratch */
xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, XT_SR_DDR, XT_REG_A3));
- xtensa_queue_dbg_reg_read(xtensa, NARADR_DDR, a3_buf);
+ xtensa_queue_dbg_reg_read(xtensa, XDMREG_DDR, a3_buf);
int res = xtensa_window_state_save(target, &woe);
if (res != ERROR_OK)
goto xtensa_fetch_all_regs_done;
if (i + j < xtensa->core_config->aregs_num) {
xtensa_queue_exec_ins(xtensa,
XT_INS_WSR(xtensa, XT_SR_DDR, xtensa_regs[XT_REG_IDX_AR0 + i].reg_num));
- xtensa_queue_dbg_reg_read(xtensa, NARADR_DDR,
+ xtensa_queue_dbg_reg_read(xtensa, XDMREG_DDR,
regvals[XT_REG_IDX_AR0 + i + j].buf);
if (debug_dsrs)
- xtensa_queue_dbg_reg_read(xtensa, NARADR_DSR,
+ xtensa_queue_dbg_reg_read(xtensa, XDMREG_DSR,
dsrs[XT_REG_IDX_AR0 + i + j].buf);
}
}
/* As the very first thing after AREGS, go grab CPENABLE */
xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, xtensa_regs[XT_REG_IDX_CPENABLE].reg_num, XT_REG_A3));
xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, XT_SR_DDR, XT_REG_A3));
- xtensa_queue_dbg_reg_read(xtensa, NARADR_DDR, regvals[XT_REG_IDX_CPENABLE].buf);
+ xtensa_queue_dbg_reg_read(xtensa, XDMREG_DDR, regvals[XT_REG_IDX_CPENABLE].buf);
}
- res = jtag_execute_queue();
+ res = xtensa_dm_queue_execute(&xtensa->dbg_mod);
if (res != ERROR_OK) {
LOG_ERROR("Failed to read ARs (%d)!", res);
goto xtensa_fetch_all_regs_done;
cpenable = buf_get_u32(regvals[XT_REG_IDX_CPENABLE].buf, 0, 32);
/* Enable all coprocessors (by setting all bits in CPENABLE) so we can read FP and user registers. */
- xtensa_queue_dbg_reg_write(xtensa, NARADR_DDR, 0xffffffff);
+ xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, 0xffffffff);
xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));
xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, xtensa_regs[XT_REG_IDX_CPENABLE].reg_num, XT_REG_A3));
}
if (reg_fetched) {
xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, XT_SR_DDR, XT_REG_A3));
- xtensa_queue_dbg_reg_read(xtensa, NARADR_DDR, regvals[i].buf);
+ xtensa_queue_dbg_reg_read(xtensa, XDMREG_DDR, regvals[i].buf);
if (debug_dsrs)
- xtensa_queue_dbg_reg_read(xtensa, NARADR_DSR, dsrs[i].buf);
+ xtensa_queue_dbg_reg_read(xtensa, XDMREG_DSR, dsrs[i].buf);
}
}
}
/* Ok, send the whole mess to the CPU. */
- res = jtag_execute_queue();
+ res = xtensa_dm_queue_execute(&xtensa->dbg_mod);
if (res != ERROR_OK) {
LOG_ERROR("Failed to fetch AR regs!");
goto xtensa_fetch_all_regs_done;
}
LOG_TARGET_DEBUG(target, "Core status 0x%" PRIx32, xtensa_dm_core_status_get(&xtensa->dbg_mod));
if (!xtensa_is_stopped(target)) {
- xtensa_queue_dbg_reg_write(xtensa, NARADR_DCRSET, OCDDCR_ENABLEOCD | OCDDCR_DEBUGINTERRUPT);
+ xtensa_queue_dbg_reg_write(xtensa, XDMREG_DCRSET, OCDDCR_ENABLEOCD | OCDDCR_DEBUGINTERRUPT);
xtensa_dm_queue_tdi_idle(&xtensa->dbg_mod);
- res = jtag_execute_queue();
+ res = xtensa_dm_queue_execute(&xtensa->dbg_mod);
if (res != ERROR_OK)
LOG_TARGET_ERROR(target, "Failed to set OCDDCR_DEBUGINTERRUPT. Can't halt.");
}
LOG_TARGET_DEBUG(target, "start");
xtensa_queue_exec_ins(xtensa, XT_INS_RFDO(xtensa));
- int res = jtag_execute_queue();
+ int res = xtensa_dm_queue_execute(&xtensa->dbg_mod);
if (res != ERROR_OK) {
LOG_TARGET_ERROR(target, "Failed to exec RFDO %d!", res);
return res;
/* We're going to use A3 here */
xtensa_mark_register_dirty(xtensa, XT_REG_IDX_A3);
/* Write start address to A3 */
- xtensa_queue_dbg_reg_write(xtensa, NARADR_DDR, addrstart_al);
+ xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, addrstart_al);
xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));
/* Now we can safely read data from addrstart_al up to addrend_al into albuff */
if (xtensa->probe_lsddr32p != 0) {
xtensa_queue_exec_ins(xtensa, XT_INS_LDDR32P(xtensa, XT_REG_A3));
for (unsigned int i = 0; adr != addrend_al; i += sizeof(uint32_t), adr += sizeof(uint32_t))
xtensa_queue_dbg_reg_read(xtensa,
- (adr + sizeof(uint32_t) == addrend_al) ? NARADR_DDR : NARADR_DDREXEC,
+ (adr + sizeof(uint32_t) == addrend_al) ? XDMREG_DDR : XDMREG_DDREXEC,
&albuff[i]);
} else {
xtensa_mark_register_dirty(xtensa, XT_REG_IDX_A4);
for (unsigned int i = 0; adr != addrend_al; i += sizeof(uint32_t), adr += sizeof(uint32_t)) {
xtensa_queue_exec_ins(xtensa, XT_INS_L32I(xtensa, XT_REG_A3, XT_REG_A4, 0));
xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, XT_SR_DDR, XT_REG_A4));
- xtensa_queue_dbg_reg_read(xtensa, NARADR_DDR, &albuff[i]);
- xtensa_queue_dbg_reg_write(xtensa, NARADR_DDR, adr + sizeof(uint32_t));
+ xtensa_queue_dbg_reg_read(xtensa, XDMREG_DDR, &albuff[i]);
+ xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, adr + sizeof(uint32_t));
xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));
}
}
- int res = jtag_execute_queue();
+ int res = xtensa_dm_queue_execute(&xtensa->dbg_mod);
if (res == ERROR_OK) {
bool prev_suppress = xtensa->suppress_dsr_errors;
xtensa->suppress_dsr_errors = true;
if (fill_head_tail) {
/* See if we need to read the first and/or last word. */
if (address & 3) {
- xtensa_queue_dbg_reg_write(xtensa, NARADR_DDR, addrstart_al);
+ xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, addrstart_al);
xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));
if (xtensa->probe_lsddr32p == 1) {
xtensa_queue_exec_ins(xtensa, XT_INS_LDDR32P(xtensa, XT_REG_A3));
xtensa_queue_exec_ins(xtensa, XT_INS_L32I(xtensa, XT_REG_A3, XT_REG_A3, 0));
xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, XT_SR_DDR, XT_REG_A3));
}
- xtensa_queue_dbg_reg_read(xtensa, NARADR_DDR, &albuff[0]);
+ xtensa_queue_dbg_reg_read(xtensa, XDMREG_DDR, &albuff[0]);
}
if ((address + (size * count)) & 3) {
- xtensa_queue_dbg_reg_write(xtensa, NARADR_DDR, addrend_al - 4);
+ xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, addrend_al - 4);
xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));
if (xtensa->probe_lsddr32p == 1) {
xtensa_queue_exec_ins(xtensa, XT_INS_LDDR32P(xtensa, XT_REG_A3));
xtensa_queue_exec_ins(xtensa, XT_INS_L32I(xtensa, XT_REG_A3, XT_REG_A3, 0));
xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, XT_SR_DDR, XT_REG_A3));
}
- xtensa_queue_dbg_reg_read(xtensa, NARADR_DDR,
+ xtensa_queue_dbg_reg_read(xtensa, XDMREG_DDR,
&albuff[addrend_al - addrstart_al - 4]);
}
/* Grab bytes */
- res = jtag_execute_queue();
+ res = xtensa_dm_queue_execute(&xtensa->dbg_mod);
if (res != ERROR_OK) {
LOG_ERROR("Error issuing unaligned memory write context instruction(s): %d", res);
if (albuff != buffer)
buf_bswap32(albuff, fill_head_tail ? albuff : buffer, addrend_al - addrstart_al);
/* Write start address to A3 */
- xtensa_queue_dbg_reg_write(xtensa, NARADR_DDR, addrstart_al);
+ xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, addrstart_al);
xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));
/* Write the aligned buffer */
if (xtensa->probe_lsddr32p != 0) {
for (unsigned int i = 0; adr != addrend_al; i += sizeof(uint32_t), adr += sizeof(uint32_t)) {
if (i == 0) {
- xtensa_queue_dbg_reg_write(xtensa, NARADR_DDR, buf_get_u32(&albuff[i], 0, 32));
+ xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, buf_get_u32(&albuff[i], 0, 32));
xtensa_queue_exec_ins(xtensa, XT_INS_SDDR32P(xtensa, XT_REG_A3));
} else {
- xtensa_queue_dbg_reg_write(xtensa, NARADR_DDREXEC, buf_get_u32(&albuff[i], 0, 32));
+ xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDREXEC, buf_get_u32(&albuff[i], 0, 32));
}
}
} else {
xtensa_mark_register_dirty(xtensa, XT_REG_IDX_A4);
for (unsigned int i = 0; adr != addrend_al; i += sizeof(uint32_t), adr += sizeof(uint32_t)) {
- xtensa_queue_dbg_reg_write(xtensa, NARADR_DDR, buf_get_u32(&albuff[i], 0, 32));
+ xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, buf_get_u32(&albuff[i], 0, 32));
xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A4));
xtensa_queue_exec_ins(xtensa, XT_INS_S32I(xtensa, XT_REG_A3, XT_REG_A4, 0));
- xtensa_queue_dbg_reg_write(xtensa, NARADR_DDR, adr + sizeof(uint32_t));
+ xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, adr + sizeof(uint32_t));
xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));
}
}
- res = jtag_execute_queue();
+ res = xtensa_dm_queue_execute(&xtensa->dbg_mod);
if (res == ERROR_OK) {
bool prev_suppress = xtensa->suppress_dsr_errors;
xtensa->suppress_dsr_errors = true;
while ((adr + off) < addrend_al) {
if (off == 0) {
/* Write start address to A3 */
- xtensa_queue_dbg_reg_write(xtensa, NARADR_DDR, adr);
+ xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, adr);
xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));
}
if (issue_ihi)
}
/* Execute cache WB/INV instructions */
- res = jtag_execute_queue();
+ res = xtensa_dm_queue_execute(&xtensa->dbg_mod);
xtensa_core_status_check(target);
if (res != ERROR_OK)
LOG_TARGET_ERROR(target,
{
struct xtensa *xtensa = target_to_xtensa(target);
- int res = xtensa_dm_power_status_read(&xtensa->dbg_mod, PWRSTAT_DEBUGWASRESET | PWRSTAT_COREWASRESET);
+ int res = xtensa_dm_power_status_read(&xtensa->dbg_mod, PWRSTAT_DEBUGWASRESET |
+ PWRSTAT_COREWASRESET);
if (xtensa->dbg_mod.power_status.stat != xtensa->dbg_mod.power_status.stath)
LOG_TARGET_DEBUG(target, "PWRSTAT: read 0x%08" PRIx32 ", clear 0x%08lx, reread 0x%08" PRIx32,
xtensa->dbg_mod.power_status.stat,
xtensa_mark_register_dirty(xtensa, XT_REG_IDX_A3);
/* Write start address to A3 and invalidate */
- xtensa_queue_dbg_reg_write(xtensa, NARADR_DDR, address);
+ xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, address);
xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));
LOG_TARGET_DEBUG(target, "DHWBI, IHI for address "TARGET_ADDR_FMT, address);
if (issue_dhwbi) {
}
/* Execute invalidate instructions */
- ret = jtag_execute_queue();
+ ret = xtensa_dm_queue_execute(&xtensa->dbg_mod);
xtensa_core_status_check(target);
if (ret != ERROR_OK) {
LOG_ERROR("Error issuing cache invaldate instruction(s): %d", ret);
if (issue_dhwbi) {
/* Flush dcache so instruction propagates. A3 may be corrupted during memory write */
- xtensa_queue_dbg_reg_write(xtensa, NARADR_DDR, address);
+ xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, address);
xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));
xtensa_queue_exec_ins(xtensa, XT_INS_DHWB(xtensa, XT_REG_A3, 0));
LOG_DEBUG("DHWB dcache line for address "TARGET_ADDR_FMT, address);
}
/* Execute invalidate instructions */
- ret = jtag_execute_queue();
+ ret = xtensa_dm_queue_execute(&xtensa->dbg_mod);
xtensa_core_status_check(target);
}
}
}
xtensa_reg_val_t orig_a4 = xtensa_reg_get(target, XT_REG_IDX_A4);
- xtensa_queue_dbg_reg_write(xtensa, NARADR_DDR, xtensa->spill_loc);
+ xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, xtensa->spill_loc);
xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A4));
int32_t tieop_status = xtensa_gdbqc_parse_exec_tie_ops(target, delim);
/* Restore a4 but not yet spill memory. Execute it all... */
- xtensa_queue_dbg_reg_write(xtensa, NARADR_DDR, orig_a4);
+ xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, orig_a4);
xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A4));
- status = jtag_execute_queue();
+ status = xtensa_dm_queue_execute(&xtensa->dbg_mod);
if (status != ERROR_OK) {
LOG_TARGET_ERROR(target, "TIE queue execute: %d\n", status);
tieop_status = status;
LOG_DEBUG("start");
if (target_was_examined(target)) {
- int ret = xtensa_queue_dbg_reg_write(xtensa, NARADR_DCRCLR, OCDDCR_ENABLEOCD);
+ int ret = xtensa_queue_dbg_reg_write(xtensa, XDMREG_DCRCLR, OCDDCR_ENABLEOCD);
if (ret != ERROR_OK) {
LOG_ERROR("Failed to queue OCDDCR_ENABLEOCD clear operation!");
return;
}
xtensa_dm_queue_tdi_idle(&xtensa->dbg_mod);
- ret = jtag_execute_queue();
+ ret = xtensa_dm_queue_execute(&xtensa->dbg_mod);
if (ret != ERROR_OK) {
LOG_ERROR("Failed to clear OCDDCR_ENABLEOCD!");
return;
xtensa_reg_val_t exccause = xtensa_reg_get(target, XT_REG_IDX_EXCCAUSE);
xtensa_reg_val_t cpenable = xtensa_reg_get(target, XT_REG_IDX_CPENABLE);
xtensa_reg_val_t a3 = xtensa_reg_get(target, XT_REG_IDX_A3);
- xtensa_queue_dbg_reg_write(xtensa, NARADR_DDR, 0xffffffff);
+ xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, 0xffffffff);
xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));
xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa,
xtensa_regs[XT_REG_IDX_CPENABLE].reg_num, XT_REG_A3));
- xtensa_queue_dbg_reg_write(xtensa, NARADR_DDR, a3);
+ xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, a3);
xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));
/* Queue instruction list and execute everything */
LOG_TARGET_DEBUG(target, "execute stub: %s", CMD_ARGV[0]);
xtensa_queue_exec_ins_wide(xtensa, ops, oplen); /* Handles endian-swap */
- status = jtag_execute_queue();
+ status = xtensa_dm_queue_execute(&xtensa->dbg_mod);
if (status != ERROR_OK)
LOG_TARGET_ERROR(target, "TIE queue execute: %d\n", status);
status = xtensa_core_status_check(target);
return ERROR_FAIL;
}
return ERROR_OK;
- } else if (CMD_ARGC != 2)
+ } else if (CMD_ARGC != 2) {
return ERROR_COMMAND_SYNTAX_ERROR;
+ }
/* "xtregfmt contiguous" must be specified prior to the first "xtreg" definition
* if general register (g-packet) requests or contiguous register maps are supported */
unsigned int numgregs = strtoul(CMD_ARGV[1], NULL, 0);
if ((numgregs <= 0) ||
((numgregs > xtensa->total_regs_num) &&
- (xtensa->total_regs_num > 0))) {
+ (xtensa->total_regs_num > 0))) {
LOG_ERROR("xtregfmt: if specified, numgregs (%d) must be <= numregs (%d)",
numgregs, xtensa->total_regs_num);
return ERROR_COMMAND_SYNTAX_ERROR;
return false;
}
-static inline int xtensa_queue_dbg_reg_read(struct xtensa *xtensa, unsigned int reg, uint8_t *data)
+static inline int xtensa_queue_dbg_reg_read(struct xtensa *xtensa, enum xtensa_dm_reg reg, uint8_t *data)
{
struct xtensa_debug_module *dm = &xtensa->dbg_mod;
if (!xtensa->core_config->trace.enabled &&
- (reg <= NARADR_MEMADDREND || (reg >= NARADR_PMG && reg <= NARADR_PMSTAT7))) {
+ (reg <= XDMREG_MEMADDREND || (reg >= XDMREG_PMG && reg <= XDMREG_PMSTAT7))) {
LOG_ERROR("Can not access %u reg when Trace Port option disabled!", reg);
return ERROR_FAIL;
}
return dm->dbg_ops->queue_reg_read(dm, reg, data);
}
-static inline int xtensa_queue_dbg_reg_write(struct xtensa *xtensa, unsigned int reg, uint32_t data)
+static inline int xtensa_queue_dbg_reg_write(struct xtensa *xtensa, enum xtensa_dm_reg reg, uint32_t data)
{
struct xtensa_debug_module *dm = &xtensa->dbg_mod;
if (!xtensa->core_config->trace.enabled &&
- (reg <= NARADR_MEMADDREND || (reg >= NARADR_PMG && reg <= NARADR_PMSTAT7))) {
+ (reg <= XDMREG_MEMADDREND || (reg >= XDMREG_PMG && reg <= XDMREG_PMSTAT7))) {
LOG_ERROR("Can not access %u reg when Trace Port option disabled!", reg);
return ERROR_FAIL;
}
/* SPDX-License-Identifier: GPL-2.0-or-later */
/***************************************************************************
- * Generic Xtensa debug module API for OpenOCD *
+ * Xtensa Debug Module (XDM) Support for OpenOCD *
+ * Copyright (C) 2020-2022 Cadence Design Systems, Inc. *
* Copyright (C) 2019 Espressif Systems Ltd. *
***************************************************************************/
#define TAPINS_IDCODE_LEN 32
#define TAPINS_BYPASS_LEN 1
+/* Table of debug register offsets for Nexus and APB space */
+static const struct xtensa_dm_reg_offsets xdm_regs[XDMREG_NUM] =
+ XTENSA_DM_REG_OFFSETS;
static void xtensa_dm_add_set_ir(struct xtensa_debug_module *dm, uint8_t value)
{
struct scan_field field;
- uint8_t t[4] = { 0 };
+ uint8_t t[4] = { 0, 0, 0, 0 };
memset(&field, 0, sizeof(field));
field.num_bits = dm->tap->ir_length;
int xtensa_dm_queue_enable(struct xtensa_debug_module *dm)
{
- return dm->dbg_ops->queue_reg_write(dm, NARADR_DCRSET, OCDDCR_ENABLEOCD);
+ return dm->dbg_ops->queue_reg_write(dm, XDMREG_DCRSET, OCDDCR_ENABLEOCD);
}
-int xtensa_dm_queue_reg_read(struct xtensa_debug_module *dm, unsigned int reg, uint8_t *value)
+int xtensa_dm_queue_reg_read(struct xtensa_debug_module *dm, enum xtensa_dm_reg reg, uint8_t *value)
{
- uint8_t regdata = (reg << 1) | 0;
- uint8_t dummy[4] = { 0, 0, 0, 0 };
-
- if (reg > NARADR_MAX) {
+ if (reg >= XDMREG_NUM) {
LOG_ERROR("Invalid DBG reg ID %d!", reg);
return ERROR_FAIL;
}
+ uint8_t regdata = (xdm_regs[reg].nar << 1) | 0;
+ uint8_t dummy[4] = { 0, 0, 0, 0 };
xtensa_dm_add_set_ir(dm, TAPINS_NARSEL);
xtensa_dm_add_dr_scan(dm, TAPINS_NARSEL_ADRLEN, ®data, NULL, TAP_IDLE);
xtensa_dm_add_dr_scan(dm, TAPINS_NARSEL_DATALEN, dummy, value, TAP_IDLE);
return ERROR_OK;
}
-int xtensa_dm_queue_reg_write(struct xtensa_debug_module *dm, unsigned int reg, uint32_t value)
+int xtensa_dm_queue_reg_write(struct xtensa_debug_module *dm, enum xtensa_dm_reg reg, uint32_t value)
{
- uint8_t regdata = (reg << 1) | 1;
- uint8_t valdata[] = { value, value >> 8, value >> 16, value >> 24 };
-
- if (reg > NARADR_MAX) {
+ if (reg >= XDMREG_NUM) {
LOG_ERROR("Invalid DBG reg ID %d!", reg);
return ERROR_FAIL;
}
+ uint8_t regdata = (xdm_regs[reg].nar << 1) | 1;
+ uint8_t valdata[] = { value, value >> 8, value >> 16, value >> 24 };
xtensa_dm_add_set_ir(dm, TAPINS_NARSEL);
xtensa_dm_add_dr_scan(dm, TAPINS_NARSEL_ADRLEN, ®data, NULL, TAP_IDLE);
xtensa_dm_add_dr_scan(dm, TAPINS_NARSEL_DATALEN, valdata, NULL, TAP_IDLE);
return ERROR_OK;
}
-int xtensa_dm_queue_pwr_reg_read(struct xtensa_debug_module *dm, unsigned int reg, uint8_t *data, uint8_t clear)
+int xtensa_dm_queue_pwr_reg_read(struct xtensa_debug_module *dm,
+ enum xtensa_dm_pwr_reg reg,
+ uint8_t *data,
+ uint32_t clear)
{
- uint8_t value_clr = clear;
- uint8_t tap_insn;
- int tap_insn_sz;
-
- if (reg == DMREG_PWRCTL) {
- tap_insn = TAPINS_PWRCTL;
- tap_insn_sz = TAPINS_PWRCTL_LEN;
- } else if (reg == DMREG_PWRSTAT) {
- tap_insn = TAPINS_PWRSTAT;
- tap_insn_sz = TAPINS_PWRSTAT_LEN;
- } else {
+ if (reg >= XDMREG_PWRNUM) {
LOG_ERROR("Invalid PWR reg ID %d!", reg);
return ERROR_FAIL;
}
+ uint8_t value_clr = (uint8_t)clear;
+ uint8_t tap_insn = (reg == XDMREG_PWRCTL) ? TAPINS_PWRCTL : TAPINS_PWRSTAT;
+ int tap_insn_sz = (reg == XDMREG_PWRCTL) ? TAPINS_PWRCTL_LEN : TAPINS_PWRSTAT_LEN;
xtensa_dm_add_set_ir(dm, tap_insn);
xtensa_dm_add_dr_scan(dm, tap_insn_sz, &value_clr, data, TAP_IDLE);
return ERROR_OK;
}
-int xtensa_dm_queue_pwr_reg_write(struct xtensa_debug_module *dm, unsigned int reg, uint8_t data)
+int xtensa_dm_queue_pwr_reg_write(struct xtensa_debug_module *dm,
+ enum xtensa_dm_pwr_reg reg,
+ uint32_t data)
{
- uint8_t value = data;
- uint8_t tap_insn;
- int tap_insn_sz;
-
- if (reg == DMREG_PWRCTL) {
- tap_insn = TAPINS_PWRCTL;
- tap_insn_sz = TAPINS_PWRCTL_LEN;
- } else if (reg == DMREG_PWRSTAT) {
- tap_insn = TAPINS_PWRSTAT;
- tap_insn_sz = TAPINS_PWRSTAT_LEN;
- } else {
+ if (reg >= XDMREG_PWRNUM) {
LOG_ERROR("Invalid PWR reg ID %d!", reg);
return ERROR_FAIL;
}
+ uint8_t tap_insn = (reg == XDMREG_PWRCTL) ? TAPINS_PWRCTL : TAPINS_PWRSTAT;
+ int tap_insn_sz = (reg == XDMREG_PWRCTL) ? TAPINS_PWRCTL_LEN : TAPINS_PWRSTAT_LEN;
+ uint8_t value = (uint8_t)data;
xtensa_dm_add_set_ir(dm, tap_insn);
xtensa_dm_add_dr_scan(dm, tap_insn_sz, &value, NULL, TAP_IDLE);
return ERROR_OK;
{
uint8_t id_buf[sizeof(uint32_t)];
- dm->dbg_ops->queue_reg_read(dm, NARADR_OCDID, id_buf);
+ dm->dbg_ops->queue_reg_read(dm, XDMREG_OCDID, id_buf);
xtensa_dm_queue_tdi_idle(dm);
- int res = jtag_execute_queue();
+ int res = xtensa_dm_queue_execute(dm);
if (res != ERROR_OK)
return res;
dm->device_id = buf_get_u32(id_buf, 0, 32);
int xtensa_dm_power_status_read(struct xtensa_debug_module *dm, uint32_t clear)
{
- /* uint8_t id_buf[sizeof(uint32_t)]; */
+ uint8_t stat_buf[sizeof(uint32_t)];
+ uint8_t stath_buf[sizeof(uint32_t)];
/* TODO: JTAG does not work when PWRCTL_JTAGDEBUGUSE is not set.
- * It is set in xtensa_examine(), need to move reading of NARADR_OCDID out of this function */
- /* dm->dbg_ops->queue_reg_read(dm, NARADR_OCDID, id_buf);
+ * It is set in xtensa_examine(), need to move reading of XDMREG_OCDID out of this function */
+ /* dm->dbg_ops->queue_reg_read(dm, XDMREG_OCDID, id_buf);
*Read reset state */
- dm->pwr_ops->queue_reg_read(dm, DMREG_PWRSTAT, &dm->power_status.stat, clear);
- dm->pwr_ops->queue_reg_read(dm, DMREG_PWRSTAT, &dm->power_status.stath, clear);
+ dm->pwr_ops->queue_reg_read(dm, XDMREG_PWRSTAT, stat_buf, clear);
+ dm->pwr_ops->queue_reg_read(dm, XDMREG_PWRSTAT, stath_buf, clear);
xtensa_dm_queue_tdi_idle(dm);
- return jtag_execute_queue();
+ int res = xtensa_dm_queue_execute(dm);
+ if (res != ERROR_OK)
+ return res;
+ dm->power_status.stat = buf_get_u32(stat_buf, 0, 32);
+ dm->power_status.stath = buf_get_u32(stath_buf, 0, 32);
+ return res;
}
int xtensa_dm_core_status_read(struct xtensa_debug_module *dm)
uint8_t dsr_buf[sizeof(uint32_t)];
xtensa_dm_queue_enable(dm);
- dm->dbg_ops->queue_reg_read(dm, NARADR_DSR, dsr_buf);
+ dm->dbg_ops->queue_reg_read(dm, XDMREG_DSR, dsr_buf);
xtensa_dm_queue_tdi_idle(dm);
- int res = jtag_execute_queue();
+ int res = xtensa_dm_queue_execute(dm);
if (res != ERROR_OK)
return res;
dm->core_status.dsr = buf_get_u32(dsr_buf, 0, 32);
int xtensa_dm_core_status_clear(struct xtensa_debug_module *dm, xtensa_dsr_t bits)
{
- dm->dbg_ops->queue_reg_write(dm, NARADR_DSR, bits);
+ dm->dbg_ops->queue_reg_write(dm, XDMREG_DSR, bits);
xtensa_dm_queue_tdi_idle(dm);
- return jtag_execute_queue();
+ return xtensa_dm_queue_execute(dm);
}
int xtensa_dm_trace_start(struct xtensa_debug_module *dm, struct xtensa_trace_start_config *cfg)
{
/*Turn off trace unit so we can start a new trace. */
- dm->dbg_ops->queue_reg_write(dm, NARADR_TRAXCTRL, 0);
+ dm->dbg_ops->queue_reg_write(dm, XDMREG_TRAXCTRL, 0);
xtensa_dm_queue_tdi_idle(dm);
- int res = jtag_execute_queue();
+ int res = xtensa_dm_queue_execute(dm);
if (res != ERROR_OK)
return res;
/*Set up parameters */
- dm->dbg_ops->queue_reg_write(dm, NARADR_TRAXADDR, 0);
+ dm->dbg_ops->queue_reg_write(dm, XDMREG_TRAXADDR, 0);
if (cfg->stopmask != XTENSA_STOPMASK_DISABLED) {
- dm->dbg_ops->queue_reg_write(dm, NARADR_PCMATCHCTRL,
+ dm->dbg_ops->queue_reg_write(dm, XDMREG_PCMATCHCTRL,
(cfg->stopmask << PCMATCHCTRL_PCML_SHIFT));
- dm->dbg_ops->queue_reg_write(dm, NARADR_TRIGGERPC, cfg->stoppc);
+ dm->dbg_ops->queue_reg_write(dm, XDMREG_TRIGGERPC, cfg->stoppc);
}
- dm->dbg_ops->queue_reg_write(dm, NARADR_DELAYCNT, cfg->after);
+ dm->dbg_ops->queue_reg_write(dm, XDMREG_DELAYCNT, cfg->after);
/*Options are mostly hardcoded for now. ToDo: make this more configurable. */
dm->dbg_ops->queue_reg_write(
dm,
- NARADR_TRAXCTRL,
+ XDMREG_TRAXCTRL,
TRAXCTRL_TREN |
((cfg->stopmask != XTENSA_STOPMASK_DISABLED) ? TRAXCTRL_PCMEN : 0) | TRAXCTRL_TMEN |
(cfg->after_is_words ? 0 : TRAXCTRL_CNTU) | (0 << TRAXCTRL_SMPER_SHIFT) | TRAXCTRL_PTOWS);
xtensa_dm_queue_tdi_idle(dm);
- return jtag_execute_queue();
+ return xtensa_dm_queue_execute(dm);
}
int xtensa_dm_trace_stop(struct xtensa_debug_module *dm, bool pto_enable)
uint32_t traxctl;
struct xtensa_trace_status trace_status;
- dm->dbg_ops->queue_reg_read(dm, NARADR_TRAXCTRL, traxctl_buf);
+ dm->dbg_ops->queue_reg_read(dm, XDMREG_TRAXCTRL, traxctl_buf);
xtensa_dm_queue_tdi_idle(dm);
- int res = jtag_execute_queue();
+ int res = xtensa_dm_queue_execute(dm);
if (res != ERROR_OK)
return res;
traxctl = buf_get_u32(traxctl_buf, 0, 32);
if (!pto_enable)
traxctl &= ~(TRAXCTRL_PTOWS | TRAXCTRL_PTOWT);
- dm->dbg_ops->queue_reg_write(dm, NARADR_TRAXCTRL, traxctl | TRAXCTRL_TRSTP);
+ dm->dbg_ops->queue_reg_write(dm, XDMREG_TRAXCTRL, traxctl | TRAXCTRL_TRSTP);
xtensa_dm_queue_tdi_idle(dm);
- res = jtag_execute_queue();
+ res = xtensa_dm_queue_execute(dm);
if (res != ERROR_OK)
return res;
{
uint8_t traxstat_buf[sizeof(uint32_t)];
- dm->dbg_ops->queue_reg_read(dm, NARADR_TRAXSTAT, traxstat_buf);
+ dm->dbg_ops->queue_reg_read(dm, XDMREG_TRAXSTAT, traxstat_buf);
xtensa_dm_queue_tdi_idle(dm);
- int res = jtag_execute_queue();
+ int res = xtensa_dm_queue_execute(dm);
if (res == ERROR_OK && status)
status->stat = buf_get_u32(traxstat_buf, 0, 32);
return res;
if (!config)
return ERROR_FAIL;
- dm->dbg_ops->queue_reg_read(dm, NARADR_TRAXCTRL, traxctl_buf);
- dm->dbg_ops->queue_reg_read(dm, NARADR_MEMADDRSTART, memadrstart_buf);
- dm->dbg_ops->queue_reg_read(dm, NARADR_MEMADDREND, memadrend_buf);
- dm->dbg_ops->queue_reg_read(dm, NARADR_TRAXADDR, adr_buf);
+ dm->dbg_ops->queue_reg_read(dm, XDMREG_TRAXCTRL, traxctl_buf);
+ dm->dbg_ops->queue_reg_read(dm, XDMREG_MEMADDRSTART, memadrstart_buf);
+ dm->dbg_ops->queue_reg_read(dm, XDMREG_MEMADDREND, memadrend_buf);
+ dm->dbg_ops->queue_reg_read(dm, XDMREG_TRAXADDR, adr_buf);
xtensa_dm_queue_tdi_idle(dm);
- int res = jtag_execute_queue();
+ int res = xtensa_dm_queue_execute(dm);
if (res == ERROR_OK) {
config->ctrl = buf_get_u32(traxctl_buf, 0, 32);
config->memaddr_start = buf_get_u32(memadrstart_buf, 0, 32);
return ERROR_FAIL;
for (unsigned int i = 0; i < size / 4; i++)
- dm->dbg_ops->queue_reg_read(dm, NARADR_TRAXDATA, &dest[i * 4]);
+ dm->dbg_ops->queue_reg_read(dm, XDMREG_TRAXDATA, &dest[i * 4]);
xtensa_dm_queue_tdi_idle(dm);
- return jtag_execute_queue();
+ return xtensa_dm_queue_execute(dm);
}
int xtensa_dm_perfmon_enable(struct xtensa_debug_module *dm, int counter_id,
(config->kernelcnt << 3);
/* enable performance monitor */
- dm->dbg_ops->queue_reg_write(dm, NARADR_PMG, 0x1);
+ dm->dbg_ops->queue_reg_write(dm, XDMREG_PMG, 0x1);
/* reset counter */
- dm->dbg_ops->queue_reg_write(dm, NARADR_PM0 + counter_id, 0);
- dm->dbg_ops->queue_reg_write(dm, NARADR_PMCTRL0 + counter_id, pmctrl);
- dm->dbg_ops->queue_reg_read(dm, NARADR_PMSTAT0 + counter_id, pmstat_buf);
+ dm->dbg_ops->queue_reg_write(dm, XDMREG_PM0 + counter_id, 0);
+ dm->dbg_ops->queue_reg_write(dm, XDMREG_PMCTRL0 + counter_id, pmctrl);
+ dm->dbg_ops->queue_reg_read(dm, XDMREG_PMSTAT0 + counter_id, pmstat_buf);
xtensa_dm_queue_tdi_idle(dm);
- return jtag_execute_queue();
+ return xtensa_dm_queue_execute(dm);
}
int xtensa_dm_perfmon_dump(struct xtensa_debug_module *dm, int counter_id,
uint8_t pmstat_buf[4];
uint8_t pmcount_buf[4];
- dm->dbg_ops->queue_reg_read(dm, NARADR_PMSTAT0 + counter_id, pmstat_buf);
- dm->dbg_ops->queue_reg_read(dm, NARADR_PM0 + counter_id, pmcount_buf);
+ dm->dbg_ops->queue_reg_read(dm, XDMREG_PMSTAT0 + counter_id, pmstat_buf);
+ dm->dbg_ops->queue_reg_read(dm, XDMREG_PM0 + counter_id, pmcount_buf);
xtensa_dm_queue_tdi_idle(dm);
- int res = jtag_execute_queue();
+ int res = xtensa_dm_queue_execute(dm);
if (res == ERROR_OK) {
uint32_t stat = buf_get_u32(pmstat_buf, 0, 32);
uint64_t result = buf_get_u32(pmcount_buf, 0, 32);
/* SPDX-License-Identifier: GPL-2.0-or-later */
/***************************************************************************
- * Xtensa debug module API *
+ * Xtensa Debug Module (XDM) Support for OpenOCD *
+ * Copyright (C) 2020-2022 Cadence Design Systems, Inc. *
* Copyright (C) 2019 Espressif Systems Ltd. *
* Derived from original ESP8266 target. *
* Author: Angus Gratton gus@projectgus.com *
#include <target/target.h>
/* Virtual IDs for using with xtensa_power_ops API */
-#define DMREG_PWRCTL 0x00
-#define DMREG_PWRSTAT 0x01
+enum xtensa_dm_pwr_reg {
+ XDMREG_PWRCTL = 0x00,
+ XDMREG_PWRSTAT,
+ XDMREG_PWRNUM
+};
+
+/* Debug Module Power Register offsets within APB */
+struct xtensa_dm_pwr_reg_offsets {
+ uint16_t apb;
+};
+
+/* Debug Module Power Register offset structure; must include XDMREG_PWRNUM entries */
+#define XTENSA_DM_PWR_REG_OFFSETS { \
+ /* Power/Reset Registers */ \
+ { .apb = 0x3020 }, /* XDMREG_PWRCTL */ \
+ { .apb = 0x3024 }, /* XDMREG_PWRSTAT */ \
+}
/*
From the manual:
#define PWRSTAT_DEBUGDOMAINON BIT(2)
#define PWRSTAT_MEMDOMAINON BIT(1)
#define PWRSTAT_COREDOMAINON BIT(0)
+/* Virtual IDs for using with xtensa_debug_ops API */
+enum xtensa_dm_reg {
+ /* TRAX Registers */
+ XDMREG_TRAXID = 0x00,
+ XDMREG_TRAXCTRL,
+ XDMREG_TRAXSTAT,
+ XDMREG_TRAXDATA,
+ XDMREG_TRAXADDR,
+ XDMREG_TRIGGERPC,
+ XDMREG_PCMATCHCTRL,
+ XDMREG_DELAYCNT,
+ XDMREG_MEMADDRSTART,
+ XDMREG_MEMADDREND,
+
+ /* Performance Monitor Registers */
+ XDMREG_PMG,
+ XDMREG_INTPC,
+ XDMREG_PM0,
+ XDMREG_PM1,
+ XDMREG_PM2,
+ XDMREG_PM3,
+ XDMREG_PM4,
+ XDMREG_PM5,
+ XDMREG_PM6,
+ XDMREG_PM7,
+ XDMREG_PMCTRL0,
+ XDMREG_PMCTRL1,
+ XDMREG_PMCTRL2,
+ XDMREG_PMCTRL3,
+ XDMREG_PMCTRL4,
+ XDMREG_PMCTRL5,
+ XDMREG_PMCTRL6,
+ XDMREG_PMCTRL7,
+ XDMREG_PMSTAT0,
+ XDMREG_PMSTAT1,
+ XDMREG_PMSTAT2,
+ XDMREG_PMSTAT3,
+ XDMREG_PMSTAT4,
+ XDMREG_PMSTAT5,
+ XDMREG_PMSTAT6,
+ XDMREG_PMSTAT7,
+
+ /* OCD Registers */
+ XDMREG_OCDID,
+ XDMREG_DCRCLR,
+ XDMREG_DCRSET,
+ XDMREG_DSR,
+ XDMREG_DDR,
+ XDMREG_DDREXEC,
+ XDMREG_DIR0EXEC,
+ XDMREG_DIR0,
+ XDMREG_DIR1,
+ XDMREG_DIR2,
+ XDMREG_DIR3,
+ XDMREG_DIR4,
+ XDMREG_DIR5,
+ XDMREG_DIR6,
+ XDMREG_DIR7,
+
+ /* Misc Registers */
+ XDMREG_ERISTAT,
+
+ /* CoreSight Registers */
+ XDMREG_ITCTRL,
+ XDMREG_CLAIMSET,
+ XDMREG_CLAIMCLR,
+ XDMREG_LOCKACCESS,
+ XDMREG_LOCKSTATUS,
+ XDMREG_AUTHSTATUS,
+ XDMREG_DEVID,
+ XDMREG_DEVTYPE,
+ XDMREG_PERID4,
+ XDMREG_PERID5,
+ XDMREG_PERID6,
+ XDMREG_PERID7,
+ XDMREG_PERID0,
+ XDMREG_PERID1,
+ XDMREG_PERID2,
+ XDMREG_PERID3,
+ XDMREG_COMPID0,
+ XDMREG_COMPID1,
+ XDMREG_COMPID2,
+ XDMREG_COMPID3,
+
+ XDMREG_NUM
+};
-/* *** NAR addresses (also used as IDs for debug registers in xtensa_debug_ops API) ***
- *TRAX registers */
-#define NARADR_TRAXID 0x00
-#define NARADR_TRAXCTRL 0x01
-#define NARADR_TRAXSTAT 0x02
-#define NARADR_TRAXDATA 0x03
-#define NARADR_TRAXADDR 0x04
-#define NARADR_TRIGGERPC 0x05
-#define NARADR_PCMATCHCTRL 0x06
-#define NARADR_DELAYCNT 0x07
-#define NARADR_MEMADDRSTART 0x08
-#define NARADR_MEMADDREND 0x09
-/*Performance monitor registers */
-#define NARADR_PMG 0x20
-#define NARADR_INTPC 0x24
-#define NARADR_PM0 0x28
-/*... */
-#define NARADR_PM7 0x2F
-#define NARADR_PMCTRL0 0x30
-/*... */
-#define NARADR_PMCTRL7 0x37
-#define NARADR_PMSTAT0 0x38
-/*... */
-#define NARADR_PMSTAT7 0x3F
-/*OCD registers */
-#define NARADR_OCDID 0x40
-#define NARADR_DCRCLR 0x42
-#define NARADR_DCRSET 0x43
-#define NARADR_DSR 0x44
-#define NARADR_DDR 0x45
-#define NARADR_DDREXEC 0x46
-#define NARADR_DIR0EXEC 0x47
-#define NARADR_DIR0 0x48
-#define NARADR_DIR1 0x49
-/*... */
-#define NARADR_DIR7 0x4F
-/*Misc registers */
-#define NARADR_PWRCTL 0x58
-#define NARADR_PWRSTAT 0x59
-#define NARADR_ERISTAT 0x5A
-/*CoreSight registers */
-#define NARADR_ITCTRL 0x60
-#define NARADR_CLAIMSET 0x68
-#define NARADR_CLAIMCLR 0x69
-#define NARADR_LOCKACCESS 0x6c
-#define NARADR_LOCKSTATUS 0x6d
-#define NARADR_AUTHSTATUS 0x6e
-#define NARADR_DEVID 0x72
-#define NARADR_DEVTYPE 0x73
-#define NARADR_PERID4 0x74
-/*... */
-#define NARADR_PERID7 0x77
-#define NARADR_PERID0 0x78
-/*... */
-#define NARADR_PERID3 0x7b
-#define NARADR_COMPID0 0x7c
-/*... */
-#define NARADR_COMPID3 0x7f
-#define NARADR_MAX NARADR_COMPID3
-
-/*OCD registers, bit definitions */
+/* Debug Module Register offsets within Nexus (NAR) or APB */
+struct xtensa_dm_reg_offsets {
+ uint8_t nar;
+ uint16_t apb;
+};
+
+/* Debug Module Register offset structure; must include XDMREG_NUM entries */
+#define XTENSA_DM_REG_OFFSETS { \
+ /* TRAX Registers */ \
+ { .nar = 0x00, .apb = 0x0000 }, /* XDMREG_TRAXID */ \
+ { .nar = 0x01, .apb = 0x0004 }, /* XDMREG_TRAXCTRL */ \
+ { .nar = 0x02, .apb = 0x0008 }, /* XDMREG_TRAXSTAT */ \
+ { .nar = 0x03, .apb = 0x000c }, /* XDMREG_TRAXDATA */ \
+ { .nar = 0x04, .apb = 0x0010 }, /* XDMREG_TRAXADDR */ \
+ { .nar = 0x05, .apb = 0x0014 }, /* XDMREG_TRIGGERPC */ \
+ { .nar = 0x06, .apb = 0x0018 }, /* XDMREG_PCMATCHCTRL */ \
+ { .nar = 0x07, .apb = 0x001c }, /* XDMREG_DELAYCNT */ \
+ { .nar = 0x08, .apb = 0x0020 }, /* XDMREG_MEMADDRSTART */ \
+ { .nar = 0x09, .apb = 0x0024 }, /* XDMREG_MEMADDREND */ \
+ \
+ /* Performance Monitor Registers */ \
+ { .nar = 0x20, .apb = 0x1000 }, /* XDMREG_PMG */ \
+ { .nar = 0x24, .apb = 0x1010 }, /* XDMREG_INTPC */ \
+ { .nar = 0x28, .apb = 0x1080 }, /* XDMREG_PM0 */ \
+ { .nar = 0x29, .apb = 0x1084 }, /* XDMREG_PM1 */ \
+ { .nar = 0x2a, .apb = 0x1088 }, /* XDMREG_PM2 */ \
+ { .nar = 0x2b, .apb = 0x108c }, /* XDMREG_PM3 */ \
+ { .nar = 0x2c, .apb = 0x1090 }, /* XDMREG_PM4 */ \
+ { .nar = 0x2d, .apb = 0x1094 }, /* XDMREG_PM5 */ \
+ { .nar = 0x2e, .apb = 0x1098 }, /* XDMREG_PM6 */ \
+ { .nar = 0x2f, .apb = 0x109c }, /* XDMREG_PM7 */ \
+ { .nar = 0x30, .apb = 0x1100 }, /* XDMREG_PMCTRL0 */ \
+ { .nar = 0x31, .apb = 0x1104 }, /* XDMREG_PMCTRL1 */ \
+ { .nar = 0x32, .apb = 0x1108 }, /* XDMREG_PMCTRL2 */ \
+ { .nar = 0x33, .apb = 0x110c }, /* XDMREG_PMCTRL3 */ \
+ { .nar = 0x34, .apb = 0x1110 }, /* XDMREG_PMCTRL4 */ \
+ { .nar = 0x35, .apb = 0x1114 }, /* XDMREG_PMCTRL5 */ \
+ { .nar = 0x36, .apb = 0x1118 }, /* XDMREG_PMCTRL6 */ \
+ { .nar = 0x37, .apb = 0x111c }, /* XDMREG_PMCTRL7 */ \
+ { .nar = 0x38, .apb = 0x1180 }, /* XDMREG_PMSTAT0 */ \
+ { .nar = 0x39, .apb = 0x1184 }, /* XDMREG_PMSTAT1 */ \
+ { .nar = 0x3a, .apb = 0x1188 }, /* XDMREG_PMSTAT2 */ \
+ { .nar = 0x3b, .apb = 0x118c }, /* XDMREG_PMSTAT3 */ \
+ { .nar = 0x3c, .apb = 0x1190 }, /* XDMREG_PMSTAT4 */ \
+ { .nar = 0x3d, .apb = 0x1194 }, /* XDMREG_PMSTAT5 */ \
+ { .nar = 0x3e, .apb = 0x1198 }, /* XDMREG_PMSTAT6 */ \
+ { .nar = 0x3f, .apb = 0x119c }, /* XDMREG_PMSTAT7 */ \
+ \
+ /* OCD Registers */ \
+ { .nar = 0x40, .apb = 0x2000 }, /* XDMREG_OCDID */ \
+ { .nar = 0x42, .apb = 0x2008 }, /* XDMREG_DCRCLR */ \
+ { .nar = 0x43, .apb = 0x200c }, /* XDMREG_DCRSET */ \
+ { .nar = 0x44, .apb = 0x2010 }, /* XDMREG_DSR */ \
+ { .nar = 0x45, .apb = 0x2014 }, /* XDMREG_DDR */ \
+ { .nar = 0x46, .apb = 0x2018 }, /* XDMREG_DDREXEC */ \
+ { .nar = 0x47, .apb = 0x201c }, /* XDMREG_DIR0EXEC */ \
+ { .nar = 0x48, .apb = 0x2020 }, /* XDMREG_DIR0 */ \
+ { .nar = 0x49, .apb = 0x2024 }, /* XDMREG_DIR1 */ \
+ { .nar = 0x4a, .apb = 0x2028 }, /* XDMREG_DIR2 */ \
+ { .nar = 0x4b, .apb = 0x202c }, /* XDMREG_DIR3 */ \
+ { .nar = 0x4c, .apb = 0x2030 }, /* XDMREG_DIR4 */ \
+ { .nar = 0x4d, .apb = 0x2034 }, /* XDMREG_DIR5 */ \
+ { .nar = 0x4e, .apb = 0x2038 }, /* XDMREG_DIR6 */ \
+ { .nar = 0x4f, .apb = 0x203c }, /* XDMREG_DIR7 */ \
+ \
+ /* Misc Registers */ \
+ { .nar = 0x5a, .apb = 0x3028 }, /* XDMREG_ERISTAT */ \
+ \
+ /* CoreSight Registers */ \
+ { .nar = 0x60, .apb = 0x3f00 }, /* XDMREG_ITCTRL */ \
+ { .nar = 0x68, .apb = 0x3fa0 }, /* XDMREG_CLAIMSET */ \
+ { .nar = 0x69, .apb = 0x3fa4 }, /* XDMREG_CLAIMCLR */ \
+ { .nar = 0x6c, .apb = 0x3fb0 }, /* XDMREG_LOCKACCESS */ \
+ { .nar = 0x6d, .apb = 0x3fb4 }, /* XDMREG_LOCKSTATUS */ \
+ { .nar = 0x6e, .apb = 0x3fb8 }, /* XDMREG_AUTHSTATUS */ \
+ { .nar = 0x72, .apb = 0x3fc8 }, /* XDMREG_DEVID */ \
+ { .nar = 0x73, .apb = 0x3fcc }, /* XDMREG_DEVTYPE */ \
+ { .nar = 0x74, .apb = 0x3fd0 }, /* XDMREG_PERID4 */ \
+ { .nar = 0x75, .apb = 0x3fd4 }, /* XDMREG_PERID5 */ \
+ { .nar = 0x76, .apb = 0x3fd8 }, /* XDMREG_PERID6 */ \
+ { .nar = 0x77, .apb = 0x3fdc }, /* XDMREG_PERID7 */ \
+ { .nar = 0x78, .apb = 0x3fe0 }, /* XDMREG_PERID0 */ \
+ { .nar = 0x79, .apb = 0x3fe4 }, /* XDMREG_PERID1 */ \
+ { .nar = 0x7a, .apb = 0x3fe8 }, /* XDMREG_PERID2 */ \
+ { .nar = 0x7b, .apb = 0x3fec }, /* XDMREG_PERID3 */ \
+ { .nar = 0x7c, .apb = 0x3ff0 }, /* XDMREG_COMPID0 */ \
+ { .nar = 0x7d, .apb = 0x3ff4 }, /* XDMREG_COMPID1 */ \
+ { .nar = 0x7e, .apb = 0x3ff8 }, /* XDMREG_COMPID2 */ \
+ { .nar = 0x7f, .apb = 0x3ffc }, /* XDMREG_COMPID3 */ \
+}
+
+#define XTENSA_DM_APB_MASK (0x3fff)
+
+/* OCD registers, bit definitions */
#define OCDDCR_ENABLEOCD BIT(0)
#define OCDDCR_DEBUGINTERRUPT BIT(1)
#define OCDDCR_INTERRUPTALLCONDS BIT(2)
#define TRAXCTRL_CTIEN BIT(5) /* Cross-trigger enable */
#define TRAXCTRL_TMEN BIT(7) /* Tracemem Enable. Always set. */
#define TRAXCTRL_CNTU BIT(9) /* Post-stop-trigger countdown units; selects when DelayCount-- happens.
- *0 - every 32-bit word written to tracemem, 1 - every cpu instruction */
+ * 0 - every 32-bit word written to tracemem, 1 - every cpu instruction */
#define TRAXCTRL_TSEN BIT(11) /* Undocumented/deprecated? */
#define TRAXCTRL_SMPER_SHIFT 12 /* Send sync every 2^(9-smper) messages. 7=reserved, 0=no sync msg */
#define TRAXCTRL_SMPER_MASK 0x07 /* Synchronization message period */
#define PCMATCHCTRL_PCML_SHIFT 0 /* Amount of lower bits to ignore in pc trigger register */
#define PCMATCHCTRL_PCML_MASK 0x1F
#define PCMATCHCTRL_PCMS BIT(31) /* PC Match Sense, 0-match when procs PC is in-range, 1-match when
- *out-of-range */
+ * out-of-range */
#define XTENSA_MAX_PERF_COUNTERS 2
#define XTENSA_MAX_PERF_SELECT 32
/** enable operation */
int (*queue_enable)(struct xtensa_debug_module *dm);
/** register read. */
- int (*queue_reg_read)(struct xtensa_debug_module *dm, unsigned int reg, uint8_t *data);
+ int (*queue_reg_read)(struct xtensa_debug_module *dm, enum xtensa_dm_reg reg, uint8_t *data);
/** register write. */
- int (*queue_reg_write)(struct xtensa_debug_module *dm, unsigned int reg, uint32_t data);
+ int (*queue_reg_write)(struct xtensa_debug_module *dm, enum xtensa_dm_reg reg, uint32_t data);
};
+/* Xtensa power registers are 8 bits wide on JTAG interfaces but 32 bits wide
+ * when accessed via APB/DAP. In order to use DAP queuing APIs (for optimal
+ * performance), the XDM power register APIs take 32-bit register params.
+ */
struct xtensa_power_ops {
/** register read. */
- int (*queue_reg_read)(struct xtensa_debug_module *dm, unsigned int reg, uint8_t *data,
- uint8_t clear);
+ int (*queue_reg_read)(struct xtensa_debug_module *dm, enum xtensa_dm_pwr_reg reg, uint8_t *data,
+ uint32_t clear);
/** register write. */
- int (*queue_reg_write)(struct xtensa_debug_module *dm, unsigned int reg, uint8_t data);
+ int (*queue_reg_write)(struct xtensa_debug_module *dm, enum xtensa_dm_pwr_reg reg, uint32_t data);
};
-typedef uint8_t xtensa_pwrstat_t;
+typedef uint32_t xtensa_pwrstat_t;
typedef uint32_t xtensa_ocdid_t;
typedef uint32_t xtensa_dsr_t;
typedef uint32_t xtensa_traxstat_t;
int xtensa_dm_init(struct xtensa_debug_module *dm, const struct xtensa_debug_module_config *cfg);
int xtensa_dm_queue_enable(struct xtensa_debug_module *dm);
-int xtensa_dm_queue_reg_read(struct xtensa_debug_module *dm, unsigned int reg, uint8_t *value);
-int xtensa_dm_queue_reg_write(struct xtensa_debug_module *dm, unsigned int reg, uint32_t value);
-int xtensa_dm_queue_pwr_reg_read(struct xtensa_debug_module *dm, unsigned int reg, uint8_t *data, uint8_t clear);
-int xtensa_dm_queue_pwr_reg_write(struct xtensa_debug_module *dm, unsigned int reg, uint8_t data);
+int xtensa_dm_queue_reg_read(struct xtensa_debug_module *dm, enum xtensa_dm_reg reg, uint8_t *value);
+int xtensa_dm_queue_reg_write(struct xtensa_debug_module *dm, enum xtensa_dm_reg reg, uint32_t value);
+int xtensa_dm_queue_pwr_reg_read(struct xtensa_debug_module *dm,
+ enum xtensa_dm_pwr_reg reg,
+ uint8_t *data,
+ uint32_t clear);
+int xtensa_dm_queue_pwr_reg_write(struct xtensa_debug_module *dm,
+ enum xtensa_dm_pwr_reg reg,
+ uint32_t data);
+
+static inline int xtensa_dm_queue_execute(struct xtensa_debug_module *dm)
+{
+ return jtag_execute_queue();
+}
static inline void xtensa_dm_queue_tdi_idle(struct xtensa_debug_module *dm)
{
int res = xtensa_dm_device_id_read(dm);
if (res != ERROR_OK)
return false;
- return (dm->device_id != 0xffffffff && dm->device_id != 0);
+ return dm->device_id != 0xffffffff && dm->device_id != 0;
}
static inline bool xtensa_dm_tap_was_reset(struct xtensa_debug_module *dm)