• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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