diff --git a/boards/xtensa/up_squared_adsp/tools/adsplog.py b/boards/xtensa/up_squared_adsp/tools/adsplog.py index 0a2a18280a1..f2084ebf13e 100755 --- a/boards/xtensa/up_squared_adsp/tools/adsplog.py +++ b/boards/xtensa/up_squared_adsp/tools/adsplog.py @@ -11,11 +11,11 @@ import mmap MAP_SIZE = 8192 SLOT_SIZE = 64 -# Location of the log output window within the mapping of the SRAM -# (BAR4) on the PCI device. These numbers are cribbed from existing -# scripting, I don't know what they really mean or where the spec for -# these protocols is. The driver on the DSP just hard codes an -# address. +# Location of the log output window within the DSP BAR on the PCI +# device. The hardware provides 4x 128k "windows" starting at 512kb +# in the BAR which the DSP software can map to 4k-aligned locations +# within its own address space. By convention log output is an 8k +# region at window index 3. WIN_OFFSET = 0x80000 WIN_ID = 3 WIN_SIZE = 0x20000 diff --git a/soc/xtensa/intel_adsp/cavs_v15/Kconfig.defconfig.series b/soc/xtensa/intel_adsp/cavs_v15/Kconfig.defconfig.series index 8cfbb05d887..8d3dfe11832 100644 --- a/soc/xtensa/intel_adsp/cavs_v15/Kconfig.defconfig.series +++ b/soc/xtensa/intel_adsp/cavs_v15/Kconfig.defconfig.series @@ -47,9 +47,6 @@ config 2ND_LEVEL_INTERRUPTS config DYNAMIC_INTERRUPTS default y -config LOG - default y - # To prevent test uses TEST_LOGGING_MINIMAL config TEST_LOGGING_DEFAULTS default n diff --git a/soc/xtensa/intel_adsp/common/printk_out.c b/soc/xtensa/intel_adsp/common/printk_out.c new file mode 100644 index 00000000000..4ce6e9a6430 --- /dev/null +++ b/soc/xtensa/intel_adsp/common/printk_out.c @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2020 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#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. + * + * IMPORTANT NOTE on cache coherence: the shared memory window is in + * HP-SRAM. Each DSP core has an L1 cache that is incoherent (!) from + * the perspective of the other cores. To handle this, we take care + * to access all memory through the uncached window into HP-SRAM at + * 0x9xxxxxxx and not the L1-cached mapping of the same memory at + * 0xBxxxxxxx. + */ + +#define SLOT_SIZE 64 +#define SLOT_MAGIC 0x55aa + +#define NSLOTS (SRAM_TRACE_SIZE / SLOT_SIZE) +#define MSGSZ (SLOT_SIZE - sizeof(struct slot_hdr)) + +/* Translates a SRAM pointer into an address of the same memory in the + * uncached region from 0x80000000-0x9fffffff + */ +#define UNCACHED_PTR(p) ((void*)(((int)p) & ~0x20000000)) + +struct slot_hdr { + uint16_t magic; + uint16_t id; +}; + +struct slot { + struct slot_hdr hdr; + char msg[MSGSZ]; +}; + +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 */ +}; + +/* Give it a cache line all its own! */ +static __aligned(64) union { + struct metadata meta; + uint32_t cache_pad[16]; +} data_rec; + +#define data ((struct metadata *)UNCACHED_PTR(&data_rec.meta)) + +static inline struct slot *slot(int i) +{ + struct slot *slots = UNCACHED_PTR(SRAM_TRACE_BASE); + + return &slots[i]; +} + +int arch_printk_char_out(int c) +{ + k_spinlock_key_t key = k_spin_lock(&data->lock); + + if (!data->initialized) { + slot(0)->hdr.magic = 0; + slot(0)->hdr.id = 0; + data->curr_slot = data->n_bytes = 0; + data->initialized = 1; + } + + struct slot *s = slot(data->curr_slot); + + s->msg[data->n_bytes++] = c; + + if (data->n_bytes < MSGSZ) { + s->msg[data->n_bytes] = 0; + } + + 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; + } + + k_spin_unlock(&data->lock, key); + return 0; +}