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