additionally to what is available via FDOC/FDOD...<TODO>

TODO:
 - fix msg_perr
 - decode all ibex straps

Signed-off-by: Stefan Tauner <[email protected]>
---
 ich_descriptors.c                                |  186 ++++++++++++++++++++
 ich_descriptors.h                                |  200 ++++++++++++++++++++++
 util/ich_descriptors_tool/Makefile               |   42 +++++
 util/ich_descriptors_tool/TODO                   |    5 +
 util/ich_descriptors_tool/ich_descriptors_tool.c |  197 +++++++++++++++++++++
 5 files changed, 630 insertions(+), 0 deletions(-)
 create mode 100644 util/ich_descriptors_tool/Makefile
 create mode 100644 util/ich_descriptors_tool/TODO
 create mode 100644 util/ich_descriptors_tool/ich_descriptors_tool.c

diff --git a/ich_descriptors.c b/ich_descriptors.c
index 43b2c52..0281488 100644
--- a/ich_descriptors.c
+++ b/ich_descriptors.c
@@ -22,8 +22,21 @@
 #if defined(__i386__) || defined(__x86_64__)
 
 #include "ich_descriptors.h"
+
+#ifdef ICH_DESCRIPTORS_FROM_MMAP_DUMP
+
+#define DESCRIPTOR_MODE_MAGIC 0x0ff0a55a
+#define msg_pdbg printf
+#define msg_pspew printf
+#define msg_perr printf
+#include <stdio.h>
+
+#else
+
 #include "flash.h" /* for msg_* */
 
+#endif // ICH_DESCRIPTORS_FROM_MMAP_DUMP
+
 uint32_t getFCBA(const struct flash_content *cont)
 {
        return (cont->FLMAP0 <<  4) & 0x00000ff0;
@@ -59,12 +72,26 @@ uint32_t getFISBA(const struct flash_content *cont)
        return (cont->FLMAP1 >> 12) & 0x00000ff0;
 }
 
+#ifdef ICH_DESCRIPTORS_FROM_MMAP_DUMP
+uint32_t getVTBA(const struct flash_upper_map *flumap)
+{      /* The bits in FLUMAP1 describe bits 4-11 out of 24 in total;
+        * others are 0. */
+       return (flumap->FLUMAP1 << 4) & 0x0ff0;
+}
+#endif
+
 void prettyprint_ich_descriptors(enum chipset cs, const struct 
flash_descriptors *desc)
 {
        prettyprint_ich_descriptor_content(&desc->content);
        prettyprint_ich_descriptor_component(desc);
        prettyprint_ich_descriptor_region(&desc->region);
        prettyprint_ich_descriptor_master(&desc->master);
+#ifdef ICH_DESCRIPTORS_FROM_MMAP_DUMP
+       if (cs >= CHIPSET_ICH8) {
+               prettyprint_ich_descriptor_upper_map(&desc->upper);
+               prettyprint_ich_descriptor_straps(cs, &desc->straps);
+       }
+#endif // ICH_DESCRIPTORS_FROM_MMAP_DUMP
 }
 
 void prettyprint_ich_descriptor_content(const struct flash_content *cont)
@@ -208,6 +235,164 @@ void prettyprint_ich9_reg_vscc(uint32_t reg_val)
        pprint_reg(VSCC, VCL, reg_val, "\n");
 }
 
