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