189a6c97a8e3f6514d3e05a98225944c1751af20
[fw/openocd] / src / target / xtensa / xtensa_debug_module.h
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2
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  ***************************************************************************/
9
10 #ifndef OPENOCD_TARGET_XTENSA_DEBUG_MODULE_H
11 #define OPENOCD_TARGET_XTENSA_DEBUG_MODULE_H
12
13 #include <jtag/jtag.h>
14 #include <helper/bits.h>
15 #include <target/target.h>
16
17 /* Virtual IDs for using with xtensa_power_ops API */
18 #define DMREG_PWRCTL       0x00
19 #define DMREG_PWRSTAT      0x01
20
21 /*
22  From the manual:
23  To properly use Debug registers through JTAG, software must ensure that:
24  - Tap is out of reset
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.
31 */
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)
38
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)
45
46 /* *** NAR addresses (also used as IDs for debug registers in xtensa_debug_ops API) ***
47  *TRAX registers */
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
62 /*... */
63 #define NARADR_PM7          0x2F
64 #define NARADR_PMCTRL0      0x30
65 /*... */
66 #define NARADR_PMCTRL7      0x37
67 #define NARADR_PMSTAT0      0x38
68 /*... */
69 #define NARADR_PMSTAT7      0x3F
70 /*OCD registers */
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
80 /*... */
81 #define NARADR_DIR7         0x4F
82 /*Misc registers */
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
96 /*... */
97 #define NARADR_PERID7       0x77
98 #define NARADR_PERID0       0x78
99 /*... */
100 #define NARADR_PERID3       0x7b
101 #define NARADR_COMPID0      0x7c
102 /*... */
103 #define NARADR_COMPID3      0x7f
104 #define NARADR_MAX          NARADR_COMPID3
105
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)
117
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)
138
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 */
145
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 */
167
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 */
181
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.*/
187
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
191                                                  *out-of-range */
192
193 #define XTENSA_MAX_PERF_COUNTERS    2
194 #define XTENSA_MAX_PERF_SELECT      32
195 #define XTENSA_MAX_PERF_MASK        0xffff
196
197 #define XTENSA_STOPMASK_DISABLED    UINT32_MAX
198
199 struct xtensa_debug_module;
200
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);
208 };
209
210 struct xtensa_power_ops {
211         /** register read. */
212         int (*queue_reg_read)(struct xtensa_debug_module *dm, unsigned int reg, uint8_t *data,
213                 uint8_t clear);
214         /** register write. */
215         int (*queue_reg_write)(struct xtensa_debug_module *dm, unsigned int reg, uint8_t data);
216 };
217
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;
222
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
227          * reset, */
228         /*       we can clear PWRSTAT_DEBUGWASRESET and PWRSTAT_COREWASRESET after reading will do
229          * the job; */
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;
233 };
234
235 struct xtensa_core_status {
236         xtensa_dsr_t dsr;
237 };
238
239 struct xtensa_trace_config {
240         uint32_t ctrl;
241         uint32_t memaddr_start;
242         uint32_t memaddr_end;
243         uint32_t addr;
244 };
245
246 struct xtensa_trace_status {
247         xtensa_traxstat_t stat;
248 };
249
250 struct xtensa_trace_start_config {
251         uint32_t stoppc;
252         bool after_is_words;
253         uint32_t after;
254         uint32_t stopmask;      /* UINT32_MAX: disable PC match option */
255 };
256
257 struct xtensa_perfmon_config {
258         int select;
259         uint32_t mask;
260         int kernelcnt;
261         int tracelevel;
262 };
263
264 struct xtensa_perfmon_result {
265         uint64_t value;
266         bool overflow;
267 };
268
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;
275 };
276
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;
283
284         struct xtensa_power_status power_status;
285         struct xtensa_core_status core_status;
286         xtensa_ocdid_t device_id;
287 };
288
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);
295
296 static inline void xtensa_dm_queue_tdi_idle(struct xtensa_debug_module *dm)
297 {
298         if (dm->queue_tdi_idle)
299                 dm->queue_tdi_idle(dm->queue_tdi_idle_arg);
300 }
301
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)
304 {
305         dm->power_status.prev_stat = 0;
306 }
307 static inline void xtensa_dm_power_status_cache(struct xtensa_debug_module *dm)
308 {
309         dm->power_status.prev_stat = dm->power_status.stath;
310 }
311 static inline xtensa_pwrstat_t xtensa_dm_power_status_get(struct xtensa_debug_module *dm)
312 {
313         return dm->power_status.stat;
314 }
315
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)
320 {
321         return dm->core_status.dsr;
322 }
323
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)
326 {
327         return dm->device_id;
328 }
329
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);
335
336 static inline bool xtensa_dm_is_online(struct xtensa_debug_module *dm)
337 {
338         int res = xtensa_dm_device_id_read(dm);
339         if (res != ERROR_OK)
340                 return false;
341         return (dm->device_id != 0xffffffff && dm->device_id != 0);
342 }
343
344 static inline bool xtensa_dm_tap_was_reset(struct xtensa_debug_module *dm)
345 {
346         return !(dm->power_status.prev_stat & PWRSTAT_DEBUGWASRESET) &&
347                dm->power_status.stat & PWRSTAT_DEBUGWASRESET;
348 }
349
350 static inline bool xtensa_dm_core_was_reset(struct xtensa_debug_module *dm)
351 {
352         return !(dm->power_status.prev_stat & PWRSTAT_COREWASRESET) &&
353                dm->power_status.stat & PWRSTAT_COREWASRESET;
354 }
355
356 static inline bool xtensa_dm_core_is_stalled(struct xtensa_debug_module *dm)
357 {
358         return dm->core_status.dsr & OCDDSR_RUNSTALLSAMPLE;
359 }
360
361 static inline bool xtensa_dm_is_powered(struct xtensa_debug_module *dm)
362 {
363         return dm->core_status.dsr & OCDDSR_DBGMODPOWERON;
364 }
365
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);
370
371 #endif  /* OPENOCD_TARGET_XTENSA_DEBUG_MODULE_H */