+#ifdef ICH_DESCRIPTORS_FROM_MMAP_DUMP
+void prettyprint_ich_descriptor_straps_ich8(const struct flash_strap *straps)
+{
+       const char * const str_GPIO12[4] = {
+               "GPIO12",
+               "LAN PHY Power Control Function (Native Output)",
+               "GLAN_DOCK# (Native Input)",
+               "invalid configuration",
+       };
+
+       msg_pdbg1("=== FISBA ===\n");
+       msg_pdbg1("STRP0    0x%8.8x\n", straps->ich8.STRPs[0]);
+       msg_pdbg1("\n");
+
+       msg_pdbg2("--- FISBA details ---\n");
+       msg_pdbg2("ME SMBus addr2 0x%2.2x\n", straps->ich8.ASD2);
+       msg_pdbg2("ME SMBus addr1 0x%2.2x\n", straps->ich8.ASD);
+       msg_pdbg2("ME SMBus Controller is connected to %s\n", 
straps->ich8.MESM2SEL ? "SMLink pins" : "SMBus pins");
+       msg_pdbg2("SPI CS1 is used for %s\n", straps->ich8.SPICS1_LANPHYPC_SEL 
? "LAN PHY Power Control Function" : "SPI Chip Select");
+       msg_pdbg2("GPIO12_SEL is used as %s\n", 
str_GPIO12[straps->ich8.GPIO12_SEL]);
+       msg_pdbg2("PCIe Port 6 is used for %s\n", straps->ich8.GLAN_PCIE_SEL ? 
"integrated GLAN" : "PCI Express");
+       msg_pdbg2("Intel AMT SMBus Controller 1 is connected to %s\n",   
straps->ich8.BMCMODE ? "SMLink" : "SMBus");
+       msg_pdbg2("TCO slave is on %s. Intel AMT SMBus Controller 1 is 
%sabled\n",
+               straps->ich8.TCOMODE ? "SMBus" : "SMLink", straps->ich8.TCOMODE 
? "en" : "dis");
+       msg_pdbg2("ME A is %sabled\n", straps->ich8.ME_DISABLE ? "dis" : "en");
+
+       msg_pdbg2("\n");
+       msg_pdbg2("=== FMSBA ===\n");
+       msg_pdbg2("STRP1    0x%8.8x\n", straps->ich8.STRPs[1]);
+
+       msg_pdbg2("\n");
+       msg_pdbg2("--- FMSBA details ---\n");
+       msg_pdbg2("ME B is %sabled\n", straps->ich8.ME_disable_B ? "dis" : 
"en");
+       msg_pdbg2("\n");
+}
+
+void prettyprint_ich_descriptor_straps_ibex(const struct flash_strap *straps)
+{
+       int i;
+       msg_pdbg2("=== FPSBA ===\n");
+       /* TODO: decode properly */
+       for(i = 0; i <= 15; i++)
+               msg_pdbg2("STRP%-2d = 0x%8.8x\n", i, straps->ibex.STRPs[i]);
+       msg_pdbg2("\n");
+}
+
+void prettyprint_ich_descriptor_straps(enum chipset cs, const struct 
flash_strap *straps)
+{
+       switch (cs) {
+       case CHIPSET_ICH8:
+               prettyprint_ich_descriptor_straps_ich8(straps);
+               break;
+       case CHIPSET_SERIES_5_IBEX_PEAK:
+               /* PCH straps only. PROCSTRPs are unknown. */
+               prettyprint_ich_descriptor_straps_ibex(straps);
+               break;
+       case CHIPSET_UNKNOWN:
+               break;
+       default:
+               msg_pdbg2("The meaning of the descriptor straps are unknown 
yet.\n");
+               msg_pdbg2("\n");
+               break;
+       }
+}
+
+void prettyprint_rdid(uint32_t reg_val)
+{
+       uint8_t mid = reg_val & 0xFF;
+       uint16_t did = ((reg_val >> 16) & 0xFF) | (reg_val & 0xFF00);
+       msg_pdbg2("Manufacturer ID 0x%02x, Device ID 0x%04x\n", mid, did);
+}
+
+void prettyprint_ich_descriptor_upper_map(const struct flash_upper_map *umap)
+{
+       int i;
+       msg_pdbg1("=== FLUMAP ===\n");
+       msg_pdbg1("FLUMAP1  0x%8.8x\n", umap->FLUMAP1);
+       msg_pdbg1("\n");
+
+       msg_pdbg2("--- FLUMAP details ---\n");
+       msg_pdbg2("VTL  (length)       = %d\n", umap->VTL);
+       msg_pdbg2("VTBA (base address) = 0x%6.6x\n", getVTBA(umap));
+       msg_pdbg2("\n");
+
+       msg_pdbg2("VSCC Table:\n");
+       for (i=0; i < umap->VTL/2; i++)
+       {
+               uint32_t jid = umap->vscc_table[i].JID;
+               uint32_t vscc = umap->vscc_table[i].VSCC;
+               msg_pdbg2("  JID%d  = 0x%8.8x\n", i, jid);
+               msg_pdbg2("  VSCC%d = 0x%8.8x\n", i, vscc);
+               msg_pdbg2("    "); /* indention */
+               prettyprint_rdid(jid);
+               msg_pdbg2("    "); /* indention */
+               prettyprint_ich9_reg_vscc(vscc);
+       }
+       msg_pdbg2("\n");
+}
+
+int read_ich_descriptors_from_dump(const uint32_t *dump, enum chipset cs, 
struct flash_descriptors *desc)
+{
+       int i;
+       uint8_t pch_bug_offset = 0;
+       if (dump[0] != DESCRIPTOR_MODE_MAGIC) {
+               if (dump[4] == DESCRIPTOR_MODE_MAGIC)
+                       pch_bug_offset = 4;
+               else
+                       return -1;
+       }
+
+       /* map */
+       desc->content.FLVALSIG  = dump[0 + pch_bug_offset];
+       desc->content.FLMAP0    = dump[1 + pch_bug_offset];
+       desc->content.FLMAP1    = dump[2 + pch_bug_offset];
+       desc->content.FLMAP2    = dump[3 + pch_bug_offset];
+
+       /* component */
+       desc->component.FLCOMP  = dump[(getFCBA(&desc->content) >> 2) + 0];
+       desc->component.FLILL   = dump[(getFCBA(&desc->content) >> 2) + 1];
+       desc->component.FLPB    = dump[(getFCBA(&desc->content) >> 2) + 2];
+
+       /* region */
+       desc->region.FLREG0 = dump[(getFRBA(&desc->content) >> 2) + 0];
+       desc->region.FLREG1 = dump[(getFRBA(&desc->content) >> 2) + 1];
+       desc->region.FLREG2 = dump[(getFRBA(&desc->content) >> 2) + 2];
+       desc->region.FLREG3 = dump[(getFRBA(&desc->content) >> 2) + 3];
+
+       /* master */
+       desc->master.FLMSTR1 = dump[(getFMBA(&desc->content) >> 2) + 0];
+       desc->master.FLMSTR2 = dump[(getFMBA(&desc->content) >> 2) + 1];
+       desc->master.FLMSTR3 = dump[(getFMBA(&desc->content) >> 2) + 2];
+
+       /* upper map */
+       desc->upper.FLUMAP1 = dump[(0x0efc >> 2) + 0];
+
+       for (i=0; i < desc->upper.VTL; i++)
+       {
+               desc->upper.vscc_table[i].JID  = dump[(getVTBA(&desc->upper) >> 
2) + i * 2 + 0];
+               desc->upper.vscc_table[i].VSCC = dump[(getVTBA(&desc->upper) >> 
2) + i * 2 + 1];
+       }
+       /* straps */
+       switch (cs) {
+               case CHIPSET_ICH8:
+                       desc->straps.ich8.STRPs[0] = 
dump[(getFISBA(&desc->content) >> 2) + 0];
+                       desc->straps.ich8.STRPs[1] = 
dump[(getFMSBA(&desc->content) >> 2) + 0];
+                       break;
+               case CHIPSET_SERIES_5_IBEX_PEAK:
+                       for(i = 0; i <= 15; i++)
+                               desc->straps.ibex.STRPs[i] = 
dump[(getFISBA(&desc->content) >> 2) + i];
+                       break;
+               default:
+                       break;
+       }
+
+       return 0;
+}
+#else // ICH_DESCRIPTORS_FROM_MMAP_DUMP
+
 static uint32_t read_descriptor_reg(uint8_t section, uint16_t offset, void 
*spibar)
 {
        uint32_t control = 0;
@@ -247,4 +432,5 @@ void read_ich_descriptors_via_fdo(void *spibar, struct 
flash_descriptors *desc)
        msg_pdbg1(" done\n");
 }
 
+#endif // ICH_DESCRIPTORS_FROM_MMAP_DUMP
 #endif // defined(__i386__) || defined(__x86_64__)
diff --git a/ich_descriptors.h b/ich_descriptors.h
index 9954149..1129805 100644
--- a/ich_descriptors.h
+++ b/ich_descriptors.h
@@ -238,11 +238,202 @@ struct flash_master {
        };
 };
 
