Skip to content

Commit

Permalink
logging: cAVS HDA based logger
Browse files Browse the repository at this point in the history
Adds a log backend that maintains a ringbuffer in coordination
with cAVS HDA.

The DMA channel is expected to be given some time after the logger
starts so a seperate step to initialize the dma channel is required.

Signed-off-by: Tom Burdick <[email protected]>
  • Loading branch information
teburd authored and nashif committed May 4, 2022
1 parent aceefa9 commit 6913da9
Show file tree
Hide file tree
Showing 15 changed files with 521 additions and 11 deletions.
5 changes: 0 additions & 5 deletions drivers/dma/dma_cavs_hda.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,6 @@

#include "dma_cavs_hda.h"

#include <logging/log.h>
LOG_MODULE_REGISTER(dma_cavs_hda_dma, CONFIG_DMA_LOG_LEVEL);

/* Define low level driver required values */
#define HDA_HOST_IN_BASE DT_PROP_BY_IDX(DT_NODELABEL(hda_host_in), reg, 0)
#define HDA_HOST_OUT_BASE DT_PROP_BY_IDX(DT_NODELABEL(hda_host_out), reg, 0)
Expand Down Expand Up @@ -257,7 +254,5 @@ int cavs_hda_dma_init(const struct device *dev)
data->ctx.atomic = data->channels_atomic;
data->ctx.magic = DMA_MAGIC;

LOG_INF("Intel cAVS HDA %s initialized", dev->name);

return 0;
}
4 changes: 0 additions & 4 deletions drivers/dma/dma_cavs_hda_host_in.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,6 @@
#include <drivers/dma.h>
#include "dma_cavs_hda.h"

#define LOG_LEVEL CONFIG_DMA_LOG_LEVEL
#include <logging/log.h>
LOG_MODULE_REGISTER(dma_cavs_hda_dma_host_in);

