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