a9f558e12406758f445d18ce1a122b865e87b92b
[fw/openocd] / src / target / arm_tpiu_swo.c
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2
3 /**
4  * @file
5  * This file implements support for the ARM CoreSight components Trace Port
6  * Interface Unit (TPIU) and Serial Wire Output (SWO). It also supports the
7  * CoreSight TPIU-Lite and the special TPIU version present with Cortex-M3
8  * and Cortex-M4 (that includes SWO).
9  */
10
11 /*
12  * Relevant specifications from ARM include:
13  *
14  * CoreSight(tm) Components Technical Reference Manual           ARM DDI 0314H
15  * CoreSight(tm) TPIU-Lite Technical Reference Manual            ARM DDI 0317A
16  * Cortex(tm)-M3 Technical Reference Manual                      ARM DDI 0337G
17  * Cortex(tm)-M4 Technical Reference Manual                      ARM DDI 0439B
18  * CoreSight(tm) SoC-400 Technical Reference Manual              ARM DDI 0480F
19  */
20
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 #include <stdlib.h>
26 #include <jim.h>
27
28 #include <helper/bits.h>
29 #include <helper/command.h>
30 #include <helper/jim-nvp.h>
31 #include <helper/list.h>
32 #include <helper/log.h>
33 #include <helper/types.h>
34 #include <jtag/interface.h>
35 #include <server/server.h>
36 #include <target/arm_adi_v5.h>
37 #include <target/target.h>
38 #include <transport/transport.h>
39 #include "arm_tpiu_swo.h"
40
41 /* START_DEPRECATED_TPIU */
42 #include <target/cortex_m.h>
43 #include <target/target_type.h>
44 #define MSG "DEPRECATED \'tpiu config\' command: "
45 /* END_DEPRECATED_TPIU */
46
47 #define TCP_SERVICE_NAME                "tpiu_swo_trace"
48
49 /* default for Cortex-M3 and Cortex-M4 specific TPIU */
50 #define TPIU_SWO_DEFAULT_BASE           0xE0040000
51
52 #define TPIU_SSPSR_OFFSET               0x000
53 #define TPIU_CSPSR_OFFSET               0x004
54 #define TPIU_ACPR_OFFSET                0x010
55 #define TPIU_SPPR_OFFSET                0x0F0
56 #define TPIU_FFSR_OFFSET                0x300
57 #define TPIU_FFCR_OFFSET                0x304
58 #define TPIU_FSCR_OFFSET                0x308
59 #define TPIU_DEVID_OFFSET               0xfc8
60
61 #define TPIU_ACPR_MAX_PRESCALER         0x1fff
62 #define TPIU_SPPR_PROTOCOL_SYNC         (TPIU_PIN_PROTOCOL_SYNC)
63 #define TPIU_SPPR_PROTOCOL_MANCHESTER   (TPIU_PIN_PROTOCOL_ASYNC_MANCHESTER)
64 #define TPIU_SPPR_PROTOCOL_UART         (TPIU_PIN_PROTOCOL_ASYNC_UART)
65 #define TPIU_DEVID_NOSUPPORT_SYNC       BIT(9)
66 #define TPIU_DEVID_SUPPORT_MANCHESTER   BIT(10)
67 #define TPIU_DEVID_SUPPORT_UART         BIT(11)
68
69 enum arm_tpiu_swo_event {
70         TPIU_SWO_EVENT_PRE_ENABLE,
71         TPIU_SWO_EVENT_POST_ENABLE,
72         TPIU_SWO_EVENT_PRE_DISABLE,
73         TPIU_SWO_EVENT_POST_DISABLE,
74 };
75
76 static const struct jim_nvp nvp_arm_tpiu_swo_event[] = {
77         { .value = TPIU_SWO_EVENT_PRE_ENABLE,   .name = "pre-enable" },
78         { .value = TPIU_SWO_EVENT_POST_ENABLE,  .name = "post-enable" },
79         { .value = TPIU_SWO_EVENT_PRE_DISABLE,  .name = "pre-disable" },
80         { .value = TPIU_SWO_EVENT_POST_DISABLE, .name = "post-disable" },
81 };
82
83 struct arm_tpiu_swo_event_action {
84         enum arm_tpiu_swo_event event;
85         Jim_Interp *interp;
86         Jim_Obj *body;
87         struct arm_tpiu_swo_event_action *next;
88 };
89
90 struct arm_tpiu_swo_object {
91         struct list_head lh;
92         struct adiv5_mem_ap_spot spot;
93         struct adiv5_ap *ap;
94         char *name;
95         struct arm_tpiu_swo_event_action *event_action;
96         /* record enable before init */
97         bool deferred_enable;
98         bool enabled;
99         bool en_capture;
100         /** Handle to output trace data in INTERNAL capture mode */
101         /** Synchronous output port width */
102         uint32_t port_width;
103         FILE *file;
104         /** output mode */
105         unsigned int pin_protocol;
106         /** Enable formatter */
107         bool en_formatter;
108         /** frequency of TRACECLKIN (usually matches HCLK) */
109         unsigned int traceclkin_freq;
110         /** SWO pin frequency */
111         unsigned int swo_pin_freq;
112         /** where to dump the captured output trace data */
113         char *out_filename;
114         /** track TCP connections */
115         struct list_head connections;
116         /* START_DEPRECATED_TPIU */
117         bool recheck_ap_cur_target;
118         /* END_DEPRECATED_TPIU */
119 };
120
121 struct arm_tpiu_swo_connection {
122         struct list_head lh;
123         struct connection *connection;
124 };
125
126 struct arm_tpiu_swo_priv_connection {
127         struct arm_tpiu_swo_object *obj;
128 };
129
130 static LIST_HEAD(all_tpiu_swo);
131
132 #define ARM_TPIU_SWO_TRACE_BUF_SIZE     4096
133
134 static int arm_tpiu_swo_poll_trace(void *priv)
135 {
136         struct arm_tpiu_swo_object *obj = priv;
137         uint8_t buf[ARM_TPIU_SWO_TRACE_BUF_SIZE];
138         size_t size = sizeof(buf);
139         struct arm_tpiu_swo_connection *c;
140
141         int retval = adapter_poll_trace(buf, &size);
142         if (retval != ERROR_OK || !size)
143                 return retval;
144
145         target_call_trace_callbacks(/*target*/NULL, size, buf);
146
147         if (obj->file) {
148                 if (fwrite(buf, 1, size, obj->file) == size) {
149                         fflush(obj->file);
150                 } else {
151                         LOG_ERROR("Error writing to the SWO trace destination file");
152                         return ERROR_FAIL;
153                 }
154         }
155
156         if (obj->out_filename && obj->out_filename[0] == ':')
157                 list_for_each_entry(c, &obj->connections, lh)
158                         if (connection_write(c->connection, buf, size) != (int)size)
159                                 LOG_ERROR("Error writing to connection"); /* FIXME: which connection? */
160
161         return ERROR_OK;
162 }
163
164 static void arm_tpiu_swo_handle_event(struct arm_tpiu_swo_object *obj, enum arm_tpiu_swo_event event)
165 {
166         for (struct arm_tpiu_swo_event_action *ea = obj->event_action; ea; ea = ea->next) {
167                 if (ea->event != event)
168                         continue;
169
170                 LOG_DEBUG("TPIU/SWO: %s event: %s (%d) action : %s",
171                         obj->name,
172                         jim_nvp_value2name_simple(nvp_arm_tpiu_swo_event, event)->name,
173                         event,
174                         Jim_GetString(ea->body, NULL));
175
176                 /* prevent event execution to change current target */
177                 struct command_context *cmd_ctx = current_command_context(ea->interp);
178                 struct target *saved_target = cmd_ctx->current_target;
179                 int retval = Jim_EvalObj(ea->interp, ea->body);
180                 cmd_ctx->current_target = saved_target;
181
182                 if (retval == JIM_RETURN)
183                         retval = ea->interp->returnCode;
184                 if (retval == JIM_OK || retval == ERROR_COMMAND_CLOSE_CONNECTION)
185                         return;
186
187                 Jim_MakeErrorMessage(ea->interp);
188                 LOG_USER("Error executing event %s on TPIU/SWO %s:\n%s",
189                         jim_nvp_value2name_simple(nvp_arm_tpiu_swo_event, event)->name,
190                         obj->name,
191                         Jim_GetString(Jim_GetResult(ea->interp), NULL));
192                 /* clean both error code and stacktrace before return */
193                 Jim_Eval(ea->interp, "error \"\" \"\"");
194                 return;
195         }
196 }
197
198 static void arm_tpiu_swo_close_output(struct arm_tpiu_swo_object *obj)
199 {
200         if (obj->file) {
201                 fclose(obj->file);
202                 obj->file = NULL;
203         }
204         if (obj->out_filename && obj->out_filename[0] == ':')
205                 remove_service(TCP_SERVICE_NAME, &obj->out_filename[1]);
206 }
207
208 int arm_tpiu_swo_cleanup_all(void)
209 {
210         struct arm_tpiu_swo_object *obj, *tmp;
211
212         list_for_each_entry_safe(obj, tmp, &all_tpiu_swo, lh) {
213                 if (obj->enabled)
214                         arm_tpiu_swo_handle_event(obj, TPIU_SWO_EVENT_PRE_DISABLE);
215
216                 arm_tpiu_swo_close_output(obj);
217
218                 if (obj->en_capture) {
219                         target_unregister_timer_callback(arm_tpiu_swo_poll_trace, obj);
220
221                         int retval = adapter_config_trace(false, 0, 0, NULL, 0, NULL);
222                         if (retval != ERROR_OK)
223                                 LOG_ERROR("Failed to stop adapter's trace");
224                 }
225
226                 if (obj->enabled)
227                         arm_tpiu_swo_handle_event(obj, TPIU_SWO_EVENT_POST_DISABLE);
228
229                 struct arm_tpiu_swo_event_action *ea = obj->event_action;
230                 while (ea) {
231                         struct arm_tpiu_swo_event_action *next = ea->next;
232                         Jim_DecrRefCount(ea->interp, ea->body);
233                         free(ea);
234                         ea = next;
235                 }
236
237                 if (obj->ap)
238                         dap_put_ap(obj->ap);
239
240                 free(obj->name);
241                 free(obj->out_filename);
242                 free(obj);
243         }
244
245         return ERROR_OK;
246 }
247
248 static int arm_tpiu_swo_service_new_connection(struct connection *connection)
249 {
250         struct arm_tpiu_swo_priv_connection *priv = connection->service->priv;
251         struct arm_tpiu_swo_object *obj = priv->obj;
252         struct arm_tpiu_swo_connection *c = malloc(sizeof(*c));
253         if (!c) {
254                 LOG_ERROR("Out of memory");
255                 return ERROR_FAIL;
256         }
257         c->connection = connection;
258         list_add(&c->lh, &obj->connections);
259         return ERROR_OK;
260 }
261
262 static int arm_tpiu_swo_service_input(struct connection *connection)
263 {
264         /* read a dummy buffer to check if the connection is still active */
265         long dummy;
266         int bytes_read = connection_read(connection, &dummy, sizeof(dummy));
267
268         if (bytes_read == 0) {
269                 return ERROR_SERVER_REMOTE_CLOSED;
270         } else if (bytes_read == -1) {
271                 LOG_ERROR("error during read: %s", strerror(errno));
272                 return ERROR_SERVER_REMOTE_CLOSED;
273         }
274
275         return ERROR_OK;
276 }
277
278 static int arm_tpiu_swo_service_connection_closed(struct connection *connection)
279 {
280         struct arm_tpiu_swo_priv_connection *priv = connection->service->priv;
281         struct arm_tpiu_swo_object *obj = priv->obj;
282         struct arm_tpiu_swo_connection *c, *tmp;
283
284         list_for_each_entry_safe(c, tmp, &obj->connections, lh)
285                 if (c->connection == connection) {
286                         list_del(&c->lh);
287                         free(c);
288                         return ERROR_OK;
289                 }
290         LOG_ERROR("Failed to find connection to close!");
291         return ERROR_FAIL;
292 }
293
294 COMMAND_HANDLER(handle_arm_tpiu_swo_event_list)
295 {
296         struct arm_tpiu_swo_object *obj = CMD_DATA;
297
298         command_print(CMD, "Event actions for TPIU/SWO %s\n", obj->name);
299         command_print(CMD, "%-25s | Body", "Event");
300         command_print(CMD, "------------------------- | "
301                         "----------------------------------------");
302
303         for (struct arm_tpiu_swo_event_action *ea = obj->event_action; ea; ea = ea->next) {
304                 struct jim_nvp *opt = jim_nvp_value2name_simple(nvp_arm_tpiu_swo_event, ea->event);
305                 command_print(CMD, "%-25s | %s",
306                                 opt->name, Jim_GetString(ea->body, NULL));
307         }
308         command_print(CMD, "***END***");
309         return ERROR_OK;
310 }
311
312 enum arm_tpiu_swo_cfg_param {
313         CFG_PORT_WIDTH,
314         CFG_PROTOCOL,
315         CFG_FORMATTER,
316         CFG_TRACECLKIN,
317         CFG_BITRATE,
318         CFG_OUTFILE,
319         CFG_EVENT,
320 };
321
322 static const struct jim_nvp nvp_arm_tpiu_swo_config_opts[] = {
323         { .name = "-port-width",    .value = CFG_PORT_WIDTH },
324         { .name = "-protocol",      .value = CFG_PROTOCOL },
325         { .name = "-formatter",     .value = CFG_FORMATTER },
326         { .name = "-traceclk",      .value = CFG_TRACECLKIN },
327         { .name = "-pin-freq",      .value = CFG_BITRATE },
328         { .name = "-output",        .value = CFG_OUTFILE },
329         { .name = "-event",         .value = CFG_EVENT },
330         /* handled by mem_ap_spot, added for jim_getopt_nvp_unknown() */
331         { .name = "-dap",           .value = -1 },
332         { .name = "-ap-num",        .value = -1 },
333         { .name = "-baseaddr",      .value = -1 },
334         { .name = NULL,             .value = -1 },
335 };
336
337 static const struct jim_nvp nvp_arm_tpiu_swo_protocol_opts[] = {
338         { .name = "sync",           .value = TPIU_SPPR_PROTOCOL_SYNC },
339         { .name = "uart",           .value = TPIU_SPPR_PROTOCOL_UART },
340         { .name = "manchester",     .value = TPIU_SPPR_PROTOCOL_MANCHESTER },
341         { .name = NULL,             .value = -1 },
342 };
343
344 static const struct jim_nvp nvp_arm_tpiu_swo_bool_opts[] = {
345         { .name = "on",             .value = 1 },
346         { .name = "yes",            .value = 1 },
347         { .name = "1",              .value = 1 },
348         { .name = "true",           .value = 1 },
349         { .name = "off",            .value = 0 },
350         { .name = "no",             .value = 0 },
351         { .name = "0",              .value = 0 },
352         { .name = "false",          .value = 0 },
353         { .name = NULL,             .value = -1 },
354 };
355
356 static int arm_tpiu_swo_configure(struct jim_getopt_info *goi, struct arm_tpiu_swo_object *obj)
357 {
358         assert(obj);
359
360         if (goi->isconfigure && obj->enabled) {
361                 Jim_SetResultFormatted(goi->interp, "Cannot configure TPIU/SWO; %s is enabled!", obj->name);
362                 return JIM_ERR;
363         }
364
365         /* parse config or cget options ... */
366         while (goi->argc > 0) {
367                 Jim_SetEmptyResult(goi->interp);
368
369                 int e = adiv5_jim_mem_ap_spot_configure(&obj->spot, goi);
370                 if (e == JIM_OK)
371                         continue;
372                 if (e == JIM_ERR)
373                         return e;
374
375                 struct jim_nvp *n;
376                 e = jim_getopt_nvp(goi, nvp_arm_tpiu_swo_config_opts, &n);
377                 if (e != JIM_OK) {
378                         jim_getopt_nvp_unknown(goi, nvp_arm_tpiu_swo_config_opts, 0);
379                         return e;
380                 }
381
382                 switch (n->value) {
383                 case CFG_PORT_WIDTH:
384                         if (goi->isconfigure) {
385                                 jim_wide port_width;
386                                 e = jim_getopt_wide(goi, &port_width);
387                                 if (e != JIM_OK)
388                                         return e;
389                                 if (port_width < 1 || port_width > 32) {
390                                         Jim_SetResultString(goi->interp, "Invalid port width!", -1);
391                                         return JIM_ERR;
392                                 }
393                                 obj->port_width = (uint32_t)port_width;
394                         } else {
395                                 if (goi->argc)
396                                         goto err_no_params;
397                                 Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, obj->port_width));
398                         }
399                         break;
400                 case CFG_PROTOCOL:
401                         if (goi->isconfigure) {
402                                 struct jim_nvp *p;
403                                 e = jim_getopt_nvp(goi, nvp_arm_tpiu_swo_protocol_opts, &p);
404                                 if (e != JIM_OK)
405                                         return e;
406                                 obj->pin_protocol = p->value;
407                         } else {
408                                 if (goi->argc)
409                                         goto err_no_params;
410                                 struct jim_nvp *p;
411                                 e = jim_nvp_value2name(goi->interp, nvp_arm_tpiu_swo_protocol_opts, obj->pin_protocol, &p);
412                                 if (e != JIM_OK) {
413                                         Jim_SetResultString(goi->interp, "protocol error", -1);
414                                         return JIM_ERR;
415                                 }
416                                 Jim_SetResult(goi->interp, Jim_NewStringObj(goi->interp, p->name, -1));
417                         }
418                         break;
419                 case CFG_FORMATTER:
420                         if (goi->isconfigure) {
421                                 struct jim_nvp *p;
422                                 e = jim_getopt_nvp(goi, nvp_arm_tpiu_swo_bool_opts, &p);
423                                 if (e != JIM_OK)
424                                         return e;
425                                 obj->en_formatter = p->value;
426                         } else {
427                                 if (goi->argc)
428                                         goto err_no_params;
429                                 struct jim_nvp *p;
430                                 e = jim_nvp_value2name(goi->interp, nvp_arm_tpiu_swo_bool_opts, obj->en_formatter, &p);
431                                 if (e != JIM_OK) {
432                                         Jim_SetResultString(goi->interp, "formatter error", -1);
433                                         return JIM_ERR;
434                                 }
435                                 Jim_SetResult(goi->interp, Jim_NewStringObj(goi->interp, p->name, -1));
436                         }
437                         break;
438                 case CFG_TRACECLKIN:
439                         if (goi->isconfigure) {
440                                 jim_wide clk;
441                                 e = jim_getopt_wide(goi, &clk);
442                                 if (e != JIM_OK)
443                                         return e;
444                                 obj->traceclkin_freq = clk;
445                         } else {
446                                 if (goi->argc)
447                                         goto err_no_params;
448                                 Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, obj->traceclkin_freq));
449                         }
450                         break;
451                 case CFG_BITRATE:
452                         if (goi->isconfigure) {
453                                 jim_wide clk;
454                                 e = jim_getopt_wide(goi, &clk);
455                                 if (e != JIM_OK)
456                                         return e;
457                                 obj->swo_pin_freq = clk;
458                         } else {
459                                 if (goi->argc)
460                                         goto err_no_params;
461                                 Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, obj->swo_pin_freq));
462                         }
463                         break;
464                 case CFG_OUTFILE:
465                         if (goi->isconfigure) {
466                                 const char *s;
467                                 e = jim_getopt_string(goi, &s, NULL);
468                                 if (e != JIM_OK)
469                                         return e;
470                                 if (s[0] == ':') {
471                                         char *end;
472                                         long port = strtol(s + 1, &end, 0);
473                                         if (port <= 0 || port > UINT16_MAX || *end != '\0') {
474                                                 Jim_SetResultFormatted(goi->interp, "Invalid TCP port \'%s\'", s + 1);
475                                                 return JIM_ERR;
476                                         }
477                                 }
478                                 free(obj->out_filename);
479                                 obj->out_filename = strdup(s);
480                                 if (!obj->out_filename) {
481                                         LOG_ERROR("Out of memory");
482                                         return JIM_ERR;
483                                 }
484                         } else {
485                                 if (goi->argc)
486                                         goto err_no_params;
487                                 if (obj->out_filename)
488                                         Jim_SetResult(goi->interp, Jim_NewStringObj(goi->interp, obj->out_filename, -1));
489                         }
490                         break;
491                 case CFG_EVENT:
492                         if (goi->isconfigure) {
493                                 if (goi->argc < 2) {
494                                         Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv, "-event ?event-name? ?EVENT-BODY?");
495                                         return JIM_ERR;
496                                 }
497                         } else {
498                                 if (goi->argc != 1) {
499                                         Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv, "-event ?event-name?");
500                                         return JIM_ERR;
501                                 }
502                         }
503
504                         {
505                                 struct jim_nvp *p;
506                                 Jim_Obj *o;
507                                 struct arm_tpiu_swo_event_action *ea = obj->event_action;
508
509                                 e = jim_getopt_nvp(goi, nvp_arm_tpiu_swo_event, &p);
510                                 if (e != JIM_OK) {
511                                         jim_getopt_nvp_unknown(goi, nvp_arm_tpiu_swo_event, 1);
512                                         return e;
513                                 }
514
515                                 while (ea) {
516                                         /* replace existing? */
517                                         if (ea->event == (enum arm_tpiu_swo_event)p->value)
518                                                 break;
519                                         ea = ea->next;
520                                 }
521
522                                 if (goi->isconfigure) {
523                                         if (!ea) {
524                                                 ea = calloc(1, sizeof(*ea));
525                                                 if (!ea) {
526                                                         LOG_ERROR("Out of memory");
527                                                         return JIM_ERR;
528                                                 }
529                                                 ea->next = obj->event_action;
530                                                 obj->event_action = ea;
531                                         }
532                                         if (ea->body)
533                                                 Jim_DecrRefCount(ea->interp, ea->body);
534                                         ea->event = p->value;
535                                         ea->interp = goi->interp;
536                                         jim_getopt_obj(goi, &o);
537                                         ea->body = Jim_DuplicateObj(goi->interp, o);
538                                         Jim_IncrRefCount(ea->body);
539                                 } else {
540                                         if (ea)
541                                                 Jim_SetResult(goi->interp, Jim_DuplicateObj(goi->interp, ea->body));
542                                 }
543                         }
544                         break;
545                 }
546         }
547
548         return JIM_OK;
549
550 err_no_params:
551         Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv, "NO PARAMS");
552         return JIM_ERR;
553 }
554
555 static int jim_arm_tpiu_swo_configure(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
556 {
557         struct command *c = jim_to_command(interp);
558         struct jim_getopt_info goi;
559
560         jim_getopt_setup(&goi, interp, argc - 1, argv + 1);
561         goi.isconfigure = !strcmp(c->name, "configure");
562         if (goi.argc < 1) {
563                 Jim_WrongNumArgs(goi.interp, goi.argc, goi.argv,
564                         "missing: -option ...");
565                 return JIM_ERR;
566         }
567         struct arm_tpiu_swo_object *obj = c->jim_handler_data;
568         return arm_tpiu_swo_configure(&goi, obj);
569 }
570
571 static int wrap_write_u32(struct target *target, struct adiv5_ap *tpiu_ap,
572                 target_addr_t address, uint32_t value)
573 {
574         if (transport_is_hla())
575                 return target_write_u32(target, address, value);
576         else
577                 return mem_ap_write_atomic_u32(tpiu_ap, address, value);
578 }
579
580 static int wrap_read_u32(struct target *target, struct adiv5_ap *tpiu_ap,
581                 target_addr_t address, uint32_t *value)
582 {
583         if (transport_is_hla())
584                 return target_read_u32(target, address, value);
585         else
586                 return mem_ap_read_atomic_u32(tpiu_ap, address, value);
587 }
588
589 static const struct service_driver arm_tpiu_swo_service_driver = {
590         .name = "tpiu_swo_trace",
591         .new_connection_during_keep_alive_handler = NULL,
592         .new_connection_handler = arm_tpiu_swo_service_new_connection,
593         .input_handler = arm_tpiu_swo_service_input,
594         .connection_closed_handler = arm_tpiu_swo_service_connection_closed,
595         .keep_client_alive_handler = NULL,
596 };
597
598 static int jim_arm_tpiu_swo_enable(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
599 {
600         struct command *c = jim_to_command(interp);
601         struct arm_tpiu_swo_object *obj = c->jim_handler_data;
602         struct command_context *cmd_ctx = current_command_context(interp);
603         uint32_t value;
604         int retval;
605
606         if (argc != 1) {
607                 Jim_WrongNumArgs(interp, 1, argv, "Too many parameters");
608                 return JIM_ERR;
609         }
610
611         if (cmd_ctx->mode == COMMAND_CONFIG) {
612                 LOG_DEBUG("%s: enable deferred", obj->name);
613                 obj->deferred_enable = true;
614                 return JIM_OK;
615         }
616
617         if (obj->enabled)
618                 return JIM_OK;
619
620         if (transport_is_hla() && obj->spot.ap_num != 0) {
621                 LOG_ERROR("Invalid access port 0x%" PRIx64 ". Only AP#0 allowed with hla transport", obj->spot.ap_num);
622                 return JIM_ERR;
623         }
624
625         if (!obj->traceclkin_freq) {
626                 LOG_ERROR("Trace clock-in frequency not set");
627                 return JIM_ERR;
628         }
629
630         if (obj->pin_protocol == TPIU_SPPR_PROTOCOL_MANCHESTER || obj->pin_protocol == TPIU_SPPR_PROTOCOL_UART)
631                 if (!obj->swo_pin_freq)
632                         LOG_DEBUG("SWO pin frequency not set, will be autodetected by the adapter");
633
634         struct target *target = get_current_target(cmd_ctx);
635
636         /* START_DEPRECATED_TPIU */
637         if (obj->recheck_ap_cur_target) {
638                 if (strcmp(target->type->name, "cortex_m") &&
639                         strcmp(target->type->name, "hla_target")) {
640                         LOG_ERROR(MSG "Current target is not a Cortex-M nor a HLA");
641                         return JIM_ERR;
642                 }
643                 if (!target_was_examined(target)) {
644                         LOG_ERROR(MSG "Current target not examined yet");
645                         return JIM_ERR;
646                 }
647                 struct cortex_m_common *cm = target_to_cm(target);
648                 obj->recheck_ap_cur_target = false;
649                 obj->spot.ap_num = cm->armv7m.debug_ap->ap_num;
650                 if (obj->spot.ap_num == 0)
651                         LOG_INFO(MSG "Confirmed TPIU %s is on AP 0", obj->name);
652                 else
653                         LOG_INFO(MSG "Target %s is on AP#0x%" PRIx64 ". Revised command is "
654                                 "\'tpiu create %s -dap %s -ap-num 0x%" PRIx64 "\'",
655                                 target_name(target), obj->spot.ap_num,
656                                 obj->name, adiv5_dap_name(obj->spot.dap), obj->spot.ap_num);
657         }
658         /* END_DEPRECATED_TPIU */
659
660         if (!obj->ap) {
661                 obj->ap = dap_get_ap(obj->spot.dap, obj->spot.ap_num);
662                 if (!obj->ap) {
663                         LOG_ERROR("Cannot get AP");
664                         return JIM_ERR;
665                 }
666         }
667
668         /* trigger the event before any attempt to R/W in the TPIU/SWO */
669         arm_tpiu_swo_handle_event(obj, TPIU_SWO_EVENT_PRE_ENABLE);
670
671         retval = wrap_read_u32(target, obj->ap, obj->spot.base + TPIU_DEVID_OFFSET, &value);
672         if (retval != ERROR_OK) {
673                 LOG_ERROR("Unable to read %s", obj->name);
674                 return JIM_ERR;
675         }
676         switch (obj->pin_protocol) {
677         case TPIU_SPPR_PROTOCOL_SYNC:
678                 value = !(value & TPIU_DEVID_NOSUPPORT_SYNC);
679                 break;
680         case TPIU_SPPR_PROTOCOL_UART:
681                 value &= TPIU_DEVID_SUPPORT_UART;
682                 break;
683         case TPIU_SPPR_PROTOCOL_MANCHESTER:
684                 value &= TPIU_DEVID_SUPPORT_MANCHESTER;
685                 break;
686         default:
687                 value = 0;
688         }
689         if (!value) {
690                 struct jim_nvp *p;
691                 jim_nvp_value2name(interp, nvp_arm_tpiu_swo_protocol_opts, obj->pin_protocol, &p);
692                 LOG_ERROR("%s does not support protocol %s", obj->name, p->name);
693                 return JIM_ERR;
694         }
695
696         if (obj->pin_protocol == TPIU_SPPR_PROTOCOL_SYNC) {
697                 retval = wrap_read_u32(target, obj->ap, obj->spot.base + TPIU_SSPSR_OFFSET, &value);
698                 if (retval != ERROR_OK) {
699                         LOG_ERROR("Cannot read TPIU register SSPSR");
700                         return JIM_ERR;
701                 }
702                 if (!(value & BIT(obj->port_width - 1))) {
703                         LOG_ERROR("TPIU does not support port-width of %d bits", obj->port_width);
704                         return JIM_ERR;
705                 }
706         }
707
708         uint16_t prescaler = 1; /* dummy value */
709         unsigned int swo_pin_freq = obj->swo_pin_freq; /* could be replaced */
710
711         if (obj->out_filename && strcmp(obj->out_filename, "external") && obj->out_filename[0]) {
712                 if (obj->out_filename[0] == ':') {
713                         struct arm_tpiu_swo_priv_connection *priv = malloc(sizeof(*priv));
714                         if (!priv) {
715                                 LOG_ERROR("Out of memory");
716                                 return JIM_ERR;
717                         }
718                         priv->obj = obj;
719                         LOG_INFO("starting trace server for %s on %s", obj->name, &obj->out_filename[1]);
720                         retval = add_service(&arm_tpiu_swo_service_driver, &obj->out_filename[1],
721                                 CONNECTION_LIMIT_UNLIMITED, priv);
722                         if (retval != ERROR_OK) {
723                                 LOG_ERROR("Can't configure trace TCP port %s", &obj->out_filename[1]);
724                                 return JIM_ERR;
725                         }
726                 } else if (strcmp(obj->out_filename, "-")) {
727                         obj->file = fopen(obj->out_filename, "ab");
728                         if (!obj->file) {
729                                 LOG_ERROR("Can't open trace destination file \"%s\"", obj->out_filename);
730                                 return JIM_ERR;
731                         }
732                 }
733
734                 retval = adapter_config_trace(true, obj->pin_protocol, obj->port_width,
735                         &swo_pin_freq, obj->traceclkin_freq, &prescaler);
736                 if (retval != ERROR_OK) {
737                         LOG_ERROR("Failed to start adapter's trace");
738                         arm_tpiu_swo_close_output(obj);
739                         return JIM_ERR;
740                 }
741
742                 if (obj->pin_protocol == TPIU_SPPR_PROTOCOL_MANCHESTER || obj->pin_protocol == TPIU_SPPR_PROTOCOL_UART)
743                         if (!swo_pin_freq) {
744                                 if (obj->swo_pin_freq)
745                                         LOG_ERROR("Adapter rejected SWO pin frequency %d Hz", obj->swo_pin_freq);
746                                 else
747                                         LOG_ERROR("Adapter does not support auto-detection of SWO pin frequency nor a default value");
748
749                                 arm_tpiu_swo_close_output(obj);
750                                 return JIM_ERR;
751                         }
752
753                 if (obj->swo_pin_freq != swo_pin_freq)
754                         LOG_INFO("SWO pin data rate adjusted by adapter to %d Hz", swo_pin_freq);
755                 obj->swo_pin_freq = swo_pin_freq;
756
757                 target_register_timer_callback(arm_tpiu_swo_poll_trace, 1,
758                         TARGET_TIMER_TYPE_PERIODIC, obj);
759
760                 obj->en_capture = true;
761         } else if (obj->pin_protocol == TPIU_SPPR_PROTOCOL_MANCHESTER || obj->pin_protocol == TPIU_SPPR_PROTOCOL_UART) {
762                 prescaler = (obj->traceclkin_freq + obj->swo_pin_freq / 2) / obj->swo_pin_freq;
763                 if (prescaler > TPIU_ACPR_MAX_PRESCALER)
764                         prescaler = TPIU_ACPR_MAX_PRESCALER;
765                 swo_pin_freq = obj->traceclkin_freq / prescaler;
766
767                 if (obj->swo_pin_freq != swo_pin_freq)
768                         LOG_INFO("SWO pin data rate adjusted to %d Hz", swo_pin_freq);
769                 obj->swo_pin_freq = swo_pin_freq;
770         }
771
772         retval = wrap_write_u32(target, obj->ap, obj->spot.base + TPIU_CSPSR_OFFSET, BIT(obj->port_width - 1));
773         if (retval != ERROR_OK)
774                 goto error_exit;
775
776         retval = wrap_write_u32(target, obj->ap, obj->spot.base + TPIU_ACPR_OFFSET, prescaler - 1);
777         if (retval != ERROR_OK)
778                 goto error_exit;
779
780         retval = wrap_write_u32(target, obj->ap, obj->spot.base + TPIU_SPPR_OFFSET, obj->pin_protocol);
781         if (retval != ERROR_OK)
782                 goto error_exit;
783
784         retval = wrap_read_u32(target, obj->ap, obj->spot.base + TPIU_FFCR_OFFSET, &value);
785         if (retval != ERROR_OK)
786                 goto error_exit;
787         if (obj->en_formatter)
788                 value |= BIT(1);
789         else
790                 value &= ~BIT(1);
791         retval = wrap_write_u32(target, obj->ap, obj->spot.base + TPIU_FFCR_OFFSET, value);
792         if (retval != ERROR_OK)
793                 goto error_exit;
794
795         arm_tpiu_swo_handle_event(obj, TPIU_SWO_EVENT_POST_ENABLE);
796
797         /* START_DEPRECATED_TPIU */
798         target_handle_event(target, TARGET_EVENT_TRACE_CONFIG);
799         /* END_DEPRECATED_TPIU */
800
801         obj->enabled = true;
802         return JIM_OK;
803
804 error_exit:
805         LOG_ERROR("Error!");
806
807         if (obj->en_capture) {
808                 obj->en_capture = false;
809
810                 arm_tpiu_swo_close_output(obj);
811
812                 target_unregister_timer_callback(arm_tpiu_swo_poll_trace, obj);
813
814                 retval = adapter_config_trace(false, 0, 0, NULL, 0, NULL);
815                 if (retval != ERROR_OK) {
816                         LOG_ERROR("Failed to stop adapter's trace");
817                         return JIM_ERR;
818                 }
819         }
820         return JIM_ERR;
821 }
822
823 static int jim_arm_tpiu_swo_disable(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
824 {
825         struct command *c = jim_to_command(interp);
826         struct arm_tpiu_swo_object *obj = c->jim_handler_data;
827
828         if (argc != 1) {
829                 Jim_WrongNumArgs(interp, 1, argv, "Too many parameters");
830                 return JIM_ERR;
831         }
832
833         if (!obj->enabled)
834                 return JIM_OK;
835         obj->enabled = false;
836
837         arm_tpiu_swo_handle_event(obj, TPIU_SWO_EVENT_PRE_DISABLE);
838
839         if (obj->en_capture) {
840                 obj->en_capture = false;
841
842                 arm_tpiu_swo_close_output(obj);
843
844                 target_unregister_timer_callback(arm_tpiu_swo_poll_trace, obj);
845
846                 int retval = adapter_config_trace(false, 0, 0, NULL, 0, NULL);
847                 if (retval != ERROR_OK) {
848                         LOG_ERROR("Failed to stop adapter's trace");
849                         return JIM_ERR;
850                 }
851         }
852
853         arm_tpiu_swo_handle_event(obj, TPIU_SWO_EVENT_POST_DISABLE);
854
855         /* START_DEPRECATED_TPIU */
856         struct command_context *cmd_ctx = current_command_context(interp);
857         struct target *target = get_current_target(cmd_ctx);
858         target_handle_event(target, TARGET_EVENT_TRACE_CONFIG);
859         /* END_DEPRECATED_TPIU */
860
861         return JIM_OK;
862 }
863
864 static const struct command_registration arm_tpiu_swo_instance_command_handlers[] = {
865         {
866                 .name = "configure",
867                 .mode = COMMAND_ANY,
868                 .jim_handler = jim_arm_tpiu_swo_configure,
869                 .help  = "configure a new TPIU/SWO for use",
870                 .usage = "[attribute value ...]",
871         },
872         {
873                 .name = "cget",
874                 .mode = COMMAND_ANY,
875                 .jim_handler = jim_arm_tpiu_swo_configure,
876                 .help  = "returns the specified TPIU/SWO attribute",
877                 .usage = "attribute",
878         },
879         {
880                 .name = "eventlist",
881                 .mode = COMMAND_ANY,
882                 .handler = handle_arm_tpiu_swo_event_list,
883                 .help = "displays a table of events defined for this TPIU/SWO",
884                 .usage = "",
885         },
886         {
887                 .name = "enable",
888                 .mode = COMMAND_ANY,
889                 .jim_handler = jim_arm_tpiu_swo_enable,
890                 .usage = "",
891                 .help = "Enables the TPIU/SWO output",
892         },
893         {
894                 .name = "disable",
895                 .mode = COMMAND_EXEC,
896                 .jim_handler = jim_arm_tpiu_swo_disable,
897                 .usage = "",
898                 .help = "Disables the TPIU/SWO output",
899         },
900         COMMAND_REGISTRATION_DONE
901 };
902
903 static int arm_tpiu_swo_create(Jim_Interp *interp, struct arm_tpiu_swo_object *obj)
904 {
905         struct command_context *cmd_ctx;
906         Jim_Cmd *cmd;
907         int e;
908
909         cmd_ctx = current_command_context(interp);
910         assert(cmd_ctx);
911
912         /* does this command exist? */
913         cmd = Jim_GetCommand(interp, Jim_NewStringObj(interp, obj->name, -1), JIM_NONE);
914         if (cmd) {
915                 Jim_SetResultFormatted(interp, "cannot create TPIU object because a command with name '%s' already exists",
916                         obj->name);
917                 return JIM_ERR;
918         }
919
920         /* now - create the new tpiu/swo name command */
921         const struct command_registration obj_commands[] = {
922                 {
923                         .name = obj->name,
924                         .mode = COMMAND_ANY,
925                         .help = "tpiu/swo instance command group",
926                         .usage = "",
927                         .chain = arm_tpiu_swo_instance_command_handlers,
928                 },
929                 COMMAND_REGISTRATION_DONE
930         };
931         e = register_commands_with_data(cmd_ctx, NULL, obj_commands, obj);
932         if (e != ERROR_OK)
933                 return JIM_ERR;
934
935         list_add_tail(&obj->lh, &all_tpiu_swo);
936
937         return JIM_OK;
938 }
939
940 static int jim_arm_tpiu_swo_create(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
941 {
942         struct jim_getopt_info goi;
943         jim_getopt_setup(&goi, interp, argc - 1, argv + 1);
944         if (goi.argc < 1) {
945                 Jim_WrongNumArgs(interp, 1, argv, "name ?option option ...?");
946                 return JIM_ERR;
947         }
948
949         struct arm_tpiu_swo_object *obj = calloc(1, sizeof(struct arm_tpiu_swo_object));
950         if (!obj) {
951                 LOG_ERROR("Out of memory");
952                 return JIM_ERR;
953         }
954         INIT_LIST_HEAD(&obj->connections);
955         adiv5_mem_ap_spot_init(&obj->spot);
956         obj->spot.base = TPIU_SWO_DEFAULT_BASE;
957         obj->port_width = 1;
958
959         Jim_Obj *n;
960         jim_getopt_obj(&goi, &n);
961         obj->name = strdup(Jim_GetString(n, NULL));
962         if (!obj->name) {
963                 LOG_ERROR("Out of memory");
964                 free(obj);
965                 return JIM_ERR;
966         }
967
968         /* Do the rest as "configure" options */
969         goi.isconfigure = 1;
970         int e = arm_tpiu_swo_configure(&goi, obj);
971         if (e != JIM_OK)
972                 goto err_exit;
973
974         if (!obj->spot.dap || obj->spot.ap_num == DP_APSEL_INVALID) {
975                 Jim_SetResultString(goi.interp, "-dap and -ap-num required when creating TPIU", -1);
976                 goto err_exit;
977         }
978
979         e = arm_tpiu_swo_create(goi.interp, obj);
980         if (e != JIM_OK)
981                 goto err_exit;
982
983         return JIM_OK;
984
985 err_exit:
986         free(obj->name);
987         free(obj->out_filename);
988         free(obj);
989         return JIM_ERR;
990 }
991
992 static int jim_arm_tpiu_swo_names(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
993 {
994         struct arm_tpiu_swo_object *obj;
995
996         if (argc != 1) {
997                 Jim_WrongNumArgs(interp, 1, argv, "Too many parameters");
998                 return JIM_ERR;
999         }
1000         Jim_SetResult(interp, Jim_NewListObj(interp, NULL, 0));
1001         list_for_each_entry(obj, &all_tpiu_swo, lh) {
1002                 Jim_ListAppendElement(interp, Jim_GetResult(interp),
1003                         Jim_NewStringObj(interp, obj->name, -1));
1004         }
1005         return JIM_OK;
1006 }
1007
1008 static int jim_arm_tpiu_swo_init(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
1009 {
1010         struct command_context *cmd_ctx = current_command_context(interp);
1011         struct arm_tpiu_swo_object *obj;
1012         int retval = JIM_OK;
1013
1014         if (argc != 1) {
1015                 Jim_WrongNumArgs(interp, 1, argv, "Too many parameters");
1016                 return JIM_ERR;
1017         }
1018         list_for_each_entry(obj, &all_tpiu_swo, lh) {
1019                 if (!obj->deferred_enable)
1020                         continue;
1021                 LOG_DEBUG("%s: running enable during init", obj->name);
1022                 int retval2 = command_run_linef(cmd_ctx, "%s enable", obj->name);
1023                 if (retval2 != ERROR_OK)
1024                         retval = JIM_ERR;
1025         }
1026         return retval;
1027 }
1028
1029 /* START_DEPRECATED_TPIU */
1030 /* DEPRECATED: emulation of old command 'tpiu config' */
1031 COMMAND_HANDLER(handle_tpiu_deprecated_config_command)
1032 {
1033         struct target *target = get_current_target(CMD_CTX);
1034         struct arm_tpiu_swo_object *obj = NULL;
1035         int retval;
1036
1037         if (strcmp(target->type->name, "cortex_m") &&
1038                 strcmp(target->type->name, "hla_target")) {
1039                 LOG_ERROR(MSG "Current target is not a Cortex-M nor a HLA");
1040                 return ERROR_FAIL;
1041         }
1042
1043         if (!list_empty(&all_tpiu_swo)) {
1044                 obj = list_first_entry(&all_tpiu_swo, typeof(*obj), lh);
1045                 LOG_INFO(MSG "Using %s", obj->name);
1046         } else {
1047                 struct cortex_m_common *cm = target_to_cm(target);
1048                 struct adiv5_private_config *pc = target->private_config;
1049                 struct adiv5_dap *dap = pc->dap;
1050                 uint64_t ap_num = pc->ap_num;
1051                 bool set_recheck_ap_cur_target = false;
1052
1053                 LOG_INFO(MSG "Adding a TPIU \'%s.tpiu\' in the configuration", target_name(target));
1054
1055                 if (ap_num == DP_APSEL_INVALID && transport_is_hla())
1056                         ap_num = 0; /* HLA should only support AP 0 */
1057
1058                 if (ap_num == DP_APSEL_INVALID && target_was_examined(target))
1059                         ap_num = cm->armv7m.debug_ap->ap_num;
1060
1061                 if (ap_num == DP_APSEL_INVALID) {
1062                         LOG_INFO(MSG "Target %s uses AP autodetection. Adding TPIU on AP 0; can be revised later",
1063                                 target_name(target));
1064                         ap_num = 0;
1065                         set_recheck_ap_cur_target = true;
1066                 }
1067
1068                 LOG_INFO(MSG "Running: \'tpiu create %s.tpiu -dap %s -ap-num 0x%" PRIx64 "\'",
1069                         target_name(target), adiv5_dap_name(dap), ap_num);
1070
1071                 retval = command_run_linef(CMD_CTX, "tpiu create %s.tpiu -dap %s -ap-num 0x%" PRIx64,
1072                         target_name(target), adiv5_dap_name(dap), ap_num);
1073                 if (retval != ERROR_OK)
1074                         return retval;
1075
1076                 obj = list_first_entry(&all_tpiu_swo, typeof(*obj), lh);
1077                 if (set_recheck_ap_cur_target)
1078                         obj->recheck_ap_cur_target = true;
1079         }
1080
1081         unsigned int cmd_idx = 0;
1082         if (cmd_idx == CMD_ARGC)
1083                 return ERROR_COMMAND_SYNTAX_ERROR;
1084
1085         if (!strcmp(CMD_ARGV[cmd_idx], "disable")) {
1086                 if (CMD_ARGC != cmd_idx + 1)
1087                         return ERROR_COMMAND_SYNTAX_ERROR;
1088                 LOG_INFO(MSG "Running: \'%s disable\'", obj->name);
1089                 return command_run_linef(CMD_CTX, "%s disable", obj->name);
1090         }
1091
1092         const char *output = NULL;
1093         const char *protocol;
1094         const char *formatter = NULL;
1095         const char *port_width = NULL;
1096         const char *trace_clk;
1097         const char *pin_clk = NULL;
1098         if (!strcmp(CMD_ARGV[cmd_idx], "internal")) {
1099                 cmd_idx++;
1100                 if (cmd_idx == CMD_ARGC)
1101                         return ERROR_COMMAND_SYNTAX_ERROR;
1102                 output = CMD_ARGV[cmd_idx];
1103         } else if (strcmp(CMD_ARGV[cmd_idx], "external"))
1104                 return ERROR_COMMAND_SYNTAX_ERROR;
1105         cmd_idx++;
1106         if (cmd_idx == CMD_ARGC)
1107                 return ERROR_COMMAND_SYNTAX_ERROR;
1108         if (!strcmp(CMD_ARGV[cmd_idx], "sync")) {
1109                 protocol = CMD_ARGV[cmd_idx];
1110                 cmd_idx++;
1111                 if (cmd_idx == CMD_ARGC)
1112                         return ERROR_COMMAND_SYNTAX_ERROR;
1113                 port_width = CMD_ARGV[cmd_idx];
1114         } else {
1115                 if (strcmp(CMD_ARGV[cmd_idx], "manchester") && strcmp(CMD_ARGV[cmd_idx], "uart"))
1116                         return ERROR_COMMAND_SYNTAX_ERROR;
1117                 protocol = CMD_ARGV[cmd_idx];
1118                 cmd_idx++;
1119                 if (cmd_idx == CMD_ARGC)
1120                         return ERROR_COMMAND_SYNTAX_ERROR;
1121                 formatter = CMD_ARGV[cmd_idx];
1122         }
1123         cmd_idx++;
1124         if (cmd_idx == CMD_ARGC)
1125                 return ERROR_COMMAND_SYNTAX_ERROR;
1126         trace_clk = CMD_ARGV[cmd_idx];
1127         cmd_idx++;
1128         if (cmd_idx != CMD_ARGC) {
1129                 pin_clk = CMD_ARGV[cmd_idx];
1130                 cmd_idx++;
1131         }
1132         if (cmd_idx != CMD_ARGC)
1133                 return ERROR_COMMAND_SYNTAX_ERROR;
1134
1135         LOG_INFO(MSG "Running: \'%s configure -protocol %s -traceclk %s" "%s%s" "%s%s" "%s%s" "%s%s\'",
1136                 obj->name, protocol, trace_clk,
1137                 pin_clk    ? " -pin-freq "   : "", pin_clk    ? pin_clk    : "",
1138                 output     ? " -output "     : "", output     ? output     : "",
1139                 formatter  ? " -formatter "  : "", formatter  ? formatter  : "",
1140                 port_width ? " -port-width " : "", port_width ? port_width : "");
1141
1142         retval = command_run_linef(CMD_CTX,
1143                 "%s configure -protocol %s -traceclk %s" "%s%s" "%s%s" "%s%s" "%s%s",
1144                 obj->name, protocol, trace_clk,
1145                 pin_clk    ? " -pin-freq "   : "", pin_clk    ? pin_clk    : "",
1146                 output     ? " -output "     : "", output     ? output     : "",
1147                 formatter  ? " -formatter "  : "", formatter  ? formatter  : "",
1148                 port_width ? " -port-width " : "", port_width ? port_width : "");
1149         if (retval != ERROR_OK)
1150                 return retval;
1151
1152         LOG_INFO(MSG "Running: \'%s enable\'", obj->name);
1153         retval = command_run_linef(CMD_CTX, "%s enable", obj->name);
1154         if (retval != ERROR_OK)
1155                 return retval;
1156
1157         return ERROR_OK;
1158 }
1159
1160 static const struct command_registration arm_tpiu_deprecated_subcommand_handlers[] = {
1161         {
1162                 .name = "config",
1163                 .handler = handle_tpiu_deprecated_config_command,
1164                 .mode = COMMAND_ANY,
1165                 .help = "Configure TPIU features, DEPRECATED, use \'tpiu create\'",
1166                 .usage = "(disable | "
1167                 "((external | internal (<filename> | <:port> | -)) "
1168                 "(sync <port width> | ((manchester | uart) <formatter enable>)) "
1169                 "<TRACECLKIN freq> [<trace freq>]))",
1170         },
1171         COMMAND_REGISTRATION_DONE
1172 };
1173
1174 const struct command_registration arm_tpiu_deprecated_command_handlers[] = {
1175         {
1176                 .name = "tpiu",
1177                 .chain = arm_tpiu_deprecated_subcommand_handlers,
1178                 .usage = "",
1179                 .help = "tpiu command group",
1180         },
1181         COMMAND_REGISTRATION_DONE
1182 };
1183 /* END_DEPRECATED_TPIU */
1184
1185 static const struct command_registration arm_tpiu_swo_subcommand_handlers[] = {
1186         {
1187                 .name = "create",
1188                 .mode = COMMAND_ANY,
1189                 .jim_handler = jim_arm_tpiu_swo_create,
1190                 .usage = "name [-dap dap] [-ap-num num] [-baseaddr baseaddr]",
1191                 .help = "Creates a new TPIU or SWO object",
1192         },
1193         {
1194                 .name = "names",
1195                 .mode = COMMAND_ANY,
1196                 .jim_handler = jim_arm_tpiu_swo_names,
1197                 .usage = "",
1198                 .help = "Lists all registered TPIU and SWO objects by name",
1199         },
1200         {
1201                 .name = "init",
1202                 .mode = COMMAND_EXEC,
1203                 .jim_handler = jim_arm_tpiu_swo_init,
1204                 .usage = "",
1205                 .help = "Initialize TPIU and SWO",
1206         },
1207         COMMAND_REGISTRATION_DONE
1208 };
1209
1210 static const struct command_registration arm_tpiu_swo_command_handlers[] = {
1211         {
1212                 .name = "tpiu",
1213                 .chain = arm_tpiu_swo_subcommand_handlers,
1214                 .usage = "",
1215                 .help = "tpiu command group",
1216         },
1217         {
1218                 .name = "swo",
1219                 .chain = arm_tpiu_swo_subcommand_handlers,
1220                 .usage = "",
1221                 .help = "swo command group",
1222         },
1223         COMMAND_REGISTRATION_DONE
1224 };
1225
1226 int arm_tpiu_swo_register_commands(struct command_context *cmd_ctx)
1227 {
1228         return register_commands(cmd_ctx, NULL, arm_tpiu_swo_command_handlers);
1229 }