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