static const struct dma_driver_api cavs_hda_dma_host_in_api = {
.config = cavs_hda_dma_host_in_config,
.reload = cavs_hda_dma_host_reload,
Expand Down
32 changes: 32 additions & 0 deletions include/zephyr/logging/log_backend_cavs_hda.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Copyright (c) 2022 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/

#ifndef ZEPHYR_LOG_BACKEND_CAVS_HDA_H_
#define ZEPHYR_LOG_BACKEND_CAVS_HDA_H_

#include <stdint.h>

/**
*@brief HDA logger requires a hook for IPC messages
*
* When the log is flushed and written with DMA an IPC message should
* be sent to inform the host. This hook function pointer allows for that
*/
typedef void(*cavs_hda_log_hook_t)(uint32_t written);

/**
* @brief Initialize the cavs hda logger
*
* @param hook Function is called after each hda flush in order to
* inform the Host of DMA log data. This hook may be called
* from multiple CPUs and multiple calling contexts concurrently.
* It is up to the author of the hook to serialize if needed.
* It is guaranteed to be called once for every flush.
* @param channel HDA stream (DMA Channel) to use for logging
*/
void cavs_hda_log_init(cavs_hda_log_hook_t hook, uint32_t channel);

#endif /* ZEPHYR_LOG_BACKEND_CAVS_HDA_H_ */
5 changes: 4 additions & 1 deletion soc/xtensa/intel_adsp/common/include/cavstool.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,10 @@ enum cavstool_cmd {
IPCCMD_HDA_VALIDATE,

/* Host sends some data */
IPCCMD_HDA_SEND
IPCCMD_HDA_SEND,

/* Host prints some data */
IPCCMD_HDA_PRINT
};

#endif /* ZEPHYR_INCLUDE_CAVS_TEST_H */
19 changes: 18 additions & 1 deletion soc/xtensa/intel_adsp/tools/cavstool.py
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,10 @@ def winstream_read(last_seq):
result += win_read(16, behind - suffix)
(wlen, start1, end, seq1) = win_hdr()
if start1 == start and seq1 == seq:
return (seq, result.decode("utf-8"))
# Best effort attempt at decoding, replacing unusable characters
# Found to be useful when it really goes wrong
return (seq, result.decode("utf-8", "replace"))


async def ipc_delay_done():
await asyncio.sleep(0.1)
Expand Down Expand Up @@ -527,6 +530,7 @@ def ipc_command(data, ext_data):
elif data == 8: # HDA START
stream_id = ext_data & 0xFF
hda_streams[stream_id].start()
hda_streams[stream_id].mem.seek(0)

elif data == 9: # HDA STOP
stream_id = ext_data & 0xFF
Expand All @@ -551,6 +555,18 @@ def ipc_command(data, ext_data):
for i in range(0, 256):
buf[i] = i
hda_streams[stream_id].write(buf)
elif data == 12: # HDA PRINT
log.info("Doing HDA Print")
stream_id = ext_data & 0xFF
buf_len = ext_data >> 8 & 0xFFFF
hda_str = hda_streams[stream_id]
pos = hda_str.mem.tell()
buf_data = hda_str.mem.read(buf_len).decode("utf-8", "replace")
log.info(f"DSP LOG MSG (idx: {pos}, len: {buf_len}): {buf_data}")
pos = hda_str.mem.tell()
if pos >= hda_str.buf_len*2:
log.info(f"Wrapping log reader, pos {pos} len {hda_str.buf_len}")
hda_str.mem.seek(0)
else:
log.warning(f"cavstool: Unrecognized IPC command 0x{data:x} ext 0x{ext_data:x}")

Expand Down Expand Up @@ -589,6 +605,7 @@ async def main():
sys.stdout.write("--\n")

hda_streams = dict()

last_seq = 0
while True:
await asyncio.sleep(0.03)
Expand Down
5 changes: 5 additions & 0 deletions subsys/logging/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,11 @@ if(NOT CONFIG_LOG_MODE_MINIMAL)
zephyr_sources_ifdef(
CONFIG_LOG_BACKEND_ADSP
log_backend_adsp.c
)

zephyr_sources_ifdef(
CONFIG_LOG_BACKEND_CAVS_HDA
log_backend_cavs_hda.c
)

if(CONFIG_LOG_BACKEND_SPINEL)
Expand Down
35 changes: 35 additions & 0 deletions subsys/logging/Kconfig.backends
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,41 @@ source "subsys/logging/Kconfig.template.log_format_config"

endif # LOG_BACKEND_ADSP

config LOG_BACKEND_CAVS_HDA
bool "cAVS HDA backend"
depends on SOC_FAMILY_INTEL_ADSP && DMA && DMA_CAVS_HDA && LOG2
help
Provide a logging backend which writes to a buffer and
periodically flushes to hardware using ringbuffer like
semantics provided by DMA_CAVS_HDA.

if LOG_BACKEND_CAVS_HDA

backend = CAVS_HDA
backend-str = cavs_hda
source "subsys/logging/Kconfig.template.log_format_config"

config LOG_BACKEND_CAVS_HDA_SIZE
int "Size of ring buffer"
range 128 8192
default 4096
help
Sets the ring buffer size cAVS HDA uses for logging. Effectively
determines how many log messages may be written to in a period of time.
The period of time is decided by how often to inform the hardware of
writes to the buffer.

config LOG_BACKEND_CAVS_HDA_FLUSH_TIME
int "Time in milliseconds to periodically flush writes to hardware"
range 1 10000
default 500
help
The cAVS HDA backend periodically writes out its buffer contents
to hardware by informing the DMA hardware the contents of the ring
buffer.

endif # LOG_BACKEND_CAVS_HDA

config LOG_BACKEND_FS
bool "File system backend"
depends on FILE_SYSTEM
Expand Down
Loading

0 comments on commit 6913da9

Please sign in to comment.