[Sound-open-firmware] [PATCH 1/2] trace: dma: Make sure we can trace platform device initialisation.
Currently the trace initialisation must be performed after DMAC init has completed. This means we miss the trace output from any platform device initialisation.
Split the DMA trace initialisation into two parts so the trace buffer is allocated early on and can accept messages meaning we dont miss any device initialisation trace.
Signed-off-by: Liam Girdwood liam.r.girdwood@linux.intel.com --- src/include/reef/dma-trace.h | 3 +- src/lib/dma-trace.c | 61 ++++++++++++++++------------------------ src/platform/baytrail/platform.c | 4 ++- 3 files changed, 30 insertions(+), 38 deletions(-)
diff --git a/src/include/reef/dma-trace.h b/src/include/reef/dma-trace.h index 2bd115e..4b17953 100644 --- a/src/include/reef/dma-trace.h +++ b/src/include/reef/dma-trace.h @@ -64,7 +64,8 @@ struct dma_trace_data { spinlock_t lock; };
-int dma_trace_init(struct dma_trace_data *d); +int dma_trace_init_early(struct dma_trace_data *d); +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); diff --git a/src/lib/dma-trace.c b/src/lib/dma-trace.c index a147219..0dccf7e 100644 --- a/src/lib/dma-trace.c +++ b/src/lib/dma-trace.c @@ -115,12 +115,9 @@ out: return DMA_TRACE_PERIOD; }
-int dma_trace_init(struct dma_trace_data *d) +int dma_trace_init_early(struct dma_trace_data *d) { struct dma_trace_buf *buffer = &d->dmatb; - int ret; - - trace_buffer("dtn");
/* allocate new buffer */ buffer->addr = rballoc(RZONE_RUNTIME, RFLAGS_NONE, DMA_TRACE_LOCAL_SIZE); @@ -129,14 +126,6 @@ int dma_trace_init(struct dma_trace_data *d) return -ENOMEM; }
- /* init DMA copy context */ - ret = dma_copy_new(&d->dc, PLATFORM_TRACE_DMAC); - if (ret < 0) { - trace_buffer_error("edm"); - rfree(buffer->addr); - return ret; - } - bzero(buffer->addr, DMA_TRACE_LOCAL_SIZE);
/* initialise the DMA buffer */ @@ -149,13 +138,32 @@ int dma_trace_init(struct dma_trace_data *d) d->copy_in_progress = 0;
list_init(&d->config.elem_list); - work_init(&d->dmat_work, trace_work, d, WORK_ASYNC); spinlock_init(&d->lock); trace_data = d;
return 0; }
+int dma_trace_init_complete(struct dma_trace_data *d) +{ + struct dma_trace_buf *buffer = &d->dmatb; + int ret; + + trace_buffer("dtn"); + + /* init DMA copy context */ + ret = dma_copy_new(&d->dc, PLATFORM_TRACE_DMAC); + if (ret < 0) { + trace_buffer_error("edm"); + rfree(buffer->addr); + return ret; + } + + work_init(&d->dmat_work, trace_work, d, WORK_ASYNC); + + return 0; +} + int dma_trace_host_buffer(struct dma_trace_data *d, struct dma_sg_elem *elem, uint32_t host_size) { @@ -193,15 +201,8 @@ static void dtrace_add_event(const char *e, uint32_t length)
margin = buffer->end_addr - buffer->w_ptr;
- /* validate */ - if (margin <= 0) { - trace_buffer_error("emm"); - return; - } - /* check for buffer wrap */ if (margin > length) { - /* no wrap */ memcpy(buffer->w_ptr, e, length); buffer->w_ptr += length; @@ -223,15 +224,11 @@ void dtrace_event(const char *e, uint32_t length) struct dma_trace_buf *buffer = NULL; unsigned long flags;
- if (trace_data == NULL || length == 0) - return; - - if (!trace_data->enabled) + if (trace_data == NULL || + length > DMA_TRACE_LOCAL_SIZE / 8 || length == 0) return;
buffer = &trace_data->dmatb; - if (buffer == NULL) - return;
spin_lock_irq(&trace_data->lock, flags); dtrace_add_event(e, length); @@ -253,16 +250,8 @@ void dtrace_event(const char *e, uint32_t length)
void dtrace_event_atomic(const char *e, uint32_t length) { - struct dma_trace_buf *buffer = NULL; - - if (trace_data == NULL || length == 0) - return; - - if (!trace_data->enabled) - return; - - buffer = &trace_data->dmatb; - if (buffer == NULL) + if (trace_data == NULL || + length > DMA_TRACE_LOCAL_SIZE / 8 || length == 0) return;
dtrace_add_event(e, length); diff --git a/src/platform/baytrail/platform.c b/src/platform/baytrail/platform.c index 12f7de5..cd884a8 100644 --- a/src/platform/baytrail/platform.c +++ b/src/platform/baytrail/platform.c @@ -297,6 +297,8 @@ int platform_init(struct reef *reef) trace_point(TRACE_BOOT_PLATFORM_IPC); ipc_init(reef);
+ dma_trace_init_early(&reef->ipc->dmat); + /* init DMACs */ trace_point(TRACE_BOOT_PLATFORM_DMA); dmac0 = dma_get(DMA_ID_DMAC0); @@ -359,7 +361,7 @@ int platform_init(struct reef *reef) #endif
/* Initialize DMA for Trace*/ - dma_trace_init(&reef->ipc->dmat); + dma_trace_init_complete(&reef->ipc->dmat);
return 0; }
Add message count and overflow detection to the trace position output so that kernel and userspace can detect the trace buffer has overflowed.
Signed-off-by: Liam Girdwood liam.r.girdwood@linux.intel.com --- src/include/reef/dma-trace.h | 2 ++ src/include/uapi/ipc.h | 2 ++ src/ipc/intel-ipc.c | 2 ++ src/lib/dma-trace.c | 9 ++++++++- 4 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/src/include/reef/dma-trace.h b/src/include/reef/dma-trace.h index 4b17953..ab9c112 100644 --- a/src/include/reef/dma-trace.h +++ b/src/include/reef/dma-trace.h @@ -57,6 +57,8 @@ struct dma_trace_data { struct dma_trace_buf dmatb; struct dma_copy dc; uint32_t host_offset; + uint32_t overflow; + uint32_t messages; uint32_t host_size; struct work dmat_work; uint32_t enabled; diff --git a/src/include/uapi/ipc.h b/src/include/uapi/ipc.h index dc35035..7123c8e 100644 --- a/src/include/uapi/ipc.h +++ b/src/include/uapi/ipc.h @@ -816,6 +816,8 @@ struct sof_ipc_dma_trace_params { struct sof_ipc_dma_trace_posn { struct sof_ipc_reply rhdr; uint32_t host_offset; /* Offset of DMA host buffer */ + uint32_t overflow; /* overflow bytes if any */ + uint32_t messages; /* total trace messages */ } __attribute__((packed));
#endif diff --git a/src/ipc/intel-ipc.c b/src/ipc/intel-ipc.c index 5ddb1e3..5a98e1f 100644 --- a/src/ipc/intel-ipc.c +++ b/src/ipc/intel-ipc.c @@ -648,6 +648,8 @@ int ipc_dma_trace_send_position(void)
posn.rhdr.hdr.cmd = SOF_IPC_GLB_TRACE_MSG | SOF_IPC_TRACE_DMA_POSITION; posn.host_offset = _ipc->dmat.host_offset; + posn.overflow = _ipc->dmat.overflow; + posn.messages = _ipc->dmat.messages; posn.rhdr.hdr.size = sizeof(posn);
return ipc_queue_host_message(_ipc, posn.rhdr.hdr.cmd, &posn, diff --git a/src/lib/dma-trace.c b/src/lib/dma-trace.c index 0dccf7e..ea63ab4 100644 --- a/src/lib/dma-trace.c +++ b/src/lib/dma-trace.c @@ -60,8 +60,12 @@ static uint64_t trace_work(void *data, uint64_t delay) d->copy_in_progress = 1;
/* make sure we dont write more than buffer */ - if (avail > DMA_TRACE_LOCAL_SIZE) + if (avail > DMA_TRACE_LOCAL_SIZE) { + d->overflow = avail - DMA_TRACE_LOCAL_SIZE; avail = DMA_TRACE_LOCAL_SIZE; + } else { + d->overflow = 0; + }
/* copy to host in sections if we wrap */ lsize = hsize = avail; @@ -134,6 +138,8 @@ int dma_trace_init_early(struct dma_trace_data *d) buffer->end_addr = buffer->addr + buffer->size; buffer->avail = 0; d->host_offset = 0; + d->overflow = 0; + d->messages = 0; d->enabled = 0; d->copy_in_progress = 0;
@@ -217,6 +223,7 @@ static void dtrace_add_event(const char *e, uint32_t length) }
buffer->avail += length; + trace_data->messages++; }
void dtrace_event(const char *e, uint32_t length)
participants (1)
-
Liam Girdwood