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