[coreboot-gerrit] Patch set updated for coreboot: util/igbetool: Add tool for Intel GbE flash region generation

Damien Zammit (damien@zamaudio.com) gerrit at coreboot.org
Sat Nov 12 04:30:03 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 4ac3c877ba75dd282d84feb27b935b341bbe690a
Author: Damien Zammit <damien at zamaudio.com>
Date:   Fri Nov 11 16:35:07 2016 +1100

    util/igbetool: Add tool for Intel GbE flash region generation
    
    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] MAC address
    (otherwise generates an empty MAC address 00:00:00:00:00:00).
    
    TODO:
    
    - main() needs to parse more command line options
    - struct handling is endian safe, but using bitfields for I/O
      could be a problem due to implementation defined ordering
      of fields (?)
    
    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 | 159 +++++++++++++++++++++++++++
 util/igbetool/ich9m-helper.h |  34 ++++++
 util/igbetool/ich9m-spec.h   | 251 +++++++++++++++++++++++++++++++++++++++++++
 util/igbetool/igbetool.c     | 115 ++++++++++++++++++++
 util/igbetool/interface.h    |  42 ++++++++
 7 files changed, 680 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..32a4c50
--- /dev/null
+++ b/util/igbetool/ich9m-helper.c
@@ -0,0 +1,159 @@
+/*
+ * 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 i, 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);
+	}
+
+	/* Output 16 bit words in LE */
+	for (i = 0; i < GBE_WORDS16; i++) {
+		uint8_t blob0 = g->blob[i] & 0xff;
+		uint8_t blob1 = (g->blob[i] >> 8) & 0xff;
+		if (write(fd, &blob0, 1) != 1)
+			perror("Error while writing main");
+		if (write(fd, &blob1, 1) != 1)
+			perror("Error while writing main");
+	}
+	/* Write two copies as per spec */
+	for (i = 0; i < GBE_WORDS16; i++) {
+		uint8_t blob0 = g->blob[i] & 0xff;
+		uint8_t blob1 = (g->blob[i] >> 8) & 0xff;
+		if (write(fd, &blob0, 1) != 1)
+			perror("Error while writing backup");
+		if (write(fd, &blob1, 1) != 1)
+			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..4cd78f3
--- /dev/null
+++ b/util/igbetool/ich9m-spec.h
@@ -0,0 +1,251 @@
+/*
+ * 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 */
+#pragma pack(2)
+
+/* 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
+} __attribute__((packed));
+
+/* 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
+} __attribute__((packed));
+
+#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
+} __attribute__((packed));
+
+/* 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
+} __attribute__((packed));
+
+/* 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
+} __attribute__((packed));
+
+/* Word 0x15 */
+struct gbe_ich9m_ext_config_control_word_2 {
+	uint8_t reserved	: 8; // 0x00
+	uint8_t extphylen	: 8; // 0x05
+} __attribute__((packed));
+
+#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
+} __attribute__((packed));
+
+/* 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
+} __attribute__((packed));
+
+/* 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
+} __attribute__((packed));
+
+/* 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
+} __attribute__((packed));
+
+/* 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
+} __attribute__((packed));
+
+/* 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
+} __attribute__((packed));
+
+/* 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, ... }
+} __attribute__((packed));
+
+/* 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, ... }
+} __attribute__((packed));
+
+#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..de7c938
--- /dev/null
+++ b/util/igbetool/interface.h
@@ -0,0 +1,42 @@
+/*
+ * 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
+#define GBE_WORDS16 (GBE_SUBREGIONSIZE >> 1)
+
+/* Chipset GbE specification includes */
+#include "ich9m-spec.h"
+//TODO: #include "ich10-spec.h"
+
+union gbe {
+	/* GbE chipset models */
+	struct gbe_ich9m ich9m;
+	//TODO: struct gbe_ich10 ich10;
+
+	/* Raw access to 16 bit words (I/O) */
+	uint16_t blob[GBE_WORDS16];
+};
+
+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