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