1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (c) 2018, Google Inc. All rights reserved.
10 #include <asm/state.h>
11 #include <test/suites.h>
12 #include <test/test.h>
15 DECLARE_GLOBAL_DATA_PTR;
17 /* Declare a new compression test */
18 #define BLOBLIST_TEST(_name, _flags) \
19 UNIT_TEST(_name, _flags, bloblist_test)
28 TEST_SIZE_LARGE = 0xe0,
30 TEST_ADDR = CONFIG_BLOBLIST_ADDR,
31 TEST_BLOBLIST_SIZE = 0x100,
34 static struct bloblist_hdr *clear_bloblist(void)
36 struct bloblist_hdr *hdr;
39 * Clear out any existing bloblist so we have a clean slate. Zero the
40 * header so that existing records are removed, but set everything else
41 * to 0xff for testing purposes.
43 hdr = map_sysmem(CONFIG_BLOBLIST_ADDR, TEST_BLOBLIST_SIZE);
44 memset(hdr, '\xff', TEST_BLOBLIST_SIZE);
45 memset(hdr, '\0', sizeof(*hdr));
50 static int check_zero(void *data, int size)
55 for (ptr = data, i = 0; i < size; i++, ptr++) {
63 static int bloblist_test_init(struct unit_test_state *uts)
65 struct bloblist_hdr *hdr;
67 hdr = clear_bloblist();
68 ut_asserteq(-ENOENT, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
69 ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
71 ut_asserteq(-EPROTONOSUPPORT, bloblist_check(TEST_ADDR,
74 ut_asserteq(-ENOSPC, bloblist_new(TEST_ADDR, 0x10, 0));
75 ut_asserteq(-EFAULT, bloblist_new(1, TEST_BLOBLIST_SIZE, 0));
76 ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
78 ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
79 ut_assertok(bloblist_finish());
80 ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
82 ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
86 BLOBLIST_TEST(bloblist_test_init, 0);
88 static int bloblist_test_blob(struct unit_test_state *uts)
90 struct bloblist_hdr *hdr;
91 struct bloblist_rec *rec, *rec2;
94 /* At the start there should be no records */
95 hdr = clear_bloblist();
96 ut_assertnull(bloblist_find(TEST_TAG, TEST_BLOBLIST_SIZE));
97 ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
99 /* Add a record and check that we can find it */
100 data = bloblist_add(TEST_TAG, TEST_SIZE);
101 rec = (void *)(hdr + 1);
102 ut_asserteq_ptr(rec + 1, data);
103 data = bloblist_find(TEST_TAG, TEST_SIZE);
104 ut_asserteq_ptr(rec + 1, data);
106 /* Check the data is zeroed */
107 ut_assertok(check_zero(data, TEST_SIZE));
109 /* Check the 'ensure' method */
110 ut_asserteq_ptr(data, bloblist_ensure(TEST_TAG, TEST_SIZE));
111 ut_assertnull(bloblist_ensure(TEST_TAG, TEST_SIZE2));
112 rec2 = (struct bloblist_rec *)(data + ALIGN(TEST_SIZE, BLOBLIST_ALIGN));
113 ut_assertok(check_zero(data, TEST_SIZE));
115 /* Check for a non-existent record */
116 ut_asserteq_ptr(data, bloblist_ensure(TEST_TAG, TEST_SIZE));
117 ut_asserteq_ptr(rec2 + 1, bloblist_ensure(TEST_TAG2, TEST_SIZE2));
118 ut_assertnull(bloblist_find(TEST_TAG_MISSING, 0));
122 BLOBLIST_TEST(bloblist_test_blob, 0);
124 /* Check bloblist_ensure_size_ret() */
125 static int bloblist_test_blob_ensure(struct unit_test_state *uts)
130 /* At the start there should be no records */
132 ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
134 /* Test with an empty bloblist */
136 ut_assertok(bloblist_ensure_size_ret(TEST_TAG, &size, &data));
137 ut_asserteq(TEST_SIZE, size);
138 ut_assertok(check_zero(data, TEST_SIZE));
140 /* Check that we get the same thing again */
141 ut_assertok(bloblist_ensure_size_ret(TEST_TAG, &size, &data2));
142 ut_asserteq(TEST_SIZE, size);
143 ut_asserteq_ptr(data, data2);
145 /* Check that the size remains the same */
147 ut_assertok(bloblist_ensure_size_ret(TEST_TAG, &size, &data));
148 ut_asserteq(TEST_SIZE, size);
150 /* Check running out of space */
151 size = TEST_SIZE_LARGE;
152 ut_asserteq(-ENOSPC, bloblist_ensure_size_ret(TEST_TAG2, &size, &data));
156 BLOBLIST_TEST(bloblist_test_blob_ensure, 0);
158 static int bloblist_test_bad_blob(struct unit_test_state *uts)
160 struct bloblist_hdr *hdr;
163 hdr = clear_bloblist();
164 ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
166 data += sizeof(struct bloblist_rec);
167 ut_asserteq_ptr(data, bloblist_ensure(TEST_TAG, TEST_SIZE));
168 ut_asserteq_ptr(data, bloblist_ensure(TEST_TAG, TEST_SIZE));
172 BLOBLIST_TEST(bloblist_test_bad_blob, 0);
174 static int bloblist_test_checksum(struct unit_test_state *uts)
176 struct bloblist_hdr *hdr;
179 hdr = clear_bloblist();
180 ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
181 ut_assertok(bloblist_finish());
182 ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
185 * Now change things amd make sure that the checksum notices. We cannot
186 * change the size or alloced fields, since that will crash the code.
187 * It has to rely on these being correct.
190 ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
194 ut_asserteq(-EFBIG, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
198 ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
202 ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
205 /* Make sure the checksum changes when we add blobs */
206 data = bloblist_add(TEST_TAG, TEST_SIZE);
207 ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
209 data2 = bloblist_add(TEST_TAG2, TEST_SIZE2);
210 ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
211 ut_assertok(bloblist_finish());
213 /* It should also change if we change the data */
214 ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
216 ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
219 ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
221 ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
225 * Changing data outside the range of valid data should not affect
228 ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
231 ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
235 BLOBLIST_TEST(bloblist_test_checksum, 0);
237 /* Test the 'bloblist info' command */
238 static int bloblist_test_cmd_info(struct unit_test_state *uts)
240 struct sandbox_state *state = state_get_current();
241 struct bloblist_hdr *hdr;
244 hdr = clear_bloblist();
245 ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
246 data = bloblist_ensure(TEST_TAG, TEST_SIZE);
247 data2 = bloblist_ensure(TEST_TAG2, TEST_SIZE2);
249 console_record_reset_enable();
250 if (!state->show_test_output)
251 gd->flags |= GD_FLG_SILENT;
252 console_record_reset();
253 run_command("bloblist info", 0);
254 ut_assert_nextline("base: %x", map_to_sysmem(hdr));
255 ut_assert_nextline("size: 100 256 Bytes");
256 ut_assert_nextline("alloced: 70 112 Bytes");
257 ut_assert_nextline("free: 90 144 Bytes");
258 ut_assert_console_end();
259 gd->flags &= ~(GD_FLG_SILENT | GD_FLG_RECORD);
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 sandbox_state *state = state_get_current();
269 struct bloblist_hdr *hdr;
272 hdr = clear_bloblist();
273 ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
274 data = bloblist_ensure(TEST_TAG, TEST_SIZE);
275 data2 = bloblist_ensure(TEST_TAG2, TEST_SIZE2);
277 console_record_reset_enable();
278 if (!state->show_test_output)
279 gd->flags |= GD_FLG_SILENT;
280 console_record_reset();
281 run_command("bloblist list", 0);
282 ut_assert_nextline("Address Size Tag Name");
283 ut_assert_nextline("%08x %8x 1 EC host event", map_to_sysmem(data),
285 ut_assert_nextline("%08x %8x 2 SPL hand-off", map_to_sysmem(data2),
287 ut_assert_console_end();
288 gd->flags &= ~(GD_FLG_SILENT | GD_FLG_RECORD);
292 BLOBLIST_TEST(bloblist_test_cmd_list, 0);
294 int do_ut_bloblist(struct cmd_tbl *cmdtp, int flag, int argc,
297 struct unit_test *tests = ll_entry_start(struct unit_test,
299 const int n_ents = ll_entry_count(struct unit_test, bloblist_test);
301 return cmd_ut_category("bloblist", "bloblist_test_",
302 tests, n_ents, argc, argv);