This patch adds a new trace_flush() feature to trace to flush the last remaining trace messages during panic.
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/dma-trace.h | 1 + src/include/reef/panic.h | 8 +++++++- src/include/reef/trace.h | 1 + src/lib/dma-trace.c | 20 ++++++++++++++++++++ src/lib/trace.c | 11 +++++++++++ src/platform/apollolake/include/platform/platform.h | 3 +++ src/platform/baytrail/include/platform/platform.h | 3 +++ src/platform/cannonlake/include/platform/platform.h | 3 +++ src/platform/haswell/include/platform/platform.h | 3 +++ 9 files changed, 52 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 f3f4dff..c915be8 100644 --- a/src/include/reef/trace.h +++ b/src/include/reef/trace.h @@ -109,6 +109,7 @@ void _trace_error_value(uint32_t event); void _trace_event_atomic(uint32_t event); void _trace_event_mbox_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 1ff2bd4..a61f1f2 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,25 @@ 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; + + /* number of bytes to flush */ + if (avail > DMA_FLUSH_TRACE_SIZE) { + size = DMA_FLUSH_TRACE_SIZE; + memcpy(t, buffer->w_ptr - DMA_FLUSH_TRACE_SIZE, size); + } else { + size = buffer->w_ptr - buffer->r_ptr; + memcpy(t, buffer->r_ptr, 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 bd0d376..b2082dd 100644 --- a/src/lib/trace.c +++ b/src/lib/trace.c @@ -201,6 +201,17 @@ void _trace_event_mbox_atomic(uint32_t event) dcache_writeback_region((void *)t, 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