xref: /rk3399_rockchip-uboot/cmd/bootfit.c (revision cd1c982e9a20e1f221cc1158f81fc40d9d0af0c2)
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_ALWAYS(
117 	boot_fit,  2,     1,      do_boot_fit,
118 	"Boot FIT Image from memory or boot/recovery partition",
119 	"boot_fit [addr]"
120 );
121