1 /*
2 * Copyright (c) 2024 Intel Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/shell/shell_adsp_memory_window.h>
8 #include <zephyr/sys/winstream.h>
9 #include <zephyr/logging/log.h>
10
11 #include <adsp_memory.h>
12 #include <adsp_debug_window.h>
13
14 SHELL_ADSP_MEMORY_WINDOW_DEFINE(shell_transport_adsp_memory_window);
15 SHELL_DEFINE(shell_adsp_memory_window, CONFIG_SHELL_BACKEND_ADSP_MEMORY_WINDOW_PROMPT,
16 &shell_transport_adsp_memory_window, 256, 0, SHELL_FLAG_OLF_CRLF);
17
18 LOG_MODULE_REGISTER(shell_adsp_memory_window);
19
20 #define RX_WINDOW_SIZE 256
21 #define POLL_INTERVAL K_MSEC(CONFIG_SHELL_BACKEND_ADSP_MEMORY_WINDOW_POLL_INTERVAL)
22
23 BUILD_ASSERT(RX_WINDOW_SIZE < ADSP_DW_SLOT_SIZE);
24
25 #ifdef CONFIG_INTEL_ADSP_DEBUG_SLOT_MANAGER
26 static struct adsp_debug_slot_shell *dw_slot;
27 #endif
28
29 struct adsp_debug_slot_shell {
30 uint8_t rx_window[RX_WINDOW_SIZE];
31 uint8_t tx_window[ADSP_DW_SLOT_SIZE - RX_WINDOW_SIZE];
32 } __packed;
33
timer_handler(struct k_timer * timer)34 static void timer_handler(struct k_timer *timer)
35 {
36 const struct shell_adsp_memory_window *sh_adsp_mw = k_timer_user_data_get(timer);
37
38 __ASSERT_NO_MSG(sh_adsp_mw->shell_handler && sh_adsp_mw->shell_context);
39
40 sh_adsp_mw->shell_handler(SHELL_TRANSPORT_EVT_RX_RDY,
41 sh_adsp_mw->shell_context);
42 }
43
init(const struct shell_transport * transport,const void * config,shell_transport_handler_t evt_handler,void * context)44 static int init(const struct shell_transport *transport,
45 const void *config,
46 shell_transport_handler_t evt_handler,
47 void *context)
48 {
49 struct shell_adsp_memory_window *sh_adsp_mw =
50 (struct shell_adsp_memory_window *)transport->ctx;
51
52 #ifdef CONFIG_INTEL_ADSP_DEBUG_SLOT_MANAGER
53 struct adsp_dw_desc slot_desc = { .type = ADSP_DW_SLOT_SHELL, };
54
55 dw_slot = (struct adsp_debug_slot_shell *)adsp_dw_request_slot(&slot_desc, NULL);
56 if (!dw_slot) {
57 return -ENOTSUP;
58 }
59 #else
60 struct adsp_debug_slot_shell *dw_slot;
61
62 if (ADSP_DW->descs[ADSP_DW_SLOT_NUM_SHELL].type &&
63 (ADSP_DW->descs[ADSP_DW_SLOT_NUM_SHELL].type !=
64 ADSP_DW_SLOT_SHELL)) {
65 LOG_WRN("Possible conflict with debug window slot for shell, key %#x\n",
66 ADSP_DW->descs[ADSP_DW_SLOT_NUM_SHELL].type);
67 }
68
69 ADSP_DW->descs[ADSP_DW_SLOT_NUM_SHELL].type = ADSP_DW->descs[ADSP_DW_SLOT_NUM_SHELL].type;
70
71 dw_slot = (struct adsp_debug_slot_shell *)ADSP_DW->slots[ADSP_DW_SLOT_NUM_SHELL];
72 #endif
73
74 sh_adsp_mw->shell_handler = evt_handler;
75 sh_adsp_mw->shell_context = context;
76
77
78 sh_adsp_mw->ws_rx = sys_winstream_init(&dw_slot->rx_window[0], sizeof(dw_slot->rx_window));
79 sh_adsp_mw->ws_tx = sys_winstream_init(&dw_slot->tx_window[0], sizeof(dw_slot->tx_window));
80
81 LOG_DBG("shell with ADSP debug window rx/tx %u/%u\n",
82 sizeof(dw_slot->rx_window), sizeof(dw_slot->tx_window));
83
84 k_timer_init(&sh_adsp_mw->timer, timer_handler, NULL);
85 k_timer_user_data_set(&sh_adsp_mw->timer, (void *)sh_adsp_mw);
86 k_timer_start(&sh_adsp_mw->timer, POLL_INTERVAL, POLL_INTERVAL);
87
88 return 0;
89 }
90
uninit(const struct shell_transport * transport)91 static int uninit(const struct shell_transport *transport)
92 {
93 struct shell_adsp_memory_window *sh_adsp_mw =
94 (struct shell_adsp_memory_window *)transport->ctx;
95
96 k_timer_stop(&sh_adsp_mw->timer);
97
98 #ifdef CONFIG_INTEL_ADSP_DEBUG_SLOT_MANAGER
99 adsp_dw_release_slot(ADSP_DW_SLOT_SHELL);
100 dw_slot = NULL;
101 #endif
102
103 return 0;
104 }
105
enable(const struct shell_transport * transport,bool blocking)106 static int enable(const struct shell_transport *transport, bool blocking)
107 {
108 return 0;
109 }
110
write(const struct shell_transport * transport,const void * data,size_t length,size_t * cnt)111 static int write(const struct shell_transport *transport,
112 const void *data, size_t length, size_t *cnt)
113 {
114 struct shell_adsp_memory_window *sh_adsp_mw =
115 (struct shell_adsp_memory_window *)transport->ctx;
116
117 sys_winstream_write(sh_adsp_mw->ws_tx, data, length);
118 *cnt = length;
119
120 return 0;
121 }
122
read(const struct shell_transport * transport,void * data,size_t length,size_t * cnt)123 static int read(const struct shell_transport *transport,
124 void *data, size_t length, size_t *cnt)
125 {
126 struct shell_adsp_memory_window *sh_adsp_mw =
127 (struct shell_adsp_memory_window *)transport->ctx;
128 uint32_t res;
129
130 res = sys_winstream_read(sh_adsp_mw->ws_rx, &sh_adsp_mw->read_seqno, data, length);
131 *cnt = res;
132
133 return 0;
134 }
135
136 const struct shell_transport_api shell_adsp_memory_window_transport_api = {
137 .init = init,
138 .uninit = uninit,
139 .enable = enable,
140 .write = write,
141 .read = read
142 };
143
enable_shell_adsp_memory_window(void)144 static int enable_shell_adsp_memory_window(void)
145 {
146 bool log_backend = true;
147 uint32_t level = CONFIG_LOG_MAX_LEVEL;
148 static const struct shell_backend_config_flags cfg_flags =
149 SHELL_DEFAULT_BACKEND_CONFIG_FLAGS;
150
151 shell_init(&shell_adsp_memory_window, NULL, cfg_flags, log_backend, level);
152
153 return 0;
154 }
155 SYS_INIT(enable_shell_adsp_memory_window, POST_KERNEL, 0);
156
shell_backend_adsp_memory_window_get_ptr(void)157 const struct shell *shell_backend_adsp_memory_window_get_ptr(void)
158 {
159 return &shell_adsp_memory_window;
160 }
161