+#ifdef ICH_DESCRIPTORS_FROM_MMAP_DUMP
+struct flash_strap {
+       union {
+               union {
+                       uint32_t STRPs[2];
+                       struct {
+                               struct {
+                                       uint32_t ME_DISABLE             :1;
+                                       uint32_t                        :6;
+                                       uint32_t TCOMODE                :1;
+                                       uint32_t ASD                    :7;
+                                       uint32_t BMCMODE                :1;
+                                       uint32_t                        :3;
+                                       uint32_t GLAN_PCIE_SEL          :1;
+                                       uint32_t GPIO12_SEL             :2;
+                                       uint32_t SPICS1_LANPHYPC_SEL    :1;
+                                       uint32_t MESM2SEL               :1;
+                                       uint32_t                        :1;
+                                       uint32_t ASD2                   :7;
+                               };
+                               struct {
+                                       uint32_t ME_disable_B           :1;
+                                       uint32_t                        :31;
+                               };
+                       };
+               }ich8;
+               union {
+                       uint32_t STRPs[15];
+                       struct {
+                               struct {
+                                       uint32_t                        :1;
+                                       uint32_t cs_ss2                 :1;
+                                       uint32_t                        :5;
+                                       uint32_t SMB_EN                 :1;
+                                       uint32_t SML0_EN                :1;
+                                       uint32_t SML1_EN                :1;
+                                       uint32_t SML1FRQ                :2;
+                                       uint32_t SMB0FRQ                :2;
+                                       uint32_t SML0FRQ                :2;
+                                       uint32_t                        :4;
+                                       uint32_t LANPHYPC_GP12_SEL      :1;
+                                       uint32_t cs_ss1                 :1;
+                                       uint32_t                        :2;
+                                       uint32_t DMI_REQID_DIS          :1;
+                                       uint32_t                        :4;
+                                       uint32_t BBBS                   :2;
+                                       uint32_t                        :1;
+                               };
+                               struct {
+                                       uint32_t cs_ss3                 :4;
+                                       uint32_t                        :28;
+                               };
+                               struct {
+                                       uint32_t                        :8;
+                                       uint32_t MESMASDEN              :1;
+                                       uint32_t MESMASDA               :7;
+                                       uint32_t                        :8;
+                                       uint32_t MESMI2CEN              :1;
+                                       uint32_t MESMI2CA               :7;
+                               };
+                               struct {
+                                       uint32_t                        :32;
+                               };
+                               struct {
+                                       uint32_t PHYCON                 :2;
+                                       uint32_t                        :6;
+                                       uint32_t GBEMAC_SMBUS_ADDR_EN   :1;
+                                       uint32_t GBEMAC_SMBUS_ADDR      :7;
+                                       uint32_t                        :1;
+                                       uint32_t GBEPHY_SMBUS_ADDR      :7;
+                                       uint32_t                        :8;
+                               };
+                               struct {
+                                       uint32_t                        :32;
+                               };
+                               struct {
+                                       uint32_t                        :32;
+                               };
+                               struct {
+                                       uint32_t MESMA2UDID_DEVICE      :16;
+                                       uint32_t MESMA2UDID_VENDOR      :16;
+                               };
+                               struct {
+                                       uint32_t                        :32;
+                               };
+                               struct {
+                                       uint32_t PCIEPCS1               :2;
+                                       uint32_t PCIEPCS2               :2;
+                                       uint32_t PCIELR1                :1;
+                                       uint32_t PCIELR2                :1;
+                                       uint32_t DMILR                  :1;
+                                       uint32_t                        :1;
+                                       uint32_t PHY_PCIEPORTSEL        :3;
+                                       uint32_t PHY_PCIE_EN            :1;
+                                       uint32_t                        :20;
+                               };
+                               struct {
+                                       uint32_t                        :1;
+                                       uint32_t ME_BOOT_FLASH          :1;
+                                       uint32_t cs_ss5                 :1;
+                                       uint32_t VE_EN                  :1;
+                                       uint32_t                        :4;
+                                       uint32_t MMDDE                  :1;
+                                       uint32_t MMADDR                 :7;
+                                       uint32_t cs_ss7                 :1;
+                                       uint32_t                        :1;
+                                       uint32_t ICC_SEL                :3;
+                                       uint32_t MER_CL1                :1;
+                                       uint32_t                        :10;
+                               };
+                               struct {
+                                       uint32_t SML1GPAEN              :1;
+                                       uint32_t SML1GPA                :7;
+                                       uint32_t                        :10;
+                                       uint32_t SML1I2CAEN             :1;
+                                       uint32_t SML1I2CA               :7;
+                               };
+                               struct {
+                                       uint32_t                        :32;
+                               };
+                               struct {
+                                       uint32_t                        :32;
+                               };
+                               struct {
+                                       uint32_t                        :8;
+                                       uint32_t VE_EN2                 :1;
+                                       uint32_t                        :5;
+                                       uint32_t VE_BOOT_FLASH          :1;
+                                       uint32_t                        :1;
+                                       uint32_t BW_SSD                 :1;
+                                       uint32_t NVMHCI_EN              :1;
+                                       uint32_t                        :14;
+                               };
+                               struct {
+                                       uint32_t                        :3;
+                                       uint32_t cs_ss6                 :2;
+                                       uint32_t                        :1;
+                                       uint32_t IWL_EN                 :1;
+                                       uint32_t                        :1;
+                                       uint32_t t209min                :2;
+                                       uint32_t                        :22;
+                               };
+                       };
+               }ibex;
+       };
+};
+
+struct flash_upper_map {
+       union {
+               uint32_t FLUMAP1;
+               struct {
+                       uint32_t VTBA   :8;
+                       uint32_t VTL    :8;
+                       uint32_t        :16;
+               };
+       };
+       struct {
+               union {
+                       uint32_t JID;
+                       struct {
+                               uint8_t vid     :8;
+                               uint8_t cid0    :8;
+                               uint8_t cid1    :8;
+                               uint32_t        :8;
+                       };
+               };
+               union {
+                       uint32_t VSCC;
+                       struct {
+                               uint32_t ubes   :2;
+                               uint32_t uwg    :1;
+                               uint32_t uwsr   :1;
+                               uint32_t uwews  :1;
+                               uint32_t        :3;
+                               uint32_t ueo    :8;
+                               uint32_t lbes   :2;
+                               uint32_t lwg    :1;
+                               uint32_t lwsr   :1;
+                               uint32_t lwews  :1;
+                               uint32_t        :3;
+                               uint32_t leo    :16;
+                       };
+               };
+       }vscc_table[128];
+};
+#endif // ICH_DESCRIPTORS_FROM_MMAP_DUMP
+
 struct flash_descriptors {
        struct flash_content content;
        struct flash_component component;
        struct flash_region region;
        struct flash_master master;
+#ifdef ICH_DESCRIPTORS_FROM_MMAP_DUMP
+       struct flash_strap straps;
+       struct flash_upper_map upper;
+#endif // ICH_DESCRIPTORS_FROM_MMAP_DUMP
 };
 
 void prettyprint_ich_descriptors(enum chipset, const struct flash_descriptors 
*desc);
@@ -252,7 +443,16 @@ void prettyprint_ich_descriptor_component(const struct 
flash_descriptors *desc);
 void prettyprint_ich_descriptor_region(const struct flash_region *region);
 void prettyprint_ich_descriptor_master(const struct flash_master *master);
 
