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