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