From patchwork Tue Jun 23 00:27:53 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Roman Kovalivskyi X-Patchwork-Id: 242778 List-Id: U-Boot discussion From: roman.kovalivskyi at globallogic.com (Roman Kovalivskyi) Date: Tue, 23 Jun 2020 03:27:53 +0300 Subject: [PATCH v4 1/3] fastboot: Extend fastboot_set_reboot_flag with reboot reason In-Reply-To: References: Message-ID: Extend fastboot_set_reboot_flag arguments with reboot reason so that it could handle different reboot cases in future. Signed-off-by: Roman Kovalivskyi --- arch/arm/mach-meson/board-common.c | 6 +++++- arch/arm/mach-rockchip/board.c | 6 +++++- board/amazon/kc1/kc1.c | 6 +++++- board/lg/sniper/sniper.c | 6 +++++- board/ti/am57xx/board.c | 6 +++++- board/ti/dra7xx/evm.c | 6 +++++- drivers/fastboot/fb_command.c | 2 +- drivers/fastboot/fb_common.c | 2 +- include/fastboot.h | 10 +++++++++- 9 files changed, 41 insertions(+), 9 deletions(-) diff --git a/arch/arm/mach-meson/board-common.c b/arch/arm/mach-meson/board-common.c index 19e5bfd3660c..a1f08bb98c6f 100644 --- a/arch/arm/mach-meson/board-common.c +++ b/arch/arm/mach-meson/board-common.c @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -153,8 +154,11 @@ int board_late_init(void) #if CONFIG_IS_ENABLED(FASTBOOT) static unsigned int reboot_reason = REBOOT_REASON_NORMAL; -int fastboot_set_reboot_flag() +int fastboot_set_reboot_flag(enum fastboot_reboot_reason reason) { + if (reason != FASTBOOT_REBOOT_REASON_BOOTLOADER) + return -ENOTSUPP; + reboot_reason = REBOOT_REASON_BOOTLOADER; printf("Using reboot reason: 0x%x\n", reboot_reason); diff --git a/arch/arm/mach-rockchip/board.c b/arch/arm/mach-rockchip/board.c index 430c0cbf41e4..ba4da72b3910 100644 --- a/arch/arm/mach-rockchip/board.c +++ b/arch/arm/mach-rockchip/board.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -152,8 +153,11 @@ int board_usb_init(int index, enum usb_init_type init) #endif /* CONFIG_USB_GADGET */ #if CONFIG_IS_ENABLED(FASTBOOT) -int fastboot_set_reboot_flag(void) +int fastboot_set_reboot_flag(enum fastboot_reboot_reason reason) { + if (reason != FASTBOOT_REBOOT_REASON_BOOTLOADER) + return -ENOTSUPP; + printf("Setting reboot to fastboot flag ...\n"); /* Set boot mode to fastboot */ writel(BOOT_FASTBOOT, CONFIG_ROCKCHIP_BOOT_MODE_REG); diff --git a/board/amazon/kc1/kc1.c b/board/amazon/kc1/kc1.c index fb1828ff44da..445980f16e62 100644 --- a/board/amazon/kc1/kc1.c +++ b/board/amazon/kc1/kc1.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -163,8 +164,11 @@ void get_board_serial(struct tag_serialnr *serialnr) omap_die_id_get_board_serial(serialnr); } -int fastboot_set_reboot_flag(void) +int fastboot_set_reboot_flag(enum fastboot_reboot_reason reason) { + if (reason != FASTBOOT_REBOOT_REASON_BOOTLOADER) + return -ENOTSUPP; + return omap_reboot_mode_store("b"); } diff --git a/board/lg/sniper/sniper.c b/board/lg/sniper/sniper.c index 2825eccc035a..99b832fe601b 100644 --- a/board/lg/sniper/sniper.c +++ b/board/lg/sniper/sniper.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -175,8 +176,11 @@ void reset_misc(void) omap_reboot_mode_store(reboot_mode); } -int fastboot_set_reboot_flag(void) +int fastboot_set_reboot_flag(enum fastboot_reboot_reason reason) { + if (reason != FASTBOOT_REBOOT_REASON_BOOTLOADER) + return -ENOTSUPP; + return omap_reboot_mode_store("b"); } diff --git a/board/ti/am57xx/board.c b/board/ti/am57xx/board.c index 8720eb87a55d..49afd3bc927b 100644 --- a/board/ti/am57xx/board.c +++ b/board/ti/am57xx/board.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -1169,8 +1170,11 @@ int board_fit_config_name_match(const char *name) #endif #if CONFIG_IS_ENABLED(FASTBOOT) && !CONFIG_IS_ENABLED(ENV_IS_NOWHERE) -int fastboot_set_reboot_flag(void) +int fastboot_set_reboot_flag(enum fastboot_reboot_reason reason) { + if (reason != FASTBOOT_REBOOT_REASON_BOOTLOADER) + return -ENOTSUPP; + printf("Setting reboot to fastboot flag ...\n"); env_set("dofastboot", "1"); env_save(); diff --git a/board/ti/dra7xx/evm.c b/board/ti/dra7xx/evm.c index acf7ff169170..3bc40c721146 100644 --- a/board/ti/dra7xx/evm.c +++ b/board/ti/dra7xx/evm.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -1050,8 +1051,11 @@ int board_fit_config_name_match(const char *name) #endif #if CONFIG_IS_ENABLED(FASTBOOT) && !CONFIG_IS_ENABLED(ENV_IS_NOWHERE) -int fastboot_set_reboot_flag(void) +int fastboot_set_reboot_flag(enum fastboot_reboot_reason reason) { + if (reason != FASTBOOT_REBOOT_REASON_BOOTLOADER) + return -ENOTSUPP; + printf("Setting reboot to fastboot flag ...\n"); env_set("dofastboot", "1"); env_save(); diff --git a/drivers/fastboot/fb_command.c b/drivers/fastboot/fb_command.c index 49f6a61c3745..8ce5d32fb2ba 100644 --- a/drivers/fastboot/fb_command.c +++ b/drivers/fastboot/fb_command.c @@ -307,7 +307,7 @@ static void erase(char *cmd_parameter, char *response) */ static void reboot_bootloader(char *cmd_parameter, char *response) { - if (fastboot_set_reboot_flag()) + if (fastboot_set_reboot_flag(FASTBOOT_REBOOT_REASON_BOOTLOADER)) fastboot_fail("Cannot set reboot flag", response); else fastboot_okay(NULL, response); diff --git a/drivers/fastboot/fb_common.c b/drivers/fastboot/fb_common.c index c3735a44af74..736ce1cd024f 100644 --- a/drivers/fastboot/fb_common.c +++ b/drivers/fastboot/fb_common.c @@ -88,7 +88,7 @@ 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. */ -int __weak fastboot_set_reboot_flag(void) +int __weak fastboot_set_reboot_flag(enum fastboot_reboot_reason reason) { return -ENOSYS; } diff --git a/include/fastboot.h b/include/fastboot.h index 1933b1d98e3b..14f4c68868d8 100644 --- a/include/fastboot.h +++ b/include/fastboot.h @@ -40,6 +40,14 @@ enum { FASTBOOT_COMMAND_COUNT }; +/** + * Reboot reasons + */ +enum fastboot_reboot_reason { + FASTBOOT_REBOOT_REASON_BOOTLOADER, + FASTBOOT_REBOOT_REASONS_COUNT +}; + /** * fastboot_response() - Writes a response of the form "$tag$reason". * @@ -77,7 +85,7 @@ 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. */ -int fastboot_set_reboot_flag(void); +int fastboot_set_reboot_flag(enum fastboot_reboot_reason reason); /** * fastboot_set_progress_callback() - set progress callback From patchwork Tue Jun 23 00:27:54 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Roman Kovalivskyi X-Patchwork-Id: 242777 List-Id: U-Boot discussion From: roman.kovalivskyi at globallogic.com (Roman Kovalivskyi) Date: Tue, 23 Jun 2020 03:27:54 +0300 Subject: [PATCH v4 2/3] fastboot: Add support for 'reboot fastboot' command In-Reply-To: References: Message-ID: <867ccae1d22fc46c0af79fc503fe9ca09780e308.1592871839.git.roman.kovalivskyi@globallogic.com> Android 10 adds support for dynamic partitions and in order to support this userspace fastboot must be used[1]. New tool fastbootd is included into recovery. Userspace fastboot works from recovery and is launched if: 1) - Dynamic partitioning is enabled 2) - Boot control block has 'boot-fastboot' value into command field The bootloader is expected to load and boot into the recovery image upon seeing boot-fastboot in the BCB command. Recovery then parses the BCB message and switches to fastbootd mode[2]. Please note that boot script is expected to handle 'boot-fastboot' command in BCB and load into recovery mode. Bootloader must support 'reboot fastboot' command which should reboot device into userspace fastboot to accomodate those changes[3]. Another command that bootloader must support[3] is 'reboot recovery'. This command should simply reboot device into recovery mode. [1] - https://source.android.com/devices/bootloader/fastbootd [2] - https://source.android.com/devices/bootloader/fastbootd#unified_fastboot_and_recovery [3] - https://source.android.com/devices/bootloader/fastbootd#modifications_to_the_bootloader Signed-off-by: Roman Kovalivskyi Signed-off-by: Roman Stratiienko Change-Id: I9d2bdc9a6f6f31ea98572fe155e1cc8341e9af76 --- drivers/fastboot/fb_command.c | 38 +++++++++++++++++++++++++++++++++ drivers/usb/gadget/f_fastboot.c | 2 ++ include/fastboot.h | 4 ++++ net/fastboot.c | 2 ++ 4 files changed, 46 insertions(+) diff --git a/drivers/fastboot/fb_command.c b/drivers/fastboot/fb_command.c index 8ce5d32fb2ba..d3c578672dc6 100644 --- a/drivers/fastboot/fb_command.c +++ b/drivers/fastboot/fb_command.c @@ -37,6 +37,8 @@ static void flash(char *, char *); static void erase(char *, char *); #endif static void reboot_bootloader(char *, char *); +static void reboot_fastbootd(char *, char *); +static void reboot_recovery(char *, char *); #if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_FORMAT) static void oem_format(char *, char *); #endif @@ -79,6 +81,14 @@ static const struct { .command = "reboot-bootloader", .dispatch = reboot_bootloader }, + [FASTBOOT_COMMAND_REBOOT_FASTBOOTD] = { + .command = "reboot-fastboot", + .dispatch = reboot_fastbootd + }, + [FASTBOOT_COMMAND_REBOOT_RECOVERY] = { + .command = "reboot-recovery", + .dispatch = reboot_recovery + }, [FASTBOOT_COMMAND_SET_ACTIVE] = { .command = "set_active", .dispatch = okay @@ -313,6 +323,34 @@ static void reboot_bootloader(char *cmd_parameter, char *response) fastboot_okay(NULL, response); } +/** + * reboot_fastbootd() - Sets reboot fastboot flag. + * + * @cmd_parameter: Pointer to command parameter + * @response: Pointer to fastboot response buffer + */ +static void reboot_fastbootd(char *cmd_parameter, char *response) +{ + if (fastboot_set_reboot_flag(FASTBOOT_REBOOT_REASON_FASTBOOTD)) + fastboot_fail("Cannot set fastboot flag", response); + else + fastboot_okay(NULL, response); +} + +/** + * reboot_recovery() - Sets reboot recovery flag. + * + * @cmd_parameter: Pointer to command parameter + * @response: Pointer to fastboot response buffer + */ +static void reboot_recovery(char *cmd_parameter, char *response) +{ + if (fastboot_set_reboot_flag(FASTBOOT_REBOOT_REASON_RECOVERY)) + fastboot_fail("Cannot set recovery flag", response); + else + fastboot_okay(NULL, response); +} + #if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_FORMAT) /** * oem_format() - Execute the OEM format command diff --git a/drivers/usb/gadget/f_fastboot.c b/drivers/usb/gadget/f_fastboot.c index 384c0f6f6e27..30f7a52087fc 100644 --- a/drivers/usb/gadget/f_fastboot.c +++ b/drivers/usb/gadget/f_fastboot.c @@ -455,6 +455,8 @@ static void rx_handler_command(struct usb_ep *ep, struct usb_request *req) case FASTBOOT_COMMAND_REBOOT: case FASTBOOT_COMMAND_REBOOT_BOOTLOADER: + case FASTBOOT_COMMAND_REBOOT_FASTBOOTD: + case FASTBOOT_COMMAND_REBOOT_RECOVERY: fastboot_func->in_req->complete = compl_do_reset; break; } diff --git a/include/fastboot.h b/include/fastboot.h index 14f4c68868d8..b86b508e69fd 100644 --- a/include/fastboot.h +++ b/include/fastboot.h @@ -32,6 +32,8 @@ enum { FASTBOOT_COMMAND_CONTINUE, FASTBOOT_COMMAND_REBOOT, FASTBOOT_COMMAND_REBOOT_BOOTLOADER, + FASTBOOT_COMMAND_REBOOT_FASTBOOTD, + FASTBOOT_COMMAND_REBOOT_RECOVERY, FASTBOOT_COMMAND_SET_ACTIVE, #if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_FORMAT) FASTBOOT_COMMAND_OEM_FORMAT, @@ -45,6 +47,8 @@ enum { */ enum fastboot_reboot_reason { FASTBOOT_REBOOT_REASON_BOOTLOADER, + FASTBOOT_REBOOT_REASON_FASTBOOTD, + FASTBOOT_REBOOT_REASON_RECOVERY, FASTBOOT_REBOOT_REASONS_COUNT }; diff --git a/net/fastboot.c b/net/fastboot.c index 0c57fb9947df..7e7a601b9fe6 100644 --- a/net/fastboot.c +++ b/net/fastboot.c @@ -227,6 +227,8 @@ static void fastboot_send(struct fastboot_header header, char *fastboot_data, case FASTBOOT_COMMAND_REBOOT: case FASTBOOT_COMMAND_REBOOT_BOOTLOADER: + case FASTBOOT_COMMAND_REBOOT_FASTBOOTD: + case FASTBOOT_COMMAND_REBOOT_RECOVERY: do_reset(NULL, 0, 0, NULL); break; } From patchwork Tue Jun 23 00:27:55 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Roman Kovalivskyi X-Patchwork-Id: 242779 List-Id: U-Boot discussion From: roman.kovalivskyi at globallogic.com (Roman Kovalivskyi) Date: Tue, 23 Jun 2020 03:27:55 +0300 Subject: [PATCH v4 3/3] fastboot: Add default fastboot_set_reboot_flag implementation In-Reply-To: References: Message-ID: Default implementation of fastboot_set_reboot_flag function that depends on "bcb" commands could be used in general case if there are no need to make any platform-specific implementation, otherwise it could be disabled via Kconfig option FASTBOOT_USE_BCB_SET_REBOOT_FLAG. Please note that FASTBOOT_USE_BCB_SET_REBOOT_FLAG is mutually exclusive with some platforms which already have their own implementation of this function. Signed-off-by: Roman Kovalivskyi --- drivers/fastboot/Kconfig | 12 +++++++++ drivers/fastboot/Makefile | 1 + drivers/fastboot/fb_bcb_impl.c | 48 ++++++++++++++++++++++++++++++++++ 3 files changed, 61 insertions(+) create mode 100644 drivers/fastboot/fb_bcb_impl.c diff --git a/drivers/fastboot/Kconfig b/drivers/fastboot/Kconfig index d4436dfc9173..4352ba67a713 100644 --- a/drivers/fastboot/Kconfig +++ b/drivers/fastboot/Kconfig @@ -165,6 +165,18 @@ config FASTBOOT_CMD_OEM_FORMAT relies on the env variable partitions to contain the list of partitions as required by the gpt command. +config FASTBOOT_USE_BCB_SET_REBOOT_FLAG + bool "Use BCB by fastboot to set boot reason" + depends on CMD_BCB && !ARCH_MESON && !ARCH_ROCKCHIP && !TARGET_KC1 && \ + !TARGET_SNIPER && !TARGET_AM57XX_EVM && !TARGET_DRA7XX_EVM + default y + help + Fastboot could implement setting of reboot reason in a generic fashion + via BCB commands. BCB commands are able to write reboot reason into + command field of boot control block. In general case it is sufficient + implementation if your platform supports BCB commands and doesn't + require any specific reboot reason handling. + endif # FASTBOOT endmenu diff --git a/drivers/fastboot/Makefile b/drivers/fastboot/Makefile index 048af5aa8234..2b2c390fe4de 100644 --- a/drivers/fastboot/Makefile +++ b/drivers/fastboot/Makefile @@ -5,3 +5,4 @@ obj-y += fb_getvar.o obj-y += fb_command.o obj-$(CONFIG_FASTBOOT_FLASH_MMC) += fb_mmc.o obj-$(CONFIG_FASTBOOT_FLASH_NAND) += fb_nand.o +obj-$(CONFIG_FASTBOOT_USE_BCB_SET_REBOOT_FLAG) += fb_bcb_impl.o diff --git a/drivers/fastboot/fb_bcb_impl.c b/drivers/fastboot/fb_bcb_impl.c new file mode 100644 index 000000000000..a5ae94e2e357 --- /dev/null +++ b/drivers/fastboot/fb_bcb_impl.c @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2020 GlobalLogic. + * Roman Kovalivskyi + */ + +#include +#include + +/** + * fastboot_set_reboot_flag() - Set flag to indicate reboot-bootloader + * + * Set flag which indicates that we should reboot into the bootloader + * following the reboot that fastboot executes after this function. + * + * This function should be overridden in your board file with one + * which sets whatever flag your board specific Android bootloader flow + * requires in order to re-enter the bootloader. + */ +int fastboot_set_reboot_flag(enum fastboot_reboot_reason reason) +{ + static const char * const boot_cmds[] = { + "bootonce-bootloader", + "boot-fastboot", + "boot-recovery" + }; + + char cmd[32]; + + if (reason >= FASTBOOT_REBOOT_REASONS_COUNT) + return -EINVAL; + + snprintf(cmd, sizeof(cmd), "bcb load %d misc", + CONFIG_FASTBOOT_FLASH_MMC_DEV); + + if (run_command(cmd, 0)) + return -ENODEV; + + snprintf(cmd, sizeof(cmd), "bcb set command %s", boot_cmds[reason]); + + if (run_command(cmd, 0)) + return -ENOEXEC; + + if (run_command("bcb store", 0)) + return -EIO; + + return 0; +}