[Sound-open-firmware] [PATCH v3 1/3] trace: core: add trace_flush()
This patch adds a new trace_flush() feature to flush the last remaining trace messages during panic.
Signed-off-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com Signed-off-by: Yan Wang yan.wang@linux.intel.com --- Tested with Minnowboard Turbot with RT5651 Kernel: https://github.com/plbossart/sound.git branch: topic/sof-v4.14 SOF: https://github.com/ranj063/sof.git branch: debug/trace_test SOFT: 1.1-stable --- --- src/include/reef/dma-trace.h | 1 + src/include/reef/panic.h | 8 ++++- src/include/reef/trace.h | 1 + src/lib/dma-trace.c | 35 ++++++++++++++++++++++ src/lib/trace.c | 11 +++++++ .../apollolake/include/platform/platform.h | 3 ++ src/platform/baytrail/include/platform/platform.h | 3 ++ .../cannonlake/include/platform/platform.h | 3 ++ src/platform/haswell/include/platform/platform.h | 3 ++ 9 files changed, 67 insertions(+), 1 deletion(-)
diff --git a/src/include/reef/dma-trace.h b/src/include/reef/dma-trace.h index f17ffe5..bf6e3f3 100644 --- a/src/include/reef/dma-trace.h +++ b/src/include/reef/dma-trace.h @@ -72,6 +72,7 @@ int dma_trace_init_complete(struct dma_trace_data *d); int dma_trace_host_buffer(struct dma_trace_data *d, struct dma_sg_elem *elem, uint32_t host_size); int dma_trace_enable(struct dma_trace_data *d); +void dma_trace_flush(void *t);
void dtrace_event(const char *e, uint32_t size); void dtrace_event_atomic(const char *e, uint32_t length); diff --git a/src/include/reef/panic.h b/src/include/reef/panic.h index e8b4ae2..71df1b8 100644 --- a/src/include/reef/panic.h +++ b/src/include/reef/panic.h @@ -34,6 +34,7 @@ #include <reef/reef.h> #include <reef/mailbox.h> #include <reef/interrupt.h> +#include <reef/trace.h> #include <platform/platform.h> #include <uapi/ipc.h> #include <stdint.h> @@ -59,8 +60,13 @@ static inline void panic_rewind(uint32_t p, uint32_t stack_rewind_frames)
/* TODO: send IPC oops message to host */
- /* panic and loop forever */ + /* panic */ platform_panic(p); + + /* flush last trace messages */ + trace_flush(); + + /* and loop forever */ while (1) {}; }
diff --git a/src/include/reef/trace.h b/src/include/reef/trace.h index 7afbd23..44824b9 100644 --- a/src/include/reef/trace.h +++ b/src/include/reef/trace.h @@ -106,6 +106,7 @@ void _trace_error(uint32_t event); void _trace_error_value(uint32_t event); void _trace_event_atomic(uint32_t event); void _trace_error_atomic(uint32_t event); +void trace_flush(void); void trace_off(void); void trace_init(struct reef * reef);
diff --git a/src/lib/dma-trace.c b/src/lib/dma-trace.c index 10e6102..5046a09 100644 --- a/src/lib/dma-trace.c +++ b/src/lib/dma-trace.c @@ -36,6 +36,7 @@ #include <arch/cache.h> #include <platform/timer.h> #include <platform/dma.h> +#include <platform/platform.h> #include <reef/lock.h> #include <stdint.h>
@@ -285,6 +286,40 @@ int dma_trace_enable(struct dma_trace_data *d) return 0; }
+void dma_trace_flush(void *t) +{ + struct dma_trace_buf *buffer = &trace_data->dmatb; + uint32_t avail = buffer->avail; + int32_t size; + int32_t wrap_count; + + /* number of bytes to flush */ + if (avail > DMA_FLUSH_TRACE_SIZE) { + size = DMA_FLUSH_TRACE_SIZE; + } else { + /* check for buffer wrap */ + if (buffer->w_ptr > buffer->r_ptr) + size = buffer->w_ptr - buffer->r_ptr; + else + size = buffer->end_addr - buffer->r_ptr + + buffer->w_ptr - buffer->addr; + } + + /* check for buffer wrap */ + if (buffer->w_ptr - size < buffer->addr) { + wrap_count = buffer->w_ptr - buffer->addr; + memcpy(t, buffer->end_addr - (size - wrap_count), + size - wrap_count); + memcpy(t + (size - wrap_count), buffer->addr, + wrap_count); + } else { + memcpy(t, buffer->w_ptr - size, size); + } + + /* writeback trace data */ + dcache_writeback_region(t, size); +} + static void dtrace_add_event(const char *e, uint32_t length) { struct dma_trace_buf *buffer = &trace_data->dmatb; diff --git a/src/lib/trace.c b/src/lib/trace.c index de99a4e..8d53b97 100644 --- a/src/lib/trace.c +++ b/src/lib/trace.c @@ -136,6 +136,17 @@ void _trace_event_atomic(uint32_t event) dtrace_event_atomic((const char*)dt, sizeof(uint64_t) * 2); }
+void trace_flush(void) +{ + volatile uint64_t *t; + + /* get mailbox position */ + t = (volatile uint64_t *)(MAILBOX_TRACE_BASE + trace.pos); + + /* flush dma trace messages */ + dma_trace_flush((void *)t); +} + void trace_off(void) { trace.enable = 0; diff --git a/src/platform/apollolake/include/platform/platform.h b/src/platform/apollolake/include/platform/platform.h index a1dfba2..86172bf 100644 --- a/src/platform/apollolake/include/platform/platform.h +++ b/src/platform/apollolake/include/platform/platform.h @@ -88,6 +88,9 @@ struct reef; /* local buffer size of DMA tracing */ #define DMA_TRACE_LOCAL_SIZE HOST_PAGE_SIZE
+/* trace bytes flushed during panic */ +#define DMA_FLUSH_TRACE_SIZE (MAILBOX_TRACE_SIZE >> 2) + /* the interval of DMA trace copying */ #define DMA_TRACE_PERIOD 500000
diff --git a/src/platform/baytrail/include/platform/platform.h b/src/platform/baytrail/include/platform/platform.h index 9a6967b..f3464f5 100644 --- a/src/platform/baytrail/include/platform/platform.h +++ b/src/platform/baytrail/include/platform/platform.h @@ -82,6 +82,9 @@ struct reef; /* local buffer size of DMA tracing */ #define DMA_TRACE_LOCAL_SIZE HOST_PAGE_SIZE
+/* trace bytes flushed during panic */ +#define DMA_FLUSH_TRACE_SIZE (MAILBOX_TRACE_SIZE >> 2) + /* the interval of DMA trace copying */ #define DMA_TRACE_PERIOD 500000
diff --git a/src/platform/cannonlake/include/platform/platform.h b/src/platform/cannonlake/include/platform/platform.h index b007e8a..764ef76 100644 --- a/src/platform/cannonlake/include/platform/platform.h +++ b/src/platform/cannonlake/include/platform/platform.h @@ -92,6 +92,9 @@ struct reef; /* local buffer size of DMA tracing */ #define DMA_TRACE_LOCAL_SIZE HOST_PAGE_SIZE
+/* trace bytes flushed during panic */ +#define DMA_FLUSH_TRACE_SIZE (MAILBOX_TRACE_SIZE >> 2) + /* the interval of DMA trace copying */ #define DMA_TRACE_PERIOD 500000
diff --git a/src/platform/haswell/include/platform/platform.h b/src/platform/haswell/include/platform/platform.h index a9efe8a..9ffab90 100644 --- a/src/platform/haswell/include/platform/platform.h +++ b/src/platform/haswell/include/platform/platform.h @@ -81,6 +81,9 @@ struct reef; /* local buffer size of DMA tracing */ #define DMA_TRACE_LOCAL_SIZE HOST_PAGE_SIZE
+/* trace bytes flushed during panic */ +#define DMA_FLUSH_TRACE_SIZE (MAILBOX_TRACE_SIZE >> 2) + /* the interval of DMA trace copying */ #define DMA_TRACE_PERIOD 500000
This patch modifies the _trace_error function names to a more generic name _trace_event_mbox() and updates users.
Signed-off-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com --- Tested with Minnowboard Turbot with RT5651 Kernel: https://github.com/plbossart/sound.git branch: topic/sof-v4.14 SOF: https://github.com/ranj063/sof.git branch: debug/trace_test SOFT: 1.1-stable --- --- src/include/reef/trace.h | 16 +++++------ src/lib/trace.c | 72 ++++++++++++++++++++++++------------------------ 2 files changed, 43 insertions(+), 45 deletions(-)
diff --git a/src/include/reef/trace.h b/src/include/reef/trace.h index 44824b9..d6a68a6 100644 --- a/src/include/reef/trace.h +++ b/src/include/reef/trace.h @@ -102,10 +102,9 @@ #define TRACEE 1
void _trace_event(uint32_t event); -void _trace_error(uint32_t event); -void _trace_error_value(uint32_t event); +void _trace_event_mbox(uint32_t event); void _trace_event_atomic(uint32_t event); -void _trace_error_atomic(uint32_t event); +void _trace_event_mbox_atomic(uint32_t event); void trace_flush(void); void trace_off(void); void trace_init(struct reef * reef); @@ -116,7 +115,6 @@ void trace_init(struct reef * reef); _trace_event(__c | (__e[0] << 16) | (__e[1] <<8) | __e[2]) #define trace_event_atomic(__c, __e) \ _trace_event_atomic(__c | (__e[0] << 16) | (__e[1] <<8) | __e[2]) - #define trace_value(x) _trace_event(x) #define trace_value_atomic(x) _trace_event_atomic(x)
@@ -138,12 +136,12 @@ void trace_init(struct reef * reef); /* error tracing */ #if TRACEE #define trace_error(__c, __e) \ - _trace_error_atomic(__c | (__e[0] << 16) | (__e[1] <<8) | __e[2]) + _trace_event_mbox_atomic(__c | (__e[0] << 16) | (__e[1] << 8) | __e[2]) #define trace_error_atomic(__c, __e) \ - _trace_error_atomic(__c | (__e[0] << 16) | (__e[1] <<8) | __e[2]) -/* write back error value to mbox*/ -#define trace_error_value(x) _trace_error_atomic(x) -#define trace_error_value_atomic(x) _trace_error_atomic(x) + _trace_event_mbox_atomic(__c | (__e[0] << 16) | (__e[1] << 8) | __e[2]) +/* write back error value to mbox */ +#define trace_error_value(x) _trace_event_mbox_atomic(x) +#define trace_error_value_atomic(x) _trace_event_mbox_atomic(x) #else #define trace_error(__c, __e) #define trace_error_atomic(__c, __e) diff --git a/src/lib/trace.c b/src/lib/trace.c index 8d53b97..5f3ba8a 100644 --- a/src/lib/trace.c +++ b/src/lib/trace.c @@ -45,28 +45,54 @@ struct trace {
static struct trace trace;
-void _trace_error(uint32_t event) +/* send trace events only to the local trace buffer */ +void _trace_event(uint32_t event) +{ + uint64_t dt[2]; + + if (!trace.enable) + return; + + dt[0] = platform_timer_get(platform_timer); + dt[1] = event; + dtrace_event((const char *)dt, sizeof(uint64_t) * 2); +} + +void _trace_event_atomic(uint32_t event) +{ + uint64_t dt[2]; + + if (!trace.enable) + return; + + dt[0] = platform_timer_get(platform_timer); + dt[1] = event; + dtrace_event_atomic((const char *)dt, sizeof(uint64_t) * 2); +} + +/* send trace events to the local trace buffer and the mailbox */ +void _trace_event_mbox(uint32_t event) { unsigned long flags; - volatile uint64_t *t; uint64_t dt[2]; uint64_t time;
+ volatile uint64_t *t; + if (!trace.enable) return;
time = platform_timer_get(platform_timer);
- /* save event to DMA tracing buffer */ dt[0] = time; dt[1] = event; - dtrace_event((const char*)dt, sizeof(uint64_t) * 2); + dtrace_event((const char *)dt, sizeof(uint64_t) * 2);
/* send event by mail box too. */ spin_lock_irq(&trace.lock, flags);
/* write timestamp and event to trace buffer */ - t = (volatile uint64_t*)(MAILBOX_TRACE_BASE + trace.pos); + t = (volatile uint64_t *)(MAILBOX_TRACE_BASE + trace.pos); trace.pos += (sizeof(uint64_t) << 1);
if (trace.pos > MAILBOX_TRACE_SIZE - sizeof(uint64_t) * 2) @@ -78,14 +104,13 @@ void _trace_error(uint32_t event) t[1] = event;
/* writeback trace data */ - dcache_writeback_region((void*)t, sizeof(uint64_t) * 2); + dcache_writeback_region((void *)t, sizeof(uint64_t) * 2); }
-void _trace_error_atomic(uint32_t event) +void _trace_event_mbox_atomic(uint32_t event) { volatile uint64_t *t; uint64_t dt[2]; - uint64_t time;
if (!trace.enable) @@ -93,13 +118,12 @@ void _trace_error_atomic(uint32_t event)
time = platform_timer_get(platform_timer);
- /* save event to DMA tracing buffer */ dt[0] = time; dt[1] = event; - dtrace_event_atomic((const char*)dt, sizeof(uint64_t) * 2); + dtrace_event_atomic((const char *)dt, sizeof(uint64_t) * 2);
/* write timestamp and event to trace buffer */ - t = (volatile uint64_t*)(MAILBOX_TRACE_BASE + trace.pos); + t = (volatile uint64_t *)(MAILBOX_TRACE_BASE + trace.pos); trace.pos += (sizeof(uint64_t) << 1);
if (trace.pos > MAILBOX_TRACE_SIZE - sizeof(uint64_t) * 2) @@ -109,31 +133,7 @@ void _trace_error_atomic(uint32_t event) t[1] = event;
/* writeback trace data */ - dcache_writeback_region((void*)t, sizeof(uint64_t) * 2); -} - -void _trace_event(uint32_t event) -{ - uint64_t dt[2]; - - if (!trace.enable) - return; - - dt[0] = platform_timer_get(platform_timer); - dt[1] = event; - dtrace_event((const char*)dt, sizeof(uint64_t) * 2); -} - -void _trace_event_atomic(uint32_t event) -{ - uint64_t dt[2]; - - if (!trace.enable) - return; - - dt[0] = platform_timer_get(platform_timer); - dt[1] = event; - dtrace_event_atomic((const char*)dt, sizeof(uint64_t) * 2); + dcache_writeback_region((void *)t, sizeof(uint64_t) * 2); }
void trace_flush(void)
This patch introduces a new macro that can be used to enable sending all trace messages to mbox alongside the local trace buffer.
Signed-off-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com --- Tested with Minnowboard Turbot with RT5651 Kernel: https://github.com/plbossart/sound.git branch: topic/sof-v4.14 SOF: https://github.com/ranj063/sof.git branch: debug/trace_test SOFT: 1.1-stable --- --- src/include/reef/trace.h | 10 ++++++++++ 1 file changed, 10 insertions(+)
diff --git a/src/include/reef/trace.h b/src/include/reef/trace.h index d6a68a6..cd1178b 100644 --- a/src/include/reef/trace.h +++ b/src/include/reef/trace.h @@ -100,6 +100,7 @@ #define TRACE 1 #define TRACEV 0 #define TRACEE 1 +#define TRACEM 0 /* send all trace messages to mbox and local trace buffer */
void _trace_event(uint32_t event); void _trace_event_mbox(uint32_t event); @@ -111,10 +112,19 @@ void trace_init(struct reef * reef);
#if TRACE
+/* send all trace to mbox and local trace buffer */ +#if TRACEM +#define trace_event(__c, __e) \ + _trace_event_mbox(__c | (__e[0] << 16) | (__e[1] << 8) | __e[2]) +#define trace_event_atomic(__c, __e) \ + _trace_event_mbox_atomic(__c | (__e[0] << 16) | (__e[1] << 8) | __e[2]) +/* send trace events only to the local trace buffer */ +#else #define trace_event(__c, __e) \ _trace_event(__c | (__e[0] << 16) | (__e[1] <<8) | __e[2]) #define trace_event_atomic(__c, __e) \ _trace_event_atomic(__c | (__e[0] << 16) | (__e[1] <<8) | __e[2]) +#endif #define trace_value(x) _trace_event(x) #define trace_value_atomic(x) _trace_event_atomic(x)
On Tue, 2018-03-27 at 22:07 -0700, Ranjani Sridharan wrote:
This patch adds a new trace_flush() feature to flush the last remaining trace messages during panic.
Signed-off-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com Signed-off-by: Yan Wang yan.wang@linux.intel.com
Tested with Minnowboard Turbot with RT5651 Kernel: https://github.com/plbossart/sound.git branch: topic/sof-v4.14 SOF: https://github.com/ranj063/sof.git branch: debug/trace_test SOFT: 1.1-stable
All applied.
Thanks
Liam
participants (2)
-
Liam Girdwood
-
Ranjani Sridharan