Skip to content

Commit fc26683

Browse files
committed
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 <[email protected]>
1 parent eaf7501 commit fc26683

File tree

9 files changed

+296
-11
lines changed

9 files changed

+296
-11
lines changed

soc/intel/intel_adsp/Kconfig

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,15 @@ config MEMORY_WIN_3_SIZE
8080

8181
This window is used for trace.
8282

83+
config INTEL_ADSP_DEBUG_SLOT_MANAGER
84+
bool "Debug slot manager"
85+
help
86+
If selected the debug slot allocation can be only done via
87+
the manager API, direct debug window access and tampering is
88+
forbidden.
89+
The API use allows dynamic slot allocation instead of static
90+
and error prone slot usage.
91+
8392
config ADSP_CLOCK
8493
bool
8594
help

soc/intel/intel_adsp/common/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ zephyr_library_sources(
2525

2626
zephyr_library_sources_ifdef(CONFIG_ADSP_CLOCK clk.c)
2727

28+
zephyr_library_sources_ifdef(CONFIG_INTEL_ADSP_DEBUG_SLOT_MANAGER
29+
debug_window.c
30+
)
31+
2832
if(CONFIG_SMP OR CONFIG_MP_MAX_NUM_CPUS GREATER 1)
2933
zephyr_library_sources(multiprocessing.c)
3034
endif()
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
/* Copyright(c) 2025 Intel Corporation. All rights reserved.
2+
* SPDX-License-Identifier: Apache-2.0
3+
*/
4+
5+
#include <adsp_memory.h>
6+
#include <adsp_debug_window.h>
7+
#include <zephyr/cache.h>
8+
9+
#include <zephyr/logging/log.h>
10+
LOG_MODULE_REGISTER(debug_window, CONFIG_SOC_LOG_LEVEL);
11+
12+
struct adsp_debug_window {
13+
struct adsp_dw_desc descs[ADSP_DW_DESC_COUNT];
14+
uint8_t reserved[ADSP_DW_PAGE0_SLOT_OFFSET -
15+
ADSP_DW_DESC_COUNT * sizeof(struct adsp_dw_desc)];
16+
uint8_t partial_page0[ADSP_DW_SLOT_SIZE - ADSP_DW_PAGE0_SLOT_OFFSET];
17+
uint8_t slots[ADSP_DW_SLOT_COUNT][ADSP_DW_SLOT_SIZE];
18+
} __packed;
19+
20+
#define WIN2_MBASE DT_REG_ADDR(DT_PHANDLE(DT_NODELABEL(mem_window2), memory))
21+
#define WIN2_SLOTS ((HP_SRAM_WIN2_SIZE / ADSP_DW_PAGE_SIZE) - 1)
22+
23+
#define ADSP_DW ((volatile struct adsp_debug_window *) \
24+
(sys_cache_uncached_ptr_get((__sparse_force void __sparse_cache *) \
25+
(WIN2_MBASE + WIN2_OFFSET))))
26+
27+
volatile void *adsp_dw_request_slot(struct adsp_dw_desc *dw_desc, size_t *slot_size)
28+
{
29+
int i;
30+
31+
if (!dw_desc->type) {
32+
return NULL;
33+
}
34+
35+
/*
36+
* Try to use partial slot if caller is prepared to handle it - slot_size pointer is
37+
* provided
38+
*/
39+
if (slot_size) {
40+
if (ADSP_DW->descs[ADSP_DW_SLOT_COUNT].type == ADSP_DW_SLOT_UNUSED ||
41+
ADSP_DW->descs[ADSP_DW_SLOT_COUNT].type == dw_desc->type) {
42+
i = ADSP_DW_SLOT_COUNT;
43+
goto found;
44+
}
45+
}
46+
47+
/* Look for an already allocated slot with the same type */
48+
for (i = 0; i < WIN2_SLOTS; i++) {
49+
if (ADSP_DW->descs[i].type == dw_desc->type) {
50+
break;
51+
}
52+
}
53+
if (i == WIN2_SLOTS) {
54+
/* Look for an empty full slot */
55+
for (i = 0; i < WIN2_SLOTS; i++) {
56+
if (ADSP_DW->descs[i].type == ADSP_DW_SLOT_UNUSED) {
57+
break;
58+
}
59+
}
60+
}
61+
62+
if (i == WIN2_SLOTS) {
63+
LOG_INF("No available slot for %#x", dw_desc->type);
64+
return NULL;
65+
}
66+
67+
found:
68+
ADSP_DW->descs[i].resource_id = dw_desc->resource_id;
69+
ADSP_DW->descs[i].type = dw_desc->type;
70+
ADSP_DW->descs[i].vma = dw_desc->vma;
71+
72+
if (slot_size) {
73+
*slot_size = ADSP_DW_SLOT_SIZE;
74+
}
75+
76+
if (i == ADSP_DW_SLOT_COUNT) {
77+
if (slot_size) {
78+
*slot_size -= ADSP_DW_PAGE0_SLOT_OFFSET;
79+
}
80+
81+
LOG_DBG("Allocating partial page0 to be used for %#x", dw_desc->type);
82+
83+
return ADSP_DW->partial_page0;
84+
}
85+
86+
LOG_DBG("Allocating debug slot %d to be used for %#x", i, dw_desc->type);
87+
88+
return ADSP_DW->slots[i];
89+
}
90+
91+
volatile void *adsp_dw_seize_slot(uint32_t slot_index, struct adsp_dw_desc *dw_desc,
92+
size_t *slot_size)
93+
{
94+
if ((slot_index >= WIN2_SLOTS && slot_index != ADSP_DW_SLOT_COUNT) || !dw_desc->type) {
95+
return NULL;
96+
}
97+
98+
if (slot_index < WIN2_SLOTS) {
99+
if (ADSP_DW->descs[slot_index].type != ADSP_DW_SLOT_UNUSED) {
100+
LOG_INF("Overtaking debug slot %d, used by %#x for %#x", slot_index,
101+
ADSP_DW->descs[slot_index].type, dw_desc->type);
102+
}
103+
104+
if (slot_size) {
105+
*slot_size = ADSP_DW_SLOT_SIZE;
106+
}
107+
108+
ADSP_DW->descs[slot_index].resource_id = dw_desc->resource_id;
109+
ADSP_DW->descs[slot_index].type = dw_desc->type;
110+
ADSP_DW->descs[slot_index].vma = dw_desc->vma;
111+
112+
return ADSP_DW->slots[slot_index];
113+
}
114+
115+
/* The caller is not prepared to handle partial debug slot */
116+
if (!slot_size) {
117+
return NULL;
118+
}
119+
120+
if (ADSP_DW->descs[slot_index].type != ADSP_DW_SLOT_UNUSED) {
121+
LOG_INF("Overtaking partial page0, used by %#x for %#x",
122+
ADSP_DW->descs[slot_index].type, dw_desc->type);
123+
}
124+
125+
*slot_size = ADSP_DW_SLOT_SIZE - ADSP_DW_PAGE0_SLOT_OFFSET;
126+
127+
ADSP_DW->descs[slot_index].resource_id = dw_desc->resource_id;
128+
ADSP_DW->descs[slot_index].type = dw_desc->type;
129+
ADSP_DW->descs[slot_index].vma = dw_desc->vma;
130+
131+
return ADSP_DW->partial_page0;
132+
}
133+
134+
void adsp_dw_release_slot(void *slot_address)
135+
{
136+
int i;
137+
138+
for (i = 0; i < WIN2_SLOTS; i++) {
139+
if (ADSP_DW->slots[i] == slot_address) {
140+
LOG_DBG("Releasing debug slot %d used by %#x", i, ADSP_DW->descs[i].type);
141+
goto found;
142+
}
143+
}
144+
145+
if (ADSP_DW->partial_page0 == slot_address) {
146+
i = ADSP_DW_SLOT_COUNT;
147+
LOG_DBG("Releasing partial page0 used by %#x", ADSP_DW->descs[i].type);
148+
goto found;
149+
}
150+
151+
return;
152+
153+
found:
154+
ADSP_DW->descs[i].resource_id = 0;
155+
ADSP_DW->descs[i].type = ADSP_DW_SLOT_UNUSED;
156+
ADSP_DW->descs[i].vma = 0;
157+
}

