diff options
Diffstat (limited to 'common')
-rw-r--r-- | common/Makefile | 10 | ||||
-rw-r--r-- | common/bootm.c | 14 | ||||
-rw-r--r-- | common/env_ext4.c | 127 | ||||
-rw-r--r-- | common/image-fdt.c | 8 | ||||
-rw-r--r-- | common/image-fit.c | 57 | ||||
-rw-r--r-- | common/image.c | 50 | ||||
-rw-r--r-- | common/spl/Makefile | 1 | ||||
-rw-r--r-- | common/spl/spl_fit.c | 194 | ||||
-rw-r--r-- | common/spl/spl_mmc.c | 75 | ||||
-rw-r--r-- | common/xyzModem.c | 2 |
10 files changed, 464 insertions, 74 deletions
diff --git a/common/Makefile b/common/Makefile index 117178ad9b..c96442bf95 100644 --- a/common/Makefile +++ b/common/Makefile @@ -46,6 +46,7 @@ obj-$(CONFIG_ENV_IS_IN_NVRAM) += env_embedded.o obj-$(CONFIG_ENV_IS_IN_FLASH) += env_flash.o obj-$(CONFIG_ENV_IS_IN_MMC) += env_mmc.o obj-$(CONFIG_ENV_IS_IN_FAT) += env_fat.o +obj-$(CONFIG_ENV_IS_IN_EXT4) += env_ext4.o obj-$(CONFIG_ENV_IS_IN_NAND) += env_nand.o obj-$(CONFIG_ENV_IS_IN_NVRAM) += env_nvram.o obj-$(CONFIG_ENV_IS_IN_ONENAND) += env_onenand.o @@ -55,7 +56,7 @@ obj-$(CONFIG_ENV_IS_IN_UBI) += env_ubi.o obj-$(CONFIG_ENV_IS_NOWHERE) += env_nowhere.o obj-$(CONFIG_CMD_BEDBUG) += bedbug.o -obj-$(CONFIG_OF_LIBFDT) += fdt_support.o +obj-$(CONFIG_$(SPL_)OF_LIBFDT) += fdt_support.o obj-$(CONFIG_MII) += miiphyutil.o obj-$(CONFIG_CMD_MII) += miiphyutil.o @@ -105,6 +106,7 @@ obj-$(CONFIG_SPL_ENV_SUPPORT) += env_callback.o obj-$(CONFIG_ENV_IS_NOWHERE) += env_nowhere.o obj-$(CONFIG_ENV_IS_IN_MMC) += env_mmc.o obj-$(CONFIG_ENV_IS_IN_FAT) += env_fat.o +obj-$(CONFIG_ENV_IS_IN_EXT4) += env_ext4.o obj-$(CONFIG_ENV_IS_IN_NAND) += env_nand.o obj-$(CONFIG_ENV_IS_IN_SPI_FLASH) += env_sf.o obj-$(CONFIG_ENV_IS_IN_FLASH) += env_flash.o @@ -129,9 +131,9 @@ obj-y += malloc_simple.o endif obj-y += image.o obj-$(CONFIG_ANDROID_BOOT_IMAGE) += image-android.o -obj-$(CONFIG_OF_LIBFDT) += image-fdt.o -obj-$(CONFIG_FIT) += image-fit.o -obj-$(CONFIG_FIT_SIGNATURE) += image-sig.o +obj-$(CONFIG_$(SPL_)OF_LIBFDT) += image-fdt.o +obj-$(CONFIG_$(SPL_)FIT) += image-fit.o +obj-$(CONFIG_$(SPL_)FIT_SIGNATURE) += image-sig.o obj-$(CONFIG_IO_TRACE) += iotrace.o obj-y += memsize.o obj-y += stdio.o diff --git a/common/bootm.c b/common/bootm.c index df27089965..c965326db4 100644 --- a/common/bootm.c +++ b/common/bootm.c @@ -108,7 +108,7 @@ static int bootm_find_os(cmd_tbl_t *cmdtp, int flag, int argc, images.os.arch = image_get_arch(os_hdr); break; #endif -#if defined(CONFIG_FIT) +#if IMAGE_ENABLE_FIT case IMAGE_FORMAT_FIT: if (fit_image_get_type(images.fit_hdr_os, images.fit_noffset_os, @@ -180,7 +180,7 @@ static int bootm_find_os(cmd_tbl_t *cmdtp, int flag, int argc, /* Kernel entry point is the setup.bin */ } else if (images.legacy_hdr_valid) { images.ep = image_get_ep(&images.legacy_hdr_os_copy); -#if defined(CONFIG_FIT) +#if IMAGE_ENABLE_FIT } else if (images.fit_uname_os) { int ret; @@ -234,7 +234,7 @@ int bootm_find_images(int flag, int argc, char * const argv[]) return 1; } -#if defined(CONFIG_OF_LIBFDT) +#if IMAGE_ENABLE_OF_LIBFDT /* find flattened device tree */ ret = boot_get_fdt(flag, argc, argv, IH_ARCH_DEFAULT, &images, &images.ft_addr, &images.ft_len); @@ -245,7 +245,7 @@ int bootm_find_images(int flag, int argc, char * const argv[]) set_working_fdt_addr((ulong)images.ft_addr); #endif -#if defined(CONFIG_FIT) +#if IMAGE_ENABLE_FIT /* find all of the loadables */ ret = boot_get_loadable(argc, argv, &images, IH_ARCH_DEFAULT, NULL, NULL); @@ -644,7 +644,7 @@ int do_bootm_states(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[], } } #endif -#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_LMB) +#if IMAGE_ENABLE_OF_LIBFDT && defined(CONFIG_LMB) if (!ret && (states & BOOTM_STATE_FDT)) { boot_fdt_add_mem_rsv_regions(&images->lmb, images->ft_addr); ret = boot_relocate_fdt(&images->lmb, &images->ft_addr, @@ -788,7 +788,7 @@ static const void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc, const void *buf; const char *fit_uname_config = NULL; const char *fit_uname_kernel = NULL; -#if defined(CONFIG_FIT) +#if IMAGE_ENABLE_FIT int os_noffset; #endif @@ -849,7 +849,7 @@ static const void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc, bootstage_mark(BOOTSTAGE_ID_DECOMP_IMAGE); break; #endif -#if defined(CONFIG_FIT) +#if IMAGE_ENABLE_FIT case IMAGE_FORMAT_FIT: os_noffset = fit_image_load(images, img_addr, &fit_uname_kernel, &fit_uname_config, diff --git a/common/env_ext4.c b/common/env_ext4.c new file mode 100644 index 0000000000..ce748ed8c7 --- /dev/null +++ b/common/env_ext4.c @@ -0,0 +1,127 @@ +/* + * (c) Copyright 2016 by VRT Technology + * + * Author: + * Stuart Longland <stuartl@vrt.com.au> + * + * Based on FAT environment driver + * (c) Copyright 2011 by Tigris Elektronik GmbH + * + * Author: + * Maximilian Schwerin <mvs@tigris.de> + * + * and EXT4 filesystem implementation + * (C) Copyright 2011 - 2012 Samsung Electronics + * EXT4 filesystem implementation in Uboot by + * Uma Shankar <uma.shankar@samsung.com> + * Manjunatha C Achar <a.manjunatha@samsung.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> + +#include <command.h> +#include <environment.h> +#include <linux/stddef.h> +#include <malloc.h> +#include <search.h> +#include <errno.h> +#include <ext4fs.h> +#include <mmc.h> + +char *env_name_spec = "EXT4"; + +env_t *env_ptr; + +DECLARE_GLOBAL_DATA_PTR; + +int env_init(void) +{ + /* use default */ + gd->env_addr = (ulong)&default_environment[0]; + gd->env_valid = 1; + + return 0; +} + +#ifdef CONFIG_CMD_SAVEENV +int saveenv(void) +{ + env_t env_new; + block_dev_desc_t *dev_desc = NULL; + disk_partition_t info; + int dev, part; + int err; + + err = env_export(&env_new); + if (err) + return err; + + part = get_device_and_partition(EXT4_ENV_INTERFACE, + EXT4_ENV_DEVICE_AND_PART, + &dev_desc, &info, 1); + if (part < 0) + return 1; + + dev = dev_desc->dev; + ext4fs_set_blk_dev(dev_desc, &info); + + if (!ext4fs_mount(info.size)) { + printf("\n** Unable to use %s %s for saveenv **\n", + EXT4_ENV_INTERFACE, EXT4_ENV_DEVICE_AND_PART); + return 1; + } + + err = ext4fs_write(EXT4_ENV_FILE, (void *)&env_new, sizeof(env_t)); + ext4fs_close(); + + if (err == -1) { + printf("\n** Unable to write \"%s\" from %s%d:%d **\n", + EXT4_ENV_FILE, EXT4_ENV_INTERFACE, dev, part); + return 1; + } + + puts("done\n"); + return 0; +} +#endif /* CONFIG_CMD_SAVEENV */ + +void env_relocate_spec(void) +{ + ALLOC_CACHE_ALIGN_BUFFER(char, buf, CONFIG_ENV_SIZE); + block_dev_desc_t *dev_desc = NULL; + disk_partition_t info; + int dev, part; + int err; + + part = get_device_and_partition(EXT4_ENV_INTERFACE, + EXT4_ENV_DEVICE_AND_PART, + &dev_desc, &info, 1); + if (part < 0) + goto err_env_relocate; + + dev = dev_desc->dev; + ext4fs_set_blk_dev(dev_desc, &info); + + if (!ext4fs_mount(info.size)) { + printf("\n** Unable to use %s %s for loading the env **\n", + EXT4_ENV_INTERFACE, EXT4_ENV_DEVICE_AND_PART); + goto err_env_relocate; + } + + err = ext4_read_file(EXT4_ENV_FILE, buf, 0, CONFIG_ENV_SIZE); + ext4fs_close(); + + if (err == -1) { + printf("\n** Unable to read \"%s\" from %s%d:%d **\n", + EXT4_ENV_FILE, EXT4_ENV_INTERFACE, dev, part); + goto err_env_relocate; + } + + env_import(buf, 1); + return; + +err_env_relocate: + set_default_env(NULL); +} diff --git a/common/image-fdt.c b/common/image-fdt.c index 79fa65563f..8c3f3e6374 100644 --- a/common/image-fdt.c +++ b/common/image-fdt.c @@ -231,7 +231,7 @@ int boot_get_fdt(int flag, int argc, char * const argv[], uint8_t arch, ulong fdt_addr; char *fdt_blob = NULL; void *buf; -#if defined(CONFIG_FIT) +#if CONFIG_IS_ENABLED(FIT) const char *fit_uname_config = images->fit_uname_cfg; const char *fit_uname_fdt = NULL; ulong default_addr; @@ -246,7 +246,7 @@ int boot_get_fdt(int flag, int argc, char * const argv[], uint8_t arch, if (argc > 2) select = argv[2]; if (select || genimg_has_config(images)) { -#if defined(CONFIG_FIT) +#if CONFIG_IS_ENABLED(FIT) if (select) { /* * If the FDT blob comes from the FIT image and the @@ -276,7 +276,7 @@ int boot_get_fdt(int flag, int argc, char * const argv[], uint8_t arch, debug("* fdt: cmdline image address = 0x%08lx\n", fdt_addr); } -#if defined(CONFIG_FIT) +#if CONFIG_IS_ENABLED(FIT) } else { /* use FIT configuration provided in first bootm * command argument @@ -351,7 +351,7 @@ int boot_get_fdt(int flag, int argc, char * const argv[], uint8_t arch, * (libfdt based) and raw FDT blob (also libfdt * based). */ -#if defined(CONFIG_FIT) +#if CONFIG_IS_ENABLED(FIT) /* check FDT blob vs FIT blob */ if (fit_check_format(buf)) { ulong load, len; diff --git a/common/image-fit.c b/common/image-fit.c index fbd9e0d770..25f8a1183d 100644 --- a/common/image-fit.c +++ b/common/image-fit.c @@ -433,7 +433,7 @@ void fit_image_print(const void *fit, int image_noffset, const char *p) if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) || (type == IH_TYPE_RAMDISK)) { - fit_image_get_entry(fit, image_noffset, &entry); + ret = fit_image_get_entry(fit, image_noffset, &entry); printf("%s Entry Point: ", p); if (ret) printf("unavailable\n"); @@ -675,6 +675,34 @@ int fit_image_get_comp(const void *fit, int noffset, uint8_t *comp) return 0; } +static int fit_image_get_address(const void *fit, int noffset, char *name, + ulong *load) +{ + int len, cell_len; + const fdt32_t *cell; + uint64_t load64 = 0; + + cell = fdt_getprop(fit, noffset, name, &len); + if (cell == NULL) { + fit_get_debug(fit, noffset, name, len); + return -1; + } + + if (len > sizeof(ulong)) { + printf("Unsupported %s address size\n", name); + return -1; + } + + cell_len = len >> 2; + /* Use load64 to avoid compiling warning for 32-bit target */ + while (cell_len--) { + load64 = (load64 << 32) | uimage_to_cpu(*cell); + cell++; + } + *load = (ulong)load64; + + return 0; +} /** * fit_image_get_load() - get load addr property for given component image node * @fit: pointer to the FIT format image header @@ -690,17 +718,7 @@ int fit_image_get_comp(const void *fit, int noffset, uint8_t *comp) */ int fit_image_get_load(const void *fit, int noffset, ulong *load) { - int len; - const uint32_t *data; - - data = fdt_getprop(fit, noffset, FIT_LOAD_PROP, &len); - if (data == NULL) { - fit_get_debug(fit, noffset, FIT_LOAD_PROP, len); - return -1; - } - - *load = uimage_to_cpu(*data); - return 0; + return fit_image_get_address(fit, noffset, FIT_LOAD_PROP, load); } /** @@ -722,17 +740,7 @@ int fit_image_get_load(const void *fit, int noffset, ulong *load) */ int fit_image_get_entry(const void *fit, int noffset, ulong *entry) { - int len; - const uint32_t *data; - - data = fdt_getprop(fit, noffset, FIT_ENTRY_PROP, &len); - if (data == NULL) { - fit_get_debug(fit, noffset, FIT_ENTRY_PROP, len); - return -1; - } - - *entry = uimage_to_cpu(*data); - return 0; + return fit_image_get_address(fit, noffset, FIT_ENTRY_PROP, entry); } /** @@ -1101,8 +1109,9 @@ int fit_all_image_verify(const void *fit) * Direct child node of the images parent node, * i.e. component image node. */ - printf(" Hash(es) for Image %u (%s): ", count++, + printf(" Hash(es) for Image %u (%s): ", count, fit_get_name(fit, noffset, NULL)); + count++; if (!fit_image_verify(fit, noffset)) return 0; diff --git a/common/image.c b/common/image.c index 1d7543dd18..26d6c9a592 100644 --- a/common/image.c +++ b/common/image.c @@ -29,7 +29,7 @@ #include <image.h> #include <mapmem.h> -#if defined(CONFIG_FIT) || defined(CONFIG_OF_LIBFDT) +#if IMAGE_ENABLE_FIT || IMAGE_ENABLE_OF_LIBFDT #include <libfdt.h> #include <fdt_support.h> #endif @@ -608,11 +608,9 @@ const char *genimg_get_type_name(uint8_t type) return (get_table_entry_name(uimage_type, "Unknown Image", type)); } -const char *genimg_get_type_short_name(uint8_t type) +static const char *genimg_get_short_name(const table_entry_t *table, int val) { - const table_entry_t *table; - - table = get_table_entry(uimage_type, type); + table = get_table_entry(table, val); if (!table) return "unknown"; #if defined(USE_HOSTCC) || !defined(CONFIG_NEEDS_MANUAL_RELOC) @@ -622,12 +620,32 @@ const char *genimg_get_type_short_name(uint8_t type) #endif } +const char *genimg_get_type_short_name(uint8_t type) +{ + return genimg_get_short_name(uimage_type, type); +} + const char *genimg_get_comp_name(uint8_t comp) { return (get_table_entry_name(uimage_comp, "Unknown Compression", comp)); } +const char *genimg_get_comp_short_name(uint8_t comp) +{ + return genimg_get_short_name(uimage_comp, comp); +} + +const char *genimg_get_os_short_name(uint8_t os) +{ + return genimg_get_short_name(uimage_os, os); +} + +const char *genimg_get_arch_short_name(uint8_t arch) +{ + return genimg_get_short_name(uimage_arch, arch); +} + /** * get_table_entry_id - translate short entry name to id * @table: pointer to a translation table for entries of a specific type @@ -707,7 +725,7 @@ ulong genimg_get_kernel_addr_fit(char * const img_addr, kernel_addr = load_addr; debug("* kernel: default image load address = 0x%08lx\n", load_addr); -#if defined(CONFIG_FIT) +#if CONFIG_IS_ENABLED(FIT) } else if (fit_parse_conf(img_addr, load_addr, &kernel_addr, fit_uname_config)) { debug("* kernel: config '%s' from image at 0x%08lx\n", @@ -762,7 +780,7 @@ int genimg_get_format(const void *img_addr) if (image_check_magic(hdr)) return IMAGE_FORMAT_LEGACY; #endif -#if defined(CONFIG_FIT) || defined(CONFIG_OF_LIBFDT) +#if IMAGE_ENABLE_FIT || IMAGE_ENABLE_OF_LIBFDT if (fdt_check_header(img_addr) == 0) return IMAGE_FORMAT_FIT; #endif @@ -799,7 +817,7 @@ ulong genimg_get_image(ulong img_addr) /* get header size */ h_size = image_get_header_size(); -#if defined(CONFIG_FIT) +#if IMAGE_ENABLE_FIT if (sizeof(struct fdt_header) > h_size) h_size = sizeof(struct fdt_header); #endif @@ -821,7 +839,7 @@ ulong genimg_get_image(ulong img_addr) ram_addr, d_size); break; #endif -#if defined(CONFIG_FIT) +#if IMAGE_ENABLE_FIT case IMAGE_FORMAT_FIT: d_size = fit_get_size(buf) - h_size; debug(" FIT/FDT format image found at 0x%08lx, " @@ -862,7 +880,7 @@ ulong genimg_get_image(ulong img_addr) */ int genimg_has_config(bootm_headers_t *images) { -#if defined(CONFIG_FIT) +#if IMAGE_ENABLE_FIT if (images->fit_uname_cfg) return 1; #endif @@ -903,7 +921,7 @@ int boot_get_ramdisk(int argc, char * const argv[], bootm_headers_t *images, #ifdef CONFIG_SUPPORT_RAW_INITRD char *end; #endif -#if defined(CONFIG_FIT) +#if IMAGE_ENABLE_FIT const char *fit_uname_config = images->fit_uname_cfg; const char *fit_uname_ramdisk = NULL; ulong default_addr; @@ -934,7 +952,7 @@ int boot_get_ramdisk(int argc, char * const argv[], bootm_headers_t *images, debug("## Skipping init Ramdisk\n"); rd_len = rd_data = 0; } else if (select || genimg_has_config(images)) { -#if defined(CONFIG_FIT) +#if IMAGE_ENABLE_FIT if (select) { /* * If the init ramdisk comes from the FIT image and @@ -965,7 +983,7 @@ int boot_get_ramdisk(int argc, char * const argv[], bootm_headers_t *images, "0x%08lx\n", rd_addr); } -#if defined(CONFIG_FIT) +#if IMAGE_ENABLE_FIT } else { /* use FIT configuration provided in first bootm * command argument. If the property is not defined, @@ -1008,7 +1026,7 @@ int boot_get_ramdisk(int argc, char * const argv[], bootm_headers_t *images, rd_load = image_get_load(rd_hdr); break; #endif -#if defined(CONFIG_FIT) +#if IMAGE_ENABLE_FIT case IMAGE_FORMAT_FIT: rd_noffset = fit_image_load(images, rd_addr, &fit_uname_ramdisk, @@ -1184,14 +1202,14 @@ error: int boot_get_setup(bootm_headers_t *images, uint8_t arch, ulong *setup_start, ulong *setup_len) { -#if defined(CONFIG_FIT) +#if IMAGE_ENABLE_FIT return boot_get_setup_fit(images, arch, setup_start, setup_len); #else return -ENOENT; #endif } -#if defined(CONFIG_FIT) +#if IMAGE_ENABLE_FIT int boot_get_loadable(int argc, char * const argv[], bootm_headers_t *images, uint8_t arch, const ulong *ld_start, ulong * const ld_len) { diff --git a/common/spl/Makefile b/common/spl/Makefile index 10a4589969..2e0f695e46 100644 --- a/common/spl/Makefile +++ b/common/spl/Makefile @@ -10,6 +10,7 @@ ifdef CONFIG_SPL_BUILD obj-$(CONFIG_SPL_FRAMEWORK) += spl.o +obj-$(CONFIG_SPL_LOAD_FIT) += spl_fit.o obj-$(CONFIG_SPL_NOR_SUPPORT) += spl_nor.o obj-$(CONFIG_SPL_YMODEM_SUPPORT) += spl_ymodem.o obj-$(CONFIG_SPL_NAND_SUPPORT) += spl_nand.o diff --git a/common/spl/spl_fit.c b/common/spl/spl_fit.c new file mode 100644 index 0000000000..1a5c0275a7 --- /dev/null +++ b/common/spl/spl_fit.c @@ -0,0 +1,194 @@ +/* + * Copyright (C) 2016 Google, Inc + * Written by Simon Glass <sjg@chromium.org> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <errno.h> +#include <image.h> +#include <libfdt.h> +#include <spl.h> + +static ulong fdt_getprop_u32(const void *fdt, int node, const char *prop) +{ + const u32 *cell; + int len; + + cell = fdt_getprop(fdt, node, prop, &len); + if (len != sizeof(*cell)) + return -1U; + return fdt32_to_cpu(*cell); +} + +static int spl_fit_select_fdt(const void *fdt, int images, int *fdt_offsetp) +{ + const char *name, *fdt_name; + int conf, node, fdt_node; + int len; + + *fdt_offsetp = 0; + conf = fdt_path_offset(fdt, FIT_CONFS_PATH); + if (conf < 0) { + debug("%s: Cannot find /configurations node: %d\n", __func__, + conf); + return -EINVAL; + } + for (node = fdt_first_subnode(fdt, conf); + node >= 0; + node = fdt_next_subnode(fdt, node)) { + name = fdt_getprop(fdt, node, "description", &len); + if (!name) + return -EINVAL; + if (board_fit_config_name_match(name)) + continue; + + debug("Selecting config '%s'", name); + fdt_name = fdt_getprop(fdt, node, FIT_FDT_PROP, &len); + if (!fdt_name) { + debug("%s: Cannot find fdt name property: %d\n", + __func__, len); + return -EINVAL; + } + + debug(", fdt '%s'\n", fdt_name); + fdt_node = fdt_subnode_offset(fdt, images, fdt_name); + if (fdt_node < 0) { + debug("%s: Cannot find fdt node '%s': %d\n", + __func__, fdt_name, fdt_node); + return -EINVAL; + } + + *fdt_offsetp = fdt_getprop_u32(fdt, fdt_node, "data-offset"); + len = fdt_getprop_u32(fdt, fdt_node, "data-size"); +#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT + printf("FIT: Selected '%s'\n", name); +#endif + + return len; + } + +#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT + printf("No matching DT out of these options:\n"); + for (node = fdt_first_subnode(fdt, conf); + node >= 0; + node = fdt_next_subnode(fdt, node)) { + name = fdt_getprop(fdt, node, "name", &len); + printf(" %s\n", name); + } +#endif + + return -ENOENT; +} + +int spl_load_simple_fit(struct spl_load_info *info, ulong sector, void *fit) +{ + int sectors; + ulong size, load; + unsigned long count; + int node, images; + void *load_ptr; + int fdt_offset, fdt_len; + int data_offset, data_size; + int base_offset; + int src_sector; + void *dst; + + /* + * Figure out where the external images start. This is the base for the + * data-offset properties in each image. + */ + size = fdt_totalsize(fit); + size = (size + 3) & ~3; + base_offset = (size + 3) & ~3; + + /* + * So far we only have one block of data from the FIT. Read the entire + * thing, including that first block, placing it so it finishes before + * where we will load the image. + * + * Note that we will load the image such that its first byte will be + * at the load address. Since that byte may be part-way through a + * block, we may load the image up to one block before the load + * address. So take account of that here by subtracting an addition + * block length from the FIT start position. + * + * In fact the FIT has its own load address, but we assume it cannot + * be before CONFIG_SYS_TEXT_BASE. + */ + fit = (void *)(CONFIG_SYS_TEXT_BASE - size - info->bl_len); + sectors = (size + info->bl_len - 1) / info->bl_len; + count = info->read(info, sector, sectors, fit); + debug("fit read sector %lx, sectors=%d, dst=%p, count=%lu\n", + sector, sectors, fit, count); + if (count == 0) + return -EIO; + + /* find the firmware image to load */ + images = fdt_path_offset(fit, FIT_IMAGES_PATH); + if (images < 0) { + debug("%s: Cannot find /images node: %d\n", __func__, images); + return -1; + } + node = fdt_first_subnode(fit, images); + if (node < 0) { + debug("%s: Cannot find first image node: %d\n", __func__, node); + return -1; + } + + /* Get its information and set up the spl_image structure */ + data_offset = fdt_getprop_u32(fit, node, "data-offset"); + data_size = fdt_getprop_u32(fit, node, "data-size"); + load = fdt_getprop_u32(fit, node, "load"); + debug("data_offset=%x, data_size=%x\n", data_offset, data_size); + spl_image.load_addr = load; + spl_image.entry_point = load; + spl_image.os = IH_OS_U_BOOT; + + /* + * Work out where to place the image. We read it so that the first + * byte will be at 'load'. This may mean we need to load it starting + * before then, since we can only read whole blocks. + */ + sectors = (data_size + info->bl_len - 1) / info->bl_len; + data_offset += base_offset; + load_ptr = (void *)load; + debug("U-Boot size %x, data %p\n", data_size, load_ptr); + dst = load_ptr - (data_offset % info->bl_len); + + /* Read the image */ + src_sector = sector + data_offset / info->bl_len; + debug("image: data_offset=%x, dst=%p, src_sector=%x, sectors=%x\n", + data_offset, dst, src_sector, sectors); + count = info->read(info, src_sector, sectors, dst); + if (count != sectors) + return -EIO; + + /* Figure out which device tree the board wants to use */ + fdt_len = spl_fit_select_fdt(fit, images, &fdt_offset); + if (fdt_len < 0) + return fdt_len; + + /* + * Read the device tree and place it after the image. There may be + * some extra data before it since we can only read entire blocks. + */ + dst = load_ptr + data_size; + fdt_offset += base_offset; + count = info->read(info, sector + fdt_offset / info->bl_len, sectors, + dst); + debug("fit read %x sectors to %x, dst %p, data_offset %x\n", + sectors, spl_image.load_addr, dst, fdt_offset); + if (count != sectors) + return -EIO; + + /* + * Copy the device tree so that it starts immediately after the image. + * After this we will have the U-Boot image and its device tree ready + * for us to start. + */ + memcpy(dst, dst + fdt_offset % info->bl_len, fdt_len); + + return 0; +} diff --git a/common/spl/spl_mmc.c b/common/spl/spl_mmc.c index 5204f5258f..c0e76be09a 100644 --- a/common/spl/spl_mmc.c +++ b/common/spl/spl_mmc.c @@ -18,41 +18,80 @@ DECLARE_GLOBAL_DATA_PTR; +static int mmc_load_legacy(struct mmc *mmc, ulong sector, + struct image_header *header) +{ + u32 image_size_sectors; + unsigned long count; + + spl_parse_image_header(header); + /* 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 = mmc->block_dev.block_read(&mmc->block_dev, sector, + image_size_sectors, + (void *)(ulong)spl_image.load_addr); + debug("read %x sectors to %x\n", image_size_sectors, + spl_image.load_addr); + if (count != image_size_sectors) + return -EIO; + + return 0; +} + +#ifdef CONFIG_SPL_LOAD_FIT +static ulong h_spl_load_read(struct spl_load_info *load, ulong sector, + ulong count, void *buf) +{ + struct mmc *mmc = load->dev; + + return mmc->block_dev.block_read(&mmc->block_dev, sector, count, buf); +} +#endif + static int mmc_load_image_raw_sector(struct mmc *mmc, unsigned long sector) { unsigned long count; - u32 image_size_sectors; struct image_header *header; + int ret = 0; header = (struct image_header *)(CONFIG_SYS_TEXT_BASE - sizeof(struct image_header)); /* read image header to find the image size & load address */ count = mmc->block_dev.block_read(&mmc->block_dev, sector, 1, header); - debug("read sector %lx, count=%lu\n", sector, count); - if (count == 0) + debug("hdr read sector %lx, count=%lu\n", sector, count); + if (count == 0) { + ret = -EIO; goto end; + } - if (image_get_magic(header) != IH_MAGIC) { + switch (image_get_magic(header)) { + case IH_MAGIC: + ret = mmc_load_legacy(mmc, sector, header); + break; +#ifdef CONFIG_SPL_LOAD_FIT + case FDT_MAGIC: { + struct spl_load_info load; + + debug("Found FIT\n"); + load.dev = mmc; + load.priv = NULL; + load.bl_len = mmc->read_bl_len; + load.read = h_spl_load_read; + ret = spl_load_simple_fit(&load, sector, header); + break; + } +#endif + default: puts("bad magic\n"); return -1; } - spl_parse_image_header(header); - - /* 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 = mmc->block_dev.block_read(&mmc->block_dev, sector, - image_size_sectors, - (void *)(ulong)spl_image.load_addr); - debug("read %x sectors to %x\n", image_size_sectors, - spl_image.load_addr); - end: - if (count == 0) { + if (ret) { #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT puts("spl: mmc block read error\n"); #endif diff --git a/common/xyzModem.c b/common/xyzModem.c index 56f4bcaf99..5656aac48f 100644 --- a/common/xyzModem.c +++ b/common/xyzModem.c @@ -446,7 +446,7 @@ xyzModem_get_hdr (void) /* Verify checksum/CRC */ if (xyz.crc_mode) { - cksum = cyg_crc16 (xyz.pkt, xyz.len); + cksum = crc16_ccitt(0, xyz.pkt, xyz.len); if (cksum != ((xyz.crc1 << 8) | xyz.crc2)) { ZM_DEBUG (zm_dprintf ("CRC error - recvd: %02x%02x, computed: %x\n", |