xref: /rk3399_rockchip-uboot/test/rockchip/test-storage.c (revision 9c7862b8bf74438f89e41b22f18d690c1833e483)
1 /*
2  * (C) Copyright 2019 Rockchip Electronics Co., Ltd
3  *
4  * SPDX-License-Identifier:     GPL-2.0+
5  */
6 
7 #include <common.h>
8 #ifdef CONFIG_DM_RAMDISK
9 #include <boot_rkimg.h>
10 #endif
11 #include <cli.h>
12 #include <dm.h>
13 #include <environment.h>
14 #include <malloc.h>
15 #include <misc.h>
16 #ifdef CONFIG_RKIMG_BOOTLOADER
17 #include <sysmem.h>
18 #endif
19 #include <linux/ctype.h>
20 #ifdef CONFIG_ROCKCHIP_VENDOR_PARTITION
21 #include <asm/arch/vendor.h>
22 #endif
23 #include "test-rockchip.h"
24 
25 #define DEFAULT_STORAGE_RW_PART		"userdata"
26 enum if_type blk_get_type_by_name(char* devtype)
27 {
28 	int type = -1;
29 
30 	if (!strcmp(devtype, "mmc"))
31 		type = IF_TYPE_MMC;
32 #ifdef CONFIG_RKNAND
33 	else if (!strcmp(devtype, "rknand"))
34 		type = IF_TYPE_RKNAND;
35 #endif
36 #ifdef CONFIG_RKSFC_NAND
37 	else if (!strcmp(devtype, "spinand"))
38 		type = IF_TYPE_SPINAND;
39 #endif
40 #ifdef CONFIG_RKSFC_NOR
41 	else if (!strcmp(devtype, "spinor"))
42 		type = IF_TYPE_SPINOR;
43 #endif
44 #ifdef CONFIG_DM_RAMDISK
45 	else if (!strcmp(devtype, "ramdisk"))
46 		type = IF_TYPE_RAMDISK;
47 #endif
48 #ifdef CONFIG_MTD_BLK
49 	else if (!strcmp(devtype, "mtd"))
50 		type = IF_TYPE_MTD;
51 #endif
52 	else if (!strcmp(devtype, "usb"))
53 		type = IF_TYPE_USB;
54 
55 	return type;
56 }
57 
58 #if defined(CONFIG_MMC) || defined(CONFIG_RKNAND) || defined(CONFIG_DM_RAMDISK) || defined(CONFIG_USB_HOST)
59 static int do_test_storage(cmd_tbl_t *cmdtp, int flag,
60 			   int argc, char *const argv[],
61 			   const char *devtype,
62 			   const char *devnum,
63 			   const char *label)
64 {
65 	struct blk_desc *dev_desc;
66 	disk_partition_t part;
67 	u32 blocks, round, sector;
68 	char *w_buf, *r_buf;
69 	char cmd[64];
70 	int i, ret;
71 	ulong ts;
72 
73 	/* 1. Switch to device type/num */
74 	if (devtype && !strcmp(devtype, "usb")) {
75 		if (run_command("usb start", 0)) {
76 			printf("Switch to %s%s failed\n", devtype, devnum);
77 			ret = -ENODEV;
78 			goto err1;
79 		}
80 	} else if (devtype) {
81 		snprintf(cmd, sizeof(cmd), "%s dev %s", devtype, devnum);
82 		if (run_command(cmd, 0)) {
83 			printf("Switch to %s%s failed\n", devtype, devnum);
84 			ret = -ENODEV;
85 			goto err1;
86 		}
87 	}
88 	if (!devtype) {
89 		/* For blk test only */
90 #ifdef CONFIG_DM_RAMDISK
91 		dev_desc = rockchip_get_bootdev();
92 #else
93 		printf("%s Not support devtype!\n", __func__);
94 		return -EINVAL;
95 #endif
96 	} else {
97 		int if_type;
98 		int num = simple_strtoul(devnum, NULL, 10);
99 		if_type = blk_get_type_by_name((char *)devtype);
100 		dev_desc = blk_get_devnum_by_type(if_type, num);
101 	}
102 	if (!dev_desc) {
103 		ut_err("%s: failed to get blk desc\n", label);
104 		return -ENODEV;
105 	}
106 
107 	/* 2. Get test partition */
108 	if (part_get_info_by_name(dev_desc,
109 				  DEFAULT_STORAGE_RW_PART, &part) < 0) {
110 		ut_err("%s: failed to find %s partition\n", label,
111 		       DEFAULT_STORAGE_RW_PART);
112 		return -EINVAL;
113 	}
114 
115 	/* 32MB */
116 	sector = part.start;
117 	blocks = part.size > 0x10000 ? 0x10000 : part.size;
118 	round  = 4;
119 
120 	/* Round up */
121 	if (blocks % 2)
122 		blocks += 1;
123 
124 	printf("%s RW sectors on %s 0x%08x - 0x%08x(size: %ld MiB) for %d round\n\n",
125 	       label, DEFAULT_STORAGE_RW_PART,
126 	       sector, sector + blocks,
127 	       (blocks * dev_desc->blksz) >> 20, round);
128 
129 
130 	/* 3. Prepare memory */
131 #ifdef CONFIG_RKIMG_BOOTLOADER
132 	w_buf = sysmem_alloc_by_name("storage_w", blocks * dev_desc->blksz);
133 #else
134 	w_buf = memalign(CONFIG_SYS_CACHELINE_SIZE, blocks * dev_desc->blksz);
135 #endif
136 	if (!w_buf) {
137 		ut_err("%s: no sysmem for w_buf\n", label);
138 		ret = -ENOMEM;
139 		goto err1;
140 	}
141 #ifdef CONFIG_RKIMG_BOOTLOADER
142 	r_buf = sysmem_alloc_by_name("storage_r", blocks * dev_desc->blksz);
143 #else
144 	r_buf = memalign(CONFIG_SYS_CACHELINE_SIZE, blocks * dev_desc->blksz);
145 #endif
146 	if (!r_buf) {
147 		ut_err("%s: no sysmem for r_buf\n", label);
148 		ret = -ENOMEM;
149 		goto err2;
150 	}
151 
152 	for (i = 0; i < blocks * dev_desc->blksz; i++) {
153 		w_buf[i] = i;
154 		r_buf[i] = 0;
155 	}
156 
157 	/* 4. Write test */
158 	ts = get_timer(0);
159 	if (devtype) {
160 		snprintf(cmd, sizeof(cmd), "%s write 0x%x 0x%x 0x%x",
161 			 devtype, (u32)(ulong)w_buf, sector, blocks);
162 		for (i = 0; i < round; i++) {
163 			if (run_command(cmd, 0)) {
164 				ut_err("%s: failed to write @%d round\n", label, i);
165 				ret = -EIO;
166 				goto err3;
167 			}
168 		}
169 	} else {
170 		for (i = 0; i < round; i++) {
171 			ret = blk_dwrite(dev_desc, sector, blocks, w_buf);
172 			if (ret != blocks) {
173 				ut_err("%s: failed to write @%d round\n", label, i);
174 				ret = -EIO;
175 				goto err3;
176 			}
177 		}
178 	}
179 
180 	ts = get_timer(0) - ts;
181 	printf("\n%s write: size %dMB, used %ldms, speed %ldMB/s\n",
182 	       label, blocks * round / 2048, ts, (blocks * round >> 1) / ts);
183 
184 	/* 5. Read test */
185 	ts = get_timer(0);
186 	if (devtype) {
187 		snprintf(cmd, sizeof(cmd), "%s read 0x%x 0x%x 0x%x",
188 			 devtype, (u32)(ulong)r_buf, sector, blocks);
189 
190 		for (i = 0; i < round; i++) {
191 			if (run_command(cmd, 0)) {
192 				ut_err("%s: failed to read @%d round\n", label, i);
193 				ret = -EIO;
194 				goto err3;
195 			}
196 		}
197 	} else {
198 		for (i = 0; i < round; i++) {
199 			ret = blk_dread(dev_desc, sector, blocks, r_buf);
200 			if (ret != blocks) {
201 				ut_err("%s: failed to read @%d round\n", label, i);
202 				ret = -EIO;
203 				goto err3;
204 			}
205 		}
206 	}
207 
208 	ts = get_timer(0) - ts;
209 	printf("\n%s read: size %dMB, used %ldms, speed %ldMB/s\n",
210 	       label, blocks * round / 2048, ts, (blocks * round >> 1) / ts);
211 
212 	/* 6. Verify the context */
213 	for (i = 0; i < blocks * dev_desc->blksz; i++) {
214 		if (w_buf[i] != r_buf[i]) {
215 			ut_err("%s: context compare error\n", label);
216 			ret = -EINVAL;
217 			goto err3;
218 		}
219 	}
220 
221 	/* 7. Switch back to default system devnum */
222 	if (devtype && !strcmp(devtype, "mmc") && env_get("devnum") &&
223 	    strcmp(devnum, env_get("devnum"))) {
224 		ret = run_command(cmd, 0);
225 		if (ret) {
226 			ut_err("%s: failed to switch to mmc1\n", label);
227 			ret = -ENODEV;
228 			goto err3;
229 		}
230 	}
231 
232 	ret = 0;
233 err3:
234 #ifdef CONFIG_RKIMG_BOOTLOADER
235 	sysmem_free((phys_addr_t)r_buf);
236 err2:
237 	sysmem_free((phys_addr_t)w_buf);
238 #else
239 	free(r_buf);
240 err2:
241 	free(w_buf);
242 #endif
243 err1:
244 
245 	return ret;
246 }
247 
248 #ifdef CONFIG_MMC
249 static int do_test_emmc(cmd_tbl_t *cmdtp, int flag,
250 			int argc, char *const argv[])
251 {
252 	return do_test_storage(cmdtp, flag, argc, argv, "mmc", "0", "MMC0");
253 }
254 
255 static int do_test_sdmmc(cmd_tbl_t *cmdtp, int flag,
256 			 int argc, char *const argv[])
257 {
258 	return do_test_storage(cmdtp, flag, argc, argv, "mmc", "1", "MMC1");
259 }
260 #endif
261 
262 #ifdef CONFIG_RKNAND
263 static int do_test_rknand(cmd_tbl_t *cmdtp, int flag,
264 			  int argc, char *const argv[])
265 {
266 	return do_test_storage(cmdtp, flag, argc, argv, "rknand", "0", "RKNAND0");
267 }
268 #endif
269 
270 #ifdef CONFIG_DM_RAMDISK
271 static int do_test_blk(cmd_tbl_t *cmdtp, int flag,
272 		       int argc, char *const argv[])
273 {
274 	return do_test_storage(cmdtp, flag, argc, argv, NULL, NULL, "BLK");
275 }
276 #endif
277 #endif/* defined(CONFIG_MMC) || defined(CONFIG_RKNAND) || defined(CONFIG_DM_RAMDISK) */
278 
279 #if defined(CONFIG_OPTEE_CLIENT) && defined(CONFIG_MMC)
280 static int do_test_secure_storage(cmd_tbl_t *cmdtp, int flag,
281 				  int argc, char *const argv[])
282 {
283 	return run_command("mmc testsecurestorage", 0);
284 }
285 #endif
286 
287 #if defined(CONFIG_CMD_SAVEENV) && !defined(CONFIG_ENV_IS_NOWHERE) && \
288 	!defined(CONFIG_SPL_BUILD)
289 static int do_test_env(cmd_tbl_t *cmdtp, int flag,
290 		       int argc, char *const argv[])
291 {
292 	int ret;
293 
294 	ret = env_save();
295 	if (ret) {
296 		ut_err("env: failed to save, ret=%d\n", ret);
297 		return ret;
298 	}
299 
300 	return env_load();
301 }
302 #endif
303 
304 #ifdef CONFIG_ROCKCHIP_VENDOR_PARTITION
305 static int do_test_vendor(cmd_tbl_t *cmdtp, int flag,
306 			  int argc, char *const argv[])
307 {
308 	return vendor_storage_test();
309 }
310 #endif
311 
312 #ifdef CONFIG_ROCKCHIP_EFUSE
313 static int do_test_efuse(cmd_tbl_t *cmdtp, int flag,
314 			 int argc, char *const argv[])
315 {
316 	struct udevice *dev;
317 	u8 fuses[128] = {0};
318 	int ret;
319 
320 	ret = uclass_get_device(UCLASS_MISC, 0, &dev);
321 	if (ret) {
322 		ut_err("efuse: failed to get device, ret=%d\n", ret);
323 		return 0;
324 	}
325 
326 	ret = misc_read(dev, 0, &fuses, sizeof(fuses));
327 	if (ret) {
328 		ut_err("efuse: failed to read, ret=%d\n", ret);
329 		return 0;
330 	}
331 
332 	printf("Efuse-content:\n");
333 	print_buffer(0, fuses, 1, 128, 16);
334 
335 	return 0;
336 }
337 #endif
338 
339 #ifdef CONFIG_ROCKCHIP_OTP
340 static int do_test_otp(cmd_tbl_t *cmdtp, int flag,
341 		       int argc, char *const argv[])
342 {
343 	struct udevice *dev;
344 	u8 otps[64] = {0};
345 	int ret;
346 
347 	/* retrieve the device */
348 	ret = uclass_get_device_by_driver(UCLASS_MISC, 0, &dev);
349 	if (ret) {
350 		ut_err("otp: failed to get device, ret=%d\n", ret);
351 		return 0;
352 	}
353 
354 	ret = misc_read(dev, 0, &otps, sizeof(otps));
355 	if (ret) {
356 		ut_err("otp: failed to read, ret=%d\n", ret);
357 		return 0;
358 	}
359 
360 	printf("Otp-content:\n");
361 	print_buffer(0, otps, 1, 64, 16);
362 
363 	return 0;
364 }
365 #endif
366 
367 #ifdef CONFIG_PARTITIONS
368 static int do_test_part(cmd_tbl_t *cmdtp, int flag,
369 			int argc, char *const argv[])
370 {
371 	return run_command("part list ${devtype} ${devnum}", 0);
372 }
373 #endif
374 
375 #ifdef CONFIG_USB_HOST
376 static int do_test_usb(cmd_tbl_t *cmdtp, int flag,
377 			int argc, char *const argv[])
378 {
379 	run_command("usb start", 0);
380 	return do_test_storage(cmdtp, flag, argc, argv, "usb", "0", "usb0");
381 }
382 #endif
383 
384 static cmd_tbl_t sub_cmd[] = {
385 #ifdef CONFIG_DM_RAMDISK
386 	UNIT_CMD_DEFINE(blk, 0),
387 #endif
388 #ifdef CONFIG_MMC
389 	UNIT_CMD_DEFINE(emmc, 0),
390 #endif
391 #ifdef CONFIG_ROCKCHIP_EFUSE
392 	UNIT_CMD_DEFINE(efuse, 0),
393 #endif
394 #if defined(CONFIG_CMD_SAVEENV) && !defined(CONFIG_ENV_IS_NOWHERE) && \
395 	!defined(CONFIG_SPL_BUILD)
396 	UNIT_CMD_DEFINE(env, 0),
397 #endif
398 #ifdef CONFIG_ROCKCHIP_OTP
399 	UNIT_CMD_DEFINE(otp, 0),
400 #endif
401 #ifdef CONFIG_RKNAND
402 	UNIT_CMD_DEFINE(rknand, 0),
403 #endif
404 #if defined(CONFIG_OPTEE_CLIENT) && defined(CONFIG_MMC)
405 	UNIT_CMD_DEFINE(secure_storage, 0),
406 #endif
407 #ifdef CONFIG_PARTITIONS
408 	UNIT_CMD_DEFINE(part, 0),
409 #endif
410 #ifdef CONFIG_USB_HOST
411 	UNIT_CMD_DEFINE(usb, 0),
412 #endif
413 #ifdef CONFIG_MMC
414 	UNIT_CMD_DEFINE(sdmmc, 0),
415 #endif
416 #ifdef CONFIG_ROCKCHIP_VENDOR_PARTITION
417 	UNIT_CMD_DEFINE(vendor, 0),
418 #endif
419 };
420 
421 static char sub_cmd_help[] =
422 #ifdef CONFIG_DM_RAMDISK
423 "    [.] rktest blk                         - test blk layer read/write\n"
424 #endif
425 #ifdef CONFIG_MMC
426 "    [.] rktest emmc                        - test emmc read/write speed\n"
427 "    [.] rktest sdmmc                       - test sd card and fat fs read/write\n"
428 #endif
429 #ifdef CONFIG_RKNAND
430 "    [.] rktest rknand                      - test rknand read/write speed\n"
431 #endif
432 #if defined(CONFIG_OPTEE_CLIENT) && defined(CONFIG_MMC)
433 "    [.] rktest secure_storage              - test secure storage\n"
434 #endif
435 #ifdef CONFIG_ROCKCHIP_VENDOR_PARTITION
436 "    [.] rktest vendor                      - test vendor storage read/write\n"
437 #endif
438 #ifdef CONFIG_ROCKCHIP_EFUSE
439 "    [.] rktest efuse                       - test efuse, dump content\n"
440 #endif
441 #ifdef CONFIG_ROCKCHIP_OTP
442 "    [.] rktest otp                         - test otp, dump content\n"
443 #endif
444 #if defined(CONFIG_CMD_SAVEENV) && !defined(CONFIG_ENV_IS_NOWHERE) && \
445 	!defined(CONFIG_SPL_BUILD)
446 "    [.] rktest env                         - test save env to storage\n"
447 #endif
448 #ifdef CONFIG_PARTITIONS
449 "    [.] rktest part                        - test part list\n"
450 #endif
451 #ifdef CONFIG_USB_HOST
452 "    [.] rktest usb                        - test usb disk\n"
453 #endif
454 ;
455 
456 const struct cmd_group cmd_grp_storage = {
457 	.id	= TEST_ID_STORAGE,
458 	.help	= sub_cmd_help,
459 	.cmd	= sub_cmd,
460 	.cmd_n	= ARRAY_SIZE(sub_cmd),
461 };
462