summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/Makefile14
-rw-r--r--common/board_f.c28
-rw-r--r--common/bootm.c4
-rw-r--r--common/dlmalloc.c7
-rw-r--r--common/fb_mmc.c406
-rw-r--r--common/fb_nand.c230
-rw-r--r--common/image-fit.c425
-rw-r--r--common/image-sparse.c259
-rw-r--r--common/menu.c3
-rw-r--r--common/spl/spl.c75
-rw-r--r--common/spl/spl_fit.c35
11 files changed, 371 insertions, 1115 deletions
diff --git a/common/Makefile b/common/Makefile
index d0681c7dd96..b3da72ebb2c 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -29,7 +29,6 @@ obj-$(CONFIG_CMD_BOOTI) += bootm.o bootm_os.o
obj-$(CONFIG_CMD_BEDBUG) += bedbug.o
obj-$(CONFIG_$(SPL_TPL_)OF_LIBFDT) += fdt_support.o
-
obj-$(CONFIG_MII) += miiphyutil.o
obj-$(CONFIG_CMD_MII) += miiphyutil.o
obj-$(CONFIG_PHYLIB) += miiphyutil.o
@@ -109,19 +108,6 @@ obj-$(CONFIG_IO_TRACE) += iotrace.o
obj-y += memsize.o
obj-y += stdio.o
-ifndef CONFIG_SPL_BUILD
-# This option is not just y/n - it can have a numeric value
-ifdef CONFIG_FASTBOOT_FLASH
-obj-y += image-sparse.o
-ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV
-obj-y += fb_mmc.o
-endif
-ifdef CONFIG_FASTBOOT_FLASH_NAND_DEV
-obj-y += fb_nand.o
-endif
-endif
-endif
-
ifdef CONFIG_CMD_EEPROM_LAYOUT
obj-y += eeprom/eeprom_field.o eeprom/eeprom_layout.o
endif
diff --git a/common/board_f.c b/common/board_f.c
index fa667c764bc..e943347ce3d 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -394,19 +394,21 @@ static int reserve_trace(void)
static int reserve_uboot(void)
{
- /*
- * reserve memory for U-Boot code, data & bss
- * round down to next 4 kB limit
- */
- gd->relocaddr -= gd->mon_len;
- gd->relocaddr &= ~(4096 - 1);
-#if defined(CONFIG_E500) || defined(CONFIG_MIPS)
- /* round down to next 64 kB limit so that IVPR stays aligned */
- gd->relocaddr &= ~(65536 - 1);
-#endif
-
- debug("Reserving %ldk for U-Boot at: %08lx\n", gd->mon_len >> 10,
- gd->relocaddr);
+ if (!(gd->flags & GD_FLG_SKIP_RELOC)) {
+ /*
+ * reserve memory for U-Boot code, data & bss
+ * round down to next 4 kB limit
+ */
+ gd->relocaddr -= gd->mon_len;
+ gd->relocaddr &= ~(4096 - 1);
+ #if defined(CONFIG_E500) || defined(CONFIG_MIPS)
+ /* round down to next 64 kB limit so that IVPR stays aligned */
+ gd->relocaddr &= ~(65536 - 1);
+ #endif
+
+ debug("Reserving %ldk for U-Boot at: %08lx\n",
+ gd->mon_len >> 10, gd->relocaddr);
+ }
gd->start_addr_sp = gd->relocaddr;
diff --git a/common/bootm.c b/common/bootm.c
index a0ffc1cd679..e789f6818aa 100644
--- a/common/bootm.c
+++ b/common/bootm.c
@@ -46,6 +46,10 @@ static const void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc,
char * const argv[], bootm_headers_t *images,
ulong *os_data, ulong *os_len);
+__weak void board_quiesce_devices(void)
+{
+}
+
#ifdef CONFIG_LMB
static void boot_start_lmb(bootm_headers_t *images)
{
diff --git a/common/dlmalloc.c b/common/dlmalloc.c
index b395eefbf86..edaad299bbb 100644
--- a/common/dlmalloc.c
+++ b/common/dlmalloc.c
@@ -1891,6 +1891,13 @@ Void_t* mEMALIGn(alignment, bytes) size_t alignment; size_t bytes;
if ((long)bytes < 0) return NULL;
+#if CONFIG_VAL(SYS_MALLOC_F_LEN)
+ if (!(gd->flags & GD_FLG_FULL_MALLOC_INIT)) {
+ nb = roundup(bytes, alignment);
+ return malloc_simple(nb);
+ }
+#endif
+
/* If need less alignment than we give anyway, just relay to malloc */
if (alignment <= MALLOC_ALIGNMENT) return mALLOc(bytes);
diff --git a/common/fb_mmc.c b/common/fb_mmc.c
deleted file mode 100644
index 46f0073dbc2..00000000000
--- a/common/fb_mmc.c
+++ /dev/null
@@ -1,406 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Copyright 2014 Broadcom Corporation.
- */
-
-#include <config.h>
-#include <common.h>
-#include <blk.h>
-#include <fastboot.h>
-#include <fb_mmc.h>
-#include <image-sparse.h>
-#include <part.h>
-#include <mmc.h>
-#include <div64.h>
-#include <linux/compat.h>
-#include <android_image.h>
-
-/*
- * FIXME: Ensure we always set these names via Kconfig once xxx_PARTITION is
- * migrated
- */
-#ifndef CONFIG_FASTBOOT_GPT_NAME
-#define CONFIG_FASTBOOT_GPT_NAME "gpt"
-#endif
-
-
-#ifndef CONFIG_FASTBOOT_MBR_NAME
-#define CONFIG_FASTBOOT_MBR_NAME "mbr"
-#endif
-
-#define BOOT_PARTITION_NAME "boot"
-
-struct fb_mmc_sparse {
- struct blk_desc *dev_desc;
-};
-
-static int part_get_info_by_name_or_alias(struct blk_desc *dev_desc,
- const char *name, disk_partition_t *info)
-{
- int ret;
-
- ret = part_get_info_by_name(dev_desc, name, info);
- if (ret < 0) {
- /* strlen("fastboot_partition_alias_") + 32(part_name) + 1 */
- char env_alias_name[25 + 32 + 1];
- char *aliased_part_name;
-
- /* check for alias */
- strcpy(env_alias_name, "fastboot_partition_alias_");
- strncat(env_alias_name, name, 32);
- aliased_part_name = env_get(env_alias_name);
- if (aliased_part_name != NULL)
- ret = part_get_info_by_name(dev_desc,
- aliased_part_name, info);
- }
- return ret;
-}
-
-static lbaint_t fb_mmc_sparse_write(struct sparse_storage *info,
- lbaint_t blk, lbaint_t blkcnt, const void *buffer)
-{
- struct fb_mmc_sparse *sparse = info->priv;
- struct blk_desc *dev_desc = sparse->dev_desc;
-
- return blk_dwrite(dev_desc, blk, blkcnt, buffer);
-}
-
-static lbaint_t fb_mmc_sparse_reserve(struct sparse_storage *info,
- lbaint_t blk, lbaint_t blkcnt)
-{
- return blkcnt;
-}
-
-static void write_raw_image(struct blk_desc *dev_desc, disk_partition_t *info,
- const char *part_name, void *buffer,
- unsigned int download_bytes)
-{
- lbaint_t blkcnt;
- lbaint_t blks;
-
- /* determine number of blocks to write */
- blkcnt = ((download_bytes + (info->blksz - 1)) & ~(info->blksz - 1));
- blkcnt = lldiv(blkcnt, info->blksz);
-
- if (blkcnt > info->size) {
- pr_err("too large for partition: '%s'\n", part_name);
- fastboot_fail("too large for partition");
- return;
- }
-
- puts("Flashing Raw Image\n");
-
- blks = blk_dwrite(dev_desc, info->start, blkcnt, buffer);
- if (blks != blkcnt) {
- pr_err("failed writing to device %d\n", dev_desc->devnum);
- fastboot_fail("failed writing to device");
- return;
- }
-
- printf("........ wrote " LBAFU " bytes to '%s'\n", blkcnt * info->blksz,
- part_name);
- fastboot_okay("");
-}
-
-#ifdef CONFIG_ANDROID_BOOT_IMAGE
-/**
- * Read Android boot image header from boot partition.
- *
- * @param[in] dev_desc MMC device descriptor
- * @param[in] info Boot partition info
- * @param[out] hdr Where to store read boot image header
- *
- * @return Boot image header sectors count or 0 on error
- */
-static lbaint_t fb_mmc_get_boot_header(struct blk_desc *dev_desc,
- disk_partition_t *info,
- struct andr_img_hdr *hdr)
-{
- ulong sector_size; /* boot partition sector size */
- lbaint_t hdr_sectors; /* boot image header sectors count */
- int res;
-
- /* Calculate boot image sectors count */
- sector_size = info->blksz;
- hdr_sectors = DIV_ROUND_UP(sizeof(struct andr_img_hdr), sector_size);
- if (hdr_sectors == 0) {
- pr_err("invalid number of boot sectors: 0");
- fastboot_fail("invalid number of boot sectors: 0");
- return 0;
- }
-
- /* Read the boot image header */
- res = blk_dread(dev_desc, info->start, hdr_sectors, (void *)hdr);
- if (res != hdr_sectors) {
- pr_err("cannot read header from boot partition");
- fastboot_fail("cannot read header from boot partition");
- return 0;
- }
-
- /* Check boot header magic string */
- res = android_image_check_header(hdr);
- if (res != 0) {
- pr_err("bad boot image magic");
- fastboot_fail("boot partition not initialized");
- return 0;
- }
-
- return hdr_sectors;
-}
-
-/**
- * Write downloaded zImage to boot partition and repack it properly.
- *
- * @param dev_desc MMC device descriptor
- * @param download_buffer Address to fastboot buffer with zImage in it
- * @param download_bytes Size of fastboot buffer, in bytes
- *
- * @return 0 on success or -1 on error
- */
-static int fb_mmc_update_zimage(struct blk_desc *dev_desc,
- void *download_buffer,
- unsigned int download_bytes)
-{
- uintptr_t hdr_addr; /* boot image header address */
- struct andr_img_hdr *hdr; /* boot image header */
- lbaint_t hdr_sectors; /* boot image header sectors */
- u8 *ramdisk_buffer;
- u32 ramdisk_sector_start;
- u32 ramdisk_sectors;
- u32 kernel_sector_start;
- u32 kernel_sectors;
- u32 sectors_per_page;
- disk_partition_t info;
- int res;
-
- puts("Flashing zImage\n");
-
- /* Get boot partition info */
- res = part_get_info_by_name(dev_desc, BOOT_PARTITION_NAME, &info);
- if (res < 0) {
- pr_err("cannot find boot partition");
- fastboot_fail("cannot find boot partition");
- return -1;
- }
-
- /* Put boot image header in fastboot buffer after downloaded zImage */
- hdr_addr = (uintptr_t)download_buffer + ALIGN(download_bytes, PAGE_SIZE);
- hdr = (struct andr_img_hdr *)hdr_addr;
-
- /* Read boot image header */
- hdr_sectors = fb_mmc_get_boot_header(dev_desc, &info, hdr);
- if (hdr_sectors == 0) {
- pr_err("unable to read boot image header");
- fastboot_fail("unable to read boot image header");
- return -1;
- }
-
- /* Check if boot image has second stage in it (we don't support it) */
- if (hdr->second_size > 0) {
- pr_err("moving second stage is not supported yet");
- fastboot_fail("moving second stage is not supported yet");
- return -1;
- }
-
- /* Extract ramdisk location */
- sectors_per_page = hdr->page_size / info.blksz;
- ramdisk_sector_start = info.start + sectors_per_page;
- ramdisk_sector_start += DIV_ROUND_UP(hdr->kernel_size, hdr->page_size) *
- sectors_per_page;
- ramdisk_sectors = DIV_ROUND_UP(hdr->ramdisk_size, hdr->page_size) *
- sectors_per_page;
-
- /* Read ramdisk and put it in fastboot buffer after boot image header */
- ramdisk_buffer = (u8 *)hdr + (hdr_sectors * info.blksz);
- res = blk_dread(dev_desc, ramdisk_sector_start, ramdisk_sectors,
- ramdisk_buffer);
- if (res != ramdisk_sectors) {
- pr_err("cannot read ramdisk from boot partition");
- fastboot_fail("cannot read ramdisk from boot partition");
- return -1;
- }
-
- /* Write new kernel size to boot image header */
- hdr->kernel_size = download_bytes;
- res = blk_dwrite(dev_desc, info.start, hdr_sectors, (void *)hdr);
- if (res == 0) {
- pr_err("cannot writeback boot image header");
- fastboot_fail("cannot write back boot image header");
- return -1;
- }
-
- /* Write the new downloaded kernel */
- kernel_sector_start = info.start + sectors_per_page;
- kernel_sectors = DIV_ROUND_UP(hdr->kernel_size, hdr->page_size) *
- sectors_per_page;
- res = blk_dwrite(dev_desc, kernel_sector_start, kernel_sectors,
- download_buffer);
- if (res == 0) {
- pr_err("cannot write new kernel");
- fastboot_fail("cannot write new kernel");
- return -1;
- }
-
- /* Write the saved ramdisk back */
- ramdisk_sector_start = info.start + sectors_per_page;
- ramdisk_sector_start += DIV_ROUND_UP(hdr->kernel_size, hdr->page_size) *
- sectors_per_page;
- res = blk_dwrite(dev_desc, ramdisk_sector_start, ramdisk_sectors,
- ramdisk_buffer);
- if (res == 0) {
- pr_err("cannot write back original ramdisk");
- fastboot_fail("cannot write back original ramdisk");
- return -1;
- }
-
- puts("........ zImage was updated in boot partition\n");
- fastboot_okay("");
- return 0;
-}
-#endif
-
-void fb_mmc_flash_write(const char *cmd, void *download_buffer,
- unsigned int download_bytes)
-{
- struct blk_desc *dev_desc;
- disk_partition_t info;
-
- dev_desc = blk_get_dev("mmc", CONFIG_FASTBOOT_FLASH_MMC_DEV);
- if (!dev_desc || dev_desc->type == DEV_TYPE_UNKNOWN) {
- pr_err("invalid mmc device\n");
- fastboot_fail("invalid mmc device");
- return;
- }
-
-#if CONFIG_IS_ENABLED(EFI_PARTITION)
- if (strcmp(cmd, CONFIG_FASTBOOT_GPT_NAME) == 0) {
- printf("%s: updating MBR, Primary and Backup GPT(s)\n",
- __func__);
- if (is_valid_gpt_buf(dev_desc, download_buffer)) {
- printf("%s: invalid GPT - refusing to write to flash\n",
- __func__);
- fastboot_fail("invalid GPT partition");
- return;
- }
- if (write_mbr_and_gpt_partitions(dev_desc, download_buffer)) {
- printf("%s: writing GPT partitions failed\n", __func__);
- fastboot_fail("writing GPT partitions failed");
- return;
- }
- printf("........ success\n");
- fastboot_okay("");
- return;
- }
-#endif
-
-#if CONFIG_IS_ENABLED(DOS_PARTITION)
- if (strcmp(cmd, CONFIG_FASTBOOT_MBR_NAME) == 0) {
- printf("%s: updating MBR\n", __func__);
- if (is_valid_dos_buf(download_buffer)) {
- printf("%s: invalid MBR - refusing to write to flash\n",
- __func__);
- fastboot_fail("invalid MBR partition");
- return;
- }
- if (write_mbr_partition(dev_desc, download_buffer)) {
- printf("%s: writing MBR partition failed\n", __func__);
- fastboot_fail("writing MBR partition failed");
- return;
- }
- printf("........ success\n");
- fastboot_okay("");
- return;
- }
-#endif
-
-#ifdef CONFIG_ANDROID_BOOT_IMAGE
- if (strncasecmp(cmd, "zimage", 6) == 0) {
- fb_mmc_update_zimage(dev_desc, download_buffer, download_bytes);
- return;
- }
-#endif
-
- if (part_get_info_by_name_or_alias(dev_desc, cmd, &info) < 0) {
- pr_err("cannot find partition: '%s'\n", cmd);
- fastboot_fail("cannot find partition");
- return;
- }
-
- if (is_sparse_image(download_buffer)) {
- struct fb_mmc_sparse sparse_priv;
- struct sparse_storage sparse;
- int err;
-
- sparse_priv.dev_desc = dev_desc;
-
- sparse.blksz = info.blksz;
- sparse.start = info.start;
- sparse.size = info.size;
- sparse.write = fb_mmc_sparse_write;
- sparse.reserve = fb_mmc_sparse_reserve;
- sparse.mssg = fastboot_fail;
-
- printf("Flashing sparse image at offset " LBAFU "\n",
- sparse.start);
-
- sparse.priv = &sparse_priv;
- err = write_sparse_image(&sparse, cmd, download_buffer);
- if (!err)
- fastboot_okay("");
- } else {
- write_raw_image(dev_desc, &info, cmd, download_buffer,
- download_bytes);
- }
-}
-
-void fb_mmc_erase(const char *cmd)
-{
- int ret;
- struct blk_desc *dev_desc;
- disk_partition_t info;
- lbaint_t blks, blks_start, blks_size, grp_size;
- struct mmc *mmc = find_mmc_device(CONFIG_FASTBOOT_FLASH_MMC_DEV);
-
- if (mmc == NULL) {
- pr_err("invalid mmc device");
- fastboot_fail("invalid mmc device");
- return;
- }
-
- dev_desc = blk_get_dev("mmc", CONFIG_FASTBOOT_FLASH_MMC_DEV);
- if (!dev_desc || dev_desc->type == DEV_TYPE_UNKNOWN) {
- pr_err("invalid mmc device");
- fastboot_fail("invalid mmc device");
- return;
- }
-
- ret = part_get_info_by_name_or_alias(dev_desc, cmd, &info);
- if (ret < 0) {
- pr_err("cannot find partition: '%s'", cmd);
- fastboot_fail("cannot find partition");
- return;
- }
-
- /* Align blocks to erase group size to avoid erasing other partitions */
- grp_size = mmc->erase_grp_size;
- blks_start = (info.start + grp_size - 1) & ~(grp_size - 1);
- if (info.size >= grp_size)
- blks_size = (info.size - (blks_start - info.start)) &
- (~(grp_size - 1));
- else
- blks_size = 0;
-
- printf("Erasing blocks " LBAFU " to " LBAFU " due to alignment\n",
- blks_start, blks_start + blks_size);
-
- blks = blk_derase(dev_desc, blks_start, blks_size);
- if (blks != blks_size) {
- pr_err("failed erasing from device %d", dev_desc->devnum);
- fastboot_fail("failed erasing from device");
- return;
- }
-
- printf("........ erased " LBAFU " bytes from '%s'\n",
- blks_size * info.blksz, cmd);
- fastboot_okay("");
-}
diff --git a/common/fb_nand.c b/common/fb_nand.c
deleted file mode 100644
index c07655e49ed..00000000000
--- a/common/fb_nand.c
+++ /dev/null
@@ -1,230 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Copyright 2014 Broadcom Corporation.
- * Copyright 2015 Free Electrons.
- */
-
-#include <config.h>
-#include <common.h>
-
-#include <fastboot.h>
-#include <image-sparse.h>
-
-#include <linux/mtd/mtd.h>
-#include <jffs2/jffs2.h>
-#include <nand.h>
-
-struct fb_nand_sparse {
- struct mtd_info *mtd;
- struct part_info *part;
-};
-
-__weak int board_fastboot_erase_partition_setup(char *name)
-{
- return 0;
-}
-
-__weak int board_fastboot_write_partition_setup(char *name)
-{
- return 0;
-}
-
-static int fb_nand_lookup(const char *partname,
- struct mtd_info **mtd,
- struct part_info **part)
-{
- struct mtd_device *dev;
- int ret;
- u8 pnum;
-
- ret = mtdparts_init();
- if (ret) {
- pr_err("Cannot initialize MTD partitions\n");
- fastboot_fail("cannot init mtdparts");
- return ret;
- }
-
- ret = find_dev_and_part(partname, &dev, &pnum, part);
- if (ret) {
- pr_err("cannot find partition: '%s'", partname);
- fastboot_fail("cannot find partition");
- return ret;
- }
-
- if (dev->id->type != MTD_DEV_TYPE_NAND) {
- pr_err("partition '%s' is not stored on a NAND device",
- partname);
- fastboot_fail("not a NAND device");
- return -EINVAL;
- }
-
- *mtd = get_nand_dev_by_index(dev->id->num);
-
- return 0;
-}
-
-static int _fb_nand_erase(struct mtd_info *mtd, struct part_info *part)
-{
- nand_erase_options_t opts;
- int ret;
-
- memset(&opts, 0, sizeof(opts));
- opts.offset = part->offset;
- opts.length = part->size;
- opts.quiet = 1;
-
- printf("Erasing blocks 0x%llx to 0x%llx\n",
- part->offset, part->offset + part->size);
-
- ret = nand_erase_opts(mtd, &opts);
- if (ret)
- return ret;
-
- printf("........ erased 0x%llx bytes from '%s'\n",
- part->size, part->name);
-
- return 0;
-}
-
-static int _fb_nand_write(struct mtd_info *mtd, struct part_info *part,
- void *buffer, unsigned int offset,
- unsigned int length, size_t *written)
-{
- int flags = WITH_WR_VERIFY;
-
-#ifdef CONFIG_FASTBOOT_FLASH_NAND_TRIMFFS
- flags |= WITH_DROP_FFS;
-#endif
-
- return nand_write_skip_bad(mtd, offset, &length, written,
- part->size - (offset - part->offset),
- buffer, flags);
-}
-
-static lbaint_t fb_nand_sparse_write(struct sparse_storage *info,
- lbaint_t blk, lbaint_t blkcnt, const void *buffer)
-{
- struct fb_nand_sparse *sparse = info->priv;
- size_t written;
- int ret;
-
- ret = _fb_nand_write(sparse->mtd, sparse->part, (void *)buffer,
- blk * info->blksz,
- blkcnt * info->blksz, &written);
- if (ret < 0) {
- printf("Failed to write sparse chunk\n");
- return ret;
- }
-
-/* TODO - verify that the value "written" includes the "bad-blocks" ... */
-
- /*
- * the return value must be 'blkcnt' ("good-blocks") plus the
- * number of "bad-blocks" encountered within this space...
- */
- return written / info->blksz;
-}
-
-static lbaint_t fb_nand_sparse_reserve(struct sparse_storage *info,
- lbaint_t blk, lbaint_t blkcnt)
-{
- int bad_blocks = 0;
-
-/*
- * TODO - implement a function to determine the total number
- * of blocks which must be used in order to reserve the specified
- * number ("blkcnt") of "good-blocks", starting at "blk"...
- * ( possibly something like the "check_skip_len()" function )
- */
-
- /*
- * the return value must be 'blkcnt' ("good-blocks") plus the
- * number of "bad-blocks" encountered within this space...
- */
- return blkcnt + bad_blocks;
-}
-
-void fb_nand_flash_write(const char *cmd, void *download_buffer,
- unsigned int download_bytes)
-{
- struct part_info *part;
- struct mtd_info *mtd = NULL;
- int ret;
-
- ret = fb_nand_lookup(cmd, &mtd, &part);
- if (ret) {
- pr_err("invalid NAND device");
- fastboot_fail("invalid NAND device");
- return;
- }
-
- ret = board_fastboot_write_partition_setup(part->name);
- if (ret)
- return;
-
- if (is_sparse_image(download_buffer)) {
- struct fb_nand_sparse sparse_priv;
- struct sparse_storage sparse;
-
- sparse_priv.mtd = mtd;
- sparse_priv.part = part;
-
- sparse.blksz = mtd->writesize;
- sparse.start = part->offset / sparse.blksz;
- sparse.size = part->size / sparse.blksz;
- sparse.write = fb_nand_sparse_write;
- sparse.reserve = fb_nand_sparse_reserve;
- sparse.mssg = fastboot_fail;
-
- printf("Flashing sparse image at offset " LBAFU "\n",
- sparse.start);
-
- sparse.priv = &sparse_priv;
- ret = write_sparse_image(&sparse, cmd, download_buffer);
- if (!ret)
- fastboot_okay("");
- } else {
- printf("Flashing raw image at offset 0x%llx\n",
- part->offset);
-
- ret = _fb_nand_write(mtd, part, download_buffer, part->offset,
- download_bytes, NULL);
-
- printf("........ wrote %u bytes to '%s'\n",
- download_bytes, part->name);
- }
-
- if (ret) {
- fastboot_fail("error writing the image");
- return;
- }
-
- fastboot_okay("");
-}
-
-void fb_nand_erase(const char *cmd)
-{
- struct part_info *part;
- struct mtd_info *mtd = NULL;
- int ret;
-
- ret = fb_nand_lookup(cmd, &mtd, &part);
- if (ret) {
- pr_err("invalid NAND device");
- fastboot_fail("invalid NAND device");
- return;
- }
-
- ret = board_fastboot_erase_partition_setup(part->name);
- if (ret)
- return;
-
- ret = _fb_nand_erase(mtd, part);
- if (ret) {
- pr_err("failed erasing from device %s", mtd->name);
- fastboot_fail("failed erasing from device");
- return;
- }
-
- fastboot_okay("");
-}
diff --git a/common/image-fit.c b/common/image-fit.c
index 5b93dceae15..728187ac883 100644
--- a/common/image-fit.c
+++ b/common/image-fit.c
@@ -142,7 +142,186 @@ int fit_get_subimage_count(const void *fit, int images_noffset)
return count;
}
-#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_FIT_SPL_PRINT)
+#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_FIT_PRINT)
+/**
+ * fit_image_print_data() - prints out the hash node details
+ * @fit: pointer to the FIT format image header
+ * @noffset: offset of the hash node
+ * @p: pointer to prefix string
+ * @type: Type of information to print ("hash" or "sign")
+ *
+ * fit_image_print_data() lists properties for the processed hash node
+ *
+ * This function avoid using puts() since it prints a newline on the host
+ * but does not in U-Boot.
+ *
+ * returns:
+ * no returned results
+ */
+static void fit_image_print_data(const void *fit, int noffset, const char *p,
+ const char *type)
+{
+ const char *keyname;
+ uint8_t *value;
+ int value_len;
+ char *algo;
+ int required;
+ int ret, i;
+
+ debug("%s %s node: '%s'\n", p, type,
+ fit_get_name(fit, noffset, NULL));
+ printf("%s %s algo: ", p, type);
+ if (fit_image_hash_get_algo(fit, noffset, &algo)) {
+ printf("invalid/unsupported\n");
+ return;
+ }
+ printf("%s", algo);
+ keyname = fdt_getprop(fit, noffset, "key-name-hint", NULL);
+ required = fdt_getprop(fit, noffset, "required", NULL) != NULL;
+ if (keyname)
+ printf(":%s", keyname);
+ if (required)
+ printf(" (required)");
+ printf("\n");
+
+ ret = fit_image_hash_get_value(fit, noffset, &value,
+ &value_len);
+ printf("%s %s value: ", p, type);
+ if (ret) {
+ printf("unavailable\n");
+ } else {
+ for (i = 0; i < value_len; i++)
+ printf("%02x", value[i]);
+ printf("\n");
+ }
+
+ debug("%s %s len: %d\n", p, type, value_len);
+
+ /* Signatures have a time stamp */
+ if (IMAGE_ENABLE_TIMESTAMP && keyname) {
+ time_t timestamp;
+
+ printf("%s Timestamp: ", p);
+ if (fit_get_timestamp(fit, noffset, &timestamp))
+ printf("unavailable\n");
+ else
+ genimg_print_time(timestamp);
+ }
+}
+
+/**
+ * fit_image_print_verification_data() - prints out the hash/signature details
+ * @fit: pointer to the FIT format image header
+ * @noffset: offset of the hash or signature node
+ * @p: pointer to prefix string
+ *
+ * This lists properties for the processed hash node
+ *
+ * returns:
+ * no returned results
+ */
+static void fit_image_print_verification_data(const void *fit, int noffset,
+ const char *p)
+{
+ const char *name;
+
+ /*
+ * Check subnode name, must be equal to "hash" or "signature".
+ * Multiple hash/signature nodes require unique unit node
+ * names, e.g. hash-1, hash-2, signature-1, signature-2, etc.
+ */
+ name = fit_get_name(fit, noffset, NULL);
+ if (!strncmp(name, FIT_HASH_NODENAME, strlen(FIT_HASH_NODENAME))) {
+ fit_image_print_data(fit, noffset, p, "Hash");
+ } else if (!strncmp(name, FIT_SIG_NODENAME,
+ strlen(FIT_SIG_NODENAME))) {
+ fit_image_print_data(fit, noffset, p, "Sign");
+ }
+}
+
+/**
+ * fit_conf_print - prints out the FIT configuration details
+ * @fit: pointer to the FIT format image header
+ * @noffset: offset of the configuration node
+ * @p: pointer to prefix string
+ *
+ * fit_conf_print() lists all mandatory properties for the processed
+ * configuration node.
+ *
+ * returns:
+ * no returned results
+ */
+static void fit_conf_print(const void *fit, int noffset, const char *p)
+{
+ char *desc;
+ const char *uname;
+ int ret;
+ int fdt_index, loadables_index;
+ int ndepth;
+
+ /* Mandatory properties */
+ ret = fit_get_desc(fit, noffset, &desc);
+ printf("%s Description: ", p);
+ if (ret)
+ printf("unavailable\n");
+ else
+ printf("%s\n", desc);
+
+ uname = fdt_getprop(fit, noffset, FIT_KERNEL_PROP, NULL);
+ printf("%s Kernel: ", p);
+ if (!uname)
+ printf("unavailable\n");
+ else
+ printf("%s\n", uname);
+
+ /* Optional properties */
+ uname = fdt_getprop(fit, noffset, FIT_RAMDISK_PROP, NULL);
+ if (uname)
+ printf("%s Init Ramdisk: %s\n", p, uname);
+
+ uname = fdt_getprop(fit, noffset, FIT_FIRMWARE_PROP, NULL);
+ if (uname)
+ printf("%s Firmware: %s\n", p, uname);
+
+ for (fdt_index = 0;
+ uname = fdt_stringlist_get(fit, noffset, FIT_FDT_PROP,
+ fdt_index, NULL), uname;
+ fdt_index++) {
+ if (fdt_index == 0)
+ printf("%s FDT: ", p);
+ else
+ printf("%s ", p);
+ printf("%s\n", uname);
+ }
+
+ uname = fdt_getprop(fit, noffset, FIT_FPGA_PROP, NULL);
+ if (uname)
+ printf("%s FPGA: %s\n", p, uname);
+
+ /* Print out all of the specified loadables */
+ for (loadables_index = 0;
+ uname = fdt_stringlist_get(fit, noffset, FIT_LOADABLE_PROP,
+ loadables_index, NULL), uname;
+ loadables_index++) {
+ if (loadables_index == 0) {
+ printf("%s Loadables: ", p);
+ } else {
+ printf("%s ", p);
+ }
+ printf("%s\n", uname);
+ }
+
+ /* Process all hash subnodes of the component configuration node */
+ for (ndepth = 0, noffset = fdt_next_node(fit, noffset, &ndepth);
+ (noffset >= 0) && (ndepth > 0);
+ noffset = fdt_next_node(fit, noffset, &ndepth)) {
+ if (ndepth == 1) {
+ /* Direct child node of the component configuration node */
+ fit_image_print_verification_data(fit, noffset, p);
+ }
+ }
+}
+
/**
* fit_print_contents - prints out the contents of the FIT format image
* @fit: pointer to the FIT format image header
@@ -245,102 +424,6 @@ void fit_print_contents(const void *fit)
}
/**
- * fit_image_print_data() - prints out the hash node details
- * @fit: pointer to the FIT format image header
- * @noffset: offset of the hash node
- * @p: pointer to prefix string
- * @type: Type of information to print ("hash" or "sign")
- *
- * fit_image_print_data() lists properties for the processed hash node
- *
- * This function avoid using puts() since it prints a newline on the host
- * but does not in U-Boot.
- *
- * returns:
- * no returned results
- */
-static void fit_image_print_data(const void *fit, int noffset, const char *p,
- const char *type)
-{
- const char *keyname;
- uint8_t *value;
- int value_len;
- char *algo;
- int required;
- int ret, i;
-
- debug("%s %s node: '%s'\n", p, type,
- fit_get_name(fit, noffset, NULL));
- printf("%s %s algo: ", p, type);
- if (fit_image_hash_get_algo(fit, noffset, &algo)) {
- printf("invalid/unsupported\n");
- return;
- }
- printf("%s", algo);
- keyname = fdt_getprop(fit, noffset, "key-name-hint", NULL);
- required = fdt_getprop(fit, noffset, "required", NULL) != NULL;
- if (keyname)
- printf(":%s", keyname);
- if (required)
- printf(" (required)");
- printf("\n");
-
- ret = fit_image_hash_get_value(fit, noffset, &value,
- &value_len);
- printf("%s %s value: ", p, type);
- if (ret) {
- printf("unavailable\n");
- } else {
- for (i = 0; i < value_len; i++)
- printf("%02x", value[i]);
- printf("\n");
- }
-
- debug("%s %s len: %d\n", p, type, value_len);
-
- /* Signatures have a time stamp */
- if (IMAGE_ENABLE_TIMESTAMP && keyname) {
- time_t timestamp;
-
- printf("%s Timestamp: ", p);
- if (fit_get_timestamp(fit, noffset, &timestamp))
- printf("unavailable\n");
- else
- genimg_print_time(timestamp);
- }
-}
-
-/**
- * fit_image_print_verification_data() - prints out the hash/signature details
- * @fit: pointer to the FIT format image header
- * @noffset: offset of the hash or signature node
- * @p: pointer to prefix string
- *
- * This lists properties for the processed hash node
- *
- * returns:
- * no returned results
- */
-static void fit_image_print_verification_data(const void *fit, int noffset,
- const char *p)
-{
- const char *name;
-
- /*
- * Check subnode name, must be equal to "hash" or "signature".
- * Multiple hash/signature nodes require unique unit node
- * names, e.g. hash-1, hash-2, signature-1, signature-2, etc.
- */
- name = fit_get_name(fit, noffset, NULL);
- if (!strncmp(name, FIT_HASH_NODENAME, strlen(FIT_HASH_NODENAME))) {
- fit_image_print_data(fit, noffset, p, "Hash");
- } else if (!strncmp(name, FIT_SIG_NODENAME,
- strlen(FIT_SIG_NODENAME))) {
- fit_image_print_data(fit, noffset, p, "Sign");
- }
-}
-
-/**
* fit_image_print - prints out the FIT component image details
* @fit: pointer to the FIT format image header
* @image_noffset: offset of the component image node
@@ -391,7 +474,7 @@ void fit_image_print(const void *fit, int image_noffset, const char *p)
fit_image_get_comp(fit, image_noffset, &comp);
printf("%s Compression: %s\n", p, genimg_get_comp_name(comp));
- ret = fit_image_get_data(fit, image_noffset, &data, &size);
+ ret = fit_image_get_data_and_size(fit, image_noffset, &data, &size);
#ifndef USE_HOSTCC
printf("%s Data Start: ", p);
@@ -459,8 +542,10 @@ void fit_image_print(const void *fit, int image_noffset, const char *p)
}
}
}
-
-#endif /* !defined(CONFIG_SPL_BUILD) || defined(CONFIG_FIT_SPL_PRINT) */
+#else
+void fit_print_contents(const void *fit) { }
+void fit_image_print(const void *fit, int image_noffset, const char *p) { }
+#endif /* !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_FIT_PRINT) */
/**
* fit_get_desc - get node description property
@@ -856,6 +941,54 @@ int fit_image_get_data_size(const void *fit, int noffset, int *data_size)
}
/**
+ * fit_image_get_data_and_size - get data and its size including
+ * both embedded and external data
+ * @fit: pointer to the FIT format image header
+ * @noffset: component image node offset
+ * @data: double pointer to void, will hold data property's data address
+ * @size: pointer to size_t, will hold data property's data size
+ *
+ * fit_image_get_data_and_size() finds data and its size including
+ * both embedded and external data. If the property is found
+ * its data start address and size are returned to the caller.
+ *
+ * returns:
+ * 0, on success
+ * otherwise, on failure
+ */
+int fit_image_get_data_and_size(const void *fit, int noffset,
+ const void **data, size_t *size)
+{
+ bool external_data = false;
+ int offset;
+ int len;
+ int ret;
+
+ if (!fit_image_get_data_position(fit, noffset, &offset)) {
+ external_data = true;
+ } else if (!fit_image_get_data_offset(fit, noffset, &offset)) {
+ external_data = true;
+ /*
+ * For FIT with external data, figure out where
+ * the external images start. This is the base
+ * for the data-offset properties in each image.
+ */
+ offset += ((fdt_totalsize(fit) + 3) & ~3);
+ }
+
+ if (external_data) {
+ debug("External Data\n");
+ ret = fit_image_get_data_size(fit, noffset, &len);
+ *data = fit + offset;
+ *size = len;
+ } else {
+ ret = fit_image_get_data(fit, noffset, data, size);
+ }
+
+ return ret;
+}
+
+/**
* fit_image_hash_get_algo - get hash algorithm name
* @fit: pointer to the FIT format image header
* @noffset: hash node offset
@@ -1153,7 +1286,7 @@ int fit_image_verify(const void *fit, int image_noffset)
char *err_msg = "";
/* Get image data and data length */
- if (fit_image_get_data(fit, image_noffset, &data, &size)) {
+ if (fit_image_get_data_and_size(fit, image_noffset, &data, &size)) {
err_msg = "Can't get image data/size";
printf("error!\n%s for '%s' hash node in '%s' image node\n",
err_msg, fit_get_name(fit, noffset, NULL),
@@ -1571,92 +1704,6 @@ int fit_conf_get_prop_node(const void *fit, int noffset,
return fit_conf_get_prop_node_index(fit, noffset, prop_name, 0);
}
-#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_FIT_SPL_PRINT)
-/**
- * fit_conf_print - prints out the FIT configuration details
- * @fit: pointer to the FIT format image header
- * @noffset: offset of the configuration node
- * @p: pointer to prefix string
- *
- * fit_conf_print() lists all mandatory properties for the processed
- * configuration node.
- *
- * returns:
- * no returned results
- */
-void fit_conf_print(const void *fit, int noffset, const char *p)
-{
- char *desc;
- const char *uname;
- int ret;
- int fdt_index, loadables_index;
- int ndepth;
-
- /* Mandatory properties */
- ret = fit_get_desc(fit, noffset, &desc);
- printf("%s Description: ", p);
- if (ret)
- printf("unavailable\n");
- else
- printf("%s\n", desc);
-
- uname = fdt_getprop(fit, noffset, FIT_KERNEL_PROP, NULL);
- printf("%s Kernel: ", p);
- if (uname == NULL)
- printf("unavailable\n");
- else
- printf("%s\n", uname);
-
- /* Optional properties */
- uname = fdt_getprop(fit, noffset, FIT_RAMDISK_PROP, NULL);
- if (uname)
- printf("%s Init Ramdisk: %s\n", p, uname);
-
- uname = fdt_getprop(fit, noffset, FIT_FIRMWARE_PROP, NULL);
- if (uname)
- printf("%s Firmware: %s\n", p, uname);
-
- for (fdt_index = 0;
- uname = fdt_stringlist_get(fit, noffset, FIT_FDT_PROP,
- fdt_index, NULL), uname;
- fdt_index++) {
-
- if (fdt_index == 0)
- printf("%s FDT: ", p);
- else
- printf("%s ", p);
- printf("%s\n", uname);
- }
-
- uname = fdt_getprop(fit, noffset, FIT_FPGA_PROP, NULL);
- if (uname)
- printf("%s FPGA: %s\n", p, uname);
-
- /* Print out all of the specified loadables */
- for (loadables_index = 0;
- uname = fdt_stringlist_get(fit, noffset, FIT_LOADABLE_PROP,
- loadables_index, NULL), uname;
- loadables_index++) {
- if (loadables_index == 0) {
- printf("%s Loadables: ", p);
- } else {
- printf("%s ", p);
- }
- printf("%s\n", uname);
- }
-
- /* Process all hash subnodes of the component configuration node */
- for (ndepth = 0, noffset = fdt_next_node(fit, noffset, &ndepth);
- (noffset >= 0) && (ndepth > 0);
- noffset = fdt_next_node(fit, noffset, &ndepth)) {
- if (ndepth == 1) {
- /* Direct child node of the component configuration node */
- fit_image_print_verification_data(fit, noffset, p);
- }
- }
-}
-#endif /* !defined(CONFIG_SPL_BUILD) || defined(CONFIG_FIT_SPL_PRINT) */
-
static int fit_image_select(const void *fit, int rd_noffset, int verify)
{
fit_image_print(fit, rd_noffset, " ");
@@ -1726,6 +1773,8 @@ static const char *fit_get_image_type_property(int type)
return FIT_LOADABLE_PROP;
case IH_TYPE_FPGA:
return FIT_FPGA_PROP;
+ case IH_TYPE_STANDALONE:
+ return FIT_STANDALONE_PROP;
}
return "unknown";
@@ -1875,7 +1924,7 @@ int fit_image_load(bootm_headers_t *images, ulong addr,
bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ALL_OK);
/* get image data address and length */
- if (fit_image_get_data(fit, noffset, &buf, &size)) {
+ if (fit_image_get_data_and_size(fit, noffset, &buf, &size)) {
printf("Could not find %s subimage data!\n", prop_name);
bootstage_error(bootstage_id + BOOTSTAGE_SUB_GET_DATA);
return -ENOENT;
diff --git a/common/image-sparse.c b/common/image-sparse.c
deleted file mode 100644
index 9223b9a1b86..00000000000
--- a/common/image-sparse.c
+++ /dev/null
@@ -1,259 +0,0 @@
-/*
- * Copyright (c) 2009, Google Inc.
- * All rights reserved.
- *
- * Copyright (c) 2009-2014, The Linux Foundation. All rights reserved.
- * Portions Copyright 2014 Broadcom Corporation.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of The Linux Foundation nor
- * the names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * NOTE:
- * Although it is very similar, this license text is not identical
- * to the "BSD-3-Clause", therefore, DO NOT MODIFY THIS LICENSE TEXT!
- */
-
-#include <config.h>
-#include <common.h>
-#include <image-sparse.h>
-#include <div64.h>
-#include <malloc.h>
-#include <part.h>
-#include <sparse_format.h>
-
-#include <linux/math64.h>
-
-#ifndef CONFIG_FASTBOOT_FLASH_FILLBUF_SIZE
-#define CONFIG_FASTBOOT_FLASH_FILLBUF_SIZE (1024 * 512)
-#endif
-
-static void default_log(const char *ignored) {}
-
-int write_sparse_image(struct sparse_storage *info,
- const char *part_name, void *data)
-{
- lbaint_t blk;
- lbaint_t blkcnt;
- lbaint_t blks;
- uint32_t bytes_written = 0;
- unsigned int chunk;
- unsigned int offset;
- unsigned int chunk_data_sz;
- uint32_t *fill_buf = NULL;
- uint32_t fill_val;
- sparse_header_t *sparse_header;
- chunk_header_t *chunk_header;
- uint32_t total_blocks = 0;
- int fill_buf_num_blks;
- int i;
- int j;
-
- fill_buf_num_blks = CONFIG_FASTBOOT_FLASH_FILLBUF_SIZE / info->blksz;
-
- /* Read and skip over sparse image header */
- sparse_header = (sparse_header_t *)data;
-
- data += sparse_header->file_hdr_sz;
- if (sparse_header->file_hdr_sz > sizeof(sparse_header_t)) {
- /*
- * Skip the remaining bytes in a header that is longer than
- * we expected.
- */
- data += (sparse_header->file_hdr_sz - sizeof(sparse_header_t));
- }
-
- if (!info->mssg)
- info->mssg = default_log;
-
- debug("=== Sparse Image Header ===\n");
- debug("magic: 0x%x\n", sparse_header->magic);
- debug("major_version: 0x%x\n", sparse_header->major_version);
- debug("minor_version: 0x%x\n", sparse_header->minor_version);
- debug("file_hdr_sz: %d\n", sparse_header->file_hdr_sz);
- debug("chunk_hdr_sz: %d\n", sparse_header->chunk_hdr_sz);
- debug("blk_sz: %d\n", sparse_header->blk_sz);
- debug("total_blks: %d\n", sparse_header->total_blks);
- debug("total_chunks: %d\n", sparse_header->total_chunks);
-
- /*
- * Verify that the sparse block size is a multiple of our
- * storage backend block size
- */
- div_u64_rem(sparse_header->blk_sz, info->blksz, &offset);
- if (offset) {
- printf("%s: Sparse image block size issue [%u]\n",
- __func__, sparse_header->blk_sz);
- info->mssg("sparse image block size issue");
- return -1;
- }
-
- puts("Flashing Sparse Image\n");
-
- /* Start processing chunks */
- blk = info->start;
- for (chunk = 0; chunk < sparse_header->total_chunks; chunk++) {
- /* Read and skip over chunk header */
- chunk_header = (chunk_header_t *)data;
- data += sizeof(chunk_header_t);
-
- if (chunk_header->chunk_type != CHUNK_TYPE_RAW) {
- debug("=== Chunk Header ===\n");
- debug("chunk_type: 0x%x\n", chunk_header->chunk_type);
- debug("chunk_data_sz: 0x%x\n", chunk_header->chunk_sz);
- debug("total_size: 0x%x\n", chunk_header->total_sz);
- }
-
- if (sparse_header->chunk_hdr_sz > sizeof(chunk_header_t)) {
- /*
- * Skip the remaining bytes in a header that is longer
- * than we expected.
- */
- data += (sparse_header->chunk_hdr_sz -
- sizeof(chunk_header_t));
- }
-
- chunk_data_sz = sparse_header->blk_sz * chunk_header->chunk_sz;
- blkcnt = chunk_data_sz / info->blksz;
- switch (chunk_header->chunk_type) {
- case CHUNK_TYPE_RAW:
- if (chunk_header->total_sz !=
- (sparse_header->chunk_hdr_sz + chunk_data_sz)) {
- info->mssg("Bogus chunk size for chunk type Raw");
- return -1;
- }
-
- if (blk + blkcnt > info->start + info->size) {
- printf(
- "%s: Request would exceed partition size!\n",
- __func__);
- info->mssg("Request would exceed partition size!");
- return -1;
- }
-
- blks = info->write(info, blk, blkcnt, data);
- /* blks might be > blkcnt (eg. NAND bad-blocks) */
- if (blks < blkcnt) {
- printf("%s: %s" LBAFU " [" LBAFU "]\n",
- __func__, "Write failed, block #",
- blk, blks);
- info->mssg("flash write failure");
- return -1;
- }
- blk += blks;
- bytes_written += blkcnt * info->blksz;
- total_blocks += chunk_header->chunk_sz;
- data += chunk_data_sz;
- break;
-
- case CHUNK_TYPE_FILL:
- if (chunk_header->total_sz !=
- (sparse_header->chunk_hdr_sz + sizeof(uint32_t))) {
- info->mssg("Bogus chunk size for chunk type FILL");
- return -1;
- }
-
- fill_buf = (uint32_t *)
- memalign(ARCH_DMA_MINALIGN,
- ROUNDUP(
- info->blksz * fill_buf_num_blks,
- ARCH_DMA_MINALIGN));
- if (!fill_buf) {
- info->mssg("Malloc failed for: CHUNK_TYPE_FILL");
- return -1;
- }
-
- fill_val = *(uint32_t *)data;
- data = (char *)data + sizeof(uint32_t);
-
- for (i = 0;
- i < (info->blksz * fill_buf_num_blks /
- sizeof(fill_val));
- i++)
- fill_buf[i] = fill_val;
-
- if (blk + blkcnt > info->start + info->size) {
- printf(
- "%s: Request would exceed partition size!\n",
- __func__);
- info->mssg("Request would exceed partition size!");
- return -1;
- }
-
- for (i = 0; i < blkcnt;) {
- j = blkcnt - i;
- if (j > fill_buf_num_blks)
- j = fill_buf_num_blks;
- blks = info->write(info, blk, j, fill_buf);
- /* blks might be > j (eg. NAND bad-blocks) */
- if (blks < j) {
- printf("%s: %s " LBAFU " [%d]\n",
- __func__,
- "Write failed, block #",
- blk, j);
- info->mssg("flash write failure");
- free(fill_buf);
- return -1;
- }
- blk += blks;
- i += j;
- }
- bytes_written += blkcnt * info->blksz;
- total_blocks += chunk_data_sz / sparse_header->blk_sz;
- free(fill_buf);
- break;
-
- case CHUNK_TYPE_DONT_CARE:
- blk += info->reserve(info, blk, blkcnt);
- total_blocks += chunk_header->chunk_sz;
- break;
-
- case CHUNK_TYPE_CRC32:
- if (chunk_header->total_sz !=
- sparse_header->chunk_hdr_sz) {
- info->mssg("Bogus chunk size for chunk type Dont Care");
- return -1;
- }
- total_blocks += chunk_header->chunk_sz;
- data += chunk_data_sz;
- break;
-
- default:
- printf("%s: Unknown chunk type: %x\n", __func__,
- chunk_header->chunk_type);
- info->mssg("Unknown chunk type");
- return -1;
- }
- }
-
- debug("Wrote %d blocks, expected to write %d blocks\n",
- total_blocks, sparse_header->total_blks);
- printf("........ wrote %u bytes to '%s'\n", bytes_written, part_name);
-
- if (total_blocks != sparse_header->total_blks) {
- info->mssg("sparse image write failure");
- return -1;
- }
-
- return 0;
-}
diff --git a/common/menu.c b/common/menu.c
index bf2b471ff87..0f0a29ac2ee 100644
--- a/common/menu.c
+++ b/common/menu.c
@@ -194,8 +194,7 @@ static inline int menu_interactive_choice(struct menu *m, void **choice)
if (!m->item_choice) {
readret = cli_readline_into_buffer("Enter choice: ",
- cbuf,
- m->timeout / 10);
+ cbuf, m->timeout);
if (readret >= 0) {
choice_item = menu_item_by_key(m, cbuf);
diff --git a/common/spl/spl.c b/common/spl/spl.c
index 6606417ff74..a09ada37d72 100644
--- a/common/spl/spl.c
+++ b/common/spl/spl.c
@@ -145,9 +145,84 @@ void spl_set_header_raw_uboot(struct spl_image_info *spl_image)
spl_image->name = "U-Boot";
}
+#ifdef CONFIG_SPL_LOAD_FIT_FULL
+/* Parse and load full fitImage in SPL */
+static int spl_load_fit_image(struct spl_image_info *spl_image,
+ const struct image_header *header)
+{
+ bootm_headers_t images;
+ const char *fit_uname_config = NULL;
+ const char *fit_uname_fdt = FIT_FDT_PROP;
+ const char *uname;
+ ulong fw_data = 0, dt_data = 0, img_data = 0;
+ ulong fw_len = 0, dt_len = 0, img_len = 0;
+ int idx, conf_noffset;
+ int ret;
+
+#ifdef CONFIG_SPL_FIT_SIGNATURE
+ images.verify = 1;
+#endif
+ ret = fit_image_load(&images, (ulong)header,
+ NULL, &fit_uname_config,
+ IH_ARCH_DEFAULT, IH_TYPE_STANDALONE, -1,
+ FIT_LOAD_REQUIRED, &fw_data, &fw_len);
+ if (ret < 0)
+ return ret;
+
+ spl_image->size = fw_len;
+ spl_image->entry_point = fw_data;
+ spl_image->load_addr = fw_data;
+ spl_image->os = IH_OS_U_BOOT;
+ spl_image->name = "U-Boot";
+
+ debug("spl: payload image: %.*s load addr: 0x%lx size: %d\n",
+ (int)sizeof(spl_image->name), spl_image->name,
+ spl_image->load_addr, spl_image->size);
+
+#ifdef CONFIG_SPL_FIT_SIGNATURE
+ images.verify = 1;
+#endif
+ fit_image_load(&images, (ulong)header,
+ &fit_uname_fdt, &fit_uname_config,
+ IH_ARCH_DEFAULT, IH_TYPE_FLATDT, -1,
+ FIT_LOAD_OPTIONAL, &dt_data, &dt_len);
+
+ conf_noffset = fit_conf_get_node((const void *)header,
+ fit_uname_config);
+ if (conf_noffset <= 0)
+ return 0;
+
+ for (idx = 0;
+ uname = fdt_stringlist_get((const void *)header, conf_noffset,
+ FIT_LOADABLE_PROP, idx,
+ NULL), uname;
+ idx++)
+ {
+#ifdef CONFIG_SPL_FIT_SIGNATURE
+ images.verify = 1;
+#endif
+ ret = fit_image_load(&images, (ulong)header,
+ &uname, &fit_uname_config,
+ IH_ARCH_DEFAULT, IH_TYPE_LOADABLE, -1,
+ FIT_LOAD_OPTIONAL_NON_ZERO,
+ &img_data, &img_len);
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+#endif
+
int spl_parse_image_header(struct spl_image_info *spl_image,
const struct image_header *header)
{
+#ifdef CONFIG_SPL_LOAD_FIT_FULL
+ int ret = spl_load_fit_image(spl_image, header);
+
+ if (!ret)
+ return ret;
+#endif
if (image_get_magic(header) == IH_MAGIC) {
#ifdef CONFIG_SPL_LEGACY_IMAGE_SUPPORT
u32 header_size = sizeof(struct image_header);
diff --git a/common/spl/spl_fit.c b/common/spl/spl_fit.c
index 8b5befcec2b..2321ebb0dde 100644
--- a/common/spl/spl_fit.c
+++ b/common/spl/spl_fit.c
@@ -140,6 +140,14 @@ static int get_aligned_image_size(struct spl_load_info *info, int data_size,
return (data_size + info->bl_len - 1) / info->bl_len;
}
+#ifdef CONFIG_SPL_FPGA_SUPPORT
+__weak int spl_load_fpga_image(struct spl_load_info *info, size_t length,
+ int nr_sectors, int sector_offset)
+{
+ return 0;
+}
+#endif
+
/**
* spl_load_fit_image(): load the image described in a certain FIT node
* @info: points to information about the device to load data from
@@ -161,7 +169,7 @@ static int spl_load_fit_image(struct spl_load_info *info, ulong sector,
void *fit, ulong base_offset, int node,
struct spl_image_info *image_info)
{
- int offset;
+ int offset, sector_offset;
size_t length;
int len;
ulong size;
@@ -209,9 +217,16 @@ static int spl_load_fit_image(struct spl_load_info *info, ulong sector,
overhead = get_aligned_image_overhead(info, offset);
nr_sectors = get_aligned_image_size(info, length, offset);
+ sector_offset = sector + get_aligned_image_offset(info, offset);
- if (info->read(info,
- sector + get_aligned_image_offset(info, offset),
+#ifdef CONFIG_SPL_FPGA_SUPPORT
+ if (type == IH_TYPE_FPGA) {
+ return spl_load_fpga_image(info, length, nr_sectors,
+ sector_offset);
+ }
+#endif
+
+ if (info->read(info, sector_offset,
nr_sectors, (void *)load_ptr) != nr_sectors)
return -EIO;
@@ -387,6 +402,20 @@ int spl_load_simple_fit(struct spl_image_info *spl_image,
return -1;
}
+#ifdef CONFIG_SPL_FPGA_SUPPORT
+ node = spl_fit_get_image_node(fit, images, "fpga", 0);
+ if (node >= 0) {
+ /* Load the image and set up the spl_image structure */
+ ret = spl_load_fit_image(info, sector, fit, base_offset, node,
+ spl_image);
+ if (ret) {
+ printf("%s: Cannot load the FPGA: %i\n", __func__, ret);
+ return ret;
+ }
+ node = -1;
+ }
+#endif
+
/*
* Find the U-Boot image using the following search order:
* - start at 'firmware' (e.g. an ARM Trusted Firmware)