From: Ian Thompson Date: Wed, 24 Aug 2022 13:51:51 +0000 (-0700) Subject: target/xtensa: virtualize XDM registers X-Git-Tag: v0.12.0-rc1~64 X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=commitdiff_plain;h=de99836cf639b63dc357a34c13825669af841f17 target/xtensa: virtualize XDM registers 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 Change-Id: I0b742fe4661ff3cf609454b8650493d141a1e1ff Reviewed-on: https://review.openocd.org/c/openocd/+/7143 Tested-by: jenkins Reviewed-by: Antonio Borneo --- diff --git a/src/target/xtensa/xtensa.c b/src/target/xtensa/xtensa.c index 2fd2c7ca57..a90cd14684 100644 --- a/src/target/xtensa/xtensa.c +++ b/src/target/xtensa/xtensa.c @@ -493,7 +493,7 @@ static void xtensa_mark_register_dirty(struct xtensa *xtensa, enum xtensa_reg_id 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) @@ -506,9 +506,9 @@ static void xtensa_queue_exec_ins_wide(struct xtensa *xtensa, uint8_t *ops, uint 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]); } } @@ -529,8 +529,8 @@ int xtensa_window_state_save(struct target *target, uint32_t *woe) /* 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; @@ -539,7 +539,7 @@ int xtensa_window_state_save(struct target *target, uint32_t *woe) *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)); } @@ -552,7 +552,7 @@ void xtensa_window_state_restore(struct target *target, uint32_t woe) 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); @@ -614,7 +614,7 @@ static int xtensa_write_dirty_registers(struct target *target) 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; @@ -641,7 +641,7 @@ static int xtensa_write_dirty_registers(struct target *target) 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, @@ -653,8 +653,8 @@ static int xtensa_write_dirty_registers(struct target *target) 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); @@ -705,7 +705,7 @@ static int xtensa_write_dirty_registers(struct target *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) { @@ -733,7 +733,7 @@ static int xtensa_write_dirty_registers(struct target *target) 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)); @@ -757,11 +757,11 @@ static int xtensa_write_dirty_registers(struct target *target) } 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; @@ -785,11 +785,11 @@ int xtensa_examine(struct target *target) 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)) { @@ -810,11 +810,11 @@ int xtensa_wakeup(struct target *target) 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) @@ -825,11 +825,11 @@ 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) @@ -848,9 +848,9 @@ int xtensa_smpbreak_read(struct xtensa *xtensa, uint32_t *val) { 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; @@ -958,11 +958,11 @@ int xtensa_assert_reset(struct target *target) 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; @@ -976,13 +976,14 @@ int xtensa_deassert_reset(struct target *target) 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; @@ -1022,7 +1023,7 @@ int xtensa_fetch_all_regs(struct target *target) /* 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; @@ -1038,10 +1039,10 @@ int xtensa_fetch_all_regs(struct target *target) 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); } } @@ -1057,9 +1058,9 @@ int xtensa_fetch_all_regs(struct target *target) /* 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; @@ -1072,7 +1073,7 @@ int xtensa_fetch_all_regs(struct target *target) 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)); @@ -1111,14 +1112,14 @@ int xtensa_fetch_all_regs(struct target *target) } 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; @@ -1305,9 +1306,9 @@ int xtensa_halt(struct target *target) } 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."); } @@ -1381,7 +1382,7 @@ int xtensa_do_resume(struct target *target) 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; @@ -1741,26 +1742,26 @@ int xtensa_read_memory(struct target *target, target_addr_t address, uint32_t si /* 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; @@ -1856,7 +1857,7 @@ int xtensa_write_memory(struct target *target, 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)); @@ -1864,10 +1865,10 @@ int xtensa_write_memory(struct target *target, 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)); @@ -1875,11 +1876,11 @@ int xtensa_write_memory(struct target *target, 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) @@ -1911,30 +1912,30 @@ int xtensa_write_memory(struct target *target, 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; @@ -1967,7 +1968,7 @@ int xtensa_write_memory(struct target *target, 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) @@ -1983,7 +1984,7 @@ int xtensa_write_memory(struct target *target, } /* 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, @@ -2013,7 +2014,8 @@ int xtensa_poll(struct target *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, @@ -2141,7 +2143,7 @@ static int xtensa_update_instruction(struct target *target, target_addr_t addres 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) { @@ -2164,7 +2166,7 @@ static int xtensa_update_instruction(struct target *target, target_addr_t addres } /* 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); @@ -2181,7 +2183,7 @@ static int xtensa_update_instruction(struct target *target, target_addr_t addres 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); @@ -2191,7 +2193,7 @@ static int xtensa_update_instruction(struct target *target, target_addr_t addres } /* Execute invalidate instructions */ - ret = jtag_execute_queue(); + ret = xtensa_dm_queue_execute(&xtensa->dbg_mod); xtensa_core_status_check(target); } @@ -2658,15 +2660,15 @@ static int xtensa_gdbqc_qxtreg(struct target *target, const char *packet, char * } } 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; @@ -2944,13 +2946,13 @@ void xtensa_target_deinit(struct target *target) 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; @@ -3013,17 +3015,17 @@ COMMAND_HELPER(xtensa_cmd_exe_do, struct target *target) 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); @@ -3346,8 +3348,9 @@ COMMAND_HELPER(xtensa_cmd_xtreg_do, struct xtensa *xtensa) 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 */ @@ -3471,7 +3474,7 @@ COMMAND_HELPER(xtensa_cmd_xtregfmt_do, struct xtensa *xtensa) 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; diff --git a/src/target/xtensa/xtensa.h b/src/target/xtensa/xtensa.h index fd03f07f85..4d98f3a36a 100644 --- a/src/target/xtensa/xtensa.h +++ b/src/target/xtensa/xtensa.h @@ -273,24 +273,24 @@ static inline bool xtensa_data_addr_valid(struct target *target, uint32_t addr) 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; } diff --git a/src/target/xtensa/xtensa_debug_module.c b/src/target/xtensa/xtensa_debug_module.c index a7de1ad5c9..7f8a75bc66 100644 --- a/src/target/xtensa/xtensa_debug_module.c +++ b/src/target/xtensa/xtensa_debug_module.c @@ -1,7 +1,8 @@ /* 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. * ***************************************************************************/ @@ -24,11 +25,14 @@ #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; @@ -67,76 +71,65 @@ int xtensa_dm_init(struct xtensa_debug_module *dm, const struct xtensa_debug_mod 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; @@ -146,9 +139,9 @@ int xtensa_dm_device_id_read(struct xtensa_debug_module *dm) { 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); @@ -157,16 +150,22 @@ int xtensa_dm_device_id_read(struct xtensa_debug_module *dm) 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) @@ -174,9 +173,9 @@ 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); @@ -185,37 +184,37 @@ int xtensa_dm_core_status_read(struct xtensa_debug_module *dm) 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) @@ -224,9 +223,9 @@ 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); @@ -234,9 +233,9 @@ int xtensa_dm_trace_stop(struct xtensa_debug_module *dm, bool pto_enable) 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; @@ -256,9 +255,9 @@ int xtensa_dm_trace_status_read(struct xtensa_debug_module *dm, struct xtensa_tr { 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; @@ -274,12 +273,12 @@ int xtensa_dm_trace_config_read(struct xtensa_debug_module *dm, struct xtensa_tr 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); @@ -295,9 +294,9 @@ int xtensa_dm_trace_data_read(struct xtensa_debug_module *dm, uint8_t *dest, uin 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, @@ -313,13 +312,13 @@ 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, @@ -328,10 +327,10 @@ 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); diff --git a/src/target/xtensa/xtensa_debug_module.h b/src/target/xtensa/xtensa_debug_module.h index 189a6c97a8..b4bb886823 100644 --- a/src/target/xtensa/xtensa_debug_module.h +++ b/src/target/xtensa/xtensa_debug_module.h @@ -1,7 +1,8 @@ /* 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 * @@ -15,8 +16,23 @@ #include /* 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: @@ -42,68 +58,187 @@ #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) @@ -150,7 +285,7 @@ #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 */ @@ -188,7 +323,7 @@ #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 @@ -202,20 +337,24 @@ struct xtensa_debug_ops { /** 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; @@ -288,10 +427,20 @@ struct xtensa_debug_module { 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) { @@ -338,7 +487,7 @@ static inline bool xtensa_dm_is_online(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)