| // SPDX-License-Identifier: GPL-2.0+ |
| /* |
| * Copyright 2019 NXP |
| */ |
| |
| #include <asm/mach-imx/sys_proto.h> |
| #include <fb_fsl.h> |
| #include <fastboot.h> |
| #include <mmc.h> |
| #include <android_image.h> |
| #include <asm/bootm.h> |
| #include <nand.h> |
| #include <part.h> |
| #include <sparse_format.h> |
| #include <image-sparse.h> |
| #include <image.h> |
| #include <asm/mach-imx/boot_mode.h> |
| #include <asm/arch/sys_proto.h> |
| #include <asm/setup.h> |
| #include <environment.h> |
| #ifdef CONFIG_ANDROID_RECOVERY |
| #include <recovery.h> |
| #endif |
| |
| #ifdef CONFIG_BCB_SUPPORT |
| #include "bcb.h" |
| #endif |
| |
| #ifdef CONFIG_AVB_SUPPORT |
| #include <dt_table.h> |
| #include <fsl_avb.h> |
| #endif |
| |
| #ifdef CONFIG_ANDROID_THINGS_SUPPORT |
| #include <asm-generic/gpio.h> |
| #include <asm/mach-imx/gpio.h> |
| #include "../lib/avb/fsl/fsl_avbkey.h" |
| #include "../arch/arm/include/asm/mach-imx/hab.h" |
| #endif |
| |
| #ifdef CONFIG_IMX_TRUSTY_OS |
| #include "u-boot/sha256.h" |
| #include <trusty/libtipc.h> |
| |
| extern int armv7_init_nonsec(void); |
| extern void trusty_os_init(void); |
| #endif |
| |
| |
| struct fastboot_device_info fastboot_devinfo = {0xff, 0xff}; |
| |
| #ifdef CONFIG_FLASH_MCUFIRMWARE_SUPPORT |
| struct fastboot_device_info fastboot_firmwareinfo; |
| #endif |
| |
| /** |
| * fastboot_none() - Skip the common write operation, nothing output. |
| * |
| * @response: Pointer to fastboot response buffer |
| */ |
| void fastboot_none_resp(char *response) |
| { |
| *response = 0; |
| } |
| |
| void board_fastboot_setup(void) |
| { |
| static char boot_dev_part[32]; |
| u32 dev_no; |
| |
| switch (get_boot_device()) { |
| 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 (!env_get("fastboot_dev")) |
| env_set("fastboot_dev", boot_dev_part); |
| sprintf(boot_dev_part, "boota mmc%d", dev_no); |
| if (!env_get("bootcmd")) |
| env_set("bootcmd", boot_dev_part); |
| break; |
| case USB_BOOT: |
| printf("Detect USB boot. Will enter fastboot mode!\n"); |
| if (!env_get("bootcmd")) |
| env_set("bootcmd", "fastboot 0"); |
| break; |
| default: |
| if (!env_get("bootcmd")) |
| printf("unsupported boot devices\n"); |
| break; |
| } |
| |
| /* add soc type into bootargs */ |
| if (is_mx6dqp()) { |
| if (!env_get("soc_type")) |
| env_set("soc_type", "imx6qp"); |
| } else if (is_mx6dq()) { |
| if (!env_get("soc_type")) |
| env_set("soc_type", "imx6q"); |
| } else if (is_mx6sdl()) { |
| if (!env_get("soc_type")) |
| env_set("soc_type", "imx6dl"); |
| } else if (is_mx6sx()) { |
| if (!env_get("soc_type")) |
| env_set("soc_type", "imx6sx"); |
| } else if (is_mx6sl()) { |
| if (!env_get("soc_type")) |
| env_set("soc_type", "imx6sl"); |
| } else if (is_mx6ul()) { |
| if (!env_get("soc_type")) |
| env_set("soc_type", "imx6ul"); |
| } else if (is_mx7()) { |
| if (!env_get("soc_type")) |
| env_set("soc_type", "imx7d"); |
| } else if (is_mx7ulp()) { |
| if (!env_get("soc_type")) |
| env_set("soc_type", "imx7ulp"); |
| } else if (is_imx8qm()) { |
| if (!env_get("soc_type")) |
| env_set("soc_type", "imx8qm"); |
| } else if (is_imx8qxp()) { |
| if (!env_get("soc_type")) |
| env_set("soc_type", "imx8qxp"); |
| } else if (is_imx8mq()) { |
| if (!env_get("soc_type")) |
| env_set("soc_type", "imx8mq"); |
| } else if (is_imx8mm()) { |
| if (!env_get("soc_type")) |
| env_set("soc_type", "imx8mm"); |
| } |
| } |
| |
| #ifdef CONFIG_ANDROID_RECOVERY |
| void board_recovery_setup(void) |
| { |
| /* boot from current mmc with avb verify */ |
| #ifdef CONFIG_AVB_SUPPORT |
| if (!env_get("bootcmd_android_recovery")) |
| env_set("bootcmd_android_recovery", "boota recovery"); |
| #else |
| static char boot_dev_part[32]; |
| u32 dev_no; |
| |
| int bootdev = get_boot_device(); |
| switch (bootdev) { |
| 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 (!env_get("bootcmd_android_recovery")) |
| env_set("bootcmd_android_recovery", boot_dev_part); |
| break; |
| default: |
| printf("Unsupported bootup device for recovery: dev: %d\n", |
| bootdev); |
| return; |
| } |
| #endif /* CONFIG_AVB_SUPPORT */ |
| printf("setup env for recovery..\n"); |
| env_set("bootcmd", env_get("bootcmd_android_recovery")); |
| } |
| #endif /*CONFIG_ANDROID_RECOVERY*/ |
| |
| #ifdef CONFIG_IMX_TRUSTY_OS |
| #ifdef CONFIG_ARM64 |
| void tee_setup(void) |
| { |
| trusty_ipc_init(); |
| } |
| |
| #else |
| extern bool tos_flashed; |
| |
| void tee_setup(void) |
| { |
| /* load tee from boot1 of eMMC. */ |
| int mmcc = mmc_get_env_dev(); |
| struct blk_desc *dev_desc = NULL; |
| |
| struct mmc *mmc; |
| mmc = find_mmc_device(mmcc); |
| if (!mmc) { |
| printf("boota: cannot find '%d' mmc device\n", mmcc); |
| goto fail; |
| } |
| |
| dev_desc = blk_get_dev("mmc", mmcc); |
| if (NULL == dev_desc) { |
| printf("** Block device MMC %d not supported\n", mmcc); |
| goto fail; |
| } |
| |
| /* below was i.MX mmc operation code */ |
| if (mmc_init(mmc)) { |
| printf("mmc%d init failed\n", mmcc); |
| goto fail; |
| } |
| |
| struct fastboot_ptentry *tee_pte; |
| char *tee_ptn = FASTBOOT_PARTITION_TEE; |
| tee_pte = fastboot_flash_find_ptn(tee_ptn); |
| mmc_switch_part(mmc, TEE_HWPARTITION_ID); |
| if (!tee_pte) { |
| printf("boota: cannot find tee partition!\n"); |
| fastboot_flash_dump_ptn(); |
| } |
| |
| if (blk_dread(dev_desc, tee_pte->start, |
| tee_pte->length, (void *)TRUSTY_OS_ENTRY) < 0) { |
| printf("Failed to load tee."); |
| } |
| mmc_switch_part(mmc, FASTBOOT_MMC_USER_PARTITION_ID); |
| |
| tos_flashed = false; |
| if(!valid_tos()) { |
| printf("TOS not flashed! Will enter TOS recovery mode. Everything will be wiped!\n"); |
| fastboot_wipe_all(); |
| run_command("fastboot 0", 0); |
| goto fail; |
| } |
| #ifdef NON_SECURE_FASTBOOT |
| armv7_init_nonsec(); |
| trusty_os_init(); |
| trusty_ipc_init(); |
| #endif |
| |
| fail: |
| return; |
| |
| } |
| #endif /* CONFIG_ARM64 */ |
| #endif /* CONFIG_IMX_TRUSTY_OS */ |
| |
| static int _fastboot_setup_dev(int *switched) |
| { |
| char *fastboot_env; |
| struct fastboot_device_info devinfo;; |
| fastboot_env = env_get("fastboot_dev"); |
| |
| if (fastboot_env) { |
| if (!strcmp(fastboot_env, "sata")) { |
| devinfo.type = DEV_SATA; |
| devinfo.dev_id = 0; |
| } else if (!strncmp(fastboot_env, "mmc", 3)) { |
| devinfo.type = DEV_MMC; |
| if(env_get("target_ubootdev")) |
| devinfo.dev_id = simple_strtoul(env_get("target_ubootdev"), NULL, 10); |
| else |
| devinfo.dev_id = mmc_get_env_dev(); |
| } else { |
| return 1; |
| } |
| } else { |
| return 1; |
| } |
| #ifdef CONFIG_FLASH_MCUFIRMWARE_SUPPORT |
| /* For imx7ulp, flash m4 images directly to spi nor-flash, M4 will |
| * run automatically after powered on. For imx8mq, flash m4 images to |
| * physical partition 'm4_os', m4 will be kicked off by A core. */ |
| fastboot_firmwareinfo.type = ANDROID_MCU_FRIMWARE_DEV_TYPE; |
| #endif |
| |
| if (switched) { |
| if (devinfo.type != fastboot_devinfo.type || devinfo.dev_id != fastboot_devinfo.dev_id) |
| *switched = 1; |
| else |
| *switched = 0; |
| } |
| |
| fastboot_devinfo.type = devinfo.type; |
| fastboot_devinfo.dev_id = devinfo.dev_id; |
| |
| return 0; |
| } |
| |
| void fastboot_setup(void) |
| { |
| int sw, ret; |
| struct tag_serialnr serialnr; |
| char serial[17]; |
| |
| get_board_serial(&serialnr); |
| sprintf(serial, "%08x%08x", serialnr.high, serialnr.low); |
| env_set("serial#", serial); |
| |
| /*execute board relevant initilizations for preparing fastboot */ |
| board_fastboot_setup(); |
| |
| /*get the fastboot dev*/ |
| ret = _fastboot_setup_dev(&sw); |
| |
| /*load partitions information for the fastboot dev*/ |
| if (!ret && sw) |
| fastboot_load_partitions(); |
| |
| fastboot_init(NULL, 0); |
| #ifdef CONFIG_AVB_SUPPORT |
| fsl_avb_ab_ops.ops = &fsl_avb_ops; |
| #ifdef CONFIG_AVB_ATX |
| fsl_avb_atx_ops.ops = &fsl_avb_ops; |
| #endif |
| #endif |
| } |