[coreboot-gerrit] Patch set updated for coreboot: fd8f2f2 autoport: Experimental stuff

Vladimir Serbinenko (phcoder@gmail.com) gerrit at coreboot.org
Mon Oct 27 00:25:39 CET 2014


Vladimir Serbinenko (phcoder at gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/7131

-gerrit

commit fd8f2f270717445939063b0e307ce4c27ff10688
Author: Vladimir Serbinenko <phcoder at gmail.com>
Date:   Wed Oct 15 21:51:47 2014 +0200

    autoport: Experimental stuff
    
    Change-Id: Ia126cf0939ef2dc2cdbb7ea100d2b63ea6b02f28
    Signed-off-by: Vladimir Serbinenko <phcoder at gmail.com>
---
 util/autoport/azalia.go      |  54 +++++
 util/autoport/bd82x6x.go     | 181 ++++++++++++++++
 util/autoport/hardcoded.go   | 407 +++++++++++++++++++++++++++++++++++
 util/autoport/i82801gx.go    | 265 +++++++++++++++++++++++
 util/autoport/i945.go        |  82 +++++++
 util/autoport/log_maker.go   |  77 +++++++
 util/autoport/log_reader.go  | 264 +++++++++++++++++++++++
 util/autoport/main.go        | 500 +++++++++++++++++++++++++++++++++++++++++++
 util/autoport/root.go        |  28 +++
 util/autoport/sandybridge.go | 112 ++++++++++
 10 files changed, 1970 insertions(+)

diff --git a/util/autoport/azalia.go b/util/autoport/azalia.go
new file mode 100644
index 0000000..97e3449
--- /dev/null
+++ b/util/autoport/azalia.go
@@ -0,0 +1,54 @@
+package main
+
+import (
+	"fmt"
+)
+
+type azalia struct {
+}
+
+func (i azalia) Scan(ctx Context, addr PCIDevData) {
+	az := Create(ctx, "hda_verb.c")
+	defer az.Close()
+
+	az.WriteString(
+		`#include <device/azalia_device.h>
+
+const u32 cim_verb_data[] = {
+`)
+
+	for _, codec := range ctx.InfoSource.GetAzaliaCodecs() {
+		fmt.Fprintf(az, "\t0x%08x, /* Codec Vendor / Device ID: %s */\n",
+			codec.VendorID, codec.Name)
+		fmt.Fprintf(az, "\t0x%08x, /* Subsystem ID */\n",
+			codec.SubsystemID)
+		fmt.Fprintf(az, "\n\t0x%08x, /* Number of 4 dword sets */\n",
+			len(codec.PinConfig)+1)
+		fmt.Fprintf(az, "\t/* NID 0x01: Subsystem ID.  */\n")
+		fmt.Fprintf(az, "\tAZALIA_SUBVENDOR(0x%x, 0x%08x),\n",
+			codec.CodecNo, codec.SubsystemID)
+
+		for nid, val := range codec.PinConfig {
+			fmt.Fprintf(az, "\n\t/* NID 0x%02x: Subsystem ID.  */\n", nid)
+			fmt.Fprintf(az, "\tAZALIA_PIN_CFG(0x%x, 0x%02x, 0x%08x),\n",
+				codec.CodecNo, nid, val)
+		}
+	}
+
+	az.WriteString(
+		`};
+
+const u32 pc_beep_verbs[0] = {};
+
+AZALIA_ARRAY_SIZES;
+`)
+
+	PutPCIDev(addr, "Audio controller")
+}
+
+func init() {
+	/* I82801GX/I945 */
+	RegisterPCI(0x8086, 0x27d8, azalia{})
+	/* C216/ivybridge */
+	RegisterPCI(0x8086, 0x1e20, azalia{})
+}
diff --git a/util/autoport/bd82x6x.go b/util/autoport/bd82x6x.go
new file mode 100644
index 0000000..e7c6e75
--- /dev/null
+++ b/util/autoport/bd82x6x.go
@@ -0,0 +1,181 @@
+package main
+
+import (
+	"fmt"
+	"os"
+)
+
+type bd82x6x struct {
+	variant string
+}
+
+func (b bd82x6x) writeGPIOSet(ctx Context, sb *os.File,
+	val uint32, set uint, partno int) {
+
+	max := uint(32)
+	if set == 3 {
+		max = 12
+	}
+
+	bits := [6][2]string{
+		{ "GPIO_MODE_NATIVE", "GPIO_MODE_GPIO"    },
+		{ "GPIO_DIR_OUTPUT",  "GPIO_DIR_INPUT"    },
+		{ "GPIO_LEVEL_LOW",   "GPIO_LEVEL_HIGH"   },
+		{ "GPIO_RESET_PWROK", "GPIO_RESET_RSMRST" },
+		{ "GPIO_NO_INVERT",   "GPIO_INVERT"       },
+		{ "GPIO_NO_BLINK",    "GPIO_BLINK"        },
+	}
+
+	for i := uint(0); i < max; i++ {
+		fmt.Fprintf(sb, "	.gpio%d = %s,\n",
+			(set - 1) * 32 + i,
+			bits[partno][(val >> i) & 1])
+	}
+}
+
+
+func (b bd82x6x) GPIO(ctx Context, inteltool InteltoolData) {
+	gpio := Create(ctx, "gpio.c")
+	defer gpio.Close()
+
+	AddROMstageFile("gpio.c", "")
+
+	gpio.WriteString(`#include "southbridge/intel/bd82x6x/gpio.h"
+`)
+
+	adresses := [3][6]int{
+		{ 0x00, 0x04, 0x0c, 0x60, 0x2c, 0x18 },
+		{ 0x30, 0x34, 0x38, 0x64, -1, -1 },
+		{ 0x40, 0x44, 0x48, 0x68, -1, -1 },
+	}
+
+	for set := 1; set <= 3; set++ {
+		for partno, part := range []string{"mode", "direction", "level", "reset", "invert", "blink"} {
+			addr := adresses[set-1][partno]
+			if addr < 0 {
+				continue
+			}
+			fmt.Fprintf(gpio, "const struct pch_gpio_set%d pch_gpio_set%d_%s = {\n",
+				set, set, part)
+
+			b.writeGPIOSet(ctx, gpio, inteltool.GPIO[uint16(addr)], uint(set), partno)
+			gpio.WriteString("};\n\n")
+		}
+	}
+
+	gpio.WriteString(`static const struct pch_gpio_map mainboard_gpio_map = {
+	.set1 = {
+		.mode		= &pch_gpio_set1_mode,
+		.direction	= &pch_gpio_set1_direction,
+		.level		= &pch_gpio_set1_level,
+		.blink		= &pch_gpio_set1_blink,
+		.invert		= &pch_gpio_set1_invert,
+		.reset		= &pch_gpio_set1_reset,
+	},
+	.set2 = {
+		.mode		= &pch_gpio_set2_mode,
+		.direction	= &pch_gpio_set2_direction,
+		.level		= &pch_gpio_set2_level,
+		.reset		= &pch_gpio_set2_reset,
+	},
+	.set3 = {
+		.mode		= &pch_gpio_set3_mode,
+		.direction	= &pch_gpio_set3_direction,
+		.level		= &pch_gpio_set3_level,
+		.reset		= &pch_gpio_set3_reset,
+	},
+};
+`)
+}
+
+func (b bd82x6x) Scan(ctx Context, addr PCIDevData) {
+	inteltool := ctx.InfoSource.GetInteltool()
+	b.GPIO(ctx, inteltool)
+
+	KconfigBool["SOUTHBRIDGE_INTEL_" + b.variant] = true
+	/* FIMXE: move */
+	KconfigBool["HAVE_SMI_HANDLER"] = true
+	KconfigInt["IRQ_SLOT_COUNT"] = 18
+	/* FIXME: hardcoded */
+	KconfigBool["SERIRQ_CONTINUOUS_MODE"] = true
+	/* FIXME: hardcoded */
+	KconfigInt["USBDEBUG_HCD_INDEX"] = 2
+	/* FIXME: hardcoded */
+	KconfigInt["DRAM_RESET_GATE_GPIO"] = 10
+
+	FADT := ctx.InfoSource.GetACPI()["FACP"]
+
+	cur := DevTreeNode{
+		Chip:          "southbridge/intel/bd82x6x",
+		Comment:       "Intel Series 6 Cougar Point PCH",
+		Registers: map[string]string{
+			/* FIXME: hardcoded. */
+			"alt_gp_smi_en": "0x0000",
+			"gpi1_routing": "2",
+			"gpi8_routing": "2",
+			"sata_port_map": "0x7",
+			"sata_interface_speed_support": "0x3",
+			"gen1_dec": "0x7c1601",
+			"gen2_dec": "0x0c15e1",
+			"gen4_dec": "0x0c06a1",
+			"pcie_port_coalesce": "1",
+
+			"p_cnt_throttling_supported": (FormatBool(FADT[104] == 1 && FADT[105] == 3)),
+			"c2_latency": FormatHexLE16(FADT[96:98]),
+			"docking_supported": (FormatBool((FADT[113] & (1 << 1)) != 0)),
+		},
+		PCISlots: []PCISlot{
+			PCISlot{PCIAddr:PCIAddr{Dev: 0x14, Func: 0}, writeEmpty: false, additionalComment: "USB 3.0 Controller"},
+			PCISlot{PCIAddr:PCIAddr{Dev: 0x16, Func: 0}, writeEmpty: true, additionalComment: "Management Engine Interface 1"},
+			PCISlot{PCIAddr:PCIAddr{Dev: 0x16, Func: 1}, writeEmpty: true, additionalComment: "Management Engine Interface 2"},
+			PCISlot{PCIAddr:PCIAddr{Dev: 0x16, Func: 2}, writeEmpty: true, additionalComment: "Management Engine IDE-R"},
+			PCISlot{PCIAddr:PCIAddr{Dev: 0x16, Func: 3}, writeEmpty: true, additionalComment: "Management Engine KT"},
+			PCISlot{PCIAddr:PCIAddr{Dev: 0x19, Func: 0}, writeEmpty: true, additionalComment: "Intel Gigabit Ethernet"},
+			PCISlot{PCIAddr:PCIAddr{Dev: 0x1a, Func: 0}, writeEmpty: true, additionalComment: "USB2 EHCI #2"},
+			PCISlot{PCIAddr:PCIAddr{Dev: 0x1b, Func: 0}, writeEmpty: true, additionalComment: "High Definition Audio"},
+			PCISlot{PCIAddr:PCIAddr{Dev: 0x1c, Func: 0}, writeEmpty: true, additionalComment: "PCIe Port #1"},
+			PCISlot{PCIAddr:PCIAddr{Dev: 0x1c, Func: 1}, writeEmpty: true, additionalComment: "PCIe Port #2"},
+			PCISlot{PCIAddr:PCIAddr{Dev: 0x1c, Func: 2}, writeEmpty: true, additionalComment: "PCIe Port #3"},
+			PCISlot{PCIAddr:PCIAddr{Dev: 0x1c, Func: 3}, writeEmpty: true, additionalComment: "PCIe Port #4"},
+			PCISlot{PCIAddr:PCIAddr{Dev: 0x1c, Func: 4}, writeEmpty: true, additionalComment: "PCIe Port #5"},
+			PCISlot{PCIAddr:PCIAddr{Dev: 0x1c, Func: 5}, writeEmpty: true, additionalComment: "PCIe Port #6"},
+			PCISlot{PCIAddr:PCIAddr{Dev: 0x1c, Func: 6}, writeEmpty: true, additionalComment: "PCIe Port #7"},
+			PCISlot{PCIAddr:PCIAddr{Dev: 0x1c, Func: 7}, writeEmpty: true, additionalComment: "PCIe Port #8"},
+			PCISlot{PCIAddr:PCIAddr{Dev: 0x1d, Func: 0}, writeEmpty: true, additionalComment: "USB2 EHCI #1"},
+			PCISlot{PCIAddr:PCIAddr{Dev: 0x1e, Func: 0}, writeEmpty: true, additionalComment: "PCI bridge"},
+			PCISlot{PCIAddr:PCIAddr{Dev: 0x1f, Func: 0}, writeEmpty: true, additionalComment: "LPC bridge"},
+			PCISlot{PCIAddr:PCIAddr{Dev: 0x1f, Func: 2}, writeEmpty: true, additionalComment: "SATA Controller 1"},
+			PCISlot{PCIAddr:PCIAddr{Dev: 0x1f, Func: 3}, writeEmpty: true, additionalComment: "SMBus"},
+			PCISlot{PCIAddr:PCIAddr{Dev: 0x1f, Func: 5}, writeEmpty: true, additionalComment: "SATA Controller 2"},
+			PCISlot{PCIAddr:PCIAddr{Dev: 0x1f, Func: 6}, writeEmpty: true, additionalComment: "Thermal"},
+		},
+	}
+
+	PutChip("pcibus0", cur)
+	PutPCIDevParent(addr, "PCI-LPC bridge", "lpc")
+
+	DSDTIncludes = append(DSDTIncludes, DSDTInclude{
+		File:    "southbridge/intel/bd82x6x/acpi/globalnvs.asl",
+		Comment: "global NVS and variables",
+	})
+	DSDTIncludes = append(DSDTIncludes, DSDTInclude{
+		File: "southbridge/intel/bd82x6x/acpi/sleepstates.asl",
+	})
+	DSDTPCI0Includes = append(DSDTPCI0Includes, DSDTInclude{
+		File: "southbridge/intel/bd82x6x/acpi/pch.asl",
+	})
+}
+
+func init() {
+	RegisterPCI(0x8086, 0x1e55, bd82x6x{variant:"C216"})
+	RegisterPCI(0x8086, 0x1e31, GenericPCI{})
+	RegisterPCI(0x8086, 0x1e26, GenericPCI{})
+	RegisterPCI(0x8086, 0x1e2d, GenericPCI{})
+	RegisterPCI(0x8086, 0x1e3a, GenericPCI{})
+	RegisterPCI(0x8086, 0x1502, GenericPCI{})
+	RegisterPCI(0x8086, 0x1e10, GenericPCI{})
+	RegisterPCI(0x8086, 0x1e12, GenericPCI{})
+	RegisterPCI(0x8086, 0x1e14, GenericPCI{})
+	RegisterPCI(0x8086, 0x1e03, GenericPCI{})
+	RegisterPCI(0x8086, 0x1e22, GenericPCI{MissingParent: "smbus"})
+}
diff --git a/util/autoport/hardcoded.go b/util/autoport/hardcoded.go
new file mode 100644
index 0000000..584ddd8
--- /dev/null
+++ b/util/autoport/hardcoded.go
@@ -0,0 +1,407 @@
+package main
+
+func Hardcoded(ctx Context) {
+	ai := Create(ctx, "acpi/ich7_pci_irqs.asl")
+	defer ai.Close()
+
+	/* FIXME: hardcoded.  */
+	ai.WriteString(
+		`/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+/* This is board specific information: IRQ routing for the
+ * 0:1e.0 PCI bridge of the ICH7
+ */
+
+If (PICM) {
+	Return (Package() {
+		Package (0x04) { 0x0000FFFF, 0x00, 0x00, 0x15 },
+		Package (0x04) { 0x0000FFFF, 0x01, 0x00, 0x16 },
+		Package (0x04) { 0x0000FFFF, 0x02, 0x00, 0x17 },
+		Package (0x04) { 0x0000FFFF, 0x03, 0x00, 0x14 },
+		Package (0x04) { 0x0001FFFF, 0x00, 0x00, 0x16 },
+		Package (0x04) { 0x0001FFFF, 0x01, 0x00, 0x15 },
+		Package (0x04) { 0x0001FFFF, 0x02, 0x00, 0x14 },
+		Package (0x04) { 0x0001FFFF, 0x03, 0x00, 0x17 },
+		Package (0x04) { 0x0002FFFF, 0x00, 0x00, 0x12 },
+		Package (0x04) { 0x0002FFFF, 0x01, 0x00, 0x13 },
+		Package (0x04) { 0x0002FFFF, 0x02, 0x00, 0x11 },
+		Package (0x04) { 0x0002FFFF, 0x03, 0x00, 0x10 },
+		Package (0x04) { 0x0003FFFF, 0x00, 0x00, 0x13 },
+		Package (0x04) { 0x0003FFFF, 0x01, 0x00, 0x12 },
+		Package (0x04) { 0x0003FFFF, 0x02, 0x00, 0x15 },
+		Package (0x04) { 0x0003FFFF, 0x03, 0x00, 0x16 },
+		Package (0x04) { 0x0005FFFF, 0x00, 0x00, 0x11 },
+		Package (0x04) { 0x0005FFFF, 0x01, 0x00, 0x14 },
+		Package (0x04) { 0x0005FFFF, 0x02, 0x00, 0x16 },
+		Package (0x04) { 0x0005FFFF, 0x03, 0x00, 0x15 },
+		Package (0x04) { 0x0008FFFF, 0x00, 0x00, 0x14 }
+	})
+ } Else {
+	Return (Package() {
+		Package (0x04) { 0x0000FFFF, 0x00, \_SB.PCI0.LPCB.LNKF, 0x00 },
+		Package (0x04) { 0x0000FFFF, 0x01, \_SB.PCI0.LPCB.LNKG, 0x00 },
+		Package (0x04) { 0x0000FFFF, 0x02, \_SB.PCI0.LPCB.LNKH, 0x00 },
+		Package (0x04) { 0x0000FFFF, 0x03, \_SB.PCI0.LPCB.LNKE, 0x00 },
+		Package (0x04) { 0x0001FFFF, 0x00, \_SB.PCI0.LPCB.LNKG, 0x00 },
+		Package (0x04) { 0x0001FFFF, 0x01, \_SB.PCI0.LPCB.LNKF, 0x00 },
+		Package (0x04) { 0x0001FFFF, 0x02, \_SB.PCI0.LPCB.LNKE, 0x00 },
+		Package (0x04) { 0x0001FFFF, 0x03, \_SB.PCI0.LPCB.LNKH, 0x00 },
+		Package (0x04) { 0x0002FFFF, 0x00, \_SB.PCI0.LPCB.LNKC, 0x00 },
+		Package (0x04) { 0x0002FFFF, 0x01, \_SB.PCI0.LPCB.LNKD, 0x00 },
+		Package (0x04) { 0x0002FFFF, 0x02, \_SB.PCI0.LPCB.LNKB, 0x00 },
+		Package (0x04) { 0x0002FFFF, 0x03, \_SB.PCI0.LPCB.LNKA, 0x00 },
+		Package (0x04) { 0x0003FFFF, 0x00, \_SB.PCI0.LPCB.LNKD, 0x00 },
+		Package (0x04) { 0x0003FFFF, 0x01, \_SB.PCI0.LPCB.LNKC, 0x00 },
+		Package (0x04) { 0x0003FFFF, 0x02, \_SB.PCI0.LPCB.LNKF, 0x00 },
+		Package (0x04) { 0x0003FFFF, 0x03, \_SB.PCI0.LPCB.LNKG, 0x00 },
+		Package (0x04) { 0x0005FFFF, 0x00, \_SB.PCI0.LPCB.LNKB, 0x00 },
+		Package (0x04) { 0x0005FFFF, 0x01, \_SB.PCI0.LPCB.LNKE, 0x00 },
+		Package (0x04) { 0x0005FFFF, 0x02, \_SB.PCI0.LPCB.LNKG, 0x00 },
+		Package (0x04) { 0x0005FFFF, 0x03, \_SB.PCI0.LPCB.LNKF, 0x00 },
+		Package (0x04) { 0x0008FFFF, 0x00, \_SB.PCI0.LPCB.LNKE, 0x00 }
+	})
+}
+`)
+	ap := Create(ctx, "acpi/platform.asl")
+	defer ap.Close()
+
+	/* FIXME: hardcoded.  */
+	ap.WriteString(
+		`Method(_WAK,1)
+{
+	Return(Package(){0,0})
+}
+
+Scope(\_SB)
+{
+	Method(_INI, 0)
+	{
+		\GOS()
+	}
+}
+`)
+	sh := Create(ctx, "smihandler.c")
+	defer sh.Close()
+
+	/* FIXME: hardcoded.  */
+	sh.WriteString(
+		`
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008-2009 coresystems GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#include <arch/io.h>
+#include <console/console.h>
+#include <cpu/x86/smm.h>
+#include "southbridge/intel/i82801gx/nvs.h"
+#include "southbridge/intel/i82801gx/i82801gx.h"
+#include <pc80/mc146818rtc.h>
+#include <delay.h>
+
+static void mainboard_smm_init(void)
+{
+	printk(BIOS_DEBUG, "initializing SMI\n");
+}
+
+int mainboard_io_trap_handler(int smif)
+{
+	static int smm_initialized;
+
+	if (!smm_initialized) {
+		mainboard_smm_init();
+		smm_initialized = 1;
+	}
+
+	switch (smif) {
+	default:
+		return 0;
+	}
+
+	/* On success, the IO Trap Handler returns 1
+	 * On failure, the IO Trap Handler returns a value != 1 */
+	return 1;
+}
+
+int mainboard_smi_apmc(u8 data)
+{
+	u16 pmbase = pci_read_config16(PCI_DEV(0, 0x1f, 0), 0x40) & 0xfffc;
+	u8 tmp;
+
+	printk(BIOS_DEBUG, "%s: pmbase %04X, data %02X\n", __func__, pmbase, data);
+
+	if (!pmbase)
+		return 0;
+
+	switch(data) {
+		case APM_CNT_ACPI_ENABLE:
+			/* route H8SCI to SCI */
+			outw(inw(ALT_GP_SMI_EN) & ~0x1000, pmbase + ALT_GP_SMI_EN);
+			tmp = pci_read_config8(PCI_DEV(0, 0x1f, 0), 0xbb);
+			tmp &= ~0x03;
+			tmp |= 0x02;
+			pci_write_config8(PCI_DEV(0, 0x1f, 0), 0xbb, tmp);
+			break;
+		case APM_CNT_ACPI_DISABLE:
+			/* route H8SCI# to SMI */
+			outw(inw(pmbase + ALT_GP_SMI_EN) | 0x1000, pmbase + ALT_GP_SMI_EN);
+			tmp = pci_read_config8(PCI_DEV(0, 0x1f, 0), 0xbb);
+			tmp &= ~0x03;
+			tmp |= 0x01;
+			pci_write_config8(PCI_DEV(0, 0x1f, 0), 0xbb, tmp);
+			break;
+		default:
+			break;
+	}
+	return 0;
+}
+`)
+	mb := Create(ctx, "mainboard.c")
+	defer mb.Close()
+
+	/* FIXME: hardcoded.  */
+	mb.WriteString(
+		`/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ * Copyright (C) 2011 Sven Schnelle <svens at stackframe.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#include <console/console.h>
+#include <device/device.h>
+#include <arch/io.h>
+#include <delay.h>
+#include <device/pci_def.h>
+#include <device/pci_ops.h>
+#include <device/pci_ids.h>
+#include <arch/io.h>
+#include <arch/interrupt.h>
+#include <northbridge/intel/i945/i945.h>
+#include <pc80/mc146818rtc.h>
+#include <arch/x86/include/arch/acpigen.h>
+#include <smbios.h>
+#include <drivers/intel/gma/int15.h>
+#define PANEL INT15_5F35_CL_DISPLAY_DEFAULT
+
+int get_cst_entries(acpi_cstate_t **entries)
+{
+	return 0;
+}
+
+static void mainboard_init(device_t dev)
+{
+	install_intel_vga_int15_handler(GMA_INT15_ACTIVE_LFP_INT_LVDS, GMA_INT15_PANEL_FIT_DEFAULT, PANEL, 3);
+}
+
+static void mainboard_enable(device_t dev)
+{
+	dev->ops->init = mainboard_init;
+}
+
+struct chip_operations mainboard_ops = {
+	.enable_dev = mainboard_enable,
+};
+`)
+
+	em := Create(ctx, "early_mainboard.h")
+	defer em.Close()
+
+	/* FIXME: hardcoded.  */
+	em.WriteString(
+		`void ich7_enable_lpc(void);
+void rcba_config(void);
+void early_ich7_init(void);
+`)
+
+	rs := Create(ctx, "romstage.c")
+	defer rs.Close()
+
+	/* FIXME: hardcoded.  */
+	rs.WriteString(
+		`/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ * Copyright (C) 2011 Sven Schnelle <svens at stackframe.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+// __PRE_RAM__ means: use "unsigned" for device, not a struct.
+
+#include <stdint.h>
+#include <string.h>
+#include <arch/io.h>
+#include <device/pci_def.h>
+#include <cpu/x86/lapic.h>
+#include <timestamp.h>
+#include <console/console.h>
+#include <cpu/x86/bist.h>
+#include "northbridge/intel/i945/i945.h"
+#include "northbridge/intel/i945/raminit.h"
+#include "early_mainboard.h"
+
+void main(unsigned long bist)
+{
+	int s3resume = 0;
+	const u8 spd_addrmap[2 * DIMM_SOCKETS] = { 0x50, 0x51, 0x52, 0x53 };
+
+	timestamp_init(get_initial_timestamp());
+	timestamp_add_now(TS_START_ROMSTAGE);
+
+	if (bist == 0)
+		enable_lapic();
+
+	/* Force PCIRST# */
+	pci_write_config16(PCI_DEV(0, 0x1e, 0), BCTRL, SBR);
+	udelay(200 * 1000);
+	pci_write_config16(PCI_DEV(0, 0x1e, 0), BCTRL, 0);
+
+	ich7_enable_lpc();
+
+	/* Set up the console */
+	console_init();
+
+	/* Halt if there was a built in self test failure */
+	report_bist_failure(bist);
+
+	if (MCHBAR16(SSKPD) == 0xCAFE) {
+		printk(BIOS_DEBUG,
+		       "Soft reset detected, rebooting properly.\n");
+		outb(0x6, 0xcf9);
+		while (1)
+			asm("hlt");
+	}
+
+	/* Perform some early chipset initialization required
+	 * before RAM initialization can work
+	 */
+	i945_early_initialization();
+
+	s3resume = southbridge_detect_s3_resume();
+
+	/* Enable SPD ROMs and DDR-II DRAM */
+	enable_smbus();
+
+#if CONFIG_DEFAULT_CONSOLE_LOGLEVEL > 8
+	dump_spd_registers();
+#endif
+
+	timestamp_add_now(TS_BEFORE_INITRAM);
+	sdram_initialize(s3resume ? 2 : 0, spd_addrmap);
+	timestamp_add_now(TS_AFTER_INITRAM);
+
+	/* Perform some initialization that must run before stage2 */
+	early_ich7_init();
+
+	/* This should probably go away. Until now it is required
+	 * and mainboard specific
+	 */
+	rcba_config();
+
+	/* Chipset Errata! */
+	fixup_i945_errata();
+
+	/* Initialize the internal PCIe links before we go into stage2 */
+	i945_late_initialization(s3resume);
+
+	timestamp_add_now(TS_END_ROMSTAGE);
+}
+`)
+
+	at := Create(ctx, "acpi_tables.c")
+	defer at.Close()
+
+	/* FIXME: hardcoded.  */
+	at.WriteString(
+		`#include <stdint.h>
+#include "southbridge/intel/i82801gx/nvs.h"
+void acpi_create_gnvs(global_nvs_t *gnvs)
+{
+	/* Enable both COM ports */
+	gnvs->cmap = 0x01;
+	gnvs->cmbp = 0x01;
+
+	/* IGD Displays */
+	gnvs->ndid = 3;
+	gnvs->did[0] = 0x80000100;
+	gnvs->did[1] = 0x80000240;
+	gnvs->did[2] = 0x80000410;
+	gnvs->did[3] = 0x80000410;
+	gnvs->did[4] = 0x00000005;
+}
+`)
+
+	av := Create(ctx, "acpi/video.asl")
+	defer av.Close()
+
+	ec := Create(ctx, "acpi/ec.asl")
+	defer ec.Close()
+
+	si := Create(ctx, "acpi/superio.asl")
+	defer si.Close()
+}
diff --git a/util/autoport/i82801gx.go b/util/autoport/i82801gx.go
new file mode 100644
index 0000000..f82de8a
--- /dev/null
+++ b/util/autoport/i82801gx.go
@@ -0,0 +1,265 @@
+package main
+
+import (
+	"fmt"
+	"os"
+)
+
+type i82801gx struct {
+}
+
+func (i i82801gx) writeGPIO(ctx Context, sb *os.File, inteltool InteltoolData, addr uint16, name string) {
+	fmt.Fprintf(sb, "	outl(0x%08x, DEFAULT_GPIOBASE + %s);\n",
+		inteltool.GPIO[addr], name)
+}
+
+func (i i82801gx) Scan(ctx Context, addr PCIDevData) {
+
+	/* FIXME: Move to southbbridge.  */
+	KconfigBool["HAVE_MP_TABLE"] = true
+
+	KconfigBool["SOUTHBRIDGE_INTEL_I82801GX"] = true
+	KconfigInt["IRQ_SLOT_COUNT"] = 18
+
+	sb := Create(ctx, "early_southbridge.c")
+	defer sb.Close()
+	AddROMstageFile("early_southbridge.c", "")
+	sb.WriteString(`#include <stdint.h>
+#include <arch/io.h>
+#include <device/pci_def.h>
+#include <console/console.h>
+#include "northbridge/intel/i945/i945.h"
+#include "southbridge/intel/i82801gx/i82801gx.h"
+#include "early_mainboard.h"
+
+void setup_ich7_gpios(void)
+{
+	printk(BIOS_DEBUG, " GPIOS...");
+
+`)
+	inteltool := ctx.InfoSource.GetInteltool()
+	i.writeGPIO(ctx, sb, inteltool, 0x0, "GPIO_USE_SEL")
+	i.writeGPIO(ctx, sb, inteltool, 0x4, "GP_IO_SEL")
+	i.writeGPIO(ctx, sb, inteltool, 0xc, "GP_LVL")
+	i.writeGPIO(ctx, sb, inteltool, 0x18, "GPO_BLINK")
+	i.writeGPIO(ctx, sb, inteltool, 0x2c, "GPI_INV")
+	i.writeGPIO(ctx, sb, inteltool, 0x30, "GPIO_USE_SEL2")
+	i.writeGPIO(ctx, sb, inteltool, 0x34, "GP_IO_SEL2")
+	i.writeGPIO(ctx, sb, inteltool, 0x38, "GP_LVL2")
+
+	sb.WriteString(`}
+
+void ich7_enable_lpc(void)
+{
+	// Enable Serial IRQ
+	pci_write_config8(PCI_DEV(0, 0x1f, 0), 0x64, 0xd0);
+
+	// Enable address decodes
+	/* FIXME: Make sure that all regions are properly reserved.  */
+`)
+
+	/* FIXME: Make sure that all regions are properly reserved.  */
+	RestorePCI16Simple(sb, addr, 0x80)
+	RestorePCI16Simple(sb, addr, 0x82)
+	RestorePCI16Simple(sb, addr, 0x84)
+	RestorePCI16Simple(sb, addr, 0x86)
+	RestorePCI16Simple(sb, addr, 0x88)
+	RestorePCI16Simple(sb, addr, 0x8a)
+	RestorePCI16Simple(sb, addr, 0x8c)
+	RestorePCI16Simple(sb, addr, 0x8e)
+	RestorePCI16Simple(sb, addr, 0x90)
+	RestorePCI16Simple(sb, addr, 0x92)
+
+	/* Just use the same interrupt map for all boards: just registers have to match ACPI.  */
+	sb.WriteString(`}
+
+void rcba_config(void)
+{
+	/* V0CTL Virtual Channel 0 Resource Control */
+	RCBA32(0x0014) = 0x80000001;
+	/* V1CAP Virtual Channel 1 Resource Capability */
+	RCBA32(0x001c) = 0x03128010;
+
+	/* Disable devices.  */
+`)
+
+	RestoreRCBA32(sb, inteltool, 0x3418)
+
+	sb.WriteString(`
+	/* Set up I/O Trap #3 for 0x800-0x80c (Trap) */
+	RCBA32(0x1e9c) = 0x000200f0;
+	RCBA32(0x1e98) = 0x000c0801;
+}
+`)
+
+	/* FIXME: does this one need adjustments?  */
+	sb.WriteString(`void early_ich7_init(void)
+{
+	uint8_t reg8;
+	uint32_t reg32;
+
+	// program secondary mlt XXX byte?
+	pci_write_config8(PCI_DEV(0, 0x1e, 0), 0x1b, 0x20);
+
+	// reset rtc power status
+	reg8 = pci_read_config8(PCI_DEV(0, 0x1f, 0), 0xa4);
+	reg8 &= ~(1 << 2);
+	pci_write_config8(PCI_DEV(0, 0x1f, 0), 0xa4, reg8);
+
+	// usb transient disconnect
+	reg8 = pci_read_config8(PCI_DEV(0, 0x1f, 0), 0xad);
+	reg8 |= (3 << 0);
+	pci_write_config8(PCI_DEV(0, 0x1f, 0), 0xad, reg8);
+
+	reg32 = pci_read_config32(PCI_DEV(0, 0x1d, 7), 0xfc);
+	reg32 |= (1 << 29) | (1 << 17);
+	pci_write_config32(PCI_DEV(0, 0x1d, 7), 0xfc, reg32);
+
+	reg32 = pci_read_config32(PCI_DEV(0, 0x1d, 7), 0xdc);
+	reg32 |= (1 << 31) | (1 << 27);
+	pci_write_config32(PCI_DEV(0, 0x1d, 7), 0xdc, reg32);
+
+	RCBA32(0x0088) = 0x0011d000;
+	RCBA16(0x01fc) = 0x060f;
+	RCBA32(0x01f4) = 0x86000040;
+	RCBA32(0x0214) = 0x10030549;
+	RCBA32(0x0218) = 0x00020504;
+	RCBA8(0x0220) = 0xc5;
+	reg32 = RCBA32(0x3410);
+	reg32 |= (1 << 6);
+	RCBA32(0x3410) = reg32;
+	reg32 = RCBA32(0x3430);
+	reg32 &= ~(3 << 0);
+	reg32 |= (1 << 0);
+	RCBA32(0x3430) = reg32;
+	RCBA32(0x3418) |= (1 << 0);
+	RCBA16(0x0200) = 0x2008;
+	RCBA8(0x2027) = 0x0d;
+	RCBA16(0x3e08) |= (1 << 7);
+	RCBA16(0x3e48) |= (1 << 7);
+	RCBA32(0x3e0e) |= (1 << 7);
+	RCBA32(0x3e4e) |= (1 << 7);
+
+	// next step only on ich7m b0 and later:
+	reg32 = RCBA32(0x2034);
+	reg32 &= ~(0x0f << 16);
+	reg32 |= (5 << 16);
+	RCBA32(0x2034) = reg32;
+}
+`)
+
+	Hardcoded(ctx)
+
+	ioapic := DevTreeNode{
+		Chip: "drivers/generic/ioapic",
+		Registers: map[string]string{
+			/* FIXME: hardcoded. */
+			"have_isa_interrupts": "1",
+			"irq_on_fsb":          "1",
+			"enable_virtual_wire": "0",
+			"base":                "0xfec00000",
+		},
+		Children: []DevTreeNode{
+			{
+				Chip: "ioapic",
+				Dev:  2,
+			},
+		},
+	}
+
+	PutChip("pcibus0", ioapic)
+
+	ideConfig := PCIMap[PCIAddr{Bus: 0, Dev: 0x1f, Func: 1}].ConfigDump[0x54]
+
+	FADT := ctx.InfoSource.GetACPI()["FACP"]
+
+	cur := DevTreeNode{
+		Chip:          "southbridge/intel/i82801gx",
+		Comment:       "Southbridge",
+		MissingParent: "southbridge",
+		Registers: map[string]string{
+			/* FIXME: should be a CMOS config */
+			"sata_ahci": "0x1",
+			/* FIXME: hardcoded. */
+			"gpi1_routing":  "2",
+			"gpi7_routing":  "2",
+			"gpe0_en":       "0x11000006",
+			"alt_gp_smi_en": "0x1000",
+
+			"sata_ports_implemented": fmt.Sprintf("0x%x", PCIMap[PCIAddr{Bus: 0, Dev: 0x1f, Func: 2}].ConfigDump[0x92]&0xf),
+			"ide_enable_primary":     fmt.Sprintf("%d", (ideConfig>>1)&1),
+			"ide_enable_secondary":   fmt.Sprintf("%d", (ideConfig>>3)&1),
+			"c4onc3_enable":          fmt.Sprintf("%d", ((addr.ConfigDump[0xa0] >> 7) & 1)),
+			"p_cnt_throttling_supported": (FormatBool(FADT[104] == 1 && FADT[105] == 3)),
+			"c3_latency": FormatHexLE16(FADT[98:100]),
+			"docking_supported": (FormatBool((FADT[113] & (1 << 1)) != 0)),
+		},
+		PCISlots: []PCISlot{
+			PCISlot{PCIAddr:PCIAddr{Dev: 0x1b, Func: 0}, writeEmpty: true, additionalComment: "High Definition Audio"},
+			PCISlot{PCIAddr:PCIAddr{Dev: 0x1c, Func: 0}, writeEmpty: true, additionalComment: "PCIe Port #1"},
+			PCISlot{PCIAddr:PCIAddr{Dev: 0x1c, Func: 1}, writeEmpty: true, additionalComment: "PCIe Port #2"},
+			PCISlot{PCIAddr:PCIAddr{Dev: 0x1c, Func: 2}, writeEmpty: true, additionalComment: "PCIe Port #3"},
+			PCISlot{PCIAddr:PCIAddr{Dev: 0x1c, Func: 3}, writeEmpty: true, additionalComment: "PCIe Port #4"},
+			PCISlot{PCIAddr:PCIAddr{Dev: 0x1c, Func: 4}, writeEmpty: true, additionalComment: "PCIe Port #5"},
+			PCISlot{PCIAddr:PCIAddr{Dev: 0x1c, Func: 5}, writeEmpty: true, additionalComment: "PCIe Port #6"},
+			PCISlot{PCIAddr:PCIAddr{Dev: 0x1c, Func: 6}, writeEmpty: true, additionalComment: "PCIe Port #7"},
+			PCISlot{PCIAddr:PCIAddr{Dev: 0x1c, Func: 7}, writeEmpty: true, additionalComment: "PCIe Port #8"},
+			PCISlot{PCIAddr:PCIAddr{Dev: 0x1d, Func: 0}, writeEmpty: true, additionalComment: "USB UHCI"},
+			PCISlot{PCIAddr:PCIAddr{Dev: 0x1d, Func: 1}, writeEmpty: true, additionalComment: "USB UHCI"},
+			PCISlot{PCIAddr:PCIAddr{Dev: 0x1d, Func: 2}, writeEmpty: true, additionalComment: "USB UHCI"},
+			PCISlot{PCIAddr:PCIAddr{Dev: 0x1d, Func: 3}, writeEmpty: true, additionalComment: "USB UHCI"},
+			PCISlot{PCIAddr:PCIAddr{Dev: 0x1d, Func: 7}, writeEmpty: true, additionalComment: "USB EHCI"},
+			PCISlot{PCIAddr:PCIAddr{Dev: 0x1e, Func: 0}, writeEmpty: true, additionalComment: "PCI bridge"},
+			PCISlot{PCIAddr:PCIAddr{Dev: 0x1f, Func: 0}, writeEmpty: true, additionalComment: "LPC bridge"},
+			PCISlot{PCIAddr:PCIAddr{Dev: 0x1f, Func: 1}, writeEmpty: true, additionalComment: "IDE Controller"},
+			PCISlot{PCIAddr:PCIAddr{Dev: 0x1f, Func: 2}, writeEmpty: true, additionalComment: "SATA Controller"},
+			PCISlot{PCIAddr:PCIAddr{Dev: 0x1f, Func: 3}, writeEmpty: true, additionalComment: "SMBus"},
+		},
+	}
+
+	PutChip("pcibus0", cur)
+	PutPCIDevParent(addr, "PCI-LPC bridge", "lpc")
+
+	IOAPICIRQs[PCIAddr{Bus: 0, Dev: 0x00}] = IOAPICIRQ{APICID: 2, IRQNO: [4]int{0x10, 0, 0, 0}}
+	IOAPICIRQs[PCIAddr{Bus: 0, Dev: 0x07}] = IOAPICIRQ{APICID: 2, IRQNO: [4]int{0x10, 0, 0, 0}}
+	IOAPICIRQs[PCIAddr{Bus: 0, Dev: 0x1b}] = IOAPICIRQ{APICID: 2, IRQNO: [4]int{0x16, 0, 0, 0}}
+	IOAPICIRQs[PCIAddr{Bus: 0, Dev: 0x1c}] = IOAPICIRQ{APICID: 2, IRQNO: [4]int{0x11, 0x10, 0x12, 0x13}}
+	IOAPICIRQs[PCIAddr{Bus: 0, Dev: 0x1d}] = IOAPICIRQ{APICID: 2, IRQNO: [4]int{0x17, 0x13, 0x12, 0x10}}
+	IOAPICIRQs[PCIAddr{Bus: 0, Dev: 0x1e}] = IOAPICIRQ{APICID: 2, IRQNO: [4]int{0x16, 0x14, 0, 0}}
+	IOAPICIRQs[PCIAddr{Bus: 0, Dev: 0x1f}] = IOAPICIRQ{APICID: 2, IRQNO: [4]int{0x12, 0x13, 0, 0x10}}
+
+	DSDTIncludes = append(DSDTIncludes, DSDTInclude{
+		File:    "southbridge/intel/i82801gx/acpi/globalnvs.asl",
+		Comment: "global NVS and variables",
+	})
+	DSDTIncludes = append(DSDTIncludes, DSDTInclude{
+		File: "southbridge/intel/i82801gx/acpi/platform.asl",
+	})
+	DSDTIncludes = append(DSDTIncludes, DSDTInclude{
+		File: "southbridge/intel/i82801gx/acpi/sleepstates.asl",
+	})
+	DSDTPCI0Includes = append(DSDTPCI0Includes, DSDTInclude{
+		File: "southbridge/intel/i82801gx/acpi/ich7.asl",
+	})
+}
+
+func init() {
+	RegisterPCI(0x8086, 0x27b9, i82801gx{})
+	RegisterPCI(0x8086, 0x27c8, GenericPCI{})
+	RegisterPCI(0x8086, 0x27c9, GenericPCI{})
+	RegisterPCI(0x8086, 0x27ca, GenericPCI{})
+	RegisterPCI(0x8086, 0x27cb, GenericPCI{})
+	RegisterPCI(0x8086, 0x27cc, GenericPCI{})
+
+	RegisterPCI(0x8086, 0x27d0, GenericPCI{})
+	RegisterPCI(0x8086, 0x27d2, GenericPCI{})
+	RegisterPCI(0x8086, 0x27d4, GenericPCI{})
+	RegisterPCI(0x8086, 0x27d6, GenericPCI{})
+
+	RegisterPCI(0x8086, 0x2448, GenericPCI{})
+
+	RegisterPCI(0x8086, 0x27c5, GenericPCI{})
+	RegisterPCI(0x8086, 0x27c4, GenericPCI{})
+	RegisterPCI(0x8086, 0x27df, GenericPCI{})
+	RegisterPCI(0x8086, 0x27da, GenericPCI{MissingParent:"smbus"})
+}
diff --git a/util/autoport/i945.go b/util/autoport/i945.go
new file mode 100644
index 0000000..013197e
--- /dev/null
+++ b/util/autoport/i945.go
@@ -0,0 +1,82 @@
+package main
+
+type i945mc struct {
+}
+
+func (i i945mc) Scan(ctx Context, addr PCIDevData) {
+	DevTree = DevTreeNode{
+		Chip:          "northbridge/intel/i945",
+		MissingParent: "northbridge",
+		Registers: map[string]string{
+			/* FIXME: hardcoded.  */
+			"gpu_hotplug":                        "0x00000220",
+			"gpu_lvds_use_spread_spectrum_clock": "1",
+			"gpu_lvds_is_dual_channel":           "0",
+			"gpu_backlight":                      "0x1280128",
+		},
+		Children: []DevTreeNode{
+			{
+				Chip: "cpu_cluster",
+				Dev:  0,
+				Children: []DevTreeNode{
+					{
+						Chip: "cpu/intel/socket_mFCPGA478",
+						Children: []DevTreeNode{
+							{
+								Chip: "lapic",
+								Dev:  0,
+							},
+						},
+					},
+				},
+			},
+			{
+				Chip:          "domain",
+				Dev:           0,
+				MissingParent: "pcibus0",
+				PCIController: true,
+				ChildPCIBus: 0,
+			},
+		},
+	}
+	PutPCIDev(addr, "Host bridge")
+
+	/* FIXME: Move part to northbridge?  */
+	/* FIXME: some configs are unsupported.  */
+	KconfigBool["MAINBOARD_HAS_NATIVE_VGA_INIT"] = true
+	KconfigBool["MAINBOARD_HAS_NATIVE_VGA_INIT_TEXTMODECFG"] = true
+	KconfigBool["VGA"] = true
+	KconfigBool["MAINBOARD_DO_EDID"] = true
+	KconfigBool["EARLY_CBMEM_INIT"] = true
+	KconfigBool["INTEL_EDID"] = true
+	KconfigBool["CPU_INTEL_SOCKET_MFCPGA478"] = true
+	KconfigBool["NORTHBRIDGE_INTEL_I945"] = true
+	KconfigBool["CHANNEL_XOR_RANDOMIZATION"] = true
+	KconfigBool["INTEL_INT15"] = true
+	KconfigBool["HAVE_ACPI_TABLES"] = true
+	KconfigBool["HAVE_ACPI_RESUME"] = true
+
+	KconfigHex["DCACHE_RAM_BASE"] = 0xffdf8000
+	KconfigHex["DCACHE_RAM_SIZE"] = 0x8000
+	KconfigHex["MMCONF_BASE_ADDRESS"] = 0xf0000000
+	KconfigInt["MAX_CPUS"] = 2
+
+	DSDTIncludes = append(DSDTIncludes, DSDTInclude{
+		File: "cpu/intel/model_6dx/acpi/cpu.asl",
+	})
+
+	DSDTPCI0Includes = append(DSDTPCI0Includes, DSDTInclude{
+		File: "northbridge/intel/i945/acpi/i945.asl",
+	})
+
+	/* FIXME: when adding new i945 variants change this.  */
+	KconfigBool["NORTHBRIDGE_INTEL_SUBTYPE_I945GM"] = true
+}
+
+func init() {
+	RegisterPCI(0x8086, 0x27a0, i945mc{})
+	RegisterPCI(0x8086, 0x27ac, i945mc{})
+	RegisterPCI(0x8086, 0x27a2, GenericVGA{GenericPCI{Comment:"VGA controller"}})
+	RegisterPCI(0x8086, 0x27ae, GenericVGA{GenericPCI{Comment:"VGA controller"}})
+	RegisterPCI(0x8086, 0x27a6, GenericPCI{Comment:"display controller"})
+}
diff --git a/util/autoport/log_maker.go b/util/autoport/log_maker.go
new file mode 100644
index 0000000..f172520
--- /dev/null
+++ b/util/autoport/log_maker.go
@@ -0,0 +1,77 @@
+package main
+
+import (
+	"io"
+	"io/ioutil"
+	"log"
+	"os"
+	"os/exec"
+	"strings"
+)
+
+func RunAndSave(output string, name string, arg ...string) {
+	cmd := exec.Command(name, arg...)
+
+	f, err := os.Create(output)
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	cmd.Stdout = f
+	cmd.Stderr = f
+
+	err = cmd.Start()
+	if err != nil {
+		log.Fatal(err)
+	}
+	cmd.Wait()
+}
+
+func MakeLogs(outDir string) {
+	os.MkdirAll(outDir, 0700)
+	RunAndSave(outDir+"/lspci.log", "lspci", "-nnvvvxxxx")
+	RunAndSave(outDir+"/dmidecode.log", "dmidecode")
+	RunAndSave(outDir+"/acpidump.log", "acpidump")
+	/* FIXME */
+	RunAndSave(outDir+"/inteltool.log", "../inteltool/inteltool", "-a")
+
+	SysDir := "/sys/class/sound/card0/"
+	files, _ := ioutil.ReadDir(SysDir)
+	for _, f := range files {
+		if (strings.HasPrefix(f.Name(), "hw") || strings.HasPrefix(f.Name(), "hdaudio")) && f.IsDir() {
+			in, err := os.Open(SysDir + f.Name() + "/init_pin_configs")
+			defer in.Close()
+			if err != nil {
+				log.Fatal(err)
+			}
+			out, err := os.Create(outDir + "/pin_" + strings.Replace(f.Name(), "hdaudio", "hw", -1))
+			if err != nil {
+				log.Fatal(err)
+			}
+			defer out.Close()
+			io.Copy(out, in)
+		}
+	}
+
+	ProcDir := "/proc/asound/card0/"
+	files, _ = ioutil.ReadDir(ProcDir)
+	for _, f := range files {
+		if strings.HasPrefix(f.Name(), "codec#") && !f.IsDir() {
+			in, err := os.Open(ProcDir + f.Name())
+			defer in.Close()
+			if err != nil {
+				log.Fatal(err)
+			}
+			out, err := os.Create(outDir + "/" + f.Name())
+			if err != nil {
+				log.Fatal(err)
+			}
+			defer out.Close()
+			io.Copy(out, in)
+		}
+	}
+
+	/*
+		l.InputDirectory + "/inteltool.log"
+	*/
+}
diff --git a/util/autoport/log_reader.go b/util/autoport/log_reader.go
new file mode 100644
index 0000000..4e89cf2
--- /dev/null
+++ b/util/autoport/log_reader.go
@@ -0,0 +1,264 @@
+package main
+
+import (
+	"bufio"
+	"flag"
+	"fmt"
+	"log"
+	"os"
+	"strconv"
+	"strings"
+)
+
+type LogDevReader struct {
+	InputDirectory string
+	ACPITables     map[string][]byte
+}
+
+func isXDigit(x uint8) bool {
+	if x >= '0' && x <= '9' {
+		return true
+	}
+	if x >= 'a' && x <= 'f' {
+		return true
+	}
+	if x >= 'A' && x <= 'F' {
+		return true
+	}
+	return false
+}
+
+type HexLine struct {
+	length uint
+	values [16]byte
+	start  uint
+}
+
+func (l *LogDevReader) ReadHexLine(line string) (hex HexLine) {
+	hex.start = 0
+	line = strings.Trim(line, " ")
+	fmt.Sscanf(line, "%x:", &hex.start)
+	ll, _ := fmt.Sscanf(line, "%x: %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x", &hex.start,
+		&hex.values[0], &hex.values[1], &hex.values[2],
+		&hex.values[3], &hex.values[4], &hex.values[5],
+		&hex.values[6], &hex.values[7], &hex.values[8],
+		&hex.values[9], &hex.values[10], &hex.values[11],
+		&hex.values[12], &hex.values[13], &hex.values[14],
+		&hex.values[15])
+	hex.length = uint(ll - 1)
+	return
+}
+
+func (l *LogDevReader) AssignHexLine(inp string, target []byte) []byte {
+	hex := l.ReadHexLine(inp)
+	if hex.start+hex.length > uint(len(target)) {
+		target = target[0 : hex.start+hex.length]
+	}
+	copy(target[hex.start:hex.start+hex.length], hex.values[0:hex.length])
+	return target
+}
+
+func (l *LogDevReader) GetACPI() (Tables map[string][]byte) {
+	if l.ACPITables != nil {
+		return l.ACPITables
+	}
+	l.ACPITables = Tables
+
+	file, err := os.Open(l.InputDirectory + "/acpidump.log")
+	if err != nil {
+		log.Fatal(err)
+	}
+	defer file.Close()
+
+	scanner := bufio.NewScanner(file)
+
+	Tables = map[string][]byte{}
+
+	curTable := ""
+	for scanner.Scan() {
+		line := scanner.Text()
+		switch {
+		case len(line) >= 6 && line[5] == '@':
+			curTable = line[0:4]
+			Tables[curTable] = make([]byte, 0, 100000)
+		case len(line) > 7 && line[0:2] == "  " && isXDigit(line[2]) && isXDigit(line[3]) && isXDigit(line[4]) && isXDigit(line[5]) && line[6] == ':':
+			Tables[curTable] = l.AssignHexLine(line, Tables[curTable])
+		}
+	}
+
+	if err := scanner.Err(); err != nil {
+		log.Fatal(err)
+	}
+
+	return
+}
+
+func (l *LogDevReader) GetPCIList() (PCIList []PCIDevData) {
+	file, err := os.Open(l.InputDirectory + "/lspci.log")
+	if err != nil {
+		log.Fatal(err)
+	}
+	defer file.Close()
+
+	scanner := bufio.NewScanner(file)
+
+	PCIList = []PCIDevData{}
+
+	for scanner.Scan() {
+		line := scanner.Text()
+		switch {
+		case !(len(line) < 7 || !isXDigit(line[0]) || !isXDigit(line[1]) || line[2] != ':' || !isXDigit(line[3]) || !isXDigit(line[4]) || line[5] != '.' || !isXDigit(line[6])):
+			cur := PCIDevData{}
+			fmt.Sscanf(line, "%x:%x.%x", &cur.Bus, &cur.Dev, &cur.Func)
+			lc := strings.LastIndex(line, ":")
+			li := strings.LastIndex(line[0:lc], "[")
+			if li < 0 {
+				continue
+			}
+			ven := 0
+			dev := 0
+			fmt.Sscanf(line[li+1:], "%x:%x", &ven, &dev)
+			cur.PCIDevID = uint16(dev)
+			cur.PCIVenID = uint16(ven)
+			cur.ConfigDump = make([]byte, 0x100, 0x1000)
+			PCIList = append(PCIList, cur)
+		case len(line) > 7 && isXDigit(line[0]) && line[1] == '0' && line[2] == ':':
+			start := 0
+			fmt.Sscanf(line, "%x:", &start)
+			cur := &PCIList[len(PCIList)-1]
+			cur.ConfigDump = l.AssignHexLine(line, cur.ConfigDump)
+		}
+	}
+
+	if err := scanner.Err(); err != nil {
+		log.Fatal(err)
+	}
+
+	return
+}
+
+func (l *LogDevReader) GetInteltool() (ret InteltoolData) {
+	file, err := os.Open(l.InputDirectory + "/inteltool.log")
+	if err != nil {
+		log.Fatal(err)
+	}
+	defer file.Close()
+
+	scanner := bufio.NewScanner(file)
+	paragraph := ""
+	ret.GPIO = map[uint16]uint32{}
+	ret.RCBA = map[uint16]uint32{}
+	for scanner.Scan() {
+		line := scanner.Text()
+		switch {
+		case len(line) > 7 && line[0] == '0' && line[1] == 'x' && line[6] == ':' && paragraph == "RCBA":
+			addr, value := 0, 0
+			fmt.Sscanf(line, "0x%x: 0x%x", &addr, &value)
+			ret.RCBA[uint16(addr)] = uint32(value)
+		case strings.HasPrefix(line, "gpiobase"):
+			addr, value := 0, 0
+			fmt.Sscanf(line, "gpiobase+0x%x: 0x%x", &addr, &value)
+			ret.GPIO[uint16(addr)] = uint32(value)
+		case strings.HasPrefix(line, "============="):
+			paragraph = strings.Trim(line, "= ")
+		}
+	}
+
+	if err := scanner.Err(); err != nil {
+		log.Fatal(err)
+	}
+	return
+}
+
+func (l *LogDevReader) GetDMI() (ret DMIData) {
+	file, err := os.Open(l.InputDirectory + "/dmidecode.log")
+	if err != nil {
+		log.Fatal(err)
+	}
+	defer file.Close()
+
+	scanner := bufio.NewScanner(file)
+	paragraph := ""
+	for scanner.Scan() {
+		line := scanner.Text()
+		if !strings.HasPrefix(line, "\t") {
+			paragraph = strings.TrimSpace(line)
+			continue
+		}
+		idx := strings.Index(line, ":")
+		if idx < 0 {
+			continue
+		}
+		name := strings.TrimSpace(line[0:idx])
+		value := strings.TrimSpace(line[idx+1:])
+		switch paragraph + ":" + name {
+		case "System Information:Manufacturer":
+			ret.Vendor = value
+		case "System Information:Product Name":
+			ret.Model = value
+		case "System Information:Version":
+			ret.Version = value
+		case "Chassis Information:Type":
+			ret.IsLaptop = (value == "Notebook" || value == "Laptop")
+		}
+	}
+
+	if err := scanner.Err(); err != nil {
+		log.Fatal(err)
+	}
+	return
+}
+
+func (l *LogDevReader) GetAzaliaCodecs() (ret []AzaliaCodec) {
+	for codecno := 0; codecno < 10; codecno++ {
+		cur := AzaliaCodec{CodecNo: codecno, PinConfig: map[int]uint32{}}
+		codec, err := os.Open(l.InputDirectory + "/codec#" + strconv.Itoa(codecno))
+		if err != nil {
+			continue
+		}
+		defer codec.Close()
+		pin, err := os.Open(l.InputDirectory + "/pin_hwC0D" + strconv.Itoa(codecno))
+		if err != nil {
+			continue
+		}
+		defer pin.Close()
+
+		scanner := bufio.NewScanner(codec)
+		for scanner.Scan() {
+			line := scanner.Text()
+			if strings.HasPrefix(line, "Codec:") {
+				fmt.Sscanf(line, "Codec: %s", &cur.Name)
+				continue
+			}
+			if strings.HasPrefix(line, "Vendor Id:") {
+				fmt.Sscanf(line, "Vendor Id: 0x%x", &cur.VendorID)
+				continue
+			}
+			if strings.HasPrefix(line, "Subsystem Id:") {
+				fmt.Sscanf(line, "Subsystem Id: 0x%x", &cur.SubsystemID)
+				continue
+			}
+		}
+
+		scanner = bufio.NewScanner(pin)
+		for scanner.Scan() {
+			line := scanner.Text()
+			addr := 0
+			val := uint32(0)
+			fmt.Sscanf(line, "0x%x 0x%x", &addr, &val)
+			cur.PinConfig[addr] = val
+		}
+		ret = append(ret, cur)
+	}
+	return
+}
+
+var FlagLogInput = flag.String("input_log", ".", "Input log directory")
+var FlagLogMkLogs = flag.Bool("make_logs", false, "Dump logs")
+
+func MakeLogReader() *LogDevReader {
+	if *FlagLogMkLogs {
+		MakeLogs(*FlagLogInput)
+	}
+	return &LogDevReader{InputDirectory: *FlagLogInput}
+}
diff --git a/util/autoport/main.go b/util/autoport/main.go
new file mode 100644
index 0000000..d24952e
--- /dev/null
+++ b/util/autoport/main.go
@@ -0,0 +1,500 @@
+/* This is just an experiment. Full automatic porting
+   is probably not possible but a lot can be automated. */
+package main
+
+import (
+	"flag"
+	"fmt"
+	"log"
+	"os"
+	"strings"
+)
+
+type PCIAddr struct {
+	Bus  int
+	Dev  int
+	Func int
+}
+
+type PCIDevData struct {
+	PCIAddr
+	PCIVenID   uint16
+	PCIDevID   uint16
+	ConfigDump []uint8
+}
+
+type PCIDevice interface {
+	Scan(ctx Context, addr PCIDevData)
+}
+
+type InteltoolData struct {
+	GPIO map[uint16]uint32
+	RCBA map[uint16]uint32
+}
+
+type DMIData struct {
+	Vendor   string
+	Model    string
+	Version  string
+	IsLaptop bool
+}
+
+type AzaliaCodec struct {
+	Name        string
+	VendorID    uint32
+	SubsystemID uint32
+	CodecNo     int
+	PinConfig   map[int]uint32
+}
+
+type DevReader interface {
+	GetPCIList() []PCIDevData
+	GetDMI() DMIData
+	GetInteltool() InteltoolData
+	GetAzaliaCodecs() []AzaliaCodec
+	GetACPI() map[string][]byte
+}
+
+var ROMStageFiles map[string]string = map[string]string{}
+var RAMStageFiles map[string]string = map[string]string{}
+
+type Context struct {
+	MoboID        string
+	KconfigName   string
+	Vendor        string
+	Model         string
+	BaseDirectory string
+	InfoSource    DevReader
+}
+
+type IOAPICIRQ struct {
+	APICID int
+	IRQNO  [4]int
+}
+
+var IOAPICIRQs map[PCIAddr]IOAPICIRQ = map[PCIAddr]IOAPICIRQ{}
+var KconfigBool map[string]bool = map[string]bool{}
+var KconfigString map[string]string = map[string]string{}
+var KconfigStringUnquoted map[string]string = map[string]string{}
+var KconfigHex map[string]uint32 = map[string]uint32{}
+var KconfigInt map[string]int = map[string]int{}
+
+func FormatHexLE16(inp []byte) string {
+	return fmt.Sprintf ("0x%04x", uint16(inp[0]) | (uint16(inp[1]) << 8))
+}
+
+func FormatBool(inp bool) string {
+	if inp {
+		return "1"
+	} else {
+		return "0"
+	}
+}
+
+func sanitize(inp string) string {
+	result := strings.ToLower(inp)
+	result = strings.Replace(result, " ", "_", -1)
+	result = strings.Replace(result, ",", "_", -1)
+	for strings.HasSuffix(result, ".") {
+		result = result[0 : len(result)-1]
+	}
+	return result
+}
+
+func AddROMstageFile(Name string, Condition string) {
+	ROMStageFiles[Name] = Condition
+}
+
+func AddRAMstageFile(Name string, Condition string) {
+	RAMStageFiles[Name] = Condition
+}
+
+var FlagOutDir = flag.String("coreboot_dir", ".", "Resulting coreboot directory")
+
+func writeMF(mf *os.File, files map[string]string, category string) {
+	for file, condition := range files {
+		if condition == "" {
+			fmt.Fprintf(mf, "%s-y += %s\n", category, file)
+		} else {
+			fmt.Fprintf(mf, "%s-$(%s) += %s\n", category,
+				condition, file)
+		}
+	}
+}
+
+func Create(ctx Context, name string) *os.File {
+	li := strings.LastIndex(name, "/")
+	if li > 0 {
+		os.MkdirAll(ctx.BaseDirectory+"/"+name[0:li], 0700)
+	}
+	mf, err := os.Create(ctx.BaseDirectory + "/" + name)
+	if err != nil {
+		log.Fatal(err)
+	}
+	return mf
+}
+
+func RestorePCI16Simple(f *os.File, pcidev PCIDevData, addr uint16) {
+	fmt.Fprintf(f, "	pci_write_config16(PCI_DEV(%d, 0x%02x, %d), 0x%02x, 0x%02x%02x);\n",
+		pcidev.Bus, pcidev.Dev, pcidev.Func, addr,
+		pcidev.ConfigDump[addr+1],
+		pcidev.ConfigDump[addr])
+}
+
+func RestoreRCBA32(f *os.File, inteltool InteltoolData, addr uint16) {
+	fmt.Fprintf(f, "\tRCBA32(0x%04x) = 0x%08x;\n", addr, inteltool.RCBA[addr])
+}
+
+type PCISlot struct {
+	PCIAddr
+	additionalComment string
+	writeEmpty bool
+}
+
+type DevTreeNode struct {
+	Bus           int
+	Dev           int
+	Func          int
+	Disabled      bool
+	Registers     map[string]string
+	Children      []DevTreeNode
+	PCISlots      []PCISlot
+	PCIController bool
+	ChildPCIBus      int
+	MissingParent string
+	SubVendor     uint16
+	SubSystem     uint16
+	Chip          string
+	Comment       string
+}
+
+var DevTree DevTreeNode
+var MissingChildren map[string][]DevTreeNode = map[string][]DevTreeNode{}
+var unmatchedPCIDevices map[PCIAddr]DevTreeNode = map[PCIAddr]DevTreeNode{}
+
+func Offset(dt *os.File, offset int) {
+	for i := 0; i < offset; i++ {
+		fmt.Fprintf(dt, "\t")
+	}
+}
+
+func MatchDev(dev *DevTreeNode) {
+	for _, slot := range dev.PCISlots {
+		slotDev, ok := unmatchedPCIDevices[slot.PCIAddr]
+		if !ok {
+			if slot.writeEmpty {
+				dev.Children = append(dev.Children,
+					DevTreeNode{
+						Registers:     map[string]string{},
+						Chip:          "pci",
+						Bus:           slot.Bus,
+						Dev:           slot.Dev,
+						Func:          slot.Func,
+						Comment:       slot.additionalComment,
+						Disabled: true,
+					},
+				)
+			}
+			continue
+		}
+
+		if slot.additionalComment != "" && slotDev.Comment != "" {
+			slotDev.Comment = slot.additionalComment + " " + slotDev.Comment
+		} else {
+			slotDev.Comment = slot.additionalComment + slotDev.Comment
+		}
+
+		dev.Children = append(dev.Children, slotDev)
+		delete (unmatchedPCIDevices, slot.PCIAddr)
+	}
+
+	for idx := range dev.Children {
+		MatchDev(&dev.Children[idx])
+	}
+
+	if dev.MissingParent != "" {
+		for _, child := range MissingChildren[dev.MissingParent] {
+			MatchDev(&child)
+			dev.Children = append(dev.Children, child)
+		}
+		delete (MissingChildren, dev.MissingParent)
+	}
+
+	if dev.PCIController {
+		for slot, slotDev := range unmatchedPCIDevices {
+			if slot.Bus == dev.ChildPCIBus {
+				MatchDev(&slotDev)
+				dev.Children = append(dev.Children, slotDev)
+				delete (unmatchedPCIDevices, slot)
+			}
+		}
+	}
+}
+
+func writeOn(dt *os.File, dev DevTreeNode) {
+	if dev.Disabled {
+		fmt.Fprintf(dt, "off")
+	} else {
+		fmt.Fprintf(dt, "on")
+	}
+}
+
+func WriteDev(dt *os.File, offset int, dev DevTreeNode) {
+	Offset(dt, offset)
+	switch dev.Chip {
+	case "cpu_cluster", "lapic", "domain", "ioapic":
+		fmt.Fprintf(dt, "device %s 0x%x ", dev.Chip, dev.Dev)
+		writeOn(dt, dev)
+	case "pci":
+		fmt.Fprintf(dt, "device %s %02x.%x ", dev.Chip, dev.Dev, dev.Func)
+		writeOn(dt, dev)
+	default:
+		fmt.Fprintf(dt, "chip %s", dev.Chip)
+	}
+	if dev.Comment != "" {
+		fmt.Fprintf(dt, " # %s", dev.Comment)
+	}
+	fmt.Fprintf(dt, "\n")
+	if dev.Chip == "pci" && dev.SubSystem != 0 && dev.SubVendor != 0 {
+		Offset(dt, offset+1)
+		fmt.Fprintf(dt, "subsystemid 0x%04x 0x%04x\n", dev.SubVendor, dev.SubSystem)
+	}
+
+	ioapic, ok := IOAPICIRQs[PCIAddr{Bus: dev.Bus, Dev: dev.Dev, Func: dev.Func}]
+	if dev.Chip == "pci" && ok {
+		for pin, irq := range ioapic.IRQNO {
+			if irq != 0 {
+				Offset(dt, offset+1)
+				fmt.Fprintf(dt, "ioapic_irq %d INT%c 0x%x\n", ioapic.APICID, 'A'+pin, irq)
+			}
+		}
+	}
+
+	for reg, val := range dev.Registers {
+		Offset(dt, offset+1)
+		fmt.Fprintf(dt, "register \"%s\" = \"%s\"\n", reg, val)
+	}
+
+	for _, child := range dev.Children {
+		WriteDev(dt, offset+1, child)
+	}
+
+	Offset(dt, offset)
+	fmt.Fprintf(dt, "end\n")
+}
+
+func PutChip(domain string, cur DevTreeNode) {
+	MissingChildren[domain] = append(MissingChildren[domain], cur)
+}
+
+func PutPCIDevParent(addr PCIDevData, comment string, parent string) {
+	cur := DevTreeNode{
+		Registers:     map[string]string{},
+		SubVendor:     uint16(addr.ConfigDump[0x2c]) | (uint16(addr.ConfigDump[0x2d]) << 8),
+		SubSystem:     uint16(addr.ConfigDump[0x2e]) | (uint16(addr.ConfigDump[0x2f]) << 8),
+		Chip:          "pci",
+		Bus:           addr.Bus,
+		Dev:           addr.Dev,
+		Func:          addr.Func,
+		MissingParent: parent,
+		Comment:       comment,
+	}
+	unmatchedPCIDevices[addr.PCIAddr] = cur
+}
+
+func PutPCIDev(addr PCIDevData, comment string) {
+	PutPCIDevParent(addr, comment, "")
+}
+
+type GenericPCI struct {
+	Comment       string
+	Bus0Subdiv    string
+	MissingParent string
+}
+
+type GenericVGA struct {
+	GenericPCI
+}
+
+
+type DSDTInclude struct {
+	Comment string
+	File    string
+}
+
+var DSDTIncludes []DSDTInclude
+var DSDTPCI0Includes []DSDTInclude
+
+func (g GenericPCI) Scan(ctx Context, addr PCIDevData) {
+	PutPCIDevParent(addr, g.Comment, g.MissingParent)
+}
+
+func (g GenericVGA) Scan(ctx Context, addr PCIDevData) {
+	KconfigString["VGA_BIOS_ID"] = fmt.Sprintf("%04x.%04x",
+		addr.PCIVenID,
+		addr.PCIDevID)
+	KconfigString["VGA_BIOS_FILE"] = fmt.Sprintf("pci%04x,%04x.rom",
+		addr.PCIVenID,
+		addr.PCIDevID)
+	PutPCIDevParent(addr, g.Comment, g.MissingParent)
+}
+
+func main() {
+	flag.Parse()
+
+	ctx := Context{}
+
+	ctx.InfoSource = MakeLogReader()
+
+	dmi := ctx.InfoSource.GetDMI()
+
+	ctx.Vendor = dmi.Vendor
+
+	if dmi.Vendor == "LENOVO" {
+		ctx.Model = dmi.Version
+	} else {
+		ctx.Model = dmi.Model
+	}
+
+	if dmi.IsLaptop {
+		KconfigBool["SYSTEM_TYPE_LAPTOP"] = true
+	}
+	ctx.MoboID = sanitize(ctx.Vendor) + "/" + sanitize(ctx.Model)
+	ctx.KconfigName = "BOARD_" + strings.ToUpper(sanitize(ctx.Vendor)+"_"+sanitize(ctx.Model))
+	ctx.BaseDirectory = *FlagOutDir + "/src/mainboard/" + ctx.MoboID
+	KconfigStringUnquoted["MAINBOARD_DIR"] = ctx.MoboID
+	KconfigString["MAINBOARD_PART_NUMBER"] = ctx.Model
+
+	/* Only x86 currently.  */
+	KconfigBool["ARCH_X86"] = true
+
+	/* FIXME: hardcoded.  */
+	KconfigBool["BOARD_ROMSIZE_KB_2048"] = true
+
+	os.MkdirAll(ctx.BaseDirectory, 0700)
+
+	ScanRoot(ctx)
+
+	if len(ROMStageFiles) > 0 || len(RAMStageFiles) > 0 {
+		mf := Create(ctx, "Makefile.inc")
+		defer mf.Close()
+		writeMF(mf, ROMStageFiles, "romstage")
+	}
+
+	devtree := Create(ctx, "devicetree.cb")
+	defer devtree.Close()
+
+	MatchDev(&DevTree)
+	WriteDev(devtree, 0, DevTree)
+
+	bi := Create(ctx, "board_info.txt")
+	defer bi.Close()
+
+	if dmi.IsLaptop {
+		bi.WriteString("Category: laptop")
+	} else {
+		/* FIXME: other categories.  */
+		bi.WriteString("Category: desktop")
+	}
+
+	/* FIXME: flash chip.  */
+
+	kc := Create(ctx, "Kconfig")
+	defer kc.Close()
+
+	fmt.Fprintf(kc, "if %s\n\n", ctx.KconfigName)
+
+	fmt.Fprintf(kc, "config BOARD_SPECIFIC_OPTIONS # dummy\n\tdef_bool y\n")
+	for name, val := range KconfigBool {
+		if val {
+			fmt.Fprintf(kc, "\tselect %s\n", name)
+		}
+	}
+
+	for name, val := range KconfigBool {
+		if !val {
+			fmt.Fprintf(kc, `
+config %s
+	string
+	default n
+`, name)
+		}
+	}
+
+	for name, val := range KconfigStringUnquoted {
+		fmt.Fprintf(kc, `
+config %s
+	string
+	default %s
+`, name, val)
+	}
+
+	for name, val := range KconfigString {
+		fmt.Fprintf(kc, `
+config %s
+	string
+	default "%s"
+`, name, val)
+	}
+
+	for name, val := range KconfigHex {
+		fmt.Fprintf(kc, `
+config %s
+	hex
+	default 0x%x
+`, name, val)
+	}
+
+	for name, val := range KconfigInt {
+		fmt.Fprintf(kc, `
+config %s
+	int
+	default %d
+`, name, val)
+	}
+
+	fmt.Fprintf(kc, "endif\n")
+
+	dsdt := Create(ctx, "dsdt.asl")
+	defer dsdt.Close()
+
+	dsdt.WriteString(
+		`DefinitionBlock(
+	"dsdt.aml",
+	"DSDT",
+	0x03,		// DSDT revision: ACPI v3.0
+	"COREv4",	// OEM id
+	"COREBOOT",	// OEM table id
+	0x20141018	// OEM revision
+)
+{
+	// Some generic macros
+	#include "acpi/platform.asl"
+`)
+
+	for _, x := range DSDTIncludes {
+		if x.Comment != "" {
+			fmt.Fprintf(dsdt, "\t/* %s.  */\n", x.Comment)
+		}
+		fmt.Fprintf(dsdt, "\t#include <%s>\n", x.File)
+	}
+
+	dsdt.WriteString(`
+	Scope (\_SB) {
+		Device (PCI0)
+		{
+`)
+	/* FIXME: use scoping at another level.  */
+	for _, x := range DSDTPCI0Includes {
+		if x.Comment != "" {
+			fmt.Fprintf(dsdt, "\t/* %s.  */\n", x.Comment)
+		}
+		fmt.Fprintf(dsdt, "\t\t#include <%s>\n", x.File)
+	}
+	dsdt.WriteString(
+		`		}
+	}
+}
+`)
+
+}
diff --git a/util/autoport/root.go b/util/autoport/root.go
new file mode 100644
index 0000000..9a32427
--- /dev/null
+++ b/util/autoport/root.go
@@ -0,0 +1,28 @@
+package main
+
+import "fmt"
+
+var supportedPCIDevices map[uint32]PCIDevice = map[uint32]PCIDevice{}
+var PCIMap map[PCIAddr]PCIDevData = map[PCIAddr]PCIDevData{}
+
+func ScanRoot(ctx Context) {
+	for _, pciDev := range ctx.InfoSource.GetPCIList() {
+		PCIMap[pciDev.PCIAddr] = pciDev
+	}
+	for _, pciDev := range ctx.InfoSource.GetPCIList() {
+		vendevid := (uint32(pciDev.PCIDevID) << 16) | uint32(pciDev.PCIVenID)
+
+		dev, ok := supportedPCIDevices[vendevid]
+		if !ok {
+			fmt.Printf("Unsupported PCI device %04x:%04x\n",
+				pciDev.PCIVenID, pciDev.PCIDevID)
+			continue
+		}
+		dev.Scan(ctx, pciDev)
+	}
+}
+
+func RegisterPCI(VenID uint16, DevID uint16, dev PCIDevice) {
+	vendevid := (uint32(DevID) << 16) | uint32(VenID)
+	supportedPCIDevices[vendevid] = dev
+}
diff --git a/util/autoport/sandybridge.go b/util/autoport/sandybridge.go
new file mode 100644
index 0000000..ba4ec04
--- /dev/null
+++ b/util/autoport/sandybridge.go
@@ -0,0 +1,112 @@
+package main
+
+type sandybridgemc struct {
+	variant string
+}
+
+func (i sandybridgemc) Scan(ctx Context, addr PCIDevData) {
+	DevTree = DevTreeNode{
+		Chip:          "northbridge/intel/sandybridge",
+		MissingParent: "northbridge",
+		Registers: map[string]string{
+			/* FIXME: hardcoded.  */
+			"gpu_dp_d_hotplug":                    "0x06",
+			"gpu_panel_port_select":               "0",
+			"gpu_panel_power_cycle_delay":         "5",
+			"gpu_panel_power_up_delay":            "300",
+			"gpu_panel_power_down_delay":          "300",
+			"gpu_panel_power_backlight_on_delay":  "2000",
+			"gpu_panel_power_backlight_off_delay": "2000",
+			"gfx.use_spread_spectrum_clock":       "1",
+			"gfx.lvds_dual_channel":               "0",
+			"gfx.link_frequency_270_mhz":          "1",
+			"gfx.lvds_num_lanes":                  "4",
+			"gpu_cpu_backlight":                   "0x1155",
+			"gpu_pch_backlight":                   "0x06100610",
+		},
+		Children: []DevTreeNode{
+			{
+				Chip: "cpu_cluster",
+				Dev:  0,
+				Children: []DevTreeNode{
+					{
+						Chip: "cpu/intel/socket_rPGA989",
+						Children: []DevTreeNode{
+							{
+								Chip: "lapic",
+								Dev:  0,
+							},
+						},
+					},
+
+					{
+						Chip: "cpu/intel/model_206ax",
+						Registers: map[string]string{
+							/* FIXME: hardcoded.  */
+							"pstate_coord_type": "0xfe",
+							"c1_acpower":        "1",
+							"c2_acpower":        "3",
+							"c3_acpower":        "5",
+							"c1_battery":        "1",
+							"c2_battery":        "3",
+							"c3_battery":        "5",
+						},
+						Children: []DevTreeNode{
+							{
+								Chip: "lapic",
+								Dev:  0xacac,
+								Disabled: true,
+							},
+						},
+					},
+				},
+			},
+
+			{
+				Chip:          "domain",
+				Dev:           0,
+				MissingParent: "pcibus0",
+				PCIController: true,
+				ChildPCIBus: 0,
+				PCISlots: []PCISlot{
+					PCISlot{PCIAddr:PCIAddr{Dev: 0x1, Func: 0}, writeEmpty: true, additionalComment: "PCIe Bridge for discrete graphics"},
+					PCISlot{PCIAddr:PCIAddr{Dev: 0x2, Func: 0}, writeEmpty: true, additionalComment: "Internal graphics"},
+				},
+		},
+	}
+	PutPCIDev(addr, "Host bridge")
+
+	/* FIXME: Move part to northbridge?  */
+	/* FIXME: some configs are unsupported.  */
+	KconfigBool["MAINBOARD_HAS_NATIVE_VGA_INIT"] = true
+	KconfigBool["MAINBOARD_HAS_NATIVE_VGA_INIT_TEXTMODECFG"] = true
+	KconfigBool[i.variant+"BRIDGE_LVDS"] = true
+
+	KconfigBool["VGA"] = true
+	KconfigBool["EARLY_CBMEM_INIT"] = true
+	KconfigBool["INTEL_EDID"] = true
+	KconfigBool["CPU_INTEL_SOCKET_RPGA989"] = true
+	KconfigBool["NORTHBRIDGE_INTEL_"+i.variant+"BRIDGE_NATIVE"] = true
+	KconfigBool["INTEL_INT15"] = true
+	KconfigBool["HAVE_ACPI_TABLES"] = true
+	KconfigBool["HAVE_ACPI_RESUME"] = true
+
+	KconfigBool["HAVE_IFD_BIN"] = false
+	KconfigBool["HAVE_ME_BIN"] = false
+
+	KconfigHex["MMCONF_BASE_ADDRESS"] = 0xf0000000
+	KconfigInt["MAX_CPUS"] = 8
+
+	DSDTIncludes = append(DSDTIncludes, DSDTInclude{
+		File: "cpu/intel/model_206ax/acpi/cpu.asl",
+	})
+
+	DSDTPCI0Includes = append(DSDTPCI0Includes, DSDTInclude{
+		File: "northbridge/intel/sandybridge/acpi/sandybridge.asl",
+	})
+}
+
+func init() {
+	RegisterPCI(0x8086, 0x0154, sandybridgemc{variant:"IVY"})
+	RegisterPCI(0x8086, 0x0166, GenericVGA{GenericPCI{Comment:"VGA controller"}})
+}



More information about the coreboot-gerrit mailing list