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