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) %zu\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 return CMD_RET_SUCCESS; 198 } 199 200 #endif 201 202 #ifdef CONFIG_SUPPORT_EMMC_RPMB 203 char temp_original_part; 204 int init_rpmb(void) 205 { 206 struct mmc *mmc; 207 208 mmc = init_mmc_device(curr_device, false); 209 if (!mmc) 210 return CMD_RET_FAILURE; 211 212 if (!(mmc->version & MMC_VERSION_MMC)) { 213 printf("It is not a EMMC device\n"); 214 return CMD_RET_FAILURE; 215 } 216 if (mmc->version < MMC_VERSION_4_41) { 217 printf("RPMB not supported before version 4.41\n"); 218 return CMD_RET_FAILURE; 219 } 220 221 /* Switch to the RPMB partition */ 222 #ifndef CONFIG_BLK 223 temp_original_part = mmc->block_dev.hwpart; 224 debug("mmc->block_dev.hwpart\n"); 225 #else 226 temp_original_part = mmc_get_blk_desc(mmc)->hwpart; 227 debug("mmc_get_blk_desc(mmc)->hwpart\n"); 228 #endif 229 debug("init_rpmb temp_original_part = 0x%X\n", temp_original_part); 230 if (blk_select_hwpart_devnum 231 (IF_TYPE_MMC, curr_device, MMC_PART_RPMB) != 0) 232 return CMD_RET_FAILURE; 233 234 return CMD_RET_SUCCESS; 235 } 236 237 int finish_rpmb(void) 238 { 239 /* Return to original partition */ 240 debug("finish_rpmb temp_original_part = 0x%X\n", temp_original_part); 241 if (blk_select_hwpart_devnum 242 (IF_TYPE_MMC, curr_device, temp_original_part) != 0) 243 return CMD_RET_FAILURE; 244 245 return CMD_RET_SUCCESS; 246 } 247 248 int do_readcounter(struct s_rpmb *requestpackets) 249 { 250 struct mmc *mmc = find_mmc_device(curr_device); 251 252 return read_counter(mmc, requestpackets); 253 } 254 255 int do_programkey(struct s_rpmb *requestpackets) 256 { 257 struct mmc *mmc = find_mmc_device(curr_device); 258 259 return program_key(mmc, requestpackets); 260 } 261 262 int do_authenticatedread(struct s_rpmb *requestpackets, uint16_t block_count) 263 { 264 struct mmc *mmc = find_mmc_device(curr_device); 265 266 return authenticated_read(mmc, requestpackets, block_count); 267 } 268 269 int do_authenticatedwrite(struct s_rpmb *requestpackets) 270 { 271 struct mmc *mmc = find_mmc_device(curr_device); 272 273 return authenticated_write(mmc, requestpackets); 274 } 275 276 struct mmc *do_returnmmc(void) 277 { 278 struct mmc *mmc = find_mmc_device(curr_device); 279 280 return mmc; 281 } 282 283 static int confirm_key_prog(void) 284 { 285 puts("Warning: Programming authentication key can be done only once !\n" 286 " Use this command only if you are sure of what you are doing,\n" 287 "Really perform the key programming? <y/N> "); 288 if (confirm_yesno()) 289 return 1; 290 291 puts("Authentication key programming aborted\n"); 292 return 0; 293 } 294 static int do_mmcrpmb_key(cmd_tbl_t *cmdtp, int flag, 295 int argc, char * const argv[]) 296 { 297 void *key_addr; 298 struct mmc *mmc = find_mmc_device(curr_device); 299 300 if (argc != 2) 301 return CMD_RET_USAGE; 302 303 key_addr = (void *)simple_strtoul(argv[1], NULL, 16); 304 if (!confirm_key_prog()) 305 return CMD_RET_FAILURE; 306 if (mmc_rpmb_set_key(mmc, key_addr)) { 307 printf("ERROR - Key already programmed ?\n"); 308 return CMD_RET_FAILURE; 309 } 310 return CMD_RET_SUCCESS; 311 } 312 static int do_mmcrpmb_read(cmd_tbl_t *cmdtp, int flag, 313 int argc, char * const argv[]) 314 { 315 u16 blk, cnt; 316 void *addr; 317 int n; 318 void *key_addr = NULL; 319 struct mmc *mmc = find_mmc_device(curr_device); 320 321 if (argc < 4) 322 return CMD_RET_USAGE; 323 324 addr = (void *)simple_strtoul(argv[1], NULL, 16); 325 blk = simple_strtoul(argv[2], NULL, 16); 326 cnt = simple_strtoul(argv[3], NULL, 16); 327 328 if (argc == 5) 329 key_addr = (void *)simple_strtoul(argv[4], NULL, 16); 330 331 printf("\nMMC RPMB read: dev # %d, block # %d, count %d ... ", 332 curr_device, blk, cnt); 333 n = mmc_rpmb_read(mmc, addr, blk, cnt, key_addr); 334 335 printf("%d RPMB blocks read: %s\n", n, (n == cnt) ? "OK" : "ERROR"); 336 if (n != cnt) 337 return CMD_RET_FAILURE; 338 return CMD_RET_SUCCESS; 339 } 340 static int do_mmcrpmb_write(cmd_tbl_t *cmdtp, int flag, 341 int argc, char * const argv[]) 342 { 343 u16 blk, cnt; 344 void *addr; 345 int n; 346 void *key_addr; 347 struct mmc *mmc = find_mmc_device(curr_device); 348 349 if (argc != 5) 350 return CMD_RET_USAGE; 351 352 addr = (void *)simple_strtoul(argv[1], NULL, 16); 353 blk = simple_strtoul(argv[2], NULL, 16); 354 cnt = simple_strtoul(argv[3], NULL, 16); 355 key_addr = (void *)simple_strtoul(argv[4], NULL, 16); 356 357 printf("\nMMC RPMB write: dev # %d, block # %d, count %d ... ", 358 curr_device, blk, cnt); 359 n = mmc_rpmb_write(mmc, addr, blk, cnt, key_addr); 360 361 printf("%d RPMB blocks written: %s\n", n, (n == cnt) ? "OK" : "ERROR"); 362 if (n != cnt) 363 return CMD_RET_FAILURE; 364 return CMD_RET_SUCCESS; 365 } 366 static int do_mmcrpmb_counter(cmd_tbl_t *cmdtp, int flag, 367 int argc, char * const argv[]) 368 { 369 unsigned long counter; 370 struct mmc *mmc = find_mmc_device(curr_device); 371 372 if (mmc_rpmb_get_counter(mmc, &counter)) 373 return CMD_RET_FAILURE; 374 printf("RPMB Write counter= %lx\n", counter); 375 return CMD_RET_SUCCESS; 376 } 377 378 static cmd_tbl_t cmd_rpmb[] = { 379 U_BOOT_CMD_MKENT(key, 2, 0, do_mmcrpmb_key, "", ""), 380 U_BOOT_CMD_MKENT(read, 5, 1, do_mmcrpmb_read, "", ""), 381 U_BOOT_CMD_MKENT(write, 5, 0, do_mmcrpmb_write, "", ""), 382 U_BOOT_CMD_MKENT(counter, 1, 1, do_mmcrpmb_counter, "", ""), 383 }; 384 385 static int do_mmcrpmb(cmd_tbl_t *cmdtp, int flag, 386 int argc, char * const argv[]) 387 { 388 cmd_tbl_t *cp; 389 struct mmc *mmc; 390 char original_part; 391 int ret; 392 393 cp = find_cmd_tbl(argv[1], cmd_rpmb, ARRAY_SIZE(cmd_rpmb)); 394 395 /* Drop the rpmb subcommand */ 396 argc--; 397 argv++; 398 399 if (cp == NULL || argc > cp->maxargs) 400 return CMD_RET_USAGE; 401 if (flag == CMD_FLAG_REPEAT && !cp->repeatable) 402 return CMD_RET_SUCCESS; 403 404 mmc = init_mmc_device(curr_device, false); 405 if (!mmc) 406 return CMD_RET_FAILURE; 407 408 if (!(mmc->version & MMC_VERSION_MMC)) { 409 printf("It is not a EMMC device\n"); 410 return CMD_RET_FAILURE; 411 } 412 if (mmc->version < MMC_VERSION_4_41) { 413 printf("RPMB not supported before version 4.41\n"); 414 return CMD_RET_FAILURE; 415 } 416 /* Switch to the RPMB partition */ 417 #ifndef CONFIG_BLK 418 original_part = mmc->block_dev.hwpart; 419 #else 420 original_part = mmc_get_blk_desc(mmc)->hwpart; 421 #endif 422 if (blk_select_hwpart_devnum(IF_TYPE_MMC, curr_device, MMC_PART_RPMB) != 423 0) 424 return CMD_RET_FAILURE; 425 ret = cp->cmd(cmdtp, flag, argc, argv); 426 427 /* Return to original partition */ 428 if (blk_select_hwpart_devnum(IF_TYPE_MMC, curr_device, original_part) != 429 0) 430 return CMD_RET_FAILURE; 431 return ret; 432 } 433 #endif 434 435 static int do_mmc_read(cmd_tbl_t *cmdtp, int flag, 436 int argc, char * const argv[]) 437 { 438 struct mmc *mmc; 439 u32 blk, cnt, n; 440 void *addr; 441 442 if (argc != 4) 443 return CMD_RET_USAGE; 444 445 addr = (void *)simple_strtoul(argv[1], NULL, 16); 446 blk = simple_strtoul(argv[2], NULL, 16); 447 cnt = simple_strtoul(argv[3], NULL, 16); 448 449 mmc = init_mmc_device(curr_device, false); 450 if (!mmc) 451 return CMD_RET_FAILURE; 452 453 printf("\nMMC read: dev # %d, block # %d, count %d ... ", 454 curr_device, blk, cnt); 455 456 n = blk_dread(mmc_get_blk_desc(mmc), blk, cnt, addr); 457 printf("%d blocks read: %s\n", n, (n == cnt) ? "OK" : "ERROR"); 458 459 return (n == cnt) ? CMD_RET_SUCCESS : CMD_RET_FAILURE; 460 } 461 static int do_mmc_write(cmd_tbl_t *cmdtp, int flag, 462 int argc, char * const argv[]) 463 { 464 struct mmc *mmc; 465 u32 blk, cnt, n; 466 void *addr; 467 468 if (argc != 4) 469 return CMD_RET_USAGE; 470 471 addr = (void *)simple_strtoul(argv[1], NULL, 16); 472 blk = simple_strtoul(argv[2], NULL, 16); 473 cnt = simple_strtoul(argv[3], NULL, 16); 474 475 mmc = init_mmc_device(curr_device, false); 476 if (!mmc) 477 return CMD_RET_FAILURE; 478 479 printf("\nMMC write: dev # %d, block # %d, count %d ... ", 480 curr_device, blk, cnt); 481 482 if (mmc_getwp(mmc) == 1) { 483 printf("Error: card is write protected!\n"); 484 return CMD_RET_FAILURE; 485 } 486 n = blk_dwrite(mmc_get_blk_desc(mmc), blk, cnt, addr); 487 printf("%d blocks written: %s\n", n, (n == cnt) ? "OK" : "ERROR"); 488 489 return (n == cnt) ? CMD_RET_SUCCESS : CMD_RET_FAILURE; 490 } 491 static int do_mmc_erase(cmd_tbl_t *cmdtp, int flag, 492 int argc, char * const argv[]) 493 { 494 struct mmc *mmc; 495 u32 blk, cnt, n; 496 497 if (argc != 3) 498 return CMD_RET_USAGE; 499 500 blk = simple_strtoul(argv[1], NULL, 16); 501 cnt = simple_strtoul(argv[2], NULL, 16); 502 503 mmc = init_mmc_device(curr_device, false); 504 if (!mmc) 505 return CMD_RET_FAILURE; 506 507 printf("\nMMC erase: dev # %d, block # %d, count %d ... ", 508 curr_device, blk, cnt); 509 510 if (mmc_getwp(mmc) == 1) { 511 printf("Error: card is write protected!\n"); 512 return CMD_RET_FAILURE; 513 } 514 n = blk_derase(mmc_get_blk_desc(mmc), blk, cnt); 515 printf("%d blocks erased: %s\n", n, (n == cnt) ? "OK" : "ERROR"); 516 517 return (n == cnt) ? CMD_RET_SUCCESS : CMD_RET_FAILURE; 518 } 519 static int do_mmc_rescan(cmd_tbl_t *cmdtp, int flag, 520 int argc, char * const argv[]) 521 { 522 struct mmc *mmc; 523 524 mmc = init_mmc_device(curr_device, true); 525 if (!mmc) 526 return CMD_RET_FAILURE; 527 528 return CMD_RET_SUCCESS; 529 } 530 static int do_mmc_part(cmd_tbl_t *cmdtp, int flag, 531 int argc, char * const argv[]) 532 { 533 struct blk_desc *mmc_dev; 534 struct mmc *mmc; 535 536 mmc = init_mmc_device(curr_device, false); 537 if (!mmc) 538 return CMD_RET_FAILURE; 539 540 mmc_dev = blk_get_devnum_by_type(IF_TYPE_MMC, curr_device); 541 if (mmc_dev != NULL && mmc_dev->type != DEV_TYPE_UNKNOWN) { 542 part_print(mmc_dev); 543 return CMD_RET_SUCCESS; 544 } 545 546 puts("get mmc type error!\n"); 547 return CMD_RET_FAILURE; 548 } 549 static int do_mmc_dev(cmd_tbl_t *cmdtp, int flag, 550 int argc, char * const argv[]) 551 { 552 int dev, part = 0, ret; 553 struct mmc *mmc; 554 555 if (argc == 1) { 556 dev = curr_device; 557 } else if (argc == 2) { 558 dev = simple_strtoul(argv[1], NULL, 10); 559 } else if (argc == 3) { 560 dev = (int)simple_strtoul(argv[1], NULL, 10); 561 part = (int)simple_strtoul(argv[2], NULL, 10); 562 if (part > PART_ACCESS_MASK) { 563 printf("#part_num shouldn't be larger than %d\n", 564 PART_ACCESS_MASK); 565 return CMD_RET_FAILURE; 566 } 567 } else { 568 return CMD_RET_USAGE; 569 } 570 571 mmc = init_mmc_device(dev, false); 572 if (!mmc) 573 return CMD_RET_FAILURE; 574 575 ret = blk_select_hwpart_devnum(IF_TYPE_MMC, dev, part); 576 printf("switch to partitions #%d, %s\n", 577 part, (!ret) ? "OK" : "ERROR"); 578 if (ret) 579 return 1; 580 581 curr_device = dev; 582 if (mmc->part_config == MMCPART_NOAVAILABLE) 583 printf("mmc%d is current device\n", curr_device); 584 else 585 printf("mmc%d(part %d) is current device\n", 586 curr_device, mmc_get_blk_desc(mmc)->hwpart); 587 588 return CMD_RET_SUCCESS; 589 } 590 static int do_mmc_list(cmd_tbl_t *cmdtp, int flag, 591 int argc, char * const argv[]) 592 { 593 print_mmc_devices('\n'); 594 return CMD_RET_SUCCESS; 595 } 596 597 static int parse_hwpart_user(struct mmc_hwpart_conf *pconf, 598 int argc, char * const argv[]) 599 { 600 int i = 0; 601 602 memset(&pconf->user, 0, sizeof(pconf->user)); 603 604 while (i < argc) { 605 if (!strcmp(argv[i], "enh")) { 606 if (i + 2 >= argc) 607 return -1; 608 pconf->user.enh_start = 609 simple_strtoul(argv[i+1], NULL, 10); 610 pconf->user.enh_size = 611 simple_strtoul(argv[i+2], NULL, 10); 612 i += 3; 613 } else if (!strcmp(argv[i], "wrrel")) { 614 if (i + 1 >= argc) 615 return -1; 616 pconf->user.wr_rel_change = 1; 617 if (!strcmp(argv[i+1], "on")) 618 pconf->user.wr_rel_set = 1; 619 else if (!strcmp(argv[i+1], "off")) 620 pconf->user.wr_rel_set = 0; 621 else 622 return -1; 623 i += 2; 624 } else { 625 break; 626 } 627 } 628 return i; 629 } 630 631 static int parse_hwpart_gp(struct mmc_hwpart_conf *pconf, int pidx, 632 int argc, char * const argv[]) 633 { 634 int i; 635 636 memset(&pconf->gp_part[pidx], 0, sizeof(pconf->gp_part[pidx])); 637 638 if (1 >= argc) 639 return -1; 640 pconf->gp_part[pidx].size = simple_strtoul(argv[0], NULL, 10); 641 642 i = 1; 643 while (i < argc) { 644 if (!strcmp(argv[i], "enh")) { 645 pconf->gp_part[pidx].enhanced = 1; 646 i += 1; 647 } else if (!strcmp(argv[i], "wrrel")) { 648 if (i + 1 >= argc) 649 return -1; 650 pconf->gp_part[pidx].wr_rel_change = 1; 651 if (!strcmp(argv[i+1], "on")) 652 pconf->gp_part[pidx].wr_rel_set = 1; 653 else if (!strcmp(argv[i+1], "off")) 654 pconf->gp_part[pidx].wr_rel_set = 0; 655 else 656 return -1; 657 i += 2; 658 } else { 659 break; 660 } 661 } 662 return i; 663 } 664 665 static int do_mmc_hwpartition(cmd_tbl_t *cmdtp, int flag, 666 int argc, char * const argv[]) 667 { 668 struct mmc *mmc; 669 struct mmc_hwpart_conf pconf = { }; 670 enum mmc_hwpart_conf_mode mode = MMC_HWPART_CONF_CHECK; 671 int i, r, pidx; 672 673 mmc = init_mmc_device(curr_device, false); 674 if (!mmc) 675 return CMD_RET_FAILURE; 676 677 if (argc < 1) 678 return CMD_RET_USAGE; 679 i = 1; 680 while (i < argc) { 681 if (!strcmp(argv[i], "user")) { 682 i++; 683 r = parse_hwpart_user(&pconf, argc-i, &argv[i]); 684 if (r < 0) 685 return CMD_RET_USAGE; 686 i += r; 687 } else if (!strncmp(argv[i], "gp", 2) && 688 strlen(argv[i]) == 3 && 689 argv[i][2] >= '1' && argv[i][2] <= '4') { 690 pidx = argv[i][2] - '1'; 691 i++; 692 r = parse_hwpart_gp(&pconf, pidx, argc-i, &argv[i]); 693 if (r < 0) 694 return CMD_RET_USAGE; 695 i += r; 696 } else if (!strcmp(argv[i], "check")) { 697 mode = MMC_HWPART_CONF_CHECK; 698 i++; 699 } else if (!strcmp(argv[i], "set")) { 700 mode = MMC_HWPART_CONF_SET; 701 i++; 702 } else if (!strcmp(argv[i], "complete")) { 703 mode = MMC_HWPART_CONF_COMPLETE; 704 i++; 705 } else { 706 return CMD_RET_USAGE; 707 } 708 } 709 710 puts("Partition configuration:\n"); 711 if (pconf.user.enh_size) { 712 puts("\tUser Enhanced Start: "); 713 print_size(((u64)pconf.user.enh_start) << 9, "\n"); 714 puts("\tUser Enhanced Size: "); 715 print_size(((u64)pconf.user.enh_size) << 9, "\n"); 716 } else { 717 puts("\tNo enhanced user data area\n"); 718 } 719 if (pconf.user.wr_rel_change) 720 printf("\tUser partition write reliability: %s\n", 721 pconf.user.wr_rel_set ? "on" : "off"); 722 for (pidx = 0; pidx < 4; pidx++) { 723 if (pconf.gp_part[pidx].size) { 724 printf("\tGP%i Capacity: ", pidx+1); 725 print_size(((u64)pconf.gp_part[pidx].size) << 9, 726 pconf.gp_part[pidx].enhanced ? 727 " ENH\n" : "\n"); 728 } else { 729 printf("\tNo GP%i partition\n", pidx+1); 730 } 731 if (pconf.gp_part[pidx].wr_rel_change) 732 printf("\tGP%i write reliability: %s\n", pidx+1, 733 pconf.gp_part[pidx].wr_rel_set ? "on" : "off"); 734 } 735 736 if (!mmc_hwpart_config(mmc, &pconf, mode)) { 737 if (mode == MMC_HWPART_CONF_COMPLETE) 738 puts("Partitioning successful, " 739 "power-cycle to make effective\n"); 740 return CMD_RET_SUCCESS; 741 } else { 742 puts("Failed!\n"); 743 return CMD_RET_FAILURE; 744 } 745 } 746 747 #ifdef CONFIG_SUPPORT_EMMC_BOOT 748 static int do_mmc_bootbus(cmd_tbl_t *cmdtp, int flag, 749 int argc, char * const argv[]) 750 { 751 int dev; 752 struct mmc *mmc; 753 u8 width, reset, mode; 754 755 if (argc != 5) 756 return CMD_RET_USAGE; 757 dev = simple_strtoul(argv[1], NULL, 10); 758 width = simple_strtoul(argv[2], NULL, 10); 759 reset = simple_strtoul(argv[3], NULL, 10); 760 mode = simple_strtoul(argv[4], NULL, 10); 761 762 mmc = init_mmc_device(dev, false); 763 if (!mmc) 764 return CMD_RET_FAILURE; 765 766 if (IS_SD(mmc)) { 767 puts("BOOT_BUS_WIDTH only exists on eMMC\n"); 768 return CMD_RET_FAILURE; 769 } 770 771 /* acknowledge to be sent during boot operation */ 772 return mmc_set_boot_bus_width(mmc, width, reset, mode); 773 } 774 static int do_mmc_boot_resize(cmd_tbl_t *cmdtp, int flag, 775 int argc, char * const argv[]) 776 { 777 int dev; 778 struct mmc *mmc; 779 u32 bootsize, rpmbsize; 780 781 if (argc != 4) 782 return CMD_RET_USAGE; 783 dev = simple_strtoul(argv[1], NULL, 10); 784 bootsize = simple_strtoul(argv[2], NULL, 10); 785 rpmbsize = simple_strtoul(argv[3], NULL, 10); 786 787 mmc = init_mmc_device(dev, false); 788 if (!mmc) 789 return CMD_RET_FAILURE; 790 791 if (IS_SD(mmc)) { 792 printf("It is not a EMMC device\n"); 793 return CMD_RET_FAILURE; 794 } 795 796 if (mmc_boot_partition_size_change(mmc, bootsize, rpmbsize)) { 797 printf("EMMC boot partition Size change Failed.\n"); 798 return CMD_RET_FAILURE; 799 } 800 801 printf("EMMC boot partition Size %d MB\n", bootsize); 802 printf("EMMC RPMB partition Size %d MB\n", rpmbsize); 803 return CMD_RET_SUCCESS; 804 } 805 806 static int mmc_partconf_print(struct mmc *mmc) 807 { 808 u8 ack, access, part; 809 810 if (mmc->part_config == MMCPART_NOAVAILABLE) { 811 printf("No part_config info for ver. 0x%x\n", mmc->version); 812 return CMD_RET_FAILURE; 813 } 814 815 access = EXT_CSD_EXTRACT_PARTITION_ACCESS(mmc->part_config); 816 ack = EXT_CSD_EXTRACT_BOOT_ACK(mmc->part_config); 817 part = EXT_CSD_EXTRACT_BOOT_PART(mmc->part_config); 818 819 printf("EXT_CSD[179], PARTITION_CONFIG:\n" 820 "BOOT_ACK: 0x%x\n" 821 "BOOT_PARTITION_ENABLE: 0x%x\n" 822 "PARTITION_ACCESS: 0x%x\n", ack, part, access); 823 824 return CMD_RET_SUCCESS; 825 } 826 827 static int do_mmc_partconf(cmd_tbl_t *cmdtp, int flag, 828 int argc, char * const argv[]) 829 { 830 int dev; 831 struct mmc *mmc; 832 u8 ack, part_num, access; 833 834 if (argc != 2 && argc != 5) 835 return CMD_RET_USAGE; 836 837 dev = simple_strtoul(argv[1], NULL, 10); 838 839 mmc = init_mmc_device(dev, false); 840 if (!mmc) 841 return CMD_RET_FAILURE; 842 843 if (IS_SD(mmc)) { 844 puts("PARTITION_CONFIG only exists on eMMC\n"); 845 return CMD_RET_FAILURE; 846 } 847 848 if (argc == 2) 849 return mmc_partconf_print(mmc); 850 851 ack = simple_strtoul(argv[2], NULL, 10); 852 part_num = simple_strtoul(argv[3], NULL, 10); 853 access = simple_strtoul(argv[4], NULL, 10); 854 855 /* acknowledge to be sent during boot operation */ 856 return mmc_set_part_conf(mmc, ack, part_num, access); 857 } 858 static int do_mmc_rst_func(cmd_tbl_t *cmdtp, int flag, 859 int argc, char * const argv[]) 860 { 861 int dev; 862 struct mmc *mmc; 863 u8 enable; 864 865 /* 866 * Set the RST_n_ENABLE bit of RST_n_FUNCTION 867 * The only valid values are 0x0, 0x1 and 0x2 and writing 868 * a value of 0x1 or 0x2 sets the value permanently. 869 */ 870 if (argc != 3) 871 return CMD_RET_USAGE; 872 873 dev = simple_strtoul(argv[1], NULL, 10); 874 enable = simple_strtoul(argv[2], NULL, 10); 875 876 if (enable > 2) { 877 puts("Invalid RST_n_ENABLE value\n"); 878 return CMD_RET_USAGE; 879 } 880 881 mmc = init_mmc_device(dev, false); 882 if (!mmc) 883 return CMD_RET_FAILURE; 884 885 if (IS_SD(mmc)) { 886 puts("RST_n_FUNCTION only exists on eMMC\n"); 887 return CMD_RET_FAILURE; 888 } 889 890 return mmc_set_rst_n_function(mmc, enable); 891 } 892 #endif 893 static int do_mmc_setdsr(cmd_tbl_t *cmdtp, int flag, 894 int argc, char * const argv[]) 895 { 896 struct mmc *mmc; 897 u32 val; 898 int ret; 899 900 if (argc != 2) 901 return CMD_RET_USAGE; 902 val = simple_strtoul(argv[1], NULL, 16); 903 904 mmc = find_mmc_device(curr_device); 905 if (!mmc) { 906 printf("no mmc device at slot %x\n", curr_device); 907 return CMD_RET_FAILURE; 908 } 909 ret = mmc_set_dsr(mmc, val); 910 printf("set dsr %s\n", (!ret) ? "OK, force rescan" : "ERROR"); 911 if (!ret) { 912 mmc->has_init = 0; 913 if (mmc_init(mmc)) 914 return CMD_RET_FAILURE; 915 else 916 return CMD_RET_SUCCESS; 917 } 918 return ret; 919 } 920 921 #ifdef CONFIG_CMD_BKOPS_ENABLE 922 static int do_mmc_bkops_enable(cmd_tbl_t *cmdtp, int flag, 923 int argc, char * const argv[]) 924 { 925 int dev; 926 struct mmc *mmc; 927 928 if (argc != 2) 929 return CMD_RET_USAGE; 930 931 dev = simple_strtoul(argv[1], NULL, 10); 932 933 mmc = init_mmc_device(dev, false); 934 if (!mmc) 935 return CMD_RET_FAILURE; 936 937 if (IS_SD(mmc)) { 938 puts("BKOPS_EN only exists on eMMC\n"); 939 return CMD_RET_FAILURE; 940 } 941 942 return mmc_set_bkops_enable(mmc); 943 } 944 #endif 945 946 static cmd_tbl_t cmd_mmc[] = { 947 U_BOOT_CMD_MKENT(info, 1, 0, do_mmcinfo, "", ""), 948 U_BOOT_CMD_MKENT(read, 4, 1, do_mmc_read, "", ""), 949 U_BOOT_CMD_MKENT(write, 4, 0, do_mmc_write, "", ""), 950 U_BOOT_CMD_MKENT(erase, 3, 0, do_mmc_erase, "", ""), 951 U_BOOT_CMD_MKENT(rescan, 1, 1, do_mmc_rescan, "", ""), 952 U_BOOT_CMD_MKENT(part, 1, 1, do_mmc_part, "", ""), 953 U_BOOT_CMD_MKENT(dev, 3, 0, do_mmc_dev, "", ""), 954 U_BOOT_CMD_MKENT(list, 1, 1, do_mmc_list, "", ""), 955 U_BOOT_CMD_MKENT(hwpartition, 28, 0, do_mmc_hwpartition, "", ""), 956 #ifdef CONFIG_SUPPORT_EMMC_BOOT 957 U_BOOT_CMD_MKENT(bootbus, 5, 0, do_mmc_bootbus, "", ""), 958 U_BOOT_CMD_MKENT(bootpart-resize, 4, 0, do_mmc_boot_resize, "", ""), 959 U_BOOT_CMD_MKENT(partconf, 5, 0, do_mmc_partconf, "", ""), 960 U_BOOT_CMD_MKENT(rst-function, 3, 0, do_mmc_rst_func, "", ""), 961 #endif 962 #ifdef CONFIG_OPTEE_CLIENT 963 U_BOOT_CMD_MKENT(testrpmb, 1, 0, do_mmc_testrpmb, "", ""), 964 U_BOOT_CMD_MKENT(testefuse, 1, 0, do_mmc_testefuse, "", ""), 965 #endif 966 #ifdef CONFIG_SUPPORT_EMMC_RPMB 967 U_BOOT_CMD_MKENT(rpmb, CONFIG_SYS_MAXARGS, 1, do_mmcrpmb, "", ""), 968 #endif 969 U_BOOT_CMD_MKENT(setdsr, 2, 0, do_mmc_setdsr, "", ""), 970 #ifdef CONFIG_CMD_BKOPS_ENABLE 971 U_BOOT_CMD_MKENT(bkops-enable, 2, 0, do_mmc_bkops_enable, "", ""), 972 #endif 973 }; 974 975 static int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 976 { 977 cmd_tbl_t *cp; 978 979 cp = find_cmd_tbl(argv[1], cmd_mmc, ARRAY_SIZE(cmd_mmc)); 980 981 /* Drop the mmc command */ 982 argc--; 983 argv++; 984 985 if (cp == NULL || argc > cp->maxargs) 986 return CMD_RET_USAGE; 987 if (flag == CMD_FLAG_REPEAT && !cp->repeatable) 988 return CMD_RET_SUCCESS; 989 990 if (curr_device < 0) { 991 if (get_mmc_num() > 0) { 992 curr_device = 0; 993 } else { 994 puts("No MMC device available\n"); 995 return CMD_RET_FAILURE; 996 } 997 } 998 return cp->cmd(cmdtp, flag, argc, argv); 999 } 1000 1001 U_BOOT_CMD( 1002 mmc, 29, 1, do_mmcops, 1003 "MMC sub system", 1004 "info - display info of the current MMC device\n" 1005 "mmc read addr blk# cnt\n" 1006 "mmc write addr blk# cnt\n" 1007 "mmc erase blk# cnt\n" 1008 "mmc rescan\n" 1009 "mmc part - lists available partition on current mmc device\n" 1010 "mmc dev [dev] [part] - show or set current mmc device [partition]\n" 1011 "mmc list - lists available devices\n" 1012 "mmc hwpartition [args...] - does hardware partitioning\n" 1013 " arguments (sizes in 512-byte blocks):\n" 1014 " [user [enh start cnt] [wrrel {on|off}]] - sets user data area attributes\n" 1015 " [gp1|gp2|gp3|gp4 cnt [enh] [wrrel {on|off}]] - general purpose partition\n" 1016 " [check|set|complete] - mode, complete set partitioning completed\n" 1017 " WARNING: Partitioning is a write-once setting once it is set to complete.\n" 1018 " Power cycling is required to initialize partitions after set to complete.\n" 1019 #ifdef CONFIG_SUPPORT_EMMC_BOOT 1020 "mmc bootbus dev boot_bus_width reset_boot_bus_width boot_mode\n" 1021 " - Set the BOOT_BUS_WIDTH field of the specified device\n" 1022 "mmc bootpart-resize <dev> <boot part size MB> <RPMB part size MB>\n" 1023 " - Change sizes of boot and RPMB partitions of specified device\n" 1024 "mmc partconf dev [boot_ack boot_partition partition_access]\n" 1025 " - Show or change the bits of the PARTITION_CONFIG field of the specified device\n" 1026 "mmc rst-function dev value\n" 1027 " - Change the RST_n_FUNCTION field of the specified device\n" 1028 " WARNING: This is a write-once field and 0 / 1 / 2 are the only valid values.\n" 1029 #endif 1030 #ifdef CONFIG_OPTEE_CLIENT 1031 "mmc testrpmb - test CA call static TA,and TA call rpmb in uboot\n" 1032 "mmc testefuse - test CA call static TA,and TA read or write efuse\n" 1033 #endif 1034 #ifdef CONFIG_SUPPORT_EMMC_RPMB 1035 "mmc rpmb read addr blk# cnt [address of auth-key] - block size is 256 bytes\n" 1036 "mmc rpmb write addr blk# cnt <address of auth-key> - block size is 256 bytes\n" 1037 "mmc rpmb key <address of auth-key> - program the RPMB authentication key.\n" 1038 "mmc rpmb counter - read the value of the write counter\n" 1039 #endif 1040 "mmc setdsr <value> - set DSR register value\n" 1041 #ifdef CONFIG_CMD_BKOPS_ENABLE 1042 "mmc bkops-enable <dev> - enable background operations handshake on device\n" 1043 " WARNING: This is a write-once setting.\n" 1044 #endif 1045 ); 1046 1047 /* Old command kept for compatibility. Same as 'mmc info' */ 1048 U_BOOT_CMD( 1049 mmcinfo, 1, 0, do_mmcinfo, 1050 "display MMC info", 1051 "- display info of the current MMC device" 1052 ); 1053 1054