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 <adc.h> 9 #include <android_bootloader.h> 10 #include <android_image.h> 11 #include <bidram.h> 12 #include <bootm.h> 13 #include <boot_rkimg.h> 14 #include <cli.h> 15 #include <crypto.h> 16 #include <dm.h> 17 #include <fs.h> 18 #include <image.h> 19 #include <key.h> 20 #include <mmc.h> 21 #include <malloc.h> 22 #include <nvme.h> 23 #include <stdlib.h> 24 #include <sysmem.h> 25 #include <asm/io.h> 26 #include <asm/arch/boot_mode.h> 27 #include <asm/arch/fit.h> 28 #include <asm/arch/hotkey.h> 29 #include <asm/arch/param.h> 30 #include <asm/arch/resource_img.h> 31 #include <asm/arch/uimage.h> 32 #include <dm/ofnode.h> 33 #include <linux/list.h> 34 #include <u-boot/sha1.h> 35 #include <u-boot/sha256.h> 36 #include <linux/usb/phy-rockchip-usb2.h> 37 38 DECLARE_GLOBAL_DATA_PTR; 39 40 __weak int rk_board_early_fdt_fixup(void *blob) 41 { 42 return 0; 43 } 44 45 static void boot_devtype_init(void) 46 { 47 const char *devtype_num_set = "run rkimg_bootdev"; 48 char *devtype = NULL, *devnum = NULL; 49 static int done; /* static */ 50 int atags_en = 0; 51 int ret; 52 53 if (done) 54 return; 55 56 /* 57 * The loader stage does not support SATA, and the boot device 58 * can only be other storage. Therefore, it is necessary to 59 * initialize the SATA device before judging the initialization 60 * of atag boot device 61 */ 62 #if defined(CONFIG_SCSI) && defined(CONFIG_CMD_SCSI) && defined(CONFIG_AHCI) 63 ret = run_command("scsi scan", 0); 64 if (!ret) { 65 ret = run_command("scsi dev 0", 0); 66 if (!ret) { 67 devtype = "scsi"; 68 devnum = "0"; 69 env_set("devtype", devtype); 70 env_set("devnum", devnum); 71 goto finish; 72 } 73 } 74 #endif 75 76 #ifdef CONFIG_NVME 77 struct udevice *udev; 78 79 pci_init(); 80 ret = nvme_scan_namespace(); 81 if (!ret) { 82 ret = blk_get_device(IF_TYPE_NVME, 0, &udev); 83 if (!ret) { 84 devtype = "nvme"; 85 devnum = "0"; 86 env_set("devtype", devtype); 87 env_set("devnum", devnum); 88 goto finish; 89 } 90 } else { 91 printf("Set nvme as boot storage fail ret=%d\n", ret); 92 } 93 #endif 94 95 /* High priority: get bootdev from atags */ 96 #ifdef CONFIG_ROCKCHIP_PRELOADER_ATAGS 97 ret = param_parse_bootdev(&devtype, &devnum); 98 if (!ret) { 99 atags_en = 1; 100 env_set("devtype", devtype); 101 env_set("devnum", devnum); 102 103 #ifdef CONFIG_MMC 104 if (!strcmp("mmc", devtype)) 105 mmc_initialize(gd->bd); 106 #endif 107 /* 108 * For example, the pre-loader do not have mtd device, 109 * and pass devtype is nand. Then U-Boot can not get 110 * dev_desc when use mtd driver to read firmware. So 111 * test the block dev is exist or not here. 112 * 113 * And the devtype & devnum maybe wrong sometimes, it 114 * is better to test first. 115 */ 116 if (blk_get_devnum_by_typename(devtype, atoi(devnum))) 117 goto finish; 118 } 119 #endif 120 121 /* Low priority: if not get bootdev by atags, scan all possible */ 122 #ifdef CONFIG_MMC 123 mmc_initialize(gd->bd); 124 #endif 125 ret = run_command_list(devtype_num_set, -1, 0); 126 if (ret) { 127 /* Set default dev type/num if command not valid */ 128 devtype = "mmc"; 129 devnum = "0"; 130 env_set("devtype", devtype); 131 env_set("devnum", devnum); 132 } 133 134 finish: 135 done = 1; 136 printf("Bootdev%s: %s %s\n", atags_en ? "(atags)" : "", 137 env_get("devtype"), env_get("devnum")); 138 } 139 140 static int get_bootdev_type(void) 141 { 142 char *boot_media = NULL, *devtype = NULL; 143 char boot_options[128] = {0}; 144 static int appended; 145 ulong devnum = 0; 146 int type = 0; 147 148 devtype = env_get("devtype"); 149 devnum = env_get_ulong("devnum", 10, 0); 150 151 /* For current use(Only EMMC support!) */ 152 if (!devtype) { 153 devtype = "mmc"; 154 printf("Use emmc as default boot media\n"); 155 } 156 157 if (!strcmp(devtype, "mmc")) { 158 type = IF_TYPE_MMC; 159 if (devnum == 1) 160 boot_media = "sd"; 161 else 162 boot_media = "emmc"; 163 } else if (!strcmp(devtype, "rknand")) { 164 type = IF_TYPE_RKNAND; 165 boot_media = "nand"; 166 } else if (!strcmp(devtype, "spinand")) { 167 type = IF_TYPE_SPINAND; 168 boot_media = "nand"; /* kernel treat sfc nand as nand device */ 169 } else if (!strcmp(devtype, "spinor")) { 170 type = IF_TYPE_SPINOR; 171 boot_media = "nor"; 172 } else if (!strcmp(devtype, "ramdisk")) { 173 type = IF_TYPE_RAMDISK; 174 boot_media = "ramdisk"; 175 } else if (!strcmp(devtype, "mtd")) { 176 type = IF_TYPE_MTD; 177 boot_media = "mtd"; 178 } else if (!strcmp(devtype, "scsi")) { 179 type = IF_TYPE_SCSI; 180 boot_media = "scsi"; 181 } else if (!strcmp(devtype, "nvme")) { 182 type = IF_TYPE_NVME; 183 boot_media = "nvme"; 184 } else { 185 /* Add new to support */ 186 } 187 188 if (!appended && boot_media) { 189 appended = 1; 190 191 /* 192 * The legacy rockchip Android (SDK < 8.1) requires "androidboot.mode=" 193 * to be "charger" or boot media which is a rockchip private solution. 194 * 195 * The official Android rule (SDK >= 8.1) is: 196 * "androidboot.mode=normal" or "androidboot.mode=charger". 197 * 198 * Now that this U-Boot is usually working with higher version 199 * Android (SDK >= 8.1), we follow the official rules. 200 * 201 * Common: androidboot.mode=charger has higher priority, don't override; 202 */ 203 #ifdef CONFIG_RKIMG_ANDROID_BOOTMODE_LEGACY 204 /* rknand doesn't need "androidboot.mode="; */ 205 if (env_exist("bootargs", "androidboot.mode=charger") || 206 (type == IF_TYPE_RKNAND) || 207 (type == IF_TYPE_SPINAND) || 208 (type == IF_TYPE_SPINOR)) 209 snprintf(boot_options, sizeof(boot_options), 210 "storagemedia=%s", boot_media); 211 else 212 snprintf(boot_options, sizeof(boot_options), 213 "storagemedia=%s androidboot.mode=%s", 214 boot_media, boot_media); 215 #else 216 /* 217 * 1. "storagemedia": This is a legacy variable to indicate board 218 * storage media for kernel and android. 219 * 220 * 2. "androidboot.storagemedia": The same purpose as "storagemedia", 221 * but the android framework will auto create property by 222 * variable with format "androidboot.xxx", eg: 223 * 224 * "androidboot.storagemedia" => "ro.boot.storagemedia". 225 * 226 * So, U-Boot pass this new variable is only for the convenience 227 * to Android. 228 */ 229 if (env_exist("bootargs", "androidboot.mode=charger")) 230 snprintf(boot_options, sizeof(boot_options), 231 "storagemedia=%s androidboot.storagemedia=%s", 232 boot_media, boot_media); 233 else 234 snprintf(boot_options, sizeof(boot_options), 235 "storagemedia=%s androidboot.storagemedia=%s " 236 "androidboot.mode=normal ", 237 boot_media, boot_media); 238 #endif 239 env_update("bootargs", boot_options); 240 } 241 242 return type; 243 } 244 245 static struct blk_desc *dev_desc; 246 247 struct blk_desc *rockchip_get_bootdev(void) 248 { 249 int dev_type; 250 int devnum; 251 252 if (dev_desc) 253 return dev_desc; 254 255 boot_devtype_init(); 256 dev_type = get_bootdev_type(); 257 devnum = env_get_ulong("devnum", 10, 0); 258 259 dev_desc = blk_get_devnum_by_type(dev_type, devnum); 260 if (!dev_desc) { 261 printf("%s: Can't find dev_desc!\n", __func__); 262 return NULL; 263 } 264 265 #ifdef CONFIG_MMC 266 if (dev_type == IF_TYPE_MMC) { 267 struct mmc *mmc; 268 const char *timing[] = { 269 "Legacy", "High Speed", "High Speed", "SDR12", 270 "SDR25", "SDR50", "SDR104", "DDR50", 271 "DDR52", "HS200", "HS400", "HS400 Enhanced Strobe"}; 272 273 mmc = find_mmc_device(devnum); 274 printf("MMC%d: %s, %dMhz\n", devnum, 275 timing[mmc->timing], mmc->clock / 1000000); 276 } 277 #endif 278 279 printf("PartType: %s\n", part_get_type(dev_desc)); 280 281 return dev_desc; 282 } 283 284 void rockchip_set_bootdev(struct blk_desc *desc) 285 { 286 dev_desc = desc; 287 } 288 289 /* 290 * detect download key status by adc, most rockchip 291 * based boards use adc sample the download key status, 292 * but there are also some use gpio. So it's better to 293 * make this a weak function that can be override by 294 * some special boards. 295 */ 296 #define KEY_DOWN_MIN_VAL 0 297 #define KEY_DOWN_MAX_VAL 30 298 299 __weak int rockchip_dnl_key_pressed(void) 300 { 301 #if defined(CONFIG_DM_KEY) 302 return key_is_pressed(key_read(KEY_VOLUMEUP)); 303 304 #elif defined(CONFIG_ADC) 305 const void *blob = gd->fdt_blob; 306 int node, ret, channel = 1; 307 u32 val, chns[2]; 308 309 node = fdt_node_offset_by_compatible(blob, 0, "adc-keys"); 310 if (node >= 0) { 311 if (!fdtdec_get_int_array(blob, node, "io-channels", chns, 2)) 312 channel = chns[1]; 313 } 314 315 ret = adc_channel_single_shot("saradc", channel, &val); 316 if (ret) { 317 printf("%s: Failed to read saradc, ret=%d\n", __func__, ret); 318 return 0; 319 } 320 321 return ((val >= KEY_DOWN_MIN_VAL) && (val <= KEY_DOWN_MAX_VAL)); 322 #endif 323 324 return 0; 325 } 326 327 void setup_download_mode(void) 328 { 329 int vbus = 1; /* Assumed 1 in case of no rockusb */ 330 331 boot_devtype_init(); 332 333 if (rockchip_dnl_key_pressed() || is_hotkey(HK_ROCKUSB_DNL)) { 334 printf("download %skey pressed... ", 335 is_hotkey(HK_ROCKUSB_DNL) ? "hot" : ""); 336 #ifdef CONFIG_CMD_ROCKUSB 337 vbus = rockchip_u2phy_vbus_detect(); 338 #endif 339 if (vbus > 0) { 340 printf("%sentering download mode...\n", 341 IS_ENABLED(CONFIG_CMD_ROCKUSB) ? 342 "" : "no rockusb, "); 343 344 /* try rockusb download and brom download */ 345 run_command("download", 0); 346 } else { 347 printf("entering recovery mode!\n"); 348 env_set("reboot_mode", "recovery-key"); 349 } 350 } else if (is_hotkey(HK_FASTBOOT)) { 351 env_set("reboot_mode", "fastboot"); 352 } 353 } 354 355 void board_run_recovery_wipe_data(void) 356 { 357 struct bootloader_message bmsg; 358 struct blk_desc *dev_desc; 359 disk_partition_t part_info; 360 #ifdef CONFIG_ANDROID_BOOT_IMAGE 361 u32 bcb_offset = android_bcb_msg_sector_offset(); 362 #else 363 u32 bcb_offset = BCB_MESSAGE_BLK_OFFSET; 364 #endif 365 int cnt, ret; 366 367 printf("Rebooting into recovery to do wipe_data\n"); 368 dev_desc = rockchip_get_bootdev(); 369 if (!dev_desc) { 370 printf("%s: dev_desc is NULL!\n", __func__); 371 return; 372 } 373 374 ret = part_get_info_by_name(dev_desc, PART_MISC, &part_info); 375 if (ret < 0) { 376 printf("%s: Could not found misc partition, just run recovery\n", 377 __func__); 378 goto out; 379 } 380 381 memset((char *)&bmsg, 0, sizeof(struct bootloader_message)); 382 strcpy(bmsg.command, "boot-recovery"); 383 strcpy(bmsg.recovery, "recovery\n--wipe_data"); 384 bmsg.status[0] = 0; 385 cnt = DIV_ROUND_UP(sizeof(struct bootloader_message), dev_desc->blksz); 386 ret = blk_dwrite(dev_desc, part_info.start + bcb_offset, cnt, &bmsg); 387 if (ret != cnt) 388 printf("Wipe data failed, ret=%d\n", ret); 389 out: 390 /* now reboot to recovery */ 391 env_set("reboot_mode", "recovery"); 392 run_command("run bootcmd", 0); 393 } 394 395 #if defined(CONFIG_USING_KERNEL_DTB) || defined(CONFIG_CMD_BOOTM) || \ 396 defined(CONFIG_CMD_BOOTZ) || defined(CONFIG_CMD_BOOTI) 397 #ifdef CONFIG_ROCKCHIP_DTB_VERIFY 398 #ifdef CONFIG_DM_CRYPTO 399 static int crypto_csum(u32 cap, char *input, u32 input_len, u8 *output) 400 { 401 sha_context csha_ctx; 402 struct udevice *dev; 403 404 dev = crypto_get_device(cap); 405 if (!dev) { 406 printf("Can't find expected crypto device\n"); 407 return -ENODEV; 408 } 409 410 csha_ctx.algo = cap; 411 csha_ctx.length = input_len; 412 crypto_sha_csum(dev, &csha_ctx, (char *)input, 413 input_len, output); 414 415 return 0; 416 } 417 418 static int fdt_check_hash(void *fdt_addr, u32 fdt_size, 419 char *hash_cmp, u32 hash_size) 420 { 421 uchar hash[32]; 422 423 if (!hash_size) 424 return 0; 425 426 if (hash_size == 20) 427 crypto_csum(CRYPTO_SHA1, fdt_addr, fdt_size, hash); 428 else if (hash_size == 32) 429 crypto_csum(CRYPTO_SHA256, fdt_addr, fdt_size, hash); 430 else 431 return -EINVAL; 432 433 printf("HASH(c): "); 434 if (memcmp(hash, hash_cmp, hash_size)) { 435 printf("error\n"); 436 return -EBADF; 437 } 438 439 printf("OK\n"); 440 441 return 0; 442 } 443 444 #else 445 static int fdt_check_hash(void *fdt_addr, u32 fdt_size, 446 char *hash_cmp, u32 hash_size) 447 { 448 uchar hash[32]; 449 450 if (!hash_size) 451 return 0; 452 453 if (hash_size == 20) 454 sha1_csum((const uchar *)fdt_addr, fdt_size, hash); 455 else if (hash_size == 32) 456 sha256_csum((const uchar *)fdt_addr, fdt_size, hash); 457 else 458 return -EINVAL; 459 460 printf("HASH(s): "); 461 if (memcmp(hash, hash_cmp, hash_size)) { 462 printf("error\n"); 463 return -EBADF; 464 } 465 466 printf("OK\n"); 467 468 return 0; 469 } 470 #endif 471 #endif /* CONFIG_ROCKCHIP_DTB_VERIFY */ 472 473 #if defined(CONFIG_ROCKCHIP_EARLY_DISTRO_DTB) 474 static int rockchip_read_distro_dtb(void *fdt_addr) 475 { 476 const char *cmd = "part list ${devtype} ${devnum} -bootable devplist"; 477 char *devnum, *devtype, *devplist; 478 char devnum_part[12]; 479 char fdt_hex_str[19]; 480 char *fs_argv[5]; 481 482 if (!rockchip_get_bootdev() || !fdt_addr) 483 return -ENODEV; 484 485 if (run_command_list(cmd, -1, 0)) { 486 printf("Failed to find -bootable\n"); 487 return -EINVAL; 488 } 489 490 devplist = env_get("devplist"); 491 if (!devplist) 492 return -ENODEV; 493 494 devtype = env_get("devtype"); 495 devnum = env_get("devnum"); 496 sprintf(devnum_part, "%s:%s", devnum, devplist); 497 sprintf(fdt_hex_str, "0x%lx", (ulong)fdt_addr); 498 499 fs_argv[0] = "load"; 500 fs_argv[1] = devtype, 501 fs_argv[2] = devnum_part; 502 fs_argv[3] = fdt_hex_str; 503 fs_argv[4] = CONFIG_ROCKCHIP_EARLY_DISTRO_DTB_PATH; 504 505 if (do_load(NULL, 0, 5, fs_argv, FS_TYPE_ANY)) 506 return -EIO; 507 508 if (fdt_check_header(fdt_addr)) 509 return -EBADF; 510 511 printf("DTB(Distro): %s\n", CONFIG_ROCKCHIP_EARLY_DISTRO_DTB_PATH); 512 513 return 0; 514 } 515 #endif 516 517 enum { 518 LOCATE_DISTRO, 519 LOCATE_RESOURCE, 520 LOCATE_FIT, 521 LOCATE_END, 522 }; 523 524 static int rkimg_traverse_read_dtb(void *fdt, int where) 525 { 526 if (where == LOCATE_DISTRO) { 527 #ifdef CONFIG_ROCKCHIP_EARLY_DISTRO_DTB 528 return rockchip_read_distro_dtb(fdt); 529 #endif 530 } else if (where == LOCATE_RESOURCE) { 531 #ifdef CONFIG_ROCKCHIP_RESOURCE_IMAGE 532 int hash_size = 0; 533 char *hash; 534 u32 ret; 535 536 ret = rockchip_read_resource_dtb(fdt, &hash, &hash_size); 537 if (ret) { 538 printf("Failed to load DTB, ret=%d\n", ret); 539 return ret; 540 } 541 542 if (fdt_check_header(fdt)) { 543 printf("Invalid DTB magic !\n"); 544 return -EBADF; 545 } 546 #ifdef CONFIG_ROCKCHIP_DTB_VERIFY 547 if (hash_size && fdt_check_hash(fdt, 548 fdt_totalsize(fdt), hash, hash_size)) { 549 printf("Invalid DTB hash !\n"); 550 return -EBADF; 551 } 552 #endif 553 return 0; 554 #endif 555 } else if (where == LOCATE_FIT) { 556 #if defined(CONFIG_ROCKCHIP_FIT_IMAGE) && !defined(CONFIG_ROCKCHIP_RESOURCE_IMAGE) 557 return fit_image_read_dtb(fdt); 558 #endif 559 } 560 561 return -EINVAL; 562 } 563 564 int rockchip_read_dtb_file(void *fdt) 565 { 566 int locate, ret; 567 int size; 568 569 /* init resource list */ 570 #ifdef CONFIG_ROCKCHIP_RESOURCE_IMAGE 571 resource_traverse_init_list(); 572 #endif 573 574 /* traverse location */ 575 for (locate = 0; locate < LOCATE_END; locate++) { 576 ret = rkimg_traverse_read_dtb(fdt, locate); 577 if (!ret) 578 break; 579 } 580 if (ret) { 581 printf("No find valid DTB, ret=%d\n", ret); 582 return ret; 583 } 584 585 /* reserved memory */ 586 size = fdt_totalsize(fdt); 587 if (!sysmem_alloc_base(MEM_FDT, (phys_addr_t)fdt, 588 ALIGN(size, RK_BLK_SIZE) + CONFIG_SYS_FDT_PAD)) 589 return -ENOMEM; 590 591 /* fixup/overlay */ 592 rk_board_early_fdt_fixup(fdt); 593 #if defined(CONFIG_ANDROID_BOOT_IMAGE) && defined(CONFIG_OF_LIBFDT_OVERLAY) 594 android_fdt_overlay_apply((void *)fdt); 595 #endif 596 597 return 0; 598 } 599 #endif 600 601 int rockchip_ram_read_dtb_file(void *img, void *fdt) 602 { 603 int format; 604 int ret; 605 606 format = (genimg_get_format(img)); 607 #ifdef CONFIG_ANDROID_BOOT_IMAGE 608 if (format == IMAGE_FORMAT_ANDROID) { 609 struct andr_img_hdr *hdr = img; 610 struct blk_desc *dev_desc; 611 ulong offset; 612 613 dev_desc = rockchip_get_bootdev(); 614 if (!dev_desc) 615 return -ENODEV; 616 617 offset = hdr->page_size + ALIGN(hdr->kernel_size, hdr->page_size) + 618 ALIGN(hdr->ramdisk_size, hdr->page_size); 619 #ifdef CONFIG_ROCKCHIP_RESOURCE_IMAGE 620 ret = resource_create_ram_list(dev_desc, (void *)hdr + offset); 621 if (ret) 622 return ret; 623 624 return rockchip_read_dtb_file((void *)fdt); 625 #else 626 if (fdt_check_header((void *)offset)) 627 return -EINVAL; 628 629 memcpy(fdt, (char *)offset, fdt_totalsize(offset)); 630 if (!sysmem_alloc_base(MEM_FDT, (phys_addr_t)fdt, 631 ALIGN(fdt_totalsize(fdt), RK_BLK_SIZE) + CONFIG_SYS_FDT_PAD)) 632 return -ENOMEM; 633 634 return 0; 635 #endif 636 } 637 #endif 638 #if IMAGE_ENABLE_FIT 639 if (format == IMAGE_FORMAT_FIT) { 640 const void *data; 641 size_t size; 642 int noffset; 643 #ifdef CONFIG_ROCKCHIP_RESOURCE_IMAGE 644 const char *path = "/images/resource"; 645 #else 646 const char *path = "/images/fdt"; 647 #endif 648 649 noffset = fdt_path_offset(img, path); 650 if (noffset < 0) 651 return noffset; 652 653 #ifdef CONFIG_ROCKCHIP_RESOURCE_IMAGE 654 ret = fit_image_get_data(img, noffset, &data, &size); 655 if (ret < 0) 656 return ret; 657 658 dev_desc = rockchip_get_bootdev(); 659 if (!dev_desc) 660 return -ENODEV; 661 662 ret = resource_create_ram_list(dev_desc, (void *)data); 663 if (ret) { 664 printf("resource_create_ram_list fail, ret=%d\n", ret); 665 return ret; 666 } 667 668 return rockchip_read_dtb_file((void *)fdt); 669 #else 670 671 ret = fit_image_get_data(img, noffset, &data, &size); 672 if (ret) 673 return ret; 674 675 if (fdt_check_header(data)) 676 return -EINVAL; 677 678 memcpy(fdt, data, size); 679 if (!sysmem_alloc_base(MEM_FDT, (phys_addr_t)fdt, 680 ALIGN(fdt_totalsize(fdt), RK_BLK_SIZE) + CONFIG_SYS_FDT_PAD)) 681 return -ENOMEM; 682 683 printf("Load DTB from 'images/fdt'\n"); 684 685 return 0; 686 #endif 687 } 688 #endif 689 690 return -EINVAL; 691 } 692