nb/intel/sandybridge: Make `PM_PDWN_Config` uppercase
[coreboot.git] / util / ifdtool / ifdtool.c
bloba59f36b8869bfadd79ff2de6a8b3f2a871966cf7
1 /*
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.
16 #include <unistd.h>
17 #include <stdlib.h>
18 #include <stdio.h>
19 #include <string.h>
20 #include <getopt.h>
21 #include <fcntl.h>
22 #include <sys/types.h>
23 #include <sys/stat.h>
24 #include <commonlib/helpers.h>
25 #include <fmap.h>
26 #include "ifdtool.h"
28 #ifndef O_BINARY
29 #define O_BINARY 0
30 #endif
32 /**
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;
44 static int chipset;
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[] = {
63 "Unknown ICH",
64 "ICH",
65 "ICH2345",
66 "ICH6",
67 "SCH U",
68 "Atom E6xx",
69 "Atom S1220 S1240 S1260",
70 "ICH7",
71 "ICH8",
72 "ICH9",
73 "ICH10",
74 "5 series Ibex Peak",
75 "6 series Cougar Point",
76 "7 series Panther Point",
77 "8 series Lynx Point",
78 "Baytrail",
79 "8 series Lynx Point LP",
80 "8 series Wellsburg",
81 "9 series Wildcat Point",
82 "9 series Wildcat Point LP",
83 "100 series Sunrise Point",
84 "C620 series Lewisburg",
85 NULL
88 static fdbar_t *find_fd(char *image, int size)
90 int i, found = 0;
92 /* Scan for FD signature */
93 for (i = 0; i < (size - 4); i += 4) {
94 if (*(uint32_t *) (image + i) == 0x0FF0A55A) {
95 found = 1;
96 break; // signature found.
100 if (!found) {
101 printf("No Flash Descriptor found in this image\n");
102 return NULL;
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
118 * works.
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);
127 if (!fdb)
128 return NULL;
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);
137 if (!fdb)
138 return NULL;
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);
146 if (!fdb)
147 return NULL;
148 frba_t *frba =
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);
156 if (!fdb)
157 return NULL;
158 fpsba_t *fpsba =
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);
166 if (!fdb)
167 return NULL;
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)
182 return CHIPSET_ICH8;
183 else if (isl <= 2)
184 return CHIPSET_ICH9;
185 else if (isl <= 10)
186 return CHIPSET_ICH10;
187 else if (isl <= 16)
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;
202 } else {
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[] = {
216 PLATFORM_GLK,
217 PLATFORM_CNL,
218 PLATFORM_ICL,
219 PLATFORM_TGL,
220 PLATFORM_JSL,
222 unsigned int i;
224 for (i = 0; i < ARRAY_SIZE(ifd_2_platforms); i++) {
225 if (platform == ifd_2_platforms[i])
226 return 1;
229 return 0;
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)
239 int read_freq;
240 const fcba_t *fcba = find_fcba(image, size);
241 const fdbar_t *fdb = find_fd(image, size);
242 if (!fcba || !fdb)
243 exit(EXIT_FAILURE);
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;
251 switch (read_freq) {
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;
257 default:
258 fprintf(stderr, "Unknown descriptor version: %d\n",
259 read_freq);
260 exit(EXIT_FAILURE);
264 static void check_ifd_version(char *image, int size)
266 if (is_platform_ifd_2())
267 ifd_version = IFD_VERSION_2;
268 else
269 ifd_version = get_ifd_version_from_fcba(image, size);
271 if (ifd_version == IFD_VERSION_1)
272 max_regions = MAX_REGIONS_OLD;
273 else
274 max_regions = MAX_REGIONS;
277 static region_t get_region(const frba_t *frba, unsigned int region_type)
279 int base_mask;
280 int limit_mask;
281 uint32_t flreg;
282 region_t region;
284 if (ifd_version >= IFD_VERSION_2)
285 base_mask = 0x7fff;
286 else
287 base_mask = 0xfff;
289 limit_mask = base_mask << 16;
291 if (region_type >= max_regions) {
292 fprintf(stderr, "Invalid region type %d.\n", region_type);
293 exit (EXIT_FAILURE);
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;
301 if (region.size < 0)
302 region.size = 0;
304 return region;
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);
312 exit (EXIT_FAILURE);
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");
324 exit (EXIT_FAILURE);
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");
334 exit (EXIT_FAILURE);
337 return region_names[region_type].terse;
340 static int region_num(const char *name)
342 unsigned int i;
344 for (i = 0; i < max_regions; i++) {
345 if (strcasecmp(name, region_names[i].pretty) == 0)
346 return i;
347 if (strcasecmp(name, region_names[i].terse) == 0)
348 return i;
351 return -1;
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);
358 exit (EXIT_FAILURE);
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,
373 const frba_t *frba)
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)
382 unsigned int i;
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;
394 unsigned int i;
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");
400 exit(EXIT_FAILURE);
403 for (i = 0; i < max_regions; i++) {
404 region_t region = get_region(frba, i);
405 /* is region invalid? */
406 if (region.size < 1)
407 continue;
409 dump_region_layout(buf, bufsize, i, frba);
410 if (write(layout_fd, buf, strlen(buf)) < 0) {
411 perror("Could not write to file");
412 exit(EXIT_FAILURE);
415 close(layout_fd);
416 printf("Wrote layout to %s\n", layout_fname);
419 static void decode_spi_frequency(unsigned int freq)
421 switch (freq) {
422 case SPI_FREQUENCY_20MHZ:
423 printf("20MHz");
424 break;
425 case SPI_FREQUENCY_33MHZ:
426 printf("33MHz");
427 break;
428 case SPI_FREQUENCY_48MHZ:
429 printf("48MHz");
430 break;
431 case SPI_FREQUENCY_50MHZ_30MHZ:
432 switch (ifd_version) {
433 case IFD_VERSION_1:
434 printf("50MHz");
435 break;
436 case IFD_VERSION_2:
437 printf("30MHz");
438 break;
440 break;
441 case SPI_FREQUENCY_17MHZ:
442 printf("17MHz");
443 break;
444 default:
445 printf("unknown<%x>MHz", freq);
449 static void decode_component_density(unsigned int density)
451 switch (density) {
452 case COMPONENT_DENSITY_512KB:
453 printf("512KB");
454 break;
455 case COMPONENT_DENSITY_1MB:
456 printf("1MB");
457 break;
458 case COMPONENT_DENSITY_2MB:
459 printf("2MB");
460 break;
461 case COMPONENT_DENSITY_4MB:
462 printf("4MB");
463 break;
464 case COMPONENT_DENSITY_8MB:
465 printf("8MB");
466 break;
467 case COMPONENT_DENSITY_16MB:
468 printf("16MB");
469 break;
470 case COMPONENT_DENSITY_32MB:
471 printf("32MB");
472 break;
473 case COMPONENT_DENSITY_64MB:
474 printf("64MB");
475 break;
476 case COMPONENT_DENSITY_UNUSED:
477 printf("UNUSED");
478 break;
479 default:
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) {
502 case IFD_VERSION_1:
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);
507 break;
508 case IFD_VERSION_2:
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);
513 break;
516 printf("\n");
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",
525 fcba->flill & 0xff);
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)
533 unsigned int i;
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 ");
546 } else {
547 printf("AltMeDisable bit is %sset\n",
548 fpsba->pchstrp[10] & (1 << 7) ? "" : "not ");
551 printf("\n");
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;
560 } else {
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",
599 flmstr & 0xffff);
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)
619 unsigned int i;
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",
635 jid & 0xff);
636 printf(" SPI Componend Device ID 0: 0x%02x\n",
637 (jid >> 8) & 0xff);
638 printf(" SPI Componend Device ID 1: 0x%02x\n",
639 (jid >> 16) & 0xff);
642 static void dump_vscc(uint32_t vscc)
644 printf(" Lower Erase Opcode: 0x%02x\n",
645 vscc >> 24);
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) {
654 case 0:
655 printf("256 Byte\n");
656 break;
657 case 1:
658 printf("4KB\n");
659 break;
660 case 2:
661 printf("8KB\n");
662 break;
663 case 3:
664 printf("64KB\n");
665 break;
668 printf(" Upper Erase Opcode: 0x%02x\n",
669 (vscc >> 8) & 0xff);
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) {
678 case 0:
679 printf("256 Byte\n");
680 break;
681 case 1:
682 printf("4KB\n");
683 break;
684 case 2:
685 printf("8KB\n");
686 break;
687 case 3:
688 printf("64KB\n");
689 break;
693 static void dump_vtba(const vtba_t *vtba, int vtl)
695 int i;
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);
706 printf("\n");
709 static void dump_oem(const uint8_t *oem)
711 int i, j;
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]);
717 printf ("\n");
719 printf ("\n");
722 static void dump_fd(char *image, int size)
724 const fdbar_t *fdb = find_fd(image, size);
725 if (!fdb)
726 exit(EXIT_FAILURE);
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);
752 dump_vtba((vtba_t *)
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) {
764 dump_frba(frba);
765 dump_fcba(fcba);
766 dump_fpsba(fpsba);
767 dump_fmba(fmba);
768 dump_fmsba(fmsba);
769 } else {
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);
777 if (!frba)
778 exit(EXIT_FAILURE);
780 dump_frba_layout(frba, layout_fname);
783 static void write_regions(char *image, int size)
785 unsigned int i;
786 const frba_t *frba = find_frba(image, size);
788 if (!frba)
789 exit(EXIT_FAILURE);
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) {
795 int region_fd;
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);
799 if (region_fd < 0) {
800 perror("Error while trying to open file");
801 exit(EXIT_FAILURE);
803 if (write(region_fd, image + region.base, region.size) != region.size)
804 perror("Error while writing");
805 close(region_fd);
810 static void validate_layout(char *image, int size)
812 uint i, errors = 0;
813 struct fmap *fmap;
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)
818 exit(EXIT_FAILURE);
820 fmap = (struct fmap *)(image + fmap_loc);
822 for (i = 0; i < max_regions; i++) {
823 if (region_names[i].fmapname == NULL)
824 continue;
826 region_t region = get_region(frba, i);
828 if (region.size == 0)
829 continue;
831 const struct fmap_area *area =
832 fmap_find_area(fmap, region_names[i].fmapname);
834 if (!area)
835 continue;
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);
847 errors++;
851 if (errors > 0)
852 exit(EXIT_FAILURE);
855 static void write_image(const char *filename, char *image, int size)
857 char new_filename[FILENAME_MAX]; // allow long file names
858 int new_fd;
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);
870 if (new_fd < 0) {
871 perror("Error while trying to open file");
872 exit(EXIT_FAILURE);
874 if (write(new_fd, image, size) != size)
875 perror("Error while writing");
876 close(new_fd);
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);
883 if (!fcba)
884 exit(EXIT_FAILURE);
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);
901 if (!fcba)
902 exit(EXIT_FAILURE);
904 int freq;
906 switch (ifd_version) {
907 case IFD_VERSION_1:
908 freq = SPI_FREQUENCY_20MHZ;
909 break;
910 case IFD_VERSION_2:
911 freq = SPI_FREQUENCY_17MHZ;
912 break;
913 default:
914 freq = SPI_FREQUENCY_17MHZ;
915 break;
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;
927 if (!fcba)
928 exit(EXIT_FAILURE);
930 printf("Setting chip density to ");
931 decode_component_density(density);
932 printf("\n");
934 switch (ifd_version) {
935 case IFD_VERSION_1:
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");
941 exit(EXIT_FAILURE);
943 mask = 0x7;
944 chip2_offset = 3;
945 break;
946 case IFD_VERSION_2:
947 mask = 0xf;
948 chip2_offset = 4;
949 break;
950 default:
951 printf("error: Unknown IFD version\n");
952 exit(EXIT_FAILURE);
953 break;
956 /* clear chip density for corresponding chip */
957 switch (selected_chip) {
958 case 1:
959 fcba->flcomp &= ~mask;
960 break;
961 case 2:
962 fcba->flcomp &= ~(mask << chip2_offset);
963 break;
964 default: /*both chips*/
965 fcba->flcomp &= ~(mask | (mask << chip2_offset));
966 break;
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)
980 region_t region;
982 if (!frba)
983 return 0;
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);
994 if (!fmba)
995 exit(EXIT_FAILURE);
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;
1006 } else {
1007 wr_shift = FLMSTR_WR_SHIFT_V1;
1008 rd_shift = FLMSTR_RD_SHIFT_V1;
1010 fmba->flmstr1 = 0;
1011 fmba->flmstr2 = 0;
1012 /* Requestor ID */
1013 fmba->flmstr3 = 0x118;
1016 switch (platform) {
1017 case PLATFORM_APL:
1018 case PLATFORM_GLK:
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;
1027 break;
1028 case PLATFORM_CNL:
1029 case PLATFORM_ICL:
1030 case PLATFORM_SKLKBL:
1031 case PLATFORM_TGL:
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;
1066 break;
1067 default:
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;
1092 break;
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);
1101 if (!fmba)
1102 exit(EXIT_FAILURE);
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);
1110 } else {
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");
1127 if (altmedisable)
1128 fpsba->pchstrp[0] |= (1 << 16);
1129 else
1130 fpsba->pchstrp[0] &= ~(1 << 16);
1131 } else {
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");
1137 if (altmedisable) {
1138 /* MCH_MeDisable */
1139 fmsba->data[0] |= 1;
1140 /* MCH_AltMeDisable */
1141 fmsba->data[0] |= (1 << 7);
1142 /* ICH_MeDisable */
1143 fpsba->pchstrp[0] |= 1;
1144 } else {
1145 fmsba->data[0] &= ~1;
1146 fmsba->data[0] &= ~(1 << 7);
1147 fpsba->pchstrp[0] &= ~1;
1149 } else {
1150 printf("%sting the AltMeDisable to %s Intel ME...\n",
1151 altmedisable?"Set":"Unset",
1152 altmedisable?"disable":"enable");
1153 if (altmedisable)
1154 fpsba->pchstrp[10] |= (1 << 7);
1155 else
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);
1165 if (!frba)
1166 exit(EXIT_FAILURE);
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));
1172 exit(EXIT_FAILURE);
1175 int region_fd = open(region_fname, O_RDONLY | O_BINARY);
1176 if (region_fd == -1) {
1177 perror("Could not open file");
1178 exit(EXIT_FAILURE);
1180 struct stat buf;
1181 if (fstat(region_fd, &buf) == -1) {
1182 perror("Could not stat file");
1183 exit(EXIT_FAILURE);
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);
1195 exit(EXIT_FAILURE);
1198 int offset = 0;
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);
1211 exit(EXIT_FAILURE);
1214 if (read(region_fd, image + region.base + offset, region_size)
1215 != region_size) {
1216 perror("Could not read file");
1217 exit(EXIT_FAILURE);
1220 close(region_fd);
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)
1229 unsigned int y = 1;
1230 if (x == 0)
1231 return 0;
1232 while (y <= x)
1233 y = y << 1;
1235 return y;
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))
1248 return 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)
1257 FILE *romlayout;
1258 char tempstr[256];
1259 char layout_region_name[256];
1260 unsigned int i, j;
1261 int region_number;
1262 region_t current_regions[MAX_REGIONS];
1263 region_t new_regions[MAX_REGIONS];
1264 int new_extent = 0;
1265 char *new_image;
1267 /* load current descriptor map and regions */
1268 frba_t *frba = find_frba(image, size);
1269 if (!frba)
1270 exit(EXIT_FAILURE);
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");
1280 if (!romlayout) {
1281 perror("Could not read layout file.\n");
1282 exit(EXIT_FAILURE);
1285 while (!feof(romlayout)) {
1286 char *tstr1, *tstr2;
1288 if (2 != fscanf(romlayout, "%255s %255s\n", tempstr,
1289 layout_region_name))
1290 continue;
1292 region_number = region_num(layout_region_name);
1293 if (region_number < 0)
1294 continue;
1296 tstr1 = strtok(tempstr, ":");
1297 tstr2 = strtok(NULL, ":");
1298 if (!tstr1 || !tstr2) {
1299 fprintf(stderr, "Could not parse layout file.\n");
1300 exit(EXIT_FAILURE);
1302 new_regions[region_number].base = strtol(tstr1,
1303 (char **)NULL, 16);
1304 new_regions[region_number].limit = strtol(tstr2,
1305 (char **)NULL, 16);
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;
1313 fclose(romlayout);
1315 /* check new layout */
1316 for (i = 0; i < max_regions; i++) {
1317 if (new_regions[i].size == 0)
1318 continue;
1320 if (new_regions[i].size < current_regions[i].size) {
1321 printf("DANGER: Region %s is shrinking.\n",
1322 region_name(i));
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");
1330 exit(EXIT_FAILURE);
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 = &current_regions[i];
1353 const region_t *new = &new_regions[i];
1355 if (new->size == 0)
1356 continue;
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,
1378 copy_size);
1381 /* update new descriptor regions */
1382 frba = find_frba(new_image, new_extent);
1383 if (!frba)
1384 exit(EXIT_FAILURE);
1386 for (i = 1; i < max_regions; i++)
1387 set_region(frba, i, &new_regions[i]);
1389 write_image(filename, new_image, new_extent);
1390 free(new_image);
1393 static void print_version(void)
1395 printf("ifdtool v%s -- ", IFDTOOL_VERSION);
1396 printf("Copyright (C) 2011 Google Inc.\n\n");
1397 printf
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);
1410 printf("\n"
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"
1436 "\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'},
1469 {0, 0, 0, 0}
1472 while ((opt = getopt_long(argc, argv, "df:D:C:M:xi:n:s:p:eluvth?",
1473 long_options, &option_index)) != EOF) {
1474 switch (opt) {
1475 case 'd':
1476 mode_dump = 1;
1477 break;
1478 case 'f':
1479 mode_layout = 1;
1480 layout_fname = strdup(optarg);
1481 if (!layout_fname) {
1482 fprintf(stderr, "No layout file specified\n");
1483 print_usage(argv[0]);
1484 exit(EXIT_FAILURE);
1486 break;
1487 case 'x':
1488 mode_extract = 1;
1489 break;
1490 case 'i':
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]);
1496 exit(EXIT_FAILURE);
1498 region_fname[0] = '\0';
1499 region_fname++;
1500 // Descriptor, BIOS, ME, GbE, Platform
1501 // valid type?
1502 if (!strcasecmp("Descriptor", region_type_string))
1503 region_type = 0;
1504 else if (!strcasecmp("BIOS", region_type_string))
1505 region_type = 1;
1506 else if (!strcasecmp("ME", region_type_string))
1507 region_type = 2;
1508 else if (!strcasecmp("GbE", region_type_string))
1509 region_type = 3;
1510 else if (!strcasecmp("Platform", region_type_string))
1511 region_type = 4;
1512 else if (!strcasecmp("EC", region_type_string))
1513 region_type = 8;
1514 if (region_type == -1) {
1515 fprintf(stderr, "No such region type: '%s'\n\n",
1516 region_type_string);
1517 print_usage(argv[0]);
1518 exit(EXIT_FAILURE);
1520 mode_inject = 1;
1521 break;
1522 case 'n':
1523 mode_newlayout = 1;
1524 layout_fname = strdup(optarg);
1525 if (!layout_fname) {
1526 fprintf(stderr, "No layout file specified\n");
1527 print_usage(argv[0]);
1528 exit(EXIT_FAILURE);
1530 break;
1531 case 'D':
1532 mode_density = 1;
1533 new_density = strtoul(optarg, NULL, 0);
1534 switch (new_density) {
1535 case 512:
1536 new_density = COMPONENT_DENSITY_512KB;
1537 break;
1538 case 1:
1539 new_density = COMPONENT_DENSITY_1MB;
1540 break;
1541 case 2:
1542 new_density = COMPONENT_DENSITY_2MB;
1543 break;
1544 case 4:
1545 new_density = COMPONENT_DENSITY_4MB;
1546 break;
1547 case 8:
1548 new_density = COMPONENT_DENSITY_8MB;
1549 break;
1550 case 16:
1551 new_density = COMPONENT_DENSITY_16MB;
1552 break;
1553 case 32:
1554 new_density = COMPONENT_DENSITY_32MB;
1555 break;
1556 case 64:
1557 new_density = COMPONENT_DENSITY_64MB;
1558 break;
1559 case 0:
1560 new_density = COMPONENT_DENSITY_UNUSED;
1561 break;
1562 default:
1563 printf("error: Unknown density\n");
1564 print_usage(argv[0]);
1565 exit(EXIT_FAILURE);
1567 break;
1568 case 'C':
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]);
1573 exit(EXIT_FAILURE);
1575 break;
1576 case 'M':
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]);
1582 exit(EXIT_FAILURE);
1584 break;
1585 case 's':
1586 // Parse the requested SPI frequency
1587 inputfreq = strtol(optarg, NULL, 0);
1588 switch (inputfreq) {
1589 case 17:
1590 spifreq = SPI_FREQUENCY_17MHZ;
1591 break;
1592 case 20:
1593 spifreq = SPI_FREQUENCY_20MHZ;
1594 break;
1595 case 30:
1596 spifreq = SPI_FREQUENCY_50MHZ_30MHZ;
1597 break;
1598 case 33:
1599 spifreq = SPI_FREQUENCY_33MHZ;
1600 break;
1601 case 48:
1602 spifreq = SPI_FREQUENCY_48MHZ;
1603 break;
1604 case 50:
1605 spifreq = SPI_FREQUENCY_50MHZ_30MHZ;
1606 break;
1607 default:
1608 fprintf(stderr, "Invalid SPI Frequency: %d\n",
1609 inputfreq);
1610 print_usage(argv[0]);
1611 exit(EXIT_FAILURE);
1613 mode_spifreq = 1;
1614 break;
1615 case 'e':
1616 mode_em100 = 1;
1617 break;
1618 case 'l':
1619 mode_locked = 1;
1620 if (mode_unlocked == 1) {
1621 fprintf(stderr, "Locking/Unlocking FD and ME are mutually exclusive\n");
1622 exit(EXIT_FAILURE);
1624 break;
1625 case 'u':
1626 mode_unlocked = 1;
1627 if (mode_locked == 1) {
1628 fprintf(stderr, "Locking/Unlocking FD and ME are mutually exclusive\n");
1629 exit(EXIT_FAILURE);
1631 break;
1632 case 'p':
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;
1647 } else {
1648 fprintf(stderr, "Unknown platform: %s\n", optarg);
1649 exit(EXIT_FAILURE);
1651 fprintf(stderr, "Platform is: %s\n", optarg);
1652 break;
1653 case 't':
1654 mode_validate = 1;
1655 break;
1656 case 'v':
1657 print_version();
1658 exit(EXIT_SUCCESS);
1659 break;
1660 case 'h':
1661 case '?':
1662 default:
1663 print_usage(argv[0]);
1664 exit(EXIT_SUCCESS);
1665 break;
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]);
1674 exit(EXIT_FAILURE);
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]);
1682 exit(EXIT_FAILURE);
1685 if (optind + 1 != argc) {
1686 fprintf(stderr, "You need to specify a file.\n\n");
1687 print_usage(argv[0]);
1688 exit(EXIT_FAILURE);
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");
1695 exit(EXIT_FAILURE);
1697 struct stat buf;
1698 if (fstat(bios_fd, &buf) == -1) {
1699 perror("Could not stat file");
1700 exit(EXIT_FAILURE);
1702 int size = buf.st_size;
1704 printf("File %s is %d bytes\n", filename, size);
1706 char *image = malloc(size);
1707 if (!image) {
1708 printf("Out of memory.\n");
1709 exit(EXIT_FAILURE);
1712 if (read(bios_fd, image, size) != size) {
1713 perror("Could not read file");
1714 exit(EXIT_FAILURE);
1717 close(bios_fd);
1719 check_ifd_version(image, size);
1721 if (mode_dump)
1722 dump_fd(image, size);
1724 if (mode_layout)
1725 dump_layout(image, size, layout_fname);
1727 if (mode_extract)
1728 write_regions(image, size);
1730 if (mode_validate)
1731 validate_layout(image, size);
1733 if (mode_inject)
1734 inject_region(filename, image, size, region_type,
1735 region_fname);
1737 if (mode_newlayout)
1738 new_layout(filename, image, size, layout_fname);
1740 if (mode_spifreq)
1741 set_spi_frequency(filename, image, size, spifreq);
1743 if (mode_density)
1744 set_chipdensity(filename, image, size, new_density);
1746 if (mode_em100)
1747 set_em100_mode(filename, image, size);
1749 if (mode_locked)
1750 lock_descriptor(filename, image, size);
1752 if (mode_unlocked)
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);
1762 free(image);
1764 return 0;