soc/intel/intel_adsp/common/gdbstub_backend_sram.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,18 +57,25 @@ static inline int ring_have_data(const volatile struct gdb_sram_ring *ring)
5757
return ring->head != ring->tail;
5858
}
5959

60+
#ifndef CONFIG_INTEL_ADSP_DEBUG_SLOT_MANAGER
6061
#define RX_UNCACHED (uint8_t *) (HP_SRAM_WIN2_BASE + SOF_GDB_WINDOW_OFFSET)
6162
#define TX_UNCACHED (uint8_t *) (RX_UNCACHED + sizeof(struct gdb_sram_ring))
63+
#endif
6264

6365
static volatile struct gdb_sram_ring *rx;
6466
static volatile struct gdb_sram_ring *tx;
6567

6668
void z_gdb_backend_init(void)
6769
{
70+
#ifdef CONFIG_INTEL_ADSP_DEBUG_SLOT_MANAGER
71+
__ASSERT_NO_MSG(rx && tx);
72+
#else
6873
__ASSERT_NO_MSG(sizeof(ADSP_DW->descs) <= SOF_GDB_WINDOW_OFFSET);
6974

7075
rx = sys_cache_uncached_ptr_get(RX_UNCACHED);
7176
tx = sys_cache_uncached_ptr_get(TX_UNCACHED);
77+
#endif
78+
7279
rx->head = rx->tail = 0;
7380
tx->head = tx->tail = 0;
7481
}
@@ -96,7 +103,24 @@ unsigned char z_gdb_getchar(void)
96103

