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:
parent
528bef2d22
commit
8590f67f69
3 changed files with 18 additions and 117 deletions
|
@ -4,6 +4,7 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
config SOC_FAMILY_INTEL_ADSP
|
||||
select WINSTREAM
|
||||
bool
|
||||
|
||||
if SOC_FAMILY_INTEL_ADSP
|
||||
|
|
|
@ -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! */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue