openocd: fix SPDX tag format for files .c
[fw/openocd] / src / target / adi_v5_dapdirect.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2
3 /*
4  * Copyright (C) 2019, STMicroelectronics - All Rights Reserved
5  * Author(s): Antonio Borneo <borneo.antonio@gmail.com> for STMicroelectronics
6  */
7
8 /**
9  * @file
10  * Utilities to support in-circuit debuggers that provide APIs to access
11  * directly ARM DAP, hiding the access to the underlining transport used
12  * for the physical connection (either JTAG or SWD).
13  * E.g. STMicroelectronics ST-Link/V2 (from version V2J24) and STLINK-V3.
14  *
15  * Single-DAP support only.
16  *
17  * For details, see "ARM IHI 0031A"
18  * ARM Debug Interface v5 Architecture Specification
19  *
20  * FIXME: in JTAG mode, trst is not managed
21  */
22
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #include <jtag/interface.h>
28 #include <jtag/tcl.h>
29 #include <transport/transport.h>
30
31 COMMAND_HANDLER(dapdirect_jtag_empty_command)
32 {
33         LOG_DEBUG("dapdirect_jtag_empty_command(\"%s\")", CMD_NAME);
34
35         return ERROR_OK;
36 }
37
38 COMMAND_HANDLER(dapdirect_jtag_reset_command)
39 {
40         enum reset_types jtag_reset_config = jtag_get_reset_config();
41
42         /*
43          * in case the adapter has not already handled asserting srst
44          * we will attempt it again
45          */
46         if (jtag_reset_config & RESET_CNCT_UNDER_SRST) {
47                 if (jtag_reset_config & RESET_SRST_NO_GATING) {
48                         adapter_assert_reset();
49                         return ERROR_OK;
50                 }
51                 LOG_WARNING("\'srst_nogate\' reset_config option is required");
52         }
53         adapter_deassert_reset();
54         return ERROR_OK;
55 }
56
57 static const struct command_registration dapdirect_jtag_subcommand_handlers[] = {
58         {
59                 .name = "newtap",
60                 .mode = COMMAND_CONFIG,
61                 .jim_handler = jim_jtag_newtap,
62                 .help = "declare a new TAP"
63         },
64         {
65                 .name = "init",
66                 .mode = COMMAND_ANY,
67                 .handler = dapdirect_jtag_empty_command,
68                 .usage = ""
69         },
70         {
71                 .name = "arp_init",
72                 .mode = COMMAND_ANY,
73                 .handler = dapdirect_jtag_empty_command,
74                 .usage = ""
75         },
76         {
77                 .name = "arp_init-reset",
78                 .mode = COMMAND_ANY,
79                 .handler = dapdirect_jtag_reset_command,
80                 .usage = ""
81         },
82         {
83                 .name = "tapisenabled",
84                 .mode = COMMAND_EXEC,
85                 .jim_handler = jim_jtag_tap_enabler,
86         },
87         {
88                 .name = "tapenable",
89                 .mode = COMMAND_EXEC,
90                 .jim_handler = jim_jtag_tap_enabler,
91         },
92         {
93                 .name = "tapdisable",
94                 .mode = COMMAND_EXEC,
95                 .handler = dapdirect_jtag_empty_command,
96                 .usage = "",
97         },
98         {
99                 .name = "configure",
100                 .mode = COMMAND_ANY,
101                 .handler = dapdirect_jtag_empty_command,
102                 .usage = "",
103         },
104         {
105                 .name = "cget",
106                 .mode = COMMAND_EXEC,
107                 .jim_handler = jim_jtag_configure,
108         },
109         {
110                 .name = "names",
111                 .mode = COMMAND_ANY,
112                 .handler = dapdirect_jtag_empty_command,
113                 .usage = "",
114         },
115         COMMAND_REGISTRATION_DONE
116 };
117
118 static const struct command_registration dapdirect_jtag_handlers[] = {
119         {
120                 .name = "jtag",
121                 .mode = COMMAND_ANY,
122                 .chain = dapdirect_jtag_subcommand_handlers,
123                 .usage = "",
124         },
125         {
126                 .name = "jtag_ntrst_delay",
127                 .mode = COMMAND_ANY,
128                 .handler = dapdirect_jtag_empty_command,
129                 .usage = "",
130         },
131         COMMAND_REGISTRATION_DONE
132 };
133
134 static const struct command_registration dapdirect_swd_subcommand_handlers[] = {
135         {
136                 .name = "newdap",
137                 .mode = COMMAND_CONFIG,
138                 .jim_handler = jim_jtag_newtap,
139                 .help = "declare a new SWD DAP",
140         },
141         COMMAND_REGISTRATION_DONE
142 };
143
144 static const struct command_registration dapdirect_swd_handlers[] = {
145         {
146                 .name = "swd",
147                 .mode = COMMAND_ANY,
148                 .help = "SWD command group",
149                 .usage = "",
150                 .chain = dapdirect_swd_subcommand_handlers,
151         },
152         COMMAND_REGISTRATION_DONE
153 };
154
155 static int dapdirect_jtag_select(struct command_context *ctx)
156 {
157         LOG_DEBUG("dapdirect_jtag_select()");
158
159         return register_commands(ctx, NULL, dapdirect_jtag_handlers);
160 }
161
162 static int dapdirect_swd_select(struct command_context *ctx)
163 {
164         LOG_DEBUG("dapdirect_swd_select()");
165
166         return register_commands(ctx, NULL, dapdirect_swd_handlers);
167 }
168
169 static int dapdirect_init(struct command_context *ctx)
170 {
171         enum reset_types jtag_reset_config = jtag_get_reset_config();
172
173         LOG_DEBUG("dapdirect_init()");
174
175         if (jtag_reset_config & RESET_CNCT_UNDER_SRST) {
176                 if (jtag_reset_config & RESET_SRST_NO_GATING)
177                         adapter_assert_reset();
178                 else
179                         LOG_WARNING("\'srst_nogate\' reset_config option is required");
180         } else
181                 adapter_deassert_reset();
182
183         return ERROR_OK;
184 }
185
186 static struct transport dapdirect_jtag_transport = {
187         .name = "dapdirect_jtag",
188         .select = dapdirect_jtag_select,
189         .init = dapdirect_init,
190 };
191
192 static struct transport dapdirect_swd_transport = {
193         .name = "dapdirect_swd",
194         .select = dapdirect_swd_select,
195         .init = dapdirect_init,
196 };
197
198 static void dapdirect_constructor(void) __attribute__((constructor));
199 static void dapdirect_constructor(void)
200 {
201         transport_register(&dapdirect_jtag_transport);
202         transport_register(&dapdirect_swd_transport);
203 }
204
205 /**
206  * Returns true if the current debug session
207  * is using JTAG as its transport.
208  */
209 bool transport_is_dapdirect_jtag(void)
210 {
211         return get_current_transport() == &dapdirect_jtag_transport;
212 }
213
214 /**
215  * Returns true if the current debug session
216  * is using SWD as its transport.
217  */
218 bool transport_is_dapdirect_swd(void)
219 {
220         return get_current_transport() == &dapdirect_swd_transport;
221 }