diff --git a/soc/xtensa/intel_adsp/cavs_v15/Kconfig.defconfig.series b/soc/xtensa/intel_adsp/cavs_v15/Kconfig.defconfig.series index 457a118b743..e4bc11228fd 100644 --- a/soc/xtensa/intel_adsp/cavs_v15/Kconfig.defconfig.series +++ b/soc/xtensa/intel_adsp/cavs_v15/Kconfig.defconfig.series @@ -66,15 +66,9 @@ if LOG config LOG_PRINTK default y -config LOG_BACKEND_RB +config LOG_BACKEND_ADSP default y -config LOG_BACKEND_RB_MEM_BASE - default 0xBE000000 - -config LOG_BACKEND_RB_MEM_SIZE - default 8192 - endif # LOG if SMP diff --git a/soc/xtensa/intel_adsp/cavs_v18/Kconfig.defconfig.series b/soc/xtensa/intel_adsp/cavs_v18/Kconfig.defconfig.series index c4179e404d4..25a1669d044 100644 --- a/soc/xtensa/intel_adsp/cavs_v18/Kconfig.defconfig.series +++ b/soc/xtensa/intel_adsp/cavs_v18/Kconfig.defconfig.series @@ -52,15 +52,9 @@ if LOG config LOG_PRINTK default y if !CONSOLE -config LOG_BACKEND_RB +config LOG_BACKEND_ADSP default y -config LOG_BACKEND_RB_MEM_BASE - default 0xBE000000 - -config LOG_BACKEND_RB_MEM_SIZE - default 8192 - endif # LOG if SMP diff --git a/soc/xtensa/intel_adsp/cavs_v20/Kconfig.defconfig.series b/soc/xtensa/intel_adsp/cavs_v20/Kconfig.defconfig.series index 4e51a07000c..d1753a8a66a 100644 --- a/soc/xtensa/intel_adsp/cavs_v20/Kconfig.defconfig.series +++ b/soc/xtensa/intel_adsp/cavs_v20/Kconfig.defconfig.series @@ -51,15 +51,9 @@ if LOG config LOG_PRINTK default y -config LOG_BACKEND_RB +config LOG_BACKEND_ADSP default y -config LOG_BACKEND_RB_MEM_BASE - default 0xBE000000 - -config LOG_BACKEND_RB_MEM_SIZE - default 8192 - endif # LOG if SMP diff --git a/soc/xtensa/intel_adsp/cavs_v25/Kconfig.defconfig.series b/soc/xtensa/intel_adsp/cavs_v25/Kconfig.defconfig.series index 3e8a83d2378..3eff6d4c01c 100644 --- a/soc/xtensa/intel_adsp/cavs_v25/Kconfig.defconfig.series +++ b/soc/xtensa/intel_adsp/cavs_v25/Kconfig.defconfig.series @@ -51,15 +51,9 @@ if LOG config LOG_PRINTK default y -config LOG_BACKEND_RB +config LOG_BACKEND_ADSP default y -config LOG_BACKEND_RB_MEM_BASE - default 0xBE000000 - -config LOG_BACKEND_RB_MEM_SIZE - default 8192 - endif # LOG if SMP diff --git a/soc/xtensa/intel_adsp/common/CMakeLists.txt b/soc/xtensa/intel_adsp/common/CMakeLists.txt index aaf9ad17880..8a323c21bc7 100644 --- a/soc/xtensa/intel_adsp/common/CMakeLists.txt +++ b/soc/xtensa/intel_adsp/common/CMakeLists.txt @@ -15,7 +15,7 @@ zephyr_library_sources(adsp.c) zephyr_library_sources(main_entry.S) zephyr_library_sources(soc.c) zephyr_library_sources(soc_mp.c) -zephyr_library_sources(printk_out.c) +zephyr_library_sources(trace_out.c) zephyr_library_link_libraries(INTEL_ADSP_COMMON) diff --git a/soc/xtensa/intel_adsp/common/printk_out.c b/soc/xtensa/intel_adsp/common/trace_out.c similarity index 55% rename from soc/xtensa/intel_adsp/common/printk_out.c rename to soc/xtensa/intel_adsp/common/trace_out.c index ddb0cdbdb41..3760268ce0b 100644 --- a/soc/xtensa/intel_adsp/common/printk_out.c +++ b/soc/xtensa/intel_adsp/common/trace_out.c @@ -7,11 +7,12 @@ #include #include -/* Simple char-at-a-time output rig to the host kernel from a ADSP - * device. The protocol uses an array of "slots" in shared memory, - * each of which has a 16 bit magic number to validate and a - * sequential ID number. The remaining bytes are a (potentially - * nul-terminated) string containing output data. +/* Simple output driver for the trace window of an ADSP device used + * for communication with the host processor as a shared memory + * region. The protocol uses an array of 64-byte "slots", each of + * which is prefixed by a 16 bit magic number followed by a sequential + * ID number. The remaining bytes are a (potentially nul-terminated) + * string containing output data. * * IMPORTANT NOTE on cache coherence: the shared memory window is in * HP-SRAM. Each DSP core has an L1 cache that is incoherent (!) from @@ -44,9 +45,9 @@ struct slot { struct metadata { struct k_spinlock lock; - int initialized; - int curr_slot; /* To which slot are we writing? */ - int n_bytes; /* How many bytes buffered in curr_slot */ + bool initialized; + uint32_t curr_slot; /* To which slot are we writing? */ + uint32_t n_bytes; /* How many bytes buffered in curr_slot */ }; /* Give it a cache line all its own! */ @@ -64,7 +65,7 @@ static inline struct slot *slot(int i) return &slots[i]; } -int arch_printk_char_out(int c) +void intel_adsp_trace_out(int8_t *str, size_t len) { k_spinlock_key_t key = k_spin_lock(&data->lock); @@ -75,22 +76,41 @@ int arch_printk_char_out(int c) data->initialized = 1; } - struct slot *s = slot(data->curr_slot); + /* We work with a local copy of the global data for + * performance reasons (*data is uncached!) and put it back at + * the end. + */ + uint32_t curr_slot = data->curr_slot; + uint32_t n_bytes = data->n_bytes; - s->msg[data->n_bytes++] = c; + for (size_t i = 0; i < len; i++) { + int8_t c = str[i]; + struct slot *s = slot(curr_slot); - if (data->n_bytes < MSGSZ) { - s->msg[data->n_bytes] = 0; + s->msg[n_bytes++] = c; + + if (c == '\n' || n_bytes >= MSGSZ) { + curr_slot = (curr_slot + 1) % NSLOTS; + n_bytes = 0; + slot(curr_slot)->hdr.magic = 0; + slot(curr_slot)->hdr.id = s->hdr.id + 1; + s->hdr.magic = SLOT_MAGIC; + } } - if (c == '\n' || data->n_bytes >= MSGSZ) { - data->curr_slot = (data->curr_slot + 1) % NSLOTS; - data->n_bytes = 0; - slot(data->curr_slot)->hdr.magic = 0; - slot(data->curr_slot)->hdr.id = s->hdr.id + 1; - s->hdr.magic = SLOT_MAGIC; + if (n_bytes < MSGSZ) { + slot(curr_slot)->msg[n_bytes] = 0; } + data->curr_slot = curr_slot; + data->n_bytes = n_bytes; k_spin_unlock(&data->lock, key); +} + +int arch_printk_char_out(int c) +{ + int8_t s = c; + + intel_adsp_trace_out(&s, 1); return 0; } diff --git a/subsys/logging/CMakeLists.txt b/subsys/logging/CMakeLists.txt index eb48c58933b..084b49cdb5d 100644 --- a/subsys/logging/CMakeLists.txt +++ b/subsys/logging/CMakeLists.txt @@ -50,8 +50,8 @@ if(NOT CONFIG_LOG_MINIMAL) ) zephyr_sources_ifdef( - CONFIG_LOG_BACKEND_RB - log_backend_rb.c + CONFIG_LOG_BACKEND_ADSP + log_backend_adsp.c ) if(CONFIG_LOG_BACKEND_SPINEL) diff --git a/subsys/logging/Kconfig b/subsys/logging/Kconfig index f68e9e30ad3..22fe0b86271 100644 --- a/subsys/logging/Kconfig +++ b/subsys/logging/Kconfig @@ -528,46 +528,12 @@ config LOG_BACKEND_NET_AUTOSTART endif # LOG_BACKEND_NET -config LOG_BACKEND_RB - bool "Enable memory ring buffer backend" - select RING_BUFFER +config LOG_BACKEND_ADSP + bool "Enable Intel ADSP buffer backend" + depends on SOC_FAMILY_INTEL_ADSP help - Enable backend in memory using ring buffer to keep messages. - -if LOG_BACKEND_RB - -config LOG_BACKEND_RB_MEM_BASE - hex "Ring buffer memory base address" - help - Address of the ring buffer in the memory. - -config LOG_BACKEND_RB_MEM_SIZE - int "Size of the ring buffer" - help - Size of the ring buffer. Must be multiply of the message slot - size. - -config LOG_BACKEND_RB_SLOT_SIZE - int "Size of the message slot" - default 64 - help - Size of the message slot inside ring buffer. All log messages - are split to similar sized logging slots. - -config LOG_BACKEND_RB_CLEAR - bool "Clear ring buffer slot" - default y - help - Clearing ring buffer slot helps to write more easy tools to read logs - on different platforms. - -config LOG_BACKEND_RB_TIMESTAMP - bool "Add timestamp to the log" - default y - help - Add timestamp to the logging string. - -endif # LOG_BACKEND_RB + Enable backend for the host trace protocol of the Intel ADSP + family of audio processors config LOG_BACKEND_SHOW_COLOR bool "Enable colors in the backend" diff --git a/subsys/logging/log_backend_adsp.c b/subsys/logging/log_backend_adsp.c new file mode 100644 index 00000000000..acadd5afa29 --- /dev/null +++ b/subsys/logging/log_backend_adsp.c @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2019 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +void intel_adsp_trace_out(int8_t *str, size_t len); + +static int char_out(uint8_t *data, size_t length, void *ctx) +{ + intel_adsp_trace_out(data, length); + + return length; +} + +/* Trace output goes in 64 byte chunks with a 4-byte header, no point + * in buffering more than 60 bytes at a time + */ +static uint8_t log_buf[60]; + +LOG_OUTPUT_DEFINE(log_output_adsp, char_out, log_buf, 1); + +static uint32_t format_flags(void) +{ + uint32_t flags = LOG_OUTPUT_FLAG_LEVEL | LOG_OUTPUT_FLAG_TIMESTAMP; + + if (IS_ENABLED(CONFIG_LOG_BACKEND_FORMAT_TIMESTAMP)) { + flags |= LOG_OUTPUT_FLAG_FORMAT_TIMESTAMP; + } + return flags; +} + +static inline void put(const struct log_backend *const backend, + struct log_msg *msg) +{ + log_backend_std_put(&log_output_adsp, format_flags(), msg); +} +static void panic(struct log_backend const *const backend) +{ + log_backend_std_panic(&log_output_adsp); +} + +static inline void dropped(const struct log_backend *const backend, + uint32_t cnt) +{ + log_output_dropped_process(&log_output_adsp, cnt); +} + +static inline void put_sync_string(const struct log_backend *const backend, + struct log_msg_ids src_level, + uint32_t timestamp, const char *fmt, + va_list ap) +{ + log_output_string(&log_output_adsp, src_level, + timestamp, fmt, ap, format_flags()); +} + +static inline void put_sync_hexdump(const struct log_backend *const backend, + struct log_msg_ids src_level, + uint32_t timestamp, const char *metadata, + const uint8_t *data, uint32_t length) +{ + log_output_hexdump(&log_output_adsp, src_level, timestamp, + metadata, data, length, format_flags()); +} + +const struct log_backend_api log_backend_adsp_api = { +#ifdef CONFIG_LOG_IMMEDIATE + .put_sync_string = put_sync_string, + .put_sync_hexdump = put_sync_hexdump, +#else + .put = put, + .dropped = dropped, +#endif + .panic = panic, +}; + +LOG_BACKEND_DEFINE(log_backend_adsp, log_backend_adsp_api, true); diff --git a/subsys/logging/log_backend_rb.c b/subsys/logging/log_backend_rb.c deleted file mode 100644 index ff8f26ce3ec..00000000000 --- a/subsys/logging/log_backend_rb.c +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright (c) 2019 Intel Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include -#include - -static struct ring_buf ringbuf; - -/* - * Log message format: - * Logging started with magic number 0x55aa followed by log message id. - * Log message ended with null terminator and takes - * CONFIG_LOG_BACKEND_RB_SLOT_SIZE slot. The long log message can occupy - * several logging slots. - */ - -/* - * All log messages are split to similar sized logging slots. Since ring - * buffer slots get rewritten we need to check that all slots are fit to - * the ring buffer - */ -BUILD_ASSERT(CONFIG_LOG_BACKEND_RB_MEM_SIZE % - CONFIG_LOG_BACKEND_RB_SLOT_SIZE == 0); - -static void init(void) -{ - ring_buf_init(&ringbuf, CONFIG_LOG_BACKEND_RB_MEM_SIZE, - (void *)CONFIG_LOG_BACKEND_RB_MEM_BASE); -} - -static void trace(const uint8_t *data, size_t length) -{ - const uint16_t magic = 0x55aa; - static uint16_t log_id; - volatile uint8_t *t, *region; - int space; - - space = ring_buf_space_get(&ringbuf); - if (space < CONFIG_LOG_BACKEND_RB_SLOT_SIZE) { - uint8_t *dummy; - - /* Remove oldest entry */ - ring_buf_get_claim(&ringbuf, &dummy, - CONFIG_LOG_BACKEND_RB_SLOT_SIZE); - ring_buf_get_finish(&ringbuf, CONFIG_LOG_BACKEND_RB_SLOT_SIZE); - } - - ring_buf_put_claim(&ringbuf, (uint8_t **)&t, - CONFIG_LOG_BACKEND_RB_SLOT_SIZE); - region = t; - - /* Add magic number at the beginning of the slot */ - sys_put_le16(magic, (uint8_t *)t); - t += 2; - - /* Add log id */ - sys_put_le16(log_id++, (uint8_t *)t); - t += 2; - - length = MIN(length, CONFIG_LOG_BACKEND_RB_SLOT_SIZE - 4); - - memcpy((void *)t, data, length); - t += length; - - /* Clear logging slot */ - if (IS_ENABLED(CONFIG_LOG_BACKEND_RB_CLEAR) && - length < CONFIG_LOG_BACKEND_RB_SLOT_SIZE - 4) { - memset((void *)t, 0, - CONFIG_LOG_BACKEND_RB_SLOT_SIZE - 4 - length); - } - - SOC_DCACHE_FLUSH((void *)region, CONFIG_LOG_BACKEND_RB_SLOT_SIZE); - - ring_buf_put_finish(&ringbuf, CONFIG_LOG_BACKEND_RB_SLOT_SIZE); -} - -static int char_out(uint8_t *data, size_t length, void *ctx) -{ - trace(data, length); - - return length; -} - -/* magic and log id takes space */ -static uint8_t rb_log_buf[CONFIG_LOG_BACKEND_RB_SLOT_SIZE - 4]; - -LOG_OUTPUT_DEFINE(log_output_rb, char_out, rb_log_buf, sizeof(rb_log_buf)); - -static void put(const struct log_backend *const backend, - struct log_msg *msg) -{ - uint32_t flags = LOG_OUTPUT_FLAG_LEVEL; - - log_msg_get(msg); - - if (IS_ENABLED(CONFIG_LOG_BACKEND_RB_TIMESTAMP)) { - flags |= LOG_OUTPUT_FLAG_TIMESTAMP; - - if (IS_ENABLED(CONFIG_LOG_BACKEND_FORMAT_TIMESTAMP)) { - flags |= LOG_OUTPUT_FLAG_FORMAT_TIMESTAMP; - } - } - - log_output_msg_process(&log_output_rb, msg, flags); - - log_msg_put(msg); -} - -static void panic(struct log_backend const *const backend) -{ - log_output_flush(&log_output_rb); -} - -static void dropped(const struct log_backend *const backend, uint32_t cnt) -{ - ARG_UNUSED(backend); - - log_output_dropped_process(&log_output_rb, cnt); -} - -static void sync_string(const struct log_backend *const backend, - struct log_msg_ids src_level, uint32_t timestamp, - const char *fmt, va_list ap) -{ - uint32_t flags = LOG_OUTPUT_FLAG_LEVEL; - uint32_t key; - - if (IS_ENABLED(CONFIG_LOG_BACKEND_RB_TIMESTAMP)) { - flags |= LOG_OUTPUT_FLAG_TIMESTAMP; - - if (IS_ENABLED(CONFIG_LOG_BACKEND_FORMAT_TIMESTAMP)) { - flags |= LOG_OUTPUT_FLAG_FORMAT_TIMESTAMP; - } - } - - key = irq_lock(); - log_output_string(&log_output_rb, src_level, - timestamp, fmt, ap, flags); - irq_unlock(key); -} - -static void sync_hexdump(const struct log_backend *const backend, - struct log_msg_ids src_level, uint32_t timestamp, - const char *metadata, const uint8_t *data, uint32_t length) -{ - uint32_t flags = LOG_OUTPUT_FLAG_LEVEL; - uint32_t key; - - if (IS_ENABLED(CONFIG_LOG_BACKEND_RB_TIMESTAMP)) { - flags |= LOG_OUTPUT_FLAG_TIMESTAMP; - - if (IS_ENABLED(CONFIG_LOG_BACKEND_FORMAT_TIMESTAMP)) { - flags |= LOG_OUTPUT_FLAG_FORMAT_TIMESTAMP; - } - } - - key = irq_lock(); - log_output_hexdump(&log_output_rb, src_level, timestamp, - metadata, data, length, flags); - irq_unlock(key); -} - -const struct log_backend_api log_backend_rb_api = { - .put = IS_ENABLED(CONFIG_LOG_IMMEDIATE) ? NULL : put, - .put_sync_string = IS_ENABLED(CONFIG_LOG_IMMEDIATE) ? - sync_string : NULL, - .put_sync_hexdump = IS_ENABLED(CONFIG_LOG_IMMEDIATE) ? - sync_hexdump : NULL, - .panic = panic, - .init = init, - .dropped = IS_ENABLED(CONFIG_LOG_IMMEDIATE) ? NULL : dropped, -}; - -LOG_BACKEND_DEFINE(log_backend_adsp, log_backend_rb_api, true);