[coreboot-gerrit] Patch set updated for coreboot: b2bc0ca autoport: Experimental stuff
Vladimir Serbinenko (phcoder@gmail.com)
gerrit at coreboot.org
Sun Oct 19 12:50:28 CEST 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 b2bc0ca1f16fab7f230b63e58908e1913b124ad8
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 | 52 ++++++
util/autoport/bd82x6x.go | 160 +++++++++++++++++
util/autoport/hardcoded.go | 419 +++++++++++++++++++++++++++++++++++++++++++
util/autoport/i82801gx.go | 239 ++++++++++++++++++++++++
util/autoport/i945.go | 80 +++++++++
util/autoport/log_maker.go | 76 ++++++++
util/autoport/log_reader.go | 203 +++++++++++++++++++++
util/autoport/main.go | 419 +++++++++++++++++++++++++++++++++++++++++++
util/autoport/root.go | 28 +++
util/autoport/sandybridge.go | 115 ++++++++++++
10 files changed, 1791 insertions(+)
diff --git a/util/autoport/azalia.go b/util/autoport/azalia.go
new file mode 100644
index 0000000..4ac79a6
--- /dev/null
+++ b/util/autoport/azalia.go
@@ -0,0 +1,52 @@
+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;
+`)
+}
+
+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..40b6cec
--- /dev/null
+++ b/util/autoport/bd82x6x.go
@@ -0,0 +1,160 @@
+package main
+
+import (
+ "fmt"
+ "os"
+)
+
+type bd82x6x struct {
+}
+
+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)
+
+ if dev.PCIDevID == 0x1e55 {
+ variant = "C216"
+ } else {
+ fmt.Fatal ("bug")
+ }
+
+ KconfigBool["SOUTHBRIDGE_INTEL_" + variant] = true
+ /* FIMXE: move */
+ KconfigBool["HAVE_SMI_HANDLER"] = true
+ KconfigInt["IRQ_SLOT_COUNT"] = 18
+ /* FIXME: hardcoded */
+ KconfigBool["SERIRQ_CONTINUOUS_MODE"] = true
+
+ cur := DevTreeNode{
+ Chip: "southbridge/intel/bd82x6x",
+ Comment: "Intel Series 6 Cougar Point PCH",
+ MissingParent: "southbridge",
+ Registers: map[string]string{
+ /* FIXME: hardcoded. */
+ "pirqa_routing": "0x8b",
+ "pirqb_routing": "0x8a",
+ "pirqc_routing": "0x8b",
+ "pirqd_routing": "0x8b",
+ "pirqe_routing": "0x80",
+ "pirqf_routing": "0x80",
+ "pirqg_routing": "0x80",
+ "pirqh_routing": "0x80",
+ "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",
+ },
+ }
+
+ PutChip("pcibus0", cur)
+ PutPCIDevParent("southbridge", 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{})
+ RegisterPCIGeneric(0x8086, 0x1e31, "southbridge", "USB xHCI")
+ RegisterPCIGeneric(0x8086, 0x1e26, "southbridge", "USB EHCI")
+ RegisterPCIGeneric(0x8086, 0x1e2d, "southbridge", "USB EHCI")
+ RegisterPCIGeneric(0x8086, 0x1e3a, "southbridge", "Management Engine Interface 1")
+ RegisterPCIGeneric(0x8086, 0x1502, "southbridge", "Intel Gigabit Ethernet")
+ RegisterPCIGeneric(0x8086, 0x1e10, "southbridge", "PCIe port 1")
+ RegisterPCIGeneric(0x8086, 0x1e12, "southbridge", "PCIe port 2")
+ RegisterPCIGeneric(0x8086, 0x1e14, "southbridge", "PCIe port 3")
+ RegisterPCIGeneric(0x8086, 0x1e03, "southbridge", "SATA")
+ RegisterPCIGenericParent(0x8086, 0x1e22, "southbridge", "SMBUS", "smbus")
+}
diff --git a/util/autoport/hardcoded.go b/util/autoport/hardcoded.go
new file mode 100644
index 0000000..1ed53a8
--- /dev/null
+++ b/util/autoport/hardcoded.go
@@ -0,0 +1,419 @@
+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);
+}
+`)
+
+ fa := Create(ctx, "fadt.c")
+ defer fa.Close()
+
+ /* FIXME: hardcoded. */
+ fa.WriteString(
+ `#include <arch/acpi.h>
+
+void mainboard_fill_fadt(acpi_fadt_t * fadt)
+{
+ fadt->p_lvl3_lat = 0x23;
+}`)
+
+ 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..054ee49
--- /dev/null
+++ b/util/autoport/i82801gx.go
@@ -0,0 +1,239 @@
+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]
+
+ 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)),
+ },
+ }
+
+ PutChip("pcibus0", cur)
+ PutPCIDev("southbridge", addr, "PCI-LPC bridge")
+
+ 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{})
+ RegisterPCIGeneric(0x8086, 0x27c8, "southbridge", "USB UHCI")
+ RegisterPCIGeneric(0x8086, 0x27c9, "southbridge", "USB UHCI")
+ RegisterPCIGeneric(0x8086, 0x27ca, "southbridge", "USB UHCI")
+ RegisterPCIGeneric(0x8086, 0x27cb, "southbridge", "USB UHCI")
+ RegisterPCIGeneric(0x8086, 0x27cc, "southbridge", "USB EHCI")
+
+ RegisterPCIGeneric(0x8086, 0x27d0, "southbridge", "PCIe port 1")
+ RegisterPCIGeneric(0x8086, 0x27d2, "southbridge", "PCIe port 2")
+ RegisterPCIGeneric(0x8086, 0x27d4, "southbridge", "PCIe port 3")
+ RegisterPCIGeneric(0x8086, 0x27d6, "southbridge", "PCIe port 4")
+
+ RegisterPCIGeneric(0x8086, 0x2448, "southbridge", "PCI bridge")
+
+ RegisterPCIGeneric(0x8086, 0x27c5, "southbridge", "SATA")
+ RegisterPCIGeneric(0x8086, 0x27c4, "southbridge", "IDE")
+ RegisterPCIGeneric(0x8086, 0x27df, "southbridge", "IDE")
+ RegisterPCIGenericParent(0x8086, 0x27da, "southbridge", "SMBUS", "smbus")
+}
diff --git a/util/autoport/i945.go b/util/autoport/i945.go
new file mode 100644
index 0000000..ae3cc85
--- /dev/null
+++ b/util/autoport/i945.go
@@ -0,0 +1,80 @@
+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",
+ },
+ },
+ }
+ PutPCIDev("pcibus0", 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{})
+ RegisterPCIGenericVGA(0x8086, 0x27a2, "pcibus0", "VGA controller")
+ RegisterPCIGenericVGA(0x8086, 0x27ae, "pcibus0", "VGA controller")
+ RegisterPCIGeneric(0x8086, 0x27a6, "pcibus0", "display controller")
+}
diff --git a/util/autoport/log_maker.go b/util/autoport/log_maker.go
new file mode 100644
index 0000000..2eeb2d1
--- /dev/null
+++ b/util/autoport/log_maker.go
@@ -0,0 +1,76 @@
+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")
+ /* 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..5bd4e09
--- /dev/null
+++ b/util/autoport/log_reader.go
@@ -0,0 +1,203 @@
+package main
+
+import (
+ "bufio"
+ "flag"
+ "fmt"
+ "log"
+ "os"
+ "strconv"
+ "strings"
+)
+
+type LogDevReader struct {
+ InputDirectory string
+}
+
+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
+}
+
+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)
+ 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]
+ fmt.Sscanf(line, "%x: %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x", &start,
+ &cur.ConfigDump[start], &cur.ConfigDump[start+1], &cur.ConfigDump[start+2],
+ &cur.ConfigDump[start+3], &cur.ConfigDump[start+4], &cur.ConfigDump[start+5],
+ &cur.ConfigDump[start+6], &cur.ConfigDump[start+7], &cur.ConfigDump[start+8],
+ &cur.ConfigDump[start+9], &cur.ConfigDump[start+10], &cur.ConfigDump[start+11],
+ &cur.ConfigDump[start+12], &cur.ConfigDump[start+13], &cur.ConfigDump[start+14],
+ &cur.ConfigDump[start+15])
+ }
+ }
+
+ 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..c0b8949
--- /dev/null
+++ b/util/autoport/main.go
@@ -0,0 +1,419 @@
+/* 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 [0x100]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
+}
+
+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 KconfigHex map[string]uint32 = map[string]uint32{}
+var KconfigInt map[string]int = map[string]int{}
+
+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 DevTreeNode struct {
+ Bus int
+ Dev int
+ Func int
+ Registers map[string]string
+ Children []DevTreeNode
+ MissingParent string
+ SubVendor uint16
+ SubSystem uint16
+ Chip string
+ Comment string
+}
+
+var DevTree DevTreeNode
+var MissingChildren map[string][]DevTreeNode = map[string][]DevTreeNode{}
+
+func Offset(dt *os.File, offset int) {
+ for i := 0; i < offset; i++ {
+ fmt.Fprintf(dt, "\t")
+ }
+}
+
+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 %x on", dev.Chip, dev.Dev)
+ case "pci":
+ fmt.Fprintf(dt, "device %s %02x.%x on", dev.Chip, dev.Dev, dev.Func)
+ 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)
+ }
+
+ if dev.MissingParent != "" {
+ for _, child := range MissingChildren[dev.MissingParent] {
+ 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(domain string, 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,
+ }
+ PutChip(domain, cur)
+}
+
+func PutPCIDev(domain string, addr PCIDevData, comment string) {
+ PutPCIDevParent(domain, addr, comment, "")
+}
+
+type GenericPCI struct {
+ Comment string
+ Bus0Subdiv string
+ MissingParent string
+ VGA bool
+}
+
+type DSDTInclude struct {
+ Comment string
+ File string
+}
+
+var DSDTIncludes []DSDTInclude
+var DSDTPCI0Includes []DSDTInclude
+
+func (g GenericPCI) Scan(ctx Context, addr PCIDevData) {
+ bus := ""
+ if addr.Bus == 0 && g.Bus0Subdiv != "" {
+ bus = g.Bus0Subdiv
+ } else {
+ bus = fmt.Sprintf("pcibus%x", bus)
+ }
+
+ if addr.VGA {
+ 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(bus, addr, g.Comment, g.MissingParent)
+}
+
+func RegisterPCIGeneric(Vendor uint16, Device uint16, Bus0Subdiv string, Comment string) {
+ RegisterPCI(Vendor, Device, GenericPCI{Comment: Comment, Bus0Subdiv: Bus0Subdiv})
+}
+
+func RegisterPCIGenericVGA(Vendor uint16, Device uint16, Bus0Subdiv string, Comment string) {
+ RegisterPCI(Vendor, Device, GenericPCI{Comment: Comment, Bus0Subdiv: Bus0Subdiv, VGA: true})
+}
+
+func RegisterPCIGenericParent(Vendor uint16, Device uint16, Bus0Subdiv string, Comment string, Parent string) {
+ RegisterPCI(Vendor, Device, GenericPCI{Comment: Comment, Bus0Subdiv: Bus0Subdiv, MissingParent: Parent})
+}
+
+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
+ KconfigString["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()
+ 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")
+ }
+
+ 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 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..f39733a
--- /dev/null
+++ b/util/autoport/sandybridge.go
@@ -0,0 +1,115 @@
+package main
+
+type sandybridgemc struct {
+}
+
+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: "cpu/intel/socket_rPGA989",
+ Children: []DevTreeNode{
+ {
+ Chip: "lapic",
+ Dev: 0xacac,
+ },
+ },
+ },
+ },
+ },
+ {
+ Chip: "domain",
+ Dev: 0,
+ MissingParent: "pcibus0",
+ },
+ },
+ }
+ PutPCIDev("pcibus0", addr, "Host bridge")
+
+ if dev.PCIDevID == 0x0154 {
+ variant = "IVY"
+ } else {
+ fmt.Fatal("bug")
+ }
+
+ /* 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[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_"+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{})
+ RegisterPCIGenericVGA(0x8086, 0x0166, "pcibus0", "VGA controller")
+}
More information about the coreboot-gerrit
mailing list