ifdtool.c
1 /* ifdtool - dump Intel Firmware Descriptor information */ 2 /* SPDX-License-Identifier: GPL-2.0-only */ 3 4 #include <unistd.h> 5 #include <stdlib.h> 6 #include <stdio.h> 7 #include <string.h> 8 #include <getopt.h> 9 #include <fcntl.h> 10 #include <sys/types.h> 11 #include <sys/stat.h> 12 #include <commonlib/helpers.h> 13 #include <fmap.h> 14 #include "ifdtool.h" 15 16 #ifndef O_BINARY 17 #define O_BINARY 0 18 #endif 19 20 /** 21 * PTR_IN_RANGE - examine whether a pointer falls in [base, base + limit) 22 * @param ptr: the non-void* pointer to a single arbitrary-sized object. 23 * @param base: base address represented with char* type. 24 * @param limit: upper limit of the legal address. 25 * 26 */ 27 #define PTR_IN_RANGE(ptr, base, limit) \ 28 ((const char *)(ptr) >= (base) && \ 29 (const char *)&(ptr)[1] <= (base) + (limit)) 30 31 /** 32 * PLATFORM_HAS_GBE_REGION - some platforms do not support the PCH GbE LAN region 33 */ 34 #define PLATFORM_HAS_GBE_REGION (platform != PLATFORM_DNV) 35 36 /* 37 * PLATFORM_HAS_EC_REGION - some platforms do not support the EC region 38 */ 39 #define PLATFORM_HAS_EC_REGION (ifd_version >= IFD_VERSION_2 && platform != PLATFORM_DNV) 40 41 /* 42 * PLATFORM_HAS_10GBE_X_REGION - some platforms have 1 or more 10GbE LAN regions 43 */ 44 #define PLATFORM_HAS_10GBE_0_REGION (platform == PLATFORM_DNV) 45 #define PLATFORM_HAS_10GBE_1_REGION (platform == PLATFORM_DNV) 46 47 union gprd { 48 struct bit_field { 49 /* 50 * Start Address: bit 0-14 of the GPRD represents the 51 * protected region start address, where bit 0-11 of 52 * the start address are assumed to be zero. 53 */ 54 uint32_t start : 15; 55 56 /* Specifies read protection is enabled */ 57 uint32_t read_protect_en : 1; 58 59 /* 60 * End Address: bit 16-30 of the GPRD represents the 61 * protected region end address, where bit 0-11 of 62 * the end address are assumed to be 0xfff. 63 */ 64 uint32_t end : 15; 65 66 /* Specifies write protection is enabled */ 67 uint32_t write_protect_en : 1; 68 } __packed data; 69 70 uint32_t value; 71 }; 72 73 static int max_regions_from_fdbar(const struct fdbar *fdb); 74 75 static int ifd_version; 76 static int chipset; 77 static unsigned int max_regions = 0; 78 static int selected_chip = 0; 79 static int platform = -1; 80 81 static const struct region_name region_names[MAX_REGIONS] = { 82 { "Flash Descriptor", "fd", "flashregion_0_flashdescriptor.bin", "SI_DESC" }, 83 { "BIOS", "bios", "flashregion_1_bios.bin", "SI_BIOS" }, 84 { "Intel ME", "me", "flashregion_2_intel_me.bin", "SI_ME" }, 85 { "GbE", "gbe", "flashregion_3_gbe.bin", "SI_GBE" }, 86 { "Platform Data", "pd", "flashregion_4_platform_data.bin", "SI_PDR" }, 87 { "Device Exp1", "devexp", "flashregion_5_device_exp.bin", "SI_DEVICEEXT" }, 88 { "Secondary BIOS", "bios2", "flashregion_6_bios2.bin", "SI_BIOS2" }, 89 { "Reserved", "res7", "flashregion_7_reserved.bin", NULL }, 90 { "EC", "ec", "flashregion_8_ec.bin", "SI_EC" }, 91 { "Device Exp2", "devexp2", "flashregion_9_device_exp.bin", "SI_DEVICEEXT2" }, 92 { "IE", "ie", "flashregion_10_ie.bin", "SI_IE" }, 93 { "10GbE_0", "10gbe_0", "flashregion_11_10gbe0.bin", "SI_10GBE0" }, 94 { "10GbE_1", "10gbe_1", "flashregion_12_10gbe1.bin", "SI_10GBE1" }, 95 { "Reserved", "res13", "flashregion_13_reserved.bin", NULL }, 96 { "Reserved", "res14", "flashregion_14_reserved.bin", NULL }, 97 { "PTT", "ptt", "flashregion_15_ptt.bin", "SI_PTT" }, 98 }; 99 100 /* port from flashrom */ 101 static const char *const ich_chipset_names[] = { 102 "Unknown ICH", 103 "ICH8", 104 "ICH9", 105 "ICH10", 106 "Unknown PCH", 107 "5 series Ibex Peak", 108 "6 series Cougar Point", 109 "7 series Panther Point", 110 "8 series Lynx Point", 111 "Baytrail", 112 "8 series Lynx Point LP", 113 "8 series Wellsburg", 114 "9 series Wildcat Point", 115 "9 series Wildcat Point LP", 116 "Apollo Lake: N3xxx, J3xxx", 117 "Gemini Lake: N5xxx, J5xxx, N4xxx, J4xxx", 118 "Jasper Lake: N6xxx, N51xx, N45xx", 119 "Elkhart Lake: x6000 series Atom", 120 "100/200 series Sunrise Point", 121 "300 series Cannon Point", 122 "400 series Ice Point", 123 "500 series Tiger Point/ 600 series Alder Point", 124 "800 series Meteor Lake", 125 "C620 series Lewisburg", 126 "Denverton: C39xx", 127 NULL 128 }; 129 130 static struct fdbar *find_fd(char *image, int size) 131 { 132 int i, found = 0; 133 134 /* Scan for FD signature */ 135 for (i = 0; i < (size - 4); i += 4) { 136 if (*(uint32_t *)(image + i) == 0x0FF0A55A) { 137 found = 1; 138 break; // signature found. 139 } 140 } 141 142 if (!found) { 143 printf("No Flash Descriptor found in this image\n"); 144 return NULL; 145 } 146 147 struct fdbar *fdb = (struct fdbar *)(image + i); 148 return PTR_IN_RANGE(fdb, image, size) ? fdb : NULL; 149 } 150 151 static char *find_flumap(char *image, int size) 152 { 153 /* The upper map is located in the word before the 256B-long OEM section 154 * at the end of the 4kB-long flash descriptor. In the official 155 * documentation this is defined as FDBAR + 0xEFC. However, starting 156 * with B-Step of Ibex Peak (5 series) the signature (and thus FDBAR) 157 * has moved 16 bytes back to offset 0x10 of the image. Although 158 * official documentation still maintains the offset relative to FDBAR 159 * this is wrong and a simple fixed offset from the start of the image 160 * works. 161 */ 162 char *flumap = image + 4096 - 256 - 4; 163 return PTR_IN_RANGE(flumap, image, size) ? flumap : NULL; 164 } 165 166 static struct fcba *find_fcba(char *image, int size) 167 { 168 struct fdbar *fdb = find_fd(image, size); 169 if (!fdb) 170 return NULL; 171 struct fcba *fcba = (struct fcba *)(image + ((fdb->flmap0 & 0xff) << 4)); 172 return PTR_IN_RANGE(fcba, image, size) ? fcba : NULL; 173 } 174 175 static struct fmba *find_fmba(char *image, int size) 176 { 177 struct fdbar *fdb = find_fd(image, size); 178 if (!fdb) 179 return NULL; 180 struct fmba *fmba = (struct fmba *)(image + ((fdb->flmap1 & 0xff) << 4)); 181 return PTR_IN_RANGE(fmba, image, size) ? fmba : NULL; 182 } 183 184 static struct frba *find_frba(char *image, int size) 185 { 186 struct fdbar *fdb = find_fd(image, size); 187 if (!fdb) 188 return NULL; 189 struct frba *frba = 190 (struct frba *) (image + (((fdb->flmap0 >> 16) & 0xff) << 4)); 191 return PTR_IN_RANGE(frba, image, size) ? frba : NULL; 192 } 193 194 static struct fpsba *find_fpsba(char *image, int size) 195 { 196 struct fdbar *fdb = find_fd(image, size); 197 if (!fdb) 198 return NULL; 199 struct fpsba *fpsba = 200 (struct fpsba *) (image + (((fdb->flmap1 >> 16) & 0xff) << 4)); 201 202 int SSL = ((fdb->flmap1 >> 24) & 0xff) * sizeof(uint32_t); 203 if ((((char *)fpsba) + SSL) >= (image + size)) 204 return NULL; 205 return fpsba; 206 } 207 208 static struct fmsba *find_fmsba(char *image, int size) 209 { 210 struct fdbar *fdb = find_fd(image, size); 211 if (!fdb) 212 return NULL; 213 struct fmsba *fmsba = (struct fmsba *)(image + ((fdb->flmap2 & 0xff) << 4)); 214 return PTR_IN_RANGE(fmsba, image, size) ? fmsba : NULL; 215 } 216 217 /* port from flashrom */ 218 static enum ich_chipset ifd1_guess_chipset(char *image, int size) 219 { 220 const struct fdbar *fdb = find_fd(image, size); 221 if (!fdb) 222 exit(EXIT_FAILURE); 223 uint32_t iccriba = (fdb->flmap2 >> 16) & 0xff; 224 uint32_t msl = (fdb->flmap2 >> 8) & 0xff; 225 uint32_t isl = (fdb->flmap1 >> 24); 226 227 /* Rest for IFD1 chipset type */ 228 if (iccriba == 0x00) { 229 if (msl == 0 && isl <= 2) 230 return CHIPSET_ICH8; 231 else if (isl <= 2) 232 return CHIPSET_ICH9; 233 else if (isl <= 10) 234 return CHIPSET_ICH10; 235 else if (isl <= 16) 236 return CHIPSET_5_SERIES_IBEX_PEAK; 237 printf("Peculiar firmware descriptor, assuming Ibex Peak compatibility.\n"); 238 return CHIPSET_5_SERIES_IBEX_PEAK; 239 } else if (iccriba < 0x31 && (fdb->flmap2 & 0xff) < 0x30) { 240 if (msl == 0 && isl <= 17) 241 return CHIPSET_BAYTRAIL; 242 else if (msl <= 1 && isl <= 18) 243 return CHIPSET_6_SERIES_COUGAR_POINT; 244 else if (msl <= 1 && isl <= 21) 245 return CHIPSET_8_SERIES_LYNX_POINT; 246 printf("Peculiar firmware descriptor, assuming Wildcat Point compatibility.\n"); 247 return CHIPSET_9_SERIES_WILDCAT_POINT; 248 } 249 return CHIPSET_PCH_UNKNOWN; 250 } 251 252 static enum ich_chipset ifd2_platform_to_chipset(const int pindex) 253 { 254 switch (pindex) { 255 case PLATFORM_APL: 256 return CHIPSET_N_J_SERIES_APOLLO_LAKE; 257 case PLATFORM_GLK: 258 return CHIPSET_N_J_SERIES_GEMINI_LAKE; 259 case PLATFORM_JSL: 260 return CHIPSET_N_SERIES_JASPER_LAKE; 261 case PLATFORM_EHL: 262 return CHIPSET_x6000_SERIES_ELKHART_LAKE; 263 case PLATFORM_SKLKBL: 264 return CHIPSET_100_200_SERIES_SUNRISE_POINT; 265 case PLATFORM_CNL: 266 return CHIPSET_300_SERIES_CANNON_POINT; 267 case PLATFORM_TGL: 268 case PLATFORM_ADL: 269 case PLATFORM_IFD2: 270 return CHIPSET_500_600_SERIES_TIGER_ALDER_POINT; 271 case PLATFORM_MTL: 272 return CHIPSET_800_SERIES_METEOR_LAKE; 273 case PLATFORM_PTL: 274 return CHIPSET_900_SERIES_PANTHER_LAKE; 275 case PLATFORM_ICL: 276 return CHIPSET_400_SERIES_ICE_POINT; 277 case PLATFORM_LBG: 278 return CHIPSET_C620_SERIES_LEWISBURG; 279 case PLATFORM_DNV: 280 return CHIPSET_DENVERTON; 281 case PLATFORM_WBG: 282 return CHIPSET_8_SERIES_WELLSBURG; 283 default: 284 return CHIPSET_PCH_UNKNOWN; 285 } 286 } 287 288 /* 289 * Some newer platforms have re-defined the FCBA field that was used to 290 * distinguish IFD v1 v/s v2. Define a list of platforms that we know do not 291 * have the required FCBA field, but are IFD v2 and return true if current 292 * platform is one of them. 293 */ 294 static int is_platform_ifd_2(void) 295 { 296 static const int ifd_2_platforms[] = { 297 PLATFORM_APL, 298 PLATFORM_GLK, 299 PLATFORM_CNL, 300 PLATFORM_LBG, 301 PLATFORM_DNV, 302 PLATFORM_ICL, 303 PLATFORM_TGL, 304 PLATFORM_JSL, 305 PLATFORM_EHL, 306 PLATFORM_ADL, 307 PLATFORM_SKLKBL, 308 PLATFORM_IFD2, 309 PLATFORM_MTL, 310 PLATFORM_PTL, 311 PLATFORM_WBG, 312 }; 313 unsigned int i; 314 315 for (i = 0; i < ARRAY_SIZE(ifd_2_platforms); i++) { 316 if (platform == ifd_2_platforms[i]) 317 return 1; 318 } 319 320 return 0; 321 } 322 323 static void check_ifd_version(char *image, int size) 324 { 325 const struct fdbar *fdb = find_fd(image, size); 326 327 if (is_platform_ifd_2()) { 328 chipset = ifd2_platform_to_chipset(platform); 329 if (chipset == CHIPSET_8_SERIES_WELLSBURG) 330 ifd_version = IFD_VERSION_1_5; 331 else 332 ifd_version = IFD_VERSION_2; 333 max_regions = MIN(max_regions_from_fdbar(fdb), MAX_REGIONS); 334 } else { 335 ifd_version = IFD_VERSION_1; 336 chipset = ifd1_guess_chipset(image, size); 337 max_regions = MIN(max_regions_from_fdbar(fdb), MAX_REGIONS_OLD); 338 } 339 } 340 341 static struct region get_region(const struct frba *frba, unsigned int region_type) 342 { 343 int base_mask; 344 int limit_mask; 345 uint32_t flreg; 346 struct region region; 347 348 if (ifd_version >= IFD_VERSION_2) 349 base_mask = 0x7fff; 350 else 351 base_mask = 0xfff; 352 353 limit_mask = base_mask << 16; 354 355 if (region_type >= max_regions) { 356 fprintf(stderr, "Invalid region type %d.\n", region_type); 357 exit(EXIT_FAILURE); 358 } 359 360 flreg = frba->flreg[region_type]; 361 region.base = (flreg & base_mask) << 12; 362 region.limit = ((flreg & limit_mask) >> 4) | 0xfff; 363 region.size = region.limit - region.base + 1; 364 region.type = region_type; 365 366 if (region.size < 0) 367 region.size = 0; 368 369 return region; 370 } 371 372 static void set_region(struct frba *frba, unsigned int region_type, 373 const struct region *region) 374 { 375 if (region_type >= max_regions) { 376 fprintf(stderr, "Invalid region type %u.\n", region_type); 377 exit (EXIT_FAILURE); 378 } 379 380 frba->flreg[region_type] = 381 (((region->limit >> 12) & 0x7fff) << 16) | 382 ((region->base >> 12) & 0x7fff); 383 } 384 385 static const char *region_name(unsigned int region_type) 386 { 387 if (region_type >= max_regions) { 388 fprintf(stderr, "Invalid region type.\n"); 389 exit(EXIT_FAILURE); 390 } 391 392 return region_names[region_type].pretty; 393 } 394 395 static int region_num(const char *name) 396 { 397 unsigned int i; 398 399 for (i = 0; i < max_regions; i++) { 400 if (strcasecmp(name, region_names[i].pretty) == 0) 401 return i; 402 if (strcasecmp(name, region_names[i].terse) == 0) 403 return i; 404 } 405 406 return -1; 407 } 408 409 static void dump_region(unsigned int num, const struct frba *frba) 410 { 411 struct region region = get_region(frba, num); 412 printf(" Flash Region %d (%s): %08x - %08x %s\n", 413 num, region_name(num), region.base, region.limit, 414 region.size < 1 ? "(unused)" : ""); 415 } 416 417 static int sort_compare(const void *a, const void *b) 418 { 419 return *(size_t *)a - *(size_t *)b; 420 } 421 422 /* 423 * IFDv1 always has 8 regions, while IFDv2 always has 16 regions. 424 * 425 * It's platform specific which regions are used or are reserved. 426 * The 'SPI programming guide' as the name says is a guide only, 427 * not a specification what the hardware actually does. 428 * The best to do is not to rely on the guide, but detect how many 429 * regions are present in the IFD and expose them all. 430 * 431 * Very early IFDv2 chipsets, sometimes unofficially referred to as 432 * IFDv1.5 platforms, only have 8 regions. To not corrupt the IFD when 433 * operating on an IFDv1.5 detect how much space is actually present 434 * in the IFD. 435 */ 436 static int max_regions_from_fdbar(const struct fdbar *fdb) 437 { 438 const size_t fcba = (fdb->flmap0 & 0xff) << 4; 439 const size_t fmba = (fdb->flmap1 & 0xff) << 4; 440 const size_t frba = ((fdb->flmap0 >> 16) & 0xff) << 4; 441 const size_t fpsba = ((fdb->flmap1 >> 16) & 0xff) << 4; 442 const size_t flumap = 4096 - 256 - 4; 443 size_t sorted[5] = {fcba, fmba, frba, fpsba, flumap}; 444 445 qsort(sorted, ARRAY_SIZE(sorted), sizeof(size_t), sort_compare); 446 447 for (size_t i = 0; i < 4; i++) { 448 /* 449 * Find FRBA in the sorted array and determine the size of the 450 * region by the start of the next region. Every region requires 451 * 4 bytes of space. 452 */ 453 if (sorted[i] == frba) 454 return MIN((sorted[i + 1] - sorted[i]) / 4, MAX_REGIONS); 455 } 456 /* Never reaches this point */ 457 return 0; 458 } 459 460 static void dump_frba(const struct frba *frba) 461 { 462 unsigned int i; 463 struct region region; 464 printf("Found Region Section\n"); 465 for (i = 0; i < max_regions; i++) { 466 region = get_region(frba, i); 467 /* Skip unused & reserved Flash Region */ 468 if (region.size < 1 && !strcmp(region_name(i), "Reserved")) 469 continue; 470 471 printf("FLREG%u: 0x%08x\n", i, frba->flreg[i]); 472 dump_region(i, frba); 473 } 474 } 475 476 static void dump_flashrom_layout(char *image, int size, const char *layout_fname) 477 { 478 const struct frba *frba = find_frba(image, size); 479 if (!frba) 480 exit(EXIT_FAILURE); 481 482 int layout_fd = open(layout_fname, O_WRONLY | O_CREAT | O_TRUNC, 0644); 483 if (layout_fd == -1) { 484 perror("Could not open file"); 485 exit(EXIT_FAILURE); 486 } 487 488 for (unsigned int i = 0; i < max_regions; i++) { 489 struct region region = get_region(frba, i); 490 491 /* A region limit of 0 is an indicator of an unused region 492 * A region base of 7FFFh is an indicator of a reserved region 493 */ 494 if (region.limit == 0 || region.base == 0x07FFF000) 495 continue; 496 497 char buf[LAYOUT_LINELEN]; 498 snprintf(buf, LAYOUT_LINELEN, "%08x:%08x %s\n", region.base, region.limit, region_names[i].terse); 499 if (write(layout_fd, buf, strlen(buf)) < 0) { 500 perror("Could not write to file"); 501 exit(EXIT_FAILURE); 502 } 503 } 504 close(layout_fd); 505 printf("Wrote layout to %s\n", layout_fname); 506 } 507 508 static void _decode_spi_frequency(unsigned int freq) 509 { 510 switch (freq) { 511 case SPI_FREQUENCY_20MHZ: 512 printf("20MHz"); 513 break; 514 case SPI_FREQUENCY_33MHZ: 515 printf("33MHz"); 516 break; 517 case SPI_FREQUENCY_48MHZ: 518 printf("48MHz"); 519 break; 520 case SPI_FREQUENCY_50MHZ_30MHZ: 521 switch (ifd_version) { 522 case IFD_VERSION_1: 523 case IFD_VERSION_1_5: 524 printf("50MHz"); 525 break; 526 case IFD_VERSION_2: 527 printf("30MHz"); 528 break; 529 } 530 break; 531 case SPI_FREQUENCY_17MHZ: 532 printf("17MHz"); 533 break; 534 default: 535 printf("unknown<%x>MHz", freq); 536 } 537 } 538 539 static void _decode_spi_frequency_500_series(unsigned int freq) 540 { 541 switch (freq) { 542 case SPI_FREQUENCY_100MHZ: 543 printf("100MHz"); 544 break; 545 case SPI_FREQUENCY_50MHZ: 546 printf("50MHz"); 547 break; 548 case SPI_FREQUENCY_500SERIES_33MHZ: 549 printf("33MHz"); 550 break; 551 case SPI_FREQUENCY_25MHZ: 552 printf("25MHz"); 553 break; 554 case SPI_FREQUENCY_14MHZ: 555 printf("14MHz"); 556 break; 557 default: 558 printf("unknown<%x>MHz", freq); 559 } 560 } 561 562 static void decode_spi_frequency(unsigned int freq) 563 { 564 switch (chipset) { 565 case CHIPSET_500_600_SERIES_TIGER_ALDER_POINT: 566 case CHIPSET_800_SERIES_METEOR_LAKE: 567 case CHIPSET_900_SERIES_PANTHER_LAKE: 568 _decode_spi_frequency_500_series(freq); 569 break; 570 default: 571 _decode_spi_frequency(freq); 572 } 573 } 574 575 static void _decode_espi_frequency(unsigned int freq) 576 { 577 switch (freq) { 578 case ESPI_FREQUENCY_20MHZ: 579 printf("20MHz"); 580 break; 581 case ESPI_FREQUENCY_24MHZ: 582 printf("24MHz"); 583 break; 584 case ESPI_FREQUENCY_30MHZ: 585 printf("30MHz"); 586 break; 587 case ESPI_FREQUENCY_48MHZ: 588 printf("48MHz"); 589 break; 590 case ESPI_FREQUENCY_60MHZ: 591 printf("60MHz"); 592 break; 593 case ESPI_FREQUENCY_17MHZ: 594 printf("17MHz"); 595 break; 596 default: 597 printf("unknown<%x>MHz", freq); 598 } 599 } 600 601 static void _decode_espi_frequency_500_series(unsigned int freq) 602 { 603 switch (freq) { 604 case ESPI_FREQUENCY_500SERIES_20MHZ: 605 printf("20MHz"); 606 break; 607 case ESPI_FREQUENCY_500SERIES_24MHZ: 608 printf("24MHz"); 609 break; 610 case ESPI_FREQUENCY_500SERIES_25MHZ: 611 printf("25MHz"); 612 break; 613 case ESPI_FREQUENCY_500SERIES_48MHZ: 614 printf("48MHz"); 615 break; 616 case ESPI_FREQUENCY_500SERIES_60MHZ: 617 printf("60MHz"); 618 break; 619 default: 620 printf("unknown<%x>MHz", freq); 621 } 622 } 623 624 static void _decode_espi_frequency_800_series(unsigned int freq) 625 { 626 switch (freq) { 627 case ESPI_FREQUENCY_800SERIES_20MHZ: 628 printf("20MHz"); 629 break; 630 case ESPI_FREQUENCY_800SERIES_25MHZ: 631 printf("25MHz"); 632 break; 633 case ESPI_FREQUENCY_800SERIES_33MHZ: 634 printf("33MHz"); 635 break; 636 case ESPI_FREQUENCY_800SERIES_50MHZ: 637 printf("50MHz"); 638 break; 639 default: 640 printf("unknown<%x>MHz", freq); 641 } 642 } 643 644 static void decode_espi_frequency(unsigned int freq) 645 { 646 switch (chipset) { 647 case CHIPSET_500_600_SERIES_TIGER_ALDER_POINT: 648 _decode_espi_frequency_500_series(freq); 649 break; 650 case CHIPSET_800_SERIES_METEOR_LAKE: 651 case CHIPSET_900_SERIES_PANTHER_LAKE: 652 _decode_espi_frequency_800_series(freq); 653 break; 654 default: 655 _decode_espi_frequency(freq); 656 } 657 } 658 659 static void decode_component_density(unsigned int density) 660 { 661 switch (density) { 662 case COMPONENT_DENSITY_512KB: 663 printf("512KB"); 664 break; 665 case COMPONENT_DENSITY_1MB: 666 printf("1MB"); 667 break; 668 case COMPONENT_DENSITY_2MB: 669 printf("2MB"); 670 break; 671 case COMPONENT_DENSITY_4MB: 672 printf("4MB"); 673 break; 674 case COMPONENT_DENSITY_8MB: 675 printf("8MB"); 676 break; 677 case COMPONENT_DENSITY_16MB: 678 printf("16MB"); 679 break; 680 case COMPONENT_DENSITY_32MB: 681 printf("32MB"); 682 break; 683 case COMPONENT_DENSITY_64MB: 684 printf("64MB"); 685 break; 686 case COMPONENT_DENSITY_UNUSED: 687 printf("UNUSED"); 688 break; 689 default: 690 printf("unknown<%x>MB", density); 691 } 692 } 693 694 static int is_platform_with_pch(void) 695 { 696 if (chipset >= CHIPSET_5_SERIES_IBEX_PEAK) 697 return 1; 698 699 return 0; 700 } 701 702 /* FLMAP0 register bit 24 onwards are reserved from SPT PCH */ 703 static int is_platform_with_100x_series_pch(void) 704 { 705 if (chipset >= CHIPSET_100_200_SERIES_SUNRISE_POINT && 706 chipset <= CHIPSET_900_SERIES_PANTHER_LAKE) 707 return 1; 708 709 return 0; 710 } 711 712 static void dump_fcba(const struct fcba *fcba, const struct fpsba *fpsba) 713 { 714 unsigned int freq; 715 716 printf("\nFound Component Section\n"); 717 printf("FLCOMP 0x%08x\n", fcba->flcomp); 718 printf(" Dual Output Fast Read Support: %ssupported\n", 719 (fcba->flcomp & (1 << 30)) ? "" : "not "); 720 printf(" Read ID/Read Status Clock Frequency: "); 721 decode_spi_frequency((fcba->flcomp >> 27) & 7); 722 printf("\n Write/Erase Clock Frequency: "); 723 decode_spi_frequency((fcba->flcomp >> 24) & 7); 724 printf("\n Fast Read Clock Frequency: "); 725 decode_spi_frequency((fcba->flcomp >> 21) & 7); 726 printf("\n Fast Read Support: %ssupported", 727 (fcba->flcomp & (1 << 20)) ? "" : "not "); 728 if (is_platform_with_100x_series_pch() && 729 chipset != CHIPSET_100_200_SERIES_SUNRISE_POINT) { 730 printf("\n Read eSPI/EC Bus Frequency: "); 731 if (chipset == CHIPSET_500_600_SERIES_TIGER_ALDER_POINT) 732 freq = (fpsba->pchstrp[22] & 0x38) >> 3; 733 else if (chipset == CHIPSET_800_SERIES_METEOR_LAKE) 734 freq = (fpsba->pchstrp[65] & 0x38) >> 3; 735 else if (chipset == CHIPSET_900_SERIES_PANTHER_LAKE) 736 freq = (fpsba->pchstrp[119] & 0x38) >> 3; 737 else 738 freq = (fcba->flcomp >> 17) & 7; 739 decode_espi_frequency(freq); 740 741 printf("\n Quad I/O Read: %s", 742 (fcba->flcomp & (1 << 15)) ? "enabled" : "disabled"); 743 printf("\n Quad Output Read: %s", 744 (fcba->flcomp & (1 << 14)) ? "enabled" : "disabled"); 745 printf("\n Dual I/O Read: %s", 746 (fcba->flcomp & (1 << 13)) ? "enabled" : "disabled"); 747 printf("\n Dual Output Read: %s", 748 (fcba->flcomp & (1 << 12)) ? "enabled" : "disabled"); 749 } else { 750 printf("\n Read Clock Frequency: "); 751 decode_spi_frequency((fcba->flcomp >> 17) & 7); 752 } 753 754 switch (ifd_version) { 755 case IFD_VERSION_1: 756 printf("\n Component 2 Density: "); 757 decode_component_density((fcba->flcomp >> 3) & 7); 758 printf("\n Component 1 Density: "); 759 decode_component_density(fcba->flcomp & 7); 760 break; 761 case IFD_VERSION_1_5: 762 case IFD_VERSION_2: 763 printf("\n Component 2 Density: "); 764 decode_component_density((fcba->flcomp >> 4) & 0xf); 765 printf("\n Component 1 Density: "); 766 decode_component_density(fcba->flcomp & 0xf); 767 break; 768 } 769 770 printf("\n"); 771 printf("FLILL 0x%08x\n", fcba->flill); 772 printf(" Invalid Instruction 3: 0x%02x\n", 773 (fcba->flill >> 24) & 0xff); 774 printf(" Invalid Instruction 2: 0x%02x\n", 775 (fcba->flill >> 16) & 0xff); 776 printf(" Invalid Instruction 1: 0x%02x\n", 777 (fcba->flill >> 8) & 0xff); 778 printf(" Invalid Instruction 0: 0x%02x\n", 779 fcba->flill & 0xff); 780 if (is_platform_with_100x_series_pch()) { 781 printf("FLILL1 0x%08x\n", fcba->flpb); 782 printf(" Invalid Instruction 7: 0x%02x\n", 783 (fcba->flpb >> 24) & 0xff); 784 printf(" Invalid Instruction 6: 0x%02x\n", 785 (fcba->flpb >> 16) & 0xff); 786 printf(" Invalid Instruction 5: 0x%02x\n", 787 (fcba->flpb >> 8) & 0xff); 788 printf(" Invalid Instruction 4: 0x%02x\n", 789 fcba->flpb & 0xff); 790 } else { 791 printf("FLPB 0x%08x\n", fcba->flpb); 792 printf(" Flash Partition Boundary Address: 0x%06x\n\n", 793 (fcba->flpb & 0xfff) << 12); 794 } 795 } 796 797 static void dump_fpsba(const struct fdbar *fdb, const struct fpsba *fpsba) 798 { 799 unsigned int i; 800 /* SoC Straps, aka PSL, aka ISL */ 801 unsigned int SS = (fdb->flmap1 >> 24) & 0xff; 802 803 printf("Found PCH Strap Section\n"); 804 for (i = 0; i < SS; i++) 805 printf("PCHSTRP%-3u: 0x%08x\n", i, fpsba->pchstrp[i]); 806 807 if (ifd_version >= IFD_VERSION_2) { 808 printf("HAP bit is %sset\n", 809 fpsba->pchstrp[0] & (1 << 16) ? "" : "not "); 810 } else if (chipset >= CHIPSET_ICH8 && chipset <= CHIPSET_ICH10) { 811 printf("ICH_MeDisable bit is %sset\n", 812 fpsba->pchstrp[0] & 1 ? "" : "not "); 813 } else { 814 printf("AltMeDisable bit is %sset\n", 815 fpsba->pchstrp[10] & (1 << 7) ? "" : "not "); 816 } 817 818 printf("\n"); 819 } 820 821 static void decode_flmstr(uint32_t flmstr) 822 { 823 int wr_shift, rd_shift; 824 if (ifd_version >= IFD_VERSION_2) { 825 wr_shift = FLMSTR_WR_SHIFT_V2; 826 rd_shift = FLMSTR_RD_SHIFT_V2; 827 } else { 828 wr_shift = FLMSTR_WR_SHIFT_V1; 829 rd_shift = FLMSTR_RD_SHIFT_V1; 830 } 831 832 /* EC region access only available on v2+ */ 833 if (PLATFORM_HAS_EC_REGION) 834 printf(" EC Region Write Access: %s\n", 835 (flmstr & (1 << (wr_shift + 8))) ? 836 "enabled" : "disabled"); 837 printf(" Platform Data Region Write Access: %s\n", 838 (flmstr & (1 << (wr_shift + 4))) ? "enabled" : "disabled"); 839 if (PLATFORM_HAS_GBE_REGION) { 840 printf(" GbE Region Write Access: %s\n", 841 (flmstr & (1 << (wr_shift + 3))) ? "enabled" : "disabled"); 842 } 843 printf(" Intel ME Region Write Access: %s\n", 844 (flmstr & (1 << (wr_shift + 2))) ? "enabled" : "disabled"); 845 printf(" Host CPU/BIOS Region Write Access: %s\n", 846 (flmstr & (1 << (wr_shift + 1))) ? "enabled" : "disabled"); 847 printf(" Flash Descriptor Write Access: %s\n", 848 (flmstr & (1 << wr_shift)) ? "enabled" : "disabled"); 849 if (PLATFORM_HAS_10GBE_0_REGION) { 850 printf(" 10GbE_0 Write Access: %s\n", 851 (flmstr & (1 << (wr_shift + 11))) ? "enabled" : "disabled"); 852 } 853 if (PLATFORM_HAS_10GBE_1_REGION) { 854 printf(" 10GbE_1 Write Access: %s\n", 855 (flmstr & (1 << 4)) ? "enabled" : "disabled"); 856 } 857 858 if (PLATFORM_HAS_EC_REGION) 859 printf(" EC Region Read Access: %s\n", 860 (flmstr & (1 << (rd_shift + 8))) ? 861 "enabled" : "disabled"); 862 printf(" Platform Data Region Read Access: %s\n", 863 (flmstr & (1 << (rd_shift + 4))) ? "enabled" : "disabled"); 864 if (PLATFORM_HAS_GBE_REGION) { 865 printf(" GbE Region Read Access: %s\n", 866 (flmstr & (1 << (rd_shift + 3))) ? "enabled" : "disabled"); 867 } 868 printf(" Intel ME Region Read Access: %s\n", 869 (flmstr & (1 << (rd_shift + 2))) ? "enabled" : "disabled"); 870 printf(" Host CPU/BIOS Region Read Access: %s\n", 871 (flmstr & (1 << (rd_shift + 1))) ? "enabled" : "disabled"); 872 printf(" Flash Descriptor Read Access: %s\n", 873 (flmstr & (1 << rd_shift)) ? "enabled" : "disabled"); 874 if (PLATFORM_HAS_10GBE_0_REGION) { 875 printf(" 10GbE_0 Read Access: %s\n", 876 (flmstr & (1 << (rd_shift + 11))) ? "enabled" : "disabled"); 877 } 878 if (PLATFORM_HAS_10GBE_1_REGION) { 879 printf(" 10GbE_1 Read Access: %s\n", 880 (flmstr & (1 << 0)) ? "enabled" : "disabled"); 881 } 882 883 /* Requestor ID doesn't exist for ifd 2 */ 884 if (ifd_version < IFD_VERSION_2) 885 printf(" Requester ID: 0x%04x\n\n", 886 flmstr & 0xffff); 887 } 888 889 static void dump_fmba(const struct fmba *fmba) 890 { 891 printf("Found Master Section\n"); 892 printf("FLMSTR1: 0x%08x (Host CPU/BIOS)\n", fmba->flmstr1); 893 decode_flmstr(fmba->flmstr1); 894 printf("FLMSTR2: 0x%08x (Intel ME)\n", fmba->flmstr2); 895 decode_flmstr(fmba->flmstr2); 896 if (PLATFORM_HAS_GBE_REGION) { 897 printf("FLMSTR3: 0x%08x (GbE)\n", fmba->flmstr3); 898 decode_flmstr(fmba->flmstr3); 899 if (ifd_version >= IFD_VERSION_2) { 900 printf("FLMSTR5: 0x%08x (EC)\n", fmba->flmstr5); 901 decode_flmstr(fmba->flmstr5); 902 } 903 } else { 904 printf("FLMSTR6: 0x%08x (IE)\n", fmba->flmstr6); 905 decode_flmstr(fmba->flmstr6); 906 } 907 } 908 909 static void dump_fmsba(const struct fmsba *fmsba) 910 { 911 unsigned int i; 912 printf("Found Processor Strap Section\n"); 913 for (i = 0; i < ARRAY_SIZE(fmsba->data); i++) 914 printf("????: 0x%08x\n", fmsba->data[i]); 915 916 if (chipset >= CHIPSET_ICH8 && chipset <= CHIPSET_ICH10) { 917 printf("MCH_MeDisable bit is %sset\n", 918 fmsba->data[0] & 1 ? "" : "not "); 919 printf("MCH_AltMeDisable bit is %sset\n", 920 fmsba->data[0] & (1 << 7) ? "" : "not "); 921 } 922 } 923 924 static void dump_jid(uint32_t jid) 925 { 926 printf(" SPI Component Vendor ID: 0x%02x\n", 927 jid & 0xff); 928 printf(" SPI Component Device ID 0: 0x%02x\n", 929 (jid >> 8) & 0xff); 930 printf(" SPI Component Device ID 1: 0x%02x\n", 931 (jid >> 16) & 0xff); 932 } 933 934 static void dump_vscc(uint32_t vscc) 935 { 936 printf(" Lower Erase Opcode: 0x%02x\n", 937 vscc >> 24); 938 printf(" Lower Write Enable on Write Status: 0x%02x\n", 939 vscc & (1 << 20) ? 0x06 : 0x50); 940 printf(" Lower Write Status Required: %s\n", 941 vscc & (1 << 19) ? "Yes" : "No"); 942 printf(" Lower Write Granularity: %d bytes\n", 943 vscc & (1 << 18) ? 64 : 1); 944 printf(" Lower Block / Sector Erase Size: "); 945 switch ((vscc >> 16) & 0x3) { 946 case 0: 947 printf("256 Byte\n"); 948 break; 949 case 1: 950 printf("4KB\n"); 951 break; 952 case 2: 953 printf("8KB\n"); 954 break; 955 case 3: 956 printf("64KB\n"); 957 break; 958 } 959 960 printf(" Upper Erase Opcode: 0x%02x\n", 961 (vscc >> 8) & 0xff); 962 printf(" Upper Write Enable on Write Status: 0x%02x\n", 963 vscc & (1 << 4) ? 0x06 : 0x50); 964 printf(" Upper Write Status Required: %s\n", 965 vscc & (1 << 3) ? "Yes" : "No"); 966 printf(" Upper Write Granularity: %d bytes\n", 967 vscc & (1 << 2) ? 64 : 1); 968 printf(" Upper Block / Sector Erase Size: "); 969 switch (vscc & 0x3) { 970 case 0: 971 printf("256 Byte\n"); 972 break; 973 case 1: 974 printf("4KB\n"); 975 break; 976 case 2: 977 printf("8KB\n"); 978 break; 979 case 3: 980 printf("64KB\n"); 981 break; 982 } 983 } 984 985 static void dump_vtba(const struct vtba *vtba, int vtl) 986 { 987 int i; 988 int max_len = sizeof(struct vtba) / sizeof(struct vscc); 989 int num = (vtl >> 1) < max_len ? (vtl >> 1) : max_len; 990 991 printf("ME VSCC table:\n"); 992 for (i = 0; i < num; i++) { 993 printf(" JID%d: 0x%08x\n", i, vtba->entry[i].jid); 994 dump_jid(vtba->entry[i].jid); 995 printf(" VSCC%d: 0x%08x\n", i, vtba->entry[i].vscc); 996 dump_vscc(vtba->entry[i].vscc); 997 } 998 printf("\n"); 999 } 1000 1001 static void dump_oem(const uint8_t *oem) 1002 { 1003 int i, j; 1004 printf("OEM Section:\n"); 1005 for (i = 0; i < 4; i++) { 1006 printf("%02x:", i << 4); 1007 for (j = 0; j < 16; j++) 1008 printf(" %02x", oem[(i << 4) + j]); 1009 printf("\n"); 1010 } 1011 printf("\n"); 1012 } 1013 1014 static void dump_fd(char *image, int size) 1015 { 1016 const struct fdbar *fdb = find_fd(image, size); 1017 if (!fdb) 1018 exit(EXIT_FAILURE); 1019 1020 printf("%s", is_platform_with_pch() ? "PCH" : "ICH"); 1021 printf(" Revision: %s\n", ich_chipset_names[chipset]); 1022 printf("FLMAP0: 0x%08x\n", fdb->flmap0); 1023 if (!is_platform_with_100x_series_pch()) 1024 printf(" NR: %d\n", (fdb->flmap0 >> 24) & 7); 1025 printf(" FRBA: 0x%x\n", ((fdb->flmap0 >> 16) & 0xff) << 4); 1026 printf(" NC: %d\n", ((fdb->flmap0 >> 8) & 3) + 1); 1027 printf(" FCBA: 0x%x\n", ((fdb->flmap0) & 0xff) << 4); 1028 1029 printf("FLMAP1: 0x%08x\n", fdb->flmap1); 1030 printf(" %s: ", is_platform_with_100x_series_pch() ? "PSL" : "ISL"); 1031 printf("0x%02x\n", (fdb->flmap1 >> 24) & 0xff); 1032 printf(" FPSBA: 0x%x\n", ((fdb->flmap1 >> 16) & 0xff) << 4); 1033 printf(" NM: %d\n", (fdb->flmap1 >> 8) & 3); 1034 printf(" FMBA: 0x%x\n", ((fdb->flmap1) & 0xff) << 4); 1035 1036 if (!is_platform_with_100x_series_pch()) { 1037 printf("FLMAP2: 0x%08x\n", fdb->flmap2); 1038 printf(" PSL: 0x%04x\n", (fdb->flmap2 >> 8) & 0xffff); 1039 printf(" FMSBA: 0x%x\n", ((fdb->flmap2) & 0xff) << 4); 1040 } 1041 1042 if (chipset == CHIPSET_500_600_SERIES_TIGER_ALDER_POINT || 1043 chipset == CHIPSET_800_SERIES_METEOR_LAKE || 1044 chipset == CHIPSET_900_SERIES_PANTHER_LAKE) { 1045 printf("FLMAP3: 0x%08x\n", fdb->flmap3); 1046 printf(" Minor Revision ID: 0x%04x\n", (fdb->flmap3 >> 14) & 0x7f); 1047 printf(" Major Revision ID: 0x%04x\n", (fdb->flmap3 >> 21) & 0x7ff); 1048 } 1049 1050 char *flumap = find_flumap(image, size); 1051 uint32_t flumap1 = *(uint32_t *)flumap; 1052 printf("FLUMAP1: 0x%08x\n", flumap1); 1053 printf(" Intel ME VSCC Table Length (VTL): %d\n", 1054 (flumap1 >> 8) & 0xff); 1055 printf(" Intel ME VSCC Table Base Address (VTBA): 0x%06x\n\n", 1056 (flumap1 & 0xff) << 4); 1057 dump_vtba((struct vtba *) 1058 (image + ((flumap1 & 0xff) << 4)), 1059 (flumap1 >> 8) & 0xff); 1060 dump_oem((const uint8_t *)image + 0xf00); 1061 1062 const struct frba *frba = find_frba(image, size); 1063 const struct fcba *fcba = find_fcba(image, size); 1064 const struct fpsba *fpsba = find_fpsba(image, size); 1065 const struct fmba *fmba = find_fmba(image, size); 1066 const struct fmsba *fmsba = find_fmsba(image, size); 1067 1068 if (frba && fcba && fpsba && fmba && fmsba) { 1069 dump_frba(frba); 1070 dump_fcba(fcba, fpsba); 1071 dump_fpsba(fdb, fpsba); 1072 dump_fmba(fmba); 1073 dump_fmsba(fmsba); 1074 } else { 1075 printf("FD is corrupted!\n"); 1076 } 1077 } 1078 1079 /* Takes an image containing an IFD and creates a Flashmap .fmd file template. 1080 * This flashmap will contain all IFD regions except the BIOS region. 1081 * The BIOS region is created by coreboot itself and 'should' match the IFD region 1082 * anyway (CONFIG_VALIDATE_INTEL_DESCRIPTOR should make sure). coreboot built system will use 1083 * this template to generate the final Flashmap file. 1084 */ 1085 static void create_fmap_template(char *image, int size, const char *layout_fname) 1086 { 1087 const struct frba *frba = find_frba(image, size); 1088 if (!frba) 1089 exit(EXIT_FAILURE); 1090 1091 int layout_fd = open(layout_fname, O_WRONLY | O_CREAT | O_TRUNC, 0644); 1092 if (layout_fd == -1) { 1093 perror("Could not open file"); 1094 exit(EXIT_FAILURE); 1095 } 1096 1097 char *bbuf = "FLASH@##ROM_BASE## ##ROM_SIZE## {\n"; 1098 if (write(layout_fd, bbuf, strlen(bbuf)) < 0) { 1099 perror("Could not write to file"); 1100 exit(EXIT_FAILURE); 1101 } 1102 1103 /* fmaptool requires regions in .fmd to be sorted. 1104 * => We need to sort the regions by base address before writing them in .fmd File 1105 */ 1106 int count_regions = 0; 1107 struct region sorted_regions[MAX_REGIONS] = { 0 }; 1108 for (unsigned int i = 0; i < max_regions; i++) { 1109 struct region region = get_region(frba, i); 1110 1111 /* A region limit of 0 is an indicator of an unused region 1112 * A region base of 7FFFh is an indicator of a reserved region 1113 */ 1114 if (region.limit == 0 || region.base == 0x07FFF000) 1115 continue; 1116 1117 /* Is there an FMAP equivalent? IFD reserved regions are usually thrown out 1118 * of the FMAP here 1119 */ 1120 if (!region_names[region.type].fmapname) { 1121 printf("Skip IFD region: %s\n", region_names[region.type].pretty); 1122 continue; 1123 } 1124 1125 /* Here we decide to use the coreboot generated FMAP BIOS region, instead of 1126 * the one specified in the IFD. The case when IFD and FMAP BIOS region do not 1127 * match cannot be caught here, therefore one should still validate IFD and 1128 * FMAP via CONFIG_VALIDATE_INTEL_DESCRIPTOR 1129 */ 1130 if (i == REGION_BIOS) 1131 continue; 1132 1133 sorted_regions[count_regions] = region; 1134 // basically insertion sort 1135 for (int i = count_regions - 1; i >= 0; i--) { 1136 if (sorted_regions[i].base > sorted_regions[i + 1].base) { 1137 struct region tmp = sorted_regions[i]; 1138 sorted_regions[i] = sorted_regions[i + 1]; 1139 sorted_regions[i + 1] = tmp; 1140 } 1141 } 1142 count_regions++; 1143 } 1144 1145 // Now write regions sorted by base address in the fmap file 1146 for (int i = 0; i < count_regions; i++) { 1147 struct region region = sorted_regions[i]; 1148 char buf[LAYOUT_LINELEN]; 1149 snprintf(buf, LAYOUT_LINELEN, "\t%s@0x%X 0x%X\n", region_names[region.type].fmapname, region.base, region.size); 1150 if (write(layout_fd, buf, strlen(buf)) < 0) { 1151 perror("Could not write to file"); 1152 exit(EXIT_FAILURE); 1153 } 1154 } 1155 1156 char *ebuf = "\tSI_BIOS@##BIOS_BASE## ##BIOS_SIZE## {\n" 1157 "\t\t##CONSOLE_ENTRY##\n" 1158 "\t\t##MRC_CACHE_ENTRY##\n" 1159 "\t\t##SMMSTORE_ENTRY##\n" 1160 "\t\t##SPD_CACHE_ENTRY##\n" 1161 "\t\t##VPD_ENTRY##\n" 1162 "\t\tFMAP@##FMAP_BASE## ##FMAP_SIZE##\n" 1163 "\t\tCOREBOOT(CBFS)@##CBFS_BASE## ##CBFS_SIZE##\n" 1164 "\t}\n" 1165 "}\n"; 1166 if (write(layout_fd, ebuf, strlen(ebuf)) < 0) { 1167 perror("Could not write to file"); 1168 exit(EXIT_FAILURE); 1169 } 1170 1171 close(layout_fd); 1172 printf("Wrote layout to %s\n", layout_fname); 1173 } 1174 1175 static void write_regions(char *image, int size) 1176 { 1177 unsigned int i; 1178 const struct frba *frba = find_frba(image, size); 1179 1180 if (!frba) 1181 exit(EXIT_FAILURE); 1182 1183 for (i = 0; i < max_regions; i++) { 1184 struct region region = get_region(frba, i); 1185 dump_region(i, frba); 1186 if (region.size > 0) { 1187 int region_fd; 1188 region_fd = open(region_names[i].filename, 1189 O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 1190 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); 1191 if (region_fd < 0) { 1192 perror("Error while trying to open file"); 1193 exit(EXIT_FAILURE); 1194 } 1195 if (write(region_fd, image + region.base, region.size) != region.size) 1196 perror("Error while writing"); 1197 close(region_fd); 1198 } 1199 } 1200 } 1201 1202 static void validate_layout(char *image, int size) 1203 { 1204 uint i, errors = 0; 1205 struct fmap *fmap; 1206 long int fmap_loc = fmap_find((uint8_t *)image, size); 1207 const struct frba *frba = find_frba(image, size); 1208 1209 if (fmap_loc < 0 || !frba) { 1210 printf("Could not find FMAP (%p) or Intel Flash Descriptor (%p)\n", 1211 (void *)fmap_loc, frba); 1212 exit(EXIT_FAILURE); 1213 } 1214 1215 fmap = (struct fmap *)(image + fmap_loc); 1216 1217 int matches = 0; 1218 for (i = 0; i < max_regions; i++) { 1219 struct region region = get_region(frba, i); 1220 if (region.size == 0) 1221 continue; 1222 1223 const struct fmap_area *area = fmap_find_area(fmap, region_names[i].fmapname); 1224 if (!area) 1225 continue; 1226 1227 matches++; // found a match between FMAP and IFD region 1228 1229 if ((uint)region.base != area->offset || (uint)region.size != area->size) { 1230 if (i == REGION_BIOS) { 1231 /* 1232 * BIOS FMAP region is a special case 1233 * coreboots FMAP BIOS region depends on the CONFIG_CBFS_SIZE 1234 * while the IFD BIOS region is always of static size. 1235 * Therefore we just make sure that the BIOS region of the FMAP 1236 * is inside the region specified by the IFD 1237 */ 1238 if ((uint)region.base <= area->offset && 1239 ((uint)region.base + region.size) >= (area->offset + area->size)) { 1240 continue; 1241 } 1242 } 1243 printf("Region mismatch between %s and %s\n", region_names[i].terse, area->name); 1244 printf(" Descriptor region %s:\n", region_names[i].terse); 1245 printf(" offset: 0x%08x\n", region.base); 1246 printf(" length: 0x%08x\n", region.size); 1247 printf(" FMAP area %s:\n", area->name); 1248 printf(" offset: 0x%08x\n", area->offset); 1249 printf(" length: 0x%08x\n", area->size); 1250 errors++; 1251 } 1252 } 1253 1254 if (!matches) { 1255 // At least a BIOS region should be present in both IFD and FMAP 1256 fprintf(stderr, "Warning: Not a single IFD region found in FMAP\n"); 1257 } 1258 1259 if (errors > 0) 1260 exit(EXIT_FAILURE); 1261 } 1262 1263 static void write_image(const char *filename, char *image, int size) 1264 { 1265 int new_fd; 1266 printf("Writing new image to %s\n", filename); 1267 1268 // Now write out new image 1269 new_fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644); 1270 if (new_fd < 0) { 1271 perror("Error while trying to open file"); 1272 exit(EXIT_FAILURE); 1273 } 1274 if (write(new_fd, image, size) != size) 1275 perror("Error while writing"); 1276 close(new_fd); 1277 } 1278 1279 static void set_spi_frequency(const char *filename, char *image, int size, 1280 enum spi_frequency freq) 1281 { 1282 struct fcba *fcba = find_fcba(image, size); 1283 if (!fcba) 1284 exit(EXIT_FAILURE); 1285 1286 /* clear bits 21-29 */ 1287 fcba->flcomp &= ~0x3fe00000; 1288 /* Read ID and Read Status Clock Frequency */ 1289 fcba->flcomp |= freq << 27; 1290 /* Write and Erase Clock Frequency */ 1291 fcba->flcomp |= freq << 24; 1292 /* Fast Read Clock Frequency */ 1293 fcba->flcomp |= freq << 21; 1294 1295 write_image(filename, image, size); 1296 } 1297 1298 static void set_em100_mode(const char *filename, char *image, int size) 1299 { 1300 struct fcba *fcba = find_fcba(image, size); 1301 if (!fcba) 1302 exit(EXIT_FAILURE); 1303 1304 int freq; 1305 1306 switch (ifd_version) { 1307 case IFD_VERSION_1: 1308 case IFD_VERSION_1_5: 1309 freq = SPI_FREQUENCY_20MHZ; 1310 break; 1311 case IFD_VERSION_2: 1312 freq = SPI_FREQUENCY_17MHZ; 1313 break; 1314 default: 1315 freq = SPI_FREQUENCY_17MHZ; 1316 break; 1317 } 1318 1319 fcba->flcomp &= ~(1 << 30); 1320 set_spi_frequency(filename, image, size, freq); 1321 } 1322 1323 static void set_chipdensity(const char *filename, char *image, int size, 1324 unsigned int density) 1325 { 1326 struct fcba *fcba = find_fcba(image, size); 1327 uint8_t mask, chip2_offset; 1328 if (!fcba) 1329 exit(EXIT_FAILURE); 1330 1331 printf("Setting chip density to "); 1332 decode_component_density(density); 1333 printf("\n"); 1334 1335 switch (ifd_version) { 1336 case IFD_VERSION_1: 1337 /* fail if selected density is not supported by this version */ 1338 if ( (density == COMPONENT_DENSITY_32MB) || 1339 (density == COMPONENT_DENSITY_64MB) || 1340 (density == COMPONENT_DENSITY_UNUSED) ) { 1341 printf("error: Selected density not supported in IFD version 1.\n"); 1342 exit(EXIT_FAILURE); 1343 } 1344 mask = 0x7; 1345 chip2_offset = 3; 1346 break; 1347 case IFD_VERSION_1_5: 1348 case IFD_VERSION_2: 1349 mask = 0xf; 1350 chip2_offset = 4; 1351 break; 1352 default: 1353 printf("error: Unknown IFD version\n"); 1354 exit(EXIT_FAILURE); 1355 break; 1356 } 1357 1358 /* clear chip density for corresponding chip */ 1359 switch (selected_chip) { 1360 case 1: 1361 fcba->flcomp &= ~mask; 1362 break; 1363 case 2: 1364 fcba->flcomp &= ~(mask << chip2_offset); 1365 break; 1366 default: /*both chips*/ 1367 fcba->flcomp &= ~(mask | (mask << chip2_offset)); 1368 break; 1369 } 1370 1371 /* set the new density */ 1372 if (selected_chip == 1 || selected_chip == 0) 1373 fcba->flcomp |= (density); /* first chip */ 1374 if (selected_chip == 2 || selected_chip == 0) 1375 fcba->flcomp |= (density << chip2_offset); /* second chip */ 1376 1377 write_image(filename, image, size); 1378 } 1379 1380 static int check_region(const struct frba *frba, unsigned int region_type) 1381 { 1382 struct region region; 1383 1384 if (!frba) 1385 return 0; 1386 1387 region = get_region(frba, region_type); 1388 return !!((region.base < region.limit) && (region.size > 0)); 1389 } 1390 1391 /* 1392 * Platforms from CNL onwards support up to 16 flash regions, not 12. The 1393 * permissions for regions [15:12] are stored in extended region read/write 1394 * access fields in the FLMSTR registers. 1395 * 1396 * FLMSTR with extended regions: 1397 * 31:20 Region Write Access 1398 * 19:8 Region Read Access 1399 * 7:4 Extended Region Write Access 1400 * 3:0 Extended Region Read Access 1401 * 1402 * FLMSTR without extended regions: 1403 * 31:20 Region Write Access 1404 * 19:8 Region Read Access 1405 * 7:0 Reserved 1406 */ 1407 static bool platform_has_extended_regions(void) 1408 { 1409 switch (platform) { 1410 case PLATFORM_CNL: 1411 case PLATFORM_JSL: 1412 case PLATFORM_TGL: 1413 case PLATFORM_ADL: 1414 case PLATFORM_MTL: 1415 case PLATFORM_PTL: 1416 return true; 1417 default: 1418 return false; 1419 } 1420 } 1421 1422 static void lock_descriptor(const char *filename, char *image, int size) 1423 { 1424 int wr_shift, rd_shift; 1425 struct fmba *fmba = find_fmba(image, size); 1426 const struct frba *frba = find_frba(image, size); 1427 if (!fmba) 1428 exit(EXIT_FAILURE); 1429 1430 if (ifd_version >= IFD_VERSION_2) { 1431 wr_shift = FLMSTR_WR_SHIFT_V2; 1432 rd_shift = FLMSTR_RD_SHIFT_V2; 1433 1434 /* 1435 * Clear all read/write access bits. See comment on 1436 * platform_has_extended_regions() for bitfields. 1437 */ 1438 if (platform_has_extended_regions()) { 1439 fmba->flmstr1 = 0; 1440 fmba->flmstr2 = 0; 1441 fmba->flmstr3 = 0; 1442 fmba->flmstr5 = 0; 1443 } else { 1444 fmba->flmstr1 &= 0xff; 1445 fmba->flmstr2 &= 0xff; 1446 fmba->flmstr3 &= 0xff; 1447 fmba->flmstr5 &= 0xff; 1448 } 1449 } else { 1450 wr_shift = FLMSTR_WR_SHIFT_V1; 1451 rd_shift = FLMSTR_RD_SHIFT_V1; 1452 1453 fmba->flmstr1 = 0; 1454 fmba->flmstr2 = 0; 1455 /* Requestor ID */ 1456 fmba->flmstr3 = 0x118; 1457 } 1458 1459 switch (platform) { 1460 case PLATFORM_APL: 1461 case PLATFORM_GLK: 1462 /* CPU/BIOS can read descriptor and BIOS */ 1463 fmba->flmstr1 |= 0x3 << rd_shift; 1464 /* CPU/BIOS can write BIOS */ 1465 fmba->flmstr1 |= 0x2 << wr_shift; 1466 /* TXE can read descriptor, BIOS and Device Expansion */ 1467 fmba->flmstr2 |= 0x23 << rd_shift; 1468 /* TXE can only write Device Expansion */ 1469 fmba->flmstr2 |= 0x20 << wr_shift; 1470 break; 1471 case PLATFORM_CNL: 1472 case PLATFORM_ICL: 1473 case PLATFORM_SKLKBL: 1474 case PLATFORM_TGL: 1475 case PLATFORM_JSL: 1476 case PLATFORM_EHL: 1477 case PLATFORM_ADL: 1478 case PLATFORM_IFD2: 1479 case PLATFORM_MTL: 1480 case PLATFORM_PTL: 1481 /* CPU/BIOS can read descriptor and BIOS. */ 1482 fmba->flmstr1 |= (1 << REGION_DESC) << rd_shift; 1483 fmba->flmstr1 |= (1 << REGION_BIOS) << rd_shift; 1484 /* CPU/BIOS can write BIOS. */ 1485 fmba->flmstr1 |= (1 << REGION_BIOS) << wr_shift; 1486 /* ME can read descriptor and ME. */ 1487 fmba->flmstr2 |= (1 << REGION_DESC) << rd_shift; 1488 fmba->flmstr2 |= (1 << REGION_ME) << rd_shift; 1489 /* ME can write ME. */ 1490 fmba->flmstr2 |= (1 << REGION_ME) << wr_shift; 1491 if (check_region(frba, REGION_GBE)) { 1492 /* BIOS can read/write GbE. */ 1493 fmba->flmstr1 |= (1 << REGION_GBE) << rd_shift; 1494 fmba->flmstr1 |= (1 << REGION_GBE) << wr_shift; 1495 /* ME can read GbE. */ 1496 fmba->flmstr2 |= (1 << REGION_GBE) << rd_shift; 1497 /* GbE can read descriptor and read/write GbE.. */ 1498 fmba->flmstr3 |= (1 << REGION_DESC) << rd_shift; 1499 fmba->flmstr3 |= (1 << REGION_GBE) << rd_shift; 1500 fmba->flmstr3 |= (1 << REGION_GBE) << wr_shift; 1501 } 1502 if (check_region(frba, REGION_PDR)) { 1503 /* BIOS can read/write PDR. */ 1504 fmba->flmstr1 |= (1 << REGION_PDR) << rd_shift; 1505 fmba->flmstr1 |= (1 << REGION_PDR) << wr_shift; 1506 } 1507 if (check_region(frba, REGION_EC)) { 1508 /* BIOS can read EC. */ 1509 fmba->flmstr1 |= (1 << REGION_EC) << rd_shift; 1510 /* EC can read descriptor and read/write EC. */ 1511 fmba->flmstr5 |= (1 << REGION_DESC) << rd_shift; 1512 fmba->flmstr5 |= (1 << REGION_EC) << rd_shift; 1513 fmba->flmstr5 |= (1 << REGION_EC) << wr_shift; 1514 } 1515 if (check_region(frba, REGION_DEV_EXP2)) { 1516 /* BIOS can read SPI device expansion 2 region. */ 1517 fmba->flmstr1 |= (1 << REGION_DEV_EXP2) << rd_shift; 1518 } 1519 break; 1520 case PLATFORM_DNV: 1521 case PLATFORM_WBG: 1522 /* CPU/BIOS can read descriptor and BIOS. */ 1523 fmba->flmstr1 |= (1 << REGION_DESC) << rd_shift; 1524 fmba->flmstr1 |= (1 << REGION_BIOS) << rd_shift; 1525 /* CPU/BIOS can write BIOS. */ 1526 fmba->flmstr1 |= (1 << REGION_BIOS) << wr_shift; 1527 /* ME can read descriptor and ME. */ 1528 fmba->flmstr2 |= (1 << REGION_DESC) << rd_shift; 1529 fmba->flmstr2 |= (1 << REGION_ME) << rd_shift; 1530 /* ME can write ME. */ 1531 fmba->flmstr2 |= (1 << REGION_ME) << wr_shift; 1532 break; 1533 default: 1534 /* CPU/BIOS can read descriptor and BIOS. */ 1535 fmba->flmstr1 |= (1 << REGION_DESC) << rd_shift; 1536 fmba->flmstr1 |= (1 << REGION_BIOS) << rd_shift; 1537 /* CPU/BIOS can write BIOS. */ 1538 fmba->flmstr1 |= (1 << REGION_BIOS) << wr_shift; 1539 /* ME can read descriptor and ME. */ 1540 fmba->flmstr2 |= (1 << REGION_DESC) << rd_shift; 1541 fmba->flmstr2 |= (1 << REGION_ME) << rd_shift; 1542 /* ME can write ME. */ 1543 fmba->flmstr2 |= (1 << REGION_ME) << wr_shift; 1544 if (check_region(frba, REGION_GBE)) { 1545 /* BIOS can read GbE. */ 1546 fmba->flmstr1 |= (1 << REGION_GBE) << rd_shift; 1547 /* BIOS can write GbE. */ 1548 fmba->flmstr1 |= (1 << REGION_GBE) << wr_shift; 1549 /* ME can read GbE. */ 1550 fmba->flmstr2 |= (1 << REGION_GBE) << rd_shift; 1551 /* ME can write GbE. */ 1552 fmba->flmstr2 |= (1 << REGION_GBE) << wr_shift; 1553 /* GbE can write GbE. */ 1554 fmba->flmstr3 |= (1 << REGION_GBE) << rd_shift; 1555 /* GbE can read GbE. */ 1556 fmba->flmstr3 |= (1 << REGION_GBE) << wr_shift; 1557 } 1558 break; 1559 } 1560 1561 write_image(filename, image, size); 1562 } 1563 1564 static void enable_cpu_read_me(const char *filename, char *image, int size) 1565 { 1566 int rd_shift; 1567 struct fmba *fmba = find_fmba(image, size); 1568 1569 if (!fmba) 1570 exit(EXIT_FAILURE); 1571 1572 if (ifd_version >= IFD_VERSION_2) 1573 rd_shift = FLMSTR_RD_SHIFT_V2; 1574 else 1575 rd_shift = FLMSTR_RD_SHIFT_V1; 1576 1577 /* CPU/BIOS can read ME. */ 1578 fmba->flmstr1 |= (1 << REGION_ME) << rd_shift; 1579 1580 write_image(filename, image, size); 1581 } 1582 1583 static void unlock_descriptor(const char *filename, char *image, int size) 1584 { 1585 struct fmba *fmba = find_fmba(image, size); 1586 if (!fmba) 1587 exit(EXIT_FAILURE); 1588 1589 if (ifd_version >= IFD_VERSION_2) { 1590 /* 1591 * Set all read/write access bits. See comment on 1592 * platform_has_extended_regions() for bitfields. 1593 */ 1594 if (platform_has_extended_regions()) { 1595 fmba->flmstr1 = 0xffffffff; 1596 fmba->flmstr2 = 0xffffffff; 1597 fmba->flmstr3 = 0xffffffff; 1598 fmba->flmstr5 = 0xffffffff; 1599 } else { 1600 fmba->flmstr1 = 0xffffff00 | (fmba->flmstr1 & 0xff); 1601 fmba->flmstr2 = 0xffffff00 | (fmba->flmstr2 & 0xff); 1602 fmba->flmstr3 = 0xffffff00 | (fmba->flmstr3 & 0xff); 1603 fmba->flmstr5 = 0xffffff00 | (fmba->flmstr5 & 0xff); 1604 } 1605 } else { 1606 fmba->flmstr1 = 0xffff0000; 1607 fmba->flmstr2 = 0xffff0000; 1608 /* Keep chipset specific Requester ID */ 1609 fmba->flmstr3 = 0x08080000 | (fmba->flmstr3 & 0xffff); 1610 } 1611 1612 write_image(filename, image, size); 1613 } 1614 1615 static void print_gpr0_range(union gprd reg) 1616 { 1617 printf("--------- GPR0 Protected Range --------------\n"); 1618 printf("Start address = 0x%08x\n", reg.data.start << 12); 1619 printf("End address = 0x%08x\n", (reg.data.end << 12) | 0xfff); 1620 } 1621 1622 static uint8_t get_cse_data_partition_offset(void) 1623 { 1624 uint8_t data_offset = 0xff; 1625 1626 switch (platform) { 1627 case PLATFORM_CNL: 1628 case PLATFORM_JSL: 1629 data_offset = 0x10; 1630 break; 1631 case PLATFORM_TGL: 1632 case PLATFORM_ADL: 1633 case PLATFORM_MTL: 1634 case PLATFORM_PTL: 1635 data_offset = 0x18; 1636 break; 1637 default: 1638 break; 1639 } 1640 1641 return data_offset; 1642 } 1643 1644 static uint32_t get_gpr0_offset(void) 1645 { 1646 /* Offset expressed as number of 32-bit fields from FPSBA */ 1647 uint32_t gpr0_offset = 0xffffffff; 1648 1649 switch (platform) { 1650 case PLATFORM_CNL: 1651 gpr0_offset = 0x10; 1652 break; 1653 case PLATFORM_JSL: 1654 gpr0_offset = 0x12; 1655 break; 1656 case PLATFORM_TGL: 1657 case PLATFORM_ADL: 1658 gpr0_offset = 0x15; 1659 break; 1660 case PLATFORM_MTL: 1661 gpr0_offset = 0x40; 1662 break; 1663 case PLATFORM_PTL: 1664 gpr0_offset = 0x76; 1665 break; 1666 default: 1667 break; 1668 } 1669 1670 return gpr0_offset; 1671 } 1672 1673 static void disable_gpr0(const char *filename, char *image, int size) 1674 { 1675 struct fpsba *fpsba = find_fpsba(image, size); 1676 if (!fpsba) 1677 exit(EXIT_FAILURE); 1678 1679 uint32_t gpr0_offset = get_gpr0_offset(); 1680 if (gpr0_offset == 0xffffffff) { 1681 fprintf(stderr, "Disabling GPR0 not supported on this platform\n"); 1682 exit(EXIT_FAILURE); 1683 } 1684 1685 union gprd reg; 1686 /* If bit 31 is set then GPR0 protection is enable */ 1687 reg.value = fpsba->pchstrp[gpr0_offset]; 1688 if (!reg.data.write_protect_en) { 1689 printf("GPR0 protection is already disabled\n"); 1690 return; 1691 } 1692 1693 printf("Value at GPRD offset (%d) is 0x%08x\n", gpr0_offset, reg.value); 1694 print_gpr0_range(reg); 1695 /* 0 means GPR0 protection is disabled */ 1696 fpsba->pchstrp[gpr0_offset] = 0; 1697 write_image(filename, image, size); 1698 printf("GPR0 protection is now disabled\n"); 1699 } 1700 1701 /* 1702 * Helper function to parse the FPT to retrieve the FITC start offset and size. 1703 * FITC is a sub-partition table inside CSE data partition known as FPT. 1704 * 1705 * CSE Region 1706 * |-----> CSE Data Partition Offset 1707 * | |-------> FPT Entry 1708 * | | |-> Sub Partition 1 1709 * | | |-> Sub Partition 2 1710 * | | |-> FITC 1711 * | | | | -> FITC Offset 1712 * | | | | -> FITC Length 1713 */ 1714 static int parse_fitc_table(struct cse_fpt *fpt, uint32_t *offset, 1715 size_t *size) 1716 { 1717 size_t num_part_header = fpt->count; 1718 /* Move to the next structure which is FPT sub-partition entries */ 1719 struct cse_fpt_sub_part *fpt_sub_part = (struct cse_fpt_sub_part *)(fpt + 1); 1720 for (size_t index = 0; index < num_part_header; index++) { 1721 if (!strncmp(fpt_sub_part->signature, "FITC", 4)) { 1722 *offset = fpt_sub_part->offset; 1723 *size = fpt_sub_part->length; 1724 return 0; 1725 } 1726 fpt_sub_part++; 1727 } 1728 1729 return -1; 1730 } 1731 1732 /* 1733 * Formula to calculate the GPR0 protection range as below: 1734 * Start: CSE Region Base Offset 1735 * End: Till the end of FITC sub-partition 1736 */ 1737 static int calculate_gpr0_range(char *image, int size, 1738 uint32_t *gpr0_start, uint32_t *gpr0_end) 1739 { 1740 struct frba *frba = find_frba(image, size); 1741 if (!frba) 1742 return -1; 1743 1744 struct region region = get_region(frba, REGION_ME); 1745 if (region.size <= 0) { 1746 fprintf(stderr, "Region %s is disabled in target\n", 1747 region_name(REGION_ME)); 1748 return -1; 1749 } 1750 1751 /* CSE Region Start */ 1752 uint32_t cse_region_start = region.base; 1753 /* Get CSE Data Partition Offset */ 1754 uint8_t cse_data_offset = get_cse_data_partition_offset(); 1755 if (cse_data_offset == 0xff) { 1756 fprintf(stderr, "Unsupported platform\n"); 1757 exit(EXIT_FAILURE); 1758 } 1759 const uint32_t *data_part_offset_ptr = (uint32_t *)(image + cse_region_start + 1760 cse_data_offset); 1761 if (!PTR_IN_RANGE(data_part_offset_ptr, image, size)) { 1762 fprintf(stderr, "Data part offset %d exceeds image size %d\n", 1763 cse_region_start + cse_data_offset, size); 1764 return -1; 1765 } 1766 uint32_t data_part_offset = *data_part_offset_ptr; 1767 1768 /* Start reading the CSE Data Partition Table, also known as FPT */ 1769 uint32_t data_part_start = data_part_offset + cse_region_start; 1770 struct cse_fpt *fpt = (struct cse_fpt *)(image + data_part_start); 1771 if (!PTR_IN_RANGE(fpt, image, size)) { 1772 fprintf(stderr, "FPT offset %d exceeds image size %d\n", 1773 data_part_start, size); 1774 return -1; 1775 } 1776 1777 uint32_t fitc_region_start = 0; 1778 size_t fitc_region_size = 0; 1779 /* 1780 * FPT holds entry for own FPT data structure also bunch of sub-partitions. 1781 * `FITC` is one of such sub-partition entry. 1782 */ 1783 if (parse_fitc_table(fpt, &fitc_region_start, &fitc_region_size) < 0) { 1784 fprintf(stderr, "Unable to find FITC entry\n"); 1785 return -1; 1786 } 1787 1788 /* 1789 * GPR0 protection is configured to the following range: 1790 * start: CSE region base offset 1791 * end: Till the end of FITC sub-partition (i.e. CSE region + data partition offset + 1792 * FITC sub partition offset + FITC sub partition size) 1793 */ 1794 *gpr0_start = cse_region_start; 1795 *gpr0_end = (cse_region_start + data_part_offset + 1796 fitc_region_start + fitc_region_size) - 1; 1797 1798 return 0; 1799 } 1800 1801 static union gprd get_enabled_gprd(char *image, int size) 1802 { 1803 union gprd enabled_gprd_reg; 1804 uint32_t gpr0_range_start, gpr0_range_end; 1805 enabled_gprd_reg.value = 0; 1806 if (calculate_gpr0_range(image, size, &gpr0_range_start, &gpr0_range_end)) 1807 exit(EXIT_FAILURE); 1808 1809 enabled_gprd_reg.data.start = (gpr0_range_start >> 12) & 0x7fff; 1810 enabled_gprd_reg.data.end = (gpr0_range_end >> 12) & 0x7fff; 1811 enabled_gprd_reg.data.read_protect_en = 0; 1812 enabled_gprd_reg.data.write_protect_en = 1; 1813 1814 return enabled_gprd_reg; 1815 } 1816 1817 static void enable_gpr0(const char *filename, char *image, int size) 1818 { 1819 struct fpsba *fpsba = find_fpsba(image, size); 1820 if (!fpsba) 1821 exit(EXIT_FAILURE); 1822 1823 uint32_t gpr0_offset = get_gpr0_offset(); 1824 if (gpr0_offset == 0xffffffff) { 1825 fprintf(stderr, "Enabling GPR0 not supported on this platform\n"); 1826 exit(EXIT_FAILURE); 1827 } 1828 1829 union gprd reg; 1830 /* If bit 31 is set then GPR0 protection is enable */ 1831 reg.value = fpsba->pchstrp[gpr0_offset]; 1832 if (reg.data.write_protect_en) { 1833 printf("GPR0 protection is already enabled\n"); 1834 print_gpr0_range(reg); 1835 return; 1836 } 1837 1838 union gprd enabled_gprd = get_enabled_gprd(image, size); 1839 1840 fpsba->pchstrp[gpr0_offset] = enabled_gprd.value; 1841 printf("Value at GPRD offset (%d) is 0x%08x\n", gpr0_offset, enabled_gprd.value); 1842 print_gpr0_range(enabled_gprd); 1843 write_image(filename, image, size); 1844 printf("GPR0 protection is now enabled\n"); 1845 } 1846 1847 static void is_gpr0_protected(char *image, int size) 1848 { 1849 struct fpsba *fpsba = find_fpsba(image, size); 1850 if (!fpsba) 1851 exit(EXIT_FAILURE); 1852 1853 uint32_t gpr0_offset = get_gpr0_offset(); 1854 if (gpr0_offset == 0xffffffff) { 1855 fprintf(stderr, "Checking GPR0 not supported on this platform\n"); 1856 exit(EXIT_FAILURE); 1857 } 1858 union gprd reg; 1859 union gprd enabled_gprd = get_enabled_gprd(image, size); 1860 reg.value = fpsba->pchstrp[gpr0_offset]; 1861 1862 if (fpsba->pchstrp[gpr0_offset] == enabled_gprd.value) 1863 printf("GPR0 status: Enabled\n\n"); 1864 else if (fpsba->pchstrp[gpr0_offset] == 0) 1865 printf("GPR0 status: Disabled\n\n"); 1866 else 1867 printf("ERROR: GPR0 setting is not expected\n\n"); 1868 1869 printf("Value at GPRD offset (%d) is 0x%08x\n", gpr0_offset, fpsba->pchstrp[gpr0_offset]); 1870 print_gpr0_range(reg); 1871 } 1872 1873 static void set_pchstrap(struct fpsba *fpsba, const struct fdbar *fdb, const int strap, 1874 const unsigned int value) 1875 { 1876 if (!fpsba || !fdb) { 1877 fprintf(stderr, "Internal error\n"); 1878 exit(EXIT_FAILURE); 1879 } 1880 1881 /* SoC Strap, aka PSL, aka ISL */ 1882 int SS = (fdb->flmap1 >> 24) & 0xff; 1883 if (strap >= SS) { 1884 fprintf(stderr, "Strap index %d out of range (max: %d)\n", strap, SS); 1885 exit(EXIT_FAILURE); 1886 } 1887 fpsba->pchstrp[strap] = value; 1888 } 1889 1890 /* Set the AltMeDisable (or HAP for >= IFD_VERSION_2) */ 1891 static void fpsba_set_altmedisable(struct fpsba *fpsba, struct fmsba *fmsba, bool altmedisable) 1892 { 1893 if (ifd_version >= IFD_VERSION_2) { 1894 printf("%sting the HAP bit to %s Intel ME...\n", 1895 altmedisable ? "Set" : "Unset", 1896 altmedisable ? "disable" : "enable"); 1897 if (altmedisable) 1898 fpsba->pchstrp[0] |= (1 << 16); 1899 else 1900 fpsba->pchstrp[0] &= ~(1 << 16); 1901 } else { 1902 if (chipset >= CHIPSET_ICH8 && chipset <= CHIPSET_ICH10) { 1903 printf("%sting the ICH_MeDisable, MCH_MeDisable, " 1904 "and MCH_AltMeDisable to %s Intel ME...\n", 1905 altmedisable ? "Set" : "Unset", 1906 altmedisable ? "disable" : "enable"); 1907 if (altmedisable) { 1908 /* MCH_MeDisable */ 1909 fmsba->data[0] |= 1; 1910 /* MCH_AltMeDisable */ 1911 fmsba->data[0] |= (1 << 7); 1912 /* ICH_MeDisable */ 1913 fpsba->pchstrp[0] |= 1; 1914 } else { 1915 fmsba->data[0] &= ~1; 1916 fmsba->data[0] &= ~(1 << 7); 1917 fpsba->pchstrp[0] &= ~1; 1918 } 1919 } else { 1920 printf("%sting the AltMeDisable to %s Intel ME...\n", 1921 altmedisable ? "Set" : "Unset", 1922 altmedisable ? "disable" : "enable"); 1923 if (altmedisable) 1924 fpsba->pchstrp[10] |= (1 << 7); 1925 else 1926 fpsba->pchstrp[10] &= ~(1 << 7); 1927 } 1928 } 1929 } 1930 1931 static void inject_region(const char *filename, char *image, int size, 1932 unsigned int region_type, const char *region_fname) 1933 { 1934 struct frba *frba = find_frba(image, size); 1935 if (!frba) 1936 exit(EXIT_FAILURE); 1937 1938 struct region region = get_region(frba, region_type); 1939 if (region.size <= 0xfff) { 1940 fprintf(stderr, "Region %s is disabled in target. Not injecting.\n", 1941 region_name(region_type)); 1942 exit(EXIT_FAILURE); 1943 } 1944 1945 int region_fd = open(region_fname, O_RDONLY | O_BINARY); 1946 if (region_fd == -1) { 1947 perror("Could not open file"); 1948 exit(EXIT_FAILURE); 1949 } 1950 struct stat buf; 1951 if (fstat(region_fd, &buf) == -1) { 1952 perror("Could not stat file"); 1953 exit(EXIT_FAILURE); 1954 } 1955 int region_size = buf.st_size; 1956 1957 printf("File %s is %d bytes\n", region_fname, region_size); 1958 1959 if (region_size > region.size) { 1960 fprintf(stderr, "Region %s is %d(0x%x) bytes. File is %d(0x%x)" 1961 " bytes. Not injecting.\n", 1962 region_name(region_type), region.size, 1963 region.size, region_size, region_size); 1964 exit(EXIT_FAILURE); 1965 } 1966 1967 int offset = 0; 1968 if ((region_type == 1) && (region_size < region.size)) { 1969 fprintf(stderr, "Region %s is %d(0x%x) bytes. File is %d(0x%x)" 1970 " bytes. Padding before injecting.\n", 1971 region_name(region_type), region.size, 1972 region.size, region_size, region_size); 1973 offset = region.size - region_size; 1974 memset(image + region.base, 0xff, offset); 1975 } 1976 1977 if (size < region.base + offset + region_size) { 1978 fprintf(stderr, "Output file is too small. (%d < %d)\n", 1979 size, region.base + offset + region_size); 1980 exit(EXIT_FAILURE); 1981 } 1982 1983 if (read(region_fd, image + region.base + offset, region_size) != region_size) { 1984 perror("Could not read file"); 1985 exit(EXIT_FAILURE); 1986 } 1987 1988 close(region_fd); 1989 1990 printf("Adding %s as the %s section of %s\n", 1991 region_fname, region_name(region_type), filename); 1992 write_image(filename, image, size); 1993 } 1994 1995 static unsigned int next_pow2(unsigned int x) 1996 { 1997 unsigned int y = 1; 1998 if (x == 0) 1999 return 0; 2000 while (y <= x) 2001 y = y << 1; 2002 2003 return y; 2004 } 2005 2006 /** 2007 * Determine if two memory regions overlap. 2008 * 2009 * @param r1, r2 Memory regions to compare. 2010 * @return 0 if the two regions are separate 2011 * @return 1 if the two regions overlap 2012 */ 2013 static int regions_collide(const struct region *r1, const struct region *r2) 2014 { 2015 if ((r1->size == 0) || (r2->size == 0)) 2016 return 0; 2017 2018 /* r1 should be either completely below or completely above r2 */ 2019 return !(r1->limit < r2->base || r1->base > r2->limit); 2020 } 2021 2022 static void new_layout(const char *filename, char *image, int size, 2023 const char *layout_fname) 2024 { 2025 FILE *romlayout; 2026 char tempstr[256]; 2027 char layout_region_name[256]; 2028 unsigned int i, j; 2029 int region_number; 2030 struct region current_regions[MAX_REGIONS]; 2031 struct region new_regions[MAX_REGIONS]; 2032 int new_extent = 0; 2033 char *new_image; 2034 2035 /* load current descriptor map and regions */ 2036 struct frba *frba = find_frba(image, size); 2037 if (!frba) 2038 exit(EXIT_FAILURE); 2039 2040 for (i = 0; i < max_regions; i++) { 2041 current_regions[i] = get_region(frba, i); 2042 new_regions[i] = get_region(frba, i); 2043 } 2044 2045 /* read new layout */ 2046 romlayout = fopen(layout_fname, "r"); 2047 2048 if (!romlayout) { 2049 perror("Could not read layout file.\n"); 2050 exit(EXIT_FAILURE); 2051 } 2052 2053 while (!feof(romlayout)) { 2054 char *tstr1, *tstr2; 2055 2056 if (2 != fscanf(romlayout, "%255s %255s\n", tempstr, 2057 layout_region_name)) 2058 continue; 2059 2060 region_number = region_num(layout_region_name); 2061 if (region_number < 0) 2062 continue; 2063 2064 tstr1 = strtok(tempstr, ":"); 2065 tstr2 = strtok(NULL, ":"); 2066 if (!tstr1 || !tstr2) { 2067 fprintf(stderr, "Could not parse layout file.\n"); 2068 exit(EXIT_FAILURE); 2069 } 2070 new_regions[region_number].base = strtol(tstr1, 2071 (char **)NULL, 16); 2072 new_regions[region_number].limit = strtol(tstr2, 2073 (char **)NULL, 16); 2074 new_regions[region_number].size = 2075 new_regions[region_number].limit - 2076 new_regions[region_number].base + 1; 2077 2078 if (new_regions[region_number].size < 0) 2079 new_regions[region_number].size = 0; 2080 } 2081 fclose(romlayout); 2082 2083 /* check new layout */ 2084 for (i = 0; i < max_regions; i++) { 2085 if (new_regions[i].size == 0) 2086 continue; 2087 2088 if (new_regions[i].size < current_regions[i].size) { 2089 printf("DANGER: Region %s is shrinking.\n", 2090 region_name(i)); 2091 printf(" The region will be truncated to fit.\n"); 2092 printf(" This may result in an unusable image.\n"); 2093 } 2094 2095 for (j = i + 1; j < max_regions; j++) { 2096 if (regions_collide(&new_regions[i], &new_regions[j])) { 2097 fprintf(stderr, "Regions would overlap.\n"); 2098 exit(EXIT_FAILURE); 2099 } 2100 } 2101 2102 /* detect if the image size should grow */ 2103 if (new_extent < new_regions[i].limit) 2104 new_extent = new_regions[i].limit; 2105 } 2106 2107 /* check if the image is actually a Flash Descriptor region */ 2108 if (size == new_regions[0].size) { 2109 printf("The image is a single Flash Descriptor:\n"); 2110 printf(" Only the descriptor will be modified\n"); 2111 new_extent = size; 2112 } else { 2113 new_extent = next_pow2(new_extent - 1); 2114 if (new_extent != size) { 2115 printf("The image has changed in size.\n"); 2116 printf("The old image is %d bytes.\n", size); 2117 printf("The new image is %d bytes.\n", new_extent); 2118 } 2119 } 2120 2121 /* copy regions to a new image */ 2122 new_image = malloc(new_extent); 2123 memset(new_image, 0xff, new_extent); 2124 for (i = 0; i < max_regions; i++) { 2125 int copy_size = new_regions[i].size; 2126 int offset_current = 0, offset_new = 0; 2127 const struct region *current = ¤t_regions[i]; 2128 const struct region *new = &new_regions[i]; 2129 2130 if (new->size == 0) 2131 continue; 2132 2133 if (new->size > current->size) { 2134 /* copy from the end of the current region */ 2135 copy_size = current->size; 2136 if (i == REGION_BIOS) 2137 offset_new = new->size - current->size; 2138 } 2139 2140 if ((i == REGION_BIOS) && (new->size < current->size)) { 2141 /* copy BIOS region to the end of the new region */ 2142 offset_current = current->size - new->size; 2143 } 2144 2145 if (size < current->base + offset_current + copy_size) { 2146 printf("Skip descriptor %d (%s) (region missing in the old image)\n", i, 2147 region_name(i)); 2148 continue; 2149 }; 2150 2151 printf("Copy Descriptor %d (%s) (%d bytes)\n", i, 2152 region_name(i), copy_size); 2153 printf(" from %08x+%08x:%08x (%10d)\n", current->base, 2154 offset_current, current->limit, current->size); 2155 printf(" to %08x+%08x:%08x (%10d)\n", new->base, 2156 offset_new, new->limit, new->size); 2157 2158 memcpy(new_image + new->base + offset_new, 2159 image + current->base + offset_current, 2160 copy_size); 2161 } 2162 2163 /* update new descriptor regions */ 2164 frba = find_frba(new_image, new_extent); 2165 if (!frba) 2166 exit(EXIT_FAILURE); 2167 2168 printf("Modify Flash Descriptor regions\n"); 2169 for (i = 1; i < max_regions; i++) 2170 set_region(frba, i, &new_regions[i]); 2171 2172 write_image(filename, new_image, new_extent); 2173 free(new_image); 2174 } 2175 2176 static void print_version(void) 2177 { 2178 printf("ifdtool v%s -- ", IFDTOOL_VERSION); 2179 printf("Copyright (C) 2011 Google Inc.\n\n"); 2180 printf 2181 ("This program is free software: you can redistribute it and/or modify\n" 2182 "it under the terms of the GNU General Public License as published by\n" 2183 "the Free Software Foundation, version 2 of the License.\n\n" 2184 "This program is distributed in the hope that it will be useful,\n" 2185 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" 2186 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" 2187 "GNU General Public License for more details.\n\n"); 2188 } 2189 2190 static void print_usage(const char *name) 2191 { 2192 printf("usage: %s [-vhdix?] <filename>\n", name); 2193 printf("\n" 2194 " -d | --dump: dump intel firmware descriptor\n" 2195 " -f | --layout <filename> dump regions into a flashrom layout file\n" 2196 " -F | --fmap-layout <filename> dump IFD regions into a fmap layout template (.fmd) file\n" 2197 " -t | --validate Validate that the firmware descriptor layout matches the fmap layout\n" 2198 " -x | --extract: extract intel fd modules\n" 2199 " -i | --inject <region>:<module> inject file <module> into region <region>\n" 2200 " -n | --newlayout <filename> update regions using a flashrom layout file\n" 2201 " -O | --output <filename> output filename\n" 2202 " -s | --spifreq <17|20|30|33|48|50> set the SPI frequency\n" 2203 " -D | --density <512|1|2|4|8|16|32|64> set chip density (512 in KByte, others in MByte)\n" 2204 " -C | --chip <0|1|2> select spi chip on which to operate\n" 2205 " can only be used once per run:\n" 2206 " 0 - both chips (default), 1 - first chip, 2 - second chip\n" 2207 " -e | --em100 set SPI frequency to 20MHz and disable\n" 2208 " Dual Output Fast Read Support\n" 2209 " -l | --lock Lock firmware descriptor and ME region\n" 2210 " -r | --read Enable CPU/BIOS read access for ME region\n" 2211 " -u | --unlock Unlock firmware descriptor and ME region\n" 2212 " -g | --gpr0-disable Disable GPR0 (Global Protected Range) register\n" 2213 " -E | --gpr0-enable Enable GPR0 (Global Protected Range) register\n" 2214 " -c | --gpr0-status Checking GPR0 (Global Protected Range) register status\n" 2215 " -M | --altmedisable <0|1> Set the MeDisable and AltMeDisable (or HAP for skylake or newer platform)\n" 2216 " bits to disable ME\n" 2217 " -p | --platform Add platform-specific quirks\n" 2218 " adl - Alder Lake\n" 2219 " aplk - Apollo Lake\n" 2220 " cnl - Cannon Lake\n" 2221 " lbg - Lewisburg PCH\n" 2222 " dnv - Denverton\n" 2223 " ehl - Elkhart Lake\n" 2224 " glk - Gemini Lake\n" 2225 " icl - Ice Lake\n" 2226 " ifd2 - IFDv2 Platform\n" 2227 " jsl - Jasper Lake\n" 2228 " mtl - Meteor Lake\n" 2229 " sklkbl - Sky Lake/Kaby Lake\n" 2230 " tgl - Tiger Lake\n" 2231 " wbg - Wellsburg\n" 2232 " -S | --setpchstrap Write a PCH strap\n" 2233 " -V | --newvalue The new value to write into PCH strap specified by -S\n" 2234 " -v | --version: print the version\n" 2235 " -h | --help: print this help\n\n" 2236 "<region> is one of Descriptor, BIOS, ME, GbE, Platform Data, Secondary BIOS, " 2237 "Device Exp1, EC, Device Exp2, IE, 10GbE_0, 10GbE_1, PTT\n" 2238 "\n"); 2239 } 2240 2241 int main(int argc, char *argv[]) 2242 { 2243 int opt, option_index = 0; 2244 int mode_dump = 0, mode_extract = 0, mode_inject = 0, mode_spifreq = 0; 2245 int mode_em100 = 0, mode_locked = 0, mode_unlocked = 0, mode_validate = 0; 2246 int mode_layout = 0, mode_newlayout = 0, mode_density = 0, mode_setstrap = 0; 2247 int mode_read = 0, mode_altmedisable = 0, altmedisable = 0, mode_fmap_template = 0; 2248 int mode_gpr0_disable = 0, mode_gpr0_enable = 0, mode_gpr0_status = 0; 2249 char *region_type_string = NULL, *region_fname = NULL, *layout_fname = NULL; 2250 char *new_filename = NULL; 2251 int region_type = -1, inputfreq = 0; 2252 unsigned int value = 0; 2253 unsigned int pchstrap = 0; 2254 unsigned int new_density = 0; 2255 enum spi_frequency spifreq = SPI_FREQUENCY_20MHZ; 2256 2257 static const struct option long_options[] = { 2258 {"dump", 0, NULL, 'd'}, 2259 {"layout", 1, NULL, 'f'}, 2260 {"fmap-template", 1, NULL, 'F'}, 2261 {"extract", 0, NULL, 'x'}, 2262 {"inject", 1, NULL, 'i'}, 2263 {"newlayout", 1, NULL, 'n'}, 2264 {"output", 1, NULL, 'O'}, 2265 {"spifreq", 1, NULL, 's'}, 2266 {"density", 1, NULL, 'D'}, 2267 {"chip", 1, NULL, 'C'}, 2268 {"altmedisable", 1, NULL, 'M'}, 2269 {"em100", 0, NULL, 'e'}, 2270 {"lock", 0, NULL, 'l'}, 2271 {"read", 0, NULL, 'r'}, 2272 {"unlock", 0, NULL, 'u'}, 2273 {"gpr0-disable", 0, NULL, 'g'}, 2274 {"gpr0-enable", 0, NULL, 'E'}, 2275 {"gpr0-status", 0, NULL, 'c'}, 2276 {"version", 0, NULL, 'v'}, 2277 {"help", 0, NULL, 'h'}, 2278 {"platform", 1, NULL, 'p'}, 2279 {"validate", 0, NULL, 't'}, 2280 {"setpchstrap", 1, NULL, 'S'}, 2281 {"newvalue", 1, NULL, 'V'}, 2282 {0, 0, 0, 0} 2283 }; 2284 2285 while ((opt = getopt_long(argc, argv, "S:V:df:F:D:C:M:xi:n:O:s:p:elrugEcvth?", 2286 long_options, &option_index)) != EOF) { 2287 switch (opt) { 2288 case 'd': 2289 mode_dump = 1; 2290 break; 2291 case 'S': 2292 mode_setstrap = 1; 2293 pchstrap = strtoul(optarg, NULL, 0); 2294 break; 2295 case 'V': 2296 value = strtoul(optarg, NULL, 0); 2297 break; 2298 case 'f': 2299 mode_layout = 1; 2300 layout_fname = strdup(optarg); 2301 if (!layout_fname) { 2302 fprintf(stderr, "No layout file specified\n"); 2303 fprintf(stderr, "run '%s -h' for usage\n", argv[0]); 2304 exit(EXIT_FAILURE); 2305 } 2306 break; 2307 case 'F': 2308 mode_fmap_template = 1; 2309 layout_fname = strdup(optarg); 2310 if (!layout_fname) { 2311 fprintf(stderr, "No layout file specified\n"); 2312 fprintf(stderr, "run '%s -h' for usage\n", argv[0]); 2313 exit(EXIT_FAILURE); 2314 } 2315 break; 2316 case 'x': 2317 mode_extract = 1; 2318 break; 2319 case 'i': 2320 // separate type and file name 2321 region_type_string = strdup(optarg); 2322 region_fname = strchr(region_type_string, ':'); 2323 if (!region_fname) { 2324 fprintf(stderr, "run '%s -h' for usage\n", argv[0]); 2325 exit(EXIT_FAILURE); 2326 } 2327 region_fname[0] = '\0'; 2328 region_fname++; 2329 // Descriptor, BIOS, ME, GbE, Platform 2330 // valid type? 2331 if (!strcasecmp("Descriptor", region_type_string)) 2332 region_type = 0; 2333 else if (!strcasecmp("BIOS", region_type_string)) 2334 region_type = 1; 2335 else if (!strcasecmp("ME", region_type_string)) 2336 region_type = 2; 2337 else if (!strcasecmp("GbE", region_type_string)) 2338 region_type = 3; 2339 else if (!strcasecmp("Platform Data", region_type_string)) 2340 region_type = 4; 2341 else if (!strcasecmp("Device Exp1", region_type_string)) 2342 region_type = 5; 2343 else if (!strcasecmp("Secondary BIOS", region_type_string)) 2344 region_type = 6; 2345 else if (!strcasecmp("Reserved", region_type_string)) 2346 region_type = 7; 2347 else if (!strcasecmp("EC", region_type_string)) 2348 region_type = 8; 2349 else if (!strcasecmp("Device Exp2", region_type_string)) 2350 region_type = 9; 2351 else if (!strcasecmp("IE", region_type_string)) 2352 region_type = 10; 2353 else if (!strcasecmp("10GbE_0", region_type_string)) 2354 region_type = 11; 2355 else if (!strcasecmp("10GbE_1", region_type_string)) 2356 region_type = 12; 2357 else if (!strcasecmp("PTT", region_type_string)) 2358 region_type = 15; 2359 if (region_type == -1) { 2360 fprintf(stderr, "No such region type: '%s'\n\n", 2361 region_type_string); 2362 fprintf(stderr, "run '%s -h' for usage\n", argv[0]); 2363 exit(EXIT_FAILURE); 2364 } 2365 mode_inject = 1; 2366 break; 2367 case 'n': 2368 mode_newlayout = 1; 2369 layout_fname = strdup(optarg); 2370 if (!layout_fname) { 2371 fprintf(stderr, "No layout file specified\n"); 2372 fprintf(stderr, "run '%s -h' for usage\n", argv[0]); 2373 exit(EXIT_FAILURE); 2374 } 2375 break; 2376 case 'O': 2377 new_filename = strdup(optarg); 2378 if (!new_filename) { 2379 fprintf(stderr, "No output filename specified\n"); 2380 fprintf(stderr, "run '%s -h' for usage\n", argv[0]); 2381 exit(EXIT_FAILURE); 2382 } 2383 break; 2384 case 'D': 2385 mode_density = 1; 2386 new_density = strtoul(optarg, NULL, 0); 2387 switch (new_density) { 2388 case 512: 2389 new_density = COMPONENT_DENSITY_512KB; 2390 break; 2391 case 1: 2392 new_density = COMPONENT_DENSITY_1MB; 2393 break; 2394 case 2: 2395 new_density = COMPONENT_DENSITY_2MB; 2396 break; 2397 case 4: 2398 new_density = COMPONENT_DENSITY_4MB; 2399 break; 2400 case 8: 2401 new_density = COMPONENT_DENSITY_8MB; 2402 break; 2403 case 16: 2404 new_density = COMPONENT_DENSITY_16MB; 2405 break; 2406 case 32: 2407 new_density = COMPONENT_DENSITY_32MB; 2408 break; 2409 case 64: 2410 new_density = COMPONENT_DENSITY_64MB; 2411 break; 2412 case 0: 2413 new_density = COMPONENT_DENSITY_UNUSED; 2414 break; 2415 default: 2416 printf("error: Unknown density\n"); 2417 fprintf(stderr, "run '%s -h' for usage\n", argv[0]); 2418 exit(EXIT_FAILURE); 2419 } 2420 break; 2421 case 'C': 2422 selected_chip = strtol(optarg, NULL, 0); 2423 if (selected_chip > 2) { 2424 fprintf(stderr, "error: Invalid chip selection\n"); 2425 fprintf(stderr, "run '%s -h' for usage\n", argv[0]); 2426 exit(EXIT_FAILURE); 2427 } 2428 break; 2429 case 'M': 2430 mode_altmedisable = 1; 2431 altmedisable = strtol(optarg, NULL, 0); 2432 if (altmedisable > 1) { 2433 fprintf(stderr, "error: Illegal value\n"); 2434 fprintf(stderr, "run '%s -h' for usage\n", argv[0]); 2435 exit(EXIT_FAILURE); 2436 } 2437 break; 2438 case 's': 2439 // Parse the requested SPI frequency 2440 inputfreq = strtol(optarg, NULL, 0); 2441 switch (inputfreq) { 2442 case 17: 2443 spifreq = SPI_FREQUENCY_17MHZ; 2444 break; 2445 case 20: 2446 spifreq = SPI_FREQUENCY_20MHZ; 2447 break; 2448 case 30: 2449 spifreq = SPI_FREQUENCY_50MHZ_30MHZ; 2450 break; 2451 case 33: 2452 spifreq = SPI_FREQUENCY_33MHZ; 2453 break; 2454 case 48: 2455 spifreq = SPI_FREQUENCY_48MHZ; 2456 break; 2457 case 50: 2458 spifreq = SPI_FREQUENCY_50MHZ_30MHZ; 2459 break; 2460 default: 2461 fprintf(stderr, "Invalid SPI Frequency: %d\n", 2462 inputfreq); 2463 fprintf(stderr, "run '%s -h' for usage\n", argv[0]); 2464 exit(EXIT_FAILURE); 2465 } 2466 mode_spifreq = 1; 2467 break; 2468 case 'e': 2469 mode_em100 = 1; 2470 break; 2471 case 'l': 2472 mode_locked = 1; 2473 if (mode_unlocked == 1) { 2474 fprintf(stderr, "Locking/Unlocking FD and ME are mutually exclusive\n"); 2475 exit(EXIT_FAILURE); 2476 } 2477 break; 2478 case 'r': 2479 mode_read = 1; 2480 break; 2481 case 'u': 2482 mode_unlocked = 1; 2483 if (mode_locked == 1) { 2484 fprintf(stderr, "Locking/Unlocking FD and ME are mutually exclusive\n"); 2485 exit(EXIT_FAILURE); 2486 } 2487 break; 2488 case 'g': 2489 mode_gpr0_disable = 1; 2490 break; 2491 case 'E': 2492 mode_gpr0_enable = 1; 2493 break; 2494 case 'c': 2495 mode_gpr0_status = 1; 2496 break; 2497 case 'p': 2498 if (!strcmp(optarg, "aplk")) { 2499 platform = PLATFORM_APL; 2500 } else if (!strcmp(optarg, "cnl")) { 2501 platform = PLATFORM_CNL; 2502 } else if (!strcmp(optarg, "lbg")) { 2503 platform = PLATFORM_LBG; 2504 } else if (!strcmp(optarg, "dnv")) { 2505 platform = PLATFORM_DNV; 2506 } else if (!strcmp(optarg, "ehl")) { 2507 platform = PLATFORM_EHL; 2508 } else if (!strcmp(optarg, "glk")) { 2509 platform = PLATFORM_GLK; 2510 } else if (!strcmp(optarg, "icl")) { 2511 platform = PLATFORM_ICL; 2512 } else if (!strcmp(optarg, "jsl")) { 2513 platform = PLATFORM_JSL; 2514 } else if (!strcmp(optarg, "sklkbl")) { 2515 platform = PLATFORM_SKLKBL; 2516 } else if (!strcmp(optarg, "tgl")) { 2517 platform = PLATFORM_TGL; 2518 } else if (!strcmp(optarg, "adl")) { 2519 platform = PLATFORM_ADL; 2520 } else if (!strcmp(optarg, "ifd2")) { 2521 platform = PLATFORM_IFD2; 2522 } else if (!strcmp(optarg, "mtl")) { 2523 platform = PLATFORM_MTL; 2524 } else if (!strcmp(optarg, "ptl")) { 2525 platform = PLATFORM_PTL; 2526 } else if (!strcmp(optarg, "wbg")) { 2527 platform = PLATFORM_WBG; 2528 } else { 2529 fprintf(stderr, "Unknown platform: %s\n", optarg); 2530 exit(EXIT_FAILURE); 2531 } 2532 break; 2533 case 't': 2534 mode_validate = 1; 2535 break; 2536 case 'v': 2537 print_version(); 2538 exit(EXIT_SUCCESS); 2539 break; 2540 case 'h': 2541 case '?': 2542 print_usage(argv[0]); 2543 exit(EXIT_SUCCESS); 2544 break; 2545 default: 2546 print_usage(argv[0]); 2547 exit(EXIT_FAILURE); 2548 break; 2549 } 2550 } 2551 2552 if ((mode_dump + mode_layout + mode_fmap_template + mode_extract + mode_inject + 2553 mode_setstrap + mode_newlayout + (mode_spifreq | mode_em100 | 2554 mode_unlocked | mode_locked) + mode_altmedisable + mode_validate + 2555 (mode_gpr0_disable | mode_gpr0_enable) + mode_gpr0_status) > 1) { 2556 fprintf(stderr, "You may not specify more than one mode.\n\n"); 2557 fprintf(stderr, "run '%s -h' for usage\n", argv[0]); 2558 exit(EXIT_FAILURE); 2559 } 2560 2561 if ((mode_dump + mode_layout + mode_fmap_template + mode_extract + mode_inject + 2562 mode_setstrap + mode_newlayout + mode_spifreq + mode_em100 + 2563 mode_locked + mode_unlocked + mode_density + mode_altmedisable + 2564 mode_validate + (mode_gpr0_disable | mode_gpr0_enable) + mode_gpr0_status) == 0) { 2565 fprintf(stderr, "You need to specify a mode.\n\n"); 2566 fprintf(stderr, "run '%s -h' for usage\n", argv[0]); 2567 exit(EXIT_FAILURE); 2568 } 2569 2570 if (optind + 1 != argc) { 2571 fprintf(stderr, "You need to specify a file.\n\n"); 2572 fprintf(stderr, "run '%s -h' for usage\n", argv[0]); 2573 exit(EXIT_FAILURE); 2574 } 2575 2576 if (platform == -1) 2577 fprintf(stderr, "Warning: No platform specified. Output may be incomplete\n"); 2578 2579 char *filename = argv[optind]; 2580 int bios_fd = open(filename, O_RDONLY | O_BINARY); 2581 if (bios_fd == -1) { 2582 perror("Could not open file"); 2583 exit(EXIT_FAILURE); 2584 } 2585 struct stat buf; 2586 if (fstat(bios_fd, &buf) == -1) { 2587 perror("Could not stat file"); 2588 exit(EXIT_FAILURE); 2589 } 2590 int size = buf.st_size; 2591 2592 printf("File %s is %d bytes\n", filename, size); 2593 2594 char *image = malloc(size); 2595 if (!image) { 2596 printf("Out of memory.\n"); 2597 exit(EXIT_FAILURE); 2598 } 2599 2600 if (read(bios_fd, image, size) != size) { 2601 perror("Could not read file"); 2602 exit(EXIT_FAILURE); 2603 } 2604 2605 close(bios_fd); 2606 2607 // generate new filename 2608 if (new_filename == NULL) { 2609 new_filename = (char *)malloc((strlen(filename) + 5) * sizeof(char)); 2610 if (!new_filename) { 2611 printf("Out of memory.\n"); 2612 exit(EXIT_FAILURE); 2613 } 2614 // - 5: leave room for ".new\0" 2615 strcpy(new_filename, filename); 2616 strcat(new_filename, ".new"); 2617 } 2618 2619 check_ifd_version(image, size); 2620 2621 if (mode_dump) 2622 dump_fd(image, size); 2623 2624 if (mode_layout) 2625 dump_flashrom_layout(image, size, layout_fname); 2626 2627 if (mode_fmap_template) 2628 create_fmap_template(image, size, layout_fname); 2629 2630 if (mode_extract) 2631 write_regions(image, size); 2632 2633 if (mode_validate) 2634 validate_layout(image, size); 2635 2636 if (mode_inject) 2637 inject_region(new_filename, image, size, region_type, 2638 region_fname); 2639 2640 if (mode_newlayout) 2641 new_layout(new_filename, image, size, layout_fname); 2642 2643 if (mode_spifreq) 2644 set_spi_frequency(new_filename, image, size, spifreq); 2645 2646 if (mode_density) 2647 set_chipdensity(new_filename, image, size, new_density); 2648 2649 if (mode_em100) 2650 set_em100_mode(new_filename, image, size); 2651 2652 if (mode_locked) 2653 lock_descriptor(new_filename, image, size); 2654 2655 if (mode_read) 2656 enable_cpu_read_me(new_filename, image, size); 2657 2658 if (mode_unlocked) 2659 unlock_descriptor(new_filename, image, size); 2660 2661 if (mode_gpr0_disable) 2662 disable_gpr0(new_filename, image, size); 2663 2664 if (mode_gpr0_enable) 2665 enable_gpr0(new_filename, image, size); 2666 2667 if (mode_gpr0_status) 2668 is_gpr0_protected(image, size); 2669 2670 if (mode_setstrap) { 2671 struct fpsba *fpsba = find_fpsba(image, size); 2672 const struct fdbar *fdb = find_fd(image, size); 2673 set_pchstrap(fpsba, fdb, pchstrap, value); 2674 write_image(new_filename, image, size); 2675 } 2676 2677 if (mode_altmedisable) { 2678 struct fpsba *fpsba = find_fpsba(image, size); 2679 struct fmsba *fmsba = find_fmsba(image, size); 2680 fpsba_set_altmedisable(fpsba, fmsba, altmedisable); 2681 write_image(new_filename, image, size); 2682 } 2683 2684 free(region_type_string); 2685 free(layout_fname); 2686 free(new_filename); 2687 free(image); 2688 2689 return 0; 2690 }