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