mirror of
				https://github.com/smaeul/u-boot.git
				synced 2025-10-31 03:58:17 +00:00 
			
		
		
		
	It is convenient for bloblist to zero out the contents of a records when it is added. This saves the callers having to do it. Update the API accordingly. Signed-off-by: Simon Glass <sjg@chromium.org>
		
			
				
	
	
		
			246 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			246 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| // SPDX-License-Identifier: GPL-2.0+
 | |
| /*
 | |
|  * Copyright (c) 2018, Google Inc. All rights reserved.
 | |
|  */
 | |
| 
 | |
| #include <common.h>
 | |
| #include <bloblist.h>
 | |
| #include <log.h>
 | |
| #include <mapmem.h>
 | |
| #include <test/suites.h>
 | |
| #include <test/test.h>
 | |
| #include <test/ut.h>
 | |
| 
 | |
| DECLARE_GLOBAL_DATA_PTR;
 | |
| 
 | |
| /* Declare a new compression test */
 | |
| #define BLOBLIST_TEST(_name, _flags) \
 | |
| 		UNIT_TEST(_name, _flags, bloblist_test)
 | |
| 
 | |
| enum {
 | |
| 	TEST_TAG		= 1,
 | |
| 	TEST_TAG2		= 2,
 | |
| 	TEST_TAG_MISSING	= 3,
 | |
| 
 | |
| 	TEST_SIZE		= 10,
 | |
| 	TEST_SIZE2		= 20,
 | |
| 	TEST_SIZE_LARGE		= 0xe0,
 | |
| 
 | |
| 	TEST_ADDR		= CONFIG_BLOBLIST_ADDR,
 | |
| 	TEST_BLOBLIST_SIZE	= 0x100,
 | |
| };
 | |
| 
 | |
| 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, '\xff', 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_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
 | |
| 	hdr->version++;
 | |
| 	ut_asserteq(-EPROTONOSUPPORT, bloblist_check(TEST_ADDR,
 | |
| 						     TEST_BLOBLIST_SIZE));
 | |
| 
 | |
| 	ut_asserteq(-ENOSPC, bloblist_new(TEST_ADDR, 0x10, 0));
 | |
| 	ut_asserteq(-EFAULT, bloblist_new(1, TEST_BLOBLIST_SIZE, 0));
 | |
| 	ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 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->flags++;
 | |
| 	ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
 | |
| 
 | |
| 	return 1;
 | |
| }
 | |
| BLOBLIST_TEST(bloblist_test_init, 0);
 | |
| 
 | |
| static int bloblist_test_blob(struct unit_test_state *uts)
 | |
| {
 | |
| 	struct bloblist_hdr *hdr;
 | |
| 	struct bloblist_rec *rec, *rec2;
 | |
| 	char *data;
 | |
| 
 | |
| 	/* At the start there should be no records */
 | |
| 	hdr = clear_bloblist();
 | |
| 	ut_assertnull(bloblist_find(TEST_TAG, TEST_BLOBLIST_SIZE));
 | |
| 	ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
 | |
| 
 | |
| 	/* Add a record and check that we can find it */
 | |
| 	data = bloblist_add(TEST_TAG, TEST_SIZE);
 | |
| 	rec = (void *)(hdr + 1);
 | |
| 	ut_asserteq_ptr(rec + 1, data);
 | |
| 	data = bloblist_find(TEST_TAG, TEST_SIZE);
 | |
| 	ut_asserteq_ptr(rec + 1, data);
 | |
| 
 | |
| 	/* Check the data is zeroed */
 | |
| 	ut_assertok(check_zero(data, TEST_SIZE));
 | |
| 
 | |
| 	/* Check the 'ensure' method */
 | |
| 	ut_asserteq_ptr(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_ptr(data, bloblist_ensure(TEST_TAG, TEST_SIZE));
 | |
| 	ut_asserteq_ptr(rec2 + 1, bloblist_ensure(TEST_TAG2, TEST_SIZE2));
 | |
| 	ut_assertnull(bloblist_find(TEST_TAG_MISSING, 0));
 | |
| 
 | |
| 	return 0;
 | |
| }
 | |
| BLOBLIST_TEST(bloblist_test_blob, 0);
 | |
| 
 | |
| /* 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));
 | |
| 
 | |
| 	/* 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_ptr(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, 0);
 | |
| 
 | |
| 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));
 | |
| 	data = hdr + 1;
 | |
| 	data += sizeof(struct bloblist_rec);
 | |
| 	ut_asserteq_ptr(data, bloblist_ensure(TEST_TAG, TEST_SIZE));
 | |
| 	ut_asserteq_ptr(data, bloblist_ensure(TEST_TAG, TEST_SIZE));
 | |
| 
 | |
| 	return 0;
 | |
| }
 | |
| BLOBLIST_TEST(bloblist_test_bad_blob, 0);
 | |
| 
 | |
| 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));
 | |
| 	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->size--;
 | |
| 	ut_asserteq(-EFBIG, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
 | |
| 	hdr->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--;
 | |
| 
 | |
| 	/* Make sure the checksum changes when we add blobs */
 | |
| 	data = bloblist_add(TEST_TAG, TEST_SIZE);
 | |
| 	ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
 | |
| 
 | |
| 	data2 = bloblist_add(TEST_TAG2, TEST_SIZE2);
 | |
| 	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 not affect
 | |
| 	 * the checksum.
 | |
| 	 */
 | |
| 	ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
 | |
| 	data[TEST_SIZE]++;
 | |
| 	data2[TEST_SIZE2]++;
 | |
| 	ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
 | |
| 
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| BLOBLIST_TEST(bloblist_test_checksum, 0);
 | |
| 
 | |
| int do_ut_bloblist(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
 | |
| {
 | |
| 	struct unit_test *tests = ll_entry_start(struct unit_test,
 | |
| 						 bloblist_test);
 | |
| 	const int n_ents = ll_entry_count(struct unit_test, bloblist_test);
 | |
| 
 | |
| 	return cmd_ut_category("bloblist", "bloblist_test_",
 | |
| 			       tests, n_ents, argc, argv);
 | |
| }
 |