u-boot/include/test/spl.h
Sean Anderson 65efaac425 test: spl: Add a test for the NOR load method
Add a test for the NOR load method. Since NOR is memory-mapped we can
substitute a buffer instead. The only major complication is testing LZMA
decompression.  It's too complex to implement LZMA compression in a test, and we
have no in-tree compressor, so we just include some pre-compressed data. This
data was generated through something like

    generate_data(plain, plain_size, "lzma")
    cat plain.dat | lzma | hexdump -C

and was cleaned up further in my editor.

Signed-off-by: Sean Anderson <seanga2@gmail.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
2023-10-17 20:50:52 -04:00

155 lines
4.7 KiB
C

/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (C) 2023 Sean Anderson <seanga2@gmail.com>
*/
#ifndef TEST_SPL_H
#define TEST_SPL_H
struct unit_test_state;
struct spl_image_info;
/* Declare a new SPL test */
#define SPL_TEST(_name, _flags) UNIT_TEST(_name, _flags, spl_test)
/**
* generate_data() - Generate some test payload data
* @data: The location to fill
* @size: The size of @data
* @test_name: The seed for the data
*
* Fill @data with data. The upper nibbles will be an incrementing counter
* (0x00, 0x10, 0x20...) to make the data identifiable in a hex dump. The lower
* nibbles are random bits seeded with @test_name.
*/
void generate_data(char *data, size_t size, const char *test_name);
/**
* enum spl_test_image - Image types for testing
* @LEGACY: "Legacy" uImages
* @LEGACY_LZMA: "Legacy" uImages, LZMA compressed
* @IMX8: i.MX8 Container images
* @FIT_INTERNAL: FITs with internal data
* @FIT_EXTERNAL: FITs with external data
*/
enum spl_test_image {
LEGACY,
LEGACY_LZMA,
IMX8,
FIT_INTERNAL,
FIT_EXTERNAL,
};
/**
* create_image() - Create an image for testing
* @dst: The location to create the image at
* @type: The type of image to create
* @info: Image parameters
* @data_offset: Offset of payload data within the image
*
* Create a new image at @dst. @dst must be initialized to all zeros. @info
* should already have name and size filled in. All other parameters will be
* filled in by this function. @info can later be passed to check_image_info().
*
* If @dst is %NULL, then no data is written. Otherwise, @dst must be
* initialized to zeros, except payload data which must already be present at
* @data_offset. @data_offset may be %NULL if unnecessary.
*
* Typically, this function will be called as follows:
*
* size = create_image(NULL, type, &info, &off);
* img = calloc(size, 1);
* generate_data(img + off, ...);
* create_image(img, type, &info, NULL);
*
* Return: The size of the image, or 0 on error
*/
size_t create_image(void *dst, enum spl_test_image type,
struct spl_image_info *info, size_t *data_offset);
/**
* check_image_info() - Check image info after loading
* @uts: Current unit test state
* @info1: The base, known good info
* @info2: The info to check
*
* Check @info2 against @info1. This function is typically called after calling
* a function to load/parse an image. Image data is not checked.
*
* Return: 0 on success, or 1 on failure
*/
int check_image_info(struct unit_test_state *uts, struct spl_image_info *info1,
struct spl_image_info *info2);
/**
* typedef write_image_t - Callback for writing an image
* @uts: Current unit test state
* @img: Image to write
* @size: Size of @img
*
* Write @img to a location which will be read by a &struct spl_image_loader.
*
* Return: 0 on success or 1 on failure
*/
typedef int write_image_t(struct unit_test_state *its, void *img, size_t size);
/**
* do_spl_test_load() - Test loading with an SPL image loader
* @uts: Current unit test state
* @test_name: Name of the current test
* @type: Type of image to try loading
* @loader: The loader to test
* @write_image: Callback to write the image to the backing storage
*
* Test @loader, performing the common tasks of setting up the image and
* checking it was loaded correctly. The caller must supply a @write_image
* callback to write the image to a location which will be read by @loader.
*
* Return: 0 on success or 1 on failure
*/
int do_spl_test_load(struct unit_test_state *uts, const char *test_name,
enum spl_test_image type, struct spl_image_loader *loader,
write_image_t write_image);
/**
* image_supported() - Determine whether an image type is supported
* @type: The image type to check
*
* Return: %true if supported and %false otherwise
*/
static inline bool image_supported(enum spl_test_image type)
{
switch (type) {
case LEGACY_LZMA:
if (!IS_ENABLED(CONFIG_SPL_LZMA))
return false;
case LEGACY:
return IS_ENABLED(CONFIG_SPL_LEGACY_IMAGE_FORMAT);
case IMX8:
return IS_ENABLED(CONFIG_SPL_LOAD_IMX_CONTAINER);
case FIT_INTERNAL:
case FIT_EXTERNAL:
return IS_ENABLED(CONFIG_SPL_LOAD_FIT) ||
IS_ENABLED(CONFIG_SPL_LOAD_FIT_FULL);
}
return false;
}
/* Declare an image test (skipped if the image type is unsupported) */
#define SPL_IMG_TEST(func, type, flags) \
static int func##_##type(struct unit_test_state *uts) \
{ \
if (!image_supported(type)) \
return -EAGAIN; \
return func(uts, __func__, type); \
} \
SPL_TEST(func##_##type, flags)
/* More than a couple blocks, and will not be aligned to anything */
#define SPL_TEST_DATA_SIZE 4099
/* Flags necessary for accessing DM devices */
#define DM_FLAGS (UT_TESTF_DM | UT_TESTF_SCAN_FDT)
#endif /* TEST_SPL_H */