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