1 /*
2 * Copyright (C) 2022 Beken Corporation
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <stdlib.h>
17 #include "sys_rtos.h"
18 #include <os/os.h>
19 #include <common/bk_kernel_err.h>
20
21 #include "bk_cli.h"
22 #include "stdarg.h"
23 #include <common/bk_include.h>
24 #include <os/mem.h>
25 #include <os/str.h>
26 #include "bk_phy.h"
27 #include "cli.h"
28 #include "cli_config.h"
29 #include <components/log.h>
30 #include <driver/uart.h>
31 #include "bk_rtos_debug.h"
32 #if CONFIG_SHELL_ASYNCLOG
33 #include "components/shell_task.h"
34 #endif
35 #include "bk_api_cli.h"
36 #include "boot.h"
37
38 static void debug_help_command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv);
39
40 #if CONFIG_DUAL_CORE
41 #include "mb_ipc_cmd.h"
42 #include <driver/gpio.h>
43
44 #include "amp_lock_api.h"
45
46 static void debug_ipc_command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv);
47 static void debug_rpc_command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv);
48 static void debug_rpc_gpio_command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv);
49 static void debug_cpulock_command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv);
50
51 static u8 ipc_inited = 0;
52 static u8 rpc_inited = 0;
53
54 #endif
55
56 #if CONFIG_ARCH_RISCV
57 static void debug_perfmon_command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv);
58 static void debug_show_boot_time(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv);
59 #endif
60
61 const struct cli_command debug_cmds[] = {
62 {"help", "list debug cmds", debug_help_command},
63 #if CONFIG_DUAL_CORE
64 {"ipc", "ipc", debug_ipc_command},
65 {"rpc", "rpc", debug_rpc_command},
66 {"gpio_out", "gpio_out gpio_id {0|1}", debug_rpc_gpio_command},
67 {"cpu_lock", "cpu_lock [timeout 1~20]", debug_cpulock_command},
68 #endif
69
70 #if CONFIG_ARCH_RISCV
71 {"perfmon", "perfmon(calc MIPS)", debug_perfmon_command},
72 {"boottime", "boottime(show boot mtime info)", debug_show_boot_time},
73 #endif
74 };
75
76 const int cli_debug_table_size = ARRAY_SIZE(debug_cmds);
77
print_cmd_table(const struct cli_command * cmd_table,int table_items)78 void print_cmd_table(const struct cli_command *cmd_table, int table_items)
79 {
80 int i;
81
82 for (i = 0; i < table_items; i++)
83 {
84 if (cmd_table[i].name)
85 {
86 if (cmd_table[i].help)
87 os_printf("%s: %s\r\n", cmd_table[i].name, cmd_table[i].help);
88 else
89 os_printf("%s\r\n", cmd_table[i].name);
90 }
91 }
92 }
93
print_cmd_help(const struct cli_command * cmd_table,int table_items,void * func)94 void print_cmd_help(const struct cli_command *cmd_table, int table_items, void *func)
95 {
96 int i;
97
98 for (i = 0; i < table_items; i++)
99 {
100 if(cmd_table[i].function == func)
101 {
102 if (cmd_table[i].help)
103 os_printf("%s\r\n", cmd_table[i].help);
104
105 break;
106 }
107 }
108 }
109
debug_help_command(char * pcWriteBuffer,int xWriteBufferLen,int argc,char ** argv)110 static void debug_help_command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
111 {
112 os_printf("====Debug Commands====\r\n");
113
114 print_cmd_table(debug_cmds, ARRAY_SIZE(debug_cmds));
115 }
116
117 #if CONFIG_DUAL_CORE
print_debug_cmd_help(void * func)118 static void print_debug_cmd_help(void *func)
119 {
120 print_cmd_help(debug_cmds, ARRAY_SIZE(debug_cmds), func);
121 }
122
debug_rpc_command(char * pcWriteBuffer,int xWriteBufferLen,int argc,char ** argv)123 static void debug_rpc_command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
124 {
125 int ret_val;
126
127 if(rpc_inited)
128 {
129 os_printf("rpc started\r\n");
130 return;
131 }
132
133 ret_val = rpc_init();
134 os_printf("rpc init: %d\r\n", ret_val);
135 rpc_inited = 1;
136
137 #if CONFIG_MASTER_CORE
138
139 if(ipc_inited)
140 {
141 ret_val = ipc_send_test_cmd(0x12);
142 os_printf("ipc server test: ret=%d\r\n", ret_val);
143
144 ret_val = ipc_send_get_ps_flag();
145 os_printf("ipc server ps: ret= 0x%x\r\n", ret_val);
146
147 ret_val = ipc_send_get_heart_rate();
148 os_printf("ipc server hr: ret= 0x%x\r\n", ret_val);
149
150 ret_val = ipc_send_set_heart_rate(0x33);
151 os_printf("ipc server set hr: ret= %d\r\n", ret_val);
152 }
153
154 #endif
155
156 }
157
debug_ipc_command(char * pcWriteBuffer,int xWriteBufferLen,int argc,char ** argv)158 static void debug_ipc_command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
159 {
160 int ret_val;
161
162 if(ipc_inited)
163 {
164 os_printf("ipc started\r\n");
165 return;
166 }
167
168 ret_val = ipc_init();
169 os_printf("ipc init: %d\r\n", ret_val);
170 ipc_inited = 1;
171
172 #if CONFIG_SLAVE_CORE
173
174 ret_val = ipc_send_power_up();
175 os_printf("ipc client power: %d\r\n", ret_val);
176
177 ret_val = ipc_send_heart_beat(0x34);
178 os_printf("ipc client heartbeat: %d\r\n", ret_val);
179
180 ret_val = ipc_send_test_cmd(0x12);
181 os_printf("ipc client test: %d\r\n", ret_val);
182
183 #endif
184 }
185
186 extern bk_err_t bk_gpio_enable_output_rpc(gpio_id_t gpio_id);
187 extern bk_err_t bk_gpio_set_output_high_rpc(gpio_id_t gpio_id);
188 extern bk_err_t bk_gpio_set_output_low_rpc(gpio_id_t gpio_id);
189
debug_rpc_gpio_command(char * pcWriteBuffer,int xWriteBufferLen,int argc,char ** argv)190 static void debug_rpc_gpio_command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
191 {
192 #if CONFIG_SLAVE_CORE
193
194 int ret_val;
195
196 u32 gpio_id = 0;
197 u32 level = 0;
198
199 if (argc < 3)
200 {
201 print_debug_cmd_help(debug_rpc_gpio_command);
202 return;
203 }
204
205 gpio_id = strtoul(argv[1], NULL, 0);
206 level = strtoul(argv[2], NULL, 0);
207
208 ret_val = bk_gpio_enable_output_rpc(gpio_id);
209 os_printf("rpc gpio:ret=%d\r\n", ret_val);
210
211 if(level)
212 ret_val = bk_gpio_set_output_high_rpc(gpio_id);
213 else
214 ret_val = bk_gpio_set_output_low_rpc(gpio_id);
215
216 os_printf("rpc gpio:ret=%d\r\n", ret_val);
217
218 #endif
219
220 }
221
debug_cpulock_command(char * pcWriteBuffer,int xWriteBufferLen,int argc,char ** argv)222 static void debug_cpulock_command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
223 {
224 u32 timeout_second = 10; // 10s
225
226 if(ipc_inited == 0)
227 {
228 os_printf("Failed: no ipc client/server in CPU0/CPU1.\r\n");
229 return;
230 }
231
232 if (argc > 1)
233 {
234 timeout_second = strtoul(argv[1], NULL, 0);
235
236 if(timeout_second > 20)
237 timeout_second = 20;
238 if(timeout_second == 0)
239 timeout_second = 10;
240 }
241 else
242 {
243 print_debug_cmd_help(debug_cpulock_command);
244 os_printf("default timeout 10s is used.\r\n");
245 }
246
247 int ret_val = BK_FAIL;
248
249 ret_val = amp_res_init(AMP_RES_ID_GPIO);
250 os_printf("amp res init:ret=%d\r\n", ret_val);
251
252 ret_val = amp_res_acquire(AMP_RES_ID_GPIO, timeout_second * 1000);
253 os_printf("amp res acquire:ret=%d\r\n", ret_val);
254
255 rtos_delay_milliseconds(timeout_second * 1000);
256
257 if(ret_val == 0)
258 {
259 ret_val = amp_res_release(AMP_RES_ID_GPIO);
260 os_printf("amp res release:ret=%d\r\n", ret_val);
261 }
262 else
263 {
264 os_printf("amp res release: no release\r\n");
265 }
266
267 }
268 #endif
269
cli_debug_cmd_table(int * num)270 const struct cli_command * cli_debug_cmd_table(int *num)
271 {
272 *num = ARRAY_SIZE(debug_cmds);
273
274 return &debug_cmds[0];
275 }
276
277 #if CONFIG_ARCH_RISCV
278
279 extern u64 riscv_get_instruct_cnt(void);
280 extern u64 riscv_get_mtimer(void);
281
282 static u64 saved_time = 0;
283 static u64 saved_inst_cnt = 0;
284
debug_perfmon_command(char * pcWriteBuffer,int xWriteBufferLen,int argc,char ** argv)285 static void debug_perfmon_command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
286 {
287 u64 cur_time = riscv_get_mtimer();
288 u64 cur_inst_cnt = riscv_get_instruct_cnt();
289
290 os_printf("cur time: %x:%08x\r\n", (u32)(cur_time >> 32), (u32)(cur_time & 0xFFFFFFFF));
291 os_printf("cur inst_cnt: %x:%08x\r\n", (u32)(cur_inst_cnt >> 32), (u32)(cur_inst_cnt & 0xFFFFFFFF));
292
293 saved_time = (cur_time - saved_time) / 26;
294 saved_inst_cnt = cur_inst_cnt - saved_inst_cnt;
295
296 // os_printf("elapse time(us): %x:%08x\r\n", (u32)(saved_time >> 32), (u32)(saved_time & 0xFFFFFFFF));
297 // os_printf("diff inst_cnt: %x:%08x\r\n", (u32)(saved_inst_cnt >> 32), (u32)(saved_inst_cnt & 0xFFFFFFFF));
298
299 os_printf("MIPS: %d KIPS\r\n", (u32)(saved_inst_cnt * 1000 / saved_time));
300
301 saved_time = cur_time;
302 saved_inst_cnt = cur_inst_cnt;
303 }
304
305
debug_show_boot_time(char * pcWriteBuffer,int xWriteBufferLen,int argc,char ** argv)306 static void debug_show_boot_time(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
307 {
308 u64 cur_time = riscv_get_mtimer();
309 u64 cur_inst_cnt = riscv_get_instruct_cnt();
310
311 BK_LOGI("debug","cur time: %x:%08x\r\n", (u32)(cur_time >> 32), (u32)(cur_time & 0xFFFFFFFF));
312 BK_LOGI("debug","cur time: %ldms\r\n", (u32)(cur_time/26000));
313 BK_LOGI("debug","cur inst_cnt: %x:%08x\r\n", (u32)(cur_inst_cnt >> 32), (u32)(cur_inst_cnt & 0xFFFFFFFF));
314
315 #if CONFIG_SAVE_BOOT_TIME_POINT
316 show_saved_mtime_info();
317 #endif
318
319 }
320 #endif
321
322