From 5271e359a46cc6a60d0048576326e2fa1527f231 Mon Sep 17 00:00:00 2001 From: Sean Anderson Date: Wed, 8 Nov 2023 11:48:43 -0500 Subject: [PATCH] spl: Only support bl_len when we have to Aligning addresses and sizes causes overhead which is unnecessary when we are not loading from block devices. Remove bl_len when it is not needed. For example, on iot2050 we save 144 bytes with this patch (once the rest of this series is applied): add/remove: 0/0 grow/shrink: 0/3 up/down: 0/-144 (-144) Function old new delta spl_load_simple_fit 920 904 -16 load_simple_fit 496 444 -52 spl_spi_load_image 384 308 -76 Total: Before=87431, After=87287, chg -0.16% We use panic() instead of BUILD_BUG_ON in spl_set_bl_len because we still need to be able to compile it for things like mmc_load_image_raw_sector, even if that function will not be used. Signed-off-by: Sean Anderson Reviewed-by: Simon Glass --- arch/arm/mach-imx/spl_imx_romapi.c | 8 ++++---- arch/arm/mach-sunxi/spl_spi_sunxi.c | 2 +- common/spl/Kconfig | 14 +++++++++++++- common/spl/spl_blk_fs.c | 2 +- common/spl/spl_fat.c | 2 +- common/spl/spl_fit.c | 6 +++--- common/spl/spl_imx_container.c | 10 +++++----- common/spl/spl_legacy.c | 4 ++-- common/spl/spl_mmc.c | 4 ++-- common/spl/spl_nand.c | 6 +++--- common/spl/spl_net.c | 2 +- common/spl/spl_nor.c | 8 ++++---- common/spl/spl_ram.c | 2 +- common/spl/spl_semihosting.c | 2 +- common/spl/spl_spi.c | 4 ++-- common/spl/spl_ymodem.c | 2 +- drivers/usb/gadget/f_sdp.c | 4 ++-- include/spl.h | 25 +++++++++++++++++++++++++ test/image/Kconfig | 1 + test/image/spl_load.c | 9 ++++----- test/image/spl_load_os.c | 2 +- 21 files changed, 78 insertions(+), 41 deletions(-) diff --git a/arch/arm/mach-imx/spl_imx_romapi.c b/arch/arm/mach-imx/spl_imx_romapi.c index d7f6cb4b5b..9f0968cdf7 100644 --- a/arch/arm/mach-imx/spl_imx_romapi.c +++ b/arch/arm/mach-imx/spl_imx_romapi.c @@ -101,7 +101,7 @@ static int spl_romapi_load_image_seekable(struct spl_image_info *spl_image, struct spl_load_info load; memset(&load, 0, sizeof(load)); - load.bl_len = pagesize; + spl_set_bl_len(&load, pagesize); load.read = spl_romapi_read_seekable; return spl_load_simple_fit(spl_image, &load, offset, header); } else if (IS_ENABLED(CONFIG_SPL_LOAD_IMX_CONTAINER) && @@ -109,7 +109,7 @@ static int spl_romapi_load_image_seekable(struct spl_image_info *spl_image, struct spl_load_info load; memset(&load, 0, sizeof(load)); - load.bl_len = pagesize; + spl_set_bl_len(&load, pagesize); load.read = spl_romapi_read_seekable; ret = spl_load_imx_container(spl_image, &load, offset); @@ -334,7 +334,7 @@ static int spl_romapi_load_image_stream(struct spl_image_info *spl_image, ss.pagesize = pagesize; memset(&load, 0, sizeof(load)); - load.bl_len = 1; + spl_set_bl_len(&load, 1); load.read = spl_romapi_read_stream; load.priv = &ss; @@ -358,7 +358,7 @@ static int spl_romapi_load_image_stream(struct spl_image_info *spl_image, printf("ROM download failure %d\n", imagesize); memset(&load, 0, sizeof(load)); - load.bl_len = 1; + spl_set_bl_len(&load, 1); load.read = spl_ram_load_read; if (IS_ENABLED(CONFIG_SPL_LOAD_IMX_CONTAINER)) diff --git a/arch/arm/mach-sunxi/spl_spi_sunxi.c b/arch/arm/mach-sunxi/spl_spi_sunxi.c index 5e7fba0c8e..267cb0b1ab 100644 --- a/arch/arm/mach-sunxi/spl_spi_sunxi.c +++ b/arch/arm/mach-sunxi/spl_spi_sunxi.c @@ -354,7 +354,7 @@ static int spl_spi_load_image(struct spl_image_info *spl_image, struct spl_load_info load; debug("Found FIT image\n"); - load.bl_len = 1; + spl_set_bl_len(&load, 1); load.read = spi_load_read; ret = spl_load_simple_fit(spl_image, &load, load_offset, header); diff --git a/common/spl/Kconfig b/common/spl/Kconfig index e929f1bbae..0bc57d5fed 100644 --- a/common/spl/Kconfig +++ b/common/spl/Kconfig @@ -280,8 +280,15 @@ config SPL_BOARD_INIT spl_board_init() from board_init_r(). This function should be provided by the board. +config SPL_LOAD_BLOCK + bool + help + Support loading images from block devices. This adds a bl_len member + to struct spl_load_info. + config SPL_BOOTROM_SUPPORT bool "Support returning to the BOOTROM" + select SPL_LOAD_BLOCK if MACH_IMX help Some platforms (e.g. the Rockchip RK3368) provide support in their ROM for loading the next boot-stage after performing basic setup @@ -482,6 +489,7 @@ config SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR ARCH_AT91 || ARCH_ZYNQ || ARCH_KEYSTONE || OMAP34XX || \ OMAP44XX || OMAP54XX || AM33XX || AM43XX || \ TARGET_SIFIVE_UNLEASHED || TARGET_SIFIVE_UNMATCHED + select SPL_LOAD_BLOCK if SPL_MMC help Use sector number for specifying U-Boot location on MMC/SD in raw mode. @@ -518,6 +526,7 @@ config SYS_MMCSD_RAW_MODE_U_BOOT_DATA_PART_OFFSET config SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION bool "MMC Raw mode: by partition" + select SPL_LOAD_BLOCK if SPL_MMC help Use a partition for loading U-Boot when using MMC/SD in raw mode. @@ -678,6 +687,7 @@ config SPL_FS_SQUASHFS config SPL_FS_FAT bool "Support FAT filesystems" select FS_FAT + select SPL_LOAD_BLOCK help Enable support for FAT and VFAT filesystems with SPL. This permits U-Boot (or Linux in Falcon mode) to be loaded from a FAT @@ -877,6 +887,7 @@ config SPL_MUSB_NEW config SPL_NAND_SUPPORT bool "Support NAND flash" + select SPL_LOAD_BLOCK help Enable support for NAND (Negative AND) flash in SPL. NAND flash can be used to allow SPL to load U-Boot from supported devices. @@ -1102,6 +1113,7 @@ config SYS_OS_BASE config SPL_FALCON_BOOT_MMCSD bool "Enable Falcon boot from MMC or SD media" depends on SPL_OS_BOOT && SPL_MMC + select SPL_LOAD_BLOCK help Select this if the Falcon mode OS image mode is on MMC or SD media. @@ -1260,9 +1272,9 @@ config SPL_SATA_RAW_U_BOOT_SECTOR config SPL_NVME bool "NVM Express device support" depends on BLK - select HAVE_BLOCK_DEVICE select FS_LOADER select SPL_BLK_FS + select SPL_LOAD_BLOCK help This option enables support for NVM Express devices. It supports basic functions of NVMe (read/write). diff --git a/common/spl/spl_blk_fs.c b/common/spl/spl_blk_fs.c index 4975ce4d6e..53b8e1b11b 100644 --- a/common/spl/spl_blk_fs.c +++ b/common/spl/spl_blk_fs.c @@ -87,7 +87,7 @@ int spl_blk_load_image(struct spl_image_info *spl_image, debug("Found FIT\n"); load.read = spl_fit_read; - load.bl_len = ARCH_DMA_MINALIGN; + spl_set_bl_len(&load, ARCH_DMA_MINALIGN); load.priv = &dev; dev.filename = filename; diff --git a/common/spl/spl_fat.c b/common/spl/spl_fat.c index 8a2c4e3af4..a0c34eba48 100644 --- a/common/spl/spl_fat.c +++ b/common/spl/spl_fat.c @@ -97,7 +97,7 @@ int spl_load_image_fat(struct spl_image_info *spl_image, debug("Found FIT\n"); load.read = spl_fit_read; - load.bl_len = ARCH_DMA_MINALIGN; + spl_set_bl_len(&load, ARCH_DMA_MINALIGN); load.priv = (void *)filename; return spl_load_simple_fit(spl_image, &load, 0, header); diff --git a/common/spl/spl_fit.c b/common/spl/spl_fit.c index 0df4e6d148..872df0c0fe 100644 --- a/common/spl/spl_fit.c +++ b/common/spl/spl_fit.c @@ -171,12 +171,12 @@ static int spl_fit_get_image_node(const struct spl_fit_info *ctx, static int get_aligned_image_offset(struct spl_load_info *info, int offset) { - return ALIGN_DOWN(offset, info->bl_len); + return ALIGN_DOWN(offset, spl_get_bl_len(info)); } static int get_aligned_image_overhead(struct spl_load_info *info, int offset) { - return offset & (info->bl_len - 1); + return offset & (spl_get_bl_len(info) - 1); } static int get_aligned_image_size(struct spl_load_info *info, int data_size, @@ -184,7 +184,7 @@ static int get_aligned_image_size(struct spl_load_info *info, int data_size, { data_size = data_size + get_aligned_image_overhead(info, offset); - return ALIGN(data_size, info->bl_len); + return ALIGN(data_size, spl_get_bl_len(info)); } /** diff --git a/common/spl/spl_imx_container.c b/common/spl/spl_imx_container.c index 7cd674f835..b4ea9241d6 100644 --- a/common/spl/spl_imx_container.c +++ b/common/spl/spl_imx_container.c @@ -32,13 +32,13 @@ static struct boot_img_t *read_auth_image(struct spl_image_info *spl_image, images = (struct boot_img_t *)((u8 *)container + sizeof(struct container_hdr)); - if (!IS_ALIGNED(images[image_index].offset, info->bl_len)) { + if (!IS_ALIGNED(images[image_index].offset, spl_get_bl_len(info))) { printf("%s: image%d offset not aligned to %u\n", - __func__, image_index, info->bl_len); + __func__, image_index, spl_get_bl_len(info)); return NULL; } - size = ALIGN(images[image_index].size, info->bl_len); + size = ALIGN(images[image_index].size, spl_get_bl_len(info)); offset = images[image_index].offset + container_offset; debug("%s: container: %p offset: %lu size: %lu\n", __func__, @@ -66,7 +66,7 @@ static int read_auth_container(struct spl_image_info *spl_image, u16 length; int i, size, ret = 0; - size = ALIGN(CONTAINER_HDR_ALIGNMENT, info->bl_len); + size = ALIGN(CONTAINER_HDR_ALIGNMENT, spl_get_bl_len(info)); /* * It will not override the ATF code, so safe to use it here, @@ -100,7 +100,7 @@ static int read_auth_container(struct spl_image_info *spl_image, debug("Container length %u\n", length); if (length > CONTAINER_HDR_ALIGNMENT) { - size = ALIGN(length, info->bl_len); + size = ALIGN(length, spl_get_bl_len(info)); free(container); container = malloc(size); diff --git a/common/spl/spl_legacy.c b/common/spl/spl_legacy.c index 9189576b77..75d9d82233 100644 --- a/common/spl/spl_legacy.c +++ b/common/spl/spl_legacy.c @@ -139,9 +139,9 @@ int spl_load_legacy_img(struct spl_image_info *spl_image, lzma_len = LZMA_LEN; /* dataptr points to compressed payload */ - dataptr = ALIGN_DOWN(sizeof(*hdr), load->bl_len); + dataptr = ALIGN_DOWN(sizeof(*hdr), spl_get_bl_len(load)); overhead = sizeof(*hdr) - dataptr; - size = ALIGN(spl_image->size + overhead, load->bl_len); + size = ALIGN(spl_image->size + overhead, spl_get_bl_len(load)); dataptr += offset; debug("LZMA: Decompressing %08lx to %08lx\n", diff --git a/common/spl/spl_mmc.c b/common/spl/spl_mmc.c index 8c4ffe743d..91272c03d3 100644 --- a/common/spl/spl_mmc.c +++ b/common/spl/spl_mmc.c @@ -108,7 +108,7 @@ int mmc_load_image_raw_sector(struct spl_image_info *spl_image, debug("Found FIT\n"); load.priv = bd; - load.bl_len = bd->blksz; + spl_set_bl_len(&load, bd->blksz); load.read = h_spl_load_read; ret = spl_load_simple_fit(spl_image, &load, sector << bd->log2blksz, header); @@ -117,7 +117,7 @@ int mmc_load_image_raw_sector(struct spl_image_info *spl_image, struct spl_load_info load; load.priv = bd; - load.bl_len = bd->blksz; + spl_set_bl_len(&load, bd->blksz); load.read = h_spl_load_read; ret = spl_load_imx_container(spl_image, &load, diff --git a/common/spl/spl_nand.c b/common/spl/spl_nand.c index 45d7c5f6cf..281211b7f2 100644 --- a/common/spl/spl_nand.c +++ b/common/spl/spl_nand.c @@ -90,7 +90,7 @@ static int spl_nand_load_element(struct spl_image_info *spl_image, debug("Found FIT\n"); load.priv = &offset; - load.bl_len = bl_len; + spl_set_bl_len(&load, bl_len); load.read = spl_nand_fit_read; return spl_load_simple_fit(spl_image, &load, offset, header); } else if (IS_ENABLED(CONFIG_SPL_LOAD_IMX_CONTAINER) && @@ -98,7 +98,7 @@ static int spl_nand_load_element(struct spl_image_info *spl_image, struct spl_load_info load; load.priv = &offset; - load.bl_len = bl_len; + spl_set_bl_len(&load, bl_len); load.read = spl_nand_fit_read; return spl_load_imx_container(spl_image, &load, offset); } else if (IS_ENABLED(CONFIG_SPL_LEGACY_IMAGE_FORMAT) && @@ -106,7 +106,7 @@ static int spl_nand_load_element(struct spl_image_info *spl_image, struct spl_load_info load; debug("Found legacy image\n"); - load.bl_len = IS_ENABLED(CONFIG_SPL_LZMA) ? bl_len : 1; + spl_set_bl_len(&load, IS_ENABLED(CONFIG_SPL_LZMA) ? bl_len : 1); load.read = spl_nand_legacy_read; return spl_load_legacy_img(spl_image, bootdev, &load, offset, header); diff --git a/common/spl/spl_net.c b/common/spl/spl_net.c index f01d4df8bc..47994e2816 100644 --- a/common/spl/spl_net.c +++ b/common/spl/spl_net.c @@ -54,7 +54,7 @@ static int spl_net_load_image(struct spl_image_info *spl_image, struct spl_load_info load; debug("Found FIT\n"); - load.bl_len = 1; + spl_set_bl_len(&load, 1); load.read = spl_net_load_read; rv = spl_load_simple_fit(spl_image, &load, 0, header); } else { diff --git a/common/spl/spl_nor.c b/common/spl/spl_nor.c index 236b071828..aad230db4d 100644 --- a/common/spl/spl_nor.c +++ b/common/spl/spl_nor.c @@ -49,7 +49,7 @@ static int spl_nor_load_image(struct spl_image_info *spl_image, int ret; debug("Found FIT\n"); - load.bl_len = 1; + spl_set_bl_len(&load, 1); load.read = spl_nor_load_read; ret = spl_load_simple_fit(spl_image, &load, @@ -97,7 +97,7 @@ static int spl_nor_load_image(struct spl_image_info *spl_image, #ifdef CONFIG_SPL_LOAD_FIT if (image_get_magic(header) == FDT_MAGIC) { debug("Found FIT format U-Boot\n"); - load.bl_len = 1; + spl_set_bl_len(&load, 1); load.read = spl_nor_load_read; return spl_load_simple_fit(spl_image, &load, spl_nor_get_uboot_base(), @@ -106,7 +106,7 @@ static int spl_nor_load_image(struct spl_image_info *spl_image, #endif if (IS_ENABLED(CONFIG_SPL_LOAD_IMX_CONTAINER) && valid_container_hdr((void *)header)) { - load.bl_len = 1; + spl_set_bl_len(&load, 1); load.read = spl_nor_load_read; return spl_load_imx_container(spl_image, &load, spl_nor_get_uboot_base()); @@ -114,7 +114,7 @@ static int spl_nor_load_image(struct spl_image_info *spl_image, /* Legacy image handling */ if (IS_ENABLED(CONFIG_SPL_LEGACY_IMAGE_FORMAT)) { - load.bl_len = 1; + spl_set_bl_len(&load, 1); load.read = spl_nor_load_read; return spl_load_legacy_img(spl_image, bootdev, &load, spl_nor_get_uboot_base(), diff --git a/common/spl/spl_ram.c b/common/spl/spl_ram.c index 4158ed1c32..8aeda237be 100644 --- a/common/spl/spl_ram.c +++ b/common/spl/spl_ram.c @@ -70,7 +70,7 @@ static int spl_ram_load_image(struct spl_image_info *spl_image, struct spl_load_info load; debug("Found FIT\n"); - load.bl_len = 1; + spl_set_bl_len(&load, 1); load.read = spl_ram_load_read; ret = spl_load_simple_fit(spl_image, &load, 0, header); } else { diff --git a/common/spl/spl_semihosting.c b/common/spl/spl_semihosting.c index 24a3d9fd1c..9b0610b8fc 100644 --- a/common/spl/spl_semihosting.c +++ b/common/spl/spl_semihosting.c @@ -68,7 +68,7 @@ static int spl_smh_load_image(struct spl_image_info *spl_image, debug("Found FIT\n"); load.read = smh_fit_read; - load.bl_len = 1; + spl_set_bl_len(&load, 1); load.priv = &fd; ret = spl_load_simple_fit(spl_image, &load, 0, header); diff --git a/common/spl/spl_spi.c b/common/spl/spl_spi.c index 373caea322..3e08ac7c1a 100644 --- a/common/spl/spl_spi.c +++ b/common/spl/spl_spi.c @@ -152,7 +152,7 @@ static int spl_spi_load_image(struct spl_image_info *spl_image, debug("Found FIT\n"); load.priv = flash; - load.bl_len = 1; + spl_set_bl_len(&load, 1); load.read = spl_spi_fit_read; err = spl_load_simple_fit(spl_image, &load, payload_offs, @@ -162,7 +162,7 @@ static int spl_spi_load_image(struct spl_image_info *spl_image, struct spl_load_info load; load.priv = flash; - load.bl_len = 1; + spl_set_bl_len(&load, 1); load.read = spl_spi_fit_read; err = spl_load_imx_container(spl_image, &load, diff --git a/common/spl/spl_ymodem.c b/common/spl/spl_ymodem.c index 3f92b9b003..1faaa2c938 100644 --- a/common/spl/spl_ymodem.c +++ b/common/spl/spl_ymodem.c @@ -135,7 +135,7 @@ int spl_ymodem_load_image(struct spl_image_info *spl_image, debug("Found FIT\n"); load.priv = (void *)&info; - load.bl_len = 1; + spl_set_bl_len(&load, 1); info.buf = buf; info.image_read = BUF_SIZE; load.read = ymodem_read_fit; diff --git a/drivers/usb/gadget/f_sdp.c b/drivers/usb/gadget/f_sdp.c index 1b16b7eb45..ca2760c00d 100644 --- a/drivers/usb/gadget/f_sdp.c +++ b/drivers/usb/gadget/f_sdp.c @@ -845,7 +845,7 @@ static int sdp_handle_in_ep(struct spl_image_info *spl_image, debug("Found FIT\n"); load.priv = header; - load.bl_len = 1; + spl_set_bl_len(&load, 1); load.read = sdp_load_read; spl_load_simple_fit(spl_image, &load, 0, header); @@ -858,7 +858,7 @@ static int sdp_handle_in_ep(struct spl_image_info *spl_image, struct spl_load_info load; load.priv = header; - load.bl_len = 1; + spl_set_bl_len(&load, 1); load.read = sdp_load_read; spl_load_imx_container(spl_image, &load, 0); return SDP_EXIT; diff --git a/include/spl.h b/include/spl.h index fec656d301..03c5c5c66b 100644 --- a/include/spl.h +++ b/include/spl.h @@ -304,9 +304,34 @@ struct spl_load_info { */ ulong (*read)(struct spl_load_info *load, ulong sector, ulong count, void *buf); +#if IS_ENABLED(CONFIG_SPL_LOAD_BLOCK) int bl_len; }; +static inline int spl_get_bl_len(struct spl_load_info *info) +{ + return info->bl_len; +} + +static inline void spl_set_bl_len(struct spl_load_info *info, int bl_len) +{ + info->bl_len = bl_len; +} +#else +}; + +static inline int spl_get_bl_len(struct spl_load_info *info) +{ + return 1; +} + +static inline void spl_set_bl_len(struct spl_load_info *info, int bl_len) +{ + if (bl_len != 1) + panic("CONFIG_SPL_LOAD_BLOCK not enabled"); +} +#endif + /* * We need to know the position of U-Boot in memory so we can jump to it. We * allow any U-Boot binary to be used (u-boot.bin, u-boot-nodtb.bin, diff --git a/test/image/Kconfig b/test/image/Kconfig index 6f0bb81f83..45b6e8c52e 100644 --- a/test/image/Kconfig +++ b/test/image/Kconfig @@ -52,6 +52,7 @@ config SPL_UT_LOAD_SPI config SPL_UT_LOAD_OS bool "Test loading from the host OS" depends on SANDBOX && SPL_LOAD_FIT + select SPL_LOAD_BLOCK default y help Smoke test to ensure that loading U-boot works in sandbox. diff --git a/test/image/spl_load.c b/test/image/spl_load.c index ab4c14d649..35ceed6775 100644 --- a/test/image/spl_load.c +++ b/test/image/spl_load.c @@ -342,12 +342,11 @@ static int spl_test_image(struct unit_test_state *uts, const char *test_name, if (check_image_info(uts, &info_write, &info_read)) return CMD_RET_FAILURE; } else { - struct spl_load_info load = { - .bl_len = 1, - .priv = img, - .read = spl_test_read, - }; + struct spl_load_info load; + spl_set_bl_len(&load, 1); + load.priv = img; + load.read = spl_test_read; if (type == IMX8) ut_assertok(spl_load_imx_container(&info_read, &load, 0)); diff --git a/test/image/spl_load_os.c b/test/image/spl_load_os.c index f46df907c6..26228a8a4a 100644 --- a/test/image/spl_load_os.c +++ b/test/image/spl_load_os.c @@ -51,7 +51,7 @@ static int spl_test_load(struct unit_test_state *uts) int fd; memset(&load, '\0', sizeof(load)); - load.bl_len = 512; + spl_set_bl_len(&load, 512); load.read = read_fit_image; ret = sandbox_find_next_phase(fname, sizeof(fname), true); -- 2.39.5