1a0e58cf2SKever Yang /* 2a0e58cf2SKever Yang * (C) Copyright 2017 Rockchip Electronics Co., Ltd 3a0e58cf2SKever Yang * 4a0e58cf2SKever Yang * SPDX-License-Identifier: GPL-2.0+ 5a0e58cf2SKever Yang */ 6a0e58cf2SKever Yang 7a0e58cf2SKever Yang #include <common.h> 8e72b9125SJoseph Chen #include <attestation_key.h> 9e72b9125SJoseph Chen #include <bootm.h> 1014768307SJoseph Chen #include <boot_rkimg.h> 1114768307SJoseph Chen #include <keymaster.h> 12e72b9125SJoseph Chen #include <console.h> 13e72b9125SJoseph Chen #include <image.h> 146caa0333SKever Yang #include <malloc.h> 15e72b9125SJoseph Chen #include <sysmem.h> 16e72b9125SJoseph Chen #include <linux/libfdt.h> 17e72b9125SJoseph Chen #include <asm/arch/hotkey.h> 18e72b9125SJoseph Chen #include <asm/arch/resource_img.h> 19e72b9125SJoseph Chen #include <asm/arch/boot_mode.h> 20a0e58cf2SKever Yang 21e72b9125SJoseph Chen DECLARE_GLOBAL_DATA_PTR; 22e72b9125SJoseph Chen 23e72b9125SJoseph Chen #ifdef CONFIG_ROCKCHIP_CRC 24e72b9125SJoseph Chen #define tole(x) cpu_to_le32(x) 25e72b9125SJoseph Chen 26e72b9125SJoseph Chen /* Table of CRC-32's of all single-byte values (made by make_crc_table) */ 27e72b9125SJoseph Chen static const uint32_t crc_table[256] = { 28e72b9125SJoseph Chen tole(0x00000000L), tole(0x04c10db7L), tole(0x09821b6eL), tole(0x0d4316d9L), 29e72b9125SJoseph Chen tole(0x130436dcL), tole(0x17c53b6bL), tole(0x1a862db2L), tole(0x1e472005L), 30e72b9125SJoseph Chen tole(0x26086db8L), tole(0x22c9600fL), tole(0x2f8a76d6L), tole(0x2b4b7b61L), 31e72b9125SJoseph Chen tole(0x350c5b64L), tole(0x31cd56d3L), tole(0x3c8e400aL), tole(0x384f4dbdL), 32e72b9125SJoseph Chen tole(0x4c10db70L), tole(0x48d1d6c7L), tole(0x4592c01eL), tole(0x4153cda9L), 33e72b9125SJoseph Chen tole(0x5f14edacL), tole(0x5bd5e01bL), tole(0x5696f6c2L), tole(0x5257fb75L), 34e72b9125SJoseph Chen tole(0x6a18b6c8L), tole(0x6ed9bb7fL), tole(0x639aada6L), tole(0x675ba011L), 35e72b9125SJoseph Chen tole(0x791c8014L), tole(0x7ddd8da3L), tole(0x709e9b7aL), tole(0x745f96cdL), 36e72b9125SJoseph Chen tole(0x9821b6e0L), tole(0x9ce0bb57L), tole(0x91a3ad8eL), tole(0x9562a039L), 37e72b9125SJoseph Chen tole(0x8b25803cL), tole(0x8fe48d8bL), tole(0x82a79b52L), tole(0x866696e5L), 38e72b9125SJoseph Chen tole(0xbe29db58L), tole(0xbae8d6efL), tole(0xb7abc036L), tole(0xb36acd81L), 39e72b9125SJoseph Chen tole(0xad2ded84L), tole(0xa9ece033L), tole(0xa4aff6eaL), tole(0xa06efb5dL), 40e72b9125SJoseph Chen tole(0xd4316d90L), tole(0xd0f06027L), tole(0xddb376feL), tole(0xd9727b49L), 41e72b9125SJoseph Chen tole(0xc7355b4cL), tole(0xc3f456fbL), tole(0xceb74022L), tole(0xca764d95L), 42e72b9125SJoseph Chen tole(0xf2390028L), tole(0xf6f80d9fL), tole(0xfbbb1b46L), tole(0xff7a16f1L), 43e72b9125SJoseph Chen tole(0xe13d36f4L), tole(0xe5fc3b43L), tole(0xe8bf2d9aL), tole(0xec7e202dL), 44e72b9125SJoseph Chen tole(0x34826077L), tole(0x30436dc0L), tole(0x3d007b19L), tole(0x39c176aeL), 45e72b9125SJoseph Chen tole(0x278656abL), tole(0x23475b1cL), tole(0x2e044dc5L), tole(0x2ac54072L), 46e72b9125SJoseph Chen tole(0x128a0dcfL), tole(0x164b0078L), tole(0x1b0816a1L), tole(0x1fc91b16L), 47e72b9125SJoseph Chen tole(0x018e3b13L), tole(0x054f36a4L), tole(0x080c207dL), tole(0x0ccd2dcaL), 48e72b9125SJoseph Chen tole(0x7892bb07L), tole(0x7c53b6b0L), tole(0x7110a069L), tole(0x75d1addeL), 49e72b9125SJoseph Chen tole(0x6b968ddbL), tole(0x6f57806cL), tole(0x621496b5L), tole(0x66d59b02L), 50e72b9125SJoseph Chen tole(0x5e9ad6bfL), tole(0x5a5bdb08L), tole(0x5718cdd1L), tole(0x53d9c066L), 51e72b9125SJoseph Chen tole(0x4d9ee063L), tole(0x495fedd4L), tole(0x441cfb0dL), tole(0x40ddf6baL), 52e72b9125SJoseph Chen tole(0xaca3d697L), tole(0xa862db20L), tole(0xa521cdf9L), tole(0xa1e0c04eL), 53e72b9125SJoseph Chen tole(0xbfa7e04bL), tole(0xbb66edfcL), tole(0xb625fb25L), tole(0xb2e4f692L), 54e72b9125SJoseph Chen tole(0x8aabbb2fL), tole(0x8e6ab698L), tole(0x8329a041L), tole(0x87e8adf6L), 55e72b9125SJoseph Chen tole(0x99af8df3L), tole(0x9d6e8044L), tole(0x902d969dL), tole(0x94ec9b2aL), 56e72b9125SJoseph Chen tole(0xe0b30de7L), tole(0xe4720050L), tole(0xe9311689L), tole(0xedf01b3eL), 57e72b9125SJoseph Chen tole(0xf3b73b3bL), tole(0xf776368cL), tole(0xfa352055L), tole(0xfef42de2L), 58e72b9125SJoseph Chen tole(0xc6bb605fL), tole(0xc27a6de8L), tole(0xcf397b31L), tole(0xcbf87686L), 59e72b9125SJoseph Chen tole(0xd5bf5683L), tole(0xd17e5b34L), tole(0xdc3d4dedL), tole(0xd8fc405aL), 60e72b9125SJoseph Chen tole(0x6904c0eeL), tole(0x6dc5cd59L), tole(0x6086db80L), tole(0x6447d637L), 61e72b9125SJoseph Chen tole(0x7a00f632L), tole(0x7ec1fb85L), tole(0x7382ed5cL), tole(0x7743e0ebL), 62e72b9125SJoseph Chen tole(0x4f0cad56L), tole(0x4bcda0e1L), tole(0x468eb638L), tole(0x424fbb8fL), 63e72b9125SJoseph Chen tole(0x5c089b8aL), tole(0x58c9963dL), tole(0x558a80e4L), tole(0x514b8d53L), 64e72b9125SJoseph Chen tole(0x25141b9eL), tole(0x21d51629L), tole(0x2c9600f0L), tole(0x28570d47L), 65e72b9125SJoseph Chen tole(0x36102d42L), tole(0x32d120f5L), tole(0x3f92362cL), tole(0x3b533b9bL), 66e72b9125SJoseph Chen tole(0x031c7626L), tole(0x07dd7b91L), tole(0x0a9e6d48L), tole(0x0e5f60ffL), 67e72b9125SJoseph Chen tole(0x101840faL), tole(0x14d94d4dL), tole(0x199a5b94L), tole(0x1d5b5623L), 68e72b9125SJoseph Chen tole(0xf125760eL), tole(0xf5e47bb9L), tole(0xf8a76d60L), tole(0xfc6660d7L), 69e72b9125SJoseph Chen tole(0xe22140d2L), tole(0xe6e04d65L), tole(0xeba35bbcL), tole(0xef62560bL), 70e72b9125SJoseph Chen tole(0xd72d1bb6L), tole(0xd3ec1601L), tole(0xdeaf00d8L), tole(0xda6e0d6fL), 71e72b9125SJoseph Chen tole(0xc4292d6aL), tole(0xc0e820ddL), tole(0xcdab3604L), tole(0xc96a3bb3L), 72e72b9125SJoseph Chen tole(0xbd35ad7eL), tole(0xb9f4a0c9L), tole(0xb4b7b610L), tole(0xb076bba7L), 73e72b9125SJoseph Chen tole(0xae319ba2L), tole(0xaaf09615L), tole(0xa7b380ccL), tole(0xa3728d7bL), 74e72b9125SJoseph Chen tole(0x9b3dc0c6L), tole(0x9ffccd71L), tole(0x92bfdba8L), tole(0x967ed61fL), 75e72b9125SJoseph Chen tole(0x8839f61aL), tole(0x8cf8fbadL), tole(0x81bbed74L), tole(0x857ae0c3L), 76e72b9125SJoseph Chen tole(0x5d86a099L), tole(0x5947ad2eL), tole(0x5404bbf7L), tole(0x50c5b640L), 77e72b9125SJoseph Chen tole(0x4e829645L), tole(0x4a439bf2L), tole(0x47008d2bL), tole(0x43c1809cL), 78e72b9125SJoseph Chen tole(0x7b8ecd21L), tole(0x7f4fc096L), tole(0x720cd64fL), tole(0x76cddbf8L), 79e72b9125SJoseph Chen tole(0x688afbfdL), tole(0x6c4bf64aL), tole(0x6108e093L), tole(0x65c9ed24L), 80e72b9125SJoseph Chen tole(0x11967be9L), tole(0x1557765eL), tole(0x18146087L), tole(0x1cd56d30L), 81e72b9125SJoseph Chen tole(0x02924d35L), tole(0x06534082L), tole(0x0b10565bL), tole(0x0fd15becL), 82e72b9125SJoseph Chen tole(0x379e1651L), tole(0x335f1be6L), tole(0x3e1c0d3fL), tole(0x3add0088L), 83e72b9125SJoseph Chen tole(0x249a208dL), tole(0x205b2d3aL), tole(0x2d183be3L), tole(0x29d93654L), 84e72b9125SJoseph Chen tole(0xc5a71679L), tole(0xc1661bceL), tole(0xcc250d17L), tole(0xc8e400a0L), 85e72b9125SJoseph Chen tole(0xd6a320a5L), tole(0xd2622d12L), tole(0xdf213bcbL), tole(0xdbe0367cL), 86e72b9125SJoseph Chen tole(0xe3af7bc1L), tole(0xe76e7676L), tole(0xea2d60afL), tole(0xeeec6d18L), 87e72b9125SJoseph Chen tole(0xf0ab4d1dL), tole(0xf46a40aaL), tole(0xf9295673L), tole(0xfde85bc4L), 88e72b9125SJoseph Chen tole(0x89b7cd09L), tole(0x8d76c0beL), tole(0x8035d667L), tole(0x84f4dbd0L), 89e72b9125SJoseph Chen tole(0x9ab3fbd5L), tole(0x9e72f662L), tole(0x9331e0bbL), tole(0x97f0ed0cL), 90e72b9125SJoseph Chen tole(0xafbfa0b1L), tole(0xab7ead06L), tole(0xa63dbbdfL), tole(0xa2fcb668L), 91e72b9125SJoseph Chen tole(0xbcbb966dL), tole(0xb87a9bdaL), tole(0xb5398d03L), tole(0xb1f880b4L) 92e72b9125SJoseph Chen }; 93e72b9125SJoseph Chen 94e72b9125SJoseph Chen #define DO_CRC(x) crc = tab[((crc >> 24) ^ (x)) & 255] ^ (crc << 8) 95e72b9125SJoseph Chen 96e72b9125SJoseph Chen static uint32_t crc32_rk(uint32_t crc, const unsigned char *s, uint32_t len) 97a0e58cf2SKever Yang { 98e72b9125SJoseph Chen const uint32_t *tab; 99e72b9125SJoseph Chen 100e72b9125SJoseph Chen tab = crc_table; 101e72b9125SJoseph Chen crc = cpu_to_le32(crc); 102e72b9125SJoseph Chen 103e72b9125SJoseph Chen do { 104e72b9125SJoseph Chen DO_CRC(*s++); 105e72b9125SJoseph Chen } while (--len); 106e72b9125SJoseph Chen 107e72b9125SJoseph Chen return le32_to_cpu(crc); 108e72b9125SJoseph Chen } 109e72b9125SJoseph Chen 110e72b9125SJoseph Chen #undef DO_CRC 111e72b9125SJoseph Chen 112e72b9125SJoseph Chen static u32 crc32_verify(unsigned char *data, u32 size) 113e72b9125SJoseph Chen { 114e72b9125SJoseph Chen u32 crc_check = 0, crc_calc = 0; 115e72b9125SJoseph Chen int i = 0; 116e72b9125SJoseph Chen 117e72b9125SJoseph Chen if (size <= 4) 118e72b9125SJoseph Chen return 0; 119e72b9125SJoseph Chen 120e72b9125SJoseph Chen size -= 4; 121e72b9125SJoseph Chen for (i = 3; i >= 0; i--) 122e72b9125SJoseph Chen crc_check = (crc_check << 8) + (*(data + size + i)); 123e72b9125SJoseph Chen 124e72b9125SJoseph Chen crc_calc = crc32_rk(0, data, size); 125e72b9125SJoseph Chen 126e72b9125SJoseph Chen return (crc_calc == crc_check) ? crc_check : 0; 127e72b9125SJoseph Chen } 128e72b9125SJoseph Chen #endif 129e72b9125SJoseph Chen 130e72b9125SJoseph Chen #if !defined(CONFIG_ARM64) 131e72b9125SJoseph Chen #ifdef CONFIG_LMB 132e72b9125SJoseph Chen static void boot_start_lmb(bootm_headers_t *images) 133e72b9125SJoseph Chen { 134e72b9125SJoseph Chen lmb_init(&images->lmb); 135e72b9125SJoseph Chen #ifdef CONFIG_NR_DRAM_BANKS 136e72b9125SJoseph Chen int i; 137e72b9125SJoseph Chen 138e72b9125SJoseph Chen for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { 139e72b9125SJoseph Chen lmb_add(&images->lmb, gd->bd->bi_dram[i].start, 140e72b9125SJoseph Chen gd->bd->bi_dram[i].size); 141e72b9125SJoseph Chen } 142e72b9125SJoseph Chen #else 143e72b9125SJoseph Chen ulong mem_start; 144e72b9125SJoseph Chen phys_size_t mem_size; 145e72b9125SJoseph Chen 146e72b9125SJoseph Chen mem_start = env_get_bootm_low(); 147e72b9125SJoseph Chen mem_size = env_get_bootm_size(); 148e72b9125SJoseph Chen lmb_add(&images->lmb, (phys_addr_t)mem_start, mem_size); 149e72b9125SJoseph Chen #endif 150e72b9125SJoseph Chen arch_lmb_reserve(&images->lmb); 151e72b9125SJoseph Chen board_lmb_reserve(&images->lmb); 152e72b9125SJoseph Chen } 153e72b9125SJoseph Chen #else 154e72b9125SJoseph Chen static inline void boot_start_lmb(bootm_headers_t *images) { } 155e72b9125SJoseph Chen #endif 156e72b9125SJoseph Chen 157e72b9125SJoseph Chen static void boot_lmb_init(bootm_headers_t *images) 158e72b9125SJoseph Chen { 159e72b9125SJoseph Chen boot_start_lmb(images); 160e72b9125SJoseph Chen images->state = BOOTM_STATE_OS_GO; 161e72b9125SJoseph Chen } 162e72b9125SJoseph Chen #endif 163e72b9125SJoseph Chen 164e72b9125SJoseph Chen static void fdt_ramdisk_skip_relocation(void) 165e72b9125SJoseph Chen { 166e72b9125SJoseph Chen char *ramdisk_high = env_get("initrd_high"); 167e72b9125SJoseph Chen char *fdt_high = env_get("fdt_high"); 168e72b9125SJoseph Chen 169e72b9125SJoseph Chen if (!fdt_high) { 170e72b9125SJoseph Chen env_set_hex("fdt_high", -1UL); 171e72b9125SJoseph Chen printf("Fdt "); 172e72b9125SJoseph Chen } 173e72b9125SJoseph Chen 174e72b9125SJoseph Chen if (!ramdisk_high) { 175e72b9125SJoseph Chen env_set_hex("initrd_high", -1UL); 176e72b9125SJoseph Chen printf("Ramdisk "); 177e72b9125SJoseph Chen } 178e72b9125SJoseph Chen 179e72b9125SJoseph Chen if (!fdt_high || !ramdisk_high) 180e72b9125SJoseph Chen printf("skip relocation\n"); 181e72b9125SJoseph Chen } 182e72b9125SJoseph Chen 183e72b9125SJoseph Chen /* 184e72b9125SJoseph Chen * non-OTA packaged kernel.img & boot.img return the image size on success, 185e72b9125SJoseph Chen * and a negative value on error. 186e72b9125SJoseph Chen */ 187e72b9125SJoseph Chen static int read_rockchip_image(struct blk_desc *dev_desc, 188e72b9125SJoseph Chen disk_partition_t *part, void *dst) 189e72b9125SJoseph Chen { 190e72b9125SJoseph Chen struct rockchip_image *img; 191e72b9125SJoseph Chen int header_len = 8; 192e72b9125SJoseph Chen int cnt, ret; 193e72b9125SJoseph Chen #ifdef CONFIG_ROCKCHIP_CRC 194e72b9125SJoseph Chen u32 crc32; 195e72b9125SJoseph Chen #endif 196e72b9125SJoseph Chen 197e72b9125SJoseph Chen img = memalign(ARCH_DMA_MINALIGN, RK_BLK_SIZE); 198e72b9125SJoseph Chen if (!img) 199e72b9125SJoseph Chen return -ENOMEM; 200e72b9125SJoseph Chen 201e72b9125SJoseph Chen /* read first block with header imformation */ 202e72b9125SJoseph Chen ret = blk_dread(dev_desc, part->start, 1, img); 203e72b9125SJoseph Chen if (ret != 1) { 204e72b9125SJoseph Chen ret = -EIO; 205e72b9125SJoseph Chen goto err; 206e72b9125SJoseph Chen } 207e72b9125SJoseph Chen 208e72b9125SJoseph Chen if (img->tag != TAG_KERNEL) { 209e72b9125SJoseph Chen printf("Invalid %s image tag(0x%x)\n", part->name, img->tag); 210e72b9125SJoseph Chen ret = -EINVAL; 211e72b9125SJoseph Chen goto err; 212e72b9125SJoseph Chen } 213e72b9125SJoseph Chen 214e72b9125SJoseph Chen /* 215e72b9125SJoseph Chen * read the rest blks 216e72b9125SJoseph Chen * total size = image size + 8 bytes header + 4 bytes crc32 217e72b9125SJoseph Chen */ 218e72b9125SJoseph Chen cnt = DIV_ROUND_UP(img->size + 8 + 4, RK_BLK_SIZE); 219e72b9125SJoseph Chen if (!sysmem_alloc_base_by_name((const char *)part->name, 220e72b9125SJoseph Chen (phys_addr_t)dst, 221e72b9125SJoseph Chen cnt * dev_desc->blksz)) { 222e72b9125SJoseph Chen ret = -ENXIO; 223e72b9125SJoseph Chen goto err; 224e72b9125SJoseph Chen } 225e72b9125SJoseph Chen 226e72b9125SJoseph Chen memcpy(dst, img->image, RK_BLK_SIZE - header_len); 227e72b9125SJoseph Chen ret = blk_dread(dev_desc, part->start + 1, cnt - 1, 228e72b9125SJoseph Chen dst + RK_BLK_SIZE - header_len); 229e72b9125SJoseph Chen if (ret != (cnt - 1)) { 230e72b9125SJoseph Chen printf("Failed to read %s part, ret=%d\n", part->name, ret); 231e72b9125SJoseph Chen ret = -EIO; 232e72b9125SJoseph Chen } else { 233e72b9125SJoseph Chen ret = img->size; 234e72b9125SJoseph Chen } 235e72b9125SJoseph Chen 236e72b9125SJoseph Chen #ifdef CONFIG_ROCKCHIP_CRC 237e72b9125SJoseph Chen printf("%s image rk crc32 verify... ", part->name); 238e72b9125SJoseph Chen crc32 = crc32_verify((uchar *)(ulong)dst, img->size + 4); 239e72b9125SJoseph Chen if (!crc32) { 240e72b9125SJoseph Chen printf("fail!\n"); 241e72b9125SJoseph Chen ret = -EINVAL; 242e72b9125SJoseph Chen } else { 243e72b9125SJoseph Chen printf("okay.\n"); 244e72b9125SJoseph Chen } 245e72b9125SJoseph Chen #endif 246e72b9125SJoseph Chen 247e72b9125SJoseph Chen err: 248e72b9125SJoseph Chen free(img); 249e72b9125SJoseph Chen return ret; 250e72b9125SJoseph Chen } 251e72b9125SJoseph Chen 252e72b9125SJoseph Chen static int boot_rockchip_image(struct blk_desc *dev_desc, 253e72b9125SJoseph Chen disk_partition_t *boot_part) 254e72b9125SJoseph Chen { 255e72b9125SJoseph Chen disk_partition_t kernel_part; 256e72b9125SJoseph Chen ulong ramdisk_addr_r; 257e72b9125SJoseph Chen ulong kernel_addr_r; 258e72b9125SJoseph Chen ulong fdt_addr_r; 259e72b9125SJoseph Chen int ramdisk_size; 260e72b9125SJoseph Chen int kernel_size; 261e72b9125SJoseph Chen int fdt_size; 262e72b9125SJoseph Chen int ret; 263e72b9125SJoseph Chen 264e72b9125SJoseph Chen printf("\n## Booting Rockchip Format Image\n"); 265e72b9125SJoseph Chen 266e72b9125SJoseph Chen ramdisk_addr_r = env_get_ulong("ramdisk_addr_r", 16, 0); 267e72b9125SJoseph Chen kernel_addr_r = env_get_ulong("kernel_addr_r", 16, 0); 268e72b9125SJoseph Chen fdt_addr_r = env_get_ulong("fdt_addr_r", 16, 0); 269e72b9125SJoseph Chen 270e72b9125SJoseph Chen ret = part_get_info_by_name(dev_desc, PART_KERNEL, &kernel_part); 271e72b9125SJoseph Chen if (ret < 0) { 272e72b9125SJoseph Chen printf("Could not find kernel partition, ret=%d\n", ret); 273e72b9125SJoseph Chen return -EINVAL; 274e72b9125SJoseph Chen } 275e72b9125SJoseph Chen 276e72b9125SJoseph Chen kernel_size = read_rockchip_image(dev_desc, &kernel_part, 277e72b9125SJoseph Chen (void *)kernel_addr_r); 278e72b9125SJoseph Chen if (kernel_size < 0) { 279e72b9125SJoseph Chen printf("Failed to read kernel image, ret=%d\n", ret); 280e72b9125SJoseph Chen return -EINVAL; 281e72b9125SJoseph Chen } 282e72b9125SJoseph Chen 283e72b9125SJoseph Chen ramdisk_size = read_rockchip_image(dev_desc, boot_part, 284e72b9125SJoseph Chen (void *)ramdisk_addr_r); 285e72b9125SJoseph Chen if (ramdisk_size < 0) 286e72b9125SJoseph Chen ramdisk_size = 0; 287e72b9125SJoseph Chen 288e72b9125SJoseph Chen if (gd->fdt_blob != (void *)fdt_addr_r) { 289e72b9125SJoseph Chen fdt_size = rockchip_read_dtb_file((void *)fdt_addr_r); 290e72b9125SJoseph Chen if (fdt_size < 0) { 291e72b9125SJoseph Chen printf("Failed to read fdt, ret=%d\n", fdt_size); 292e72b9125SJoseph Chen return -EINVAL; 293e72b9125SJoseph Chen } 294e72b9125SJoseph Chen } 295e72b9125SJoseph Chen 296e72b9125SJoseph Chen printf("fdt @ 0x%08lx (0x%08x)\n", fdt_addr_r, fdt_totalsize(fdt_addr_r)); 297e72b9125SJoseph Chen printf("kernel @ 0x%08lx (0x%08x)\n", kernel_addr_r, kernel_size); 298e72b9125SJoseph Chen printf("ramdisk @ 0x%08lx (0x%08x)\n", ramdisk_addr_r, ramdisk_size); 299e72b9125SJoseph Chen 300e72b9125SJoseph Chen fdt_ramdisk_skip_relocation(); 301e72b9125SJoseph Chen hotkey_run(HK_SYSMEM); 302e72b9125SJoseph Chen sysmem_overflow_check(); 303e72b9125SJoseph Chen 304e72b9125SJoseph Chen #if defined(CONFIG_ARM64) 305e72b9125SJoseph Chen char cmdbuf[64]; 306e72b9125SJoseph Chen 307e72b9125SJoseph Chen snprintf(cmdbuf, 64, "booti 0x%lx 0x%lx:0x%x 0x%lx", 308e72b9125SJoseph Chen kernel_addr_r, ramdisk_addr_r, ramdisk_size, fdt_addr_r); 309e72b9125SJoseph Chen run_command(cmdbuf, 0); 310e72b9125SJoseph Chen #else 311e72b9125SJoseph Chen /* We asume it's always zImage on 32-bit platform */ 312e72b9125SJoseph Chen ulong kaddr_c = env_get_ulong("kernel_addr_c", 16, 0); 313e72b9125SJoseph Chen ulong kaddr_r, kaddr, ksize; 314e72b9125SJoseph Chen 315e72b9125SJoseph Chen if (kernel_addr_r && !kaddr_c) { 316e72b9125SJoseph Chen kaddr_c = kernel_addr_r; 317e72b9125SJoseph Chen kaddr_r = CONFIG_SYS_SDRAM_BASE; 318e72b9125SJoseph Chen } 319e72b9125SJoseph Chen 320e72b9125SJoseph Chen if (!sysmem_free((phys_addr_t)kaddr_c)) { 321e72b9125SJoseph Chen kaddr = kaddr_r; 322e72b9125SJoseph Chen ksize = kernel_size * 100 / 45 ; /* Ratio: 45% */ 323e72b9125SJoseph Chen ksize = ALIGN(ksize, dev_desc->blksz); 324*c01d4489SJoseph Chen if (!sysmem_alloc_base(MEM_UNCOMP_KERNEL, 325e72b9125SJoseph Chen (phys_addr_t)kaddr, ksize)) 326e72b9125SJoseph Chen return -ENOMEM; 327e72b9125SJoseph Chen } 328e72b9125SJoseph Chen 329e72b9125SJoseph Chen hotkey_run(HK_SYSMEM); 330e72b9125SJoseph Chen sysmem_overflow_check(); 331e72b9125SJoseph Chen 332e72b9125SJoseph Chen boot_lmb_init(&images); 333e72b9125SJoseph Chen images.ep = kernel_addr_r; 334e72b9125SJoseph Chen images.initrd_start = ramdisk_addr_r; 335e72b9125SJoseph Chen images.initrd_end = ramdisk_addr_r + ramdisk_size; 336e72b9125SJoseph Chen images.ft_addr = (void *)fdt_addr_r; 337e72b9125SJoseph Chen images.ft_len = fdt_totalsize(fdt_addr_r); 338e72b9125SJoseph Chen do_bootm_linux(0, 0, NULL, &images); 339e72b9125SJoseph Chen #endif 340e72b9125SJoseph Chen 341e72b9125SJoseph Chen return 0; 342e72b9125SJoseph Chen } 343e72b9125SJoseph Chen 344e72b9125SJoseph Chen static int do_boot_rockchip(cmd_tbl_t *cmdtp, int flag, 345e72b9125SJoseph Chen int argc, char *const argv[]) 346e72b9125SJoseph Chen { 347e72b9125SJoseph Chen char *part_name = PART_BOOT; 348a0e58cf2SKever Yang struct blk_desc *dev_desc; 349e72b9125SJoseph Chen disk_partition_t part; 350e72b9125SJoseph Chen int ret; 351a0e58cf2SKever Yang 352a0e58cf2SKever Yang dev_desc = rockchip_get_bootdev(); 3536651d4c0SJason Zhu if (!dev_desc) { 354e72b9125SJoseph Chen printf("dev_desc is NULL!\n"); 3554701d790SAndy Yan return CMD_RET_FAILURE; 3566651d4c0SJason Zhu } 35791c73fb4Sqiujian 358c2ba77d9SJian Qiu #ifdef CONFIG_ANDROID_KEYMASTER_CA 35991c73fb4Sqiujian /* load attestation key from misc partition. */ 360e72b9125SJoseph Chen ret = part_get_info_by_name(dev_desc, PART_MISC, &part); 36191c73fb4Sqiujian if (ret < 0) 362e72b9125SJoseph Chen printf("Could not find misc partition\n"); 36391c73fb4Sqiujian else 364e72b9125SJoseph Chen load_attestation_key(dev_desc, &part); 36591c73fb4Sqiujian #endif 36691c73fb4Sqiujian 36765413a00SJian Qiu #ifdef CONFIG_FASTBOOT_OEM_UNLOCK 3689e68721bSqiujian /* read oem unlock status and attach to bootargs */ 36914768307SJoseph Chen char oem_unlock[30] = {0}; 3709e68721bSqiujian TEEC_Result result; 37114768307SJoseph Chen uint8_t unlock = 0; 37214768307SJoseph Chen 3739e68721bSqiujian result = trusty_read_oem_unlock(&unlock); 3749e68721bSqiujian if (result) { 375e72b9125SJoseph Chen printf("Failed to read oem unlock status, ret=%d\n", result); 3769e68721bSqiujian } else { 37714768307SJoseph Chen snprintf(oem_unlock, sizeof(oem_unlock), 37814768307SJoseph Chen "androidboot.oem_unlocked=%d", unlock); 3799e68721bSqiujian env_update("bootargs", oem_unlock); 3809e68721bSqiujian } 3819e68721bSqiujian #endif 382e72b9125SJoseph Chen if (rockchip_get_boot_mode() == BOOT_MODE_RECOVERY) 383e72b9125SJoseph Chen part_name = PART_RECOVERY; 3849e68721bSqiujian 385e72b9125SJoseph Chen ret = part_get_info_by_name(dev_desc, part_name, &part); 38614768307SJoseph Chen if (ret < 0) { 387e72b9125SJoseph Chen printf("Could not find %s part\n", part.name); 38814768307SJoseph Chen return CMD_RET_FAILURE; 38914768307SJoseph Chen } 390a0e58cf2SKever Yang 391e72b9125SJoseph Chen return boot_rockchip_image(dev_desc, &part) ? CMD_RET_FAILURE : 0; 392a0e58cf2SKever Yang } 393a0e58cf2SKever Yang 394a0e58cf2SKever Yang U_BOOT_CMD( 395e72b9125SJoseph Chen bootrkp, 1, 1, do_boot_rockchip, 39632af749aSKever Yang "Boot Linux Image from rockchip image type", 39732af749aSKever Yang "kernel.img: zImage/Image\n" 39832af749aSKever Yang "boot.img: ramdisk\n" 39932af749aSKever Yang "resource.img: dtb, u-boot logo, kernel logo" 400a0e58cf2SKever Yang ); 401