97104
static int gdbstub_backend_sram_init(void)
98105
{
106+
#ifdef CONFIG_INTEL_ADSP_DEBUG_SLOT_MANAGER
107+
struct adsp_dw_desc slot_desc = { .type = ADSP_DW_SLOT_GDB_STUB, };
108+
size_t slot_size;
109+
char *slot_addr;
110+
111+
/* Force use the partial page0 slot */
112+
slot_addr = (char *)adsp_dw_request_slot(&slot_desc, &slot_size);
113+
114+
if (!slot_addr) {
115+
return -ENOMEM;
116+
}
117+
118+
rx = sys_cache_uncached_ptr_get(slot_addr);
119+
tx = sys_cache_uncached_ptr_get(slot_addr + sizeof(struct gdb_sram_ring));
120+
#else
99121
ADSP_DW->descs[ADSP_DW_SLOT_NUM_GDB].type = ADSP_DW_SLOT_GDB_STUB;
122+
#endif
123+
100124
return 0;
101125
}
102126

soc/intel/intel_adsp/common/include/adsp_debug_window.h

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -65,14 +65,6 @@
6565
#define ADSP_DW_PAGE0_SLOT_OFFSET 1024
6666
#define ADSP_DW_DESC_COUNT (ADSP_DW_SLOT_COUNT + 1)
6767

68-
/* debug window slots usage, mutually exclusive options can reuse slots */
69-
#define ADSP_DW_SLOT_NUM_SHELL 0
70-
#define ADSP_DW_SLOT_NUM_MTRACE 0
71-
#define ADSP_DW_SLOT_NUM_TRACE 1
72-
#define ADSP_DW_SLOT_NUM_TELEMETRY 1
73-
/* this uses remaining space in the first page after descriptors */
74-
#define ADSP_DW_SLOT_NUM_GDB (ADSP_DW_DESC_COUNT - 1)
75-
7668
/* debug log slot types */
7769
#define ADSP_DW_SLOT_UNUSED 0x00000000
7870
#define ADSP_DW_SLOT_CRITICAL_LOG 0x54524300
@@ -94,6 +86,21 @@ struct adsp_dw_desc {
9486
uint32_t vma;
9587
} __packed;
9688

