xref: /OK3568_Linux_fs/u-boot/cmd/bootfit.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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 
do_boot_fit_storage(ulong * size)18 static void *do_boot_fit_storage(ulong *size)
19 {
20 	return fit_image_load_bootables(size);
21 }
22 
do_boot_fit_ram(char * const argv[],ulong * data_size)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  */
do_boot_fit(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])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