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 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 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 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 /**********************************************************/ 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 */ 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 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 */ 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 */ 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 */ 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 */ 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