1 /* 2 * ifdtool - Manage Intel Firmware Descriptor information 3 * 4 * Copyright 2014 Google, Inc 5 * 6 * SPDX-License-Identifier: GPL-2.0 7 * 8 * From Coreboot project, but it got a serious code clean-up 9 * and a few new features 10 */ 11 12 #include <assert.h> 13 #include <fcntl.h> 14 #include <getopt.h> 15 #include <stdlib.h> 16 #include <stdio.h> 17 #include <string.h> 18 #include <unistd.h> 19 #include <sys/types.h> 20 #include <sys/stat.h> 21 #include "ifdtool.h" 22 23 #undef DEBUG 24 25 #ifdef DEBUG 26 #define debug(fmt, args...) printf(fmt, ##args) 27 #else 28 #define debug(fmt, args...) 29 #endif 30 31 #define FD_SIGNATURE 0x0FF0A55A 32 #define FLREG_BASE(reg) ((reg & 0x00000fff) << 12); 33 #define FLREG_LIMIT(reg) (((reg & 0x0fff0000) >> 4) | 0xfff); 34 35 /** 36 * find_fd() - Find the flash description in the ROM image 37 * 38 * @image: Pointer to image 39 * @size: Size of image in bytes 40 * @return pointer to structure, or NULL if not found 41 */ 42 static struct fdbar_t *find_fd(char *image, int size) 43 { 44 uint32_t *ptr, *end; 45 46 /* Scan for FD signature */ 47 for (ptr = (uint32_t *)image, end = ptr + size / 4; ptr < end; ptr++) { 48 if (*ptr == FD_SIGNATURE) 49 break; 50 } 51 52 if (ptr == end) { 53 printf("No Flash Descriptor found in this image\n"); 54 return NULL; 55 } 56 57 debug("Found Flash Descriptor signature at 0x%08lx\n", 58 (char *)ptr - image); 59 60 return (struct fdbar_t *)ptr; 61 } 62 63 /** 64 * get_region() - Get information about the selected region 65 * 66 * @frba: Flash region list 67 * @region_type: Type of region (0..MAX_REGIONS-1) 68 * @region: Region information is written here 69 * @return 0 if OK, else -ve 70 */ 71 static int get_region(struct frba_t *frba, int region_type, 72 struct region_t *region) 73 { 74 if (region_type >= MAX_REGIONS) { 75 fprintf(stderr, "Invalid region type.\n"); 76 return -1; 77 } 78 79 region->base = FLREG_BASE(frba->flreg[region_type]); 80 region->limit = FLREG_LIMIT(frba->flreg[region_type]); 81 region->size = region->limit - region->base + 1; 82 83 return 0; 84 } 85 86 static const char *region_name(int region_type) 87 { 88 static const char *const regions[] = { 89 "Flash Descriptor", 90 "BIOS", 91 "Intel ME", 92 "GbE", 93 "Platform Data" 94 }; 95 96 assert(region_type < MAX_REGIONS); 97 98 return regions[region_type]; 99 } 100 101 static const char *region_filename(int region_type) 102 { 103 static const char *const region_filenames[] = { 104 "flashregion_0_flashdescriptor.bin", 105 "flashregion_1_bios.bin", 106 "flashregion_2_intel_me.bin", 107 "flashregion_3_gbe.bin", 108 "flashregion_4_platform_data.bin" 109 }; 110 111 assert(region_type < MAX_REGIONS); 112 113 return region_filenames[region_type]; 114 } 115 116 static int dump_region(int num, struct frba_t *frba) 117 { 118 struct region_t region; 119 int ret; 120 121 ret = get_region(frba, num, ®ion); 122 if (ret) 123 return ret; 124 125 printf(" Flash Region %d (%s): %08x - %08x %s\n", 126 num, region_name(num), region.base, region.limit, 127 region.size < 1 ? "(unused)" : ""); 128 129 return ret; 130 } 131 132 static void dump_frba(struct frba_t *frba) 133 { 134 int i; 135 136 printf("Found Region Section\n"); 137 for (i = 0; i < MAX_REGIONS; i++) { 138 printf("FLREG%d: 0x%08x\n", i, frba->flreg[i]); 139 dump_region(i, frba); 140 } 141 } 142 143 static void decode_spi_frequency(unsigned int freq) 144 { 145 switch (freq) { 146 case SPI_FREQUENCY_20MHZ: 147 printf("20MHz"); 148 break; 149 case SPI_FREQUENCY_33MHZ: 150 printf("33MHz"); 151 break; 152 case SPI_FREQUENCY_50MHZ: 153 printf("50MHz"); 154 break; 155 default: 156 printf("unknown<%x>MHz", freq); 157 } 158 } 159 160 static void decode_component_density(unsigned int density) 161 { 162 switch (density) { 163 case COMPONENT_DENSITY_512KB: 164 printf("512KiB"); 165 break; 166 case COMPONENT_DENSITY_1MB: 167 printf("1MiB"); 168 break; 169 case COMPONENT_DENSITY_2MB: 170 printf("2MiB"); 171 break; 172 case COMPONENT_DENSITY_4MB: 173 printf("4MiB"); 174 break; 175 case COMPONENT_DENSITY_8MB: 176 printf("8MiB"); 177 break; 178 case COMPONENT_DENSITY_16MB: 179 printf("16MiB"); 180 break; 181 default: 182 printf("unknown<%x>MiB", density); 183 } 184 } 185 186 static void dump_fcba(struct fcba_t *fcba) 187 { 188 printf("\nFound Component Section\n"); 189 printf("FLCOMP 0x%08x\n", fcba->flcomp); 190 printf(" Dual Output Fast Read Support: %ssupported\n", 191 (fcba->flcomp & (1 << 30)) ? "" : "not "); 192 printf(" Read ID/Read Status Clock Frequency: "); 193 decode_spi_frequency((fcba->flcomp >> 27) & 7); 194 printf("\n Write/Erase Clock Frequency: "); 195 decode_spi_frequency((fcba->flcomp >> 24) & 7); 196 printf("\n Fast Read Clock Frequency: "); 197 decode_spi_frequency((fcba->flcomp >> 21) & 7); 198 printf("\n Fast Read Support: %ssupported", 199 (fcba->flcomp & (1 << 20)) ? "" : "not "); 200 printf("\n Read Clock Frequency: "); 201 decode_spi_frequency((fcba->flcomp >> 17) & 7); 202 printf("\n Component 2 Density: "); 203 decode_component_density((fcba->flcomp >> 3) & 7); 204 printf("\n Component 1 Density: "); 205 decode_component_density(fcba->flcomp & 7); 206 printf("\n"); 207 printf("FLILL 0x%08x\n", fcba->flill); 208 printf(" Invalid Instruction 3: 0x%02x\n", 209 (fcba->flill >> 24) & 0xff); 210 printf(" Invalid Instruction 2: 0x%02x\n", 211 (fcba->flill >> 16) & 0xff); 212 printf(" Invalid Instruction 1: 0x%02x\n", 213 (fcba->flill >> 8) & 0xff); 214 printf(" Invalid Instruction 0: 0x%02x\n", 215 fcba->flill & 0xff); 216 printf("FLPB 0x%08x\n", fcba->flpb); 217 printf(" Flash Partition Boundary Address: 0x%06x\n\n", 218 (fcba->flpb & 0xfff) << 12); 219 } 220 221 static void dump_fpsba(struct fpsba_t *fpsba) 222 { 223 int i; 224 225 printf("Found PCH Strap Section\n"); 226 for (i = 0; i < MAX_STRAPS; i++) 227 printf("PCHSTRP%-2d: 0x%08x\n", i, fpsba->pchstrp[i]); 228 } 229 230 static const char *get_enabled(int flag) 231 { 232 return flag ? "enabled" : "disabled"; 233 } 234 235 static void decode_flmstr(uint32_t flmstr) 236 { 237 printf(" Platform Data Region Write Access: %s\n", 238 get_enabled(flmstr & (1 << 28))); 239 printf(" GbE Region Write Access: %s\n", 240 get_enabled(flmstr & (1 << 27))); 241 printf(" Intel ME Region Write Access: %s\n", 242 get_enabled(flmstr & (1 << 26))); 243 printf(" Host CPU/BIOS Region Write Access: %s\n", 244 get_enabled(flmstr & (1 << 25))); 245 printf(" Flash Descriptor Write Access: %s\n", 246 get_enabled(flmstr & (1 << 24))); 247 248 printf(" Platform Data Region Read Access: %s\n", 249 get_enabled(flmstr & (1 << 20))); 250 printf(" GbE Region Read Access: %s\n", 251 get_enabled(flmstr & (1 << 19))); 252 printf(" Intel ME Region Read Access: %s\n", 253 get_enabled(flmstr & (1 << 18))); 254 printf(" Host CPU/BIOS Region Read Access: %s\n", 255 get_enabled(flmstr & (1 << 17))); 256 printf(" Flash Descriptor Read Access: %s\n", 257 get_enabled(flmstr & (1 << 16))); 258 259 printf(" Requester ID: 0x%04x\n\n", 260 flmstr & 0xffff); 261 } 262 263 static void dump_fmba(struct fmba_t *fmba) 264 { 265 printf("Found Master Section\n"); 266 printf("FLMSTR1: 0x%08x (Host CPU/BIOS)\n", fmba->flmstr1); 267 decode_flmstr(fmba->flmstr1); 268 printf("FLMSTR2: 0x%08x (Intel ME)\n", fmba->flmstr2); 269 decode_flmstr(fmba->flmstr2); 270 printf("FLMSTR3: 0x%08x (GbE)\n", fmba->flmstr3); 271 decode_flmstr(fmba->flmstr3); 272 } 273 274 static void dump_fmsba(struct fmsba_t *fmsba) 275 { 276 int i; 277 278 printf("Found Processor Strap Section\n"); 279 for (i = 0; i < 4; i++) 280 printf("????: 0x%08x\n", fmsba->data[0]); 281 } 282 283 static void dump_jid(uint32_t jid) 284 { 285 printf(" SPI Component Device ID 1: 0x%02x\n", 286 (jid >> 16) & 0xff); 287 printf(" SPI Component Device ID 0: 0x%02x\n", 288 (jid >> 8) & 0xff); 289 printf(" SPI Component Vendor ID: 0x%02x\n", 290 jid & 0xff); 291 } 292 293 static void dump_vscc(uint32_t vscc) 294 { 295 printf(" Lower Erase Opcode: 0x%02x\n", 296 vscc >> 24); 297 printf(" Lower Write Enable on Write Status: 0x%02x\n", 298 vscc & (1 << 20) ? 0x06 : 0x50); 299 printf(" Lower Write Status Required: %s\n", 300 vscc & (1 << 19) ? "Yes" : "No"); 301 printf(" Lower Write Granularity: %d bytes\n", 302 vscc & (1 << 18) ? 64 : 1); 303 printf(" Lower Block / Sector Erase Size: "); 304 switch ((vscc >> 16) & 0x3) { 305 case 0: 306 printf("256 Byte\n"); 307 break; 308 case 1: 309 printf("4KB\n"); 310 break; 311 case 2: 312 printf("8KB\n"); 313 break; 314 case 3: 315 printf("64KB\n"); 316 break; 317 } 318 319 printf(" Upper Erase Opcode: 0x%02x\n", 320 (vscc >> 8) & 0xff); 321 printf(" Upper Write Enable on Write Status: 0x%02x\n", 322 vscc & (1 << 4) ? 0x06 : 0x50); 323 printf(" Upper Write Status Required: %s\n", 324 vscc & (1 << 3) ? "Yes" : "No"); 325 printf(" Upper Write Granularity: %d bytes\n", 326 vscc & (1 << 2) ? 64 : 1); 327 printf(" Upper Block / Sector Erase Size: "); 328 switch (vscc & 0x3) { 329 case 0: 330 printf("256 Byte\n"); 331 break; 332 case 1: 333 printf("4KB\n"); 334 break; 335 case 2: 336 printf("8KB\n"); 337 break; 338 case 3: 339 printf("64KB\n"); 340 break; 341 } 342 } 343 344 static void dump_vtba(struct vtba_t *vtba, int vtl) 345 { 346 int i; 347 int num = (vtl >> 1) < 8 ? (vtl >> 1) : 8; 348 349 printf("ME VSCC table:\n"); 350 for (i = 0; i < num; i++) { 351 printf(" JID%d: 0x%08x\n", i, vtba->entry[i].jid); 352 dump_jid(vtba->entry[i].jid); 353 printf(" VSCC%d: 0x%08x\n", i, vtba->entry[i].vscc); 354 dump_vscc(vtba->entry[i].vscc); 355 } 356 printf("\n"); 357 } 358 359 static void dump_oem(uint8_t *oem) 360 { 361 int i, j; 362 printf("OEM Section:\n"); 363 for (i = 0; i < 4; i++) { 364 printf("%02x:", i << 4); 365 for (j = 0; j < 16; j++) 366 printf(" %02x", oem[(i<<4)+j]); 367 printf("\n"); 368 } 369 printf("\n"); 370 } 371 372 /** 373 * dump_fd() - Display a dump of the full flash description 374 * 375 * @image: Pointer to image 376 * @size: Size of image in bytes 377 * @return 0 if OK, -1 on error 378 */ 379 static int dump_fd(char *image, int size) 380 { 381 struct fdbar_t *fdb = find_fd(image, size); 382 383 if (!fdb) 384 return -1; 385 386 printf("FLMAP0: 0x%08x\n", fdb->flmap0); 387 printf(" NR: %d\n", (fdb->flmap0 >> 24) & 7); 388 printf(" FRBA: 0x%x\n", ((fdb->flmap0 >> 16) & 0xff) << 4); 389 printf(" NC: %d\n", ((fdb->flmap0 >> 8) & 3) + 1); 390 printf(" FCBA: 0x%x\n", ((fdb->flmap0) & 0xff) << 4); 391 392 printf("FLMAP1: 0x%08x\n", fdb->flmap1); 393 printf(" ISL: 0x%02x\n", (fdb->flmap1 >> 24) & 0xff); 394 printf(" FPSBA: 0x%x\n", ((fdb->flmap1 >> 16) & 0xff) << 4); 395 printf(" NM: %d\n", (fdb->flmap1 >> 8) & 3); 396 printf(" FMBA: 0x%x\n", ((fdb->flmap1) & 0xff) << 4); 397 398 printf("FLMAP2: 0x%08x\n", fdb->flmap2); 399 printf(" PSL: 0x%04x\n", (fdb->flmap2 >> 8) & 0xffff); 400 printf(" FMSBA: 0x%x\n", ((fdb->flmap2) & 0xff) << 4); 401 402 printf("FLUMAP1: 0x%08x\n", fdb->flumap1); 403 printf(" Intel ME VSCC Table Length (VTL): %d\n", 404 (fdb->flumap1 >> 8) & 0xff); 405 printf(" Intel ME VSCC Table Base Address (VTBA): 0x%06x\n\n", 406 (fdb->flumap1 & 0xff) << 4); 407 dump_vtba((struct vtba_t *) 408 (image + ((fdb->flumap1 & 0xff) << 4)), 409 (fdb->flumap1 >> 8) & 0xff); 410 dump_oem((uint8_t *)image + 0xf00); 411 dump_frba((struct frba_t *)(image + (((fdb->flmap0 >> 16) & 0xff) 412 << 4))); 413 dump_fcba((struct fcba_t *)(image + (((fdb->flmap0) & 0xff) << 4))); 414 dump_fpsba((struct fpsba_t *) 415 (image + (((fdb->flmap1 >> 16) & 0xff) << 4))); 416 dump_fmba((struct fmba_t *)(image + (((fdb->flmap1) & 0xff) << 4))); 417 dump_fmsba((struct fmsba_t *)(image + (((fdb->flmap2) & 0xff) << 4))); 418 419 return 0; 420 } 421 422 /** 423 * write_regions() - Write each region from an image to its own file 424 * 425 * The filename to use in each case is fixed - see region_filename() 426 * 427 * @image: Pointer to image 428 * @size: Size of image in bytes 429 * @return 0 if OK, -ve on error 430 */ 431 static int write_regions(char *image, int size) 432 { 433 struct fdbar_t *fdb; 434 struct frba_t *frba; 435 int ret = 0; 436 int i; 437 438 fdb = find_fd(image, size); 439 if (!fdb) 440 return -1; 441 442 frba = (struct frba_t *)(image + (((fdb->flmap0 >> 16) & 0xff) << 4)); 443 444 for (i = 0; i < MAX_REGIONS; i++) { 445 struct region_t region; 446 int region_fd; 447 448 ret = get_region(frba, i, ®ion); 449 if (ret) 450 return ret; 451 dump_region(i, frba); 452 if (region.size == 0) 453 continue; 454 region_fd = open(region_filename(i), 455 O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | 456 S_IWUSR | S_IRGRP | S_IROTH); 457 if (write(region_fd, image + region.base, region.size) != 458 region.size) { 459 perror("Error while writing"); 460 ret = -1; 461 } 462 close(region_fd); 463 } 464 465 return ret; 466 } 467 468 /** 469 * write_image() - Write the image to a file 470 * 471 * @filename: Filename to use for the image 472 * @image: Pointer to image 473 * @size: Size of image in bytes 474 * @return 0 if OK, -ve on error 475 */ 476 static int write_image(char *filename, char *image, int size) 477 { 478 int new_fd; 479 480 debug("Writing new image to %s\n", filename); 481 482 new_fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | 483 S_IWUSR | S_IRGRP | S_IROTH); 484 if (write(new_fd, image, size) != size) { 485 perror("Error while writing"); 486 return -1; 487 } 488 close(new_fd); 489 490 return 0; 491 } 492 493 /** 494 * set_spi_frequency() - Set the SPI frequency to use when booting 495 * 496 * Several frequencies are supported, some of which work with fast devices. 497 * For SPI emulators, the slowest (SPI_FREQUENCY_20MHZ) is often used. The 498 * Intel boot system uses this information somehow on boot. 499 * 500 * The image is updated with the supplied value 501 * 502 * @image: Pointer to image 503 * @size: Size of image in bytes 504 * @freq: SPI frequency to use 505 */ 506 static void set_spi_frequency(char *image, int size, enum spi_frequency freq) 507 { 508 struct fdbar_t *fdb = find_fd(image, size); 509 struct fcba_t *fcba; 510 511 fcba = (struct fcba_t *)(image + (((fdb->flmap0) & 0xff) << 4)); 512 513 /* clear bits 21-29 */ 514 fcba->flcomp &= ~0x3fe00000; 515 /* Read ID and Read Status Clock Frequency */ 516 fcba->flcomp |= freq << 27; 517 /* Write and Erase Clock Frequency */ 518 fcba->flcomp |= freq << 24; 519 /* Fast Read Clock Frequency */ 520 fcba->flcomp |= freq << 21; 521 } 522 523 /** 524 * set_em100_mode() - Set a SPI frequency that will work with Dediprog EM100 525 * 526 * @image: Pointer to image 527 * @size: Size of image in bytes 528 */ 529 static void set_em100_mode(char *image, int size) 530 { 531 struct fdbar_t *fdb = find_fd(image, size); 532 struct fcba_t *fcba; 533 534 fcba = (struct fcba_t *)(image + (((fdb->flmap0) & 0xff) << 4)); 535 fcba->flcomp &= ~(1 << 30); 536 set_spi_frequency(image, size, SPI_FREQUENCY_20MHZ); 537 } 538 539 /** 540 * lock_descriptor() - Lock the NE descriptor so it cannot be updated 541 * 542 * @image: Pointer to image 543 * @size: Size of image in bytes 544 */ 545 static void lock_descriptor(char *image, int size) 546 { 547 struct fdbar_t *fdb = find_fd(image, size); 548 struct fmba_t *fmba; 549 550 /* 551 * TODO: Dynamically take Platform Data Region and GbE Region into 552 * account. 553 */ 554 fmba = (struct fmba_t *)(image + (((fdb->flmap1) & 0xff) << 4)); 555 fmba->flmstr1 = 0x0a0b0000; 556 fmba->flmstr2 = 0x0c0d0000; 557 fmba->flmstr3 = 0x08080118; 558 } 559 560 /** 561 * unlock_descriptor() - Lock the NE descriptor so it can be updated 562 * 563 * @image: Pointer to image 564 * @size: Size of image in bytes 565 */ 566 static void unlock_descriptor(char *image, int size) 567 { 568 struct fdbar_t *fdb = find_fd(image, size); 569 struct fmba_t *fmba; 570 571 fmba = (struct fmba_t *)(image + (((fdb->flmap1) & 0xff) << 4)); 572 fmba->flmstr1 = 0xffff0000; 573 fmba->flmstr2 = 0xffff0000; 574 fmba->flmstr3 = 0x08080118; 575 } 576 577 /** 578 * open_for_read() - Open a file for reading 579 * 580 * @fname: Filename to open 581 * @sizep: Returns file size in bytes 582 * @return 0 if OK, -1 on error 583 */ 584 int open_for_read(const char *fname, int *sizep) 585 { 586 int fd = open(fname, O_RDONLY); 587 struct stat buf; 588 589 if (fd == -1) { 590 perror("Could not open file"); 591 return -1; 592 } 593 if (fstat(fd, &buf) == -1) { 594 perror("Could not stat file"); 595 return -1; 596 } 597 *sizep = buf.st_size; 598 debug("File %s is %d bytes\n", fname, *sizep); 599 600 return fd; 601 } 602 603 /** 604 * inject_region() - Add a file to an image region 605 * 606 * This puts a file into a particular region of the flash. Several pre-defined 607 * regions are used. 608 * 609 * @image: Pointer to image 610 * @size: Size of image in bytes 611 * @region_type: Region where the file should be added 612 * @region_fname: Filename to add to the image 613 * @return 0 if OK, -ve on error 614 */ 615 int inject_region(char *image, int size, int region_type, char *region_fname) 616 { 617 struct fdbar_t *fdb = find_fd(image, size); 618 struct region_t region; 619 struct frba_t *frba; 620 int region_size; 621 int offset = 0; 622 int region_fd; 623 int ret; 624 625 if (!fdb) 626 exit(EXIT_FAILURE); 627 frba = (struct frba_t *)(image + (((fdb->flmap0 >> 16) & 0xff) << 4)); 628 629 ret = get_region(frba, region_type, ®ion); 630 if (ret) 631 return -1; 632 if (region.size <= 0xfff) { 633 fprintf(stderr, "Region %s is disabled in target. Not injecting.\n", 634 region_name(region_type)); 635 return -1; 636 } 637 638 region_fd = open_for_read(region_fname, ®ion_size); 639 if (region_fd < 0) 640 return region_fd; 641 642 if ((region_size > region.size) || 643 ((region_type != 1) && (region_size > region.size))) { 644 fprintf(stderr, "Region %s is %d(0x%x) bytes. File is %d(0x%x) bytes. Not injecting.\n", 645 region_name(region_type), region.size, 646 region.size, region_size, region_size); 647 return -1; 648 } 649 650 if ((region_type == 1) && (region_size < region.size)) { 651 fprintf(stderr, "Region %s is %d(0x%x) bytes. File is %d(0x%x) bytes. Padding before injecting.\n", 652 region_name(region_type), region.size, 653 region.size, region_size, region_size); 654 offset = region.size - region_size; 655 memset(image + region.base, 0xff, offset); 656 } 657 658 if (size < region.base + offset + region_size) { 659 fprintf(stderr, "Output file is too small. (%d < %d)\n", 660 size, region.base + offset + region_size); 661 return -1; 662 } 663 664 if (read(region_fd, image + region.base + offset, region_size) 665 != region_size) { 666 perror("Could not read file"); 667 return -1; 668 } 669 670 close(region_fd); 671 672 debug("Adding %s as the %s section\n", region_fname, 673 region_name(region_type)); 674 675 return 0; 676 } 677 678 /** 679 * write_data() - Write some raw data into a region 680 * 681 * This puts a file into a particular place in the flash, ignoring the 682 * regions. Be careful not to overwrite something important. 683 * 684 * @image: Pointer to image 685 * @size: Size of image in bytes 686 * @addr: x86 ROM address to put file. The ROM ends at 687 * 0xffffffff so use an address relative to that. For an 688 * 8MB ROM the start address is 0xfff80000. 689 * @write_fname: Filename to add to the image 690 * @return 0 if OK, -ve on error 691 */ 692 static int write_data(char *image, int size, unsigned int addr, 693 const char *write_fname) 694 { 695 int write_fd, write_size; 696 int offset; 697 698 write_fd = open_for_read(write_fname, &write_size); 699 if (write_fd < 0) 700 return write_fd; 701 702 offset = addr + size; 703 debug("Writing %s to offset %#x\n", write_fname, offset); 704 705 if (offset < 0 || offset + write_size > size) { 706 fprintf(stderr, "Output file is too small. (%d < %d)\n", 707 size, offset + write_size); 708 return -1; 709 } 710 711 if (read(write_fd, image + offset, write_size) != write_size) { 712 perror("Could not read file"); 713 return -1; 714 } 715 716 close(write_fd); 717 718 return 0; 719 } 720 721 static void print_version(void) 722 { 723 printf("ifdtool v%s -- ", IFDTOOL_VERSION); 724 printf("Copyright (C) 2014 Google Inc.\n\n"); 725 printf("SPDX-License-Identifier: GPL-2.0+\n"); 726 } 727 728 static void print_usage(const char *name) 729 { 730 printf("usage: %s [-vhdix?] <filename> [<outfile>]\n", name); 731 printf("\n" 732 " -d | --dump: dump intel firmware descriptor\n" 733 " -x | --extract: extract intel fd modules\n" 734 " -i | --inject <region>:<module> inject file <module> into region <region>\n" 735 " -w | --write <addr>:<file> write file to appear at memory address <addr>\n" 736 " multiple files can be written simultaneously\n" 737 " -s | --spifreq <20|33|50> set the SPI frequency\n" 738 " -e | --em100 set SPI frequency to 20MHz and disable\n" 739 " Dual Output Fast Read Support\n" 740 " -l | --lock Lock firmware descriptor and ME region\n" 741 " -u | --unlock Unlock firmware descriptor and ME region\n" 742 " -r | --romsize Specify ROM size\n" 743 " -D | --write-descriptor <file> Write descriptor at base\n" 744 " -c | --create Create a new empty image\n" 745 " -v | --version: print the version\n" 746 " -h | --help: print this help\n\n" 747 "<region> is one of Descriptor, BIOS, ME, GbE, Platform\n" 748 "\n"); 749 } 750 751 /** 752 * get_two_words() - Convert a string into two words separated by : 753 * 754 * The supplied string is split at ':', two substrings are allocated and 755 * returned. 756 * 757 * @str: String to split 758 * @firstp: Returns first string 759 * @secondp: Returns second string 760 * @return 0 if OK, -ve if @str does not have a : 761 */ 762 static int get_two_words(const char *str, char **firstp, char **secondp) 763 { 764 const char *p; 765 766 p = strchr(str, ':'); 767 if (!p) 768 return -1; 769 *firstp = strdup(str); 770 (*firstp)[p - str] = '\0'; 771 *secondp = strdup(p + 1); 772 773 return 0; 774 } 775 776 int main(int argc, char *argv[]) 777 { 778 int opt, option_index = 0; 779 int mode_dump = 0, mode_extract = 0, mode_inject = 0; 780 int mode_spifreq = 0, mode_em100 = 0, mode_locked = 0; 781 int mode_unlocked = 0, mode_write = 0, mode_write_descriptor = 0; 782 int create = 0; 783 char *region_type_string = NULL, *inject_fname = NULL; 784 char *desc_fname = NULL, *addr_str = NULL; 785 int region_type = -1, inputfreq = 0; 786 enum spi_frequency spifreq = SPI_FREQUENCY_20MHZ; 787 unsigned int addr[WRITE_MAX]; 788 char *wr_fname[WRITE_MAX]; 789 unsigned char wr_idx, wr_num = 0; 790 int rom_size = -1; 791 bool write_it; 792 char *filename; 793 char *outfile = NULL; 794 struct stat buf; 795 int size = 0; 796 int bios_fd; 797 char *image; 798 int ret; 799 static struct option long_options[] = { 800 {"create", 0, NULL, 'c'}, 801 {"dump", 0, NULL, 'd'}, 802 {"descriptor", 1, NULL, 'D'}, 803 {"em100", 0, NULL, 'e'}, 804 {"extract", 0, NULL, 'x'}, 805 {"inject", 1, NULL, 'i'}, 806 {"lock", 0, NULL, 'l'}, 807 {"romsize", 1, NULL, 'r'}, 808 {"spifreq", 1, NULL, 's'}, 809 {"unlock", 0, NULL, 'u'}, 810 {"write", 1, NULL, 'w'}, 811 {"version", 0, NULL, 'v'}, 812 {"help", 0, NULL, 'h'}, 813 {0, 0, 0, 0} 814 }; 815 816 while ((opt = getopt_long(argc, argv, "cdD:ehi:lr:s:uvw:x?", 817 long_options, &option_index)) != EOF) { 818 switch (opt) { 819 case 'c': 820 create = 1; 821 break; 822 case 'd': 823 mode_dump = 1; 824 break; 825 case 'D': 826 mode_write_descriptor = 1; 827 desc_fname = optarg; 828 break; 829 case 'e': 830 mode_em100 = 1; 831 break; 832 case 'i': 833 if (get_two_words(optarg, ®ion_type_string, 834 &inject_fname)) { 835 print_usage(argv[0]); 836 exit(EXIT_FAILURE); 837 } 838 if (!strcasecmp("Descriptor", region_type_string)) 839 region_type = 0; 840 else if (!strcasecmp("BIOS", region_type_string)) 841 region_type = 1; 842 else if (!strcasecmp("ME", region_type_string)) 843 region_type = 2; 844 else if (!strcasecmp("GbE", region_type_string)) 845 region_type = 3; 846 else if (!strcasecmp("Platform", region_type_string)) 847 region_type = 4; 848 if (region_type == -1) { 849 fprintf(stderr, "No such region type: '%s'\n\n", 850 region_type_string); 851 print_usage(argv[0]); 852 exit(EXIT_FAILURE); 853 } 854 mode_inject = 1; 855 break; 856 case 'l': 857 mode_locked = 1; 858 break; 859 case 'r': 860 rom_size = strtol(optarg, NULL, 0); 861 debug("ROM size %d\n", rom_size); 862 break; 863 case 's': 864 /* Parse the requested SPI frequency */ 865 inputfreq = strtol(optarg, NULL, 0); 866 switch (inputfreq) { 867 case 20: 868 spifreq = SPI_FREQUENCY_20MHZ; 869 break; 870 case 33: 871 spifreq = SPI_FREQUENCY_33MHZ; 872 break; 873 case 50: 874 spifreq = SPI_FREQUENCY_50MHZ; 875 break; 876 default: 877 fprintf(stderr, "Invalid SPI Frequency: %d\n", 878 inputfreq); 879 print_usage(argv[0]); 880 exit(EXIT_FAILURE); 881 } 882 mode_spifreq = 1; 883 break; 884 case 'u': 885 mode_unlocked = 1; 886 break; 887 case 'v': 888 print_version(); 889 exit(EXIT_SUCCESS); 890 break; 891 case 'w': 892 mode_write = 1; 893 if (wr_num < WRITE_MAX) { 894 if (get_two_words(optarg, &addr_str, 895 &wr_fname[wr_num])) { 896 print_usage(argv[0]); 897 exit(EXIT_FAILURE); 898 } 899 addr[wr_num] = strtol(optarg, NULL, 0); 900 wr_num++; 901 } else { 902 fprintf(stderr, 903 "The number of files to write simultaneously exceeds the limitation (%d)\n", 904 WRITE_MAX); 905 } 906 break; 907 case 'x': 908 mode_extract = 1; 909 break; 910 case 'h': 911 case '?': 912 default: 913 print_usage(argv[0]); 914 exit(EXIT_SUCCESS); 915 break; 916 } 917 } 918 919 if (mode_locked == 1 && mode_unlocked == 1) { 920 fprintf(stderr, "Locking/Unlocking FD and ME are mutually exclusive\n"); 921 exit(EXIT_FAILURE); 922 } 923 924 if (mode_inject == 1 && mode_write == 1) { 925 fprintf(stderr, "Inject/Write are mutually exclusive\n"); 926 exit(EXIT_FAILURE); 927 } 928 929 if ((mode_dump + mode_extract + mode_inject + 930 (mode_spifreq | mode_em100 | mode_unlocked | 931 mode_locked)) > 1) { 932 fprintf(stderr, "You may not specify more than one mode.\n\n"); 933 print_usage(argv[0]); 934 exit(EXIT_FAILURE); 935 } 936 937 if ((mode_dump + mode_extract + mode_inject + mode_spifreq + 938 mode_em100 + mode_locked + mode_unlocked + mode_write + 939 mode_write_descriptor) == 0 && !create) { 940 fprintf(stderr, "You need to specify a mode.\n\n"); 941 print_usage(argv[0]); 942 exit(EXIT_FAILURE); 943 } 944 945 if (create && rom_size == -1) { 946 fprintf(stderr, "You need to specify a rom size when creating.\n\n"); 947 exit(EXIT_FAILURE); 948 } 949 950 if (optind + 1 != argc) { 951 fprintf(stderr, "You need to specify a file.\n\n"); 952 print_usage(argv[0]); 953 exit(EXIT_FAILURE); 954 } 955 956 filename = argv[optind]; 957 if (optind + 2 != argc) 958 outfile = argv[optind + 1]; 959 960 if (create) 961 bios_fd = open(filename, O_WRONLY | O_CREAT, 0666); 962 else 963 bios_fd = open(filename, outfile ? O_RDONLY : O_RDWR); 964 965 if (bios_fd == -1) { 966 perror("Could not open file"); 967 exit(EXIT_FAILURE); 968 } 969 970 if (!create) { 971 if (fstat(bios_fd, &buf) == -1) { 972 perror("Could not stat file"); 973 exit(EXIT_FAILURE); 974 } 975 size = buf.st_size; 976 } 977 978 debug("File %s is %d bytes\n", filename, size); 979 980 if (rom_size == -1) 981 rom_size = size; 982 983 image = malloc(rom_size); 984 if (!image) { 985 printf("Out of memory.\n"); 986 exit(EXIT_FAILURE); 987 } 988 989 memset(image, '\xff', rom_size); 990 if (!create && read(bios_fd, image, size) != size) { 991 perror("Could not read file"); 992 exit(EXIT_FAILURE); 993 } 994 if (size != rom_size) { 995 debug("ROM size changed to %d bytes\n", rom_size); 996 size = rom_size; 997 } 998 999 write_it = true; 1000 ret = 0; 1001 if (mode_dump) { 1002 ret = dump_fd(image, size); 1003 write_it = false; 1004 } 1005 1006 if (mode_extract) { 1007 ret = write_regions(image, size); 1008 write_it = false; 1009 } 1010 1011 if (mode_write_descriptor) 1012 ret = write_data(image, size, -size, desc_fname); 1013 1014 if (mode_inject) 1015 ret = inject_region(image, size, region_type, inject_fname); 1016 1017 if (mode_write) { 1018 for (wr_idx = 0; wr_idx < wr_num; wr_idx++) { 1019 ret = write_data(image, size, 1020 addr[wr_idx], wr_fname[wr_idx]); 1021 if (ret) 1022 break; 1023 } 1024 } 1025 1026 if (mode_spifreq) 1027 set_spi_frequency(image, size, spifreq); 1028 1029 if (mode_em100) 1030 set_em100_mode(image, size); 1031 1032 if (mode_locked) 1033 lock_descriptor(image, size); 1034 1035 if (mode_unlocked) 1036 unlock_descriptor(image, size); 1037 1038 if (write_it) { 1039 if (outfile) { 1040 ret = write_image(outfile, image, size); 1041 } else { 1042 if (lseek(bios_fd, 0, SEEK_SET)) { 1043 perror("Error while seeking"); 1044 ret = -1; 1045 } 1046 if (write(bios_fd, image, size) != size) { 1047 perror("Error while writing"); 1048 ret = -1; 1049 } 1050 } 1051 } 1052 1053 free(image); 1054 close(bios_fd); 1055 1056 return ret ? 1 : 0; 1057 } 1058