target: add Espressif ESP32-S2 basic support
[fw/openocd] / src / target / xtensa / xtensa_debug_module.h
1 /***************************************************************************
2  *   Xtensa debug module API                                               *
3  *   Copyright (C) 2019 Espressif Systems Ltd.                             *
4  *   <alexey@espressif.com>                                                *
5  *                                                                         *
6  *   Derived from original ESP8266 target.                                 *
7  *   Copyright (C) 2015 by Angus Gratton                                   *
8  *   gus@projectgus.com                                                    *
9  *                                                                         *
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.                                   *
14  *                                                                         *
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.                          *
19  *                                                                         *
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  ***************************************************************************/
23
24 #ifndef OPENOCD_TARGET_XTENSA_DEBUG_MODULE_H
25 #define OPENOCD_TARGET_XTENSA_DEBUG_MODULE_H
26
27 #include <jtag/jtag.h>
28 #include <helper/bits.h>
29 #include <target/target.h>
30
31 /* Virtual IDs for using with xtensa_power_ops API */
32 #define DMREG_PWRCTL       0x00
33 #define DMREG_PWRSTAT      0x01
34
35 /*
36  From the manual:
37  To properly use Debug registers through JTAG, software must ensure that:
38  - Tap is out of reset
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.
45 */
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)
52
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)
59
60 /* *** NAR addresses (also used as IDs for debug registers in xtensa_debug_ops API) ***
61  *TRAX registers */
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
76 /*... */
77 #define NARADR_PM7          0x2F
78 #define NARADR_PMCTRL0      0x30
79 /*... */
80 #define NARADR_PMCTRL7      0x37
81 #define NARADR_PMSTAT0      0x38
82 /*... */
83 #define NARADR_PMSTAT7      0x3F
84 /*OCD registers */
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
94 /*... */
95 #define NARADR_DIR7         0x4F
96 /*Misc registers */
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
110 /*... */
111 #define NARADR_PERID7       0x77
112 #define NARADR_PERID0       0x78
113 /*... */
114 #define NARADR_PERID3       0x7b
115 #define NARADR_COMPID0      0x7c
116 /*... */
117 #define NARADR_COMPID3      0x7f
118 #define NARADR_MAX          NARADR_COMPID3
119
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)
131
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)
152
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 */
159
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 */
181
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 */
195
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.*/
201
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
205                                                  *out-of-range */
206
207 #define XTENSA_MAX_PERF_COUNTERS    2
208 #define XTENSA_MAX_PERF_SELECT      32
209 #define XTENSA_MAX_PERF_MASK        0xffff
210
211 #define XTENSA_STOPMASK_DISABLED    UINT32_MAX
212
213 struct xtensa_debug_module;
214
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);
222 };
223
224 struct xtensa_power_ops {
225         /** register read. */
226         int (*queue_reg_read)(struct xtensa_debug_module *dm, unsigned int reg, uint8_t *data,
227                 uint8_t clear);
228         /** register write. */
229         int (*queue_reg_write)(struct xtensa_debug_module *dm, unsigned int reg, uint8_t data);
230 };
231
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;
236
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
241          * reset, */
242         /*       we can clear PWRSTAT_DEBUGWASRESET and PWRSTAT_COREWASRESET after reading will do
243          * the job; */
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;
247 };
248
249 struct xtensa_core_status {
250         xtensa_dsr_t dsr;
251 };
252
253 struct xtensa_trace_config {
254         uint32_t ctrl;
255         uint32_t memaddr_start;
256         uint32_t memaddr_end;
257         uint32_t addr;
258 };
259
260 struct xtensa_trace_status {
261         xtensa_traxstat_t stat;
262 };
263
264 struct xtensa_trace_start_config {
265         uint32_t stoppc;
266         bool after_is_words;
267         uint32_t after;
268         uint32_t stopmask;      /* UINT32_MAX: disable PC match option */
269 };
270
271 struct xtensa_perfmon_config {
272         int select;
273         uint32_t mask;
274         int kernelcnt;
275         int tracelevel;
276 };
277
278 struct xtensa_perfmon_result {
279         uint64_t value;
280         bool overflow;
281 };
282
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;
289 };
290
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;
297
298         struct xtensa_power_status power_status;
299         struct xtensa_core_status core_status;
300         xtensa_ocdid_t device_id;
301 };
302
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);
309
310 static inline void xtensa_dm_queue_tdi_idle(struct xtensa_debug_module *dm)
311 {
312         if (dm->queue_tdi_idle)
313                 dm->queue_tdi_idle(dm->queue_tdi_idle_arg);
314 }
315
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)
318 {
319         dm->power_status.prev_stat = 0;
320 }
321 static inline void xtensa_dm_power_status_cache(struct xtensa_debug_module *dm)
322 {
323         dm->power_status.prev_stat = dm->power_status.stath;
324 }
325 static inline xtensa_pwrstat_t xtensa_dm_power_status_get(struct xtensa_debug_module *dm)
326 {
327         return dm->power_status.stat;
328 }
329
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)
334 {
335         return dm->core_status.dsr;
336 }
337
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)
340 {
341         return dm->device_id;
342 }
343
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);
349
350 static inline bool xtensa_dm_is_online(struct xtensa_debug_module *dm)
351 {
352         int res = xtensa_dm_device_id_read(dm);
353         if (res != ERROR_OK)
354                 return false;
355         return (dm->device_id != 0xffffffff && dm->device_id != 0);
356 }
357
358 static inline bool xtensa_dm_tap_was_reset(struct xtensa_debug_module *dm)
359 {
360         return !(dm->power_status.prev_stat & PWRSTAT_DEBUGWASRESET) &&
361                dm->power_status.stat & PWRSTAT_DEBUGWASRESET;
362 }
363
364 static inline bool xtensa_dm_core_was_reset(struct xtensa_debug_module *dm)
365 {
366         return !(dm->power_status.prev_stat & PWRSTAT_COREWASRESET) &&
367                dm->power_status.stat & PWRSTAT_COREWASRESET;
368 }
369
370 static inline bool xtensa_dm_core_is_stalled(struct xtensa_debug_module *dm)
371 {
372         return dm->core_status.dsr & OCDDSR_RUNSTALLSAMPLE;
373 }
374
375 static inline bool xtensa_dm_is_powered(struct xtensa_debug_module *dm)
376 {
377         return dm->core_status.dsr & OCDDSR_DBGMODPOWERON;
378 }
379
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);
384
385 #endif  /* OPENOCD_TARGET_XTENSA_DEBUG_MODULE_H */