aboutsummaryrefslogtreecommitdiff
path: root/src/northbridge/intel/fsp_sandybridge
diff options
context:
space:
mode:
authorMartin Roth <martinroth@google.com>2015-10-11 10:37:02 +0200
committerRonald G. Minnich <rminnich@gmail.com>2015-10-22 21:51:01 +0200
commitbf6b83abe06ff53033e7cd74134972de6791cf26 (patch)
tree39d542ba472cd4398a030989e824e661a8751d49 /src/northbridge/intel/fsp_sandybridge
parenta4ffe8aa4981130b240eee5ed22c5bbfa1c7598b (diff)
Revert "Remove sandybridge and ivybridge FSP code path"
Please don't remove chipsets and mainboards without discussion and input from the owners. Someone was asking about cougar canyon 2 just a couple of weeks ago - there's obviously still interest. This reverts commit fb50124d22014742b6990a95df87a7a828e891b6. Change-Id: Icd7dcea21fa4a7808b25bb8727020701aeebffc9 Signed-off-by: Martin Roth <martinroth@google.com> Signed-off-by: Ronald G. Minnich <rminnich@gmail.com> Reviewed-on: http://review.coreboot.org/12128 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
Diffstat (limited to 'src/northbridge/intel/fsp_sandybridge')
-rw-r--r--src/northbridge/intel/fsp_sandybridge/Kconfig46
-rw-r--r--src/northbridge/intel/fsp_sandybridge/Makefile.inc41
-rw-r--r--src/northbridge/intel/fsp_sandybridge/acpi.c212
-rw-r--r--src/northbridge/intel/fsp_sandybridge/acpi/hostbridge.asl359
-rw-r--r--src/northbridge/intel/fsp_sandybridge/acpi/sandybridge.asl58
-rw-r--r--src/northbridge/intel/fsp_sandybridge/chip.h45
-rw-r--r--src/northbridge/intel/fsp_sandybridge/early_init.c88
-rw-r--r--src/northbridge/intel/fsp_sandybridge/finalize.c56
-rw-r--r--src/northbridge/intel/fsp_sandybridge/fsp/Kconfig40
-rw-r--r--src/northbridge/intel/fsp_sandybridge/fsp/Makefile.inc21
-rw-r--r--src/northbridge/intel/fsp_sandybridge/fsp/chipset_fsp_util.c113
-rw-r--r--src/northbridge/intel/fsp_sandybridge/fsp/chipset_fsp_util.h68
-rw-r--r--src/northbridge/intel/fsp_sandybridge/gma.c110
-rw-r--r--src/northbridge/intel/fsp_sandybridge/gma.h167
-rw-r--r--src/northbridge/intel/fsp_sandybridge/northbridge.c407
-rw-r--r--src/northbridge/intel/fsp_sandybridge/northbridge.h231
-rw-r--r--src/northbridge/intel/fsp_sandybridge/northbridge_pci_devs.h47
-rw-r--r--src/northbridge/intel/fsp_sandybridge/ram_calc.c38
-rw-r--r--src/northbridge/intel/fsp_sandybridge/raminit.c76
-rw-r--r--src/northbridge/intel/fsp_sandybridge/raminit.h25
-rw-r--r--src/northbridge/intel/fsp_sandybridge/report_platform.c114
-rw-r--r--src/northbridge/intel/fsp_sandybridge/udelay.c55
22 files changed, 2417 insertions, 0 deletions
diff --git a/src/northbridge/intel/fsp_sandybridge/Kconfig b/src/northbridge/intel/fsp_sandybridge/Kconfig
new file mode 100644
index 0000000000..e1f2e888fd
--- /dev/null
+++ b/src/northbridge/intel/fsp_sandybridge/Kconfig
@@ -0,0 +1,46 @@
+##
+## This file is part of the coreboot project.
+##
+## Copyright (C) 2010 Google Inc.
+## Copyright (C) 2013 Sage Electronic Engineering, LLC.
+##
+## 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.
+##
+
+config NORTHBRIDGE_INTEL_FSP_SANDYBRIDGE
+ bool
+ select CPU_INTEL_FSP_MODEL_206AX
+ select INTEL_GMA_ACPI
+
+config NORTHBRIDGE_INTEL_FSP_IVYBRIDGE
+ bool
+ select CPU_INTEL_FSP_MODEL_306AX
+ select INTEL_GMA_ACPI
+
+if NORTHBRIDGE_INTEL_FSP_IVYBRIDGE || NORTHBRIDGE_INTEL_FSP_SANDYBRIDGE
+
+config VGA_BIOS_ID
+ string
+ default "8086,0106"
+ help
+ This is the default PCI ID for the sandybridge/ivybridge graphics
+ devices. This string names the vbios ROM in cbfs. The following
+ PCI IDs will be remapped to load this ROM:
+ 0x80860102, 0x8086010a, 0x80860112, 0x80860116
+ 0x80860122, 0x80860126, 0x80860166
+
+# Ivybridge Specific FSP Kconfig
+source src/northbridge/intel/fsp_sandybridge/fsp/Kconfig
+
+endif # NORTHBRIDGE_INTEL_FSP_IVYBRIDGE || NORTHBRIDGE_INTEL_FSP_SANDYBRIDGE
diff --git a/src/northbridge/intel/fsp_sandybridge/Makefile.inc b/src/northbridge/intel/fsp_sandybridge/Makefile.inc
new file mode 100644
index 0000000000..6c5e09f9b4
--- /dev/null
+++ b/src/northbridge/intel/fsp_sandybridge/Makefile.inc
@@ -0,0 +1,41 @@
+#
+# This file is part of the coreboot project.
+#
+# Copyright (C) 2010 Google Inc.
+# Copyright (C) 2013-2014 Sage Electronic Engineering, LLC.
+#
+# 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.
+#
+
+ifeq ($(CONFIG_NORTHBRIDGE_INTEL_FSP_SANDYBRIDGE)$(CONFIG_NORTHBRIDGE_INTEL_FSP_IVYBRIDGE),y)
+
+subdirs-y += fsp
+ramstage-y += northbridge.c
+ramstage-y += ram_calc.c
+ramstage-y += gma.c
+
+ramstage-y += acpi.c
+
+romstage-y += raminit.c
+romstage-y += ram_calc.c
+romstage-y += early_init.c
+romstage-y += report_platform.c
+romstage-y += ../../../arch/x86/walkcbfs.S
+
+smm-$(CONFIG_HAVE_SMI_HANDLER) += udelay.c
+smm-$(CONFIG_HAVE_SMI_HANDLER) += finalize.c
+
+CPPFLAGS_common += -I$(src)/northbridge/intel/fsp_sandybridge/fsp
+
+endif
diff --git a/src/northbridge/intel/fsp_sandybridge/acpi.c b/src/northbridge/intel/fsp_sandybridge/acpi.c
new file mode 100644
index 0000000000..1e20945138
--- /dev/null
+++ b/src/northbridge/intel/fsp_sandybridge/acpi.c
@@ -0,0 +1,212 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ * Copyright (C) 2012 The Chromium OS Authors
+ *
+ * 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.
+ */
+
+#include <types.h>
+#include <string.h>
+#include <console/console.h>
+#include <arch/io.h>
+#include <arch/acpi.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <drivers/intel/gma/i915.h>
+#include <arch/acpigen.h>
+#include "northbridge.h"
+#include <cbmem.h>
+
+unsigned long acpi_fill_mcfg(unsigned long current)
+{
+ device_t dev;
+ u32 pciexbar = 0;
+ u32 pciexbar_reg;
+ int max_buses;
+
+ dev = dev_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_SB, 0);
+ if (!dev)
+ dev = dev_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_IB, 0);
+ if (!dev)
+ return current;
+
+ pciexbar_reg=pci_read_config32(dev, PCIEXBAR);
+
+ // MMCFG not supported or not enabled.
+ if (!(pciexbar_reg & (1 << 0)))
+ return current;
+
+ switch ((pciexbar_reg >> 1) & 3) {
+ case 0: // 256MB
+ pciexbar = pciexbar_reg & ((1 << 31)|(1 << 30)|(1 << 29)|(1 << 28));
+ max_buses = 256;
+ break;
+ case 1: // 128M
+ pciexbar = pciexbar_reg & ((1 << 31)|(1 << 30)|(1 << 29)|(1 << 28)|(1 << 27));
+ max_buses = 128;
+ break;
+ case 2: // 64M
+ pciexbar = pciexbar_reg & ((1 << 31)|(1 << 30)|(1 << 29)|(1 << 28)|(1 << 27)|(1 << 26));
+ max_buses = 64;
+ break;
+ default: // RSVD
+ return current;
+ }
+
+ if (!pciexbar)
+ return current;
+
+ current += acpi_create_mcfg_mmconfig((acpi_mcfg_mmconfig_t *) current,
+ pciexbar, 0x0, 0x0, max_buses - 1);
+
+ return current;
+}
+
+static void *get_intel_vbios(void)
+{
+ /* This should probably be looking at CBFS or we should always
+ * deploy the VBIOS on Intel systems, even if we don't run it
+ * in coreboot (e.g. SeaBIOS only scenarios).
+ */
+ u8 *vbios = (u8 *)0xc0000;
+
+ optionrom_header_t *oprom = (optionrom_header_t *)vbios;
+ optionrom_pcir_t *pcir = (optionrom_pcir_t *)(vbios +
+ oprom->pcir_offset);
+
+
+ printk(BIOS_DEBUG, "GET_VBIOS: %x %x %x %x %x\n",
+ oprom->signature, pcir->vendor, pcir->classcode[0],
+ pcir->classcode[1], pcir->classcode[2]);
+
+
+ if ((oprom->signature == OPROM_SIGNATURE) &&
+ (pcir->vendor == PCI_VENDOR_ID_INTEL) &&
+ (pcir->classcode[0] == 0x00) &&
+ (pcir->classcode[1] == 0x00) &&
+ (pcir->classcode[2] == 0x03))
+ return (void *)vbios;
+
+ return NULL;
+}
+
+static int init_opregion_vbt(igd_opregion_t *opregion)
+{
+ void *vbios;
+ vbios = get_intel_vbios();
+ if (!vbios) {
+ printk(BIOS_DEBUG, "VBIOS not found.\n");
+ return 1;
+ }
+
+ printk(BIOS_DEBUG, " ... VBIOS found at %p\n", vbios);
+ optionrom_header_t *oprom = (optionrom_header_t *)vbios;
+ optionrom_vbt_t *vbt = (optionrom_vbt_t *)(vbios +
+ oprom->vbt_offset);
+
+ if (read32(vbt->hdr_signature) != VBT_SIGNATURE) {
+ printk(BIOS_DEBUG, "VBT not found!\n");
+ return 1;
+ }
+
+ memcpy(opregion->header.vbios_version, vbt->coreblock_biosbuild, 4);
+ memcpy(opregion->vbt.gvd1, vbt, vbt->hdr_vbt_size < 7168 ?
+ vbt->hdr_vbt_size : 7168);
+
+ return 0;
+}
+
+
+/* Initialize IGD OpRegion, called from ACPI code */
+int init_igd_opregion(igd_opregion_t *opregion)
+{
+ device_t igd;
+ u16 reg16;
+
+ memset((void *)opregion, 0, sizeof(igd_opregion_t));
+
+ // FIXME if IGD is disabled, we should exit here.
+
+ memcpy(&opregion->header.signature, IGD_OPREGION_SIGNATURE,
+ sizeof(opregion->header.signature));
+
+ /* 8kb */
+ opregion->header.size = sizeof(igd_opregion_t) / 1024;
+ opregion->header.version = IGD_OPREGION_VERSION;
+
+ // FIXME We just assume we're mobile for now
+ opregion->header.mailboxes = MAILBOXES_MOBILE;
+
+ // TODO Initialize Mailbox 1
+
+ // TODO Initialize Mailbox 3
+ opregion->mailbox3.bclp = IGD_BACKLIGHT_BRIGHTNESS;
+ opregion->mailbox3.pfit = IGD_FIELD_VALID | IGD_PFIT_STRETCH;
+ opregion->mailbox3.pcft = 0; // should be (IMON << 1) & 0x3e
+ opregion->mailbox3.cblv = IGD_FIELD_VALID | IGD_INITIAL_BRIGHTNESS;
+ opregion->mailbox3.bclm[0] = IGD_WORD_FIELD_VALID + 0x0000;
+ opregion->mailbox3.bclm[1] = IGD_WORD_FIELD_VALID + 0x0a19;
+ opregion->mailbox3.bclm[2] = IGD_WORD_FIELD_VALID + 0x1433;
+ opregion->mailbox3.bclm[3] = IGD_WORD_FIELD_VALID + 0x1e4c;
+ opregion->mailbox3.bclm[4] = IGD_WORD_FIELD_VALID + 0x2866;
+ opregion->mailbox3.bclm[5] = IGD_WORD_FIELD_VALID + 0x327f;
+ opregion->mailbox3.bclm[6] = IGD_WORD_FIELD_VALID + 0x3c99;
+ opregion->mailbox3.bclm[7] = IGD_WORD_FIELD_VALID + 0x46b2;
+ opregion->mailbox3.bclm[8] = IGD_WORD_FIELD_VALID + 0x50cc;
+ opregion->mailbox3.bclm[9] = IGD_WORD_FIELD_VALID + 0x5ae5;
+ opregion->mailbox3.bclm[10] = IGD_WORD_FIELD_VALID + 0x64ff;
+
+ init_opregion_vbt(opregion);
+
+ /* TODO This needs to happen in S3 resume, too.
+ * Maybe it should move to the finalize handler
+ */
+ igd = dev_find_slot(0, PCI_DEVFN(0x2, 0));
+
+ pci_write_config32(igd, ASLS, (u32)opregion);
+ reg16 = pci_read_config16(igd, SWSCI);
+ reg16 &= ~(1 << 0);
+ reg16 |= (1 << 15);
+ pci_write_config16(igd, SWSCI, reg16);
+
+ /* clear dmisci status */
+ reg16 = inw(DEFAULT_PMBASE + TCO1_STS);
+ reg16 |= DMISCI_STS; // reference code does an &=
+ outw(DEFAULT_PMBASE + TCO1_STS, reg16);
+
+ /* clear acpi tco status */
+ outl(DEFAULT_PMBASE + GPE0_STS, TCOSCI_STS);
+
+ /* enable acpi tco scis */
+ reg16 = inw(DEFAULT_PMBASE + GPE0_EN);
+ reg16 |= TCOSCI_EN;
+ outw(DEFAULT_PMBASE + GPE0_EN, reg16);
+
+ return 0;
+}
+
+void *igd_make_opregion(void)
+{
+ igd_opregion_t *opregion;
+
+ printk(BIOS_DEBUG, "ACPI: * IGD OpRegion\n");
+ opregion = cbmem_add(CBMEM_ID_IGD_OPREGION, sizeof (*opregion));
+ if (opregion)
+ init_igd_opregion(opregion);
+ return opregion;
+}
diff --git a/src/northbridge/intel/fsp_sandybridge/acpi/hostbridge.asl b/src/northbridge/intel/fsp_sandybridge/acpi/hostbridge.asl
new file mode 100644
index 0000000000..a1b99b899c
--- /dev/null
+++ b/src/northbridge/intel/fsp_sandybridge/acpi/hostbridge.asl
@@ -0,0 +1,359 @@
+/*
+ * 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.
+ */
+
+
+Name(_HID,EISAID("PNP0A08")) // PCIe
+Name(_CID,EISAID("PNP0A03")) // PCI
+
+Name(_ADR, 0)
+Name(_BBN, 0)
+
+Device (MCHC)
+{
+ Name(_ADR, 0x00000000) // 0:0.0
+
+ OperationRegion(MCHP, PCI_Config, 0x00, 0x100)
+ Field (MCHP, DWordAcc, NoLock, Preserve)
+ {
+ Offset (0x40), // EPBAR
+ EPEN, 1, // Enable
+ , 11, //
+ EPBR, 24, // EPBAR
+
+ Offset (0x48), // MCHBAR
+ MHEN, 1, // Enable
+ , 13, //
+ MHBR, 22, // MCHBAR
+
+ Offset (0x60), // PCIe BAR
+ PXEN, 1, // Enable
+ PXSZ, 2, // BAR size
+ , 23, //
+ PXBR, 10, // PCIe BAR
+
+ Offset (0x68), // DMIBAR
+ DMEN, 1, // Enable
+ , 11, //
+ DMBR, 24, // DMIBAR
+
+ Offset (0x70), // ME Base Address
+ MEBA, 64,
+
+ // ...
+
+ Offset (0x80), // PAM0
+ , 4,
+ PM0H, 2,
+ , 2,
+ Offset (0x81), // PAM1
+ PM1L, 2,
+ , 2,
+ PM1H, 2,
+ , 2,
+ Offset (0x82), // PAM2
+ PM2L, 2,
+ , 2,
+ PM2H, 2,
+ , 2,
+ Offset (0x83), // PAM3
+ PM3L, 2,
+ , 2,
+ PM3H, 2,
+ , 2,
+ Offset (0x84), // PAM4
+ PM4L, 2,
+ , 2,
+ PM4H, 2,
+ , 2,
+ Offset (0x85), // PAM5
+ PM5L, 2,
+ , 2,
+ PM5H, 2,
+ , 2,
+ Offset (0x86), // PAM6
+ PM6L, 2,
+ , 2,
+ PM6H, 2,
+ , 2,
+
+ Offset (0xa0), // Top of Used Memory
+ TOM, 64,
+
+ Offset (0xbc), // Top of Low Used Memory
+ TLUD, 32,
+ }
+
+ Mutex (CTCM, 1) /* CTDP Switch Mutex (sync level 1) */
+ Name (CTCC, 0) /* CTDP Current Selection */
+ Name (CTCN, 0) /* CTDP Nominal Select */
+ Name (CTCD, 1) /* CTDP Down Select */
+ Name (CTCU, 2) /* CTDP Up Select */
+
+ OperationRegion (MCHB, SystemMemory, DEFAULT_MCHBAR, 0x8000)
+ Field (MCHB, DWordAcc, Lock, Preserve)
+ {
+ Offset (0x5930),
+ CTDN, 15, /* CTDP Nominal PL1 */
+ Offset (0x59a0),
+ PL1V, 15, /* Power Limit 1 Value */
+ PL1E, 1, /* Power Limit 1 Enable */
+ PL1C, 1, /* Power Limit 1 Clamp */
+ PL1T, 7, /* Power Limit 1 Time */
+ Offset (0x59a4),
+ PL2V, 15, /* Power Limit 2 Value */
+ PL2E, 1, /* Power Limit 2 Enable */
+ PL2C, 1, /* Power Limit 2 Clamp */
+ PL2T, 7, /* Power Limit 2 Time */
+ Offset (0x5f3c),
+ TARN, 8, /* CTDP Nominal Turbo Activation Ratio */
+ Offset (0x5f40),
+ CTDD, 15, /* CTDP Down PL1 */
+ , 1,
+ TARD, 8, /* CTDP Down Turbo Activation Ratio */
+ Offset (0x5f48),
+ CTDU, 15, /* CTDP Up PL1 */
+ , 1,
+ TARU, 8, /* CTDP Up Turbo Activation Ratio */
+ Offset (0x5f50),
+ CTCS, 2, /* CTDP Select */
+ Offset (0x5f54),
+ TARS, 8, /* Turbo Activation Ratio Select */
+ }
+
+ /*
+ * Search CPU0 _PSS looking for control=arg0 and then
+ * return previous P-state entry number for new _PPC
+ *
+ * Format of _PSS:
+ * Name (_PSS, Package () {
+ * Package (6) { freq, power, tlat, blat, control, status }
+ * }
+ */
+ External (\_PR.CP00._PSS)
+ Method (PSSS, 1, NotSerialized)
+ {
+ Store (One, Local0) /* Start at P1 */
+ Store (SizeOf (\_PR.CP00._PSS), Local1)
+
+ While (LLess (Local0, Local1)) {
+ /* Store _PSS entry Control value to Local2 */
+ ShiftRight (DeRefOf (Index (DeRefOf (Index
+ (\_PR.CP00._PSS, Local0)), 4)), 8, Local2)
+ If (LEqual (Local2, Arg0)) {
+ Return (Subtract (Local0, 1))
+ }
+ Increment (Local0)
+ }
+
+ Return (0)
+ }
+
+ /* Set TDP Down */
+ Method (STND, 0, Serialized)
+ {
+ If (Acquire (CTCM, 100)) {
+ Return (0)
+ }
+ If (LEqual (CTCD, CTCC)) {
+ Release (CTCM)
+ Return (0)
+ }
+
+ Store ("Set TDP Down", Debug)
+
+ /* Set CTC */
+ Store (CTCD, CTCS)
+
+ /* Set TAR */
+ Store (TARD, TARS)
+
+ /* Set PPC limit and notify OS */
+ Store (PSSS (TARD), PPCM)
+ PPCN ()
+
+ /* Set PL2 to 1.25 * PL1 */
+ Divide (Multiply (CTDD, 125), 100, Local0, PL2V)
+
+ /* Set PL1 */
+ Store (CTDD, PL1V)
+
+ /* Store the new TDP Down setting */
+ Store (CTCD, CTCC)
+
+ Release (CTCM)
+ Return (1)
+ }
+
+ /* Set TDP Nominal from Down */
+ Method (STDN, 0, Serialized)
+ {
+ If (Acquire (CTCM, 100)) {
+ Return (0)
+ }
+ If (LEqual (CTCN, CTCC)) {
+ Release (CTCM)
+ Return (0)
+ }
+
+ Store ("Set TDP Nominal", Debug)
+
+ /* Set PL1 */
+ Store (CTDN, PL1V)
+
+ /* Set PL2 to 1.25 * PL1 */
+ Divide (Multiply (CTDN, 125), 100, Local0, PL2V)
+
+ /* Set PPC limit and notify OS */
+ Store (PSSS (TARN), PPCM)
+ PPCN ()
+
+ /* Set TAR */
+ Store (TARN, TARS)
+
+ /* Set CTC */
+ Store (CTCN, CTCS)
+
+ /* Store the new TDP Nominal setting */
+ Store (CTCN, CTCC)
+
+ Release (CTCM)
+ Return (1)
+ }
+}
+
+// Current Resource Settings
+
+Method (_CRS, 0, Serialized)
+{
+ Name (MCRS, ResourceTemplate()
+ {
+ // Bus Numbers
+ WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode,
+ 0x0000, 0x0000, 0x00ff, 0x0000, 0x0100,,, PB00)
+
+ // IO Region 0
+ DWordIO (ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
+ 0x0000, 0x0000, 0x0cf7, 0x0000, 0x0cf8,,, PI00)
+
+ // PCI Config Space
+ Io (Decode16, 0x0cf8, 0x0cf8, 0x0001, 0x0008)
+
+ // IO Region 1
+ DWordIO (ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
+ 0x0000, 0x0d00, 0xffff, 0x0000, 0xf300,,, PI01)
+
+ // VGA memory (0xa0000-0xbffff)
+ DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
+ Cacheable, ReadWrite,
+ 0x00000000, 0x000a0000, 0x000bffff, 0x00000000,
+ 0x00020000,,, ASEG)
+
+ // OPROM reserved (0xd0000-0xd3fff)
+ DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
+ Cacheable, ReadWrite,
+ 0x00000000, 0x000d0000, 0x000d3fff, 0x00000000,
+ 0x00004000,,, OPR0)
+
+ // OPROM reserved (0xd4000-0xd7fff)
+ DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
+ Cacheable, ReadWrite,
+ 0x00000000, 0x000d4000, 0x000d7fff, 0x00000000,
+ 0x00004000,,, OPR1)
+
+ // OPROM reserved (0xd8000-0xdbfff)
+ DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
+ Cacheable, ReadWrite,
+ 0x00000000, 0x000d8000, 0x000dbfff, 0x00000000,
+ 0x00004000,,, OPR2)
+
+ // OPROM reserved (0xdc000-0xdffff)
+ DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
+ Cacheable, ReadWrite,
+ 0x00000000, 0x000dc000, 0x000dffff, 0x00000000,
+ 0x00004000,,, OPR3)
+
+ // BIOS Extension (0xe0000-0xe3fff)
+ DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
+ Cacheable, ReadWrite,
+ 0x00000000, 0x000e0000, 0x000e3fff, 0x00000000,
+ 0x00004000,,, ESG0)
+
+ // BIOS Extension (0xe4000-0xe7fff)
+ DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
+ Cacheable, ReadWrite,
+ 0x00000000, 0x000e4000, 0x000e7fff, 0x00000000,
+ 0x00004000,,, ESG1)
+
+ // BIOS Extension (0xe8000-0xebfff)
+ DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
+ Cacheable, ReadWrite,
+ 0x00000000, 0x000e8000, 0x000ebfff, 0x00000000,
+ 0x00004000,,, ESG2)
+
+ // BIOS Extension (0xec000-0xeffff)
+ DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
+ Cacheable, ReadWrite,
+ 0x00000000, 0x000ec000, 0x000effff, 0x00000000,
+ 0x00004000,,, ESG3)
+
+ // System BIOS (0xf0000-0xfffff)
+ DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
+ Cacheable, ReadWrite,
+ 0x00000000, 0x000f0000, 0x000fffff, 0x00000000,
+ 0x00010000,,, FSEG)
+
+ // PCI Memory Region (Top of memory-CONFIG_MMCONF_BASE_ADDRESS)
+ DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
+ Cacheable, ReadWrite,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000,,, PM01)
+
+ // TPM Area (0xfed40000-0xfed44fff)
+ DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
+ Cacheable, ReadWrite,
+ 0x00000000, 0xfed40000, 0xfed44fff, 0x00000000,
+ 0x00005000,,, TPMR)
+ })
+
+ // Find PCI resource area in MCRS
+ CreateDwordField(MCRS, PM01._MIN, PMIN)
+ CreateDwordField(MCRS, PM01._MAX, PMAX)
+ CreateDwordField(MCRS, PM01._LEN, PLEN)
+
+ // Fix up PCI memory region
+ // Start with Top of Lower Usable DRAM
+ Store (^MCHC.TLUD, Local0)
+ Store (^MCHC.MEBA, Local1)
+
+ // Check if ME base is equal
+ If (LEqual (Local0, Local1)) {
+ // Use Top Of Memory instead
+ Store (^MCHC.TOM, Local0)
+ }
+
+ Store (Local0, PMIN)
+ Store (Subtract(CONFIG_MMCONF_BASE_ADDRESS, 1), PMAX)
+ Add(Subtract(PMAX, PMIN), 1, PLEN)
+
+ Return (MCRS)
+}
+
+/* IRQ assignment is mainboard specific. Get it from mainboard ACPI code */
+#include "acpi/hostbridge_pci_irqs.asl"
diff --git a/src/northbridge/intel/fsp_sandybridge/acpi/sandybridge.asl b/src/northbridge/intel/fsp_sandybridge/acpi/sandybridge.asl
new file mode 100644
index 0000000000..b7595f2dd1
--- /dev/null
+++ b/src/northbridge/intel/fsp_sandybridge/acpi/sandybridge.asl
@@ -0,0 +1,58 @@
+/*
+ * 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.
+ */
+
+#include "../northbridge.h"
+#include "hostbridge.asl"
+
+/* PCI Device Resource Consumption */
+Device (PDRC)
+{
+ Name (_HID, EISAID("PNP0C02"))
+ Name (_UID, 1)
+
+ Name (PDRS, ResourceTemplate() {
+ Memory32Fixed(ReadWrite, 0xfed1c000, 0x00004000) // RCBA
+ Memory32Fixed(ReadWrite, DEFAULT_MCHBAR, 0x00008000)
+ Memory32Fixed(ReadWrite, DEFAULT_DMIBAR, 0x00001000)
+ Memory32Fixed(ReadWrite, DEFAULT_EPBAR, 0x00001000)
+ Memory32Fixed(ReadWrite, DEFAULT_PCIEXBAR, 0x04000000)
+ Memory32Fixed(ReadWrite, 0xfed20000, 0x00020000) // Misc ICH
+ Memory32Fixed(ReadWrite, 0xfed40000, 0x00005000) // Misc ICH
+ Memory32Fixed(ReadWrite, 0xfed45000, 0x0004b000) // Misc ICH
+
+#if CONFIG_CHROMEOS_RAMOOPS
+ Memory32Fixed(ReadWrite, CONFIG_CHROMEOS_RAMOOPS_RAM_START,
+ CONFIG_CHROMEOS_RAMOOPS_RAM_SIZE)
+#endif
+
+ /* Required for SandyBridge sighting 3715511 */
+ Memory32Fixed(ReadWrite, 0x20000000, 0x00200000)
+ Memory32Fixed(ReadWrite, 0x40000000, 0x00200000)
+ })
+
+ // Current Resource Settings
+ Method (_CRS, 0, Serialized)
+ {
+ Return(PDRS)
+ }
+}
+
+// Integrated graphics 0:2.0
+#include <drivers/intel/gma/acpi/pch.asl>
diff --git a/src/northbridge/intel/fsp_sandybridge/chip.h b/src/northbridge/intel/fsp_sandybridge/chip.h
new file mode 100644
index 0000000000..6e823dc986
--- /dev/null
+++ b/src/northbridge/intel/fsp_sandybridge/chip.h
@@ -0,0 +1,45 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2008 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.
+ */
+
+#include <drivers/intel/gma/i915.h>
+
+/*
+ * Digital Port Hotplug Enable:
+ * 0x04 = Enabled, 2ms short pulse
+ * 0x05 = Enabled, 4.5ms short pulse
+ * 0x06 = Enabled, 6ms short pulse
+ * 0x07 = Enabled, 100ms short pulse
+ */
+struct northbridge_intel_fsp_sandybridge_config {
+ u8 gpu_dp_b_hotplug; /* Digital Port B Hotplug Config */
+ u8 gpu_dp_c_hotplug; /* Digital Port C Hotplug Config */
+ u8 gpu_dp_d_hotplug; /* Digital Port D Hotplug Config */
+
+ u8 gpu_panel_port_select; /* 0=LVDS 1=DP_B 2=DP_C 3=DP_D */
+ u8 gpu_panel_power_cycle_delay; /* T4 time sequence */
+ u16 gpu_panel_power_up_delay; /* T1+T2 time sequence */
+ u16 gpu_panel_power_down_delay; /* T3 time sequence */
+ u16 gpu_panel_power_backlight_on_delay; /* T5 time sequence */
+ u16 gpu_panel_power_backlight_off_delay; /* Tx time sequence */
+
+ u32 gpu_cpu_backlight; /* CPU Backlight PWM value */
+ u32 gpu_pch_backlight; /* PCH Backlight PWM value */
+
+ struct i915_gpu_controller_info gfx;
+};
diff --git a/src/northbridge/intel/fsp_sandybridge/early_init.c b/src/northbridge/intel/fsp_sandybridge/early_init.c
new file mode 100644
index 0000000000..6ba1ab6828
--- /dev/null
+++ b/src/northbridge/intel/fsp_sandybridge/early_init.c
@@ -0,0 +1,88 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2010 coresystems GmbH
+ * Copyright (C) 2011 Google Inc
+ *
+ * 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.
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <console/console.h>
+#include <arch/io.h>
+#include <device/pci_def.h>
+#include <elog.h>
+#include "northbridge.h"
+
+static void sandybridge_setup_bars(void)
+{
+ printk(BIOS_DEBUG, "Setting up static northbridge registers...");
+ /* Set up all hardcoded northbridge BARs */
+ pci_write_config32(PCI_DEV(0, 0x00, 0), EPBAR, DEFAULT_EPBAR | 1);
+ pci_write_config32(PCI_DEV(0, 0x00, 0), EPBAR + 4, (0LL+DEFAULT_EPBAR) >> 32);
+ pci_write_config32(PCI_DEV(0, 0x00, 0), MCHBAR, (uintptr_t)DEFAULT_MCHBAR | 1);
+ pci_write_config32(PCI_DEV(0, 0x00, 0), MCHBAR + 4, (0LL+(uintptr_t)DEFAULT_MCHBAR) >> 32);
+ pci_write_config32(PCI_DEV(0, 0x00, 0), PCIEXBAR, DEFAULT_PCIEXBAR | 5); /* 64MB - busses 0-63 */
+ pci_write_config32(PCI_DEV(0, 0x00, 0), PCIEXBAR + 4, (0LL+DEFAULT_PCIEXBAR) >> 32);
+ pci_write_config32(PCI_DEV(0, 0x00, 0), DMIBAR, (uintptr_t)DEFAULT_DMIBAR | 1);
+ pci_write_config32(PCI_DEV(0, 0x00, 0), DMIBAR + 4, (0LL+(uintptr_t)DEFAULT_DMIBAR) >> 32);
+
+ /* Set C0000-FFFFF to access RAM on both reads and writes */
+ pci_write_config8(PCI_DEV(0, 0x00, 0), PAM0, 0x30);
+ pci_write_config8(PCI_DEV(0, 0x00, 0), PAM1, 0x33);
+ pci_write_config8(PCI_DEV(0, 0x00, 0), PAM2, 0x33);
+ pci_write_config8(PCI_DEV(0, 0x00, 0), PAM3, 0x33);
+ pci_write_config8(PCI_DEV(0, 0x00, 0), PAM4, 0x33);
+ pci_write_config8(PCI_DEV(0, 0x00, 0), PAM5, 0x33);
+ pci_write_config8(PCI_DEV(0, 0x00, 0), PAM6, 0x33);
+
+#if CONFIG_ELOG_BOOT_COUNT
+ /* Increment Boot Counter for non-S3 resume */
+ if ((inw(DEFAULT_PMBASE + PM1_STS) & WAK_STS) &&
+ ((inl(DEFAULT_PMBASE + PM1_CNT) >> 10) & 7) != SLP_TYP_S3)
+ boot_count_increment();
+#endif
+
+ printk(BIOS_DEBUG, " done.\n");
+
+#if CONFIG_ELOG_BOOT_COUNT
+ /* Increment Boot Counter except when resuming from S3 */
+ if ((inw(DEFAULT_PMBASE + PM1_STS) & WAK_STS) &&
+ ((inl(DEFAULT_PMBASE + PM1_CNT) >> 10) & 7) == SLP_TYP_S3)
+ return;
+ boot_count_increment();
+#endif
+}
+
+void sandybridge_early_initialization(int chipset_type)
+{
+ u32 capid0_a;
+ u8 reg8;
+
+ /* Device ID Override Enable should be done very early */
+ capid0_a = pci_read_config32(PCI_DEV(0, 0, 0), 0xe4);
+ if (capid0_a & (1 << 10)) {
+ reg8 = pci_read_config8(PCI_DEV(0, 0, 0), 0xf3);
+ reg8 &= ~7; /* Clear 2:0 */
+
+ if (chipset_type == SANDYBRIDGE_MOBILE)
+ reg8 |= 1; /* Set bit 0 */
+
+ pci_write_config8(PCI_DEV(0, 0, 0), 0xf3, reg8);
+ }
+
+ /* Setup all BARs required for early PCIe and raminit */
+ sandybridge_setup_bars();
+}
diff --git a/src/northbridge/intel/fsp_sandybridge/finalize.c b/src/northbridge/intel/fsp_sandybridge/finalize.c
new file mode 100644
index 0000000000..90c3635a7c
--- /dev/null
+++ b/src/northbridge/intel/fsp_sandybridge/finalize.c
@@ -0,0 +1,56 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2012 The Chromium OS Authors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include <arch/io.h>
+#include <stdlib.h>
+#include "northbridge.h"
+
+#define PCI_DEV_SNB PCI_DEV(0, 0, 0)
+
+void intel_sandybridge_finalize_smm(void)
+{
+ pcie_or_config16(PCI_DEV_SNB, 0x50, 1 << 0); /* GGC */
+ pcie_or_config32(PCI_DEV_SNB, 0x5c, 1 << 0); /* DPR */
+ pcie_or_config32(PCI_DEV_SNB, 0x78, 1 << 10); /* ME */
+ pcie_or_config32(PCI_DEV_SNB, 0x90, 1 << 0); /* REMAPBASE */
+ pcie_or_config32(PCI_DEV_SNB, 0x98, 1 << 0); /* REMAPLIMIT */
+ pcie_or_config32(PCI_DEV_SNB, 0xa0, 1 << 0); /* TOM */
+ pcie_or_config32(PCI_DEV_SNB, 0xa8, 1 << 0); /* TOUUD */
+ pcie_or_config32(PCI_DEV_SNB, 0xb0, 1 << 0); /* BDSM */
+ pcie_or_config32(PCI_DEV_SNB, 0xb4, 1 << 0); /* BGSM */
+ pcie_or_config32(PCI_DEV_SNB, 0xb8, 1 << 0); /* TSEGMB */
+ pcie_or_config32(PCI_DEV_SNB, 0xbc, 1 << 0); /* TOLUD */
+
+ MCHBAR32_OR(0x5500, 1 << 0); /* PAVP */
+ MCHBAR32_OR(0x5f00, 1 << 31); /* SA PM */
+ MCHBAR32_OR(0x6020, 1 << 0); /* UMA GFX */
+ MCHBAR32_OR(0x63fc, 1 << 0); /* VTDTRK */
+ MCHBAR32_OR(0x6800, 1 << 31);
+ MCHBAR32_OR(0x7000, 1 << 31);
+ MCHBAR32_OR(0x77fc, 1 << 0);
+
+ /* Memory Controller Lockdown */
+ MCHBAR8(0x50fc) = 0x8f;
+
+ /* Read+write the following */
+ MCHBAR32(0x6030) = MCHBAR32(0x6030);
+ MCHBAR32(0x6034) = MCHBAR32(0x6034);
+ MCHBAR32(0x6008) = MCHBAR32(0x6008);
+}
diff --git a/src/northbridge/intel/fsp_sandybridge/fsp/Kconfig b/src/northbridge/intel/fsp_sandybridge/fsp/Kconfig
new file mode 100644
index 0000000000..82e5361505
--- /dev/null
+++ b/src/northbridge/intel/fsp_sandybridge/fsp/Kconfig
@@ -0,0 +1,40 @@
+##
+## This file is part of the coreboot project.
+##
+## Copyright (C) 2014 Sage Electronic Engineering, LLC.
+##
+## 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.
+##
+
+config SANDYBRIDGE_FSP_SPECIFIC_OPTIONS
+ def_bool y
+ select PLATFORM_USES_FSP1_0
+ select USE_GENERIC_FSP_CAR_INC
+
+config FSP_FILE
+ string
+ default "../intel/fsp/ivybridge_bd82x6x/FvFsp.bin" if SOUTHBRIDGE_INTEL_FSP_BD82X6X
+ help
+ The path and filename of the Intel FSP binary for this platform.
+
+config FSP_LOC
+ hex "Intel FSP Binary location in CBFS"
+ default 0xfff80000
+ help
+ The location in CBFS that the FSP is located. This must match the
+ value that is set in the FSP binary. If the FSP needs to be moved,
+ rebase the FSP with the Intel's BCT (tool).
+
+ The Ivy Bridge Processor/Panther Point FSP is built with a preferred
+ base address of 0xFFF80000
diff --git a/src/northbridge/intel/fsp_sandybridge/fsp/Makefile.inc b/src/northbridge/intel/fsp_sandybridge/fsp/Makefile.inc
new file mode 100644
index 0000000000..282570351b
--- /dev/null
+++ b/src/northbridge/intel/fsp_sandybridge/fsp/Makefile.inc
@@ -0,0 +1,21 @@
+#
+# This file is part of the coreboot project.
+#
+# Copyright (C) 2014 Sage Electronic Engineering, LLC.
+#
+# 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.
+#
+
+ramstage-y += chipset_fsp_util.c
+romstage-y += chipset_fsp_util.c
diff --git a/src/northbridge/intel/fsp_sandybridge/fsp/chipset_fsp_util.c b/src/northbridge/intel/fsp_sandybridge/fsp/chipset_fsp_util.c
new file mode 100644
index 0000000000..e9dad29f4c
--- /dev/null
+++ b/src/northbridge/intel/fsp_sandybridge/fsp/chipset_fsp_util.c
@@ -0,0 +1,113 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013-2014 Sage Electronic Engineering, LLC.
+ *
+ * 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.
+ */
+
+#include <types.h>
+#include <string.h>
+#include <console/console.h>
+#include <bootstate.h>
+#include <cbmem.h>
+#include <device/device.h>
+#include <southbridge_pci_devs.h>
+#include <fsp_util.h>
+#include "../chip.h"
+#include <reset.h>
+
+#ifndef CONFIG_ENABLE_FSP_FAST_BOOT
+# error "CONFIG_ENABLE_FSP_FAST_BOOT must be set."
+#endif
+
+#ifdef __PRE_RAM__
+
+#if IS_ENABLED(CONFIG_SOUTHBRIDGE_INTEL_FSP_I89XX)
+static void GetUpdDefaultFromFsp (FSP_INFO_HEADER *FspInfo, UPD_DATA_REGION *UpdData)
+{
+ VPD_DATA_REGION *VpdDataRgnPtr;
+ UPD_DATA_REGION *UpdDataRgnPtr;
+ VpdDataRgnPtr = (VPD_DATA_REGION *)(UINT32)(FspInfo->CfgRegionOffset + FspInfo->ImageBase);
+ UpdDataRgnPtr = (UPD_DATA_REGION *)(UINT32)(VpdDataRgnPtr->PcdUpdRegionOffset + FspInfo->ImageBase);
+ memcpy((void*)UpdData, (void*)UpdDataRgnPtr, sizeof(UPD_DATA_REGION));
+}
+
+static void ConfigureDefaultUpdData(UPD_DATA_REGION *UpdData)
+{
+ UpdData->HTEnable = TRUE;
+ UpdData->TurboEnable = FALSE;
+ UpdData->MemoryDownEnable = FALSE;
+ UpdData->FastBootEnable = CONFIG_ENABLE_FSP_FAST_BOOT;
+}
+#else /* IS_ENABLED(CONFIG_SOUTHBRIDGE_INTEL_FSP_I89XX) */
+const PLATFORM_CONFIG DefaultPlatformConfig = {
+ TRUE, /* Hyperthreading */
+ FALSE, /* Turbo Mode */
+ FALSE, /* Memory Down */
+#if IS_ENABLED(CONFIG_ENABLE_FSP_FAST_BOOT)
+ TRUE, /* Fast Boot */
+#else
+ FALSE, /* Fast Boot */
+#endif /* CONFIG_ENABLE_FSP_FAST_BOOT */
+};
+#endif /* IS_ENABLED(CONFIG_SOUTHBRIDGE_INTEL_FSP_I89XX) */
+
+/*
+ *
+ * Call the FSP to do memory init. The FSP doesn't return to this function.
+ * The FSP returns to the romstage_main_continue().
+ *
+ */
+void chipset_fsp_early_init(FSP_INIT_PARAMS *FspInitParams,
+ FSP_INFO_HEADER *fsp_ptr)
+{
+ FSP_INIT_RT_BUFFER *pFspRtBuffer = FspInitParams->RtBufferPtr;
+#if IS_ENABLED(CONFIG_SOUTHBRIDGE_INTEL_FSP_I89XX)
+ UPD_DATA_REGION *fsp_upd_data = pFspRtBuffer->Common.UpdDataRgnPtr;
+#else
+ MEM_CONFIG MemoryConfig;
+ memset((void*)&MemoryConfig, 0, sizeof(MEM_CONFIG));
+#endif
+ FspInitParams->NvsBufferPtr = NULL;
+
+#if IS_ENABLED(CONFIG_SOUTHBRIDGE_INTEL_FSP_I89XX)
+ /* Initialize the UPD Data */
+ GetUpdDefaultFromFsp (fsp_ptr, fsp_upd_data);
+ ConfigureDefaultUpdData(fsp_upd_data);
+#else
+ pFspRtBuffer->Platform.MemoryConfig = &MemoryConfig;
+ pFspRtBuffer->PlatformConfiguration.PlatformConfig = &DefaultPlatformConfig;
+#endif
+
+#if IS_ENABLED(CONFIG_ENABLE_FSP_FAST_BOOT)
+ /* Find the fastboot cache that was saved in the ROM */
+ FspInitParams->NvsBufferPtr = find_and_set_fastboot_cache();
+#endif
+
+ pFspRtBuffer->Common.BootMode = 0;
+}
+
+/* The FSP returns here after the fsp_early_init call */
+void ChipsetFspReturnPoint(EFI_STATUS Status,
+ VOID *HobListPtr)
+{
+ *(void **)CBMEM_FSP_HOB_PTR=HobListPtr;
+ if (Status == 0xFFFFFFFF) {
+ hard_reset();
+ }
+ romstage_main_continue(Status, HobListPtr);
+}
+
+#endif /* __PRE_RAM__ */
diff --git a/src/northbridge/intel/fsp_sandybridge/fsp/chipset_fsp_util.h b/src/northbridge/intel/fsp_sandybridge/fsp/chipset_fsp_util.h
new file mode 100644
index 0000000000..cb0434776b
--- /dev/null
+++ b/src/northbridge/intel/fsp_sandybridge/fsp/chipset_fsp_util.h
@@ -0,0 +1,68 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013-2014 Sage Electronic Engineering, LLC.
+ *
+ * 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.
+ */
+
+#ifndef CHIPSET_FSP_UTIL_H
+#define CHIPSET_FSP_UTIL_H
+
+#include <fsptypes.h>
+#include <fspfv.h>
+#include <fspffs.h>
+#include <fspapi.h>
+#include <fspplatform.h>
+#include <fspinfoheader.h>
+#include <fsphob.h>
+#if IS_ENABLED(CONFIG_SOUTHBRIDGE_INTEL_FSP_I89XX)
+#include <peifsp.h>
+#include <fsp_vpd.h>
+#endif
+
+#define FSP_RESERVE_MEMORY_SIZE 0x200000
+
+#define FSP_INFO_HEADER_GUID \
+ { \
+ 0x912740BE, 0x2284, 0x4734, {0xB9, 0x71, 0x84, 0xB0, 0x27, 0x35, 0x3F, 0x0C} \
+ }
+
+#define FSP_NON_VOLATILE_STORAGE_HOB_GUID \
+ { \
+ 0x721acf02, 0x4d77, 0x4c2a, { 0xb3, 0xdc, 0x27, 0xb, 0x7b, 0xa9, 0xe4, 0xb0 } \
+ }
+
+
+/*
+ *The FSP Image ID is different for each platform's FSP and
+ * can be used to verify that the right FSP binary is loaded.
+ */
+
+#if IS_ENABLED(CONFIG_SOUTHBRIDGE_INTEL_FSP_I89XX)
+/* ST2-FSP0 */
+#define FSP_IMAGE_ID_DWORD0 0x2D325453
+#define FSP_IMAGE_ID_DWORD1 0x30505346
+#elif IS_ENABLED(CONFIG_SOUTHBRIDGE_INTEL_FSP_BD82X6X)
+/* CC2-FSP\0 */
+#define FSP_IMAGE_ID_DWORD0 0x2D324343
+#define FSP_IMAGE_ID_DWORD1 0x00505346
+#endif
+
+#ifdef __PRE_RAM__
+void main(FSP_INFO_HEADER *fsp_info_header);
+void romstage_main_continue(EFI_STATUS status, VOID *HobListPtr);
+#endif
+
+#endif /* CHIPSET_FSP_UTIL_H */
diff --git a/src/northbridge/intel/fsp_sandybridge/gma.c b/src/northbridge/intel/fsp_sandybridge/gma.c
new file mode 100644
index 0000000000..132a1b869b
--- /dev/null
+++ b/src/northbridge/intel/fsp_sandybridge/gma.c
@@ -0,0 +1,110 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2011 Chromium OS Authors
+ *
+ * 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.
+ */
+
+#include <arch/io.h>
+#include <console/console.h>
+#include <delay.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+
+#include "chip.h"
+#include "northbridge.h"
+
+
+/* some vga option roms are used for several chipsets but they only have one
+ * PCI ID in their header. If we encounter such an option rom, we need to do
+ * the mapping ourselfes
+ */
+
+u32 map_oprom_vendev(u32 vendev)
+{
+ u32 new_vendev=vendev;
+
+ switch (vendev) {
+ case 0x80860102: /* GT1 Desktop */
+ case 0x8086010a: /* GT1 Server */
+ case 0x80860112: /* GT2 Desktop */
+ case 0x80860116: /* GT2 Mobile */
+ case 0x80860122: /* GT2 Desktop >=1.3GHz */
+ case 0x80860126: /* GT2 Mobile >=1.3GHz */
+ case 0x80860166: /* IVB */
+ new_vendev=0x80860106; /* GT1 Mobile */
+ break;
+ }
+
+ return new_vendev;
+}
+
+static void gma_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+ if (!vendor || !device) {
+ pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
+ pci_read_config32(dev, PCI_VENDOR_ID));
+ } else {
+ pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
+ ((device & 0xffff) << 16) | (vendor & 0xffff));
+ }
+}
+
+const struct i915_gpu_controller_info *
+intel_gma_get_controller_info(void)
+{
+ device_t dev = dev_find_slot(0, PCI_DEVFN(0x2,0));
+ if (!dev) {
+ return NULL;
+ }
+ struct northbridge_intel_fsp_sandybridge_config *chip = dev->chip_info;
+ return &chip->gfx;
+}
+
+static void gma_ssdt(device_t device)
+{
+ const struct i915_gpu_controller_info *gfx = intel_gma_get_controller_info();
+ if (!gfx) {
+ return;
+ }
+
+ drivers_intel_gma_displays_ssdt_generate(gfx);
+}
+
+static struct pci_operations gma_pci_ops = {
+ .set_subsystem = gma_set_subsystem,
+};
+
+static struct device_operations gma_func0_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .acpi_fill_ssdt_generator = gma_ssdt,
+ .init = pci_dev_init,
+ .scan_bus = 0,
+ .enable = 0,
+ .ops_pci = &gma_pci_ops,
+};
+
+static const unsigned short gma_ids[] = {
+ 0x0102, 0x0106, 0x010a, 0x0112, 0x0116, 0x0122, 0x0126, 0x166,
+ 0,
+};
+static const struct pci_driver gma_gt1_desktop __pci_driver = {
+ .ops = &gma_func0_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .devices= gma_ids,
+};
diff --git a/src/northbridge/intel/fsp_sandybridge/gma.h b/src/northbridge/intel/fsp_sandybridge/gma.h
new file mode 100644
index 0000000000..9cc2241410
--- /dev/null
+++ b/src/northbridge/intel/fsp_sandybridge/gma.h
@@ -0,0 +1,167 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2012 Chromium OS Authors
+ *
+ * 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.
+ */
+
+/* mailbox 0: header */
+typedef struct {
+ u8 signature[16];
+ u32 size;
+ u32 version;
+ u8 sbios_version[32];
+ u8 vbios_version[16];
+ u8 driver_version[16];
+ u32 mailboxes;
+ u8 reserved[164];
+} __attribute__((packed)) opregion_header_t;
+
+#define IGD_OPREGION_SIGNATURE "IntelGraphicsMem"
+#define IGD_OPREGION_VERSION 2
+
+#define IGD_MBOX1 (1 << 0)
+#define IGD_MBOX2 (1 << 1)
+#define IGD_MBOX3 (1 << 2)
+#define IGD_MBOX4 (1 << 3)
+#define IGD_MBOX5 (1 << 4)
+
+#define MAILBOXES_MOBILE (IGD_MBOX1 | IGD_MBOX2 | IGD_MBOX3 | \
+ IGD_MBOX4 | IGD_MBOX5)
+#define MAILBOXES_DESKTOP (IGD_MBOX2 | IGD_MBOX4)
+
+#define SBIOS_VERSION_SIZE 32
+
+/* mailbox 1: public acpi methods */
+typedef struct {
+ u32 drdy;
+ u32 csts;
+ u32 cevt;
+ u8 reserved1[20];
+ u32 didl[8];
+ u32 cpdl[8];
+ u32 cadl[8];
+ u32 nadl[8];
+ u32 aslp;
+ u32 tidx;
+ u32 chpd;
+ u32 clid;
+ u32 cdck;
+ u32 sxsw;
+ u32 evts;
+ u32 cnot;
+ u32 nrdy;
+ u8 reserved2[60];
+} __attribute__((packed)) opregion_mailbox1_t;
+
+/* mailbox 2: software sci interface */
+typedef struct {
+ u32 scic;
+ u32 parm;
+ u32 dslp;
+ u8 reserved[244];
+} __attribute__((packed)) opregion_mailbox2_t;
+
+/* mailbox 3: power conservation */
+typedef struct {
+ u32 ardy;
+ u32 aslc;
+ u32 tche;
+ u32 alsi;
+ u32 bclp;
+ u32 pfit;
+ u32 cblv;
+ u16 bclm[20];
+ u32 cpfm;
+ u32 epfm;
+ u8 plut[74];
+ u32 pfmb;
+ u32 ccdv;
+ u32 pcft;
+ u8 reserved[94];
+} __attribute__((packed)) opregion_mailbox3_t;
+
+#define IGD_BACKLIGHT_BRIGHTNESS 0xff
+#define IGD_INITIAL_BRIGHTNESS 0x64
+
+#define IGD_FIELD_VALID (1 << 31)
+#define IGD_WORD_FIELD_VALID (1 << 15)
+#define IGD_PFIT_STRETCH 6
+
+/* mailbox 4: vbt */
+typedef struct {
+ u8 gvd1[7168];
+} __attribute__((packed)) opregion_vbt_t;
+
+/* IGD OpRegion */
+typedef struct {
+ opregion_header_t header;
+ opregion_mailbox1_t mailbox1;
+ opregion_mailbox2_t mailbox2;
+ opregion_mailbox3_t mailbox3;
+ opregion_vbt_t vbt;
+} __attribute__((packed)) igd_opregion_t;
+
+/* Intel Video BIOS (Option ROM) */
+typedef struct {
+ u16 signature;
+ u8 size;
+ u8 reserved[21];
+ u16 pcir_offset;
+ u16 vbt_offset;
+} __attribute__((packed)) optionrom_header_t;
+
+#define OPROM_SIGNATURE 0xaa55
+
+typedef struct {
+ u32 signature;
+ u16 vendor;
+ u16 device;
+ u16 reserved1;
+ u16 length;
+ u8 revision;
+ u8 classcode[3];
+ u16 imagelength;
+ u16 coderevision;
+ u8 codetype;
+ u8 indicator;
+ u16 reserved2;
+} __attribute__((packed)) optionrom_pcir_t;
+
+typedef struct {
+ u8 hdr_signature[20];
+ u16 hdr_version;
+ u16 hdr_size;
+ u16 hdr_vbt_size;
+ u8 hdr_vbt_checksum;
+ u8 hdr_reserved;
+ u32 hdr_vbt_datablock;
+ u32 hdr_aim[4];
+ u8 datahdr_signature[16];
+ u16 datahdr_version;
+ u16 datahdr_size;
+ u16 datahdr_datablocksize;
+ u8 coreblock_id;
+ u16 coreblock_size;
+ u16 coreblock_biossize;
+ u8 coreblock_biostype;
+ u8 coreblock_releasestatus;
+ u8 coreblock_hwsupported;
+ u8 coreblock_integratedhw;
+ u8 coreblock_biosbuild[4];
+ u8 coreblock_biossignon[155];
+} __attribute__((packed)) optionrom_vbt_t;
+
+#define VBT_SIGNATURE 0x54425624
diff --git a/src/northbridge/intel/fsp_sandybridge/northbridge.c b/src/northbridge/intel/fsp_sandybridge/northbridge.c
new file mode 100644
index 0000000000..3f982c4a17
--- /dev/null
+++ b/src/northbridge/intel/fsp_sandybridge/northbridge.c
@@ -0,0 +1,407 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ * Copyright (C) 2011 The ChromiumOS Authors. All rights reserved.
+ * Copyright (C) 2013 Sage Electronic Engineering, LLC.
+ *
+ * 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.
+ */
+
+#include <console/console.h>
+#include <arch/acpi.h>
+#include <arch/io.h>
+#include <stdint.h>
+#include <delay.h>
+#include <cpu/intel/fsp_model_206ax/model_206ax.h>
+#include <cpu/x86/msr.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/hypertransport.h>
+#include <stdlib.h>
+#include <string.h>
+#include <cpu/cpu.h>
+#include <cbmem.h>
+#include "chip.h"
+#include "northbridge.h"
+#include <fsp_util.h>
+#include <cpu/intel/smm/gen1/smi.h>
+
+static int bridge_revision_id = -1;
+
+/* IGD UMA memory */
+static uint64_t uma_memory_base = 0;
+static uint64_t uma_memory_size = 0;
+
+int bridge_silicon_revision(void)
+{
+ if (bridge_revision_id < 0) {
+ uint8_t stepping = cpuid_eax(1) & 0xf;
+ uint8_t bridge_id = pci_read_config16(
+ dev_find_slot(0, PCI_DEVFN(0, 0)),
+ PCI_DEVICE_ID) & 0xf0;
+ bridge_revision_id = bridge_id | stepping;
+ }
+ return bridge_revision_id;
+}
+
+/* Reserve everything between A segment and 1MB:
+ *
+ * 0xa0000 - 0xbffff: legacy VGA
+ * 0xc0000 - 0xcffff: VGA OPROM (needed by kernel)
+ * 0xe0000 - 0xfffff: SeaBIOS, if used, otherwise DMI
+ */
+static const int legacy_hole_base_k = 0xa0000 / 1024;
+static const int legacy_hole_size_k = 384;
+
+static int get_pcie_bar(u32 *base, u32 *len)
+{
+ device_t dev;
+ u32 pciexbar_reg;
+
+ *base = 0;
+ *len = 0;
+
+ dev = dev_find_slot(0, PCI_DEVFN(0, 0));
+ if (!dev)
+ return 0;
+
+ pciexbar_reg = pci_read_config32(dev, PCIEXBAR);
+
+ if (!(pciexbar_reg & (1 << 0)))
+ return 0;
+
+ switch ((pciexbar_reg >> 1) & 3) {
+ case 0: // 256MB
+ *base = pciexbar_reg & ((1 << 31)|(1 << 30)|(1 << 29)|(1 << 28));
+ *len = 256 * 1024 * 1024;
+ return 1;
+ case 1: // 128M
+ *base = pciexbar_reg & ((1 << 31)|(1 << 30)|(1 << 29)|(1 << 28)|(1 << 27));
+ *len = 128 * 1024 * 1024;
+ return 1;
+ case 2: // 64M
+ *base = pciexbar_reg & ((1 << 31)|(1 << 30)|(1 << 29)|(1 << 28)|(1 << 27)|(1 << 26));
+ *len = 64 * 1024 * 1024;
+ return 1;
+ }
+
+ return 0;
+}
+
+static void add_fixed_resources(struct device *dev, int index)
+{
+ struct resource *resource;
+ u32 pcie_config_base, pcie_config_size;
+
+ mmio_resource(dev, index++, uma_memory_base >> 10, uma_memory_size >> 10);
+
+ if (get_pcie_bar(&pcie_config_base, &pcie_config_size)) {
+ printk(BIOS_DEBUG, "Adding PCIe config bar base=0x%08x "
+ "size=0x%x\n", pcie_config_base, pcie_config_size);
+ resource = new_resource(dev, index++);
+ resource->base = (resource_t) pcie_config_base;
+ resource->size = (resource_t) pcie_config_size;
+ resource->flags = IORESOURCE_MEM | IORESOURCE_RESERVE |
+ IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_ASSIGNED;
+ }
+
+ mmio_resource(dev, index++, legacy_hole_base_k, legacy_hole_size_k);
+}
+
+static void pci_domain_set_resources(device_t dev)
+{
+ uint64_t tom, me_base, touud;
+ uint32_t tseg_base, uma_size, tolud;
+ uint16_t ggc;
+ unsigned long long tomk;
+
+ tomk = ggc = tseg_base = uma_size = tolud = tom = me_base = touud = 0;
+
+ /* Total Memory 2GB example:
+ *
+ * 00000000 0000MB-1992MB 1992MB RAM (writeback)
+ * 7c800000 1992MB-2000MB 8MB TSEG (SMRR)
+ * 7d000000 2000MB-2002MB 2MB GFX GTT (uncached)
+ * 7d200000 2002MB-2034MB 32MB GFX UMA (uncached)
+ * 7f200000 2034MB TOLUD
+ * 7f800000 2040MB MEBASE
+ * 7f800000 2040MB-2048MB 8MB ME UMA (uncached)
+ * 80000000 2048MB TOM
+ * 100000000 4096MB-4102MB 6MB RAM (writeback)
+ *
+ * Total Memory 4GB example:
+ *
+ * 00000000 0000MB-2768MB 2768MB RAM (writeback)
+ * ad000000 2768MB-2776MB 8MB TSEG (SMRR)
+ * ad800000 2776MB-2778MB 2MB GFX GTT (uncached)
+ * ada00000 2778MB-2810MB 32MB GFX UMA (uncached)
+ * afa00000 2810MB TOLUD
+ * ff800000 4088MB MEBASE
+ * ff800000 4088MB-4096MB 8MB ME UMA (uncached)
+ * 100000000 4096MB TOM
+ * 100000000 4096MB-5374MB 1278MB RAM (writeback)
+ * 14fe00000 5368MB TOUUD
+ */
+
+ /* Top of Upper Usable DRAM, including remap */
+ touud = pci_read_config32(dev, TOUUD+4);
+ touud <<= 32;
+ touud |= pci_read_config32(dev, TOUUD) & ~(1UL << 0);
+
+ /* Top of Lower Usable DRAM */
+ tolud = pci_read_config32(dev, TOLUD) & ~(1UL << 0);
+
+ /* Top of Memory - does not account for any UMA */
+ tom = pci_read_config32(dev, 0xa4);
+ tom <<= 32;
+ tom |= pci_read_config32(dev, 0xa0) & ~(1UL << 0);
+
+ printk(BIOS_DEBUG, "TOUUD 0x%llx TOLUD 0x%08x TOM 0x%llx\n",
+ touud, tolud, tom);
+
+ /* ME UMA needs excluding if total memory <4GB */
+ me_base = pci_read_config32(dev, 0x74);
+ me_base <<= 32;
+ me_base |= pci_read_config32(dev, 0x70);
+
+ printk(BIOS_DEBUG, "MEBASE 0x%llx\n", me_base);
+
+ tomk = tolud >> 10;
+ if (me_base == tolud) {
+ /* ME is from MEBASE-TOM */
+ uma_size = (tom - me_base) >> 10;
+ /* Increment TOLUD to account for ME as RAM */
+ tolud += uma_size << 10;
+ /* UMA starts at old TOLUD */
+ uma_memory_base = tomk * 1024ULL;
+ uma_memory_size = uma_size * 1024ULL;
+ printk(BIOS_DEBUG, "ME UMA base 0x%llx size %uM\n",
+ me_base, uma_size >> 10);
+ }
+
+ /* Graphics memory comes next */
+ ggc = pci_read_config16(dev, GGC);
+ if (!(ggc & 2)) {
+ printk(BIOS_DEBUG, "IGD decoded, subtracting ");
+
+ /* Graphics memory */
+ uma_size = ((ggc >> 3) & 0x1f) * 32 * 1024ULL;
+ printk(BIOS_DEBUG, "%uM UMA", uma_size >> 10);
+ tomk -= uma_size;
+ uma_memory_base = tomk * 1024ULL;
+ uma_memory_size += uma_size * 1024ULL;
+
+ /* GTT Graphics Stolen Memory Size (GGMS) */
+ uma_size = ((ggc >> 8) & 0x3) * 1024ULL;
+ tomk -= uma_size;
+ uma_memory_base = tomk * 1024ULL;
+ uma_memory_size += uma_size * 1024ULL;
+ printk(BIOS_DEBUG, " and %uM GTT\n", uma_size >> 10);
+ }
+
+ /* Calculate TSEG size from its base which must be below GTT */
+ uma_memory_base = tomk * 1024ULL;
+ tseg_base = pci_read_config32(dev, 0xb8) & ~(1UL << 0);
+ uma_size = (uma_memory_base - tseg_base) >> 10;
+ tomk -= uma_size;
+ uma_memory_base = tomk * 1024ULL;
+ uma_memory_size += uma_size * 1024ULL;
+ printk(BIOS_DEBUG, "TSEG base 0x%08x size %uM\n",
+ tseg_base, uma_size >> 10);
+
+ printk(BIOS_INFO, "Available memory below 4GB: %lluM\n", tomk >> 10);
+
+ /* Report the memory regions */
+ ram_resource(dev, 3, 0, legacy_hole_base_k);
+ ram_resource(dev, 4, legacy_hole_base_k + legacy_hole_size_k,
+ (tomk - (legacy_hole_base_k + legacy_hole_size_k)));
+
+ /*
+ * If >= 4GB installed then memory from TOLUD to 4GB
+ * is remapped above TOM, TOUUD will account for both
+ */
+ touud >>= 10; /* Convert to KB */
+ if (touud > 4096 * 1024) {
+ ram_resource(dev, 5, 4096 * 1024, touud - (4096 * 1024));
+ printk(BIOS_INFO, "Available memory above 4GB: %lluM\n",
+ (touud >> 10) - 4096);
+ }
+
+ add_fixed_resources(dev, 6);
+
+ assign_resources(dev->link_list);
+}
+
+ /* TODO We could determine how many PCIe busses we need in
+ * the bar. For now that number is hardcoded to a max of 64.
+ * See e7525/northbridge.c for an example.
+ */
+static struct device_operations pci_domain_ops = {
+ .read_resources = pci_domain_read_resources,
+ .set_resources = pci_domain_set_resources,
+ .enable_resources = NULL,
+ .init = NULL,
+ .scan_bus = pci_domain_scan_bus,
+ .ops_pci_bus = pci_bus_default_ops,
+};
+
+static void mc_read_resources(device_t dev)
+{
+ struct resource *resource;
+
+ pci_dev_read_resources(dev);
+
+ /* So, this is one of the big mysteries in the coreboot resource
+ * allocator. This resource should make sure that the address space
+ * of the PCIe memory mapped config space bar. But it does not.
+ */
+
+ /* We use 0xcf as an unused index for our PCIe bar so that we find it again */
+ resource = new_resource(dev, 0xcf);
+ resource->base = DEFAULT_PCIEXBAR;
+ resource->size = 64 * 1024 * 1024; /* 64MB hard coded PCIe config space */
+ resource->flags =
+ IORESOURCE_MEM | IORESOURCE_FIXED | IORESOURCE_STORED |
+ IORESOURCE_ASSIGNED;
+ printk(BIOS_DEBUG, "Adding PCIe enhanced config space BAR 0x%08lx-0x%08lx.\n",
+ (unsigned long)(resource->base), (unsigned long)(resource->base + resource->size));
+}
+
+static void mc_set_resources(device_t dev)
+{
+ struct resource *resource;
+
+ /* Report the PCIe BAR */
+ resource = find_resource(dev, 0xcf);
+ if (resource) {
+ report_resource_stored(dev, resource, "<mmconfig>");
+ }
+
+ /* And call the normal set_resources */
+ pci_dev_set_resources(dev);
+}
+
+static void intel_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+ if (!vendor || !device) {
+ pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
+ pci_read_config32(dev, PCI_VENDOR_ID));
+ } else {
+ pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
+ ((device & 0xffff) << 16) | (vendor & 0xffff));
+ }
+}
+
+static void northbridge_init(struct device *dev)
+{
+ u8 bios_reset_cpl;
+
+ /*
+ * Set bit 0 of BIOS_RESET_CPL to indicate to the CPU
+ * that BIOS has initialized memory and power management
+ */
+ bios_reset_cpl = MCHBAR8(BIOS_RESET_CPL);
+ bios_reset_cpl |= 1;
+ MCHBAR8(BIOS_RESET_CPL) = bios_reset_cpl;
+ printk(BIOS_DEBUG, "Set BIOS_RESET_CPL\n");
+}
+
+static u32 northbridge_get_base_reg(device_t dev, int reg)
+{
+ u32 value;
+
+ value = pci_read_config32(dev, reg);
+ /* Base registers are at 1MiB granularity. */
+ value &= ~((1 << 20) - 1);
+ return value;
+}
+
+void
+northbridge_get_tseg_base_and_size(u32 *tsegmb, u32 *tseg_size)
+{
+ device_t dev;
+ u32 bgsm;
+ dev = dev_find_slot(0, PCI_DEVFN(0, 0));
+
+ *tsegmb = northbridge_get_base_reg(dev, TSEG);
+ bgsm = northbridge_get_base_reg(dev, BGSM);
+ *tseg_size = bgsm - *tsegmb;
+}
+
+void northbridge_write_smram(u8 smram)
+{
+ pci_write_config8(dev_find_slot(0, PCI_DEVFN(0, 0)), SMRAM, smram);
+}
+
+static struct pci_operations intel_pci_ops = {
+ .set_subsystem = intel_set_subsystem,
+};
+
+static struct device_operations mc_ops = {
+ .read_resources = mc_read_resources,
+ .set_resources = mc_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = northbridge_init,
+ .scan_bus = 0,
+ .ops_pci = &intel_pci_ops,
+ .acpi_fill_ssdt_generator = generate_cpu_entries,
+};
+
+static const struct pci_driver mc_driver_0100 __pci_driver = {
+ .ops = &mc_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = 0x0100,
+};
+
+static const struct pci_driver mc_driver __pci_driver = {
+ .ops = &mc_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = 0x0104, /* Sandy bridge */
+};
+
+static const struct pci_driver mc_driver_1 __pci_driver = {
+ .ops = &mc_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = 0x0154, /* Ivy bridge */
+};
+
+static void cpu_bus_init(device_t dev)
+{
+ initialize_cpus(dev->link_list);
+}
+
+static struct device_operations cpu_bus_ops = {
+ .read_resources = DEVICE_NOOP,
+ .set_resources = DEVICE_NOOP,
+ .enable_resources = DEVICE_NOOP,
+ .init = cpu_bus_init,
+ .scan_bus = 0,
+};
+
+static void enable_dev(device_t dev)
+{
+ /* Set the operations if it is a special bus type */
+ if (dev->path.type == DEVICE_PATH_DOMAIN) {
+ dev->ops = &pci_domain_ops;
+ } else if (dev->path.type == DEVICE_PATH_CPU_CLUSTER) {
+ dev->ops = &cpu_bus_ops;
+ }
+}
+
+struct chip_operations northbridge_intel_fsp_sandybridge_ops = {
+ CHIP_NAME("Intel i7 (SandyBridge/IvyBridge) integrated Northbridge")
+ .enable_dev = enable_dev,
+};
diff --git a/src/northbridge/intel/fsp_sandybridge/northbridge.h b/src/northbridge/intel/fsp_sandybridge/northbridge.h
new file mode 100644
index 0000000000..4861254902
--- /dev/null
+++ b/src/northbridge/intel/fsp_sandybridge/northbridge.h
@@ -0,0 +1,231 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2008 coresystems GmbH
+ * Copyright (C) 2011 Google Inc.
+ * Copyright (C) 2013 Sage Electronic Engineering, LLC.
+ *
+ * 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.
+ */
+
+#ifndef __NORTHBRIDGE_INTEL_SANDYBRIDGE_SANDYBRIDGE_H__
+#define __NORTHBRIDGE_INTEL_SANDYBRIDGE_SANDYBRIDGE_H__
+
+/* Chipset types */
+#define SANDYBRIDGE_MOBILE 0
+#define SANDYBRIDGE_DESKTOP 1
+#define SANDYBRIDGE_SERVER 2
+
+/* Device ID for SandyBridge and IvyBridge */
+#define BASE_REV_SNB 0x00
+#define BASE_REV_IVB 0x50
+#define BASE_REV_MASK 0x50
+
+/* SandyBridge CPU stepping */
+#define SNB_STEP_D0 (BASE_REV_SNB + 5) /* Also J0 */
+#define SNB_STEP_D1 (BASE_REV_SNB + 6)
+#define SNB_STEP_D2 (BASE_REV_SNB + 7) /* Also J1/Q0 */
+
+/* IvyBridge CPU stepping */
+#define IVB_STEP_A0 (BASE_REV_IVB + 0)
+#define IVB_STEP_B0 (BASE_REV_IVB + 2)
+#define IVB_STEP_C0 (BASE_REV_IVB + 4)
+#define IVB_STEP_K0 (BASE_REV_IVB + 5)
+#define IVB_STEP_D0 (BASE_REV_IVB + 6)
+
+/* Intel Enhanced Debug region must be 4MB */
+#define IED_SIZE 0x400000
+
+/* Northbridge BARs */
+#define DEFAULT_PCIEXBAR CONFIG_MMCONF_BASE_ADDRESS /* 4 KB per PCIe device */
+#ifndef __ACPI__
+#define DEFAULT_MCHBAR ((u8 *)0xfed10000) /* 16 KB */
+#define DEFAULT_DMIBAR ((u8 *)0xfed18000) /* 4 KB */
+#else
+#define DEFAULT_MCHBAR 0xfed10000 /* 16 KB */
+#define DEFAULT_DMIBAR 0xfed18000 /* 4 KB */
+#endif
+#define DEFAULT_EPBAR 0xfed19000 /* 4 KB */
+#define DEFAULT_RCBABASE ((u8 *)0xfed1c000)
+
+#if CONFIG_SOUTHBRIDGE_INTEL_FSP_BD82X6X
+#include <southbridge/intel/fsp_bd82x6x/pch.h>
+#endif
+
+/* Everything below this line is ignored in the DSDT */
+#ifndef __ACPI__
+
+/* Device 0:0.0 PCI configuration space (Host Bridge) */
+
+#define EPBAR 0x40
+#define MCHBAR 0x48
+#define PCIEXBAR 0x60
+#define DMIBAR 0x68
+#define X60BAR 0x60
+
+#define GGC 0x50 /* GMCH Graphics Control */
+
+#define DEVEN 0x54 /* Device Enable */
+#define DEVEN_PEG60 (1 << 13)
+#define DEVEN_IGD (1 << 4)
+#define DEVEN_PEG10 (1 << 3)
+#define DEVEN_PEG11 (1 << 2)
+#define DEVEN_PEG12 (1 << 1)
+#define DEVEN_HOST (1 << 0)
+
+#define PAM0 0x80
+#define PAM1 0x81
+#define PAM2 0x82
+#define PAM3 0x83
+#define PAM4 0x84
+#define PAM5 0x85
+#define PAM6 0x86
+
+#define LAC 0x87 /* Legacy Access Control */
+#define SMRAM 0x88 /* System Management RAM Control */
+
+#define TOM 0xa0
+#define TOUUD 0xa8 /* Top of Upper Usable DRAM */
+#define BGSM 0xb4 /* Base GTT Stolen Memory */
+#define TSEG 0xb8 /* TSEG base */
+#define TOLUD 0xbc /* Top of Low Used Memory */
+
+#define SKPAD 0xdc /* Scratchpad Data */
+
+/* Device 0:1.0 PCI configuration space (PCI Express) */
+
+#define BCTRL1 0x3e /* 16bit */
+
+
+/* Device 0:2.0 PCI configuration space (Graphics Device) */
+
+#define MSAC 0x62 /* Multi Size Aperture Control */
+#define SWSCI 0xe8 /* SWSCI enable */
+#define ASLS 0xfc /* OpRegion Base */
+
+/*
+ * MCHBAR
+ */
+
+#define MCHBAR8(x) *((volatile u8 *)(DEFAULT_MCHBAR + x))
+#define MCHBAR16(x) *((volatile u16 *)(DEFAULT_MCHBAR + x))
+#define MCHBAR32(x) *((volatile u32 *)(DEFAULT_MCHBAR + x))
+#define MCHBAR32_OR(x, or) MCHBAR32(x) = (MCHBAR32(x) | (or))
+
+#define SSKPD 0x5d14 /* 16bit (scratchpad) */
+#define BIOS_RESET_CPL 0x5da8 /* 8bit */
+
+/*
+ * EPBAR - Egress Port Root Complex Register Block
+ */
+
+#define EPBAR8(x) *((volatile u8 *)(DEFAULT_EPBAR + x))
+#define EPBAR16(x) *((volatile u16 *)(DEFAULT_EPBAR + x))
+#define EPBAR32(x) *((volatile u32 *)(DEFAULT_EPBAR + x))
+
+#define EPPVCCAP1 0x004 /* 32bit */
+#define EPPVCCAP2 0x008 /* 32bit */
+
+#define EPVC0RCAP 0x010 /* 32bit */
+#define EPVC0RCTL 0x014 /* 32bit */
+#define EPVC0RSTS 0x01a /* 16bit */
+
+#define EPVC1RCAP 0x01c /* 32bit */
+#define EPVC1RCTL 0x020 /* 32bit */
+#define EPVC1RSTS 0x026 /* 16bit */
+
+#define EPVC1MTS 0x028 /* 32bit */
+#define EPVC1IST 0x038 /* 64bit */
+
+#define EPESD 0x044 /* 32bit */
+
+#define EPLE1D 0x050 /* 32bit */
+#define EPLE1A 0x058 /* 64bit */
+#define EPLE2D 0x060 /* 32bit */
+#define EPLE2A 0x068 /* 64bit */
+
+#define PORTARB 0x100 /* 256bit */
+
+/*
+ * DMIBAR
+ */
+
+#define DMIBAR8(x) *((volatile u8 *)(DEFAULT_DMIBAR + x))
+#define DMIBAR16(x) *((volatile u16 *)(DEFAULT_DMIBAR + x))
+#define DMIBAR32(x) *((volatile u32 *)(DEFAULT_DMIBAR + x))
+
+#define DMIVCECH 0x000 /* 32bit */
+#define DMIPVCCAP1 0x004 /* 32bit */
+#define DMIPVCCAP2 0x008 /* 32bit */
+
+#define DMIPVCCCTL 0x00c /* 16bit */
+
+#define DMIVC0RCAP 0x010 /* 32bit */
+#define DMIVC0RCTL0 0x014 /* 32bit */
+#define DMIVC0RSTS 0x01a /* 16bit */
+
+#define DMIVC1RCAP 0x01c /* 32bit */
+#define DMIVC1RCTL 0x020 /* 32bit */
+#define DMIVC1RSTS 0x026 /* 16bit */
+
+#define DMILE1D 0x050 /* 32bit */
+#define DMILE1A 0x058 /* 64bit */
+#define DMILE2D 0x060 /* 32bit */
+#define DMILE2A 0x068 /* 64bit */
+
+#define DMILCAP 0x084 /* 32bit */
+#define DMILCTL 0x088 /* 16bit */
+#define DMILSTS 0x08a /* 16bit */
+
+#define DMICTL1 0x0f0 /* 32bit */
+#define DMICTL2 0x0fc /* 32bit */
+
+#define DMICC 0x208 /* 32bit */
+
+#define DMIDRCCFG 0xeb4 /* 32bit */
+
+#ifndef __ASSEMBLER__
+static inline void barrier(void) { asm("" ::: "memory"); }
+
+#define PCI_DEVICE_ID_SB 0x0104
+#define PCI_DEVICE_ID_IB 0x0154
+
+#ifdef __SMM__
+void intel_sandybridge_finalize_smm(void);
+#else /* !__SMM__ */
+int bridge_silicon_revision(void);
+void sandybridge_early_initialization(int chipset_type);
+void sandybridge_late_initialization(void);
+
+/* debugging functions */
+void print_pci_devices(void);
+void dump_pci_device(unsigned dev);
+void dump_pci_devices(void);
+void dump_spd_registers(void);
+void dump_mem(unsigned start, unsigned end);
+void report_platform_info(void);
+#endif /* !__SMM__ */
+
+
+#define MRC_DATA_ALIGN 0x1000
+#define MRC_DATA_SIGNATURE (('M'<<0)|('R'<<8)|('C'<<16)|('D'<<24))
+
+#if !defined(__PRE_RAM__)
+#include "gma.h"
+int init_igd_opregion(igd_opregion_t *igd_opregion);
+#endif
+
+#endif
+#endif
+#endif /* __NORTHBRIDGE_INTEL_SANDYBRIDGE_SANDYBRIDGE_H__ */
diff --git a/src/northbridge/intel/fsp_sandybridge/northbridge_pci_devs.h b/src/northbridge/intel/fsp_sandybridge/northbridge_pci_devs.h
new file mode 100644
index 0000000000..b63149f61f
--- /dev/null
+++ b/src/northbridge/intel/fsp_sandybridge/northbridge_pci_devs.h
@@ -0,0 +1,47 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google Inc.
+ * Copyright (C) 2014 Sage Electronic Engineering, LLC.
+ *
+ * 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.
+ */
+
+#ifndef _INTEL_FSP_SANDYBRIDGE_PCI_DEVS_H_
+#define _INTEL_FSP_SANDYBRIDGE_PCI_DEVS_H_
+
+#include <device/pci_def.h>
+
+#define BUS0 0
+
+/* NB PCIe PEG slot */
+#define NB_PEG_DEV 0x01
+#define NB_PEG_FUNC 0
+# define NB_PEG_DEVFN PCI_DEVFN(NB_PEG_DEV, NB_PEG_FUNC)
+#define PCIE_CTRL1_FUNC 1
+# define PCIE_CTRL1_DEVFN PCI_DEVFN(NB_PEG_DEV, PCIE_CTRL1_FUNC)
+#define PCIE_CTRL2_FUNC 2
+# define PCIE_CTRL2_DEVFN PCI_DEVFN(NB_PEG_DEV, PCIE_CTRL2_FUNC)
+
+/* Onboard Graphics */
+#define GFX_DEV 0x02
+#define GFX_FUNC 0
+# define GFX_DEVFN PCI_DEVFN(GFX_DEV, GFX_FUNC)
+
+/* NB PCIe slot */
+#define NB_PCIE_DEV 0x06
+#define NB_PCIE_FUNC 0
+# define NB_PCIE_DEVFN PCI_DEVFN(NB_PCIE_DEV, NB_PCIE_FUNC)
+
+#endif /* _INTEL_FSP_SANDYBRIDGE_PCI_DEVS_H_ */
diff --git a/src/northbridge/intel/fsp_sandybridge/ram_calc.c b/src/northbridge/intel/fsp_sandybridge/ram_calc.c
new file mode 100644
index 0000000000..37d74fc617
--- /dev/null
+++ b/src/northbridge/intel/fsp_sandybridge/ram_calc.c
@@ -0,0 +1,38 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2011 Google Inc.
+ * Copyright (C) 2013 Sage Electronic Engineering, LLC.
+ *
+ * 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.
+ */
+
+#define __SIMPLE_DEVICE__
+
+#include <arch/io.h>
+#include <cbmem.h>
+#include <fsp_util.h>
+#include "northbridge.h"
+
+static uintptr_t smm_region_start(void)
+{
+ /* Base of TSEG is top of usable DRAM */
+ uintptr_t tom = pci_read_config32(PCI_DEV(0,0,0), TSEG) & ~(1UL << 0);
+ return tom;
+}
+
+void *cbmem_top(void)
+{
+ return (void *) (smm_region_start() - FSP_RESERVE_MEMORY_SIZE);
+}
diff --git a/src/northbridge/intel/fsp_sandybridge/raminit.c b/src/northbridge/intel/fsp_sandybridge/raminit.c
new file mode 100644
index 0000000000..408b4b0611
--- /dev/null
+++ b/src/northbridge/intel/fsp_sandybridge/raminit.c
@@ -0,0 +1,76 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2011 Google Inc.
+ *
+ * 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.
+ */
+
+#include <console/console.h>
+#include <string.h>
+#include <arch/io.h>
+#include <cbmem.h>
+#include <device/pci_def.h>
+#include "raminit.h"
+#include "northbridge.h"
+
+static const char* ecc_decoder[] = {
+ "inactive",
+ "active on IO",
+ "disabled on IO",
+ "active"
+};
+
+/*
+ * Dump in the log memory controller configuration as read from the memory
+ * controller registers.
+ */
+void report_memory_config(void)
+{
+ u32 addr_decoder_common, addr_decode_ch[2];
+ int i;
+
+ addr_decoder_common = MCHBAR32(0x5000);
+ addr_decode_ch[0] = MCHBAR32(0x5004);
+ addr_decode_ch[1] = MCHBAR32(0x5008);
+
+ printk(BIOS_DEBUG, "memcfg DDR3 clock %d MHz\n",
+ (MCHBAR32(0x5e04) * 13333 * 2 + 50)/100);
+ printk(BIOS_DEBUG, "memcfg channel assignment: A: %d, B % d, C % d\n",
+ addr_decoder_common & 3,
+ (addr_decoder_common >> 2) & 3,
+ (addr_decoder_common >> 4) & 3);
+
+ for (i = 0; i < ARRAY_SIZE(addr_decode_ch); i++) {
+ u32 ch_conf = addr_decode_ch[i];
+ printk(BIOS_DEBUG, "memcfg channel[%d] config (%8.8x):\n",
+ i, ch_conf);
+ printk(BIOS_DEBUG, " ECC %s\n",
+ ecc_decoder[(ch_conf >> 24) & 3]);
+ printk(BIOS_DEBUG, " enhanced interleave mode %s\n",
+ ((ch_conf >> 22) & 1) ? "on" : "off");
+ printk(BIOS_DEBUG, " rank interleave %s\n",
+ ((ch_conf >> 21) & 1) ? "on" : "off");
+ printk(BIOS_DEBUG, " DIMMA %d MB width x%d %s rank%s\n",
+ ((ch_conf >> 0) & 0xff) * 256,
+ ((ch_conf >> 19) & 1) ? 16 : 8,
+ ((ch_conf >> 17) & 1) ? "dual" : "single",
+ ((ch_conf >> 16) & 1) ? "" : ", selected");
+ printk(BIOS_DEBUG, " DIMMB %d MB width x%d %s rank%s\n",
+ ((ch_conf >> 8) & 0xff) * 256,
+ ((ch_conf >> 20) & 1) ? 16 : 8,
+ ((ch_conf >> 18) & 1) ? "dual" : "single",
+ ((ch_conf >> 16) & 1) ? ", selected" : "");
+ }
+}
diff --git a/src/northbridge/intel/fsp_sandybridge/raminit.h b/src/northbridge/intel/fsp_sandybridge/raminit.h
new file mode 100644
index 0000000000..c97b64cb2c
--- /dev/null
+++ b/src/northbridge/intel/fsp_sandybridge/raminit.h
@@ -0,0 +1,25 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2010 Google Inc.
+ *
+ * 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.
+ */
+
+#ifndef RAMINIT_H
+#define RAMINIT_H
+
+void report_memory_config(void);
+
+#endif /* RAMINIT_H */
diff --git a/src/northbridge/intel/fsp_sandybridge/report_platform.c b/src/northbridge/intel/fsp_sandybridge/report_platform.c
new file mode 100644
index 0000000000..e661487a6f
--- /dev/null
+++ b/src/northbridge/intel/fsp_sandybridge/report_platform.c
@@ -0,0 +1,114 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2012 Google Inc.
+ * Copyright (C) 2013 Sage Electronic Engineering, LLC.
+ *
+ * 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.
+ */
+
+#include <console/console.h>
+#include <arch/cpu.h>
+#include <string.h>
+
+#if CONFIG_SOUTHBRIDGE_INTEL_FSP_BD82X6X
+#include <southbridge/intel/fsp_bd82x6x/pch.h>
+#endif
+
+#include <arch/io.h>
+#include "northbridge.h"
+
+static void report_cpu_info(void)
+{
+ struct cpuid_result cpuidr;
+ u32 i, index;
+ char cpu_string[50], *cpu_name = cpu_string; /* 48 bytes are reported */
+ int vt, txt, aes;
+ const char *mode[] = {"NOT ", ""};
+
+ index = 0x80000000;
+ cpuidr = cpuid(index);
+ if (cpuidr.eax < 0x80000004) {
+ strcpy(cpu_string, "Platform info not available");
+ } else {
+ u32 *p = (u32*) cpu_string;
+ for (i = 2; i <= 4 ; i++) {
+ cpuidr = cpuid(index + i);
+ *p++ = cpuidr.eax;
+ *p++ = cpuidr.ebx;
+ *p++ = cpuidr.ecx;
+ *p++ = cpuidr.edx;
+ }
+ }
+ /* Skip leading spaces in CPU name string */
+ while (cpu_name[0] == ' ')
+ cpu_name++;
+
+ cpuidr = cpuid(1);
+ printk(BIOS_DEBUG, "CPU id(%x): %s\n", cpuidr.eax, cpu_name);
+ aes = (cpuidr.ecx & (1 << 25)) ? 1 : 0;
+ txt = (cpuidr.ecx & (1 << 6)) ? 1 : 0;
+ vt = (cpuidr.ecx & (1 << 5)) ? 1 : 0;
+ printk(BIOS_DEBUG, "AES %ssupported, TXT %ssupported, VT %ssupported\n",
+ mode[aes], mode[txt], mode[vt]);
+}
+
+/* The PCI id name match comes from Intel document 472178 */
+static struct {
+ u16 dev_id;
+ const char *dev_name;
+} pch_table [] = {
+ {0x1E41, "Desktop Sample"},
+ {0x1E42, "Mobile Sample"},
+ {0x1E43, "SFF Sample"},
+ {0x1E44, "Z77"},
+ {0x1E45, "H71"},
+ {0x1E46, "Z75"},
+ {0x1E47, "Q77"},
+ {0x1E48, "Q75"},
+ {0x1E49, "B75"},
+ {0x1E4A, "H77"},
+ {0x1E53, "C216"},
+ {0x1E55, "QM77"},
+ {0x1E56, "QS77"},
+ {0x1E58, "UM77"},
+ {0x1E57, "HM77"},
+ {0x1E59, "HM76"},
+ {0x1E5D, "HM75"},
+ {0x1E5E, "HM70"},
+ {0x1E5F, "NM70"},
+};
+
+static void report_pch_info(void)
+{
+ int i;
+ u16 dev_id = pci_read_config16(PCH_LPC_DEV, 2);
+
+
+ const char *pch_type = "Unknown";
+ for (i = 0; i < ARRAY_SIZE(pch_table); i++) {
+ if (pch_table[i].dev_id == dev_id) {
+ pch_type = pch_table[i].dev_name;
+ break;
+ }
+ }
+ printk (BIOS_DEBUG, "PCH type: %s, device id: %x, rev id %x\n",
+ pch_type, dev_id, pci_read_config8(PCH_LPC_DEV, 8));
+}
+
+void report_platform_info(void)
+{
+ report_cpu_info();
+ report_pch_info();
+}
diff --git a/src/northbridge/intel/fsp_sandybridge/udelay.c b/src/northbridge/intel/fsp_sandybridge/udelay.c
new file mode 100644
index 0000000000..e6dcbf180e
--- /dev/null
+++ b/src/northbridge/intel/fsp_sandybridge/udelay.c
@@ -0,0 +1,55 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2008 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.
+ */
+
+#include <delay.h>
+#include <stdint.h>
+#include <cpu/x86/tsc.h>
+#include <cpu/x86/msr.h>
+
+/**
+ * Intel SandyBridge/IvyBridge CPUs always run the TSC at BCLK=100MHz
+ */
+
+void udelay(u32 us)
+{
+ u32 dword;
+ tsc_t tsc, tsc1, tscd;
+ msr_t msr;
+ u32 fsb = 100, divisor;
+ u32 d; /* ticks per us */
+
+ msr = rdmsr(0xce);
+ divisor = (msr.lo >> 8) & 0xff;
+
+ d = fsb * divisor; /* On Core/Core2 this is divided by 4 */
+ multiply_to_tsc(&tscd, us, d);
+
+ tsc1 = rdtsc();
+ dword = tsc1.lo + tscd.lo;
+ if ((dword < tsc1.lo) || (dword < tscd.lo)) {
+ tsc1.hi++;
+ }
+ tsc1.lo = dword;
+ tsc1.hi += tscd.hi;
+
+ do {
+ tsc = rdtsc();
+ } while ((tsc.hi < tsc1.hi)
+ || ((tsc.hi == tsc1.hi) && (tsc.lo <= tsc1.lo)));
+}