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