From: Sam Day <[email protected]> The weak symbol currently implements `fastboot reboot` support using the BCB. Nowadays, there's robust reboot-mode driver support which is ideal for this use-case.
Signed-off-by: Sam Day <[email protected]> --- drivers/fastboot/Kconfig | 7 ++++++ drivers/fastboot/Makefile | 1 + drivers/fastboot/fb_reboot_mode.c | 51 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+) diff --git a/drivers/fastboot/Kconfig b/drivers/fastboot/Kconfig index 90212fcf9ef..a1586e79c7e 100644 --- a/drivers/fastboot/Kconfig +++ b/drivers/fastboot/Kconfig @@ -108,6 +108,13 @@ config FASTBOOT_UUU_SUPPORT feature if you are using verified boot, as it will allow an attacker to bypass any restrictions you have in place. +config FASTBOOT_REBOOT_MODE + bool "Use reboot-mode for fastboot reboot commands" + depends on DM_REBOOT_MODE + help + Use a reboot-mode driver to implement fastboot reboot target flags + such as reboot-bootloader, reboot-fastboot and reboot-recovery. + choice prompt "Flash provider for FASTBOOT" depends on FASTBOOT_FLASH diff --git a/drivers/fastboot/Makefile b/drivers/fastboot/Makefile index a341af076d1..531e694f393 100644 --- a/drivers/fastboot/Makefile +++ b/drivers/fastboot/Makefile @@ -8,3 +8,4 @@ obj-$(CONFIG_FASTBOOT_FLASH_BLOCK) += fb_block.o 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_FASTBOOT_REBOOT_MODE) += fb_reboot_mode.o diff --git a/drivers/fastboot/fb_reboot_mode.c b/drivers/fastboot/fb_reboot_mode.c new file mode 100644 index 00000000000..abf4066f1f5 --- /dev/null +++ b/drivers/fastboot/fb_reboot_mode.c @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: GPL-2.0+ + +#include <dm.h> +#include <dm/uclass.h> +#include <errno.h> +#include <fastboot.h> +#include <reboot-mode/reboot-mode.h> +#include <linux/kernel.h> + +static int fastboot_set_reboot_mode(const char *mode) +{ + struct udevice *dev; + int ret = -ENOENT; + + uclass_foreach_dev_probe(UCLASS_REBOOT_MODE, dev) + { + ret = dm_reboot_mode_activate(dev, mode); + if (!ret || (ret != -ENOENT && ret != -ENOSYS)) + return ret; + } + + return ret; +} + +int fastboot_set_reboot_flag(enum fastboot_reboot_reason reason) +{ + static const char *const + reboot_modes[FASTBOOT_REBOOT_REASONS_COUNT][2] = { + [FASTBOOT_REBOOT_REASON_BOOTLOADER] = { "bootloader", + NULL }, + [FASTBOOT_REBOOT_REASON_FASTBOOTD] = { "fastboot", + "bootloader" }, + [FASTBOOT_REBOOT_REASON_RECOVERY] = { "recovery", + NULL }, + }; + int i, ret; + + if (reason >= FASTBOOT_REBOOT_REASONS_COUNT) + return -EINVAL; + + for (i = 0; i < ARRAY_SIZE(reboot_modes[reason]); i++) { + if (!reboot_modes[reason][i]) + continue; + + ret = fastboot_set_reboot_mode(reboot_modes[reason][i]); + if (!ret || (ret != -ENOENT && ret != -ENOSYS)) + return ret; + } + + return -ENOENT; +} -- 2.54.0

