trace.c: add mtrace_printf() low-level shortcut

Direct access to mbox shared memory logging when DMA tracing is
either not initialized yet or disabled or found broken for any
reason.

Signed-off-by: Marc Herbert <marc.herbert@intel.com>
This commit is contained in:
Marc Herbert 2021-05-27 02:23:34 +00:00 committed by Liam Girdwood
parent 532642bb32
commit 50eb5c9ca2
3 changed files with 58 additions and 4 deletions

View File

@ -413,4 +413,31 @@ struct tr_ctx {
_TRACE_INV_ID, _TRACE_INV_ID, \ _TRACE_INV_ID, _TRACE_INV_ID, \
fmt, ##__VA_ARGS__) fmt, ##__VA_ARGS__)
/** Direct, low-level access to mbox / shared memory logging when DMA
* tracing is either not initialized yet or disabled or found broken for
* any reason.
* To keep it simpler than and with minimal dependencies on
* the huge number of lines above, this does not check arguments at compile
* time.
* There is neither log level filtering, throttling or any other
* advanced feature.
*/
#define mtrace_printf(log_level, format_str, ...) \
do { \
STATIC_ASSERT(META_COUNT_VARAGS_BEFORE_COMPILE(__VA_ARGS__) \
<= _TRACE_EVENT_MAX_ARGUMENT_COUNT, \
too_many_mtrace_printf_arguments); \
_DECLARE_LOG_ENTRY(log_level, format_str, _TRACE_INV_CLASS, \
META_COUNT_VARAGS_BEFORE_COMPILE(__VA_ARGS__)); \
mtrace_dict_entry((uint32_t)&log_entry, \
META_COUNT_VARAGS_BEFORE_COMPILE(__VA_ARGS__), \
##__VA_ARGS__); \
} while (0)
/** Adds log_header prefix and appends arguments before sending */
void mtrace_dict_entry(uint32_t log_entry_pointer, int n_args, ...);
/** Posts a fully prepared log header + log entry */
void mtrace_event(const char *complete_packet, uint32_t length);
#endif /* __SOF_TRACE_TRACE_H__ */ #endif /* __SOF_TRACE_TRACE_H__ */

View File

@ -70,7 +70,7 @@ struct trace {
#define TRACE_ID_MASK ((1 << TRACE_ID_LENGTH) - 1) #define TRACE_ID_MASK ((1 << TRACE_ID_LENGTH) - 1)
static void put_header(uint32_t *dst, const struct sof_uuid_entry *uid, static void put_header(void *dst, const struct sof_uuid_entry *uid,
uint32_t id_1, uint32_t id_2, uint32_t id_1, uint32_t id_2,
uint32_t entry, uint64_t timestamp) uint32_t entry, uint64_t timestamp)
{ {
@ -93,7 +93,7 @@ static void put_header(uint32_t *dst, const struct sof_uuid_entry *uid,
} }
/** Ring buffer for the mailbox trace */ /** Ring buffer for the mailbox trace */
static inline void mtrace_event(const char *data, uint32_t length) void mtrace_event(const char *data, uint32_t length)
{ {
struct trace *trace = trace_get(); struct trace *trace = trace_get();
char *t = (char *)MAILBOX_TRACE_BASE; char *t = (char *)MAILBOX_TRACE_BASE;
@ -531,3 +531,22 @@ void trace_init(struct sof *sof)
dma_trace_init_early(sof); dma_trace_init_early(sof);
} }
void mtrace_dict_entry(uint32_t dict_entry_address, int n_args, ...)
{
va_list ap;
int i;
char packet[MESSAGE_SIZE(_TRACE_EVENT_MAX_ARGUMENT_COUNT)];
uint32_t *args = (uint32_t *)&packet[MESSAGE_SIZE(0)];
const uint64_t tstamp = platform_safe_get_time(timer_get());
put_header(packet, dt_tr.uuid_p, _TRACE_INV_ID, _TRACE_INV_ID,
dict_entry_address, tstamp);
va_start(ap, n_args);
for (i = 0; i < n_args; i++)
args[i] = va_arg(ap, uint32_t);
va_end(ap);
mtrace_event(packet, MESSAGE_SIZE(n_args));
}

View File

@ -25,18 +25,26 @@ struct timer;
uint64_t platform_timer_get(struct timer *timer); uint64_t platform_timer_get(struct timer *timer);
/* /*
* Use SOF macros, but let Zephyr take care of the physical log IO. * Override SOF dictionary macros for now and let Zephyr take care of
* the physical log IO.
*/ */
#undef _log_message #undef _log_message
#undef mtrace_printf
#if USE_PRINTK #if USE_PRINTK
#define mtrace_printf(level, format, ...) \
do { \
if ((level) <= SOF_ZEPHYR_TRACE_LEVEL) \
printk("%llu: " format "\n", platform_timer_get(NULL), \
##__VA_ARGS__); \
} while (0)
#define _log_message(log_func, atomic, level, comp_class, ctx, id1, id2, format, ...) \ #define _log_message(log_func, atomic, level, comp_class, ctx, id1, id2, format, ...) \
do { \ do { \
if ((level) <= SOF_ZEPHYR_TRACE_LEVEL) \ if ((level) <= SOF_ZEPHYR_TRACE_LEVEL) \
printk("%llu: " format "\n", platform_timer_get(NULL), \ printk("%llu: " format "\n", platform_timer_get(NULL), \
##__VA_ARGS__); \ ##__VA_ARGS__); \
} while (0) } while (0)
#else #else /* not tested */
#define _log_message(log_func, atomic, level, comp_class, ctx, id1, id2, format, ...) \ #define _log_message(log_func, atomic, level, comp_class, ctx, id1, id2, format, ...) \
do { \ do { \
Z_LOG(level, "%u: " format, (uint32_t)platform_timer_get(NULL), \ Z_LOG(level, "%u: " format, (uint32_t)platform_timer_get(NULL), \