soc/intel/denverton_ns: Add support for Intel Atom C3000 SoC

This change adds support for Intel Atom C3000 SoC
("Denverton" and "Denverton-NS").
Code is partially based on Apollo Lake/Skylake code.

Change-Id: I53d69aede3b92f1fe06b74a96cc40187fb9825f1
Signed-off-by: Mariusz Szafranski <mariuszx.szafranski@intel.com>
Reviewed-on: https://review.coreboot.org/20861
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: FEI WANG <wangfei.jimei@gmail.com>
diff --git a/src/soc/intel/denverton_ns/Kconfig b/src/soc/intel/denverton_ns/Kconfig
new file mode 100644
index 0000000..cb13f3f
--- /dev/null
+++ b/src/soc/intel/denverton_ns/Kconfig
@@ -0,0 +1,182 @@
+##
+## This file is part of the coreboot project.
+##
+## Copyright (C) 2014 - 2017 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.
+##
+
+config SOC_INTEL_DENVERTON_NS
+	bool
+	help
+	  Intel Denverton-NS SoC support
+
+if SOC_INTEL_DENVERTON_NS
+
+config CPU_SPECIFIC_OPTIONS
+	def_bool y
+	select ARCH_BOOTBLOCK_X86_32
+	select ARCH_RAMSTAGE_X86_32
+	select ARCH_ROMSTAGE_X86_32
+	select ARCH_VERSTAGE_X86_32
+	select BOOTBLOCK_CONSOLE
+	select BOOT_DEVICE_SPI_FLASH_RW_NOMMAP_EARLY if BOOT_DEVICE_SPI_FLASH
+	select BOOT_DEVICE_SUPPORTS_WRITES
+	select POSTCAR_CONSOLE
+	select SOC_INTEL_COMMON
+	select SOC_INTEL_COMMON_RESET
+	select PLATFORM_USES_FSP2_0
+	select HAVE_HARD_RESET
+	select POSTCAR_STAGE
+	select C_ENVIRONMENT_BOOTBLOCK
+	select IOAPIC
+	select HAVE_SMI_HANDLER
+	select SMM_TSEG
+	select CACHE_MRC_SETTINGS
+	select RELOCATABLE_RAMSTAGE     # Build fails if this is not selected
+	select PARALLEL_MP
+	select SMP
+	select SOC_INTEL_COMMON_BLOCK
+#	select SOC_INTEL_COMMON_BLOCK_SA
+	select SOC_INTEL_COMMON_BLOCK_FAST_SPI
+	select TSC_CONSTANT_RATE
+	select TSC_MONOTONIC_TIMER
+	select TSC_SYNC_MFENCE
+	select UDELAY_TSC
+
+config FSP_T_ADDR
+	hex "Intel FSP-T (temp ram init) binary location"
+	depends on ADD_FSP_BINARIES && FSP_CAR
+	default 0xfff30000
+	help
+	  The memory location of the Intel FSP-T binary for this platform.
+
+config FSP_M_ADDR
+	hex "Intel FSP-M (memory init) binary location"
+	depends on ADD_FSP_BINARIES
+	default 0xfff32000
+	help
+	  The memory location of the Intel FSP-M binary for this platform.
+
+config FSP_S_ADDR
+	hex "Intel FSP-S (silicon init) binary location"
+	depends on ADD_FSP_BINARIES
+	default 0xfffc3000
+	help
+	  The memory location of the Intel FSP-S binary for this platform.
+
+# CAR memory layout on DENVERTON_NS hardware:
+## CAR base address - 0xfef00000
+## CAR size 1MB - 0x100 (0xfff00)
+## coreboot usage:
+## DCACHE base - 0xfef00000
+## DCACHE size - 0xb0000
+## FSP usage:
+## FSP base - 0xfefb0000
+## FSP size - 0x50000 - 0x100 (0x4ff00)
+config MAX_CPUS
+	int
+	default 16
+
+config DCACHE_RAM_BASE
+	hex
+	default 0xfef00000
+
+config DCACHE_RAM_SIZE
+	hex
+	default 0xb0000 if FSP_CAR
+	default 0x100000 if !FSP_CAR
+
+config DCACHE_BSP_STACK_SIZE
+	hex
+	default 0x10000
+
+config CPU_MICROCODE_CBFS_LOC
+	hex
+	default 0xfff20040
+
+config CPU_MICROCODE_CBFS_LEN
+	hex
+	default 0x0ff80
+
+config SMM_TSEG_SIZE
+	hex
+	default 0x200000
+
+config SMM_RESERVED_SIZE
+	hex
+	default 0x000000
+
+config IQAT_ENABLE
+	bool "Enable IQAT"
+	default y
+
+config IQAT_MEMORY_REGION_SIZE
+	depends on IQAT_ENABLE
+	hex
+	default 0x100000
+	help
+	  Do not change this value
+
+config HSUART_DEV
+	hex
+	default 0x1a
+
+config HSUART_FUNC
+	hex
+	default 0x0
+
+choice
+	prompt "UART mode selection"
+	default NON_LEGACY_UART_MODE
+
+config NON_LEGACY_UART_MODE
+	bool "Non Legacy Mode"
+	help
+	  Disable legacy UART mode
+
+config LEGACY_UART_MODE
+	bool "Legacy Mode"
+	help
+	  Enable legacy UART mode
+endchoice
+
+config ENABLE_HSUART
+	depends on (!DRIVERS_UART_8250IO && NON_LEGACY_UART_MODE)
+	bool "Enable High-speed UART debug port selected by UART_FOR_CONSOLE."
+	default n
+	select CONSOLE_SERIAL
+	select DRIVERS_UART
+	select DRIVERS_UART_8250MEM
+
+config CONSOLE_UART_BASE_ADDRESS
+	depends on ENABLE_HSUART
+	hex "MMIO base address for UART"
+	default 0xd4000000
+
+config C_ENV_BOOTBLOCK_SIZE
+	hex
+	default 0x8000
+
+config DENVERTON_NS_CAR_NEM_ENHANCED
+	bool "Enhanced Non-evict mode"
+	depends on !FSP_CAR
+	default y
+	select SOC_INTEL_COMMON_BLOCK_CAR
+	select INTEL_CAR_NEM_ENHANCED
+	help
+	  A current limitation of NEM (Non-Evict mode) is that code and data sizes
+	  are derived from the requirement to not write out any modified cache line.
+	  With NEM, if there is no physical memory behind the cached area,
+	  the modified data will be lost and NEM results will be inconsistent.
+	  ENHANCED NEM guarantees that modified data is always
+	  kept in cache while clean data is replaced.
+
+endif ## SOC_INTEL_DENVERTON_NS
diff --git a/src/soc/intel/denverton_ns/Makefile.inc b/src/soc/intel/denverton_ns/Makefile.inc
new file mode 100644
index 0000000..5feea13
--- /dev/null
+++ b/src/soc/intel/denverton_ns/Makefile.inc
@@ -0,0 +1,94 @@
+##
+## This file is part of the coreboot project.
+##
+## Copyright (C) 2014 - 2017 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.
+##
+
+ifeq ($(CONFIG_SOC_INTEL_DENVERTON_NS),y)
+
+subdirs-y += ../../../cpu/intel/microcode
+subdirs-y += ../../../cpu/intel/turbo
+subdirs-y += ../../../cpu/x86/lapic
+subdirs-y += ../../../cpu/x86/mtrr
+subdirs-$(CONFIG_HAVE_SMI_HANDLER) += ../../../cpu/x86/smm
+subdirs-y += ../../../cpu/x86/tsc
+subdirs-y += ../../../cpu/x86/cache
+
+bootblock-$(CONFIG_FSP_CAR)+= bootblock/cache_as_ram_fsp.S
+bootblock-y += bootblock/bootblock.c
+bootblock-y += spi.c
+bootblock-y += tsc_freq.c
+bootblock-$(CONFIG_CONSOLE_SERIAL) += bootblock/uart.c
+bootblock-$(CONFIG_DRIVERS_UART_8250MEM) += uart_debug.c
+
+postcar-y += memmap.c
+postcar-$(CONFIG_FSP_CAR) += exit_car_fsp.S
+postcar-y += spi.c
+postcar-$(CONFIG_DRIVERS_UART_8250MEM) += uart_debug.c
+
+romstage-y += memmap.c
+romstage-y += reset.c
+romstage-y += romstage.c
+romstage-y += tsc_freq.c
+romstage-y += gpio.c
+romstage-y += soc_util.c
+romstage-y += spi.c
+romstage-y += fiamux.c
+romstage-$(CONFIG_DRIVERS_UART_8250MEM) += uart_debug.c
+romstage-$(CONFIG_DISPLAY_UPD_DATA) += upd_display.c
+romstage-$(CONFIG_DISPLAY_HOBS) += hob_display.c
+
+ramstage-y += memmap.c
+ramstage-y += systemagent.c
+ramstage-y += reset.c
+ramstage-y += chip.c
+ramstage-y += soc_util.c
+ramstage-y += uart.c
+ramstage-y += xhci.c
+ramstage-y += csme_ie_kt.c
+ramstage-y += lpc.c
+ramstage-y += pmc.c
+ramstage-y += npk.c
+ramstage-y += sata.c
+ramstage-y += cpu.c
+ramstage-y += tsc_freq.c
+ramstage-y += spi.c
+ramstage-y += fiamux.c
+ramstage-$(CONFIG_DRIVERS_UART_8250MEM) += uart_debug.c
+ramstage-$(CONFIG_HAVE_ACPI_TABLES) += acpi.c
+ramstage-$(CONFIG_HAVE_SMI_HANDLER) += smm.c
+ramstage-$(CONFIG_HAVE_SMI_HANDLER) += pmutil.c
+ramstage-$(CONFIG_DISPLAY_UPD_DATA) += upd_display.c
+ramstage-$(CONFIG_DISPLAY_HOBS) += hob_display.c
+
+smm-$(CONFIG_HAVE_SMI_HANDLER) += pmutil.c
+smm-$(CONFIG_HAVE_SMI_HANDLER) += soc_util.c
+smm-$(CONFIG_HAVE_SMI_HANDLER) += smihandler.c
+smm-$(CONFIG_HAVE_SMI_HANDLER) += tsc_freq.c
+smm-$(CONFIG_SPI_FLASH_SMM) += spi.c
+smm-$(CONFIG_DRIVERS_UART_8250MEM) += uart_debug.c
+
+verstage-y += memmap.c
+verstage-y += reset.c
+verstage-y += spi.c
+verstage-$(CONFIG_DRIVERS_UART_8250MEM) += uart_debug.c
+
+CPPFLAGS_common += -I$(src)/soc/intel/denverton_ns/include
+CPPFLAGS_common += -I$(src)/vendorcode/intel/fsp/fsp2_0/denverton_ns
+
+##Set FSP binary blobs memory location
+
+$(CONFIG_FSP_T_CBFS)-options := -b $(CONFIG_FSP_T_ADDR) --xip
+$(CONFIG_FSP_M_CBFS)-options := -b $(CONFIG_FSP_M_ADDR) --xip
+$(CONFIG_FSP_S_CBFS)-options := -b $(CONFIG_FSP_S_ADDR) --xip
+
+endif ## CONFIG_SOC_INTEL_DENVERTON_NS
diff --git a/src/soc/intel/denverton_ns/acpi.c b/src/soc/intel/denverton_ns/acpi.c
new file mode 100644
index 0000000..7386db3
--- /dev/null
+++ b/src/soc/intel/denverton_ns/acpi.c
@@ -0,0 +1,332 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007 - 2009 coresystems GmbH
+ * Copyright (C) 2013 Google Inc.
+ * Copyright (C) 2014 - 2017 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/smp/mpspec.h>
+#include <cpu/x86/smm.h>
+#include <string.h>
+#include <device/pci.h>
+#include <cpu/cpu.h>
+#include <cbmem.h>
+
+#include <soc/acpi.h>
+#include <soc/cpu.h>
+#include <soc/soc_util.h>
+#include <soc/pmc.h>
+#include <soc/systemagent.h>
+
+void acpi_init_gnvs(global_nvs_t *gnvs)
+{
+	/* CPU core count */
+	gnvs->pcnt = dev_count_cpu();
+
+	/* Top of Low Memory (start of resource allocation) */
+	gnvs->tolm = top_of_32bit_ram();
+
+#if IS_ENABLED(CONFIG_CONSOLE_CBMEM)
+	/* Update the mem console pointer. */
+	gnvs->cbmc = (u32)cbmem_find(CBMEM_ID_CONSOLE);
+#endif
+
+	/* MMIO Low/High & TSEG base and length */
+	gnvs->mmiob = (u32)get_top_of_low_memory();
+	gnvs->mmiol = (u32)(get_pciebase() - 1);
+	gnvs->mmiohb = (u64)get_top_of_upper_memory();
+	gnvs->mmiohl = (u64)(((u64)1 << CONFIG_CPU_ADDR_BITS) - 1);
+	gnvs->tsegb = (u32)get_tseg_memory();
+	gnvs->tsegl = (u32)(get_top_of_low_memory() - get_tseg_memory());
+}
+
+static int acpi_sci_irq(void)
+{
+	int scis, sci_irq;
+	device_t dev = get_pmc_dev();
+
+	if (!dev)
+		return 0;
+
+	/* Determine how SCI is routed. */
+	scis = pci_read_config32(dev, PMC_ACPI_CNT) & PMC_ACPI_CNT_SCIS_MASK;
+	switch (scis) {
+	case PMC_ACPI_CNT_SCIS_IRQ9:
+	case PMC_ACPI_CNT_SCIS_IRQ10:
+	case PMC_ACPI_CNT_SCIS_IRQ11:
+		sci_irq = scis - PMC_ACPI_CNT_SCIS_IRQ9 + 9;
+		break;
+	case PMC_ACPI_CNT_SCIS_IRQ20:
+	case PMC_ACPI_CNT_SCIS_IRQ21:
+	case PMC_ACPI_CNT_SCIS_IRQ22:
+	case PMC_ACPI_CNT_SCIS_IRQ23:
+		sci_irq = scis - PMC_ACPI_CNT_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;
+}
+
+unsigned long acpi_fill_mcfg(unsigned long current)
+{
+	u32 pciexbar_reg;
+	int max_buses;
+
+	pciexbar_reg = get_pciebase();
+	max_buses = get_pcielength();
+
+	if (!pciexbar_reg)
+		return current;
+
+	current += acpi_create_mcfg_mmconfig((acpi_mcfg_mmconfig_t *)current,
+					     pciexbar_reg, 0x0, 0x0,
+					     (u8)(max_buses - 1));
+
+	return current;
+}
+
+void acpi_fill_in_fadt(acpi_fadt_t *fadt)
+{
+	u16 pmbase = get_pmbase();
+
+	/* System Management */
+	fadt->sci_int = acpi_sci_irq();
+#if IS_ENABLED(CONFIG_HAVE_SMI_HANDLER)
+	fadt->smi_cmd = APM_CNT;
+	fadt->acpi_enable = APM_CNT_ACPI_ENABLE;
+	fadt->acpi_disable = APM_CNT_ACPI_DISABLE;
+#else
+	fadt->smi_cmd = 0x00;
+	fadt->acpi_enable = 0x00;
+	fadt->acpi_disable = 0x00;
+#endif
+
+	/* Power Control */
+	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;
+	fadt->pm_tmr_blk = pmbase + PM1_TMR;
+	fadt->gpe0_blk = pmbase + GPE0_STS;
+	fadt->gpe1_blk = 0;
+
+	/* Control Registers - Length */
+	fadt->pm1_evt_len = 4;
+	fadt->pm1_cnt_len = 2;
+	fadt->pm2_cnt_len = 1;
+	fadt->pm_tmr_len = 4;
+	fadt->gpe0_blk_len = 8;
+	fadt->gpe1_blk_len = 0;
+	fadt->gpe1_base = 0;
+	fadt->cst_cnt = 0;
+	fadt->p_lvl2_lat = ACPI_FADT_C2_NOT_SUPPORTED;
+	fadt->p_lvl3_lat = ACPI_FADT_C3_NOT_SUPPORTED;
+	fadt->flush_size = 0;   /* set to 0 if WBINVD is 1 in flags */
+	fadt->flush_stride = 0; /* set to 0 if WBINVD is 1 in flags */
+	fadt->duty_offset = 1;
+	fadt->duty_width = 0;
+
+	/* RTC Registers */
+	fadt->day_alrm = 0x0D;
+	fadt->mon_alrm = 0x00;
+	fadt->century = 0x00;
+	fadt->iapc_boot_arch = 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_SLEEP_TYPE |
+		      ACPI_FADT_S4_RTC_WAKE | ACPI_FADT_PLATFORM_CLOCK;
+
+	/* Reset Register */
+	fadt->reset_reg.space_id = ACPI_ADDRESS_SPACE_IO;
+	fadt->reset_reg.bit_width = 8;
+	fadt->reset_reg.bit_offset = 0;
+	fadt->reset_reg.access_size = ACPI_ACCESS_SIZE_BYTE_ACCESS;
+	fadt->reset_reg.addrl = 0xCF9;
+	fadt->reset_reg.addrh = 0x00;
+	fadt->reset_value = 6;
+
+	/* PM1 Status & PM1 Enable */
+	fadt->x_pm1a_evt_blk.space_id = ACPI_ADDRESS_SPACE_IO;
+	fadt->x_pm1a_evt_blk.bit_width = 32;
+	fadt->x_pm1a_evt_blk.bit_offset = 0;
+	fadt->x_pm1a_evt_blk.access_size = ACPI_ACCESS_SIZE_DWORD_ACCESS;
+	fadt->x_pm1a_evt_blk.addrl = fadt->pm1a_evt_blk;
+	fadt->x_pm1a_evt_blk.addrh = 0x00;
+
+	fadt->x_pm1b_evt_blk.space_id = ACPI_ADDRESS_SPACE_IO;
+	fadt->x_pm1b_evt_blk.bit_width = 0;
+	fadt->x_pm1b_evt_blk.bit_offset = 0;
+	fadt->x_pm1b_evt_blk.access_size = 0;
+	fadt->x_pm1b_evt_blk.addrl = fadt->pm1b_evt_blk;
+	fadt->x_pm1b_evt_blk.addrh = 0x00;
+
+	/* PM1 Control Registers */
+	fadt->x_pm1a_cnt_blk.space_id = ACPI_ADDRESS_SPACE_IO;
+	fadt->x_pm1a_cnt_blk.bit_width = 16;
+	fadt->x_pm1a_cnt_blk.bit_offset = 0;
+	fadt->x_pm1a_cnt_blk.access_size = ACPI_ACCESS_SIZE_WORD_ACCESS;
+	fadt->x_pm1a_cnt_blk.addrl = fadt->pm1a_cnt_blk;
+	fadt->x_pm1a_cnt_blk.addrh = 0x00;
+
+	fadt->x_pm1b_cnt_blk.space_id = ACPI_ADDRESS_SPACE_IO;
+	fadt->x_pm1b_cnt_blk.bit_width = 0;
+	fadt->x_pm1b_cnt_blk.bit_offset = 0;
+	fadt->x_pm1b_cnt_blk.access_size = 0;
+	fadt->x_pm1b_cnt_blk.addrl = fadt->pm1b_cnt_blk;
+	fadt->x_pm1b_cnt_blk.addrh = 0x00;
+
+	/* PM2 Control Registers */
+	fadt->x_pm2_cnt_blk.space_id = ACPI_ADDRESS_SPACE_IO;
+	fadt->x_pm2_cnt_blk.bit_width = 8;
+	fadt->x_pm2_cnt_blk.bit_offset = 0;
+	fadt->x_pm2_cnt_blk.access_size = ACPI_ACCESS_SIZE_BYTE_ACCESS;
+	fadt->x_pm2_cnt_blk.addrl = fadt->pm2_cnt_blk;
+	fadt->x_pm2_cnt_blk.addrh = 0x00;
+
+	/* PM1 Timer Register */
+	fadt->x_pm_tmr_blk.space_id = ACPI_ADDRESS_SPACE_IO;
+	fadt->x_pm_tmr_blk.bit_width = 32;
+	fadt->x_pm_tmr_blk.bit_offset = 0;
+	fadt->x_pm_tmr_blk.access_size = ACPI_ACCESS_SIZE_DWORD_ACCESS;
+	fadt->x_pm_tmr_blk.addrl = fadt->pm_tmr_blk;
+	fadt->x_pm_tmr_blk.addrh = 0x00;
+
+	/*  General-Purpose Event Registers */
+	fadt->x_gpe0_blk.space_id = ACPI_ADDRESS_SPACE_IO;
+	fadt->x_gpe0_blk.bit_width = 64; /* EventStatus + EventEnable */
+	fadt->x_gpe0_blk.bit_offset = 0;
+	fadt->x_gpe0_blk.access_size = ACPI_ACCESS_SIZE_DWORD_ACCESS;
+	fadt->x_gpe0_blk.addrl = fadt->gpe0_blk;
+	fadt->x_gpe0_blk.addrh = 0x00;
+
+	fadt->x_gpe1_blk.space_id = ACPI_ADDRESS_SPACE_IO;
+	fadt->x_gpe1_blk.bit_width = 0;
+	fadt->x_gpe1_blk.bit_offset = 0;
+	fadt->x_gpe1_blk.access_size = 0;
+	fadt->x_gpe1_blk.addrl = fadt->gpe1_blk;
+	fadt->x_gpe1_blk.addrh = 0x00;
+}
+
+void generate_cpu_entries(device_t device)
+{
+	int core;
+	int pcontrol_blk = get_pmbase(), plen = 6;
+	int num_cpus = get_cpu_count();
+
+	for (core = 0; core < num_cpus; core++) {
+		if (core > 0) {
+			pcontrol_blk = 0;
+			plen = 0;
+		}
+
+		/* Generate processor \_PR.CPUx */
+		acpigen_write_processor(core, pcontrol_blk, plen);
+
+		/* Generate  P-state tables */
+
+		/* Generate C-state tables */
+
+		/* Generate T-state tables */
+
+		acpigen_pop_len();
+	}
+}
+
+unsigned long acpi_madt_irq_overrides(unsigned long current)
+{
+	int sci_irq = acpi_sci_irq();
+	acpi_madt_irqoverride_t *irqovr;
+	uint16_t sci_flags = MP_IRQ_TRIGGER_LEVEL;
+
+	/* INT_SRC_OVR */
+	irqovr = (acpi_madt_irqoverride_t *)current;
+	current += acpi_create_madt_irqoverride(irqovr, 0, 0, 2, 0);
+
+	if (sci_irq >= 20)
+		sci_flags |= MP_IRQ_POLARITY_LOW;
+	else
+		sci_flags |= MP_IRQ_POLARITY_HIGH;
+
+	irqovr = (acpi_madt_irqoverride_t *)current;
+	current += acpi_create_madt_irqoverride(irqovr, 0, (u8)sci_irq, sci_irq,
+						sci_flags);
+
+	return current;
+}
+
+unsigned long southcluster_write_acpi_tables(device_t device,
+					     unsigned long current,
+					     struct acpi_rsdp *rsdp)
+{
+	acpi_header_t *ssdt2;
+
+	current = acpi_write_hpet(device, current, rsdp);
+	current = (ALIGN(current, 16));
+
+	ssdt2 = (acpi_header_t *)current;
+	memset(ssdt2, 0, sizeof(acpi_header_t));
+	acpi_create_serialio_ssdt(ssdt2);
+	if (ssdt2->length) {
+		current += ssdt2->length;
+		acpi_add_table(rsdp, ssdt2);
+		printk(BIOS_DEBUG, "ACPI:     * SSDT2 @ %p Length %x\n", ssdt2,
+		       ssdt2->length);
+		current = (ALIGN(current, 16));
+	} else {
+		ssdt2 = NULL;
+		printk(BIOS_DEBUG, "ACPI:     * SSDT2 not generated.\n");
+	}
+
+	printk(BIOS_DEBUG, "current = %lx\n", current);
+
+	return 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_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();
+	}
+}
+
+__attribute__((weak)) void acpi_create_serialio_ssdt(acpi_header_t *ssdt) {}
diff --git a/src/soc/intel/denverton_ns/acpi/cpu.asl b/src/soc/intel/denverton_ns/acpi/cpu.asl
new file mode 100644
index 0000000..00dc6c7
--- /dev/null
+++ b/src/soc/intel/denverton_ns/acpi/cpu.asl
@@ -0,0 +1,141 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2011 The ChromiumOS Authors.  All rights reserved.
+ * Copyright (C) 2014 - 2017 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.
+ *
+ */
+
+/* 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)
+External (\_PR.CP08, DeviceObj)
+External (\_PR.CP09, DeviceObj)
+External (\_PR.CP10, DeviceObj)
+External (\_PR.CP11, DeviceObj)
+External (\_PR.CP12, DeviceObj)
+External (\_PR.CP13, DeviceObj)
+External (\_PR.CP14, DeviceObj)
+External (\_PR.CP15, 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
+	}
+	If (LGreaterEqual (\PCNT, 16)) {
+		Notify (\_PR.CP08, 0x81)  // _CST
+		Notify (\_PR.CP09, 0x81)  // _CST
+		Notify (\_PR.CP10, 0x81)  // _CST
+		Notify (\_PR.CP11, 0x81)  // _CST
+		Notify (\_PR.CP12, 0x81)  // _CST
+		Notify (\_PR.CP13, 0x81)  // _CST
+		Notify (\_PR.CP14, 0x81)  // _CST
+		Notify (\_PR.CP15, 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
+	}
+	If (LGreaterEqual (\PCNT, 16)) {
+		Notify (\_PR.CP08, 0x80)  // _PPC
+		Notify (\_PR.CP09, 0x80)  // _PPC
+		Notify (\_PR.CP10, 0x80)  // _PPC
+		Notify (\_PR.CP11, 0x80)  // _PPC
+		Notify (\_PR.CP12, 0x80)  // _PPC
+		Notify (\_PR.CP13, 0x80)  // _PPC
+		Notify (\_PR.CP14, 0x80)  // _PPC
+		Notify (\_PR.CP15, 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
+	}
+	If (LGreaterEqual (\PCNT, 16)) {
+		Notify (\_PR.CP08, 0x82)  // _TPC
+		Notify (\_PR.CP09, 0x82)  // _TPC
+		Notify (\_PR.CP10, 0x82)  // _TPC
+		Notify (\_PR.CP11, 0x82)  // _TPC
+		Notify (\_PR.CP12, 0x82)  // _TPC
+		Notify (\_PR.CP13, 0x82)  // _TPC
+		Notify (\_PR.CP14, 0x82)  // _TPC
+		Notify (\_PR.CP15, 0x82)  // _TPC
+	}
+}
+
+/* Return a package containing enabled processor entries */
+Method (PPKG)
+{
+	If (LGreaterEqual (\PCNT, 16)) {
+		Return (Package() {\_PR.CP00, \_PR.CP01, \_PR.CP02, \_PR.CP03,
+				   \_PR.CP04, \_PR.CP05, \_PR.CP06, \_PR.CP07,
+				   \_PR.CP08, \_PR.CP09, \_PR.CP10, \_PR.CP11,
+				   \_PR.CP12, \_PR.CP13, \_PR.CP14, \_PR.CP15})
+	} ElseIf (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/denverton_ns/acpi/globalnvs.asl b/src/soc/intel/denverton_ns/acpi/globalnvs.asl
new file mode 100644
index 0000000..5ef029e
--- /dev/null
+++ b/src/soc/intel/denverton_ns/acpi/globalnvs.asl
@@ -0,0 +1,103 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google Inc.
+ * Copyright (C) 2014 - 2017 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
+	P80D,	32,	// 0x0b - Debug port (IO 0x80) value
+	LIDS,	 8,	// 0x0f - LID state (open = 1)
+	PWRS,	 8,	// 0x10 - Power State (AC = 1)
+	PCNT,	 8,	// 0x11 - Processor count
+	TPMP,	 8,	// 0x12 - TPM Present and Enabled
+	TLVL,	 8,	// 0x13 - Throttle Level
+	PPCM,	 8,	// 0x14 - Maximum P-state usable by OS
+
+	/* Device Config */
+	Offset (0x20),
+	S5U0,	 8,	// 0x20 - Enable USB0 in S5
+	S5U1,	 8,	// 0x21 - Enable USB1 in S5
+	S3U0,	 8,	// 0x22 - Enable USB0 in S3
+	S3U1,	 8,	// 0x23 - Enable USB1 in S3
+	TACT,	 8,	// 0x24 - Thermal Active trip point
+	TPSV,	 8,	// 0x25 - Thermal Passive trip point
+	TCRT,	 8,	// 0x26 - Thermal Critical trip point
+	DPTE,	 8,	// 0x27 - Enable DPTF
+
+	/* Base addresses */
+	Offset (0x30),
+	CMEM,	 32,	// 0x30 - CBMEM TOC
+	TOLM,	 32,	// 0x34 - Top of Low Memory
+	CBMC,	 32,	// 0x38 - coreboot mem console pointer
+	MMOB,	 32,	// 0x3c - MMIO Base Low Base
+	MMOL,	 32,	// 0x40 - MMIO Base Low Limit
+	MMHB,	 64,	// 0x44 - MMIO Base High Base
+	MMHL,	 64,	// 0x4c - MMIO Base High Limit
+	TSGB,	 32,	// 0x54 - TSEG Base
+	TSSZ,	 32,	// 0x58 - TSEG Size
+}
+
+/* Set flag to enable USB charging in S3 */
+Method (S3UE)
+{
+	Store (One, \S3U0)
+	Store (One, \S3U1)
+}
+
+/* Set flag to disable USB charging in S3 */
+Method (S3UD)
+{
+	Store (Zero, \S3U0)
+	Store (Zero, \S3U1)
+}
+
+/* Set flag to enable USB charging in S5 */
+Method (S5UE)
+{
+	Store (One, \S5U0)
+	Store (One, \S5U1)
+}
+
+/* Set flag to disable USB charging in S5 */
+Method (S5UD)
+{
+	Store (Zero, \S5U0)
+	Store (Zero, \S5U1)
+}
diff --git a/src/soc/intel/denverton_ns/acpi/irqlinks.asl b/src/soc/intel/denverton_ns/acpi/irqlinks.asl
new file mode 100644
index 0000000..308ef1e
--- /dev/null
+++ b/src/soc/intel/denverton_ns/acpi/irqlinks.asl
@@ -0,0 +1,488 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007 - 2009 coresystems GmbH
+ * Copyright (C) 2015 - 2017 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 (LNKA)
+{
+	Name (_HID, EISAID("PNP0C0F"))
+	Name (_UID, 1)
+
+	// Disable method
+	Method (_DIS, 0, Serialized)
+	{
+		Store (0x80, PRTA)
+	}
+
+	// Possible Resource Settings for this Link
+	Name (_PRS, ResourceTemplate()
+	{
+		IRQ(Level, ActiveLow, Shared)
+			{ 6, 7, 10, 11, 12, 14, 15 }
+	})
+
+	// Current Resource Settings for this link
+	Method (_CRS, 0, Serialized)
+	{
+		Name (RTLA, ResourceTemplate()
+		{
+			IRQ(Level, ActiveLow, Shared) {}
+		})
+		CreateWordField(RTLA, 1, IRQ0)
+
+		// Clear the WordField
+		Store (Zero, IRQ0)
+
+		// Set the bit from PRTA
+		ShiftLeft(1, And(PRTA, 0x0f), IRQ0)
+
+		Return (RTLA)
+	}
+
+	// Set Resource Setting for this IRQ link
+	Method (_SRS, 1, Serialized)
+	{
+		CreateWordField(Arg0, 1, IRQ0)
+
+		// Which bit is set?
+		FindSetRightBit(IRQ0, Local0)
+
+		Decrement(Local0)
+		Store(Local0, PRTA)
+	}
+
+	// Status
+	Method (_STA, 0, Serialized)
+	{
+		If(And(PRTA, 0x80)) {
+			Return (0x9)
+		} Else {
+			Return (0xb)
+		}
+	}
+}
+
+Device (LNKB)
+{
+	Name (_HID, EISAID("PNP0C0F"))
+	Name (_UID, 2)
+
+	// Disable method
+	Method (_DIS, 0, Serialized)
+	{
+		Store (0x80, PRTB)
+	}
+
+	// Possible Resource Settings for this Link
+	Name (_PRS, ResourceTemplate()
+	{
+		IRQ(Level, ActiveLow, Shared)
+			{ 6, 7, 10, 11, 12, 14, 15 }
+	})
+
+	// Current Resource Settings for this link
+	Method (_CRS, 0, Serialized)
+	{
+		Name (RTLB, ResourceTemplate()
+		{
+			IRQ(Level, ActiveLow, Shared) {}
+		})
+		CreateWordField(RTLB, 1, IRQ0)
+
+		// Clear the WordField
+		Store (Zero, IRQ0)
+
+		// Set the bit from PRTB
+		ShiftLeft(1, And(PRTB, 0x0f), IRQ0)
+
+		Return (RTLB)
+	}
+
+	// Set Resource Setting for this IRQ link
+	Method (_SRS, 1, Serialized)
+	{
+		CreateWordField(Arg0, 1, IRQ0)
+
+		// Which bit is set?
+		FindSetRightBit(IRQ0, Local0)
+
+		Decrement(Local0)
+		Store(Local0, PRTB)
+	}
+
+	// Status
+	Method (_STA, 0, Serialized)
+	{
+		If(And(PRTB, 0x80)) {
+			Return (0x9)
+		} Else {
+			Return (0xb)
+		}
+	}
+}
+
+Device (LNKC)
+{
+	Name (_HID, EISAID("PNP0C0F"))
+	Name (_UID, 3)
+
+	// Disable method
+	Method (_DIS, 0, Serialized)
+	{
+		Store (0x80, PRTC)
+	}
+
+	// Possible Resource Settings for this Link
+	Name (_PRS, ResourceTemplate()
+	{
+		IRQ(Level, ActiveLow, Shared)
+			{ 6, 7, 10, 11, 12, 14, 15 }
+	})
+
+	// Current Resource Settings for this link
+	Method (_CRS, 0, Serialized)
+	{
+		Name (RTLC, ResourceTemplate()
+		{
+			IRQ(Level, ActiveLow, Shared) {}
+		})
+		CreateWordField(RTLC, 1, IRQ0)
+
+		// Clear the WordField
+		Store (Zero, IRQ0)
+
+		// Set the bit from PRTC
+		ShiftLeft(1, And(PRTC, 0x0f), IRQ0)
+
+		Return (RTLC)
+	}
+
+	// Set Resource Setting for this IRQ link
+	Method (_SRS, 1, Serialized)
+	{
+		CreateWordField(Arg0, 1, IRQ0)
+
+		// Which bit is set?
+		FindSetRightBit(IRQ0, Local0)
+
+		Decrement(Local0)
+		Store(Local0, PRTC)
+	}
+
+	// Status
+	Method (_STA, 0, Serialized)
+	{
+		If(And(PRTC, 0x80)) {
+			Return (0x9)
+		} Else {
+			Return (0xb)
+		}
+	}
+}
+
+Device (LNKD)
+{
+	Name (_HID, EISAID("PNP0C0F"))
+	Name (_UID, 4)
+
+	// Disable method
+	Method (_DIS, 0, Serialized)
+	{
+		Store (0x80, PRTD)
+	}
+
+	// Possible Resource Settings for this Link
+	Name (_PRS, ResourceTemplate()
+	{
+		IRQ(Level, ActiveLow, Shared)
+			{ 6, 7, 10, 11, 12, 14, 15 }
+	})
+
+	// Current Resource Settings for this link
+	Method (_CRS, 0, Serialized)
+	{
+		Name (RTLD, ResourceTemplate()
+		{
+			IRQ(Level, ActiveLow, Shared) {}
+		})
+		CreateWordField(RTLD, 1, IRQ0)
+
+		// Clear the WordField
+		Store (Zero, IRQ0)
+
+		// Set the bit from PRTD
+		ShiftLeft(1, And(PRTD, 0x0f), IRQ0)
+
+		Return (RTLD)
+	}
+
+	// Set Resource Setting for this IRQ link
+	Method (_SRS, 1, Serialized)
+	{
+		CreateWordField(Arg0, 1, IRQ0)
+
+		// Which bit is set?
+		FindSetRightBit(IRQ0, Local0)
+
+		Decrement(Local0)
+		Store(Local0, PRTD)
+	}
+
+	// Status
+	Method (_STA, 0, Serialized)
+	{
+		If(And(PRTD, 0x80)) {
+			Return (0x9)
+		} Else {
+			Return (0xb)
+		}
+	}
+}
+
+Device (LNKE)
+{
+	Name (_HID, EISAID("PNP0C0F"))
+	Name (_UID, 5)
+
+	// Disable method
+	Method (_DIS, 0, Serialized)
+	{
+		Store (0x80, PRTE)
+	}
+
+	// Possible Resource Settings for this Link
+	Name (_PRS, ResourceTemplate()
+	{
+		IRQ(Level, ActiveLow, Shared)
+			{ 6, 7, 10, 11, 12, 14, 15 }
+	})
+
+	// Current Resource Settings for this link
+	Method (_CRS, 0, Serialized)
+	{
+		Name (RTLE, ResourceTemplate()
+		{
+			IRQ(Level, ActiveLow, Shared) {}
+		})
+		CreateWordField(RTLE, 1, IRQ0)
+
+		// Clear the WordField
+		Store (Zero, IRQ0)
+
+		// Set the bit from PRTE
+		ShiftLeft(1, And(PRTE, 0x0f), IRQ0)
+
+		Return (RTLE)
+	}
+
+	// Set Resource Setting for this IRQ link
+	Method (_SRS, 1, Serialized)
+	{
+		CreateWordField(Arg0, 1, IRQ0)
+
+		// Which bit is set?
+		FindSetRightBit(IRQ0, Local0)
+
+		Decrement(Local0)
+		Store(Local0, PRTE)
+	}
+
+	// Status
+	Method (_STA, 0, Serialized)
+	{
+		If(And(PRTE, 0x80)) {
+			Return (0x9)
+		} Else {
+			Return (0xb)
+		}
+	}
+}
+
+Device (LNKF)
+{
+	Name (_HID, EISAID("PNP0C0F"))
+	Name (_UID, 6)
+
+	// Disable method
+	Method (_DIS, 0, Serialized)
+	{
+		Store (0x80, PRTF)
+	}
+
+	// Possible Resource Settings for this Link
+	Name (_PRS, ResourceTemplate()
+	{
+		IRQ(Level, ActiveLow, Shared)
+			{ 6, 7, 10, 11, 12, 14, 15 }
+	})
+
+	// Current Resource Settings for this link
+	Method (_CRS, 0, Serialized)
+	{
+		Name (RTLF, ResourceTemplate()
+		{
+			IRQ(Level, ActiveLow, Shared) {}
+		})
+		CreateWordField(RTLF, 1, IRQ0)
+
+		// Clear the WordField
+		Store (Zero, IRQ0)
+
+		// Set the bit from PRTF
+		ShiftLeft(1, And(PRTF, 0x0f), IRQ0)
+
+		Return (RTLF)
+	}
+
+	// Set Resource Setting for this IRQ link
+	Method (_SRS, 1, Serialized)
+	{
+		CreateWordField(Arg0, 1, IRQ0)
+
+		// Which bit is set?
+		FindSetRightBit(IRQ0, Local0)
+
+		Decrement(Local0)
+		Store(Local0, PRTF)
+	}
+
+	// Status
+	Method (_STA, 0, Serialized)
+	{
+		If(And(PRTF, 0x80)) {
+			Return (0x9)
+		} Else {
+			Return (0xb)
+		}
+	}
+}
+
+Device (LNKG)
+{
+	Name (_HID, EISAID("PNP0C0F"))
+	Name (_UID, 7)
+
+	// Disable method
+	Method (_DIS, 0, Serialized)
+	{
+		Store (0x80, PRTG)
+	}
+
+	// Possible Resource Settings for this Link
+	Name (_PRS, ResourceTemplate()
+	{
+		IRQ(Level, ActiveLow, Shared)
+			{ 6, 7, 10, 11, 12, 14, 15 }
+	})
+
+	// Current Resource Settings for this link
+	Method (_CRS, 0, Serialized)
+	{
+		Name (RTLG, ResourceTemplate()
+		{
+			IRQ(Level, ActiveLow, Shared) {}
+		})
+		CreateWordField(RTLG, 1, IRQ0)
+
+		// Clear the WordField
+		Store (Zero, IRQ0)
+
+		// Set the bit from PRTG
+		ShiftLeft(1, And(PRTG, 0x0f), IRQ0)
+
+		Return (RTLG)
+	}
+
+	// Set Resource Setting for this IRQ link
+	Method (_SRS, 1, Serialized)
+	{
+		CreateWordField(Arg0, 1, IRQ0)
+
+		// Which bit is set?
+		FindSetRightBit(IRQ0, Local0)
+
+		Decrement(Local0)
+		Store(Local0, PRTG)
+	}
+
+	// Status
+	Method (_STA, 0, Serialized)
+	{
+		If(And(PRTG, 0x80)) {
+			Return (0x9)
+		} Else {
+			Return (0xb)
+		}
+	}
+}
+
+Device (LNKH)
+{
+	Name (_HID, EISAID("PNP0C0F"))
+	Name (_UID, 8)
+
+	// Disable method
+	Method (_DIS, 0, Serialized)
+	{
+		Store (0x80, PRTH)
+	}
+
+	// Possible Resource Settings for this Link
+	Name (_PRS, ResourceTemplate()
+	{
+		IRQ(Level, ActiveLow, Shared)
+			{ 6, 7, 10, 11, 12, 14, 15 }
+	})
+
+	// Current Resource Settings for this link
+	Method (_CRS, 0, Serialized)
+	{
+		Name (RTLH, ResourceTemplate()
+		{
+			IRQ(Level, ActiveLow, Shared) {}
+		})
+		CreateWordField(RTLH, 1, IRQ0)
+
+		// Clear the WordField
+		Store (Zero, IRQ0)
+
+		// Set the bit from PRTH
+		ShiftLeft(1, And(PRTH, 0x0f), IRQ0)
+
+		Return (RTLH)
+	}
+
+	// Set Resource Setting for this IRQ link
+	Method (_SRS, 1, Serialized)
+	{
+		CreateWordField(Arg0, 1, IRQ0)
+
+		// Which bit is set?
+		FindSetRightBit(IRQ0, Local0)
+
+		Decrement(Local0)
+		Store(Local0, PRTH)
+	}
+
+	// Status
+	Method (_STA, 0, Serialized)
+	{
+		If(And(PRTH, 0x80)) {
+			Return (0x9)
+		} Else {
+			Return (0xb)
+		}
+	}
+}
diff --git a/src/soc/intel/denverton_ns/acpi/lpc.asl b/src/soc/intel/denverton_ns/acpi/lpc.asl
new file mode 100644
index 0000000..262ac55
--- /dev/null
+++ b/src/soc/intel/denverton_ns/acpi/lpc.asl
@@ -0,0 +1,232 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007 - 2009 coresystems GmbH
+ * Copyright (C) 2014 - 2017 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 LPC Bus Device  - 0:1f.0
+
+Device (LPCB)
+{
+	Name(_ADR, 0x001f0000)
+
+	OperationRegion(LPC0, PCI_Config, 0x00, 0x100)
+	Field (LPC0, AnyAcc, NoLock, Preserve)
+	{
+		Offset (0x80),	// IO Decode Ranges
+		IOD0,	8,
+		IOD1,	8,
+	}
+
+	#include "irqlinks.asl"
+
+	Device(APIC)	// IO APIC
+	{
+		Name(_HID,EISAID("PNP0003"))
+		Name(_CRS, ResourceTemplate()
+		{
+			Memory32Fixed(ReadOnly, 0xFEC00000, 0x1000)
+		})
+	}
+
+	Device (HPET)
+	{
+		Name (_HID, EISAID("PNP0103"))
+		Name (_CID, 0x010CD041)
+
+		Method (_STA, 0)	// Device Status
+		{
+			Return (0xF)	// Enable and show device
+		}
+
+		Name(_CRS, ResourceTemplate()
+		{
+			Memory32Fixed(ReadOnly, DEFAULT_HPET_ADDR, 0x400)
+		})
+	}
+
+	Device(PIC)	// 8259 Interrupt Controller
+	{
+		Name(_HID,EISAID("PNP0000"))
+		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(LDRC)	// LPC device: Resource consumption
+	{
+		Name (_HID, EISAID("PNP0C02"))
+		Name (_UID, 2)
+		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, 0x70, 0x70, 0x1, 0x01)		// NMI Enable.
+			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, 0x800, 0x800, 0x1, 0x10)		// ACPI I/O trap
+
+			// BIOS ROM shadow memory range
+			Memory32Fixed(ReadOnly, 0x000E0000, 0x20000)
+
+			// BIOS flash 16MB
+			Memory32Fixed(ReadOnly,0xFF000000,0x1000000)
+		})
+	}
+
+	Device (RTC)	// Real Time Clock
+	{
+		Name (_HID, EISAID("PNP0B00"))
+		Name (_CRS, ResourceTemplate()
+		{
+			IO (Decode16, 0x70, 0x70, 1, 8)
+// Disable as Windows doesn't like it, and systems don't seem to use it.
+//			IRQNoFlags() { 8 }
+		})
+	}
+
+	Device (TIMR)	// Intel 8254 timer
+	{
+		Name(_HID, EISAID("PNP0100"))
+		Name(_CRS, ResourceTemplate()
+		{
+			IO (Decode16, 0x40, 0x40, 0x01, 0x04)
+			IO (Decode16, 0x50, 0x50, 0x10, 0x04)
+			IRQNoFlags() {0}
+		})
+	}
+
+	Device(IUR3) // Internal UART 1
+	{
+	  Name(_HID, EISAID("PNP0501"))
+
+	  Name(_UID,1)
+
+	  // Status Method for internal UART 1.
+
+	  Method(_STA,0,Serialized)
+	  {
+		Return(0x000F)
+	  }
+
+	  // Current Resource Setting Method for internal UART 1.
+
+	  Method(_CRS,0,Serialized)
+	  {
+		// Create the Buffer that stores the Resources to
+		// be returned.
+
+		Name(BUF0,ResourceTemplate()
+		{
+		  IO(Decode16,0x03F8,0x03F8,0x01,0x08)
+		  Interrupt (ResourceConsumer, Level, ActiveLow, Shared) {16}
+		})
+
+		Return(BUF0)
+	  }
+	}
+
+	Device(IUR4) // Internal UART 2
+	{
+	  Name(_HID, EISAID("PNP0501"))
+	  Name(_UID,2)
+	  // Status Method for internal UART 2.
+	  Method(_STA,0,Serialized)
+	  {
+		Return(0x000F)
+	  }
+	  // Current Resource Setting Method for internal UART 2.
+	  Method(_CRS,0,Serialized)
+	  {
+		// Create the Buffer that stores the Resources to
+		// be returned.
+		Name(BUF0,ResourceTemplate()
+		{
+		  IO(Decode16,0x02F8,0x02F8,0x01,0x08)
+ 		  Interrupt (ResourceConsumer, Level, ActiveLow, Shared) {17}
+		})
+		Return(BUF0)
+	  }
+	}
+
+	Device(IUR5) // Internal UART 3
+	{
+	  Name(_HID, EISAID("PNP0501"))
+	  Name(_UID,3)
+	  // Status Method for internal UART 3.
+	  Method(_STA,0,Serialized)
+	  {
+		Return(0x000F)
+	  }
+	  // Current Resource Setting Method for internal UART 3.
+	  Method(_CRS,0,Serialized)
+	  {
+		// Create the Buffer that stores the Resources to
+		// be returned.
+		Name(BUF0,ResourceTemplate()
+		{
+		  IO(Decode16,0x03E8,0x03E8,0x01,0x08)
+		  Interrupt (ResourceConsumer, Level, ActiveLow, Shared) {18}
+		})
+		Return(BUF0)
+	  }
+	}
+
+#ifdef ENABLE_TPM
+	Device (TPM)		// Trusted Platform Module
+	{
+		Name(_HID, EISAID("IFX0102"))
+		Name(_CID, 0x310cd041)
+		Name(_UID, 1)
+
+		Method(_STA, 0)
+		{
+			If (TPMP) {
+				Return (0xf)
+			}
+			Return (0x0)
+		}
+
+		Name(_CRS, ResourceTemplate() {
+			IO (Decode16, 0x2e, 0x2e, 0x01, 0x02)
+			IO (Decode16, 0x6f0, 0x6f0, 0x01, 0x10)
+			Memory32Fixed (ReadWrite, 0xfed40000, 0x5000)
+			IRQ (Edge, Activehigh, Exclusive) { 6 }
+		})
+	}
+#endif
+}
diff --git a/src/soc/intel/denverton_ns/acpi/northcluster.asl b/src/soc/intel/denverton_ns/acpi/northcluster.asl
new file mode 100644
index 0000000..bbfa133
--- /dev/null
+++ b/src/soc/intel/denverton_ns/acpi/northcluster.asl
@@ -0,0 +1,171 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007 - 2009 coresystems GmbH
+ * Copyright (C) 2014 - 2017 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 "../include/soc/iomap.h"
+
+Name(_HID,EISAID("PNP0A08"))	// PCIe
+Name(_CID,EISAID("PNP0A03"))	// PCI
+
+Name(_ADR, 0)
+Name(_BBN, 0)
+
+Device (MCHC)
+{
+	Name(_ADR, 0x00000000)	// 0:0.0
+
+	OperationRegion(MCHP, PCI_Config, 0x00, 0x100)
+	Field (MCHP, DWordAcc, NoLock, Preserve)
+	{
+		Offset (0x48),	// MCHBAR
+		MHEN,	 1,	// Enable
+		,	13,	//
+		MHBR,	22,	// MCHBAR
+
+		Offset (0x60),	// PCIe BAR
+		PXEN,	 1,	// Enable
+		PXSZ,	 2,	// BAR size
+		,	23,	//
+		PXBR,	10,	// PCIe BAR
+
+		Offset (0xa8),	// Top of Upper Memory
+		TUUD,	 64,
+
+		Offset (0xb8),	// TSEGMB
+		TSEG,	 32,
+
+		Offset (0xbc),	// Top of Low Used Memory
+		TLUD,	 32,
+	}
+}
+
+// Current Resource Settings
+
+Name (MCRS, ResourceTemplate()
+{
+	// Bus Numbers
+	WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode,
+			0x0000, 0x0000, 0x00ff, 0x0000, 0x0100,,, PB00)
+
+	// IO Region 0
+	DWordIO (ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
+			0x0000, 0x0000, 0x0cf7, 0x0000, 0x0cf8,,, PI00)
+
+	// PCI Config Space
+	Io (Decode16, 0x0cf8, 0x0cf8, 0x0001, 0x0008)
+
+	// IO Region 1
+	DWordIO (ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
+			0x0000, 0x0d00, 0xffff, 0x0000, 0xf300,,, PI01)
+
+	// VGA memory (0xa0000-0xbffff)
+	DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
+			Cacheable, ReadWrite,
+			0x00000000, 0x000a0000, 0x000bffff, 0x00000000,
+			0x00020000,,, ASEG)
+
+	// RAM (0xc0000-0xdffff)
+	DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
+			Cacheable, ReadWrite,
+			0x00000000, 0x000c0000, 0x000dffff, 0x00000000,
+			0x00020000,,, OPR0)
+
+	// PCI Memory Region (Top of memory-PCIEXBAR)
+	DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
+			NonCacheable, ReadWrite,
+			0x00000000, 0x00000000, 0xfebfffff, 0x00000000,
+			0xfec00000,,, PM01)
+
+#ifdef ENABLE_TPM
+	// TPM Area (0xfed40000-0xfed44fff)
+	DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
+			Cacheable, ReadWrite,
+			0x00000000, 0xfed40000, 0xfed44fff, 0x00000000,
+			0x00005000,,, TPMR)
+#endif
+
+	// PCI Memory Region (TOUUD - 64G)
+	QWORDMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
+			NonCacheable, ReadWrite,
+			0x00000000, 0x00000000, 0x1ffffffff, 0x00000000,
+			0x200000000,,, PM02)
+
+})	// End MCRS
+
+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)
+
+	// MMIO Low is saved in NVS
+	Store (\MMOB, PMIN)
+	Store (\MMOL, PMAX)
+	Add (Subtract (PMAX, PMIN), 1, PLEN)
+
+	// Find PCI resource area in MCRS
+	CreateQWordField(MCRS, ^PM02._MIN, P2MN)
+	CreateQWordField(MCRS, ^PM02._MAX, P2MX)
+	CreateQWordField(MCRS, ^PM02._LEN, P2LN)
+
+	// MMIO High is saved in NVS
+	Store(\MMHB, P2MN)
+	Store(\MMHL, P2MX)
+	Add(Subtract(P2MX,P2MN),1,P2LN)
+
+	Return (MCRS)
+}	// End _CRS
+
+/* PCI Device Resource Consumption */
+Device (PDRC)
+{
+	Name (_HID, EISAID("PNP0C02"))
+	Name (_UID, 1)
+
+	Name (PDRS, ResourceTemplate() {
+		// PCIEXBAR memory range
+		Memory32Fixed(ReadOnly, DEFAULT_PCIEXBAR, 0x10000000)
+		// TSEG
+		Memory32Fixed(ReadOnly, 0x00000000, 0x00000000, TSMB)
+	})
+
+	// Current Resource Settings
+	Method (_CRS, 0, Serialized)
+	{
+		// Fix up 32-bit TSEG
+		CreateDWordField(PDRS, ^TSMB._BAS, TSMN)
+		Store(\TSGB, TSMN)
+		CreateDWordField(PDRS, ^TSMB._LEN, TSLN)
+		Store(\TSSZ, TSLN)
+		Return(PDRS)
+	}
+}
+
+// Global Registers
+Device (GREG) {
+	Name   (_ADR, 0x00040000)
+}
+
+// Root Complex Event Collector
+Device (RCEC) {
+	Name   (_ADR, 0x00050000)
+}
+
+// Virtual root port 2
+Device (VRP2) {
+	Name   (_ADR, 0x00060000)
+}
diff --git a/src/soc/intel/denverton_ns/acpi/npk.asl b/src/soc/intel/denverton_ns/acpi/npk.asl
new file mode 100644
index 0000000..dfb5d9c
--- /dev/null
+++ b/src/soc/intel/denverton_ns/acpi/npk.asl
@@ -0,0 +1,28 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2016 - 2017 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 NPK Controller 0:1f.7
+
+Device (NPK0)
+{
+	Name (_ADR, 0x001f0007)
+
+	// Northpeak DFX
+	Method(_STA, 0, NotSerialized)
+	{
+		Return(0x0B)
+	}
+}
diff --git a/src/soc/intel/denverton_ns/acpi/pcie.asl b/src/soc/intel/denverton_ns/acpi/pcie.asl
new file mode 100644
index 0000000..cb14cf8
--- /dev/null
+++ b/src/soc/intel/denverton_ns/acpi/pcie.asl
@@ -0,0 +1,298 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007 - 2009 coresystems GmbH
+ * Copyright (C) 2012 The Chromium OS Authors.  All Rights Reserved.
+ * Copyright (C) 2014 - 2017 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 6/7 Series PCH PCIe support */
+
+// PCI Express Ports
+
+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.LPCB.LNKA, 0 },
+		Package() { 0x0000ffff, 1, \_SB.PCI0.LPCB.LNKB, 0 },
+		Package() { 0x0000ffff, 2, \_SB.PCI0.LPCB.LNKC, 0 },
+		Package() { 0x0000ffff, 3, \_SB.PCI0.LPCB.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.LPCB.LNKB, 0 },
+		Package() { 0x0000ffff, 1, \_SB.PCI0.LPCB.LNKC, 0 },
+		Package() { 0x0000ffff, 2, \_SB.PCI0.LPCB.LNKD, 0 },
+		Package() { 0x0000ffff, 3, \_SB.PCI0.LPCB.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.LPCB.LNKC, 0 },
+		Package() { 0x0000ffff, 1, \_SB.PCI0.LPCB.LNKD, 0 },
+		Package() { 0x0000ffff, 2, \_SB.PCI0.LPCB.LNKA, 0 },
+		Package() { 0x0000ffff, 3, \_SB.PCI0.LPCB.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.LPCB.LNKD, 0 },
+		Package() { 0x0000ffff, 1, \_SB.PCI0.LPCB.LNKA, 0 },
+		Package() { 0x0000ffff, 2, \_SB.PCI0.LPCB.LNKB, 0 },
+		Package() { 0x0000ffff, 3, \_SB.PCI0.LPCB.LNKC, 0 } })
+
+	/* Interrupt Map INTA->INTE, INTB->INTF, INTC->INTG, INTD->INTH */
+	Name (IQEA, Package() {
+		Package() { 0x0000ffff, 0, 0, 20 },
+		Package() { 0x0000ffff, 1, 0, 21 },
+		Package() { 0x0000ffff, 2, 0, 22 },
+		Package() { 0x0000ffff, 3, 0, 23 } })
+	Name (IQEP, Package() {
+		Package() { 0x0000ffff, 0, \_SB.PCI0.LPCB.LNKE, 0 },
+		Package() { 0x0000ffff, 1, \_SB.PCI0.LPCB.LNKF, 0 },
+		Package() { 0x0000ffff, 2, \_SB.PCI0.LPCB.LNKG, 0 },
+		Package() { 0x0000ffff, 3, \_SB.PCI0.LPCB.LNKH, 0 } })
+
+	/* Interrupt Map INTA->INTF, INTB->INTG, INTC->INTH, INTD->INTE */
+	Name (IQFA, Package() {
+		Package() { 0x0000ffff, 0, 0, 21 },
+		Package() { 0x0000ffff, 1, 0, 22 },
+		Package() { 0x0000ffff, 2, 0, 23 },
+		Package() { 0x0000ffff, 3, 0, 20 } })
+	Name (IQFP, Package() {
+		Package() { 0x0000ffff, 0, \_SB.PCI0.LPCB.LNKF, 0 },
+		Package() { 0x0000ffff, 1, \_SB.PCI0.LPCB.LNKG, 0 },
+		Package() { 0x0000ffff, 2, \_SB.PCI0.LPCB.LNKH, 0 },
+		Package() { 0x0000ffff, 3, \_SB.PCI0.LPCB.LNKE, 0 } })
+
+	/* Interrupt Map INTA->INTG, INTB->INTH, INTC->INTE, INTD->INTF */
+	Name (IQGA, Package() {
+		Package() { 0x0000ffff, 0, 0, 22 },
+		Package() { 0x0000ffff, 1, 0, 23 },
+		Package() { 0x0000ffff, 2, 0, 20 },
+		Package() { 0x0000ffff, 3, 0, 21 } })
+	Name (IQGP, Package() {
+		Package() { 0x0000ffff, 0, \_SB.PCI0.LPCB.LNKG, 0 },
+		Package() { 0x0000ffff, 1, \_SB.PCI0.LPCB.LNKH, 0 },
+		Package() { 0x0000ffff, 2, \_SB.PCI0.LPCB.LNKE, 0 },
+		Package() { 0x0000ffff, 3, \_SB.PCI0.LPCB.LNKF, 0 } })
+
+	/* Interrupt Map INTA->INTH, INTB->INTE, INTC->INTF, INTD->INTG */
+	Name (IQHA, Package() {
+		Package() { 0x0000ffff, 0, 0, 23 },
+		Package() { 0x0000ffff, 1, 0, 20 },
+		Package() { 0x0000ffff, 2, 0, 21 },
+		Package() { 0x0000ffff, 3, 0, 22 } })
+	Name (IQHP, Package() {
+		Package() { 0x0000ffff, 0, \_SB.PCI0.LPCB.LNKH, 0 },
+		Package() { 0x0000ffff, 1, \_SB.PCI0.LPCB.LNKE, 0 },
+		Package() { 0x0000ffff, 2, \_SB.PCI0.LPCB.LNKF, 0 },
+		Package() { 0x0000ffff, 3, \_SB.PCI0.LPCB.LNKG, 0 } })
+
+	Switch (ToInteger (Arg0)) {
+		/* PCIe Root Port 1 */
+		Case (Package() { 1 }) {
+			If (PICM) {
+				Return (IQAA)
+			} Else {
+				Return (IQAP)
+			}
+		}
+
+		/* PCIe Root Port 2 */
+		Case (Package() { 2 }) {
+			If (PICM) {
+				Return (IQBA)
+			} Else {
+				Return (IQBP)
+			}
+		}
+
+		/* PCIe Root Port 3 */
+		Case (Package() { 3 }) {
+			If (PICM) {
+				Return (IQCA)
+			} Else {
+				Return (IQCP)
+			}
+		}
+
+		/* PCIe Root Port 4 */
+		Case (Package() { 4 }) {
+			If (PICM) {
+				Return (IQDA)
+			} Else {
+				Return (IQDP)
+			}
+		}
+
+		/* PCIe Root Port 5 */
+		Case (Package() { 5 }) {
+			If (PICM) {
+				Return (IQEA)
+			} Else {
+				Return (IQEP)
+			}
+		}
+
+		/* PCIe Root Port 6 */
+		Case (Package() { 6 }) {
+			If (PICM) {
+				Return (IQFA)
+			} Else {
+				Return (IQFP)
+			}
+		}
+
+		/* PCIe Root Port 7 */
+		Case (Package() { 7 }) {
+			If (PICM) {
+				Return (IQGA)
+			} Else {
+				Return (IQGP)
+			}
+		}
+
+		/* PCIe Root Port 8 */
+		Case (Package() { 8 }) {
+			If (PICM) {
+				Return (IQHA)
+			} Else {
+				Return (IQHP)
+			}
+		}
+
+		Default {
+			If (PICM) {
+				Return (IQDA)
+			} Else {
+				Return (IQDP)
+			}
+		}
+	}
+}
+
+Device (RP01)
+{
+	Name (_ADR, 0x00090000)
+
+	#include "pcie_port.asl"
+
+	Method (_PRT)
+	{
+		Return (IRQM (RPPN))
+	}
+}
+
+Device (RP02)
+{
+	Name (_ADR, 0x000A0000)
+
+	#include "pcie_port.asl"
+
+	Method (_PRT)
+	{
+		Return (IRQM (RPPN))
+	}
+}
+
+Device (RP03)
+{
+	Name (_ADR, 0x000B0000)
+
+	#include "pcie_port.asl"
+
+	Method (_PRT)
+	{
+		Return (IRQM (RPPN))
+	}
+}
+
+Device (RP04)
+{
+	Name (_ADR, 0x000C0000)
+
+	#include "pcie_port.asl"
+
+	Method (_PRT)
+	{
+		Return (IRQM (RPPN))
+	}
+}
+
+Device (RP05)
+{
+	Name (_ADR, 0x000E0000)
+
+	#include "pcie_port.asl"
+
+	Method (_PRT)
+	{
+		Return (IRQM (RPPN))
+	}
+}
+
+Device (RP06)
+{
+	Name (_ADR, 0x000F0000)
+
+	#include "pcie_port.asl"
+
+	Method (_PRT)
+	{
+		Return (IRQM (RPPN))
+	}
+}
+
+Device (RP07)
+{
+	Name (_ADR, 0x00100000)
+
+	#include "pcie_port.asl"
+
+	Method (_PRT)
+	{
+		Return (IRQM (RPPN))
+	}
+}
+
+Device (RP08)
+{
+	Name (_ADR, 0x00110000)
+
+	#include "pcie_port.asl"
+
+	Method (_PRT)
+	{
+		Return (IRQM (RPPN))
+	}
+}
diff --git a/src/soc/intel/denverton_ns/acpi/pcie_port.asl b/src/soc/intel/denverton_ns/acpi/pcie_port.asl
new file mode 100644
index 0000000..e0132ca
--- /dev/null
+++ b/src/soc/intel/denverton_ns/acpi/pcie_port.asl
@@ -0,0 +1,26 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2012 The Chromium OS Authors.  All Rights Reserved.
+ * Copyright (C) 2014 - 2017 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.
+ *
+ */
+
+/* Included in each PCIe Root Port device */
+
+OperationRegion (RPCS, PCI_Config, 0x00, 0xFF)
+Field (RPCS, AnyAcc, NoLock, Preserve)
+{
+	Offset (0x4c),	// Link Capabilities
+	, 24,
+	RPPN, 8,	// Root Port Number
+}
diff --git a/src/soc/intel/denverton_ns/acpi/pmc.asl b/src/soc/intel/denverton_ns/acpi/pmc.asl
new file mode 100644
index 0000000..1b85ac8
--- /dev/null
+++ b/src/soc/intel/denverton_ns/acpi/pmc.asl
@@ -0,0 +1,39 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 - 2017 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 PMC Controller 0:1f.2
+
+Device (PMC0)
+{
+	Name (_ADR, 0x001F0002)
+
+	Device(PDRC)	// PMC Device Resource Consumption
+	{
+		Name(_HID,EISAID("PNP0C02"))
+		Name(_UID, 0x10)
+
+		Name(PMCR,ResourceTemplate()
+		{
+			IO (Decode16, DEFAULT_PMBASE, DEFAULT_PMBASE, 0x1, 0x80)	// ACPI Base
+			Memory32Fixed(ReadOnly, DEFAULT_PWRM_BASE, 0x1000) // PMC memory range
+		})
+
+		Method(_CRS, 0)
+		{
+			return(PMCR)
+		}
+	}
+}
diff --git a/src/soc/intel/denverton_ns/acpi/sata.asl b/src/soc/intel/denverton_ns/acpi/sata.asl
new file mode 100644
index 0000000..a210bcc
--- /dev/null
+++ b/src/soc/intel/denverton_ns/acpi/sata.asl
@@ -0,0 +1,24 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 - 2017 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 SATA Controller 0:13.0
+
+Device (SATA)
+{
+	Name (_ADR, 0x00130000)
+
+	/* TODO */
+}
diff --git a/src/soc/intel/denverton_ns/acpi/sata2.asl b/src/soc/intel/denverton_ns/acpi/sata2.asl
new file mode 100644
index 0000000..46be4e4
--- /dev/null
+++ b/src/soc/intel/denverton_ns/acpi/sata2.asl
@@ -0,0 +1,24 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 - 2017 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 SATA Controller 0:14.0
+
+Device (SAT2)
+{
+	Name (_ADR, 0x00140000)
+
+	/* TODO */
+}
diff --git a/src/soc/intel/denverton_ns/acpi/sleepstates.asl b/src/soc/intel/denverton_ns/acpi/sleepstates.asl
new file mode 100644
index 0000000..7da8413
--- /dev/null
+++ b/src/soc/intel/denverton_ns/acpi/sleepstates.asl
@@ -0,0 +1,22 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007 - 2009 coresystems GmbH
+ * Copyright (C) 2014 - 2017 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(\_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/denverton_ns/acpi/smbus.asl b/src/soc/intel/denverton_ns/acpi/smbus.asl
new file mode 100644
index 0000000..ca0e963
--- /dev/null
+++ b/src/soc/intel/denverton_ns/acpi/smbus.asl
@@ -0,0 +1,237 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007 - 2009 coresystems GmbH
+ * Copyright (C) 2014 - 2017 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.4
+
+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/denverton_ns/acpi/smbus2.asl b/src/soc/intel/denverton_ns/acpi/smbus2.asl
new file mode 100644
index 0000000..4b315de
--- /dev/null
+++ b/src/soc/intel/denverton_ns/acpi/smbus2.asl
@@ -0,0 +1,24 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 - 2017 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:12.0
+
+Device (SMB2)
+{
+	Name (_ADR, 0x00120000)
+
+	/* TODO */
+}
diff --git a/src/soc/intel/denverton_ns/acpi/southcluster.asl b/src/soc/intel/denverton_ns/acpi/southcluster.asl
new file mode 100644
index 0000000..bcc8a5c
--- /dev/null
+++ b/src/soc/intel/denverton_ns/acpi/southcluster.asl
@@ -0,0 +1,148 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007 - 2009 coresystems GmbH
+ * Copyright (C) 2014 - 2017 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 "../include/soc/iomap.h"
+
+Scope(\)
+{
+	// 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
+	}
+
+	// Private Chipset Register(PCR). Memory Mapped through ILB
+	OperationRegion(PCRR, SystemMemory, DEFAULT_PCR_BASE, 0x01000000)
+	Field(PCRR, DWordAcc, Lock, Preserve)
+	{
+		Offset (0xD03100),	// Interrupt Routing Registers
+		PRTA,	8,
+		PRTB,	8,
+		PRTC,	8,
+		PRTD,	8,
+		PRTE,	8,
+		PRTF,	8,
+		PRTG,	8,
+		PRTH,	8,
+	}
+}
+
+// PCI Express Ports 0:[9-11].0
+#include "pcie.asl"
+
+// SMBus 0:12.0
+#include "smbus2.asl"
+
+// SATA 0:13.0
+#include "sata.asl"
+
+// SATA 0:14.0
+#include "sata2.asl"
+
+// xHCI 0:15.0
+#include "xhci.asl"
+
+// Virtual root port 0
+Device (VRP0) {
+	Name   (_ADR, 0x00160000)
+}
+
+// Virtual root port 1
+Device (VRP1) {
+	Name   (_ADR, 0x00170000)
+}
+
+// ME HECI
+Device (HECI) {
+	Name   (_ADR, 0x00180000)
+}
+
+// ME HECI2
+Device (HEC2) {
+	Name   (_ADR, 0x00180001)
+}
+
+// MEKT on PCH
+Device (MEKT) {
+	Name   (_ADR, 0x00180003)
+}
+
+// ME HECI3
+Device (HEC3) {
+	Name   (_ADR, 0x00180004)
+}
+
+// UART 0
+Device (UAR0) {
+	Name   (_ADR, 0x001A0000)
+}
+
+// UART 1
+Device (UAR1) {
+	Name   (_ADR, 0x001A0001)
+}
+
+// UART 2
+Device (UAR2) {
+	Name   (_ADR, 0x001A0002)
+}
+
+// eMMC
+Device (EMMC) {
+	Name   (_ADR, 0x001C0000)
+}
+
+// LPC Bridge 0:1f.0
+#include "lpc.asl"
+
+// P2SB 0:1f.1
+Device (P2SB)
+{
+	Name (_ADR, 0x001F0001)
+}
+
+// PMC 0:1f.2
+#include "pmc.asl"
+
+// SMBus 0:1f.4
+#include "smbus.asl"
+
+// Northpeak 0:1f.7
+#include "npk.asl"
+
+/* IRQ assignment is mainboard specific. Get it from mainboard ACPI code */
+#include "acpi/mainboard_pci_irqs.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/denverton_ns/acpi/xhci.asl b/src/soc/intel/denverton_ns/acpi/xhci.asl
new file mode 100644
index 0000000..8f29aba
--- /dev/null
+++ b/src/soc/intel/denverton_ns/acpi/xhci.asl
@@ -0,0 +1,45 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007 - 2009 coresystems GmbH
+ * Copyright (C) 2014 - 2017 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:15.0
+
+Device (XHC1)
+{
+	Name(_ADR, 0x00150000)
+
+	Name (_PRW, Package(){ 0x0D, 3 }) // Power Resources for Wake
+
+	// Leave USB ports on for to allow Wake from USB
+
+	Method(_S3D,0)	// Highest D State in S3 State
+	{
+		Return (2)
+	}
+
+	Device (HUB7)
+	{
+		Name (_ADR, 0x00000000)
+
+		// How many are there?
+		Device (PRT1) { Name (_ADR, 1) } // USB Port 0
+		Device (PRT2) { Name (_ADR, 2) } // USB Port 1
+		Device (PRT3) { Name (_ADR, 3) } // USB Port 2
+		Device (PRT4) { Name (_ADR, 4) } // USB Port 3
+		Device (PRT5) { Name (_ADR, 5) } // USB Port 4
+		Device (PRT6) { Name (_ADR, 6) } // USB Port 5
+	}
+}
diff --git a/src/soc/intel/denverton_ns/bootblock/bootblock.c b/src/soc/intel/denverton_ns/bootblock/bootblock.c
new file mode 100644
index 0000000..6179bf7
--- /dev/null
+++ b/src/soc/intel/denverton_ns/bootblock/bootblock.c
@@ -0,0 +1,72 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2016 - 2017 Intel Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <arch/cpu.h>
+#include <bootblock_common.h>
+#include <cpu/x86/mtrr.h>
+#include <device/pci.h>
+#include <FsptUpd.h>
+#include <intelblocks/fast_spi.h>
+#include <lib.h>
+#include <soc/bootblock.h>
+#include <soc/iomap.h>
+#include <spi-generic.h>
+#include <timestamp.h>
+#include <console/console.h>
+
+const FSPT_UPD temp_ram_init_params = {
+	.FspUpdHeader = {
+			.Signature = 0x545F445055564E44ULL,
+			.Revision = 1,
+			.Reserved = {0},
+	},
+	.FsptCoreUpd = {
+			.MicrocodeRegionBase =
+				(UINT32)CONFIG_CPU_MICROCODE_CBFS_LOC,
+			.MicrocodeRegionLength =
+				(UINT32)CONFIG_CPU_MICROCODE_CBFS_LEN,
+			.CodeRegionBase =
+				(UINT32)(0x100000000ULL - CONFIG_CBFS_SIZE),
+			.CodeRegionLength = (UINT32)CONFIG_CBFS_SIZE,
+			.Reserved1 = {0},
+	},
+	.FsptConfig = {
+			.PcdFsptPort80RouteDisable = 0,
+			.ReservedTempRamInitUpd = {0},
+	},
+	.UnusedUpdSpace0 = {0},
+	.UpdTerminator = 0x55AA,
+};
+
+asmlinkage void bootblock_c_entry(uint64_t base_timestamp)
+{
+	/* Call lib/bootblock.c main */
+	bootblock_main_with_timestamp(base_timestamp);
+};
+
+void bootblock_soc_early_init(void)
+{
+
+#if (IS_ENABLED(CONFIG_CONSOLE_SERIAL))
+	early_uart_init();
+#endif
+};
+
+void bootblock_soc_init(void)
+{
+	if (IS_ENABLED(CONFIG_BOOTBLOCK_CONSOLE))
+		printk(BIOS_DEBUG, "FSP TempRamInit successful...\n");
+};
diff --git a/src/soc/intel/denverton_ns/bootblock/cache_as_ram_fsp.S b/src/soc/intel/denverton_ns/bootblock/cache_as_ram_fsp.S
new file mode 100644
index 0000000..b998c21
--- /dev/null
+++ b/src/soc/intel/denverton_ns/bootblock/cache_as_ram_fsp.S
@@ -0,0 +1,122 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 - 2017 Intel Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <device/pci_def.h>
+#include <cpu/x86/mtrr.h>
+#include <cpu/x86/cache.h>
+#include <cpu/x86/cr.h>
+#include <cpu/x86/post_code.h>
+
+#include <../../../arch/x86/walkcbfs.S>
+
+#define FSP_HDR_OFFSET 0x94
+
+.extern	temp_ram_init_params
+
+.global	bootblock_pre_c_entry
+bootblock_pre_c_entry:
+
+.global	cache_as_ram
+cache_as_ram:
+	post_code(0x2f)
+
+	/* find fsp in cbfs */
+	lea	fsp_name, %esi
+	mov	$1f, %esp
+	jmp	walkcbfs_asm
+1:
+	cmp	$0, %eax
+	jz	.halt_forever
+	mov	CBFS_FILE_OFFSET(%eax), %ebx
+	bswap	%ebx
+	add	%eax, %ebx
+
+	addl	$FSP_HDR_OFFSET, %ebx
+
+	/*
+	 * save mm2 into ebp, because TempRamInit API doesn't preserve
+	 * mm2 register
+	 */
+	movd	%mm2, %ebp
+
+	/*
+	 * ebx = FSP INFO HEADER
+	 * Calculate entry into FSP
+	 */
+	movl	0x30(%ebx), %eax	/* Load TempRamInitEntryOffset */
+	addl	0x1c(%ebx), %eax	/* add the FSP ImageBase */
+
+	/*
+	 * Pass early init variables on a fake stack (no memory yet)
+	 * as well as the return location
+	 */
+	leal	CAR_init_stack, %esp
+
+	/* call FSP binary to setup temporary stack */
+	jmp	*%eax
+
+/*
+ * If the TempRamInit API is successful, then when returning, the ECX and
+ * EDX registers will point to the temporary but writeable memory range
+ * available to the bootloader where ECX is the start and EDX is the end of
+ * the range i.e. [ECX,EDX).  See Denverton_ns FSP Integration Guide for more
+ * information.
+ *
+ * Return Values:
+ * EAX | Return Status
+ * ECX | Temporary Memory Start
+ * EDX | Temporary Memory End
+ * EBX, EDI, ESI, EBP, MM0, MM1 | Preserved Through API Call
+ */
+
+CAR_init_done:
+	cmp	$0, %eax
+	jnz	.halt_forever
+
+	/* clear CAR_GLOBAL area as it is not shared */
+	cld
+	xor     %eax, %eax
+	movl    $(_car_global_end), %ecx
+	movl    $(_car_global_start), %edi
+	sub     %edi, %ecx
+	shrl	$2, %ecx
+	rep     stosl
+
+	/* Setup bootblock stack */
+	movl    $(_car_stack_end), %esp
+
+	/* Restore the timestamp from bootblock_crt0.S (ebp:mm1) */
+	push	%ebp
+	movd    %mm1, %eax
+	push    %eax
+
+	/* We can call into C functions now */
+	call	bootblock_c_entry
+
+	/* Never reached */
+
+.halt_forever:
+	post_code(POST_DEAD_CODE)
+	hlt
+	jmp	.halt_forever
+
+	.align	4
+CAR_init_stack:
+	.long	CAR_init_done
+	.long	temp_ram_init_params
+
+fsp_name:
+	.ascii	"fspt.bin\x00"
diff --git a/src/soc/intel/denverton_ns/bootblock/uart.c b/src/soc/intel/denverton_ns/bootblock/uart.c
new file mode 100644
index 0000000..bad16de
--- /dev/null
+++ b/src/soc/intel/denverton_ns/bootblock/uart.c
@@ -0,0 +1,198 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2016 - 2017 Intel Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <arch/io.h>
+#include <device/pci_def.h>
+#include <fsp/soc_binding.h>
+#include <commonlib/helpers.h>
+
+#include <soc/bootblock.h>
+#include <soc/gpio_defs.h>
+#include <soc/uart.h>
+
+static uint16_t legacy_uart_ioadr_tab[] = {0x3F8, 0x2F8, 0x3E8, 0x2E8};
+
+#define ELEM_OF_UART_TAB ARRAY_SIZE(legacy_uart_ioadr_tab)
+
+static void pci_early_hsuart_device_probe(u8 bus, u8 dev, u8 func,
+					  u32 mmio_base)
+{
+	register uint16_t reg16;
+
+	device_t uart_dev = PCI_DEV(bus, dev, func);
+
+	/* We're using MMIO for HSUARTs. This section is needed for logging
+	*  from FSP only
+	*/
+	/* Decode IOBASE at IOBA (BAR0). */
+	reg16 = pci_read_config16(uart_dev, PCI_BASE_ADDRESS_0) | mmio_base;
+	pci_write_config16(uart_dev, PCI_BASE_ADDRESS_0, reg16);
+
+#if (IS_ENABLED(CONFIG_NON_LEGACY_UART_MODE))
+	/* Decode MMIO at MEMBA (BAR1) */
+	pci_write_config32(uart_dev, PCI_BASE_ADDRESS_1,
+			   CONFIG_CONSOLE_UART_BASE_ADDRESS +
+				   SIZE_OF_HSUART_RES * func);
+#endif
+
+	/* Enable memory/io space and allow to initiate
+	 * a transaction as a master
+	 */
+	pci_write_config16(uart_dev, PCI_COMMAND,
+			   pci_read_config16(uart_dev, PCI_COMMAND) |
+#if (IS_ENABLED(CONFIG_NON_LEGACY_UART_MODE))
+			   PCI_COMMAND_MEMORY |
+#endif
+				   PCI_COMMAND_MASTER | PCI_COMMAND_IO);
+
+#if (IS_ENABLED(CONFIG_CONSOLE_SERIAL_230400))
+	/* Change the highest speed to 230400 */
+	uint32_t *psr_reg =
+		(uint32_t *)(CONFIG_CONSOLE_UART_BASE_ADDRESS +
+			     SIZE_OF_HSUART_RES * func + PSR_OFFSET);
+	*psr_reg >>= 1;
+#endif
+
+#if (IS_ENABLED(CONFIG_LEGACY_UART_MODE))
+	/* Hide HSUART on PCI to prevent re-enumeration
+	 * and enable legacy mode.
+	 */
+	pci_write_config32(uart_dev, PCI_FUNC_RDCFG_HIDE,
+			   pci_read_config32(uart_dev, PCI_FUNC_RDCFG_HIDE) |
+			       1);
+#endif
+}
+
+static void early_config_gpio(void)
+{
+	uint32_t reg32;
+
+	// HSUART0:
+	// UART0_RXD
+	reg32 = read32(
+		(void *)PCH_PCR_ADDRESS(PID_GPIOCOM1, R_PAD_CFG_DW0_UART0_RXD));
+	if (((reg32 & B_PCH_GPIO_PAD_MODE) >> N_PCH_GPIO_PAD_MODE) !=
+	    V_PCH_GPIO_PAD_MODE_NAT_1) {
+		reg32 &= ~B_PCH_GPIO_PAD_MODE;
+		reg32 |= (UINT32)(V_PCH_GPIO_PAD_MODE_NAT_1
+				  << N_PCH_GPIO_PAD_MODE);
+		write32((void *)PCH_PCR_ADDRESS(PID_GPIOCOM1,
+						R_PAD_CFG_DW0_UART0_RXD),
+			reg32);
+	}
+	// UART0_TXD
+	reg32 = read32(
+		(void *)PCH_PCR_ADDRESS(PID_GPIOCOM1, R_PAD_CFG_DW0_UART0_TXD));
+	if (((reg32 & B_PCH_GPIO_PAD_MODE) >> N_PCH_GPIO_PAD_MODE) !=
+	    V_PCH_GPIO_PAD_MODE_NAT_1) {
+		reg32 &= ~B_PCH_GPIO_PAD_MODE;
+		reg32 |= (UINT32)(V_PCH_GPIO_PAD_MODE_NAT_1
+				  << N_PCH_GPIO_PAD_MODE);
+		write32((void *)PCH_PCR_ADDRESS(PID_GPIOCOM1,
+						R_PAD_CFG_DW0_UART0_TXD),
+			reg32);
+	}
+	// UART0_CTS
+	reg32 = read32((void *)PCH_PCR_ADDRESS(PID_GPIOCOM1,
+					       R_PAD_CFG_DW0_SMB3_CLTT_CLK));
+	if (((reg32 & B_PCH_GPIO_PAD_MODE) >> N_PCH_GPIO_PAD_MODE) !=
+	    V_PCH_GPIO_PAD_MODE_NAT_2) {
+		reg32 &= ~B_PCH_GPIO_PAD_MODE;
+		reg32 |= (UINT32)(V_PCH_GPIO_PAD_MODE_NAT_2
+				  << N_PCH_GPIO_PAD_MODE);
+		write32((void *)PCH_PCR_ADDRESS(PID_GPIOCOM1,
+						R_PAD_CFG_DW0_SMB3_CLTT_CLK),
+			reg32);
+	}
+	// UART0_RTS
+	reg32 = read32((void *)PCH_PCR_ADDRESS(PID_GPIOCOM1,
+					       R_PAD_CFG_DW0_PCIE_CLKREQ5_N));
+	if (((reg32 & B_PCH_GPIO_PAD_MODE) >> N_PCH_GPIO_PAD_MODE) !=
+	    V_PCH_GPIO_PAD_MODE_NAT_3) {
+		reg32 &= ~B_PCH_GPIO_PAD_MODE;
+		reg32 |= (UINT32)(V_PCH_GPIO_PAD_MODE_NAT_3
+				  << N_PCH_GPIO_PAD_MODE);
+		write32((void *)PCH_PCR_ADDRESS(PID_GPIOCOM1,
+						R_PAD_CFG_DW0_PCIE_CLKREQ5_N),
+			reg32);
+	}
+
+	// HSUART1:
+	// UART1_RXD
+	reg32 = read32(
+		(void *)PCH_PCR_ADDRESS(PID_GPIOCOM1, R_PAD_CFG_DW0_UART1_RXD));
+	if (((reg32 & B_PCH_GPIO_PAD_MODE) >> N_PCH_GPIO_PAD_MODE) !=
+	    V_PCH_GPIO_PAD_MODE_NAT_1) {
+		reg32 &= ~B_PCH_GPIO_PAD_MODE;
+		reg32 |= (UINT32)(V_PCH_GPIO_PAD_MODE_NAT_1
+				  << N_PCH_GPIO_PAD_MODE);
+		write32((void *)PCH_PCR_ADDRESS(PID_GPIOCOM1,
+						R_PAD_CFG_DW0_UART1_RXD),
+			reg32);
+	}
+	// UART1_TXD
+	reg32 = read32(
+		(void *)PCH_PCR_ADDRESS(PID_GPIOCOM1, R_PAD_CFG_DW0_UART1_TXD));
+	if (((reg32 & B_PCH_GPIO_PAD_MODE) >> N_PCH_GPIO_PAD_MODE) !=
+	    V_PCH_GPIO_PAD_MODE_NAT_1) {
+		reg32 &= ~B_PCH_GPIO_PAD_MODE;
+		reg32 |= (UINT32)(V_PCH_GPIO_PAD_MODE_NAT_1
+				  << N_PCH_GPIO_PAD_MODE);
+		write32((void *)PCH_PCR_ADDRESS(PID_GPIOCOM1,
+						R_PAD_CFG_DW0_UART1_TXD),
+			reg32);
+	}
+	// UART1_CTS
+	reg32 = read32((void *)PCH_PCR_ADDRESS(PID_GPIOCOM1,
+					       R_PAD_CFG_DW0_SATA1_SDOUT));
+	if (((reg32 & B_PCH_GPIO_PAD_MODE) >> N_PCH_GPIO_PAD_MODE) !=
+	    V_PCH_GPIO_PAD_MODE_NAT_1) {
+		reg32 &= ~B_PCH_GPIO_PAD_MODE;
+		reg32 |= (UINT32)(V_PCH_GPIO_PAD_MODE_NAT_1
+				  << N_PCH_GPIO_PAD_MODE);
+		write32((void *)PCH_PCR_ADDRESS(PID_GPIOCOM1,
+						R_PAD_CFG_DW0_SATA1_SDOUT),
+			reg32);
+	}
+	// UART1_RTS
+	reg32 = read32((void *)PCH_PCR_ADDRESS(PID_GPIOCOM1,
+					       R_PAD_CFG_DW0_SATA0_SDOUT));
+	if (((reg32 & B_PCH_GPIO_PAD_MODE) >> N_PCH_GPIO_PAD_MODE) !=
+	    V_PCH_GPIO_PAD_MODE_NAT_1) {
+		reg32 &= ~B_PCH_GPIO_PAD_MODE;
+		reg32 |= (UINT32)(V_PCH_GPIO_PAD_MODE_NAT_1
+				  << N_PCH_GPIO_PAD_MODE);
+		write32((void *)PCH_PCR_ADDRESS(PID_GPIOCOM1,
+						R_PAD_CFG_DW0_SATA0_SDOUT),
+			reg32);
+	}
+}
+
+void early_uart_init(void)
+{
+	register int i;
+
+	/* Check: do we have enought elements to init. ? */
+	BUILD_BUG_ON(HARCUVAR_UARTS_TO_INI > ELEM_OF_UART_TAB);
+
+	/* HSUART(B0:D26:0-1) GPIO init. */
+	early_config_gpio();
+
+	for (i = HARCUVAR_UARTS_TO_INI - 1; i >= 0; --i) {
+		pci_early_hsuart_device_probe(0, CONFIG_HSUART_DEV, i,
+					      legacy_uart_ioadr_tab[i]);
+	}
+}
diff --git a/src/soc/intel/denverton_ns/chip.c b/src/soc/intel/denverton_ns/chip.c
new file mode 100644
index 0000000..9547bec
--- /dev/null
+++ b/src/soc/intel/denverton_ns/chip.c
@@ -0,0 +1,167 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 - 2017 Intel Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <arch/acpi.h>
+#include <bootstate.h>
+#include <cbfs.h>
+#include <cbmem.h>
+#include <console/console.h>
+#include <cpu/cpu.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <fsp/api.h>
+#include <fsp/util.h>
+#include <intelblocks/fast_spi.h>
+#include <soc/iomap.h>
+#include <soc/intel/common/vbt.h>
+#include <soc/pci_devs.h>
+#include <soc/ramstage.h>
+#include <soc/fiamux.h>
+#include <spi-generic.h>
+#include <hsio.h>
+#include <harcuvar_boardid.h>
+
+static void pci_domain_set_resources(device_t dev)
+{
+	assign_resources(dev->link_list);
+}
+
+static struct device_operations pci_domain_ops = {
+	.read_resources = &pci_domain_read_resources,
+	.set_resources = &pci_domain_set_resources,
+	.scan_bus = &pci_domain_scan_bus,
+	.ops_pci_bus = &pci_bus_default_ops,
+};
+
+static struct device_operations cpu_bus_ops = {
+	.read_resources = DEVICE_NOOP,
+	.set_resources = DEVICE_NOOP,
+	.enable_resources = DEVICE_NOOP,
+	.init = denverton_init_cpus,
+	.scan_bus = NULL,
+#if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES)
+	.acpi_fill_ssdt_generator = generate_cpu_entries,
+#endif
+};
+
+static void soc_enable_dev(device_t dev)
+{
+	/* Set the operations if it is a special bus type */
+	if (dev->path.type == DEVICE_PATH_DOMAIN)
+		dev->ops = &pci_domain_ops;
+	else if (dev->path.type == DEVICE_PATH_CPU_CLUSTER)
+		dev->ops = &cpu_bus_ops;
+}
+
+static void soc_init(void *data) { fsp_silicon_init(false); }
+
+static void soc_final(void *data) {}
+
+static void soc_silicon_init_params(FSPS_UPD *silupd)
+{
+	size_t num;
+	uint16_t supported_hsio_lanes;
+	uint8_t boardid = board_id();
+	BL_HSIO_INFORMATION *hsio_config;
+	BL_FIA_MUX_CONFIG_HOB *fiamux_hob_data = get_fiamux_hob_data();
+
+	/* Configure FIA MUX PCD */
+	supported_hsio_lanes =
+		(uint16_t)fiamux_hob_data->FiaMuxConfig.SkuNumLanesAllowed;
+
+	switch (boardid) {
+	case BoardIdHarcuvar:
+		num = ARRAY_SIZE(harcuvar_hsio_config);
+		hsio_config = (BL_HSIO_INFORMATION *)harcuvar_hsio_config;
+		break;
+	default:
+		num = 0;
+		hsio_config = NULL;
+		break;
+	}
+
+	if (get_fiamux_hsio_info(supported_hsio_lanes, num, &hsio_config))
+		die("HSIO Configuration is invalid, please correct it!");
+
+	/* Check the requested FIA MUX Configuration */
+	if (!(&hsio_config->FiaConfig)) {
+		die("Requested FIA MUX Configuration is invalid,"
+		    " please correct it!");
+	}
+
+	/* Initialize PCIE Bifurcation & HSIO configuration */
+	silupd->FspsConfig.PcdBifurcationPcie0 = hsio_config->PcieBifCtr[0];
+	silupd->FspsConfig.PcdBifurcationPcie1 = hsio_config->PcieBifCtr[1];
+
+	silupd->FspsConfig.PcdFiaMuxConfigRequestPtr =
+		(uint32_t)&hsio_config->FiaConfig;
+}
+
+void platform_fsp_silicon_init_params_cb(FSPS_UPD *silupd)
+{
+	const struct microcode *microcode_file;
+	size_t microcode_len;
+
+	microcode_file = cbfs_boot_map_with_leak("cpu_microcode_blob.bin",
+		CBFS_TYPE_MICROCODE, &microcode_len);
+
+	if ((microcode_file != NULL) && (microcode_len != 0)) {
+		/* Update CPU Microcode patch base address/size */
+		silupd->FspsConfig.PcdCpuMicrocodePatchBase =
+		       (uint32_t)microcode_file;
+		silupd->FspsConfig.PcdCpuMicrocodePatchSize =
+		       (uint32_t)microcode_len;
+	}
+
+	soc_silicon_init_params(silupd);
+	mainboard_silicon_init_params(silupd);
+}
+
+struct chip_operations soc_intel_denverton_ns_ops = {
+	CHIP_NAME("Intel Denverton-NS SOC")
+	.enable_dev = &soc_enable_dev,
+	.init = &soc_init,
+	.final = &soc_final
+};
+
+static void soc_set_subsystem(device_t dev, uint32_t vendor, uint32_t device)
+{
+	if (!vendor || !device) {
+		pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
+				   pci_read_config32(dev, PCI_VENDOR_ID));
+	} else {
+		pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
+				   ((device & 0xffff) << 16) |
+					   (vendor & 0xffff));
+	}
+}
+
+struct pci_operations soc_pci_ops = {
+	.set_subsystem = soc_set_subsystem,
+};
+
+/*
+ * spi_flash init() needs to run unconditionally on every boot (including
+ * resume) to allow write protect to be disabled for eventlog and nvram
+ * updates. This needs to be done as early as possible in ramstage. Thus, add a
+ * callback for entry into BS_PRE_DEVICE.
+ */
+static void spi_flash_init_cb(void *unused)
+{
+	fast_spi_init();
+}
+
+BOOT_STATE_INIT_ENTRY(BS_PRE_DEVICE, BS_ON_ENTRY, spi_flash_init_cb, NULL);
diff --git a/src/soc/intel/denverton_ns/chip.h b/src/soc/intel/denverton_ns/chip.h
new file mode 100644
index 0000000..bfa6a01
--- /dev/null
+++ b/src/soc/intel/denverton_ns/chip.h
@@ -0,0 +1,77 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 - 2017 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_INTEL_DENVERTON_NS_CHIP_H
+#define SOC_INTEL_DENVERTON_NS_CHIP_H
+
+struct soc_intel_denverton_ns_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;
+
+	/**
+	 * Device Interrupt Routing configuration
+	 * Interrupt Pin x Route.
+	 * 0h = PIRQA#
+	 * 1h = PIRQB#
+	 * 2h = PIRQC#
+	 * 3h = PIRQD#
+	 * 4h = PIRQE#
+	 * 5h = PIRQF#
+	 * 6h = PIRQG#
+	 * 7h = PIRQH#
+	 */
+	uint16_t ir00_routing;
+	uint16_t ir01_routing;
+	uint16_t ir02_routing;
+	uint16_t ir03_routing;
+	uint16_t ir04_routing;
+	uint16_t ir05_routing;
+	uint16_t ir06_routing;
+	uint16_t ir07_routing;
+	uint16_t ir08_routing;
+	uint16_t ir09_routing;
+	uint16_t ir10_routing;
+	uint16_t ir11_routing;
+	uint16_t ir12_routing;
+
+	/**
+	* Device Interrupt Polarity Control
+	* ipc0 - IRQ-00-31 - 1: Active low to IOAPIC, 0: Active high to IOAPIC
+	* ipc1 - IRQ-32-63 - 1: Active low to IOAPIC, 0: Active high to IOAPIC
+	* ipc2 - IRQ-64-95 - 1: Active low to IOAPIC, 0: Active high to IOAPIC
+	* ipc3 - IRQ-96-119 - 1: Active low to IOAPIC, 0: Active high to IOAPIC
+	*/
+	uint32_t ipc0;
+	uint32_t ipc1;
+	uint32_t ipc2;
+	uint32_t ipc3;
+};
+
+extern struct chip_operations soc_intel_denverton_ns_ops;
+
+typedef struct soc_intel_denverton_ns_config config_t;
+
+#endif /* SOC_INTEL_FSP_DENVERTON_NS_CHIP_H */
diff --git a/src/soc/intel/denverton_ns/cpu.c b/src/soc/intel/denverton_ns/cpu.c
new file mode 100644
index 0000000..b6c05e7
--- /dev/null
+++ b/src/soc/intel/denverton_ns/cpu.c
@@ -0,0 +1,254 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 - 2017 Intel Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <console/console.h>
+#include <cpu/cpu.h>
+#include <cpu/x86/cache.h>
+#include <cpu/x86/mp.h>
+#include <cpu/x86/msr.h>
+#include <cpu/x86/mtrr.h>
+#include <cpu/intel/turbo.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <reg_script.h>
+
+#include <soc/msr.h>
+#include <soc/cpu.h>
+#include <soc/iomap.h>
+#include <soc/smm.h>
+#include <soc/soc_util.h>
+
+static struct smm_relocation_attrs relo_attrs;
+
+static void denverton_core_init(device_t cpu)
+{
+	msr_t msr;
+
+	printk(BIOS_DEBUG, "Init Denverton-NS SoC cores.\n");
+
+	/* Enable Turbo */
+	enable_turbo();
+
+	/* Enable speed step. */
+	if (get_turbo_state() == TURBO_ENABLED) {
+		msr = rdmsr(MSR_IA32_MISC_ENABLES);
+		msr.lo |= SPEED_STEP_ENABLE_BIT;
+		wrmsr(MSR_IA32_MISC_ENABLES, msr);
+	}
+}
+
+static struct device_operations cpu_dev_ops = {
+	.init = denverton_core_init,
+};
+
+static struct cpu_device_id cpu_table[] = {
+	{X86_VENDOR_INTEL,
+	 CPUID_DENVERTON_A0_A1},		/* Denverton-NS A0/A1 CPUID */
+	{X86_VENDOR_INTEL, CPUID_DENVERTON_B0}, /* Denverton-NS B0 CPUID */
+	{0, 0},
+};
+
+static const struct cpu_driver driver __cpu_driver = {
+	.ops = &cpu_dev_ops,
+	.id_table = cpu_table,
+};
+
+/*
+ * MP and SMM loading initialization.
+ */
+
+static void relocation_handler(int cpu, uintptr_t curr_smbase,
+			       uintptr_t staggered_smbase)
+{
+	msr_t smrr;
+	em64t100_smm_state_save_area_t *smm_state;
+	(void)cpu;
+
+	/* Set up SMRR. */
+	smrr.lo = relo_attrs.smrr_base;
+	smrr.hi = 0;
+	wrmsr(SMRR_PHYS_BASE, smrr);
+	smrr.lo = relo_attrs.smrr_mask;
+	smrr.hi = 0;
+	wrmsr(SMRR_PHYS_MASK, smrr);
+	smm_state = (void *)(SMM_EM64T100_SAVE_STATE_OFFSET + curr_smbase);
+	smm_state->smbase = staggered_smbase;
+}
+
+static void get_smm_info(uintptr_t *perm_smbase, size_t *perm_smsize,
+			 size_t *smm_save_state_size)
+{
+	void *smm_base;
+	size_t smm_size;
+	void *handler_base;
+	size_t handler_size;
+
+	/* All range registers are aligned to 4KiB */
+	const uint32_t rmask = ~((1 << 12) - 1);
+
+	/* Initialize global tracking state. */
+	smm_region(&smm_base, &smm_size);
+	smm_subregion(SMM_SUBREGION_HANDLER, &handler_base, &handler_size);
+
+	relo_attrs.smbase = (uint32_t)smm_base;
+	relo_attrs.smrr_base = relo_attrs.smbase | MTRR_TYPE_WRBACK;
+	relo_attrs.smrr_mask = ~(smm_size - 1) & rmask;
+	relo_attrs.smrr_mask |= MTRR_PHYS_MASK_VALID;
+
+	*perm_smbase = (uintptr_t)handler_base;
+	*perm_smsize = handler_size;
+	*smm_save_state_size = sizeof(em64t100_smm_state_save_area_t);
+}
+
+static int detect_num_cpus_via_cpuid(void)
+{
+	register int ecx = 0;
+	struct cpuid_result leaf_b;
+
+	while (1) {
+		leaf_b = cpuid_ext(0xb, ecx);
+
+		/* Processor doesn't have hyperthreading so just determine the
+		* number of cores by from level type (ecx[15:8] == * 2). */
+		if ((leaf_b.ecx & 0xff00) == 0x0200)
+			break;
+		ecx++;
+	}
+	return (leaf_b.ebx & 0xffff);
+}
+
+static int detect_num_cpus_via_mch(void)
+{
+	/* Assumes that FSP has already programmed the cores disabled register
+	 */
+	u32 core_exists_mask, active_cores_mask;
+	u32 core_disable_mask;
+	register int active_cores = 0, total_cores = 0;
+	register int counter = 0;
+
+	/* Get Masks for Total Existing SOC Cores and Core Disable Mask */
+	core_exists_mask = MMIO32(DEFAULT_MCHBAR + MCH_BAR_CORE_EXISTS_MASK);
+	core_disable_mask = MMIO32(DEFAULT_MCHBAR + MCH_BAR_CORE_DISABLE_MASK);
+	active_cores_mask = (~core_disable_mask) & core_exists_mask;
+
+	/* Calculate Number of Active Cores */
+	for (; counter < CONFIG_MAX_CPUS;
+	     counter++, active_cores_mask >>= 1, core_exists_mask >>= 1) {
+		active_cores += (active_cores_mask & CORE_BIT_MSK);
+		total_cores += (core_exists_mask & CORE_BIT_MSK);
+	}
+
+	printk(BIOS_DEBUG, "Number of Active Cores: %d of %d total.\n",
+	       active_cores, total_cores);
+
+	return active_cores;
+}
+
+/* Find CPU topology */
+int get_cpu_count(void)
+{
+	int num_cpus = detect_num_cpus_via_mch();
+
+	if (num_cpus <= 0 || num_cpus > CONFIG_MAX_CPUS) {
+		num_cpus = detect_num_cpus_via_cpuid();
+		printk(BIOS_DEBUG, "Number of Cores (CPUID): %d.\n", num_cpus);
+	}
+	return num_cpus;
+}
+
+static 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;
+}
+
+static void set_max_turbo_freq(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);
+}
+
+/*
+ * Do essential initialization tasks before APs can be fired up
+ *
+ * 1. Prevent race condition in MTRR solution. Enable MTRRs on the BSP. This
+ * creates the MTRR solution that the APs will use. Otherwise APs will try to
+ * apply the incomplete solution as the BSP is calculating it.
+ */
+static void pre_mp_init(void)
+{
+	x86_setup_mtrrs_with_detect();
+	x86_mtrr_check();
+}
+
+static void post_mp_init(void)
+{
+	/* Set Max Ratio */
+	set_max_turbo_freq();
+
+	/*
+	 * Now that all APs have been relocated as well as the BSP let SMIs
+	 * start flowing.
+	 */
+	southcluster_smm_enable_smi();
+}
+
+/*
+ * CPU initialization recipe
+ *
+ * Note that no microcode update is passed to the init function. CSE updates
+ * the microcode on all cores before releasing them from reset. That means that
+ * the BSP and all APs will come up with the same microcode revision.
+ */
+static const struct mp_ops mp_ops = {
+	.pre_mp_init = pre_mp_init,
+	.get_cpu_count = get_cpu_count,
+	.get_smm_info = get_smm_info,
+	.pre_mp_smm_init = southcluster_smm_clear_state,
+	.relocation_handler = relocation_handler,
+	.post_mp_init = post_mp_init,
+};
+
+void denverton_init_cpus(device_t dev)
+{
+	/* Clear for take-off */
+	if (mp_init_with_smm(dev->link_list, &mp_ops) < 0)
+		printk(BIOS_ERR, "MP initialization failure.\n");
+}
diff --git a/src/soc/intel/denverton_ns/csme_ie_kt.c b/src/soc/intel/denverton_ns/csme_ie_kt.c
new file mode 100644
index 0000000..7848883
--- /dev/null
+++ b/src/soc/intel/denverton_ns/csme_ie_kt.c
@@ -0,0 +1,90 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2016 - 2017 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 <stdlib.h>
+#include <string.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <console/console.h>
+#include <soc/pci_devs.h>
+#include <soc/ramstage.h>
+
+/**
+* Read the base address registers for a given device.
+*
+* @param dev Pointer to the dev structure.
+* @param howmany How many registers to read.
+*/
+static void pci_read_bases(struct device *dev, unsigned int howmany)
+{
+	unsigned long index;
+
+	for (index = PCI_BASE_ADDRESS_0;
+	     (index < PCI_BASE_ADDRESS_0 + (howmany << 2));) {
+		struct resource *resource;
+		resource = pci_get_resource(dev, index);
+		/**
+		* Workarond for Denverton-NS silicon (Rev A0/A1 for CSME/IE,
+		*  Rev B0 for CSME only)
+		*  CSME&IEs KT IO bar must be 16-byte aligned
+		*/
+		if ((resource->flags & IORESOURCE_IO) &&
+		    (resource->align != 4)) {
+			printk(BIOS_DEBUG,
+			       "CSME&IEs KT IO bar must be 16-byte aligned!\n");
+			resource->align = 4;
+			resource->gran = 4;
+			resource->size = 16;
+		}
+		index += (resource->flags & IORESOURCE_PCI64) ? 8 : 4;
+	}
+
+	compact_resources(dev);
+}
+
+static void pci_csme_ie_kt_read_resources(device_t dev)
+{
+	/**
+	* CSME/IE KT has 2 BARs to chec:
+	*   0x10 - KT IO BAR
+	*   0x14 - KT Memory BAR
+	* CSME/IE KT has no Expansion ROM BAR to check:
+	*   0x30 - KT Host XRBAR, READ ONLY
+	*/
+	pci_read_bases(dev, 2);
+}
+
+static struct device_operations csme_ie_kt_ops = {
+	.read_resources = pci_csme_ie_kt_read_resources,
+	.set_resources = pci_dev_set_resources,
+	.enable_resources = pci_dev_enable_resources,
+	.scan_bus = 0,
+	.init = 0,
+	.ops_pci = &soc_pci_ops,
+};
+
+static const unsigned short pci_device_ids[] = {
+	ME_MEKT_DEVID, /* DVN CSME KT */
+	IE_MEKT_DEVID, /* DVN IE KT */
+	0
+};
+
+static const struct pci_driver csme_ie_kt __pci_driver = {
+	.ops = &csme_ie_kt_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.devices = pci_device_ids,
+};
diff --git a/src/soc/intel/denverton_ns/exit_car_fsp.S b/src/soc/intel/denverton_ns/exit_car_fsp.S
new file mode 100644
index 0000000..2ec625b
--- /dev/null
+++ b/src/soc/intel/denverton_ns/exit_car_fsp.S
@@ -0,0 +1,47 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2016-2017 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/cr.h>
+//#include <soc/cpu.h>
+
+/*
+ * This path for CAR teardown is taken when CONFIG_FSP_CAR is employed.
+ * This version of chipset_teardown_car sets up the stack, then bypasses
+ * the rest of arch/x86/exit_car.S and calls main() itself instead of
+ * returning to _start. In main(), the TempRamExit FSP API is called
+ * to tear down the CAR and set up caching which can be overwritten
+ * after the API call.  More info can be found in the Denverton-NS FSP
+ * Integration Guide included with the FSP binary.  The below
+ * caching settings are based on an 8MiB Flash Size given as a
+ * parameter to TempRamInit.
+ *
+ * 	TempRamExit MTRR Settings:
+ * 	0x00000000  - 0x0009FFFF           | Write Back
+ * 	0x000C0000  - Top of Low Memory    | Write Back
+ * 	0xFF800000  - 0xFFFFFFFF Flash Reg | Write Protect
+ * 	0x100000000 - Top of High Memory   | Write Back
+ */
+
+.text
+.global chipset_teardown_car
+chipset_teardown_car:
+
+	/* Set up new stack. */
+	mov	post_car_stack_top, %esp
+
+	/* Call C code */
+	call	main
diff --git a/src/soc/intel/denverton_ns/fiamux.c b/src/soc/intel/denverton_ns/fiamux.c
new file mode 100644
index 0000000..282ba03
--- /dev/null
+++ b/src/soc/intel/denverton_ns/fiamux.c
@@ -0,0 +1,140 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 - 2017 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 <soc/fiamux.h>
+
+#define FSP_FIAMUX_HOB_GUID                                            \
+	{                                                              \
+		0x26ad492e, 0xf951, 0x4e43,                            \
+		{                                                      \
+			0xbc, 0x72, 0x22, 0x76, 0x58, 0xb1, 0xf6, 0x23 \
+		}                                                      \
+	}
+
+int get_fiamux_hsio_info(uint16_t num_of_lanes, size_t num_of_entry,
+				BL_HSIO_INFORMATION **config)
+{
+	uint8_t entry;
+
+	if ((num_of_lanes == 0) || (num_of_entry == 0) || (*config == NULL))
+		return 1;
+
+	for (entry = 0; entry < num_of_entry; entry++) {
+		if ((*config)[entry].NumLanesSupported == num_of_lanes) {
+			*config = &(*config)[entry];
+			return 0;
+		}
+	}
+
+	return 1;
+}
+
+/*
+* Display the FIA MUX HOB.
+*
+*   @param   Pointer of FIA MUX HOB data
+*
+*   @return  None
+*
+*/
+void print_fiamux_config_hob(BL_FIA_MUX_CONFIG_HOB *fiamux_hob_data)
+{
+	/* Display the FIA MUX Configuration */
+	printk(BIOS_DEBUG, "FIA MUX Configuration in FSP HOB is:\n");
+
+	printk(BIOS_DEBUG, "    FiaMuxConfig.SkuNumLanesAllowed = 0x%x\n",
+	       (uint32_t)(fiamux_hob_data->FiaMuxConfig.SkuNumLanesAllowed));
+
+	printk(BIOS_DEBUG, "    FiaMuxConfig.FiaMuxConfig = 0x%llx\n",
+	       (uint64_t)(fiamux_hob_data->FiaMuxConfig.FiaMuxConfig
+				  .MuxConfiguration.MeFiaMuxLaneConfig));
+
+	printk(BIOS_DEBUG,
+	       "    FiaMuxConfig.FiaMuxConfig.SataLaneConfiguration = 0x%llx\n",
+	       (uint64_t)(fiamux_hob_data->FiaMuxConfig.FiaMuxConfig
+				  .SataLaneConfiguration.MeFiaSataLaneConfig));
+
+	printk(BIOS_DEBUG, "    FiaMuxConfig.FiaMuxConfig."
+			   "PcieRootPortsConfiguration = 0x%llx\n",
+	       (uint64_t)(fiamux_hob_data->FiaMuxConfig.FiaMuxConfig
+				  .PcieRootPortsConfiguration
+				  .MeFiaPcieRootPortsConfig));
+
+	printk(BIOS_DEBUG, "    FiaMuxConfig.FiaMuxConfigRequest = 0x%llx\n",
+	       (uint64_t)(fiamux_hob_data->FiaMuxConfig.FiaMuxConfigRequest
+				  .MuxConfiguration.MeFiaMuxLaneConfig));
+
+	printk(BIOS_DEBUG, "    FiaMuxConfig.FiaMuxConfigRequest."
+			   "SataLaneConfiguration = 0x%llx\n",
+	       (uint64_t)(fiamux_hob_data->FiaMuxConfig.FiaMuxConfigRequest
+				  .SataLaneConfiguration.MeFiaSataLaneConfig));
+
+	printk(BIOS_DEBUG, "    FiaMuxConfig.FiaMuxConfigRequest."
+			   "PcieRootPortsConfiguration = 0x%llx\n",
+	       (uint64_t)(fiamux_hob_data->FiaMuxConfig.FiaMuxConfigRequest
+				  .PcieRootPortsConfiguration
+				  .MeFiaPcieRootPortsConfig));
+	printk(BIOS_DEBUG,
+	       "    FiaMuxConfigStatus.FiaMuxConfigGetStatus = 0x%x\n",
+	       (uint32_t)(fiamux_hob_data->FiaMuxConfigStatus
+				  .FiaMuxConfigGetStatus));
+
+	printk(BIOS_DEBUG,
+	       "    FiaMuxConfigStatus.FiaMuxConfigSetStatus = 0x%x\n",
+	       (uint32_t)(fiamux_hob_data->FiaMuxConfigStatus
+				  .FiaMuxConfigSetStatus));
+
+	printk(BIOS_DEBUG,
+	       "    FiaMuxConfigStatus.FiaMuxConfigSetRequired = 0x%x\n",
+	       (uint8_t)(fiamux_hob_data->FiaMuxConfigStatus
+				 .FiaMuxConfigSetRequired));
+}
+
+/*
+* Get the pointer of FIA MUX HOB data
+*
+*   @param   Pointer of FIA MUX HOB data
+*
+*   @return:
+*     Non-zero - FIA MUX configuration correct.
+*     Zero - Either FIA MUX configuration incorrect or
+*     it can not be verified.
+*/
+BL_FIA_MUX_CONFIG_HOB *get_fiamux_hob_data(void)
+{
+	u32 const *fiamux_hob = NULL;
+	BL_FIA_MUX_CONFIG_HOB *fiamux_hob_data = NULL;
+	const EFI_GUID fiamux_guid = FSP_FIAMUX_HOB_GUID;
+	size_t size;
+
+	/* Parse FIA MUX configuration HOB */
+	fiamux_hob = fsp_find_extension_hob_by_guid(
+		(uint8_t const *)&fiamux_guid, &size);
+
+	if (fiamux_hob == NULL) {
+		/* FIA MUX configuration HOB not exist */
+		die("FIA MUX Configuration Data Hob does not present!\n");
+	} else {
+		/* Get FIA MUX configuration HOB */
+		fiamux_hob_data = (BL_FIA_MUX_CONFIG_HOB *)(fiamux_hob);
+
+		/* Display FIA MUX configuration HOB */
+		print_fiamux_config_hob(fiamux_hob_data);
+	}
+
+	return fiamux_hob_data;
+}
diff --git a/src/soc/intel/denverton_ns/gpio.c b/src/soc/intel/denverton_ns/gpio.c
new file mode 100644
index 0000000..3030fbb
--- /dev/null
+++ b/src/soc/intel/denverton_ns/gpio.c
@@ -0,0 +1,509 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 - 2017 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 <soc/iomap.h>
+#include <soc/pcr.h>
+#include <soc/soc_util.h>
+#include <soc/gpio.h>
+
+//         Community               PadOwnOffset                HostOwnOffset
+//         GpiIsOffset
+//         GpiIeOffset             GpiGpeStsOffset             GpiGpeEnOffset
+//         SmiStsOffset
+//         SmiEnOffset             NmiStsOffset                NmiEnOffset
+//         PadCfgLockOffset
+//         PadCfgLockTxOffset      PadCfgOffset                PadPerGroup
+static const struct GPIO_GROUP_INFO mGpioGroupInfo[] = {
+	{PID_GPIOCOM0, R_PCH_PCR_GPIO_NC_PAD_OWN, R_PCH_PCR_GPIO_NC_HOSTSW_OWN,
+	 R_PCH_PCR_GPIO_NC_GPI_IS, R_PCH_PCR_GPIO_NC_GPI_IE,
+	 R_PCH_PCR_GPIO_NC_GPI_GPE_STS, R_PCH_PCR_GPIO_NC_GPI_GPE_EN,
+	 R_PCH_PCR_GPIO_NC_SMI_STS, R_PCH_PCR_GPIO_NC_SMI_EN,
+	 R_PCH_PCR_GPIO_NC_NMI_STS, R_PCH_PCR_GPIO_NC_NMI_EN,
+	 R_PCH_PCR_GPIO_NC_PADCFGLOCK, R_PCH_PCR_GPIO_NC_PADCFGLOCKTX,
+	 R_PCH_PCR_GPIO_NC_PADCFG_OFFSET,
+	 V_PCH_GPIO_NC_PAD_MAX}, // DNV NORTH_ALL
+	{PID_GPIOCOM1, R_PCH_PCR_GPIO_SC_DFX_PAD_OWN,
+	 R_PCH_PCR_GPIO_SC_DFX_HOSTSW_OWN, R_PCH_PCR_GPIO_SC_DFX_GPI_IS,
+	 R_PCH_PCR_GPIO_SC_DFX_GPI_IE, R_PCH_PCR_GPIO_SC_DFX_GPI_GPE_STS,
+	 R_PCH_PCR_GPIO_SC_DFX_GPI_GPE_EN, NO_REGISTER_FOR_PROPERTY,
+	 NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY,
+	 NO_REGISTER_FOR_PROPERTY, R_PCH_PCR_GPIO_SC_DFX_PADCFGLOCK,
+	 R_PCH_PCR_GPIO_SC_DFX_PADCFGLOCKTX,
+	 R_PCH_PCR_GPIO_SC_DFX_PADCFG_OFFSET,
+	 V_PCH_GPIO_SC_DFX_PAD_MAX}, // DNV SOUTH_DFX
+	{PID_GPIOCOM1, R_PCH_PCR_GPIO_SC0_PAD_OWN,
+	 R_PCH_PCR_GPIO_SC0_HOSTSW_OWN, R_PCH_PCR_GPIO_SC0_GPI_IS,
+	 R_PCH_PCR_GPIO_SC0_GPI_IE, R_PCH_PCR_GPIO_SC0_GPI_GPE_STS,
+	 R_PCH_PCR_GPIO_SC0_GPI_GPE_EN, R_PCH_PCR_GPIO_SC0_SMI_STS,
+	 R_PCH_PCR_GPIO_SC0_SMI_EN, R_PCH_PCR_GPIO_SC0_NMI_STS,
+	 R_PCH_PCR_GPIO_SC0_NMI_EN, R_PCH_PCR_GPIO_SC0_PADCFGLOCK,
+	 R_PCH_PCR_GPIO_SC0_PADCFGLOCKTX, R_PCH_PCR_GPIO_SC0_PADCFG_OFFSET,
+	 V_PCH_GPIO_SC0_PAD_MAX}, // DNV South Community 0
+	{PID_GPIOCOM1, R_PCH_PCR_GPIO_SC1_PAD_OWN,
+	 R_PCH_PCR_GPIO_SC1_HOSTSW_OWN, R_PCH_PCR_GPIO_SC1_GPI_IS,
+	 R_PCH_PCR_GPIO_SC1_GPI_IE, R_PCH_PCR_GPIO_SC1_GPI_GPE_STS,
+	 R_PCH_PCR_GPIO_SC1_GPI_GPE_EN, R_PCH_PCR_GPIO_SC1_SMI_STS,
+	 R_PCH_PCR_GPIO_SC1_SMI_EN, R_PCH_PCR_GPIO_SC1_NMI_STS,
+	 R_PCH_PCR_GPIO_SC1_NMI_EN, R_PCH_PCR_GPIO_SC1_PADCFGLOCK,
+	 R_PCH_PCR_GPIO_SC1_PADCFGLOCKTX, R_PCH_PCR_GPIO_SC1_PADCFG_OFFSET,
+	 V_PCH_GPIO_SC1_PAD_MAX}, // DNV South Community 1
+};
+
+/* Retrieve address and length of GPIO info table */
+static struct GPIO_GROUP_INFO *
+GpioGetGroupInfoTable(uint32_t *GpioGroupInfoTableLength)
+{
+	*GpioGroupInfoTableLength =
+		sizeof(mGpioGroupInfo) / sizeof(struct GPIO_GROUP_INFO);
+	return (struct GPIO_GROUP_INFO *)mGpioGroupInfo;
+}
+
+/* Get Gpio Pad Ownership */
+static void GpioGetPadOwnership(GPIO_PAD GpioPad, GPIO_PAD_OWN *PadOwnVal)
+{
+	uint32_t Mask;
+	uint32_t RegOffset;
+	uint32_t GroupIndex;
+	uint32_t PadNumber;
+	struct GPIO_GROUP_INFO *GpioGroupInfo;
+	uint32_t GpioGroupInfoLength;
+	uint32_t PadOwnRegValue;
+
+	GroupIndex = GPIO_GET_GROUP_INDEX_FROM_PAD(GpioPad);
+	PadNumber = GPIO_GET_PAD_NUMBER(GpioPad);
+
+	GpioGroupInfo = GpioGetGroupInfoTable(&GpioGroupInfoLength);
+
+	//
+	// Check if group argument exceeds GPIO GROUP INFO array
+	//
+	if ((uint32_t)GroupIndex >= GpioGroupInfoLength) {
+		printk(BIOS_ERR, "GPIO ERROR: Group argument (%d) exceeds GPIO "
+				 "group range\n",
+		       GroupIndex);
+		return;
+	}
+
+	//
+	// Check if legal pin number
+	//
+	if (PadNumber >= GpioGroupInfo[GroupIndex].PadPerGroup) {
+		printk(BIOS_ERR, "GPIO ERROR: Pin number (%d) exceeds possible "
+				 "range for this group\n",
+		       PadNumber);
+		return;
+	}
+	//
+	// Calculate RegOffset using Pad Ownership offset and GPIO Pad number.
+	// One DWord register contains information for 8 pads.
+	//
+	RegOffset =
+		GpioGroupInfo[GroupIndex].PadOwnOffset + (PadNumber >> 3) * 0x4;
+
+	//
+	// Calculate pad bit position within DWord register
+	//
+	PadNumber %= 8;
+	Mask = ((1 << 1) | (1 << 0)) << (PadNumber * 4);
+
+	PadOwnRegValue = read32((void *)PCH_PCR_ADDRESS(
+		GpioGroupInfo[GroupIndex].Community, RegOffset));
+
+	*PadOwnVal = (GPIO_PAD_OWN)((PadOwnRegValue & Mask) >> (PadNumber * 4));
+}
+
+void gpio_configure_pads(const struct pad_config *gpio, size_t num)
+{
+	/* Return if gpio not valid */
+	if ((gpio == NULL) || (num == 0))
+		return;
+
+	uint32_t Index;
+	uint32_t Dw0Reg;
+	uint32_t Dw0RegMask;
+	uint32_t Dw1Reg;
+	uint32_t Dw1RegMask;
+	uint32_t PadCfgReg;
+	uint64_t HostSoftOwnReg[V_PCH_GPIO_GROUP_MAX];
+	uint64_t HostSoftOwnRegMask[V_PCH_GPIO_GROUP_MAX];
+	uint64_t GpiGpeEnReg[V_PCH_GPIO_GROUP_MAX];
+	uint64_t GpiGpeEnRegMask[V_PCH_GPIO_GROUP_MAX];
+	struct GPIO_GROUP_INFO *GpioGroupInfo;
+	uint32_t GpioGroupInfoLength;
+	GPIO_PAD GpioGroupOffset;
+	uint32_t NumberOfGroups;
+	GPIO_PAD_OWN PadOwnVal;
+	struct pad_config *GpioData;
+	GPIO_PAD Group;
+	uint32_t GroupIndex;
+	uint32_t PadNumber;
+	uint32_t FinalValue;
+	uint32_t Data32;
+	uint32_t PadMode1, PadMode2;
+
+	PadOwnVal = GpioPadOwnHost;
+
+	memset(HostSoftOwnReg, 0, sizeof(HostSoftOwnReg));
+	memset(HostSoftOwnRegMask, 0, sizeof(HostSoftOwnRegMask));
+	memset(GpiGpeEnReg, 0, sizeof(GpiGpeEnReg));
+	memset(GpiGpeEnRegMask, 0, sizeof(GpiGpeEnRegMask));
+
+	GpioGroupInfo = GpioGetGroupInfoTable(&GpioGroupInfoLength);
+
+	GpioGroupOffset = GPIO_DNV_GROUP_MIN;
+	NumberOfGroups = V_PCH_GPIO_GROUP_MAX;
+
+	for (Index = 0; Index < (uint32_t)num; Index++) {
+
+		Dw0RegMask = 0;
+		Dw0Reg = 0;
+		Dw1RegMask = 0;
+		Dw1Reg = 0;
+
+		GpioData = (struct pad_config *)&(gpio[Index]);
+
+		Group = GPIO_GET_GROUP_FROM_PAD(GpioData->GpioPad);
+		GroupIndex = GPIO_GET_GROUP_INDEX_FROM_PAD(GpioData->GpioPad);
+		PadNumber = GPIO_GET_PAD_NUMBER(GpioData->GpioPad);
+
+		//
+		// Check if group index argument exceeds GPIO group index range
+		//
+		if (GroupIndex >= V_PCH_GPIO_GROUP_MAX) {
+			printk(BIOS_ERR, "GPIO ERROR: Invalid Group Index "
+					 "(GroupIndex=%d, Pad=%d)!\n",
+			       GroupIndex, PadNumber);
+			continue;
+		}
+
+		//
+		// Check if group argument exceeds GPIO group range
+		//
+		if ((Group < GpioGroupOffset) ||
+		    (Group >= NumberOfGroups + GpioGroupOffset)) {
+			printk(BIOS_ERR,
+			       "GPIO ERROR: Invalid Group (Group=%d)!\n",
+			       Group);
+			return;
+		}
+
+		//
+		// Check if legal pin number
+		//
+		if (PadNumber >= GpioGroupInfo[GroupIndex].PadPerGroup) {
+			printk(BIOS_ERR, "GPIO ERROR: Invalid PadNumber "
+					 "(PadNumber=%d)!\n",
+			       PadNumber);
+			return;
+		}
+
+		//
+		// Check if selected GPIO Pad is not owned by CSME/ISH
+		//
+		GpioGetPadOwnership(GpioData->GpioPad, &PadOwnVal);
+
+		if (PadOwnVal != GpioPadOwnHost) {
+			printk(BIOS_ERR, "GPIO WARNING: Accessing pad not "
+					 "owned by host (Group=%d, Pad=%d)!",
+			       GroupIndex, PadNumber);
+			if (PadOwnVal == GpioPadOwnCsme)
+				printk(BIOS_ERR, "The owner is CSME\n");
+			else if (PadOwnVal == GpioPadOwnIsh)
+				printk(BIOS_ERR, "The owner is ISH\n");
+			printk(BIOS_ERR, "** Please make sure the GPIO usage "
+					 "in sync between CSME/ISH and Host IA "
+					 "FW configuration.\n");
+			printk(BIOS_ERR, "** All the GPIO occupied by CSME/ISH "
+					 "should not do any configuration by "
+					 "Host IA FW.\n");
+			continue;
+		}
+
+		//
+		// Configure Reset Type (PadRstCfg)
+		//
+		Dw0RegMask |=
+			((((GpioData->GpioConfig.PowerConfig &
+			    GPIO_CONF_RESET_MASK) >>
+			   GPIO_CONF_RESET_BIT_POS) == GpioHardwareDefault)
+				 ? 0x0
+				 : B_PCH_GPIO_RST_CONF);
+		Dw0Reg |= (((GpioData->GpioConfig.PowerConfig &
+			     GPIO_CONF_RESET_MASK) >>
+			    (GPIO_CONF_RESET_BIT_POS + 1))
+			   << N_PCH_GPIO_RST_CONF);
+
+		//
+		// Configure how interrupt is triggered (RxEvCfg)
+		//
+		Dw0RegMask |=
+			((((GpioData->GpioConfig.InterruptConfig &
+			    GPIO_CONF_INT_TRIG_MASK) >>
+			   GPIO_CONF_INT_TRIG_BIT_POS) == GpioHardwareDefault)
+				 ? 0x0
+				 : B_PCH_GPIO_RX_LVL_EDG);
+		Dw0Reg |= (((GpioData->GpioConfig.InterruptConfig &
+			     GPIO_CONF_INT_TRIG_MASK) >>
+			    (GPIO_CONF_INT_TRIG_BIT_POS + 1))
+			   << N_PCH_GPIO_RX_LVL_EDG);
+
+		//
+		// Configure interrupt generation (GPIRoutIOxAPIC/SCI/SMI/NMI)
+		//
+		Dw0RegMask |=
+			((((GpioData->GpioConfig.InterruptConfig &
+			    GPIO_CONF_INT_ROUTE_MASK) >>
+			   GPIO_CONF_INT_ROUTE_BIT_POS) == GpioHardwareDefault)
+				 ? 0x0
+				 : (B_PCH_GPIO_RX_NMI_ROUTE |
+				    B_PCH_GPIO_RX_SCI_ROUTE |
+				    B_PCH_GPIO_RX_SMI_ROUTE |
+				    B_PCH_GPIO_RX_APIC_ROUTE));
+		Dw0Reg |= (((GpioData->GpioConfig.InterruptConfig &
+			     GPIO_CONF_INT_ROUTE_MASK) >>
+			    (GPIO_CONF_INT_ROUTE_BIT_POS + 1))
+			   << N_PCH_GPIO_RX_NMI_ROUTE);
+
+		// If CFIO is not Working as GPIO mode, Don't move TxDisabe and
+		// RxDisable
+		if (GpioData->GpioConfig.PadMode == GpioPadModeGpio) {
+			//
+			// Configure GPIO direction (GPIORxDis and GPIOTxDis)
+			//
+			Dw0RegMask |= ((((GpioData->GpioConfig.Direction &
+					  GPIO_CONF_DIR_MASK) >>
+					 GPIO_CONF_DIR_BIT_POS) ==
+					GpioHardwareDefault)
+					       ? 0x0
+					       : (B_PCH_GPIO_RXDIS |
+						  B_PCH_GPIO_TXDIS));
+			Dw0Reg |= (((GpioData->GpioConfig.Direction &
+				     GPIO_CONF_DIR_MASK) >>
+				    (GPIO_CONF_DIR_BIT_POS + 1))
+				   << N_PCH_GPIO_TXDIS);
+		}
+
+		//
+		// Configure GPIO input inversion (RXINV)
+		//
+		Dw0RegMask |= ((((GpioData->GpioConfig.Direction &
+				  GPIO_CONF_INV_MASK) >>
+				 GPIO_CONF_INV_BIT_POS) == GpioHardwareDefault)
+				       ? 0x0
+				       : B_PCH_GPIO_RXINV);
+		Dw0Reg |= (((GpioData->GpioConfig.Direction &
+			     GPIO_CONF_INV_MASK) >>
+			    (GPIO_CONF_INV_BIT_POS + 1))
+			   << N_PCH_GPIO_RXINV);
+
+		//
+		// Configure GPIO output state (GPIOTxState)
+		//
+		Dw0RegMask |=
+			((((GpioData->GpioConfig.OutputState &
+			    GPIO_CONF_OUTPUT_MASK) >>
+			   GPIO_CONF_OUTPUT_BIT_POS) == GpioHardwareDefault)
+				 ? 0x0
+				 : B_PCH_GPIO_TX_STATE);
+		Dw0Reg |= (((GpioData->GpioConfig.OutputState &
+			     GPIO_CONF_OUTPUT_MASK) >>
+			    (GPIO_CONF_OUTPUT_BIT_POS + 1))
+			   << N_PCH_GPIO_TX_STATE);
+
+		//
+		// Configure GPIO RX raw override to '1' (RXRAW1)
+		//
+		Dw0RegMask |=
+			((((GpioData->GpioConfig.OtherSettings &
+			    GPIO_CONF_RXRAW_MASK) >>
+			   GPIO_CONF_RXRAW_BIT_POS) == GpioHardwareDefault)
+				 ? 0x0
+				 : B_PCH_GPIO_RX_RAW1);
+		Dw0Reg |= (((GpioData->GpioConfig.OtherSettings &
+			     GPIO_CONF_RXRAW_MASK) >>
+			    (GPIO_CONF_RXRAW_BIT_POS + 1))
+			   << N_PCH_GPIO_RX_RAW1);
+
+		//
+		// Configure GPIO Pad Mode (PMode)
+		//
+		Dw0RegMask |=
+			((((GpioData->GpioConfig.PadMode &
+			    GPIO_CONF_PAD_MODE_MASK) >>
+			   GPIO_CONF_PAD_MODE_BIT_POS) == GpioHardwareDefault)
+				 ? 0x0
+				 : B_PCH_GPIO_PAD_MODE);
+		Dw0Reg |= (((GpioData->GpioConfig.PadMode &
+			     GPIO_CONF_PAD_MODE_MASK) >>
+			    (GPIO_CONF_PAD_MODE_BIT_POS + 1))
+			   << N_PCH_GPIO_PAD_MODE);
+
+		//
+		// Configure GPIO termination (Term)
+		//
+		Dw1RegMask |= ((((GpioData->GpioConfig.ElectricalConfig &
+				  GPIO_CONF_TERM_MASK) >>
+				 GPIO_CONF_TERM_BIT_POS) == GpioHardwareDefault)
+				       ? 0x0
+				       : B_PCH_GPIO_TERM);
+		Dw1Reg |= (((GpioData->GpioConfig.ElectricalConfig &
+			     GPIO_CONF_TERM_MASK) >>
+			    (GPIO_CONF_TERM_BIT_POS + 1))
+			   << N_PCH_GPIO_TERM);
+
+		//
+		// Configure GPIO pad tolerance (padtol)
+		//
+		Dw1RegMask |=
+			((((GpioData->GpioConfig.ElectricalConfig &
+			    GPIO_CONF_PADTOL_MASK) >>
+			   GPIO_CONF_PADTOL_BIT_POS) == GpioHardwareDefault)
+				 ? 0x0
+				 : B_PCH_GPIO_PADTOL);
+		Dw1Reg |= (((GpioData->GpioConfig.ElectricalConfig &
+			     GPIO_CONF_PADTOL_MASK) >>
+			    (GPIO_CONF_PADTOL_BIT_POS + 1))
+			   << N_PCH_GPIO_PADTOL);
+
+		//
+		// Check for additional requirements on setting PADCFG register
+		//
+
+		//
+		// Create PADCFG register offset using group and pad number
+		//
+		PadCfgReg = 0x8 * PadNumber +
+			    GpioGroupInfo[GroupIndex].PadCfgOffset;
+		Data32 = read32((void *)PCH_PCR_ADDRESS(
+			GpioGroupInfo[GroupIndex].Community, PadCfgReg));
+
+		FinalValue = ((Data32 & (~Dw0RegMask)) | Dw0Reg);
+
+		PadMode1 =
+			(Data32 & B_PCH_GPIO_PAD_MODE) >> N_PCH_GPIO_PAD_MODE;
+		PadMode2 =
+			(Dw0Reg & B_PCH_GPIO_PAD_MODE) >> N_PCH_GPIO_PAD_MODE;
+
+		if (((Data32 & B_PCH_GPIO_PAD_MODE) !=
+		     (FinalValue & B_PCH_GPIO_PAD_MODE)) ||
+		    (PadMode2 == 0)) {
+			printk(BIOS_DEBUG, "Changing GpioPad PID: %x Offset: "
+					   "0x%x PadModeP1: %d P2: %d ",
+			       GpioGroupInfo[GroupIndex].Community, PadCfgReg,
+			       PadMode1, PadMode2);
+			printk(BIOS_DEBUG, "R: 0x%08x Fx%08x !\n", Data32,
+			       FinalValue);
+			//
+			// Write PADCFG DW0 register``
+			//
+			mmio_andthenor32(
+				(void *)(uint32_t)PCH_PCR_ADDRESS(
+					GpioGroupInfo[GroupIndex].Community,
+					PadCfgReg),
+				~(uint32_t)Dw0RegMask, (uint32_t)Dw0Reg);
+		}
+
+		Data32 = read32((void *)PCH_PCR_ADDRESS(
+			GpioGroupInfo[GroupIndex].Community, PadCfgReg + 0x4));
+		FinalValue = ((Data32 & (~Dw1RegMask)) | Dw1Reg);
+		if (Data32 != FinalValue) {
+			//
+			// Write PADCFG DW1 register
+			//
+			mmio_andthenor32(
+				(void *)(uint32_t)PCH_PCR_ADDRESS(
+					GpioGroupInfo[GroupIndex].Community,
+					PadCfgReg + 0x4),
+				~(uint32_t)Dw1RegMask, (uint32_t)Dw1Reg);
+		}
+
+		//
+		// Update value to be programmed in HOSTSW_OWN register
+		//
+		HostSoftOwnRegMask[GroupIndex] |= LShiftU64(
+			(uint64_t)GpioData->GpioConfig.HostSoftPadOwn & 0x1,
+			PadNumber);
+		HostSoftOwnReg[GroupIndex] |= LShiftU64(
+			(uint64_t)GpioData->GpioConfig.HostSoftPadOwn >> 0x1,
+			PadNumber);
+
+		//
+		// Update value to be programmed in GPI_GPE_EN register
+		//
+		GpiGpeEnRegMask[GroupIndex] |= LShiftU64(
+			(uint64_t)(GpioData->GpioConfig.InterruptConfig & 0x1),
+			PadNumber);
+		GpiGpeEnReg[GroupIndex] |= LShiftU64(
+			(uint64_t)(GpioData->GpioConfig.InterruptConfig &
+				   GpioIntSci) >>
+				3,
+			PadNumber);
+	}
+
+	for (Index = 0; Index < NumberOfGroups; Index++) {
+		//
+		// Write HOSTSW_OWN registers
+		//
+		if (GpioGroupInfo[Index].HostOwnOffset !=
+		    NO_REGISTER_FOR_PROPERTY) {
+			mmio_andthenor32(
+				(void *)PCH_PCR_ADDRESS(
+					GpioGroupInfo[Index].Community,
+					GpioGroupInfo[Index].HostOwnOffset),
+				~(uint32_t)(HostSoftOwnRegMask[Index] &
+					    0xFFFFFFFF),
+				(uint32_t)(HostSoftOwnReg[Index] & 0xFFFFFFFF));
+			mmio_andthenor32(
+				(void *)PCH_PCR_ADDRESS(
+					GpioGroupInfo[Index].Community,
+					GpioGroupInfo[Index].HostOwnOffset +
+						0x4),
+				~(uint32_t)(RShiftU64(HostSoftOwnRegMask[Index],
+						      32)),
+				(uint32_t)(
+					RShiftU64(HostSoftOwnReg[Index], 32)));
+		}
+
+		//
+		// Write GPI_GPE_EN registers
+		//
+		if (GpioGroupInfo[Index].GpiGpeEnOffset !=
+		    NO_REGISTER_FOR_PROPERTY) {
+			mmio_andthenor32(
+				(void *)PCH_PCR_ADDRESS(
+					GpioGroupInfo[Index].Community,
+					GpioGroupInfo[Index].GpiGpeEnOffset),
+				~(uint32_t)(GpiGpeEnRegMask[Index] &
+					    0xFFFFFFFF),
+				(uint32_t)(GpiGpeEnReg[Index] & 0xFFFFFFFF));
+			mmio_andthenor32(
+				(void *)PCH_PCR_ADDRESS(
+					GpioGroupInfo[Index].Community,
+					GpioGroupInfo[Index].GpiGpeEnOffset +
+						0x4),
+				~(uint32_t)(
+					RShiftU64(GpiGpeEnRegMask[Index], 32)),
+				(uint32_t)(RShiftU64(GpiGpeEnReg[Index], 32)));
+		}
+	}
+}
diff --git a/src/soc/intel/denverton_ns/hob_display.c b/src/soc/intel/denverton_ns/hob_display.c
new file mode 100644
index 0000000..39b799d
--- /dev/null
+++ b/src/soc/intel/denverton_ns/hob_display.c
@@ -0,0 +1,71 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2017 Intel Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <console/console.h>
+#include <fsp/util.h>
+#include <lib.h>
+
+static const uint8_t fsp_hob_resource_owner_graphics_guid[16] = {
+	0xa7, 0x3a, 0x7c, 0x9c, 0x32, 0x55, 0x17, 0x49,
+	0x82, 0xb9, 0x56, 0xa5, 0xf3, 0xe6, 0x2a, 0x07
+};
+
+static const uint8_t fsp_hob_resource_owner_fiamux_guid[16] = {
+	0x2e, 0x49, 0xad, 0x26, 0x51, 0xf9, 0x43, 0x4e,
+	0xbc, 0x72, 0x22, 0x76, 0x58, 0xb1, 0xf6, 0x23
+};
+
+static const uint8_t fsp_hob_fast_boot_checker_guid[16] = {
+	0x7b, 0xf0, 0x97, 0x78, 0xda, 0x0c, 0xe3, 0x40,
+	0xb4, 0xe4, 0x51, 0x5f, 0x47, 0x3b, 0x04, 0xb6
+};
+
+struct guid_name_map {
+	const void *guid;
+	const char *name;
+};
+
+static const struct guid_name_map  guid_names[] = {
+	{ fsp_hob_resource_owner_graphics_guid,
+		"FSP_HOB_RESOURCE_OWNER_GRAPHICS_GUID" },
+	{ fsp_hob_resource_owner_fiamux_guid,
+		"FSP_HOB_RESOURCE_OWNER_FIAMUX_GUID" },
+	{ fsp_hob_fast_boot_checker_guid,
+		"FSP_HOB_FAST_BOOT_CHECKER_GUID" },
+};
+
+const char *soc_get_hob_type_name(
+	const struct hob_header *hob)
+{
+	return NULL;
+}
+
+const char *soc_get_guid_name(const uint8_t *guid)
+{
+	size_t index;
+
+	/* Compare the GUID values in this module */
+	for (index = 0; index < ARRAY_SIZE(guid_names); index++)
+		if (fsp_guid_compare(guid, guid_names[index].guid))
+			return guid_names[index].name;
+
+	return NULL;
+}
+
+void soc_display_hob(const struct hob_header *hob)
+{
+	hexdump(hob, hob->length);
+}
diff --git a/src/soc/intel/denverton_ns/include/soc/acpi.h b/src/soc/intel/denverton_ns/include/soc/acpi.h
new file mode 100644
index 0000000..dd2be4d
--- /dev/null
+++ b/src/soc/intel/denverton_ns/include/soc/acpi.h
@@ -0,0 +1,34 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google, Inc.
+ * Copyright (C) 2014 - 2017 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 _DENVERTON_NS_ACPI_H_
+#define _DENVERTON_NS_ACPI_H_
+
+#include <arch/acpi.h>
+#include <soc/nvs.h>
+
+void acpi_create_intel_hpet(acpi_hpet_t *hpet);
+void acpi_create_serialio_ssdt(acpi_header_t *ssdt);
+void acpi_fill_in_fadt(acpi_fadt_t *fadt);
+unsigned long acpi_madt_irq_overrides(unsigned long current);
+void acpi_init_gnvs(global_nvs_t *gnvs);
+unsigned long southcluster_write_acpi_tables(device_t device,
+					     unsigned long current,
+					     struct acpi_rsdp *rsdp);
+void southcluster_inject_dsdt(device_t device);
+
+#endif /* _DENVERTON_NS_ACPI_H_ */
diff --git a/src/soc/intel/denverton_ns/include/soc/bootblock.h b/src/soc/intel/denverton_ns/include/soc/bootblock.h
new file mode 100644
index 0000000..8e58529
--- /dev/null
+++ b/src/soc/intel/denverton_ns/include/soc/bootblock.h
@@ -0,0 +1,33 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2016-2017 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_DENVERTON_NS_BOOTBLOCK_H_
+#define _SOC_DENVERTON_NS_BOOTBLOCK_H_
+
+/* Bootblock pre console init programing */
+//void bootblock_cpu_init(void);
+//void bootblock_pch_early_init(void);
+//void bootblock_systemagent_early_init(void);
+void early_uart_init(void);
+
+/* Bootblock post console init programing */
+//void enable_smbus(void);
+//void i2c_early_init(void);
+//void pch_early_init(void);
+//void report_platform_info(void);
+//void report_memory_config(void);
+//void set_max_freq(void);
+
+#endif
diff --git a/src/soc/intel/denverton_ns/include/soc/cpu.h b/src/soc/intel/denverton_ns/include/soc/cpu.h
new file mode 100644
index 0000000..7fd2e94
--- /dev/null
+++ b/src/soc/intel/denverton_ns/include/soc/cpu.h
@@ -0,0 +1,45 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 - 2017 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 _CPU_INTEL_DENVERTON_NS_H
+#define _CPU_INTEL_DENVERTON_NS_H
+
+int get_cpu_count(void);
+
+#ifndef __ASSEMBLER__
+#include <device/device.h>
+
+void denverton_init_cpus(struct device *dev);
+#endif
+
+/* Everything below this line is ignored in the DSDT */
+#ifndef __ACPI__
+
+/* Denverton-NS CPUID */
+#define CPUID_DENVERTON_A0_A1 0x506f0
+#define CPUID_DENVERTON_B0 0x506f1
+
+#define MSR_CORE_THREAD_COUNT 0x35
+#define CORE_BIT_MSK 0x1
+#define MCH_BAR_CORE_EXISTS_MASK 0x7164
+#define MCH_BAR_CORE_DISABLE_MASK 0x7168
+
+/* CPU bus clock is fixed at 100MHz */
+#define CPU_BCLK 100
+
+#endif /* __ACPI__ */
+
+#endif /* _CPU_INTEL_DENVERTON_NS_H */
diff --git a/src/soc/intel/denverton_ns/include/soc/fiamux.h b/src/soc/intel/denverton_ns/include/soc/fiamux.h
new file mode 100644
index 0000000..e8aaf65
--- /dev/null
+++ b/src/soc/intel/denverton_ns/include/soc/fiamux.h
@@ -0,0 +1,27 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2017 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 _MAINBOARD_HARCUVAR_FIAMUX_H
+#define _MAINBOARD_HARCUVAR_FIAMUX_H
+
+#include <fsp/util.h>
+
+int get_fiamux_hsio_info(uint16_t num_of_lanes, size_t num_of_entry,
+				BL_HSIO_INFORMATION **config);
+
+BL_FIA_MUX_CONFIG_HOB *get_fiamux_hob_data(void);
+void print_fiamux_config_hob(BL_FIA_MUX_CONFIG_HOB *fiamux_hob_data);
+
+#endif // _MAINBOARD_HARCUVAR_FIAMUX_H
diff --git a/src/soc/intel/denverton_ns/include/soc/gpio.h b/src/soc/intel/denverton_ns/include/soc/gpio.h
new file mode 100644
index 0000000..964b5e0
--- /dev/null
+++ b/src/soc/intel/denverton_ns/include/soc/gpio.h
@@ -0,0 +1,309 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 - 2017 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 _DENVERTON_NS_GPIO_H_
+#define _DENVERTON_NS_GPIO_H_
+
+#define RShiftU64(Operand, Count) (Operand >> Count)
+#define LShiftU64(Operand, Count) (Operand << Count)
+
+#include <soc/gpio_defs.h>
+
+#ifndef __ACPI__
+#include <stdint.h>
+#include <stddef.h>
+
+//
+// Structure for storing information about registers offset, community,
+// maximal pad number for available groups
+//
+struct GPIO_GROUP_INFO {
+	uint32_t Community;
+	uint32_t PadOwnOffset;
+	uint32_t HostOwnOffset;
+	uint32_t GpiIsOffset;
+	uint32_t GpiIeOffset;
+	uint32_t GpiGpeStsOffset;
+	uint32_t GpiGpeEnOffset;
+	uint32_t SmiStsOffset;
+	uint32_t SmiEnOffset;
+	uint32_t NmiStsOffset;
+	uint32_t NmiEnOffset;
+	uint32_t PadCfgLockOffset;
+	uint32_t PadCfgLockTxOffset;
+	uint32_t PadCfgOffset;
+	uint32_t PadPerGroup;
+};
+
+//
+// If in GPIO_GROUP_INFO structure certain register doesn't exist
+// it will have value equal to NO_REGISTER_FOR_PROPERTY
+//
+#define NO_REGISTER_FOR_PROPERTY (~0u)
+
+//
+// Below defines are based on GPIO_CONFIG structure fields
+//
+#define GPIO_CONF_PAD_MODE_MASK 0xF
+#define GPIO_CONF_PAD_MODE_BIT_POS 0
+#define GPIO_CONF_HOST_OWN_MASK 0x3
+#define GPIO_CONF_HOST_OWN_BIT_POS 0
+#define GPIO_CONF_DIR_MASK 0x7
+#define GPIO_CONF_DIR_BIT_POS 0
+#define GPIO_CONF_INV_MASK 0x18
+#define GPIO_CONF_INV_BIT_POS 3
+#define GPIO_CONF_OUTPUT_MASK 0x3
+#define GPIO_CONF_OUTPUT_BIT_POS 0
+#define GPIO_CONF_INT_ROUTE_MASK 0x1F
+#define GPIO_CONF_INT_ROUTE_BIT_POS 0
+#define GPIO_CONF_INT_TRIG_MASK 0xE0
+#define GPIO_CONF_INT_TRIG_BIT_POS 5
+#define GPIO_CONF_RESET_MASK 0x7
+#define GPIO_CONF_RESET_BIT_POS 0
+#define GPIO_CONF_TERM_MASK 0x1F
+#define GPIO_CONF_TERM_BIT_POS 0
+#define GPIO_CONF_PADTOL_MASK 0x60
+#define GPIO_CONF_PADTOL_BIT_POS 5
+#define GPIO_CONF_LOCK_MASK 0x7
+#define GPIO_CONF_LOCK_BIT_POS 0
+#define GPIO_CONF_RXRAW_MASK 0x3
+#define GPIO_CONF_RXRAW_BIT_POS 0
+
+/**
+GPIO configuration structure used for pin programming.
+Structure contains fields that can be used to configure pad.
+**/
+struct GPIO_CONFIG {
+	/**
+	Pad Mode
+	Pad can be set as GPIO or one of its native functions.
+	When in native mode setting Direction (except Inversion), OutputState,
+	InterruptConfig and Host Software Pad Ownership are unnecessary.
+	Refer to definition of GPIO_PAD_MODE.
+	Refer to EDS for each native mode according to the pad.
+	**/
+	uint32_t PadMode : 4;
+	/**
+	Host Software Pad Ownership
+	Set pad to ACPI mode or GPIO Driver Mode.
+	Refer to definition of GPIO_HOSTSW_OWN.
+	**/
+	uint32_t HostSoftPadOwn : 2;
+	/**
+	GPIO Direction
+	Can choose between In, In with inversion Out, both In and Out, both In
+	with inversion and out or disabling both.
+	Refer to definition of GPIO_DIRECTION for supported settings.
+	**/
+	uint32_t Direction : 5;
+	/**
+	Output State
+	Set Pad output value.
+	Refer to definition of GPIO_OUTPUT_STATE for supported settings.
+	This setting takes place when output is enabled.
+	**/
+	uint32_t OutputState : 2;
+	/**
+	GPIO Interrupt Configuration
+	Set Pad to cause one of interrupts (IOxAPIC/SCI/SMI/NMI). This setting
+	is applicable only if GPIO is in input mode.
+	If GPIO is set to cause an SCI then also Gpe is enabled for this pad.
+	Refer to definition of GPIO_INT_CONFIG for supported settings.
+	**/
+	uint32_t InterruptConfig : 8;
+	/**
+	GPIO Power Configuration.
+	This setting controls Pad Reset Configuration.
+	Refer to definition of GPIO_RESET_CONFIG for supported settings.
+	**/
+	uint32_t PowerConfig : 4;
+
+	/**
+	GPIO Electrical Configuration
+	This setting controls pads termination and voltage tolerance.
+	Refer to definition of GPIO_ELECTRICAL_CONFIG for supported settings.
+	**/
+	uint32_t ElectricalConfig : 7;
+
+	/**
+	GPIO Lock Configuration
+	This setting controls pads lock.
+	Refer to definition of GPIO_LOCK_CONFIG for supported settings.
+	**/
+	uint32_t LockConfig : 3;
+	/**
+	Additional GPIO configuration
+	Refer to definition of GPIO_OTHER_CONFIG for supported settings.
+	**/
+	uint32_t OtherSettings : 2;
+	uint32_t RsvdBits : 27; ///< Reserved bits for future extension
+} __attribute__((packed));
+
+typedef enum { GpioHardwareDefault = 0x0 } GPIO_HARDWARE_DEFAULT;
+
+///
+/// GPIO Pad Mode
+///
+typedef enum {
+	GpioPadModeGpio = 0x1,
+	GpioPadModeNative1 = 0x3,
+	GpioPadModeNative2 = 0x5,
+	GpioPadModeNative3 = 0x7,
+	GpioPadModeNative4 = 0x9
+} GPIO_PAD_MODE;
+
+///
+/// Host Software Pad Ownership modes
+///
+typedef enum {
+	GpioHostOwnDefault = 0x0, ///< Leave ownership value unmodified
+	GpioHostOwnAcpi = 0x1,    ///< Set HOST ownership to ACPI
+	GpioHostOwnGpio = 0x3     ///< Set HOST ownership to GPIO
+} GPIO_HOSTSW_OWN;
+
+///
+/// GPIO Direction
+///
+typedef enum {
+	GpioDirDefault = 0x0, ///< Leave pad direction setting unmodified
+	GpioDirInOut =
+		(0x1 | (0x1 << 3)), ///< Set pad for both output and input
+	GpioDirInInvOut = (0x1 | (0x3 << 3)), ///< Set pad for both output and
+					      ///input with inversion
+	GpioDirIn = (0x3 | (0x1 << 3)),       ///< Set pad for input only
+	GpioDirInInv = (0x3 | (0x3 << 3)), ///< Set pad for input with inversion
+	GpioDirOut = 0x5,		   ///< Set pad for output only
+	GpioDirNone = 0x7		   ///< Disable both output and input
+} GPIO_DIRECTION;
+
+///
+/// GPIO Output State
+///
+typedef enum {
+	GpioOutDefault = 0x0, ///< Leave output value unmodified
+	GpioOutLow = 0x1,     ///< Set output to low
+	GpioOutHigh = 0x3     ///< Set output to high
+} GPIO_OUTPUT_STATE;
+
+///
+/// GPIO interrupt configuration
+/// This setting is applicable only if GPIO is in input mode.
+/// GPIO_INT_CONFIG allows to choose which interrupt is generated
+/// (IOxAPIC/SCI/SMI/NMI)
+/// and how it is triggered (edge or level).
+/// Field from GpioIntNmi to GpioIntApic can be OR'ed with GpioIntLevel to
+/// GpioIntBothEdgecan
+/// to describe an interrupt e.g. GpioIntApic | GpioIntLevel
+/// If GPIO is set to cause an SCI then also Gpe is enabled for this pad.
+/// Not all GPIO are capable of generating an SMI or NMI interrupt
+///
+
+typedef enum {
+	GpioIntDefault = 0x0, ///< Leave value of interrupt routing unmodified
+	GpioIntDis = 0x1, ///< Disable IOxAPIC/SCI/SMI/NMI interrupt generation
+	GpioIntNmi = 0x3, ///< Enable NMI interrupt only
+	GpioIntSmi = 0x5, ///< Enable SMI interrupt only
+	GpioIntSci = 0x9, ///< Enable SCI interrupt only
+	GpioIntApic = 0x11,	///< Enable IOxAPIC interrupt only
+	GpioIntLevel = (0x1 << 5), ///< Set interrupt as level triggered
+	GpioIntEdge = (0x3 << 5),  ///< Set interrupt as edge triggered (type of
+				   ///edge depends on input inversion)
+	GpioIntLvlEdgDis = (0x5 << 5), ///< Disable interrupt trigger
+	GpioIntBothEdge = (0x7 << 5)   ///< Set interrupt as both edge triggered
+} GPIO_INT_CONFIG;
+
+///
+/// GPIO Power Configuration
+/// GPIO_RESET_CONFIG allows to set GPIO Reset (used to reset the specified
+/// Pad Register fields).
+///
+typedef enum {
+	GpioResetDefault = 0x0, ///< Leave value of pad reset unmodified
+	GpioResetPwrGood = 0x1, ///< Powergood reset
+	GpioResetDeep = 0x3,    ///< Deep GPIO Reset
+	GpioResetNormal = 0x5,  ///< GPIO Reset
+	GpioResetResume = 0x7 ///< Resume Reset (applicable only for GPD group)
+} GPIO_RESET_CONFIG;
+
+///
+/// GPIO Electrical Configuration
+/// Set GPIO termination and Pad Tolerance (applicable only for some pads)
+/// Field from GpioTermDefault to GpioTermNative can be OR'ed with
+/// GpioTolerance1v8.
+///
+typedef enum {
+	GpioTermDefault = 0x0,  ///< Leave termination setting unmodified
+	GpioTermNone = 0x1,     ///< none
+	GpioTermWpd5K = 0x5,    ///< 5kOhm weak pull-down
+	GpioTermWpd20K = 0x9,   ///< 20kOhm weak pull-down
+	GpioTermWpu1K = 0x13,   ///< 1kOhm weak pull-up
+	GpioTermWpu2K = 0x17,   ///< 2kOhm weak pull-up
+	GpioTermWpu5K = 0x15,   ///< 5kOhm weak pull-up
+	GpioTermWpu20K = 0x19,  ///< 20kOhm weak pull-up
+	GpioTermWpu1K2K = 0x1B, ///< 1kOhm & 2kOhm weak pull-up
+	GpioTermNative = 0x1F,  ///< Native function controls pads termination
+	GpioNoTolerance1v8 = (0x1 << 5), ///< Disable 1.8V pad tolerance
+	GpioTolerance1v8 = (0x3 << 5)    ///< Enable 1.8V pad tolerance
+} GPIO_ELECTRICAL_CONFIG;
+
+///
+/// GPIO LockConfiguration
+/// Set GPIO configuration lock and output state lock
+/// GpioLockPadConfig and GpioLockOutputState can be OR'ed
+///
+typedef enum {
+	GpioLockDefault = 0x0,    ///< Leave lock setting unmodified
+	GpioPadConfigLock = 0x3,  ///< Lock Pad Configuration
+	GpioOutputStateLock = 0x5 ///< Lock GPIO pad output value
+} GPIO_LOCK_CONFIG;
+
+///
+/// Other GPIO Configuration
+/// GPIO_OTHER_CONFIG is used for less often settings and for future extensions
+/// Supported settings:
+///  - RX raw override to '1' - allows to override input value to '1'
+///     This setting is applicable only if in input mode (both in GPIO and
+///     native usage).
+///     The override takes place at the internal pad state directly from buffer
+///     and before the RXINV.
+///
+typedef enum {
+	GpioRxRaw1Default = 0x0, ///< Use default input override value
+	GpioRxRaw1Dis = 0x1,     ///< Don't override input
+	GpioRxRaw1En = 0x3       ///< Override input to '1'
+} GPIO_OTHER_CONFIG;
+
+//
+// Possible values of Pad Ownership
+//
+typedef enum {
+	GpioPadOwnHost = 0x0,
+	GpioPadOwnCsme = 0x1,
+	GpioPadOwnIsh = 0x2,
+} GPIO_PAD_OWN;
+
+typedef uint32_t GPIO_PAD;
+
+struct pad_config {
+	GPIO_PAD GpioPad;
+	struct GPIO_CONFIG GpioConfig;
+};
+
+/* Configure GPIOs with mainboard provided settings */
+void gpio_configure_pads(const struct pad_config *gpio, size_t num);
+
+#endif /* __ACPI__ */
+#endif /* _DENVERTON_NS_GPIO_H_ */
diff --git a/src/soc/intel/denverton_ns/include/soc/gpio_defs.h b/src/soc/intel/denverton_ns/include/soc/gpio_defs.h
new file mode 100644
index 0000000..9b63a08
--- /dev/null
+++ b/src/soc/intel/denverton_ns/include/soc/gpio_defs.h
@@ -0,0 +1,500 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2015 Google Inc.
+ * Copyright (C) 2015-2017 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 _DENVERTON_NS_GPIO_DEFS_H_
+#define _DENVERTON_NS_GPIO_DEFS_H_
+
+#include <soc/pcr.h>
+
+/*
+* There are 3 GPIO groups. North Community, South Community DFX/Group0/Group1.
+* The GPIO groups are accessed through register blocks called communities.
+*/
+
+#define V_PCH_GPIO_NC_PAD_MAX 41
+#define V_PCH_GPIO_SC_DFX_PAD_MAX 18
+#define V_PCH_GPIO_SC0_PAD_MAX 53
+#define V_PCH_GPIO_SC1_PAD_MAX 42
+#define V_PCH_GPIO_GROUP_MAX 4
+
+//
+// GPIO Community 0 Private Configuration Registers
+//
+
+//
+// Power Group NORTH_ALL
+//
+#define R_PCH_PCR_GPIO_NC_PAD_OWN 0x20
+#define R_PCH_PCR_GPIO_NC_GPI_VWM_EN 0x70
+#define R_PCH_PCR_GPIO_NC_PADCFGLOCK 0x90
+#define R_PCH_PCR_GPIO_NC_PADCFGLOCKTX 0x94
+#define R_PCH_PCR_GPIO_NC1_PADCFGLOCK_1 0x98
+#define R_PCH_PCR_GPIO_NC1_PADCFGLOCKTX_1 0x9C
+#define R_PCH_PCR_GPIO_NC_HOSTSW_OWN 0xC0
+#define R_PCH_PCR_GPIO_NC_GPI_IS 0x0100
+#define R_PCH_PCR_GPIO_NC_GPI_IE 0x0120
+#define R_PCH_PCR_GPIO_NC_GPI_GPE_STS 0x0140
+#define R_PCH_PCR_GPIO_NC_GPI_GPE_EN 0x0160
+#define R_PCH_PCR_GPIO_NC_SMI_STS 0x0180
+#define R_PCH_PCR_GPIO_NC_SMI_EN 0x01A0
+#define R_PCH_PCR_GPIO_NC_NMI_STS 0x01C0
+#define R_PCH_PCR_GPIO_NC_NMI_EN 0x01E0
+#define R_PCH_PCR_GPIO_NC_PADCFG_OFFSET 0x400
+
+//
+// GPIO Community 1 Private Configuration Registers
+//
+
+//
+// Power Group SOUTH_DFX
+//
+#define R_PCH_PCR_GPIO_SC_DFX_PAD_OWN 0x20
+#define R_PCH_PCR_GPIO_SC_DFX_GPI_VWM_EN 0x70
+#define R_PCH_PCR_GPIO_SC_DFX_PADCFGLOCK 0x90
+#define R_PCH_PCR_GPIO_SC_DFX_PADCFGLOCKTX 0x94
+#define R_PCH_PCR_GPIO_SC_DFX_HOSTSW_OWN 0xC0
+#define R_PCH_PCR_GPIO_SC_DFX_GPI_IS 0x0100
+#define R_PCH_PCR_GPIO_SC_DFX_GPI_IE 0x0120
+#define R_PCH_PCR_GPIO_SC_DFX_GPI_GPE_STS 0x0140
+#define R_PCH_PCR_GPIO_SC_DFX_GPI_GPE_EN 0x0160
+#define R_PCH_PCR_GPIO_SC_DFX_PADCFG_OFFSET 0x400
+//
+// Power Group SOUTH_GROUP0
+//
+#define R_PCH_PCR_GPIO_SC0_PAD_OWN 0x2C
+#define R_PCH_PCR_GPIO_SC0_GPI_VWM_EN 0x74
+#define R_PCH_PCR_GPIO_SC0_PADCFGLOCK 0x98
+#define R_PCH_PCR_GPIO_SC0_PADCFGLOCKTX 0x9C
+#define R_PCH_PCR_GPIO_SC0_HOSTSW_OWN 0xC4
+#define R_PCH_PCR_GPIO_SC0_GPI_IS 0x0104
+#define R_PCH_PCR_GPIO_SC0_GPI_IE 0x0124
+#define R_PCH_PCR_GPIO_SC0_GPI_GPE_STS 0x0144
+#define R_PCH_PCR_GPIO_SC0_GPI_GPE_EN 0x0164
+#define R_PCH_PCR_GPIO_SC0_SMI_STS 0x0184
+#define R_PCH_PCR_GPIO_SC0_SMI_EN 0x01A4
+#define R_PCH_PCR_GPIO_SC0_NMI_STS 0x01C4
+#define R_PCH_PCR_GPIO_SC0_NMI_EN 0x01E4
+#define R_PCH_PCR_GPIO_SC0_PADCFG_OFFSET 0x490
+//
+// Power Group SOUTH_GROUP1
+//
+#define R_PCH_PCR_GPIO_SC1_PAD_OWN 0x48
+#define R_PCH_PCR_GPIO_SC1_GPI_VWM_EN 0x7C
+#define R_PCH_PCR_GPIO_SC1_PADCFGLOCK 0xA8
+#define R_PCH_PCR_GPIO_SC1_PADCFGLOCKTX 0xAC
+#define R_PCH_PCR_GPIO_SC1_HOSTSW_OWN 0xCC
+#define R_PCH_PCR_GPIO_SC1_GPI_IS 0x010C
+#define R_PCH_PCR_GPIO_SC1_GPI_IE 0x012C
+#define R_PCH_PCR_GPIO_SC1_GPI_GPE_STS 0x014C
+#define R_PCH_PCR_GPIO_SC1_GPI_GPE_EN 0x016C
+#define R_PCH_PCR_GPIO_SC1_SMI_STS 0x018C
+#define R_PCH_PCR_GPIO_SC1_SMI_EN 0x01AC
+#define R_PCH_PCR_GPIO_SC1_NMI_STS 0x01CC
+#define R_PCH_PCR_GPIO_SC1_NMI_EN 0x01EC
+#define R_PCH_PCR_GPIO_SC1_PADCFG_OFFSET 0x638
+
+#define R_PCH_PCR_GPIO_GPP_PADCFGLOCK_NORTH_ALL_0 0x90
+#define R_PCH_PCR_GPIO_GPP_PADCFGLOCKTX_NORTH_ALL_0 0x94
+#define R_PCH_PCR_GPIO_GPP_PADCFGLOCK_NORTH_ALL_1 0x98
+#define R_PCH_PCR_GPIO_GPP_PADCFGLOCKTX_NORTH_ALL_1 0x9C
+
+#define R_PCH_PCR_GPIO_GPP_PADCFGLOCK_SOUTH_DFX_0 0x90
+#define R_PCH_PCR_GPIO_GPP_PADCFGLOCKTX_SOUTH_DFX_0 0x94
+#define R_PCH_PCR_GPIO_GPP_PADCFGLOCK_SOUTH_GROUP0_0 0x98
+#define R_PCH_PCR_GPIO_GPP_PADCFGLOCKTX_SOUTH_GROUP0_0 0x9C
+#define R_PCH_PCR_GPIO_GPP_PADCFGLOCK_SOUTH_GROUP0_1 0xA0
+#define R_PCH_PCR_GPIO_GPP_PADCFGLOCKTX_SOUTH_GROUP0_1 0xA4
+#define R_PCH_PCR_GPIO_GPP_PADCFGLOCK_SOUTH_GROUP1_0 0xA8
+#define R_PCH_PCR_GPIO_GPP_PADCFGLOCKTX_SOUTH_GROUP1_0 0xAC
+#define R_PCH_PCR_GPIO_GPP_PADCFGLOCK_SOUTH_GROUP1_1 0xB0
+#define R_PCH_PCR_GPIO_GPP_PADCFGLOCKTX_SOUTH_GROUP1_1 0xB4
+
+//
+// Pad Configuration Register DW0
+//
+
+// Pad Reset Config
+#define B_PCH_GPIO_RST_CONF ((1 << 31) | (1 << 30))
+#define N_PCH_GPIO_RST_CONF 30
+#define V_PCH_GPIO_RST_CONF_POW_GOOD 0x00
+#define V_PCH_GPIO_RST_CONF_DEEP_RST 0x01
+#define V_PCH_GPIO_RST_CONF_GPIO_RST 0x02
+#define V_PCH_GPIO_RST_CONF_RESUME_RST 0x03 // Only for GPD Group
+
+// RX Pad State Select
+#define B_PCH_GPIO_RX_PAD_STATE (1 << 29)
+#define N_PCH_GPIO_RX_PAD_STATE 29
+#define V_PCH_GPIO_RX_PAD_STATE_RAW 0x00
+#define V_PCH_GPIO_RX_PAD_STATE_INT 0x01
+
+// RX Raw Overrride to 1
+#define B_PCH_GPIO_RX_RAW1 (1 << 28)
+#define N_PCH_GPIO_RX_RAW1 28
+#define V_PCH_GPIO_RX_RAW1_DIS 0x00
+#define V_PCH_GPIO_RX_RAW1_EN 0x01
+
+// RX Level/Edge Configuration
+#define B_PCH_GPIO_RX_LVL_EDG ((1 << 26) | (1 << 25))
+#define N_PCH_GPIO_RX_LVL_EDG 25
+#define V_PCH_GPIO_RX_LVL_EDG_LVL 0x00
+#define V_PCH_GPIO_RX_LVL_EDG_EDG 0x01
+#define V_PCH_GPIO_RX_LVL_EDG_0 0x02
+#define V_PCH_GPIO_RX_LVL_EDG_RIS_FAL 0x03
+
+// RX Level/Edge Configuration
+#define B_PCH_GPIO_PRE_GFRX_SEL (1 << 24)
+#define N_PCH_GPIO_PRE_GFRX_SEL 24
+#define V_PCH_GPIO_PRE_GFRX_SEL_DIS 0x00
+#define V_PCH_GPIO_PRE_GFRX_SEL_EN 0x01
+
+// RX Invert
+#define B_PCH_GPIO_RXINV (1 << 23)
+#define N_PCH_GPIO_RXINV 23
+#define V_PCH_GPIO_RXINV_NO 0x00
+#define V_PCH_GPIO_RXINV_YES 0x01
+
+// RXTXENCFG
+#define B_PCH_GPIO_RXTXENCFG ((1 << 22) | (1 << 21))
+#define N_PCH_GPIO_RXTXENCFG 21
+#define V_PCH_GPIO_RXTXENCFG_DEF_FUN 0x00
+#define V_PCH_GPIO_RXTXENCFG_TX_EN_L 0x01
+#define V_PCH_GPIO_RXTXENCFG_TX_EN_H 0x02
+#define V_PCH_GPIO_RXTXENCFG_TXRXEN 0x03
+
+// GPIO Input Route IOxAPIC
+#define B_PCH_GPIO_RX_APIC_ROUTE (1 << 20)
+#define N_PCH_GPIO_RX_APIC_ROUTE 20
+#define V_PCH_GPIO_RX_APIC_ROUTE_DIS 0x00
+#define V_PCH_GPIO_RX_APIC_ROUTE_EN 0x01
+
+// GPIO Input Route SCI
+#define B_PCH_GPIO_RX_SCI_ROUTE (1 << 10)
+#define N_PCH_GPIO_RX_SCI_ROUTE 19
+#define V_PCH_GPIO_RX_SCI_ROUTE_DIS 0x00
+#define V_PCH_GPIO_RX_SCI_ROUTE_EN 0x01
+
+// GPIO Input Route SMI
+#define B_PCH_GPIO_RX_SMI_ROUTE (1 << 18)
+#define N_PCH_GPIO_RX_SMI_ROUTE 18
+#define V_PCH_GPIO_RX_SMI_ROUTE_DIS 0x00
+#define V_PCH_GPIO_RX_SMI_ROUTE_EN 0x01
+
+// GPIO Input Route NMI
+#define B_PCH_GPIO_RX_NMI_ROUTE (1 << 17)
+#define N_PCH_GPIO_RX_NMI_ROUTE 17
+#define V_PCH_GPIO_RX_NMI_ROUTE_DIS 0x00
+#define V_PCH_GPIO_RX_NMI_ROUTE_EN 0x01
+
+// GPIO Pad Mode
+#define B_PCH_GPIO_PAD_MODE ((1 << 12) | (1 << 11) | (1 << 10))
+#define N_PCH_GPIO_PAD_MODE 10
+#define V_PCH_GPIO_PAD_MODE_GPIO 0
+#define V_PCH_GPIO_PAD_MODE_NAT_1 1
+#define V_PCH_GPIO_PAD_MODE_NAT_2 2
+#define V_PCH_GPIO_PAD_MODE_NAT_3 3
+#define V_PCH_GPIO_PAD_MODE_NAT_4 4
+#define V_PCH_GPIO_PAD_MODE_NAT_5 5
+#define V_PCH_GPIO_PAD_MODE_NAT_6 6
+#define V_PCH_GPIO_PAD_MODE_NAT_7 7
+
+// GPIO RX Disable
+#define B_PCH_GPIO_RXDIS (1 << 9)
+#define N_PCH_GPIO_RXDIS 9
+#define V_PCH_GPIO_RXDIS_EN 0x00
+#define V_PCH_GPIO_RXDIS_DIS 0x01
+
+// GPIO TX Disable
+#define B_PCH_GPIO_TXDIS (1 << 8)
+#define N_PCH_GPIO_TXDIS 8
+#define V_PCH_GPIO_TXDIS_EN 0x00
+#define V_PCH_GPIO_TXDIS_DIS 0x01
+
+// GPIO RX State
+#define B_PCH_GPIO_RX_STATE (1 << 1)
+#define N_PCH_GPIO_RX_STATE 1
+#define V_PCH_GPIO_RX_STATE_LOW 0x00
+#define V_PCH_GPIO_RX_STATE_HIGH 0x01
+
+// GPIO TX State
+#define B_PCH_GPIO_TX_STATE (1 << 0)
+#define N_PCH_GPIO_TX_STATE 0
+#define V_PCH_GPIO_TX_STATE_LOW 0x00
+#define V_PCH_GPIO_TX_STATE_HIGH 0x01
+
+//
+// Pad Configuration Register DW1
+//
+
+// Padtol
+#define B_PCH_GPIO_PADTOL (1 << 25)
+#define N_PCH_GPIO_PADTOL 25
+#define V_PCH_GPIO_PADTOL_NONE 0x00
+#define V_PCH_GPIO_PADTOL_CLEAR 0x00
+#define V_PCH_GPIO_PADTOL_SET 0x01
+
+// Termination
+#define B_PCH_GPIO_TERM ((1 << 13) | (1 << 12) | (1 << 11) | (1 << 10))
+#define N_PCH_GPIO_TERM 10
+#define V_PCH_GPIO_TERM_WPD_NONE 0x00
+#define V_PCH_GPIO_TERM_WPD_5K 0x02
+#define V_PCH_GPIO_TERM_WPD_20K 0x04
+#define V_PCH_GPIO_TERM_WPU_NONE 0x08
+#define V_PCH_GPIO_TERM_WPU_1K 0x09
+#define V_PCH_GPIO_TERM_WPU_2K 0x0B
+#define V_PCH_GPIO_TERM_WPU_5K 0x0A
+#define V_PCH_GPIO_TERM_WPU_20K 0x0C
+#define V_PCH_GPIO_TERM_WPU_1K_2K 0x0D
+#define V_PCH_GPIO_TERM_NATIVE 0x0F
+
+#define PID_NorthCommunity PID_GPIOCOM0
+#define PID_SouthCommunity PID_GPIOCOM1
+
+// GPIO_MISC0
+// HSUART0: 101, 102, 13, 98
+// HSUART1: 96, 97,95 94
+
+#define GPIO_SMB3_CLTT_DATA 12
+#define R_PAD_CFG_DW0_SMB3_CLTT_DATA 0x490
+#define PID_SMB3_CLTT_DATA PID_SouthCommunity
+
+#define GPIO_SMB3_CLTT_CLK 13
+#define R_PAD_CFG_DW0_SMB3_CLTT_CLK 0x498
+#define PID_SMB3_CLTT_CLK PID_SouthCommunity
+
+#define GPIO_PCIE_CLKREQ5_N 98
+#define R_PAD_CFG_DW0_PCIE_CLKREQ5_N 0x4A0
+#define PID_PCIE_CLKREQ5_N PID_SouthCommunity
+
+#define GPIO_PCIE_CLKREQ6_N 99
+#define R_PAD_CFG_DW0_PCIE_CLKREQ6_N 0x4a8
+#define PID_PCIE_CLKREQ6_N PID_SouthCommunity
+
+#define GPIO_PCIE_CLKREQ7_N 100
+#define R_PAD_CFG_DW0_PCIE_CLKREQ7_N 0x4b0
+#define PID_PCIE_CLKREQ7_N PID_SouthCommunity
+
+#define GPIO_UART0_RXD 101
+#define R_PAD_CFG_DW0_UART0_RXD 0x4b8
+#define PID_UART0_RXD PID_SouthCommunity
+
+#define GPIO_UART0_TXD 102
+#define R_PAD_CFG_DW0_UART0_TXD 0x4c0
+#define PID_UART0_TXD PID_SouthCommunity
+
+#define GPIO_UART1_RXD 96
+#define R_PAD_CFG_DW0_UART1_RXD 0x5b8
+#define PID_UART1_RXD PID_SouthCommunity
+
+#define GPIO_UART1_TXD 97
+#define R_PAD_CFG_DW0_UART1_TXD 0x5c0
+#define PID_UART1_TXD PID_SouthCommunity
+
+#define GPIO_SATA1_SDOUT 95
+#define R_PAD_CFG_DW0_SATA1_SDOUT 0x5b0
+#define PID_SATA1_SDOUT PID_SouthCommunity
+
+#define GPIO_SATA0_SDOUT 94
+#define R_PAD_CFG_DW0_SATA0_SDOUT 0x5a8
+#define PID_SATA0_SDOUT PID_SouthCommunity
+
+///
+/// Denverton GPIO Groups
+///
+
+#define GPIO_DNV_GROUP_NC 0x0100
+#define GPIO_DNV_GROUP_SC_DFX 0x0101
+#define GPIO_DNV_GROUP_SC0 0x0102
+#define GPIO_DNV_GROUP_SC1 0x0103
+#define GPIO_DNV_GROUP_MIN GPIO_DNV_GROUP_NC
+#define GPIO_DNV_GROUP_MAX GPIO_DNV_GROUP_SC1
+#define NORTH_ALL_GBE0_SDP0 0x01000000
+#define NORTH_ALL_GBE1_SDP0 0x01000001
+#define NORTH_ALL_GBE0_SDP1 0x01000002
+#define NORTH_ALL_GBE1_SDP1 0x01000003
+#define NORTH_ALL_GBE0_SDP2 0x01000004
+#define NORTH_ALL_GBE1_SDP2 0x01000005
+#define NORTH_ALL_GBE0_SDP3 0x01000006
+#define NORTH_ALL_GBE1_SDP3 0x01000007
+#define NORTH_ALL_GBE2_LED0 0x01000008
+#define NORTH_ALL_GBE2_LED1 0x01000009
+#define NORTH_ALL_GBE0_I2C_CLK 0x0100000A
+#define NORTH_ALL_GBE0_I2C_DATA 0x0100000B
+#define NORTH_ALL_GBE1_I2C_CLK 0x0100000C
+#define NORTH_ALL_GBE1_I2C_DATA 0x0100000D
+#define NORTH_ALL_NCSI_RXD0 0x0100000E
+#define NORTH_ALL_NCSI_CLK_IN 0x0100000F
+#define NORTH_ALL_NCSI_RXD1 0x01000010
+#define NORTH_ALL_NCSI_CRS_DV 0x01000011
+#define NORTH_ALL_NCSI_ARB_IN 0x01000012
+#define NORTH_ALL_NCSI_TX_EN 0x01000013
+#define NORTH_ALL_NCSI_TXD0 0x01000014
+#define NORTH_ALL_NCSI_TXD1 0x01000015
+#define NORTH_ALL_NCSI_ARB_OUT 0x01000016
+#define NORTH_ALL_GBE0_LED0 0x01000017
+#define NORTH_ALL_GBE0_LED1 0x01000018
+#define NORTH_ALL_GBE1_LED0 0x01000019
+#define NORTH_ALL_GBE1_LED1 0x0100001A
+#define NORTH_ALL_GPIO_0 0x0100001B
+#define NORTH_ALL_PCIE_CLKREQ0_N 0x0100001C
+#define NORTH_ALL_PCIE_CLKREQ1_N 0x0100001D
+#define NORTH_ALL_PCIE_CLKREQ2_N 0x0100001E
+#define NORTH_ALL_PCIE_CLKREQ3_N 0x0100001F
+#define NORTH_ALL_PCIE_CLKREQ4_N 0x01000020
+#define NORTH_ALL_GPIO_1 0x01000021
+#define NORTH_ALL_GPIO_2 0x01000022
+#define NORTH_ALL_SVID_ALERT_N 0x01000023
+#define NORTH_ALL_SVID_DATA 0x01000024
+#define NORTH_ALL_SVID_CLK 0x01000025
+#define NORTH_ALL_THERMTRIP_N 0x01000026
+#define NORTH_ALL_PROCHOT_N 0x01000027
+#define NORTH_ALL_MEMHOT_N 0x01000028
+#define SOUTH_DFX_DFX_PORT_CLK0 0x01010000
+#define SOUTH_DFX_DFX_PORT_CLK1 0x01010001
+#define SOUTH_DFX_DFX_PORT0 0x01010002
+#define SOUTH_DFX_DFX_PORT1 0x01010003
+#define SOUTH_DFX_DFX_PORT2 0x01010004
+#define SOUTH_DFX_DFX_PORT3 0x01010005
+#define SOUTH_DFX_DFX_PORT4 0x01010006
+#define SOUTH_DFX_DFX_PORT5 0x01010007
+#define SOUTH_DFX_DFX_PORT6 0x01010008
+#define SOUTH_DFX_DFX_PORT7 0x01010009
+#define SOUTH_DFX_DFX_PORT8 0x0101000A
+#define SOUTH_DFX_DFX_PORT9 0x0101000B
+#define SOUTH_DFX_DFX_PORT10 0x0101000C
+#define SOUTH_DFX_DFX_PORT11 0x0101000D
+#define SOUTH_DFX_DFX_PORT12 0x0101000E
+#define SOUTH_DFX_DFX_PORT13 0x0101000F
+#define SOUTH_DFX_DFX_PORT14 0x01010010
+#define SOUTH_DFX_DFX_PORT15 0x01010011
+#define SOUTH_GROUP0_SMB3_CLTT_DATA 0x01020000
+#define SOUTH_GROUP0_SMB3_CLTT_CLK 0x01020001
+#define SOUTH_GROUP0_GPIO_12 0x01020000
+#define SOUTH_GROUP0_SMB5_GBE_ALRT_N 0x01020001
+#define SOUTH_GROUP0_PCIE_CLKREQ5_N 0x01020002
+#define SOUTH_GROUP0_PCIE_CLKREQ6_N 0x01020003
+#define SOUTH_GROUP0_PCIE_CLKREQ7_N 0x01020004
+#define SOUTH_GROUP0_UART0_RXD 0x01020005
+#define SOUTH_GROUP0_UART0_TXD 0x01020006
+#define SOUTH_GROUP0_SMB5_GBE_CLK 0x01020007
+#define SOUTH_GROUP0_SMB5_GBE_DATA 0x01020008
+#define SOUTH_GROUP0_ERROR2_N 0x01020009
+#define SOUTH_GROUP0_ERROR1_N 0x0102000A
+#define SOUTH_GROUP0_ERROR0_N 0x0102000B
+#define SOUTH_GROUP0_IERR_N 0x0102000C
+#define SOUTH_GROUP0_MCERR_N 0x0102000D
+#define SOUTH_GROUP0_SMB0_LEG_CLK 0x0102000E
+#define SOUTH_GROUP0_SMB0_LEG_DATA 0x0102000F
+#define SOUTH_GROUP0_SMB0_LEG_ALRT_N 0x01020010
+#define SOUTH_GROUP0_SMB1_HOST_DATA 0x01020011
+#define SOUTH_GROUP0_SMB1_HOST_CLK 0x01020012
+#define SOUTH_GROUP0_SMB2_PECI_DATA 0x01020013
+#define SOUTH_GROUP0_SMB2_PECI_CLK 0x01020014
+#define SOUTH_GROUP0_SMB4_CSME0_DATA 0x01020015
+#define SOUTH_GROUP0_SMB4_CSME0_CLK 0x01020016
+#define SOUTH_GROUP0_SMB4_CSME0_ALRT_N 0x01020017
+#define SOUTH_GROUP0_USB_OC0_N 0x01020018
+#define SOUTH_GROUP0_FLEX_CLK_SE0 0x01020019
+#define SOUTH_GROUP0_FLEX_CLK_SE1 0x0102001A
+#define SOUTH_GROUP0_GPIO_4 0x0102001B
+#define SOUTH_GROUP0_GPIO_5 0x0102001C
+#define SOUTH_GROUP0_GPIO_6 0x0102001D
+#define SOUTH_GROUP0_GPIO_7 0x0102001E
+#define SOUTH_GROUP0_SATA0_LED_N 0x0102001F
+#define SOUTH_GROUP0_SATA1_LED_N 0x01020020
+#define SOUTH_GROUP0_SATA_PDETECT0 0x01020021
+#define SOUTH_GROUP0_SATA_PDETECT1 0x01020022
+#define SOUTH_GROUP0_SATA0_SDOUT 0x01020023
+#define SOUTH_GROUP0_SATA1_SDOUT 0x01020024
+#define SOUTH_GROUP0_UART1_RXD 0x01020025
+#define SOUTH_GROUP0_UART1_TXD 0x01020026
+#define SOUTH_GROUP0_GPIO_8 0x01020027
+#define SOUTH_GROUP0_GPIO_9 0x01020028
+#define SOUTH_GROUP0_TCK 0x01020029
+#define SOUTH_GROUP0_TRST_N 0x0102002A
+#define SOUTH_GROUP0_TMS 0x0102002B
+#define SOUTH_GROUP0_TDI 0x0102002C
+#define SOUTH_GROUP0_TDO 0x0102002D
+#define SOUTH_GROUP0_CX_PRDY_N 0x0102002E
+#define SOUTH_GROUP0_CX_PREQ_N 0x0102002F
+#define SOUTH_GROUP0_CTBTRIGINOUT 0x01020030
+#define SOUTH_GROUP0_CTBTRIGOUT 0x01020031
+#define SOUTH_GROUP0_DFX_SPARE2 0x01020032
+#define SOUTH_GROUP0_DFX_SPARE3 0x01020033
+#define SOUTH_GROUP0_DFX_SPARE4 0x01020034
+#define SOUTH_GROUP1_SUSPWRDNACK 0x01030000
+#define SOUTH_GROUP1_PMU_SUSCLK 0x01030001
+#define SOUTH_GROUP1_ADR_TRIGGER 0x01030002
+#define SOUTH_GROUP1_PMU_AC_PRESENT 0x01030002
+#define SOUTH_GROUP1_PMU_SLP_S45_N 0x01030003
+#define SOUTH_GROUP1_PMU_SLP_S3_N 0x01030004
+#define SOUTH_GROUP1_PMU_WAKE_N 0x01030005
+#define SOUTH_GROUP1_PMU_PWRBTN_N 0x01030006
+#define SOUTH_GROUP1_PMU_RESETBUTTON_N 0x01030007
+#define SOUTH_GROUP1_PMU_PLTRST_N 0x01030008
+#define SOUTH_GROUP1_SUS_STAT_N 0x01030009
+#define SOUTH_GROUP1_SLP_S0IX_N 0x0103000A
+#define SOUTH_GROUP1_SPI_CS0_N 0x0103000B
+#define SOUTH_GROUP1_SPI_CS1_N 0x0103000C
+#define SOUTH_GROUP1_SPI_MOSI_IO0 0x0103000D
+#define SOUTH_GROUP1_SPI_MISO_IO1 0x0103000E
+#define SOUTH_GROUP1_SPI_IO2 0x0103000F
+#define SOUTH_GROUP1_SPI_IO3 0x01030010
+#define SOUTH_GROUP1_SPI_CLK 0x01030011
+#define SOUTH_GROUP1_SPI_CLK_LOOPBK 0x01030012
+#define SOUTH_GROUP1_ESPI_IO0 0x01030013
+#define SOUTH_GROUP1_ESPI_IO1 0x01030014
+#define SOUTH_GROUP1_ESPI_IO2 0x01030015
+#define SOUTH_GROUP1_ESPI_IO3 0x01030016
+#define SOUTH_GROUP1_ESPI_CS0_N 0x01030017
+#define SOUTH_GROUP1_ESPI_CLK 0x01030018
+#define SOUTH_GROUP1_ESPI_RST_N 0x01030019
+#define SOUTH_GROUP1_ESPI_ALRT0_N 0x0103001A
+#define SOUTH_GROUP1_GPIO_10 0x0103001B
+#define SOUTH_GROUP1_GPIO_11 0x0103001C
+#define SOUTH_GROUP1_ESPI_CLK_LOOPBK 0x0103001D
+#define SOUTH_GROUP1_EMMC_CMD 0x0103001E
+#define SOUTH_GROUP1_EMMC_STROBE 0x0103001F
+#define SOUTH_GROUP1_EMMC_CLK 0x01030020
+#define SOUTH_GROUP1_EMMC_D0 0x01030021
+#define SOUTH_GROUP1_EMMC_D1 0x01030022
+#define SOUTH_GROUP1_EMMC_D2 0x01030023
+#define SOUTH_GROUP1_EMMC_D3 0x01030024
+#define SOUTH_GROUP1_EMMC_D4 0x01030025
+#define SOUTH_GROUP1_EMMC_D5 0x01030026
+#define SOUTH_GROUP1_EMMC_D6 0x01030027
+#define SOUTH_GROUP1_EMMC_D7 0x01030028
+#define SOUTH_GROUP1_GPIO_3 0x01030029
+
+// BIT15-0  - pad number
+// BIT31-16 - group info
+//   BIT23- 16 - group index
+//   BIT31- 24 - chipset ID (default to 0x01)
+#define PAD_INFO_MASK 0x0000FFFF
+#define GROUP_INFO_POSITION 16
+#define GROUP_INFO_MASK 0xFFFF0000
+#define GROUP_INDEX_MASK 0x00FF0000
+#define UNIQUE_ID_MASK 0xFF000000
+#define UNIQUE_ID_POSITION 24
+
+#define GPIO_PAD_DEF(Group, Pad) (uint32_t)((Group << 16) + Pad)
+#define GPIO_GET_GROUP_INDEX(Group) (Group & 0xFF)
+#define GPIO_GET_GROUP_FROM_PAD(Pad) (Pad >> 16)
+#define GPIO_GET_GROUP_INDEX_FROM_PAD(Pad) GPIO_GET_GROUP_INDEX((Pad >> 16))
+#define GPIO_GET_PAD_NUMBER(Pad) (Pad & 0xFFFF)
+#define GPIO_GET_CHIPSET_ID(Pad) (Pad >> 24)
+
+#endif /* _DENVERTON_NS_GPIO_DEFS_H_ */
diff --git a/src/soc/intel/denverton_ns/include/soc/iomap.h b/src/soc/intel/denverton_ns/include/soc/iomap.h
new file mode 100644
index 0000000..29b231f
--- /dev/null
+++ b/src/soc/intel/denverton_ns/include/soc/iomap.h
@@ -0,0 +1,40 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google Inc.
+ * Copyright (C) 2014-2017 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 _DENVERTON_NS_IOMAP_H_
+#define _DENVERTON_NS_IOMAP_H_
+
+/*
+ * Memory Mapped IO bases.
+ */
+
+/* Northbridge BARs */
+#define DEFAULT_PCIEXBAR CONFIG_MMCONF_BASE_ADDRESS /* 4 KB per PCIe device */
+#define DEFAULT_MCHBAR 0xfed10000		    /* 16 KB */
+
+/* Southbridge internal device IO BARs (Set to match FSP settings) */
+#define DEFAULT_PMBASE 0x1800
+#define DEFAULT_ACPI_BASE DEFAULT_PMBASE
+#define DEFAULT_TCO_BASE 0x400
+
+/* Southbridge internal device MEM BARs (Set to match FSP settings) */
+#define DEFAULT_PCR_BASE 0xfd000000
+#define DEFAULT_PWRM_BASE 0xfe000000
+#define DEFAULT_HPET_ADDR CONFIG_HPET_ADDRESS
+#define DEFAULT_SPI_BASE 0xfed01000
+
+#endif /* _DENVERTON_NS_IOMAP_H_ */
diff --git a/src/soc/intel/denverton_ns/include/soc/lpc.h b/src/soc/intel/denverton_ns/include/soc/lpc.h
new file mode 100644
index 0000000..b1b4462
--- /dev/null
+++ b/src/soc/intel/denverton_ns/include/soc/lpc.h
@@ -0,0 +1,63 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google Inc.
+ * Copyright (C) 2013 - 2014 Sage Electronic Engineering, LLC.
+ * Copyright (C) 2014 - 2017 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 _DENVERTON_NS_LPC_H_
+#define _DENVERTON_NS_LPC_H_
+
+/* PCI Configuration Space (D31:F0): LPC */
+#define PCH_LPC_DEV PCI_DEV(0, LPC_DEV, LPC_FUNC)
+
+#define SERIRQ_CNTL 0x64
+#define LPC_IO_DEC 0x80  /* IO Decode Ranges Register */
+#define FDD_LPC_SHIFT 12 /* LPC_IO_DEC[12] */
+#define FDD_DEC_MASK 1
+#define FDD_DEC_3F8 0   /* 3F0h - 3F5Fh, 3F7h (Primary) */
+#define FDD_DEC_2F8 1   /* 370h - 375h, 377h (Secondary) */
+#define LPT_LPC_SHIFT 8 /* LPC_IO_DEC[9:8] */
+#define LPT_DEC_MASK 3
+#define LPT_DEC_378 0    /* 378h - 37Fh and 778h - 77Fh */
+#define LPT_DEC_278 1    /* 278h - 27Fh and 678h - 67Fh */
+#define LPT_DEC_3BC 2    /* 3BCh - 3BEh and 7BCh - 7BEh */
+#define COMB_LPC_SHIFT 4 /* LPC_IO_DEC[6:4] */
+#define COMA_LPC_SHIFT 0 /* LPC_IO_DEC[2:0] */
+#define COM_DEC_MASK 7
+#define COM_DEC_3F8 0	 /* 3F8h - 3FFh (COM1) */
+#define COM_DEC_2F8 1	 /* 2F8h - 2FFh (COM2) */
+#define COM_DEC_220 2	 /* 220h - 227h */
+#define COM_DEC_228 3	 /* 228h - 22Fh */
+#define COM_DEC_238 4	 /* 238h - 23Fh */
+#define COM_DEC_2E8 5	 /* 2E8h - 2EFh (COM4) */
+#define COM_DEC_338 6	 /* 338h - 33Fh */
+#define COM_DEC_3E8 7	 /* 3E8h - 3EFh (COM3) */
+#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 */
+
+#endif /* _DENVERTON_NS_LPC_H_ */
diff --git a/src/soc/intel/denverton_ns/include/soc/msr.h b/src/soc/intel/denverton_ns/include/soc/msr.h
new file mode 100644
index 0000000..4d1ac70
--- /dev/null
+++ b/src/soc/intel/denverton_ns/include/soc/msr.h
@@ -0,0 +1,114 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google, Inc.
+ * Copyright (C) 2014 - 2017 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 _DENVERTON_NS_MSR_H_
+#define _DENVERTON_NS_MSR_H_
+
+#define MSR_PLATFORM_ID 0x17
+#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 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
+
+/* MTRRcap_MSR bits */
+#define SMRR_SUPPORTED (1 << 11)
+#define PRMRR_SUPPORTED (1 << 12)
+
+/* IA32_MISC_ENABLE bits */
+#define SPEED_STEP_ENABLE_BIT (1 << 16)
+
+/* Read BCLK from MSR */
+unsigned int bus_freq_khz(void);
+
+#endif /* _DENVERTON_NS_MSR_H_ */
diff --git a/src/soc/intel/denverton_ns/include/soc/nvs.h b/src/soc/intel/denverton_ns/include/soc/nvs.h
new file mode 100644
index 0000000..cf10823
--- /dev/null
+++ b/src/soc/intel/denverton_ns/include/soc/nvs.h
@@ -0,0 +1,74 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008 - 2009 coresystems GmbH
+ * Copyright (C) 2011 Google Inc
+ * Copyright (C) 2014 - 2017 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 _DENVERTON_NS_NVS_H_
+#define _DENVERTON_NS_NVS_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 */
+	u32 p80d; /* 0x0b - Debug port (IO 0x80) value */
+	u8 lids;  /* 0x0f - LID state (open = 1) */
+	u8 pwrs;  /* 0x10 - Power state (AC = 1) */
+	u8 pcnt;  /* 0x11 - Processor Count */
+	u8 tpmp;  /* 0x12 - TPM Present and Enabled */
+	u8 tlvl;  /* 0x13 - Throttle Level */
+	u8 ppcm;  /* 0x14 - Maximum P-state usable by OS */
+	u8 rsvd1[11];
+
+	/* Device Config */
+	u8 s5u0; /* 0x20 - Enable USB0 in S5 */
+	u8 s5u1; /* 0x21 - Enable USB1 in S5 */
+	u8 s3u0; /* 0x22 - Enable USB0 in S3 */
+	u8 s3u1; /* 0x23 - Enable USB1 in S3 */
+	u8 tact; /* 0x24 - Thermal Active trip point */
+	u8 tpsv; /* 0x25 - Thermal Passive trip point */
+	u8 tcrt; /* 0x26 - Thermal Critical trip point */
+	u8 dpte; /* 0x27 - Enable DPTF */
+	u8 rsvd2[8];
+
+	/* Base Addresses */
+	u32 obsolete_cmem; /* 0x30 - CBMEM TOC */
+	u32 tolm;	  /* 0x34 - Top of Low Memory */
+	u32 cbmc;	  /* 0x38 - coreboot memconsole */
+	u32 mmiob;	 /* 0x3c - MMIO Base Low */
+	u32 mmiol;	 /* 0x40 - MMIO Base Limit */
+	u64 mmiohb;	/* 0x44 - MMIO Base High */
+	u64 mmiohl;	/* 0x4c - MMIO Base Limit */
+	u32 tsegb;	 /* 0x54 - TSEG Base Low */
+	u32 tsegl;	 /* 0x58 - TSEG Length/Size */
+	u8 rsvd3[164];
+
+} __attribute__((packed)) global_nvs_t;
+
+void acpi_create_gnvs(global_nvs_t *gnvs);
+#ifdef __SMM__
+/* Used in SMM to find the ACPI GNVS address */
+global_nvs_t *smm_get_gnvs(void);
+#endif
+
+#endif /* _DENVERTON_NS_NVS_H_ */
diff --git a/src/soc/intel/denverton_ns/include/soc/p2sb.h b/src/soc/intel/denverton_ns/include/soc/p2sb.h
new file mode 100644
index 0000000..6d5a415
--- /dev/null
+++ b/src/soc/intel/denverton_ns/include/soc/p2sb.h
@@ -0,0 +1,67 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 - 2017 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 _DENVERTON_NS_P2SB_H_
+#define _DENVERTON_NS_P2SB_H_
+
+/* Generate MP-table IRQ numbers for PCI devices. */
+#define IO_APIC0 1
+
+/* P2SB Bridge Registers (D31:F1) */
+#define PCH_P2SB_DEV PCI_DEV(0, P2SB_DEV, P2SB_FUNC)
+
+/* IO/MEM BARs */
+#define SBREG_LO 0x10
+#define MASK_SBREG_LO 0xff000000
+#define SBREG_HI 0x14
+#define MASK_SBREG_HI 0xffffffff
+
+/* ITSS PCRs (PID:ITSS) */
+#define PCR_ITSS_PIRQA_ROUT 0x3100
+#define PCR_ITSS_PIRQB_ROUT 0x3101
+#define PCR_ITSS_PIRQC_ROUT 0x3102
+#define PCR_ITSS_PIRQD_ROUT 0x3103
+#define PCR_ITSS_PIRQE_ROUT 0x3104
+#define PCR_ITSS_PIRQF_ROUT 0x3105
+#define PCR_ITSS_PIRQG_ROUT 0x3106
+#define PCR_ITSS_PIRQH_ROUT 0x3107
+
+#define PCR_ITSS_PIR00 0x3140
+#define PCR_ITSS_PIR01 0x3142
+#define PCR_ITSS_PIR02 0x3144
+#define PCR_ITSS_PIR03 0x3146
+#define PCR_ITSS_PIR04 0x3148
+#define PCR_ITSS_PIR05 0x314A
+#define PCR_ITSS_PIR06 0x314C
+#define PCR_ITSS_PIR07 0x314E
+#define PCR_ITSS_PIR08 0x3150
+#define PCR_ITSS_PIR09 0x3152
+#define PCR_ITSS_PIR10 0x3154
+#define PCR_ITSS_PIR11 0x3156
+#define PCR_ITSS_PIR12 0x3158
+
+#define PCH_PCR_ITSS_GIC 0x31FC ///< General Interrupt Control
+///< Max IRQ entry size, 1 = 24 entry size, 0 = 120 entry size
+#define PCH_PCR_ITSS_GIC_MAX_IRQ_24 \
+	(1 << 9)
+#define PCH_PCR_ITSS_GIC_AME (1 << 17) ///< Alternate Access Mode Enable
+#define PCH_PCR_ITSS_GIC_SPS (1 << 16) ///< Shutdown Policy Select
+#define PCH_PCR_ITSS_IPC0 0x3200       ///< Interrupt Polarity Control 0
+#define PCH_PCR_ITSS_IPC1 0x3204       ///< Interrupt Polarity Control 1
+#define PCH_PCR_ITSS_IPC2 0x3208       ///< Interrupt Polarity Control 2
+#define PCH_PCR_ITSS_IPC3 0x320C       ///< Interrupt Polarity Control 3
+
+#endif /* _DENVERTON_NS_P2SB_H_ */
diff --git a/src/soc/intel/denverton_ns/include/soc/pattrs.h b/src/soc/intel/denverton_ns/include/soc/pattrs.h
new file mode 100644
index 0000000..b558e24
--- /dev/null
+++ b/src/soc/intel/denverton_ns/include/soc/pattrs.h
@@ -0,0 +1,55 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google Inc.
+ * Copyright (C) 2017 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 _DENVERTON_NS_PATTRS_H_
+#define _DENVERTON_NS_PATTRS_H_
+
+#include <stdint.h>
+#include <cpu/x86/msr.h>
+
+enum { IACORE_MIN, IACORE_LFM, IACORE_MAX, IACORE_TURBO, IACORE_END };
+
+/* The pattrs structure is a common place to stash pertinent information
+ * about the processor or platform. Instead of going to the source (msrs, cpuid)
+ * every time an attribute is needed use the pattrs structure.
+ */
+struct pattrs {
+	msr_t platform_id;
+	msr_t platform_info;
+	int iacore_ratios[IACORE_END];
+	int iacore_vids[IACORE_END];
+	uint32_t cpuid;
+	int revid;
+	int stepping;
+	const void *microcode_patch;
+	int address_bits;
+	int num_cpus;
+	unsigned int bclk_khz;
+};
+
+/* This is just to hide the abstraction w/o relying on how the underlying
+ * storage is allocated. */
+#define PATTRS_GLOB_NAME __global_pattrs
+#define DEFINE_PATTRS struct pattrs PATTRS_GLOB_NAME
+extern DEFINE_PATTRS;
+
+static inline const struct pattrs *pattrs_get(void)
+{
+	return &PATTRS_GLOB_NAME;
+}
+
+#endif /* _DENVERTON_NS_PATTRS_H_ */
diff --git a/src/soc/intel/denverton_ns/include/soc/pci_devs.h b/src/soc/intel/denverton_ns/include/soc/pci_devs.h
new file mode 100644
index 0000000..138b6f6
--- /dev/null
+++ b/src/soc/intel/denverton_ns/include/soc/pci_devs.h
@@ -0,0 +1,204 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google Inc.
+ * Copyright (C) 2014-2017 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 _DENVERTON_NS_PCI_DEVS_H_
+#define _DENVERTON_NS_PCI_DEVS_H_
+
+/* All these devices live on bus 0 with the associated device and function */
+
+#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
+
+/* SoC transaction router */
+#define SA_DEV 0x0
+#define SA_FUNC 0
+#define SA_DEVID 0x1980
+#define SOC_DEV SA_DEV
+#define SOC_FUNC SA_FUNC
+#define SOC_DEVID SA_DEVID
+
+/* RAS */
+#define RAS_DEV 0x4
+#define RAS_FUNC 0
+#define RAS_DEVID 0x19a1
+
+/* Root Complex Event Collector */
+#define RCEC_DEV 0x5
+#define RCEC_FUNC 0
+#define RCEC_DEVID 0x19a2
+
+/* Virtual Root Port 2 */
+#define VRP2_DEV 0x6
+#define VRP2_FUNC 0
+#define VRP2_DEVID 0x19a3
+
+/* PCIe Root Ports */
+#define PCIE_DEV 0x09
+#define MAX_PCIE_PORT 0x8
+#define PCIE_PORT1_DEV 0x09
+#define PCIE_PORT1_FUNC 0
+#define PCIE_PORT1_DEVID 0x19a4
+#define PCIE_PORT2_DEV 0x0a
+#define PCIE_PORT2_FUNC 0
+#define PCIE_PORT2_DEVID 0x19a5
+#define PCIE_PORT3_DEV 0x0b
+#define PCIE_PORT3_FUNC 0
+#define PCIE_PORT3_DEVID 0x19a6
+#define PCIE_PORT4_DEV 0x0c
+#define PCIE_PORT4_FUNC 0
+#define PCIE_PORT4_DEVID 0x19a7
+#define PCIE_PORT5_DEV 0x0e
+#define PCIE_PORT5_FUNC 0
+#define PCIE_PORT5_DEVID 0x19a8
+#define PCIE_PORT6_DEV 0x0f
+#define PCIE_PORT6_FUNC 0
+#define PCIE_PORT6_DEVID 0x19a9
+#define PCIE_PORT7_DEV 0x10
+#define PCIE_PORT7_FUNC 0
+#define PCIE_PORT7_DEVID 0x19aa
+#define PCIE_PORT8_DEV 0x11
+#define PCIE_PORT8_FUNC 0
+#define PCIE_PORT8_DEVID 0x19ab
+
+/* SMBUS 2 */
+#define SMBUS2_DEV 0x12
+#define SMBUS2_FUNC 0
+#define SMBUS2_DEVID 0x19ac
+
+/* SATA */
+#define SATA_DEV 0x13
+#define SATA_FUNC 0
+#define AHCI_DEVID 0x19b2
+#define SATA2_DEV 0x14
+#define SATA2_FUNC 0
+#define AHCI2_DEVID 0x19c2
+
+/* xHCI */
+#define XHCI_DEV 0x15
+#define XHCI_FUNC 0
+#define XHCI_DEVID 0x19d0
+
+/* Virtual Root Port 0 */
+#define VRP0_DEV 0x16
+#define VRP0_FUNC 0
+#define VRP0_DEVID 0x19d1
+
+/* Virtual Root Port 1 */
+#define VRP1_DEV 0x17
+#define VRP1_FUNC 0
+#define VRP1_DEVID 0x19d2
+
+/* CSME */
+#define ME_HECI_DEV 0x18
+#define ME_HECI1_DEV ME_HECI_DEV
+#define ME_HECI1_FUNC 0
+#define ME_HECI1_DEVID 0x19d3
+#define ME_HECI2_DEV ME_HECI_DEV
+#define ME_HECI2_FUNC 1
+#define ME_HECI2_DEVID 0x19d4
+#define ME_IEDR_DEV ME_HECI_DEV
+#define ME_IEDR_FUNC 2
+#define ME_IEDR_DEVID 0x19ea
+#define ME_MEKT_DEV ME_HECI_DEV
+#define ME_MEKT_FUNC 3
+#define ME_MEKT_DEVID 0x19d5
+#define ME_HECI3_DEV ME_HECI_DEV
+#define ME_HECI3_FUNC 4
+#define ME_HECI3_DEVID 0x19d6
+
+/* HSUART */
+#define HSUART_DEV 0x1a
+#define HSUART_DEVID 0x19d8
+#define HSUART1_DEV HSUART_DEV
+#define HSUART1_FUNC 0
+#define HSUART1_DEVID HSUART_DEVID
+#define HSUART2_DEV HSUART_DEV
+#define HSUART2_FUNC 1
+#define HSUART2_DEVID HSUART_DEVID
+#define HSUART3_DEV HSUART_DEV
+#define HSUART3_FUNC 2
+#define HSUART3_DEVID HSUART_DEVID
+
+/* IE */
+#define IE_HECI_DEV 0x1b
+#define IE_HECI1_DEV IE_HECI_DEV
+#define IE_HECI1_FUNC 0
+#define IE_HECI1_DEVID 0x19e5
+#define IE_HECI2_DEV IE_HECI_DEV
+#define IE_HECI2_FUNC 1
+#define IE_HECI2_DEVID 0x19e6
+#define IE_IEDR_DEV IE_HECI_DEV
+#define IE_IEDR_FUNC 2
+#define IE_IEDR_DEVID 0x19e7
+#define IE_MEKT_DEV IE_HECI_DEV
+#define IE_MEKT_FUNC 3
+#define IE_MEKT_DEVID 0x19e8
+#define IE_HECI3_DEV IE_HECI_DEV
+#define IE_HECI3_FUNC 4
+#define IE_HECI3_DEVID 0x19e9
+
+/* MMC Port */
+#define MMC_DEV 0x1c
+#define MMC_FUNC 0
+#define MMC_DEVID 0x19db
+
+/* Platform Controller Unit */
+#define PCU_DEV 0x1f
+#define LPC_DEV PCU_DEV
+#define LPC_FUNC 0
+#define LPC_DEVID 0x19dc
+#define P2SB_DEV PCU_DEV
+#define P2SB_FUNC 1
+#define P2SB_DEVID 0x19dd
+#define PMC_DEV PCU_DEV
+#define PMC_FUNC 2
+#define PMC_DEVID 0x19de
+#define SMBUS_DEV PCU_DEV
+#define SMBUS_FUNC 4
+#define SMBUS_DEVID 0x19df
+#define SPI_DEV PCU_DEV
+#define SPI_FUNC 5
+#define SPI_DEVID 0x19e0
+#define NPK_DEV PCU_DEV
+#define NPK_FUNC 7
+#define NPK_DEVID 0x19e1
+
+/* TODO - New added */
+#define SA_DEV_SLOT_ROOT 0x00
+#define SA_DEVFN_ROOT _SA_DEVFN(ROOT)
+#define SA_DEV_ROOT _SA_DEV(ROOT)
+
+#define PCH_DEV_SLOT_LPC 0x1f
+#define PCH_DEVFN_LPC _PCH_DEVFN(LPC, 0)
+#define PCH_DEVFN_SPI _PCH_DEVFN(LPC, 5)
+#define PCH_DEV_LPC _PCH_DEV(LPC, 0)
+#define PCH_DEV_SPI _PCH_DEV(LPC, 5)
+
+#endif /* _DENVERTON_NS_PCI_DEVS_H_ */
diff --git a/src/soc/intel/denverton_ns/include/soc/pcr.h b/src/soc/intel/denverton_ns/include/soc/pcr.h
new file mode 100644
index 0000000..6015776
--- /dev/null
+++ b/src/soc/intel/denverton_ns/include/soc/pcr.h
@@ -0,0 +1,35 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 - 2017 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 _DENVERTON_NS_PCR_H_
+#define _DENVERTON_NS_PCR_H_
+
+/* PCR BASE */
+#include <soc/iomap.h>
+
+/* PCR address */
+#define PCH_PCR_ADDRESS(Pid, Offset) \
+	(DEFAULT_PCR_BASE | ((uint8_t)(Pid) << 16) | (uint16_t)(Offset))
+
+/* PID for PCR and SBI */
+typedef enum {
+	PID_SMB = 0xCF,
+	PID_ITSS = 0xD0,
+	PID_GPIOCOM0 = 0xC2,
+	PID_GPIOCOM1 = 0xC5,
+} PCH_SBI_PID;
+
+#endif /* _DENVERTON_NS_PCR_H_ */
diff --git a/src/soc/intel/denverton_ns/include/soc/pm.h b/src/soc/intel/denverton_ns/include/soc/pm.h
new file mode 100644
index 0000000..2dc8781
--- /dev/null
+++ b/src/soc/intel/denverton_ns/include/soc/pm.h
@@ -0,0 +1,59 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015 - 2017 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 _DENVERTON_NS_PM_H_
+#define _DENVERTON_NS_PM_H_
+
+#include <arch/io.h>
+#include <soc/pmc.h>
+
+#define SLEEP_STATE_S0 0
+#define SLEEP_STATE_S3 3
+#define SLEEP_STATE_S5 5
+
+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);
+
+/* Power Management Utility Functions. */
+uint32_t clear_smi_status(void);
+uint16_t clear_pm1_status(void);
+uint32_t clear_tco_status(void);
+uint32_t clear_gpe_status(void);
+void clear_pmc_status(void);
+void enable_smi(uint32_t mask);
+void disable_smi(uint32_t mask);
+void enable_pm1(uint16_t events);
+void enable_pm1_control(uint32_t mask);
+void disable_pm1_control(uint32_t mask);
+void enable_gpe(uint32_t mask);
+void disable_gpe(uint32_t mask);
+void disable_all_gpe(void);
+
+#endif /* _DENVERTON_NS_PM_H_ */
diff --git a/src/soc/intel/denverton_ns/include/soc/pmc.h b/src/soc/intel/denverton_ns/include/soc/pmc.h
new file mode 100644
index 0000000..edb5c55
--- /dev/null
+++ b/src/soc/intel/denverton_ns/include/soc/pmc.h
@@ -0,0 +1,255 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google Inc.
+ * Copyright (C) 2014 - 2017 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 _DENVERTON_NS_PMC_H_
+#define _DENVERTON_NS_PMC_H_
+
+/* PCI Configuration Space (D31:F2): PMC/ACPI */
+#define PCH_PMC_DEV PCI_DEV(0, PMC_DEV, PMC_FUNC)
+
+/* Memory mapped IO registers behind PMC_BASE_ADDRESS */
+#define PMC_ACPI_BASE 0x40 /* IO BAR */
+#define MASK_PMC_ACPI_BASE 0xfffc
+#define PMC_ACPI_CNT 0x44
+#define PMC_ACPI_CNT_PWRM_EN (1 << 8)			   /* PWRM enable */
+#define PMC_ACPI_CNT_ACPI_EN (1 << 7)			   /* ACPI eanble */
+#define PMC_ACPI_CNT_SCIS ((1 << 2) | (1 << 1) | (1 << 0)) /* SCI IRQ select \
+							      */
+#define PMC_ACPI_CNT_SCIS_MASK 0x07
+#define PMC_ACPI_CNT_SCIS_IRQ9 0x00
+#define PMC_ACPI_CNT_SCIS_IRQ10 0x01
+#define PMC_ACPI_CNT_SCIS_IRQ11 0x02
+#define PMC_ACPI_CNT_SCIS_DISABLE 0x03
+#define PMC_ACPI_CNT_SCIS_IRQ20 0x04
+#define PMC_ACPI_CNT_SCIS_IRQ21 0x05
+#define PMC_ACPI_CNT_SCIS_IRQ22 0x06
+#define PMC_ACPI_CNT_SCIS_IRQ23 0x07
+#define PMC_PWRM_BASE   0x48 /* MEM BAR */
+#define   MASK_PMC_PWRM_BASE    0xfffff000 /* 4K alignment */
+#define PMC_GEN_PMCON_A               0xA0
+#define PMC_GEN_PMCON_B               0xA4
+#define   PMC_GEN_PMCON_B_RTC_PWR_STS   0x04
+#define   PMC_GEN_PMCON_B_PWR_FLR       0x02
+#define   PMC_GEN_PMCON_B_AFTERG3_EN    0x00
+#define PMC_ETR3                      0xAC
+#define   PMC_ETR3_CF9LOCK              BIT31 ///< CF9h Lockdown
+#define   PMC_ETR3_CF9GR                BIT20 ///< CF9h Global Reset
+
+/* IO Mapped registers behind ACPI_BASE_ADDRESS */
+#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 SLP_EN (1 << 13)
+#define SLP_TYP_SHIFT 10
+#define SLP_TYP (7 << SLP_TYP_SHIFT)
+#define SLP_TYP_S0 0
+#define SLP_TYP_S1 1
+#define SLP_TYP_S3 5
+#define SLP_TYP_S4 6
+#define SLP_TYP_S5 7
+#define GBL_RLS (1 << 2)
+#define BM_RLD (1 << 1)
+#define SCI_EN (1 << 0)
+#define PM1_TMR 0x08
+#define SMI_EN 0x30
+#define LEGACY_USB3_EN (1 << 31) // Legacy USB3 SMI logic
+#define GPIO_UNLOCK_EN (1 << 27) // GPIO unlock SMI
+#define INTEL_USB2_EN (1 << 18)  // Intel-Specific USB2 SMI logic
+#define LEGACY_USB2_EN (1 << 17) // Legacy USB2 SMI logic
+#define PERIODIC_EN (1 << 14)    // SMI on PERIODIC_STS in SMI_STS
+#define TCO_EN (1 << 13)	 // Enable TCO Logic (BIOSWE et al)
+#define MCSMI_EN (1 << 11)       // Trap microcontroller range access
+#define BIOS_RLS (1 << 7)	// asserts SCI on bit set
+#define SWSMI_TMR_EN (1 << 6)    // start software smi timer on bit set
+#define APMC_EN (1 << 5)	 // Writes to APM_CNT cause SMI#
+#define SLP_SMI_EN (1 << 4)      // Write to SLP_EN in PM1_CNT asserts SMI#
+#define LEGACY_USB_EN (1 << 3)   // Legacy USB circuit SMI logic
+#define BIOS_EN (1 << 2)	 // Assert SMI# on setting GBL_RLS bit
+#define EOS (1 << 1)		 // End of SMI (deassert SMI#)
+#define GBL_SMI_EN (1 << 0)      // SMI# generation at all?
+#define SMI_STS 0x34
+#define SMI_STS_LEGACY_USB3 (1 << 31)
+#define SMI_STS_GPIO_UNLOCK (1 << 27)
+#define SMI_STS_SPI (1 << 26)
+#define SMI_STS_MONITOR (1 << 21)
+#define SMI_STS_PCI_EXP (1 << 20)
+#define SMI_STS_PATCH (1 << 19)
+#define SMI_STS_INTEL_USB2 (1 << 18)
+#define SMI_STS_LEGACY_USB2 (1 << 17)
+#define SMI_STS_SMBUS (1 << 16)
+#define SMI_STS_SERIRQ (1 << 15)
+#define SMI_STS_PERIODIC (1 << 14)
+#define SMI_STS_TCO (1 << 13)
+#define SMI_STS_DEVMON (1 << 12)
+#define SMI_STS_MCSMI (1 << 11)
+#define SMI_STS_GPE1 (1 << 10)
+#define SMI_STS_GPE0 (1 << 9)
+#define SMI_STS_PM1 (1 << 8)
+#define SMI_STS_SWSMI_TMR (1 << 6)
+#define SMI_STS_APMC (1 << 5)
+#define SMI_STS_SLP_SMI (1 << 4)
+#define SMI_STS_LEGACY_USB (1 << 3)
+#define SMI_STS_BIOS (1 << 2)
+#define GPE_CTRL 0x40
+#define SWGPE_CTRL	(1 << 17)
+#define PM2_CNT 0x50
+#define GPE0_STS 0x80
+#define GPIO31_STS (1 << 31)
+#define GPIO30_STS (1 << 30)
+#define GPIO29_STS (1 << 29)
+#define GPIO28_STS (1 << 28)
+#define GPIO27_STS (1 << 27)
+#define GPIO26_STS (1 << 26)
+#define GPIO25_STS (1 << 25)
+#define GPIO24_STS (1 << 24)
+#define GPIO23_STS (1 << 23)
+#define GPIO22_STS (1 << 22)
+#define GPIO21_STS (1 << 21)
+#define GPIO20_STS (1 << 20)
+#define GPIO19_STS (1 << 19)
+#define GPIO18_STS (1 << 18)
+#define GPIO17_STS (1 << 17)
+#define GPIO16_STS (1 << 16)
+#define GPIO15_STS (1 << 15)
+#define GPIO14_STS (1 << 14)
+#define GPIO13_STS (1 << 13)
+#define GPIO12_STS (1 << 12)
+#define GPIO11_STS (1 << 11)
+#define GPIO10_STS (1 << 10)
+#define GPIO09_STS (1 << 09)
+#define GPIO08_STS (1 << 08)
+#define GPIO07_STS (1 << 07)
+#define GPIO06_STS (1 << 06)
+#define GPIO05_STS (1 << 05)
+#define GPIO04_STS (1 << 04)
+#define GPIO03_STS (1 << 03)
+#define GPIO02_STS (1 << 02)
+#define GPIO01_STS (1 << 01)
+#define GPIO00_STS (1 << 00)
+#define GPE0_STS_63_32 0x84
+#define GPE0_STS_95_64 0x88
+#define GPE0_STS_127_96 0x8c
+#define PME_B0_STS (1 << 13)
+#define ME_SCI_STS (1 << 12)
+#define PME_STS (1 << 11)
+#define PCI_EXP_STS (1 << 9)
+#define RI_STS (1 << 8)
+#define SMB_WAK_STS (1 << 7)
+#define TCOSCI_STS (1 << 6)
+#define IE_SCI_STS (1 << 3)
+#define SWGPE_STS (1 << 2)
+#define HOT_PLUG_STS (1 << 1)
+#define GPE0_EN 0x90
+#define GPIO31_EN (1 << 31)
+#define GPIO30_EN (1 << 30)
+#define GPIO29_EN (1 << 29)
+#define GPIO28_EN (1 << 28)
+#define GPIO27_EN (1 << 27)
+#define GPIO26_EN (1 << 26)
+#define GPIO25_EN (1 << 25)
+#define GPIO24_EN (1 << 24)
+#define GPIO23_EN (1 << 23)
+#define GPIO22_EN (1 << 22)
+#define GPIO21_EN (1 << 21)
+#define GPIO20_EN (1 << 20)
+#define GPIO19_EN (1 << 19)
+#define GPIO18_EN (1 << 18)
+#define GPIO17_EN (1 << 17)
+#define GPIO16_EN (1 << 16)
+#define GPIO15_EN (1 << 15)
+#define GPIO14_EN (1 << 14)
+#define GPIO13_EN (1 << 13)
+#define GPIO12_EN (1 << 12)
+#define GPIO11_EN (1 << 11)
+#define GPIO10_EN (1 << 10)
+#define GPIO09_EN (1 << 09)
+#define GPIO08_EN (1 << 08)
+#define GPIO07_EN (1 << 07)
+#define GPIO06_EN (1 << 06)
+#define GPIO05_EN (1 << 05)
+#define GPIO04_EN (1 << 04)
+#define GPIO03_EN (1 << 03)
+#define GPIO02_EN (1 << 02)
+#define GPIO01_EN (1 << 01)
+#define GPIO00_EN (1 << 00)
+#define GPE0_EN_63_32 0x94
+#define GPE0_EN_95_64 0x98
+#define GPE0_EN_127_96 0x9c
+#define PME_B0_EN (1 << 13)
+#define ME_SCI_EN (1 << 12)
+#define PME_EN (1 << 11)
+#define PCI_EXP_EN (1 << 9)
+#define RI_EN (1 << 8)
+#define SMB_WAK_EN (1 << 7)
+#define TCOSCI_EN (1 << 6)
+#define IE_SCI_EN (1 << 3)
+#define SWGPE_EN (1 << 2)
+#define HOT_PLUG_EN (1 << 1)
+
+/* TCO registers and fields live behind TCOBASE I/O bar in SMBus device. */
+#define TCO_RLD 0x00
+#define TCO1_STS 0x04
+#define TCO1_STS_TCO_SLVSEL (1 << 13)
+#define TCO1_STS_CPUSERR (1 << 12)
+#define TCO1_STS_CPUSMI (1 << 10)
+#define TCO1_STS_CPUSCI (1 << 9)
+#define TCO1_STS_BIOSWR (1 << 8)
+#define TCO1_STS_NEWCENTURY (1 << 7)
+#define TCO1_STS_TIMEOUT (1 << 3)
+#define TCO1_STS_TCO_INT (1 << 2)
+#define TCO1_STS_OS_TCO_SMI (1 << 1)
+#define TCO1_STS_NMI2SMI (1 << 0)
+#define TCO2_STS 0x06
+#define TCO2_STS_SMLINK_SLAVE_SMI 0x04
+#define TCO2_STS_SECOND_TO 0x02
+#define TCO2_STS_INTRD_DET 0x01
+#define TCO1_CNT 0x08
+#define TCO_LOCK (1 << 12)
+#define TCO_TMR_HLT (1 << 11)
+#define TCO2_CNT 0x0a
+#define TCO_TMR 0x12
+
+/* I/O ports */
+#define RST_CNT 0xcf9
+#define FULL_RST (1 << 3)
+#define RST_CPU (1 << 2)
+#define SYS_RST (1 << 1)
+
+#if !defined(__ASSEMBLER__) && !defined(__ACPI__)
+
+#if IS_ENABLED(CONFIG_ELOG)
+void southcluster_log_state(void);
+#else
+static inline void southcluster_log_state(void) {}
+#endif
+
+#endif /* !defined(__ASSEMBLER__) && !defined(__ACPI__) */
+
+#endif /* _DENVERTON_NS_PMC_H_ */
diff --git a/src/soc/intel/denverton_ns/include/soc/ramstage.h b/src/soc/intel/denverton_ns/include/soc/ramstage.h
new file mode 100644
index 0000000..63ed432
--- /dev/null
+++ b/src/soc/intel/denverton_ns/include/soc/ramstage.h
@@ -0,0 +1,30 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 - 2017 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 _DENVERTON_NS_SOC_RAMSTAGE_H_
+#define _DENVERTON_NS_SOC_RAMSTAGE_H_
+
+#include <device/device.h>
+#include <fsp/api.h>
+#include <fsp/util.h>
+#include <soc/intel/common/opregion.h>
+
+void denverton_init_cpus(device_t dev);
+void mainboard_silicon_init_params(FSPS_UPD *params);
+void southcluster_enable_dev(device_t dev);
+
+extern struct pci_operations soc_pci_ops;
+
+#endif
diff --git a/src/soc/intel/denverton_ns/include/soc/romstage.h b/src/soc/intel/denverton_ns/include/soc/romstage.h
new file mode 100644
index 0000000..2c6c5ce
--- /dev/null
+++ b/src/soc/intel/denverton_ns/include/soc/romstage.h
@@ -0,0 +1,28 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 - 2017 Intel Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _SOC_DENVERTON_NS_ROMSTAGE_H_
+#define _SOC_DENVERTON_NS_ROMSTAGE_H_
+
+#include <arch/cpu.h>
+#include <fsp/api.h>
+
+/* These functions are weak and can be overridden by a mainboard functions. */
+void mainboard_memory_init_params(FSPM_UPD *mupd);
+void mainboard_config_gpios(void);
+
+#endif /* _SOC_DENVERTON_NS_ROMSTAGE_H_ */
diff --git a/src/soc/intel/denverton_ns/include/soc/sata.h b/src/soc/intel/denverton_ns/include/soc/sata.h
new file mode 100644
index 0000000..afa39b5
--- /dev/null
+++ b/src/soc/intel/denverton_ns/include/soc/sata.h
@@ -0,0 +1,31 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google Inc.
+ * Copyright (C) 2014 - 2017 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 _DENVERTON_NS_SATA_H
+#define _DENVERTON_NS_SATA_H
+
+/* PCI Configuration Space (D19:F0): SATA #0 */
+/* PCI Configuration Space (D20:F0): SATA #1 */
+#define PCH_SATA0_DEV PCI_DEV(0, SATA_DEV, SATA_FUNC)
+#define PCH_SATA1_DEV PCI_DEV(0, SATA2_DEV, SATA2_FUNC)
+
+#define SATA_MAP 0x90
+#define SATA_MAP_AHCI (0 << 6)
+#define SATA_MAP_RAID (1 << 6)
+#define SATA_PSC 0x92
+
+#endif //_DENVERTON_NS_SATA_H
diff --git a/src/soc/intel/denverton_ns/include/soc/smbus.h b/src/soc/intel/denverton_ns/include/soc/smbus.h
new file mode 100644
index 0000000..5dbeecc
--- /dev/null
+++ b/src/soc/intel/denverton_ns/include/soc/smbus.h
@@ -0,0 +1,85 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2005 Yinghai Lu <yinghailu@gmail.com>
+ * Copyright (C) 2009 coresystems GmbH
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015 - 2017 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 _DENVERTON_NS_SMBUS_H_
+#define _DENVERTON_NS_SMBUS_H_
+
+/* PCI Configuration Space (D31:F4): SMBus */
+#define SMB_BASE 0x20
+#define HOSTC 0x40
+#define HST_EN (1 << 0)
+#define HOSTC_SMI_EN (1 << 1)
+#define HOSTC_I2C_EN (1 << 2)
+#define SMB_RCV_SLVA 0x09
+/* SMBUS TCO base address. */
+#define TCOBASE 0x50
+#define MASK_TCOBASE 0xffe0
+#define TCOCTL 0x54
+#define TCOBASE_EN (1 << 8)
+#define TCOBASE_LOCK (1 << 0)
+
+/* SMBus I/O bits. */
+#define SMBHSTSTAT 0x0
+#define HST_HBSY (1 << 0)
+#define HST_INTR (1 << 1)
+#define HST_DERR (1 << 2)
+#define HST_BERR (1 << 3)
+#define HST_BYTE_DONE_STS (1 << 7)
+#define HST_HSTS_ALL 0xFF
+#define SMBHSTCTL 0x2
+#define HST_LAST_BYTE (1 << 5)
+#define HST_START (1 << 6)
+#define HST_CMD_IIC_READ 0x18
+#define HST_READ 0x01 // RW
+#define SMBHSTCMD 0x3
+#define SMBXMITADD 0x4
+#define SMBHSTDAT0 0x5
+#define SMBHSTDAT1 0x6
+#define SMBBLKDAT 0x7
+#define SMBTRNSADD 0x9
+#define SMBSLVDATA 0xa
+#define SMBHSTAUXC 0xd
+#define SMLINK_PIN_CTL 0xe
+#define SMBUS_PIN_CTL 0xf
+
+/*
+ * SMBus Private Config Registers (PID:SMB)
+ */
+#define PCR_SMBUS_TCOCFG 0x00	/* TCO Configuration register */
+#define PCR_SMBUS_TCOCFG_IE (1 << 7) /* TCO IRQ Enable */
+#define PCR_SMBUS_TCOCFG_IS 7	/* TCO IRQ Select */
+#define PCR_SMBUS_TCOCFG_IRQ_9 0x00
+#define PCR_SMBUS_TCOCFG_IRQ_10 0x01
+#define PCR_SMBUS_TCOCFG_IRQ_11 0x02
+#define PCR_SMBUS_TCOCFG_IRQ_20 0x04   /* only if APIC enabled */
+#define PCR_SMBUS_TCOCFG_IRQ_21 0x05   /* only if APIC enabled */
+#define PCR_SMBUS_TCOCFG_IRQ_22 0x06   /* only if APIC enabled */
+#define PCR_SMBUS_TCOCFG_IRQ_23 0x07   /* only if APIC enabled */
+#define PCR_SMBUS_SMBTM 0x04	   /* SMBus Test Mode */
+#define PCR_SMBUS_SMBTM_SMBCT (1 << 1) /* SMBus Counter */
+#define PCR_SMBUS_SMBTM_SMBDG (1 << 0) /* SMBus Deglitch */
+#define PCR_SMBUS_SCTM 0x08	    /* Short Counter Test Mode */
+#define PCR_SMBUS_SCTM_SSU (1 << 31)   /* Simulation Speed-Up */
+#define PCR_SMBUS_GC 0x0C	      /* General Control */
+#define PCR_SMBUS_GC_FD (1 << 0)       /* Function Disable */
+#define PCR_SMBUS_GC_NR (1 << 1)       /* No Reboot */
+#define PCR_SMBUS_GC_SMBSCGE (1 << 2)  /* SMB Static Clock Gating Enable */
+#define PCR_SMBUS_PCE 0x10	     /* Power Control Enable */
+#define PCR_SMBUS_PCE_HAE (1 << 5)     /* Hardware Autonomous Enable */
+
+#endif /* _DENVERTON_NS_SMBUS_H_ */
diff --git a/src/soc/intel/denverton_ns/include/soc/smm.h b/src/soc/intel/denverton_ns/include/soc/smm.h
new file mode 100644
index 0000000..fe6dc82
--- /dev/null
+++ b/src/soc/intel/denverton_ns/include/soc/smm.h
@@ -0,0 +1,60 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google Inc.
+ * Copyright (C) 2014 - 2017 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 _DENVERTON_NS_SMM_H_
+#define _DENVERTON_NS_SMM_H_
+
+struct smm_relocation_attrs {
+	uint32_t smbase;
+	uint32_t smrr_base;
+	uint32_t smrr_mask;
+};
+
+/*
+ * mmap_region_granularity must to return a size which is a positive non-zero
+ * integer multiple of the SMM size when SMM is in use.  When not using SMM,
+ * this value should be set to 8 MiB.
+ */
+size_t mmap_region_granularity(void);
+
+/* Fills in the arguments for the entire SMM region covered by chipset
+ * protections. e.g. TSEG. */
+void smm_region(void **start, size_t *size);
+
+enum {
+	/* SMM handler area. */
+	SMM_SUBREGION_HANDLER,
+	/* SMM cache region. */
+	SMM_SUBREGION_CACHE,
+	/* Chipset specific area. */
+	SMM_SUBREGION_CHIPSET,
+	/* Total sub regions supported. */
+	SMM_SUBREGION_NUM,
+};
+
+/* Fills in the start and size for the requested SMM subregion. Returns
+ * 0 on susccess, < 0 on failure. */
+int smm_subregion(int sub, void **start, size_t *size);
+
+#if !defined(__PRE_RAM__) && !defined(__SMM___)
+#include <stdint.h>
+void southcluster_smm_clear_state(void);
+void southcluster_smm_enable_smi(void);
+void southcluster_smm_save_gpio_route(uint32_t route);
+#endif
+
+#endif /* _DENVERTON_NS_SMM_H_ */
diff --git a/src/soc/intel/denverton_ns/include/soc/soc_util.h b/src/soc/intel/denverton_ns/include/soc/soc_util.h
new file mode 100644
index 0000000..074ec16
--- /dev/null
+++ b/src/soc/intel/denverton_ns/include/soc/soc_util.h
@@ -0,0 +1,70 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2016 - 2017 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 _DENVERTON_NS_SOC_UTIL_H_
+#define _DENVERTON_NS_SOC_UTIL_H_
+
+#ifndef __ACPI__
+#include <device/device.h>
+
+/* Silicon revisions */
+typedef enum {
+	SILICON_REV_DENVERTON_A0 = 0x00,
+	SILICON_REV_DENVERTON_A1 = 0x01,
+	SILICON_REV_DENVERTON_B0 = 0x02,
+} silicon_revision;
+
+/* soc_util.c */
+device_t get_hostbridge_dev(void);
+device_t get_lpc_dev(void);
+device_t get_pmc_dev(void);
+device_t get_smbus_dev(void);
+
+uint32_t get_pciebase(void);
+uint32_t get_pcielength(void);
+uint32_t get_tseg_memory(void);
+uint32_t get_top_of_low_memory(void);
+uint64_t get_top_of_upper_memory(void);
+uint16_t get_pmbase(void);
+uint16_t get_tcobase(void);
+
+/*
+* Secure functions.
+*/
+void *memcpy_s(void *dest, const void *src, size_t n);
+
+void mmio_andthenor32(void *addr, uint32_t val2and, uint32_t val2or);
+uint8_t silicon_stepping(void);
+
+/*
+* MMIO Read/Write
+*/
+#define MMIO8(x) (*((volatile u8 *)(x)))
+#define MMIO16(x) (*((volatile u16 *)(x)))
+#define MMIO32(x) (*((volatile u32 *)(x)))
+
+#define MMIO_AND_OR(bits, x, and, or) \
+	(MMIO##bits(x) = ((MMIO##bits(x) & (and)) | (or)))
+
+#define MMIO8_AND_OR(x, and, or) MMIO_AND_OR(8, x, and, or)
+#define MMIO16_AND_OR(x, and, or) MMIO_AND_OR(16, x, and, or)
+#define MMIO32_AND_OR(x, and, or) MMIO_AND_OR(32, x, and, or)
+#define MMIO32_OR(x, or) MMIO_AND_OR(32, x, ~0UL, or)
+#define MMIO32_AND(x, and) MMIO_AND_OR(32, x, and, 0UL)
+
+#endif //__ACPI__
+
+#endif /* _DENVERTON_NS_SOC_UTIL_H_ */
diff --git a/src/soc/intel/denverton_ns/include/soc/systemagent.h b/src/soc/intel/denverton_ns/include/soc/systemagent.h
new file mode 100644
index 0000000..a02aea3
--- /dev/null
+++ b/src/soc/intel/denverton_ns/include/soc/systemagent.h
@@ -0,0 +1,89 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007 - 2008 coresystems GmbH
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2014 - 2017 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 _DENVERTON_NS_SYSTEMAGENT_H_
+#define _DENVERTON_NS_SYSTEMAGENT_H_
+
+#include <soc/iomap.h>
+
+/* Device 0:0.0 PCI configuration space (Host Bridge) */
+#define PCH_SA_DEV PCI_DEV(0, SA_DEV, SA_FUNC)
+
+#define MCHBAR 0x48   /* MCH space. */
+#define PCIEXBAR 0x60 /* PCI express space. */
+#define MASK_PCIEXBAR_256M 0xF0000000
+#define MASK_PCIEXBAR_128M 0xF8000000
+#define MASK_PCIEXBAR_64M 0xFC000000
+#define MASK_PCIEXBAR_LENGTH 0x6
+#define SHIFT_PCIEXBAR_LENGTH 0x1
+#define MASK_PCIEXBAR_LENGTH_256M (0x0 << SHIFT_PCIEXBAR_LENGTH)
+#define MASK_PCIEXBAR_LENGTH_128M (0x1 << SHIFT_PCIEXBAR_LENGTH)
+#define MASK_PCIEXBAR_LENGTH_64M (0x2 << SHIFT_PCIEXBAR_LENGTH)
+
+#define TOUUD_LO 0xa8 /* Top of Upper Usable DRAM - Low */
+#define MASK_TOUUD_LO 0xFFF00000
+#define TOUUD_HI 0xac /* Top of Upper Usable DRAM - High */
+#define MASK_TOUUD_HI 0x0000007F
+#define TOUUD TOUUD_LO /* Top of Upper Usable DRAM */
+#define MASK_TOUUD 0x7FFFF00000
+
+#define TSEGMB 0xb8 /* TSEG base */
+#define MASK_TSEGMB 0xFFF00000
+#define TOLUD 0xbc /* Top of Low Used Memory */
+#define MASK_TOLUD 0xFFF00000
+
+/* SideBand B-UNIT */
+#define B_UNIT 3
+
+/* SideBand C-UNIT */
+#define C_UNIT 8
+
+/* SideBand D-UNIT */
+#define D_UNIT 1
+
+/* SideBand P-UNIT */
+#define P_UNIT 4
+
+/*
+ * MCHBAR
+ */
+#define MCH_BASE_SIZE 0x8000
+#define MCH_BMISC 0x6800
+#define MCH_BMISC_SBVDRAM \
+	0x08 /* Bit 3: 1 - reads targeting boot vector are routed to DRAM. */
+#define MCH_BMISC_ABSEGINDRAM \
+	0x04 /* Bit 2: 1 - reads targeting A/B-segment are routed to DRAM. */
+#define MCH_BMISC_RFSDRAM \
+	0x02 /* Bit 1: 1 - reads targeting E-segment are routed to DRAM. */
+#define MCH_BMISC_RESDRAM \
+	0x01 /* Bit 0: 1 - reads targeting E-segment are routed to DRAM. */
+
+#define MCH_BAR_BIOS_RESET_CPL 0x7078
+#define RST_CPL_BIT (1 << 0)
+#define PCODE_INIT_DONE (1 << 8)
+#define MCH_BAR_CORE_EXISTS_MASK 0x7164
+#define MCH_BAR_CORE_DISABLE_MASK 0x7168
+
+/* Device 0:4.0 PCI configuration space (RAS) */
+
+/* Device 0:5.0 PCI configuration space (RCEC) */
+
+/* Top of 32bit usable memory */
+u32 top_of_32bit_ram(void);
+
+#endif //_DENVERTON_NS_SYSTEMAGENT_H_
diff --git a/src/soc/intel/denverton_ns/include/soc/uart.h b/src/soc/intel/denverton_ns/include/soc/uart.h
new file mode 100644
index 0000000..29e9024
--- /dev/null
+++ b/src/soc/intel/denverton_ns/include/soc/uart.h
@@ -0,0 +1,27 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2016 - 2017 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 _DENVERTON_NS_UART_H
+#define _DENVERTON_NS_UART_H
+
+#define SIZE_OF_HSUART_RES 0x100
+#define HARCUVAR_UARTS_TO_INI 3
+#define PSR_OFFSET 0x30
+#define PCI_FUNC_RDCFG_HIDE 0x74
+
+#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2 * !!(condition)]))
+
+#endif /* _DENVERTON_NS_UART_H */
diff --git a/src/soc/intel/denverton_ns/lpc.c b/src/soc/intel/denverton_ns/lpc.c
new file mode 100644
index 0000000..48e81e5
--- /dev/null
+++ b/src/soc/intel/denverton_ns/lpc.c
@@ -0,0 +1,336 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 - 2017 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 <device/pci_ids.h>
+#include <arch/io.h>
+#include <arch/ioapic.h>
+#include <arch/acpi.h>
+#include <cpu/cpu.h>
+#include <cpu/x86/smm.h>
+#include <bootstate.h>
+
+#include <soc/lpc.h>
+#include <soc/pci_devs.h>
+#include <soc/ramstage.h>
+#include <soc/iomap.h>
+#include <soc/pcr.h>
+#include <soc/p2sb.h>
+#include <soc/acpi.h>
+
+#include "chip.h"
+
+/* PCH-LP redirection entries */
+#define PCH_LP_REDIR_ETR 120
+
+/**
+ * Set miscellanous static southbridge features.
+ *
+ * @param dev PCI device with I/O APIC control registers
+ */
+static void pch_enable_ioapic(struct device *dev)
+{
+	u32 reg32;
+
+	set_ioapic_id((void *)IO_APIC_ADDR, IO_APIC0);
+
+	/* affirm full set of redirection table entries ("write once") */
+	reg32 = io_apic_read((void *)IO_APIC_ADDR, 0x01);
+
+	reg32 &= ~0x00ff0000;
+	reg32 |= (PCH_LP_REDIR_ETR - 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;
+	/* Get the chip configuration */
+	config_t *config = dev->chip_info;
+
+	/* Initialize PIRQ Routings */
+	write8((void *)PCH_PCR_ADDRESS(PID_ITSS, PCR_ITSS_PIRQA_ROUT),
+	       config->pirqa_routing);
+	write8((void *)PCH_PCR_ADDRESS(PID_ITSS, PCR_ITSS_PIRQB_ROUT),
+	       config->pirqb_routing);
+	write8((void *)PCH_PCR_ADDRESS(PID_ITSS, PCR_ITSS_PIRQC_ROUT),
+	       config->pirqc_routing);
+	write8((void *)PCH_PCR_ADDRESS(PID_ITSS, PCR_ITSS_PIRQD_ROUT),
+	       config->pirqd_routing);
+
+	write8((void *)PCH_PCR_ADDRESS(PID_ITSS, PCR_ITSS_PIRQE_ROUT),
+	       config->pirqe_routing);
+	write8((void *)PCH_PCR_ADDRESS(PID_ITSS, PCR_ITSS_PIRQF_ROUT),
+	       config->pirqf_routing);
+	write8((void *)PCH_PCR_ADDRESS(PID_ITSS, PCR_ITSS_PIRQG_ROUT),
+	       config->pirqg_routing);
+	write8((void *)PCH_PCR_ADDRESS(PID_ITSS, PCR_ITSS_PIRQH_ROUT),
+	       config->pirqh_routing);
+
+	/* Initialize device's Interrupt Routings */
+	write16((void *)PCH_PCR_ADDRESS(PID_ITSS, PCR_ITSS_PIR00),
+		config->ir00_routing);
+	write16((void *)PCH_PCR_ADDRESS(PID_ITSS, PCR_ITSS_PIR01),
+		config->ir01_routing);
+	write16((void *)PCH_PCR_ADDRESS(PID_ITSS, PCR_ITSS_PIR02),
+		config->ir02_routing);
+	write16((void *)PCH_PCR_ADDRESS(PID_ITSS, PCR_ITSS_PIR03),
+		config->ir03_routing);
+	write16((void *)PCH_PCR_ADDRESS(PID_ITSS, PCR_ITSS_PIR04),
+		config->ir04_routing);
+	write16((void *)PCH_PCR_ADDRESS(PID_ITSS, PCR_ITSS_PIR05),
+		config->ir05_routing);
+	write16((void *)PCH_PCR_ADDRESS(PID_ITSS, PCR_ITSS_PIR06),
+		config->ir06_routing);
+	write16((void *)PCH_PCR_ADDRESS(PID_ITSS, PCR_ITSS_PIR07),
+		config->ir07_routing);
+	write16((void *)PCH_PCR_ADDRESS(PID_ITSS, PCR_ITSS_PIR08),
+		config->ir08_routing);
+	write16((void *)PCH_PCR_ADDRESS(PID_ITSS, PCR_ITSS_PIR09),
+		config->ir09_routing);
+	write16((void *)PCH_PCR_ADDRESS(PID_ITSS, PCR_ITSS_PIR10),
+		config->ir10_routing);
+	write16((void *)PCH_PCR_ADDRESS(PID_ITSS, PCR_ITSS_PIR11),
+		config->ir11_routing);
+	write16((void *)PCH_PCR_ADDRESS(PID_ITSS, PCR_ITSS_PIR12),
+		config->ir12_routing);
+
+	/* Initialize device's Interrupt Polarity Control */
+	write32((void *)PCH_PCR_ADDRESS(PID_ITSS, PCH_PCR_ITSS_IPC0),
+		config->ipc0);
+	write32((void *)PCH_PCR_ADDRESS(PID_ITSS, PCH_PCR_ITSS_IPC1),
+		config->ipc1);
+	write32((void *)PCH_PCR_ADDRESS(PID_ITSS, PCH_PCR_ITSS_IPC2),
+		config->ipc2);
+	write32((void *)PCH_PCR_ADDRESS(PID_ITSS, PCH_PCR_ITSS_IPC3),
+		config->ipc3);
+
+	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 void pci_p2sb_read_resources(device_t dev)
+{
+	struct resource *res;
+
+	/* Add MMIO resource
+	 * Use 0xda as an unused index for PCR BAR.
+	 */
+	res = new_resource(dev, 0xda);
+	res->base = DEFAULT_PCR_BASE;
+	res->size = 16 * 1024 * 1024; /* 16MB PCR config space */
+	res->flags = IORESOURCE_MEM | IORESOURCE_FIXED | IORESOURCE_STORED |
+		     IORESOURCE_ASSIGNED;
+	printk(BIOS_DEBUG,
+	       "Adding P2SB PCR config space BAR 0x%08lx-0x%08lx.\n",
+	       (unsigned long)(res->base),
+	       (unsigned long)(res->base + res->size));
+
+	/* Add MMIO resource
+	 * Use 0xdb as an unused index for IOAPIC.
+	 */
+	res = new_resource(dev, 0xdb); /* IOAPIC */
+	res->base = IO_APIC_ADDR;
+	res->size = 0x00001000;
+	res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+}
+
+static void pch_enable_serial_irqs(struct device *dev)
+{
+	/* Set packet length and toggle silent mode bit for one frame. */
+	pci_write_config8(dev, SERIRQ_CNTL,
+			  (1 << 7) | (1 << 6) | ((21 - 17) << 2) | (0 << 0));
+#if !IS_ENABLED(CONFIG_SERIRQ_CONTINUOUS_MODE)
+	pci_write_config8(dev, SERIRQ_CNTL,
+			  (1 << 7) | (0 << 6) | ((21 - 17) << 2) | (0 << 0));
+#endif
+}
+
+static void lpc_init(struct device *dev)
+{
+	printk(BIOS_DEBUG, "pch: lpc_init\n");
+
+	/* Get the base address */
+
+	/* Set the value for PCI command register. */
+	pci_write_config16(dev, PCI_COMMAND,
+			   PCI_COMMAND_SPECIAL | PCI_COMMAND_MASTER |
+				   PCI_COMMAND_MEMORY | PCI_COMMAND_IO);
+
+	/* Serial IRQ initialization. */
+	pch_enable_serial_irqs(dev);
+
+	/* IO APIC initialization. */
+	pch_enable_ioapic(dev);
+
+	/* Setup the PIRQ. */
+	pch_pirq_init(dev);
+}
+
+static void pch_lpc_add_mmio_resources(device_t dev) { /* TODO */ }
+
+static void pch_lpc_add_io_resources(device_t dev)
+{
+	struct resource *res;
+	u8 io_index = 0;
+
+	/* Add an extra subtractive resource for both memory and I/O. */
+	res = new_resource(dev, IOINDEX_SUBTRACTIVE(io_index++, 0));
+	res->base = 0;
+	res->size = 0x1000;
+	res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
+		     IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+
+	res = new_resource(dev, IOINDEX_SUBTRACTIVE(io_index++, 0));
+	res->base = 0xff000000;
+	res->size = 0x01000000; /* 16 MB for flash */
+	res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE |
+		     IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+}
+
+static void lpc_read_resources(device_t dev)
+{
+	/* 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);
+
+	/* Add MMIO resource for IOAPIC. */
+	pci_p2sb_read_resources(dev);
+}
+
+static void pch_decode_init(struct device *dev) { /* TODO */ }
+
+static void lpc_enable_resources(device_t dev)
+{
+	pch_decode_init(dev);
+	pci_dev_enable_resources(dev);
+}
+
+/* Set bit in Function Disable register to hide this device */
+static void pch_hide_devfn(uint32_t devfn) { /* TODO */ }
+
+void southcluster_enable_dev(device_t dev)
+{
+	u32 reg32;
+
+	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);
+
+		/* Hide this device if possible */
+		pch_hide_devfn(dev->path.pci.devfn);
+	} else {
+		/* Enable SERR */
+		reg32 = pci_read_config32(dev, PCI_COMMAND);
+		reg32 |= PCI_COMMAND_SERR;
+		pci_write_config32(dev, PCI_COMMAND, reg32);
+	}
+}
+
+static struct device_operations device_ops = {
+	.read_resources = lpc_read_resources,
+	.set_resources = pci_dev_set_resources,
+#if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES)
+	.acpi_inject_dsdt_generator = southcluster_inject_dsdt,
+	.write_acpi_tables = southcluster_write_acpi_tables,
+#endif
+	.enable_resources = lpc_enable_resources,
+	.init = lpc_init,
+	.enable = southcluster_enable_dev,
+	.scan_bus = scan_lpc_bus,
+	.ops_pci = &soc_pci_ops,
+};
+
+static const struct pci_driver lpc_driver __pci_driver = {
+	.ops = &device_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = LPC_DEVID,
+};
+
+static void finalize_chipset(void *unused)
+{
+	printk(BIOS_DEBUG, "Finalizing SMM.\n");
+	outb(APM_CNT_FINALIZE, APM_CNT);
+}
+
+BOOT_STATE_INIT_ENTRY(BS_OS_RESUME, BS_ON_ENTRY, finalize_chipset, NULL);
+BOOT_STATE_INIT_ENTRY(BS_PAYLOAD_LOAD, BS_ON_EXIT, finalize_chipset, NULL);
diff --git a/src/soc/intel/denverton_ns/memmap.c b/src/soc/intel/denverton_ns/memmap.c
new file mode 100644
index 0000000..3fe41d2
--- /dev/null
+++ b/src/soc/intel/denverton_ns/memmap.c
@@ -0,0 +1,108 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 - 2017 Intel Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <arch/io.h>
+#include <cbfs.h>
+#include <cbmem.h>
+#include <assert.h>
+#include <device/device.h>
+#include <device/pci_def.h>
+#include <device/pci_ops.h>
+#include <console/console.h>
+#include <soc/pci_devs.h>
+#include <soc/systemagent.h>
+#include <soc/smm.h>
+#include <lib.h>
+
+/* Returns base of requested region encoded in the system agent. */
+static inline uintptr_t system_agent_region_base(size_t reg)
+{
+	device_t dev = SA_DEV_ROOT;
+
+	/* All regions concerned for have 1 MiB alignment. */
+	return ALIGN_DOWN(pci_read_config32(dev, reg), 1 * MiB);
+}
+
+/* Returns min power of 2 >= size */
+static inline u32 power_of_2(u32 size)
+{
+	return size ? 1 << (1 + log2(size - 1)) : 0;
+}
+
+u32 top_of_32bit_ram(void)
+{
+	u32 iqat_region_size = 0;
+	u32 tseg_region_size = system_agent_region_base(TOLUD) -
+			       system_agent_region_base(TSEGMB);
+
+/*
+ * Add IQAT region size if enabled.
+ */
+#if IS_ENABLED(CONFIG_IQAT_ENABLE)
+	iqat_region_size = CONFIG_IQAT_MEMORY_REGION_SIZE;
+#endif
+	return system_agent_region_base(TOLUD) -
+	       power_of_2(iqat_region_size + tseg_region_size);
+}
+
+void *cbmem_top(void) { return (void *)top_of_32bit_ram(); }
+
+static inline uintptr_t smm_region_start(void)
+{
+	return system_agent_region_base(TSEGMB);
+}
+
+static inline size_t smm_region_size(void)
+{
+	return system_agent_region_base(TOLUD) - smm_region_start();
+}
+
+void smm_region(void **start, size_t *size)
+{
+	*start = (void *)smm_region_start();
+	*size = smm_region_size();
+}
+
+int smm_subregion(int sub, void **start, size_t *size)
+{
+	uintptr_t sub_base;
+	size_t sub_size;
+	const size_t cache_size = CONFIG_SMM_RESERVED_SIZE;
+
+	sub_base = smm_region_start();
+	sub_size = smm_region_size();
+
+	assert(sub_size > CONFIG_SMM_RESERVED_SIZE);
+
+	switch (sub) {
+	case SMM_SUBREGION_HANDLER:
+		/* Handler starts at the base of TSEG. */
+		sub_size -= cache_size;
+		break;
+	case SMM_SUBREGION_CACHE:
+		/* External cache is in the middle of TSEG. */
+		sub_base += sub_size - cache_size;
+		sub_size = cache_size;
+		break;
+	default:
+		return -1;
+	}
+
+	*start = (void *)sub_base;
+	*size = sub_size;
+
+	return 0;
+}
diff --git a/src/soc/intel/denverton_ns/npk.c b/src/soc/intel/denverton_ns/npk.c
new file mode 100644
index 0000000..46e5c7e
--- /dev/null
+++ b/src/soc/intel/denverton_ns/npk.c
@@ -0,0 +1,51 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 - 2017 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/pci.h>
+#include <device/pci_ids.h>
+
+#include <soc/pci_devs.h>
+#include <soc/ramstage.h>
+
+static void npk_init(device_t dev)
+{
+	printk(BIOS_DEBUG, "pch: npk_init\n");
+
+	/* TODO */
+}
+
+static void pci_npk_read_resources(device_t dev)
+{
+	/* Skip NorthPeak enumeration. */
+}
+
+static struct device_operations pmc_ops = {
+	.read_resources = pci_npk_read_resources,
+	.set_resources = pci_dev_set_resources,
+	.enable_resources = pci_dev_enable_resources,
+	.scan_bus = 0,
+	.init = npk_init,
+	.ops_pci = &soc_pci_ops,
+};
+
+static const struct pci_driver pch_pmc __pci_driver = {
+	.ops = &pmc_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = NPK_DEVID,
+};
diff --git a/src/soc/intel/denverton_ns/pmc.c b/src/soc/intel/denverton_ns/pmc.c
new file mode 100644
index 0000000..90237a0
--- /dev/null
+++ b/src/soc/intel/denverton_ns/pmc.c
@@ -0,0 +1,116 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 - 2017 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 <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+
+#include <soc/iomap.h>
+#include <soc/pmc.h>
+#include <soc/pci_devs.h>
+#include <soc/ramstage.h>
+#include <cpu/x86/smm.h>
+
+/* While we read BAR dynamically in case it changed, let's
+ * initialize it with a same value
+ */
+static u16 acpi_base = DEFAULT_ACPI_BASE;
+static u32 pwrm_base = DEFAULT_PWRM_BASE;
+
+static void pch_power_options(device_t dev) { /* TODO */ }
+
+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");
+	}
+}
+
+static void pmc_init(device_t dev)
+{
+	printk(BIOS_DEBUG, "pch: pmc_init\n");
+
+	/* Get the base address */
+	acpi_base = pci_read_config16(dev, PMC_ACPI_BASE) & MASK_PMC_ACPI_BASE;
+	pwrm_base = pci_read_config32(dev, PMC_PWRM_BASE) & MASK_PMC_PWRM_BASE;
+
+	/* Set the value for PCI command register. */
+	pci_write_config16(dev, PCI_COMMAND, PCI_COMMAND_MASTER |
+						     PCI_COMMAND_MEMORY |
+						     PCI_COMMAND_IO);
+
+	/* Setup power options. */
+	pch_power_options(dev);
+
+	/* Configure ACPI mode. */
+	pch_set_acpi_mode();
+}
+
+static void pci_pmc_read_resources(device_t dev)
+{
+	struct resource *res;
+
+	/* Get the normal PCI resources of this device. */
+	pci_dev_read_resources(dev);
+
+	/* Add MMIO resource
+	 * Use 0xaa as an unused index for PWRM BAR.
+	 */
+	u32 reg32 = pci_read_config32(dev, PMC_PWRM_BASE) & MASK_PMC_PWRM_BASE;
+	if ((reg32 != 0x0) && (reg32 != 0xffffffff)) {
+		res = new_resource(dev, 0xaa);
+		res->base = reg32;
+		res->size = 64 * 1024; /* 64K bytes memory config space */
+		res->flags =
+			IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+		printk(BIOS_DEBUG,
+		       "Adding PMC PWRM config space BAR 0x%08lx-0x%08lx.\n",
+		       (unsigned long)(res->base),
+		       (unsigned long)(res->base + res->size));
+	}
+
+	/* Add MMIO resource
+	 * Use 0xab as an unused index for ACPI BAR.
+	 */
+	u16 reg16 = pci_read_config16(dev, PMC_ACPI_BASE) & MASK_PMC_ACPI_BASE;
+	if ((reg16 != 0x0) && (reg16 != 0xffff)) {
+		res = new_resource(dev, 0xab);
+		res->base = reg16;
+		res->size = 0x100; /* 256 bytes I/O config space */
+		res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
+			     IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+	}
+}
+
+static struct device_operations pmc_ops = {
+	.read_resources = pci_pmc_read_resources,
+	.set_resources = pci_dev_set_resources,
+	.enable_resources = pci_dev_enable_resources,
+	.scan_bus = 0,
+	.init = pmc_init,
+	.ops_pci = &soc_pci_ops,
+};
+
+static const struct pci_driver pch_pmc __pci_driver = {
+	.ops = &pmc_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = PMC_DEVID,
+};
diff --git a/src/soc/intel/denverton_ns/pmutil.c b/src/soc/intel/denverton_ns/pmutil.c
new file mode 100644
index 0000000..542997c
--- /dev/null
+++ b/src/soc/intel/denverton_ns/pmutil.c
@@ -0,0 +1,248 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google Inc.
+ * Copyright (C) 2014 - 2017 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/io.h>
+#include <console/console.h>
+
+#include <soc/iomap.h>
+#include <soc/soc_util.h>
+#include <soc/pm.h>
+
+static void print_num_status_bits(int num_bits, uint32_t status,
+				  const char * const bit_names[])
+{
+	int i;
+
+	if (!status)
+		return;
+
+	for (i = num_bits - 1; 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);
+		}
+	}
+}
+
+static uint32_t print_smi_status(uint32_t smi_sts)
+{
+	static const char * const smi_sts_bits[] = {
+		[2] = "BIOS",
+		[4] = "SLP_SMI",
+		[5] = "APM",
+		[6] = "SWSMI_TMR",
+		[8] = "PM1",
+		[9] = "GPE0",
+		[10] = "GPE1",
+		[11] = "MC_SMI",
+		[12] = "DEVMON",
+		[13] = "TCO",
+		[14] = "PERIODIC",
+		[15] = "SERIRQ",
+		[16] = "SMBUS_SMI",
+		[17] = "LEGACY_USB2",
+		[18] = "INTEL_USB2",
+		[19] = "PATCH",
+		[20] = "PCI_EXP_SMI",
+		[21] = "MONITOR",
+		[26] = "SPI",
+		[27] = "GPIO_UNLOCK",
+		[31] = "LEGACY_USB3",
+	};
+
+	if (!smi_sts)
+		return 0;
+
+	printk(BIOS_DEBUG, "SMI_STS: ");
+	print_num_status_bits(ARRAY_SIZE(smi_sts_bits), smi_sts, smi_sts_bits);
+	printk(BIOS_DEBUG, "\n");
+
+	return smi_sts;
+}
+
+static uint32_t reset_smi_status(void)
+{
+	uint16_t pmbase = get_pmbase();
+	uint32_t smi_sts = inl((uint16_t)(pmbase + SMI_STS));
+	outl(smi_sts, (uint16_t)(pmbase + SMI_STS));
+	return smi_sts;
+}
+
+uint32_t clear_smi_status(void) { return print_smi_status(reset_smi_status()); }
+
+void enable_smi(uint32_t mask)
+{
+	uint16_t pmbase = get_pmbase();
+	uint32_t smi_en = inl((uint16_t)(pmbase + SMI_EN));
+	smi_en |= mask;
+	outl(smi_en, (uint16_t)(pmbase + SMI_EN));
+}
+
+void disable_smi(uint32_t mask)
+{
+	uint16_t pmbase = get_pmbase();
+	uint32_t smi_en = inl((uint16_t)(pmbase + SMI_EN));
+	smi_en &= ~mask;
+	outl(smi_en, (uint16_t)(pmbase + SMI_EN));
+}
+
+void enable_pm1_control(uint32_t mask)
+{
+	uint16_t pmbase = get_pmbase();
+	uint32_t pm1_cnt = inl((uint16_t)(pmbase + PM1_CNT));
+	pm1_cnt |= mask;
+	outl(pm1_cnt, (uint16_t)(pmbase + PM1_CNT));
+}
+
+void disable_pm1_control(uint32_t mask)
+{
+	uint16_t pmbase = get_pmbase();
+	uint32_t pm1_cnt = inl((uint16_t)(pmbase + PM1_CNT));
+	pm1_cnt &= ~mask;
+	outl(pm1_cnt, (uint16_t)(pmbase + PM1_CNT));
+}
+
+static uint16_t reset_pm1_status(void)
+{
+	uint16_t pmbase = get_pmbase();
+	uint16_t pm1_sts = inw((uint16_t)(pmbase + PM1_STS));
+	outw(pm1_sts, (uint16_t)(pmbase + PM1_STS));
+	return pm1_sts;
+}
+
+static uint16_t print_pm1_status(uint16_t pm1_sts)
+{
+	static const char * const pm1_sts_bits[] = {
+		[0] = "TMROF",  [4] = "BM",   [5] = "GBL",
+		[8] = "PWRBTN", [10] = "RTC", [11] = "PRBTNOR",
+		[15] = "WAK",
+	};
+
+	if (!pm1_sts)
+		return 0;
+
+	printk(BIOS_SPEW, "PM1_STS: ");
+	print_num_status_bits(ARRAY_SIZE(pm1_sts_bits), pm1_sts, pm1_sts_bits);
+	printk(BIOS_SPEW, "\n");
+
+	return pm1_sts;
+}
+
+uint16_t clear_pm1_status(void) { return print_pm1_status(reset_pm1_status()); }
+
+void enable_pm1(uint16_t events)
+{
+	uint16_t pmbase = get_pmbase();
+	outw(events, (uint16_t)(pmbase + PM1_EN));
+}
+
+static uint32_t print_tco_status(uint32_t tco_sts)
+{
+	static const char * const tco_sts_bits[] = {
+		[0] = "NMI2SMI",     [1] = "OS_TCO_SMI",
+		[2] = "TCO_INIT",    [3] = "TIMEOUT",
+		[7] = "NEWCENTURY ", [8] = "BIOSWR ",
+		[9] = "CPUSCI ",     [10] = "CPUSMI ",
+		[12] = "CPUSERR ",   [16] = "INTRD_DET ",
+		[17] = "SECOND_TO",  [20] = "SMLINK_SLV_SMI",
+	};
+
+	if (!tco_sts)
+		return 0;
+
+	printk(BIOS_DEBUG, "TCO_STS: ");
+	print_num_status_bits(ARRAY_SIZE(tco_sts_bits), tco_sts, tco_sts_bits);
+	printk(BIOS_DEBUG, "\n");
+
+	return tco_sts;
+}
+
+static uint32_t reset_tco_status(void)
+{
+	uint16_t tcobase = get_tcobase();
+	uint32_t tco_sts = inl((uint16_t)(tcobase + TCO1_STS));
+	uint32_t tco_en = inl((uint16_t)(tcobase + TCO1_CNT));
+
+	outl(tco_sts, (uint16_t)(tcobase + TCO1_STS));
+	return tco_sts & tco_en;
+}
+
+uint32_t clear_tco_status(void) { return print_tco_status(reset_tco_status()); }
+
+void enable_gpe(uint32_t mask)
+{
+	uint16_t pmbase = get_pmbase();
+	uint32_t gpe0_en = inl((uint16_t)(pmbase + GPE0_EN));
+	gpe0_en |= mask;
+	outl(gpe0_en, (uint16_t)(pmbase + GPE0_EN));
+}
+
+void disable_gpe(uint32_t mask)
+{
+	uint16_t pmbase = get_pmbase();
+	uint32_t gpe0_en = inl((uint16_t)(pmbase + GPE0_EN));
+	gpe0_en &= ~mask;
+	outl(gpe0_en, (uint16_t)(pmbase + GPE0_EN));
+}
+
+void disable_all_gpe(void) { disable_gpe(~0); }
+
+static uint32_t reset_gpe_status(void)
+{
+	uint16_t pmbase = get_pmbase();
+	uint32_t gpe_sts = inl((uint16_t)(pmbase + GPE0_STS));
+	outl(gpe_sts, (uint16_t)(pmbase + GPE0_STS));
+	return gpe_sts;
+}
+
+static uint32_t print_gpe_sts(uint32_t gpe_sts)
+{
+	static const char * const gpe_sts_bits[] = {
+		[0] = "GPIO_0", [1] = "GPIO_1",
+		[2] = "GPIO_2", [3] = "GPIO_3",
+		[4] = "GPIO_4", [5] = "GPIO_5",
+		[6] = "GPIO_6", [7] = "GPIO_7",
+		[8] = "GPIO_8", [9] = "GPIO_9",
+		[10] = "GPIO_10", [11] = "GPIO_11",
+		[12] = "GPIO_12", [13] = "GPIO_13",
+		[14] = "GPIO_14", [15] = "GPIO_15",
+		[16] = "GPIO_16", [17] = "GPIO_17",
+		[18] = "GPIO_18", [19] = "GPIO_19",
+		[20] = "GPIO_20", [21] = "GPIO_21",
+		[22] = "GPIO_22", [23] = "GPIO_23",
+		[24] = "GPIO_24", [25] = "GPIO_25",
+		[26] = "GPIO_26", [27] = "GPIO_27",
+		[28] = "GPIO_28", [29] = "GPIO_29",
+		[30] = "GPIO_30", [31] = "GPIO_31",
+	};
+
+	if (!gpe_sts)
+		return gpe_sts;
+
+	printk(BIOS_DEBUG, "GPE0a_STS: ");
+	print_num_status_bits(ARRAY_SIZE(gpe_sts_bits), gpe_sts, gpe_sts_bits);
+	printk(BIOS_DEBUG, "\n");
+
+	return gpe_sts;
+}
+
+uint32_t clear_gpe_status(void) { return print_gpe_sts(reset_gpe_status()); }
+
+void clear_pmc_status(void) { /* TODO */ }
diff --git a/src/soc/intel/denverton_ns/reset.c b/src/soc/intel/denverton_ns/reset.c
new file mode 100644
index 0000000..97955a5
--- /dev/null
+++ b/src/soc/intel/denverton_ns/reset.c
@@ -0,0 +1,31 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * 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 <console/console.h>
+#include <fsp/util.h>
+#include <reset.h>
+
+void chipset_handle_reset(uint32_t status)
+{
+	switch (status) {
+	case FSP_STATUS_RESET_REQUIRED_5: /* Global Reset */
+		global_reset();
+		break;
+	default:
+		printk(BIOS_ERR, "unhandled reset type %x\n", status);
+		die("unknown reset type");
+		break;
+	}
+}
diff --git a/src/soc/intel/denverton_ns/romstage.c b/src/soc/intel/denverton_ns/romstage.c
new file mode 100644
index 0000000..512d8ccb
--- /dev/null
+++ b/src/soc/intel/denverton_ns/romstage.c
@@ -0,0 +1,295 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2016 - 2017 Intel Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <cbmem.h>
+#include <console/console.h>
+#include <cpu/x86/mtrr.h>
+#include <harcuvar_boardid.h>
+#include <hsio.h>
+#include <reset.h>
+#include <soc/fiamux.h>
+#include <soc/iomap.h>
+#include <soc/pci_devs.h>
+#include <soc/pcr.h>
+#include <soc/pmc.h>
+#include <soc/romstage.h>
+#include <soc/smbus.h>
+#include <soc/smm.h>
+#include <soc/soc_util.h>
+
+void __attribute__((weak)) mainboard_config_gpios(void) {}
+
+#if IS_ENABLED(CONFIG_DISPLAY_HOBS)
+static void display_fsp_smbios_memory_info_hob(void)
+{
+	int channel, dimm;
+	size_t hob_size;
+	const DIMM_INFO *dimm_info;
+	const CHANNEL_INFO *channel_info;
+	const FSP_SMBIOS_MEMORY_INFO *memory_info_hob;
+
+	/* Locate the memory info HOB */
+	memory_info_hob = fsp_find_smbios_memory_info(&hob_size);
+
+	/* Display the data in the FSP_SMBIOS_MEMORY_INFO HOB */
+	if (memory_info_hob) {
+		printk(BIOS_DEBUG, "FSP_SMBIOS_MEMORY_INFO HOB\n");
+		printk(BIOS_DEBUG, "    0x%02x: Revision\n",
+			memory_info_hob->Revision);
+		printk(BIOS_DEBUG, "    0x%02x: MemoryType\n",
+			memory_info_hob->MemoryType);
+		printk(BIOS_DEBUG, "    %d: MemoryFrequencyInMHz\n",
+			memory_info_hob->MemoryFrequencyInMHz);
+		printk(BIOS_DEBUG, "    %d: DataWidth in bits\n",
+			memory_info_hob->DataWidth);
+		printk(BIOS_DEBUG, "    0x%02x: ErrorCorrectionType\n",
+			memory_info_hob->ErrorCorrectionType);
+		printk(BIOS_DEBUG, "    0x%02x: ChannelCount\n",
+			memory_info_hob->ChannelCount);
+		for (channel = 0; channel < memory_info_hob->ChannelCount;
+			channel++) {
+			channel_info = &memory_info_hob->ChannelInfo[channel];
+			printk(BIOS_DEBUG, "  Channel %d\n", channel);
+			printk(BIOS_DEBUG, "      0x%02x: ChannelId\n",
+				channel_info->ChannelId);
+			printk(BIOS_DEBUG, "      0x%02x: DimmCount\n",
+				channel_info->DimmCount);
+			for (dimm = 0; dimm < channel_info->DimmCount;
+				dimm++) {
+				dimm_info = &channel_info->DimmInfo[dimm];
+				printk(BIOS_DEBUG, "   DIMM %d\n", dimm);
+				printk(BIOS_DEBUG, "      0x%02x: DimmId\n",
+					dimm_info->DimmId);
+				printk(BIOS_DEBUG, "      %d: SizeInMb\n",
+					dimm_info->SizeInMb);
+				printk(BIOS_DEBUG, "    0x%04x: MfgId\n",
+					dimm_info->MfgId);
+				printk(BIOS_DEBUG, "%*.*s: ModulePartNum\n",
+					(int)sizeof(dimm_info->ModulePartNum),
+					(int)sizeof(dimm_info->ModulePartNum),
+					dimm_info->ModulePartNum);
+			}
+		}
+	} else {
+		printk(BIOS_DEBUG, "FSP_SMBIOS_MEMORY_INFO HOB not found!!!\n");
+	}
+}
+#endif
+
+static void early_pmc_init(void)
+{
+	/* PMC (B0:D31:F2). */
+	device_t dev = PCH_PMC_DEV;
+
+	/* Is PMC present */
+	if (pci_read_config16(dev, 0) == 0xffff) {
+		printk(BIOS_ERR, "PMC controller (B0:D31:F2) does not present!\n");
+		return;
+	}
+
+	uint32_t pwrm_base =
+		pci_read_config32(dev, PMC_PWRM_BASE) & MASK_PMC_PWRM_BASE;
+	if (!pwrm_base) {
+		printk(BIOS_ERR, "PWRM base address is not configured!\n");
+		return;
+	}
+
+	/* Workaround for sighting report (doc#: 560805) v1.86.
+	   42. System Might Hang In AC Power Loss
+	   Problem :
+	       When removing and reapplying AC power to the board,
+	       the system might hang at serial output
+	       'RESET required : change of frequency'
+	       due to PMC ROM change on B0.
+	   Implication :
+	       1. This issue is only shown in B0 stepping.
+	       2. This issue does not impact a system without an RTC battery.
+	   Alternative workaround :
+	       Remove RTC battery on the board if possible.
+	   Status : Plan Fix.
+	*/
+	if (silicon_stepping() == SILICON_REV_DENVERTON_B0) {
+		if (!(pci_read_config32(dev, PMC_GEN_PMCON_B)
+					& PMC_GEN_PMCON_B_RTC_PWR_STS)) {
+			if (read32((void *)(pwrm_base + 0x124))
+				   & ((1 << 11) | (1 << 12))) {
+				/* Performs a global reset */
+				printk(BIOS_DEBUG,
+					"Requesting Global Reset...\n");
+				pci_write_config32(dev, PMC_ETR3,
+					pci_read_config32(dev, PMC_ETR3)
+					| PMC_ETR3_CF9GR);
+				hard_reset();
+			}
+		}
+	}
+}
+
+static void early_tco_init(void)
+{
+	/* SMBUS (B0:D31:F4). */
+	device_t dev = PCI_DEV(0, SMBUS_DEV, SMBUS_FUNC);
+
+	/* Configure TCO base address */
+	if (pci_read_config16(dev, TCOBASE) == 0xffff) {
+		printk(BIOS_ERR, "SMBus controller (B0:D31:F4) does not present!\n");
+		return;
+	}
+	uint16_t tco_ctl = pci_read_config16(dev, TCOCTL);
+	if (tco_ctl & TCOBASE_LOCK) {
+		printk(BIOS_ERR, "TCO base register already has been locked!\n");
+	} else {
+		pci_write_config16(dev, TCOCTL, tco_ctl & (~TCOBASE_EN));
+		pci_write_config16(dev, TCOBASE, DEFAULT_TCO_BASE | 0x1);
+		pci_write_config16(dev, TCOCTL, tco_ctl | TCOBASE_EN);
+	}
+
+	uint16_t tco_base = pci_read_config16(dev, TCOBASE) & MASK_TCOBASE;
+	printk(BIOS_DEBUG, "TCO base address set to 0x%x!\n", tco_base);
+
+	/* Disable the TCO timer expiration from causing a system reset */
+	MMIO32_OR(PCH_PCR_ADDRESS(PID_SMB, PCR_SMBUS_GC),
+		(uint32_t)PCR_SMBUS_GC_NR);
+
+	/*  Halt the TCO timer */
+	uint16_t reg16 = inw(tco_base + TCO1_CNT);
+	reg16 |= TCO_TMR_HLT;
+	outw(reg16, tco_base + TCO1_CNT);
+
+	/* Clear the Second TCO status bit */
+	reg16 = inw(tco_base + TCO2_STS);
+	reg16 |= TCO2_STS_SECOND_TO;
+	outw(reg16, tco_base + TCO2_STS);
+}
+
+asmlinkage void car_stage_entry(void)
+{
+
+	struct postcar_frame pcf;
+	uintptr_t top_of_ram;
+
+#if IS_ENABLED(CONFIG_HAVE_SMI_HANDLER)
+	void *smm_base;
+	size_t smm_size;
+	uintptr_t tseg_base;
+#endif
+
+	console_init();
+
+	printk(BIOS_DEBUG, "FSP TempRamInit was successful...\n");
+
+	mainboard_config_gpios();
+	early_tco_init();
+	early_pmc_init();
+
+	fsp_memory_init(false);
+
+#if IS_ENABLED(CONFIG_DISPLAY_HOBS)
+	display_fsp_smbios_memory_info_hob();
+#endif
+
+	if (postcar_frame_init(&pcf, 1 * KiB))
+		die("Unable to initialize postcar frame.\n");
+
+	/*
+	 * We need to make sure ramstage will be run cached. At this point exact
+	 * location of ramstage in cbmem is not known. Instruct postcar to cache
+	 * 16 megs under cbmem top which is a safe bet to cover ramstage.
+	 */
+	top_of_ram = (uintptr_t)cbmem_top();
+	postcar_frame_add_mtrr(&pcf, top_of_ram - 16 * MiB, 16 * MiB,
+			       MTRR_TYPE_WRBACK);
+
+	/* Cache the memory-mapped boot media. */
+	if (IS_ENABLED(CONFIG_BOOT_DEVICE_MEMORY_MAPPED))
+		postcar_frame_add_mtrr(&pcf, -CONFIG_ROM_SIZE, CONFIG_ROM_SIZE,
+				       MTRR_TYPE_WRPROT);
+#if IS_ENABLED(CONFIG_HAVE_SMI_HANDLER)
+	/*
+	 * Cache the TSEG region at the top of ram. This region is
+	 * not restricted to SMM mode until SMM has been relocated.
+	 * By setting the region to cacheable it provides faster access
+	 * when relocating the SMM handler as well as using the TSEG
+	 * region for other purposes.
+	 */
+	smm_region(&smm_base, &smm_size);
+	tseg_base = (uintptr_t)smm_base;
+	postcar_frame_add_mtrr(&pcf, tseg_base, smm_size, MTRR_TYPE_WRBACK);
+#endif
+
+	run_postcar_phase(&pcf);
+}
+
+static void soc_memory_init_params(FSP_M_CONFIG *m_cfg)
+{
+	FSPM_UPD *mupd = container_of(m_cfg, FSPM_UPD, FspmConfig);
+	size_t num;
+	uint16_t supported_hsio_lanes;
+	uint8_t boardid = board_id();
+	BL_HSIO_INFORMATION *hsio_config;
+
+	/* Set the parameters for MemoryInit */
+	m_cfg->PcdEnableIQAT = IS_ENABLED(CONFIG_IQAT_ENABLE);
+
+	/* if ME HECI communication is disabled, apply default one*/
+	if (mupd->FspmConfig.PcdMeHeciCommunication == 0) {
+
+		/* Configure FIA MUX PCD */
+		/* Assume the validating silicon has max lanes. */
+		supported_hsio_lanes = BL_ME_FIA_MUX_LANE_NUM_MAX;
+
+		switch (boardid) {
+		case BoardIdHarcuvar:
+			num = ARRAY_SIZE(harcuvar_hsio_config);
+			hsio_config =
+			    (BL_HSIO_INFORMATION *)harcuvar_hsio_config;
+			break;
+		default:
+			num = 0;
+			hsio_config = NULL;
+			break;
+		}
+
+		if (get_fiamux_hsio_info(supported_hsio_lanes, num,
+					 &hsio_config))
+			die("HSIO Configuration is invalid, please correct "
+			    "it!");
+
+		/* Check the requested FIA MUX Configuration */
+		if (!(&hsio_config->FiaConfig)) {
+			die("Requested FIA MUX Configuration is invalid,"
+			    " please correct it!");
+		}
+
+		mupd->FspmConfig.PcdHsioLanesNumber =
+		    (uint32_t)hsio_config->NumLanesSupported;
+		mupd->FspmConfig.PcdFiaMuxConfigPtr =
+		    (uint32_t)&hsio_config->FiaConfig;
+	}
+}
+
+__attribute__((weak)) void mainboard_memory_init_params(FSPM_UPD *mupd)
+{
+	/* Do nothing */
+}
+
+void platform_fsp_memory_init_params_cb(FSPM_UPD *mupd, uint32_t version)
+{
+	FSP_M_CONFIG *m_cfg = &mupd->FspmConfig;
+
+	soc_memory_init_params(m_cfg);
+
+	mainboard_memory_init_params(mupd);
+}
diff --git a/src/soc/intel/denverton_ns/sata.c b/src/soc/intel/denverton_ns/sata.c
new file mode 100644
index 0000000..421b6e3
--- /dev/null
+++ b/src/soc/intel/denverton_ns/sata.c
@@ -0,0 +1,93 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008 - 2009 coresystems GmbH
+ * Copyright (C) 2014 - 2017 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/pci.h>
+#include <device/pci_ids.h>
+
+#include <soc/pci_devs.h>
+#include <soc/ramstage.h>
+#include <soc/sata.h>
+
+#include "chip.h"
+
+static void sata_init(struct device *dev)
+{
+	u32 reg32;
+	u16 reg16;
+	u32 abar;
+
+	/* Get the chip configuration */
+	config_t *config = dev->chip_info;
+
+	printk(BIOS_DEBUG, "SATA: Initializing...\n");
+
+	if (config == NULL) {
+		printk(BIOS_ERR, "SATA: ERROR: Device not in devicetree.cb!\n");
+		return;
+	}
+
+	/* SATA configuration is handled by the FSP */
+
+	/* Enable BARs */
+	pci_write_config16(dev, PCI_COMMAND, PCI_COMMAND_MASTER |
+						     PCI_COMMAND_MEMORY |
+						     PCI_COMMAND_IO);
+
+	printk(BIOS_DEBUG, "SATA: Controller in AHCI mode.\n");
+
+	/* Set the controller mode */
+	reg16 = pci_read_config16(dev, SATA_MAP);
+	reg16 &= ~(3 << 6);
+	reg16 |= SATA_MAP_AHCI;
+	pci_write_config16(dev, SATA_MAP, reg16);
+
+	/* Initialize AHCI memory-mapped space */
+	abar = pci_read_config32(dev, PCI_BASE_ADDRESS_5);
+	printk(BIOS_DEBUG, "ABAR: %08X\n", abar);
+
+	/* Enable AHCI Mode */
+	reg32 = read32((void *)(abar + 0x04));
+	reg32 |= (1 << 31);
+	write32((void *)(abar + 0x04), reg32);
+}
+
+static void sata_enable(device_t dev) { /* TODO */ }
+
+static struct device_operations sata_ops = {
+	.read_resources = pci_dev_read_resources,
+	.set_resources = pci_dev_set_resources,
+	.enable_resources = pci_dev_enable_resources,
+	.init = sata_init,
+	.enable = sata_enable,
+	.scan_bus = 0,
+	.ops_pci = &soc_pci_ops,
+};
+
+static const unsigned short pci_device_ids[] = {
+	AHCI_DEVID,  /* DVN SATA AHCI */
+	AHCI2_DEVID, /* DVN SATA2 AHCI */
+	0
+};
+
+static const struct pci_driver soc_sata __pci_driver = {
+	.ops = &sata_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.devices = pci_device_ids,
+};
diff --git a/src/soc/intel/denverton_ns/smihandler.c b/src/soc/intel/denverton_ns/smihandler.c
new file mode 100644
index 0000000..e434c1c
--- /dev/null
+++ b/src/soc/intel/denverton_ns/smihandler.c
@@ -0,0 +1,372 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google Inc.
+ * Copyright (C) 2014 - 2017 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 <stdlib.h>
+#include <arch/hlt.h>
+#include <arch/io.h>
+#include <console/console.h>
+#include <cpu/x86/cache.h>
+#include <cpu/x86/smm.h>
+#include <device/pci_def.h>
+#include <elog.h>
+#include <intelblocks/fast_spi.h>
+#include <spi-generic.h>
+#include <soc/iomap.h>
+#include <soc/soc_util.h>
+#include <soc/pm.h>
+#include <soc/nvs.h>
+
+/* GNVS needs to be set by coreboot initiating a software SMI. */
+static global_nvs_t *gnvs;
+static int smm_initialized;
+
+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;
+}
+
+void southbridge_smi_set_eos(void) { enable_smi(EOS); }
+
+global_nvs_t *smm_get_gnvs(void) { return gnvs; }
+
+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)
+{
+	uint32_t reg32;
+	uint8_t slp_typ;
+	uint16_t pmbase = get_pmbase();
+
+	/* First, disable further SMIs */
+	disable_smi(SLP_SMI_EN);
+
+	/* Figure out SLP_TYP */
+	reg32 = inl((uint16_t)(pmbase + PM1_CNT));
+	printk(BIOS_SPEW, "SMI#: SLP = 0x%08x\n", reg32);
+	slp_typ = (reg32 >> 10) & 7;
+
+	/* Do any mainboard sleep handling */
+	mainboard_smi_sleep((uint8_t)(slp_typ - 2));
+
+	/* Next, do the deed.
+	 */
+
+	switch (slp_typ) {
+	case SLP_TYP_S0:
+		printk(BIOS_DEBUG, "SMI#: Entering S0 (On)\n");
+		break;
+	case SLP_TYP_S1:
+		printk(BIOS_DEBUG, "SMI#: Entering S1 (Assert STPCLK#)\n");
+		break;
+	case SLP_TYP_S3:
+		printk(BIOS_DEBUG, "SMI#: Entering S3 (Suspend-To-RAM)\n");
+
+		/* Invalidate the cache before going to S3 */
+		wbinvd();
+		break;
+	case SLP_TYP_S4:
+		printk(BIOS_DEBUG, "SMI#: Entering S4 (Suspend-To-Disk)\n");
+		break;
+	case SLP_TYP_S5:
+		printk(BIOS_DEBUG, "SMI#: Entering S5 (Soft Power off)\n");
+
+		/* Disable all GPE */
+		disable_all_gpe();
+
+		/* 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 > 1)
+		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((uint16_t)(pmbase + 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 em64t100_smm_state_save_area_t *smi_apmc_find_state_save(uint8_t cmd)
+{
+	em64t100_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 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 */
+		fast_spi_init();
+}
+
+static void southbridge_smi_apmc(void)
+{
+	uint8_t reg8;
+	em64t100_smm_state_save_area_t *state;
+
+	/* Emulate B2 register as the FADT / Linux expects it */
+
+	reg8 = inb(APM_CNT);
+	switch (reg8) {
+	case APM_CNT_CST_CONTROL:
+		/* Calling this function seems to cause
+		 * some kind of race condition in Linux
+		 * and causes a kernel oops
+		 */
+		printk(BIOS_DEBUG, "C-state control\n");
+		break;
+	case APM_CNT_PST_CONTROL:
+		/* Calling this function seems to cause
+		 * some kind of race condition in Linux
+		 * and causes a kernel oops
+		 */
+		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 *)((uint32_t)state->rbx);
+			smm_initialized = 1;
+			printk(BIOS_DEBUG, "SMI#: Setting GNVS to %p\n", gnvs);
+		}
+		break;
+	}
+
+	mainboard_smi_apmc(reg8);
+}
+
+static void southbridge_smi_pm1(void)
+{
+	uint16_t 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
+		disable_pm1_control(-1UL);
+		enable_pm1_control(SLP_EN | (SLP_TYP_S5 << SLP_TYP_SHIFT));
+	}
+}
+
+static void southbridge_smi_gpe0(void) { clear_gpe_status(); }
+
+static void southbridge_smi_tco(void)
+{
+	uint32_t tco_sts = clear_tco_status();
+
+	/* Any TCO event? */
+	if (!tco_sts)
+		return;
+
+	if (tco_sts & TCO1_STS_TIMEOUT) { /* TIMEOUT */
+		/* Handle TCO timeout */
+		printk(BIOS_DEBUG, "TCO Timeout.\n");
+	}
+}
+
+static void southbridge_smi_periodic(void)
+{
+	uint32_t reg32;
+
+	reg32 = inl((uint16_t)(get_pmbase() + SMI_EN));
+
+	/* Are periodic SMIs enabled? */
+	if ((reg32 & PERIODIC_EN) == 0)
+		return;
+
+	printk(BIOS_DEBUG, "Periodic SMI.\n");
+}
+
+typedef void (*smi_handler_t)(void);
+
+static const smi_handler_t southbridge_smi[32] = {
+	NULL,			  //  [0] reserved
+	NULL,			  //  [1] reserved
+	NULL,			  //  [2] BIOS_STS
+	NULL,			  //  [3] LEGACY_USB_STS
+	southbridge_smi_sleep,    //  [4] SLP_SMI_STS
+	southbridge_smi_apmc,     //  [5] APM_STS
+	NULL,			  //  [6] SWSMI_TMR_STS
+	NULL,			  //  [7] reserved
+	southbridge_smi_pm1,      //  [8] PM1_STS
+	southbridge_smi_gpe0,     //  [9] GPE0_STS
+	NULL,			  // [10] reserved
+	NULL,			  // [11] reserved
+	NULL,			  // [12] reserved
+	southbridge_smi_tco,      // [13] TCO_STS
+	southbridge_smi_periodic, // [14] PERIODIC_STS
+	NULL,			  // [15] SERIRQ_SMI_STS
+	NULL,			  // [16] SMBUS_SMI_STS
+	NULL,			  // [17] LEGACY_USB2_STS
+	NULL,			  // [18] INTEL_USB2_STS
+	NULL,			  // [19] reserved
+	NULL,			  // [20] PCI_EXP_SMI_STS
+	NULL,			  // [21] reserved
+	NULL,			  // [22] reserved
+	NULL,			  // [23] reserved
+	NULL,			  // [24] reserved
+	NULL,			  // [25] reserved
+	NULL,			  // [26] SPI_STS
+	NULL,			  // [27] reserved
+	NULL,			  // [28] PUNIT
+	NULL,			  // [29] GUNIT
+	NULL,			  // [30] reserved
+	NULL			  // [31] reserved
+};
+
+void southbridge_smi_handler(void)
+{
+	int i;
+	uint32_t 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)))
+			continue;
+
+		if (southbridge_smi[i] != NULL) {
+			southbridge_smi[i]();
+		} else {
+			printk(BIOS_DEBUG, "SMI_STS[%d] occurred, but no "
+					   "handler available.\n",
+			       i);
+		}
+	}
+}
diff --git a/src/soc/intel/denverton_ns/smm.c b/src/soc/intel/denverton_ns/smm.c
new file mode 100644
index 0000000..732aed4
--- /dev/null
+++ b/src/soc/intel/denverton_ns/smm.c
@@ -0,0 +1,92 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google Inc.
+ * Copyright (C) 2014 - 2017 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/smm.h>
+#include <string.h>
+
+#include <soc/iomap.h>
+#include <soc/soc_util.h>
+#include <soc/pm.h>
+#include <soc/smm.h>
+
+/* Save the gpio route register. The settings are committed from
+ * southcluster_smm_enable_smi(). */
+static uint32_t gpio_route;
+
+void southcluster_smm_save_gpio_route(uint32_t route) { gpio_route = route; }
+
+void southcluster_smm_clear_state(void)
+{
+	uint32_t smi_en;
+
+	printk(BIOS_DEBUG, "Initializing Southbridge SMI...");
+	printk(BIOS_SPEW, " pmbase = 0x%04x\n", get_pmbase());
+
+	smi_en = inl((uint16_t)(get_pmbase() + SMI_EN));
+	if (smi_en & APMC_EN) {
+		printk(BIOS_INFO, "SMI# handler already enabled?\n");
+		return;
+	}
+
+	/* Dump and clear status registers */
+	clear_smi_status();
+	clear_pm1_status();
+	clear_tco_status();
+	clear_gpe_status();
+	clear_pmc_status();
+}
+
+void southcluster_smm_enable_smi(void)
+{
+
+	printk(BIOS_DEBUG, "Enabling SMIs.\n");
+	/* Configure events Disable pcie wake. */
+	enable_pm1(PWRBTN_EN | GBL_EN | PCIEXPWAK_DIS);
+	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 TCO events
+	 *  - on microcontroller writes (io 0x62/0x66)
+	 */
+	enable_smi(APMC_EN | SLP_SMI_EN | GBL_SMI_EN | 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"((uint32_t)gnvs),
+		       "d"(APM_CNT));
+}
diff --git a/src/soc/intel/denverton_ns/soc_util.c b/src/soc/intel/denverton_ns/soc_util.c
new file mode 100644
index 0000000..1626927
--- /dev/null
+++ b/src/soc/intel/denverton_ns/soc_util.c
@@ -0,0 +1,254 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 - 2017 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/io.h>
+#include <device/pci.h>
+#include <device/pci_def.h>
+#include <device/device.h>
+#include <console/console.h>
+
+#include <soc/iomap.h>
+#include <soc/soc_util.h>
+#include <soc/pmc.h>
+#include <soc/smbus.h>
+#include <soc/lpc.h>
+#include <soc/pci_devs.h>
+#include <soc/systemagent.h>
+
+device_t get_hostbridge_dev(void)
+{
+#if defined(__PRE_RAM__) || defined(__SMM__)
+	return PCI_DEV(0, SA_DEV, SA_FUNC);
+#else
+	return dev_find_slot(0, PCI_DEVFN(SA_DEV, SA_FUNC));
+#endif
+}
+
+device_t get_lpc_dev(void)
+{
+#if defined(__PRE_RAM__) || defined(__SMM__)
+	return PCI_DEV(0, LPC_DEV, LPC_FUNC);
+#else
+	return dev_find_slot(0, PCI_DEVFN(LPC_DEV, LPC_FUNC));
+#endif
+}
+
+device_t get_pmc_dev(void)
+{
+#if defined(__PRE_RAM__) || defined(__SMM__)
+	return PCI_DEV(0, PMC_DEV, PMC_FUNC);
+#else
+	return dev_find_slot(0, PCI_DEVFN(PMC_DEV, PMC_FUNC));
+#endif
+}
+
+device_t get_smbus_dev(void)
+{
+#if defined(__PRE_RAM__) || defined(__SMM__)
+	return PCI_DEV(0, SMBUS_DEV, SMBUS_FUNC);
+#else
+	return dev_find_slot(0, PCI_DEVFN(SMBUS_DEV, SMBUS_FUNC));
+#endif
+}
+
+uint32_t get_pciebase(void)
+{
+	device_t dev;
+	u32 pciexbar_reg;
+
+	dev = get_hostbridge_dev();
+	if (!dev)
+		return 0;
+
+	pciexbar_reg = pci_read_config32(dev, PCIEXBAR);
+
+	if (!(pciexbar_reg & (1 << 0)))
+		return 0;
+
+	switch (pciexbar_reg & MASK_PCIEXBAR_LENGTH) {
+	case MASK_PCIEXBAR_LENGTH_256M:
+		pciexbar_reg &= MASK_PCIEXBAR_256M;
+		break;
+	case MASK_PCIEXBAR_LENGTH_128M:
+		pciexbar_reg &= MASK_PCIEXBAR_128M;
+		break;
+	case MASK_PCIEXBAR_LENGTH_64M:
+		pciexbar_reg &= MASK_PCIEXBAR_64M;
+		break;
+	default:
+		pciexbar_reg &= MASK_PCIEXBAR_256M;
+		break;
+	}
+
+	return pciexbar_reg;
+}
+
+uint32_t get_pcielength(void)
+{
+	device_t dev;
+	u32 pciexbar_reg;
+
+	dev = get_hostbridge_dev();
+	if (!dev)
+		return 0;
+
+	pciexbar_reg = pci_read_config32(dev, PCIEXBAR);
+
+	if (!(pciexbar_reg & (1 << 0)))
+		return 0;
+
+	switch (pciexbar_reg & MASK_PCIEXBAR_LENGTH) {
+	case MASK_PCIEXBAR_LENGTH_256M:
+		pciexbar_reg = 256;
+		break;
+	case MASK_PCIEXBAR_LENGTH_128M:
+		pciexbar_reg = 128;
+		break;
+	case MASK_PCIEXBAR_LENGTH_64M:
+		pciexbar_reg = 64;
+		break;
+	default:
+		pciexbar_reg = 64;
+		break;
+	}
+
+	return pciexbar_reg;
+}
+
+uint32_t get_tseg_memory(void)
+{
+	device_t dev = get_hostbridge_dev();
+
+	if (!dev)
+		return 0;
+
+	return pci_read_config32(dev, TSEGMB) & MASK_TSEGMB;
+}
+
+uint32_t get_top_of_low_memory(void)
+{
+	device_t dev = get_hostbridge_dev();
+
+	if (!dev)
+		return 0;
+
+	return pci_read_config32(dev, TOLUD) & MASK_TOLUD;
+}
+
+uint64_t get_top_of_upper_memory(void)
+{
+	device_t dev = get_hostbridge_dev();
+
+	if (!dev)
+		return 0;
+
+	return ((uint64_t)(pci_read_config32(dev, TOUUD_HI) & MASK_TOUUD_HI)
+		<< 32) +
+	       (uint64_t)(pci_read_config32(dev, TOUUD_LO) & MASK_TOUUD_LO);
+}
+
+uint16_t get_pmbase(void)
+{
+	device_t dev = get_pmc_dev();
+
+	if (!dev)
+		return 0;
+
+	return pci_read_config16(dev, PMC_ACPI_BASE) & 0xfff8;
+}
+
+uint16_t get_tcobase(void)
+{
+	device_t dev = get_smbus_dev();
+
+	if (!dev)
+		return 0;
+
+	return pci_read_config16(dev, TCOBASE) & MASK_TCOBASE;
+}
+
+void mmio_andthenor32(void *addr, uint32_t val2and, uint32_t val2or)
+{
+	uint32_t reg32;
+
+	reg32 = read32(addr);
+	reg32 &= (uint32_t)val2and;
+	reg32 |= (uint32_t)val2or;
+	write32(addr, reg32);
+}
+
+uint8_t silicon_stepping(void)
+{
+	uint8_t revision_id;
+	device_t dev = get_lpc_dev();
+
+	if (!dev)
+		return 0;
+
+	revision_id = pci_read_config8(dev, PCI_REVISION_ID);
+
+	return revision_id;
+}
+
+void *memcpy_s(void *dest, const void *src, size_t n)
+{
+	uint8_t *dp;
+	const uint8_t *sp;
+
+	dp = (uint8_t *)dest;
+	sp = (uint8_t *)src;
+
+	if (!n)
+		return dest;
+
+	if (n > UINT32_MAX)
+		return dest;
+
+	if (!dp)
+		return dest;
+
+	if (!sp)
+		return dest;
+
+	/*
+	 * overlap is undefined behavior, do not allow
+	 */
+	if (((dp > sp) && (dp < (sp + n))) || ((sp > dp) && (sp < (dp + n))))
+		return dest;
+
+	/*
+	 * now perform the copy
+	 */
+
+	/* Original memcpy() function */
+	unsigned long d0, d1, d2;
+
+	asm volatile(
+#ifdef __x86_64__
+		"rep ; movsd\n\t"
+		"mov %4,%%rcx\n\t"
+#else
+		"rep ; movsl\n\t"
+		"movl %4,%%ecx\n\t"
+#endif
+		"rep ; movsb\n\t"
+		: "=&c"(d0), "=&D"(d1), "=&S"(d2)
+		: "0"(n >> 2), "g"(n & 3), "1"(dest), "2"(src)
+		: "memory");
+
+	return dest;
+}
diff --git a/src/soc/intel/denverton_ns/spi.c b/src/soc/intel/denverton_ns/spi.c
new file mode 100644
index 0000000..9a651ee
--- /dev/null
+++ b/src/soc/intel/denverton_ns/spi.c
@@ -0,0 +1,25 @@
+/*
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <console/console.h>
+#include <intelblocks/fast_spi.h>
+#include <spi-generic.h>
+
+const struct spi_ctrlr_buses spi_ctrlr_bus_map[] = {
+	{ .ctrlr = &fast_spi_flash_ctrlr, .bus_start = 0, .bus_end = 0 },
+};
+
+const size_t spi_ctrlr_bus_map_count = ARRAY_SIZE(spi_ctrlr_bus_map);
diff --git a/src/soc/intel/denverton_ns/systemagent.c b/src/soc/intel/denverton_ns/systemagent.c
new file mode 100644
index 0000000..bb5f81a
--- /dev/null
+++ b/src/soc/intel/denverton_ns/systemagent.c
@@ -0,0 +1,356 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015 - 2017 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 <delay.h>
+#include <timer.h>
+
+#include <soc/iomap.h>
+#include <soc/pci_devs.h>
+#include <soc/ramstage.h>
+#include <soc/systemagent.h>
+
+#define _1ms 1
+#define WAITING_STEP 100
+
+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;
+}
+
+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"},
+};
+
+/*
+ * 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 {
+	TOUUD_REG,
+	TOLUD_REG,
+	TSEG_REG,
+	/* Must be last. */
+	NUM_MAP_ENTRIES
+};
+
+static struct map_entry memory_map[NUM_MAP_ENTRIES] = {
+		[TOUUD_REG] = MAP_ENTRY_BASE_64(TOUUD, "TOUUD"),
+		[TOLUD_REG] = MAP_ENTRY_BASE_32(TOLUD, "TOLUD"),
+		[TSEG_REG] = MAP_ENTRY_BASE_32(TSEGMB, "TSEGMB"),
+};
+
+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]);
+	}
+}
+
+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];
+
+	/* 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]);
+
+	/*
+	 * These are the host memory ranges that should be added:
+	 * - 0 -> 0xa0000: cacheable
+	 * - 0xc0000 -> 0x100000 : reserved
+	 * - 0x100000 -> top_of_ram : cacheable
+	 * - top_of_ram -> TSEG: uncacheable
+	 * - TESG -> TOLUD: 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);
+
+	/* 0x100000 -> top_of_ram */
+	base_k = 0x100000 >> 10;
+	size_k = (top_of_32bit_ram() >> 10) - base_k;
+	ram_resource(dev, index++, base_k, size_k);
+
+	/* top_of_ram -> TSEG */
+	resource = new_resource(dev, index++);
+	resource->base = top_of_32bit_ram();
+	resource->size = mc_values[TSEG_REG] - resource->base;
+	resource->flags = IORESOURCE_MEM | IORESOURCE_FIXED |
+			  IORESOURCE_STORED | IORESOURCE_RESERVE |
+			  IORESOURCE_ASSIGNED;
+
+	/* TSEG -> TOLUD */
+	resource = new_resource(dev, index++);
+	resource->base = mc_values[TSEG_REG];
+	resource->size = mc_values[TOLUD_REG] - resource->base;
+	resource->flags = IORESOURCE_MEM | IORESOURCE_FIXED |
+			  IORESOURCE_STORED | IORESOURCE_RESERVE |
+			  IORESOURCE_ASSIGNED | IORESOURCE_CACHEABLE;
+	printk(BIOS_DEBUG,
+		"SMM memory location: 0x%llx  SMM memory size: 0x%llx\n",
+		resource->base, resource->size);
+
+	/* 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: reserved RAM
+	 */
+	mmio_resource(dev, index++, (0xa0000 >> 10), (0xc0000 - 0xa0000) >> 10);
+	reserved_ram_resource(dev, index++, (0xc0000 >> 10),
+			      (0x100000 - 0xc0000) >> 10);
+}
+
+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)
+{
+	struct stopwatch sw;
+	void *bios_reset_cpl =
+		(void *)(DEFAULT_MCHBAR + MCH_BAR_BIOS_RESET_CPL);
+	uint32_t reg = read32(bios_reset_cpl);
+
+	/* Stage0 BIOS Reset Complete (RST_CPL) */
+	reg |= RST_CPL_BIT;
+	write32(bios_reset_cpl, reg);
+
+	/*
+	* Poll for bit 8 in same reg (RST_CPL).
+	* We wait here till 1 ms for the bit to get set.
+	*/
+	stopwatch_init_msecs_expire(&sw, _1ms);
+	while (!(read32(bios_reset_cpl) & PCODE_INIT_DONE)) {
+		if (stopwatch_expired(&sw)) {
+			printk(BIOS_DEBUG, "Failed to set RST_CPL bit\n");
+			return;
+		}
+		udelay(WAITING_STEP);
+	}
+	printk(BIOS_DEBUG, "Set BIOS_RESET_CPL\n");
+}
+
+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,
+};
+
+/* IDs for System Agent device of Intel Denverton SoC */
+static const unsigned short systemagent_ids[] = {
+	SA_DEVID, /* DVN System Agent */
+	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/denverton_ns/tsc_freq.c b/src/soc/intel/denverton_ns/tsc_freq.c
new file mode 100644
index 0000000..6bf2a48
--- /dev/null
+++ b/src/soc/intel/denverton_ns/tsc_freq.c
@@ -0,0 +1,31 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google Inc.
+ * Copyright (C) 2014 - 2017 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 <cpu/x86/msr.h>
+#include <cpu/x86/tsc.h>
+#include <arch/cpu.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/denverton_ns/uart.c b/src/soc/intel/denverton_ns/uart.c
new file mode 100644
index 0000000..ca4e8b5
--- /dev/null
+++ b/src/soc/intel/denverton_ns/uart.c
@@ -0,0 +1,53 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 - 2017 Intel Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+/*
+ * The sole purpose of this driver is to avoid BAR to be changed during
+ * resource allocation. Since configuration space is just 32 bytes it
+ * shouldn't cause any fragmentation.
+ */
+
+#include <console/uart.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <soc/pci_devs.h>
+#include <console/console.h>
+
+static void dnv_ns_uart_read_resources(struct device *dev)
+{
+	/* read resources to be visible in the log*/
+	pci_dev_read_resources(dev);
+}
+
+static struct device_operations uart_ops = {
+	.read_resources = dnv_ns_uart_read_resources,
+	.set_resources = pci_dev_set_resources,
+	.enable_resources = pci_dev_enable_resources,
+	.init = pci_dev_init,
+	.enable = DEVICE_NOOP
+};
+
+static const unsigned short uart_ids[] = {
+	HSUART_DEVID, /* HSUART 0/1/2 */
+	0
+};
+
+static const struct pci_driver uart_driver __pci_driver = {
+	.ops = &uart_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.devices = uart_ids
+};
diff --git a/src/soc/intel/denverton_ns/uart_debug.c b/src/soc/intel/denverton_ns/uart_debug.c
new file mode 100644
index 0000000..f909d56
--- /dev/null
+++ b/src/soc/intel/denverton_ns/uart_debug.c
@@ -0,0 +1,34 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2016 - 2017 Intel Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <stdint.h>
+#include <device/pci_def.h>
+#include <io.h>
+#include <arch/pci_io_cfg.h>
+#include <soc/uart.h>
+
+#define MY_PCI_DEV(SEGBUS, DEV, FN) \
+	((((SEGBUS)&0xFFF) << 20) | (((DEV)&0x1F) << 15) | (((FN)&0x07) << 12))
+
+uintptr_t uart_platform_base(int idx);
+
+uintptr_t uart_platform_base(int idx)
+{
+	return (uintptr_t)pci_io_read_config32(
+		       MY_PCI_DEV(0, CONFIG_HSUART_DEV, idx),
+		       PCI_BASE_ADDRESS_1) +
+	       SIZE_OF_HSUART_RES * idx;
+}
diff --git a/src/soc/intel/denverton_ns/upd_display.c b/src/soc/intel/denverton_ns/upd_display.c
new file mode 100644
index 0000000..076ffec
--- /dev/null
+++ b/src/soc/intel/denverton_ns/upd_display.c
@@ -0,0 +1,141 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2016 - 2017 Intel Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <arch/cpu.h>
+#include <console/console.h>
+#include <fsp/util.h>
+#include <lib.h>
+
+/* Display the UPD parameters for MemoryInit */
+void soc_display_fspm_upd_params(
+	const FSPM_UPD *fspm_old_upd,
+	const FSPM_UPD *fspm_new_upd)
+{
+	const FSP_M_CONFIG *new;
+	const FSP_M_CONFIG *old;
+
+	old = &fspm_old_upd->FspmConfig;
+	new = &fspm_new_upd->FspmConfig;
+
+	printk(BIOS_SPEW, "UPD values for MemoryInit:\n");
+
+	#define DISPLAY_UPD(field) \
+		fsp_display_upd_value(#field, sizeof(old->field), \
+			old->field, new->field)
+
+	DISPLAY_UPD(PcdSmmTsegSize);
+	DISPLAY_UPD(PcdFspDebugPrintErrorLevel);
+	DISPLAY_UPD(PcdSpdSmbusAddress_0_0);
+	DISPLAY_UPD(PcdSpdSmbusAddress_0_1);
+	DISPLAY_UPD(PcdSpdSmbusAddress_1_0);
+	DISPLAY_UPD(PcdSpdSmbusAddress_1_1);
+	DISPLAY_UPD(PcdMrcRmtSupport);
+	DISPLAY_UPD(PcdMrcRmtCpgcExpLoopCntValue);
+	DISPLAY_UPD(PcdMrcRmtCpgcNumBursts);
+	DISPLAY_UPD(PcdMemoryPreservation);
+	DISPLAY_UPD(PcdFastBoot);
+	DISPLAY_UPD(PcdEccSupport);
+	DISPLAY_UPD(PcdHsuartDevice);
+	DISPLAY_UPD(PcdMemoryDown);
+	DISPLAY_UPD(PcdEnableSATA0);
+	DISPLAY_UPD(PcdEnableSATA1);
+	DISPLAY_UPD(PcdEnableIQAT);
+	DISPLAY_UPD(PcdSmbusSpdWriteDisable);
+	DISPLAY_UPD(PcdEnableMeShutdown);
+	DISPLAY_UPD(PcdEnableXhci);
+	DISPLAY_UPD(PcdDdrFreq);
+	DISPLAY_UPD(PcdMmioSize);
+	DISPLAY_UPD(PcdMeHeciCommunication);
+	DISPLAY_UPD(PcdHsioLanesNumber);
+	DISPLAY_UPD(PcdFiaMuxConfigPtr);
+	DISPLAY_UPD(PcdHalfWidthEnable);
+	DISPLAY_UPD(PcdTclIdle);
+	DISPLAY_UPD(PcdInterleaveMode);
+	DISPLAY_UPD(PcdMemoryThermalThrottling);
+	DISPLAY_UPD(PcdSkipMemoryTest);
+	DISPLAY_UPD(PcdUsb2Port1Pin);
+	DISPLAY_UPD(PcdUsb2Port2Pin);
+	DISPLAY_UPD(PcdUsb2Port3Pin);
+	DISPLAY_UPD(PcdUsb2Port4Pin);
+	DISPLAY_UPD(PcdUsb3Port1Pin);
+	DISPLAY_UPD(PcdUsb3Port2Pin);
+	DISPLAY_UPD(PcdUsb3Port3Pin);
+	DISPLAY_UPD(PcdUsb3Port4Pin);
+	DISPLAY_UPD(PcdIOxAPIC0_199);
+	DISPLAY_UPD(PcdDmapX16);
+
+	#undef DISPLAY_UPD
+
+	hexdump(fspm_new_upd, sizeof(*fspm_new_upd));
+}
+
+/* Display the UPD parameters for SiliconInit */
+void soc_display_fsps_upd_params(
+	const FSPS_UPD *fsps_old_upd,
+	const FSPS_UPD *fsps_new_upd)
+{
+	const FSP_S_CONFIG *new;
+	const FSP_S_CONFIG *old;
+
+	old = &fsps_old_upd->FspsConfig;
+	new = &fsps_new_upd->FspsConfig;
+
+	printk(BIOS_SPEW, "UPD values for SiliconInit:\n");
+
+	#define DISPLAY_UPD(field) \
+		fsp_display_upd_value(#field, sizeof(old->field), \
+			old->field, new->field)
+
+	DISPLAY_UPD(PcdBifurcationPcie0);
+	DISPLAY_UPD(PcdBifurcationPcie1);
+	DISPLAY_UPD(PcdActiveCoreCount);
+	DISPLAY_UPD(PcdCpuMicrocodePatchBase);
+	DISPLAY_UPD(PcdCpuMicrocodePatchSize);
+	DISPLAY_UPD(PcdEnablePcie0);
+	DISPLAY_UPD(PcdEnablePcie1);
+	DISPLAY_UPD(PcdEnableEmmc);
+	DISPLAY_UPD(PcdEnableGbE);
+	DISPLAY_UPD(PcdFiaMuxConfigRequestPtr);
+	DISPLAY_UPD(PcdPcieRootPort0DeEmphasis);
+	DISPLAY_UPD(PcdPcieRootPort1DeEmphasis);
+	DISPLAY_UPD(PcdPcieRootPort2DeEmphasis);
+	DISPLAY_UPD(PcdPcieRootPort3DeEmphasis);
+	DISPLAY_UPD(PcdPcieRootPort4DeEmphasis);
+	DISPLAY_UPD(PcdPcieRootPort5DeEmphasis);
+	DISPLAY_UPD(PcdPcieRootPort6DeEmphasis);
+	DISPLAY_UPD(PcdPcieRootPort7DeEmphasis);
+	DISPLAY_UPD(PcdEMMCDLLConfigPtr);
+	DISPLAY_UPD(PcdPcieRootPort0LinkSpeed);
+	DISPLAY_UPD(PcdPcieRootPort1LinkSpeed);
+	DISPLAY_UPD(PcdPcieRootPort2LinkSpeed);
+	DISPLAY_UPD(PcdPcieRootPort3LinkSpeed);
+	DISPLAY_UPD(PcdPcieRootPort4LinkSpeed);
+	DISPLAY_UPD(PcdPcieRootPort5LinkSpeed);
+	DISPLAY_UPD(PcdPcieRootPort6LinkSpeed);
+	DISPLAY_UPD(PcdPcieRootPort7LinkSpeed);
+	DISPLAY_UPD(PcdPcieRootPort0Aspm);
+	DISPLAY_UPD(PcdPcieRootPort1Aspm);
+	DISPLAY_UPD(PcdPcieRootPort2Aspm);
+	DISPLAY_UPD(PcdPcieRootPort3Aspm);
+	DISPLAY_UPD(PcdPcieRootPort4Aspm);
+	DISPLAY_UPD(PcdPcieRootPort5Aspm);
+	DISPLAY_UPD(PcdPcieRootPort6Aspm);
+	DISPLAY_UPD(PcdPcieRootPort7Aspm);
+
+	#undef DISPLAY_UPD
+
+	hexdump(fsps_new_upd, sizeof(*fsps_new_upd));
+}
diff --git a/src/soc/intel/denverton_ns/xhci.c b/src/soc/intel/denverton_ns/xhci.c
new file mode 100644
index 0000000..5f8482e
--- /dev/null
+++ b/src/soc/intel/denverton_ns/xhci.c
@@ -0,0 +1,51 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 - 2017 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 <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <arch/io.h>
+
+#include <soc/pci_devs.h>
+#include <soc/ramstage.h>
+
+static void usb_xhci_init(struct device *dev)
+{
+	/* USB XHCI configuration is handled by the FSP */
+
+	printk(BIOS_NOTICE, "pch: %s\n", __func__);
+
+	/* Set the value for PCI command register. */
+	pci_write_config16(dev, PCI_COMMAND,
+			   PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
+}
+
+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,
+	.init = usb_xhci_init,
+	.enable = pci_dev_enable_resources,
+	.scan_bus = 0,
+	.ops_pci = &soc_pci_ops,
+};
+
+static const struct pci_driver pch_usb_xhci __pci_driver = {
+	.ops = &usb_xhci_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = XHCI_DEVID,
+};