[coreboot-gerrit] New patch to review for coreboot: util/igbetool: Initial tool for Intel GbE flash region generator

Damien Zammit (damien@zamaudio.com) gerrit at coreboot.org
Fri Nov 11 06:38:58 CET 2016


Damien Zammit (damien at zamaudio.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/17375

-gerrit

commit 0135178cb1431c393e6c7f192fcbf37e5321a6c3
Author: Damien Zammit <damien at zamaudio.com>
Date:   Fri Nov 11 16:35:07 2016 +1100

    util/igbetool: Initial tool for Intel GbE flash region generator
    
    The main() function needs work to parse command line options.
    However, the design of this tool is extensible to other chipset models.
    
    Currently, it generates a valid X200 GbE region based on configurable values
    in main(), and parses argv[1] for mac address, otherwise generates a null mac.
    
    Change-Id: I0bc72fe6e5a9730675387f06e21dec5d24a309ec
    Signed-off-by: Damien Zammit <damien at zamaudio.com>
---
 util/igbetool/Makefile       |  45 ++++++++
 util/igbetool/common.h       |  34 ++++++
 util/igbetool/ich9m-helper.c | 148 +++++++++++++++++++++++++
 util/igbetool/ich9m-helper.h |  34 ++++++
 util/igbetool/ich9m-spec.h   | 249 +++++++++++++++++++++++++++++++++++++++++++
 util/igbetool/igbetool.c     | 115 ++++++++++++++++++++
 util/igbetool/interface.h    |  37 +++++++
 7 files changed, 662 insertions(+)

diff --git a/util/igbetool/Makefile b/util/igbetool/Makefile
new file mode 100644
index 0000000..51cb3ac
--- /dev/null
+++ b/util/igbetool/Makefile
@@ -0,0 +1,45 @@
+#
+# igbetool - Generate Intel GigaBit Ethernet flash region
+#
+# Copyright (C) 2016 Damien Zammit <damien at zamaudio.com>
+#
+# 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 3 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.
+#
+
+PROGRAM = igbetool
+
+CC      = gcc
+INSTALL = /usr/bin/install
+PREFIX  = /usr/local
+CFLAGS  = -O2 -g -Wall -W -Werror
+LDFLAGS =
+
+OBJS = ich9m-helper.o igbetool.o
+
+all: dep $(PROGRAM)
+
+$(PROGRAM): $(OBJS)
+	$(CC) -o $(PROGRAM) $(OBJS) $(LDFLAGS)
+
+clean:
+	rm -f $(PROGRAM) *.o *~ flashregion_3_gbe.bin
+distclean: clean
+
+dep:
+	@$(CC) $(CFLAGS) -MM *.c > .dependencies
+
+%.o: %.c
+	$(CC) $(CFLAGS) -c -o $@ $<
+
+install: $(PROGRAM)
+	mkdir -p $(DESTDIR)$(PREFIX)/bin
+	$(INSTALL) $(PROGRAM) $(DESTDIR)$(PREFIX)/bin
+
+.PHONY: all clean distclean dep
diff --git a/util/igbetool/common.h b/util/igbetool/common.h
new file mode 100644
index 0000000..0427c2e
--- /dev/null
+++ b/util/igbetool/common.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2016 Damien Zammit <damien at zamaudio.com>
+ *
+ * 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 3 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.
+ */
+
+#ifndef COMMON_H
+#define COMMON_H
+
+#include <inttypes.h>
+
+/* Forward declaration */
+union gbe;
+
+struct macaddr {
+	char byte[6];
+};
+
+struct pciids {
+	uint16_t ssdid;	// Subsystem device id
+	uint16_t ssvid;	// Subsystem vendor id
+	uint16_t did;	// Device id
+	uint16_t vid;	// Vendor id
+};
+
+#endif
diff --git a/util/igbetool/ich9m-helper.c b/util/igbetool/ich9m-helper.c
new file mode 100644
index 0000000..3fd8513
--- /dev/null
+++ b/util/igbetool/ich9m-helper.c
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2016 Damien Zammit <damien at zamaudio.com>
+ *
+ * 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 3 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.
+ */
+
+#include "ich9m-helper.h"
+#include "interface.h"
+
+void
+set_chipset_defaults_ich9m(union gbe *g)
+{
+	int i;
+
+	// Hardcoded values for ICH9M
+	g->ich9m.reserved04 = 0xffff;
+	g->ich9m.version05 = 0x1083;
+	g->ich9m.reserved06 = 0xffff;
+	g->ich9m.reserved07 = 0xffff;
+	g->ich9m.pbalow = 0xffff;
+	g->ich9m.pbahigh = 0xffff;
+	g->ich9m.word0a.loadvid = 1;
+	g->ich9m.word0a.loadssid = 1;
+	g->ich9m.word0a.pmen = 1;
+	g->ich9m.word0a.auxpwr = 1;
+	g->ich9m.word0a.reserved4 = 1;
+	g->ich9m.init13.phy_enpwrdown = 1;
+	g->ich9m.init13.reserved1 = 0x5;
+	g->ich9m.init13.reserved3 = 1;
+	g->ich9m.init13.sign = 0x2;
+	g->ich9m.extcfg14.extcfgptr = 0x020;
+	g->ich9m.extcfg14.oemload = 1;
+	g->ich9m.extcfg14.reserved1 = 1;
+	g->ich9m.extcfg15.extphylen = 0x05;
+	g->ich9m.ledctl1.reserved2 = 1;
+	g->ich9m.ledctl1.reserved4 = 1;
+	g->ich9m.ledctl1.lplu_non_d0a = 1;
+	g->ich9m.ledctl1.gbedis_non_d0a = 1;
+	g->ich9m.reserved19 = 0x2b40;
+	g->ich9m.reserved1a = 0x0043;
+	g->ich9m.reserved1c = 0x10f5;
+	g->ich9m.reserved1d = 0xbaad;
+	g->ich9m._82567lm = 0x10f5;
+	g->ich9m._82567lf = 0x10bf;
+	g->ich9m.reserved20 = 0xbaad;
+	g->ich9m._82567v = 0x10cb;
+	g->ich9m.reserved22 = 0xbaad;
+	g->ich9m.reserved23 = 0xbaad;
+
+	// Hardcoded PXE setup (disabled)
+	g->ich9m.pxeregion.pxe30.defbootsel = 0x3;
+	g->ich9m.pxeregion.pxe30.ctrlsprompt = 0x3;
+	g->ich9m.pxeregion.pxe30.pxeabsent = 1;
+	g->ich9m.pxeregion.pxe31.disablemenu = 1;
+	g->ich9m.pxeregion.pxe31.disabletitle = 1;
+	g->ich9m.pxeregion.pxe31.signature = 1;
+	g->ich9m.pxeregion.pxe32.buildnum = 0x18;
+	g->ich9m.pxeregion.pxe32.minorversion = 0x3;
+	g->ich9m.pxeregion.pxe32.majorversion = 0x1;
+	g->ich9m.pxeregion.pxe33.basecodeabsent = 1;
+	g->ich9m.pxeregion.pxe33.undipresent = 1;
+	g->ich9m.pxeregion.pxe33.reserved1 = 1;
+	g->ich9m.pxeregion.pxe33.signature = 1;
+	for (i = 0; i < 11; i++) {
+		g->ich9m.pxeregion.padding[i] = 0xffff;
+	}
+
+	// GbE power settings
+	g->ich9m.lanpwr10.lan_d3pwr = LANPWR_100mW;
+	g->ich9m.lanpwr10.lan_d0pwr = 13 * LANPWR_100mW;
+
+	// GbE LED modes
+	g->ich9m.ledctl1.led1mode = LED_ACTIVITY;
+	g->ich9m.ledctl1.led1blinks = 1;
+	g->ich9m.ledctl02.led0mode = LED_LINK_UP;
+	g->ich9m.ledctl02.led2mode = LED_LINK_100_1000;
+
+	// Padding
+	for (i = 0; i < 0xf80; i++) {
+		g->ich9m.padding[i] = 0xff;
+	}
+}
+
+void
+set_mac_ich9m(union gbe *g, struct macaddr *m)
+{
+	g->ich9m.macaddress[0] = m->byte[0];
+	g->ich9m.macaddress[1] = m->byte[1];
+	g->ich9m.macaddress[2] = m->byte[2];
+	g->ich9m.macaddress[3] = m->byte[3];
+	g->ich9m.macaddress[4] = m->byte[4];
+	g->ich9m.macaddress[5] = m->byte[5];
+}
+
+void
+set_pciids_ich9m(union gbe *g, struct pciids *ids)
+{
+	g->ich9m.ssdid = ids->ssdid;
+	g->ich9m.ssvid = ids->ssvid;
+	g->ich9m.did = ids->did;
+	g->ich9m.vid = ids->vid;
+}
+
+void
+do_checksum_ich9m(union gbe *g)
+{
+	int i;
+	uint16_t total = 0;
+	uint16_t *gbeword = (uint16_t *)&(g->ich9m);
+
+	for (i = 0; i < 0x3f; i++) {
+		total += gbeword[i];
+	}
+
+	g->ich9m.checksum = GBE_ICH9M_CHECKSUMTOTAL - total;
+}
+
+void
+write_binary_ich9m(union gbe *g)
+{
+	char filename[22] = "flashregion_3_gbe.bin";
+	int fd;
+
+	printf("Generating 8KiB GbE region `%s`\n", filename);
+
+	fd = open(filename,
+			 O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
+			 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+	if (fd < 0) {
+		perror("Error while trying to open file");
+		exit(EXIT_FAILURE);
+	}
+	if (write(fd, &g->ich9m, GBE_SUBREGIONSIZE) != GBE_SUBREGIONSIZE)
+		perror("Error while writing main");
+	/* Write two copies as per spec */
+	if (write(fd, &g->ich9m, GBE_SUBREGIONSIZE) != GBE_SUBREGIONSIZE)
+		perror("Error while writing backup");
+	close(fd);
+}
+
diff --git a/util/igbetool/ich9m-helper.h b/util/igbetool/ich9m-helper.h
new file mode 100644
index 0000000..d499cf3
--- /dev/null
+++ b/util/igbetool/ich9m-helper.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2016 Damien Zammit <damien at zamaudio.com>
+ *
+ * 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 3 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.
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <inttypes.h>
+
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
+#include "common.h"
+
+void set_chipset_defaults_ich9m(union gbe *g);
+void set_mac_ich9m(union gbe *g, struct macaddr *m);
+void set_pciids_ich9m(union gbe *g, struct pciids *ids);
+void do_checksum_ich9m(union gbe *g);
+void write_binary_ich9m(union gbe *g);
diff --git a/util/igbetool/ich9m-spec.h b/util/igbetool/ich9m-spec.h
new file mode 100644
index 0000000..c99a9f6
--- /dev/null
+++ b/util/igbetool/ich9m-spec.h
@@ -0,0 +1,249 @@
+/*
+ * Copyright (C) 2014 Steve Shenton <sgsit at libreboot.org>
+ *                    Leah Rowe <info at minifree.org>
+ * Copyright (C) 2016 Damien Zammit <damien at zamaudio.com>
+ *
+ * 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 3 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.
+ */
+
+#ifndef IGBE_ICH9M_H
+#define IGBE_ICH9M_H
+
+#include <inttypes.h>
+
+/* Datasheets:
+ *
+ * http://www.intel.co.uk/content/dam/doc/application-note/i-o-controller-hub-9m-82567lf-lm-v-nvm-map-appl-note.pdf
+ * https://communities.intel.com/community/wired/blog/2010/10/14/how-to-basic-eeprom-checksums
+ */
+
+/* When adding up the first 0x3F 16-bit words in a 4KiB GBE sub-region,
+ * it should have a checksum such that 0xBABA = sum of words + checksum.
+ */
+#define GBE_ICH9M_CHECKSUMTOTAL 0xBABA
+
+/* NB: The GBE region of 8K is actually 2x 4K regions in a row.
+ * These 4K blocks can be identical (and we have seen they are in factory roms).
+ * The second one is a "backup", but we don't know when it is used.
+ * Perhaps it is used when the checksum on the first one does not match (?)
+ * We populate the full region with two identical 4K sub regions.
+ */
+
+/* 16-bits words:			Default value	value = meaning */
+
+/* Word 0x03 */
+struct gbe_ich9m_boot_agent {
+	uint8_t reserved1_0	: 8; // 00000000
+	uint8_t reserved1_1	: 3; // 000
+	uint8_t ibootagent	: 1; // 0		1 = Boot Agent ON
+	uint8_t reserved2	: 4; // 0000
+};
+
+/* Word 0x0A */
+struct gbe_ich9m_pci_init_control_word {
+	uint8_t loadvid		: 1; // 1		0 = load from MAC fuses
+	uint8_t loadssid	: 1; // 1		0 = load from MAC fuses
+	uint8_t reserved1	: 1; // 0
+	uint8_t reserved2	: 3; // 000
+	uint8_t pmen		: 1; // 1		0 = no power management
+	uint8_t auxpwr		: 1; // 1		0 = no auxpwr indicator
+	uint8_t reserved3	: 4; // 0000
+	uint8_t reserved4	: 4; // 0001
+};
+
+#define LANPWR_100mW 1
+
+/* Word 0x10 */
+struct gbe_ich9m_lan_pwr_word {
+	uint8_t lan_d3pwr	: 5; // 00001
+	uint8_t reserved	: 3; // 000
+	uint8_t lan_d0pwr	: 8; // 0x0d
+};
+
+/* Word 0x13 */
+struct gbe_ich9m_shared_init_control_word {
+	uint8_t reserved1	: 3; // 101
+	uint8_t force_halfduplex: 1; // 0		1 = force half duplex
+	uint8_t force_lowspeed	: 1; // 0		1 = force low speed
+	uint8_t reserved2_0	: 3; // 000
+	uint8_t reserved2_1	: 1; // 0
+	uint8_t phy_enpwrdown	: 1; // 1		0 = no PHY pwr off in D3
+	uint8_t reserved3	: 1; // 1
+	uint8_t reserved4	: 3; // 000
+	uint8_t sign		: 2; // 10
+};
+
+/* Word 0x14 */
+struct gbe_ich9m_ext_config_control_word_1 {
+	uint16_t extcfgptr	: 12;// 0x020
+	uint8_t oemload		: 1; // 1		0 = don't load oem bits
+	uint8_t reserved1	: 1; // 1
+	uint8_t reserved2	: 1; // 0
+	uint8_t reserved3	: 1; // 0
+};
+
+/* Word 0x15 */
+struct gbe_ich9m_ext_config_control_word_2 {
+	uint8_t reserved	: 8; // 0x00
+	uint8_t extphylen	: 8; // 0x05
+};
+
+#define LED_ACTIVITY 0xb
+#define LED_LINK_UP 0x2
+#define LED_LINK_100 0x6
+#define LED_LINK_100_1000 0x1
+
+/* Word 0x17: LED 1 Configuration and Power Management
+ *
+ * Default values for LEDCTL register fields controlling LED1 (LINK_1000)
+ * output behaviours and OEM fields that define PHY power management
+ * parameters loaded to the PHY_CTRL register.
+ */
+struct led_ctl_1 {
+	// See datasheet page 16 for different modes
+	uint8_t led1mode	: 4; // 0xb (ACTIVITY)
+	uint8_t reserved1	: 1; // 0
+	uint8_t led1fastblink	: 1; // 0		1 = fast blinking
+	uint8_t led1invert	: 1; // 0		1 = high active output
+	uint8_t led1blinks	: 1; // 1		0 = does not blink
+	uint8_t reserved2	: 1; // 1
+	uint8_t lplu_all	: 1; // 0
+	uint8_t lplu_non_d0a	: 1; // 1
+	uint8_t gbedis_non_d0a	: 1; // 1
+	uint8_t reserved3	: 2; // 00
+	uint8_t gbedis		: 1; // 0		1 = no gigabit speed
+	uint8_t reserved4	: 1; // 1
+};
+
+/* Word 0x18: LED 0 and 2 Configuration Defaults
+ *
+ * Hardware defaults for LEDCTL register fields controlling LED0 (LINK/ACTIVITY)
+ * and LED2 (LINK_100) output behaviours.
+ */
+struct led_ctl_0_2 {
+	// See datasheet page 16 for different modes
+	uint8_t led0mode	: 4; // 0x2 (LINK-UP)
+	uint8_t reserved1	: 1; // 0
+	uint8_t led0fastblink	: 1; // 0		1 = fast blinking
+	uint8_t led0invert	: 1; // 0		1 = high active output
+	uint8_t led0blinks	: 1; // 0		1 = led0 blinks
+	uint8_t led2mode	: 4; // 0x6 (LINK-100)
+	uint8_t reserved2	: 1; // 0
+	uint8_t led2fastblink	: 1; // 0		1 = fast blinking
+	uint8_t led2invert	: 1; // 0		1 = high active output
+	uint8_t led2blinks	: 1; // 0		1 = led2 blinks
+};
+
+/* Word 0x30 */
+struct gbe_ich9m_pxe_boot_agent_main_setup_options {
+	uint8_t protocolsel	: 2; // 00
+	uint8_t reserved1	: 1; // 0
+	uint8_t defbootsel	: 2; // 11		11 = local boot only
+	uint8_t reserved2	: 1; // 0
+	uint8_t ctrlsprompt	: 2; // 11		11 = 0 seconds
+	uint8_t dispsetup	: 1; // 0
+	uint8_t reserved3	: 1; // 0
+	uint8_t forcespeed	: 2; // 00		00 = auto-negotiate
+	uint8_t forcefullduplex	: 1; // 0
+	uint8_t reserved4	: 1; // 0
+	uint8_t efipresent	: 1; // 0		0 = efi absent
+	uint8_t pxeabsent	: 1; // 1		1 = pxe absent
+};
+
+/* Word 0x31 */
+struct gbe_ich9m_pxe_boot_agent_config_options_31 {
+	uint8_t disablemenu	: 1; // 1
+	uint8_t disabletitle	: 1; // 1
+	uint8_t disableprotsel	: 1; // 0
+	uint8_t disablebootorder: 1; // 0
+	uint8_t disablelegacywak: 1; // 0
+	uint8_t disableflash_pro: 1; // 0
+	uint8_t reserved1	: 2; // 00
+	uint8_t ibootagentmode	: 3; // 000		000 = normal behaviour
+	uint8_t reserved2	: 3; // 000
+	uint8_t signature	: 2; // 01		01 = configured
+};
+
+/* Word 0x32 */
+struct gbe_ich9m_pxe_boot_agent_config_options_32 {
+	uint8_t buildnum	: 8; // 0x18
+	uint8_t minorversion	: 4; // 0x3
+	uint8_t majorversion	: 4; // 0x1
+};
+
+/* Word 0x33 */
+struct gbe_ich9m_pxe_iba_capabilities {
+	uint8_t basecodeabsent	: 1; // 1		1 = basecode is absent
+	uint8_t undipresent	: 1; // 1		1 = UNDI is present
+	uint8_t reserved1	: 1; // 1
+	uint8_t efiundipresent	: 1; // 0		0 = EFI UNDI absent
+	uint8_t reserved2_0	: 4; // 0000
+	uint8_t reserved2_1	: 6; // 000000
+	uint8_t signature	: 2; // 01
+};
+
+/* Words 30h to 3Eh */
+struct gbe_ich9m_pxe_setup_region {
+	struct gbe_ich9m_pxe_boot_agent_main_setup_options	pxe30;
+	struct gbe_ich9m_pxe_boot_agent_config_options_31	pxe31;
+	struct gbe_ich9m_pxe_boot_agent_config_options_32	pxe32;
+	struct gbe_ich9m_pxe_iba_capabilities			pxe33;
+	uint16_t padding[11];		// { 0xffff, ... }
+};
+
+/* GbE 4KiB Record for ICH9M */
+struct gbe_ich9m {
+	uint8_t macaddress[6];		// aa:bb:cc:dd:ee:ff
+	struct gbe_ich9m_boot_agent word03;
+	uint16_t reserved04;		// 0xffff
+	uint16_t version05;		// 0x1083
+	uint16_t reserved06;		// 0xffff
+	uint16_t reserved07;		// 0xffff
+	uint16_t pbalow;		// 0xffff
+	uint16_t pbahigh;		// 0xffff
+	struct gbe_ich9m_pci_init_control_word word0a;
+	uint16_t ssdid;			// 0x20ee
+	uint16_t ssvid;			// 0x17aa
+	/* Word 0D: device ID
+	 * 10F5 is for Intel 82567LM
+	 * 10BF is for Intel 82567LF
+	 * 10CB is for Intel 82567V
+	 */
+	uint16_t did;			// 0x10f5 (X200)
+	uint16_t vid;			// 0x8086
+	uint16_t devrevid;		// 0x0000
+	struct gbe_ich9m_lan_pwr_word lanpwr10;
+	uint16_t reserved11;		// 0x0000
+	uint16_t reserved12;		// 0x0000
+	struct gbe_ich9m_shared_init_control_word init13;
+	struct gbe_ich9m_ext_config_control_word_1 extcfg14;
+	struct gbe_ich9m_ext_config_control_word_2 extcfg15;
+	uint16_t extcfg16;		// 0x0000
+	struct led_ctl_1 ledctl1;
+	struct led_ctl_0_2 ledctl02;
+	uint16_t reserved19;		// 0x2b40
+	uint16_t reserved1a;		// 0x0043
+	uint16_t reserved1b;		// 0x0000
+	uint16_t reserved1c;		// 0x10f5
+	uint16_t reserved1d;		// 0xbaad
+	uint16_t _82567lm;		// 0x10f5
+	uint16_t _82567lf;		// 0x10bf
+	uint16_t reserved20;		// 0xbaad
+	uint16_t _82567v;		// 0x10cb
+	uint16_t reserved22;		// 0xbaad
+	uint16_t reserved23;		// 0xbaad
+	uint16_t reserved24_2F[12];	// { 0 }
+	struct gbe_ich9m_pxe_setup_region pxeregion;
+	uint16_t checksum;		// = 0xBABA - sum of words above
+	uint8_t padding[0xf80];		// { 0xff, ... }
+};
+
+#endif
diff --git a/util/igbetool/igbetool.c b/util/igbetool/igbetool.c
new file mode 100644
index 0000000..674bab4
--- /dev/null
+++ b/util/igbetool/igbetool.c
@@ -0,0 +1,115 @@
+/*
+ * igbetool - Generates Intel GigaBit Ethernet flash region
+ * Copyright (C) 2016 Damien Zammit <damien at zamaudio.com>
+ *
+ * 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 3 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.
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
+#include "common.h"
+#include "ich9m-helper.h"
+#include "interface.h"
+
+#define ICH9M 0
+#define ICH10 1
+struct gbe_interface chipset[] = {
+	{
+		.set_chipset_defaults = set_chipset_defaults_ich9m,
+		.set_mac = set_mac_ich9m,
+		.set_pciids = set_pciids_ich9m,
+		.write_binary = write_binary_ich9m,
+		.do_checksum = do_checksum_ich9m,
+	},
+/*
+	{
+		.set_chipset_defaults = set_chipset_defaults_ich10,
+		.set_mac = set_mac_ich10,
+		.set_pciids = set_pciids_ich10,
+		.write_binary = write_binary_ich10,
+		.do_checksum = do_checksum_ich10,
+	}
+*/
+	{},
+};
+
+static struct gbe_interface gbemodel;
+static union gbe gberecord;
+
+static struct macaddr parsemac(char *mac)
+{
+	struct macaddr m = { 0 };
+	int i, j;
+
+	for (i = 0; i < 6; i++) {
+		/* Go through each nibble of the byte */
+		for (j = 0; j < 2; j++) {
+			if (mac[(i*3) + j] >= 'a' && mac[(i*3) + j] <= 'f')
+				m.byte[i] |= (uint8_t)(
+					(mac[(i*3)+j] - 87) << ((j^1) << 2)
+					);
+			else if (mac[(i*3) + j] >= 'A' && mac[(i*3) + j] <= 'F')
+				m.byte[i] |= (uint8_t)(
+					(mac[(i*3) + j] - 55) << ((j^1) << 2)
+					);
+			else if (mac[(i*3) +j ] >= '0' && mac[(i*3) + j] <= '9')
+				m.byte[i] |= (uint8_t)(
+					(mac[(i*3) + j] - 48) << ((j^1) << 2)
+					);
+			else {
+				printf("Error: MAC address invalid \n");
+				exit(1);
+			}
+		}
+	}
+	return m;
+}
+
+int main(int argc, char *argv[]) {
+	struct pciids ids = { 0 };
+	struct macaddr mac = { 0 };
+	int i = ICH9M;
+
+	switch (i) {
+	default:
+	case ICH9M: gbemodel = chipset[ICH9M]; break;
+	//case ICH10: gbemodel = chipset[ICH10]; break;
+	}
+
+	// Configurable IDs based on model
+	ids.ssdid = 0x20ee;
+	ids.ssvid = 0x17aa;
+	ids.did = 0x10f5;
+	ids.vid = 0x8086;
+
+	// MAC address
+	if (argc == 2) {
+		mac = parsemac(argv[1]);
+	}
+
+	gbemodel.set_chipset_defaults (&gberecord);
+	gbemodel.set_mac (&gberecord, &mac);
+	gbemodel.set_pciids (&gberecord, &ids);
+	gbemodel.do_checksum (&gberecord);
+	gbemodel.write_binary (&gberecord);
+
+	return 0;
+}
diff --git a/util/igbetool/interface.h b/util/igbetool/interface.h
new file mode 100644
index 0000000..7514cc7
--- /dev/null
+++ b/util/igbetool/interface.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2016 Damien Zammit <damien at zamaudio.com>
+ *
+ * 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 3 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.
+ */
+#ifndef INTERFACE_H
+#define INTERFACE_H
+
+#define GBE_FULLREGIONSIZE 0x2000
+#define GBE_SUBREGIONSIZE 0x1000
+
+/* Chipset GbE specification includes */
+#include "ich9m-spec.h"
+//TODO: #include "ich10-spec.h"
+
+union gbe {
+	struct gbe_ich9m ich9m;
+	//struct gbe_ich10 ich10;
+};
+
+struct gbe_interface {
+	void (*set_chipset_defaults) (union gbe *);
+	void (*set_mac) (union gbe *, struct macaddr *);
+	void (*set_pciids) (union gbe *, struct pciids *);
+	void (*do_checksum) (union gbe *);
+	void (*write_binary) (union gbe *);
+};
+
+#endif



More information about the coreboot-gerrit mailing list