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 struct adsp_debug_slot_shell {
26 uint8_t rx_window[RX_WINDOW_SIZE];
27 uint8_t tx_window[ADSP_DW_SLOT_SIZE - RX_WINDOW_SIZE];
28 } __packed;
29
timer_handler(struct k_timer * timer)30 static void timer_handler(struct k_timer *timer)
31 {
32 const struct shell_adsp_memory_window *sh_adsp_mw = k_timer_user_data_get(timer);
33
34 __ASSERT_NO_MSG(sh_adsp_mw->shell_handler && sh_adsp_mw->shell_context);
35
36 sh_adsp_mw->shell_handler(SHELL_TRANSPORT_EVT_RX_RDY,
37 sh_adsp_mw->shell_context);
38 }
39
init(const struct shell_transport * transport,const void * config,shell_transport_handler_t evt_handler,void * context)40 static int init(const struct shell_transport *transport,
41 const void *config,
42 shell_transport_handler_t evt_handler,
43 void *context)
44 {
45 struct shell_adsp_memory_window *sh_adsp_mw =
46 (struct shell_adsp_memory_window *)transport->ctx;
47 struct adsp_debug_slot_shell *dw_slot;
48
49 if (ADSP_DW->descs[ADSP_DW_SLOT_NUM_SHELL].type &&
50 (ADSP_DW->descs[ADSP_DW_SLOT_NUM_SHELL].type !=
51 ADSP_DW_SLOT_SHELL)) {
52 LOG_WRN("Possible conflict with debug window slot for shell, key %#x\n",
53 ADSP_DW->descs[ADSP_DW_SLOT_NUM_SHELL].type);
54 }
55
56 ADSP_DW->descs[ADSP_DW_SLOT_NUM_SHELL].type = ADSP_DW->descs[ADSP_DW_SLOT_NUM_SHELL].type;
57
58 sh_adsp_mw->shell_handler = evt_handler;
59 sh_adsp_mw->shell_context = context;
60
61 dw_slot = (struct adsp_debug_slot_shell *)ADSP_DW->slots[ADSP_DW_SLOT_NUM_SHELL];
62
63 sh_adsp_mw->ws_rx = sys_winstream_init(&dw_slot->rx_window[0], sizeof(dw_slot->rx_window));
64 sh_adsp_mw->ws_tx = sys_winstream_init(&dw_slot->tx_window[0], sizeof(dw_slot->tx_window));
65
66 LOG_DBG("shell with ADSP debug window rx/tx %u/%u\n",
67 sizeof(dw_slot->rx_window), sizeof(dw_slot->tx_window));
68
69 k_timer_init(&sh_adsp_mw->timer, timer_handler, NULL);
70 k_timer_user_data_set(&sh_adsp_mw->timer, (void *)sh_adsp_mw);
71 k_timer_start(&sh_adsp_mw->timer, POLL_INTERVAL, POLL_INTERVAL);
72
73 return 0;
74 }
75
uninit(const struct shell_transport * transport)76 static int uninit(const struct shell_transport *transport)
77 {
78 struct shell_adsp_memory_window *sh_adsp_mw =
79 (struct shell_adsp_memory_window *)transport->ctx;
80
81 k_timer_stop(&sh_adsp_mw->timer);
82
83 return 0;
84 }
85
enable(const struct shell_transport * transport,bool blocking)86 static int enable(const struct shell_transport *transport, bool blocking)
87 {
88 return 0;
89 }
90
write(const struct shell_transport * transport,const void * data,size_t length,size_t * cnt)91 static int write(const struct shell_transport *transport,
92 const void *data, size_t length, size_t *cnt)
93 {
94 struct shell_adsp_memory_window *sh_adsp_mw =
95 (struct shell_adsp_memory_window *)transport->ctx;
96
97 sys_winstream_write(sh_adsp_mw->ws_tx, data, length);
98 *cnt = length;
99
100 return 0;
101 }
102
read(const struct shell_transport * transport,void * data,size_t length,size_t * cnt)103 static int read(const struct shell_transport *transport,
104 void *data, size_t length, size_t *cnt)
105 {
106 struct shell_adsp_memory_window *sh_adsp_mw =
107 (struct shell_adsp_memory_window *)transport->ctx;
108 uint32_t res;
109
110 res = sys_winstream_read(sh_adsp_mw->ws_rx, &sh_adsp_mw->read_seqno, data, length);
111 *cnt = res;
112
113 return 0;
114 }
115
116 const struct shell_transport_api shell_adsp_memory_window_transport_api = {
117 .init = init,
118 .uninit = uninit,
119 .enable = enable,
120 .write = write,
121 .read = read
122 };
123
enable_shell_adsp_memory_window(void)124 static int enable_shell_adsp_memory_window(void)
125 {
126 bool log_backend = true;
127 uint32_t level = CONFIG_LOG_MAX_LEVEL;
128 static const struct shell_backend_config_flags cfg_flags =
129 SHELL_DEFAULT_BACKEND_CONFIG_FLAGS;
130
131 shell_init(&shell_adsp_memory_window, NULL, cfg_flags, log_backend, level);
132
133 return 0;
134 }
135 SYS_INIT(enable_shell_adsp_memory_window, POST_KERNEL, 0);
136
shell_backend_adsp_memory_window_get_ptr(void)137 const struct shell *shell_backend_adsp_memory_window_get_ptr(void)
138 {
139 return &shell_adsp_memory_window;
140 }
141