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