/* SPDX-License-Identifier: GPL-2.0 */ /* * Thunderbolt tracing support * * Copyright (C) 2024, Intel Corporation * Author: Mika Westerberg * Gil Fine */ #undef TRACE_SYSTEM #define TRACE_SYSTEM thunderbolt #if !defined(TB_TRACE_H_) || defined(TRACE_HEADER_MULTI_READ) #define TB_TRACE_H_ #include #include #include "tb_msgs.h" #define tb_cfg_type_name(type) { type, #type } #define show_type_name(val) \ __print_symbolic(val, \ tb_cfg_type_name(TB_CFG_PKG_READ), \ tb_cfg_type_name(TB_CFG_PKG_WRITE), \ tb_cfg_type_name(TB_CFG_PKG_ERROR), \ tb_cfg_type_name(TB_CFG_PKG_NOTIFY_ACK), \ tb_cfg_type_name(TB_CFG_PKG_EVENT), \ tb_cfg_type_name(TB_CFG_PKG_XDOMAIN_REQ), \ tb_cfg_type_name(TB_CFG_PKG_XDOMAIN_RESP), \ tb_cfg_type_name(TB_CFG_PKG_OVERRIDE), \ tb_cfg_type_name(TB_CFG_PKG_RESET), \ tb_cfg_type_name(TB_CFG_PKG_ICM_EVENT), \ tb_cfg_type_name(TB_CFG_PKG_ICM_CMD), \ tb_cfg_type_name(TB_CFG_PKG_ICM_RESP)) #ifndef TB_TRACE_HELPERS #define TB_TRACE_HELPERS static inline const char *show_data_read_write(struct trace_seq *p, const u32 *data) { const struct cfg_read_pkg *msg = (const struct cfg_read_pkg *)data; const char *ret = trace_seq_buffer_ptr(p); trace_seq_printf(p, "offset=%#x, len=%u, port=%d, config=%#x, seq=%d, ", msg->addr.offset, msg->addr.length, msg->addr.port, msg->addr.space, msg->addr.seq); return ret; } static inline const char *show_data_error(struct trace_seq *p, const u32 *data) { const struct cfg_error_pkg *msg = (const struct cfg_error_pkg *)data; const char *ret = trace_seq_buffer_ptr(p); trace_seq_printf(p, "error=%#x, port=%d, plug=%#x, ", msg->error, msg->port, msg->pg); return ret; } static inline const char *show_data_event(struct trace_seq *p, const u32 *data) { const struct cfg_event_pkg *msg = (const struct cfg_event_pkg *)data; const char *ret = trace_seq_buffer_ptr(p); trace_seq_printf(p, "port=%d, unplug=%#x, ", msg->port, msg->unplug); return ret; } static inline const char *show_route(struct trace_seq *p, const u32 *data) { const struct tb_cfg_header *header = (const struct tb_cfg_header *)data; const char *ret = trace_seq_buffer_ptr(p); trace_seq_printf(p, "route=%llx, ", tb_cfg_get_route(header)); return ret; } static inline const char *show_data(struct trace_seq *p, u8 type, const u32 *data, u32 length) { const char *ret = trace_seq_buffer_ptr(p); const char *prefix = ""; int i; show_route(p, data); switch (type) { case TB_CFG_PKG_READ: case TB_CFG_PKG_WRITE: show_data_read_write(p, data); break; case TB_CFG_PKG_ERROR: show_data_error(p, data); break; case TB_CFG_PKG_EVENT: show_data_event(p, data); break; default: break; } trace_seq_printf(p, "data=["); for (i = 0; i < length; i++) { trace_seq_printf(p, "%s0x%08x", prefix, data[i]); prefix = ", "; } trace_seq_printf(p, "]"); trace_seq_putc(p, 0); return ret; } #endif DECLARE_EVENT_CLASS(tb_raw, TP_PROTO(int index, u8 type, const void *data, size_t size), TP_ARGS(index, type, data, size), TP_STRUCT__entry( __field(int, index) __field(u8, type) __field(size_t, size) __dynamic_array(u32, data, size / 4) ), TP_fast_assign( __entry->index = index; __entry->type = type; __entry->size = size / 4; memcpy(__get_dynamic_array(data), data, size); ), TP_printk("type=%s, size=%zd, domain=%d, %s", show_type_name(__entry->type), __entry->size, __entry->index, show_data(p, __entry->type, __get_dynamic_array(data), __entry->size) ) ); DEFINE_EVENT(tb_raw, tb_tx, TP_PROTO(int index, u8 type, const void *data, size_t size), TP_ARGS(index, type, data, size) ); DEFINE_EVENT(tb_raw, tb_event, TP_PROTO(int index, u8 type, const void *data, size_t size), TP_ARGS(index, type, data, size) ); TRACE_EVENT(tb_rx, TP_PROTO(int index, u8 type, const void *data, size_t size, bool dropped), TP_ARGS(index, type, data, size, dropped), TP_STRUCT__entry( __field(int, index) __field(u8, type) __field(size_t, size) __dynamic_array(u32, data, size / 4) __field(bool, dropped) ), TP_fast_assign( __entry->index = index; __entry->type = type; __entry->size = size / 4; memcpy(__get_dynamic_array(data), data, size); __entry->dropped = dropped; ), TP_printk("type=%s, dropped=%u, size=%zd, domain=%d, %s", show_type_name(__entry->type), __entry->dropped, __entry->size, __entry->index, show_data(p, __entry->type, __get_dynamic_array(data), __entry->size) ) ); #endif /* TB_TRACE_H_ */ #undef TRACE_INCLUDE_PATH #define TRACE_INCLUDE_PATH . #undef TRACE_INCLUDE_FILE #define TRACE_INCLUDE_FILE trace /* This part must be outside protection */ #include