89+
#ifdef CONFIG_INTEL_ADSP_DEBUG_SLOT_MANAGER
90+
volatile void *adsp_dw_request_slot(struct adsp_dw_desc *dw_desc, size_t *slot_size);
91+
volatile void *adsp_dw_seize_slot(uint32_t slot_index, struct adsp_dw_desc *dw_desc,
92+
size_t *slot_size);
93+
void adsp_dw_release_slot(void *slot_address);
94+
#else /* CONFIG_INTEL_ADSP_DEBUG_SLOT_MANAGER */
95+
96+
/* debug window slots usage, mutually exclusive options can reuse slots */
97+
#define ADSP_DW_SLOT_NUM_SHELL 0
98+
#define ADSP_DW_SLOT_NUM_MTRACE 0
99+
#define ADSP_DW_SLOT_NUM_TRACE 1
100+
#define ADSP_DW_SLOT_NUM_TELEMETRY 1
101+
/* this uses remaining space in the first page after descriptors */
102+
#define ADSP_DW_SLOT_NUM_GDB (ADSP_DW_DESC_COUNT - 1)
103+
97104
struct adsp_debug_window {
98105
struct adsp_dw_desc descs[ADSP_DW_DESC_COUNT];
99106
uint8_t reserved[ADSP_DW_PAGE0_SLOT_OFFSET -
@@ -108,4 +115,6 @@ struct adsp_debug_window {
108115
(sys_cache_uncached_ptr_get((__sparse_force void __sparse_cache *) \
109116
(WIN2_MBASE + WIN2_OFFSET))))
110117

118+
#endif /* CONFIG_INTEL_ADSP_DEBUG_SLOT_MANAGER */
119+
111120
#endif

subsys/debug/coredump/coredump_backend_intel_adsp_mem_window.c

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,27 @@ LOG_MODULE_REGISTER(coredump, CONFIG_DEBUG_COREDUMP_LOG_LEVEL);
2020
static int error;
2121
static uint32_t mem_wptr;
2222

23+
#ifdef CONFIG_INTEL_ADSP_DEBUG_SLOT_MANAGER
24+
static void *slot_addr;
25+
#endif
26+
2327
static void coredump_mem_window_backend_start(void)
2428
{
2529
/* Reset error & mem write ptr */
2630
error = 0;
2731
mem_wptr = 0;
32+
#ifdef CONFIG_INTEL_ADSP_DEBUG_SLOT_MANAGER
33+
struct adsp_dw_desc slot_desc = { .type = ADSP_DW_SLOT_TELEMETRY, };
34+
35+
/* Forcably take debug slot 1 */
36+
slot_addr = (void *)adsp_dw_seize_slot(1, &slot_desc, NULL);
37+
if (!slot_addr) {
38+
/* Try to get the first slot if slot 1 is not available as fallback */
39+
slot_addr = (void *)adsp_dw_seize_slot(0, &slot_desc, NULL);
40+
}
41+
#else
2842
ADSP_DW->descs[1].type = ADSP_DW_SLOT_TELEMETRY;
43+
#endif
2944

3045
while (LOG_PROCESS()) {
3146
;
@@ -46,10 +61,20 @@ static void coredump_mem_window_backend_end(void)
4661

4762
static void coredump_mem_window_backend_buffer_output(uint8_t *buf, size_t buflen)
4863
{
49-
uint32_t *mem_window_separator = (uint32_t *)(ADSP_DW->slots[1]);
50-
uint8_t *mem_window_sink = (uint8_t *)(ADSP_DW->slots[1]) + 4 + mem_wptr;
5164
uint8_t *coredump_data = buf;
5265
size_t data_left;
66+
#ifdef CONFIG_INTEL_ADSP_DEBUG_SLOT_MANAGER
67+
uint32_t *mem_window_separator = (uint32_t *)slot_addr;
68+
uint8_t *mem_window_sink = (uint8_t *)slot_addr + 4 + mem_wptr;
69+
70+
if (!slot_addr) {
71+
return;
72+
}
73+
#else
74+
uint32_t *mem_window_separator = (uint32_t *)(ADSP_DW->slots[1]);
75+
uint8_t *mem_window_sink = (uint8_t *)(ADSP_DW->slots[1]) + 4 + mem_wptr;
76+
#endif
77+
5378
/* Default place for telemetry dump is in memory window. Each data is easily find using
5479
* separator. For telemetry that separator is 0x0DEC0DEB.
5580
*/

subsys/logging/backends/log_backend_adsp_mtrace.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,19 +64,41 @@ struct adsp_debug_slot {
6464
uint8_t data[ADSP_DW_SLOT_SIZE - sizeof(uint32_t) * 2];
6565
} __packed;
6666

67+
#ifdef CONFIG_INTEL_ADSP_DEBUG_SLOT_MANAGER
68+
static struct adsp_debug_slot *slot;
69+
#endif
70+
6771
static void mtrace_init(void)
6872
{
73+
#ifdef CONFIG_INTEL_ADSP_DEBUG_SLOT_MANAGER
74+
struct adsp_dw_desc slot_desc = { .type = MTRACE_LOGGING_SLOT_TYPE(MTRACE_CORE), };
75+
76+
if (slot) {
77+
return;
78+
}
79+
80+
slot = (struct adsp_debug_slot *)adsp_dw_request_slot(&slot_desc, NULL);
81+
#else
6982
if (ADSP_DW->descs[ADSP_DW_SLOT_NUM_MTRACE].type == MTRACE_LOGGING_SLOT_TYPE(MTRACE_CORE)) {
7083
return;
7184
}
7285

7386
ADSP_DW->descs[ADSP_DW_SLOT_NUM_MTRACE].type = MTRACE_LOGGING_SLOT_TYPE(MTRACE_CORE);
87+
#endif
7488
}
7589

7690
static size_t mtrace_out(int8_t *str, size_t len, size_t *space_left)
7791
{
92+
#ifdef CONFIG_INTEL_ADSP_DEBUG_SLOT_MANAGER
93+
/* Debug slot is not allocated */
94+
if (!slot) {
95+
return 0;
96+
}
97+
#else
7898
struct adsp_debug_slot *slot = (struct adsp_debug_slot *)
7999
ADSP_DW->slots[ADSP_DW_SLOT_NUM_MTRACE];
100+
#endif
101+
80102
uint8_t *data = slot->data;
81103
uint32_t r = slot->host_ptr;
82104
uint32_t w = slot->dsp_ptr;

0 commit comments

Comments
 (0)