[coreboot-gerrit] Patch set updated for coreboot: soc/intel: Add Broadwell-DE SoC support

York Yang (york.yang@intel.com) gerrit at coreboot.org
Thu Apr 7 23:59:46 CEST 2016


York Yang (york.yang at intel.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/14014

-gerrit

commit 20f98b9579b3e12fc148b6462ed02f697ad1a127
Author: York Yang <york.yang at intel.com>
Date:   Wed Mar 9 10:54:26 2016 -0800

    soc/intel: Add Broadwell-DE SoC support
    
    Initial files to support Broadwell-DE SoC. This is FSP 1.0 based
    project and is based on Broadwell-DE Gold release. Change has been
    verified on Intel Camelback Mountain CRB.
    
    Change-Id: I20ce8ee8dd1113a7a20a96910292697421f1ca57
    Signed-off-by: York Yang <york.yang at intel.com>
---
 src/soc/intel/fsp_broadwell_de/Kconfig             |  85 +++
 src/soc/intel/fsp_broadwell_de/Makefile.inc        |  35 ++
 src/soc/intel/fsp_broadwell_de/acpi.c              | 454 +++++++++++++++
 src/soc/intel/fsp_broadwell_de/acpi/irq_helper.h   |  45 ++
 src/soc/intel/fsp_broadwell_de/acpi/irqlinks.asl   | 464 +++++++++++++++
 src/soc/intel/fsp_broadwell_de/acpi/irqroute.asl   |  39 ++
 src/soc/intel/fsp_broadwell_de/acpi/lpc.asl        |  92 +++
 src/soc/intel/fsp_broadwell_de/acpi/pcie1.asl      | 465 +++++++++++++++
 .../intel/fsp_broadwell_de/acpi/southcluster.asl   | 350 ++++++++++++
 .../intel/fsp_broadwell_de/bootblock/bootblock.c   |  23 +
 src/soc/intel/fsp_broadwell_de/chip.c              | 106 ++++
 src/soc/intel/fsp_broadwell_de/chip.h              |  29 +
 src/soc/intel/fsp_broadwell_de/cpu.c               | 110 ++++
 src/soc/intel/fsp_broadwell_de/fsp/Kconfig         |  93 +++
 src/soc/intel/fsp_broadwell_de/fsp/Makefile.inc    |  17 +
 .../intel/fsp_broadwell_de/fsp/chipset_fsp_util.c  | 126 ++++
 .../intel/fsp_broadwell_de/fsp/chipset_fsp_util.h  |  35 ++
 src/soc/intel/fsp_broadwell_de/include/soc/acpi.h  |  27 +
 .../fsp_broadwell_de/include/soc/broadwell_de.h    |  20 +
 src/soc/intel/fsp_broadwell_de/include/soc/iomap.h |  66 +++
 src/soc/intel/fsp_broadwell_de/include/soc/irq.h   |  88 +++
 src/soc/intel/fsp_broadwell_de/include/soc/lpc.h   |  86 +++
 src/soc/intel/fsp_broadwell_de/include/soc/msr.h   |  28 +
 .../intel/fsp_broadwell_de/include/soc/pattrs.h    |  52 ++
 .../intel/fsp_broadwell_de/include/soc/pci_devs.h  | 110 ++++
 .../intel/fsp_broadwell_de/include/soc/ramstage.h  |  30 +
 src/soc/intel/fsp_broadwell_de/include/soc/reset.h |  24 +
 .../intel/fsp_broadwell_de/include/soc/romstage.h  |  35 ++
 src/soc/intel/fsp_broadwell_de/memmap.c            |  23 +
 src/soc/intel/fsp_broadwell_de/northcluster.c      | 156 +++++
 src/soc/intel/fsp_broadwell_de/ramstage.c          |  86 +++
 src/soc/intel/fsp_broadwell_de/reset.c             |  29 +
 .../intel/fsp_broadwell_de/romstage/Makefile.inc   |   3 +
 src/soc/intel/fsp_broadwell_de/romstage/romstage.c | 129 +++++
 src/soc/intel/fsp_broadwell_de/southcluster.c      | 267 +++++++++
 src/soc/intel/fsp_broadwell_de/spi.c               | 633 +++++++++++++++++++++
 src/soc/intel/fsp_broadwell_de/uart.c              | 112 ++++
 37 files changed, 4572 insertions(+)

diff --git a/src/soc/intel/fsp_broadwell_de/Kconfig b/src/soc/intel/fsp_broadwell_de/Kconfig
new file mode 100644
index 0000000..14db2e3
--- /dev/null
+++ b/src/soc/intel/fsp_broadwell_de/Kconfig
@@ -0,0 +1,85 @@
+config SOC_INTEL_FSP_BROADWELL_DE
+	bool
+	help
+	  Broadwell-DE support using the Intel FSP.
+
+if SOC_INTEL_FSP_BROADWELL_DE
+
+config CPU_SPECIFIC_OPTIONS
+	def_bool y
+	select ARCH_BOOTBLOCK_X86_32
+	select ARCH_VERSTAGE_X86_32
+	select ARCH_ROMSTAGE_X86_32
+	select ARCH_RAMSTAGE_X86_32
+	select HAVE_HARD_RESET
+	select MMCONF_SUPPORT
+	select MMCONF_SUPPORT_DEFAULT
+	select RELOCATABLE_MODULES
+	select PARALLEL_MP
+	select SMP
+	select IOAPIC
+	select SPI_FLASH
+	select UDELAY_TSC
+	select SUPPORT_CPU_UCODE_IN_CBFS
+	# Microcode header files are delivered in FSP package
+	select USES_MICROCODE_HEADER_FILES if HAVE_FSP_BIN
+
+config CBFS_SIZE
+	hex
+	default 0x200000
+
+config RAMTOP
+	hex
+	default 0x400000
+
+config HEAP_SIZE
+	hex
+	default 0x100000
+
+config BOOTBLOCK_CPU_INIT
+	string
+	default "soc/intel/fsp_broadwell_de/bootblock/bootblock.c"
+
+config MMCONF_BASE_ADDRESS
+	hex
+	default 0x80000000
+
+config MAX_CPUS
+	int
+	default 16
+
+config CPU_ADDR_BITS
+	int
+	default 36
+
+config VGA_BIOS
+	bool
+	default n
+
+config INTEGRATED_UART
+	bool "Integrated UART ports"
+	default y
+	select HAVE_UART_SPECIAL
+	select CONSOLE_SERIAL
+	help
+	  Use Broadwell-DE Integrated UART ports @3F8h and 2F8h.
+
+config DRIVERS_UART_8250IO
+	bool "Serial port on SuperIO (Broadwell-DE's UART ports unselected)"
+	depends on !INTEGRATED_UART
+	help
+	  Select to choose SuperIO's serial port for console output.
+	  CANNOT select if intend to use SoC integrated serial ports.
+
+config CONSOLE_CBMEM
+	bool "Send console output to a CBMEM buffer"
+	default n
+
+config CPU_MICROCODE_HEADER_FILES
+	string
+	default "../intel/cpu/broadwell_de/microcode/M1050663_07000001.h ../intel/cpu/broadwell_de/microcode/M1050662_0000000A.h ../intel/cpu/broadwell_de/microcode/MFF50661_F1000008.h"
+
+## Broadwell-DE Specific FSP Kconfig
+source src/soc/intel/fsp_broadwell_de/fsp/Kconfig
+
+endif	# SOC_INTEL_FSP_BROADWELL_DE
diff --git a/src/soc/intel/fsp_broadwell_de/Makefile.inc b/src/soc/intel/fsp_broadwell_de/Makefile.inc
new file mode 100644
index 0000000..a0d5203
--- /dev/null
+++ b/src/soc/intel/fsp_broadwell_de/Makefile.inc
@@ -0,0 +1,35 @@
+ifeq ($(CONFIG_SOC_INTEL_FSP_BROADWELL_DE),y)
+
+subdirs-y += romstage
+subdirs-y += ../../../cpu/intel/microcode
+subdirs-y += ../../../cpu/intel/turbo
+subdirs-y += ../../../cpu/x86/lapic
+subdirs-y += ../../../cpu/x86/mtrr
+subdirs-y += ../../../cpu/x86/tsc
+subdirs-y += ../../../cpu/x86/cache
+subdirs-y += ../../../lib/fsp
+subdirs-y += fsp
+
+ramstage-y += spi.c
+ramstage-y += cpu.c
+ramstage-y += chip.c
+ramstage-y += northcluster.c
+ramstage-y += ramstage.c
+romstage-y += memmap.c
+ramstage-y += memmap.c
+ramstage-y += southcluster.c
+romstage-y += reset.c
+ramstage-y += reset.c
+ramstage-y += acpi.c
+
+ifeq ($(CONFIG_INTEGRATED_UART),y)
+romstage-y += uart.c
+ramstage-y += uart.c
+smm-$(CONFIG_DEBUG_SMI) += uart.c
+endif
+
+CPPFLAGS_common += -I$(src)/soc/intel/fsp_broadwell_de/include
+CPPFLAGS_common += -I$(src)/soc/intel/fsp_broadwell_de/fsp
+CPPFLAGS_common += -I$(src)/soc/intel/fsp_broadwell_de/
+
+endif # ifeq ($(CONFIG_SOC_INTEL_FSP_BROADWELL_DE),y)
diff --git a/src/soc/intel/fsp_broadwell_de/acpi.c b/src/soc/intel/fsp_broadwell_de/acpi.c
new file mode 100644
index 0000000..afa4048
--- /dev/null
+++ b/src/soc/intel/fsp_broadwell_de/acpi.c
@@ -0,0 +1,454 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ * Copyright (C) 2013 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corp.
+ *
+ * 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.
+ */
+
+#include <string.h>
+#include <types.h>
+#include <arch/acpigen.h>
+#include <arch/cpu.h>
+#include <arch/io.h>
+#include <arch/smp/mpspec.h>
+#include <console/console.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 <device/pci_ids.h>
+#include <soc/acpi.h>
+#include <soc/iomap.h>
+#include <soc/irq.h>
+#include <soc/lpc.h>
+#include <soc/msr.h>
+#include <soc/pattrs.h>
+#include <soc/pci_devs.h>
+#include <chip.h>
+
+uint16_t get_pmbase(void)
+{
+	return ACPI_BASE_ADDRESS;
+}
+
+#define MWAIT_RES(state, sub_state)                         \
+	{                                                   \
+		.addrl = (((state) << 4) | (sub_state)),    \
+		.space_id = ACPI_ADDRESS_SPACE_FIXED,       \
+		.bit_width = ACPI_FFIXEDHW_VENDOR_INTEL,    \
+		.bit_offset = ACPI_FFIXEDHW_CLASS_MWAIT,    \
+		.access_size = ACPI_FFIXEDHW_FLAG_HW_COORD, \
+	}
+
+/* C-state map */
+static acpi_cstate_t cstate_map[] = {
+	{
+		/* C1 */
+		.ctype = 1, /* ACPI C1 */
+		.latency = 1,
+		.power = 1000,
+		.resource = MWAIT_RES(0, 0),
+	},
+	{
+		/* C3 */
+		.ctype = 2, /* ACPI C2 */
+		.latency = 15,
+		.power = 500,
+		.resource = MWAIT_RES(1, 0),
+	},
+	{
+		/* C6 */
+		.ctype = 3, /* ACPI C3 */
+		.latency = 41,
+		.power = 350,
+		.resource = MWAIT_RES(2, 0),
+	}
+};
+
+static int acpi_sci_irq(void)
+{
+	return 9;
+}
+
+void acpi_create_intel_hpet(acpi_hpet_t *hpet)
+{
+	acpi_header_t *header = &(hpet->header);
+	acpi_addr_t *addr = &(hpet->addr);
+
+	memset((void *) hpet, 0, sizeof(acpi_hpet_t));
+
+	/* fill out header fields */
+	memcpy(header->signature, "HPET", 4);
+	memcpy(header->oem_id, OEM_ID, 6);
+	memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8);
+	memcpy(header->asl_compiler_id, ASLC, 4);
+
+	header->length = sizeof(acpi_hpet_t);
+	header->revision = 1;
+
+	/* fill out HPET address */
+	addr->space_id   = 0;	/* Memory */
+	addr->bit_width  = 64;
+	addr->bit_offset = 0;
+	addr->addrl      = (unsigned long long)HPET_BASE_ADDRESS & 0xffffffff;
+	addr->addrh      = (unsigned long long)HPET_BASE_ADDRESS >> 32;
+
+	hpet->id         = 0x8086a201;	/* Intel */
+	hpet->number     = 0x00;
+	hpet->min_tick   = 0x0080;
+
+	header->checksum = acpi_checksum((void *) hpet, sizeof(acpi_hpet_t));
+}
+
+unsigned long acpi_fill_mcfg(unsigned long current)
+{
+	current += acpi_create_mcfg_mmconfig((acpi_mcfg_mmconfig_t *)current,
+	                                     MCFG_BASE_ADDRESS, 0, 0, 255);
+	return current;
+}
+
+/**
+ * Fill in the fadt with generic values that can be overridden later.
+ */
+
+void acpi_fill_in_fadt(acpi_fadt_t *fadt, acpi_facs_t *facs, void *dsdt)
+{
+	acpi_header_t *header = &(fadt->header);
+	u16 pmbase = get_pmbase();
+
+	memset((void *) fadt, 0, sizeof(acpi_fadt_t));
+
+	/*
+	 * Reference section 5.2.9 Fixed ACPI Description Table (FADT)
+	 * in the ACPI 3.0b specification.
+	 */
+
+	/* FADT Header Structure */
+	memcpy(header->signature, "FACP", 4);
+	header->length = sizeof(acpi_fadt_t);
+	header->revision = ACPI_FADT_REV_ACPI_3_0;
+	memcpy(header->oem_id, OEM_ID, 6);
+	memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8);
+	memcpy(header->asl_compiler_id, ASLC, 4);
+	header->asl_compiler_revision = 1;
+
+	/* ACPI Pointers */
+	fadt->firmware_ctrl = (unsigned long) facs;
+	fadt->dsdt = (unsigned long) dsdt;
+
+	fadt->model                = 0; /* reserved, should be 0 ACPI 3.0 */
+	fadt->preferred_pm_profile = 0;
+	fadt->sci_int              = acpi_sci_irq();
+
+	/* System Management */
+	fadt->smi_cmd      = 0x00; /* disable SMM */
+	fadt->acpi_enable  = 0x00; /* unused  if  SMI_CMD = 0 */
+	fadt->acpi_disable = 0x00; /* unused  if  SMI_CMD = 0 */
+
+	/* Enable ACPI */
+	outl(inl(pmbase + 4) | 0x01, pmbase + 4);
+
+	/* Power Control */
+	fadt->s4bios_req = 0x00;
+	fadt->pstate_cnt = 0x00;
+
+	/* Control Registers - Base Address */
+	fadt->pm1a_evt_blk = pmbase + PM1_STS;
+	fadt->pm1b_evt_blk = 0x00; /* Not Used */
+	fadt->pm1a_cnt_blk = pmbase + PM1_CNT;
+	fadt->pm1b_cnt_blk = 0x00; /* Not Used */
+	fadt->pm2_cnt_blk  = pmbase + PM2A_CNT_BLK;
+	fadt->pm_tmr_blk   = pmbase + PM1_TMR;
+	fadt->gpe0_blk     = pmbase + GPE0_STS;
+	fadt->gpe1_blk     = 0x00; /* Not Used */
+
+	/* Control Registers - Length */
+	fadt->pm1_evt_len  = 4; /* 32 bits */
+	fadt->pm1_cnt_len  = 2; /* 32 bit register, 16 bits used */
+	fadt->pm2_cnt_len  = 1; /* 8 bits */
+	fadt->pm_tmr_len   = 4; /* 32 bits */
+	fadt->gpe0_blk_len = 8; /* 64 bits */
+	fadt->gpe1_blk_len = 0;
+	fadt->gpe1_base    = 0;
+	fadt->cst_cnt      = 0;
+	fadt->p_lvl2_lat   = ACPI_FADT_C2_NOT_SUPPORTED;
+	fadt->p_lvl3_lat   = ACPI_FADT_C3_NOT_SUPPORTED;
+	fadt->flush_size   = 0; /* set to 0 if WBINVD is 1 in flags */
+	fadt->flush_stride = 0; /* set to 0 if WBINVD is 1 in flags */
+	fadt->duty_offset  = 1;
+	fadt->duty_width   = 0;
+
+	/* RTC Registers */
+	fadt->day_alrm       = 0x0D;
+	fadt->mon_alrm       = 0x00;
+	fadt->century        = 0x00;
+	fadt->iapc_boot_arch = 0;
+
+	fadt->flags = ACPI_FADT_WBINVD | ACPI_FADT_C1_SUPPORTED |
+			ACPI_FADT_C2_MP_SUPPORTED | ACPI_FADT_SLEEP_BUTTON |
+			ACPI_FADT_RESET_REGISTER | ACPI_FADT_SLEEP_TYPE |
+			ACPI_FADT_S4_RTC_WAKE | ACPI_FADT_PLATFORM_CLOCK;
+
+	/* Reset Register */
+	fadt->reset_reg.space_id    = ACPI_ADDRESS_SPACE_IO;
+	fadt->reset_reg.bit_width   = 8;
+	fadt->reset_reg.bit_offset  = 0;
+	fadt->reset_reg.access_size = ACPI_ACCESS_SIZE_BYTE_ACCESS;
+	fadt->reset_reg.addrl       = 0xCF9;
+	fadt->reset_reg.addrh       = 0x00;
+	fadt->reset_value           = 6;
+
+	/* Reserved Bits */
+	fadt->res3 = 0x00; /* reserved, MUST be 0 ACPI 3.0 */
+	fadt->res4 = 0x00; /* reserved, MUST be 0 ACPI 3.0 */
+	fadt->res5 = 0x00; /* reserved, MUST be 0 ACPI 3.0 */
+
+	/* Extended ACPI Pointers */
+	fadt->x_firmware_ctl_l = (unsigned long)facs;
+	fadt->x_firmware_ctl_h = 0x00;
+	fadt->x_dsdt_l         = (unsigned long)dsdt;
+	fadt->x_dsdt_h         = 0x00;
+
+	/* PM1 Status & PM1 Enable */
+	fadt->x_pm1a_evt_blk.space_id    = ACPI_ADDRESS_SPACE_IO;
+	fadt->x_pm1a_evt_blk.bit_width   = fadt->pm1_evt_len * 8;
+	fadt->x_pm1a_evt_blk.bit_offset  = 0;
+	fadt->x_pm1a_evt_blk.access_size = ACPI_ACCESS_SIZE_DWORD_ACCESS;
+	fadt->x_pm1a_evt_blk.addrl       = fadt->pm1a_evt_blk;
+	fadt->x_pm1a_evt_blk.addrh       = 0x00;
+
+	fadt->x_pm1b_evt_blk.space_id    = ACPI_ADDRESS_SPACE_IO;
+	fadt->x_pm1b_evt_blk.bit_width   = 0;
+	fadt->x_pm1b_evt_blk.bit_offset  = 0;
+	fadt->x_pm1b_evt_blk.access_size = 0;
+	fadt->x_pm1b_evt_blk.addrl       = fadt->pm1b_evt_blk;
+	fadt->x_pm1b_evt_blk.addrh       = 0x00;
+
+	/* PM1 Control Registers */
+	fadt->x_pm1a_cnt_blk.space_id    = ACPI_ADDRESS_SPACE_IO;
+	fadt->x_pm1a_cnt_blk.bit_width   = 16;
+	fadt->x_pm1a_cnt_blk.bit_offset  = 0;
+	fadt->x_pm1a_cnt_blk.access_size = ACPI_ACCESS_SIZE_WORD_ACCESS;
+	fadt->x_pm1a_cnt_blk.addrl       = fadt->pm1a_cnt_blk;
+	fadt->x_pm1a_cnt_blk.addrh       = 0x00;
+
+	fadt->x_pm1b_cnt_blk.space_id    = ACPI_ADDRESS_SPACE_IO;
+	fadt->x_pm1b_cnt_blk.bit_width   = 0;
+	fadt->x_pm1b_cnt_blk.bit_offset  = 0;
+	fadt->x_pm1b_cnt_blk.access_size = 0;
+	fadt->x_pm1b_cnt_blk.addrl       = fadt->pm1b_cnt_blk;
+	fadt->x_pm1b_cnt_blk.addrh       = 0x00;
+
+	/* PM2 Control Registers */
+	fadt->x_pm2_cnt_blk.space_id     = ACPI_ADDRESS_SPACE_IO;
+	fadt->x_pm2_cnt_blk.bit_width    = 8;
+	fadt->x_pm2_cnt_blk.bit_offset   = 0;
+	fadt->x_pm2_cnt_blk.access_size  = ACPI_ACCESS_SIZE_BYTE_ACCESS;
+	fadt->x_pm2_cnt_blk.addrl        = fadt->pm2_cnt_blk;
+	fadt->x_pm2_cnt_blk.addrh        = 0x00;
+
+	/* PM1 Timer Register */
+	fadt->x_pm_tmr_blk.space_id      = ACPI_ADDRESS_SPACE_IO;
+	fadt->x_pm_tmr_blk.bit_width     = 32;
+	fadt->x_pm_tmr_blk.bit_offset    = 0;
+	fadt->x_pm_tmr_blk.access_size   = ACPI_ACCESS_SIZE_DWORD_ACCESS;
+	fadt->x_pm_tmr_blk.addrl         = fadt->pm_tmr_blk;
+	fadt->x_pm_tmr_blk.addrh         = 0x00;
+
+	/*  General-Purpose Event Registers */
+	fadt->x_gpe0_blk.space_id        = ACPI_ADDRESS_SPACE_IO;
+	fadt->x_gpe0_blk.bit_width       = 64;	/* EventStatus + EventEnable */
+	fadt->x_gpe0_blk.bit_offset      = 0;
+	fadt->x_gpe0_blk.access_size     = ACPI_ACCESS_SIZE_DWORD_ACCESS;
+	fadt->x_gpe0_blk.addrl           = fadt->gpe0_blk;
+	fadt->x_gpe0_blk.addrh           = 0x00;
+
+	fadt->x_gpe1_blk.space_id        = ACPI_ADDRESS_SPACE_IO;
+	fadt->x_gpe1_blk.bit_width       = 0;
+	fadt->x_gpe1_blk.bit_offset      = 0;
+	fadt->x_gpe1_blk.access_size     = 0;
+	fadt->x_gpe1_blk.addrl           = fadt->gpe1_blk;
+	fadt->x_gpe1_blk.addrh           = 0x00;
+
+	header->checksum = acpi_checksum((void *) fadt, sizeof(acpi_fadt_t));
+}
+
+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 void generate_P_state_entries(int core, int cores_per_package)
+{
+	int ratio_min, ratio_max, ratio_step;
+	int coord_type, power_max, power_unit, num_entries;
+	int ratio, power, clock, clock_max;
+	int turbo;
+	u32 control_status;
+	msr_t msr;
+
+	/* Hardware coordination of P-states */
+	coord_type = HW_ALL;
+
+	/* Check for Turbo Mode */
+	turbo = get_turbo_state() == TURBO_ENABLED;
+
+	/* CPU attributes */
+	msr = rdmsr(MSR_PLATFORM_INFO);
+	ratio_min = (msr.hi >>  8) & 0xff;	// LFM
+	ratio_max = (msr.lo >>  8) & 0xff;	// HFM
+	clock_max = (ratio_max * 100);
+
+	/* Calculate CPU TDP in mW */
+	msr = rdmsr(MSR_PKG_POWER_SKU_UNIT);
+	power_unit = 1 << (msr.lo & 0xf);
+	msr = rdmsr(MSR_PKG_POWER_LIMIT);
+	power_max = ((msr.lo & 0x7fff) / power_unit) * 1000;
+
+	/* Write _PCT indicating use of FFixedHW */
+	acpigen_write_empty_PCT();
+
+	/* Write _PPC starting from first supported P-state */
+	acpigen_write_PPC(0);
+
+	/* Write PSD indicating configured coordination type */
+	acpigen_write_PSD_package(core, 1, coord_type);
+
+	/* Add P-state entries in _PSS table */
+	acpigen_write_name("_PSS");
+
+	/* Determine ratio points */
+	/* Note: There should be at most 16 performance states. If Turbo Mode
+	   is enabled, the Max Turbo Ratio will occupy one of these states. */
+	ratio_step = 1;
+	num_entries = (ratio_max - ratio_min) / ratio_step;
+	while (num_entries > (15-turbo)) {
+		ratio_step <<= 1;
+		num_entries >>= 1;
+	}
+
+	if (turbo) {
+		/* _PSS package count (with turbo)  */
+		acpigen_write_package(num_entries + 2);
+
+		/* Get Max Turbo Ratio */
+		msr = rdmsr(MSR_TURBO_RATIO_LIMIT);
+		ratio = msr.lo & 0xff;
+
+		acpigen_write_PSS_package(
+			ratio * 100,		/* MHz */
+			power_max,		/* mW */
+			10,			/* lat1 */
+			10,			/* lat2 */
+			ratio << 8,		/* control */
+			ratio << 8);		/* status */
+	} else {
+		/* _PSS package count (without turbo) */
+		acpigen_write_package(num_entries + 1);
+	}
+
+	/* Generate the _PSS entries */
+	for (ratio = ratio_min + (num_entries * ratio_step);
+		ratio >= ratio_min; ratio -= ratio_step) {
+
+		/* Calculate power at this ratio */
+		power = calculate_power(power_max, ratio_max, ratio);
+		clock = ratio * 100;
+		control_status = ratio << 8;
+
+		acpigen_write_PSS_package(
+			clock,			/* MHz */
+			power,			/* mW */
+			10,			/* lat1 */
+			10,			/* lat2 */
+			control_status,		/* control */
+			control_status);	/* status */
+	}
+
+	/* Fix package length */
+	acpigen_pop_len();
+}
+
+void generate_cpu_entries(device_t device)
+{
+	int core;
+	int pcontrol_blk = get_pmbase(), plen = 6;
+	const struct pattrs *pattrs = pattrs_get();
+
+	for (core = 0; core < pattrs->num_cpus; core++) {
+		if (core > 0) {
+			pcontrol_blk = 0;
+			plen = 0;
+		}
+
+		/* Generate processor \_PR.CP0x */
+		acpigen_write_processor(core, pcontrol_blk, plen);
+
+		/* Generate P-state tables */
+		generate_P_state_entries(core, pattrs->num_cpus);
+
+		/* Generate C-state tables */
+		acpigen_write_CST_package(cstate_map, ARRAY_SIZE(cstate_map));
+
+		acpigen_pop_len();
+	}
+}
+
+unsigned long acpi_madt_irq_overrides(unsigned long current)
+{
+	int sci_irq = acpi_sci_irq();
+	acpi_madt_irqoverride_t *irqovr;
+	uint16_t sci_flags = MP_IRQ_TRIGGER_LEVEL;
+
+	/* INT_SRC_OVR */
+	irqovr = (void *)current;
+	current += acpi_create_madt_irqoverride(irqovr, 0, 0, 2, 0);
+
+	if (sci_irq >= 20)
+		sci_flags |= MP_IRQ_POLARITY_LOW;
+	else
+		sci_flags |= MP_IRQ_POLARITY_HIGH;
+
+	irqovr = (void *)current;
+	current += acpi_create_madt_irqoverride(irqovr, 0, sci_irq, sci_irq,
+	                                        sci_flags);
+
+	irqovr = (void *)current;
+	current += acpi_create_madt_irqoverride(irqovr, 0, 3, 3,
+	                                       (MP_IRQ_TRIGGER_LEVEL
+	                                       |MP_IRQ_POLARITY_LOW));
+
+	irqovr = (void *)current;
+	current += acpi_create_madt_irqoverride(irqovr, 0, 4, 4,
+	                                       (MP_IRQ_TRIGGER_LEVEL
+	                                       |MP_IRQ_POLARITY_LOW));
+
+	return current;
+}
diff --git a/src/soc/intel/fsp_broadwell_de/acpi/irq_helper.h b/src/soc/intel/fsp_broadwell_de/acpi/irq_helper.h
new file mode 100644
index 0000000..8799a9b
--- /dev/null
+++ b/src/soc/intel/fsp_broadwell_de/acpi/irq_helper.h
@@ -0,0 +1,45 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 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.
+ */
+
+#undef PCI_DEV_PIRQ_ROUTES
+#undef ACPI_DEV_IRQ
+#undef PCI_DEV_PIRQ_ROUTE
+#undef PIRQ_PIC_ROUTES
+#undef PIRQ_PIC
+#undef IRQROUTE_H
+
+#if defined(PIC_MODE)
+
+#define ACPI_DEV_IRQ(dev_, pin_, pin_name_) \
+	{ Package() { ## dev_ ## ffff, pin_, \_SB.PCI0.LPCB.LNK ## pin_name_, 0 } }
+
+#else /* defined(PIC_MODE) */
+
+#define ACPI_DEV_IRQ(dev_, pin_, pin_name_) \
+	{ Package() { ## dev_ ## ffff, pin_, 0, PIRQ ## pin_name_ ## _APIC_IRQ } }
+
+#endif
+
+#define PCI_DEV_PIRQ_ROUTE(dev_, a_, b_, c_, d_) \
+	{ ACPI_DEV_IRQ(dev_, 0, a_), \
+	  ACPI_DEV_IRQ(dev_, 1, b_), \
+	  ACPI_DEV_IRQ(dev_, 2, c_), \
+	  ACPI_DEV_IRQ(dev_, 3, d_)  }
+
+/* Empty PIRQ_PIC definition. */
+#define PIRQ_PIC(pirq_, pic_irq_)
+
+/* Include the mainboard irq route definition */
+#include "irqroute.h"
diff --git a/src/soc/intel/fsp_broadwell_de/acpi/irqlinks.asl b/src/soc/intel/fsp_broadwell_de/acpi/irqlinks.asl
new file mode 100644
index 0000000..7d02eb0
--- /dev/null
+++ b/src/soc/intel/fsp_broadwell_de/acpi/irqlinks.asl
@@ -0,0 +1,464 @@
+/*
+ * 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.
+ */
+
+OperationRegion (PRR0, PCI_Config, 0x00, 0x100)
+Field (PRR0, AnyAcc, NoLock, Preserve) {
+  Offset(0x60),
+  PIRA, 8,
+  PIRB, 8,
+  PIRC, 8,
+  PIRD, 8,
+  Offset(0x68),
+  PIRE, 8,
+  PIRF, 8,
+  PIRG, 8,
+  PIRH, 8
+}
+
+Device (LNKA) {      // PCI IRQ link A
+  Name (_HID,EISAID("PNP0C0F"))
+  //Name(_UID, 1)
+  Method (_STA,0,NotSerialized) {
+    If(And(PIRA, 0x80)) {
+      Return (0x9)
+    } Else {
+      Return (0xB)
+    } // Don't display
+  }
+
+  Method (_DIS,0,NotSerialized) {
+    Or (PIRA, 0x80, PIRA)
+  }
+
+  Method (_CRS,0,Serialized) {
+    Name (BUF0, ResourceTemplate() {IRQ(Level,ActiveLow,Shared){0}})
+    //
+    // Define references to buffer elements
+    //
+    CreateWordField (BUF0, 0x01, IRQW)  // IRQ low
+    //
+    // Write current settings into IRQ descriptor
+    //
+    If (And(PIRA, 0x80)) {
+      Store (Zero, Local0)
+    } Else {
+      Store (One,Local0)
+    }
+    //
+    // Shift 1 by value in register 70, Save in buffer
+    //
+    ShiftLeft (Local0,And (PIRA,0x0F),IRQW)       // Save in buffer
+    Return (BUF0)                                 // Return Buf0
+  }                                               // End of _CRS method
+
+  Name (_PRS, ResourceTemplate()
+        {IRQ(Level,ActiveLow,Shared){3,4,5,6,7,9,10,11,12,14,15}})
+
+    Method (_SRS,1,NotSerialized) {
+      CreateWordField (ARG0, 0x01, IRQW)  // IRQ low
+
+      FindSetRightBit(IRQW,Local0)          // Set IRQ
+      If (LNotEqual (IRQW,Zero)){
+        And (Local0, 0x7F,Local0)
+        Decrement (Local0)
+      } Else {
+        Or (Local0, 0x80,Local0)
+      }
+      Store (Local0, PIRA)
+    }   // End of _SRS Method
+}
+
+Device(LNKB) {  // PCI IRQ link B
+  Name (_HID,EISAID("PNP0C0F"))
+  //Name(_UID, 2)
+  Method (_STA,0,NotSerialized) {
+    If (And (PIRB, 0x80)) {
+      Return (0x9)
+    } Else {
+      Return (0xB)
+    } // Don't display
+  }
+
+  Method (_DIS,0,NotSerialized) {
+    Or (PIRB, 0x80,PIRB)
+  }
+
+  Method (_CRS,0,Serialized) {
+    Name(BUF0, ResourceTemplate()
+        {IRQ(Level,ActiveLow,Shared){0}})
+    //
+    // Define references to buffer elements
+    //
+    CreateWordField (BUF0, 0x01, IRQW)  // IRQ low
+    //
+    // Write current settings into IRQ descriptor
+    //
+    If (And (PIRB, 0x80)) {
+      Store (Zero, Local0)
+    } Else {
+      Store (One,Local0)
+    }
+    //
+    // Shift 1 by value in register 70, Save in buffer
+    //
+    ShiftLeft (Local0,And (PIRB,0x0F),IRQW)   // Save in buffer
+    Return (BUF0)               // Return Buf0
+  }                             // End of _CRS method
+
+  Name (_PRS,
+      ResourceTemplate()
+      {IRQ(Level,ActiveLow,Shared){3,4,5,6,7,9,10,11,12,14,15}})
+
+  Method (_SRS,1,NotSerialized) {
+    CreateWordField (ARG0, 0x01, IRQW)      // IRQ low
+
+    FindSetRightBit(IRQW,Local0) // Set IRQ
+    If (LNotEqual(IRQW,Zero)) {
+      And (Local0, 0x7F, Local0)
+      Decrement (Local0)
+    } Else  {
+      Or (Local0, 0x80, Local0)
+    }
+    Store (Local0, PIRB)
+  }   // End of _SRS Method
+}
+
+Device(LNKC) {  // PCI IRQ link C
+  Name(_HID, EISAID("PNP0C0F"))
+  //Name(_UID, 3)
+
+  Method (_STA,0,NotSerialized) {
+    If (And (PIRC, 0x80)) {
+      Return (0x9)
+    } Else {
+      Return (0xB)
+    } // Don't display
+  }
+
+  Method (_DIS, 0, NotSerialized) {
+    Or (PIRC, 0x80, PIRC)
+  }
+
+  Method (_CRS, 0, Serialized) {
+    Name (BUF0, ResourceTemplate()
+        {IRQ(Level,ActiveLow,Shared){0}})
+    //
+    // Define references to buffer elements
+    //
+    CreateWordField (BUF0, 0x01, IRQW)  // IRQ low
+    //
+    // Write current settings into IRQ descriptor
+    //
+    If (And (PIRC, 0x80)) {
+      Store (Zero, Local0)
+    } Else {
+      Store (One,Local0)
+    }
+    //
+    // Shift 1 by value in register 70, Save in buffer
+    //
+    ShiftLeft (Local0,And (PIRC,0x0F),IRQW)
+    Return (BUF0)
+  } // End of _CRS method
+
+  Name (_PRS, ResourceTemplate()
+      {IRQ(Level,ActiveLow,Shared){3,4,5,6,7,9,10,11,12,14,15}})
+
+  Method (_SRS,1,NotSerialized) {
+    CreateWordField (ARG0, 0x01, IRQW)  // IRQ low
+    FindSetRightBit(IRQW,Local0)        // Set IRQ
+    If (LNotEqual (IRQW,Zero)) {
+      And (Local0, 0x7F, Local0)
+      Decrement (Local0)
+    } Else {
+      Or (Local0, 0x80,Local0)
+    }
+    Store (Local0, PIRC)
+  }   // End of _SRS Method
+}
+
+Device (LNKD) {  // PCI IRQ link D
+  Name (_HID,EISAID ("PNP0C0F"))
+
+  //Name(_UID, 4)
+
+  Method (_STA, 0, NotSerialized) {
+    If (And (PIRD, 0x80)) {
+      Return (0x9)
+    } Else  {
+      Return (0xB)
+    }    // Don't display
+  }
+
+  Method (_DIS, 0, NotSerialized) {
+    Or(PIRD, 0x80,PIRD)
+  }
+
+  Method (_CRS,0,Serialized) {
+    Name (BUF0, ResourceTemplate()
+        {IRQ(Level,ActiveLow,Shared){0}})
+    //
+    // Define references to buffer elements
+    //
+    CreateWordField (BUF0, 0x01, IRQW)  // IRQ low
+    //
+    // Write current settings into IRQ descriptor
+    //
+    If (And (PIRD, 0x80)) {
+      Store (Zero, Local0)
+    } Else {
+      Store (One,Local0)
+    }
+    //
+    // Shift 1 by value in register 70, Save in buffer
+    //
+    ShiftLeft (Local0, And (PIRD,0x0F), IRQW)
+    Return (BUF0)  // Return Buf0
+  } // End of _CRS method
+
+  Name (_PRS, ResourceTemplate()
+      {IRQ(Level,ActiveLow,Shared){3,4,5,6,7,9,10,11,12,14,15}})
+
+  Method (_SRS,1,NotSerialized) {
+    CreateWordField (ARG0, 0x01, IRQW)  // IRQ low
+    FindSetRightBit (IRQW, Local0)// Set IRQ
+    If (LNotEqual (IRQW, Zero)) {
+        And (Local0, 0x7F, Local0)
+        Decrement (Local0)
+    } Else {
+        Or (Local0, 0x80, Local0)
+    }
+    Store(Local0, PIRD)
+  }  // End of _SRS Method
+}
+
+Device(LNKE) {  // PCI IRQ link E
+  Name(_HID,EISAID("PNP0C0F"))
+
+  //Name(_UID, 5)
+
+  Method (_STA,0,NotSerialized) {
+    If (And (PIRE, 0x80)) {
+      Return(0x9)
+    } Else  {
+      Return(0xB)
+    }    // Don't display
+  }
+
+  Method (_DIS,0,NotSerialized) {
+    Or (PIRE, 0x80, PIRE)
+  }
+
+  Method (_CRS, 0, Serialized) {
+    Name (BUF0, ResourceTemplate()
+        {IRQ(Level,ActiveLow,Shared){0}})
+    //
+    // Define references to buffer elements
+    //
+    CreateWordField (BUF0, 0x01, IRQW)  // IRQ low
+    //
+    // Write current settings into IRQ descriptor
+    //
+    If (And (PIRE, 0x80)) {
+      Store (Zero, Local0)
+    } Else {
+      Store (One, Local0)
+    }
+    //
+    // Shift 1 by value in register 70, Save in buffer
+    //
+    ShiftLeft (Local0, And (PIRE,0x0F), IRQW)
+    Return (BUF0) // Return Buf0
+  }  // End of _CRS method
+
+  Name(_PRS, ResourceTemplate()
+      {IRQ(Level,ActiveLow,Shared){3,4,5,6,7,9,10,11,12,14,15}})
+
+  Method (_SRS,1,NotSerialized) {
+    CreateWordField (ARG0, 0x01, IRQW)  // IRQ low
+    FindSetRightBit (IRQW, Local0)      // Set IRQ
+    If (LNotEqual (IRQW, Zero)) {
+        And (Local0, 0x7F, Local0)
+        Decrement (Local0)
+    } Else  {
+        Or (Local0, 0x80, Local0)
+    }
+    Store (Local0, PIRE)
+  }   // End of _SRS Method
+}
+
+Device(LNKF) { // PCI IRQ link F
+  Name (_HID,EISAID("PNP0C0F"))
+
+  //Name(_UID, 6)
+
+  Method (_STA,0,NotSerialized) {
+    If (And (PIRF, 0x80)) {
+      Return (0x9)
+    } Else {
+      Return (0xB)
+    }    // Don't display
+  }
+
+  Method (_DIS,0,NotSerialized) {
+    Or (PIRB, 0x80, PIRF)
+  }
+
+  Method (_CRS,0,Serialized) {
+    Name(BUF0, ResourceTemplate()
+        {IRQ(Level,ActiveLow,Shared){0}})
+    //
+    // Define references to buffer elements
+    //
+    CreateWordField (BUF0, 0x01, IRQW)  // IRQ low
+    //
+    // Write current settings into IRQ descriptor
+    //
+    If (And (PIRF, 0x80)) {
+      Store (Zero, Local0)
+    } Else {
+      Store (One, Local0)
+    }
+    //
+    // Shift 1 by value in register 70, Save in buffer
+    //
+    ShiftLeft (Local0, And (PIRF, 0x0F),IRQW)
+    Return (BUF0)
+  }  // End of _CRS method
+
+  Name(_PRS, ResourceTemplate()
+      {IRQ(Level,ActiveLow,Shared){3,4,5,6,7,9,10,11,12,14,15}})
+
+  Method (_SRS,1,NotSerialized) {
+    CreateWordField (ARG0, 0x01, IRQW)      // IRQ low
+    FindSetRightBit (IRQW,Local0)           // Set IRQ
+    If (LNotEqual (IRQW,Zero)) {
+      And (Local0, 0x7F,Local0)
+      Decrement (Local0)
+    } Else {
+      Or (Local0, 0x80, Local0)
+    }
+    Store (Local0, PIRF)
+  }  // End of _SRS Method
+}
+
+Device(LNKG) { // PCI IRQ link G
+    Name(_HID,EISAID("PNP0C0F"))
+    //Name(_UID, 7)
+    Method(_STA,0,NotSerialized) {
+      If (And (PIRG, 0x80)) {
+        Return (0x9)
+      } Else  {
+        Return (0xB)
+      }    // Don't display
+    }
+
+    Method (_DIS, 0, NotSerialized) {
+      Or(PIRG, 0x80,PIRG)
+    }
+
+    Method (_CRS,0,Serialized){
+      Name(BUF0,ResourceTemplate()
+          {IRQ(Level,ActiveLow,Shared){0}})
+      //
+      // Define references to buffer elements
+      //
+      CreateWordField (BUF0, 0x01, IRQW)  // IRQ low
+      //
+      // Write current settings into IRQ descriptor
+      //
+      If (And(PIRG, 0x80)) {
+          Store(Zero, Local0)
+      } Else {
+          Store(One,Local0)
+      }
+      //
+      // Shift 1 by value in register 70, Save in buffer
+      //
+      ShiftLeft (Local0,And(PIRG,0x0F),IRQW)
+      Return (BUF0)
+    }  // End of _CRS method
+
+    Name (_PRS, ResourceTemplate()
+        {IRQ(Level,ActiveLow,Shared){3,4,5,6,7,9,10,11,12,14,15}})
+
+    Method (_SRS,1,NotSerialized) {
+      CreateWordField (ARG0, 0x01, IRQW)  // IRQ low
+      FindSetRightBit(IRQW,Local0)        // Set IRQ
+      If (LNotEqual (IRQW,Zero)) {
+        And (Local0, 0x7F,Local0)
+        Decrement (Local0)
+      } Else {
+        Or (Local0, 0x80,Local0)
+      }
+      Store (Local0, PIRG)
+    }  // End of _SRS Method
+}
+
+Device(LNKH) { // PCI IRQ link H
+    Name (_HID,EISAID("PNP0C0F"))
+
+    //Name(_UID, 8)
+
+    Method (_STA,0,NotSerialized) {
+      If (And(PIRH, 0x80)) {
+        Return(0x9)
+      } Else    {
+        Return(0xB)
+      }    // Don't display
+    }
+
+    Method (_DIS,0,NotSerialized) {
+      Or(PIRH, 0x80,PIRH)
+    }
+
+    Method (_CRS,0,Serialized) {
+      Name(BUF0, ResourceTemplate()
+          {IRQ(Level,ActiveLow,Shared){0}})
+      //
+      // Define references to buffer elements
+      //
+      CreateWordField (BUF0, 0x01, IRQW)  // IRQ low
+      //
+      // Write current settings into IRQ descriptor
+      //
+      If (And (PIRH, 0x80)) {
+        Store (Zero, Local0)
+      } Else {
+        Store (One,Local0)
+      }
+      //
+      // Shift 1 by value in register 70, Save in buffer
+      //
+      ShiftLeft (Local0,And(PIRH,0x0F),IRQW)
+      Return (BUF0)
+    } // End of _CRS method
+
+    Name(_PRS, ResourceTemplate()
+        {IRQ(Level,ActiveLow,Shared){3,4,5,6,7,9,10,11,12,14,15}})
+
+    Method (_SRS,1,NotSerialized) {
+      CreateWordField (ARG0, 0x01, IRQW)  // IRQ low
+      FindSetRightBit (IRQW,Local0)// Set IRQ
+      If (LNotEqual (IRQW,Zero)) {
+        And (Local0, 0x7F,Local0)
+        Decrement (Local0)
+      } Else {
+        Or (Local0, 0x80,Local0)
+      }
+      Store (Local0, PIRH)
+    }
+}
diff --git a/src/soc/intel/fsp_broadwell_de/acpi/irqroute.asl b/src/soc/intel/fsp_broadwell_de/acpi/irqroute.asl
new file mode 100644
index 0000000..a4ce5ea
--- /dev/null
+++ b/src/soc/intel/fsp_broadwell_de/acpi/irqroute.asl
@@ -0,0 +1,39 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ * Copyright (C) 2013 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.
+ */
+
+/* PCI Interrupt Routing */
+Method(_PRT)
+{
+	/*
+	 * PICM comes from _PIC, which returns the following:
+	 * 0 – PIC mode
+	 * 1 – APIC mode
+	 * 2 – SAPIC mode
+	 */
+	If (PICM) {
+		Return (Package() {
+			#undef PIC_MODE
+			#include "irq_helper.h"
+			PCI_DEV_PIRQ_ROUTES
+		})
+	} Else {
+		Return (Package() {
+			#define PIC_MODE
+			#include "irq_helper.h"
+			PCI_DEV_PIRQ_ROUTES
+		})
+	}
+}
diff --git a/src/soc/intel/fsp_broadwell_de/acpi/lpc.asl b/src/soc/intel/fsp_broadwell_de/acpi/lpc.asl
new file mode 100644
index 0000000..6a7a2f1
--- /dev/null
+++ b/src/soc/intel/fsp_broadwell_de/acpi/lpc.asl
@@ -0,0 +1,92 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ * Copyright (C) 2013 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.
+ */
+
+/* Intel LPC Bus Device  - 0:1f.0 */
+
+Device (LPC0)
+{
+	Name(_ADR, 0x001f0000)
+
+	#include "irqlinks.asl"
+
+	Device (FWH)		// Firmware Hub
+	{
+		Name (_HID, EISAID("INT0800"))
+		Name (_CRS, ResourceTemplate()
+		{
+			Memory32Fixed(ReadOnly, 0xff000000, 0x01000000)
+		})
+	}
+
+	Device (HPET)
+	{
+		Name (_HID, EISAID("PNP0103"))
+		Name (_CID, 0x010CD041)
+
+		Method (_STA, 0)	// Device Status
+		{
+			Return (0xf)	// Enable and show device
+		}
+
+		Name(_CRS, ResourceTemplate()
+		{
+			Memory32Fixed(ReadOnly, 0xfed00000, 0x400)
+		})
+	}
+
+	Device(LDRC)	// LPC device: Resource consumption
+	{
+		Name (_HID, EISAID("PNP0C02"))
+		Name (_UID, 2)
+
+		Name (RBUF, ResourceTemplate()
+		{
+			IO (Decode16, 0x61, 0x61, 0x1, 0x01) // NMI Status
+			IO (Decode16, 0x63, 0x63, 0x1, 0x01) // CPU Reserved
+			IO (Decode16, 0x65, 0x65, 0x1, 0x01) // CPU Reserved
+			IO (Decode16, 0x67, 0x67, 0x1, 0x01) // CPU Reserved
+			IO (Decode16, 0x80, 0x80, 0x1, 0x01) // Port 80 Post
+			IO (Decode16, 0x92, 0x92, 0x1, 0x01) // CPU Reserved
+			IO (Decode16, 0xb2, 0xb2, 0x1, 0x02) // SWSMI
+		})
+
+		Method (_CRS, 0, NotSerialized)
+		{
+			Return (RBUF)
+		}
+	}
+
+	Device (RTC)	// Real Time Clock
+	{
+		Name (_HID, EISAID("PNP0B00"))
+		Name (_CRS, ResourceTemplate()
+		{
+			IO (Decode16, 0x70, 0x70, 1, 8)
+		})
+	}
+
+	Device (TIMR)	// Intel 8254 timer
+	{
+		Name(_HID, EISAID("PNP0100"))
+		Name(_CRS, ResourceTemplate()
+		{
+			IO (Decode16, 0x40, 0x40, 0x01, 0x04)
+			IO (Decode16, 0x50, 0x50, 0x10, 0x04)
+			IRQNoFlags() {0}
+		})
+	}
+}
diff --git a/src/soc/intel/fsp_broadwell_de/acpi/pcie1.asl b/src/soc/intel/fsp_broadwell_de/acpi/pcie1.asl
new file mode 100644
index 0000000..950a362
--- /dev/null
+++ b/src/soc/intel/fsp_broadwell_de/acpi/pcie1.asl
@@ -0,0 +1,465 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015-2016 Intel Corp.
+ *
+ * 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.
+ */
+
+Name (PR01, Package() {
+    // [SL01]: PCI Express Slot 1 on 1A on PCI0
+    Package() { 0x0000FFFF, 0, \_SB.PCI0.LPC0.LNKA, 0 },
+    Package() { 0x0000FFFF, 1, \_SB.PCI0.LPC0.LNKB, 0 },
+    Package() { 0x0000FFFF, 2, \_SB.PCI0.LPC0.LNKC, 0 },
+    Package() { 0x0000FFFF, 3, \_SB.PCI0.LPC0.LNKD, 0 },
+})
+
+Name (AR01, Package() {
+    // [SL01]: PCI Express Slot 1 on 1A on PCI0
+    Package() { 0x0000FFFF, 0, 0, 16 },
+    Package() { 0x0000FFFF, 1, 0, 17 },
+    Package() { 0x0000FFFF, 2, 0, 18 },
+    Package() { 0x0000FFFF, 3, 0, 19 },
+})
+
+Name (AH01, Package() {
+    // [SL01]: PCI Express Slot 1 on 1A on PCI0
+    Package() { 0x0000FFFF, 0, 0, 26 },
+    Package() { 0x0000FFFF, 1, 0, 28 },
+    Package() { 0x0000FFFF, 2, 0, 29 },
+    Package() { 0x0000FFFF, 3, 0, 30 },
+})
+
+Name (PR02, Package() {
+    // [SL02]: PCI Express Slot 2 on 1B on PCI0
+    Package() { 0x0000FFFF, 0, \_SB.PCI0.LPC0.LNKA, 0 },
+    Package() { 0x0000FFFF, 1, \_SB.PCI0.LPC0.LNKB, 0 },
+    Package() { 0x0000FFFF, 2, \_SB.PCI0.LPC0.LNKC, 0 },
+    Package() { 0x0000FFFF, 3, \_SB.PCI0.LPC0.LNKD, 0 },
+})
+
+Name (AR02, Package() {
+    // [SL02]: PCI Express Slot 2 on 1B on PCI0
+    Package() { 0x0000FFFF, 0, 0, 16 },
+    Package() { 0x0000FFFF, 1, 0, 17 },
+    Package() { 0x0000FFFF, 2, 0, 18 },
+    Package() { 0x0000FFFF, 3, 0, 19 },
+})
+
+Name (AH02, Package() {
+    // [SL02]: PCI Express Slot 2 on 1B on PCI0
+    Package() { 0x0000FFFF, 0, 0, 27 },
+    Package() { 0x0000FFFF, 1, 0, 30 },
+    Package() { 0x0000FFFF, 2, 0, 28 },
+    Package() { 0x0000FFFF, 3, 0, 29 },
+})
+
+Name (PR03, Package() {
+    // [CB0I]: CB3DMA on IOSF
+    Package() { 0x0000FFFF, 0, \_SB.PCI0.LPC0.LNKA, 0 },
+    // [CB0J]: CB3DMA on IOSF
+    Package() { 0x0000FFFF, 1, \_SB.PCI0.LPC0.LNKB, 0 },
+    // [CB0K]: CB3DMA on IOSF
+    Package() { 0x0000FFFF, 2, \_SB.PCI0.LPC0.LNKC, 0 },
+    // [CB0L]: CB3DMA on IOSF
+    Package() { 0x0000FFFF, 3, \_SB.PCI0.LPC0.LNKD, 0 },
+})
+
+Name (AR03, Package() {
+    // [CB0I]: CB3DMA on IOSF
+    Package() { 0x0000FFFF, 0, 0, 16 },
+    // [CB0J]: CB3DMA on IOSF
+    Package() { 0x0000FFFF, 1, 0, 17 },
+    // [CB0K]: CB3DMA on IOSF
+    Package() { 0x0000FFFF, 2, 0, 18 },
+    // [CB0L]: CB3DMA on IOSF
+    Package() { 0x0000FFFF, 3, 0, 19 },
+})
+
+Name (AH03, Package() {
+    // [CB0I]: CB3DMA on IOSF
+    Package() { 0x0000FFFF, 0, 0, 32 },
+    // [CB0J]: CB3DMA on IOSF
+    Package() { 0x0000FFFF, 1, 0, 36 },
+    // [CB0K]: CB3DMA on IOSF
+    Package() { 0x0000FFFF, 2, 0, 37 },
+    // [CB0L]: CB3DMA on IOSF
+    Package() { 0x0000FFFF, 3, 0, 38 },
+})
+
+Name (PR04, Package() {
+    // [SL04]: PCI Express Slot 4 on 2B on PCI0
+    Package() { 0x0000FFFF, 0, \_SB.PCI0.LPC0.LNKA, 0 },
+    Package() { 0x0000FFFF, 1, \_SB.PCI0.LPC0.LNKB, 0 },
+    Package() { 0x0000FFFF, 2, \_SB.PCI0.LPC0.LNKC, 0 },
+    Package() { 0x0000FFFF, 3, \_SB.PCI0.LPC0.LNKD, 0 },
+})
+
+Name (AR04, Package() {
+    // [SL04]: PCI Express Slot 4 on 2B on PCI0
+    Package() { 0x0000FFFF, 0, 0, 16 },
+    Package() { 0x0000FFFF, 1, 0, 17 },
+    Package() { 0x0000FFFF, 2, 0, 18 },
+    Package() { 0x0000FFFF, 3, 0, 19 },
+})
+
+Name (AH04, Package() {
+    // [SL04]: PCI Express Slot 4 on 2B on PCI0
+    Package() { 0x0000FFFF, 0, 0, 33 },
+    Package() { 0x0000FFFF, 1, 0, 37 },
+    Package() { 0x0000FFFF, 2, 0, 38 },
+    Package() { 0x0000FFFF, 3, 0, 36 },
+})
+
+Name (PR05, Package() {
+    // [SL05]: PCI Express Slot 5 on 2C on PCI0
+    Package() { 0x0000FFFF, 0, \_SB.PCI0.LPC0.LNKA, 0 },
+    Package() { 0x0000FFFF, 1, \_SB.PCI0.LPC0.LNKB, 0 },
+    Package() { 0x0000FFFF, 2, \_SB.PCI0.LPC0.LNKC, 0 },
+    Package() { 0x0000FFFF, 3, \_SB.PCI0.LPC0.LNKD, 0 },
+})
+
+Name (AR05, Package() {
+    // [SL05]: PCI Express Slot 5 on 2C on PCI0
+    Package() { 0x0000FFFF, 0, 0, 16 },
+    Package() { 0x0000FFFF, 1, 0, 17 },
+    Package() { 0x0000FFFF, 2, 0, 18 },
+    Package() { 0x0000FFFF, 3, 0, 19 },
+})
+
+Name (AH05, Package() {
+    // [SL05]: PCI Express Slot 5 on 2C on PCI0
+    Package() { 0x0000FFFF, 0, 0, 34 },
+    Package() { 0x0000FFFF, 1, 0, 37 },
+    Package() { 0x0000FFFF, 2, 0, 36 },
+    Package() { 0x0000FFFF, 3, 0, 38 },
+})
+
+Name (PR06, Package() {
+    // [SL06]: PCI Express Slot 6 on 2D on PCI0
+    Package() { 0x0000FFFF, 0, \_SB.PCI0.LPC0.LNKA, 0 },
+    Package() { 0x0000FFFF, 1, \_SB.PCI0.LPC0.LNKB, 0 },
+    Package() { 0x0000FFFF, 2, \_SB.PCI0.LPC0.LNKC, 0 },
+    Package() { 0x0000FFFF, 3, \_SB.PCI0.LPC0.LNKD, 0 },
+})
+
+Name (AR06, Package() {
+    // [SL06]: PCI Express Slot 6 on 2D on PCI0
+    Package() { 0x0000FFFF, 0, 0, 16 },
+    Package() { 0x0000FFFF, 1, 0, 17 },
+    Package() { 0x0000FFFF, 2, 0, 18 },
+    Package() { 0x0000FFFF, 3, 0, 19 },
+})
+
+Name (AH06, Package() {
+    // [SL06]: PCI Express Slot 6 on 2D on PCI0
+    Package() { 0x0000FFFF, 0, 0, 35 },
+    Package() { 0x0000FFFF, 1, 0, 36 },
+    Package() { 0x0000FFFF, 2, 0, 38 },
+    Package() { 0x0000FFFF, 3, 0, 37 },
+})
+
+Name (PR07, Package() {
+    // [SL07]: PCI Express Slot 7 on 3A on PCI0
+    Package() { 0x0000FFFF, 0, \_SB.PCI0.LPC0.LNKA, 0 },
+    Package() { 0x0000FFFF, 1, \_SB.PCI0.LPC0.LNKB, 0 },
+    Package() { 0x0000FFFF, 2, \_SB.PCI0.LPC0.LNKC, 0 },
+    Package() { 0x0000FFFF, 3, \_SB.PCI0.LPC0.LNKD, 0 },
+})
+
+Name (AR07, Package() {
+    // [SL07]: PCI Express Slot 7 on 3A on PCI0
+    Package() { 0x0000FFFF, 0, 0, 16 },
+    Package() { 0x0000FFFF, 1, 0, 17 },
+    Package() { 0x0000FFFF, 2, 0, 18 },
+    Package() { 0x0000FFFF, 3, 0, 19 },
+})
+
+Name (AH07, Package() {
+    // [SL07]: PCI Express Slot 7 on 3A on PCI0
+    Package() { 0x0000FFFF, 0, 0, 40 },
+    Package() { 0x0000FFFF, 1, 0, 44 },
+    Package() { 0x0000FFFF, 2, 0, 45 },
+    Package() { 0x0000FFFF, 3, 0, 46 },
+})
+
+Name (PR08, Package() {
+    // [SL08]: PCI Express Slot 8 on 3B on PCI0
+    Package() { 0x0000FFFF, 0, \_SB.PCI0.LPC0.LNKA, 0 },
+    Package() { 0x0000FFFF, 1, \_SB.PCI0.LPC0.LNKB, 0 },
+    Package() { 0x0000FFFF, 2, \_SB.PCI0.LPC0.LNKC, 0 },
+    Package() { 0x0000FFFF, 3, \_SB.PCI0.LPC0.LNKD, 0 },
+})
+
+Name (AR08, Package() {
+    // [SL08]: PCI Express Slot 8 on 3B on PCI0
+    Package() { 0x0000FFFF, 0, 0, 16 },
+    Package() { 0x0000FFFF, 1, 0, 17 },
+    Package() { 0x0000FFFF, 2, 0, 18 },
+    Package() { 0x0000FFFF, 3, 0, 19 },
+})
+
+Name (AH08, Package() {
+    // [SL08]: PCI Express Slot 8 on 3B on PCI0
+    Package() { 0x0000FFFF, 0, 0, 41 },
+    Package() { 0x0000FFFF, 1, 0, 45 },
+    Package() { 0x0000FFFF, 2, 0, 46 },
+    Package() { 0x0000FFFF, 3, 0, 44 },
+})
+
+Name (PR09, Package() {
+    // [SL09]: PCI Express Slot 9 on 3C on PCI0
+    Package() { 0x0000FFFF, 0, \_SB.PCI0.LPC0.LNKA, 0 },
+    Package() { 0x0000FFFF, 1, \_SB.PCI0.LPC0.LNKB, 0 },
+    Package() { 0x0000FFFF, 2, \_SB.PCI0.LPC0.LNKC, 0 },
+    Package() { 0x0000FFFF, 3, \_SB.PCI0.LPC0.LNKD, 0 },
+})
+
+Name (AR09, Package() {
+    // [SL09]: PCI Express Slot 9 on 3C on PCI0
+    Package() { 0x0000FFFF, 0, 0, 16 },
+    Package() { 0x0000FFFF, 1, 0, 17 },
+    Package() { 0x0000FFFF, 2, 0, 18 },
+    Package() { 0x0000FFFF, 3, 0, 19 },
+})
+
+Name (AH09, Package() {
+    // [SL09]: PCI Express Slot 9 on 3C on PCI0
+    Package() { 0x0000FFFF, 0, 0, 42 },
+    Package() { 0x0000FFFF, 1, 0, 45 },
+    Package() { 0x0000FFFF, 2, 0, 44 },
+    Package() { 0x0000FFFF, 3, 0, 46 },
+})
+
+Name (PR0A, Package() {
+    // [SL0A]: PCI Express Slot 10 on 3D on PCI0
+    Package() { 0x0000FFFF, 0, \_SB.PCI0.LPC0.LNKA, 0 },
+    Package() { 0x0000FFFF, 1, \_SB.PCI0.LPC0.LNKB, 0 },
+    Package() { 0x0000FFFF, 2, \_SB.PCI0.LPC0.LNKC, 0 },
+    Package() { 0x0000FFFF, 3, \_SB.PCI0.LPC0.LNKD, 0 },
+})
+
+Name (AR0A, Package() {
+    // [SL0A]: PCI Express Slot 10 on 3D on PCI0
+    Package() { 0x0000FFFF, 0, 0, 16 },
+    Package() { 0x0000FFFF, 1, 0, 17 },
+    Package() { 0x0000FFFF, 2, 0, 18 },
+    Package() { 0x0000FFFF, 3, 0, 19 },
+})
+
+Name (AH0A, Package() {
+    // [SL0A]: PCI Express Slot 10 on 3D on PCI0
+    Package() { 0x0000FFFF, 0, 0, 43 },
+    Package() { 0x0000FFFF, 1, 0, 44 },
+    Package() { 0x0000FFFF, 2, 0, 46 },
+    Package() { 0x0000FFFF, 3, 0, 45 },
+})
+
+
+ // PCI Express Port 1A on PCI0
+Device (BR1A) {
+    Name   (_ADR, 0x00010000)
+    Method (_PRW, 0) {
+        Return (Package (0x02) {0x09, 0x04})
+    }
+    Method (_PRT, 0) {
+        If (LEqual(PICM, Zero)) {
+            Return (PR01)
+        }
+        If (LEqual(APC1, One)) {
+            Return (AH01)
+        }
+        Return (AR01)
+    }
+
+}
+
+// PCI Express Port 1B on PCI0
+Device (BR1B) {
+    Name   (_ADR, 0x00010001)
+    Method (_PRW, 0) {
+        Return (Package (0x02) {0x09, 0x04})
+    }
+    Method (_PRT, 0) {
+        If (LEqual(PICM, Zero)) {
+            Return (PR02)
+        }
+        If (LEqual(APC1, One)) {
+            Return (AH02)
+        }
+        Return (AR02)
+    }
+
+}
+
+// PCI Express Port 2A on PCI0
+Device (BR2A) {
+    Name   (_ADR, 0x00020000)
+    Method (_PRW, 0) {
+        Return (Package (0x02) {0x09, 0x04})
+    }
+    Method (_PRT, 0) {
+        If (LEqual(PICM, Zero)) {
+            Return (PR03)
+        }
+        If (LEqual(APC1, One)) {
+            Return (AH03)
+        }
+        Return (AR03)
+    }
+
+
+    // CB3DMA on IOSF
+    Device (CB0I) {
+        Name   (_ADR, 0x00000000)
+    }
+
+    // CB3DMA on IOSF
+    Device (CB0J) {
+        Name   (_ADR, 0x00000001)
+    }
+
+    // CB3DMA on IOSF
+    Device (CB0K) {
+        Name   (_ADR, 0x00000002)
+    }
+
+    // CB3DMA on IOSF
+    Device (CB0L) {
+        Name   (_ADR, 0x00000003)
+    }
+}
+
+// PCI Express Port 2B on PCI0
+Device (BR2B) {
+    Name   (_ADR, 0x00020001)
+    Method (_PRW, 0) {
+        Return (Package (0x02) {0x09, 0x04})
+    }
+    Method (_PRT, 0) {
+        If (LEqual(PICM, Zero)) {
+            Return (PR04)
+        }
+        If (LEqual(APC1, One)) {
+            Return (AH04)
+        }
+        Return (AR04)
+    }
+
+}
+
+// PCI Express Port 2C on PCI0
+Device (BR2C) {
+    Name   (_ADR, 0x00020002)
+    Method (_PRW, 0) {
+        Return (Package (0x02) {0x09, 0x04})
+    }
+    Method (_PRT, 0) {
+        If (LEqual(PICM, Zero)) {
+            Return (PR05)
+        }
+        If (LEqual(APC1, One)) {
+            Return (AH05)
+        }
+        Return (AR05)
+    }
+
+}
+
+// PCI Express Port 2D on PCI0
+Device (BR2D) {
+    Name   (_ADR, 0x00020003)
+    Method (_PRW, 0) {
+        Return (Package (0x02) {0x09, 0x04})
+    }
+    Method (_PRT, 0) {
+        If (LEqual(PICM, Zero)) {
+            Return (PR06)
+        }
+        If (LEqual(APC1, One)) {
+            Return (AH06)
+        }
+        Return (AR06)
+    }
+
+}
+
+// PCI Express Port 3A on PCI0
+Device (BR3A) {
+    Name   (_ADR, 0x00030000)
+    Method (_PRW, 0) {
+        Return (Package (0x02) {0x09, 0x04})
+    }
+    Method (_PRT, 0) {
+        If (LEqual(PICM, Zero)) {
+            Return (PR07)
+        }
+        If (LEqual(APC1, One)) {
+            Return (AH07)
+        }
+        Return (AR07)
+    }
+
+}
+
+// PCI Express Port 3B on PCI0
+Device (BR3B) {
+    Name   (_ADR, 0x00030001)
+    Method (_PRW, 0) {
+        Return (Package (0x02) {0x09, 0x04})
+    }
+    Method (_PRT, 0) {
+        If (LEqual(PICM, Zero)) {
+            Return (PR08)
+        }
+        If (LEqual(APC1, One)) {
+            Return (AH08)
+        }
+        Return (AR08)
+    }
+
+}
+
+// PCI Express Port 3C on PCI0
+Device (BR3C) {
+    Name   (_ADR, 0x00030002)
+    Method (_PRW, 0) {
+        Return (Package (0x02) {0x09, 0x04})
+    }
+    Method (_PRT, 0) {
+        If (LEqual(PICM, Zero)) {
+            Return (PR09)
+        }
+        If (LEqual(APC1, One)) {
+            Return (AH09)
+        }
+        Return (AR09)
+    }
+
+}
+
+// PCI Express Port 3D on PCI0
+Device (BR3D) {
+    Name   (_ADR, 0x00030003)
+    Method (_PRW, 0) {
+        Return (Package (0x02) {0x09, 0x04})
+    }
+    Method (_PRT, 0) {
+        If (LEqual(PICM, Zero)) {
+            Return (PR0A)
+        }
+        If (LEqual(APC1, One)) {
+            Return (AH0A)
+        }
+        Return (AR0A)
+    }
+
+}
diff --git a/src/soc/intel/fsp_broadwell_de/acpi/southcluster.asl b/src/soc/intel/fsp_broadwell_de/acpi/southcluster.asl
new file mode 100644
index 0000000..fa83f59
--- /dev/null
+++ b/src/soc/intel/fsp_broadwell_de/acpi/southcluster.asl
@@ -0,0 +1,350 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corp.
+ *
+ * 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.
+ */
+
+#include <soc/iomap.h>
+#include <soc/irq.h>
+
+Name(_HID,EISAID("PNP0A08"))	// PCIe
+Name(_CID,EISAID("PNP0A03"))	// PCI
+
+Name(_ADR, 0)
+Name(_BBN, 0)
+
+Name (MCRS, ResourceTemplate() {
+	// Bus Numbers
+	WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode,
+		0x0000, 0x0000, 0x00fe, 0x0000, 0xff,,, 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, 0xefff, 0x0000, 0xE300,,, PI01)
+
+	// VGA memory (0xa0000-0xbffff)
+	DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
+		Cacheable, ReadWrite,
+		0x00000000, 0x000a0000, 0x000bffff, 0x00000000,
+		0x00020000,,, ASEG)
+
+	// OPROM reserved (0xc0000-0xc3fff)
+	DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
+		Cacheable, ReadWrite,
+		0x00000000, 0x000c0000, 0x000c3fff, 0x00000000,
+		0x00004000,,, OPR0)
+
+	// OPROM reserved (0xc4000-0xc7fff)
+	DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
+		Cacheable, ReadWrite,
+		0x00000000, 0x000c4000, 0x000c7fff, 0x00000000,
+		0x00004000,,, OPR1)
+
+	// OPROM reserved (0xc8000-0xcbfff)
+	DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
+		Cacheable, ReadWrite,
+		0x00000000, 0x000c8000, 0x000cbfff, 0x00000000,
+		0x00004000,,, OPR2)
+
+	// OPROM reserved (0xcc000-0xcffff)
+	DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
+		Cacheable, ReadWrite,
+		0x00000000, 0x000cc000, 0x000cffff, 0x00000000,
+		0x00004000,,, OPR3)
+
+	// OPROM reserved (0xd0000-0xd3fff)
+	DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
+		Cacheable, ReadWrite,
+		0x00000000, 0x000d0000, 0x000d3fff, 0x00000000,
+		0x00004000,,, OPR4)
+
+	// OPROM reserved (0xd4000-0xd7fff)
+	DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
+		Cacheable, ReadWrite,
+		0x00000000, 0x000d4000, 0x000d7fff, 0x00000000,
+		0x00004000,,, OPR5)
+
+	// OPROM reserved (0xd8000-0xdbfff)
+	DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
+		Cacheable, ReadWrite,
+		0x00000000, 0x000d8000, 0x000dbfff, 0x00000000,
+		0x00004000,,, OPR6)
+
+	// OPROM reserved (0xdc000-0xdffff)
+	DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
+		Cacheable, ReadWrite,
+		0x00000000, 0x000dc000, 0x000dffff, 0x00000000,
+		0x00004000,,, OPR7)
+
+	// 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-0xfeafffff)
+	DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
+		Cacheable, ReadWrite,
+		0x00000000, 0x90000000, 0xFEAFFFFF, 0x00000000,
+		0x6EB00000,,, PMEM)
+
+	DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
+		Cacheable, ReadWrite,
+		0x00000000, 0xfec00000, 0xfecfffff, 0x00000000,
+		0x00100000,,, APIC)
+
+	DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
+		Cacheable, ReadWrite,
+		0x00000000, 0xfed00000, 0xfedfffff, 0x00000000,
+		0x00100000,,, PCHR)
+
+	QWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, NonCacheable, ReadWrite,
+		0x0000000000000000, // Granularity
+		0x0000380000000000, // Range Minimum
+		0x0000383FFFFFFFFF, // Range Maximum
+		0x0000000000000000, // Translation Offset
+		0x0000004000000000, // Length
+		,,, AddressRangeMemory, TypeStatic)
+})
+
+Method (_CRS, 0, Serialized) {
+	Return (MCRS)
+}
+
+/* Device Resource Consumption */
+Device (PDRC) {
+	Name (_HID, EISAID("PNP0C02"))
+	Name (_UID, 1)
+
+	Name (PDRS, ResourceTemplate() {
+		Memory32Fixed(ReadWrite, ABORT_BASE_ADDRESS,    ABORT_BASE_SIZE)
+		Memory32Fixed(ReadWrite, PSEG_BASE_ADDRESS,     PSEG_BASE_SIZE)
+		Memory32Fixed(ReadWrite, IOXAPIC1_BASE_ADDRESS, IOXAPIC1_BASE_SIZE)
+		Memory32Fixed(ReadWrite, IOXAPIC2_BASE_ADDRESS, IOXAPIC2_BASE_SIZE)
+		Memory32Fixed(ReadWrite, PCH_BASE_ADDRESS,      PCH_BASE_SIZE)
+		Memory32Fixed(ReadWrite, LXAPIC_BASE_ADDRESS,   LXAPIC_BASE_SIZE)
+		Memory32Fixed(ReadWrite, FIRMWARE_BASE_ADDRESS, FIRMWARE_BASE_SIZE)
+	})
+
+	// Current Resource Settings
+	Method (_CRS, 0, Serialized)
+	{
+		Return(PDRS)
+	}
+}
+
+Method (_OSC, 4) {
+	/* Check for proper GUID */
+	If (LEqual (Arg0, ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766")))
+	{
+		/* Let OS control everything */
+		Return (Arg3)
+	}
+	Else
+	{
+		/* Unrecognized UUID */
+		CreateDWordField (Arg3, 0, CDW1)
+		Or (CDW1, 4, CDW1)
+		Return (Arg3)
+	}
+}
+
+Name (PR00, Package() {
+	// [DMI0]: Legacy PCI Express Port 0 on PCI0
+	Package() { 0x0000FFFF, 0, \_SB.PCI0.LPC0.LNKA, 0 },
+	// [BR1A]: PCI Express Port 1A on PCI0
+	// [BR1B]: PCI Express Port 1B on PCI0
+	Package() { 0x0001FFFF, 0, \_SB.PCI0.LPC0.LNKA, 0 },
+	// [BR2A]: PCI Express Port 2A on PCI0
+	// [BR2B]: PCI Express Port 2B on PCI0
+	// [BR2C]: PCI Express Port 2C on PCI0
+	// [BR2D]: PCI Express Port 2D on PCI0
+	Package() { 0x0002FFFF, 0, \_SB.PCI0.LPC0.LNKA, 0 },
+	// [BR3A]: PCI Express Port 3A on PCI0
+	// [BR3B]: PCI Express Port 3B on PCI0
+	// [BR3C]: PCI Express Port 3C on PCI0
+	// [BR3D]: PCI Express Port 3D on PCI0
+	Package() { 0x0003FFFF, 0, \_SB.PCI0.LPC0.LNKA, 0 },
+	// [CB0A]: CB3DMA on PCI0
+	// [CB0E]: CB3DMA on PCI0
+	Package() { 0x0004FFFF, 0, \_SB.PCI0.LPC0.LNKA, 0 },
+	// [CB0B]: CB3DMA on PCI0
+	// [CB0F]: CB3DMA on PCI0
+	Package() { 0x0004FFFF, 1, \_SB.PCI0.LPC0.LNKB, 0 },
+	// [CB0C]: CB3DMA on PCI0
+	// [CB0G]: CB3DMA on PCI0
+	Package() { 0x0004FFFF, 2, \_SB.PCI0.LPC0.LNKC, 0 },
+	// [CB0D]: CB3DMA on PCI0
+	// [CB0H]: CB3DMA on PCI0
+	Package() { 0x0004FFFF, 3, \_SB.PCI0.LPC0.LNKD, 0 },
+	// [IIM0]: IIOMISC on PCI0
+	Package() { 0x0005FFFF, 0, \_SB.PCI0.LPC0.LNKA, 0 },
+	Package() { 0x0005FFFF, 1, \_SB.PCI0.LPC0.LNKB, 0 },
+	Package() { 0x0005FFFF, 2, \_SB.PCI0.LPC0.LNKC, 0 },
+	Package() { 0x0005FFFF, 3, \_SB.PCI0.LPC0.LNKD, 0 },
+	// [IID0]: IIODFX0 on PCI0
+	Package() { 0x0006FFFF, 0, \_SB.PCI0.LPC0.LNKA, 0 },
+	Package() { 0x0006FFFF, 1, \_SB.PCI0.LPC0.LNKB, 0 },
+	Package() { 0x0006FFFF, 2, \_SB.PCI0.LPC0.LNKC, 0 },
+	Package() { 0x0006FFFF, 3, \_SB.PCI0.LPC0.LNKD, 0 },
+	// [XHCI]: xHCI controller 1 on PCH
+	Package() { 0x0014FFFF, 3, \_SB.PCI0.LPC0.LNKD, 0 },
+	// [HECI]: ME HECI on PCH
+	// [IDER]: ME IDE redirect on PCH
+	Package() { 0x0016FFFF, 0, \_SB.PCI0.LPC0.LNKA, 0 },
+	// [HEC2]: ME HECI2 on PCH
+	// [MEKT]: MEKT on PCH
+	Package() { 0x0016FFFF, 1, \_SB.PCI0.LPC0.LNKB, 0 },
+	// [GBEM]: GbE Controller VPRO
+	Package() { 0x0019FFFF, 0, \_SB.PCI0.LPC0.LNKE, 0 },
+	// [EHC2]: EHCI controller #2 on PCH
+	Package() { 0x001AFFFF, 2, \_SB.PCI0.LPC0.LNKC, 0 },
+	// [ALZA]: High definition Audio Controller
+	Package() { 0x001BFFFF, 0, \_SB.PCI0.LPC0.LNKG, 0 },
+	// [RP01]: Pci Express Port 1 on PCH
+	// [RP05]: Pci Express Port 5 on PCH
+	Package() { 0x001CFFFF, 0, \_SB.PCI0.LPC0.LNKA, 0 },
+	// [RP02]: Pci Express Port 2 on PCH
+	// [RP06]: Pci Express Port 6 on PCH
+	Package() { 0x001CFFFF, 1, \_SB.PCI0.LPC0.LNKB, 0 },
+	// [RP03]: Pci Express Port 3 on PCH
+	// [RP07]: Pci Express Port 7 on PCH
+	Package() { 0x001CFFFF, 2, \_SB.PCI0.LPC0.LNKC, 0 },
+	// [RP04]: Pci Express Port 4 on PCH
+	// [RP08]: Pci Express Port 8 on ICH
+	Package() { 0x001CFFFF, 3, \_SB.PCI0.LPC0.LNKD, 0 },
+	// [EHC1]: EHCI controller #1 on PCH
+	Package() { 0x001DFFFF, 2, \_SB.PCI0.LPC0.LNKC, 0 },
+	// [SAT1]: SATA controller 1 on PCH
+	// [SAT2]: SATA Host controller 2 on PCH
+	Package() { 0x001FFFFF, 0, \_SB.PCI0.LPC0.LNKA, 0 },
+	// [SMBS]: SMBus controller on PCH
+	// [TERM]: Thermal Subsystem on ICH
+	Package() { 0x001FFFFF, 2, \_SB.PCI0.LPC0.LNKC, 0 },
+})
+
+Name (AR00, Package() {
+	// [DMI0]: Legacy PCI Express Port 0 on PCI0
+	Package() { 0x0000FFFF, 0, 0, 47 },
+	// [BR1A]: PCI Express Port 1A on PCI0
+	// [BR1B]: PCI Express Port 1B on PCI0
+	Package() { 0x0001FFFF, 0, 0, 47 },
+	// [BR2A]: PCI Express Port 2A on PCI0
+	// [BR2B]: PCI Express Port 2B on PCI0
+	// [BR2C]: PCI Express Port 2C on PCI0
+	// [BR2D]: PCI Express Port 2D on PCI0
+	Package() { 0x0002FFFF, 0, 0, 47 },
+	// [BR3A]: PCI Express Port 3A on PCI0
+	// [BR3B]: PCI Express Port 3B on PCI0
+	// [BR3C]: PCI Express Port 3C on PCI0
+	// [BR3D]: PCI Express Port 3D on PCI0
+	Package() { 0x0003FFFF, 0, 0, 47 },
+	// [CB0A]: CB3DMA on PCI0
+	// [CB0E]: CB3DMA on PCI0
+	Package() { 0x0004FFFF, 0, 0, 31 },
+	// [CB0B]: CB3DMA on PCI0
+	// [CB0F]: CB3DMA on PCI0
+	Package() { 0x0004FFFF, 1, 0, 39 },
+	// [CB0C]: CB3DMA on PCI0
+	// [CB0G]: CB3DMA on PCI0
+	Package() { 0x0004FFFF, 2, 0, 31 },
+	// [CB0D]: CB3DMA on PCI0
+	// [CB0H]: CB3DMA on PCI0
+	Package() { 0x0004FFFF, 3, 0, 39 },
+	// [IIM0]: IIOMISC on PCI0
+	Package() { 0x0005FFFF, 0, 0, 16 },
+	Package() { 0x0005FFFF, 1, 0, 17 },
+	Package() { 0x0005FFFF, 2, 0, 18 },
+	Package() { 0x0005FFFF, 3, 0, 19 },
+	// [IID0]: IIODFX0 on PCI0
+	Package() { 0x0006FFFF, 0, 0, 16 },
+	Package() { 0x0006FFFF, 1, 0, 17 },
+	Package() { 0x0006FFFF, 2, 0, 18 },
+	Package() { 0x0006FFFF, 3, 0, 19 },
+	// [XHCI]: xHCI controller 1 on PCH
+	Package() { 0x0014FFFF, 3, 0, 19 },
+	// [HECI]: ME HECI on PCH
+	// [IDER]: ME IDE redirect on PCH
+	Package() { 0x0016FFFF, 0, 0, 16 },
+	// [HEC2]: ME HECI2 on PCH
+	// [MEKT]: MEKT on PCH
+	Package() { 0x0016FFFF, 1, 0, 17 },
+	// [GBEM]: GbE Controller VPRO
+	Package() { 0x0019FFFF, 0, 0, 20 },
+	// [EHC2]: EHCI controller #2 on PCH
+	Package() { 0x001AFFFF, 2, 0, 18 },
+	// [ALZA]: High definition Audio Controller
+	Package() { 0x001BFFFF, 0, 0, 22 },
+	// [RP01]: Pci Express Port 1 on PCH
+	// [RP05]: Pci Express Port 5 on PCH
+	Package() { 0x001CFFFF, 0, 0, 16 },
+	// [RP02]: Pci Express Port 2 on PCH
+	// [RP06]: Pci Express Port 6 on PCH
+	Package() { 0x001CFFFF, 1, 0, 17 },
+	// [RP03]: Pci Express Port 3 on PCH
+	// [RP07]: Pci Express Port 7 on PCH
+	Package() { 0x001CFFFF, 2, 0, 18 },
+	// [RP04]: Pci Express Port 4 on PCH
+	// [RP08]: Pci Express Port 8 on ICH
+	Package() { 0x001CFFFF, 3, 0, 19 },
+	// [EHC1]: EHCI controller #1 on PCH
+	Package() { 0x001DFFFF, 2, 0, 18 },
+	// [SAT1]: SATA controller 1 on PCH
+	// [SAT2]: SATA Host controller 2 on PCH
+	Package() { 0x001FFFFF, 0, 0, 16 },
+	// [SMBS]: SMBus controller on PCH
+	// [TERM]: Thermal Subsystem on ICH
+	Package() { 0x001FFFFF, 2, 0, 18 },
+})
+
+// Socket 0 Root bridge
+Method (_PRT, 0) {
+	If (LEqual(PICM, Zero)) {
+		Return (PR00)
+	}
+	Return (AR00) // If you disable the IOxAPIC in IIO, you should return AR00
+}
+
+#include "lpc.asl"
diff --git a/src/soc/intel/fsp_broadwell_de/bootblock/bootblock.c b/src/soc/intel/fsp_broadwell_de/bootblock/bootblock.c
new file mode 100644
index 0000000..c026c83
--- /dev/null
+++ b/src/soc/intel/fsp_broadwell_de/bootblock/bootblock.c
@@ -0,0 +1,23 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google, Inc.
+ * Copyright (C) 2015-2016 Intel Corp.
+ *
+ * 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 wacbmem_entryanty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <cpu/intel/microcode/microcode.c>
+
+static void bootblock_cpu_init(void)
+{
+	/* Load microcode before any caching. */
+	intel_update_microcode_from_cbfs();
+}
diff --git a/src/soc/intel/fsp_broadwell_de/chip.c b/src/soc/intel/fsp_broadwell_de/chip.c
new file mode 100644
index 0000000..78649fc
--- /dev/null
+++ b/src/soc/intel/fsp_broadwell_de/chip.c
@@ -0,0 +1,106 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corp.
+ *
+ * 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.
+ */
+
+#include <lib.h>
+#include <string.h>
+#include <bootstate.h>
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <drivers/intel/fsp1_0/fsp_util.h>
+#include <soc/pci_devs.h>
+#include <soc/ramstage.h>
+#include <chip.h>
+
+static void pci_domain_set_resources(device_t dev)
+{
+	assign_resources(dev->link_list);
+}
+
+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 struct device_operations cpu_bus_ops = {
+	.read_resources   = DEVICE_NOOP,
+	.set_resources    = DEVICE_NOOP,
+	.enable_resources = DEVICE_NOOP,
+	.init             = broadwell_de_init_cpus,
+	.scan_bus         = NULL,
+};
+
+static void enable_dev(device_t dev)
+{
+	printk(BIOS_DEBUG, "enable_dev(%s, %d)\n",
+	       dev_name(dev), dev->path.type);
+
+	/* 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;
+	} else if (dev->path.type == DEVICE_PATH_PCI) {
+		/* Handle south cluster enablement. */
+		if (PCI_SLOT(dev->path.pci.devfn) > 0 &&
+		    (dev->ops == NULL || dev->ops->enable == NULL)) {
+			southcluster_enable_dev(dev);
+		}
+	}
+}
+
+static void fsp_notify(void *arg)
+{
+	FspNotify (*(uint32_t *)arg);
+}
+
+static uint32_t gFspNotifyAfterPciEnumeration = EnumInitPhaseAfterPciEnumeration;
+static uint32_t gFspNotifyReadtToBoot         = EnumInitPhaseReadyToBoot;
+static BOOT_STATE_CALLBACK(bscb_fspnotify1, fsp_notify, &gFspNotifyAfterPciEnumeration);
+static BOOT_STATE_CALLBACK(bscb_fspnotify2, fsp_notify, &gFspNotifyReadtToBoot);
+
+/* Called at BS_DEV_INIT_CHIPS time -- very early. Just after BS_PRE_DEVICE. */
+static void soc_init(void *chip_info)
+{
+	boot_state_sched_on_exit(&bscb_fspnotify1, BS_DEV_RESOURCES);
+	boot_state_sched_on_exit(&bscb_fspnotify2, BS_PAYLOAD_LOAD);
+	broadwell_de_init_pre_device();
+}
+
+struct chip_operations soc_intel_fsp_broadwell_de_ops = {
+	CHIP_NAME("Intel(R) Xeon(R) Processor D-1500 Product Family")
+	.enable_dev = enable_dev,
+	.init = soc_init,
+};
+
+static void pci_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));
+	}
+}
+
+struct pci_operations soc_pci_ops = {
+	.set_subsystem = &pci_set_subsystem,
+};
diff --git a/src/soc/intel/fsp_broadwell_de/chip.h b/src/soc/intel/fsp_broadwell_de/chip.h
new file mode 100644
index 0000000..ed01c89
--- /dev/null
+++ b/src/soc/intel/fsp_broadwell_de/chip.h
@@ -0,0 +1,29 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corp.
+ *
+ * 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.
+ */
+
+#ifndef _SOC_CHIP_H_
+#define _SOC_CHIP_H_
+
+#include <arch/acpi.h>
+
+/* The devicetree parser expects chip.h to reside directly in the path
+ * specified by the devicetree. */
+
+struct soc_intel_fsp_broadwell_de_config {
+};
+
+extern struct chip_operations soc_intel_fsp_broadwell_de_ops;
+#endif /* _SOC_CHIP_H_ */
diff --git a/src/soc/intel/fsp_broadwell_de/cpu.c b/src/soc/intel/fsp_broadwell_de/cpu.c
new file mode 100644
index 0000000..173e978
--- /dev/null
+++ b/src/soc/intel/fsp_broadwell_de/cpu.c
@@ -0,0 +1,110 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corp.
+ *
+ * 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.
+ */
+
+#include <stdlib.h>
+#include <console/console.h>
+#include <cpu/cpu.h>
+#include <cpu/intel/microcode.h>
+#include <cpu/x86/cache.h>
+#include <cpu/x86/lapic.h>
+#include <cpu/x86/mp.h>
+#include <cpu/x86/msr.h>
+#include <cpu/x86/mtrr.h>
+#include <soc/msr.h>
+#include <soc/pattrs.h>
+#include <soc/ramstage.h>
+
+static void configure_mca(void);
+
+static struct mp_flight_record mp_steps[] = {
+	MP_FR_BLOCK_APS(mp_initialize_cpu, NULL, mp_initialize_cpu, NULL),
+};
+
+static int adjust_apic_id(int index, int apic_id)
+{
+	return index;
+}
+
+static void configure_mca(void)
+{
+	msr_t msr;
+	const unsigned int mcg_cap_msr = 0x179;
+	int i;
+	int num_banks;
+
+	msr = rdmsr(mcg_cap_msr);
+	num_banks = msr.lo & 0xff;
+
+	/* TODO(adurbin): This should only be done on a cold boot. Also, some
+	 * of these banks are core vs package scope. For now every CPU clears
+	 * every bank. */
+	msr.lo = msr.hi = 0;
+	for (i = 0; i < num_banks; i++) {
+		wrmsr(MSR_IA32_MC0_STATUS + (i * 4) + 1, msr);
+		wrmsr(MSR_IA32_MC0_STATUS + (i * 4) + 2, msr);
+		wrmsr(MSR_IA32_MC0_STATUS + (i * 4) + 3, msr);
+	}
+
+	msr.lo = msr.hi = 0xffffffff;
+	for (i = 0; i < num_banks; i++)
+		wrmsr(MSR_IA32_MC0_STATUS + (i * 4), msr);
+}
+
+void broadwell_de_init_cpus(device_t dev)
+{
+	struct bus *cpu_bus = dev->link_list;
+	const struct pattrs *pattrs = pattrs_get();
+	struct mp_params mp_params;
+
+	x86_mtrr_check();
+
+	/* Enable the local cpu apics */
+	setup_lapic();
+
+	mp_params.num_cpus = pattrs->num_cpus,
+	mp_params.parallel_microcode_load = 1,
+	mp_params.adjust_apic_id = adjust_apic_id;
+	mp_params.flight_plan = &mp_steps[0];
+	mp_params.num_records = ARRAY_SIZE(mp_steps);
+	mp_params.microcode_pointer = pattrs->microcode_patch;
+
+	if (mp_init(cpu_bus, &mp_params)) {
+		printk(BIOS_ERR, "MP initialization failure.\n");
+	}
+}
+
+static void broadwell_de_core_init(device_t cpu)
+{
+	printk(BIOS_DEBUG, "Init Broadwell-DE core.\n");
+	configure_mca();
+}
+
+static struct device_operations cpu_dev_ops = {
+	.init = broadwell_de_core_init,
+};
+
+static struct cpu_device_id cpu_table[] = {
+	{ X86_VENDOR_INTEL, 0x50661 },
+	{ X86_VENDOR_INTEL, 0x50662 },
+	{ X86_VENDOR_INTEL, 0x50663 },
+	{ X86_VENDOR_INTEL, 0x50664 },
+	{ 0, 0 },
+};
+
+static const struct cpu_driver driver __cpu_driver = {
+	.ops      = &cpu_dev_ops,
+	.id_table = cpu_table,
+};
diff --git a/src/soc/intel/fsp_broadwell_de/fsp/Kconfig b/src/soc/intel/fsp_broadwell_de/fsp/Kconfig
new file mode 100644
index 0000000..2e1ebeb
--- /dev/null
+++ b/src/soc/intel/fsp_broadwell_de/fsp/Kconfig
@@ -0,0 +1,93 @@
+config BROADWELL_DE_FSP_SPECIFIC_OPTIONS
+	def_bool y
+	select PLATFORM_USES_FSP1_0
+	select USE_GENERIC_FSP_CAR_INC
+	select FSP_USES_UPD
+
+config FSP_FILE
+	string
+	default "../intel/fsp/broadwell_de/BROADWELLDE_FSP.bin"
+	help
+	  The path and filename of the Intel FSP binary for this platform.
+
+config FSP_LOC
+	hex
+	default 0xffeb0000
+	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 Broadwell-DE FSP is built with a preferred base address of
+	  0xffeb0000.
+
+config FSP_MEMORY_DOWN
+	bool "Enable Memory Down"
+	default n
+	help
+	  Load SPD data from ROM instead of trying to read from SMBus.
+
+	  If the platform has DIMM sockets, say N. If memory is down, say Y and
+	  supply the appropriate SPD data for each Channel/DIMM.
+
+config FSP_MEMORY_DOWN_CH0DIMM0_SPD_PRESENT
+	bool "Channel 0, DIMM 0 Present"
+	default n
+	depends on FSP_MEMORY_DOWN
+	help
+	  Select Y if Channel 0, DIMM 0 is present.
+
+config FSP_MEMORY_DOWN_CH0DIMM0_SPD_FILE
+	string "Channel 0, DIMM 0 SPD File"
+	default "spd_ch0_dimm0.bin"
+	depends on FSP_MEMORY_DOWN_CH0DIMM0_SPD_PRESENT
+	help
+	  Path to the file which contains the SPD data for Channel 0, DIMM 0.
+
+config FSP_MEMORY_DOWN_CH0DIMM1_SPD_PRESENT
+	bool "Channel 0, DIMM 1 Present"
+	default n
+	depends on FSP_MEMORY_DOWN
+	help
+	  Select Y if Channel 0, DIMM 1 is present.
+
+config FSP_MEMORY_DOWN_CH0DIMM1_SPD_FILE
+	string "Channel 0, DIMM 1 SPD File"
+	default "spd_ch0_dimm1.bin"
+	depends on FSP_MEMORY_DOWN_CH0DIMM1_SPD_PRESENT
+	help
+	  Path to the file which contains the SPD data for Channel 0, DIMM 1.
+
+config FSP_MEMORY_DOWN_CH1DIMM0_SPD_PRESENT
+	bool "Channel 1, DIMM 0 Present"
+	default n
+	depends on FSP_MEMORY_DOWN
+	help
+	  Select Y if Channel 1, DIMM 0 is present.
+
+config FSP_MEMORY_DOWN_CH1DIMM0_SPD_FILE
+	string "Channel 1, DIMM 0 SPD File"
+	default "spd_ch1_dimm0.bin"
+	depends on FSP_MEMORY_DOWN_CH1DIMM0_SPD_PRESENT
+	help
+	  Path to the file which contains the SPD data for Channel 1, DIMM 0.
+
+config FSP_MEMORY_DOWN_CH1DIMM1_SPD_PRESENT
+	bool "Channel 1, DIMM 1 Present"
+	default n
+	depends on FSP_MEMORY_DOWN
+	help
+	  Select Y if Channel 1, DIMM 1 is present.
+
+config FSP_MEMORY_DOWN_CH1DIMM1_SPD_FILE
+	string "Channel 1, DIMM 1 SPD File"
+	default "spd_ch1_dimm1.bin"
+	depends on FSP_MEMORY_DOWN_CH1DIMM1_SPD_PRESENT
+	help
+	  Path to the file which contains the SPD data for Channel 1, DIMM 1.
+
+config FSP_HYPERTHREADING
+	bool "Enable Hyper-Threading"
+	default y
+	help
+	  Enable Intel(r) Hyper-Threading Technology for the Broadwell-DE SoC.
diff --git a/src/soc/intel/fsp_broadwell_de/fsp/Makefile.inc b/src/soc/intel/fsp_broadwell_de/fsp/Makefile.inc
new file mode 100644
index 0000000..6519764
--- /dev/null
+++ b/src/soc/intel/fsp_broadwell_de/fsp/Makefile.inc
@@ -0,0 +1,17 @@
+romstage-y += chipset_fsp_util.c
+
+cbfs-files-$(CONFIG_FSP_MEMORY_DOWN_CH0DIMM0_SPD_PRESENT) += spd_ch0_dimm0.bin
+spd_ch0_dimm0.bin-file := $(call strip_quotes,$(CONFIG_FSP_MEMORY_DOWN_CH0DIMM0_SPD_FILE))
+spd_ch0_dimm0.bin-type := spd
+
+cbfs-files-$(CONFIG_FSP_MEMORY_DOWN_CH0DIMM1_SPD_PRESENT) += spd_ch0_dimm1.bin
+spd_ch0_dimm1.bin-file := $(call strip_quotes,$(CONFIG_FSP_MEMORY_DOWN_CH0DIMM1_SPD_FILE))
+spd_ch0_dimm1.bin-type := spd
+
+cbfs-files-$(CONFIG_FSP_MEMORY_DOWN_CH1DIMM0_SPD_PRESENT) += spd_ch1_dimm0.bin
+spd_ch1_dimm0.bin-file := $(call strip_quotes,$(CONFIG_FSP_MEMORY_DOWN_CH1DIMM0_SPD_FILE))
+spd_ch1_dimm0.bin-type := spd
+
+cbfs-files-$(CONFIG_FSP_MEMORY_DOWN_CH1DIMM1_SPD_PRESENT) += spd_ch1_dimm1.bin
+spd_ch1_dimm1.bin-file := $(call strip_quotes,$(CONFIG_FSP_MEMORY_DOWN_CH1DIMM1_SPD_FILE))
+spd_ch1_dimm1.bin-type := spd
diff --git a/src/soc/intel/fsp_broadwell_de/fsp/chipset_fsp_util.c b/src/soc/intel/fsp_broadwell_de/fsp/chipset_fsp_util.c
new file mode 100644
index 0000000..cab4b59
--- /dev/null
+++ b/src/soc/intel/fsp_broadwell_de/fsp/chipset_fsp_util.c
@@ -0,0 +1,126 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013-2014 Sage Electronic Engineering, LLC.
+ * Copyright (C) 2015-2016 Intel Corporation. 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.
+ */
+
+#include <types.h>
+#include <string.h>
+#include <console/console.h>
+#include <bootstate.h>
+#include <cbfs.h>
+#include <cbmem.h>
+#include <device/device.h>
+#include <device/pci_def.h>
+#include <drivers/intel/fsp1_0/fsp_util.h>
+#include <soc/pci_devs.h>
+#include <soc/reset.h>
+#include <soc/romstage.h>
+#include <chip.h>
+#include <fsp.h>
+
+/* 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 soc_intel_fsp_broadwell_de_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)
+{
+	/*
+	 * Serial Port
+	 */
+	if (IS_ENABLED(CONFIG_INTEGRATED_UART))
+		UpdData->SerialPortConfigure = 1;
+
+	/*
+	 * Memory Down
+	 */
+	if (IS_ENABLED(CONFIG_FSP_MEMORY_DOWN)) {
+		UpdData->MemDownEnable = 1;
+
+		if (IS_ENABLED(CONFIG_FSP_MEMORY_DOWN_CH0DIMM0_SPD_PRESENT))
+			UpdData->MemDownCh0Dimm0SpdPtr
+			= (UINT32)cbfs_boot_map_with_leak("spd_ch0_dimm0.bin", CBFS_TYPE_RAW, NULL);
+		if (IS_ENABLED(CONFIG_FSP_MEMORY_DOWN_CH0DIMM1_SPD_PRESENT))
+			UpdData->MemDownCh0Dimm1SpdPtr
+			= (UINT32)cbfs_boot_map_with_leak("spd_ch0_dimm1.bin", CBFS_TYPE_RAW, NULL);
+		if (IS_ENABLED(CONFIG_FSP_MEMORY_DOWN_CH1DIMM0_SPD_PRESENT))
+			UpdData->MemDownCh1Dimm0SpdPtr
+			= (UINT32)cbfs_boot_map_with_leak("spd_ch1_dimm0.bin", CBFS_TYPE_RAW, NULL);
+		if (IS_ENABLED(CONFIG_FSP_MEMORY_DOWN_CH1DIMM1_SPD_PRESENT))
+			UpdData->MemDownCh1Dimm1SpdPtr
+			= (UINT32)cbfs_boot_map_with_leak("spd_ch1_dimm1.bin", CBFS_TYPE_RAW, NULL);
+	} else {
+		UpdData->MemDownEnable = 0;
+	}
+	printk(FSP_INFO_LEVEL, "Memory Down Support: %s\n",
+		UpdData->MemDownEnable ? "Enabled" : "Disabled");
+
+	/*
+	 * Fast Boot
+	 */
+	if (IS_ENABLED(CONFIG_ENABLE_MRC_CACHE))
+		UpdData->MemFastBoot = 1;
+	else
+		UpdData->MemFastBoot = 0;
+
+	/*
+	 * Hyper-Threading
+	 */
+	if (IS_ENABLED(CONFIG_FSP_HYPERTHREADING))
+		UpdData->HyperThreading = 1;
+	else
+		UpdData->HyperThreading = 0;
+}
+
+/* Set up the Broadwell-DE 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;
+
+#if IS_ENABLED(CONFIG_ENABLE_MRC_CACHE)
+	/* Find the fastboot cache that was saved in the ROM */
+	pFspInitParams->NvsBufferPtr = find_and_set_fastboot_cache();
+#endif
+
+	return;
+}
+
+/* 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) {
+		warm_reset();
+	}
+
+	romstage_main_continue(Status, HobListPtr);
+}
diff --git a/src/soc/intel/fsp_broadwell_de/fsp/chipset_fsp_util.h b/src/soc/intel/fsp_broadwell_de/fsp/chipset_fsp_util.h
new file mode 100644
index 0000000..057d7fd
--- /dev/null
+++ b/src/soc/intel/fsp_broadwell_de/fsp/chipset_fsp_util.h
@@ -0,0 +1,35 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013-2014 Sage Electronic Engineering, LLC.
+ * Copyright (C) 2015-2016 Intel Corporation
+ *
+ * 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.
+ */
+
+#ifndef CHIPSET_FSP_UTIL_H
+#define CHIPSET_FSP_UTIL_H
+
+#include <fsp.h>
+
+#define FSP_INFO_HEADER_GUID \
+  { \
+  0x912740BE, 0x2284, 0x4734, {0xB9, 0x71, 0x84, 0xB0, 0x27, 0x35, 0x3F, 0x0C} \
+  }
+
+/*
+ * 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 Broadwell-DE FSP, the Image Id is "BDX-DE".
+ */
+#define FSP_IMAGE_ID_DWORD0 ((unsigned int)(FSP_IMAGE_ID))
+#define FSP_IMAGE_ID_DWORD1 ((unsigned int)(FSP_IMAGE_ID >> 32))
+
+#endif /* CHIPSET_FSP_UTIL_H */
diff --git a/src/soc/intel/fsp_broadwell_de/include/soc/acpi.h b/src/soc/intel/fsp_broadwell_de/include/soc/acpi.h
new file mode 100644
index 0000000..f717d15
--- /dev/null
+++ b/src/soc/intel/fsp_broadwell_de/include/soc/acpi.h
@@ -0,0 +1,27 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google, Inc.
+ * Copyright (C) 2015-2016 Intel Corp.
+ *
+ * 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.
+ */
+
+#ifndef _SOC_ACPI_H_
+#define _SOC_ACPI_H_
+
+#include <arch/acpi.h>
+
+void acpi_create_intel_hpet(acpi_hpet_t *hpet);
+void acpi_fill_in_fadt(acpi_fadt_t *fadt, acpi_facs_t *facs, void *dsdt);
+unsigned long acpi_madt_irq_overrides(unsigned long current);
+uint16_t get_pmbase(void);
+
+#endif /* _SOC_ACPI_H_ */
diff --git a/src/soc/intel/fsp_broadwell_de/include/soc/broadwell_de.h b/src/soc/intel/fsp_broadwell_de/include/soc/broadwell_de.h
new file mode 100644
index 0000000..6828d03
--- /dev/null
+++ b/src/soc/intel/fsp_broadwell_de/include/soc/broadwell_de.h
@@ -0,0 +1,20 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google, Inc.
+ * Copyright (C) 2015-2016 Intel Corp.
+ *
+ * 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.
+ */
+
+#ifndef _SOC_BROADWELL_DE_H_
+#define _SOC_BROADWELL_DE_H_
+
+#endif /* _SOC_BROADWELL_DE_H_ */
diff --git a/src/soc/intel/fsp_broadwell_de/include/soc/iomap.h b/src/soc/intel/fsp_broadwell_de/include/soc/iomap.h
new file mode 100644
index 0000000..ca84299
--- /dev/null
+++ b/src/soc/intel/fsp_broadwell_de/include/soc/iomap.h
@@ -0,0 +1,66 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corp.
+ *
+ * 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.
+ */
+
+#ifndef _SOC_IOMAP_H_
+#define _SOC_IOMAP_H_
+
+/*
+ * Memory Mapped IO bases.
+ */
+
+/* PCI Configuration Space */
+#define MCFG_BASE_ADDRESS        CONFIG_MMCONF_BASE_ADDRESS
+#define MCFG_BASE_SIZE           0x10000000
+
+/* Transactions in this range will abort */
+#define ABORT_BASE_ADDRESS       0xfeb00000
+#define ABORT_BASE_SIZE          0x00010000
+
+/* PSEG */
+#define PSEG_BASE_ADDRESS        0xfeb80000
+#define PSEG_BASE_SIZE           0x00080000
+
+/* IOxAPIC */
+#define IOXAPIC1_BASE_ADDRESS    0xfec00000
+#define IOXAPIC1_BASE_SIZE       0x00100000
+#define IOXAPIC2_BASE_ADDRESS    0xfec01000
+#define IOXAPIC2_BASE_SIZE       0x00100000
+
+/* PCH (HPET/LT/TPM/Others) */
+#define PCH_BASE_ADDRESS         0xfed00000
+#define PCH_BASE_SIZE            0x00100000
+
+/* Local XAPIC */
+#define LXAPIC_BASE_ADDRESS      0xfee00000
+#define LXAPIC_BASE_SIZE         0x00100000
+
+/* High Performance Event Timer */
+#define HPET_BASE_ADDRESS        0xfed00000
+#define HPET_BASE_SIZE           0x400
+
+/* Firmware */
+#define FIRMWARE_BASE_ADDRESS    0xff000000
+#define FIRMWARE_BASE_SIZE       0x01000000
+
+/*
+ * IO Port bases.
+ */
+
+/* ACPI Base Address */
+#define ACPI_BASE_ADDRESS        0x400
+#define ACPI_BASE_SIZE           0x80
+
+#endif /* _SOC_IOMAP_H_ */
diff --git a/src/soc/intel/fsp_broadwell_de/include/soc/irq.h b/src/soc/intel/fsp_broadwell_de/include/soc/irq.h
new file mode 100644
index 0000000..ea04326
--- /dev/null
+++ b/src/soc/intel/fsp_broadwell_de/include/soc/irq.h
@@ -0,0 +1,88 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corp.
+ *
+ * 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.
+ */
+
+#ifndef _SOC_IRQ_H_
+#define _SOC_IRQ_H_
+
+#define PIRQA_APIC_IRQ 16
+#define PIRQB_APIC_IRQ 17
+#define PIRQC_APIC_IRQ 18
+#define PIRQD_APIC_IRQ 19
+#define PIRQE_APIC_IRQ 20
+#define PIRQF_APIC_IRQ 21
+#define PIRQG_APIC_IRQ 22
+#define PIRQH_APIC_IRQ 23
+
+/* PIC IRQ settings. */
+#define PIRQ_PIC_IRQ3           0x3
+#define PIRQ_PIC_IRQ4           0x4
+#define PIRQ_PIC_IRQ5           0x5
+#define PIRQ_PIC_IRQ6           0x6
+#define PIRQ_PIC_IRQ7           0x7
+#define PIRQ_PIC_IRQ9           0x9
+#define PIRQ_PIC_IRQ10          0xa
+#define PIRQ_PIC_IRQ11          0xb
+#define PIRQ_PIC_IRQ12          0xc
+#define PIRQ_PIC_IRQ14          0xe
+#define PIRQ_PIC_IRQ15          0xf
+#define PIRQ_PIC_IRQDISABLE     0x80
+#define PIRQ_PIC_UNKNOWN_UNUSED 0xff
+
+/* Overloaded term, but these values determine the per device route. */
+#define PIRQA 0
+#define PIRQB 1
+#define PIRQC 2
+#define PIRQD 3
+#define PIRQE 4
+#define PIRQF 5
+#define PIRQG 6
+#define PIRQH 7
+
+/* In each mainboard directory there should exist a header file irqroute.h that
+ * defines the PCI_DEV_PIRQ_ROUTES and PIRQ_PIC_ROUTES macros which
+ * consist of PCI_DEV_PIRQ_ROUTE and PIRQ_PIC entries. */
+
+#if !defined(__ASSEMBLER__) && !defined(__ACPI__)
+#include <stdint.h>
+
+#define NUM_OF_PCI_DEVS 32
+#define NUM_PIRQS   8
+
+struct broadwell_de_irq_route {
+	/* Per device configuration. */
+	uint16_t pcidev[NUM_OF_PCI_DEVS];
+	/* Route path for each internal PIRQx in PIC mode. */
+	uint8_t  pic[NUM_PIRQS];
+};
+
+extern const struct broadwell_de_irq_route global_broadwell_de_irq_route;
+
+#define DEFINE_IRQ_ROUTES \
+	const struct broadwell_de_irq_route global_broadwell_de_irq_route = { \
+		.pcidev = { PCI_DEV_PIRQ_ROUTES, }, \
+		.pic = { PIRQ_PIC_ROUTES, }, \
+	}
+
+#define PCI_DEV_PIRQ_ROUTE(dev_, a_, b_, c_, d_) \
+	[dev_] = ((PIRQ ## d_) << 12) | ((PIRQ ## c_) << 8) | \
+	         ((PIRQ ## b_) <<  4) | ((PIRQ ## a_) << 0)
+
+#define PIRQ_PIC(pirq_, pic_irq_) \
+	[PIRQ ## pirq_] = PIRQ_PIC_IRQ ## pic_irq_
+
+#endif /* !defined(__ASSEMBLER__) && !defined(__ACPI__) */
+
+#endif /* _SOC_IRQ_H_ */
diff --git a/src/soc/intel/fsp_broadwell_de/include/soc/lpc.h b/src/soc/intel/fsp_broadwell_de/include/soc/lpc.h
new file mode 100644
index 0000000..2c02ebd
--- /dev/null
+++ b/src/soc/intel/fsp_broadwell_de/include/soc/lpc.h
@@ -0,0 +1,86 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corp.
+ *
+ * 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.
+ */
+
+#ifndef _SOC_LPC_H_
+#define _SOC_LPC_H_
+
+/* LPC Interface Bridge PCI Configuration Registers */
+#define REVID			0x08
+#define PIRQ_RCR1		0x60
+#define PIRQ_RCR2		0x68
+#define GEN_PMCON_1		0xA0
+#define GEN_PMCON_2		0xA2
+#define GEN_PMCON_3		0xA4
+#define   RTC_PWR_STS		(1 << 2)
+
+/* Default IO range claimed by the LPC device. The upper bound is exclusive. */
+#define LPC_DEFAULT_IO_RANGE_LOWER 0
+#define LPC_DEFAULT_IO_RANGE_UPPER 0x1000
+
+/* IO Mapped registers behind ACPI_BASE_ADDRESS */
+#define PM1_STS			0x00
+#define   WAK_STS		(1 << 15)
+#define   PCIEXPWAK_STS		(1 << 14)
+#define   USB_STS		(1 << 13)
+#define   PRBTNOR_STS		(1 << 11)
+#define   RTC_STS		(1 << 10)
+#define   PWRBTN_STS		(1 << 8)
+#define   GBL_STS		(1 << 5)
+#define   TMROF_STS		(1 << 0)
+#define PM1_EN			0x02
+#define   PCIEXPWAK_DIS		(1 << 14)
+#define   RTC_EN		(1 << 10)
+#define   PWRBTN_EN		(1 << 8)
+#define   GBL_EN		(1 << 5)
+#define   TMROF_EN		(1 << 0)
+#define PM1_CNT			0x04
+#define   SLP_EN		(1 << 13)
+#define   SLP_TYP_SHIFT		10
+#define   SLP_TYP		(7 << SLP_TYP_SHIFT)
+#define    SLP_TYP_S0		0
+#define    SLP_TYP_S1		1
+#define    SLP_TYP_S3		5
+#define    SLP_TYP_S4		6
+#define    SLP_TYP_S5		7
+#define   GBL_RLS		(1 << 2)
+#define   BM_RLD		(1 << 1)
+#define   SCI_EN		(1 << 0)
+#define PM1_TMR			0x08
+#define GPE0_STS		0x20
+#define   PCI_EXP_STS		(1 << 9)
+#define   RI_STS		(1 << 8)
+#define   SMB_WAK_STS		(1 << 7)
+#define   TCOSCI_STS		(1 << 6)
+#define   SWGPE_STS		(1 << 2)
+#define   HOT_PLUG_STS		(1 << 1)
+#define GPE0_EN			0x28
+#define SMI_EN			0x30
+#define SMI_STS			0x34
+#define ALT_GPIO_SMI		0x38
+#define UPRWC			0x3c
+#define   UPRWC_WR_EN		(1 << 1) // USB Per-Port Registers Write Enable
+#define GPE_CTRL		0x40
+#define PM2A_CNT_BLK		0x50
+#define TCO_RLD			0x60
+#define TCO_STS			0x64
+#define   SECOND_TO_STS		(1 << 17)
+#define   TCO_TIMEOUT		(1 << 3)
+#define TCO1_CNT		0x68
+#define   TCO_LOCK		(1 << 12)
+#define   TCO_TMR_HALT		(1 << 11)
+#define TCO_TMR			0x70
+
+#endif /* _SOC_LPC_H_ */
\ No newline at end of file
diff --git a/src/soc/intel/fsp_broadwell_de/include/soc/msr.h b/src/soc/intel/fsp_broadwell_de/include/soc/msr.h
new file mode 100644
index 0000000..c409ec8
--- /dev/null
+++ b/src/soc/intel/fsp_broadwell_de/include/soc/msr.h
@@ -0,0 +1,28 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google, Inc.
+ * Copyright (C) 2015-2016 Intel Corp.
+ *
+ * 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 wacbmem_entryanty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _SOC_MSR_H_
+#define _SOC_MSR_H_
+
+#define MSR_IA32_PLATFORM_ID    0x17
+#define MSR_CORE_THREAD_COUNT   0x35
+#define MSR_PLATFORM_INFO       0xce
+#define MSR_TURBO_RATIO_LIMIT   0x1ad
+#define MSR_IA32_MC0_STATUS     0x400
+#define MSR_PKG_POWER_SKU_UNIT  0x606
+#define MSR_PKG_POWER_LIMIT     0x610
+
+#endif /* _SOC_MSR_H_ */
diff --git a/src/soc/intel/fsp_broadwell_de/include/soc/pattrs.h b/src/soc/intel/fsp_broadwell_de/include/soc/pattrs.h
new file mode 100644
index 0000000..232a4f4
--- /dev/null
+++ b/src/soc/intel/fsp_broadwell_de/include/soc/pattrs.h
@@ -0,0 +1,52 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corp.
+ *
+ * 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.
+ */
+
+#ifndef _SOC_PATTRS_H_
+#define _SOC_PATTRS_H_
+
+#include <stdint.h>
+#include <cpu/x86/msr.h>
+
+/*
+ * The pattrs structure is a common place to stash pertinent information
+ * about the processor or platform. Instead of going to the source (msrs, cpuid)
+ * every time an attribute is needed use the pattrs structure.
+ */
+struct pattrs {
+	msr_t platform_id;
+	msr_t platform_info;
+	uint32_t cpuid;
+	int revid;
+	int stepping;
+	const void *microcode_patch;
+	int address_bits;
+	int num_cpus;
+};
+
+/*
+ * This is just to hide the abstraction w/o relying on how the underlying
+ * storage is allocated.
+ */
+#define PATTRS_GLOB_NAME __global_pattrs
+#define DEFINE_PATTRS struct pattrs PATTRS_GLOB_NAME
+extern DEFINE_PATTRS;
+
+static inline const struct pattrs *pattrs_get(void)
+{
+	return &PATTRS_GLOB_NAME;
+}
+
+#endif /* _SOC_PATTRS_H_ */
diff --git a/src/soc/intel/fsp_broadwell_de/include/soc/pci_devs.h b/src/soc/intel/fsp_broadwell_de/include/soc/pci_devs.h
new file mode 100644
index 0000000..646ed3f
--- /dev/null
+++ b/src/soc/intel/fsp_broadwell_de/include/soc/pci_devs.h
@@ -0,0 +1,110 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corp.
+ *
+ * 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.
+ */
+
+#ifndef _SOC_PCI_DEVS_H_
+#define _SOC_PCI_DEVS_H_
+
+#define BUS0 0
+
+#define SOC_DEV                 0
+#define SOC_FUNC                0
+#define SOC_DEVID               0x2F00
+#define SOC_DEVID_ES2           0x6F00
+#define SOC_DEV_FUNC DEV_FUNC(SOC_DEV, SOC_FUNC)
+
+#define LPC_DEV                 31
+#define LPC_FUNC                0
+#define LPC_DEVID               0x8C42
+#define LPC_DEVID_ES2           0x8C54
+#define LPC_DEV_FUNC DEV_FUNC(LPC_DEV, LPC_FUNC)
+
+#define SATA_DEV                31
+#define SATA_FUNC               2
+#define AHCI_DEVID              0x8C02
+#define SATA_DEV_FUNC DEV_FUNC(SATA_DEV, SATA_FUNC)
+
+#define SATA2_DEV               31
+#define SATA2_FUNC              5
+#define SATA2_DEV_FUNC DEV_FUNC(SATA2_DEV, SATA2_FUNC)
+
+#define EHCI1_DEV               29
+#define EHCI1_FUNC              0
+#define EHCI1_DEVID             0x8C26
+#define EHCI1_DEV_FUNC DEV_FUNC(EHCI_DEV1, EHCI_FUNC1)
+
+#define EHCI2_DEV               26
+#define EHCI2_FUNC              0
+#define EHCI2_DEVID             0x8C2D
+#define EHCI2_DEV_FUNC DEV_FUNC(EHCI_DEV2, EHCI_FUNC2)
+
+#define XHCI_DEV                20
+#define XHCI_FUNC               0
+#define XHCI_DEVID              0x8C31
+#define XHCI_FUS_REG            0xE0
+#define XHCI_FUNC_DISABLE       (1 << 0)
+#define XHCI_USB2PR_REG         0xD0
+#define XHCI_DEV_FUNC DEV_FUNC(XHCI_DEV, XHCI_FUNC)
+
+#define GBE_DEV                 25
+#define GBE_FUNC                0
+#define GBE_DEVID               0x8C33
+#define GBE_DEV_FUNC DEV_FUNC(GBE_DEV, GBE_FUNC)
+
+#define ME_DEV                  22
+#define ME_FUNC                 0
+#define ME_DEVID                0x8C3A
+#define ME_DEV_FUNC DEV_FUNC(ME_DEV, ME_FUNC)
+
+#define HDA_DEV                 27
+#define HDA_FUNC                0
+#define HDA_DEVID               0x8C20
+#define HDA_DEV_FUNC DEV_FUNC(HDA_DEV, HDA_FUNC)
+
+#define PCIE_DEV                28
+#define PCIE_PORT1_DEV          PCIE_DEV
+#define PCIE_PORT1_FUNC         0
+#define PCIE_PORT1_DEVID        0x8C10
+#define PCIE_PORT2_DEV          PCIE_DEV
+#define PCIE_PORT2_FUNC         1
+#define PCIE_PORT2_DEVID        0x8C12
+#define PCIE_PORT3_DEV          PCIE_DEV
+#define PCIE_PORT3_FUNC         2
+#define PCIE_PORT3_DEVID        0x8C14
+#define PCIE_PORT4_DEV          PCIE_DEV
+#define PCIE_PORT4_FUNC         3
+#define PCIE_PORT4_DEVID        0x8C16
+#define PCIE_PORT5_DEV          PCIE_DEV
+#define PCIE_PORT5_FUNC         4
+#define PCIE_PORT5_DEVID        0x8C18
+#define PCIE_PORT6_DEV          PCIE_DEV
+#define PCIE_PORT6_FUNC         5
+#define PCIE_PORT6_DEVID        0x8C1A
+#define PCIE_PORT7_DEV          PCIE_DEV
+#define PCIE_PORT7_FUNC         6
+#define PCIE_PORT7_DEVID        0x8C1C
+#define PCIE_PORT8_DEV          PCIE_DEV
+#define PCIE_PORT8_FUNC         7
+#define PCIE_PORT8_DEVID        0x8C1E
+#define PCIE_PORT1_DEV_FUNC DEV_FUNC(PCIE_DEV, PCIE_PORT1_FUNC)
+#define PCIE_PORT2_DEV_FUNC DEV_FUNC(PCIE_DEV, PCIE_PORT2_FUNC)
+#define PCIE_PORT3_DEV_FUNC DEV_FUNC(PCIE_DEV, PCIE_PORT3_FUNC)
+#define PCIE_PORT4_DEV_FUNC DEV_FUNC(PCIE_DEV, PCIE_PORT4_FUNC)
+#define PCIE_PORT5_DEV_FUNC DEV_FUNC(PCIE_DEV, PCIE_PORT5_FUNC)
+#define PCIE_PORT6_DEV_FUNC DEV_FUNC(PCIE_DEV, PCIE_PORT6_FUNC)
+#define PCIE_PORT7_DEV_FUNC DEV_FUNC(PCIE_DEV, PCIE_PORT7_FUNC)
+#define PCIE_PORT8_DEV_FUNC DEV_FUNC(PCIE_DEV, PCIE_PORT8_FUNC)
+
+#endif /* _SOC_PCI_DEVS_H_ */
diff --git a/src/soc/intel/fsp_broadwell_de/include/soc/ramstage.h b/src/soc/intel/fsp_broadwell_de/include/soc/ramstage.h
new file mode 100644
index 0000000..c01c9ac
--- /dev/null
+++ b/src/soc/intel/fsp_broadwell_de/include/soc/ramstage.h
@@ -0,0 +1,30 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corp.
+ *
+ * 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.
+ */
+
+#ifndef _SOC_RAMSTAGE_H_
+#define _SOC_RAMSTAGE_H_
+
+#include <device/device.h>
+
+/* The broadwell_de_init_pre_device() function is called prior to device
+ * initialization, but it's after console and cbmem has been reinitialized. */
+void broadwell_de_init_pre_device(void);
+void broadwell_de_init_cpus(device_t dev);
+void southcluster_enable_dev(device_t dev);
+
+extern struct pci_operations soc_pci_ops;
+
+#endif /* _SOC_RAMSTAGE_H_ */
diff --git a/src/soc/intel/fsp_broadwell_de/include/soc/reset.h b/src/soc/intel/fsp_broadwell_de/include/soc/reset.h
new file mode 100644
index 0000000..fa0ceac
--- /dev/null
+++ b/src/soc/intel/fsp_broadwell_de/include/soc/reset.h
@@ -0,0 +1,24 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corp.
+ *
+ * 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.
+ */
+
+#ifndef _SOC_RESET_H_
+#define _SOC_RESET_H_
+
+#include <reset.h>
+
+void warm_reset(void);
+
+#endif /* _SOC_RESET_H_ */
diff --git a/src/soc/intel/fsp_broadwell_de/include/soc/romstage.h b/src/soc/intel/fsp_broadwell_de/include/soc/romstage.h
new file mode 100644
index 0000000..94a5a56
--- /dev/null
+++ b/src/soc/intel/fsp_broadwell_de/include/soc/romstage.h
@@ -0,0 +1,35 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corp.
+ *
+ * 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.
+ */
+
+#ifndef _SOC_ROMSTAGE_H_
+#define _SOC_ROMSTAGE_H_
+
+#if !defined(__PRE_RAM__)
+#error "Don't include romstage.h from a ramstage compilation unit!"
+#endif
+
+#include <stdint.h>
+#include <arch/cpu.h>
+#include <fsp.h>
+
+void romstage_main_continue(EFI_STATUS status, void *hob_list_ptr);
+
+#define NUM_ROMSTAGE_TS 4
+
+void early_mainboard_romstage_entry(void);
+void late_mainboard_romstage_entry(void);
+
+#endif /* _SOC_ROMSTAGE_H_ */
diff --git a/src/soc/intel/fsp_broadwell_de/memmap.c b/src/soc/intel/fsp_broadwell_de/memmap.c
new file mode 100644
index 0000000..7510094
--- /dev/null
+++ b/src/soc/intel/fsp_broadwell_de/memmap.c
@@ -0,0 +1,23 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google, Inc.
+ * Copyright (C) 2015-2016 Intel Corp.
+ *
+ * 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.
+ */
+
+#include <cbmem.h>
+#include <drivers/intel/fsp1_0/fsp_util.h>
+
+void *cbmem_top(void)
+{
+	return find_fsp_reserved_mem(*(void **)CBMEM_FSP_HOB_PTR);
+}
diff --git a/src/soc/intel/fsp_broadwell_de/northcluster.c b/src/soc/intel/fsp_broadwell_de/northcluster.c
new file mode 100644
index 0000000..307137b
--- /dev/null
+++ b/src/soc/intel/fsp_broadwell_de/northcluster.c
@@ -0,0 +1,156 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corp.
+ *
+ * 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.
+ */
+
+#include <arch/acpi.h>
+#include <console/console.h>
+#include <cpu/x86/lapic.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <drivers/intel/fsp1_0/fsp_util.h>
+#include <soc/iomap.h>
+#include <soc/pci_devs.h>
+#include <soc/ramstage.h>
+
+static const int legacy_hole_base_k = 0xa0000 / 1024;
+static const int legacy_hole_size_k = 384;
+
+static int add_fixed_resources(struct device *dev, int index)
+{
+	struct resource *resource;
+	u32 pcie_config_base, pcie_config_size;
+	pcie_config_base = MCFG_BASE_ADDRESS;
+	pcie_config_size = MCFG_BASE_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 mc_add_dram_resources(device_t dev)
+{
+	u32 fsp_mem_base, fsp_mem_len;
+	u32 tseg_base, tseg_length;
+	u32 rsv_base, rsv_length;
+	u32 tolm;
+	int index = 0;
+	uint64_t highmem_size = 0;
+
+	fsp_mem_base = GetFspReservedMemory(FspHobListPtr, &fsp_mem_len);
+	highmem_size = GetUsableHighMemTop(FspHobListPtr) - 0x100000000L;
+	tseg_base    = GetTsegReservedMemory(FspHobListPtr, &tseg_length);
+	tolm         = GetPhysicalLowMemTop(FspHobListPtr);
+
+	printk(BIOS_DEBUG, "\n\n");
+	printk(BIOS_DEBUG, "fsp_mem_base:             0x%.8x\n", fsp_mem_base);
+	printk(BIOS_DEBUG, "fsp_mem_len:              0x%.8x\n", fsp_mem_len);
+	printk(BIOS_DEBUG, "tseg_base:                0x%.8x\n", tseg_base);
+	printk(BIOS_DEBUG, "tseg_len:                 0x%.8x\n", tseg_length);
+	printk(BIOS_DEBUG, "highmem_size:             0x%.8x %.8x\n",
+	       (u32)(highmem_size>>32),
+	       (u32)(highmem_size&0xffffffff));
+	printk(BIOS_DEBUG, "tolm:                     0x%.8x\n", tolm);
+	printk(BIOS_DEBUG, "Top of system low memory: 0x%08x\n", tolm);
+	printk(BIOS_DEBUG, "FSP memory location:      0x%x\n (size: %dM)\n",
+	       fsp_mem_base, fsp_mem_len >> 20);
+	printk(BIOS_DEBUG, "tseg:                     0x%08x (size: 0x%.8x)\n",
+	       tseg_base, tseg_length);
+
+	/* 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,
+		 ((fsp_mem_base >> 10) - (legacy_hole_base_k + legacy_hole_size_k)));
+
+	/* Mark SMM & FSP regions reserved */
+	mmio_resource(dev, index++, tseg_base >> 10, tseg_length >> 10);
+	mmio_resource(dev, index++, fsp_mem_base >> 10, fsp_mem_len >> 10);
+
+	/* Reserve MMIO space */
+	rsv_base = fsp_mem_base + fsp_mem_len;
+	rsv_length = tseg_base - rsv_base;
+	if (rsv_length) {
+		mmio_resource(dev, index++, rsv_base >> 10,	rsv_length >> 10);
+		printk(BIOS_DEBUG, "Reserved MMIO : 0x%08x length 0x%08x\n",
+		       rsv_base, rsv_length);
+	}
+
+	rsv_base = tseg_base + tseg_length;
+	rsv_length = tolm - rsv_base;
+	if (rsv_length) {
+		mmio_resource(dev, index++, rsv_base >> 10,	rsv_length >> 10);
+		printk(BIOS_DEBUG, "Reserved MMIO : 0x%08x length 0x%08x\n",
+		       rsv_base, rsv_length);
+	}
+
+	if (highmem_size) {
+		ram_resource(dev, index++, 0x100000000 >> 10, highmem_size >> 10);
+	}
+	printk(BIOS_INFO, "Available memory above 4GB: %lluM\n",
+	       highmem_size >> 20);
+
+	index = add_fixed_resources(dev, index);
+}
+
+static void nc_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 nc_enable(device_t dev)
+{
+	print_fsp_info();
+}
+
+static struct device_operations nc_ops = {
+	.read_resources   = nc_read_resources,
+	.acpi_fill_ssdt_generator = generate_cpu_entries,
+	.set_resources    = pci_dev_set_resources,
+	.enable_resources = pci_dev_enable_resources,
+	.init             = NULL,
+	.enable           = &nc_enable,
+	.scan_bus         = 0,
+	.ops_pci          = &soc_pci_ops,
+};
+
+static const struct pci_driver nc_driver __pci_driver = {
+	.ops    = &nc_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = SOC_DEVID,
+};
+
+static const struct pci_driver nc_driver_es2 __pci_driver = {
+	.ops    = &nc_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = SOC_DEVID_ES2,
+};
\ No newline at end of file
diff --git a/src/soc/intel/fsp_broadwell_de/ramstage.c b/src/soc/intel/fsp_broadwell_de/ramstage.c
new file mode 100644
index 0000000..7b2f141
--- /dev/null
+++ b/src/soc/intel/fsp_broadwell_de/ramstage.c
@@ -0,0 +1,86 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corp.
+ *
+ * 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.
+ */
+
+#include <stdlib.h>
+#include <arch/cpu.h>
+#include <arch/acpi.h>
+#include <console/console.h>
+#include <cpu/intel/microcode.h>
+#include <cpu/x86/cr.h>
+#include <cpu/x86/msr.h>
+#include <device/device.h>
+#include <device/pci_def.h>
+#include <device/pci_ops.h>
+#include <romstage_handoff.h>
+#include <soc/lpc.h>
+#include <soc/msr.h>
+#include <soc/pattrs.h>
+#include <soc/pci_devs.h>
+#include <soc/ramstage.h>
+
+/* Global PATTRS */
+DEFINE_PATTRS;
+
+#define SHOW_PATTRS 1
+
+static void detect_num_cpus(struct pattrs *attrs)
+{
+	msr_t core_thread_count = rdmsr(MSR_CORE_THREAD_COUNT);
+	attrs->num_cpus = core_thread_count.lo & 0xffff;
+}
+
+static inline void fill_in_msr(msr_t *msr, int idx)
+{
+	*msr = rdmsr(idx);
+	if (SHOW_PATTRS) {
+		printk(BIOS_DEBUG, "msr(%x) = %08x%08x\n",
+		       idx, msr->hi, msr->lo);
+	}
+}
+
+static const char *stepping_str[] = {
+	"U0", "V1", "V2", "Y0"
+};
+
+static void fill_in_pattrs(void)
+{
+	device_t dev;
+	struct pattrs *attrs = (struct pattrs *)pattrs_get();
+
+	attrs->cpuid = cpuid_eax(1);
+	attrs->stepping = (attrs->cpuid & 0x0F) - 1;
+	dev = dev_find_slot(0, PCI_DEVFN(LPC_DEV, LPC_FUNC));
+	attrs->revid = pci_read_config8(dev, REVID);
+	attrs->microcode_patch = intel_microcode_find();
+	attrs->address_bits = cpuid_eax(0x80000008) & 0xff;
+	detect_num_cpus(attrs);
+
+	if (SHOW_PATTRS) {
+		printk(BIOS_DEBUG, "CPUID: %08x\n", attrs->cpuid);
+		printk(BIOS_DEBUG, "Cores: %d\n", attrs->num_cpus);
+		printk(BIOS_DEBUG, "Stepping: %s\n", (attrs->stepping >= ARRAY_SIZE(stepping_str))
+							? "??" : stepping_str[attrs->stepping]);
+		printk(BIOS_DEBUG, "Revision ID: %02x\n", attrs->revid);
+	}
+
+	fill_in_msr(&attrs->platform_id, MSR_IA32_PLATFORM_ID);
+	fill_in_msr(&attrs->platform_info, MSR_PLATFORM_INFO);
+}
+
+void broadwell_de_init_pre_device(void)
+{
+	fill_in_pattrs();
+}
diff --git a/src/soc/intel/fsp_broadwell_de/reset.c b/src/soc/intel/fsp_broadwell_de/reset.c
new file mode 100644
index 0000000..7e1c582
--- /dev/null
+++ b/src/soc/intel/fsp_broadwell_de/reset.c
@@ -0,0 +1,29 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corp.
+ *
+ * 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.
+ */
+
+#include <arch/io.h>
+#include <soc/reset.h>
+
+void warm_reset(void)
+{
+    outb(0x00, 0xcf9);
+    outb(0x06, 0xcf9);
+}
+
+void hard_reset(void)
+{
+	warm_reset();
+}
diff --git a/src/soc/intel/fsp_broadwell_de/romstage/Makefile.inc b/src/soc/intel/fsp_broadwell_de/romstage/Makefile.inc
new file mode 100644
index 0000000..436f038
--- /dev/null
+++ b/src/soc/intel/fsp_broadwell_de/romstage/Makefile.inc
@@ -0,0 +1,3 @@
+romstage-y += romstage.c
+
+$(obj)/soc/intel/fsp_broadwell_de/romstage/romstage.romstage.o : $(obj)/build.h
\ No newline at end of file
diff --git a/src/soc/intel/fsp_broadwell_de/romstage/romstage.c b/src/soc/intel/fsp_broadwell_de/romstage/romstage.c
new file mode 100644
index 0000000..b1e7b93
--- /dev/null
+++ b/src/soc/intel/fsp_broadwell_de/romstage/romstage.c
@@ -0,0 +1,129 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corp.
+ *
+ * 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.
+ */
+
+#include <stddef.h>
+#include <arch/cpu.h>
+#include <lib.h>
+#include <arch/io.h>
+#include <arch/cbfs.h>
+#include <arch/stages.h>
+#include <console/console.h>
+#include <cpu/x86/mtrr.h>
+#include <romstage_handoff.h>
+#include <timestamp.h>
+#include <version.h>
+#include <drivers/intel/fsp1_0/fsp_util.h>
+#include <pc80/mc146818rtc.h>
+#include <soc/iomap.h>
+#include <soc/lpc.h>
+#include <soc/pci_devs.h>
+#include <soc/romstage.h>
+#include <build.h>
+
+static void init_rtc(void)
+{
+	u16 gen_pmcon3 = pci_read_config16(PCI_DEV(0, LPC_DEV, LPC_FUNC), GEN_PMCON_3);
+
+	if (gen_pmcon3 & RTC_PWR_STS) {
+		printk(BIOS_DEBUG, "RTC Failure detected.  Resetting Date to %s\n",
+			coreboot_dmi_date);
+	}
+	cmos_init(gen_pmcon3 & RTC_PWR_STS);
+}
+
+/* Entry from cache-as-ram.inc. */
+void *asmlinkage main(FSP_INFO_HEADER *fsp_info_header)
+{
+	post_code(0x40);
+	console_init();
+
+	init_rtc();
+
+	/* Call into mainboard. */
+	early_mainboard_romstage_entry();
+
+	/*
+	 * Call early init to initialize memory and chipset. This function returns
+	 * to the romstage_main_continue function with a pointer to the HOB
+	 * structure.
+	 */
+	post_code(0x48);
+	printk(BIOS_DEBUG, "Starting the Intel FSP (early_init)\n");
+	fsp_early_init(fsp_info_header);
+	die("Uh Oh! fsp_early_init should not return here.\n");
+}
+
+/*******************************************************************************
+ * The FSP early_init function returns to this function.
+ * Memory is setup and the stack is set by the FSP.
+ */
+void romstage_main_continue(EFI_STATUS status, void *hob_list_ptr)
+{
+	int cbmem_was_initted;
+	void *cbmem_hob_ptr;
+
+#if IS_ENABLED(CONFIG_COLLECT_TIMESTAMPS)
+	tsc_t after_initram_time = rdtsc();
+	tsc_t base_time;
+	base_time.hi = 0;
+	base_time.lo = 0;
+#endif
+	post_code(0x4a);
+	printk(BIOS_DEBUG, "%s status: %x  hob_list_ptr: %x\n",
+		__func__, (u32) status, (u32) hob_list_ptr);
+
+#if IS_ENABLED(CONFIG_USBDEBUG_IN_ROMSTAGE)
+	/* FSP reconfigures USB, so reinit it to have debug */
+	usbdebug_init();
+#endif	/* IS_ENABLED(CONFIG_USBDEBUG_IN_ROMSTAGE) */
+
+	printk(BIOS_DEBUG, "FSP Status: 0x%0x\n", (u32)status);
+
+#if IS_ENABLED(CONFIG_COLLECT_TIMESTAMPS)
+	after_initram_time = rdtsc();
+#endif
+	post_code(0x4b);
+
+	late_mainboard_romstage_entry();
+	post_code(0x4c);
+
+	quick_ram_check();
+	post_code(0x4d);
+
+	cbmem_was_initted = !cbmem_recovery(0);
+
+	/* Save the HOB pointer in CBMEM to be used in ramstage*/
+	cbmem_hob_ptr = cbmem_add (CBMEM_ID_HOB_POINTER, sizeof(*hob_list_ptr));
+	if (cbmem_hob_ptr == NULL) {
+	   printk(BIOS_DEBUG, "Failed to save HOB pointer in CBMEM.\n");
+	   return;
+	}
+	*(u32 *)cbmem_hob_ptr = (u32)hob_list_ptr;
+	post_code(0x4e);
+
+#if IS_ENABLED(CONFIG_COLLECT_TIMESTAMPS)
+	timestamp_init(base_time);
+	timestamp_reinit();
+	timestamp_add(TS_AFTER_INITRAM, after_initram_time);
+	timestamp_add_now(TS_END_ROMSTAGE);
+#endif
+
+	post_code(0x4f);
+
+	/* Load the ramstage. */
+	copy_and_run();
+	while (1);
+}
diff --git a/src/soc/intel/fsp_broadwell_de/southcluster.c b/src/soc/intel/fsp_broadwell_de/southcluster.c
new file mode 100644
index 0000000..7024814
--- /dev/null
+++ b/src/soc/intel/fsp_broadwell_de/southcluster.c
@@ -0,0 +1,267 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008-2009 coresystems GmbH
+ * Copyright (C) 2013 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corp.
+ *
+ * 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.
+ */
+
+#include <stdint.h>
+#include <arch/io.h>
+#include <arch/ioapic.h>
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_def.h>
+#include <pc80/mc146818rtc.h>
+#include <pc80/i8254.h>
+#include <pc80/i8259.h>
+#include <pc80/isa-dma.h>
+#include <romstage_handoff.h>
+#include <soc/iomap.h>
+#include <soc/irq.h>
+#include <soc/lpc.h>
+#include <soc/pci_devs.h>
+#include <soc/ramstage.h>
+#include <chip.h>
+
+typedef struct soc_intel_fsp_broadwell_de_config config_t;
+
+static inline void
+add_mmio_resource(device_t dev, int i, unsigned long addr, unsigned long size)
+{
+	mmio_resource(dev, i, addr >> 10, size >> 10);
+}
+
+static void sc_add_mmio_resources(device_t dev)
+{
+	add_mmio_resource(dev, 0xfeb0,
+	                       ABORT_BASE_ADDRESS,
+	                       ABORT_BASE_SIZE);
+	add_mmio_resource(dev, 0xfeb8,
+	                       PSEG_BASE_ADDRESS,
+	                       PSEG_BASE_SIZE);
+	add_mmio_resource(dev, 0xfec0,
+	                       IOXAPIC1_BASE_ADDRESS,
+	                       IOXAPIC1_BASE_SIZE);
+	add_mmio_resource(dev, 0xfec1,
+	                       IOXAPIC2_BASE_ADDRESS,
+	                       IOXAPIC2_BASE_SIZE);
+	add_mmio_resource(dev, 0xfed0,
+	                       PCH_BASE_ADDRESS,
+	                       PCH_BASE_SIZE);
+	add_mmio_resource(dev, 0xfee0,
+	                       LXAPIC_BASE_ADDRESS,
+	                       LXAPIC_BASE_SIZE);
+	add_mmio_resource(dev, 0xff00,
+	                       FIRMWARE_BASE_ADDRESS,
+	                       FIRMWARE_BASE_SIZE);
+}
+
+/*
+ * Write PCI config space IRQ assignments.  PCI devices have the INT_LINE
+ * (0x3C) and INT_PIN (0x3D) registers which report interrupt routing
+ * information to operating systems and drivers.  The INT_PIN register is
+ * generally read only and reports which interrupt pin A - D it uses.  The
+ * INT_LINE register is configurable and reports which IRQ (generally the
+ * PIC IRQs 1 - 15) it will use.  This needs to take interrupt pin swizzling
+ * on devices that are downstream on a PCI bridge into account.
+ *
+ * This function will loop through all enabled PCI devices and program the
+ * INT_LINE register with the correct PIC IRQ number for the INT_PIN that it
+ * uses.  It then configures each interrupt in the pic to be level triggered.
+ */
+static void write_pci_config_irqs(void)
+{
+	device_t irq_dev;
+	device_t targ_dev;
+	uint8_t int_line = 0;
+	uint8_t original_int_pin = 0;
+	uint8_t new_int_pin = 0;
+	uint16_t current_bdf = 0;
+	uint16_t parent_bdf = 0;
+	uint8_t pirq = 0;
+	uint8_t device_num = 0;
+	const struct broadwell_de_irq_route *ir = &global_broadwell_de_irq_route;
+
+	if (ir == NULL) {
+		printk(BIOS_WARNING, "Warning: Can't write PCI IRQ assignments because"
+				" 'global_broadwell_de_irq_route' structure does not exist\n");
+		return;
+	}
+
+	/*
+	 * Loop through all enabled devices and program their
+	 * INT_LINE, INT_PIN registers from values taken from
+	 * the Interrupt Route registers in the ILB
+	 */
+	printk(BIOS_DEBUG, "PCI_CFG IRQ: Write PCI config space IRQ assignments\n");
+	for (irq_dev = all_devices; irq_dev; irq_dev = irq_dev->next) {
+
+		if ((irq_dev->path.type != DEVICE_PATH_PCI) ||
+			(!irq_dev->enabled))
+			continue;
+
+		current_bdf = irq_dev->path.pci.devfn |
+			irq_dev->bus->secondary << 8;
+
+		/*
+		 * Step 1: Get the INT_PIN and device structure to look for
+		 * in the pirq_data table defined in the mainboard directory.
+		 */
+		targ_dev = NULL;
+		new_int_pin = get_pci_irq_pins(irq_dev, &targ_dev);
+		if (targ_dev == NULL || new_int_pin < 1)
+			continue;
+
+		/* Get the original INT_PIN for record keeping */
+		original_int_pin = pci_read_config8(irq_dev, PCI_INTERRUPT_PIN);
+
+		parent_bdf = targ_dev->path.pci.devfn
+			| targ_dev->bus->secondary << 8;
+		device_num = PCI_SLOT(parent_bdf);
+
+		if (ir->pcidev[device_num] == 0) {
+			printk(BIOS_WARNING,
+				"Warning: PCI Device %d does not have an IRQ entry, skipping it\n",
+				device_num);
+			continue;
+		}
+
+		/* Find the PIRQ that is attached to the INT_PIN this device uses */
+		pirq = (ir->pcidev[device_num] >> ((new_int_pin - 1) * 4)) & 0xF;
+
+		/* Get the INT_LINE this device/function will use */
+		int_line = ir->pic[pirq];
+
+		if (int_line != PIRQ_PIC_IRQDISABLE) {
+			/* Set this IRQ to level triggered since it is used by a PCI device */
+			i8259_configure_irq_trigger(int_line, IRQ_LEVEL_TRIGGERED);
+			/* Set the Interrupt Line register in PCI config space */
+			pci_write_config8(irq_dev, PCI_INTERRUPT_LINE, int_line);
+		} else {
+			/* Set the Interrupt line register as "unknown or unused" */
+			pci_write_config8(irq_dev, PCI_INTERRUPT_LINE,
+				PIRQ_PIC_UNKNOWN_UNUSED);
+		}
+
+		printk(BIOS_SPEW, "\tINT_PIN\t\t: %d (%s)\n",
+			original_int_pin, pin_to_str(original_int_pin));
+		if (parent_bdf != current_bdf)
+			printk(BIOS_SPEW, "\tSwizzled to\t: %d (%s)\n",
+							new_int_pin, pin_to_str(new_int_pin));
+		printk(BIOS_SPEW, "\tPIRQ\t\t: %c\n"
+						"\tINT_LINE\t: 0x%X (IRQ %d)\n",
+						'A' + pirq, int_line, int_line);
+	}
+	printk(BIOS_DEBUG, "PCI_CFG IRQ: Finished writing PCI config space IRQ assignments\n");
+}
+
+static void sc_pirq_init(device_t dev)
+{
+	int i;
+	const uint8_t *pirq = global_broadwell_de_irq_route.pic;
+	printk(BIOS_DEBUG, "Programming PIRQ[A-H] Routing Control Register\n");
+
+	for (i = 0; i < 8; i++) {
+		pci_write_config8(dev, (i < 4) ? (PIRQ_RCR1+i) : (PIRQ_RCR2+i-4), pirq[i]);
+		printk(BIOS_DEBUG, "  PIRQ[%c]: %.2x\n"
+			, 'A'+i
+			, pci_read_config8(dev, (i < 4) ? (PIRQ_RCR1+i) : (PIRQ_RCR2+i-4))
+			);
+	}
+}
+
+static void sc_add_io_resources(device_t dev)
+{
+	struct resource *res;
+	u8 io_index = 0;
+
+	/*
+	 * Add the default claimed IO range for the LPC device
+	 * and mark it as subtractive decode.
+	 */
+	res = new_resource(dev, IOINDEX_SUBTRACTIVE(io_index++, 0));
+	res->base = LPC_DEFAULT_IO_RANGE_LOWER;
+	res->size = LPC_DEFAULT_IO_RANGE_UPPER - LPC_DEFAULT_IO_RANGE_LOWER;
+	res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
+		     IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+}
+
+static void sc_read_resources(device_t dev)
+{
+	pci_dev_read_resources(dev);
+	sc_add_mmio_resources(dev);
+	sc_add_io_resources(dev);
+}
+
+static void sc_init(struct device *dev)
+{
+	printk(BIOS_DEBUG, "soc: southcluster_init\n");
+
+	/* Set the value for PCI command register. */
+	pci_write_config16(dev, PCI_COMMAND,
+		PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
+		PCI_COMMAND_MASTER | PCI_COMMAND_SPECIAL);
+
+	/* Program Serial IRQ register. */
+	pci_write_config16(dev, 0x64, 0xd0);
+
+	sc_pirq_init(dev);
+	write_pci_config_irqs();
+	isa_dma_init();
+	setup_i8259();
+	setup_i8254();
+}
+
+/*
+ * Common code for the south cluster devices.
+ */
+void southcluster_enable_dev(device_t dev)
+{
+	uint32_t reg32;
+
+	if (!dev->enabled) {
+		int slot = PCI_SLOT(dev->path.pci.devfn);
+		int func = PCI_FUNC(dev->path.pci.devfn);
+		printk(BIOS_DEBUG, "%s: Disabling device: %02x.%01x\n",
+		       dev_path(dev), slot, func);
+
+		/* Ensure memory, io, and bus master are all disabled */
+		reg32 = pci_read_config32(dev, PCI_COMMAND);
+		reg32 &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO);
+		pci_write_config32(dev, PCI_COMMAND, reg32);
+	}
+}
+
+static struct device_operations device_ops = {
+	.read_resources   = sc_read_resources,
+	.set_resources    = pci_dev_set_resources,
+	.enable_resources = NULL,
+	.init             = sc_init,
+	.enable           = southcluster_enable_dev,
+	.scan_bus         = scan_lpc_bus,
+	.ops_pci          = &soc_pci_ops,
+};
+
+static const struct pci_driver southcluster __pci_driver = {
+	.ops    = &device_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = LPC_DEVID,
+};
+
+static const struct pci_driver southcluster_es2 __pci_driver = {
+	.ops    = &device_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = LPC_DEVID_ES2,
+};
diff --git a/src/soc/intel/fsp_broadwell_de/spi.c b/src/soc/intel/fsp_broadwell_de/spi.c
new file mode 100644
index 0000000..f98ab97
--- /dev/null
+++ b/src/soc/intel/fsp_broadwell_de/spi.c
@@ -0,0 +1,633 @@
+/*
+ * Copyright (c) 2013 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corp.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but without any warranty; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+/* This file is derived from the flashrom project. */
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <delay.h>
+#include <arch/io.h>
+#include <console/console.h>
+#include <device/pci_ids.h>
+#include <spi_flash.h>
+#include <spi-generic.h>
+
+#ifdef __SMM__
+#define pci_read_config_byte(dev, reg, targ)\
+	*(targ) = pci_read_config8(dev, reg)
+#define pci_read_config_word(dev, reg, targ)\
+	*(targ) = pci_read_config16(dev, reg)
+#define pci_read_config_dword(dev, reg, targ)\
+	*(targ) = pci_read_config32(dev, reg)
+#define pci_write_config_byte(dev, reg, val)\
+	pci_write_config8(dev, reg, val)
+#define pci_write_config_word(dev, reg, val)\
+	pci_write_config16(dev, reg, val)
+#define pci_write_config_dword(dev, reg, val)\
+	pci_write_config32(dev, reg, val)
+#else /* !__SMM__ */
+#include <device/device.h>
+#include <device/pci.h>
+#define pci_read_config_byte(dev, reg, targ)\
+	*(targ) = pci_read_config8(dev, reg)
+#define pci_read_config_word(dev, reg, targ)\
+	*(targ) = pci_read_config16(dev, reg)
+#define pci_read_config_dword(dev, reg, targ)\
+	*(targ) = pci_read_config32(dev, reg)
+#define pci_write_config_byte(dev, reg, val)\
+	pci_write_config8(dev, reg, val)
+#define pci_write_config_word(dev, reg, val)\
+	pci_write_config16(dev, reg, val)
+#define pci_write_config_dword(dev, reg, val)\
+	pci_write_config32(dev, reg, val)
+#endif /* !__SMM__ */
+
+typedef struct spi_slave ich_spi_slave;
+
+static int ichspi_lock = 0;
+
+typedef struct ich9_spi_regs {
+	uint32_t bfpr;
+	uint16_t hsfs;
+	uint16_t hsfc;
+	uint32_t faddr;
+	uint32_t _reserved0;
+	uint32_t fdata[16];
+	uint32_t frap;
+	uint32_t freg[5];
+	uint32_t _reserved1[3];
+	uint32_t pr[5];
+	uint32_t _reserved2[2];
+	uint8_t ssfs;
+	uint8_t ssfc[3];
+	uint16_t preop;
+	uint16_t optype;
+	uint8_t opmenu[8];
+	uint32_t bbar;
+	uint8_t _reserved3[12];
+	uint32_t fdoc;
+	uint32_t fdod;
+	uint8_t _reserved4[8];
+	uint32_t afc;
+	uint32_t lvscc;
+	uint32_t uvscc;
+	uint8_t _reserved5[4];
+	uint32_t fpb;
+	uint8_t _reserved6[28];
+	uint32_t srdl;
+	uint32_t srdc;
+	uint32_t srd;
+} __attribute__((packed)) ich9_spi_regs;
+
+typedef struct ich_spi_controller {
+	int locked;
+
+	uint8_t *opmenu;
+	int menubytes;
+	uint16_t *preop;
+	uint16_t *optype;
+	uint32_t *addr;
+	uint8_t *data;
+	unsigned databytes;
+	uint8_t *status;
+	uint16_t *control;
+	uint32_t *bbar;
+} ich_spi_controller;
+
+static ich_spi_controller cntlr;
+
+enum {
+	SPIS_SCIP =		0x0001,
+	SPIS_GRANT =		0x0002,
+	SPIS_CDS =		0x0004,
+	SPIS_FCERR =		0x0008,
+	SSFS_AEL =		0x0010,
+	SPIS_LOCK =		0x8000,
+	SPIS_RESERVED_MASK =	0x7ff0,
+	SSFS_RESERVED_MASK =	0x7fe2
+};
+
+enum {
+	SPIC_SCGO =		0x000002,
+	SPIC_ACS =		0x000004,
+	SPIC_SPOP =		0x000008,
+	SPIC_DBC =		0x003f00,
+	SPIC_DS =		0x004000,
+	SPIC_SME =		0x008000,
+	SSFC_SCF_MASK =		0x070000,
+	SSFC_RESERVED =		0xf80000
+};
+
+enum {
+	HSFS_FDONE =		0x0001,
+	HSFS_FCERR =		0x0002,
+	HSFS_AEL =		0x0004,
+	HSFS_BERASE_MASK =	0x0018,
+	HSFS_BERASE_SHIFT =	3,
+	HSFS_SCIP =		0x0020,
+	HSFS_FDOPSS =		0x2000,
+	HSFS_FDV =		0x4000,
+	HSFS_FLOCKDN =		0x8000
+};
+
+enum {
+	HSFC_FGO =		0x0001,
+	HSFC_FCYCLE_MASK =	0x0006,
+	HSFC_FCYCLE_SHIFT =	1,
+	HSFC_FDBC_MASK =	0x3f00,
+	HSFC_FDBC_SHIFT =	8,
+	HSFC_FSMIE =		0x8000
+};
+
+enum {
+	SPI_OPCODE_TYPE_READ_NO_ADDRESS =	0,
+	SPI_OPCODE_TYPE_WRITE_NO_ADDRESS =	1,
+	SPI_OPCODE_TYPE_READ_WITH_ADDRESS =	2,
+	SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS =	3
+};
+
+#if IS_ENABLED(CONFIG_DEBUG_SPI_FLASH)
+
+static u8 readb_(const void *addr)
+{
+	u8 v = read8(addr);
+	printk(BIOS_DEBUG, "read %2.2x from %4.4x\n",
+	       v, ((unsigned) addr & 0xffff) - 0xf020);
+	return v;
+}
+
+static u16 readw_(const void *addr)
+{
+	u16 v = read16(addr);
+	printk(BIOS_DEBUG, "read %4.4x from %4.4x\n",
+	       v, ((unsigned) addr & 0xffff) - 0xf020);
+	return v;
+}
+
+static u32 readl_(const void *addr)
+{
+	u32 v = read32(addr);
+	printk(BIOS_DEBUG, "read %8.8x from %4.4x\n",
+	       v, ((unsigned) addr & 0xffff) - 0xf020);
+	return v;
+}
+
+static void writeb_(u8 b, const void *addr)
+{
+	write8(addr, b);
+	printk(BIOS_DEBUG, "wrote %2.2x to %4.4x\n",
+	       b, ((unsigned) addr & 0xffff) - 0xf020);
+}
+
+static void writew_(u16 b, const void *addr)
+{
+	write16(addr, b);
+	printk(BIOS_DEBUG, "wrote %4.4x to %4.4x\n",
+	       b, ((unsigned) addr & 0xffff) - 0xf020);
+}
+
+static void writel_(u32 b, const void *addr)
+{
+	write32(addr, b);
+	printk(BIOS_DEBUG, "wrote %8.8x to %4.4x\n",
+	       b, ((unsigned) addr & 0xffff) - 0xf020);
+}
+
+#else /* CONFIG_DEBUG_SPI_FLASH ^^^ enabled  vvv NOT enabled */
+
+#define readb_(a) read8(a)
+#define readw_(a) read16(a)
+#define readl_(a) read32(a)
+#define writeb_(val, addr) write8(addr, val)
+#define writew_(val, addr) write16(addr, val)
+#define writel_(val, addr) write32(addr, val)
+
+#endif  /* CONFIG_DEBUG_SPI_FLASH ^^^ NOT enabled */
+
+static void write_reg(const void *value, void *dest, uint32_t size)
+{
+	const uint8_t *bvalue = value;
+	uint8_t *bdest = dest;
+
+	while (size >= 4) {
+		writel_(*(const uint32_t *)bvalue, bdest);
+		bdest += 4; bvalue += 4; size -= 4;
+	}
+	while (size) {
+		writeb_(*bvalue, bdest);
+		bdest++; bvalue++; size--;
+	}
+}
+
+static void read_reg(const void *src, void *value, uint32_t size)
+{
+	const uint8_t *bsrc = src;
+	uint8_t *bvalue = value;
+
+	while (size >= 4) {
+		*(uint32_t *)bvalue = readl_(bsrc);
+		bsrc += 4; bvalue += 4; size -= 4;
+	}
+	while (size) {
+		*bvalue = readb_(bsrc);
+		bsrc++; bvalue++; size--;
+	}
+}
+
+static void ich_set_bbar(uint32_t minaddr)
+{
+	const uint32_t bbar_mask = 0x00ffff00;
+	uint32_t ichspi_bbar;
+
+	minaddr &= bbar_mask;
+	ichspi_bbar = readl_(cntlr.bbar) & ~bbar_mask;
+	ichspi_bbar |= minaddr;
+	writel_(ichspi_bbar, cntlr.bbar);
+}
+
+struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs)
+{
+	ich_spi_slave *slave = malloc(sizeof(*slave));
+
+	if (!slave) {
+		printk(BIOS_DEBUG, "ICH SPI: Bad allocation\n");
+		return NULL;
+	}
+
+	memset(slave, 0, sizeof(*slave));
+
+	slave->bus = bus;
+	slave->cs = cs;
+	return slave;
+}
+
+void spi_init(void)
+{
+	uint8_t *rcrb; /* Root Complex Register Block */
+	uint32_t rcba; /* Root Complex Base Address */
+	uint8_t bios_cntl;
+	device_t dev;
+	ich9_spi_regs *ich9_spi;
+
+#ifdef __SMM__
+	dev = PCI_DEV(0, 31, 0);
+#else
+	dev = dev_find_slot(0, PCI_DEVFN(31, 0));
+#endif
+
+	pci_read_config_dword(dev, 0xf0, &rcba);
+	/* Bits 31-14 are the base address, 13-1 are reserved, 0 is enable. */
+	rcrb = (uint8_t *)(rcba & 0xffffc000);
+	ich9_spi = (ich9_spi_regs *)(rcrb + 0x3800);
+	ichspi_lock = readw_(&ich9_spi->hsfs) & HSFS_FLOCKDN;
+	cntlr.opmenu = ich9_spi->opmenu;
+	cntlr.menubytes = sizeof(ich9_spi->opmenu);
+	cntlr.optype = &ich9_spi->optype;
+	cntlr.addr = &ich9_spi->faddr;
+	cntlr.data = (uint8_t *)ich9_spi->fdata;
+	cntlr.databytes = sizeof(ich9_spi->fdata);
+	cntlr.status = &ich9_spi->ssfs;
+	cntlr.control = (uint16_t *)ich9_spi->ssfc;
+	cntlr.bbar = &ich9_spi->bbar;
+	cntlr.preop = &ich9_spi->preop;
+	ich_set_bbar(0);
+
+	/* Disable the BIOS write protect so write commands are allowed. */
+	pci_read_config_byte(dev, 0xdc, &bios_cntl);
+	bios_cntl &= ~(1 << 5);
+	pci_write_config_byte(dev, 0xdc, bios_cntl | 0x1);
+}
+
+int spi_claim_bus(struct spi_slave *slave)
+{
+	/* Handled by ICH automatically. */
+	return 0;
+}
+
+void spi_release_bus(struct spi_slave *slave)
+{
+	/* Handled by ICH automatically. */
+}
+
+typedef struct spi_transaction {
+	const uint8_t *out;
+	uint32_t bytesout;
+	uint8_t *in;
+	uint32_t bytesin;
+	uint8_t type;
+	uint8_t opcode;
+	uint32_t offset;
+} spi_transaction;
+
+static inline void spi_use_out(spi_transaction *trans, unsigned bytes)
+{
+	trans->out += bytes;
+	trans->bytesout -= bytes;
+}
+
+static inline void spi_use_in(spi_transaction *trans, unsigned bytes)
+{
+	trans->in += bytes;
+	trans->bytesin -= bytes;
+}
+
+static void spi_setup_type(spi_transaction *trans)
+{
+	trans->type = 0xFF;
+
+	/* Try to guess spi type from read/write sizes. */
+	if (trans->bytesin == 0) {
+		if (trans->bytesout > 4)
+			/*
+			 * If bytesin = 0 and bytesout > 4, we presume this is
+			 * a write data operation, which is accompanied by an
+			 * address.
+			 */
+			trans->type = SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS;
+		else
+			trans->type = SPI_OPCODE_TYPE_WRITE_NO_ADDRESS;
+		return;
+	}
+
+	if (trans->bytesout == 1) { /* and bytesin is > 0 */
+		trans->type = SPI_OPCODE_TYPE_READ_NO_ADDRESS;
+		return;
+	}
+
+	if (trans->bytesout == 4) { /* and bytesin is > 0 */
+		trans->type = SPI_OPCODE_TYPE_READ_WITH_ADDRESS;
+	}
+
+	/* Fast read command is called with 5 bytes instead of 4 */
+	if (trans->out[0] == SPI_OPCODE_FAST_READ && trans->bytesout == 5) {
+		trans->type = SPI_OPCODE_TYPE_READ_WITH_ADDRESS;
+		--trans->bytesout;
+	}
+}
+
+static int spi_setup_opcode(spi_transaction *trans)
+{
+	uint16_t optypes;
+	uint8_t opmenu[cntlr.menubytes];
+
+	trans->opcode = trans->out[0];
+	spi_use_out(trans, 1);
+	if (!ichspi_lock) {
+		/* The lock is off, so just use index 0. */
+		writeb_(trans->opcode, cntlr.opmenu);
+		optypes = readw_(cntlr.optype);
+		optypes = (optypes & 0xfffc) | (trans->type & 0x3);
+		writew_(optypes, cntlr.optype);
+		return 0;
+	} else {
+		/* The lock is on. See if what we need is on the menu. */
+		uint8_t optype;
+		uint16_t opcode_index;
+
+		/* Write Enable is handled as atomic prefix */
+		if (trans->opcode == SPI_OPCODE_WREN)
+			return 0;
+
+		read_reg(cntlr.opmenu, opmenu, sizeof(opmenu));
+		for (opcode_index = 0; opcode_index < cntlr.menubytes;
+				opcode_index++) {
+			if (opmenu[opcode_index] == trans->opcode)
+				break;
+		}
+
+		if (opcode_index == cntlr.menubytes) {
+			printk(BIOS_DEBUG, "ICH SPI: Opcode %x not found\n",
+				trans->opcode);
+			return -1;
+		}
+
+		optypes = readw_(cntlr.optype);
+		optype = (optypes >> (opcode_index * 2)) & 0x3;
+		if (trans->type == SPI_OPCODE_TYPE_WRITE_NO_ADDRESS &&
+			optype == SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS &&
+			trans->bytesout >= 3) {
+			/* We guessed wrong earlier. Fix it up. */
+			trans->type = optype;
+		}
+		if (optype != trans->type) {
+			printk(BIOS_DEBUG, "ICH SPI: Transaction doesn't fit type %d\n",
+				optype);
+			return -1;
+		}
+		return opcode_index;
+	}
+}
+
+static int spi_setup_offset(spi_transaction *trans)
+{
+	/* Separate the SPI address and data. */
+	switch (trans->type) {
+	case SPI_OPCODE_TYPE_READ_NO_ADDRESS:
+	case SPI_OPCODE_TYPE_WRITE_NO_ADDRESS:
+		return 0;
+	case SPI_OPCODE_TYPE_READ_WITH_ADDRESS:
+	case SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS:
+		trans->offset = ((uint32_t)trans->out[0] << 16) |
+				((uint32_t)trans->out[1] << 8) |
+				((uint32_t)trans->out[2] << 0);
+		spi_use_out(trans, 3);
+		return 1;
+	default:
+		printk(BIOS_DEBUG, "Unrecognized SPI transaction type %#x\n", trans->type);
+		return -1;
+	}
+}
+
+/*
+ * Wait for up to 60ms til status register bit(s) turn 1 (in case wait_til_set
+ * below is True) or 0. In case the wait was for the bit(s) to set - write
+ * those bits back, which would cause resetting them.
+ *
+ * Return the last read status value on success or -1 on failure.
+ */
+static int ich_status_poll(u16 bitmask, int wait_til_set)
+{
+	int timeout = 40000; /* This will result in 400 ms */
+	u16 status = 0;
+
+	while (timeout--) {
+		status = readw_(cntlr.status);
+		if (wait_til_set ^ ((status & bitmask) == 0)) {
+			if (wait_til_set)
+				writew_((status & bitmask), cntlr.status);
+			return status;
+		}
+		udelay(10);
+	}
+
+	printk(BIOS_DEBUG, "ICH SPI: SCIP timeout, read %x, expected %x\n",
+		status, bitmask);
+	return -1;
+}
+
+unsigned int spi_crop_chunk(unsigned int cmd_len, unsigned int buf_len)
+{
+	return min(cntlr.databytes, buf_len);
+}
+
+int spi_xfer(struct spi_slave *slave, const void *dout,
+		unsigned int bytesout, void *din, unsigned int bytesin)
+{
+	uint16_t control;
+	int16_t opcode_index;
+	int with_address;
+	int status;
+
+	spi_transaction trans = {
+		dout, bytesout,
+		din, bytesin,
+		0xff, 0xff, 0
+	};
+
+	/* There has to always at least be an opcode. */
+	if (!bytesout || !dout) {
+		printk(BIOS_DEBUG, "ICH SPI: No opcode for transfer\n");
+		return -1;
+	}
+	/* Make sure if we read something we have a place to put it. */
+	if (bytesin != 0 && !din) {
+		printk(BIOS_DEBUG, "ICH SPI: Read but no target buffer\n");
+		return -1;
+	}
+
+	if (ich_status_poll(SPIS_SCIP, 0) == -1)
+		return -1;
+
+	writew_(SPIS_CDS | SPIS_FCERR, cntlr.status);
+
+	spi_setup_type(&trans);
+	opcode_index = spi_setup_opcode(&trans);
+	if (opcode_index < 0)
+		return -1;
+	with_address = spi_setup_offset(&trans);
+	if (with_address < 0)
+		return -1;
+
+	if (!ichspi_lock && trans.opcode == SPI_OPCODE_WREN) {
+		/*
+		 * Treat Write Enable as Atomic Pre-Op if possible
+		 * in order to prevent the Management Engine from
+		 * issuing a transaction between WREN and DATA.
+		 */
+		writew_(trans.opcode, cntlr.preop);
+		return 0;
+	}
+
+	/* Preset control fields */
+	control = SPIC_SCGO | ((opcode_index & 0x07) << 4);
+
+	/* Issue atomic preop cycle if needed */
+	if (readw_(cntlr.preop))
+		control |= SPIC_ACS;
+
+	if (!trans.bytesout && !trans.bytesin) {
+		/* SPI addresses are 24 bit only */
+		if (with_address)
+			writel_(trans.offset & 0x00FFFFFF, cntlr.addr);
+
+		/*
+		 * This is a 'no data' command (like Write Enable), its
+		 * bitesout size was 1, decremented to zero while executing
+		 * spi_setup_opcode() above. Tell the chip to send the
+		 * command.
+		 */
+		writew_(control, cntlr.control);
+
+		/* wait for the result */
+		status = ich_status_poll(SPIS_CDS | SPIS_FCERR, 1);
+		if (status == -1)
+			return -1;
+
+		if (status & SPIS_FCERR) {
+			printk(BIOS_DEBUG, "ICH SPI: Command transaction error\n");
+			return -1;
+		}
+
+		goto spi_xfer_exit;
+	}
+
+	/*
+	 * Check if this is a write command attempting to transfer more bytes
+	 * than the controller can handle. Iterations for writes are not
+	 * supported here because each SPI write command needs to be preceded
+	 * and followed by other SPI commands, and this sequence is controlled
+	 * by the SPI chip driver.
+	 */
+	if (trans.bytesout > cntlr.databytes) {
+		printk(BIOS_DEBUG, "ICH SPI: Too much to write. Does your SPI chip driver use"
+		     " spi_crop_chunk()?\n");
+		return -1;
+	}
+
+	/*
+	 * Read or write up to databytes bytes at a time until everything has
+	 * been sent.
+	 */
+	while (trans.bytesout || trans.bytesin) {
+		uint32_t data_length;
+
+		/* SPI addresses are 24 bit only */
+		writel_(trans.offset & 0x00FFFFFF, cntlr.addr);
+
+		if (trans.bytesout)
+			data_length = min(trans.bytesout, cntlr.databytes);
+		else
+			data_length = min(trans.bytesin, cntlr.databytes);
+
+		/* Program data into FDATA0 to N */
+		if (trans.bytesout) {
+			write_reg(trans.out, cntlr.data, data_length);
+			spi_use_out(&trans, data_length);
+			if (with_address)
+				trans.offset += data_length;
+		}
+
+		/* Add proper control fields' values */
+		control &= ~((cntlr.databytes - 1) << 8);
+		control |= SPIC_DS;
+		control |= (data_length - 1) << 8;
+
+		/* write it */
+		writew_(control, cntlr.control);
+
+		/* Wait for Cycle Done Status or Flash Cycle Error. */
+		status = ich_status_poll(SPIS_CDS | SPIS_FCERR, 1);
+		if (status == -1)
+			return -1;
+
+		if (status & SPIS_FCERR) {
+			printk(BIOS_DEBUG, "ICH SPI: Data transaction error\n");
+			return -1;
+		}
+
+		if (trans.bytesin) {
+			read_reg(cntlr.data, trans.in, data_length);
+			spi_use_in(&trans, data_length);
+			if (with_address)
+				trans.offset += data_length;
+		}
+	}
+
+spi_xfer_exit:
+	/* Clear atomic preop now that xfer is done */
+	writew_(0, cntlr.preop);
+
+	return 0;
+}
diff --git a/src/soc/intel/fsp_broadwell_de/uart.c b/src/soc/intel/fsp_broadwell_de/uart.c
new file mode 100644
index 0000000..d22dd0d
--- /dev/null
+++ b/src/soc/intel/fsp_broadwell_de/uart.c
@@ -0,0 +1,112 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2003 Eric Biederman
+ * Copyright (C) 2006-2010 coresystems GmbH
+ * Copyright (C) 2015-2016 Intel Corporation
+ *
+ * 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.
+ */
+
+#include <rules.h>
+#include <stdlib.h>
+#include <arch/io.h>
+#include <console/uart.h>
+#include <trace.h>
+#include <drivers/uart/uart8250reg.h>
+
+#ifndef __ROMCC__
+#include <boot/coreboot_tables.h>
+#endif
+
+/* Expected character delay at 1200bps is 9ms for a working UART
+ * and no flow-control. Assume UART as stuck if shift register
+ * or FIFO takes more than 50ms per character to appear empty.
+ *
+ * Estimated that inb() from UART takes 1 microsecond.
+ */
+#define SINGLE_CHAR_TIMEOUT	(50 * 1000)
+#define FIFO_TIMEOUT		(16 * SINGLE_CHAR_TIMEOUT)
+
+static int uart8250_can_tx_byte(unsigned base_port)
+{
+	return inb(base_port + UART8250_LSR) & UART8250_LSR_THRE;
+}
+
+static void uart8250_tx_byte(unsigned base_port, unsigned char data)
+{
+	unsigned long int i = SINGLE_CHAR_TIMEOUT;
+	while (i-- && !uart8250_can_tx_byte(base_port));
+	outb(data, base_port + UART8250_TBR);
+}
+
+static void uart8250_tx_flush(unsigned base_port)
+{
+	unsigned long int i = FIFO_TIMEOUT;
+	while (i-- && !(inb(base_port + UART8250_LSR) & UART8250_LSR_TEMT));
+}
+
+static int uart8250_can_rx_byte(unsigned base_port)
+{
+	return inb(base_port + UART8250_LSR) & UART8250_LSR_DR;
+}
+
+static unsigned char uart8250_rx_byte(unsigned base_port)
+{
+	unsigned long int i = SINGLE_CHAR_TIMEOUT;
+	while (i-- && !uart8250_can_rx_byte(base_port));
+
+	if (i)
+		return inb(base_port + UART8250_RBR);
+	else
+		return 0x0;
+}
+
+static const unsigned bases[] = { 0x3f8, 0x2f8 };
+
+uintptr_t uart_platform_base(int idx)
+{
+	if (idx < ARRAY_SIZE(bases))
+		return bases[idx];
+	return 0;
+}
+
+void uart_init(int idx)
+{
+	// No needed to configure as setting has been done in BDX-DE FSP
+}
+
+void uart_tx_byte(int idx, unsigned char data)
+{
+	uart8250_tx_byte(uart_platform_base(idx), data);
+}
+
+unsigned char uart_rx_byte(int idx)
+{
+	return uart8250_rx_byte(uart_platform_base(idx));
+}
+
+void uart_tx_flush(int idx)
+{
+	uart8250_tx_flush(uart_platform_base(idx));
+}
+
+#if ENV_RAMSTAGE
+void uart_fill_lb(void *data)
+{
+	struct lb_serial serial;
+	serial.type = LB_SERIAL_TYPE_IO_MAPPED;
+	serial.baseaddr = uart_platform_base(CONFIG_UART_FOR_CONSOLE);
+	serial.baud = default_baudrate();
+	lb_add_serial(&serial, data);
+
+	lb_add_console(LB_TAG_CONSOLE_SERIAL8250, data);
+}
+#endif



More information about the coreboot-gerrit mailing list