From 81c9431f562bbeb2b6b1efb0f99e023ed818dc5d Mon Sep 17 00:00:00 2001 From: zhang sanshan Date: Wed, 10 May 2017 10:14:27 +0800 Subject: MA-9375 [Android IMX] uboot: enable BCB and bootctrl * Add API to read\write MISC partition. * get the boot mode from BCB command when boot up. * get the boot up tactics from bootctrl. Change-Id: Icbba6340e10983dddc1b04804ecc012a3a3c57d0 Signed-off-by: zhang sanshan --- arch/arm/cpu/armv7/mx6/soc.c | 52 --- arch/arm/cpu/armv7/mx7/soc.c | 56 --- arch/arm/cpu/armv7/mx7ulp/soc.c | 32 +- board/freescale/common/Makefile | 2 +- board/freescale/common/recovery.c | 78 ----- board/freescale/common/recovery_keypad.c | 60 ++++ board/freescale/common/recovery_keypad.h | 13 + board/freescale/mx6qsabreauto/mx6qsabreauto.c | 93 +---- board/freescale/mx6sabresd/mx6sabresd.c | 89 +---- board/freescale/mx6slevk/mx6slevk.c | 76 +--- board/freescale/mx6sxsabreauto/mx6sxsabreauto.c | 82 +---- board/freescale/mx6sxsabresd/mx6sxsabresd.c | 73 +--- board/freescale/mx6ul_14x14_evk/mx6ul_14x14_evk.c | 83 +---- board/freescale/mx7dsabresd/mx7dsabresd.c | 59 +--- board/freescale/mx7ulp_evk/mx7ulp_evk.c | 8 +- cmd/read.c | 4 +- common/board_r.c | 2 +- common/image-android.c | 11 + drivers/usb/gadget/Makefile | 2 + drivers/usb/gadget/bcb.c | 170 +++++++++ drivers/usb/gadget/bcb.h | 58 ++++ drivers/usb/gadget/bootctrl.c | 405 ++++++++++++++++++++++ drivers/usb/gadget/bootctrl.h | 37 ++ drivers/usb/gadget/command.c | 120 +++++++ drivers/usb/gadget/f_fastboot.c | 385 +++++++++++++------- include/common.h | 4 + include/fsl_fastboot.h | 48 ++- include/recovery.h | 4 +- 28 files changed, 1211 insertions(+), 895 deletions(-) delete mode 100644 board/freescale/common/recovery.c create mode 100644 board/freescale/common/recovery_keypad.c create mode 100644 board/freescale/common/recovery_keypad.h create mode 100644 drivers/usb/gadget/bcb.c create mode 100644 drivers/usb/gadget/bcb.h create mode 100644 drivers/usb/gadget/bootctrl.c create mode 100644 drivers/usb/gadget/bootctrl.h create mode 100644 drivers/usb/gadget/command.c diff --git a/arch/arm/cpu/armv7/mx6/soc.c b/arch/arm/cpu/armv7/mx6/soc.c index be34786..f2a16e2 100644 --- a/arch/arm/cpu/armv7/mx6/soc.c +++ b/arch/arm/cpu/armv7/mx6/soc.c @@ -1055,55 +1055,3 @@ void finish_anatop_bypass(void) } #endif -#ifdef CONFIG_FSL_FASTBOOT - -#ifdef CONFIG_ANDROID_RECOVERY -#define ANDROID_RECOVERY_BOOT (1 << 7) -/* check if the recovery bit is set by kernel, it can be set by kernel - * issue a command '# reboot recovery' */ -int recovery_check_and_clean_flag(void) -{ - int flag_set = 0; - u32 reg; - reg = readl(SNVS_BASE_ADDR + SNVS_LPGPR); - - flag_set = !!(reg & ANDROID_RECOVERY_BOOT); - printf("check_and_clean: reg %x, flag_set %d\n", reg, flag_set); - /* clean it in case looping infinite here.... */ - if (flag_set) { - reg &= ~ANDROID_RECOVERY_BOOT; - writel(reg, SNVS_BASE_ADDR + SNVS_LPGPR); - } - - return flag_set; -} -#endif /*CONFIG_ANDROID_RECOVERY*/ - -#define ANDROID_FASTBOOT_BOOT (1 << 8) -/* check if the recovery bit is set by kernel, it can be set by kernel - * issue a command '# reboot fastboot' */ -int fastboot_check_and_clean_flag(void) -{ - int flag_set = 0; - u32 reg; - - reg = readl(SNVS_BASE_ADDR + SNVS_LPGPR); - - flag_set = !!(reg & ANDROID_FASTBOOT_BOOT); - - /* clean it in case looping infinite here.... */ - if (flag_set) { - reg &= ~ANDROID_FASTBOOT_BOOT; - writel(reg, SNVS_BASE_ADDR + SNVS_LPGPR); - } - - return flag_set; -} - -void fastboot_enable_flag(void) -{ - setbits_le32(SNVS_BASE_ADDR + SNVS_LPGPR, - ANDROID_FASTBOOT_BOOT); -} -#endif /*CONFIG_FSL_FASTBOOT*/ - diff --git a/arch/arm/cpu/armv7/mx7/soc.c b/arch/arm/cpu/armv7/mx7/soc.c index 89a339c..9e85bf1 100644 --- a/arch/arm/cpu/armv7/mx7/soc.c +++ b/arch/arm/cpu/armv7/mx7/soc.c @@ -507,59 +507,3 @@ void reset_cpu(ulong addr) } } - -#ifdef CONFIG_FSL_FASTBOOT - -#ifdef CONFIG_ANDROID_RECOVERY -#define ANDROID_RECOVERY_BOOT (1 << 7) -/* - * check if the recovery bit is set by kernel, it can be set by kernel - * issue a command '# reboot recovery' - */ -int recovery_check_and_clean_flag(void) -{ - int flag_set = 0; - u32 reg; - reg = readl(SNVS_BASE_ADDR + SNVS_LPGPR); - - flag_set = !!(reg & ANDROID_RECOVERY_BOOT); - printf("check_and_clean: reg %x, flag_set %d\n", reg, flag_set); - /* clean it in case looping infinite here.... */ - if (flag_set) { - reg &= ~ANDROID_RECOVERY_BOOT; - writel(reg, SNVS_BASE_ADDR + SNVS_LPGPR); - } - - return flag_set; -} -#endif /*CONFIG_ANDROID_RECOVERY*/ - -#define ANDROID_FASTBOOT_BOOT (1 << 8) -/* - * check if the recovery bit is set by kernel, it can be set by kernel - * issue a command '# reboot fastboot' - */ -int fastboot_check_and_clean_flag(void) -{ - int flag_set = 0; - u32 reg; - - reg = readl(SNVS_BASE_ADDR + SNVS_LPGPR); - - flag_set = !!(reg & ANDROID_FASTBOOT_BOOT); - - /* clean it in case looping infinite here.... */ - if (flag_set) { - reg &= ~ANDROID_FASTBOOT_BOOT; - writel(reg, SNVS_BASE_ADDR + SNVS_LPGPR); - } - - return flag_set; -} - -void fastboot_enable_flag(void) -{ - setbits_le32(SNVS_BASE_ADDR + SNVS_LPGPR, - ANDROID_FASTBOOT_BOOT); -} -#endif /*CONFIG_FSL_FASTBOOT*/ diff --git a/arch/arm/cpu/armv7/mx7ulp/soc.c b/arch/arm/cpu/armv7/mx7ulp/soc.c index 1440c0f..2cd16c8 100644 --- a/arch/arm/cpu/armv7/mx7ulp/soc.c +++ b/arch/arm/cpu/armv7/mx7ulp/soc.c @@ -375,35 +375,5 @@ void get_board_serial(struct tag_serialnr *serialnr) serialnr->low = (fuse->cfg0 & 0xFFFF) + ((fuse->cfg1 & 0xFFFF) << 16); serialnr->high = (fuse->cfg2 & 0xFFFF) + ((fuse->cfg3 & 0xFFFF) << 16); } -#endif -#ifdef CONFIG_ANDROID_RECOVERY -/* - * check if the recovery filed is set by kernel, it can be set by kernel - * issue a command '# reboot recovery' - */ -int recovery_check_and_clean_flag(void) -{ -/* - * TODO: will implement this part after porting BCB - */ - return 0; -} -#endif /*CONFIG_ANDROID_RECOVERY*/ -/* - * check if the recovery field is set by kernel, it can be set by kernel - * issue a command '# reboot fastboot' - */ -int fastboot_check_and_clean_flag(void) -{ -/* - * TODO: will implement this part after porting BCB - */ - return 0; -} -void fastboot_enable_flag(void) -{ -/* - * TODO: will implement this part after porting BCB - */ -} +#endif /*CONFIG_SERIAL_TAG*/ #endif /*CONFIG_FSL_FASTBOOT*/ diff --git a/board/freescale/common/Makefile b/board/freescale/common/Makefile index 66cdf0c..21830be 100644 --- a/board/freescale/common/Makefile +++ b/board/freescale/common/Makefile @@ -66,7 +66,7 @@ obj-$(CONFIG_DM_PMIC_PFUZE100) += pfuze_dm.o obj-$(CONFIG_MXC_EPDC) += epdc_setup.o obj-y += mmc.o ifdef CONFIG_FSL_FASTBOOT -obj-${CONFIG_ANDROID_RECOVERY} += recovery.o +obj-${CONFIG_ANDROID_RECOVERY} += recovery_keypad.o endif obj-$(CONFIG_LS102XA_STREAM_ID) += ls102xa_stream_id.o diff --git a/board/freescale/common/recovery.c b/board/freescale/common/recovery.c deleted file mode 100644 index 396bc73..0000000 --- a/board/freescale/common/recovery.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (C) 2010-2016 Freescale Semiconductor, Inc. All Rights Reserved. - * - * SPDX-License-Identifier: GPL-2.0+ - */ -#include -#include -#include -#ifdef CONFIG_MXC_KPD -#include -#endif -#include - -#ifdef CONFIG_MXC_KPD -#define PRESSED_VOL_DOWN 0x01 -#define PRESSED_POWER 0x02 -#define RECOVERY_KEY_MASK (PRESSED_VOL_DOWN | PRESSED_POWER) - -inline int test_key(int value, struct kpp_key_info *ki) -{ - return (ki->val == value) && (ki->evt == KDepress); -} - -int check_key_pressing(void) -{ - struct kpp_key_info *key_info = NULL; - int state = 0, keys, i; - - int ret = 0; - - mxc_kpp_init(); - /* due to glitch suppression circuit, - wait sometime to let all keys scanned. */ - udelay(1000); - keys = mxc_kpp_getc(&key_info); - - printf("Detecting VOL_DOWN+POWER key for recovery(%d:%d) ...\n", - keys, keys ? key_info->val : 0); - if (keys > 1) { - for (i = 0; i < keys; i++) { - if (test_key(CONFIG_POWER_KEY, &key_info[i])) - state |= PRESSED_POWER; - else if (test_key(CONFIG_VOL_DOWN_KEY, &key_info[i])) - state |= PRESSED_VOL_DOWN; - } - } - if ((state & RECOVERY_KEY_MASK) == RECOVERY_KEY_MASK) - ret = 1; - if (key_info) - free(key_info); - return ret; -} -#else -/* If not using mxc keypad, currently we will detect power key on board */ -int check_key_pressing(void) -{ - return 0; -} -#endif - -void setup_recovery_env(void) -{ - board_recovery_setup(); -} - -/* export to lib_arm/board.c */ -void check_recovery_mode(void) -{ - if (check_key_pressing()) { - puts("Fastboot: Recovery key pressing got!\n"); - setup_recovery_env(); - } else if (check_recovery_cmd_file()) { - puts("Fastboot: Recovery command file found!\n"); - setup_recovery_env(); - } else { - puts("Fastboot: Normal\n"); - } -} diff --git a/board/freescale/common/recovery_keypad.c b/board/freescale/common/recovery_keypad.c new file mode 100644 index 0000000..f73f88b --- /dev/null +++ b/board/freescale/common/recovery_keypad.c @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2010-2016 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2017 NXP + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include +#include +#include +#ifdef CONFIG_MXC_KPD +#include +#endif +#include + +#ifdef CONFIG_MXC_KPD +#define PRESSED_VOL_DOWN 0x01 +#define PRESSED_POWER 0x02 +#define RECOVERY_KEY_MASK (PRESSED_VOL_DOWN | PRESSED_POWER) + +inline int test_key(int value, struct kpp_key_info *ki) +{ + return (ki->val == value) && (ki->evt == KDepress); +} + +int is_recovery_keypad_pressing(void) +{ + struct kpp_key_info *key_info = NULL; + int state = 0, keys, i; + + int ret = 0; + + mxc_kpp_init(); + /* due to glitch suppression circuit, + wait sometime to let all keys scanned. */ + udelay(1000); + keys = mxc_kpp_getc(&key_info); + + printf("Detecting VOL_DOWN+POWER key for recovery(%d:%d) ...\n", + keys, keys ? key_info->val : 0); + if (keys > 1) { + for (i = 0; i < keys; i++) { + if (test_key(CONFIG_POWER_KEY, &key_info[i])) + state |= PRESSED_POWER; + else if (test_key(CONFIG_VOL_DOWN_KEY, &key_info[i])) + state |= PRESSED_VOL_DOWN; + } + } + if ((state & RECOVERY_KEY_MASK) == RECOVERY_KEY_MASK) + ret = 1; + if (key_info) + free(key_info); + return ret; +} +#else +/* If not using mxc keypad, currently we will detect power key on board */ +int is_recovery_keypad_pressing(void) +{ + return 0; +} +#endif diff --git a/board/freescale/common/recovery_keypad.h b/board/freescale/common/recovery_keypad.h new file mode 100644 index 0000000..d315cea --- /dev/null +++ b/board/freescale/common/recovery_keypad.h @@ -0,0 +1,13 @@ +/* + * Copyright (C) 2016 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2017 NXP + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __RECOVERY_KEYPAD_H_ +#define __RECOVERY_KEYPAD_H_ + +int is_recovery_keypad_pressing(void); + +#endif diff --git a/board/freescale/mx6qsabreauto/mx6qsabreauto.c b/board/freescale/mx6qsabreauto/mx6qsabreauto.c index 159d9f3..1ea4185 100644 --- a/board/freescale/mx6qsabreauto/mx6qsabreauto.c +++ b/board/freescale/mx6qsabreauto/mx6qsabreauto.c @@ -1,5 +1,6 @@ /* * Copyright (C) 2012-2016 Freescale Semiconductor, Inc. + * Copyright 2017 NXP * * Author: Fabio Estevam * @@ -1136,51 +1137,6 @@ int checkboard(void) } #ifdef CONFIG_FSL_FASTBOOT -void board_fastboot_setup(void) -{ - switch (get_boot_device()) { -#if defined(CONFIG_FASTBOOT_STORAGE_SATA) - case SATA_BOOT: - if (!getenv("fastboot_dev")) - setenv("fastboot_dev", "sata"); - if (!getenv("bootcmd")) - setenv("bootcmd", "boota sata"); - break; -#endif /*CONFIG_FASTBOOT_STORAGE_SATA*/ -#if defined(CONFIG_FASTBOOT_STORAGE_MMC) - case SD1_BOOT: - case MMC1_BOOT: - if (!getenv("fastboot_dev")) - setenv("fastboot_dev", "mmc0"); - if (!getenv("bootcmd")) - setenv("bootcmd", "boota mmc0"); - break; - case SD3_BOOT: - case MMC3_BOOT: - if (!getenv("fastboot_dev")) - setenv("fastboot_dev", "mmc1"); - if (!getenv("bootcmd")) - setenv("bootcmd", "boota mmc1"); - break; -#endif /*CONFIG_FASTBOOT_STORAGE_MMC*/ -#if defined(CONFIG_FASTBOOT_STORAGE_NAND) - case NAND_BOOT: - if (!getenv("fastboot_dev")) - setenv("fastboot_dev", "nand"); - if (!getenv("fbparts")) - setenv("fbparts", ANDROID_FASTBOOT_NAND_PARTS); - if (!getenv("bootcmd")) - setenv("bootcmd", - "nand read ${loadaddr} ${boot_nand_offset} " - "${boot_nand_size};boota ${loadaddr}"); - break; -#endif /*CONFIG_FASTBOOT_STORAGE_NAND*/ - default: - printf("unsupported boot devices\n"); - break; - } -} - #ifdef CONFIG_ANDROID_RECOVERY #define GPIO_VOL_DN_KEY IMX_GPIO_NR(5, 14) @@ -1188,12 +1144,9 @@ iomux_v3_cfg_t const recovery_key_pads[] = { (MX6_PAD_DISP0_DAT20__GPIO5_IO14 | MUX_PAD_CTRL(NO_PAD_CTRL)), }; -int check_recovery_cmd_file(void) +int is_recovery_key_pressing(void) { int button_pressed = 0; - int recovery_mode = 0; - - recovery_mode = recovery_check_and_clean_flag(); /* Check Recovery Combo Button press or not. */ imx_iomux_v3_setup_multiple_pads(recovery_key_pads, @@ -1207,49 +1160,9 @@ int check_recovery_cmd_file(void) printf("Recovery key pressed\n"); } - return recovery_mode || button_pressed; + return button_pressed; } -void board_recovery_setup(void) -{ - int bootdev = get_boot_device(); - - switch (bootdev) { -#if defined(CONFIG_FASTBOOT_STORAGE_SATA) - case SATA_BOOT: - if (!getenv("bootcmd_android_recovery")) - setenv("bootcmd_android_recovery", "boota sata recovery"); - break; -#endif /*CONFIG_FASTBOOT_STORAGE_SATA*/ -#if defined(CONFIG_FASTBOOT_STORAGE_MMC) - case SD1_BOOT: - case MMC1_BOOT: - if (!getenv("bootcmd_android_recovery")) - setenv("bootcmd_android_recovery", "boota mmc0 recovery"); - break; - case SD3_BOOT: - case MMC3_BOOT: - if (!getenv("bootcmd_android_recovery")) - setenv("bootcmd_android_recovery", "boota mmc1 recovery"); - break; -#endif /*CONFIG_FASTBOOT_STORAGE_MMC*/ -#if defined(CONFIG_FASTBOOT_STORAGE_NAND) - case NAND_BOOT: - if (!getenv("bootcmd_android_recovery")) - setenv("bootcmd_android_recovery", - "nand read ${loadaddr} ${recovery_nand_offset} " - "${recovery_nand_size};boota ${loadaddr}"); - break; -#endif /*CONFIG_FASTBOOT_STORAGE_NAND*/ - default: - printf("Unsupported bootup device for recovery: dev: %d\n", - bootdev); - return; - } - - printf("setup env for recovery..\n"); - setenv("bootcmd", "run bootcmd_android_recovery"); -} #endif /*CONFIG_ANDROID_RECOVERY*/ #endif /*CONFIG_FSL_FASTBOOT*/ diff --git a/board/freescale/mx6sabresd/mx6sabresd.c b/board/freescale/mx6sabresd/mx6sabresd.c index b655347..2a09e2f 100644 --- a/board/freescale/mx6sabresd/mx6sabresd.c +++ b/board/freescale/mx6sabresd/mx6sabresd.c @@ -1353,47 +1353,6 @@ int checkboard(void) } #ifdef CONFIG_FSL_FASTBOOT - -void board_fastboot_setup(void) -{ - switch (get_boot_device()) { -#if defined(CONFIG_FASTBOOT_STORAGE_SATA) - case SATA_BOOT: - if (!getenv("fastboot_dev")) - setenv("fastboot_dev", "sata"); - if (!getenv("bootcmd")) - setenv("bootcmd", "boota sata"); - break; -#endif /*CONFIG_FASTBOOT_STORAGE_SATA*/ -#if defined(CONFIG_FASTBOOT_STORAGE_MMC) - case SD2_BOOT: - case MMC2_BOOT: - if (!getenv("fastboot_dev")) - setenv("fastboot_dev", "mmc0"); - if (!getenv("bootcmd")) - setenv("bootcmd", "boota mmc0"); - break; - case SD3_BOOT: - case MMC3_BOOT: - if (!getenv("fastboot_dev")) - setenv("fastboot_dev", "mmc1"); - if (!getenv("bootcmd")) - setenv("bootcmd", "boota mmc1"); - break; - case MMC4_BOOT: - if (!getenv("fastboot_dev")) - setenv("fastboot_dev", "mmc2"); - if (!getenv("bootcmd")) - setenv("bootcmd", "boota mmc2"); - break; -#endif /*CONFIG_FASTBOOT_STORAGE_MMC*/ - default: - printf("unsupported boot devices\n"); - break; - } - -} - #ifdef CONFIG_ANDROID_RECOVERY #define GPIO_VOL_DN_KEY IMX_GPIO_NR(1, 5) @@ -1401,12 +1360,9 @@ iomux_v3_cfg_t const recovery_key_pads[] = { (MX6_PAD_GPIO_5__GPIO1_IO05 | MUX_PAD_CTRL(NO_PAD_CTRL)), }; -int check_recovery_cmd_file(void) +int is_recovery_key_pressing(void) { int button_pressed = 0; - int recovery_mode = 0; - - recovery_mode = recovery_check_and_clean_flag(); /* Check Recovery Combo Button press or not. */ imx_iomux_v3_setup_multiple_pads(recovery_key_pads, @@ -1420,48 +1376,7 @@ int check_recovery_cmd_file(void) printf("Recovery key pressed\n"); } - return recovery_mode || button_pressed; -} - -void board_recovery_setup(void) -{ - int bootdev = get_boot_device(); - - switch (bootdev) { -#if defined(CONFIG_FASTBOOT_STORAGE_SATA) - case SATA_BOOT: - if (!getenv("bootcmd_android_recovery")) - setenv("bootcmd_android_recovery", - "boota sata recovery"); - break; -#endif /*CONFIG_FASTBOOT_STORAGE_SATA*/ -#if defined(CONFIG_FASTBOOT_STORAGE_MMC) - case SD2_BOOT: - case MMC2_BOOT: - if (!getenv("bootcmd_android_recovery")) - setenv("bootcmd_android_recovery", - "boota mmc0 recovery"); - break; - case SD3_BOOT: - case MMC3_BOOT: - if (!getenv("bootcmd_android_recovery")) - setenv("bootcmd_android_recovery", - "boota mmc1 recovery"); - break; - case MMC4_BOOT: - if (!getenv("bootcmd_android_recovery")) - setenv("bootcmd_android_recovery", - "boota mmc2 recovery"); - break; -#endif /*CONFIG_FASTBOOT_STORAGE_MMC*/ - default: - printf("Unsupported bootup device for recovery: dev: %d\n", - bootdev); - return; - } - - printf("setup env for recovery..\n"); - setenv("bootcmd", "run bootcmd_android_recovery"); + return button_pressed; } #endif /*CONFIG_ANDROID_RECOVERY*/ diff --git a/board/freescale/mx6slevk/mx6slevk.c b/board/freescale/mx6slevk/mx6slevk.c index 33e7ef6..7a11f13 100644 --- a/board/freescale/mx6slevk/mx6slevk.c +++ b/board/freescale/mx6slevk/mx6slevk.c @@ -1,5 +1,6 @@ /* * Copyright (C) 2013 - 2016 Freescale Semiconductor, Inc. + * Copyright 2017 NXP * * Author: Fabio Estevam * @@ -37,6 +38,7 @@ #ifdef CONFIG_FSL_FASTBOOT #include #ifdef CONFIG_ANDROID_RECOVERY +#include "../common/recovery_keypad.h" #include #endif #endif /*CONFIG_FSL_FASTBOOT*/ @@ -915,83 +917,13 @@ int setup_mxc_kpd(void) #endif /*CONFIG_MXC_KPD*/ #ifdef CONFIG_FSL_FASTBOOT -void board_fastboot_setup(void) -{ - switch (get_boot_device()) { -#if defined(CONFIG_FASTBOOT_STORAGE_MMC) - case SD1_BOOT: - case MMC1_BOOT: - if (!getenv("fastboot_dev")) - setenv("fastboot_dev", "mmc0"); - if (!getenv("bootcmd")) - setenv("bootcmd", "boota mmc0"); - break; - case SD2_BOOT: - case MMC2_BOOT: - if (!getenv("fastboot_dev")) - setenv("fastboot_dev", "mmc1"); - if (!getenv("bootcmd")) - setenv("bootcmd", "boota mmc1"); - break; - case SD3_BOOT: - case MMC3_BOOT: - if (!getenv("fastboot_dev")) - setenv("fastboot_dev", "mmc2"); - if (!getenv("bootcmd")) - setenv("bootcmd", "boota mmc2"); - break; -#endif /*CONFIG_FASTBOOT_STORAGE_MMC*/ - default: - printf("unsupported boot devices\n"); - break; - } - -} - #ifdef CONFIG_ANDROID_RECOVERY -int check_recovery_cmd_file(void) +int is_recovery_key_pressing(void) { - return recovery_check_and_clean_flag(); -} - -void board_recovery_setup(void) -{ - int bootdev = get_boot_device(); - - /*current uboot BSP only supports USDHC2*/ - switch (bootdev) { -#if defined(CONFIG_FASTBOOT_STORAGE_MMC) - case SD1_BOOT: - case MMC1_BOOT: - if (!getenv("bootcmd_android_recovery")) - setenv("bootcmd_android_recovery", - "boota mmc0 recovery"); - break; - case SD2_BOOT: - case MMC2_BOOT: - if (!getenv("bootcmd_android_recovery")) - setenv("bootcmd_android_recovery", - "boota mmc1 recovery"); - break; - case SD3_BOOT: - case MMC3_BOOT: - if (!getenv("bootcmd_android_recovery")) - setenv("bootcmd_android_recovery", - "boota mmc2 recovery"); - break; -#endif /*CONFIG_FASTBOOT_STORAGE_MMC*/ - default: - printf("Unsupported bootup device for recovery: dev: %d\n", - bootdev); - return; - } - - printf("setup env for recovery..\n"); - setenv("bootcmd", "run bootcmd_android_recovery"); + return is_recovery_keypad_pressing(); } #endif /*CONFIG_ANDROID_RECOVERY*/ - #endif /*CONFIG_FSL_FASTBOOT*/ diff --git a/board/freescale/mx6sxsabreauto/mx6sxsabreauto.c b/board/freescale/mx6sxsabreauto/mx6sxsabreauto.c index 648dbf0..71c51eb 100644 --- a/board/freescale/mx6sxsabreauto/mx6sxsabreauto.c +++ b/board/freescale/mx6sxsabreauto/mx6sxsabreauto.c @@ -1,5 +1,6 @@ /* * Copyright (C) 2014-2016 Freescale Semiconductor, Inc. + * Copyright 2017 nxp * * Author: Ye Li * @@ -32,6 +33,7 @@ #include #ifdef CONFIG_ANDROID_RECOVERY #include +#include "../common/recovery_keypad.h" #endif #endif /*CONFIG_FSL_FASTBOOT*/ @@ -557,88 +559,12 @@ int checkboard(void) } #ifdef CONFIG_FSL_FASTBOOT -void board_fastboot_setup(void) -{ - switch (get_boot_device()) { -#if defined(CONFIG_FASTBOOT_STORAGE_MMC) - case SD3_BOOT: - case MMC3_BOOT: - if (!getenv("fastboot_dev")) - setenv("fastboot_dev", "mmc0"); - if (!getenv("bootcmd")) - setenv("bootcmd", "boota mmc0"); - break; - case SD4_BOOT: - case MMC4_BOOT: - if (!getenv("fastboot_dev")) - setenv("fastboot_dev", "mmc1"); - if (!getenv("bootcmd")) - setenv("bootcmd", "boota mmc1"); - break; -#endif /*CONFIG_FASTBOOT_STORAGE_MMC*/ -#if defined(CONFIG_FASTBOOT_STORAGE_NAND) - case NAND_BOOT: - if (!getenv("fastboot_dev")) - setenv("fastboot_dev", "nand"); - if (!getenv("fbparts")) - setenv("fbparts", ANDROID_FASTBOOT_NAND_PARTS); - if (!getenv("bootcmd")) - setenv("bootcmd", - "nand read ${loadaddr} ${boot_nand_offset} " - "${boot_nand_size};boota ${loadaddr}"); - break; -#endif /*CONFIG_FASTBOOT_STORAGE_NAND*/ - - default: - printf("unsupported boot devices\n"); - break; - } -} - #ifdef CONFIG_ANDROID_RECOVERY -int check_recovery_cmd_file(void) +int is_recovery_key_pressing(void) { - int recovery_mode = 0; - - recovery_mode = recovery_check_and_clean_flag(); - - return recovery_mode; + return is_recovery_keypad_pressing(); } -void board_recovery_setup(void) -{ - int bootdev = get_boot_device(); - - switch (bootdev) { -#if defined(CONFIG_FASTBOOT_STORAGE_MMC) - case SD3_BOOT: - case MMC3_BOOT: - if (!getenv("bootcmd_android_recovery")) - setenv("bootcmd_android_recovery", "boota mmc0 recovery"); - break; - case SD4_BOOT: - case MMC4_BOOT: - if (!getenv("bootcmd_android_recovery")) - setenv("bootcmd_android_recovery", "boota mmc1 recovery"); - break; -#endif /*CONFIG_FASTBOOT_STORAGE_MMC*/ -#if defined(CONFIG_FASTBOOT_STORAGE_NAND) - case NAND_BOOT: - if (!getenv("bootcmd_android_recovery")) - setenv("bootcmd_android_recovery", - "nand read ${loadaddr} ${recovery_nand_offset} " - "${recovery_nand_size};boota ${loadaddr}"); - break; -#endif /*CONFIG_FASTBOOT_STORAGE_NAND*/ - default: - printf("Unsupported bootup device for recovery: dev: %d\n", - bootdev); - return; - } - - printf("setup env for recovery..\n"); - setenv("bootcmd", "run bootcmd_android_recovery"); -} #endif /*CONFIG_ANDROID_RECOVERY*/ #endif /*CONFIG_FSL_FASTBOOT*/ diff --git a/board/freescale/mx6sxsabresd/mx6sxsabresd.c b/board/freescale/mx6sxsabresd/mx6sxsabresd.c index f99048a..608bd1d 100644 --- a/board/freescale/mx6sxsabresd/mx6sxsabresd.c +++ b/board/freescale/mx6sxsabresd/mx6sxsabresd.c @@ -1,5 +1,6 @@ /* * Copyright (C) 2014-2016 Freescale Semiconductor, Inc. + * Copyright 2017 NXP * * Author: Fabio Estevam * @@ -977,38 +978,6 @@ int checkboard(void) } #ifdef CONFIG_FSL_FASTBOOT -void board_fastboot_setup(void) -{ - switch (get_boot_device()) { -#if defined(CONFIG_FASTBOOT_STORAGE_MMC) - case SD2_BOOT: - case MMC2_BOOT: - if (!getenv("fastboot_dev")) - setenv("fastboot_dev", "mmc0"); - if (!getenv("bootcmd")) - setenv("bootcmd", "boota mmc0"); - break; - case SD3_BOOT: - case MMC3_BOOT: - if (!getenv("fastboot_dev")) - setenv("fastboot_dev", "mmc1"); - if (!getenv("bootcmd")) - setenv("bootcmd", "boota mmc1"); - break; - case SD4_BOOT: - case MMC4_BOOT: - if (!getenv("fastboot_dev")) - setenv("fastboot_dev", "mmc2"); - if (!getenv("bootcmd")) - setenv("bootcmd", "boota mmc2"); - break; -#endif /*CONFIG_FASTBOOT_STORAGE_MMC*/ - default: - printf("unsupported boot devices\n"); - break; - } -} - #ifdef CONFIG_ANDROID_RECOVERY #define GPIO_VOL_DN_KEY IMX_GPIO_NR(1, 19) @@ -1016,12 +985,9 @@ iomux_v3_cfg_t const recovery_key_pads[] = { (MX6_PAD_CSI_DATA05__GPIO1_IO_19 | MUX_PAD_CTRL(BUTTON_PAD_CTRL)), }; -int check_recovery_cmd_file(void) +int is_recovery_key_pressing(void) { int button_pressed = 0; - int recovery_mode = 0; - - recovery_mode = recovery_check_and_clean_flag(); /* Check Recovery Combo Button press or not. */ imx_iomux_v3_setup_multiple_pads(recovery_key_pads, @@ -1035,42 +1001,9 @@ int check_recovery_cmd_file(void) printf("Recovery key pressed\n"); } - return recovery_mode || button_pressed; -} - -void board_recovery_setup(void) -{ - int bootdev = get_boot_device(); - - switch (bootdev) { -#if defined(CONFIG_FASTBOOT_STORAGE_MMC) - case SD2_BOOT: - case MMC2_BOOT: - if (!getenv("bootcmd_android_recovery")) - setenv("bootcmd_android_recovery", "boota mmc0 recovery"); - break; - case SD3_BOOT: - case MMC3_BOOT: - if (!getenv("bootcmd_android_recovery")) - setenv("bootcmd_android_recovery", "boota mmc1 recovery"); - break; - case SD4_BOOT: - case MMC4_BOOT: - if (!getenv("bootcmd_android_recovery")) - setenv("bootcmd_android_recovery", "boota mmc2 recovery"); - break; -#endif /*CONFIG_FASTBOOT_STORAGE_MMC*/ - default: - printf("Unsupported bootup device for recovery: dev: %d\n", - bootdev); - return; - } - - printf("setup env for recovery..\n"); - setenv("bootcmd", "run bootcmd_android_recovery"); + return button_pressed; } #endif /*CONFIG_ANDROID_RECOVERY*/ - #endif /*CONFIG_FSL_FASTBOOT*/ #ifdef CONFIG_SPL_BUILD diff --git a/board/freescale/mx6ul_14x14_evk/mx6ul_14x14_evk.c b/board/freescale/mx6ul_14x14_evk/mx6ul_14x14_evk.c index 8b707b6..325b6df 100644 --- a/board/freescale/mx6ul_14x14_evk/mx6ul_14x14_evk.c +++ b/board/freescale/mx6ul_14x14_evk/mx6ul_14x14_evk.c @@ -1,5 +1,6 @@ /* * Copyright (C) 2015-2016 Freescale Semiconductor, Inc. + * Copyright 2017 NXP * * SPDX-License-Identifier: GPL-2.0+ */ @@ -928,89 +929,13 @@ int checkboard(void) } #ifdef CONFIG_FSL_FASTBOOT -void board_fastboot_setup(void) -{ - switch (get_boot_device()) { -#if defined(CONFIG_FASTBOOT_STORAGE_MMC) - case SD1_BOOT: - case MMC1_BOOT: - if (!getenv("fastboot_dev")) - setenv("fastboot_dev", "mmc0"); - if (!getenv("bootcmd")) - setenv("bootcmd", "boota mmc0"); - break; - case SD2_BOOT: - case MMC2_BOOT: - if (!getenv("fastboot_dev")) - setenv("fastboot_dev", "mmc1"); - if (!getenv("bootcmd")) - setenv("bootcmd", "boota mmc1"); - break; -#endif /*CONFIG_FASTBOOT_STORAGE_MMC*/ -#if defined(CONFIG_FASTBOOT_STORAGE_NAND) - case NAND_BOOT: - if (!getenv("fastboot_dev")) - setenv("fastboot_dev", "nand"); - if (!getenv("fbparts")) - setenv("fbparts", ANDROID_FASTBOOT_NAND_PARTS); - if (!getenv("bootcmd")) - setenv("bootcmd", - "nand read ${loadaddr} ${boot_nand_offset} " - "${boot_nand_size};boota ${loadaddr}"); - break; -#endif /*CONFIG_FASTBOOT_STORAGE_NAND*/ - - default: - printf("unsupported boot devices\n"); - break; - } -} - #ifdef CONFIG_ANDROID_RECOVERY -int check_recovery_cmd_file(void) +int is_recovery_key_pressing(void) { - int recovery_mode = 0; - - recovery_mode = recovery_check_and_clean_flag(); - - return recovery_mode; + /* No key defined for this board */ + return 0; } -void board_recovery_setup(void) -{ - int bootdev = get_boot_device(); - - switch (bootdev) { -#if defined(CONFIG_FASTBOOT_STORAGE_MMC) - case SD1_BOOT: - case MMC1_BOOT: - if (!getenv("bootcmd_android_recovery")) - setenv("bootcmd_android_recovery", "boota mmc0 recovery"); - break; - case SD2_BOOT: - case MMC2_BOOT: - if (!getenv("bootcmd_android_recovery")) - setenv("bootcmd_android_recovery", "boota mmc1 recovery"); - break; -#endif /*CONFIG_FASTBOOT_STORAGE_MMC*/ -#if defined(CONFIG_FASTBOOT_STORAGE_NAND) - case NAND_BOOT: - if (!getenv("bootcmd_android_recovery")) - setenv("bootcmd_android_recovery", - "nand read ${loadaddr} ${recovery_nand_offset} " - "${recovery_nand_size};boota ${loadaddr}"); - break; -#endif /*CONFIG_FASTBOOT_STORAGE_NAND*/ - - default: - printf("Unsupported bootup device for recovery: dev: %d\n", - bootdev); - return; - } - - printf("setup env for recovery..\n"); - setenv("bootcmd", "run bootcmd_android_recovery"); -} #endif /*CONFIG_ANDROID_RECOVERY*/ #endif /*CONFIG_FSL_FASTBOOT*/ diff --git a/board/freescale/mx7dsabresd/mx7dsabresd.c b/board/freescale/mx7dsabresd/mx7dsabresd.c index 216f5b3..b97de36 100644 --- a/board/freescale/mx7dsabresd/mx7dsabresd.c +++ b/board/freescale/mx7dsabresd/mx7dsabresd.c @@ -689,31 +689,6 @@ int checkboard(void) } #ifdef CONFIG_FSL_FASTBOOT -void board_fastboot_setup(void) -{ - switch (get_boot_device()) { -#if defined(CONFIG_FASTBOOT_STORAGE_MMC) - case SD1_BOOT: - case MMC1_BOOT: - if (!getenv("fastboot_dev")) - setenv("fastboot_dev", "mmc0"); - if (!getenv("bootcmd")) - setenv("bootcmd", "boota mmc0"); - break; - case SD3_BOOT: - case MMC3_BOOT: - if (!getenv("fastboot_dev")) - setenv("fastboot_dev", "mmc1"); - if (!getenv("bootcmd")) - setenv("bootcmd", "boota mmc1"); - break; -#endif /*CONFIG_FASTBOOT_STORAGE_MMC*/ - default: - printf("unsupported boot devices\n"); - break; - } -} - #ifdef CONFIG_ANDROID_RECOVERY /* Use S3 button for recovery key */ @@ -722,12 +697,9 @@ iomux_v3_cfg_t const recovery_key_pads[] = { (MX7D_PAD_SD2_WP__GPIO5_IO10 | MUX_PAD_CTRL(BUTTON_PAD_CTRL)), }; -int check_recovery_cmd_file(void) +int is_recovery_key_pressing(void) { int button_pressed = 0; - int recovery_mode = 0; - - recovery_mode = recovery_check_and_clean_flag(); /* Check Recovery Combo Button press or not. */ imx_iomux_v3_setup_multiple_pads(recovery_key_pads, @@ -741,35 +713,8 @@ int check_recovery_cmd_file(void) printf("Recovery key pressed\n"); } - return recovery_mode || button_pressed; + return button_pressed; } -void board_recovery_setup(void) -{ - int bootdev = get_boot_device(); - - switch (bootdev) { -#if defined(CONFIG_FASTBOOT_STORAGE_MMC) - case SD1_BOOT: - case MMC1_BOOT: - if (!getenv("bootcmd_android_recovery")) - setenv("bootcmd_android_recovery", "boota mmc0 recovery"); - break; - case SD3_BOOT: - case MMC3_BOOT: - if (!getenv("bootcmd_android_recovery")) - setenv("bootcmd_android_recovery", "boota mmc1 recovery"); - break; -#endif /*CONFIG_FASTBOOT_STORAGE_MMC*/ - default: - printf("Unsupported bootup device for recovery: dev: %d\n", - bootdev); - return; - } - - printf("setup env for recovery..\n"); - setenv("bootcmd", "run bootcmd_android_recovery"); -} #endif /*CONFIG_ANDROID_RECOVERY*/ - #endif /*CONFIG_FSL_FASTBOOT*/ diff --git a/board/freescale/mx7ulp_evk/mx7ulp_evk.c b/board/freescale/mx7ulp_evk/mx7ulp_evk.c index a7ceb91..a35f724 100644 --- a/board/freescale/mx7ulp_evk/mx7ulp_evk.c +++ b/board/freescale/mx7ulp_evk/mx7ulp_evk.c @@ -1,5 +1,6 @@ /* * Copyright (C) 2016 Freescale Semiconductor, Inc. + * Copyright 2017 NXP * * SPDX-License-Identifier: GPL-2.0+ */ @@ -233,11 +234,10 @@ void board_fastboot_setup(void) } #ifdef CONFIG_ANDROID_RECOVERY -int check_recovery_cmd_file(void) +int is_recovery_key_pressing(void) { - int recovery_mode = 0; - recovery_mode = recovery_check_and_clean_flag(); - return recovery_mode; + /* TODO: uboot can get the key event from M4 core*/ + return 0; } void board_recovery_setup(void) diff --git a/cmd/read.c b/cmd/read.c index ecf9254..caabf1f 100644 --- a/cmd/read.c +++ b/cmd/read.c @@ -12,7 +12,7 @@ #include #include -int do_read(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +int do_raw_read(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { char *ep; struct blk_desc *dev_desc = NULL; @@ -75,7 +75,7 @@ int do_read(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) } U_BOOT_CMD( - read, 6, 0, do_read, + read, 6, 0, do_raw_read, "Load binary data from a partition", " addr blk# cnt" ); diff --git a/common/board_r.c b/common/board_r.c index 014dbff..a69bc3f 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -731,7 +731,7 @@ static int initr_fastboot_setup(void) static int initr_check_fastboot(void) { - check_fastboot(); + fastboot_run_bootmode(); return 0; } #endif diff --git a/common/image-android.c b/common/image-android.c index de5e97c..4f1408b 100644 --- a/common/image-android.c +++ b/common/image-android.c @@ -19,6 +19,12 @@ static char andr_tmp_str[ANDR_BOOT_ARGS_SIZE + 1]; +#ifdef CONFIG_FSL_BOOTCTL +#include +#include +#include "../drivers/usb/gadget/bootctrl.h" +#endif + static ulong android_image_get_kernel_addr(const struct andr_img_hdr *hdr) { /* @@ -125,6 +131,11 @@ int android_image_get_kernel(const struct andr_img_hdr *hdr, int verify, } else printf("boot device type is incorrect.\n"); +#ifdef CONFIG_FSL_BOOTCTL + char suffixStr[64]; + sprintf(suffixStr, " androidboot.slot_suffix=%s", get_slot_suffix()); + strcat(commandline, suffixStr); +#endif setenv("bootargs", commandline); if (os_data) { diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile index 0fbbb7c..6431d8a 100644 --- a/drivers/usb/gadget/Makefile +++ b/drivers/usb/gadget/Makefile @@ -28,6 +28,8 @@ obj-$(CONFIG_USB_FUNCTION_THOR) += f_thor.o obj-$(CONFIG_USB_FUNCTION_DFU) += f_dfu.o obj-$(CONFIG_USB_FUNCTION_MASS_STORAGE) += f_mass_storage.o obj-$(CONFIG_USB_FUNCTION_FASTBOOT) += f_fastboot.o +obj-$(CONFIG_FSL_BOOTCTL) += bootctrl.o +obj-$(CONFIG_BCB_SUPPORT) += command.o bcb.o endif endif ifdef CONFIG_USB_ETHER diff --git a/drivers/usb/gadget/bcb.c b/drivers/usb/gadget/bcb.c new file mode 100644 index 0000000..159f929 --- /dev/null +++ b/drivers/usb/gadget/bcb.c @@ -0,0 +1,170 @@ +/* + * Copyright (C) 2015-2016 Freescale Semiconductor, Inc. + * Copyright 2017 NXP + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include "bcb.h" +#include "bootctrl.h" +#define ALIGN_BYTES 64 /*armv7 cache line need 64 bytes aligned */ + +static ulong get_block_size(char *ifname, int dev) +{ + struct blk_desc *dev_desc = NULL; + + dev_desc = blk_get_dev(ifname, dev); + if (dev_desc == NULL) { + printf("Block device %s %d not supported\n", ifname, dev); + return 0; + } + + return dev_desc->blksz; +} + +static int do_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + char *ep; + struct blk_desc *dev_desc = NULL; + int dev; + int part = 0; + disk_partition_t part_info; + ulong offset = 0u; + ulong limit = 0u; + void *addr; + uint blk; + uint cnt; + + if (argc != 6) { + cmd_usage(cmdtp); + return 1; + } + + dev = (int)simple_strtoul(argv[2], &ep, 16); + if (*ep) { + if (*ep != ':') { + printf("Invalid block device %s\n", argv[2]); + return 1; + } + part = (int)simple_strtoul(++ep, NULL, 16); + } + + dev_desc = blk_get_dev(argv[1], dev); + if (dev_desc == NULL) { + printf("Block device %s %d not supported\n", argv[1], dev); + return 1; + } + + addr = (void *)simple_strtoul(argv[3], NULL, 16); + blk = simple_strtoul(argv[4], NULL, 16); + cnt = simple_strtoul(argv[5], NULL, 16); + + if (part != 0) { + if (part_get_info(dev_desc, part, &part_info)) { + printf("Cannot find partition %d\n", part); + return 1; + } + offset = part_info.start; + limit = part_info.size; + } else { + /* Largest address not available in block_dev_desc_t. */ + limit = ~0; + } + + if (cnt + blk > limit) { + printf("Write out of range\n"); + return 1; + } + + if (dev_desc->block_write(dev_desc, offset + blk, cnt, addr) != cnt) { + printf("Error writing blocks\n"); + return 1; + } + + return 0; +} + +U_BOOT_CMD( + write, 6, 0, do_write, + "write binary data to a partition", + " addr blk# cnt" +); + +int bcb_rw_block(bool bread, char **ppblock, + uint *pblksize, char *pblock_write, uint offset, uint size) +{ + int ret; + char *argv[6]; + char addr_str[20]; + char cnt_str[8]; + char devpart_str[8]; + char block_begin_str[8]; + ulong blk_size = 0; + uint blk_begin = 0; + uint blk_end = 0; + uint block_cnt = 0; + char *p_block = NULL; + unsigned int mmc_id; + + if (bread && ((ppblock == NULL) || (pblksize == NULL))) + return -1; + + if (!bread && (pblock_write == NULL)) + return -1; + + mmc_id = mmc_get_env_dev(); + blk_size = get_block_size("mmc", mmc_id); + if (blk_size == 0) { + printf("bcb_rw_block, get_block_size return 0\n"); + return -1; + } + + blk_begin = offset/blk_size; + blk_end = (offset + size)/blk_size; + block_cnt = 1 + (blk_end - blk_begin); + + sprintf(devpart_str, "0x%x:0x%x", mmc_id, + fastboot_flash_find_index(FASTBOOT_PARTITION_MISC)); + sprintf(block_begin_str, "0x%x", blk_begin); + sprintf(cnt_str, "0x%x", block_cnt); + + argv[0] = "rw"; /* not care */ + argv[1] = "mmc"; + argv[2] = devpart_str; + argv[3] = addr_str; + argv[4] = block_begin_str; + argv[5] = cnt_str; + + if (bread) { + p_block = (char *)memalign(ALIGN_BYTES, blk_size * block_cnt); + if (NULL == p_block) { + printf("bcb_rw_block, memalign %d bytes failed\n", + (int)(blk_size * block_cnt)); + return -1; + } + sprintf(addr_str, "0x%x", (unsigned int)p_block); + ret = do_raw_read(NULL, 0, 6, argv); + if (ret) { + free(p_block); + printf("do_raw_read failed, ret %d\n", ret); + return -1; + } + + *ppblock = p_block; + *pblksize = (uint)blk_size; + } else { + sprintf(addr_str, "0x%x", (unsigned int)pblock_write); + ret = do_write(NULL, 0, 6, argv); + if (ret) { + printf("do_write failed, ret %d\n", ret); + return -1; + } + } + return 0; +} diff --git a/drivers/usb/gadget/bcb.h b/drivers/usb/gadget/bcb.h new file mode 100644 index 0000000..1e02508 --- /dev/null +++ b/drivers/usb/gadget/bcb.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2015-2016 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef BCB_H +#define BCB_H +#include +#include + +#define FASTBOOT_BCB_CMD "bootonce-bootloader" +#ifdef CONFIG_ANDROID_RECOVERY +#define RECOVERY_BCB_CMD "boot-recovery" +#endif +/* keep same as bootable/recovery/bootloader.h */ +struct bootloader_message { + char command[32]; + char status[32]; + char recovery[768]; + + /* The 'recovery' field used to be 1024 bytes. It has only ever + been used to store the recovery command line, so 768 bytes + should be plenty. We carve off the last 256 bytes to store the + stage string (for multistage packages) and possible future + expansion. */ + char stage[32]; + + /* The 'reserved' field used to be 224 bytes when it was initially + carved off from the 1024-byte recovery field. Bump it up to + 1184-byte so that the entire bootloader_message struct rounds up + to 2048-byte. + */ + char reserved[1184]; +}; + +struct bootloader_message_ab { + struct bootloader_message message; + char slot_suffix[32]; + + /* Round up the entire struct to 4096-byte. */ + char reserved[2016]; +}; + +/* start from bootloader_message_ab.slot_suffix[BOOTCTRL_IDX] */ +#define BOOTCTRL_IDX 0 +#define MISC_COMMAND_IDX 0 +#define BOOTCTRL_OFFSET \ + (u32)(&(((struct bootloader_message_ab *)0)->slot_suffix[BOOTCTRL_IDX])) +#define MISC_COMMAND \ + (u32)(&(((struct bootloader_message *)0)->command[MISC_COMMAND_IDX])) +int bcb_rw_block(bool bread, char **ppblock, + uint *pblksize, char *pblock_write, uint offset, uint size); + +int bcb_write_command(char *bcb_command); +int bcb_read_command(char *command); + +#endif diff --git a/drivers/usb/gadget/bootctrl.c b/drivers/usb/gadget/bootctrl.c new file mode 100644 index 0000000..8e0b999 --- /dev/null +++ b/drivers/usb/gadget/bootctrl.c @@ -0,0 +1,405 @@ +/* + * Copyright (C) 2015-2016 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include "bootctrl.h" +#include +#include +static unsigned int g_slot_selected; +static const char *g_slot_suffix[SLOT_NUM] = {"_a", "_b"}; +static int init_slotmeta(struct boot_ctl *ptbootctl); + +static int strcmp_l1(const char *s1, const char *s2) +{ + if (!s1 || !s2) + return -1; + return strncmp(s1, s2, strlen(s1)); +} + + +static void dump_slotmeta(struct boot_ctl *ptbootctl) +{ + int i; + + if (ptbootctl == NULL) + return; + + printf("RecoveryTryRemain %d, crc %u\n", + ptbootctl->recovery_tryremain, ptbootctl->crc); + + for (i = 0; i < SLOT_NUM; i++) { + printf("slot %d: pri %d, try %d, suc %d\n", i, + ptbootctl->a_slot_meta[i].priority, + ptbootctl->a_slot_meta[i].tryremain, + ptbootctl->a_slot_meta[i].bootsuc); + } + + return; +} + +const char *get_slot_suffix(void) +{ + return g_slot_suffix[g_slot_selected]; +} + +static unsigned int slot_find(struct boot_ctl *ptbootctl) +{ + unsigned int max_pri = 0; + unsigned int slot = -1; + int i; + + for (i = 0; i < SLOT_NUM; i++) { + struct slot_meta *pslot_meta = &(ptbootctl->a_slot_meta[i]); + if ((pslot_meta->priority > max_pri) && + ((pslot_meta->bootsuc > 0) || + (pslot_meta->tryremain > 0))) { + max_pri = pslot_meta->priority; + slot = i; + printf("select_slot slot %d\n", slot); + } + } + + return slot; +} + + + +static int read_bootctl(struct boot_ctl *ptbootctl) +{ + int ret = 0; + unsigned int crc = 0; + char *p_block = NULL; + uint offset_in_block = 0; + uint blk_size = 0; + char *pmagic = NULL; + + if (ptbootctl == NULL) + return -1; + ret = bcb_rw_block(true, &p_block, &blk_size, NULL, + BOOTCTRL_OFFSET, sizeof(struct boot_ctl)); + if (ret) { + printf("read_bootctl, bcb_rw_block read failed\n"); + return -1; + } + + offset_in_block = BOOTCTRL_OFFSET%blk_size; + memcpy(ptbootctl, p_block + offset_in_block, sizeof(struct boot_ctl)); + + pmagic = ptbootctl->magic; + if (!((pmagic[0] == '\0') && (pmagic[1] == 'F') && + (pmagic[2] == 'S') && (pmagic[3] == 'L'))) { + printf("magic error, 0x%x 0x%x 0x%x 0x%x\n", + pmagic[0], pmagic[1], pmagic[2], pmagic[3]); + + ret = init_slotmeta(ptbootctl); + if (ret) { + printf("init_slotmeta failed, ret %d\n", ret); + free(p_block); + return -1; + } + } + + /* check crc */ + crc = crc32(0, (unsigned char *)ptbootctl + CRC_DATA_OFFSET, + sizeof(struct boot_ctl) - CRC_DATA_OFFSET); + if (crc != ptbootctl->crc) { + printf("crc check failed, caculated %d, read %d\n", + crc, ptbootctl->crc); + + free(p_block); + return -1; + } + + free(p_block); + return 0; +} + +static int write_bootctl(struct boot_ctl *ptbootctl) +{ + int ret = 0; + char *p_block = NULL; + uint offset_in_block = 0; + uint blk_size = 0; + + if (ptbootctl == NULL) + return -1; + + ptbootctl->crc = crc32(0, (unsigned char *)ptbootctl + CRC_DATA_OFFSET, + sizeof(struct boot_ctl) - CRC_DATA_OFFSET); + + ret = bcb_rw_block(true, &p_block, &blk_size, NULL, + BOOTCTRL_OFFSET, sizeof(struct boot_ctl)); + if (ret) { + printf("write_bootctl, bcb_rw_block read failed\n"); + return -1; + } + offset_in_block = BOOTCTRL_OFFSET%blk_size; + memcpy(p_block + offset_in_block, ptbootctl, sizeof(struct boot_ctl)); + + ret = bcb_rw_block(false, NULL, NULL, p_block, + BOOTCTRL_OFFSET, sizeof(struct boot_ctl)); + if (ret) { + free(p_block); + printf("write_bootctl, bcb_rw_block write failed\n"); + return -1; + } + free(p_block); + return 0; +} + +static int init_slotmeta(struct boot_ctl *ptbootctl) +{ + int ret = 0; + if (ptbootctl == NULL) + return -1; + memset(ptbootctl, 0, sizeof(struct boot_ctl)); + ptbootctl->recovery_tryremain = 7; + ptbootctl->a_slot_meta[0].priority = 8; + ptbootctl->a_slot_meta[0].tryremain = 7; + ptbootctl->a_slot_meta[0].bootsuc = 0; + ptbootctl->a_slot_meta[1].priority = 6; + ptbootctl->a_slot_meta[1].tryremain = 7; + ptbootctl->a_slot_meta[1].bootsuc = 0; + + ptbootctl->magic[0] = '\0'; + ptbootctl->magic[1] = 'F'; + ptbootctl->magic[2] = 'S'; + ptbootctl->magic[3] = 'L'; + + ptbootctl->crc = crc32(0, (uint8_t *)ptbootctl + CRC_DATA_OFFSET, + sizeof(struct boot_ctl) - CRC_DATA_OFFSET); + ret = write_bootctl(ptbootctl); + return ret; +} + +char *select_slot(void) +{ + int i = 0; + int ret = 0; + unsigned int slot; + struct boot_ctl t_bootctl; + bool b_need_write = false; + + ret = read_bootctl(&t_bootctl); + if (ret) { + printf("read_bootctl failed, ret %d\n", ret); + return NULL; + } + + dump_slotmeta(&t_bootctl); + + slot = slot_find(&t_bootctl); + if (slot >= SLOT_NUM) { + printf("!!! select_slot, no valid slot\n"); + return NULL; + } + + /* invalid slot, set priority to 0 */ + for (i = 0; i < SLOT_NUM; i++) { + struct slot_meta *pslot_meta = &(t_bootctl.a_slot_meta[i]); + if ((pslot_meta->bootsuc == 0) && + (pslot_meta->tryremain == 0) && + (pslot_meta->priority > 0)) { + pslot_meta->priority = 0; + b_need_write = true; + } + } + + if (t_bootctl.recovery_tryremain != 7) { + b_need_write = true; + t_bootctl.recovery_tryremain = 7; + } + + if ((t_bootctl.a_slot_meta[slot].bootsuc == 0) && + (t_bootctl.a_slot_meta[slot].tryremain > 0)) { + b_need_write = true; + t_bootctl.a_slot_meta[slot].tryremain--; + } + + if (b_need_write) { + ret = write_bootctl(&t_bootctl); + if (ret) + printf("!!! write_bootctl failed, ret %d\n", ret); + } + + g_slot_selected = slot; + + if (slot == 0) + return FASTBOOT_PARTITION_BOOT_A; + else + return FASTBOOT_PARTITION_BOOT_B; +} + + +int invalid_curslot(void) +{ + int ret = 0; + struct boot_ctl t_bootctl; + unsigned int slot = g_slot_selected; + + printf("invalid_curslot %d\n", slot); + + if (slot >= SLOT_NUM) + return -1; + + ret = read_bootctl(&t_bootctl); + if (ret) { + printf("invalid_slot failed, ret %d\n", ret); + return -1; + } + + t_bootctl.a_slot_meta[slot].priority = 0; + ret = write_bootctl(&t_bootctl); + if (ret) { + printf("!!! write_bootctl failed, ret %d\n", ret); + return -1; + } + + return 0; +} + + +static unsigned int slotidx_from_suffix(char *suffix) +{ + unsigned int slot = -1; + + if (!strcmp(suffix, "_a") || + !strcmp(suffix, "a")) + slot = 0; + else if (!strcmp(suffix, "_b") || + !strcmp(suffix, "b")) + slot = 1; + + return slot; +} + + +int get_slotvar(char *cmd, char *response, size_t chars_left) +{ + int ret; + struct boot_ctl t_bootctl; + memset(&t_bootctl, 0, sizeof(t_bootctl)); + + /* these two var no need to read_bootctl */ + if (!strcmp_l1("has-slot:", cmd)) { + char *ptnname = NULL; + ptnname = strchr(cmd, ':') + 1; + if (!strcmp(ptnname, "system") || !strcmp(ptnname, "boot")) + strlcpy(response, "yes", chars_left); + else + strlcpy(response, "no", chars_left); + return 0; + } else if (!strcmp_l1("slot-suffixes", cmd)) { + strlcpy(response, "_a,_b", chars_left); + return 0; + } + + ret = read_bootctl(&t_bootctl); + if (ret) { + error("get_slotvar, read_bootctl failed\n"); + strcpy(response, "get_slotvar read_bootctl failed"); + return -1; + } + if (!strcmp_l1("current-slot", cmd)) { + unsigned int slot = slot_find(&t_bootctl); + if (slot < SLOT_NUM) + strlcpy(response, g_slot_suffix[slot], chars_left); + else { + strlcpy(response, "no valid slot", chars_left); + return -1; + } + } else if (!strcmp_l1("slot-successful:", cmd)) { + char *suffix = strchr(cmd, ':') + 1; + unsigned int slot = slotidx_from_suffix(suffix); + if (slot >= SLOT_NUM) { + strlcpy(response, "no such slot", chars_left); + return -1; + } else { + bool suc = t_bootctl.a_slot_meta[slot].bootsuc; + strlcpy(response, suc ? "yes" : "no", chars_left); + } + } else if (!strcmp_l1("slot-unbootable:", cmd)) { + char *suffix = strchr(cmd, ':') + 1; + unsigned int slot = slotidx_from_suffix(suffix); + if (slot >= SLOT_NUM) { + strlcpy(response, "no such slot", chars_left); + return -1; + } else { + unsigned int pri = t_bootctl.a_slot_meta[slot].priority; + strlcpy(response, pri ? "no" : "yes", chars_left); + } + } else if (!strcmp_l1("slot-retry-count:", cmd)) { + char *suffix = strchr(cmd, ':') + 1; + unsigned int slot = slotidx_from_suffix(suffix); + if (slot >= SLOT_NUM) { + strlcpy(response, "no such slot", chars_left); + return -1; + } else { + char str_num[7]; + sprintf(str_num, "%d", + t_bootctl.a_slot_meta[slot].tryremain); + strlcpy(response, str_num, chars_left); + } + } else { + strlcpy(response, "no such slot command", chars_left); + return -1; + } + + return 0; +} + + +void cb_set_active(struct usb_ep *ep, struct usb_request *req) +{ + int ret; + int i; + unsigned int slot = 0; + char *cmd = req->buf; + struct boot_ctl t_bootctl; + + memset(&t_bootctl, 0, sizeof(t_bootctl)); + + strsep(&cmd, ":"); + if (!cmd) { + error("missing slot suffix\n"); + fastboot_tx_write_str("FAILmissing slot suffix"); + return; + } + + slot = slotidx_from_suffix(cmd); + if (slot >= SLOT_NUM) { + fastboot_tx_write_str("FAILerr slot suffix"); + return; + } + + ret = read_bootctl(&t_bootctl); + if (ret) + fastboot_tx_write_str("FAILReadBootCtl failed"); + + t_bootctl.a_slot_meta[slot].bootsuc = 0; + t_bootctl.a_slot_meta[slot].priority = 15; + t_bootctl.a_slot_meta[slot].tryremain = 7; + + /* low other slot priority */ + for (i = 0; i < SLOT_NUM; i++) { + if (i == slot) + continue; + + if (t_bootctl.a_slot_meta[i].priority >= 15) + t_bootctl.a_slot_meta[i].priority = 14; + } + + ret = write_bootctl(&t_bootctl); + if (ret) + fastboot_tx_write_str("write_bootctl failed"); + else + fastboot_tx_write_str("OKAY"); + + return; +} + diff --git a/drivers/usb/gadget/bootctrl.h b/drivers/usb/gadget/bootctrl.h new file mode 100644 index 0000000..a181cd7 --- /dev/null +++ b/drivers/usb/gadget/bootctrl.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2015-2016 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef BOOTCTRL_H +#define BOOTCTRL_H + +#include +#include +#include +#include +#include "bcb.h" + +#define SLOT_NUM (unsigned int)2 +#define CRC_DATA_OFFSET \ + (uint32_t)(&(((struct boot_ctl *)0)->a_slot_meta[0])) + +struct slot_meta { + u8 bootsuc:1; + u8 tryremain:3; + u8 priority:4; +}; + +struct boot_ctl { + char magic[4]; /* "\0FSL" */ + u32 crc; + struct slot_meta a_slot_meta[SLOT_NUM]; + u8 recovery_tryremain; +}; +char *select_slot(void); +int invalid_curslot(void); +int get_slotvar(char *cmd, char *response, size_t chars_left); +void cb_set_active(struct usb_ep *ep, struct usb_request *req); +const char *get_slot_suffix(void); +#endif diff --git a/drivers/usb/gadget/command.c b/drivers/usb/gadget/command.c new file mode 100644 index 0000000..e66e033 --- /dev/null +++ b/drivers/usb/gadget/command.c @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2015-2016 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#ifdef CONFIG_FASTBOOT_STORAGE_NAND +#include +#endif +#include "bcb.h" + +#ifndef CONFIG_FASTBOOT_STORAGE_NAND +int bcb_read_command(char *command) +{ + int ret = 0; + char *p_block = NULL; + uint offset_in_block = 0; + uint blk_size = 0; + + if (command == NULL) + return -1; + + ret = bcb_rw_block(true, &p_block, &blk_size, NULL, MISC_COMMAND, 32); + if (ret) { + printf("read_bootctl, bcb_rw_block read failed\n"); + return -1; + } + + offset_in_block = MISC_COMMAND%blk_size; + memcpy(command, p_block + offset_in_block, 32); + free(p_block); + + return 0; +} +int bcb_write_command(char *bcb_command) +{ + int ret = 0; + char *p_block = NULL; + uint offset_in_block = 0; + uint blk_size = 0; + + if (bcb_command == NULL) + return -1; + + + ret = bcb_rw_block(true, &p_block, &blk_size, NULL, MISC_COMMAND, 32); + if (ret) { + printf("write_bootctl, bcb_rw_block read failed\n"); + return -1; + } + + offset_in_block = MISC_COMMAND%blk_size; + memcpy(p_block + offset_in_block, bcb_command, 32); + + ret = bcb_rw_block(false, NULL, NULL, p_block, MISC_COMMAND, 32); + if (ret) { + free(p_block); + printf("write_bootctl, bcb_rw_block write failed\n"); + return -1; + } + + free(p_block); + return 0; +} +#else +#define ALIGN_BYTES 64 +#define MISC_PAGES 3 +int bcb_read_command(char *command) +{ + char read_cmd[128]; + char *addr_str; + char *nand_str; + ulong misc_info_size; + nand_info_t *nand = &nand_info[0]; + if (command == NULL) + return -1; + memset(read_cmd, 0, 128); + misc_info_size = MISC_PAGES * nand->writesize; + nand_str = (char *)memalign(ALIGN_BYTES, misc_info_size); + sprintf(read_cmd, "nand read 0x%x ${misc_nand_offset} \ + 0x%x", nand_str, misc_info_size); + run_command(read_cmd, 0); + /* The offset of bootloader_message is 1 PAGE. + * The offset of bootloader_message and the size of misc info + * need align with user space and recovery. + */ + addr_str = nand_str + nand->writesize; + memcpy(command, (char *)addr_str, 32); + free(nand_str); + return 0; +} +int bcb_write_command(char *command) +{ + char cmd[128]; + char *addr_str; + char *nand_str; + ulong misc_info_size; + nand_info_t *nand = &nand_info[0]; + if (command == NULL) + return -1; + memset(cmd, 0, 128); + misc_info_size = MISC_PAGES * nand->writesize; + nand_str = (char *)memalign(ALIGN_BYTES, misc_info_size); + sprintf(cmd, "nand read 0x%x ${misc_nand_offset} \ + 0x%x", nand_str, misc_info_size); + run_command(cmd, 0); + /* the offset of bootloader_message is 1 PAGE*/ + addr_str = nand_str + nand->writesize; + memcpy((char *)addr_str, command, 32); + /* erase 3 pages which hold BCB struct.*/ + sprintf(cmd, "nand erase ${misc_nand_offset} 0x%x",nand->erasesize); + run_command(cmd, 0); + sprintf(cmd, "nand write 0x%x ${misc_nand_offset} 0x%x",nand_str, misc_info_size); + run_command(cmd, 0); + free(nand_str); + return 0; +} +#endif diff --git a/drivers/usb/gadget/f_fastboot.c b/drivers/usb/gadget/f_fastboot.c index 9f07940..f8c9414 100644 --- a/drivers/usb/gadget/f_fastboot.c +++ b/drivers/usb/gadget/f_fastboot.c @@ -40,17 +40,24 @@ #include #include #include +#include #ifdef CONFIG_ANDROID_RECOVERY #include #endif #endif +#ifdef CONFIG_FSL_BOOTCTL +#include "bootctrl.h" +#endif +#ifdef CONFIG_BCB_SUPPORT +#include "bcb.h" +#endif + + #define FASTBOOT_VERSION "0.4" -#ifdef CONFIG_EFI_PARTITION #define ANDROID_GPT_OFFSET 0 #define ANDROID_GPT_SIZE 0x100000 -#endif #define FASTBOOT_INTERFACE_CLASS 0xff #define FASTBOOT_INTERFACE_SUB_CLASS 0x42 #define FASTBOOT_INTERFACE_PROTOCOL 0x03 @@ -170,20 +177,6 @@ static struct usb_gadget_strings *fastboot_strings[] = { #ifdef CONFIG_FSL_FASTBOOT -#ifdef CONFIG_EFI_PARTITION -#define ANDROID_BOOT_PARTITION_MMC 1 -#define ANDROID_RECOVERY_PARTITION_MMC 2 -#define ANDROID_SYSTEM_PARTITION_MMC 3 -#define ANDROID_CACHE_PARTITION_MMC 4 -#define ANDROID_MISC_PARTITION_MMC 6 -#define ANDROID_DATA_PARTITION_MMC 10 -#else -#define ANDROID_BOOT_PARTITION_MMC 1 -#define ANDROID_SYSTEM_PARTITION_MMC 5 -#define ANDROID_RECOVERY_PARTITION_MMC 2 -#define ANDROID_CACHE_PARTITION_MMC 6 -#define ANDROID_DATA_PARTITION_MMC 4 -#endif #define ANDROID_MBR_OFFSET 0 #define ANDROID_MBR_SIZE 0x200 @@ -199,39 +192,13 @@ static struct usb_gadget_strings *fastboot_strings[] = { #define MMC_SATA_BLOCK_SIZE 512 #define FASTBOOT_FBPARTS_ENV_MAX_LEN 1024 /* To support the Android-style naming of flash */ -#define MAX_PTN 16 +#define MAX_PTN 32 -/*pentry index internally*/ -#ifdef CONFIG_EFI_PARTITION enum { PTN_GPT_INDEX = 0, - PTN_BOOTLOADER_INDEX, - PTN_BOOT_INDEX, - PTN_RECOVERY_INDEX, - PTN_SYSTEM_INDEX, - PTN_CACHE_INDEX, - PTN_DEVICE_INDEX, - PTN_MISC_INDEX, - PTN_DATAFOOTER_INDEX, - PTN_VBMETA_INDEX, - PTN_PRESISTDATA_INDEX, - PTN_DATA_INDEX, - PTN_FBMISC_INDEX, - PTN_NUM + PTN_BOOTLOADER_INDEX }; -#else -enum { - PTN_MBR_INDEX = 0, - PTN_BOOTLOADER_INDEX, - PTN_KERNEL_INDEX, - PTN_URAMDISK_INDEX, - PTN_SYSTEM_INDEX, - PTN_RECOVERY_INDEX, - PTN_DATA_INDEX, - PTN_NUM -}; -#endif /*CONFIG_EFI_PARTITION*/ static unsigned int download_bytes_unpadded; static struct cmd_fastboot_interface interface = { @@ -862,16 +829,39 @@ static void process_flash_sata(const char *cmdbuf) #endif #if defined(CONFIG_FASTBOOT_STORAGE_MMC) -static int is_sparse_partition(struct fastboot_ptentry *ptn) -{ - if (ptn && (!strncmp(ptn->name, - FASTBOOT_PARTITION_SYSTEM, strlen(FASTBOOT_PARTITION_SYSTEM)) - || !strncmp(ptn->name, - FASTBOOT_PARTITION_DATA, strlen(FASTBOOT_PARTITION_DATA)))) { +static int is_raw_partition(struct fastboot_ptentry *ptn) +{ +#ifdef CONFIG_ANDROID_AB_SUPPORT + if (ptn && (!strncmp(ptn->name, FASTBOOT_PARTITION_BOOTLOADER, + strlen(FASTBOOT_PARTITION_BOOTLOADER)) || + !strncmp(ptn->name, FASTBOOT_PARTITION_GPT, + strlen(FASTBOOT_PARTITION_GPT)) || + !strncmp(ptn->name, FASTBOOT_PARTITION_BOOT_A, + strlen(FASTBOOT_PARTITION_BOOT_A)) || + !strncmp(ptn->name, FASTBOOT_PARTITION_BOOT_B, + strlen(FASTBOOT_PARTITION_BOOT_B)) || +#ifdef CONFIG_FASTBOOT_LOCK + !strncmp(ptn->name, FASTBOOT_PARTITION_FBMISC, + strlen(FASTBOOT_PARTITION_FBMISC)) || +#endif + !strncmp(ptn->name, FASTBOOT_PARTITION_MISC, + strlen(FASTBOOT_PARTITION_MISC)))) { +#else + if (ptn && (!strncmp(ptn->name, FASTBOOT_PARTITION_BOOTLOADER, + strlen(FASTBOOT_PARTITION_BOOTLOADER)) || + !strncmp(ptn->name, FASTBOOT_PARTITION_BOOT, + strlen(FASTBOOT_PARTITION_BOOT)) || +#ifdef CONFIG_FASTBOOT_LOCK + !strncmp(ptn->name, FASTBOOT_PARTITION_FBMISC, + strlen(FASTBOOT_PARTITION_FBMISC)) || +#endif + !strncmp(ptn->name, FASTBOOT_PARTITION_MISC, + strlen(FASTBOOT_PARTITION_MISC)))) { +#endif printf("support sparse flash partition for %s\n", ptn->name); return 1; } else - return 0; + return 0; } static lbaint_t mmc_sparse_write(struct sparse_storage *info, @@ -964,7 +954,7 @@ static void process_flash_mmc(const char *cmdbuf) sprintf(mmc_dev, "mmc dev %x", fastboot_devinfo.dev_id /*slot no*/); - if (is_sparse_partition(ptn) && + if (!is_raw_partition(ptn) && is_sparse_image(interface.transfer_buffer)) { int mmc_no = 0; struct mmc *mmc; @@ -1154,25 +1144,6 @@ static struct fastboot_ptentry ptable[MAX_PTN]; static unsigned int pcount; struct fastboot_device_info fastboot_devinfo; -/* - Get mmc control number from passed string, eg, "mmc1" mean device 1. Only - support "mmc0" to "mmc9" currently. It will be treated as device 0 for - other string. -*/ -static int _fastboot_get_mmc_no(char *env_str) -{ - int digit = 0; - unsigned char a; - - if (env_str && (strlen(env_str) >= 4) && - !strncmp(env_str, "mmc", 3)) { - a = env_str[3]; - if (a >= '0' && a <= '9') - digit = a - '0'; - } - - return digit; -} static int _fastboot_setup_dev(void) { char *fastboot_env; @@ -1187,7 +1158,7 @@ static int _fastboot_setup_dev(void) fastboot_devinfo.dev_id = 0; } else if (!strncmp(fastboot_env, "mmc", 3)) { fastboot_devinfo.type = DEV_MMC; - fastboot_devinfo.dev_id = _fastboot_get_mmc_no(fastboot_env); + fastboot_devinfo.dev_id = mmc_get_env_dev(); } } else { return 1; @@ -1245,7 +1216,7 @@ static int _fastboot_parts_load_from_ptable(void) struct mmc *mmc; struct blk_desc *dev_desc; - struct fastboot_ptentry ptable[PTN_NUM + 1]; + struct fastboot_ptentry ptable[MAX_PTN]; /* sata case in env */ if (fastboot_devinfo.type == DEV_SATA) { @@ -1292,20 +1263,12 @@ static int _fastboot_parts_load_from_ptable(void) } memset((char *)ptable, 0, - sizeof(struct fastboot_ptentry) * (PTN_NUM + 1)); -#ifdef CONFIG_EFI_PARTITION + sizeof(struct fastboot_ptentry) * (MAX_PTN)); /* GPT */ - strcpy(ptable[PTN_GPT_INDEX].name, "gpt"); + strcpy(ptable[PTN_GPT_INDEX].name, FASTBOOT_PARTITION_GPT); ptable[PTN_GPT_INDEX].start = ANDROID_GPT_OFFSET / dev_desc->blksz; ptable[PTN_GPT_INDEX].length = ANDROID_GPT_SIZE / dev_desc->blksz; ptable[PTN_GPT_INDEX].partition_id = user_partition; -#else - /* MBR */ - strcpy(ptable[PTN_MBR_INDEX].name, "mbr"); - ptable[PTN_MBR_INDEX].start = ANDROID_MBR_OFFSET / dev_desc->blksz; - ptable[PTN_MBR_INDEX].length = ANDROID_MBR_SIZE / dev_desc->blksz; - ptable[PTN_MBR_INDEX].partition_id = user_partition; -#endif /* Bootloader */ strcpy(ptable[PTN_BOOTLOADER_INDEX].name, FASTBOOT_PARTITION_BOOTLOADER); ptable[PTN_BOOTLOADER_INDEX].start = @@ -1314,28 +1277,10 @@ static int _fastboot_parts_load_from_ptable(void) ANDROID_BOOTLOADER_SIZE / dev_desc->blksz; ptable[PTN_BOOTLOADER_INDEX].partition_id = boot_partition; -#ifndef CONFIG_EFI_PARTITION - _fastboot_parts_add_ptable_entry(PTN_KERNEL_INDEX, - ANDROID_BOOT_PARTITION_MMC, - user_partition, - FASTBOOT_PARTITION_BOOT , dev_desc, ptable); - _fastboot_parts_add_ptable_entry(PTN_RECOVERY_INDEX, - ANDROID_RECOVERY_PARTITION_MMC, - user_partition, - FASTBOOT_PARTITION_RECOVERY, dev_desc, ptable); - _fastboot_parts_add_ptable_entry(PTN_SYSTEM_INDEX, - ANDROID_SYSTEM_PARTITION_MMC, - user_partition, - FASTBOOT_PARTITION_SYSTEM, dev_desc, ptable); - _fastboot_parts_add_ptable_entry(PTN_DATA_INDEX, - ANDROID_DATA_PARTITION_MMC, - user_partition, - FASTBOOT_PARTITION_DATA, dev_desc, ptable); -#else int tbl_idx; int part_idx = 1; int ret; - for (tbl_idx = 2; tbl_idx < PTN_NUM; tbl_idx++) { + for (tbl_idx = 2; tbl_idx < MAX_PTN; tbl_idx++) { ret = _fastboot_parts_add_ptable_entry(tbl_idx, part_idx++, user_partition, @@ -1344,8 +1289,7 @@ static int _fastboot_parts_load_from_ptable(void) if (ret) break; } -#endif /*CONFIG_EFI_PARTITION*/ - for (i = 0; i <= PTN_NUM; i++) + for (i = 0; i <= part_idx; i++) fastboot_flash_add_ptn(&ptable[i]); return 0; @@ -1563,6 +1507,16 @@ struct fastboot_ptentry *fastboot_flash_find_ptn(const char *name) return 0; } +int fastboot_flash_find_index(const char *name) +{ + struct fastboot_ptentry *ptentry = fastboot_flash_find_ptn(name); + if (ptentry == NULL) { + printf("cannot get the partion info for %s\n",name); + return -1; + } + return ptentry->partition_index; +} + struct fastboot_ptentry *fastboot_flash_get_ptn(unsigned int n) { if (n < pcount) @@ -1576,17 +1530,93 @@ unsigned int fastboot_flash_get_ptn_count(void) return pcount; } -/* - * CPU and board-specific fastboot initializations. Aliased function - * signals caller to move on - */ -static void __def_fastboot_setup(void) +#ifdef CONFIG_FSL_FASTBOOT +void board_fastboot_setup(void) { - /*do nothing here*/ +#if defined(CONFIG_FASTBOOT_STORAGE_MMC) + static char boot_dev_part[32]; + u32 dev_no; +#endif + switch (get_boot_device()) { +#if defined(CONFIG_FASTBOOT_STORAGE_MMC) + case SD1_BOOT: + case SD2_BOOT: + case SD3_BOOT: + case SD4_BOOT: + case MMC1_BOOT: + case MMC2_BOOT: + case MMC3_BOOT: + case MMC4_BOOT: + dev_no = mmc_get_env_dev(); + sprintf(boot_dev_part,"mmc%d",dev_no); + if (!getenv("fastboot_dev")) + setenv("fastboot_dev", boot_dev_part); + sprintf(boot_dev_part, "boota mmc%d", dev_no); + if (!getenv("bootcmd")) + setenv("bootcmd", boot_dev_part); + break; +#endif /*CONFIG_FASTBOOT_STORAGE_MMC*/ +#if defined(CONFIG_FASTBOOT_STORAGE_NAND) + case NAND_BOOT: + if (!getenv("fastboot_dev")) + setenv("fastboot_dev", "nand"); + if (!getenv("fbparts")) + setenv("fbparts", ANDROID_FASTBOOT_NAND_PARTS); + if (!getenv("bootcmd")) + setenv("bootcmd", + "nand read ${loadaddr} ${boot_nand_offset} " + "${boot_nand_size};boota ${loadaddr}"); + break; +#endif /*CONFIG_FASTBOOT_STORAGE_NAND*/ + default: + printf("unsupported boot devices\n"); + break; + } } -void board_fastboot_setup(void) \ - __attribute__((weak, alias("__def_fastboot_setup"))); +#ifdef CONFIG_ANDROID_RECOVERY +void board_recovery_setup(void) +{ +#if defined(CONFIG_FASTBOOT_STORAGE_MMC) + static char boot_dev_part[32]; + u32 dev_no; +#endif + int bootdev = get_boot_device(); + switch (bootdev) { +#if defined(CONFIG_FASTBOOT_STORAGE_MMC) + case SD1_BOOT: + case SD2_BOOT: + case SD3_BOOT: + case SD4_BOOT: + case MMC1_BOOT: + case MMC2_BOOT: + case MMC3_BOOT: + case MMC4_BOOT: + dev_no = mmc_get_env_dev(); + sprintf(boot_dev_part,"boota mmc%d recovery",dev_no); + if (!getenv("bootcmd_android_recovery")) + setenv("bootcmd_android_recovery", boot_dev_part); + break; +#endif /*CONFIG_FASTBOOT_STORAGE_MMC*/ +#if defined(CONFIG_FASTBOOT_STORAGE_NAND) + case NAND_BOOT: + if (!getenv("bootcmd_android_recovery")) + setenv("bootcmd_android_recovery", + "nand read ${loadaddr} ${recovery_nand_offset} " + "${recovery_nand_size};boota ${loadaddr}"); + break; +#endif /*CONFIG_FASTBOOT_STORAGE_NAND*/ + default: + printf("Unsupported bootup device for recovery: dev: %d\n", + bootdev); + return; + } + + printf("setup env for recovery..\n"); + setenv("bootcmd", "run bootcmd_android_recovery"); +} +#endif /*CONFIG_ANDROID_RECOVERY*/ +#endif /*CONFIG_FSL_FASTBOOT*/ void fastboot_setup(void) { @@ -1603,10 +1633,6 @@ void fastboot_setup(void) /*get the fastboot dev*/ _fastboot_setup_dev(); - /*check if we need to setup recovery*/ -#ifdef CONFIG_ANDROID_RECOVERY - check_recovery_mode(); -#endif /*load partitions information for the fastboot dev*/ _fastboot_load_partitions(); @@ -1614,11 +1640,79 @@ void fastboot_setup(void) parameters_setup(); } -/* export to lib_arm/board.c */ -void check_fastboot(void) +/* Write the bcb with fastboot bootloader commands */ +static void enable_fastboot_command(void) +{ + char fastboot_command[32] = {0}; + strncpy(fastboot_command, FASTBOOT_BCB_CMD, 31); + bcb_write_command(fastboot_command); +} + +/* Get the Boot mode from BCB cmd or Key pressed */ +static FbBootMode fastboot_get_bootmode(void) { - if (fastboot_check_and_clean_flag()) - run_command("fastboot", 0); + int ret = 0; + int boot_mode = BOOTMODE_NORMAL; + char command[32]; +#ifdef CONFIG_ANDROID_RECOVERY + if(is_recovery_key_pressing()) { + boot_mode = BOOTMODE_RECOVERY_KEY_PRESSED; + return boot_mode; + } +#endif + ret = bcb_read_command(command); + if (ret < 0) { + printf("read command failed\n"); + return boot_mode; + } + if (!strcmp(command, FASTBOOT_BCB_CMD)) { + memset(command, 0, 32); + bcb_write_command(command); + boot_mode = BOOTMODE_FASTBOOT_BCB_CMD; + } +#ifdef CONFIG_ANDROID_RECOVERY + else if (!strcmp(command, RECOVERY_BCB_CMD)) { + memset(command, 0, 32); + bcb_write_command(command); + boot_mode = BOOTMODE_RECOVERY_BCB_CMD; + } +#endif + return boot_mode; +} + +/* export to lib_arm/board.c */ +void fastboot_run_bootmode(void) +{ + FbBootMode boot_mode = fastboot_get_bootmode(); + switch(boot_mode){ + case BOOTMODE_FASTBOOT_BCB_CMD: + /* Make the boot into fastboot mode*/ + puts("Fastboot: Got bootloader commands!\n"); +#ifdef CONFIG_SYSTEM_RAMDISK_SUPPORT + is_recovery_mode = false; +#endif + run_command("fastboot 0", 0); + break; +#ifdef CONFIG_ANDROID_RECOVERY + case BOOTMODE_RECOVERY_BCB_CMD: + case BOOTMODE_RECOVERY_KEY_PRESSED: + /* Make the boot into recovery mode */ + puts("Fastboot: Got Recovery key pressing or recovery commands!\n"); +#ifdef CONFIG_SYSTEM_RAMDISK_SUPPORT + is_recovery_mode = true; +#else + board_recovery_setup(); +#endif + break; +#endif + default: + /* skip special mode boot*/ +#ifdef CONFIG_SYSTEM_RAMDISK_SUPPORT + is_recovery_mode = false; +#endif + puts("Fastboot: Normal\n"); + break; + } } #ifdef CONFIG_CMD_BOOTA @@ -1690,6 +1784,19 @@ int do_boota(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) if (argc > 2) ptn = argv[2]; +#ifdef CONFIG_FSL_BOOTCTL + else { +slot_select: + ptn = select_slot(); + if (ptn == NULL) { + printf("no valid slot found, enter to recovery\n"); + ptn = "recovery"; + } +use_given_ptn: + printf("use slot %s\n", ptn); + } +#endif + if (mmcc != -1) { #ifdef CONFIG_MMC struct fastboot_ptentry *pte; @@ -1917,7 +2024,23 @@ int do_boota(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) return 1; fail: -#ifdef CONFIG_FSL_FASTBOOT +#if defined(CONFIG_FSL_BOOTCTL) + if (argc > 2) + return -1; + if (0 == strcmp(ptn, "recovery")) { + printf("boot recovery partition failed\n"); + return -1; + } + printf("invalid slot %s\n", ptn); + int ret = 0; + ret = invalid_curslot(); + if (ret == 0) { + goto slot_select; + } else { + ptn = "recovery"; + goto use_given_ptn; + } +#elif defined(CONFIG_FSL_FASTBOOT) return run_command("fastboot", 0); #else /*! CONFIG_FSL_FASTBOOT*/ return -1; @@ -2155,7 +2278,7 @@ static int fastboot_tx_write(const char *buffer, unsigned int buffer_size) return 0; } -static int fastboot_tx_write_str(const char *buffer) +int fastboot_tx_write_str(const char *buffer) { return fastboot_tx_write(buffer, strlen(buffer)); } @@ -2207,6 +2330,13 @@ static void cb_getvar(struct usb_ep *ep, struct usb_request *req) return; } +#ifdef CONFIG_FSL_BOOTCTL + if (is_sotvar(cmd)) { + get_slotvar(cmd, response, chars_left); + fastboot_tx_write_str(response); + return; + } +#endif if (!strcmp_l1("version", cmd)) { strncat(response, FASTBOOT_VERSION, chars_left); } else if (!strcmp_l1("bootloader-version", cmd)) { @@ -2225,6 +2355,8 @@ static void cb_getvar(struct usb_ep *ep, struct usb_request *req) strcpy(response, "FAILValue not set"); } else if (!strcmp_l1("partition-type", cmd)) { strcpy(response, "FAILVariable not implemented"); + } else if (!strcmp_l1("product", cmd)) { + strncat(response, "Freescale i.MX", chars_left); } else { char envstr[32]; @@ -2234,7 +2366,6 @@ static void cb_getvar(struct usb_ep *ep, struct usb_request *req) strncat(response, s, chars_left); } else { printf("WARNING: unknown variable: %s\n", cmd); - strcpy(response, "FAILVariable not implemented"); } } fastboot_tx_write_str(response); @@ -2503,7 +2634,7 @@ static void cb_reboot_bootloader(struct usb_ep *ep, struct usb_request *req) fastboot_tx_write_str("OKAY"); udelay(1000000); - fastboot_enable_flag(); + enable_fastboot_command(); do_reset(NULL, 0, 0, NULL); } #endif @@ -2549,6 +2680,12 @@ static const struct cmd_dispatch_info cmd_dispatch_info[] = { .cmd = "oem", .cb = cb_oem, }, +#ifdef CONFIG_FSL_BOOTCTL + { + .cmd = "set_active", + .cb = cb_set_active, + }, +#endif }; static void rx_handler_command(struct usb_ep *ep, struct usb_request *req) diff --git a/include/common.h b/include/common.h index 6842cdb..ef97b15 100644 --- a/include/common.h +++ b/include/common.h @@ -932,6 +932,10 @@ int cpu_disable(int nr); int cpu_release(int nr, int argc, char * const argv[]); #endif +#ifdef CONFIG_CMD_READ +int do_raw_read(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); +#endif + #else /* __ASSEMBLY__ */ /* Drop a C type modifier (like in 3UL) for constants used in assembly. */ diff --git a/include/fsl_fastboot.h b/include/fsl_fastboot.h index 078c873..f6132e3 100644 --- a/include/fsl_fastboot.h +++ b/include/fsl_fastboot.h @@ -1,5 +1,6 @@ /* * Copyright (C) 2010-2016 Freescale Semiconductor, Inc. + * Copyright 2017 NXP * * SPDX-License-Identifier: GPL-2.0+ */ @@ -33,11 +34,25 @@ #define FASTBOOT_MMC_USER_PARTITION_ID 0 #define FASTBOOT_MMC_NONE_PARTITION_ID -1 +#ifdef CONFIG_ANDROID_THINGS_SUPPORT +#define FASTBOOT_PARTITION_BOOT_A "boot_a" +#define FASTBOOT_PARTITION_RECOVERY "recovery" +#define FASTBOOT_PARTITION_SYSTEM_A "system_a" +#define FASTBOOT_PARTITION_BOOTLOADER "bootloader" +#define FASTBOOT_PARTITION_DATA "userdata" +#define FASTBOOT_PARTITION_BOOT_B "boot_b" +#define FASTBOOT_PARTITION_SYSTEM_B "system_b" +#define FASTBOOT_PARTITION_MISC "misc" +#define FASTBOOT_PARTITION_GPT "gpt" +#else #define FASTBOOT_PARTITION_BOOT "boot" #define FASTBOOT_PARTITION_RECOVERY "recovery" #define FASTBOOT_PARTITION_SYSTEM "system" #define FASTBOOT_PARTITION_BOOTLOADER "bootloader" -#define FASTBOOT_PARTITION_DATA "data" +#define FASTBOOT_PARTITION_DATA "userdata" +#define FASTBOOT_PARTITION_GPT "gpt" +#define FASTBOOT_PARTITION_MISC "misc" +#endif enum { DEV_SATA, @@ -45,6 +60,20 @@ enum { DEV_NAND }; +typedef enum { +#ifdef CONFIG_ANDROID_RECOVERY + /* Revoery boot due to combo keys pressed */ + BOOTMODE_RECOVERY_KEY_PRESSED, + /* Recovery boot due to boot-recovery cmd in misc parition */ + BOOTMODE_RECOVERY_BCB_CMD, +#endif + /* Fastboot boot due to bootonce-bootloader cmd in misc parition */ + BOOTMODE_FASTBOOT_BCB_CMD, + /* Normal boot */ + BOOTMODE_NORMAL +}FbBootMode; + + struct cmd_fastboot_interface { /* This function is called when a buffer has been recieved from the client app. @@ -144,19 +173,18 @@ struct fastboot_ptentry *fastboot_flash_get_ptn(unsigned n); unsigned int fastboot_flash_get_ptn_count(void); void fastboot_flash_dump_ptn(void); - -/* Check the board special boot mode reboot to fastboot mode. */ -int fastboot_check_and_clean_flag(void); - -/* Set the flag which reboot to fastboot mode*/ -void fastboot_enable_flag(void); - -/*check if fastboot mode is requested by user*/ -void check_fastboot(void); +/* Make board into special boot mode */ +void fastboot_run_bootmode(void); /*Setup board-relative fastboot environment */ void board_fastboot_setup(void); +/* Check whether the combo keys pressed + * Return 1 if combo keys pressed for recovery boot + * Return 0 if no combo keys pressed + */ +int is_recovery_key_pressing(void); + #ifdef CONFIG_FASTBOOT_STORAGE_NAND /*Save parameters for NAND storage partitions */ void save_parts_values(struct fastboot_ptentry *ptn, diff --git a/include/recovery.h b/include/recovery.h index 4c368c6..4519cff 100644 --- a/include/recovery.h +++ b/include/recovery.h @@ -1,5 +1,6 @@ /* * Copyright (C) 2010-2016 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2017 NXP * * SPDX-License-Identifier: GPL-2.0+ */ @@ -12,9 +13,6 @@ struct reco_envs { char *args; }; -void check_recovery_mode(void); -int recovery_check_and_clean_flag(void); -int check_recovery_cmd_file(void); void board_recovery_setup(void); #endif -- cgit v1.1