1 /* SPDX-License-Identifier: GPL-2.0 */
3 * Thunderbolt tracing support
5 * Copyright (C) 2024, Intel Corporation
6 * Author: Mika Westerberg <mika.westerberg@linux.intel.com>
7 * Gil Fine <gil.fine@intel.com>
11 #define TRACE_SYSTEM thunderbolt
13 #if !defined(TB_TRACE_H_) || defined(TRACE_HEADER_MULTI_READ)
16 #include <linux/trace_seq.h>
17 #include <linux/tracepoint.h>
21 #define tb_cfg_type_name(type) { type, #type }
22 #define show_type_name(val) \
23 __print_symbolic(val, \
24 tb_cfg_type_name(TB_CFG_PKG_READ), \
25 tb_cfg_type_name(TB_CFG_PKG_WRITE), \
26 tb_cfg_type_name(TB_CFG_PKG_ERROR), \
27 tb_cfg_type_name(TB_CFG_PKG_NOTIFY_ACK), \
28 tb_cfg_type_name(TB_CFG_PKG_EVENT), \
29 tb_cfg_type_name(TB_CFG_PKG_XDOMAIN_REQ), \
30 tb_cfg_type_name(TB_CFG_PKG_XDOMAIN_RESP), \
31 tb_cfg_type_name(TB_CFG_PKG_OVERRIDE), \
32 tb_cfg_type_name(TB_CFG_PKG_RESET), \
33 tb_cfg_type_name(TB_CFG_PKG_ICM_EVENT), \
34 tb_cfg_type_name(TB_CFG_PKG_ICM_CMD), \
35 tb_cfg_type_name(TB_CFG_PKG_ICM_RESP))
37 #ifndef TB_TRACE_HELPERS
38 #define TB_TRACE_HELPERS
39 static inline const char *show_data_read_write(struct trace_seq
*p
,
42 const struct cfg_read_pkg
*msg
= (const struct cfg_read_pkg
*)data
;
43 const char *ret
= trace_seq_buffer_ptr(p
);
45 trace_seq_printf(p
, "offset=%#x, len=%u, port=%d, config=%#x, seq=%d, ",
46 msg
->addr
.offset
, msg
->addr
.length
, msg
->addr
.port
,
47 msg
->addr
.space
, msg
->addr
.seq
);
52 static inline const char *show_data_error(struct trace_seq
*p
, const u32
*data
)
54 const struct cfg_error_pkg
*msg
= (const struct cfg_error_pkg
*)data
;
55 const char *ret
= trace_seq_buffer_ptr(p
);
57 trace_seq_printf(p
, "error=%#x, port=%d, plug=%#x, ", msg
->error
,
63 static inline const char *show_data_event(struct trace_seq
*p
, const u32
*data
)
65 const struct cfg_event_pkg
*msg
= (const struct cfg_event_pkg
*)data
;
66 const char *ret
= trace_seq_buffer_ptr(p
);
68 trace_seq_printf(p
, "port=%d, unplug=%#x, ", msg
->port
, msg
->unplug
);
73 static inline const char *show_route(struct trace_seq
*p
, const u32
*data
)
75 const struct tb_cfg_header
*header
= (const struct tb_cfg_header
*)data
;
76 const char *ret
= trace_seq_buffer_ptr(p
);
78 trace_seq_printf(p
, "route=%llx, ", tb_cfg_get_route(header
));
83 static inline const char *show_data(struct trace_seq
*p
, u8 type
,
84 const u32
*data
, u32 length
)
86 const char *ret
= trace_seq_buffer_ptr(p
);
87 const char *prefix
= "";
92 case TB_CFG_PKG_WRITE
:
94 show_data_read_write(p
, data
);
97 case TB_CFG_PKG_ERROR
:
99 show_data_error(p
, data
);
102 case TB_CFG_PKG_EVENT
:
104 show_data_event(p
, data
);
107 case TB_CFG_PKG_ICM_EVENT
:
108 case TB_CFG_PKG_ICM_CMD
:
109 case TB_CFG_PKG_ICM_RESP
:
110 /* ICM messages always target the host router */
111 trace_seq_puts(p
, "route=0, ");
119 trace_seq_printf(p
, "data=[");
120 for (i
= 0; i
< length
; i
++) {
121 trace_seq_printf(p
, "%s0x%08x", prefix
, data
[i
]);
124 trace_seq_printf(p
, "]");
125 trace_seq_putc(p
, 0);
131 DECLARE_EVENT_CLASS(tb_raw
,
132 TP_PROTO(int index
, u8 type
, const void *data
, size_t size
),
133 TP_ARGS(index
, type
, data
, size
),
137 __field(size_t, size
)
138 __dynamic_array(u32
, data
, size
/ 4)
141 __entry
->index
= index
;
142 __entry
->type
= type
;
143 __entry
->size
= size
/ 4;
144 memcpy(__get_dynamic_array(data
), data
, size
);
146 TP_printk("type=%s, size=%zd, domain=%d, %s",
147 show_type_name(__entry
->type
), __entry
->size
, __entry
->index
,
148 show_data(p
, __entry
->type
, __get_dynamic_array(data
),
153 DEFINE_EVENT(tb_raw
, tb_tx
,
154 TP_PROTO(int index
, u8 type
, const void *data
, size_t size
),
155 TP_ARGS(index
, type
, data
, size
)
158 DEFINE_EVENT(tb_raw
, tb_event
,
159 TP_PROTO(int index
, u8 type
, const void *data
, size_t size
),
160 TP_ARGS(index
, type
, data
, size
)
164 TP_PROTO(int index
, u8 type
, const void *data
, size_t size
, bool dropped
),
165 TP_ARGS(index
, type
, data
, size
, dropped
),
169 __field(size_t, size
)
170 __dynamic_array(u32
, data
, size
/ 4)
171 __field(bool, dropped
)
174 __entry
->index
= index
;
175 __entry
->type
= type
;
176 __entry
->size
= size
/ 4;
177 memcpy(__get_dynamic_array(data
), data
, size
);
178 __entry
->dropped
= dropped
;
180 TP_printk("type=%s, dropped=%u, size=%zd, domain=%d, %s",
181 show_type_name(__entry
->type
), __entry
->dropped
,
182 __entry
->size
, __entry
->index
,
183 show_data(p
, __entry
->type
, __get_dynamic_array(data
),
188 #endif /* TB_TRACE_H_ */
190 #undef TRACE_INCLUDE_PATH
191 #define TRACE_INCLUDE_PATH .
193 #undef TRACE_INCLUDE_FILE
194 #define TRACE_INCLUDE_FILE trace
196 /* This part must be outside protection */
197 #include <trace/define_trace.h>