xref: /rk3399_rockchip-uboot/cmd/bootuimage.c (revision e39c2b5d453540cfd6be600b611d67811920d465)
1*e39c2b5dSJoseph Chen /*
2*e39c2b5dSJoseph Chen  * (C) Copyright 2019 Rockchip Electronics Co., Ltd
3*e39c2b5dSJoseph Chen  *
4*e39c2b5dSJoseph Chen  * SPDX-License-Identifier:     GPL-2.0+
5*e39c2b5dSJoseph Chen  */
6*e39c2b5dSJoseph Chen 
7*e39c2b5dSJoseph Chen #include <common.h>
8*e39c2b5dSJoseph Chen #include <bootm.h>
9*e39c2b5dSJoseph Chen #include <boot_rkimg.h>
10*e39c2b5dSJoseph Chen #include <console.h>
11*e39c2b5dSJoseph Chen #include <image.h>
12*e39c2b5dSJoseph Chen #include <malloc.h>
13*e39c2b5dSJoseph Chen #include <sysmem.h>
14*e39c2b5dSJoseph Chen #include <linux/libfdt.h>
15*e39c2b5dSJoseph Chen #include <asm/arch/hotkey.h>
16*e39c2b5dSJoseph Chen #include <asm/arch/resource_img.h>
17*e39c2b5dSJoseph Chen #include <asm/arch/boot_mode.h>
18*e39c2b5dSJoseph Chen #include <asm/arch/uimage.h>
19*e39c2b5dSJoseph Chen 
20*e39c2b5dSJoseph Chen DECLARE_GLOBAL_DATA_PTR;
21*e39c2b5dSJoseph Chen 
22*e39c2b5dSJoseph Chen static void *do_boot_uimage_storage(void)
23*e39c2b5dSJoseph Chen {
24*e39c2b5dSJoseph Chen 	return uimage_load_bootables();
25*e39c2b5dSJoseph Chen }
26*e39c2b5dSJoseph Chen 
27*e39c2b5dSJoseph Chen static void *do_boot_uimage_ram(char *const argv[])
28*e39c2b5dSJoseph Chen {
29*e39c2b5dSJoseph Chen 	image_header_t *hdr;
30*e39c2b5dSJoseph Chen 	int blknum;
31*e39c2b5dSJoseph Chen 
32*e39c2b5dSJoseph Chen 	hdr = (void *)simple_strtoul(argv[1], NULL, 16);
33*e39c2b5dSJoseph Chen 	if (!hdr || !image_check_magic(hdr)) {
34*e39c2b5dSJoseph Chen 		UIMG_I("Invalid header");
35*e39c2b5dSJoseph Chen 		return NULL;
36*e39c2b5dSJoseph Chen 	}
37*e39c2b5dSJoseph Chen 
38*e39c2b5dSJoseph Chen 	if (image_get_type(hdr) != IH_TYPE_MULTI) {
39*e39c2b5dSJoseph Chen 		UIMG_I("Invalid multi images\n");
40*e39c2b5dSJoseph Chen 		return NULL;
41*e39c2b5dSJoseph Chen 	}
42*e39c2b5dSJoseph Chen 
43*e39c2b5dSJoseph Chen 	/* reserve this full uImage */
44*e39c2b5dSJoseph Chen 	blknum = DIV_ROUND_UP(image_get_image_size(hdr), RK_BLK_SIZE);
45*e39c2b5dSJoseph Chen 	if (!sysmem_alloc_base(MEM_UIMAGE_USER, (phys_addr_t)hdr,
46*e39c2b5dSJoseph Chen 			       blknum * RK_BLK_SIZE))
47*e39c2b5dSJoseph Chen 		return NULL;
48*e39c2b5dSJoseph Chen 
49*e39c2b5dSJoseph Chen 	return hdr;
50*e39c2b5dSJoseph Chen }
51*e39c2b5dSJoseph Chen 
52*e39c2b5dSJoseph Chen static int do_boot_uimage(cmd_tbl_t *cmdtp, int flag,
53*e39c2b5dSJoseph Chen 			  int argc, char *const argv[])
54*e39c2b5dSJoseph Chen {
55*e39c2b5dSJoseph Chen 	char *bootm_args[1];
56*e39c2b5dSJoseph Chen 	image_header_t *img;
57*e39c2b5dSJoseph Chen 	char uimg_addr[12];
58*e39c2b5dSJoseph Chen 	int ret;
59*e39c2b5dSJoseph Chen 
60*e39c2b5dSJoseph Chen 	if (argc > 2)
61*e39c2b5dSJoseph Chen 		return CMD_RET_USAGE;
62*e39c2b5dSJoseph Chen 
63*e39c2b5dSJoseph Chen 	printf("\n## Booting Multi uImage ");
64*e39c2b5dSJoseph Chen 
65*e39c2b5dSJoseph Chen 	if (argc == 1)
66*e39c2b5dSJoseph Chen 		img = do_boot_uimage_storage();
67*e39c2b5dSJoseph Chen 	else
68*e39c2b5dSJoseph Chen 		img = do_boot_uimage_ram(argv);
69*e39c2b5dSJoseph Chen 
70*e39c2b5dSJoseph Chen 	if (!img) {
71*e39c2b5dSJoseph Chen 		UIMG_I("Failed to load multi images\n");
72*e39c2b5dSJoseph Chen 		return -EINVAL;
73*e39c2b5dSJoseph Chen 	}
74*e39c2b5dSJoseph Chen 
75*e39c2b5dSJoseph Chen 	if (uimage_sysmem_reserve_each(img))
76*e39c2b5dSJoseph Chen 		return -ENOMEM;
77*e39c2b5dSJoseph Chen 
78*e39c2b5dSJoseph Chen 	snprintf(uimg_addr, sizeof(uimg_addr), "0x%lx", (ulong)img);
79*e39c2b5dSJoseph Chen 	bootm_args[0] = uimg_addr;
80*e39c2b5dSJoseph Chen 
81*e39c2b5dSJoseph Chen 	printf("at %s\n", uimg_addr);
82*e39c2b5dSJoseph Chen 
83*e39c2b5dSJoseph Chen 	ret = do_bootm_states(NULL, 0, ARRAY_SIZE(bootm_args), bootm_args,
84*e39c2b5dSJoseph Chen 		BOOTM_STATE_START |
85*e39c2b5dSJoseph Chen 		BOOTM_STATE_FINDOS | BOOTM_STATE_FINDOTHER |
86*e39c2b5dSJoseph Chen 		BOOTM_STATE_LOADOS |
87*e39c2b5dSJoseph Chen #ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH
88*e39c2b5dSJoseph Chen 		BOOTM_STATE_RAMDISK |
89*e39c2b5dSJoseph Chen #endif
90*e39c2b5dSJoseph Chen 		BOOTM_STATE_OS_PREP | BOOTM_STATE_OS_FAKE_GO |
91*e39c2b5dSJoseph Chen 		BOOTM_STATE_OS_GO, &images, 1);
92*e39c2b5dSJoseph Chen 
93*e39c2b5dSJoseph Chen 	if (ret && argc != 1)
94*e39c2b5dSJoseph Chen 		uimage_sysmem_free_each(img);
95*e39c2b5dSJoseph Chen 
96*e39c2b5dSJoseph Chen 	return ret;
97*e39c2b5dSJoseph Chen }
98*e39c2b5dSJoseph Chen 
99*e39c2b5dSJoseph Chen U_BOOT_CMD(
100*e39c2b5dSJoseph Chen 	boot_uimage,  2,     1,      do_boot_uimage,
101*e39c2b5dSJoseph Chen 	"Boot Legacy uImage from memory or boot(recovery) partitions",
102*e39c2b5dSJoseph Chen 	"boot_uimage [addr]"
103*e39c2b5dSJoseph Chen );
104