soc/intel_adsp: Unify trace backends
This platform had separate backends for the log subsystem and printk handler, which was silly. Unify them to use the same backend so they don't clobber each other. This patch appears to be a lot of lines, but it's really mostly code motion and renaming. Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
This commit is contained in:
parent
5a10f27f13
commit
be2a5824f3
10 changed files with 135 additions and 270 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -7,11 +7,12 @@
|
|||
#include <adsp/cache.h>
|
||||
#include <soc/shim.h>
|
||||
|
||||
/* 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;
|
||||
}
|
|
@ -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)
|
||||
|
|
|
@ -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"
|
||||
|
|
84
subsys/logging/log_backend_adsp.c
Normal file
84
subsys/logging/log_backend_adsp.c
Normal file
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <logging/log_backend.h>
|
||||
#include <logging/log_core.h>
|
||||
#include <logging/log_msg.h>
|
||||
#include <logging/log_output.h>
|
||||
#include <logging/log_backend_std.h>
|
||||
|
||||
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);
|
|
@ -1,181 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <logging/log_backend.h>
|
||||
#include <logging/log_core.h>
|
||||
#include <logging/log_msg.h>
|
||||
#include <logging/log_output.h>
|
||||
#include <sys/byteorder.h>
|
||||
#include <sys/ring_buffer.h>
|
||||
|
||||
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);
|
Loading…
Add table
Add a link
Reference in a new issue