xtensa: update XDM register map for TRAX support
- Include additional debug module registers - Add translation function for DM reg addr -> ID - Add DM read/write commands Signed-off-by: ianst <ianst@cadence.com> Change-Id: If95419d24a9f27a40fa695c8c15326cdfd127ef1 Reviewed-on: https://review.openocd.org/c/openocd/+/7973 Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com> Tested-by: jenkins
This commit is contained in:
parent
9ebc2a6519
commit
f8096ce687
|
@ -11487,6 +11487,12 @@ Execute arbitrary instruction(s) provided as an ascii string. The string repres
|
||||||
number of instruction bytes, thus its length must be even.
|
number of instruction bytes, thus its length must be even.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
|
@deffn {Command} {xtensa dm} (address) [value]
|
||||||
|
Read or write Xtensa Debug Module (DM) registers. @var{address} is required for both reads
|
||||||
|
and writes and is a 4-byte-aligned value typically between 0 and 0x3ffc. @var{value} is specified
|
||||||
|
only for write accesses.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
@subsection Xtensa Performance Monitor Configuration
|
@subsection Xtensa Performance Monitor Configuration
|
||||||
|
|
||||||
@deffn {Command} {xtensa perfmon_enable} <counter_id> <select> [mask] [kernelcnt] [tracelevel]
|
@deffn {Command} {xtensa perfmon_enable} <counter_id> <select> [mask] [kernelcnt] [tracelevel]
|
||||||
|
|
|
@ -3978,6 +3978,38 @@ COMMAND_HANDLER(xtensa_cmd_smpbreak)
|
||||||
get_current_target(CMD_CTX));
|
get_current_target(CMD_CTX));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
COMMAND_HELPER(xtensa_cmd_dm_rw_do, struct xtensa *xtensa)
|
||||||
|
{
|
||||||
|
if (CMD_ARGC == 1) {
|
||||||
|
// read: xtensa dm addr
|
||||||
|
uint32_t addr = strtoul(CMD_ARGV[0], NULL, 0);
|
||||||
|
uint32_t val;
|
||||||
|
int res = xtensa_dm_read(&xtensa->dbg_mod, addr, &val);
|
||||||
|
if (res == ERROR_OK)
|
||||||
|
command_print(CMD, "xtensa DM(0x%08" PRIx32 ") -> 0x%08" PRIx32, addr, val);
|
||||||
|
else
|
||||||
|
command_print(CMD, "xtensa DM(0x%08" PRIx32 ") : read ERROR %" PRId32, addr, res);
|
||||||
|
return res;
|
||||||
|
} else if (CMD_ARGC == 2) {
|
||||||
|
// write: xtensa dm addr value
|
||||||
|
uint32_t addr = strtoul(CMD_ARGV[0], NULL, 0);
|
||||||
|
uint32_t val = strtoul(CMD_ARGV[1], NULL, 0);
|
||||||
|
int res = xtensa_dm_write(&xtensa->dbg_mod, addr, val);
|
||||||
|
if (res == ERROR_OK)
|
||||||
|
command_print(CMD, "xtensa DM(0x%08" PRIx32 ") <- 0x%08" PRIx32, addr, val);
|
||||||
|
else
|
||||||
|
command_print(CMD, "xtensa DM(0x%08" PRIx32 ") : write ERROR %" PRId32, addr, res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
COMMAND_HANDLER(xtensa_cmd_dm_rw)
|
||||||
|
{
|
||||||
|
return CALL_COMMAND_HANDLER(xtensa_cmd_dm_rw_do,
|
||||||
|
target_to_xtensa(get_current_target(CMD_CTX)));
|
||||||
|
}
|
||||||
|
|
||||||
COMMAND_HELPER(xtensa_cmd_tracestart_do, struct xtensa *xtensa)
|
COMMAND_HELPER(xtensa_cmd_tracestart_do, struct xtensa *xtensa)
|
||||||
{
|
{
|
||||||
struct xtensa_trace_status trace_status;
|
struct xtensa_trace_status trace_status;
|
||||||
|
@ -4234,6 +4266,13 @@ static const struct command_registration xtensa_any_command_handlers[] = {
|
||||||
.help = "Set the way the CPU chains OCD breaks",
|
.help = "Set the way the CPU chains OCD breaks",
|
||||||
.usage = "[none|breakinout|runstall] | [BreakIn] [BreakOut] [RunStallIn] [DebugModeOut]",
|
.usage = "[none|breakinout|runstall] | [BreakIn] [BreakOut] [RunStallIn] [DebugModeOut]",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.name = "dm",
|
||||||
|
.handler = xtensa_cmd_dm_rw,
|
||||||
|
.mode = COMMAND_ANY,
|
||||||
|
.help = "Xtensa DM read/write",
|
||||||
|
.usage = "addr [value]"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
.name = "perfmon_enable",
|
.name = "perfmon_enable",
|
||||||
.handler = xtensa_cmd_perfmon_enable,
|
.handler = xtensa_cmd_perfmon_enable,
|
||||||
|
|
|
@ -34,6 +34,16 @@ static const struct xtensa_dm_pwr_reg_offsets xdm_pwr_regs[XDMREG_PWRNUM] =
|
||||||
static const struct xtensa_dm_reg_offsets xdm_regs[XDMREG_NUM] =
|
static const struct xtensa_dm_reg_offsets xdm_regs[XDMREG_NUM] =
|
||||||
XTENSA_DM_REG_OFFSETS;
|
XTENSA_DM_REG_OFFSETS;
|
||||||
|
|
||||||
|
static enum xtensa_dm_reg xtensa_dm_regaddr_to_id(uint32_t addr)
|
||||||
|
{
|
||||||
|
enum xtensa_dm_reg id;
|
||||||
|
uint32_t addr_masked = (addr & (XTENSA_DM_APB_ALIGN - 1));
|
||||||
|
for (id = XDMREG_TRAXID; id < XDMREG_NUM; id++)
|
||||||
|
if (xdm_regs[id].apb == addr_masked)
|
||||||
|
break;
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
static void xtensa_dm_add_set_ir(struct xtensa_debug_module *dm, uint8_t value)
|
static void xtensa_dm_add_set_ir(struct xtensa_debug_module *dm, uint8_t value)
|
||||||
{
|
{
|
||||||
struct scan_field field;
|
struct scan_field field;
|
||||||
|
@ -285,6 +295,34 @@ int xtensa_dm_core_status_clear(struct xtensa_debug_module *dm, xtensa_dsr_t bit
|
||||||
return xtensa_dm_queue_execute(dm);
|
return xtensa_dm_queue_execute(dm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int xtensa_dm_read(struct xtensa_debug_module *dm, uint32_t addr, uint32_t *val)
|
||||||
|
{
|
||||||
|
enum xtensa_dm_reg reg = xtensa_dm_regaddr_to_id(addr);
|
||||||
|
uint8_t buf[sizeof(uint32_t)];
|
||||||
|
if (reg < XDMREG_NUM) {
|
||||||
|
xtensa_dm_queue_enable(dm);
|
||||||
|
dm->dbg_ops->queue_reg_read(dm, reg, buf);
|
||||||
|
xtensa_dm_queue_tdi_idle(dm);
|
||||||
|
int res = xtensa_dm_queue_execute(dm);
|
||||||
|
if (res == ERROR_OK && val)
|
||||||
|
*val = buf_get_u32(buf, 0, 32);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
return ERROR_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int xtensa_dm_write(struct xtensa_debug_module *dm, uint32_t addr, uint32_t val)
|
||||||
|
{
|
||||||
|
enum xtensa_dm_reg reg = xtensa_dm_regaddr_to_id(addr);
|
||||||
|
if (reg < XDMREG_NUM) {
|
||||||
|
xtensa_dm_queue_enable(dm);
|
||||||
|
dm->dbg_ops->queue_reg_write(dm, reg, val);
|
||||||
|
xtensa_dm_queue_tdi_idle(dm);
|
||||||
|
return xtensa_dm_queue_execute(dm);
|
||||||
|
}
|
||||||
|
return ERROR_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
int xtensa_dm_trace_start(struct xtensa_debug_module *dm, struct xtensa_trace_start_config *cfg)
|
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. */
|
/*Turn off trace unit so we can start a new trace. */
|
||||||
|
|
|
@ -75,6 +75,22 @@ enum xtensa_dm_reg {
|
||||||
XDMREG_DELAYCNT,
|
XDMREG_DELAYCNT,
|
||||||
XDMREG_MEMADDRSTART,
|
XDMREG_MEMADDRSTART,
|
||||||
XDMREG_MEMADDREND,
|
XDMREG_MEMADDREND,
|
||||||
|
XDMREG_EXTTIMELO,
|
||||||
|
XDMREG_EXTTIMEHI,
|
||||||
|
XDMREG_TRAXRSVD48,
|
||||||
|
XDMREG_TRAXRSVD4C,
|
||||||
|
XDMREG_TRAXRSVD50,
|
||||||
|
XDMREG_TRAXRSVD54,
|
||||||
|
XDMREG_TRAXRSVD58,
|
||||||
|
XDMREG_TRAXRSVD5C,
|
||||||
|
XDMREG_TRAXRSVD60,
|
||||||
|
XDMREG_TRAXRSVD64,
|
||||||
|
XDMREG_TRAXRSVD68,
|
||||||
|
XDMREG_TRAXRSVD6C,
|
||||||
|
XDMREG_TRAXRSVD70,
|
||||||
|
XDMREG_TRAXRSVD74,
|
||||||
|
XDMREG_CONFIGID0,
|
||||||
|
XDMREG_CONFIGID1,
|
||||||
|
|
||||||
/* Performance Monitor Registers */
|
/* Performance Monitor Registers */
|
||||||
XDMREG_PMG,
|
XDMREG_PMG,
|
||||||
|
@ -168,6 +184,22 @@ struct xtensa_dm_reg_offsets {
|
||||||
{ .nar = 0x07, .apb = 0x001c }, /* XDMREG_DELAYCNT */ \
|
{ .nar = 0x07, .apb = 0x001c }, /* XDMREG_DELAYCNT */ \
|
||||||
{ .nar = 0x08, .apb = 0x0020 }, /* XDMREG_MEMADDRSTART */ \
|
{ .nar = 0x08, .apb = 0x0020 }, /* XDMREG_MEMADDRSTART */ \
|
||||||
{ .nar = 0x09, .apb = 0x0024 }, /* XDMREG_MEMADDREND */ \
|
{ .nar = 0x09, .apb = 0x0024 }, /* XDMREG_MEMADDREND */ \
|
||||||
|
{ .nar = 0x10, .apb = 0x0040 }, /* XDMREG_EXTTIMELO */ \
|
||||||
|
{ .nar = 0x11, .apb = 0x0044 }, /* XDMREG_EXTTIMEHI */ \
|
||||||
|
{ .nar = 0x12, .apb = 0x0048 }, /* XDMREG_TRAXRSVD48 */ \
|
||||||
|
{ .nar = 0x13, .apb = 0x004c }, /* XDMREG_TRAXRSVD4C */ \
|
||||||
|
{ .nar = 0x14, .apb = 0x0050 }, /* XDMREG_TRAXRSVD50 */ \
|
||||||
|
{ .nar = 0x15, .apb = 0x0054 }, /* XDMREG_TRAXRSVD54 */ \
|
||||||
|
{ .nar = 0x16, .apb = 0x0058 }, /* XDMREG_TRAXRSVD58 */ \
|
||||||
|
{ .nar = 0x17, .apb = 0x005c }, /* XDMREG_TRAXRSVD5C */ \
|
||||||
|
{ .nar = 0x18, .apb = 0x0060 }, /* XDMREG_TRAXRSVD60 */ \
|
||||||
|
{ .nar = 0x19, .apb = 0x0064 }, /* XDMREG_TRAXRSVD64 */ \
|
||||||
|
{ .nar = 0x1a, .apb = 0x0068 }, /* XDMREG_TRAXRSVD68 */ \
|
||||||
|
{ .nar = 0x1b, .apb = 0x006c }, /* XDMREG_TRAXRSVD6C */ \
|
||||||
|
{ .nar = 0x1c, .apb = 0x0070 }, /* XDMREG_TRAXRSVD70 */ \
|
||||||
|
{ .nar = 0x1d, .apb = 0x0074 }, /* XDMREG_TRAXRSVD74 */ \
|
||||||
|
{ .nar = 0x1e, .apb = 0x0078 }, /* XDMREG_CONFIGID0 */ \
|
||||||
|
{ .nar = 0x1f, .apb = 0x007c }, /* XDMREG_CONFIGID1 */ \
|
||||||
\
|
\
|
||||||
/* Performance Monitor Registers */ \
|
/* Performance Monitor Registers */ \
|
||||||
{ .nar = 0x20, .apb = 0x1000 }, /* XDMREG_PMG */ \
|
{ .nar = 0x20, .apb = 0x1000 }, /* XDMREG_PMG */ \
|
||||||
|
@ -297,6 +329,11 @@ struct xtensa_dm_reg_offsets {
|
||||||
#define DEBUGCAUSE_DI BIT(5) /* Debug Interrupt */
|
#define DEBUGCAUSE_DI BIT(5) /* Debug Interrupt */
|
||||||
#define DEBUGCAUSE_VALID BIT(31) /* Pseudo-value to trigger reread (NX only) */
|
#define DEBUGCAUSE_VALID BIT(31) /* Pseudo-value to trigger reread (NX only) */
|
||||||
|
|
||||||
|
/* TRAXID */
|
||||||
|
#define TRAXID_PRODNO_TRAX 0 /* TRAXID.PRODNO value for TRAX module */
|
||||||
|
#define TRAXID_PRODNO_SHIFT 28
|
||||||
|
#define TRAXID_PRODNO_MASK 0xf
|
||||||
|
|
||||||
#define TRAXCTRL_TREN BIT(0) /* Trace enable. Tracing starts on 0->1 */
|
#define TRAXCTRL_TREN BIT(0) /* Trace enable. Tracing starts on 0->1 */
|
||||||
#define TRAXCTRL_TRSTP BIT(1) /* Trace Stop. Make 1 to stop trace. */
|
#define TRAXCTRL_TRSTP BIT(1) /* Trace Stop. Make 1 to stop trace. */
|
||||||
#define TRAXCTRL_PCMEN BIT(2) /* PC match enable */
|
#define TRAXCTRL_PCMEN BIT(2) /* PC match enable */
|
||||||
|
@ -512,6 +549,9 @@ static inline xtensa_dsr_t xtensa_dm_core_status_get(struct xtensa_debug_module
|
||||||
return dm->core_status.dsr;
|
return dm->core_status.dsr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int xtensa_dm_read(struct xtensa_debug_module *dm, uint32_t addr, uint32_t *val);
|
||||||
|
int xtensa_dm_write(struct xtensa_debug_module *dm, uint32_t addr, uint32_t val);
|
||||||
|
|
||||||
int xtensa_dm_device_id_read(struct xtensa_debug_module *dm);
|
int xtensa_dm_device_id_read(struct xtensa_debug_module *dm);
|
||||||
static inline xtensa_ocdid_t xtensa_dm_device_id_get(struct xtensa_debug_module *dm)
|
static inline xtensa_ocdid_t xtensa_dm_device_id_get(struct xtensa_debug_module *dm)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue