additionally to what is available via FDOC/FDOD...<TODO>
Signed-off-by: Stefan Tauner <stefan.tauner(a)student.tuwien.ac.at>
---
ich_descriptors.c | 334 ++++++++++++++++++++++
ich_descriptors.h | 200 +++++++++++++
util/ich_descriptors_tool/Makefile | 42 +++
util/ich_descriptors_tool/TODO | 6 +
util/ich_descriptors_tool/ich_descriptors_tool.c | 191 ++++++++++++
5 files changed, 773 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 4156959..f4d8f88 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
+
+#include <stdio.h>
+#define DESCRIPTOR_MODE_MAGIC 0x0ff0a55a
+#define msg_pdbg printf
+#define msg_pspew printf
+#define getVTBA(flumap) (((flumap)->FLUMAP1 << 4) & 0x0ff0)
+
+#else
+
#include "flash.h" /* for msg_* */
+#endif // ICH_DESCRIPTORS_FROM_MMAP_DUMP
+
#define getFCBA(cont) (((cont)->FLMAP0 << 4) & 0x00000ff0)
#define getFRBA(cont) (((cont)->FLMAP0 >> 12) & 0x00000ff0)
#define getFMBA(cont) (((cont)->FLMAP1 << 4) & 0x00000ff0)
@@ -36,6 +49,12 @@ void prettyprint_ich_descriptors(enum chipset cs, const struct flash_descriptors
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)
@@ -202,6 +221,320 @@ 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_pdbg2("--- ICH ---\n");
+ msg_pdbg1("STRP0 0x%08x\n", straps->ich8.STRPs[0]);
+ msg_pdbg2("\n");
+
+ msg_pdbg2("--- ICH details ---\n");
+ msg_pdbg2("ME SMBus Address 1: 0x%02x\n", straps->ich8.ASD);
+ msg_pdbg2("ME SMBus Address 2: 0x%02x\n", straps->ich8.ASD2);
+ msg_pdbg2("ME SMBus Controller is connected to the %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 Select 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 LAN" : "PCI Express");
+ msg_pdbg2("%sn BMC Mode: "
+ "Intel AMT SMBus Controller 1 is connected to %s.\n",
+ straps->ich8.BMCMODE ? "I" : "Not i",
+ straps->ich8.BMCMODE ? "SMLink" : "SMBus");
+ msg_pdbg2("TCO is in %s Mode.\n",
+ straps->ich8.TCOMODE ? "Advanced TCO" : "Legacy/Compatible");
+ msg_pdbg2("ME A is %sabled.\n", straps->ich8.ME_DISABLE ? "dis" : "en");
+ msg_pdbg2("\n");
+
+ msg_pdbg2("--- MCH ---\n");
+ msg_pdbg1("STRP1 0x%08x\n", straps->ich8.STRPs[1]);
+ msg_pdbg2("\n");
+
+ msg_pdbg2("--- MCH details ---\n");
+ msg_pdbg2("ME B is %sabled.\n", straps->ich8.MDB ? "dis" : "en");
+ msg_pdbg1("\n");
+}
+
+static void prettyprint_ich_descriptor_straps_ibex_pciecs(uint8_t conf, uint8_t off)
+{
+ msg_pdbg2("PCI Express Port Configuration Strap %d: ", off+1);
+
+ off *= 4;
+ switch(conf){
+ case 0:
+ msg_pdbg2("4x1 Ports %d-%d (x1)", 1+off, 4+off);
+ break;
+ case 1:
+ msg_pdbg2("1x2, 2x1 Port %d (x2), Port %d (disabled), "
+ "Ports %d, %d (x1)", 1+off, 2+off, 3+off, 4+off);
+ break;
+ case 2:
+ msg_pdbg2("2x2 Port %d (x2), Port %d (x2), Ports "
+ "%d, %d (disabled)", 1+off, 3+off, 2+off, 4+off);
+ break;
+ case 3:
+ msg_pdbg2("1x4 Port %d (x4), Ports %d-%d (disabled)",
+ 1+off, 2+off, 4+off);
+ break;
+ }
+ msg_pdbg2("\n");
+}
+
+void prettyprint_ich_descriptor_straps_ibex(const struct flash_strap *s)
+{
+ int i;
+ const uint8_t const dec_t209min[4] = {
+ 100,
+ 50,
+ 5,
+ 1
+ };
+
+ msg_pdbg2("--- PCH ---\n");
+ for(i = 0; i <= 15; i++)
+ msg_pdbg1("PCHSTRP%-2d = 0x%08x\n", i, s->ibex.STRPs[i]);
+ msg_pdbg1("\n");
+
+ /* PCHSTRP1 */
+ msg_pdbg2("Chipset configuration Softstrap 2: %d\n", s->ibex.cs_ss2);
+ msg_pdbg2("Intel ME SMBus Select is %sabled.\n",
+ s->ibex.SMB_EN ? "en" : "dis");
+ msg_pdbg2("SMLink0 segment is %sabled.\n",
+ s->ibex.SML0_EN ? "en" : "dis");
+ msg_pdbg2("SMLink1 segment is %sabled.\n",
+ s->ibex.SML1_EN ? "en" : "dis");
+ msg_pdbg2("SMLink1 Frequency: %s\n",
+ (s->ibex.SML1FRQ == 1) ? "100 kHz" : "reserved");
+ msg_pdbg2("Intel ME SMBus Frequency: %s\n",
+ (s->ibex.SMB0FRQ == 1) ? "100 kHz" : "reserved");
+ msg_pdbg2("SMLink0 Frequency: %s\n",
+ (s->ibex.SML0FRQ == 1) ? "100 kHz" : "reserved");
+ msg_pdbg2("GPIO12 is used as %s.\n", s->ibex.LANPHYPC_GP12_SEL ?
+ "LAN_PHY_PWR_CTRL" : "general purpose output");
+
+ /* PCHSTRP2 */
+ msg_pdbg2("Chipset configuration Softstrap 3: 0x%x\n", s->ibex.cs_ss3);
+
+ /* PCHSTRP3 */
+ msg_pdbg2("ME SMBus ASD address is %sabled.\n",
+ s->ibex.MESMASDEN ? "en" : "dis");
+ msg_pdbg2("ME SMBus Controller ASD Target address: 0x%02x\n",
+ s->ibex.MESMASDA);
+ msg_pdbg2("ME SMBus I2C address is %sabled.\n",
+ s->ibex.MESMI2CEN ? "en" : "dis");
+ msg_pdbg2("ME SMBus I2C target address: 0x%02x\n",
+ s->ibex.MESMI2CA);
+
+ /* PCHSTRP4 */
+ /* PCHSTRP5 */
+ msg_pdbg2("Intel PHY is %s.\n",
+ (s->ibex.PHYCON == 2) ? "connected" :
+ (s->ibex.PHYCON == 0) ? "disconnected" : "reserved");
+ msg_pdbg2("GbE MAC SMBus address is %sabled.\n",
+ s->ibex.GBEMAC_SMBUS_ADDR_EN ? "en" : "dis");
+ msg_pdbg2("GbE MAC SMBus address: 0x%02x\n",
+ s->ibex.GBEMAC_SMBUS_ADDR);
+ msg_pdbg2("GbE PHY SMBus address: 0x%02x\n",
+ s->ibex.GBEPHY_SMBUS_ADDR);
+
+ /* PCHSTRP6 */
+ /* PCHSTRP7 */
+ msg_pdbg2("Intel ME SMBus Subsystem Vendor ID: 0x%04x\n",
+ s->ibex.MESMA2UDID_VENDOR);
+ msg_pdbg2("Intel ME SMBus Subsystem Device ID: 0x%04x\n",
+ s->ibex.MESMA2UDID_VENDOR);
+
+ /* PCHSTRP8 */
+ /* PCHSTRP9 */
+ prettyprint_ich_descriptor_straps_ibex_pciecs(s->ibex.PCIEPCS1, 0);
+ prettyprint_ich_descriptor_straps_ibex_pciecs(s->ibex.PCIEPCS1, 1);
+ msg_pdbg2("PCIe Lane Reversal 1: PCIe Lanes 0-3 are %sreserved.\n",
+ s->ibex.PCIELR1 ? "" : "not ");
+ msg_pdbg2("PCIe Lane Reversal 2: PCIe Lanes 4-7 are %sreserved.\n",
+ s->ibex.PCIELR2 ? "" : "not ");
+ msg_pdbg2("DMI Lane Reversal: DMI Lanes 0-3 are %sreserved.\n",
+ s->ibex.DMILR ? "" : "not ");
+ msg_pdbg2("Default PHY PCIe Port is %d.\n", s->ibex.PHY_PCIEPORTSEL+1);
+ msg_pdbg2("Integrated MAC/PHY communication over PCIe is %sabled.\n",
+ s->ibex.PHY_PCIE_EN ? "en" : "dis");
+
+ /* PCHSTRP10 */
+ msg_pdbg2("Management Engine will boot from %sflash.\n",
+ s->ibex.ME_BOOT_FLASH ? "" : "ROM, then ");
+ msg_pdbg2("Chipset configuration Softstrap 5: %d\n", s->ibex.cs_ss5);
+ msg_pdbg2("Virtualization Engine Enable 1 is %sabled.\n",
+ s->ibex.VE_EN ? "en" : "dis");
+ msg_pdbg2("ME Memory-attached Debug Display Device is %sabled.\n",
+ s->ibex.MMDDE ? "en" : "dis");
+ msg_pdbg2("ME Memory-attached Debug Display Device address: 0x%02x\n",
+ s->ibex.MMADDR);
+ msg_pdbg2("Chipset configuration Softstrap 7: %d\n", s->ibex.cs_ss7);
+ msg_pdbg2("Integrated Clocking Configuration is %d.\n",
+ (s->ibex.ICC_SEL == 7) ? 0 : s->ibex.ICC_SEL);
+ msg_pdbg2("PCH Signal CL_RST1# does %sassert when Intel ME performs a "
+ "reset.\n", s->ibex.MER_CL1 ? "" : "not");
+
+ /* PCHSTRP11 */
+ msg_pdbg2("SMLink1 GP Address is %sabled.\n",
+ s->ibex.SML1GPAEN ? "en" : "dis");
+ msg_pdbg2("SMLink1 controller General Purpose Target address: 0x%02x\n",
+ s->ibex.SML1GPA);
+ msg_pdbg2("SMLink1 I2C Target address is %sabled.\n",
+ s->ibex.SML1I2CAEN ? "en" : "dis");
+ msg_pdbg2("SMLink1 I2C Target address: 0x%02x\n",
+ s->ibex.SML1I2CA);
+
+ /* PCHSTRP12 */
+ /* PCHSTRP13 */
+ /* PCHSTRP14 */
+ msg_pdbg2("Virtualization Engine Enable 2 is %sabled.\n",
+ s->ibex.VE_EN2 ? "en" : "dis");
+ msg_pdbg2("Virtualization Engine will boot from %sflash.\n",
+ s->ibex.VE_BOOT_FLASH ? "" : "ROM, then ");
+ msg_pdbg2("Braidwood SSD functionality is %sabled.\n",
+ s->ibex.BW_SSD ? "en" : "dis");
+ msg_pdbg2("Braidwood NVMHCI functionality is %sabled.\n",
+ s->ibex.NVMHCI_EN ? "en" : "dis");
+
+ /* PCHSTRP15 */
+ msg_pdbg2("Chipset configuration Softstrap 6: %d\n", s->ibex.cs_ss6);
+ msg_pdbg2("Integrated wired LAN Solution is %sabled.\n",
+ s->ibex.IWL_EN ? "en" : "dis");
+ msg_pdbg2("t209 min Timing: %d ms\n",
+ dec_t209min[s->ibex.t209min]);
+ msg_pdbg2("\n");
+}
+
+void prettyprint_ich_descriptor_straps(enum chipset cs, const struct flash_strap *straps)
+{
+ msg_pdbg2("=== Softstraps ===\n");
+ 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\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("=== Upper Map Section ===\n");
+ msg_pdbg1("FLUMAP1 0x%08x\n", umap->FLUMAP1);
+ msg_pdbg1("\n");
+
+ msg_pdbg2("--- 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%08x\n", i, jid);
+ msg_pdbg2(" VSCC%d = 0x%08x\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.FLREGs[0] = dump[(getFRBA(&desc->content) >> 2) + 0];
+ desc->region.FLREGs[1] = dump[(getFRBA(&desc->content) >> 2) + 1];
+ desc->region.FLREGs[2] = dump[(getFRBA(&desc->content) >> 2) + 2];
+ desc->region.FLREGs[3] = dump[(getFRBA(&desc->content) >> 2) + 3];
+ desc->region.FLREGs[4] = dump[(getFRBA(&desc->content) >> 2) + 4];
+
+ /* 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;
@@ -244,4 +577,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 71327ad..e960d28 100644
--- a/ich_descriptors.h
+++ b/ich_descriptors.h
@@ -244,11 +244,202 @@ struct flash_master {
};
};
+#ifdef ICH_DESCRIPTORS_FROM_MMAP_DUMP
+struct flash_strap {
+ union {
+ union {
+ uint32_t STRPs[2];
+ struct {
+ struct { /* STRP1 */
+ 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 { /* STRP2 */
+ uint32_t MDB :1;
+ uint32_t :31;
+ };
+ };
+ }ich8;
+ union {
+ uint32_t STRPs[15];
+ struct {
+ struct { /* STRP1 */
+ 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 { /* STRP2 */
+ uint32_t cs_ss3 :4;
+ uint32_t :28;
+ };
+ struct { /* STRP3 */
+ uint32_t :8;
+ uint32_t MESMASDEN :1;
+ uint32_t MESMASDA :7;
+ uint32_t :8;
+ uint32_t MESMI2CEN :1;
+ uint32_t MESMI2CA :7;
+ };
+ struct { /* STRP4 */
+ uint32_t :32;
+ };
+ struct { /* STRP5 */
+ 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 { /* STRP6 */
+ uint32_t :32;
+ };
+ struct { /* STRP7 */
+ uint32_t :32;
+ };
+ struct { /* STRP8 */
+ uint32_t MESMA2UDID_VENDOR :16;
+ uint32_t MESMA2UDID_DEVICE :16;
+ };
+ struct { /* STRP8 */
+ uint32_t :32;
+ };
+ struct { /* STRP10 */
+ 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 { /* STRP11 */
+ 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 { /* STRP12 */
+ uint32_t SML1GPAEN :1;
+ uint32_t SML1GPA :7;
+ uint32_t :10;
+ uint32_t SML1I2CAEN :1;
+ uint32_t SML1I2CA :7;
+ };
+ struct { /* STRP13 */
+ uint32_t :32;
+ };
+ struct { /* STRP14 */
+ uint32_t :32;
+ };
+ struct { /* STRP15 */
+ 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 { /* STRP16 */
+ 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);
@@ -258,7 +449,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)/$((a)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..03701bf
--- /dev/null
+++ b/util/ich_descriptors_tool/TODO
@@ -0,0 +1,6 @@
+- 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
+- little endian only
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..68546c1
--- /dev/null
+++ b/util/ich_descriptors_tool/ich_descriptors_tool.c
@@ -0,0 +1,191 @@
+/*
+ * 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