1 /* 2 * (C) Copyright 2019 Rockchip Electronics Co., Ltd 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 7 #include <common.h> 8 #include <android_ab.h> 9 #include <bootm.h> 10 #include <boot_rkimg.h> 11 #include <image.h> 12 #include <malloc.h> 13 #include <sysmem.h> 14 #include <asm/arch/fit.h> 15 16 DECLARE_GLOBAL_DATA_PTR; 17 18 static void *do_boot_fit_storage(ulong *size) 19 { 20 return fit_image_load_bootables(size); 21 } 22 23 static void *do_boot_fit_ram(char *const argv[], ulong *data_size) 24 { 25 void *fit; 26 int size; 27 28 fit = (void *)simple_strtoul(argv[1], NULL, 16); 29 if (!fit || fdt_check_header(fit)) { 30 FIT_I("Invalid header\n"); 31 return NULL; 32 } 33 34 size = fit_image_get_bootables_size(fit); 35 if (!size) { 36 FIT_I("Failed to get bootable image size\n"); 37 return NULL; 38 } 39 40 /* reserve this full FIT image */ 41 if (!sysmem_alloc_base(MEM_FIT_USER, 42 (phys_addr_t)fit, ALIGN(size, 512))) 43 return NULL; 44 45 *data_size = size; 46 47 return fit; 48 } 49 50 /* 51 * argc == 1: 52 * FIT image is loaded from storage(eg. CONFIG_BOOTCOMMAND). 53 * 54 * argc == 2: 55 * FIT image is already in ram, the booflow is: 56 * CLI cmd "bootm <fit_addr>" => do_bootm() => 57 * board_do_bootm() => boot_fit <fit_addr> 58 */ 59 static int do_boot_fit(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) 60 { 61 char *bootm_args[1]; 62 char fit_addr[12]; 63 ulong size; 64 void *fit; 65 int ret; 66 67 if (argc > 2) 68 return CMD_RET_USAGE; 69 70 printf("## Booting FIT Image "); 71 72 if (argc == 1) 73 fit = do_boot_fit_storage(&size); 74 else 75 fit = do_boot_fit_ram(argv, &size); 76 77 if (!fit) { 78 FIT_I("No FIT image\n"); 79 goto out; 80 } 81 82 if (fdt_check_header(fit)) { 83 FIT_I("Invalid FIT format\n"); 84 goto out; 85 } 86 87 /* fixup entry/load and alloc sysmem */ 88 if (fit_image_pre_process(fit)) 89 goto out; 90 91 env_set("bootm-no-reloc", "y"); 92 snprintf(fit_addr, sizeof(fit_addr), "0x%lx", (ulong)fit); 93 bootm_args[0] = fit_addr; 94 95 printf("at %s with size 0x%08lx\n", fit_addr, size); 96 97 #ifdef CONFIG_ANDROID_AB 98 ab_update_root_uuid(); 99 if (ab_decrease_tries()) 100 printf("Decrease ab tries count fail!\n"); 101 #endif 102 103 ret = do_bootm_states(NULL, 0, ARRAY_SIZE(bootm_args), bootm_args, 104 BOOTM_STATE_START | 105 BOOTM_STATE_FINDOS | BOOTM_STATE_FINDOTHER | 106 BOOTM_STATE_LOADOS | 107 #ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH 108 BOOTM_STATE_RAMDISK | 109 #endif 110 BOOTM_STATE_OS_PREP | BOOTM_STATE_OS_FAKE_GO | 111 BOOTM_STATE_OS_GO, &images, 1); 112 113 if (ret && argc != 1) { 114 fit_image_fail_process(fit); 115 goto out; 116 } 117 118 return CMD_RET_SUCCESS; 119 out: 120 return CMD_RET_FAILURE; 121 } 122 123 U_BOOT_CMD_ALWAYS( 124 boot_fit, 2, 1, do_boot_fit, 125 "Boot FIT Image from memory or boot/recovery partition", 126 "boot_fit [addr]" 127 ); 128