44 #define MSG "DEPRECATED \'tpiu config\' command: "
47 #define TCP_SERVICE_NAME "tpiu_swo_trace"
50 #define TPIU_SWO_DEFAULT_BASE 0xE0040000
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
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)
132 #define ARM_TPIU_SWO_TRACE_BUF_SIZE 4096
138 size_t size =
sizeof(buf);
151 LOG_ERROR(
"Error writing to the SWO trace destination file");
159 LOG_ERROR(
"Error writing to connection");
167 if (ea->event != event)
170 LOG_DEBUG(
"TPIU/SWO: %s event: %s (%d) action : %s",
174 Jim_GetString(ea->body,
NULL));
179 int retval = Jim_EvalObj(ea->interp, ea->body);
182 if (retval == JIM_RETURN)
183 retval = ea->interp->returnCode;
187 Jim_MakeErrorMessage(ea->interp);
188 LOG_USER(
"Error executing event %s on TPIU/SWO %s:\n%s",
191 Jim_GetString(Jim_GetResult(ea->interp),
NULL));
193 Jim_Eval(ea->interp,
"error \"\" \"\"");
223 LOG_ERROR(
"Failed to stop adapter's trace");
268 if (bytes_read == 0) {
270 }
else if (bytes_read == -1) {
271 LOG_ERROR(
"error during read: %s", strerror(errno));
290 LOG_ERROR(
"Failed to find connection to close!");
301 "----------------------------------------");
306 opt->
name, Jim_GetString(ea->body,
NULL));
329 { .name =
"-event", .value =
CFG_EVENT },
331 { .name =
"-dap", .value = -1 },
332 { .name =
"-ap-num", .value = -1 },
333 { .name =
"-baseaddr", .value = -1 },
334 { .name =
NULL, .value = -1 },
341 { .name =
NULL, .value = -1 },
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 },
361 Jim_SetResultFormatted(goi->
interp,
"Cannot configure TPIU/SWO; %s is enabled!", obj->
name);
366 while (goi->
argc > 0) {
367 Jim_SetEmptyResult(goi->
interp);
389 if (port_width < 1 || port_width > 32) {
390 Jim_SetResultString(goi->
interp,
"Invalid port width!", -1);
413 Jim_SetResultString(goi->
interp,
"protocol error", -1);
432 Jim_SetResultString(goi->
interp,
"formatter error", -1);
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);
494 Jim_WrongNumArgs(goi->
interp, goi->
argc, goi->
argv,
"-event ?event-name? ?EVENT-BODY?");
498 if (goi->
argc != 1) {
499 Jim_WrongNumArgs(goi->
interp, goi->
argc, goi->
argv,
"-event ?event-name?");
524 ea = calloc(1,
sizeof(*ea));
538 Jim_IncrRefCount(ea->
body);
564 "missing: -option ...");
590 .
name =
"tpiu_swo_trace",
591 .new_connection_during_keep_alive_handler =
NULL,
595 .keep_client_alive_handler =
NULL,
607 Jim_WrongNumArgs(
interp, 1, argv,
"Too many parameters");
621 LOG_ERROR(
"Invalid access port 0x%" PRIx64
". Only AP#0 allowed with hla transport", obj->
spot.
ap_num);
626 LOG_ERROR(
"Trace clock-in frequency not set");
632 LOG_DEBUG(
"SWO pin frequency not set, will be autodetected by the adapter");
640 LOG_ERROR(
MSG "Current target is not a Cortex-M nor a HLA");
653 LOG_INFO(
MSG "Target %s is on AP#0x%" PRIx64
". Revised command is "
654 "\'tpiu create %s -dap %s -ap-num 0x%" PRIx64
"\'",
699 LOG_ERROR(
"Cannot read TPIU register SSPSR");
708 uint16_t prescaler = 1;
737 LOG_ERROR(
"Failed to start adapter's trace");
747 LOG_ERROR(
"Adapter does not support auto-detection of SWO pin frequency nor a default value");
754 LOG_INFO(
"SWO pin data rate adjusted by adapter to %d Hz", swo_pin_freq);
768 LOG_INFO(
"SWO pin data rate adjusted to %d Hz", swo_pin_freq);
816 LOG_ERROR(
"Failed to stop adapter's trace");
829 Jim_WrongNumArgs(interp, 1, argv,
"Too many parameters");
848 LOG_ERROR(
"Failed to stop adapter's trace");
869 .help =
"configure a new TPIU/SWO for use",
870 .usage =
"[attribute value ...]",
876 .help =
"returns the specified TPIU/SWO attribute",
877 .usage =
"attribute",
882 .handler = handle_arm_tpiu_swo_event_list,
883 .help =
"displays a table of events defined for this TPIU/SWO",
891 .help =
"Enables the TPIU/SWO output",
898 .help =
"Disables the TPIU/SWO output",
915 Jim_SetResultFormatted(
interp,
"cannot create TPIU object because a command with name '%s' already exists",
925 .help =
"tpiu/swo instance command group",
945 Jim_WrongNumArgs(
interp, 1,
argv,
"name ?option option ...?");
961 obj->
name = strdup(Jim_GetString(n,
NULL));
975 Jim_SetResultString(goi.
interp,
"-dap and -ap-num required when creating TPIU", -1);
997 Jim_WrongNumArgs(interp, 1, argv,
"Too many parameters");
1000 Jim_SetResult(interp, Jim_NewListObj(interp,
NULL, 0));
1002 Jim_ListAppendElement(interp, Jim_GetResult(interp),
1003 Jim_NewStringObj(interp, obj->
name, -1));
1012 int retval = JIM_OK;
1015 Jim_WrongNumArgs(interp, 1, argv,
"Too many parameters");
1039 LOG_ERROR(
MSG "Current target is not a Cortex-M nor a HLA");
1050 uint64_t ap_num = pc->
ap_num;
1051 bool set_recheck_ap_cur_target =
false;
1062 LOG_INFO(
MSG "Target %s uses AP autodetection. Adding TPIU on AP 0; can be revised later",
1065 set_recheck_ap_cur_target =
true;
1068 LOG_INFO(
MSG "Running: \'tpiu create %s.tpiu -dap %s -ap-num 0x%" PRIx64
"\'",
1077 if (set_recheck_ap_cur_target)
1081 unsigned int cmd_idx = 0;
1085 if (!strcmp(
CMD_ARGV[cmd_idx],
"disable")) {
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")) {
1103 }
else if (strcmp(
CMD_ARGV[cmd_idx],
"external"))
1108 if (!strcmp(
CMD_ARGV[cmd_idx],
"sync")) {
1115 if (strcmp(
CMD_ARGV[cmd_idx],
"manchester") && strcmp(
CMD_ARGV[cmd_idx],
"uart"))
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 :
"",
1139 formatter ?
" -formatter " :
"", formatter ? formatter :
"",
1140 port_width ?
" -port-width " :
"", port_width ? port_width :
"");
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 :
"",
1147 formatter ?
" -formatter " :
"", formatter ? formatter :
"",
1148 port_width ?
" -port-width " :
"", port_width ? port_width :
"");
1163 .handler = handle_tpiu_deprecated_config_command,
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>]))",
1179 .help =
"tpiu command group",
1190 .usage =
"name [-dap dap] [-ap-num num] [-baseaddr baseaddr]",
1191 .help =
"Creates a new TPIU or SWO object",
1198 .help =
"Lists all registered TPIU and SWO objects by name",
1205 .help =
"Initialize TPIU and SWO",
1215 .help =
"tpiu command group",
1221 .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[]
static void arm_tpiu_swo_handle_event(struct arm_tpiu_swo_object *obj, enum arm_tpiu_swo_event event)
#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_service_input(struct connection *connection)
static int jim_arm_tpiu_swo_names(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
#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
static int jim_arm_tpiu_swo_enable(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
#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 jim_arm_tpiu_swo_init(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
static int jim_arm_tpiu_swo_disable(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
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)
list_add - add a new entry
#define list_first_entry(ptr, type, member)
list_first_entry - get the first element from a list
static void list_add_tail(struct list_head *new, struct list_head *head)
list_add_tail - add a new entry
static int list_empty(const struct list_head *head)
list_empty - tests whether a list is empty
#define list_for_each_entry(pos, head, member)
list_for_each_entry - iterate over list of given type
static void list_del(struct list_head *entry)
list_del - deletes entry from list.
#define list_for_each_entry_safe(pos, n, head, member)
list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
static void INIT_LIST_HEAD(struct list_head *list)
INIT_LIST_HEAD - Initialize a list_head structure.
#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
const char * name
Name of this type of target.
struct target_type * type
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)
int target_call_trace_callbacks(struct target *target, size_t len, uint8_t *data)
@ TARGET_TIMER_TYPE_PERIODIC
@ TARGET_EVENT_TRACE_CONFIG
static const char * target_name(struct target *target)
Returns the instance-specific name of the specified target.
static bool target_was_examined(struct target *target)