1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (c) 2018, Google Inc. All rights reserved.
10 #include <test/suites.h>
11 #include <test/test.h>
14 DECLARE_GLOBAL_DATA_PTR;
16 /* Declare a new compression test */
17 #define BLOBLIST_TEST(_name, _flags) \
18 UNIT_TEST(_name, _flags, bloblist_test)
27 TEST_SIZE_LARGE = 0x3e0,
29 TEST_ADDR = CONFIG_BLOBLIST_ADDR,
30 TEST_BLOBLIST_SIZE = 0x400,
35 static struct bloblist_hdr *clear_bloblist(void)
37 struct bloblist_hdr *hdr;
40 * Clear out any existing bloblist so we have a clean slate. Zero the
41 * header so that existing records are removed, but set everything else
42 * to 0xff for testing purposes.
44 hdr = map_sysmem(CONFIG_BLOBLIST_ADDR, TEST_BLOBLIST_SIZE);
45 memset(hdr, ERASE_BYTE, TEST_BLOBLIST_SIZE);
46 memset(hdr, '\0', sizeof(*hdr));
51 static int check_zero(void *data, int size)
56 for (ptr = data, i = 0; i < size; i++, ptr++) {
64 static int bloblist_test_init(struct unit_test_state *uts)
66 struct bloblist_hdr *hdr;
68 hdr = clear_bloblist();
69 ut_asserteq(-ENOENT, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
70 ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
72 ut_asserteq(-EPROTONOSUPPORT, bloblist_check(TEST_ADDR,
75 ut_asserteq(-ENOSPC, bloblist_new(TEST_ADDR, 0x10, 0));
76 ut_asserteq(-EFAULT, bloblist_new(1, TEST_BLOBLIST_SIZE, 0));
77 ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
79 ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
80 ut_assertok(bloblist_finish());
81 ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
83 ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
87 BLOBLIST_TEST(bloblist_test_init, 0);
89 static int bloblist_test_blob(struct unit_test_state *uts)
91 struct bloblist_hdr *hdr;
92 struct bloblist_rec *rec, *rec2;
95 /* At the start there should be no records */
96 hdr = clear_bloblist();
97 ut_assertnull(bloblist_find(TEST_TAG, TEST_BLOBLIST_SIZE));
98 ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
99 ut_asserteq(map_to_sysmem(hdr), TEST_ADDR);
101 /* Add a record and check that we can find it */
102 data = bloblist_add(TEST_TAG, TEST_SIZE, 0);
103 rec = (void *)(hdr + 1);
104 ut_asserteq_addr(rec + 1, data);
105 data = bloblist_find(TEST_TAG, TEST_SIZE);
106 ut_asserteq_addr(rec + 1, data);
108 /* Check the data is zeroed */
109 ut_assertok(check_zero(data, TEST_SIZE));
111 /* Check the 'ensure' method */
112 ut_asserteq_addr(data, bloblist_ensure(TEST_TAG, TEST_SIZE));
113 ut_assertnull(bloblist_ensure(TEST_TAG, TEST_SIZE2));
114 rec2 = (struct bloblist_rec *)(data + ALIGN(TEST_SIZE, BLOBLIST_ALIGN));
115 ut_assertok(check_zero(data, TEST_SIZE));
117 /* Check for a non-existent record */
118 ut_asserteq_addr(data, bloblist_ensure(TEST_TAG, TEST_SIZE));
119 ut_asserteq_addr(rec2 + 1, bloblist_ensure(TEST_TAG2, TEST_SIZE2));
120 ut_assertnull(bloblist_find(TEST_TAG_MISSING, 0));
124 BLOBLIST_TEST(bloblist_test_blob, 0);
126 /* Check bloblist_ensure_size_ret() */
127 static int bloblist_test_blob_ensure(struct unit_test_state *uts)
132 /* At the start there should be no records */
134 ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
136 /* Test with an empty bloblist */
138 ut_assertok(bloblist_ensure_size_ret(TEST_TAG, &size, &data));
139 ut_asserteq(TEST_SIZE, size);
140 ut_assertok(check_zero(data, TEST_SIZE));
142 /* Check that we get the same thing again */
143 ut_assertok(bloblist_ensure_size_ret(TEST_TAG, &size, &data2));
144 ut_asserteq(TEST_SIZE, size);
145 ut_asserteq_addr(data, data2);
147 /* Check that the size remains the same */
149 ut_assertok(bloblist_ensure_size_ret(TEST_TAG, &size, &data));
150 ut_asserteq(TEST_SIZE, size);
152 /* Check running out of space */
153 size = TEST_SIZE_LARGE;
154 ut_asserteq(-ENOSPC, bloblist_ensure_size_ret(TEST_TAG2, &size, &data));
158 BLOBLIST_TEST(bloblist_test_blob_ensure, 0);
160 static int bloblist_test_bad_blob(struct unit_test_state *uts)
162 struct bloblist_hdr *hdr;
165 hdr = clear_bloblist();
166 ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
168 data += sizeof(struct bloblist_rec);
169 ut_asserteq_addr(data, bloblist_ensure(TEST_TAG, TEST_SIZE));
170 ut_asserteq_addr(data, bloblist_ensure(TEST_TAG, TEST_SIZE));
174 BLOBLIST_TEST(bloblist_test_bad_blob, 0);
176 static int bloblist_test_checksum(struct unit_test_state *uts)
178 struct bloblist_hdr *hdr;
181 hdr = clear_bloblist();
182 ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
183 ut_assertok(bloblist_finish());
184 ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
187 * Now change things amd make sure that the checksum notices. We cannot
188 * change the size or alloced fields, since that will crash the code.
189 * It has to rely on these being correct.
192 ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
196 ut_asserteq(-EFBIG, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
200 ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
204 ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
207 /* Make sure the checksum changes when we add blobs */
208 data = bloblist_add(TEST_TAG, TEST_SIZE, 0);
209 ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
211 data2 = bloblist_add(TEST_TAG2, TEST_SIZE2, 0);
212 ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
213 ut_assertok(bloblist_finish());
215 /* It should also change if we change the data */
216 ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
218 ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
221 ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
223 ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
227 * Changing data outside the range of valid data should not affect
230 ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
233 ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
237 BLOBLIST_TEST(bloblist_test_checksum, 0);
239 /* Test the 'bloblist info' command */
240 static int bloblist_test_cmd_info(struct unit_test_state *uts)
242 struct bloblist_hdr *hdr;
245 hdr = clear_bloblist();
246 ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
247 data = bloblist_ensure(TEST_TAG, TEST_SIZE);
248 data2 = bloblist_ensure(TEST_TAG2, TEST_SIZE2);
250 console_record_reset_enable();
251 ut_silence_console(uts);
252 console_record_reset();
253 run_command("bloblist info", 0);
254 ut_assert_nextline("base: %lx", (ulong)map_to_sysmem(hdr));
255 ut_assert_nextline("size: 400 1 KiB");
256 ut_assert_nextline("alloced: 70 112 Bytes");
257 ut_assert_nextline("free: 390 912 Bytes");
258 ut_assert_console_end();
259 ut_unsilence_console(uts);
263 BLOBLIST_TEST(bloblist_test_cmd_info, 0);
265 /* Test the 'bloblist list' command */
266 static int bloblist_test_cmd_list(struct unit_test_state *uts)
268 struct bloblist_hdr *hdr;
271 hdr = clear_bloblist();
272 ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
273 data = bloblist_ensure(TEST_TAG, TEST_SIZE);
274 data2 = bloblist_ensure(TEST_TAG2, TEST_SIZE2);
276 console_record_reset_enable();
277 ut_silence_console(uts);
278 console_record_reset();
279 run_command("bloblist list", 0);
280 ut_assert_nextline("Address Size Tag Name");
281 ut_assert_nextline("%08lx %8x 1 EC host event",
282 (ulong)map_to_sysmem(data), TEST_SIZE);
283 ut_assert_nextline("%08lx %8x 2 SPL hand-off",
284 (ulong)map_to_sysmem(data2), TEST_SIZE2);
285 ut_assert_console_end();
286 ut_unsilence_console(uts);
290 BLOBLIST_TEST(bloblist_test_cmd_list, 0);
292 /* Test alignment of bloblist blobs */
293 static int bloblist_test_align(struct unit_test_state *uts)
295 struct bloblist_hdr *hdr;
300 /* At the start there should be no records */
301 hdr = clear_bloblist();
302 ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
303 ut_assertnull(bloblist_find(TEST_TAG, TEST_BLOBLIST_SIZE));
305 /* Check the default alignment */
306 for (i = 0; i < 3; i++) {
312 data = bloblist_add(i, size, 0);
313 ut_assertnonnull(data);
314 addr = map_to_sysmem(data);
315 ut_asserteq(0, addr & (BLOBLIST_ALIGN - 1));
317 /* Only the bytes in the blob data should be zeroed */
318 for (j = 0; j < size; j++)
319 ut_asserteq(0, data[j]);
320 for (; j < BLOBLIST_ALIGN; j++)
321 ut_asserteq(ERASE_BYTE, data[j]);
324 /* Check larger alignment */
325 for (i = 0; i < 3; i++) {
328 data = bloblist_add(3 + i, i * 4, align);
329 ut_assertnonnull(data);
330 addr = map_to_sysmem(data);
331 ut_asserteq(0, addr & (align - 1));
334 /* Check alignment with an bloblist starting on a smaller alignment */
335 hdr = map_sysmem(TEST_ADDR + BLOBLIST_ALIGN, TEST_BLOBLIST_SIZE);
336 memset(hdr, ERASE_BYTE, TEST_BLOBLIST_SIZE);
337 memset(hdr, '\0', sizeof(*hdr));
338 ut_assertok(bloblist_new(TEST_ADDR + BLOBLIST_ALIGN, TEST_BLOBLIST_SIZE,
341 data = bloblist_add(1, 5, BLOBLIST_ALIGN * 2);
342 ut_assertnonnull(data);
343 addr = map_to_sysmem(data);
344 ut_asserteq(0, addr & (BLOBLIST_ALIGN * 2 - 1));
348 BLOBLIST_TEST(bloblist_test_align, 0);
350 int do_ut_bloblist(struct cmd_tbl *cmdtp, int flag, int argc,
353 struct unit_test *tests = ll_entry_start(struct unit_test,
355 const int n_ents = ll_entry_count(struct unit_test, bloblist_test);
357 return cmd_ut_category("bloblist", "bloblist_test_",
358 tests, n_ents, argc, argv);