1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Copyright (c) 2018, Google Inc. All rights reserved. 4 */ 5 6#include <common.h> 7#include <bloblist.h> 8#include <log.h> 9#include <mapmem.h> 10#include <asm/global_data.h> 11#include <test/suites.h> 12#include <test/test.h> 13#include <test/ut.h> 14 15DECLARE_GLOBAL_DATA_PTR; 16 17/* Declare a new bloblist test */ 18#define BLOBLIST_TEST(_name, _flags) \ 19 UNIT_TEST(_name, _flags, bloblist_test) 20 21enum { 22 TEST_TAG = BLOBLISTT_U_BOOT_SPL_HANDOFF, 23 TEST_TAG2 = BLOBLISTT_VBOOT_CTX, 24 TEST_TAG_MISSING = 0x10000, 25 26 TEST_SIZE = 10, 27 TEST_SIZE2 = 20, 28 TEST_SIZE_LARGE = 0x3e0, 29 30 TEST_ADDR = CONFIG_BLOBLIST_ADDR, 31 TEST_BLOBLIST_SIZE = 0x400, 32 33 ERASE_BYTE = '\xff', 34}; 35 36static const char test1_str[] = "the eyes are open"; 37static const char test2_str[] = "the mouth moves"; 38 39static struct bloblist_hdr *clear_bloblist(void) 40{ 41 struct bloblist_hdr *hdr; 42 43 /* 44 * Clear out any existing bloblist so we have a clean slate. Zero the 45 * header so that existing records are removed, but set everything else 46 * to 0xff for testing purposes. 47 */ 48 hdr = map_sysmem(CONFIG_BLOBLIST_ADDR, TEST_BLOBLIST_SIZE); 49 memset(hdr, ERASE_BYTE, TEST_BLOBLIST_SIZE); 50 memset(hdr, '\0', sizeof(*hdr)); 51 52 return hdr; 53} 54 55static int check_zero(void *data, int size) 56{ 57 u8 *ptr; 58 int i; 59 60 for (ptr = data, i = 0; i < size; i++, ptr++) { 61 if (*ptr) 62 return -EINVAL; 63 } 64 65 return 0; 66} 67 68static int bloblist_test_init(struct unit_test_state *uts) 69{ 70 struct bloblist_hdr *hdr; 71 72 hdr = clear_bloblist(); 73 ut_asserteq(-ENOENT, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); 74 ut_asserteq_ptr(NULL, bloblist_check_magic(TEST_ADDR)); 75 ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0, 0)); 76 ut_asserteq_ptr(hdr, bloblist_check_magic(TEST_ADDR)); 77 hdr->version++; 78 ut_asserteq(-EPROTONOSUPPORT, bloblist_check(TEST_ADDR, 79 TEST_BLOBLIST_SIZE)); 80 81 ut_asserteq(-ENOSPC, bloblist_new(TEST_ADDR, 0xc, 0, 0)); 82 ut_asserteq(-EFAULT, bloblist_new(1, TEST_BLOBLIST_SIZE, 0, 0)); 83 ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0, 0)); 84 85 ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); 86 ut_assertok(bloblist_finish()); 87 ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); 88 89 hdr->magic++; 90 ut_asserteq_ptr(NULL, bloblist_check_magic(TEST_ADDR)); 91 hdr->magic--; 92 93 hdr->flags++; 94 ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); 95 96 return 1; 97} 98BLOBLIST_TEST(bloblist_test_init, 0); 99 100static int bloblist_test_blob(struct unit_test_state *uts) 101{ 102 struct bloblist_hdr *hdr; 103 struct bloblist_rec *rec, *rec2; 104 char *data; 105 106 /* At the start there should be no records */ 107 hdr = clear_bloblist(); 108 ut_assertnull(bloblist_find(TEST_TAG, TEST_BLOBLIST_SIZE)); 109 ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0, 0)); 110 ut_asserteq(sizeof(struct bloblist_hdr), bloblist_get_size()); 111 ut_asserteq(TEST_BLOBLIST_SIZE, bloblist_get_total_size()); 112 ut_asserteq(TEST_ADDR, bloblist_get_base()); 113 ut_asserteq(map_to_sysmem(hdr), TEST_ADDR); 114 115 /* Add a record and check that we can find it */ 116 data = bloblist_add(TEST_TAG, TEST_SIZE, 0); 117 rec = (void *)(hdr + 1); 118 ut_asserteq_addr(rec + 1, data); 119 data = bloblist_find(TEST_TAG, TEST_SIZE); 120 ut_asserteq_addr(rec + 1, data); 121 122 /* Check the data is zeroed */ 123 ut_assertok(check_zero(data, TEST_SIZE)); 124 125 /* Check the 'ensure' method */ 126 ut_asserteq_addr(data, bloblist_ensure(TEST_TAG, TEST_SIZE)); 127 ut_assertnull(bloblist_ensure(TEST_TAG, TEST_SIZE2)); 128 rec2 = (struct bloblist_rec *)(data + ALIGN(TEST_SIZE, BLOBLIST_ALIGN)); 129 ut_assertok(check_zero(data, TEST_SIZE)); 130 131 /* Check for a non-existent record */ 132 ut_asserteq_addr(data, bloblist_ensure(TEST_TAG, TEST_SIZE)); 133 ut_asserteq_addr(rec2 + 1, bloblist_ensure(TEST_TAG2, TEST_SIZE2)); 134 ut_assertnull(bloblist_find(TEST_TAG_MISSING, 0)); 135 136 return 0; 137} 138BLOBLIST_TEST(bloblist_test_blob, 0); 139 140/* Check bloblist_ensure_size_ret() */ 141static int bloblist_test_blob_ensure(struct unit_test_state *uts) 142{ 143 void *data, *data2; 144 int size; 145 146 /* At the start there should be no records */ 147 clear_bloblist(); 148 ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0, 0)); 149 150 /* Test with an empty bloblist */ 151 size = TEST_SIZE; 152 ut_assertok(bloblist_ensure_size_ret(TEST_TAG, &size, &data)); 153 ut_asserteq(TEST_SIZE, size); 154 ut_assertok(check_zero(data, TEST_SIZE)); 155 156 /* Check that we get the same thing again */ 157 ut_assertok(bloblist_ensure_size_ret(TEST_TAG, &size, &data2)); 158 ut_asserteq(TEST_SIZE, size); 159 ut_asserteq_addr(data, data2); 160 161 /* Check that the size remains the same */ 162 size = TEST_SIZE2; 163 ut_assertok(bloblist_ensure_size_ret(TEST_TAG, &size, &data)); 164 ut_asserteq(TEST_SIZE, size); 165 166 /* Check running out of space */ 167 size = TEST_SIZE_LARGE; 168 ut_asserteq(-ENOSPC, bloblist_ensure_size_ret(TEST_TAG2, &size, &data)); 169 170 return 0; 171} 172BLOBLIST_TEST(bloblist_test_blob_ensure, 0); 173 174static int bloblist_test_bad_blob(struct unit_test_state *uts) 175{ 176 struct bloblist_hdr *hdr; 177 void *data; 178 179 hdr = clear_bloblist(); 180 ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0, 0)); 181 data = hdr + 1; 182 data += sizeof(struct bloblist_rec); 183 ut_asserteq_addr(data, bloblist_ensure(TEST_TAG, TEST_SIZE)); 184 ut_asserteq_addr(data, bloblist_ensure(TEST_TAG, TEST_SIZE)); 185 186 return 0; 187} 188BLOBLIST_TEST(bloblist_test_bad_blob, 0); 189 190static int bloblist_test_checksum(struct unit_test_state *uts) 191{ 192 struct bloblist_hdr *hdr; 193 char *data, *data2; 194 195 hdr = clear_bloblist(); 196 ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0, 0)); 197 ut_assertok(bloblist_finish()); 198 ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); 199 200 /* 201 * Now change things amd make sure that the checksum notices. We cannot 202 * change the size or alloced fields, since that will crash the code. 203 * It has to rely on these being correct. 204 */ 205 hdr->flags--; 206 ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); 207 hdr->flags++; 208 209 hdr->total_size--; 210 ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); 211 hdr->total_size++; 212 213 hdr->spare++; 214 ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); 215 hdr->spare--; 216 217 hdr->chksum++; 218 ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); 219 hdr->chksum--; 220 221 hdr->align_log2++; 222 ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); 223 hdr->align_log2--; 224 225 /* Make sure the checksum changes when we add blobs */ 226 data = bloblist_add(TEST_TAG, TEST_SIZE, 0); 227 ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); 228 229 data2 = bloblist_add(TEST_TAG2, TEST_SIZE2, 0); 230 ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); 231 ut_assertok(bloblist_finish()); 232 233 /* It should also change if we change the data */ 234 ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); 235 *data += 1; 236 ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); 237 *data -= 1; 238 239 ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); 240 *data2 += 1; 241 ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); 242 *data2 -= 1; 243 244 /* 245 * Changing data outside the range of valid data should affect the 246 * checksum. 247 */ 248 ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); 249 data[TEST_SIZE]++; 250 ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); 251 data[TEST_SIZE]--; 252 ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); 253 254 data2[TEST_SIZE2]++; 255 ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); 256 data[TEST_SIZE]--; 257 ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); 258 259 return 0; 260} 261BLOBLIST_TEST(bloblist_test_checksum, 0); 262 263/* Test the 'bloblist info' command */ 264static int bloblist_test_cmd_info(struct unit_test_state *uts) 265{ 266 struct bloblist_hdr *hdr; 267 char *data, *data2; 268 269 hdr = clear_bloblist(); 270 ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0, 0)); 271 data = bloblist_ensure(TEST_TAG, TEST_SIZE); 272 data2 = bloblist_ensure(TEST_TAG2, TEST_SIZE2); 273 274 console_record_reset_enable(); 275 ut_silence_console(uts); 276 console_record_reset(); 277 run_command("bloblist info", 0); 278 ut_assert_nextline("base: %lx", (ulong)map_to_sysmem(hdr)); 279 ut_assert_nextline("total size: 400 1 KiB"); 280 ut_assert_nextline("used size: 50 80 Bytes"); 281 ut_assert_nextline("free: 3b0 944 Bytes"); 282 ut_assert_console_end(); 283 ut_unsilence_console(uts); 284 285 return 0; 286} 287BLOBLIST_TEST(bloblist_test_cmd_info, 0); 288 289/* Test the 'bloblist list' command */ 290static int bloblist_test_cmd_list(struct unit_test_state *uts) 291{ 292 struct bloblist_hdr *hdr; 293 char *data, *data2; 294 295 hdr = clear_bloblist(); 296 ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0, 0)); 297 data = bloblist_ensure(TEST_TAG, TEST_SIZE); 298 data2 = bloblist_ensure(TEST_TAG2, TEST_SIZE2); 299 300 console_record_reset_enable(); 301 ut_silence_console(uts); 302 console_record_reset(); 303 run_command("bloblist list", 0); 304 ut_assert_nextline("Address Size Tag Name"); 305 ut_assert_nextline("%08lx %8x fff000 SPL hand-off", 306 (ulong)map_to_sysmem(data), TEST_SIZE); 307 ut_assert_nextline("%08lx %8x 202 Chrome OS vboot context", 308 (ulong)map_to_sysmem(data2), TEST_SIZE2); 309 ut_assert_console_end(); 310 ut_unsilence_console(uts); 311 312 return 0; 313} 314BLOBLIST_TEST(bloblist_test_cmd_list, 0); 315 316/* Test alignment of bloblist blobs */ 317static int bloblist_test_align(struct unit_test_state *uts) 318{ 319 struct bloblist_hdr *hdr; 320 ulong addr; 321 char *data; 322 int i; 323 324 /* At the start there should be no records */ 325 hdr = clear_bloblist(); 326 ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0, 0)); 327 ut_assertnull(bloblist_find(TEST_TAG, TEST_BLOBLIST_SIZE)); 328 329 /* Check the default alignment */ 330 for (i = 0; i < 3; i++) { 331 int size = i * 3; 332 ulong addr; 333 char *data; 334 int j; 335 336 data = bloblist_add(i, size, 0); 337 ut_assertnonnull(data); 338 addr = map_to_sysmem(data); 339 ut_asserteq(0, addr & (BLOBLIST_BLOB_ALIGN - 1)); 340 341 /* Only the bytes in the blob data should be zeroed */ 342 for (j = 0; j < size; j++) 343 ut_asserteq(0, data[j]); 344 for (; j < BLOBLIST_BLOB_ALIGN; j++) 345 ut_asserteq(ERASE_BYTE, data[j]); 346 } 347 348 /* Check larger alignment */ 349 for (i = 0; i < 3; i++) { 350 int align = 5 - i; 351 352 data = bloblist_add(3 + i, i * 4, align); 353 ut_assertnonnull(data); 354 addr = map_to_sysmem(data); 355 ut_asserteq(0, addr & (align - 1)); 356 } 357 358 /* Check alignment with an bloblist starting on a smaller alignment */ 359 hdr = map_sysmem(TEST_ADDR + BLOBLIST_BLOB_ALIGN, TEST_BLOBLIST_SIZE); 360 memset(hdr, ERASE_BYTE, TEST_BLOBLIST_SIZE); 361 memset(hdr, '\0', sizeof(*hdr)); 362 ut_assertok(bloblist_new(TEST_ADDR + BLOBLIST_ALIGN, TEST_BLOBLIST_SIZE, 363 0, 0)); 364 365 data = bloblist_add(1, 5, BLOBLIST_ALIGN_LOG2 + 1); 366 ut_assertnonnull(data); 367 addr = map_to_sysmem(data); 368 ut_asserteq(0, addr & (BLOBLIST_BLOB_ALIGN * 2 - 1)); 369 370 return 0; 371} 372BLOBLIST_TEST(bloblist_test_align, 0); 373 374/* Test relocation of a bloblist */ 375static int bloblist_test_reloc(struct unit_test_state *uts) 376{ 377 const uint large_size = TEST_BLOBLIST_SIZE; 378 const uint small_size = 0x20; 379 void *new_ptr; 380 void *blob1, *blob2; 381 ulong new_addr; 382 ulong new_size; 383 384 ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0, 0)); 385 386 /* Add one blob and then one that won't fit */ 387 blob1 = bloblist_add(TEST_TAG, small_size, 0); 388 ut_assertnonnull(blob1); 389 blob2 = bloblist_add(TEST_TAG2, large_size, 0); 390 ut_assertnull(blob2); 391 392 /* Relocate the bloblist somewhere else, a bit larger */ 393 new_addr = TEST_ADDR + TEST_BLOBLIST_SIZE; 394 new_size = TEST_BLOBLIST_SIZE + 0x100; 395 new_ptr = map_sysmem(new_addr, TEST_BLOBLIST_SIZE); 396 ut_assertok(bloblist_reloc(new_ptr, new_size)); 397 398 /* Check the old blob is there and that we can now add the bigger one */ 399 ut_assertnonnull(bloblist_find(TEST_TAG, small_size)); 400 ut_assertnull(bloblist_find(TEST_TAG2, small_size)); 401 blob2 = bloblist_add(TEST_TAG2, large_size, 0); 402 ut_assertnonnull(blob2); 403 404 return 0; 405} 406BLOBLIST_TEST(bloblist_test_reloc, 0); 407 408/* Test expansion of a blob */ 409static int bloblist_test_grow(struct unit_test_state *uts) 410{ 411 const uint small_size = 0x20; 412 void *blob1, *blob2, *blob1_new; 413 struct bloblist_hdr *hdr; 414 void *ptr; 415 416 ptr = map_sysmem(TEST_ADDR, TEST_BLOBLIST_SIZE); 417 hdr = ptr; 418 memset(hdr, ERASE_BYTE, TEST_BLOBLIST_SIZE); 419 420 /* Create two blobs */ 421 ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0, 0)); 422 blob1 = bloblist_add(TEST_TAG, small_size, 0); 423 ut_assertnonnull(blob1); 424 ut_assertok(check_zero(blob1, small_size)); 425 strcpy(blob1, test1_str); 426 427 blob2 = bloblist_add(TEST_TAG2, small_size, 0); 428 ut_assertnonnull(blob2); 429 strcpy(blob2, test2_str); 430 431 ut_asserteq(sizeof(struct bloblist_hdr) + 432 sizeof(struct bloblist_rec) * 2 + small_size * 2, 433 hdr->used_size); 434 435 /* Resize the first one */ 436 ut_assertok(bloblist_resize(TEST_TAG, small_size + 4)); 437 438 /* The first one should not have moved, just got larger */ 439 blob1_new = bloblist_find(TEST_TAG, small_size + 4); 440 ut_asserteq_ptr(blob1, blob1_new); 441 442 /* The new space should be zeroed */ 443 ut_assertok(check_zero(blob1 + small_size, 4)); 444 445 /* The second one should have moved */ 446 blob2 = bloblist_find(TEST_TAG2, small_size); 447 ut_assertnonnull(blob2); 448 ut_asserteq_str(test2_str, blob2); 449 450 /* The header should have more bytes in use */ 451 hdr = ptr; 452 ut_asserteq(sizeof(struct bloblist_hdr) + 453 sizeof(struct bloblist_rec) * 2 + small_size * 2 + 454 BLOBLIST_BLOB_ALIGN, 455 hdr->used_size); 456 457 return 0; 458} 459BLOBLIST_TEST(bloblist_test_grow, 0); 460 461/* Test shrinking of a blob */ 462static int bloblist_test_shrink(struct unit_test_state *uts) 463{ 464 const uint small_size = 0x20; 465 void *blob1, *blob2, *blob1_new; 466 struct bloblist_hdr *hdr; 467 int new_size; 468 void *ptr; 469 470 ptr = map_sysmem(TEST_ADDR, TEST_BLOBLIST_SIZE); 471 472 /* Create two blobs */ 473 ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0, 0)); 474 blob1 = bloblist_add(TEST_TAG, small_size, 0); 475 ut_assertnonnull(blob1); 476 strcpy(blob1, test1_str); 477 478 blob2 = bloblist_add(TEST_TAG2, small_size, 0); 479 ut_assertnonnull(blob2); 480 strcpy(blob2, test2_str); 481 482 hdr = ptr; 483 ut_asserteq(sizeof(struct bloblist_hdr) + 484 sizeof(struct bloblist_rec) * 2 + small_size * 2, 485 hdr->used_size); 486 487 /* Resize the first one */ 488 new_size = small_size - BLOBLIST_ALIGN - 4; 489 ut_assertok(bloblist_resize(TEST_TAG, new_size)); 490 491 /* The first one should not have moved, just got smaller */ 492 blob1_new = bloblist_find(TEST_TAG, new_size); 493 ut_asserteq_ptr(blob1, blob1_new); 494 495 /* The second one should have moved */ 496 blob2 = bloblist_find(TEST_TAG2, small_size); 497 ut_assertnonnull(blob2); 498 ut_asserteq_str(test2_str, blob2); 499 500 /* The header should have fewer bytes in use */ 501 hdr = ptr; 502 ut_asserteq(sizeof(struct bloblist_hdr) + 503 sizeof(struct bloblist_rec) * 2 + small_size * 2 - 504 BLOBLIST_ALIGN, 505 hdr->used_size); 506 507 return 0; 508} 509BLOBLIST_TEST(bloblist_test_shrink, 0); 510 511/* Test failing to adjust a blob size */ 512static int bloblist_test_resize_fail(struct unit_test_state *uts) 513{ 514 const uint small_size = 0x20; 515 struct bloblist_hdr *hdr; 516 void *blob1, *blob2; 517 int new_size; 518 void *ptr; 519 520 ptr = map_sysmem(TEST_ADDR, TEST_BLOBLIST_SIZE); 521 522 /* Create two blobs */ 523 ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0, 0)); 524 blob1 = bloblist_add(TEST_TAG, small_size, 0); 525 ut_assertnonnull(blob1); 526 527 blob2 = bloblist_add(TEST_TAG2, small_size, 0); 528 ut_assertnonnull(blob2); 529 530 hdr = ptr; 531 ut_asserteq(sizeof(struct bloblist_hdr) + 532 sizeof(struct bloblist_rec) * 2 + small_size * 2, 533 hdr->used_size); 534 535 /* Resize the first one, to check the boundary conditions */ 536 ut_asserteq(-EINVAL, bloblist_resize(TEST_TAG, -1)); 537 538 new_size = small_size + (hdr->total_size - hdr->used_size); 539 ut_asserteq(-ENOSPC, bloblist_resize(TEST_TAG, new_size + 1)); 540 ut_assertok(bloblist_resize(TEST_TAG, new_size)); 541 542 return 0; 543} 544BLOBLIST_TEST(bloblist_test_resize_fail, 0); 545 546/* Test expanding the last blob in a bloblist */ 547static int bloblist_test_resize_last(struct unit_test_state *uts) 548{ 549 const uint small_size = 0x20; 550 struct bloblist_hdr *hdr; 551 void *blob1, *blob2, *blob2_new; 552 int alloced_val; 553 void *ptr; 554 555 ptr = map_sysmem(TEST_ADDR, TEST_BLOBLIST_SIZE); 556 memset(ptr, ERASE_BYTE, TEST_BLOBLIST_SIZE); 557 hdr = ptr; 558 559 /* Create two blobs */ 560 ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0, 0)); 561 blob1 = bloblist_add(TEST_TAG, small_size, 0); 562 ut_assertnonnull(blob1); 563 564 blob2 = bloblist_add(TEST_TAG2, small_size, 0); 565 ut_assertnonnull(blob2); 566 567 /* Check the byte after the last blob */ 568 alloced_val = sizeof(struct bloblist_hdr) + 569 sizeof(struct bloblist_rec) * 2 + small_size * 2; 570 ut_asserteq(alloced_val, hdr->used_size); 571 ut_asserteq_ptr((void *)hdr + alloced_val, blob2 + small_size); 572 ut_asserteq((u8)ERASE_BYTE, *((u8 *)hdr + hdr->used_size)); 573 574 /* Resize the second one, checking nothing changes */ 575 ut_asserteq(0, bloblist_resize(TEST_TAG2, small_size + 4)); 576 577 blob2_new = bloblist_find(TEST_TAG2, small_size + 4); 578 ut_asserteq_ptr(blob2, blob2_new); 579 580 /* 581 * the new blob should encompass the byte we checked now, so it should 582 * be zeroed. This zeroing should affect only the four new bytes added 583 * to the blob. 584 */ 585 ut_asserteq(0, *((u8 *)hdr + alloced_val)); 586 ut_asserteq((u8)ERASE_BYTE, *((u8 *)hdr + alloced_val + 4)); 587 588 /* Check that the new top of the allocated blobs has not been touched */ 589 alloced_val += BLOBLIST_BLOB_ALIGN; 590 ut_asserteq(alloced_val, hdr->used_size); 591 ut_asserteq((u8)ERASE_BYTE, *((u8 *)hdr + hdr->used_size)); 592 593 return 0; 594} 595BLOBLIST_TEST(bloblist_test_resize_last, 0); 596 597/* Check a completely full bloblist */ 598static int bloblist_test_blob_maxsize(struct unit_test_state *uts) 599{ 600 void *ptr; 601 int size; 602 603 /* At the start there should be no records */ 604 clear_bloblist(); 605 ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0, 0)); 606 607 /* Add a blob that takes up all space */ 608 size = TEST_BLOBLIST_SIZE - sizeof(struct bloblist_hdr) - 609 sizeof(struct bloblist_rec); 610 ptr = bloblist_add(TEST_TAG, size, 0); 611 ut_assertnonnull(ptr); 612 613 ptr = bloblist_add(TEST_TAG, size + 1, 0); 614 ut_assertnull(ptr); 615 616 return 0; 617} 618BLOBLIST_TEST(bloblist_test_blob_maxsize, 0); 619 620int do_ut_bloblist(struct cmd_tbl *cmdtp, int flag, int argc, 621 char *const argv[]) 622{ 623 struct unit_test *tests = UNIT_TEST_SUITE_START(bloblist_test); 624 const int n_ents = UNIT_TEST_SUITE_COUNT(bloblist_test); 625 626 return cmd_ut_category("bloblist", "bloblist_test_", 627 tests, n_ents, argc, argv); 628} 629