soc/intel_adsp: Replace trace_out code with a sys_winstream

The newer sys_winstream utility is considerably simpler and much
faster for the reader.  Use that instead.

Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
This commit is contained in:
Andy Ross 2021-12-30 19:48:34 -08:00 committed by Anas Nashif
commit 8590f67f69
3 changed files with 18 additions and 117 deletions

View file

@ -4,6 +4,7 @@
# SPDX-License-Identifier: Apache-2.0
config SOC_FAMILY_INTEL_ADSP
select WINSTREAM
bool
if SOC_FAMILY_INTEL_ADSP

View file

@ -66,6 +66,8 @@
#define MANIFEST_SEGMENT_COUNT 3
extern void soc_trace_init(void);
/* Initial/true entry point. Does nothing but jump to
* z_boot_asm_entry (which cannot be here, because it needs to be able
* to reference immediates which must link before it)
@ -324,6 +326,7 @@ __imr void boot_core0(void)
win_setup();
lp_sram_init();
parse_manifest();
soc_trace_init();
z_xtensa_cache_flush_all();
/* Zephyr! */

View file

@ -1,72 +1,14 @@
/*
* Copyright (c) 2020 Intel Corporation
*
/* Copyright (c) 2021 Intel Corporation
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr.h>
#include <soc.h>
#include <cavs-mem.h>
#include <sys/winstream.h>
/* 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 starting from 1. 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.
*/
struct k_spinlock trace_lock;
#define SRAM_TRACE_BASE HP_SRAM_WIN3_BASE
#define SRAM_TRACE_SIZE HP_SRAM_WIN3_SIZE
#define SLOT_SIZE 64
#define SLOT_MAGIC 0x55aa
#define NSLOTS (SRAM_TRACE_SIZE / SLOT_SIZE)
#define MSGSZ (SLOT_SIZE - sizeof(struct slot_hdr))
struct slot_hdr {
uint16_t magic;
uint16_t id;
};
struct slot {
struct slot_hdr hdr;
char msg[MSGSZ];
};
struct metadata {
struct k_spinlock lock;
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! */
static __aligned(64) union {
struct metadata meta;
uint32_t cache_pad[16];
} data_rec;
#define data ((volatile struct metadata *)z_soc_uncached_ptr(&data_rec.meta))
static inline struct slot *slot(int i)
{
struct slot *slots = z_soc_uncached_ptr((void *)SRAM_TRACE_BASE);
return &slots[i];
}
static int slot_incr(int s)
{
return (s + 1) % NSLOTS;
}
static struct sys_winstream *winstream;
void intel_adsp_trace_out(int8_t *str, size_t len)
{
@ -84,62 +26,10 @@ void intel_adsp_trace_out(int8_t *str, size_t len)
: "r"(a4), "r"(a5) : "memory");
#endif
k_spinlock_key_t key = k_spin_lock((void *)&data->lock);
k_spinlock_key_t key = k_spin_lock(&trace_lock);
if (!data->initialized) {
slot(0)->hdr.magic = 0;
slot(0)->hdr.id = 0;
data->curr_slot = data->n_bytes = 0;
data->initialized = 1;
}
/* We work with a local copy of the global data for
* performance reasons (The memory behind the "data" pointer
* is uncached and volatile!) and put it back at the end.
*/
uint32_t curr_slot = data->curr_slot;
uint32_t n_bytes = data->n_bytes;
for (size_t i = 0; i < len; i++) {
int8_t c = str[i];
struct slot *s = slot(curr_slot);
s->msg[n_bytes++] = c;
/* Are we done with this slot? Terminate it and flag
* it for consumption on the other side
*/
if (c == '\n' || n_bytes >= MSGSZ) {
if (n_bytes < MSGSZ) {
s->msg[n_bytes] = 0;
}
/* Make sure the next slot has a magic number
* (so the reader can distinguish between
* no-new-data and system-reset), but does NOT
* have the correct successor ID (so can never
* be picked up as valid data). We'll
* increment it later when we terminate that
* slot.
*/
int next_slot = slot_incr(curr_slot);
uint16_t new_id = s->hdr.id + 1;
slot(next_slot)->hdr.id = new_id;
slot(next_slot)->hdr.magic = SLOT_MAGIC;
slot(next_slot)->msg[0] = 0;
s->hdr.id = new_id;
s->hdr.magic = SLOT_MAGIC;
curr_slot = next_slot;
n_bytes = 0;
}
}
data->curr_slot = curr_slot;
data->n_bytes = n_bytes;
k_spin_unlock((void *)&data->lock, key);
sys_winstream_write(winstream, str, len);
k_spin_unlock(&trace_lock, key);
}
int arch_printk_char_out(int c)
@ -149,3 +39,10 @@ int arch_printk_char_out(int c)
intel_adsp_trace_out(&s, 1);
return 0;
}
void soc_trace_init(void)
{
void *buf = z_soc_uncached_ptr((void *)HP_SRAM_WIN3_BASE);
winstream = sys_winstream_init(buf, HP_SRAM_WIN3_SIZE);
}