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 "cli.h"
18 #include "driver/flash.h"
19 #include <driver/flash_partition.h>
20 #include "sys_driver.h"
21 #include "flash_bypass.h"
22 #include "flash.h"
23 #include <driver/psram.h>
24
25 #define TICK_PER_US 26
26 beken_thread_t idle_read_flash_handle = NULL;
27 beken_thread_t idle_read_psram_handle = NULL;
28 extern void delay_ms(UINT32 ms_count);
29
test_flash_write(volatile uint32_t start_addr,uint32_t len)30 static bk_err_t test_flash_write(volatile uint32_t start_addr, uint32_t len)
31 {
32 uint32_t i;
33 u8 buf[256];
34 uint32_t addr = start_addr;
35 uint32_t length = len;
36 uint32_t tmp = addr + length;
37
38 for (i = 0; i < 256; i++)
39 buf[i] = i;
40
41 for (; addr < tmp; addr += 256) {
42 os_printf("write addr(size:256):%d\r\n", addr);
43 bk_flash_write_bytes(addr, (uint8_t *)buf, 256);
44 }
45
46 return kNoErr;
47 }
48
test_flash_erase(volatile uint32_t start_addr,uint32_t len)49 static bk_err_t test_flash_erase(volatile uint32_t start_addr, uint32_t len)
50 {
51 uint32_t addr = start_addr;
52 uint32_t length = len;
53 uint32_t tmp = addr + length;
54
55 for (; addr < tmp; addr += 0x1000) {
56 os_printf("erase addr:%d\r\n", addr);
57 bk_flash_erase_sector(addr);
58 }
59 return kNoErr;
60 }
61
test_flash_read(volatile uint32_t start_addr,uint32_t len)62 static bk_err_t test_flash_read(volatile uint32_t start_addr, uint32_t len)
63 {
64 uint32_t i, j, tmp;
65 u8 buf[256];
66 uint32_t addr = start_addr;
67 uint32_t length = len;
68 tmp = addr + length;
69
70 for (; addr < tmp; addr += 256) {
71 os_memset(buf, 0, 256);
72 bk_flash_read_bytes(addr, (uint8_t *)buf, 256);
73 os_printf("read addr:%x\r\n", addr);
74 for (i = 0; i < 16; i++) {
75 for (j = 0; j < 16; j++)
76 os_printf("%02x ", buf[i * 16 + j]);
77 os_printf("\r\n");
78 }
79 }
80
81 return kNoErr;
82 }
83
test_flash_read_without_print(volatile uint32_t start_addr,uint32_t len)84 static bk_err_t test_flash_read_without_print(volatile uint32_t start_addr, uint32_t len)
85 {
86 uint32_t tmp;
87 u8 buf[256];
88 uint32_t addr = start_addr;
89 uint32_t length = len;
90 tmp = addr + length;
91
92 for (; addr < tmp; addr += 256) {
93 os_memset(buf, 0, 256);
94 bk_flash_read_bytes(addr, (uint8_t *)buf, 256);
95 }
96
97 return kNoErr;
98 }
99
test_flash_read_time(volatile uint32_t start_addr,uint32_t len)100 static bk_err_t test_flash_read_time(volatile uint32_t start_addr, uint32_t len)
101 {
102 UINT32 time_start, time_end;
103 uint32_t tmp;
104 u8 buf[256];
105 uint32_t addr = start_addr;
106 uint32_t length = len;
107
108 tmp = addr + length;
109 beken_time_get_time((beken_time_t *)&time_start);
110 os_printf("read time start:%d\r\n", time_start);
111
112 for (; addr < tmp; addr += 256) {
113 os_memset(buf, 0, 256);
114 bk_flash_read_bytes(addr, (uint8_t *)buf, 256);
115 }
116 beken_time_get_time((beken_time_t *)&time_end);
117 os_printf("read time end:%d\r\n", time_end);
118 os_printf("cost time:%d\r\n", time_end - time_start);
119
120 return kNoErr;
121 }
122
123 #if (CONFIG_SYSTEM_CTRL)
test_flash_count_time(volatile uint32_t start_addr,uint32_t len,uint32_t test_times)124 static bk_err_t test_flash_count_time(volatile uint32_t start_addr, uint32_t len, uint32_t test_times)
125 {
126 UINT32 time_start, time_end;
127 uint32_t tmp;
128 u8 buf[256];
129 uint32_t addr = start_addr;
130 uint32_t length = len;
131 extern u64 riscv_get_mtimer(void);
132 uint64_t start_tick, end_tick, tick_cnt = 0;
133
134 tmp = addr + length;
135 bk_flash_set_protect_type(FLASH_PROTECT_NONE);
136
137 beken_time_get_time((beken_time_t *)&time_start);
138 os_printf("----- FLASH COUNT TIME TEST BEGIN: start time:%d ms -----\r\n", time_start);
139 os_printf("===============================\r\n");
140
141 start_tick = riscv_get_mtimer();
142 for (addr = start_addr; addr < tmp; addr += 256) {
143 os_memset(buf, 0, 256);
144 bk_flash_read_bytes(addr, (uint8_t *)buf, 256);
145 }
146 end_tick = riscv_get_mtimer();
147 tick_cnt = end_tick - start_tick;
148 os_printf("[read 1 time] >>>>> cost tick time: %d us.\r\n", (uint32_t) (tick_cnt / TICK_PER_US));
149 os_printf("===============================\r\n");
150
151
152 start_tick = riscv_get_mtimer();
153 for (int i = 0; i < test_times; i++ ) {
154 for (addr = start_addr; addr < tmp; addr += 256) {
155 os_memset(buf, 0, 256);
156 bk_flash_read_bytes(addr, (uint8_t *)buf, 256);
157 }
158 }
159 end_tick = riscv_get_mtimer();
160 tick_cnt = end_tick - start_tick;
161 os_printf("[read %d time] >>>>> average tick time: %d us.\r\n", test_times, (uint32_t) (tick_cnt / TICK_PER_US / test_times));
162 os_printf("===============================\r\n");
163
164
165 start_tick = riscv_get_mtimer();
166 for (addr = start_addr; addr < tmp; addr += 0x1000) {
167 os_printf("erase addr:%d\r\n", addr);
168 bk_flash_erase_sector(addr);
169 }
170 end_tick = riscv_get_mtimer();
171 tick_cnt = end_tick - start_tick;
172 os_printf("[erase 1 time] >>>>> cost tick time: %d us.\r\n", (uint32_t) (tick_cnt / TICK_PER_US));
173 os_printf("===============================\r\n");
174
175
176 start_tick = riscv_get_mtimer();
177 for (int i = 0; i < test_times; i++ ) {
178 for (addr = start_addr; addr < tmp; addr += 0x1000) {
179 bk_flash_erase_sector(addr);
180 }
181 }
182 end_tick = riscv_get_mtimer();
183 tick_cnt = end_tick - start_tick;
184 os_printf("[erase %d time] >>>>> average tick time: %d us.\r\n", test_times, (uint32_t) (tick_cnt / TICK_PER_US / test_times));
185 os_printf("===============================\r\n");
186
187
188 start_tick = riscv_get_mtimer();
189 for (int i = 0; i < 256; i++)
190 buf[i] = i;
191
192 for (addr = start_addr; addr < tmp; addr += 256) {
193 bk_flash_write_bytes(addr, (uint8_t *)buf, 256);
194 }
195 end_tick = riscv_get_mtimer();
196 tick_cnt = end_tick - start_tick;
197 os_printf("[write 1 time] >>>>> cost tick time: %d us.\r\n", (uint32_t) (tick_cnt / TICK_PER_US));
198 os_printf("===============================\r\n");
199
200
201 start_tick = riscv_get_mtimer();
202 for (int i = 0; i < test_times; i++ ) {
203 for (addr = start_addr; addr < tmp; addr += 256) {
204 bk_flash_write_bytes(addr, (uint8_t *)buf, 256);
205 }
206 }
207 end_tick = riscv_get_mtimer();
208 tick_cnt = end_tick - start_tick;
209 os_printf("[write %d time] >>>>> average tick time: %d us.\r\n", test_times, (uint32_t) (tick_cnt / TICK_PER_US / test_times));
210 os_printf("===============================\r\n");
211
212
213 start_tick = riscv_get_mtimer();
214 bk_flash_set_protect_type(FLASH_PROTECT_NONE);
215 end_tick = riscv_get_mtimer();
216 tick_cnt = end_tick - start_tick;
217 os_printf("[enable security 1 time] >>>>> cost tick time: %d us.\r\n", (uint32_t)(tick_cnt / TICK_PER_US));
218 os_printf("===============================\r\n");
219
220
221 start_tick = riscv_get_mtimer();
222 for (int i = 0; i < test_times; i++ ) {
223 bk_flash_set_protect_type(FLASH_PROTECT_NONE);
224 }
225 end_tick = riscv_get_mtimer();
226 tick_cnt = end_tick - start_tick;
227 os_printf("[enable security %d time] >>>>> average tick time: %d us.\r\n", test_times, (uint32_t)(tick_cnt / TICK_PER_US / test_times));
228 os_printf("===============================\r\n");
229
230
231 start_tick = riscv_get_mtimer();
232 bk_flash_set_protect_type(FLASH_PROTECT_NONE);
233 bk_flash_set_protect_type(FLASH_UNPROTECT_LAST_BLOCK);
234 end_tick = riscv_get_mtimer();
235 tick_cnt = end_tick - start_tick;
236 os_printf("[en/dis security 1 time] >>>>> cost tick time: %d us.\r\n", (uint32_t) ((tick_cnt / TICK_PER_US)));
237 os_printf("===============================\r\n");
238
239
240 beken_time_get_time((beken_time_t *)&time_end);
241 os_printf("----- FLASH COUNT TIME TEST END: end time:%d ms -----\r\n", time_end);
242 os_printf("----- OVERALL TEST TIME:%d ms -----\r\n", time_end - time_start);
243
244 bk_flash_set_protect_type(FLASH_UNPROTECT_LAST_BLOCK);
245 return kNoErr;
246 }
247 #endif
248
test_idle_read_flash(void * arg)249 static void test_idle_read_flash(void *arg) {
250 while (1) {
251 test_flash_read_without_print(0x1000, 1000);
252 test_flash_read_without_print(0x100000, 1000);
253 test_flash_read_without_print(0x200000, 1000);
254 test_flash_read_without_print(0x300000, 0x1000);
255 }
256 rtos_delete_thread(&idle_read_flash_handle);
257 }
258
259 #define write_data(addr,val) *((volatile unsigned long *)(addr)) = val
260 #define read_data(addr,val) val = *((volatile unsigned long *)(addr))
261 #define get_addr_data(addr) *((volatile unsigned long *)(addr))
262
263 #if (CONFIG_SYSTEM_CTRL && CONFIG_PSRAM)
test_idle_read_psram(void * arg)264 static void test_idle_read_psram(void *arg) {
265 uint32_t i,val = 0;
266 uint32_t s0 = 0;
267 uint32_t s1 = 0;
268 uint32_t s2 = 0;
269 uint32_t s3 = 0;
270
271 os_printf("enter test_idle_read_psram\r\n");
272
273 bk_psram_init();
274
275 while (1) {
276 for(i=0;i<1024;i++){
277 write_data((0x60000000+i*0x4),0x11+i);
278 write_data((0x60001000+i*0x4),0x22+i);
279 write_data((0x60002000+i*0x4),0x33+i);
280 write_data((0x60003000+i*0x4),0x44+i);
281 }
282 for(i=0;i<1024;i++){
283 write_data((0x60004000+i*0x4),0x55+i);
284 write_data((0x60005000+i*0x4),0x66+i);
285 write_data((0x60006000+i*0x4),0x77+i);
286 write_data((0x60007000+i*0x4),0x88+i);
287 }
288 for(i=0;i<4*1024;i++){
289 val = get_addr_data(0x60000000+i*0x4);
290 s0 += val;
291 }
292 for(i=0;i<4*1024;i++){
293 val = get_addr_data(0x60004000+i*0x4);
294 s1 += val;
295 }
296 for(i=0;i<4*1024;i++){
297 val = get_addr_data(0x60000000+i*0x4);
298 s2 += val;
299 }
300 for(i=0;i<4*1024;i++){
301 val = get_addr_data(0x60004000+i*0x4);
302 s3 += val;
303 }
304
305 }
306 rtos_delete_thread(&idle_read_psram_handle);
307 }
308 #endif
flash_command_test(char * pcWriteBuffer,int xWriteBufferLen,int argc,char ** argv)309 static void flash_command_test(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
310 {
311 char cmd = 0;
312 uint32_t len = 0;
313 uint32_t addr = 0;
314 #if (CONFIG_SYSTEM_CTRL)
315 if (os_strcmp(argv[1], "config") == 0) {
316 uint32_t flash_src_clk = os_strtoul(argv[2], NULL, 10);
317 uint32_t flash_div_clk = os_strtoul(argv[3], NULL, 10);
318 uint32_t flash_line_mode = os_strtoul(argv[4], NULL, 10);
319
320 if (FLASH_CLK_XTAL == flash_src_clk) {
321 sys_drv_flash_cksel(flash_src_clk);
322 }
323
324 if((FLASH_CLK_XTAL != sys_drv_flash_get_clk_sel()) && (0 == flash_div_clk)) {
325 os_printf("Config fail. Please set src clk as 26M, or set div larger than 0 firstly.\n");
326 return;
327 }
328
329 sys_drv_flash_set_clk_div(flash_div_clk);
330 sys_drv_flash_cksel(flash_src_clk);
331 bk_flash_set_line_mode(flash_line_mode);
332 os_printf("flash_src_clk = %u. [0 -> 26M; 1->98M; 2-> 120M]\n", flash_src_clk);
333 os_printf("flash_div_clk = %u. \n", flash_div_clk);
334 os_printf("flash_line_mode = %u. \n", flash_line_mode);
335
336 return;
337 }
338 if (os_strcmp(argv[1], "qe") == 0) {
339 uint32_t param = 0;
340 uint32_t quad_enable = os_strtoul(argv[2], NULL, 10);
341 uint32_t delay_cycle1 = os_strtoul(argv[3], NULL, 10);
342 uint32_t delay_cycle2 = os_strtoul(argv[4], NULL, 10);
343
344 for(int i = 0; i< 20; i++) {
345 bk_flash_set_line_mode(2);
346 flash_bypass_quad_test(quad_enable, delay_cycle1, delay_cycle2);
347 while (REG_READ(REG_FLASH_OPERATE_SW) & BUSY_SW);
348 param = bk_flash_read_status_reg();
349 if (quad_enable) {
350 if(param & 0x200){
351 break;
352 } else {
353 os_printf("retry quad test, i = %d, flash status: 0x%x.\n", i, param);
354 }
355 } else {
356 if(param & 0x200){
357 os_printf("retry quad test, i = %d, flash status: 0x%x.\n", i, param);
358 } else {
359 break;
360 }
361 }
362 }
363
364 if (quad_enable) {
365 if(param & 0x200){
366 os_printf("flash quad enable success, flash status: 0x%x.\n", param);
367 } else {
368 os_printf("flash quad enable fail, flash status: 0x%x.\n", param);
369 }
370 } else {
371 if(param & 0x200){
372 os_printf("flash quad disable fail, flash status: 0x%x.\n", param);
373 } else {
374 os_printf("flash quad disable success, flash status: 0x%x.\n", param);
375 }
376 }
377 return;
378 }
379 #endif
380 if (os_strcmp(argv[1], "idle_read_start") == 0) {
381 uint32_t task_prio = os_strtoul(argv[2], NULL, 10);
382 os_printf("idle_read_flash task start: task_prio = %u.\n", task_prio);
383 rtos_create_thread(&idle_read_flash_handle, task_prio,
384 "idle_read_flash",
385 (beken_thread_function_t) test_idle_read_flash,
386 CONFIG_APP_MAIN_TASK_STACK_SIZE,
387 (beken_thread_arg_t)0);
388
389 return;
390 } else if (os_strcmp(argv[1], "idle_read_stop") == 0) {
391 if (idle_read_flash_handle) {
392 rtos_delete_thread(&idle_read_flash_handle);
393 idle_read_flash_handle = NULL;
394 os_printf("idle_read_flash task stop\n");
395 }
396 return;
397 }
398
399 #if (CONFIG_SYSTEM_CTRL && CONFIG_PSRAM)
400 if (os_strcmp(argv[1], "idle_read_psram_start") == 0) {
401 uint32_t task_prio = os_strtoul(argv[2], NULL, 10);
402 os_printf("idle_read_psram task start: task_prio = %u.\n", task_prio);
403 rtos_create_thread(&idle_read_psram_handle, task_prio,
404 "idle_read_psram",
405 (beken_thread_function_t) test_idle_read_psram,
406 CONFIG_APP_MAIN_TASK_STACK_SIZE,
407 (beken_thread_arg_t)0);
408
409 return;
410 } else if (os_strcmp(argv[1], "idle_read_psram_stop") == 0) {
411 if (idle_read_psram_handle) {
412 rtos_delete_thread(&idle_read_psram_handle);
413 idle_read_psram_handle = NULL;
414 os_printf("idle_read_psram task stop\n");
415 }
416 return;
417 }
418 #endif
419
420 if (os_strcmp(argv[1], "U") == 0) {
421 bk_flash_set_protect_type(FLASH_PROTECT_NONE);
422 return;
423 } else if (os_strcmp(argv[1], "P") == 0) {
424 bk_flash_set_protect_type(FLASH_UNPROTECT_LAST_BLOCK);
425 return;
426 } else if (os_strcmp(argv[1], "RSR") == 0) {
427 uint16_t sts_val = bk_flash_read_status_reg();
428 os_printf("read sts_val = 0x%x\n", sts_val);
429 return;
430 } else if (os_strcmp(argv[1], "WSR") == 0) {
431 uint16_t sts_val = os_strtoul(argv[2], NULL, 16);
432 bk_flash_write_status_reg(sts_val);
433 return;
434 } else if (os_strcmp(argv[1], "C") == 0) {
435 #if (CONFIG_SYSTEM_CTRL)
436 addr = atoi(argv[2]);
437 len = atoi(argv[3]);
438 uint32_t test_times = os_strtoul(argv[4], NULL, 10);
439 test_flash_count_time(addr, len, test_times);
440 #endif
441 return;
442 }
443
444 if (argc == 4) {
445 cmd = argv[1][0];
446 addr = atoi(argv[2]);
447 len = atoi(argv[3]);
448
449 switch (cmd) {
450 case 'E':
451 bk_flash_set_protect_type(FLASH_PROTECT_NONE);
452 test_flash_erase(addr, len);
453 bk_flash_set_protect_type(FLASH_UNPROTECT_LAST_BLOCK);
454 break;
455
456 case 'R':
457 test_flash_read(addr, len);
458 break;
459 case 'W':
460 bk_flash_set_protect_type(FLASH_PROTECT_NONE);
461 test_flash_write(addr, len);
462 bk_flash_set_protect_type(FLASH_UNPROTECT_LAST_BLOCK);
463 break;
464 //to check whether protection mechanism can work
465 case 'N':
466 test_flash_erase(addr, len);
467 break;
468 case 'M':
469 test_flash_write(addr, len);
470 break;
471 case 'T':
472 test_flash_read_time(addr, len);
473 break;
474 default:
475 break;
476 }
477 } else
478 os_printf("FLASH <R/W/E/M/N/T> <start_addr> <len>\r\n");
479 }
480
481
partShow_Command(char * pcWriteBuffer,int xWriteBufferLen,int argc,char ** argv)482 static void partShow_Command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
483 {
484 bk_partition_t i;
485 bk_logic_partition_t *partition;
486
487 for (i = BK_PARTITION_BOOTLOADER; i <= BK_PARTITION_MAX; i++) {
488 partition = bk_flash_partition_get_info(i);
489 if (partition == NULL)
490 continue;
491
492 os_printf("%4d | %11s | Dev:%d | 0x%08lx | 0x%08lx |\r\n", i,
493 partition->partition_description, partition->partition_owner,
494 partition->partition_start_addr, partition->partition_length);
495 };
496
497 }
498
499 #define FLASH_CMD_CNT (sizeof(s_flash_commands) / sizeof(struct cli_command))
500 static const struct cli_command s_flash_commands[] = {
501 {"fmap_test", "flash_test memory map", partShow_Command},
502 {"flash_test", "flash_test <cmd(R/W/E/N)>", flash_command_test},
503 };
504
cli_flash_test_init(void)505 int cli_flash_test_init(void)
506 {
507 return cli_register_commands(s_flash_commands, FLASH_CMD_CNT);
508 }
509