1 /* ifdtool - dump Intel Firmware Descriptor information */
2 /* SPDX-License-Identifier: GPL-2.0-only */
10 #include <sys/types.h>
12 #include <commonlib/helpers.h>
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.
27 #define PTR_IN_RANGE(ptr, base, limit) \
28 ((const char *)(ptr) >= (base) && \
29 (const char *)&(ptr)[1] <= (base) + (limit))
32 * PLATFORM_HAS_GBE_REGION - some platforms do not support the PCH GbE LAN region
34 #define PLATFORM_HAS_GBE_REGION (platform != PLATFORM_DNV)
37 * PLATFORM_HAS_EC_REGION - some platforms do not support the EC region
39 #define PLATFORM_HAS_EC_REGION (ifd_version >= IFD_VERSION_2 && platform != PLATFORM_DNV)
42 * PLATFORM_HAS_10GBE_X_REGION - some platforms have 1 or more 10GbE LAN regions
44 #define PLATFORM_HAS_10GBE_0_REGION (platform == PLATFORM_DNV)
45 #define PLATFORM_HAS_10GBE_1_REGION (platform == PLATFORM_DNV)
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.
56 /* Specifies read protection is enabled */
57 uint32_t read_protect_en
: 1;
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.
66 /* Specifies write protection is enabled */
67 uint32_t write_protect_en
: 1;
73 static int max_regions_from_fdbar(const struct fdbar
*fdb
);
75 static int ifd_version
;
77 static unsigned int max_regions
= 0;
78 static int selected_chip
= 0;
79 static int platform
= -1;
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" },
100 /* port from flashrom */
101 static const char *const ich_chipset_names
[] = {
107 "5 series Ibex Peak",
108 "6 series Cougar Point",
109 "7 series Panther Point",
110 "8 series Lynx Point",
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",
130 static struct fdbar
*find_fd(char *image
, int size
)
134 /* Scan for FD signature */
135 for (i
= 0; i
< (size
- 4); i
+= 4) {
136 if (*(uint32_t *)(image
+ i
) == 0x0FF0A55A) {
138 break; // signature found.
143 printf("No Flash Descriptor found in this image\n");
147 struct fdbar
*fdb
= (struct fdbar
*)(image
+ i
);
148 return PTR_IN_RANGE(fdb
, image
, size
) ? fdb
: NULL
;
151 static char *find_flumap(char *image
, int size
)
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
162 char *flumap
= image
+ 4096 - 256 - 4;
163 return PTR_IN_RANGE(flumap
, image
, size
) ? flumap
: NULL
;
166 static struct fcba
*find_fcba(char *image
, int size
)
168 struct fdbar
*fdb
= find_fd(image
, size
);
171 struct fcba
*fcba
= (struct fcba
*)(image
+ ((fdb
->flmap0
& 0xff) << 4));
172 return PTR_IN_RANGE(fcba
, image
, size
) ? fcba
: NULL
;
175 static struct fmba
*find_fmba(char *image
, int size
)
177 struct fdbar
*fdb
= find_fd(image
, size
);
180 struct fmba
*fmba
= (struct fmba
*)(image
+ ((fdb
->flmap1
& 0xff) << 4));
181 return PTR_IN_RANGE(fmba
, image
, size
) ? fmba
: NULL
;
184 static struct frba
*find_frba(char *image
, int size
)
186 struct fdbar
*fdb
= find_fd(image
, size
);
190 (struct frba
*) (image
+ (((fdb
->flmap0
>> 16) & 0xff) << 4));
191 return PTR_IN_RANGE(frba
, image
, size
) ? frba
: NULL
;
194 static struct fpsba
*find_fpsba(char *image
, int size
)
196 struct fdbar
*fdb
= find_fd(image
, size
);
199 struct fpsba
*fpsba
=
200 (struct fpsba
*) (image
+ (((fdb
->flmap1
>> 16) & 0xff) << 4));
202 int SSL
= ((fdb
->flmap1
>> 24) & 0xff) * sizeof(uint32_t);
203 if ((((char *)fpsba
) + SSL
) >= (image
+ size
))
208 static struct fmsba
*find_fmsba(char *image
, int size
)
210 struct fdbar
*fdb
= find_fd(image
, size
);
213 struct fmsba
*fmsba
= (struct fmsba
*)(image
+ ((fdb
->flmap2
& 0xff) << 4));
214 return PTR_IN_RANGE(fmsba
, image
, size
) ? fmsba
: NULL
;
217 /* port from flashrom */
218 static enum ich_chipset
ifd1_guess_chipset(char *image
, int size
)
220 const struct fdbar
*fdb
= find_fd(image
, size
);
223 uint32_t iccriba
= (fdb
->flmap2
>> 16) & 0xff;
224 uint32_t msl
= (fdb
->flmap2
>> 8) & 0xff;
225 uint32_t isl
= (fdb
->flmap1
>> 24);
227 /* Rest for IFD1 chipset type */
228 if (iccriba
== 0x00) {
229 if (msl
== 0 && isl
<= 2)
234 return CHIPSET_ICH10
;
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
;
249 return CHIPSET_PCH_UNKNOWN
;
252 static enum ich_chipset
ifd2_platform_to_chipset(const int pindex
)
256 return CHIPSET_N_J_SERIES_APOLLO_LAKE
;
258 return CHIPSET_N_J_SERIES_GEMINI_LAKE
;
260 return CHIPSET_N_SERIES_JASPER_LAKE
;
262 return CHIPSET_x6000_SERIES_ELKHART_LAKE
;
263 case PLATFORM_SKLKBL
:
264 return CHIPSET_100_200_SERIES_SUNRISE_POINT
;
266 return CHIPSET_300_SERIES_CANNON_POINT
;
270 return CHIPSET_500_600_SERIES_TIGER_ALDER_POINT
;
272 return CHIPSET_800_SERIES_METEOR_LAKE
;
274 return CHIPSET_900_SERIES_PANTHER_LAKE
;
276 return CHIPSET_400_SERIES_ICE_POINT
;
278 return CHIPSET_C620_SERIES_LEWISBURG
;
280 return CHIPSET_DENVERTON
;
282 return CHIPSET_8_SERIES_WELLSBURG
;
284 return CHIPSET_PCH_UNKNOWN
;
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.
294 static int is_platform_ifd_2(void)
296 static const int ifd_2_platforms
[] = {
315 for (i
= 0; i
< ARRAY_SIZE(ifd_2_platforms
); i
++) {
316 if (platform
== ifd_2_platforms
[i
])
323 static void check_ifd_version(char *image
, int size
)
325 const struct fdbar
*fdb
= find_fd(image
, size
);
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
;
332 ifd_version
= IFD_VERSION_2
;
333 max_regions
= MIN(max_regions_from_fdbar(fdb
), MAX_REGIONS
);
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
);
341 static struct region
get_region(const struct frba
*frba
, unsigned int region_type
)
346 struct region region
;
348 if (ifd_version
>= IFD_VERSION_2
)
353 limit_mask
= base_mask
<< 16;
355 if (region_type
>= max_regions
) {
356 fprintf(stderr
, "Invalid region type %d.\n", region_type
);
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
;
372 static void set_region(struct frba
*frba
, unsigned int region_type
,
373 const struct region
*region
)
375 if (region_type
>= max_regions
) {
376 fprintf(stderr
, "Invalid region type %u.\n", region_type
);
380 frba
->flreg
[region_type
] =
381 (((region
->limit
>> 12) & 0x7fff) << 16) |
382 ((region
->base
>> 12) & 0x7fff);
385 static const char *region_name(unsigned int region_type
)
387 if (region_type
>= max_regions
) {
388 fprintf(stderr
, "Invalid region type.\n");
392 return region_names
[region_type
].pretty
;
395 static int region_num(const char *name
)
399 for (i
= 0; i
< max_regions
; i
++) {
400 if (strcasecmp(name
, region_names
[i
].pretty
) == 0)
402 if (strcasecmp(name
, region_names
[i
].terse
) == 0)
409 static void dump_region(unsigned int num
, const struct frba
*frba
)
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)" : "");
417 static int sort_compare(const void *a
, const void *b
)
419 return *(size_t *)a
- *(size_t *)b
;
423 * IFDv1 always has 8 regions, while IFDv2 always has 16 regions.
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.
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
436 static int max_regions_from_fdbar(const struct fdbar
*fdb
)
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
};
445 qsort(sorted
, ARRAY_SIZE(sorted
), sizeof(size_t), sort_compare
);
447 for (size_t i
= 0; i
< 4; i
++) {
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
453 if (sorted
[i
] == frba
)
454 return MIN((sorted
[i
+ 1] - sorted
[i
]) / 4, MAX_REGIONS
);
456 /* Never reaches this point */
460 static void dump_frba(const struct frba
*frba
)
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"))
471 printf("FLREG%u: 0x%08x\n", i
, frba
->flreg
[i
]);
472 dump_region(i
, frba
);
476 static void dump_flashrom_layout(char *image
, int size
, const char *layout_fname
)
478 const struct frba
*frba
= find_frba(image
, size
);
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");
488 for (unsigned int i
= 0; i
< max_regions
; i
++) {
489 struct region region
= get_region(frba
, i
);
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
494 if (region
.limit
== 0 || region
.base
== 0x07FFF000)
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");
505 printf("Wrote layout to %s\n", layout_fname
);
508 static void _decode_spi_frequency(unsigned int freq
)
511 case SPI_FREQUENCY_20MHZ
:
514 case SPI_FREQUENCY_33MHZ
:
517 case SPI_FREQUENCY_48MHZ
:
520 case SPI_FREQUENCY_50MHZ_30MHZ
:
521 switch (ifd_version
) {
523 case IFD_VERSION_1_5
:
531 case SPI_FREQUENCY_17MHZ
:
535 printf("unknown<%x>MHz", freq
);
539 static void _decode_spi_frequency_500_series(unsigned int freq
)
542 case SPI_FREQUENCY_100MHZ
:
545 case SPI_FREQUENCY_50MHZ
:
548 case SPI_FREQUENCY_500SERIES_33MHZ
:
551 case SPI_FREQUENCY_25MHZ
:
554 case SPI_FREQUENCY_14MHZ
:
558 printf("unknown<%x>MHz", freq
);
562 static void decode_spi_frequency(unsigned int freq
)
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
);
571 _decode_spi_frequency(freq
);
575 static void _decode_espi_frequency(unsigned int freq
)
578 case ESPI_FREQUENCY_20MHZ
:
581 case ESPI_FREQUENCY_24MHZ
:
584 case ESPI_FREQUENCY_30MHZ
:
587 case ESPI_FREQUENCY_48MHZ
:
590 case ESPI_FREQUENCY_60MHZ
:
593 case ESPI_FREQUENCY_17MHZ
:
597 printf("unknown<%x>MHz", freq
);
601 static void _decode_espi_frequency_500_series(unsigned int freq
)
604 case ESPI_FREQUENCY_500SERIES_20MHZ
:
607 case ESPI_FREQUENCY_500SERIES_24MHZ
:
610 case ESPI_FREQUENCY_500SERIES_25MHZ
:
613 case ESPI_FREQUENCY_500SERIES_48MHZ
:
616 case ESPI_FREQUENCY_500SERIES_60MHZ
:
620 printf("unknown<%x>MHz", freq
);
624 static void _decode_espi_frequency_800_series(unsigned int freq
)
627 case ESPI_FREQUENCY_800SERIES_20MHZ
:
630 case ESPI_FREQUENCY_800SERIES_25MHZ
:
633 case ESPI_FREQUENCY_800SERIES_33MHZ
:
636 case ESPI_FREQUENCY_800SERIES_50MHZ
:
640 printf("unknown<%x>MHz", freq
);
644 static void decode_espi_frequency(unsigned int freq
)
647 case CHIPSET_500_600_SERIES_TIGER_ALDER_POINT
:
648 _decode_espi_frequency_500_series(freq
);
650 case CHIPSET_800_SERIES_METEOR_LAKE
:
651 case CHIPSET_900_SERIES_PANTHER_LAKE
:
652 _decode_espi_frequency_800_series(freq
);
655 _decode_espi_frequency(freq
);
659 static void decode_component_density(unsigned int density
)
662 case COMPONENT_DENSITY_512KB
:
665 case COMPONENT_DENSITY_1MB
:
668 case COMPONENT_DENSITY_2MB
:
671 case COMPONENT_DENSITY_4MB
:
674 case COMPONENT_DENSITY_8MB
:
677 case COMPONENT_DENSITY_16MB
:
680 case COMPONENT_DENSITY_32MB
:
683 case COMPONENT_DENSITY_64MB
:
686 case COMPONENT_DENSITY_UNUSED
:
690 printf("unknown<%x>MB", density
);
694 static int is_platform_with_pch(void)
696 if (chipset
>= CHIPSET_5_SERIES_IBEX_PEAK
)
702 /* FLMAP0 register bit 24 onwards are reserved from SPT PCH */
703 static int is_platform_with_100x_series_pch(void)
705 if (chipset
>= CHIPSET_100_200_SERIES_SUNRISE_POINT
&&
706 chipset
<= CHIPSET_900_SERIES_PANTHER_LAKE
)
712 static void dump_fcba(const struct fcba
*fcba
, const struct fpsba
*fpsba
)
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;
738 freq
= (fcba
->flcomp
>> 17) & 7;
739 decode_espi_frequency(freq
);
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");
750 printf("\n Read Clock Frequency: ");
751 decode_spi_frequency((fcba
->flcomp
>> 17) & 7);
754 switch (ifd_version
) {
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);
761 case IFD_VERSION_1_5
:
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);
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",
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",
791 printf("FLPB 0x%08x\n", fcba
->flpb
);
792 printf(" Flash Partition Boundary Address: 0x%06x\n\n",
793 (fcba
->flpb
& 0xfff) << 12);
797 static void dump_fpsba(const struct fdbar
*fdb
, const struct fpsba
*fpsba
)
800 /* SoC Straps, aka PSL, aka ISL */
801 unsigned int SS
= (fdb
->flmap1
>> 24) & 0xff;
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
]);
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 ");
814 printf("AltMeDisable bit is %sset\n",
815 fpsba
->pchstrp
[10] & (1 << 7) ? "" : "not ");
821 static void decode_flmstr(uint32_t flmstr
)
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
;
828 wr_shift
= FLMSTR_WR_SHIFT_V1
;
829 rd_shift
= FLMSTR_RD_SHIFT_V1
;
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");
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");
853 if (PLATFORM_HAS_10GBE_1_REGION
) {
854 printf(" 10GbE_1 Write Access: %s\n",
855 (flmstr
& (1 << 4)) ? "enabled" : "disabled");
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");
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");
878 if (PLATFORM_HAS_10GBE_1_REGION
) {
879 printf(" 10GbE_1 Read Access: %s\n",
880 (flmstr
& (1 << 0)) ? "enabled" : "disabled");
883 /* Requestor ID doesn't exist for ifd 2 */
884 if (ifd_version
< IFD_VERSION_2
)
885 printf(" Requester ID: 0x%04x\n\n",
889 static void dump_fmba(const struct fmba
*fmba
)
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
);
904 printf("FLMSTR6: 0x%08x (IE)\n", fmba
->flmstr6
);
905 decode_flmstr(fmba
->flmstr6
);
909 static void dump_fmsba(const struct fmsba
*fmsba
)
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
]);
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 ");
924 static void dump_jid(uint32_t jid
)
926 printf(" SPI Component Vendor ID: 0x%02x\n",
928 printf(" SPI Component Device ID 0: 0x%02x\n",
930 printf(" SPI Component Device ID 1: 0x%02x\n",
934 static void dump_vscc(uint32_t vscc
)
936 printf(" Lower Erase Opcode: 0x%02x\n",
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) {
947 printf("256 Byte\n");
960 printf(" Upper Erase Opcode: 0x%02x\n",
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) {
971 printf("256 Byte\n");
985 static void dump_vtba(const struct vtba
*vtba
, int vtl
)
988 int max_len
= sizeof(struct vtba
) / sizeof(struct vscc
);
989 int num
= (vtl
>> 1) < max_len
? (vtl
>> 1) : max_len
;
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
);
1001 static void dump_oem(const uint8_t *oem
)
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
]);
1014 static void dump_fd(char *image
, int size
)
1016 const struct fdbar
*fdb
= find_fd(image
, size
);
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);
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);
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);
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);
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);
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
);
1068 if (frba
&& fcba
&& fpsba
&& fmba
&& fmsba
) {
1070 dump_fcba(fcba
, fpsba
);
1071 dump_fpsba(fdb
, fpsba
);
1075 printf("FD is corrupted!\n");
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.
1085 static void create_fmap_template(char *image
, int size
, const char *layout_fname
)
1087 const struct frba
*frba
= find_frba(image
, size
);
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");
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");
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
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
);
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
1114 if (region
.limit
== 0 || region
.base
== 0x07FFF000)
1117 /* Is there an FMAP equivalent? IFD reserved regions are usually thrown out
1120 if (!region_names
[region
.type
].fmapname
) {
1121 printf("Skip IFD region: %s\n", region_names
[region
.type
].pretty
);
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
1130 if (i
== REGION_BIOS
)
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
;
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");
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"
1166 if (write(layout_fd
, ebuf
, strlen(ebuf
)) < 0) {
1167 perror("Could not write to file");
1172 printf("Wrote layout to %s\n", layout_fname
);
1175 static void write_regions(char *image
, int size
)
1178 const struct frba
*frba
= find_frba(image
, size
);
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) {
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");
1195 if (write(region_fd
, image
+ region
.base
, region
.size
) != region
.size
)
1196 perror("Error while writing");
1202 static void validate_layout(char *image
, int size
)
1206 long int fmap_loc
= fmap_find((uint8_t *)image
, size
);
1207 const struct frba
*frba
= find_frba(image
, size
);
1209 if (fmap_loc
< 0 || !frba
) {
1210 printf("Could not find FMAP (%p) or Intel Flash Descriptor (%p)\n",
1211 (void *)fmap_loc
, frba
);
1215 fmap
= (struct fmap
*)(image
+ fmap_loc
);
1218 for (i
= 0; i
< max_regions
; i
++) {
1219 struct region region
= get_region(frba
, i
);
1220 if (region
.size
== 0)
1223 const struct fmap_area
*area
= fmap_find_area(fmap
, region_names
[i
].fmapname
);
1227 matches
++; // found a match between FMAP and IFD region
1229 if ((uint
)region
.base
!= area
->offset
|| (uint
)region
.size
!= area
->size
) {
1230 printf("Region mismatch between %s and %s\n", region_names
[i
].terse
, area
->name
);
1231 printf(" Descriptor region %s:\n", region_names
[i
].terse
);
1232 printf(" offset: 0x%08x\n", region
.base
);
1233 printf(" length: 0x%08x\n", region
.size
);
1234 printf(" FMAP area %s:\n", area
->name
);
1235 printf(" offset: 0x%08x\n", area
->offset
);
1236 printf(" length: 0x%08x\n", area
->size
);
1242 // At least a BIOS region should be present in both IFD and FMAP
1243 fprintf(stderr
, "Warning: Not a single IFD region found in FMAP\n");
1250 static void write_image(const char *filename
, char *image
, int size
)
1253 printf("Writing new image to %s\n", filename
);
1255 // Now write out new image
1256 new_fd
= open(filename
, O_WRONLY
| O_CREAT
| O_TRUNC
| O_BINARY
, 0644);
1258 perror("Error while trying to open file");
1261 if (write(new_fd
, image
, size
) != size
)
1262 perror("Error while writing");
1266 static void set_spi_frequency(const char *filename
, char *image
, int size
,
1267 enum spi_frequency freq
)
1269 struct fcba
*fcba
= find_fcba(image
, size
);
1273 /* clear bits 21-29 */
1274 fcba
->flcomp
&= ~0x3fe00000;
1275 /* Read ID and Read Status Clock Frequency */
1276 fcba
->flcomp
|= freq
<< 27;
1277 /* Write and Erase Clock Frequency */
1278 fcba
->flcomp
|= freq
<< 24;
1279 /* Fast Read Clock Frequency */
1280 fcba
->flcomp
|= freq
<< 21;
1282 write_image(filename
, image
, size
);
1285 static void set_em100_mode(const char *filename
, char *image
, int size
)
1287 struct fcba
*fcba
= find_fcba(image
, size
);
1293 switch (ifd_version
) {
1295 case IFD_VERSION_1_5
:
1296 freq
= SPI_FREQUENCY_20MHZ
;
1299 freq
= SPI_FREQUENCY_17MHZ
;
1302 freq
= SPI_FREQUENCY_17MHZ
;
1306 fcba
->flcomp
&= ~(1 << 30);
1307 set_spi_frequency(filename
, image
, size
, freq
);
1310 static void set_chipdensity(const char *filename
, char *image
, int size
,
1311 unsigned int density
)
1313 struct fcba
*fcba
= find_fcba(image
, size
);
1314 uint8_t mask
, chip2_offset
;
1318 printf("Setting chip density to ");
1319 decode_component_density(density
);
1322 switch (ifd_version
) {
1324 /* fail if selected density is not supported by this version */
1325 if ( (density
== COMPONENT_DENSITY_32MB
) ||
1326 (density
== COMPONENT_DENSITY_64MB
) ||
1327 (density
== COMPONENT_DENSITY_UNUSED
) ) {
1328 printf("error: Selected density not supported in IFD version 1.\n");
1334 case IFD_VERSION_1_5
:
1340 printf("error: Unknown IFD version\n");
1345 /* clear chip density for corresponding chip */
1346 switch (selected_chip
) {
1348 fcba
->flcomp
&= ~mask
;
1351 fcba
->flcomp
&= ~(mask
<< chip2_offset
);
1353 default: /*both chips*/
1354 fcba
->flcomp
&= ~(mask
| (mask
<< chip2_offset
));
1358 /* set the new density */
1359 if (selected_chip
== 1 || selected_chip
== 0)
1360 fcba
->flcomp
|= (density
); /* first chip */
1361 if (selected_chip
== 2 || selected_chip
== 0)
1362 fcba
->flcomp
|= (density
<< chip2_offset
); /* second chip */
1364 write_image(filename
, image
, size
);
1367 static int check_region(const struct frba
*frba
, unsigned int region_type
)
1369 struct region region
;
1374 region
= get_region(frba
, region_type
);
1375 return !!((region
.base
< region
.limit
) && (region
.size
> 0));
1379 * Platforms from CNL onwards support up to 16 flash regions, not 12. The
1380 * permissions for regions [15:12] are stored in extended region read/write
1381 * access fields in the FLMSTR registers.
1383 * FLMSTR with extended regions:
1384 * 31:20 Region Write Access
1385 * 19:8 Region Read Access
1386 * 7:4 Extended Region Write Access
1387 * 3:0 Extended Region Read Access
1389 * FLMSTR without extended regions:
1390 * 31:20 Region Write Access
1391 * 19:8 Region Read Access
1394 static bool platform_has_extended_regions(void)
1409 static void lock_descriptor(const char *filename
, char *image
, int size
)
1411 int wr_shift
, rd_shift
;
1412 struct fmba
*fmba
= find_fmba(image
, size
);
1413 const struct frba
*frba
= find_frba(image
, size
);
1417 if (ifd_version
>= IFD_VERSION_2
) {
1418 wr_shift
= FLMSTR_WR_SHIFT_V2
;
1419 rd_shift
= FLMSTR_RD_SHIFT_V2
;
1422 * Clear all read/write access bits. See comment on
1423 * platform_has_extended_regions() for bitfields.
1425 if (platform_has_extended_regions()) {
1431 fmba
->flmstr1
&= 0xff;
1432 fmba
->flmstr2
&= 0xff;
1433 fmba
->flmstr3
&= 0xff;
1434 fmba
->flmstr5
&= 0xff;
1437 wr_shift
= FLMSTR_WR_SHIFT_V1
;
1438 rd_shift
= FLMSTR_RD_SHIFT_V1
;
1443 fmba
->flmstr3
= 0x118;
1449 /* CPU/BIOS can read descriptor and BIOS */
1450 fmba
->flmstr1
|= 0x3 << rd_shift
;
1451 /* CPU/BIOS can write BIOS */
1452 fmba
->flmstr1
|= 0x2 << wr_shift
;
1453 /* TXE can read descriptor, BIOS and Device Expansion */
1454 fmba
->flmstr2
|= 0x23 << rd_shift
;
1455 /* TXE can only write Device Expansion */
1456 fmba
->flmstr2
|= 0x20 << wr_shift
;
1460 case PLATFORM_SKLKBL
:
1468 /* CPU/BIOS can read descriptor and BIOS. */
1469 fmba
->flmstr1
|= (1 << REGION_DESC
) << rd_shift
;
1470 fmba
->flmstr1
|= (1 << REGION_BIOS
) << rd_shift
;
1471 /* CPU/BIOS can write BIOS. */
1472 fmba
->flmstr1
|= (1 << REGION_BIOS
) << wr_shift
;
1473 /* ME can read descriptor and ME. */
1474 fmba
->flmstr2
|= (1 << REGION_DESC
) << rd_shift
;
1475 fmba
->flmstr2
|= (1 << REGION_ME
) << rd_shift
;
1476 /* ME can write ME. */
1477 fmba
->flmstr2
|= (1 << REGION_ME
) << wr_shift
;
1478 if (check_region(frba
, REGION_GBE
)) {
1479 /* BIOS can read/write GbE. */
1480 fmba
->flmstr1
|= (1 << REGION_GBE
) << rd_shift
;
1481 fmba
->flmstr1
|= (1 << REGION_GBE
) << wr_shift
;
1482 /* ME can read GbE. */
1483 fmba
->flmstr2
|= (1 << REGION_GBE
) << rd_shift
;
1484 /* GbE can read descriptor and read/write GbE.. */
1485 fmba
->flmstr3
|= (1 << REGION_DESC
) << rd_shift
;
1486 fmba
->flmstr3
|= (1 << REGION_GBE
) << rd_shift
;
1487 fmba
->flmstr3
|= (1 << REGION_GBE
) << wr_shift
;
1489 if (check_region(frba
, REGION_PDR
)) {
1490 /* BIOS can read/write PDR. */
1491 fmba
->flmstr1
|= (1 << REGION_PDR
) << rd_shift
;
1492 fmba
->flmstr1
|= (1 << REGION_PDR
) << wr_shift
;
1494 if (check_region(frba
, REGION_EC
)) {
1495 /* BIOS can read EC. */
1496 fmba
->flmstr1
|= (1 << REGION_EC
) << rd_shift
;
1497 /* EC can read descriptor and read/write EC. */
1498 fmba
->flmstr5
|= (1 << REGION_DESC
) << rd_shift
;
1499 fmba
->flmstr5
|= (1 << REGION_EC
) << rd_shift
;
1500 fmba
->flmstr5
|= (1 << REGION_EC
) << wr_shift
;
1502 if (check_region(frba
, REGION_DEV_EXP2
)) {
1503 /* BIOS can read SPI device expansion 2 region. */
1504 fmba
->flmstr1
|= (1 << REGION_DEV_EXP2
) << rd_shift
;
1509 /* CPU/BIOS can read descriptor and BIOS. */
1510 fmba
->flmstr1
|= (1 << REGION_DESC
) << rd_shift
;
1511 fmba
->flmstr1
|= (1 << REGION_BIOS
) << rd_shift
;
1512 /* CPU/BIOS can write BIOS. */
1513 fmba
->flmstr1
|= (1 << REGION_BIOS
) << wr_shift
;
1514 /* ME can read descriptor and ME. */
1515 fmba
->flmstr2
|= (1 << REGION_DESC
) << rd_shift
;
1516 fmba
->flmstr2
|= (1 << REGION_ME
) << rd_shift
;
1517 /* ME can write ME. */
1518 fmba
->flmstr2
|= (1 << REGION_ME
) << wr_shift
;
1521 /* CPU/BIOS can read descriptor and BIOS. */
1522 fmba
->flmstr1
|= (1 << REGION_DESC
) << rd_shift
;
1523 fmba
->flmstr1
|= (1 << REGION_BIOS
) << rd_shift
;
1524 /* CPU/BIOS can write BIOS. */
1525 fmba
->flmstr1
|= (1 << REGION_BIOS
) << wr_shift
;
1526 /* ME can read descriptor and ME. */
1527 fmba
->flmstr2
|= (1 << REGION_DESC
) << rd_shift
;
1528 fmba
->flmstr2
|= (1 << REGION_ME
) << rd_shift
;
1529 /* ME can write ME. */
1530 fmba
->flmstr2
|= (1 << REGION_ME
) << wr_shift
;
1531 if (check_region(frba
, REGION_GBE
)) {
1532 /* BIOS can read GbE. */
1533 fmba
->flmstr1
|= (1 << REGION_GBE
) << rd_shift
;
1534 /* BIOS can write GbE. */
1535 fmba
->flmstr1
|= (1 << REGION_GBE
) << wr_shift
;
1536 /* ME can read GbE. */
1537 fmba
->flmstr2
|= (1 << REGION_GBE
) << rd_shift
;
1538 /* ME can write GbE. */
1539 fmba
->flmstr2
|= (1 << REGION_GBE
) << wr_shift
;
1540 /* GbE can write GbE. */
1541 fmba
->flmstr3
|= (1 << REGION_GBE
) << rd_shift
;
1542 /* GbE can read GbE. */
1543 fmba
->flmstr3
|= (1 << REGION_GBE
) << wr_shift
;
1548 write_image(filename
, image
, size
);
1551 static void enable_cpu_read_me(const char *filename
, char *image
, int size
)
1554 struct fmba
*fmba
= find_fmba(image
, size
);
1559 if (ifd_version
>= IFD_VERSION_2
)
1560 rd_shift
= FLMSTR_RD_SHIFT_V2
;
1562 rd_shift
= FLMSTR_RD_SHIFT_V1
;
1564 /* CPU/BIOS can read ME. */
1565 fmba
->flmstr1
|= (1 << REGION_ME
) << rd_shift
;
1567 write_image(filename
, image
, size
);
1570 static void unlock_descriptor(const char *filename
, char *image
, int size
)
1572 struct fmba
*fmba
= find_fmba(image
, size
);
1576 if (ifd_version
>= IFD_VERSION_2
) {
1578 * Set all read/write access bits. See comment on
1579 * platform_has_extended_regions() for bitfields.
1581 if (platform_has_extended_regions()) {
1582 fmba
->flmstr1
= 0xffffffff;
1583 fmba
->flmstr2
= 0xffffffff;
1584 fmba
->flmstr3
= 0xffffffff;
1585 fmba
->flmstr5
= 0xffffffff;
1587 fmba
->flmstr1
= 0xffffff00 | (fmba
->flmstr1
& 0xff);
1588 fmba
->flmstr2
= 0xffffff00 | (fmba
->flmstr2
& 0xff);
1589 fmba
->flmstr3
= 0xffffff00 | (fmba
->flmstr3
& 0xff);
1590 fmba
->flmstr5
= 0xffffff00 | (fmba
->flmstr5
& 0xff);
1593 fmba
->flmstr1
= 0xffff0000;
1594 fmba
->flmstr2
= 0xffff0000;
1595 /* Keep chipset specific Requester ID */
1596 fmba
->flmstr3
= 0x08080000 | (fmba
->flmstr3
& 0xffff);
1599 write_image(filename
, image
, size
);
1602 static void print_gpr0_range(union gprd reg
)
1604 printf("--------- GPR0 Protected Range --------------\n");
1605 printf("Start address = 0x%08x\n", reg
.data
.start
<< 12);
1606 printf("End address = 0x%08x\n", (reg
.data
.end
<< 12) | 0xfff);
1609 static uint8_t get_cse_data_partition_offset(void)
1611 uint8_t data_offset
= 0xff;
1631 static uint32_t get_gpr0_offset(void)
1633 /* Offset expressed as number of 32-bit fields from FPSBA */
1634 uint32_t gpr0_offset
= 0xffffffff;
1660 static void disable_gpr0(const char *filename
, char *image
, int size
)
1662 struct fpsba
*fpsba
= find_fpsba(image
, size
);
1666 uint32_t gpr0_offset
= get_gpr0_offset();
1667 if (gpr0_offset
== 0xffffffff) {
1668 fprintf(stderr
, "Disabling GPR0 not supported on this platform\n");
1673 /* If bit 31 is set then GPR0 protection is enable */
1674 reg
.value
= fpsba
->pchstrp
[gpr0_offset
];
1675 if (!reg
.data
.write_protect_en
) {
1676 printf("GPR0 protection is already disabled\n");
1680 printf("Value at GPRD offset (%d) is 0x%08x\n", gpr0_offset
, reg
.value
);
1681 print_gpr0_range(reg
);
1682 /* 0 means GPR0 protection is disabled */
1683 fpsba
->pchstrp
[gpr0_offset
] = 0;
1684 write_image(filename
, image
, size
);
1685 printf("GPR0 protection is now disabled\n");
1689 * Helper function to parse the FPT to retrieve the FITC start offset and size.
1690 * FITC is a sub-partition table inside CSE data partition known as FPT.
1693 * |-----> CSE Data Partition Offset
1694 * | |-------> FPT Entry
1695 * | | |-> Sub Partition 1
1696 * | | |-> Sub Partition 2
1698 * | | | | -> FITC Offset
1699 * | | | | -> FITC Length
1701 static int parse_fitc_table(struct cse_fpt
*fpt
, uint32_t *offset
,
1704 size_t num_part_header
= fpt
->count
;
1705 /* Move to the next structure which is FPT sub-partition entries */
1706 struct cse_fpt_sub_part
*fpt_sub_part
= (struct cse_fpt_sub_part
*)(fpt
+ 1);
1707 for (size_t index
= 0; index
< num_part_header
; index
++) {
1708 if (!strncmp(fpt_sub_part
->signature
, "FITC", 4)) {
1709 *offset
= fpt_sub_part
->offset
;
1710 *size
= fpt_sub_part
->length
;
1720 * Formula to calculate the GPR0 protection range as below:
1721 * Start: CSE Region Base Offset
1722 * End: Till the end of FITC sub-partition
1724 static int calculate_gpr0_range(char *image
, int size
,
1725 uint32_t *gpr0_start
, uint32_t *gpr0_end
)
1727 struct frba
*frba
= find_frba(image
, size
);
1731 struct region region
= get_region(frba
, REGION_ME
);
1732 if (region
.size
<= 0) {
1733 fprintf(stderr
, "Region %s is disabled in target\n",
1734 region_name(REGION_ME
));
1738 /* CSE Region Start */
1739 uint32_t cse_region_start
= region
.base
;
1740 /* Get CSE Data Partition Offset */
1741 uint8_t cse_data_offset
= get_cse_data_partition_offset();
1742 if (cse_data_offset
== 0xff) {
1743 fprintf(stderr
, "Unsupported platform\n");
1746 uint32_t data_part_offset
= *((uint32_t *)(image
+ cse_region_start
+ cse_data_offset
));
1747 /* Start reading the CSE Data Partition Table, also known as FPT */
1748 uint32_t data_part_start
= data_part_offset
+ cse_region_start
;
1750 uint32_t fitc_region_start
= 0;
1751 size_t fitc_region_size
= 0;
1753 * FPT holds entry for own FPT data structure also bunch of sub-partitions.
1754 * `FITC` is one of such sub-partition entry.
1756 if (parse_fitc_table(((struct cse_fpt
*)(image
+ data_part_start
)),
1757 &fitc_region_start
, &fitc_region_size
) < 0) {
1758 fprintf(stderr
, "Unable to find FITC entry\n");
1763 * GPR0 protection is configured to the following range:
1764 * start: CSE region base offset
1765 * end: Till the end of FITC sub-partition (i.e. CSE region + data partition offset +
1766 * FITC sub partition offset + FITC sub partition size)
1768 *gpr0_start
= cse_region_start
;
1769 *gpr0_end
= (cse_region_start
+ data_part_offset
+
1770 fitc_region_start
+ fitc_region_size
) - 1;
1775 static union gprd
get_enabled_gprd(char *image
, int size
)
1777 union gprd enabled_gprd_reg
;
1778 uint32_t gpr0_range_start
, gpr0_range_end
;
1779 enabled_gprd_reg
.value
= 0;
1780 if (calculate_gpr0_range(image
, size
, &gpr0_range_start
, &gpr0_range_end
))
1783 enabled_gprd_reg
.data
.start
= (gpr0_range_start
>> 12) & 0x7fff;
1784 enabled_gprd_reg
.data
.end
= (gpr0_range_end
>> 12) & 0x7fff;
1785 enabled_gprd_reg
.data
.read_protect_en
= 0;
1786 enabled_gprd_reg
.data
.write_protect_en
= 1;
1788 return enabled_gprd_reg
;
1791 static void enable_gpr0(const char *filename
, char *image
, int size
)
1793 struct fpsba
*fpsba
= find_fpsba(image
, size
);
1797 uint32_t gpr0_offset
= get_gpr0_offset();
1798 if (gpr0_offset
== 0xffffffff) {
1799 fprintf(stderr
, "Enabling GPR0 not supported on this platform\n");
1804 /* If bit 31 is set then GPR0 protection is enable */
1805 reg
.value
= fpsba
->pchstrp
[gpr0_offset
];
1806 if (reg
.data
.write_protect_en
) {
1807 printf("GPR0 protection is already enabled\n");
1808 print_gpr0_range(reg
);
1812 union gprd enabled_gprd
= get_enabled_gprd(image
, size
);
1814 fpsba
->pchstrp
[gpr0_offset
] = enabled_gprd
.value
;
1815 printf("Value at GPRD offset (%d) is 0x%08x\n", gpr0_offset
, enabled_gprd
.value
);
1816 print_gpr0_range(enabled_gprd
);
1817 write_image(filename
, image
, size
);
1818 printf("GPR0 protection is now enabled\n");
1821 static void is_gpr0_protected(char *image
, int size
)
1823 struct fpsba
*fpsba
= find_fpsba(image
, size
);
1827 uint32_t gpr0_offset
= get_gpr0_offset();
1828 if (gpr0_offset
== 0xffffffff) {
1829 fprintf(stderr
, "Checking GPR0 not supported on this platform\n");
1833 union gprd enabled_gprd
= get_enabled_gprd(image
, size
);
1834 reg
.value
= fpsba
->pchstrp
[gpr0_offset
];
1836 if (fpsba
->pchstrp
[gpr0_offset
] == enabled_gprd
.value
)
1837 printf("GPR0 status: Enabled\n\n");
1838 else if (fpsba
->pchstrp
[gpr0_offset
] == 0)
1839 printf("GPR0 status: Disabled\n\n");
1841 printf("ERROR: GPR0 setting is not expected\n\n");
1843 printf("Value at GPRD offset (%d) is 0x%08x\n", gpr0_offset
, fpsba
->pchstrp
[gpr0_offset
]);
1844 print_gpr0_range(reg
);
1847 static void set_pchstrap(struct fpsba
*fpsba
, const struct fdbar
*fdb
, const int strap
,
1848 const unsigned int value
)
1850 if (!fpsba
|| !fdb
) {
1851 fprintf(stderr
, "Internal error\n");
1855 /* SoC Strap, aka PSL, aka ISL */
1856 int SS
= (fdb
->flmap1
>> 24) & 0xff;
1858 fprintf(stderr
, "Strap index %d out of range (max: %d)\n", strap
, SS
);
1861 fpsba
->pchstrp
[strap
] = value
;
1864 /* Set the AltMeDisable (or HAP for >= IFD_VERSION_2) */
1865 static void fpsba_set_altmedisable(struct fpsba
*fpsba
, struct fmsba
*fmsba
, bool altmedisable
)
1867 if (ifd_version
>= IFD_VERSION_2
) {
1868 printf("%sting the HAP bit to %s Intel ME...\n",
1869 altmedisable
? "Set" : "Unset",
1870 altmedisable
? "disable" : "enable");
1872 fpsba
->pchstrp
[0] |= (1 << 16);
1874 fpsba
->pchstrp
[0] &= ~(1 << 16);
1876 if (chipset
>= CHIPSET_ICH8
&& chipset
<= CHIPSET_ICH10
) {
1877 printf("%sting the ICH_MeDisable, MCH_MeDisable, "
1878 "and MCH_AltMeDisable to %s Intel ME...\n",
1879 altmedisable
? "Set" : "Unset",
1880 altmedisable
? "disable" : "enable");
1883 fmsba
->data
[0] |= 1;
1884 /* MCH_AltMeDisable */
1885 fmsba
->data
[0] |= (1 << 7);
1887 fpsba
->pchstrp
[0] |= 1;
1889 fmsba
->data
[0] &= ~1;
1890 fmsba
->data
[0] &= ~(1 << 7);
1891 fpsba
->pchstrp
[0] &= ~1;
1894 printf("%sting the AltMeDisable to %s Intel ME...\n",
1895 altmedisable
? "Set" : "Unset",
1896 altmedisable
? "disable" : "enable");
1898 fpsba
->pchstrp
[10] |= (1 << 7);
1900 fpsba
->pchstrp
[10] &= ~(1 << 7);
1905 static void inject_region(const char *filename
, char *image
, int size
,
1906 unsigned int region_type
, const char *region_fname
)
1908 struct frba
*frba
= find_frba(image
, size
);
1912 struct region region
= get_region(frba
, region_type
);
1913 if (region
.size
<= 0xfff) {
1914 fprintf(stderr
, "Region %s is disabled in target. Not injecting.\n",
1915 region_name(region_type
));
1919 int region_fd
= open(region_fname
, O_RDONLY
| O_BINARY
);
1920 if (region_fd
== -1) {
1921 perror("Could not open file");
1925 if (fstat(region_fd
, &buf
) == -1) {
1926 perror("Could not stat file");
1929 int region_size
= buf
.st_size
;
1931 printf("File %s is %d bytes\n", region_fname
, region_size
);
1933 if (region_size
> region
.size
) {
1934 fprintf(stderr
, "Region %s is %d(0x%x) bytes. File is %d(0x%x)"
1935 " bytes. Not injecting.\n",
1936 region_name(region_type
), region
.size
,
1937 region
.size
, region_size
, region_size
);
1942 if ((region_type
== 1) && (region_size
< region
.size
)) {
1943 fprintf(stderr
, "Region %s is %d(0x%x) bytes. File is %d(0x%x)"
1944 " bytes. Padding before injecting.\n",
1945 region_name(region_type
), region
.size
,
1946 region
.size
, region_size
, region_size
);
1947 offset
= region
.size
- region_size
;
1948 memset(image
+ region
.base
, 0xff, offset
);
1951 if (size
< region
.base
+ offset
+ region_size
) {
1952 fprintf(stderr
, "Output file is too small. (%d < %d)\n",
1953 size
, region
.base
+ offset
+ region_size
);
1957 if (read(region_fd
, image
+ region
.base
+ offset
, region_size
) != region_size
) {
1958 perror("Could not read file");
1964 printf("Adding %s as the %s section of %s\n",
1965 region_fname
, region_name(region_type
), filename
);
1966 write_image(filename
, image
, size
);
1969 static unsigned int next_pow2(unsigned int x
)
1981 * Determine if two memory regions overlap.
1983 * @param r1, r2 Memory regions to compare.
1984 * @return 0 if the two regions are separate
1985 * @return 1 if the two regions overlap
1987 static int regions_collide(const struct region
*r1
, const struct region
*r2
)
1989 if ((r1
->size
== 0) || (r2
->size
== 0))
1992 /* r1 should be either completely below or completely above r2 */
1993 return !(r1
->limit
< r2
->base
|| r1
->base
> r2
->limit
);
1996 static void new_layout(const char *filename
, char *image
, int size
,
1997 const char *layout_fname
)
2001 char layout_region_name
[256];
2004 struct region current_regions
[MAX_REGIONS
];
2005 struct region new_regions
[MAX_REGIONS
];
2009 /* load current descriptor map and regions */
2010 struct frba
*frba
= find_frba(image
, size
);
2014 for (i
= 0; i
< max_regions
; i
++) {
2015 current_regions
[i
] = get_region(frba
, i
);
2016 new_regions
[i
] = get_region(frba
, i
);
2019 /* read new layout */
2020 romlayout
= fopen(layout_fname
, "r");
2023 perror("Could not read layout file.\n");
2027 while (!feof(romlayout
)) {
2028 char *tstr1
, *tstr2
;
2030 if (2 != fscanf(romlayout
, "%255s %255s\n", tempstr
,
2031 layout_region_name
))
2034 region_number
= region_num(layout_region_name
);
2035 if (region_number
< 0)
2038 tstr1
= strtok(tempstr
, ":");
2039 tstr2
= strtok(NULL
, ":");
2040 if (!tstr1
|| !tstr2
) {
2041 fprintf(stderr
, "Could not parse layout file.\n");
2044 new_regions
[region_number
].base
= strtol(tstr1
,
2046 new_regions
[region_number
].limit
= strtol(tstr2
,
2048 new_regions
[region_number
].size
=
2049 new_regions
[region_number
].limit
-
2050 new_regions
[region_number
].base
+ 1;
2052 if (new_regions
[region_number
].size
< 0)
2053 new_regions
[region_number
].size
= 0;
2057 /* check new layout */
2058 for (i
= 0; i
< max_regions
; i
++) {
2059 if (new_regions
[i
].size
== 0)
2062 if (new_regions
[i
].size
< current_regions
[i
].size
) {
2063 printf("DANGER: Region %s is shrinking.\n",
2065 printf(" The region will be truncated to fit.\n");
2066 printf(" This may result in an unusable image.\n");
2069 for (j
= i
+ 1; j
< max_regions
; j
++) {
2070 if (regions_collide(&new_regions
[i
], &new_regions
[j
])) {
2071 fprintf(stderr
, "Regions would overlap.\n");
2076 /* detect if the image size should grow */
2077 if (new_extent
< new_regions
[i
].limit
)
2078 new_extent
= new_regions
[i
].limit
;
2081 /* check if the image is actually a Flash Descriptor region */
2082 if (size
== new_regions
[0].size
) {
2083 printf("The image is a single Flash Descriptor:\n");
2084 printf(" Only the descriptor will be modified\n");
2087 new_extent
= next_pow2(new_extent
- 1);
2088 if (new_extent
!= size
) {
2089 printf("The image has changed in size.\n");
2090 printf("The old image is %d bytes.\n", size
);
2091 printf("The new image is %d bytes.\n", new_extent
);
2095 /* copy regions to a new image */
2096 new_image
= malloc(new_extent
);
2097 memset(new_image
, 0xff, new_extent
);
2098 for (i
= 0; i
< max_regions
; i
++) {
2099 int copy_size
= new_regions
[i
].size
;
2100 int offset_current
= 0, offset_new
= 0;
2101 const struct region
*current
= ¤t_regions
[i
];
2102 const struct region
*new = &new_regions
[i
];
2107 if (new->size
> current
->size
) {
2108 /* copy from the end of the current region */
2109 copy_size
= current
->size
;
2110 if (i
== REGION_BIOS
)
2111 offset_new
= new->size
- current
->size
;
2114 if ((i
== REGION_BIOS
) && (new->size
< current
->size
)) {
2115 /* copy BIOS region to the end of the new region */
2116 offset_current
= current
->size
- new->size
;
2119 if (size
< current
->base
+ offset_current
+ copy_size
) {
2120 printf("Skip descriptor %d (%s) (region missing in the old image)\n", i
,
2125 printf("Copy Descriptor %d (%s) (%d bytes)\n", i
,
2126 region_name(i
), copy_size
);
2127 printf(" from %08x+%08x:%08x (%10d)\n", current
->base
,
2128 offset_current
, current
->limit
, current
->size
);
2129 printf(" to %08x+%08x:%08x (%10d)\n", new->base
,
2130 offset_new
, new->limit
, new->size
);
2132 memcpy(new_image
+ new->base
+ offset_new
,
2133 image
+ current
->base
+ offset_current
,
2137 /* update new descriptor regions */
2138 frba
= find_frba(new_image
, new_extent
);
2142 printf("Modify Flash Descriptor regions\n");
2143 for (i
= 1; i
< max_regions
; i
++)
2144 set_region(frba
, i
, &new_regions
[i
]);
2146 write_image(filename
, new_image
, new_extent
);
2150 static void print_version(void)
2152 printf("ifdtool v%s -- ", IFDTOOL_VERSION
);
2153 printf("Copyright (C) 2011 Google Inc.\n\n");
2155 ("This program is free software: you can redistribute it and/or modify\n"
2156 "it under the terms of the GNU General Public License as published by\n"
2157 "the Free Software Foundation, version 2 of the License.\n\n"
2158 "This program is distributed in the hope that it will be useful,\n"
2159 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
2160 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
2161 "GNU General Public License for more details.\n\n");
2164 static void print_usage(const char *name
)
2166 printf("usage: %s [-vhdix?] <filename>\n", name
);
2168 " -d | --dump: dump intel firmware descriptor\n"
2169 " -f | --layout <filename> dump regions into a flashrom layout file\n"
2170 " -F | --fmap-layout <filename> dump IFD regions into a fmap layout template (.fmd) file\n"
2171 " -t | --validate Validate that the firmware descriptor layout matches the fmap layout\n"
2172 " -x | --extract: extract intel fd modules\n"
2173 " -i | --inject <region>:<module> inject file <module> into region <region>\n"
2174 " -n | --newlayout <filename> update regions using a flashrom layout file\n"
2175 " -O | --output <filename> output filename\n"
2176 " -s | --spifreq <17|20|30|33|48|50> set the SPI frequency\n"
2177 " -D | --density <512|1|2|4|8|16|32|64> set chip density (512 in KByte, others in MByte)\n"
2178 " -C | --chip <0|1|2> select spi chip on which to operate\n"
2179 " can only be used once per run:\n"
2180 " 0 - both chips (default), 1 - first chip, 2 - second chip\n"
2181 " -e | --em100 set SPI frequency to 20MHz and disable\n"
2182 " Dual Output Fast Read Support\n"
2183 " -l | --lock Lock firmware descriptor and ME region\n"
2184 " -r | --read Enable CPU/BIOS read access for ME region\n"
2185 " -u | --unlock Unlock firmware descriptor and ME region\n"
2186 " -g | --gpr0-disable Disable GPR0 (Global Protected Range) register\n"
2187 " -E | --gpr0-enable Enable GPR0 (Global Protected Range) register\n"
2188 " -c | --gpr0-status Checking GPR0 (Global Protected Range) register status\n"
2189 " -M | --altmedisable <0|1> Set the MeDisable and AltMeDisable (or HAP for skylake or newer platform)\n"
2190 " bits to disable ME\n"
2191 " -p | --platform Add platform-specific quirks\n"
2192 " adl - Alder Lake\n"
2193 " aplk - Apollo Lake\n"
2194 " cnl - Cannon Lake\n"
2195 " lbg - Lewisburg PCH\n"
2196 " dnv - Denverton\n"
2197 " ehl - Elkhart Lake\n"
2198 " glk - Gemini Lake\n"
2200 " ifd2 - IFDv2 Platform\n"
2201 " jsl - Jasper Lake\n"
2202 " mtl - Meteor Lake\n"
2203 " sklkbl - Sky Lake/Kaby Lake\n"
2204 " tgl - Tiger Lake\n"
2205 " wbg - Wellsburg\n"
2206 " -S | --setpchstrap Write a PCH strap\n"
2207 " -V | --newvalue The new value to write into PCH strap specified by -S\n"
2208 " -v | --version: print the version\n"
2209 " -h | --help: print this help\n\n"
2210 "<region> is one of Descriptor, BIOS, ME, GbE, Platform Data, Secondary BIOS, "
2211 "Device Exp1, EC, Device Exp2, IE, 10GbE_0, 10GbE_1, PTT\n"
2215 int main(int argc
, char *argv
[])
2217 int opt
, option_index
= 0;
2218 int mode_dump
= 0, mode_extract
= 0, mode_inject
= 0, mode_spifreq
= 0;
2219 int mode_em100
= 0, mode_locked
= 0, mode_unlocked
= 0, mode_validate
= 0;
2220 int mode_layout
= 0, mode_newlayout
= 0, mode_density
= 0, mode_setstrap
= 0;
2221 int mode_read
= 0, mode_altmedisable
= 0, altmedisable
= 0, mode_fmap_template
= 0;
2222 int mode_gpr0_disable
= 0, mode_gpr0_enable
= 0, mode_gpr0_status
= 0;
2223 char *region_type_string
= NULL
, *region_fname
= NULL
;
2224 const char *layout_fname
= NULL
;
2225 char *new_filename
= NULL
;
2226 int region_type
= -1, inputfreq
= 0;
2227 unsigned int value
= 0;
2228 unsigned int pchstrap
= 0;
2229 unsigned int new_density
= 0;
2230 enum spi_frequency spifreq
= SPI_FREQUENCY_20MHZ
;
2232 static const struct option long_options
[] = {
2233 {"dump", 0, NULL
, 'd'},
2234 {"layout", 1, NULL
, 'f'},
2235 {"fmap-template", 1, NULL
, 'F'},
2236 {"extract", 0, NULL
, 'x'},
2237 {"inject", 1, NULL
, 'i'},
2238 {"newlayout", 1, NULL
, 'n'},
2239 {"output", 1, NULL
, 'O'},
2240 {"spifreq", 1, NULL
, 's'},
2241 {"density", 1, NULL
, 'D'},
2242 {"chip", 1, NULL
, 'C'},
2243 {"altmedisable", 1, NULL
, 'M'},
2244 {"em100", 0, NULL
, 'e'},
2245 {"lock", 0, NULL
, 'l'},
2246 {"read", 0, NULL
, 'r'},
2247 {"unlock", 0, NULL
, 'u'},
2248 {"gpr0-disable", 0, NULL
, 'g'},
2249 {"gpr0-enable", 0, NULL
, 'E'},
2250 {"gpr0-status", 0, NULL
, 'c'},
2251 {"version", 0, NULL
, 'v'},
2252 {"help", 0, NULL
, 'h'},
2253 {"platform", 1, NULL
, 'p'},
2254 {"validate", 0, NULL
, 't'},
2255 {"setpchstrap", 1, NULL
, 'S'},
2256 {"newvalue", 1, NULL
, 'V'},
2260 while ((opt
= getopt_long(argc
, argv
, "S:V:df:F:D:C:M:xi:n:O:s:p:elrugEcvth?",
2261 long_options
, &option_index
)) != EOF
) {
2268 pchstrap
= strtoul(optarg
, NULL
, 0);
2271 value
= strtoul(optarg
, NULL
, 0);
2275 layout_fname
= strdup(optarg
);
2276 if (!layout_fname
) {
2277 fprintf(stderr
, "No layout file specified\n");
2278 fprintf(stderr
, "run '%s -h' for usage\n", argv
[0]);
2283 mode_fmap_template
= 1;
2284 layout_fname
= strdup(optarg
);
2285 if (!layout_fname
) {
2286 fprintf(stderr
, "No layout file specified\n");
2287 fprintf(stderr
, "run '%s -h' for usage\n", argv
[0]);
2295 // separate type and file name
2296 region_type_string
= strdup(optarg
);
2297 region_fname
= strchr(region_type_string
, ':');
2298 if (!region_fname
) {
2299 fprintf(stderr
, "run '%s -h' for usage\n", argv
[0]);
2302 region_fname
[0] = '\0';
2304 // Descriptor, BIOS, ME, GbE, Platform
2306 if (!strcasecmp("Descriptor", region_type_string
))
2308 else if (!strcasecmp("BIOS", region_type_string
))
2310 else if (!strcasecmp("ME", region_type_string
))
2312 else if (!strcasecmp("GbE", region_type_string
))
2314 else if (!strcasecmp("Platform Data", region_type_string
))
2316 else if (!strcasecmp("Device Exp1", region_type_string
))
2318 else if (!strcasecmp("Secondary BIOS", region_type_string
))
2320 else if (!strcasecmp("Reserved", region_type_string
))
2322 else if (!strcasecmp("EC", region_type_string
))
2324 else if (!strcasecmp("Device Exp2", region_type_string
))
2326 else if (!strcasecmp("IE", region_type_string
))
2328 else if (!strcasecmp("10GbE_0", region_type_string
))
2330 else if (!strcasecmp("10GbE_1", region_type_string
))
2332 else if (!strcasecmp("PTT", region_type_string
))
2334 if (region_type
== -1) {
2335 fprintf(stderr
, "No such region type: '%s'\n\n",
2336 region_type_string
);
2337 fprintf(stderr
, "run '%s -h' for usage\n", argv
[0]);
2344 layout_fname
= strdup(optarg
);
2345 if (!layout_fname
) {
2346 fprintf(stderr
, "No layout file specified\n");
2347 fprintf(stderr
, "run '%s -h' for usage\n", argv
[0]);
2352 new_filename
= strdup(optarg
);
2353 if (!new_filename
) {
2354 fprintf(stderr
, "No output filename specified\n");
2355 fprintf(stderr
, "run '%s -h' for usage\n", argv
[0]);
2361 new_density
= strtoul(optarg
, NULL
, 0);
2362 switch (new_density
) {
2364 new_density
= COMPONENT_DENSITY_512KB
;
2367 new_density
= COMPONENT_DENSITY_1MB
;
2370 new_density
= COMPONENT_DENSITY_2MB
;
2373 new_density
= COMPONENT_DENSITY_4MB
;
2376 new_density
= COMPONENT_DENSITY_8MB
;
2379 new_density
= COMPONENT_DENSITY_16MB
;
2382 new_density
= COMPONENT_DENSITY_32MB
;
2385 new_density
= COMPONENT_DENSITY_64MB
;
2388 new_density
= COMPONENT_DENSITY_UNUSED
;
2391 printf("error: Unknown density\n");
2392 fprintf(stderr
, "run '%s -h' for usage\n", argv
[0]);
2397 selected_chip
= strtol(optarg
, NULL
, 0);
2398 if (selected_chip
> 2) {
2399 fprintf(stderr
, "error: Invalid chip selection\n");
2400 fprintf(stderr
, "run '%s -h' for usage\n", argv
[0]);
2405 mode_altmedisable
= 1;
2406 altmedisable
= strtol(optarg
, NULL
, 0);
2407 if (altmedisable
> 1) {
2408 fprintf(stderr
, "error: Illegal value\n");
2409 fprintf(stderr
, "run '%s -h' for usage\n", argv
[0]);
2414 // Parse the requested SPI frequency
2415 inputfreq
= strtol(optarg
, NULL
, 0);
2416 switch (inputfreq
) {
2418 spifreq
= SPI_FREQUENCY_17MHZ
;
2421 spifreq
= SPI_FREQUENCY_20MHZ
;
2424 spifreq
= SPI_FREQUENCY_50MHZ_30MHZ
;
2427 spifreq
= SPI_FREQUENCY_33MHZ
;
2430 spifreq
= SPI_FREQUENCY_48MHZ
;
2433 spifreq
= SPI_FREQUENCY_50MHZ_30MHZ
;
2436 fprintf(stderr
, "Invalid SPI Frequency: %d\n",
2438 fprintf(stderr
, "run '%s -h' for usage\n", argv
[0]);
2448 if (mode_unlocked
== 1) {
2449 fprintf(stderr
, "Locking/Unlocking FD and ME are mutually exclusive\n");
2458 if (mode_locked
== 1) {
2459 fprintf(stderr
, "Locking/Unlocking FD and ME are mutually exclusive\n");
2464 mode_gpr0_disable
= 1;
2467 mode_gpr0_enable
= 1;
2470 mode_gpr0_status
= 1;
2473 if (!strcmp(optarg
, "aplk")) {
2474 platform
= PLATFORM_APL
;
2475 } else if (!strcmp(optarg
, "cnl")) {
2476 platform
= PLATFORM_CNL
;
2477 } else if (!strcmp(optarg
, "lbg")) {
2478 platform
= PLATFORM_LBG
;
2479 } else if (!strcmp(optarg
, "dnv")) {
2480 platform
= PLATFORM_DNV
;
2481 } else if (!strcmp(optarg
, "ehl")) {
2482 platform
= PLATFORM_EHL
;
2483 } else if (!strcmp(optarg
, "glk")) {
2484 platform
= PLATFORM_GLK
;
2485 } else if (!strcmp(optarg
, "icl")) {
2486 platform
= PLATFORM_ICL
;
2487 } else if (!strcmp(optarg
, "jsl")) {
2488 platform
= PLATFORM_JSL
;
2489 } else if (!strcmp(optarg
, "sklkbl")) {
2490 platform
= PLATFORM_SKLKBL
;
2491 } else if (!strcmp(optarg
, "tgl")) {
2492 platform
= PLATFORM_TGL
;
2493 } else if (!strcmp(optarg
, "adl")) {
2494 platform
= PLATFORM_ADL
;
2495 } else if (!strcmp(optarg
, "ifd2")) {
2496 platform
= PLATFORM_IFD2
;
2497 } else if (!strcmp(optarg
, "mtl")) {
2498 platform
= PLATFORM_MTL
;
2499 } else if (!strcmp(optarg
, "ptl")) {
2500 platform
= PLATFORM_PTL
;
2501 } else if (!strcmp(optarg
, "wbg")) {
2502 platform
= PLATFORM_WBG
;
2504 fprintf(stderr
, "Unknown platform: %s\n", optarg
);
2517 print_usage(argv
[0]);
2521 print_usage(argv
[0]);
2527 if ((mode_dump
+ mode_layout
+ mode_fmap_template
+ mode_extract
+ mode_inject
+
2528 mode_setstrap
+ mode_newlayout
+ (mode_spifreq
| mode_em100
|
2529 mode_unlocked
| mode_locked
) + mode_altmedisable
+ mode_validate
+
2530 (mode_gpr0_disable
| mode_gpr0_enable
) + mode_gpr0_status
) > 1) {
2531 fprintf(stderr
, "You may not specify more than one mode.\n\n");
2532 fprintf(stderr
, "run '%s -h' for usage\n", argv
[0]);
2536 if ((mode_dump
+ mode_layout
+ mode_fmap_template
+ mode_extract
+ mode_inject
+
2537 mode_setstrap
+ mode_newlayout
+ mode_spifreq
+ mode_em100
+
2538 mode_locked
+ mode_unlocked
+ mode_density
+ mode_altmedisable
+
2539 mode_validate
+ (mode_gpr0_disable
| mode_gpr0_enable
) + mode_gpr0_status
) == 0) {
2540 fprintf(stderr
, "You need to specify a mode.\n\n");
2541 fprintf(stderr
, "run '%s -h' for usage\n", argv
[0]);
2545 if (optind
+ 1 != argc
) {
2546 fprintf(stderr
, "You need to specify a file.\n\n");
2547 fprintf(stderr
, "run '%s -h' for usage\n", argv
[0]);
2552 fprintf(stderr
, "Warning: No platform specified. Output may be incomplete\n");
2554 char *filename
= argv
[optind
];
2555 int bios_fd
= open(filename
, O_RDONLY
| O_BINARY
);
2556 if (bios_fd
== -1) {
2557 perror("Could not open file");
2561 if (fstat(bios_fd
, &buf
) == -1) {
2562 perror("Could not stat file");
2565 int size
= buf
.st_size
;
2567 printf("File %s is %d bytes\n", filename
, size
);
2569 char *image
= malloc(size
);
2571 printf("Out of memory.\n");
2575 if (read(bios_fd
, image
, size
) != size
) {
2576 perror("Could not read file");
2582 // generate new filename
2583 if (new_filename
== NULL
) {
2584 new_filename
= (char *)malloc((strlen(filename
) + 5) * sizeof(char));
2585 if (!new_filename
) {
2586 printf("Out of memory.\n");
2589 // - 5: leave room for ".new\0"
2590 strcpy(new_filename
, filename
);
2591 strcat(new_filename
, ".new");
2594 check_ifd_version(image
, size
);
2597 dump_fd(image
, size
);
2600 dump_flashrom_layout(image
, size
, layout_fname
);
2602 if (mode_fmap_template
)
2603 create_fmap_template(image
, size
, layout_fname
);
2606 write_regions(image
, size
);
2609 validate_layout(image
, size
);
2612 inject_region(new_filename
, image
, size
, region_type
,
2616 new_layout(new_filename
, image
, size
, layout_fname
);
2619 set_spi_frequency(new_filename
, image
, size
, spifreq
);
2622 set_chipdensity(new_filename
, image
, size
, new_density
);
2625 set_em100_mode(new_filename
, image
, size
);
2628 lock_descriptor(new_filename
, image
, size
);
2631 enable_cpu_read_me(new_filename
, image
, size
);
2634 unlock_descriptor(new_filename
, image
, size
);
2636 if (mode_gpr0_disable
)
2637 disable_gpr0(new_filename
, image
, size
);
2639 if (mode_gpr0_enable
)
2640 enable_gpr0(new_filename
, image
, size
);
2642 if (mode_gpr0_status
)
2643 is_gpr0_protected(image
, size
);
2645 if (mode_setstrap
) {
2646 struct fpsba
*fpsba
= find_fpsba(image
, size
);
2647 const struct fdbar
*fdb
= find_fd(image
, size
);
2648 set_pchstrap(fpsba
, fdb
, pchstrap
, value
);
2649 write_image(new_filename
, image
, size
);
2652 if (mode_altmedisable
) {
2653 struct fpsba
*fpsba
= find_fpsba(image
, size
);
2654 struct fmsba
*fmsba
= find_fmsba(image
, size
);
2655 fpsba_set_altmedisable(fpsba
, fmsba
, altmedisable
);
2656 write_image(new_filename
, image
, size
);