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