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