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 char slot_suffix[3] = {0}; 99 char slot_info[21] = "android_slotsufix="; 100 101 if (ab_get_slot_suffix(slot_suffix)) 102 goto out; 103 104 strcat(slot_info, slot_suffix); 105 env_update("bootargs", slot_info); 106 #endif 107 108 ret = do_bootm_states(NULL, 0, ARRAY_SIZE(bootm_args), bootm_args, 109 BOOTM_STATE_START | 110 BOOTM_STATE_FINDOS | BOOTM_STATE_FINDOTHER | 111 BOOTM_STATE_LOADOS | 112 #ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH 113 BOOTM_STATE_RAMDISK | 114 #endif 115 BOOTM_STATE_OS_PREP | BOOTM_STATE_OS_FAKE_GO | 116 BOOTM_STATE_OS_GO, &images, 1); 117 118 if (ret && argc != 1) { 119 fit_image_fail_process(fit); 120 goto out; 121 } 122 123 return CMD_RET_SUCCESS; 124 out: 125 return CMD_RET_FAILURE; 126 } 127 128 U_BOOT_CMD_ALWAYS( 129 boot_fit, 2, 1, do_boot_fit, 130 "Boot FIT Image from memory or boot/recovery partition", 131 "boot_fit [addr]" 132 ); 133