Martin Roth (gaumless(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/6369
-gerrit
commit b4c31939eacfaafe2aa1ae73fc6a86c5dc86a372
Author: Martin Roth <gaumless(a)gmail.com>
Date: Wed May 21 14:20:38 2014 -0600
northbridge/intel: Add fsp_rangeley northbridge support
This adds the northbridge initialization pieces for Intel's Atom C2000
processor (Formerly Rangeley). It is intended to be used with the Intel
Atom C2000 FSP and does not contain all of the pieces that would
otherwise be required for initialization.
Not currently supported:
S3 suspend/resume
CAR memory Migration (No early cbmem console)
SMM
Change-Id: I7665212c892d9a08ecf35d7be70d0afe5fd2c77b
Signed-off-by: Martin Roth <gaumless(a)gmail.com>
---
src/northbridge/intel/Kconfig | 1 +
src/northbridge/intel/Makefile.inc | 1 +
src/northbridge/intel/fsp_rangeley/Kconfig | 92 +++++++
src/northbridge/intel/fsp_rangeley/Makefile.inc | 39 +++
src/northbridge/intel/fsp_rangeley/acpi.c | 66 +++++
.../intel/fsp_rangeley/acpi/hostbridge.asl | 138 ++++++++++
.../intel/fsp_rangeley/acpi/rangeley.asl | 41 +++
src/northbridge/intel/fsp_rangeley/chip.h | 63 +++++
src/northbridge/intel/fsp_rangeley/fsp/Kconfig | 49 ++++
.../intel/fsp_rangeley/fsp/Makefile.inc | 21 ++
.../intel/fsp_rangeley/fsp/chipset_fsp_util.c | 177 ++++++++++++
.../intel/fsp_rangeley/fsp/chipset_fsp_util.h | 52 ++++
src/northbridge/intel/fsp_rangeley/northbridge.c | 302 +++++++++++++++++++++
src/northbridge/intel/fsp_rangeley/northbridge.h | 78 ++++++
src/northbridge/intel/fsp_rangeley/port_access.c | 72 +++++
src/northbridge/intel/fsp_rangeley/raminit.c | 44 +++
src/northbridge/intel/fsp_rangeley/udelay.c | 68 +++++
17 files changed, 1304 insertions(+)
diff --git a/src/northbridge/intel/Kconfig b/src/northbridge/intel/Kconfig
index b9ee5c6..001e875 100644
--- a/src/northbridge/intel/Kconfig
+++ b/src/northbridge/intel/Kconfig
@@ -16,3 +16,4 @@ source src/northbridge/intel/nehalem/Kconfig
source src/northbridge/intel/sandybridge/Kconfig
source src/northbridge/intel/haswell/Kconfig
source src/northbridge/intel/fsp_sandybridge/Kconfig
+source src/northbridge/intel/fsp_rangeley/Kconfig
diff --git a/src/northbridge/intel/Makefile.inc b/src/northbridge/intel/Makefile.inc
index 808a1b2..b4fdefe 100644
--- a/src/northbridge/intel/Makefile.inc
+++ b/src/northbridge/intel/Makefile.inc
@@ -18,3 +18,4 @@ subdirs-$(CONFIG_NORTHBRIDGE_INTEL_IVYBRIDGE) += sandybridge
subdirs-$(CONFIG_NORTHBRIDGE_INTEL_HASWELL) += haswell
subdirs-$(CONFIG_NORTHBRIDGE_INTEL_FSP_SANDYBRIDGE) += fsp_sandybridge
subdirs-$(CONFIG_NORTHBRIDGE_INTEL_FSP_IVYBRIDGE) += fsp_sandybridge
+subdirs-$(CONFIG_NORTHBRIDGE_INTEL_FSP_RANGELEY) += fsp_rangeley
diff --git a/src/northbridge/intel/fsp_rangeley/Kconfig b/src/northbridge/intel/fsp_rangeley/Kconfig
new file mode 100644
index 0000000..c1353ca
--- /dev/null
+++ b/src/northbridge/intel/fsp_rangeley/Kconfig
@@ -0,0 +1,92 @@
+##
+## 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+##
+
+config NORTHBRIDGE_INTEL_FSP_RANGELEY
+ bool
+ select CPU_INTEL_FSP_MODEL_406DX
+
+if NORTHBRIDGE_INTEL_FSP_RANGELEY
+
+config MMCONF_BASE_ADDRESS
+ hex
+ default 0xe0000000
+
+choice
+ prompt "Set TSEG Size"
+ default SET_TSEG_1MB if SET_DEFAULT_TSEG_1MB
+ default SET_TSEG_2MB if SET_DEFAULT_TSEG_2MB
+ default SET_TSEG_4MB if SET_DEFAULT_TSEG_4MB
+ default SET_TSEG_8MB if SET_DEFAULT_TSEG_8MB
+
+config SET_TSEG_1MB
+ bool "1 MB"
+ help
+ Set the TSEG area to 1 MB.
+
+config SET_TSEG_2MB
+ bool "2 MB"
+ help
+ Set the TSEG area to 2 MB.
+
+config SET_TSEG_4MB
+ bool "4 MB"
+ help
+ Set the TSEG area to 4 MB.
+
+config SET_TSEG_8MB
+ bool "8 MB"
+ help
+ Set the TSEG area to 8 MB.
+endchoice
+
+config SMM_TSEG_SIZE
+ hex
+ default 0x200000 if SET_TSEG_2MB
+ default 0x400000 if SET_TSEG_4MB
+ default 0x800000 if SET_TSEG_8MB
+ default 0x100000 # SET_TSEG_1MB
+
+config SMM_RESERVED_SIZE
+ hex
+ default 0x200000 if SET_TSEG_2MB
+ default 0x400000 if SET_TSEG_4MB
+ default 0x800000 if SET_TSEG_8MB
+ default 0x100000 # SET_TSEG_1MB
+
+config SET_DEFAULT_TSEG_1MB
+ bool
+ default n
+
+config SET_DEFAULT_TSEG_2MB
+ bool
+ default n
+
+config SET_DEFAULT_TSEG_4MB
+ bool
+ default n
+
+config SET_DEFAULT_TSEG_8MB
+ bool
+ default n
+
+# Rangeley Specific FSP Kconfig
+source src/northbridge/intel/fsp_rangeley/fsp/Kconfig
+
+endif # NORTHBRIDGE_INTEL_FSP_RANGELEY
diff --git a/src/northbridge/intel/fsp_rangeley/Makefile.inc b/src/northbridge/intel/fsp_rangeley/Makefile.inc
new file mode 100644
index 0000000..d9955fe
--- /dev/null
+++ b/src/northbridge/intel/fsp_rangeley/Makefile.inc
@@ -0,0 +1,39 @@
+#
+# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+#
+
+subdirs-y += fsp
+ramstage-y += northbridge.c
+ramstage-y += raminit.c
+
+ramstage-$(CONFIG_GENERATE_ACPI_TABLES) += acpi.c
+ramstage-y += port_access.c
+
+romstage-y += raminit.c
+romstage-y += ../../../arch/x86/lib/walkcbfs.S
+romstage-y += port_access.c
+
+smm-$(CONFIG_HAVE_SMI_HANDLER) += udelay.c
+
+CPPFLAGS_common += -I$(src)/mainboard/$(MAINBOARDDIR)
+
+CPPFLAGS_common += -I$(src)/northbridge/intel/fsp_rangeley/
+CPPFLAGS_common += -I$(src)/northbridge/intel/fsp_rangeley/fsp
+
+$(obj)/northbridge/intel/fsp_rangeley/acpi.ramstage.o : $(obj)/build.h
diff --git a/src/northbridge/intel/fsp_rangeley/acpi.c b/src/northbridge/intel/fsp_rangeley/acpi.c
new file mode 100644
index 0000000..895f5b4
--- /dev/null
+++ b/src/northbridge/intel/fsp_rangeley/acpi.c
@@ -0,0 +1,66 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ * Copyright (C) 2012 The Chromium OS Authors
+ * 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., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#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 <build.h>
+#include "northbridge.h"
+
+unsigned long acpi_fill_mcfg(unsigned long current)
+{
+ device_t dev;
+ u32 pciexbar = 0;
+ u32 pciexbar_reg;
+ int max_buses;
+ int pci_dev_id;
+
+ for (pci_dev_id = PCI_DEVICE_ID_RG_MIN; pci_dev_id <= PCI_DEVICE_ID_RG_MAX; pci_dev_id++) {
+ dev = dev_find_device(PCI_VENDOR_ID_INTEL, pci_dev_id, 0);
+ if (dev)
+ break;
+ }
+
+ if (!dev)
+ return current;
+
+ pciexbar_reg = sideband_read(B_UNIT, BECREG);
+
+ /* MMCFG not supported or not enabled. */
+ if (!(pciexbar_reg & (1 << 0)))
+ return current;
+
+ /* 256MB ECAM range */
+ pciexbar = pciexbar_reg & ((1 << 31)|(1 << 30)|(1 << 29)|(1 << 28));
+ max_buses = 256;
+
+ current += acpi_create_mcfg_mmconfig((acpi_mcfg_mmconfig_t *) current,
+ pciexbar, 0x0, 0x0, max_buses - 1);
+
+ return current;
+}
diff --git a/src/northbridge/intel/fsp_rangeley/acpi/hostbridge.asl b/src/northbridge/intel/fsp_rangeley/acpi/hostbridge.asl
new file mode 100644
index 0000000..5cefaeb
--- /dev/null
+++ b/src/northbridge/intel/fsp_rangeley/acpi/hostbridge.asl
@@ -0,0 +1,138 @@
+/*
+ * 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
+ */
+
+#include <arch/ioapic.h>
+
+Name(_HID,EISAID("PNP0A08")) // PCIe
+Name(_CID,EISAID("PNP0A03")) // PCI
+
+Name(_ADR, 0)
+Name(_BBN, 0)
+
+// This is in the SSDT and can be accessed by the DSDT
+External (BMBD)
+
+// 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-0xfebfffff)
+ DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
+ Cacheable, ReadWrite,
+ 0x00000000, 0x00000000, 0xfebfffff, 0x00000000,
+ 0xfec00000,,, PM01)
+
+ // TPM Area (0xfed40000-0xfed44fff)
+ DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
+ Cacheable, ReadWrite,
+ 0x00000000, 0xfed40000, 0xfed44fff, 0x00000000,
+ 0x00005000,,, TPMR)
+ }) // End MCRS
+
+ // 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 (BMBD, PMIN) // Memory goes from BMBOUND to 0xfebfffff (PM01 above)
+ Add(Subtract(PMAX, PMIN), 1, PLEN) // Store Memory Size
+
+ Return (MCRS)
+} // End _CRS
diff --git a/src/northbridge/intel/fsp_rangeley/acpi/rangeley.asl b/src/northbridge/intel/fsp_rangeley/acpi/rangeley.asl
new file mode 100644
index 0000000..6a8c2e0
--- /dev/null
+++ b/src/northbridge/intel/fsp_rangeley/acpi/rangeley.asl
@@ -0,0 +1,41 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ * 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., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#include "../northbridge.h"
+#include "hostbridge.asl"
+
+/* PCI Device Resource Consumption */
+Device (PDRC)
+{
+ Name (_HID, EISAID("PNP0C02"))
+ Name (_UID, 1)
+
+ Name (PDRS, ResourceTemplate() {
+ Memory32Fixed(ReadWrite, DEFAULT_ECBASE, 0x04000000)
+ })
+
+ // Current Resource Settings
+ Method (_CRS, 0, Serialized)
+ {
+ Return(PDRS)
+ }
+}
diff --git a/src/northbridge/intel/fsp_rangeley/chip.h b/src/northbridge/intel/fsp_rangeley/chip.h
new file mode 100644
index 0000000..24609a1
--- /dev/null
+++ b/src/northbridge/intel/fsp_rangeley/chip.h
@@ -0,0 +1,63 @@
+/*
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _FSP_RANGELEY_CHIP_H_
+#define _FSP_RANGELEY_CHIP_H_
+
+#include <arch/acpi.h>
+
+struct northbridge_intel_fsp_rangeley_config {
+
+ /* Set the CPGC exp_loop_cnt field for RMT execution 2^(exp_loop_cnt -1) */
+ /* Valid values: 0 - 15 */
+ uint8_t MrcRmtCpgcExpLoopCntValue;
+ /* Set the CPGC num_bursts field for RMT execution 2^(num_bursts -1) */
+ /* Valid values: 0 - 15 */
+ uint8_t MrcRmtCpgcNumBursts;
+ /* DIMM SPD SMBus Addresses */
+ uint8_t SpdBaseAddress_0_0;
+ uint8_t SpdBaseAddress_0_1;
+ uint8_t SpdBaseAddress_1_0;
+ uint8_t SpdBaseAddress_1_1;
+
+#define UPD_ENABLE 1
+#define UPD_DISABLE 0
+ uint8_t EnableLan;
+ uint8_t EnableSata2;
+ uint8_t EnableSata3;
+ uint8_t EnableIQAT;
+ uint8_t EnableUsb20;
+ uint8_t PrintDebugMessages;
+ uint8_t Fastboot;
+ uint8_t EccSupport;
+ uint8_t SpdWriteProtect;
+ /* Enable = Memory Down, Disable = DIMM */
+ uint8_t MemoryDown;
+ /* Enable the Rank Margin Tool, needs PrintDebugMessages */
+ uint8_t MrcRmtSupport;
+
+#define BIFURCATION_4_4_4_4 0
+#define BIFURCATION_4_4_8 1
+#define BIFURCATION_8_4_4 2
+#define BIFURCATION_8_8 3
+#define BIFURCATION_16 4
+ uint8_t Bifurcation;
+};
+
+#endif
diff --git a/src/northbridge/intel/fsp_rangeley/fsp/Kconfig b/src/northbridge/intel/fsp_rangeley/fsp/Kconfig
new file mode 100644
index 0000000..82eceda
--- /dev/null
+++ b/src/northbridge/intel/fsp_rangeley/fsp/Kconfig
@@ -0,0 +1,49 @@
+##
+## 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+##
+
+config RANGELEY_FSP_SPECIFIC_OPTIONS
+ def_bool y
+ select PLATFORM_USES_FSP
+ select USE_GENERIC_FSP_CAR_INC
+ select FSP_USES_UPD
+ select ENABLE_MRC_CACHE #rangeley FSP always needs MRC data
+
+config FSP_FILE
+ string
+ default "../intel/fsp/rangeley/FvFsp.bin"
+ help
+ The path and filename of the Intel FSP binary for this platform.
+
+config FSP_LOC
+ hex
+ 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 Intel's BCT (tool).
+
+ The Rangeley FSP is built with a preferred base address of 0xFFF80000
+
+config DCACHE_RAM_BASE
+ hex
+ default 0xfef00000
+
+config DCACHE_RAM_SIZE
+ hex
+ default 0x4000
diff --git a/src/northbridge/intel/fsp_rangeley/fsp/Makefile.inc b/src/northbridge/intel/fsp_rangeley/fsp/Makefile.inc
new file mode 100644
index 0000000..05620ae
--- /dev/null
+++ b/src/northbridge/intel/fsp_rangeley/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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+#
+
+ramstage-y += chipset_fsp_util.c
+romstage-y += chipset_fsp_util.c
diff --git a/src/northbridge/intel/fsp_rangeley/fsp/chipset_fsp_util.c b/src/northbridge/intel/fsp_rangeley/fsp/chipset_fsp_util.c
new file mode 100644
index 0000000..bd196a5
--- /dev/null
+++ b/src/northbridge/intel/fsp_rangeley/fsp/chipset_fsp_util.c
@@ -0,0 +1,177 @@
+/*
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <types.h>
+#include <string.h>
+#include <cpu/x86/stack.h>
+#include <console/console.h>
+#include <bootstate.h>
+#include <cbmem.h>
+#include <device/device.h>
+#include <southbridge/intel/fsp_rangeley/pci_devs.h>
+#include <drivers/intel/fsp/fsp_util.h>
+#include <fspvpd.h>
+#include <fspbootmode.h>
+#include <reset.h>
+#include "../chip.h"
+
+#ifdef __PRE_RAM__
+#include <southbridge/intel/fsp_rangeley/romstage.h>
+#endif
+
+#ifdef __PRE_RAM__
+
+/* Copy the default UPD region and settings to a buffer for modification */
+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));
+}
+
+typedef struct northbridge_intel_fsp_rangeley_config config_t;
+
+/**
+ * Update the UPD data based on values from devicetree.cb
+ *
+ * @param UpdData Pointer to the UPD Data structure
+ */
+static void ConfigureDefaultUpdData(UPD_DATA_REGION *UpdData)
+{
+ ROMSTAGE_CONST struct device *dev;
+ ROMSTAGE_CONST config_t *config;
+ printk(BIOS_DEBUG, "Configure Default UPD Data\n");
+
+ dev = dev_find_slot(0, SOC_DEV_FUNC);
+ config = dev->chip_info;
+
+ /* Set SPD addresses */
+ if(config->SpdBaseAddress_0_0) {
+ UpdData->PcdSpdBaseAddress_0_0 = config->SpdBaseAddress_0_0;
+ }
+ if(config->SpdBaseAddress_0_1) {
+ UpdData->PcdSpdBaseAddress_0_1 = config->SpdBaseAddress_0_1;
+ }
+ if(config->SpdBaseAddress_1_0) {
+ UpdData->PcdSpdBaseAddress_1_0 = config->SpdBaseAddress_1_0;
+ }
+ if(config->SpdBaseAddress_1_1) {
+ UpdData->PcdSpdBaseAddress_1_1 = config->SpdBaseAddress_1_1;
+ }
+ if(config->EccSupport) {
+ UpdData->PcdEccSupport = config->EccSupport;
+ }
+ if(config->PrintDebugMessages) {
+ UpdData->PcdPrintDebugMessages = config->PrintDebugMessages;
+ }
+ if(config->Bifurcation) {
+ UpdData->PcdBifurcation = config->Bifurcation;
+ }
+ if(config->MemoryDown) {
+ UpdData->PcdMemoryDown = config->MemoryDown;
+ }
+
+ UpdData->PcdMrcInitTsegSize = CONFIG_SMM_TSEG_SIZE >> 20;
+
+ if(config->MrcRmtCpgcExpLoopCntValue) {
+ UpdData->PcdMrcRmtCpgcExpLoopCntValue =
+ config->MrcRmtCpgcExpLoopCntValue;
+ }
+ if(config->MrcRmtCpgcNumBursts) {
+ UpdData->PcdMrcRmtCpgcNumBursts = config->MrcRmtCpgcNumBursts;
+ }
+#if IS_ENABLED(CONFIG_ENABLE_FSP_FAST_BOOT)
+ UpdData->PcdFastboot = UPD_ENABLE;
+#endif
+ /*
+ * Loop through all the SOC devices in the devicetree
+ * enabling and disabling them as requested.
+ */
+ for (; dev; dev = dev->sibling) {
+
+ if (dev->path.type != DEVICE_PATH_PCI)
+ continue;
+
+ switch (dev->path.pci.devfn) {
+ case GBE1_DEV_FUNC:
+ case GBE2_DEV_FUNC:
+ case GBE3_DEV_FUNC:
+ case GBE4_DEV_FUNC:
+ UpdData->PcdEnableLan |= dev->enabled;
+ printk(BIOS_DEBUG, "PcdEnableLan %d\n",
+ UpdData->PcdEnableLan);
+ break;
+ case SATA2_DEV_FUNC:
+ UpdData->PcdEnableSata2 = dev->enabled;
+ printk(BIOS_DEBUG, "PcdEnableSata2 %d\n",
+ UpdData->PcdEnableSata2);
+ break;
+ case SATA3_DEV_FUNC:
+ UpdData->PcdEnableSata3 = dev->enabled;
+ printk(BIOS_DEBUG, "PcdEnableSata3 %d\n",
+ UpdData->PcdEnableSata3);
+ break;
+ case IQAT_DEV_FUNC:
+ UpdData->PcdEnableIQAT |= dev->enabled;
+ printk(BIOS_DEBUG, "PcdEnableIQAT %d\n",
+ UpdData->PcdEnableIQAT);
+ break;
+ case USB2_DEV_FUNC:
+ UpdData->PcdEnableUsb20 = dev->enabled;
+ printk(BIOS_DEBUG, "PcdEnableUsb20 %d\n",
+ UpdData->PcdEnableUsb20);
+ break;
+ }
+ }
+}
+
+/* Set up the Rangeley specific structures for the call into the FSP */
+void chipset_fsp_early_init(FSP_INIT_PARAMS *pFspInitParams,
+ FSP_INFO_HEADER *fsp_ptr)
+{
+ FSP_INIT_RT_BUFFER *pFspRtBuffer = pFspInitParams->RtBufferPtr;
+
+ /* Initialize the UPD Data */
+ GetUpdDefaultFromFsp (fsp_ptr, pFspRtBuffer->Common.UpdDataRgnPtr);
+ ConfigureDefaultUpdData(pFspRtBuffer->Common.UpdDataRgnPtr);
+ pFspInitParams->NvsBufferPtr = NULL;
+ pFspRtBuffer->Common.BootMode = BOOT_WITH_FULL_CONFIGURATION;
+
+ /* Find the fastboot cache that was saved in the ROM */
+ pFspInitParams->NvsBufferPtr = find_and_set_fastboot_cache();
+
+ return;
+}
+
+/* The FSP returns here after the fsp_early_init call */
+void ChipsetFspReturnPoint(EFI_STATUS Status,
+ VOID *HobListPtr)
+{
+ if (Status == 0xFFFFFFFF) {
+ soft_reset();
+ }
+ romstage_main_continue(Status, HobListPtr);
+}
+
+#endif /* __PRE_RAM__ */
diff --git a/src/northbridge/intel/fsp_rangeley/fsp/chipset_fsp_util.h b/src/northbridge/intel/fsp_rangeley/fsp/chipset_fsp_util.h
new file mode 100644
index 0000000..3057865
--- /dev/null
+++ b/src/northbridge/intel/fsp_rangeley/fsp/chipset_fsp_util.h
@@ -0,0 +1,52 @@
+/*
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#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>
+#include <fspvpd.h>
+
+#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.
+ * For the Rangeley FSP, the Image Id is "AVN-FSP0".
+ */
+#define FSP_IMAGE_ID_DWORD0 0x2d4e5641 /* 'AVN-' */
+#define FSP_IMAGE_ID_DWORD1 0x30505346 /* 'FSP0' */
+
+#endif /* CHIPSET_FSP_UTIL_H */
diff --git a/src/northbridge/intel/fsp_rangeley/northbridge.c b/src/northbridge/intel/fsp_rangeley/northbridge.c
new file mode 100644
index 0000000..98c0b9c
--- /dev/null
+++ b/src/northbridge/intel/fsp_rangeley/northbridge.c
@@ -0,0 +1,302 @@
+/*
+ * 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-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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <console/console.h>
+#include <arch/acpi.h>
+#include <arch/io.h>
+#include <stdint.h>
+#include <delay.h>
+#include <cpu/intel/fsp_model_406dx/model_406dx.h>
+#include <cpu/x86/msr.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <stdlib.h>
+#include <string.h>
+#include <cpu/cpu.h>
+#include <cbmem.h>
+#include "chip.h"
+#include "northbridge.h"
+#include <drivers/intel/fsp/fsp_util.h>
+#include <cpu/x86/lapic.h>
+
+static int bridge_revision_id = -1;
+
+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 = sideband_read(B_UNIT, BECREG);
+
+ if (!(pciexbar_reg & (1 << 0)))
+ return 0;
+
+ *base = pciexbar_reg & ((1 << 31) | (1 << 30) | (1 << 29) |
+ (1 << 28));
+ *len = 256 * 1024 * 1024; /* 256MB ECAM range */
+ return 1;
+
+}
+
+static int add_fixed_resources(struct device *dev, int index)
+{
+ struct resource *resource;
+ u32 pcie_config_base, pcie_config_size;
+
+
+ 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;
+ }
+
+ resource = new_resource(dev, index++); /* Local APIC */
+ resource->base = LAPIC_DEFAULT_BASE;
+ resource->size = 0x00001000;
+ resource->flags = IORESOURCE_MEM | IORESOURCE_RESERVE |
+ IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_ASSIGNED;
+
+ mmio_resource(dev, index++, legacy_hole_base_k, legacy_hole_size_k);
+
+ return index;
+}
+
+static void finalize_dev (device_t dev)
+{
+ /*
+ * Notify FSP for PostPciEnumeration.
+ * Northbridge APIC init should be early and late enough...
+ */
+ printk(BIOS_DEBUG, "FspNotify(EnumInitPhaseAfterPciEnumeration)\n");
+ FspNotify(EnumInitPhaseAfterPciEnumeration);
+ printk(BIOS_DEBUG, "Returned from FspNotify(EnumInitPhaseAfterPciEnumeration)\n");
+}
+
+static void mc_add_dram_resources(device_t dev)
+{
+ u32 tomlow, bmbound, bsmmrrl, bsmmrrh;
+ u64 bmbound_hi;
+ int index = 0;
+
+ /*
+ * These are the host memory ranges :
+ * - 0 -> SMM (SMMRRL) : cacheable
+ * - SMM -> LOW TOM (BMBOUND) : cacheable WP
+ * - 4GB -> HIGH TOM (BMBOUND_HI): cacheable
+ *
+ */
+
+ tomlow = bmbound = sideband_read(B_UNIT, BMBOUND);
+ printk(BIOS_SPEW, "Top of Low Used DRAM (BMBOUND): 0x%08x\n", bmbound);
+
+ bmbound_hi = (u64)(sideband_read(B_UNIT, BMBOUND_HI)) << 4;
+ printk(BIOS_SPEW, "Top of Upper Used DRAM (BMBOUND_HI): 0x%llx\n", bmbound_hi);
+
+ bsmmrrl = sideband_read(B_UNIT, BSMMRRL) << 20;
+ bsmmrrh = ((sideband_read(B_UNIT, BSMMRRH) + 1) << 20) - 1;
+ if (bsmmrrl) {
+ tomlow = bsmmrrl;
+ printk(BIOS_DEBUG, "SMM memory location: 0x%x SMM memory size: 0x%x\n", bsmmrrl, (bsmmrrh - bsmmrrl + 1));
+ printk(BIOS_DEBUG, "Subtracting %dM for SMM\n", (bmbound - bsmmrrl) >> 20);
+ }
+ tomlow -= FSP_RESERVE_MEMORY_SIZE;
+ printk(BIOS_SPEW, "Available memory below 4GB: 0x%08x (%dM)\n", tomlow, tomlow >> 20);
+
+ /* Report the memory regions. */
+ ram_resource(dev, index++, 0, legacy_hole_base_k);
+ ram_resource(dev, index++, legacy_hole_base_k + legacy_hole_size_k,
+ ((tomlow >> 10) - (legacy_hole_base_k + legacy_hole_size_k)));
+
+ mmio_resource(dev, index++, tomlow >> 10, (bmbound - bsmmrrl) >> 10);
+
+ if (bmbound_hi > 0x100000000) {
+ ram_resource(dev, index++, 0x100000000 >> 10, (bmbound_hi - 0x100000000) >> 10 );
+ printk(BIOS_INFO, "Available memory above 4GB: %lluM\n", (bmbound_hi - 0x100000000) >> 20);
+ }
+
+ index = add_fixed_resources(dev, index);
+}
+
+static void mc_read_resources(device_t dev)
+{
+ /* Call the normal read_resources */
+ pci_dev_read_resources(dev);
+
+ /* Calculate and add DRAM resources. */
+ mc_add_dram_resources(dev);
+}
+
+static void pci_domain_set_resources(device_t dev)
+{
+ /*
+ * Assign memory resources for PCI devices
+ */
+ mc_add_dram_resources(dev);
+
+ assign_resources(dev->link_list);
+}
+
+static void mc_set_resources(device_t dev)
+{
+ /* 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)
+{
+}
+
+static void northbridge_enable(device_t dev)
+{
+}
+
+static struct pci_operations intel_pci_ops = {
+ .set_subsystem = intel_set_subsystem,
+};
+
+static struct device_operations pci_domain_ops = {
+ .read_resources = pci_domain_read_resources,
+ .set_resources = pci_domain_set_resources,
+ .enable_resources = NULL,
+ .init = NULL,
+ .final = finalize_dev,
+ .scan_bus = pci_domain_scan_bus,
+ .ops_pci_bus = pci_bus_default_ops,
+};
+
+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,
+ .enable = northbridge_enable,
+ .scan_bus = 0,
+ .ops_pci = &intel_pci_ops,
+};
+
+/*
+ * The following entries are taken from Intel document number 510524, rev 1.6:
+ * Rangeley SoC External Design Specification (EDS)
+ * Section 10.3 PCI Configuration Space
+ * Table 10-6. PCI Devices and Functions
+ *
+ * These are the Device ID values for the item at bus 0, device 0, function 0.
+ */
+static const unsigned short pci_device_ids[] = {
+ 0x1f00, 0x1f01, 0x1f02, 0x1f03,
+ 0x1f04, 0x1f05, 0x1f06, 0x1f07,
+ 0x1f08, 0x1f09, 0x1f0a, 0x1f0b,
+ 0x1f0c, 0x1f0d, 0x1f0e, 0x1f0f,
+ 0, /* -- END OF LIST -- */
+};
+
+static const struct pci_driver mc_driver __pci_driver = {
+ .ops = &mc_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .devices = pci_device_ids,
+};
+
+static void cpu_bus_init(device_t dev)
+{
+ initialize_cpus(dev->link_list);
+}
+
+
+static void cpu_bus_noop(device_t dev)
+{
+}
+
+static struct device_operations cpu_bus_ops = {
+ .read_resources = cpu_bus_noop,
+ .set_resources = cpu_bus_noop,
+ .enable_resources = cpu_bus_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;
+ }
+}
+
+static void finalize_chip(void *chip_info)
+{
+ /* Notify FSP for ReadyToBoot */
+ printk(BIOS_DEBUG, "FspNotify(EnumInitPhaseReadyToBoot)\n");
+ print_fsp_info();
+ FspNotify(EnumInitPhaseReadyToBoot);
+ printk(BIOS_DEBUG, "Returned from FspNotify(EnumInitPhaseReadyToBoot)\n");
+}
+
+struct chip_operations northbridge_intel_fsp_rangeley_ops = {
+ CHIP_NAME("Intel Rangeley Northbridge")
+ .enable_dev = enable_dev,
+ .final = finalize_chip,
+};
diff --git a/src/northbridge/intel/fsp_rangeley/northbridge.h b/src/northbridge/intel/fsp_rangeley/northbridge.h
new file mode 100644
index 0000000..855a056
--- /dev/null
+++ b/src/northbridge/intel/fsp_rangeley/northbridge.h
@@ -0,0 +1,78 @@
+/*
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __NORTHBRIDGE_INTEL_RANGELEY_NORTHBRIDGE_H__
+#define __NORTHBRIDGE_INTEL_RANGELEY_NORTHBRIDGE_H__ 1
+
+#define DEFAULT_ECBASE CONFIG_MMCONF_BASE_ADDRESS
+
+/* Everything below this line is ignored in the DSDT */
+#ifndef __ACPI__
+
+/* Device 0:0.0 PCI configuration space (Host Bridge) */
+
+/* SideBand B-UNIT */
+#define B_UNIT 3
+ #define BNOCACHE 0x23
+ #define BNOCACHECTL 0x24
+ #define BMBOUND 0x25
+ #define BMBOUND_HI 0x26
+ #define BECREG 0x27
+ #define BMISC 0x28
+ #define BSMMRRL 0x2E
+ #define BSMMRRH 0x2F
+ #define BIMR0L 0x80
+ #define BIMR0H 0x81
+ #define BIMR0RAC 0x82
+ #define BIMR0WAC 0x83
+
+/* SideBand C-UNIT */
+#define C_UNIT 8
+
+/* SideBand D-UNIT */
+#define D_UNIT 1
+
+/* SideBand P-UNIT */
+#define P_UNIT 4
+
+#ifndef __ASSEMBLER__
+static inline void barrier(void) { asm("" ::: "memory"); }
+
+#define PCI_DEVICE_ID_RG_MIN 0x1F00
+#define PCI_DEVICE_ID_RG_MAX 0x1F0F
+#define SKPAD 0xFC
+
+int bridge_silicon_revision(void);
+void rangeley_late_initialization(void);
+u32 sideband_read(int port, int reg);
+void sideband_write(int port, int reg, long data);
+
+/* 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 /* #ifndef __ASSEMBLER__ */
+#endif /* #ifndef __ACPI__ */
+#endif /* #ifndef __NORTHBRIDGE_INTEL_RANGELEY_NORTHBRIDGE_H__ */
diff --git a/src/northbridge/intel/fsp_rangeley/port_access.c b/src/northbridge/intel/fsp_rangeley/port_access.c
new file mode 100644
index 0000000..508630e
--- /dev/null
+++ b/src/northbridge/intel/fsp_rangeley/port_access.c
@@ -0,0 +1,72 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2009-2010 iWave Systems
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __PRE_RAM__
+#define __PRE_RAM__ // Use simple device model for this file even in ramstage
+#endif
+
+#include <stdint.h>
+#include <arch/io.h>
+#include <device/pci_def.h>
+#include <device/pnp_def.h>
+#include <cpu/x86/lapic.h>
+#include "northbridge.h"
+
+/*
+ * Restricted Access Regions:
+ *
+ * MCR - Message Control Register
+ * 31 24 16 8 4 0
+ * ----------------------------------------------------------------------------
+ * | | | Target | Write | |
+ * | Opcode | Port | register | byte | Reserved |
+ * | | | Address | Enables | |
+ * ----------------------------------------------------------------------------
+ *
+ * MDR - Message Data Register
+ * 31 0
+ * ----------------------------------------------------------------------------
+ * | |
+ * | Data |
+ * | |
+ * ----------------------------------------------------------------------------
+ */
+
+#define MSG_OPCODE_READ 0x10 << 24
+#define MSG_OPCODE_WRITE 0x11 << 24
+
+#define MCR 0xD0
+#define MDR 0xD4
+#define MCRE 0xD8
+
+u32 sideband_read(int port, int reg)
+{
+ pci_write_config32(PCI_DEV(0, 0, 0), MCR,
+ (MSG_OPCODE_READ | (port << 16) | (reg << 8)));
+ return pci_read_config32(PCI_DEV(0, 0, 0), MDR);
+}
+
+void sideband_write(int port, int reg, long data)
+{
+ pci_write_config32(PCI_DEV(0, 0, 0), MDR, data);
+ pci_write_config32(PCI_DEV(0, 0, 0), MCR,
+ (MSG_OPCODE_WRITE | (port << 16) | (reg << 8) | (0xF << 4)));
+ pci_read_config32(PCI_DEV(0, 0, 0), MDR);
+}
diff --git a/src/northbridge/intel/fsp_rangeley/raminit.c b/src/northbridge/intel/fsp_rangeley/raminit.c
new file mode 100644
index 0000000..3513c0f
--- /dev/null
+++ b/src/northbridge/intel/fsp_rangeley/raminit.c
@@ -0,0 +1,44 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2011 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <console/console.h>
+#include <string.h>
+#include <arch/io.h>
+#include <cbmem.h>
+#include <device/pci_def.h>
+#include "northbridge.h"
+#include <drivers/intel/fsp/fsp_util.h>
+
+unsigned long get_top_of_ram(void)
+{
+ /*
+ * Calculate the top of usable (low) DRAM.
+ * The FSP's reserved memory sits just below the SMM region,
+ * allowing calculation of the top of usable memory.
+ */
+ u32 tom = sideband_read(B_UNIT, BMBOUND);
+ u32 bsmmrrl = sideband_read(B_UNIT, BSMMRRL) << 20;
+ if (bsmmrrl) {
+ tom = bsmmrrl;
+ }
+ tom -= FSP_RESERVE_MEMORY_SIZE;
+
+ return (unsigned long) tom;
+}
diff --git a/src/northbridge/intel/fsp_rangeley/udelay.c b/src/northbridge/intel/fsp_rangeley/udelay.c
new file mode 100644
index 0000000..bdd9f78
--- /dev/null
+++ b/src/northbridge/intel/fsp_rangeley/udelay.c
@@ -0,0 +1,68 @@
+/*
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <delay.h>
+#include <stdint.h>
+#include <cpu/x86/tsc.h>
+#include <cpu/x86/msr.h>
+
+/**
+ * Intel Rangeley CPUs always run the TSC at BCLK=100MHz
+ */
+
+/* Simple 32- to 64-bit multiplication. Uses 16-bit words to avoid overflow.
+ * This code is used to prevent use of libgcc's umoddi3.
+ */
+static inline void multiply_to_tsc(tsc_t *const tsc, const u32 a, const u32 b)
+{
+ tsc->lo = (a & 0xffff) * (b & 0xffff);
+ tsc->hi = ((tsc->lo >> 16)
+ + ((a & 0xffff) * (b >> 16))
+ + ((b & 0xffff) * (a >> 16)));
+ tsc->lo = ((tsc->hi & 0xffff) << 16) | (tsc->lo & 0xffff);
+ tsc->hi = ((a >> 16) * (b >> 16)) + (tsc->hi >> 16);
+}
+
+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;
+ 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)));
+}
Martin Roth (gaumless(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/6368
-gerrit
commit bd1ce2f55e8c917cfa89f1f7f3e4ff2e35c60e91
Author: Martin Roth <gaumless(a)gmail.com>
Date: Wed May 21 13:40:21 2014 -0600
cpu/intel: Add fsp version of model 406dx (Rangeley / Atom C2000)
This adds the CPU initialization pieces for Intel's Atom C2000 processor
(Formerly Rangeley).
Change-Id: I77d69f42c959bbc294784f044b7b0dcc2e30f30c
Signed-off-by: Martin Roth <gaumless(a)gmail.com>
---
src/cpu/intel/Kconfig | 1 +
src/cpu/intel/Makefile.inc | 1 +
src/cpu/intel/fsp_model_406dx/Kconfig | 75 ++++++
src/cpu/intel/fsp_model_406dx/Makefile.inc | 31 +++
src/cpu/intel/fsp_model_406dx/acpi.c | 320 +++++++++++++++++++++++
src/cpu/intel/fsp_model_406dx/acpi/cpu.asl | 102 ++++++++
src/cpu/intel/fsp_model_406dx/bootblock.c | 95 +++++++
src/cpu/intel/fsp_model_406dx/chip.h | 33 +++
src/cpu/intel/fsp_model_406dx/microcode_blob.c | 29 ++
src/cpu/intel/fsp_model_406dx/model_406dx.h | 113 ++++++++
src/cpu/intel/fsp_model_406dx/model_406dx_init.c | 217 +++++++++++++++
11 files changed, 1017 insertions(+)
diff --git a/src/cpu/intel/Kconfig b/src/cpu/intel/Kconfig
index fb4b023..aa3dd5b 100644
--- a/src/cpu/intel/Kconfig
+++ b/src/cpu/intel/Kconfig
@@ -11,6 +11,7 @@ source src/cpu/intel/model_1067x/Kconfig
source src/cpu/intel/model_106cx/Kconfig
source src/cpu/intel/model_206ax/Kconfig
source src/cpu/intel/fsp_model_206ax/Kconfig
+source src/cpu/intel/fsp_model_406dx/Kconfig
source src/cpu/intel/model_2065x/Kconfig
source src/cpu/intel/model_f0x/Kconfig
source src/cpu/intel/model_f1x/Kconfig
diff --git a/src/cpu/intel/Makefile.inc b/src/cpu/intel/Makefile.inc
index 0392f69..2648c79 100644
--- a/src/cpu/intel/Makefile.inc
+++ b/src/cpu/intel/Makefile.inc
@@ -22,6 +22,7 @@ subdirs-$(CONFIG_NORTHBRIDGE_INTEL_IVYBRIDGE) += model_206ax
subdirs-$(CONFIG_NORTHBRIDGE_INTEL_HASWELL) += haswell
subdirs-$(CONFIG_NORTHBRIDGE_INTEL_FSP_SANDYBRIDGE) += fsp_model_206ax
subdirs-$(CONFIG_NORTHBRIDGE_INTEL_FSP_IVYBRIDGE) += fsp_model_206ax
+subdirs-$(CONFIG_NORTHBRIDGE_INTEL_FSP_RANGELEY) += fsp_model_406dx
subdirs-$(CONFIG_CPU_INTEL_SLOT_2) += slot_2
subdirs-$(CONFIG_CPU_INTEL_SLOT_1) += slot_1
subdirs-$(CONFIG_CPU_INTEL_SOCKET_LGA771) += socket_LGA771
diff --git a/src/cpu/intel/fsp_model_406dx/Kconfig b/src/cpu/intel/fsp_model_406dx/Kconfig
new file mode 100644
index 0000000..11a92a0
--- /dev/null
+++ b/src/cpu/intel/fsp_model_406dx/Kconfig
@@ -0,0 +1,75 @@
+##
+## 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+##
+
+config CPU_INTEL_FSP_MODEL_406DX
+ bool
+
+if CPU_INTEL_FSP_MODEL_406DX
+
+config CPU_SPECIFIC_OPTIONS
+ def_bool y
+ select PLATFORM_USES_FSP
+ select ARCH_BOOTBLOCK_X86_32
+ select ARCH_ROMSTAGE_X86_32
+ select ARCH_RAMSTAGE_X86_32
+ select SMP
+ select SSE2
+ select UDELAY_LAPIC
+ select SUPPORT_CPU_UCODE_IN_CBFS if HAVE_FSP_BIN
+ select PARALLEL_CPU_INIT
+ select TSC_SYNC_MFENCE
+ select LAPIC_MONOTONIC_TIMER
+ select BROKEN_CAR_MIGRATE
+
+choice
+ prompt "Rangeley CPU Stepping"
+ default FSP_MODEL_406DX_B0
+
+config FSP_MODEL_406DX_A1
+ bool "A1"
+
+config FSP_MODEL_406DX_B0
+ bool "B0"
+
+endchoice
+
+config BOOTBLOCK_CPU_INIT
+ string
+ default "cpu/intel/fsp_model_406dx/bootblock.c"
+
+config ENABLE_VMX
+ bool "Enable VMX for virtualization"
+ default n
+
+config CPU_MICROCODE_CBFS_LOC
+ hex
+ depends on SUPPORT_CPU_UCODE_IN_CBFS
+ default 0xfff60040
+
+config CPU_MICROCODE_CBFS_LEN
+ hex
+ depends on SUPPORT_CPU_UCODE_IN_CBFS
+ default 0x14400 if FSP_MODEL_406DX_A1
+ default 0x14800 if FSP_MODEL_406DX_B0
+
+config MICROCODE_INCLUDE_PATH
+ string "Location of the intel microcode patches"
+ default "../intel/cpu/rangeley/microcode"
+
+endif #CPU_INTEL_FSP_MODEL_406DX
diff --git a/src/cpu/intel/fsp_model_406dx/Makefile.inc b/src/cpu/intel/fsp_model_406dx/Makefile.inc
new file mode 100644
index 0000000..118efee
--- /dev/null
+++ b/src/cpu/intel/fsp_model_406dx/Makefile.inc
@@ -0,0 +1,31 @@
+#
+# This file is part of the coreboot project.
+#
+# Copyrignt (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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+#
+
+ramstage-y += model_406dx_init.c
+subdirs-y += ../../x86/name
+
+ramstage-$(CONFIG_GENERATE_ACPI_TABLES) += acpi.c
+
+cpu_microcode-$(CONFIG_CPU_MICROCODE_CBFS_GENERATE) += microcode_blob.c
+
+ifneq ($(CONFIG_MICROCODE_INCLUDE_PATH),)
+ifneq ($(wildcard $(shell readlink -f "$(top)/$(CONFIG_MICROCODE_INCLUDE_PATH)")),)
+CPPFLAGS_common += -I$(CONFIG_MICROCODE_INCLUDE_PATH)
+endif
+endif
diff --git a/src/cpu/intel/fsp_model_406dx/acpi.c b/src/cpu/intel/fsp_model_406dx/acpi.c
new file mode 100644
index 0000000..07a9dbe
--- /dev/null
+++ b/src/cpu/intel/fsp_model_406dx/acpi.c
@@ -0,0 +1,320 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2009 coresystems GmbH
+ * Copyright (C) 2011 The Chromium OS 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., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#include <types.h>
+#include <console/console.h>
+#include <arch/acpi.h>
+#include <arch/acpigen.h>
+#include <arch/cpu.h>
+#include <cpu/x86/msr.h>
+#include <cpu/intel/speedstep.h>
+#include <cpu/intel/turbo.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include "model_406dx.h"
+#include "chip.h"
+
+static int get_cores_per_package(void)
+{
+ struct cpuinfo_x86 c;
+ struct cpuid_result result;
+ int cores = 1;
+
+ get_fms(&c, cpuid_eax(1));
+ if (c.x86 != 6)
+ return 1;
+
+ result = cpuid_ext(0xb, 1);
+ cores = result.ebx & 0xff;
+
+ return cores;
+}
+
+static int generate_C_state_entries(void)
+{
+ struct cpu_info *info;
+ struct cpu_driver *cpu;
+ int len, lenif;
+ device_t lapic;
+ struct cpu_intel_model_406dx_config *conf = NULL;
+
+ /* Find the SpeedStep CPU in the device tree using magic APIC ID */
+ lapic = dev_find_lapic(SPEEDSTEP_APIC_MAGIC);
+ if (!lapic)
+ return 0;
+ conf = lapic->chip_info;
+ if (!conf)
+ return 0;
+
+ /* Find CPU map of supported C-states */
+ info = cpu_info();
+ if (!info)
+ return 0;
+ cpu = find_cpu_driver(info->cpu);
+ if (!cpu || !cpu->cstates)
+ return 0;
+
+ len = acpigen_emit_byte(0x14); /* MethodOp */
+ len += acpigen_write_len_f(); /* PkgLength */
+ len += acpigen_emit_namestring("_CST");
+ len += acpigen_emit_byte(0x00); /* No Arguments */
+
+ /* If running on AC power */
+ len += acpigen_emit_byte(0xa0); /* IfOp */
+ lenif = acpigen_write_len_f(); /* PkgLength */
+ lenif += acpigen_emit_namestring("PWRS");
+ lenif += acpigen_emit_byte(0xa4); /* ReturnOp */
+ acpigen_patch_len(lenif - 1);
+ len += lenif;
+
+ /* Else on battery power */
+ len += acpigen_emit_byte(0xa4); /* ReturnOp */
+ acpigen_patch_len(len - 1);
+ return len;
+}
+
+static acpi_tstate_t tss_table_fine[] = {
+ { 100, 1000, 0, 0x00, 0 },
+ { 94, 940, 0, 0x1f, 0 },
+ { 88, 880, 0, 0x1e, 0 },
+ { 82, 820, 0, 0x1d, 0 },
+ { 75, 760, 0, 0x1c, 0 },
+ { 69, 700, 0, 0x1b, 0 },
+ { 63, 640, 0, 0x1a, 0 },
+ { 57, 580, 0, 0x19, 0 },
+ { 50, 520, 0, 0x18, 0 },
+ { 44, 460, 0, 0x17, 0 },
+ { 38, 400, 0, 0x16, 0 },
+ { 32, 340, 0, 0x15, 0 },
+ { 25, 280, 0, 0x14, 0 },
+ { 19, 220, 0, 0x13, 0 },
+ { 13, 160, 0, 0x12, 0 },
+};
+
+static acpi_tstate_t tss_table_coarse[] = {
+ { 100, 1000, 0, 0x00, 0 },
+ { 88, 875, 0, 0x1f, 0 },
+ { 75, 750, 0, 0x1e, 0 },
+ { 63, 625, 0, 0x1d, 0 },
+ { 50, 500, 0, 0x1c, 0 },
+ { 38, 375, 0, 0x1b, 0 },
+ { 25, 250, 0, 0x1a, 0 },
+ { 13, 125, 0, 0x19, 0 },
+};
+
+static int generate_T_state_entries(int core, int cores_per_package)
+{
+ int len;
+
+ /* Indicate SW_ALL coordination for T-states */
+ len = acpigen_write_TSD_package(core, cores_per_package, SW_ALL);
+
+ /* Indicate FFixedHW so OS will use MSR */
+ len += acpigen_write_empty_PTC();
+
+ /* Set a T-state limit that can be modified in NVS */
+ len += acpigen_write_TPC("\\TLVL");
+
+ /*
+ * CPUID.(EAX=6):EAX[5] indicates support
+ * for extended throttle levels.
+ */
+ if (cpuid_eax(6) & (1 << 5))
+ len += acpigen_write_TSS_package(
+ ARRAY_SIZE(tss_table_fine), tss_table_fine);
+ else
+ len += acpigen_write_TSS_package(
+ ARRAY_SIZE(tss_table_coarse), tss_table_coarse);
+
+ return len;
+}
+
+static int calculate_power(int tdp, int p1_ratio, int ratio)
+{
+ u32 m;
+ u32 power;
+
+ /*
+ * M = ((1.1 - ((p1_ratio - ratio) * 0.00625)) / 1.1) ^ 2
+ *
+ * Power = (ratio / p1_ratio) * m * tdp
+ */
+
+ m = (110000 - ((p1_ratio - ratio) * 625)) / 11;
+ m = (m * m) / 1000;
+
+ power = ((ratio * 100000 / p1_ratio) / 100);
+ power *= (m / 100) * (tdp / 1000);
+ power /= 1000;
+
+ return (int)power;
+}
+
+static int generate_P_state_entries(int core, int cores_per_package)
+{
+ int len, len_pss;
+ int ratio_min, ratio_max, ratio_turbo, ratio_step;
+ int coord_type, power_max, num_entries;
+ int ratio, power, clock, clock_max;
+ msr_t msr;
+
+ /* Rangeley uses hardware only control */
+ coord_type = HW_ALL;
+
+ /* Get bus ratio limits and calculate clock speeds */
+ msr = rdmsr(MSR_PLATFORM_INFO);
+ ratio_min = (msr.hi >> (40-32)) & 0xff; /* Max Efficiency Ratio */
+
+ /* Determine if this CPU has configurable TDP */
+ if (cpu_config_tdp_levels()) {
+ /* Set max ratio to nominal TDP ratio */
+ msr = rdmsr(MSR_CONFIG_TDP_NOMINAL);
+ ratio_max = msr.lo & 0xff;
+ } else {
+ /* Max Non-Turbo Ratio */
+ ratio_max = (msr.lo >> 8) & 0xff;
+ }
+ clock_max = ratio_max * RANGELEY_BCLK;
+
+ /* Calculate CPU TDP in mW */
+ msr = rdmsr(MSR_PKG_POWER_SKU_UNIT);
+ power_max = 2 << ((msr.lo & 0xf) - 1);
+
+
+ /* Write _PCT indicating use of FFixedHW */
+ len = acpigen_write_empty_PCT();
+
+ /* Write _PPC with no limit on supported P-state */
+ len += acpigen_write_PPC_NVS();
+
+ /* Write PSD indicating configured coordination type */
+ len += acpigen_write_PSD_package(core, cores_per_package, coord_type);
+
+ /* Add P-state entries in _PSS table */
+ len += acpigen_write_name("_PSS");
+
+ /* Determine ratio points */
+ ratio_step = PSS_RATIO_STEP;
+ num_entries = (ratio_max - ratio_min) / ratio_step;
+ while (num_entries > PSS_MAX_ENTRIES-1) {
+ ratio_step <<= 1;
+ num_entries >>= 1;
+ }
+
+ /* P[T] is Turbo state if enabled */
+ if (get_turbo_state() == TURBO_ENABLED) {
+ /* _PSS package count including Turbo */
+ len_pss = acpigen_write_package(num_entries + 2);
+
+ msr = rdmsr(MSR_TURBO_RATIO_LIMIT);
+ ratio_turbo = msr.lo & 0xff;
+
+ /* Add entry for Turbo ratio */
+ len_pss += acpigen_write_PSS_package(
+ clock_max + 1, /*MHz*/
+ power_max, /*mW*/
+ PSS_LATENCY_TRANSITION, /*lat1*/
+ PSS_LATENCY_BUSMASTER, /*lat2*/
+ ratio_turbo << 8, /*control*/
+ ratio_turbo << 8); /*status*/
+ } else {
+ /* _PSS package count without Turbo */
+ len_pss = acpigen_write_package(num_entries + 1);
+ }
+
+ /* First regular entry is max non-turbo ratio */
+ len_pss += acpigen_write_PSS_package(
+ clock_max, /*MHz*/
+ power_max, /*mW*/
+ PSS_LATENCY_TRANSITION, /*lat1*/
+ PSS_LATENCY_BUSMASTER, /*lat2*/
+ ratio_max << 8, /*control*/
+ ratio_max << 8); /*status*/
+
+ /* Generate the remaining entries */
+ for (ratio = ratio_min + ((num_entries - 1) * ratio_step);
+ ratio >= ratio_min; ratio -= ratio_step) {
+
+ /* Calculate power at this ratio */
+ power = calculate_power(power_max, ratio_max, ratio);
+ clock = ratio * RANGELEY_BCLK;
+
+ len_pss += acpigen_write_PSS_package(
+ clock, /*MHz*/
+ power, /*mW*/
+ PSS_LATENCY_TRANSITION, /*lat1*/
+ PSS_LATENCY_BUSMASTER, /*lat2*/
+ ratio << 8, /*control*/
+ ratio << 8); /*status*/
+ }
+
+ /* Fix package length */
+ len_pss--;
+ acpigen_patch_len(len_pss);
+
+ return len + len_pss;
+}
+
+void generate_cpu_entries(void)
+{
+ int len_pr;
+ int coreID, cpuID, pcontrol_blk = PMB0_BASE, plen = 6;
+ int totalcores = dev_count_cpu();
+ int cores_per_package = get_cores_per_package();
+ int numcpus = totalcores/cores_per_package;
+
+ printk(BIOS_DEBUG, "Found %d CPU(s) with %d core(s) each.\n",
+ numcpus, cores_per_package);
+
+ for (cpuID=1; cpuID <=numcpus; cpuID++) {
+ for (coreID=1; coreID<=cores_per_package; coreID++) {
+ if (coreID>1) {
+ pcontrol_blk = 0;
+ plen = 0;
+ }
+
+ /* Generate processor \_PR.CPUx */
+ len_pr = acpigen_write_processor(
+ (cpuID-1)*cores_per_package+coreID-1,
+ pcontrol_blk, plen);
+
+ /* Generate P-state tables */
+ len_pr += generate_P_state_entries(
+ cpuID-1, cores_per_package);
+
+ /* Generate C-state tables */
+ len_pr += generate_C_state_entries();
+
+ /* Generate T-state tables */
+ len_pr += generate_T_state_entries(
+ cpuID-1, cores_per_package);
+
+ len_pr--;
+ acpigen_patch_len(len_pr);
+ }
+ }
+}
+
+struct chip_operations cpu_intel_model_406dx_ops = {
+ CHIP_NAME("Intel Rangeley CPU")
+};
diff --git a/src/cpu/intel/fsp_model_406dx/acpi/cpu.asl b/src/cpu/intel/fsp_model_406dx/acpi/cpu.asl
new file mode 100644
index 0000000..558a9d3
--- /dev/null
+++ b/src/cpu/intel/fsp_model_406dx/acpi/cpu.asl
@@ -0,0 +1,102 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2011 The ChromiumOS 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., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+/* These devices are created at runtime */
+External (\_PR.CPU0, DeviceObj)
+External (\_PR.CPU1, DeviceObj)
+External (\_PR.CPU2, DeviceObj)
+External (\_PR.CPU3, DeviceObj)
+External (\_PR.CPU4, DeviceObj)
+External (\_PR.CPU5, DeviceObj)
+External (\_PR.CPU6, DeviceObj)
+External (\_PR.CPU7, DeviceObj)
+
+/* Notify OS to re-read CPU tables, assuming ^2 CPU count */
+Method (PNOT)
+{
+ If (LGreaterEqual (\PCNT, 2)) {
+ Notify (\_PR.CPU0, 0x81) // _CST
+ Notify (\_PR.CPU1, 0x81) // _CST
+ }
+ If (LGreaterEqual (\PCNT, 4)) {
+ Notify (\_PR.CPU2, 0x81) // _CST
+ Notify (\_PR.CPU3, 0x81) // _CST
+ }
+ If (LGreaterEqual (\PCNT, 8)) {
+ Notify (\_PR.CPU4, 0x81) // _CST
+ Notify (\_PR.CPU5, 0x81) // _CST
+ Notify (\_PR.CPU6, 0x81) // _CST
+ Notify (\_PR.CPU7, 0x81) // _CST
+ }
+}
+
+/* Notify OS to re-read CPU _PPC limit, assuming ^2 CPU count */
+Method (PPCN)
+{
+ If (LGreaterEqual (\PCNT, 2)) {
+ Notify (\_PR.CPU0, 0x80) // _PPC
+ Notify (\_PR.CPU1, 0x80) // _PPC
+ }
+ If (LGreaterEqual (\PCNT, 4)) {
+ Notify (\_PR.CPU2, 0x80) // _PPC
+ Notify (\_PR.CPU3, 0x80) // _PPC
+ }
+ If (LGreaterEqual (\PCNT, 8)) {
+ Notify (\_PR.CPU4, 0x80) // _PPC
+ Notify (\_PR.CPU5, 0x80) // _PPC
+ Notify (\_PR.CPU6, 0x80) // _PPC
+ Notify (\_PR.CPU7, 0x80) // _PPC
+ }
+}
+
+/* Notify OS to re-read Throttle Limit tables, assuming ^2 CPU count */
+Method (TNOT)
+{
+ If (LGreaterEqual (\PCNT, 2)) {
+ Notify (\_PR.CPU0, 0x82) // _TPC
+ Notify (\_PR.CPU1, 0x82) // _TPC
+ }
+ If (LGreaterEqual (\PCNT, 4)) {
+ Notify (\_PR.CPU2, 0x82) // _TPC
+ Notify (\_PR.CPU3, 0x82) // _TPC
+ }
+ If (LGreaterEqual (\PCNT, 8)) {
+ Notify (\_PR.CPU4, 0x82) // _TPC
+ Notify (\_PR.CPU5, 0x82) // _TPC
+ Notify (\_PR.CPU6, 0x82) // _TPC
+ Notify (\_PR.CPU7, 0x82) // _TPC
+ }
+}
+
+/* Return a package containing enabled processor entries */
+Method (PPKG)
+{
+ If (LGreaterEqual (\PCNT, 8)) {
+ Return (Package() {\_PR.CPU0, \_PR.CPU1, \_PR.CPU2, \_PR.CPU3,
+ \_PR.CPU4, \_PR.CPU5, \_PR.CPU6, \_PR.CPU7})
+ } ElseIf (LGreaterEqual (\PCNT, 4)) {
+ Return (Package() {\_PR.CPU0, \_PR.CPU1, \_PR.CPU2, \_PR.CPU3})
+ } ElseIf (LGreaterEqual (\PCNT, 2)) {
+ Return (Package() {\_PR.CPU0, \_PR.CPU1})
+ } Else {
+ Return (Package() {\_PR.CPU0})
+ }
+}
diff --git a/src/cpu/intel/fsp_model_406dx/bootblock.c b/src/cpu/intel/fsp_model_406dx/bootblock.c
new file mode 100644
index 0000000..28e83b2
--- /dev/null
+++ b/src/cpu/intel/fsp_model_406dx/bootblock.c
@@ -0,0 +1,95 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2011 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdint.h>
+#include <arch/cpu.h>
+#include <cpu/x86/cache.h>
+#include <cpu/x86/msr.h>
+#include <cpu/x86/mtrr.h>
+#include <arch/io.h>
+#include <reset.h>
+#include <src/southbridge/intel/fsp_rangeley/soc.h>
+
+#include "model_406dx.h"
+
+/*
+ * check for a warm reset and do a hard reset instead.
+ */
+static void check_for_warm_reset(void)
+{
+
+ /*
+ * Check if INIT# is asserted by port 0xCF9 and whether RCBA has been set.
+ * If either is true, then this is a warm reset so execute a Hard Reset
+ */
+ if ( (inb(0xcf9) == 0x04) ||
+ (pci_io_read_config32(SOC_LPC_DEV, RCBA) & RCBA_ENABLE) ) {
+ outb(0x00, 0xcf9);
+ outb(0x06, 0xcf9);
+ }
+}
+
+static void set_var_mtrr(int reg, uint32_t base, uint32_t size, int type)
+{
+#ifndef CONFIG_CPU_ADDR_BITS
+#error "CONFIG_CPU_ADDR_BITS must be set."
+#endif
+
+ /* Bit Bit 32-35 of MTRRphysMask should be set to 1 */
+ msr_t basem, maskm;
+ basem.lo = base | type;
+ basem.hi = 0;
+ wrmsr(MTRRphysBase_MSR(reg), basem);
+ maskm.lo = ~(size - 1) | MTRRphysMaskValid;
+ maskm.hi = (1 << (CONFIG_CPU_ADDR_BITS - 32)) - 1;
+ wrmsr(MTRRphysMask_MSR(reg), maskm);
+}
+
+static void enable_rom_caching(void)
+{
+ msr_t msr;
+
+ disable_cache();
+ set_var_mtrr(1, 0xffffffff - CACHE_ROM_SIZE + 1,
+ CACHE_ROM_SIZE, MTRR_TYPE_WRPROT);
+ enable_cache();
+
+ /* Enable Variable MTRRs */
+ msr.hi = 0x00000000;
+ msr.lo = 0x00000800;
+ wrmsr(MTRRdefType_MSR, msr);
+}
+
+static void set_no_evict_mode_msr(void)
+{
+ msr_t msr;
+ msr.hi = 0x00000000;
+ msr.lo = 0x00000000;
+
+ wrmsr(MSR_NO_EVICT_MODE, msr);
+}
+
+static void bootblock_cpu_init(void)
+{
+ /* Check for Warm Reset */
+ check_for_warm_reset();
+ enable_rom_caching();
+ set_no_evict_mode_msr();
+}
diff --git a/src/cpu/intel/fsp_model_406dx/chip.h b/src/cpu/intel/fsp_model_406dx/chip.h
new file mode 100644
index 0000000..90d32d3
--- /dev/null
+++ b/src/cpu/intel/fsp_model_406dx/chip.h
@@ -0,0 +1,33 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2011 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* Magic value used to locate this chip in the device tree */
+#define SPEEDSTEP_APIC_MAGIC 0xACAC
+
+struct cpu_intel_fsp_model_406dx_config {
+ u8 pstate_coord_type; /* Processor Coordination Type */
+
+ int c1_battery; /* ACPI C1 on Battery Power */
+ int c2_battery; /* ACPI C2 on Battery Power */
+ int c3_battery; /* ACPI C3 on Battery Power */
+
+ int c1_acpower; /* ACPI C1 on AC Power */
+ int c2_acpower; /* ACPI C2 on AC Power */
+ int c3_acpower; /* ACPI C3 on AC Power */
+};
diff --git a/src/cpu/intel/fsp_model_406dx/microcode_blob.c b/src/cpu/intel/fsp_model_406dx/microcode_blob.c
new file mode 100644
index 0000000..a4b7d42
--- /dev/null
+++ b/src/cpu/intel/fsp_model_406dx/microcode_blob.c
@@ -0,0 +1,29 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2012 The ChromiumOS Authors. All rights reserved.
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+unsigned microcode[] = {
+#if IS_ENABLED(CONFIG_FSP_MODEL_406DX_A1)
+ /* Size is 0x14400 */
+ #include <microcode-m01406d000e.h>
+#elif IS_ENABLED(CONFIG_FSP_MODEL_406DX_B0)
+ /* Size is 0x14800 */
+ #include <microcode-m01406d811d.h>
+#endif
+};
diff --git a/src/cpu/intel/fsp_model_406dx/model_406dx.h b/src/cpu/intel/fsp_model_406dx/model_406dx.h
new file mode 100644
index 0000000..095e4b9
--- /dev/null
+++ b/src/cpu/intel/fsp_model_406dx/model_406dx.h
@@ -0,0 +1,113 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#ifndef _CPU_INTEL_MODEL_406DX_H
+#define _CPU_INTEL_MODEL_406DX_H
+
+/* Rangeley bus clock is fixed at 100MHz */
+#define RANGELEY_BCLK 100
+
+#define IA32_FEATURE_CONTROL 0x3a
+#define CPUID_VMX (1 << 5)
+#define CPUID_SMX (1 << 6)
+#define MSR_FEATURE_CONFIG 0x13c
+#define MSR_FLEX_RATIO 0x194
+#define FLEX_RATIO_LOCK (1 << 20)
+#define FLEX_RATIO_EN (1 << 16)
+#define IA32_PLATFORM_DCA_CAP 0x1f8
+#define IA32_MISC_ENABLE 0x1a0
+#define MSR_TEMPERATURE_TARGET 0x1a2
+#define IA32_PERF_CTL 0x199
+#define IA32_THERM_INTERRUPT 0x19b
+#define IA32_ENERGY_PERFORMANCE_BIAS 0x1b0
+#define ENERGY_POLICY_PERFORMANCE 0
+#define ENERGY_POLICY_NORMAL 6
+#define ENERGY_POLICY_POWERSAVE 15
+#define IA32_PACKAGE_THERM_INTERRUPT 0x1b2
+#define MSR_LT_LOCK_MEMORY 0x2e7
+#define IA32_MC0_STATUS 0x401
+
+#define MSR_NO_EVICT_MODE 0x2e0
+#define MSR_PIC_MSG_CONTROL 0x2e
+#define MSR_PLATFORM_INFO 0xce
+#define PLATFORM_INFO_SET_TDP (1 << 29)
+#define MSR_PMG_CST_CONFIG_CONTROL 0xe2
+#define MSR_PMG_IO_CAPTURE_BASE 0xe4
+
+#define MSR_MISC_PWR_MGMT 0x1aa
+#define MISC_PWR_MGMT_EIST_HW_DIS (1 << 0)
+#define MSR_TURBO_RATIO_LIMIT 0x1ad
+#define MSR_POWER_CTL 0x1fc
+
+#define MSR_PKGC3_IRTL 0x60a
+#define MSR_PKGC6_IRTL 0x60b
+#define MSR_PKGC7_IRTL 0x60c
+#define IRTL_VALID (1 << 15)
+#define IRTL_1_NS (0 << 10)
+#define IRTL_32_NS (1 << 10)
+#define IRTL_1024_NS (2 << 10)
+#define IRTL_32768_NS (3 << 10)
+#define IRTL_1048576_NS (4 << 10)
+#define IRTL_33554432_NS (5 << 10)
+#define IRTL_RESPONSE_MASK (0x3ff)
+
+/* long duration in low dword, short duration in high dword */
+#define MSR_PKG_POWER_LIMIT 0x610
+#define PKG_POWER_LIMIT_MASK 0x7fff
+#define PKG_POWER_LIMIT_EN (1 << 15)
+#define PKG_POWER_LIMIT_CLAMP (1 << 16)
+#define PKG_POWER_LIMIT_TIME_SHIFT 17
+#define PKG_POWER_LIMIT_TIME_MASK 0x7f
+
+#define MSR_PP0_CURRENT_CONFIG 0x601
+#define PP0_CURRENT_LIMIT (112 << 3) /* 112 A */
+#define MSR_PP1_CURRENT_CONFIG 0x602
+#define PP1_CURRENT_LIMIT_SNB (35 << 3) /* 35 A */
+#define PP1_CURRENT_LIMIT_IVB (50 << 3) /* 50 A */
+#define MSR_PKG_POWER_SKU_UNIT 0x606
+#define MSR_PKG_POWER_SKU 0x614
+#define MSR_PP0_POWER_LIMIT 0x638
+#define MSR_PP1_POWER_LIMIT 0x640
+
+#define IVB_CONFIG_TDP_MIN_CPUID 0x306a2
+#define MSR_CONFIG_TDP_NOMINAL 0x648
+#define MSR_CONFIG_TDP_LEVEL1 0x649
+#define MSR_CONFIG_TDP_LEVEL2 0x64a
+#define MSR_CONFIG_TDP_CONTROL 0x64b
+#define MSR_TURBO_ACTIVATION_RATIO 0x64c
+
+/* P-state configuration */
+#define PSS_MAX_ENTRIES 8
+#define PSS_RATIO_STEP 2
+#define PSS_LATENCY_TRANSITION 10
+#define PSS_LATENCY_BUSMASTER 10
+
+#ifndef __ROMCC__
+#ifdef __SMM__
+/* Lock MSRs */
+void intel_model_406dx_finalize_smm(void);
+#else
+int cpu_config_tdp_levels(void);
+#endif
+#endif
+
+#endif
diff --git a/src/cpu/intel/fsp_model_406dx/model_406dx_init.c b/src/cpu/intel/fsp_model_406dx/model_406dx_init.c
new file mode 100644
index 0000000..61add22
--- /dev/null
+++ b/src/cpu/intel/fsp_model_406dx/model_406dx_init.c
@@ -0,0 +1,217 @@
+/*
+ * 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) 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., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <string.h>
+#include <arch/acpi.h>
+#include <cpu/cpu.h>
+#include <cpu/x86/mtrr.h>
+#include <cpu/x86/msr.h>
+#include <cpu/x86/lapic.h>
+#include <cpu/intel/speedstep.h>
+#include <cpu/intel/turbo.h>
+#include <cpu/x86/cache.h>
+#include <cpu/x86/name.h>
+#include <pc80/mc146818rtc.h>
+#include "model_406dx.h"
+#include "chip.h"
+
+static void enable_vmx(void)
+{
+ struct cpuid_result regs;
+ msr_t msr;
+ int enable = CONFIG_ENABLE_VMX;
+
+ regs = cpuid(1);
+ /* Check that the VMX is supported before reading or writing the MSR. */
+ if (!((regs.ecx & CPUID_VMX) || (regs.ecx & CPUID_SMX)))
+ return;
+
+ msr = rdmsr(IA32_FEATURE_CONTROL);
+
+ if (msr.lo & (1 << 0)) {
+ printk(BIOS_ERR, "VMX is locked, so %s will do nothing\n", __func__);
+ /* VMX locked. If we set it again we get an illegal
+ * instruction
+ */
+ return;
+ }
+
+ /* The IA32_FEATURE_CONTROL MSR may initialize with random values.
+ * It must be cleared regardless of VMX config setting.
+ */
+ msr.hi = msr.lo = 0;
+
+ printk(BIOS_DEBUG, "%s VMX\n", enable ? "Enabling" : "Disabling");
+
+ if (enable) {
+ msr.lo |= (1 << 2);
+ if (regs.ecx & CPUID_SMX)
+ msr.lo |= (1 << 1);
+ }
+
+ wrmsr(IA32_FEATURE_CONTROL, msr);
+}
+
+int cpu_config_tdp_levels(void)
+{
+ msr_t platform_info;
+
+ /* Minimum CPU revision */
+ if (cpuid_eax(1) < IVB_CONFIG_TDP_MIN_CPUID)
+ return 0;
+
+ /* Bits 34:33 indicate how many levels supported */
+ platform_info = rdmsr(MSR_PLATFORM_INFO);
+ return (platform_info.hi >> 1) & 3;
+}
+
+static void configure_misc(void)
+{
+ msr_t msr;
+
+ msr = rdmsr(IA32_MISC_ENABLE);
+ msr.lo |= (1 << 0); /* Fast String enable */
+ msr.lo |= (1 << 3); /* TM1/TM2/EMTTM enable */
+ msr.lo |= (1 << 16); /* Enhanced SpeedStep Enable */
+ wrmsr(IA32_MISC_ENABLE, msr);
+
+ /* Disable Thermal interrupts */
+ msr.lo = 0;
+ msr.hi = 0;
+ wrmsr(IA32_THERM_INTERRUPT, msr);
+}
+
+static void configure_mca(void)
+{
+ msr_t msr;
+ int i;
+
+ msr.lo = msr.hi = 0;
+ /* This should only be done on a cold boot */
+ for (i = 0; i < 6; i++)
+ wrmsr(IA32_MC0_STATUS + (i * 4), msr);
+}
+
+/*
+ * Initialize any extra cores/threads in this package.
+ */
+static void intel_cores_init(device_t cpu)
+{
+ struct cpuid_result result;
+ unsigned threads_per_package, threads_per_core, i;
+
+ /* Logical processors (threads) per core */
+ result = cpuid_ext(0xb, 0);
+ threads_per_core = result.ebx & 0xffff;
+
+ /* Logical processors (threads) per package */
+ result = cpuid_ext(0xb, 1);
+ threads_per_package = result.ebx & 0xffff;
+
+ /* Only initialize extra cores from BSP */
+ if (cpu->path.apic.apic_id)
+ return;
+
+ printk(BIOS_DEBUG, "CPU: %u has %u cores, %u threads per core\n",
+ cpu->path.apic.apic_id, threads_per_package/threads_per_core,
+ threads_per_core);
+
+ for (i = 1; i < threads_per_package; ++i) {
+ struct device_path cpu_path;
+ device_t new;
+
+ /* Build the cpu device path */
+ cpu_path.type = DEVICE_PATH_APIC;
+ cpu_path.apic.apic_id =
+ cpu->path.apic.apic_id + i;
+
+ /* Update APIC ID if no hyperthreading */
+ if (threads_per_core == 1)
+ cpu_path.apic.apic_id <<= 1;
+
+ /* Allocate the new cpu device structure */
+ new = alloc_dev(cpu->bus, &cpu_path);
+ if (!new)
+ continue;
+
+ printk(BIOS_DEBUG, "CPU: %u has core %u\n",
+ cpu->path.apic.apic_id,
+ new->path.apic.apic_id);
+
+#if IS_ENABLED(CONFIG_SMP) && CONFIG_MAX_CPUS > 1
+ /* Start the new cpu */
+ if (!start_cpu(new)) {
+ /* Record the error in cpu? */
+ printk(BIOS_ERR, "CPU %u would not start!\n",
+ new->path.apic.apic_id);
+ }
+#endif
+ }
+}
+
+static void model_406dx_init(device_t cpu)
+{
+ char processor_name[49];
+
+ /* Turn on caching if we haven't already */
+ x86_enable_cache();
+
+ /* Clear out pending MCEs */
+ configure_mca();
+
+ /* Print processor name */
+ fill_processor_name(processor_name);
+ printk(BIOS_INFO, "CPU: %s.\n", processor_name);
+
+ x86_mtrr_check();
+
+ /* Enable the local cpu apics */
+ setup_lapic();
+
+ /* Enable virtualization */
+ enable_vmx();
+
+ /* Configure Enhanced SpeedStep and Thermal Sensors */
+ configure_misc();
+
+ /* Start up extra cores */
+ intel_cores_init(cpu);
+}
+
+static struct device_operations cpu_dev_ops = {
+ .init = model_406dx_init,
+};
+
+static struct cpu_device_id cpu_table[] = {
+ { X86_VENDOR_INTEL, 0x406d0 }, /* Intel Avoton/Rangeley A1 */
+ { X86_VENDOR_INTEL, 0x406d8 }, /* Intel Avoton/Rangeley B0 */
+ { 0, 0 },
+};
+
+static const struct cpu_driver driver __cpu_driver = {
+ .ops = &cpu_dev_ops,
+ .id_table = cpu_table,
+};
Martin Roth (gaumless(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/6367
-gerrit
commit 9f15e5bd983304712c63c1844e23727d79b7f85f
Author: Martin Roth <martin.roth(a)se-eng.com>
Date: Fri Jul 25 15:28:22 2014 -0600
bayleybay_fsp/Kconfig: Update defaults
- Select a default loglevel of 7 correctly
- Push the SeaBIOS buffers down to 0x90000 segment for XHCI.
- Default to using SeaBIOS master so that the platform can boot
from XHCI.
Change-Id: If46e7bb79613188aa318e9b6082d47868c822ca5
Signed-off-by: Martin Roth <martin.roth(a)se-eng.com>
---
src/mainboard/intel/bayleybay_fsp/Kconfig | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/src/mainboard/intel/bayleybay_fsp/Kconfig b/src/mainboard/intel/bayleybay_fsp/Kconfig
index 7272cbc..5e3f68b 100644
--- a/src/mainboard/intel/bayleybay_fsp/Kconfig
+++ b/src/mainboard/intel/bayleybay_fsp/Kconfig
@@ -30,7 +30,8 @@ config BOARD_SPECIFIC_OPTIONS # dummy
select INCLUDE_MICROCODE_IN_BUILD if FSP_PACKAGE_DEFAULT
select ENABLE_BUILTIN_COM1 if FSP_PACKAGE_DEFAULT
select HAVE_FSP_BIN if FSP_PACKAGE_DEFAULT
- select DEFAULT_CONSOLE_LOGLEVEL_7 if FSP_PACKAGE_DEFAULT
+ select DEFAULT_DEFAULT_CONSOLE_LOGLEVEL_7 if FSP_PACKAGE_DEFAULT
+ select SEABIOS_MALLOC_UPPERMEMORY if PAYLOAD_SEABIOS
select TSC_MONOTONIC_TIMER
config MAINBOARD_DIR
@@ -100,4 +101,9 @@ config VGA_BIOS
bool
default y if FSP_PACKAGE_DEFAULT
+config DEFAULT_TO_SEABIOS_MASTER
+ bool
+ depends on PAYLOAD_SEABIOS
+ default y if FSP_PACKAGE_DEFAULT
+
endif # BOARD_INTEL_BAYLEYBAY_FSP
Martin Roth (gaumless(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/6366
-gerrit
commit 4570ef159e93412deea5fde60f9910295448df1c
Author: Martin Roth <martin.roth(a)se-eng.com>
Date: Fri Jul 25 15:25:07 2014 -0600
src/console/Kconfig: Default loglevel to 7 or 5 if desired
coreboot has the default loglevel set to spew. This change allows
the platform to set the default loglevel to 7 (Debug) or 5 (Notice).
Change-Id: Ibdddb05b22273a18d2eaf2f609127fad46aa3a7f
Signed-off-by: Martin Roth <martin.roth(a)se-eng.com>
---
src/console/Kconfig | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/src/console/Kconfig b/src/console/Kconfig
index 710cc6e..55cf3de 100644
--- a/src/console/Kconfig
+++ b/src/console/Kconfig
@@ -211,6 +211,8 @@ config CONSOLE_QEMU_DEBUGCON_PORT
choice
prompt "Default console log level"
+ default DEFAULT_CONSOLE_LOGLEVEL_5 if DEFAULT_DEFAULT_CONSOLE_LOGLEVEL_5
+ default DEFAULT_CONSOLE_LOGLEVEL_7 if DEFAULT_DEFAULT_CONSOLE_LOGLEVEL_7
default DEFAULT_CONSOLE_LOGLEVEL_8
config DEFAULT_CONSOLE_LOGLEVEL_8
@@ -252,6 +254,18 @@ config DEFAULT_CONSOLE_LOGLEVEL_0
endchoice
+config DEFAULT_DEFAULT_CONSOLE_LOGLEVEL_5
+ bool
+ default n
+ help
+ Set the default for the default loglevel to Notice
+
+config DEFAULT_DEFAULT_CONSOLE_LOGLEVEL_7
+ bool
+ default n
+ help
+ Set the default for the default loglevel to Debug
+
config DEFAULT_CONSOLE_LOGLEVEL
int
default 0 if DEFAULT_CONSOLE_LOGLEVEL_0
Martin Roth (gaumless(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/6365
-gerrit
commit dc7798cdbacb5fd65213b8c1deb98a3636069ba7
Author: Martin Roth <martin.roth(a)se-eng.com>
Date: Fri Jul 25 14:57:11 2014 -0600
src/Kconfig: Select SeaBIOS master branch by default if desired
This just adds a way to select the SeaBIOS master branch by default
if desired. The Intel CRBs I'm adding have a single switch to
set up the configuration the way that Intel desires. This allows
that switch to set the platform to use the master branch.
Change-Id: I99fe7448ffbeb90b63878981f9dd8fc6b7d408f3
Signed-off-by: Martin Roth <martin.roth(a)se-eng.com>
---
src/Kconfig | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/src/Kconfig b/src/Kconfig
index 397b20c..5ebff3c 100644
--- a/src/Kconfig
+++ b/src/Kconfig
@@ -591,6 +591,7 @@ endchoice
choice
prompt "SeaBIOS version"
+ default SEABIOS_MASTER if DEFAULT_TO_SEABIOS_MASTER
default SEABIOS_STABLE
depends on PAYLOAD_SEABIOS
@@ -605,6 +606,13 @@ config SEABIOS_MASTER
endchoice
+config DEFAULT_TO_SEABIOS_MASTER
+ bool
+ default n
+ depends on PAYLOAD_SEABIOS
+ help
+ Allow a platform to default to using the SeaBIOS master branch
+
config SEABIOS_PS2_TIMEOUT
prompt "PS/2 keyboard controller initialization timeout (milliseconds)" if PAYLOAD_SEABIOS
default 0
Martin Roth (gaumless(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/6364
-gerrit
commit f2392b23a1999fa1d6f8dc8ad7f3b3a4b4f7135c
Author: Martin Roth <martin.roth(a)se-eng.com>
Date: Fri Jul 25 14:39:05 2014 -0600
payloads/external/SeaBIOS: Allow setting buffers below 0xC0000
Add the option to coreboot to set the SeaBIOS buffers below C0000.
This is an absolute requirement on the upcoming rangeley processor
because it is designed so that only the processor can write the
higher memory areas. This prevents USB from bus-mastering into the
buffers when they're set in the typical 0xE0000 area.
Change-Id: I15638605d1c66a2277d4b852796db89978551a34
Signed-off-by: Martin Roth <martin.roth(a)se-eng.com>
---
payloads/external/SeaBIOS/Makefile.inc | 3 +++
src/Kconfig | 9 +++++++++
src/arch/x86/Makefile.inc | 1 +
3 files changed, 13 insertions(+)
diff --git a/payloads/external/SeaBIOS/Makefile.inc b/payloads/external/SeaBIOS/Makefile.inc
index da587b7..7782ee6 100644
--- a/payloads/external/SeaBIOS/Makefile.inc
+++ b/payloads/external/SeaBIOS/Makefile.inc
@@ -31,6 +31,9 @@ ifeq ($(CONFIG_CONSOLE_SERIAL),y)
else
echo "# CONFIG_DEBUG_SERIAL is not set" >> $(OUT)/seabios/.config
endif
+ifneq ($(CONFIG_SEABIOS_MALLOC_UPPERMEMORY),y)
+ echo "# CONFIG_MALLOC_UPPERMEMORY is not set" >> $(OUT)/seabios/.config
+endif
ifneq ($(CONFIG_SEABIOS_THREAD_OPTIONROMS),y)
echo "# CONFIG_THREAD_OPTIONROMS is not set" >> $(OUT)/seabios/.config
endif
diff --git a/src/Kconfig b/src/Kconfig
index af82353..397b20c 100644
--- a/src/Kconfig
+++ b/src/Kconfig
@@ -626,6 +626,15 @@ config SEABIOS_THREAD_OPTIONROMS
variations during option ROM code execution. It is not
known if all option ROMs will behave properly with this option.
+config SEABIOS_MALLOC_UPPERMEMORY
+ prompt "Allocate memory that needs to be in first Meg above 0xc0000" if PAYLOAD_SEABIOS
+ default y
+ bool
+ help
+ Use the "Upper Memory Block" area (0xc0000-0xf0000) for internal
+ "low memory" allocations. If this is not selected, the memory is
+ instead allocated from the "9-segment" (0x90000-0xa0000).
+
choice
prompt "GRUB2 version"
default GRUB2_MASTER
diff --git a/src/arch/x86/Makefile.inc b/src/arch/x86/Makefile.inc
index 2e92d89..3b2517b 100644
--- a/src/arch/x86/Makefile.inc
+++ b/src/arch/x86/Makefile.inc
@@ -352,6 +352,7 @@ seabios:
CONFIG_SEABIOS_THREAD_OPTIONROMS=$(CONFIG_SEABIOS_THREAD_OPTIONROMS) \
CONFIG_CONSOLE_SERIAL=$(CONFIG_CONSOLE_SERIAL) \
CONFIG_TTYS0_BASE=$(CONFIG_TTYS0_BASE) \
+ CONFIG_SEABIOS_MALLOC_UPPERMEMORY=$(CONFIG_SEABIOS_MALLOC_UPPERMEMORY) \
OUT=$(abspath $(obj)) IASL="$(IASL)"
filo:
Martin Roth (gaumless(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/6363
-gerrit
commit 557dad06a8c8c4080c4582a512ced9505ed17955
Author: Martin Roth <martin.roth(a)se-eng.com>
Date: Fri Jul 25 14:33:49 2014 -0600
payloads/external/SeaBIOS: Update makefile for serial console
Set up the serial console on SeaBIOS to match coreboot's settings.
Previously, we were just forcing it on, and setting it to 0x3f8.
Change-Id: I107245c8bd1ba2cf948c6671337c6169226aaaaf
Signed-off-by: Martin Roth <martin.roth(a)se-eng.com>
---
payloads/external/SeaBIOS/Makefile.inc | 5 +++++
src/arch/x86/Makefile.inc | 2 ++
2 files changed, 7 insertions(+)
diff --git a/payloads/external/SeaBIOS/Makefile.inc b/payloads/external/SeaBIOS/Makefile.inc
index d568c66..da587b7 100644
--- a/payloads/external/SeaBIOS/Makefile.inc
+++ b/payloads/external/SeaBIOS/Makefile.inc
@@ -25,7 +25,12 @@ checkout: fetch
config: checkout
echo " CONFIG SeaBIOS $(TAG-y)"
echo "CONFIG_COREBOOT=y" >> $(OUT)/seabios/.config
+ifeq ($(CONFIG_CONSOLE_SERIAL),y)
echo "CONFIG_DEBUG_SERIAL=y" >> $(OUT)/seabios/.config
+ echo "CONFIG_DEBUG_SERIAL_PORT=$(CONFIG_TTYS0_BASE)" >> $(OUT)/seabios/.config
+else
+ echo "# CONFIG_DEBUG_SERIAL is not set" >> $(OUT)/seabios/.config
+endif
ifneq ($(CONFIG_SEABIOS_THREAD_OPTIONROMS),y)
echo "# CONFIG_THREAD_OPTIONROMS is not set" >> $(OUT)/seabios/.config
endif
diff --git a/src/arch/x86/Makefile.inc b/src/arch/x86/Makefile.inc
index c0e908d..2e92d89 100644
--- a/src/arch/x86/Makefile.inc
+++ b/src/arch/x86/Makefile.inc
@@ -350,6 +350,8 @@ seabios:
CONFIG_SEABIOS_MASTER=$(CONFIG_SEABIOS_MASTER) \
CONFIG_SEABIOS_STABLE=$(CONFIG_SEABIOS_STABLE) \
CONFIG_SEABIOS_THREAD_OPTIONROMS=$(CONFIG_SEABIOS_THREAD_OPTIONROMS) \
+ CONFIG_CONSOLE_SERIAL=$(CONFIG_CONSOLE_SERIAL) \
+ CONFIG_TTYS0_BASE=$(CONFIG_TTYS0_BASE) \
OUT=$(abspath $(obj)) IASL="$(IASL)"
filo:
Martin Roth (gaumless(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/6362
-gerrit
commit f7fb70a31e297defadbf1b996fd60ed769fb1d14
Author: Martin Roth <martin.roth(a)se-eng.com>
Date: Fri Jul 25 14:24:32 2014 -0600
payloads/external/SeaBIOS: Update makefile for olddefconfig
Instead of creating the SeaBIOS .config file for QEMU, then changing
things to be coreboot specific, create a default config for coreboot,
then run olddefconfig to use the SeaBIOS defaults as they're set for
coreboot. This leads to a cleaner config.
Note that CONFIG_THREAD_OPTIONROMS defaults to enabled for SeaBIOS if
we're building for coreboot, so I reversed the logic.
I *ASSUMED* that leaving CONFIG_QEMU_HARDWARE=y and CONFIG_DEBUG_IO=y
previously was an oversight. If this is not correct, please let me
know and I'll them it back in. SeaBIOS disables these by default if
building for coreboot.
Change-Id: I42c6a56205bb15c6693a5f3a716b7876a4d78abe
Signed-off-by: Martin Roth <martin.roth(a)se-eng.com>
---
payloads/external/SeaBIOS/Makefile.inc | 14 ++++----------
1 file changed, 4 insertions(+), 10 deletions(-)
diff --git a/payloads/external/SeaBIOS/Makefile.inc b/payloads/external/SeaBIOS/Makefile.inc
index 48ca582..d568c66 100644
--- a/payloads/external/SeaBIOS/Makefile.inc
+++ b/payloads/external/SeaBIOS/Makefile.inc
@@ -24,20 +24,14 @@ checkout: fetch
config: checkout
echo " CONFIG SeaBIOS $(TAG-y)"
- $(MAKE) -C $(OUT)/seabios defconfig OUT=$(OUT)/seabios/out/
echo "CONFIG_COREBOOT=y" >> $(OUT)/seabios/.config
-ifeq ($(CONFIG_SEABIOS_THREAD_OPTIONROMS),y)
- echo "CONFIG_THREAD_OPTIONROMS=y" >> $(OUT)/seabios/.config
-endif
echo "CONFIG_DEBUG_SERIAL=y" >> $(OUT)/seabios/.config
- echo "CONFIG_DEBUG_SERIAL_PORT=0x3f8" >> $(OUT)/seabios/.config
- echo "CONFIG_COREBOOT_FLASH=y" >> $(OUT)/seabios/.config
- echo "CONFIG_LZMA=y" >> $(OUT)/seabios/.config
- echo "CONFIG_FLASH_FLOPPY=y" >> $(OUT)/seabios/.config
- echo "CONFIG_VGAHOOKS=y" >> $(OUT)/seabios/.config
- echo "CONFIG_DEBUG_COREBOOT=y" >> $(OUT)/seabios/.config
+ifneq ($(CONFIG_SEABIOS_THREAD_OPTIONROMS),y)
+ echo "# CONFIG_THREAD_OPTIONROMS is not set" >> $(OUT)/seabios/.config
+endif
# This shows how to force a previously set .config option *off*
#echo "# CONFIG_SMBIOS is not set" >> $(OUT)/seabios/.config
+ $(MAKE) -C $(OUT)/seabios olddefconfig OUT=$(OUT)/seabios/out/
build: config
echo " MAKE SeaBIOS $(TAG-y)"