1 /* SPDX-License-Identifier: BSD-3-Clause
2 *
3 * Copyright(c) 2016 Intel Corporation. All rights reserved.
4 *
5 * Author: Liam Girdwood <liam.r.girdwood@linux.intel.com>
6 * Keyon Jie <yang.jie@linux.intel.com>
7 * Artur Kloniecki <arturx.kloniecki@linux.intel.com>
8 * Karol Trzcinski <karolx.trzcinski@linux.intel.com>
9 */
10
11 #ifndef __SOF_TRACE_TRACE_H__
12 #define __SOF_TRACE_TRACE_H__
13
14 #ifndef RELATIVE_FILE
15 #error "This file requires RELATIVE_FILE to be defined. " \
16 "Add it to CMake's target with sof_append_relative_path_definitions."
17 #endif
18
19 #if !CONFIG_LIBRARY
20 #include <platform/trace/trace.h>
21 #endif
22 #include <sof/common.h>
23 #include <rtos/sof.h>
24 #include <sof/trace/preproc.h>
25
26 #include <stdbool.h>
27 #include <stdint.h>
28 #include <string.h>
29 #if CONFIG_LIBRARY
30 #include <stdio.h>
31 #endif
32
33 #ifdef __ZEPHYR__
34 #include <zephyr/kernel.h>
35 #include <zephyr/logging/log.h>
36 #endif
37
38 struct sof;
39 struct trace;
40 struct tr_ctx;
41
42 /* bootloader trace values */
43 #define TRACE_BOOT_LDR_ENTRY 0x100
44 #define TRACE_BOOT_LDR_HPSRAM 0x110
45 #define TRACE_BOOT_LDR_MANIFEST 0x120
46 #define TRACE_BOOT_LDR_LPSRAM 0x130
47 #define TRACE_BOOT_LDR_L1DRAM 0x140
48 #define TRACE_BOOT_LDR_JUMP 0x150
49
50 #define TRACE_BOOT_LDR_PARSE_MODULE 0x210
51 #define TRACE_BOOT_LDR_PARSE_SEGMENT 0x220
52
53 /* general trace init codes - only used at boot
54 * when main trace is not available
55 */
56 #define TRACE_BOOT_START 0x1000
57 #define TRACE_BOOT_ARCH 0x2000
58 #define TRACE_BOOT_SYS 0x3000
59 #define TRACE_BOOT_PLATFORM 0x4000
60
61 /* system specific codes */
62 #define TRACE_BOOT_SYS_HEAP (TRACE_BOOT_SYS + 0x100)
63 #define TRACE_BOOT_SYS_TRACES (TRACE_BOOT_SYS + 0x200)
64 #define TRACE_BOOT_SYS_NOTIFIER (TRACE_BOOT_SYS + 0x300)
65 #define TRACE_BOOT_SYS_POWER (TRACE_BOOT_SYS + 0x400)
66
67 /* platform/device specific codes */
68 #define TRACE_BOOT_PLATFORM_ENTRY (TRACE_BOOT_PLATFORM + 0x100)
69 #define TRACE_BOOT_PLATFORM_IRQ (TRACE_BOOT_PLATFORM + 0x110)
70 #define TRACE_BOOT_PLATFORM_MBOX (TRACE_BOOT_PLATFORM + 0x120)
71 #define TRACE_BOOT_PLATFORM_SHIM (TRACE_BOOT_PLATFORM + 0x130)
72 #define TRACE_BOOT_PLATFORM_PMC (TRACE_BOOT_PLATFORM + 0x140)
73 #define TRACE_BOOT_PLATFORM_TIMER (TRACE_BOOT_PLATFORM + 0x150)
74 #define TRACE_BOOT_PLATFORM_CLOCK (TRACE_BOOT_PLATFORM + 0x160)
75 #define TRACE_BOOT_PLATFORM_SCHED (TRACE_BOOT_PLATFORM + 0x170)
76 #define TRACE_BOOT_PLATFORM_AGENT (TRACE_BOOT_PLATFORM + 0x180)
77 #define TRACE_BOOT_PLATFORM_CPU_FREQ (TRACE_BOOT_PLATFORM + 0x190)
78 #define TRACE_BOOT_PLATFORM_SSP_FREQ (TRACE_BOOT_PLATFORM + 0x1A0)
79 #define TRACE_BOOT_PLATFORM_DMA (TRACE_BOOT_PLATFORM + 0x1B0)
80 #define TRACE_BOOT_PLATFORM_IPC (TRACE_BOOT_PLATFORM + 0x1C0)
81 #define TRACE_BOOT_PLATFORM_IDC (TRACE_BOOT_PLATFORM + 0x1D0)
82 #define TRACE_BOOT_PLATFORM_DAI (TRACE_BOOT_PLATFORM + 0x1E0)
83 #define TRACE_BOOT_PLATFORM_SSP (TRACE_BOOT_PLATFORM + 0x1F0)
84 #define TRACE_BOOT_PLATFORM_SPI (TRACE_BOOT_PLATFORM + 0x200)
85 #define TRACE_BOOT_PLATFORM_DMA_TRACE (TRACE_BOOT_PLATFORM + 0x210)
86
87 #define _TRACE_EVENT_MAX_ARGUMENT_COUNT 4
88
trace_get(void)89 static inline struct trace *trace_get(void)
90 {
91 return sof_get()->trace;
92 }
93
94 /* Silences compiler warnings about unused variables */
95 #define trace_unused(class, ctx, id_1, id_2, format, ...) \
96 UNUSED(ctx, id_1, id_2, ##__VA_ARGS__)
97
98 struct trace_filter {
99 uint32_t uuid_id; /**< type id, or 0 when not important */
100 int32_t comp_id; /**< component id or -1 when not important */
101 int32_t pipe_id; /**< pipeline id or -1 when not important */
102 int32_t log_level; /**< new log level value */
103 };
104
105 /** The start of this linker output MUST match the 'ldc_entry_header'
106 * struct defined in the logger program running in user space.
107 */
108 #define _DECLARE_LOG_ENTRY(lvl, format, comp_class, n_params) \
109 __section(".static_log." #lvl) \
110 static const struct { \
111 uint32_t level; \
112 uint32_t component_class; \
113 uint32_t params_num; \
114 uint32_t line_idx; \
115 uint32_t file_name_len; \
116 uint32_t text_len; \
117 const char file_name[sizeof(RELATIVE_FILE)]; \
118 const char text[sizeof(format)]; \
119 } log_entry = { \
120 lvl, \
121 comp_class, \
122 n_params, \
123 __LINE__, \
124 sizeof(RELATIVE_FILE), \
125 sizeof(format), \
126 RELATIVE_FILE, \
127 format \
128 }
129
130 #if CONFIG_TRACE
131
132 #include <stdarg.h>
133 #include <user/trace.h> /* LOG_LEVEL_... */
134
135 /*
136 * trace_event macro definition
137 *
138 * trace_event() macro is used for logging events that occur at runtime.
139 * It comes in 2 main flavours, atomic and non-atomic. Depending of definitions
140 * above, it might also propagate log messages to mbox if desired.
141 *
142 * First argument is always class of event being logged, as defined in
143 * user/trace.h - TRACE_CLASS_* (deprecated - do not use).
144 * Second argument is string literal in printf format, followed by up to 4
145 * parameters (uint32_t), that are used to expand into string fromat when
146 * parsing log data.
147 *
148 * All compile-time accessible data (verbosity, class, source file name, line
149 * index and string literal) are linked into .static_log_entries section
150 * of binary and then extracted by smex, so they do not contribute to loadable
151 * image size. This way more elaborate log messages are possible and encouraged,
152 * for better debugging experience, without worrying about runtime performance.
153 */
154
155 /* Map the different trace_xxxx_with_ids(... ) levels to the
156 * _trace_event_with_ids(level_xxxx, ...) macro shared across log
157 * levels.
158 */
159 #define trace_event_with_ids(class, ctx, id_1, id_2, format, ...) \
160 _trace_event_with_ids(LOG_LEVEL_INFO, class, ctx, id_1, id_2, \
161 format, ##__VA_ARGS__)
162
163 #define trace_event_atomic_with_ids(class, ctx, id_1, id_2, format, ...) \
164 _trace_event_atomic_with_ids(LOG_LEVEL_INFO, class, ctx, id_1, id_2, \
165 format, ##__VA_ARGS__)
166
167 #define trace_warn_with_ids(class, ctx, id_1, id_2, format, ...) \
168 _trace_event_with_ids(LOG_LEVEL_WARNING, class, ctx, id_1, id_2, \
169 format, ##__VA_ARGS__)
170
171 #define trace_warn_atomic_with_ids(class, ctx, id_1, id_2, format, ...) \
172 _trace_event_atomic_with_ids(LOG_LEVEL_WARNING, class, \
173 ctx, id_1, id_2, \
174 format, ##__VA_ARGS__)
175
176 void trace_flush_dma_to_mbox(void);
177 void trace_on(void);
178 void trace_off(void);
179 void trace_init(struct sof *sof);
180
181 /* All tracing macros in this file end up calling these functions in the end. */
182 typedef void (*log_func_t)(bool send_atomic, const void *log_entry, const struct tr_ctx *ctx,
183 uint32_t lvl, uint32_t id_1, uint32_t id_2, int arg_count, va_list args);
184
185 void trace_log_filtered(bool send_atomic, const void *log_entry, const struct tr_ctx *ctx,
186 uint32_t lvl, uint32_t id_1, uint32_t id_2, int arg_count, va_list args);
187 void trace_log_unfiltered(bool send_atomic, const void *log_entry, const struct tr_ctx *ctx,
188 uint32_t lvl, uint32_t id_1, uint32_t id_2, int arg_count, va_list args);
189 struct sof_ipc_trace_filter_elem *trace_filter_fill(struct sof_ipc_trace_filter_elem *elem,
190 struct sof_ipc_trace_filter_elem *end,
191 struct trace_filter *filter);
192 int trace_filter_update(const struct trace_filter *elem);
193
194 #define _trace_event_with_ids(lvl, class, ctx, id_1, id_2, format, ...) \
195 _log_message(trace_log_filtered, false, lvl, class, ctx, id_1, id_2, format, ##__VA_ARGS__)
196
197 #define _trace_event_atomic_with_ids(lvl, class, ctx, id_1, id_2, format, ...) \
198 _log_message(trace_log_filtered, true, lvl, class, ctx, id_1, id_2, format, ##__VA_ARGS__)
199
200 /**
201 * Appends one SOF dictionary entry and log statement to the ring buffer
202 * implementing the 'etrace' in shared memory.
203 *
204 * @param atomic_context Take the trace->lock if false.
205 * @param log_entry_pointer dictionary index produced by the
206 * _DECLARE_LOG_ENTRY macro.
207 * @param n_args number of va_args
208 */
209 void mtrace_dict_entry(bool atomic_context, uint32_t log_entry_pointer, int n_args, ...);
210
211 /** Posts a fully prepared log header + log entry */
212 void mtrace_event(const char *complete_packet, uint32_t length);
213
214 #ifdef CONFIG_TRACEM /* Send everything to shared memory too */
215 # ifdef __ZEPHYR__
216 /* We don't use Zephyr's dictionary yet so there's not enough space for
217 * DEBUG messages
218 */
219 # define MTRACE_DUPLICATION_LEVEL LOG_LEVEL_INFO
220 # else
221 # define MTRACE_DUPLICATION_LEVEL LOG_LEVEL_DEBUG
222 # endif
223 #else /* copy only ERRORS */
224 # define MTRACE_DUPLICATION_LEVEL LOG_LEVEL_ERROR
225 #endif /* CONFIG_TRACEM */
226
227 /* This function is _not_ passed the format string to save space */
228 void _log_sofdict(log_func_t sofdict_logf, bool atomic, const void *log_entry,
229 const struct tr_ctx *ctx, const uint32_t lvl,
230 uint32_t id_1, uint32_t id_2, int arg_count, ...);
231
232 /* _log_message() */
233
234 #ifdef CONFIG_LIBRARY
235
236 extern int test_bench_trace;
237 char *get_trace_class(uint32_t trace_class);
238 #define _log_message(ignored_log_func, atomic, level, comp_class, ctx, id_1, id_2, format, ...) \
239 do { \
240 (void)ctx; \
241 (void)id_1; \
242 (void)id_2; \
243 if (test_bench_trace) { \
244 char *msg = "(%s:%d) " format; \
245 fprintf(stderr, msg, strrchr(__FILE__, '/') + 1,\
246 __LINE__, ##__VA_ARGS__); \
247 fprintf(stderr, "\n"); \
248 } \
249 } while (0)
250
251 #define trace_point(x) do {} while (0)
252
253 #else /* CONFIG_LIBRARY */
254
255 #define trace_point(x) platform_trace_point(x)
256
257 #define BASE_LOG_ASSERT_FAIL_MSG \
258 unsupported_amount_of_params_in_trace_event\
259 _thrown_from_macro_BASE_LOG_in_trace_h
260
261 #define CT_ASSERT(COND, MESSAGE) \
262 ((void)sizeof(char[1 - 2 * !(COND)]))
263
264 #define trace_check_size_uint32(a) \
265 CT_ASSERT(sizeof(a) <= sizeof(uint32_t), "error: trace argument is bigger than a uint32_t");
266
267 #define STATIC_ASSERT_ARG_SIZE(...) \
268 META_MAP(1, trace_check_size_uint32, __VA_ARGS__)
269
270 /** _log_message is where the memory-saving dictionary magic described
271 * above happens: the "format" string argument is moved to a special
272 * linker section and replaced by a &log_entry pointer to it. This must
273 * be a macro for the source location to be meaningful.
274 */
275 #define _log_message(log_func, atomic, lvl, comp_class, ctx, id_1, id_2, format, ...) \
276 do { \
277 _DECLARE_LOG_ENTRY(lvl, format, comp_class, \
278 META_COUNT_VARAGS_BEFORE_COMPILE(__VA_ARGS__)); \
279 STATIC_ASSERT_ARG_SIZE(__VA_ARGS__); \
280 STATIC_ASSERT(_TRACE_EVENT_MAX_ARGUMENT_COUNT >= \
281 META_COUNT_VARAGS_BEFORE_COMPILE(__VA_ARGS__), \
282 BASE_LOG_ASSERT_FAIL_MSG \
283 ); \
284 _log_sofdict(log_func, atomic, &log_entry, ctx, lvl, id_1, id_2, \
285 META_COUNT_VARAGS_BEFORE_COMPILE(__VA_ARGS__), ##__VA_ARGS__); \
286 _log_nodict(atomic, META_COUNT_VARAGS_BEFORE_COMPILE(__VA_ARGS__), \
287 lvl, format, ##__VA_ARGS__); \
288 } while (0)
289
290 #ifdef __ZEPHYR__
291 /* Just like XTOS, only the most urgent messages go to limited
292 * shared memory.
293 */
294 #define _log_nodict(atomic, arg_count, lvl, format, ...) \
295 do { \
296 if ((lvl) <= MTRACE_DUPLICATION_LEVEL) \
297 printk("%llu " format "\n", k_cycle_get_64(), \
298 ##__VA_ARGS__); \
299 } while (0)
300 #else
301 #define _log_nodict(atomic, n_args, lvl, format, ...)
302 #endif
303
304 #endif /* CONFIG_LIBRARY */
305
306 #else /* CONFIG_TRACE */
307
308 #define trace_event_with_ids(class, ctx, id_1, id_2, format, ...) \
309 trace_unused(class, ctx, id_1, id_2, format, ##__VA_ARGS__)
310 #define trace_event_atomic_with_ids(class, ctx, id_1, id_2, format, ...) \
311 trace_unused(class, ctx, id_1, id_2, format, ##__VA_ARGS__)
312
313 #define trace_warn_with_ids(class, ctx, id_1, id_2, format, ...) \
314 trace_unused(class, ctx, id_1, id_2, format, ##__VA_ARGS__)
315 #define trace_warn_atomic_with_ids(class, ctx, id_1, id_2, format, ...) \
316 trace_unused(class, ctx, id_1, id_2, format, ##__VA_ARGS__)
317
318 #define trace_point(x) do {} while (0)
319
trace_flush_dma_to_mbox(void)320 static inline void trace_flush_dma_to_mbox(void) { }
trace_on(void)321 static inline void trace_on(void) { }
trace_off(void)322 static inline void trace_off(void) { }
trace_init(struct sof * sof)323 static inline void trace_init(struct sof *sof) { }
trace_filter_update(const struct trace_filter * filter)324 static inline int trace_filter_update(const struct trace_filter *filter)
325 { return 0; }
326
327 #endif /* CONFIG_TRACE */
328
329 #if CONFIG_TRACEV
330 /* Enable tr_dbg() statements by defining tracev_...() */
331 #define tracev_event_with_ids(class, ctx, id_1, id_2, format, ...) \
332 _trace_event_with_ids(LOG_LEVEL_VERBOSE, class, \
333 ctx, id_1, id_2, \
334 format, ##__VA_ARGS__)
335
336 #define tracev_event_atomic_with_ids(class, ctx, id_1, id_2, format, ...) \
337 _trace_event_atomic_with_ids(LOG_LEVEL_VERBOSE, class, \
338 ctx, id_1, id_2, \
339 format, ##__VA_ARGS__)
340
341 #else /* CONFIG_TRACEV */
342 #define tracev_event_with_ids(class, ctx, id_1, id_2, format, ...) \
343 trace_unused(class, ctx, id_1, id_2, format, ##__VA_ARGS__)
344 #define tracev_event_atomic_with_ids(class, ctx, id_1, id_2, format, ...) \
345 trace_unused(class, ctx, id_1, id_2, format, ##__VA_ARGS__)
346
347 #endif /* CONFIG_TRACEV */
348
349 /* The _error_ level has 2, 1 or 0 backends depending on Kconfig */
350 #if CONFIG_TRACEE
351 /* LOG_LEVEL_CRITICAL messages are duplicated to the mail box */
352 #define _trace_error_with_ids(class, ctx, id_1, id_2, format, ...) \
353 _log_message(trace_log_filtered, true, LOG_LEVEL_CRITICAL, class, ctx, id_1, \
354 id_2, format, ##__VA_ARGS__)
355 #define trace_error_with_ids(class, ctx, id_1, id_2, format, ...) \
356 _trace_error_with_ids(class, ctx, id_1, id_2, format, ##__VA_ARGS__)
357 #define trace_error_atomic_with_ids(...) trace_error_with_ids(__VA_ARGS__)
358
359 #elif CONFIG_TRACE
360 /* Goes to trace_log_filtered() too but with a downgraded, LOG_INFO level */
361 #define trace_error_with_ids(...) trace_event_with_ids(__VA_ARGS__)
362 #define trace_error_atomic_with_ids(...) \
363 trace_event_atomic_with_ids(__VA_ARGS__)
364
365 #else /* CONFIG_TRACEE, CONFIG_TRACE */
366 #define trace_error_with_ids(class, ctx, id_1, id_2, format, ...) \
367 trace_unused(class, ctx, id_1, id_2, format, ##__VA_ARGS__)
368 #define trace_error_atomic_with_ids(class, ctx, id_1, id_2, format, ...) \
369 trace_unused(class, ctx, id_1, id_2, format, ##__VA_ARGS__)
370
371 #endif /* CONFIG_TRACEE, CONFIG_TRACE */
372
373 /** Default value when there is no specific pipeline, dev, dai, etc. */
374 #define _TRACE_INV_ID -1
375
376 /** This has been replaced in commits 6ce635aa82 and earlier by the
377 * DECLARE_TR_CTX, tr_ctx and component UUID system below
378 */
379 #define _TRACE_INV_CLASS TRACE_CLASS_DEPRECATED
380
381 /**
382 * Trace context.
383 */
384 struct tr_ctx {
385 const struct sof_uuid_entry *uuid_p; /**< UUID pointer, use SOF_UUID() to init */
386 uint32_t level; /**< Default log level */
387 };
388
389 #if defined(UNIT_TEST)
390 #define TRACE_CONTEXT_SECTION
391 #else
392 #define TRACE_CONTEXT_SECTION __section(".trace_ctx")
393 #endif
394
395 /**
396 * Declares trace context.
397 * @param ctx_name (Symbol) name.
398 * @param uuid UUID pointer, use SOF_UUID() to inititalize.
399 * @param default_log_level Default log level.
400 */
401 #define DECLARE_TR_CTX(ctx_name, uuid, default_log_level) \
402 struct tr_ctx ctx_name TRACE_CONTEXT_SECTION = { \
403 .uuid_p = uuid, \
404 .level = default_log_level, \
405 }
406
407 /* tracing from device (component, pipeline, dai, ...) */
408
409 /** \brief Trace from a device on err level.
410 *
411 * @param get_ctx_m Macro that can retrieve trace context from dev
412 * @param get_id_m Macro that can retrieve device's id0 from the dev
413 * @param get_subid_m Macro that can retrieve device's id1 from the dev
414 * @param dev Device
415 * @param fmt Format followed by parameters
416 * @param ... Parameters
417 */
418 #define trace_dev_err(get_ctx_m, get_id_m, get_subid_m, dev, fmt, ...) \
419 trace_error_with_ids(_TRACE_INV_CLASS, get_ctx_m(dev), \
420 get_id_m(dev), get_subid_m(dev), \
421 fmt, ##__VA_ARGS__)
422
423 /** \brief Trace from a device on warning level. */
424 #define trace_dev_warn(get_ctx_m, get_id_m, get_subid_m, dev, fmt, ...) \
425 trace_warn_with_ids(_TRACE_INV_CLASS, get_ctx_m(dev), \
426 get_id_m(dev), get_subid_m(dev), \
427 fmt, ##__VA_ARGS__)
428
429 /** \brief Trace from a device on info level. */
430 #define trace_dev_info(get_ctx_m, get_id_m, get_subid_m, dev, fmt, ...) \
431 trace_event_with_ids(_TRACE_INV_CLASS, get_ctx_m(dev), \
432 get_id_m(dev), get_subid_m(dev), \
433 fmt, ##__VA_ARGS__)
434
435 /** \brief Trace from a device on dbg level. */
436 #define trace_dev_dbg(get_ctx_m, get_id_m, get_subid_m, dev, fmt, ...) \
437 tracev_event_with_ids(_TRACE_INV_CLASS, \
438 get_ctx_m(dev), get_id_m(dev), \
439 get_subid_m(dev), fmt, ##__VA_ARGS__)
440
441 /* tracing from infrastructure part */
442
443 #define tr_err_atomic(ctx, fmt, ...) \
444 trace_error_atomic_with_ids(_TRACE_INV_CLASS, ctx, \
445 _TRACE_INV_ID, _TRACE_INV_ID, \
446 fmt, ##__VA_ARGS__)
447
448 #define tr_warn_atomic(ctx, fmt, ...) \
449 trace_warn_atomic_with_ids(_TRACE_INV_CLASS, ctx, \
450 _TRACE_INV_ID, _TRACE_INV_ID, \
451 fmt, ##__VA_ARGS__)
452
453 #define tr_info_atomic(ctx, fmt, ...) \
454 trace_event_atomic_with_ids(_TRACE_INV_CLASS, ctx, \
455 _TRACE_INV_ID, _TRACE_INV_ID, \
456 fmt, ##__VA_ARGS__)
457
458 #define tr_dbg_atomic(ctx, fmt, ...) \
459 tracev_event_atomic_with_ids(_TRACE_INV_CLASS, ctx, \
460 _TRACE_INV_ID, _TRACE_INV_ID, \
461 fmt, ##__VA_ARGS__)
462
463 #if defined(__ZEPHYR__) && defined(CONFIG_ZEPHYR_LOG)
464
465 #define tr_err(ctx, fmt, ...) LOG_ERR(fmt, ##__VA_ARGS__)
466
467 #define tr_warn(ctx, fmt, ...) LOG_WRN(fmt, ##__VA_ARGS__)
468
469 #define tr_info(ctx, fmt, ...) LOG_INF(fmt, ##__VA_ARGS__)
470
471 #define tr_dbg(ctx, fmt, ...) LOG_DBG(fmt, ##__VA_ARGS__)
472
473 #else
474
475 /* Only define these two macros for XTOS to avoid the collision with
476 * zephyr/include/zephyr/logging/log.h
477 */
478 #ifndef __ZEPHYR__
479 #define LOG_MODULE_REGISTER(ctx, level)
480 #define LOG_MODULE_DECLARE(ctx, level)
481 #endif
482
483 #define tr_err(ctx, fmt, ...) \
484 trace_error_with_ids(_TRACE_INV_CLASS, ctx, \
485 _TRACE_INV_ID, _TRACE_INV_ID, fmt, ##__VA_ARGS__)
486
487 #define tr_warn(ctx, fmt, ...) \
488 trace_warn_with_ids(_TRACE_INV_CLASS, ctx, \
489 _TRACE_INV_ID, _TRACE_INV_ID, fmt, ##__VA_ARGS__)
490
491 #define tr_info(ctx, fmt, ...) \
492 trace_event_with_ids(_TRACE_INV_CLASS, ctx, \
493 _TRACE_INV_ID, _TRACE_INV_ID, fmt, ##__VA_ARGS__)
494
495 /* tracev_ output depends on CONFIG_TRACEV=y */
496 #define tr_dbg(ctx, fmt, ...) \
497 tracev_event_with_ids(_TRACE_INV_CLASS, ctx, \
498 _TRACE_INV_ID, _TRACE_INV_ID, fmt, ##__VA_ARGS__)
499
500 #endif
501
502 #if CONFIG_TRACE
503
504 /** Direct, low-level access to mbox / shared memory logging when DMA
505 * tracing is either not initialized yet or disabled or found broken for
506 * any reason.
507 * To keep it simpler than and with minimal dependencies on
508 * the huge number of lines above, this does not check arguments at compile
509 * time.
510 * There is neither log level filtering, throttling or any other
511 * advanced feature.
512 */
513 #define mtrace_printf(log_level, format_str, ...) \
514 do { \
515 STATIC_ASSERT(META_COUNT_VARAGS_BEFORE_COMPILE(__VA_ARGS__) \
516 <= _TRACE_EVENT_MAX_ARGUMENT_COUNT, \
517 too_many_mtrace_printf_arguments); \
518 _DECLARE_LOG_ENTRY(log_level, format_str, _TRACE_INV_CLASS, \
519 META_COUNT_VARAGS_BEFORE_COMPILE(__VA_ARGS__)); \
520 mtrace_dict_entry(true, (uint32_t)&log_entry, \
521 META_COUNT_VARAGS_BEFORE_COMPILE(__VA_ARGS__), \
522 ##__VA_ARGS__); \
523 } while (0)
524
525
526 #else
527
mtrace_printf(int log_level,const char * format_str,...)528 static inline void mtrace_printf(int log_level, const char *format_str, ...)
529 {
530 };
531
532 #endif /* CONFIG_TRACE */
533
534 #endif /* __SOF_TRACE_TRACE_H__ */
535