#define OPENOCD_TARGET_XTENSA_DEBUG_MODULE_H
#include <jtag/jtag.h>
+#include <target/arm_adi_v5.h>
#include <helper/bits.h>
#include <target/target.h>
Module to happen correctly. When it is set, any write to this bit clears it.
Either don't access it, or re-write it to 1 so JTAG accesses continue.
*/
-#define PWRCTL_JTAGDEBUGUSE BIT(7)
-#define PWRCTL_DEBUGRESET BIT(6)
-#define PWRCTL_CORERESET BIT(4)
-#define PWRCTL_DEBUGWAKEUP BIT(2)
-#define PWRCTL_MEMWAKEUP BIT(1)
-#define PWRCTL_COREWAKEUP BIT(0)
-
-#define PWRSTAT_DEBUGWASRESET BIT(6)
-#define PWRSTAT_COREWASRESET BIT(4)
-#define PWRSTAT_CORESTILLNEEDED BIT(3)
-#define PWRSTAT_DEBUGDOMAINON BIT(2)
-#define PWRSTAT_MEMDOMAINON BIT(1)
-#define PWRSTAT_COREDOMAINON BIT(0)
+#define PWRCTL_JTAGDEBUGUSE(x) (((x)->dbg_mod.dap) ? (0) : BIT(7))
+#define PWRCTL_DEBUGRESET(x) (((x)->dbg_mod.dap) ? BIT(28) : BIT(6))
+#define PWRCTL_CORERESET(x) (((x)->dbg_mod.dap) ? BIT(16) : BIT(4))
+#define PWRCTL_DEBUGWAKEUP(x) (((x)->dbg_mod.dap) ? BIT(12) : BIT(2))
+#define PWRCTL_MEMWAKEUP(x) (((x)->dbg_mod.dap) ? BIT(8) : BIT(1))
+#define PWRCTL_COREWAKEUP(x) (((x)->dbg_mod.dap) ? BIT(0) : BIT(0))
+
+#define PWRSTAT_DEBUGWASRESET_DM(d) (((d)->dap) ? BIT(28) : BIT(6))
+#define PWRSTAT_COREWASRESET_DM(d) (((d)->dap) ? BIT(16) : BIT(4))
+#define PWRSTAT_DEBUGWASRESET(x) (PWRSTAT_DEBUGWASRESET_DM(&((x)->dbg_mod)))
+#define PWRSTAT_COREWASRESET(x) (PWRSTAT_COREWASRESET_DM(&((x)->dbg_mod)))
+#define PWRSTAT_CORESTILLNEEDED(x) (((x)->dbg_mod.dap) ? BIT(4) : BIT(3))
+#define PWRSTAT_DEBUGDOMAINON(x) (((x)->dbg_mod.dap) ? BIT(12) : BIT(2))
+#define PWRSTAT_MEMDOMAINON(x) (((x)->dbg_mod.dap) ? BIT(8) : BIT(1))
+#define PWRSTAT_COREDOMAINON(x) (((x)->dbg_mod.dap) ? BIT(0) : BIT(0))
+
/* Virtual IDs for using with xtensa_debug_ops API */
enum xtensa_dm_reg {
/* TRAX Registers */
XDMREG_DELAYCNT,
XDMREG_MEMADDRSTART,
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 */
XDMREG_PMG,
{ .nar = 0x07, .apb = 0x001c }, /* XDMREG_DELAYCNT */ \
{ .nar = 0x08, .apb = 0x0020 }, /* XDMREG_MEMADDRSTART */ \
{ .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 */ \
{ .nar = 0x20, .apb = 0x1000 }, /* XDMREG_PMG */ \
{ .nar = 0x7f, .apb = 0x3ffc }, /* XDMREG_COMPID3 */ \
}
-#define XTENSA_DM_APB_MASK (0x3fff)
+#define XTENSA_DM_APB_ALIGN 0x4000
/* OCD registers, bit definitions */
#define OCDDCR_ENABLEOCD BIT(0)
#define OCDDCR_DEBUGINTERRUPT BIT(1)
#define OCDDCR_INTERRUPTALLCONDS BIT(2)
+#define OCDDCR_STEPREQUEST BIT(3) /* NX only */
#define OCDDCR_BREAKINEN BIT(16)
#define OCDDCR_BREAKOUTEN BIT(17)
#define OCDDCR_DEBUGSWACTIVE BIT(20)
#define OCDDSR_EXECBUSY BIT(2)
#define OCDDSR_EXECOVERRUN BIT(3)
#define OCDDSR_STOPPED BIT(4)
+#define OCDDSR_STOPCAUSE (0xF << 5) /* NX only */
+#define OCDDSR_STOPCAUSE_SHIFT (5) /* NX only */
#define OCDDSR_COREWROTEDDR BIT(10)
#define OCDDSR_COREREADDDR BIT(11)
#define OCDDSR_HOSTWROTEDDR BIT(14)
#define OCDDSR_BREAKINITI BIT(26)
#define OCDDSR_DBGMODPOWERON BIT(31)
+/* NX stop cause */
+#define OCDDSR_STOPCAUSE_DI (0) /* Debug Interrupt */
+#define OCDDSR_STOPCAUSE_SS (1) /* Single-step completed */
+#define OCDDSR_STOPCAUSE_IB (2) /* HW breakpoint (IBREAKn match) */
+#define OCDDSR_STOPCAUSE_B1 (4) /* SW breakpoint (BREAK.1 instruction) */
+#define OCDDSR_STOPCAUSE_BN (5) /* SW breakpoint (BREAK.N instruction) */
+#define OCDDSR_STOPCAUSE_B (6) /* SW breakpoint (BREAK instruction) */
+#define OCDDSR_STOPCAUSE_DB0 (8) /* HW watchpoint (DBREAK0 match) */
+#define OCDDSR_STOPCAUSE_DB1 (9) /* HW watchpoint (DBREAK0 match) */
+
+/* LX stop cause */
#define DEBUGCAUSE_IC BIT(0) /* ICOUNT exception */
#define DEBUGCAUSE_IB BIT(1) /* IBREAK exception */
#define DEBUGCAUSE_DB BIT(2) /* DBREAK exception */
#define DEBUGCAUSE_BI BIT(3) /* BREAK instruction encountered */
#define DEBUGCAUSE_BN BIT(4) /* BREAK.N instruction encountered */
#define DEBUGCAUSE_DI BIT(5) /* Debug Interrupt */
+#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_TRSTP BIT(1) /* Trace Stop. Make 1 to stop trace. */
struct xtensa_debug_module_config {
const struct xtensa_power_ops *pwr_ops;
const struct xtensa_debug_ops *dbg_ops;
+
+ /* Either JTAG or DAP structures will be populated */
struct jtag_tap *tap;
void (*queue_tdi_idle)(struct target *target);
void *queue_tdi_idle_arg;
+
+ /* For targets conforming to ARM Debug Interface v5,
+ * "dap" references the Debug Access Port (DAP)
+ * used to make requests to the target;
+ * "debug_ap" is AP instance connected to processor
+ */
+ struct adiv5_dap *dap;
+ struct adiv5_ap *debug_ap;
+ int debug_apsel;
+ uint32_t ap_offset;
};
struct xtensa_debug_module {
const struct xtensa_power_ops *pwr_ops;
const struct xtensa_debug_ops *dbg_ops;
+
+ /* Either JTAG or DAP structures will be populated */
struct jtag_tap *tap;
void (*queue_tdi_idle)(struct target *target);
void *queue_tdi_idle_arg;
+ /* DAP struct; AP instance connected to processor */
+ struct adiv5_dap *dap;
+ struct adiv5_ap *debug_ap;
+ int debug_apsel;
+
struct xtensa_power_status power_status;
struct xtensa_core_status core_status;
xtensa_ocdid_t device_id;
+ uint32_t ap_offset;
};
int xtensa_dm_init(struct xtensa_debug_module *dm, const struct xtensa_debug_module_config *cfg);
+void xtensa_dm_deinit(struct xtensa_debug_module *dm);
+int xtensa_dm_poll(struct xtensa_debug_module *dm);
+int xtensa_dm_examine(struct xtensa_debug_module *dm);
int xtensa_dm_queue_enable(struct xtensa_debug_module *dm);
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);
static inline int xtensa_dm_queue_execute(struct xtensa_debug_module *dm)
{
- return jtag_execute_queue();
+ return dm->dap ? dap_run(dm->dap) : jtag_execute_queue();
}
static inline void xtensa_dm_queue_tdi_idle(struct xtensa_debug_module *dm)
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);
static inline xtensa_ocdid_t xtensa_dm_device_id_get(struct xtensa_debug_module *dm)
{
static inline bool xtensa_dm_tap_was_reset(struct xtensa_debug_module *dm)
{
- return !(dm->power_status.prev_stat & PWRSTAT_DEBUGWASRESET) &&
- dm->power_status.stat & PWRSTAT_DEBUGWASRESET;
+ return !(dm->power_status.prev_stat & PWRSTAT_DEBUGWASRESET_DM(dm)) &&
+ dm->power_status.stat & PWRSTAT_DEBUGWASRESET_DM(dm);
}
static inline bool xtensa_dm_core_was_reset(struct xtensa_debug_module *dm)
{
- return !(dm->power_status.prev_stat & PWRSTAT_COREWASRESET) &&
- dm->power_status.stat & PWRSTAT_COREWASRESET;
+ return !(dm->power_status.prev_stat & PWRSTAT_COREWASRESET_DM(dm)) &&
+ dm->power_status.stat & PWRSTAT_COREWASRESET_DM(dm);
}
static inline bool xtensa_dm_core_is_stalled(struct xtensa_debug_module *dm)