1 /* 2 * (C) Copyright 2003 3 * Kyle Harris, kharris@nexus-tech.net 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 */ 7 #include <common.h> 8 #include <command.h> 9 #include <console.h> 10 #include <mmc.h> 11 #include <optee_include/OpteeClientInterface.h> 12 #include <optee_include/OpteeClientApiLib.h> 13 14 static int curr_device = -1; 15 16 static void print_mmcinfo(struct mmc *mmc) 17 { 18 int i; 19 const char *timing[] = { 20 "Legacy", "High Speed", "High Speed", "SDR12", 21 "SDR25", "SDR50", "SDR104", "DDR50", 22 "DDR52", "HS200", "HS400", "HS400 Enhanced Strobe"}; 23 24 printf("Device: %s\n", mmc->cfg->name); 25 printf("Manufacturer ID: %x\n", mmc->cid[0] >> 24); 26 printf("OEM: %x\n", (mmc->cid[0] >> 8) & 0xffff); 27 printf("Name: %c%c%c%c%c \n", mmc->cid[0] & 0xff, 28 (mmc->cid[1] >> 24), (mmc->cid[1] >> 16) & 0xff, 29 (mmc->cid[1] >> 8) & 0xff, mmc->cid[1] & 0xff); 30 31 printf("Timing Interface: %s\n", timing[mmc->timing]); 32 printf("Tran Speed: %d\n", mmc->clock); 33 printf("Rd Block Len: %d\n", mmc->read_bl_len); 34 35 printf("%s version %d.%d", IS_SD(mmc) ? "SD" : "MMC", 36 EXTRACT_SDMMC_MAJOR_VERSION(mmc->version), 37 EXTRACT_SDMMC_MINOR_VERSION(mmc->version)); 38 if (EXTRACT_SDMMC_CHANGE_VERSION(mmc->version) != 0) 39 printf(".%d", EXTRACT_SDMMC_CHANGE_VERSION(mmc->version)); 40 printf("\n"); 41 42 printf("High Capacity: %s\n", mmc->high_capacity ? "Yes" : "No"); 43 puts("Capacity: "); 44 print_size(mmc->capacity, "\n"); 45 46 printf("Bus Width: %d-bit%s\n", mmc->bus_width, 47 mmc_card_ddr(mmc) ? " DDR" : ""); 48 49 puts("Erase Group Size: "); 50 print_size(((u64)mmc->erase_grp_size) << 9, "\n"); 51 52 if (!IS_SD(mmc) && mmc->version >= MMC_VERSION_4_41) { 53 bool has_enh = (mmc->part_support & ENHNCD_SUPPORT) != 0; 54 bool usr_enh = has_enh && (mmc->part_attr & EXT_CSD_ENH_USR); 55 56 puts("HC WP Group Size: "); 57 print_size(((u64)mmc->hc_wp_grp_size) << 9, "\n"); 58 59 puts("User Capacity: "); 60 print_size(mmc->capacity_user, usr_enh ? " ENH" : ""); 61 if (mmc->wr_rel_set & EXT_CSD_WR_DATA_REL_USR) 62 puts(" WRREL\n"); 63 else 64 putc('\n'); 65 if (usr_enh) { 66 puts("User Enhanced Start: "); 67 print_size(mmc->enh_user_start, "\n"); 68 puts("User Enhanced Size: "); 69 print_size(mmc->enh_user_size, "\n"); 70 } 71 puts("Boot Capacity: "); 72 print_size(mmc->capacity_boot, has_enh ? " ENH\n" : "\n"); 73 puts("RPMB Capacity: "); 74 print_size(mmc->capacity_rpmb, has_enh ? " ENH\n" : "\n"); 75 76 for (i = 0; i < ARRAY_SIZE(mmc->capacity_gp); i++) { 77 bool is_enh = has_enh && 78 (mmc->part_attr & EXT_CSD_ENH_GP(i)); 79 if (mmc->capacity_gp[i]) { 80 printf("GP%i Capacity: ", i+1); 81 print_size(mmc->capacity_gp[i], 82 is_enh ? " ENH" : ""); 83 if (mmc->wr_rel_set & EXT_CSD_WR_DATA_REL_GP(i)) 84 puts(" WRREL\n"); 85 else 86 putc('\n'); 87 } 88 } 89 } 90 } 91 static struct mmc *init_mmc_device(int dev, bool force_init) 92 { 93 struct mmc *mmc; 94 mmc = find_mmc_device(dev); 95 if (!mmc) { 96 printf("no mmc device at slot %x\n", dev); 97 return NULL; 98 } 99 100 if (force_init) 101 mmc->has_init = 0; 102 if (mmc_init(mmc)) 103 return NULL; 104 return mmc; 105 } 106 static int do_mmcinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 107 { 108 struct mmc *mmc; 109 110 if (curr_device < 0) { 111 if (get_mmc_num() > 0) 112 curr_device = 0; 113 else { 114 puts("No MMC device available\n"); 115 return 1; 116 } 117 } 118 119 mmc = init_mmc_device(curr_device, false); 120 if (!mmc) 121 return CMD_RET_FAILURE; 122 123 print_mmcinfo(mmc); 124 return CMD_RET_SUCCESS; 125 } 126 127 #ifdef CONFIG_OPTEE_CLIENT 128 static int do_mmc_testrpmb(cmd_tbl_t *cmdtp, 129 int flag, int argc, char * const argv[]) 130 { 131 struct mmc *mmc; 132 133 if (curr_device < 0) { 134 if (get_mmc_num() > 0) { 135 puts("MMC device available\n"); 136 curr_device = 0; 137 } else { 138 puts("No MMC device available\n"); 139 return 1; 140 } 141 } 142 143 mmc = init_mmc_device(curr_device, false); 144 if (!mmc) 145 return CMD_RET_FAILURE; 146 147 uint64_t value; 148 trusty_write_rollback_index(0x87654321, 0x1122334455667788); 149 trusty_read_rollback_index(0x87654321, &value); 150 debug("sizeof(value) %x\n ", sizeof(value)); 151 if (value == 0x1122334455667788) 152 printf("good ! value==0x1122334455667788\n "); 153 else 154 printf("error ! value!=0x1122334455667788\n "); 155 156 uint8_t data[] = "just a data"; 157 uint8_t data_read[11]; 158 trusty_write_permanent_attributes(data, sizeof(data)); 159 trusty_read_permanent_attributes(data_read, sizeof(data)); 160 printf("attribute: %s\n ", data_read); 161 162 trusty_notify_optee_uboot_end(); 163 printf(" tell_optee_uboot_end \n "); 164 value = 0; 165 trusty_read_rollback_index(0x87654321, &value); 166 if (value == 0x1122334455667788) 167 printf(" value==0x1122334455667788 read still enable\n "); 168 else 169 printf(" good! value!=0x1122334455667788 read denied\n "); 170 return CMD_RET_SUCCESS; 171 } 172 173 static int do_mmc_testefuse(cmd_tbl_t *cmdtp, 174 int flag, int argc, char * const argv[]) 175 { 176 uint32_t buf32[8]; 177 uint32_t outbuf32[8]; 178 179 buf32[0] = 0x01020304; 180 buf32[1] = 0x05060708; 181 buf32[2] = 0x090a0b0c; 182 buf32[3] = 0x0d0e0f10; 183 buf32[4] = 0x11121314; 184 buf32[5] = 0x15161718; 185 buf32[6] = 0x191a1b1c; 186 buf32[7] = 0x1d1e1f20; 187 188 trusty_write_attribute_hash(buf32, 8); 189 190 trusty_read_attribute_hash(outbuf32, 8); 191 192 printf(" 0x%x 0x%x 0x%x 0x%x \n", 193 outbuf32[0], outbuf32[1], outbuf32[2], outbuf32[3]); 194 printf(" 0x%x 0x%x 0x%x 0x%x \n", 195 outbuf32[4], outbuf32[5], outbuf32[6], outbuf32[7]); 196 197 trusty_write_vbootkey_hash(buf32, 8); 198 199 trusty_read_vbootkey_hash(outbuf32, 8); 200 201 printf(" 0x%x 0x%x 0x%x 0x%x \n", 202 outbuf32[0], outbuf32[1], outbuf32[2], outbuf32[3]); 203 printf(" 0x%x 0x%x 0x%x 0x%x \n", 204 outbuf32[4], outbuf32[5], outbuf32[6], outbuf32[7]); 205 206 return CMD_RET_SUCCESS; 207 } 208 209 #endif 210 211 #ifdef CONFIG_SUPPORT_EMMC_RPMB 212 char temp_original_part; 213 int init_rpmb(void) 214 { 215 struct mmc *mmc; 216 217 mmc = init_mmc_device(curr_device, false); 218 if (!mmc) 219 return CMD_RET_FAILURE; 220 221 if (!(mmc->version & MMC_VERSION_MMC)) { 222 printf("It is not a EMMC device\n"); 223 return CMD_RET_FAILURE; 224 } 225 if (mmc->version < MMC_VERSION_4_41) { 226 printf("RPMB not supported before version 4.41\n"); 227 return CMD_RET_FAILURE; 228 } 229 230 /* Switch to the RPMB partition */ 231 #ifndef CONFIG_BLK 232 temp_original_part = mmc->block_dev.hwpart; 233 debug("mmc->block_dev.hwpart\n"); 234 #else 235 temp_original_part = mmc_get_blk_desc(mmc)->hwpart; 236 debug("mmc_get_blk_desc(mmc)->hwpart\n"); 237 #endif 238 debug("init_rpmb temp_original_part = 0x%X\n", temp_original_part); 239 if (blk_select_hwpart_devnum 240 (IF_TYPE_MMC, curr_device, MMC_PART_RPMB) != 0) 241 return CMD_RET_FAILURE; 242 243 return CMD_RET_SUCCESS; 244 } 245 246 int finish_rpmb(void) 247 { 248 /* Return to original partition */ 249 debug("finish_rpmb temp_original_part = 0x%X\n", temp_original_part); 250 if (blk_select_hwpart_devnum 251 (IF_TYPE_MMC, curr_device, temp_original_part) != 0) 252 return CMD_RET_FAILURE; 253 254 return CMD_RET_SUCCESS; 255 } 256 257 int do_readcounter(struct s_rpmb *requestpackets) 258 { 259 struct mmc *mmc = find_mmc_device(curr_device); 260 261 return read_counter(mmc, requestpackets); 262 } 263 264 int do_programkey(struct s_rpmb *requestpackets) 265 { 266 struct mmc *mmc = find_mmc_device(curr_device); 267 268 return program_key(mmc, requestpackets); 269 } 270 271 int do_authenticatedread(struct s_rpmb *requestpackets, uint16_t block_count) 272 { 273 struct mmc *mmc = find_mmc_device(curr_device); 274 275 return authenticated_read(mmc, requestpackets, block_count); 276 } 277 278 int do_authenticatedwrite(struct s_rpmb *requestpackets) 279 { 280 struct mmc *mmc = find_mmc_device(curr_device); 281 282 return authenticated_write(mmc, requestpackets); 283 } 284 285 struct mmc *do_returnmmc(void) 286 { 287 struct mmc *mmc = find_mmc_device(curr_device); 288 289 return mmc; 290 } 291 292 static int confirm_key_prog(void) 293 { 294 puts("Warning: Programming authentication key can be done only once !\n" 295 " Use this command only if you are sure of what you are doing,\n" 296 "Really perform the key programming? <y/N> "); 297 if (confirm_yesno()) 298 return 1; 299 300 puts("Authentication key programming aborted\n"); 301 return 0; 302 } 303 static int do_mmcrpmb_key(cmd_tbl_t *cmdtp, int flag, 304 int argc, char * const argv[]) 305 { 306 void *key_addr; 307 struct mmc *mmc = find_mmc_device(curr_device); 308 309 if (argc != 2) 310 return CMD_RET_USAGE; 311 312 key_addr = (void *)simple_strtoul(argv[1], NULL, 16); 313 if (!confirm_key_prog()) 314 return CMD_RET_FAILURE; 315 if (mmc_rpmb_set_key(mmc, key_addr)) { 316 printf("ERROR - Key already programmed ?\n"); 317 return CMD_RET_FAILURE; 318 } 319 return CMD_RET_SUCCESS; 320 } 321 static int do_mmcrpmb_read(cmd_tbl_t *cmdtp, int flag, 322 int argc, char * const argv[]) 323 { 324 u16 blk, cnt; 325 void *addr; 326 int n; 327 void *key_addr = NULL; 328 struct mmc *mmc = find_mmc_device(curr_device); 329 330 if (argc < 4) 331 return CMD_RET_USAGE; 332 333 addr = (void *)simple_strtoul(argv[1], NULL, 16); 334 blk = simple_strtoul(argv[2], NULL, 16); 335 cnt = simple_strtoul(argv[3], NULL, 16); 336 337 if (argc == 5) 338 key_addr = (void *)simple_strtoul(argv[4], NULL, 16); 339 340 printf("\nMMC RPMB read: dev # %d, block # %d, count %d ... ", 341 curr_device, blk, cnt); 342 n = mmc_rpmb_read(mmc, addr, blk, cnt, key_addr); 343 344 printf("%d RPMB blocks read: %s\n", n, (n == cnt) ? "OK" : "ERROR"); 345 if (n != cnt) 346 return CMD_RET_FAILURE; 347 return CMD_RET_SUCCESS; 348 } 349 static int do_mmcrpmb_write(cmd_tbl_t *cmdtp, int flag, 350 int argc, char * const argv[]) 351 { 352 u16 blk, cnt; 353 void *addr; 354 int n; 355 void *key_addr; 356 struct mmc *mmc = find_mmc_device(curr_device); 357 358 if (argc != 5) 359 return CMD_RET_USAGE; 360 361 addr = (void *)simple_strtoul(argv[1], NULL, 16); 362 blk = simple_strtoul(argv[2], NULL, 16); 363 cnt = simple_strtoul(argv[3], NULL, 16); 364 key_addr = (void *)simple_strtoul(argv[4], NULL, 16); 365 366 printf("\nMMC RPMB write: dev # %d, block # %d, count %d ... ", 367 curr_device, blk, cnt); 368 n = mmc_rpmb_write(mmc, addr, blk, cnt, key_addr); 369 370 printf("%d RPMB blocks written: %s\n", n, (n == cnt) ? "OK" : "ERROR"); 371 if (n != cnt) 372 return CMD_RET_FAILURE; 373 return CMD_RET_SUCCESS; 374 } 375 static int do_mmcrpmb_counter(cmd_tbl_t *cmdtp, int flag, 376 int argc, char * const argv[]) 377 { 378 unsigned long counter; 379 struct mmc *mmc = find_mmc_device(curr_device); 380 381 if (mmc_rpmb_get_counter(mmc, &counter)) 382 return CMD_RET_FAILURE; 383 printf("RPMB Write counter= %lx\n", counter); 384 return CMD_RET_SUCCESS; 385 } 386 387 static cmd_tbl_t cmd_rpmb[] = { 388 U_BOOT_CMD_MKENT(key, 2, 0, do_mmcrpmb_key, "", ""), 389 U_BOOT_CMD_MKENT(read, 5, 1, do_mmcrpmb_read, "", ""), 390 U_BOOT_CMD_MKENT(write, 5, 0, do_mmcrpmb_write, "", ""), 391 U_BOOT_CMD_MKENT(counter, 1, 1, do_mmcrpmb_counter, "", ""), 392 }; 393 394 static int do_mmcrpmb(cmd_tbl_t *cmdtp, int flag, 395 int argc, char * const argv[]) 396 { 397 cmd_tbl_t *cp; 398 struct mmc *mmc; 399 char original_part; 400 int ret; 401 402 cp = find_cmd_tbl(argv[1], cmd_rpmb, ARRAY_SIZE(cmd_rpmb)); 403 404 /* Drop the rpmb subcommand */ 405 argc--; 406 argv++; 407 408 if (cp == NULL || argc > cp->maxargs) 409 return CMD_RET_USAGE; 410 if (flag == CMD_FLAG_REPEAT && !cp->repeatable) 411 return CMD_RET_SUCCESS; 412 413 mmc = init_mmc_device(curr_device, false); 414 if (!mmc) 415 return CMD_RET_FAILURE; 416 417 if (!(mmc->version & MMC_VERSION_MMC)) { 418 printf("It is not a EMMC device\n"); 419 return CMD_RET_FAILURE; 420 } 421 if (mmc->version < MMC_VERSION_4_41) { 422 printf("RPMB not supported before version 4.41\n"); 423 return CMD_RET_FAILURE; 424 } 425 /* Switch to the RPMB partition */ 426 #ifndef CONFIG_BLK 427 original_part = mmc->block_dev.hwpart; 428 #else 429 original_part = mmc_get_blk_desc(mmc)->hwpart; 430 #endif 431 if (blk_select_hwpart_devnum(IF_TYPE_MMC, curr_device, MMC_PART_RPMB) != 432 0) 433 return CMD_RET_FAILURE; 434 ret = cp->cmd(cmdtp, flag, argc, argv); 435 436 /* Return to original partition */ 437 if (blk_select_hwpart_devnum(IF_TYPE_MMC, curr_device, original_part) != 438 0) 439 return CMD_RET_FAILURE; 440 return ret; 441 } 442 #endif 443 444 static int do_mmc_read(cmd_tbl_t *cmdtp, int flag, 445 int argc, char * const argv[]) 446 { 447 struct mmc *mmc; 448 u32 blk, cnt, n; 449 void *addr; 450 451 if (argc != 4) 452 return CMD_RET_USAGE; 453 454 addr = (void *)simple_strtoul(argv[1], NULL, 16); 455 blk = simple_strtoul(argv[2], NULL, 16); 456 cnt = simple_strtoul(argv[3], NULL, 16); 457 458 mmc = init_mmc_device(curr_device, false); 459 if (!mmc) 460 return CMD_RET_FAILURE; 461 462 printf("\nMMC read: dev # %d, block # %d, count %d ... ", 463 curr_device, blk, cnt); 464 465 n = blk_dread(mmc_get_blk_desc(mmc), blk, cnt, addr); 466 /* flush cache after read */ 467 flush_cache((ulong)addr, cnt * 512); /* FIXME */ 468 printf("%d blocks read: %s\n", n, (n == cnt) ? "OK" : "ERROR"); 469 470 return (n == cnt) ? CMD_RET_SUCCESS : CMD_RET_FAILURE; 471 } 472 static int do_mmc_write(cmd_tbl_t *cmdtp, int flag, 473 int argc, char * const argv[]) 474 { 475 struct mmc *mmc; 476 u32 blk, cnt, n; 477 void *addr; 478 479 if (argc != 4) 480 return CMD_RET_USAGE; 481 482 addr = (void *)simple_strtoul(argv[1], NULL, 16); 483 blk = simple_strtoul(argv[2], NULL, 16); 484 cnt = simple_strtoul(argv[3], NULL, 16); 485 486 mmc = init_mmc_device(curr_device, false); 487 if (!mmc) 488 return CMD_RET_FAILURE; 489 490 printf("\nMMC write: dev # %d, block # %d, count %d ... ", 491 curr_device, blk, cnt); 492 493 if (mmc_getwp(mmc) == 1) { 494 printf("Error: card is write protected!\n"); 495 return CMD_RET_FAILURE; 496 } 497 n = blk_dwrite(mmc_get_blk_desc(mmc), blk, cnt, addr); 498 printf("%d blocks written: %s\n", n, (n == cnt) ? "OK" : "ERROR"); 499 500 return (n == cnt) ? CMD_RET_SUCCESS : CMD_RET_FAILURE; 501 } 502 static int do_mmc_erase(cmd_tbl_t *cmdtp, int flag, 503 int argc, char * const argv[]) 504 { 505 struct mmc *mmc; 506 u32 blk, cnt, n; 507 508 if (argc != 3) 509 return CMD_RET_USAGE; 510 511 blk = simple_strtoul(argv[1], NULL, 16); 512 cnt = simple_strtoul(argv[2], NULL, 16); 513 514 mmc = init_mmc_device(curr_device, false); 515 if (!mmc) 516 return CMD_RET_FAILURE; 517 518 printf("\nMMC erase: dev # %d, block # %d, count %d ... ", 519 curr_device, blk, cnt); 520 521 if (mmc_getwp(mmc) == 1) { 522 printf("Error: card is write protected!\n"); 523 return CMD_RET_FAILURE; 524 } 525 n = blk_derase(mmc_get_blk_desc(mmc), blk, cnt); 526 printf("%d blocks erased: %s\n", n, (n == cnt) ? "OK" : "ERROR"); 527 528 return (n == cnt) ? CMD_RET_SUCCESS : CMD_RET_FAILURE; 529 } 530 static int do_mmc_rescan(cmd_tbl_t *cmdtp, int flag, 531 int argc, char * const argv[]) 532 { 533 struct mmc *mmc; 534 535 mmc = init_mmc_device(curr_device, true); 536 if (!mmc) 537 return CMD_RET_FAILURE; 538 539 return CMD_RET_SUCCESS; 540 } 541 static int do_mmc_part(cmd_tbl_t *cmdtp, int flag, 542 int argc, char * const argv[]) 543 { 544 struct blk_desc *mmc_dev; 545 struct mmc *mmc; 546 547 mmc = init_mmc_device(curr_device, false); 548 if (!mmc) 549 return CMD_RET_FAILURE; 550 551 mmc_dev = blk_get_devnum_by_type(IF_TYPE_MMC, curr_device); 552 if (mmc_dev != NULL && mmc_dev->type != DEV_TYPE_UNKNOWN) { 553 part_print(mmc_dev); 554 return CMD_RET_SUCCESS; 555 } 556 557 puts("get mmc type error!\n"); 558 return CMD_RET_FAILURE; 559 } 560 static int do_mmc_dev(cmd_tbl_t *cmdtp, int flag, 561 int argc, char * const argv[]) 562 { 563 int dev, part = 0, ret; 564 struct mmc *mmc; 565 566 if (argc == 1) { 567 dev = curr_device; 568 } else if (argc == 2) { 569 dev = simple_strtoul(argv[1], NULL, 10); 570 } else if (argc == 3) { 571 dev = (int)simple_strtoul(argv[1], NULL, 10); 572 part = (int)simple_strtoul(argv[2], NULL, 10); 573 if (part > PART_ACCESS_MASK) { 574 printf("#part_num shouldn't be larger than %d\n", 575 PART_ACCESS_MASK); 576 return CMD_RET_FAILURE; 577 } 578 } else { 579 return CMD_RET_USAGE; 580 } 581 582 mmc = init_mmc_device(dev, true); 583 if (!mmc) 584 return CMD_RET_FAILURE; 585 586 ret = blk_select_hwpart_devnum(IF_TYPE_MMC, dev, part); 587 printf("switch to partitions #%d, %s\n", 588 part, (!ret) ? "OK" : "ERROR"); 589 if (ret) 590 return 1; 591 592 curr_device = dev; 593 if (mmc->part_config == MMCPART_NOAVAILABLE) 594 printf("mmc%d is current device\n", curr_device); 595 else 596 printf("mmc%d(part %d) is current device\n", 597 curr_device, mmc_get_blk_desc(mmc)->hwpart); 598 599 return CMD_RET_SUCCESS; 600 } 601 static int do_mmc_list(cmd_tbl_t *cmdtp, int flag, 602 int argc, char * const argv[]) 603 { 604 print_mmc_devices('\n'); 605 return CMD_RET_SUCCESS; 606 } 607 608 static int parse_hwpart_user(struct mmc_hwpart_conf *pconf, 609 int argc, char * const argv[]) 610 { 611 int i = 0; 612 613 memset(&pconf->user, 0, sizeof(pconf->user)); 614 615 while (i < argc) { 616 if (!strcmp(argv[i], "enh")) { 617 if (i + 2 >= argc) 618 return -1; 619 pconf->user.enh_start = 620 simple_strtoul(argv[i+1], NULL, 10); 621 pconf->user.enh_size = 622 simple_strtoul(argv[i+2], NULL, 10); 623 i += 3; 624 } else if (!strcmp(argv[i], "wrrel")) { 625 if (i + 1 >= argc) 626 return -1; 627 pconf->user.wr_rel_change = 1; 628 if (!strcmp(argv[i+1], "on")) 629 pconf->user.wr_rel_set = 1; 630 else if (!strcmp(argv[i+1], "off")) 631 pconf->user.wr_rel_set = 0; 632 else 633 return -1; 634 i += 2; 635 } else { 636 break; 637 } 638 } 639 return i; 640 } 641 642 static int parse_hwpart_gp(struct mmc_hwpart_conf *pconf, int pidx, 643 int argc, char * const argv[]) 644 { 645 int i; 646 647 memset(&pconf->gp_part[pidx], 0, sizeof(pconf->gp_part[pidx])); 648 649 if (1 >= argc) 650 return -1; 651 pconf->gp_part[pidx].size = simple_strtoul(argv[0], NULL, 10); 652 653 i = 1; 654 while (i < argc) { 655 if (!strcmp(argv[i], "enh")) { 656 pconf->gp_part[pidx].enhanced = 1; 657 i += 1; 658 } else if (!strcmp(argv[i], "wrrel")) { 659 if (i + 1 >= argc) 660 return -1; 661 pconf->gp_part[pidx].wr_rel_change = 1; 662 if (!strcmp(argv[i+1], "on")) 663 pconf->gp_part[pidx].wr_rel_set = 1; 664 else if (!strcmp(argv[i+1], "off")) 665 pconf->gp_part[pidx].wr_rel_set = 0; 666 else 667 return -1; 668 i += 2; 669 } else { 670 break; 671 } 672 } 673 return i; 674 } 675 676 static int do_mmc_hwpartition(cmd_tbl_t *cmdtp, int flag, 677 int argc, char * const argv[]) 678 { 679 struct mmc *mmc; 680 struct mmc_hwpart_conf pconf = { }; 681 enum mmc_hwpart_conf_mode mode = MMC_HWPART_CONF_CHECK; 682 int i, r, pidx; 683 684 mmc = init_mmc_device(curr_device, false); 685 if (!mmc) 686 return CMD_RET_FAILURE; 687 688 if (argc < 1) 689 return CMD_RET_USAGE; 690 i = 1; 691 while (i < argc) { 692 if (!strcmp(argv[i], "user")) { 693 i++; 694 r = parse_hwpart_user(&pconf, argc-i, &argv[i]); 695 if (r < 0) 696 return CMD_RET_USAGE; 697 i += r; 698 } else if (!strncmp(argv[i], "gp", 2) && 699 strlen(argv[i]) == 3 && 700 argv[i][2] >= '1' && argv[i][2] <= '4') { 701 pidx = argv[i][2] - '1'; 702 i++; 703 r = parse_hwpart_gp(&pconf, pidx, argc-i, &argv[i]); 704 if (r < 0) 705 return CMD_RET_USAGE; 706 i += r; 707 } else if (!strcmp(argv[i], "check")) { 708 mode = MMC_HWPART_CONF_CHECK; 709 i++; 710 } else if (!strcmp(argv[i], "set")) { 711 mode = MMC_HWPART_CONF_SET; 712 i++; 713 } else if (!strcmp(argv[i], "complete")) { 714 mode = MMC_HWPART_CONF_COMPLETE; 715 i++; 716 } else { 717 return CMD_RET_USAGE; 718 } 719 } 720 721 puts("Partition configuration:\n"); 722 if (pconf.user.enh_size) { 723 puts("\tUser Enhanced Start: "); 724 print_size(((u64)pconf.user.enh_start) << 9, "\n"); 725 puts("\tUser Enhanced Size: "); 726 print_size(((u64)pconf.user.enh_size) << 9, "\n"); 727 } else { 728 puts("\tNo enhanced user data area\n"); 729 } 730 if (pconf.user.wr_rel_change) 731 printf("\tUser partition write reliability: %s\n", 732 pconf.user.wr_rel_set ? "on" : "off"); 733 for (pidx = 0; pidx < 4; pidx++) { 734 if (pconf.gp_part[pidx].size) { 735 printf("\tGP%i Capacity: ", pidx+1); 736 print_size(((u64)pconf.gp_part[pidx].size) << 9, 737 pconf.gp_part[pidx].enhanced ? 738 " ENH\n" : "\n"); 739 } else { 740 printf("\tNo GP%i partition\n", pidx+1); 741 } 742 if (pconf.gp_part[pidx].wr_rel_change) 743 printf("\tGP%i write reliability: %s\n", pidx+1, 744 pconf.gp_part[pidx].wr_rel_set ? "on" : "off"); 745 } 746 747 if (!mmc_hwpart_config(mmc, &pconf, mode)) { 748 if (mode == MMC_HWPART_CONF_COMPLETE) 749 puts("Partitioning successful, " 750 "power-cycle to make effective\n"); 751 return CMD_RET_SUCCESS; 752 } else { 753 puts("Failed!\n"); 754 return CMD_RET_FAILURE; 755 } 756 } 757 758 #ifdef CONFIG_SUPPORT_EMMC_BOOT 759 static int do_mmc_bootbus(cmd_tbl_t *cmdtp, int flag, 760 int argc, char * const argv[]) 761 { 762 int dev; 763 struct mmc *mmc; 764 u8 width, reset, mode; 765 766 if (argc != 5) 767 return CMD_RET_USAGE; 768 dev = simple_strtoul(argv[1], NULL, 10); 769 width = simple_strtoul(argv[2], NULL, 10); 770 reset = simple_strtoul(argv[3], NULL, 10); 771 mode = simple_strtoul(argv[4], NULL, 10); 772 773 mmc = init_mmc_device(dev, false); 774 if (!mmc) 775 return CMD_RET_FAILURE; 776 777 if (IS_SD(mmc)) { 778 puts("BOOT_BUS_WIDTH only exists on eMMC\n"); 779 return CMD_RET_FAILURE; 780 } 781 782 /* acknowledge to be sent during boot operation */ 783 return mmc_set_boot_bus_width(mmc, width, reset, mode); 784 } 785 static int do_mmc_boot_resize(cmd_tbl_t *cmdtp, int flag, 786 int argc, char * const argv[]) 787 { 788 int dev; 789 struct mmc *mmc; 790 u32 bootsize, rpmbsize; 791 792 if (argc != 4) 793 return CMD_RET_USAGE; 794 dev = simple_strtoul(argv[1], NULL, 10); 795 bootsize = simple_strtoul(argv[2], NULL, 10); 796 rpmbsize = simple_strtoul(argv[3], NULL, 10); 797 798 mmc = init_mmc_device(dev, false); 799 if (!mmc) 800 return CMD_RET_FAILURE; 801 802 if (IS_SD(mmc)) { 803 printf("It is not a EMMC device\n"); 804 return CMD_RET_FAILURE; 805 } 806 807 if (mmc_boot_partition_size_change(mmc, bootsize, rpmbsize)) { 808 printf("EMMC boot partition Size change Failed.\n"); 809 return CMD_RET_FAILURE; 810 } 811 812 printf("EMMC boot partition Size %d MB\n", bootsize); 813 printf("EMMC RPMB partition Size %d MB\n", rpmbsize); 814 return CMD_RET_SUCCESS; 815 } 816 817 static int mmc_partconf_print(struct mmc *mmc) 818 { 819 u8 ack, access, part; 820 821 if (mmc->part_config == MMCPART_NOAVAILABLE) { 822 printf("No part_config info for ver. 0x%x\n", mmc->version); 823 return CMD_RET_FAILURE; 824 } 825 826 access = EXT_CSD_EXTRACT_PARTITION_ACCESS(mmc->part_config); 827 ack = EXT_CSD_EXTRACT_BOOT_ACK(mmc->part_config); 828 part = EXT_CSD_EXTRACT_BOOT_PART(mmc->part_config); 829 830 printf("EXT_CSD[179], PARTITION_CONFIG:\n" 831 "BOOT_ACK: 0x%x\n" 832 "BOOT_PARTITION_ENABLE: 0x%x\n" 833 "PARTITION_ACCESS: 0x%x\n", ack, part, access); 834 835 return CMD_RET_SUCCESS; 836 } 837 838 static int do_mmc_partconf(cmd_tbl_t *cmdtp, int flag, 839 int argc, char * const argv[]) 840 { 841 int dev; 842 struct mmc *mmc; 843 u8 ack, part_num, access; 844 845 if (argc != 2 && argc != 5) 846 return CMD_RET_USAGE; 847 848 dev = simple_strtoul(argv[1], NULL, 10); 849 850 mmc = init_mmc_device(dev, false); 851 if (!mmc) 852 return CMD_RET_FAILURE; 853 854 if (IS_SD(mmc)) { 855 puts("PARTITION_CONFIG only exists on eMMC\n"); 856 return CMD_RET_FAILURE; 857 } 858 859 if (argc == 2) 860 return mmc_partconf_print(mmc); 861 862 ack = simple_strtoul(argv[2], NULL, 10); 863 part_num = simple_strtoul(argv[3], NULL, 10); 864 access = simple_strtoul(argv[4], NULL, 10); 865 866 /* acknowledge to be sent during boot operation */ 867 return mmc_set_part_conf(mmc, ack, part_num, access); 868 } 869 static int do_mmc_rst_func(cmd_tbl_t *cmdtp, int flag, 870 int argc, char * const argv[]) 871 { 872 int dev; 873 struct mmc *mmc; 874 u8 enable; 875 876 /* 877 * Set the RST_n_ENABLE bit of RST_n_FUNCTION 878 * The only valid values are 0x0, 0x1 and 0x2 and writing 879 * a value of 0x1 or 0x2 sets the value permanently. 880 */ 881 if (argc != 3) 882 return CMD_RET_USAGE; 883 884 dev = simple_strtoul(argv[1], NULL, 10); 885 enable = simple_strtoul(argv[2], NULL, 10); 886 887 if (enable > 2) { 888 puts("Invalid RST_n_ENABLE value\n"); 889 return CMD_RET_USAGE; 890 } 891 892 mmc = init_mmc_device(dev, false); 893 if (!mmc) 894 return CMD_RET_FAILURE; 895 896 if (IS_SD(mmc)) { 897 puts("RST_n_FUNCTION only exists on eMMC\n"); 898 return CMD_RET_FAILURE; 899 } 900 901 return mmc_set_rst_n_function(mmc, enable); 902 } 903 #endif 904 static int do_mmc_setdsr(cmd_tbl_t *cmdtp, int flag, 905 int argc, char * const argv[]) 906 { 907 struct mmc *mmc; 908 u32 val; 909 int ret; 910 911 if (argc != 2) 912 return CMD_RET_USAGE; 913 val = simple_strtoul(argv[1], NULL, 16); 914 915 mmc = find_mmc_device(curr_device); 916 if (!mmc) { 917 printf("no mmc device at slot %x\n", curr_device); 918 return CMD_RET_FAILURE; 919 } 920 ret = mmc_set_dsr(mmc, val); 921 printf("set dsr %s\n", (!ret) ? "OK, force rescan" : "ERROR"); 922 if (!ret) { 923 mmc->has_init = 0; 924 if (mmc_init(mmc)) 925 return CMD_RET_FAILURE; 926 else 927 return CMD_RET_SUCCESS; 928 } 929 return ret; 930 } 931 932 #ifdef CONFIG_CMD_BKOPS_ENABLE 933 static int do_mmc_bkops_enable(cmd_tbl_t *cmdtp, int flag, 934 int argc, char * const argv[]) 935 { 936 int dev; 937 struct mmc *mmc; 938 939 if (argc != 2) 940 return CMD_RET_USAGE; 941 942 dev = simple_strtoul(argv[1], NULL, 10); 943 944 mmc = init_mmc_device(dev, false); 945 if (!mmc) 946 return CMD_RET_FAILURE; 947 948 if (IS_SD(mmc)) { 949 puts("BKOPS_EN only exists on eMMC\n"); 950 return CMD_RET_FAILURE; 951 } 952 953 return mmc_set_bkops_enable(mmc); 954 } 955 #endif 956 957 static cmd_tbl_t cmd_mmc[] = { 958 U_BOOT_CMD_MKENT(info, 1, 0, do_mmcinfo, "", ""), 959 U_BOOT_CMD_MKENT(read, 4, 1, do_mmc_read, "", ""), 960 U_BOOT_CMD_MKENT(write, 4, 0, do_mmc_write, "", ""), 961 U_BOOT_CMD_MKENT(erase, 3, 0, do_mmc_erase, "", ""), 962 U_BOOT_CMD_MKENT(rescan, 1, 1, do_mmc_rescan, "", ""), 963 U_BOOT_CMD_MKENT(part, 1, 1, do_mmc_part, "", ""), 964 U_BOOT_CMD_MKENT(dev, 3, 0, do_mmc_dev, "", ""), 965 U_BOOT_CMD_MKENT(list, 1, 1, do_mmc_list, "", ""), 966 U_BOOT_CMD_MKENT(hwpartition, 28, 0, do_mmc_hwpartition, "", ""), 967 #ifdef CONFIG_SUPPORT_EMMC_BOOT 968 U_BOOT_CMD_MKENT(bootbus, 5, 0, do_mmc_bootbus, "", ""), 969 U_BOOT_CMD_MKENT(bootpart-resize, 4, 0, do_mmc_boot_resize, "", ""), 970 U_BOOT_CMD_MKENT(partconf, 5, 0, do_mmc_partconf, "", ""), 971 U_BOOT_CMD_MKENT(rst-function, 3, 0, do_mmc_rst_func, "", ""), 972 #endif 973 #ifdef CONFIG_OPTEE_CLIENT 974 U_BOOT_CMD_MKENT(testrpmb, 1, 0, do_mmc_testrpmb, "", ""), 975 U_BOOT_CMD_MKENT(testefuse, 1, 0, do_mmc_testefuse, "", ""), 976 #endif 977 #ifdef CONFIG_SUPPORT_EMMC_RPMB 978 U_BOOT_CMD_MKENT(rpmb, CONFIG_SYS_MAXARGS, 1, do_mmcrpmb, "", ""), 979 #endif 980 U_BOOT_CMD_MKENT(setdsr, 2, 0, do_mmc_setdsr, "", ""), 981 #ifdef CONFIG_CMD_BKOPS_ENABLE 982 U_BOOT_CMD_MKENT(bkops-enable, 2, 0, do_mmc_bkops_enable, "", ""), 983 #endif 984 }; 985 986 static int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 987 { 988 cmd_tbl_t *cp; 989 990 cp = find_cmd_tbl(argv[1], cmd_mmc, ARRAY_SIZE(cmd_mmc)); 991 992 /* Drop the mmc command */ 993 argc--; 994 argv++; 995 996 if (cp == NULL || argc > cp->maxargs) 997 return CMD_RET_USAGE; 998 if (flag == CMD_FLAG_REPEAT && !cp->repeatable) 999 return CMD_RET_SUCCESS; 1000 1001 if (curr_device < 0) { 1002 if (get_mmc_num() > 0) { 1003 curr_device = 0; 1004 } else { 1005 puts("No MMC device available\n"); 1006 return CMD_RET_FAILURE; 1007 } 1008 } 1009 return cp->cmd(cmdtp, flag, argc, argv); 1010 } 1011 1012 U_BOOT_CMD( 1013 mmc, 29, 1, do_mmcops, 1014 "MMC sub system", 1015 "info - display info of the current MMC device\n" 1016 "mmc read addr blk# cnt\n" 1017 "mmc write addr blk# cnt\n" 1018 "mmc erase blk# cnt\n" 1019 "mmc rescan\n" 1020 "mmc part - lists available partition on current mmc device\n" 1021 "mmc dev [dev] [part] - show or set current mmc device [partition]\n" 1022 "mmc list - lists available devices\n" 1023 "mmc hwpartition [args...] - does hardware partitioning\n" 1024 " arguments (sizes in 512-byte blocks):\n" 1025 " [user [enh start cnt] [wrrel {on|off}]] - sets user data area attributes\n" 1026 " [gp1|gp2|gp3|gp4 cnt [enh] [wrrel {on|off}]] - general purpose partition\n" 1027 " [check|set|complete] - mode, complete set partitioning completed\n" 1028 " WARNING: Partitioning is a write-once setting once it is set to complete.\n" 1029 " Power cycling is required to initialize partitions after set to complete.\n" 1030 #ifdef CONFIG_SUPPORT_EMMC_BOOT 1031 "mmc bootbus dev boot_bus_width reset_boot_bus_width boot_mode\n" 1032 " - Set the BOOT_BUS_WIDTH field of the specified device\n" 1033 "mmc bootpart-resize <dev> <boot part size MB> <RPMB part size MB>\n" 1034 " - Change sizes of boot and RPMB partitions of specified device\n" 1035 "mmc partconf dev [boot_ack boot_partition partition_access]\n" 1036 " - Show or change the bits of the PARTITION_CONFIG field of the specified device\n" 1037 "mmc rst-function dev value\n" 1038 " - Change the RST_n_FUNCTION field of the specified device\n" 1039 " WARNING: This is a write-once field and 0 / 1 / 2 are the only valid values.\n" 1040 #endif 1041 #ifdef CONFIG_OPTEE_CLIENT 1042 "mmc testrpmb - test CA call static TA,and TA call rpmb in uboot\n" 1043 "mmc testefuse - test CA call static TA,and TA read or write efuse\n" 1044 #endif 1045 #ifdef CONFIG_SUPPORT_EMMC_RPMB 1046 "mmc rpmb read addr blk# cnt [address of auth-key] - block size is 256 bytes\n" 1047 "mmc rpmb write addr blk# cnt <address of auth-key> - block size is 256 bytes\n" 1048 "mmc rpmb key <address of auth-key> - program the RPMB authentication key.\n" 1049 "mmc rpmb counter - read the value of the write counter\n" 1050 #endif 1051 "mmc setdsr <value> - set DSR register value\n" 1052 #ifdef CONFIG_CMD_BKOPS_ENABLE 1053 "mmc bkops-enable <dev> - enable background operations handshake on device\n" 1054 " WARNING: This is a write-once setting.\n" 1055 #endif 1056 ); 1057 1058 /* Old command kept for compatibility. Same as 'mmc info' */ 1059 U_BOOT_CMD( 1060 mmcinfo, 1, 0, do_mmcinfo, 1061 "display MMC info", 1062 "- display info of the current MMC device" 1063 ); 1064 1065