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