2 * ifdtool - dump Intel Firmware Descriptor information
4 * Copyright (C) 2011 The ChromiumOS Authors. All rights reserved.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
22 #include <sys/types.h>
24 #include <commonlib/helpers.h>
33 * PTR_IN_RANGE - examine whether a pointer falls in [base, base + limit)
34 * @param ptr: the non-void* pointer to a single arbitrary-sized object.
35 * @param base: base address represented with char* type.
36 * @param limit: upper limit of the legal address.
39 #define PTR_IN_RANGE(ptr, base, limit) \
40 ((const char *)(ptr) >= (base) && \
41 (const char *)&(ptr)[1] <= (base) + (limit))
43 static int ifd_version
;
45 static unsigned int max_regions
= 0;
46 static int selected_chip
= 0;
47 static int platform
= -1;
49 static const struct region_name region_names
[MAX_REGIONS
] = {
50 { "Flash Descriptor", "fd", "flashregion_0_flashdescriptor.bin", "SI_DESC" },
51 { "BIOS", "bios", "flashregion_1_bios.bin", "SI_BIOS" },
52 { "Intel ME", "me", "flashregion_2_intel_me.bin", "SI_ME" },
53 { "GbE", "gbe", "flashregion_3_gbe.bin", "SI_GBE" },
54 { "Platform Data", "pd", "flashregion_4_platform_data.bin", "SI_PDR" },
55 { "Reserved", "res1", "flashregion_5_reserved.bin", NULL
},
56 { "Reserved", "res2", "flashregion_6_reserved.bin", NULL
},
57 { "Reserved", "res3", "flashregion_7_reserved.bin", NULL
},
58 { "EC", "ec", "flashregion_8_ec.bin", "SI_EC" },
61 /* port from flashrom */
62 static const char *const ich_chipset_names
[] = {
69 "Atom S1220 S1240 S1260",
75 "6 series Cougar Point",
76 "7 series Panther Point",
77 "8 series Lynx Point",
79 "8 series Lynx Point LP",
81 "9 series Wildcat Point",
82 "9 series Wildcat Point LP",
83 "100 series Sunrise Point",
84 "C620 series Lewisburg",
88 static fdbar_t
*find_fd(char *image
, int size
)
92 /* Scan for FD signature */
93 for (i
= 0; i
< (size
- 4); i
+= 4) {
94 if (*(uint32_t *) (image
+ i
) == 0x0FF0A55A) {
96 break; // signature found.
101 printf("No Flash Descriptor found in this image\n");
105 fdbar_t
*fdb
= (fdbar_t
*) (image
+ i
);
106 return PTR_IN_RANGE(fdb
, image
, size
) ? fdb
: NULL
;
109 static char *find_flumap(char *image
, int size
)
111 /* The upper map is located in the word before the 256B-long OEM section
112 * at the end of the 4kB-long flash descriptor. In the official
113 * documentation this is defined as FDBAR + 0xEFC. However, starting
114 * with B-Step of Ibex Peak (5 series) the signature (and thus FDBAR)
115 * has moved 16 bytes back to offset 0x10 of the image. Although
116 * official documentation still maintains the offset relative to FDBAR
117 * this is wrong and a simple fixed offset from the start of the image
120 char *flumap
= image
+ 4096 - 256 - 4;
121 return PTR_IN_RANGE(flumap
, image
, size
) ? flumap
: NULL
;
124 static fcba_t
*find_fcba(char *image
, int size
)
126 fdbar_t
*fdb
= find_fd(image
, size
);
129 fcba_t
*fcba
= (fcba_t
*) (image
+ ((fdb
->flmap0
& 0xff) << 4));
130 return PTR_IN_RANGE(fcba
, image
, size
) ? fcba
: NULL
;
134 static fmba_t
*find_fmba(char *image
, int size
)
136 fdbar_t
*fdb
= find_fd(image
, size
);
139 fmba_t
*fmba
= (fmba_t
*) (image
+ ((fdb
->flmap1
& 0xff) << 4));
140 return PTR_IN_RANGE(fmba
, image
, size
) ? fmba
: NULL
;
143 static frba_t
*find_frba(char *image
, int size
)
145 fdbar_t
*fdb
= find_fd(image
, size
);
149 (frba_t
*) (image
+ (((fdb
->flmap0
>> 16) & 0xff) << 4));
150 return PTR_IN_RANGE(frba
, image
, size
) ? frba
: NULL
;
153 static fpsba_t
*find_fpsba(char *image
, int size
)
155 fdbar_t
*fdb
= find_fd(image
, size
);
159 (fpsba_t
*) (image
+ (((fdb
->flmap1
>> 16) & 0xff) << 4));
160 return PTR_IN_RANGE(fpsba
, image
, size
) ? fpsba
: NULL
;
163 static fmsba_t
*find_fmsba(char *image
, int size
)
165 fdbar_t
*fdb
= find_fd(image
, size
);
168 fmsba_t
*fmsba
= (fmsba_t
*) (image
+ ((fdb
->flmap2
& 0xff) << 4));
169 return PTR_IN_RANGE(fmsba
, image
, size
) ? fmsba
: NULL
;
172 /* port from flashrom */
173 static enum ich_chipset
guess_ich_chipset(const fdbar_t
*fdb
)
175 uint32_t iccriba
= (fdb
->flmap2
>> 16) & 0xff;
176 uint32_t msl
= (fdb
->flmap2
>> 8) & 0xff;
177 uint32_t isl
= (fdb
->flmap1
>> 24);
178 uint32_t nm
= (fdb
->flmap1
>> 8) & 0x7;
180 if (iccriba
== 0x00) {
181 if (msl
== 0 && isl
<= 2)
186 return CHIPSET_ICH10
;
188 return CHIPSET_5_SERIES_IBEX_PEAK
;
189 printf("Peculiar firmware descriptor, assuming Ibex Peak compatibility.\n");
190 return CHIPSET_5_SERIES_IBEX_PEAK
;
191 } else if (iccriba
< 0x31 && (fdb
->flmap2
& 0xff) < 0x30) {
192 if (msl
== 0 && isl
<= 17)
193 return CHIPSET_BAYTRAIL
;
194 else if (msl
<= 1 && isl
<= 18)
195 return CHIPSET_6_SERIES_COUGAR_POINT
;
196 else if (msl
<= 1 && isl
<= 21)
197 return CHIPSET_8_SERIES_LYNX_POINT
;
198 printf("Peculiar firmware descriptor, assuming Wildcat Point compatibility.\n");
199 return CHIPSET_9_SERIES_WILDCAT_POINT
;
200 } else if (nm
== 6) {
201 return CHIPSET_C620_SERIES_LEWISBURG
;
203 return CHIPSET_100_SERIES_SUNRISE_POINT
;
208 * Some newer platforms have re-defined the FCBA field that was used to
209 * distinguish IFD v1 v/s v2. Define a list of platforms that we know do not
210 * have the required FCBA field, but are IFD v2 and return true if current
211 * platform is one of them.
213 static int is_platform_ifd_2(void)
215 static const int ifd_2_platforms
[] = {
224 for (i
= 0; i
< ARRAY_SIZE(ifd_2_platforms
); i
++) {
225 if (platform
== ifd_2_platforms
[i
])
233 * There is no version field in the descriptor so to determine
234 * if this is a new descriptor format we check the hardcoded SPI
235 * read frequency to see if it is fixed at 20MHz or 17MHz.
237 static int get_ifd_version_from_fcba(char *image
, int size
)
240 const fcba_t
*fcba
= find_fcba(image
, size
);
241 const fdbar_t
*fdb
= find_fd(image
, size
);
245 chipset
= guess_ich_chipset(fdb
);
246 /* TODO: port ifd_version and max_regions
247 * against guess_ich_chipset()
249 read_freq
= (fcba
->flcomp
>> 17) & 7;
252 case SPI_FREQUENCY_20MHZ
:
253 return IFD_VERSION_1
;
254 case SPI_FREQUENCY_17MHZ
:
255 case SPI_FREQUENCY_50MHZ_30MHZ
:
256 return IFD_VERSION_2
;
258 fprintf(stderr
, "Unknown descriptor version: %d\n",
264 static void check_ifd_version(char *image
, int size
)
266 if (is_platform_ifd_2())
267 ifd_version
= IFD_VERSION_2
;
269 ifd_version
= get_ifd_version_from_fcba(image
, size
);
271 if (ifd_version
== IFD_VERSION_1
)
272 max_regions
= MAX_REGIONS_OLD
;
274 max_regions
= MAX_REGIONS
;
277 static region_t
get_region(const frba_t
*frba
, unsigned int region_type
)
284 if (ifd_version
>= IFD_VERSION_2
)
289 limit_mask
= base_mask
<< 16;
291 if (region_type
>= max_regions
) {
292 fprintf(stderr
, "Invalid region type %d.\n", region_type
);
296 flreg
= frba
->flreg
[region_type
];
297 region
.base
= (flreg
& base_mask
) << 12;
298 region
.limit
= ((flreg
& limit_mask
) >> 4) | 0xfff;
299 region
.size
= region
.limit
- region
.base
+ 1;
307 static void set_region(frba_t
*frba
, unsigned int region_type
,
308 const region_t
*region
)
310 if (region_type
>= max_regions
) {
311 fprintf(stderr
, "Invalid region type %u.\n", region_type
);
315 frba
->flreg
[region_type
] =
316 (((region
->limit
>> 12) & 0x7fff) << 16) |
317 ((region
->base
>> 12) & 0x7fff);
320 static const char *region_name(unsigned int region_type
)
322 if (region_type
>= max_regions
) {
323 fprintf(stderr
, "Invalid region type.\n");
327 return region_names
[region_type
].pretty
;
330 static const char *region_name_short(unsigned int region_type
)
332 if (region_type
>= max_regions
) {
333 fprintf(stderr
, "Invalid region type.\n");
337 return region_names
[region_type
].terse
;
340 static int region_num(const char *name
)
344 for (i
= 0; i
< max_regions
; i
++) {
345 if (strcasecmp(name
, region_names
[i
].pretty
) == 0)
347 if (strcasecmp(name
, region_names
[i
].terse
) == 0)
354 static const char *region_filename(unsigned int region_type
)
356 if (region_type
>= max_regions
) {
357 fprintf(stderr
, "Invalid region type %d.\n", region_type
);
361 return region_names
[region_type
].filename
;
364 static void dump_region(unsigned int num
, const frba_t
*frba
)
366 region_t region
= get_region(frba
, num
);
367 printf(" Flash Region %d (%s): %08x - %08x %s\n",
368 num
, region_name(num
), region
.base
, region
.limit
,
369 region
.size
< 1 ? "(unused)" : "");
372 static void dump_region_layout(char *buf
, size_t bufsize
, unsigned int num
,
375 region_t region
= get_region(frba
, num
);
376 snprintf(buf
, bufsize
, "%08x:%08x %s\n",
377 region
.base
, region
.limit
, region_name_short(num
));
380 static void dump_frba(const frba_t
*frba
)
383 printf("Found Region Section\n");
384 for (i
= 0; i
< max_regions
; i
++) {
385 printf("FLREG%u: 0x%08x\n", i
, frba
->flreg
[i
]);
386 dump_region(i
, frba
);
390 static void dump_frba_layout(const frba_t
*frba
, const char *layout_fname
)
392 char buf
[LAYOUT_LINELEN
];
393 size_t bufsize
= LAYOUT_LINELEN
;
396 int layout_fd
= open(layout_fname
, O_WRONLY
| O_CREAT
| O_TRUNC
,
397 S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IROTH
);
398 if (layout_fd
== -1) {
399 perror("Could not open file");
403 for (i
= 0; i
< max_regions
; i
++) {
404 region_t region
= get_region(frba
, i
);
405 /* is region invalid? */
409 dump_region_layout(buf
, bufsize
, i
, frba
);
410 if (write(layout_fd
, buf
, strlen(buf
)) < 0) {
411 perror("Could not write to file");
416 printf("Wrote layout to %s\n", layout_fname
);
419 static void decode_spi_frequency(unsigned int freq
)
422 case SPI_FREQUENCY_20MHZ
:
425 case SPI_FREQUENCY_33MHZ
:
428 case SPI_FREQUENCY_48MHZ
:
431 case SPI_FREQUENCY_50MHZ_30MHZ
:
432 switch (ifd_version
) {
441 case SPI_FREQUENCY_17MHZ
:
445 printf("unknown<%x>MHz", freq
);
449 static void decode_component_density(unsigned int density
)
452 case COMPONENT_DENSITY_512KB
:
455 case COMPONENT_DENSITY_1MB
:
458 case COMPONENT_DENSITY_2MB
:
461 case COMPONENT_DENSITY_4MB
:
464 case COMPONENT_DENSITY_8MB
:
467 case COMPONENT_DENSITY_16MB
:
470 case COMPONENT_DENSITY_32MB
:
473 case COMPONENT_DENSITY_64MB
:
476 case COMPONENT_DENSITY_UNUSED
:
480 printf("unknown<%x>MB", density
);
484 static void dump_fcba(const fcba_t
*fcba
)
486 printf("\nFound Component Section\n");
487 printf("FLCOMP 0x%08x\n", fcba
->flcomp
);
488 printf(" Dual Output Fast Read Support: %ssupported\n",
489 (fcba
->flcomp
& (1 << 30))?"":"not ");
490 printf(" Read ID/Read Status Clock Frequency: ");
491 decode_spi_frequency((fcba
->flcomp
>> 27) & 7);
492 printf("\n Write/Erase Clock Frequency: ");
493 decode_spi_frequency((fcba
->flcomp
>> 24) & 7);
494 printf("\n Fast Read Clock Frequency: ");
495 decode_spi_frequency((fcba
->flcomp
>> 21) & 7);
496 printf("\n Fast Read Support: %ssupported",
497 (fcba
->flcomp
& (1 << 20))?"":"not ");
498 printf("\n Read Clock Frequency: ");
499 decode_spi_frequency((fcba
->flcomp
>> 17) & 7);
501 switch (ifd_version
) {
503 printf("\n Component 2 Density: ");
504 decode_component_density((fcba
->flcomp
>> 3) & 7);
505 printf("\n Component 1 Density: ");
506 decode_component_density(fcba
->flcomp
& 7);
509 printf("\n Component 2 Density: ");
510 decode_component_density((fcba
->flcomp
>> 4) & 0xf);
511 printf("\n Component 1 Density: ");
512 decode_component_density(fcba
->flcomp
& 0xf);
517 printf("FLILL 0x%08x\n", fcba
->flill
);
518 printf(" Invalid Instruction 3: 0x%02x\n",
519 (fcba
->flill
>> 24) & 0xff);
520 printf(" Invalid Instruction 2: 0x%02x\n",
521 (fcba
->flill
>> 16) & 0xff);
522 printf(" Invalid Instruction 1: 0x%02x\n",
523 (fcba
->flill
>> 8) & 0xff);
524 printf(" Invalid Instruction 0: 0x%02x\n",
526 printf("FLPB 0x%08x\n", fcba
->flpb
);
527 printf(" Flash Partition Boundary Address: 0x%06x\n\n",
528 (fcba
->flpb
& 0xfff) << 12);
531 static void dump_fpsba(const fpsba_t
*fpsba
)
534 printf("Found PCH Strap Section\n");
535 for (i
= 0; i
< ARRAY_SIZE(fpsba
->pchstrp
); i
++)
536 printf("PCHSTRP%u:%s 0x%08x\n", i
,
537 i
< 10 ? " " : "", fpsba
->pchstrp
[i
]);
539 if (ifd_version
>= IFD_VERSION_2
) {
540 printf("HAP bit is %sset\n",
541 fpsba
->pchstrp
[0] & (1 << 16) ? "" : "not ");
542 } else if (chipset
>= CHIPSET_ICH8
543 && chipset
<= CHIPSET_ICH10
) {
544 printf("ICH_MeDisable bit is %sset\n",
545 fpsba
->pchstrp
[0] & 1 ? "" : "not ");
547 printf("AltMeDisable bit is %sset\n",
548 fpsba
->pchstrp
[10] & (1 << 7) ? "" : "not ");
554 static void decode_flmstr(uint32_t flmstr
)
556 int wr_shift
, rd_shift
;
557 if (ifd_version
>= IFD_VERSION_2
) {
558 wr_shift
= FLMSTR_WR_SHIFT_V2
;
559 rd_shift
= FLMSTR_RD_SHIFT_V2
;
561 wr_shift
= FLMSTR_WR_SHIFT_V1
;
562 rd_shift
= FLMSTR_RD_SHIFT_V1
;
565 /* EC region access only available on v2+ */
566 if (ifd_version
>= IFD_VERSION_2
)
567 printf(" EC Region Write Access: %s\n",
568 (flmstr
& (1 << (wr_shift
+ 8))) ?
569 "enabled" : "disabled");
570 printf(" Platform Data Region Write Access: %s\n",
571 (flmstr
& (1 << (wr_shift
+ 4))) ? "enabled" : "disabled");
572 printf(" GbE Region Write Access: %s\n",
573 (flmstr
& (1 << (wr_shift
+ 3))) ? "enabled" : "disabled");
574 printf(" Intel ME Region Write Access: %s\n",
575 (flmstr
& (1 << (wr_shift
+ 2))) ? "enabled" : "disabled");
576 printf(" Host CPU/BIOS Region Write Access: %s\n",
577 (flmstr
& (1 << (wr_shift
+ 1))) ? "enabled" : "disabled");
578 printf(" Flash Descriptor Write Access: %s\n",
579 (flmstr
& (1 << wr_shift
)) ? "enabled" : "disabled");
581 if (ifd_version
>= IFD_VERSION_2
)
582 printf(" EC Region Read Access: %s\n",
583 (flmstr
& (1 << (rd_shift
+ 8))) ?
584 "enabled" : "disabled");
585 printf(" Platform Data Region Read Access: %s\n",
586 (flmstr
& (1 << (rd_shift
+ 4))) ? "enabled" : "disabled");
587 printf(" GbE Region Read Access: %s\n",
588 (flmstr
& (1 << (rd_shift
+ 3))) ? "enabled" : "disabled");
589 printf(" Intel ME Region Read Access: %s\n",
590 (flmstr
& (1 << (rd_shift
+ 2))) ? "enabled" : "disabled");
591 printf(" Host CPU/BIOS Region Read Access: %s\n",
592 (flmstr
& (1 << (rd_shift
+ 1))) ? "enabled" : "disabled");
593 printf(" Flash Descriptor Read Access: %s\n",
594 (flmstr
& (1 << rd_shift
)) ? "enabled" : "disabled");
596 /* Requestor ID doesn't exist for ifd 2 */
597 if (ifd_version
< IFD_VERSION_2
)
598 printf(" Requester ID: 0x%04x\n\n",
602 static void dump_fmba(const fmba_t
*fmba
)
604 printf("Found Master Section\n");
605 printf("FLMSTR1: 0x%08x (Host CPU/BIOS)\n", fmba
->flmstr1
);
606 decode_flmstr(fmba
->flmstr1
);
607 printf("FLMSTR2: 0x%08x (Intel ME)\n", fmba
->flmstr2
);
608 decode_flmstr(fmba
->flmstr2
);
609 printf("FLMSTR3: 0x%08x (GbE)\n", fmba
->flmstr3
);
610 decode_flmstr(fmba
->flmstr3
);
611 if (ifd_version
>= IFD_VERSION_2
) {
612 printf("FLMSTR5: 0x%08x (EC)\n", fmba
->flmstr5
);
613 decode_flmstr(fmba
->flmstr5
);
617 static void dump_fmsba(const fmsba_t
*fmsba
)
620 printf("Found Processor Strap Section\n");
621 for (i
= 0; i
< ARRAY_SIZE(fmsba
->data
); i
++)
622 printf("????: 0x%08x\n", fmsba
->data
[i
]);
624 if (chipset
>= CHIPSET_ICH8
&& chipset
<= CHIPSET_ICH10
) {
625 printf("MCH_MeDisable bit is %sset\n",
626 fmsba
->data
[0] & 1 ? "" : "not ");
627 printf("MCH_AltMeDisable bit is %sset\n",
628 fmsba
->data
[0] & (1 << 7) ? "" : "not ");
632 static void dump_jid(uint32_t jid
)
634 printf(" SPI Componend Vendor ID: 0x%02x\n",
636 printf(" SPI Componend Device ID 0: 0x%02x\n",
638 printf(" SPI Componend Device ID 1: 0x%02x\n",
642 static void dump_vscc(uint32_t vscc
)
644 printf(" Lower Erase Opcode: 0x%02x\n",
646 printf(" Lower Write Enable on Write Status: 0x%02x\n",
647 vscc
& (1 << 20) ? 0x06 : 0x50);
648 printf(" Lower Write Status Required: %s\n",
649 vscc
& (1 << 19) ? "Yes" : "No");
650 printf(" Lower Write Granularity: %d bytes\n",
651 vscc
& (1 << 18) ? 64 : 1);
652 printf(" Lower Block / Sector Erase Size: ");
653 switch ((vscc
>> 16) & 0x3) {
655 printf("256 Byte\n");
668 printf(" Upper Erase Opcode: 0x%02x\n",
670 printf(" Upper Write Enable on Write Status: 0x%02x\n",
671 vscc
& (1 << 4) ? 0x06 : 0x50);
672 printf(" Upper Write Status Required: %s\n",
673 vscc
& (1 << 3) ? "Yes" : "No");
674 printf(" Upper Write Granularity: %d bytes\n",
675 vscc
& (1 << 2) ? 64 : 1);
676 printf(" Upper Block / Sector Erase Size: ");
677 switch (vscc
& 0x3) {
679 printf("256 Byte\n");
693 static void dump_vtba(const vtba_t
*vtba
, int vtl
)
696 int max_len
= sizeof(vtba_t
)/sizeof(vscc_t
);
697 int num
= (vtl
>> 1) < max_len
? (vtl
>> 1) : max_len
;
699 printf("ME VSCC table:\n");
700 for (i
= 0; i
< num
; i
++) {
701 printf(" JID%d: 0x%08x\n", i
, vtba
->entry
[i
].jid
);
702 dump_jid(vtba
->entry
[i
].jid
);
703 printf(" VSCC%d: 0x%08x\n", i
, vtba
->entry
[i
].vscc
);
704 dump_vscc(vtba
->entry
[i
].vscc
);
709 static void dump_oem(const uint8_t *oem
)
712 printf("OEM Section:\n");
713 for (i
= 0; i
< 4; i
++) {
714 printf("%02x:", i
<< 4);
715 for (j
= 0; j
< 16; j
++)
716 printf(" %02x", oem
[(i
<<4)+j
]);
722 static void dump_fd(char *image
, int size
)
724 const fdbar_t
*fdb
= find_fd(image
, size
);
728 printf("ICH Revision: %s\n", ich_chipset_names
[chipset
]);
729 printf("FLMAP0: 0x%08x\n", fdb
->flmap0
);
730 printf(" NR: %d\n", (fdb
->flmap0
>> 24) & 7);
731 printf(" FRBA: 0x%x\n", ((fdb
->flmap0
>> 16) & 0xff) << 4);
732 printf(" NC: %d\n", ((fdb
->flmap0
>> 8) & 3) + 1);
733 printf(" FCBA: 0x%x\n", ((fdb
->flmap0
) & 0xff) << 4);
735 printf("FLMAP1: 0x%08x\n", fdb
->flmap1
);
736 printf(" ISL: 0x%02x\n", (fdb
->flmap1
>> 24) & 0xff);
737 printf(" FPSBA: 0x%x\n", ((fdb
->flmap1
>> 16) & 0xff) << 4);
738 printf(" NM: %d\n", (fdb
->flmap1
>> 8) & 3);
739 printf(" FMBA: 0x%x\n", ((fdb
->flmap1
) & 0xff) << 4);
741 printf("FLMAP2: 0x%08x\n", fdb
->flmap2
);
742 printf(" PSL: 0x%04x\n", (fdb
->flmap2
>> 8) & 0xffff);
743 printf(" FMSBA: 0x%x\n", ((fdb
->flmap2
) & 0xff) << 4);
745 char *flumap
= find_flumap(image
, size
);
746 uint32_t flumap1
= *(uint32_t *)flumap
;
747 printf("FLUMAP1: 0x%08x\n", flumap1
);
748 printf(" Intel ME VSCC Table Length (VTL): %d\n",
749 (flumap1
>> 8) & 0xff);
750 printf(" Intel ME VSCC Table Base Address (VTBA): 0x%06x\n\n",
751 (flumap1
& 0xff) << 4);
753 (image
+ ((flumap1
& 0xff) << 4)),
754 (flumap1
>> 8) & 0xff);
755 dump_oem((const uint8_t *)image
+ 0xf00);
757 const frba_t
*frba
= find_frba(image
, size
);
758 const fcba_t
*fcba
= find_fcba(image
, size
);
759 const fpsba_t
*fpsba
= find_fpsba(image
, size
);
760 const fmba_t
*fmba
= find_fmba(image
, size
);
761 const fmsba_t
*fmsba
= find_fmsba(image
, size
);
763 if (frba
&& fcba
&& fpsba
&& fmba
&& fmsba
) {
770 printf("FD is corrupted!\n");
774 static void dump_layout(char *image
, int size
, const char *layout_fname
)
776 const frba_t
*frba
= find_frba(image
, size
);
780 dump_frba_layout(frba
, layout_fname
);
783 static void write_regions(char *image
, int size
)
786 const frba_t
*frba
= find_frba(image
, size
);
791 for (i
= 0; i
< max_regions
; i
++) {
792 region_t region
= get_region(frba
, i
);
793 dump_region(i
, frba
);
794 if (region
.size
> 0) {
796 region_fd
= open(region_filename(i
),
797 O_WRONLY
| O_CREAT
| O_TRUNC
| O_BINARY
,
798 S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IROTH
);
800 perror("Error while trying to open file");
803 if (write(region_fd
, image
+ region
.base
, region
.size
) != region
.size
)
804 perror("Error while writing");
810 static void validate_layout(char *image
, int size
)
814 long int fmap_loc
= fmap_find((uint8_t *)image
, size
);
815 const frba_t
*frba
= find_frba(image
, size
);
817 if (fmap_loc
< 0 || !frba
)
820 fmap
= (struct fmap
*)(image
+ fmap_loc
);
822 for (i
= 0; i
< max_regions
; i
++) {
823 if (region_names
[i
].fmapname
== NULL
)
826 region_t region
= get_region(frba
, i
);
828 if (region
.size
== 0)
831 const struct fmap_area
*area
=
832 fmap_find_area(fmap
, region_names
[i
].fmapname
);
837 if ((uint
)region
.base
!= area
->offset
||
838 (uint
)region
.size
!= area
->size
) {
839 printf("Region mismatch between %s and %s\n",
840 region_names
[i
].terse
, area
->name
);
841 printf(" Descriptor region %s:\n", region_names
[i
].terse
);
842 printf(" offset: 0x%08x\n", region
.base
);
843 printf(" length: 0x%08x\n", region
.size
);
844 printf(" FMAP area %s:\n", area
->name
);
845 printf(" offset: 0x%08x\n", area
->offset
);
846 printf(" length: 0x%08x\n", area
->size
);
855 static void write_image(const char *filename
, char *image
, int size
)
857 char new_filename
[FILENAME_MAX
]; // allow long file names
860 // - 5: leave room for ".new\0"
861 strncpy(new_filename
, filename
, FILENAME_MAX
- 5);
862 strncat(new_filename
, ".new", FILENAME_MAX
- strlen(filename
));
864 printf("Writing new image to %s\n", new_filename
);
866 // Now write out new image
867 new_fd
= open(new_filename
,
868 O_WRONLY
| O_CREAT
| O_TRUNC
| O_BINARY
,
869 S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IROTH
);
871 perror("Error while trying to open file");
874 if (write(new_fd
, image
, size
) != size
)
875 perror("Error while writing");
879 static void set_spi_frequency(const char *filename
, char *image
, int size
,
880 enum spi_frequency freq
)
882 fcba_t
*fcba
= find_fcba(image
, size
);
886 /* clear bits 21-29 */
887 fcba
->flcomp
&= ~0x3fe00000;
888 /* Read ID and Read Status Clock Frequency */
889 fcba
->flcomp
|= freq
<< 27;
890 /* Write and Erase Clock Frequency */
891 fcba
->flcomp
|= freq
<< 24;
892 /* Fast Read Clock Frequency */
893 fcba
->flcomp
|= freq
<< 21;
895 write_image(filename
, image
, size
);
898 static void set_em100_mode(const char *filename
, char *image
, int size
)
900 fcba_t
*fcba
= find_fcba(image
, size
);
906 switch (ifd_version
) {
908 freq
= SPI_FREQUENCY_20MHZ
;
911 freq
= SPI_FREQUENCY_17MHZ
;
914 freq
= SPI_FREQUENCY_17MHZ
;
918 fcba
->flcomp
&= ~(1 << 30);
919 set_spi_frequency(filename
, image
, size
, freq
);
922 static void set_chipdensity(const char *filename
, char *image
, int size
,
923 unsigned int density
)
925 fcba_t
*fcba
= find_fcba(image
, size
);
926 uint8_t mask
, chip2_offset
;
930 printf("Setting chip density to ");
931 decode_component_density(density
);
934 switch (ifd_version
) {
936 /* fail if selected density is not supported by this version */
937 if ( (density
== COMPONENT_DENSITY_32MB
) ||
938 (density
== COMPONENT_DENSITY_64MB
) ||
939 (density
== COMPONENT_DENSITY_UNUSED
) ) {
940 printf("error: Selected density not supported in IFD version 1.\n");
951 printf("error: Unknown IFD version\n");
956 /* clear chip density for corresponding chip */
957 switch (selected_chip
) {
959 fcba
->flcomp
&= ~mask
;
962 fcba
->flcomp
&= ~(mask
<< chip2_offset
);
964 default: /*both chips*/
965 fcba
->flcomp
&= ~(mask
| (mask
<< chip2_offset
));
969 /* set the new density */
970 if (selected_chip
== 1 || selected_chip
== 0)
971 fcba
->flcomp
|= (density
); /* first chip */
972 if (selected_chip
== 2 || selected_chip
== 0)
973 fcba
->flcomp
|= (density
<< chip2_offset
); /* second chip */
975 write_image(filename
, image
, size
);
978 static int check_region(const frba_t
*frba
, unsigned int region_type
)
985 region
= get_region(frba
, region_type
);
986 return !!((region
.base
< region
.limit
) && (region
.size
> 0));
989 static void lock_descriptor(const char *filename
, char *image
, int size
)
991 int wr_shift
, rd_shift
;
992 fmba_t
*fmba
= find_fmba(image
, size
);
993 const frba_t
*frba
= find_frba(image
, size
);
997 if (ifd_version
>= IFD_VERSION_2
) {
998 wr_shift
= FLMSTR_WR_SHIFT_V2
;
999 rd_shift
= FLMSTR_RD_SHIFT_V2
;
1001 /* Clear non-reserved bits */
1002 fmba
->flmstr1
&= 0xff;
1003 fmba
->flmstr2
&= 0xff;
1004 fmba
->flmstr3
&= 0xff;
1005 fmba
->flmstr5
&= 0xff;
1007 wr_shift
= FLMSTR_WR_SHIFT_V1
;
1008 rd_shift
= FLMSTR_RD_SHIFT_V1
;
1013 fmba
->flmstr3
= 0x118;
1019 /* CPU/BIOS can read descriptor and BIOS */
1020 fmba
->flmstr1
|= 0x3 << rd_shift
;
1021 /* CPU/BIOS can write BIOS */
1022 fmba
->flmstr1
|= 0x2 << wr_shift
;
1023 /* TXE can read descriptor, BIOS and Device Expansion */
1024 fmba
->flmstr2
|= 0x23 << rd_shift
;
1025 /* TXE can only write Device Expansion */
1026 fmba
->flmstr2
|= 0x20 << wr_shift
;
1030 case PLATFORM_SKLKBL
:
1032 /* CPU/BIOS can read descriptor and BIOS. */
1033 fmba
->flmstr1
|= (1 << REGION_DESC
) << rd_shift
;
1034 fmba
->flmstr1
|= (1 << REGION_BIOS
) << rd_shift
;
1035 /* CPU/BIOS can write BIOS. */
1036 fmba
->flmstr1
|= (1 << REGION_BIOS
) << wr_shift
;
1037 /* ME can read descriptor and ME. */
1038 fmba
->flmstr2
|= (1 << REGION_DESC
) << rd_shift
;
1039 fmba
->flmstr2
|= (1 << REGION_ME
) << rd_shift
;
1040 /* ME can write ME. */
1041 fmba
->flmstr2
|= (1 << REGION_ME
) << wr_shift
;
1042 if (check_region(frba
, REGION_GBE
)) {
1043 /* BIOS can read/write GbE. */
1044 fmba
->flmstr1
|= (1 << REGION_GBE
) << rd_shift
;
1045 fmba
->flmstr1
|= (1 << REGION_GBE
) << wr_shift
;
1046 /* ME can read GbE. */
1047 fmba
->flmstr2
|= (1 << REGION_GBE
) << rd_shift
;
1048 /* GbE can read descriptor and read/write GbE.. */
1049 fmba
->flmstr3
|= (1 << REGION_DESC
) << rd_shift
;
1050 fmba
->flmstr3
|= (1 << REGION_GBE
) << rd_shift
;
1051 fmba
->flmstr3
|= (1 << REGION_GBE
) << wr_shift
;
1053 if (check_region(frba
, REGION_PDR
)) {
1054 /* BIOS can read/write PDR. */
1055 fmba
->flmstr1
|= (1 << REGION_PDR
) << rd_shift
;
1056 fmba
->flmstr1
|= (1 << REGION_PDR
) << wr_shift
;
1058 if (check_region(frba
, REGION_EC
)) {
1059 /* BIOS can read EC. */
1060 fmba
->flmstr1
|= (1 << REGION_EC
) << rd_shift
;
1061 /* EC can read descriptor and read/write EC. */
1062 fmba
->flmstr5
|= (1 << REGION_DESC
) << rd_shift
;
1063 fmba
->flmstr5
|= (1 << REGION_EC
) << rd_shift
;
1064 fmba
->flmstr5
|= (1 << REGION_EC
) << wr_shift
;
1068 /* CPU/BIOS can read descriptor and BIOS. */
1069 fmba
->flmstr1
|= (1 << REGION_DESC
) << rd_shift
;
1070 fmba
->flmstr1
|= (1 << REGION_BIOS
) << rd_shift
;
1071 /* CPU/BIOS can write BIOS. */
1072 fmba
->flmstr1
|= (1 << REGION_BIOS
) << wr_shift
;
1073 /* ME can read descriptor and ME. */
1074 fmba
->flmstr2
|= (1 << REGION_DESC
) << rd_shift
;
1075 fmba
->flmstr2
|= (1 << REGION_ME
) << rd_shift
;
1076 /* ME can write ME. */
1077 fmba
->flmstr2
|= (1 << REGION_ME
) << wr_shift
;
1078 if (check_region(frba
, REGION_GBE
)) {
1079 /* BIOS can read GbE. */
1080 fmba
->flmstr1
|= (1 << REGION_GBE
) << rd_shift
;
1081 /* BIOS can write GbE. */
1082 fmba
->flmstr1
|= (1 << REGION_GBE
) << wr_shift
;
1083 /* ME can read GbE. */
1084 fmba
->flmstr2
|= (1 << REGION_GBE
) << rd_shift
;
1085 /* ME can write GbE. */
1086 fmba
->flmstr2
|= (1 << REGION_GBE
) << wr_shift
;
1087 /* GbE can write GbE. */
1088 fmba
->flmstr3
|= (1 << REGION_GBE
) << rd_shift
;
1089 /* GbE can read GbE. */
1090 fmba
->flmstr3
|= (1 << REGION_GBE
) << wr_shift
;
1095 write_image(filename
, image
, size
);
1098 static void unlock_descriptor(const char *filename
, char *image
, int size
)
1100 fmba_t
*fmba
= find_fmba(image
, size
);
1104 if (ifd_version
>= IFD_VERSION_2
) {
1105 /* Access bits for each region are read: 19:8 write: 31:20 */
1106 fmba
->flmstr1
= 0xffffff00 | (fmba
->flmstr1
& 0xff);
1107 fmba
->flmstr2
= 0xffffff00 | (fmba
->flmstr2
& 0xff);
1108 fmba
->flmstr3
= 0xffffff00 | (fmba
->flmstr3
& 0xff);
1109 fmba
->flmstr5
= 0xffffff00 | (fmba
->flmstr5
& 0xff);
1111 fmba
->flmstr1
= 0xffff0000;
1112 fmba
->flmstr2
= 0xffff0000;
1113 /* Keep chipset specific Requester ID */
1114 fmba
->flmstr3
= 0x08080000 | (fmba
->flmstr3
& 0xffff);
1117 write_image(filename
, image
, size
);
1120 /* Set the AltMeDisable (or HAP for >= IFD_VERSION_2) */
1121 static void fpsba_set_altmedisable(fpsba_t
*fpsba
, fmsba_t
*fmsba
, bool altmedisable
)
1123 if (ifd_version
>= IFD_VERSION_2
) {
1124 printf("%sting the HAP bit to %s Intel ME...\n",
1125 altmedisable
?"Set":"Unset",
1126 altmedisable
?"disable":"enable");
1128 fpsba
->pchstrp
[0] |= (1 << 16);
1130 fpsba
->pchstrp
[0] &= ~(1 << 16);
1132 if (chipset
>= CHIPSET_ICH8
&& chipset
<= CHIPSET_ICH10
) {
1133 printf("%sting the ICH_MeDisable, MCH_MeDisable, "
1134 "and MCH_AltMeDisable to %s Intel ME...\n",
1135 altmedisable
?"Set":"Unset",
1136 altmedisable
?"disable":"enable");
1139 fmsba
->data
[0] |= 1;
1140 /* MCH_AltMeDisable */
1141 fmsba
->data
[0] |= (1 << 7);
1143 fpsba
->pchstrp
[0] |= 1;
1145 fmsba
->data
[0] &= ~1;
1146 fmsba
->data
[0] &= ~(1 << 7);
1147 fpsba
->pchstrp
[0] &= ~1;
1150 printf("%sting the AltMeDisable to %s Intel ME...\n",
1151 altmedisable
?"Set":"Unset",
1152 altmedisable
?"disable":"enable");
1154 fpsba
->pchstrp
[10] |= (1 << 7);
1156 fpsba
->pchstrp
[10] &= ~(1 << 7);
1161 static void inject_region(const char *filename
, char *image
, int size
,
1162 unsigned int region_type
, const char *region_fname
)
1164 frba_t
*frba
= find_frba(image
, size
);
1168 region_t region
= get_region(frba
, region_type
);
1169 if (region
.size
<= 0xfff) {
1170 fprintf(stderr
, "Region %s is disabled in target. Not injecting.\n",
1171 region_name(region_type
));
1175 int region_fd
= open(region_fname
, O_RDONLY
| O_BINARY
);
1176 if (region_fd
== -1) {
1177 perror("Could not open file");
1181 if (fstat(region_fd
, &buf
) == -1) {
1182 perror("Could not stat file");
1185 int region_size
= buf
.st_size
;
1187 printf("File %s is %d bytes\n", region_fname
, region_size
);
1189 if ( (region_size
> region
.size
) || ((region_type
!= 1) &&
1190 (region_size
> region
.size
))) {
1191 fprintf(stderr
, "Region %s is %d(0x%x) bytes. File is %d(0x%x)"
1192 " bytes. Not injecting.\n",
1193 region_name(region_type
), region
.size
,
1194 region
.size
, region_size
, region_size
);
1199 if ((region_type
== 1) && (region_size
< region
.size
)) {
1200 fprintf(stderr
, "Region %s is %d(0x%x) bytes. File is %d(0x%x)"
1201 " bytes. Padding before injecting.\n",
1202 region_name(region_type
), region
.size
,
1203 region
.size
, region_size
, region_size
);
1204 offset
= region
.size
- region_size
;
1205 memset(image
+ region
.base
, 0xff, offset
);
1208 if (size
< region
.base
+ offset
+ region_size
) {
1209 fprintf(stderr
, "Output file is too small. (%d < %d)\n",
1210 size
, region
.base
+ offset
+ region_size
);
1214 if (read(region_fd
, image
+ region
.base
+ offset
, region_size
)
1216 perror("Could not read file");
1222 printf("Adding %s as the %s section of %s\n",
1223 region_fname
, region_name(region_type
), filename
);
1224 write_image(filename
, image
, size
);
1227 static unsigned int next_pow2(unsigned int x
)
1239 * Determine if two memory regions overlap.
1241 * @param r1, r2 Memory regions to compare.
1242 * @return 0 if the two regions are separate
1243 * @return 1 if the two regions overlap
1245 static int regions_collide(const region_t
*r1
, const region_t
*r2
)
1247 if ((r1
->size
== 0) || (r2
->size
== 0))
1250 /* r1 should be either completely below or completely above r2 */
1251 return !(r1
->limit
< r2
->base
|| r1
->base
> r2
->limit
);
1254 static void new_layout(const char *filename
, char *image
, int size
,
1255 const char *layout_fname
)
1259 char layout_region_name
[256];
1262 region_t current_regions
[MAX_REGIONS
];
1263 region_t new_regions
[MAX_REGIONS
];
1267 /* load current descriptor map and regions */
1268 frba_t
*frba
= find_frba(image
, size
);
1272 for (i
= 0; i
< max_regions
; i
++) {
1273 current_regions
[i
] = get_region(frba
, i
);
1274 new_regions
[i
] = get_region(frba
, i
);
1277 /* read new layout */
1278 romlayout
= fopen(layout_fname
, "r");
1281 perror("Could not read layout file.\n");
1285 while (!feof(romlayout
)) {
1286 char *tstr1
, *tstr2
;
1288 if (2 != fscanf(romlayout
, "%255s %255s\n", tempstr
,
1289 layout_region_name
))
1292 region_number
= region_num(layout_region_name
);
1293 if (region_number
< 0)
1296 tstr1
= strtok(tempstr
, ":");
1297 tstr2
= strtok(NULL
, ":");
1298 if (!tstr1
|| !tstr2
) {
1299 fprintf(stderr
, "Could not parse layout file.\n");
1302 new_regions
[region_number
].base
= strtol(tstr1
,
1304 new_regions
[region_number
].limit
= strtol(tstr2
,
1306 new_regions
[region_number
].size
=
1307 new_regions
[region_number
].limit
-
1308 new_regions
[region_number
].base
+ 1;
1310 if (new_regions
[region_number
].size
< 0)
1311 new_regions
[region_number
].size
= 0;
1315 /* check new layout */
1316 for (i
= 0; i
< max_regions
; i
++) {
1317 if (new_regions
[i
].size
== 0)
1320 if (new_regions
[i
].size
< current_regions
[i
].size
) {
1321 printf("DANGER: Region %s is shrinking.\n",
1323 printf(" The region will be truncated to fit.\n");
1324 printf(" This may result in an unusable image.\n");
1327 for (j
= i
+ 1; j
< max_regions
; j
++) {
1328 if (regions_collide(&new_regions
[i
], &new_regions
[j
])) {
1329 fprintf(stderr
, "Regions would overlap.\n");
1334 /* detect if the image size should grow */
1335 if (new_extent
< new_regions
[i
].limit
)
1336 new_extent
= new_regions
[i
].limit
;
1339 new_extent
= next_pow2(new_extent
- 1);
1340 if (new_extent
!= size
) {
1341 printf("The image has changed in size.\n");
1342 printf("The old image is %d bytes.\n", size
);
1343 printf("The new image is %d bytes.\n", new_extent
);
1346 /* copy regions to a new image */
1347 new_image
= malloc(new_extent
);
1348 memset(new_image
, 0xff, new_extent
);
1349 for (i
= 0; i
< max_regions
; i
++) {
1350 int copy_size
= new_regions
[i
].size
;
1351 int offset_current
= 0, offset_new
= 0;
1352 const region_t
*current
= ¤t_regions
[i
];
1353 const region_t
*new = &new_regions
[i
];
1358 if (new->size
> current
->size
) {
1359 /* copy from the end of the current region */
1360 copy_size
= current
->size
;
1361 offset_new
= new->size
- current
->size
;
1364 if (new->size
< current
->size
) {
1365 /* copy to the end of the new region */
1366 offset_current
= current
->size
- new->size
;
1369 printf("Copy Descriptor %d (%s) (%d bytes)\n", i
,
1370 region_name(i
), copy_size
);
1371 printf(" from %08x+%08x:%08x (%10d)\n", current
->base
,
1372 offset_current
, current
->limit
, current
->size
);
1373 printf(" to %08x+%08x:%08x (%10d)\n", new->base
,
1374 offset_new
, new->limit
, new->size
);
1376 memcpy(new_image
+ new->base
+ offset_new
,
1377 image
+ current
->base
+ offset_current
,
1381 /* update new descriptor regions */
1382 frba
= find_frba(new_image
, new_extent
);
1386 for (i
= 1; i
< max_regions
; i
++)
1387 set_region(frba
, i
, &new_regions
[i
]);
1389 write_image(filename
, new_image
, new_extent
);
1393 static void print_version(void)
1395 printf("ifdtool v%s -- ", IFDTOOL_VERSION
);
1396 printf("Copyright (C) 2011 Google Inc.\n\n");
1398 ("This program is free software: you can redistribute it and/or modify\n"
1399 "it under the terms of the GNU General Public License as published by\n"
1400 "the Free Software Foundation, version 2 of the License.\n\n"
1401 "This program is distributed in the hope that it will be useful,\n"
1402 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
1403 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
1404 "GNU General Public License for more details.\n\n");
1407 static void print_usage(const char *name
)
1409 printf("usage: %s [-vhdix?] <filename>\n", name
);
1411 " -d | --dump: dump intel firmware descriptor\n"
1412 " -f | --layout <filename> dump regions into a flashrom layout file\n"
1413 " -t | --validate Validate that the firmware descriptor layout matches the fmap layout\n"
1414 " -x | --extract: extract intel fd modules\n"
1415 " -i | --inject <region>:<module> inject file <module> into region <region>\n"
1416 " -n | --newlayout <filename> update regions using a flashrom layout file\n"
1417 " -s | --spifreq <17|20|30|33|48|50> set the SPI frequency\n"
1418 " -D | --density <512|1|2|4|8|16|32|64> set chip density (512 in KByte, others in MByte)\n"
1419 " -C | --chip <0|1|2> select spi chip on which to operate\n"
1420 " can only be used once per run:\n"
1421 " 0 - both chips (default), 1 - first chip, 2 - second chip\n"
1422 " -e | --em100 set SPI frequency to 20MHz and disable\n"
1423 " Dual Output Fast Read Support\n"
1424 " -l | --lock Lock firmware descriptor and ME region\n"
1425 " -u | --unlock Unlock firmware descriptor and ME region\n"
1426 " -M | --altmedisable <0|1> Set the AltMeDisable (or HAP for skylake or newer platform)\n"
1427 " bit to disable ME\n"
1428 " -p | --platform Add platform-specific quirks\n"
1429 " aplk - Apollo Lake\n"
1430 " cnl - Cannon Lake\n"
1431 " glk - Gemini Lake\n"
1432 " sklkbl - Skylake/Kaby Lake\n"
1433 " -v | --version: print the version\n"
1434 " -h | --help: print this help\n\n"
1435 "<region> is one of Descriptor, BIOS, ME, GbE, Platform\n"
1439 int main(int argc
, char *argv
[])
1441 int opt
, option_index
= 0;
1442 int mode_dump
= 0, mode_extract
= 0, mode_inject
= 0, mode_spifreq
= 0;
1443 int mode_em100
= 0, mode_locked
= 0, mode_unlocked
= 0, mode_validate
= 0;
1444 int mode_layout
= 0, mode_newlayout
= 0, mode_density
= 0;
1445 int mode_altmedisable
= 0, altmedisable
= 0;
1446 char *region_type_string
= NULL
, *region_fname
= NULL
;
1447 const char *layout_fname
= NULL
;
1448 int region_type
= -1, inputfreq
= 0;
1449 unsigned int new_density
= 0;
1450 enum spi_frequency spifreq
= SPI_FREQUENCY_20MHZ
;
1452 static const struct option long_options
[] = {
1453 {"dump", 0, NULL
, 'd'},
1454 {"layout", 1, NULL
, 'f'},
1455 {"extract", 0, NULL
, 'x'},
1456 {"inject", 1, NULL
, 'i'},
1457 {"newlayout", 1, NULL
, 'n'},
1458 {"spifreq", 1, NULL
, 's'},
1459 {"density", 1, NULL
, 'D'},
1460 {"chip", 1, NULL
, 'C'},
1461 {"altmedisable", 1, NULL
, 'M'},
1462 {"em100", 0, NULL
, 'e'},
1463 {"lock", 0, NULL
, 'l'},
1464 {"unlock", 0, NULL
, 'u'},
1465 {"version", 0, NULL
, 'v'},
1466 {"help", 0, NULL
, 'h'},
1467 {"platform", 0, NULL
, 'p'},
1468 {"validate", 0, NULL
, 't'},
1472 while ((opt
= getopt_long(argc
, argv
, "df:D:C:M:xi:n:s:p:eluvth?",
1473 long_options
, &option_index
)) != EOF
) {
1480 layout_fname
= strdup(optarg
);
1481 if (!layout_fname
) {
1482 fprintf(stderr
, "No layout file specified\n");
1483 print_usage(argv
[0]);
1491 // separate type and file name
1492 region_type_string
= strdup(optarg
);
1493 region_fname
= strchr(region_type_string
, ':');
1494 if (!region_fname
) {
1495 print_usage(argv
[0]);
1498 region_fname
[0] = '\0';
1500 // Descriptor, BIOS, ME, GbE, Platform
1502 if (!strcasecmp("Descriptor", region_type_string
))
1504 else if (!strcasecmp("BIOS", region_type_string
))
1506 else if (!strcasecmp("ME", region_type_string
))
1508 else if (!strcasecmp("GbE", region_type_string
))
1510 else if (!strcasecmp("Platform", region_type_string
))
1512 else if (!strcasecmp("EC", region_type_string
))
1514 if (region_type
== -1) {
1515 fprintf(stderr
, "No such region type: '%s'\n\n",
1516 region_type_string
);
1517 print_usage(argv
[0]);
1524 layout_fname
= strdup(optarg
);
1525 if (!layout_fname
) {
1526 fprintf(stderr
, "No layout file specified\n");
1527 print_usage(argv
[0]);
1533 new_density
= strtoul(optarg
, NULL
, 0);
1534 switch (new_density
) {
1536 new_density
= COMPONENT_DENSITY_512KB
;
1539 new_density
= COMPONENT_DENSITY_1MB
;
1542 new_density
= COMPONENT_DENSITY_2MB
;
1545 new_density
= COMPONENT_DENSITY_4MB
;
1548 new_density
= COMPONENT_DENSITY_8MB
;
1551 new_density
= COMPONENT_DENSITY_16MB
;
1554 new_density
= COMPONENT_DENSITY_32MB
;
1557 new_density
= COMPONENT_DENSITY_64MB
;
1560 new_density
= COMPONENT_DENSITY_UNUSED
;
1563 printf("error: Unknown density\n");
1564 print_usage(argv
[0]);
1569 selected_chip
= strtol(optarg
, NULL
, 0);
1570 if (selected_chip
> 2) {
1571 fprintf(stderr
, "error: Invalid chip selection\n");
1572 print_usage(argv
[0]);
1577 mode_altmedisable
= 1;
1578 altmedisable
= strtol(optarg
, NULL
, 0);
1579 if (altmedisable
> 1) {
1580 fprintf(stderr
, "error: Illegal value\n");
1581 print_usage(argv
[0]);
1586 // Parse the requested SPI frequency
1587 inputfreq
= strtol(optarg
, NULL
, 0);
1588 switch (inputfreq
) {
1590 spifreq
= SPI_FREQUENCY_17MHZ
;
1593 spifreq
= SPI_FREQUENCY_20MHZ
;
1596 spifreq
= SPI_FREQUENCY_50MHZ_30MHZ
;
1599 spifreq
= SPI_FREQUENCY_33MHZ
;
1602 spifreq
= SPI_FREQUENCY_48MHZ
;
1605 spifreq
= SPI_FREQUENCY_50MHZ_30MHZ
;
1608 fprintf(stderr
, "Invalid SPI Frequency: %d\n",
1610 print_usage(argv
[0]);
1620 if (mode_unlocked
== 1) {
1621 fprintf(stderr
, "Locking/Unlocking FD and ME are mutually exclusive\n");
1627 if (mode_locked
== 1) {
1628 fprintf(stderr
, "Locking/Unlocking FD and ME are mutually exclusive\n");
1633 if (!strcmp(optarg
, "aplk")) {
1634 platform
= PLATFORM_APL
;
1635 } else if (!strcmp(optarg
, "cnl")) {
1636 platform
= PLATFORM_CNL
;
1637 } else if (!strcmp(optarg
, "glk")) {
1638 platform
= PLATFORM_GLK
;
1639 } else if (!strcmp(optarg
, "icl")) {
1640 platform
= PLATFORM_ICL
;
1641 } else if (!strcmp(optarg
, "jsl")) {
1642 platform
= PLATFORM_JSL
;
1643 } else if (!strcmp(optarg
, "sklkbl")) {
1644 platform
= PLATFORM_SKLKBL
;
1645 } else if (!strcmp(optarg
, "tgl")) {
1646 platform
= PLATFORM_TGL
;
1648 fprintf(stderr
, "Unknown platform: %s\n", optarg
);
1651 fprintf(stderr
, "Platform is: %s\n", optarg
);
1663 print_usage(argv
[0]);
1669 if ((mode_dump
+ mode_layout
+ mode_extract
+ mode_inject
+
1670 mode_newlayout
+ (mode_spifreq
| mode_em100
| mode_unlocked
|
1671 mode_locked
) + mode_altmedisable
+ mode_validate
) > 1) {
1672 fprintf(stderr
, "You may not specify more than one mode.\n\n");
1673 print_usage(argv
[0]);
1677 if ((mode_dump
+ mode_layout
+ mode_extract
+ mode_inject
+
1678 mode_newlayout
+ mode_spifreq
+ mode_em100
+ mode_locked
+
1679 mode_unlocked
+ mode_density
+ mode_altmedisable
+ mode_validate
) == 0) {
1680 fprintf(stderr
, "You need to specify a mode.\n\n");
1681 print_usage(argv
[0]);
1685 if (optind
+ 1 != argc
) {
1686 fprintf(stderr
, "You need to specify a file.\n\n");
1687 print_usage(argv
[0]);
1691 char *filename
= argv
[optind
];
1692 int bios_fd
= open(filename
, O_RDONLY
| O_BINARY
);
1693 if (bios_fd
== -1) {
1694 perror("Could not open file");
1698 if (fstat(bios_fd
, &buf
) == -1) {
1699 perror("Could not stat file");
1702 int size
= buf
.st_size
;
1704 printf("File %s is %d bytes\n", filename
, size
);
1706 char *image
= malloc(size
);
1708 printf("Out of memory.\n");
1712 if (read(bios_fd
, image
, size
) != size
) {
1713 perror("Could not read file");
1719 check_ifd_version(image
, size
);
1722 dump_fd(image
, size
);
1725 dump_layout(image
, size
, layout_fname
);
1728 write_regions(image
, size
);
1731 validate_layout(image
, size
);
1734 inject_region(filename
, image
, size
, region_type
,
1738 new_layout(filename
, image
, size
, layout_fname
);
1741 set_spi_frequency(filename
, image
, size
, spifreq
);
1744 set_chipdensity(filename
, image
, size
, new_density
);
1747 set_em100_mode(filename
, image
, size
);
1750 lock_descriptor(filename
, image
, size
);
1753 unlock_descriptor(filename
, image
, size
);
1755 if (mode_altmedisable
) {
1756 fpsba_t
*fpsba
= find_fpsba(image
, size
);
1757 fmsba_t
*fmsba
= find_fmsba(image
, size
);
1758 fpsba_set_altmedisable(fpsba
, fmsba
, altmedisable
);
1759 write_image(filename
, image
, size
);