From: Sean Anderson Date: Sat, 14 Oct 2023 20:48:02 +0000 (-0400) Subject: test: spl: Add a test for the MMC load method X-Git-Url: http://git.dujemihanovic.xyz/img/sics.gif?a=commitdiff_plain;h=6ba8ecaa96cc4ede483a353b18c19715b27ba19a;p=u-boot.git test: spl: Add a test for the MMC load method Add a test for the MMC load method. This shows the general shape of tests to come: The main test function calls do_spl_test_load with an appropriate callback to write the image to the medium. Signed-off-by: Sean Anderson Reviewed-by: Simon Glass --- diff --git a/configs/sandbox_noinst_defconfig b/configs/sandbox_noinst_defconfig index 11be2dccf7..4f16d9860d 100644 --- a/configs/sandbox_noinst_defconfig +++ b/configs/sandbox_noinst_defconfig @@ -41,6 +41,8 @@ CONFIG_SPL_SYS_MALLOC=y CONFIG_SPL_HAS_CUSTOM_MALLOC_START=y CONFIG_SPL_CUSTOM_SYS_MALLOC_ADDR=0xa000000 CONFIG_SPL_SYS_MALLOC_SIZE=0x4000000 +CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y +CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x0 CONFIG_SPL_ENV_SUPPORT=y CONFIG_SPL_FS_EXT4=y CONFIG_SPL_I2C=y diff --git a/include/spl.h b/include/spl.h index 03a4a83eb2..ad1543ae16 100644 --- a/include/spl.h +++ b/include/spl.h @@ -673,6 +673,10 @@ static inline const char *spl_loader_name(const struct spl_image_loader *loader) } #endif +#define SPL_LOAD_IMAGE_GET(_priority, _boot_device, _method) \ + ll_entry_get(struct spl_image_loader, \ + _boot_device ## _priority ## _method, spl_image_loader) + /* SPL FAT image functions */ /** diff --git a/include/test/spl.h b/include/test/spl.h index 7dba3f03d0..009c6b3546 100644 --- a/include/test/spl.h +++ b/include/test/spl.h @@ -79,6 +79,36 @@ size_t create_image(void *dst, enum spl_test_image type, 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 diff --git a/test/image/Kconfig b/test/image/Kconfig index a52766b77d..e6be1b829f 100644 --- a/test/image/Kconfig +++ b/test/image/Kconfig @@ -18,6 +18,7 @@ config SPL_UT_LOAD_FS depends on SPL_FS_FAT depends on SPL_FS_EXT4 depends on SPL_MMC_WRITE + depends on SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR default y help Test filesystems and the various load methods which use them. diff --git a/test/image/spl_load.c b/test/image/spl_load.c index de2fddae35..d2ce66071b 100644 --- a/test/image/spl_load.c +++ b/test/image/spl_load.c @@ -365,3 +365,39 @@ SPL_IMG_TEST(spl_test_image, LEGACY, 0); 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; +} diff --git a/test/image/spl_load_fs.c b/test/image/spl_load_fs.c index a8b45bdbc4..297ab08a82 100644 --- a/test/image/spl_load_fs.c +++ b/test/image/spl_load_fs.c @@ -306,8 +306,16 @@ static int spl_test_fat(struct unit_test_state *uts) } 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; @@ -321,7 +329,11 @@ static int spl_test_mmc_fs(struct unit_test_state *uts, const char *test_name, .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; @@ -346,7 +358,12 @@ static int spl_test_mmc_fs(struct unit_test_state *uts, const char *test_name, 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); @@ -359,11 +376,53 @@ static int spl_test_blk(struct unit_test_state *uts, const char *test_name, 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);