+#ifdef ICH_DESCRIPTORS_FROM_MMAP_DUMP
+
+void prettyprint_ich_descriptor_upper_map(const struct flash_upper_map *umap);
+void prettyprint_ich_descriptor_straps(enum chipset cs, const struct 
flash_strap *straps);
+int read_ich_descriptors_from_dump(const uint32_t *dump, enum chipset cs, 
struct flash_descriptors *desc);
+
+#else // ICH_DESCRIPTORS_FROM_MMAP_DUMP
+
 void read_ich_descriptors_via_fdo(void *spibar, struct flash_descriptors 
*desc);
 
+#endif // ICH_DESCRIPTORS_FROM_MMAP_DUMP
 #endif // __ICH_DESCRIPTORS_H__
 #endif // defined(__i386__) || defined(__x86_64__)
diff --git a/util/ich_descriptors_tool/Makefile 
b/util/ich_descriptors_tool/Makefile
new file mode 100644
index 0000000..1d7f056
--- /dev/null
+++ b/util/ich_descriptors_tool/Makefile
@@ -0,0 +1,42 @@
+CC ?= gcc
+
+PROGRAM=ich_descriptors_tool
+EXTRAINCDIRS = ../../ .
+DEPPATH = .dep
+OBJATH = .obj
+SHAREDSRC = ich_descriptors.c
+SHAREDSRCDIR = ../..
+
+SRC = $(wildcard *.c)
+
+CFLAGS=-Wall
+CFLAGS += -MMD -MP -MF $(DEPPATH)/$(@F).d
+# enables functions that populate the descriptor structs from plain binary 
dumps
+CFLAGS += -D ICH_DESCRIPTORS_FROM_MMAP_DUMP
+CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
+
+OBJ = $(OBJATH)/$(SRC:%.c=%.o)
+
+SHAREDOBJ = $(OBJATH)/$(notdir $(SHAREDSRC:%.c=%.o))
+
+all:$(PROGRAM)
+
+$(OBJ): $(OBJATH)/%.o : %.c
+       $(CC) $(CFLAGS) -o $@ -c $<
+
+# this enables us to share source files without simultaneously sharing .o files
+# with flashrom, which would lead to unexpected results (w/o running make 
clean)
+$(SHAREDOBJ): $(OBJATH)/%.o : $(SHAREDSRCDIR)/%.c
+       $(CC) $(CFLAGS) -o $@ -c $<
+
+$(PROGRAM): $(OBJ) $(SHAREDOBJ)
+       $(CC) -o $(PROGRAM) $(OBJ) $(SHAREDOBJ)
+
+clean:
+       rm -f $(PROGRAM)
+       rm -rf $(DEPPATH) $(OBJATH)
+
+# Include the dependency files.
+-include $(shell mkdir -p $(DEPPATH) $(OBJATH) 2>/dev/null) $(wildcard 
$(DEPPATH)/*)
+
+.PHONY: all clean
diff --git a/util/ich_descriptors_tool/TODO b/util/ich_descriptors_tool/TODO
new file mode 100644
index 0000000..e3933ee
--- /dev/null
+++ b/util/ich_descriptors_tool/TODO
@@ -0,0 +1,5 @@
+- reverse the path, as in assemble a descriptormode image from various
+  blobs (BIOS, GbE, ME, OEM) and a description (xml? custom config?
+  sane defaults and cmd-line switches?)
+- dump 256 OEM bytes
+- handle descriptors of various chipsets correctly
\ No newline at end of file
diff --git a/util/ich_descriptors_tool/ich_descriptors_tool.c 
b/util/ich_descriptors_tool/ich_descriptors_tool.c
new file mode 100644
index 0000000..f6fd77a
--- /dev/null
+++ b/util/ich_descriptors_tool/ich_descriptors_tool.c
@@ -0,0 +1,197 @@
+/*
+ * This file is part of the flashrom project.
+ *
+ * Copyright (C) 2010  Matthias Wenzel <bios at mazzoo dot de>
+ * Copyright (C) 2011 Stefan Tauner
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+
+/*
+ * dump information and binaries from BIOS images that are in descriptor mode
+ */
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include "ich_descriptors.h"
+
+static void dump_file(const char *filename, const char *suf, uint32_t offset, 
uint32_t length, const uint32_t *dump)
+{
+       int ret;
+       char *n = malloc(strlen(filename) + strlen(suf) + 1);
+
+       if (!n) {
+               fprintf(stderr, "Out of memory!\n");
+               exit(1);
+       }
+       snprintf(n, strlen(filename) + strlen(suf) + 1, "%s%s", filename, suf);
+       printf("\n");
+       printf("+++ dumping %s... ", n);
+       int fh = open(n, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
+       free(n);
+       if (fh < 0) {
+               fprintf(stderr,
+                       "ERROR: couldn't open(%s): %s\n", n, strerror(errno));
+               exit(1);
+       }
+
+       ret = write(fh, &dump[offset >> 2], length);
+       if (ret != length) {
+               fprintf(stderr, "FAILED.\n");
+               exit(1);
+       }
+
+       printf("done.\n");
+       close(fh);
+}
+
+void dump_files(const char *n, const uint32_t *fm, struct flash_region *freg)
+{
+       printf("=== dumping section files ===\n");
+       if (freg->reg0_limit)
+               dump_file(n, ".descr.bin", freg->reg0_base, freg->reg0_limit, 
fm);
+       if (freg->reg1_limit)
+               dump_file(n, ".BIOS.bin", freg->reg1_base, freg->reg1_limit, 
fm);
+       if (freg->reg2_limit)
+               dump_file(n, ".ME.bin", freg->reg2_base, freg->reg2_limit, fm);
+       if (freg->reg3_limit) {
+               uint8_t *pMAC = (uint8_t *) &fm[freg->reg3_base >> 2];
+               dump_file(n, ".GbE.bin", freg->reg2_base, freg->reg2_limit, fm);
+               printf("the MAC-address might be: 
%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n",
+                       pMAC[0],
+                       pMAC[1],
+                       pMAC[2],
+                       pMAC[3],
+                       pMAC[4],
+                       pMAC[5]
+                       );
+       }
+}
+
+static void usage(char *argv[], char *error)
+{
+       if (error != NULL) {
+               fprintf(stderr, "%s\n", error);
+       }
+       printf("usage: '%s -f <image file name> [-c <chipset name>] [-d]'\n\n"
+"where <image file name> points to an image of the contents of the SPI 
flash.\n"
+"In case that image is really in descriptor mode %s\n"
+"will pretty print some of the contained information.\n"
+"To also print the data stored in the descriptor strap you have to indicate\n"
+"the chipset series with the '-c' parameter and one of the possible 
arguments:\n"
+"\t- \"ich8\",\n"
+"\t- \"ich9\",\n"
+"\t- \"ich10\",\n"
+"\t- \"5\" or \"ibex\" for Intel's 5 series chipsets,\n"
+"\t- \"6\" or \"cougar\" for Intel's 6 series chipsets,\n"
+"\t- \"7\" or \"panther\" for Intel's 7 series chipsets.\n"
+"If '-d' is specified some sections such as the BIOS image as seen by the CPU 
or\n"
+"the GbE blob that is required to initialize the GbE are also dumped to 
files.\n",
+       argv[0], argv[0]);
+       exit(1);
+}
+
+int main(int argc, char *argv[])
+{
+       int f;                  /* file descriptor to flash file */
+       unsigned int fs;        /* file size */
+       uint32_t *fm;           /* mmap'd file */
+
+       int opt;
+       int dump = 0;
+       const char *fn = NULL;
+       const char *csn = NULL;
+       enum chipset cs = CHIPSET_UNKNOWN;
+       struct flash_descriptors desc = {{ 0 }};
+
+       while ((opt = getopt(argc, argv, "df:c:")) != -1) {
+               switch (opt) {
+               case 'd':
+                       dump = 1;
+                       break;
+               case 'f':
+                       fn = optarg;
+                       break;
+               case 'c':
+                       csn = optarg;
+                       break;
+               default: /* '?' */
+                       usage(argv, NULL);
+               }
+       }
+       if (fn == NULL)
+               usage(argv,
+                     "Need a file name of a descriptor image to read from.");
+
+       f = open(fn, O_RDONLY);
+       if (f < 0)
+               usage(argv, "No such file");
+       fs = lseek(f, 0, SEEK_END);
+       if (fs < 0)
+               usage(argv, "Seeking to the end of the file failed");
+
+       fm = mmap(NULL, fs, PROT_READ, MAP_PRIVATE, f, 0);
+       if (fm == (void *) -1) {
+               /* fallback for stupid OSes like cygwin */
+               int ret;
+               fm = malloc(fs);
+               if (!fm)
+                       usage(argv, "Could not allocate memory");
+               lseek(f, 0, SEEK_SET);
+               ret = read(f, fm, fs);
+               if (ret != fs)
+                       usage(argv, "Seeking to the end of the file failed");
+       }
+       printf("flash image has a size of %d [0x%x] bytes.\n", fs, fs);
+       close(f);
+
+       if (csn != NULL) {
+               if (strcmp(csn, "ich8") == 0)
+                       cs = CHIPSET_ICH8;
+               else if (strcmp(csn, "ich9") == 0)
+                       cs = CHIPSET_ICH9;
+               else if (strcmp(csn, "ich10") == 0)
+                       cs = CHIPSET_ICH10;
+               else if ((strcmp(csn, "5") == 0) ||
+                        (strcmp(csn, "ibex") == 0))
+                       cs = CHIPSET_SERIES_5_IBEX_PEAK;
+               else if ((strcmp(csn, "6") == 0) ||
+                        (strcmp(csn, "cougar") == 0))
+                       cs = CHIPSET_SERIES_6_COUGAR_POINT;
+               else if ((strcmp(csn, "7") == 0) ||
+                        (strcmp(csn, "panther") == 0))
+                       cs = CHIPSET_SERIES_7_PANTHER_POINT;
+       }
+
+       if(read_ich_descriptors_from_dump(fm, cs, &desc)){
+               printf("not in descriptor mode\n");
+               exit(1);
+       }
+
+       prettyprint_ich_descriptors(cs, &desc);
+
+       if (dump == 1)
+               dump_files(fn, fm, &desc.region);
+
+       return 0;
+}
+
-- 
1.7.1


_______________________________________________
flashrom mailing list
[email protected]
http://www.flashrom.org/mailman/listinfo/flashrom

Reply via email to