target/xtensa: virtualize XDM registers
[fw/openocd] / src / target / xtensa / xtensa_debug_module.h
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2
3 /***************************************************************************
4  *   Xtensa Debug Module (XDM) Support for OpenOCD                         *
5  *   Copyright (C) 2020-2022 Cadence Design Systems, Inc.                  *
6  *   Copyright (C) 2019 Espressif Systems Ltd.                             *
7  *   Derived from original ESP8266 target.                                 *
8  *   Author: Angus Gratton gus@projectgus.com                              *
9  ***************************************************************************/
10
11 #ifndef OPENOCD_TARGET_XTENSA_DEBUG_MODULE_H
12 #define OPENOCD_TARGET_XTENSA_DEBUG_MODULE_H
13
14 #include <jtag/jtag.h>
15 #include <helper/bits.h>
16 #include <target/target.h>
17
18 /* Virtual IDs for using with xtensa_power_ops API */
19 enum xtensa_dm_pwr_reg {
20         XDMREG_PWRCTL = 0x00,
21         XDMREG_PWRSTAT,
22         XDMREG_PWRNUM
23 };
24
25 /* Debug Module Power Register offsets within APB */
26 struct xtensa_dm_pwr_reg_offsets {
27         uint16_t apb;
28 };
29
30 /* Debug Module Power Register offset structure; must include XDMREG_PWRNUM entries */
31 #define XTENSA_DM_PWR_REG_OFFSETS       {                               \
32         /* Power/Reset Registers */                                             \
33         { .apb = 0x3020 },              /* XDMREG_PWRCTL */             \
34         { .apb = 0x3024 },              /* XDMREG_PWRSTAT */    \
35 }
36
37 /*
38  From the manual:
39  To properly use Debug registers through JTAG, software must ensure that:
40  - Tap is out of reset
41  - Xtensa Debug Module is out of reset
42  - Other bits of PWRCTL are set to their desired values, and finally
43  - JtagDebugUse transitions from 0 to 1
44  The bit must continue to be 1 in order for JTAG accesses to the Debug
45  Module to happen correctly. When it is set, any write to this bit clears it.
46  Either don't access it, or re-write it to 1 so JTAG accesses continue.
47 */
48 #define PWRCTL_JTAGDEBUGUSE     BIT(7)
49 #define PWRCTL_DEBUGRESET       BIT(6)
50 #define PWRCTL_CORERESET        BIT(4)
51 #define PWRCTL_DEBUGWAKEUP      BIT(2)
52 #define PWRCTL_MEMWAKEUP        BIT(1)
53 #define PWRCTL_COREWAKEUP       BIT(0)
54
55 #define PWRSTAT_DEBUGWASRESET   BIT(6)
56 #define PWRSTAT_COREWASRESET    BIT(4)
57 #define PWRSTAT_CORESTILLNEEDED BIT(3)
58 #define PWRSTAT_DEBUGDOMAINON   BIT(2)
59 #define PWRSTAT_MEMDOMAINON     BIT(1)
60 #define PWRSTAT_COREDOMAINON    BIT(0)
61 /* Virtual IDs for using with xtensa_debug_ops API */
62 enum xtensa_dm_reg {
63         /* TRAX Registers */
64         XDMREG_TRAXID = 0x00,
65         XDMREG_TRAXCTRL,
66         XDMREG_TRAXSTAT,
67         XDMREG_TRAXDATA,
68         XDMREG_TRAXADDR,
69         XDMREG_TRIGGERPC,
70         XDMREG_PCMATCHCTRL,
71         XDMREG_DELAYCNT,
72         XDMREG_MEMADDRSTART,
73         XDMREG_MEMADDREND,
74
75         /* Performance Monitor Registers */
76         XDMREG_PMG,
77         XDMREG_INTPC,
78         XDMREG_PM0,
79         XDMREG_PM1,
80         XDMREG_PM2,
81         XDMREG_PM3,
82         XDMREG_PM4,
83         XDMREG_PM5,
84         XDMREG_PM6,
85         XDMREG_PM7,
86         XDMREG_PMCTRL0,
87         XDMREG_PMCTRL1,
88         XDMREG_PMCTRL2,
89         XDMREG_PMCTRL3,
90         XDMREG_PMCTRL4,
91         XDMREG_PMCTRL5,
92         XDMREG_PMCTRL6,
93         XDMREG_PMCTRL7,
94         XDMREG_PMSTAT0,
95         XDMREG_PMSTAT1,
96         XDMREG_PMSTAT2,
97         XDMREG_PMSTAT3,
98         XDMREG_PMSTAT4,
99         XDMREG_PMSTAT5,
100         XDMREG_PMSTAT6,
101         XDMREG_PMSTAT7,
102
103         /* OCD Registers */
104         XDMREG_OCDID,
105         XDMREG_DCRCLR,
106         XDMREG_DCRSET,
107         XDMREG_DSR,
108         XDMREG_DDR,
109         XDMREG_DDREXEC,
110         XDMREG_DIR0EXEC,
111         XDMREG_DIR0,
112         XDMREG_DIR1,
113         XDMREG_DIR2,
114         XDMREG_DIR3,
115         XDMREG_DIR4,
116         XDMREG_DIR5,
117         XDMREG_DIR6,
118         XDMREG_DIR7,
119
120         /* Misc Registers */
121         XDMREG_ERISTAT,
122
123         /* CoreSight Registers */
124         XDMREG_ITCTRL,
125         XDMREG_CLAIMSET,
126         XDMREG_CLAIMCLR,
127         XDMREG_LOCKACCESS,
128         XDMREG_LOCKSTATUS,
129         XDMREG_AUTHSTATUS,
130         XDMREG_DEVID,
131         XDMREG_DEVTYPE,
132         XDMREG_PERID4,
133         XDMREG_PERID5,
134         XDMREG_PERID6,
135         XDMREG_PERID7,
136         XDMREG_PERID0,
137         XDMREG_PERID1,
138         XDMREG_PERID2,
139         XDMREG_PERID3,
140         XDMREG_COMPID0,
141         XDMREG_COMPID1,
142         XDMREG_COMPID2,
143         XDMREG_COMPID3,
144
145         XDMREG_NUM
146 };
147
148 /* Debug Module Register offsets within Nexus (NAR) or APB */
149 struct xtensa_dm_reg_offsets {
150         uint8_t  nar;
151         uint16_t apb;
152 };
153
154 /* Debug Module Register offset structure; must include XDMREG_NUM entries */
155 #define XTENSA_DM_REG_OFFSETS   {                                                               \
156         /* TRAX Registers */                                                                            \
157         { .nar = 0x00, .apb = 0x0000 }, /* XDMREG_TRAXID */                     \
158         { .nar = 0x01, .apb = 0x0004 }, /* XDMREG_TRAXCTRL */           \
159         { .nar = 0x02, .apb = 0x0008 }, /* XDMREG_TRAXSTAT */           \
160         { .nar = 0x03, .apb = 0x000c }, /* XDMREG_TRAXDATA */           \
161         { .nar = 0x04, .apb = 0x0010 }, /* XDMREG_TRAXADDR */           \
162         { .nar = 0x05, .apb = 0x0014 }, /* XDMREG_TRIGGERPC */          \
163         { .nar = 0x06, .apb = 0x0018 }, /* XDMREG_PCMATCHCTRL */        \
164         { .nar = 0x07, .apb = 0x001c }, /* XDMREG_DELAYCNT */           \
165         { .nar = 0x08, .apb = 0x0020 }, /* XDMREG_MEMADDRSTART */       \
166         { .nar = 0x09, .apb = 0x0024 }, /* XDMREG_MEMADDREND */         \
167                                                                                                                                 \
168         /* Performance Monitor Registers */                                                     \
169         { .nar = 0x20, .apb = 0x1000 }, /* XDMREG_PMG */                        \
170         { .nar = 0x24, .apb = 0x1010 }, /* XDMREG_INTPC */                      \
171         { .nar = 0x28, .apb = 0x1080 }, /* XDMREG_PM0 */                        \
172         { .nar = 0x29, .apb = 0x1084 }, /* XDMREG_PM1 */                        \
173         { .nar = 0x2a, .apb = 0x1088 }, /* XDMREG_PM2 */                        \
174         { .nar = 0x2b, .apb = 0x108c }, /* XDMREG_PM3 */                        \
175         { .nar = 0x2c, .apb = 0x1090 }, /* XDMREG_PM4 */                        \
176         { .nar = 0x2d, .apb = 0x1094 }, /* XDMREG_PM5 */                        \
177         { .nar = 0x2e, .apb = 0x1098 }, /* XDMREG_PM6 */                        \
178         { .nar = 0x2f, .apb = 0x109c }, /* XDMREG_PM7 */                        \
179         { .nar = 0x30, .apb = 0x1100 }, /* XDMREG_PMCTRL0 */            \
180         { .nar = 0x31, .apb = 0x1104 }, /* XDMREG_PMCTRL1 */            \
181         { .nar = 0x32, .apb = 0x1108 }, /* XDMREG_PMCTRL2 */            \
182         { .nar = 0x33, .apb = 0x110c }, /* XDMREG_PMCTRL3 */            \
183         { .nar = 0x34, .apb = 0x1110 }, /* XDMREG_PMCTRL4 */            \
184         { .nar = 0x35, .apb = 0x1114 }, /* XDMREG_PMCTRL5 */            \
185         { .nar = 0x36, .apb = 0x1118 }, /* XDMREG_PMCTRL6 */            \
186         { .nar = 0x37, .apb = 0x111c }, /* XDMREG_PMCTRL7 */            \
187         { .nar = 0x38, .apb = 0x1180 }, /* XDMREG_PMSTAT0 */            \
188         { .nar = 0x39, .apb = 0x1184 }, /* XDMREG_PMSTAT1 */            \
189         { .nar = 0x3a, .apb = 0x1188 }, /* XDMREG_PMSTAT2 */            \
190         { .nar = 0x3b, .apb = 0x118c }, /* XDMREG_PMSTAT3 */            \
191         { .nar = 0x3c, .apb = 0x1190 }, /* XDMREG_PMSTAT4 */            \
192         { .nar = 0x3d, .apb = 0x1194 }, /* XDMREG_PMSTAT5 */            \
193         { .nar = 0x3e, .apb = 0x1198 }, /* XDMREG_PMSTAT6 */            \
194         { .nar = 0x3f, .apb = 0x119c }, /* XDMREG_PMSTAT7 */            \
195                                                                                                                                 \
196         /* OCD Registers */                                                                                     \
197         { .nar = 0x40, .apb = 0x2000 }, /* XDMREG_OCDID */                      \
198         { .nar = 0x42, .apb = 0x2008 }, /* XDMREG_DCRCLR */                     \
199         { .nar = 0x43, .apb = 0x200c }, /* XDMREG_DCRSET */                     \
200         { .nar = 0x44, .apb = 0x2010 }, /* XDMREG_DSR */                        \
201         { .nar = 0x45, .apb = 0x2014 }, /* XDMREG_DDR */                        \
202         { .nar = 0x46, .apb = 0x2018 }, /* XDMREG_DDREXEC */            \
203         { .nar = 0x47, .apb = 0x201c }, /* XDMREG_DIR0EXEC */           \
204         { .nar = 0x48, .apb = 0x2020 }, /* XDMREG_DIR0 */                       \
205         { .nar = 0x49, .apb = 0x2024 }, /* XDMREG_DIR1 */                       \
206         { .nar = 0x4a, .apb = 0x2028 }, /* XDMREG_DIR2 */                       \
207         { .nar = 0x4b, .apb = 0x202c }, /* XDMREG_DIR3 */                       \
208         { .nar = 0x4c, .apb = 0x2030 }, /* XDMREG_DIR4 */                       \
209         { .nar = 0x4d, .apb = 0x2034 }, /* XDMREG_DIR5 */                       \
210         { .nar = 0x4e, .apb = 0x2038 }, /* XDMREG_DIR6 */                       \
211         { .nar = 0x4f, .apb = 0x203c }, /* XDMREG_DIR7 */                       \
212                                                                                                                                 \
213         /* Misc Registers */                                                                            \
214         { .nar = 0x5a, .apb = 0x3028 }, /* XDMREG_ERISTAT */            \
215                                                                                                                                 \
216         /* CoreSight Registers */                                                                       \
217         { .nar = 0x60, .apb = 0x3f00 }, /* XDMREG_ITCTRL */                     \
218         { .nar = 0x68, .apb = 0x3fa0 }, /* XDMREG_CLAIMSET */           \
219         { .nar = 0x69, .apb = 0x3fa4 }, /* XDMREG_CLAIMCLR */           \
220         { .nar = 0x6c, .apb = 0x3fb0 }, /* XDMREG_LOCKACCESS */         \
221         { .nar = 0x6d, .apb = 0x3fb4 }, /* XDMREG_LOCKSTATUS */         \
222         { .nar = 0x6e, .apb = 0x3fb8 }, /* XDMREG_AUTHSTATUS */         \
223         { .nar = 0x72, .apb = 0x3fc8 }, /* XDMREG_DEVID */                      \
224         { .nar = 0x73, .apb = 0x3fcc }, /* XDMREG_DEVTYPE */            \
225         { .nar = 0x74, .apb = 0x3fd0 }, /* XDMREG_PERID4 */                     \
226         { .nar = 0x75, .apb = 0x3fd4 }, /* XDMREG_PERID5 */                     \
227         { .nar = 0x76, .apb = 0x3fd8 }, /* XDMREG_PERID6 */                     \
228         { .nar = 0x77, .apb = 0x3fdc }, /* XDMREG_PERID7 */                     \
229         { .nar = 0x78, .apb = 0x3fe0 }, /* XDMREG_PERID0 */                     \
230         { .nar = 0x79, .apb = 0x3fe4 }, /* XDMREG_PERID1 */                     \
231         { .nar = 0x7a, .apb = 0x3fe8 }, /* XDMREG_PERID2 */                     \
232         { .nar = 0x7b, .apb = 0x3fec }, /* XDMREG_PERID3 */                     \
233         { .nar = 0x7c, .apb = 0x3ff0 }, /* XDMREG_COMPID0 */            \
234         { .nar = 0x7d, .apb = 0x3ff4 }, /* XDMREG_COMPID1 */            \
235         { .nar = 0x7e, .apb = 0x3ff8 }, /* XDMREG_COMPID2 */            \
236         { .nar = 0x7f, .apb = 0x3ffc }, /* XDMREG_COMPID3 */            \
237 }
238
239 #define XTENSA_DM_APB_MASK          (0x3fff)
240
241 /* OCD registers, bit definitions */
242 #define OCDDCR_ENABLEOCD            BIT(0)
243 #define OCDDCR_DEBUGINTERRUPT       BIT(1)
244 #define OCDDCR_INTERRUPTALLCONDS    BIT(2)
245 #define OCDDCR_BREAKINEN            BIT(16)
246 #define OCDDCR_BREAKOUTEN           BIT(17)
247 #define OCDDCR_DEBUGSWACTIVE        BIT(20)
248 #define OCDDCR_RUNSTALLINEN         BIT(21)
249 #define OCDDCR_DEBUGMODEOUTEN       BIT(22)
250 #define OCDDCR_BREAKOUTITO          BIT(24)
251 #define OCDDCR_BREAKACKITO          BIT(25)
252
253 #define OCDDSR_EXECDONE             BIT(0)
254 #define OCDDSR_EXECEXCEPTION        BIT(1)
255 #define OCDDSR_EXECBUSY             BIT(2)
256 #define OCDDSR_EXECOVERRUN          BIT(3)
257 #define OCDDSR_STOPPED              BIT(4)
258 #define OCDDSR_COREWROTEDDR         BIT(10)
259 #define OCDDSR_COREREADDDR          BIT(11)
260 #define OCDDSR_HOSTWROTEDDR         BIT(14)
261 #define OCDDSR_HOSTREADDDR          BIT(15)
262 #define OCDDSR_DEBUGPENDBREAK       BIT(16)
263 #define OCDDSR_DEBUGPENDHOST        BIT(17)
264 #define OCDDSR_DEBUGPENDTRAX        BIT(18)
265 #define OCDDSR_DEBUGINTBREAK        BIT(20)
266 #define OCDDSR_DEBUGINTHOST         BIT(21)
267 #define OCDDSR_DEBUGINTTRAX         BIT(22)
268 #define OCDDSR_RUNSTALLTOGGLE       BIT(23)
269 #define OCDDSR_RUNSTALLSAMPLE       BIT(24)
270 #define OCDDSR_BREACKOUTACKITI      BIT(25)
271 #define OCDDSR_BREAKINITI           BIT(26)
272 #define OCDDSR_DBGMODPOWERON        BIT(31)
273
274 #define DEBUGCAUSE_IC               BIT(0)      /* ICOUNT exception */
275 #define DEBUGCAUSE_IB               BIT(1)      /* IBREAK exception */
276 #define DEBUGCAUSE_DB               BIT(2)      /* DBREAK exception */
277 #define DEBUGCAUSE_BI               BIT(3)      /* BREAK instruction encountered */
278 #define DEBUGCAUSE_BN               BIT(4)      /* BREAK.N instruction encountered */
279 #define DEBUGCAUSE_DI               BIT(5)      /* Debug Interrupt */
280
281 #define TRAXCTRL_TREN               BIT(0)      /* Trace enable. Tracing starts on 0->1 */
282 #define TRAXCTRL_TRSTP              BIT(1)      /* Trace Stop. Make 1 to stop trace. */
283 #define TRAXCTRL_PCMEN              BIT(2)      /* PC match enable */
284 #define TRAXCTRL_PTIEN              BIT(4)      /* Processor-trigger enable */
285 #define TRAXCTRL_CTIEN              BIT(5)      /* Cross-trigger enable */
286 #define TRAXCTRL_TMEN               BIT(7)      /* Tracemem Enable. Always set. */
287 #define TRAXCTRL_CNTU               BIT(9)      /* Post-stop-trigger countdown units; selects when DelayCount-- happens.
288                                                                                          * 0 - every 32-bit word written to tracemem, 1 - every cpu instruction */
289 #define TRAXCTRL_TSEN               BIT(11)     /* Undocumented/deprecated? */
290 #define TRAXCTRL_SMPER_SHIFT        12          /* Send sync every 2^(9-smper) messages. 7=reserved, 0=no sync msg */
291 #define TRAXCTRL_SMPER_MASK         0x07        /* Synchronization message period */
292 #define TRAXCTRL_PTOWT              BIT(16)     /* Processor Trigger Out (OCD halt) enabled when stop triggered */
293 #define TRAXCTRL_PTOWS              BIT(17)     /* Processor Trigger Out (OCD halt) enabled when trace stop completes */
294 #define TRAXCTRL_CTOWT              BIT(20)     /* Cross-trigger Out enabled when stop triggered */
295 #define TRAXCTRL_CTOWS              BIT(21)     /* Cross-trigger Out enabled when trace stop completes */
296 #define TRAXCTRL_ITCTO              BIT(22)     /* Integration mode: cross-trigger output */
297 #define TRAXCTRL_ITCTIA             BIT(23)     /* Integration mode: cross-trigger ack */
298 #define TRAXCTRL_ITATV              BIT(24)     /* replaces ATID when in integration mode: ATVALID output */
299 #define TRAXCTRL_ATID_MASK          0x7F        /* ARB source ID */
300 #define TRAXCTRL_ATID_SHIFT         24
301 #define TRAXCTRL_ATEN               BIT(31)     /* ATB interface enable */
302
303 #define TRAXSTAT_TRACT              BIT(0)      /* Trace active flag. */
304 #define TRAXSTAT_TRIG               BIT(1)      /* Trace stop trigger. Clears on TREN 1->0 */
305 #define TRAXSTAT_PCMTG              BIT(2)      /* Stop trigger caused by PC match. Clears on TREN 1->0 */
306 #define TRAXSTAT_PJTR               BIT(3)      /* JTAG transaction result. 1=err in preceding jtag transaction. */
307 #define TRAXSTAT_PTITG              BIT(4)      /* Stop trigger caused by Processor Trigger Input.Clears on TREN 1->0 */
308 #define TRAXSTAT_CTITG              BIT(5)      /* Stop trigger caused by Cross-Trigger Input. Clears on TREN 1->0 */
309 #define TRAXSTAT_MEMSZ_SHIFT        8           /* Traceram size inducator. Usable trace ram is 2^MEMSZ bytes. */
310 #define TRAXSTAT_MEMSZ_MASK         0x1F
311 #define TRAXSTAT_PTO                BIT(16)     /* Processor Trigger Output: current value */
312 #define TRAXSTAT_CTO                BIT(17)     /* Cross-Trigger Output: current value */
313 #define TRAXSTAT_ITCTOA             BIT(22)     /* Cross-Trigger Out Ack: current value */
314 #define TRAXSTAT_ITCTI              BIT(23)     /* Cross-Trigger Input: current value */
315 #define TRAXSTAT_ITATR              BIT(24)     /* ATREADY Input: current value */
316
317 #define TRAXADDR_TADDR_SHIFT        0           /* Trax memory address, in 32-bit words. */
318 #define TRAXADDR_TADDR_MASK         0x1FFFFF    /* Actually is only as big as the trace buffer size max addr. */
319 #define TRAXADDR_TWRAP_SHIFT        21          /* Amount of times TADDR has overflown */
320 #define TRAXADDR_TWRAP_MASK         0x3FF
321 #define TRAXADDR_TWSAT              BIT(31)     /* 1 if TWRAP has overflown, clear by disabling tren.*/
322
323 #define PCMATCHCTRL_PCML_SHIFT      0           /* Amount of lower bits to ignore in pc trigger register */
324 #define PCMATCHCTRL_PCML_MASK       0x1F
325 #define PCMATCHCTRL_PCMS            BIT(31)     /* PC Match Sense, 0-match when procs PC is in-range, 1-match when
326                                                                                          * out-of-range */
327
328 #define XTENSA_MAX_PERF_COUNTERS    2
329 #define XTENSA_MAX_PERF_SELECT      32
330 #define XTENSA_MAX_PERF_MASK        0xffff
331
332 #define XTENSA_STOPMASK_DISABLED    UINT32_MAX
333
334 struct xtensa_debug_module;
335
336 struct xtensa_debug_ops {
337         /** enable operation */
338         int (*queue_enable)(struct xtensa_debug_module *dm);
339         /** register read. */
340         int (*queue_reg_read)(struct xtensa_debug_module *dm, enum xtensa_dm_reg reg, uint8_t *data);
341         /** register write. */
342         int (*queue_reg_write)(struct xtensa_debug_module *dm, enum xtensa_dm_reg reg, uint32_t data);
343 };
344
345 /* Xtensa power registers are 8 bits wide on JTAG interfaces but 32 bits wide
346  * when accessed via APB/DAP.  In order to use DAP queuing APIs (for optimal
347  * performance), the XDM power register APIs take 32-bit register params.
348  */
349 struct xtensa_power_ops {
350         /** register read. */
351         int (*queue_reg_read)(struct xtensa_debug_module *dm, enum xtensa_dm_pwr_reg reg, uint8_t *data,
352                 uint32_t clear);
353         /** register write. */
354         int (*queue_reg_write)(struct xtensa_debug_module *dm, enum xtensa_dm_pwr_reg reg, uint32_t data);
355 };
356
357 typedef uint32_t xtensa_pwrstat_t;
358 typedef uint32_t xtensa_ocdid_t;
359 typedef uint32_t xtensa_dsr_t;
360 typedef uint32_t xtensa_traxstat_t;
361
362 struct xtensa_power_status {
363         xtensa_pwrstat_t stat;
364         xtensa_pwrstat_t stath;
365         /* TODO: do not need to keep previous status to detect that core or debug module has been
366          * reset, */
367         /*       we can clear PWRSTAT_DEBUGWASRESET and PWRSTAT_COREWASRESET after reading will do
368          * the job; */
369         /*       upon next reet those bits will be set again. So we can get rid of
370          *       xtensa_dm_power_status_cache_reset() and xtensa_dm_power_status_cache(). */
371         xtensa_pwrstat_t prev_stat;
372 };
373
374 struct xtensa_core_status {
375         xtensa_dsr_t dsr;
376 };
377
378 struct xtensa_trace_config {
379         uint32_t ctrl;
380         uint32_t memaddr_start;
381         uint32_t memaddr_end;
382         uint32_t addr;
383 };
384
385 struct xtensa_trace_status {
386         xtensa_traxstat_t stat;
387 };
388
389 struct xtensa_trace_start_config {
390         uint32_t stoppc;
391         bool after_is_words;
392         uint32_t after;
393         uint32_t stopmask;      /* UINT32_MAX: disable PC match option */
394 };
395
396 struct xtensa_perfmon_config {
397         int select;
398         uint32_t mask;
399         int kernelcnt;
400         int tracelevel;
401 };
402
403 struct xtensa_perfmon_result {
404         uint64_t value;
405         bool overflow;
406 };
407
408 struct xtensa_debug_module_config {
409         const struct xtensa_power_ops *pwr_ops;
410         const struct xtensa_debug_ops *dbg_ops;
411         struct jtag_tap *tap;
412         void (*queue_tdi_idle)(struct target *target);
413         void *queue_tdi_idle_arg;
414 };
415
416 struct xtensa_debug_module {
417         const struct xtensa_power_ops *pwr_ops;
418         const struct xtensa_debug_ops *dbg_ops;
419         struct jtag_tap *tap;
420         void (*queue_tdi_idle)(struct target *target);
421         void *queue_tdi_idle_arg;
422
423         struct xtensa_power_status power_status;
424         struct xtensa_core_status core_status;
425         xtensa_ocdid_t device_id;
426 };
427
428 int xtensa_dm_init(struct xtensa_debug_module *dm, const struct xtensa_debug_module_config *cfg);
429 int xtensa_dm_queue_enable(struct xtensa_debug_module *dm);
430 int xtensa_dm_queue_reg_read(struct xtensa_debug_module *dm, enum xtensa_dm_reg reg, uint8_t *value);
431 int xtensa_dm_queue_reg_write(struct xtensa_debug_module *dm, enum xtensa_dm_reg reg, uint32_t value);
432 int xtensa_dm_queue_pwr_reg_read(struct xtensa_debug_module *dm,
433         enum xtensa_dm_pwr_reg reg,
434         uint8_t *data,
435         uint32_t clear);
436 int xtensa_dm_queue_pwr_reg_write(struct xtensa_debug_module *dm,
437         enum xtensa_dm_pwr_reg reg,
438         uint32_t data);
439
440 static inline int xtensa_dm_queue_execute(struct xtensa_debug_module *dm)
441 {
442         return jtag_execute_queue();
443 }
444
445 static inline void xtensa_dm_queue_tdi_idle(struct xtensa_debug_module *dm)
446 {
447         if (dm->queue_tdi_idle)
448                 dm->queue_tdi_idle(dm->queue_tdi_idle_arg);
449 }
450
451 int xtensa_dm_power_status_read(struct xtensa_debug_module *dm, uint32_t clear);
452 static inline void xtensa_dm_power_status_cache_reset(struct xtensa_debug_module *dm)
453 {
454         dm->power_status.prev_stat = 0;
455 }
456 static inline void xtensa_dm_power_status_cache(struct xtensa_debug_module *dm)
457 {
458         dm->power_status.prev_stat = dm->power_status.stath;
459 }
460 static inline xtensa_pwrstat_t xtensa_dm_power_status_get(struct xtensa_debug_module *dm)
461 {
462         return dm->power_status.stat;
463 }
464
465 int xtensa_dm_core_status_read(struct xtensa_debug_module *dm);
466 int xtensa_dm_core_status_clear(struct xtensa_debug_module *dm, xtensa_dsr_t bits);
467 int xtensa_dm_core_status_check(struct xtensa_debug_module *dm);
468 static inline xtensa_dsr_t xtensa_dm_core_status_get(struct xtensa_debug_module *dm)
469 {
470         return dm->core_status.dsr;
471 }
472
473 int xtensa_dm_device_id_read(struct xtensa_debug_module *dm);
474 static inline xtensa_ocdid_t xtensa_dm_device_id_get(struct xtensa_debug_module *dm)
475 {
476         return dm->device_id;
477 }
478
479 int xtensa_dm_trace_start(struct xtensa_debug_module *dm, struct xtensa_trace_start_config *cfg);
480 int xtensa_dm_trace_stop(struct xtensa_debug_module *dm, bool pto_enable);
481 int xtensa_dm_trace_config_read(struct xtensa_debug_module *dm, struct xtensa_trace_config *config);
482 int xtensa_dm_trace_status_read(struct xtensa_debug_module *dm, struct xtensa_trace_status *status);
483 int xtensa_dm_trace_data_read(struct xtensa_debug_module *dm, uint8_t *dest, uint32_t size);
484
485 static inline bool xtensa_dm_is_online(struct xtensa_debug_module *dm)
486 {
487         int res = xtensa_dm_device_id_read(dm);
488         if (res != ERROR_OK)
489                 return false;
490         return dm->device_id != 0xffffffff && dm->device_id != 0;
491 }
492
493 static inline bool xtensa_dm_tap_was_reset(struct xtensa_debug_module *dm)
494 {
495         return !(dm->power_status.prev_stat & PWRSTAT_DEBUGWASRESET) &&
496                dm->power_status.stat & PWRSTAT_DEBUGWASRESET;
497 }
498
499 static inline bool xtensa_dm_core_was_reset(struct xtensa_debug_module *dm)
500 {
501         return !(dm->power_status.prev_stat & PWRSTAT_COREWASRESET) &&
502                dm->power_status.stat & PWRSTAT_COREWASRESET;
503 }
504
505 static inline bool xtensa_dm_core_is_stalled(struct xtensa_debug_module *dm)
506 {
507         return dm->core_status.dsr & OCDDSR_RUNSTALLSAMPLE;
508 }
509
510 static inline bool xtensa_dm_is_powered(struct xtensa_debug_module *dm)
511 {
512         return dm->core_status.dsr & OCDDSR_DBGMODPOWERON;
513 }
514
515 int xtensa_dm_perfmon_enable(struct xtensa_debug_module *dm, int counter_id,
516         const struct xtensa_perfmon_config *config);
517 int xtensa_dm_perfmon_dump(struct xtensa_debug_module *dm, int counter_id,
518         struct xtensa_perfmon_result *out_result);
519
520 #endif  /* OPENOCD_TARGET_XTENSA_DEBUG_MODULE_H */