intel_adsp: Add debug slot manager
Currently all drivers which uses a slot from the debug window have fragile hardwired slot 'mapping', they are locked to use specific slots even if there are free slots available for them to take. The new API hides the management of the slots and descriptors and users can ask, release or even seize slots that they want to use. Add a new debug slot manager API and a new default no config option to allow selection between the hardwired or dynamic debug slot management. Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
This commit is contained in:
committed by
Anas Nashif
parent
2ce9d5f5e3
commit
ebb5625bee
@@ -77,6 +77,15 @@ config MEMORY_WIN_3_SIZE
|
||||
|
||||
This window is used for trace.
|
||||
|
||||
config INTEL_ADSP_DEBUG_SLOT_MANAGER
|
||||
bool "Debug slot manager"
|
||||
help
|
||||
If selected the debug slot allocation can be only done via
|
||||
the manager API, direct debug window access and tampering is
|
||||
forbidden.
|
||||
The API use allows dynamic slot allocation instead of static
|
||||
and error prone slot usage.
|
||||
|
||||
config ADSP_CLOCK
|
||||
bool
|
||||
help
|
||||
|
||||
@@ -25,6 +25,10 @@ zephyr_library_sources(
|
||||
|
||||
zephyr_library_sources_ifdef(CONFIG_ADSP_CLOCK clk.c)
|
||||
|
||||
zephyr_library_sources_ifdef(CONFIG_INTEL_ADSP_DEBUG_SLOT_MANAGER
|
||||
debug_window.c
|
||||
)
|
||||
|
||||
if(CONFIG_SMP OR CONFIG_MP_MAX_NUM_CPUS GREATER 1)
|
||||
zephyr_library_sources(multiprocessing.c)
|
||||
endif()
|
||||
|
||||
187
soc/intel/intel_adsp/common/debug_window.c
Normal file
187
soc/intel/intel_adsp/common/debug_window.c
Normal file
@@ -0,0 +1,187 @@
|
||||
/* Copyright (c) 2025 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <adsp_memory.h>
|
||||
#include <adsp_debug_window.h>
|
||||
#include <zephyr/cache.h>
|
||||
|
||||
#include <zephyr/logging/log.h>
|
||||
LOG_MODULE_REGISTER(debug_window, CONFIG_SOC_LOG_LEVEL);
|
||||
|
||||
struct adsp_debug_window {
|
||||
struct adsp_dw_desc descs[ADSP_DW_DESC_COUNT];
|
||||
uint8_t reserved[ADSP_DW_PAGE0_SLOT_OFFSET -
|
||||
ADSP_DW_DESC_COUNT * sizeof(struct adsp_dw_desc)];
|
||||
uint8_t partial_page0[ADSP_DW_SLOT_SIZE - ADSP_DW_PAGE0_SLOT_OFFSET];
|
||||
uint8_t slots[ADSP_DW_SLOT_COUNT][ADSP_DW_SLOT_SIZE];
|
||||
} __packed;
|
||||
|
||||
#define WIN2_MBASE DT_REG_ADDR(DT_PHANDLE(DT_NODELABEL(mem_window2), memory))
|
||||
#define WIN2_SLOTS ((HP_SRAM_WIN2_SIZE / ADSP_DW_PAGE_SIZE) - 1)
|
||||
#define ADSP_DW_FULL_SLOTS MIN(WIN2_SLOTS, ADSP_DW_SLOT_COUNT)
|
||||
|
||||
#define ADSP_DW ((struct adsp_debug_window *) \
|
||||
(sys_cache_uncached_ptr_get((__sparse_force void __sparse_cache *) \
|
||||
(WIN2_MBASE + WIN2_OFFSET))))
|
||||
|
||||
static int adsp_dw_find_unused_slot(bool prefer_partial)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (prefer_partial) {
|
||||
if (ADSP_DW->descs[ADSP_DW_SLOT_COUNT].type == ADSP_DW_SLOT_UNUSED) {
|
||||
return ADSP_DW_SLOT_COUNT;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < ADSP_DW_FULL_SLOTS; i++) {
|
||||
if (ADSP_DW->descs[i].type == ADSP_DW_SLOT_UNUSED) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
if (!prefer_partial) {
|
||||
if (ADSP_DW->descs[ADSP_DW_SLOT_COUNT].type == ADSP_DW_SLOT_UNUSED) {
|
||||
return ADSP_DW_SLOT_COUNT;
|
||||
}
|
||||
}
|
||||
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
static int adsp_dw_find_slot_by_type(uint32_t type)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ADSP_DW_FULL_SLOTS; i++) {
|
||||
if (ADSP_DW->descs[i].type == type) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
if (ADSP_DW->descs[ADSP_DW_SLOT_COUNT].type == type) {
|
||||
return ADSP_DW_SLOT_COUNT;
|
||||
}
|
||||
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
void *adsp_dw_request_slot(struct adsp_dw_desc *dw_desc, size_t *slot_size)
|
||||
{
|
||||
int slot_idx;
|
||||
|
||||
if (!dw_desc->type) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Check if a slot has been allocated for this type */
|
||||
slot_idx = adsp_dw_find_slot_by_type(dw_desc->type);
|
||||
if (slot_idx >= 0) {
|
||||
if (slot_size) {
|
||||
*slot_size = ADSP_DW_SLOT_SIZE;
|
||||
}
|
||||
|
||||
if (slot_idx == ADSP_DW_SLOT_COUNT) {
|
||||
if (slot_size) {
|
||||
*slot_size -= ADSP_DW_PAGE0_SLOT_OFFSET;
|
||||
}
|
||||
return ADSP_DW->partial_page0;
|
||||
}
|
||||
|
||||
return ADSP_DW->slots[slot_idx];
|
||||
}
|
||||
|
||||
/* Look for an empty slot */
|
||||
slot_idx = adsp_dw_find_unused_slot(!!slot_size);
|
||||
if (slot_idx < 0) {
|
||||
LOG_INF("No available slot for %#x", dw_desc->type);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ADSP_DW->descs[slot_idx].resource_id = dw_desc->resource_id;
|
||||
ADSP_DW->descs[slot_idx].type = dw_desc->type;
|
||||
ADSP_DW->descs[slot_idx].vma = dw_desc->vma;
|
||||
|
||||
if (slot_size) {
|
||||
*slot_size = ADSP_DW_SLOT_SIZE;
|
||||
}
|
||||
|
||||
if (slot_idx == ADSP_DW_SLOT_COUNT) {
|
||||
if (slot_size) {
|
||||
*slot_size -= ADSP_DW_PAGE0_SLOT_OFFSET;
|
||||
}
|
||||
|
||||
LOG_DBG("Allocating partial page0 to be used for %#x", dw_desc->type);
|
||||
|
||||
return ADSP_DW->partial_page0;
|
||||
}
|
||||
|
||||
LOG_DBG("Allocating debug slot %d to be used for %#x", slot_idx, dw_desc->type);
|
||||
|
||||
return ADSP_DW->slots[slot_idx];
|
||||
}
|
||||
|
||||
void *adsp_dw_seize_slot(uint32_t slot_index, struct adsp_dw_desc *dw_desc,
|
||||
size_t *slot_size)
|
||||
{
|
||||
if ((slot_index >= ADSP_DW_FULL_SLOTS && slot_index != ADSP_DW_SLOT_COUNT) ||
|
||||
!dw_desc->type) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (slot_index < ADSP_DW_FULL_SLOTS) {
|
||||
if (ADSP_DW->descs[slot_index].type != ADSP_DW_SLOT_UNUSED) {
|
||||
LOG_INF("Overtaking debug slot %d, used by %#x for %#x", slot_index,
|
||||
ADSP_DW->descs[slot_index].type, dw_desc->type);
|
||||
}
|
||||
|
||||
if (slot_size) {
|
||||
*slot_size = ADSP_DW_SLOT_SIZE;
|
||||
}
|
||||
|
||||
ADSP_DW->descs[slot_index].resource_id = dw_desc->resource_id;
|
||||
ADSP_DW->descs[slot_index].type = dw_desc->type;
|
||||
ADSP_DW->descs[slot_index].vma = dw_desc->vma;
|
||||
|
||||
return ADSP_DW->slots[slot_index];
|
||||
}
|
||||
|
||||
/* The caller is not prepared to handle partial debug slot */
|
||||
if (!slot_size) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ADSP_DW->descs[slot_index].type != ADSP_DW_SLOT_UNUSED) {
|
||||
LOG_INF("Overtaking partial page0, used by %#x for %#x",
|
||||
ADSP_DW->descs[slot_index].type, dw_desc->type);
|
||||
}
|
||||
|
||||
*slot_size = ADSP_DW_SLOT_SIZE - ADSP_DW_PAGE0_SLOT_OFFSET;
|
||||
|
||||
ADSP_DW->descs[slot_index].resource_id = dw_desc->resource_id;
|
||||
ADSP_DW->descs[slot_index].type = dw_desc->type;
|
||||
ADSP_DW->descs[slot_index].vma = dw_desc->vma;
|
||||
|
||||
return ADSP_DW->partial_page0;
|
||||
}
|
||||
|
||||
void adsp_dw_release_slot(uint32_t type)
|
||||
{
|
||||
int slot_idx;
|
||||
|
||||
slot_idx = adsp_dw_find_slot_by_type(type);
|
||||
if (slot_idx < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (slot_idx == ADSP_DW_SLOT_COUNT) {
|
||||
LOG_DBG("Releasing partial page0 used by %#x", type);
|
||||
} else {
|
||||
LOG_DBG("Releasing debug slot %d used by %#x", slot_idx, type);
|
||||
}
|
||||
|
||||
ADSP_DW->descs[slot_idx].resource_id = 0;
|
||||
ADSP_DW->descs[slot_idx].type = ADSP_DW_SLOT_UNUSED;
|
||||
ADSP_DW->descs[slot_idx].vma = 0;
|
||||
}
|
||||
@@ -57,18 +57,51 @@ static inline int ring_have_data(const volatile struct gdb_sram_ring *ring)
|
||||
return ring->head != ring->tail;
|
||||
}
|
||||
|
||||
#define RX_UNCACHED (uint8_t *) (HP_SRAM_WIN2_BASE + SOF_GDB_WINDOW_OFFSET)
|
||||
#define TX_UNCACHED (uint8_t *) (RX_UNCACHED + sizeof(struct gdb_sram_ring))
|
||||
|
||||
static volatile struct gdb_sram_ring *rx;
|
||||
static volatile struct gdb_sram_ring *tx;
|
||||
|
||||
#ifndef CONFIG_INTEL_ADSP_DEBUG_SLOT_MANAGER
|
||||
static int gdb_get_debug_slot(void)
|
||||
{
|
||||
struct adsp_dw_desc slot_desc = { .type = ADSP_DW_SLOT_GDB_STUB, };
|
||||
size_t slot_size;
|
||||
char *slot_addr;
|
||||
|
||||
if (rx && tx) {
|
||||
/* Slot already allocated */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Force use the partial page0 slot */
|
||||
slot_addr = (char *)adsp_dw_request_slot(&slot_desc, &slot_size);
|
||||
if (!slot_addr) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
rx = sys_cache_uncached_ptr_get(slot_addr);
|
||||
tx = sys_cache_uncached_ptr_get(slot_addr + sizeof(struct gdb_sram_ring));
|
||||
|
||||
return 0;
|
||||
}
|
||||
#define RX_UNCACHED (uint8_t *) (HP_SRAM_WIN2_BASE + SOF_GDB_WINDOW_OFFSET)
|
||||
#define TX_UNCACHED (uint8_t *) (RX_UNCACHED + sizeof(struct gdb_sram_ring))
|
||||
#endif
|
||||
|
||||
int z_gdb_backend_init(void)
|
||||
{
|
||||
#ifdef CONFIG_INTEL_ADSP_DEBUG_SLOT_MANAGER
|
||||
int ret = gdb_get_debug_slot();
|
||||
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
__ASSERT_NO_MSG(sizeof(ADSP_DW->descs) <= SOF_GDB_WINDOW_OFFSET);
|
||||
|
||||
rx = sys_cache_uncached_ptr_get(RX_UNCACHED);
|
||||
tx = sys_cache_uncached_ptr_get(TX_UNCACHED);
|
||||
#endif
|
||||
|
||||
rx->head = rx->tail = 0;
|
||||
tx->head = tx->tail = 0;
|
||||
|
||||
@@ -98,7 +131,12 @@ unsigned char z_gdb_getchar(void)
|
||||
|
||||
static int gdbstub_backend_sram_init(void)
|
||||
{
|
||||
#ifdef CONFIG_INTEL_ADSP_DEBUG_SLOT_MANAGER
|
||||
return gdb_get_debug_slot();
|
||||
#else
|
||||
ADSP_DW->descs[ADSP_DW_SLOT_NUM_GDB].type = ADSP_DW_SLOT_GDB_STUB;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -65,14 +65,6 @@
|
||||
#define ADSP_DW_PAGE0_SLOT_OFFSET 1024
|
||||
#define ADSP_DW_DESC_COUNT (ADSP_DW_SLOT_COUNT + 1)
|
||||
|
||||
/* debug window slots usage, mutually exclusive options can reuse slots */
|
||||
#define ADSP_DW_SLOT_NUM_SHELL 0
|
||||
#define ADSP_DW_SLOT_NUM_MTRACE 0
|
||||
#define ADSP_DW_SLOT_NUM_TRACE 1
|
||||
#define ADSP_DW_SLOT_NUM_TELEMETRY 1
|
||||
/* this uses remaining space in the first page after descriptors */
|
||||
#define ADSP_DW_SLOT_NUM_GDB (ADSP_DW_DESC_COUNT - 1)
|
||||
|
||||
/* debug log slot types */
|
||||
#define ADSP_DW_SLOT_UNUSED 0x00000000
|
||||
#define ADSP_DW_SLOT_CRITICAL_LOG 0x54524300
|
||||
@@ -94,6 +86,56 @@ struct adsp_dw_desc {
|
||||
uint32_t vma;
|
||||
} __packed;
|
||||
|
||||
#ifdef CONFIG_INTEL_ADSP_DEBUG_SLOT_MANAGER
|
||||
/**
|
||||
* @brief Request a free debug slot for a function described by desc
|
||||
*
|
||||
* if a slot for the same function has been already allocated, the existing slot will be returned
|
||||
*
|
||||
* @param dw_desc Description of the slot to be requested for
|
||||
* @param slot_size Optional pointer to receive back the size of the assigned slot, if not
|
||||
* provided then the partial slot from window 0 cannot be requested as caller
|
||||
* must be aware and be able to handle the different size of the slot
|
||||
*
|
||||
* @return Pointer to the start of the slot or NULL in case of an error. When NULL is
|
||||
* returned, the @slot_size value is undefined.
|
||||
*/
|
||||
void *adsp_dw_request_slot(struct adsp_dw_desc *dw_desc, size_t *slot_size);
|
||||
|
||||
/**
|
||||
* @brief Forcibly overtake a slot
|
||||
*
|
||||
* @param slot_index Index of the slot to take.
|
||||
* Requesting ADSP_DW_FULL_SLOTS will return the partial slot
|
||||
* @param dw_desc Description of the slot to be requested for
|
||||
* @param slot_size Optional pointer to receive back the size of the assigned slot, if not
|
||||
* provided then the partial slot from window 0 cannot be requested as caller
|
||||
* must be aware and be able to handle the different size of the slot
|
||||
*
|
||||
* @return Pointer to the start of the slot or NULL in case of an error. When NULL is
|
||||
* returned, the @slot_size value is undefined.
|
||||
*/
|
||||
void *adsp_dw_seize_slot(uint32_t slot_index, struct adsp_dw_desc *dw_desc,
|
||||
size_t *slot_size);
|
||||
|
||||
/**(
|
||||
* @brief Release a slot allocated for type
|
||||
*
|
||||
* @param type Slot type to be released
|
||||
*
|
||||
* @note Only a single slot can be allocated at the same time for a type
|
||||
*/
|
||||
void adsp_dw_release_slot(uint32_t type);
|
||||
#else /* CONFIG_INTEL_ADSP_DEBUG_SLOT_MANAGER */
|
||||
|
||||
/* debug window slots usage, mutually exclusive options can reuse slots */
|
||||
#define ADSP_DW_SLOT_NUM_SHELL 0
|
||||
#define ADSP_DW_SLOT_NUM_MTRACE 0
|
||||
#define ADSP_DW_SLOT_NUM_TRACE 1
|
||||
#define ADSP_DW_SLOT_NUM_TELEMETRY 1
|
||||
/* this uses remaining space in the first page after descriptors */
|
||||
#define ADSP_DW_SLOT_NUM_GDB (ADSP_DW_DESC_COUNT - 1)
|
||||
|
||||
struct adsp_debug_window {
|
||||
struct adsp_dw_desc descs[ADSP_DW_DESC_COUNT];
|
||||
uint8_t reserved[ADSP_DW_PAGE0_SLOT_OFFSET -
|
||||
@@ -108,4 +150,6 @@ struct adsp_debug_window {
|
||||
(sys_cache_uncached_ptr_get((__sparse_force void __sparse_cache *) \
|
||||
(WIN2_MBASE + WIN2_OFFSET))))
|
||||
|
||||
#endif /* CONFIG_INTEL_ADSP_DEBUG_SLOT_MANAGER */
|
||||
|
||||
#endif
|
||||
|
||||
@@ -20,12 +20,27 @@ LOG_MODULE_REGISTER(coredump, CONFIG_DEBUG_COREDUMP_LOG_LEVEL);
|
||||
static int error;
|
||||
static uint32_t mem_wptr;
|
||||
|
||||
#ifdef CONFIG_INTEL_ADSP_DEBUG_SLOT_MANAGER
|
||||
static void *coredump_slot_addr;
|
||||
#endif
|
||||
|
||||
static void coredump_mem_window_backend_start(void)
|
||||
{
|
||||
/* Reset error & mem write ptr */
|
||||
error = 0;
|
||||
mem_wptr = 0;
|
||||
#ifdef CONFIG_INTEL_ADSP_DEBUG_SLOT_MANAGER
|
||||
struct adsp_dw_desc slot_desc = { .type = ADSP_DW_SLOT_TELEMETRY, };
|
||||
|
||||
/* Forcibly take debug slot 1 */
|
||||
coredump_slot_addr = adsp_dw_seize_slot(1, &slot_desc, NULL);
|
||||
if (!coredump_slot_addr) {
|
||||
/* Try to get the first slot if slot 1 is not available as fallback */
|
||||
coredump_slot_addr = adsp_dw_seize_slot(0, &slot_desc, NULL);
|
||||
}
|
||||
#else
|
||||
ADSP_DW->descs[1].type = ADSP_DW_SLOT_TELEMETRY;
|
||||
#endif
|
||||
|
||||
while (LOG_PROCESS()) {
|
||||
;
|
||||
@@ -46,10 +61,20 @@ static void coredump_mem_window_backend_end(void)
|
||||
|
||||
static void coredump_mem_window_backend_buffer_output(uint8_t *buf, size_t buflen)
|
||||
{
|
||||
uint32_t *mem_window_separator = (uint32_t *)(ADSP_DW->slots[1]);
|
||||
uint8_t *mem_window_sink = (uint8_t *)(ADSP_DW->slots[1]) + 4 + mem_wptr;
|
||||
uint8_t *coredump_data = buf;
|
||||
size_t data_left;
|
||||
#ifdef CONFIG_INTEL_ADSP_DEBUG_SLOT_MANAGER
|
||||
uint32_t *mem_window_separator = (uint32_t *)coredump_slot_addr;
|
||||
uint8_t *mem_window_sink = (uint8_t *)coredump_slot_addr + 4 + mem_wptr;
|
||||
|
||||
if (!coredump_slot_addr) {
|
||||
return;
|
||||
}
|
||||
#else
|
||||
uint32_t *mem_window_separator = (uint32_t *)(ADSP_DW->slots[1]);
|
||||
uint8_t *mem_window_sink = (uint8_t *)(ADSP_DW->slots[1]) + 4 + mem_wptr;
|
||||
#endif
|
||||
|
||||
/* Default place for telemetry dump is in memory window. Each data is easily find using
|
||||
* separator. For telemetry that separator is 0x0DEC0DEB.
|
||||
*/
|
||||
|
||||
@@ -64,19 +64,41 @@ struct adsp_debug_slot {
|
||||
uint8_t data[ADSP_DW_SLOT_SIZE - sizeof(uint32_t) * 2];
|
||||
} __packed;
|
||||
|
||||
#ifdef CONFIG_INTEL_ADSP_DEBUG_SLOT_MANAGER
|
||||
static struct adsp_debug_slot *slot;
|
||||
#endif
|
||||
|
||||
static void mtrace_init(void)
|
||||
{
|
||||
#ifdef CONFIG_INTEL_ADSP_DEBUG_SLOT_MANAGER
|
||||
struct adsp_dw_desc slot_desc = { .type = MTRACE_LOGGING_SLOT_TYPE(MTRACE_CORE), };
|
||||
|
||||
if (slot) {
|
||||
return;
|
||||
}
|
||||
|
||||
slot = adsp_dw_request_slot(&slot_desc, NULL);
|
||||
#else
|
||||
if (ADSP_DW->descs[ADSP_DW_SLOT_NUM_MTRACE].type == MTRACE_LOGGING_SLOT_TYPE(MTRACE_CORE)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ADSP_DW->descs[ADSP_DW_SLOT_NUM_MTRACE].type = MTRACE_LOGGING_SLOT_TYPE(MTRACE_CORE);
|
||||
#endif
|
||||
}
|
||||
|
||||
static size_t mtrace_out(int8_t *str, size_t len, size_t *space_left)
|
||||
{
|
||||
#ifdef CONFIG_INTEL_ADSP_DEBUG_SLOT_MANAGER
|
||||
/* Debug slot is not allocated */
|
||||
if (!slot) {
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
struct adsp_debug_slot *slot = (struct adsp_debug_slot *)
|
||||
ADSP_DW->slots[ADSP_DW_SLOT_NUM_MTRACE];
|
||||
#endif
|
||||
|
||||
uint8_t *data = slot->data;
|
||||
uint32_t r = slot->host_ptr;
|
||||
uint32_t w = slot->dsp_ptr;
|
||||
|
||||
@@ -22,6 +22,10 @@ LOG_MODULE_REGISTER(shell_adsp_memory_window);
|
||||
|
||||
BUILD_ASSERT(RX_WINDOW_SIZE < ADSP_DW_SLOT_SIZE);
|
||||
|
||||
#ifdef CONFIG_INTEL_ADSP_DEBUG_SLOT_MANAGER
|
||||
static struct adsp_debug_slot_shell *dw_slot;
|
||||
#endif
|
||||
|
||||
struct adsp_debug_slot_shell {
|
||||
uint8_t rx_window[RX_WINDOW_SIZE];
|
||||
uint8_t tx_window[ADSP_DW_SLOT_SIZE - RX_WINDOW_SIZE];
|
||||
@@ -44,6 +48,15 @@ static int init(const struct shell_transport *transport,
|
||||
{
|
||||
struct shell_adsp_memory_window *sh_adsp_mw =
|
||||
(struct shell_adsp_memory_window *)transport->ctx;
|
||||
|
||||
#ifdef CONFIG_INTEL_ADSP_DEBUG_SLOT_MANAGER
|
||||
struct adsp_dw_desc slot_desc = { .type = ADSP_DW_SLOT_SHELL, };
|
||||
|
||||
dw_slot = (struct adsp_debug_slot_shell *)adsp_dw_request_slot(&slot_desc, NULL);
|
||||
if (!dw_slot) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
#else
|
||||
struct adsp_debug_slot_shell *dw_slot;
|
||||
|
||||
if (ADSP_DW->descs[ADSP_DW_SLOT_NUM_SHELL].type &&
|
||||
@@ -55,10 +68,12 @@ static int init(const struct shell_transport *transport,
|
||||
|
||||
ADSP_DW->descs[ADSP_DW_SLOT_NUM_SHELL].type = ADSP_DW->descs[ADSP_DW_SLOT_NUM_SHELL].type;
|
||||
|
||||
dw_slot = (struct adsp_debug_slot_shell *)ADSP_DW->slots[ADSP_DW_SLOT_NUM_SHELL];
|
||||
#endif
|
||||
|
||||
sh_adsp_mw->shell_handler = evt_handler;
|
||||
sh_adsp_mw->shell_context = context;
|
||||
|
||||
dw_slot = (struct adsp_debug_slot_shell *)ADSP_DW->slots[ADSP_DW_SLOT_NUM_SHELL];
|
||||
|
||||
sh_adsp_mw->ws_rx = sys_winstream_init(&dw_slot->rx_window[0], sizeof(dw_slot->rx_window));
|
||||
sh_adsp_mw->ws_tx = sys_winstream_init(&dw_slot->tx_window[0], sizeof(dw_slot->tx_window));
|
||||
@@ -80,6 +95,11 @@ static int uninit(const struct shell_transport *transport)
|
||||
|
||||
k_timer_stop(&sh_adsp_mw->timer);
|
||||
|
||||
#ifdef CONFIG_INTEL_ADSP_DEBUG_SLOT_MANAGER
|
||||
adsp_dw_release_slot(ADSP_DW_SLOT_SHELL);
|
||||
dw_slot = NULL;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,12 @@ static void tracing_backend_adsp_memory_window_output(
|
||||
const struct tracing_backend *backend,
|
||||
uint8_t *data, uint32_t length)
|
||||
{
|
||||
#ifdef CONFIG_INTEL_ADSP_DEBUG_SLOT_MANAGER
|
||||
if (!mem_window) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* copy data to ring buffer,
|
||||
* to make FW part fast, there's no sync with the data reader
|
||||
* the reader MUST read data before they got overwritten
|
||||
@@ -48,6 +54,15 @@ static void tracing_backend_adsp_memory_window_output(
|
||||
|
||||
static void tracing_backend_adsp_memory_window_init(void)
|
||||
{
|
||||
#ifdef CONFIG_INTEL_ADSP_DEBUG_SLOT_MANAGER
|
||||
struct adsp_dw_desc slot_desc = { .type = ADSP_DW_SLOT_TRACE, };
|
||||
|
||||
mem_window = (struct tracing_backend_adsp_memory_window *)adsp_dw_request_slot(&slot_desc,
|
||||
NULL);
|
||||
if (mem_window) {
|
||||
mem_window->head_offset = 0;
|
||||
}
|
||||
#else
|
||||
volatile struct adsp_debug_window *window = ADSP_DW;
|
||||
|
||||
window->descs[ADSP_DW_SLOT_NUM_TRACE].type = ADSP_DW_SLOT_TRACE;
|
||||
@@ -56,6 +71,7 @@ static void tracing_backend_adsp_memory_window_init(void)
|
||||
ADSP_DW->slots[ADSP_DW_SLOT_NUM_TRACE];
|
||||
|
||||
mem_window->head_offset = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
const struct tracing_backend_api tracing_backend_adsp_memory_window_api = {
|
||||
|
||||
Reference in New Issue
Block a user