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, µcode_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,
+};