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