From: Alex Kiernan Date: Tue, 29 May 2018 15:30:39 +0000 (+0000) Subject: fastboot: Move fastboot to drivers/fastboot X-Git-Tag: v2018.07-rc1~15^2~17 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=312a10f16bf3e8b68066fa359d4dd6a887b5fd55;p=u-boot fastboot: Move fastboot to drivers/fastboot Separate CMD_FASTBOOT from FASTBOOT and move code and configuration to drivers/fastboot. Switch dependencies on FASTBOOT to USB_FUNCTION_FASTBOOT as anyone who wants FASTBOOT before this series wants USB_FUNCTION_FASTBOOT. Split USB_FUNCTION_FASTBOOT from FASTBOOT so they retain their existing behaviour. Signed-off-by: Alex Kiernan Reviewed-by: Simon Glass Acked-by: Joe Hershberger --- diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 582e84cf40..dde422bc5d 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1258,9 +1258,7 @@ config ARCH_ROCKCHIP select DM_REGULATOR select ENABLE_ARM_SOC_BOOT0_HOOK select SPI - imply CMD_FASTBOOT imply DISTRO_DEFAULTS - imply FASTBOOT imply FAT_WRITE imply USB_FUNCTION_FASTBOOT imply SPL_SYSRESET diff --git a/board/ti/common/Kconfig b/board/ti/common/Kconfig index c21eb8c2d2..b1956b8100 100644 --- a/board/ti/common/Kconfig +++ b/board/ti/common/Kconfig @@ -25,7 +25,6 @@ config TI_COMMON_CMD_OPTIONS imply CMD_EXT2 imply CMD_EXT4 imply CMD_EXT4_WRITE - imply CMD_FASTBOOT if FASTBOOT imply CMD_FAT imply FAT_WRITE if CMD_FAT imply CMD_FS_GENERIC diff --git a/cmd/Kconfig b/cmd/Kconfig index d532c9fc41..9848c067da 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -137,8 +137,6 @@ config AUTOBOOT_STOP_STR_SHA256 endmenu -source "cmd/fastboot/Kconfig" - config BUILD_BIN2C bool @@ -650,6 +648,18 @@ config CMD_DM can be useful to see the state of driver model for debugging or interest. +config CMD_FASTBOOT + bool "fastboot - Android fastboot support" + depends on FASTBOOT + help + This enables the command "fastboot" which enables the Android + fastboot mode for the platform. Fastboot is a protocol for + downloading images, flashing and device control used on + Android devices. Fastboot requires support for acting as a USB + device. + + See doc/README.android-fastboot for more information. + config CMD_FDC bool "fdcboot - Boot from floppy device" help diff --git a/cmd/fastboot/Kconfig b/cmd/fastboot/Kconfig deleted file mode 100644 index 0d2c2f131e..0000000000 --- a/cmd/fastboot/Kconfig +++ /dev/null @@ -1,134 +0,0 @@ -comment "FASTBOOT" - -menuconfig FASTBOOT - bool "Fastboot support" - depends on USB_GADGET - default y if ARCH_SUNXI && USB_MUSB_GADGET - -if FASTBOOT - -config USB_FUNCTION_FASTBOOT - bool "Enable USB fastboot gadget" - default y - select USB_GADGET_DOWNLOAD - imply ANDROID_BOOT_IMAGE - imply CMD_FASTBOOT - help - This enables the USB part of the fastboot gadget. - -config CMD_FASTBOOT - bool "Enable FASTBOOT command" - help - This enables the command "fastboot" which enables the Android - fastboot mode for the platform's USB device. Fastboot is a USB - protocol for downloading images, flashing and device control - used on Android devices. - - See doc/README.android-fastboot for more information. - -if USB_FUNCTION_FASTBOOT - -config FASTBOOT_BUF_ADDR - hex "Define FASTBOOT buffer address" - default 0x82000000 if MX6SX || MX6SL || MX6UL || MX6SLL - default 0x81000000 if ARCH_OMAP2PLUS - default 0x42000000 if ARCH_SUNXI && !MACH_SUN9I - default 0x22000000 if ARCH_SUNXI && MACH_SUN9I - default 0x60800800 if ROCKCHIP_RK3036 || ROCKCHIP_RK3188 || \ - ROCKCHIP_RK322X - default 0x800800 if ROCKCHIP_RK3288 || ROCKCHIP_RK3329 || \ - ROCKCHIP_RK3399 - default 0x280000 if ROCKCHIP_RK3368 - default 0x100000 if ARCH_ZYNQMP - help - The fastboot protocol requires a large memory buffer for - downloads. Define this to the starting RAM address to use for - downloaded images. - -config FASTBOOT_BUF_SIZE - hex "Define FASTBOOT buffer size" - default 0x8000000 if ARCH_ROCKCHIP - default 0x6000000 if ARCH_ZYNQMP - default 0x2000000 if ARCH_SUNXI - default 0x7000000 - help - The fastboot protocol requires a large memory buffer for - downloads. This buffer should be as large as possible for a - platform. Define this to the size available RAM for fastboot. - -config FASTBOOT_USB_DEV - int "USB controller number" - default 0 - help - Some boards have USB OTG controller other than 0. Define this - option so it can be used in compiled environment (e.g. in - CONFIG_BOOTCOMMAND). - -config FASTBOOT_FLASH - bool "Enable FASTBOOT FLASH command" - default y if ARCH_SUNXI - help - The fastboot protocol includes a "flash" command for writing - the downloaded image to a non-volatile storage device. Define - this to enable the "fastboot flash" command. - -choice - prompt "Flash provider for FASTBOOT" - depends on FASTBOOT_FLASH - -config FASTBOOT_FLASH_MMC - bool "FASTBOOT on MMC" - depends on MMC - -config FASTBOOT_FLASH_NAND - bool "FASTBOOT on NAND" - depends on NAND - -endchoice - -config FASTBOOT_FLASH_MMC_DEV - int "Define FASTBOOT MMC FLASH default device" - depends on FASTBOOT_FLASH_MMC - default 0 if ARCH_SUNXI && MMC_SUNXI_SLOT_EXTRA = -1 - default 1 if ARCH_SUNXI && MMC_SUNXI_SLOT_EXTRA != -1 - help - The fastboot "flash" command requires additional information - regarding the non-volatile storage device. Define this to - the eMMC device that fastboot should use to store the image. - -config FASTBOOT_FLASH_NAND_DEV - int "Define FASTBOOT NAND FLASH default device" - depends on FASTBOOT_FLASH_NAND - depends on CMD_MTDPARTS - default 0 if ARCH_SUNXI && NAND_SUNXI - help - The fastboot "flash" command requires additional information - regarding the non-volatile storage device. Define this to - the NAND device that fastboot should use to store the image. - -config FASTBOOT_GPT_NAME - string "Target name for updating GPT" - depends on FASTBOOT_FLASH - default "gpt" - help - The fastboot "flash" command supports writing the downloaded - image to the Protective MBR and the Primary GUID Partition - Table. (Additionally, this downloaded image is post-processed - to generate and write the Backup GUID Partition Table.) - This occurs when the specified "partition name" on the - "fastboot flash" command line matches the value defined here. - The default target name for updating GPT is "gpt". - -config FASTBOOT_MBR_NAME - string "Target name for updating MBR" - depends on FASTBOOT_FLASH - default "mbr" - help - The fastboot "flash" command allows to write the downloaded image - to the Master Boot Record. This occurs when the "partition name" - specified on the "fastboot flash" command line matches the value - defined here. The default target name for updating MBR is "mbr". - -endif # USB_FUNCTION_FASTBOOT - -endif # FASTBOOT diff --git a/common/Makefile b/common/Makefile index d0681c7dd9..9ec40b9d27 100644 --- a/common/Makefile +++ b/common/Makefile @@ -29,7 +29,7 @@ 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_FASTBOOT_FLASH) += image-sparse.o obj-$(CONFIG_MII) += miiphyutil.o obj-$(CONFIG_CMD_MII) += miiphyutil.o obj-$(CONFIG_PHYLIB) += miiphyutil.o @@ -109,19 +109,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/fb_mmc.c b/common/fb_mmc.c deleted file mode 100644 index 46f0073dbc..0000000000 --- a/common/fb_mmc.c +++ /dev/null @@ -1,406 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright 2014 Broadcom Corporation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * 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 c07655e49e..0000000000 --- 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 -#include - -#include -#include - -#include -#include -#include - -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/configs/am335x_boneblack_defconfig b/configs/am335x_boneblack_defconfig index 5c01b20dff..bd3a37427d 100644 --- a/configs/am335x_boneblack_defconfig +++ b/configs/am335x_boneblack_defconfig @@ -16,7 +16,7 @@ CONFIG_AUTOBOOT_KEYED=y CONFIG_AUTOBOOT_PROMPT="Press SPACE to abort autoboot in %d seconds\n" CONFIG_AUTOBOOT_DELAY_STR="d" CONFIG_AUTOBOOT_STOP_STR=" " -CONFIG_FASTBOOT=y +CONFIG_USB_FUNCTION_FASTBOOT=y CONFIG_FASTBOOT_FLASH=y CONFIG_FASTBOOT_FLASH_MMC_DEV=1 CONFIG_CMD_SPL=y diff --git a/configs/am335x_boneblack_vboot_defconfig b/configs/am335x_boneblack_vboot_defconfig index abbacdc77e..baaae36d28 100644 --- a/configs/am335x_boneblack_vboot_defconfig +++ b/configs/am335x_boneblack_vboot_defconfig @@ -19,7 +19,7 @@ CONFIG_AUTOBOOT_KEYED=y CONFIG_AUTOBOOT_PROMPT="Press SPACE to abort autoboot in %d seconds\n" CONFIG_AUTOBOOT_DELAY_STR="d" CONFIG_AUTOBOOT_STOP_STR=" " -CONFIG_FASTBOOT=y +CONFIG_USB_FUNCTION_FASTBOOT=y CONFIG_CMD_SPL=y # CONFIG_CMD_FLASH is not set # CONFIG_CMD_SETEXPR is not set diff --git a/configs/am335x_evm_defconfig b/configs/am335x_evm_defconfig index 6732013b03..cc556d1c3d 100644 --- a/configs/am335x_evm_defconfig +++ b/configs/am335x_evm_defconfig @@ -13,7 +13,7 @@ CONFIG_ARCH_MISC_INIT=y CONFIG_SPL_MTD_SUPPORT=y CONFIG_SPL_MUSB_NEW_SUPPORT=y CONFIG_SPL_OS_BOOT=y -CONFIG_FASTBOOT=y +CONFIG_USB_FUNCTION_FASTBOOT=y CONFIG_CMD_SPL=y CONFIG_CMD_SPL_NAND_OFS=0x00080000 # CONFIG_CMD_FLASH is not set diff --git a/configs/am335x_evm_nor_defconfig b/configs/am335x_evm_nor_defconfig index bbde07fb1d..41a5c79604 100644 --- a/configs/am335x_evm_nor_defconfig +++ b/configs/am335x_evm_nor_defconfig @@ -12,7 +12,7 @@ CONFIG_ARCH_MISC_INIT=y CONFIG_SPL_MTD_SUPPORT=y CONFIG_SPL_MUSB_NEW_SUPPORT=y CONFIG_SPL_OS_BOOT=y -CONFIG_FASTBOOT=y +CONFIG_USB_FUNCTION_FASTBOOT=y CONFIG_CMD_SPL=y CONFIG_CMD_SPL_NAND_OFS=0x00080000 CONFIG_CMD_NAND=y diff --git a/configs/am335x_evm_norboot_defconfig b/configs/am335x_evm_norboot_defconfig index 3ddcf64942..75d0793f2d 100644 --- a/configs/am335x_evm_norboot_defconfig +++ b/configs/am335x_evm_norboot_defconfig @@ -12,7 +12,7 @@ CONFIG_SYS_CONSOLE_INFO_QUIET=y CONFIG_VERSION_VARIABLE=y CONFIG_ARCH_MISC_INIT=y CONFIG_BOARD_EARLY_INIT_F=y -CONFIG_FASTBOOT=y +CONFIG_USB_FUNCTION_FASTBOOT=y # CONFIG_CMD_SETEXPR is not set CONFIG_CMD_MTDPARTS=y CONFIG_MTDIDS_DEFAULT="nor0=physmap-flash.0" diff --git a/configs/am335x_evm_spiboot_defconfig b/configs/am335x_evm_spiboot_defconfig index 10eb0fe1ee..b2678875ec 100644 --- a/configs/am335x_evm_spiboot_defconfig +++ b/configs/am335x_evm_spiboot_defconfig @@ -15,7 +15,7 @@ CONFIG_VERSION_VARIABLE=y CONFIG_ARCH_MISC_INIT=y CONFIG_SPL_MUSB_NEW_SUPPORT=y CONFIG_SPL_SPI_LOAD=y -CONFIG_FASTBOOT=y +CONFIG_USB_FUNCTION_FASTBOOT=y # CONFIG_CMD_FLASH is not set # CONFIG_CMD_SETEXPR is not set CONFIG_CMD_MTDPARTS=y diff --git a/configs/am335x_evm_usbspl_defconfig b/configs/am335x_evm_usbspl_defconfig index dc9ac216c2..44012919a3 100644 --- a/configs/am335x_evm_usbspl_defconfig +++ b/configs/am335x_evm_usbspl_defconfig @@ -19,7 +19,7 @@ CONFIG_SPL_OS_BOOT=y CONFIG_SPL_USB_GADGET_SUPPORT=y CONFIG_SPL_USB_ETHER=y # CONFIG_SPL_YMODEM_SUPPORT is not set -CONFIG_FASTBOOT=y +CONFIG_USB_FUNCTION_FASTBOOT=y CONFIG_CMD_SPL=y CONFIG_CMD_SPL_NAND_OFS=0x00080000 # CONFIG_CMD_FLASH is not set diff --git a/configs/am57xx_evm_defconfig b/configs/am57xx_evm_defconfig index 0e99268441..3b83b69e5f 100644 --- a/configs/am57xx_evm_defconfig +++ b/configs/am57xx_evm_defconfig @@ -24,7 +24,7 @@ CONFIG_SPL_SEPARATE_BSS=y CONFIG_SPL_DMA_SUPPORT=y CONFIG_SPL_OS_BOOT=y CONFIG_SPL_SPI_LOAD=y -CONFIG_FASTBOOT=y +CONFIG_USB_FUNCTION_FASTBOOT=y CONFIG_FASTBOOT_BUF_ADDR=0x82000000 CONFIG_FASTBOOT_BUF_SIZE=0x2F000000 CONFIG_FASTBOOT_USB_DEV=1 diff --git a/configs/am57xx_hs_evm_defconfig b/configs/am57xx_hs_evm_defconfig index 165c2a40ba..9c2aef482f 100644 --- a/configs/am57xx_hs_evm_defconfig +++ b/configs/am57xx_hs_evm_defconfig @@ -29,7 +29,7 @@ CONFIG_SPL_SYS_MALLOC_SIMPLE=y CONFIG_SPL_SEPARATE_BSS=y CONFIG_SPL_DMA_SUPPORT=y CONFIG_SPL_SPI_LOAD=y -CONFIG_FASTBOOT=y +CONFIG_USB_FUNCTION_FASTBOOT=y CONFIG_FASTBOOT_BUF_ADDR=0x82000000 CONFIG_FASTBOOT_BUF_SIZE=0x2F000000 CONFIG_FASTBOOT_USB_DEV=1 diff --git a/configs/bcm23550_w1d_defconfig b/configs/bcm23550_w1d_defconfig index 9a986ca9ae..de4fa60df7 100644 --- a/configs/bcm23550_w1d_defconfig +++ b/configs/bcm23550_w1d_defconfig @@ -7,7 +7,7 @@ CONFIG_VERSION_VARIABLE=y # CONFIG_DISPLAY_CPUINFO is not set # CONFIG_DISPLAY_BOARDINFO is not set CONFIG_HUSH_PARSER=y -CONFIG_FASTBOOT=y +CONFIG_USB_FUNCTION_FASTBOOT=y CONFIG_FASTBOOT_BUF_ADDR=0x80000000 CONFIG_FASTBOOT_BUF_SIZE=0x1D000000 CONFIG_FASTBOOT_FLASH=y diff --git a/configs/bcm28155_ap_defconfig b/configs/bcm28155_ap_defconfig index d26cde5b0e..4f7a58e362 100644 --- a/configs/bcm28155_ap_defconfig +++ b/configs/bcm28155_ap_defconfig @@ -8,7 +8,7 @@ CONFIG_VERSION_VARIABLE=y # CONFIG_DISPLAY_BOARDINFO is not set CONFIG_HUSH_PARSER=y # CONFIG_AUTOBOOT is not set -CONFIG_FASTBOOT=y +CONFIG_USB_FUNCTION_FASTBOOT=y CONFIG_FASTBOOT_BUF_ADDR=0x80000000 CONFIG_FASTBOOT_BUF_SIZE=0x7FF00000 CONFIG_FASTBOOT_FLASH=y diff --git a/configs/birdland_bav335a_defconfig b/configs/birdland_bav335a_defconfig index 51b3e6b4e1..3efd5669a7 100644 --- a/configs/birdland_bav335a_defconfig +++ b/configs/birdland_bav335a_defconfig @@ -25,7 +25,7 @@ CONFIG_SPL_MUSB_NEW_SUPPORT=y CONFIG_SPL_OS_BOOT=y CONFIG_SPL_POWER_SUPPORT=y CONFIG_SPL_YMODEM_SUPPORT=y -CONFIG_FASTBOOT=y +CONFIG_USB_FUNCTION_FASTBOOT=y CONFIG_FASTBOOT_BUF_ADDR=0x82000000 CONFIG_CMD_SPL=y CONFIG_CMD_ASKENV=y diff --git a/configs/birdland_bav335b_defconfig b/configs/birdland_bav335b_defconfig index 29b223a580..2f98116873 100644 --- a/configs/birdland_bav335b_defconfig +++ b/configs/birdland_bav335b_defconfig @@ -25,7 +25,7 @@ CONFIG_SPL_MUSB_NEW_SUPPORT=y CONFIG_SPL_OS_BOOT=y CONFIG_SPL_POWER_SUPPORT=y CONFIG_SPL_YMODEM_SUPPORT=y -CONFIG_FASTBOOT=y +CONFIG_USB_FUNCTION_FASTBOOT=y CONFIG_FASTBOOT_BUF_ADDR=0x82000000 CONFIG_CMD_SPL=y CONFIG_CMD_ASKENV=y diff --git a/configs/cgtqmx6eval_defconfig b/configs/cgtqmx6eval_defconfig index d4204aa712..241e9582a5 100644 --- a/configs/cgtqmx6eval_defconfig +++ b/configs/cgtqmx6eval_defconfig @@ -24,7 +24,7 @@ CONFIG_SPL_I2C_SUPPORT=y CONFIG_SPL_SPI_LOAD=y CONFIG_HUSH_PARSER=y CONFIG_SYS_PROMPT="CGT-QMX6-Quad U-Boot > " -CONFIG_FASTBOOT=y +CONFIG_USB_FUNCTION_FASTBOOT=y CONFIG_FASTBOOT_BUF_ADDR=0x12000000 CONFIG_CMD_BOOTZ=y CONFIG_CMD_DFU=y diff --git a/configs/dra7xx_evm_defconfig b/configs/dra7xx_evm_defconfig index 9b81b0cc71..b766ba27cd 100644 --- a/configs/dra7xx_evm_defconfig +++ b/configs/dra7xx_evm_defconfig @@ -25,7 +25,7 @@ CONFIG_SPL_SEPARATE_BSS=y CONFIG_SPL_DMA_SUPPORT=y CONFIG_SPL_OS_BOOT=y CONFIG_SPL_SPI_LOAD=y -CONFIG_FASTBOOT=y +CONFIG_USB_FUNCTION_FASTBOOT=y CONFIG_FASTBOOT_BUF_ADDR=0x82000000 CONFIG_FASTBOOT_BUF_SIZE=0x2F000000 CONFIG_FASTBOOT_FLASH=y diff --git a/configs/dra7xx_hs_evm_defconfig b/configs/dra7xx_hs_evm_defconfig index 536946eb29..39a6801216 100644 --- a/configs/dra7xx_hs_evm_defconfig +++ b/configs/dra7xx_hs_evm_defconfig @@ -30,7 +30,7 @@ CONFIG_SPL_SYS_MALLOC_SIMPLE=y CONFIG_SPL_SEPARATE_BSS=y CONFIG_SPL_DMA_SUPPORT=y CONFIG_SPL_SPI_LOAD=y -CONFIG_FASTBOOT=y +CONFIG_USB_FUNCTION_FASTBOOT=y CONFIG_FASTBOOT_BUF_ADDR=0x82000000 CONFIG_FASTBOOT_BUF_SIZE=0x2F000000 CONFIG_FASTBOOT_FLASH=y diff --git a/configs/imx6dl_mamoj_defconfig b/configs/imx6dl_mamoj_defconfig index 0001457f5d..40a128b8cb 100644 --- a/configs/imx6dl_mamoj_defconfig +++ b/configs/imx6dl_mamoj_defconfig @@ -9,7 +9,7 @@ CONFIG_DEFAULT_DEVICE_TREE="imx6dl-mamoj" CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/mach-imx/spl_sd.cfg" CONFIG_BOOTDELAY=3 CONFIG_HUSH_PARSER=y -CONFIG_FASTBOOT=y +CONFIG_USB_FUNCTION_FASTBOOT=y CONFIG_FASTBOOT_BUF_ADDR=0x12000000 CONFIG_FASTBOOT_BUF_SIZE=0x10000000 CONFIG_FASTBOOT_FLASH=y diff --git a/configs/kc1_defconfig b/configs/kc1_defconfig index 534d60484a..ce71e37011 100644 --- a/configs/kc1_defconfig +++ b/configs/kc1_defconfig @@ -12,7 +12,7 @@ CONFIG_SYS_CONSOLE_IS_IN_ENV=y CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION=y CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION=2 CONFIG_SYS_PROMPT="kc1 # " -CONFIG_FASTBOOT=y +CONFIG_USB_FUNCTION_FASTBOOT=y CONFIG_FASTBOOT_BUF_ADDR=0x82000000 CONFIG_FASTBOOT_BUF_SIZE=0x2000000 CONFIG_FASTBOOT_FLASH=y diff --git a/configs/mx6qsabrelite_defconfig b/configs/mx6qsabrelite_defconfig index 966e823b40..a4740d49cf 100644 --- a/configs/mx6qsabrelite_defconfig +++ b/configs/mx6qsabrelite_defconfig @@ -9,7 +9,7 @@ CONFIG_BOOTDELAY=3 # CONFIG_USE_BOOTCOMMAND is not set CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE=y CONFIG_BOARD_EARLY_INIT_F=y -CONFIG_FASTBOOT=y +CONFIG_USB_FUNCTION_FASTBOOT=y CONFIG_FASTBOOT_BUF_ADDR=0x12000000 CONFIG_CMD_MEMTEST=y CONFIG_SYS_ALT_MEMTEST=y diff --git a/configs/mx6sabresd_defconfig b/configs/mx6sabresd_defconfig index ca37d8bef8..5c8e9de081 100644 --- a/configs/mx6sabresd_defconfig +++ b/configs/mx6sabresd_defconfig @@ -22,7 +22,7 @@ CONFIG_SPL_USB_HOST_SUPPORT=y CONFIG_SPL_USB_GADGET_SUPPORT=y CONFIG_SPL_USB_SDP_SUPPORT=y CONFIG_HUSH_PARSER=y -CONFIG_FASTBOOT=y +CONFIG_USB_FUNCTION_FASTBOOT=y CONFIG_FASTBOOT_BUF_ADDR=0x12000000 CONFIG_FASTBOOT_BUF_SIZE=0x10000000 CONFIG_FASTBOOT_FLASH=y diff --git a/configs/nitrogen6dl2g_defconfig b/configs/nitrogen6dl2g_defconfig index 6ef4226db9..cfb2ed8889 100644 --- a/configs/nitrogen6dl2g_defconfig +++ b/configs/nitrogen6dl2g_defconfig @@ -9,7 +9,7 @@ CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE=y CONFIG_SUPPORT_RAW_INITRD=y CONFIG_BOARD_EARLY_INIT_F=y CONFIG_HUSH_PARSER=y -CONFIG_FASTBOOT=y +CONFIG_USB_FUNCTION_FASTBOOT=y CONFIG_FASTBOOT_BUF_ADDR=0x12000000 CONFIG_CMD_BOOTZ=y CONFIG_CMD_MEMTEST=y diff --git a/configs/nitrogen6dl_defconfig b/configs/nitrogen6dl_defconfig index b9784a2d23..9cb7ac22d5 100644 --- a/configs/nitrogen6dl_defconfig +++ b/configs/nitrogen6dl_defconfig @@ -9,7 +9,7 @@ CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE=y CONFIG_SUPPORT_RAW_INITRD=y CONFIG_BOARD_EARLY_INIT_F=y CONFIG_HUSH_PARSER=y -CONFIG_FASTBOOT=y +CONFIG_USB_FUNCTION_FASTBOOT=y CONFIG_FASTBOOT_BUF_ADDR=0x12000000 CONFIG_CMD_BOOTZ=y CONFIG_CMD_MEMTEST=y diff --git a/configs/nitrogen6q2g_defconfig b/configs/nitrogen6q2g_defconfig index 61688ba49e..e31521a060 100644 --- a/configs/nitrogen6q2g_defconfig +++ b/configs/nitrogen6q2g_defconfig @@ -9,7 +9,7 @@ CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE=y CONFIG_SUPPORT_RAW_INITRD=y CONFIG_BOARD_EARLY_INIT_F=y CONFIG_HUSH_PARSER=y -CONFIG_FASTBOOT=y +CONFIG_USB_FUNCTION_FASTBOOT=y CONFIG_FASTBOOT_BUF_ADDR=0x12000000 CONFIG_CMD_BOOTZ=y CONFIG_CMD_MEMTEST=y diff --git a/configs/nitrogen6q_defconfig b/configs/nitrogen6q_defconfig index cfee7ba889..85c352c6f0 100644 --- a/configs/nitrogen6q_defconfig +++ b/configs/nitrogen6q_defconfig @@ -9,7 +9,7 @@ CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE=y CONFIG_SUPPORT_RAW_INITRD=y CONFIG_BOARD_EARLY_INIT_F=y CONFIG_HUSH_PARSER=y -CONFIG_FASTBOOT=y +CONFIG_USB_FUNCTION_FASTBOOT=y CONFIG_FASTBOOT_BUF_ADDR=0x12000000 CONFIG_CMD_BOOTZ=y CONFIG_CMD_MEMTEST=y diff --git a/configs/nitrogen6s1g_defconfig b/configs/nitrogen6s1g_defconfig index 0f29a56c46..1f3732019d 100644 --- a/configs/nitrogen6s1g_defconfig +++ b/configs/nitrogen6s1g_defconfig @@ -9,7 +9,7 @@ CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE=y CONFIG_SUPPORT_RAW_INITRD=y CONFIG_BOARD_EARLY_INIT_F=y CONFIG_HUSH_PARSER=y -CONFIG_FASTBOOT=y +CONFIG_USB_FUNCTION_FASTBOOT=y CONFIG_FASTBOOT_BUF_ADDR=0x12000000 CONFIG_CMD_BOOTZ=y CONFIG_CMD_MEMTEST=y diff --git a/configs/nitrogen6s_defconfig b/configs/nitrogen6s_defconfig index 7ad1584af2..0696f09d5e 100644 --- a/configs/nitrogen6s_defconfig +++ b/configs/nitrogen6s_defconfig @@ -9,7 +9,7 @@ CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE=y CONFIG_SUPPORT_RAW_INITRD=y CONFIG_BOARD_EARLY_INIT_F=y CONFIG_HUSH_PARSER=y -CONFIG_FASTBOOT=y +CONFIG_USB_FUNCTION_FASTBOOT=y CONFIG_FASTBOOT_BUF_ADDR=0x12000000 CONFIG_CMD_BOOTZ=y CONFIG_CMD_MEMTEST=y diff --git a/configs/omap3_beagle_defconfig b/configs/omap3_beagle_defconfig index 7b81b039c9..05dc73755f 100644 --- a/configs/omap3_beagle_defconfig +++ b/configs/omap3_beagle_defconfig @@ -13,7 +13,7 @@ CONFIG_VERSION_VARIABLE=y CONFIG_SPL_MTD_SUPPORT=y CONFIG_SPL_OS_BOOT=y CONFIG_SYS_PROMPT="BeagleBoard # " -CONFIG_FASTBOOT=y +CONFIG_USB_FUNCTION_FASTBOOT=y CONFIG_FASTBOOT_BUF_ADDR=0x82000000 CONFIG_CMD_SPL=y CONFIG_CMD_SPL_NAND_OFS=0x280000 diff --git a/configs/omap3_evm_defconfig b/configs/omap3_evm_defconfig index 20795c3170..52285cc165 100644 --- a/configs/omap3_evm_defconfig +++ b/configs/omap3_evm_defconfig @@ -12,7 +12,7 @@ CONFIG_VERSION_VARIABLE=y CONFIG_SPL_MTD_SUPPORT=y CONFIG_SPL_OS_BOOT=y CONFIG_SYS_PROMPT="OMAP3_EVM # " -CONFIG_FASTBOOT=y +CONFIG_USB_FUNCTION_FASTBOOT=y CONFIG_FASTBOOT_BUF_ADDR=0x82000000 CONFIG_CMD_SPL=y CONFIG_CMD_SPL_NAND_OFS=0x280000 diff --git a/configs/omap3_logic_defconfig b/configs/omap3_logic_defconfig index 5a31e46dba..953980c95c 100644 --- a/configs/omap3_logic_defconfig +++ b/configs/omap3_logic_defconfig @@ -13,7 +13,7 @@ CONFIG_SPL_SYS_MALLOC_SIMPLE=y CONFIG_SPL_MTD_SUPPORT=y CONFIG_SPL_OS_BOOT=y CONFIG_SYS_PROMPT="OMAP Logic # " -CONFIG_FASTBOOT=y +CONFIG_USB_FUNCTION_FASTBOOT=y CONFIG_FASTBOOT_BUF_ADDR=0x82000000 # CONFIG_CMD_IMI is not set CONFIG_CMD_SPL=y diff --git a/configs/sniper_defconfig b/configs/sniper_defconfig index ad22a1cbe2..70e485fab2 100644 --- a/configs/sniper_defconfig +++ b/configs/sniper_defconfig @@ -13,7 +13,7 @@ CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION=y CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION=2 # CONFIG_SPL_EXT_SUPPORT is not set CONFIG_SYS_PROMPT="sniper # " -CONFIG_FASTBOOT=y +CONFIG_USB_FUNCTION_FASTBOOT=y CONFIG_FASTBOOT_BUF_ADDR=0x82000000 CONFIG_FASTBOOT_BUF_SIZE=0x2000000 CONFIG_FASTBOOT_FLASH=y diff --git a/configs/stih410-b2260_defconfig b/configs/stih410-b2260_defconfig index 67391bdfdf..7d990f9a34 100644 --- a/configs/stih410-b2260_defconfig +++ b/configs/stih410-b2260_defconfig @@ -10,7 +10,7 @@ CONFIG_USE_BOOTARGS=y CONFIG_BOOTARGS="console=ttyAS1,115200 CONSOLE=/dev/ttyAS1 consoleblank=0 root=/dev/mmcblk0p2 rootfstype=ext4 rw rootwait mem=992M@0x40000000 vmalloc=256m" # CONFIG_DISPLAY_CPUINFO is not set CONFIG_SYS_PROMPT="stih410-b2260 => " -CONFIG_FASTBOOT=y +CONFIG_USB_FUNCTION_FASTBOOT=y CONFIG_FASTBOOT_BUF_ADDR=0x40000000 CONFIG_FASTBOOT_BUF_SIZE=0x3DF00000 CONFIG_FASTBOOT_FLASH=y diff --git a/configs/xilinx_zynqmp_zc1751_xm015_dc1_defconfig b/configs/xilinx_zynqmp_zc1751_xm015_dc1_defconfig index f5a33342fa..9e4886d064 100644 --- a/configs/xilinx_zynqmp_zc1751_xm015_dc1_defconfig +++ b/configs/xilinx_zynqmp_zc1751_xm015_dc1_defconfig @@ -19,7 +19,7 @@ CONFIG_SPL_RAM_SUPPORT=y CONFIG_SPL_RAM_DEVICE=y CONFIG_SPL_ATF=y CONFIG_SYS_PROMPT="ZynqMP> " -CONFIG_FASTBOOT=y +CONFIG_USB_FUNCTION_FASTBOOT=y CONFIG_FASTBOOT_FLASH=y CONFIG_FASTBOOT_FLASH_MMC_DEV=0 CONFIG_CMD_THOR_DOWNLOAD=y diff --git a/configs/xilinx_zynqmp_zc1751_xm016_dc2_defconfig b/configs/xilinx_zynqmp_zc1751_xm016_dc2_defconfig index 7f7ee558ee..9d9216f5fe 100644 --- a/configs/xilinx_zynqmp_zc1751_xm016_dc2_defconfig +++ b/configs/xilinx_zynqmp_zc1751_xm016_dc2_defconfig @@ -20,7 +20,7 @@ CONFIG_SPL_RAM_SUPPORT=y CONFIG_SPL_RAM_DEVICE=y CONFIG_SPL_ATF=y CONFIG_SYS_PROMPT="ZynqMP> " -CONFIG_FASTBOOT=y +CONFIG_USB_FUNCTION_FASTBOOT=y CONFIG_FASTBOOT_FLASH=y CONFIG_CMD_THOR_DOWNLOAD=y CONFIG_CMD_MEMTEST=y diff --git a/configs/xilinx_zynqmp_zcu102_rev1_0_defconfig b/configs/xilinx_zynqmp_zcu102_rev1_0_defconfig index 4cb3959f36..29743bdb1e 100644 --- a/configs/xilinx_zynqmp_zcu102_rev1_0_defconfig +++ b/configs/xilinx_zynqmp_zcu102_rev1_0_defconfig @@ -19,7 +19,7 @@ CONFIG_SPL_RAM_SUPPORT=y CONFIG_SPL_RAM_DEVICE=y CONFIG_SPL_ATF=y CONFIG_SYS_PROMPT="ZynqMP> " -CONFIG_FASTBOOT=y +CONFIG_USB_FUNCTION_FASTBOOT=y CONFIG_FASTBOOT_FLASH=y CONFIG_FASTBOOT_FLASH_MMC_DEV=0 CONFIG_CMD_THOR_DOWNLOAD=y diff --git a/configs/xilinx_zynqmp_zcu102_revA_defconfig b/configs/xilinx_zynqmp_zcu102_revA_defconfig index e989d1635c..cc4118230e 100644 --- a/configs/xilinx_zynqmp_zcu102_revA_defconfig +++ b/configs/xilinx_zynqmp_zcu102_revA_defconfig @@ -19,7 +19,7 @@ CONFIG_SPL_RAM_SUPPORT=y CONFIG_SPL_RAM_DEVICE=y CONFIG_SPL_ATF=y CONFIG_SYS_PROMPT="ZynqMP> " -CONFIG_FASTBOOT=y +CONFIG_USB_FUNCTION_FASTBOOT=y CONFIG_FASTBOOT_FLASH=y CONFIG_FASTBOOT_FLASH_MMC_DEV=0 CONFIG_CMD_THOR_DOWNLOAD=y diff --git a/configs/xilinx_zynqmp_zcu102_revB_defconfig b/configs/xilinx_zynqmp_zcu102_revB_defconfig index bd67df904a..ae791c3567 100644 --- a/configs/xilinx_zynqmp_zcu102_revB_defconfig +++ b/configs/xilinx_zynqmp_zcu102_revB_defconfig @@ -19,7 +19,7 @@ CONFIG_SPL_RAM_SUPPORT=y CONFIG_SPL_RAM_DEVICE=y CONFIG_SPL_ATF=y CONFIG_SYS_PROMPT="ZynqMP> " -CONFIG_FASTBOOT=y +CONFIG_USB_FUNCTION_FASTBOOT=y CONFIG_FASTBOOT_FLASH=y CONFIG_FASTBOOT_FLASH_MMC_DEV=0 CONFIG_CMD_THOR_DOWNLOAD=y diff --git a/configs/xilinx_zynqmp_zcu106_revA_defconfig b/configs/xilinx_zynqmp_zcu106_revA_defconfig index a5fa33e366..34e3c857e2 100644 --- a/configs/xilinx_zynqmp_zcu106_revA_defconfig +++ b/configs/xilinx_zynqmp_zcu106_revA_defconfig @@ -18,7 +18,7 @@ CONFIG_SPL_RAM_SUPPORT=y CONFIG_SPL_RAM_DEVICE=y CONFIG_SPL_ATF=y CONFIG_SYS_PROMPT="ZynqMP> " -CONFIG_FASTBOOT=y +CONFIG_USB_FUNCTION_FASTBOOT=y CONFIG_FASTBOOT_FLASH=y CONFIG_FASTBOOT_FLASH_MMC_DEV=0 CONFIG_CMD_THOR_DOWNLOAD=y diff --git a/drivers/Kconfig b/drivers/Kconfig index c2e813f5ad..8424898dbd 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -28,6 +28,8 @@ source "drivers/dfu/Kconfig" source "drivers/dma/Kconfig" +source "drivers/fastboot/Kconfig" + source "drivers/firmware/Kconfig" source "drivers/fpga/Kconfig" diff --git a/drivers/Makefile b/drivers/Makefile index b3f1b600a5..a79ff2e6b0 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -71,6 +71,9 @@ obj-y += block/ obj-$(CONFIG_BOOTCOUNT_LIMIT) += bootcount/ obj-$(CONFIG_CPU) += cpu/ obj-y += crypto/ +ifneq ($(CONFIG_FASTBOOT_FLASH_MMC_DEV)$(CONFIG_FASTBOOT_FLASH_NAND_DEV),) +obj-y += fastboot/ +endif obj-y += firmware/ obj-$(CONFIG_FPGA) += fpga/ obj-y += misc/ diff --git a/drivers/fastboot/Kconfig b/drivers/fastboot/Kconfig new file mode 100644 index 0000000000..93a8ac64e7 --- /dev/null +++ b/drivers/fastboot/Kconfig @@ -0,0 +1,123 @@ +menu "Fastboot support" + +config FASTBOOT + bool + imply ANDROID_BOOT_IMAGE + imply CMD_FASTBOOT + +config USB_FUNCTION_FASTBOOT + bool "Enable USB fastboot gadget" + depends on USB_GADGET + default y if ARCH_SUNXI && USB_MUSB_GADGET + select FASTBOOT + select USB_GADGET_DOWNLOAD + help + This enables the USB part of the fastboot gadget. + +if FASTBOOT + +config FASTBOOT_BUF_ADDR + hex "Define FASTBOOT buffer address" + default 0x82000000 if MX6SX || MX6SL || MX6UL || MX6SLL + default 0x81000000 if ARCH_OMAP2PLUS + default 0x42000000 if ARCH_SUNXI && !MACH_SUN9I + default 0x22000000 if ARCH_SUNXI && MACH_SUN9I + default 0x60800800 if ROCKCHIP_RK3036 || ROCKCHIP_RK3188 || \ + ROCKCHIP_RK322X + default 0x800800 if ROCKCHIP_RK3288 || ROCKCHIP_RK3329 || \ + ROCKCHIP_RK3399 + default 0x280000 if ROCKCHIP_RK3368 + default 0x100000 if ARCH_ZYNQMP + help + The fastboot protocol requires a large memory buffer for + downloads. Define this to the starting RAM address to use for + downloaded images. + +config FASTBOOT_BUF_SIZE + hex "Define FASTBOOT buffer size" + default 0x8000000 if ARCH_ROCKCHIP + default 0x6000000 if ARCH_ZYNQMP + default 0x2000000 if ARCH_SUNXI + default 0x7000000 + help + The fastboot protocol requires a large memory buffer for + downloads. This buffer should be as large as possible for a + platform. Define this to the size available RAM for fastboot. + +config FASTBOOT_USB_DEV + int "USB controller number" + depends on USB_FUNCTION_FASTBOOT + default 0 + help + Some boards have USB OTG controller other than 0. Define this + option so it can be used in compiled environment (e.g. in + CONFIG_BOOTCOMMAND). + +config FASTBOOT_FLASH + bool "Enable FASTBOOT FLASH command" + default y if ARCH_SUNXI + help + The fastboot protocol includes a "flash" command for writing + the downloaded image to a non-volatile storage device. Define + this to enable the "fastboot flash" command. + +choice + prompt "Flash provider for FASTBOOT" + depends on FASTBOOT_FLASH + +config FASTBOOT_FLASH_MMC + bool "FASTBOOT on MMC" + depends on MMC + +config FASTBOOT_FLASH_NAND + bool "FASTBOOT on NAND" + depends on NAND + +endchoice + +config FASTBOOT_FLASH_MMC_DEV + int "Define FASTBOOT MMC FLASH default device" + depends on FASTBOOT_FLASH_MMC + default 0 if ARCH_SUNXI && MMC_SUNXI_SLOT_EXTRA = -1 + default 1 if ARCH_SUNXI && MMC_SUNXI_SLOT_EXTRA != -1 + help + The fastboot "flash" command requires additional information + regarding the non-volatile storage device. Define this to + the eMMC device that fastboot should use to store the image. + +config FASTBOOT_FLASH_NAND_DEV + int "Define FASTBOOT NAND FLASH default device" + depends on FASTBOOT_FLASH_NAND + depends on CMD_MTDPARTS + default 0 if ARCH_SUNXI && NAND_SUNXI + help + The fastboot "flash" command requires additional information + regarding the non-volatile storage device. Define this to + the NAND device that fastboot should use to store the image. + +config FASTBOOT_GPT_NAME + string "Target name for updating GPT" + depends on FASTBOOT_FLASH + default "gpt" + help + The fastboot "flash" command supports writing the downloaded + image to the Protective MBR and the Primary GUID Partition + Table. (Additionally, this downloaded image is post-processed + to generate and write the Backup GUID Partition Table.) + This occurs when the specified "partition name" on the + "fastboot flash" command line matches the value defined here. + The default target name for updating GPT is "gpt". + +config FASTBOOT_MBR_NAME + string "Target name for updating MBR" + depends on FASTBOOT_FLASH + default "mbr" + help + The fastboot "flash" command allows to write the downloaded image + to the Master Boot Record. This occurs when the "partition name" + specified on the "fastboot flash" command line matches the value + defined here. The default target name for updating MBR is "mbr". + +endif # FASTBOOT + +endmenu diff --git a/drivers/fastboot/Makefile b/drivers/fastboot/Makefile new file mode 100644 index 0000000000..651fbf0935 --- /dev/null +++ b/drivers/fastboot/Makefile @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: GPL-2.0+ + +ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV +obj-y += fb_mmc.o +endif +ifdef CONFIG_FASTBOOT_FLASH_NAND_DEV +obj-y += fb_nand.o +endif diff --git a/drivers/fastboot/fb_mmc.c b/drivers/fastboot/fb_mmc.c new file mode 100644 index 0000000000..46f0073dbc --- /dev/null +++ b/drivers/fastboot/fb_mmc.c @@ -0,0 +1,406 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2014 Broadcom Corporation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * 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/drivers/fastboot/fb_nand.c b/drivers/fastboot/fb_nand.c new file mode 100644 index 0000000000..c07655e49e --- /dev/null +++ b/drivers/fastboot/fb_nand.c @@ -0,0 +1,230 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2014 Broadcom Corporation. + * Copyright 2015 Free Electrons. + */ + +#include +#include + +#include +#include + +#include +#include +#include + +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(""); +}