1 /* Copyright 2013-2015 IBM Corp. 2 * 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 12 * implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #define _GNU_SOURCE 18 19 #include <stdio.h> 20 #include <stdlib.h> 21 #include <string.h> 22 #include <fcntl.h> 23 #include <sys/mman.h> 24 #include <sys/types.h> 25 #include <sys/stat.h> 26 #include <unistd.h> 27 #include <byteswap.h> 28 #include <stdint.h> 29 #include <stdbool.h> 30 #include <getopt.h> 31 #include <limits.h> 32 #include <arpa/inet.h> 33 #include <assert.h> 34 #include <inttypes.h> 35 36 #include <libflash/libflash.h> 37 #include <libflash/libffs.h> 38 #include <libflash/blocklevel.h> 39 #include <libflash/ecc.h> 40 #include <common/arch_flash.h> 41 #include "progress.h" 42 43 #define __aligned(x) __attribute__((aligned(x))) 44 45 struct flash_details { 46 struct blocklevel_device *bl; 47 int need_relock; 48 const char *name; 49 uint64_t toc; 50 uint64_t total_size; 51 uint32_t erase_granule; 52 bool mark_ecc; 53 }; 54 55 /* Full pflash version number (possibly includes gitid). */ 56 extern const char version[]; 57 58 const char *flashfilename = NULL; 59 static bool must_confirm = true; 60 static bool dummy_run; 61 static bool bmc_flash; 62 63 #define FILE_BUF_SIZE 0x10000 64 static uint8_t file_buf[FILE_BUF_SIZE] __aligned(0x1000); 65 66 static bool check_confirm(void) 67 { 68 char yes[8], *p; 69 70 if (!must_confirm) 71 return true; 72 73 printf("WARNING ! This will modify your %s flash chip content !\n", 74 bmc_flash ? "BMC" : "HOST"); 75 printf("Enter \"yes\" to confirm:"); 76 memset(yes, 0, sizeof(yes)); 77 if (!fgets(yes, 7, stdin)) 78 return false; 79 p = strchr(yes, 10); 80 if (p) 81 *p = 0; 82 p = strchr(yes, 13); 83 if (p) 84 *p = 0; 85 if (strcmp(yes, "yes")) { 86 printf("Operation cancelled !\n"); 87 return false; 88 } 89 must_confirm = false; 90 return true; 91 } 92 93 static uint32_t print_ffs_info(struct ffs_handle *ffsh, uint32_t toc) 94 { 95 struct ffs_entry *ent; 96 uint32_t next_toc = toc; 97 int rc; 98 int i; 99 100 printf("\n"); 101 printf("TOC@0x%08x Partitions:\n", toc); 102 printf("-----------\n"); 103 104 for (i = 0;; i++) { 105 uint32_t start, size, act, end; 106 struct ffs_entry_user user; 107 char *name = NULL, *flags; 108 109 rc = ffs_part_info(ffsh, i, &name, &start, &size, &act, NULL); 110 if (rc == FFS_ERR_PART_NOT_FOUND) 111 break; 112 113 ent = ffs_entry_get(ffsh, i); 114 if (rc || !ent) { 115 fprintf(stderr, "Error %d scanning partitions\n", 116 !ent ? FFS_ERR_PART_NOT_FOUND : rc); 117 goto out; 118 } 119 120 user = ffs_entry_user_get(ent); 121 ffs_entry_put(ent); 122 flags = ffs_entry_user_to_string(&user); 123 if (!flags) 124 goto out; 125 126 end = start + size; 127 printf("ID=%02d %15s 0x%08x..0x%08x (actual=0x%08x) [%s]\n", 128 i, name, start, end, act, flags); 129 130 if (strcmp(name, "OTHER_SIDE") == 0) 131 next_toc = start; 132 133 free(flags); 134 out: 135 free(name); 136 } 137 138 return next_toc; 139 } 140 141 static struct ffs_handle *open_ffs(struct flash_details *flash) 142 { 143 struct ffs_handle *ffsh; 144 int rc; 145 146 rc = ffs_init(flash->toc, flash->total_size, 147 flash->bl, &ffsh, flash->mark_ecc); 148 if (rc) { 149 fprintf(stderr, "Error %d opening ffs !\n", rc); 150 if (flash->toc) { 151 fprintf(stderr, "You specified 0x%" PRIx64 " as the libffs TOC\n" 152 "Looks like it doesn't exist\n", flash->toc); 153 return NULL; 154 } 155 } 156 157 return ffsh; 158 } 159 160 static void print_flash_info(struct flash_details *flash) 161 { 162 struct ffs_handle *ffsh; 163 uint32_t next_toc; 164 uint32_t toc; 165 166 printf("Flash info:\n"); 167 printf("-----------\n"); 168 printf("Name = %s\n", flash->name); 169 printf("Total size = %" PRIu64 "MB\t Flags E:ECC, P:PRESERVED, R:READONLY, " 170 "B:BACKUP\n", flash->total_size >> 20); 171 printf("Erase granule = %2d%-13sF:REPROVISION, V:VOLATILE, C:CLEARECC\n", 172 flash->erase_granule >> 10, "KB"); 173 174 if (bmc_flash) 175 return; 176 177 toc = flash->toc; 178 179 ffsh = open_ffs(flash); 180 if (!ffsh) 181 return; 182 183 next_toc = print_ffs_info(ffsh, toc); 184 ffs_close(ffsh); 185 while(next_toc != toc) { 186 struct ffs_handle *next_ffsh; 187 188 flash->toc = next_toc; 189 next_ffsh = open_ffs(flash); 190 if (!next_ffsh) 191 break; 192 next_toc = print_ffs_info(next_ffsh, next_toc); 193 ffs_close(next_ffsh); 194 } 195 flash->toc = toc; 196 } 197 198 static struct ffs_handle *open_partition(struct flash_details *flash, 199 const char *name, uint32_t *index) 200 { 201 struct ffs_handle *ffsh; 202 int rc; 203 204 ffsh = open_ffs(flash); 205 if (!ffsh) 206 return NULL; 207 208 if (!name) 209 /* Just open the FFS */ 210 return ffsh; 211 212 /* Find partition */ 213 rc = ffs_lookup_part(ffsh, name, index); 214 if (rc == FFS_ERR_PART_NOT_FOUND) { 215 fprintf(stderr, "Partition '%s' not found !\n", name); 216 goto out; 217 } 218 if (rc) { 219 fprintf(stderr, "Error %d looking for partition '%s' !\n", 220 rc, name); 221 goto out; 222 } 223 return ffsh; 224 out: 225 ffs_close(ffsh); 226 return NULL; 227 } 228 229 static struct ffs_handle *lookup_partition_at_toc(struct flash_details *flash, 230 const char *name, uint32_t *index) 231 { 232 return open_partition(flash, name, index); 233 } 234 235 static struct ffs_handle *lookup_partition_at_side(struct flash_details *flash, 236 int side, const char *name, uint32_t *index) 237 { 238 uint32_t toc = 0; 239 int rc; 240 241 if (side == 1) { 242 struct ffs_handle *ffsh; 243 uint32_t side_index; 244 245 ffsh = open_partition(flash, "OTHER_SIDE", &side_index); 246 if (!ffsh) 247 return NULL; 248 249 /* Just need to know where it starts */ 250 rc = ffs_part_info(ffsh, side_index, NULL, &toc, NULL, NULL, NULL); 251 ffs_close(ffsh); 252 if (rc) 253 return NULL; 254 } 255 256 flash->toc = toc; 257 return lookup_partition_at_toc(flash, name, index); 258 } 259 260 static int erase_chip(struct flash_details *flash) 261 { 262 bool confirm; 263 int rc; 264 uint64_t pos; 265 266 printf("About to erase chip !\n"); 267 confirm = check_confirm(); 268 if (!confirm) 269 return 1; 270 271 printf("Erasing... (may take a while)\n"); 272 fflush(stdout); 273 274 if (dummy_run) { 275 printf("skipped (dummy)\n"); 276 return 1; 277 } 278 279 /* 280 * We could use arch_flash_erase_chip() here BUT everyone really 281 * likes the progress bars. 282 * Lets do an erase block at a time erase then... 283 */ 284 progress_init(flash->total_size); 285 for (pos = 0; pos < flash->total_size; pos += flash->erase_granule) { 286 rc = blocklevel_erase(flash->bl, pos, flash->erase_granule); 287 if (rc) 288 break; 289 progress_tick(pos); 290 } 291 progress_end(); 292 if (rc) { 293 fprintf(stderr, "Error %d erasing chip\n", rc); 294 return rc; 295 } 296 297 printf("done !\n"); 298 return 0; 299 } 300 301 static int erase_range(struct flash_details *flash, 302 uint32_t start, uint32_t size, bool will_program, 303 struct ffs_handle *ffsh, int ffs_index) 304 { 305 uint32_t done = 0, erase_mask = flash->erase_granule - 1; 306 struct ffs_entry *toc; 307 bool confirm; 308 int rc; 309 310 printf("About to erase 0x%08x..0x%08x !\n", start, start + size); 311 confirm = check_confirm(); 312 if (!confirm) 313 return 1; 314 315 if (dummy_run) { 316 printf("skipped (dummy)\n"); 317 return 1; 318 } 319 320 printf("Erasing...\n"); 321 /* 322 * blocklevel_smart_erase() can do the entire thing in one call 323 * BUT everyone really likes progress bars so break stuff up 324 */ 325 progress_init(size); 326 if (start & erase_mask) { 327 /* 328 * Align to next erase block, or just do the entire 329 * thing if we fit within one erase block 330 */ 331 uint32_t first_size = MIN(size, (flash->erase_granule - (start & erase_mask))); 332 333 rc = blocklevel_smart_erase(flash->bl, start, first_size); 334 if (rc) { 335 fprintf(stderr, "Failed to blocklevel_smart_erase(): %d\n", rc); 336 return 1; 337 } 338 size -= first_size; 339 done = first_size; 340 start += first_size; 341 } 342 progress_tick(done); 343 while (size & ~(erase_mask)) { 344 rc = blocklevel_smart_erase(flash->bl, start, flash->erase_granule); 345 if (rc) { 346 fprintf(stderr, "Failed to blocklevel_smart_erase(): %d\n", rc); 347 return 1; 348 } 349 start += flash->erase_granule; 350 size -= flash->erase_granule; 351 done += flash->erase_granule; 352 progress_tick(done); 353 } 354 if (size) { 355 rc = blocklevel_smart_erase(flash->bl, start, size); 356 if (rc) { 357 fprintf(stderr, "Failed to blocklevel_smart_erase(): %d\n", rc); 358 return 1; 359 } 360 done += size; 361 progress_tick(done); 362 } 363 progress_end(); 364 365 if (!ffsh) 366 return 0; 367 368 /* If this is a flash partition, mark it empty if we aren't 369 * going to program over it as well 370 */ 371 toc = ffs_entry_get(ffsh, 0); 372 if (toc) { 373 struct ffs_entry_user user; 374 bool rw_toc; 375 376 user = ffs_entry_user_get(toc); 377 rw_toc = !(user.miscflags & FFS_MISCFLAGS_READONLY); 378 if (ffs_index >= 0 && !will_program && rw_toc) { 379 printf("Updating actual size in partition header...\n"); 380 ffs_update_act_size(ffsh, ffs_index, 0); 381 } 382 } 383 384 return 0; 385 } 386 387 static int set_ecc(struct flash_details *flash, uint32_t start, uint32_t size) 388 { 389 uint32_t i = start + 8; 390 uint8_t ecc = 0; 391 bool confirm; 392 int rc; 393 394 printf("About to erase and set ECC bits in region 0x%08x to 0x%08x\n", start, start + size); 395 confirm = check_confirm(); 396 if (!confirm) 397 return 1; 398 399 rc = erase_range(flash, start, size, true, NULL, 0); 400 if (rc) { 401 fprintf(stderr, "Couldn't erase region to mark with ECC\n"); 402 return rc; 403 } 404 405 printf("Programming ECC bits...\n"); 406 progress_init(size); 407 while (i < start + size) { 408 rc = blocklevel_write(flash->bl, i, &ecc, sizeof(ecc)); 409 if (rc) { 410 fprintf(stderr, "\nError setting ECC byte at 0x%08x\n", i); 411 return rc; 412 } 413 i += 9; 414 progress_tick(i - start); 415 } 416 progress_end(); 417 return 0; 418 } 419 420 static int program_file(struct blocklevel_device *bl, 421 const char *file, uint32_t start, uint32_t size, 422 struct ffs_handle *ffsh, int ffs_index) 423 { 424 uint32_t actual_size = 0; 425 struct ffs_entry *toc; 426 int fd, rc = 0; 427 bool confirm; 428 429 fd = open(file, O_RDONLY); 430 if (fd == -1) { 431 perror("Failed to open file"); 432 return 1; 433 } 434 printf("About to program \"%s\" at 0x%08x..0x%08x !\n", 435 file, start, start + size); 436 confirm = check_confirm(); 437 if (!confirm) { 438 rc = 1; 439 goto out; 440 } 441 442 if (dummy_run) { 443 printf("skipped (dummy)\n"); 444 rc = 1; 445 goto out; 446 } 447 448 printf("Programming & Verifying...\n"); 449 progress_init(size); 450 while(size) { 451 ssize_t len; 452 453 len = read(fd, file_buf, FILE_BUF_SIZE); 454 if (len < 0) { 455 perror("Error reading file"); 456 rc = 1; 457 goto out; 458 } 459 if (len == 0) 460 break; 461 if (len > size) 462 len = size; 463 size -= len; 464 actual_size += len; 465 rc = blocklevel_write(bl, start, file_buf, len); 466 if (rc) { 467 if (rc == FLASH_ERR_VERIFY_FAILURE) 468 fprintf(stderr, "Verification failed for" 469 " chunk at 0x%08x\n", start); 470 else 471 fprintf(stderr, "Flash write error %d for" 472 " chunk at 0x%08x\n", rc, start); 473 goto out; 474 } 475 start += len; 476 progress_tick(actual_size); 477 } 478 progress_end(); 479 480 if (!ffsh) 481 goto out; 482 483 /* If this is a flash partition, adjust its size */ 484 toc = ffs_entry_get(ffsh, 0); 485 if (toc) { 486 struct ffs_entry_user user; 487 bool rw_toc; 488 489 user = ffs_entry_user_get(toc); 490 rw_toc = !(user.miscflags & FFS_MISCFLAGS_READONLY); 491 if (ffs_index >= 0 && rw_toc) { 492 printf("Updating actual size in partition header...\n"); 493 ffs_update_act_size(ffsh, ffs_index, actual_size); 494 } 495 } 496 out: 497 close(fd); 498 return rc; 499 } 500 501 static int do_read_file(struct blocklevel_device *bl, const char *file, 502 uint32_t start, uint32_t size, uint32_t skip_size) 503 { 504 int fd, rc = 0; 505 uint32_t done = 0; 506 507 fd = open(file, O_WRONLY | O_TRUNC | O_CREAT, 00666); 508 if (fd == -1) { 509 perror("Failed to open file"); 510 return 1; 511 } 512 start += skip_size; 513 size -= skip_size; 514 515 printf("Reading to \"%s\" from 0x%08x..0x%08x !\n", 516 file, start, start + size); 517 518 progress_init(size); 519 while(size) { 520 ssize_t len; 521 522 len = size > FILE_BUF_SIZE ? FILE_BUF_SIZE : size; 523 rc = blocklevel_read(bl, start, file_buf, len); 524 if (rc) { 525 fprintf(stderr, "Flash read error %d for" 526 " chunk at 0x%08x\n", rc, start); 527 break; 528 } 529 rc = write(fd, file_buf, len); 530 /* 531 * zero isn't strictly an error. 532 * Treat it as such so we can be sure we'lre always 533 * making forward progress. 534 */ 535 if (rc <= 0) { 536 perror("Error writing file"); 537 break; 538 } 539 start += rc; 540 size -= rc; 541 done += rc; 542 progress_tick(done); 543 } 544 progress_end(); 545 close(fd); 546 return size ? rc : 0; 547 } 548 549 static int enable_4B_addresses(struct blocklevel_device *bl) 550 { 551 int rc; 552 553 printf("Switching to 4-bytes address mode\n"); 554 555 rc = arch_flash_4b_mode(bl, true); 556 if (rc) { 557 if (rc == -1) { 558 fprintf(stderr, "Switching address mode not available on this architecture\n"); 559 } else { 560 fprintf(stderr, "Error %d enabling 4b mode\n", rc); 561 } 562 } 563 564 return rc; 565 } 566 567 static int disable_4B_addresses(struct blocklevel_device *bl) 568 { 569 int rc; 570 571 printf("Switching to 3-bytes address mode\n"); 572 573 rc = arch_flash_4b_mode(bl, false); 574 if (rc) { 575 if (rc == -1) { 576 fprintf(stderr, "Switching address mode not available on this architecture\n"); 577 } else { 578 fprintf(stderr, "Error %d enabling 4b mode\n", rc); 579 } 580 } 581 582 return rc; 583 } 584 585 static void print_partition_detail(struct ffs_handle *ffsh, uint32_t part_id) 586 { 587 uint32_t start, size, act, end; 588 char *ent_name = NULL, *flags; 589 struct ffs_entry *ent; 590 int rc, l; 591 592 rc = ffs_part_info(ffsh, part_id, &ent_name, &start, &size, 593 &act, NULL); 594 if (rc) { 595 fprintf(stderr, "Partition with ID %d doesn't exist error: %d\n", 596 part_id, rc); 597 goto out; 598 } 599 600 ent = ffs_entry_get(ffsh, part_id); 601 if (!ent) { 602 rc = FFS_ERR_PART_NOT_FOUND; 603 fprintf(stderr, "Couldn't open partition entry\n"); 604 goto out; 605 } 606 607 printf("Detailed partition information\n"); 608 end = start + size; 609 printf("Name:\n"); 610 printf("%s (ID=%02d)\n\n", ent_name, part_id); 611 printf("%-10s %-10s %-10s\n", "Start", "End", "Actual"); 612 printf("0x%08x 0x%08x 0x%08x\n\n", start, end, act); 613 614 printf("Flags:\n"); 615 616 l = asprintf(&flags, "%s%s%s%s%s%s%s", has_ecc(ent) ? "ECC [E]\n" : "", 617 has_flag(ent, FFS_MISCFLAGS_PRESERVED) ? "PRESERVED [P]\n" : "", 618 has_flag(ent, FFS_MISCFLAGS_READONLY) ? "READONLY [R]\n" : "", 619 has_flag(ent, FFS_MISCFLAGS_BACKUP) ? "BACKUP [B]\n" : "", 620 has_flag(ent, FFS_MISCFLAGS_REPROVISION) ? 621 "REPROVISION [F]\n" : "", 622 has_flag(ent, FFS_MISCFLAGS_VOLATILE) ? "VOLATILE [V]\n" : "", 623 has_flag(ent, FFS_MISCFLAGS_CLEARECC) ? "CLEARECC [C]\n" : ""); 624 ffs_entry_put(ent); 625 if (l < 0) { 626 fprintf(stderr, "Memory allocation failure printing flags!\n"); 627 goto out; 628 } 629 630 printf("%s", flags); 631 free(flags); 632 633 out: 634 free(ent_name); 635 } 636 637 static void print_version(void) 638 { 639 printf("Open-Power Flash tool %s\n", version); 640 } 641 642 static void print_help(const char *pname) 643 { 644 printf("Usage: %s [options] commands...\n\n", pname); 645 printf(" Options:\n"); 646 printf("\t-a address, --address=address\n"); 647 printf("\t\tSpecify the start address for erasing, reading\n"); 648 printf("\t\tor flashing\n\n"); 649 printf("\t-s size, --size=size\n"); 650 printf("\t\tSpecify the size in bytes for erasing, reading\n"); 651 printf("\t\tor flashing\n\n"); 652 printf("\t-P part_name, --partition=part_name\n"); 653 printf("\t\tSpecify the partition whose content is to be erased\n"); 654 printf("\t\tprogrammed or read. This is an alternative to -a and -s\n"); 655 printf("\t\tif both -P and -s are specified, the smallest of the\n"); 656 printf("\t\ttwo will be used\n\n"); 657 printf("\t-f, --force\n"); 658 printf("\t\tDon't ask for confirmation before erasing or flashing\n\n"); 659 printf("\t-d, --dummy\n"); 660 printf("\t\tDon't write to flash\n\n"); 661 printf("\t--direct\n"); 662 printf("\t\tBypass all safety provided to you by the kernel driver\n"); 663 printf("\t\tand use the flash driver built into pflash.\n"); 664 printf("\t\tIf you have mtd devices and you use this command, the\n"); 665 printf("\t\tsystem may become unstable.\n"); 666 printf("\t\tIf you are reading this sentence then this flag is not\n"); 667 printf("\t\twhat you want! Using this feature without knowing\n"); 668 printf("\t\twhat it does can and likely will result in a bricked\n"); 669 printf("\t\tmachine\n\n"); 670 printf("\t-b, --bmc\n"); 671 printf("\t\tTarget BMC flash instead of host flash.\n"); 672 printf("\t\tNote: This carries a high chance of bricking your BMC if you\n"); 673 printf("\t\tdon't know what you're doing. Consider --mtd to be safe(r)\n\n"); 674 printf("\t-F filename, --flash-file filename\n"); 675 printf("\t\tTarget filename instead of actual flash.\n\n"); 676 printf("\t-S, --side\n"); 677 printf("\t\tSide of the flash on which to operate, 0 (default) or 1\n\n"); 678 printf("\t--skip=N\n"); 679 printf("\t\tSkip N number of bytes from the start when reading\n\n"); 680 printf("\t-T, --toc\n"); 681 printf("\t\tlibffs TOC on which to operate, defaults to 0.\n"); 682 printf("\t\tleading 0x is required for interpretation of a hex value\n\n"); 683 printf("\t-g\n"); 684 printf("\t\tEnable verbose libflash debugging\n\n"); 685 printf(" Commands:\n"); 686 printf("\t-4, --enable-4B\n"); 687 printf("\t\tSwitch the flash and controller to 4-bytes address\n"); 688 printf("\t\tmode (no confirmation needed).\n\n"); 689 printf("\t-3, --disable-4B\n"); 690 printf("\t\tSwitch the flash and controller to 3-bytes address\n"); 691 printf("\t\tmode (no confirmation needed).\n\n"); 692 printf("\t-r file, --read=file\n"); 693 printf("\t\tRead flash content from address into file, use -s\n"); 694 printf("\t\tto specify the size to read (or it will use the source\n"); 695 printf("\t\tfile size if used in conjunction with -p and -s is not\n"); 696 printf("\t\tspecified). When using -r together with -e or -p, the\n"); 697 printf("\t\tread will be performed first\n\n"); 698 printf("\t-E, --erase-all\n"); 699 printf("\t\tErase entire flash chip\n"); 700 printf("\t\t(Not supported on all chips/controllers)\n\n"); 701 printf("\t-e, --erase\n"); 702 printf("\t\tErase the specified region. If size or address are not\n"); 703 printf("\t\tspecified, but \'--program\' is used, then the file\n"); 704 printf("\t\tsize will be used (rounded to an erase block) and the\n"); 705 printf("\t\taddress defaults to 0.\n\n"); 706 printf("\t-p file, --program=file\n"); 707 printf("\t\tWill program the file to flash. If the address is not\n"); 708 printf("\t\tspecified, it will use 0. If the size is not specified\n"); 709 printf("\t\tit will use the file size. Otherwise it will limit to\n"); 710 printf("\t\tthe specified size (whatever is smaller). If used in\n"); 711 printf("\t\tconjunction with any erase command, the erase will\n"); 712 printf("\t\ttake place first.\n\n"); 713 printf("\t-t, --tune\n"); 714 printf("\t\tJust tune the flash controller & access size\n"); 715 printf("\t\tMust be used in conjuction with --direct\n"); 716 printf("\t\t(Implicit for all other operations)\n\n"); 717 printf("\t-c --clear\n"); 718 printf("\t\tUsed to ECC clear a partition of the flash\n"); 719 printf("\t\tMust be used in conjunction with -P. Will erase the\n"); 720 printf("\t\tpartition and then set all the ECC bits as they should be\n\n"); 721 printf("\t-9 --ecc\n"); 722 printf("\t\tEncode/Decode ECC where specified in the FFS header.\n"); 723 printf("\t\tThis 9 byte ECC method is used for some OpenPOWER\n"); 724 printf("\t\tpartitions.\n"); 725 printf("\t-i, --info\n"); 726 printf("\t\tDisplay some information about the flash.\n\n"); 727 printf("\t--detail\n"); 728 printf("\t\tDisplays detailed info about a particular partition.\n"); 729 printf("\t\tAccepts a numeric partition or can be used in conjuction\n"); 730 printf("\t\twith the -P flag.\n\n"); 731 printf("\t-h, --help\n"); 732 printf("\t\tThis message.\n\n"); 733 } 734 735 int main(int argc, char *argv[]) 736 { 737 const char *pname = argv[0]; 738 struct flash_details flash = { 0 }; 739 static struct ffs_handle *ffsh = NULL; 740 uint32_t ffs_index; 741 uint32_t address = 0, read_size = 0, detail_id = UINT_MAX; 742 uint32_t write_size = 0, write_size_minus_ecc = 0; 743 bool erase = false, do_clear = false; 744 bool program = false, erase_all = false, info = false, do_read = false; 745 bool enable_4B = false, disable_4B = false; 746 bool show_help = false, show_version = false; 747 bool no_action = false, tune = false; 748 char *write_file = NULL, *read_file = NULL, *part_name = NULL; 749 bool ffs_toc_seen = false, direct = false, print_detail = false; 750 int flash_side = 0, skip_size = 0; 751 int rc = 0; 752 753 while(1) { 754 struct option long_opts[] = { 755 {"address", required_argument, NULL, 'a'}, 756 {"size", required_argument, NULL, 's'}, 757 {"partition", required_argument, NULL, 'P'}, 758 {"bmc", no_argument, NULL, 'b'}, 759 {"direct", no_argument, NULL, 'D'}, 760 {"enable-4B", no_argument, NULL, '4'}, 761 {"disable-4B", no_argument, NULL, '3'}, 762 {"read", required_argument, NULL, 'r'}, 763 {"erase-all", no_argument, NULL, 'E'}, 764 {"erase", no_argument, NULL, 'e'}, 765 {"program", required_argument, NULL, 'p'}, 766 {"force", no_argument, NULL, 'f'}, 767 {"flash-file", required_argument, NULL, 'F'}, 768 {"info", no_argument, NULL, 'i'}, 769 {"detail", optional_argument, NULL, 'm'}, 770 {"tune", no_argument, NULL, 't'}, 771 {"dummy", no_argument, NULL, 'd'}, 772 {"help", no_argument, NULL, 'h'}, 773 {"version", no_argument, NULL, 'v'}, 774 {"debug", no_argument, NULL, 'g'}, 775 {"side", required_argument, NULL, 'S'}, 776 {"skip", required_argument, NULL, 'k'}, 777 {"toc", required_argument, NULL, 'T'}, 778 {"clear", no_argument, NULL, 'c'}, 779 {"ecc", no_argument, NULL, '9'}, 780 {NULL, 0, NULL, 0 } 781 }; 782 int c, oidx = 0; 783 784 c = getopt_long(argc, argv, "+:a:s:P:r:43Eep:fdihvbtgS:T:c9F:", 785 long_opts, &oidx); 786 if (c == -1) 787 break; 788 switch(c) { 789 char *endptr; 790 791 case 'a': 792 address = strtoul(optarg, &endptr, 0); 793 if (*endptr != '\0') { 794 rc = 1; 795 no_action = true; 796 } 797 break; 798 case 's': 799 read_size = write_size = strtoul(optarg, &endptr, 0); 800 if (*endptr != '\0') { 801 rc = 1; 802 no_action = true; 803 } 804 break; 805 case 'P': 806 free(part_name); 807 part_name = strdup(optarg); 808 break; 809 case '4': 810 enable_4B = true; 811 break; 812 case '3': 813 disable_4B = true; 814 break; 815 case 'r': 816 if (!optarg) 817 break; 818 do_read = true; 819 free(read_file); 820 read_file = strdup(optarg); 821 break; 822 case 'E': 823 erase_all = erase = true; 824 break; 825 case 'e': 826 erase = true; 827 break; 828 case 'D': 829 direct = true; 830 break; 831 case 'p': 832 if (!optarg) 833 break; 834 program = true; 835 free(write_file); 836 write_file = strdup(optarg); 837 break; 838 case 'f': 839 must_confirm = false; 840 break; 841 case 'F': 842 flashfilename = optarg; 843 break; 844 case 'd': 845 must_confirm = false; 846 dummy_run = true; 847 break; 848 case 'i': 849 info = true; 850 break; 851 case 'b': 852 bmc_flash = true; 853 break; 854 case 't': 855 tune = true; 856 break; 857 case 'v': 858 show_version = true; 859 break; 860 case 'h': 861 show_help = show_version = true; 862 break; 863 case 'g': 864 libflash_debug = true; 865 break; 866 case 'S': 867 flash_side = atoi(optarg); 868 break; 869 case 'k': 870 skip_size = strtoul(optarg, &endptr, 0); 871 if (*endptr != '\0') { 872 rc = 1; 873 no_action = true; 874 } 875 break; 876 case 'T': 877 if (!optarg) 878 break; 879 ffs_toc_seen = true; 880 flash.toc = strtoul(optarg, &endptr, 0); 881 if (*endptr != '\0') { 882 rc = 1; 883 no_action = true; 884 } 885 break; 886 case 'c': 887 do_clear = true; 888 break; 889 case 'm': 890 print_detail = true; 891 if (optarg) { 892 detail_id = strtoul(optarg, &endptr, 0); 893 if (*endptr != '\0') { 894 rc = 1; 895 no_action = true; 896 } 897 } 898 break; 899 case '9': 900 flash.mark_ecc = true; 901 break; 902 case ':': 903 fprintf(stderr, "Unrecognised option \"%s\" to '%c'\n", optarg, optopt); 904 no_action = true; 905 break; 906 case '?': 907 fprintf(stderr, "Unrecognised option '%c'\n", optopt); 908 no_action = true; 909 break; 910 default: 911 fprintf(stderr , "Encountered unknown error parsing options\n"); 912 no_action = true; 913 } 914 } 915 916 if (optind < argc) { 917 /* 918 * It appears not everything passed to pflash was an option, best to 919 * not continue 920 */ 921 while (optind < argc) 922 fprintf(stderr, "Unrecognised option or argument \"%s\"\n", argv[optind++]); 923 924 no_action = true; 925 } 926 927 /* Check if we need to access the flash at all (which will 928 * also tune them as a side effect 929 */ 930 no_action = no_action || (!erase && !program && !info && !do_read && 931 !enable_4B && !disable_4B && !tune && !do_clear && !print_detail); 932 933 /* Nothing to do, if we didn't already, print usage */ 934 if (no_action && !show_version) 935 show_help = show_version = true; 936 937 if (show_version) 938 print_version(); 939 if (show_help) 940 print_help(pname); 941 942 if (no_action) 943 goto out; 944 945 /* --enable-4B and --disable-4B are mutually exclusive */ 946 if (enable_4B && disable_4B) { 947 fprintf(stderr, "--enable-4B and --disable-4B are mutually" 948 " exclusive !\n"); 949 rc = 1; 950 goto out; 951 } 952 953 /* 4B not supported on BMC flash */ 954 if (enable_4B && bmc_flash) { 955 fprintf(stderr, "--enable-4B not supported on BMC flash !\n"); 956 rc = 1; 957 goto out;; 958 } 959 960 /* partitions not supported on BMC flash */ 961 if (part_name && bmc_flash) { 962 fprintf(stderr, "--partition not supported on BMC flash !\n"); 963 rc = 1; 964 goto out; 965 } 966 967 if (print_detail && ((detail_id == UINT_MAX && !part_name) 968 || (detail_id != UINT_MAX && part_name))) { 969 fprintf(stderr, "--detail requires either a partition id or\n"); 970 fprintf(stderr, "a partition name with -P\n"); 971 } 972 973 /* part-name and erase-all make no sense together */ 974 if (part_name && erase_all) { 975 fprintf(stderr, "--partition and --erase-all are mutually" 976 " exclusive !\n"); 977 rc = 1; 978 goto out; 979 } 980 981 /* Read command should always come with a file */ 982 if (do_read && !read_file) { 983 fprintf(stderr, "Read with no file specified !\n"); 984 rc = 1; 985 goto out; 986 } 987 988 /* Skip only supported on read */ 989 if (skip_size && !do_read) { 990 fprintf(stderr, "--skip requires a --read command !\n"); 991 rc = 1; 992 goto out; 993 } 994 995 /* Program command should always come with a file */ 996 if (program && !write_file) { 997 fprintf(stderr, "Program with no file specified !\n"); 998 rc = 1; 999 goto out; 1000 } 1001 1002 /* If both partition and address specified, error out */ 1003 if (address && part_name) { 1004 fprintf(stderr, "Specify partition or address, not both !\n"); 1005 rc = 1; 1006 goto out; 1007 } 1008 1009 if (do_clear && !part_name) { 1010 fprintf(stderr, "--clear only supported on a partition name\n"); 1011 rc = 1; 1012 goto out; 1013 } 1014 1015 /* Explicitly only support two sides */ 1016 if (flash_side != 0 && flash_side != 1) { 1017 fprintf(stderr, "Unexpected value for --side '%d'\n", flash_side); 1018 rc = 1; 1019 goto out; 1020 } 1021 1022 if (ffs_toc_seen && flash_side) { 1023 fprintf(stderr, "--toc and --side are exclusive"); 1024 rc = 1; 1025 goto out; 1026 } 1027 1028 if (flashfilename && bmc_flash) { 1029 fprintf(stderr, "Filename or bmc flash but not both\n"); 1030 rc = 1; 1031 goto out; 1032 } 1033 1034 if (flashfilename && direct) { 1035 fprintf(stderr, "Filename or direct access but not both\n"); 1036 rc = 1; 1037 goto out; 1038 } 1039 1040 if (tune && !direct) { 1041 fprintf(stderr, "It doesn't make sense to --tune without --direct\n"); 1042 rc = 1; 1043 goto out; 1044 } 1045 1046 if (direct) { 1047 /* If -t is passed, then print a nice message */ 1048 if (tune) 1049 printf("Flash and controller tuned\n"); 1050 1051 if (arch_flash_access(NULL, bmc_flash ? BMC_DIRECT : PNOR_DIRECT) == ACCESS_INVAL) { 1052 fprintf(stderr, "Can't access %s flash directly on this architecture\n", 1053 bmc_flash ? "BMC" : "PNOR"); 1054 rc = 1; 1055 goto out; 1056 } 1057 } else if (!flashfilename) { 1058 if (arch_flash_access(NULL, bmc_flash ? BMC_MTD : PNOR_MTD) == ACCESS_INVAL) { 1059 fprintf(stderr, "Can't access %s flash through MTD on this system\n", 1060 bmc_flash ? "BMC" : "PNOR"); 1061 rc = 1; 1062 goto out; 1063 } 1064 } 1065 1066 if (arch_flash_init(&flash.bl, flashfilename, true)) { 1067 fprintf(stderr, "Couldn't initialise architecture flash structures\n"); 1068 rc = 1; 1069 goto out; 1070 } 1071 1072 rc = blocklevel_get_info(flash.bl, &flash.name, 1073 &flash.total_size, &flash.erase_granule); 1074 if (rc) { 1075 fprintf(stderr, "Error %d getting flash info\n", rc); 1076 rc = 1; 1077 goto close; 1078 } 1079 1080 /* If file specified but not size, get size from file */ 1081 if (write_file && !write_size) { 1082 struct stat stbuf; 1083 1084 if (stat(write_file, &stbuf)) { 1085 perror("Failed to get file size"); 1086 rc = 1; 1087 goto close; 1088 } 1089 write_size = stbuf.st_size; 1090 } 1091 1092 /* Only take ECC into account under some conditions later */ 1093 write_size_minus_ecc = write_size; 1094 1095 /* If read specified and no read_size, use flash size */ 1096 if (do_read && !read_size && !part_name) 1097 read_size = flash.total_size; 1098 1099 /* We have a partition, adjust read/write size if needed */ 1100 if (part_name || print_detail) { 1101 uint32_t pstart, pmaxsz, pactsize; 1102 bool ecc, confirm; 1103 1104 if (ffs_toc_seen) 1105 ffsh = lookup_partition_at_toc(&flash, 1106 part_name, &ffs_index); 1107 else 1108 ffsh = lookup_partition_at_side(&flash, flash_side, 1109 part_name, &ffs_index); 1110 if (!ffsh) 1111 goto close; 1112 1113 if (!part_name) 1114 ffs_index = detail_id; 1115 1116 rc = ffs_part_info(ffsh, ffs_index, NULL, 1117 &pstart, &pmaxsz, &pactsize, &ecc); 1118 if (rc) { 1119 fprintf(stderr,"Failed to get partition info\n"); 1120 goto close; 1121 } 1122 1123 if (!ecc && do_clear) { 1124 fprintf(stderr, "The partition on which to do --clear " 1125 "does not have ECC, are you sure?\n"); 1126 confirm = check_confirm(); 1127 if (!confirm) { 1128 rc = 1; 1129 goto close; 1130 } 1131 /* Still confirm later on */ 1132 must_confirm = true; 1133 } 1134 1135 /* Read size is obtained from partition "actual" size */ 1136 if (!read_size) 1137 read_size = pactsize; 1138 /* If we're decoding ecc and partition is ECC'd, then adjust */ 1139 if (ecc && flash.mark_ecc) 1140 read_size = ecc_buffer_size_minus_ecc(read_size); 1141 1142 /* Write size is max size of partition */ 1143 if (!write_size) 1144 write_size = pmaxsz; 1145 1146 /* But write size can take into account ECC as well */ 1147 if (ecc && flash.mark_ecc) 1148 write_size_minus_ecc = ecc_buffer_size_minus_ecc(write_size); 1149 else 1150 write_size_minus_ecc = write_size; 1151 1152 /* Crop write size to partition size if --force was passed */ 1153 if ((write_size_minus_ecc > pmaxsz) && !must_confirm) { 1154 printf("WARNING: Size (%d bytes) larger than partition" 1155 " (%d bytes), cropping to fit\n", 1156 write_size, pmaxsz); 1157 write_size = pmaxsz; 1158 } else if (write_size_minus_ecc > pmaxsz) { 1159 printf("ERROR: Size (%d bytes) larger than partition" 1160 " (%d bytes). Use --force to force\n", 1161 write_size, pmaxsz); 1162 goto close; 1163 } 1164 1165 /* Set address */ 1166 address = pstart; 1167 } else if (erase) { 1168 if ((address | write_size) & (flash.erase_granule - 1)) { 1169 if (must_confirm) { 1170 printf("ERROR: Erase at 0x%08x for 0x%08x isn't erase block aligned\n", 1171 address, write_size); 1172 printf("Use --force to force\n"); 1173 goto close; 1174 } else { 1175 printf("WARNING: Erase at 0x%08x for 0x%08x isn't erase block aligned\n", 1176 address, write_size); 1177 } 1178 } 1179 } 1180 1181 /* Process commands */ 1182 1183 /* Both enable and disable can't be set (we've checked) */ 1184 if (enable_4B) 1185 rc = enable_4B_addresses(flash.bl); 1186 if (disable_4B) 1187 rc = disable_4B_addresses(flash.bl); 1188 if (rc) 1189 goto close; 1190 1191 if (info) { 1192 /* 1193 * Don't pass through modfied TOC value if the modification was done 1194 * because of --size, but still respect if it came from --toc (we 1195 * assume the user knows what they're doing in that case) 1196 */ 1197 print_flash_info(&flash); 1198 } 1199 1200 if (print_detail) 1201 print_partition_detail(ffsh, ffs_index); 1202 1203 /* Unlock flash (PNOR only) */ 1204 if ((erase || program || do_clear) && !bmc_flash && !flashfilename) { 1205 flash.need_relock = arch_flash_set_wrprotect(flash.bl, false); 1206 if (flash.need_relock == -1) { 1207 fprintf(stderr, "Architecture doesn't support write protection on flash\n"); 1208 flash.need_relock = 0; 1209 goto close; 1210 } 1211 } 1212 rc = 0; 1213 if (do_read) 1214 rc = do_read_file(flash.bl, read_file, address, read_size, skip_size); 1215 if (!rc && erase_all) 1216 rc = erase_chip(&flash); 1217 else if (!rc && erase) 1218 rc = erase_range(&flash, address, write_size, 1219 program, ffsh, ffs_index); 1220 if (!rc && program) 1221 rc = program_file(flash.bl, write_file, address, write_size_minus_ecc, 1222 ffsh, ffs_index); 1223 if (!rc && do_clear) 1224 rc = set_ecc(&flash, address, write_size); 1225 1226 close: 1227 if (flash.need_relock) 1228 arch_flash_set_wrprotect(flash.bl, 1); 1229 arch_flash_close(flash.bl, flashfilename); 1230 if (ffsh) 1231 ffs_close(ffsh); 1232 out: 1233 free(part_name); 1234 free(read_file); 1235 free(write_file); 1236 1237 return rc; 1238 } 1239