diff options
Diffstat (limited to 'common/spl')
-rw-r--r-- | common/spl/Kconfig | 37 | ||||
-rw-r--r-- | common/spl/spl.c | 13 | ||||
-rw-r--r-- | common/spl/spl_blk_fs.c | 73 | ||||
-rw-r--r-- | common/spl/spl_ext.c | 36 | ||||
-rw-r--r-- | common/spl/spl_fat.c | 62 | ||||
-rw-r--r-- | common/spl/spl_fit.c | 74 | ||||
-rw-r--r-- | common/spl/spl_imx_container.c | 55 | ||||
-rw-r--r-- | common/spl/spl_legacy.c | 110 | ||||
-rw-r--r-- | common/spl/spl_mmc.c | 101 | ||||
-rw-r--r-- | common/spl/spl_nand.c | 100 | ||||
-rw-r--r-- | common/spl/spl_net.c | 29 | ||||
-rw-r--r-- | common/spl/spl_nor.c | 42 | ||||
-rw-r--r-- | common/spl/spl_ram.c | 2 | ||||
-rw-r--r-- | common/spl/spl_semihosting.c | 65 | ||||
-rw-r--r-- | common/spl/spl_spi.c | 128 | ||||
-rw-r--r-- | common/spl/spl_ymodem.c | 4 |
16 files changed, 265 insertions, 666 deletions
diff --git a/common/spl/Kconfig b/common/spl/Kconfig index 00332cf..fc284a5 100644 --- a/common/spl/Kconfig +++ b/common/spl/Kconfig @@ -183,6 +183,7 @@ config SPL_SYS_REPORT_STACK_F_USAGE config SPL_SHOW_ERRORS bool "Show more information when something goes wrong" + depends on SPL_LIBCOMMON_SUPPORT help This enabled more verbose error messages and checking when something goes wrong in SPL. For example, it shows the error code when U-Boot @@ -279,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 @@ -473,6 +481,11 @@ config SPL_DISPLAY_PRINT banner ("U-Boot SPL ..."). This function should be provided by the board. +config SPL_SYS_MMCSD_RAW_MODE + bool + help + Support booting from an MMC without a filesystem. + config SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR bool "MMC raw mode: by sector" default y if ARCH_SUNXI || ARCH_DAVINCI || ARCH_UNIPHIER || \ @@ -481,6 +494,8 @@ 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 + select SPL_SYS_MMCSD_RAW_MODE if SPL_MMC help Use sector number for specifying U-Boot location on MMC/SD in raw mode. @@ -517,6 +532,8 @@ 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 + select SPL_SYS_MMCSD_RAW_MODE if SPL_MMC help Use a partition for loading U-Boot when using MMC/SD in raw mode. @@ -683,6 +700,22 @@ config SPL_FS_FAT filesystem from within SPL. Support for the underlying block device (e.g. MMC or USB) must be enabled separately. +config SPL_FS_FAT_DMA_ALIGN + bool "Use DMA-aligned buffers with FAT" + depends on SPL_FS_FAT + select SPL_LOAD_BLOCK + default y if SPL_LOAD_FIT + help + The FAT filesystem driver tries to ensure that the reads it issues to + the block subsystem use DMA-aligned buffers. If the supplied buffer is + not DMA-aligned, the FAT driver will use a bounce-buffer and read + block-by-block. This is separate from the bounce-buffer used by the + block subsystem (CONFIG_BOUNCE_BUFFER). + + Enable this config to align buffers passed to the FAT filesystem + driver. This will speed up reads, but will increase the size of U-Boot + by around 60 bytes. + config SPL_FS_LOAD_PAYLOAD_NAME string "File to load for U-Boot from the filesystem" depends on SPL_FS_EXT4 || SPL_FS_FAT || SPL_FS_SQUASHFS || SPL_SEMIHOSTING @@ -876,6 +909,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. @@ -1101,6 +1135,8 @@ 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 + select SPL_SYS_MMCSD_RAW_MODE help Select this if the Falcon mode OS image mode is on MMC or SD media. @@ -1259,7 +1295,6 @@ 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 help diff --git a/common/spl/spl.c b/common/spl/spl.c index 732d90d..3ce5bfe 100644 --- a/common/spl/spl.c +++ b/common/spl/spl.c @@ -19,6 +19,7 @@ #include <mapmem.h> #include <serial.h> #include <spl.h> +#include <spl_load.h> #include <system-constants.h> #include <asm/global_data.h> #include <asm-generic/gpio.h> @@ -352,6 +353,15 @@ int spl_parse_image_header(struct spl_image_info *spl_image, return 0; } +#if SPL_LOAD_USERS > 1 +int spl_load(struct spl_image_info *spl_image, + const struct spl_boot_device *bootdev, struct spl_load_info *info, + size_t size, size_t offset) +{ + return _spl_load(spl_image, bootdev, info, size, offset); +} +#endif + __weak void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image) { typedef void __noreturn (*image_entry_noargs_t)(void); @@ -718,8 +728,7 @@ void board_init_r(gd_t *dummy1, ulong dummy2) ret = boot_from_devices(&spl_image, spl_boot_list, ARRAY_SIZE(spl_boot_list)); if (ret) { - if (CONFIG_IS_ENABLED(SHOW_ERRORS) && - CONFIG_IS_ENABLED(LIBCOMMON_SUPPORT)) + if (CONFIG_IS_ENABLED(SHOW_ERRORS)) printf(SPL_TPL_PROMPT "failed to boot from all boot devices (err=%d)\n", ret); else diff --git a/common/spl/spl_blk_fs.c b/common/spl/spl_blk_fs.c index 63825d6..04eac6f 100644 --- a/common/spl/spl_blk_fs.c +++ b/common/spl/spl_blk_fs.c @@ -7,12 +7,15 @@ #include <common.h> #include <spl.h> +#include <spl_load.h> #include <image.h> #include <fs.h> +#include <asm/cache.h> #include <asm/io.h> struct blk_dev { const char *ifname; + const char *filename; char dev_part_str[8]; }; @@ -30,11 +33,11 @@ static ulong spl_fit_read(struct spl_load_info *load, ulong file_offset, return ret; } - ret = fs_read(load->filename, virt_to_phys(buf), file_offset, size, + ret = fs_read(dev->filename, virt_to_phys(buf), file_offset, size, &actlen); if (ret < 0) { printf("spl: error reading image %s. Err - %d\n", - load->filename, ret); + dev->filename, ret); return ret; } @@ -46,10 +49,10 @@ int spl_blk_load_image(struct spl_image_info *spl_image, enum uclass_id uclass_id, int devnum, int partnum) { const char *filename = CONFIG_SPL_FS_LOAD_PAYLOAD_NAME; - struct legacy_img_hdr *header; struct blk_desc *blk_desc; - loff_t actlen, filesize; + loff_t filesize; struct blk_dev dev; + struct spl_load_info load; int ret; blk_desc = blk_get_devnum_by_uclass_id(uclass_id, devnum); @@ -59,8 +62,8 @@ int spl_blk_load_image(struct spl_image_info *spl_image, } blk_show_device(uclass_id, devnum); - header = spl_get_load_buffer(-sizeof(*header), sizeof(*header)); + dev.filename = filename; dev.ifname = blk_get_uclass_name(uclass_id); snprintf(dev.dev_part_str, sizeof(dev.dev_part_str) - 1, "%x:%x", devnum, partnum); @@ -68,63 +71,21 @@ int spl_blk_load_image(struct spl_image_info *spl_image, if (ret) { printf("spl: unable to set blk_dev %s %s. Err - %d\n", dev.ifname, dev.dev_part_str, ret); - goto out; - } - - ret = fs_read(filename, virt_to_phys(header), 0, - sizeof(struct legacy_img_hdr), &actlen); - if (ret) { - printf("spl: unable to read file %s. Err - %d\n", filename, - ret); - goto out; - } - - if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) && - image_get_magic(header) == FDT_MAGIC) { - struct spl_load_info load; - - debug("Found FIT\n"); - load.read = spl_fit_read; - load.bl_len = 1; - load.filename = (void *)filename; - load.priv = &dev; - - return spl_load_simple_fit(spl_image, &load, 0, header); - } - - ret = spl_parse_image_header(spl_image, bootdev, header); - if (ret) { - printf("spl: unable to parse image header. Err - %d\n", - ret); - goto out; - } - - ret = fs_set_blk_dev(dev.ifname, dev.dev_part_str, FS_TYPE_ANY); - if (ret) { - printf("spl: unable to set blk_dev %s %s. Err - %d\n", - dev.ifname, dev.dev_part_str, ret); - goto out; + return ret; } ret = fs_size(filename, &filesize); if (ret) { printf("spl: unable to get file size: %s. Err - %d\n", filename, ret); - goto out; - } - - ret = fs_set_blk_dev(dev.ifname, dev.dev_part_str, FS_TYPE_ANY); - if (ret) { - printf("spl: unable to set blk_dev %s %s. Err - %d\n", - dev.ifname, dev.dev_part_str, ret); - goto out; + return ret; } - ret = fs_read(filename, (ulong)spl_image->load_addr, 0, filesize, - &actlen); - if (ret) - printf("spl: unable to read file %s. Err - %d\n", - filename, ret); -out: - return ret; + load.read = spl_fit_read; + if (IS_ENABLED(CONFIG_SPL_FS_FAT_DMA_ALIGN)) + spl_set_bl_len(&load, ARCH_DMA_MINALIGN); + else + spl_set_bl_len(&load, 1); + load.priv = &dev; + return spl_load(spl_image, bootdev, &load, filesize, 0); } diff --git a/common/spl/spl_ext.c b/common/spl/spl_ext.c index af836ca..d280b69 100644 --- a/common/spl/spl_ext.c +++ b/common/spl/spl_ext.c @@ -2,25 +2,35 @@ #include <common.h> #include <env.h> -#include <mapmem.h> #include <part.h> #include <spl.h> +#include <spl_load.h> #include <asm/u-boot.h> #include <ext4fs.h> #include <errno.h> #include <image.h> +static ulong spl_fit_read(struct spl_load_info *load, ulong file_offset, + ulong size, void *buf) +{ + int ret; + loff_t actlen; + + ret = ext4fs_read(buf, file_offset, size, &actlen); + if (ret) + return ret; + return actlen; +} + int spl_load_image_ext(struct spl_image_info *spl_image, struct spl_boot_device *bootdev, struct blk_desc *block_dev, int partition, const char *filename) { s32 err; - struct legacy_img_hdr *header; - loff_t filelen, actlen; + loff_t filelen; struct disk_partition part_info = {}; - - header = spl_get_load_buffer(-sizeof(*header), sizeof(*header)); + struct spl_load_info load; if (part_get_info(block_dev, partition, &part_info)) { printf("spl: no partition table found\n"); @@ -42,20 +52,10 @@ int spl_load_image_ext(struct spl_image_info *spl_image, puts("spl: ext4fs_open failed\n"); goto end; } - err = ext4fs_read((char *)header, 0, sizeof(struct legacy_img_hdr), &actlen); - if (err < 0) { - puts("spl: ext4fs_read failed\n"); - goto end; - } - - err = spl_parse_image_header(spl_image, bootdev, header); - if (err < 0) { - puts("spl: ext: failed to parse image header\n"); - goto end; - } - err = ext4fs_read(map_sysmem(spl_image->load_addr, filelen), 0, filelen, - &actlen); + spl_set_bl_len(&load, 1); + load.read = spl_fit_read; + err = spl_load(spl_image, bootdev, &load, filelen, 0); end: #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT diff --git a/common/spl/spl_fat.c b/common/spl/spl_fat.c index 014074f..a52f9e1 100644 --- a/common/spl/spl_fat.c +++ b/common/spl/spl_fat.c @@ -11,8 +11,8 @@ #include <common.h> #include <env.h> #include <log.h> -#include <mapmem.h> #include <spl.h> +#include <spl_load.h> #include <asm/u-boot.h> #include <fat.h> #include <errno.h> @@ -51,7 +51,7 @@ static ulong spl_fit_read(struct spl_load_info *load, ulong file_offset, { loff_t actread; int ret; - char *filename = (char *)load->filename; + char *filename = load->priv; ret = fat_read_file(filename, buf, file_offset, size, &actread); if (ret) @@ -66,59 +66,41 @@ int spl_load_image_fat(struct spl_image_info *spl_image, const char *filename) { int err; - struct legacy_img_hdr *header; + loff_t size; + struct spl_load_info load; err = spl_register_fat_device(block_dev, partition); if (err) goto end; - header = spl_get_load_buffer(-sizeof(*header), sizeof(*header)); - - err = file_fat_read(filename, header, sizeof(struct legacy_img_hdr)); - if (err <= 0) - goto end; - - if (IS_ENABLED(CONFIG_SPL_LOAD_FIT_FULL) && - image_get_magic(header) == FDT_MAGIC) { - err = file_fat_read(filename, - map_sysmem(CONFIG_SYS_LOAD_ADDR, 0), 0); - if (err <= 0) - goto end; - err = spl_parse_image_header(spl_image, bootdev, - map_sysmem(CONFIG_SYS_LOAD_ADDR, - err)); - if (err == -EAGAIN) - return err; - if (err == 0) - err = 1; - } else if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) && - image_get_magic(header) == FDT_MAGIC) { - struct spl_load_info load; - - debug("Found FIT\n"); - load.read = spl_fit_read; - load.bl_len = 1; - load.filename = (void *)filename; - load.priv = NULL; - - return spl_load_simple_fit(spl_image, &load, 0, header); - } else { - err = spl_parse_image_header(spl_image, bootdev, header); + /* + * Avoid pulling in this function for other image types since we are + * very short on space on some boards. + */ + if (IS_ENABLED(CONFIG_SPL_LOAD_FIT_FULL)) { + err = fat_size(filename, &size); if (err) goto end; - - err = file_fat_read(filename, map_sysmem(spl_image->load_addr, - spl_image->size), 0); + } else { + size = 0; } + load.read = spl_fit_read; + if (IS_ENABLED(CONFIG_SPL_FS_FAT_DMA_ALIGN)) + spl_set_bl_len(&load, ARCH_DMA_MINALIGN); + else + spl_set_bl_len(&load, 1); + load.priv = (void *)filename; + err = spl_load(spl_image, bootdev, &load, size, 0); + end: #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT - if (err <= 0) + if (err < 0) printf("%s: error reading image %s, err - %d\n", __func__, filename, err); #endif - return (err <= 0); + return err; } #if CONFIG_IS_ENABLED(OS_BOOT) diff --git a/common/spl/spl_fit.c b/common/spl/spl_fit.c index 70d8d59..872df0c 100644 --- a/common/spl/spl_fit.c +++ b/common/spl/spl_fit.c @@ -14,7 +14,6 @@ #include <mapmem.h> #include <spl.h> #include <sysinfo.h> -#include <asm/cache.h> #include <asm/global_data.h> #include <asm/io.h> #include <linux/libfdt.h> @@ -172,29 +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) { - /* - * If it is a FS read, get the first address before offset which is - * aligned to ARCH_DMA_MINALIGN. If it is raw read return the - * block number to which offset belongs. - */ - if (info->filename) - return offset & ~(ARCH_DMA_MINALIGN - 1); - - return 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) { - /* - * If it is a FS read, get the difference between the offset and - * the first address before offset which is aligned to - * ARCH_DMA_MINALIGN. If it is raw read return the offset within the - * block. - */ - if (info->filename) - return offset & (ARCH_DMA_MINALIGN - 1); - - return offset % info->bl_len; + return offset & (spl_get_bl_len(info) - 1); } static int get_aligned_image_size(struct spl_load_info *info, int data_size, @@ -202,10 +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); - if (info->filename) - return data_size; - - return (data_size + info->bl_len - 1) / info->bl_len; + return ALIGN(data_size, spl_get_bl_len(info)); } /** @@ -222,7 +201,7 @@ static int get_aligned_image_size(struct spl_load_info *info, int data_size, * * Return: 0 on success or a negative error number. */ -static int load_simple_fit(struct spl_load_info *info, ulong sector, +static int load_simple_fit(struct spl_load_info *info, ulong fit_offset, const struct spl_fit_info *ctx, int node, struct spl_image_info *image_info) { @@ -234,7 +213,6 @@ static int load_simple_fit(struct spl_load_info *info, ulong sector, void *load_ptr; void *src; ulong overhead; - int nr_sectors; uint8_t image_comp = -1, type = -1; const void *data; const void *fit = ctx->fit; @@ -291,11 +269,12 @@ static int load_simple_fit(struct spl_load_info *info, ulong sector, length = len; overhead = get_aligned_image_overhead(info, offset); - nr_sectors = get_aligned_image_size(info, length, offset); + size = get_aligned_image_size(info, length, offset); if (info->read(info, - sector + get_aligned_image_offset(info, offset), - nr_sectors, src_ptr) != nr_sectors) + fit_offset + + get_aligned_image_offset(info, offset), size, + src_ptr) < length) return -EIO; debug("External data: dst=%p, offset=%x, size=%lx\n", @@ -380,7 +359,7 @@ __weak int board_spl_fit_append_fdt_skip(const char *name) } static int spl_fit_append_fdt(struct spl_image_info *spl_image, - struct spl_load_info *info, ulong sector, + struct spl_load_info *info, ulong offset, const struct spl_fit_info *ctx) { struct spl_image_info image_info; @@ -414,7 +393,7 @@ static int spl_fit_append_fdt(struct spl_image_info *spl_image, spl_image->fdt_addr = map_sysmem(image_info.load_addr, size); memcpy(spl_image->fdt_addr, gd->fdt_blob, size); } else { - ret = load_simple_fit(info, sector, ctx, node, &image_info); + ret = load_simple_fit(info, offset, ctx, node, &image_info); if (ret < 0) return ret; @@ -465,7 +444,7 @@ static int spl_fit_append_fdt(struct spl_image_info *spl_image, __func__); } image_info.load_addr = (ulong)tmpbuffer; - ret = load_simple_fit(info, sector, ctx, node, + ret = load_simple_fit(info, offset, ctx, node, &image_info); if (ret < 0) break; @@ -642,7 +621,7 @@ static int spl_fit_upload_fpga(struct spl_fit_info *ctx, int node, } static int spl_fit_load_fpga(struct spl_fit_info *ctx, - struct spl_load_info *info, ulong sector) + struct spl_load_info *info, ulong offset) { int node, ret; @@ -657,7 +636,7 @@ static int spl_fit_load_fpga(struct spl_fit_info *ctx, warn_deprecated("'fpga' property in config node. Use 'loadables'"); /* Load the image and set up the fpga_image structure */ - ret = load_simple_fit(info, sector, ctx, node, &fpga_image); + ret = load_simple_fit(info, offset, ctx, node, &fpga_image); if (ret) { printf("%s: Cannot load the FPGA: %i\n", __func__, ret); return ret; @@ -667,11 +646,10 @@ static int spl_fit_load_fpga(struct spl_fit_info *ctx, } static int spl_simple_fit_read(struct spl_fit_info *ctx, - struct spl_load_info *info, ulong sector, + struct spl_load_info *info, ulong offset, const void *fit_header) { unsigned long count, size; - int sectors; void *buf; /* @@ -690,13 +668,13 @@ static int spl_simple_fit_read(struct spl_fit_info *ctx, * For FIT with data embedded, data is loaded as part of FIT image. * For FIT with external data, data is not loaded in this step. */ - sectors = get_aligned_image_size(info, size, 0); - buf = board_spl_fit_buffer_addr(size, sectors, info->bl_len); + size = get_aligned_image_size(info, size, 0); + buf = board_spl_fit_buffer_addr(size, size, 1); - count = info->read(info, sector, sectors, buf); + count = info->read(info, offset, size, buf); ctx->fit = buf; - debug("fit read sector %lx, sectors=%d, dst=%p, count=%lu, size=0x%lx\n", - sector, sectors, buf, count, size); + debug("fit read offset %lx, size=%lu, dst=%p, count=%lu\n", + offset, size, buf, count); return (count == 0) ? -EIO : 0; } @@ -728,7 +706,7 @@ static int spl_simple_fit_parse(struct spl_fit_info *ctx) } int spl_load_simple_fit(struct spl_image_info *spl_image, - struct spl_load_info *info, ulong sector, void *fit) + struct spl_load_info *info, ulong offset, void *fit) { struct spl_image_info image_info; struct spl_fit_info ctx; @@ -737,7 +715,7 @@ int spl_load_simple_fit(struct spl_image_info *spl_image, int index = 0; int firmware_node; - ret = spl_simple_fit_read(&ctx, info, sector, fit); + ret = spl_simple_fit_read(&ctx, info, offset, fit); if (ret < 0) return ret; @@ -752,7 +730,7 @@ int spl_load_simple_fit(struct spl_image_info *spl_image, return ret; if (IS_ENABLED(CONFIG_SPL_FPGA)) - spl_fit_load_fpga(&ctx, info, sector); + spl_fit_load_fpga(&ctx, info, offset); /* * Find the U-Boot image using the following search order: @@ -782,7 +760,7 @@ int spl_load_simple_fit(struct spl_image_info *spl_image, } /* Load the image and set up the spl_image structure */ - ret = load_simple_fit(info, sector, &ctx, node, spl_image); + ret = load_simple_fit(info, offset, &ctx, node, spl_image); if (ret) return ret; @@ -800,7 +778,7 @@ int spl_load_simple_fit(struct spl_image_info *spl_image, * We allow this to fail, as the U-Boot image might embed its FDT. */ if (os_takes_devicetree(spl_image->os)) { - ret = spl_fit_append_fdt(spl_image, info, sector, &ctx); + ret = spl_fit_append_fdt(spl_image, info, offset, &ctx); if (ret < 0 && spl_image->os != IH_OS_U_BOOT) return ret; } @@ -823,7 +801,7 @@ int spl_load_simple_fit(struct spl_image_info *spl_image, continue; image_info.load_addr = 0; - ret = load_simple_fit(info, sector, &ctx, node, &image_info); + ret = load_simple_fit(info, offset, &ctx, node, &image_info); if (ret < 0) { printf("%s: can't load image loadables index %d (ret = %d)\n", __func__, index, ret); @@ -837,7 +815,7 @@ int spl_load_simple_fit(struct spl_image_info *spl_image, debug("Loadable is %s\n", genimg_get_os_name(os_type)); if (os_takes_devicetree(os_type)) { - spl_fit_append_fdt(&image_info, info, sector, &ctx); + spl_fit_append_fdt(&image_info, info, offset, &ctx); spl_image->fdt_addr = image_info.fdt_addr; } diff --git a/common/spl/spl_imx_container.c b/common/spl/spl_imx_container.c index 127802f..b4ea924 100644 --- a/common/spl/spl_imx_container.c +++ b/common/spl/spl_imx_container.c @@ -19,11 +19,10 @@ static struct boot_img_t *read_auth_image(struct spl_image_info *spl_image, struct spl_load_info *info, struct container_hdr *container, int image_index, - u32 container_sector) + ulong container_offset) { struct boot_img_t *images; - ulong sector; - u32 sectors; + ulong offset, overhead, size; if (image_index > container->num_images) { debug("Invalid image number\n"); @@ -33,22 +32,21 @@ 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 (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; } - sectors = roundup(images[image_index].size, info->bl_len) / - info->bl_len; - sector = images[image_index].offset / info->bl_len + - container_sector; + size = ALIGN(images[image_index].size, spl_get_bl_len(info)); + offset = images[image_index].offset + container_offset; - debug("%s: container: %p sector: %lu sectors: %u\n", __func__, - container, sector, sectors); - if (info->read(info, sector, sectors, - map_sysmem(images[image_index].dst, - images[image_index].size)) != sectors) { + debug("%s: container: %p offset: %lu size: %lu\n", __func__, + container, offset, size); + if (info->read(info, offset, size, + map_sysmem(images[image_index].dst - overhead, + images[image_index].size)) < + images[image_index].size) { printf("%s wrong\n", __func__); return NULL; } @@ -62,15 +60,13 @@ static struct boot_img_t *read_auth_image(struct spl_image_info *spl_image, } static int read_auth_container(struct spl_image_info *spl_image, - struct spl_load_info *info, ulong sector) + struct spl_load_info *info, ulong offset) { struct container_hdr *container = NULL; u16 length; - u32 sectors; int i, size, ret = 0; - size = roundup(CONTAINER_HDR_ALIGNMENT, info->bl_len); - sectors = size / 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, @@ -80,9 +76,10 @@ static int read_auth_container(struct spl_image_info *spl_image, if (!container) return -ENOMEM; - debug("%s: container: %p sector: %lu sectors: %u\n", __func__, - container, sector, sectors); - if (info->read(info, sector, sectors, container) != sectors) { + debug("%s: container: %p offset: %lu size: %u\n", __func__, + container, offset, size); + if (info->read(info, offset, size, container) < + CONTAINER_HDR_ALIGNMENT) { ret = -EIO; goto end; } @@ -103,18 +100,16 @@ static int read_auth_container(struct spl_image_info *spl_image, debug("Container length %u\n", length); if (length > CONTAINER_HDR_ALIGNMENT) { - size = roundup(length, info->bl_len); - sectors = size / info->bl_len; + size = ALIGN(length, spl_get_bl_len(info)); free(container); container = malloc(size); if (!container) return -ENOMEM; - debug("%s: container: %p sector: %lu sectors: %u\n", - __func__, container, sector, sectors); - if (info->read(info, sector, sectors, container) != - sectors) { + debug("%s: container: %p offset: %lu size: %u\n", + __func__, container, offset, size); + if (info->read(info, offset, size, container) < length) { ret = -EIO; goto end; } @@ -129,7 +124,7 @@ static int read_auth_container(struct spl_image_info *spl_image, for (i = 0; i < container->num_images; i++) { struct boot_img_t *image = read_auth_image(spl_image, info, container, i, - sector); + offset); if (!image) { ret = -EINVAL; @@ -154,7 +149,7 @@ end: } int spl_load_imx_container(struct spl_image_info *spl_image, - struct spl_load_info *info, ulong sector) + struct spl_load_info *info, ulong offset) { - return read_auth_container(spl_image, info, sector); + return read_auth_container(spl_image, info, offset); } diff --git a/common/spl/spl_legacy.c b/common/spl/spl_legacy.c index 9189576..08687ca 100644 --- a/common/spl/spl_legacy.c +++ b/common/spl/spl_legacy.c @@ -82,95 +82,39 @@ int spl_parse_legacy_header(struct spl_image_info *spl_image, return 0; } -/* - * This function is added explicitly to avoid code size increase, when - * no compression method is enabled. The compiler will optimize the - * following switch/case statement in spl_load_legacy_img() away due to - * Dead Code Elimination. - */ -static inline int spl_image_get_comp(const struct legacy_img_hdr *hdr) +int spl_load_legacy_lzma(struct spl_image_info *spl_image, + struct spl_load_info *load, ulong offset) { - if (IS_ENABLED(CONFIG_SPL_LZMA)) - return image_get_comp(hdr); - - return IH_COMP_NONE; -} - -int spl_load_legacy_img(struct spl_image_info *spl_image, - struct spl_boot_device *bootdev, - struct spl_load_info *load, ulong offset, - struct legacy_img_hdr *hdr) -{ - __maybe_unused SizeT lzma_len; - __maybe_unused void *src; - ulong dataptr; + SizeT lzma_len = LZMA_LEN; + void *src; + ulong dataptr, overhead, size; int ret; - /* - * If the payload is compressed, the decompressed data should be - * directly write to its load address. - */ - if (spl_image_get_comp(hdr) != IH_COMP_NONE) - spl_image->flags |= SPL_COPY_PAYLOAD_ONLY; + /* dataptr points to compressed payload */ + dataptr = ALIGN_DOWN(sizeof(struct legacy_img_hdr), + spl_get_bl_len(load)); + overhead = sizeof(struct legacy_img_hdr) - dataptr; + size = ALIGN(spl_image->size + overhead, spl_get_bl_len(load)); + dataptr += offset; + + debug("LZMA: Decompressing %08lx to %08lx\n", + dataptr, spl_image->load_addr); + src = malloc(size); + if (!src) { + printf("Unable to allocate %d bytes for LZMA\n", + spl_image->size); + return -ENOMEM; + } - ret = spl_parse_image_header(spl_image, bootdev, hdr); - if (ret) + load->read(load, dataptr, size, src); + ret = lzmaBuffToBuffDecompress(map_sysmem(spl_image->load_addr, + spl_image->size), &lzma_len, + src + overhead, spl_image->size); + if (ret) { + printf("LZMA decompression error: %d\n", ret); return ret; - - /* Read image */ - switch (spl_image_get_comp(hdr)) { - case IH_COMP_NONE: - dataptr = offset; - - /* - * Image header will be skipped only if SPL_COPY_PAYLOAD_ONLY - * is set - */ - if (spl_image->flags & SPL_COPY_PAYLOAD_ONLY) - dataptr += sizeof(*hdr); - - load->read(load, dataptr, spl_image->size, - map_sysmem(spl_image->load_addr, spl_image->size)); - break; - - case IH_COMP_LZMA: { - ulong overhead, size; - - lzma_len = LZMA_LEN; - - /* dataptr points to compressed payload */ - dataptr = ALIGN_DOWN(sizeof(*hdr), load->bl_len); - overhead = sizeof(*hdr) - dataptr; - size = ALIGN(spl_image->size + overhead, load->bl_len); - dataptr += offset; - - debug("LZMA: Decompressing %08lx to %08lx\n", - dataptr, spl_image->load_addr); - src = malloc(size); - if (!src) { - printf("Unable to allocate %d bytes for LZMA\n", - spl_image->size); - return -ENOMEM; - } - - load->read(load, dataptr, size, src); - ret = lzmaBuffToBuffDecompress(map_sysmem(spl_image->load_addr, - spl_image->size), - &lzma_len, src + overhead, - spl_image->size); - if (ret) { - printf("LZMA decompression error: %d\n", ret); - return ret; - } - - spl_image->size = lzma_len; - break; - } - default: - debug("Compression method %s is not supported\n", - genimg_get_comp_short_name(image_get_comp(hdr))); - return -EINVAL; } + spl_image->size = lzma_len; return 0; } diff --git a/common/spl/spl_mmc.c b/common/spl/spl_mmc.c index 82689da..3d032bb 100644 --- a/common/spl/spl_mmc.c +++ b/common/spl/spl_mmc.c @@ -8,9 +8,9 @@ #include <common.h> #include <dm.h> #include <log.h> -#include <mapmem.h> #include <part.h> #include <spl.h> +#include <spl_load.h> #include <linux/compiler.h> #include <errno.h> #include <asm/u-boot.h> @@ -19,55 +19,14 @@ #include <image.h> #include <imx_container.h> -static int mmc_load_legacy(struct spl_image_info *spl_image, - struct spl_boot_device *bootdev, - struct mmc *mmc, - ulong sector, struct legacy_img_hdr *header) +static ulong h_spl_load_read(struct spl_load_info *load, ulong off, + ulong size, void *buf) { - u32 image_offset_sectors; - u32 image_size_sectors; - unsigned long count; - u32 image_offset; - int ret; - - ret = spl_parse_image_header(spl_image, bootdev, header); - if (ret) - return ret; - - /* convert offset to sectors - round down */ - image_offset_sectors = spl_image->offset / mmc->read_bl_len; - /* calculate remaining offset */ - image_offset = spl_image->offset % mmc->read_bl_len; + struct blk_desc *bd = load->priv; + lbaint_t sector = off >> bd->log2blksz; + lbaint_t count = size >> bd->log2blksz; - /* convert size to sectors - round up */ - image_size_sectors = (spl_image->size + mmc->read_bl_len - 1) / - mmc->read_bl_len; - - /* Read the header too to avoid extra memcpy */ - count = blk_dread(mmc_get_blk_desc(mmc), - sector + image_offset_sectors, - image_size_sectors, - map_sysmem(spl_image->load_addr, - image_size_sectors * mmc->read_bl_len)); - debug("read %x sectors to %lx\n", image_size_sectors, - spl_image->load_addr); - if (count != image_size_sectors) - return -EIO; - - if (image_offset) - memmove((void *)(ulong)spl_image->load_addr, - (void *)(ulong)spl_image->load_addr + image_offset, - spl_image->size); - - return 0; -} - -static ulong h_spl_load_read(struct spl_load_info *load, ulong sector, - ulong count, void *buf) -{ - struct mmc *mmc = load->dev; - - return blk_dread(mmc_get_blk_desc(mmc), sector, count, buf); + return blk_dread(bd, sector, count, buf) << bd->log2blksz; } static __maybe_unused unsigned long spl_mmc_raw_uboot_offset(int part) @@ -85,48 +44,14 @@ int mmc_load_image_raw_sector(struct spl_image_info *spl_image, struct spl_boot_device *bootdev, struct mmc *mmc, unsigned long sector) { - unsigned long count; - struct legacy_img_hdr *header; + int ret; struct blk_desc *bd = mmc_get_blk_desc(mmc); - int ret = 0; - - header = spl_get_load_buffer(-sizeof(*header), bd->blksz); - - /* read image header to find the image size & load address */ - count = blk_dread(bd, sector, 1, header); - debug("hdr read sector %lx, count=%lu\n", sector, count); - if (count == 0) { - ret = -EIO; - goto end; - } - - if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) && - image_get_magic(header) == FDT_MAGIC) { - struct spl_load_info load; - - debug("Found FIT\n"); - load.dev = mmc; - load.priv = NULL; - load.filename = NULL; - load.bl_len = mmc->read_bl_len; - load.read = h_spl_load_read; - ret = spl_load_simple_fit(spl_image, &load, sector, header); - } else if (IS_ENABLED(CONFIG_SPL_LOAD_IMX_CONTAINER) && - valid_container_hdr((void *)header)) { - struct spl_load_info load; - - load.dev = mmc; - load.priv = NULL; - load.filename = NULL; - load.bl_len = mmc->read_bl_len; - load.read = h_spl_load_read; - - ret = spl_load_imx_container(spl_image, &load, sector); - } else { - ret = mmc_load_legacy(spl_image, bootdev, mmc, sector, header); - } + struct spl_load_info load; -end: + load.priv = bd; + spl_set_bl_len(&load, bd->blksz); + load.read = h_spl_load_read; + ret = spl_load(spl_image, bootdev, &load, 0, sector << bd->log2blksz); if (ret) { #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT puts("mmc_load_image_raw_sector: mmc block read error\n"); diff --git a/common/spl/spl_nand.c b/common/spl/spl_nand.c index b8cd640..3b0a152 100644 --- a/common/spl/spl_nand.c +++ b/common/spl/spl_nand.c @@ -10,6 +10,7 @@ #include <imx_container.h> #include <log.h> #include <spl.h> +#include <spl_load.h> #include <asm/io.h> #include <mapmem.h> #include <nand.h> @@ -42,32 +43,24 @@ static int spl_nand_load_image(struct spl_image_info *spl_image, } #else -static ulong spl_nand_fit_read(struct spl_load_info *load, ulong offs, - ulong size, void *dst) +__weak u32 nand_spl_adjust_offset(u32 sector, u32 offs) { - int err; - ulong sector; - - sector = *(int *)load->priv; - offs *= load->bl_len; - size *= load->bl_len; - offs = sector + nand_spl_adjust_offset(sector, offs - sector); - err = nand_spl_load_image(offs, size, dst); - if (err) - return 0; - - return size / load->bl_len; + return offs; } -static ulong spl_nand_legacy_read(struct spl_load_info *load, ulong offs, - ulong size, void *dst) +static ulong spl_nand_read(struct spl_load_info *load, ulong offs, ulong size, + void *dst) { int err; + ulong sector; debug("%s: offs %lx, size %lx, dst %p\n", __func__, offs, size, dst); + sector = *(int *)load->priv; + offs = sector + nand_spl_adjust_offset(sector, offs - sector); err = nand_spl_load_image(offs, size, dst); + spl_set_bl_len(load, nand_page_size()); if (err) return 0; @@ -75,67 +68,20 @@ static ulong spl_nand_legacy_read(struct spl_load_info *load, ulong offs, } static int spl_nand_load_element(struct spl_image_info *spl_image, - struct spl_boot_device *bootdev, - int offset, struct legacy_img_hdr *header) + struct spl_boot_device *bootdev, int offset) { - int bl_len; - int err; + struct spl_load_info load; - err = nand_spl_load_image(offset, sizeof(*header), (void *)header); - if (err) - return err; - - bl_len = nand_page_size(); - if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) && - image_get_magic(header) == FDT_MAGIC) { - struct spl_load_info load; - - debug("Found FIT\n"); - load.dev = NULL; - load.priv = &offset; - load.filename = NULL; - load.bl_len = bl_len; - load.read = spl_nand_fit_read; - return spl_load_simple_fit(spl_image, &load, offset / bl_len, header); - } else if (IS_ENABLED(CONFIG_SPL_LOAD_IMX_CONTAINER) && - valid_container_hdr((void *)header)) { - struct spl_load_info load; - - load.dev = NULL; - load.priv = &offset; - load.filename = NULL; - load.bl_len = bl_len; - load.read = spl_nand_fit_read; - return spl_load_imx_container(spl_image, &load, offset / bl_len); - } else if (IS_ENABLED(CONFIG_SPL_LEGACY_IMAGE_FORMAT) && - image_get_magic(header) == IH_MAGIC) { - struct spl_load_info load; - - debug("Found legacy image\n"); - load.dev = NULL; - load.priv = NULL; - load.filename = NULL; - load.bl_len = 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); - } else { - err = spl_parse_image_header(spl_image, bootdev, header); - if (err) - return err; - return nand_spl_load_image(offset, spl_image->size, - map_sysmem(spl_image->load_addr, - spl_image->size)); - } + load.priv = &offset; + spl_set_bl_len(&load, 1); + load.read = spl_nand_read; + return spl_load(spl_image, bootdev, &load, 0, offset); } static int spl_nand_load_image(struct spl_image_info *spl_image, struct spl_boot_device *bootdev) { int err; - struct legacy_img_hdr *header; - int *src __attribute__((unused)); - int *dst __attribute__((unused)); #ifdef CONFIG_SPL_NAND_SOFTECC debug("spl: nand - using sw ecc\n"); @@ -144,10 +90,12 @@ static int spl_nand_load_image(struct spl_image_info *spl_image, #endif nand_init(); - header = spl_get_load_buffer(0, sizeof(*header)); - #if CONFIG_IS_ENABLED(OS_BOOT) if (!spl_start_uboot()) { + int *src, *dst; + struct legacy_img_hdr *header = + spl_get_load_buffer(0, sizeof(*header)); + /* * load parameter image * load to temp position since nand_spl_load_image reads @@ -190,20 +138,18 @@ static int spl_nand_load_image(struct spl_image_info *spl_image, } #endif #ifdef CONFIG_NAND_ENV_DST - spl_nand_load_element(spl_image, bootdev, CONFIG_ENV_OFFSET, header); + spl_nand_load_element(spl_image, bootdev, CONFIG_ENV_OFFSET); #ifdef CONFIG_ENV_OFFSET_REDUND - spl_nand_load_element(spl_image, bootdev, CONFIG_ENV_OFFSET_REDUND, header); + spl_nand_load_element(spl_image, bootdev, CONFIG_ENV_OFFSET_REDUND); #endif #endif /* Load u-boot */ - err = spl_nand_load_element(spl_image, bootdev, spl_nand_get_uboot_raw_page(), - header); + err = spl_nand_load_element(spl_image, bootdev, spl_nand_get_uboot_raw_page()); #ifdef CONFIG_SYS_NAND_U_BOOT_OFFS_REDUND #if CONFIG_SYS_NAND_U_BOOT_OFFS != CONFIG_SYS_NAND_U_BOOT_OFFS_REDUND if (err) err = spl_nand_load_element(spl_image, bootdev, - CONFIG_SYS_NAND_U_BOOT_OFFS_REDUND, - header); + CONFIG_SYS_NAND_U_BOOT_OFFS_REDUND); #endif #endif nand_deselect(); diff --git a/common/spl/spl_net.c b/common/spl/spl_net.c index f01d4df..898f9df 100644 --- a/common/spl/spl_net.c +++ b/common/spl/spl_net.c @@ -11,8 +11,8 @@ #include <errno.h> #include <image.h> #include <log.h> -#include <mapmem.h> #include <spl.h> +#include <spl_load.h> #include <net.h> #include <linux/libfdt.h> @@ -29,8 +29,7 @@ static ulong spl_net_load_read(struct spl_load_info *load, ulong sector, static int spl_net_load_image(struct spl_image_info *spl_image, struct spl_boot_device *bootdev) { - struct legacy_img_hdr *header = map_sysmem(image_load_addr, - sizeof(*header)); + struct spl_load_info load; int rv; env_init(); @@ -49,27 +48,9 @@ static int spl_net_load_image(struct spl_image_info *spl_image, return rv; } - if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) && - image_get_magic(header) == FDT_MAGIC) { - struct spl_load_info load; - - debug("Found FIT\n"); - load.bl_len = 1; - load.read = spl_net_load_read; - rv = spl_load_simple_fit(spl_image, &load, 0, header); - } else { - debug("Legacy image\n"); - - rv = spl_parse_image_header(spl_image, bootdev, header); - if (rv) - return rv; - - memcpy(map_sysmem(spl_image->load_addr, spl_image->size), - map_sysmem(image_load_addr, spl_image->size), - spl_image->size); - } - - return rv; + spl_set_bl_len(&load, 1); + load.read = spl_net_load_read; + return spl_load(spl_image, bootdev, &load, 0, 0); } #endif diff --git a/common/spl/spl_nor.c b/common/spl/spl_nor.c index 236b071..7074511 100644 --- a/common/spl/spl_nor.c +++ b/common/spl/spl_nor.c @@ -7,8 +7,8 @@ #include <image.h> #include <imx_container.h> #include <log.h> -#include <mapmem.h> #include <spl.h> +#include <spl_load.h> static ulong spl_nor_load_read(struct spl_load_info *load, ulong sector, ulong count, void *buf) @@ -28,8 +28,7 @@ unsigned long __weak spl_nor_get_uboot_base(void) static int spl_nor_load_image(struct spl_image_info *spl_image, struct spl_boot_device *bootdev) { - struct legacy_img_hdr *header; - __maybe_unused struct spl_load_info load; + struct spl_load_info load; /* * Loading of the payload to SDRAM is done with skipping of @@ -43,13 +42,14 @@ static int spl_nor_load_image(struct spl_image_info *spl_image, * Load Linux from its location in NOR flash to its defined * location in SDRAM */ - header = (void *)CONFIG_SYS_OS_BASE; + const struct legacy_img_hdr *header = + (const struct legacy_img_hdr *)CONFIG_SYS_OS_BASE; #ifdef CONFIG_SPL_LOAD_FIT if (image_get_magic(header) == FDT_MAGIC) { 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, @@ -93,34 +93,8 @@ static int spl_nor_load_image(struct spl_image_info *spl_image, * Load real U-Boot from its location in NOR flash to its * defined location in SDRAM */ - header = map_sysmem(spl_nor_get_uboot_base(), sizeof(*header)); -#ifdef CONFIG_SPL_LOAD_FIT - if (image_get_magic(header) == FDT_MAGIC) { - debug("Found FIT format U-Boot\n"); - load.bl_len = 1; - load.read = spl_nor_load_read; - return spl_load_simple_fit(spl_image, &load, - spl_nor_get_uboot_base(), - (void *)header); - } -#endif - if (IS_ENABLED(CONFIG_SPL_LOAD_IMX_CONTAINER) && - valid_container_hdr((void *)header)) { - load.bl_len = 1; - load.read = spl_nor_load_read; - return spl_load_imx_container(spl_image, &load, - spl_nor_get_uboot_base()); - } - - /* Legacy image handling */ - if (IS_ENABLED(CONFIG_SPL_LEGACY_IMAGE_FORMAT)) { - load.bl_len = 1; - load.read = spl_nor_load_read; - return spl_load_legacy_img(spl_image, bootdev, &load, - spl_nor_get_uboot_base(), - header); - } - - return -EINVAL; + spl_set_bl_len(&load, 1); + load.read = spl_nor_load_read; + return spl_load(spl_image, bootdev, &load, 0, spl_nor_get_uboot_base()); } SPL_LOAD_IMAGE_METHOD("NOR", 0, BOOT_DEVICE_NOR, spl_nor_load_image); diff --git a/common/spl/spl_ram.c b/common/spl/spl_ram.c index 4158ed1..8aeda23 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 f7dd289..941fa91 100644 --- a/common/spl/spl_semihosting.c +++ b/common/spl/spl_semihosting.c @@ -8,34 +8,19 @@ #include <log.h> #include <semihosting.h> #include <spl.h> - -static int smh_read_full(long fd, void *memp, size_t len) -{ - long read; - - read = smh_read(fd, memp, len); - if (read < 0) - return read; - if (read != len) - return -EIO; - return 0; -} +#include <spl_load.h> static ulong smh_fit_read(struct spl_load_info *load, ulong file_offset, ulong size, void *buf) { - long fd; + long fd = *(long *)load->priv; ulong ret; - fd = smh_open(load->filename, MODE_READ | MODE_BINARY); - if (fd < 0) { - log_debug("could not open %s: %ld\n", load->filename, fd); + if (smh_seek(fd, file_offset)) return 0; - } - ret = smh_read(fd, buf, size); - smh_close(fd); - return ret; + ret = smh_read(fd, buf, size); + return ret < 0 ? 0 : ret; } static int spl_smh_load_image(struct spl_image_info *spl_image, @@ -44,8 +29,7 @@ static int spl_smh_load_image(struct spl_image_info *spl_image, const char *filename = CONFIG_SPL_FS_LOAD_PAYLOAD_NAME; int ret; long fd, len; - struct legacy_img_hdr *header = - spl_get_load_buffer(-sizeof(*header), sizeof(*header)); + struct spl_load_info load; fd = smh_open(filename, MODE_READ | MODE_BINARY); if (fd < 0) { @@ -60,39 +44,10 @@ static int spl_smh_load_image(struct spl_image_info *spl_image, } len = ret; - ret = smh_read_full(fd, header, sizeof(struct legacy_img_hdr)); - if (ret) { - log_debug("could not read image header: %d\n", ret); - goto out; - } - - if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) && - image_get_magic(header) == FDT_MAGIC) { - struct spl_load_info load; - - debug("Found FIT\n"); - load.read = smh_fit_read; - load.bl_len = 1; - load.filename = filename; - load.priv = NULL; - smh_close(fd); - - return spl_load_simple_fit(spl_image, &load, 0, header); - } - - ret = spl_parse_image_header(spl_image, bootdev, header); - if (ret) { - log_debug("failed to parse image header: %d\n", ret); - goto out; - } - - ret = smh_seek(fd, 0); - if (ret) { - log_debug("could not seek to start of image: %d\n", ret); - goto out; - } - - ret = smh_read_full(fd, (void *)spl_image->load_addr, len); + load.read = smh_fit_read; + spl_set_bl_len(&load, 1); + load.priv = &fd; + ret = spl_load(spl_image, bootdev, &load, len, 0); if (ret) log_debug("could not read %s: %d\n", filename, ret); out: diff --git a/common/spl/spl_spi.c b/common/spl/spl_spi.c index 3ac4b1b..89de73c 100644 --- a/common/spl/spl_spi.c +++ b/common/spl/spl_spi.c @@ -12,54 +12,19 @@ #include <image.h> #include <imx_container.h> #include <log.h> -#include <mapmem.h> #include <spi.h> #include <spi_flash.h> #include <errno.h> #include <spl.h> +#include <spl_load.h> #include <asm/global_data.h> #include <asm/io.h> #include <dm/ofnode.h> -#if CONFIG_IS_ENABLED(OS_BOOT) -/* - * Load the kernel, check for a valid header we can parse, and if found load - * the kernel and then device tree. - */ -static int spi_load_image_os(struct spl_image_info *spl_image, - struct spl_boot_device *bootdev, - struct spi_flash *flash, - struct legacy_img_hdr *header) -{ - int err; - - /* Read for a header, parse or error out. */ - spi_flash_read(flash, CFG_SYS_SPI_KERNEL_OFFS, sizeof(*header), - (void *)header); - - if (image_get_magic(header) != IH_MAGIC) - return -1; - - err = spl_parse_image_header(spl_image, bootdev, header); - if (err) - return err; - - spi_flash_read(flash, CFG_SYS_SPI_KERNEL_OFFS, - spl_image->size, (void *)spl_image->load_addr); - - /* Read device tree. */ - spi_flash_read(flash, CFG_SYS_SPI_ARGS_OFFS, - CFG_SYS_SPI_ARGS_SIZE, - (void *)CONFIG_SPL_PAYLOAD_ARGS_ADDR); - - return 0; -} -#endif - static ulong spl_spi_fit_read(struct spl_load_info *load, ulong sector, ulong count, void *buf) { - struct spi_flash *flash = load->dev; + struct spi_flash *flash = load->priv; ulong ret; ret = spi_flash_read(flash, sector, count, buf); @@ -95,9 +60,9 @@ static int spl_spi_load_image(struct spl_image_info *spl_image, int err = 0; unsigned int payload_offs; struct spi_flash *flash; - struct legacy_img_hdr *header; unsigned int sf_bus = spl_spi_boot_bus(); unsigned int sf_cs = spl_spi_boot_cs(); + struct spl_load_info load; /* * Load U-Boot image from SPI flash into RAM @@ -112,81 +77,32 @@ static int spl_spi_load_image(struct spl_image_info *spl_image, return -ENODEV; } - payload_offs = spl_spi_get_uboot_offs(flash); + load.priv = flash; + spl_set_bl_len(&load, 1); + load.read = spl_spi_fit_read; - header = spl_get_load_buffer(-sizeof(*header), sizeof(*header)); +#if CONFIG_IS_ENABLED(OS_BOOT) + if (spl_start_uboot()) { + int err = spl_load(spl_image, bootdev, &load, 0, + CFG_SYS_SPI_KERNEL_OFFS); + + if (!err) + /* Read device tree. */ + return spi_flash_read(flash, CFG_SYS_SPI_ARGS_OFFS, + CFG_SYS_SPI_ARGS_SIZE, + (void *)CONFIG_SPL_PAYLOAD_ARGS_ADDR); + } +#endif + payload_offs = spl_spi_get_uboot_offs(flash); if (CONFIG_IS_ENABLED(OF_REAL)) { payload_offs = ofnode_conf_read_int("u-boot,spl-payload-offset", payload_offs); } -#if CONFIG_IS_ENABLED(OS_BOOT) - if (spl_start_uboot() || spi_load_image_os(spl_image, bootdev, flash, header)) -#endif - { - /* Load u-boot, mkimage header is 64 bytes. */ - err = spi_flash_read(flash, payload_offs, sizeof(*header), - (void *)header); - if (err) { - debug("%s: Failed to read from SPI flash (err=%d)\n", - __func__, err); - return err; - } - - if (IS_ENABLED(CONFIG_SPL_LOAD_FIT_FULL) && - image_get_magic(header) == FDT_MAGIC) { - u32 size = roundup(fdt_totalsize(header), 4); - - err = spi_flash_read(flash, payload_offs, - size, - map_sysmem(CONFIG_SYS_LOAD_ADDR, - size)); - if (err) - return err; - err = spl_parse_image_header(spl_image, bootdev, - phys_to_virt(CONFIG_SYS_LOAD_ADDR)); - } else if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) && - image_get_magic(header) == FDT_MAGIC) { - struct spl_load_info load; - - debug("Found FIT\n"); - load.dev = flash; - load.priv = NULL; - load.filename = NULL; - load.bl_len = 1; - load.read = spl_spi_fit_read; - err = spl_load_simple_fit(spl_image, &load, - payload_offs, - header); - } else if (IS_ENABLED(CONFIG_SPL_LOAD_IMX_CONTAINER) && - valid_container_hdr((void *)header)) { - struct spl_load_info load; - - load.dev = flash; - load.priv = NULL; - load.filename = NULL; - load.bl_len = 1; - load.read = spl_spi_fit_read; - - err = spl_load_imx_container(spl_image, &load, - payload_offs); - } else { - err = spl_parse_image_header(spl_image, bootdev, header); - if (err) - return err; - err = spi_flash_read(flash, payload_offs + spl_image->offset, - spl_image->size, - map_sysmem(spl_image->load_addr, - spl_image->size)); - } - if (IS_ENABLED(CONFIG_SPI_FLASH_SOFT_RESET)) { - err = spi_nor_remove(flash); - if (err) - return err; - } - } - + err = spl_load(spl_image, bootdev, &load, 0, payload_offs); + if (IS_ENABLED(CONFIG_SPI_FLASH_SOFT_RESET)) + err = spi_nor_remove(flash); return err; } /* Use priorty 1 so that boards can override this */ diff --git a/common/spl/spl_ymodem.c b/common/spl/spl_ymodem.c index 038b443..1faaa2c 100644 --- a/common/spl/spl_ymodem.c +++ b/common/spl/spl_ymodem.c @@ -134,10 +134,8 @@ int spl_ymodem_load_image(struct spl_image_info *spl_image, struct ymodem_fit_info info; debug("Found FIT\n"); - load.dev = NULL; load.priv = (void *)&info; - load.filename = NULL; - load.bl_len = 1; + spl_set_bl_len(&load, 1); info.buf = buf; info.image_read = BUF_SIZE; load.read = ymodem_read_fit; |