From patchwork Wed Feb 12 07:49:03 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Weijie Gao X-Patchwork-Id: 236176 List-Id: U-Boot discussion From: weijie.gao at mediatek.com (Weijie Gao) Date: Wed, 12 Feb 2020 15:49:03 +0800 Subject: [PATCH v4 17/20] spl: nor: add lzma decompression support for legacy image Message-ID: <1581493743-8992-1-git-send-email-weijie.gao@mediatek.com> This patch adds support for decompressing LZMA compressed u-boot payload in legacy uImage format. Using this patch together with u-boot-lzma.img is useful for NOR flashes as they can reduce the size and load time of u-boot payload. Reviewed-by: Stefan Roese Signed-off-by: Weijie Gao --- Changes since v3: none --- common/spl/spl_nor.c | 59 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 54 insertions(+), 5 deletions(-) diff --git a/common/spl/spl_nor.c b/common/spl/spl_nor.c index b1e79b9ded..7c81fb28f6 100644 --- a/common/spl/spl_nor.c +++ b/common/spl/spl_nor.c @@ -4,8 +4,19 @@ */ #include +#include #include +#if IS_ENABLED(CONFIG_SPL_LZMA) +#include +#include +#include +#endif + +#ifndef CONFIG_SYS_BOOTM_LEN +#define CONFIG_SYS_BOOTM_LEN (8 << 20) +#endif + static ulong spl_nor_load_read(struct spl_load_info *load, ulong sector, ulong count, void *buf) { @@ -27,6 +38,9 @@ static int spl_nor_load_image(struct spl_image_info *spl_image, int ret; __maybe_unused const struct image_header *header; __maybe_unused struct spl_load_info load; + __maybe_unused SizeT lzma_len; + struct image_header hdr; + uintptr_t dataptr; /* * Loading of the payload to SDRAM is done with skipping of @@ -107,14 +121,49 @@ static int spl_nor_load_image(struct spl_image_info *spl_image, spl_nor_get_uboot_base()); } - ret = spl_parse_image_header(spl_image, - (const struct image_header *)spl_nor_get_uboot_base()); + /* Payload image may not be aligned, so copy it for safety. */ + memcpy(&hdr, (void *)spl_nor_get_uboot_base(), sizeof(hdr)); + ret = spl_parse_image_header(spl_image, &hdr); if (ret) return ret; - memcpy((void *)(unsigned long)spl_image->load_addr, - (void *)(spl_nor_get_uboot_base() + sizeof(struct image_header)), - spl_image->size); + dataptr = spl_nor_get_uboot_base() + sizeof(struct image_header); + + switch (image_get_comp(&hdr)) { + case IH_COMP_NONE: + memmove((void *)(unsigned long)spl_image->load_addr, + (void *)dataptr, spl_image->size); + break; +#if IS_ENABLED(CONFIG_SPL_LZMA) + case IH_COMP_LZMA: + lzma_len = CONFIG_SYS_BOOTM_LEN; + + ret = lzmaBuffToBuffDecompress((void *)spl_image->load_addr, + &lzma_len, (void *)dataptr, + spl_image->size); + + if (ret) { + printf("LZMA decompression error: %d\n", ret); + return ret; + } + + spl_image->size = lzma_len; + break; +#endif + default: + debug("Compression method %s is not supported\n", + genimg_get_comp_short_name(image_get_comp(&hdr))); + return -EINVAL; + } + + flush_cache((unsigned long)spl_image->load_addr, spl_image->size); + + /* + * If the image did not provide an entry point, assume the entry point + * is the same as its load address. + */ + if (!spl_image->entry_point) + spl_image->entry_point = spl_image->load_addr; return 0; }