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