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