1 /* SPDX-License-Identifier: GPL-2.0-or-later */
3 /***************************************************************************
4 * Xtensa debug module API *
5 * Copyright (C) 2019 Espressif Systems Ltd. *
6 * Derived from original ESP8266 target. *
7 * Author: Angus Gratton gus@projectgus.com *
8 ***************************************************************************/
10 #ifndef OPENOCD_TARGET_XTENSA_DEBUG_MODULE_H
11 #define OPENOCD_TARGET_XTENSA_DEBUG_MODULE_H
13 #include <jtag/jtag.h>
14 #include <helper/bits.h>
15 #include <target/target.h>
17 /* Virtual IDs for using with xtensa_power_ops API */
18 #define DMREG_PWRCTL 0x00
19 #define DMREG_PWRSTAT 0x01
23 To properly use Debug registers through JTAG, software must ensure that:
25 - Xtensa Debug Module is out of reset
26 - Other bits of PWRCTL are set to their desired values, and finally
27 - JtagDebugUse transitions from 0 to 1
28 The bit must continue to be 1 in order for JTAG accesses to the Debug
29 Module to happen correctly. When it is set, any write to this bit clears it.
30 Either don't access it, or re-write it to 1 so JTAG accesses continue.
32 #define PWRCTL_JTAGDEBUGUSE BIT(7)
33 #define PWRCTL_DEBUGRESET BIT(6)
34 #define PWRCTL_CORERESET BIT(4)
35 #define PWRCTL_DEBUGWAKEUP BIT(2)
36 #define PWRCTL_MEMWAKEUP BIT(1)
37 #define PWRCTL_COREWAKEUP BIT(0)
39 #define PWRSTAT_DEBUGWASRESET BIT(6)
40 #define PWRSTAT_COREWASRESET BIT(4)
41 #define PWRSTAT_CORESTILLNEEDED BIT(3)
42 #define PWRSTAT_DEBUGDOMAINON BIT(2)
43 #define PWRSTAT_MEMDOMAINON BIT(1)
44 #define PWRSTAT_COREDOMAINON BIT(0)
46 /* *** NAR addresses (also used as IDs for debug registers in xtensa_debug_ops API) ***
48 #define NARADR_TRAXID 0x00
49 #define NARADR_TRAXCTRL 0x01
50 #define NARADR_TRAXSTAT 0x02
51 #define NARADR_TRAXDATA 0x03
52 #define NARADR_TRAXADDR 0x04
53 #define NARADR_TRIGGERPC 0x05
54 #define NARADR_PCMATCHCTRL 0x06
55 #define NARADR_DELAYCNT 0x07
56 #define NARADR_MEMADDRSTART 0x08
57 #define NARADR_MEMADDREND 0x09
58 /*Performance monitor registers */
59 #define NARADR_PMG 0x20
60 #define NARADR_INTPC 0x24
61 #define NARADR_PM0 0x28
63 #define NARADR_PM7 0x2F
64 #define NARADR_PMCTRL0 0x30
66 #define NARADR_PMCTRL7 0x37
67 #define NARADR_PMSTAT0 0x38
69 #define NARADR_PMSTAT7 0x3F
71 #define NARADR_OCDID 0x40
72 #define NARADR_DCRCLR 0x42
73 #define NARADR_DCRSET 0x43
74 #define NARADR_DSR 0x44
75 #define NARADR_DDR 0x45
76 #define NARADR_DDREXEC 0x46
77 #define NARADR_DIR0EXEC 0x47
78 #define NARADR_DIR0 0x48
79 #define NARADR_DIR1 0x49
81 #define NARADR_DIR7 0x4F
83 #define NARADR_PWRCTL 0x58
84 #define NARADR_PWRSTAT 0x59
85 #define NARADR_ERISTAT 0x5A
86 /*CoreSight registers */
87 #define NARADR_ITCTRL 0x60
88 #define NARADR_CLAIMSET 0x68
89 #define NARADR_CLAIMCLR 0x69
90 #define NARADR_LOCKACCESS 0x6c
91 #define NARADR_LOCKSTATUS 0x6d
92 #define NARADR_AUTHSTATUS 0x6e
93 #define NARADR_DEVID 0x72
94 #define NARADR_DEVTYPE 0x73
95 #define NARADR_PERID4 0x74
97 #define NARADR_PERID7 0x77
98 #define NARADR_PERID0 0x78
100 #define NARADR_PERID3 0x7b
101 #define NARADR_COMPID0 0x7c
103 #define NARADR_COMPID3 0x7f
104 #define NARADR_MAX NARADR_COMPID3
106 /*OCD registers, bit definitions */
107 #define OCDDCR_ENABLEOCD BIT(0)
108 #define OCDDCR_DEBUGINTERRUPT BIT(1)
109 #define OCDDCR_INTERRUPTALLCONDS BIT(2)
110 #define OCDDCR_BREAKINEN BIT(16)
111 #define OCDDCR_BREAKOUTEN BIT(17)
112 #define OCDDCR_DEBUGSWACTIVE BIT(20)
113 #define OCDDCR_RUNSTALLINEN BIT(21)
114 #define OCDDCR_DEBUGMODEOUTEN BIT(22)
115 #define OCDDCR_BREAKOUTITO BIT(24)
116 #define OCDDCR_BREAKACKITO BIT(25)
118 #define OCDDSR_EXECDONE BIT(0)
119 #define OCDDSR_EXECEXCEPTION BIT(1)
120 #define OCDDSR_EXECBUSY BIT(2)
121 #define OCDDSR_EXECOVERRUN BIT(3)
122 #define OCDDSR_STOPPED BIT(4)
123 #define OCDDSR_COREWROTEDDR BIT(10)
124 #define OCDDSR_COREREADDDR BIT(11)
125 #define OCDDSR_HOSTWROTEDDR BIT(14)
126 #define OCDDSR_HOSTREADDDR BIT(15)
127 #define OCDDSR_DEBUGPENDBREAK BIT(16)
128 #define OCDDSR_DEBUGPENDHOST BIT(17)
129 #define OCDDSR_DEBUGPENDTRAX BIT(18)
130 #define OCDDSR_DEBUGINTBREAK BIT(20)
131 #define OCDDSR_DEBUGINTHOST BIT(21)
132 #define OCDDSR_DEBUGINTTRAX BIT(22)
133 #define OCDDSR_RUNSTALLTOGGLE BIT(23)
134 #define OCDDSR_RUNSTALLSAMPLE BIT(24)
135 #define OCDDSR_BREACKOUTACKITI BIT(25)
136 #define OCDDSR_BREAKINITI BIT(26)
137 #define OCDDSR_DBGMODPOWERON BIT(31)
139 #define DEBUGCAUSE_IC BIT(0) /* ICOUNT exception */
140 #define DEBUGCAUSE_IB BIT(1) /* IBREAK exception */
141 #define DEBUGCAUSE_DB BIT(2) /* DBREAK exception */
142 #define DEBUGCAUSE_BI BIT(3) /* BREAK instruction encountered */
143 #define DEBUGCAUSE_BN BIT(4) /* BREAK.N instruction encountered */
144 #define DEBUGCAUSE_DI BIT(5) /* Debug Interrupt */
146 #define TRAXCTRL_TREN BIT(0) /* Trace enable. Tracing starts on 0->1 */
147 #define TRAXCTRL_TRSTP BIT(1) /* Trace Stop. Make 1 to stop trace. */
148 #define TRAXCTRL_PCMEN BIT(2) /* PC match enable */
149 #define TRAXCTRL_PTIEN BIT(4) /* Processor-trigger enable */
150 #define TRAXCTRL_CTIEN BIT(5) /* Cross-trigger enable */
151 #define TRAXCTRL_TMEN BIT(7) /* Tracemem Enable. Always set. */
152 #define TRAXCTRL_CNTU BIT(9) /* Post-stop-trigger countdown units; selects when DelayCount-- happens.
153 *0 - every 32-bit word written to tracemem, 1 - every cpu instruction */
154 #define TRAXCTRL_TSEN BIT(11) /* Undocumented/deprecated? */
155 #define TRAXCTRL_SMPER_SHIFT 12 /* Send sync every 2^(9-smper) messages. 7=reserved, 0=no sync msg */
156 #define TRAXCTRL_SMPER_MASK 0x07 /* Synchronization message period */
157 #define TRAXCTRL_PTOWT BIT(16) /* Processor Trigger Out (OCD halt) enabled when stop triggered */
158 #define TRAXCTRL_PTOWS BIT(17) /* Processor Trigger Out (OCD halt) enabled when trace stop completes */
159 #define TRAXCTRL_CTOWT BIT(20) /* Cross-trigger Out enabled when stop triggered */
160 #define TRAXCTRL_CTOWS BIT(21) /* Cross-trigger Out enabled when trace stop completes */
161 #define TRAXCTRL_ITCTO BIT(22) /* Integration mode: cross-trigger output */
162 #define TRAXCTRL_ITCTIA BIT(23) /* Integration mode: cross-trigger ack */
163 #define TRAXCTRL_ITATV BIT(24) /* replaces ATID when in integration mode: ATVALID output */
164 #define TRAXCTRL_ATID_MASK 0x7F /* ARB source ID */
165 #define TRAXCTRL_ATID_SHIFT 24
166 #define TRAXCTRL_ATEN BIT(31) /* ATB interface enable */
168 #define TRAXSTAT_TRACT BIT(0) /* Trace active flag. */
169 #define TRAXSTAT_TRIG BIT(1) /* Trace stop trigger. Clears on TREN 1->0 */
170 #define TRAXSTAT_PCMTG BIT(2) /* Stop trigger caused by PC match. Clears on TREN 1->0 */
171 #define TRAXSTAT_PJTR BIT(3) /* JTAG transaction result. 1=err in preceding jtag transaction. */
172 #define TRAXSTAT_PTITG BIT(4) /* Stop trigger caused by Processor Trigger Input.Clears on TREN 1->0 */
173 #define TRAXSTAT_CTITG BIT(5) /* Stop trigger caused by Cross-Trigger Input. Clears on TREN 1->0 */
174 #define TRAXSTAT_MEMSZ_SHIFT 8 /* Traceram size inducator. Usable trace ram is 2^MEMSZ bytes. */
175 #define TRAXSTAT_MEMSZ_MASK 0x1F
176 #define TRAXSTAT_PTO BIT(16) /* Processor Trigger Output: current value */
177 #define TRAXSTAT_CTO BIT(17) /* Cross-Trigger Output: current value */
178 #define TRAXSTAT_ITCTOA BIT(22) /* Cross-Trigger Out Ack: current value */
179 #define TRAXSTAT_ITCTI BIT(23) /* Cross-Trigger Input: current value */
180 #define TRAXSTAT_ITATR BIT(24) /* ATREADY Input: current value */
182 #define TRAXADDR_TADDR_SHIFT 0 /* Trax memory address, in 32-bit words. */
183 #define TRAXADDR_TADDR_MASK 0x1FFFFF /* Actually is only as big as the trace buffer size max addr. */
184 #define TRAXADDR_TWRAP_SHIFT 21 /* Amount of times TADDR has overflown */
185 #define TRAXADDR_TWRAP_MASK 0x3FF
186 #define TRAXADDR_TWSAT BIT(31) /* 1 if TWRAP has overflown, clear by disabling tren.*/
188 #define PCMATCHCTRL_PCML_SHIFT 0 /* Amount of lower bits to ignore in pc trigger register */
189 #define PCMATCHCTRL_PCML_MASK 0x1F
190 #define PCMATCHCTRL_PCMS BIT(31) /* PC Match Sense, 0-match when procs PC is in-range, 1-match when
193 #define XTENSA_MAX_PERF_COUNTERS 2
194 #define XTENSA_MAX_PERF_SELECT 32
195 #define XTENSA_MAX_PERF_MASK 0xffff
197 #define XTENSA_STOPMASK_DISABLED UINT32_MAX
199 struct xtensa_debug_module;
201 struct xtensa_debug_ops {
202 /** enable operation */
203 int (*queue_enable)(struct xtensa_debug_module *dm);
204 /** register read. */
205 int (*queue_reg_read)(struct xtensa_debug_module *dm, unsigned int reg, uint8_t *data);
206 /** register write. */
207 int (*queue_reg_write)(struct xtensa_debug_module *dm, unsigned int reg, uint32_t data);
210 struct xtensa_power_ops {
211 /** register read. */
212 int (*queue_reg_read)(struct xtensa_debug_module *dm, unsigned int reg, uint8_t *data,
214 /** register write. */
215 int (*queue_reg_write)(struct xtensa_debug_module *dm, unsigned int reg, uint8_t data);
218 typedef uint8_t xtensa_pwrstat_t;
219 typedef uint32_t xtensa_ocdid_t;
220 typedef uint32_t xtensa_dsr_t;
221 typedef uint32_t xtensa_traxstat_t;
223 struct xtensa_power_status {
224 xtensa_pwrstat_t stat;
225 xtensa_pwrstat_t stath;
226 /* TODO: do not need to keep previous status to detect that core or debug module has been
228 /* we can clear PWRSTAT_DEBUGWASRESET and PWRSTAT_COREWASRESET after reading will do
230 /* upon next reet those bits will be set again. So we can get rid of
231 * xtensa_dm_power_status_cache_reset() and xtensa_dm_power_status_cache(). */
232 xtensa_pwrstat_t prev_stat;
235 struct xtensa_core_status {
239 struct xtensa_trace_config {
241 uint32_t memaddr_start;
242 uint32_t memaddr_end;
246 struct xtensa_trace_status {
247 xtensa_traxstat_t stat;
250 struct xtensa_trace_start_config {
254 uint32_t stopmask; /* UINT32_MAX: disable PC match option */
257 struct xtensa_perfmon_config {
264 struct xtensa_perfmon_result {
269 struct xtensa_debug_module_config {
270 const struct xtensa_power_ops *pwr_ops;
271 const struct xtensa_debug_ops *dbg_ops;
272 struct jtag_tap *tap;
273 void (*queue_tdi_idle)(struct target *target);
274 void *queue_tdi_idle_arg;
277 struct xtensa_debug_module {
278 const struct xtensa_power_ops *pwr_ops;
279 const struct xtensa_debug_ops *dbg_ops;
280 struct jtag_tap *tap;
281 void (*queue_tdi_idle)(struct target *target);
282 void *queue_tdi_idle_arg;
284 struct xtensa_power_status power_status;
285 struct xtensa_core_status core_status;
286 xtensa_ocdid_t device_id;
289 int xtensa_dm_init(struct xtensa_debug_module *dm, const struct xtensa_debug_module_config *cfg);
290 int xtensa_dm_queue_enable(struct xtensa_debug_module *dm);
291 int xtensa_dm_queue_reg_read(struct xtensa_debug_module *dm, unsigned int reg, uint8_t *value);
292 int xtensa_dm_queue_reg_write(struct xtensa_debug_module *dm, unsigned int reg, uint32_t value);
293 int xtensa_dm_queue_pwr_reg_read(struct xtensa_debug_module *dm, unsigned int reg, uint8_t *data, uint8_t clear);
294 int xtensa_dm_queue_pwr_reg_write(struct xtensa_debug_module *dm, unsigned int reg, uint8_t data);
296 static inline void xtensa_dm_queue_tdi_idle(struct xtensa_debug_module *dm)
298 if (dm->queue_tdi_idle)
299 dm->queue_tdi_idle(dm->queue_tdi_idle_arg);
302 int xtensa_dm_power_status_read(struct xtensa_debug_module *dm, uint32_t clear);
303 static inline void xtensa_dm_power_status_cache_reset(struct xtensa_debug_module *dm)
305 dm->power_status.prev_stat = 0;
307 static inline void xtensa_dm_power_status_cache(struct xtensa_debug_module *dm)
309 dm->power_status.prev_stat = dm->power_status.stath;
311 static inline xtensa_pwrstat_t xtensa_dm_power_status_get(struct xtensa_debug_module *dm)
313 return dm->power_status.stat;
316 int xtensa_dm_core_status_read(struct xtensa_debug_module *dm);
317 int xtensa_dm_core_status_clear(struct xtensa_debug_module *dm, xtensa_dsr_t bits);
318 int xtensa_dm_core_status_check(struct xtensa_debug_module *dm);
319 static inline xtensa_dsr_t xtensa_dm_core_status_get(struct xtensa_debug_module *dm)
321 return dm->core_status.dsr;
324 int xtensa_dm_device_id_read(struct xtensa_debug_module *dm);
325 static inline xtensa_ocdid_t xtensa_dm_device_id_get(struct xtensa_debug_module *dm)
327 return dm->device_id;
330 int xtensa_dm_trace_start(struct xtensa_debug_module *dm, struct xtensa_trace_start_config *cfg);
331 int xtensa_dm_trace_stop(struct xtensa_debug_module *dm, bool pto_enable);
332 int xtensa_dm_trace_config_read(struct xtensa_debug_module *dm, struct xtensa_trace_config *config);
333 int xtensa_dm_trace_status_read(struct xtensa_debug_module *dm, struct xtensa_trace_status *status);
334 int xtensa_dm_trace_data_read(struct xtensa_debug_module *dm, uint8_t *dest, uint32_t size);
336 static inline bool xtensa_dm_is_online(struct xtensa_debug_module *dm)
338 int res = xtensa_dm_device_id_read(dm);
341 return (dm->device_id != 0xffffffff && dm->device_id != 0);
344 static inline bool xtensa_dm_tap_was_reset(struct xtensa_debug_module *dm)
346 return !(dm->power_status.prev_stat & PWRSTAT_DEBUGWASRESET) &&
347 dm->power_status.stat & PWRSTAT_DEBUGWASRESET;
350 static inline bool xtensa_dm_core_was_reset(struct xtensa_debug_module *dm)
352 return !(dm->power_status.prev_stat & PWRSTAT_COREWASRESET) &&
353 dm->power_status.stat & PWRSTAT_COREWASRESET;
356 static inline bool xtensa_dm_core_is_stalled(struct xtensa_debug_module *dm)
358 return dm->core_status.dsr & OCDDSR_RUNSTALLSAMPLE;
361 static inline bool xtensa_dm_is_powered(struct xtensa_debug_module *dm)
363 return dm->core_status.dsr & OCDDSR_DBGMODPOWERON;
366 int xtensa_dm_perfmon_enable(struct xtensa_debug_module *dm, int counter_id,
367 const struct xtensa_perfmon_config *config);
368 int xtensa_dm_perfmon_dump(struct xtensa_debug_module *dm, int counter_id,
369 struct xtensa_perfmon_result *out_result);
371 #endif /* OPENOCD_TARGET_XTENSA_DEBUG_MODULE_H */