[coreboot-gerrit] Patch set updated for coreboot: soc/intel/kabylake: Initial SoC Commit

Naveenkrishna Ch (naveenkrishna.ch@intel.com) gerrit at coreboot.org
Mon Jul 25 12:41:06 CEST 2016


Naveenkrishna Ch (naveenkrishna.ch at intel.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/15768

-gerrit

commit a207c8a8418f3624d03a503c599e0ffdbc0d6800
Author: Naveen Krishna Chatradhi <naveenkrishna.ch at intel.com>
Date:   Tue Jul 5 14:05:53 2016 +0530

    soc/intel/kabylake: Initial SoC Commit
    
    Cloned entirely from Skylake
    commit-id: 67870f508fbec35be393efccdac2c658cbc40ed0
    with the following changes:
    1. String Skylake replaced to Kabylake
    2. Year in copyright license updated to 2016
    3. src/soc/intel/kabylake/Makefile.inc retains "skylake"
       to make the kabylake compilable.
       This will be modified when the FSP2.0 header are added.
    
    BUG=chrome-os-partner:55399
    TEST= with the mainboard patches.
      #make menuconfig, select Kabylake SoC, kblrvp3 board.
      #make compiles
    
    Change-Id: I27712f6011f425e2f1bdd35990e89d0596105e06
    Signed-off-by: Naveen Krishna Chatradhi <naveenkrishna.ch at intel.com>
---
 src/soc/intel/kabylake/Kconfig                     |  200 ++++
 src/soc/intel/kabylake/Makefile.inc                |   90 ++
 src/soc/intel/kabylake/acpi.c                      |  609 +++++++++++
 src/soc/intel/kabylake/acpi/cpu.asl                |  118 +++
 src/soc/intel/kabylake/acpi/dptf/charger.asl       |   75 ++
 src/soc/intel/kabylake/acpi/dptf/cpu.asl           |  224 ++++
 src/soc/intel/kabylake/acpi/dptf/dptf.asl          |  116 +++
 src/soc/intel/kabylake/acpi/dptf/fan.asl           |   68 ++
 src/soc/intel/kabylake/acpi/dptf/thermal.asl       |  283 +++++
 src/soc/intel/kabylake/acpi/globalnvs.asl          |   95 ++
 src/soc/intel/kabylake/acpi/gpio.asl               |  115 ++
 src/soc/intel/kabylake/acpi/irqlinks.asl           |  436 ++++++++
 src/soc/intel/kabylake/acpi/lpc.asl                |  144 +++
 src/soc/intel/kabylake/acpi/pch.asl                |   72 ++
 src/soc/intel/kabylake/acpi/pch_hda.asl            |   84 ++
 src/soc/intel/kabylake/acpi/pci_irqs.asl           |  133 +++
 src/soc/intel/kabylake/acpi/pcie.asl               |  316 ++++++
 src/soc/intel/kabylake/acpi/pcr.asl                |   71 ++
 src/soc/intel/kabylake/acpi/platform.asl           |   84 ++
 src/soc/intel/kabylake/acpi/pmc.asl                |   41 +
 src/soc/intel/kabylake/acpi/scs.asl                |  127 +++
 src/soc/intel/kabylake/acpi/serialio.asl           |   83 ++
 src/soc/intel/kabylake/acpi/sleepstates.asl        |   23 +
 src/soc/intel/kabylake/acpi/smbus.asl              |  238 +++++
 src/soc/intel/kabylake/acpi/systemagent.asl        |  372 +++++++
 src/soc/intel/kabylake/acpi/xhci.asl               |  185 ++++
 src/soc/intel/kabylake/bootblock/cpu.c             |  165 +++
 src/soc/intel/kabylake/bootblock/pch.c             |   58 ++
 src/soc/intel/kabylake/bootblock/systemagent.c     |   41 +
 src/soc/intel/kabylake/bootblock/timestamp.inc     |   35 +
 src/soc/intel/kabylake/chip.c                      | 1102 ++++++++++++++++++++
 src/soc/intel/kabylake/chip.h                      |  386 +++++++
 src/soc/intel/kabylake/cpu.c                       |  494 +++++++++
 src/soc/intel/kabylake/cpu_info.c                  |   50 +
 src/soc/intel/kabylake/dsp.c                       |   33 +
 src/soc/intel/kabylake/elog.c                      |  125 +++
 src/soc/intel/kabylake/finalize.c                  |  221 ++++
 src/soc/intel/kabylake/flash_controller.c          |  437 ++++++++
 src/soc/intel/kabylake/fsp_reset.c                 |   62 ++
 src/soc/intel/kabylake/gpio.c                      |  415 ++++++++
 src/soc/intel/kabylake/i2c.c                       |  116 +++
 src/soc/intel/kabylake/igd.c                       |  219 ++++
 src/soc/intel/kabylake/include/soc/acpi.h          |   37 +
 src/soc/intel/kabylake/include/soc/car_setup.S     |  334 ++++++
 src/soc/intel/kabylake/include/soc/car_teardown.S  |   54 +
 src/soc/intel/kabylake/include/soc/cpu.h           |   65 ++
 src/soc/intel/kabylake/include/soc/device_nvs.h    |   43 +
 .../intel/kabylake/include/soc/flash_controller.h  |  181 ++++
 src/soc/intel/kabylake/include/soc/gpe.h           |  133 +++
 src/soc/intel/kabylake/include/soc/gpio.h          |  174 ++++
 src/soc/intel/kabylake/include/soc/gpio_defs.h     |  509 +++++++++
 src/soc/intel/kabylake/include/soc/interrupt.h     |   46 +
 src/soc/intel/kabylake/include/soc/iomap.h         |   71 ++
 src/soc/intel/kabylake/include/soc/irq.h           |  103 ++
 src/soc/intel/kabylake/include/soc/lpc.h           |   58 ++
 src/soc/intel/kabylake/include/soc/me.h            |  182 ++++
 src/soc/intel/kabylake/include/soc/msr.h           |  109 ++
 src/soc/intel/kabylake/include/soc/nhlt.h          |   63 ++
 src/soc/intel/kabylake/include/soc/nvs.h           |   68 ++
 src/soc/intel/kabylake/include/soc/pch.h           |   38 +
 src/soc/intel/kabylake/include/soc/pci_devs.h      |  179 ++++
 src/soc/intel/kabylake/include/soc/pcr.h           |  120 +++
 src/soc/intel/kabylake/include/soc/pei_data.h      |   99 ++
 src/soc/intel/kabylake/include/soc/pei_wrapper.h   |   27 +
 src/soc/intel/kabylake/include/soc/pm.h            |  194 ++++
 src/soc/intel/kabylake/include/soc/pmc.h           |  112 ++
 src/soc/intel/kabylake/include/soc/ramstage.h      |   31 +
 src/soc/intel/kabylake/include/soc/romstage.h      |   36 +
 src/soc/intel/kabylake/include/soc/serialio.h      |   56 +
 src/soc/intel/kabylake/include/soc/smbus.h         |   51 +
 src/soc/intel/kabylake/include/soc/smm.h           |   88 ++
 src/soc/intel/kabylake/include/soc/spi.h           |  136 +++
 src/soc/intel/kabylake/include/soc/systemagent.h   |  122 +++
 src/soc/intel/kabylake/include/soc/usb.h           |  172 +++
 src/soc/intel/kabylake/include/soc/vr_config.h     |   80 ++
 src/soc/intel/kabylake/include/soc/xhci.h          |   60 ++
 src/soc/intel/kabylake/lpc.c                       |  327 ++++++
 src/soc/intel/kabylake/me_status.c                 |  324 ++++++
 src/soc/intel/kabylake/memmap.c                    |  207 ++++
 src/soc/intel/kabylake/monotonic_timer.c           |   39 +
 src/soc/intel/kabylake/nhlt/Makefile.inc           |   47 +
 src/soc/intel/kabylake/nhlt/dmic.c                 |  116 +++
 src/soc/intel/kabylake/nhlt/max98357.c             |   47 +
 src/soc/intel/kabylake/nhlt/nau88l25.c             |   71 ++
 src/soc/intel/kabylake/nhlt/ssm4567.c              |   70 ++
 src/soc/intel/kabylake/pch.c                       |   97 ++
 src/soc/intel/kabylake/pcie.c                      |  106 ++
 src/soc/intel/kabylake/pcr.c                       |  187 ++++
 src/soc/intel/kabylake/pei_data.c                  |   49 +
 src/soc/intel/kabylake/pmc.c                       |  312 ++++++
 src/soc/intel/kabylake/pmutil.c                    |  439 ++++++++
 src/soc/intel/kabylake/ramstage.c                  |   23 +
 src/soc/intel/kabylake/romstage/Makefile.inc       |   21 +
 src/soc/intel/kabylake/romstage/cpu.c              |   52 +
 src/soc/intel/kabylake/romstage/i2c.c              |  109 ++
 src/soc/intel/kabylake/romstage/pch.c              |  133 +++
 src/soc/intel/kabylake/romstage/power_state.c      |  180 ++++
 src/soc/intel/kabylake/romstage/report_platform.c  |  216 ++++
 src/soc/intel/kabylake/romstage/romstage.c         |  268 +++++
 src/soc/intel/kabylake/romstage/smbus.c            |   51 +
 src/soc/intel/kabylake/romstage/spi.c              |   42 +
 src/soc/intel/kabylake/romstage/systemagent.c      |   52 +
 src/soc/intel/kabylake/romstage/uart.c             |   70 ++
 src/soc/intel/kabylake/sd.c                        |   88 ++
 src/soc/intel/kabylake/smbus.c                     |  109 ++
 src/soc/intel/kabylake/smbus_common.c              |  150 +++
 src/soc/intel/kabylake/smi.c                       |  121 +++
 src/soc/intel/kabylake/smihandler.c                |  517 +++++++++
 src/soc/intel/kabylake/smmrelocate.c               |  317 ++++++
 src/soc/intel/kabylake/systemagent.c               |  424 ++++++++
 src/soc/intel/kabylake/tsc_freq.c                  |   29 +
 src/soc/intel/kabylake/uart.c                      |   63 ++
 src/soc/intel/kabylake/uart_debug.c                |   26 +
 src/soc/intel/kabylake/vr_config.c                 |  107 ++
 src/soc/intel/kabylake/xhci.c                      |   43 +
 115 files changed, 17841 insertions(+)

diff --git a/src/soc/intel/kabylake/Kconfig b/src/soc/intel/kabylake/Kconfig
new file mode 100644
index 0000000..893c35a
--- /dev/null
+++ b/src/soc/intel/kabylake/Kconfig
@@ -0,0 +1,200 @@
+config SOC_INTEL_KABYLAKE
+	bool
+	help
+	  Intel Kabylake support
+
+if SOC_INTEL_KABYLAKE
+
+config CPU_SPECIFIC_OPTIONS
+	def_bool y
+	select ACPI_INTEL_HARDWARE_SLEEP_VALUES
+	select ARCH_BOOTBLOCK_X86_32
+	select ARCH_RAMSTAGE_X86_32
+	select ARCH_ROMSTAGE_X86_32
+	select ARCH_VERSTAGE_X86_32
+	select ACPI_NHLT
+	select CACHE_MRC_SETTINGS
+	select CACHE_RELOCATED_RAMSTAGE_OUTSIDE_CBMEM if RELOCATABLE_RAMSTAGE
+	select COLLECT_TIMESTAMPS
+	select CPU_INTEL_FIRMWARE_INTERFACE_TABLE
+	select GENERIC_GPIO_LIB
+	select HAVE_HARD_RESET
+	select HAVE_INTEL_FIRMWARE
+	select HAVE_MONOTONIC_TIMER
+	select HAVE_SMI_HANDLER
+	select IOAPIC
+	select MMCONF_SUPPORT
+	select MMCONF_SUPPORT_DEFAULT
+	select NO_FIXED_XIP_ROM_SIZE
+	select MRC_SETTINGS_PROTECT
+	select PARALLEL_MP
+	select PCIEXP_ASPM
+	select PCIEXP_COMMON_CLOCK
+	select PCIEXP_CLK_PM
+	select PCIEXP_L1_SUB_STATE
+	select PLATFORM_USES_FSP1_1
+	select REG_SCRIPT
+	select RELOCATABLE_MODULES
+	select RELOCATABLE_RAMSTAGE
+	select SOC_INTEL_COMMON
+	select SOC_INTEL_COMMON_ACPI_WAKE_SOURCE
+	select SOC_INTEL_COMMON_LPSS_I2C
+	select SOC_INTEL_COMMON_NHLT
+	select SOC_INTEL_COMMON_RESET
+	select SMM_TSEG
+	select SMP
+	select SPI_FLASH
+	select SSE2
+	select SUPPORT_CPU_UCODE_IN_CBFS
+	select TSC_CONSTANT_RATE
+	select TSC_SYNC_MFENCE
+	select UDELAY_TSC
+	select USE_GENERIC_FSP_CAR_INC
+
+config BOOTBLOCK_CPU_INIT
+	string
+	default "soc/intel/kabylake/bootblock/cpu.c"
+
+config BOOTBLOCK_NORTHBRIDGE_INIT
+	string
+	default "soc/intel/kabylake/bootblock/systemagent.c"
+
+config BOOTBLOCK_RESETS
+	string
+	default "soc/intel/common/reset.c"
+
+config BOOTBLOCK_SOUTHBRIDGE_INIT
+	string
+	default "soc/intel/kabylake/bootblock/pch.c"
+
+config CBFS_SIZE
+	hex
+	default 0x200000
+
+config CPU_ADDR_BITS
+	int
+	default 36
+
+config SOC_INTEL_COMMON_LPSS_I2C_CLOCK_MHZ
+	int
+	default 120
+
+config DCACHE_RAM_BASE
+	hex "Base address of cache-as-RAM"
+	default 0xfef00000
+
+config DCACHE_RAM_SIZE
+	hex "Length in bytes of cache-as-RAM"
+	default 0x10000
+	help
+	  The size of the cache-as-ram region required during bootblock
+	  and/or romstage.
+
+config EXCLUDE_NATIVE_SD_INTERFACE
+	bool
+	default n
+	help
+	  If you set this option to n, will not use native SD controller.
+
+config HEAP_SIZE
+	hex
+	default 0x80000
+
+config IED_REGION_SIZE
+	hex
+	default 0x400000
+
+config MMCONF_BASE_ADDRESS
+	hex "MMIO Base Address"
+	default 0xe0000000
+
+config MONOTONIC_TIMER_MSR
+	def_bool y
+	select HAVE_MONOTONIC_TIMER
+	help
+	  Provide a monotonic timer using the 24MHz MSR counter.
+
+config PRE_GRAPHICS_DELAY
+	int "Graphics initialization delay in ms"
+	default 0
+	help
+	  On some systems, coreboot boots so fast that connected monitors
+	  (mostly TVs) won't be able to wake up fast enough to talk to the
+	  VBIOS. On those systems we need to wait for a bit before executing
+	  the VBIOS.
+
+config SERIAL_CPU_INIT
+	bool
+	default n
+
+config SERIRQ_CONTINUOUS_MODE
+	bool
+	default n
+	help
+	  If you set this option to y, the serial IRQ machine will be
+	  operated in continuous mode.
+
+config SMM_RESERVED_SIZE
+	hex
+	default 0x200000
+
+config SMM_TSEG_SIZE
+	hex
+	default 0x800000
+
+config VGA_BIOS_ID
+	string
+	default "8086,0406"
+
+config UART_DEBUG
+	bool "Enable UART debug port."
+	default n
+	select CONSOLE_SERIAL
+	select DRIVERS_UART
+	select DRIVERS_UART_8250MEM_32
+
+config CHIPSET_BOOTBLOCK_INCLUDE
+	string
+	default "soc/intel/kabylake/bootblock/timestamp.inc"
+
+config NHLT_DMIC_2CH
+	bool
+	default n
+	help
+	  Include DSP firmware settings for 2 channel DMIC array.
+
+config NHLT_DMIC_4CH
+	bool
+	default n
+	help
+	  Include DSP firmware settings for 4 channel DMIC array.
+
+config NHLT_NAU88L25
+	bool
+	default n
+	help
+	  Include DSP firmware settings for nau88l25 headset codec.
+
+config NHLT_MAX98357
+	bool
+	default n
+	help
+	  Include DSP firmware settings for max98357 amplifier.
+
+config NHLT_SSM4567
+	bool
+	default n
+	help
+	  Include DSP firmware settings for ssm4567 smart amplifier.
+
+config DCACHE_RAM_SIZE_TOTAL
+	hex
+	default 0x40000
+
+config SKIP_FSP_CAR
+	bool "Skip cache as RAM setup in FSP"
+	default y
+	help
+	  Skip Cache as RAM setup in FSP.
+
+endif
diff --git a/src/soc/intel/kabylake/Makefile.inc b/src/soc/intel/kabylake/Makefile.inc
new file mode 100644
index 0000000..be2b5fe
--- /dev/null
+++ b/src/soc/intel/kabylake/Makefile.inc
@@ -0,0 +1,90 @@
+ifeq ($(CONFIG_SOC_INTEL_KABYLAKE),y)
+
+subdirs-y += nhlt
+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/smm
+subdirs-y += ../../../cpu/x86/tsc
+
+verstage-y += gpio.c
+verstage-y += memmap.c
+verstage-y += monotonic_timer.c
+verstage-y += pch.c
+verstage-y += pmutil.c
+verstage-y += pcr.c
+verstage-y += tsc_freq.c
+verstage-$(CONFIG_UART_DEBUG) += uart_debug.c
+
+romstage-y += flash_controller.c
+romstage-y += gpio.c
+romstage-y += memmap.c
+romstage-y += monotonic_timer.c
+romstage-y += pch.c
+romstage-y += pcr.c
+romstage-y += pei_data.c
+romstage-y += pmutil.c
+romstage-y += smbus_common.c
+romstage-y += tsc_freq.c
+romstage-$(CONFIG_UART_DEBUG) += uart_debug.c
+
+ramstage-$(CONFIG_HAVE_ACPI_TABLES) += acpi.c
+ramstage-y += chip.c
+ramstage-y += cpu.c
+ramstage-y += cpu_info.c
+ramstage-y += dsp.c
+ramstage-y += elog.c
+ramstage-y += finalize.c
+ramstage-y += flash_controller.c
+ramstage-$(CONFIG_VBOOT_VERIFY_FIRMWARE) += fsp_reset.c
+ramstage-y += gpio.c
+ramstage-y += i2c.c
+ramstage-y += igd.c
+ramstage-y += lpc.c
+ramstage-y += me_status.c
+ramstage-y += memmap.c
+ramstage-y += monotonic_timer.c
+ramstage-y += pch.c
+ramstage-y += pcie.c
+ramstage-y += pcr.c
+ramstage-y += pei_data.c
+ramstage-y += pmc.c
+ramstage-y += pmutil.c
+ramstage-y += ramstage.c
+ramstage-y += sd.c
+ramstage-y += smbus.c
+ramstage-y += smbus_common.c
+ramstage-y += smi.c
+ramstage-y += smmrelocate.c
+ramstage-y += systemagent.c
+ramstage-y += tsc_freq.c
+ramstage-y += uart.c
+ramstage-$(CONFIG_UART_DEBUG) += uart_debug.c
+ramstage-y += vr_config.c
+ramstage-y += xhci.c
+
+smm-y += cpu_info.c
+smm-y += gpio.c
+smm-y += monotonic_timer.c
+smm-y += pcr.c
+smm-y += pch.c
+smm-y += pmutil.c
+smm-y += smihandler.c
+smm-$(CONFIG_SPI_FLASH_SMM) += flash_controller.c
+smm-y += tsc_freq.c
+smm-$(CONFIG_UART_DEBUG) += uart_debug.c
+
+# cpu_microcode_bins += ???
+
+CPPFLAGS_common += -I$(src)/soc/intel/kabylake
+CPPFLAGS_common += -I$(src)/soc/intel/kabylake/include
+CPPFLAGS_common += -I$(src)/vendorcode/intel/fsp/fsp1_1/skylake
+
+# Currently used for microcode path.
+CPPFLAGS_common += -I3rdparty/blobs/mainboard/$(CONFIG_MAINBOARD_DIR)
+
+ROMCCFLAGS := -mcpu=p4 -fno-simplify-phi -O2
+
+endif
diff --git a/src/soc/intel/kabylake/acpi.c b/src/soc/intel/kabylake/acpi.c
new file mode 100644
index 0000000..14a84ae
--- /dev/null
+++ b/src/soc/intel/kabylake/acpi.c
@@ -0,0 +1,609 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2009 coresystems GmbH
+ * Copyright (C) 2014 Google Inc.
+ * 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 <arch/acpi.h>
+#include <arch/acpigen.h>
+#include <arch/cpu.h>
+#include <arch/io.h>
+#include <arch/ioapic.h>
+#include <arch/smp/mpspec.h>
+#include <cbmem.h>
+#include <chip.h>
+#include <console/console.h>
+#include <cpu/cpu.h>
+#include <cpu/x86/smm.h>
+#include <cpu/x86/msr.h>
+#include <cpu/x86/tsc.h>
+#include <cpu/intel/turbo.h>
+#include <ec/google/chromeec/ec.h>
+#include <soc/intel/common/acpi.h>
+#include <soc/acpi.h>
+#include <soc/cpu.h>
+#include <soc/iomap.h>
+#include <soc/lpc.h>
+#include <soc/msr.h>
+#include <soc/pci_devs.h>
+#include <soc/pm.h>
+#include <string.h>
+#include <types.h>
+#include <vendorcode/google/chromeos/gnvs.h>
+#include <wrdd.h>
+
+/*
+ * List of suported C-states in this processor.
+ */
+enum {
+	C_STATE_C0,		/* 0 */
+	C_STATE_C1,		/* 1 */
+	C_STATE_C1E,		/* 2 */
+	C_STATE_C3,		/* 3 */
+	C_STATE_C6_SHORT_LAT,	/* 4 */
+	C_STATE_C6_LONG_LAT,	/* 5 */
+	C_STATE_C7_SHORT_LAT,	/* 6 */
+	C_STATE_C7_LONG_LAT,	/* 7 */
+	C_STATE_C7S_SHORT_LAT,	/* 8 */
+	C_STATE_C7S_LONG_LAT,	/* 9 */
+	C_STATE_C8,		/* 10 */
+	C_STATE_C9,		/* 11 */
+	C_STATE_C10,		/* 12 */
+	NUM_C_STATES
+};
+#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,	\
+	}
+
+static acpi_cstate_t cstate_map[NUM_C_STATES] = {
+	[C_STATE_C0] = { },
+	[C_STATE_C1] = {
+		.latency = 0,
+		.power = C1_POWER,
+		.resource = MWAIT_RES(0, 0),
+	},
+	[C_STATE_C1E] = {
+		.latency = 0,
+		.power = C1_POWER,
+		.resource = MWAIT_RES(0, 1),
+	},
+	[C_STATE_C3] = {
+		.latency = C_STATE_LATENCY_FROM_LAT_REG(0),
+		.power = C3_POWER,
+		.resource = MWAIT_RES(1, 0),
+	},
+	[C_STATE_C6_SHORT_LAT] = {
+		.latency = C_STATE_LATENCY_FROM_LAT_REG(1),
+		.power = C6_POWER,
+		.resource = MWAIT_RES(2, 0),
+	},
+	[C_STATE_C6_LONG_LAT] = {
+		.latency = C_STATE_LATENCY_FROM_LAT_REG(2),
+		.power = C6_POWER,
+		.resource = MWAIT_RES(2, 1),
+	},
+	[C_STATE_C7_SHORT_LAT] = {
+		.latency = C_STATE_LATENCY_FROM_LAT_REG(1),
+		.power = C7_POWER,
+		.resource = MWAIT_RES(3, 0),
+	},
+	[C_STATE_C7_LONG_LAT] = {
+		.latency = C_STATE_LATENCY_FROM_LAT_REG(2),
+		.power = C7_POWER,
+		.resource = MWAIT_RES(3, 1),
+	},
+	[C_STATE_C7S_SHORT_LAT] = {
+		.latency = C_STATE_LATENCY_FROM_LAT_REG(1),
+		.power = C7_POWER,
+		.resource = MWAIT_RES(3, 2),
+	},
+	[C_STATE_C7S_LONG_LAT] = {
+		.latency = C_STATE_LATENCY_FROM_LAT_REG(2),
+		.power = C7_POWER,
+		.resource = MWAIT_RES(3, 3),
+	},
+	[C_STATE_C8] = {
+		.latency = C_STATE_LATENCY_FROM_LAT_REG(3),
+		.power = C8_POWER,
+		.resource = MWAIT_RES(4, 0),
+	},
+	[C_STATE_C9] = {
+		.latency = C_STATE_LATENCY_FROM_LAT_REG(4),
+		.power = C9_POWER,
+		.resource = MWAIT_RES(5, 0),
+	},
+	[C_STATE_C10] = {
+		.latency = C_STATE_LATENCY_FROM_LAT_REG(5),
+		.power = C10_POWER,
+		.resource = MWAIT_RES(6, 0),
+	},
+};
+
+static int cstate_set_s0ix[] = {
+	C_STATE_C1E,
+	C_STATE_C7S_LONG_LAT,
+	C_STATE_C10
+};
+
+static int cstate_set_non_s0ix[] = {
+	C_STATE_C1E,
+	C_STATE_C3,
+	C_STATE_C7S_LONG_LAT,
+	C_STATE_C8,
+	C_STATE_C9,
+	C_STATE_C10
+};
+
+static int get_cores_per_package(void)
+{
+	struct cpuinfo_x86 c;
+	struct cpuid_result result;
+	int cores = 1;
+
+	get_fms(&c, cpuid_eax(1));
+	if (c.x86 != 6)
+		return 1;
+
+	result = cpuid_ext(0xb, 1);
+	cores = result.ebx & 0xff;
+
+	return cores;
+}
+
+static void acpi_create_gnvs(global_nvs_t *gnvs)
+{
+	const struct device *dev = dev_find_slot(0, PCH_DEVFN_LPC);
+	const struct soc_intel_kabylake_config *config = dev->chip_info;
+
+	/* Set unknown wake source */
+	gnvs->pm1i = -1;
+
+	/* CPU core count */
+	gnvs->pcnt = dev_count_cpu();
+
+#if IS_ENABLED(CONFIG_CONSOLE_CBMEM)
+	/* Update the mem console pointer. */
+	gnvs->cbmc = (u32)cbmem_find(CBMEM_ID_CONSOLE);
+#endif
+
+#if IS_ENABLED(CONFIG_CHROMEOS)
+	/* Initialize Verified Boot data */
+	chromeos_init_vboot(&(gnvs->chromeos));
+#if IS_ENABLED(CONFIG_EC_GOOGLE_CHROMEEC)
+	gnvs->chromeos.vbt2 = google_ec_running_ro() ?
+		ACTIVE_ECFW_RO : ACTIVE_ECFW_RW;
+#endif
+	gnvs->chromeos.vbt2 = ACTIVE_ECFW_RO;
+#endif
+
+	/* Enable DPTF based on mainboard configuration */
+	gnvs->dpte = config->dptf_enable;
+
+	/* Fill in the Wifi Region id */
+	gnvs->cid1 = wifi_regulatory_domain();
+}
+
+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;
+}
+
+unsigned long acpi_fill_madt(unsigned long current)
+{
+	/* Local APICs */
+	current = acpi_create_madt_lapics(current);
+
+	/* IOAPIC */
+	current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *) current,
+				2, IO_APIC_ADDR, 0);
+
+	return acpi_madt_irq_overrides(current);
+}
+
+void acpi_fill_in_fadt(acpi_fadt_t *fadt)
+{
+	const uint16_t pmbase = ACPI_BASE_ADDRESS;
+	const struct device *dev = dev_find_slot(0, PCH_DEVFN_LPC);
+	config_t *config = dev->chip_info;
+
+	fadt->sci_int = acpi_sci_irq();
+	fadt->smi_cmd = APM_CNT;
+	fadt->acpi_enable = APM_CNT_ACPI_ENABLE;
+	fadt->acpi_disable = APM_CNT_ACPI_DISABLE;
+	fadt->s4bios_req = 0x0;
+	fadt->pstate_cnt = 0;
+
+	fadt->pm1a_evt_blk = pmbase + PM1_STS;
+	fadt->pm1b_evt_blk = 0x0;
+	fadt->pm1a_cnt_blk = pmbase + PM1_CNT;
+	fadt->pm1b_cnt_blk = 0x0;
+	fadt->pm2_cnt_blk = pmbase + PM2_CNT;
+	if (config->PmTimerDisabled == 0)
+		fadt->pm_tmr_blk = pmbase + PM1_TMR;
+	fadt->gpe0_blk = pmbase + GPE0_STS(0);
+	fadt->gpe1_blk = 0;
+
+	fadt->pm1_evt_len = 4;
+	fadt->pm1_cnt_len = 2;
+	fadt->pm2_cnt_len = 1;
+	if (config->PmTimerDisabled == 0)
+		fadt->pm_tmr_len = 4;
+	/* There are 4 GPE0 STS/EN pairs each 32 bits wide. */
+	fadt->gpe0_blk_len = 2 * GPE0_REG_MAX * sizeof(uint32_t);
+	fadt->gpe1_blk_len = 0;
+	fadt->gpe1_base = 0;
+	fadt->cst_cnt = 0;
+	fadt->p_lvl2_lat = 1;
+	fadt->p_lvl3_lat = 87;
+	fadt->flush_size = 1024;
+	fadt->flush_stride = 16;
+	fadt->duty_offset = 1;
+	fadt->duty_width = 0;
+	fadt->day_alrm = 0xd;
+	fadt->mon_alrm = 0x00;
+	fadt->century = 0x00;
+	fadt->iapc_boot_arch = ACPI_FADT_LEGACY_DEVICES | ACPI_FADT_8042;
+
+	fadt->flags = ACPI_FADT_WBINVD | ACPI_FADT_C1_SUPPORTED |
+			ACPI_FADT_C2_MP_SUPPORTED | ACPI_FADT_SLEEP_BUTTON |
+			ACPI_FADT_RESET_REGISTER | ACPI_FADT_SEALED_CASE |
+			ACPI_FADT_S4_RTC_WAKE | ACPI_FADT_PLATFORM_CLOCK;
+
+	fadt->reset_reg.space_id = 1;
+	fadt->reset_reg.bit_width = 8;
+	fadt->reset_reg.bit_offset = 0;
+	fadt->reset_reg.resv = 0;
+	fadt->reset_reg.addrl = 0xcf9;
+	fadt->reset_reg.addrh = 0;
+	fadt->reset_value = 6;
+
+	fadt->x_pm1a_evt_blk.space_id = 1;
+	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.resv = 0;
+	fadt->x_pm1a_evt_blk.addrl = pmbase + PM1_STS;
+	fadt->x_pm1a_evt_blk.addrh = 0x0;
+
+	fadt->x_pm1b_evt_blk.space_id = 1;
+	fadt->x_pm1b_evt_blk.bit_width = 0;
+	fadt->x_pm1b_evt_blk.bit_offset = 0;
+	fadt->x_pm1b_evt_blk.resv = 0;
+	fadt->x_pm1b_evt_blk.addrl = 0x0;
+	fadt->x_pm1b_evt_blk.addrh = 0x0;
+
+	fadt->x_pm1a_cnt_blk.space_id = 1;
+	fadt->x_pm1a_cnt_blk.bit_width = fadt->pm1_cnt_len * 8;
+	fadt->x_pm1a_cnt_blk.bit_offset = 0;
+	fadt->x_pm1a_cnt_blk.resv = 0;
+	fadt->x_pm1a_cnt_blk.addrl = pmbase + PM1_CNT;
+	fadt->x_pm1a_cnt_blk.addrh = 0x0;
+
+	fadt->x_pm1b_cnt_blk.space_id = 1;
+	fadt->x_pm1b_cnt_blk.bit_width = 0;
+	fadt->x_pm1b_cnt_blk.bit_offset = 0;
+	fadt->x_pm1b_cnt_blk.resv = 0;
+	fadt->x_pm1b_cnt_blk.addrl = 0x0;
+	fadt->x_pm1b_cnt_blk.addrh = 0x0;
+
+	fadt->x_pm2_cnt_blk.space_id = 1;
+	fadt->x_pm2_cnt_blk.bit_width = fadt->pm2_cnt_len * 8;
+	fadt->x_pm2_cnt_blk.bit_offset = 0;
+	fadt->x_pm2_cnt_blk.resv = 0;
+	fadt->x_pm2_cnt_blk.addrl = pmbase + PM2_CNT;
+	fadt->x_pm2_cnt_blk.addrh = 0x0;
+
+	if (config->PmTimerDisabled == 0) {
+		fadt->x_pm_tmr_blk.space_id = 1;
+		fadt->x_pm_tmr_blk.bit_width = fadt->pm_tmr_len * 8;
+		fadt->x_pm_tmr_blk.bit_offset = 0;
+		fadt->x_pm_tmr_blk.resv = 0;
+		fadt->x_pm_tmr_blk.addrl = pmbase + PM1_TMR;
+		fadt->x_pm_tmr_blk.addrh = 0x0;
+	}
+
+	fadt->x_gpe0_blk.space_id = 0;
+	fadt->x_gpe0_blk.bit_width = 0;
+	fadt->x_gpe0_blk.bit_offset = 0;
+	fadt->x_gpe0_blk.resv = 0;
+	fadt->x_gpe0_blk.addrl = 0;
+	fadt->x_gpe0_blk.addrh = 0;
+
+	fadt->x_gpe1_blk.space_id = 1;
+	fadt->x_gpe1_blk.bit_width = 0;
+	fadt->x_gpe1_blk.bit_offset = 0;
+	fadt->x_gpe1_blk.resv = 0;
+	fadt->x_gpe1_blk.addrl = 0x0;
+	fadt->x_gpe1_blk.addrh = 0x0;
+}
+
+static void generate_c_state_entries(int s0ix_enable, int max_cstate)
+{
+
+	acpi_cstate_t map[max_cstate];
+	int *set;
+	int i;
+
+	if (s0ix_enable)
+		set = cstate_set_s0ix;
+	else
+		set = cstate_set_non_s0ix;
+
+	for (i = 0; i < max_cstate; i++) {
+		memcpy(&map[i], &cstate_map[set[i]], sizeof(acpi_cstate_t));
+		map[i].ctype = i + 1;
+	}
+
+	/* Generate C-state tables */
+	acpigen_write_CST_package(map, ARRAY_SIZE(map));
+}
+
+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_turbo, ratio_step;
+	int coord_type, power_max, power_unit, num_entries;
+	int ratio, power, clock, clock_max;
+	msr_t msr;
+
+	/* Determine P-state coordination type from MISC_PWR_MGMT[0] */
+	msr = rdmsr(MSR_MISC_PWR_MGMT);
+	if (msr.lo & MISC_PWR_MGMT_EIST_HW_DIS)
+		coord_type = SW_ANY;
+	else
+		coord_type = HW_ALL;
+
+	/* Get bus ratio limits and calculate clock speeds */
+	msr = rdmsr(MSR_PLATFORM_INFO);
+	ratio_min = (msr.hi >> (40-32)) & 0xff; /* Max Efficiency Ratio */
+
+	/* Determine if this CPU has configurable TDP */
+	if (cpu_config_tdp_levels()) {
+		/* Set max ratio to nominal TDP ratio */
+		msr = rdmsr(MSR_CONFIG_TDP_NOMINAL);
+		ratio_max = msr.lo & 0xff;
+	} else {
+		/* Max Non-Turbo Ratio */
+		ratio_max = (msr.lo >> 8) & 0xff;
+	}
+	clock_max = ratio_max * CPU_BCLK;
+
+	/* Calculate CPU TDP in mW */
+	msr = rdmsr(MSR_PKG_POWER_SKU_UNIT);
+	power_unit = 2 << ((msr.lo & 0xf) - 1);
+	msr = rdmsr(MSR_PKG_POWER_SKU);
+	power_max = ((msr.lo & 0x7fff) / power_unit) * 1000;
+
+	/* Write _PCT indicating use of FFixedHW */
+	acpigen_write_empty_PCT();
+
+	/* Write _PPC with no limit on supported P-state */
+	acpigen_write_PPC_NVS();
+
+	/* 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 */
+	ratio_step = PSS_RATIO_STEP;
+	num_entries = ((ratio_max - ratio_min) / ratio_step) + 1;
+	if (num_entries > PSS_MAX_ENTRIES) {
+		ratio_step += 1;
+		num_entries = ((ratio_max - ratio_min) / ratio_step) + 1;
+	}
+
+	/* P[T] is Turbo state if enabled */
+	if (get_turbo_state() == TURBO_ENABLED) {
+		/* _PSS package count including Turbo */
+		acpigen_write_package(num_entries + 2);
+
+		msr = rdmsr(MSR_TURBO_RATIO_LIMIT);
+		ratio_turbo = msr.lo & 0xff;
+
+		/* Add entry for Turbo ratio */
+		acpigen_write_PSS_package(
+			clock_max + 1,		/* MHz */
+			power_max,		/* mW */
+			PSS_LATENCY_TRANSITION,	/* lat1 */
+			PSS_LATENCY_BUSMASTER,	/* lat2 */
+			ratio_turbo << 8,	/* control */
+			ratio_turbo << 8);	/* status */
+	} else {
+		/* _PSS package count without Turbo */
+		acpigen_write_package(num_entries + 1);
+	}
+
+	/* First regular entry is max non-turbo ratio */
+	acpigen_write_PSS_package(
+		clock_max,		/* MHz */
+		power_max,		/* mW */
+		PSS_LATENCY_TRANSITION,	/* lat1 */
+		PSS_LATENCY_BUSMASTER,	/* lat2 */
+		ratio_max << 8,		/* control */
+		ratio_max << 8);	/* status */
+
+	/* Generate the remaining entries */
+	for (ratio = ratio_min + ((num_entries - 1) * ratio_step);
+	     ratio >= ratio_min; ratio -= ratio_step) {
+
+		/* Calculate power at this ratio */
+		power = calculate_power(power_max, ratio_max, ratio);
+		clock = ratio * CPU_BCLK;
+
+		acpigen_write_PSS_package(
+			clock,			/* MHz */
+			power,			/* mW */
+			PSS_LATENCY_TRANSITION,	/* lat1 */
+			PSS_LATENCY_BUSMASTER,	/* lat2 */
+			ratio << 8,		/* control */
+			ratio << 8);		/* status */
+	}
+
+	/* Fix package length */
+	acpigen_pop_len();
+}
+
+void generate_cpu_entries(device_t device)
+{
+	int core_id, cpu_id, pcontrol_blk = ACPI_BASE_ADDRESS, plen = 6;
+	int totalcores = dev_count_cpu();
+	int cores_per_package = get_cores_per_package();
+	int numcpus = totalcores/cores_per_package;
+	device_t dev = SA_DEV_ROOT;
+	config_t *config = dev->chip_info;
+	int is_s0ix_enable = config->s0ix_enable;
+	int max_c_state;
+
+	if (is_s0ix_enable)
+		max_c_state = ARRAY_SIZE(cstate_set_s0ix);
+	else
+		max_c_state = ARRAY_SIZE(cstate_set_non_s0ix);
+
+	printk(BIOS_DEBUG, "Found %d CPU(s) with %d core(s) each.\n",
+	       numcpus, cores_per_package);
+
+	for (cpu_id = 0; cpu_id < numcpus; cpu_id++) {
+		for (core_id = 0; core_id < cores_per_package; core_id++) {
+			if (core_id > 0) {
+				pcontrol_blk = 0;
+				plen = 0;
+			}
+
+			/* Generate processor \_PR.CPUx */
+			acpigen_write_processor(
+				cpu_id*cores_per_package+core_id,
+				pcontrol_blk, plen);
+			/* Generate C-state tables */
+			generate_c_state_entries(is_s0ix_enable,
+				max_c_state);
+
+			/* Generate P-state tables */
+			generate_p_state_entries(core_id,
+				cores_per_package);
+
+			acpigen_pop_len();
+		}
+	}
+}
+
+unsigned long acpi_madt_irq_overrides(unsigned long current)
+{
+	int sci = acpi_sci_irq();
+	acpi_madt_irqoverride_t *irqovr;
+	uint16_t flags = MP_IRQ_TRIGGER_LEVEL;
+
+	/* INT_SRC_OVR */
+	irqovr = (void *)current;
+	current += acpi_create_madt_irqoverride(irqovr, 0, 0, 2, 0);
+
+	if (sci >= 20)
+		flags |= MP_IRQ_POLARITY_LOW;
+	else
+		flags |= MP_IRQ_POLARITY_HIGH;
+
+	/* SCI */
+	irqovr = (void *)current;
+	current += acpi_create_madt_irqoverride(irqovr, 0, sci, sci, flags);
+
+	return current;
+}
+
+unsigned long southcluster_write_acpi_tables(device_t device,
+					     unsigned long current,
+					     struct acpi_rsdp *rsdp)
+{
+	current = acpi_write_hpet(device, current, rsdp);
+	return acpi_align_current(current);
+}
+
+void southcluster_inject_dsdt(device_t device)
+{
+	global_nvs_t *gnvs;
+
+	gnvs = cbmem_find(CBMEM_ID_ACPI_GNVS);
+	if (!gnvs) {
+		gnvs = cbmem_add(CBMEM_ID_ACPI_GNVS, sizeof (*gnvs));
+		if (gnvs)
+			memset(gnvs, 0, sizeof(*gnvs));
+	}
+
+	if (gnvs) {
+		acpi_create_gnvs(gnvs);
+		acpi_mainboard_gnvs(gnvs);
+		acpi_save_gnvs((unsigned long)gnvs);
+		/* And tell SMI about it */
+		smm_setup_structures(gnvs, NULL, NULL);
+
+		/* Add it to DSDT.  */
+		acpigen_write_scope("\\");
+		acpigen_write_name_dword("NVSA", (u32) gnvs);
+		acpigen_pop_len();
+	}
+}
+
+/* Save wake source information for calculating ACPI _SWS values */
+int soc_fill_acpi_wake(uint32_t *pm1, uint32_t **gpe0)
+{
+	struct chipset_power_state *ps;
+	static uint32_t gpe0_sts[GPE0_REG_MAX];
+	uint32_t pm1_en;
+	int i;
+
+	ps = cbmem_find(CBMEM_ID_POWER_STATE);
+	if (ps == NULL)
+		return -1;
+
+	/* PM1_EN state is lost in Deep S3 so enable basic wake events */
+	pm1_en = ps->pm1_en | PCIEXPWAK_STS | RTC_STS | PWRBTN_STS | BM_STS;
+	*pm1 = ps->pm1_sts & pm1_en;
+
+	/* Mask off GPE0 status bits that are not enabled */
+	*gpe0 = &gpe0_sts[0];
+	for (i = 0; i < GPE0_REG_MAX; i++)
+		gpe0_sts[i] = ps->gpe0_sts[i] & ps->gpe0_en[i];
+
+	return GPE0_REG_MAX;
+}
+
+__attribute__((weak)) void acpi_mainboard_gnvs(global_nvs_t *gnvs)
+{
+}
diff --git a/src/soc/intel/kabylake/acpi/cpu.asl b/src/soc/intel/kabylake/acpi/cpu.asl
new file mode 100644
index 0000000..a202ceb
--- /dev/null
+++ b/src/soc/intel/kabylake/acpi/cpu.asl
@@ -0,0 +1,118 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 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.
+ */
+
+/* These devices are created at runtime */
+External (\_PR.CP00, DeviceObj)
+External (\_PR.CP01, DeviceObj)
+External (\_PR.CP02, DeviceObj)
+External (\_PR.CP03, DeviceObj)
+External (\_PR.CP04, DeviceObj)
+External (\_PR.CP05, DeviceObj)
+External (\_PR.CP06, DeviceObj)
+External (\_PR.CP07, DeviceObj)
+
+/* Notify OS to re-read CPU tables, assuming ^2 CPU count */
+Method (PNOT)
+{
+	If (LGreaterEqual (\PCNT, 2)) {
+		Notify (\_PR.CP00, 0x81)  // _CST
+		Notify (\_PR.CP01, 0x81)  // _CST
+	}
+	If (LGreaterEqual (\PCNT, 4)) {
+		Notify (\_PR.CP02, 0x81)  // _CST
+		Notify (\_PR.CP03, 0x81)  // _CST
+	}
+	If (LGreaterEqual (\PCNT, 8)) {
+		Notify (\_PR.CP04, 0x81)  // _CST
+		Notify (\_PR.CP05, 0x81)  // _CST
+		Notify (\_PR.CP06, 0x81)  // _CST
+		Notify (\_PR.CP07, 0x81)  // _CST
+	}
+}
+
+/* Notify OS to re-read CPU _PPC limit, assuming ^2 CPU count */
+Method (PPCN)
+{
+	If (LGreaterEqual (\PCNT, 2)) {
+		Notify (\_PR.CP00, 0x80)  // _PPC
+		Notify (\_PR.CP01, 0x80)  // _PPC
+	}
+	If (LGreaterEqual (\PCNT, 4)) {
+		Notify (\_PR.CP02, 0x80)  // _PPC
+		Notify (\_PR.CP03, 0x80)  // _PPC
+	}
+	If (LGreaterEqual (\PCNT, 8)) {
+		Notify (\_PR.CP04, 0x80)  // _PPC
+		Notify (\_PR.CP05, 0x80)  // _PPC
+		Notify (\_PR.CP06, 0x80)  // _PPC
+		Notify (\_PR.CP07, 0x80)  // _PPC
+	}
+}
+
+/* Notify OS to re-read Throttle Limit tables, assuming ^2 CPU count */
+Method (TNOT)
+{
+	If (LGreaterEqual (\PCNT, 2)) {
+		Notify (\_PR.CP00, 0x82)  // _TPC
+		Notify (\_PR.CP01, 0x82)  // _TPC
+	}
+	If (LGreaterEqual (\PCNT, 4)) {
+		Notify (\_PR.CP02, 0x82)  // _TPC
+		Notify (\_PR.CP03, 0x82)  // _TPC
+	}
+	If (LGreaterEqual (\PCNT, 8)) {
+		Notify (\_PR.CP04, 0x82)  // _TPC
+		Notify (\_PR.CP05, 0x82)  // _TPC
+		Notify (\_PR.CP06, 0x82)  // _TPC
+		Notify (\_PR.CP07, 0x82)  // _TPC
+	}
+}
+
+/* Return a package containing enabled processor entries */
+Method (PPKG)
+{
+	If (LGreaterEqual (\PCNT, 8)) {
+		Return (Package()
+		{
+			\_PR.CP00,
+			\_PR.CP01,
+			\_PR.CP02,
+			\_PR.CP03,
+			\_PR.CP04,
+			\_PR.CP05,
+			\_PR.CP06,
+			\_PR.CP07
+		})
+	} ElseIf (LGreaterEqual (\PCNT, 4)) {
+		Return (Package ()
+		{
+			\_PR.CP00,
+			\_PR.CP01,
+			\_PR.CP02,
+			\_PR.CP03
+		})
+	} ElseIf (LGreaterEqual (\PCNT, 2)) {
+		Return (Package ()
+		{
+			\_PR.CP00,
+			\_PR.CP01
+		})
+	} Else {
+		Return (Package ()
+		{
+			\_PR.CP00
+		})
+	}
+}
diff --git a/src/soc/intel/kabylake/acpi/dptf/charger.asl b/src/soc/intel/kabylake/acpi/dptf/charger.asl
new file mode 100644
index 0000000..4495d84
--- /dev/null
+++ b/src/soc/intel/kabylake/acpi/dptf/charger.asl
@@ -0,0 +1,75 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * 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.
+ */
+
+Device (TCHG)
+{
+	Name (_HID, "INT3403")
+	Name (_UID, 0)
+	Name (PTYP, 0x0B)
+	Name (_STR, Unicode("Battery Charger"))
+
+	Method (_STA)
+	{
+		If (LEqual (\DPTE, One)) {
+			Return (0xF)
+		} Else {
+			Return (0x0)
+		}
+	}
+
+	/* Return charger performance states defined by mainboard */
+	Method (PPSS)
+	{
+		Return (\_SB.CHPS)
+	}
+
+	/* Return maximum charger current limit */
+	Method (PPPC)
+	{
+		/* Convert size of PPSS table to index */
+		Store (SizeOf (\_SB.CHPS), Local0)
+		Decrement (Local0)
+
+		/* Check if charging is disabled (AC removed) */
+		If (LEqual (\_SB.PCI0.LPCB.EC0.ACEX, Zero)) {
+			/* Return last power state */
+			Return (Local0)
+		} Else {
+			/* Return highest power state */
+			Return (0)
+		}
+
+		Return (0)
+	}
+
+	/* Set charger current limit */
+	Method (SPPC, 1)
+	{
+		/* Retrieve Control (index 4) for specified PPSS level */
+		Store (DeRefOf (Index (DeRefOf (Index
+			(\_SB.CHPS, ToInteger (Arg0))), 4)), Local0)
+
+		/* Pass Control value to EC to limit charging */
+		\_SB.PCI0.LPCB.EC0.CHGS (Local0)
+	}
+
+	/* Initialize charger participant */
+	Method (INIT)
+	{
+		/* Disable charge limit */
+		\_SB.PCI0.LPCB.EC0.CHGD ()
+	}
+}
diff --git a/src/soc/intel/kabylake/acpi/dptf/cpu.asl b/src/soc/intel/kabylake/acpi/dptf/cpu.asl
new file mode 100644
index 0000000..6ba666b
--- /dev/null
+++ b/src/soc/intel/kabylake/acpi/dptf/cpu.asl
@@ -0,0 +1,224 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * 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 DPTF_CPU_PASSIVE
+#define DPTF_CPU_PASSIVE        80
+#endif
+
+#ifndef DPTF_CPU_CRITICAL
+#define DPTF_CPU_CRITICAL       90
+#endif
+
+#ifndef DPTF_CPU_ACTIVE_AC0
+#define DPTF_CPU_ACTIVE_AC0     90
+#endif
+
+#ifndef DPTF_CPU_ACTIVE_AC1
+#define DPTF_CPU_ACTIVE_AC1     80
+#endif
+
+#ifndef DPTF_CPU_ACTIVE_AC2
+#define DPTF_CPU_ACTIVE_AC2     70
+#endif
+
+#ifndef DPTF_CPU_ACTIVE_AC3
+#define DPTF_CPU_ACTIVE_AC3     60
+#endif
+
+#ifndef DPTF_CPU_ACTIVE_AC4
+#define DPTF_CPU_ACTIVE_AC4     50
+#endif
+
+External (\_PR.CP00._PSS, PkgObj)
+External (\_PR.CP00._TSS, PkgObj)
+External (\_PR.CP00._TPC, MethodObj)
+External (\_PR.CP00._PTC, PkgObj)
+External (\_PR.CP00._TSD, PkgObj)
+External (\_SB.MPDL, IntObj)
+
+Device (B0D4)
+{
+	Name(_ADR, 0x00040000)  /* Bus 0, Device 4, Function 0 */
+
+	Method (_STA)
+	{
+		If (LEqual (\DPTE, One)) {
+			Return (0xF)
+		} Else {
+			Return (0x0)
+		}
+	}
+
+	/*
+	 * Processor Throttling Controls
+	 */
+
+	Method (_TSS)
+	{
+		If (CondRefOf (\_PR.CP00._TSS)) {
+			Return (\_PR.CP00._TSS)
+		} Else {
+			Return (Package ()
+			{
+				Package () { 0, 0, 0, 0, 0 }
+			})
+		}
+	}
+
+	Method (_TPC)
+	{
+		If (CondRefOf (\_PR.CP00._TPC)) {
+			Return (\_PR.CP00._TPC)
+		} Else {
+			Return (0)
+		}
+	}
+
+	Method (_PTC)
+	{
+		If (CondRefOf (\_PR.CP00._PTC)) {
+			Return (\_PR.CP00._PTC)
+		} Else {
+			Return (Package ()
+			{
+				Buffer () { 0 },
+				Buffer () { 0 }
+			})
+		}
+	}
+
+	Method (_TSD)
+	{
+		If (CondRefOf (\_PR.CP00._TSD)) {
+			Return (\_PR.CP00._TSD)
+		} Else {
+			Return (Package ()
+			{
+				Package () { 5, 0, 0, 0, 0 }
+			})
+		}
+	}
+
+	Method (_TDL)
+	{
+		If (CondRefOf (\_PR.CP00._TSS)) {
+			Store (SizeOf (\_PR.CP00._TSS), Local0)
+			Decrement (Local0)
+			Return (Local0)
+		} Else {
+			Return (0)
+		}
+	}
+
+	/*
+	 * Processor Performance Control
+	 */
+
+	Method (_PPC)
+	{
+		Return (0)
+	}
+
+	Method (SPPC, 1)
+	{
+		Store (Arg0, \PPCM)
+
+		/* Notify OS to re-read _PPC limit on each CPU */
+		\PPCN ()
+	}
+
+	Method (_PSS)
+	{
+		If (CondRefOf (\_PR.CP00._PSS)) {
+			Return (\_PR.CP00._PSS)
+		} Else {
+			Return (Package ()
+			{
+				Package () { 0, 0, 0, 0, 0, 0 }
+			})
+		}
+	}
+
+
+	Method (_PDL)
+	{
+		/* Check for mainboard specific _PDL override */
+		If (CondRefOf (\_SB.MPDL)) {
+			Return (\_SB.MPDL)
+		} ElseIf (CondRefOf (\_PR.CP00._PSS)) {
+			Store (SizeOf (\_PR.CP00._PSS), Local0)
+			Decrement (Local0)
+			Return (Local0)
+		} Else {
+			Return (0)
+		}
+	}
+
+	/* Return PPCC table defined by mainboard */
+	Method (PPCC)
+	{
+		Return (\_SB.MPPC)
+	}
+
+#ifdef DPTF_CPU_CRITICAL
+	Method (_CRT)
+	{
+		Return (\_SB.DPTF.CTOK (DPTF_CPU_CRITICAL))
+	}
+#endif
+
+#ifdef DPTF_CPU_PASSIVE
+	Method (_PSV)
+	{
+		Return (\_SB.DPTF.CTOK (DPTF_CPU_PASSIVE))
+	}
+#endif
+
+#ifdef DPTF_CPU_ACTIVE_AC0
+	Method (_AC0)
+	{
+		Return (\_SB.DPTF.CTOK (DPTF_CPU_ACTIVE_AC0))
+	}
+#endif
+
+#ifdef DPTF_CPU_ACTIVE_AC1
+	Method (_AC1)
+	{
+		Return (\_SB.DPTF.CTOK (DPTF_CPU_ACTIVE_AC1))
+	}
+#endif
+
+#ifdef DPTF_CPU_ACTIVE_AC2
+	Method (_AC2)
+	{
+		Return (\_SB.DPTF.CTOK (DPTF_CPU_ACTIVE_AC2))
+	}
+#endif
+
+#ifdef DPTF_CPU_ACTIVE_AC3
+	Method (_AC3)
+	{
+		Return (\_SB.DPTF.CTOK (DPTF_CPU_ACTIVE_AC3))
+	}
+#endif
+
+#ifdef DPTF_CPU_ACTIVE_AC4
+	Method (_AC4)
+	{
+		Return (\_SB.DPTF.CTOK (DPTF_CPU_ACTIVE_AC4))
+	}
+#endif
+}
diff --git a/src/soc/intel/kabylake/acpi/dptf/dptf.asl b/src/soc/intel/kabylake/acpi/dptf/dptf.asl
new file mode 100644
index 0000000..6c79d3c
--- /dev/null
+++ b/src/soc/intel/kabylake/acpi/dptf/dptf.asl
@@ -0,0 +1,116 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * 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.
+ */
+
+Device (DPTF)
+{
+	Name (_HID, EISAID ("INT3400"))
+	Name (_UID, 0)
+
+	Name (IDSP, Package()
+	{
+		/* DPPM Passive Policy 1.0 */
+		ToUUID ("42A441D6-AE6A-462B-A84B-4A8CE79027D3"),
+
+		/* DPPM Critical Policy */
+		ToUUID ("97C68AE7-15FA-499c-B8C9-5DA81D606E0A"),
+
+		/* DPPM Cooling Policy */
+		ToUUID ("16CAF1B7-DD38-40ED-B1C1-1B8A1913D531"),
+
+#ifdef DPTF_ENABLE_FAN_CONTROL
+		/* DPPM Active Policy */
+		ToUUID ("3A95C389-E4B8-4629-A526-C52C88626BAE"),
+#endif
+	})
+
+	Method (_STA)
+	{
+		If (LEqual (\DPTE, One)) {
+			Return (0xF)
+		} Else {
+			Return (0x0)
+		}
+	}
+
+	/*
+	 * Arg0: Buffer containing UUID
+	 * Arg1: Integer containing Revision ID of buffer format
+	 * Arg2: Integer containing count of entries in Arg3
+	 * Arg3: Buffer containing list of DWORD capabilities
+	 * Return: Buffer containing list of DWORD capabilities
+	 */
+	Method (_OSC, 4, Serialized)
+	{
+		/* Check for Passive Policy UUID */
+		If (LEqual (DeRefOf (Index (IDSP, 0)), Arg0)) {
+			/* Initialize Thermal Devices */
+			^TINI ()
+
+#ifdef DPTF_ENABLE_CHARGER
+			/* Initialize Charger Device */
+			^TCHG.INIT ()
+#endif
+		}
+
+		Return (Arg3)
+	}
+
+	/* Priority based _TRT */
+	Name (TRTR, 1)
+
+	Method (_TRT)
+	{
+		Return (\_SB.DTRT)
+	}
+
+#ifdef DPTF_ENABLE_FAN_CONTROL
+	/* _ART : Active Cooling Relationship Table */
+	Method (_ART)
+	{
+		Return (\_SB.DART)
+	}
+#endif
+
+	/* Convert from Degrees C to 1/10 Kelvin for ACPI */
+	Method (CTOK, 1) {
+		/* 10th of Degrees C */
+		Multiply (Arg0, 10, Local0)
+
+		/* Convert to Kelvin */
+		Add (Local0, 2732, Local0)
+
+		Return (Local0)
+	}
+
+	/* Include Thermal Participants */
+	#include "thermal.asl"
+
+#ifdef DPTF_ENABLE_CHARGER
+	/* Include Charger Participant */
+	#include "charger.asl"
+#endif
+
+#ifdef DPTF_ENABLE_FAN_CONTROL
+	/* Include Fan Participant */
+	#include "fan.asl"
+#endif
+
+}
+
+Scope (\_SB.PCI0)
+{
+	#include "cpu.asl"
+}
diff --git a/src/soc/intel/kabylake/acpi/dptf/fan.asl b/src/soc/intel/kabylake/acpi/dptf/fan.asl
new file mode 100644
index 0000000..e3c88c3
--- /dev/null
+++ b/src/soc/intel/kabylake/acpi/dptf/fan.asl
@@ -0,0 +1,68 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * 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.
+ */
+
+Device (TFN1)
+{
+	Name (_HID, "INT3404")
+	Name (_UID, 0)
+	Name (_STR, Unicode("Fan Control"))
+
+	/* _FIF: Fan Information */
+	Name (_FIF, Package ()
+	{
+		0,	// Revision
+		1,	// Fine Grained Control
+		2,	// Step Size
+		0	// No Low Speed Notification
+	})
+
+	/* Return Fan Performance States defined by mainboard */
+	Method (_FPS)
+	{
+		Return (\_SB.DFPS)
+	}
+
+	Name (TFST, Package ()
+	{
+		0,	// Revision
+		0x00,	// Control
+		0x00	// Speed
+	})
+
+	/* _FST: Fan current Status */
+	Method (_FST, 0, Serialized,,PkgObj)
+	{
+		/* Fill in TFST with current control. */
+		Store (\_SB.PCI0.LPCB.EC0.FAND, Index (TFST, 1))
+		Return (TFST)
+	}
+
+	/* _FSL: Fan Speed Level */
+	Method (_FSL, 1, Serialized)
+	{
+		Store (Arg0, \_SB.PCI0.LPCB.EC0.FAND)
+		Notify (DPTF, 0x83)	// Re evaluate _ART
+	}
+
+	Method (_STA)
+	{
+		If (LEqual (\DPTE, One))
+		{
+			Return (0xF)
+		} Else {
+			Return (0x0)
+		}
+	}
+}
diff --git a/src/soc/intel/kabylake/acpi/dptf/thermal.asl b/src/soc/intel/kabylake/acpi/dptf/thermal.asl
new file mode 100644
index 0000000..67da119
--- /dev/null
+++ b/src/soc/intel/kabylake/acpi/dptf/thermal.asl
@@ -0,0 +1,283 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * 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.
+ */
+
+/* Thermal Threshold Event Handler */
+Method (TEVT, 1, NotSerialized)
+{
+	Store (ToInteger (Arg0), Local0)
+
+#ifdef DPTF_TSR0_SENSOR_ID
+	If (LEqual (Local0, DPTF_TSR0_SENSOR_ID)) {
+		Notify (^TSR0, 0x90)
+	}
+#endif
+#ifdef DPTF_TSR1_SENSOR_ID
+	If (LEqual (Local0, DPTF_TSR1_SENSOR_ID)) {
+		Notify (^TSR1, 0x90)
+	}
+#endif
+#ifdef DPTF_TSR2_SENSOR_ID
+	If (LEqual (Local0, DPTF_TSR2_SENSOR_ID)) {
+		Notify (^TSR2, 0x90)
+	}
+#endif
+#ifdef DPTF_TSR3_SENSOR_ID
+	If (LEqual (Local0, DPTF_TSR3_SENSOR_ID)) {
+		Notify (^TSR3, 0x90)
+	}
+#endif
+}
+
+/* Thermal device initialization - Disable Aux Trip Points */
+Method (TINI)
+{
+#ifdef DPTF_TSR0_SENSOR_ID
+	^TSR0.PATD ()
+#endif
+#ifdef DPTF_TSR1_SENSOR_ID
+	^TSR1.PATD ()
+#endif
+#ifdef DPTF_TSR2_SENSOR_ID
+	^TSR2.PATD ()
+#endif
+#ifdef DPTF_TSR3_SENSOR_ID
+	^TSR3.PATD ()
+#endif
+}
+
+#ifdef DPTF_TSR0_SENSOR_ID
+Device (TSR0)
+{
+	Name (_HID, EISAID ("INT3403"))
+	Name (_UID, 1)
+	Name (PTYP, 0x03)
+	Name (TMPI, DPTF_TSR0_SENSOR_ID)
+	Name (_STR, Unicode (DPTF_TSR0_SENSOR_NAME))
+	Name (GTSH, 20) /* 2 degree hysteresis */
+
+	Method (_STA)
+	{
+		If (LEqual (\DPTE, One)) {
+			Return (0xF)
+		} Else {
+			Return (0x0)
+		}
+	}
+
+	Method (_TMP, 0, Serialized)
+	{
+		Return (\_SB.PCI0.LPCB.EC0.TSRD (TMPI))
+	}
+
+	Method (_PSV)
+	{
+		Return (CTOK (DPTF_TSR0_PASSIVE))
+	}
+
+	Method (_CRT)
+	{
+		Return (CTOK (DPTF_TSR0_CRITICAL))
+	}
+
+	Name (PATC, 2)
+
+	/* Set Aux Trip Point */
+	Method (PAT0, 1, Serialized)
+	{
+		\_SB.PCI0.LPCB.EC0.PAT0 (TMPI, Arg0)
+	}
+
+	/* Set Aux Trip Point */
+	Method (PAT1, 1, Serialized)
+	{
+		\_SB.PCI0.LPCB.EC0.PAT1 (TMPI, Arg0)
+	}
+
+	/* Disable Aux Trip Point */
+	Method (PATD, 0, Serialized)
+	{
+		\_SB.PCI0.LPCB.EC0.PATD (TMPI)
+	}
+}
+#endif
+
+#ifdef DPTF_TSR1_SENSOR_ID
+Device (TSR1)
+{
+	Name (_HID, EISAID ("INT3403"))
+	Name (_UID, 2)
+	Name (PTYP, 0x03)
+	Name (TMPI, DPTF_TSR1_SENSOR_ID)
+	Name (_STR, Unicode (DPTF_TSR1_SENSOR_NAME))
+	Name (GTSH, 20) /* 2 degree hysteresis */
+
+	Method (_STA)
+	{
+		If (LEqual (\DPTE, One)) {
+			Return (0xF)
+		} Else {
+			Return (0x0)
+		}
+	}
+
+	Method (_TMP, 0, Serialized)
+	{
+		Return (\_SB.PCI0.LPCB.EC0.TSRD (TMPI))
+	}
+
+	Method (_PSV)
+	{
+		Return (CTOK (DPTF_TSR1_PASSIVE))
+	}
+
+	Method (_CRT)
+	{
+		Return (CTOK (DPTF_TSR1_CRITICAL))
+	}
+
+	Name (PATC, 2)
+
+	/* Set Aux Trip Point */
+	Method (PAT0, 1, Serialized)
+	{
+		\_SB.PCI0.LPCB.EC0.PAT0 (TMPI, Arg0)
+	}
+
+	/* Set Aux Trip Point */
+	Method (PAT1, 1, Serialized)
+	{
+		\_SB.PCI0.LPCB.EC0.PAT1 (TMPI, Arg0)
+	}
+
+	/* Disable Aux Trip Point */
+	Method (PATD, 0, Serialized)
+	{
+		\_SB.PCI0.LPCB.EC0.PATD (TMPI)
+	}
+}
+#endif
+
+#ifdef DPTF_TSR2_SENSOR_ID
+Device (TSR2)
+{
+	Name (_HID, EISAID ("INT3403"))
+	Name (_UID, 3)
+	Name (PTYP, 0x03)
+	Name (TMPI, DPTF_TSR2_SENSOR_ID)
+	Name (_STR, Unicode (DPTF_TSR2_SENSOR_NAME))
+	Name (GTSH, 20) /* 2 degree hysteresis */
+
+	Method (_STA)
+	{
+		If (LEqual (\DPTE, One)) {
+			Return (0xF)
+		} Else {
+			Return (0x0)
+		}
+	}
+
+	Method (_TMP, 0, Serialized)
+	{
+		Return (\_SB.PCI0.LPCB.EC0.TSRD (TMPI))
+	}
+
+	Method (_PSV)
+	{
+		Return (CTOK (DPTF_TSR2_PASSIVE))
+	}
+
+	Method (_CRT)
+	{
+		Return (CTOK (DPTF_TSR2_CRITICAL))
+	}
+
+	Name (PATC, 2)
+
+	/* Set Aux Trip Point */
+	Method (PAT0, 1, Serialized)
+	{
+		\_SB.PCI0.LPCB.EC0.PAT0 (TMPI, Arg0)
+	}
+
+	/* Set Aux Trip Point */
+	Method (PAT1, 1, Serialized)
+	{
+		\_SB.PCI0.LPCB.EC0.PAT1 (TMPI, Arg0)
+	}
+
+	/* Disable Aux Trip Point */
+	Method (PATD, 0, Serialized)
+	{
+		\_SB.PCI0.LPCB.EC0.PATD (TMPI)
+	}
+}
+#endif
+
+#ifdef DPTF_TSR3_SENSOR_ID
+Device (TSR3)
+{
+	Name (_HID, EISAID ("INT3403"))
+	Name (_UID, 4)
+	Name (PTYP, 0x03)
+	Name (TMPI, DPTF_TSR3_SENSOR_ID)
+	Name (_STR, Unicode (DPTF_TSR3_SENSOR_NAME))
+	Name (GTSH, 20) /* 2 degree hysteresis */
+
+	Method (_STA)
+	{
+		If (LEqual (\DPTE, One)) {
+			Return (0xF)
+		} Else {
+			Return (0x0)
+		}
+	}
+
+	Method (_TMP, 0, Serialized)
+	{
+		Return (\_SB.PCI0.LPCB.EC0.TSRD (TMPI))
+	}
+
+	Method (_PSV)
+	{
+		Return (CTOK (DPTF_TSR3_PASSIVE))
+	}
+
+	Method (_CRT)
+	{
+		Return (CTOK (DPTF_TSR3_CRITICAL))
+	}
+
+	Name (PATC, 2)
+
+	/* Set Aux Trip Point */
+	Method (PAT0, 1, Serialized)
+	{
+		\_SB.PCI0.LPCB.EC0.PAT0 (TMPI, Arg0)
+	}
+
+	/* Set Aux Trip Point */
+	Method (PAT1, 1, Serialized)
+	{
+		\_SB.PCI0.LPCB.EC0.PAT1 (TMPI, Arg0)
+	}
+
+	/* Disable Aux Trip Point */
+	Method (PATD, 0, Serialized)
+	{
+		\_SB.PCI0.LPCB.EC0.PATD (TMPI)
+	}
+}
+#endif
diff --git a/src/soc/intel/kabylake/acpi/globalnvs.asl b/src/soc/intel/kabylake/acpi/globalnvs.asl
new file mode 100644
index 0000000..373674e
--- /dev/null
+++ b/src/soc/intel/kabylake/acpi/globalnvs.asl
@@ -0,0 +1,95 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ * Copyright (C) 2014 Google Inc.
+ * 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.
+ */
+
+/* Global Variables */
+
+Name (\PICM, 0)		// IOAPIC/8259
+
+/*
+ * Global ACPI memory region. This region is used for passing information
+ * between coreboot (aka "the system bios"), ACPI, and the SMI handler.
+ * Since we don't know where this will end up in memory at ACPI compile time,
+ * we have to fix it up in coreboot's ACPI creation phase.
+ */
+
+External (NVSA)
+
+OperationRegion (GNVS, SystemMemory, NVSA, 0x2000)
+Field (GNVS, ByteAcc, NoLock, Preserve)
+{
+	/* Miscellaneous */
+	Offset (0x00),
+	OSYS,	16,	// 0x00 - Operating System
+	SMIF,	8,	// 0x02 - SMI function
+	PRM0,	8,	// 0x03 - SMI function parameter
+	PRM1,	8,	// 0x04 - SMI function parameter
+	SCIF,	8,	// 0x05 - SCI function
+	PRM2,	8,	// 0x06 - SCI function parameter
+	PRM3,	8,	// 0x07 - SCI function parameter
+	LCKF,	8,	// 0x08 - Global Lock function for EC
+	PRM4,	8,	// 0x09 - Lock function parameter
+	PRM5,	8,	// 0x0a - Lock function parameter
+	PCNT,	8,	// 0x0b - Processor Count
+	PPCM,	8,	// 0x0c - Max PPC State
+	TMPS,	8,	// 0x0d - Temperature Sensor ID
+	TLVL,	8,	// 0x0e - Throttle Level Limit
+	FLVL,	8,	// 0x0f - Current FAN Level
+	TCRT,	8,	// 0x10 - Critical Threshold
+	TPSV,	8,	// 0x11 - Passive Threshold
+	TMAX,	8,	// 0x12 - CPU Tj_max
+	S5U0,	8,	// 0x13 - Enable USB in S5
+	S3U0,	8,	// 0x14 - Enable USB in S3
+	S33G,	8,	// 0x15 - Enable 3G in S3
+	LIDS,	8,	// 0x16 - LID State
+	PWRS,	8,	// 0x17 - AC Power State
+	CMEM,	32,	// 0x18 - 0x1b - CBMEM TOC
+	CBMC,	32,	// 0x1c - 0x1f - Coreboot Memory Console
+	PM1I,	64,	// 0x20 - 0x27 - PM1 wake status bit
+	GPEI,	64,	// 0x28 - 0x2f - GPE wake status bit
+	DPTE,	8,	// 0x30 - Enable DPTF
+	NHLA,	64,	// 0x31 - NHLT Address
+	NHLL,	32,	// 0x39 - NHLT Length
+	CID1,	16,	// 0x3d - Wifi Country Identifier
+
+	/* ChromeOS specific */
+	Offset (0x100),
+	#include <vendorcode/google/chromeos/acpi/gnvs.asl>
+}
+
+/* Set flag to enable USB charging in S3 */
+Method (S3UE)
+{
+	Store (One, \S3U0)
+}
+
+/* Set flag to disable USB charging in S3 */
+Method (S3UD)
+{
+	Store (Zero, \S3U0)
+}
+
+/* Set flag to enable USB charging in S5 */
+Method (S5UE)
+{
+	Store (One, \S5U0)
+}
+
+/* Set flag to disable USB charging in S5 */
+Method (S5UD)
+{
+	Store (Zero, \S5U0)
+}
diff --git a/src/soc/intel/kabylake/acpi/gpio.asl b/src/soc/intel/kabylake/acpi/gpio.asl
new file mode 100644
index 0000000..789957c
--- /dev/null
+++ b/src/soc/intel/kabylake/acpi/gpio.asl
@@ -0,0 +1,115 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * 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 <soc/gpio_defs.h>
+
+Device (GPIO)
+{
+	Name (_HID, "INT344B")
+	Name (_UID, 1)
+	Name (_DDN, "GPIO Controller")
+
+	Name (RBUF, ResourceTemplate()
+	{
+		Memory32Fixed (ReadWrite, 0, 0, COM0)
+		Memory32Fixed (ReadWrite, 0, 0, COM1)
+		Memory32Fixed (ReadWrite, 0, 0, COM3)
+		Interrupt (ResourceConsumer, Level, ActiveLow, Shared,,, GIRQ)
+			{ 0 }
+	})
+
+	Method (_CRS, 0, NotSerialized)
+	{
+		/* GPIO Community 0 */
+		CreateDWordField (^RBUF, ^COM0._BAS, BAS0)
+		CreateDWordField (^RBUF, ^COM0._LEN, LEN0)
+		Store (^^PCRB (PID_GPIOCOM0), BAS0)
+		Store (GPIO_BASE_SIZE, LEN0)
+
+		/* GPIO Community 1 */
+		CreateDWordField (^RBUF, ^COM1._BAS, BAS1)
+		CreateDWordField (^RBUF, ^COM1._LEN, LEN1)
+		Store (^^PCRB (PID_GPIOCOM1), BAS1)
+		Store (GPIO_BASE_SIZE, LEN1)
+
+		/* GPIO Community 3 */
+		CreateDWordField (^RBUF, ^COM3._BAS, BAS3)
+		CreateDWordField (^RBUF, ^COM3._LEN, LEN3)
+		Store (^^PCRB (PID_GPIOCOM3), BAS3)
+		Store (GPIO_BASE_SIZE, LEN3)
+
+		CreateDWordField (^RBUF, ^GIRQ._INT, IRQN)
+		And (^^PCRR (PID_GPIOCOM0, MISCCFG_OFFSET),
+			GPIO_DRIVER_IRQ_ROUTE_MASK, Local0)
+
+		If (LEqual (Local0, GPIO_DRIVER_IRQ_ROUTE_IRQ14)) {
+			Store (GPIO_IRQ14, IRQN)
+		} Else {
+			Store (GPIO_IRQ15, IRQN)
+		}
+
+		Return (RBUF)
+	}
+
+	Method (_STA, 0, NotSerialized)
+	{
+		Return (0xF)
+	}
+}
+
+/*
+ * Get GPIO DW0 Address
+ * Arg0 - GPIO Number
+ */
+Method (GADD, 1, NotSerialized)
+{
+	/* GPIO Community 0 */
+	If (LAnd (LGreaterEqual (Arg0, GPP_A0), LLessEqual (Arg0, GPP_B23)))
+	{
+		Store (PID_GPIOCOM0, Local0)
+		Subtract (Arg0, GPP_A0, Local1)
+	}
+	/* GPIO Community 1 */
+	If (LAnd (LGreaterEqual (Arg0, GPP_C0), LLessEqual (Arg0, GPP_E23)))
+	{
+		Store (PID_GPIOCOM1, Local0)
+		Subtract (Arg0, GPP_C0, Local1)
+	}
+	/* GPIO Community 03*/
+	If (LAnd (LGreaterEqual (Arg0, GPP_F0), LLessEqual (Arg0, GPP_G7)))
+	{
+		Store (PID_GPIOCOM3, Local0)
+		Subtract (Arg0, GPP_F0, Local1)
+	}
+	Store (PCRB (Local0), Local2)
+	Add (Local2, PAD_CFG_DW_OFFSET, Local2)
+	Return (Add (Local2, Multiply (Local1, 8)))
+}
+
+/*
+ * Get GPIO Value
+ * Arg0 - GPIO Number
+ */
+Method (GRXS, 1, Serialized)
+{
+	OperationRegion (PREG, SystemMemory, GADD (Arg0), 4)
+	Field (PREG, AnyAcc, NoLock, Preserve)
+	{
+		VAL0, 32
+	}
+	And (GPIORXSTATE_MASK, ShiftRight (VAL0, GPIORXSTATE_SHIFT), Local0)
+
+	Return (Local0)
+}
diff --git a/src/soc/intel/kabylake/acpi/irqlinks.asl b/src/soc/intel/kabylake/acpi/irqlinks.asl
new file mode 100644
index 0000000..f9d68e7
--- /dev/null
+++ b/src/soc/intel/kabylake/acpi/irqlinks.asl
@@ -0,0 +1,436 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ * Copyright (C) 2014 Google Inc.
+ * 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.
+ */
+
+/*
+ * PIRQ routing control is in PCR ITSS region.
+ *
+ * Due to what appears to be an ACPI interpreter bug we do not use
+ * the PCRB() method here as it may not be defined yet because the method
+ * definiton depends on the order of the include files in pch.asl.
+ *
+ * https://bugs.acpica.org/show_bug.cgi?id=1201
+ */
+OperationRegion (ITSS, SystemMemory,
+		 Add (R_PCH_PCR_ITSS_PIRQA_ROUT,
+		      Add (PCH_PCR_BASE_ADDRESS,
+		           ShiftLeft (PID_ITSS, PCR_PORTID_SHIFT))), 8)
+Field (ITSS, ByteAcc, NoLock, Preserve)
+{
+	PIRA, 8,	/* PIRQA Routing Control */
+	PIRB, 8,	/* PIRQB Routing Control */
+	PIRC, 8,	/* PIRQC Routing Control */
+	PIRD, 8,	/* PIRQD Routing Control */
+	PIRE, 8,	/* PIRQE Routing Control */
+	PIRF, 8,	/* PIRQF Routing Control */
+	PIRG, 8,	/* PIRQG Routing Control */
+	PIRH, 8,	/* PIRQH Routing Control */
+}
+
+Name (IREN, 0x80)	/* Interrupt Routing Enable */
+Name (IREM, 0x0f)	/* Interrupt Routing Mask */
+
+Device (LNKA)
+{
+	Name (_HID, EISAID ("PNP0C0F"))
+	Name (_UID, 1)
+
+	Name (_PRS, ResourceTemplate ()
+	{
+		IRQ (Level, ActiveLow, Shared)
+			{ 3, 4, 5, 6, 10, 12, 14, 15 }
+	})
+
+	Method (_CRS, 0, Serialized)
+	{
+		Name (RTLA, ResourceTemplate ()
+		{
+			IRQ (Level, ActiveLow, Shared) {}
+		})
+		CreateWordField (RTLA, 1, IRQ0)
+		Store (Zero, IRQ0)
+
+		/* Set the bit from PIRQ Routing Register */
+		ShiftLeft (1, And (^^PIRA, ^^IREM), IRQ0)
+
+		Return (RTLA)
+	}
+
+	Method (_SRS, 1, Serialized)
+	{
+		CreateWordField (Arg0, 1, IRQ0)
+		FindSetRightBit (IRQ0, Local0)
+		Decrement (Local0)
+		Store (Local0, ^^PIRA)
+	}
+
+	Method (_STA, 0, Serialized)
+	{
+		If (And (^^PIRA, ^^IREN)) {
+			Return (0x9)
+		} Else {
+			Return (0xb)
+		}
+	}
+
+	Method (_DIS, 0, Serialized)
+	{
+		Or (^^PIRA, ^^IREN, ^^PIRA)
+	}
+}
+
+Device (LNKB)
+{
+	Name (_HID, EISAID ("PNP0C0F"))
+	Name (_UID, 2)
+
+	Name (_PRS, ResourceTemplate ()
+	{
+		IRQ (Level, ActiveLow, Shared)
+			{ 3, 4, 5, 6, 10, 12, 14, 15 }
+	})
+
+	Method (_CRS, 0, Serialized)
+	{
+		Name (RTLA, ResourceTemplate ()
+		{
+			IRQ (Level, ActiveLow, Shared) {}
+		})
+		CreateWordField (RTLA, 1, IRQ0)
+		Store (Zero, IRQ0)
+
+		/* Set the bit from PIRQ Routing Register */
+		ShiftLeft (1, And (^^PIRB, ^^IREM), IRQ0)
+
+		Return (RTLA)
+	}
+
+	Method (_SRS, 1, Serialized)
+	{
+		CreateWordField (Arg0, 1, IRQ0)
+		FindSetRightBit (IRQ0, Local0)
+		Decrement (Local0)
+		Store (Local0, ^^PIRB)
+	}
+
+	Method (_STA, 0, Serialized)
+	{
+		If (And (^^PIRB, ^^IREN)) {
+			Return (0x9)
+		} Else {
+			Return (0xb)
+		}
+	}
+
+	Method (_DIS, 0, Serialized)
+	{
+		Or (^^PIRB, ^^IREN, ^^PIRB)
+	}
+}
+
+Device (LNKC)
+{
+	Name (_HID, EISAID ("PNP0C0F"))
+	Name (_UID, 3)
+
+	Name (_PRS, ResourceTemplate ()
+	{
+		IRQ (Level, ActiveLow, Shared)
+			{ 3, 4, 5, 6, 10, 12, 14, 15 }
+	})
+
+	Method (_CRS, 0, Serialized)
+	{
+		Name (RTLA, ResourceTemplate ()
+		{
+			IRQ (Level, ActiveLow, Shared) {}
+		})
+		CreateWordField (RTLA, 1, IRQ0)
+		Store (Zero, IRQ0)
+
+		/* Set the bit from PIRQ Routing Register */
+		ShiftLeft (1, And (^^PIRC, ^^IREM), IRQ0)
+
+		Return (RTLA)
+	}
+
+	Method (_SRS, 1, Serialized)
+	{
+		CreateWordField (Arg0, 1, IRQ0)
+		FindSetRightBit (IRQ0, Local0)
+		Decrement (Local0)
+		Store (Local0, ^^PIRC)
+	}
+
+	Method (_STA, 0, Serialized)
+	{
+		If (And (^^PIRC, ^^IREN)) {
+			Return (0x9)
+		} Else {
+			Return (0xb)
+		}
+	}
+
+	Method (_DIS, 0, Serialized)
+	{
+		Or (^^PIRC, ^^IREN, ^^PIRC)
+	}
+}
+
+Device (LNKD)
+{
+	Name (_HID, EISAID ("PNP0C0F"))
+	Name (_UID, 4)
+
+	Name (_PRS, ResourceTemplate ()
+	{
+		IRQ (Level, ActiveLow, Shared)
+			{ 3, 4, 5, 6, 10, 12, 14, 15 }
+	})
+
+	Method (_CRS, 0, Serialized)
+	{
+		Name (RTLA, ResourceTemplate ()
+		{
+			IRQ (Level, ActiveLow, Shared) {}
+		})
+		CreateWordField (RTLA, 1, IRQ0)
+		Store (Zero, IRQ0)
+
+		/* Set the bit from PIRQ Routing Register */
+		ShiftLeft (1, And (^^PIRD, ^^IREM), IRQ0)
+
+		Return (RTLA)
+	}
+
+	Method (_SRS, 1, Serialized)
+	{
+		CreateWordField (Arg0, 1, IRQ0)
+		FindSetRightBit (IRQ0, Local0)
+		Decrement (Local0)
+		Store (Local0, ^^PIRD)
+	}
+
+	Method (_STA, 0, Serialized)
+	{
+		If (And (^^PIRD, ^^IREN)) {
+			Return (0x9)
+		} Else {
+			Return (0xb)
+		}
+	}
+
+	Method (_DIS, 0, Serialized)
+	{
+		Or (^^PIRD, ^^IREN, ^^PIRD)
+	}
+}
+
+Device (LNKE)
+{
+	Name (_HID, EISAID ("PNP0C0F"))
+	Name (_UID, 5)
+
+	Name (_PRS, ResourceTemplate ()
+	{
+		IRQ (Level, ActiveLow, Shared)
+			{ 3, 4, 5, 6, 10, 12, 14, 15 }
+	})
+
+	Method (_CRS, 0, Serialized)
+	{
+		Name (RTLA, ResourceTemplate ()
+		{
+			IRQ (Level, ActiveLow, Shared) {}
+		})
+		CreateWordField (RTLA, 1, IRQ0)
+		Store (Zero, IRQ0)
+
+		/* Set the bit from PIRQ Routing Register */
+		ShiftLeft (1, And (^^PIRE, ^^IREM), IRQ0)
+
+		Return (RTLA)
+	}
+
+	Method (_SRS, 1, Serialized)
+	{
+		CreateWordField (Arg0, 1, IRQ0)
+		FindSetRightBit (IRQ0, Local0)
+		Decrement (Local0)
+		Store (Local0, ^^PIRE)
+	}
+
+	Method (_STA, 0, Serialized)
+	{
+		If (And (^^PIRE, ^^IREN)) {
+			Return (0x9)
+		} Else {
+			Return (0xb)
+		}
+	}
+
+	Method (_DIS, 0, Serialized)
+	{
+		Or (^^PIRE, ^^IREN, ^^PIRE)
+	}
+}
+
+Device (LNKF)
+{
+	Name (_HID, EISAID ("PNP0C0F"))
+	Name (_UID, 6)
+
+	Name (_PRS, ResourceTemplate ()
+	{
+		IRQ (Level, ActiveLow, Shared)
+			{ 3, 4, 5, 6, 10, 12, 14, 15 }
+	})
+
+	Method (_CRS, 0, Serialized)
+	{
+		Name (RTLA, ResourceTemplate ()
+		{
+			IRQ (Level, ActiveLow, Shared) {}
+		})
+		CreateWordField (RTLA, 1, IRQ0)
+		Store (Zero, IRQ0)
+
+		/* Set the bit from PIRQ Routing Register */
+		ShiftLeft (1, And (^^PIRF, ^^IREM), IRQ0)
+
+		Return (RTLA)
+	}
+
+	Method (_SRS, 1, Serialized)
+	{
+		CreateWordField (Arg0, 1, IRQ0)
+		FindSetRightBit (IRQ0, Local0)
+		Decrement (Local0)
+		Store (Local0, ^^PIRF)
+	}
+
+	Method (_STA, 0, Serialized)
+	{
+		If (And (^^PIRF, ^^IREN)) {
+			Return (0x9)
+		} Else {
+			Return (0xb)
+		}
+	}
+
+	Method (_DIS, 0, Serialized)
+	{
+		Or (^^PIRF, ^^IREN, ^^PIRF)
+	}
+}
+
+Device (LNKG)
+{
+	Name (_HID, EISAID ("PNP0C0F"))
+	Name (_UID, 7)
+
+	Name (_PRS, ResourceTemplate ()
+	{
+		IRQ (Level, ActiveLow, Shared)
+			{ 3, 4, 5, 6, 10, 12, 14, 15 }
+	})
+
+	Method (_CRS, 0, Serialized)
+	{
+		Name (RTLA, ResourceTemplate ()
+		{
+			IRQ (Level, ActiveLow, Shared) {}
+		})
+		CreateWordField (RTLA, 1, IRQ0)
+		Store (Zero, IRQ0)
+
+		/* Set the bit from PIRQ Routing Register */
+		ShiftLeft (1, And (^^PIRG, ^^IREM), IRQ0)
+
+		Return (RTLA)
+	}
+
+	Method (_SRS, 1, Serialized)
+	{
+		CreateWordField (Arg0, 1, IRQ0)
+		FindSetRightBit (IRQ0, Local0)
+		Decrement (Local0)
+		Store (Local0, ^^PIRG)
+	}
+
+	Method (_STA, 0, Serialized)
+	{
+		If (And (^^PIRG, ^^IREN)) {
+			Return (0x9)
+		} Else {
+			Return (0xb)
+		}
+	}
+
+	Method (_DIS, 0, Serialized)
+	{
+		Or (^^PIRG, ^^IREN, ^^PIRG)
+	}
+}
+
+Device (LNKH)
+{
+	Name (_HID, EISAID ("PNP0C0F"))
+	Name (_UID, 1)
+
+	Name (_PRS, ResourceTemplate ()
+	{
+		IRQ (Level, ActiveLow, Shared)
+			{ 3, 4, 5, 6, 10, 12, 14, 15 }
+	})
+
+	Method (_CRS, 0, Serialized)
+	{
+		Name (RTLA, ResourceTemplate ()
+		{
+			IRQ (Level, ActiveLow, Shared) {}
+		})
+		CreateWordField (RTLA, 1, IRQ0)
+		Store (Zero, IRQ0)
+
+		/* Set the bit from PIRQ Routing Register */
+		ShiftLeft (1, And (^^PIRH, ^^IREM), IRQ0)
+
+		Return (RTLA)
+	}
+
+	Method (_SRS, 1, Serialized)
+	{
+		CreateWordField (Arg0, 1, IRQ0)
+		FindSetRightBit (IRQ0, Local0)
+		Decrement (Local0)
+		Store (Local0, ^^PIRH)
+	}
+
+	Method (_STA, 0, Serialized)
+	{
+		If (And (^^PIRH, ^^IREN)) {
+			Return (0x9)
+		} Else {
+			Return (0xb)
+		}
+	}
+
+	Method (_DIS, 0, Serialized)
+	{
+		Or (^^PIRH, ^^IREN, ^^PIRH)
+	}
+}
diff --git a/src/soc/intel/kabylake/acpi/lpc.asl b/src/soc/intel/kabylake/acpi/lpc.asl
new file mode 100644
index 0000000..0bc6fae
--- /dev/null
+++ b/src/soc/intel/kabylake/acpi/lpc.asl
@@ -0,0 +1,144 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ * Copyright (C) 2014 Google Inc.
+ * 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.
+ */
+
+Device (LPCB)
+{
+	Name (_ADR, 0x001f0000)
+	Name (_DDN, "LPC Bus Device")
+
+	Device (DMAC)
+	{
+		Name (_HID, EISAID ("PNP0200"))
+		Name (_DDN, "DMA Controller")
+		Name (_CRS, ResourceTemplate ()
+		{
+			IO (Decode16, 0x00, 0x00, 0x01, 0x20)
+			IO (Decode16, 0x81, 0x81, 0x01, 0x11)
+			IO (Decode16, 0x93, 0x93, 0x01, 0x0d)
+			IO (Decode16, 0xc0, 0xc0, 0x01, 0x20)
+			DMA (Compatibility, NotBusMaster, Transfer8_16) { 4 }
+		})
+	}
+
+	Device (FWH)
+	{
+		Name (_HID, EISAID ("INT0800"))
+		Name (_DDN, "Firmware Hub")
+		Name (_CRS, ResourceTemplate ()
+		{
+			Memory32Fixed (ReadOnly, 0xff000000, 0x01000000)
+		})
+	}
+
+	Device (HPET)
+	{
+		Name (_HID, EISAID ("PNP0103"))
+		Name (_DDN, "High Precision Event Timer")
+		Name (_CRS, ResourceTemplate ()
+		{
+			Memory32Fixed (ReadWrite, HPET_BASE_ADDRESS, 0x400)
+		})
+		Method (_STA, 0)
+		{
+			Return (0xf)
+		}
+	}
+
+	Device (PIC)
+	{
+		Name (_HID, EISAID ("PNP0000"))
+		Name (_DDN, "8259 Interrupt Controller")
+		Name (_CRS, ResourceTemplate()
+		{
+			IO (Decode16, 0x20, 0x20, 0x01, 0x02)
+			IO (Decode16, 0x24, 0x24, 0x01, 0x02)
+			IO (Decode16, 0x28, 0x28, 0x01, 0x02)
+			IO (Decode16, 0x2c, 0x2c, 0x01, 0x02)
+			IO (Decode16, 0x30, 0x30, 0x01, 0x02)
+			IO (Decode16, 0x34, 0x34, 0x01, 0x02)
+			IO (Decode16, 0x38, 0x38, 0x01, 0x02)
+			IO (Decode16, 0x3c, 0x3c, 0x01, 0x02)
+			IO (Decode16, 0xa0, 0xa0, 0x01, 0x02)
+			IO (Decode16, 0xa4, 0xa4, 0x01, 0x02)
+			IO (Decode16, 0xa8, 0xa8, 0x01, 0x02)
+			IO (Decode16, 0xac, 0xac, 0x01, 0x02)
+			IO (Decode16, 0xb0, 0xb0, 0x01, 0x02)
+			IO (Decode16, 0xb4, 0xb4, 0x01, 0x02)
+			IO (Decode16, 0xb8, 0xb8, 0x01, 0x02)
+			IO (Decode16, 0xbc, 0xbc, 0x01, 0x02)
+			IO (Decode16, 0x4d0, 0x4d0, 0x01, 0x02)
+			IRQNoFlags () { 2 }
+		})
+	}
+
+	Device (MATH)
+	{
+		Name (_HID, EISAID ("PNP0C04"))
+		Name (_DDN, "Floating Point Unit")
+		Name (_CRS, ResourceTemplate ()
+		{
+			IO (Decode16, 0xf0, 0xf0, 0x01, 0x01)
+			IRQNoFlags () { 13 }
+		})
+	}
+
+	Device (LDRC)
+	{
+		Name (_HID, EISAID ("PNP0C02"))
+		Name (_UID, 2)
+		Name (_DDN, "Legacy Device Resources")
+		Name (_CRS, ResourceTemplate ()
+		{
+			IO (Decode16, 0x2e, 0x2e, 0x1, 0x02) // First SuperIO
+			IO (Decode16, 0x4e, 0x4e, 0x1, 0x02) // Second SuperIO
+			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
+			IO (Decode16, ACPI_BASE_ADDRESS, ACPI_BASE_ADDRESS,
+			    0x1, 0xff)
+		})
+	}
+
+	Device (RTC)
+	{
+		Name (_HID, EISAID ("PNP0B00"))
+		Name (_DDN, "Real Time Clock")
+		Name (_CRS, ResourceTemplate ()
+		{
+			IO (Decode16, 0x70, 0x70, 1, 8)
+		})
+	}
+
+	Device (TIMR)
+	{
+		Name (_HID, EISAID ("PNP0100"))
+		Name (_DDN, "8254 Timer")
+		Name (_CRS, ResourceTemplate ()
+		{
+			IO (Decode16, 0x40, 0x40, 0x01, 0x04)
+			IO (Decode16, 0x50, 0x50, 0x10, 0x04)
+			IRQNoFlags () {0}
+		})
+	}
+
+	#include <acpi/ec.asl>
+	#include <acpi/superio.asl>
+}
diff --git a/src/soc/intel/kabylake/acpi/pch.asl b/src/soc/intel/kabylake/acpi/pch.asl
new file mode 100644
index 0000000..6277c27
--- /dev/null
+++ b/src/soc/intel/kabylake/acpi/pch.asl
@@ -0,0 +1,72 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ * Copyright (C) 2015 Google Inc.
+ * 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 <soc/iomap.h>
+#include <soc/irq.h>
+#include <soc/gpio_defs.h>
+#include <soc/gpe.h>
+#include <soc/pcr.h>
+
+/* GPIO Controller */
+#include "gpio.asl"
+
+/* Interrupt Routing */
+#include "irqlinks.asl"
+
+/* LPC 0:1f.0 */
+#include "lpc.asl"
+
+/* PCH HDA */
+#include "pch_hda.asl"
+
+/* PCIE Ports */
+#include "pcie.asl"
+
+/* PCR Access */
+#include "pcr.asl"
+
+/* PMC 0:1f.2 */
+#include "pmc.asl"
+
+/* Serial IO */
+#include "serialio.asl"
+
+/* SMBus 0:1f.3 */
+#include "smbus.asl"
+
+/* Storage Controllers */
+#include "scs.asl"
+
+/* USB XHCI 0:14.0 */
+#include "xhci.asl"
+
+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)
+	}
+}
diff --git a/src/soc/intel/kabylake/acpi/pch_hda.asl b/src/soc/intel/kabylake/acpi/pch_hda.asl
new file mode 100644
index 0000000..86d5894
--- /dev/null
+++ b/src/soc/intel/kabylake/acpi/pch_hda.asl
@@ -0,0 +1,84 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015-2016 Intel Corporation.
+ * Copyright (C) 2015 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.
+ */
+
+/* Audio Controller - Device 31, Function 3 */
+
+Device (HDAS)
+{
+	Name (_ADR, 0x001F0003)
+	Name (_DDN, "Audio Controller")
+	Name (UUID, ToUUID ("A69F886E-6CEB-4594-A41F-7B5DCE24C553"))
+
+	/* Device is D3 wake capable */
+	Name (_S0W, 3)
+
+	/* NHLT Table Address populated from GNVS values */
+	Name (NBUF, ResourceTemplate () {
+		QWordMemory (ResourceConsumer, PosDecode, MinFixed,
+			     MaxFixed, NonCacheable, ReadOnly,
+			     0, 0, 0, 0, 1,,, NHLT, AddressRangeACPI)
+	})
+
+	/*
+	 * Device Specific Method
+	 * Arg0 - UUID
+	 * Arg1 - Revision
+	 * Arg2 - Function Index
+	 */
+	Method (_DSM, 4)
+	{
+		If (LEqual (Arg0, ^UUID)) {
+			/*
+			 * Function 0: Function Support Query
+			 * Returns a bitmask of functions supported.
+			 */
+			If (LEqual (Arg2, Zero)) {
+				/*
+				 * NHLT Query only supported for revision 1 and
+				 * if NHLT address and length are set in NVS.
+				 */
+				If (LAnd (LEqual (Arg1, One),
+					  LAnd (LNotEqual (NHLA, Zero),
+						LNotEqual (NHLL, Zero)))) {
+					Return (Buffer (One) { 0x03 })
+				} Else {
+					Return (Buffer (One) { 0x01 })
+				}
+			}
+
+			/*
+			 * Function 1: Query NHLT memory address used by
+			 * Intel Offload Engine Driver to discover any non-HDA
+			 * devices that are supported by the DSP.
+			 *
+			 * Returns a pointer to NHLT table in memory.
+			 */
+			If (LEqual (Arg2, One)) {
+				CreateQWordField (NBUF, ^NHLT._MIN, NBAS)
+				CreateQWordField (NBUF, ^NHLT._MAX, NMAS)
+				CreateQWordField (NBUF, ^NHLT._LEN, NLEN)
+
+				Store (NHLA, NBAS)
+				Store (NHLA, NMAS)
+				Store (NHLL, NLEN)
+
+				Return (NBUF)
+			}
+		}
+
+		Return (Buffer (One) { 0x00 })
+	}
+}
diff --git a/src/soc/intel/kabylake/acpi/pci_irqs.asl b/src/soc/intel/kabylake/acpi/pci_irqs.asl
new file mode 100644
index 0000000..ec31fb2
--- /dev/null
+++ b/src/soc/intel/kabylake/acpi/pci_irqs.asl
@@ -0,0 +1,133 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ * Copyright (C) 2014 Google Inc.
+ * 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 <soc/interrupt.h>
+#include <soc/irq.h>
+
+Name (PICP, Package () {
+	/* D31: cAVS, SMBus, GbE, Nothpeak */
+	Package () { 0x001FFFFF, 0, 0, cAVS_INTA_IRQ },
+	Package () { 0x001FFFFF, 1, 0, SMBUS_INTB_IRQ },
+	Package () { 0x001FFFFF, 2, 0, GbE_INTC_IRQ },
+	Package () { 0x001FFFFF, 3, 0, TRACE_HUB_INTD_IRQ },
+	/* D30: SerialIo and SCS */
+	Package () { 0x001EFFFF, 0, 0, LPSS_UART0_IRQ },
+	Package () { 0x001EFFFF, 1, 0, eMMC_IRQ },
+	Package () { 0x001EFFFF, 2, 0, SDIO_IRQ },
+	Package () { 0x001EFFFF, 3, 0, SD_IRQ },
+	/* D29: PCI Express Port 9-16 */
+	Package () { 0x001DFFFF, 0, 0, PCIE_9_IRQ },
+	Package () { 0x001DFFFF, 1, 0, PCIE_10_IRQ },
+	Package () { 0x001DFFFF, 2, 0, PCIE_11_IRQ },
+	Package () { 0x001DFFFF, 3, 0, PCIE_12_IRQ },
+	/* D28: PCI Express Port 1-8 */
+	Package () { 0x001CFFFF, 0, 0, PCIE_1_IRQ },
+	Package () { 0x001CFFFF, 1, 0, PCIE_2_IRQ },
+	Package () { 0x001CFFFF, 2, 0, PCIE_3_IRQ },
+	Package () { 0x001CFFFF, 3, 0, PCIE_4_IRQ },
+	/* D25: SerialIo */
+	Package () { 0x0019FFFF, 0, 0, LPSS_UART2_IRQ },
+	Package () { 0x0019FFFF, 1, 0, LPSS_I2C5_IRQ },
+	Package () { 0x0019FFFF, 2, 0, LPSS_I2C4_IRQ },
+	/* D22: CSME (HECI, IDE-R, KT redirection */
+	Package () { 0x0016FFFF, 0, 0, HECI_1_IRQ },
+	Package () { 0x0016FFFF, 1, 0, HECI_2_IRQ },
+	Package () { 0x0016FFFF, 2, 0, IDER_IRQ },
+	Package () { 0x0016FFFF, 3, 0, KT_IRQ },
+	/* D21: SerialIo */
+	Package () { 0x0015FFFF, 0, 0, LPSS_I2C0_IRQ },
+	Package () { 0x0015FFFF, 1, 0, LPSS_I2C1_IRQ },
+	Package () { 0x0015FFFF, 2, 0, LPSS_I2C2_IRQ },
+	Package () { 0x0015FFFF, 3, 0, LPSS_I2C3_IRQ },
+	/* D20: xHCI, OTG, Thermal, Camera */
+	Package () { 0x0014FFFF, 0, 0, XHCI_IRQ },
+	Package () { 0x0014FFFF, 1, 0, OTG_IRQ },
+	Package () { 0x0014FFFF, 2, 0, THRMAL_IRQ },
+	Package () { 0x0014FFFF, 3, 0, CIO_INTD_IRQ },
+	/* D19: Integrated Sensor Hub */
+	Package () { 0x0013FFFF, 0, 0, ISH_IRQ },
+	/* P.E.G. Root Port D1F0 */
+	Package () { 0x0001FFFF, 0, 0, PEG_RP_INTA_IRQ },
+	Package () { 0x0001FFFF, 1, 0, PEG_RP_INTB_IRQ },
+	Package () { 0x0001FFFF, 2, 0, PEG_RP_INTC_IRQ },
+	Package () { 0x0001FFFF, 3, 0, PEG_RP_INTD_IRQ },
+	/* SA IGFX Device */
+	Package () { 0x0002FFFF, 0, 0, IGFX_IRQ },
+	/* SA Thermal Device */
+	Package () { 0x0004FFFF, 0, 0, SA_THERMAL_IRQ },
+	/* SA SkyCam Device */
+	Package () { 0x0005FFFF, 0, 0, SKYCAM_IRQ },
+	/* SA GMM Device */
+	Package () { 0x0008FFFF, 0, 0, GMM_IRQ },
+})
+
+Name (PICN, Package () {
+	/* D31: cAVS, SMBus, GbE, Nothpeak */
+	Package () { 0x001FFFFF, 0, \_SB.PCI0.LNKA, 0 },
+	Package () { 0x001FFFFF, 1, \_SB.PCI0.LNKB, 0 },
+	Package () { 0x001FFFFF, 2, \_SB.PCI0.LNKC, 0 },
+	Package () { 0x001FFFFF, 3, \_SB.PCI0.LNKD, 0 },
+	/* D29: PCI Express Port 9-16 */
+	Package () { 0x001DFFFF, 0, \_SB.PCI0.LNKA, 0 },
+	Package () { 0x001DFFFF, 1, \_SB.PCI0.LNKB, 0 },
+	Package () { 0x001DFFFF, 2, \_SB.PCI0.LNKC, 0 },
+	Package () { 0x001DFFFF, 3, \_SB.PCI0.LNKD, 0 },
+	/* D28: PCI Express Port 1-8 */
+	Package () { 0x001CFFFF, 0, \_SB.PCI0.LNKA, 0 },
+	Package () { 0x001CFFFF, 1, \_SB.PCI0.LNKB, 0 },
+	Package () { 0x001CFFFF, 2, \_SB.PCI0.LNKC, 0 },
+	Package () { 0x001CFFFF, 3, \_SB.PCI0.LNKD, 0 },
+	/* D27: PCI Express Port 17-20 */
+	Package () { 0x001BFFFF, 0, \_SB.PCI0.LNKA, 0 },
+	Package () { 0x001BFFFF, 1, \_SB.PCI0.LNKB, 0 },
+	Package () { 0x001BFFFF, 2, \_SB.PCI0.LNKC, 0 },
+	Package () { 0x001BFFFF, 3, \_SB.PCI0.LNKD, 0 },
+	/* D23 */
+	Package () { 0x0017FFFF, 0, \_SB.PCI0.LNKA, 0 },
+	/* D22: CSME (HECI, IDE-R, KT redirection */
+	Package () { 0x0016FFFF, 0, \_SB.PCI0.LNKA, 0 },
+	Package () { 0x0016FFFF, 1, \_SB.PCI0.LNKB, 0 },
+	Package () { 0x0016FFFF, 2, \_SB.PCI0.LNKC, 0 },
+	Package () { 0x0016FFFF, 3, \_SB.PCI0.LNKD, 0 },
+	/* D20: xHCI, OTG, Thermal, Camera */
+	Package () { 0x0014FFFF, 0, \_SB.PCI0.LNKA, 0 },
+	Package () { 0x0014FFFF, 1, \_SB.PCI0.LNKB, 0 },
+	Package () { 0x0014FFFF, 2, \_SB.PCI0.LNKC, 0 },
+	Package () { 0x0014FFFF, 3, \_SB.PCI0.LNKD, 0 },
+	/* P.E.G. Root Port D1F0 */
+	Package () { 0x0001FFFF, 0, \_SB.PCI0.LNKA, 0 },
+	Package () { 0x0001FFFF, 1, \_SB.PCI0.LNKB, 0 },
+	Package () { 0x0001FFFF, 2, \_SB.PCI0.LNKC, 0 },
+	Package () { 0x0001FFFF, 3, \_SB.PCI0.LNKD, 0 },
+	/* SA IGFX Device */
+	Package () { 0x0002FFFF, 0, \_SB.PCI0.LNKA, 0 },
+	/* SA Thermal Device */
+	Package () { 0x0004FFFF, 0, \_SB.PCI0.LNKA, 0 },
+	/* SA Skycam Device */
+	Package () { 0x0005FFFF, 0, \_SB.PCI0.LNKA, 0 },
+	/* SA GMM Device */
+	Package () { 0x0008FFFF, 0, \_SB.PCI0.LNKA, 0 },
+})
+
+Method (_PRT)
+{
+	If (PICM) {
+		Return (^PICP)
+	} Else {
+		Return (^PICN)
+	}
+}
diff --git a/src/soc/intel/kabylake/acpi/pcie.asl b/src/soc/intel/kabylake/acpi/pcie.asl
new file mode 100644
index 0000000..71a27d7
--- /dev/null
+++ b/src/soc/intel/kabylake/acpi/pcie.asl
@@ -0,0 +1,316 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ * Copyright (C) 2014 Google Inc.
+ * 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.
+ */
+
+/* Intel PCH PCIe support */
+
+Method (IRQM, 1, Serialized) {
+
+	/* Interrupt Map INTA->INTA, INTB->INTB, INTC->INTC, INTD->INTD */
+	Name (IQAA, Package () {
+		Package () { 0x0000ffff, 0, 0, 16 },
+		Package () { 0x0000ffff, 1, 0, 17 },
+		Package () { 0x0000ffff, 2, 0, 18 },
+		Package () { 0x0000ffff, 3, 0, 19 } })
+	Name (IQAP, Package () {
+		Package () { 0x0000ffff, 0, \_SB.PCI0.LNKA, 0 },
+		Package () { 0x0000ffff, 1, \_SB.PCI0.LNKB, 0 },
+		Package () { 0x0000ffff, 2, \_SB.PCI0.LNKC, 0 },
+		Package () { 0x0000ffff, 3, \_SB.PCI0.LNKD, 0 } })
+
+	/* Interrupt Map INTA->INTB, INTB->INTC, INTC->INTD, INTD->INTA */
+	Name (IQBA, Package () {
+		Package () { 0x0000ffff, 0, 0, 17 },
+		Package () { 0x0000ffff, 1, 0, 18 },
+		Package () { 0x0000ffff, 2, 0, 19 },
+		Package () { 0x0000ffff, 3, 0, 16 } })
+	Name (IQBP, Package () {
+		Package () { 0x0000ffff, 0, \_SB.PCI0.LNKB, 0 },
+		Package () { 0x0000ffff, 1, \_SB.PCI0.LNKC, 0 },
+		Package () { 0x0000ffff, 2, \_SB.PCI0.LNKD, 0 },
+		Package () { 0x0000ffff, 3, \_SB.PCI0.LNKA, 0 } })
+
+	/* Interrupt Map INTA->INTC, INTB->INTD, INTC->INTA, INTD->INTB */
+	Name (IQCA, Package () {
+		Package () { 0x0000ffff, 0, 0, 18 },
+		Package () { 0x0000ffff, 1, 0, 19 },
+		Package () { 0x0000ffff, 2, 0, 16 },
+		Package () { 0x0000ffff, 3, 0, 17 } })
+	Name (IQCP, Package () {
+		Package () { 0x0000ffff, 0, \_SB.PCI0.LNKC, 0 },
+		Package () { 0x0000ffff, 1, \_SB.PCI0.LNKD, 0 },
+		Package () { 0x0000ffff, 2, \_SB.PCI0.LNKA, 0 },
+		Package () { 0x0000ffff, 3, \_SB.PCI0.LNKB, 0 } })
+
+	/* Interrupt Map INTA->INTD, INTB->INTA, INTC->INTB, INTD->INTC */
+	Name (IQDA, Package () {
+		Package () { 0x0000ffff, 0, 0, 19 },
+		Package () { 0x0000ffff, 1, 0, 16 },
+		Package () { 0x0000ffff, 2, 0, 17 },
+		Package () { 0x0000ffff, 3, 0, 18 } })
+	Name (IQDP, Package () {
+		Package () { 0x0000ffff, 0, \_SB.PCI0.LNKD, 0 },
+		Package () { 0x0000ffff, 1, \_SB.PCI0.LNKA, 0 },
+		Package () { 0x0000ffff, 2, \_SB.PCI0.LNKB, 0 },
+		Package () { 0x0000ffff, 3, \_SB.PCI0.LNKC, 0 } })
+
+	Switch (ToInteger (Arg0))
+	{
+		Case (Package () { 1, 5, 9 }) {
+			If (PICM) {
+				Return (IQAA)
+			} Else {
+				Return (IQAP)
+			}
+		}
+
+		Case (Package () { 2, 6, 10 }) {
+			If (PICM) {
+				Return (IQBA)
+			} Else {
+				Return (IQBP)
+			}
+		}
+
+		Case (Package () { 3, 7, 11 }) {
+			If (PICM) {
+				Return (IQCA)
+			} Else {
+				Return (IQCP)
+			}
+		}
+
+		Case (Package () { 4, 8, 12 }) {
+			If (PICM) {
+				Return (IQDA)
+			} Else {
+				Return (IQDP)
+			}
+		}
+
+		Default {
+			If (PICM) {
+				Return (IQDA)
+			} Else {
+				Return (IQDP)
+			}
+		}
+	}
+}
+
+Device (RP01)
+{
+	Name (_ADR, 0x001C0000)
+
+	OperationRegion (RPCS, PCI_Config, 0x4c, 4)
+	Field (RPCS, AnyAcc, NoLock, Preserve)
+	{
+		, 24,
+		RPPN, 8,	/* Root Port Number */
+	}
+
+	Method (_PRT)
+	{
+		Return (IRQM (RPPN))
+	}
+}
+
+Device (RP02)
+{
+	Name (_ADR, 0x001C0001)
+
+	OperationRegion (RPCS, PCI_Config, 0x4c, 4)
+	Field (RPCS, AnyAcc, NoLock, Preserve)
+	{
+		, 24,
+		RPPN, 8,	/* Root Port Number */
+	}
+
+	Method (_PRT)
+	{
+		Return (IRQM (RPPN))
+	}
+}
+
+Device (RP03)
+{
+	Name (_ADR, 0x001C0002)
+
+	OperationRegion (RPCS, PCI_Config, 0x4c, 4)
+	Field (RPCS, AnyAcc, NoLock, Preserve)
+	{
+		, 24,
+		RPPN, 8,	/* Root Port Number */
+	}
+
+	Method (_PRT)
+	{
+		Return (IRQM (RPPN))
+	}
+}
+
+Device (RP04)
+{
+	Name (_ADR, 0x001C0003)
+
+	OperationRegion (RPCS, PCI_Config, 0x4c, 4)
+	Field (RPCS, AnyAcc, NoLock, Preserve)
+	{
+		, 24,
+		RPPN, 8,	/* Root Port Number */
+	}
+
+	Method (_PRT)
+	{
+		Return (IRQM (RPPN))
+	}
+}
+
+Device (RP05)
+{
+	Name (_ADR, 0x001C0004)
+
+	OperationRegion (RPCS, PCI_Config, 0x4c, 4)
+	Field (RPCS, AnyAcc, NoLock, Preserve)
+	{
+		, 24,
+		RPPN, 8,	/* Root Port Number */
+	}
+
+	Method (_PRT)
+	{
+		Return (IRQM (RPPN))
+	}
+}
+
+Device (RP06)
+{
+	Name (_ADR, 0x001C0005)
+
+	OperationRegion (RPCS, PCI_Config, 0x4c, 4)
+	Field (RPCS, AnyAcc, NoLock, Preserve)
+	{
+		, 24,
+		RPPN, 8,	/* Root Port Number */
+	}
+
+	Method (_PRT)
+	{
+		Return (IRQM (RPPN))
+	}
+}
+
+Device (RP07)
+{
+	Name (_ADR, 0x001C0006)
+
+	OperationRegion (RPCS, PCI_Config, 0x4c, 4)
+	Field (RPCS, AnyAcc, NoLock, Preserve)
+	{
+		, 24,
+		RPPN, 8,	/* Root Port Number */
+	}
+
+	Method (_PRT)
+	{
+		Return (IRQM (RPPN))
+	}
+}
+
+Device (RP08)
+{
+	Name (_ADR, 0x001C0007)
+
+	OperationRegion (RPCS, PCI_Config, 0x4c, 4)
+	Field (RPCS, AnyAcc, NoLock, Preserve)
+	{
+		, 24,
+		RPPN, 8,	/* Root Port Number */
+	}
+
+	Method (_PRT)
+	{
+		Return (IRQM (RPPN))
+	}
+}
+
+Device (RP09)
+{
+        Name (_ADR, 0x001D0000)
+
+	OperationRegion (RPCS, PCI_Config, 0x4c, 4)
+	Field (RPCS, AnyAcc, NoLock, Preserve)
+	{
+		, 24,
+		RPPN, 8,	/* Root Port Number */
+	}
+
+        Method (_PRT)
+        {
+		Return (IRQM (RPPN))
+        }
+}
+
+Device (RP10)
+{
+        Name (_ADR, 0x001D0001)
+
+	OperationRegion (RPCS, PCI_Config, 0x4c, 4)
+	Field (RPCS, AnyAcc, NoLock, Preserve)
+	{
+		, 24,
+		RPPN, 8,	/* Root Port Number */
+	}
+
+        Method (_PRT)
+        {
+		Return (IRQM (RPPN))
+        }
+}
+
+Device (RP11)
+{
+        Name (_ADR, 0x001D0002)
+
+	OperationRegion (RPCS, PCI_Config, 0x4c, 4)
+	Field (RPCS, AnyAcc, NoLock, Preserve)
+	{
+		, 24,
+		RPPN, 8,	/* Root Port Number */
+	}
+
+        Method (_PRT)
+        {
+		Return (IRQM (RPPN))
+        }
+}
+
+Device (RP12)
+{
+	Name (_ADR, 0x001D0003)
+
+	OperationRegion (RPCS, PCI_Config, 0x4c, 4)
+	Field (RPCS, AnyAcc, NoLock, Preserve)
+	{
+		, 24,
+		RPPN, 8,	/* Root Port Number */
+	}
+
+        Method (_PRT)
+        {
+		Return (IRQM (RPPN))
+        }
+}
diff --git a/src/soc/intel/kabylake/acpi/pcr.asl b/src/soc/intel/kabylake/acpi/pcr.asl
new file mode 100644
index 0000000..38ea4d2
--- /dev/null
+++ b/src/soc/intel/kabylake/acpi/pcr.asl
@@ -0,0 +1,71 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 Google Inc.
+ * 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.
+ */
+
+/*
+ * Calculate PCR register base at specified PID
+ * Arg0 - PCR Port ID
+ */
+Method (PCRB, 1, NotSerialized)
+{
+	Return (Add (PCH_PCR_BASE_ADDRESS, ShiftLeft (Arg0, PCR_PORTID_SHIFT)))
+}
+
+/*
+ * Read a PCR register at specified PID and offset
+ * Arg0 - PCR Port ID
+ * Arg1 - Register Offset
+ */
+Method (PCRR, 2, Serialized)
+{
+	OperationRegion (PCRD, SystemMemory, Add (PCRB (Arg0), Arg1), 4)
+	Field (PCRD, DWordAcc, NoLock, Preserve)
+	{
+		DATA, 32
+	}
+	Return (DATA)
+}
+
+/*
+ * AND a value with PCR register at specified PID and offset
+ * Arg0 - PCR Port ID
+ * Arg1 - Register Offset
+ * Arg2 - Value to AND
+ */
+Method (PCRA, 3, Serialized)
+{
+	OperationRegion (PCRD, SystemMemory, Add (PCRB (Arg0), Arg1), 4)
+	Field (PCRD, DWordAcc, NoLock, Preserve)
+	{
+		DATA, 32
+	}
+	And (DATA, Arg2, DATA)
+}
+
+/*
+ * OR a value with PCR register at specified PID and offset
+ * Arg0 - PCR Port ID
+ * Arg1 - Register Offset
+ * Arg2 - Value to OR
+ */
+Method (PCRO, 3, Serialized)
+{
+	OperationRegion (PCRD, SystemMemory, Add (PCRB (Arg0), Arg1), 4)
+	Field (PCRD, DWordAcc, NoLock, Preserve)
+	{
+		DATA, 32
+	}
+	Or (DATA, Arg2, DATA)
+}
diff --git a/src/soc/intel/kabylake/acpi/platform.asl b/src/soc/intel/kabylake/acpi/platform.asl
new file mode 100644
index 0000000..2f62709
--- /dev/null
+++ b/src/soc/intel/kabylake/acpi/platform.asl
@@ -0,0 +1,84 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ * Copyright (C) 2014 Google Inc.
+ * 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.
+ */
+
+/* Enable ACPI _SWS methods */
+#include <soc/intel/common/acpi/acpi_wake_source.asl>
+
+/* The APM port can be used for generating software SMIs */
+
+OperationRegion (APMP, SystemIO, 0xb2, 2)
+Field (APMP, ByteAcc, NoLock, Preserve)
+{
+	APMC, 8,	// APM command
+	APMS, 8		// APM status
+}
+
+/* Port 80 POST */
+
+OperationRegion (POST, SystemIO, 0x80, 1)
+Field (POST, ByteAcc, Lock, Preserve)
+{
+	DBG0, 8
+}
+
+/* IO-Trap at 0x800.
+ * This is the ACPI->SMI communication interface.
+ */
+OperationRegion (IO_T, SystemIO, 0x800, 0x10)
+Field (IO_T, ByteAcc, NoLock, Preserve)
+{
+	Offset (0x8),
+	TRP0, 8		/* IO-Trap at 0x808 */
+}
+
+/* SMI I/O Trap */
+Method (TRAP, 1, Serialized)
+{
+	Store (Arg0, SMIF)	// SMI Function
+	Store (0, TRP0)		// Generate trap
+	Return (SMIF)		// Return value of SMI handler
+}
+
+/*
+ * The _PIC method is called by the OS to choose between interrupt
+ * routing via the i8259 interrupt controller or the APIC.
+ *
+ * _PIC is called with a parameter of 0 for i8259 configuration and
+ * with a parameter of 1 for Local Apic/IOAPIC configuration.
+ */
+
+Method (_PIC, 1)
+{
+	/* Remember the OS' IRQ routing choice. */
+	Store (Arg0, PICM)
+}
+
+/*
+ * The _PTS method (Prepare To Sleep) is called before the OS is
+ * entering a sleep state. The sleep state number is passed in Arg0
+ */
+
+Method (_PTS, 1)
+{
+}
+
+/* The _WAK method is called on system wakeup */
+
+Method (_WAK, 1)
+{
+	Return (Package (){ 0, 0 })
+}
diff --git a/src/soc/intel/kabylake/acpi/pmc.asl b/src/soc/intel/kabylake/acpi/pmc.asl
new file mode 100644
index 0000000..d097082
--- /dev/null
+++ b/src/soc/intel/kabylake/acpi/pmc.asl
@@ -0,0 +1,41 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 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.
+ */
+
+Device (PMC)
+{
+	Name (_ADR, 0x001f0002)
+	Name (_DDN, "Power Management Controller")
+
+	OperationRegion (PMCP, PCI_Config, 0x00, 0x100)
+	Field (PMCP, AnyAcc, NoLock, Preserve)
+	{
+		Offset (0x48),
+		, 12,
+		PWRM, 20,	/* PWRMBASE */
+	}
+
+	OperationRegion (PMCM, SystemMemory, ShiftLeft (PWRM, 12), 0x3f)
+	Field (PMCM, DWordAcc, NoLock, Preserve)
+	{
+		Offset (0x1c),	/* PCH_PM_STS */
+		, 24,
+		PMFS, 1,	/* PMC_MSG_FULL_STS */
+		Offset (0x20),
+		MPMC, 32,	/* MTPMC */
+		Offset (0x24),	/* PCH_PM_STS2 */
+		, 20,
+		UWAB, 1,	/* USB2 Workaround Available */
+	}
+}
diff --git a/src/soc/intel/kabylake/acpi/scs.asl b/src/soc/intel/kabylake/acpi/scs.asl
new file mode 100644
index 0000000..c0b8046
--- /dev/null
+++ b/src/soc/intel/kabylake/acpi/scs.asl
@@ -0,0 +1,127 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 Google Inc.
+ * 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.
+ */
+
+/* Intel Storage Controllers */
+
+Device (EMMC)
+{
+	Name (_ADR, 0x001E0004)
+	Name (_DDN, "eMMC Controller")
+
+	OperationRegion (EMCR, PCI_Config, 0x00, 0x100)
+	Field (EMCR, DWordAcc, NoLock, Preserve)
+	{
+		Offset (0x84),	/* PMECTRLSTATUS */
+		D0D3, 2,	/* POWERSTATE */
+		Offset (0xa2),	/* PG_CONFIG */
+		, 2,
+		PGEN, 1,	/* PG_ENABLE */
+	}
+
+	Method (_PS0, 0, Serialized)
+	{
+		/* Disable Power Gate */
+		Store (0, ^PGEN)
+
+		/* Clear bits 31, 6, 2, 0 */
+		^^PCRA (PID_SCS, 0x600, 0x7FFFFFBA)
+		Sleep (2)
+
+		/* Set bits 31, 6, 2, 0 */
+		^^PCRO (PID_SCS, 0x600, 0x80000045)
+
+		/* Set Power State to D0 */
+		Store (Zero, Local0)
+		Store (Local0, ^D0D3)
+		Store (^D0D3, Local0)
+	}
+
+	Method (_PS3, 0, Serialized)
+	{
+		/* Enable Power Gate */
+		Store (1, ^PGEN)
+
+		/* Set Power State to D0 */
+		Store (3, Local0)
+		Store (Local0, ^D0D3)
+		Store (^D0D3, Local0)
+	}
+
+	Device (CARD)
+	{
+		Name (_ADR, 0x00000008)
+		Method (_RMV, 0, NotSerialized)
+		{
+			Return (0)
+		}
+	}
+}
+
+#if !IS_ENABLED(CONFIG_EXCLUDE_NATIVE_SD_INTERFACE)
+Device (SDXC)
+{
+	Name (_ADR, 0x001E0006)
+	Name (_DDN, "SD Controller")
+
+	OperationRegion (SDCR, PCI_Config, 0x00, 0x100)
+	Field (SDCR, DWordAcc, NoLock, Preserve)
+	{
+		Offset (0x84),	/* PMECTRLSTATUS */
+		D0D3, 2,	/* POWERSTATE */
+		Offset (0xa2),	/* PG_CONFIG */
+		, 2,
+		PGEN, 1,	/* PG_ENABLE */
+	}
+
+	Method (_PS0, 0, Serialized)
+	{
+		/* Disable Power Gate */
+		Store (0, ^PGEN)
+
+		/* Clear bits 8, 7, 2, 0 */
+		^^PCRA (PID_SCS, 0x600, 0xFFFFFE7A)
+		Sleep (2)
+
+		/* Set bits 31, 6, 2, 0 */
+		^^PCRO (PID_SCS, 0x600, 0x00000185)
+
+		/* Set Power State to D0 */
+		Store (Zero, Local0)
+		Store (Local0, ^D0D3)
+		Store (^D0D3, Local0)
+	}
+
+	Method (_PS3, 0, Serialized)
+	{
+		/* Enable Power Gate */
+		Store (1, ^PGEN)
+
+		/* Set Power State to D0 */
+		Store (3, Local0)
+		Store (Local0, ^D0D3)
+		Store (^D0D3, Local0)
+	}
+
+	Device (CARD)
+	{
+		Name (_ADR, 0x00000008)
+		Method (_RMV, 0, NotSerialized)
+		{
+			Return (1)
+		}
+	}
+}
+#endif
\ No newline at end of file
diff --git a/src/soc/intel/kabylake/acpi/serialio.asl b/src/soc/intel/kabylake/acpi/serialio.asl
new file mode 100644
index 0000000..9e7b24c
--- /dev/null
+++ b/src/soc/intel/kabylake/acpi/serialio.asl
@@ -0,0 +1,83 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 Google Inc.
+ * 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.
+ */
+
+/* Intel Serial IO Devices */
+
+Device (I2C0)
+{
+	Name (_ADR, 0x00150000)
+	Name (_DDN, "Serial IO I2C Controller 0")
+}
+
+Device (I2C1)
+{
+	Name (_ADR, 0x00150001)
+	Name (_DDN, "Serial IO I2C Controller 1")
+}
+
+Device (I2C2)
+{
+	Name (_ADR, 0x00150002)
+	Name (_DDN, "Serial IO I2C Controller 2")
+}
+
+Device (I2C3)
+{
+	Name (_ADR, 0x00150003)
+	Name (_DDN, "Serial IO I2C Controller 3")
+}
+
+Device (I2C4)
+{
+	Name (_ADR, 0x00190002)
+	Name (_DDN, "Serial IO I2C Controller 4")
+}
+
+Device (I2C5)
+{
+	Name (_ADR, 0x00190002)
+	Name (_DDN, "Serial IO I2C Controller 5")
+}
+
+Device (SPI0)
+{
+	Name (_ADR, 0x001E0002)
+	Name (_DDN, "Serial IO SPI Controller 0")
+}
+
+Device (SPI1)
+{
+	Name (_ADR, 0x001E0003)
+	Name (_DDN, "Serial IO SPI Controller 1")
+}
+
+Device (UAR0)
+{
+	Name (_ADR, 0x001E0000)
+	Name (_DDN, "Serial IO UART Controller 0")
+}
+
+Device (UAR1)
+{
+	Name (_ADR, 0x001E0001)
+	Name (_DDN, "Serial IO UART Controller 1")
+}
+
+Device (UAR2)
+{
+	Name (_ADR, 0x00190000)
+	Name (_DDN, "Serial IO UART Controller 2")
+}
diff --git a/src/soc/intel/kabylake/acpi/sleepstates.asl b/src/soc/intel/kabylake/acpi/sleepstates.asl
new file mode 100644
index 0000000..cb175f4
--- /dev/null
+++ b/src/soc/intel/kabylake/acpi/sleepstates.asl
@@ -0,0 +1,23 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ * Copyright (C) 2014 Google Inc.
+ * 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.
+ */
+
+Name (\_S0, Package () { 0x0, 0x0, 0x0, 0x0 })
+Name (\_S1, Package () { 0x1, 0x1, 0x0, 0x0 })
+Name (\_S2, Package () { 0x1, 0x1, 0x0, 0x0 })
+Name (\_S3, Package () { 0x5, 0x5, 0x0, 0x0 })
+Name (\_S4, Package () { 0x6, 0x6, 0x0, 0x0 })
+Name (\_S5, Package () { 0x7, 0x7, 0x0, 0x0 })
diff --git a/src/soc/intel/kabylake/acpi/smbus.asl b/src/soc/intel/kabylake/acpi/smbus.asl
new file mode 100644
index 0000000..b71cbda
--- /dev/null
+++ b/src/soc/intel/kabylake/acpi/smbus.asl
@@ -0,0 +1,238 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ * Copyright (C) 2014 Google Inc.
+ * 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.
+ */
+
+// Intel SMBus Controller 0:1f.3
+
+Device (SBUS)
+{
+	Name (_ADR, 0x001f0004)
+
+#ifdef ENABLE_SMBUS_METHODS
+	OperationRegion (SMBP, PCI_Config, 0x00, 0x100)
+	Field(SMBP, DWordAcc, NoLock, Preserve)
+	{
+		Offset(0x40),
+		,	2,
+		I2CE,	1
+	}
+
+	OperationRegion (SMBI, SystemIO, SMBUS_IO_BASE, 0x20)
+	Field (SMBI, ByteAcc, NoLock, Preserve)
+	{
+		HSTS,	8,	// Host Status
+		,	8,
+		HCNT,	8,	// Host Control
+		HCMD,	8,	// Host Command
+		TXSA,	8,	// Transmit Slave Address
+		DAT0,	8,	// Host Data 0
+		DAT1,	8,	// Host Data 1
+		HBDB,	8,	// Host Block Data Byte
+		PECK,	8,	// Packet Error Check
+		RXSA,	8,	// Receive Slave Address
+		RXDA,	16,	// Receive Slave Data
+		AUXS,	8,	// Auxiliary Status
+		AUXC,	8,	// Auxiliary Control
+		SLPC,	8,	// SMLink Pin Control
+		SBPC,	8,	// SMBus Pin Control
+		SSTS,	8,	// Slave Status
+		SCMD,	8,	// Slave Command
+		NADR,	8,	// Notify Device Address
+		NDLB,	8,	// Notify Data Low Byte
+		NDLH,	8,	// Notify Data High Byte
+	}
+
+	// Kill all SMBus communication
+	Method (KILL, 0, Serialized)
+	{
+		Or (HCNT, 0x02, HCNT)	// Send Kill
+		Or (HSTS, 0xff, HSTS)	// Clean Status
+	}
+
+	// Check if last operation completed
+	// return	Failure = 0, Success = 1
+	Method (CMPL, 0, Serialized)
+	{
+		Store (4000, Local0)		// Timeout 200ms in 50us steps
+		While (Local0) {
+			If (And(HSTS, 0x02)) {	// Completion Status?
+				Return (1)	// Operation Completed
+			} Else {
+				Stall (50)
+				Decrement (Local0)
+				If (LEqual(Local0, 0)) {
+					KILL()
+				}
+			}
+		}
+
+		Return (0)		//  Failure
+	}
+
+
+	// Wait for SMBus to become ready
+	Method (SRDY, 0, Serialized)
+	{
+		Store (200, Local0)	// Timeout 200ms
+		While (Local0) {
+			If (And(HSTS, 0x40)) {		// IN_USE?
+				Sleep(1)		// Wait 1ms
+				Decrement(Local0)	// timeout--
+				If (LEqual(Local0, 0)) {
+					Return (1)
+				}
+			} Else {
+				Store (0, Local0)	// We're ready
+			}
+		}
+
+		Store (4000, Local0)	// Timeout 200ms (50us * 4000)
+		While (Local0) {
+			If (And (HSTS, 0x01)) {		// Host Busy?
+				Stall(50)		// Wait 50us
+				Decrement(Local0)	// timeout--
+				If (LEqual(Local0, 0)) {
+					KILL()
+				}
+			} Else {
+				Return (0)		// Success
+			}
+		}
+
+		Return (1)		// Failure
+	}
+
+	// SMBus Send Byte
+	// Arg0:	Address
+	// Arg1:	Data
+	// Return:	1 = Success, 0=Failure
+
+	Method (SSXB, 2, Serialized)
+	{
+
+		// Is the SMBus Controller Ready?
+		If (SRDY()) {
+			Return (0)
+		}
+
+		// Send Byte
+		Store (0, I2CE)		// SMBus Enable
+		Store (0xbf, HSTS)
+		Store (Arg0, TXSA)	// Write Address
+		Store (Arg1, HCMD)	// Write Data
+
+		Store (0x48, HCNT)	// Start + Byte Data Protocol
+
+		If (CMPL()) {
+			Or (HSTS, 0xff, HSTS)	// Clean up
+			Return (1)		// Success
+		}
+
+		Return (0)
+	}
+
+
+	// SMBus Receive Byte
+	// Arg0:	Address
+	// Return:	0xffff = Failure, Data (8bit) = Success
+
+	Method (SRXB, 2, Serialized)
+	{
+
+		// Is the SMBus Controller Ready?
+		If (SRDY()) {
+			Return (0xffff)
+		}
+
+		// Receive Byte
+		Store (0, I2CE)		// SMBus Enable
+		Store (0xbf, HSTS)
+		Store (Or (Arg0, 1), TXSA)	// Write Address
+
+		Store (0x44, HCNT)	// Start
+
+		If (CMPL()) {
+			Or (HSTS, 0xff, HSTS)	// Clean up
+			Return (DAT0)		// Success
+		}
+
+		Return (0xffff)
+	}
+
+
+	// SMBus Write Byte
+	// Arg0:	Address
+	// Arg1:	Command
+	// Arg2:	Data
+	// Return:	1 = Success, 0=Failure
+
+	Method (SWRB, 3, Serialized)
+	{
+
+		// Is the SMBus Controller Ready?
+		If (SRDY()) {
+			Return (0)
+		}
+
+		// Send Byte
+		Store (0, I2CE)		// SMBus Enable
+		Store (0xbf, HSTS)
+		Store (Arg0, TXSA)	// Write Address
+		Store (Arg1, HCMD)	// Write Command
+		Store (Arg2, DAT0)	// Write Data
+
+		Store (0x48, HCNT)	// Start + Byte Protocol
+
+		If (CMPL()) {
+			Or (HSTS, 0xff, HSTS)	// Clean up
+			Return (1)		// Success
+		}
+
+		Return (0)
+	}
+
+
+	// SMBus Read Byte
+	// Arg0:	Address
+	// Arg1:	Command
+	// Return:	0xffff = Failure, Data (8bit) = Success
+
+	Method (SRDB, 2, Serialized)
+	{
+
+		// Is the SMBus Controller Ready?
+		If (SRDY()) {
+			Return (0xffff)
+		}
+
+		// Receive Byte
+		Store (0, I2CE)			// SMBus Enable
+		Store (0xbf, HSTS)
+		Store (Or (Arg0, 1), TXSA)	// Write Address
+		Store (Arg1, HCMD)		// Command
+
+		Store (0x48, HCNT)		// Start
+
+		If (CMPL()) {
+			Or (HSTS, 0xff, HSTS)	// Clean up
+			Return (DAT0)		// Success
+		}
+
+		Return (0xffff)
+	}
+#endif
+}
+
diff --git a/src/soc/intel/kabylake/acpi/systemagent.asl b/src/soc/intel/kabylake/acpi/systemagent.asl
new file mode 100644
index 0000000..53a2748
--- /dev/null
+++ b/src/soc/intel/kabylake/acpi/systemagent.asl
@@ -0,0 +1,372 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ * Copyright (C) 2015 Google Inc.
+ * 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 <soc/iomap.h>
+
+#define BASE_32GB	0x800000000
+#define SIZE_16GB	0x400000000
+
+Name (_HID, EISAID ("PNP0A08"))	/* PCIe */
+Name (_CID, EISAID ("PNP0A03"))	/* PCI */
+
+Name (_ADR, 0)
+Name (_BBN, 0)
+
+Device (MCHC)
+{
+	Name (_ADR, 0x00000000)
+
+	OperationRegion (MCHP, PCI_Config, 0x00, 0x100)
+	Field (MCHP, DWordAcc, NoLock, Preserve)
+	{
+		Offset(0x40),	/* EPBAR (0:0:0:40) */
+		EPEN, 1,	/* Enable */
+		, 11,
+		EPBR, 20,	/* EPBAR [31:12] */
+
+		Offset(0x48),	/* MCHBAR (0:0:0:48) */
+		MHEN, 1,	/* Enable */
+		, 14,
+		MHBR, 17,	/* MCHBAR [31:15] */
+
+		Offset(0x60),	/* PCIEXBAR (0:0:0:60) */
+		PXEN, 1,	/* Enable */
+		PXSZ, 2,	/* PCI Express Size */
+		, 23,
+		PXBR, 6,	/* PCI Express BAR [31:26] */
+
+		Offset(0x68),	/* DMIBAR (0:0:0:68) */
+		DIEN, 1,	/* Enable */
+		, 11,
+		DIBR, 20,	/* DMIBAR [31:12] */
+
+		Offset (0x70),	/* ME Base Address */
+		MEBA, 64,
+
+		Offset (0xa0),	/* Top of Used Memory */
+		TOM, 64,
+
+		Offset (0xa8),	/* Top of Upper Used Memory */
+		TUUD, 64,
+
+		Offset (0xbc),	/* Top of Low Used Memory */
+		TLUD, 32,
+	}
+}
+
+Name (MCRS, ResourceTemplate ()
+{
+	/* Bus Numbers */
+	WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode,
+			0x0000, 0x0000, 0x00ff, 0x0000, 0x0100)
+
+	/* IO Region 0 */
+	DWordIO (ResourceProducer, MinFixed, MaxFixed, PosDecode,
+			EntireRange,
+			0x0000, 0x0000, 0x0cf7, 0x0000, 0x0cf8)
+
+	/* PCI Config Space */
+	Io (Decode16, 0x0cf8, 0x0cf8, 0x0001, 0x0008)
+
+	/* IO Region 1 */
+	DWordIO (ResourceProducer, MinFixed, MaxFixed, PosDecode,
+			EntireRange,
+			0x0000, 0x0d00, 0xffff, 0x0000, 0xf300)
+
+	/* VGA memory (0xa0000-0xbffff) */
+	DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
+			Cacheable, ReadWrite,
+			0x00000000, 0x000a0000, 0x000bffff, 0x00000000,
+			0x00020000)
+
+	/*  OPROM reserved (0xc0000-0xc3fff) */
+	DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
+			Cacheable, ReadWrite,
+			0x00000000, 0x000c0000, 0x000c3fff, 0x00000000,
+			0x00004000)
+
+	/* OPROM reserved (0xc4000-0xc7fff) */
+	DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
+			Cacheable, ReadWrite,
+			0x00000000, 0x000c4000, 0x000c7fff, 0x00000000,
+			0x00004000)
+
+	/* OPROM reserved (0xc8000-0xcbfff) */
+	DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
+			Cacheable, ReadWrite,
+			0x00000000, 0x000c8000, 0x000cbfff, 0x00000000,
+			0x00004000)
+
+	/* OPROM reserved (0xcc000-0xcffff) */
+	DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
+			Cacheable, ReadWrite,
+			0x00000000, 0x000cc000, 0x000cffff, 0x00000000,
+			0x00004000)
+
+	/* OPROM reserved (0xd0000-0xd3fff) */
+	DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
+			Cacheable, ReadWrite,
+			0x00000000, 0x000d0000, 0x000d3fff, 0x00000000,
+			0x00004000)
+
+	/* OPROM reserved (0xd4000-0xd7fff) */
+	DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
+			Cacheable, ReadWrite,
+			0x00000000, 0x000d4000, 0x000d7fff, 0x00000000,
+			0x00004000)
+
+	/* OPROM reserved (0xd8000-0xdbfff) */
+	DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
+			Cacheable, ReadWrite,
+			0x00000000, 0x000d8000, 0x000dbfff, 0x00000000,
+			0x00004000)
+
+	/* OPROM reserved (0xdc000-0xdffff) */
+	DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
+			Cacheable, ReadWrite,
+			0x00000000, 0x000dc000, 0x000dffff, 0x00000000,
+			0x00004000)
+
+	/* BIOS Extension (0xe0000-0xe3fff) */
+	DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
+			Cacheable, ReadWrite,
+			0x00000000, 0x000e0000, 0x000e3fff, 0x00000000,
+			0x00004000)
+
+	/* BIOS Extension (0xe4000-0xe7fff) */
+	DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
+			Cacheable, ReadWrite,
+			0x00000000, 0x000e4000, 0x000e7fff, 0x00000000,
+			0x00004000)
+
+	/* BIOS Extension (0xe8000-0xebfff) */
+	DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
+			Cacheable, ReadWrite,
+			0x00000000, 0x000e8000, 0x000ebfff, 0x00000000,
+			0x00004000)
+
+	/* BIOS Extension (0xec000-0xeffff) */
+	DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
+			Cacheable, ReadWrite,
+			0x00000000, 0x000ec000, 0x000effff, 0x00000000,
+			0x00004000)
+
+	/* System BIOS (0xf0000-0xfffff) */
+	DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
+			Cacheable, ReadWrite,
+			0x00000000, 0x000f0000, 0x000fffff, 0x00000000,
+			0x00010000)
+
+	/* PCI Memory Region (TOLUD - 0xdfffffff) */
+	DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
+			NonCacheable, ReadWrite,
+			0x00000000, 0x00000000, 0xdfffffff, 0x00000000,
+			0xE0000000,,, PM01)
+
+	/* PCI Memory Region (TOUUD - (TOUUD + ABOVE_4G_MMIO_SIZE)) */
+	QWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
+			NonCacheable, ReadWrite,
+			0x00000000, 0x10000, 0x1ffff, 0x00000000,
+			0x10000,,, PM02)
+
+	/* PCH reserved resource (0xfd000000-0xfe7fffff) */
+	DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
+			Cacheable, ReadWrite,
+			0x00000000, 0xfd000000, 0xfe7fffff, 0x00000000,
+			0x1800000)
+
+	/* TPM Area (0xfed40000-0xfed44fff) */
+	DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
+			Cacheable, ReadWrite,
+			0x00000000, 0xfed40000, 0xfed44fff, 0x00000000,
+			0x00005000)
+})
+
+Method (_CRS, 0, Serialized)
+{
+	/* Find PCI resource area in MCRS */
+	CreateDwordField (^MCRS, ^PM01._MIN, PMIN)
+	CreateDwordField (^MCRS, ^PM01._MAX, PMAX)
+	CreateDwordField (^MCRS, ^PM01._LEN, PLEN)
+
+	/*
+	 * Fix up PCI memory region
+	 * Start with Top of Lower Usable DRAM
+	 */
+	Store (^MCHC.TLUD, Local0)
+	Store (^MCHC.MEBA, Local1)
+
+	/*  Check if ME base is equal */
+	If (LEqual (Local0, Local1)) {
+		/*  Use Top Of Memory instead */
+		Store (^MCHC.TOM, Local0)
+	}
+
+	Store (Local0, PMIN)
+	Add (Subtract (PMAX, PMIN), 1, PLEN)
+
+	/* Patch PM02 range based on Memory Size */
+	CreateQwordField (^MCRS, ^PM02._MIN, MMIN)
+	CreateQwordField (^MCRS, ^PM02._MAX, MMAX)
+	CreateQwordField (^MCRS, ^PM02._LEN, MLEN)
+
+	Store (^MCHC.TUUD, Local0)
+
+	If (LLessEqual (Local0, BASE_32GB)) {
+		Store (BASE_32GB, MMIN)
+		Store (SIZE_16GB, MLEN)
+	} Else {
+		Store (0, MMIN)
+		Store (0, MLEN)
+	}
+	Subtract (Add (MMIN, MLEN), 1, MMAX)
+
+	Return (^MCRS)
+}
+
+Name (EP_B, 0) /* to store EP BAR */
+Name (MH_B, 0) /* to store MCH BAR */
+Name (PC_B, 0) /* to store PCIe BAR */
+Name (PC_L, 0) /* to store PCIe BAR Length */
+Name (DM_B, 0) /* to store DMI BAR */
+
+/* Get MCH BAR */
+Method (GMHB, 0, Serialized)
+{
+	If (LEqual (MH_B, 0)) {
+		ShiftLeft (\_SB.PCI0.MCHC.MHBR, 15, MH_B)
+	}
+	Return (MH_B)
+}
+
+/* Get EP BAR */
+Method (GEPB, 0, Serialized)
+{
+	If (LEqual (EP_B, 0)) {
+		ShiftLeft (\_SB.PCI0.MCHC.EPBR, 12, EP_B)
+	}
+	Return (EP_B)
+}
+
+/* Get PCIe BAR */
+Method (GPCB, 0, Serialized)
+{
+	If (LEqual (PC_B, 0)) {
+		ShiftLeft (\_SB.PCI0.MCHC.PXBR, 26, PC_B)
+	}
+	Return (PC_B)
+}
+
+/* Get PCIe Length */
+Method (GPCL, 0, Serialized)
+{
+	If (LEqual (PC_L, 0)) {
+		ShiftRight (0x10000000, \_SB.PCI0.MCHC.PXSZ, PC_L)
+	}
+	Return (PC_L)
+}
+
+/* Get DMI BAR */
+Method (GDMB, 0, Serialized)
+{
+	If (LEqual (DM_B, 0)) {
+		ShiftLeft (\_SB.PCI0.MCHC.DIBR, 12, DM_B)
+	}
+	Return (DM_B)
+}
+
+/* PCI Device Resource Consumption */
+Device (PDRC)
+{
+	Name (_HID, EISAID ("PNP0C02"))
+	Name (_UID, 1)
+
+	Name (BUF0, ResourceTemplate ()
+	{
+		/* MCH BAR _BAS will be updated in _CRS below according to
+		 * B0:D0:F0:Reg.48h
+		 */
+		Memory32Fixed (ReadWrite, 0, 0x08000, MCHB)
+
+		/* DMI BAR _BAS will be updated in _CRS below according to
+		 * B0:D0:F0:Reg.68h
+		 */
+		Memory32Fixed (ReadWrite, 0, 0x01000, DMIB)
+
+		/* EP BAR _BAS will be updated in _CRS below according to
+		 * B0:D0:F0:Reg.40h
+		 */
+		Memory32Fixed (ReadWrite, 0, 0x01000, EGPB)
+
+		/* PCI Express BAR _BAS and _LEN will be updated in
+		 * _CRS below according to B0:D0:F0:Reg.60h
+		 */
+		Memory32Fixed (ReadWrite, 0, 0, PCIX)
+
+		/* MISC ICH TTT base address reserved for the
+		 * TxT module use.
+		 */
+		Memory32Fixed (ReadWrite, 0xFED20000, 0x20000)
+
+		/* VTD engine memory range.
+		 * Check if the hard code meets the real configuration.
+		 */
+		Memory32Fixed (ReadOnly, 0xFED90000, 0x00004000)
+
+		/* MISC ICH. Check if the hard code meets the
+		 * real configuration.
+		 */
+		Memory32Fixed (ReadWrite, 0xFED45000, 0x4B000, TPMM)
+
+		/* FLASH range */
+		Memory32Fixed (ReadOnly, 0xFF000000, 0x1000000, FIOH) /* 16MB */
+
+		/* Local APIC range(0xFEE0_0000 to 0xFEEF_FFFF) */
+		Memory32Fixed (ReadOnly, 0xFEE00000, 0x100000, LIOH)
+
+		/* HPET address decode range */
+		Memory32Fixed (ReadWrite, HPET_BASE_ADDRESS, 0x400)
+
+		/* Debug Base Address
+		 * Base Address for ACPI debug output memory buffer
+		 */
+		Memory32Fixed (ReadWrite, 0, 0, DBAD)
+	})
+
+	Method (_CRS, 0, Serialized)
+	{
+		CreateDwordField (BUF0, ^MCHB._BAS, MBR0)
+		Store (\_SB.PCI0.GMHB (), MBR0)
+
+		CreateDwordField (BUF0, ^DMIB._BAS, DBR0)
+		Store (\_SB.PCI0.GDMB (), DBR0)
+
+		CreateDwordField (BUF0, ^EGPB._BAS, EBR0)
+		Store (\_SB.PCI0.GEPB (), EBR0)
+
+		CreateDwordField (BUF0, ^PCIX._BAS, XBR0)
+		Store (\_SB.PCI0.GPCB (), XBR0)
+
+		CreateDwordField (BUF0, ^PCIX._LEN, XSZ0)
+		Store (\_SB.PCI0.GPCL (), XSZ0)
+
+		Return (BUF0)
+	}
+}
+
+/* PCI IRQ assignment */
+#include "pci_irqs.asl"
diff --git a/src/soc/intel/kabylake/acpi/xhci.asl b/src/soc/intel/kabylake/acpi/xhci.asl
new file mode 100644
index 0000000..7d0618f
--- /dev/null
+++ b/src/soc/intel/kabylake/acpi/xhci.asl
@@ -0,0 +1,185 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ * Copyright (C) 2015 Google Inc.
+ * 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.
+ */
+
+/* XHCI Controller 0:14.0 */
+
+Device (XHCI)
+{
+	Name (_ADR, 0x00140000)
+
+	Name (_PRW, Package () { GPE0_PME_B0, 3 })
+
+	Method (_DSW, 3)
+	{
+		Store (Arg0, PMEE)
+	}
+
+	Name (_S3D, 3)	/* D3 supported in S3 */
+	Name (_S4D, 3)	/* D3 supported in S4 */
+	Name (_S0W, 3)	/* D3 can wake device in S0 */
+	Name (_S3W, 3)	/* D3 can wake system from S3 */
+	Name (_S4W, 3)	/* D3 can wake system from S4 */
+
+	OperationRegion (XPRT, PCI_Config, 0x00, 0x100)
+	Field (XPRT, AnyAcc, NoLock, Preserve)
+	{
+		Offset (0x0),
+		DVID, 16,	/* VENDORID */
+		Offset (0x10),
+		, 16,
+		XMEM, 16,	/* MEM_BASE */
+		Offset (0x74),
+		D0D3, 2,	/* POWERSTATE */
+		, 6,
+		PMEE, 1,	/* PME_EN */
+		, 6,
+		PMES, 1,	/* PME_STS */
+	}
+
+	OperationRegion (XREG, SystemMemory,
+			 Add (ShiftLeft (XMEM, 16), 0x8000), 0x200)
+	Field (XREG, DWordAcc, Lock, Preserve)
+	{
+		Offset (0x1c4),	/* USB2PMCTRL */
+		, 2,
+		UPSW, 2,	/* U2PSUSPGP */
+	}
+
+	Method (_PSC, 0, Serialized)
+	{
+		Return (^D0D3)
+	}
+
+	Method (_PS0, 0, Serialized)
+	{
+		If (LEqual (^DVID, 0xFFFF)) {
+			Return
+		}
+		If (LOr (LEqual (^XMEM, 0xFFFF), LEqual (^XMEM, 0x0000))) {
+			Return
+		}
+
+		/* If device is in D3, set back to D0 */
+		If (LEqual (^D0D3, 3)) {
+			Store (Zero, Local0)
+			Store (Local0, ^D0D3)
+			Store (^D0D3, Local0)
+		}
+
+		/* Disable USB2 PHY SUS Well Power Gating */
+		Store (Zero, ^UPSW)
+
+		/*
+		 * Apply USB2 PHPY Power Gating workaround if needed.
+		 */
+		If (^^PMC.UWAB) {
+			/* Write to MTPMC to have PMC disable power gating */
+			Store (1, ^^PMC.MPMC)
+
+			/* Wait for PCH_PM_STS.MSG_FULL_STS to be 0 */
+			Store (10, Local0)
+			While (^^PMC.PMFS) {
+				If (LNot (Local0)) {
+					Break
+				}
+				Decrement (Local0)
+				Sleep (10)
+			}
+		}
+	}
+
+	Method (_PS3, 0, Serialized)
+	{
+		If (LEqual (^DVID, 0xFFFF)) {
+			Return
+		}
+		If (LOr (LEqual (^XMEM, 0xFFFF), LEqual (^XMEM, 0x0000))) {
+			Return
+		}
+
+		/* Clear PME Status */
+		Store (1, ^PMES)
+
+		/* Enable PME */
+		Store (1, ^PMEE)
+
+		/* If device is in D3, set back to D0 */
+		If (LEqual (^D0D3, 3)) {
+			Store (Zero, Local0)
+			Store (Local0, ^D0D3)
+			Store (^D0D3, Local0)
+		}
+
+		/* Enable USB2 PHY SUS Well Power Gating in D0/D0i2/D0i3/D3 */
+		Store (3, ^UPSW)
+
+		/* Now put device in D3 */
+		Store (3, Local0)
+		Store (Local0, ^D0D3)
+		Store (^D0D3, Local0)
+
+		/*
+		 * Apply USB2 PHPY Power Gating workaround if needed.
+		 * This code assumes XDCI is disabled, if it is enabled
+		 * then this must also check if it is in D3 state too.
+		 */
+		If (^^PMC.UWAB) {
+			/* Write to MTPMC to have PMC enable power gating */
+			Store (3, ^^PMC.MPMC)
+
+			/* Wait for PCH_PM_STS.MSG_FULL_STS to be 0 */
+			Store (10, Local0)
+			While (^^PMC.PMFS) {
+				If (LNot (Local0)) {
+					Break
+				}
+				Decrement (Local0)
+				Sleep (10)
+			}
+		}
+	}
+
+	/* Root Hub for Kabylake-LP PCH */
+	Device (RHUB)
+	{
+		Name (_ADR, Zero)
+
+		/* USB2 */
+		Device (HS01) { Name (_ADR, 1) }
+		Device (HS02) { Name (_ADR, 2) }
+		Device (HS03) { Name (_ADR, 3) }
+		Device (HS04) { Name (_ADR, 4) }
+		Device (HS05) { Name (_ADR, 5) }
+		Device (HS06) { Name (_ADR, 6) }
+		Device (HS07) { Name (_ADR, 7) }
+		Device (HS08) { Name (_ADR, 8) }
+		Device (HS09) { Name (_ADR, 9) }
+		Device (HS10) { Name (_ADR, 10) }
+
+		/* USBr */
+		Device (USR1) { Name (_ADR, 11) }
+		Device (USR2) { Name (_ADR, 12) }
+
+		/* USB3 */
+		Device (SS01) { Name (_ADR, 13) }
+		Device (SS02) { Name (_ADR, 14) }
+		Device (SS03) { Name (_ADR, 15) }
+		Device (SS04) { Name (_ADR, 16) }
+		Device (SS05) { Name (_ADR, 17) }
+		Device (SS06) { Name (_ADR, 18) }
+	}
+}
diff --git a/src/soc/intel/kabylake/bootblock/cpu.c b/src/soc/intel/kabylake/bootblock/cpu.c
new file mode 100644
index 0000000..6d5065a
--- /dev/null
+++ b/src/soc/intel/kabylake/bootblock/cpu.c
@@ -0,0 +1,165 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * 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 <stdint.h>
+#include <arch/cpu.h>
+#include <cpu/x86/cache.h>
+#include <cpu/x86/msr.h>
+#include <cpu/x86/mtrr.h>
+#include <device/pci_def.h>
+#include <arch/io.h>
+#include <cpu/intel/microcode/microcode.c>
+#include <reset.h>
+#include <soc/iomap.h>
+#include <soc/msr.h>
+#include <soc/pci_devs.h>
+#include <soc/spi.h>
+
+/* Soft Reset Data Register Bit 12 = MAX Boot Frequency */
+#define SPI_STRAP_MAX_FREQ	(1<<12)
+/* Soft Reset Data Register Bit 6-11 = Flex Ratio */
+#define FLEX_RATIO_BIT	6
+
+static void set_var_mtrr(
+	unsigned reg, unsigned base, unsigned size, unsigned type)
+
+{
+	/* Bit Bit 32-35 of MTRRphysMask should be set to 1 */
+	msr_t basem, maskm;
+	basem.lo = base | type;
+	basem.hi = 0;
+	wrmsr(MTRR_PHYS_BASE(reg), basem);
+	maskm.lo = ~(size - 1) | MTRR_PHYS_MASK_VALID;
+	maskm.hi = (1 << (CONFIG_CPU_ADDR_BITS - 32)) - 1;
+	wrmsr(MTRR_PHYS_MASK(reg), maskm);
+}
+
+static void enable_rom_caching(void)
+{
+	msr_t msr;
+
+	disable_cache();
+	set_var_mtrr(1, CACHE_ROM_BASE, CACHE_ROM_SIZE, MTRR_TYPE_WRPROT);
+	enable_cache();
+
+	/* Enable Variable MTRRs */
+	msr.hi = 0x00000000;
+	msr.lo = 0x00000800;
+	wrmsr(MTRR_DEF_TYPE_MSR, msr);
+}
+
+static void bootblock_mdelay(int ms)
+{
+	u32 target = ms * 24 * 1000;
+	msr_t current;
+	msr_t start = rdmsr(MSR_COUNTER_24_MHZ);
+
+	do {
+		current = rdmsr(MSR_COUNTER_24_MHZ);
+	} while ((current.lo - start.lo) < target);
+}
+
+static void set_pch_cpu_strap(u8 flex_ratio)
+{
+	uint8_t *spibar = (void *)SPI_BASE_ADDRESS;
+	u32 ssl, ssms, soft_reset_data;
+
+
+	/* Set Strap Lock Disable */
+	ssl = read32(spibar + SPIBAR_RESET_LOCK);
+	ssl |= SPIBAR_RESET_LOCK_DISABLE;
+	write32(spibar + SPIBAR_RESET_LOCK, ssl);
+
+	/* Soft Reset Data Register Bit 12 = MAX Boot Frequency
+	 * Bit 6-11 = Flex Ratio
+	 * Soft Reset Data register located at SPIBAR0 offset 0xF8[0:15].
+	 */
+	soft_reset_data = SPI_STRAP_MAX_FREQ;
+	soft_reset_data |= (flex_ratio << FLEX_RATIO_BIT);
+	write32(spibar + SPIBAR_RESET_DATA, soft_reset_data);
+
+	/* Set Strap Mux Select  set to '1' */
+	ssms = read32(spibar + SPIBAR_RESET_CTRL);
+	ssms |= SPIBAR_RESET_CTRL_SSMC;
+	write32(spibar + SPIBAR_RESET_CTRL, ssms);
+
+	/* Set Strap Lock Enable */
+	ssl = read32(spibar + SPIBAR_RESET_LOCK);
+	ssl |= SPIBAR_RESET_LOCK_ENABLE;
+	write32(spibar + SPIBAR_RESET_LOCK, ssl);
+}
+
+static void set_flex_ratio_to_tdp_nominal(void)
+{
+	msr_t flex_ratio, msr;
+	u8 nominal_ratio;
+
+	/* Check for Flex Ratio support */
+	flex_ratio = rdmsr(MSR_FLEX_RATIO);
+	if (!(flex_ratio.lo & FLEX_RATIO_EN))
+		return;
+
+	/* Check for >0 configurable TDPs */
+	msr = rdmsr(MSR_PLATFORM_INFO);
+	if (((msr.hi >> 1) & 3) == 0)
+		return;
+
+	/* Use nominal TDP ratio for flex ratio */
+	msr = rdmsr(MSR_CONFIG_TDP_NOMINAL);
+	nominal_ratio = msr.lo & 0xff;
+
+	/* See if flex ratio is already set to nominal TDP ratio */
+	if (((flex_ratio.lo >> 8) & 0xff) == nominal_ratio)
+		return;
+
+	/* Set flex ratio to nominal TDP ratio */
+	flex_ratio.lo &= ~0xff00;
+	flex_ratio.lo |= nominal_ratio << 8;
+	flex_ratio.lo |= FLEX_RATIO_LOCK;
+	wrmsr(MSR_FLEX_RATIO, flex_ratio);
+
+	/* Set PCH Soft Reset Data Register with new Flex Ratio */
+	set_pch_cpu_strap(nominal_ratio);
+
+	/* Delay before reset to avoid potential TPM lockout */
+	bootblock_mdelay(30);
+
+	/* Issue soft reset, will be "CPU only" due to soft reset data */
+	soft_reset();
+}
+
+static void check_for_clean_reset(void)
+{
+	msr_t msr;
+	msr = rdmsr(MTRR_DEF_TYPE_MSR);
+
+	/*
+	 * Use the MTRR default type MSR as a proxy for detecting INIT#.
+	 * Reset the system if any known bits are set in that MSR. That is
+	 * an indication of the CPU not being properly reset.
+	 */
+	if (msr.lo & (MTRR_DEF_TYPE_EN | MTRR_DEF_TYPE_FIX_EN))
+		soft_reset();
+}
+
+static void bootblock_cpu_init(void)
+{
+	/* Set flex ratio and reset if needed */
+	set_flex_ratio_to_tdp_nominal();
+	check_for_clean_reset();
+	enable_rom_caching();
+	intel_update_microcode_from_cbfs();
+}
diff --git a/src/soc/intel/kabylake/bootblock/pch.c b/src/soc/intel/kabylake/bootblock/pch.c
new file mode 100644
index 0000000..65ad5cf
--- /dev/null
+++ b/src/soc/intel/kabylake/bootblock/pch.c
@@ -0,0 +1,58 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * 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 <arch/io.h>
+#include <soc/iomap.h>
+#include <soc/lpc.h>
+#include <soc/pci_devs.h>
+#include <soc/spi.h>
+
+/*
+ * Enable Prefetching and Caching.
+ */
+static void enable_spi_prefetch(void)
+{
+	u8 reg8 = pci_read_config8(PCH_DEV_SPI, 0xdc);
+	reg8 &= ~(3 << 2);
+	reg8 |= (2 << 2); /* Prefetching and Caching Enabled */
+	pci_write_config8(PCH_DEV_SPI, 0xdc, reg8);
+}
+
+static void enable_spibar(void)
+{
+	device_t dev = PCH_DEV_SPI;
+	u8 pcireg;
+
+	/* Assign Resources to SPI Controller */
+	/* Clear BIT 1-2 SPI Command Register */
+	pcireg = pci_read_config8(dev, PCI_COMMAND);
+	pcireg &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
+	pci_write_config8(dev, PCI_COMMAND, pcireg);
+
+	/* Program Temporary BAR for SPI */
+	pci_write_config32(dev, PCI_BASE_ADDRESS_0,
+		SPI_BASE_ADDRESS | PCI_BASE_ADDRESS_SPACE_MEMORY);
+
+	/* Enable Bus Master and MMIO Space */
+	pcireg = pci_read_config8(dev, PCI_COMMAND);
+	pcireg |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
+	pci_write_config8(dev, PCI_COMMAND, pcireg);
+}
+
+static void bootblock_southbridge_init(void)
+{
+	enable_spibar();
+	enable_spi_prefetch();
+}
diff --git a/src/soc/intel/kabylake/bootblock/systemagent.c b/src/soc/intel/kabylake/bootblock/systemagent.c
new file mode 100644
index 0000000..12b23a8
--- /dev/null
+++ b/src/soc/intel/kabylake/bootblock/systemagent.c
@@ -0,0 +1,41 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * 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 <arch/io.h>
+#include <soc/pci_devs.h>
+#include <soc/systemagent.h>
+
+static void bootblock_northbridge_init(void)
+{
+	uint32_t reg;
+
+	/*
+	 * The "io" variant of the config access is explicitly used to
+	 * setup the PCIEXBAR because CONFIG_MMCONF_SUPPORT_DEFAULT is set to
+	 * to true. That way all subsequent non-explicit config accesses use
+	 * MCFG. This code also assumes that bootblock_northbridge_init() is
+	 * the first thing called in the non-asm boot block code. The final
+	 * assumption is that no assembly code is using the
+	 * CONFIG_MMCONF_SUPPORT_DEFAULT option to do PCI config acceses.
+	 *
+	 * The PCIEXBAR is assumed to live in the memory mapped IO space under
+	 * 4GiB.
+	 */
+	reg = 0;
+	pci_io_write_config32(SA_DEV_ROOT, PCIEXBAR + 4, reg);
+	reg = CONFIG_MMCONF_BASE_ADDRESS | 4 | 1; /* 64MiB - 0-63 buses. */
+	pci_io_write_config32(SA_DEV_ROOT, PCIEXBAR, reg);
+}
diff --git a/src/soc/intel/kabylake/bootblock/timestamp.inc b/src/soc/intel/kabylake/bootblock/timestamp.inc
new file mode 100644
index 0000000..48986b2
--- /dev/null
+++ b/src/soc/intel/kabylake/bootblock/timestamp.inc
@@ -0,0 +1,35 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * 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.
+ */
+
+/*
+ * Store the initial timestamp for booting in mmx registers. This works
+ * because the bootblock isn't being compiled with MMX support so mm0 and
+ * mm1 will be preserved into romstage.
+ */
+	.code32
+
+.global stash_timestamp
+stash_timestamp:
+
+	/* Save the BIST value */
+	movl	%eax, %ebp
+
+	finit
+	rdtsc
+	movd	%eax, %mm0
+	movd	%edx, %mm1
+
+	/* Restore the BIST value to %eax */
+	movl	%ebp, %eax
+
diff --git a/src/soc/intel/kabylake/chip.c b/src/soc/intel/kabylake/chip.c
new file mode 100644
index 0000000..ad0d433
--- /dev/null
+++ b/src/soc/intel/kabylake/chip.c
@@ -0,0 +1,1102 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * 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 <arch/acpi.h>
+#include <chip.h>
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <fsp/util.h>
+#include <soc/acpi.h>
+#include <soc/interrupt.h>
+#include <soc/irq.h>
+#include <soc/pci_devs.h>
+#include <soc/ramstage.h>
+#include <string.h>
+
+static const SI_PCH_DEVICE_INTERRUPT_CONFIG devintconfig[] = {
+	/*
+	 * cAVS(Audio, Voice, Speach), INTA is default, programmed in
+	 * PciCfgSpace 3Dh
+	 */
+	DEVICE_INT_CONFIG(PCH_DEV_SLOT_LPC,
+			PCI_FUNC(PCH_DEVFN_HDA), int_A, cAVS_INTA_IRQ),
+	/*
+	 * SMBus Controller, no default value, programmed in
+	 * PciCfgSpace 3Dh
+	 */
+	DEVICE_INT_CONFIG(PCH_DEV_SLOT_LPC,
+			PCI_FUNC(PCH_DEVFN_SMBUS), int_A, SMBUS_INTA_IRQ),
+	/* GbE Controller, INTA is default, programmed in PciCfgSpace 3Dh */
+	DEVICE_INT_CONFIG(PCH_DEV_SLOT_LPC,
+			PCI_FUNC(PCH_DEVFN_GBE), int_A, GbE_INTA_IRQ),
+	/* TraceHub, INTA is default, RO register */
+	DEVICE_INT_CONFIG(PCH_DEV_SLOT_LPC,
+			PCI_FUNC(PCH_DEVFN_TRACEHUB), int_A, TRACE_HUB_INTA_IRQ),
+	/*
+	 * SerialIo: UART #0, INTA is default,
+	 * programmed in PCR[SERIALIO] + PCICFGCTRL[7]
+	 */
+	DEVICE_INT_CONFIG(PCH_DEV_SLOT_STORAGE,
+			PCI_FUNC(PCH_DEVFN_UART0), int_A, LPSS_UART0_IRQ),
+	/*
+	 * SerialIo: UART #1, INTA is default,
+	 * programmed in PCR[SERIALIO] + PCICFGCTRL[8]
+	 */
+	DEVICE_INT_CONFIG(PCH_DEV_SLOT_STORAGE,
+			PCI_FUNC(PCH_DEVFN_UART1), int_B, LPSS_UART1_IRQ),
+	/*
+	 * SerialIo: SPI #0, INTA is default,
+	 * programmed in PCR[SERIALIO] + PCICFGCTRL[10]
+	 */
+	DEVICE_INT_CONFIG(PCH_DEV_SLOT_STORAGE,
+			PCI_FUNC(PCH_DEVFN_GSPI0), int_C, LPSS_SPI0_IRQ),
+	/*
+	 * SerialIo: SPI #1, INTA is default,
+	 * programmed in PCR[SERIALIO] + PCICFGCTRL[11]
+	 */
+	DEVICE_INT_CONFIG(PCH_DEV_SLOT_STORAGE,
+			PCI_FUNC(PCH_DEVFN_GSPI1), int_D, LPSS_SPI1_IRQ),
+	/* SCS: eMMC (SKL PCH-LP Only) */
+	DEVICE_INT_CONFIG(PCH_DEV_SLOT_STORAGE,
+			PCI_FUNC(PCH_DEVFN_EMMC), int_B, eMMC_IRQ),
+	/* SCS: SDIO (SKL PCH-LP Only) */
+	DEVICE_INT_CONFIG(PCH_DEV_SLOT_STORAGE,
+			PCI_FUNC(PCH_DEVFN_SDIO), int_C, SDIO_IRQ),
+	/* SCS: SDCard (SKL PCH-LP Only) */
+	DEVICE_INT_CONFIG(PCH_DEV_SLOT_STORAGE,
+			PCI_FUNC(PCH_DEVFN_SDCARD), int_D, SD_IRQ),
+	/* PCI Express Port 9, INT is default, programmed in PciCfgSpace + FCh */
+	DEVICE_INT_CONFIG(PCH_DEV_SLOT_PCIE_1,
+			PCI_FUNC(PCH_DEVFN_PCIE9), int_A, PCIE_9_IRQ),
+	/* PCI Express Port 10, INT is default, programmed in PciCfgSpace + FCh */
+	DEVICE_INT_CONFIG(PCH_DEV_SLOT_PCIE_1,
+			PCI_FUNC(PCH_DEVFN_PCIE10), int_B, PCIE_10_IRQ),
+	/* PCI Express Port 11, INT is default, programmed in PciCfgSpace + FCh */
+	DEVICE_INT_CONFIG(PCH_DEV_SLOT_PCIE_1,
+			PCI_FUNC(PCH_DEVFN_PCIE11), int_C, PCIE_11_IRQ),
+	/* PCI Express Port 12, INT is default, programmed in PciCfgSpace + FCh */
+	DEVICE_INT_CONFIG(PCH_DEV_SLOT_PCIE_1,
+			PCI_FUNC(PCH_DEVFN_PCIE12), int_D, PCIE_12_IRQ),
+	/*
+	 * PCI Express Port 1, INT is default,
+	 * programmed in PciCfgSpace + FCh
+	 */
+	DEVICE_INT_CONFIG(PCH_DEV_SLOT_PCIE,
+			PCI_FUNC(PCH_DEVFN_PCIE1), int_A, PCIE_1_IRQ),
+	/*
+	 * PCI Express Port 2, INT is default,
+	 * programmed in PciCfgSpace + FCh
+	 */
+	DEVICE_INT_CONFIG(PCH_DEV_SLOT_PCIE,
+			PCI_FUNC(PCH_DEVFN_PCIE2), int_B, PCIE_2_IRQ),
+	/*
+	 * PCI Express Port 3, INT is default,
+	 * programmed in PciCfgSpace + FCh
+	 */
+	DEVICE_INT_CONFIG(PCH_DEV_SLOT_PCIE,
+			PCI_FUNC(PCH_DEVFN_PCIE3), int_C, PCIE_3_IRQ),
+	/*
+	 * PCI Express Port 4, INT is default,
+	 * programmed in PciCfgSpace + FCh
+	 */
+	DEVICE_INT_CONFIG(PCH_DEV_SLOT_PCIE,
+			PCI_FUNC(PCH_DEVFN_PCIE4), int_D, PCIE_4_IRQ),
+	/*
+	 * PCI Express Port 5, INT is default,
+	 * programmed in PciCfgSpace + FCh
+	 */
+	DEVICE_INT_CONFIG(PCH_DEV_SLOT_PCIE,
+			PCI_FUNC(PCH_DEVFN_PCIE5), int_A, PCIE_5_IRQ),
+	/*
+	 * PCI Express Port 6, INT is default,
+	 * programmed in PciCfgSpace + FCh
+	 */
+	DEVICE_INT_CONFIG(PCH_DEV_SLOT_PCIE,
+			PCI_FUNC(PCH_DEVFN_PCIE6), int_B, PCIE_6_IRQ),
+	/*
+	 * PCI Express Port 7, INT is default,
+	 * programmed in PciCfgSpace + FCh
+	 */
+	DEVICE_INT_CONFIG(PCH_DEV_SLOT_PCIE,
+			PCI_FUNC(PCH_DEVFN_PCIE7), int_C, PCIE_7_IRQ),
+	/*
+	 * PCI Express Port 8, INT is default,
+	 * programmed in PciCfgSpace + FCh
+	 */
+	DEVICE_INT_CONFIG(PCH_DEV_SLOT_PCIE,
+			PCI_FUNC(PCH_DEVFN_PCIE8), int_D, PCIE_8_IRQ),
+	/*
+	 * SerialIo UART Controller #2, INTA is default,
+	 * programmed in PCR[SERIALIO] + PCICFGCTRL[9]
+	 */
+	DEVICE_INT_CONFIG(PCH_DEV_SLOT_SIO2,
+			PCI_FUNC(PCH_DEVFN_UART2), int_A, LPSS_UART2_IRQ),
+	/*
+	 * SerialIo UART Controller #5, INTA is default,
+	 * programmed in PCR[SERIALIO] + PCICFGCTRL[6]
+	 */
+	DEVICE_INT_CONFIG(PCH_DEV_SLOT_SIO2,
+			PCI_FUNC(PCH_DEVFN_I2C5), int_B, LPSS_I2C5_IRQ),
+	/*
+	 * SerialIo UART Controller #4, INTA is default,
+	 * programmed in PCR[SERIALIO] + PCICFGCTRL[5]
+	 */
+	DEVICE_INT_CONFIG(PCH_DEV_SLOT_SIO2,
+			PCI_FUNC(PCH_DEVFN_I2C4), int_C, LPSS_I2C4_IRQ),
+	/*
+	 * SATA Controller, INTA is default,
+	 * programmed in PciCfgSpace + 3Dh
+	 */
+	DEVICE_INT_CONFIG(PCH_DEV_SLOT_SATA,
+			PCI_FUNC(PCH_DEVFN_SATA), int_A, SATA_IRQ),
+	/* CSME: HECI #1 */
+	DEVICE_INT_CONFIG(PCH_DEV_SLOT_ME,
+			PCI_FUNC(PCH_DEVFN_ME), int_A, HECI_1_IRQ),
+	/* CSME: HECI #2 */
+	DEVICE_INT_CONFIG(PCH_DEV_SLOT_ME,
+			PCI_FUNC(PCH_DEVFN_ME_2), int_B, HECI_2_IRQ),
+	/* CSME: IDE-Redirection (IDE-R) */
+	DEVICE_INT_CONFIG(PCH_DEV_SLOT_ME,
+			PCI_FUNC(PCH_DEVFN_ME_IDER), int_C, IDER_IRQ),
+	/* CSME: Keyboard and Text (KT) Redirection */
+	DEVICE_INT_CONFIG(PCH_DEV_SLOT_ME,
+			PCI_FUNC(PCH_DEVFN_ME_KT), int_D, KT_IRQ),
+	/* CSME: HECI #3 */
+	DEVICE_INT_CONFIG(PCH_DEV_SLOT_ME,
+			PCI_FUNC(PCH_DEVFN_ME_3), int_A, HECI_3_IRQ),
+	/*
+	 * SerialIo I2C Controller #0, INTA is default,
+	 * programmed in PCR[SERIALIO] + PCICFGCTRL[1]
+	 */
+	DEVICE_INT_CONFIG(PCH_DEV_SLOT_SIO1,
+			PCI_FUNC(PCH_DEVFN_I2C0), int_A, LPSS_I2C0_IRQ),
+	/*
+	 * SerialIo I2C Controller #1, INTA is default,
+	 * programmed in PCR[SERIALIO] + PCICFGCTRL[2]
+	 */
+	DEVICE_INT_CONFIG(PCH_DEV_SLOT_SIO1,
+			PCI_FUNC(PCH_DEVFN_I2C1), int_B, LPSS_I2C1_IRQ),
+	/*
+	 * SerialIo I2C Controller #2, INTA is default,
+	 * programmed in PCR[SERIALIO] + PCICFGCTRL[3]
+	 */
+	DEVICE_INT_CONFIG(PCH_DEV_SLOT_SIO1,
+			PCI_FUNC(PCH_DEVFN_I2C2), int_C, LPSS_I2C2_IRQ),
+	/*
+	 * SerialIo I2C Controller #3, INTA is default,
+	 * programmed in PCR[SERIALIO] + PCICFGCTRL[4]
+	 */
+	DEVICE_INT_CONFIG(PCH_DEV_SLOT_SIO1,
+			PCI_FUNC(PCH_DEVFN_I2C3), int_D, LPSS_I2C3_IRQ),
+	/*
+	 * USB 3.0 xHCI Controller, no default value,
+	 * programmed in PciCfgSpace 3Dh
+	 */
+	DEVICE_INT_CONFIG(PCH_DEV_SLOT_XHCI,
+			PCI_FUNC(PCH_DEVFN_XHCI), int_A, XHCI_IRQ),
+	/* USB Device Controller (OTG) */
+	DEVICE_INT_CONFIG(PCH_DEV_SLOT_XHCI,
+			PCI_FUNC(PCH_DEVFN_USBOTG), int_B, OTG_IRQ),
+	/* Thermal Subsystem */
+	DEVICE_INT_CONFIG(PCH_DEV_SLOT_XHCI,
+			PCI_FUNC(PCH_DEVFN_THERMAL), int_C, THRMAL_IRQ),
+	/* Camera IO Host Controller */
+	DEVICE_INT_CONFIG(PCH_DEV_SLOT_XHCI,
+			PCI_FUNC(PCH_DEVFN_CIO), int_A, CIO_INTA_IRQ),
+	/* Integrated Sensor Hub */
+	DEVICE_INT_CONFIG(PCH_DEV_SLOT_ISH,
+			PCI_FUNC(PCH_DEVFN_ISH), int_A, ISH_IRQ)
+};
+
+#if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES)
+const char *soc_acpi_name(struct device *dev)
+{
+	if (dev->path.type == DEVICE_PATH_DOMAIN)
+		return "PCI0";
+
+	if (dev->path.type != DEVICE_PATH_PCI)
+		return NULL;
+
+	switch (dev->path.pci.devfn) {
+	case SA_DEVFN_ROOT:	return "MCHC";
+	case SA_DEVFN_IGD:	return "GFX0";
+	case PCH_DEVFN_ISH:	return "ISHB";
+	case PCH_DEVFN_XHCI:	return "XHCI";
+	case PCH_DEVFN_USBOTG:	return "XDCI";
+	case PCH_DEVFN_THERMAL:	return "THRM";
+	case PCH_DEVFN_CIO:	return "ICIO";
+	case PCH_DEVFN_I2C0:	return "I2C0";
+	case PCH_DEVFN_I2C1:	return "I2C1";
+	case PCH_DEVFN_I2C2:	return "I2C2";
+	case PCH_DEVFN_I2C3:	return "I2C3";
+	case PCH_DEVFN_ME:	return "MEI1";
+	case PCH_DEVFN_ME_2:	return "MEI2";
+	case PCH_DEVFN_ME_IDER:	return "MEID";
+	case PCH_DEVFN_ME_KT:	return "MEKT";
+	case PCH_DEVFN_ME_3:	return "MEI3";
+	case PCH_DEVFN_SATA:	return "SATA";
+	case PCH_DEVFN_UART2:	return "UAR2";
+	case PCH_DEVFN_I2C4:	return "I2C4";
+	case PCH_DEVFN_I2C5:	return "I2C5";
+	case PCH_DEVFN_PCIE1:	return "RP01";
+	case PCH_DEVFN_PCIE2:	return "RP02";
+	case PCH_DEVFN_PCIE3:	return "RP03";
+	case PCH_DEVFN_PCIE4:	return "RP04";
+	case PCH_DEVFN_PCIE5:	return "RP05";
+	case PCH_DEVFN_PCIE6:	return "RP06";
+	case PCH_DEVFN_PCIE7:	return "RP07";
+	case PCH_DEVFN_PCIE8:	return "RP08";
+	case PCH_DEVFN_PCIE9:	return "RP09";
+	case PCH_DEVFN_PCIE10:	return "RP10";
+	case PCH_DEVFN_PCIE11:	return "RP11";
+	case PCH_DEVFN_PCIE12:	return "RP12";
+	case PCH_DEVFN_UART0:	return "UAR0";
+	case PCH_DEVFN_UART1:	return "UAR1";
+	case PCH_DEVFN_GSPI0:	return "SPI0";
+	case PCH_DEVFN_GSPI1:	return "SPI1";
+	case PCH_DEVFN_EMMC:	return "EMMC";
+	case PCH_DEVFN_SDIO:	return "SDIO";
+	case PCH_DEVFN_SDCARD:	return "SDXC";
+	case PCH_DEVFN_LPC:	return "LPCB";
+	case PCH_DEVFN_P2SB:	return "P2SB";
+	case PCH_DEVFN_PMC:	return "PMC_";
+	case PCH_DEVFN_HDA:	return "HDAS";
+	case PCH_DEVFN_SMBUS:	return "SBUS";
+	case PCH_DEVFN_SPI:	return "FSPI";
+	case PCH_DEVFN_GBE:	return "IGBE";
+	case PCH_DEVFN_TRACEHUB:return "THUB";
+	}
+
+	return NULL;
+}
+#endif
+
+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,
+	.scan_bus         = &pci_domain_scan_bus,
+	.ops_pci_bus      = &pci_bus_default_ops,
+#if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES)
+	.acpi_name        = &soc_acpi_name,
+#endif
+};
+
+static struct device_operations cpu_bus_ops = {
+	.init             = &soc_init_cpus,
+#if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES)
+	.acpi_fill_ssdt_generator = generate_cpu_entries,
+#endif
+};
+
+static void soc_enable(device_t dev)
+{
+	/* Set the operations if it is a special bus type */
+	if (dev->path.type == DEVICE_PATH_DOMAIN) {
+		dev->ops = &pci_domain_ops;
+	} else if (dev->path.type == DEVICE_PATH_CPU_CLUSTER) {
+		dev->ops = &cpu_bus_ops;
+	} else if (dev->path.type == DEVICE_PATH_PCI) {
+		/* Handle PCH device enable */
+		if (PCI_SLOT(dev->path.pci.devfn) > SA_DEV_SLOT_IGD &&
+		    (dev->ops == NULL || dev->ops->enable == NULL)) {
+			pch_enable_dev(dev);
+		}
+	}
+}
+
+struct chip_operations soc_intel_kabylake_ops = {
+	CHIP_NAME("Intel Kabylake")
+	.enable_dev = &soc_enable,
+	.init       = &soc_init_pre_device,
+};
+
+/* UPD parameters to be initialized before SiliconInit */
+void soc_silicon_init_params(SILICON_INIT_UPD *params)
+{
+	const struct device *dev = dev_find_slot(0, PCH_DEVFN_LPC);
+	const struct soc_intel_kabylake_config *config = dev->chip_info;
+	u8 irq_config[PCH_MAX_IRQ_CONFIG];
+	int i;
+	int intdeventry;
+
+	memcpy(params->SerialIoDevMode, config->SerialIoDevMode,
+	       sizeof(params->SerialIoDevMode));
+
+	for (i = 0; i < ARRAY_SIZE(config->usb2_ports); i++) {
+		params->PortUsb20Enable[i] =
+			config->usb2_ports[i].enable;
+		params->Usb2AfePetxiset[i] =
+			config->usb2_ports[i].pre_emp_bias;
+		params->Usb2AfeTxiset[i] =
+			config->usb2_ports[i].tx_bias;
+		params->Usb2AfePredeemp[i] =
+			config->usb2_ports[i].tx_emp_enable;
+		params->Usb2AfePehalfbit[i] =
+			config->usb2_ports[i].pre_emp_bit;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(config->usb3_ports); i++) {
+		params->PortUsb30Enable[i] = config->usb3_ports[i].enable;
+		if (config->usb3_ports[i].tx_de_emp) {
+			params->Usb3HsioTxDeEmphEnable[i] = 1;
+			params->Usb3HsioTxDeEmph[i] =
+				config->usb3_ports[i].tx_de_emp;
+		}
+		if (config->usb3_ports[i].tx_downscale_amp) {
+			params->Usb3HsioTxDownscaleAmpEnable[i] = 1;
+			params->Usb3HsioTxDownscaleAmp[i] =
+				config->usb3_ports[i].tx_downscale_amp;
+		}
+	}
+
+	memcpy(params->PcieRpEnable, config->PcieRpEnable,
+			sizeof(params->PcieRpEnable));
+	memcpy(params->PcieRpClkReqSupport, config->PcieRpClkReqSupport,
+			sizeof(params->PcieRpClkReqSupport));
+	memcpy(params->PcieRpClkReqNumber, config->PcieRpClkReqNumber,
+			sizeof(params->PcieRpClkReqNumber));
+
+	params->EnableLan = config->EnableLan;
+	params->Cio2Enable = config->Cio2Enable;
+	params->SataSalpSupport = config->SataSalpSupport;
+	params->SataPortsEnable[0] = config->SataPortsEnable[0];
+	params->SsicPortEnable = config->SsicPortEnable;
+	params->SmbusEnable = config->SmbusEnable;
+	params->ScsEmmcEnabled = config->ScsEmmcEnabled;
+	params->ScsEmmcHs400Enabled = config->ScsEmmcHs400Enabled;
+	params->ScsSdCardEnabled = config->ScsSdCardEnabled;
+	params->IshEnable = 0;
+	params->EnableAzalia = config->EnableAzalia;
+	params->IoBufferOwnership = config->IoBufferOwnership;
+	params->DspEnable = config->DspEnable;
+	params->XdciEnable = config->XdciEnable;
+	params->Device4Enable = config->Device4Enable;
+	params->EnableSata = config->EnableSata;
+	params->SataMode = config->SataMode;
+	params->LockDownConfigGlobalSmi = config->LockDownConfigGlobalSmi;
+	params->LockDownConfigBiosInterface = config->LockDownConfigBiosInterface;
+	params->LockDownConfigRtcLock = config->LockDownConfigRtcLock;
+	params->LockDownConfigBiosLock = config->LockDownConfigBiosLock;
+	params->LockDownConfigSpiEiss = config->LockDownConfigSpiEiss;
+	params->PchConfigSubSystemVendorId = config->PchConfigSubSystemVendorId;
+	params->PchConfigSubSystemId = config->PchConfigSubSystemId;
+	params->WakeConfigWolEnableOverride = config->WakeConfigWolEnableOverride;
+	params->WakeConfigPcieWakeFromDeepSx = config->WakeConfigPcieWakeFromDeepSx;
+	params->PmConfigDeepSxPol = config->PmConfigDeepSxPol;
+	params->PmConfigSlpS3MinAssert = config->PmConfigSlpS3MinAssert;
+	params->PmConfigSlpS4MinAssert = config->PmConfigSlpS4MinAssert;
+	params->PmConfigSlpSusMinAssert = config->PmConfigSlpSusMinAssert;
+	params->PmConfigSlpAMinAssert = config->PmConfigSlpAMinAssert;
+	params->PmConfigPciClockRun = config->PmConfigPciClockRun;
+	params->PmConfigSlpStrchSusUp = config->PmConfigSlpStrchSusUp;
+	params->PmConfigPwrBtnOverridePeriod = config->PmConfigPwrBtnOverridePeriod;
+	params->PmConfigPwrCycDur = config->PmConfigPwrCycDur;
+	params->SerialIrqConfigSirqEnable = config->SerialIrqConfigSirqEnable;
+	params->SerialIrqConfigSirqMode = config->SerialIrqConfigSirqMode;
+	params->SerialIrqConfigStartFramePulse = config->SerialIrqConfigStartFramePulse;
+
+	params->SkipMpInit = config->FspSkipMpInit;
+
+	for (i = 0; i < ARRAY_SIZE(config->i2c); i++)
+		params->SerialIoI2cVoltage[i] = config->i2c[i].voltage;
+
+	/*
+	 * To disable Heci, the Psf needs to be left unlocked
+	 * by FSP after end of post sequence. Based on the devicetree
+	 * setting, we set the appropriate PsfUnlock policy in Fsp,
+	 * do the changes and then lock it back in Coreboot
+	 *
+	 */
+	if (config->HeciEnabled == 0)
+		params->PsfUnlock = 1;
+	else
+		params->PsfUnlock = 0;
+
+	for (i = 0; i < ARRAY_SIZE(config->domain_vr_config); i++)
+		fill_vr_domain_config(params, i, &config->domain_vr_config[i]);
+
+	/* Show SPI controller if enabled in devicetree.cb */
+	dev = dev_find_slot(0, PCH_DEVFN_SPI);
+	params->ShowSpiController = dev->enabled;
+
+	/* Get Device Int Count */
+	intdeventry = ARRAY_SIZE(devintconfig);
+	/*update irq table*/
+	memcpy((SI_PCH_DEVICE_INTERRUPT_CONFIG *)(params->DevIntConfigPtr), devintconfig,
+			intdeventry * sizeof(SI_PCH_DEVICE_INTERRUPT_CONFIG));
+
+	params->NumOfDevIntConfig = intdeventry;
+	/* PxRC to IRQ programing */
+	for (i = 0; i < PCH_MAX_IRQ_CONFIG; i++) {
+		switch(i) {
+		case PCH_PARC:
+		case PCH_PCRC:
+		case PCH_PDRC:
+		case PCH_PERC:
+		case PCH_PFRC:
+		case PCH_PGRC:
+		case PCH_PHRC:
+			irq_config[i] = PCH_IRQ11;
+			break;
+		case PCH_PBRC:
+			irq_config[PCH_PBRC] = PCH_IRQ10;
+			break;
+		}
+	}
+	memcpy(params->PxRcConfig, irq_config, PCH_MAX_IRQ_CONFIG);
+	/* GPIO IRQ Route  The valid values is 14 or 15*/
+	if(config->GpioIrqSelect == 0)
+		params->GpioIrqRoute = GPIO_IRQ14;
+	else
+		params->GpioIrqRoute = config->GpioIrqSelect;
+	/* SCI IRQ Select  The valid values is 9, 10, 11 and 20 21, 22, 23*/
+	if(config->SciIrqSelect == 0)
+		params->SciIrqSelect = SCI_IRQ9;
+	else
+		params->SciIrqSelect = config->SciIrqSelect;
+	/* TCO IRQ Select  The valid values is 9, 10, 11, 20 21, 22, 23*/
+	if(config->TcoIrqSelect == 0)
+		params->TcoIrqSelect = TCO_IRQ9;
+	else
+		params->TcoIrqSelect = config->TcoIrqSelect;
+	/* TCO Irq enable/disable */
+	params->TcoIrqEnable = config->TcoIrqEnable;
+	params->SendVrMbxCmd = config->SendVrMbxCmd;
+}
+
+void soc_display_silicon_init_params(const SILICON_INIT_UPD *original,
+	SILICON_INIT_UPD *params)
+{
+	/* Display the parameters for SiliconInit */
+	printk(BIOS_SPEW, "UPD values for SiliconInit:\n");
+	fsp_display_upd_value("LogoPtr", 4,
+			(uint32_t)original->LogoPtr,
+			(uint32_t)params->LogoPtr);
+	fsp_display_upd_value("LogoSize", 4,
+		(uint32_t)original->LogoSize,
+		(uint32_t)params->LogoSize);
+	fsp_display_upd_value("GraphicsConfigPtr", 4,
+		(uint32_t)original->GraphicsConfigPtr,
+		(uint32_t)params->GraphicsConfigPtr);
+	fsp_display_upd_value("MicrocodeRegionBase", 4,
+		(uint32_t)original->MicrocodeRegionBase,
+		(uint32_t)params->MicrocodeRegionBase);
+	fsp_display_upd_value("MicrocodeRegionSize", 4,
+		(uint32_t)original->MicrocodeRegionSize,
+		(uint32_t)params->MicrocodeRegionSize);
+	fsp_display_upd_value("TurboMode", 1,
+		(uint32_t)original->TurboMode,
+		(uint32_t)params->TurboMode);
+	fsp_display_upd_value("Device4Enable", 1,
+		original->Device4Enable,
+		params->Device4Enable);
+	fsp_display_upd_value("PcieRpEnable[0]", 1, original->PcieRpEnable[0],
+		params->PcieRpEnable[0]);
+	fsp_display_upd_value("PcieRpEnable[1]", 1, original->PcieRpEnable[1],
+		params->PcieRpEnable[1]);
+	fsp_display_upd_value("PcieRpEnable[2]", 1, original->PcieRpEnable[2],
+		params->PcieRpEnable[2]);
+	fsp_display_upd_value("PcieRpEnable[3]", 1, original->PcieRpEnable[3],
+		params->PcieRpEnable[3]);
+	fsp_display_upd_value("PcieRpEnable[4]", 1, original->PcieRpEnable[4],
+		params->PcieRpEnable[4]);
+	fsp_display_upd_value("PcieRpEnable[5]", 1, original->PcieRpEnable[5],
+		params->PcieRpEnable[5]);
+	fsp_display_upd_value("PcieRpEnable[6]", 1, original->PcieRpEnable[6],
+		params->PcieRpEnable[6]);
+	fsp_display_upd_value("PcieRpEnable[7]", 1, original->PcieRpEnable[7],
+		params->PcieRpEnable[7]);
+	fsp_display_upd_value("PcieRpEnable[8]", 1, original->PcieRpEnable[8],
+		params->PcieRpEnable[8]);
+	fsp_display_upd_value("PcieRpEnable[9]", 1, original->PcieRpEnable[9],
+		params->PcieRpEnable[9]);
+	fsp_display_upd_value("PcieRpEnable[10]", 1, original->PcieRpEnable[10],
+		params->PcieRpEnable[10]);
+	fsp_display_upd_value("PcieRpEnable[11]", 1, original->PcieRpEnable[11],
+		params->PcieRpEnable[11]);
+	fsp_display_upd_value("PcieRpEnable[12]", 1, original->PcieRpEnable[12],
+		params->PcieRpEnable[12]);
+	fsp_display_upd_value("PcieRpEnable[13]", 1, original->PcieRpEnable[13],
+		params->PcieRpEnable[13]);
+	fsp_display_upd_value("PcieRpEnable[14]", 1, original->PcieRpEnable[14],
+		params->PcieRpEnable[14]);
+	fsp_display_upd_value("PcieRpEnable[15]", 1, original->PcieRpEnable[15],
+		params->PcieRpEnable[15]);
+	fsp_display_upd_value("PcieRpEnable[16]", 1, original->PcieRpEnable[16],
+		params->PcieRpEnable[16]);
+	fsp_display_upd_value("PcieRpEnable[17]", 1, original->PcieRpEnable[17],
+		params->PcieRpEnable[17]);
+	fsp_display_upd_value("PcieRpEnable[18]", 1, original->PcieRpEnable[18],
+		params->PcieRpEnable[18]);
+	fsp_display_upd_value("PcieRpEnable[19]", 1, original->PcieRpEnable[19],
+		params->PcieRpEnable[19]);
+	fsp_display_upd_value("PcieRpClkReqSupport[0]", 1,
+		original->PcieRpClkReqSupport[0],
+		params->PcieRpClkReqSupport[0]);
+	fsp_display_upd_value("PcieRpClkReqSupport[1]", 1,
+		original->PcieRpClkReqSupport[1],
+		params->PcieRpClkReqSupport[1]);
+	fsp_display_upd_value("PcieRpClkReqSupport[2]", 1,
+		original->PcieRpClkReqSupport[2],
+		params->PcieRpClkReqSupport[2]);
+	fsp_display_upd_value("PcieRpClkReqSupport[3]", 1,
+		original->PcieRpClkReqSupport[3],
+		params->PcieRpClkReqSupport[3]);
+	fsp_display_upd_value("PcieRpClkReqSupport[4]", 1,
+		original->PcieRpClkReqSupport[4],
+		params->PcieRpClkReqSupport[4]);
+	fsp_display_upd_value("PcieRpClkReqSupport[5]", 1,
+		original->PcieRpClkReqSupport[5],
+		params->PcieRpClkReqSupport[5]);
+	fsp_display_upd_value("PcieRpClkReqSupport[6]", 1,
+		original->PcieRpClkReqSupport[6],
+		params->PcieRpClkReqSupport[6]);
+	fsp_display_upd_value("PcieRpClkReqSupport[7]", 1,
+		original->PcieRpClkReqSupport[7],
+		params->PcieRpClkReqSupport[7]);
+	fsp_display_upd_value("PcieRpClkReqSupport[8]", 1,
+		original->PcieRpClkReqSupport[8],
+		params->PcieRpClkReqSupport[8]);
+	fsp_display_upd_value("PcieRpClkReqSupport[9]", 1,
+		original->PcieRpClkReqSupport[9],
+		params->PcieRpClkReqSupport[9]);
+	fsp_display_upd_value("PcieRpClkReqSupport[10]", 1,
+		original->PcieRpClkReqSupport[10],
+		params->PcieRpClkReqSupport[10]);
+	fsp_display_upd_value("PcieRpClkReqSupport[11]", 1,
+		original->PcieRpClkReqSupport[11],
+		params->PcieRpClkReqSupport[11]);
+	fsp_display_upd_value("PcieRpClkReqSupport[12]", 1,
+		original->PcieRpClkReqSupport[12],
+		params->PcieRpClkReqSupport[12]);
+	fsp_display_upd_value("PcieRpClkReqSupport[13]", 1,
+		original->PcieRpClkReqSupport[13],
+		params->PcieRpClkReqSupport[13]);
+	fsp_display_upd_value("PcieRpClkReqSupport[14]", 1,
+		original->PcieRpClkReqSupport[14],
+		params->PcieRpClkReqSupport[14]);
+	fsp_display_upd_value("PcieRpClkReqSupport[15]", 1,
+		original->PcieRpClkReqSupport[15],
+		params->PcieRpClkReqSupport[15]);
+	fsp_display_upd_value("PcieRpClkReqSupport[16]", 1,
+		original->PcieRpClkReqSupport[16],
+		params->PcieRpClkReqSupport[16]);
+	fsp_display_upd_value("PcieRpClkReqSupport[17]", 1,
+		original->PcieRpClkReqSupport[17],
+		params->PcieRpClkReqSupport[17]);
+	fsp_display_upd_value("PcieRpClkReqSupport[18]", 1,
+		original->PcieRpClkReqSupport[18],
+		params->PcieRpClkReqSupport[18]);
+	fsp_display_upd_value("PcieRpClkReqSupport[19]", 1,
+		original->PcieRpClkReqSupport[19],
+		params->PcieRpClkReqSupport[19]);
+	fsp_display_upd_value("PcieRpClkReqNumber[0]", 1,
+		original->PcieRpClkReqNumber[0],
+		params->PcieRpClkReqNumber[0]);
+	fsp_display_upd_value("PcieRpClkReqNumber[1]", 1,
+		original->PcieRpClkReqNumber[1],
+		params->PcieRpClkReqNumber[1]);
+	fsp_display_upd_value("PcieRpClkReqNumber[2]", 1,
+		original->PcieRpClkReqNumber[2],
+		params->PcieRpClkReqNumber[2]);
+	fsp_display_upd_value("PcieRpClkReqNumber[3]", 1,
+		original->PcieRpClkReqNumber[3],
+		params->PcieRpClkReqNumber[3]);
+	fsp_display_upd_value("PcieRpClkReqNumber[4]", 1,
+		original->PcieRpClkReqNumber[4],
+		params->PcieRpClkReqNumber[4]);
+	fsp_display_upd_value("PcieRpClkReqNumber[5]", 1,
+		original->PcieRpClkReqNumber[5],
+		params->PcieRpClkReqNumber[5]);
+	fsp_display_upd_value("PcieRpClkReqNumber[6]", 1,
+		original->PcieRpClkReqNumber[6],
+		params->PcieRpClkReqNumber[6]);
+	fsp_display_upd_value("PcieRpClkReqNumber[7]", 1,
+		original->PcieRpClkReqNumber[7],
+		params->PcieRpClkReqNumber[7]);
+	fsp_display_upd_value("PcieRpClkReqNumber[8]", 1,
+		original->PcieRpClkReqNumber[8],
+		params->PcieRpClkReqNumber[8]);
+	fsp_display_upd_value("PcieRpClkReqNumber[9]", 1,
+		original->PcieRpClkReqNumber[9],
+		params->PcieRpClkReqNumber[9]);
+	fsp_display_upd_value("PcieRpClkReqNumber[10]", 1,
+		original->PcieRpClkReqNumber[10],
+		params->PcieRpClkReqNumber[10]);
+	fsp_display_upd_value("PcieRpClkReqNumber[11]", 1,
+		original->PcieRpClkReqNumber[11],
+		params->PcieRpClkReqNumber[11]);
+	fsp_display_upd_value("PcieRpClkReqNumber[12]", 1,
+		original->PcieRpClkReqNumber[12],
+		params->PcieRpClkReqNumber[12]);
+	fsp_display_upd_value("PcieRpClkReqNumber[13]", 1,
+		original->PcieRpClkReqNumber[13],
+		params->PcieRpClkReqNumber[13]);
+	fsp_display_upd_value("PcieRpClkReqNumber[14]", 1,
+		original->PcieRpClkReqNumber[14],
+		params->PcieRpClkReqNumber[14]);
+	fsp_display_upd_value("PcieRpClkReqNumber[15]", 1,
+		original->PcieRpClkReqNumber[15],
+		params->PcieRpClkReqNumber[15]);
+	fsp_display_upd_value("PcieRpClkReqNumber[16]", 1,
+		original->PcieRpClkReqNumber[16],
+		params->PcieRpClkReqNumber[16]);
+	fsp_display_upd_value("PcieRpClkReqNumber[17]", 1,
+		original->PcieRpClkReqNumber[17],
+		params->PcieRpClkReqNumber[17]);
+	fsp_display_upd_value("PcieRpClkReqNumber[18]", 1,
+		original->PcieRpClkReqNumber[18],
+		params->PcieRpClkReqNumber[18]);
+	fsp_display_upd_value("PcieRpClkReqNumber[19]", 1,
+		original->PcieRpClkReqNumber[19],
+		params->PcieRpClkReqNumber[19]);
+	fsp_display_upd_value("EnableLan", 1, original->EnableLan,
+		params->EnableLan);
+	fsp_display_upd_value("Cio2Enable", 1, original->Cio2Enable,
+		params->Cio2Enable);
+	fsp_display_upd_value("SataSalpSupport", 1, original->SataSalpSupport,
+		params->SataSalpSupport);
+	fsp_display_upd_value("SataPortsEnable[0]", 1,
+		original->SataPortsEnable[0], params->SataPortsEnable[0]);
+	fsp_display_upd_value("SataPortsEnable[1]", 1,
+		original->SataPortsEnable[1], params->SataPortsEnable[1]);
+	fsp_display_upd_value("SataPortsEnable[2]", 1,
+		original->SataPortsEnable[2], params->SataPortsEnable[2]);
+	fsp_display_upd_value("SataPortsEnable[3]", 1,
+		original->SataPortsEnable[3], params->SataPortsEnable[3]);
+	fsp_display_upd_value("SataPortsEnable[4]", 1,
+		original->SataPortsEnable[4], params->SataPortsEnable[4]);
+	fsp_display_upd_value("SataPortsEnable[5]", 1,
+		original->SataPortsEnable[5], params->SataPortsEnable[5]);
+	fsp_display_upd_value("SataPortsEnable[6]", 1,
+		original->SataPortsEnable[6], params->SataPortsEnable[6]);
+	fsp_display_upd_value("SataPortsEnable[7]", 1,
+		original->SataPortsEnable[7], params->SataPortsEnable[7]);
+	fsp_display_upd_value("SataPortsDevSlp[0]", 1,
+		original->SataPortsDevSlp[0], params->SataPortsDevSlp[0]);
+	fsp_display_upd_value("SataPortsDevSlp[1]", 1,
+		original->SataPortsDevSlp[1], params->SataPortsDevSlp[1]);
+	fsp_display_upd_value("SataPortsDevSlp[2]", 1,
+		original->SataPortsDevSlp[2], params->SataPortsDevSlp[2]);
+	fsp_display_upd_value("SataPortsDevSlp[3]", 1,
+		original->SataPortsDevSlp[3], params->SataPortsDevSlp[3]);
+	fsp_display_upd_value("SataPortsDevSlp[4]", 1,
+		original->SataPortsDevSlp[4], params->SataPortsDevSlp[4]);
+	fsp_display_upd_value("SataPortsDevSlp[5]", 1,
+		original->SataPortsDevSlp[5], params->SataPortsDevSlp[5]);
+	fsp_display_upd_value("SataPortsDevSlp[6]", 1,
+		original->SataPortsDevSlp[6], params->SataPortsDevSlp[6]);
+	fsp_display_upd_value("SataPortsDevSlp[7]", 1,
+		original->SataPortsDevSlp[7], params->SataPortsDevSlp[7]);
+	fsp_display_upd_value("EnableAzalia", 1,
+		original->EnableAzalia,	params->EnableAzalia);
+	fsp_display_upd_value("DspEnable", 1, original->DspEnable,
+		params->DspEnable);
+	fsp_display_upd_value("IoBufferOwnership", 1,
+		original->IoBufferOwnership, params->IoBufferOwnership);
+	fsp_display_upd_value("PortUsb20Enable[0]", 1,
+		original->PortUsb20Enable[0], params->PortUsb20Enable[0]);
+	fsp_display_upd_value("PortUsb20Enable[1]", 1,
+		original->PortUsb20Enable[1], params->PortUsb20Enable[1]);
+	fsp_display_upd_value("PortUsb20Enable[2]", 1,
+		original->PortUsb20Enable[2], params->PortUsb20Enable[2]);
+	fsp_display_upd_value("PortUsb20Enable[3]", 1,
+		original->PortUsb20Enable[3], params->PortUsb20Enable[3]);
+	fsp_display_upd_value("PortUsb20Enable[4]", 1,
+		original->PortUsb20Enable[4], params->PortUsb20Enable[4]);
+	fsp_display_upd_value("PortUsb20Enable[5]", 1,
+		original->PortUsb20Enable[5], params->PortUsb20Enable[5]);
+	fsp_display_upd_value("PortUsb20Enable[6]", 1,
+		original->PortUsb20Enable[6], params->PortUsb20Enable[6]);
+	fsp_display_upd_value("PortUsb20Enable[7]", 1,
+		original->PortUsb20Enable[7], params->PortUsb20Enable[7]);
+	fsp_display_upd_value("PortUsb20Enable[8]", 1,
+		original->PortUsb20Enable[8], params->PortUsb20Enable[8]);
+	fsp_display_upd_value("PortUsb20Enable[9]", 1,
+		original->PortUsb20Enable[9], params->PortUsb20Enable[9]);
+	fsp_display_upd_value("PortUsb20Enable[10]", 1,
+		original->PortUsb20Enable[10], params->PortUsb20Enable[10]);
+	fsp_display_upd_value("PortUsb20Enable[11]", 1,
+		original->PortUsb20Enable[11], params->PortUsb20Enable[11]);
+	fsp_display_upd_value("PortUsb20Enable[12]", 1,
+		original->PortUsb20Enable[12], params->PortUsb20Enable[12]);
+	fsp_display_upd_value("PortUsb20Enable[13]", 1,
+		original->PortUsb20Enable[13], params->PortUsb20Enable[13]);
+	fsp_display_upd_value("PortUsb20Enable[14]", 1,
+		original->PortUsb20Enable[14], params->PortUsb20Enable[14]);
+	fsp_display_upd_value("PortUsb20Enable[15]", 1,
+		original->PortUsb20Enable[15], params->PortUsb20Enable[15]);
+	fsp_display_upd_value("PortUsb30Enable[0]", 1,
+		original->PortUsb30Enable[0], params->PortUsb30Enable[0]);
+	fsp_display_upd_value("PortUsb30Enable[1]", 1,
+		original->PortUsb30Enable[1], params->PortUsb30Enable[1]);
+	fsp_display_upd_value("PortUsb30Enable[2]", 1,
+		original->PortUsb30Enable[2], params->PortUsb30Enable[2]);
+	fsp_display_upd_value("PortUsb30Enable[3]", 1,
+		original->PortUsb30Enable[3], params->PortUsb30Enable[3]);
+	fsp_display_upd_value("PortUsb30Enable[4]", 1,
+		original->PortUsb30Enable[4], params->PortUsb30Enable[4]);
+	fsp_display_upd_value("PortUsb30Enable[5]", 1,
+		original->PortUsb30Enable[5], params->PortUsb30Enable[5]);
+	fsp_display_upd_value("PortUsb30Enable[6]", 1,
+		original->PortUsb30Enable[6], params->PortUsb30Enable[6]);
+	fsp_display_upd_value("PortUsb30Enable[7]", 1,
+		original->PortUsb30Enable[7], params->PortUsb30Enable[7]);
+	fsp_display_upd_value("PortUsb30Enable[8]", 1,
+		original->PortUsb30Enable[8], params->PortUsb30Enable[8]);
+	fsp_display_upd_value("PortUsb30Enable[9]", 1,
+		original->PortUsb30Enable[9], params->PortUsb30Enable[9]);
+	fsp_display_upd_value("XdciEnable", 1, original->XdciEnable,
+		params->XdciEnable);
+	fsp_display_upd_value("SsicPortEnable", 1, original->SsicPortEnable,
+		params->SsicPortEnable);
+	fsp_display_upd_value("SmbusEnable", 1, original->SmbusEnable,
+		params->SmbusEnable);
+	fsp_display_upd_value("SerialIoDevMode[0]", 1,
+		original->SerialIoDevMode[0], params->SerialIoDevMode[0]);
+	fsp_display_upd_value("SerialIoDevMode[1]", 1,
+		original->SerialIoDevMode[1], params->SerialIoDevMode[1]);
+	fsp_display_upd_value("SerialIoDevMode[2]", 1,
+		original->SerialIoDevMode[2], params->SerialIoDevMode[2]);
+	fsp_display_upd_value("SerialIoDevMode[3]", 1,
+		original->SerialIoDevMode[3], params->SerialIoDevMode[3]);
+	fsp_display_upd_value("SerialIoDevMode[4]", 1,
+		original->SerialIoDevMode[4], params->SerialIoDevMode[4]);
+	fsp_display_upd_value("SerialIoDevMode[5]", 1,
+		original->SerialIoDevMode[5], params->SerialIoDevMode[5]);
+	fsp_display_upd_value("SerialIoDevMode[6]", 1,
+		original->SerialIoDevMode[6], params->SerialIoDevMode[6]);
+	fsp_display_upd_value("SerialIoDevMode[7]", 1,
+		original->SerialIoDevMode[7], params->SerialIoDevMode[7]);
+	fsp_display_upd_value("SerialIoDevMode[8]", 1,
+		original->SerialIoDevMode[8], params->SerialIoDevMode[8]);
+	fsp_display_upd_value("SerialIoDevMode[9]", 1,
+		original->SerialIoDevMode[9], params->SerialIoDevMode[9]);
+	fsp_display_upd_value("SerialIoDevMode[10]", 1,
+		original->SerialIoDevMode[10], params->SerialIoDevMode[10]);
+	fsp_display_upd_value("ScsEmmcEnabled", 1, original->ScsEmmcEnabled,
+		params->ScsEmmcEnabled);
+	fsp_display_upd_value("ScsEmmcHs400Enabled", 1,
+		original->ScsEmmcHs400Enabled, params->ScsEmmcHs400Enabled);
+	fsp_display_upd_value("ScsSdCardEnabled", 1, original->ScsSdCardEnabled,
+		params->ScsSdCardEnabled);
+	fsp_display_upd_value("IshEnable", 1, original->IshEnable,
+		params->IshEnable);
+	fsp_display_upd_value("ShowSpiController", 1,
+		original->ShowSpiController, params->ShowSpiController);
+	fsp_display_upd_value("HsioMessaging", 1, original->HsioMessaging,
+		params->HsioMessaging);
+	fsp_display_upd_value("Heci3Enabled", 1, original->Heci3Enabled,
+		params->Heci3Enabled);
+	fsp_display_upd_value("EnableSata", 1, original->EnableSata,
+		params->EnableSata);
+	fsp_display_upd_value("SataMode", 1, original->SataMode,
+		params->SataMode);
+	fsp_display_upd_value("NumOfDevIntConfig", 1,
+		original->NumOfDevIntConfig,
+		params->NumOfDevIntConfig);
+	fsp_display_upd_value("PxRcConfig[PARC]", 1,
+		original->PxRcConfig[PCH_PARC],
+		params->PxRcConfig[PCH_PARC]);
+	fsp_display_upd_value("PxRcConfig[PBRC]", 1,
+		original->PxRcConfig[PCH_PBRC],
+		params->PxRcConfig[PCH_PBRC]);
+	fsp_display_upd_value("PxRcConfig[PCRC]", 1,
+		original->PxRcConfig[PCH_PCRC],
+		params->PxRcConfig[PCH_PCRC]);
+	fsp_display_upd_value("PxRcConfig[PDRC]", 1,
+		original->PxRcConfig[PCH_PDRC],
+		params->PxRcConfig[PCH_PDRC]);
+	fsp_display_upd_value("PxRcConfig[PERC]", 1,
+		original->PxRcConfig[PCH_PERC],
+		params->PxRcConfig[PCH_PERC]);
+	fsp_display_upd_value("PxRcConfig[PFRC]", 1,
+		original->PxRcConfig[PCH_PFRC],
+		params->PxRcConfig[PCH_PFRC]);
+	fsp_display_upd_value("PxRcConfig[PGRC]", 1,
+		original->PxRcConfig[PCH_PGRC],
+		params->PxRcConfig[PCH_PGRC]);
+	fsp_display_upd_value("PxRcConfig[PHRC]", 1,
+		original->PxRcConfig[PCH_PHRC],
+		params->PxRcConfig[PCH_PHRC]);
+	fsp_display_upd_value("GpioIrqRoute", 1,
+		original->GpioIrqRoute,
+		params->GpioIrqRoute);
+	fsp_display_upd_value("SciIrqSelect", 1,
+		original->SciIrqSelect,
+		params->SciIrqSelect);
+	fsp_display_upd_value("TcoIrqSelect", 1,
+		original->TcoIrqSelect,
+		params->TcoIrqSelect);
+	fsp_display_upd_value("TcoIrqEnable", 1,
+		original->TcoIrqEnable,
+		params->TcoIrqEnable);
+	fsp_display_upd_value("LockDownConfigGlobalSmi", 1,
+		original->LockDownConfigGlobalSmi,
+		params->LockDownConfigGlobalSmi);
+	fsp_display_upd_value("LockDownConfigBiosInterface", 1,
+		original->LockDownConfigBiosInterface,
+		params->LockDownConfigBiosInterface);
+	fsp_display_upd_value("LockDownConfigRtcLock", 1,
+		original->LockDownConfigRtcLock,
+		params->LockDownConfigRtcLock);
+	fsp_display_upd_value("LockDownConfigBiosLock", 1,
+		original->LockDownConfigBiosLock,
+		params->LockDownConfigBiosLock);
+	fsp_display_upd_value("LockDownConfigSpiEiss", 1,
+		original->LockDownConfigSpiEiss,
+		params->LockDownConfigSpiEiss);
+	fsp_display_upd_value("PchConfigSubSystemVendorId", 1,
+		original->PchConfigSubSystemVendorId,
+		params->PchConfigSubSystemVendorId);
+	fsp_display_upd_value("PchConfigSubSystemId", 1,
+		original->PchConfigSubSystemId,
+		params->PchConfigSubSystemId);
+	fsp_display_upd_value("WakeConfigWolEnableOverride", 1,
+		original->WakeConfigWolEnableOverride,
+		params->WakeConfigWolEnableOverride);
+	fsp_display_upd_value("WakeConfigPcieWakeFromDeepSx", 1,
+		original->WakeConfigPcieWakeFromDeepSx,
+		params->WakeConfigPcieWakeFromDeepSx);
+	fsp_display_upd_value("PmConfigDeepSxPol", 1,
+		original->PmConfigDeepSxPol,
+		params->PmConfigDeepSxPol);
+	fsp_display_upd_value("PmConfigSlpS3MinAssert", 1,
+		original->PmConfigSlpS3MinAssert,
+		params->PmConfigSlpS3MinAssert);
+	fsp_display_upd_value("PmConfigSlpS4MinAssert", 1,
+		original->PmConfigSlpS4MinAssert,
+		params->PmConfigSlpS4MinAssert);
+	fsp_display_upd_value("PmConfigSlpSusMinAssert", 1,
+		original->PmConfigSlpSusMinAssert,
+		params->PmConfigSlpSusMinAssert);
+	fsp_display_upd_value("PmConfigSlpAMinAssert", 1,
+		original->PmConfigSlpAMinAssert,
+		params->PmConfigSlpAMinAssert);
+	fsp_display_upd_value("PmConfigPciClockRun", 1,
+		original->PmConfigPciClockRun,
+		params->PmConfigPciClockRun);
+	fsp_display_upd_value("PmConfigSlpStrchSusUp", 1,
+		original->PmConfigSlpStrchSusUp,
+		params->PmConfigSlpStrchSusUp);
+	fsp_display_upd_value("PmConfigPwrBtnOverridePeriod", 1,
+		original->PmConfigPwrBtnOverridePeriod,
+		params->PmConfigPwrBtnOverridePeriod);
+	fsp_display_upd_value("PmConfigPwrCycDur", 1,
+		original->PmConfigPwrCycDur,
+		params->PmConfigPwrCycDur);
+	fsp_display_upd_value("SerialIrqConfigSirqEnable", 1,
+		original->SerialIrqConfigSirqEnable,
+		params->SerialIrqConfigSirqEnable);
+	fsp_display_upd_value("SerialIrqConfigSirqMode", 1,
+		original->SerialIrqConfigSirqMode,
+		params->SerialIrqConfigSirqMode);
+	fsp_display_upd_value("SerialIrqConfigStartFramePulse", 1,
+		original->SerialIrqConfigStartFramePulse,
+		params->SerialIrqConfigStartFramePulse);
+
+	fsp_display_upd_value("Psi1Threshold[0]", 1,
+		original->Psi1Threshold[0],
+		params->Psi1Threshold[0]);
+	fsp_display_upd_value("Psi1Threshold[1]", 1,
+		original->Psi1Threshold[1],
+		params->Psi1Threshold[1]);
+	fsp_display_upd_value("Psi1Threshold[2]", 1,
+		original->Psi1Threshold[2],
+		params->Psi1Threshold[2]);
+	fsp_display_upd_value("Psi1Threshold[3]", 1,
+		original->Psi1Threshold[3],
+		params->Psi1Threshold[3]);
+	fsp_display_upd_value("Psi1Threshold[4]", 1,
+		original->Psi1Threshold[4],
+		params->Psi1Threshold[4]);
+	fsp_display_upd_value("Psi2Threshold[0]", 1,
+		original->Psi2Threshold[0],
+		params->Psi2Threshold[0]);
+	fsp_display_upd_value("Psi2Threshold[1]", 1,
+		original->Psi2Threshold[1],
+		params->Psi2Threshold[1]);
+	fsp_display_upd_value("Psi2Threshold[2]", 1,
+		original->Psi2Threshold[2],
+		params->Psi2Threshold[2]);
+	fsp_display_upd_value("Psi2Threshold[3]", 1,
+		original->Psi2Threshold[3],
+		params->Psi2Threshold[3]);
+	fsp_display_upd_value("Psi2Threshold[4]", 1,
+		original->Psi2Threshold[4],
+		params->Psi2Threshold[4]);
+	fsp_display_upd_value("Psi3Threshold[0]", 1,
+		original->Psi3Threshold[0],
+		params->Psi3Threshold[0]);
+	fsp_display_upd_value("Psi3Threshold[1]", 1,
+		original->Psi3Threshold[1],
+		params->Psi3Threshold[1]);
+	fsp_display_upd_value("Psi3Threshold[2]", 1,
+		original->Psi3Threshold[2],
+		params->Psi3Threshold[2]);
+	fsp_display_upd_value("Psi3Threshold[3]", 1,
+		original->Psi3Threshold[3],
+		params->Psi3Threshold[3]);
+	fsp_display_upd_value("Psi3Threshold[4]", 1,
+		original->Psi3Threshold[4],
+		params->Psi3Threshold[4]);
+	fsp_display_upd_value("Psi3Enable[0]", 1,
+		original->Psi3Enable[0],
+		params->Psi3Enable[0]);
+	fsp_display_upd_value("Psi3Enable[1]", 1,
+		original->Psi3Enable[1],
+		params->Psi3Enable[1]);
+	fsp_display_upd_value("Psi3Enable[2]", 1,
+		original->Psi3Enable[2],
+		params->Psi3Enable[2]);
+	fsp_display_upd_value("Psi3Enable[3]", 1,
+		original->Psi3Enable[3],
+		params->Psi3Enable[3]);
+	fsp_display_upd_value("Psi3Enable[4]", 1,
+		original->Psi3Enable[4],
+		params->Psi3Enable[4]);
+	fsp_display_upd_value("Psi4Enable[0]", 1,
+		original->Psi4Enable[0],
+		params->Psi4Enable[0]);
+	fsp_display_upd_value("Psi4Enable[1]", 1,
+		original->Psi4Enable[1],
+		params->Psi4Enable[1]);
+	fsp_display_upd_value("Psi4Enable[2]", 1,
+		original->Psi4Enable[2],
+		params->Psi4Enable[2]);
+	fsp_display_upd_value("Psi4Enable[3]", 1,
+		original->Psi4Enable[3],
+		params->Psi4Enable[3]);
+	fsp_display_upd_value("Psi4Enable[4]", 1,
+		original->Psi4Enable[4],
+		params->Psi4Enable[4]);
+	fsp_display_upd_value("ImonSlope[0]", 1,
+		original->ImonSlope[0],
+		params->ImonSlope[0]);
+	fsp_display_upd_value("ImonSlope[1]", 1,
+		original->ImonSlope[1],
+		params->ImonSlope[1]);
+	fsp_display_upd_value("ImonSlope[2]", 1,
+		original->ImonSlope[2],
+		params->ImonSlope[2]);
+	fsp_display_upd_value("ImonSlope[3]", 1,
+		original->ImonSlope[3],
+		params->ImonSlope[3]);
+	fsp_display_upd_value("ImonSlope[4]", 1,
+		original->ImonSlope[4],
+		params->ImonSlope[4]);
+	fsp_display_upd_value("ImonOffse[0]t", 1,
+		original->ImonOffset[0],
+		params->ImonOffset[0]);
+	fsp_display_upd_value("ImonOffse[1]t", 1,
+		original->ImonOffset[1],
+		params->ImonOffset[1]);
+	fsp_display_upd_value("ImonOffse[2]t", 1,
+		original->ImonOffset[2],
+		params->ImonOffset[2]);
+	fsp_display_upd_value("ImonOffse[3]t", 1,
+		original->ImonOffset[3],
+		params->ImonOffset[3]);
+	fsp_display_upd_value("ImonOffse[4]t", 1,
+		original->ImonOffset[4],
+		params->ImonOffset[4]);
+	fsp_display_upd_value("IccMax[0]", 1,
+		original->IccMax[0],
+		params->IccMax[0]);
+	fsp_display_upd_value("IccMax[1]", 1,
+		original->IccMax[1],
+		params->IccMax[1]);
+	fsp_display_upd_value("IccMax[2]", 1,
+		original->IccMax[2],
+		params->IccMax[2]);
+	fsp_display_upd_value("IccMax[3]", 1,
+		original->IccMax[3],
+		params->IccMax[3]);
+	fsp_display_upd_value("IccMax[4]", 1,
+		original->IccMax[4],
+		params->IccMax[4]);
+	fsp_display_upd_value("VrVoltageLimit[0]", 1,
+		original->VrVoltageLimit[0],
+		params->VrVoltageLimit[0]);
+	fsp_display_upd_value("VrVoltageLimit[1]", 1,
+		original->VrVoltageLimit[1],
+		params->VrVoltageLimit[1]);
+	fsp_display_upd_value("VrVoltageLimit[2]", 1,
+		original->VrVoltageLimit[2],
+		params->VrVoltageLimit[2]);
+	fsp_display_upd_value("VrVoltageLimit[3]", 1,
+		original->VrVoltageLimit[3],
+		params->VrVoltageLimit[3]);
+	fsp_display_upd_value("VrVoltageLimit[4]", 1,
+		original->VrVoltageLimit[4],
+		params->VrVoltageLimit[4]);
+	fsp_display_upd_value("VrConfigEnable[0]", 1,
+		original->VrConfigEnable[0],
+		params->VrConfigEnable[0]);
+	fsp_display_upd_value("VrConfigEnable[1]", 1,
+		original->VrConfigEnable[1],
+		params->VrConfigEnable[1]);
+	fsp_display_upd_value("VrConfigEnable[2]", 1,
+		original->VrConfigEnable[2],
+		params->VrConfigEnable[2]);
+	fsp_display_upd_value("VrConfigEnable[3]", 1,
+		original->VrConfigEnable[3],
+		params->VrConfigEnable[3]);
+	fsp_display_upd_value("VrConfigEnable[4]", 1,
+		original->VrConfigEnable[4],
+		params->VrConfigEnable[4]);
+	fsp_display_upd_value("SerialIoI2cVoltage[0]", 1,
+		original->SerialIoI2cVoltage[0],
+		params->SerialIoI2cVoltage[0]);
+	fsp_display_upd_value("SerialIoI2cVoltage[1]", 1,
+		original->SerialIoI2cVoltage[1],
+		params->SerialIoI2cVoltage[1]);
+	fsp_display_upd_value("SerialIoI2cVoltage[2]", 1,
+		original->SerialIoI2cVoltage[2],
+		params->SerialIoI2cVoltage[2]);
+	fsp_display_upd_value("SerialIoI2cVoltage[3]", 1,
+		original->SerialIoI2cVoltage[3],
+		params->SerialIoI2cVoltage[3]);
+	fsp_display_upd_value("SerialIoI2cVoltage[4]", 1,
+		original->SerialIoI2cVoltage[4],
+		params->SerialIoI2cVoltage[4]);
+	fsp_display_upd_value("SerialIoI2cVoltage[5]", 1,
+		original->SerialIoI2cVoltage[5],
+		params->SerialIoI2cVoltage[5]);
+	fsp_display_upd_value("SendVrMbxCmd", 1,
+		original->SendVrMbxCmd,
+		params->SendVrMbxCmd);
+}
+
+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 << 16) | vendor);
+}
+
+struct pci_operations soc_pci_ops = {
+	.set_subsystem = &pci_set_subsystem
+};
diff --git a/src/soc/intel/kabylake/chip.h b/src/soc/intel/kabylake/chip.h
new file mode 100644
index 0000000..c1b8a9c
--- /dev/null
+++ b/src/soc/intel/kabylake/chip.h
@@ -0,0 +1,386 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2008 coresystems GmbH
+ * Copyright (C) 2014 Google Inc.
+ * 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 _SOC_CHIP_H_
+#define _SOC_CHIP_H_
+
+#include <arch/acpi_device.h>
+#include <device/i2c.h>
+#include <stdint.h>
+#include <soc/gpio_defs.h>
+#include <soc/gpe.h>
+#include <soc/intel/common/lpss_i2c.h>
+#include <soc/pci_devs.h>
+#include <soc/pmc.h>
+#include <soc/serialio.h>
+#include <soc/usb.h>
+#include <soc/vr_config.h>
+
+#define KABYLAKE_I2C_DEV_MAX 6
+
+enum kabylake_i2c_voltage {
+	I2C_VOLTAGE_3V3,
+	I2C_VOLTAGE_1V8
+};
+
+struct kabylake_i2c_config {
+	/* Bus voltage level, default is 3.3V */
+	enum kabylake_i2c_voltage voltage;
+	/* Bus speed in Hz, default is I2C_SPEED_FAST (400 KHz) */
+	enum i2c_speed speed;
+	/* Bus should be enabled prior to ramstage with temporary base */
+	int early_init;
+	/* Custom bus speed configuration { scl_lcnt, scl_hcnt, sda_hold } */
+	struct lpss_i2c_speed_config speed_config[LPSS_I2C_SPEED_CONFIG_COUNT];
+};
+
+struct soc_intel_kabylake_config {
+	/*
+	 * Interrupt Routing configuration
+	 * If bit7 is 1, the interrupt is disabled.
+	 */
+	uint8_t pirqa_routing;
+	uint8_t pirqb_routing;
+	uint8_t pirqc_routing;
+	uint8_t pirqd_routing;
+	uint8_t pirqe_routing;
+	uint8_t pirqf_routing;
+	uint8_t pirqg_routing;
+	uint8_t pirqh_routing;
+
+	/* GPE configuration */
+	uint32_t gpe0_en_1; /* GPE0_EN_31_0 */
+	uint32_t gpe0_en_2; /* GPE0_EN_63_32 */
+	uint32_t gpe0_en_3; /* GPE0_EN_95_64 */
+	uint32_t gpe0_en_4; /* GPE0_EN_127_96 / GPE_STD */
+	/* Gpio group routed to each dword of the GPE0 block. Values are
+	 * of the form GPP_[A:G] or GPD. */
+	uint8_t gpe0_dw0; /* GPE0_31_0 STS/EN */
+	uint8_t gpe0_dw1; /* GPE0_63_32 STS/EN */
+	uint8_t gpe0_dw2; /* GPE0_95_64 STS/EN */
+
+	/* Generic IO decode ranges */
+	uint32_t gen1_dec;
+	uint32_t gen2_dec;
+	uint32_t gen3_dec;
+	uint32_t gen4_dec;
+
+	/* Enable S0iX support */
+	int s0ix_enable;
+
+	/* Enable DPTF support */
+	int dptf_enable;
+
+	/* Deep SX enable for both AC and DC */
+	int deep_s3_enable;
+	int deep_s5_enable;
+
+	/*
+	 * Deep Sx Configuration
+	 *  DSX_EN_WAKE_PIN       - Enable WAKE# pin
+	 *  DSX_EN_LAN_WAKE_PIN   - Enable LAN_WAKE# pin
+	 *  DSX_EN_AC_PRESENT_PIN - Enable AC_PRESENT pin
+	 */
+	uint32_t deep_sx_config;
+
+	/* TCC activation offset */
+	int tcc_offset;
+
+	/*
+	 * The following fields come from FspUpdVpd.h.
+	 * These are configuration values that are passed to FSP during
+	 * MemoryInit.
+	 */
+	u64 PlatformMemorySize;
+	u8 SmramMask;
+	u8 MrcFastBoot;
+	u32 TsegSize;
+	u16 MmioSize;
+
+	/*
+	 * DDR Frequency Limit
+	 * 0(Auto), 1067, 1333, 1600, 1867, 2133, 2400
+	 */
+	u16 DdrFreqLimit;
+
+	/* Probeless Trace function */
+	u8 ProbelessTrace;
+
+	/*
+	 * System Agent dynamic frequency configuration
+	 * When enabled memory will be trained at two different frequencies.
+	 * 0 = Disabled
+	 * 1 = FixedLow
+	 * 2 = FixedHigh
+	 * 3 = Enabled
+	*/
+	u8 SaGv;
+
+	/* Enable/disable Rank Margin Tool */
+	u8 Rmt;
+
+	/* Lan */
+	u8 EnableLan;
+
+	/* SATA related */
+	u8 EnableSata;
+	u8 SataMode;
+	u8 SataSalpSupport;
+	u8 SataPortsEnable[8];
+	u8 SataPortsDevSlp[8];
+
+	/* Audio related */
+	u8 EnableAzalia;
+	u8 DspEnable;
+
+	/*
+	 * I/O Buffer Ownership:
+	 * 0: HD-A Link
+	 * 1 Shared, HD-A Link and I2S Port
+	 * 3: I2S Ports
+	 */
+	u8 IoBufferOwnership;
+
+	/* Trace Hub function */
+	u8 EnableTraceHub;
+
+	/* Pcie Root Ports */
+	u8 PcieRpEnable[20];
+	u8 PcieRpClkReqSupport[20];
+	u8 PcieRpClkReqNumber[20];
+
+	/* USB related */
+	struct usb2_port_config usb2_ports[16];
+	struct usb3_port_config usb3_ports[10];
+	u8 XdciEnable;
+	u8 SsicPortEnable;
+
+	/* SMBus */
+	u8 SmbusEnable;
+
+	/*
+	 * SerialIO device mode selection:
+	 *
+	 * Device index:
+	 * PchSerialIoIndexI2C0
+	 * PchSerialIoIndexI2C1
+	 * PchSerialIoIndexI2C2
+	 * PchSerialIoIndexI2C3
+	 * PchSerialIoIndexI2C4
+	 * PchSerialIoIndexI2C5
+	 * PchSerialIoIndexI2C6
+	 * PchSerialIoIndexSpi0
+	 * PchSerialIoIndexSpi1
+	 * PchSerialIoIndexUart0
+	 * PchSerialIoIndexUart1
+	 * PchSerialIoIndexUart2
+	 *
+	 * Mode select:
+	 * PchSerialIoDisabled
+	 * PchSerialIoAcpi
+	 * PchSerialIoPci
+	 * PchSerialIoAcpiHidden
+	 * PchSerialIoLegacyUart
+	 */
+	u8 SerialIoDevMode[PchSerialIoIndexMax];
+
+	/* I2C */
+	struct kabylake_i2c_config i2c[KABYLAKE_I2C_DEV_MAX];
+
+	/* Camera */
+	u8 Cio2Enable;
+
+	/* eMMC and SD */
+	u8 ScsEmmcEnabled;
+	u8 ScsEmmcHs400Enabled;
+	u8 ScsSdCardEnabled;
+
+	/* Integrated Sensor */
+	u8 IshEnable;
+
+	u8 PttSwitch;
+	u8 HeciTimeouts;
+	u8 HsioMessaging;
+	u8 Heci3Enabled;
+
+	/* Gfx related */
+	u8 IgdDvmt50PreAlloc;
+	u8 PrimaryDisplay;
+	u8 InternalGfx;
+	u8 ApertureSize;
+	u8 SkipExtGfxScan;
+	u8 ScanExtGfxForLegacyOpRom;
+
+	/*
+	 * The following fields come from fsp_vpd.h
+	 * These are configuration values that are passed to FSP during
+	 * SiliconInit.
+	 */
+	u32 LogoPtr;
+	u32 LogoSize;
+	u32 GraphicsConfigPtr;
+	u8 Device4Enable;
+	u8 RtcLock;
+	/* GPIO IRQ Route  The valid values is 14 or 15*/
+	u8 GpioIrqSelect;
+	/* SCI IRQ Select  The valid values is 9, 10, 11 and 20 21, 22, 23*/
+	u8 SciIrqSelect;
+	/* TCO IRQ Select  The valid values is 9, 10, 11, 20 21, 22, 23*/
+	u8 TcoIrqSelect;
+	u8 TcoIrqEnable;
+	/* Enable SMI_LOCK bit to prevent writes to the Global SMI Enable bit.*/
+	u8 LockDownConfigGlobalSmi;
+	/*
+	 * Enable BIOS Interface Lock Down bit to prevent writes to the Backup
+	 * Control Register. Top Swap bit and the General Control and Status
+	 * Registers Boot BIOS Straps.
+	 */
+	u8 LockDownConfigBiosInterface;
+	/*
+	 * Enable RTC lower and upper 128 byte Lock bits to lock Bytes 38h-3Fh
+	 * in the upper and and lower 128-byte bank of RTC RAM.
+	 */
+	u8 LockDownConfigRtcLock;
+	/*
+	 * When enabled, the BIOS Region can only be modified from SMM after
+	 * EndOfDxe protocol is installed
+	 */
+	u8 LockDownConfigBiosLock;
+	/*
+	 * Enable InSMM.STS (EISS) in SPI If this bit is set, then WPD must be a
+	 * '1' and InSMM.STS must be '1' also in order to write to BIOS regions of
+	 * SPI Flash. If this bit is clear, then the InSMM.STS is a don't care. The
+	 * BIOS must set the EISS bit while BIOS Guard support is enabled.
+	 */
+	u8 LockDownConfigSpiEiss;
+	/* Subsystem Vendor ID of the PCH devices*/
+	u16 PchConfigSubSystemVendorId;
+	/* Subsystem ID of the PCH devices*/
+	u16 PchConfigSubSystemId;
+	/*
+	 * Corresponds to the "WOL Enable Override" bit in the General PM
+	 * Configuration B (GEN_PMCON_B) register
+	 */
+	u8 WakeConfigWolEnableOverride;
+	/* Determine if enable PCIe to wake from deep Sx*/
+	u8 WakeConfigPcieWakeFromDeepSx;
+	/* Deep Sx Policy. Values 0: PchDeepSxPolDisable,
+	 * 1: PchDpS5BatteryEn, 2: PchDpS5AlwaysEn, 3: PchDpS4S5BatteryEn,
+	 * 4: PchDpS4S5AlwaysEn, 5: PchDpS3S4S5BatteryEn, 6: PchDpS3S4S5AlwaysEn
+	 */
+	u8 PmConfigDeepSxPol;
+	/*
+	 * SLP_S3 Minimum Assertion Width Policy. Values 0: PchSlpS360us,
+	 * 1: PchSlpS31ms, 2: PchSlpS350ms, 3: PchSlpS32s.
+	 */
+	u8 PmConfigSlpS3MinAssert;
+	/*
+	 * SLP_S4 Minimum Assertion Width Policy. Values 0: PchSlpS4PchTime,
+	 * 1: PchSlpS41s, 2: PchSlpS42s, 3: PchSlpS43s, 4: PchSlpS44s.
+	 */
+	u8 PmConfigSlpS4MinAssert;
+	/*
+	 * SLP_SUS Minimum Assertion Width Policy. Values 0: PchSlpSus0ms,
+	 * 1: PchSlpSus500ms, 2: PchSlpSus1s, 3: PchSlpSus4s.
+	 */
+	u8 PmConfigSlpSusMinAssert;
+	/*
+	 * SLP_A Minimum Assertion Width Policy. Values 0: PchSlpA0ms,
+	 * 1: PchSlpA4s, 2: PchSlpA98ms, 3: PchSlpA2s.
+	 */
+	u8 PmConfigSlpAMinAssert;
+	/*
+	 * This member describes whether or not the PCI ClockRun feature of PCH
+	 * should be enabled. Values 0: Disabled, 1: Enabled
+	 */
+	u8 PmConfigPciClockRun;
+	/*
+	 * SLP_X Stretching After SUS Well Power Up. Values 0: Disabled, 1: Enabled
+	 */
+	u8 PmConfigSlpStrchSusUp;
+	/*
+	 * PCH power button override period.
+	 * Values: 0x0 - 4s, 0x1 - 6s, 0x2 - 8s, 0x3 - 10s, 0x4 - 12s, 0x5 - 14s
+	 */
+	u8 PmConfigPwrBtnOverridePeriod;
+	/*
+	 * Reset Power Cycle Duration could be customized in the unit of second.
+	 * PCH HW default is 4 seconds, and range is 1~4 seconds.
+	 * Values: 0x0 - 0s, 0x1 - 1s, 0x2 - 2s, 0x3 - 3s, 0x4 - 4s
+	 */
+	u8 PmConfigPwrCycDur;
+	/* Determines if enable Serial IRQ. Values 0: Disabled, 1: Enabled.*/
+	u8 SerialIrqConfigSirqEnable;
+	/* Serial IRQ Mode Select. Values: 0: PchQuietMode, 1: PchContinuousMode.*/
+	u8 SerialIrqConfigSirqMode;
+	/*
+	 * Start Frame Pulse Width.
+	 * Values: 0: PchSfpw4Clk, 1: PchSfpw6Clk, 2; PchSfpw8Clk.
+	 */
+	u8 SerialIrqConfigStartFramePulse;
+	u8 FspSkipMpInit;
+	/*
+	 * VrConfig Settings for 5 domains
+	 * 0 = System Agent, 1 = IA Core, 2 = Ring,
+	 * 3 = GT unsliced,  4 = GT sliced
+	 */
+	struct vr_config domain_vr_config[NUM_VR_DOMAINS];
+	/*
+	 * HeciEnabled decides the state of Heci1 at end of boot
+	 * Setting to 0 (default) disables Heci1 and hides the device from OS
+	 */
+	u8 HeciEnabled;
+	/* PL2 Override value in Watts */
+	u32 tdp_pl2_override;
+	u8 PmTimerDisabled;
+	/* Intel Speed Shift Technology */
+	u8 speed_shift_enable;
+	/*
+	 * Enable VR specific mailbox command
+	 * 000b - Don't Send any VR command
+	 * 001b - VR command specifically for the MPS IMPV8 VR will be sent
+	 * 010b - VR specific command sent for PS4 exit issue
+	 * 011b - VR specific command sent for both MPS IMPV8 & PS4 exit issue
+	*/
+	u8 SendVrMbxCmd;
+	/* Statically clock gate 8254 PIT. */
+	u8 clock_gate_8254;
+
+	/*
+	 * Use SD card detect GPIO with default config:
+	 * - Edge triggered
+	 * - No internal pull
+	 * - Active both (high + low)
+	 * - Can wake device from D3
+	 * - 100ms debounce timeout
+	 *
+	 * GpioInt (Edge, ActiveBoth, SharedAndWake, PullNone, 10000,
+	 *          "\\_SB.PCI0.GPIO", 0, ResourceConsumer)
+	 *          { sdcard_cd_gpio_default }
+	 */
+	unsigned sdcard_cd_gpio_default;
+
+	/* Use custom SD card detect GPIO configuration */
+	struct acpi_gpio sdcard_cd_gpio;
+};
+
+typedef struct soc_intel_kabylake_config config_t;
+
+extern struct chip_operations soc_ops;
+
+#endif
diff --git a/src/soc/intel/kabylake/cpu.c b/src/soc/intel/kabylake/cpu.c
new file mode 100644
index 0000000..c5687b0
--- /dev/null
+++ b/src/soc/intel/kabylake/cpu.c
@@ -0,0 +1,494 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ * Copyright (C) 2014 Google Inc.
+ * 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 <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <string.h>
+#include <chip.h>
+#include <cpu/cpu.h>
+#include <cpu/x86/mtrr.h>
+#include <cpu/x86/msr.h>
+#include <cpu/x86/lapic.h>
+#include <cpu/x86/mp.h>
+#include <cpu/intel/microcode.h>
+#include <cpu/intel/speedstep.h>
+#include <cpu/intel/turbo.h>
+#include <cpu/x86/cache.h>
+#include <cpu/x86/name.h>
+#include <cpu/x86/smm.h>
+#include <delay.h>
+#include <pc80/mc146818rtc.h>
+#include <soc/cpu.h>
+#include <soc/msr.h>
+#include <soc/pci_devs.h>
+#include <soc/ramstage.h>
+#include <soc/smm.h>
+#include <soc/systemagent.h>
+
+/* Convert time in seconds to POWER_LIMIT_1_TIME MSR value */
+static const u8 power_limit_time_sec_to_msr[] = {
+	[0]   = 0x00,
+	[1]   = 0x0a,
+	[2]   = 0x0b,
+	[3]   = 0x4b,
+	[4]   = 0x0c,
+	[5]   = 0x2c,
+	[6]   = 0x4c,
+	[7]   = 0x6c,
+	[8]   = 0x0d,
+	[10]  = 0x2d,
+	[12]  = 0x4d,
+	[14]  = 0x6d,
+	[16]  = 0x0e,
+	[20]  = 0x2e,
+	[24]  = 0x4e,
+	[28]  = 0x6e,
+	[32]  = 0x0f,
+	[40]  = 0x2f,
+	[48]  = 0x4f,
+	[56]  = 0x6f,
+	[64]  = 0x10,
+	[80]  = 0x30,
+	[96]  = 0x50,
+	[112] = 0x70,
+	[128] = 0x11,
+};
+
+/* Convert POWER_LIMIT_1_TIME MSR value to seconds */
+static const u8 power_limit_time_msr_to_sec[] = {
+	[0x00] = 0,
+	[0x0a] = 1,
+	[0x0b] = 2,
+	[0x4b] = 3,
+	[0x0c] = 4,
+	[0x2c] = 5,
+	[0x4c] = 6,
+	[0x6c] = 7,
+	[0x0d] = 8,
+	[0x2d] = 10,
+	[0x4d] = 12,
+	[0x6d] = 14,
+	[0x0e] = 16,
+	[0x2e] = 20,
+	[0x4e] = 24,
+	[0x6e] = 28,
+	[0x0f] = 32,
+	[0x2f] = 40,
+	[0x4f] = 48,
+	[0x6f] = 56,
+	[0x10] = 64,
+	[0x30] = 80,
+	[0x50] = 96,
+	[0x70] = 112,
+	[0x11] = 128,
+};
+
+int cpu_config_tdp_levels(void)
+{
+	msr_t platform_info;
+
+	/* Bits 34:33 indicate how many levels supported */
+	platform_info = rdmsr(MSR_PLATFORM_INFO);
+	return (platform_info.hi >> 1) & 3;
+}
+
+/*
+ * Configure processor power limits if possible
+ * This must be done AFTER set of BIOS_RESET_CPL
+ */
+void set_power_limits(u8 power_limit_1_time)
+{
+	msr_t msr = rdmsr(MSR_PLATFORM_INFO);
+	msr_t limit;
+	unsigned power_unit;
+	unsigned tdp, min_power, max_power, max_time, tdp_pl2;
+	u8 power_limit_1_val;
+	device_t dev = SA_DEV_ROOT;
+	config_t *conf = dev->chip_info;
+
+	if (power_limit_1_time > ARRAY_SIZE(power_limit_time_sec_to_msr))
+		power_limit_1_time = 28;
+
+	if (!(msr.lo & PLATFORM_INFO_SET_TDP))
+		return;
+
+	/* Get units */
+	msr = rdmsr(MSR_PKG_POWER_SKU_UNIT);
+	power_unit = 1 << (msr.lo & 0xf);
+
+	/* Get power defaults for this SKU */
+	msr = rdmsr(MSR_PKG_POWER_SKU);
+	tdp = msr.lo & 0x7fff;
+	min_power = (msr.lo >> 16) & 0x7fff;
+	max_power = msr.hi & 0x7fff;
+	max_time = (msr.hi >> 16) & 0x7f;
+
+	printk(BIOS_DEBUG, "CPU TDP: %u Watts\n", tdp / power_unit);
+
+	if (power_limit_time_msr_to_sec[max_time] > power_limit_1_time)
+		power_limit_1_time = power_limit_time_msr_to_sec[max_time];
+
+	if (min_power > 0 && tdp < min_power)
+		tdp = min_power;
+
+	if (max_power > 0 && tdp > max_power)
+		tdp = max_power;
+
+	power_limit_1_val = power_limit_time_sec_to_msr[power_limit_1_time];
+
+	/* Set long term power limit to TDP */
+	limit.lo = 0;
+	limit.lo |= tdp & PKG_POWER_LIMIT_MASK;
+
+	/* Set PL1 Pkg Power clamp bit */
+	limit.lo |= PKG_POWER_LIMIT_CLAMP;
+
+	limit.lo |= PKG_POWER_LIMIT_EN;
+	limit.lo |= (power_limit_1_val & PKG_POWER_LIMIT_TIME_MASK) <<
+		PKG_POWER_LIMIT_TIME_SHIFT;
+
+	/* Set short term power limit to 1.25 * TDP */
+	limit.hi = 0;
+	tdp_pl2 = (conf->tdp_pl2_override == 0) ?
+		(tdp * 125) / 100 : (conf->tdp_pl2_override * power_unit);
+	limit.hi |= (tdp_pl2) & PKG_POWER_LIMIT_MASK;
+	limit.hi |= PKG_POWER_LIMIT_CLAMP;
+	limit.hi |= PKG_POWER_LIMIT_EN;
+
+	/* Power limit 2 time is only programmable on server SKU */
+	wrmsr(MSR_PKG_POWER_LIMIT, limit);
+
+	/* Set PL2 power limit values in MCHBAR and disable PL1 */
+	MCHBAR32(MCH_PKG_POWER_LIMIT_LO) = limit.lo & (~(PKG_POWER_LIMIT_EN));
+	MCHBAR32(MCH_PKG_POWER_LIMIT_HI) = limit.hi;
+
+	/* Set DDR RAPL power limit by copying from MMIO to MSR */
+	msr.lo = MCHBAR32(MCH_DDR_POWER_LIMIT_LO);
+	msr.hi = MCHBAR32(MCH_DDR_POWER_LIMIT_HI);
+	wrmsr(MSR_DDR_RAPL_LIMIT, msr);
+
+	/* Use nominal TDP values for CPUs with configurable TDP */
+	if (cpu_config_tdp_levels()) {
+		msr = rdmsr(MSR_CONFIG_TDP_NOMINAL);
+		limit.hi = 0;
+		limit.lo = msr.lo & 0xff;
+		wrmsr(MSR_TURBO_ACTIVATION_RATIO, limit);
+	}
+}
+
+static void configure_thermal_target(void)
+{
+	device_t dev = SA_DEV_ROOT;
+	config_t *conf = dev->chip_info;
+	msr_t msr;
+
+	/* Set TCC activaiton offset if supported */
+	msr = rdmsr(MSR_PLATFORM_INFO);
+	if ((msr.lo & (1 << 30)) && conf->tcc_offset) {
+		msr = rdmsr(MSR_TEMPERATURE_TARGET);
+		msr.lo &= ~(0xf << 24); /* Bits 27:24 */
+		msr.lo |= (conf->tcc_offset & 0xf) << 24;
+		wrmsr(MSR_TEMPERATURE_TARGET, msr);
+	}
+}
+
+static void configure_isst(void)
+{
+	device_t dev = SA_DEV_ROOT;
+	config_t *conf = dev->chip_info;
+	msr_t msr;
+
+	if (conf->speed_shift_enable) {
+		/*
+		* Kernel driver checks CPUID.06h:EAX[Bit 7] to determine if HWP
+		  is supported or not. Coreboot needs to configure MSR 0x1AA
+		  which is then reflected in the CPUID register.
+		*/
+		msr = rdmsr(MSR_MISC_PWR_MGMT);
+		msr.lo |= MISC_PWR_MGMT_ISST_EN; /* Enable Speed Shift */
+		msr.lo |= MISC_PWR_MGMT_ISST_EN_INT; /* Enable Interrupt */
+		msr.lo |= MISC_PWR_MGMT_ISST_EN_EPP; /* Enable EPP */
+		wrmsr(MSR_MISC_PWR_MGMT, msr);
+	} else {
+		msr = rdmsr(MSR_MISC_PWR_MGMT);
+		msr.lo &= ~MISC_PWR_MGMT_ISST_EN; /* Disable Speed Shift */
+		msr.lo &= ~MISC_PWR_MGMT_ISST_EN_INT; /* Disable Interrupt */
+		msr.lo &= ~MISC_PWR_MGMT_ISST_EN_EPP; /* Disable EPP */
+		wrmsr(MSR_MISC_PWR_MGMT, msr);
+	}
+}
+
+static void configure_misc(void)
+{
+	msr_t msr;
+
+	msr = rdmsr(IA32_MISC_ENABLE);
+	msr.lo |= (1 << 0);	/* Fast String enable */
+	msr.lo |= (1 << 3);	/* TM1/TM2/EMTTM enable */
+	msr.lo |= (1 << 16);	/* Enhanced SpeedStep Enable */
+	wrmsr(IA32_MISC_ENABLE, msr);
+
+	/* Disable Thermal interrupts */
+	msr.lo = 0;
+	msr.hi = 0;
+	wrmsr(IA32_THERM_INTERRUPT, msr);
+
+	/* Enable package critical interrupt only */
+	msr.lo = 1 << 4;
+	msr.hi = 0;
+	wrmsr(IA32_PACKAGE_THERM_INTERRUPT, msr);
+
+	/* Enable PROCHOT */
+	msr = rdmsr(MSR_POWER_CTL);
+	msr.lo |= (1 << 0);	/* Enable Bi-directional PROCHOT as an input*/
+	msr.lo |= (1 << 23);	/* Lock it */
+	wrmsr(MSR_POWER_CTL, msr);
+}
+
+static void enable_lapic_tpr(void)
+{
+	msr_t msr;
+
+	msr = rdmsr(MSR_PIC_MSG_CONTROL);
+	msr.lo &= ~(1 << 10);	/* Enable APIC TPR updates */
+	wrmsr(MSR_PIC_MSG_CONTROL, msr);
+}
+
+static void configure_dca_cap(void)
+{
+	struct cpuid_result cpuid_regs;
+	msr_t msr;
+
+	/* Check feature flag in CPUID.(EAX=1):ECX[18]==1 */
+	cpuid_regs = cpuid(1);
+	if (cpuid_regs.ecx & (1 << 18)) {
+		msr = rdmsr(IA32_PLATFORM_DCA_CAP);
+		msr.lo |= 1;
+		wrmsr(IA32_PLATFORM_DCA_CAP, msr);
+	}
+}
+
+static void set_max_ratio(void)
+{
+	msr_t msr, perf_ctl;
+
+	perf_ctl.hi = 0;
+
+	/* Check for configurable TDP option */
+	if (get_turbo_state() == TURBO_ENABLED) {
+		msr = rdmsr(MSR_TURBO_RATIO_LIMIT);
+		perf_ctl.lo = (msr.lo & 0xff) << 8;
+	} else if (cpu_config_tdp_levels()) {
+		/* Set to nominal TDP ratio */
+		msr = rdmsr(MSR_CONFIG_TDP_NOMINAL);
+		perf_ctl.lo = (msr.lo & 0xff) << 8;
+	} else {
+		/* Platform Info bits 15:8 give max ratio */
+		msr = rdmsr(MSR_PLATFORM_INFO);
+		perf_ctl.lo = msr.lo & 0xff00;
+	}
+	wrmsr(IA32_PERF_CTL, perf_ctl);
+
+	printk(BIOS_DEBUG, "cpu: frequency set to %d\n",
+	       ((perf_ctl.lo >> 8) & 0xff) * CPU_BCLK);
+}
+
+static void set_energy_perf_bias(u8 policy)
+{
+	msr_t msr;
+	int ecx;
+
+	/* Determine if energy efficient policy is supported. */
+	ecx = cpuid_ecx(0x6);
+	if (!(ecx & (1 << 3)))
+		return;
+
+	/* Energy Policy is bits 3:0 */
+	msr = rdmsr(IA32_ENERGY_PERFORMANCE_BIAS);
+	msr.lo &= ~0xf;
+	msr.lo |= policy & 0xf;
+	wrmsr(IA32_ENERGY_PERFORMANCE_BIAS, msr);
+
+	printk(BIOS_DEBUG, "cpu: energy policy set to %u\n", policy);
+}
+
+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;
+	msr.lo = msr.hi = 0;
+	/*
+	 * 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.
+	 */
+	for (i = 0; i < num_banks; i++)
+		wrmsr(IA32_MC0_STATUS + (i * 4), msr);
+}
+
+/* All CPUs including BSP will run the following function. */
+static void cpu_core_init(device_t cpu)
+{
+	/* Clear out pending MCEs */
+	configure_mca();
+
+	/* Enable the local cpu apics */
+	enable_lapic_tpr();
+	setup_lapic();
+
+	/* Configure Enhanced SpeedStep and Thermal Sensors */
+	configure_misc();
+
+	/* Configure Intel Speed Shift */
+	configure_isst();
+
+	/* Thermal throttle activation offset */
+	configure_thermal_target();
+
+	/* Enable Direct Cache Access */
+	configure_dca_cap();
+
+	/* Set energy policy */
+	set_energy_perf_bias(ENERGY_POLICY_NORMAL);
+
+	/* Enable Turbo */
+	enable_turbo();
+}
+
+static struct device_operations cpu_dev_ops = {
+	.init = cpu_core_init,
+};
+
+static struct cpu_device_id cpu_table[] = {
+	{ X86_VENDOR_INTEL, CPUID_KABYLAKE_C0 },
+	{ X86_VENDOR_INTEL, CPUID_KABYLAKE_D0 },
+	{ 0, 0 },
+};
+
+static const struct cpu_driver driver __cpu_driver = {
+	.ops      = &cpu_dev_ops,
+	.id_table = cpu_table,
+};
+
+/* MP initialization support. */
+static const void *microcode_patch;
+static int ht_disabled;
+
+static void pre_mp_init(void)
+{
+	/* Setup MTRRs based on physical address size. */
+	x86_setup_mtrrs_with_detect();
+	x86_mtrr_check();
+}
+
+static int get_cpu_count(void)
+{
+	msr_t msr;
+	int num_threads;
+	int num_cores;
+
+	msr = rdmsr(CORE_THREAD_COUNT_MSR);
+	num_threads = (msr.lo >> 0) & 0xffff;
+	num_cores = (msr.lo >> 16) & 0xffff;
+	printk(BIOS_DEBUG, "CPU has %u cores, %u threads enabled.\n",
+	       num_cores, num_threads);
+
+	ht_disabled = num_threads == num_cores;
+
+	return num_threads;
+}
+
+static void get_microcode_info(const void **microcode, int *parallel)
+{
+	microcode_patch = intel_microcode_find();
+	*microcode = microcode_patch;
+	*parallel = 1;
+}
+
+static int adjust_apic_id(int index, int apic_id)
+{
+	if (ht_disabled)
+		return 2 * index;
+	else
+		return index;
+}
+
+static void per_cpu_smm_trigger(void)
+{
+	/* Relocate the SMM handler. */
+	smm_relocate();
+
+	/* After SMM relocation a 2nd microcode load is required. */
+	intel_microcode_load_unlocked(microcode_patch);
+}
+
+static void post_mp_init(void)
+{
+	/* Set Max Ratio */
+	set_max_ratio();
+
+	/*
+	 * Now that all APs have been relocated as well as the BSP let SMIs
+	 * start flowing.
+	 */
+	southbridge_smm_enable_smi();
+
+	/* Lock down the SMRAM space. */
+#if IS_ENABLED(CONFIG_HAVE_SMI_HANDLER)
+	smm_lock();
+#endif
+}
+
+static const struct mp_ops mp_ops = {
+	.pre_mp_init = pre_mp_init,
+	.get_cpu_count = get_cpu_count,
+	.get_smm_info = smm_info,
+	.get_microcode_info = get_microcode_info,
+	.adjust_cpu_apic_entry = adjust_apic_id,
+	.pre_mp_smm_init = smm_initialize,
+	.per_cpu_smm_trigger = per_cpu_smm_trigger,
+	.relocation_handler = smm_relocation_handler,
+	.post_mp_init = post_mp_init,
+};
+
+void soc_init_cpus(device_t dev)
+{
+	struct bus *cpu_bus = dev->link_list;
+
+	if (mp_init_with_smm(cpu_bus, &mp_ops)) {
+		printk(BIOS_ERR, "MP initialization failure.\n");
+	}
+}
+
+int soc_skip_ucode_update(u32 current_patch_id, u32 new_patch_id)
+{
+	msr_t msr;
+	/* If PRMRR/SGX is supported the FIT microcode load will set the msr
+	 * 0x08b with the Patch revision id one less than the id in the
+	 * microcode binary. The PRMRR support is indicated in the MSR
+	 * MTRRCAP[12]. Check for this feature and avoid reloading the
+	 * same microcode during cpu initialization.
+	 */
+	msr = rdmsr(MTRR_CAP_MSR);
+	return (msr.lo & PRMRR_SUPPORTED) && (current_patch_id == new_patch_id - 1);
+}
diff --git a/src/soc/intel/kabylake/cpu_info.c b/src/soc/intel/kabylake/cpu_info.c
new file mode 100644
index 0000000..70b47ea
--- /dev/null
+++ b/src/soc/intel/kabylake/cpu_info.c
@@ -0,0 +1,50 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ * Copyright (C) 2014 Google Inc.
+ * 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 <console/console.h>
+#include <cpu/cpu.h>
+#include <cpu/x86/msr.h>
+#include <soc/cpu.h>
+#include <soc/msr.h>
+#include <soc/ramstage.h>
+#include <soc/systemagent.h>
+
+u32 cpu_family_model(void)
+{
+	return cpuid_eax(1) & 0x0fff0ff0;
+}
+
+u32 cpu_stepping(void)
+{
+	return cpuid_eax(1) & 0xf;
+}
+
+/* Dynamically determine if the part is ULT. */
+int cpu_is_ult(void)
+{
+	static int ult = -1;
+
+	if (ult < 0) {
+		u32 fm = cpu_family_model();
+		if (fm == KABYLAKE_FAMILY_ULT)
+			ult = 1;
+		else
+			ult = 0;
+	}
+
+	return ult;
+}
diff --git a/src/soc/intel/kabylake/dsp.c b/src/soc/intel/kabylake/dsp.c
new file mode 100644
index 0000000..5297900
--- /dev/null
+++ b/src/soc/intel/kabylake/dsp.c
@@ -0,0 +1,33 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2016 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.
+ */
+
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <soc/ramstage.h>
+
+static struct device_operations dsp_dev_ops = {
+	.read_resources		= &pci_dev_read_resources,
+	.set_resources		= &pci_dev_set_resources,
+	.enable_resources	= &pci_dev_enable_resources,
+	.scan_bus		= &scan_static_bus,
+	.ops_pci		= &soc_pci_ops,
+};
+
+static const struct pci_driver kabylake_dsp __pci_driver = {
+	.ops	= &dsp_dev_ops,
+	.vendor	= PCI_VENDOR_ID_INTEL,
+	.device = 0x9d70
+};
diff --git a/src/soc/intel/kabylake/elog.c b/src/soc/intel/kabylake/elog.c
new file mode 100644
index 0000000..18efbeb
--- /dev/null
+++ b/src/soc/intel/kabylake/elog.c
@@ -0,0 +1,125 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * 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 <bootstate.h>
+#include <cbmem.h>
+#include <console/console.h>
+#include <stdint.h>
+#include <elog.h>
+#include <soc/pm.h>
+#include <soc/pmc.h>
+
+static void pch_log_gpio_gpe(u32 gpe0_sts, u32 gpe0_en, int start)
+{
+	int i;
+
+	gpe0_sts &= gpe0_en;
+
+	for (i = 0; i <= 31; i++) {
+		if (gpe0_sts & (1 << i))
+			elog_add_event_wake(ELOG_WAKE_SOURCE_GPIO, i + start);
+	}
+}
+
+static void pch_log_wake_source(struct chipset_power_state *ps)
+{
+	/* Power Button */
+	if (ps->pm1_sts & PWRBTN_STS)
+		elog_add_event_wake(ELOG_WAKE_SOURCE_PWRBTN, 0);
+
+	/* RTC */
+	if (ps->pm1_sts & RTC_STS)
+		elog_add_event_wake(ELOG_WAKE_SOURCE_RTC, 0);
+
+	/* PCI Express (TODO: determine wake device) */
+	if (ps->pm1_sts & PCIEXPWAK_STS)
+		elog_add_event_wake(ELOG_WAKE_SOURCE_PCIE, 0);
+
+	/* PME (TODO: determine wake device) */
+	if (ps->gpe0_sts[GPE_STD] & PME_STS)
+		elog_add_event_wake(ELOG_WAKE_SOURCE_PME, 0);
+
+	/* Internal PME (TODO: determine wake device) */
+	if (ps->gpe0_sts[GPE_STD] & PME_B0_STS)
+		elog_add_event_wake(ELOG_WAKE_SOURCE_PME_INTERNAL, 0);
+
+	/* SMBUS Wake */
+	if (ps->gpe0_sts[GPE_STD] & SMB_WAK_STS)
+		elog_add_event_wake(ELOG_WAKE_SOURCE_SMBUS, 0);
+
+	/* Log GPIO events in set 1-3 */
+	pch_log_gpio_gpe(ps->gpe0_sts[GPE_31_0], ps->gpe0_en[GPE_31_0], 0);
+	pch_log_gpio_gpe(ps->gpe0_sts[GPE_63_32], ps->gpe0_en[GPE_63_32], 32);
+	pch_log_gpio_gpe(ps->gpe0_sts[GPE_95_64], ps->gpe0_en[GPE_95_64], 64);
+	/* Treat the STD as an extension of GPIO to obtain visibility. */
+	pch_log_gpio_gpe(ps->gpe0_sts[GPE_STD], ps->gpe0_en[GPE_STD], 96);
+}
+
+static void pch_log_power_and_resets(struct chipset_power_state *ps)
+{
+	/* Thermal Trip */
+	if (ps->gblrst_cause[0] & GBLRST_CAUSE0_THERMTRIP)
+		elog_add_event(ELOG_TYPE_THERM_TRIP);
+
+	/* PWR_FLR Power Failure */
+	if (ps->gen_pmcon_b & PWR_FLR)
+		elog_add_event(ELOG_TYPE_POWER_FAIL);
+
+	/* SUS Well Power Failure */
+	if (ps->gen_pmcon_b & SUS_PWR_FLR)
+		elog_add_event(ELOG_TYPE_SUS_POWER_FAIL);
+
+	/* TCO Timeout */
+	if (ps->prev_sleep_state != ACPI_S3 &&
+	    ps->tco2_sts & TCO2_STS_SECOND_TO)
+		elog_add_event(ELOG_TYPE_TCO_RESET);
+
+	/* Power Button Override */
+	if (ps->pm1_sts & PRBTNOR_STS)
+		elog_add_event(ELOG_TYPE_POWER_BUTTON_OVERRIDE);
+
+	/* RTC reset */
+	if (ps->gen_pmcon_b & RTC_BATTERY_DEAD)
+		elog_add_event(ELOG_TYPE_RTC_RESET);
+
+	/* Host Reset Status */
+	if (ps->gen_pmcon_b & HOST_RST_STS)
+		elog_add_event(ELOG_TYPE_SYSTEM_RESET);
+
+	/* ACPI Wake Event */
+	if (ps->prev_sleep_state != ACPI_S0)
+		elog_add_event_byte(ELOG_TYPE_ACPI_WAKE, ps->prev_sleep_state);
+}
+
+static void pch_log_state(void *unused)
+{
+	struct chipset_power_state *ps = cbmem_find(CBMEM_ID_POWER_STATE);
+
+	if (ps == NULL) {
+		printk(BIOS_ERR,
+			"Not logging power state information. Power state not found in cbmem.\n");
+		return;
+	}
+
+	/* Power and Reset */
+	pch_log_power_and_resets(ps);
+
+	/* Wake Sources */
+	if (ps->prev_sleep_state > 0)
+		pch_log_wake_source(ps);
+}
+
+BOOT_STATE_INIT_ENTRY(BS_DEV_INIT, BS_ON_ENTRY, pch_log_state, NULL);
diff --git a/src/soc/intel/kabylake/finalize.c b/src/soc/intel/kabylake/finalize.c
new file mode 100644
index 0000000..7713c03
--- /dev/null
+++ b/src/soc/intel/kabylake/finalize.c
@@ -0,0 +1,221 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * 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 <arch/io.h>
+#include <bootstate.h>
+#include <chip.h>
+#include <console/console.h>
+#include <console/post_codes.h>
+#include <cpu/x86/smm.h>
+#include <reg_script.h>
+#include <spi-generic.h>
+#include <stdlib.h>
+#include <soc/lpc.h>
+#include <soc/me.h>
+#include <soc/pci_devs.h>
+#include <soc/pcr.h>
+#include <soc/pm.h>
+#include <soc/pmc.h>
+#include <soc/spi.h>
+#include <soc/systemagent.h>
+#include <device/pci.h>
+#include <chip.h>
+
+#define PCH_P2SB_EPMASK0		0xB0
+#define PCH_P2SB_EPMASK(mask_number) 	PCH_P2SB_EPMASK0 + (mask_number * 4)
+
+#define PCH_P2SB_E0			0xE0
+#define PCH_PWRM_ACPI_TMR_CTL		0xFC
+
+static void pch_configure_endpoints(device_t dev, int epmask_id, uint32_t mask)
+{
+	uint32_t reg32;
+
+	reg32 = pci_read_config32(dev, PCH_P2SB_EPMASK(epmask_id));
+	pci_write_config32(dev, PCH_P2SB_EPMASK(epmask_id), reg32 | mask);
+}
+
+static void pch_disable_heci(void)
+{
+	device_t dev;
+	u8 reg8;
+	uint32_t mask;
+
+	dev = PCH_DEV_P2SB;
+
+	/*
+	 * if p2sb device 1f.1 is not present or hidden in devicetree
+	 * p2sb device becomes NULL
+	 */
+	if (!dev)
+		return;
+
+	/* unhide p2sb device */
+	pci_write_config8(dev, PCH_P2SB_E0 + 1, 0);
+
+	/* disable heci */
+	pcr_andthenor32(PID_PSF1, PSF_BASE_ADDRESS + PCH_PCR_PSFX_T0_SHDW_PCIEN,
+				~0, PCH_PCR_PSFX_T0_SHDW_PCIEN_FUNDIS);
+
+	/* Remove the host accessing right to PSF register range. */
+	/* Set p2sb PCI offset EPMASK5 C4h [29, 28, 27, 26] to [1, 1, 1, 1] */
+	mask = (1 << 29) | (1 << 28) | (1 << 27)  | (1 << 26);
+	pch_configure_endpoints(dev, 5, mask);
+
+	/* Set the "Endpoint Mask Lock!", P2SB PCI offset E2h bit[1] to 1. */
+	reg8 = pci_read_config8(dev, PCH_P2SB_E0 + 2);
+	pci_write_config8(dev, PCH_P2SB_E0 + 2, reg8 | (1 << 1));
+
+	/* hide p2sb device */
+	pci_write_config8(dev, PCH_P2SB_E0 + 1, 1);
+}
+
+static void pch_finalize_script(void)
+{
+	device_t dev;
+	uint32_t reg32, hsfs;
+	void *spibar = get_spi_bar();
+	u16 tcobase;
+	u16 tcocnt;
+	uint8_t *pmcbase;
+	config_t *config;
+	u32 pmsyncreg;
+	u8 reg8;
+
+	/* Set SPI opcode menu */
+	write16(spibar + SPIBAR_PREOP, SPI_OPPREFIX);
+	write16(spibar + SPIBAR_OPTYPE, SPI_OPTYPE);
+	write32(spibar + SPIBAR_OPMENU_LOWER, SPI_OPMENU_LOWER);
+	write32(spibar + SPIBAR_OPMENU_UPPER, SPI_OPMENU_UPPER);
+	/* Lock SPIBAR */
+	hsfs = read32(spibar + SPIBAR_HSFS);
+	hsfs |= SPIBAR_HSFS_FLOCKDN;
+	write32(spibar + SPIBAR_HSFS, hsfs);
+
+	/*TCO Lock down */
+	tcobase = pmc_tco_regs();
+	tcocnt = inw(tcobase + TCO1_CNT);
+	tcocnt |= TCO_LOCK;
+	outw(tcocnt, tcobase + TCO1_CNT);
+
+	/* Lock down ABASE and sleep stretching policy */
+	dev = PCH_DEV_PMC;
+	reg32 = pci_read_config32(dev, GEN_PMCON_B);
+	reg32 |= (SLP_STR_POL_LOCK | ACPI_BASE_LOCK);
+	pci_write_config32(dev, GEN_PMCON_B, reg32);
+
+	/* PMSYNC */
+	pmcbase = pmc_mmio_regs();
+	pmsyncreg = read32(pmcbase + PMSYNC_TPR_CFG);
+	pmsyncreg |= PMSYNC_LOCK;
+	write32(pmcbase + PMSYNC_TPR_CFG, pmsyncreg);
+
+	/* Display me status before we hide it */
+	intel_me_status();
+
+	/* we should disable Heci1 based on the devicetree policy */
+	config = dev->chip_info;
+
+	/*
+	 * Disable ACPI PM timer based on dt policy
+	 *
+	 * Disabling ACPI PM timer is necessary for XTAL OSC shutdown.
+	 * Disabling ACPI PM timer also switches off TCO
+	 */
+
+	if (config->PmTimerDisabled) {
+		reg8 = read8(pmcbase + PCH_PWRM_ACPI_TMR_CTL);
+		reg8 |= (1 << 1);
+		write8(pmcbase + PCH_PWRM_ACPI_TMR_CTL, reg8);
+	}
+
+	/* we should disable Heci1 based on the devicetree policy */
+	if (config->HeciEnabled == 0)
+		pch_disable_heci();
+}
+
+static void soc_lockdown(void)
+{
+	u8 reg8;
+	device_t dev;
+	const struct device *dev1 = dev_find_slot(0, PCH_DEVFN_LPC);
+	const struct soc_intel_kabylake_config *config = dev1->chip_info;
+
+	/* Global SMI Lock */
+	if (config->LockDownConfigGlobalSmi == 0) {
+		dev = PCH_DEV_PMC;
+		reg8 = pci_read_config8(dev, GEN_PMCON_A);
+		reg8 |= SMI_LOCK;
+		pci_write_config8(dev, GEN_PMCON_A, reg8);
+	}
+
+	/* Bios Interface Lock */
+	if (config->LockDownConfigBiosInterface == 0) {
+		pci_write_config8(PCH_DEV_LPC, BIOS_CNTL,
+				  pci_read_config8(PCH_DEV_LPC,
+						   BIOS_CNTL) | LPC_BC_BILD);
+		/* Reads back for posted write to take effect */
+		pci_read_config8(PCH_DEV_LPC, BIOS_CNTL);
+		pci_write_config32(PCH_DEV_SPI, SPIBAR_BIOS_CNTL,
+				   pci_read_config32(PCH_DEV_SPI,
+						     SPIBAR_BIOS_CNTL) |
+				   SPIBAR_BC_BILD);
+		/* Reads back for posted write to take effect */
+		pci_read_config32(PCH_DEV_SPI, SPIBAR_BIOS_CNTL);
+		/* GCS reg of DMI */
+		pcr_andthenor8(PID_DMI, R_PCH_PCR_DMI_GCS, 0xFF,
+			       B_PCH_PCR_DMI_GCS_BILD);
+	}
+
+	/* Bios Lock */
+	if (config->LockDownConfigBiosLock == 0) {
+		pci_write_config8(PCH_DEV_LPC, BIOS_CNTL,
+				  pci_read_config8(PCH_DEV_LPC,
+						   BIOS_CNTL) | LPC_BC_LE);
+		pci_write_config8(PCH_DEV_SPI, BIOS_CNTL,
+				  pci_read_config8(PCH_DEV_SPI,
+						   BIOS_CNTL) | SPIBAR_BC_LE);
+	}
+
+	/* SPIEiss */
+	if (config->LockDownConfigSpiEiss == 0) {
+		pci_write_config8(PCH_DEV_LPC, BIOS_CNTL,
+				  pci_read_config8(PCH_DEV_LPC,
+						   BIOS_CNTL) | LPC_BC_EISS);
+		pci_write_config8(PCH_DEV_SPI, BIOS_CNTL,
+				  pci_read_config8(PCH_DEV_SPI,
+						   SPIBAR_BIOS_CNTL) |
+				  SPIBAR_BC_EISS);
+	}
+}
+
+static void soc_finalize(void *unused)
+{
+	printk(BIOS_DEBUG, "Finalizing chipset.\n");
+
+	pch_finalize_script();
+
+	soc_lockdown();
+
+	printk(BIOS_DEBUG, "Finalizing SMM.\n");
+	outb(APM_CNT_FINALIZE, APM_CNT);
+
+	/* Indicate finalize step with post code */
+	post_code(POST_OS_BOOT);
+}
+
+BOOT_STATE_INIT_ENTRY(BS_OS_RESUME, BS_ON_ENTRY, soc_finalize, NULL);
+BOOT_STATE_INIT_ENTRY(BS_PAYLOAD_LOAD, BS_ON_EXIT, soc_finalize, NULL);
diff --git a/src/soc/intel/kabylake/flash_controller.c b/src/soc/intel/kabylake/flash_controller.c
new file mode 100644
index 0000000..388c31a
--- /dev/null
+++ b/src/soc/intel/kabylake/flash_controller.c
@@ -0,0 +1,437 @@
+/*
+ * Copyright (C) 2014 Google Inc.
+ * 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.
+ */
+
+/* This file is derived from the flashrom project. */
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <bootstate.h>
+#include <spi_flash.h>
+#include <timer.h>
+#include <soc/flash_controller.h>
+#include <soc/pci_devs.h>
+#include <soc/spi.h>
+
+static inline uint16_t spi_read_hsfs(pch_spi_regs * const regs)
+{
+	return readw_(&regs->hsfs);
+}
+
+static inline void spi_clear_status(pch_spi_regs * const regs)
+{
+	/* clear FDONE, FCERR, AEL by writing 1 to them (if they are set) */
+	writew_(spi_read_hsfs(regs), &regs->hsfs);
+}
+
+static inline uint16_t spi_read_hsfc(pch_spi_regs * const regs)
+{
+	return readw_(&regs->hsfc);
+}
+
+static inline uint32_t spi_read_faddr(pch_spi_regs * const regs)
+{
+	return readl_(&regs->faddr) & SPIBAR_FADDR_MASK;
+}
+
+/*
+ * Polls for Cycle Done Status, Flash Cycle Error
+ * Resets all error flags in HSFS.
+ * Returns 0 if the cycle completes successfully without errors within
+ * timeout, 1 on errors.
+ */
+static int wait_for_completion(pch_spi_regs * const regs, int timeout_ms,
+				size_t len)
+{
+	uint16_t hsfs;
+	uint16_t hsfc;
+	uint32_t addr;
+	struct stopwatch sw;
+	int timeout = 0;
+
+	stopwatch_init_msecs_expire(&sw, timeout_ms);
+
+	do {
+		hsfs = spi_read_hsfs(regs);
+
+		if ((hsfs & (HSFS_FDONE | HSFS_FCERR)))
+			break;
+	} while (!(timeout = stopwatch_expired(&sw)));
+
+	if (timeout) {
+		addr = spi_read_faddr(regs);
+		hsfc = spi_read_hsfc(regs);
+		printk(BIOS_ERR, "%ld ms Transaction timeout between offset "
+			"0x%08x and 0x%08zx (= 0x%08x + %zd) HSFC=%x HSFS=%x!\n",
+			stopwatch_duration_msecs(&sw), addr, addr + len - 1,
+			addr, len - 1, hsfc, hsfs);
+		return 1;
+	}
+
+	if (hsfs & HSFS_FCERR) {
+		addr = spi_read_faddr(regs);
+		hsfc = spi_read_hsfc(regs);
+		printk(BIOS_ERR, "Transaction error between offset 0x%08x and "
+		       "0x%08zx (= 0x%08x + %zd) HSFC=%x HSFS=%x!\n",
+		       addr, addr + len - 1, addr, len - 1,
+		       hsfc, hsfs);
+		return 1;
+	}
+
+	return 0;
+}
+
+/* Start operation returning 0 on success, non-zero on error or timeout. */
+static int spi_do_operation(int op, size_t offset, size_t size, int timeout_ms)
+{
+	uint16_t hsfc;
+	pch_spi_regs * const regs = get_spi_bar();
+
+	/* Clear status prior to operation. */
+	spi_clear_status(regs);
+
+	/* Set the FADDR */
+	writel_(offset & SPIBAR_FADDR_MASK, &regs->faddr);
+
+	hsfc = readw_(&regs->hsfc);
+	/* Clear then set the correct op. */
+	hsfc &= ~HSFC_FCYCLE_MASK;
+	hsfc |= op;
+	/* Set the size field */
+	hsfc &= ~HSFC_FDBC_MASK;
+	/* Check for sizes of confirming operations. */
+	if (size && size <= SPI_FDATA_BYTES)
+		hsfc |= ((size - 1) << HSFC_FDBC_SHIFT) & HSFC_FDBC_MASK;
+	/* start operation */
+	hsfc |= HSFC_FGO;
+	writew_(hsfc, &regs->hsfc);
+
+	return wait_for_completion(regs, timeout_ms, size);
+}
+
+unsigned int spi_crop_chunk(unsigned int cmd_len, unsigned int buf_len)
+{
+	return min(SPI_FDATA_BYTES, buf_len);
+}
+
+static size_t spi_get_flash_size(pch_spi_regs *spi_bar)
+{
+	uint32_t flcomp;
+	size_t size;
+
+	writel_(SPIBAR_FDOC_COMPONENT, &spi_bar->fdoc);
+	flcomp = readl_(&spi_bar->fdod);
+
+	switch (flcomp & FLCOMP_C0DEN_MASK) {
+	case FLCOMP_C0DEN_8MB:
+		size = 8*MiB;
+		break;
+	case FLCOMP_C0DEN_16MB:
+		size = 16*MiB;
+		break;
+	case FLCOMP_C0DEN_32MB:
+		size = 32*MiB;
+		break;
+	default:
+		size = 16*MiB;
+	}
+
+	return size;
+}
+
+int spi_xfer(struct spi_slave *slave, const void *dout,
+		unsigned int bytesout, void *din, unsigned int bytesin)
+{
+	/* TODO: Define xfer for hardware sequencing. */
+	return -1;
+}
+
+void spi_init(void)
+{
+	uint8_t bios_cntl;
+	device_t dev = PCH_DEV_SPI;
+
+	/* Disable the BIOS write protect so write commands are allowed. */
+	pci_read_config_byte(dev, SPIBAR_BIOS_CNTL, &bios_cntl);
+	bios_cntl &= ~SPIBAR_BC_EISS;
+	bios_cntl |= SPIBAR_BC_WPD;
+	pci_write_config_byte(dev, SPIBAR_BIOS_CNTL, bios_cntl);
+}
+
+int spi_claim_bus(struct spi_slave *slave)
+{
+	/* Handled by PCH automatically. */
+	return 0;
+}
+
+void spi_release_bus(struct spi_slave *slave)
+{
+	/* Handled by PCH automatically. */
+}
+
+int pch_hwseq_erase(struct spi_flash *flash, u32 offset, size_t len)
+{
+	u32 start, end, erase_size;
+	int ret = 0;
+
+	erase_size = flash->sector_size;
+	if (offset % erase_size || len % erase_size) {
+		printk(BIOS_ERR, "SF: Erase offset/length not multiple of erase size\n");
+		return -1;
+	}
+
+	flash->spi->rw = SPI_WRITE_FLAG;
+
+	start = offset;
+	end = start + len;
+
+	while (offset < end) {
+		if (spi_do_operation(HSFC_FCYCLE_4KE, offset, 0, 5000)) {
+			printk(BIOS_ERR, "SF: Erase failed at %x\n", offset);
+			ret = -1;
+			goto out;
+		}
+
+		offset += erase_size;
+	}
+
+	printk(BIOS_DEBUG, "SF: Successfully erased %zu bytes @ %#x\n",
+		len, start);
+
+out:
+	spi_release_bus(flash->spi);
+	return ret;
+}
+
+static void pch_read_data(uint8_t *data, int len)
+{
+	int i;
+	pch_spi_regs *spi_bar;
+	uint32_t temp32 = 0;
+
+	spi_bar = get_spi_bar();
+
+	for (i = 0; i < len; i++) {
+		if ((i % 4) == 0)
+			temp32 = readl_((uint8_t *)spi_bar->fdata + i);
+
+		data[i] = (temp32 >> ((i % 4) * 8)) & 0xff;
+	}
+}
+
+int pch_hwseq_read(struct spi_flash *flash, u32 addr, size_t len, void *buf)
+{
+	uint8_t block_len;
+
+	if (addr + len > spi_get_flash_size(get_spi_bar())) {
+		printk(BIOS_ERR,
+			"Attempt to read %x-%x which is out of chip\n",
+			(unsigned) addr,
+			(unsigned) addr+(unsigned) len);
+		return -1;
+	}
+
+	while (len > 0) {
+		const int timeout_ms = 6;
+
+		block_len = min(len, SPI_FDATA_BYTES);
+		if (block_len > (~addr & 0xff))
+			block_len = (~addr & 0xff) + 1;
+
+		if (spi_do_operation(HSFC_FCYCLE_RD, addr, block_len,
+					timeout_ms))
+			return -1;
+
+		pch_read_data(buf, block_len);
+		addr += block_len;
+		buf += block_len;
+		len -= block_len;
+	}
+	return 0;
+}
+
+/* Fill len bytes from the data array into the fdata/spid registers.
+ *
+ * Note that using len > flash->pgm->spi.max_data_write will trash the registers
+ * following the data registers.
+ */
+static void pch_fill_data(const uint8_t *data, int len)
+{
+	uint32_t temp32 = 0;
+	int i;
+	pch_spi_regs *spi_bar;
+
+	spi_bar = get_spi_bar();
+	if (len <= 0)
+		return;
+
+	for (i = 0; i < len; i++) {
+		if ((i % 4) == 0)
+			temp32 = 0;
+
+		temp32 |= ((uint32_t) data[i]) << ((i % 4) * 8);
+
+		if ((i % 4) == 3) /* 32 bits are full, write them to regs. */
+			writel_(temp32,
+				(uint8_t *)spi_bar->fdata + (i - (i % 4)));
+	}
+	i--;
+	if ((i % 4) != 3) /* Write remaining data to regs. */
+		writel_(temp32, (uint8_t *)spi_bar->fdata + (i - (i % 4)));
+}
+
+int pch_hwseq_write(struct spi_flash *flash,
+			   u32 addr, size_t len, const void *buf)
+{
+	uint8_t block_len;
+	uint32_t start = addr;
+	pch_spi_regs *spi_bar;
+
+	spi_bar = get_spi_bar();
+
+	if (addr + len > spi_get_flash_size(spi_bar)) {
+		printk(BIOS_ERR,
+			"Attempt to write 0x%x-0x%x which is out of chip\n",
+			(unsigned)addr, (unsigned) (addr+len));
+		return -1;
+	}
+
+	while (len > 0) {
+		const int timeout_ms = 6;
+
+		block_len = min(len, sizeof(spi_bar->fdata));
+		if (block_len > (~addr & 0xff))
+			block_len = (~addr & 0xff) + 1;
+
+		pch_fill_data(buf, block_len);
+		if (spi_do_operation(HSFC_FCYCLE_WR, addr, block_len,
+					timeout_ms)) {
+			printk(BIOS_ERR, "SF: write failure at %x\n", addr);
+			return -1;
+		}
+		addr += block_len;
+		buf += block_len;
+		len -= block_len;
+	}
+	printk(BIOS_DEBUG, "SF: Successfully written %u bytes @ %#x\n",
+	       (unsigned) (addr - start), start);
+	return 0;
+}
+
+int pch_hwseq_read_status(struct spi_flash *flash, u8 *reg)
+{
+	size_t block_len = SPI_READ_STATUS_LENGTH;
+	const int timeout_ms = 6;
+
+	if (spi_do_operation(HSFC_FCYCLE_RS, 0, block_len, timeout_ms))
+		return -1;
+
+	pch_read_data(reg, block_len);
+
+	return 0;
+}
+
+static struct spi_flash *spi_flash_hwseq_probe(struct spi_slave *spi)
+{
+	struct spi_flash *flash;
+
+	flash = malloc(sizeof(*flash));
+	if (!flash) {
+		printk(BIOS_WARNING, "SF: Failed to allocate memory\n");
+		return NULL;
+	}
+
+	flash->spi = spi;
+	flash->name = "Opaque HW-sequencing";
+
+	flash->write = pch_hwseq_write;
+	flash->erase = pch_hwseq_erase;
+	flash->read = pch_hwseq_read;
+	flash->status = pch_hwseq_read_status;
+
+	/* The hardware sequencing supports 4KiB or 64KiB erase. Use 4KiB. */
+	flash->sector_size = 4*KiB;
+
+	flash->size = spi_get_flash_size(get_spi_bar());
+
+	return flash;
+}
+
+struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs)
+{
+	struct spi_slave *slave = malloc(sizeof(*slave));
+
+	if (!slave) {
+		printk(BIOS_DEBUG, "PCH SPI: Bad allocation\n");
+		return NULL;
+	}
+
+	memset(slave, 0, sizeof(*slave));
+
+	slave->bus = bus;
+	slave->cs = cs;
+	slave->force_programmer_specific = 1;
+	slave->programmer_specific_probe = spi_flash_hwseq_probe;
+
+	return slave;
+}
+
+int spi_flash_protect(u32 start, u32 size)
+{
+	pch_spi_regs *spi_bar = get_spi_bar();
+	u32 end = start + size - 1;
+	u32 reg;
+	int prr;
+
+	if (!spi_bar)
+		return -1;
+
+	/* Find first empty PRR */
+	for (prr = 0; prr < SPI_PRR_MAX; prr++) {
+		reg = read32(&spi_bar->pr[prr]);
+		if (reg == 0)
+			break;
+	}
+	if (prr >= SPI_PRR_MAX) {
+		printk(BIOS_ERR, "ERROR: No SPI PRR free!\n");
+		return -1;
+	}
+
+	/* Set protected range base and limit */
+	reg = SPI_PRR(start, end) | SPI_PRR_WPE;
+
+	/* Set the PRR register and verify it is protected */
+	write32(&spi_bar->pr[prr], reg);
+	reg = read32(&spi_bar->pr[prr]);
+	if (!(reg & SPI_PRR_WPE)) {
+		printk(BIOS_ERR, "ERROR: Unable to set SPI PRR %d\n", prr);
+		return -1;
+	}
+
+	printk(BIOS_INFO, "%s: PRR %d is enabled for range 0x%08x-0x%08x\n",
+	       __func__, prr, start, end);
+	return 0;
+}
+
+#if ENV_RAMSTAGE
+/*
+ * spi_init() needs run unconditionally in every boot (including resume) to
+ * allow write protect to be disabled for eventlog and firmware updates.
+ */
+static void spi_init_cb(void *unused)
+{
+	spi_init();
+}
+
+BOOT_STATE_INIT_ENTRY(BS_PRE_DEVICE, BS_ON_ENTRY, spi_init_cb, NULL);
+#endif
diff --git a/src/soc/intel/kabylake/fsp_reset.c b/src/soc/intel/kabylake/fsp_reset.c
new file mode 100644
index 0000000..cb716af
--- /dev/null
+++ b/src/soc/intel/kabylake/fsp_reset.c
@@ -0,0 +1,62 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * 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 <bootstate.h>
+#include <vendorcode/google/chromeos/vboot_handoff.h>
+
+static int is_recovery; /* flag to identify recovery mode */
+
+/*
+ * coreboot used to clear recovery status towards romstage end after FSP
+ * memory init. Later inside FSP silicon init due to HSIO CRC mismatch
+ * or other silicon related programming may request for an additional
+ * reset. Thus on the next boot the system resumed in normal mode rather than
+ * recovery because it lost its original state due to FSP silicon init reset.
+ * Hence it needs an addition reset to get into old state and continue
+ * booting into recovery mode. This function will set recovery reason
+ * during Silicon init, in case of recovery mode booting,
+ * so, system will not lose its original context.
+ */
+static void set_recovery_request(void *unused)
+{
+	is_recovery = recovery_mode_enabled();
+	/*
+	* Set recovery flag during Recovery Mode Silicon Init
+	* & store recovery request into VBNV
+	*/
+	if (is_recovery)
+		set_recovery_mode_into_vbnv(vboot_recovery_reason());
+
+}
+
+static void clear_recovery_request(void *unused)
+{
+	/*
+	 * Done with Silicon Init, it's safe to clear
+	 * reset request now with assumption that no reset occurs hereafter
+	 * so we will not miss original data.
+	 */
+	if (is_recovery)
+		set_recovery_mode_into_vbnv(0);
+}
+/*
+ * On Recovery Path Set Recovery Request during early RAMSTAGE
+ * before initiated Silicon Init
+ */
+BOOT_STATE_INIT_ENTRY(BS_PRE_DEVICE, BS_ON_ENTRY, set_recovery_request, NULL);
+/*
+ * On Recovery Path Clear Recovery Request during early RAMSTAGE
+ * end of Silicon Init
+ */
+BOOT_STATE_INIT_ENTRY(BS_DEV_INIT_CHIPS, BS_ON_EXIT, clear_recovery_request, NULL);
diff --git a/src/soc/intel/kabylake/gpio.c b/src/soc/intel/kabylake/gpio.c
new file mode 100644
index 0000000..ad0c1f3
--- /dev/null
+++ b/src/soc/intel/kabylake/gpio.c
@@ -0,0 +1,415 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * 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 <stdint.h>
+#include <string.h>
+#include <arch/io.h>
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <gpio.h>
+#include <soc/pcr.h>
+#include <soc/iomap.h>
+#include <soc/pm.h>
+
+static const int gpio_debug = 0;
+
+/* There are 4 communities with 8 GPIO groups (GPP_[A:G] and GPD) */
+struct gpio_community {
+	int port_id;
+	/* Inclusive pads within the community. */
+	gpio_t min;
+	gpio_t max;
+};
+
+/* This is ordered to match ACPI and OS driver. */
+static const struct gpio_community communities[] = {
+	{
+		.port_id = PID_GPIOCOM0,
+		.min = GPP_A0,
+		.max = GPP_B23,
+	},
+	{
+		.port_id = PID_GPIOCOM1,
+		.min = GPP_C0,
+		.max = GPP_E23,
+	},
+	{
+		.port_id = PID_GPIOCOM3,
+		.min = GPP_F0,
+		.max = GPP_G7,
+	},
+	{
+		.port_id = PID_GPIOCOM2,
+		.min = GPD0,
+		.max = GPD11,
+	},
+};
+
+static const char *gpio_group_names[GPIO_NUM_GROUPS] = {
+	"GPP_A",
+	"GPP_B",
+	"GPP_C",
+	"GPP_D",
+	"GPP_E",
+	"GPP_F",
+	"GPP_G",
+	"GPD",
+};
+
+static inline size_t gpios_in_community(const struct gpio_community *comm)
+{
+	/* max is inclusive */
+	return comm->max - comm->min + 1;
+}
+
+static inline size_t groups_in_community(const struct gpio_community *comm)
+{
+	size_t n = gpios_in_community(comm) + GPIO_MAX_NUM_PER_GROUP - 1;
+	return n / GPIO_MAX_NUM_PER_GROUP;
+}
+
+static inline int gpio_index_gpd(gpio_t gpio)
+{
+	if (gpio >= GPD0 && gpio <= GPD11)
+		return 1;
+	return 0;
+}
+
+static const struct gpio_community *gpio_get_community(gpio_t pad)
+{
+	size_t i;
+
+	for (i = 0; i < ARRAY_SIZE(communities); i++) {
+		const struct gpio_community *c = &communities[i];
+
+		if (pad >= c->min && pad <= c->max)
+			return c;
+	}
+
+	return NULL;
+}
+
+static size_t community_clr_get_smi_sts(const struct gpio_community *comm,
+					uint32_t *sts)
+{
+	uint8_t *regs;
+	size_t i;
+	uint32_t *gpi_status_reg;
+	uint32_t *gpi_en_reg;
+	const size_t num_grps = groups_in_community(comm);
+
+	/* Not all groups can be routed to SMI. However, the registers
+	 * read as 0. In order to simplify the logic read everything from
+	 * each community. */
+	regs = pcr_port_regs(comm->port_id);
+	gpi_status_reg = (void *)&regs[GPI_SMI_STS_OFFSET];
+	gpi_en_reg = (void *)&regs[GPI_SMI_EN_OFFSET];
+	for (i = 0; i < num_grps; i++) {
+		sts[i] = read32(gpi_status_reg + i) & read32(gpi_en_reg + i);
+		/* Clear the enabled and set status bits. */
+		write32(gpi_status_reg + i, sts[i]);
+	}
+
+	return num_grps;
+}
+
+static void print_gpi_status(uint32_t status, const char *grp_name)
+{
+	int i;
+
+	if (!status)
+		return;
+
+	for (i = 31; i >= 0; i--) {
+		if (status & (1 << i))
+			printk(BIOS_DEBUG, "%s%d ", grp_name, i);
+	}
+}
+
+void gpi_clear_get_smi_status(struct gpi_status *sts)
+{
+	int i;
+	int do_print;
+	size_t sts_index = 0;
+
+	for (i = 0; i < ARRAY_SIZE(communities); i++) {
+		const struct gpio_community *comm = &communities[i];
+		sts_index += community_clr_get_smi_sts(comm,
+						&sts->grp[sts_index]);
+	}
+
+	do_print = 0;
+	for (i = 0; i < ARRAY_SIZE(sts->grp); i++) {
+		if (sts->grp[i] == 0)
+			continue;
+		do_print = 1;
+		break;
+	}
+
+	if (!do_print)
+		return;
+
+	printk(BIOS_DEBUG, "GPI_SMI_STS: ");
+	for (i = 0; i < ARRAY_SIZE(sts->grp); i++)
+		print_gpi_status(sts->grp[i], gpio_group_names[i]);
+	printk(BIOS_DEBUG, "\n");
+}
+
+int gpi_status_get(const struct gpi_status *sts, gpio_t gpi)
+{
+	const uint32_t *gpi_sts;
+
+	/* Check if valid gpi */
+	if (gpio_get_community(gpi) == NULL)
+		return 0;
+
+	/* If not in GPD group the index is a linear function based on
+	 * GPI number and GPIO_MAX_NUM_PER_GROUP. */
+	if (gpio_index_gpd(gpi))
+		gpi_sts = &sts->grp[GPD];
+	else
+		gpi_sts = &sts->grp[gpi / GPIO_MAX_NUM_PER_GROUP];
+
+	return !!(*gpi_sts & (1 << (gpi % GPIO_MAX_NUM_PER_GROUP)));
+}
+
+void gpio_route_gpe(uint16_t gpe0_route)
+{
+	int i;
+	uint32_t misc_cfg;
+	const uint32_t misc_cfg_reg_mask = GPE_DW_MASK;
+
+	misc_cfg = (uint32_t)gpe0_route << GPE_DW_SHIFT;
+	misc_cfg &= misc_cfg_reg_mask;
+
+	for (i = 0; i < ARRAY_SIZE(communities); i++) {
+		uint8_t *regs;
+		uint32_t reg;
+		const struct gpio_community *comm = &communities[i];
+
+		regs = pcr_port_regs(comm->port_id);
+
+		reg = read32(regs + MISCCFG_OFFSET);
+		reg &= ~misc_cfg_reg_mask;
+		reg |= misc_cfg;
+		write32(regs + MISCCFG_OFFSET, reg);
+	}
+}
+
+static void *gpio_dw_regs(gpio_t pad)
+{
+	const struct gpio_community *comm;
+	uint8_t *regs;
+	size_t pad_relative;
+
+	comm = gpio_get_community(pad);
+
+	if (comm == NULL)
+		return NULL;
+
+	regs = pcr_port_regs(comm->port_id);
+
+	pad_relative = pad - comm->min;
+
+	/* DW0 and DW1 regs are 4 bytes each. */
+	return &regs[PAD_CFG_DW_OFFSET + pad_relative * 8];
+}
+
+static void *gpio_hostsw_reg(gpio_t pad, size_t *bit)
+{
+	const struct gpio_community *comm;
+	uint8_t *regs;
+	size_t pad_relative;
+
+	comm = gpio_get_community(pad);
+
+	if (comm == NULL)
+		return NULL;
+
+	regs = pcr_port_regs(comm->port_id);
+
+	pad_relative = pad - comm->min;
+
+	/* Update the bit for this pad. */
+	*bit = (pad_relative % HOSTSW_OWN_PADS_PER);
+
+	/* HostSw regs are 4 bytes each. */
+	regs = &regs[HOSTSW_OWN_REG_OFFSET];
+	return &regs[(pad_relative / HOSTSW_OWN_PADS_PER) * 4];
+}
+
+static void gpio_handle_pad_mode(const struct pad_config *cfg)
+{
+	size_t bit;
+	uint32_t *hostsw_own_reg;
+	uint32_t reg;
+
+	bit = 0;
+	hostsw_own_reg = gpio_hostsw_reg(cfg->pad, &bit);
+
+	if (hostsw_own_reg == NULL)
+		return;
+
+	reg = read32(hostsw_own_reg);
+	reg &= ~(1U << bit);
+
+	if ((cfg->attrs & PAD_FIELD(HOSTSW, GPIO)) == PAD_FIELD(HOSTSW, GPIO))
+		reg |= (HOSTSW_GPIO << bit);
+	else
+		reg |= (HOSTSW_ACPI << bit);
+
+	write32(hostsw_own_reg, reg);
+}
+
+static void gpi_enable_smi(gpio_t pad)
+{
+	const struct gpio_community *comm;
+	uint8_t *regs;
+	uint32_t *gpi_status_reg;
+	uint32_t *gpi_en_reg;
+	size_t group_offset;
+	uint32_t pad_mask;
+
+	comm = gpio_get_community(pad);
+	if (comm == NULL)
+		return;
+	regs = pcr_port_regs(comm->port_id);
+	gpi_status_reg = (void *)&regs[GPI_SMI_STS_OFFSET];
+	gpi_en_reg = (void *)&regs[GPI_SMI_EN_OFFSET];
+
+	/* Offset of SMI STS/EN for this pad's group within the community. */
+	group_offset = (pad - comm->min) / GPIO_MAX_NUM_PER_GROUP;
+
+	/* Clear status then set enable. */
+	pad_mask = 1 << ((pad - comm->min) % GPIO_MAX_NUM_PER_GROUP);
+	write32(&gpi_status_reg[group_offset], pad_mask);
+	write32(&gpi_en_reg[group_offset],
+		read32(&gpi_en_reg[group_offset]) | pad_mask);
+}
+
+static void gpio_configure_pad(const struct pad_config *cfg)
+{
+	uint32_t *dw_regs;
+	uint32_t reg;
+	uint32_t dw0;
+	uint32_t mask;
+
+	dw_regs = gpio_dw_regs(cfg->pad);
+
+	if (dw_regs == NULL)
+		return;
+
+	dw0 = cfg->dw0;
+
+	write32(&dw_regs[0], dw0);
+	reg = read32(&dw_regs[1]);
+
+	/* Apply termination field */
+	mask = PAD_TERM_MASK << PAD_TERM_SHIFT;
+	reg &= ~mask;
+	reg |= cfg->attrs & mask;
+
+	/* Apply voltage tolerance field */
+	mask = PAD_TOL_MASK << PAD_TOL_SHIFT;
+	reg &= ~mask;
+	reg |= cfg->attrs & mask;
+	write32(&dw_regs[1], reg);
+
+	gpio_handle_pad_mode(cfg);
+
+	if ((dw0 & PAD_FIELD(GPIROUTSMI, MASK)) == PAD_FIELD(GPIROUTSMI, YES))
+		gpi_enable_smi(cfg->pad);
+
+	if (gpio_debug)
+		printk(BIOS_DEBUG,
+			"Write Pad: Base(%p) - conf0 = %x conf1= %x pad # = %d\n",
+			&dw_regs[0], dw0, reg, cfg->pad);
+}
+
+void gpio_configure_pads(const struct pad_config *cfgs, size_t num)
+{
+	size_t i;
+
+	for (i = 0; i < num; i++)
+		gpio_configure_pad(&cfgs[i]);
+}
+
+void gpio_input_pulldown(gpio_t gpio)
+{
+	struct pad_config cfg = PAD_CFG_GPI(gpio, 5K_PD, DEEP);
+	gpio_configure_pad(&cfg);
+}
+
+void gpio_input_pullup(gpio_t gpio)
+{
+	struct pad_config cfg = PAD_CFG_GPI(gpio, 5K_PU, DEEP);
+	gpio_configure_pad(&cfg);
+}
+
+void gpio_input(gpio_t gpio)
+{
+	struct pad_config cfg = PAD_CFG_GPI(gpio, NONE, DEEP);
+	gpio_configure_pad(&cfg);
+}
+
+void gpio_output(gpio_t gpio, int value)
+{
+	struct pad_config cfg = PAD_CFG_GPO(gpio, value, DEEP);
+	gpio_configure_pad(&cfg);
+}
+
+int gpio_get(gpio_t gpio_num)
+{
+	uint32_t *dw_regs;
+	uint32_t reg;
+
+	dw_regs = gpio_dw_regs(gpio_num);
+
+	if (dw_regs == NULL)
+		return -1;
+
+	reg = read32(&dw_regs[0]);
+
+	return (reg >> GPIORXSTATE_SHIFT) & GPIORXSTATE_MASK;
+}
+
+void gpio_set(gpio_t gpio_num, int value)
+{
+	uint32_t *dw_regs;
+	uint32_t reg;
+
+	dw_regs = gpio_dw_regs(gpio_num);
+
+	if (dw_regs == NULL)
+		return;
+
+	reg = read32(&dw_regs[0]);
+	reg &= ~PAD_FIELD(GPIOTXSTATE, MASK);
+	reg |= PAD_FIELD_VAL(GPIOTXSTATE, value);
+	write32(&dw_regs[0], reg);
+	/* GPIO port ids support posted write semantics. */
+}
+
+const char *gpio_acpi_path(gpio_t gpio_num)
+{
+	return "\\_SB.PCI0.GPIO";
+}
+
+uint16_t gpio_acpi_pin(gpio_t gpio_num)
+{
+	return gpio_num;
+}
diff --git a/src/soc/intel/kabylake/i2c.c b/src/soc/intel/kabylake/i2c.c
new file mode 100644
index 0000000..fe524b2
--- /dev/null
+++ b/src/soc/intel/kabylake/i2c.c
@@ -0,0 +1,116 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2016 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.
+ */
+
+#include <arch/acpigen.h>
+#include <device/device.h>
+#include <device/i2c.h>
+#include <device/pci.h>
+#include <device/pci_def.h>
+#include <device/pci_ids.h>
+#include <soc/intel/common/lpss_i2c.h>
+#include <soc/ramstage.h>
+
+uintptr_t lpss_i2c_base_address(unsigned bus)
+{
+	unsigned devfn;
+	struct device *dev;
+	struct resource *res;
+
+	/* bus -> devfn */
+	devfn = i2c_bus_to_devfn(bus);
+	if (devfn >= 0) {
+		/* devfn -> dev */
+		dev = dev_find_slot(0, devfn);
+		if (dev) {
+			/* dev -> bar0 */
+			res = find_resource(dev, PCI_BASE_ADDRESS_0);
+			if (res)
+				return res->base;
+		}
+	}
+
+	return (uintptr_t)NULL;
+}
+
+static int i2c_dev_to_bus(struct device *dev)
+{
+	return i2c_devfn_to_bus(dev->path.pci.devfn);
+}
+
+/*
+ * The device should already be enabled and out of reset,
+ * either from early init in coreboot or SiliconInit in FSP.
+ */
+static void i2c_dev_init(struct device *dev)
+{
+	struct soc_intel_kabylake_config *config = dev->chip_info;
+	const struct lpss_i2c_speed_config *sptr;
+	enum i2c_speed speed;
+	int i, bus = i2c_dev_to_bus(dev);
+
+	if (!config || bus < 0)
+		return;
+
+	speed = config->i2c[bus].speed ? : I2C_SPEED_FAST;
+	lpss_i2c_init(bus, speed);
+
+	/* Apply custom speed config if it has been set by the board */
+	for (i = 0; i < LPSS_I2C_SPEED_CONFIG_COUNT; i++) {
+		sptr = &config->i2c[bus].speed_config[i];
+		if (sptr->speed == speed) {
+			lpss_i2c_set_speed_config(bus, sptr);
+			break;
+		}
+	}
+}
+
+/* Generate ACPI I2C device objects */
+static void i2c_fill_ssdt(struct device *dev)
+{
+	struct soc_intel_kabylake_config *config = dev->chip_info;
+	int bus = i2c_dev_to_bus(dev);
+
+	if (!config || bus < 0)
+		return;
+
+	acpigen_write_scope(acpi_device_path(dev));
+	lpss_i2c_acpi_fill_ssdt(config->i2c[bus].speed_config);
+	acpigen_pop_len();
+}
+
+static struct i2c_bus_operations i2c_bus_ops = {
+	.dev_to_bus			= &i2c_dev_to_bus,
+};
+
+static struct device_operations i2c_dev_ops = {
+	.read_resources			= &pci_dev_read_resources,
+	.set_resources			= &pci_dev_set_resources,
+	.enable_resources		= &pci_dev_enable_resources,
+	.scan_bus			= &scan_smbus,
+	.ops_pci			= &soc_pci_ops,
+	.ops_i2c_bus			= &i2c_bus_ops,
+	.init				= &i2c_dev_init,
+	.acpi_fill_ssdt_generator	= &i2c_fill_ssdt,
+};
+
+static const unsigned short pci_device_ids[] = {
+	0x9d60, 0x9d61, 0x9d62, 0x9d63, 0x9d64, 0x9d65, 0
+};
+
+static const struct pci_driver pch_i2c __pci_driver = {
+	.ops	 = &i2c_dev_ops,
+	.vendor	 = PCI_VENDOR_ID_INTEL,
+	.devices = pci_device_ids,
+};
diff --git a/src/soc/intel/kabylake/igd.c b/src/soc/intel/kabylake/igd.c
new file mode 100644
index 0000000..01982d7
--- /dev/null
+++ b/src/soc/intel/kabylake/igd.c
@@ -0,0 +1,219 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * 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 <arch/acpi.h>
+#include <arch/io.h>
+#include <chip.h>
+#include <console/console.h>
+#include <delay.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <drivers/intel/gma/i915_reg.h>
+#include <fsp/gop.h>
+#include <soc/acpi.h>
+#include <soc/cpu.h>
+#include <soc/pm.h>
+#include <soc/ramstage.h>
+#include <soc/systemagent.h>
+#include <stdlib.h>
+#include <string.h>
+#include <vendorcode/google/chromeos/chromeos.h>
+
+u32 map_oprom_vendev(u32 vendev)
+{
+	return SA_IGD_OPROM_VENDEV;
+}
+
+static struct resource *gtt_res = NULL;
+
+static unsigned long gtt_read(unsigned long reg)
+{
+	u32 val;
+	val = read32((void *)(unsigned int)(gtt_res->base + reg));
+	return val;
+}
+
+static void gtt_write(unsigned long reg, unsigned long data)
+{
+	write32((void *)(unsigned int)(gtt_res->base + reg), data);
+}
+
+static inline void gtt_rmw(u32 reg, u32 andmask, u32 ormask)
+{
+	u32 val = gtt_read(reg);
+	val &= andmask;
+	val |= ormask;
+	gtt_write(reg, val);
+}
+
+static void igd_init(struct device *dev)
+{
+	u32 ddi_buf_ctl;
+
+	gtt_res = find_resource(dev, PCI_BASE_ADDRESS_0);
+	if (!gtt_res || !gtt_res->base)
+		return;
+
+	/*
+	 * Enable DDI-A (eDP) 4-lane operation if the link is not up yet.
+	 * This will allow the kernel to use 4-lane eDP links properly
+	 * if the VBIOS or GOP driver does not execute.
+	 */
+	ddi_buf_ctl = gtt_read(DDI_BUF_CTL_A);
+	if (!acpi_is_wakeup_s3() && !(ddi_buf_ctl & DDI_BUF_CTL_ENABLE)) {
+		ddi_buf_ctl |= DDI_A_4_LANES;
+		gtt_write(DDI_BUF_CTL_A, ddi_buf_ctl);
+	}
+
+	if (IS_ENABLED(CONFIG_GOP_SUPPORT))
+		return;
+
+	/* IGD needs to be Bus Master */
+	u32 reg32 = pci_read_config32(dev, PCI_COMMAND);
+	reg32 |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO;
+	pci_write_config32(dev, PCI_COMMAND, reg32);
+
+	/* Wait for any configured pre-graphics delay */
+	if (!acpi_is_wakeup_s3()) {
+#if IS_ENABLED(CONFIG_CHROMEOS)
+		if (developer_mode_enabled() || recovery_mode_enabled() ||
+		    vboot_wants_oprom())
+			mdelay(CONFIG_PRE_GRAPHICS_DELAY);
+#else
+		mdelay(CONFIG_PRE_GRAPHICS_DELAY);
+#endif
+	}
+
+	/* Initialize PCI device, load/execute BIOS Option ROM */
+	pci_dev_init(dev);
+
+#if IS_ENABLED(CONFIG_CHROMEOS)
+	if (!gfx_get_init_done() && !acpi_is_wakeup_s3()) {
+		/*
+		 * Enable DDI-A if the Option ROM did not execute:
+		 *
+		 * bit 0: Display detected (RO)
+		 * bit 4: DDI A supports 4 lanes and DDI E is not used
+		 * bit 7: DDI buffer is idle
+		 */
+		gtt_write(DDI_BUF_CTL_A, DDI_BUF_IS_IDLE | DDI_A_4_LANES |
+			  DDI_INIT_DISPLAY_DETECTED);
+	}
+#endif
+}
+
+/* Initialize IGD OpRegion, called from ACPI code */
+static int init_igd_opregion(igd_opregion_t *opregion)
+{
+	const optionrom_vbt_t *vbt;
+	uint32_t vbt_len;
+	u16 reg16;
+
+	memset(opregion, 0, sizeof(igd_opregion_t));
+
+	/* Read VBT table from flash */
+	vbt = fsp_get_vbt(&vbt_len);
+	if (!vbt)
+		die("vbt data not found");
+
+	memcpy(&opregion->header.signature, IGD_OPREGION_SIGNATURE,
+		sizeof(IGD_OPREGION_SIGNATURE) - 1);
+	memcpy(opregion->header.vbios_version, vbt->coreblock_biosbuild, sizeof(u32));
+	memcpy(opregion->vbt.gvd1, vbt, vbt->hdr_vbt_size <
+		sizeof(opregion->vbt.gvd1) ? vbt->hdr_vbt_size :
+		sizeof(opregion->vbt.gvd1));
+
+	/* Size, in KB, of the entire OpRegion structure (including header)*/
+	opregion->header.size = sizeof(igd_opregion_t) / KiB;
+	opregion->header.version = IGD_OPREGION_VERSION;
+
+	/* We just assume we're mobile for now */
+	opregion->header.mailboxes = MAILBOXES_MOBILE;
+
+	/* TODO Initialize Mailbox 1 */
+
+	/* Initialize Mailbox 3 */
+	opregion->mailbox3.bclp = IGD_BACKLIGHT_BRIGHTNESS;
+	opregion->mailbox3.pfit = IGD_FIELD_VALID | IGD_PFIT_STRETCH;
+	opregion->mailbox3.pcft = 0; /* should be (IMON << 1) & 0x3e */
+	opregion->mailbox3.cblv = IGD_FIELD_VALID | IGD_INITIAL_BRIGHTNESS;
+	opregion->mailbox3.bclm[0] = IGD_WORD_FIELD_VALID + 0x0000;
+	opregion->mailbox3.bclm[1] = IGD_WORD_FIELD_VALID + 0x0a19;
+	opregion->mailbox3.bclm[2] = IGD_WORD_FIELD_VALID + 0x1433;
+	opregion->mailbox3.bclm[3] = IGD_WORD_FIELD_VALID + 0x1e4c;
+	opregion->mailbox3.bclm[4] = IGD_WORD_FIELD_VALID + 0x2866;
+	opregion->mailbox3.bclm[5] = IGD_WORD_FIELD_VALID + 0x327f;
+	opregion->mailbox3.bclm[6] = IGD_WORD_FIELD_VALID + 0x3c99;
+	opregion->mailbox3.bclm[7] = IGD_WORD_FIELD_VALID + 0x46b2;
+	opregion->mailbox3.bclm[8] = IGD_WORD_FIELD_VALID + 0x50cc;
+	opregion->mailbox3.bclm[9] = IGD_WORD_FIELD_VALID + 0x5ae5;
+	opregion->mailbox3.bclm[10] = IGD_WORD_FIELD_VALID + 0x64ff;
+
+	/* TODO This may need to happen in S3 resume */
+	pci_write_config32(SA_DEV_IGD, ASLS, (u32)opregion);
+	reg16 = pci_read_config16(SA_DEV_IGD, SWSCI);
+	reg16 &= ~GSSCIE;
+	reg16 |= SMISCISEL;
+	pci_write_config16(SA_DEV_IGD, SWSCI, reg16);
+
+	return 0;
+}
+
+static unsigned long write_acpi_igd_opregion(device_t device,
+				unsigned long current, struct acpi_rsdp *rsdp)
+{
+	igd_opregion_t *opregion;
+
+	/* If GOP is not used, exit here */
+	if (!IS_ENABLED(CONFIG_GOP_SUPPORT))
+		return current;
+
+	/* If IGD is disabled, exit here */
+	if (pci_read_config16(device, PCI_VENDOR_ID) == 0xFFFF)
+		return current;
+
+	printk(BIOS_DEBUG, "ACPI: * IGD OpRegion\n");
+	opregion = (igd_opregion_t *)current;
+	init_igd_opregion(opregion);
+	current += sizeof(igd_opregion_t);
+	current = acpi_align_current(current);
+
+	printk(BIOS_DEBUG, "current = %lx\n", current);
+	return current;
+}
+
+static struct device_operations igd_ops = {
+	.read_resources		= &pci_dev_read_resources,
+	.set_resources		= &pci_dev_set_resources,
+	.enable_resources	= &pci_dev_enable_resources,
+	.init			= &igd_init,
+	.ops_pci		= &soc_pci_ops,
+	.write_acpi_tables	= write_acpi_igd_opregion,
+};
+
+static const unsigned short pci_device_ids[] = {
+	IGD_KABYLAKE_GT1_SULTM,
+	IGD_KABYLAKE_GT2_SULXM,
+	IGD_KABYLAKE_GT2_SULTM,
+	0,
+};
+
+static const struct pci_driver igd_driver __pci_driver = {
+	.ops	 = &igd_ops,
+	.vendor	 = PCI_VENDOR_ID_INTEL,
+	.devices = pci_device_ids,
+};
diff --git a/src/soc/intel/kabylake/include/soc/acpi.h b/src/soc/intel/kabylake/include/soc/acpi.h
new file mode 100644
index 0000000..8e06ca4
--- /dev/null
+++ b/src/soc/intel/kabylake/include/soc/acpi.h
@@ -0,0 +1,37 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * 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 _SOC_ACPI_H_
+#define _SOC_ACPI_H_
+
+#include <arch/acpi.h>
+#include <soc/nvs.h>
+
+/* P-state configuration */
+#define PSS_MAX_ENTRIES			8
+#define PSS_RATIO_STEP			2
+#define PSS_LATENCY_TRANSITION		10
+#define PSS_LATENCY_BUSMASTER		10
+
+void acpi_fill_in_fadt(acpi_fadt_t *fadt);
+unsigned long acpi_madt_irq_overrides(unsigned long current);
+void acpi_mainboard_gnvs(global_nvs_t *gnvs);
+void southcluster_inject_dsdt(device_t device);
+unsigned long southcluster_write_acpi_tables(device_t device,
+	unsigned long current, struct acpi_rsdp *rsdp);
+
+#endif /* _SOC_ACPI_H_ */
+
diff --git a/src/soc/intel/kabylake/include/soc/car_setup.S b/src/soc/intel/kabylake/include/soc/car_setup.S
new file mode 100644
index 0000000..4b881a1
--- /dev/null
+++ b/src/soc/intel/kabylake/include/soc/car_setup.S
@@ -0,0 +1,334 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013-2014 Sage Electronic Engineering, LLC.
+ * Copyright (C) 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 <cpu/x86/mtrr.h>
+#include <cpu/x86/cache.h>
+#include <cpu/x86/post_code.h>
+
+/*
+ * MTRR definitions
+ */
+.equ		IA32_MTRR_CAP,			0x00fe
+
+.equ		NO_EVICT_MODE,			0x02e0
+
+.equ		IA32_PQR_ASSOC,			0x0c8f
+.equ		IA32_L3_MASK_1,			0x0c91
+.equ		IA32_L3_MASK_2,			0x0c92
+.equ		CACHE_INIT_VALUE,		0
+
+/*
+ * See BWG - chapter "Determining Cacheable Code Region Base Addresses and Ranges".
+ *
+ */
+
+	movl	%edi, %ebp		/* Put BIST value in a safe place */
+	/*
+	 * Ensure that all variable-range MTRR valid flags are clear and
+	 * IA32_MTRR_DEF_TYPE MSR E flag is clear.  Note: This is the default state
+	 * after hardware reset.
+	 *
+	 * Initialize all fixed-range and variable-range MTRR register fields to 0.
+	 */
+	mov	$(MtrrByteCountFixed), %ebx		/* EBX = size of  Fixed MTRRs */
+
+	xorl	%eax, %eax			/* Clear the low dword to write */
+	xorl	%edx, %edx			/* Clear the high dword to write */
+	xorl	%ecx, %ecx
+	/* Clearing Fixed Range MTRRs */
+clear_mtrr_fixed:
+	addl	$(-2), %ebx			/* need to check it */
+	movw	(MtrrInitTable)(%ebx), %cx	/* cx <- address of mtrr to zero */
+	wrmsr
+	jnz	clear_mtrr_fixed			/* loop through the whole table */
+
+	post_code(0x21)
+
+	/* Clearing Variable Range MTRRs */
+	movl	$MTRR_CAP_MSR, %ecx
+	rdmsr
+	movzx	%al, %ebx
+	clr	%eax
+	clr	%edx
+	movl	$MTRR_PHYS_BASE(0), %ecx
+clear_var_mtrr:
+	wrmsr
+	inc	%ecx
+	wrmsr
+	inc	%ecx
+	dec	%ebx
+	jnz	clear_var_mtrr
+
+	post_code(0x22)
+
+	/*
+	 * Configure the default memory type to un-cacheable (UC) in the
+	 * IA32_MTRR_DEF_TYPE MSR.
+	 */
+
+	movl	$MTRR_DEF_TYPE_MSR, %ecx	/* Load the MTRR default type index */
+	rdmsr
+	andl	$0xFFFFF300, %eax		/* Clear the enable bits and def type UC. */
+	wrmsr
+
+	/* Configure MTRR_PHYS_MASK_HIGH for proper addressing above 4GB
+	 * based on the physical address size supported for this processor
+	 * This is based on read from CPUID EAX = 080000008h, EAX bits [7:0]
+	 *
+	 * Examples:
+	 *  MTRR_PHYS_MASK_HIGH = 00000000Fh  For 36 bit addressing
+	 *  MTRR_PHYS_MASK_HIGH = 0000000FFh  For 40 bit addressing
+	 */
+
+	movl	$0x80000008, %eax 	/* Address sizes leaf */
+	cpuid
+	sub	$32, %al
+	movzx	%al, %eax
+	xorl	%esi, %esi
+	bts	%eax, %esi
+	dec	%esi			/* esi <- MTRR_PHYS_MASK_HIGH */
+
+	/*
+	 *   Configure the DataStack region as write-back (WB) cacheable memory type
+	 *   using the variable range MTRRs.
+	 *
+	 *
+	 * Set the base address of the DataStack cache range
+	 */
+
+	movl	$CONFIG_DCACHE_RAM_BASE, %eax
+	orl	$MTRR_TYPE_WRBACK, %eax	/* Load the write-back cache value */
+	xorl	%edx, %edx			/* clear upper dword */
+	movl	$MTRR_PHYS_BASE(0), %ecx	/* Load the MTRR index */
+	wrmsr					/* the value in MTRR_PHYS_BASE_0 */
+
+	/*
+	 * Set the mask for the DataStack cache range
+	 * Compute MTRR mask value:  Mask = NOT (Size - 1)
+	 */
+	movl	$CONFIG_DCACHE_RAM_SIZE_TOTAL, %eax
+	dec	%eax
+	not	%eax
+	orl	$MTRR_PHYS_MASK_VALID, %eax	/* turn on the Valid flag */
+	movl	%esi, %edx			/* edx <- MTRR_PHYS_MASK_HIGH */
+	inc	%ecx
+	wrmsr					/* the value in MTRR_PHYS_MASK_0 */
+
+	post_code(0x23)
+
+	/*
+	 * Enable the MTRRs by setting the IA32_MTRR_DEF_TYPE MSR E flag.
+	 */
+	movl	$MTRR_DEF_TYPE_MSR, %ecx               /* Load the MTRR default type index */
+	rdmsr
+	orl	$MTRR_DEF_TYPE_EN, %eax             /* Enable variable range MTRRs */
+	wrmsr
+
+	post_code(0x24)
+
+	/*
+	 *   Enable the logical processor's (BSP) cache: execute INVD and set
+	 *   CR0.CD = 0, CR0.NW = 0.
+	 */
+	movl	%cr0, %eax
+	and	$(~(CR0_CD + CR0_NW)), %eax
+	invd
+	movl	%eax, %cr0
+
+	/*
+	 *   Enable No-Eviction Mode Setup State by setting
+	 *   NO_EVICT_MODE  MSR 2E0h bit [0] = '1'.
+	 */
+	movl	$NO_EVICT_MODE, %ecx
+	rdmsr
+	orl	$0x01, %eax
+	wrmsr
+
+	/* Create n-way set associativity of cache */
+	xorl	%edi, %edi
+Find_LLC_subleaf:
+	movl	%edi, %ecx
+	movl	$0x04, %eax
+	cpuid
+	inc	%edi
+	and	$0xe0, %al	/* EAX[7:5] = Cache Level */
+	cmp	$0x60, %al	/* Check to see if it is LLC */
+	jnz	Find_LLC_subleaf
+
+	/*
+	 * Set MSR 0xC91 IA32_L3_MASK_! = 0xE/0xFE/0xFFE/0xFFFE
+	 * for 4/8/16 way of LLC
+	*/
+	shr	$22, %ebx
+	inc	%ebx
+	/* Calculate n-way associativity of LLC */
+	mov	%bl, %cl
+
+	/*
+	 * Maximizing RO cacheability while locking in the CAR to a
+	 * single way since that particular way won't be victim candidate
+	 * for evictions.
+	 * This has been done after programing LLC_WAY_MASK_1 MSR
+	 * with desired LLC way as mentioned below.
+	 *
+	 * Hence create Code and Data Size as per request
+	 * Code Size (RO) : Up to 16M
+	 * Data Size (RW) : Up to 256K
+	 */
+	movl	$0x01, %eax
+	/*
+	 * LLC Ways -> LLC_WAY_MASK_1:
+	 *  4: 0x000E
+	 *  8: 0x00FE
+	 * 12: 0x0FFE
+	 * 16: 0xFFFE
+	 *
+	 * These MSRs contain one bit per each way of LLC
+	 * - If this bit is '0' - the way is protected from eviction
+	 * - If this bit is '1' - the way is not protected from eviction
+	 */
+	shl	%cl, %eax
+	subl	$0x02, %eax
+	movl	$IA32_L3_MASK_1, %ecx
+	xorl	%edx, %edx
+	wrmsr
+	/*
+	 * Set MSR 0xC92 IA32_L3_MASK_2 = 0x1
+	 *
+	 * For SKL SOC, data size remains 256K consistently.
+	 * Hence, creating 1-way associative cache for Data
+	*/
+	mov	$IA32_L3_MASK_2, %ecx
+	mov	$0x01, %eax
+	xorl	%edx, %edx
+	wrmsr
+	/*
+	 * Set IA32_PQR_ASSOC = 0x02
+	 *
+	 * Possible values:
+	 * 0: Default value, no way mask should be applied
+	 * 1: Apply way mask 1 to LLC
+	 * 2: Apply way mask 2 to LLC
+	 * 3: Shouldn't be use in NEM Mode
+	 */
+	movl	$IA32_PQR_ASSOC, %ecx
+	movl	$0x02, %eax
+	xorl	%edx, %edx
+	wrmsr
+
+	movl	$CONFIG_DCACHE_RAM_BASE, %edi
+	movl	$CONFIG_DCACHE_RAM_SIZE_TOTAL, %ecx
+	shr	$0x02, %ecx
+	movl	$CACHE_INIT_VALUE, %eax
+	cld
+	rep	stosl
+	/*
+	 * Set IA32_PQR_ASSOC = 0x01
+	 * At this stage we apply LLC_WAY_MASK_1 to the cache.
+	 * i.e. way 0 is protected from eviction.
+	*/
+	movl	$IA32_PQR_ASSOC, %ecx
+	movl	$0x01, %eax
+	xorl	%edx, %edx
+	wrmsr
+
+	/*
+	 * Enable No-Eviction Mode Run State by setting
+	 * NO_EVICT_MODE MSR 2E0h bit [1] = '1'.
+	 */
+
+	movl	$NO_EVICT_MODE, %ecx
+	rdmsr
+	orl	$0x02, %eax
+	wrmsr
+
+	post_code(0x25)
+	/*
+	 *   Configure the BIOS code region as write-protected (WP) cacheable
+	 *   memory type using a single variable range MTRR.
+	 *
+	 *   Ensure region to cache meets MTRR requirements for
+	 *   size and alignment.
+	 */
+	movl	$(0xFFFFFFFF - CONFIG_ROM_SIZE + 1), %edi	/* Code region base */
+	movl	$CONFIG_ROM_SIZE, %eax				/* Code region size */
+	cmpl	$0, %edi
+	jz	InvalidParameter
+	cmpl	$0, %eax
+	jz	InvalidParameter
+	jmp	CheckPass
+
+InvalidParameter:
+	movl	$0x80000002, %eax	/* RETURN_INVALID_PARAMETER */
+	jmp	.Lhlt
+
+CheckPass:
+
+	post_code(0x26)
+
+	/*
+	 * Program base register
+	 */
+	xorl	%edx, %edx			/* clear upper dword */
+	movl	$MTRR_PHYS_BASE(1), %ecx	/* setup variable mtrr */
+	movl	%edi, %eax
+	orl	$MTRR_TYPE_WRPROT, %eax	/* set type to write protect */
+	wrmsr
+
+	movl	$CONFIG_ROM_SIZE, %eax
+
+	/*
+	 * Compute MTRR mask value:  Mask = NOT (Size - 1)
+	 */
+	dec	%eax	/* eax - size to cache less one byte */
+	not	%eax	/* eax contains low 32 bits of mask */
+	or	$MTRR_PHYS_MASK_VALID, %eax
+	/*
+	 * Program mask register
+	 */
+	movl	$MTRR_PHYS_MASK(1) , %ecx	/* setup variable mtrr */
+	movl	%esi, %edx	/* edx <- MTRR_PHYS_MASK_HIGH */
+	wrmsr
+
+	post_code(0x27)
+
+	/*
+	 * edi:  BIST value
+	 * mm0:  low 32-bits of TSC value
+	 * mm1:  high 32-bits of TSC value
+	 */
+	movl	%ebp, %edi		/* Restore BIST value */
+
+	.section	.rodata
+
+MtrrInitTable:
+	.word      MTRR_DEF_TYPE_MSR
+	.word      MTRR_FIX_64K_00000
+	.word      MTRR_FIX_16K_80000
+	.word      MTRR_FIX_16K_A0000
+	.word      MTRR_FIX_4K_C0000
+	.word      MTRR_FIX_4K_C8000
+	.word      MTRR_FIX_4K_D0000
+	.word      MTRR_FIX_4K_D8000
+	.word      MTRR_FIX_4K_E0000
+	.word      MTRR_FIX_4K_E8000
+	.word      MTRR_FIX_4K_F0000
+	.word      MTRR_FIX_4K_F8000
+
+.equ MtrrByteCountFixed,  (.-MtrrInitTable)
+
+	.previous
diff --git a/src/soc/intel/kabylake/include/soc/car_teardown.S b/src/soc/intel/kabylake/include/soc/car_teardown.S
new file mode 100644
index 0000000..315b3c1
--- /dev/null
+++ b/src/soc/intel/kabylake/include/soc/car_teardown.S
@@ -0,0 +1,54 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013-2014 Sage Electronic Engineering, LLC.
+ * Copyright (C) 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.
+ *
+ */
+
+.equ		IA32_PQR_ASSOC,			0x0c8f
+
+	/* Disable MTRR by clearing the IA32_MTRR_DEF_TYPE MSR E flag. */
+	movl	$MTRR_DEF_TYPE_MSR, %ecx
+	rdmsr
+	andl	$(~MTRR_DEF_TYPE_EN), %eax
+	wrmsr
+
+	/* Invalidate Cache */
+	invd
+
+	/*
+	 * Disable No-Eviction Mode Run State by clearing
+	 * NO_EVICT_MODE MSR 2E0h bit [1] = 0
+	 */
+	movl	$0x000002E0, %ecx
+	rdmsr
+	andl	$~(0x2), %eax
+	wrmsr
+
+	/*
+	 * Disable No-Eviction Mode Setup State by clearing
+	 * NO_EVICT_MODE MSR 2E0h bit [0] = 0
+	 */
+	rdmsr
+	andl	$~(0x1), %eax
+	wrmsr
+
+	/*
+	 * Set IA32_PQR_ASSOC = 0x00
+	 * This step guarantees that no protected way remain in LLC cache,
+	 * all the ways are open for the evictions.
+	 */
+	movl	$IA32_PQR_ASSOC, %ecx
+	movl	$0x00, %eax
+	xorl	%edx, %edx
+	wrmsr
diff --git a/src/soc/intel/kabylake/include/soc/cpu.h b/src/soc/intel/kabylake/include/soc/cpu.h
new file mode 100644
index 0000000..91fc133
--- /dev/null
+++ b/src/soc/intel/kabylake/include/soc/cpu.h
@@ -0,0 +1,65 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * 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 _SOC_CPU_H_
+#define _SOC_CPU_H_
+
+#include <arch/cpu.h>
+#include <device/device.h>
+
+/* CPU types */
+#define KABYLAKE_FAMILY_ULT	0x406e0
+
+/* Supported CPUIDs */
+#define CPUID_KABYLAKE_C0	0x406e2
+#define CPUID_KABYLAKE_D0	0x406e3
+
+/* CPU bus clock is fixed at 100MHz */
+#define CPU_BCLK		100
+
+/* Latency times in units of 1024ns. */
+#define C_STATE_LATENCY_CONTROL_0_LIMIT	0x4e
+#define C_STATE_LATENCY_CONTROL_1_LIMIT	0x76
+#define C_STATE_LATENCY_CONTROL_2_LIMIT	0x94
+#define C_STATE_LATENCY_CONTROL_3_LIMIT	0xfa
+#define C_STATE_LATENCY_CONTROL_4_LIMIT	0x14c
+#define C_STATE_LATENCY_CONTROL_5_LIMIT	0x3f2
+
+/* Power in units of mW */
+#define C1_POWER	0x3e8
+#define C3_POWER	0x1f4
+#define C6_POWER	0x15e
+#define C7_POWER	0xc8
+#define C8_POWER	0xc8
+#define C9_POWER	0xc8
+#define C10_POWER	0xc8
+
+#define C_STATE_LATENCY_MICRO_SECONDS(limit, base) \
+	(((1 << ((base)*5)) * (limit)) / 1000)
+#define C_STATE_LATENCY_FROM_LAT_REG(reg) \
+	C_STATE_LATENCY_MICRO_SECONDS(C_STATE_LATENCY_CONTROL_ ##reg## _LIMIT, \
+				      (IRTL_1024_NS >> 10))
+
+/* Configure power limits for turbo mode */
+void set_power_limits(u8 power_limit_1_time);
+int cpu_config_tdp_levels(void);
+
+/* CPU identification */
+u32 cpu_family_model(void);
+u32 cpu_stepping(void);
+int cpu_is_ult(void);
+
+#endif
diff --git a/src/soc/intel/kabylake/include/soc/device_nvs.h b/src/soc/intel/kabylake/include/soc/device_nvs.h
new file mode 100644
index 0000000..d10420b
--- /dev/null
+++ b/src/soc/intel/kabylake/include/soc/device_nvs.h
@@ -0,0 +1,43 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * 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 _SOC_DEVICE_NVS_H_
+#define _SOC_DEVICE_NVS_H_
+
+#include <stdint.h>
+
+/* Offset in Global NVS where this structure lives */
+#define DEVICE_NVS_OFFSET	0x1000
+
+#define SIO_NVS_I2C0		0
+#define SIO_NVS_I2C1		1
+#define SIO_NVS_I2C2		2
+#define SIO_NVS_I2C3		3
+#define SIO_NVS_I2C4		4
+#define SIO_NVS_I2C5		5
+#define SIO_NVS_SPI0		6
+#define SIO_NVS_SPI1		7
+#define SIO_NVS_UART0		8
+#define SIO_NVS_UART1		9
+#define SIO_NVS_UART2		10
+
+typedef struct {
+	u8	enable[11];
+	u32	bar0[11];
+	u32	bar1[11];
+} __attribute__((packed)) device_nvs_t;
+
+#endif
diff --git a/src/soc/intel/kabylake/include/soc/flash_controller.h b/src/soc/intel/kabylake/include/soc/flash_controller.h
new file mode 100644
index 0000000..3e08a7f
--- /dev/null
+++ b/src/soc/intel/kabylake/include/soc/flash_controller.h
@@ -0,0 +1,181 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * 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 _SOC_FLASH_CONTROLLER__H_
+#define _SOC_FLASH_CONTROLLER__H_
+
+#include <rules.h>
+#include <arch/io.h>
+#include <console/console.h>
+#include <spi_flash.h>
+
+int pch_hwseq_erase(struct spi_flash *flash, u32 offset, size_t len);
+int pch_hwseq_write(struct spi_flash *flash,
+			   u32 addr, size_t len, const void *buf);
+
+int pch_hwseq_read(struct spi_flash *flash,
+			  u32 addr, size_t len, void *buf);
+int pch_hwseq_read_status(struct spi_flash *flash, u8 *reg);
+
+
+#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, 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, 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, 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 */
+
+#if ENV_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 /* !ENV_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 /* ENV_SMM */
+
+#define HSFC_FCYCLE_MASK	(0xf << HSFC_FCYCLE_SHIFT)
+#define HSFC_FCYCLE_RD		(0x0 << HSFC_FCYCLE_SHIFT)
+#define HSFC_FCYCLE_WR		(0x2 << HSFC_FCYCLE_SHIFT)
+#define HSFC_FCYCLE_4KE		(0x3 << HSFC_FCYCLE_SHIFT)
+#define HSFC_FCYCLE_64KE	(0x4 << HSFC_FCYCLE_SHIFT)
+#define HSFC_FCYCLE_SFDP	(0x5 << HSFC_FCYCLE_SHIFT)
+#define HSFC_FCYCLE_JEDECID	(0x6 << HSFC_FCYCLE_SHIFT)
+#define HSFC_FCYCLE_WS		(0x7 << HSFC_FCYCLE_SHIFT)
+#define HSFC_FCYCLE_RS		(0x8 << HSFC_FCYCLE_SHIFT)
+#define HSFC_FDBC_MASK		(0x3f << HSFC_FDBC_SHIFT)
+
+#define SPI_READ_STATUS_LENGTH 1 /* Read Status Register 1 */
+
+#define WPSR_MASK_SRP0_BIT 0x80
+
+#define SPI_FDATA_REGS 16
+#define SPI_FDATA_BYTES (SPI_FDATA_REGS * sizeof(uint32_t))
+
+typedef struct pch_spi_regs {
+	uint32_t bfpr;
+	uint16_t hsfs;
+	uint16_t hsfc;
+	uint32_t faddr;
+	uint32_t dlock;
+	uint32_t fdata[SPI_FDATA_REGS];
+	uint32_t frap;
+	uint32_t freg[6];
+	uint32_t _reserved1[6];
+	uint32_t pr[5];
+	uint32_t gpr0;
+	uint32_t _reserved2;
+	uint32_t _reserved3;
+	uint16_t preop;
+	uint16_t optype;
+	uint8_t opmenu[8];
+	uint32_t bbar;
+	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)) pch_spi_regs;
+
+enum {
+	HSFS_FDONE =		0x0001,
+	HSFS_FCERR =		0x0002,
+	HSFS_FDV =		0x4000,
+};
+
+enum {
+	HSFC_FGO =		0x0001,
+	HSFC_FCYCLE_SHIFT =	1,
+	HSFC_FDBC_SHIFT =	8,
+};
+#endif	/* _SOC_FLASH_CONTROLLER__H_ */
diff --git a/src/soc/intel/kabylake/include/soc/gpe.h b/src/soc/intel/kabylake/include/soc/gpe.h
new file mode 100644
index 0000000..655cc11
--- /dev/null
+++ b/src/soc/intel/kabylake/include/soc/gpe.h
@@ -0,0 +1,133 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2015 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.
+ */
+
+#ifndef _SOC_GPE_H_
+#define _SOC_GPE_H_
+
+/* GPE_31_0 */
+#define GPE0_DW0_00		0
+#define GPE0_DW0_01		1
+#define GPE0_DW0_02		2
+#define GPE0_DW0_03		3
+#define GPE0_DW0_04		4
+#define GPE0_DW0_05		5
+#define GPE0_DW0_06		6
+#define GPE0_DW0_07		7
+#define GPE0_DW0_08		8
+#define GPE0_DW0_09		9
+#define GPE0_DW0_10		10
+#define GPE0_DW0_11		11
+#define GPE0_DW0_12		12
+#define GPE0_DW0_13		13
+#define GPE0_DW0_14		14
+#define GPE0_DW0_15		15
+#define GPE0_DW0_16		16
+#define GPE0_DW0_17		17
+#define GPE0_DW0_18		18
+#define GPE0_DW0_19		19
+#define GPE0_DW0_20		20
+#define GPE0_DW0_21		21
+#define GPE0_DW0_22		22
+#define GPE0_DW0_23		23
+#define GPE0_DW0_24		24
+#define GPE0_DW0_25		25
+#define GPE0_DW0_26		26
+#define GPE0_DW0_27		27
+#define GPE0_DW0_28		28
+#define GPE0_DW0_29		29
+#define GPE0_DW0_30		30
+#define GPE0_DW0_31		31
+/* GPE_63_32 */
+#define GPE0_DW1_00		32
+#define GPE0_DW1_01		33
+#define GPE0_DW1_02		34
+#define GPE0_DW1_03		36
+#define GPE0_DW1_04		36
+#define GPE0_DW1_05		37
+#define GPE0_DW1_06		38
+#define GPE0_DW1_07		39
+#define GPE0_DW1_08		40
+#define GPE0_DW1_09		41
+#define GPE0_DW1_10		42
+#define GPE0_DW1_11		43
+#define GPE0_DW1_12		44
+#define GPE0_DW1_13		45
+#define GPE0_DW1_14		46
+#define GPE0_DW1_15		47
+#define GPE0_DW1_16		48
+#define GPE0_DW1_17		49
+#define GPE0_DW1_18		50
+#define GPE0_DW1_19		51
+#define GPE0_DW1_20		52
+#define GPE0_DW1_21		53
+#define GPE0_DW1_22		54
+#define GPE0_DW1_23		55
+#define GPE0_DW1_24		56
+#define GPE0_DW1_25		57
+#define GPE0_DW1_26		58
+#define GPE0_DW1_27		59
+#define GPE0_DW1_28		60
+#define GPE0_DW1_29		61
+#define GPE0_DW1_30		62
+#define GPE0_DW1_31		63
+/* GPE_95_64 */
+#define GPE0_DW2_00		64
+#define GPE0_DW2_01		65
+#define GPE0_DW2_02		66
+#define GPE0_DW2_03		67
+#define GPE0_DW2_04		68
+#define GPE0_DW2_05		69
+#define GPE0_DW2_06		70
+#define GPE0_DW2_07		71
+#define GPE0_DW2_08		72
+#define GPE0_DW2_09		73
+#define GPE0_DW2_10		74
+#define GPE0_DW2_11		75
+#define GPE0_DW2_12		76
+#define GPE0_DW2_13		77
+#define GPE0_DW2_14		78
+#define GPE0_DW2_15		79
+#define GPE0_DW2_16		80
+#define GPE0_DW2_17		81
+#define GPE0_DW2_18		82
+#define GPE0_DW2_19		83
+#define GPE0_DW2_20		84
+#define GPE0_DW2_21		85
+#define GPE0_DW2_22		86
+#define GPE0_DW2_23		87
+#define GPE0_DW2_24		88
+#define GPE0_DW2_25		89
+#define GPE0_DW2_26		90
+#define GPE0_DW2_27		91
+#define GPE0_DW2_28		92
+#define GPE0_DW2_29		93
+#define GPE0_DW2_30		94
+#define GPE0_DW2_31		95
+/* GPE_STD */
+#define GPE0_HOT_PLUG		97
+#define GPE0_SWGPE		98
+#define GPE0_TCOSCI		102
+#define GPE0_SMB_WAK		103
+#define GPE0_PCI_EXP		105
+#define GPE0_BATLOW		106
+#define GPE0_PME		107
+#define GPE0_ME_SCI		108
+#define GPE0_PME_B0		109
+#define GPE0_ESPI		110
+#define GPE0_GPIO_T2		111
+#define GPE0_LAN_WAK		112
+#define GPE0_WADT		114
+
+#endif /* _SOC_GPE_H_ */
diff --git a/src/soc/intel/kabylake/include/soc/gpio.h b/src/soc/intel/kabylake/include/soc/gpio.h
new file mode 100644
index 0000000..0c4e40d
--- /dev/null
+++ b/src/soc/intel/kabylake/include/soc/gpio.h
@@ -0,0 +1,174 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * 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 _SOC_GPIO_H_
+#define _SOC_GPIO_H_
+
+#include <soc/gpio_defs.h>
+
+#ifndef __ACPI__
+#include <stdint.h>
+#include <stddef.h>
+
+typedef uint32_t gpio_t;
+
+/* Structure to represent GPI status for GPE and SMI. Use helper
+ * functions for interrogating particular GPIs. */
+struct gpi_status {
+	uint32_t grp[GPIO_NUM_GROUPS];
+};
+
+/*
+ * Clear GPI SMI status and fill in the structure representing enabled
+ * and set status.
+ */
+void gpi_clear_get_smi_status(struct gpi_status *sts);
+
+/* Return 1 if gpio is set in the gpi_status struct. Otherwise 0. */
+int gpi_status_get(const struct gpi_status *sts, gpio_t gpi);
+
+/*
+ * Set the GPIO groups for the GPE blocks. The gpe0_route is interpreted
+ * as the packed configuration for GPE0_DW[2:0]:
+ *  dw0 = gpe0_route[3:0]
+ *  dw1 = gpe0_route[7:4]
+ *  dw2 = gpe0_route[11:8].
+ */
+void gpio_route_gpe(uint16_t gpe0_route);
+
+/* Configure the pads according to the pad_config array. */
+struct pad_config;
+void gpio_configure_pads(const struct pad_config *cfgs, size_t num);
+
+#define PAD_FIELD_VAL(field_, val_) \
+	(((val_) & field_ ## _MASK) << field_ ## _SHIFT)
+
+#define PAD_FIELD(field_, setting_) \
+	PAD_FIELD_VAL(field_, field_ ## _ ## setting_)
+
+/*
+ * This encodes all the fields found within the dw0 register for each
+ * pad. It directly follows the register specification:
+ *   rst - reset type when pad configuration is reset
+ *   rxst - native function routing: raw buffer or internal buffer
+ *   rxraw1 - drive fixed '1' for Rx buffer
+ *   rxev - event filtering for pad value: level, edge, drive '0'
+ *   rxgf - glitch filter enable
+ *   rxinv - invert the internal pad state
+ *   gpiioapic - route to IOxAPIC
+ *   gpisci -  route for SCI
+ *   gpismi - route for SMI
+ *   gpinmi - route for NMI
+ *   mode -  GPIO vs native function
+ *   rxdis - disable Rx buffer
+ *   txdis - disable Tx buffer
+ */
+#define _DW0_VALS(rst, rxst, rxraw1, rxev, rxgf, rxinv, gpiioapic, gpisci, \
+			gpismi, gpinmi, mode, rxdis, txdis) \
+	(PAD_FIELD(PADRSTCFG, rst) | \
+	 PAD_FIELD(RXPADSTSEL, rxst) | \
+	 PAD_FIELD(RXRAW1, rxraw1) | \
+	 PAD_FIELD(RXEVCFG, rxev) | \
+	 PAD_FIELD(PREGFRXSEL, rxgf) | \
+	 PAD_FIELD(RXINV, rxinv) | \
+	 PAD_FIELD(GPIROUTIOXAPIC, gpiioapic) | \
+	 PAD_FIELD(GPIROUTSCI, gpisci) | \
+	 PAD_FIELD(GPIROUTSMI, gpismi) | \
+	 PAD_FIELD(GPIROUTNMI, gpinmi) | \
+	 PAD_FIELD(PMODE, mode) | \
+	 PAD_FIELD(GPIORXDIS, rxdis) | \
+	 PAD_FIELD(GPIOTXDIS, txdis))
+
+#define _PAD_CFG_ATTRS(pad_, term_, dw0_, attrs_)			\
+	{ 								\
+		.pad = pad_,						\
+		.attrs = PAD_FIELD(PAD_TERM,  term_) | attrs_,		\
+		.dw0 = dw0_,						\
+	}
+
+/* Default to ACPI owned. Ownership only matters for GPI pads. */
+#define _PAD_CFG(pad_, term_, dw0_) \
+	_PAD_CFG_ATTRS(pad_, term_, dw0_, PAD_FIELD(HOSTSW, ACPI))
+
+/* Native Function - No Rx buffer manipulation */
+#define PAD_CFG_NF(pad_, term_, rst_, func_) \
+	_PAD_CFG(pad_, term_, \
+	_DW0_VALS(rst_, RAW, NO, LEVEL, NO, NO, NO, NO, NO, NO, func_, NO, NO))
+
+/* Native 1.8V tolerant pad, only applies to some pads like I2C/I2S. */
+#define PAD_CFG_NF_1V8(pad_, term_, rst_, func_) \
+	_PAD_CFG_ATTRS(pad_, term_, \
+	_DW0_VALS(rst_, RAW, NO, LEVEL, NO, NO, \
+		NO, NO, NO, NO, func_, NO, NO), PAD_FIELD(PAD_TOL, 1V8))
+
+/* Unused PINS will be controlled by GPIO controller (PMODE = GPIO) and
+   GPIO TX/RX will be disabled. */
+#define PAD_CFG_NC(pad_) \
+	_PAD_CFG(pad_, NONE, \
+	_DW0_VALS(DEEP, RAW, NO, LEVEL, NO, NO, NO, NO, NO, NO, GPIO, YES, YES))
+
+/* General purpose output with termination. */
+#define PAD_CFG_TERM_GPO(pad_, val_, term_, rst_) \
+	_PAD_CFG(pad_, term_, \
+	_DW0_VALS(rst_, RAW, NO, LEVEL, NO, NO, NO, NO, NO, NO, GPIO, YES, NO) \
+		| PAD_FIELD_VAL(GPIOTXSTATE, val_))
+
+/* General purpose output. By default no termination. */
+#define PAD_CFG_GPO(pad_, val_, rst_) \
+	PAD_CFG_TERM_GPO(pad_, val_, NONE, rst_)
+
+/* General purpose input with no special IRQ routing. */
+#define PAD_CFG_GPI(pad_, term_, rst_) \
+	_PAD_CFG_ATTRS(pad_, term_, \
+	_DW0_VALS(rst_, RAW, NO, LEVEL, NO, NO, NO, NO, NO, NO, GPIO, NO, YES),\
+	PAD_FIELD(HOSTSW, GPIO))
+
+/* General purpose input passed through to IOxAPIC. Assume APIC logic can
+ * handle polarity/edge/level constraints. */
+#define PAD_CFG_GPI_APIC(pad_, term_, rst_) \
+	_PAD_CFG(pad_, term_, \
+	_DW0_VALS(rst_, RAW, NO, LEVEL, NO, NO, YES, NO, NO, NO, GPIO, NO, YES))
+
+/* General purpose input routed to SCI. This assumes edge triggered events. */
+#define PAD_CFG_GPI_ACPI_SCI(pad_, term_, rst_, inv_) \
+	_PAD_CFG_ATTRS(pad_, term_, \
+	_DW0_VALS(rst_, RAW, NO, EDGE, NO, inv_, \
+		NO, YES, NO, NO, GPIO, NO, YES), PAD_FIELD(HOSTSW, ACPI))
+
+/* General purpose input routed to SMI. This assumes edge triggered events. */
+#define PAD_CFG_GPI_ACPI_SMI(pad_, term_, rst_, inv_) \
+	_PAD_CFG_ATTRS(pad_, term_, \
+	_DW0_VALS(rst_, RAW, NO, EDGE, NO, inv_, \
+		NO, NO, YES, NO, GPIO, NO, YES), PAD_FIELD(HOSTSW, ACPI))
+
+/*
+ * The 'attrs' field carries the termination in bits 13:10 and tolerance in bit
+ * 25 to match up with thd DW1 pad configuration register. Additionally, other
+ * attributes can be applied such as the ones below. Bit allocation matters.
+ */
+#define HOSTSW_SHIFT		0
+#define HOSTSW_MASK		1
+#define HOSTSW_ACPI		HOSTSW_OWN_ACPI
+#define HOSTSW_GPIO		HOSTSW_OWN_GPIO
+
+struct pad_config {
+	uint16_t pad;
+	uint32_t attrs;
+	uint32_t dw0;
+};
+
+#endif /* __ACPI__ */
+#endif
diff --git a/src/soc/intel/kabylake/include/soc/gpio_defs.h b/src/soc/intel/kabylake/include/soc/gpio_defs.h
new file mode 100644
index 0000000..4008dfe
--- /dev/null
+++ b/src/soc/intel/kabylake/include/soc/gpio_defs.h
@@ -0,0 +1,509 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2015 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.
+ */
+
+#ifndef _SOC_GPIO_DEFS_H_
+#define _SOC_GPIO_DEFS_H_
+
+/*
+ * There are 8 GPIO groups. GPP_A -> GPP_G and GPD. GPD is the special case
+ * where that group is not so generic. So most of the fixed numbers and macros
+ * are based on the GPP groups. The GPIO groups are accessed through register
+ * blocks called communities.
+ */
+#define GPP_A			0
+#define GPP_B			1
+#define GPP_C			2
+#define GPP_D			3
+#define GPP_E			4
+#define GPP_F			5
+#define GPP_G			6
+#define GPD			7
+#define GPIO_NUM_GROUPS		8
+#define GPIO_MAX_NUM_PER_GROUP	24
+
+/*
+ * GPIOs are ordered monotonically increasing to match ACPI/OS driver.
+ */
+
+/* Group A */
+#define GPP_A0			0
+#define GPP_A1			1
+#define GPP_A2			2
+#define GPP_A3			3
+#define GPP_A4			4
+#define GPP_A5			5
+#define GPP_A6			6
+#define GPP_A7			7
+#define GPP_A8			8
+#define GPP_A9			9
+#define GPP_A10			10
+#define GPP_A11			11
+#define GPP_A12			12
+#define GPP_A13			13
+#define GPP_A14			14
+#define GPP_A15			15
+#define GPP_A16			16
+#define GPP_A17			17
+#define GPP_A18			18
+#define GPP_A19			19
+#define GPP_A20			20
+#define GPP_A21			21
+#define GPP_A22			22
+#define GPP_A23			23
+/* Group B */
+#define GPP_B0			24
+#define GPP_B1			25
+#define GPP_B2			26
+#define GPP_B3			27
+#define GPP_B4			28
+#define GPP_B5			29
+#define GPP_B6			30
+#define GPP_B7			31
+#define GPP_B8			32
+#define GPP_B9			33
+#define GPP_B10			34
+#define GPP_B11			35
+#define GPP_B12			36
+#define GPP_B13			37
+#define GPP_B14			38
+#define GPP_B15			39
+#define GPP_B16			40
+#define GPP_B17			41
+#define GPP_B18			42
+#define GPP_B19			43
+#define GPP_B20			44
+#define GPP_B21			45
+#define GPP_B22			46
+#define GPP_B23			47
+/* Group C */
+#define GPP_C0			48
+#define GPP_C1			49
+#define GPP_C2			50
+#define GPP_C3			51
+#define GPP_C4			52
+#define GPP_C5			53
+#define GPP_C6			54
+#define GPP_C7			55
+#define GPP_C8			56
+#define GPP_C9			57
+#define GPP_C10			58
+#define GPP_C11			59
+#define GPP_C12			60
+#define GPP_C13			61
+#define GPP_C14			62
+#define GPP_C15			63
+#define GPP_C16			64
+#define GPP_C17			65
+#define GPP_C18			66
+#define GPP_C19			67
+#define GPP_C20			68
+#define GPP_C21			69
+#define GPP_C22			70
+#define GPP_C23			71
+/* Group D */
+#define GPP_D0			72
+#define GPP_D1			73
+#define GPP_D2			74
+#define GPP_D3			75
+#define GPP_D4			76
+#define GPP_D5			77
+#define GPP_D6			78
+#define GPP_D7			79
+#define GPP_D8			80
+#define GPP_D9			81
+#define GPP_D10			82
+#define GPP_D11			83
+#define GPP_D12			84
+#define GPP_D13			85
+#define GPP_D14			86
+#define GPP_D15			87
+#define GPP_D16			88
+#define GPP_D17			89
+#define GPP_D18			90
+#define GPP_D19			91
+#define GPP_D20			92
+#define GPP_D21			93
+#define GPP_D22			94
+#define GPP_D23			95
+/* Group E */
+#define GPP_E0			96
+#define GPP_E1			97
+#define GPP_E2			98
+#define GPP_E3			99
+#define GPP_E4			100
+#define GPP_E5			101
+#define GPP_E6			102
+#define GPP_E7			103
+#define GPP_E8			104
+#define GPP_E9			105
+#define GPP_E10			106
+#define GPP_E11			107
+#define GPP_E12			108
+#define GPP_E13			109
+#define GPP_E14			110
+#define GPP_E15			111
+#define GPP_E16			112
+#define GPP_E17			113
+#define GPP_E18			114
+#define GPP_E19			115
+#define GPP_E20			116
+#define GPP_E21			117
+#define GPP_E22			118
+#define GPP_E23			119
+/* Group F */
+#define GPP_F0			120
+#define GPP_F1			121
+#define GPP_F2			122
+#define GPP_F3			123
+#define GPP_F4			124
+#define GPP_F5			125
+#define GPP_F6			126
+#define GPP_F7			127
+#define GPP_F8			128
+#define GPP_F9			129
+#define GPP_F10			130
+#define GPP_F11			131
+#define GPP_F12			132
+#define GPP_F13			133
+#define GPP_F14			134
+#define GPP_F15			135
+#define GPP_F16			136
+#define GPP_F17			137
+#define GPP_F18			138
+#define GPP_F19			139
+#define GPP_F20			140
+#define GPP_F21			141
+#define GPP_F22			142
+#define GPP_F23			143
+/* Group G */
+#define GPP_G0			144
+#define GPP_G1			145
+#define GPP_G2			146
+#define GPP_G3			147
+#define GPP_G4			148
+#define GPP_G5			149
+#define GPP_G6			150
+#define GPP_G7			151
+/* Group GPD  */
+#define GPD0			152
+#define GPD1			153
+#define GPD2			154
+#define GPD3			155
+#define GPD4			156
+#define GPD5			157
+#define GPD6			158
+#define GPD7			159
+#define GPD8			160
+#define GPD9			161
+#define GPD10			162
+#define GPD11			163
+
+/*
+ * IOxAPIC IRQs for the GPIOs
+ */
+
+/* Group A */
+#define GPP_A0_IRQ		0x18
+#define GPP_A1_IRQ		0x19
+#define GPP_A2_IRQ		0x1a
+#define GPP_A3_IRQ		0x1b
+#define GPP_A4_IRQ		0x1c
+#define GPP_A5_IRQ		0x1d
+#define GPP_A6_IRQ		0x1e
+#define GPP_A7_IRQ		0x1f
+#define GPP_A8_IRQ		0x20
+#define GPP_A9_IRQ		0x21
+#define GPP_A10_IRQ		0x22
+#define GPP_A11_IRQ		0x23
+#define GPP_A12_IRQ		0x24
+#define GPP_A13_IRQ		0x25
+#define GPP_A14_IRQ		0x26
+#define GPP_A15_IRQ		0x27
+#define GPP_A16_IRQ		0x28
+#define GPP_A17_IRQ		0x29
+#define GPP_A18_IRQ		0x2a
+#define GPP_A19_IRQ		0x2b
+#define GPP_A20_IRQ		0x2c
+#define GPP_A21_IRQ		0x2d
+#define GPP_A22_IRQ		0x2e
+#define GPP_A23_IRQ		0x2f
+/* Group B */
+#define GPP_B0_IRQ		0x30
+#define GPP_B1_IRQ		0x31
+#define GPP_B2_IRQ		0x32
+#define GPP_B3_IRQ		0x33
+#define GPP_B4_IRQ		0x34
+#define GPP_B5_IRQ		0x35
+#define GPP_B6_IRQ		0x36
+#define GPP_B7_IRQ		0x37
+#define GPP_B8_IRQ		0x38
+#define GPP_B9_IRQ		0x39
+#define GPP_B10_IRQ		0x3a
+#define GPP_B11_IRQ		0x3b
+#define GPP_B12_IRQ		0x3c
+#define GPP_B13_IRQ		0x3d
+#define GPP_B14_IRQ		0x3e
+#define GPP_B15_IRQ		0x3f
+#define GPP_B16_IRQ		0x40
+#define GPP_B17_IRQ		0x41
+#define GPP_B18_IRQ		0x42
+#define GPP_B19_IRQ		0x43
+#define GPP_B20_IRQ		0x44
+#define GPP_B21_IRQ		0x45
+#define GPP_B22_IRQ		0x46
+#define GPP_B23_IRQ		0x47
+/* Group C */
+#define GPP_C0_IRQ		0x48
+#define GPP_C1_IRQ		0x49
+#define GPP_C2_IRQ		0x4a
+#define GPP_C3_IRQ		0x4b
+#define GPP_C4_IRQ		0x4c
+#define GPP_C5_IRQ		0x4d
+#define GPP_C6_IRQ		0x4e
+#define GPP_C7_IRQ		0x4f
+#define GPP_C8_IRQ		0x50
+#define GPP_C9_IRQ		0x51
+#define GPP_C10_IRQ		0x52
+#define GPP_C11_IRQ		0x53
+#define GPP_C12_IRQ		0x54
+#define GPP_C13_IRQ		0x55
+#define GPP_C14_IRQ		0x56
+#define GPP_C15_IRQ		0x57
+#define GPP_C16_IRQ		0x58
+#define GPP_C17_IRQ		0x59
+#define GPP_C18_IRQ		0x5a
+#define GPP_C19_IRQ		0x5b
+#define GPP_C20_IRQ		0x5c
+#define GPP_C21_IRQ		0x5d
+#define GPP_C22_IRQ		0x5e
+#define GPP_C23_IRQ		0x5f
+/* Group D */
+#define GPP_D0_IRQ		0x60
+#define GPP_D1_IRQ		0x61
+#define GPP_D2_IRQ		0x62
+#define GPP_D3_IRQ		0x63
+#define GPP_D4_IRQ		0x64
+#define GPP_D5_IRQ		0x65
+#define GPP_D6_IRQ		0x66
+#define GPP_D7_IRQ		0x67
+#define GPP_D8_IRQ		0x68
+#define GPP_D9_IRQ		0x69
+#define GPP_D10_IRQ		0x6a
+#define GPP_D11_IRQ		0x6b
+#define GPP_D12_IRQ		0x6c
+#define GPP_D13_IRQ		0x6d
+#define GPP_D14_IRQ		0x6e
+#define GPP_D15_IRQ		0x6f
+#define GPP_D16_IRQ		0x70
+#define GPP_D17_IRQ		0x71
+#define GPP_D18_IRQ		0x72
+#define GPP_D19_IRQ		0x73
+#define GPP_D20_IRQ		0x74
+#define GPP_D21_IRQ		0x75
+#define GPP_D22_IRQ		0x76
+#define GPP_D23_IRQ		0x77
+/* Group E */
+#define GPP_E0_IRQ		0x18
+#define GPP_E1_IRQ		0x19
+#define GPP_E2_IRQ		0x1a
+#define GPP_E3_IRQ		0x1b
+#define GPP_E4_IRQ		0x1c
+#define GPP_E5_IRQ		0x1d
+#define GPP_E6_IRQ		0x1e
+#define GPP_E7_IRQ		0x1f
+#define GPP_E8_IRQ		0x20
+#define GPP_E9_IRQ		0x21
+#define GPP_E10_IRQ		0x22
+#define GPP_E11_IRQ		0x23
+#define GPP_E12_IRQ		0x24
+#define GPP_E13_IRQ		0x25
+#define GPP_E14_IRQ		0x26
+#define GPP_E15_IRQ		0x27
+#define GPP_E16_IRQ		0x28
+#define GPP_E17_IRQ		0x29
+#define GPP_E18_IRQ		0x2a
+#define GPP_E19_IRQ		0x2b
+#define GPP_E20_IRQ		0x2c
+#define GPP_E21_IRQ		0x2d
+#define GPP_E22_IRQ		0x2e
+#define GPP_E23_IRQ		0x2f
+/* Group F */
+#define GPP_F0_IRQ		0x30
+#define GPP_F1_IRQ		0x31
+#define GPP_F2_IRQ		0x32
+#define GPP_F3_IRQ		0x33
+#define GPP_F4_IRQ		0x34
+#define GPP_F5_IRQ		0x35
+#define GPP_F6_IRQ		0x36
+#define GPP_F7_IRQ		0x37
+#define GPP_F8_IRQ		0x38
+#define GPP_F9_IRQ		0x39
+#define GPP_F10_IRQ		0x3a
+#define GPP_F11_IRQ		0x3b
+#define GPP_F12_IRQ		0x3c
+#define GPP_F13_IRQ		0x3d
+#define GPP_F14_IRQ		0x3e
+#define GPP_F15_IRQ		0x3f
+#define GPP_F16_IRQ		0x40
+#define GPP_F17_IRQ		0x41
+#define GPP_F18_IRQ		0x42
+#define GPP_F19_IRQ		0x43
+#define GPP_F20_IRQ		0x44
+#define GPP_F21_IRQ		0x45
+#define GPP_F22_IRQ		0x46
+#define GPP_F23_IRQ		0x47
+/* Group G */
+#define GPP_G0_IRQ		0x48
+#define GPP_G1_IRQ		0x49
+#define GPP_G2_IRQ		0x4a
+#define GPP_G3_IRQ		0x4b
+#define GPP_G4_IRQ		0x4c
+#define GPP_G5_IRQ		0x4d
+#define GPP_G6_IRQ		0x4e
+#define GPP_G7_IRQ		0x4f
+/* Group GPD */
+#define GPD0_IRQ		0x50
+#define GPD1_IRQ		0x51
+#define GPD2_IRQ		0x52
+#define GPD3_IRQ		0x53
+#define GPD4_IRQ		0x54
+#define GPD5_IRQ		0x55
+#define GPD6_IRQ		0x56
+#define GPD7_IRQ		0x57
+#define GPD8_IRQ		0x58
+#define GPD9_IRQ		0x59
+#define GPD10_IRQ		0x5a
+#define GPD11_IRQ		0x5b
+
+/* Register defines. */
+#define MISCCFG_OFFSET		0x10
+#define  GPIO_DRIVER_IRQ_ROUTE_MASK	8
+#define  GPIO_DRIVER_IRQ_ROUTE_IRQ14	0
+#define  GPIO_DRIVER_IRQ_ROUTE_IRQ15	8
+#define  GPE_DW_SHIFT		8
+#define  GPE_DW_MASK		0xfff00
+#define PAD_OWN_REG_OFFSET	0x20
+#define  PAD_OWN_PADS_PER	8
+#define  PAD_OWN_WIDTH_PER	4
+#define  PAD_OWN_MASK		0x03
+#define  PAD_OWN_HOST		0x00
+#define  PAD_OWN_ME		0x01
+#define  PAD_OWN_ISH		0x02
+#define HOSTSW_OWN_REG_OFFSET	0xd0
+#define  HOSTSW_OWN_PADS_PER	24
+#define  HOSTSW_OWN_ACPI	0
+#define  HOSTSW_OWN_GPIO	1
+#define PAD_CFG_DW_OFFSET	0x400
+	/* PADRSTCFG - when to reset the pad config */
+#define  PADRSTCFG_SHIFT	30
+#define  PADRSTCFG_MASK		0x3
+#define  PADRSTCFG_DSW_PWROK	0
+#define  PADRSTCFG_DEEP		1
+#define  PADRSTCFG_PLTRST	2
+#define  PADRSTCFG_RSMRST	3
+	/* RXPADSTSEL - raw signal or internal state */
+#define  RXPADSTSEL_SHIFT	29
+#define  RXPADSTSEL_MASK	0x1
+#define  RXPADSTSEL_RAW		0
+#define  RXPADSTSEL_INTERNAL	1
+	/* RXRAW1 - drive 1 instead instead of pad value */
+#define  RXRAW1_SHIFT		28
+#define  RXRAW1_MASK		0x1
+#define  RXRAW1_NO		0
+#define  RXRAW1_YES		1
+	/* RXEVCFG - Interrupt and wake types */
+#define  RXEVCFG_SHIFT		25
+#define  RXEVCFG_MASK		0x3
+#define  RXEVCFG_LEVEL		0
+#define  RXEVCFG_EDGE		1
+#define  RXEVCFG_DRIVE0		2
+	/* PREGFRXSEL - use filtering on Rx pad */
+#define  PREGFRXSEL_SHIFT	24
+#define  PREGFRXSEL_MASK	0x1
+#define  PREGFRXSEL_NO		0
+#define  PREGFRXSEL_YES		1
+	/* RXINV - invert signal to SMI, SCI, NMI, or IRQ routing. */
+#define  RXINV_SHIFT		23
+#define  RXINV_MASK		0x1
+#define  RXINV_NO		0
+#define  RXINV_YES		1
+	/* GPIROUTIOXAPIC - route to io-xapic or not */
+#define  GPIROUTIOXAPIC_SHIFT	20
+#define  GPIROUTIOXAPIC_MASK	0x1
+#define  GPIROUTIOXAPIC_NO	0
+#define  GPIROUTIOXAPIC_YES	1
+	/* GPIROUTSCI - route to SCI */
+#define  GPIROUTSCI_SHIFT	19
+#define  GPIROUTSCI_MASK	0x1
+#define  GPIROUTSCI_NO		0
+#define  GPIROUTSCI_YES		1
+	/* GPIROUTSMI - route to SMI */
+#define  GPIROUTSMI_SHIFT	18
+#define  GPIROUTSMI_MASK	0x1
+#define  GPIROUTSMI_NO		0
+#define  GPIROUTSMI_YES		1
+	/* GPIROUTNMI - route to NMI */
+#define  GPIROUTNMI_SHIFT	17
+#define  GPIROUTNMI_MASK	0x1
+#define  GPIROUTNMI_NO		0
+#define  GPIROUTNMI_YES		1
+	/* PMODE - mode of pad */
+#define  PMODE_SHIFT		10
+#define  PMODE_MASK		0x3
+#define  PMODE_GPIO		0
+#define  PMODE_NF1		1
+#define  PMODE_NF2		2
+#define  PMODE_NF3		3
+	/* GPIORXDIS - Disable Rx */
+#define  GPIORXDIS_SHIFT	9
+#define  GPIORXDIS_MASK		0x1
+#define  GPIORXDIS_NO		0
+#define  GPIORXDIS_YES		1
+	/* GPIOTXDIS - Disable Tx */
+#define  GPIOTXDIS_SHIFT	8
+#define  GPIOTXDIS_MASK		0x1
+#define  GPIOTXDIS_NO		0
+#define  GPIOTXDIS_YES		1
+	/* GPIORXSTATE - Internal state after glitch filter */
+#define  GPIORXSTATE_SHIFT	1
+#define  GPIORXSTATE_MASK	0x1
+	/* GPIOTXSTATE - Drive value onto pad */
+#define  GPIOTXSTATE_SHIFT	0
+#define  GPIOTXSTATE_MASK	0x1
+#define PAD_CFG_DW_OFFSET	0x400
+	/* TERM - termination control */
+#define  PAD_TERM_SHIFT		10
+#define  PAD_TERM_MASK		0xf
+#define  PAD_TERM_NONE		0
+#define  PAD_TERM_5K_PD		2
+#define  PAD_TERM_20K_PD	4
+#define  PAD_TERM_1K_PU		9
+#define  PAD_TERM_2K_PU		11
+#define  PAD_TERM_5K_PU		10
+#define  PAD_TERM_20K_PU	12
+#define  PAD_TERM_667_PU	13
+#define  PAD_TERM_NATIVE	15
+	/* TOL - voltage tolerance */
+#define  PAD_TOL_SHIFT		25
+#define  PAD_TOL_MASK		0x1
+#define  PAD_TOL_3V3		0	/* 3.3V default */
+#define  PAD_TOL_1V8		1	/* 1.8V tolerant */
+
+#define GPI_GPE_STS_OFFSET	0x140
+#define GPI_GPE_EN_OFFSET	0x160
+#define GPI_SMI_STS_OFFSET	0x180
+#define GPI_SMI_EN_OFFSET	0x1a0
+
+#endif /* _SOC_GPIO_DEFS_H_ */
diff --git a/src/soc/intel/kabylake/include/soc/interrupt.h b/src/soc/intel/kabylake/include/soc/interrupt.h
new file mode 100644
index 0000000..1796a05
--- /dev/null
+++ b/src/soc/intel/kabylake/include/soc/interrupt.h
@@ -0,0 +1,46 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * 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 _INTERRUPT_H_
+#define _INTERRUPT_H_
+
+/* Number of all PCH devices */
+#define PCH_MAX_DEV_INT_CONFIG 64
+
+/* Number of PxRC register in ITSS */
+#define PCH_PARC 0
+#define PCH_PBRC 1
+#define PCH_PCRC 2
+#define PCH_PDRC 3
+#define PCH_PERC 4
+#define PCH_PFRC 5
+#define PCH_PGRC 6
+#define PCH_PHRC 7
+#define PCH_MAX_IRQ_CONFIG 8
+
+#define DEVICE_INT_CONFIG(dev, func, line, irqno) {\
+	.Device = dev, \
+	.Function = func, \
+	.IntX = line, \
+	.Irq = irqno }
+
+#define no_int 0
+#define int_A 1
+#define int_B 2
+#define int_C 3
+#define int_D 4
+
+#endif /* _INTERRUPT_H_ */
diff --git a/src/soc/intel/kabylake/include/soc/iomap.h b/src/soc/intel/kabylake/include/soc/iomap.h
new file mode 100644
index 0000000..70365e8
--- /dev/null
+++ b/src/soc/intel/kabylake/include/soc/iomap.h
@@ -0,0 +1,71 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * 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 _SOC_IOMAP_H_
+#define _SOC_IOMAP_H_
+
+/*
+ * Memory-mapped I/O registers.
+ */
+#define MCFG_BASE_ADDRESS	CONFIG_MMCONF_BASE_ADDRESS
+#define MCFG_BASE_SIZE		0x4000000
+
+#define PCH_PCR_BASE_ADDRESS	0xfd000000
+#define PCH_PCR_BASE_SIZE	0x1000000
+
+#define UART_DEBUG_BASE_ADDRESS	0xfe034000
+#define UART_DEBUG_BASE_SIZE	0x1000
+
+#define EARLY_I2C_BASE_ADDRESS	0xfe040000
+#define EARLY_I2C_BASE(x)	(EARLY_I2C_BASE_ADDRESS + (0x1000 * (x)))
+
+#define MCH_BASE_ADDRESS	0xfed10000
+#define MCH_BASE_SIZE		0x8000
+
+#define DMI_BASE_ADDRESS	0xfed18000
+#define DMI_BASE_SIZE		0x1000
+
+#define EP_BASE_ADDRESS		0xfed19000
+#define EP_BASE_SIZE		0x1000
+
+#define EDRAM_BASE_ADDRESS	0xfed80000
+#define EDRAM_BASE_SIZE		0x4000
+
+#define GDXC_BASE_ADDRESS	0xfed84000
+#define GDXC_BASE_SIZE		0x1000
+
+#define HPET_BASE_ADDRESS	0xfed00000
+
+#define PCH_PWRM_BASE_ADDRESS	0xfe000000
+#define PCH_PWRM_BASE_SIZE	0x10000
+
+#define SPI_BASE_ADDRESS	0xfe010000
+
+#define GPIO_BASE_SIZE		0x10000
+
+/*
+ * I/O port address space
+ */
+#define SMBUS_BASE_ADDRESS	0x0efa0
+#define SMBUS_BASE_SIZE		0x20
+
+#define ACPI_BASE_ADDRESS	0x1800
+#define ACPI_BASE_SIZE		0x100
+
+#define TCO_BASE_ADDDRESS	0x400
+#define TCO_BASE_SIZE		0x20
+
+#endif
diff --git a/src/soc/intel/kabylake/include/soc/irq.h b/src/soc/intel/kabylake/include/soc/irq.h
new file mode 100644
index 0000000..dcc3704
--- /dev/null
+++ b/src/soc/intel/kabylake/include/soc/irq.h
@@ -0,0 +1,103 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * 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 _SOC_IRQ_H_
+#define _SOC_IRQ_H_
+
+#define GPIO_IRQ14 14
+#define GPIO_IRQ15 15
+
+#define PCH_IRQ10 10
+#define PCH_IRQ11 11
+
+#define SCI_IRQ9 9
+#define SCI_IRQ10 10
+#define SCI_IRQ11 11
+#define SCI_IRQ20 20
+#define SCI_IRQ21 21
+#define SCI_IRQ22 22
+#define SCI_IRQ23 23
+
+#define TCO_IRQ9 9
+#define TCO_IRQ10 10
+#define TCO_IRQ11 11
+#define TCO_IRQ20 20
+#define TCO_IRQ21 21
+#define TCO_IRQ22 22
+#define TCO_IRQ23 23
+
+#define LPSS_I2C0_IRQ 16
+#define LPSS_I2C1_IRQ 17
+#define LPSS_I2C2_IRQ 18
+#define LPSS_I2C3_IRQ 19
+#define LPSS_I2C4_IRQ 34
+#define LPSS_I2C5_IRQ 33
+#define LPSS_SPI0_IRQ 22
+#define LPSS_SPI1_IRQ 23
+#define LPSS_UART0_IRQ 20
+#define LPSS_UART1_IRQ 21
+#define LPSS_UART2_IRQ 32
+#define SDIO_IRQ 22
+
+#define cAVS_INTA_IRQ 16
+#define SMBUS_INTA_IRQ 16
+#define SMBUS_INTB_IRQ 17
+#define GbE_INTA_IRQ 16
+#define GbE_INTC_IRQ 18
+#define TRACE_HUB_INTA_IRQ 16
+#define TRACE_HUB_INTD_IRQ 19
+
+#define eMMC_IRQ 21
+#define SD_IRQ 23
+
+#define PCIE_1_IRQ 16
+#define PCIE_2_IRQ 17
+#define PCIE_3_IRQ 18
+#define PCIE_4_IRQ 19
+#define PCIE_5_IRQ 16
+#define PCIE_6_IRQ 17
+#define PCIE_7_IRQ 18
+#define PCIE_8_IRQ 19
+#define PCIE_9_IRQ 16
+#define PCIE_10_IRQ 17
+#define PCIE_11_IRQ 18
+#define PCIE_12_IRQ 19
+
+#define SATA_IRQ 16
+
+#define HECI_1_IRQ 16
+#define HECI_2_IRQ 17
+#define IDER_IRQ 18
+#define KT_IRQ 19
+#define HECI_3_IRQ 16
+
+#define XHCI_IRQ 16
+#define OTG_IRQ 17
+#define THRMAL_IRQ 18
+#define CIO_INTA_IRQ 16
+#define CIO_INTD_IRQ 19
+#define ISH_IRQ 20
+
+#define PEG_RP_INTA_IRQ 16
+#define PEG_RP_INTB_IRQ 17
+#define PEG_RP_INTC_IRQ 18
+#define PEG_RP_INTD_IRQ 19
+
+#define IGFX_IRQ 16
+#define SA_THERMAL_IRQ 16
+#define SKYCAM_IRQ 16
+#define GMM_IRQ 16
+#endif /* _SOC_IRQ_H_ */
diff --git a/src/soc/intel/kabylake/include/soc/lpc.h b/src/soc/intel/kabylake/include/soc/lpc.h
new file mode 100644
index 0000000..526c710
--- /dev/null
+++ b/src/soc/intel/kabylake/include/soc/lpc.h
@@ -0,0 +1,58 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * 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 _SOC_LPC_H_
+#define _SOC_LPC_H_
+
+/* PCI Configuration Space (D31:F0): LPC */
+#define ABASE			0x40
+#define ACNTL			0x44
+#define  ACPI_EN		(1 << 7)
+#define  SCI_IRQ_SEL		(7 << 0)
+#define  SCIS_IRQ9		0
+#define  SCIS_IRQ10		1
+#define  SCIS_IRQ11		2
+#define  SCIS_IRQ20		4
+#define  SCIS_IRQ21		5
+#define  SCIS_IRQ22		6
+#define  SCIS_IRQ23		7
+#define SERIRQ_CNTL		0x64
+#define LPC_IO_DEC		0x80 /* IO Decode Ranges Register */
+#define  COMA_RANGE		0x0 /* 0x3F8 - 0x3FF COM1*/
+#define  COMB_RANGE		0x1 /* 0x2F8 - 0x2FF COM2*/
+#define LPC_EN			0x82 /* LPC IF Enables Register */
+#define  CNF2_LPC_EN		(1 << 13) /* 0x4e/0x4f */
+#define  CNF1_LPC_EN		(1 << 12) /* 0x2e/0x2f */
+#define  MC_LPC_EN		(1 << 11) /* 0x62/0x66 */
+#define  KBC_LPC_EN		(1 << 10) /* 0x60/0x64 */
+#define  GAMEH_LPC_EN		(1 << 9)  /* 0x208/0x20f */
+#define  GAMEL_LPC_EN		(1 << 8)  /* 0x200/0x207 */
+#define  FDD_LPC_EN		(1 << 3)  /* LPC_IO_DEC[12] */
+#define  LPT_LPC_EN		(1 << 2)  /* LPC_IO_DEC[9:8] */
+#define  COMB_LPC_EN		(1 << 1)  /* LPC_IO_DEC[6:4] */
+#define  COMA_LPC_EN		(1 << 0)  /* LPC_IO_DEC[2:0] */
+#define LPC_GEN1_DEC		0x84 /* LPC IF Generic Decode Range 1 */
+#define LPC_GEN2_DEC		0x88 /* LPC IF Generic Decode Range 2 */
+#define LPC_GEN3_DEC		0x8c /* LPC IF Generic Decode Range 3 */
+#define LPC_GEN4_DEC		0x90 /* LPC IF Generic Decode Range 4 */
+#define LGMR			0x98 /* LPC Generic Memory Range */
+#define BIOS_CNTL		0xdc
+#define  LPC_BC_BILD		(1 << 7) /* BILD */
+#define  LPC_BC_LE		(1 << 2) /* LE */
+#define  LPC_BC_EISS		(1 << 5) /* EISS */
+#define PCCTL			0xE0 /* PCI Clock Control */
+#define CLKRUN_EN		(1 << 0)
+#endif
diff --git a/src/soc/intel/kabylake/include/soc/me.h b/src/soc/intel/kabylake/include/soc/me.h
new file mode 100644
index 0000000..d92b835
--- /dev/null
+++ b/src/soc/intel/kabylake/include/soc/me.h
@@ -0,0 +1,182 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008-2009 coresystems GmbH
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 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 _KABYLAKE_ME_H_
+#define _KABYLAKE_ME_H_
+
+/*
+ * Management Engine PCI registers
+ */
+#define PCI_ME_HFSTS1		0x40
+#define  ME_HFS_CWS_RESET	0
+#define  ME_HFS_CWS_INIT	1
+#define  ME_HFS_CWS_REC		2
+#define  ME_HFS_CWS_NORMAL	5
+#define  ME_HFS_CWS_WAIT	6
+#define  ME_HFS_CWS_TRANS	7
+#define  ME_HFS_CWS_INVALID	8
+#define  ME_HFS_STATE_PREBOOT	0
+#define  ME_HFS_STATE_M0_UMA	1
+#define  ME_HFS_STATE_M3	4
+#define  ME_HFS_STATE_M0	5
+#define  ME_HFS_STATE_BRINGUP	6
+#define  ME_HFS_STATE_ERROR	7
+#define  ME_HFS_ERROR_NONE	0
+#define  ME_HFS_ERROR_UNCAT	1
+#define  ME_HFS_ERROR_IMAGE	3
+#define  ME_HFS_ERROR_DEBUG	4
+#define  ME_HFS_MODE_NORMAL	0
+#define  ME_HFS_MODE_DEBUG	2
+#define  ME_HFS_MODE_DIS	3
+#define  ME_HFS_MODE_OVER_JMPR	4
+#define  ME_HFS_MODE_OVER_MEI	5
+#define  ME_HFS_BIOS_DRAM_ACK	1
+#define  ME_HFS_POWER_SOURCE_AC 1
+#define  ME_HFS_POWER_SOURCE_DC 2
+
+struct me_hfs {
+	u32 working_state: 4;
+	u32 mfg_mode: 1;
+	u32 fpt_bad: 1;
+	u32 operation_state: 3;
+	u32 fw_init_complete: 1;
+	u32 ft_bup_ld_flr: 1;
+	u32 update_in_progress: 1;
+	u32 error_code: 4;
+	u32 operation_mode: 4;
+	u32 reset_count: 4;
+	u32 boot_options_present: 1;
+	u32 reserved1: 1;
+	u32 bist_test_state: 1;
+	u32 bist_reset_request: 1;
+	u32 current_power_source: 2;
+	u32 d3_support_valid: 1;
+	u32 d0i3_support_valid: 1;
+} __attribute__ ((packed));
+
+#define PCI_ME_HFSTS2		0x48
+/* Infrastructure Progress Values */
+#define  ME_HFS2_PHASE_ROM		0
+#define  ME_HFS2_PHASE_UKERNEL		2
+#define  ME_HFS2_PHASE_BUP		3
+#define  ME_HFS2_PHASE_HOST_COMM	6
+/* Current State - Based on Infra Progress values. */
+/* ROM State */
+#define  ME_HFS2_STATE_ROM_BEGIN 0
+#define  ME_HFS2_STATE_ROM_DISABLE 6
+/* BUP State */
+#define  ME_HFS2_STATE_BUP_INIT 0
+#define  ME_HFS2_STATE_BUP_DIS_HOST_WAKE 1
+#define  ME_HFS2_STATE_BUP_CG_ENABLE 2
+#define  ME_HFS2_STATE_BUP_PM_HND_EN 3
+#define  ME_HFS2_STATE_BUP_FLOW_DET 4
+#define  ME_HFS2_STATE_BUP_PMC_PATCHING 5
+#define  ME_HFS2_STATE_BUP_GET_FLASH_VSCC 6
+#define  ME_HFS2_STATE_BUP_SET_FLASH_VSCC 7
+#define  ME_HFS2_STATE_BUP_VSCC_ERR 8
+#define  ME_HFS2_STATE_BUP_EFSS_INIT 9
+#define  ME_HFS2_STATE_BUP_CHECK_STRAP 0xa
+#define  ME_HFS2_STATE_BUP_PWR_OK_TIMEOUT 0xb
+#define  ME_HFS2_STATE_BUP_STRAP_DIS 0xc
+#define  ME_HFS2_STATE_BUP_MANUF_OVRD_STRAP 0xd
+#define  ME_HFS2_STATE_BUP_M3 0x11
+#define  ME_HFS2_STATE_BUP_M0 0x12
+#define  ME_HFS2_STATE_BUP_FLOW_DET_ERR 0x13
+#define  ME_HFS2_STATE_BUP_M3_CLK_ERR 0x15
+#define  ME_HFS2_STATE_BUP_CPU_RESET_DID_TIMEOUT_MEM_MISSING 0x17
+#define  ME_HFS2_STATE_BUP_M3_KERN_LOAD 0x18
+#define  ME_HFS2_STATE_BUP_T32_MISSING 0x1c
+#define  ME_HFS2_STATE_BUP_WAIT_DID 0x1f
+#define  ME_HFS2_STATE_BUP_WAIT_DID_FAIL 0x20
+#define  ME_HFS2_STATE_BUP_DID_NO_FAIL 0x21
+#define  ME_HFS2_STATE_BUP_ENABLE_UMA 0x22
+#define  ME_HFS2_STATE_BUP_ENABLE_UMA_ERR 0x23
+#define  ME_HFS2_STATE_BUP_SEND_DID_ACK 0x24
+#define  ME_HFS2_STATE_BUP_SEND_DID_ACK_ERR 0x25
+#define  ME_HFS2_STATE_BUP_M0_CLK 0x26
+#define  ME_HFS2_STATE_BUP_M0_CLK_ERR 0x27
+#define  ME_HFS2_STATE_BUP_TEMP_DIS 0x28
+#define  ME_HFS2_STATE_BUP_M0_KERN_LOAD 0x32
+/* Policy Module State */
+#define  ME_HFS2_STATE_POLICY_ENTRY 0
+#define  ME_HFS2_STATE_POLICY_RCVD_S3 3
+#define  ME_HFS2_STATE_POLICY_RCVD_S4 4
+#define  ME_HFS2_STATE_POLICY_RCVD_S5 5
+#define  ME_HFS2_STATE_POLICY_RCVD_UPD 6
+#define  ME_HFS2_STATE_POLICY_RCVD_PCR 7
+#define  ME_HFS2_STATE_POLICY_RCVD_NPCR 8
+#define  ME_HFS2_STATE_POLICY_RCVD_HOST_WAKE 9
+#define  ME_HFS2_STATE_POLICY_RCVD_AC_DC 0xa
+#define  ME_HFS2_STATE_POLICY_RCVD_DID 0xb
+#define  ME_HFS2_STATE_POLICY_VSCC_NOT_FOUND 0xc
+#define  ME_HFS2_STATE_POLICY_VSCC_INVALID 0xd
+#define  ME_HFS2_STATE_POLICY_FPB_ERR 0xe
+#define  ME_HFS2_STATE_POLICY_DESCRIPTOR_ERR 0xf
+#define  ME_HFS2_STATE_POLICY_VSCC_NO_MATCH 0x10
+/* Current PM Event Values */
+#define  ME_HFS2_PMEVENT_CLEAN_MOFF_MX_WAKE 0
+#define  ME_HFS2_PMEVENT_MOFF_MX_WAKE_ERROR 1
+#define  ME_HFS2_PMEVENT_CLEAN_GLOBAL_RESET 2
+#define  ME_HFS2_PMEVENT_CLEAN_GLOBAL_RESET_ERROR 3
+#define  ME_HFS2_PMEVENT_CLEAN_ME_RESET 4
+#define  ME_HFS2_PMEVENT_ME_RESET_EXCEPTION 5
+#define  ME_HFS2_PMEVENT_PSEUDO_ME_RESET 6
+#define  ME_HFS2_PMEVENT_CM0_CM3 7
+#define  ME_HFS2_PMEVENT_CM3_CM0 8
+#define  ME_HFS2_PMEVENT_NON_PWR_CYCLE_RESET 9
+#define  ME_HFS2_PMEVENT_PWR_CYCLE_RESET_M3 0xa
+#define  ME_HFS2_PMEVENT_PWR_CYCLE_RESET_MOFF 0xb
+#define  ME_HFS2_PMEVENT_CMX_CMOFF 0xc
+#define  ME_HFS2_PMEVENT_CM0_CM0PG 0xd
+#define  ME_HFS2_PMEVENT_CM3_CM3PG 0xe
+#define  ME_HFS2_PMEVENT_CM0PG_CM0 0xf
+
+struct me_hfs2 {
+	u32 reserved1: 3;
+	u32 invoke_mebx: 1;
+	u32 cpu_replaced_sts: 1;
+	u32 reserved2: 1;
+	u32 mfs_failure: 1;
+	u32 warm_reset_request: 1;
+	u32 cpu_replaced_valid: 1;
+	u32 low_power_state: 1;
+	u32 power_gating_ind: 1;
+	u32 reserved3: 1;
+	u32 fw_upd_forced_sb: 1;
+	u32 reserved4: 3;
+	u32 current_state: 8;
+	u32 current_pmevent: 4;
+	u32 progress_code: 4;
+} __attribute__ ((packed));
+
+#define PCI_ME_HFSTS3			0x60
+#define  ME_HFS3_FW_SKU_CONSUMER	0x2
+#define  ME_HFS3_FW_SKU_CORPORATE	0x3
+
+struct me_hfs3 {
+	u32 reserved1: 4;
+	u32 fw_sku: 3;
+	u32 encrypt_key_check: 1;
+	u32 pch_config_change: 1;
+	u32 reserved2: 21;
+	u32 encrypt_key_override: 1;
+	u32 power_down_mitigation: 1;
+} __attribute__ ((packed));
+
+void intel_me_status(void);
+
+#endif
diff --git a/src/soc/intel/kabylake/include/soc/msr.h b/src/soc/intel/kabylake/include/soc/msr.h
new file mode 100644
index 0000000..4f7d440
--- /dev/null
+++ b/src/soc/intel/kabylake/include/soc/msr.h
@@ -0,0 +1,109 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * 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 _SOC_MSR_H_
+#define _SOC_MSR_H_
+
+#define MSR_PIC_MSG_CONTROL		0x2e
+#define CORE_THREAD_COUNT_MSR		0x35
+#define IA32_FEATURE_CONTROL		0x3a
+#define  CPUID_VMX			(1 << 5)
+#define  CPUID_SMX			(1 << 6)
+#define MSR_PLATFORM_INFO		0xce
+#define  PLATFORM_INFO_SET_TDP		(1 << 29)
+#define MSR_PMG_CST_CONFIG_CONTROL	0xe2
+#define MSR_PMG_IO_CAPTURE_BASE		0xe4
+#define MSR_FEATURE_CONFIG		0x13c
+#define SMM_MCA_CAP_MSR			0x17d
+#define  SMM_CPU_SVRSTR_BIT		57
+#define  SMM_CPU_SVRSTR_MASK		(1 << (SMM_CPU_SVRSTR_BIT - 32))
+#define MSR_FLEX_RATIO			0x194
+#define  FLEX_RATIO_LOCK		(1 << 20)
+#define  FLEX_RATIO_EN			(1 << 16)
+#define IA32_MISC_ENABLE		0x1a0
+#define MSR_MISC_PWR_MGMT		0x1aa
+#define  MISC_PWR_MGMT_EIST_HW_DIS	(1 << 0)
+#define  MISC_PWR_MGMT_ISST_EN	(1 << 6)
+#define  MISC_PWR_MGMT_ISST_EN_INT	(1 << 7)
+#define  MISC_PWR_MGMT_ISST_EN_EPP	(1 << 12)
+#define MSR_TURBO_RATIO_LIMIT		0x1ad
+#define MSR_TEMPERATURE_TARGET		0x1a2
+#define IA32_PERF_CTL			0x199
+#define IA32_THERM_INTERRUPT		0x19b
+#define IA32_ENERGY_PERFORMANCE_BIAS	0x1b0
+#define  ENERGY_POLICY_PERFORMANCE	0
+#define  ENERGY_POLICY_NORMAL		6
+#define  ENERGY_POLICY_POWERSAVE	15
+#define IA32_PACKAGE_THERM_INTERRUPT	0x1b2
+#define EMRR_PHYS_BASE_MSR		0x1f4
+#define EMRR_PHYS_MASK_MSR		0x1f5
+#define IA32_PLATFORM_DCA_CAP		0x1f8
+#define MSR_POWER_CTL			0x1fc
+#define MSR_LT_LOCK_MEMORY		0x2e7
+#define UNCORE_PRMRR_PHYS_BASE_MSR	0x2f4
+#define UNCORE_PRMRR_PHYS_MASK_MSR	0x2f5
+#define IA32_MC0_STATUS			0x401
+#define SMM_FEATURE_CONTROL_MSR		0x4e0
+#define  SMM_CPU_SAVE_EN		(1 << 1)
+
+#define MSR_C_STATE_LATENCY_CONTROL_0	0x60a
+#define MSR_C_STATE_LATENCY_CONTROL_1	0x60b
+#define MSR_C_STATE_LATENCY_CONTROL_2	0x60c
+#define MSR_C_STATE_LATENCY_CONTROL_3	0x633
+#define MSR_C_STATE_LATENCY_CONTROL_4	0x634
+#define MSR_C_STATE_LATENCY_CONTROL_5	0x635
+#define  IRTL_VALID			(1 << 15)
+#define  IRTL_1_NS			(0 << 10)
+#define  IRTL_32_NS			(1 << 10)
+#define  IRTL_1024_NS			(2 << 10)
+#define  IRTL_32768_NS			(3 << 10)
+#define  IRTL_1048576_NS		(4 << 10)
+#define  IRTL_33554432_NS		(5 << 10)
+#define  IRTL_RESPONSE_MASK		(0x3ff)
+#define MSR_COUNTER_24_MHZ		0x637
+
+/* long duration in low dword, short duration in high dword */
+#define MSR_PKG_POWER_LIMIT		0x610
+#define  PKG_POWER_LIMIT_MASK		0x7fff
+#define  PKG_POWER_LIMIT_EN		(1 << 15)
+#define  PKG_POWER_LIMIT_CLAMP		(1 << 16)
+#define  PKG_POWER_LIMIT_TIME_SHIFT	17
+#define  PKG_POWER_LIMIT_TIME_MASK	0x7f
+
+#define MSR_VR_CURRENT_CONFIG		0x601
+#define MSR_VR_MISC_CONFIG		0x603
+#define MSR_PKG_POWER_SKU_UNIT		0x606
+#define MSR_PKG_POWER_SKU		0x614
+#define MSR_DDR_RAPL_LIMIT		0x618
+#define MSR_VR_MISC_CONFIG2		0x636
+#define MSR_PP0_POWER_LIMIT		0x638
+#define MSR_PP1_POWER_LIMIT		0x640
+
+#define MSR_CONFIG_TDP_NOMINAL		0x648
+#define MSR_CONFIG_TDP_LEVEL1		0x649
+#define MSR_CONFIG_TDP_LEVEL2		0x64a
+#define MSR_CONFIG_TDP_CONTROL		0x64b
+#define MSR_TURBO_ACTIVATION_RATIO	0x64c
+
+/* SMM save state MSRs */
+#define SMBASE_MSR			0xc20
+#define IEDBASE_MSR			0xc22
+
+/* MTRR_CAP_MSR bits */
+#define SMRR_SUPPORTED (1<<11)
+#define PRMRR_SUPPORTED (1<<12)
+
+#endif
diff --git a/src/soc/intel/kabylake/include/soc/nhlt.h b/src/soc/intel/kabylake/include/soc/nhlt.h
new file mode 100644
index 0000000..ae74f53
--- /dev/null
+++ b/src/soc/intel/kabylake/include/soc/nhlt.h
@@ -0,0 +1,63 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2015 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.
+ */
+
+#ifndef _SOC_NHLT_H_
+#define _SOC_NHLT_H_
+
+#include <nhlt.h>
+
+#define NHLT_VID 0x8086
+#define NHLT_DID_DMIC 0xae20
+#define NHLT_DID_BT 0xae30
+#define NHLT_DID_SSP 0xae34
+
+/*
+ * Kabylake NHLT link types. These values are to be used for the hwlink
+ * fields in the functions below to specify which link a device is on.
+ */
+
+enum {
+	AUDIO_LINK_SSP0,
+	AUDIO_LINK_SSP1,
+	AUDIO_LINK_SSP2, /* Only Bluetooth supported on SSP2. */
+	AUDIO_LINK_DMIC,
+};
+
+/*
+ * Add a dmic array composed of the provided number of channels. The kabylake
+ * SoC currently only supports dmic arrays on the dmic signals. Either 2
+ * or 4 channel arrays are supported. Returns 0 on success, < 0 on error.
+ */
+int nhlt_soc_add_dmic_array(struct nhlt *nhlt, int num_channels);
+
+/*
+ * Add nau88l25 headset codec on provided SSP link. Return 0 on succes, < 0
+ * on error.
+ */
+int nhlt_soc_add_nau88l25(struct nhlt *nhlt, int hwlink);
+
+/*
+ * Add ssm4567 smart amplifiers in stereo configuration on provided SSP link.
+ * Return 0 on success, < 0 on error.
+ */
+int nhlt_soc_add_ssm4567(struct nhlt *nhlt, int hwlink);
+
+/*
+ * Add max98357a amplifier in stereo configuration on provide SSP link.
+ * Return 0 on success, < 0 on error.
+ */
+int nhlt_soc_add_max98357(struct nhlt *nhlt, int hwlink);
+
+#endif
diff --git a/src/soc/intel/kabylake/include/soc/nvs.h b/src/soc/intel/kabylake/include/soc/nvs.h
new file mode 100644
index 0000000..5af840f
--- /dev/null
+++ b/src/soc/intel/kabylake/include/soc/nvs.h
@@ -0,0 +1,68 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008-2009 coresystems GmbH
+ * Copyright (C) 2014 Google Inc.
+ * 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 _SOC_NVS_H_
+#define _SOC_NVS_H_
+
+#include <rules.h>
+#include <vendorcode/google/chromeos/gnvs.h>
+
+typedef struct {
+	/* Miscellaneous */
+	u16	osys; /* 0x00 - Operating System */
+	u8	smif; /* 0x02 - SMI function call ("TRAP") */
+	u8	prm0; /* 0x03 - SMI function call parameter */
+	u8	prm1; /* 0x04 - SMI function call parameter */
+	u8	scif; /* 0x05 - SCI function call (via _L00) */
+	u8	prm2; /* 0x06 - SCI function call parameter */
+	u8	prm3; /* 0x07 - SCI function call parameter */
+	u8	lckf; /* 0x08 - Global Lock function for EC */
+	u8	prm4; /* 0x09 - Lock function parameter */
+	u8	prm5; /* 0x0a - Lock function parameter */
+	u8      pcnt; /* 0x0b - Processor Count */
+	u8	ppcm; /* 0x0c - Max PPC State */
+	u8	tmps; /* 0x0d - Temperature Sensor ID */
+	u8	tlvl; /* 0x0e - Throttle Level Limit */
+	u8	flvl; /* 0x0f - Current FAN Level */
+	u8	tcrt; /* 0x10 - Critical Threshold */
+	u8	tpsv; /* 0x11 - Passive Threshold */
+	u8	tmax; /* 0x12 - CPU Tj_max */
+	u8	s5u0; /* 0x13 - Enable USB in S5 */
+	u8	s3u0; /* 0x14 - Enable USB in S3 */
+	u8	s33g; /* 0x15 - Enable 3G in S3 */
+	u8	lids; /* 0x16 - LID State */
+	u8	pwrs; /* 0x17 - AC Power State */
+	u32	cmem; /* 0x18 - 0x1b - CBMEM TOC */
+	u32	cbmc; /* 0x1c - 0x1f - Coreboot Memory Console */
+	u64	pm1i; /* 0x20 - 0x27 - PM1 wake status bit */
+	u64	gpei; /* 0x28 - 0x2f - GPE wake status bit */
+	u8	dpte; /* 0x30 - Enable DPTF */
+	u64	nhla; /* 0x31 - NHLT Address */
+	u32	nhll; /* 0x39 - NHLT Length */
+	u16	cid1; /* 0x3d - Wifi Country Identifier */
+	u8	unused[193];
+
+	/* ChromeOS specific (0x100 - 0xfff) */
+	chromeos_acpi_t chromeos;
+} __attribute__((packed)) global_nvs_t;
+
+#if ENV_SMM
+/* Used in SMM to find the ACPI GNVS address */
+global_nvs_t *smm_get_gnvs(void);
+#endif
+
+#endif
diff --git a/src/soc/intel/kabylake/include/soc/pch.h b/src/soc/intel/kabylake/include/soc/pch.h
new file mode 100644
index 0000000..4a7c85e
--- /dev/null
+++ b/src/soc/intel/kabylake/include/soc/pch.h
@@ -0,0 +1,38 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008-2009 coresystems GmbH
+ * Copyright (C) 2014 Google Inc.
+ * 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 _SOC_PCH_H_
+#define _SOC_PCH_H_
+
+#include <device/device.h>
+#include <rules.h>
+
+/* PCH (SunRisePoint LP) */
+#define PCH_SPT_LP_SAMPLE		0x9d41
+#define PCH_SPT_LP_U_BASE		0x9d43
+#define PCH_SPT_LP_U_PREMIUM		0x9d48
+#define PCH_SPT_LP_Y_PREMIUM		0x9d46
+
+u8 pch_revision(void);
+u16 pch_type(void);
+u32 pch_read_soft_strap(int id);
+void pch_log_state(void);
+#if ENV_RAMSTAGE
+void pch_disable_devfn(device_t dev);
+#endif
+
+#endif /* _SOC_PCH_H_ */
diff --git a/src/soc/intel/kabylake/include/soc/pci_devs.h b/src/soc/intel/kabylake/include/soc/pci_devs.h
new file mode 100644
index 0000000..5f0b0f9
--- /dev/null
+++ b/src/soc/intel/kabylake/include/soc/pci_devs.h
@@ -0,0 +1,179 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * 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 _SOC_PCI_DEVS_H_
+#define _SOC_PCI_DEVS_H_
+
+#include <device/pci_def.h>
+#include <rules.h>
+
+#define _SA_DEVFN(slot)		PCI_DEVFN(SA_DEV_SLOT_ ## slot, 0)
+#define _PCH_DEVFN(slot, func)	PCI_DEVFN(PCH_DEV_SLOT_ ## slot, func)
+
+#if ENV_RAMSTAGE
+#include <device/device.h>
+#include <device/pci_def.h>
+#define _SA_DEV(slot)		dev_find_slot(0, _SA_DEVFN(slot))
+#define _PCH_DEV(slot, func)	dev_find_slot(0, _PCH_DEVFN(slot, func))
+#else
+#include <arch/io.h>
+#define _SA_DEV(slot)		PCI_DEV(0, SA_DEV_SLOT_ ## slot, 0)
+#define _PCH_DEV(slot, func)	PCI_DEV(0, PCH_DEV_SLOT_ ## slot, func)
+#endif
+
+/* System Agent Devices */
+
+#define SA_DEV_SLOT_ROOT	0x00
+#define  SA_DEVFN_ROOT		_SA_DEVFN(ROOT)
+#define  SA_DEV_ROOT		_SA_DEV(ROOT)
+
+#define SA_DEV_SLOT_IGD		0x02
+#define  SA_DEVFN_IGD		_SA_DEVFN(IGD)
+#define  SA_DEV_IGD		_SA_DEV(IGD)
+
+#define SA_DEV_SLOT_DSP		0x04
+#define  SA_DEVFN_DSP		_SA_DEVFN(DSP)
+#define  SA_DEV_DSP		_SA_DEV(DSP)
+
+/* PCH Devices */
+
+#define PCH_DEV_SLOT_ISH	0x13
+#define  PCH_DEVFN_ISH		_PCH_DEVFN(ISH, 0)
+
+#define PCH_DEV_SLOT_XHCI	0x14
+#define  PCH_DEVFN_XHCI		_PCH_DEVFN(XHCI, 0)
+#define  PCH_DEVFN_USBOTG	_PCH_DEVFN(XHCI, 1)
+#define  PCH_DEVFN_THERMAL	_PCH_DEVFN(XHCI, 2)
+#define  PCH_DEVFN_CIO		_PCH_DEVFN(XHCI, 3)
+#define  PCH_DEV_XHCI		_PCH_DEV(XHCI, 0)
+#define  PCH_DEV_USBOTG		_PCH_DEV(XHCI, 1)
+#define  PCH_DEV_THERMAL	_PCH_DEV(XHCI, 2)
+
+#define PCH_DEV_SLOT_SIO1	0x15
+#define  PCH_DEVFN_I2C0		_PCH_DEVFN(SIO1, 0)
+#define  PCH_DEVFN_I2C1		_PCH_DEVFN(SIO1, 1)
+#define  PCH_DEVFN_I2C2		_PCH_DEVFN(SIO1, 2)
+#define  PCH_DEVFN_I2C3		_PCH_DEVFN(SIO1, 3)
+#define  PCH_DEV_I2C0		_PCH_DEV(SIO1, 0)
+#define  PCH_DEV_I2C1		_PCH_DEV(SIO1, 1)
+#define  PCH_DEV_I2C2		_PCH_DEV(SIO1, 2)
+#define  PCH_DEV_I2C3		_PCH_DEV(SIO1, 3)
+
+#define PCH_DEV_SLOT_ME		0x16
+#define  PCH_DEVFN_ME		_PCH_DEVFN(ME, 0)
+#define  PCH_DEVFN_ME_2		_PCH_DEVFN(ME, 1)
+#define  PCH_DEVFN_ME_IDER	_PCH_DEVFN(ME, 2)
+#define  PCH_DEVFN_ME_KT	_PCH_DEVFN(ME, 3)
+#define  PCH_DEVFN_ME_3		_PCH_DEVFN(ME, 4)
+#define  PCH_DEV_ME		_PCH_DEV(ME, 0)
+#define  PCH_DEV_ME_2		_PCH_DEV(ME, 1)
+#define  PCH_DEV_ME_IDER	_PCH_DEV(ME, 2)
+#define  PCH_DEV_ME_KT		_PCH_DEV(ME, 3)
+#define  PCH_DEV_ME_3		_PCH_DEV(ME, 4)
+
+#define PCH_DEV_SLOT_SATA	0x17
+#define  PCH_DEVFN_SATA		_PCH_DEVFN(SATA, 0)
+#define  PCH_DEV_SATA		_PCH_DEV(SATA, 0)
+
+#define PCH_DEV_SLOT_SIO2	0x19
+#define  PCH_DEVFN_UART2	_PCH_DEVFN(SIO2, 0)
+#define  PCH_DEVFN_I2C5		_PCH_DEVFN(SIO2, 1)
+#define  PCH_DEVFN_I2C4		_PCH_DEVFN(SIO2, 2)
+#define  PCH_DEV_UART2		_PCH_DEV(SIO2, 0)
+#define  PCH_DEV_I2C5		_PCH_DEV(SIO2, 1)
+#define  PCH_DEV_I2C4		_PCH_DEV(SIO2, 2)
+
+#define PCH_DEV_SLOT_PCIE	0x1c
+#define  PCH_DEVFN_PCIE1	_PCH_DEVFN(PCIE, 0)
+#define  PCH_DEVFN_PCIE2	_PCH_DEVFN(PCIE, 1)
+#define  PCH_DEVFN_PCIE3	_PCH_DEVFN(PCIE, 2)
+#define  PCH_DEVFN_PCIE4	_PCH_DEVFN(PCIE, 3)
+#define  PCH_DEVFN_PCIE5	_PCH_DEVFN(PCIE, 4)
+#define  PCH_DEVFN_PCIE6	_PCH_DEVFN(PCIE, 5)
+#define  PCH_DEVFN_PCIE7	_PCH_DEVFN(PCIE, 6)
+#define  PCH_DEVFN_PCIE8	_PCH_DEVFN(PCIE, 7)
+#define  PCH_DEV_PCIE1		_PCH_DEV(PCIE, 0)
+#define  PCH_DEV_PCIE2		_PCH_DEV(PCIE, 1)
+#define  PCH_DEV_PCIE3		_PCH_DEV(PCIE, 2)
+#define  PCH_DEV_PCIE4		_PCH_DEV(PCIE, 3)
+#define  PCH_DEV_PCIE5		_PCH_DEV(PCIE, 4)
+#define  PCH_DEV_PCIE6		_PCH_DEV(PCIE, 5)
+
+#define PCH_DEV_SLOT_PCIE_1	0x1d
+#define  PCH_DEVFN_PCIE9	_PCH_DEVFN(PCIE_1, 0)
+#define  PCH_DEVFN_PCIE10	_PCH_DEVFN(PCIE_1, 1)
+#define  PCH_DEVFN_PCIE11	_PCH_DEVFN(PCIE_1, 2)
+#define  PCH_DEVFN_PCIE12	_PCH_DEVFN(PCIE_1, 3)
+
+#define PCH_DEV_SLOT_STORAGE	0x1e
+#define  PCH_DEVFN_UART0	_PCH_DEVFN(STORAGE, 0)
+#define  PCH_DEVFN_UART1	_PCH_DEVFN(STORAGE, 1)
+#define  PCH_DEVFN_GSPI0	_PCH_DEVFN(STORAGE, 2)
+#define  PCH_DEVFN_GSPI1	_PCH_DEVFN(STORAGE, 3)
+#define  PCH_DEVFN_EMMC		_PCH_DEVFN(STORAGE, 4)
+#define  PCH_DEVFN_SDIO		_PCH_DEVFN(STORAGE, 5)
+#define  PCH_DEVFN_SDCARD	_PCH_DEVFN(STORAGE, 6)
+#define  PCH_DEV_UART0		_PCH_DEV(STORAGE, 0)
+#define  PCH_DEV_UART1		_PCH_DEV(STORAGE, 1)
+#define  PCH_DEV_EMMC		_PCH_DEV(STORAGE, 4)
+#define  PCH_DEV_SDCARD		_PCH_DEV(STORAGE, 6)
+
+#define PCH_DEV_SLOT_LPC	0x1f
+#define  PCH_DEVFN_LPC		_PCH_DEVFN(LPC, 0)
+#define  PCH_DEVFN_P2SB         _PCH_DEVFN(LPC, 1)
+#define  PCH_DEVFN_PMC		_PCH_DEVFN(LPC, 2)
+#define  PCH_DEVFN_HDA		_PCH_DEVFN(LPC, 3)
+#define  PCH_DEVFN_SMBUS	_PCH_DEVFN(LPC, 4)
+#define  PCH_DEVFN_SPI		_PCH_DEVFN(LPC, 5)
+#define  PCH_DEVFN_GBE		_PCH_DEVFN(LPC, 6)
+#define  PCH_DEVFN_TRACEHUB	_PCH_DEVFN(LPC, 7)
+#define  PCH_DEV_LPC		_PCH_DEV(LPC, 0)
+#define  PCH_DEV_P2SB		_PCH_DEV(LPC, 1)
+#define  PCH_DEV_PMC		_PCH_DEV(LPC, 2)
+#define  PCH_DEV_HDA		_PCH_DEV(LPC, 3)
+#define  PCH_DEV_SMBUS		_PCH_DEV(LPC, 4)
+#define  PCH_DEV_SPI		_PCH_DEV(LPC, 5)
+#define  PCH_DEV_GBE		_PCH_DEV(LPC, 6)
+
+/* Convert I2C bus number to PCI device and function */
+static inline int i2c_bus_to_devfn(unsigned bus)
+{
+	switch (bus) {
+	case 0: return PCH_DEVFN_I2C0;
+	case 1: return PCH_DEVFN_I2C1;
+	case 2: return PCH_DEVFN_I2C2;
+	case 3: return PCH_DEVFN_I2C3;
+	case 4: return PCH_DEVFN_I2C4;
+	case 5: return PCH_DEVFN_I2C5;
+	}
+	return -1;
+}
+
+/* Convert PCI device and function to I2C bus number */
+static inline int i2c_devfn_to_bus(unsigned devfn)
+{
+	switch (devfn) {
+	case PCH_DEVFN_I2C0: return 0;
+	case PCH_DEVFN_I2C1: return 1;
+	case PCH_DEVFN_I2C2: return 2;
+	case PCH_DEVFN_I2C3: return 3;
+	case PCH_DEVFN_I2C4: return 4;
+	case PCH_DEVFN_I2C5: return 5;
+	}
+	return -1;
+}
+
+#endif
diff --git a/src/soc/intel/kabylake/include/soc/pcr.h b/src/soc/intel/kabylake/include/soc/pcr.h
new file mode 100644
index 0000000..78dd319
--- /dev/null
+++ b/src/soc/intel/kabylake/include/soc/pcr.h
@@ -0,0 +1,120 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * 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 _SOC_PCR_H_
+#define _SOC_PCR_H_
+
+/*
+ * Primary to sideband (P2SB) for private configuration registers (PCR).
+ */
+
+/* Port Id lives in bits 23:16 and register offset lives in 15:0 of address. */
+#define PCR_PORTID_SHIFT	16
+#define PCR_OFFSET_SHIFT	0
+
+/* DMI Control Register */
+#define R_PCH_PCR_DMI_DMIC	0x2234
+#define B_PCH_PCR_DMI_DMIC_SRL	(1 << 31)
+#define R_PCH_PCR_DMI_LPCLGIR1	0x2730
+#define R_PCH_PCR_DMI_LPCLGIR2	0x2734
+#define R_PCH_PCR_DMI_LPCLGIR3	0x2738
+#define R_PCH_PCR_DMI_LPCLGIR4	0x273c
+#define R_PCH_PCR_DMI_GCS	0x274C
+#define B_PCH_PCR_DMI_GCS_BILD  (1 << 0)
+#define R_PCH_PCR_DMI_LPCIOD	0x2770
+#define R_PCH_PCR_DMI_LPCIOE	0x2774
+
+/* RTC configuration */
+#define R_PCH_PCR_RTC_CONF	0x3400
+#define B_PCH_PCR_RTC_CONF_UCMOS_LOCK             (1 << 4)
+#define B_PCH_PCR_RTC_CONF_LCMOS_LOCK             (1 << 3)
+#define B_PCH_PCR_RTC_CONF_RESERVED               (1 << 31)
+#define B_PCH_PCR_RTC_CONF_UCMOS_EN	0x4
+
+/* ITSS PCRs*/
+/* PIRQA Routing Control Register*/
+#define R_PCH_PCR_ITSS_PIRQA_ROUT	0x3100
+/* PIRQB Routing Control Register*/
+#define R_PCH_PCR_ITSS_PIRQB_ROUT	0x3101
+/* PIRQC Routing Control Register*/
+#define R_PCH_PCR_ITSS_PIRQC_ROUT	0x3102
+/* PIRQD Routing Control Register*/
+#define R_PCH_PCR_ITSS_PIRQD_ROUT	0x3103
+/* PIRQE Routing Control Register*/
+#define R_PCH_PCR_ITSS_PIRQE_ROUT	0x3104
+/* PIRQF Routing Control Register*/
+#define R_PCH_PCR_ITSS_PIRQF_ROUT	0x3105
+/* PIRQG Routing Control Register*/
+#define R_PCH_PCR_ITSS_PIRQG_ROUT	0x3106
+/* PIRQH Routing Control Register*/
+#define R_PCH_PCR_ITSS_PIRQH_ROUT	0x3107
+/* ITSS Power reduction control */
+#define R_PCH_PCR_ITSS_ITSSPRC		0x3300
+# define CGE8254			(1 << 2)
+
+/* IO Trap PCRs */
+/* Trap status Register */
+#define R_PCH_PCR_PSTH_TRPST	0x1E00
+/* Trapped cycle */
+#define R_PCH_PCR_PSTH_TRPC		0x1E10
+/* Trapped write data */
+#define R_PCH_PCR_PSTH_TRPD		0x1E18
+
+/* Serial IO UART controller legacy mode */
+#define R_PCH_PCR_SERIAL_IO_GPPRVRW7	0x618
+#define SIO_PCH_LEGACY_UART0		(1 << 0)
+#define SIO_PCH_LEGACY_UART1		(1 << 1)
+#define SIO_PCH_LEGACY_UART2		(1 << 2)
+
+/*
+ * P2SB port ids.
+ */
+#define PID_PSTH	0x89
+#define PID_GPIOCOM3	0xAC
+#define PID_GPIOCOM2	0xAD
+#define PID_GPIOCOM1	0xAE
+#define PID_GPIOCOM0	0xAF
+#define PID_PSF1	0xBA
+#define PID_SCS		0xC0
+#define PID_RTC		0xC3
+#define PID_ITSS	0xC4
+#define PID_LPC		0xC7
+#define PID_SERIALIO	0xCB
+#define PID_DMI		0xEF
+
+#define PCH_PCR_PSFX_T0_SHDW_PCIEN		0x1C
+
+#define PCH_PCR_PSFX_T0_SHDW_PCIEN_FUNDIS	(1 << 8)
+#define PSF_BASE_ADDRESS			0xA00
+
+#if !defined(__ASSEMBLER__) && !defined(__ACPI__)
+#include <stdint.h>
+
+/* All these return 0 on success and < 0 on errror. */
+int pcr_read32(u8 pid, u16 offset, u32 *outdata);
+int pcr_read16(u8 pid, u16 offset, u16 *outdata);
+int pcr_read8(u8 pid, u16 offset, u8 *outdata);
+int pcr_write32(u8 pid, u16 offset, u32 indata);
+int pcr_write16(u8 pid, u16 offset, u16 indata);
+int pcr_write8(u8 pid, u16 offset, u8 indata);
+int pcr_andthenor32(u8 pid, u16 offset, u32 anddata, u32 ordata);
+int pcr_andthenor16(u8 pid, u16 offset, u16 anddata, u16 ordata);
+int pcr_andthenor8(u8 pid, u16 offset, u8 anddata, u8 ordata);
+
+/* Get the starting address of the port's registers. */
+uint8_t *pcr_port_regs(u8 pid);
+#endif /* if !defined(__ASSEMBLER__) && !defined(__ACPI__) */
+
+#endif /* _SOC_PCR_H_ */
diff --git a/src/soc/intel/kabylake/include/soc/pei_data.h b/src/soc/intel/kabylake/include/soc/pei_data.h
new file mode 100644
index 0000000..5c94727
--- /dev/null
+++ b/src/soc/intel/kabylake/include/soc/pei_data.h
@@ -0,0 +1,99 @@
+/*
+ * UEFI PEI wrapper
+ *
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of Google Inc. nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _PEI_DATA_H_
+#define _PEI_DATA_H_
+
+#include <types.h>
+
+#define PEI_VERSION 22
+
+#define ABI_X86 __attribute__((regparm(0)))
+
+typedef void ABI_X86(*tx_byte_func)(unsigned char byte);
+
+struct pei_data {
+	uint32_t pei_version;
+
+	int boot_mode;
+	int ec_present;
+
+	/* Console output function */
+	tx_byte_func tx_byte;
+
+	/*
+	 * DIMM SPD data for memory down configurations
+	 * [CHANNEL][SLOT][SPD]
+	 */
+	uint8_t spd_data[2][2][512];
+
+	/*
+	 * LPDDR3 DQ byte map
+	 * [CHANNEL][ITERATION][2]
+	 *
+	 * Maps which PI clocks are used by what LPDDR DQ Bytes (from CPU side)
+	 * DQByteMap[0] - ClkDQByteMap:
+	 * - If clock is per rank, program to [0xFF, 0xFF]
+	 * - If clock is shared by 2 ranks, program to [0xFF, 0] or [0, 0xFF]
+	 * - If clock is shared by 2 ranks but does not go to all bytes,
+	 *   Entry[i] defines which DQ bytes Group i services
+	 * DQByteMap[1] - CmdNDQByteMap: [0] is CmdN/CAA and [1] is CmdN/CAB
+	 * DQByteMap[2] - CmdSDQByteMap: [0] is CmdS/CAA and [1] is CmdS/CAB
+	 * DQByteMap[3] - CkeDQByteMap : [0] is CKE /CAA and [1] is CKE /CAB
+	 *                For DDR, DQByteMap[3:1] = [0xFF, 0]
+	 * DQByteMap[4] - CtlDQByteMap : Always program to [0xFF, 0]
+	 *                since we have 1 CTL / rank
+	 * DQByteMap[5] - CmdVDQByteMap: Always program to [0xFF, 0]
+	 *                since we have 1 CA Vref
+	 */
+	uint8_t dq_map[2][12];
+
+	/*
+	 * LPDDR3 Map from CPU DQS pins to SDRAM DQS pins
+	 * [CHANNEL][MAX_BYTES]
+	 */
+	uint8_t dqs_map[2][8];
+	uint16_t RcompResistor[3];
+	uint16_t RcompTarget[5];
+	/* Data read from flash and passed into MRC */
+	const void *saved_data;
+	int saved_data_size;
+
+	/* Disable use of saved data (can be set by mainboard) */
+	int disable_saved_data;
+
+	/* Data from MRC that should be saved to flash */
+	void *data_to_save;
+	int data_to_save_size;
+	int mem_cfg_id;
+} __attribute__((packed));
+
+typedef struct pei_data PEI_DATA;
+
+#endif /* _PEI_DATA_H_ */
diff --git a/src/soc/intel/kabylake/include/soc/pei_wrapper.h b/src/soc/intel/kabylake/include/soc/pei_wrapper.h
new file mode 100644
index 0000000..0f52cda
--- /dev/null
+++ b/src/soc/intel/kabylake/include/soc/pei_wrapper.h
@@ -0,0 +1,27 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * 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 _SOC_PEI_WRAPPER_H_
+#define _SOC_PEI_WRAPPER_H_
+
+#include <soc/pei_data.h>
+
+typedef int ABI_X86(*pei_wrapper_entry_t)(struct pei_data *pei_data);
+
+void soc_fill_pei_data(struct pei_data *pei_data);
+void mainboard_fill_pei_data(struct pei_data *pei_data);
+
+#endif
diff --git a/src/soc/intel/kabylake/include/soc/pm.h b/src/soc/intel/kabylake/include/soc/pm.h
new file mode 100644
index 0000000..d1aa0b4
--- /dev/null
+++ b/src/soc/intel/kabylake/include/soc/pm.h
@@ -0,0 +1,194 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * 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 _SOC_PM_H_
+#define _SOC_PM_H_
+
+#include <arch/acpi.h>
+#include <arch/io.h>
+#include <soc/pmc.h>
+
+/* ACPI_BASE_ADDRESS / PMBASE */
+
+#define PM1_STS			0x00
+#define  WAK_STS		(1 << 15)
+#define  PCIEXPWAK_STS		(1 << 14)
+#define  PRBTNOR_STS		(1 << 11)
+#define  RTC_STS		(1 << 10)
+#define  PWRBTN_STS		(1 << 8)
+#define  GBL_STS		(1 << 5)
+#define  BM_STS			(1 << 4)
+#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  GBL_RLS		(1 << 2)
+#define  BM_RLD			(1 << 1)
+#define  SCI_EN			(1 << 0)
+#define PM1_TMR			0x08
+#define SMI_EN			0x30
+#define  XHCI_SMI_EN		(1 << 31)
+#define  ME_SMI_EN		(1 << 30)
+#define  GPIO_UNLOCK_SMI_EN	(1 << 27)
+#define  INTEL_USB2_EN		(1 << 18)
+#define  LEGACY_USB2_EN		(1 << 17)
+#define  PERIODIC_EN		(1 << 14)
+#define  TCO_EN			(1 << 13)
+#define  MCSMI_EN		(1 << 11)
+#define  BIOS_RLS		(1 <<  7)
+#define  SWSMI_TMR_EN		(1 <<  6)
+#define  APMC_EN		(1 <<  5)
+#define  SLP_SMI_EN		(1 <<  4)
+#define  LEGACY_USB_EN		(1 <<  3)
+#define  BIOS_EN		(1 <<  2)
+#define  EOS			(1 <<  1)
+#define  GBL_SMI_EN		(1 <<  0)
+#define SMI_STS			0x34
+#define  SMI_STS_BITS			32
+#define  XHCI_SMI_STS_BIT		31
+#define  ME_SMI_STS_BIT			30
+#define  SERIAL_IO_SMI_STS_BIT		29
+#define  ESPI_SMI_STS_BIT		28
+#define  GPIO_UNLOCK_SMI_STS_BIT	27
+#define  SPI_SMI_STS_BIT		26
+#define  SCC_SMI_STS_BIT		25
+#define  MONITOR_STS_BIT		21
+#define  PCI_EXP_SMI_STS_BIT		20
+#define  SMBUS_SMI_STS_BIT		16
+#define  SERIRQ_SMI_STS_BIT		15
+#define  PERIODIC_STS_BIT		14
+#define  TCO_STS_BIT			13
+#define  DEVMON_STS_BIT			12
+#define  MCSMI_STS_BIT			11
+#define  GPIO_STS_BIT			10
+#define  GPE0_STS_BIT			9
+#define  PM1_STS_BIT			8
+#define  SWSMI_TMR_STS_BIT		6
+#define  APM_STS_BIT			5
+#define  SMI_ON_SLP_EN_STS_BIT		4
+#define  LEGACY_USB_STS_BIT		3
+#define  BIOS_STS_BIT			2
+#define UPWRC			0x3c
+#define  UPWRC_WS		(1 << 8)
+#define  UPWRC_WE		(1 << 1)
+#define  UPWRC_SMI		(1 << 0)
+#define GPE_CNTL		0x42
+#define  SWGPE_CTRL		(1 << 1)
+#define DEVACT_STS		0x44
+#define PM2_CNT			0x50
+
+#define GPE0_REG_MAX		4
+#define GPE0_REG_SIZE		32
+#define GPE0_STS(x)		(0x80 + (x * 4))
+#define  GPE_31_0		0	/* 0x80/0x90 = GPE[31:0] */
+#define  GPE_63_32		1	/* 0x84/0x94 = GPE[63:32] */
+#define  GPE_95_64		2	/* 0x88/0x98 = GPE[95:64] */
+#define  GPE_STD		3	/* 0x8c/0x9c = Standard GPE */
+#define   WADT_STS		(1 << 18)
+#define   LAN_WAK_STS		(1 << 16)
+#define   GPIO_T2_STS		(1 << 15)
+#define   ESPI_STS		(1 << 14)
+#define   PME_B0_STS		(1 << 13)
+#define   ME_SCI_STS		(1 << 12)
+#define   PME_STS		(1 << 11)
+#define   BATLOW_STS		(1 << 10)
+#define   PCI_EXP_STS		(1 << 9)
+#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(x)		(0x90 + (x * 4))
+#define   WADT_EN		(1 << 18)
+#define   LAN_WAK_EN		(1 << 16)
+#define   GPIO_T2_EN		(1 << 15)
+#define   ESPI_EN		(1 << 14)
+#define   PME_B0_EN		(1 << 13)
+#define   ME_SCI_EN		(1 << 12)
+#define   PME_EN		(1 << 11)
+#define   BATLOW_EN		(1 << 10)
+#define   PCI_EXP_EN		(1 << 9)
+#define   TCOSCI_EN		(1 << 6)
+#define   SWGPE_EN		(1 << 2)
+#define   HOT_PLUG_EN		(1 << 1)
+
+#define GBLRST_CAUSE0_THERMTRIP	(1 << 5)
+
+#define MAINBOARD_POWER_OFF	0
+#define MAINBOARD_POWER_ON	1
+#define MAINBOARD_POWER_KEEP	2
+
+struct chipset_power_state {
+	uint16_t pm1_sts;
+	uint16_t pm1_en;
+	uint32_t pm1_cnt;
+	uint16_t tco1_sts;
+	uint16_t tco2_sts;
+	uint32_t gpe0_sts[4];
+	uint32_t gpe0_en[4];
+	uint32_t gen_pmcon_a;
+	uint32_t gen_pmcon_b;
+	uint32_t gblrst_cause[2];
+	uint32_t prev_sleep_state;
+} __attribute__ ((packed));
+
+struct chipset_power_state *fill_power_state(void);
+
+/* PM1_CNT */
+void enable_pm1_control(uint32_t mask);
+void disable_pm1_control(uint32_t mask);
+
+/* PM1 */
+uint16_t clear_pm1_status(void);
+void enable_pm1(uint16_t events);
+uint32_t clear_smi_status(void);
+
+/* SMI */
+void enable_smi(uint32_t mask);
+void disable_smi(uint32_t mask);
+
+/* TCO */
+uint32_t clear_tco_status(void);
+void enable_tco_sci(void);
+
+/* GPE0 */
+uint32_t clear_gpe_status(void);
+void clear_gpe_enable(void);
+void enable_all_gpe(uint32_t set1, uint32_t set2, uint32_t set3, uint32_t set4);
+void disable_all_gpe(void);
+void enable_gpe(uint32_t mask);
+void disable_gpe(uint32_t mask);
+
+/* Return the selected ACPI SCI IRQ */
+int acpi_sci_irq(void);
+
+/* Get base address PMC memory mapped registers. */
+uint8_t *pmc_mmio_regs(void);
+/* Get base address of TCO I/O registers. */
+uint16_t pmc_tco_regs(void);
+
+static inline int deep_s3_enabled(void)
+{
+	uint32_t deep_s3_pol;
+
+	deep_s3_pol = read32(pmc_mmio_regs() + S3_PWRGATE_POL);
+	return !!(deep_s3_pol & (S3DC_GATE_SUS | S3AC_GATE_SUS));
+}
+
+#endif
diff --git a/src/soc/intel/kabylake/include/soc/pmc.h b/src/soc/intel/kabylake/include/soc/pmc.h
new file mode 100644
index 0000000..eb14b65
--- /dev/null
+++ b/src/soc/intel/kabylake/include/soc/pmc.h
@@ -0,0 +1,112 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * 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 _SOC_PMC_H_
+#define _SOC_PMC_H_
+
+/* PCI Configuration Space (D31:F2): PMC */
+#define ABASE			0x40
+#define ACTL			0x44
+#define  PWRM_EN		(1 << 8)
+#define  ACPI_EN		(1 << 7)
+#define  SCI_IRQ_SEL		(7 << 0)
+#define  SCIS_IRQ9		0
+#define  SCIS_IRQ10		1
+#define  SCIS_IRQ11		2
+#define  SCIS_IRQ20		4
+#define  SCIS_IRQ21		5
+#define  SCIS_IRQ22		6
+#define  SCIS_IRQ23		7
+#define PWRMBASE		0x48
+#define GEN_PMCON_A		0xa0
+#define  DC_PP_DIS		(1 << 30)
+#define  DSX_PP_DIS		(1 << 29)
+#define  AG3_PP_EN		(1 << 28)
+#define  SX_PP_EN		(1 << 27)
+#define  DISB			(1 << 23)
+#define  MEM_SR			(1 << 21)
+#define  MS4V			(1 << 18)
+#define  GBL_RST_STS		(1 << 16)
+#define  ALLOW_ICLK_PLL_SD_INC0	(1 << 15)
+#define  MPHY_CRICLK_GATE_OVER	(1 << 14)
+#define  ALLOW_OPI_PLL_SD_INC0	(1 << 13)
+#define  ALLOW_SPXB_CG_INC0	(1 << 12)
+#define  BIOS_PCI_EXP_EN	(1 << 10)
+#define  PWRBTN_LVL		(1 << 9)
+#define  ALLOW_L1LOW_C0		(1 << 7)
+#define  ALLOW_L1LOW_OPI_ON	(1 << 6)
+#define  SMI_LOCK		(1 << 4)
+#define GEN_PMCON_B		0xa4
+#define  SLP_STR_POL_LOCK	(1 << 18)
+#define  ACPI_BASE_LOCK		(1 << 17)
+#define  SUS_PWR_FLR		(1 << 14)
+#define  WOL_EN_OVRD		(1 << 13)
+#define  DIS_SLP_X_STRCH_SUS_UP		(1 << 12)
+#define  SLP_S3_MIN_ASST_WDTH_MASK	(0x3 << 10)
+#define  SLP_S3_MIN_ASST_WDTH_60USEC	(0 << 10)
+#define  SLP_S3_MIN_ASST_WDTH_1MS	(1 << 10)
+#define  SLP_S3_MIN_ASST_WDTH_50MS	(2 << 10)
+#define  SLP_S3_MIN_ASST_WDTH_2S	(3 << 10)
+#define  HOST_RST_STS		(1 << 9)
+#define  S4MAW_MASK		(0x3 << 4)
+#define  S4MAW_1S		(1 << 4)
+#define  S4MAW_2S		(2 << 4)
+#define  S4MAW_3S		(3 << 4)
+#define  S4MAW_4S		(0 << 4)
+#define  S4ASE			(1 << 3)
+#define  RTC_BATTERY_DEAD	(1 << 2)
+#define  PWR_FLR		(1 << 1)
+#define  SLEEP_AFTER_POWER_FAIL	(1 << 0)
+#define ETR3			0xac
+#define  ETR3_CF9LOCK		(1 << 31)
+#define  ETR3_CF9GR		(1 << 20)
+
+/* Memory mapped IO registers in PMC */
+#define S3_PWRGATE_POL		0x28
+#define  S3DC_GATE_SUS		(1 << 1)
+#define  S3AC_GATE_SUS		(1 << 0)
+#define S4_PWRGATE_POL		0x2c
+#define  S4DC_GATE_SUS		(1 << 1)
+#define  S4AC_GATE_SUS		(1 << 0)
+#define S5_PWRGATE_POL		0x30
+#define  S5DC_GATE_SUS		(1 << 15)
+#define  S5AC_GATE_SUS		(1 << 14)
+#define DSX_CFG			0x34
+#define  DSX_CFG_MASK		0x7
+#define  DSX_EN_WAKE_PIN	(1 << 2)
+#define  DSX_EN_AC_PRESENT_PIN	(1 << 1)
+#define  DSX_EN_LAN_WAKE_PIN	(1 << 0)
+#define PMSYNC_TPR_CFG		0xc4
+#define  PMSYNC_LOCK		(1 << 31)
+#define GPIO_CFG		0x120
+#define  GPE0_DWX_MASK		0xf
+#define  GPE0_DW0_SHIFT		0
+#define  GPE0_DW1_SHIFT		4
+#define  GPE0_DW2_SHIFT		8
+#define GBLRST_CAUSE0		0x124
+#define GBLRST_CAUSE1		0x128
+
+
+/* TCO registers and fields live behind TCOBASE I/O bar in SMBus device. */
+#define TCO1_STS			0x04
+#define TCO2_STS			0x06
+#define  TCO2_STS_SECOND_TO		0x02
+#define  TCO2_STS_BOOT		0x04
+#define TCO1_CNT			0x08
+#define  TCO_LOCK			(1 << 12)
+#define  TCO_TMR_HLT			(1 << 11)
+
+#endif
diff --git a/src/soc/intel/kabylake/include/soc/ramstage.h b/src/soc/intel/kabylake/include/soc/ramstage.h
new file mode 100644
index 0000000..27d318f
--- /dev/null
+++ b/src/soc/intel/kabylake/include/soc/ramstage.h
@@ -0,0 +1,31 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * 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 _SOC_RAMSTAGE_H_
+#define _SOC_RAMSTAGE_H_
+
+#include <chip.h>
+#include <device/device.h>
+#include <fsp/ramstage.h>
+
+void pch_enable_dev(device_t dev);
+void soc_init_pre_device(void *chip_info);
+void soc_init_cpus(device_t dev);
+const char *soc_acpi_name(struct device *dev);
+
+extern struct pci_operations soc_pci_ops;
+
+#endif
diff --git a/src/soc/intel/kabylake/include/soc/romstage.h b/src/soc/intel/kabylake/include/soc/romstage.h
new file mode 100644
index 0000000..56bace1
--- /dev/null
+++ b/src/soc/intel/kabylake/include/soc/romstage.h
@@ -0,0 +1,36 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * 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 _SOC_ROMSTAGE_H_
+#define _SOC_ROMSTAGE_H_
+
+#include <fsp/romstage.h>
+
+void i2c_early_init(void);
+void systemagent_early_init(void);
+void pch_early_init(void);
+void pch_uart_init(void);
+void intel_early_me_status(void);
+void report_platform_info(void);
+void set_max_freq(void);
+
+void enable_smbus(void);
+int smbus_read_byte(unsigned device, unsigned address);
+
+int early_spi_read_wpsr(u8 *sr);
+void mainboard_fill_spd_data(struct pei_data *pei_data);
+
+#endif /* _SOC_ROMSTAGE_H_ */
diff --git a/src/soc/intel/kabylake/include/soc/serialio.h b/src/soc/intel/kabylake/include/soc/serialio.h
new file mode 100644
index 0000000..02d6103
--- /dev/null
+++ b/src/soc/intel/kabylake/include/soc/serialio.h
@@ -0,0 +1,56 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google Inc.
+ * 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 _SERIALIO_H_
+#define _SERIALIO_H_
+
+#define SIO_REG_PPR_CLOCK         0x200
+#define SIO_REG_PPR_CLOCK_EN      (1 << 0)
+#define SIO_REG_PPR_CLOCK_UPDATE  (1 << 31)
+#define SIO_REG_PPR_CLOCK_N_DIV   0xc35
+#define SIO_REG_PPR_CLOCK_M_DIV   0x30
+
+#define SIO_REG_PPR_RESETS        0x204
+#define SIO_REG_PPR_RESETS_FUNC   (1 << 0)
+#define SIO_REG_PPR_RESETS_APB    (1 << 1)
+#define SIO_REG_PPR_RESETS_IDMA   (1 << 2)
+
+typedef enum {
+	PchSerialIoDisabled,
+	PchSerialIoAcpi,
+	PchSerialIoPci,
+	PchSerialIoAcpiHidden,
+	PchSerialIoLegacyUart,
+	PchSerialIoSkipInit
+} PCH_SERIAL_IO_MODE;
+
+typedef enum {
+	PchSerialIoIndexI2C0,
+	PchSerialIoIndexI2C1,
+	PchSerialIoIndexI2C2,
+	PchSerialIoIndexI2C3,
+	PchSerialIoIndexI2C4,
+	PchSerialIoIndexI2C5,
+	PchSerialIoIndexSpi0,
+	PchSerialIoIndexSpi1,
+	PchSerialIoIndexUart0,
+	PchSerialIoIndexUart1,
+	PchSerialIoIndexUart2,
+	PchSerialIoIndexMax
+} PCH_SERIAL_IO_CONTROLLER;
+
+#endif
+
diff --git a/src/soc/intel/kabylake/include/soc/smbus.h b/src/soc/intel/kabylake/include/soc/smbus.h
new file mode 100644
index 0000000..613fbb3
--- /dev/null
+++ b/src/soc/intel/kabylake/include/soc/smbus.h
@@ -0,0 +1,51 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2005 Yinghai Lu <yinghailu at gmail.com>
+ * Copyright (C) 2009 coresystems GmbH
+ * Copyright (C) 2014 Google Inc.
+ * 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 _SOC_SMBUS_H_
+#define _SOC_SMBUS_H_
+
+/* PCI Configuration Space (D31:F3): SMBus */
+#define SMB_BASE		0x20
+#define HOSTC			0x40
+#define  HST_EN			(1 << 0)
+#define SMB_RCV_SLVA		0x09
+/* SMBUS TCO base address. */
+#define TCOBASE		0x50
+
+/* SMBus I/O bits. */
+#define SMBHSTSTAT		0x0
+#define SMBHSTCTL		0x2
+#define SMBHSTCMD		0x3
+#define SMBXMITADD		0x4
+#define SMBHSTDAT0		0x5
+#define SMBHSTDAT1		0x6
+#define SMBBLKDAT		0x7
+#define SMBTRNSADD		0x9
+#define SMBSLVDATA		0xa
+#define SMLINK_PIN_CTL		0xe
+#define SMBUS_PIN_CTL		0xf
+
+#define SMBUS_TIMEOUT		(10 * 1000 * 100)
+#define SMBUS_SLAVE_ADDR	0x24
+
+int do_smbus_read_byte(unsigned smbus_base, unsigned device,
+		       unsigned address);
+int do_smbus_write_byte(unsigned smbus_base, unsigned device,
+			unsigned address, unsigned data);
+
+#endif
diff --git a/src/soc/intel/kabylake/include/soc/smm.h b/src/soc/intel/kabylake/include/soc/smm.h
new file mode 100644
index 0000000..92095c8
--- /dev/null
+++ b/src/soc/intel/kabylake/include/soc/smm.h
@@ -0,0 +1,88 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * 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 _SOC_SMM_H_
+#define _SOC_SMM_H_
+
+#include <stdint.h>
+#include <cpu/x86/msr.h>
+#include <fsp/memmap.h>
+#include <fsp/romstage.h>
+#include <soc/gpio.h>
+
+struct ied_header {
+	char signature[10];
+	u32 size;
+	u8 reserved[34];
+} __attribute__ ((packed));
+
+struct smm_relocation_params {
+	u32 smram_base;
+	u32 smram_size;
+	u32 ied_base;
+	u32 ied_size;
+	msr_t smrr_base;
+	msr_t smrr_mask;
+	msr_t emrr_base;
+	msr_t emrr_mask;
+	msr_t uncore_emrr_base;
+	msr_t uncore_emrr_mask;
+	/*
+	 * The smm_save_state_in_msrs field indicates if SMM save state
+	 * locations live in MSRs. This indicates to the CPUs how to adjust
+	 * the SMMBASE and IEDBASE
+	 */
+	int smm_save_state_in_msrs;
+};
+
+/* Mainboard handler for GPI SMIs*/
+void mainboard_smi_gpi_handler(const struct gpi_status *sts);
+
+
+#if IS_ENABLED(CONFIG_HAVE_SMI_HANDLER)
+void smm_relocation_handler(int cpu, uintptr_t curr_smbase,
+				uintptr_t staggered_smbase);
+void smm_info(uintptr_t *perm_smbase, size_t *perm_smsize,
+		size_t *smm_save_state_size);
+void smm_initialize(void);
+void smm_relocate(void);
+
+/* These helpers are for performing SMM relocation. */
+void southbridge_trigger_smi(void);
+void southbridge_clear_smi_status(void);
+
+/*
+ * The initialization of the southbridge is split into 2 compoments. One is
+ * for clearing the state in the SMM registers. The other is for enabling
+ * SMIs.
+ */
+void southbridge_smm_clear_state(void);
+void southbridge_smm_enable_smi(void);
+#else	/* CONFIG_HAVE_SMI_HANDLER */
+static inline void smm_relocation_handler(int cpu, uintptr_t curr_smbase,
+				uintptr_t staggered_smbase) {}
+static inline void smm_info(uintptr_t *perm_smbase, size_t *perm_smsize,
+		size_t *smm_save_state_size) {}
+static inline void smm_initialize(void) {}
+
+static inline void smm_relocate(void) {}
+static inline void southbridge_trigger_smi(void) {}
+static inline void southbridge_clear_smi_status(void) {}
+static inline void southbridge_smm_clear_state(void) {}
+static inline void southbridge_smm_enable_smi(void) {}
+#endif	/* CONFIG_HAVE_SMI_HANDLER */
+
+#endif
diff --git a/src/soc/intel/kabylake/include/soc/spi.h b/src/soc/intel/kabylake/include/soc/spi.h
new file mode 100644
index 0000000..508e195
--- /dev/null
+++ b/src/soc/intel/kabylake/include/soc/spi.h
@@ -0,0 +1,136 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * 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 _SOC_SPI_H_
+#define _SOC_SPI_H_
+
+/*
+ * SPI Opcode Menu setup for SPIBAR lockdown
+ * should support most common flash chips.
+ */
+#define SPIDVID_OFFSET	0x0
+
+/* Reigsters within the SPIBAR */
+#define SPIBAR_SSFC		0xA1
+
+#define SPIBAR_PREOP		0xA4
+#define SPIBAR_OPTYPE		0xA6
+#define SPIBAR_OPMENU_LOWER	0xA8
+#define SPIBAR_OPMENU_UPPER	0xAc
+/* STRAP LOCK Register */
+#define SPIBAR_RESET_LOCK 0xF0
+#define SPIBAR_RESET_LOCK_DISABLE	0
+#define SPIBAR_RESET_LOCK_ENABLE	1
+/* STRAP MSG Control Register*/
+#define SPIBAR_RESET_CTRL 0xF4
+#define SPIBAR_RESET_CTRL_SSMC	1
+/* STRAP Data Register*/
+#define SPIBAR_RESET_DATA 0xF8
+
+#define SPI_PRR_MAX		5
+#define SPI_PRR_SHIFT		12
+#define SPI_PRR_MASK		0x7fff
+#define SPI_PRR_BASE_SHIFT	0
+#define SPI_PRR_LIMIT_SHIFT	16
+#define SPI_PRR_RPE		(1 << 15) /* Read Protect */
+#define SPI_PRR_WPE		(1 << 31) /* Write Protect */
+#define SPI_PRR(base, limit)	\
+	(((((limit) >> SPI_PRR_SHIFT) & SPI_PRR_MASK) << SPI_PRR_LIMIT_SHIFT) |\
+	 ((((base) >> SPI_PRR_SHIFT) & SPI_PRR_MASK) << SPI_PRR_BASE_SHIFT))
+
+#define SPI_OPMENU_0 0x01 /* WRSR: Write Status Register */
+#define SPI_OPTYPE_0 0x01 /* Write, no address */
+
+#define SPI_OPMENU_1 0x02 /* BYPR: Byte Program */
+#define SPI_OPTYPE_1 0x03 /* Write, address required */
+
+#define SPI_OPMENU_2 0x03 /* READ: Read Data */
+#define SPI_OPTYPE_2 0x02 /* Read, address required */
+
+#define SPI_OPMENU_3 0x05 /* RDSR: Read Status Register */
+#define SPI_OPTYPE_3 0x00 /* Read, no address */
+
+#define SPI_OPMENU_4 0x20 /* SE20: Sector Erase 0x20 */
+#define SPI_OPTYPE_4 0x03 /* Write, address required */
+
+#define SPI_OPMENU_5 0x9f /* RDID: Read ID */
+#define SPI_OPTYPE_5 0x00 /* Read, no address */
+
+#define SPI_OPMENU_6 0xd8 /* BED8: Block Erase 0xd8 */
+#define SPI_OPTYPE_6 0x03 /* Write, address required */
+
+#define SPI_OPMENU_7 0x0b /* FAST: Fast Read */
+#define SPI_OPTYPE_7 0x02 /* Read, address required */
+
+#define SPI_OPMENU_UPPER ((SPI_OPMENU_7 << 24) | (SPI_OPMENU_6 << 16) | \
+			  (SPI_OPMENU_5 << 8) | SPI_OPMENU_4)
+#define SPI_OPMENU_LOWER ((SPI_OPMENU_3 << 24) | (SPI_OPMENU_2 << 16) | \
+			  (SPI_OPMENU_1 << 8) | SPI_OPMENU_0)
+
+#define SPI_OPTYPE ((SPI_OPTYPE_7 << 14) | (SPI_OPTYPE_6 << 12) | \
+		    (SPI_OPTYPE_5 << 10) | (SPI_OPTYPE_4 << 8)  | \
+		    (SPI_OPTYPE_3 << 6) | (SPI_OPTYPE_2 << 4)   | \
+		    (SPI_OPTYPE_1 << 2) | (SPI_OPTYPE_0))
+
+#define SPI_OPPREFIX ((0x50 << 8) | 0x06) /* EWSR and WREN */
+
+#define SPIBAR_HSFS		0x04	 /* SPI hardware sequence status */
+#define  SPIBAR_HSFS_FLOCKDN	(1 << 15)/* Flash Configuration Lock-Down */
+#define  SPIBAR_HSFS_SCIP	(1 << 5) /* SPI Cycle In Progress */
+#define  SPIBAR_HSFS_AEL	(1 << 2) /* SPI Access Error Log */
+#define  SPIBAR_HSFS_FCERR	(1 << 1) /* SPI Flash Cycle Error */
+#define  SPIBAR_HSFS_FDONE	(1 << 0) /* SPI Flash Cycle Done */
+#define  SPIBAR_HSFS_BERASE_MASK	3 /* Block/Sector Erase MASK */
+#define  SPIBAR_HSFS_BERASE_OFFSET	3 /* Block/Sector Erase OFFSET */
+#define SPIBAR_HSFC		0x06	 /* SPI hardware sequence control */
+#define  SPIBAR_HSFC_BYTE_COUNT(c)	(((c - 1) & 0x3f) << 8)
+#define  SPIBAR_HSFC_CYCLE_READ		(0 << 1) /* Read cycle */
+#define  SPIBAR_HSFC_CYCLE_WRITE	(2 << 1) /* Write cycle */
+#define  SPIBAR_HSFC_CYCLE_ERASE	(3 << 1) /* Erase cycle */
+#define  SPIBAR_HSFC_GO		(1 << 0) /* GO: start SPI transaction */
+#define SPIBAR_FADDR		0x08	 /* SPI flash address */
+#define  SPIBAR_FADDR_MASK	0x7FFFFFF
+
+#define SPIBAR_FDATA(n)		(0x10 + (4 * n)) /* SPI flash data */
+#define SPIBAR_FPR(n)		(0x84 + (4 * n)) /* SPI flash protected range */
+#define SPIBAR_FPR_WPE		(1 << 31) /* Flash Write protected */
+#define SPIBAR_SSFS		0xA0
+#define  SPIBAR_SSFS_ERROR	(1 << 3)
+#define  SPIBAR_SSFS_DONE	(1 << 2)
+#define SPIBAR_SSFC		0xA1
+#define  SPIBAR_SSFC_DATA	(1 << 14)
+#define  SPIBAR_SSFC_GO		(1 << 1)
+
+#define SPIBAR_FDOC		0xB4
+#define  SPIBAR_FDOC_COMPONENT	(1 << 12)
+#define  SPIBAR_FDOC_FDSI_1	(1 << 2)
+
+#define SPIBAR_FDOD		0xB8
+#define  FLCOMP_C0DEN_MASK	0xF
+#define  FLCOMP_C0DEN_8MB	4
+#define  FLCOMP_C0DEN_16MB	5
+#define  FLCOMP_C0DEN_32MB	6
+
+#define SPIBAR_BIOS_CNTL	0xDC
+#define  SPIBAR_BC_BILD		(1 << 7)
+#define  SPIBAR_BC_EISS		(1 << 5)
+#define  SPIBAR_BC_LE           (1 << 2)
+#define  SPIBAR_BC_WPD		(1 << 0)
+
+void *get_spi_bar(void);
+int spi_flash_protect(u32 start, u32 size);
+
+#endif
diff --git a/src/soc/intel/kabylake/include/soc/systemagent.h b/src/soc/intel/kabylake/include/soc/systemagent.h
new file mode 100644
index 0000000..d75ec9f
--- /dev/null
+++ b/src/soc/intel/kabylake/include/soc/systemagent.h
@@ -0,0 +1,122 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2008 coresystems GmbH
+ * Copyright (C) 2014 Google Inc.
+ * 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 _SOC_SYSTEMAGENT_H_
+#define _SOC_SYSTEMAGENT_H_
+
+#include <soc/iomap.h>
+
+#define SA_IGD_OPROM_VENDEV	0x80860406
+
+#define IGD_KABYLAKE_GT1_SULTM	0x1906
+#define IGD_KABYLAKE_GT2_SULXM	0x191E
+#define IGD_KABYLAKE_GT2_SULTM	0x1916
+
+#define MCH_KABYLAKE_ID_U	0x1904
+#define MCH_KABYLAKE_ID_Y	0x190c
+#define MCH_KABYLAKE_ID_ULX	0x1924
+
+/* Device 0:0.0 PCI configuration space */
+
+#define EPBAR		0x40
+#define MCHBAR		0x48
+#define PCIEXBAR	0x60
+#define DMIBAR		0x68
+#define GGC		0x50	/* GMCH Graphics Control */
+#define DEVEN		0x54	/* Device Enable */
+#define  DEVEN_D7EN	(1 << 14)
+#define  DEVEN_D4EN	(1 << 7)
+#define  DEVEN_D3EN	(1 << 5)
+#define  DEVEN_D2EN	(1 << 4)
+#define  DEVEN_D1F0EN	(1 << 3)
+#define  DEVEN_D1F1EN	(1 << 2)
+#define  DEVEN_D1F2EN	(1 << 1)
+#define  DEVEN_D0EN	(1 << 0)
+#define DPR		0x5c
+#define  DPR_EPM	(1 << 2)
+#define  DPR_PRS	(1 << 1)
+#define  DPR_SIZE_MASK	0xff0
+
+#define PAM0		0x80
+#define PAM1		0x81
+#define PAM2		0x82
+#define PAM3		0x83
+#define PAM4		0x84
+#define PAM5		0x85
+#define PAM6		0x86
+
+#define SMRAM		0x88	/* System Management RAM Control */
+#define  D_OPEN		(1 << 6)
+#define  D_CLS		(1 << 5)
+#define  D_LCK		(1 << 4)
+#define  G_SMRAME	(1 << 3)
+#define  C_BASE_SEG	((0 << 2) | (1 << 1) | (0 << 0))
+
+#define MESEG_BASE	0x70	/* Management Engine Base. */
+#define MESEG_LIMIT	0x78	/* Management Engine Limit. */
+#define REMAPBASE	0x90	/* Remap base. */
+#define REMAPLIMIT	0x98	/* Remap limit. */
+#define TOM		0xa0	/* Top of DRAM in memory controller space. */
+#define TOUUD		0xa8	/* Top of Upper Usable DRAM */
+#define BDSM		0xb0	/* Base Data Stolen Memory */
+#define BGSM		0xb4	/* Base GTT Stolen Memory */
+#define TSEG		0xb8	/* TSEG base */
+#define TOLUD		0xbc	/* Top of Low Used Memory */
+#define SKPAD		0xdc	/* Scratchpad Data */
+
+/* MCHBAR */
+
+#define MCHBAR8(x)	(*(volatile u8 *)(MCH_BASE_ADDRESS + x))
+#define MCHBAR16(x)	(*(volatile u16 *)(MCH_BASE_ADDRESS + x))
+#define MCHBAR32(x)	(*(volatile u32 *)(MCH_BASE_ADDRESS + x))
+
+#define MCHBAR_PEI_VERSION	0x5034
+#define BIOS_RESET_CPL		0x5da8
+#define EDRAMBAR		0x5408
+#define MCH_PAIR		0x5418
+#define GDXCBAR			0x5420
+
+#define MCH_PKG_POWER_LIMIT_LO	0x59a0
+#define MCH_PKG_POWER_LIMIT_HI	0x59a4
+#define MCH_DDR_POWER_LIMIT_LO	0x58e0
+#define MCH_DDR_POWER_LIMIT_HI	0x58e4
+
+/* PCODE MMIO communications live in the MCHBAR. */
+#define BIOS_MAILBOX_INTERFACE			0x5da4
+#define  MAILBOX_RUN_BUSY			(1 << 31)
+/* Errors are returned back in bits 7:0. */
+#define  MAILBOX_BIOS_ERROR_NONE		0
+#define  MAILBOX_BIOS_ERROR_INVALID_COMMAND	1
+#define  MAILBOX_BIOS_ERROR_TIMEOUT		2
+#define  MAILBOX_BIOS_ERROR_ILLEGAL_DATA	3
+#define  MAILBOX_BIOS_ERROR_RESERVED		4
+#define  MAILBOX_BIOS_ERROR_ILLEGAL_VR_ID	5
+#define  MAILBOX_BIOS_ERROR_VR_INTERFACE_LOCKED	6
+#define  MAILBOX_BIOS_ERROR_VR_ERROR		7
+/* Data is passed through bits 31:0 of the data register. */
+#define BIOS_MAILBOX_DATA			0x5da0
+
+/* CPU Trace reserved memory size */
+#define TRACE_MEMORY_SIZE	0x8000000	/* 128MiB */
+
+/* System Agent identification */
+u8 systemagent_revision(void);
+
+/* Top of 32bit usable memory */
+u32 top_of_32bit_ram(void);
+
+#endif
diff --git a/src/soc/intel/kabylake/include/soc/usb.h b/src/soc/intel/kabylake/include/soc/usb.h
new file mode 100644
index 0000000..93f221c
--- /dev/null
+++ b/src/soc/intel/kabylake/include/soc/usb.h
@@ -0,0 +1,172 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 Google Inc.
+ * 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 _SOC_USB_H_
+#define _SOC_USB_H_
+
+#include <stdint.h>
+
+#define USB2_EMP_OFF		0
+#define USB2_DE_EMP_ON		1
+#define USB2_PRE_EMP_ON		2
+
+#define USB2_FULL_BIT_PRE_EMP	0
+#define USB2_HALF_BIT_PRE_EMP	1
+
+#define USB2_BIAS_0MV		0
+#define USB2_BIAS_11MV		1
+#define USB2_BIAS_17MV		2
+#define USB2_BIAS_28MV		3
+#define USB2_BIAS_28MV2		4
+#define USB2_BIAS_39MV		5
+#define USB2_BIAS_45MV		6
+#define USB2_BIAS_56MV		7
+
+struct usb2_port_config {
+	uint8_t enable;
+	uint8_t tx_bias;
+	uint8_t tx_emp_enable;
+	uint8_t pre_emp_bias;
+	uint8_t pre_emp_bit;
+};
+
+#define USB2_PORT_EMPTY { \
+	.enable        = 0, \
+	.tx_bias       = USB2_BIAS_0MV, \
+	.tx_emp_enable = USB2_EMP_OFF, \
+	.pre_emp_bias  = USB2_BIAS_0MV, \
+	.pre_emp_bit   = USB2_HALF_BIT_PRE_EMP, \
+}
+
+/*
+ * Standard USB Port based on length:
+ * - External
+ * - Back Panel
+ * - OTG
+ * - M.2
+ * - Internal device down
+ */
+
+/* Max TX and Pre-emp settings */
+#define USB2_PORT_MAX { \
+	.enable        = 1, \
+	.tx_bias       = USB2_BIAS_56MV, \
+	.tx_emp_enable = USB2_PRE_EMP_ON, \
+	.pre_emp_bias  = USB2_BIAS_56MV, \
+	.pre_emp_bit   = USB2_HALF_BIT_PRE_EMP, \
+}
+
+/* 11.5"-12" */
+#define USB2_PORT_LONG { \
+	.enable        = 1, \
+	.tx_bias       = USB2_BIAS_39MV, \
+	.tx_emp_enable = USB2_PRE_EMP_ON, \
+	.pre_emp_bias  = USB2_BIAS_56MV, \
+	.pre_emp_bit   = USB2_HALF_BIT_PRE_EMP, \
+}
+
+/* 6"-11.5" */
+#define USB2_PORT_MID { \
+	.enable        = 1, \
+	.tx_bias       = USB2_BIAS_0MV, \
+	.tx_emp_enable = USB2_PRE_EMP_ON, \
+	.pre_emp_bias  = USB2_BIAS_56MV, \
+	.pre_emp_bit   = USB2_HALF_BIT_PRE_EMP, \
+}
+
+/* 3"-6" */
+#define USB2_PORT_SHORT { \
+	.enable        = 1, \
+	.tx_bias       = USB2_BIAS_39MV, \
+	.tx_emp_enable = USB2_PRE_EMP_ON | USB2_DE_EMP_ON, \
+	.pre_emp_bias  = USB2_BIAS_39MV, \
+	.pre_emp_bit   = USB2_FULL_BIT_PRE_EMP, \
+}
+
+/* Type-C Port, no BC1.2 charge detect module / MUX */
+#define USB2_PORT_TYPE_C { \
+	.enable        = 1, \
+	.tx_bias       = USB2_BIAS_0MV, \
+	.tx_emp_enable = USB2_PRE_EMP_ON, \
+	.pre_emp_bias  = USB2_BIAS_56MV, \
+	.pre_emp_bit   = USB2_HALF_BIT_PRE_EMP, \
+}
+
+/* Port with BC1.2 charge detect module / MUX */
+#define USB2_PORT_BC12_MUX { \
+	.enable        = 1, \
+	.tx_bias       = USB2_BIAS_0MV, \
+	.tx_emp_enable = USB2_PRE_EMP_ON, \
+	.pre_emp_bias  = USB2_BIAS_56MV, \
+	.pre_emp_bit   = USB2_HALF_BIT_PRE_EMP, \
+}
+
+/* Internal Flex Cable, 3"-5" + cable + 2" card */
+#define USB2_PORT_FLEX { \
+	.enable        = 1, \
+	.tx_bias       = USB2_BIAS_0MV, \
+	.tx_emp_enable = USB2_PRE_EMP_ON, \
+	.pre_emp_bias  = USB2_BIAS_56MV, \
+	.pre_emp_bit   = USB2_HALF_BIT_PRE_EMP, \
+}
+
+/* Docking, 3"-9" */
+#define USB2_PORT_DOCKING_LONG { \
+	.enable        = 1, \
+	.tx_bias       = USB2_BIAS_0MV, \
+	.tx_emp_enable = USB2_PRE_EMP_ON, \
+	.pre_emp_bias  = USB2_BIAS_56MV, \
+	.pre_emp_bit   = USB2_HALF_BIT_PRE_EMP, \
+}
+
+/* Docking, 3"-6" */
+#define USB2_PORT_DOCKING_SHORT { \
+	.enable        = 1, \
+	.tx_bias       = USB2_BIAS_17MV, \
+	.tx_emp_enable = USB2_PRE_EMP_ON | USB2_DE_EMP_ON, \
+	.pre_emp_bias  = USB2_BIAS_45MV, \
+	.pre_emp_bit   = USB2_FULL_BIT_PRE_EMP, \
+}
+
+/* 2:1 Detachable, 2"-4" on tablet + 2"-4" on base */
+#define USB2_PORT_DETACHABLE_TABLET { \
+	.enable        = 1, \
+	.tx_bias       = USB2_BIAS_56MV, \
+	.tx_emp_enable = USB2_PRE_EMP_ON, \
+	.pre_emp_bias  = USB2_BIAS_56MV, \
+	.pre_emp_bit   = USB2_HALF_BIT_PRE_EMP, \
+}
+
+struct usb3_port_config {
+	uint8_t enable;
+	uint8_t tx_de_emp;
+	uint8_t tx_downscale_amp;
+};
+
+#define USB3_PORT_EMPTY { \
+	.enable           = 0, \
+	.tx_de_emp        = 0x00, \
+	.tx_downscale_amp = 0x00, \
+}
+
+#define USB3_PORT_DEFAULT { \
+	.enable           = 1, \
+	.tx_de_emp        = 0x29, \
+	.tx_downscale_amp = 0x00, \
+}
+
+#endif
diff --git a/src/soc/intel/kabylake/include/soc/vr_config.h b/src/soc/intel/kabylake/include/soc/vr_config.h
new file mode 100644
index 0000000..99b43d2
--- /dev/null
+++ b/src/soc/intel/kabylake/include/soc/vr_config.h
@@ -0,0 +1,80 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * 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.
+ */
+
+/* VR Settings for each domain */
+
+#ifndef _SOC_VR_CONFIG_H_
+#define _SOC_VR_CONFIG_H_
+
+#include <fsp/soc_binding.h>
+
+struct vr_config {
+
+	/*
+	 * The below settings will take effect when this is set to 1
+	 * for that domain.
+	 */
+	int vr_config_enable;
+
+	/* Power State X current cuttof in 1/4 Amp increments
+	 * Range is 0-128A
+	 */
+	int psi1threshold;
+	int psi2threshold;
+	int psi3threshold;
+
+	/* Enable power state 3/4 for different domains */
+	int psi3enable;
+	int psi4enable;
+
+	/*
+	 * Imon slope correction. Specified in 1/100 increment
+	 * values. Range is 0-200. 125 = 1.25
+	 */
+	int imon_slope;
+
+	/*
+	 * Imon offset correction. Units 1/4, Range 0-255.
+	 * Value of 100 = 100/4 = 25 offset.
+	 */
+	int imon_offset;
+
+	/* VR Icc Max limit. 0-255A in 1/4 A units. 400 = 100A */
+	int icc_max;
+
+	/* VR Voltage Limit. Range is 0-7999mV */
+	int voltage_limit;
+};
+
+#define VR_CFG_AMP(i) ((i) * 4)
+
+/* VrConfig Settings for 5 domains
+ * 0 = System Agent, 1 = IA Core, 2 = Ring,
+ * 3 = GT unsliced,  4 = GT sliced
+ */
+enum vr_domain{
+	VR_SYSTEM_AGENT,
+	VR_IA_CORE,
+	VR_RING,
+	VR_GT_UNSLICED,
+	VR_GT_SLICED,
+	NUM_VR_DOMAINS
+};
+
+void fill_vr_domain_config(SILICON_INIT_UPD *params, int domain,
+				const struct vr_config *cfg);
+
+#endif
diff --git a/src/soc/intel/kabylake/include/soc/xhci.h b/src/soc/intel/kabylake/include/soc/xhci.h
new file mode 100644
index 0000000..6cb0edd
--- /dev/null
+++ b/src/soc/intel/kabylake/include/soc/xhci.h
@@ -0,0 +1,60 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * 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 _SOC_XHCI_H_
+#define _SOC_XHCI_H_
+
+#include <rules.h>
+
+/* XHCI PCI Registers */
+#define XHCI_PWR_CTL_STS	0x74
+#define  XHCI_PWR_CTL_SET_MASK	0x3
+#define  XHCI_PWR_CTL_SET_D0	0x0
+#define  XHCI_PWR_CTL_SET_D3	0x3
+#define  XHCI_PWR_CTL_ENABLE_PME (1 << 8)
+#define  XHCI_PWR_CTL_STATUS_PME (1 << 15)
+#define XHCI_USB2PR		0xd0
+#define XHCI_USB2PRM		0xd4
+#define  XHCI_USB2PR_HCSEL	0x7fff
+#define XHCI_USB3PR		0xd8
+#define  XHCI_USB3PR_SSEN	0x3f
+#define XHCI_USB3PRM		0xdc
+#define XHCI_USB3FUS		0xe0
+#define  XHCI_USB3FUS_SS_MASK	3
+#define  XHCI_USB3FUS_SS_SHIFT	3
+#define XHCI_USB3PDO		0xe8
+
+/* XHCI Memory Registers */
+#define XHCI_USB3_PORTSC(port)	(0x510 + (port * 0x10))
+#define  XHCI_USB3_PORTSC_CHST	(0x7f << 17)
+#define  XHCI_USB3_PORTSC_WCE	(1 << 25)	/* Wake on Connect */
+#define  XHCI_USB3_PORTSC_WDE	(1 << 26)	/* Wake on Disconnect */
+#define  XHCI_USB3_PORTSC_WOE	(1 << 27)	/* Wake on Overcurrent */
+#define  XHCI_USB3_PORTSC_WRC	(1 << 19)	/* Warm Reset Complete */
+#define  XHCI_USB3_PORTSC_LWS	(1 << 16)	/* Link Write Strobe */
+#define  XHCI_USB3_PORTSC_PED	(1 << 1)	/* Port Enabled/Disabled */
+#define  XHCI_USB3_PORTSC_WPR	(1 << 31)	/* Warm Port Reset */
+#define  XHCI_USB3_PORTSC_PLS	(0xf << 5)	/* Port Link State */
+#define   XHCI_PLSR_DISABLED	(4 << 5)	/* Port is disabled */
+#define   XHCI_PLSR_RXDETECT	(5 << 5)	/* Port is disconnected */
+#define   XHCI_PLSR_POLLING	(7 << 5)	/* Port is polling */
+#define   XHCI_PLSW_ENABLE	(5 << 5)	/* Transition from disabled */
+
+#if ENV_SMM
+void usb_xhci_sleep_prepare(device_t dev, u8 slp_typ);
+#endif
+
+#endif
diff --git a/src/soc/intel/kabylake/lpc.c b/src/soc/intel/kabylake/lpc.c
new file mode 100644
index 0000000..55598d0
--- /dev/null
+++ b/src/soc/intel/kabylake/lpc.c
@@ -0,0 +1,327 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008-2009 coresystems GmbH
+ * Copyright (C) 2014 Google Inc.
+ * 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 <arch/acpigen.h>
+#include "chip.h"
+#include <console/console.h>
+#include <delay.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <pc80/isa-dma.h>
+#include <pc80/i8259.h>
+#include <arch/io.h>
+#include <arch/ioapic.h>
+#include <arch/acpi.h>
+#include <cpu/cpu.h>
+#include <cpu/x86/smm.h>
+#include <cbmem.h>
+#include <reg_script.h>
+#include <string.h>
+#include <soc/acpi.h>
+#include <soc/gpio.h>
+#include <soc/iomap.h>
+#include <soc/lpc.h>
+#include <soc/nvs.h>
+#include <soc/pch.h>
+#include <soc/pci_devs.h>
+#include <soc/pm.h>
+#include <soc/pmc.h>
+#include <soc/ramstage.h>
+#include <soc/pcr.h>
+#if IS_ENABLED(CONFIG_CHROMEOS)
+#include <vendorcode/google/chromeos/chromeos.h>
+#endif
+
+static void pch_enable_ioapic(struct device *dev)
+{
+	u32 reg32;
+	/* PCH-LP has 120 redirection entries */
+	const int redir_entries = 120;
+
+	set_ioapic_id((void *)IO_APIC_ADDR, 0x02);
+
+	/* affirm full set of redirection table entries ("write once") */
+	reg32 = io_apic_read((void *)IO_APIC_ADDR, 0x01);
+
+	reg32 &= ~0x00ff0000;
+	reg32 |= (redir_entries - 1) << 16;
+
+	io_apic_write((void *)IO_APIC_ADDR, 0x01, reg32);
+
+	/*
+	 * Select Boot Configuration register (0x03) and
+	 * use Processor System Bus (0x01) to deliver interrupts.
+	 */
+	io_apic_write((void *)IO_APIC_ADDR, 0x03, 0x01);
+}
+
+/*
+ * PIRQ[n]_ROUT[3:0] - PIRQ Routing Control
+ * 0x00 - 0000 = Reserved
+ * 0x01 - 0001 = Reserved
+ * 0x02 - 0010 = Reserved
+ * 0x03 - 0011 = IRQ3
+ * 0x04 - 0100 = IRQ4
+ * 0x05 - 0101 = IRQ5
+ * 0x06 - 0110 = IRQ6
+ * 0x07 - 0111 = IRQ7
+ * 0x08 - 1000 = Reserved
+ * 0x09 - 1001 = IRQ9
+ * 0x0A - 1010 = IRQ10
+ * 0x0B - 1011 = IRQ11
+ * 0x0C - 1100 = IRQ12
+ * 0x0D - 1101 = Reserved
+ * 0x0E - 1110 = IRQ14
+ * 0x0F - 1111 = IRQ15
+ * PIRQ[n]_ROUT[7] - PIRQ Routing Control
+ * 0x80 - The PIRQ is not routed.
+ */
+
+static void pch_pirq_init(device_t dev)
+{
+	device_t irq_dev;
+	config_t *config = dev->chip_info;
+
+	pcr_write8(PID_ITSS, R_PCH_PCR_ITSS_PIRQA_ROUT, config->pirqa_routing);
+	pcr_write8(PID_ITSS, R_PCH_PCR_ITSS_PIRQB_ROUT, config->pirqb_routing);
+	pcr_write8(PID_ITSS, R_PCH_PCR_ITSS_PIRQC_ROUT, config->pirqc_routing);
+	pcr_write8(PID_ITSS, R_PCH_PCR_ITSS_PIRQD_ROUT, config->pirqd_routing);
+	pcr_write8(PID_ITSS, R_PCH_PCR_ITSS_PIRQE_ROUT, config->pirqe_routing);
+	pcr_write8(PID_ITSS, R_PCH_PCR_ITSS_PIRQF_ROUT, config->pirqf_routing);
+	pcr_write8(PID_ITSS, R_PCH_PCR_ITSS_PIRQG_ROUT, config->pirqg_routing);
+	pcr_write8(PID_ITSS, R_PCH_PCR_ITSS_PIRQH_ROUT, config->pirqh_routing);
+
+	for (irq_dev = all_devices; irq_dev; irq_dev = irq_dev->next) {
+		u8 int_pin = 0, int_line = 0;
+
+		if (!irq_dev->enabled || irq_dev->path.type != DEVICE_PATH_PCI)
+			continue;
+
+		int_pin = pci_read_config8(irq_dev, PCI_INTERRUPT_PIN);
+
+		switch (int_pin) {
+		case 1: /* INTA# */
+			int_line = config->pirqa_routing;
+			break;
+		case 2: /* INTB# */
+			int_line = config->pirqb_routing;
+			break;
+		case 3: /* INTC# */
+			int_line = config->pirqc_routing;
+			break;
+		case 4: /* INTD# */
+			int_line = config->pirqd_routing;
+			break;
+		}
+
+		if (!int_line)
+			continue;
+
+		pci_write_config8(irq_dev, PCI_INTERRUPT_LINE, int_line);
+	}
+}
+
+
+static const struct reg_script pch_misc_init_script[] = {
+	/* Setup NMI on errors, disable SERR */
+	REG_IO_RMW8(0x61, ~0xf0, (1 << 2)),
+	/* Disable NMI sources */
+	REG_IO_OR8(0x70, (1 << 7)),
+	/* Enable BIOS updates outside of SMM */
+	REG_PCI_RMW8(0xdc, ~(1 << 5), 0),
+	/* Setup SERIRQ, enable continuous mode */
+	REG_PCI_OR8(SERIRQ_CNTL, (1 << 7) | (1 << 6)),
+#if !IS_ENABLED(CONFIG_SERIRQ_CONTINUOUS_MODE)
+	REG_PCI_RMW8(SERIRQ_CNTL, ~(1 << 6), 0),
+#endif
+	/* Enable CLKRUN_EN for power gating LPC */
+	REG_PCI_OR8(PCCTL, (CLKRUN_EN)),
+	REG_SCRIPT_END
+};
+
+static void clock_gate_8254(struct device *dev)
+{
+	config_t *config = dev->chip_info;
+	const uint32_t cge8254_mask = CGE8254;
+
+	if (!config->clock_gate_8254)
+		return;
+
+	pcr_andthenor32(PID_ITSS, R_PCH_PCR_ITSS_ITSSPRC,
+			~cge8254_mask, cge8254_mask);
+}
+
+static void lpc_init(struct device *dev)
+{
+	/* Legacy initialization */
+	isa_dma_init();
+	reg_script_run_on_dev(dev, pch_misc_init_script);
+
+	/* Interrupt configuration */
+	pch_enable_ioapic(dev);
+	pch_pirq_init(dev);
+	setup_i8259();
+	i8259_configure_irq_trigger(9, 1);
+	clock_gate_8254(dev);
+}
+
+static void pch_lpc_add_mmio_resources(device_t dev)
+{
+	u32 reg;
+	struct resource *res;
+	/*
+	 * As per the BWG, Chapter 5.9.1. "PCH BIOS component will reserve
+	 * certain memory range as reserved range for BIOS usage.
+	 * For this SOC, the range will be from 0FD000000h till FE7FFFFFh"
+	 * Hence, use FD000000h as PCR_BASE
+	 */
+	const u32 default_decode_base = PCH_PCR_BASE_ADDRESS;
+
+	res = new_resource(dev, PCI_BASE_ADDRESS_0);
+	res->base = default_decode_base;
+	res->size = 0 - default_decode_base;
+	res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED |
+		     IORESOURCE_FIXED | IORESOURCE_RESERVE;
+
+	/* Check LPC Memory Decode register. */
+	reg = pci_read_config32(dev, LGMR);
+	if (reg & 1) {
+		reg &= ~0xffff;
+		if (reg < default_decode_base) {
+			res = new_resource(dev, LGMR);
+			res->base = reg;
+			res->size = 16 * 1024;
+			res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED |
+				     IORESOURCE_FIXED | IORESOURCE_RESERVE;
+		}
+	}
+}
+
+/* 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
+
+static inline int pch_io_range_in_default(u16 base, u16 size)
+{
+	/* Does it start above the range? */
+	if (base >= LPC_DEFAULT_IO_RANGE_UPPER)
+		return 0;
+
+	/*
+	 * Is it entirely contained?
+	 * Since LPC_DEFAULT_IO_RANGE_LOWER is Zero,
+	 * it need not be checked against lower base.
+	 */
+	if ((base + size) < LPC_DEFAULT_IO_RANGE_UPPER)
+		return 1;
+
+	/* This will return not in range for partial overlaps. */
+	return 0;
+}
+
+/*
+ * Note: this function assumes there is no overlap with the default LPC device's
+ * claimed range: LPC_DEFAULT_IO_RANGE_LOWER -> LPC_DEFAULT_IO_RANGE_UPPER.
+ */
+static void pch_lpc_add_io_resource(device_t dev, u16 base, u16 size, int index)
+{
+	struct resource *res;
+
+	if (pch_io_range_in_default(base, size))
+		return;
+
+	res = new_resource(dev, index);
+	res->base = base;
+	res->size = size;
+	res->flags = IORESOURCE_IO | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+}
+
+static void pch_lpc_add_gen_io_resources(device_t dev, int reg_value, int index)
+{
+	/*
+	 * Check if the register is enabled. If so and the base exceeds the
+	 * device's deafult claim range add the resoure.
+	 */
+	if (reg_value & 1) {
+		u16 base = reg_value & 0xfffc;
+		u16 size = (0x3 | ((reg_value >> 16) & 0xfc)) + 1;
+		pch_lpc_add_io_resource(dev, base, size, index);
+	}
+}
+
+static void pch_lpc_add_io_resources(device_t dev)
+{
+	struct resource *res;
+	config_t *config = dev->chip_info;
+
+	/* Add the default claimed IO range for the LPC device. */
+	res = new_resource(dev, 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_ASSIGNED | IORESOURCE_FIXED;
+
+	/* LPC Generic IO Decode range. */
+	pch_lpc_add_gen_io_resources(dev, config->gen1_dec, LPC_GEN1_DEC);
+	pch_lpc_add_gen_io_resources(dev, config->gen2_dec, LPC_GEN2_DEC);
+	pch_lpc_add_gen_io_resources(dev, config->gen3_dec, LPC_GEN3_DEC);
+	pch_lpc_add_gen_io_resources(dev, config->gen4_dec, LPC_GEN4_DEC);
+}
+
+static void pch_lpc_read_resources(device_t dev)
+{
+	global_nvs_t *gnvs;
+
+	/* Get the normal PCI resources of this device. */
+	pci_dev_read_resources(dev);
+
+	/* Add non-standard MMIO resources. */
+	pch_lpc_add_mmio_resources(dev);
+
+	/* Add IO resources. */
+	pch_lpc_add_io_resources(dev);
+
+	/* Allocate ACPI NVS in CBMEM */
+	gnvs = cbmem_add(CBMEM_ID_ACPI_GNVS, sizeof(global_nvs_t));
+	if (!acpi_is_wakeup_s3() && gnvs)
+		memset(gnvs, 0, sizeof(global_nvs_t));
+}
+
+static struct device_operations device_ops = {
+	.read_resources		= &pch_lpc_read_resources,
+	.set_resources		= &pci_dev_set_resources,
+	.enable_resources	= &pci_dev_enable_resources,
+	.acpi_inject_dsdt_generator = southcluster_inject_dsdt,
+	.write_acpi_tables	= southcluster_write_acpi_tables,
+	.init			= &lpc_init,
+	.scan_bus		= &scan_lpc_bus,
+	.ops_pci		= &soc_pci_ops,
+};
+
+static const unsigned short pci_device_ids[] = {
+	PCH_SPT_LP_SAMPLE,
+	PCH_SPT_LP_U_BASE,
+	PCH_SPT_LP_U_PREMIUM,
+	PCH_SPT_LP_Y_PREMIUM,
+	0
+};
+
+static const struct pci_driver pch_lpc __pci_driver = {
+	.ops	 = &device_ops,
+	.vendor	 = PCI_VENDOR_ID_INTEL,
+	.devices = pci_device_ids,
+};
diff --git a/src/soc/intel/kabylake/me_status.c b/src/soc/intel/kabylake/me_status.c
new file mode 100644
index 0000000..79d4dfb
--- /dev/null
+++ b/src/soc/intel/kabylake/me_status.c
@@ -0,0 +1,324 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008-2009 coresystems GmbH
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 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 <arch/io.h>
+#include <console/console.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <stdlib.h>
+#include <string.h>
+#include <soc/pci_devs.h>
+#include <soc/me.h>
+#include <delay.h>
+
+static inline void me_read_dword_ptr(void *ptr, int offset)
+{
+	u32 dword = pci_read_config32(PCH_DEV_ME, offset);
+	memcpy(ptr, &dword, sizeof(dword));
+}
+
+/* HFSTS1[3:0] Current Working State Values */
+static const char *me_cws_values[] = {
+	[ME_HFS_CWS_RESET]	= "Reset",
+	[ME_HFS_CWS_INIT]	= "Initializing",
+	[ME_HFS_CWS_REC]	= "Recovery",
+	[3]			= "Unknown (3)",
+	[4]			= "Unknown (4)",
+	[ME_HFS_CWS_NORMAL]	= "Normal",
+	[ME_HFS_CWS_WAIT]	= "Platform Disable Wait",
+	[ME_HFS_CWS_TRANS]	= "OP State Transition",
+	[ME_HFS_CWS_INVALID]	= "Invalid CPU Plugged In",
+	[9]			= "Unknown (9)",
+	[10]			= "Unknown (10)",
+	[11]			= "Unknown (11)",
+	[12]			= "Unknown (12)",
+	[13]			= "Unknown (13)",
+	[14]			= "Unknown (14)",
+	[15]			= "Unknown (15)",
+};
+
+/* HFSTS1[8:6] Current Operation State Values */
+static const char *me_opstate_values[] = {
+	[ME_HFS_STATE_PREBOOT]	= "Preboot",
+	[ME_HFS_STATE_M0_UMA]	= "M0 with UMA",
+	[ME_HFS_STATE_M3]	= "M3 without UMA",
+	[ME_HFS_STATE_M0]	= "M0 without UMA",
+	[ME_HFS_STATE_BRINGUP]	= "Bring up",
+	[ME_HFS_STATE_ERROR]	= "M0 without UMA but with error"
+};
+
+/* HFSTS1[19:16] Current Operation Mode Values */
+static const char *me_opmode_values[] = {
+	[ME_HFS_MODE_NORMAL]	= "Normal",
+	[ME_HFS_MODE_DEBUG]	= "Debug",
+	[ME_HFS_MODE_DIS]	= "Soft Temporary Disable",
+	[ME_HFS_MODE_OVER_JMPR]	= "Security Override via Jumper",
+	[ME_HFS_MODE_OVER_MEI]	= "Security Override via MEI Message"
+};
+
+/* HFSTS1[15:12] Error Code Values */
+static const char *me_error_values[] = {
+	[ME_HFS_ERROR_NONE]	= "No Error",
+	[ME_HFS_ERROR_UNCAT]	= "Uncategorized Failure",
+	[ME_HFS_ERROR_IMAGE]	= "Image Failure",
+	[ME_HFS_ERROR_DEBUG]	= "Debug Failure"
+};
+
+/* HFSTS2[31:28] ME Progress Code */
+static const char *me_progress_values[] = {
+	[ME_HFS2_PHASE_ROM]		= "ROM Phase",
+	[1]				= "Unknown (1)",
+	[ME_HFS2_PHASE_UKERNEL]		= "uKernel Phase",
+	[ME_HFS2_PHASE_BUP]		= "BUP Phase",
+	[4]				= "Unknown (4)",
+	[5]				= "Unknown (5)",
+	[ME_HFS2_PHASE_HOST_COMM]	= "Host Communication",
+	[7]				= "Unknown (7)",
+	[8]				= "Unknown (8)"
+};
+
+/* HFSTS2[27:24] Power Management Event */
+static const char *me_pmevent_values[] = {
+	[ME_HFS2_PMEVENT_CLEAN_MOFF_MX_WAKE] =
+	"Clean Moff->Mx wake",
+	[ME_HFS2_PMEVENT_MOFF_MX_WAKE_ERROR] =
+	"Moff->Mx wake after an error",
+	[ME_HFS2_PMEVENT_CLEAN_GLOBAL_RESET] =
+	"Clean global reset",
+	[ME_HFS2_PMEVENT_CLEAN_GLOBAL_RESET_ERROR] =
+	"Global reset after an error",
+	[ME_HFS2_PMEVENT_CLEAN_ME_RESET] =
+	"Clean Intel ME reset",
+	[ME_HFS2_PMEVENT_ME_RESET_EXCEPTION] =
+	"Intel ME reset due to exception",
+	[ME_HFS2_PMEVENT_PSEUDO_ME_RESET] =
+	"Pseudo-global reset",
+	[ME_HFS2_PMEVENT_CM0_CM3] =
+	"CM0->CM3",
+	[ME_HFS2_PMEVENT_CM3_CM0] =
+	"CM3->CM0",
+	[ME_HFS2_PMEVENT_NON_PWR_CYCLE_RESET] =
+	"Non-power cycle reset",
+	[ME_HFS2_PMEVENT_PWR_CYCLE_RESET_M3] =
+	"Power cycle reset through M3",
+	[ME_HFS2_PMEVENT_PWR_CYCLE_RESET_MOFF] =
+	"Power cycle reset through Moff",
+	[ME_HFS2_PMEVENT_CMX_CMOFF] =
+	"Cx/Mx->Cx/Moff",
+	[ME_HFS2_PMEVENT_CM0_CM0PG] =
+	"CM0->CM0PG",
+	[ME_HFS2_PMEVENT_CM3_CM3PG] =
+	"CM3->CM3PG",
+	[ME_HFS2_PMEVENT_CM0PG_CM0] =
+	"CM0PG->CM0"
+
+};
+
+/* Progress Code 0 states */
+static const char *me_progress_rom_values[] = {
+	[ME_HFS2_STATE_ROM_BEGIN]	= "BEGIN",
+	[ME_HFS2_STATE_ROM_DISABLE]	= "DISABLE"
+};
+
+/* Progress Code 1 states */
+static const char *me_progress_bup_values[] = {
+	[ME_HFS2_STATE_BUP_INIT] =
+	"Initialization starts",
+	[ME_HFS2_STATE_BUP_DIS_HOST_WAKE] =
+	"Disable the host wake event",
+	[ME_HFS2_STATE_BUP_CG_ENABLE] =
+	"Enabling CG for cset",
+	[ME_HFS2_STATE_BUP_PM_HND_EN] =
+	"Enabling PM handshaking",
+	[ME_HFS2_STATE_BUP_FLOW_DET] =
+	"Flow determination start process",
+	[ME_HFS2_STATE_BUP_PMC_PATCHING] =
+	"PMC Patching process",
+	[ME_HFS2_STATE_BUP_GET_FLASH_VSCC] =
+	"Get VSCC params",
+	[ME_HFS2_STATE_BUP_SET_FLASH_VSCC] =
+	"Set VSCC params",
+	[ME_HFS2_STATE_BUP_VSCC_ERR] =
+	"Error reading/matching the VSCC table in the descriptor",
+	[ME_HFS2_STATE_BUP_EFSS_INIT] =
+	"Initialize EFFS",
+	[ME_HFS2_STATE_BUP_CHECK_STRAP] =
+	"Check to see if straps say ME DISABLED",
+	[ME_HFS2_STATE_BUP_PWR_OK_TIMEOUT] =
+	"Timeout waiting for PWROK",
+	[ME_HFS2_STATE_BUP_STRAP_DIS] =
+	"EFFS says ME disabled",
+	[ME_HFS2_STATE_BUP_MANUF_OVRD_STRAP] =
+	"Possibly handle BUP manufacturing override strap",
+	[ME_HFS2_STATE_BUP_M3] =
+	"Bringup in M3",
+	[ME_HFS2_STATE_BUP_M0] =
+	"Bringup in M0",
+	[ME_HFS2_STATE_BUP_FLOW_DET_ERR] =
+	"Flow detection error",
+	[ME_HFS2_STATE_BUP_M3_CLK_ERR] =
+	"M3 clock switching error",
+	[ME_HFS2_STATE_BUP_CPU_RESET_DID_TIMEOUT_MEM_MISSING] =
+	"Host error - CPU reset timeout, DID timeout, memory missing",
+	[ME_HFS2_STATE_BUP_M3_KERN_LOAD] =
+	"M3 kernel load",
+	[ME_HFS2_STATE_BUP_T32_MISSING] =
+	"T34 missing - cannot program ICC",
+	[ME_HFS2_STATE_BUP_WAIT_DID] =
+	"Waiting for DID BIOS message",
+	[ME_HFS2_STATE_BUP_WAIT_DID_FAIL] =
+	"Waiting for DID BIOS message failure",
+	[ME_HFS2_STATE_BUP_DID_NO_FAIL] =
+	"DID reported no error",
+	[ME_HFS2_STATE_BUP_ENABLE_UMA] =
+	"Enabling UMA",
+	[ME_HFS2_STATE_BUP_ENABLE_UMA_ERR] =
+	"Enabling UMA error",
+	[ME_HFS2_STATE_BUP_SEND_DID_ACK] =
+	"Sending DID Ack to BIOS",
+	[ME_HFS2_STATE_BUP_SEND_DID_ACK_ERR] =
+	"Sending DID Ack to BIOS error",
+	[ME_HFS2_STATE_BUP_M0_CLK] =
+	"Switching clocks in M0",
+	[ME_HFS2_STATE_BUP_M0_CLK_ERR] =
+	"Switching clocks in M0 error",
+	[ME_HFS2_STATE_BUP_TEMP_DIS] =
+	"ME in temp disable",
+	[ME_HFS2_STATE_BUP_M0_KERN_LOAD] =
+	"M0 kernel load",
+};
+
+void intel_me_status(void)
+{
+	struct me_hfs _hfs, *hfs = &_hfs;
+	struct me_hfs2 _hfs2, *hfs2 = &_hfs2;
+	struct me_hfs3 _hfs3, *hfs3 = &_hfs3;
+
+	me_read_dword_ptr(hfs, PCI_ME_HFSTS1);
+	me_read_dword_ptr(hfs2, PCI_ME_HFSTS2);
+	me_read_dword_ptr(hfs3, PCI_ME_HFSTS3);
+
+	/* Check Current States */
+	printk(BIOS_DEBUG, "ME: FW Partition Table      : %s\n",
+	       hfs->fpt_bad ? "BAD" : "OK");
+	printk(BIOS_DEBUG, "ME: Bringup Loader Failure  : %s\n",
+	       hfs->ft_bup_ld_flr ? "YES" : "NO");
+	printk(BIOS_DEBUG, "ME: Firmware Init Complete  : %s\n",
+	       hfs->fw_init_complete ? "YES" : "NO");
+	printk(BIOS_DEBUG, "ME: Manufacturing Mode      : %s\n",
+	       hfs->mfg_mode ? "YES" : "NO");
+	printk(BIOS_DEBUG, "ME: Boot Options Present    : %s\n",
+	       hfs->boot_options_present ? "YES" : "NO");
+	printk(BIOS_DEBUG, "ME: Update In Progress      : %s\n",
+	       hfs->update_in_progress ? "YES" : "NO");
+	printk(BIOS_DEBUG, "ME: D3 Support              : %s\n",
+	       hfs->d3_support_valid ? "YES" : "NO");
+	printk(BIOS_DEBUG, "ME: D0i3 Support            : %s\n",
+	       hfs->d0i3_support_valid ? "YES" : "NO");
+	printk(BIOS_DEBUG, "ME: Low Power State Enabled : %s\n",
+	       hfs2->low_power_state ? "YES" : "NO");
+	printk(BIOS_DEBUG, "ME: Power Gated             : %s\n",
+	       hfs2->power_gating_ind ? "YES" : "NO");
+	printk(BIOS_DEBUG, "ME: CPU Replaced            : %s\n",
+	       hfs2->cpu_replaced_sts  ? "YES" : "NO");
+	printk(BIOS_DEBUG, "ME: CPU Replacement Valid   : %s\n",
+	       hfs2->cpu_replaced_valid ? "YES" : "NO");
+	printk(BIOS_DEBUG, "ME: Current Working State   : %s\n",
+	       me_cws_values[hfs->working_state]);
+	printk(BIOS_DEBUG, "ME: Current Operation State : %s\n",
+	       me_opstate_values[hfs->operation_state]);
+	printk(BIOS_DEBUG, "ME: Current Operation Mode  : %s\n",
+	       me_opmode_values[hfs->operation_mode]);
+	printk(BIOS_DEBUG, "ME: Error Code              : %s\n",
+	       me_error_values[hfs->error_code]);
+	printk(BIOS_DEBUG, "ME: Progress Phase          : %s\n",
+	       me_progress_values[hfs2->progress_code]);
+	printk(BIOS_DEBUG, "ME: Power Management Event  : %s\n",
+	       me_pmevent_values[hfs2->current_pmevent]);
+
+	printk(BIOS_DEBUG, "ME: Progress Phase State    : ");
+	switch (hfs2->progress_code) {
+	case ME_HFS2_PHASE_ROM:		/* ROM Phase */
+		printk(BIOS_DEBUG, "%s",
+		       me_progress_rom_values[hfs2->current_state]);
+		break;
+
+	case ME_HFS2_PHASE_UKERNEL:	/* uKernel Phase */
+		printk(BIOS_DEBUG, "0x%02x", hfs2->current_state);
+		break;
+
+	case ME_HFS2_PHASE_BUP:		/* Bringup Phase */
+		if (hfs2->current_state < ARRAY_SIZE(me_progress_bup_values)
+		    && me_progress_bup_values[hfs2->current_state])
+			printk(BIOS_DEBUG, "%s",
+			       me_progress_bup_values[hfs2->current_state]);
+		else
+			printk(BIOS_DEBUG, "0x%02x", hfs2->current_state);
+		break;
+
+	case ME_HFS2_PHASE_HOST_COMM:	/* Host Communication Phase */
+		if (!hfs2->current_state)
+			printk(BIOS_DEBUG, "Host communication established");
+		else
+			printk(BIOS_DEBUG, "0x%02x", hfs2->current_state);
+		break;
+
+	default:
+		printk(BIOS_DEBUG, "Unknown phase: 0x%02x state: 0x%02x",
+		       hfs2->progress_code, hfs2->current_state);
+	}
+	printk(BIOS_DEBUG, "\n");
+
+	/* Power Down Mitigation Status */
+	printk(BIOS_DEBUG, "ME: Power Down Mitigation   : %s\n",
+	       hfs3->power_down_mitigation ? "YES" : "NO");
+
+	if (hfs3->power_down_mitigation) {
+		printk(BIOS_INFO, "ME: PD Mitigation State     : ");
+		if (hfs3->encrypt_key_override == 1 &&
+		    hfs3->encrypt_key_check == 0 &&
+		    hfs3->pch_config_change == 0)
+			printk(BIOS_INFO, "Normal Operation");
+		else if (hfs3->encrypt_key_override == 1 &&
+			 hfs3->encrypt_key_check == 1 &&
+			 hfs3->pch_config_change == 0)
+			printk(BIOS_INFO, "Issue Detected and Recovered");
+		else
+			printk(BIOS_INFO, "Issue Detected but not Recovered");
+		printk(BIOS_INFO, "\n");
+
+		printk(BIOS_DEBUG, "ME: Encryption Key Override : %s\n",
+		       hfs3->encrypt_key_override ? "Workaround Applied" :
+		       "Unable to override");
+		printk(BIOS_DEBUG, "ME: Encryption Key Check    : %s\n",
+		       hfs3->encrypt_key_check ? "FAIL" : "PASS");
+		printk(BIOS_DEBUG, "ME: PCH Configuration Info  : %s\n",
+		       hfs3->pch_config_change ? "Changed" : "No Change");
+
+		printk(BIOS_DEBUG, "ME: Firmware SKU            : ");
+		switch (hfs3->fw_sku) {
+		case ME_HFS3_FW_SKU_CONSUMER:
+			printk(BIOS_DEBUG, "Consumer\n");
+			break;
+		case ME_HFS3_FW_SKU_CORPORATE:
+			printk(BIOS_DEBUG, "Corporate\n");
+			break;
+		default:
+			printk(BIOS_DEBUG, "Unknown (0x%x)\n", hfs3->fw_sku);
+		}
+	}
+}
diff --git a/src/soc/intel/kabylake/memmap.c b/src/soc/intel/kabylake/memmap.c
new file mode 100644
index 0000000..a4c0c0b
--- /dev/null
+++ b/src/soc/intel/kabylake/memmap.c
@@ -0,0 +1,207 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * 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 <arch/io.h>
+#include <cbmem.h>
+#include <chip.h>
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <soc/msr.h>
+#include <soc/pci_devs.h>
+#include <soc/romstage.h>
+#include <soc/smm.h>
+#include <soc/systemagent.h>
+#include <stdlib.h>
+
+size_t mmap_region_granularity(void)
+{
+	if (IS_ENABLED(CONFIG_HAVE_SMI_HANDLER))
+		/* Align to TSEG size when SMM is in use */
+		if (CONFIG_SMM_TSEG_SIZE != 0)
+			return CONFIG_SMM_TSEG_SIZE;
+
+	/* Make it 8MiB by default. */
+	return 8*MiB;
+}
+
+/* Returns base of requested region encoded in the system agent. */
+static inline uintptr_t system_agent_region_base(size_t reg)
+{
+	/* All regions concerned for have 1 MiB alignment. */
+	return ALIGN_DOWN(pci_read_config32(SA_DEV_ROOT, reg), 1*MiB);
+}
+
+static inline uintptr_t smm_region_start(void)
+{
+	return system_agent_region_base(TSEG);
+}
+
+static inline size_t smm_region_size(void)
+{
+	return system_agent_region_base(BGSM) - smm_region_start();
+}
+
+void smm_region(void **start, size_t *size)
+{
+	*start = (void *)smm_region_start();
+	*size = smm_region_size();
+}
+
+/*
+ *        Subregions within SMM
+ *     +-------------------------+ BGSM
+ *     |          IED            | IED_REGION_SIZE
+ *     +-------------------------+
+ *     |  External Stage Cache   | SMM_RESERVED_SIZE
+ *     +-------------------------+
+ *     |      code and data      |
+ *     |         (TSEG)          |
+ *     +-------------------------+ TSEG
+ */
+int smm_subregion(int sub, void **start, size_t *size)
+{
+	uintptr_t sub_base;
+	size_t sub_size;
+	const size_t ied_size = CONFIG_IED_REGION_SIZE;
+	const size_t cache_size = CONFIG_SMM_RESERVED_SIZE;
+
+	sub_base = smm_region_start();
+	sub_size = smm_region_size();
+
+	switch (sub) {
+	case SMM_SUBREGION_HANDLER:
+		/* Handler starts at the base of TSEG. */
+		sub_size -= ied_size;
+		sub_size -= cache_size;
+		break;
+	case SMM_SUBREGION_CACHE:
+		/* External cache is in the middle of TSEG. */
+		sub_base += sub_size - (ied_size + cache_size);
+		sub_size = cache_size;
+		break;
+	case SMM_SUBREGION_CHIPSET:
+		/* IED is at the top. */
+		sub_base += sub_size - ied_size;
+		sub_size = ied_size;
+		break;
+	default:
+		return -1;
+	}
+
+	*start = (void *)sub_base;
+	*size = sub_size;
+
+	return 0;
+}
+
+/*
+ * Host Memory Map:
+ *
+ * +--------------------------+ TOUUD
+ * |                          |
+ * +--------------------------+ 4GiB
+ * |     PCI Address Space    |
+ * +--------------------------+ TOLUD (also maps into MC address space)
+ * |     iGD                  |
+ * +--------------------------+ BDSM
+ * |     GTT                  |
+ * +--------------------------+ BGSM
+ * |     TSEG                 |
+ * +--------------------------+ TSEGMB
+ * |   DMA Protected Region   |
+ * +--------------------------+ DPR
+ * |    PRM (C6DRAM/SGX)      |
+ * +--------------------------+ PRMRR
+ * |     Trace Memory         |
+ * +--------------------------+ top_of_ram
+ * |     Reserved - FSP/CBMEM |
+ * +--------------------------+ TOLUM
+ * |     Usage DRAM           |
+ * +--------------------------+ 0
+ *
+ * Some of the base registers above can be equal making the size of those
+ * regions 0. The reason is because the memory controller internally subtracts
+ * the base registers from each other to determine sizes of the regions. In
+ * other words, the memory map is in a fixed order no matter what.
+ */
+
+u32 top_of_32bit_ram(void)
+{
+	msr_t prmrr_base;
+	u32 top_of_ram;
+	const struct device *dev;
+	const struct soc_intel_kabylake_config *config;
+
+	/*
+	 * Check if Tseg has been initialized, we will use this as a flag
+	 * to check if the MRC is done, and only then continue to read the
+	 * PRMMR_BASE MSR. The system hangs if PRMRR_BASE MSR is read before
+	 * PRMRR_MASK MSR lock bit is set.
+	 */
+	if (smm_region_start() == 0)
+		return 0;
+
+	dev = dev_find_slot(0, PCI_DEVFN(SA_DEV_SLOT_ROOT, 0));
+	config = dev->chip_info;
+
+	/*
+	 * On Kabylake, cbmem_top is offset down from PRMRR_BASE by reserved
+	 * memory (128MiB) for CPU trace if enabled, then reserved memory (4KB)
+	 * for PTT if enabled. PTT is in fact not used on Kabylake platforms.
+	 * Refer to Fsp Integration Guide for the memory mapping layout.
+	 */
+	prmrr_base = rdmsr(UNCORE_PRMRR_PHYS_BASE_MSR);
+	top_of_ram = prmrr_base.lo;
+
+	if (config->ProbelessTrace)
+		top_of_ram -= TRACE_MEMORY_SIZE;
+
+	return top_of_ram;
+}
+
+void *cbmem_top(void)
+{
+	/*
+	 *     +-------------------------+  Top of RAM (aligned)
+	 *     | System Management Mode  |
+	 *     |      code and data      |  Length: CONFIG_TSEG_SIZE
+	 *     |         (TSEG)          |
+	 *     +-------------------------+  SMM base (aligned)
+	 *     |                         |
+	 *     | Chipset Reserved Memory |
+	 *     |                         |
+	 *     +-------------------------+  top_of_ram (aligned)
+	 *     |                         |
+	 *     |       CBMEM Root        |
+	 *     |                         |
+	 *     +-------------------------+
+	 *     |                         |
+	 *     |   FSP Reserved Memory   |
+	 *     |                         |
+	 *     +-------------------------+
+	 *     |                         |
+	 *     |  Various CBMEM Entries  |
+	 *     |                         |
+	 *     +-------------------------+  top_of_stack (8 byte aligned)
+	 *     |                         |
+	 *     |   stack (CBMEM Entry)   |
+	 *     |                         |
+	 *     +-------------------------+
+	 */
+	return (void *)top_of_32bit_ram();
+}
+
diff --git a/src/soc/intel/kabylake/monotonic_timer.c b/src/soc/intel/kabylake/monotonic_timer.c
new file mode 100644
index 0000000..d2a4879
--- /dev/null
+++ b/src/soc/intel/kabylake/monotonic_timer.c
@@ -0,0 +1,39 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * 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 <stdint.h>
+#include <cpu/x86/msr.h>
+#include <timer.h>
+#include <soc/msr.h>
+
+static inline uint32_t read_counter_msr(void)
+{
+	/*
+	 * Even though the MSR is 64-bit it is assumed that the hardware
+	 * is polled frequently enough to only use the lower 32-bits.
+	 */
+	msr_t counter_msr;
+
+	counter_msr = rdmsr(MSR_COUNTER_24_MHZ);
+
+	return counter_msr.lo;
+}
+
+void timer_monotonic_get(struct mono_time *mt)
+{
+	/* Always increases. Don't normalize to 0 between stages. */
+	mono_time_set_usecs(mt, read_counter_msr() / 24);
+}
diff --git a/src/soc/intel/kabylake/nhlt/Makefile.inc b/src/soc/intel/kabylake/nhlt/Makefile.inc
new file mode 100644
index 0000000..9a572d0
--- /dev/null
+++ b/src/soc/intel/kabylake/nhlt/Makefile.inc
@@ -0,0 +1,47 @@
+ramstage-y += dmic.c
+ramstage-y += nau88l25.c
+ramstage-y += max98357.c
+ramstage-y += ssm4567.c
+
+# DSP firmware settings files.
+NHLT_BLOB_PATH = 3rdparty/blobs/soc/intel/kabylake
+DMIC_2CH_48KHZ_16B = dmic-2ch-48khz-16b.bin
+DMIC_2CH_48KHZ_32B = dmic-2ch-48khz-32b.bin
+DMIC_4CH_48KHZ_16B = dmic-4ch-48khz-16b.bin
+DMIC_4CH_48KHZ_32B = dmic-4ch-48khz-32b.bin
+NAU88L25 = nau88l25-2ch-48khz-24b.bin
+MAX98357_RENDER = max98357-render-2ch-48khz-24b.bin
+SSM4567_RENDER = ssm4567-render-2ch-48khz-24b.bin
+SSM4567_CAPTURE = ssm4567-capture-4ch-48khz-32b.bin
+
+cbfs-files-$(CONFIG_NHLT_DMIC_2CH) += $(DMIC_2CH_48KHZ_16B)
+$(DMIC_2CH_48KHZ_16B)-file := $(NHLT_BLOB_PATH)/$(DMIC_2CH_48KHZ_16B)
+$(DMIC_2CH_48KHZ_16B)-type := raw
+
+cbfs-files-$(CONFIG_NHLT_DMIC_2CH) += $(DMIC_2CH_48KHZ_32B)
+$(DMIC_2CH_48KHZ_32B)-file := $(NHLT_BLOB_PATH)/$(DMIC_2CH_48KHZ_32B)
+$(DMIC_2CH_48KHZ_32B)-type := raw
+
+cbfs-files-$(CONFIG_NHLT_DMIC_4CH) += $(DMIC_4CH_48KHZ_16B)
+$(DMIC_4CH_48KHZ_16B)-file := $(NHLT_BLOB_PATH)/$(DMIC_4CH_48KHZ_16B)
+$(DMIC_4CH_48KHZ_16B)-type := raw
+
+cbfs-files-$(CONFIG_NHLT_DMIC_4CH) += $(DMIC_4CH_48KHZ_32B)
+$(DMIC_4CH_48KHZ_32B)-file := $(NHLT_BLOB_PATH)/$(DMIC_4CH_48KHZ_32B)
+$(DMIC_4CH_48KHZ_32B)-type := raw
+
+cbfs-files-$(CONFIG_NHLT_NAU88L25) += $(NAU88L25)
+$(NAU88L25)-file := $(NHLT_BLOB_PATH)/$(NAU88L25)
+$(NAU88L25)-type := raw
+
+cbfs-files-$(CONFIG_NHLT_MAX98357) += $(MAX98357_RENDER)
+$(MAX98357_RENDER)-file := $(NHLT_BLOB_PATH)/$(MAX98357_RENDER)
+$(MAX98357_RENDER)-type := raw
+
+cbfs-files-$(CONFIG_NHLT_SSM4567) += $(SSM4567_RENDER)
+$(SSM4567_RENDER)-file := $(NHLT_BLOB_PATH)/$(SSM4567_RENDER)
+$(SSM4567_RENDER)-type := raw
+
+cbfs-files-$(CONFIG_NHLT_SSM4567) += $(SSM4567_CAPTURE)
+$(SSM4567_CAPTURE)-file := $(NHLT_BLOB_PATH)/$(SSM4567_CAPTURE)
+$(SSM4567_CAPTURE)-type := raw
diff --git a/src/soc/intel/kabylake/nhlt/dmic.c b/src/soc/intel/kabylake/nhlt/dmic.c
new file mode 100644
index 0000000..a7684bd
--- /dev/null
+++ b/src/soc/intel/kabylake/nhlt/dmic.c
@@ -0,0 +1,116 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2015 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.
+ */
+
+#include <soc/nhlt.h>
+
+static const struct nhlt_format_config dmic_2ch_formats[] = {
+	/* 48 KHz 16-bits per sample. */
+	{
+		.num_channels = 2,
+		.sample_freq_khz = 48,
+		.container_bits_per_sample = 16,
+		.valid_bits_per_sample = 16,
+		.speaker_mask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT,
+		.settings_file = "dmic-2ch-48khz-16b.bin",
+	},
+	/* 48 KHz 32-bits per sample. */
+	{
+		.num_channels = 2,
+		.sample_freq_khz = 48,
+		.container_bits_per_sample = 32,
+		.valid_bits_per_sample = 32,
+		.speaker_mask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT,
+		.settings_file = "dmic-2ch-48khz-32b.bin",
+	},
+};
+
+static const struct nhlt_dmic_array_config dmic_2ch_mic_config = {
+	.tdm_config = {
+		.config_type = NHLT_TDM_MIC_ARRAY,
+	},
+	.array_type = NHLT_MIC_ARRAY_2CH_SMALL,
+};
+
+static const struct nhlt_endp_descriptor dmic_2ch_descriptors[] = {
+	{
+		.link = NHLT_LINK_PDM,
+		.device = NHLT_PDM_DEV,
+		.direction = NHLT_DIR_CAPTURE,
+		.vid = NHLT_VID,
+		.did = NHLT_DID_DMIC,
+		.cfg = &dmic_2ch_mic_config,
+		.cfg_size = sizeof(dmic_2ch_mic_config),
+		.formats = dmic_2ch_formats,
+		.num_formats = ARRAY_SIZE(dmic_2ch_formats),
+	},
+};
+
+static const struct nhlt_format_config dmic_4ch_formats[] = {
+	/* 48 KHz 16-bits per sample. */
+	{
+		.num_channels = 4,
+		.sample_freq_khz = 48,
+		.container_bits_per_sample = 16,
+		.valid_bits_per_sample = 16,
+		.speaker_mask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT |
+				SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT,
+		.settings_file = "dmic-4ch-48khz-16b.bin",
+	},
+	/* 48 KHz 32-bits per sample. */
+	{
+		.num_channels = 4,
+		.sample_freq_khz = 48,
+		.container_bits_per_sample = 32,
+		.valid_bits_per_sample = 32,
+		.speaker_mask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT |
+				SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT,
+		.settings_file = "dmic-4ch-48khz-32b.bin",
+	},
+};
+
+static const struct nhlt_dmic_array_config dmic_4ch_mic_config = {
+	.tdm_config = {
+		.config_type = NHLT_TDM_MIC_ARRAY,
+	},
+	.array_type = NHLT_MIC_ARRAY_4CH_L_SHAPED,
+};
+
+static const struct nhlt_endp_descriptor dmic_4ch_descriptors[] = {
+	{
+		.link = NHLT_LINK_PDM,
+		.device = NHLT_PDM_DEV,
+		.direction = NHLT_DIR_CAPTURE,
+		.vid = NHLT_VID,
+		.did = NHLT_DID_DMIC,
+		.cfg = &dmic_4ch_mic_config,
+		.cfg_size = sizeof(dmic_4ch_mic_config),
+		.formats = dmic_4ch_formats,
+		.num_formats = ARRAY_SIZE(dmic_4ch_formats),
+	},
+};
+
+int nhlt_soc_add_dmic_array(struct nhlt *nhlt, int num_channels)
+{
+	switch (num_channels) {
+	case 2:
+		return nhlt_add_endpoints(nhlt, dmic_2ch_descriptors,
+					ARRAY_SIZE(dmic_2ch_descriptors));
+	case 4:
+		return nhlt_add_endpoints(nhlt, dmic_4ch_descriptors,
+					ARRAY_SIZE(dmic_4ch_descriptors));
+	default:
+		return -1;
+	}
+}
diff --git a/src/soc/intel/kabylake/nhlt/max98357.c b/src/soc/intel/kabylake/nhlt/max98357.c
new file mode 100644
index 0000000..b2abc26
--- /dev/null
+++ b/src/soc/intel/kabylake/nhlt/max98357.c
@@ -0,0 +1,47 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2015 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.
+ */
+
+#include <soc/nhlt.h>
+
+static const struct nhlt_format_config max98357_render_formats[] = {
+	/* 48 KHz 24-bits per sample. */
+	{
+		.num_channels = 2,
+		.sample_freq_khz = 48,
+		.container_bits_per_sample = 32,
+		.valid_bits_per_sample = 24,
+		.speaker_mask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT,
+		.settings_file = "max98357-render-2ch-48khz-24b.bin",
+	},
+};
+
+static const struct nhlt_endp_descriptor max98357_descriptors[] = {
+	{
+		.link = NHLT_LINK_SSP,
+		.device = NHLT_SSP_DEV_I2S,
+		.direction = NHLT_DIR_RENDER,
+		.vid = NHLT_VID,
+		.did = NHLT_DID_SSP,
+		.formats = max98357_render_formats,
+		.num_formats = ARRAY_SIZE(max98357_render_formats),
+	},
+};
+
+int nhlt_soc_add_max98357(struct nhlt *nhlt, int hwlink)
+{
+	/* Virtual bus id of SSP links are the hardware port ids proper. */
+	return nhlt_add_ssp_endpoints(nhlt, hwlink, max98357_descriptors,
+					ARRAY_SIZE(max98357_descriptors));
+}
diff --git a/src/soc/intel/kabylake/nhlt/nau88l25.c b/src/soc/intel/kabylake/nhlt/nau88l25.c
new file mode 100644
index 0000000..dd91435
--- /dev/null
+++ b/src/soc/intel/kabylake/nhlt/nau88l25.c
@@ -0,0 +1,71 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2015 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.
+ */
+
+#include <soc/nhlt.h>
+
+/* The same DSP firmware settings are used for both the capture and
+ * render endpoints. */
+static const struct nhlt_format_config nau88l25_formats[] = {
+	/* 48 KHz 24-bits per sample. */
+	{
+		.num_channels = 2,
+		.sample_freq_khz = 48,
+		.container_bits_per_sample = 32,
+		.valid_bits_per_sample = 24,
+		.speaker_mask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT,
+		.settings_file = "nau88l25-2ch-48khz-24b.bin",
+	},
+};
+
+/* The nau88l25 just has headphones and a mic. Both the capture and render
+ * endpoints occupy the same virtual slot. */
+static const struct nhlt_tdm_config tdm_config = {
+	.virtual_slot = 0,
+	.config_type = NHLT_TDM_BASIC,
+};
+
+static const struct nhlt_endp_descriptor nau88l25_descriptors[] = {
+	/* Render Endpoint */
+	{
+		.link = NHLT_LINK_SSP,
+		.device = NHLT_SSP_DEV_I2S,
+		.direction = NHLT_DIR_RENDER,
+		.vid = NHLT_VID,
+		.did = NHLT_DID_SSP,
+		.cfg = &tdm_config,
+		.cfg_size = sizeof(tdm_config),
+		.formats = nau88l25_formats,
+		.num_formats = ARRAY_SIZE(nau88l25_formats),
+	},
+	/* Capture Endpoint */
+	{
+		.link = NHLT_LINK_SSP,
+		.device = NHLT_SSP_DEV_I2S,
+		.direction = NHLT_DIR_CAPTURE,
+		.vid = NHLT_VID,
+		.did = NHLT_DID_SSP,
+		.cfg = &tdm_config,
+		.cfg_size = sizeof(tdm_config),
+		.formats = nau88l25_formats,
+		.num_formats = ARRAY_SIZE(nau88l25_formats),
+	},
+};
+
+int nhlt_soc_add_nau88l25(struct nhlt *nhlt, int hwlink)
+{
+	/* Virtual bus id of SSP links are the hardware port ids proper. */
+	return nhlt_add_ssp_endpoints(nhlt, hwlink, nau88l25_descriptors,
+					ARRAY_SIZE(nau88l25_descriptors));
+}
diff --git a/src/soc/intel/kabylake/nhlt/ssm4567.c b/src/soc/intel/kabylake/nhlt/ssm4567.c
new file mode 100644
index 0000000..6808bff
--- /dev/null
+++ b/src/soc/intel/kabylake/nhlt/ssm4567.c
@@ -0,0 +1,70 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2015 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.
+ */
+
+#include <soc/nhlt.h>
+
+static const struct nhlt_format_config ssm4567_render_formats[] = {
+	/* 48 KHz 24-bits per sample. */
+	{
+		.num_channels = 2,
+		.sample_freq_khz = 48,
+		.container_bits_per_sample = 32,
+		.valid_bits_per_sample = 24,
+		.speaker_mask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT,
+		.settings_file = "ssm4567-render-2ch-48khz-24b.bin",
+	},
+};
+
+/* Capture Blob used for IV feedback for Speaker Protection Algorithm */
+static const struct nhlt_format_config ssm4567_capture_formats[] = {
+	/* 48 KHz 32-bits per sample. */
+	{
+		.num_channels = 4,
+		.sample_freq_khz = 48,
+		.container_bits_per_sample = 32,
+		.valid_bits_per_sample = 32,
+		.settings_file = "ssm4567-capture-4ch-48khz-32b.bin",
+	},
+};
+
+static const struct nhlt_endp_descriptor ssm4567_descriptors[] = {
+	/* Render Endpoint */
+	{
+		.link = NHLT_LINK_SSP,
+		.device = NHLT_SSP_DEV_I2S,
+		.direction = NHLT_DIR_RENDER,
+		.vid = NHLT_VID,
+		.did = NHLT_DID_SSP,
+		.formats = ssm4567_render_formats,
+		.num_formats = ARRAY_SIZE(ssm4567_render_formats),
+	},
+	/* Capture Endpoint */
+	{
+		.link = NHLT_LINK_SSP,
+		.device = NHLT_SSP_DEV_I2S,
+		.direction = NHLT_DIR_CAPTURE,
+		.vid = NHLT_VID,
+		.did = NHLT_DID_SSP,
+		.formats = ssm4567_capture_formats,
+		.num_formats = ARRAY_SIZE(ssm4567_capture_formats),
+	},
+};
+
+int nhlt_soc_add_ssm4567(struct nhlt *nhlt, int hwlink)
+{
+	/* Virtual bus id of SSP links are the hardware port ids proper. */
+	return nhlt_add_ssp_endpoints(nhlt, hwlink, ssm4567_descriptors,
+					ARRAY_SIZE(ssm4567_descriptors));
+}
diff --git a/src/soc/intel/kabylake/pch.c b/src/soc/intel/kabylake/pch.c
new file mode 100644
index 0000000..cf221ad
--- /dev/null
+++ b/src/soc/intel/kabylake/pch.c
@@ -0,0 +1,97 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008-2009 coresystems GmbH
+ * Copyright (C) 2014 Google Inc.
+ * 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 <console/console.h>
+#include <delay.h>
+#include <arch/io.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_def.h>
+#include <soc/pch.h>
+#include <soc/pci_devs.h>
+#include <soc/ramstage.h>
+#include <soc/spi.h>
+
+u8 pch_revision(void)
+{
+	return pci_read_config8(PCH_DEV_LPC, PCI_REVISION_ID);
+}
+
+u16 pch_type(void)
+{
+	return pci_read_config16(PCH_DEV_LPC, PCI_DEVICE_ID);
+}
+
+void *get_spi_bar(void)
+{
+	device_t dev = PCH_DEV_SPI;
+	uint32_t bar;
+
+	bar = pci_read_config32(dev, PCI_BASE_ADDRESS_0);
+	/* Bits 31-12 are the base address as per EDS for SPI 1F/5,
+	 *  Don't care about  0-11 bit
+	 */
+	return (void *)(bar & ~PCI_BASE_ADDRESS_MEM_ATTR_MASK);
+}
+
+u32 pch_read_soft_strap(int id)
+{
+	uint32_t fdoc;
+	void *spibar = get_spi_bar();
+
+	fdoc = read32(spibar + SPIBAR_FDOC);
+	fdoc &= ~0x00007ffc;
+	write32(spibar + SPIBAR_FDOC, fdoc);
+
+	fdoc |= 0x00004000;
+	fdoc |= id * 4;
+	write32(spibar + SPIBAR_FDOC, fdoc);
+
+	return read32(spibar + SPIBAR_FDOD);
+}
+
+#if ENV_RAMSTAGE
+void pch_enable_dev(device_t dev)
+{
+	/* FSP should implement routines to disable PCH IPs */
+	u32 reg32;
+
+	/* These devices need special enable/disable handling */
+	switch (PCI_SLOT(dev->path.pci.devfn)) {
+	case PCH_DEV_SLOT_PCIE:
+		return;
+	}
+
+	if (!dev->enabled) {
+		printk(BIOS_DEBUG, "%s: Disabling device\n", dev_path(dev));
+
+		/* 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);
+
+		/* Disable this device if possible */
+	} else {
+		/* Enable SERR */
+		reg32 = pci_read_config32(dev, PCI_COMMAND);
+		reg32 |= PCI_COMMAND_SERR;
+		pci_write_config32(dev, PCI_COMMAND, reg32);
+	}
+}
+
+#endif
diff --git a/src/soc/intel/kabylake/pcie.c b/src/soc/intel/kabylake/pcie.c
new file mode 100644
index 0000000..f594bf1
--- /dev/null
+++ b/src/soc/intel/kabylake/pcie.c
@@ -0,0 +1,106 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008-2009 coresystems GmbH
+ * Copyright (C) 2014 Google Inc.
+ * 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 <chip.h>
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pciexp.h>
+#include <device/pci_def.h>
+#include <device/pci_ids.h>
+#include <soc/gpio.h>
+#include <soc/lpc.h>
+#include <soc/pch.h>
+#include <soc/pci_devs.h>
+#include <soc/cpu.h>
+#include <delay.h>
+
+static void pch_pcie_init(struct device *dev)
+{
+	u16 reg16;
+	u32 reg32;
+
+	printk(BIOS_DEBUG, "Initializing PCH PCIe bridge.\n");
+
+	/* Enable SERR */
+	reg32 = pci_read_config32(dev, PCI_COMMAND);
+	reg32 |= PCI_COMMAND_SERR;
+	pci_write_config32(dev, PCI_COMMAND, reg32);
+
+	/* Enable Bus Master */
+	reg32 = pci_read_config32(dev, PCI_COMMAND);
+	reg32 |= PCI_COMMAND_MASTER;
+	pci_write_config32(dev, PCI_COMMAND, reg32);
+
+	/* Set Cache Line Size to 0x10 */
+	pci_write_config8(dev, 0x0c, 0x10);
+
+	reg16 = pci_read_config16(dev, 0x3e);
+	reg16 &= ~(1 << 0); /* disable parity error response */
+	reg16 |= (1 << 2); /* ISA enable */
+	pci_write_config16(dev, 0x3e, reg16);
+
+#ifdef EVEN_MORE_DEBUG
+	reg32 = pci_read_config32(dev, 0x20);
+	printk(BIOS_SPEW, "    MBL    = 0x%08x\n", reg32);
+	reg32 = pci_read_config32(dev, 0x24);
+	printk(BIOS_SPEW, "    PMBL   = 0x%08x\n", reg32);
+	reg32 = pci_read_config32(dev, 0x28);
+	printk(BIOS_SPEW, "    PMBU32 = 0x%08x\n", reg32);
+	reg32 = pci_read_config32(dev, 0x2c);
+	printk(BIOS_SPEW, "    PMLU32 = 0x%08x\n", reg32);
+#endif
+
+	/* Clear errors in status registers */
+	reg16 = pci_read_config16(dev, 0x06);
+	pci_write_config16(dev, 0x06, reg16);
+	reg16 = pci_read_config16(dev, 0x1e);
+	pci_write_config16(dev, 0x1e, reg16);
+}
+
+static void pcie_set_L1_ss_max_latency(device_t dev, unsigned int off)
+{
+	/* Set max snoop and non-snoop latency for the SOC */
+	pci_mmio_write_config32(dev, off, 0x10031003);
+}
+
+static struct pci_operations pcie_ops = {
+	.set_L1_ss_latency = pcie_set_L1_ss_max_latency,
+};
+
+static struct device_operations device_ops = {
+	.read_resources		= pci_bus_read_resources,
+	.set_resources		= pci_dev_set_resources,
+	.enable_resources	= pci_bus_enable_resources,
+	.init			= pch_pcie_init,
+	.enable			= NULL,
+	.scan_bus		= pciexp_scan_bridge,
+	.ops_pci		= &pcie_ops,
+};
+
+static const unsigned short pcie_device_ids[] = {
+	/* Sunrisepoint-LP */
+	0x9d10, 0x9d11, 0x9d12, 0x9d13, 0x9d14, 0x9d15, 0x9d16, 0x9d17,
+	0x9d18, 0x9d19, 0x9d1a, 0x9d1b,
+	0
+};
+
+static const struct pci_driver pch_pcie __pci_driver = {
+	.ops	 = &device_ops,
+	.vendor	 = PCI_VENDOR_ID_INTEL,
+	.devices = pcie_device_ids,
+};
diff --git a/src/soc/intel/kabylake/pcr.c b/src/soc/intel/kabylake/pcr.c
new file mode 100644
index 0000000..260cadd
--- /dev/null
+++ b/src/soc/intel/kabylake/pcr.c
@@ -0,0 +1,187 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * 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 <stdint.h>
+#include <string.h>
+#include <arch/io.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <soc/pcr.h>
+#include <soc/iomap.h>
+#include <console/console.h>
+
+static inline void *pcr_reg_address(u8 pid, u16 offset)
+{
+	uintptr_t reg_addr;
+
+	/* Create an address based off of port id and offset. */
+	reg_addr = PCH_PCR_BASE_ADDRESS;
+	reg_addr += ((uintptr_t)pid) << PCR_PORTID_SHIFT;
+	reg_addr += ((uintptr_t)offset) << PCR_OFFSET_SHIFT;
+
+	return (void *)reg_addr;
+}
+
+uint8_t *pcr_port_regs(u8 pid)
+{
+	return pcr_reg_address(pid, 0);
+}
+
+/*
+ * Read PCR register. (This is internal function)
+ * It returns PCR register and size in 1/2/4 bytes.
+ * The offset should not exceed 0xFFFF and must be aligned with size
+ */
+static int pch_pcr_read(u8 pid, u16 offset, u32 size, void *data)
+{
+	if ((offset & (size - 1)) != 0) {
+		printk(BIOS_DEBUG,
+			"PchPcrRead error. Invalid Offset: %x Size: %x",
+			offset, size);
+		return -1;
+	}
+	switch (size) {
+	case 4:
+		*(u32 *) data = read32(pcr_reg_address(pid, offset));
+		break;
+	case 2:
+		*(u16 *) data = read16(pcr_reg_address(pid, offset));
+		break;
+	case 1:
+		*(u8 *) data = read8(pcr_reg_address(pid, offset));
+		break;
+	default:
+		return -1;
+	}
+	return 0;
+}
+
+int pcr_read32(u8 pid, u16 offset, u32 *outdata)
+{
+	return pch_pcr_read(pid, offset, sizeof(u32), (u32 *)outdata);
+}
+
+int pcr_read16(u8 pid, u16 offset, u16 *outdata)
+{
+	return pch_pcr_read(pid, offset, sizeof(u16), (u32 *)outdata);
+}
+
+int pcr_read8(u8 pid, u16 offset, u8 *outdata)
+{
+	return pch_pcr_read(pid, offset, sizeof(u8), (u32 *)outdata);
+}
+
+/*
+ * After every write one needs to perform a read an innocuous register to
+ * ensure the writes are completed for certain ports. This is done for
+ * all ports so that the callers don't need the per-port knowledge for
+ * each transaction.
+ */
+static inline void complete_write(void)
+{
+	/* Read the general control and function disable register. */
+	const size_t R_PCH_PCR_LPC_GCFD = 0x3418;
+	read32(pcr_reg_address(PID_LPC, R_PCH_PCR_LPC_GCFD));
+}
+
+/*
+ * Write PCR register. (This is internal function)
+ * It returns PCR register and size in 1/2/4 bytes.
+ * The offset should not exceed 0xFFFF and must be aligned with size
+ */
+static int pch_pcr_write(u8 pid, u16 offset, u32 size, u32 data)
+{
+	if ((offset & (size - 1)) != 0) {
+		printk(BIOS_DEBUG,
+			"PchPcrWrite error. Invalid Offset: %x Size: %x",
+			offset, size);
+		return -1;
+	}
+	/* Write the PCR register with provided data
+	 * Then read back PCR register to prevent from back to back write.
+	 */
+	switch (size) {
+	case 4:
+		write32(pcr_reg_address(pid, offset), (u32) data);
+		break;
+	case 2:
+		write16(pcr_reg_address(pid, offset), (u16) data);
+		break;
+	case 1:
+		write8(pcr_reg_address(pid, offset), (u8) data);
+		break;
+	default:
+		return -1;
+	}
+	/* Ensure the writes complete. */
+	complete_write();
+
+	return 0;
+}
+
+int pcr_write32(u8 pid, u16 offset, u32 indata)
+{
+	return pch_pcr_write(pid, offset, sizeof(u32), indata);
+}
+
+int pcr_write16(u8 pid, u16 offset, u16 indata)
+{
+	return pch_pcr_write(pid, offset, sizeof(u16), indata);
+}
+
+int pcr_write8(u8 pid, u16 offset, u8 indata)
+{
+	return pch_pcr_write(pid, offset, sizeof(u8), indata);
+}
+
+/*
+ * Write PCR register. (This is internal function)
+ * It programs  PCR register and size in 1/2/4 bytes.
+ * The offset should not exceed 0xFFFF and must be aligned with size
+ *
+ * u8 defines as 8 bit Port ID that will be used when sending
+ * transaction to sideband.
+ */
+static int pcr_and_then_or(u8 pid, u16 offset, u32 size, u32 anddata,
+		   u32 ordata)
+{
+	u8 status;
+	u32 data32 = 0;
+
+	status = pch_pcr_read(pid, offset, size, &data32);
+	if (status != 0)
+		return -1;
+
+	data32 &= anddata;
+	data32 |= ordata;
+
+	status = pch_pcr_write(pid, offset, size, data32);
+	return status;
+}
+
+int pcr_andthenor32(u8 pid, u16 offset, u32 anddata, u32 ordata)
+{
+	return pcr_and_then_or(pid, offset, sizeof(u32), anddata, ordata);
+}
+
+int pcr_andthenor16(u8 pid, u16 offset, u16 anddata, u16 ordata)
+{
+	return pcr_and_then_or(pid, offset, sizeof(u16), anddata, ordata);
+}
+
+int pcr_andthenor8(u8 pid, u16 offset, u8 anddata, u8 ordata)
+{
+	return pcr_and_then_or(pid, offset, sizeof(u8), anddata, ordata);
+}
diff --git a/src/soc/intel/kabylake/pei_data.c b/src/soc/intel/kabylake/pei_data.c
new file mode 100644
index 0000000..789fe09
--- /dev/null
+++ b/src/soc/intel/kabylake/pei_data.c
@@ -0,0 +1,49 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * 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 <chip.h>
+#include <console/console.h>
+#include <console/streams.h>
+#include <device/device.h>
+#include <device/pci_def.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <soc/iomap.h>
+#include <soc/pci_devs.h>
+#include <soc/pei_data.h>
+#include <soc/pei_wrapper.h>
+#include <soc/smm.h>
+
+static void ABI_X86 send_to_console(unsigned char b)
+{
+	console_tx_byte(b);
+}
+
+void soc_fill_pei_data(struct pei_data *pei_data)
+{
+	const struct device *dev;
+	const struct soc_intel_kabylake_config *config;
+
+	/* Set the parameters for MemoryInit */
+	dev = dev_find_slot(0, PCH_DEVFN_LPC);
+	config = dev->chip_info;
+
+	pei_data->pei_version = PEI_VERSION;
+	pei_data->tx_byte = &send_to_console;
+
+	/* Force a full memory train if RMT is enabled */
+	pei_data->disable_saved_data = config->Rmt;
+}
diff --git a/src/soc/intel/kabylake/pmc.c b/src/soc/intel/kabylake/pmc.c
new file mode 100644
index 0000000..e4eab6d
--- /dev/null
+++ b/src/soc/intel/kabylake/pmc.c
@@ -0,0 +1,312 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008-2009 coresystems GmbH
+ * Copyright (C) 2014 Google Inc.
+ * 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 <chip.h>
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <arch/io.h>
+#include <arch/ioapic.h>
+#include <arch/acpi.h>
+#include <cpu/cpu.h>
+#include <pc80/mc146818rtc.h>
+#include <reg_script.h>
+#include <string.h>
+#include <soc/gpio.h>
+#include <soc/iomap.h>
+#include <soc/pci_devs.h>
+#include <soc/pmc.h>
+#include <soc/pm.h>
+#include <cpu/x86/smm.h>
+#include <soc/pcr.h>
+#include <soc/ramstage.h>
+#if IS_ENABLED(CONFIG_CHROMEOS)
+#include <vendorcode/google/chromeos/chromeos.h>
+#include <vendorcode/google/chromeos/vbnv_layout.h>
+#endif
+
+static const struct reg_script pch_pmc_misc_init_script[] = {
+	/* SLP_S4=4s, SLP_S3=50ms, disable SLP_X stretching after SUS loss. */
+	REG_PCI_RMW16(GEN_PMCON_B,
+			~(S4MAW_MASK | SLP_S3_MIN_ASST_WDTH_MASK),
+			S4MAW_4S | SLP_S3_MIN_ASST_WDTH_50MS |
+			DIS_SLP_X_STRCH_SUS_UP),
+	/* Enable SCI and clear SLP requests. */
+	REG_IO_RMW32(ACPI_BASE_ADDRESS + PM1_CNT, ~SLP_TYP, SCI_EN),
+	REG_SCRIPT_END
+};
+
+static const struct reg_script pmc_write1_to_clear_script[] = {
+	REG_PCI_OR32(GEN_PMCON_A, 0),
+	REG_PCI_OR32(GEN_PMCON_B, 0),
+	REG_PCI_OR32(GEN_PMCON_B, 0),
+	REG_RES_OR32(PWRMBASE, GBLRST_CAUSE0, 0),
+	REG_RES_OR32(PWRMBASE, GBLRST_CAUSE1, 0),
+	REG_SCRIPT_END
+};
+
+static void pch_pmc_add_mmio_resources(device_t dev)
+{
+	struct resource *res;
+
+	/* Memory-mmapped I/O registers. */
+	res = new_resource(dev, PWRMBASE);
+	res->base = PCH_PWRM_BASE_ADDRESS;
+	res->size = PCH_PWRM_BASE_SIZE;
+	res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED |
+			IORESOURCE_FIXED | IORESOURCE_RESERVE;
+}
+
+static void pch_pmc_add_io_resource(device_t dev, u16 base, u16 size, int index)
+{
+	struct resource *res;
+	res = new_resource(dev, index);
+	res->base = base;
+	res->size = size;
+	res->flags = IORESOURCE_IO | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+}
+
+static void pch_pmc_add_io_resources(device_t dev)
+{
+	/* PMBASE */
+	pch_pmc_add_io_resource(dev, ACPI_BASE_ADDRESS, ACPI_BASE_SIZE, ABASE);
+}
+
+static void pch_pmc_read_resources(device_t dev)
+{
+	/* Get the normal PCI resources of this device. */
+	pci_dev_read_resources(dev);
+
+	/* Add non-standard MMIO resources. */
+	pch_pmc_add_mmio_resources(dev);
+
+	/* Add IO resources. */
+	pch_pmc_add_io_resources(dev);
+}
+
+static void pch_set_acpi_mode(void)
+{
+	if (IS_ENABLED(CONFIG_HAVE_SMI_HANDLER) && !acpi_is_wakeup_s3()) {
+		printk(BIOS_DEBUG, "Disabling ACPI via APMC:\n");
+		outb(APM_CNT_ACPI_DISABLE, APM_CNT);
+		printk(BIOS_DEBUG, "done.\n");
+	}
+}
+
+#if IS_ENABLED(CONFIG_CHROMEOS_VBNV_CMOS)
+/*
+ * Preserve Vboot NV data when clearing CMOS as it will
+ * have been re-initialized already by Vboot firmware init.
+ */
+static void pch_cmos_init_preserve(int reset)
+{
+	uint8_t vbnv[VBNV_BLOCK_SIZE];
+	if (reset)
+		read_vbnv(vbnv);
+
+	cmos_init(reset);
+
+	if (reset)
+		save_vbnv(vbnv);
+}
+#endif
+
+static void pch_rtc_init(void)
+{
+	u8 reg8;
+	int rtc_failed;
+	/*PMC Controller Device 0x1F, Func 02*/
+	device_t dev = PCH_DEV_PMC;
+	reg8 = pci_read_config8(dev, GEN_PMCON_B);
+	rtc_failed = reg8 & RTC_BATTERY_DEAD;
+	if (rtc_failed) {
+		reg8 &= ~RTC_BATTERY_DEAD;
+		pci_write_config8(dev, GEN_PMCON_B, reg8);
+		printk(BIOS_DEBUG, "rtc_failed = 0x%x\n", rtc_failed);
+	}
+
+	/* Ensure the date is set including century byte. */
+	cmos_check_update_date();
+
+#if IS_ENABLED(CONFIG_CHROMEOS_VBNV_CMOS)
+	pch_cmos_init_preserve(rtc_failed);
+#else
+	cmos_init(rtc_failed);
+#endif
+}
+
+static void pmc_gpe_init(config_t *config)
+{
+	uint8_t *pmc_regs;
+	uint32_t gpio_cfg;
+	uint32_t gpio_cfg_reg;
+	const uint32_t gpio_cfg_mask =
+		(GPE0_DWX_MASK << GPE0_DW0_SHIFT) |
+		(GPE0_DWX_MASK << GPE0_DW1_SHIFT) |
+		(GPE0_DWX_MASK << GPE0_DW2_SHIFT);
+
+	pmc_regs = pmc_mmio_regs();
+	gpio_cfg = 0;
+
+	/* Route the GPIOs to the GPE0 block. Determine that all values
+	 * are different, and if they aren't use the reset values. */
+	if (config->gpe0_dw0 == config->gpe0_dw1 ||
+		config->gpe0_dw1 == config->gpe0_dw2) {
+		printk(BIOS_INFO, "PMC: Using default GPE route.\n");
+		gpio_cfg = read32(pmc_regs + GPIO_CFG);
+	} else {
+		gpio_cfg |= (uint32_t)config->gpe0_dw0 << GPE0_DW0_SHIFT;
+		gpio_cfg |= (uint32_t)config->gpe0_dw1 << GPE0_DW1_SHIFT;
+		gpio_cfg |= (uint32_t)config->gpe0_dw2 << GPE0_DW2_SHIFT;
+	}
+	gpio_cfg_reg = read32(pmc_regs + GPIO_CFG) & ~gpio_cfg_mask;
+	gpio_cfg_reg |= gpio_cfg & gpio_cfg_mask;
+	write32(pmc_regs + GPIO_CFG, gpio_cfg_reg);
+
+	/* Set the routes in the GPIO communities as well. */
+	gpio_route_gpe(gpio_cfg_reg >> GPE0_DW0_SHIFT);
+
+	/* Set GPE enables based on devictree. */
+	enable_all_gpe(config->gpe0_en_1, config->gpe0_en_2,
+			config->gpe0_en_3, config->gpe0_en_4);
+}
+
+static void pch_power_options(void)
+{
+	u16 reg16;
+	const char *state;
+	/*PMC Controller Device 0x1F, Func 02*/
+	device_t dev = PCH_DEV_PMC;
+	/* Get the chip configuration */
+	config_t *config = dev->chip_info;
+	int pwr_on = CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL;
+
+	/*
+	 * Which state do we want to goto after g3 (power restored)?
+	 * 0 == S0 Full On
+	 * 1 == S5 Soft Off
+	 *
+	 * If the option is not existent (Laptops), use Kconfig setting.
+	 */
+	/*TODO: cmos_layout.bin need to verify; cause wrong CMOS setup*/
+	//get_option(&pwr_on, "power_on_after_fail");
+	pwr_on = MAINBOARD_POWER_ON;
+	reg16 = pci_read_config16(dev, GEN_PMCON_B);
+	reg16 &= 0xfffe;
+	switch (pwr_on) {
+	case MAINBOARD_POWER_OFF:
+		reg16 |= 1;
+		state = "off";
+		break;
+	case MAINBOARD_POWER_ON:
+		reg16 &= ~1;
+		state = "on";
+		break;
+	case MAINBOARD_POWER_KEEP:
+		reg16 &= ~1;
+		state = "state keep";
+		break;
+	default:
+		state = "undefined";
+	}
+	pci_write_config16(dev, GEN_PMCON_B, reg16);
+	printk(BIOS_INFO, "Set power %s after power failure.\n", state);
+
+	/* Set up GPE configuration. */
+	pmc_gpe_init(config);
+}
+
+static void config_deep_sX(uint32_t offset, uint32_t mask, int sx, int enable)
+{
+	uint32_t reg;
+	uint8_t *pmcbase = pmc_mmio_regs();
+
+	printk(BIOS_DEBUG, "%sabling Deep S%c\n",
+		enable ? "En" : "Dis", sx + '0');
+	reg = read32(pmcbase + offset);
+	if (enable)
+		reg |= mask;
+	else
+		reg &= ~mask;
+	write32(pmcbase + offset, reg);
+}
+
+static void config_deep_s5(int on)
+{
+	/* Treat S4 the same as S5. */
+	config_deep_sX(S4_PWRGATE_POL, S4DC_GATE_SUS | S4AC_GATE_SUS, 4, on);
+	config_deep_sX(S5_PWRGATE_POL, S5DC_GATE_SUS | S5AC_GATE_SUS, 5, on);
+}
+
+static void config_deep_s3(int on)
+{
+	config_deep_sX(S3_PWRGATE_POL, S3DC_GATE_SUS | S3AC_GATE_SUS, 3, on);
+}
+
+static void config_deep_sx(uint32_t deepsx_config)
+{
+	uint32_t reg;
+	uint8_t *pmcbase = pmc_mmio_regs();
+
+	reg = read32(pmcbase + DSX_CFG);
+	reg &= ~DSX_CFG_MASK;
+	reg |= deepsx_config;
+	write32(pmcbase + DSX_CFG, reg);
+}
+
+static void pmc_init(struct device *dev)
+{
+	config_t *config = dev->chip_info;
+
+	pch_rtc_init();
+
+	/* Initialize power management */
+	pch_power_options();
+
+	/* Note that certain bits may be cleared from running script as
+	 * certain bit fields are write 1 to clear. */
+	reg_script_run_on_dev(dev, pch_pmc_misc_init_script);
+	pch_set_acpi_mode();
+
+	config_deep_s3(config->deep_s3_enable);
+	config_deep_s5(config->deep_s5_enable);
+	config_deep_sx(config->deep_sx_config);
+
+	/* Clear registers that contain write-1-to-clear bits. */
+	reg_script_run_on_dev(dev, pmc_write1_to_clear_script);
+}
+
+static struct device_operations device_ops = {
+	.read_resources		= &pch_pmc_read_resources,
+	.set_resources		= &pci_dev_set_resources,
+	.enable_resources	= &pci_dev_enable_resources,
+	.init			= &pmc_init,
+	.scan_bus		= &scan_lpc_bus,
+	.ops_pci		= &soc_pci_ops,
+};
+
+static const unsigned short pci_device_ids[] = {
+	0x9d21,
+	0
+};
+
+static const struct pci_driver pch_lpc __pci_driver = {
+	.ops	 = &device_ops,
+	.vendor	 = PCI_VENDOR_ID_INTEL,
+	.devices = pci_device_ids,
+};
diff --git a/src/soc/intel/kabylake/pmutil.c b/src/soc/intel/kabylake/pmutil.c
new file mode 100644
index 0000000..6b06180
--- /dev/null
+++ b/src/soc/intel/kabylake/pmutil.c
@@ -0,0 +1,439 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * 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.
+ */
+
+/*
+ * Helper functions for dealing with power management registers
+ * and the differences between PCH variants.
+ */
+
+#include <arch/io.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_def.h>
+#include <console/console.h>
+#include <halt.h>
+#include <stdlib.h>
+#include <soc/gpio.h>
+#include <soc/iomap.h>
+#include <soc/lpc.h>
+#include <soc/pci_devs.h>
+#include <soc/pm.h>
+#include <soc/pmc.h>
+#include <soc/smbus.h>
+
+/* Print status bits with descriptive names */
+static void print_status_bits(u32 status, const char *bit_names[])
+{
+	int i;
+
+	if (!status)
+		return;
+
+	for (i = 31; i >= 0; i--) {
+		if (status & (1 << i)) {
+			if (bit_names[i])
+				printk(BIOS_DEBUG, "%s ", bit_names[i]);
+			else
+				printk(BIOS_DEBUG, "BIT%d ", i);
+		}
+	}
+}
+
+/* Print status bits as GPIO numbers */
+static void print_gpio_status(u32 status, int start)
+{
+	int i;
+
+	if (!status)
+		return;
+
+	for (i = 31; i >= 0; i--) {
+		if (status & (1 << i))
+			printk(BIOS_DEBUG, "GPIO%d ", start + i);
+	}
+}
+
+
+/*
+ * PM1_CNT
+ */
+
+/* Enable events in PM1 control register */
+void enable_pm1_control(u32 mask)
+{
+	u32 pm1_cnt = inl(ACPI_BASE_ADDRESS + PM1_CNT);
+	pm1_cnt |= mask;
+	outl(pm1_cnt, ACPI_BASE_ADDRESS + PM1_CNT);
+}
+
+/* Disable events in PM1 control register */
+void disable_pm1_control(u32 mask)
+{
+	u32 pm1_cnt = inl(ACPI_BASE_ADDRESS + PM1_CNT);
+	pm1_cnt &= ~mask;
+	outl(pm1_cnt, ACPI_BASE_ADDRESS + PM1_CNT);
+}
+
+
+/*
+ * PM1
+ */
+
+/* Clear and return PM1 status register */
+static u16 reset_pm1_status(void)
+{
+	u16 pm1_sts = inw(ACPI_BASE_ADDRESS + PM1_STS);
+	outw(pm1_sts, ACPI_BASE_ADDRESS + PM1_STS);
+	return pm1_sts;
+}
+
+/* Print PM1 status bits */
+static u16 print_pm1_status(u16 pm1_sts)
+{
+	const char *pm1_sts_bits[] = {
+		[0] = "TMROF",
+		[4] = "BM",
+		[5] = "GBL",
+		[8] = "PWRBTN",
+		[10] = "RTC",
+		[11] = "PRBTNOR",
+		[14] = "PCIEXPWAK",
+		[15] = "WAK",
+	};
+
+	if (!pm1_sts)
+		return 0;
+
+	printk(BIOS_SPEW, "PM1_STS: ");
+	print_status_bits(pm1_sts, pm1_sts_bits);
+	printk(BIOS_SPEW, "\n");
+
+	return pm1_sts;
+}
+
+/* Print, clear, and return PM1 status */
+u16 clear_pm1_status(void)
+{
+	return print_pm1_status(reset_pm1_status());
+}
+
+/* Set the PM1 register to events */
+void enable_pm1(u16 events)
+{
+	outw(events, ACPI_BASE_ADDRESS + PM1_EN);
+}
+
+
+/*
+ * SMI
+ */
+
+/* Clear and return SMI status register */
+static u32 reset_smi_status(void)
+{
+	u32 smi_sts = inl(ACPI_BASE_ADDRESS + SMI_STS);
+	outl(smi_sts, ACPI_BASE_ADDRESS + SMI_STS);
+	return smi_sts;
+}
+
+/* Print SMI status bits */
+static u32 print_smi_status(u32 smi_sts)
+{
+	const char *smi_sts_bits[] = {
+		[2] = "BIOS",
+		[3] = "LEGACY_USB",
+		[4] = "SLP_SMI",
+		[5] = "APM",
+		[6] = "SWSMI_TMR",
+		[8] = "PM1",
+		[9] = "GPE0",
+		[10] = "GPI",
+		[11] = "MCSMI",
+		[12] = "DEVMON",
+		[13] = "TCO",
+		[14] = "PERIODIC",
+		[15] = "SERIRQ_SMI",
+		[16] = "SMBUS_SMI",
+		[17] = "LEGACY_USB2",
+		[18] = "INTEL_USB2",
+		[20] = "PCI_EXP_SMI",
+		[21] = "MONITOR",
+		[26] = "SPI",
+		[27] = "GPIO_UNLOCK"
+	};
+
+	if (!smi_sts)
+		return 0;
+
+	printk(BIOS_DEBUG, "SMI_STS: ");
+	print_status_bits(smi_sts, smi_sts_bits);
+	printk(BIOS_DEBUG, "\n");
+
+	return smi_sts;
+}
+
+/* Print, clear, and return SMI status */
+u32 clear_smi_status(void)
+{
+	return print_smi_status(reset_smi_status());
+}
+
+/* Enable SMI event */
+void enable_smi(u32 mask)
+{
+	u32 smi_en = inl(ACPI_BASE_ADDRESS + SMI_EN);
+	smi_en |= mask;
+	outl(smi_en, ACPI_BASE_ADDRESS + SMI_EN);
+}
+
+/* Disable SMI event */
+void disable_smi(u32 mask)
+{
+	u32 smi_en = inl(ACPI_BASE_ADDRESS + SMI_EN);
+	smi_en &= ~mask;
+	outl(smi_en, ACPI_BASE_ADDRESS + SMI_EN);
+}
+
+/*
+ * TCO
+ */
+
+/* Clear TCO status and return events that are enabled and active */
+static u32 reset_tco_status(void)
+{
+	u16 tco1_sts;
+	u16 tco2_sts;
+	u16 tcobase;
+
+	tcobase = pmc_tco_regs();
+
+	/* TCO Status 2 register*/
+	tco2_sts = inw(tcobase + TCO2_STS);
+	tco2_sts |= (TCO2_STS_SECOND_TO | TCO2_STS_BOOT);
+	outw(tco2_sts, tcobase + TCO2_STS);
+
+	/* TCO Status 1 register*/
+	tco1_sts = inw(tcobase + TCO1_STS);
+
+	/* Clear SECOND_TO_STS bit */
+	if (tco2_sts & TCO2_STS_SECOND_TO)
+		outw(tco2_sts & ~TCO2_STS_SECOND_TO, tcobase + TCO2_STS);
+
+	return (tco2_sts << 16) | tco1_sts;
+}
+
+/* Print TCO status bits */
+static u32 print_tco_status(u32 tco_sts)
+{
+	const char *tco_sts_bits[] = {
+		[0] = "NMI2SMI",
+		[1] = "SW_TCO",
+		[2] = "TCO_INT",
+		[3] = "TIMEOUT",
+		[7] = "NEWCENTURY",
+		[8] = "BIOSWR",
+		[9] = "DMISCI",
+		[10] = "DMISMI",
+		[12] = "DMISERR",
+		[13] = "SLVSEL",
+		[16] = "INTRD_DET",
+		[17] = "SECOND_TO",
+		[18] = "BOOT",
+		[20] = "SMLINK_SLV"
+	};
+
+	if (!tco_sts)
+		return 0;
+
+	printk(BIOS_DEBUG, "TCO_STS: ");
+	print_status_bits(tco_sts, tco_sts_bits);
+	printk(BIOS_DEBUG, "\n");
+
+	return tco_sts;
+}
+
+/* Print, clear, and return TCO status */
+u32 clear_tco_status(void)
+{
+	return print_tco_status(reset_tco_status());
+}
+
+/* Enable TCO SCI */
+void enable_tco_sci(void)
+{
+	/* Clear pending events */
+	outl(TCOSCI_STS, ACPI_BASE_ADDRESS + GPE0_STS(3));
+
+	/* Enable TCO SCI events */
+	enable_gpe(TCOSCI_EN);
+}
+
+
+/*
+ * GPE0
+ */
+
+/* Clear a GPE0 status and return events that are enabled and active */
+static u32 reset_gpe(u16 sts_reg, u16 en_reg)
+{
+	u32 gpe0_sts = inl(ACPI_BASE_ADDRESS + sts_reg);
+	u32 gpe0_en = inl(ACPI_BASE_ADDRESS + en_reg);
+
+	outl(gpe0_sts, ACPI_BASE_ADDRESS + sts_reg);
+
+	/* Only report enabled events */
+	return gpe0_sts & gpe0_en;
+}
+
+/* Print GPE0 status bits */
+static u32 print_gpe_status(u32 gpe0_sts, const char *bit_names[])
+{
+	if (!gpe0_sts)
+		return 0;
+
+	printk(BIOS_DEBUG, "GPE0_STS: ");
+	print_status_bits(gpe0_sts, bit_names);
+	printk(BIOS_DEBUG, "\n");
+
+	return gpe0_sts;
+}
+
+/* Print GPE0 GPIO status bits */
+static u32 print_gpe_gpio(u32 gpe0_sts, int start)
+{
+	if (!gpe0_sts)
+		return 0;
+
+	printk(BIOS_DEBUG, "GPE0_STS: ");
+	print_gpio_status(gpe0_sts, start);
+	printk(BIOS_DEBUG, "\n");
+
+	return gpe0_sts;
+}
+
+/* Clear all GPE status and return "standard" GPE event status */
+u32 clear_gpe_status(void)
+{
+	const char *gpe0_sts_3_bits[] = {
+		[1] = "HOTPLUG",
+		[2] = "SWGPE",
+		[6] = "TCO_SCI",
+		[7] = "SMB_WAK",
+		[9] = "PCI_EXP",
+		[10] = "BATLOW",
+		[11] = "PME",
+		[12] = "ME",
+		[13] = "PME_B0",
+		[14] = "eSPI",
+		[15] = "GPIO Tier-2",
+		[16] = "LAN_WAKE",
+		[18] = "WADT"
+	};
+
+	print_gpe_gpio(reset_gpe(GPE0_STS(GPE_31_0), GPE0_EN(GPE_31_0)), 0);
+	print_gpe_gpio(reset_gpe(GPE0_STS(GPE_63_32), GPE0_EN(GPE_63_32)), 32);
+	print_gpe_gpio(reset_gpe(GPE0_STS(GPE_95_64), GPE0_EN(GPE_95_64)), 64);
+	return print_gpe_status(reset_gpe(GPE0_STS(GPE_STD), GPE0_EN(GPE_STD)),
+				gpe0_sts_3_bits);
+}
+
+/* Enable all requested GPE */
+void enable_all_gpe(u32 set1, u32 set2, u32 set3, u32 set4)
+{
+	outl(set1, ACPI_BASE_ADDRESS + GPE0_EN(GPE_31_0));
+	outl(set2, ACPI_BASE_ADDRESS + GPE0_EN(GPE_63_32));
+	outl(set3, ACPI_BASE_ADDRESS + GPE0_EN(GPE_95_64));
+	outl(set4, ACPI_BASE_ADDRESS + GPE0_EN(GPE_STD));
+}
+
+/* Disable all GPE */
+void disable_all_gpe(void)
+{
+	enable_all_gpe(0, 0, 0, 0);
+}
+
+/* Enable a standard GPE */
+void enable_gpe(u32 mask)
+{
+	u32 gpe0_en = inl(ACPI_BASE_ADDRESS + GPE0_EN(GPE_STD));
+	gpe0_en |= mask;
+	outl(gpe0_en, ACPI_BASE_ADDRESS + GPE0_EN(GPE_STD));
+}
+
+/* Disable a standard GPE */
+void disable_gpe(u32 mask)
+{
+	u32 gpe0_en = inl(ACPI_BASE_ADDRESS + GPE0_EN(GPE_STD));
+	gpe0_en &= ~mask;
+	outl(gpe0_en, ACPI_BASE_ADDRESS + GPE0_EN(GPE_STD));
+}
+
+int acpi_sci_irq(void)
+{
+	int scis = pci_read_config32(PCH_DEV_PMC, ACTL) & SCI_IRQ_SEL;
+	int sci_irq = 9;
+
+	/* Determine how SCI is routed. */
+	switch (scis) {
+	case SCIS_IRQ9:
+	case SCIS_IRQ10:
+	case SCIS_IRQ11:
+		sci_irq = scis - SCIS_IRQ9 + 9;
+		break;
+	case SCIS_IRQ20:
+	case SCIS_IRQ21:
+	case SCIS_IRQ22:
+	case SCIS_IRQ23:
+		sci_irq = scis - SCIS_IRQ20 + 20;
+		break;
+	default:
+		printk(BIOS_DEBUG, "Invalid SCI route! Defaulting to IRQ9.\n");
+		sci_irq = 9;
+		break;
+	}
+
+	printk(BIOS_DEBUG, "SCI is IRQ%d\n", sci_irq);
+	return sci_irq;
+}
+
+uint8_t *pmc_mmio_regs(void)
+{
+	uint32_t reg32;
+
+	reg32 = pci_read_config32(PCH_DEV_PMC, PWRMBASE);
+
+	/* 4KiB alignment. */
+	reg32 &= ~0xfff;
+
+	return (void *)(uintptr_t)reg32;
+}
+
+uint16_t pmc_tco_regs(void)
+{
+	uint16_t reg16;
+
+	reg16 = pci_read_config16(PCH_DEV_SMBUS, TCOBASE);
+
+	reg16 &= ~0x1f;
+
+	return reg16;
+}
+
+void poweroff(void)
+{
+	enable_pm1_control(SLP_EN | (SLP_TYP_S5 << SLP_TYP_SHIFT));
+	halt();
+}
diff --git a/src/soc/intel/kabylake/ramstage.c b/src/soc/intel/kabylake/ramstage.c
new file mode 100644
index 0000000..bfee655
--- /dev/null
+++ b/src/soc/intel/kabylake/ramstage.c
@@ -0,0 +1,23 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * 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 <soc/ramstage.h>
+
+void soc_init_pre_device(void *chip_info)
+{
+	/* Perform silicon specific init. */
+	intel_silicon_init();
+}
diff --git a/src/soc/intel/kabylake/romstage/Makefile.inc b/src/soc/intel/kabylake/romstage/Makefile.inc
new file mode 100644
index 0000000..6ae8137
--- /dev/null
+++ b/src/soc/intel/kabylake/romstage/Makefile.inc
@@ -0,0 +1,21 @@
+verstage-y += cpu.c
+verstage-y += i2c.c
+verstage-y += pch.c
+verstage-y += power_state.c
+verstage-y += report_platform.c
+verstage-y += romstage.c
+verstage-y += smbus.c
+verstage-y += spi.c
+verstage-y += systemagent.c
+verstage-y += uart.c
+
+romstage-y += cpu.c
+romstage-y += i2c.c
+romstage-y += pch.c
+romstage-y += power_state.c
+romstage-y += report_platform.c
+romstage-y += romstage.c
+romstage-y += smbus.c
+romstage-y += spi.c
+romstage-y += systemagent.c
+romstage-y += uart.c
diff --git a/src/soc/intel/kabylake/romstage/cpu.c b/src/soc/intel/kabylake/romstage/cpu.c
new file mode 100644
index 0000000..ab91317
--- /dev/null
+++ b/src/soc/intel/kabylake/romstage/cpu.c
@@ -0,0 +1,52 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * 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 <arch/cpu.h>
+#include <stdlib.h>
+#include <console/console.h>
+#include <cpu/x86/msr.h>
+#include <soc/cpu.h>
+#include <soc/msr.h>
+#include <soc/romstage.h>
+
+u32 cpu_family_model(void)
+{
+	return cpuid_eax(1) & 0x0fff0ff0;
+}
+
+void set_max_freq(void)
+{
+	msr_t msr, perf_ctl, platform_info;
+
+	/* Check for configurable TDP option */
+	platform_info = rdmsr(MSR_PLATFORM_INFO);
+
+	if ((platform_info.hi >> 1) & 3) {
+		/* Set to nominal TDP ratio */
+		msr = rdmsr(MSR_CONFIG_TDP_NOMINAL);
+		perf_ctl.lo = (msr.lo & 0xff) << 8;
+	} else {
+		/* Platform Info bits 15:8 give max ratio */
+		msr = rdmsr(MSR_PLATFORM_INFO);
+		perf_ctl.lo = msr.lo & 0xff00;
+	}
+
+	perf_ctl.hi = 0;
+	wrmsr(IA32_PERF_CTL, perf_ctl);
+
+	printk(BIOS_DEBUG, "CPU: frequency set to %d MHz\n",
+		((perf_ctl.lo >> 8) & 0xff) * CPU_BCLK);
+}
diff --git a/src/soc/intel/kabylake/romstage/i2c.c b/src/soc/intel/kabylake/romstage/i2c.c
new file mode 100644
index 0000000..41f13ce
--- /dev/null
+++ b/src/soc/intel/kabylake/romstage/i2c.c
@@ -0,0 +1,109 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2016 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.
+ */
+
+#include <arch/io.h>
+#include <commonlib/helpers.h>
+#include <device/device.h>
+#include <device/i2c.h>
+#include <device/pci_def.h>
+#include <soc/intel/common/lpss_i2c.h>
+#include <soc/iomap.h>
+#include <soc/pci_devs.h>
+#include <soc/romstage.h>
+#include <soc/serialio.h>
+#include "chip.h"
+
+uintptr_t lpss_i2c_base_address(unsigned bus)
+{
+	unsigned devfn;
+	pci_devfn_t dev;
+
+	/* Find device+function for this controller */
+	devfn = i2c_bus_to_devfn(bus);
+	if (devfn < 0)
+		return 0;
+
+	/* Form a PCI address for this device */
+	dev = PCI_DEV(0, PCI_SLOT(devfn), PCI_FUNC(devfn));
+
+	/* Read the first base address for this device */
+	return ALIGN_DOWN(pci_read_config32(dev, PCI_BASE_ADDRESS_0), 16);
+}
+
+static void i2c_early_init_bus(unsigned bus)
+{
+	ROMSTAGE_CONST struct soc_intel_kabylake_config *config;
+	ROMSTAGE_CONST struct device *tree_dev;
+	const struct lpss_i2c_speed_config *sptr;
+	enum i2c_speed speed;
+	pci_devfn_t dev;
+	unsigned devfn;
+	uintptr_t base;
+	uint32_t value;
+	void *reg;
+
+	/* Find the PCI device for this bus controller */
+	devfn = i2c_bus_to_devfn(bus);
+	if (devfn < 0)
+		return;
+
+	/* Look up the controller device in the devicetree */
+	dev = PCI_DEV(0, PCI_SLOT(devfn), PCI_FUNC(devfn));
+	tree_dev = dev_find_slot(0, devfn);
+	if (!tree_dev || !tree_dev->enabled)
+		return;
+
+	/* Skip if not enabled for early init */
+	config = tree_dev->chip_info;
+	if (!config)
+		return;
+	if (!config->i2c[bus].early_init)
+		return;
+
+	/* Prepare early base address for access before memory */
+	base = EARLY_I2C_BASE(bus);
+	pci_write_config32(dev, PCI_BASE_ADDRESS_0, base);
+	pci_write_config32(dev, PCI_COMMAND,
+			   PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
+
+	/* Take device out of reset */
+	reg = (void *)(base + SIO_REG_PPR_RESETS);
+	value = read32(reg);
+	value |= SIO_REG_PPR_RESETS_FUNC | SIO_REG_PPR_RESETS_APB |
+		SIO_REG_PPR_RESETS_IDMA;
+	write32(reg, value);
+
+	/* Initialize the controller */
+	speed = config->i2c[bus].speed ? : I2C_SPEED_FAST;
+	lpss_i2c_init(bus, speed);
+
+	/* Apply custom speed config if it has been set by the board */
+	for (value = 0; value < LPSS_I2C_SPEED_CONFIG_COUNT; value++) {
+		sptr = &config->i2c[bus].speed_config[value];
+		if (sptr->speed == speed) {
+			lpss_i2c_set_speed_config(bus, sptr);
+			break;
+		}
+	}
+}
+
+void i2c_early_init(void)
+{
+	int bus;
+
+	/* Initialize I2C controllers that are enabled in devicetree */
+	for (bus = 0; bus < KABYLAKE_I2C_DEV_MAX; bus++)
+		i2c_early_init_bus(bus);
+}
diff --git a/src/soc/intel/kabylake/romstage/pch.c b/src/soc/intel/kabylake/romstage/pch.c
new file mode 100644
index 0000000..49022e0
--- /dev/null
+++ b/src/soc/intel/kabylake/romstage/pch.c
@@ -0,0 +1,133 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * 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 <arch/io.h>
+#include <chip.h>
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci_def.h>
+#include <reg_script.h>
+#include <soc/iomap.h>
+#include <soc/lpc.h>
+#include <soc/pch.h>
+#include <soc/pcr.h>
+#include <soc/pci_devs.h>
+#include <soc/pm.h>
+#include <soc/pmc.h>
+#include <soc/romstage.h>
+#include <soc/smbus.h>
+
+/* Max PXRC registers in ITSS*/
+#define MAX_PXRC_CONFIG		0x08
+
+static const u8 pch_interrupt_routing[] = {
+		11,	/* PARC: PIRQA -> IRQ11 */
+		10,	/* PBRC: PIRQB -> IRQ10 */
+		11,	/* PCRC: PIRQC -> IRQ11 */
+		11,	/* PDRC: PIRQD -> IRQ11 */
+		11,	/* PERC: PIRQE -> IRQ11 */
+		11,	/* PFRC: PIRQF -> IRQ11 */
+		11,	/* PGRC: PIRQG -> IRQ11 */
+		11	/* PHRC: PIRQH -> IRQ11 */
+};
+
+static void pch_enable_lpc(void)
+{
+	/* Lookup device tree in romstage */
+	const struct device *dev;
+	const config_t *config;
+	u16 lpc_en;
+
+	/* IO Decode Range */
+	lpc_en = COMA_RANGE | (COMB_RANGE << 4);
+	pci_write_config16(PCH_DEV_LPC, LPC_IO_DEC, lpc_en);
+	pcr_write16(PID_DMI, R_PCH_PCR_DMI_LPCIOD, lpc_en);
+
+	/* IO Decode Enable */
+	lpc_en = CNF1_LPC_EN | CNF2_LPC_EN | GAMEL_LPC_EN | GAMEH_LPC_EN |
+		COMA_LPC_EN | KBC_LPC_EN | MC_LPC_EN;
+	pci_write_config16(PCH_DEV_LPC, LPC_EN, lpc_en);
+	pcr_write16(PID_DMI, R_PCH_PCR_DMI_LPCIOE, lpc_en);
+
+	dev = dev_find_slot(0, PCI_DEVFN(PCH_DEV_SLOT_LPC, 0));
+	if (!dev || !dev->chip_info)
+		return;
+	config = dev->chip_info;
+
+	/* Set in PCI generic decode range registers */
+	pci_write_config32(PCH_DEV_LPC, LPC_GEN1_DEC, config->gen1_dec);
+	pci_write_config32(PCH_DEV_LPC, LPC_GEN2_DEC, config->gen2_dec);
+	pci_write_config32(PCH_DEV_LPC, LPC_GEN3_DEC, config->gen3_dec);
+	pci_write_config32(PCH_DEV_LPC, LPC_GEN4_DEC, config->gen4_dec);
+
+	/* Mirror these same settings in DMI PCR */
+	pcr_write32(PID_DMI, R_PCH_PCR_DMI_LPCLGIR1, config->gen1_dec);
+	pcr_write32(PID_DMI, R_PCH_PCR_DMI_LPCLGIR2, config->gen2_dec);
+	pcr_write32(PID_DMI, R_PCH_PCR_DMI_LPCLGIR3, config->gen3_dec);
+	pcr_write32(PID_DMI, R_PCH_PCR_DMI_LPCLGIR4, config->gen4_dec);
+}
+
+static void pch_device_init(void)
+{
+	device_t dev;
+	u32 reg32;
+	u16 tcobase;
+	u16 tcocnt;
+
+	dev = PCH_DEV_PMC;
+
+	/* Enable ACPI and PMC mmio regs in PMC Config */
+	reg32 = pci_read_config32(dev, ACTL);
+	reg32 |= ACPI_EN | PWRM_EN;
+	pci_write_config32(dev, ACTL, reg32);
+
+	/* TCO timer halt */
+	tcobase = pmc_tco_regs();
+	tcocnt = inw(tcobase + TCO1_CNT);
+	tcocnt |= TCO_TMR_HLT;
+	outw(tcocnt, tcobase + TCO1_CNT);
+
+	/* Enable upper 128 bytes of CMOS */
+	pcr_andthenor32(PID_RTC, R_PCH_PCR_RTC_CONF, (u32)~0,
+			B_PCH_PCR_RTC_CONF_UCMOS_EN);
+}
+
+static void pch_interrupt_init(void)
+{
+	u8 index = 0;
+
+	for (index = 0; index < MAX_PXRC_CONFIG; index++) {
+		if (pch_interrupt_routing[index] < 16 &&
+			pch_interrupt_routing[index] > 2 &&
+			pch_interrupt_routing[index] != 8 &&
+			pch_interrupt_routing[index] != 13) {
+				pcr_write8(PID_ITSS,
+					(R_PCH_PCR_ITSS_PIRQA_ROUT + index),
+					pch_interrupt_routing[index]);
+		}
+	}
+}
+
+void pch_early_init(void)
+{
+	pch_device_init();
+
+	pch_interrupt_init();
+
+	pch_enable_lpc();
+
+	enable_smbus();
+}
diff --git a/src/soc/intel/kabylake/romstage/power_state.c b/src/soc/intel/kabylake/romstage/power_state.c
new file mode 100644
index 0000000..f03c304
--- /dev/null
+++ b/src/soc/intel/kabylake/romstage/power_state.c
@@ -0,0 +1,180 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * 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 <arch/early_variables.h>
+#include <arch/io.h>
+#include <cbmem.h>
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_def.h>
+#include <reg_script.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <soc/iomap.h>
+#include <soc/pmc.h>
+#include <soc/pci_devs.h>
+#include <soc/pm.h>
+#include <soc/romstage.h>
+#include <vendorcode/google/chromeos/vboot_common.h>
+
+static struct chipset_power_state power_state CAR_GLOBAL;
+
+static void migrate_power_state(int is_recovery)
+{
+	struct chipset_power_state *ps_cbmem;
+	struct chipset_power_state *ps_car;
+
+	ps_car = car_get_var_ptr(&power_state);
+	ps_cbmem = cbmem_add(CBMEM_ID_POWER_STATE, sizeof(*ps_cbmem));
+
+	if (ps_cbmem == NULL) {
+		printk(BIOS_DEBUG, "Not adding power state to cbmem!\n");
+		return;
+	}
+	memcpy(ps_cbmem, ps_car, sizeof(*ps_cbmem));
+}
+ROMSTAGE_CBMEM_INIT_HOOK(migrate_power_state)
+
+/* Return 0, 3, or 5 to indicate the previous sleep state. */
+static uint32_t prev_sleep_state(struct chipset_power_state *ps)
+{
+	/* Default to S0. */
+	uint32_t prev_sleep_state = ACPI_S0;
+
+	if (ps->pm1_sts & WAK_STS) {
+		switch (acpi_sleep_from_pm1(ps->pm1_cnt)) {
+		case ACPI_S3:
+			if (IS_ENABLED(CONFIG_HAVE_ACPI_RESUME))
+				prev_sleep_state = ACPI_S3;
+			break;
+		case ACPI_S5:
+			prev_sleep_state = ACPI_S5;
+			break;
+		}
+		/* Clear SLP_TYP. */
+		outl(ps->pm1_cnt & ~(SLP_TYP), ACPI_BASE_ADDRESS + PM1_CNT);
+	} else {
+		/*
+		 * Check for any power failure to determine if this a wake from
+		 * S5 because the PCH does not set the WAK_STS bit when waking
+		 * from a true G3 state.
+		 */
+		if (ps->gen_pmcon_b & (PWR_FLR | SUS_PWR_FLR))
+			prev_sleep_state = ACPI_S5;
+	}
+
+	/*
+	 * If waking from S3 determine if deep S3 is enabled. If not,
+	 * need to check both deep sleep well and normal suspend well.
+	 * Otherwise just check deep sleep well.
+	 */
+	if (prev_sleep_state == ACPI_S3) {
+		/* PWR_FLR represents deep sleep power well loss. */
+		uint32_t mask = PWR_FLR;
+
+		/* If deep s3 isn't enabled check the suspend well too. */
+		if (!deep_s3_enabled())
+			mask |= SUS_PWR_FLR;
+
+		if (ps->gen_pmcon_b & mask)
+			prev_sleep_state = ACPI_S5;
+	}
+
+	return prev_sleep_state;
+}
+
+static void dump_power_state(struct chipset_power_state *ps)
+{
+	printk(BIOS_DEBUG, "PM1_STS:   %04x\n", ps->pm1_sts);
+	printk(BIOS_DEBUG, "PM1_EN:    %04x\n", ps->pm1_en);
+	printk(BIOS_DEBUG, "PM1_CNT:   %08x\n", ps->pm1_cnt);
+	printk(BIOS_DEBUG, "TCO_STS:   %04x %04x\n",
+	       ps->tco1_sts, ps->tco2_sts);
+
+	printk(BIOS_DEBUG, "GPE0_STS:  %08x %08x %08x %08x\n",
+	       ps->gpe0_sts[0], ps->gpe0_sts[1],
+	       ps->gpe0_sts[2], ps->gpe0_sts[3]);
+	printk(BIOS_DEBUG, "GPE0_EN:   %08x %08x %08x %08x\n",
+	       ps->gpe0_en[0], ps->gpe0_en[1],
+	       ps->gpe0_en[2], ps->gpe0_en[3]);
+
+	printk(BIOS_DEBUG, "GEN_PMCON: %08x %08x\n",
+	       ps->gen_pmcon_a, ps->gen_pmcon_b);
+
+	printk(BIOS_DEBUG, "GBLRST_CAUSE: %08x %08x\n",
+	       ps->gblrst_cause[0], ps->gblrst_cause[1]);
+
+	printk(BIOS_DEBUG, "Previous Sleep State: S%d\n",
+	       ps->prev_sleep_state);
+}
+
+/* Fill power state structure from ACPI PM registers */
+struct chipset_power_state *fill_power_state(void)
+{
+	uint16_t tcobase;
+	uint8_t *pmc;
+	struct chipset_power_state *ps = car_get_var_ptr(&power_state);
+
+	tcobase = pmc_tco_regs();
+
+	ps->pm1_sts = inw(ACPI_BASE_ADDRESS + PM1_STS);
+	ps->pm1_en = inw(ACPI_BASE_ADDRESS + PM1_EN);
+	ps->pm1_cnt = inl(ACPI_BASE_ADDRESS + PM1_CNT);
+	ps->tco1_sts = inw(tcobase + TCO1_STS);
+	ps->tco2_sts = inw(tcobase + TCO2_STS);
+	ps->gpe0_sts[0] = inl(ACPI_BASE_ADDRESS + GPE0_STS(0));
+	ps->gpe0_sts[1] = inl(ACPI_BASE_ADDRESS + GPE0_STS(1));
+	ps->gpe0_sts[2] = inl(ACPI_BASE_ADDRESS + GPE0_STS(2));
+	ps->gpe0_sts[3] = inl(ACPI_BASE_ADDRESS + GPE0_STS(3));
+	ps->gpe0_en[0] = inl(ACPI_BASE_ADDRESS + GPE0_EN(0));
+	ps->gpe0_en[1] = inl(ACPI_BASE_ADDRESS + GPE0_EN(1));
+	ps->gpe0_en[2] = inl(ACPI_BASE_ADDRESS + GPE0_EN(2));
+	ps->gpe0_en[3] = inl(ACPI_BASE_ADDRESS + GPE0_EN(3));
+
+	ps->gen_pmcon_a = pci_read_config32(PCH_DEV_PMC, GEN_PMCON_A);
+	ps->gen_pmcon_b = pci_read_config32(PCH_DEV_PMC, GEN_PMCON_B);
+
+	pmc = pmc_mmio_regs();
+	ps->gblrst_cause[0] = read32(pmc + GBLRST_CAUSE0);
+	ps->gblrst_cause[1] = read32(pmc + GBLRST_CAUSE1);
+
+	ps->prev_sleep_state = prev_sleep_state(ps);
+
+	dump_power_state(ps);
+
+	return ps;
+}
+
+int vboot_platform_is_resuming(void)
+{
+	return acpi_sleep_from_pm1(inl(ACPI_BASE_ADDRESS + PM1_CNT)) == ACPI_S3;
+}
+
+/*
+ * The PM1 control is set to S5 when vboot requests a reboot because the power
+ * state code above may not have collected it's data yet. Therefore, set it to
+ * S5 when vboot requests a reboot. That's necessary if vboot fails in the
+ * resume path and requests a reboot. This prevents a reboot loop where the
+ * error is continually hit on the failing vboot resume path.
+ */
+void vboot_platform_prepare_reboot(void)
+{
+	uint16_t port = ACPI_BASE_ADDRESS + PM1_CNT;
+
+	outl((inl(port) & ~(SLP_TYP)) | (SLP_TYP_S5 << SLP_TYP_SHIFT), port);
+}
diff --git a/src/soc/intel/kabylake/romstage/report_platform.c b/src/soc/intel/kabylake/romstage/report_platform.c
new file mode 100644
index 0000000..eb5f216
--- /dev/null
+++ b/src/soc/intel/kabylake/romstage/report_platform.c
@@ -0,0 +1,216 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * 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 <arch/cpu.h>
+#include <arch/io.h>
+#include <console/console.h>
+#include <cpu/x86/msr.h>
+#include <device/pci.h>
+#include <soc/cpu.h>
+#include <soc/pch.h>
+#include <soc/pci_devs.h>
+#include <soc/romstage.h>
+#include <soc/systemagent.h>
+#include <string.h>
+
+static struct {
+	u32 cpuid;
+	const char *name;
+} cpu_table[] = {
+	{ CPUID_KABYLAKE_C0,	"Kabylake C0" },
+	{ CPUID_KABYLAKE_D0,	"Kabylake D0" },
+};
+
+static struct {
+	u16 mchid;
+	const char *name;
+} mch_table[] = {
+	{ MCH_KABYLAKE_ID_U,	"Kabylake-U" },
+	{ MCH_KABYLAKE_ID_Y,	"Kabylake-Y" },
+	{ MCH_KABYLAKE_ID_ULX,	"Kabylake-ULX" },
+};
+
+static struct {
+	u16 lpcid;
+	const char *name;
+} pch_table[] = {
+	{ PCH_SPT_LP_SAMPLE,	"Kabylake LP Sample" },
+	{ PCH_SPT_LP_U_BASE,	"Kabylake-U Base" },
+	{ PCH_SPT_LP_U_PREMIUM,	"Kabylake-U Premium" },
+	{ PCH_SPT_LP_Y_PREMIUM,	"Kabylake-Y Premium" },
+};
+
+static struct {
+	u16 igdid;
+	const char *name;
+} igd_table[] = {
+	{ IGD_KABYLAKE_GT1_SULTM, "Kabylake ULT GT1"},
+	{ IGD_KABYLAKE_GT2_SULXM, "Kabylake ULX GT2" },
+	{ IGD_KABYLAKE_GT2_SULTM, "Kabylake ULT GT2" },
+};
+
+static void report_cpu_info(void)
+{
+	struct cpuid_result cpuidr;
+	u32 i, index;
+	char cpu_string[50], *cpu_name = cpu_string; /* 48 bytes are reported */
+	int vt, txt, aes;
+	msr_t microcode_ver;
+	const char *mode[] = {"NOT ", ""};
+	const char *cpu_type = "Unknown";
+
+	index = 0x80000000;
+	cpuidr = cpuid(index);
+	if (cpuidr.eax < 0x80000004) {
+		strcpy(cpu_string, "Platform info not available");
+	} else {
+		u32 *p = (u32 *) cpu_string;
+		for (i = 2; i <= 4; i++) {
+			cpuidr = cpuid(index + i);
+			*p++ = cpuidr.eax;
+			*p++ = cpuidr.ebx;
+			*p++ = cpuidr.ecx;
+			*p++ = cpuidr.edx;
+		}
+	}
+	/* Skip leading spaces in CPU name string */
+	while (cpu_name[0] == ' ')
+		cpu_name++;
+
+	microcode_ver.lo = 0;
+	microcode_ver.hi = 0;
+	wrmsr(0x8B, microcode_ver);
+	cpuidr = cpuid(1);
+	microcode_ver = rdmsr(0x8b);
+
+	/* Look for string to match the name */
+	for (i = 0; i < ARRAY_SIZE(cpu_table); i++) {
+		if (cpu_table[i].cpuid == cpuidr.eax) {
+			cpu_type = cpu_table[i].name;
+			break;
+		}
+	}
+
+	printk(BIOS_DEBUG, "CPU: %s\n", cpu_name);
+	printk(BIOS_DEBUG, "CPU: ID %x, %s, ucode: %08x\n",
+	       cpuidr.eax, cpu_type, microcode_ver.hi);
+
+	aes = (cpuidr.ecx & (1 << 25)) ? 1 : 0;
+	txt = (cpuidr.ecx & (1 << 6)) ? 1 : 0;
+	vt = (cpuidr.ecx & (1 << 5)) ? 1 : 0;
+	printk(BIOS_DEBUG,
+		"CPU: AES %ssupported, TXT %ssupported, VT %ssupported\n",
+		mode[aes], mode[txt], mode[vt]);
+}
+
+static void report_mch_info(void)
+{
+	int i;
+	u16 mchid = pci_read_config16(SA_DEV_ROOT, PCI_DEVICE_ID);
+	u8 mch_revision = pci_read_config8(SA_DEV_ROOT, PCI_REVISION_ID);
+	const char *mch_type = "Unknown";
+
+	for (i = 0; i < ARRAY_SIZE(mch_table); i++) {
+		if (mch_table[i].mchid == mchid) {
+			mch_type = mch_table[i].name;
+			break;
+		}
+	}
+
+	printk(BIOS_DEBUG, "MCH: device id %04x (rev %02x) is %s\n",
+	       mchid, mch_revision, mch_type);
+}
+
+static void report_pch_info(void)
+{
+	int i;
+	u16 lpcid = pch_type();
+	const char *pch_type = "Unknown";
+
+	for (i = 0; i < ARRAY_SIZE(pch_table); i++) {
+		if (pch_table[i].lpcid == lpcid) {
+			pch_type = pch_table[i].name;
+			break;
+		}
+	}
+	printk(BIOS_DEBUG, "PCH: device id %04x (rev %02x) is %s\n",
+	       lpcid, pch_revision(), pch_type);
+}
+
+static void report_igd_info(void)
+{
+	int i;
+	u16 igdid = pci_read_config16(SA_DEV_IGD, PCI_DEVICE_ID);
+	const char *igd_type = "Unknown";
+
+	for (i = 0; i < ARRAY_SIZE(igd_table); i++) {
+		if (igd_table[i].igdid == igdid) {
+			igd_type = igd_table[i].name;
+			break;
+		}
+	}
+	printk(BIOS_DEBUG, "IGD: device id %04x (rev %02x) is %s\n",
+	       igdid, pci_read_config8(SA_DEV_IGD, PCI_REVISION_ID), igd_type);
+}
+
+void report_platform_info(void)
+{
+	report_cpu_info();
+	report_mch_info();
+	report_pch_info();
+	report_igd_info();
+}
+
+/*
+ * Dump in the log memory controller configuration as read from the memory
+ * controller registers.
+ */
+void report_memory_config(void)
+{
+	u32 addr_decoder_common, addr_decode_ch[2];
+	int i;
+
+	addr_decoder_common = MCHBAR32(0x5000);
+	addr_decode_ch[0] = MCHBAR32(0x5004);
+	addr_decode_ch[1] = MCHBAR32(0x5008);
+
+	printk(BIOS_DEBUG, "memcfg DDR3 clock %d MHz\n",
+	       (MCHBAR32(0x5e04) * 13333 * 2 + 50)/100);
+	printk(BIOS_DEBUG, "memcfg channel assignment: A: %d, B % d, C % d\n",
+	       addr_decoder_common & 3,
+	       (addr_decoder_common >> 2) & 3,
+	       (addr_decoder_common >> 4) & 3);
+
+	for (i = 0; i < ARRAY_SIZE(addr_decode_ch); i++) {
+		u32 ch_conf = addr_decode_ch[i];
+		printk(BIOS_DEBUG, "memcfg channel[%d] config (%8.8x):\n",
+		       i, ch_conf);
+		printk(BIOS_DEBUG, "   enhanced interleave mode %s\n",
+		       ((ch_conf >> 22) & 1) ? "on" : "off");
+		printk(BIOS_DEBUG, "   rank interleave %s\n",
+		       ((ch_conf >> 21) & 1) ? "on" : "off");
+		printk(BIOS_DEBUG, "   DIMMA %d MB width %s %s rank%s\n",
+		       ((ch_conf >> 0) & 0xff) * 256,
+		       ((ch_conf >> 19) & 1) ? "x16" : "x8 or x32",
+		       ((ch_conf >> 17) & 1) ? "dual" : "single",
+		       ((ch_conf >> 16) & 1) ? "" : ", selected");
+		printk(BIOS_DEBUG, "   DIMMB %d MB width %s %s rank%s\n",
+		       ((ch_conf >> 8) & 0xff) * 256,
+		       ((ch_conf >> 19) & 1) ? "x16" : "x8 or x32",
+		       ((ch_conf >> 18) & 1) ? "dual" : "single",
+		       ((ch_conf >> 16) & 1) ? ", selected" : "");
+	}
+}
diff --git a/src/soc/intel/kabylake/romstage/romstage.c b/src/soc/intel/kabylake/romstage/romstage.c
new file mode 100644
index 0000000..211be43
--- /dev/null
+++ b/src/soc/intel/kabylake/romstage/romstage.c
@@ -0,0 +1,268 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * 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 <stddef.h>
+#include <stdint.h>
+#include <arch/cpu.h>
+#include <arch/io.h>
+#include <arch/cbfs.h>
+#include <arch/stages.h>
+#include <arch/early_variables.h>
+#include <cbmem.h>
+#include <chip.h>
+#include <console/console.h>
+#include <cpu/x86/mtrr.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_def.h>
+#include <elog.h>
+#include <reset.h>
+#include <romstage_handoff.h>
+#include <soc/pci_devs.h>
+#include <soc/pei_wrapper.h>
+#include <soc/pm.h>
+#include <soc/pmc.h>
+#include <soc/serialio.h>
+#include <soc/romstage.h>
+#include <soc/spi.h>
+#include <stage_cache.h>
+#include <timestamp.h>
+#include <vendorcode/google/chromeos/chromeos.h>
+
+/* SOC initialization before RAM is enabled */
+void soc_pre_ram_init(struct romstage_params *params)
+{
+	/* Prepare to initialize memory */
+	soc_fill_pei_data(params->pei_data);
+}
+
+/* SOC initialization before the console is enabled. */
+void car_soc_pre_console_init(void)
+{
+	/* System Agent Early Initialization */
+	systemagent_early_init();
+
+	if (IS_ENABLED(CONFIG_UART_DEBUG))
+		pch_uart_init();
+}
+
+void car_soc_post_console_init(void)
+{
+	report_platform_info();
+	set_max_freq();
+	pch_early_init();
+	i2c_early_init();
+}
+
+int get_sw_write_protect_state(void)
+{
+	u8 status;
+
+	/* Return unprotected status if status read fails. */
+	return early_spi_read_wpsr(&status) ? 0 : !!(status & 0x80);
+}
+
+/* UPD parameters to be initialized before MemoryInit */
+void soc_memory_init_params(struct romstage_params *params,
+			    MEMORY_INIT_UPD *upd)
+{
+	const struct device *dev;
+	const struct soc_intel_kabylake_config *config;
+
+	/* Set the parameters for MemoryInit */
+	dev = dev_find_slot(0, PCI_DEVFN(PCH_DEV_SLOT_LPC, 0));
+	config = dev->chip_info;
+
+	/*
+	 * Set IGD stolen size to 64MB.  The FBC hardware for kabylake does not
+	 * have access to the bios_reserved range so it always assumes 8MB is
+	 * used and so the kernel will avoid the last 8MB of the stolen window.
+	 * With the default stolen size of 32MB(-8MB) there is not enough space
+	 * for FBC to work with a high resolution panel.
+	 */
+	upd->IgdDvmt50PreAlloc = 2;
+
+	upd->MmioSize = 0x800; /* 2GB in MB */
+	upd->TsegSize = CONFIG_SMM_TSEG_SIZE;
+	upd->IedSize = CONFIG_IED_REGION_SIZE;
+	upd->ProbelessTrace = config->ProbelessTrace;
+	upd->EnableTraceHub = config->EnableTraceHub;
+	if (recovery_mode_enabled())
+		upd->SaGv = 0; /* Disable SaGv in recovery mode. */
+	else
+		upd->SaGv = config->SaGv;
+	upd->RMT = config->Rmt;
+	upd->DdrFreqLimit = config->DdrFreqLimit;
+	if (IS_ENABLED(CONFIG_SKIP_FSP_CAR)) {
+		upd->FspCarBase = CONFIG_DCACHE_RAM_BASE;
+		upd->FspCarSize = CONFIG_DCACHE_RAM_SIZE_TOTAL;
+	}
+}
+
+void soc_display_memory_init_params(const MEMORY_INIT_UPD *old,
+	MEMORY_INIT_UPD *new)
+{
+	/* Display the parameters for MemoryInit */
+	printk(BIOS_SPEW, "UPD values for MemoryInit:\n");
+
+	fsp_display_upd_value("PlatformMemorySize", 8,
+		old->PlatformMemorySize, new->PlatformMemorySize);
+	fsp_display_upd_value("MemorySpdPtr00", 4, old->MemorySpdPtr00,
+		new->MemorySpdPtr00);
+	fsp_display_upd_value("MemorySpdPtr01", 4, old->MemorySpdPtr01,
+		new->MemorySpdPtr01);
+	fsp_display_upd_value("MemorySpdPtr10", 4, old->MemorySpdPtr10,
+		new->MemorySpdPtr10);
+	fsp_display_upd_value("MemorySpdPtr11", 4, old->MemorySpdPtr11,
+		new->MemorySpdPtr11);
+	fsp_display_upd_value("MemorySpdDataLen", 2, old->MemorySpdDataLen,
+		new->MemorySpdDataLen);
+	fsp_display_upd_value("DqByteMapCh0[0]", 1, old->DqByteMapCh0[0],
+		new->DqByteMapCh0[0]);
+	fsp_display_upd_value("DqByteMapCh0[1]", 1, old->DqByteMapCh0[1],
+		new->DqByteMapCh0[1]);
+	fsp_display_upd_value("DqByteMapCh0[2]", 1, old->DqByteMapCh0[2],
+		new->DqByteMapCh0[2]);
+	fsp_display_upd_value("DqByteMapCh0[3]", 1, old->DqByteMapCh0[3],
+		new->DqByteMapCh0[3]);
+	fsp_display_upd_value("DqByteMapCh0[4]", 1, old->DqByteMapCh0[4],
+		new->DqByteMapCh0[4]);
+	fsp_display_upd_value("DqByteMapCh0[5]", 1, old->DqByteMapCh0[5],
+		new->DqByteMapCh0[5]);
+	fsp_display_upd_value("DqByteMapCh0[6]", 1, old->DqByteMapCh0[6],
+		new->DqByteMapCh0[6]);
+	fsp_display_upd_value("DqByteMapCh0[7]", 1, old->DqByteMapCh0[7],
+		new->DqByteMapCh0[7]);
+	fsp_display_upd_value("DqByteMapCh0[8]", 1, old->DqByteMapCh0[8],
+		new->DqByteMapCh0[8]);
+	fsp_display_upd_value("DqByteMapCh0[9]", 1, old->DqByteMapCh0[9],
+		new->DqByteMapCh0[9]);
+	fsp_display_upd_value("DqByteMapCh0[10]", 1, old->DqByteMapCh0[10],
+		new->DqByteMapCh0[10]);
+	fsp_display_upd_value("DqByteMapCh0[11]", 1, old->DqByteMapCh0[11],
+		new->DqByteMapCh0[11]);
+	fsp_display_upd_value("DqByteMapCh1[0]", 1, old->DqByteMapCh1[0],
+		new->DqByteMapCh1[0]);
+	fsp_display_upd_value("DqByteMapCh1[1]", 1, old->DqByteMapCh1[1],
+		new->DqByteMapCh1[1]);
+	fsp_display_upd_value("DqByteMapCh1[2]", 1, old->DqByteMapCh1[2],
+		new->DqByteMapCh1[2]);
+	fsp_display_upd_value("DqByteMapCh1[3]", 1, old->DqByteMapCh1[3],
+		new->DqByteMapCh1[3]);
+	fsp_display_upd_value("DqByteMapCh1[4]", 1, old->DqByteMapCh1[4],
+		new->DqByteMapCh1[4]);
+	fsp_display_upd_value("DqByteMapCh1[5]", 1, old->DqByteMapCh1[5],
+		new->DqByteMapCh1[5]);
+	fsp_display_upd_value("DqByteMapCh1[6]", 1, old->DqByteMapCh1[6],
+		new->DqByteMapCh1[6]);
+	fsp_display_upd_value("DqByteMapCh1[7]", 1, old->DqByteMapCh1[7],
+		new->DqByteMapCh1[7]);
+	fsp_display_upd_value("DqByteMapCh1[8]", 1, old->DqByteMapCh1[8],
+		new->DqByteMapCh1[8]);
+	fsp_display_upd_value("DqByteMapCh1[9]", 1, old->DqByteMapCh1[9],
+		new->DqByteMapCh1[9]);
+	fsp_display_upd_value("DqByteMapCh1[10]", 1, old->DqByteMapCh1[10],
+		new->DqByteMapCh1[10]);
+	fsp_display_upd_value("DqByteMapCh1[11]", 1, old->DqByteMapCh1[11],
+		new->DqByteMapCh1[11]);
+	fsp_display_upd_value("DqsMapCpu2DramCh0[0]", 1,
+		old->DqsMapCpu2DramCh0[0], new->DqsMapCpu2DramCh0[0]);
+	fsp_display_upd_value("DqsMapCpu2DramCh0[1]", 1,
+		old->DqsMapCpu2DramCh0[1], new->DqsMapCpu2DramCh0[1]);
+	fsp_display_upd_value("DqsMapCpu2DramCh0[2]", 1,
+		old->DqsMapCpu2DramCh0[2], new->DqsMapCpu2DramCh0[2]);
+	fsp_display_upd_value("DqsMapCpu2DramCh0[3]", 1,
+		old->DqsMapCpu2DramCh0[3], new->DqsMapCpu2DramCh0[3]);
+	fsp_display_upd_value("DqsMapCpu2DramCh0[4]", 1,
+		old->DqsMapCpu2DramCh0[4], new->DqsMapCpu2DramCh0[4]);
+	fsp_display_upd_value("DqsMapCpu2DramCh0[5]", 1,
+		old->DqsMapCpu2DramCh0[5], new->DqsMapCpu2DramCh0[5]);
+	fsp_display_upd_value("DqsMapCpu2DramCh0[6]", 1,
+		old->DqsMapCpu2DramCh0[6], new->DqsMapCpu2DramCh0[6]);
+	fsp_display_upd_value("DqsMapCpu2DramCh0[7]", 1,
+		old->DqsMapCpu2DramCh0[7], new->DqsMapCpu2DramCh0[7]);
+	fsp_display_upd_value("DqsMapCpu2DramCh1[0]", 1,
+		old->DqsMapCpu2DramCh1[0], new->DqsMapCpu2DramCh1[0]);
+	fsp_display_upd_value("DqsMapCpu2DramCh1[1]", 1,
+		old->DqsMapCpu2DramCh1[1], new->DqsMapCpu2DramCh1[1]);
+	fsp_display_upd_value("DqsMapCpu2DramCh1[2]", 1,
+		old->DqsMapCpu2DramCh1[2], new->DqsMapCpu2DramCh1[2]);
+	fsp_display_upd_value("DqsMapCpu2DramCh1[3]", 1,
+		old->DqsMapCpu2DramCh1[3], new->DqsMapCpu2DramCh1[3]);
+	fsp_display_upd_value("DqsMapCpu2DramCh1[4]", 1,
+		old->DqsMapCpu2DramCh1[4], new->DqsMapCpu2DramCh1[4]);
+	fsp_display_upd_value("DqsMapCpu2DramCh1[5]", 1,
+		old->DqsMapCpu2DramCh1[5], new->DqsMapCpu2DramCh1[5]);
+	fsp_display_upd_value("DqsMapCpu2DramCh1[6]", 1,
+		old->DqsMapCpu2DramCh1[6], new->DqsMapCpu2DramCh1[6]);
+	fsp_display_upd_value("DqsMapCpu2DramCh1[7]", 1,
+		old->DqsMapCpu2DramCh1[7], new->DqsMapCpu2DramCh1[7]);
+	fsp_display_upd_value("DqPinsInterleaved", 1,
+		old->DqPinsInterleaved, new->DqPinsInterleaved);
+	fsp_display_upd_value("RcompResistor[0]", 2, old->RcompResistor[0],
+		new->RcompResistor[0]);
+	fsp_display_upd_value("RcompResistor[1]", 2, old->RcompResistor[1],
+		new->RcompResistor[1]);
+	fsp_display_upd_value("RcompResistor[2]", 2, old->RcompResistor[2],
+		new->RcompResistor[2]);
+	fsp_display_upd_value("RcompTarget[0]", 1, old->RcompTarget[0],
+		new->RcompTarget[0]);
+	fsp_display_upd_value("RcompTarget[1]", 1, old->RcompTarget[1],
+		new->RcompTarget[1]);
+	fsp_display_upd_value("RcompTarget[2]", 1, old->RcompTarget[2],
+		new->RcompTarget[2]);
+	fsp_display_upd_value("RcompTarget[3]", 1, old->RcompTarget[3],
+		new->RcompTarget[3]);
+	fsp_display_upd_value("RcompTarget[4]", 1, old->RcompTarget[4],
+		new->RcompTarget[4]);
+	fsp_display_upd_value("CaVrefConfig", 1, old->CaVrefConfig,
+		new->CaVrefConfig);
+	fsp_display_upd_value("SmramMask", 1, old->SmramMask, new->SmramMask);
+	fsp_display_upd_value("MrcFastBoot", 1, old->MrcFastBoot,
+		new->MrcFastBoot);
+	fsp_display_upd_value("IedSize", 4, old->IedSize, new->IedSize);
+	fsp_display_upd_value("TsegSize", 4, old->TsegSize, new->TsegSize);
+	fsp_display_upd_value("MmioSize", 2, old->MmioSize, new->MmioSize);
+	fsp_display_upd_value("EnableTraceHub", 1, old->EnableTraceHub,
+		new->EnableTraceHub);
+	fsp_display_upd_value("IgdDvmt50PreAlloc", 1, old->IgdDvmt50PreAlloc,
+		new->IgdDvmt50PreAlloc);
+	fsp_display_upd_value("InternalGfx", 1, old->InternalGfx,
+		new->InternalGfx);
+	fsp_display_upd_value("ApertureSize", 1, old->ApertureSize,
+		new->ApertureSize);
+	fsp_display_upd_value("SaGv", 1, old->SaGv, new->SaGv);
+	fsp_display_upd_value("RMT", 1, old->RMT, new->RMT);
+	fsp_display_upd_value("FspCarBase", 1, old->FspCarBase,
+		new->FspCarBase);
+	fsp_display_upd_value("FspCarSize", 1, old->FspCarSize,
+		new->FspCarSize);
+}
+
+/* SOC initialization after RAM is enabled. */
+void soc_after_ram_init(struct romstage_params *params)
+{
+	/* Set the DISB as soon as possible after DRAM
+	 * init and MRC cache is saved.
+	 */
+	u32 disb_val = 0;
+	device_t dev = PCH_DEV_PMC;
+	disb_val = pci_read_config32(dev, GEN_PMCON_A);
+	disb_val |= DISB;
+	/* Preserve bits which get cleared up if written 1 */
+	disb_val &= ~(GBL_RST_STS | MS4V);
+	pci_write_config32(dev, GEN_PMCON_A, disb_val);
+}
diff --git a/src/soc/intel/kabylake/romstage/smbus.c b/src/soc/intel/kabylake/romstage/smbus.c
new file mode 100644
index 0000000..f7e5dab
--- /dev/null
+++ b/src/soc/intel/kabylake/romstage/smbus.c
@@ -0,0 +1,51 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008-2009 coresystems GmbH
+ * Copyright (C) 2014 Google Inc.
+ * 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 <arch/io.h>
+#include <console/console.h>
+#include <device/pci_ids.h>
+#include <device/pci_def.h>
+#include <reg_script.h>
+#include <soc/iomap.h>
+#include <soc/pci_devs.h>
+#include <soc/smbus.h>
+#include <soc/romstage.h>
+
+static const struct reg_script smbus_init_script[] = {
+	/* Set SMBUS I/O base address */
+	REG_PCI_WRITE32(SMB_BASE, SMBUS_BASE_ADDRESS | 1),
+	/* Set SMBUS enable */
+	REG_PCI_WRITE8(HOSTC, HST_EN),
+	/* Enable I/O access */
+	REG_PCI_WRITE16(PCI_COMMAND, PCI_COMMAND_IO),
+	/* Disable interrupts */
+	REG_IO_WRITE8(SMBUS_BASE_ADDRESS + SMBHSTCTL, 0),
+	/* Clear errors */
+	REG_IO_WRITE8(SMBUS_BASE_ADDRESS + SMBHSTSTAT, 0xff),
+	/* Indicate the end of this array by REG_SCRIPT_END */
+	REG_SCRIPT_END,
+};
+
+void enable_smbus(void)
+{
+	reg_script_run_on_dev(PCH_DEV_SMBUS, smbus_init_script);
+}
+
+int smbus_read_byte(unsigned device, unsigned address)
+{
+	return do_smbus_read_byte(SMBUS_BASE_ADDRESS, device, address);
+}
diff --git a/src/soc/intel/kabylake/romstage/spi.c b/src/soc/intel/kabylake/romstage/spi.c
new file mode 100644
index 0000000..95a07c5
--- /dev/null
+++ b/src/soc/intel/kabylake/romstage/spi.c
@@ -0,0 +1,42 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * 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 <soc/flash_controller.h>
+#include <soc/romstage.h>
+
+/*
+ * Minimal set of commands to read WPSR from SPI.
+ * Returns 0 on success, < 0 on failure.
+ */
+int early_spi_read_wpsr(u8 *sr)
+{
+	uint8_t rdsr;
+	int ret = 0;
+
+	spi_init();
+
+	/* sending NULL for spiflash struct parameter since we are not
+	 * calling HWSEQ read_status() call via Probe.
+	 */
+	ret = pch_hwseq_read_status(NULL, &rdsr);
+	if (ret) {
+		printk(BIOS_ERR, "SPI rdsr failed\n");
+		return ret;
+	}
+	*sr = rdsr & WPSR_MASK_SRP0_BIT;
+
+	return 0;
+}
diff --git a/src/soc/intel/kabylake/romstage/systemagent.c b/src/soc/intel/kabylake/romstage/systemagent.c
new file mode 100644
index 0000000..2b796e3
--- /dev/null
+++ b/src/soc/intel/kabylake/romstage/systemagent.c
@@ -0,0 +1,52 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2010 coresystems GmbH
+ * Copyright (C) 2014 Google Inc.
+ * 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 <stdlib.h>
+#include <arch/io.h>
+#include <device/pci_def.h>
+#include <reg_script.h>
+#include <soc/iomap.h>
+#include <soc/pci_devs.h>
+#include <soc/romstage.h>
+#include <soc/systemagent.h>
+
+static const struct reg_script systemagent_early_init_script[] = {
+	REG_PCI_WRITE32(MCHBAR, MCH_BASE_ADDRESS | 1),
+	REG_PCI_WRITE32(DMIBAR, DMI_BASE_ADDRESS | 1),
+	REG_PCI_WRITE32(EPBAR, EP_BASE_ADDRESS | 1),
+	REG_MMIO_WRITE32(MCH_BASE_ADDRESS + EDRAMBAR, EDRAM_BASE_ADDRESS | 1),
+	REG_MMIO_WRITE32(MCH_BASE_ADDRESS + GDXCBAR, GDXC_BASE_ADDRESS | 1),
+
+	/* Set C0000-FFFFF to access RAM on both reads and writes */
+	REG_PCI_WRITE8(PAM0, 0x30),
+	REG_PCI_WRITE8(PAM1, 0x33),
+	REG_PCI_WRITE8(PAM2, 0x33),
+	REG_PCI_WRITE8(PAM3, 0x33),
+	REG_PCI_WRITE8(PAM4, 0x33),
+	REG_PCI_WRITE8(PAM5, 0x33),
+	REG_PCI_WRITE8(PAM6, 0x33),
+
+	/* Device enable: IGD and Mini-HD */
+	REG_PCI_WRITE32(DEVEN, DEVEN_D0EN | DEVEN_D2EN | DEVEN_D3EN),
+
+	REG_SCRIPT_END
+};
+
+void systemagent_early_init(void)
+{
+	reg_script_run_on_dev(SA_DEV_ROOT, systemagent_early_init_script);
+}
diff --git a/src/soc/intel/kabylake/romstage/uart.c b/src/soc/intel/kabylake/romstage/uart.c
new file mode 100644
index 0000000..303d99f
--- /dev/null
+++ b/src/soc/intel/kabylake/romstage/uart.c
@@ -0,0 +1,70 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 Google Inc.
+ * 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 <arch/io.h>
+#include <console/uart.h>
+#include <device/pci_def.h>
+#include <stdint.h>
+#include <soc/pci_devs.h>
+#include <soc/pcr.h>
+#include <soc/romstage.h>
+#include <soc/serialio.h>
+#include <gpio.h>
+
+/* UART2 pad configuration. Support RXD and TXD for now. */
+static const struct pad_config uart2_pads[] = {
+/* UART2_RXD */		PAD_CFG_NF(GPP_C20, NONE, DEEP, NF1),
+/* UART2_TXD */		PAD_CFG_NF(GPP_C21, NONE, DEEP, NF1),
+};
+
+void pch_uart_init(void)
+{
+	device_t dev = PCH_DEV_UART2;
+	u32 tmp;
+	u8 *base = (void *)uart_platform_base(CONFIG_UART_FOR_CONSOLE);
+
+	/* Set configured UART2 base address */
+	pci_write_config32(dev, PCI_BASE_ADDRESS_0, (u32)base);
+
+	/* Enable memory access and bus master */
+	tmp = pci_read_config32(dev, PCI_COMMAND);
+	tmp |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
+	pci_write_config32(dev, PCI_COMMAND, tmp);
+
+	/* Take UART2 out of reset */
+	tmp = read32(base + SIO_REG_PPR_RESETS);
+	tmp |= SIO_REG_PPR_RESETS_FUNC | SIO_REG_PPR_RESETS_APB |
+		SIO_REG_PPR_RESETS_IDMA;
+	write32(base + SIO_REG_PPR_RESETS, tmp);
+
+	/*
+	 * Set M and N divisor inputs and enable clock.
+	 * Main reference frequency to UART is:
+	 *  120MHz * M / N = 120MHz * 48 / 3125 = 1843200Hz
+	 */
+	tmp = read32(base + SIO_REG_PPR_CLOCK);
+	tmp |= SIO_REG_PPR_CLOCK_EN | SIO_REG_PPR_CLOCK_UPDATE |
+		(SIO_REG_PPR_CLOCK_N_DIV << 16) |
+		(SIO_REG_PPR_CLOCK_M_DIV << 1);
+	write32(base + SIO_REG_PPR_CLOCK, tmp);
+
+	/* Put UART2 in byte access mode for 16550 compatibility */
+	if (!IS_ENABLED(CONFIG_DRIVERS_UART_8250MEM_32))
+		pcr_andthenor32(PID_SERIALIO,
+		R_PCH_PCR_SERIAL_IO_GPPRVRW7, 0, SIO_PCH_LEGACY_UART2);
+
+	gpio_configure_pads(uart2_pads, ARRAY_SIZE(uart2_pads));
+}
diff --git a/src/soc/intel/kabylake/sd.c b/src/soc/intel/kabylake/sd.c
new file mode 100644
index 0000000..a75cf63
--- /dev/null
+++ b/src/soc/intel/kabylake/sd.c
@@ -0,0 +1,88 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2016 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.
+ */
+
+#include <arch/acpi_device.h>
+#include <arch/acpigen.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <gpio.h>
+#include <soc/ramstage.h>
+#include "chip.h"
+
+#if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES)
+static void sd_fill_ssdt(struct device *dev)
+{
+	config_t *config = dev->chip_info;
+	const char *path;
+	struct acpi_gpio default_gpio = {
+		.type = ACPI_GPIO_TYPE_INTERRUPT,
+		.pull = ACPI_GPIO_PULL_NONE,
+		.irq.mode = IRQ_EDGE_TRIGGERED,
+		.irq.polarity = IRQ_ACTIVE_BOTH,
+		.irq.shared = IRQ_SHARED,
+		.irq.wake = IRQ_WAKE,
+		.interrupt_debounce_timeout = 10000, /* 100ms */
+		.pin_count = 1,
+		.pins = { config->sdcard_cd_gpio_default }
+	};
+	struct acpi_dp *dp;
+
+	if (!dev->enabled)
+		return;
+
+	/* Nothing to write if GPIO is not set in devicetree */
+	if (!config->sdcard_cd_gpio_default && !config->sdcard_cd_gpio.pins[0])
+		return;
+
+	/* Use device path as the Scope for the SSDT */
+	path = acpi_device_path(dev);
+	if (!path)
+		return;
+	acpigen_write_scope(path);
+	acpigen_write_name("_CRS");
+
+	/* Write GpioInt() as default (if set) or custom from devicetree */
+	acpigen_write_resourcetemplate_header();
+	if (config->sdcard_cd_gpio_default)
+		acpi_device_write_gpio(&default_gpio);
+	else
+		acpi_device_write_gpio(&config->sdcard_cd_gpio);
+	acpigen_write_resourcetemplate_footer();
+
+	/* Bind the cd-gpio name to the GpioInt() resource */
+	dp = acpi_dp_new_table("_DSD");
+	acpi_dp_add_gpio(dp, "cd-gpio", path, 0, 0, 1);
+	acpi_dp_write(dp);
+
+	acpigen_pop_len();
+}
+#endif
+
+static struct device_operations dev_ops = {
+	.read_resources		  = &pci_dev_read_resources,
+	.set_resources		  = &pci_dev_set_resources,
+	.enable_resources	  = &pci_dev_enable_resources,
+	.ops_pci		  = &soc_pci_ops,
+#if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES)
+	.acpi_fill_ssdt_generator = &sd_fill_ssdt,
+#endif
+};
+
+static const struct pci_driver pch_sd __pci_driver = {
+	.ops	= &dev_ops,
+	.vendor	= PCI_VENDOR_ID_INTEL,
+	.device	= 0x9d2d
+};
diff --git a/src/soc/intel/kabylake/smbus.c b/src/soc/intel/kabylake/smbus.c
new file mode 100644
index 0000000..97d05b6
--- /dev/null
+++ b/src/soc/intel/kabylake/smbus.c
@@ -0,0 +1,109 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008-2009 coresystems GmbH
+ * Copyright (C) 2014 Google Inc.
+ * 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 <arch/io.h>
+#include <console/console.h>
+#include <device/device.h>
+#include <device/path.h>
+#include <device/smbus.h>
+#include <device/smbus_def.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <soc/iomap.h>
+#include <soc/ramstage.h>
+#include <soc/smbus.h>
+
+static void pch_smbus_init(device_t dev)
+{
+	struct resource *res;
+	u16 reg16;
+
+	/* Enable clock gating */
+	reg16 = pci_read_config32(dev, 0x80);
+	reg16 &= ~((1 << 8)|(1 << 10)|(1 << 12)|(1 << 14));
+	pci_write_config32(dev, 0x80, reg16);
+
+	/* Set Receive Slave Address */
+	res = find_resource(dev, PCI_BASE_ADDRESS_4);
+	if (res)
+		outb(SMBUS_SLAVE_ADDR, res->base + SMB_RCV_SLVA);
+}
+
+static int lsmbus_read_byte(device_t dev, u8 address)
+{
+	u16 device;
+	struct resource *res;
+	struct bus *pbus;
+
+	device = dev->path.i2c.device;
+	pbus = get_pbus_smbus(dev);
+	res = find_resource(pbus->dev, PCI_BASE_ADDRESS_4);
+
+	return do_smbus_read_byte(res->base, device, address);
+}
+
+static int lsmbus_write_byte(device_t dev, u8 address, u8 data)
+{
+	u16 device;
+	struct resource *res;
+	struct bus *pbus;
+
+	device = dev->path.i2c.device;
+	pbus = get_pbus_smbus(dev);
+	res = find_resource(pbus->dev, PCI_BASE_ADDRESS_4);
+	return do_smbus_write_byte(res->base, device, address, data);
+}
+
+static struct smbus_bus_operations lops_smbus_bus = {
+	.read_byte	= lsmbus_read_byte,
+	.write_byte	= lsmbus_write_byte,
+};
+
+static void smbus_read_resources(device_t dev)
+{
+	struct resource *res = new_resource(dev, PCI_BASE_ADDRESS_4);
+	res->base = SMBUS_BASE_ADDRESS;
+	res->size = 32;
+	res->limit = res->base + res->size - 1;
+	res->flags = IORESOURCE_IO | IORESOURCE_FIXED | IORESOURCE_RESERVE |
+		     IORESOURCE_STORED | IORESOURCE_ASSIGNED;
+
+	/* Also add MMIO resource */
+	res = pci_get_resource(dev, PCI_BASE_ADDRESS_0);
+}
+
+static struct device_operations smbus_ops = {
+	.read_resources		= &smbus_read_resources,
+	.set_resources		= &pci_dev_set_resources,
+	.enable_resources	= &pci_dev_enable_resources,
+	.scan_bus		= &scan_smbus,
+	.init			= &pch_smbus_init,
+	.ops_smbus_bus		= &lops_smbus_bus,
+	.ops_pci		= &soc_pci_ops,
+};
+
+static const unsigned short pci_device_ids[] = {
+	0x9d23, /* SunRisePoint LP */
+	0
+};
+
+static const struct pci_driver pch_smbus __pci_driver = {
+	.ops	 = &smbus_ops,
+	.vendor	 = PCI_VENDOR_ID_INTEL,
+	.devices = pci_device_ids,
+};
diff --git a/src/soc/intel/kabylake/smbus_common.c b/src/soc/intel/kabylake/smbus_common.c
new file mode 100644
index 0000000..9b1cac8
--- /dev/null
+++ b/src/soc/intel/kabylake/smbus_common.c
@@ -0,0 +1,150 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2005 Yinghai Lu <yinghailu at gmail.com>
+ * Copyright (C) 2008-2009 coresystems GmbH
+ * Copyright (C) 2014 Google Inc.
+ * 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 <arch/io.h>
+#include <console/console.h>
+#include <device/device.h>
+#include <device/path.h>
+#include <device/smbus_def.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <soc/ramstage.h>
+#include <soc/smbus.h>
+
+static void smbus_delay(void)
+{
+	inb(0x80);
+}
+
+static int smbus_wait_until_ready(u16 smbus_base)
+{
+	unsigned loops = SMBUS_TIMEOUT;
+	unsigned char byte;
+	do {
+		smbus_delay();
+		if (--loops == 0)
+			break;
+		byte = inb(smbus_base + SMBHSTSTAT);
+	} while (byte & 1);
+	return loops ? 0 : -1;
+}
+
+static int smbus_wait_until_done(u16 smbus_base)
+{
+	unsigned loops = SMBUS_TIMEOUT;
+	unsigned char byte;
+	do {
+		smbus_delay();
+		if (--loops == 0)
+			break;
+		byte = inb(smbus_base + SMBHSTSTAT);
+	} while ((byte & 1) || (byte & ~((1 << 6) | (1 << 0))) == 0);
+	return loops ? 0 : -1;
+}
+
+int do_smbus_read_byte(unsigned smbus_base, unsigned device, unsigned address)
+{
+	unsigned char global_status_register;
+	unsigned char byte;
+
+	if (smbus_wait_until_ready(smbus_base) < 0)
+		return SMBUS_WAIT_UNTIL_READY_TIMEOUT;
+
+	/* Setup transaction */
+	/* Disable interrupts */
+	outb(inb(smbus_base + SMBHSTCTL) & (~1), smbus_base + SMBHSTCTL);
+	/* Set the device I'm talking too */
+	outb(((device & 0x7f) << 1) | 1, smbus_base + SMBXMITADD);
+	/* Set the command/address... */
+	outb(address & 0xff, smbus_base + SMBHSTCMD);
+	/* Set up for a byte data read */
+	outb((inb(smbus_base + SMBHSTCTL) & 0xe3) | (0x2 << 2),
+	     (smbus_base + SMBHSTCTL));
+	/* Clear any lingering errors, so the transaction will run */
+	outb(inb(smbus_base + SMBHSTSTAT), smbus_base + SMBHSTSTAT);
+
+	/* Clear the data byte... */
+	outb(0, smbus_base + SMBHSTDAT0);
+
+	/* Start the command */
+	outb((inb(smbus_base + SMBHSTCTL) | 0x40),
+	     smbus_base + SMBHSTCTL);
+
+	/* Poll for transaction completion */
+	if (smbus_wait_until_done(smbus_base) < 0)
+		return SMBUS_WAIT_UNTIL_DONE_TIMEOUT;
+
+	global_status_register = inb(smbus_base + SMBHSTSTAT);
+
+	/* Ignore the "In Use" status... */
+	global_status_register &= ~(3 << 5);
+
+	/* Read results of transaction */
+	byte = inb(smbus_base + SMBHSTDAT0);
+	if (global_status_register != (1 << 1))
+		return SMBUS_ERROR;
+	return byte;
+}
+
+int do_smbus_write_byte(unsigned smbus_base, unsigned device,
+			unsigned address, unsigned data)
+{
+	unsigned char global_status_register;
+
+	if (smbus_wait_until_ready(smbus_base) < 0)
+		return SMBUS_WAIT_UNTIL_READY_TIMEOUT;
+
+	/* Setup transaction */
+	/* Disable interrupts */
+	outb(inb(smbus_base + SMBHSTCTL) & (~1), smbus_base + SMBHSTCTL);
+	/* Set the device I'm talking too */
+	outb(((device & 0x7f) << 1) & ~0x01, smbus_base + SMBXMITADD);
+	/* Set the command/address... */
+	outb(address & 0xff, smbus_base + SMBHSTCMD);
+	/* Set up for a byte data read */
+	outb((inb(smbus_base + SMBHSTCTL) & 0xe3) | (0x2 << 2),
+	     (smbus_base + SMBHSTCTL));
+	/* Clear any lingering errors, so the transaction will run */
+	outb(inb(smbus_base + SMBHSTSTAT), smbus_base + SMBHSTSTAT);
+
+	/* Clear the data byte... */
+	outb(data, smbus_base + SMBHSTDAT0);
+
+	/* Start the command */
+	outb((inb(smbus_base + SMBHSTCTL) | 0x40),
+	     smbus_base + SMBHSTCTL);
+
+	/* Poll for transaction completion */
+	if (smbus_wait_until_done(smbus_base) < 0) {
+		printk(BIOS_ERR, "SMBUS transaction timeout\n");
+		return SMBUS_WAIT_UNTIL_DONE_TIMEOUT;
+	}
+
+	global_status_register = inb(smbus_base + SMBHSTSTAT);
+
+	/* Ignore the "In Use" status... */
+	global_status_register &= ~(3 << 5);
+
+	/* Read results of transaction */
+	if (global_status_register != (1 << 1)) {
+		printk(BIOS_ERR, "SMBUS transaction error\n");
+		return SMBUS_ERROR;
+	}
+
+	return 0;
+}
diff --git a/src/soc/intel/kabylake/smi.c b/src/soc/intel/kabylake/smi.c
new file mode 100644
index 0000000..85c4663
--- /dev/null
+++ b/src/soc/intel/kabylake/smi.c
@@ -0,0 +1,121 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008-2009 coresystems GmbH
+ * Copyright (C) 2014 Google Inc.
+ * 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 <device/device.h>
+#include <device/pci.h>
+#include <console/console.h>
+#include <arch/io.h>
+#include <cpu/cpu.h>
+#include <cpu/x86/cache.h>
+#include <cpu/x86/smm.h>
+#include <string.h>
+#include <soc/iomap.h>
+#include <soc/pch.h>
+#include <soc/pm.h>
+#include <soc/smm.h>
+
+void southbridge_smm_clear_state(void)
+{
+	u32 smi_en;
+
+	printk(BIOS_DEBUG, "Initializing Southbridge SMI...");
+	printk(BIOS_SPEW, " ... pmbase = 0x%04x\n", ACPI_BASE_ADDRESS);
+
+	smi_en = inl(ACPI_BASE_ADDRESS + SMI_EN);
+	if (smi_en & APMC_EN) {
+		printk(BIOS_INFO, "SMI# handler already enabled?\n");
+		return;
+	}
+
+	printk(BIOS_DEBUG, "\n");
+
+	/* Dump and clear status registers */
+	clear_smi_status();
+	clear_pm1_status();
+	clear_tco_status();
+	clear_gpe_status();
+}
+
+void southbridge_smm_enable_smi(void)
+{
+	printk(BIOS_DEBUG, "Enabling SMIs.\n");
+	/* Configure events */
+	enable_pm1(PWRBTN_EN | GBL_EN);
+	disable_gpe(PME_B0_EN);
+
+	/*
+	 * Enable SMI generation:
+	 *  - on APMC writes (io 0xb2)
+	 *  - on writes to SLP_EN (sleep states)
+	 *  - on writes to GBL_RLS (bios commands)
+	 * No SMIs:
+	 *  - on microcontroller writes (io 0x62/0x66)
+	 *  - on TCO events
+	 */
+	enable_smi(APMC_EN | SLP_SMI_EN | GBL_SMI_EN | EOS);
+}
+
+void southbridge_trigger_smi(void)
+{
+	/*
+	 * There are several methods of raising a controlled SMI# via
+	 * software, among them:
+	 *  - Writes to io 0xb2 (APMC)
+	 *  - Writes to the Local Apic ICR with Delivery mode SMI.
+	 *
+	 * Using the local apic is a bit more tricky. According to
+	 * AMD Family 11 Processor BKDG no destination shorthand must be
+	 * used.
+	 * The whole SMM initialization is quite a bit hardware specific, so
+	 * I'm not too worried about the better of the methods at the moment
+	 */
+
+	/* raise an SMI interrupt */
+	printk(BIOS_SPEW, "  ... raise SMI#\n");
+	outb(0x00, 0xb2);
+}
+
+void southbridge_clear_smi_status(void)
+{
+	/* Clear SMI status */
+	clear_smi_status();
+
+	/* Clear PM1 status */
+	clear_pm1_status();
+
+	/* Set EOS bit so other SMIs can occur. */
+	enable_smi(EOS);
+}
+
+void smm_setup_structures(void *gnvs, void *tcg, void *smi1)
+{
+	/*
+	 * Issue SMI to set the gnvs pointer in SMM.
+	 * tcg and smi1 are unused.
+	 *
+	 * EAX = APM_CNT_GNVS_UPDATE
+	 * EBX = gnvs pointer
+	 * EDX = APM_CNT
+	 */
+	asm volatile (
+		"outb %%al, %%dx\n\t"
+		: /* ignore result */
+		: "a" (APM_CNT_GNVS_UPDATE),
+		  "b" ((u32)gnvs),
+		  "d" (APM_CNT)
+	);
+}
diff --git a/src/soc/intel/kabylake/smihandler.c b/src/soc/intel/kabylake/smihandler.c
new file mode 100644
index 0000000..68e86ba
--- /dev/null
+++ b/src/soc/intel/kabylake/smihandler.c
@@ -0,0 +1,517 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008-2009 coresystems GmbH
+ * Copyright (C) 2014 Google Inc.
+ * 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 <delay.h>
+#include <types.h>
+#include <arch/hlt.h>
+#include <arch/io.h>
+#include <console/console.h>
+#include <cpu/x86/cache.h>
+#include <device/pci_def.h>
+#include <cpu/x86/smm.h>
+#include <spi-generic.h>
+#include <elog.h>
+#include <pc80/mc146818rtc.h>
+#include <soc/iomap.h>
+#include <soc/lpc.h>
+#include <soc/nvs.h>
+#include <soc/pci_devs.h>
+#include <soc/pch.h>
+#include <soc/pcr.h>
+#include <soc/pm.h>
+#include <soc/pmc.h>
+#include <soc/smm.h>
+
+static u8 smm_initialized = 0;
+
+/*
+ * GNVS needs to be updated by an 0xEA PM Trap (B2) after it has been located
+ * by coreboot.
+ */
+static global_nvs_t *gnvs;
+global_nvs_t *smm_get_gnvs(void)
+{
+	return gnvs;
+}
+
+int southbridge_io_trap_handler(int smif)
+{
+	switch (smif) {
+	case 0x32:
+		printk(BIOS_DEBUG, "OS Init\n");
+		/*
+		 * gnvs->smif:
+		 * - On success, the IO Trap Handler returns 0
+		 * - On failure, the IO Trap Handler returns a value != 0
+		 */
+		gnvs->smif = 0;
+		return 1; /* IO trap handled */
+	}
+
+	/* Not handled */
+	return 0;
+}
+
+/* Set the EOS bit */
+void southbridge_smi_set_eos(void)
+{
+	enable_smi(EOS);
+}
+
+static void busmaster_disable_on_bus(int bus)
+{
+	int slot, func;
+	unsigned int val;
+	unsigned char hdr;
+
+	for (slot = 0; slot < 0x20; slot++) {
+		for (func = 0; func < 8; func++) {
+			u32 reg32;
+			device_t dev = PCI_DEV(bus, slot, func);
+
+			val = pci_read_config32(dev, PCI_VENDOR_ID);
+
+			if (val == 0xffffffff || val == 0x00000000 ||
+			    val == 0x0000ffff || val == 0xffff0000)
+				continue;
+
+			/* Disable Bus Mastering for this one device */
+			reg32 = pci_read_config32(dev, PCI_COMMAND);
+			reg32 &= ~PCI_COMMAND_MASTER;
+			pci_write_config32(dev, PCI_COMMAND, reg32);
+
+			/* If this is a bridge, then follow it. */
+			hdr = pci_read_config8(dev, PCI_HEADER_TYPE);
+			hdr &= 0x7f;
+			if (hdr == PCI_HEADER_TYPE_BRIDGE ||
+			    hdr == PCI_HEADER_TYPE_CARDBUS) {
+				unsigned int buses;
+				buses = pci_read_config32(dev, PCI_PRIMARY_BUS);
+				busmaster_disable_on_bus((buses >> 8) & 0xff);
+			}
+		}
+	}
+}
+
+
+static void southbridge_smi_sleep(void)
+{
+	u8 reg8;
+	u32 reg32;
+	u8 slp_typ;
+	u8 s5pwr = CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL;
+
+	/* save and recover RTC port values */
+	u8 tmp70, tmp72;
+	tmp70 = inb(0x70);
+	tmp72 = inb(0x72);
+	get_option(&s5pwr, "power_on_after_fail");
+	outb(tmp70, 0x70);
+	outb(tmp72, 0x72);
+
+	/* First, disable further SMIs */
+	disable_smi(SLP_SMI_EN);
+
+	/* Figure out SLP_TYP */
+	reg32 = inl(ACPI_BASE_ADDRESS + PM1_CNT);
+	printk(BIOS_SPEW, "SMI#: SLP = 0x%08x\n", reg32);
+	slp_typ = acpi_sleep_from_pm1(reg32);
+
+	/* Do any mainboard sleep handling */
+	mainboard_smi_sleep(slp_typ);
+
+	if (IS_ENABLED(CONFIG_ELOG_GSMI))
+		/* Log S3, S4, and S5 entry */
+		if (slp_typ >= ACPI_S3)
+			elog_add_event_byte(ELOG_TYPE_ACPI_ENTER, slp_typ);
+
+	/* Clear pending GPE events */
+	clear_gpe_status();
+
+	/* Next, do the deed. */
+	switch (slp_typ) {
+	case ACPI_S0:
+		printk(BIOS_DEBUG, "SMI#: Entering S0 (On)\n");
+		break;
+	case ACPI_S1:
+		printk(BIOS_DEBUG, "SMI#: Entering S1 (Assert STPCLK#)\n");
+		break;
+	case ACPI_S3:
+		printk(BIOS_DEBUG, "SMI#: Entering S3 (Suspend-To-RAM)\n");
+
+		/* Invalidate the cache before going to S3 */
+		wbinvd();
+		break;
+	case ACPI_S5:
+		printk(BIOS_DEBUG, "SMI#: Entering S5 (Soft Power off)\n");
+		/*TODO: cmos_layout.bin need to verify; cause wrong CMOS setup*/
+		s5pwr = MAINBOARD_POWER_ON;
+		/* Disable all GPE */
+		disable_all_gpe();
+
+		/*
+		 * Always set the flag in case CMOS was changed on runtime. For
+		 * "KEEP", switch to "OFF" - KEEP is software emulated
+		 */
+		reg8 = pci_read_config8(PCH_DEV_PMC, GEN_PMCON_B);
+		if (s5pwr == MAINBOARD_POWER_ON)
+			reg8 &= ~1;
+		else
+			reg8 |= 1;
+		pci_write_config8(PCH_DEV_PMC, GEN_PMCON_B, reg8);
+
+		/* also iterates over all bridges on bus 0 */
+		busmaster_disable_on_bus(0);
+		break;
+	default:
+		printk(BIOS_DEBUG, "SMI#: ERROR: SLP_TYP reserved\n");
+		break;
+	}
+
+	/*
+	 * Write back to the SLP register to cause the originally intended
+	 * event again. We need to set BIT13 (SLP_EN) though to make the
+	 * sleep happen.
+	 */
+	enable_pm1_control(SLP_EN);
+
+	/* Make sure to stop executing code here for S3/S4/S5 */
+	if (slp_typ >= ACPI_S3)
+		hlt();
+
+	/*
+	 * In most sleep states, the code flow of this function ends at
+	 * the line above. However, if we entered sleep state S1 and wake
+	 * up again, we will continue to execute code in this function.
+	 */
+	reg32 = inl(ACPI_BASE_ADDRESS + PM1_CNT);
+	if (reg32 & SCI_EN) {
+		/* The OS is not an ACPI OS, so we set the state to S0 */
+		disable_pm1_control(SLP_EN | SLP_TYP);
+	}
+}
+
+/*
+ * Look for Synchronous IO SMI and use save state from that
+ * core in case we are not running on the same core that
+ * initiated the IO transaction.
+ */
+static em64t101_smm_state_save_area_t *smi_apmc_find_state_save(u8 cmd)
+{
+	em64t101_smm_state_save_area_t *state;
+	int node;
+
+	/* Check all nodes looking for the one that issued the IO */
+	for (node = 0; node < CONFIG_MAX_CPUS; node++) {
+		state = smm_get_save_state(node);
+
+		/* Check for Synchronous IO (bit0==1) */
+		if (!(state->io_misc_info & (1 << 0)))
+			continue;
+
+		/* Make sure it was a write (bit4==0) */
+		if (state->io_misc_info & (1 << 4))
+			continue;
+
+		/* Check for APMC IO port */
+		if (((state->io_misc_info >> 16) & 0xff) != APM_CNT)
+			continue;
+
+		/* Check AX against the requested command */
+		if ((state->rax & 0xff) != cmd)
+			continue;
+
+		return state;
+	}
+
+	return NULL;
+}
+
+static void southbridge_smi_gsmi(void)
+{
+#if IS_ENABLED(CONFIG_ELOG_GSMI)
+	u32 *ret, *param;
+	u8 sub_command;
+	em64t101_smm_state_save_area_t *io_smi =
+		smi_apmc_find_state_save(ELOG_GSMI_APM_CNT);
+
+	if (!io_smi)
+		return;
+
+	/* Command and return value in EAX */
+	ret = (u32 *)&io_smi->rax;
+	sub_command = (u8)(*ret >> 8);
+
+	/* Parameter buffer in EBX */
+	param = (u32 *)&io_smi->rbx;
+
+	/* drivers/elog/gsmi.c */
+	*ret = gsmi_exec(sub_command, param);
+#endif
+}
+
+static void finalize(void)
+{
+	static int finalize_done;
+
+	if (finalize_done) {
+		printk(BIOS_DEBUG, "SMM already finalized.\n");
+		return;
+	}
+	finalize_done = 1;
+
+	if (IS_ENABLED(CONFIG_SPI_FLASH_SMM))
+		/* Re-init SPI driver to handle locked BAR */
+		spi_init();
+}
+
+static void southbridge_smi_apmc(void)
+{
+	u8 reg8;
+	em64t101_smm_state_save_area_t *state;
+
+	/* Emulate B2 register as the FADT / Linux expects it */
+
+	reg8 = inb(APM_CNT);
+	switch (reg8) {
+	case APM_CNT_PST_CONTROL:
+		printk(BIOS_DEBUG, "P-state control\n");
+		break;
+	case APM_CNT_ACPI_DISABLE:
+		disable_pm1_control(SCI_EN);
+		printk(BIOS_DEBUG, "SMI#: ACPI disabled.\n");
+		break;
+	case APM_CNT_ACPI_ENABLE:
+		enable_pm1_control(SCI_EN);
+		printk(BIOS_DEBUG, "SMI#: ACPI enabled.\n");
+		break;
+	case APM_CNT_FINALIZE:
+		finalize();
+		break;
+	case APM_CNT_GNVS_UPDATE:
+		if (smm_initialized) {
+			printk(BIOS_DEBUG,
+			       "SMI#: SMM structures already initialized!\n");
+			return;
+		}
+		state = smi_apmc_find_state_save(reg8);
+		if (state) {
+			/* EBX in the state save contains the GNVS pointer */
+			gnvs = (global_nvs_t *)((u32)state->rbx);
+			smm_initialized = 1;
+			printk(BIOS_DEBUG, "SMI#: Setting GNVS to %p\n", gnvs);
+		}
+		break;
+	case ELOG_GSMI_APM_CNT:
+		if (IS_ENABLED(CONFIG_ELOG_GSMI))
+			southbridge_smi_gsmi();
+		break;
+	}
+
+	mainboard_smi_apmc(reg8);
+}
+
+static void southbridge_smi_pm1(void)
+{
+	u16 pm1_sts = clear_pm1_status();
+
+	/*
+	 * While OSPM is not active, poweroff immediately on a power button
+	 * event.
+	 */
+	if (pm1_sts & PWRBTN_STS) {
+		/* power button pressed */
+		if (IS_ENABLED(CONFIG_ELOG_GSMI))
+			elog_add_event(ELOG_TYPE_POWER_BUTTON);
+		disable_pm1_control(-1UL);
+		enable_pm1_control(SLP_EN | (SLP_TYP_S5 << 10));
+	}
+}
+
+static void southbridge_smi_gpe0(void)
+{
+	clear_gpe_status();
+}
+
+void __attribute__((weak))
+mainboard_smi_gpi_handler(const struct gpi_status *sts) { }
+
+static void southbridge_smi_gpi(void)
+{
+	struct gpi_status smi_sts;
+
+	gpi_clear_get_smi_status(&smi_sts);
+	mainboard_smi_gpi_handler(&smi_sts);
+
+	/* Clear again after mainboard handler */
+	gpi_clear_get_smi_status(&smi_sts);
+}
+
+static void southbridge_smi_mc(void)
+{
+	u32 reg32 = inl(ACPI_BASE_ADDRESS + SMI_EN);
+
+	/* Are microcontroller SMIs enabled? */
+	if ((reg32 & MCSMI_EN) == 0)
+		return;
+
+	printk(BIOS_DEBUG, "Microcontroller SMI.\n");
+}
+
+static void southbridge_smi_tco(void)
+{
+	u32 tco_sts = clear_tco_status();
+
+	/* Any TCO event? */
+	if (!tco_sts)
+		return;
+
+	if (tco_sts & (1 << 8)) { /* BIOSWR */
+		u8 bios_cntl = pci_read_config16(PCH_DEV_SPI, BIOS_CNTL);
+
+		if (bios_cntl & 1) {
+			/*
+			 * BWE is RW, so the SMI was caused by a
+			 * write to BWE, not by a write to the BIOS
+			 *
+			 * This is the place where we notice someone
+			 * is trying to tinker with the BIOS. We are
+			 * trying to be nice and just ignore it. A more
+			 * resolute answer would be to power down the
+			 * box.
+			 */
+			printk(BIOS_DEBUG, "Switching back to RO\n");
+			pci_write_config32(PCH_DEV_SPI, BIOS_CNTL,
+					   (bios_cntl & ~1));
+		} /* No else for now? */
+	} else if (tco_sts & (1 << 3)) { /* TIMEOUT */
+		/* Handle TCO timeout */
+		printk(BIOS_DEBUG, "TCO Timeout.\n");
+	}
+}
+
+static void southbridge_smi_periodic(void)
+{
+	u32 reg32 = inl(ACPI_BASE_ADDRESS + SMI_EN);
+
+	/* Are periodic SMIs enabled? */
+	if ((reg32 & PERIODIC_EN) == 0)
+		return;
+
+	printk(BIOS_DEBUG, "Periodic SMI.\n");
+}
+
+static void southbridge_smi_monitor(void)
+{
+#define IOTRAP(x) (trap_sts & (1 << x))
+	u32 trap_sts, trap_cycle;
+	u32 data, mask = 0;
+	int i;
+	/* TRSR - Trap Status Register */
+	pcr_read32(PID_PSTH, R_PCH_PCR_PSTH_TRPST, &trap_sts);
+	/* Clear trap(s) in TRSR */
+	pcr_write8(PID_PSTH, R_PCH_PCR_PSTH_TRPST, trap_sts);
+
+	/* TRPC - Trapped cycle */
+	pcr_read32(PID_PSTH, R_PCH_PCR_PSTH_TRPC, &trap_cycle);
+	for (i = 16; i < 20; i++) {
+		if (trap_cycle & (1 << i))
+			mask |= (0xff << ((i - 16) << 2));
+	}
+
+
+	/* IOTRAP(3) SMI function call */
+	if (IOTRAP(3)) {
+		if (gnvs && gnvs->smif)
+			io_trap_handler(gnvs->smif); /* call function smif */
+		return;
+	}
+
+	/*
+	 * IOTRAP(2) currently unused
+	 * IOTRAP(1) currently unused
+	 */
+
+	/* IOTRAP(0) SMIC */
+	if (IOTRAP(0)) {
+		if (!(trap_cycle & (1 << 24))) { /* It's a write */
+			printk(BIOS_DEBUG, "SMI1 command\n");
+			/* Trapped write data */
+			pcr_read32(PID_PSTH, R_PCH_PCR_PSTH_TRPD, &data);
+			data &= mask;
+		}
+	}
+
+	printk(BIOS_DEBUG, "  trapped io address = 0x%x\n",
+	       trap_cycle & 0xfffc);
+	for (i = 0; i < 4; i++)
+		if (IOTRAP(i))
+			printk(BIOS_DEBUG, "  TRAP = %d\n", i);
+	printk(BIOS_DEBUG, "  AHBE = %x\n", (trap_cycle >> 16) & 0xf);
+	printk(BIOS_DEBUG, "  MASK = 0x%08x\n", mask);
+	printk(BIOS_DEBUG, "  read/write: %s\n",
+	       (trap_cycle & (1 << 24)) ? "read" : "write");
+
+	if (!(trap_cycle & (1 << 24))) {
+		/* Write Cycle */
+		pcr_read32(PID_PSTH, R_PCH_PCR_PSTH_TRPD, &data);
+		printk(BIOS_DEBUG, "  iotrap written data = 0x%08x\n", data);
+	}
+#undef IOTRAP
+}
+
+typedef void (*smi_handler_t)(void);
+
+static smi_handler_t southbridge_smi[SMI_STS_BITS] = {
+	[SMI_ON_SLP_EN_STS_BIT] = southbridge_smi_sleep,
+	[APM_STS_BIT] = southbridge_smi_apmc,
+	[PM1_STS_BIT] = southbridge_smi_pm1,
+	[GPE0_STS_BIT] = southbridge_smi_gpe0,
+	[GPIO_STS_BIT] = southbridge_smi_gpi,
+	[MCSMI_STS_BIT] = southbridge_smi_mc,
+	[TCO_STS_BIT] = southbridge_smi_tco,
+	[PERIODIC_STS_BIT] = southbridge_smi_periodic,
+	[MONITOR_STS_BIT] = southbridge_smi_monitor,
+};
+
+/*
+ * Interrupt handler for SMI#
+ */
+void southbridge_smi_handler(void)
+{
+	int i;
+	u32 smi_sts;
+
+	/*
+	 * We need to clear the SMI status registers, or we won't see what's
+	 * happening in the following calls.
+	 */
+	smi_sts = clear_smi_status();
+
+	/* Call SMI sub handler for each of the status bits */
+	for (i = 0; i < ARRAY_SIZE(southbridge_smi); i++) {
+		if (smi_sts & (1 << i)) {
+			if (southbridge_smi[i]) {
+				southbridge_smi[i]();
+			} else {
+				printk(BIOS_DEBUG,
+				    "SMI_STS[%d] occurred, but no handler available.\n",
+				    i);
+			}
+		}
+	}
+}
diff --git a/src/soc/intel/kabylake/smmrelocate.c b/src/soc/intel/kabylake/smmrelocate.c
new file mode 100644
index 0000000..ae59c4f
--- /dev/null
+++ b/src/soc/intel/kabylake/smmrelocate.c
@@ -0,0 +1,317 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * 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 <types.h>
+#include <string.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <cpu/cpu.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 <cpu/x86/smm.h>
+#include <console/console.h>
+#include <soc/cpu.h>
+#include <soc/msr.h>
+#include <soc/pci_devs.h>
+#include <soc/smm.h>
+#include <soc/systemagent.h>
+#include "chip.h"
+
+/* This gets filled in and used during relocation. */
+static struct smm_relocation_params smm_reloc_params;
+
+static inline void write_smrr(struct smm_relocation_params *relo_params)
+{
+	printk(BIOS_DEBUG, "Writing SMRR. base = 0x%08x, mask=0x%08x\n",
+	       relo_params->smrr_base.lo, relo_params->smrr_mask.lo);
+	wrmsr(SMRR_PHYS_BASE, relo_params->smrr_base);
+	wrmsr(SMRR_PHYS_MASK, relo_params->smrr_mask);
+}
+
+static inline void write_uncore_emrr(struct smm_relocation_params *relo_params)
+{
+	printk(BIOS_DEBUG,
+	       "Writing UNCORE_EMRR. base = 0x%08x, mask=0x%08x\n",
+	       relo_params->uncore_emrr_base.lo,
+	       relo_params->uncore_emrr_mask.lo);
+	wrmsr(UNCORE_PRMRR_PHYS_BASE_MSR, relo_params->uncore_emrr_base);
+	wrmsr(UNCORE_PRMRR_PHYS_MASK_MSR, relo_params->uncore_emrr_mask);
+}
+
+static void update_save_state(int cpu, uintptr_t curr_smbase,
+				uintptr_t staggered_smbase,
+				struct smm_relocation_params *relo_params)
+{
+	u32 smbase;
+	u32 iedbase;
+
+	/*
+	 * The relocated handler runs with all CPUs concurrently. Therefore
+	 * stagger the entry points adjusting SMBASE downwards by save state
+	 * size * CPU num.
+	 */
+	smbase = staggered_smbase;
+	iedbase = relo_params->ied_base;
+
+	printk(BIOS_DEBUG, "New SMBASE=0x%08x IEDBASE=0x%08x\n",
+	       smbase, iedbase);
+
+	/*
+	 * All threads need to set IEDBASE and SMBASE to the relocated
+	 * handler region. However, the save state location depends on the
+	 * smm_save_state_in_msrs field in the relocation parameters. If
+	 * smm_save_state_in_msrs is non-zero then the CPUs are relocating
+	 * the SMM handler in parallel, and each CPUs save state area is
+	 * located in their respective MSR space. If smm_save_state_in_msrs
+	 * is zero then the SMM relocation is happening serially so the
+	 * save state is at the same default location for all CPUs.
+	 */
+	if (relo_params->smm_save_state_in_msrs) {
+		msr_t smbase_msr;
+		msr_t iedbase_msr;
+
+		smbase_msr.lo = smbase;
+		smbase_msr.hi = 0;
+
+		/*
+		 * According the BWG the IEDBASE MSR is in bits 63:32. It's
+		 * not clear why it differs from the SMBASE MSR.
+		 */
+		iedbase_msr.lo = 0;
+		iedbase_msr.hi = iedbase;
+
+		wrmsr(SMBASE_MSR, smbase_msr);
+		wrmsr(IEDBASE_MSR, iedbase_msr);
+	} else {
+		em64t101_smm_state_save_area_t *save_state;
+
+		save_state = (void *)(curr_smbase + SMM_DEFAULT_SIZE -
+				      sizeof(*save_state));
+
+		save_state->smbase = smbase;
+		save_state->iedbase = iedbase;
+	}
+}
+
+/* Returns 1 if SMM MSR save state was set. */
+static int bsp_setup_msr_save_state(struct smm_relocation_params *relo_params)
+{
+	msr_t smm_mca_cap;
+
+	smm_mca_cap = rdmsr(SMM_MCA_CAP_MSR);
+	if (smm_mca_cap.hi & SMM_CPU_SVRSTR_MASK) {
+		msr_t smm_feature_control;
+
+		smm_feature_control = rdmsr(SMM_FEATURE_CONTROL_MSR);
+		smm_feature_control.hi = 0;
+		smm_feature_control.lo |= SMM_CPU_SAVE_EN;
+		wrmsr(SMM_FEATURE_CONTROL_MSR, smm_feature_control);
+		relo_params->smm_save_state_in_msrs = 1;
+	}
+	return relo_params->smm_save_state_in_msrs;
+}
+
+/*
+ * The relocation work is actually performed in SMM context, but the code
+ * resides in the ramstage module. This occurs by trampolining from the default
+ * SMRAM entry point to here.
+ */
+void smm_relocation_handler(int cpu, uintptr_t curr_smbase,
+				uintptr_t staggered_smbase)
+{
+	msr_t mtrr_cap;
+	struct smm_relocation_params *relo_params = &smm_reloc_params;
+
+	printk(BIOS_DEBUG, "In relocation handler: cpu %d\n", cpu);
+
+	/*
+	 * Determine if the processor supports saving state in MSRs. If so,
+	 * enable it before the non-BSPs run so that SMM relocation can occur
+	 * in parallel in the non-BSP CPUs.
+	 */
+	if (cpu == 0) {
+		/*
+		 * If smm_save_state_in_msrs is 1 then that means this is the
+		 * 2nd time through the relocation handler for the BSP.
+		 * Parallel SMM handler relocation is taking place. However,
+		 * it is desired to access other CPUs save state in the real
+		 * SMM handler. Therefore, disable the SMM save state in MSRs
+		 * feature.
+		 */
+		if (relo_params->smm_save_state_in_msrs) {
+			msr_t smm_feature_control;
+
+			smm_feature_control = rdmsr(SMM_FEATURE_CONTROL_MSR);
+			smm_feature_control.lo &= ~SMM_CPU_SAVE_EN;
+			wrmsr(SMM_FEATURE_CONTROL_MSR, smm_feature_control);
+		} else if (bsp_setup_msr_save_state(relo_params))
+			/*
+			 * Just return from relocation handler if MSR save
+			 * state is enabled. In that case the BSP will come
+			 * back into the relocation handler to setup the new
+			 * SMBASE as well disabling SMM save state in MSRs.
+			 */
+			return;
+	}
+
+	/* Make appropriate changes to the save state map. */
+	update_save_state(cpu, curr_smbase, staggered_smbase, relo_params);
+
+	/* Write EMRR and SMRR MSRs based on indicated support. */
+	mtrr_cap = rdmsr(MTRR_CAP_MSR);
+	if (mtrr_cap.lo & SMRR_SUPPORTED)
+		write_smrr(relo_params);
+}
+
+static void fill_in_relocation_params(device_t dev,
+				      struct smm_relocation_params *params)
+{
+	void *handler_base;
+	size_t handler_size;
+	void *ied_base;
+	size_t ied_size;
+	void *tseg_base;
+	size_t tseg_size;
+	u32 emrr_base;
+	u32 emrr_size;
+	int phys_bits;
+	/* All range registers are aligned to 4KiB */
+	const u32 rmask = ~((1 << 12) - 1);
+
+	/*
+	 * Some of the range registers are dependent on the number of physical
+	 * address bits supported.
+	 */
+	phys_bits = cpuid_eax(0x80000008) & 0xff;
+
+	smm_region(&tseg_base, &tseg_size);
+	smm_subregion(SMM_SUBREGION_HANDLER, &handler_base, &handler_size);
+	smm_subregion(SMM_SUBREGION_CHIPSET, &ied_base, &ied_size);
+
+	params->smram_size = handler_size;
+	params->smram_base = (uintptr_t)handler_base;
+
+	params->ied_base = (uintptr_t)ied_base;
+	params->ied_size = ied_size;
+
+	/* SMRR has 32-bits of valid address aligned to 4KiB. */
+	params->smrr_base.lo = (params->smram_base & rmask) | MTRR_TYPE_WRBACK;
+	params->smrr_base.hi = 0;
+	params->smrr_mask.lo = (~(tseg_size - 1) & rmask) | MTRR_PHYS_MASK_VALID;
+	params->smrr_mask.hi = 0;
+
+	/* The EMRR and UNCORE_EMRR are at IEDBASE + 2MiB */
+	emrr_base = (params->ied_base + (2 << 20)) & rmask;
+	emrr_size = params->ied_size - (2 << 20);
+
+	/*
+	 * EMRR has 46 bits of valid address aligned to 4KiB. It's dependent
+	 * on the number of physical address bits supported.
+	 */
+	params->emrr_base.lo = emrr_base | MTRR_TYPE_WRBACK;
+	params->emrr_base.hi = 0;
+	params->emrr_mask.lo = (~(emrr_size - 1) & rmask) | MTRR_PHYS_MASK_VALID;
+	params->emrr_mask.hi = (1 << (phys_bits - 32)) - 1;
+
+	/* UNCORE_EMRR has 39 bits of valid address aligned to 4KiB. */
+	params->uncore_emrr_base.lo = emrr_base;
+	params->uncore_emrr_base.hi = 0;
+	params->uncore_emrr_mask.lo = (~(emrr_size - 1) & rmask) |
+					MTRR_PHYS_MASK_VALID;
+	params->uncore_emrr_mask.hi = (1 << (39 - 32)) - 1;
+}
+
+static void setup_ied_area(struct smm_relocation_params *params)
+{
+	char *ied_base;
+
+	struct ied_header ied = {
+		.signature = "INTEL RSVD",
+		.size = params->ied_size,
+		.reserved = {0},
+	};
+
+	ied_base = (void *)params->ied_base;
+
+	printk(BIOS_DEBUG, "IED base = 0x%08x\n", params->ied_base);
+	printk(BIOS_DEBUG, "IED size = 0x%08x\n", params->ied_size);
+
+	/* Place IED header at IEDBASE. */
+	memcpy(ied_base, &ied, sizeof(ied));
+
+	/* Zero out 32KiB at IEDBASE + 1MiB */
+	memset(ied_base + (1 << 20), 0, (32 << 10));
+}
+
+void smm_info(uintptr_t *perm_smbase, size_t *perm_smsize,
+				size_t *smm_save_state_size)
+{
+	device_t dev = SA_DEV_ROOT;
+
+	printk(BIOS_DEBUG, "Setting up SMI for CPU\n");
+
+	fill_in_relocation_params(dev, &smm_reloc_params);
+
+	if (smm_reloc_params.ied_size)
+		setup_ied_area(&smm_reloc_params);
+
+	*perm_smbase = smm_reloc_params.smram_base;
+	*perm_smsize = smm_reloc_params.smram_size;
+	*smm_save_state_size = sizeof(em64t101_smm_state_save_area_t);
+}
+
+void smm_initialize(void)
+{
+	/* Clear the SMM state in the southbridge. */
+	southbridge_smm_clear_state();
+
+	/*
+	 * Run the relocation handler for on the BSP to check and set up
+	 * parallel SMM relocation.
+	 */
+	smm_initiate_relocation();
+
+	if (smm_reloc_params.smm_save_state_in_msrs)
+		printk(BIOS_DEBUG, "Doing parallel SMM relocation.\n");
+}
+
+void smm_relocate(void)
+{
+	/*
+	 * If smm_save_state_in_msrs is non-zero then parallel SMM relocation
+	 * shall take place. Run the relocation handler a second time on the
+	 * BSP to do * the final move. For APs, a relocation handler always
+	 * needs to be run.
+	 */
+	if (smm_reloc_params.smm_save_state_in_msrs)
+		smm_initiate_relocation_parallel();
+	else if (!boot_cpu())
+		smm_initiate_relocation();
+}
+
+void smm_lock(void)
+{
+	/*
+	 * LOCK the SMM memory window and enable normal SMM.
+	 * After running this function, only a full reset can
+	 * make the SMM registers writable again.
+	 */
+	printk(BIOS_DEBUG, "Locking SMM.\n");
+	pci_write_config8(SA_DEV_ROOT, SMRAM, D_LCK | G_SMRAME | C_BASE_SEG);
+}
diff --git a/src/soc/intel/kabylake/systemagent.c b/src/soc/intel/kabylake/systemagent.c
new file mode 100644
index 0000000..f4f7150
--- /dev/null
+++ b/src/soc/intel/kabylake/systemagent.c
@@ -0,0 +1,424 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ * Copyright (C) 2014 Google Inc.
+ * 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 <console/console.h>
+#include <arch/acpi.h>
+#include <arch/io.h>
+#include <stdint.h>
+#include <delay.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <stdlib.h>
+#include <string.h>
+#include <cbmem.h>
+#include <romstage_handoff.h>
+#include <vendorcode/google/chromeos/chromeos.h>
+#include <soc/cpu.h>
+#include <soc/iomap.h>
+#include <soc/pci_devs.h>
+#include <soc/ramstage.h>
+#include <soc/systemagent.h>
+
+u8 systemagent_revision(void)
+{
+	return pci_read_config8(SA_DEV_ROOT, PCI_REVISION_ID);
+}
+
+static int get_pcie_bar(device_t dev, unsigned int index, u32 *base, u32 *len)
+{
+	u32 pciexbar_reg;
+
+	*base = 0;
+	*len = 0;
+
+	pciexbar_reg = pci_read_config32(dev, index);
+
+	if (!(pciexbar_reg & (1 << 0)))
+		return 0;
+
+	switch ((pciexbar_reg >> 1) & 3) {
+	case 0: /* 256MB */
+		*base = pciexbar_reg & ((1 << 31)|(1 << 30)|(1 << 29)|
+					(1 << 28));
+		*len = 256 * 1024 * 1024;
+		return 1;
+	case 1: /* 128M */
+		*base = pciexbar_reg & ((1 << 31)|(1 << 30)|(1 << 29)|
+					(1 << 28)|(1 << 27));
+		*len = 128 * 1024 * 1024;
+		return 1;
+	case 2: /* 64M */
+		*base = pciexbar_reg & ((1 << 31)|(1 << 30)|(1 << 29)|
+					(1 << 28)|(1 << 27)|(1 << 26));
+		*len = 64 * 1024 * 1024;
+		return 1;
+	}
+
+	return 0;
+}
+
+static int get_bar(device_t dev, unsigned int index, u32 *base, u32 *len)
+{
+	u32 bar;
+
+	bar = pci_read_config32(dev, index);
+
+	/* If not enabled don't report it. */
+	if (!(bar & 0x1))
+		return 0;
+
+	/* Knock down the enable bit. */
+	*base = bar & ~1;
+
+	return 1;
+}
+
+/*
+ * There are special BARs that actually are programmed in the MCHBAR. These
+ * Intel special features, but they do consume resources that need to be
+ * accounted for.
+ */
+static int get_bar_in_mchbar(device_t dev, unsigned int index, u32 *base,
+			     u32 *len)
+{
+	u32 bar;
+
+	bar = MCHBAR32(index);
+
+	/* If not enabled don't report it. */
+	if (!(bar & 0x1))
+		return 0;
+
+	/* Knock down the enable bit. */
+	*base = bar & ~1;
+
+	return 1;
+}
+
+struct fixed_mmio_descriptor {
+	unsigned int index;
+	u32 size;
+	int (*get_resource)(device_t dev, unsigned int index,
+			    u32 *base, u32 *size);
+	const char *description;
+};
+
+struct fixed_mmio_descriptor mc_fixed_resources[] = {
+	{ PCIEXBAR, 0,               get_pcie_bar,      "PCIEXBAR" },
+	{ MCHBAR,   MCH_BASE_SIZE,   get_bar,           "MCHBAR"   },
+	{ DMIBAR,   DMI_BASE_SIZE,   get_bar,           "DMIBAR"   },
+	{ EPBAR,    EP_BASE_SIZE,    get_bar,           "EPBAR"    },
+	{ GDXCBAR,  GDXC_BASE_SIZE,  get_bar_in_mchbar, "GDXCBAR"  },
+	{ EDRAMBAR, EDRAM_BASE_SIZE, get_bar_in_mchbar, "EDRAMBAR" },
+};
+
+/*
+ * Add all known fixed MMIO ranges that hang off the host bridge/memory
+ * controller device.
+ */
+static void mc_add_fixed_mmio_resources(device_t dev)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(mc_fixed_resources); i++) {
+		u32 base;
+		u32 size;
+		struct resource *resource;
+		unsigned int index;
+
+		size = mc_fixed_resources[i].size;
+		index = mc_fixed_resources[i].index;
+		if (!mc_fixed_resources[i].get_resource(dev, index,
+							&base, &size))
+			continue;
+
+		resource = new_resource(dev, mc_fixed_resources[i].index);
+		resource->flags = IORESOURCE_MEM | IORESOURCE_FIXED |
+				  IORESOURCE_STORED | IORESOURCE_RESERVE |
+				  IORESOURCE_ASSIGNED;
+		resource->base = base;
+		resource->size = size;
+		printk(BIOS_DEBUG, "%s: Adding %s @ %x 0x%08lx-0x%08lx.\n",
+		       __func__, mc_fixed_resources[i].description, index,
+		       (unsigned long)base, (unsigned long)(base + size - 1));
+	}
+}
+
+struct map_entry {
+	int reg;
+	int is_64_bit;
+	int is_limit;
+	const char *description;
+};
+
+static void read_map_entry(device_t dev, struct map_entry *entry,
+			   uint64_t *result)
+{
+	uint64_t value;
+	uint64_t mask;
+
+	/* All registers are on a 1MiB granularity. */
+	mask = ((1ULL<<20)-1);
+	mask = ~mask;
+
+	value = 0;
+
+	if (entry->is_64_bit) {
+		value = pci_read_config32(dev, entry->reg + 4);
+		value <<= 32;
+	}
+
+	value |= (uint64_t) pci_read_config32(dev, entry->reg);
+	value &= mask;
+
+	if (entry->is_limit)
+		value |= ~mask;
+
+	*result = value;
+}
+
+#define MAP_ENTRY(reg_, is_64_, is_limit_, desc_) \
+	{ \
+		.reg = reg_,           \
+		.is_64_bit = is_64_,   \
+		.is_limit = is_limit_, \
+		.description = desc_,  \
+	}
+
+#define MAP_ENTRY_BASE_64(reg_, desc_) \
+	MAP_ENTRY(reg_, 1, 0, desc_)
+#define MAP_ENTRY_LIMIT_64(reg_, desc_) \
+	MAP_ENTRY(reg_, 1, 1, desc_)
+#define MAP_ENTRY_BASE_32(reg_, desc_) \
+	MAP_ENTRY(reg_, 0, 0, desc_)
+
+enum {
+	TOM_REG,
+	TOUUD_REG,
+	MESEG_BASE_REG,
+	MESEG_LIMIT_REG,
+	REMAP_BASE_REG,
+	REMAP_LIMIT_REG,
+	TOLUD_REG,
+	BGSM_REG,
+	BDSM_REG,
+	TSEG_REG,
+	/* Must be last. */
+	NUM_MAP_ENTRIES
+};
+
+static struct map_entry memory_map[NUM_MAP_ENTRIES] = {
+	[TOM_REG] = MAP_ENTRY_BASE_64(TOM, "TOM"),
+	[TOUUD_REG] = MAP_ENTRY_BASE_64(TOUUD, "TOUUD"),
+	[MESEG_BASE_REG] = MAP_ENTRY_BASE_64(MESEG_BASE, "MESEG_BASE"),
+	[MESEG_LIMIT_REG] = MAP_ENTRY_LIMIT_64(MESEG_LIMIT, "MESEG_LIMIT"),
+	[REMAP_BASE_REG] = MAP_ENTRY_BASE_64(REMAPBASE, "REMAP_BASE"),
+	[REMAP_LIMIT_REG] = MAP_ENTRY_LIMIT_64(REMAPLIMIT, "REMAP_LIMIT"),
+	[TOLUD_REG] = MAP_ENTRY_BASE_32(TOLUD, "TOLUD"),
+	[BDSM_REG] = MAP_ENTRY_BASE_32(BDSM, "BDSM"),
+	[BGSM_REG] = MAP_ENTRY_BASE_32(BGSM, "BGSM"),
+	[TSEG_REG] = MAP_ENTRY_BASE_32(TSEG, "TESGMB"),
+};
+
+static void mc_read_map_entries(device_t dev, uint64_t *values)
+{
+	int i;
+	for (i = 0; i < NUM_MAP_ENTRIES; i++)
+		read_map_entry(dev, &memory_map[i], &values[i]);
+}
+
+static void mc_report_map_entries(device_t dev, uint64_t *values)
+{
+	int i;
+	for (i = 0; i < NUM_MAP_ENTRIES; i++) {
+		printk(BIOS_DEBUG, "MC MAP: %s: 0x%llx\n",
+		       memory_map[i].description, values[i]);
+	}
+	/* One can validate the BDSM and BGSM against the GGC. */
+	printk(BIOS_DEBUG, "MC MAP: GGC: 0x%x\n", pci_read_config16(dev, GGC));
+}
+
+static void mc_add_dram_resources(device_t dev)
+{
+	unsigned long base_k, size_k;
+	unsigned long touud_k;
+	unsigned long index;
+	struct resource *resource;
+	uint64_t mc_values[NUM_MAP_ENTRIES];
+	unsigned long dpr_size = 0;
+	u32 dpr_reg;
+
+	/* Read in the MAP registers and report their values. */
+	mc_read_map_entries(dev, &mc_values[0]);
+	mc_report_map_entries(dev, &mc_values[0]);
+
+	/*
+	 * DMA Protected Range can be reserved below TSEG for PCODE patch
+	 * or TXT/BootGuard related data.  Rather than report a base address
+	 * the DPR register reports the TOP of the region, which is the same
+	 * as TSEG base.  The region size is reported in MiB in bits 11:4.
+	 */
+	dpr_reg = pci_read_config32(SA_DEV_ROOT, DPR);
+	if (dpr_reg & DPR_EPM) {
+		dpr_size = (dpr_reg & DPR_SIZE_MASK) << 16;
+		printk(BIOS_INFO, "DPR SIZE: 0x%lx\n", dpr_size);
+	}
+
+	/*
+	 * These are the host memory ranges that should be added:
+	 * - 0 -> 0xa0000: cacheable
+	 * - 0xc0000 -> top_of_ram : cacheable
+	 * - top_of_ram -> TSEG - DPR: uncacheable
+	 * - TESG - DPR -> BGSM: cacheable with standard MTRRs and reserved
+	 * - BGSM -> TOLUD: not cacheable with standard MTRRs and reserved
+	 * - 4GiB -> TOUUD: cacheable
+	 *
+	 * The default SMRAM space is reserved so that the range doesn't
+	 * have to be saved during S3 Resume. Once marked reserved the OS
+	 * cannot use the memory. This is a bit of an odd place to reserve
+	 * the region, but the CPU devices don't have dev_ops->read_resources()
+	 * called on them.
+	 *
+	 * The range 0xa0000 -> 0xc0000 does not have any resources
+	 * associated with it to handle legacy VGA memory. If this range
+	 * is not omitted the mtrr code will setup the area as cacheable
+	 * causing VGA access to not work.
+	 *
+	 * The TSEG region is mapped as cacheable so that one can perform
+	 * SMRAM relocation faster. Once the SMRR is enabled the SMRR takes
+	 * precedence over the existing MTRRs covering this region.
+	 *
+	 * It should be noted that cacheable entry types need to be added in
+	 * order. The reason is that the current MTRR code assumes this and
+	 * falls over itself if it isn't.
+	 *
+	 * The resource index starts low and should not meet or exceed
+	 * PCI_BASE_ADDRESS_0.
+	 */
+	index = 0;
+
+	/* 0 - > 0xa0000 */
+	base_k = 0;
+	size_k = (0xa0000 >> 10) - base_k;
+	ram_resource(dev, index++, base_k, size_k);
+
+	/* 0xc0000 -> top_of_ram */
+	base_k = 0xc0000 >> 10;
+	size_k = (top_of_32bit_ram() >> 10) - base_k;
+	ram_resource(dev, index++, base_k, size_k);
+
+	/* top_of_ram -> TSEG - DPR */
+	resource = new_resource(dev, index++);
+	resource->base = top_of_32bit_ram();
+	resource->size = mc_values[TSEG_REG] - dpr_size - resource->base;
+	resource->flags = IORESOURCE_MEM | IORESOURCE_FIXED |
+			  IORESOURCE_STORED | IORESOURCE_RESERVE |
+			  IORESOURCE_ASSIGNED;
+
+	/* TSEG - DPR -> BGSM */
+	resource = new_resource(dev, index++);
+	resource->base = mc_values[TSEG_REG] - dpr_size;
+	resource->size = mc_values[BGSM_REG] - resource->base;
+	resource->flags = IORESOURCE_MEM | IORESOURCE_FIXED |
+			  IORESOURCE_STORED | IORESOURCE_RESERVE |
+			  IORESOURCE_ASSIGNED | IORESOURCE_CACHEABLE;
+
+	/* BGSM -> TOLUD */
+	resource = new_resource(dev, index++);
+	resource->base = mc_values[BGSM_REG];
+	resource->size = mc_values[TOLUD_REG] - resource->base;
+	resource->flags = IORESOURCE_MEM | IORESOURCE_FIXED |
+			  IORESOURCE_STORED | IORESOURCE_RESERVE |
+			  IORESOURCE_ASSIGNED;
+
+	/* 4GiB -> TOUUD */
+	base_k = 4096 * 1024; /* 4GiB */
+	touud_k = mc_values[TOUUD_REG] >> 10;
+	size_k = touud_k - base_k;
+	if (touud_k > base_k)
+		ram_resource(dev, index++, base_k, size_k);
+
+	/*
+	 * Reserve everything between A segment and 1MB:
+	 *
+	 * 0xa0000 - 0xbffff: legacy VGA
+	 * 0xc0000 - 0xfffff: RAM
+	 */
+	mmio_resource(dev, index++, (0xa0000 >> 10), (0xc0000 - 0xa0000) >> 10);
+	reserved_ram_resource(dev, index++, (0xc0000 >> 10),
+			      (0x100000 - 0xc0000) >> 10);
+
+	chromeos_reserve_ram_oops(dev, index++);
+}
+
+static void systemagent_read_resources(device_t dev)
+{
+	/* Read standard PCI resources. */
+	pci_dev_read_resources(dev);
+
+	/* Add all fixed MMIO resources. */
+	mc_add_fixed_mmio_resources(dev);
+
+	/* Calculate and add DRAM resources. */
+	mc_add_dram_resources(dev);
+}
+
+static void systemagent_init(struct device *dev)
+{
+	u8 bios_reset_cpl, pair;
+
+	/* Enable Power Aware Interrupt Routing */
+	pair = MCHBAR8(MCH_PAIR);
+	pair &= ~0x7;	/* Clear 2:0 */
+	pair |= 0x4;	/* Fixed Priority */
+	MCHBAR8(MCH_PAIR) = pair;
+
+	/*
+	 * Set bits 0+1 of BIOS_RESET_CPL to indicate to the CPU
+	 * that BIOS has initialized memory and power management
+	 */
+	bios_reset_cpl = MCHBAR8(BIOS_RESET_CPL);
+	bios_reset_cpl |= 3;
+	MCHBAR8(BIOS_RESET_CPL) = bios_reset_cpl;
+	printk(BIOS_DEBUG, "Set BIOS_RESET_CPL\n");
+
+	/* Configure turbo power limits 1ms after reset complete bit */
+	mdelay(1);
+	set_power_limits(28);
+}
+
+static struct device_operations systemagent_ops = {
+	.read_resources   = &systemagent_read_resources,
+	.set_resources    = &pci_dev_set_resources,
+	.enable_resources = &pci_dev_enable_resources,
+	.init             = &systemagent_init,
+	.ops_pci          = &soc_pci_ops,
+};
+
+static const unsigned short systemagent_ids[] = {
+	MCH_KABYLAKE_ID_U,
+	MCH_KABYLAKE_ID_Y,
+	MCH_KABYLAKE_ID_ULX,
+	0
+};
+
+static const struct pci_driver systemagent_driver __pci_driver = {
+	.ops     = &systemagent_ops,
+	.vendor  = PCI_VENDOR_ID_INTEL,
+	.devices = systemagent_ids
+};
diff --git a/src/soc/intel/kabylake/tsc_freq.c b/src/soc/intel/kabylake/tsc_freq.c
new file mode 100644
index 0000000..81ba8ba
--- /dev/null
+++ b/src/soc/intel/kabylake/tsc_freq.c
@@ -0,0 +1,29 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * 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 <stdint.h>
+#include <cpu/x86/msr.h>
+#include <cpu/x86/tsc.h>
+#include <soc/cpu.h>
+#include <soc/msr.h>
+
+unsigned long tsc_freq_mhz(void)
+{
+	msr_t platform_info;
+
+	platform_info = rdmsr(MSR_PLATFORM_INFO);
+	return CPU_BCLK * ((platform_info.lo >> 8) & 0xff);
+}
diff --git a/src/soc/intel/kabylake/uart.c b/src/soc/intel/kabylake/uart.c
new file mode 100644
index 0000000..4727a84
--- /dev/null
+++ b/src/soc/intel/kabylake/uart.c
@@ -0,0 +1,63 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 Google Inc.
+ * 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 <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <stdlib.h>
+#include <soc/iomap.h>
+#include <soc/pci_devs.h>
+#include <soc/ramstage.h>
+
+static int pch_uart_is_debug(struct device *dev)
+{
+	return dev->path.pci.devfn == PCH_DEVFN_UART2;
+}
+
+static void pch_uart_read_resources(struct device *dev)
+{
+	pci_dev_read_resources(dev);
+
+	/* Set the configured UART base address for the debug port */
+	if (IS_ENABLED(CONFIG_UART_DEBUG) && pch_uart_is_debug(dev)) {
+		struct resource *res = find_resource(dev, PCI_BASE_ADDRESS_0);
+		/* Need to set the base and size for the resource allocator. */
+		res->base = UART_DEBUG_BASE_ADDRESS;
+		res->size = UART_DEBUG_BASE_SIZE;
+		res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED |
+			IORESOURCE_FIXED;
+	}
+}
+
+static struct device_operations device_ops = {
+	.read_resources		= &pch_uart_read_resources,
+	.set_resources		= &pci_dev_set_resources,
+	.enable_resources	= &pci_dev_enable_resources,
+	.ops_pci		= &soc_pci_ops,
+};
+
+static const unsigned short pci_device_ids[] = {
+	0x9d27, /* UART0 */
+	0x9d28, /* UART1 */
+	0x9d66, /* UART2 */
+	0
+};
+
+static const struct pci_driver pch_uart __pci_driver = {
+	.ops	 = &device_ops,
+	.vendor	 = PCI_VENDOR_ID_INTEL,
+	.devices = pci_device_ids,
+};
diff --git a/src/soc/intel/kabylake/uart_debug.c b/src/soc/intel/kabylake/uart_debug.c
new file mode 100644
index 0000000..f3d576b
--- /dev/null
+++ b/src/soc/intel/kabylake/uart_debug.c
@@ -0,0 +1,26 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2015 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.
+ */
+
+#include <stddef.h>
+#include <console/uart.h>
+#include <soc/iomap.h>
+#include <soc/serialio.h>
+
+uintptr_t uart_platform_base(int idx)
+{
+	/* Same base address for all debug port usage. In reality UART2
+	 * is currently only supported. */
+	return UART_DEBUG_BASE_ADDRESS;
+}
diff --git a/src/soc/intel/kabylake/vr_config.c b/src/soc/intel/kabylake/vr_config.c
new file mode 100644
index 0000000..40223e3
--- /dev/null
+++ b/src/soc/intel/kabylake/vr_config.c
@@ -0,0 +1,107 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2015 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.
+ *
+ */
+
+#include <soc/vr_config.h>
+
+/* Default values for domain configuration. PSI3 and PSI4 are disabled. */
+static const struct vr_config default_configs[NUM_VR_DOMAINS] = {
+	[VR_SYSTEM_AGENT] = {
+		.vr_config_enable = 1,
+		.psi1threshold = VR_CFG_AMP(20),
+		.psi2threshold = VR_CFG_AMP(4),
+		.psi3threshold = VR_CFG_AMP(1),
+		.psi3enable = 0,
+		.psi4enable = 0,
+		.imon_slope = 0x0,
+		.imon_offset = 0x0,
+		.icc_max = VR_CFG_AMP(7),
+		.voltage_limit = 1520,
+	},
+	[VR_IA_CORE] = {
+		.vr_config_enable = 1,
+		.psi1threshold = VR_CFG_AMP(20),
+		.psi2threshold = VR_CFG_AMP(5),
+		.psi3threshold = VR_CFG_AMP(1),
+		.psi3enable = 0,
+		.psi4enable = 0,
+		.imon_slope = 0x0,
+		.imon_offset = 0x0,
+		.icc_max = VR_CFG_AMP(34),
+		.voltage_limit = 1520,
+	},
+	[VR_RING] = {
+		.vr_config_enable = 1,
+		.psi1threshold = VR_CFG_AMP(20),
+		.psi2threshold = VR_CFG_AMP(5),
+		.psi3threshold = VR_CFG_AMP(1),
+		.psi3enable = 0,
+		.psi4enable = 0,
+		.imon_slope = 0x0,
+		.imon_offset = 0x0,
+		.icc_max = VR_CFG_AMP(34),
+		.voltage_limit = 1520,
+	},
+	[VR_GT_UNSLICED] = {
+		.vr_config_enable = 1,
+		.psi1threshold = VR_CFG_AMP(20),
+		.psi2threshold = VR_CFG_AMP(5),
+		.psi3threshold = VR_CFG_AMP(1),
+		.psi3enable = 0,
+		.psi4enable = 0,
+		.imon_slope = 0x0,
+		.imon_offset = 0x0,
+		.icc_max = VR_CFG_AMP(35),
+		.voltage_limit = 1520,
+	},
+	[VR_GT_SLICED] = {
+		.vr_config_enable = 1,
+		.psi1threshold = VR_CFG_AMP(20),
+		.psi2threshold = VR_CFG_AMP(5),
+		.psi3threshold = VR_CFG_AMP(1),
+		.psi3enable = 0,
+		.psi4enable = 0,
+		.imon_slope = 0x0,
+		.imon_offset = 0x0,
+		.icc_max = VR_CFG_AMP(35),
+		.voltage_limit = 1520,
+	},
+};
+
+void fill_vr_domain_config(SILICON_INIT_UPD *params, int domain,
+				const struct vr_config *chip_cfg)
+{
+	const struct vr_config *cfg;
+
+	if (domain < 0 || domain >= NUM_VR_DOMAINS)
+		return;
+
+	/* Use device tree override if requested. */
+	if (chip_cfg->vr_config_enable)
+		cfg = chip_cfg;
+	else
+		cfg = &default_configs[domain];
+
+	params->VrConfigEnable[domain] = cfg->vr_config_enable;
+	params->Psi1Threshold[domain] = cfg->psi1threshold;
+	params->Psi2Threshold[domain] = cfg->psi2threshold;
+	params->Psi3Threshold[domain] = cfg->psi3threshold;
+	params->Psi3Enable[domain] = cfg->psi3enable;
+	params->Psi4Enable[domain] = cfg->psi4enable;
+	params->ImonSlope[domain] = cfg->imon_slope;
+	params->ImonOffset[domain] = cfg->imon_offset;
+	params->IccMax[domain] = cfg->icc_max;
+	params->VrVoltageLimit[domain] = cfg->voltage_limit;
+}
diff --git a/src/soc/intel/kabylake/xhci.c b/src/soc/intel/kabylake/xhci.c
new file mode 100644
index 0000000..1dd91eb
--- /dev/null
+++ b/src/soc/intel/kabylake/xhci.c
@@ -0,0 +1,43 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * 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 <console/console.h>
+#include <delay.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <arch/io.h>
+#include <soc/ramstage.h>
+#include <soc/xhci.h>
+#include <soc/cpu.h>
+
+static struct device_operations usb_xhci_ops = {
+	.read_resources		= &pci_dev_read_resources,
+	.set_resources		= &pci_dev_set_resources,
+	.enable_resources	= &pci_dev_enable_resources,
+	.ops_pci		= &soc_pci_ops,
+};
+
+static const unsigned short pci_device_ids[] = {
+	0x9d2f, /* SunRisePoint LP */
+	0
+};
+
+static const struct pci_driver pch_usb_xhci __pci_driver = {
+	.ops	 = &usb_xhci_ops,
+	.vendor	 = PCI_VENDOR_ID_INTEL,
+	.devices = pci_device_ids,
+};



More information about the coreboot-gerrit mailing list