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));
98 ut_asserteq(map_to_sysmem(hdr), TEST_ADDR);
100 /* Add a record and check that we can find it */
101 data = bloblist_add(TEST_TAG, TEST_SIZE);
102 rec = (void *)(hdr + 1);
103 ut_asserteq_addr(rec + 1, data);
104 data = bloblist_find(TEST_TAG, TEST_SIZE);
105 ut_asserteq_addr(rec + 1, data);
107 /* Check the data is zeroed */
108 ut_assertok(check_zero(data, TEST_SIZE));
110 /* Check the 'ensure' method */
111 ut_asserteq_addr(data, bloblist_ensure(TEST_TAG, TEST_SIZE));
112 ut_assertnull(bloblist_ensure(TEST_TAG, TEST_SIZE2));
113 rec2 = (struct bloblist_rec *)(data + ALIGN(TEST_SIZE, BLOBLIST_ALIGN));
114 ut_assertok(check_zero(data, TEST_SIZE));
116 /* Check for a non-existent record */
117 ut_asserteq_addr(data, bloblist_ensure(TEST_TAG, TEST_SIZE));
118 ut_asserteq_addr(rec2 + 1, bloblist_ensure(TEST_TAG2, TEST_SIZE2));
119 ut_assertnull(bloblist_find(TEST_TAG_MISSING, 0));
123 BLOBLIST_TEST(bloblist_test_blob, 0);
125 /* Check bloblist_ensure_size_ret() */
126 static int bloblist_test_blob_ensure(struct unit_test_state *uts)
131 /* At the start there should be no records */
133 ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
135 /* Test with an empty bloblist */
137 ut_assertok(bloblist_ensure_size_ret(TEST_TAG, &size, &data));
138 ut_asserteq(TEST_SIZE, size);
139 ut_assertok(check_zero(data, TEST_SIZE));
141 /* Check that we get the same thing again */
142 ut_assertok(bloblist_ensure_size_ret(TEST_TAG, &size, &data2));
143 ut_asserteq(TEST_SIZE, size);
144 ut_asserteq_addr(data, data2);
146 /* Check that the size remains the same */
148 ut_assertok(bloblist_ensure_size_ret(TEST_TAG, &size, &data));
149 ut_asserteq(TEST_SIZE, size);
151 /* Check running out of space */
152 size = TEST_SIZE_LARGE;
153 ut_asserteq(-ENOSPC, bloblist_ensure_size_ret(TEST_TAG2, &size, &data));
157 BLOBLIST_TEST(bloblist_test_blob_ensure, 0);
159 static int bloblist_test_bad_blob(struct unit_test_state *uts)
161 struct bloblist_hdr *hdr;
164 hdr = clear_bloblist();
165 ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
167 data += sizeof(struct bloblist_rec);
168 ut_asserteq_addr(data, bloblist_ensure(TEST_TAG, TEST_SIZE));
169 ut_asserteq_addr(data, bloblist_ensure(TEST_TAG, TEST_SIZE));
173 BLOBLIST_TEST(bloblist_test_bad_blob, 0);
175 static int bloblist_test_checksum(struct unit_test_state *uts)
177 struct bloblist_hdr *hdr;
180 hdr = clear_bloblist();
181 ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
182 ut_assertok(bloblist_finish());
183 ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
186 * Now change things amd make sure that the checksum notices. We cannot
187 * change the size or alloced fields, since that will crash the code.
188 * It has to rely on these being correct.
191 ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
195 ut_asserteq(-EFBIG, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
199 ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
203 ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
206 /* Make sure the checksum changes when we add blobs */
207 data = bloblist_add(TEST_TAG, TEST_SIZE);
208 ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
210 data2 = bloblist_add(TEST_TAG2, TEST_SIZE2);
211 ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
212 ut_assertok(bloblist_finish());
214 /* It should also change if we change the data */
215 ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
217 ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
220 ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
222 ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
226 * Changing data outside the range of valid data should not affect
229 ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
232 ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
236 BLOBLIST_TEST(bloblist_test_checksum, 0);
238 /* Test the 'bloblist info' command */
239 static int bloblist_test_cmd_info(struct unit_test_state *uts)
241 struct sandbox_state *state = state_get_current();
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 if (!state->show_test_output)
252 gd->flags |= GD_FLG_SILENT;
253 console_record_reset();
254 run_command("bloblist info", 0);
255 ut_assert_nextline("base: %lx", (ulong)map_to_sysmem(hdr));
256 ut_assert_nextline("size: 100 256 Bytes");
257 ut_assert_nextline("alloced: 70 112 Bytes");
258 ut_assert_nextline("free: 90 144 Bytes");
259 ut_assert_console_end();
260 gd->flags &= ~(GD_FLG_SILENT | GD_FLG_RECORD);
264 BLOBLIST_TEST(bloblist_test_cmd_info, 0);
266 /* Test the 'bloblist list' command */
267 static int bloblist_test_cmd_list(struct unit_test_state *uts)
269 struct sandbox_state *state = state_get_current();
270 struct bloblist_hdr *hdr;
273 hdr = clear_bloblist();
274 ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
275 data = bloblist_ensure(TEST_TAG, TEST_SIZE);
276 data2 = bloblist_ensure(TEST_TAG2, TEST_SIZE2);
278 console_record_reset_enable();
279 if (!state->show_test_output)
280 gd->flags |= GD_FLG_SILENT;
281 console_record_reset();
282 run_command("bloblist list", 0);
283 ut_assert_nextline("Address Size Tag Name");
284 ut_assert_nextline("%08lx %8x 1 EC host event",
285 (ulong)map_to_sysmem(data), TEST_SIZE);
286 ut_assert_nextline("%08lx %8x 2 SPL hand-off",
287 (ulong)map_to_sysmem(data2), TEST_SIZE2);
288 ut_assert_console_end();
289 gd->flags &= ~(GD_FLG_SILENT | GD_FLG_RECORD);
293 BLOBLIST_TEST(bloblist_test_cmd_list, 0);
295 int do_ut_bloblist(struct cmd_tbl *cmdtp, int flag, int argc,
298 struct unit_test *tests = ll_entry_start(struct unit_test,
300 const int n_ents = ll_entry_count(struct unit_test, bloblist_test);
302 return cmd_ut_category("bloblist", "bloblist_test_",
303 tests, n_ents, argc, argv);