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
SPL_IMG_TEST(spl_test_image, IMX8, 0);
SPL_IMG_TEST(spl_test_image, FIT_INTERNAL, 0);
SPL_IMG_TEST(spl_test_image, FIT_EXTERNAL, 0);
+
+int do_spl_test_load(struct unit_test_state *uts, const char *test_name,
+ enum spl_test_image type, struct spl_image_loader *loader,
+ int (*write_image)(struct unit_test_state *, void *, size_t))
+{
+ size_t img_size, img_data, plain_size = SPL_TEST_DATA_SIZE;
+ struct spl_image_info info_write = {
+ .name = test_name,
+ .size = plain_size,
+ }, info_read = { };
+ struct spl_boot_device bootdev = {
+ .boot_device = loader->boot_device,
+ };
+ char *plain;
+ void *img;
+
+ img_size = create_image(NULL, type, &info_write, &img_data);
+ ut_assert(img_size);
+ img = calloc(img_size, 1);
+ ut_assertnonnull(img);
+
+ plain = img + img_data;
+ generate_data(plain, plain_size, test_name);
+ ut_asserteq(img_size, create_image(img, type, &info_write, NULL));
+
+ if (write_image(uts, img, img_size))
+ return CMD_RET_FAILURE;
+
+ ut_assertok(loader->load_image(&info_read, &bootdev));
+ if (check_image_info(uts, &info_write, &info_read))
+ return CMD_RET_FAILURE;
+ ut_asserteq_mem(plain, phys_to_virt(info_write.load_addr), plain_size);
+
+ free(img);
+ return 0;
+}
}
SPL_TEST(spl_test_fat, DM_FLAGS);
+static bool spl_mmc_raw;
+
+u32 spl_mmc_boot_mode(struct mmc *mmc, const u32 boot_device)
+{
+ return spl_mmc_raw ? MMCSD_MODE_RAW : MMCSD_MODE_FS;
+}
+
static int spl_test_mmc_fs(struct unit_test_state *uts, const char *test_name,
- enum spl_test_image type, create_fs_t create_fs)
+ enum spl_test_image type, create_fs_t create_fs,
+ bool blk_mode)
{
const char *filename = CONFIG_SPL_FS_LOAD_PAYLOAD_NAME;
struct blk_desc *dev_desc;
.start = 1,
.sys_ind = 0x83,
};
- struct spl_boot_device bootdev = { };
+ struct spl_image_loader *loader =
+ SPL_LOAD_IMAGE_GET(0, BOOT_DEVICE_MMC1, spl_mmc_load_image);
+ struct spl_boot_device bootdev = {
+ .boot_device = loader->boot_device,
+ };
void *fs;
char *data;
ut_assertok(write_mbr_partitions(dev_desc, &part, 1, 0));
ut_asserteq(part.size, blk_dwrite(dev_desc, part.start, part.size, fs));
- ut_assertok(spl_blk_load_image(&info_read, &bootdev, UCLASS_MMC, 0, 1));
+ spl_mmc_raw = false;
+ if (blk_mode)
+ ut_assertok(spl_blk_load_image(&info_read, &bootdev, UCLASS_MMC,
+ 0, 1));
+ else
+ ut_assertok(loader->load_image(&info_read, &bootdev));
if (check_image_info(uts, &info_write, &info_read))
return CMD_RET_FAILURE;
ut_asserteq_mem(data, phys_to_virt(info_write.load_addr), data_size);
enum spl_test_image type)
{
spl_fat_force_reregister();
- if (spl_test_mmc_fs(uts, test_name, type, create_fat))
+ if (spl_test_mmc_fs(uts, test_name, type, create_fat, true))
return CMD_RET_FAILURE;
- return spl_test_mmc_fs(uts, test_name, type, create_ext2);
+ return spl_test_mmc_fs(uts, test_name, type, create_ext2, true);
}
SPL_IMG_TEST(spl_test_blk, LEGACY, DM_FLAGS);
SPL_IMG_TEST(spl_test_blk, FIT_EXTERNAL, DM_FLAGS);
SPL_IMG_TEST(spl_test_blk, FIT_INTERNAL, DM_FLAGS);
+
+static int spl_test_mmc_write_image(struct unit_test_state *uts, void *img,
+ size_t img_size)
+{
+ struct blk_desc *dev_desc;
+ size_t img_blocks;
+
+ dev_desc = blk_get_devnum_by_uclass_id(UCLASS_MMC, 0);
+ ut_assertnonnull(dev_desc);
+
+ img_blocks = DIV_ROUND_UP(img_size, dev_desc->blksz);
+ ut_asserteq(img_blocks, blk_dwrite(dev_desc,
+ CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR,
+ img_blocks, img));
+
+ spl_mmc_raw = true;
+ return 0;
+}
+
+static int spl_test_mmc(struct unit_test_state *uts, const char *test_name,
+ enum spl_test_image type)
+{
+ spl_mmc_clear_cache();
+ spl_fat_force_reregister();
+
+ if (type == LEGACY &&
+ spl_test_mmc_fs(uts, test_name, type, create_ext2, false))
+ return CMD_RET_FAILURE;
+
+ if (type != IMX8 &&
+ spl_test_mmc_fs(uts, test_name, type, create_fat, false))
+ return CMD_RET_FAILURE;
+
+ return do_spl_test_load(uts, test_name, type,
+ SPL_LOAD_IMAGE_GET(0, BOOT_DEVICE_MMC1,
+ spl_mmc_load_image),
+ spl_test_mmc_write_image);
+}
+SPL_IMG_TEST(spl_test_mmc, LEGACY, DM_FLAGS);
+SPL_IMG_TEST(spl_test_mmc, IMX8, DM_FLAGS);
+SPL_IMG_TEST(spl_test_mmc, FIT_EXTERNAL, DM_FLAGS);
+SPL_IMG_TEST(spl_test_mmc, FIT_INTERNAL, DM_FLAGS);