[coreboot] New patch to review for coreboot: 6b198e3 Add ifdtool, utility to read / modify Intel Firmware Descriptor images

Stefan Reinauer (stefan.reinauer@coreboot.org) gerrit at coreboot.org
Sat Oct 15 00:27:00 CEST 2011


Stefan Reinauer (stefan.reinauer at coreboot.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/272

-gerrit

commit 6b198e35154a58720348c3f1fb962f77f7f0550b
Author: Stefan Reinauer <reinauer at chromium.org>
Date:   Fri Oct 14 12:49:41 2011 -0700

    Add ifdtool, utility to read / modify Intel Firmware Descriptor images
    
    Change-Id: Ie78b97bf573d238d0dff9a663e774deb1b7dea44
    Signed-off-by: Stefan Reinauer <reinauer at google.com>
---
 util/ifdtool/Makefile  |   53 +++++
 util/ifdtool/ifdtool.c |  551 ++++++++++++++++++++++++++++++++++++++++++++++++
 util/ifdtool/ifdtool.h |   87 ++++++++
 3 files changed, 691 insertions(+), 0 deletions(-)

diff --git a/util/ifdtool/Makefile b/util/ifdtool/Makefile
new file mode 100644
index 0000000..fc8581f
--- /dev/null
+++ b/util/ifdtool/Makefile
@@ -0,0 +1,53 @@
+#
+# ifdtool - dump Intel Firmware Descriptor information
+#
+# Copyright (C) 2011 The ChromiumOS Authors.  All rights reserved.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA
+#
+
+PROGRAM = ifdtool
+
+CC      = gcc
+INSTALL = /usr/bin/install
+PREFIX  = /usr/local
+CFLAGS  = -O2 -g -Wall -W
+LDFLAGS = 
+
+OBJS = ifdtool.o
+
+all: dep $(PROGRAM)
+
+$(PROGRAM): $(OBJS)
+	$(CC) -o $(PROGRAM) $(OBJS) $(LDFLAGS)
+
+clean:
+	rm -f $(PROGRAM) *.o *~
+
+distclean: clean
+	rm -f .dependencies
+
+dep:
+	@$(CC) $(CFLAGS) -MM *.c > .dependencies
+
+install: $(PROGRAM)
+	mkdir -p $(DESTDIR)$(PREFIX)/bin
+	$(INSTALL) $(PROGRAM) $(DESTDIR)$(PREFIX)/bin
+	mkdir -p $(DESTDIR)$(PREFIX)/share/man/man8
+	$(INSTALL) $(PROGRAM).8 $(DESTDIR)$(PREFIX)/share/man/man8
+
+.PHONY: all clean distclean dep 
+
+-include .dependencies
+
diff --git a/util/ifdtool/ifdtool.c b/util/ifdtool/ifdtool.c
new file mode 100644
index 0000000..204c449
--- /dev/null
+++ b/util/ifdtool/ifdtool.c
@@ -0,0 +1,551 @@
+/*
+ * ifdtool - dump Intel Firmware Descriptor information
+ *
+ * Copyright (C) 2011 The ChromiumOS Authors.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA
+ */
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <getopt.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include "ifdtool.h"
+
+static fdbar_t *find_fd(char *image, int size)
+{
+	int i, found = 0;
+
+	/* Scan for FD signature */
+	for (i = 0; i < (size - 4); i += 4) {
+		if (*(uint32_t *) (image + i) == 0x0FF0A55A) {
+			found = 1;
+			break;	// signature found.
+		}
+	}
+
+	if (!found) {
+		printf("No Flash Descriptor found in this image\n");
+		return NULL;
+	}
+
+	printf("Found Flash Descriptor signature at 0x%08x\n", i);
+
+	return (fdbar_t *) (image + i);
+}
+
+typedef struct {
+	int base, limit, size;
+} region_t;
+
+static region_t get_region(frba_t *frba, int region_type)
+{
+	region_t region;
+	region.base = 0, region.limit = 0, region.size = 0;
+
+	switch (region_type) {
+	case 0:
+		region.base = (frba->flreg0 & 0x00000fff) << 12;
+		region.limit = ((frba->flreg0 & 0x0fff0000) >> 4) | 0xfff;
+		break;
+	case 1:
+		region.base = (frba->flreg1 & 0x00000fff) << 12;
+		region.limit = ((frba->flreg1 & 0x0fff0000) >> 4) | 0xfff;
+		break;
+	case 2:
+		region.base = (frba->flreg2 & 0x00000fff) << 12;
+		region.limit = ((frba->flreg2 & 0x0fff0000) >> 4) | 0xfff;
+		break;
+	case 3:
+		region.base = (frba->flreg3 & 0x00000fff) << 12;
+		region.limit = ((frba->flreg3 & 0x0fff0000) >> 4) | 0xfff;
+		break;
+	case 4:
+		region.base = (frba->flreg4 & 0x00000fff) << 12;
+		region.limit = ((frba->flreg4 & 0x0fff0000) >> 4) | 0xfff;
+		break;
+	default:
+		fprintf(stderr, "Invalid region type.\n");
+		exit (EXIT_FAILURE);
+	}
+
+	region.size = region.limit - region.base + 1;
+
+	return region;
+}
+
+static const char *region_name(int region_type)
+{
+	static const char *regions[5] = {
+		"Flash Descriptor",
+		"BIOS",
+		"Intel ME",
+		"GbE",
+		"Platform Data"
+	};
+
+	if (region_type < 0 || region_type > 4) {
+		fprintf(stderr, "Invalid region type.\n");
+		exit (EXIT_FAILURE);
+	}
+
+	return regions[region_type];
+}
+
+static const char *region_filename(int region_type)
+{
+	static const char *region_filenames[5] = {
+		"flashregion_0_flashdescriptor.bin",
+		"flashregion_1_bios.bin",
+		"flashregion_2_intel_me.bin",
+		"flashregion_3_gbe.bin",
+		"flashregion_4_platform_data.bin"
+	};
+
+	if (region_type < 0 || region_type > 4) {
+		fprintf(stderr, "Invalid region type.\n");
+		exit (EXIT_FAILURE);
+	}
+
+	return region_filenames[region_type];
+}
+
+static void dump_frba(frba_t * frba)
+{
+	printf("\nFound Region Section\n");
+	printf("FLREG0:    0x%08x\n", frba->flreg0);
+	printf("FLREG1:    0x%08x\n", frba->flreg1);
+	printf("FLREG2:    0x%08x\n", frba->flreg2);
+	printf("FLREG3:    0x%08x\n", frba->flreg3);
+	printf("FLREG4:    0x%08x\n", frba->flreg4);
+}
+
+static void decode_spi_frequency(unsigned int freq)
+{
+	switch (freq) {
+	case SPI_FREQUENCY_20MHZ:
+		printf("20MHz");
+		break;
+	case SPI_FREQUENCY_33MHZ:
+		printf("33MHz");
+		break;
+	case SPI_FREQUENCY_50MHZ:
+		printf("50MHz");
+		break;
+	default:
+		printf("unknown<%x>MHz", freq);
+	}
+}
+
+static void dump_fcba(fcba_t * fcba)
+{
+	printf("\nFound Component Section\n");
+	printf("FLCOMP     0x%08x\n", fcba->flcomp);
+	printf("  Read ID/Read Status Clock Frequency: ");
+	decode_spi_frequency((fcba->flcomp >> 27) & 7);
+	printf("\n  Write/Erase Clock Frequency:         ");
+	decode_spi_frequency((fcba->flcomp >> 24) & 7);
+	printf("\n  Fast Read Clock Frequency:           ");
+	decode_spi_frequency((fcba->flcomp >> 21) & 7);
+	printf("\n");
+	printf("FLILL      0x%08x\n", fcba->flill);
+	printf("FLPB       0x%08x\n", fcba->flpb);
+}
+
+static void dump_fpsba(fpsba_t * fpsba)
+{
+	printf("\nFound PCH Strap Section\n");
+	printf("PCHSTRP0:  0x%08x\n", fpsba->pchstrp0);
+	printf("PCHSTRP1:  0x%08x\n", fpsba->pchstrp1);
+	printf("PCHSTRP2:  0x%08x\n", fpsba->pchstrp2);
+	printf("PCHSTRP3:  0x%08x\n", fpsba->pchstrp3);
+	printf("PCHSTRP4:  0x%08x\n", fpsba->pchstrp4);
+	printf("PCHSTRP5:  0x%08x\n", fpsba->pchstrp5);
+	printf("PCHSTRP6:  0x%08x\n", fpsba->pchstrp6);
+	printf("PCHSTRP7:  0x%08x\n", fpsba->pchstrp7);
+	printf("PCHSTRP8:  0x%08x\n", fpsba->pchstrp8);
+	printf("PCHSTRP9:  0x%08x\n", fpsba->pchstrp9);
+	printf("PCHSTRP10: 0x%08x\n", fpsba->pchstrp10);
+	printf("PCHSTRP11: 0x%08x\n", fpsba->pchstrp11);
+	printf("PCHSTRP12: 0x%08x\n", fpsba->pchstrp12);
+	printf("PCHSTRP13: 0x%08x\n", fpsba->pchstrp13);
+	printf("PCHSTRP14: 0x%08x\n", fpsba->pchstrp14);
+	printf("PCHSTRP15: 0x%08x\n", fpsba->pchstrp15);
+}
+
+static void dump_fmba(fmba_t * fmba)
+{
+	printf("\nFound Master Section\n");
+	printf("FLMSTR1:   0x%08x\n", fmba->flmstr1);
+	printf("FLMSTR2:   0x%08x\n", fmba->flmstr2);
+	printf("FLMSTR3:   0x%08x\n", fmba->flmstr3);
+}
+
+static void dump_fmsba(fmsba_t * fmsba)
+{
+	printf("\nFound Processor Strap Section\n");
+	printf("????:      0x%08x\n", fmsba->data[0]);
+	printf("????:      0x%08x\n", fmsba->data[1]);
+	printf("????:      0x%08x\n", fmsba->data[2]);
+	printf("????:      0x%08x\n", fmsba->data[3]);
+}
+
+static void dump_fd(char *image, int size)
+{
+	fdbar_t *fdb = find_fd(image, size);
+	if (!fdb)
+		exit(EXIT_FAILURE);
+
+	printf("FLMAP0:    0x%08x\n", fdb->flmap0);
+	printf("  NR:      %d\n", (fdb->flmap0 >> 24) & 7);
+	printf("  FRBA:    0x%x\n", ((fdb->flmap0 >> 16) & 0xff) << 4);
+	printf("  NC:      %d\n", ((fdb->flmap0 >> 8) & 3) + 1);
+	printf("  FCBA:    0x%x\n", ((fdb->flmap0) & 0xff) << 4);
+
+	printf("FLMAP1:    0x%08x\n", fdb->flmap1);
+	printf("  ISL:     0x%02x\n", (fdb->flmap1 >> 24) & 0xff);
+	printf("  FPSBA:   0x%x\n", ((fdb->flmap1 >> 16) & 0xff) << 4);
+	printf("  NM:      %d\n", (fdb->flmap1 >> 8) & 3);
+	printf("  FMBA:    0x%x\n", ((fdb->flmap1) & 0xff) << 4);
+
+	printf("FLMAP2:    0x%08x\n", fdb->flmap2);
+	printf("  PSL:     0x%04x\n", (fdb->flmap2 >> 8) & 0xffff);
+	printf("  FMSBA:   0x%x\n", ((fdb->flmap2) & 0xff) << 4);
+
+	printf("FLUMAP1:   0x%08x\n", fdb->flumap1);
+
+	dump_frba((frba_t *)
+			(image + (((fdb->flmap0 >> 16) & 0xff) << 4)));
+	dump_fcba((fcba_t *) (image + (((fdb->flmap0) & 0xff) << 4)));
+	dump_fpsba((fpsba_t *)
+			(image + (((fdb->flmap1 >> 16) & 0xff) << 4)));
+	dump_fmba((fmba_t *) (image + (((fdb->flmap1) & 0xff) << 4)));
+	dump_fmsba((fmsba_t *) (image + (((fdb->flmap2) & 0xff) << 4)));
+}
+
+static void write_regions(char *image, int size)
+{
+	int i;
+
+	fdbar_t *fdb = find_fd(image, size);
+	if (!fdb)
+		exit(EXIT_FAILURE);
+
+	frba_t *frba =
+	    (frba_t *) (image + (((fdb->flmap0 >> 16) & 0xff) << 4));
+
+	for (i = 0; i<5; i++) {
+		region_t region = get_region(frba, i);
+		printf("Flash Region %d (%s): %08x - %08x %s\n",
+		       i, region_name(i), region.base, region.limit,
+		       region.size < 1 ? "(unused)" : "");
+		if (region.size > 0) {
+			int region_fd;
+			region_fd = open(region_filename(i),
+					 O_WRONLY | O_CREAT | O_TRUNC,
+					 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+			if (write(region_fd, image + region.base, region.size) != region.size)
+				printf("Error while writing.");
+			close(region_fd);
+		}
+	}
+}
+
+static void write_image(char *filename, char *image, int size)
+{
+	char new_filename[FILENAME_MAX]; // allow long file names
+	int new_fd;
+
+	strncpy(new_filename, filename, FILENAME_MAX);
+	strncat(new_filename, ".new", FILENAME_MAX - strlen(filename));
+
+	printf("Writing new image to %s\n", new_filename);
+
+	// Now write out new image
+	new_fd = open(new_filename,
+			 O_WRONLY | O_CREAT | O_TRUNC,
+			 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+	if (write(new_fd, image, size) != size)
+		printf("Error while writing.");
+	close(new_fd);
+}
+
+static void set_spi_frequency(char *filename, char *image, int size,
+			      enum spi_frequency freq)
+{
+	fdbar_t *fdb = find_fd(image, size);
+	fcba_t *fcba = (fcba_t *) (image + (((fdb->flmap0) & 0xff) << 4));
+
+	/* clear bits 21-29 */
+	fcba->flcomp &= ~0x3fe00000;
+	/* Read ID and Read Status Clock Frequency */
+	fcba->flcomp |= freq << 27;
+	/* Write and Erase Clock Frequency */
+	fcba->flcomp |= freq << 24;
+	/* Fast Read Clock Frequency */
+	fcba->flcomp |= freq << 21;
+
+	write_image(filename, image, size);
+}
+
+void inject_region(char *filename, char *image, int size, int region_type,
+		   char *region_fname)
+{
+	fdbar_t *fdb = find_fd(image, size);
+	if (!fdb)
+		exit(EXIT_FAILURE);
+	frba_t *frba =
+	    (frba_t *) (image + (((fdb->flmap0 >> 16) & 0xff) << 4));
+	
+	region_t region = get_region(frba, region_type);
+	if (region.size <= 0xfff) {
+		fprintf(stderr, "Region %s is disabled in target. Not injecting.\n",
+				region_name(region_type));
+		exit(EXIT_FAILURE);
+	}
+
+	int region_fd = open(region_fname, O_RDONLY);
+	if (region_fd == -1) {
+		perror("Could not open file");
+		exit(EXIT_FAILURE);
+	}
+	struct stat buf;
+	if (fstat(region_fd, &buf) == -1) {
+		perror("Could not stat file");
+		exit(EXIT_FAILURE);
+	}
+	int region_size = buf.st_size;
+
+	printf("File %s is %d bytes\n", region_fname, region_size);
+
+	if ( (region_size > region.size) || ((region_type != 1) &&
+		(region_size != region.size))) {
+		fprintf(stderr, "Region %s is %d(0x%x) bytes. File is %d(0x%x)"
+				" bytes. Not injecting.\n",
+				region_name(region_type), region.size,
+				region.size, region_size, region_size);
+		exit(EXIT_FAILURE);
+	}
+
+	int offset = 0;
+	if ((region_type == 1) && (region_size < region.size)) {
+		fprintf(stderr, "Region %s is %d(0x%x) bytes. File is %d(0x%x)"
+				" bytes. Padding before injecting.\n",
+				region_name(region_type), region.size,
+				region.size, region_size, region_size);
+		offset = region.size - region_size;
+		memset(image + region.base, 0xff, offset);
+	}
+
+	if (read(region_fd, image + region.base + offset, region_size)
+							!= region_size) {
+		perror("Could not read file");
+		exit(EXIT_FAILURE);
+	}
+
+	close(region_fd);
+
+	printf("Adding %s as the %s section of %s\n",
+	       region_fname, region_name(region_type), filename);
+	write_image(filename, image, size);
+}
+
+static void print_version(void)
+{
+	printf("ifdtool v%s -- ", IFDTOOL_VERSION);
+	printf("Copyright (C) 2011 Google Inc.\n\n");
+	printf
+	    ("This program is free software: you can redistribute it and/or modify\n"
+	     "it under the terms of the GNU General Public License as published by\n"
+	     "the Free Software Foundation, version 2 of the License.\n\n"
+	     "This program is distributed in the hope that it will be useful,\n"
+	     "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+	     "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
+	     "GNU General Public License for more details.\n\n"
+	     "You should have received a copy of the GNU General Public License\n"
+	     "along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\n");
+}
+
+static void print_usage(const char *name)
+{
+	printf("usage: %s [-vhdix?] <filename>\n", name);
+	printf("\n"
+	       "   -d | --dump:                      dump intel firmware descriptor\n"
+	       "   -x | --extract:                   extract intel fd modules\n"
+	       "   -i | --inject <region>:<module>   inject file <module> into region <region>\n"
+	       "   -s | --spifreq <20|33|50>         set the SPI frequency\n"
+	       "   -v | --version:                   print the version\n"
+	       "   -h | --help:                      print this help\n\n"
+	       "<region> is one of Descriptor, BIOS, ME, GbE, Platform\n"
+	       "\n");
+}
+
+int main(int argc, char *argv[])
+{
+	int opt, option_index = 0;
+	int mode_dump = 0, mode_extract = 0, mode_inject = 0, mode_spifreq = 0;
+	char *region_type_string = NULL, *region_fname = NULL;
+	int region_type = -1, inputfreq = 0;
+	enum spi_frequency spifreq = SPI_FREQUENCY_20MHZ;
+
+	static struct option long_options[] = {
+		{"dump", 0, NULL, 'd'},
+		{"extract", 0, NULL, 'x'},
+		{"inject", 1, NULL, 'i'},
+		{"spifreq", 1, NULL, 's'},
+		{"version", 0, NULL, 'v'},
+		{"help", 0, NULL, 'h'},
+		{0, 0, 0, 0}
+	};
+
+	while ((opt = getopt_long(argc, argv, "dxi:s:vh?",
+				  long_options, &option_index)) != EOF) {
+		switch (opt) {
+		case 'd':
+			mode_dump = 1;
+			break;
+		case 'x':
+			mode_extract = 1;
+			break;
+		case 'i':
+			// separate type and file name
+			region_type_string = strdup(optarg);
+			region_fname = strchr(region_type_string, ':');
+			if (!region_fname) {
+				print_usage(argv[0]);
+				exit(EXIT_FAILURE);
+			}
+			region_fname[0] = '\0';
+			region_fname++;
+			// Descriptor, BIOS, ME, GbE, Platform
+			// valid type?
+			if (!strcasecmp("Descriptor", region_type_string))
+				region_type = 0;
+			else if (!strcasecmp("BIOS", region_type_string))
+				region_type = 1;
+			else if (!strcasecmp("ME", region_type_string))
+				region_type = 2;
+			else if (!strcasecmp("GbE", region_type_string))
+				region_type = 3;
+			else if (!strcasecmp("Platform", region_type_string))
+				region_type = 4;
+			if (region_type == -1) {
+				fprintf(stderr, "No such region type: '%s'\n\n",
+					region_type_string);
+				print_usage(argv[0]);
+				exit(EXIT_FAILURE);
+			}
+			mode_inject = 1;
+			break;
+		case 's':
+			// Parse the requested SPI frequency
+			inputfreq = strtol(optarg, NULL, 0);
+			switch (inputfreq) {
+			case 20:
+				spifreq = SPI_FREQUENCY_20MHZ;
+				break;
+			case 33:
+				spifreq = SPI_FREQUENCY_33MHZ;
+				break;
+			case 50:
+				spifreq = SPI_FREQUENCY_50MHZ;
+				break;
+			default:
+				fprintf(stderr, "Invalid SPI Frequency: %d\n",
+					inputfreq);
+				print_usage(argv[0]);
+				exit(EXIT_FAILURE);
+			}
+			mode_spifreq = 1;
+			break;
+		case 'v':
+			print_version();
+			exit(EXIT_SUCCESS);
+			break;
+		case 'h':
+		case '?':
+		default:
+			print_usage(argv[0]);
+			exit(EXIT_SUCCESS);
+			break;
+		}
+	}
+
+	if ((mode_dump + mode_extract + mode_inject + mode_spifreq) > 1) {
+		fprintf(stderr, "Only one mode allowed.\n\n");
+		print_usage(argv[0]);
+		exit(EXIT_FAILURE);
+	}
+
+	if ((mode_dump + mode_extract + mode_inject + mode_spifreq) == 0) {
+		fprintf(stderr, "You need to specify a mode.\n\n");
+		print_usage(argv[0]);
+		exit(EXIT_FAILURE);
+	}
+
+	if (optind + 1 != argc) {
+		fprintf(stderr, "You need to specify a file.\n\n");
+		print_usage(argv[0]);
+		exit(EXIT_FAILURE);
+	}
+
+	char *filename = argv[optind];
+	int bios_fd = open(filename, O_RDONLY);
+	if (bios_fd == -1) {
+		perror("Could not open file");
+		exit(EXIT_FAILURE);
+	}
+	struct stat buf;
+	if (fstat(bios_fd, &buf) == -1) {
+		perror("Could not stat file");
+		exit(EXIT_FAILURE);
+	}
+	int size = buf.st_size;
+
+	printf("File %s is %d bytes\n", filename, size);
+
+	char *image = malloc(size);
+	if (!image) {
+		printf("Out of memory.\n");
+		exit(EXIT_FAILURE);
+	}
+
+	if (read(bios_fd, image, size) != size) {
+		perror("Could not read file");
+		exit(EXIT_FAILURE);
+	}
+
+	close(bios_fd);
+
+	if (mode_dump)
+		dump_fd(image, size);
+
+	if (mode_extract)
+		write_regions(image, size);
+
+	if (mode_inject)
+		inject_region(filename, image, size, region_type,
+				region_fname);
+
+	if (mode_spifreq)
+		set_spi_frequency(filename, image, size, spifreq);
+
+	free(image);
+
+	return 0;
+}
diff --git a/util/ifdtool/ifdtool.h b/util/ifdtool/ifdtool.h
new file mode 100644
index 0000000..0571534
--- /dev/null
+++ b/util/ifdtool/ifdtool.h
@@ -0,0 +1,87 @@
+/*
+ * ifdtool - dump Intel Firmware Descriptor information
+ *
+ * Copyright (C) 2011 The ChromiumOS Authors.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA
+ */
+
+#include <stdint.h>
+#define IFDTOOL_VERSION "1.0"
+
+enum spi_frequency {
+	SPI_FREQUENCY_20MHZ = 0,
+	SPI_FREQUENCY_33MHZ = 1,
+	SPI_FREQUENCY_50MHZ = 4,
+};
+
+// flash descriptor
+typedef struct {
+	uint32_t flvalsig;
+	uint32_t flmap0;
+	uint32_t flmap1;
+	uint32_t flmap2;
+	uint8_t  reserved[0xefc - 0x20];
+	uint32_t flumap1;
+} __attribute__((packed)) fdbar_t;
+
+// regions
+typedef struct {
+	uint32_t flreg0;
+	uint32_t flreg1;
+	uint32_t flreg2;
+	uint32_t flreg3;
+	uint32_t flreg4;
+} __attribute__((packed)) frba_t;
+
+// component section
+typedef struct {
+	uint32_t flcomp;
+	uint32_t flill;
+	uint32_t flpb;
+} __attribute__((packed)) fcba_t;
+
+// pch strap
+typedef struct {
+	uint32_t pchstrp0;
+	uint32_t pchstrp1;
+	uint32_t pchstrp2;
+	uint32_t pchstrp3;
+	uint32_t pchstrp4;
+	uint32_t pchstrp5;
+	uint32_t pchstrp6;
+	uint32_t pchstrp7;
+	uint32_t pchstrp8;
+	uint32_t pchstrp9;
+	uint32_t pchstrp10;
+	uint32_t pchstrp11;
+	uint32_t pchstrp12;
+	uint32_t pchstrp13;
+	uint32_t pchstrp14;
+	uint32_t pchstrp15;
+} __attribute__((packed)) fpsba_t;
+
+// master
+typedef struct {
+	uint32_t flmstr1;
+	uint32_t flmstr2;
+	uint32_t flmstr3;
+} __attribute__((packed)) fmba_t;
+
+// processor strap
+typedef struct {
+	uint32_t data[8];
+} __attribute__((packed)) fmsba_t;
+
+




More information about the coreboot mailing list