xref: /OK3568_Linux_fs/u-boot/arch/arm/mach-rockchip/vendor.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  * (C) Copyright 2008-2017 Fuzhou Rockchip Electronics Co., Ltd
3  *
4  * SPDX-License-Identifier:	GPL-2.0+
5  */
6 
7 #include <common.h>
8 #include <malloc.h>
9 #include <asm/arch/vendor.h>
10 #include <boot_rkimg.h>
11 #include <nand.h>
12 #include <part.h>
13 #include <fdt_support.h>
14 
15 /* tag for vendor check */
16 #define VENDOR_TAG		0x524B5644
17 /* The Vendor partition contains the number of Vendor blocks */
18 #define MTD_VENDOR_PART_NUM	1
19 #define NAND_VENDOR_PART_NUM	2
20 #define VENDOR_PART_NUM		4
21 /* align to 64 bytes */
22 #define VENDOR_BTYE_ALIGN	0x3F
23 #define VENDOR_BLOCK_SIZE	512
24 
25 #define PAGE_ALGIN_SIZE		(4096uL)
26 #define PAGE_ALGIN_MASK		(~(PAGE_ALGIN_SIZE - 1))
27 
28 /* --- Emmc define --- */
29 /* Starting address of the Vendor in memory. */
30 #define EMMC_VENDOR_PART_OFFSET		(1024 * 7)
31 /*
32  * The number of memory blocks used by each
33  * Vendor structure(128 * 512B = 64KB)
34  */
35 #define EMMC_VENDOR_PART_BLKS		128
36 /* The maximum number of items in each Vendor block */
37 #define EMMC_VENDOR_ITEM_NUM		126
38 
39 /* --- Spi Nand/SLC/MLC large capacity case define --- */
40 /* The Vendor partition contains the number of Vendor blocks */
41 #define NAND_VENDOR_PART_OFFSET		0
42 /*
43  * The number of memory blocks used by each
44  * Vendor structure(8 * 512B = 4KB)
45  */
46 #define NAND_VENDOR_PART_BLKS		128
47 /* The maximum number of items in each Vendor block */
48 #define NAND_VENDOR_ITEM_NUM		126
49 
50 /* --- Spi/Spi Nand/SLC/MLC small capacity case define --- */
51 /* The Vendor partition contains the number of Vendor blocks */
52 #define	FLASH_VENDOR_PART_OFFSET	8
53 /*
54  * The number of memory blocks used by each
55  * Vendor structure(8 * 512B = 4KB)
56  */
57 #define FLASH_VENDOR_PART_BLKS		8
58 /* The maximum number of items in each Vendor block */
59 #define FLASH_VENDOR_ITEM_NUM		62
60 
61 /* Vendor uinit test define */
62 int vendor_storage_test(void);
63 
64 struct vendor_hdr {
65 	u32	tag;
66 	u32	version;
67 	u16	next_index;
68 	u16	item_num;
69 	u16	free_offset; /* Free space offset */
70 	u16	free_size; /* Free space size */
71 };
72 
73 /*
74  * Different types of Flash vendor info are different.
75  * EMMC:EMMC_VENDOR_PART_BLKS * BLOCK_SIZE(512) = 64KB;
76  * Spi Nor/Spi Nand/SLC/MLC: FLASH_VENDOR_PART_BLKS *
77  * BLOCK_SIZE(512) = 4KB.
78  * hash: For future expansion.
79  * version2: Together with hdr->version, it is used to
80  * ensure the current Vendor block content integrity.
81  *   (version2 == hdr->version):Data valid;
82  *   (version2 != hdr->version):Data invalid.
83  */
84 struct vendor_info {
85 	struct vendor_hdr *hdr;
86 	struct vendor_item *item;
87 	u8 *data;
88 	u32 *hash;
89 	u32 *version2;
90 };
91 
92 struct mtd_flash_info {
93 	u32 part_offset;
94 	u32 part_size;
95 	u32 blk_offset;
96 	u32 page_offset;
97 	u32 version;
98 	u32 ops_size;
99 	u32 blk_size;
100 };
101 
102 /*
103  * Calculate the offset of each field for emmc.
104  * Emmc vendor info size: 64KB
105  */
106 #define EMMC_VENDOR_INFO_SIZE	(EMMC_VENDOR_PART_BLKS * VENDOR_BLOCK_SIZE)
107 #define EMMC_VENDOR_DATA_OFFSET	(sizeof(struct vendor_hdr) + EMMC_VENDOR_ITEM_NUM * sizeof(struct vendor_item))
108 #define EMMC_VENDOR_HASH_OFFSET (EMMC_VENDOR_INFO_SIZE - 8)
109 #define EMMC_VENDOR_VERSION2_OFFSET (EMMC_VENDOR_INFO_SIZE - 4)
110 
111 /*
112  * Calculate the offset of each field for spi nand/slc/mlc large capacity case.
113  * Flash vendor info size: 4KB
114  */
115 #define NAND_VENDOR_INFO_SIZE	(NAND_VENDOR_PART_BLKS * VENDOR_BLOCK_SIZE)
116 #define NAND_VENDOR_DATA_OFFSET	(sizeof(struct vendor_hdr) + NAND_VENDOR_ITEM_NUM * sizeof(struct vendor_item))
117 #define NAND_VENDOR_HASH_OFFSET (NAND_VENDOR_INFO_SIZE - 8)
118 #define NAND_VENDOR_VERSION2_OFFSET (NAND_VENDOR_INFO_SIZE - 4)
119 
120 /*
121  * Calculate the offset of each field for spi nor/spi nand/slc/mlc large small capacity case.
122  * Flash vendor info size: 4KB
123  */
124 #define FLASH_VENDOR_INFO_SIZE	(FLASH_VENDOR_PART_BLKS * VENDOR_BLOCK_SIZE)
125 #define FLASH_VENDOR_DATA_OFFSET (sizeof(struct vendor_hdr) + FLASH_VENDOR_ITEM_NUM * sizeof(struct vendor_item))
126 #define FLASH_VENDOR_HASH_OFFSET (FLASH_VENDOR_INFO_SIZE - 8)
127 #define FLASH_VENDOR_VERSION2_OFFSET (FLASH_VENDOR_INFO_SIZE - 4)
128 
129 /* vendor info */
130 static struct vendor_info vendor_info;
131 /* The storage type of the device */
132 static int bootdev_type;
133 
134 #ifdef CONFIG_MTD_BLK
135 static struct mtd_flash_info s_flash_info;
136 static const char *vendor_mtd_name = "vnvm";
137 #endif
138 
139 /* vendor private read write ops*/
140 static	int (*_flash_read)(struct blk_desc *dev_desc,
141 			   u32 sec,
142 			   u32 n_sec,
143 			   void *buffer);
144 static	int (*_flash_write)(struct blk_desc *dev_desc,
145 			    u32 sec,
146 			    u32 n_sec,
147 			    void *buffer);
148 
flash_vendor_dev_ops_register(int (* read)(struct blk_desc * dev_desc,u32 sec,u32 n_sec,void * p_data),int (* write)(struct blk_desc * dev_desc,u32 sec,u32 n_sec,void * p_data))149 int flash_vendor_dev_ops_register(int (*read)(struct blk_desc *dev_desc,
150 					      u32 sec,
151 					      u32 n_sec,
152 					      void *p_data),
153 				  int (*write)(struct blk_desc *dev_desc,
154 					       u32 sec,
155 					       u32 n_sec,
156 					       void *p_data))
157 {
158 	if (!_flash_read) {
159 		_flash_read = read;
160 		_flash_write = write;
161 		return 0;
162 	}
163 
164 	return -EPERM;
165 }
166 
167 #ifdef CONFIG_MTD_BLK
mtd_vendor_storage_init(struct blk_desc * dev_desc)168 static int mtd_vendor_storage_init(struct blk_desc *dev_desc)
169 {
170 	struct mtd_info *mtd = (struct mtd_info *)dev_desc->bdev->priv;
171 	disk_partition_t vnvm_part_info;
172 	void *buf = vendor_info.hdr;
173 	int ret, offset;
174 	int part_num, bad_block_size;
175 
176 	memset(&vnvm_part_info, 0x0, sizeof(vnvm_part_info));
177 	part_num = part_get_info_by_name(dev_desc, vendor_mtd_name, &vnvm_part_info);
178 	if (part_num < 0)
179 		return -EIO;
180 
181 	s_flash_info.part_offset = (u32)vnvm_part_info.start;
182 	s_flash_info.part_size = (u32)vnvm_part_info.size;
183 	s_flash_info.page_offset = 0;
184 	s_flash_info.blk_offset = 0;
185 	s_flash_info.version = 0;
186 	/* SPI Nor unified to Support 64KB erase block */
187 	if (dev_desc->devnum == BLK_MTD_SPI_NOR)
188 		s_flash_info.blk_size = 0x80;
189 	else
190 		s_flash_info.blk_size = mtd->erasesize >> 9;
191 	s_flash_info.ops_size = roundup(FLASH_VENDOR_INFO_SIZE, mtd->writesize) >> 9;
192 
193 	/* scan bad block and calculate the real size can be used */
194 	bad_block_size = 0;
195 	for (offset = 0; offset < s_flash_info.part_size; offset += s_flash_info.blk_size) {
196 		if (mtd_block_isbad(mtd, (s_flash_info.part_offset + offset) << 9))
197 			bad_block_size += s_flash_info.blk_size;
198 	}
199 	s_flash_info.part_size -= bad_block_size;
200 
201 	for (offset = 0; offset < s_flash_info.part_size; offset += s_flash_info.blk_size) {
202 		ret = blk_dread(dev_desc, s_flash_info.part_offset + offset,
203 				FLASH_VENDOR_INFO_SIZE >> 9,
204 				(u8 *)buf);
205 		debug("%s: read %x version = %x\n", __func__,
206 		      s_flash_info.part_offset + offset,
207 		      vendor_info.hdr->version);
208 		if (ret == (FLASH_VENDOR_INFO_SIZE >> 9) && vendor_info.hdr->tag == VENDOR_TAG &&
209 		    vendor_info.hdr->version == *vendor_info.version2) {
210 			if (vendor_info.hdr->version > s_flash_info.version) {
211 				s_flash_info.version = vendor_info.hdr->version;
212 				s_flash_info.blk_offset = offset;
213 			}
214 		}
215 	}
216 
217 	debug("%s: s_flash_info.version = %x %x\n", __func__, s_flash_info.version, s_flash_info.blk_offset);
218 	if (s_flash_info.version) {
219 		for (offset = s_flash_info.blk_size  - s_flash_info.ops_size;
220 		     offset >= 0;
221 		     offset -= s_flash_info.ops_size) {
222 			ret = blk_dread(dev_desc, s_flash_info.part_offset +
223 					s_flash_info.blk_offset + offset,
224 					1,
225 					(u8 *)buf);
226 
227 			/* the page is not programmed */
228 			if (ret == 1 && vendor_info.hdr->tag == 0xFFFFFFFF)
229 				continue;
230 
231 			/* point to the next free page */
232 			if (s_flash_info.page_offset < offset)
233 				s_flash_info.page_offset = offset + s_flash_info.ops_size;
234 
235 			if (ret != 1 || vendor_info.hdr->tag != VENDOR_TAG)
236 				continue;
237 			ret = blk_dread(dev_desc, s_flash_info.part_offset +
238 					s_flash_info.blk_offset + offset,
239 					FLASH_VENDOR_INFO_SIZE >> 9,
240 					(u8 *)buf);
241 			debug("%s: read %x version = %x\n", __func__,
242 			      s_flash_info.part_offset + s_flash_info.blk_offset  + offset,
243 			      vendor_info.hdr->version);
244 
245 			if (ret == (FLASH_VENDOR_INFO_SIZE >> 9)  && vendor_info.hdr->tag == VENDOR_TAG &&
246 			    vendor_info.hdr->version == *vendor_info.version2) {
247 				s_flash_info.version = vendor_info.hdr->version;
248 				break;
249 			}
250 		}
251 	} else {
252 		memset((u8 *)vendor_info.hdr, 0, FLASH_VENDOR_INFO_SIZE);
253 		vendor_info.hdr->version = 1;
254 		vendor_info.hdr->tag = VENDOR_TAG;
255 		vendor_info.hdr->free_size =
256 			((u32)(size_t)vendor_info.hash
257 			- (u32)(size_t)vendor_info.data);
258 		*vendor_info.version2 = vendor_info.hdr->version;
259 	}
260 
261 	return 0;
262 }
263 
mtd_vendor_write(struct blk_desc * dev_desc,u32 sec,u32 n_sec,void * buf)264 static int mtd_vendor_write(struct blk_desc *dev_desc,
265 			    u32 sec,
266 			    u32 n_sec,
267 			    void *buf)
268 {
269 	int ret, count = 0, err = 0;
270 
271 re_write:
272 	debug("[Vendor INFO]:%s page_offset=0x%x count = %x\n", __func__, s_flash_info.part_offset +
273 	      s_flash_info.blk_offset + s_flash_info.page_offset, count);
274 	if (s_flash_info.page_offset >= s_flash_info.blk_size) {
275 		s_flash_info.blk_offset += s_flash_info.blk_size;
276 		if (s_flash_info.blk_offset >= s_flash_info.part_size)
277 			s_flash_info.blk_offset = 0;
278 		s_flash_info.page_offset = 0;
279 		/*
280 		 * The spi NOR driver only erase 4KB while write data, and here need to
281 		 * erase one block for vendor storage request.
282 		 */
283 		blk_derase(dev_desc, s_flash_info.part_offset + s_flash_info.blk_offset, s_flash_info.blk_size);
284 	}
285 
286 	dev_desc->op_flag |= BLK_MTD_CONT_WRITE;
287 	ret = blk_dwrite(dev_desc, s_flash_info.part_offset +
288 			 s_flash_info.blk_offset + s_flash_info.page_offset,
289 			 FLASH_VENDOR_INFO_SIZE >> 9,
290 			 (u8 *)buf);
291 	dev_desc->op_flag &= ~(BLK_MTD_CONT_WRITE);
292 
293 	s_flash_info.page_offset += s_flash_info.ops_size;
294 	if (ret != (FLASH_VENDOR_INFO_SIZE >> 9)) {
295 		err++;
296 		if (err > 3)
297 			return -EIO;
298 		goto re_write;
299 	}
300 
301 	count++;
302 	/* write 2 copies for reliability */
303 	if (count < 2)
304 		goto re_write;
305 
306 	return ret;
307 }
308 #endif
309 
310 /**********************************************************/
311 /*              vendor API implementation                 */
312 /**********************************************************/
vendor_ops(u8 * buffer,u32 addr,u32 n_sec,int write)313 static int vendor_ops(u8 *buffer, u32 addr, u32 n_sec, int write)
314 {
315 	struct blk_desc *dev_desc;
316 	unsigned int lba = 0;
317 	int ret = 0;
318 
319 	dev_desc = rockchip_get_bootdev();
320 	if (!dev_desc) {
321 		printf("%s: dev_desc is NULL!\n", __func__);
322 		return -ENODEV;
323 	}
324 
325 	if (dev_desc->if_type == IF_TYPE_NVME || dev_desc->if_type == IF_TYPE_SCSI) {
326 		dev_desc = blk_get_devnum_by_type(IF_TYPE_MTD, BLK_MTD_SPI_NOR);
327 		if (!dev_desc) {
328 			printf("%s: dev_desc is NULL!\n", __func__);
329 			return -ENODEV;
330 		}
331 	}
332 
333 	/* Get the offset address according to the device type */
334 	switch (dev_desc->if_type) {
335 	case IF_TYPE_MMC:
336 		/*
337 		 * The location of VendorStorage in Flash is shown in the
338 		 * following figure. The starting address of the VendorStorage
339 		 * partition offset is 3.5MB(EMMC_VENDOR_PART_OFFSET*BLOCK_SIZE(512)),
340 		 * and the partition size is 256KB.
341 		 * ----------------------------------------------------
342 		 * |   3.5MB    |  VendorStorage  |                   |
343 		 * ----------------------------------------------------
344 		 */
345 		lba = EMMC_VENDOR_PART_OFFSET;
346 		debug("[Vendor INFO]:VendorStorage offset address=0x%x\n", lba);
347 		break;
348 	case IF_TYPE_RKNAND:
349 	case IF_TYPE_SPINAND:
350 		/*
351 		 * The location of VendorStorage in Flash is shown in the
352 		 * following figure. The starting address of the VendorStorage
353 		 * partition offset is 0KB in FTL vendor block,
354 		 * and the partition size is 128KB.
355 		 * ----------------------------------------------------
356 		 * |  VendorStorage  |                     |
357 		 * ----------------------------------------------------
358 		 */
359 		lba = NAND_VENDOR_PART_OFFSET;
360 		debug("[Vendor INFO]:VendorStorage offset address=0x%x\n", lba);
361 		break;
362 	case IF_TYPE_SPINOR:
363 		/*
364 		 * The location of VendorStorage in Flash is shown in the
365 		 * following figure. The starting address of the VendorStorage
366 		 * partition offset is 4KB (FLASH_VENDOR_PART_OFFSET * BLOCK_SIZE),
367 		 * and the partition size is 16KB.
368 		 * ----------------------------------------------------
369 		 * |   4KB    |  VendorStorage  |                     |
370 		 * ----------------------------------------------------
371 		 */
372 		lba = FLASH_VENDOR_PART_OFFSET;
373 		debug("[Vendor INFO]:VendorStorage offset address=0x%x\n", lba);
374 		break;
375 #ifdef CONFIG_MTD_BLK
376 	case IF_TYPE_MTD:
377 		/*
378 		 * The location of VendorStorage in NAND FLASH or SPI NAND partition "vnvm"
379 		 * is shown in the following figure. The partition size is at least  4
380 		 * NAND FLASH blocks.
381 		 * ----------------------------------------------------
382 		 * |   .....    |  vnvm  |  .......                   |
383 		 * ----------------------------------------------------
384 		 */
385 		lba = 0;
386 		break;
387 #endif
388 	default:
389 		printf("[Vendor ERROR]:Boot device type is invalid!\n");
390 		return -ENODEV;
391 	}
392 	if (write) {
393 		if (_flash_write)
394 			ret = _flash_write(dev_desc, lba + addr, n_sec, buffer);
395 		else
396 			ret = blk_dwrite(dev_desc, lba + addr, n_sec, buffer);
397 	} else {
398 		if (_flash_read)
399 			ret = _flash_read(dev_desc, lba + addr, n_sec, buffer);
400 		else
401 			ret = blk_dread(dev_desc, lba + addr, n_sec, buffer);
402 	}
403 
404 	debug("[Vendor INFO]:op=%s, ret=%d\n", write ? "write" : "read", ret);
405 
406 	return ret;
407 }
408 
409 /*
410  * The VendorStorage partition is divided into four parts
411  * (vendor 0-3) and its structure is shown in the following figure.
412  * The init function is used to select the latest and valid vendor.
413  *
414  * |******************** FLASH ********************|
415  * -------------------------------------------------
416  * |  vendor0  |  vendor1  |  vendor2  |  vendor3  |
417  * -------------------------------------------------
418  * Notices:
419  *   1. "version" and "version2" are used to verify that the vendor
420  *      is valid (equal is valid).
421  *   2. the "version" value is larger, indicating that the current
422  *      verndor data is new.
423  */
vendor_storage_init(void)424 int vendor_storage_init(void)
425 {
426 	int ret = 0;
427 	int ret_size;
428 	u8 *buffer;
429 	u32 size, i;
430 	u32 max_ver = 0;
431 	u32 max_index = 0;
432 	u16 data_offset, hash_offset, part_num;
433 	u16 version2_offset, part_size;
434 	struct blk_desc *dev_desc;
435 
436 	dev_desc = rockchip_get_bootdev();
437 	if (!dev_desc) {
438 		printf("[Vendor ERROR]:Invalid boot device type(%d)\n",
439 		       bootdev_type);
440 		return -ENODEV;
441 	}
442 
443 	if (dev_desc->if_type == IF_TYPE_NVME || dev_desc->if_type == IF_TYPE_SCSI) {
444 		dev_desc = blk_get_devnum_by_type(IF_TYPE_MTD, BLK_MTD_SPI_NOR);
445 		if (!dev_desc) {
446 			printf("%s: dev_desc is NULL!\n", __func__);
447 			return -ENODEV;
448 		}
449 	}
450 
451 	switch (dev_desc->if_type) {
452 	case IF_TYPE_MMC:
453 		size = EMMC_VENDOR_INFO_SIZE;
454 		part_size = EMMC_VENDOR_PART_BLKS;
455 		data_offset = EMMC_VENDOR_DATA_OFFSET;
456 		hash_offset = EMMC_VENDOR_HASH_OFFSET;
457 		version2_offset = EMMC_VENDOR_VERSION2_OFFSET;
458 		part_num = VENDOR_PART_NUM;
459 		break;
460 	case IF_TYPE_RKNAND:
461 	case IF_TYPE_SPINAND:
462 		size = NAND_VENDOR_INFO_SIZE;
463 		part_size = NAND_VENDOR_PART_BLKS;
464 		data_offset = NAND_VENDOR_DATA_OFFSET;
465 		hash_offset = NAND_VENDOR_HASH_OFFSET;
466 		version2_offset = NAND_VENDOR_VERSION2_OFFSET;
467 		part_num = NAND_VENDOR_PART_NUM;
468 		break;
469 	case IF_TYPE_SPINOR:
470 		size = FLASH_VENDOR_INFO_SIZE;
471 		part_size = FLASH_VENDOR_PART_BLKS;
472 		data_offset = FLASH_VENDOR_DATA_OFFSET;
473 		hash_offset = FLASH_VENDOR_HASH_OFFSET;
474 		version2_offset = FLASH_VENDOR_VERSION2_OFFSET;
475 		part_num = VENDOR_PART_NUM;
476 		break;
477 #ifdef CONFIG_MTD_BLK
478 	case IF_TYPE_MTD:
479 		size = FLASH_VENDOR_INFO_SIZE;
480 		part_size = FLASH_VENDOR_PART_BLKS;
481 		data_offset = FLASH_VENDOR_DATA_OFFSET;
482 		hash_offset = FLASH_VENDOR_HASH_OFFSET;
483 		version2_offset = FLASH_VENDOR_VERSION2_OFFSET;
484 		part_num = MTD_VENDOR_PART_NUM;
485 		_flash_write = mtd_vendor_write;
486 		break;
487 #endif
488 	default:
489 		debug("[Vendor ERROR]:Boot device type is invalid!\n");
490 		ret = -ENODEV;
491 		break;
492 	}
493 	/* Invalid bootdev type */
494 	if (ret)
495 		return ret;
496 
497 	/* Initialize */
498 	bootdev_type = dev_desc->if_type;
499 
500 	/* Always use, no need to release, align to page size for kerenl reserved memory */
501 	buffer = (u8 *)memalign(PAGE_ALGIN_SIZE, size);
502 	if (!buffer) {
503 		printf("[Vendor ERROR]:Malloc failed!\n");
504 		ret = -ENOMEM;
505 		goto out;
506 	}
507 
508 	/* Pointer initialization */
509 	vendor_info.hdr = (struct vendor_hdr *)buffer;
510 	vendor_info.item = (struct vendor_item *)(buffer + sizeof(struct vendor_hdr));
511 	vendor_info.data = buffer + data_offset;
512 	vendor_info.hash = (u32 *)(buffer + hash_offset);
513 	vendor_info.version2 = (u32 *)(buffer + version2_offset);
514 
515 #ifdef CONFIG_MTD_BLK
516 	if (dev_desc->if_type == IF_TYPE_MTD) {
517 		ret = mtd_vendor_storage_init(dev_desc);
518 		goto out;
519 	}
520 #endif
521 
522 	/* Find valid and up-to-date one from (vendor0 - vendor3) */
523 	for (i = 0; i < part_num; i++) {
524 		ret_size = vendor_ops((u8 *)vendor_info.hdr,
525 				      part_size * i, part_size, 0);
526 		if (ret_size != part_size) {
527 			ret = -EIO;
528 			goto out;
529 		}
530 
531 		if ((vendor_info.hdr->tag == VENDOR_TAG) &&
532 		    (*(vendor_info.version2) == vendor_info.hdr->version)) {
533 			if (max_ver < vendor_info.hdr->version) {
534 				max_index = i;
535 				max_ver = vendor_info.hdr->version;
536 			}
537 		}
538 	}
539 
540 	if (max_ver) {
541 		debug("[Vendor INFO]:max_ver=%d, vendor_id=%d.\n", max_ver, max_index);
542 		/*
543 		 * Keep vendor_info the same as the largest
544 		 * version of vendor
545 		 */
546 		if (max_index != (part_num - 1)) {
547 			ret_size = vendor_ops((u8 *)vendor_info.hdr,
548 					       part_size * max_index, part_size, 0);
549 			if (ret_size != part_size) {
550 				ret = -EIO;
551 				goto out;
552 			}
553 		}
554 	} else {
555 		debug("[Vendor INFO]:Reset vendor info...\n");
556 		memset((u8 *)vendor_info.hdr, 0, size);
557 		vendor_info.hdr->version = 1;
558 		vendor_info.hdr->tag = VENDOR_TAG;
559 		/* data field length */
560 		vendor_info.hdr->free_size =
561 			((u32)(size_t)vendor_info.hash
562 			- (u32)(size_t)vendor_info.data);
563 		*(vendor_info.version2) = vendor_info.hdr->version;
564 	}
565 	debug("[Vendor INFO]:ret=%d.\n", ret);
566 
567 out:
568 	if (ret)
569 		bootdev_type = 0;
570 
571 	return ret;
572 }
573 
vendor_storage_fixup(void * blob)574 void vendor_storage_fixup(void *blob)
575 {
576 	unsigned long size;
577 	unsigned long start;
578 	ulong offset;
579 
580 	/* init vendor storage */
581 	if (!bootdev_type) {
582 		if (vendor_storage_init() < 0)
583 			return;
584 	}
585 
586 	offset = fdt_node_offset_by_compatible(blob, 0, "rockchip,vendor-storage-rm");
587 	if (offset >= 0) {
588 		start = (unsigned long)vendor_info.hdr;
589 		size = (unsigned long)((void *)vendor_info.version2 - (void *)vendor_info.hdr);
590 		size += 4;
591 		fdt_update_reserved_memory(blob, "rockchip,vendor-storage-rm",
592 					   (u64)start,
593 					   (u64)size);
594 	}
595 }
596 
597 /*
598  * @id: item id, first 4 id is occupied:
599  *	VENDOR_SN_ID
600  *	VENDOR_WIFI_MAC_ID
601  *	VENDOR_LAN_MAC_ID
602  *	VENDOR_BLUETOOTH_ID
603  * @pbuf: read data buffer;
604  * @size: read bytes;
605  *
606  * return: bytes equal to @size is success, other fail;
607  */
vendor_storage_read(u16 id,void * pbuf,u16 size)608 int vendor_storage_read(u16 id, void *pbuf, u16 size)
609 {
610 	int ret = 0;
611 	u32 i;
612 	u16 offset;
613 	struct vendor_item *item;
614 
615 	/* init vendor storage */
616 	if (!bootdev_type) {
617 		ret = vendor_storage_init();
618 		if (ret < 0)
619 			return ret;
620 	}
621 
622 	item = vendor_info.item;
623 	for (i = 0; i < vendor_info.hdr->item_num; i++) {
624 		if ((item + i)->id == id) {
625 			debug("[Vendor INFO]:Find the matching item, id=%d\n", id);
626 			/* Correct the size value */
627 			if (size > (item + i)->size)
628 				size = (item + i)->size;
629 			offset = (item + i)->offset;
630 			memcpy(pbuf, (vendor_info.data + offset), size);
631 			return size;
632 		}
633 	}
634 	debug("[Vendor ERROR]:No matching item, id=%d\n", id);
635 
636 	return -EINVAL;
637 }
638 
639 /*
640  * @id: item id, first 4 id is occupied:
641  *	VENDOR_SN_ID
642  *	VENDOR_WIFI_MAC_ID
643  *	VENDOR_LAN_MAC_ID
644  *	VENDOR_BLUETOOTH_ID
645  * @pbuf: write data buffer;
646  * @size: write bytes;
647  *
648  * return: bytes equal to @size is success, other fail;
649  */
vendor_storage_write(u16 id,void * pbuf,u16 size)650 int vendor_storage_write(u16 id, void *pbuf, u16 size)
651 {
652 	int cnt, ret = 0;
653 	u32 i, next_index, align_size;
654 	struct vendor_item *item;
655 	u16 part_size, max_item_num, offset, part_num;
656 
657 	/* init vendor storage */
658 	if (!bootdev_type) {
659 		ret = vendor_storage_init();
660 		if (ret < 0)
661 			return ret;
662 	}
663 
664 	switch (bootdev_type) {
665 	case IF_TYPE_MMC:
666 		part_size = EMMC_VENDOR_PART_BLKS;
667 		max_item_num = EMMC_VENDOR_ITEM_NUM;
668 		part_num = VENDOR_PART_NUM;
669 		break;
670 	case IF_TYPE_RKNAND:
671 	case IF_TYPE_SPINAND:
672 		part_size = NAND_VENDOR_PART_BLKS;
673 		max_item_num = NAND_VENDOR_ITEM_NUM;
674 		part_num = NAND_VENDOR_PART_NUM;
675 		break;
676 	case IF_TYPE_SPINOR:
677 		part_size = FLASH_VENDOR_PART_BLKS;
678 		max_item_num = FLASH_VENDOR_ITEM_NUM;
679 		part_num = VENDOR_PART_NUM;
680 		break;
681 #ifdef CONFIG_MTD_BLK
682 	case IF_TYPE_MTD:
683 		part_size = FLASH_VENDOR_PART_BLKS;
684 		max_item_num = FLASH_VENDOR_ITEM_NUM;
685 		part_num = MTD_VENDOR_PART_NUM;
686 		break;
687 #endif
688 	default:
689 		ret = -ENODEV;
690 		break;
691 	}
692 	/* Invalid bootdev? */
693 	if (ret < 0)
694 		return ret;
695 
696 	next_index = vendor_info.hdr->next_index;
697 	/* algin to 64 bytes*/
698 	align_size = (size + VENDOR_BTYE_ALIGN) & (~VENDOR_BTYE_ALIGN);
699 	if (size > align_size)
700 		return -EINVAL;
701 
702 	item = vendor_info.item;
703 	/* If item already exist, update the item data */
704 	for (i = 0; i < vendor_info.hdr->item_num; i++) {
705 		if ((item + i)->id == id) {
706 			debug("[Vendor INFO]:Find the matching item, id=%d\n", id);
707 			offset = (item + i)->offset;
708 			memcpy((vendor_info.data + offset), pbuf, size);
709 			(item + i)->size = size;
710 			vendor_info.hdr->version++;
711 			*(vendor_info.version2) = vendor_info.hdr->version;
712 			vendor_info.hdr->next_index++;
713 			if (vendor_info.hdr->next_index >= part_num)
714 				vendor_info.hdr->next_index = 0;
715 			cnt = vendor_ops((u8 *)vendor_info.hdr, part_size * next_index, part_size, 1);
716 			return (cnt == part_size) ? size : -EIO;
717 		}
718 	}
719 	/*
720 	 * If item does not exist, and free size is enough,
721 	 * creat a new one
722 	 */
723 	if ((vendor_info.hdr->item_num < max_item_num) &&
724 	    (vendor_info.hdr->free_size >= align_size)) {
725 		debug("[Vendor INFO]:Create new Item, id=%d\n", id);
726 		item = vendor_info.item + vendor_info.hdr->item_num;
727 		item->id = id;
728 		item->offset = vendor_info.hdr->free_offset;
729 		item->size = size;
730 
731 		vendor_info.hdr->free_offset += align_size;
732 		vendor_info.hdr->free_size -= align_size;
733 		memcpy((vendor_info.data + item->offset), pbuf, size);
734 		vendor_info.hdr->item_num++;
735 		vendor_info.hdr->version++;
736 		vendor_info.hdr->next_index++;
737 		*(vendor_info.version2) = vendor_info.hdr->version;
738 		if (vendor_info.hdr->next_index >= part_num)
739 			vendor_info.hdr->next_index = 0;
740 
741 		cnt = vendor_ops((u8 *)vendor_info.hdr, part_size * next_index, part_size, 1);
742 		return (cnt == part_size) ? size : -EIO;
743 	}
744 	debug("[Vendor ERROR]:Vendor has no space left!\n");
745 
746 	return -ENOMEM;
747 }
748 
749 /**********************************************************/
750 /*              vendor API uinit test                      */
751 /**********************************************************/
752 /* Reset the vendor storage space to the initial state */
vendor_test_reset(void)753 static void vendor_test_reset(void)
754 {
755 	u16 i, part_size, part_num;
756 	u32 size;
757 
758 	switch (bootdev_type) {
759 	case IF_TYPE_MMC:
760 		size = EMMC_VENDOR_INFO_SIZE;
761 		part_size = EMMC_VENDOR_PART_BLKS;
762 		part_num = VENDOR_PART_NUM;
763 		break;
764 	case IF_TYPE_RKNAND:
765 	case IF_TYPE_SPINAND:
766 		size = NAND_VENDOR_INFO_SIZE;
767 		part_size = NAND_VENDOR_PART_BLKS;
768 		part_num = NAND_VENDOR_PART_NUM;
769 		break;
770 	case IF_TYPE_SPINOR:
771 		size = FLASH_VENDOR_INFO_SIZE;
772 		part_size = FLASH_VENDOR_PART_BLKS;
773 		part_num = VENDOR_PART_NUM;
774 		break;
775 	default:
776 		size = 0;
777 		part_size = 0;
778 		break;
779 	}
780 	/* Invalid bootdev? */
781 	if (!size)
782 		return;
783 
784 	memset((u8 *)vendor_info.hdr, 0, size);
785 	vendor_info.hdr->version = 1;
786 	vendor_info.hdr->tag = VENDOR_TAG;
787 	/* data field length */
788 	vendor_info.hdr->free_size = (unsigned long)vendor_info.hash -
789 				     (unsigned long)vendor_info.data;
790 	*(vendor_info.version2) = vendor_info.hdr->version;
791 	/* write to flash. */
792 	for (i = 0; i < part_num; i++)
793 		vendor_ops((u8 *)vendor_info.hdr, part_size * i, part_size, 1);
794 }
795 
796 /*
797  * A total of four tests
798  * 1.All items test.
799  * 2.Overrides the maximum number of items test.
800  * 3.Single Item memory overflow test.
801  * 4.Total memory overflow test.
802  */
vendor_storage_test(void)803 int vendor_storage_test(void)
804 {
805 	u16 id, size, j, item_num;
806 	u32 total_size;
807 	u8 *buffer = NULL;
808 	int ret = 0;
809 
810 	if (!bootdev_type) {
811 		ret = vendor_storage_init();
812 		if (ret) {
813 			printf("%s: vendor storage init failed, ret=%d\n",
814 			       __func__, ret);
815 			return ret;
816 		}
817 	}
818 
819 	/*
820 	 * Calculate the maximum number of items and the maximum
821 	 * allocable memory for each item.
822 	 */
823 	switch (bootdev_type) {
824 	case IF_TYPE_MMC:
825 		item_num = EMMC_VENDOR_ITEM_NUM;
826 		total_size = (unsigned long)vendor_info.hash -
827 			     (unsigned long)vendor_info.data;
828 		size = total_size / item_num;
829 		break;
830 	case IF_TYPE_RKNAND:
831 	case IF_TYPE_SPINAND:
832 		item_num = NAND_VENDOR_ITEM_NUM;
833 		total_size = (unsigned long)vendor_info.hash -
834 			     (unsigned long)vendor_info.data;
835 		size = total_size / item_num;
836 		break;
837 	case IF_TYPE_SPINOR:
838 	case IF_TYPE_MTD:
839 		item_num = FLASH_VENDOR_ITEM_NUM;
840 		total_size = (unsigned long)vendor_info.hash -
841 			     (unsigned long)vendor_info.data;
842 		size = total_size / item_num;
843 		break;
844 	default:
845 		item_num = 0;
846 		total_size = 0;
847 		size = 0;
848 		break;
849 	}
850 	/* Invalid bootdev? */
851 	if (!total_size)
852 		return -ENODEV;
853 	/* 64 bytes are aligned and rounded down */
854 	if (size > 64)
855 		size = (size / 64) * 64;
856 	/* malloc memory */
857 	buffer = (u8 *)malloc(size);
858 	if (!buffer) {
859 		printf("[Vendor Test]:Malloc failed(size=%d)!\n", size);
860 		return -ENOMEM;
861 	}
862 	printf("[Vendor Test]:Test Start...\n");
863 	printf("[Vendor Test]:Before Test, Vendor Resetting.\n");
864 	if (bootdev_type != IF_TYPE_MTD)
865 		vendor_test_reset();
866 
867 	/* FIRST TEST: test all items can be used correctly */
868 	printf("[Vendor Test]:<All Items Used> Test Start...\n");
869 	printf("[Vendor Test]:item_num=%d, size=%d.\n", item_num, size);
870 	/*
871 	 * Write data, then read the data, and compare the
872 	 * data consistency
873 	 */
874 	for (id = 0; id < item_num; id++) {
875 		memset(buffer, id, size);
876 		ret = vendor_storage_write(id, buffer, size);
877 		if (ret < 0) {
878 			printf("[Vendor Test]:vendor write failed(id=%d)!\n", id);
879 			free(buffer);
880 			return ret;
881 		}
882 	}
883 	/* Read data */
884 	for (id = 0; id < item_num; id++) {
885 		memset(buffer, 0, size);
886 		ret = vendor_storage_read(id, buffer, size);
887 		if (ret < 0) {
888 			printf("[Vendor Test]:vendor read failed(id=%d)!\n", id);
889 			free(buffer);
890 			return ret;
891 		}
892 		/* check data Correctness */
893 		for (j = 0; j < size; j++) {
894 			if (*(buffer + j) != id) {
895 				printf("[Vendor Test]:Unexpected error occurs(id=%d)\n", id);
896 				printf("the data content is:\n");
897 				print_buffer(0, buffer, 1, size, 16);
898 
899 				free(buffer);
900 				return -1;
901 			}
902 		}
903 		debug("\t#id=%03d success,data=0x%02x,size=%d.\n", id, *buffer, size);
904 	}
905 	printf("[Vendor Test]:<All Items Used> Test End,States:OK\n");
906 
907 	printf("[Vendor Test]:<All Items Used> re init,States:OK\n");
908 	ret = vendor_storage_init();
909 	/* Read data */
910 	for (id = 0; id < item_num; id++) {
911 		memset(buffer, 0, size);
912 		ret = vendor_storage_read(id, buffer, size);
913 		if (ret < 0) {
914 			printf("[Vendor Test]:vendor read failed(id=%d)!\n", id);
915 			free(buffer);
916 			return ret;
917 		}
918 		/* check data Correctness */
919 		for (j = 0; j < size; j++) {
920 			if (*(buffer + j) != id) {
921 				printf("[Vendor Test]:Unexpected error occurs(id=%d)\n", id);
922 				printf("the data content is:\n");
923 				print_buffer(0, buffer, 1, size, 16);
924 
925 				free(buffer);
926 				return -1;
927 			}
928 		}
929 		debug("\t#id=%03d success,data=0x%02x,size=%d.\n", id, *buffer, size);
930 	}
931 	printf("[Vendor Test]:<All Items Used> Test End,States:OK\n");
932 #ifdef CONFIG_MTD_BLK
933 	if (bootdev_type == IF_TYPE_MTD)
934 		return 0;
935 #endif
936 	/*
937 	 * SECOND TEST: Overrides the maximum number of items to see if the
938 	 * return value matches the expectation
939 	 */
940 	printf("[Vendor Test]:<Overflow Items Cnt> Test Start...\n");
941 	/* Any id value that was not used before */
942 	id = item_num;
943 	printf("[Vendor Test]:id=%d, size=%d.\n", id, size);
944 	ret = vendor_storage_write(id, buffer, size);
945 	if (ret == -ENOMEM)
946 		printf("[Vendor Test]:<Overflow Items Cnt> Test End,States:OK\n");
947 	else
948 		printf("[Vendor Test]:<Overflow Items Cnt> Test End,States:Failed\n");
949 
950 	/* free buffer, remalloc later */
951 	free(buffer);
952 	buffer = NULL;
953 	/*
954 	 * remalloc memory and recalculate size to test memory overflow
955 	 * (1) item_num > 10: Memory is divided into 10 blocks,
956 	 * 11th memory will overflow.
957 	 * (2) 10 > item_num > 1: Memory is divided into item_num-1
958 	 * blocks. item_num block, memory will overflow.
959 	 * (3) item_num = 1: size = total_size + 512 Bytes, The first
960 	 * block, memory will overflow.
961 	 * The reason to do so is to minimize the size of the memory,
962 	 * making malloc easier to perform successfully.
963 	 */
964 	item_num = (item_num > 10) ? 10 : (item_num - 1);
965 	size = item_num ? (total_size / item_num) : (total_size + 512);
966 	size = (size + VENDOR_BTYE_ALIGN) & (~VENDOR_BTYE_ALIGN);
967 	/* Find item_num value that can make the memory overflow */
968 	for (id = 0; id <= item_num; id++) {
969 		if (((id + 1) * size) > total_size) {
970 			item_num = id;
971 			break;
972 		}
973 	}
974 	/* malloc */
975 	buffer = (u8 *)malloc(size);
976 	if (buffer == NULL) {
977 		printf("[Vendor Test]:Malloc failed(size=%d)!\n", size);
978 		return -ENOMEM;
979 	}
980 
981 	/* THIRD TEST: Single Item memory overflow test */
982 	printf("[Vendor Test]:<Single Item Memory Overflow> Test Start...\n");
983 	/* The value can be arbitrary */
984 	memset(buffer, 'a', size);
985 	/* Any id value that was used before */
986 	id = 0;
987 	printf("[Vendor Test]:id=%d, size=%d.\n", id, size);
988 	ret = vendor_storage_write(id, buffer, size);
989 	if (ret == size)
990 		printf("[Vendor Test]:<Single Item Memory Overflow> Test End, States:OK\n");
991 	else
992 		printf("[Vendor Test]:<Single Item Memory Overflow> Test End, States:Failed\n");
993 
994 	/* FORTH TEST: Total memory overflow test */
995 	printf("[Vendor Test]:<Total memory overflow> Test Start...\n");
996 	printf("[Vendor Test]:item_num=%d, size=%d.\n", item_num, size);
997 
998 	vendor_test_reset();
999 	for (id = 0; id < item_num; id++) {
1000 		memset(buffer, id, size);
1001 		ret = vendor_storage_write(id, buffer, size);
1002 		if (ret < 0) {
1003 			if ((id == item_num) && (ret == -ENOMEM)) {
1004 				printf("[Vendor Test]:<Total memory overflow> Test End, States:OK\n");
1005 				break;
1006 			} else {
1007 				printf("[Vendor Test]:<Total memory overflow> Test End, States:Failed\n");
1008 				break;
1009 			}
1010 		}
1011 		debug("\t#id=%03d success,data=0x%02x,size=%d.\n", id, *buffer, size);
1012 	}
1013 
1014 	/* Test end */
1015 	printf("[Vendor Test]:After Test, Vendor Resetting...\n");
1016 	vendor_test_reset();
1017 	printf("[Vendor Test]:Test End.\n");
1018 	free(buffer);
1019 
1020 	return 0;
1021 }
1022