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