Signed-off-by: Julien Masson <[email protected]>
Signed-off-by: Vitor Sato Eschholz <[email protected]>
Signed-off-by: Carlo Caione <[email protected]>
---
cmd/fastboot.c | 60 +++++----------------------
doc/android/fastboot.rst | 27 ++++++++++++-
drivers/Makefile | 2 +-
drivers/fastboot/Kconfig | 89 ++++++++++++++++++++++++++++++++++++++++-
drivers/fastboot/Makefile | 13 ++++--
drivers/fastboot/fb_block.c | 9 ++---
drivers/fastboot/fb_command.c | 58 +++++++++++++++++++--------
drivers/fastboot/fb_common.c | 25 +++++++++++-
drivers/fastboot/fb_getvar.c | 19 +++++----
drivers/fastboot/fb_mmc.c | 36 ++++++++---------
drivers/fastboot/fb_usb.c | 68 +++++++++++++++++++++++++++++++
drivers/usb/gadget/Makefile | 1 +
drivers/usb/gadget/f_fastboot.c | 6 ++-
include/fastboot.h | 10 +++++
lib/Kconfig | 11 +++++
lib/Makefile | 3 +-
lib/image-sparse.c | 2 +-
17 files changed, 328 insertions(+), 111 deletions(-)
diff --git a/cmd/fastboot.c b/cmd/fastboot.c
index f3929f88dfa..b12f9ea0ac4 100644
--- a/cmd/fastboot.c
+++ b/cmd/fastboot.c
@@ -7,12 +7,9 @@
* Rob Herring <[email protected]>
*/
#include <command.h>
-#include <console.h>
-#include <g_dnl.h>
#include <fastboot.h>
#include <net.h>
-#include <usb.h>
-#include <watchdog.h>
+#include <vsprintf.h>
#include <linux/printk.h>
#include <linux/stringify.h>
@@ -63,7 +60,6 @@ static int do_fastboot_usb(int argc, char *const argv[],
{
int controller_index;
char *usb_controller;
- struct udevice *udc;
char *endp;
int ret;
@@ -82,48 +78,9 @@ static int do_fastboot_usb(int argc, char *const argv[],
return CMD_RET_FAILURE;
}
- ret = udc_device_get_by_index(controller_index, &udc);
- if (ret) {
- pr_err("USB init failed: %d\n", ret);
- return CMD_RET_FAILURE;
- }
-
- g_dnl_clear_detach();
- ret = g_dnl_register("usb_dnl_fastboot");
- if (ret)
- return ret;
-
- if (!g_dnl_board_usb_cable_connected()) {
- puts("\rUSB cable not detected.\n" \
- "Command exit.\n");
- ret = CMD_RET_FAILURE;
- goto exit;
- }
-
- while (1) {
- if (g_dnl_detach())
- break;
- if (IS_ENABLED(CONFIG_CMD_FASTBOOT_ABORT_KEYED)) {
- if (tstc()) {
- getchar();
- puts("\rOperation aborted.\n");
- break;
- }
- } else if (ctrlc()) {
- break;
- }
- schedule();
- dm_usb_gadget_handle_interrupts(udc);
- }
-
- ret = CMD_RET_SUCCESS;
-
-exit:
- udc_device_put(udc);
- g_dnl_unregister();
- g_dnl_clear_detach();
+ ret = fastboot_usb_start(controller_index, (void *)buf_addr, buf_size);
- return ret;
+ return ret ? CMD_RET_FAILURE : CMD_RET_SUCCESS;
}
static int do_fastboot(struct cmd_tbl *cmdtp, int flag, int argc,
@@ -167,13 +124,14 @@ NXTARG:
return CMD_RET_USAGE;
}
- fastboot_init((void *)buf_addr, buf_size);
-
#if CONFIG_IS_ENABLED(NET_LEGACY)
- if (!strcmp(argv[1], "udp"))
- return do_fastboot_udp(argc, argv, buf_addr, buf_size);
- if (!strcmp(argv[1], "tcp"))
+ if (!strcmp(argv[1], "udp") || !strcmp(argv[1], "tcp")) {
+ fastboot_init((void *)buf_addr, buf_size);
+ if (!strcmp(argv[1], "udp"))
+ return do_fastboot_udp(argc, argv, buf_addr, buf_size);
+
return do_fastboot_tcp(argc, argv, buf_addr, buf_size);
+ }
#endif
if (!strcmp(argv[1], "usb")) {
argv++;
diff --git a/doc/android/fastboot.rst b/doc/android/fastboot.rst
index 96c544ae11b..3f9cfb2fa78 100644
--- a/doc/android/fastboot.rst
+++ b/doc/android/fastboot.rst
@@ -10,7 +10,7 @@ The protocol that is used over USB and UDP is described in
[1]_.
The current implementation supports the following standard commands:
-- ``boot``
+- ``boot`` (not available in SPL)
- ``continue``
- ``download``
- ``erase`` (if enabled)
@@ -72,6 +72,31 @@ platform. The location of the buffer and size are set with
may be overridden on the fastboot command line using ``-l`` and
``-s``.
+Fastboot in SPL
+^^^^^^^^^^^^^^^
+
+Fastboot can be used from SPL without enabling the command line. Enable
+``CONFIG_SPL_FASTBOOT`` together with the platform's SPL USB gadget support,
+then start the session from board code::
+
+ ret = fastboot_usb_start(controller_index, NULL, 0);
+
+A ``NULL`` buffer and zero size select ``CONFIG_FASTBOOT_BUF_ADDR`` and
+``CONFIG_FASTBOOT_BUF_SIZE``. Passing explicit values overrides these
+defaults. The ``continue`` command ends the session and returns control to the
+caller. Unlike the command-line invocation, an SPL session cannot be aborted
+from the local console.
+
+MMC flash and erase support is enabled with
+``CONFIG_SPL_FASTBOOT_FLASH_MMC``. The SPL partition-table parser matching the
+storage layout must also be enabled, for example ``CONFIG_SPL_EFI_PARTITION``
+for GPT.
+
+The ``boot`` command is not available in SPL. Reboot commands require
+``CONFIG_SPL_FASTBOOT_REBOOT`` and a platform ``reset_cpu()`` implementation.
+The ``reboot-bootloader``, ``reboot-fastboot`` and ``reboot-recovery`` commands
+also require a platform ``fastboot_set_reboot_flag()`` implementation.
+
Fastboot environment variables
------------------------------
diff --git a/drivers/Makefile b/drivers/Makefile
index 43d0ba33281..43d03479146 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_$(PHASE_)DMA) += dma/
obj-$(CONFIG_$(PHASE_)DMA_LEGACY) += dma/
obj-$(CONFIG_$(PHASE_)DFU) += dfu/
obj-$(CONFIG_$(PHASE_)EXTCON) += extcon/
+obj-$(CONFIG_$(PHASE_)FASTBOOT) += fastboot/
obj-$(CONFIG_$(PHASE_)GPIO) += gpio/
obj-$(CONFIG_$(PHASE_)DRIVERS_MISC) += misc/
obj-$(CONFIG_$(PHASE_)SYSRESET) += sysreset/
@@ -93,7 +94,6 @@ obj-y += block/
obj-y += cache/
obj-$(CONFIG_CPU) += cpu/
obj-y += crypto/
-obj-$(CONFIG_FASTBOOT) += fastboot/
obj-$(CONFIG_FWU_MDATA) += fwu-mdata/
obj-y += misc/
obj-$(CONFIG_MMC) += mmc/
diff --git a/drivers/fastboot/Kconfig b/drivers/fastboot/Kconfig
index 90212fcf9ef..017fb7956a1 100644
--- a/drivers/fastboot/Kconfig
+++ b/drivers/fastboot/Kconfig
@@ -1,5 +1,6 @@
menu "Fastboot support"
- depends on CMDLINE
+
+if CMDLINE
config FASTBOOT
bool
@@ -47,7 +48,27 @@ config TCP_FUNCTION_FASTBOOT
help
This enables the fastboot protocol over TCP.
-if FASTBOOT
+endif # CMDLINE
+
+config SPL_FASTBOOT
+ bool "Support fastboot in SPL"
+ depends on USB_GADGET && SPL_USB_GADGET
+ depends on SPL_ENV_SUPPORT
+ depends on !SPL_USE_TINY_PRINTF
+ select SPL_LIBCOMMON_SUPPORT
+ select SPL_LIBGENERIC_SUPPORT
+ select SPL_PRINTF
+ help
+ Enable the USB fastboot protocol in SPL. The board is responsible
+ for starting the fastboot session.
+
+config SPL_FASTBOOT_REBOOT
+ bool "Enable fastboot reboot commands in SPL"
+ depends on SPL_FASTBOOT
+ help
+ Enable the fastboot reboot commands in SPL.
+
+if FASTBOOT || SPL_FASTBOOT
config FASTBOOT_BUF_ADDR
hex "Define FASTBOOT buffer address"
@@ -79,6 +100,10 @@ config FASTBOOT_BUF_SIZE
downloads. This buffer should be as large as possible for a
platform. Define this to the size available RAM for fastboot.
+endif # FASTBOOT || SPL_FASTBOOT
+
+if FASTBOOT
+
config FASTBOOT_USB_DEV
int "USB controller number"
depends on USB_FUNCTION_FASTBOOT
@@ -294,4 +319,64 @@ config FASTBOOT_OEM_BOARD
endif # FASTBOOT
+config SPL_FASTBOOT_FLASH
+ bool
+ default y if SPL_FASTBOOT_FLASH_MMC
+ select SPL_IMAGE_SPARSE
+
+config SPL_FASTBOOT_FLASH_MMC
+ bool "Enable fastboot MMC flashing in SPL"
+ depends on SPL_FASTBOOT && SPL_MMC && SPL_DM_MMC && SPL_PARTITIONS
+ select SPL_MMC_WRITE
+ help
+ Build the fastboot MMC flashing backend into SPL. This allows the
+ fastboot flash and erase commands to operate on MMC partitions. A
+ suitable SPL partition-table parser must also be enabled.
+
+config SPL_FASTBOOT_FLASH_MMC_DEV
+ int "Define fastboot MMC flash device in SPL"
+ depends on SPL_FASTBOOT_FLASH_MMC
+ default 0
+ help
+ Define the MMC device that the SPL fastboot flash backend uses.
+
+config SPL_FASTBOOT_MMC_BOOT_SUPPORT
+ bool "Enable eMMC boot-partition flash/erase in SPL"
+ depends on SPL_FASTBOOT_FLASH_MMC && SUPPORT_EMMC_BOOT
+ help
+ Enable the special fastboot targets used to flash or erase the eMMC
+ boot hardware partitions from SPL.
+
+config SPL_FASTBOOT_MMC_BOOT1_NAME
+ string "Target name for updating eMMC boot partition 1 in SPL"
+ depends on SPL_FASTBOOT_MMC_BOOT_SUPPORT
+ default "mmc0boot0"
+
+config SPL_FASTBOOT_MMC_BOOT2_NAME
+ string "Target name for updating eMMC boot partition 2 in SPL"
+ depends on SPL_FASTBOOT_MMC_BOOT_SUPPORT
+ default "mmc0boot1"
+
+config SPL_FASTBOOT_MMC_USER_SUPPORT
+ bool "Enable eMMC user-area flash/erase in SPL"
+ depends on SPL_FASTBOOT_FLASH_MMC
+ help
+ Enable a special fastboot target for flashing or erasing the complete
+ eMMC user area from SPL.
+
+config SPL_FASTBOOT_MMC_USER_NAME
+ string "Target name for updating the eMMC user area in SPL"
+ depends on SPL_FASTBOOT_MMC_USER_SUPPORT
+ default "mmc0"
+
+config SPL_FASTBOOT_GPT_NAME
+ string "Target name for updating GPT from SPL"
+ depends on SPL_FASTBOOT_FLASH_MMC && SPL_EFI_PARTITION
+ default "gpt"
+
+config SPL_FASTBOOT_MBR_NAME
+ string "Target name for updating MBR from SPL"
+ depends on SPL_FASTBOOT_FLASH_MMC && SPL_DOS_PARTITION
+ default "mbr"
+
endmenu
diff --git a/drivers/fastboot/Makefile b/drivers/fastboot/Makefile
index a341af076d1..43e391d8ec4 100644
--- a/drivers/fastboot/Makefile
+++ b/drivers/fastboot/Makefile
@@ -3,8 +3,13 @@
obj-y += fb_common.o
obj-y += fb_getvar.o
obj-y += fb_command.o
-obj-$(CONFIG_FASTBOOT_FLASH_BLOCK) += fb_block.o
+ifndef CONFIG_XPL_BUILD
+obj-$(CONFIG_USB_FUNCTION_FASTBOOT) += fb_usb.o
+else
+obj-$(CONFIG_SPL_FASTBOOT) += fb_usb.o
+endif
+obj-$(CONFIG_$(PHASE_)FASTBOOT_FLASH_BLOCK) += fb_block.o
# MMC reuses block implementation
-obj-$(CONFIG_FASTBOOT_FLASH_MMC) += fb_block.o fb_mmc.o
-obj-$(CONFIG_FASTBOOT_FLASH_NAND) += fb_nand.o
-obj-$(CONFIG_FASTBOOT_FLASH_SPI) += fb_spi_flash.o
+obj-$(CONFIG_$(PHASE_)FASTBOOT_FLASH_MMC) += fb_block.o fb_mmc.o
+obj-$(CONFIG_$(PHASE_)FASTBOOT_FLASH_NAND) += fb_nand.o
+obj-$(CONFIG_$(PHASE_)FASTBOOT_FLASH_SPI) += fb_spi_flash.o
diff --git a/drivers/fastboot/fb_block.c b/drivers/fastboot/fb_block.c
index 51d1abb18c7..9658b14e668 100644
--- a/drivers/fastboot/fb_block.c
+++ b/drivers/fastboot/fb_block.c
@@ -130,11 +130,10 @@ int fastboot_block_get_part_info(const char *part_name,
char *response)
{
int ret;
- const char *interface = config_opt_enabled(CONFIG_FASTBOOT_FLASH_BLOCK,
-
CONFIG_FASTBOOT_FLASH_BLOCK_INTERFACE_NAME,
- NULL);
- const int device = config_opt_enabled(CONFIG_FASTBOOT_FLASH_BLOCK,
-
CONFIG_FASTBOOT_FLASH_BLOCK_DEVICE_ID, -1);
+ const char *interface = CONFIG_IS_ENABLED(FASTBOOT_FLASH_BLOCK,
+ (CONFIG_VAL(FASTBOOT_FLASH_BLOCK_INTERFACE_NAME)), (NULL));
+ const int device = CONFIG_IS_ENABLED(FASTBOOT_FLASH_BLOCK,
+ (CONFIG_VAL(FASTBOOT_FLASH_BLOCK_DEVICE_ID)), (-1));
if (!part_name || !strcmp(part_name, "")) {
fastboot_fail("partition not given", response);
diff --git a/drivers/fastboot/fb_command.c b/drivers/fastboot/fb_command.c
index 18d86988f4c..4a3cc4cbb27 100644
--- a/drivers/fastboot/fb_command.c
+++ b/drivers/fastboot/fb_command.c
@@ -37,9 +37,9 @@ static void getvar(char *, char *);
static void download(char *, char *);
static void flash(char *, char *);
static void erase(char *, char *);
-static void reboot_bootloader(char *, char *);
-static void reboot_fastbootd(char *, char *);
-static void reboot_recovery(char *, char *);
+static void __maybe_unused reboot_bootloader(char *, char *);
+static void __maybe_unused reboot_fastbootd(char *, char *);
+static void __maybe_unused reboot_recovery(char *, char *);
static void oem_format(char *, char *);
static void oem_partconf(char *, char *);
static void oem_bootbus(char *, char *);
@@ -70,7 +70,9 @@ static const struct {
},
[FASTBOOT_COMMAND_BOOT] = {
.command = "boot",
+#ifndef CONFIG_XPL_BUILD
.dispatch = okay
+#endif
},
[FASTBOOT_COMMAND_CONTINUE] = {
.command = "continue",
@@ -78,19 +80,38 @@ static const struct {
},
[FASTBOOT_COMMAND_REBOOT] = {
.command = "reboot",
+#ifdef CONFIG_XPL_BUILD
+ .dispatch = CONFIG_IS_ENABLED(FASTBOOT_REBOOT, (okay), (NULL))
+#else
.dispatch = okay
+#endif
},
[FASTBOOT_COMMAND_REBOOT_BOOTLOADER] = {
.command = "reboot-bootloader",
+#ifdef CONFIG_XPL_BUILD
+ .dispatch = CONFIG_IS_ENABLED(FASTBOOT_REBOOT,
+ (reboot_bootloader), (NULL))
+#else
.dispatch = reboot_bootloader
+#endif
},
[FASTBOOT_COMMAND_REBOOT_FASTBOOTD] = {
.command = "reboot-fastboot",
+#ifdef CONFIG_XPL_BUILD
+ .dispatch = CONFIG_IS_ENABLED(FASTBOOT_REBOOT,
+ (reboot_fastbootd), (NULL))
+#else
.dispatch = reboot_fastbootd
+#endif
},
[FASTBOOT_COMMAND_REBOOT_RECOVERY] = {
.command = "reboot-recovery",
+#ifdef CONFIG_XPL_BUILD
+ .dispatch = CONFIG_IS_ENABLED(FASTBOOT_REBOOT,
+ (reboot_recovery), (NULL))
+#else
.dispatch = reboot_recovery
+#endif
},
[FASTBOOT_COMMAND_SET_ACTIVE] = {
.command = "set_active",
@@ -339,19 +360,19 @@ void fastboot_data_complete(char *response)
*/
static void __maybe_unused flash(char *cmd_parameter, char *response)
{
- if (IS_ENABLED(CONFIG_FASTBOOT_FLASH_BLOCK))
+ if (CONFIG_IS_ENABLED(FASTBOOT_FLASH_BLOCK))
fastboot_block_flash_write(cmd_parameter, fastboot_buf_addr,
image_size, response);
- if (IS_ENABLED(CONFIG_FASTBOOT_FLASH_MMC))
+ if (CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC))
fastboot_mmc_flash_write(cmd_parameter, fastboot_buf_addr,
image_size, response);
- if (IS_ENABLED(CONFIG_FASTBOOT_FLASH_NAND))
+ if (CONFIG_IS_ENABLED(FASTBOOT_FLASH_NAND))
fastboot_nand_flash_write(cmd_parameter, fastboot_buf_addr,
image_size, response);
- if (IS_ENABLED(CONFIG_FASTBOOT_FLASH_SPI))
+ if (CONFIG_IS_ENABLED(FASTBOOT_FLASH_SPI))
fastboot_spi_flash_write(cmd_parameter, fastboot_buf_addr,
image_size, response);
}
@@ -367,16 +388,16 @@ static void __maybe_unused flash(char *cmd_parameter,
char *response)
*/
static void __maybe_unused erase(char *cmd_parameter, char *response)
{
- if (IS_ENABLED(CONFIG_FASTBOOT_FLASH_BLOCK))
+ if (CONFIG_IS_ENABLED(FASTBOOT_FLASH_BLOCK))
fastboot_block_erase(cmd_parameter, response);
- if (IS_ENABLED(CONFIG_FASTBOOT_FLASH_MMC))
+ if (CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC))
fastboot_mmc_erase(cmd_parameter, response);
- if (IS_ENABLED(CONFIG_FASTBOOT_FLASH_NAND))
+ if (CONFIG_IS_ENABLED(FASTBOOT_FLASH_NAND))
fastboot_nand_erase(cmd_parameter, response);
- if (IS_ENABLED(CONFIG_FASTBOOT_FLASH_SPI))
+ if (CONFIG_IS_ENABLED(FASTBOOT_FLASH_SPI))
fastboot_spi_flash_erase(cmd_parameter, response);
}
@@ -482,8 +503,9 @@ static void reboot_recovery(char *cmd_parameter, char *response)
static void __maybe_unused oem_format(char *cmd_parameter, char *response)
{
char cmdbuf[32];
- const int mmc_dev = config_opt_enabled(CONFIG_FASTBOOT_FLASH_MMC,
- CONFIG_FASTBOOT_FLASH_MMC_DEV,
-1);
+ const int mmc_dev = CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC,
+
(CONFIG_VAL(FASTBOOT_FLASH_MMC_DEV)),
+ (-1));
if (!env_get("partitions")) {
fastboot_fail("partitions not set", response);
@@ -505,8 +527,9 @@ static void __maybe_unused oem_format(char *cmd_parameter,
char *response)
static void __maybe_unused oem_partconf(char *cmd_parameter, char *response)
{
char cmdbuf[32];
- const int mmc_dev = config_opt_enabled(CONFIG_FASTBOOT_FLASH_MMC,
- CONFIG_FASTBOOT_FLASH_MMC_DEV,
-1);
+ const int mmc_dev = CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC,
+
(CONFIG_VAL(FASTBOOT_FLASH_MMC_DEV)),
+ (-1));
if (!cmd_parameter) {
fastboot_fail("Expected command parameter", response);
@@ -531,8 +554,9 @@ static void __maybe_unused oem_partconf(char
*cmd_parameter, char *response)
static void __maybe_unused oem_bootbus(char *cmd_parameter, char *response)
{
char cmdbuf[32];
- const int mmc_dev = config_opt_enabled(CONFIG_FASTBOOT_FLASH_MMC,
- CONFIG_FASTBOOT_FLASH_MMC_DEV,
-1);
+ const int mmc_dev = CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC,
+
(CONFIG_VAL(FASTBOOT_FLASH_MMC_DEV)),
+ (-1));
if (!cmd_parameter) {
fastboot_fail("Expected command parameter", response);
diff --git a/drivers/fastboot/fb_common.c b/drivers/fastboot/fb_common.c
index 9c52e004588..bd8ba8824de 100644
--- a/drivers/fastboot/fb_common.c
+++ b/drivers/fastboot/fb_common.c
@@ -12,6 +12,7 @@
#include <bcb.h>
#include <command.h>
+#include <cpu_func.h>
#include <env.h>
#include <fastboot.h>
#include <net.h>
@@ -89,6 +90,14 @@ void fastboot_okay(const char *reason, char *response)
* which sets whatever flag your board specific Android bootloader flow
* requires in order to re-enter the bootloader.
*/
+#ifdef CONFIG_XPL_BUILD
+int __weak fastboot_set_reboot_flag(enum fastboot_reboot_reason reason)
+{
+ (void)reason;
+
+ return -EOPNOTSUPP;
+}
+#else
int __weak fastboot_set_reboot_flag(enum fastboot_reboot_reason reason)
{
int ret;
@@ -127,6 +136,7 @@ out:
bcb_reset();
return ret;
}
+#endif
/**
* fastboot_get_progress_callback() - Return progress callback
@@ -138,6 +148,7 @@ void (*fastboot_get_progress_callback(void))(const char *)
return fastboot_progress_callback;
}
+#ifndef CONFIG_XPL_BUILD
/**
* fastboot_boot() - Execute fastboot boot command
*
@@ -175,6 +186,7 @@ void fastboot_boot(void)
do_reset(NULL, 0, 0, NULL);
}
}
+#endif /* !CONFIG_XPL_BUILD */
/**
* fastboot_handle_boot() - Shared implementation of system reaction to
@@ -189,12 +201,14 @@ void fastboot_handle_boot(int command, bool success)
return;
switch (command) {
+#ifndef CONFIG_XPL_BUILD
case FASTBOOT_COMMAND_BOOT:
fastboot_boot();
#if CONFIG_IS_ENABLED(NET_LEGACY)
net_set_state(NETLOOP_SUCCESS);
#endif
break;
+#endif
case FASTBOOT_COMMAND_CONTINUE:
#if CONFIG_IS_ENABLED(NET_LEGACY)
@@ -206,7 +220,14 @@ void fastboot_handle_boot(int command, bool success)
case FASTBOOT_COMMAND_REBOOT_BOOTLOADER:
case FASTBOOT_COMMAND_REBOOT_FASTBOOTD:
case FASTBOOT_COMMAND_REBOOT_RECOVERY:
+#ifdef CONFIG_XPL_BUILD
+#if CONFIG_IS_ENABLED(FASTBOOT_REBOOT)
+ /* SPL may omit CMDLINE, so use the platform reset hook
directly. */
+ reset_cpu();
+#endif
+#else
do_reset(NULL, 0, 0, NULL);
+#endif
break;
}
}
@@ -234,8 +255,8 @@ void fastboot_set_progress_callback(void (*progress)(const
char *msg))
*/
void fastboot_init(void *buf_addr, u32 buf_size)
{
-#if IS_ENABLED(CONFIG_FASTBOOT_FLASH_BLOCK)
- if (!strcmp(CONFIG_FASTBOOT_FLASH_BLOCK_INTERFACE_NAME, "mmc"))
+#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_BLOCK)
+ if (!strcmp(CONFIG_VAL(FASTBOOT_FLASH_BLOCK_INTERFACE_NAME), "mmc"))
printf("Warning: the fastboot block backend features are limited,
consider using the MMC backend\n");
#endif
diff --git a/drivers/fastboot/fb_getvar.c b/drivers/fastboot/fb_getvar.c
index e8aa0e09aa6..608a62299af 100644
--- a/drivers/fastboot/fb_getvar.c
+++ b/drivers/fastboot/fb_getvar.c
@@ -70,19 +70,19 @@ static const struct {
.variable = "current-slot",
.dispatch = getvar_current_slot,
.list = true
-#if IS_ENABLED(CONFIG_FASTBOOT_FLASH)
+#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
}, {
.variable = "has-slot",
.dispatch = getvar_has_slot,
.list = false
#endif
-#if IS_ENABLED(CONFIG_FASTBOOT_FLASH_MMC)
+#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
}, {
.variable = "partition-type",
.dispatch = getvar_partition_type,
.list = false
#endif
-#if IS_ENABLED(CONFIG_FASTBOOT_FLASH)
+#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
}, {
.variable = "partition-size",
.dispatch = getvar_partition_size,
@@ -116,21 +116,21 @@ static int getvar_get_part_info(const char *part_name,
char *response,
struct disk_partition disk_part;
struct part_info *part_info;
- if (IS_ENABLED(CONFIG_FASTBOOT_FLASH_BLOCK)) {
+ if (CONFIG_IS_ENABLED(FASTBOOT_FLASH_BLOCK)) {
r = fastboot_block_get_part_info(part_name, &dev_desc,
&disk_part,
response);
if (r >= 0 && size)
*size = disk_part.size * disk_part.blksz;
- } else if (IS_ENABLED(CONFIG_FASTBOOT_FLASH_MMC)) {
+ } else if (CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)) {
r = fastboot_mmc_get_part_info(part_name, &dev_desc, &disk_part,
response);
if (r >= 0 && size)
*size = disk_part.size * disk_part.blksz;
- } else if (IS_ENABLED(CONFIG_FASTBOOT_FLASH_NAND)) {
+ } else if (CONFIG_IS_ENABLED(FASTBOOT_FLASH_NAND)) {
r = fastboot_nand_get_part_info(part_name, &part_info,
response);
if (r >= 0 && size)
*size = part_info->size;
- } else if (IS_ENABLED(CONFIG_FASTBOOT_FLASH_SPI)) {
+ } else if (CONFIG_IS_ENABLED(FASTBOOT_FLASH_SPI)) {
r = fastboot_spi_flash_get_part_info(part_name, &disk_part,
response);
if (r >= 0 && size)
@@ -240,12 +240,17 @@ static void __maybe_unused getvar_partition_type(char
*part_name, char *response
r = fastboot_mmc_get_part_info(part_name, &dev_desc, &part_info,
response);
if (r >= 0) {
+#ifdef CONFIG_XPL_BUILD
+ /* SPL does not pull in filesystem probing just for this
getvar. */
+ fastboot_okay("raw", response);
+#else
r = fs_set_blk_dev_with_part(dev_desc, r);
if (r < 0)
/* If we don't know then just default to raw */
fastboot_okay("raw", response);
else
fastboot_okay(fs_get_type_name(), response);
+#endif
}
}
diff --git a/drivers/fastboot/fb_mmc.c b/drivers/fastboot/fb_mmc.c
index 9bc782ccd02..ae33e35365b 100644
--- a/drivers/fastboot/fb_mmc.c
+++ b/drivers/fastboot/fb_mmc.c
@@ -75,7 +75,7 @@ static int do_get_part_info(struct blk_desc **dev_desc, const
char *name,
int ret;
/* First try partition names on the default device */
- *dev_desc = blk_get_dev("mmc", CONFIG_FASTBOOT_FLASH_MMC_DEV);
+ *dev_desc = blk_get_dev("mmc", CONFIG_VAL(FASTBOOT_FLASH_MMC_DEV));
if (*dev_desc) {
ret = part_get_info_by_name(*dev_desc, name, info);
if (ret >= 0)
@@ -111,7 +111,7 @@ static int part_get_info_by_name_or_alias(struct blk_desc
**dev_desc,
return do_get_part_info(dev_desc, name, info);
}
-#ifdef CONFIG_FASTBOOT_MMC_BOOT_SUPPORT
+#if CONFIG_IS_ENABLED(FASTBOOT_MMC_BOOT_SUPPORT)
static void fb_mmc_boot_ops(struct blk_desc *dev_desc, void *buffer,
int hwpart, u32 buff_sz, char *response)
{
@@ -130,7 +130,7 @@ static void fb_mmc_boot_ops(struct blk_desc *dev_desc, void
*buffer,
}
#endif
-#ifdef CONFIG_ANDROID_BOOT_IMAGE
+#if CONFIG_IS_ENABLED(ANDROID_BOOT_IMAGE)
/**
* Read Android boot image header from boot partition.
*
@@ -346,7 +346,7 @@ int fastboot_mmc_get_part_info(const char *part_name,
static struct blk_desc *fastboot_mmc_get_dev(char *response)
{
struct blk_desc *ret = blk_get_dev("mmc",
- CONFIG_FASTBOOT_FLASH_MMC_DEV);
+ CONFIG_VAL(FASTBOOT_FLASH_MMC_DEV));
if (!ret || ret->type == DEV_TYPE_UNKNOWN) {
pr_err("invalid mmc device\n");
@@ -370,15 +370,15 @@ void fastboot_mmc_flash_write(const char *cmd, void
*download_buffer,
struct blk_desc *dev_desc;
struct disk_partition info = {0};
-#ifdef CONFIG_FASTBOOT_MMC_BOOT_SUPPORT
- if (strcmp(cmd, CONFIG_FASTBOOT_MMC_BOOT1_NAME) == 0) {
+#if CONFIG_IS_ENABLED(FASTBOOT_MMC_BOOT_SUPPORT)
+ if (!strcmp(cmd, CONFIG_VAL(FASTBOOT_MMC_BOOT1_NAME))) {
dev_desc = fastboot_mmc_get_dev(response);
if (dev_desc)
fb_mmc_boot_ops(dev_desc, download_buffer, 1,
download_bytes, response);
return;
}
- if (strcmp(cmd, CONFIG_FASTBOOT_MMC_BOOT2_NAME) == 0) {
+ if (!strcmp(cmd, CONFIG_VAL(FASTBOOT_MMC_BOOT2_NAME))) {
dev_desc = fastboot_mmc_get_dev(response);
if (dev_desc)
fb_mmc_boot_ops(dev_desc, download_buffer, 2,
@@ -388,7 +388,7 @@ void fastboot_mmc_flash_write(const char *cmd, void
*download_buffer,
#endif
#if CONFIG_IS_ENABLED(EFI_PARTITION)
- if (strcmp(cmd, CONFIG_FASTBOOT_GPT_NAME) == 0) {
+ if (!strcmp(cmd, CONFIG_VAL(FASTBOOT_GPT_NAME))) {
dev_desc = fastboot_mmc_get_dev(response);
if (!dev_desc)
return;
@@ -415,7 +415,7 @@ void fastboot_mmc_flash_write(const char *cmd, void
*download_buffer,
#endif
#if CONFIG_IS_ENABLED(DOS_PARTITION)
- if (strcmp(cmd, CONFIG_FASTBOOT_MBR_NAME) == 0) {
+ if (!strcmp(cmd, CONFIG_VAL(FASTBOOT_MBR_NAME))) {
dev_desc = fastboot_mmc_get_dev(response);
if (!dev_desc)
return;
@@ -440,7 +440,7 @@ void fastboot_mmc_flash_write(const char *cmd, void
*download_buffer,
}
#endif
-#ifdef CONFIG_ANDROID_BOOT_IMAGE
+#if CONFIG_IS_ENABLED(ANDROID_BOOT_IMAGE)
if (strncasecmp(cmd, "zimage", 6) == 0) {
dev_desc = fastboot_mmc_get_dev(response);
if (dev_desc)
@@ -450,8 +450,8 @@ void fastboot_mmc_flash_write(const char *cmd, void
*download_buffer,
}
#endif
-#if IS_ENABLED(CONFIG_FASTBOOT_MMC_USER_SUPPORT)
- if (strcmp(cmd, CONFIG_FASTBOOT_MMC_USER_NAME) == 0) {
+#if CONFIG_IS_ENABLED(FASTBOOT_MMC_USER_SUPPORT)
+ if (!strcmp(cmd, CONFIG_VAL(FASTBOOT_MMC_USER_NAME))) {
dev_desc = fastboot_mmc_get_dev(response);
if (!dev_desc)
return;
@@ -485,17 +485,17 @@ void fastboot_mmc_erase(const char *cmd, char *response)
{
struct blk_desc *dev_desc;
struct disk_partition info;
- struct mmc *mmc = find_mmc_device(CONFIG_FASTBOOT_FLASH_MMC_DEV);
+ struct mmc *mmc = find_mmc_device(CONFIG_VAL(FASTBOOT_FLASH_MMC_DEV));
-#ifdef CONFIG_FASTBOOT_MMC_BOOT_SUPPORT
- if (strcmp(cmd, CONFIG_FASTBOOT_MMC_BOOT1_NAME) == 0) {
+#if CONFIG_IS_ENABLED(FASTBOOT_MMC_BOOT_SUPPORT)
+ if (!strcmp(cmd, CONFIG_VAL(FASTBOOT_MMC_BOOT1_NAME))) {
/* erase EMMC boot1 */
dev_desc = fastboot_mmc_get_dev(response);
if (dev_desc)
fb_mmc_boot_ops(dev_desc, NULL, 1, 0, response);
return;
}
- if (strcmp(cmd, CONFIG_FASTBOOT_MMC_BOOT2_NAME) == 0) {
+ if (!strcmp(cmd, CONFIG_VAL(FASTBOOT_MMC_BOOT2_NAME))) {
/* erase EMMC boot2 */
dev_desc = fastboot_mmc_get_dev(response);
if (dev_desc)
@@ -504,8 +504,8 @@ void fastboot_mmc_erase(const char *cmd, char *response)
}
#endif
-#ifdef CONFIG_FASTBOOT_MMC_USER_SUPPORT
- if (strcmp(cmd, CONFIG_FASTBOOT_MMC_USER_NAME) == 0) {
+#if CONFIG_IS_ENABLED(FASTBOOT_MMC_USER_SUPPORT)
+ if (!strcmp(cmd, CONFIG_VAL(FASTBOOT_MMC_USER_NAME))) {
/* erase EMMC userdata */
dev_desc = fastboot_mmc_get_dev(response);
if (!dev_desc)
diff --git a/drivers/fastboot/fb_usb.c b/drivers/fastboot/fb_usb.c
new file mode 100644
index 00000000000..b6637c49fd8
--- /dev/null
+++ b/drivers/fastboot/fb_usb.c
@@ -0,0 +1,68 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2008 - 2009 Windriver, <www.windriver.com>
+ * Author: Tom Rix <[email protected]>
+ *
+ * (C) Copyright 2014 Linaro, Ltd.
+ * Rob Herring <[email protected]>
+ */
+
+#include <console.h>
+#include <fastboot.h>
+#include <g_dnl.h>
+#include <usb.h>
+#include <u-boot/schedule.h>
+#include <linux/errno.h>
+#include <linux/printk.h>
+
+int fastboot_usb_start(int controller_index, void *buf_addr, u32 buf_size)
+{
+ struct udevice *udc;
+ int ret;
+
+ ret = udc_device_get_by_index(controller_index, &udc);
+ if (ret) {
+ pr_err("USB init failed: %d\n", ret);
+ return ret;
+ }
+
+ fastboot_init(buf_addr, buf_size);
+ g_dnl_clear_detach();
+
+ ret = g_dnl_register("usb_dnl_fastboot");
+ if (ret)
+ goto err_put;
+
+ if (!g_dnl_board_usb_cable_connected()) {
+ puts("\rUSB cable not detected.\n");
+ ret = -ENODEV;
+ goto err_unregister;
+ }
+
+ while (!g_dnl_detach()) {
+#ifndef CONFIG_XPL_BUILD
+ /* SPL callers own the session lifetime and may have no
console. */
+ if (IS_ENABLED(CONFIG_CMD_FASTBOOT_ABORT_KEYED)) {
+ if (tstc()) {
+ getchar();
+ puts("\rOperation aborted.\n");
+ break;
+ }
+ } else if (ctrlc()) {
+ break;
+ }
+#endif
+ schedule();
+ dm_usb_gadget_handle_interrupts(udc);
+ }
+
+ ret = 0;
+
+err_unregister:
+ g_dnl_unregister();
+ g_dnl_clear_detach();
+err_put:
+ udc_device_put(udc);
+
+ return ret;
+}
diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
index f2aebf4e480..87ec0cf6c40 100644
--- a/drivers/usb/gadget/Makefile
+++ b/drivers/usb/gadget/Makefile
@@ -10,6 +10,7 @@ obj-$(CONFIG_$(PHASE_)USB_ETH_RNDIS) += rndis.o
ifdef CONFIG_XPL_BUILD
obj-$(CONFIG_SPL_USB_GADGET) += g_dnl.o
obj-$(CONFIG_SPL_DFU) += f_dfu.o
+obj-$(CONFIG_SPL_FASTBOOT) += f_fastboot.o
obj-$(CONFIG_SPL_USB_SDP_SUPPORT) += f_sdp.o
endif
diff --git a/drivers/usb/gadget/f_fastboot.c b/drivers/usb/gadget/f_fastboot.c
index 8df0e3f331d..49cacde9db5 100644
--- a/drivers/usb/gadget/f_fastboot.c
+++ b/drivers/usb/gadget/f_fastboot.c
@@ -422,7 +422,7 @@ static int fastboot_tx_write_str(const char *buffer)
static void compl_do_reset(struct usb_ep *ep, struct usb_request *req)
{
g_dnl_unregister();
- do_reset(NULL, 0, 0, NULL);
+ fastboot_handle_boot(FASTBOOT_COMMAND_REBOOT, true);
}
static unsigned int rx_bytes_expected(struct usb_ep *ep)
@@ -490,11 +490,13 @@ static void do_exit_on_complete(struct usb_ep *ep, struct
usb_request *req)
g_dnl_trigger_detach();
}
+#ifndef CONFIG_XPL_BUILD
static void do_bootm_on_complete(struct usb_ep *ep, struct usb_request *req)
{
fastboot_boot();
do_exit_on_complete(ep, req);
}
+#endif
static int multiresponse_cmd = -1;
static void multiresponse_on_complete(struct usb_ep *ep, struct usb_request
*req)
@@ -560,7 +562,9 @@ static void rx_handler_command(struct usb_ep *ep, struct
usb_request *req)
if (!strncmp("OKAY", response, 4)) {
switch (cmd) {
case FASTBOOT_COMMAND_BOOT:
+#ifndef CONFIG_XPL_BUILD
fastboot_func->in_req->complete = do_bootm_on_complete;
+#endif
break;
case FASTBOOT_COMMAND_CONTINUE:
diff --git a/include/fastboot.h b/include/fastboot.h
index b106d617749..b7b661b9591 100644
--- a/include/fastboot.h
+++ b/include/fastboot.h
@@ -125,6 +125,16 @@ void fastboot_set_progress_callback(void (*progress)(const
char *msg));
*/
void fastboot_init(void *buf_addr, u32 buf_size);
+/**
+ * fastboot_usb_start() - run a USB fastboot session
+ *
+ * @controller_index: USB gadget controller index
+ * @buf_addr: Pointer to download buffer, or NULL for default
+ * @buf_size: Size of download buffer, or zero for default
+ * Return: 0 on success, or a negative error code
+ */
+int fastboot_usb_start(int controller_index, void *buf_addr, u32 buf_size);
+
/**
* fastboot_boot() - Execute fastboot boot command
*
diff --git a/lib/Kconfig b/lib/Kconfig
index 24e55ade4d3..07ee3c88fd3 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -205,6 +205,9 @@ config VPL_STRTO
config IMAGE_SPARSE
bool
+config SPL_IMAGE_SPARSE
+ bool
+
config IMAGE_SPARSE_FILLBUF_SIZE
hex "Android sparse image CHUNK_TYPE_FILL buffer size"
default 0x80000
@@ -213,6 +216,14 @@ config IMAGE_SPARSE_FILLBUF_SIZE
Set the size of the fill buffer used when processing CHUNK_TYPE_FILL
chunks.
+config SPL_IMAGE_SPARSE_FILLBUF_SIZE
+ hex "Android sparse image fill buffer size in SPL"
+ default 0x80000
+ depends on SPL_IMAGE_SPARSE
+ help
+ Set the size of the fill buffer used when processing CHUNK_TYPE_FILL
+ chunks in SPL.
+
config USE_PRIVATE_LIBGCC
bool "Use private libgcc"
depends on HAVE_PRIVATE_LIBGCC
diff --git a/lib/Makefile b/lib/Makefile
index 222378a8531..014fda82860 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -44,7 +44,6 @@ obj-$(CONFIG_GENERATE_SMBIOS_TABLE) += smbios.o
endif
obj-$(CONFIG_SMBIOS_PARSER) += smbios-parser.o
-obj-$(CONFIG_IMAGE_SPARSE) += image-sparse.o
obj-y += ldiv.o
obj-$(CONFIG_XXHASH) += xxhash.o
obj-y += net_utils.o
@@ -56,6 +55,8 @@ obj-y += list_sort.o
obj-$(CONFIG_PMBUS) += pmbus.o
endif
+obj-$(CONFIG_$(PHASE_)IMAGE_SPARSE) += image-sparse.o
+
obj-$(CONFIG_$(PHASE_)TPM) += tpm-common.o
ifeq ($(CONFIG_$(PHASE_)TPM),y)
obj-$(CONFIG_TPM) += tpm_api.o
diff --git a/lib/image-sparse.c b/lib/image-sparse.c
index 09225692e9b..48e5d8ee869 100644
--- a/lib/image-sparse.c
+++ b/lib/image-sparse.c
@@ -125,7 +125,7 @@ int write_sparse_image(struct sparse_storage *info,
int i;
int j;
- fill_buf_num_blks = CONFIG_IMAGE_SPARSE_FILLBUF_SIZE / info->blksz;
+ fill_buf_num_blks = CONFIG_VAL(IMAGE_SPARSE_FILLBUF_SIZE) / info->blksz;
/* Read and skip over sparse image header */
sparse_header = (sparse_header_t *)data;
---
base-commit: 96c308b8d2a6a1496c0a7366db9a7becf42d2454
change-id: 20260718-ccaione-upstream-spl-fastboot-14fa2b6b2b64
Best regards,
--
Carlo Caione <[email protected]>