43 #define MSG "DEPRECATED \'tpiu config\' command: "
46 #define TCP_SERVICE_NAME "tpiu_swo_trace"
49 #define TPIU_SWO_DEFAULT_BASE 0xE0040000
51 #define TPIU_SSPSR_OFFSET 0x000
52 #define TPIU_CSPSR_OFFSET 0x004
53 #define TPIU_ACPR_OFFSET 0x010
54 #define TPIU_SPPR_OFFSET 0x0F0
55 #define TPIU_FFSR_OFFSET 0x300
56 #define TPIU_FFCR_OFFSET 0x304
57 #define TPIU_FSCR_OFFSET 0x308
58 #define TPIU_DEVID_OFFSET 0xfc8
60 #define TPIU_ACPR_MAX_PRESCALER 0x1fff
61 #define TPIU_SPPR_PROTOCOL_SYNC (TPIU_PIN_PROTOCOL_SYNC)
62 #define TPIU_SPPR_PROTOCOL_MANCHESTER (TPIU_PIN_PROTOCOL_ASYNC_MANCHESTER)
63 #define TPIU_SPPR_PROTOCOL_UART (TPIU_PIN_PROTOCOL_ASYNC_UART)
64 #define TPIU_DEVID_NOSUPPORT_SYNC BIT(9)
65 #define TPIU_DEVID_SUPPORT_MANCHESTER BIT(10)
66 #define TPIU_DEVID_SUPPORT_UART BIT(11)
131 #define ARM_TPIU_SWO_TRACE_BUF_SIZE 4096
137 size_t size =
sizeof(buf);
150 LOG_ERROR(
"Error writing to the SWO trace destination file");
158 LOG_ERROR(
"Error writing to connection");
166 if (ea->event != event)
169 LOG_DEBUG(
"TPIU/SWO: %s event: %s (%d) action : %s",
173 Jim_GetString(ea->body,
NULL));
178 int retval = Jim_EvalObj(ea->interp, ea->body);
181 if (retval == JIM_RETURN)
182 retval = ea->interp->returnCode;
186 Jim_MakeErrorMessage(ea->interp);
187 LOG_USER(
"Error executing event %s on TPIU/SWO %s:\n%s",
190 Jim_GetString(Jim_GetResult(ea->interp),
NULL));
192 Jim_Eval(ea->interp,
"error \"\" \"\"");
224 LOG_ERROR(
"Failed to stop adapter's trace");
269 if (bytes_read == 0) {
271 }
else if (bytes_read == -1) {
272 LOG_ERROR(
"error during read: %s", strerror(errno));
291 LOG_ERROR(
"Failed to find connection to close!");
302 "----------------------------------------");
307 opt->
name, Jim_GetString(ea->body,
NULL));
330 { .name =
"-event", .value =
CFG_EVENT },
332 { .name =
"-dap", .value = -1 },
333 { .name =
"-ap-num", .value = -1 },
334 { .name =
"-baseaddr", .value = -1 },
335 { .name =
NULL, .value = -1 },
342 { .name =
NULL, .value = -1 },
346 { .
name =
"on", .value = 1 },
347 { .name =
"yes", .value = 1 },
348 { .name =
"1", .value = 1 },
349 { .name =
"true", .value = 1 },
350 { .name =
"off", .value = 0 },
351 { .name =
"no", .value = 0 },
352 { .name =
"0", .value = 0 },
353 { .name =
"false", .value = 0 },
354 { .name =
NULL, .value = -1 },
362 Jim_SetResultFormatted(goi->
interp,
"Cannot configure TPIU/SWO; %s is enabled!", obj->
name);
367 while (goi->
argc > 0) {
368 Jim_SetEmptyResult(goi->
interp);
390 if (port_width < 1 || port_width > 32) {
391 Jim_SetResultString(goi->
interp,
"Invalid port width!", -1);
414 Jim_SetResultString(goi->
interp,
"protocol error", -1);
433 Jim_SetResultString(goi->
interp,
"formatter error", -1);
473 long port = strtol(s + 1, &end, 0);
474 if (port <= 0 || port > UINT16_MAX || *end !=
'\0') {
475 Jim_SetResultFormatted(goi->
interp,
"Invalid TCP port \'%s\'", s + 1);
479 char *out_filename = strdup(s);
496 Jim_WrongNumArgs(goi->
interp, goi->
argc, goi->
argv,
"-event ?event-name? ?EVENT-BODY?");
500 if (goi->
argc != 1) {
501 Jim_WrongNumArgs(goi->
interp, goi->
argc, goi->
argv,
"-event ?event-name?");
526 ea = calloc(1,
sizeof(*ea));
540 Jim_IncrRefCount(ea->
body);
566 "missing: -option ...");
592 .
name =
"tpiu_swo_trace",
593 .new_connection_during_keep_alive_handler =
NULL,
597 .keep_client_alive_handler =
NULL,
620 "Invalid access port 0x%" PRIx64
". Only AP#0 allowed with hla transport",
630 const bool output_external = !strcmp(obj->
out_filename,
"external");
634 if (output_external) {
635 command_print(
CMD,
"SWO pin frequency required when using external capturing");
639 LOG_DEBUG(
"SWO pin frequency not set, will be autodetected by the adapter");
649 LOG_ERROR(
MSG "Current target is not a Cortex-M nor a HLA");
662 LOG_INFO(
MSG "Target %s is on AP#0x%" PRIx64
". Revised command is "
663 "\'tpiu create %s -dap %s -ap-num 0x%" PRIx64
"\'",
718 uint16_t prescaler = 1;
721 if (!output_external) {
758 "Adapter does not support auto-detection of SWO pin frequency nor a default value");
765 LOG_INFO(
"SWO pin data rate adjusted by adapter to %d Hz", swo_pin_freq);
779 LOG_INFO(
"SWO pin data rate adjusted to %d Hz", swo_pin_freq);
876 .help =
"configure a new TPIU/SWO for use",
877 .usage =
"[attribute value ...]",
883 .help =
"returns the specified TPIU/SWO attribute",
884 .usage =
"attribute",
889 .handler = handle_arm_tpiu_swo_event_list,
890 .help =
"displays a table of events defined for this TPIU/SWO",
896 .handler = handle_arm_tpiu_swo_enable,
898 .help =
"Enables the TPIU/SWO output",
903 .handler = handle_arm_tpiu_swo_disable,
905 .help =
"Disables the TPIU/SWO output",
922 Jim_SetResultFormatted(
interp,
"cannot create TPIU object because a command with name '%s' already exists",
932 .help =
"tpiu/swo instance command group",
952 Jim_WrongNumArgs(
interp, 1,
argv,
"name ?option option ...?");
973 obj->
name = strdup(Jim_GetString(n,
NULL));
986 Jim_SetResultString(goi.
interp,
"-dap and -ap-num required when creating TPIU", -1);
1045 LOG_ERROR(
MSG "Current target is not a Cortex-M nor a HLA");
1056 uint64_t ap_num = pc->
ap_num;
1057 bool set_recheck_ap_cur_target =
false;
1068 LOG_INFO(
MSG "Target %s uses AP autodetection. Adding TPIU on AP 0; can be revised later",
1071 set_recheck_ap_cur_target =
true;
1074 LOG_INFO(
MSG "Running: \'tpiu create %s.tpiu -dap %s -ap-num 0x%" PRIx64
"\'",
1083 if (set_recheck_ap_cur_target)
1087 unsigned int cmd_idx = 0;
1091 if (!strcmp(
CMD_ARGV[cmd_idx],
"disable")) {
1099 const char *protocol;
1100 const char *formatter =
NULL;
1101 const char *port_width =
NULL;
1102 const char *trace_clk;
1103 const char *pin_clk =
NULL;
1104 if (!strcmp(
CMD_ARGV[cmd_idx],
"internal")) {
1109 }
else if (strcmp(
CMD_ARGV[cmd_idx],
"external"))
1114 if (!strcmp(
CMD_ARGV[cmd_idx],
"sync")) {
1121 if (strcmp(
CMD_ARGV[cmd_idx],
"manchester") && strcmp(
CMD_ARGV[cmd_idx],
"uart"))
1141 LOG_INFO(
MSG "Running: \'%s configure -protocol %s -traceclk %s" "%s%s" "%s%s" "%s%s" "%s%s\'",
1142 obj->
name, protocol, trace_clk,
1143 pin_clk ?
" -pin-freq " :
"", pin_clk ? pin_clk :
"",
1145 formatter ?
" -formatter " :
"", formatter ? formatter :
"",
1146 port_width ?
" -port-width " :
"", port_width ? port_width :
"");
1149 "%s configure -protocol %s -traceclk %s" "%s%s" "%s%s" "%s%s" "%s%s",
1150 obj->
name, protocol, trace_clk,
1151 pin_clk ?
" -pin-freq " :
"", pin_clk ? pin_clk :
"",
1153 formatter ?
" -formatter " :
"", formatter ? formatter :
"",
1154 port_width ?
" -port-width " :
"", port_width ? port_width :
"");
1169 .handler = handle_tpiu_deprecated_config_command,
1171 .help =
"Configure TPIU features, DEPRECATED, use \'tpiu create\'",
1172 .usage =
"(disable | "
1173 "((external | internal (<filename> | <:port> | -)) "
1174 "(sync <port width> | ((manchester | uart) <formatter enable>)) "
1175 "<TRACECLKIN freq> [<trace freq>]))",
1185 .help =
"tpiu command group",
1196 .usage =
"name [-dap dap] [-ap-num num] [-baseaddr baseaddr]",
1197 .help =
"Creates a new TPIU or SWO object",
1202 .handler = handle_arm_tpiu_swo_names,
1204 .help =
"Lists all registered TPIU and SWO objects by name",
1209 .handler = handle_arm_tpiu_swo_init,
1211 .help =
"Initialize TPIU and SWO",
1221 .help =
"tpiu command group",
1227 .help =
"swo command group",
int adiv5_mem_ap_spot_init(struct adiv5_mem_ap_spot *p)
int mem_ap_read_atomic_u32(struct adiv5_ap *ap, target_addr_t address, uint32_t *value)
Synchronous read of a word from memory or a system register.
struct adiv5_ap * dap_get_ap(struct adiv5_dap *dap, uint64_t ap_num)
int dap_put_ap(struct adiv5_ap *ap)
int adiv5_jim_mem_ap_spot_configure(struct adiv5_mem_ap_spot *cfg, struct jim_getopt_info *goi)
int mem_ap_write_atomic_u32(struct adiv5_ap *ap, target_addr_t address, uint32_t value)
Synchronous write of a word to memory or a system register.
This defines formats and data structures used to talk to ADIv5 entities.
const char * adiv5_dap_name(struct adiv5_dap *self)
static LIST_HEAD(all_tpiu_swo)
static const struct jim_nvp nvp_arm_tpiu_swo_bool_opts[]
#define ARM_TPIU_SWO_TRACE_BUF_SIZE
static const struct command_registration arm_tpiu_deprecated_subcommand_handlers[]
static int jim_arm_tpiu_swo_configure(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
#define TPIU_SWO_DEFAULT_BASE
#define TPIU_SPPR_PROTOCOL_MANCHESTER
@ TPIU_SWO_EVENT_PRE_DISABLE
@ TPIU_SWO_EVENT_PRE_ENABLE
@ TPIU_SWO_EVENT_POST_ENABLE
@ TPIU_SWO_EVENT_POST_DISABLE
static const struct jim_nvp nvp_arm_tpiu_swo_config_opts[]
#define TPIU_DEVID_OFFSET
#define TPIU_CSPSR_OFFSET
static int jim_arm_tpiu_swo_create(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
static const struct service_driver arm_tpiu_swo_service_driver
const struct command_registration arm_tpiu_deprecated_command_handlers[]
static const struct command_registration arm_tpiu_swo_subcommand_handlers[]
static void arm_tpiu_swo_close_output(struct arm_tpiu_swo_object *obj)
int arm_tpiu_swo_register_commands(struct command_context *cmd_ctx)
static const struct jim_nvp nvp_arm_tpiu_swo_protocol_opts[]
static int arm_tpiu_swo_service_connection_closed(struct connection *connection)
static int arm_tpiu_swo_handle_event(struct arm_tpiu_swo_object *obj, enum arm_tpiu_swo_event event)
static int arm_tpiu_swo_service_input(struct connection *connection)
#define TPIU_SPPR_PROTOCOL_SYNC
static const struct command_registration arm_tpiu_swo_instance_command_handlers[]
static int arm_tpiu_swo_service_new_connection(struct connection *connection)
#define TPIU_ACPR_MAX_PRESCALER
#define TPIU_DEVID_SUPPORT_UART
#define TPIU_SPPR_PROTOCOL_UART
static const struct jim_nvp nvp_arm_tpiu_swo_event[]
static int arm_tpiu_swo_create(Jim_Interp *interp, struct arm_tpiu_swo_object *obj)
#define TPIU_DEVID_SUPPORT_MANCHESTER
static int wrap_write_u32(struct target *target, struct adiv5_ap *tpiu_ap, target_addr_t address, uint32_t value)
static const struct command_registration arm_tpiu_swo_command_handlers[]
#define TPIU_SSPSR_OFFSET
#define TPIU_DEVID_NOSUPPORT_SYNC
int arm_tpiu_swo_cleanup_all(void)
static int wrap_read_u32(struct target *target, struct adiv5_ap *tpiu_ap, target_addr_t address, uint32_t *value)
static int arm_tpiu_swo_configure(struct jim_getopt_info *goi, struct arm_tpiu_swo_object *obj)
COMMAND_HANDLER(handle_arm_tpiu_swo_event_list)
static int arm_tpiu_swo_poll_trace(void *priv)
struct command_context * current_command_context(Jim_Interp *interp)
void command_print(struct command_invocation *cmd, const char *format,...)
int command_run_linef(struct command_context *context, const char *format,...)
#define CMD
Use this macro to access the command being handled, rather than accessing the variable directly.
#define CMD_ARGV
Use this macro to access the arguments for the command being handled, rather than accessing the varia...
static int register_commands_with_data(struct command_context *cmd_ctx, const char *cmd_prefix, const struct command_registration *cmds, void *data)
Register one or more commands, as register_commands(), plus specify a pointer to command private data...
#define ERROR_COMMAND_SYNTAX_ERROR
#define CMD_DATA
Use this macro to access the invoked command handler's data pointer, rather than accessing the variab...
#define ERROR_COMMAND_CLOSE_CONNECTION
#define CMD_ARGC
Use this macro to access the number of arguments for the command being handled, rather than accessing...
#define CMD_CTX
Use this macro to access the context of the command being handled, rather than accessing the variable...
static struct command * jim_to_command(Jim_Interp *interp)
#define COMMAND_REGISTRATION_DONE
Use this as the last entry in an array of command_registration records.
static int register_commands(struct command_context *cmd_ctx, const char *cmd_prefix, const struct command_registration *cmds)
Register one or more commands in the specified context, as children of parent (or top-level commends,...
static struct cortex_m_common * target_to_cm(struct target *target)
static struct esp_usb_jtag * priv
bool transport_is_hla(void)
int jim_getopt_wide(struct jim_getopt_info *goi, jim_wide *puthere)
Remove argv[0] as wide.
int jim_getopt_setup(struct jim_getopt_info *p, Jim_Interp *interp, int argc, Jim_Obj *const *argv)
GetOpt - how to.
int jim_getopt_string(struct jim_getopt_info *goi, const char **puthere, int *len)
Remove argv[0] as string.
int jim_getopt_nvp(struct jim_getopt_info *goi, const struct jim_nvp *nvp, struct jim_nvp **puthere)
Remove argv[0] as NVP.
void jim_getopt_nvp_unknown(struct jim_getopt_info *goi, const struct jim_nvp *nvptable, int hadprefix)
Create an appropriate error message for an NVP.
int jim_getopt_obj(struct jim_getopt_info *goi, Jim_Obj **puthere)
Remove argv[0] from the list.
struct jim_nvp * jim_nvp_value2name_simple(const struct jim_nvp *p, int value)
int jim_nvp_value2name(Jim_Interp *interp, const struct jim_nvp *_p, int value, struct jim_nvp **result)
int adapter_config_trace(bool enabled, enum tpiu_pin_protocol pin_protocol, uint32_t port_size, unsigned int *trace_freq, unsigned int traceclkin_freq, uint16_t *prescaler)
int adapter_poll_trace(uint8_t *buf, size_t *size)
static void list_add(struct list_head *new, struct list_head *head)
#define list_first_entry(ptr, type, member)
static void list_add_tail(struct list_head *new, struct list_head *head)
static int list_empty(const struct list_head *head)
#define list_for_each_entry_safe(p, n, h, field)
#define list_for_each_entry(p, h, field)
static void list_del(struct list_head *entry)
static void INIT_LIST_HEAD(struct list_head *list)
#define LOG_USER(expr ...)
#define LOG_ERROR(expr ...)
#define LOG_INFO(expr ...)
#define LOG_DEBUG(expr ...)
static uint32_t lh(unsigned int rd, unsigned int base, uint16_t offset) __attribute__((unused))
size_t size
Size of the control block search area.
int connection_write(struct connection *connection, const void *data, int len)
int connection_read(struct connection *connection, void *data, int len)
int remove_service(const char *name, const char *port)
int add_service(const struct service_driver *driver, const char *port, int max_connections, void *priv)
#define CONNECTION_LIMIT_UNLIMITED
#define ERROR_SERVER_REMOTE_CLOSED
This represents an ARM Debug Interface (v5) Access Port (AP).
uint64_t ap_num
ADIv5: Number of this AP (0~255) ADIv6: Base address of this AP (4k aligned) TODO: to be more coheren...
This represents an ARM Debug Interface (v5) Debug Access Port (DAP).
struct connection * connection
struct arm_tpiu_swo_event_action * next
enum arm_tpiu_swo_event event
uint32_t port_width
Handle to output trace data in INTERNAL capture mode.
struct arm_tpiu_swo_event_action * event_action
bool recheck_ap_cur_target
bool en_formatter
Enable formatter.
unsigned int traceclkin_freq
frequency of TRACECLKIN (usually matches HCLK)
unsigned int swo_pin_freq
SWO pin frequency.
struct adiv5_mem_ap_spot spot
struct list_head connections
track TCP connections
unsigned int pin_protocol
output mode
char * out_filename
where to dump the captured output trace data
struct arm_tpiu_swo_object * obj
struct adiv5_ap * debug_ap
struct target * current_target
const char * usage
a string listing the options and arguments, required or optional
struct armv7m_common armv7m
A TCL -ish GetOpt like code.
Name Value Pairs, aka: NVP.
const char * name
the name of the server
int target_unregister_timer_callback(int(*callback)(void *priv), void *priv)
int target_write_u32(struct target *target, target_addr_t address, uint32_t value)
int target_register_timer_callback(int(*callback)(void *priv), unsigned int time_ms, enum target_timer_type type, void *priv)
The period is very approximate, the callback can happen much more often or much more rarely than spec...
int target_read_u32(struct target *target, target_addr_t address, uint32_t *value)
struct target * get_current_target(struct command_context *cmd_ctx)
void target_handle_event(struct target *target, enum target_event e)
const char * target_type_name(const struct target *target)
Get the target type name.
int target_call_trace_callbacks(struct target *target, size_t len, uint8_t *data)
static bool target_was_examined(const struct target *target)
@ TARGET_TIMER_TYPE_PERIODIC
@ TARGET_EVENT_TRACE_CONFIG
static const char * target_name(const struct target *target)
Returns the instance-specific name of the specified target.