| // SPDX-License-Identifier: GPL-2.0+ | |
| /* | |
| * Copyright (c) 2018, Google Inc. All rights reserved. | |
| */ | |
| #include <bloblist.h> | |
| #include <log.h> | |
| #include <mapmem.h> | |
| #include <test/test.h> | |
| #include <test/ut.h> | |
| /* Declare a new bloblist test */ | |
| #define BLOBLIST_TEST(_name, _flags) \ | |
| UNIT_TEST(_name, _flags, bloblist) | |
| enum { | |
| TEST_TAG = BLOBLISTT_U_BOOT_SPL_HANDOFF, | |
| TEST_TAG2 = BLOBLISTT_VBOOT_CTX, | |
| TEST_TAG_MISSING = 0x10000, | |
| TEST_SIZE = 10, | |
| TEST_SIZE2 = 20, | |
| TEST_SIZE_LARGE = 0x3e0, | |
| TEST_ADDR = CONFIG_BLOBLIST_ADDR, | |
| TEST_BLOBLIST_SIZE = 0x400, | |
| ERASE_BYTE = '\xff', | |
| }; | |
| static const char test1_str[] = "the eyes are open"; | |
| static const char test2_str[] = "the mouth moves"; | |
| static struct bloblist_hdr *clear_bloblist(void) | |
| { | |
| struct bloblist_hdr *hdr; | |
| /* | |
| * Clear out any existing bloblist so we have a clean slate. Zero the | |
| * header so that existing records are removed, but set everything else | |
| * to 0xff for testing purposes. | |
| */ | |
| hdr = map_sysmem(CONFIG_BLOBLIST_ADDR, TEST_BLOBLIST_SIZE); | |
| memset(hdr, ERASE_BYTE, TEST_BLOBLIST_SIZE); | |
| memset(hdr, '\0', sizeof(*hdr)); | |
| return hdr; | |
| } | |
| static int check_zero(void *data, int size) | |
| { | |
| u8 *ptr; | |
| int i; | |
| for (ptr = data, i = 0; i < size; i++, ptr++) { | |
| if (*ptr) | |
| return -EINVAL; | |
| } | |
| return 0; | |
| } | |
| static int bloblist_test_init(struct unit_test_state *uts) | |
| { | |
| struct bloblist_hdr *hdr; | |
| hdr = clear_bloblist(); | |
| ut_asserteq(-ENOENT, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); | |
| ut_asserteq_ptr(NULL, bloblist_check_magic(TEST_ADDR)); | |
| ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0, 0)); | |
| ut_asserteq_ptr(hdr, bloblist_check_magic(TEST_ADDR)); | |
| hdr->version++; | |
| ut_asserteq(-EPROTONOSUPPORT, bloblist_check(TEST_ADDR, | |
| TEST_BLOBLIST_SIZE)); | |
| ut_asserteq(-ENOSPC, bloblist_new(TEST_ADDR, 0xc, 0, 0)); | |
| ut_asserteq(-EFAULT, bloblist_new(1, TEST_BLOBLIST_SIZE, 0, 0)); | |
| ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0, 0)); | |
| ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); | |
| ut_assertok(bloblist_finish()); | |
| ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); | |
| hdr->magic++; | |
| ut_asserteq_ptr(NULL, bloblist_check_magic(TEST_ADDR)); | |
| hdr->magic--; | |
| hdr->flags++; | |
| ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); | |
| return 1; | |
| } | |
| BLOBLIST_TEST(bloblist_test_init, UFT_BLOBLIST); | |
| static int bloblist_test_blob(struct unit_test_state *uts) | |
| { | |
| struct bloblist_hdr *hdr; | |
| struct bloblist_rec *rec, *rec2; | |
| char *data; | |
| int size = 0; | |
| /* At the start there should be no records */ | |
| hdr = clear_bloblist(); | |
| ut_assertnull(bloblist_find(TEST_TAG, TEST_BLOBLIST_SIZE)); | |
| ut_assertnull(bloblist_get_blob(TEST_TAG, &size)); | |
| ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0, 0)); | |
| ut_asserteq(sizeof(struct bloblist_hdr), bloblist_get_size()); | |
| ut_asserteq(TEST_BLOBLIST_SIZE, bloblist_get_total_size()); | |
| ut_asserteq(TEST_ADDR, bloblist_get_base()); | |
| ut_asserteq(map_to_sysmem(hdr), TEST_ADDR); | |
| /* Add a record and check that we can find it */ | |
| data = bloblist_add(TEST_TAG, TEST_SIZE, 0); | |
| rec = (void *)(hdr + 1); | |
| ut_asserteq_addr(rec + 1, data); | |
| data = bloblist_find(TEST_TAG, TEST_SIZE); | |
| ut_asserteq_addr(rec + 1, data); | |
| ut_asserteq_addr(bloblist_get_blob(TEST_TAG, &size), data); | |
| ut_asserteq(size, TEST_SIZE); | |
| /* Check the data is zeroed */ | |
| ut_assertok(check_zero(data, TEST_SIZE)); | |
| /* Check the 'ensure' method */ | |
| ut_asserteq_addr(data, bloblist_ensure(TEST_TAG, TEST_SIZE)); | |
| ut_assertnull(bloblist_ensure(TEST_TAG, TEST_SIZE2)); | |
| rec2 = (struct bloblist_rec *)(data + ALIGN(TEST_SIZE, BLOBLIST_ALIGN)); | |
| ut_assertok(check_zero(data, TEST_SIZE)); | |
| /* Check for a non-existent record */ | |
| ut_asserteq_addr(data, bloblist_ensure(TEST_TAG, TEST_SIZE)); | |
| ut_asserteq_addr(rec2 + 1, bloblist_ensure(TEST_TAG2, TEST_SIZE2)); | |
| ut_assertnull(bloblist_find(TEST_TAG_MISSING, 0)); | |
| return 0; | |
| } | |
| BLOBLIST_TEST(bloblist_test_blob, UFT_BLOBLIST); | |
| /* Check bloblist_ensure_size_ret() */ | |
| static int bloblist_test_blob_ensure(struct unit_test_state *uts) | |
| { | |
| void *data, *data2; | |
| int size; | |
| /* At the start there should be no records */ | |
| clear_bloblist(); | |
| ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0, 0)); | |
| /* Test with an empty bloblist */ | |
| size = TEST_SIZE; | |
| ut_assertok(bloblist_ensure_size_ret(TEST_TAG, &size, &data)); | |
| ut_asserteq(TEST_SIZE, size); | |
| ut_assertok(check_zero(data, TEST_SIZE)); | |
| /* Check that we get the same thing again */ | |
| ut_assertok(bloblist_ensure_size_ret(TEST_TAG, &size, &data2)); | |
| ut_asserteq(TEST_SIZE, size); | |
| ut_asserteq_addr(data, data2); | |
| /* Check that the size remains the same */ | |
| size = TEST_SIZE2; | |
| ut_assertok(bloblist_ensure_size_ret(TEST_TAG, &size, &data)); | |
| ut_asserteq(TEST_SIZE, size); | |
| /* Check running out of space */ | |
| size = TEST_SIZE_LARGE; | |
| ut_asserteq(-ENOSPC, bloblist_ensure_size_ret(TEST_TAG2, &size, &data)); | |
| return 0; | |
| } | |
| BLOBLIST_TEST(bloblist_test_blob_ensure, UFT_BLOBLIST); | |
| static int bloblist_test_bad_blob(struct unit_test_state *uts) | |
| { | |
| struct bloblist_hdr *hdr; | |
| void *data; | |
| hdr = clear_bloblist(); | |
| ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0, 0)); | |
| data = hdr + 1; | |
| data += sizeof(struct bloblist_rec); | |
| ut_asserteq_addr(data, bloblist_ensure(TEST_TAG, TEST_SIZE)); | |
| ut_asserteq_addr(data, bloblist_ensure(TEST_TAG, TEST_SIZE)); | |
| return 0; | |
| } | |
| BLOBLIST_TEST(bloblist_test_bad_blob, UFT_BLOBLIST); | |
| static int bloblist_test_checksum(struct unit_test_state *uts) | |
| { | |
| struct bloblist_hdr *hdr; | |
| char *data, *data2; | |
| hdr = clear_bloblist(); | |
| ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0, 0)); | |
| ut_assertok(bloblist_finish()); | |
| ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); | |
| /* | |
| * Now change things amd make sure that the checksum notices. We cannot | |
| * change the size or alloced fields, since that will crash the code. | |
| * It has to rely on these being correct. | |
| */ | |
| hdr->flags--; | |
| ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); | |
| hdr->flags++; | |
| hdr->total_size--; | |
| ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); | |
| hdr->total_size++; | |
| hdr->spare++; | |
| ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); | |
| hdr->spare--; | |
| hdr->chksum++; | |
| ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); | |
| hdr->chksum--; | |
| hdr->align_log2++; | |
| ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); | |
| hdr->align_log2--; | |
| /* Make sure the checksum changes when we add blobs */ | |
| data = bloblist_add(TEST_TAG, TEST_SIZE, 0); | |
| ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); | |
| data2 = bloblist_add(TEST_TAG2, TEST_SIZE2, 0); | |
| ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); | |
| ut_assertok(bloblist_finish()); | |
| /* It should also change if we change the data */ | |
| ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); | |
| *data += 1; | |
| ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); | |
| *data -= 1; | |
| ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); | |
| *data2 += 1; | |
| ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); | |
| *data2 -= 1; | |
| /* | |
| * Changing data outside the range of valid data should affect the | |
| * checksum. | |
| */ | |
| ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); | |
| data[TEST_SIZE]++; | |
| ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); | |
| data[TEST_SIZE]--; | |
| ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); | |
| data2[TEST_SIZE2]++; | |
| ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); | |
| data[TEST_SIZE]--; | |
| ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); | |
| return 0; | |
| } | |
| BLOBLIST_TEST(bloblist_test_checksum, UFT_BLOBLIST); | |
| /* Test the 'bloblist info' command */ | |
| static int bloblist_test_cmd_info(struct unit_test_state *uts) | |
| { | |
| struct bloblist_hdr *hdr; | |
| char *data, *data2; | |
| hdr = clear_bloblist(); | |
| ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0, 0)); | |
| data = bloblist_ensure(TEST_TAG, TEST_SIZE); | |
| data2 = bloblist_ensure(TEST_TAG2, TEST_SIZE2); | |
| run_command("bloblist info", 0); | |
| ut_assert_nextline("base: %lx", (ulong)map_to_sysmem(hdr)); | |
| ut_assert_nextline("total size: 400 1 KiB"); | |
| ut_assert_nextline("used size: 50 80 Bytes"); | |
| ut_assert_nextline("free: 3b0 944 Bytes"); | |
| return 0; | |
| } | |
| BLOBLIST_TEST(bloblist_test_cmd_info, UFT_BLOBLIST | UTF_CONSOLE); | |
| /* Test the 'bloblist list' command */ | |
| static int bloblist_test_cmd_list(struct unit_test_state *uts) | |
| { | |
| struct bloblist_hdr *hdr; | |
| char *data, *data2; | |
| hdr = clear_bloblist(); | |
| ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0, 0)); | |
| data = bloblist_ensure(TEST_TAG, TEST_SIZE); | |
| data2 = bloblist_ensure(TEST_TAG2, TEST_SIZE2); | |
| run_command("bloblist list", 0); | |
| ut_assert_nextline("Address Size Tag Name"); | |
| ut_assert_nextline("%08lx %8x fff000 SPL hand-off", | |
| (ulong)map_to_sysmem(data), TEST_SIZE); | |
| ut_assert_nextline("%08lx %8x 202 Chrome OS vboot context", | |
| (ulong)map_to_sysmem(data2), TEST_SIZE2); | |
| return 0; | |
| } | |
| BLOBLIST_TEST(bloblist_test_cmd_list, UFT_BLOBLIST | UTF_CONSOLE); | |
| /* Test alignment of bloblist blobs */ | |
| static int bloblist_test_align(struct unit_test_state *uts) | |
| { | |
| struct bloblist_hdr *hdr; | |
| ulong addr; | |
| char *data; | |
| int i; | |
| /* At the start there should be no records */ | |
| hdr = clear_bloblist(); | |
| ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0, 0)); | |
| ut_assertnull(bloblist_find(TEST_TAG, TEST_BLOBLIST_SIZE)); | |
| /* Check the default alignment */ | |
| for (i = 0; i < 3; i++) { | |
| int size = i * 3; | |
| ulong addr; | |
| char *data; | |
| int j; | |
| data = bloblist_add(i, size, 0); | |
| ut_assertnonnull(data); | |
| addr = map_to_sysmem(data); | |
| ut_asserteq(0, addr & (BLOBLIST_BLOB_ALIGN - 1)); | |
| /* Only the bytes in the blob data should be zeroed */ | |
| for (j = 0; j < size; j++) | |
| ut_asserteq(0, data[j]); | |
| for (; j < BLOBLIST_BLOB_ALIGN; j++) | |
| ut_asserteq(ERASE_BYTE, data[j]); | |
| } | |
| /* Check larger alignment */ | |
| for (i = 0; i < 3; i++) { | |
| int align = 5 - i; | |
| data = bloblist_add(3 + i, i * 4, align); | |
| ut_assertnonnull(data); | |
| addr = map_to_sysmem(data); | |
| ut_asserteq(0, addr & (align - 1)); | |
| } | |
| /* Check alignment with an bloblist starting on a smaller alignment */ | |
| hdr = map_sysmem(TEST_ADDR + BLOBLIST_BLOB_ALIGN, TEST_BLOBLIST_SIZE); | |
| memset(hdr, ERASE_BYTE, TEST_BLOBLIST_SIZE); | |
| memset(hdr, '\0', sizeof(*hdr)); | |
| ut_assertok(bloblist_new(TEST_ADDR + BLOBLIST_ALIGN, TEST_BLOBLIST_SIZE, | |
| 0, 0)); | |
| data = bloblist_add(1, 5, BLOBLIST_ALIGN_LOG2 + 1); | |
| ut_assertnonnull(data); | |
| addr = map_to_sysmem(data); | |
| ut_asserteq(0, addr & (BLOBLIST_BLOB_ALIGN * 2 - 1)); | |
| return 0; | |
| } | |
| BLOBLIST_TEST(bloblist_test_align, UFT_BLOBLIST); | |
| /* Test relocation of a bloblist */ | |
| static int bloblist_test_reloc(struct unit_test_state *uts) | |
| { | |
| const uint large_size = TEST_BLOBLIST_SIZE; | |
| const uint small_size = 0x20; | |
| void *new_ptr; | |
| void *blob1, *blob2; | |
| ulong new_addr; | |
| ulong new_size; | |
| ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0, 0)); | |
| /* Add one blob and then one that won't fit */ | |
| blob1 = bloblist_add(TEST_TAG, small_size, 0); | |
| ut_assertnonnull(blob1); | |
| blob2 = bloblist_add(TEST_TAG2, large_size, 0); | |
| ut_assertnull(blob2); | |
| /* Relocate the bloblist somewhere else, a bit larger */ | |
| new_addr = TEST_ADDR + TEST_BLOBLIST_SIZE; | |
| new_size = TEST_BLOBLIST_SIZE + 0x100; | |
| new_ptr = map_sysmem(new_addr, TEST_BLOBLIST_SIZE); | |
| ut_assertok(bloblist_reloc(new_ptr, new_size)); | |
| /* Check the old blob is there and that we can now add the bigger one */ | |
| ut_assertnonnull(bloblist_find(TEST_TAG, small_size)); | |
| ut_assertnull(bloblist_find(TEST_TAG2, small_size)); | |
| blob2 = bloblist_add(TEST_TAG2, large_size, 0); | |
| ut_assertnonnull(blob2); | |
| return 0; | |
| } | |
| BLOBLIST_TEST(bloblist_test_reloc, UFT_BLOBLIST); | |
| /* Test expansion of a blob */ | |
| static int bloblist_test_grow(struct unit_test_state *uts) | |
| { | |
| const uint small_size = 0x20; | |
| void *blob1, *blob2, *blob1_new; | |
| struct bloblist_hdr *hdr; | |
| void *ptr; | |
| ptr = map_sysmem(TEST_ADDR, TEST_BLOBLIST_SIZE); | |
| hdr = ptr; | |
| memset(hdr, ERASE_BYTE, TEST_BLOBLIST_SIZE); | |
| /* Create two blobs */ | |
| ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0, 0)); | |
| blob1 = bloblist_add(TEST_TAG, small_size, 0); | |
| ut_assertnonnull(blob1); | |
| ut_assertok(check_zero(blob1, small_size)); | |
| strcpy(blob1, test1_str); | |
| blob2 = bloblist_add(TEST_TAG2, small_size, 0); | |
| ut_assertnonnull(blob2); | |
| strcpy(blob2, test2_str); | |
| ut_asserteq(sizeof(struct bloblist_hdr) + | |
| sizeof(struct bloblist_rec) * 2 + small_size * 2, | |
| hdr->used_size); | |
| /* Resize the first one */ | |
| ut_assertok(bloblist_resize(TEST_TAG, small_size + 4)); | |
| /* The first one should not have moved, just got larger */ | |
| blob1_new = bloblist_find(TEST_TAG, small_size + 4); | |
| ut_asserteq_ptr(blob1, blob1_new); | |
| /* The new space should be zeroed */ | |
| ut_assertok(check_zero(blob1 + small_size, 4)); | |
| /* The second one should have moved */ | |
| blob2 = bloblist_find(TEST_TAG2, small_size); | |
| ut_assertnonnull(blob2); | |
| ut_asserteq_str(test2_str, blob2); | |
| /* The header should have more bytes in use */ | |
| hdr = ptr; | |
| ut_asserteq(sizeof(struct bloblist_hdr) + | |
| sizeof(struct bloblist_rec) * 2 + small_size * 2 + | |
| BLOBLIST_BLOB_ALIGN, | |
| hdr->used_size); | |
| return 0; | |
| } | |
| BLOBLIST_TEST(bloblist_test_grow, UFT_BLOBLIST); | |
| /* Test shrinking of a blob */ | |
| static int bloblist_test_shrink(struct unit_test_state *uts) | |
| { | |
| const uint small_size = 0x20; | |
| void *blob1, *blob2, *blob1_new; | |
| struct bloblist_hdr *hdr; | |
| int new_size; | |
| void *ptr; | |
| ptr = map_sysmem(TEST_ADDR, TEST_BLOBLIST_SIZE); | |
| /* Create two blobs */ | |
| ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0, 0)); | |
| blob1 = bloblist_add(TEST_TAG, small_size, 0); | |
| ut_assertnonnull(blob1); | |
| strcpy(blob1, test1_str); | |
| blob2 = bloblist_add(TEST_TAG2, small_size, 0); | |
| ut_assertnonnull(blob2); | |
| strcpy(blob2, test2_str); | |
| hdr = ptr; | |
| ut_asserteq(sizeof(struct bloblist_hdr) + | |
| sizeof(struct bloblist_rec) * 2 + small_size * 2, | |
| hdr->used_size); | |
| /* Resize the first one */ | |
| new_size = small_size - BLOBLIST_ALIGN - 4; | |
| ut_assertok(bloblist_resize(TEST_TAG, new_size)); | |
| /* The first one should not have moved, just got smaller */ | |
| blob1_new = bloblist_find(TEST_TAG, new_size); | |
| ut_asserteq_ptr(blob1, blob1_new); | |
| /* The second one should have moved */ | |
| blob2 = bloblist_find(TEST_TAG2, small_size); | |
| ut_assertnonnull(blob2); | |
| ut_asserteq_str(test2_str, blob2); | |
| /* The header should have fewer bytes in use */ | |
| hdr = ptr; | |
| ut_asserteq(sizeof(struct bloblist_hdr) + | |
| sizeof(struct bloblist_rec) * 2 + small_size * 2 - | |
| BLOBLIST_ALIGN, | |
| hdr->used_size); | |
| return 0; | |
| } | |
| BLOBLIST_TEST(bloblist_test_shrink, UFT_BLOBLIST); | |
| /* Test failing to adjust a blob size */ | |
| static int bloblist_test_resize_fail(struct unit_test_state *uts) | |
| { | |
| const uint small_size = 0x20; | |
| struct bloblist_hdr *hdr; | |
| void *blob1, *blob2; | |
| int new_size; | |
| void *ptr; | |
| ptr = map_sysmem(TEST_ADDR, TEST_BLOBLIST_SIZE); | |
| /* Create two blobs */ | |
| ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0, 0)); | |
| blob1 = bloblist_add(TEST_TAG, small_size, 0); | |
| ut_assertnonnull(blob1); | |
| blob2 = bloblist_add(TEST_TAG2, small_size, 0); | |
| ut_assertnonnull(blob2); | |
| hdr = ptr; | |
| ut_asserteq(sizeof(struct bloblist_hdr) + | |
| sizeof(struct bloblist_rec) * 2 + small_size * 2, | |
| hdr->used_size); | |
| /* Resize the first one, to check the boundary conditions */ | |
| ut_asserteq(-EINVAL, bloblist_resize(TEST_TAG, -1)); | |
| new_size = small_size + (hdr->total_size - hdr->used_size); | |
| ut_asserteq(-ENOSPC, bloblist_resize(TEST_TAG, new_size + 1)); | |
| ut_assertok(bloblist_resize(TEST_TAG, new_size)); | |
| return 0; | |
| } | |
| BLOBLIST_TEST(bloblist_test_resize_fail, UFT_BLOBLIST); | |
| /* Test expanding the last blob in a bloblist */ | |
| static int bloblist_test_resize_last(struct unit_test_state *uts) | |
| { | |
| const uint small_size = 0x20; | |
| struct bloblist_hdr *hdr; | |
| void *blob1, *blob2, *blob2_new; | |
| int alloced_val; | |
| void *ptr; | |
| ptr = map_sysmem(TEST_ADDR, TEST_BLOBLIST_SIZE); | |
| memset(ptr, ERASE_BYTE, TEST_BLOBLIST_SIZE); | |
| hdr = ptr; | |
| /* Create two blobs */ | |
| ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0, 0)); | |
| blob1 = bloblist_add(TEST_TAG, small_size, 0); | |
| ut_assertnonnull(blob1); | |
| blob2 = bloblist_add(TEST_TAG2, small_size, 0); | |
| ut_assertnonnull(blob2); | |
| /* Check the byte after the last blob */ | |
| alloced_val = sizeof(struct bloblist_hdr) + | |
| sizeof(struct bloblist_rec) * 2 + small_size * 2; | |
| ut_asserteq(alloced_val, hdr->used_size); | |
| ut_asserteq_ptr((void *)hdr + alloced_val, blob2 + small_size); | |
| ut_asserteq((u8)ERASE_BYTE, *((u8 *)hdr + hdr->used_size)); | |
| /* Resize the second one, checking nothing changes */ | |
| ut_asserteq(0, bloblist_resize(TEST_TAG2, small_size + 4)); | |
| blob2_new = bloblist_find(TEST_TAG2, small_size + 4); | |
| ut_asserteq_ptr(blob2, blob2_new); | |
| /* | |
| * the new blob should encompass the byte we checked now, so it should | |
| * be zeroed. This zeroing should affect only the four new bytes added | |
| * to the blob. | |
| */ | |
| ut_asserteq(0, *((u8 *)hdr + alloced_val)); | |
| ut_asserteq((u8)ERASE_BYTE, *((u8 *)hdr + alloced_val + 4)); | |
| /* Check that the new top of the allocated blobs has not been touched */ | |
| alloced_val += BLOBLIST_BLOB_ALIGN; | |
| ut_asserteq(alloced_val, hdr->used_size); | |
| ut_asserteq((u8)ERASE_BYTE, *((u8 *)hdr + hdr->used_size)); | |
| return 0; | |
| } | |
| BLOBLIST_TEST(bloblist_test_resize_last, UFT_BLOBLIST); | |
| /* Check a completely full bloblist */ | |
| static int bloblist_test_blob_maxsize(struct unit_test_state *uts) | |
| { | |
| void *ptr; | |
| int size; | |
| /* At the start there should be no records */ | |
| clear_bloblist(); | |
| ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0, 0)); | |
| /* Add a blob that takes up all space */ | |
| size = TEST_BLOBLIST_SIZE - sizeof(struct bloblist_hdr) - | |
| sizeof(struct bloblist_rec); | |
| ptr = bloblist_add(TEST_TAG, size, 0); | |
| ut_assertnonnull(ptr); | |
| ptr = bloblist_add(TEST_TAG, size + 1, 0); | |
| ut_assertnull(ptr); | |
| return 0; | |
| } | |
| BLOBLIST_TEST(bloblist_test_blob_maxsize, UFT_BLOBLIST); |