[coreboot-gerrit] Patch set updated for coreboot: soc/intel/kabylake: Initial SoC Commit
Naveen Krishna (naveenkrishna.ch@gmail.com)
gerrit at coreboot.org
Thu Jul 21 18:23:06 CEST 2016
Naveen Krishna (naveenkrishna.ch at gmail.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/15768
-gerrit
commit 8e6188254e3a37e74155d305d7d867c774dbf812
Author: Naveen Krishna Chatradhi <naveenkrishna.ch at intel.com>
Date: Tue Jul 5 14:05:53 2016 +0530
soc/intel/kabylake: Initial SoC Commit
Cloned entirely from Skylake
commit-id: 67870f508fbec35be393efccdac2c658cbc40ed0
with the following changes
1. String Skylake replaced to Kabylake
2. Year in copyright license updated to 2016
3. src/soc/intel/kabylake/Makefile.inc retains "skylake"
to make the kabylake compilable.
This will be modified when the FSP2.0 header are added.
BUG=chrome-os-partner:55399
TEST= with the mainboard patches.
#make menuconfig, select Kabylake SoC, kblrvp3 board.
#make compiles
Change-Id: I27712f6011f425e2f1bdd35990e89d0596105e06
Signed-off-by: Naveen Krishna Chatradhi <naveenkrishna.ch at intel.com>
---
src/soc/intel/kabylake/Kconfig | 200 ++++
src/soc/intel/kabylake/Makefile.inc | 90 ++
src/soc/intel/kabylake/acpi.c | 609 +++++++++++
src/soc/intel/kabylake/acpi/cpu.asl | 118 +++
src/soc/intel/kabylake/acpi/dptf/charger.asl | 75 ++
src/soc/intel/kabylake/acpi/dptf/cpu.asl | 224 ++++
src/soc/intel/kabylake/acpi/dptf/dptf.asl | 116 +++
src/soc/intel/kabylake/acpi/dptf/fan.asl | 68 ++
src/soc/intel/kabylake/acpi/dptf/thermal.asl | 283 +++++
src/soc/intel/kabylake/acpi/globalnvs.asl | 95 ++
src/soc/intel/kabylake/acpi/gpio.asl | 115 ++
src/soc/intel/kabylake/acpi/irqlinks.asl | 436 ++++++++
src/soc/intel/kabylake/acpi/lpc.asl | 144 +++
src/soc/intel/kabylake/acpi/pch.asl | 72 ++
src/soc/intel/kabylake/acpi/pch_hda.asl | 84 ++
src/soc/intel/kabylake/acpi/pci_irqs.asl | 133 +++
src/soc/intel/kabylake/acpi/pcie.asl | 316 ++++++
src/soc/intel/kabylake/acpi/pcr.asl | 71 ++
src/soc/intel/kabylake/acpi/platform.asl | 84 ++
src/soc/intel/kabylake/acpi/pmc.asl | 41 +
src/soc/intel/kabylake/acpi/scs.asl | 127 +++
src/soc/intel/kabylake/acpi/serialio.asl | 83 ++
src/soc/intel/kabylake/acpi/sleepstates.asl | 23 +
src/soc/intel/kabylake/acpi/smbus.asl | 238 +++++
src/soc/intel/kabylake/acpi/systemagent.asl | 372 +++++++
src/soc/intel/kabylake/acpi/xhci.asl | 185 ++++
src/soc/intel/kabylake/bootblock/cpu.c | 165 +++
src/soc/intel/kabylake/bootblock/pch.c | 58 ++
src/soc/intel/kabylake/bootblock/systemagent.c | 41 +
src/soc/intel/kabylake/bootblock/timestamp.inc | 35 +
src/soc/intel/kabylake/chip.c | 1102 ++++++++++++++++++++
src/soc/intel/kabylake/chip.h | 386 +++++++
src/soc/intel/kabylake/cpu.c | 494 +++++++++
src/soc/intel/kabylake/cpu_info.c | 50 +
src/soc/intel/kabylake/dsp.c | 33 +
src/soc/intel/kabylake/elog.c | 125 +++
src/soc/intel/kabylake/finalize.c | 221 ++++
src/soc/intel/kabylake/flash_controller.c | 437 ++++++++
src/soc/intel/kabylake/fsp_reset.c | 62 ++
src/soc/intel/kabylake/gpio.c | 415 ++++++++
src/soc/intel/kabylake/i2c.c | 116 +++
src/soc/intel/kabylake/igd.c | 219 ++++
src/soc/intel/kabylake/include/soc/acpi.h | 37 +
src/soc/intel/kabylake/include/soc/car_setup.S | 334 ++++++
src/soc/intel/kabylake/include/soc/car_teardown.S | 54 +
src/soc/intel/kabylake/include/soc/cpu.h | 65 ++
src/soc/intel/kabylake/include/soc/device_nvs.h | 43 +
.../intel/kabylake/include/soc/flash_controller.h | 181 ++++
src/soc/intel/kabylake/include/soc/gpe.h | 133 +++
src/soc/intel/kabylake/include/soc/gpio.h | 174 ++++
src/soc/intel/kabylake/include/soc/gpio_defs.h | 509 +++++++++
src/soc/intel/kabylake/include/soc/interrupt.h | 46 +
src/soc/intel/kabylake/include/soc/iomap.h | 71 ++
src/soc/intel/kabylake/include/soc/irq.h | 103 ++
src/soc/intel/kabylake/include/soc/lpc.h | 58 ++
src/soc/intel/kabylake/include/soc/me.h | 182 ++++
src/soc/intel/kabylake/include/soc/msr.h | 109 ++
src/soc/intel/kabylake/include/soc/nhlt.h | 63 ++
src/soc/intel/kabylake/include/soc/nvs.h | 68 ++
src/soc/intel/kabylake/include/soc/pch.h | 38 +
src/soc/intel/kabylake/include/soc/pci_devs.h | 179 ++++
src/soc/intel/kabylake/include/soc/pcr.h | 120 +++
src/soc/intel/kabylake/include/soc/pei_data.h | 99 ++
src/soc/intel/kabylake/include/soc/pei_wrapper.h | 27 +
src/soc/intel/kabylake/include/soc/pm.h | 194 ++++
src/soc/intel/kabylake/include/soc/pmc.h | 112 ++
src/soc/intel/kabylake/include/soc/ramstage.h | 31 +
src/soc/intel/kabylake/include/soc/romstage.h | 36 +
src/soc/intel/kabylake/include/soc/serialio.h | 56 +
src/soc/intel/kabylake/include/soc/smbus.h | 51 +
src/soc/intel/kabylake/include/soc/smm.h | 88 ++
src/soc/intel/kabylake/include/soc/spi.h | 136 +++
src/soc/intel/kabylake/include/soc/systemagent.h | 122 +++
src/soc/intel/kabylake/include/soc/usb.h | 172 +++
src/soc/intel/kabylake/include/soc/vr_config.h | 80 ++
src/soc/intel/kabylake/include/soc/xhci.h | 60 ++
src/soc/intel/kabylake/lpc.c | 327 ++++++
src/soc/intel/kabylake/me_status.c | 324 ++++++
src/soc/intel/kabylake/memmap.c | 207 ++++
src/soc/intel/kabylake/monotonic_timer.c | 39 +
src/soc/intel/kabylake/nhlt/Makefile.inc | 47 +
src/soc/intel/kabylake/nhlt/dmic.c | 116 +++
src/soc/intel/kabylake/nhlt/max98357.c | 47 +
src/soc/intel/kabylake/nhlt/nau88l25.c | 71 ++
src/soc/intel/kabylake/nhlt/ssm4567.c | 70 ++
src/soc/intel/kabylake/pch.c | 97 ++
src/soc/intel/kabylake/pcie.c | 106 ++
src/soc/intel/kabylake/pcr.c | 187 ++++
src/soc/intel/kabylake/pei_data.c | 49 +
src/soc/intel/kabylake/pmc.c | 312 ++++++
src/soc/intel/kabylake/pmutil.c | 439 ++++++++
src/soc/intel/kabylake/ramstage.c | 23 +
src/soc/intel/kabylake/romstage/Makefile.inc | 21 +
src/soc/intel/kabylake/romstage/cpu.c | 52 +
src/soc/intel/kabylake/romstage/i2c.c | 109 ++
src/soc/intel/kabylake/romstage/pch.c | 133 +++
src/soc/intel/kabylake/romstage/power_state.c | 180 ++++
src/soc/intel/kabylake/romstage/report_platform.c | 216 ++++
src/soc/intel/kabylake/romstage/romstage.c | 268 +++++
src/soc/intel/kabylake/romstage/smbus.c | 51 +
src/soc/intel/kabylake/romstage/spi.c | 42 +
src/soc/intel/kabylake/romstage/systemagent.c | 52 +
src/soc/intel/kabylake/romstage/uart.c | 70 ++
src/soc/intel/kabylake/sd.c | 88 ++
src/soc/intel/kabylake/smbus.c | 109 ++
src/soc/intel/kabylake/smbus_common.c | 150 +++
src/soc/intel/kabylake/smi.c | 121 +++
src/soc/intel/kabylake/smihandler.c | 517 +++++++++
src/soc/intel/kabylake/smmrelocate.c | 317 ++++++
src/soc/intel/kabylake/systemagent.c | 424 ++++++++
src/soc/intel/kabylake/tsc_freq.c | 29 +
src/soc/intel/kabylake/uart.c | 63 ++
src/soc/intel/kabylake/uart_debug.c | 26 +
src/soc/intel/kabylake/vr_config.c | 107 ++
src/soc/intel/kabylake/xhci.c | 43 +
115 files changed, 17841 insertions(+)
diff --git a/src/soc/intel/kabylake/Kconfig b/src/soc/intel/kabylake/Kconfig
new file mode 100644
index 0000000..893c35a
--- /dev/null
+++ b/src/soc/intel/kabylake/Kconfig
@@ -0,0 +1,200 @@
+config SOC_INTEL_KABYLAKE
+ bool
+ help
+ Intel Kabylake support
+
+if SOC_INTEL_KABYLAKE
+
+config CPU_SPECIFIC_OPTIONS
+ def_bool y
+ select ACPI_INTEL_HARDWARE_SLEEP_VALUES
+ select ARCH_BOOTBLOCK_X86_32
+ select ARCH_RAMSTAGE_X86_32
+ select ARCH_ROMSTAGE_X86_32
+ select ARCH_VERSTAGE_X86_32
+ select ACPI_NHLT
+ select CACHE_MRC_SETTINGS
+ select CACHE_RELOCATED_RAMSTAGE_OUTSIDE_CBMEM if RELOCATABLE_RAMSTAGE
+ select COLLECT_TIMESTAMPS
+ select CPU_INTEL_FIRMWARE_INTERFACE_TABLE
+ select GENERIC_GPIO_LIB
+ select HAVE_HARD_RESET
+ select HAVE_INTEL_FIRMWARE
+ select HAVE_MONOTONIC_TIMER
+ select HAVE_SMI_HANDLER
+ select IOAPIC
+ select MMCONF_SUPPORT
+ select MMCONF_SUPPORT_DEFAULT
+ select NO_FIXED_XIP_ROM_SIZE
+ select MRC_SETTINGS_PROTECT
+ select PARALLEL_MP
+ select PCIEXP_ASPM
+ select PCIEXP_COMMON_CLOCK
+ select PCIEXP_CLK_PM
+ select PCIEXP_L1_SUB_STATE
+ select PLATFORM_USES_FSP1_1
+ select REG_SCRIPT
+ select RELOCATABLE_MODULES
+ select RELOCATABLE_RAMSTAGE
+ select SOC_INTEL_COMMON
+ select SOC_INTEL_COMMON_ACPI_WAKE_SOURCE
+ select SOC_INTEL_COMMON_LPSS_I2C
+ select SOC_INTEL_COMMON_NHLT
+ select SOC_INTEL_COMMON_RESET
+ select SMM_TSEG
+ select SMP
+ select SPI_FLASH
+ select SSE2
+ select SUPPORT_CPU_UCODE_IN_CBFS
+ select TSC_CONSTANT_RATE
+ select TSC_SYNC_MFENCE
+ select UDELAY_TSC
+ select USE_GENERIC_FSP_CAR_INC
+
+config BOOTBLOCK_CPU_INIT
+ string
+ default "soc/intel/kabylake/bootblock/cpu.c"
+
+config BOOTBLOCK_NORTHBRIDGE_INIT
+ string
+ default "soc/intel/kabylake/bootblock/systemagent.c"
+
+config BOOTBLOCK_RESETS
+ string
+ default "soc/intel/common/reset.c"
+
+config BOOTBLOCK_SOUTHBRIDGE_INIT
+ string
+ default "soc/intel/kabylake/bootblock/pch.c"
+
+config CBFS_SIZE
+ hex
+ default 0x200000
+
+config CPU_ADDR_BITS
+ int
+ default 36
+
+config SOC_INTEL_COMMON_LPSS_I2C_CLOCK_MHZ
+ int
+ default 120
+
+config DCACHE_RAM_BASE
+ hex "Base address of cache-as-RAM"
+ default 0xfef00000
+
+config DCACHE_RAM_SIZE
+ hex "Length in bytes of cache-as-RAM"
+ default 0x10000
+ help
+ The size of the cache-as-ram region required during bootblock
+ and/or romstage.
+
+config EXCLUDE_NATIVE_SD_INTERFACE
+ bool
+ default n
+ help
+ If you set this option to n, will not use native SD controller.
+
+config HEAP_SIZE
+ hex
+ default 0x80000
+
+config IED_REGION_SIZE
+ hex
+ default 0x400000
+
+config MMCONF_BASE_ADDRESS
+ hex "MMIO Base Address"
+ default 0xe0000000
+
+config MONOTONIC_TIMER_MSR
+ def_bool y
+ select HAVE_MONOTONIC_TIMER
+ help
+ Provide a monotonic timer using the 24MHz MSR counter.
+
+config PRE_GRAPHICS_DELAY
+ int "Graphics initialization delay in ms"
+ default 0
+ help
+ On some systems, coreboot boots so fast that connected monitors
+ (mostly TVs) won't be able to wake up fast enough to talk to the
+ VBIOS. On those systems we need to wait for a bit before executing
+ the VBIOS.
+
+config SERIAL_CPU_INIT
+ bool
+ default n
+
+config SERIRQ_CONTINUOUS_MODE
+ bool
+ default n
+ help
+ If you set this option to y, the serial IRQ machine will be
+ operated in continuous mode.
+
+config SMM_RESERVED_SIZE
+ hex
+ default 0x200000
+
+config SMM_TSEG_SIZE
+ hex
+ default 0x800000
+
+config VGA_BIOS_ID
+ string
+ default "8086,0406"
+
+config UART_DEBUG
+ bool "Enable UART debug port."
+ default n
+ select CONSOLE_SERIAL
+ select DRIVERS_UART
+ select DRIVERS_UART_8250MEM_32
+
+config CHIPSET_BOOTBLOCK_INCLUDE
+ string
+ default "soc/intel/kabylake/bootblock/timestamp.inc"
+
+config NHLT_DMIC_2CH
+ bool
+ default n
+ help
+ Include DSP firmware settings for 2 channel DMIC array.
+
+config NHLT_DMIC_4CH
+ bool
+ default n
+ help
+ Include DSP firmware settings for 4 channel DMIC array.
+
+config NHLT_NAU88L25
+ bool
+ default n
+ help
+ Include DSP firmware settings for nau88l25 headset codec.
+
+config NHLT_MAX98357
+ bool
+ default n
+ help
+ Include DSP firmware settings for max98357 amplifier.
+
+config NHLT_SSM4567
+ bool
+ default n
+ help
+ Include DSP firmware settings for ssm4567 smart amplifier.
+
+config DCACHE_RAM_SIZE_TOTAL
+ hex
+ default 0x40000
+
+config SKIP_FSP_CAR
+ bool "Skip cache as RAM setup in FSP"
+ default y
+ help
+ Skip Cache as RAM setup in FSP.
+
+endif
diff --git a/src/soc/intel/kabylake/Makefile.inc b/src/soc/intel/kabylake/Makefile.inc
new file mode 100644
index 0000000..be2b5fe
--- /dev/null
+++ b/src/soc/intel/kabylake/Makefile.inc
@@ -0,0 +1,90 @@
+ifeq ($(CONFIG_SOC_INTEL_KABYLAKE),y)
+
+subdirs-y += nhlt
+subdirs-y += romstage
+subdirs-y += ../../../cpu/intel/microcode
+subdirs-y += ../../../cpu/intel/turbo
+subdirs-y += ../../../cpu/x86/lapic
+subdirs-y += ../../../cpu/x86/mtrr
+subdirs-y += ../../../cpu/x86/smm
+subdirs-y += ../../../cpu/x86/tsc
+
+verstage-y += gpio.c
+verstage-y += memmap.c
+verstage-y += monotonic_timer.c
+verstage-y += pch.c
+verstage-y += pmutil.c
+verstage-y += pcr.c
+verstage-y += tsc_freq.c
+verstage-$(CONFIG_UART_DEBUG) += uart_debug.c
+
+romstage-y += flash_controller.c
+romstage-y += gpio.c
+romstage-y += memmap.c
+romstage-y += monotonic_timer.c
+romstage-y += pch.c
+romstage-y += pcr.c
+romstage-y += pei_data.c
+romstage-y += pmutil.c
+romstage-y += smbus_common.c
+romstage-y += tsc_freq.c
+romstage-$(CONFIG_UART_DEBUG) += uart_debug.c
+
+ramstage-$(CONFIG_HAVE_ACPI_TABLES) += acpi.c
+ramstage-y += chip.c
+ramstage-y += cpu.c
+ramstage-y += cpu_info.c
+ramstage-y += dsp.c
+ramstage-y += elog.c
+ramstage-y += finalize.c
+ramstage-y += flash_controller.c
+ramstage-$(CONFIG_VBOOT_VERIFY_FIRMWARE) += fsp_reset.c
+ramstage-y += gpio.c
+ramstage-y += i2c.c
+ramstage-y += igd.c
+ramstage-y += lpc.c
+ramstage-y += me_status.c
+ramstage-y += memmap.c
+ramstage-y += monotonic_timer.c
+ramstage-y += pch.c
+ramstage-y += pcie.c
+ramstage-y += pcr.c
+ramstage-y += pei_data.c
+ramstage-y += pmc.c
+ramstage-y += pmutil.c
+ramstage-y += ramstage.c
+ramstage-y += sd.c
+ramstage-y += smbus.c
+ramstage-y += smbus_common.c
+ramstage-y += smi.c
+ramstage-y += smmrelocate.c
+ramstage-y += systemagent.c
+ramstage-y += tsc_freq.c
+ramstage-y += uart.c
+ramstage-$(CONFIG_UART_DEBUG) += uart_debug.c
+ramstage-y += vr_config.c
+ramstage-y += xhci.c
+
+smm-y += cpu_info.c
+smm-y += gpio.c
+smm-y += monotonic_timer.c
+smm-y += pcr.c
+smm-y += pch.c
+smm-y += pmutil.c
+smm-y += smihandler.c
+smm-$(CONFIG_SPI_FLASH_SMM) += flash_controller.c
+smm-y += tsc_freq.c
+smm-$(CONFIG_UART_DEBUG) += uart_debug.c
+
+# cpu_microcode_bins += ???
+
+CPPFLAGS_common += -I$(src)/soc/intel/kabylake
+CPPFLAGS_common += -I$(src)/soc/intel/kabylake/include
+CPPFLAGS_common += -I$(src)/vendorcode/intel/fsp/fsp1_1/skylake
+
+# Currently used for microcode path.
+CPPFLAGS_common += -I3rdparty/blobs/mainboard/$(CONFIG_MAINBOARD_DIR)
+
+ROMCCFLAGS := -mcpu=p4 -fno-simplify-phi -O2
+
+endif
diff --git a/src/soc/intel/kabylake/acpi.c b/src/soc/intel/kabylake/acpi.c
new file mode 100644
index 0000000..14a84ae
--- /dev/null
+++ b/src/soc/intel/kabylake/acpi.c
@@ -0,0 +1,609 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2009 coresystems GmbH
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <arch/acpi.h>
+#include <arch/acpigen.h>
+#include <arch/cpu.h>
+#include <arch/io.h>
+#include <arch/ioapic.h>
+#include <arch/smp/mpspec.h>
+#include <cbmem.h>
+#include <chip.h>
+#include <console/console.h>
+#include <cpu/cpu.h>
+#include <cpu/x86/smm.h>
+#include <cpu/x86/msr.h>
+#include <cpu/x86/tsc.h>
+#include <cpu/intel/turbo.h>
+#include <ec/google/chromeec/ec.h>
+#include <soc/intel/common/acpi.h>
+#include <soc/acpi.h>
+#include <soc/cpu.h>
+#include <soc/iomap.h>
+#include <soc/lpc.h>
+#include <soc/msr.h>
+#include <soc/pci_devs.h>
+#include <soc/pm.h>
+#include <string.h>
+#include <types.h>
+#include <vendorcode/google/chromeos/gnvs.h>
+#include <wrdd.h>
+
+/*
+ * List of suported C-states in this processor.
+ */
+enum {
+ C_STATE_C0, /* 0 */
+ C_STATE_C1, /* 1 */
+ C_STATE_C1E, /* 2 */
+ C_STATE_C3, /* 3 */
+ C_STATE_C6_SHORT_LAT, /* 4 */
+ C_STATE_C6_LONG_LAT, /* 5 */
+ C_STATE_C7_SHORT_LAT, /* 6 */
+ C_STATE_C7_LONG_LAT, /* 7 */
+ C_STATE_C7S_SHORT_LAT, /* 8 */
+ C_STATE_C7S_LONG_LAT, /* 9 */
+ C_STATE_C8, /* 10 */
+ C_STATE_C9, /* 11 */
+ C_STATE_C10, /* 12 */
+ NUM_C_STATES
+};
+#define MWAIT_RES(state, sub_state) \
+ { \
+ .addrl = (((state) << 4) | (sub_state)), \
+ .space_id = ACPI_ADDRESS_SPACE_FIXED, \
+ .bit_width = ACPI_FFIXEDHW_VENDOR_INTEL, \
+ .bit_offset = ACPI_FFIXEDHW_CLASS_MWAIT, \
+ .access_size = ACPI_FFIXEDHW_FLAG_HW_COORD, \
+ }
+
+static acpi_cstate_t cstate_map[NUM_C_STATES] = {
+ [C_STATE_C0] = { },
+ [C_STATE_C1] = {
+ .latency = 0,
+ .power = C1_POWER,
+ .resource = MWAIT_RES(0, 0),
+ },
+ [C_STATE_C1E] = {
+ .latency = 0,
+ .power = C1_POWER,
+ .resource = MWAIT_RES(0, 1),
+ },
+ [C_STATE_C3] = {
+ .latency = C_STATE_LATENCY_FROM_LAT_REG(0),
+ .power = C3_POWER,
+ .resource = MWAIT_RES(1, 0),
+ },
+ [C_STATE_C6_SHORT_LAT] = {
+ .latency = C_STATE_LATENCY_FROM_LAT_REG(1),
+ .power = C6_POWER,
+ .resource = MWAIT_RES(2, 0),
+ },
+ [C_STATE_C6_LONG_LAT] = {
+ .latency = C_STATE_LATENCY_FROM_LAT_REG(2),
+ .power = C6_POWER,
+ .resource = MWAIT_RES(2, 1),
+ },
+ [C_STATE_C7_SHORT_LAT] = {
+ .latency = C_STATE_LATENCY_FROM_LAT_REG(1),
+ .power = C7_POWER,
+ .resource = MWAIT_RES(3, 0),
+ },
+ [C_STATE_C7_LONG_LAT] = {
+ .latency = C_STATE_LATENCY_FROM_LAT_REG(2),
+ .power = C7_POWER,
+ .resource = MWAIT_RES(3, 1),
+ },
+ [C_STATE_C7S_SHORT_LAT] = {
+ .latency = C_STATE_LATENCY_FROM_LAT_REG(1),
+ .power = C7_POWER,
+ .resource = MWAIT_RES(3, 2),
+ },
+ [C_STATE_C7S_LONG_LAT] = {
+ .latency = C_STATE_LATENCY_FROM_LAT_REG(2),
+ .power = C7_POWER,
+ .resource = MWAIT_RES(3, 3),
+ },
+ [C_STATE_C8] = {
+ .latency = C_STATE_LATENCY_FROM_LAT_REG(3),
+ .power = C8_POWER,
+ .resource = MWAIT_RES(4, 0),
+ },
+ [C_STATE_C9] = {
+ .latency = C_STATE_LATENCY_FROM_LAT_REG(4),
+ .power = C9_POWER,
+ .resource = MWAIT_RES(5, 0),
+ },
+ [C_STATE_C10] = {
+ .latency = C_STATE_LATENCY_FROM_LAT_REG(5),
+ .power = C10_POWER,
+ .resource = MWAIT_RES(6, 0),
+ },
+};
+
+static int cstate_set_s0ix[] = {
+ C_STATE_C1E,
+ C_STATE_C7S_LONG_LAT,
+ C_STATE_C10
+};
+
+static int cstate_set_non_s0ix[] = {
+ C_STATE_C1E,
+ C_STATE_C3,
+ C_STATE_C7S_LONG_LAT,
+ C_STATE_C8,
+ C_STATE_C9,
+ C_STATE_C10
+};
+
+static int get_cores_per_package(void)
+{
+ struct cpuinfo_x86 c;
+ struct cpuid_result result;
+ int cores = 1;
+
+ get_fms(&c, cpuid_eax(1));
+ if (c.x86 != 6)
+ return 1;
+
+ result = cpuid_ext(0xb, 1);
+ cores = result.ebx & 0xff;
+
+ return cores;
+}
+
+static void acpi_create_gnvs(global_nvs_t *gnvs)
+{
+ const struct device *dev = dev_find_slot(0, PCH_DEVFN_LPC);
+ const struct soc_intel_kabylake_config *config = dev->chip_info;
+
+ /* Set unknown wake source */
+ gnvs->pm1i = -1;
+
+ /* CPU core count */
+ gnvs->pcnt = dev_count_cpu();
+
+#if IS_ENABLED(CONFIG_CONSOLE_CBMEM)
+ /* Update the mem console pointer. */
+ gnvs->cbmc = (u32)cbmem_find(CBMEM_ID_CONSOLE);
+#endif
+
+#if IS_ENABLED(CONFIG_CHROMEOS)
+ /* Initialize Verified Boot data */
+ chromeos_init_vboot(&(gnvs->chromeos));
+#if IS_ENABLED(CONFIG_EC_GOOGLE_CHROMEEC)
+ gnvs->chromeos.vbt2 = google_ec_running_ro() ?
+ ACTIVE_ECFW_RO : ACTIVE_ECFW_RW;
+#endif
+ gnvs->chromeos.vbt2 = ACTIVE_ECFW_RO;
+#endif
+
+ /* Enable DPTF based on mainboard configuration */
+ gnvs->dpte = config->dptf_enable;
+
+ /* Fill in the Wifi Region id */
+ gnvs->cid1 = wifi_regulatory_domain();
+}
+
+unsigned long acpi_fill_mcfg(unsigned long current)
+{
+ current += acpi_create_mcfg_mmconfig((acpi_mcfg_mmconfig_t *)current,
+ MCFG_BASE_ADDRESS, 0, 0, 255);
+ return current;
+}
+
+unsigned long acpi_fill_madt(unsigned long current)
+{
+ /* Local APICs */
+ current = acpi_create_madt_lapics(current);
+
+ /* IOAPIC */
+ current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *) current,
+ 2, IO_APIC_ADDR, 0);
+
+ return acpi_madt_irq_overrides(current);
+}
+
+void acpi_fill_in_fadt(acpi_fadt_t *fadt)
+{
+ const uint16_t pmbase = ACPI_BASE_ADDRESS;
+ const struct device *dev = dev_find_slot(0, PCH_DEVFN_LPC);
+ config_t *config = dev->chip_info;
+
+ fadt->sci_int = acpi_sci_irq();
+ fadt->smi_cmd = APM_CNT;
+ fadt->acpi_enable = APM_CNT_ACPI_ENABLE;
+ fadt->acpi_disable = APM_CNT_ACPI_DISABLE;
+ fadt->s4bios_req = 0x0;
+ fadt->pstate_cnt = 0;
+
+ fadt->pm1a_evt_blk = pmbase + PM1_STS;
+ fadt->pm1b_evt_blk = 0x0;
+ fadt->pm1a_cnt_blk = pmbase + PM1_CNT;
+ fadt->pm1b_cnt_blk = 0x0;
+ fadt->pm2_cnt_blk = pmbase + PM2_CNT;
+ if (config->PmTimerDisabled == 0)
+ fadt->pm_tmr_blk = pmbase + PM1_TMR;
+ fadt->gpe0_blk = pmbase + GPE0_STS(0);
+ fadt->gpe1_blk = 0;
+
+ fadt->pm1_evt_len = 4;
+ fadt->pm1_cnt_len = 2;
+ fadt->pm2_cnt_len = 1;
+ if (config->PmTimerDisabled == 0)
+ fadt->pm_tmr_len = 4;
+ /* There are 4 GPE0 STS/EN pairs each 32 bits wide. */
+ fadt->gpe0_blk_len = 2 * GPE0_REG_MAX * sizeof(uint32_t);
+ fadt->gpe1_blk_len = 0;
+ fadt->gpe1_base = 0;
+ fadt->cst_cnt = 0;
+ fadt->p_lvl2_lat = 1;
+ fadt->p_lvl3_lat = 87;
+ fadt->flush_size = 1024;
+ fadt->flush_stride = 16;
+ fadt->duty_offset = 1;
+ fadt->duty_width = 0;
+ fadt->day_alrm = 0xd;
+ fadt->mon_alrm = 0x00;
+ fadt->century = 0x00;
+ fadt->iapc_boot_arch = ACPI_FADT_LEGACY_DEVICES | ACPI_FADT_8042;
+
+ fadt->flags = ACPI_FADT_WBINVD | ACPI_FADT_C1_SUPPORTED |
+ ACPI_FADT_C2_MP_SUPPORTED | ACPI_FADT_SLEEP_BUTTON |
+ ACPI_FADT_RESET_REGISTER | ACPI_FADT_SEALED_CASE |
+ ACPI_FADT_S4_RTC_WAKE | ACPI_FADT_PLATFORM_CLOCK;
+
+ fadt->reset_reg.space_id = 1;
+ fadt->reset_reg.bit_width = 8;
+ fadt->reset_reg.bit_offset = 0;
+ fadt->reset_reg.resv = 0;
+ fadt->reset_reg.addrl = 0xcf9;
+ fadt->reset_reg.addrh = 0;
+ fadt->reset_value = 6;
+
+ fadt->x_pm1a_evt_blk.space_id = 1;
+ fadt->x_pm1a_evt_blk.bit_width = fadt->pm1_evt_len * 8;
+ fadt->x_pm1a_evt_blk.bit_offset = 0;
+ fadt->x_pm1a_evt_blk.resv = 0;
+ fadt->x_pm1a_evt_blk.addrl = pmbase + PM1_STS;
+ fadt->x_pm1a_evt_blk.addrh = 0x0;
+
+ fadt->x_pm1b_evt_blk.space_id = 1;
+ fadt->x_pm1b_evt_blk.bit_width = 0;
+ fadt->x_pm1b_evt_blk.bit_offset = 0;
+ fadt->x_pm1b_evt_blk.resv = 0;
+ fadt->x_pm1b_evt_blk.addrl = 0x0;
+ fadt->x_pm1b_evt_blk.addrh = 0x0;
+
+ fadt->x_pm1a_cnt_blk.space_id = 1;
+ fadt->x_pm1a_cnt_blk.bit_width = fadt->pm1_cnt_len * 8;
+ fadt->x_pm1a_cnt_blk.bit_offset = 0;
+ fadt->x_pm1a_cnt_blk.resv = 0;
+ fadt->x_pm1a_cnt_blk.addrl = pmbase + PM1_CNT;
+ fadt->x_pm1a_cnt_blk.addrh = 0x0;
+
+ fadt->x_pm1b_cnt_blk.space_id = 1;
+ fadt->x_pm1b_cnt_blk.bit_width = 0;
+ fadt->x_pm1b_cnt_blk.bit_offset = 0;
+ fadt->x_pm1b_cnt_blk.resv = 0;
+ fadt->x_pm1b_cnt_blk.addrl = 0x0;
+ fadt->x_pm1b_cnt_blk.addrh = 0x0;
+
+ fadt->x_pm2_cnt_blk.space_id = 1;
+ fadt->x_pm2_cnt_blk.bit_width = fadt->pm2_cnt_len * 8;
+ fadt->x_pm2_cnt_blk.bit_offset = 0;
+ fadt->x_pm2_cnt_blk.resv = 0;
+ fadt->x_pm2_cnt_blk.addrl = pmbase + PM2_CNT;
+ fadt->x_pm2_cnt_blk.addrh = 0x0;
+
+ if (config->PmTimerDisabled == 0) {
+ fadt->x_pm_tmr_blk.space_id = 1;
+ fadt->x_pm_tmr_blk.bit_width = fadt->pm_tmr_len * 8;
+ fadt->x_pm_tmr_blk.bit_offset = 0;
+ fadt->x_pm_tmr_blk.resv = 0;
+ fadt->x_pm_tmr_blk.addrl = pmbase + PM1_TMR;
+ fadt->x_pm_tmr_blk.addrh = 0x0;
+ }
+
+ fadt->x_gpe0_blk.space_id = 0;
+ fadt->x_gpe0_blk.bit_width = 0;
+ fadt->x_gpe0_blk.bit_offset = 0;
+ fadt->x_gpe0_blk.resv = 0;
+ fadt->x_gpe0_blk.addrl = 0;
+ fadt->x_gpe0_blk.addrh = 0;
+
+ fadt->x_gpe1_blk.space_id = 1;
+ fadt->x_gpe1_blk.bit_width = 0;
+ fadt->x_gpe1_blk.bit_offset = 0;
+ fadt->x_gpe1_blk.resv = 0;
+ fadt->x_gpe1_blk.addrl = 0x0;
+ fadt->x_gpe1_blk.addrh = 0x0;
+}
+
+static void generate_c_state_entries(int s0ix_enable, int max_cstate)
+{
+
+ acpi_cstate_t map[max_cstate];
+ int *set;
+ int i;
+
+ if (s0ix_enable)
+ set = cstate_set_s0ix;
+ else
+ set = cstate_set_non_s0ix;
+
+ for (i = 0; i < max_cstate; i++) {
+ memcpy(&map[i], &cstate_map[set[i]], sizeof(acpi_cstate_t));
+ map[i].ctype = i + 1;
+ }
+
+ /* Generate C-state tables */
+ acpigen_write_CST_package(map, ARRAY_SIZE(map));
+}
+
+static int calculate_power(int tdp, int p1_ratio, int ratio)
+{
+ u32 m;
+ u32 power;
+
+ /*
+ * M = ((1.1 - ((p1_ratio - ratio) * 0.00625)) / 1.1) ^ 2
+ *
+ * Power = (ratio / p1_ratio) * m * tdp
+ */
+
+ m = (110000 - ((p1_ratio - ratio) * 625)) / 11;
+ m = (m * m) / 1000;
+
+ power = ((ratio * 100000 / p1_ratio) / 100);
+ power *= (m / 100) * (tdp / 1000);
+ power /= 1000;
+
+ return (int)power;
+}
+
+static void generate_p_state_entries(int core, int cores_per_package)
+{
+ int ratio_min, ratio_max, ratio_turbo, ratio_step;
+ int coord_type, power_max, power_unit, num_entries;
+ int ratio, power, clock, clock_max;
+ msr_t msr;
+
+ /* Determine P-state coordination type from MISC_PWR_MGMT[0] */
+ msr = rdmsr(MSR_MISC_PWR_MGMT);
+ if (msr.lo & MISC_PWR_MGMT_EIST_HW_DIS)
+ coord_type = SW_ANY;
+ else
+ coord_type = HW_ALL;
+
+ /* Get bus ratio limits and calculate clock speeds */
+ msr = rdmsr(MSR_PLATFORM_INFO);
+ ratio_min = (msr.hi >> (40-32)) & 0xff; /* Max Efficiency Ratio */
+
+ /* Determine if this CPU has configurable TDP */
+ if (cpu_config_tdp_levels()) {
+ /* Set max ratio to nominal TDP ratio */
+ msr = rdmsr(MSR_CONFIG_TDP_NOMINAL);
+ ratio_max = msr.lo & 0xff;
+ } else {
+ /* Max Non-Turbo Ratio */
+ ratio_max = (msr.lo >> 8) & 0xff;
+ }
+ clock_max = ratio_max * CPU_BCLK;
+
+ /* Calculate CPU TDP in mW */
+ msr = rdmsr(MSR_PKG_POWER_SKU_UNIT);
+ power_unit = 2 << ((msr.lo & 0xf) - 1);
+ msr = rdmsr(MSR_PKG_POWER_SKU);
+ power_max = ((msr.lo & 0x7fff) / power_unit) * 1000;
+
+ /* Write _PCT indicating use of FFixedHW */
+ acpigen_write_empty_PCT();
+
+ /* Write _PPC with no limit on supported P-state */
+ acpigen_write_PPC_NVS();
+
+ /* Write PSD indicating configured coordination type */
+ acpigen_write_PSD_package(core, 1, coord_type);
+
+ /* Add P-state entries in _PSS table */
+ acpigen_write_name("_PSS");
+
+ /* Determine ratio points */
+ ratio_step = PSS_RATIO_STEP;
+ num_entries = ((ratio_max - ratio_min) / ratio_step) + 1;
+ if (num_entries > PSS_MAX_ENTRIES) {
+ ratio_step += 1;
+ num_entries = ((ratio_max - ratio_min) / ratio_step) + 1;
+ }
+
+ /* P[T] is Turbo state if enabled */
+ if (get_turbo_state() == TURBO_ENABLED) {
+ /* _PSS package count including Turbo */
+ acpigen_write_package(num_entries + 2);
+
+ msr = rdmsr(MSR_TURBO_RATIO_LIMIT);
+ ratio_turbo = msr.lo & 0xff;
+
+ /* Add entry for Turbo ratio */
+ acpigen_write_PSS_package(
+ clock_max + 1, /* MHz */
+ power_max, /* mW */
+ PSS_LATENCY_TRANSITION, /* lat1 */
+ PSS_LATENCY_BUSMASTER, /* lat2 */
+ ratio_turbo << 8, /* control */
+ ratio_turbo << 8); /* status */
+ } else {
+ /* _PSS package count without Turbo */
+ acpigen_write_package(num_entries + 1);
+ }
+
+ /* First regular entry is max non-turbo ratio */
+ acpigen_write_PSS_package(
+ clock_max, /* MHz */
+ power_max, /* mW */
+ PSS_LATENCY_TRANSITION, /* lat1 */
+ PSS_LATENCY_BUSMASTER, /* lat2 */
+ ratio_max << 8, /* control */
+ ratio_max << 8); /* status */
+
+ /* Generate the remaining entries */
+ for (ratio = ratio_min + ((num_entries - 1) * ratio_step);
+ ratio >= ratio_min; ratio -= ratio_step) {
+
+ /* Calculate power at this ratio */
+ power = calculate_power(power_max, ratio_max, ratio);
+ clock = ratio * CPU_BCLK;
+
+ acpigen_write_PSS_package(
+ clock, /* MHz */
+ power, /* mW */
+ PSS_LATENCY_TRANSITION, /* lat1 */
+ PSS_LATENCY_BUSMASTER, /* lat2 */
+ ratio << 8, /* control */
+ ratio << 8); /* status */
+ }
+
+ /* Fix package length */
+ acpigen_pop_len();
+}
+
+void generate_cpu_entries(device_t device)
+{
+ int core_id, cpu_id, pcontrol_blk = ACPI_BASE_ADDRESS, plen = 6;
+ int totalcores = dev_count_cpu();
+ int cores_per_package = get_cores_per_package();
+ int numcpus = totalcores/cores_per_package;
+ device_t dev = SA_DEV_ROOT;
+ config_t *config = dev->chip_info;
+ int is_s0ix_enable = config->s0ix_enable;
+ int max_c_state;
+
+ if (is_s0ix_enable)
+ max_c_state = ARRAY_SIZE(cstate_set_s0ix);
+ else
+ max_c_state = ARRAY_SIZE(cstate_set_non_s0ix);
+
+ printk(BIOS_DEBUG, "Found %d CPU(s) with %d core(s) each.\n",
+ numcpus, cores_per_package);
+
+ for (cpu_id = 0; cpu_id < numcpus; cpu_id++) {
+ for (core_id = 0; core_id < cores_per_package; core_id++) {
+ if (core_id > 0) {
+ pcontrol_blk = 0;
+ plen = 0;
+ }
+
+ /* Generate processor \_PR.CPUx */
+ acpigen_write_processor(
+ cpu_id*cores_per_package+core_id,
+ pcontrol_blk, plen);
+ /* Generate C-state tables */
+ generate_c_state_entries(is_s0ix_enable,
+ max_c_state);
+
+ /* Generate P-state tables */
+ generate_p_state_entries(core_id,
+ cores_per_package);
+
+ acpigen_pop_len();
+ }
+ }
+}
+
+unsigned long acpi_madt_irq_overrides(unsigned long current)
+{
+ int sci = acpi_sci_irq();
+ acpi_madt_irqoverride_t *irqovr;
+ uint16_t flags = MP_IRQ_TRIGGER_LEVEL;
+
+ /* INT_SRC_OVR */
+ irqovr = (void *)current;
+ current += acpi_create_madt_irqoverride(irqovr, 0, 0, 2, 0);
+
+ if (sci >= 20)
+ flags |= MP_IRQ_POLARITY_LOW;
+ else
+ flags |= MP_IRQ_POLARITY_HIGH;
+
+ /* SCI */
+ irqovr = (void *)current;
+ current += acpi_create_madt_irqoverride(irqovr, 0, sci, sci, flags);
+
+ return current;
+}
+
+unsigned long southcluster_write_acpi_tables(device_t device,
+ unsigned long current,
+ struct acpi_rsdp *rsdp)
+{
+ current = acpi_write_hpet(device, current, rsdp);
+ return acpi_align_current(current);
+}
+
+void southcluster_inject_dsdt(device_t device)
+{
+ global_nvs_t *gnvs;
+
+ gnvs = cbmem_find(CBMEM_ID_ACPI_GNVS);
+ if (!gnvs) {
+ gnvs = cbmem_add(CBMEM_ID_ACPI_GNVS, sizeof (*gnvs));
+ if (gnvs)
+ memset(gnvs, 0, sizeof(*gnvs));
+ }
+
+ if (gnvs) {
+ acpi_create_gnvs(gnvs);
+ acpi_mainboard_gnvs(gnvs);
+ acpi_save_gnvs((unsigned long)gnvs);
+ /* And tell SMI about it */
+ smm_setup_structures(gnvs, NULL, NULL);
+
+ /* Add it to DSDT. */
+ acpigen_write_scope("\\");
+ acpigen_write_name_dword("NVSA", (u32) gnvs);
+ acpigen_pop_len();
+ }
+}
+
+/* Save wake source information for calculating ACPI _SWS values */
+int soc_fill_acpi_wake(uint32_t *pm1, uint32_t **gpe0)
+{
+ struct chipset_power_state *ps;
+ static uint32_t gpe0_sts[GPE0_REG_MAX];
+ uint32_t pm1_en;
+ int i;
+
+ ps = cbmem_find(CBMEM_ID_POWER_STATE);
+ if (ps == NULL)
+ return -1;
+
+ /* PM1_EN state is lost in Deep S3 so enable basic wake events */
+ pm1_en = ps->pm1_en | PCIEXPWAK_STS | RTC_STS | PWRBTN_STS | BM_STS;
+ *pm1 = ps->pm1_sts & pm1_en;
+
+ /* Mask off GPE0 status bits that are not enabled */
+ *gpe0 = &gpe0_sts[0];
+ for (i = 0; i < GPE0_REG_MAX; i++)
+ gpe0_sts[i] = ps->gpe0_sts[i] & ps->gpe0_en[i];
+
+ return GPE0_REG_MAX;
+}
+
+__attribute__((weak)) void acpi_mainboard_gnvs(global_nvs_t *gnvs)
+{
+}
diff --git a/src/soc/intel/kabylake/acpi/cpu.asl b/src/soc/intel/kabylake/acpi/cpu.asl
new file mode 100644
index 0000000..a202ceb
--- /dev/null
+++ b/src/soc/intel/kabylake/acpi/cpu.asl
@@ -0,0 +1,118 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/* These devices are created at runtime */
+External (\_PR.CP00, DeviceObj)
+External (\_PR.CP01, DeviceObj)
+External (\_PR.CP02, DeviceObj)
+External (\_PR.CP03, DeviceObj)
+External (\_PR.CP04, DeviceObj)
+External (\_PR.CP05, DeviceObj)
+External (\_PR.CP06, DeviceObj)
+External (\_PR.CP07, DeviceObj)
+
+/* Notify OS to re-read CPU tables, assuming ^2 CPU count */
+Method (PNOT)
+{
+ If (LGreaterEqual (\PCNT, 2)) {
+ Notify (\_PR.CP00, 0x81) // _CST
+ Notify (\_PR.CP01, 0x81) // _CST
+ }
+ If (LGreaterEqual (\PCNT, 4)) {
+ Notify (\_PR.CP02, 0x81) // _CST
+ Notify (\_PR.CP03, 0x81) // _CST
+ }
+ If (LGreaterEqual (\PCNT, 8)) {
+ Notify (\_PR.CP04, 0x81) // _CST
+ Notify (\_PR.CP05, 0x81) // _CST
+ Notify (\_PR.CP06, 0x81) // _CST
+ Notify (\_PR.CP07, 0x81) // _CST
+ }
+}
+
+/* Notify OS to re-read CPU _PPC limit, assuming ^2 CPU count */
+Method (PPCN)
+{
+ If (LGreaterEqual (\PCNT, 2)) {
+ Notify (\_PR.CP00, 0x80) // _PPC
+ Notify (\_PR.CP01, 0x80) // _PPC
+ }
+ If (LGreaterEqual (\PCNT, 4)) {
+ Notify (\_PR.CP02, 0x80) // _PPC
+ Notify (\_PR.CP03, 0x80) // _PPC
+ }
+ If (LGreaterEqual (\PCNT, 8)) {
+ Notify (\_PR.CP04, 0x80) // _PPC
+ Notify (\_PR.CP05, 0x80) // _PPC
+ Notify (\_PR.CP06, 0x80) // _PPC
+ Notify (\_PR.CP07, 0x80) // _PPC
+ }
+}
+
+/* Notify OS to re-read Throttle Limit tables, assuming ^2 CPU count */
+Method (TNOT)
+{
+ If (LGreaterEqual (\PCNT, 2)) {
+ Notify (\_PR.CP00, 0x82) // _TPC
+ Notify (\_PR.CP01, 0x82) // _TPC
+ }
+ If (LGreaterEqual (\PCNT, 4)) {
+ Notify (\_PR.CP02, 0x82) // _TPC
+ Notify (\_PR.CP03, 0x82) // _TPC
+ }
+ If (LGreaterEqual (\PCNT, 8)) {
+ Notify (\_PR.CP04, 0x82) // _TPC
+ Notify (\_PR.CP05, 0x82) // _TPC
+ Notify (\_PR.CP06, 0x82) // _TPC
+ Notify (\_PR.CP07, 0x82) // _TPC
+ }
+}
+
+/* Return a package containing enabled processor entries */
+Method (PPKG)
+{
+ If (LGreaterEqual (\PCNT, 8)) {
+ Return (Package()
+ {
+ \_PR.CP00,
+ \_PR.CP01,
+ \_PR.CP02,
+ \_PR.CP03,
+ \_PR.CP04,
+ \_PR.CP05,
+ \_PR.CP06,
+ \_PR.CP07
+ })
+ } ElseIf (LGreaterEqual (\PCNT, 4)) {
+ Return (Package ()
+ {
+ \_PR.CP00,
+ \_PR.CP01,
+ \_PR.CP02,
+ \_PR.CP03
+ })
+ } ElseIf (LGreaterEqual (\PCNT, 2)) {
+ Return (Package ()
+ {
+ \_PR.CP00,
+ \_PR.CP01
+ })
+ } Else {
+ Return (Package ()
+ {
+ \_PR.CP00
+ })
+ }
+}
diff --git a/src/soc/intel/kabylake/acpi/dptf/charger.asl b/src/soc/intel/kabylake/acpi/dptf/charger.asl
new file mode 100644
index 0000000..4495d84
--- /dev/null
+++ b/src/soc/intel/kabylake/acpi/dptf/charger.asl
@@ -0,0 +1,75 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+Device (TCHG)
+{
+ Name (_HID, "INT3403")
+ Name (_UID, 0)
+ Name (PTYP, 0x0B)
+ Name (_STR, Unicode("Battery Charger"))
+
+ Method (_STA)
+ {
+ If (LEqual (\DPTE, One)) {
+ Return (0xF)
+ } Else {
+ Return (0x0)
+ }
+ }
+
+ /* Return charger performance states defined by mainboard */
+ Method (PPSS)
+ {
+ Return (\_SB.CHPS)
+ }
+
+ /* Return maximum charger current limit */
+ Method (PPPC)
+ {
+ /* Convert size of PPSS table to index */
+ Store (SizeOf (\_SB.CHPS), Local0)
+ Decrement (Local0)
+
+ /* Check if charging is disabled (AC removed) */
+ If (LEqual (\_SB.PCI0.LPCB.EC0.ACEX, Zero)) {
+ /* Return last power state */
+ Return (Local0)
+ } Else {
+ /* Return highest power state */
+ Return (0)
+ }
+
+ Return (0)
+ }
+
+ /* Set charger current limit */
+ Method (SPPC, 1)
+ {
+ /* Retrieve Control (index 4) for specified PPSS level */
+ Store (DeRefOf (Index (DeRefOf (Index
+ (\_SB.CHPS, ToInteger (Arg0))), 4)), Local0)
+
+ /* Pass Control value to EC to limit charging */
+ \_SB.PCI0.LPCB.EC0.CHGS (Local0)
+ }
+
+ /* Initialize charger participant */
+ Method (INIT)
+ {
+ /* Disable charge limit */
+ \_SB.PCI0.LPCB.EC0.CHGD ()
+ }
+}
diff --git a/src/soc/intel/kabylake/acpi/dptf/cpu.asl b/src/soc/intel/kabylake/acpi/dptf/cpu.asl
new file mode 100644
index 0000000..6ba666b
--- /dev/null
+++ b/src/soc/intel/kabylake/acpi/dptf/cpu.asl
@@ -0,0 +1,224 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef DPTF_CPU_PASSIVE
+#define DPTF_CPU_PASSIVE 80
+#endif
+
+#ifndef DPTF_CPU_CRITICAL
+#define DPTF_CPU_CRITICAL 90
+#endif
+
+#ifndef DPTF_CPU_ACTIVE_AC0
+#define DPTF_CPU_ACTIVE_AC0 90
+#endif
+
+#ifndef DPTF_CPU_ACTIVE_AC1
+#define DPTF_CPU_ACTIVE_AC1 80
+#endif
+
+#ifndef DPTF_CPU_ACTIVE_AC2
+#define DPTF_CPU_ACTIVE_AC2 70
+#endif
+
+#ifndef DPTF_CPU_ACTIVE_AC3
+#define DPTF_CPU_ACTIVE_AC3 60
+#endif
+
+#ifndef DPTF_CPU_ACTIVE_AC4
+#define DPTF_CPU_ACTIVE_AC4 50
+#endif
+
+External (\_PR.CP00._PSS, PkgObj)
+External (\_PR.CP00._TSS, PkgObj)
+External (\_PR.CP00._TPC, MethodObj)
+External (\_PR.CP00._PTC, PkgObj)
+External (\_PR.CP00._TSD, PkgObj)
+External (\_SB.MPDL, IntObj)
+
+Device (B0D4)
+{
+ Name(_ADR, 0x00040000) /* Bus 0, Device 4, Function 0 */
+
+ Method (_STA)
+ {
+ If (LEqual (\DPTE, One)) {
+ Return (0xF)
+ } Else {
+ Return (0x0)
+ }
+ }
+
+ /*
+ * Processor Throttling Controls
+ */
+
+ Method (_TSS)
+ {
+ If (CondRefOf (\_PR.CP00._TSS)) {
+ Return (\_PR.CP00._TSS)
+ } Else {
+ Return (Package ()
+ {
+ Package () { 0, 0, 0, 0, 0 }
+ })
+ }
+ }
+
+ Method (_TPC)
+ {
+ If (CondRefOf (\_PR.CP00._TPC)) {
+ Return (\_PR.CP00._TPC)
+ } Else {
+ Return (0)
+ }
+ }
+
+ Method (_PTC)
+ {
+ If (CondRefOf (\_PR.CP00._PTC)) {
+ Return (\_PR.CP00._PTC)
+ } Else {
+ Return (Package ()
+ {
+ Buffer () { 0 },
+ Buffer () { 0 }
+ })
+ }
+ }
+
+ Method (_TSD)
+ {
+ If (CondRefOf (\_PR.CP00._TSD)) {
+ Return (\_PR.CP00._TSD)
+ } Else {
+ Return (Package ()
+ {
+ Package () { 5, 0, 0, 0, 0 }
+ })
+ }
+ }
+
+ Method (_TDL)
+ {
+ If (CondRefOf (\_PR.CP00._TSS)) {
+ Store (SizeOf (\_PR.CP00._TSS), Local0)
+ Decrement (Local0)
+ Return (Local0)
+ } Else {
+ Return (0)
+ }
+ }
+
+ /*
+ * Processor Performance Control
+ */
+
+ Method (_PPC)
+ {
+ Return (0)
+ }
+
+ Method (SPPC, 1)
+ {
+ Store (Arg0, \PPCM)
+
+ /* Notify OS to re-read _PPC limit on each CPU */
+ \PPCN ()
+ }
+
+ Method (_PSS)
+ {
+ If (CondRefOf (\_PR.CP00._PSS)) {
+ Return (\_PR.CP00._PSS)
+ } Else {
+ Return (Package ()
+ {
+ Package () { 0, 0, 0, 0, 0, 0 }
+ })
+ }
+ }
+
+
+ Method (_PDL)
+ {
+ /* Check for mainboard specific _PDL override */
+ If (CondRefOf (\_SB.MPDL)) {
+ Return (\_SB.MPDL)
+ } ElseIf (CondRefOf (\_PR.CP00._PSS)) {
+ Store (SizeOf (\_PR.CP00._PSS), Local0)
+ Decrement (Local0)
+ Return (Local0)
+ } Else {
+ Return (0)
+ }
+ }
+
+ /* Return PPCC table defined by mainboard */
+ Method (PPCC)
+ {
+ Return (\_SB.MPPC)
+ }
+
+#ifdef DPTF_CPU_CRITICAL
+ Method (_CRT)
+ {
+ Return (\_SB.DPTF.CTOK (DPTF_CPU_CRITICAL))
+ }
+#endif
+
+#ifdef DPTF_CPU_PASSIVE
+ Method (_PSV)
+ {
+ Return (\_SB.DPTF.CTOK (DPTF_CPU_PASSIVE))
+ }
+#endif
+
+#ifdef DPTF_CPU_ACTIVE_AC0
+ Method (_AC0)
+ {
+ Return (\_SB.DPTF.CTOK (DPTF_CPU_ACTIVE_AC0))
+ }
+#endif
+
+#ifdef DPTF_CPU_ACTIVE_AC1
+ Method (_AC1)
+ {
+ Return (\_SB.DPTF.CTOK (DPTF_CPU_ACTIVE_AC1))
+ }
+#endif
+
+#ifdef DPTF_CPU_ACTIVE_AC2
+ Method (_AC2)
+ {
+ Return (\_SB.DPTF.CTOK (DPTF_CPU_ACTIVE_AC2))
+ }
+#endif
+
+#ifdef DPTF_CPU_ACTIVE_AC3
+ Method (_AC3)
+ {
+ Return (\_SB.DPTF.CTOK (DPTF_CPU_ACTIVE_AC3))
+ }
+#endif
+
+#ifdef DPTF_CPU_ACTIVE_AC4
+ Method (_AC4)
+ {
+ Return (\_SB.DPTF.CTOK (DPTF_CPU_ACTIVE_AC4))
+ }
+#endif
+}
diff --git a/src/soc/intel/kabylake/acpi/dptf/dptf.asl b/src/soc/intel/kabylake/acpi/dptf/dptf.asl
new file mode 100644
index 0000000..6c79d3c
--- /dev/null
+++ b/src/soc/intel/kabylake/acpi/dptf/dptf.asl
@@ -0,0 +1,116 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+Device (DPTF)
+{
+ Name (_HID, EISAID ("INT3400"))
+ Name (_UID, 0)
+
+ Name (IDSP, Package()
+ {
+ /* DPPM Passive Policy 1.0 */
+ ToUUID ("42A441D6-AE6A-462B-A84B-4A8CE79027D3"),
+
+ /* DPPM Critical Policy */
+ ToUUID ("97C68AE7-15FA-499c-B8C9-5DA81D606E0A"),
+
+ /* DPPM Cooling Policy */
+ ToUUID ("16CAF1B7-DD38-40ED-B1C1-1B8A1913D531"),
+
+#ifdef DPTF_ENABLE_FAN_CONTROL
+ /* DPPM Active Policy */
+ ToUUID ("3A95C389-E4B8-4629-A526-C52C88626BAE"),
+#endif
+ })
+
+ Method (_STA)
+ {
+ If (LEqual (\DPTE, One)) {
+ Return (0xF)
+ } Else {
+ Return (0x0)
+ }
+ }
+
+ /*
+ * Arg0: Buffer containing UUID
+ * Arg1: Integer containing Revision ID of buffer format
+ * Arg2: Integer containing count of entries in Arg3
+ * Arg3: Buffer containing list of DWORD capabilities
+ * Return: Buffer containing list of DWORD capabilities
+ */
+ Method (_OSC, 4, Serialized)
+ {
+ /* Check for Passive Policy UUID */
+ If (LEqual (DeRefOf (Index (IDSP, 0)), Arg0)) {
+ /* Initialize Thermal Devices */
+ ^TINI ()
+
+#ifdef DPTF_ENABLE_CHARGER
+ /* Initialize Charger Device */
+ ^TCHG.INIT ()
+#endif
+ }
+
+ Return (Arg3)
+ }
+
+ /* Priority based _TRT */
+ Name (TRTR, 1)
+
+ Method (_TRT)
+ {
+ Return (\_SB.DTRT)
+ }
+
+#ifdef DPTF_ENABLE_FAN_CONTROL
+ /* _ART : Active Cooling Relationship Table */
+ Method (_ART)
+ {
+ Return (\_SB.DART)
+ }
+#endif
+
+ /* Convert from Degrees C to 1/10 Kelvin for ACPI */
+ Method (CTOK, 1) {
+ /* 10th of Degrees C */
+ Multiply (Arg0, 10, Local0)
+
+ /* Convert to Kelvin */
+ Add (Local0, 2732, Local0)
+
+ Return (Local0)
+ }
+
+ /* Include Thermal Participants */
+ #include "thermal.asl"
+
+#ifdef DPTF_ENABLE_CHARGER
+ /* Include Charger Participant */
+ #include "charger.asl"
+#endif
+
+#ifdef DPTF_ENABLE_FAN_CONTROL
+ /* Include Fan Participant */
+ #include "fan.asl"
+#endif
+
+}
+
+Scope (\_SB.PCI0)
+{
+ #include "cpu.asl"
+}
diff --git a/src/soc/intel/kabylake/acpi/dptf/fan.asl b/src/soc/intel/kabylake/acpi/dptf/fan.asl
new file mode 100644
index 0000000..e3c88c3
--- /dev/null
+++ b/src/soc/intel/kabylake/acpi/dptf/fan.asl
@@ -0,0 +1,68 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+Device (TFN1)
+{
+ Name (_HID, "INT3404")
+ Name (_UID, 0)
+ Name (_STR, Unicode("Fan Control"))
+
+ /* _FIF: Fan Information */
+ Name (_FIF, Package ()
+ {
+ 0, // Revision
+ 1, // Fine Grained Control
+ 2, // Step Size
+ 0 // No Low Speed Notification
+ })
+
+ /* Return Fan Performance States defined by mainboard */
+ Method (_FPS)
+ {
+ Return (\_SB.DFPS)
+ }
+
+ Name (TFST, Package ()
+ {
+ 0, // Revision
+ 0x00, // Control
+ 0x00 // Speed
+ })
+
+ /* _FST: Fan current Status */
+ Method (_FST, 0, Serialized,,PkgObj)
+ {
+ /* Fill in TFST with current control. */
+ Store (\_SB.PCI0.LPCB.EC0.FAND, Index (TFST, 1))
+ Return (TFST)
+ }
+
+ /* _FSL: Fan Speed Level */
+ Method (_FSL, 1, Serialized)
+ {
+ Store (Arg0, \_SB.PCI0.LPCB.EC0.FAND)
+ Notify (DPTF, 0x83) // Re evaluate _ART
+ }
+
+ Method (_STA)
+ {
+ If (LEqual (\DPTE, One))
+ {
+ Return (0xF)
+ } Else {
+ Return (0x0)
+ }
+ }
+}
diff --git a/src/soc/intel/kabylake/acpi/dptf/thermal.asl b/src/soc/intel/kabylake/acpi/dptf/thermal.asl
new file mode 100644
index 0000000..67da119
--- /dev/null
+++ b/src/soc/intel/kabylake/acpi/dptf/thermal.asl
@@ -0,0 +1,283 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/* Thermal Threshold Event Handler */
+Method (TEVT, 1, NotSerialized)
+{
+ Store (ToInteger (Arg0), Local0)
+
+#ifdef DPTF_TSR0_SENSOR_ID
+ If (LEqual (Local0, DPTF_TSR0_SENSOR_ID)) {
+ Notify (^TSR0, 0x90)
+ }
+#endif
+#ifdef DPTF_TSR1_SENSOR_ID
+ If (LEqual (Local0, DPTF_TSR1_SENSOR_ID)) {
+ Notify (^TSR1, 0x90)
+ }
+#endif
+#ifdef DPTF_TSR2_SENSOR_ID
+ If (LEqual (Local0, DPTF_TSR2_SENSOR_ID)) {
+ Notify (^TSR2, 0x90)
+ }
+#endif
+#ifdef DPTF_TSR3_SENSOR_ID
+ If (LEqual (Local0, DPTF_TSR3_SENSOR_ID)) {
+ Notify (^TSR3, 0x90)
+ }
+#endif
+}
+
+/* Thermal device initialization - Disable Aux Trip Points */
+Method (TINI)
+{
+#ifdef DPTF_TSR0_SENSOR_ID
+ ^TSR0.PATD ()
+#endif
+#ifdef DPTF_TSR1_SENSOR_ID
+ ^TSR1.PATD ()
+#endif
+#ifdef DPTF_TSR2_SENSOR_ID
+ ^TSR2.PATD ()
+#endif
+#ifdef DPTF_TSR3_SENSOR_ID
+ ^TSR3.PATD ()
+#endif
+}
+
+#ifdef DPTF_TSR0_SENSOR_ID
+Device (TSR0)
+{
+ Name (_HID, EISAID ("INT3403"))
+ Name (_UID, 1)
+ Name (PTYP, 0x03)
+ Name (TMPI, DPTF_TSR0_SENSOR_ID)
+ Name (_STR, Unicode (DPTF_TSR0_SENSOR_NAME))
+ Name (GTSH, 20) /* 2 degree hysteresis */
+
+ Method (_STA)
+ {
+ If (LEqual (\DPTE, One)) {
+ Return (0xF)
+ } Else {
+ Return (0x0)
+ }
+ }
+
+ Method (_TMP, 0, Serialized)
+ {
+ Return (\_SB.PCI0.LPCB.EC0.TSRD (TMPI))
+ }
+
+ Method (_PSV)
+ {
+ Return (CTOK (DPTF_TSR0_PASSIVE))
+ }
+
+ Method (_CRT)
+ {
+ Return (CTOK (DPTF_TSR0_CRITICAL))
+ }
+
+ Name (PATC, 2)
+
+ /* Set Aux Trip Point */
+ Method (PAT0, 1, Serialized)
+ {
+ \_SB.PCI0.LPCB.EC0.PAT0 (TMPI, Arg0)
+ }
+
+ /* Set Aux Trip Point */
+ Method (PAT1, 1, Serialized)
+ {
+ \_SB.PCI0.LPCB.EC0.PAT1 (TMPI, Arg0)
+ }
+
+ /* Disable Aux Trip Point */
+ Method (PATD, 0, Serialized)
+ {
+ \_SB.PCI0.LPCB.EC0.PATD (TMPI)
+ }
+}
+#endif
+
+#ifdef DPTF_TSR1_SENSOR_ID
+Device (TSR1)
+{
+ Name (_HID, EISAID ("INT3403"))
+ Name (_UID, 2)
+ Name (PTYP, 0x03)
+ Name (TMPI, DPTF_TSR1_SENSOR_ID)
+ Name (_STR, Unicode (DPTF_TSR1_SENSOR_NAME))
+ Name (GTSH, 20) /* 2 degree hysteresis */
+
+ Method (_STA)
+ {
+ If (LEqual (\DPTE, One)) {
+ Return (0xF)
+ } Else {
+ Return (0x0)
+ }
+ }
+
+ Method (_TMP, 0, Serialized)
+ {
+ Return (\_SB.PCI0.LPCB.EC0.TSRD (TMPI))
+ }
+
+ Method (_PSV)
+ {
+ Return (CTOK (DPTF_TSR1_PASSIVE))
+ }
+
+ Method (_CRT)
+ {
+ Return (CTOK (DPTF_TSR1_CRITICAL))
+ }
+
+ Name (PATC, 2)
+
+ /* Set Aux Trip Point */
+ Method (PAT0, 1, Serialized)
+ {
+ \_SB.PCI0.LPCB.EC0.PAT0 (TMPI, Arg0)
+ }
+
+ /* Set Aux Trip Point */
+ Method (PAT1, 1, Serialized)
+ {
+ \_SB.PCI0.LPCB.EC0.PAT1 (TMPI, Arg0)
+ }
+
+ /* Disable Aux Trip Point */
+ Method (PATD, 0, Serialized)
+ {
+ \_SB.PCI0.LPCB.EC0.PATD (TMPI)
+ }
+}
+#endif
+
+#ifdef DPTF_TSR2_SENSOR_ID
+Device (TSR2)
+{
+ Name (_HID, EISAID ("INT3403"))
+ Name (_UID, 3)
+ Name (PTYP, 0x03)
+ Name (TMPI, DPTF_TSR2_SENSOR_ID)
+ Name (_STR, Unicode (DPTF_TSR2_SENSOR_NAME))
+ Name (GTSH, 20) /* 2 degree hysteresis */
+
+ Method (_STA)
+ {
+ If (LEqual (\DPTE, One)) {
+ Return (0xF)
+ } Else {
+ Return (0x0)
+ }
+ }
+
+ Method (_TMP, 0, Serialized)
+ {
+ Return (\_SB.PCI0.LPCB.EC0.TSRD (TMPI))
+ }
+
+ Method (_PSV)
+ {
+ Return (CTOK (DPTF_TSR2_PASSIVE))
+ }
+
+ Method (_CRT)
+ {
+ Return (CTOK (DPTF_TSR2_CRITICAL))
+ }
+
+ Name (PATC, 2)
+
+ /* Set Aux Trip Point */
+ Method (PAT0, 1, Serialized)
+ {
+ \_SB.PCI0.LPCB.EC0.PAT0 (TMPI, Arg0)
+ }
+
+ /* Set Aux Trip Point */
+ Method (PAT1, 1, Serialized)
+ {
+ \_SB.PCI0.LPCB.EC0.PAT1 (TMPI, Arg0)
+ }
+
+ /* Disable Aux Trip Point */
+ Method (PATD, 0, Serialized)
+ {
+ \_SB.PCI0.LPCB.EC0.PATD (TMPI)
+ }
+}
+#endif
+
+#ifdef DPTF_TSR3_SENSOR_ID
+Device (TSR3)
+{
+ Name (_HID, EISAID ("INT3403"))
+ Name (_UID, 4)
+ Name (PTYP, 0x03)
+ Name (TMPI, DPTF_TSR3_SENSOR_ID)
+ Name (_STR, Unicode (DPTF_TSR3_SENSOR_NAME))
+ Name (GTSH, 20) /* 2 degree hysteresis */
+
+ Method (_STA)
+ {
+ If (LEqual (\DPTE, One)) {
+ Return (0xF)
+ } Else {
+ Return (0x0)
+ }
+ }
+
+ Method (_TMP, 0, Serialized)
+ {
+ Return (\_SB.PCI0.LPCB.EC0.TSRD (TMPI))
+ }
+
+ Method (_PSV)
+ {
+ Return (CTOK (DPTF_TSR3_PASSIVE))
+ }
+
+ Method (_CRT)
+ {
+ Return (CTOK (DPTF_TSR3_CRITICAL))
+ }
+
+ Name (PATC, 2)
+
+ /* Set Aux Trip Point */
+ Method (PAT0, 1, Serialized)
+ {
+ \_SB.PCI0.LPCB.EC0.PAT0 (TMPI, Arg0)
+ }
+
+ /* Set Aux Trip Point */
+ Method (PAT1, 1, Serialized)
+ {
+ \_SB.PCI0.LPCB.EC0.PAT1 (TMPI, Arg0)
+ }
+
+ /* Disable Aux Trip Point */
+ Method (PATD, 0, Serialized)
+ {
+ \_SB.PCI0.LPCB.EC0.PATD (TMPI)
+ }
+}
+#endif
diff --git a/src/soc/intel/kabylake/acpi/globalnvs.asl b/src/soc/intel/kabylake/acpi/globalnvs.asl
new file mode 100644
index 0000000..373674e
--- /dev/null
+++ b/src/soc/intel/kabylake/acpi/globalnvs.asl
@@ -0,0 +1,95 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/* Global Variables */
+
+Name (\PICM, 0) // IOAPIC/8259
+
+/*
+ * Global ACPI memory region. This region is used for passing information
+ * between coreboot (aka "the system bios"), ACPI, and the SMI handler.
+ * Since we don't know where this will end up in memory at ACPI compile time,
+ * we have to fix it up in coreboot's ACPI creation phase.
+ */
+
+External (NVSA)
+
+OperationRegion (GNVS, SystemMemory, NVSA, 0x2000)
+Field (GNVS, ByteAcc, NoLock, Preserve)
+{
+ /* Miscellaneous */
+ Offset (0x00),
+ OSYS, 16, // 0x00 - Operating System
+ SMIF, 8, // 0x02 - SMI function
+ PRM0, 8, // 0x03 - SMI function parameter
+ PRM1, 8, // 0x04 - SMI function parameter
+ SCIF, 8, // 0x05 - SCI function
+ PRM2, 8, // 0x06 - SCI function parameter
+ PRM3, 8, // 0x07 - SCI function parameter
+ LCKF, 8, // 0x08 - Global Lock function for EC
+ PRM4, 8, // 0x09 - Lock function parameter
+ PRM5, 8, // 0x0a - Lock function parameter
+ PCNT, 8, // 0x0b - Processor Count
+ PPCM, 8, // 0x0c - Max PPC State
+ TMPS, 8, // 0x0d - Temperature Sensor ID
+ TLVL, 8, // 0x0e - Throttle Level Limit
+ FLVL, 8, // 0x0f - Current FAN Level
+ TCRT, 8, // 0x10 - Critical Threshold
+ TPSV, 8, // 0x11 - Passive Threshold
+ TMAX, 8, // 0x12 - CPU Tj_max
+ S5U0, 8, // 0x13 - Enable USB in S5
+ S3U0, 8, // 0x14 - Enable USB in S3
+ S33G, 8, // 0x15 - Enable 3G in S3
+ LIDS, 8, // 0x16 - LID State
+ PWRS, 8, // 0x17 - AC Power State
+ CMEM, 32, // 0x18 - 0x1b - CBMEM TOC
+ CBMC, 32, // 0x1c - 0x1f - Coreboot Memory Console
+ PM1I, 64, // 0x20 - 0x27 - PM1 wake status bit
+ GPEI, 64, // 0x28 - 0x2f - GPE wake status bit
+ DPTE, 8, // 0x30 - Enable DPTF
+ NHLA, 64, // 0x31 - NHLT Address
+ NHLL, 32, // 0x39 - NHLT Length
+ CID1, 16, // 0x3d - Wifi Country Identifier
+
+ /* ChromeOS specific */
+ Offset (0x100),
+ #include <vendorcode/google/chromeos/acpi/gnvs.asl>
+}
+
+/* Set flag to enable USB charging in S3 */
+Method (S3UE)
+{
+ Store (One, \S3U0)
+}
+
+/* Set flag to disable USB charging in S3 */
+Method (S3UD)
+{
+ Store (Zero, \S3U0)
+}
+
+/* Set flag to enable USB charging in S5 */
+Method (S5UE)
+{
+ Store (One, \S5U0)
+}
+
+/* Set flag to disable USB charging in S5 */
+Method (S5UD)
+{
+ Store (Zero, \S5U0)
+}
diff --git a/src/soc/intel/kabylake/acpi/gpio.asl b/src/soc/intel/kabylake/acpi/gpio.asl
new file mode 100644
index 0000000..789957c
--- /dev/null
+++ b/src/soc/intel/kabylake/acpi/gpio.asl
@@ -0,0 +1,115 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#include <soc/gpio_defs.h>
+
+Device (GPIO)
+{
+ Name (_HID, "INT344B")
+ Name (_UID, 1)
+ Name (_DDN, "GPIO Controller")
+
+ Name (RBUF, ResourceTemplate()
+ {
+ Memory32Fixed (ReadWrite, 0, 0, COM0)
+ Memory32Fixed (ReadWrite, 0, 0, COM1)
+ Memory32Fixed (ReadWrite, 0, 0, COM3)
+ Interrupt (ResourceConsumer, Level, ActiveLow, Shared,,, GIRQ)
+ { 0 }
+ })
+
+ Method (_CRS, 0, NotSerialized)
+ {
+ /* GPIO Community 0 */
+ CreateDWordField (^RBUF, ^COM0._BAS, BAS0)
+ CreateDWordField (^RBUF, ^COM0._LEN, LEN0)
+ Store (^^PCRB (PID_GPIOCOM0), BAS0)
+ Store (GPIO_BASE_SIZE, LEN0)
+
+ /* GPIO Community 1 */
+ CreateDWordField (^RBUF, ^COM1._BAS, BAS1)
+ CreateDWordField (^RBUF, ^COM1._LEN, LEN1)
+ Store (^^PCRB (PID_GPIOCOM1), BAS1)
+ Store (GPIO_BASE_SIZE, LEN1)
+
+ /* GPIO Community 3 */
+ CreateDWordField (^RBUF, ^COM3._BAS, BAS3)
+ CreateDWordField (^RBUF, ^COM3._LEN, LEN3)
+ Store (^^PCRB (PID_GPIOCOM3), BAS3)
+ Store (GPIO_BASE_SIZE, LEN3)
+
+ CreateDWordField (^RBUF, ^GIRQ._INT, IRQN)
+ And (^^PCRR (PID_GPIOCOM0, MISCCFG_OFFSET),
+ GPIO_DRIVER_IRQ_ROUTE_MASK, Local0)
+
+ If (LEqual (Local0, GPIO_DRIVER_IRQ_ROUTE_IRQ14)) {
+ Store (GPIO_IRQ14, IRQN)
+ } Else {
+ Store (GPIO_IRQ15, IRQN)
+ }
+
+ Return (RBUF)
+ }
+
+ Method (_STA, 0, NotSerialized)
+ {
+ Return (0xF)
+ }
+}
+
+/*
+ * Get GPIO DW0 Address
+ * Arg0 - GPIO Number
+ */
+Method (GADD, 1, NotSerialized)
+{
+ /* GPIO Community 0 */
+ If (LAnd (LGreaterEqual (Arg0, GPP_A0), LLessEqual (Arg0, GPP_B23)))
+ {
+ Store (PID_GPIOCOM0, Local0)
+ Subtract (Arg0, GPP_A0, Local1)
+ }
+ /* GPIO Community 1 */
+ If (LAnd (LGreaterEqual (Arg0, GPP_C0), LLessEqual (Arg0, GPP_E23)))
+ {
+ Store (PID_GPIOCOM1, Local0)
+ Subtract (Arg0, GPP_C0, Local1)
+ }
+ /* GPIO Community 03*/
+ If (LAnd (LGreaterEqual (Arg0, GPP_F0), LLessEqual (Arg0, GPP_G7)))
+ {
+ Store (PID_GPIOCOM3, Local0)
+ Subtract (Arg0, GPP_F0, Local1)
+ }
+ Store (PCRB (Local0), Local2)
+ Add (Local2, PAD_CFG_DW_OFFSET, Local2)
+ Return (Add (Local2, Multiply (Local1, 8)))
+}
+
+/*
+ * Get GPIO Value
+ * Arg0 - GPIO Number
+ */
+Method (GRXS, 1, Serialized)
+{
+ OperationRegion (PREG, SystemMemory, GADD (Arg0), 4)
+ Field (PREG, AnyAcc, NoLock, Preserve)
+ {
+ VAL0, 32
+ }
+ And (GPIORXSTATE_MASK, ShiftRight (VAL0, GPIORXSTATE_SHIFT), Local0)
+
+ Return (Local0)
+}
diff --git a/src/soc/intel/kabylake/acpi/irqlinks.asl b/src/soc/intel/kabylake/acpi/irqlinks.asl
new file mode 100644
index 0000000..f9d68e7
--- /dev/null
+++ b/src/soc/intel/kabylake/acpi/irqlinks.asl
@@ -0,0 +1,436 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/*
+ * PIRQ routing control is in PCR ITSS region.
+ *
+ * Due to what appears to be an ACPI interpreter bug we do not use
+ * the PCRB() method here as it may not be defined yet because the method
+ * definiton depends on the order of the include files in pch.asl.
+ *
+ * https://bugs.acpica.org/show_bug.cgi?id=1201
+ */
+OperationRegion (ITSS, SystemMemory,
+ Add (R_PCH_PCR_ITSS_PIRQA_ROUT,
+ Add (PCH_PCR_BASE_ADDRESS,
+ ShiftLeft (PID_ITSS, PCR_PORTID_SHIFT))), 8)
+Field (ITSS, ByteAcc, NoLock, Preserve)
+{
+ PIRA, 8, /* PIRQA Routing Control */
+ PIRB, 8, /* PIRQB Routing Control */
+ PIRC, 8, /* PIRQC Routing Control */
+ PIRD, 8, /* PIRQD Routing Control */
+ PIRE, 8, /* PIRQE Routing Control */
+ PIRF, 8, /* PIRQF Routing Control */
+ PIRG, 8, /* PIRQG Routing Control */
+ PIRH, 8, /* PIRQH Routing Control */
+}
+
+Name (IREN, 0x80) /* Interrupt Routing Enable */
+Name (IREM, 0x0f) /* Interrupt Routing Mask */
+
+Device (LNKA)
+{
+ Name (_HID, EISAID ("PNP0C0F"))
+ Name (_UID, 1)
+
+ Name (_PRS, ResourceTemplate ()
+ {
+ IRQ (Level, ActiveLow, Shared)
+ { 3, 4, 5, 6, 10, 12, 14, 15 }
+ })
+
+ Method (_CRS, 0, Serialized)
+ {
+ Name (RTLA, ResourceTemplate ()
+ {
+ IRQ (Level, ActiveLow, Shared) {}
+ })
+ CreateWordField (RTLA, 1, IRQ0)
+ Store (Zero, IRQ0)
+
+ /* Set the bit from PIRQ Routing Register */
+ ShiftLeft (1, And (^^PIRA, ^^IREM), IRQ0)
+
+ Return (RTLA)
+ }
+
+ Method (_SRS, 1, Serialized)
+ {
+ CreateWordField (Arg0, 1, IRQ0)
+ FindSetRightBit (IRQ0, Local0)
+ Decrement (Local0)
+ Store (Local0, ^^PIRA)
+ }
+
+ Method (_STA, 0, Serialized)
+ {
+ If (And (^^PIRA, ^^IREN)) {
+ Return (0x9)
+ } Else {
+ Return (0xb)
+ }
+ }
+
+ Method (_DIS, 0, Serialized)
+ {
+ Or (^^PIRA, ^^IREN, ^^PIRA)
+ }
+}
+
+Device (LNKB)
+{
+ Name (_HID, EISAID ("PNP0C0F"))
+ Name (_UID, 2)
+
+ Name (_PRS, ResourceTemplate ()
+ {
+ IRQ (Level, ActiveLow, Shared)
+ { 3, 4, 5, 6, 10, 12, 14, 15 }
+ })
+
+ Method (_CRS, 0, Serialized)
+ {
+ Name (RTLA, ResourceTemplate ()
+ {
+ IRQ (Level, ActiveLow, Shared) {}
+ })
+ CreateWordField (RTLA, 1, IRQ0)
+ Store (Zero, IRQ0)
+
+ /* Set the bit from PIRQ Routing Register */
+ ShiftLeft (1, And (^^PIRB, ^^IREM), IRQ0)
+
+ Return (RTLA)
+ }
+
+ Method (_SRS, 1, Serialized)
+ {
+ CreateWordField (Arg0, 1, IRQ0)
+ FindSetRightBit (IRQ0, Local0)
+ Decrement (Local0)
+ Store (Local0, ^^PIRB)
+ }
+
+ Method (_STA, 0, Serialized)
+ {
+ If (And (^^PIRB, ^^IREN)) {
+ Return (0x9)
+ } Else {
+ Return (0xb)
+ }
+ }
+
+ Method (_DIS, 0, Serialized)
+ {
+ Or (^^PIRB, ^^IREN, ^^PIRB)
+ }
+}
+
+Device (LNKC)
+{
+ Name (_HID, EISAID ("PNP0C0F"))
+ Name (_UID, 3)
+
+ Name (_PRS, ResourceTemplate ()
+ {
+ IRQ (Level, ActiveLow, Shared)
+ { 3, 4, 5, 6, 10, 12, 14, 15 }
+ })
+
+ Method (_CRS, 0, Serialized)
+ {
+ Name (RTLA, ResourceTemplate ()
+ {
+ IRQ (Level, ActiveLow, Shared) {}
+ })
+ CreateWordField (RTLA, 1, IRQ0)
+ Store (Zero, IRQ0)
+
+ /* Set the bit from PIRQ Routing Register */
+ ShiftLeft (1, And (^^PIRC, ^^IREM), IRQ0)
+
+ Return (RTLA)
+ }
+
+ Method (_SRS, 1, Serialized)
+ {
+ CreateWordField (Arg0, 1, IRQ0)
+ FindSetRightBit (IRQ0, Local0)
+ Decrement (Local0)
+ Store (Local0, ^^PIRC)
+ }
+
+ Method (_STA, 0, Serialized)
+ {
+ If (And (^^PIRC, ^^IREN)) {
+ Return (0x9)
+ } Else {
+ Return (0xb)
+ }
+ }
+
+ Method (_DIS, 0, Serialized)
+ {
+ Or (^^PIRC, ^^IREN, ^^PIRC)
+ }
+}
+
+Device (LNKD)
+{
+ Name (_HID, EISAID ("PNP0C0F"))
+ Name (_UID, 4)
+
+ Name (_PRS, ResourceTemplate ()
+ {
+ IRQ (Level, ActiveLow, Shared)
+ { 3, 4, 5, 6, 10, 12, 14, 15 }
+ })
+
+ Method (_CRS, 0, Serialized)
+ {
+ Name (RTLA, ResourceTemplate ()
+ {
+ IRQ (Level, ActiveLow, Shared) {}
+ })
+ CreateWordField (RTLA, 1, IRQ0)
+ Store (Zero, IRQ0)
+
+ /* Set the bit from PIRQ Routing Register */
+ ShiftLeft (1, And (^^PIRD, ^^IREM), IRQ0)
+
+ Return (RTLA)
+ }
+
+ Method (_SRS, 1, Serialized)
+ {
+ CreateWordField (Arg0, 1, IRQ0)
+ FindSetRightBit (IRQ0, Local0)
+ Decrement (Local0)
+ Store (Local0, ^^PIRD)
+ }
+
+ Method (_STA, 0, Serialized)
+ {
+ If (And (^^PIRD, ^^IREN)) {
+ Return (0x9)
+ } Else {
+ Return (0xb)
+ }
+ }
+
+ Method (_DIS, 0, Serialized)
+ {
+ Or (^^PIRD, ^^IREN, ^^PIRD)
+ }
+}
+
+Device (LNKE)
+{
+ Name (_HID, EISAID ("PNP0C0F"))
+ Name (_UID, 5)
+
+ Name (_PRS, ResourceTemplate ()
+ {
+ IRQ (Level, ActiveLow, Shared)
+ { 3, 4, 5, 6, 10, 12, 14, 15 }
+ })
+
+ Method (_CRS, 0, Serialized)
+ {
+ Name (RTLA, ResourceTemplate ()
+ {
+ IRQ (Level, ActiveLow, Shared) {}
+ })
+ CreateWordField (RTLA, 1, IRQ0)
+ Store (Zero, IRQ0)
+
+ /* Set the bit from PIRQ Routing Register */
+ ShiftLeft (1, And (^^PIRE, ^^IREM), IRQ0)
+
+ Return (RTLA)
+ }
+
+ Method (_SRS, 1, Serialized)
+ {
+ CreateWordField (Arg0, 1, IRQ0)
+ FindSetRightBit (IRQ0, Local0)
+ Decrement (Local0)
+ Store (Local0, ^^PIRE)
+ }
+
+ Method (_STA, 0, Serialized)
+ {
+ If (And (^^PIRE, ^^IREN)) {
+ Return (0x9)
+ } Else {
+ Return (0xb)
+ }
+ }
+
+ Method (_DIS, 0, Serialized)
+ {
+ Or (^^PIRE, ^^IREN, ^^PIRE)
+ }
+}
+
+Device (LNKF)
+{
+ Name (_HID, EISAID ("PNP0C0F"))
+ Name (_UID, 6)
+
+ Name (_PRS, ResourceTemplate ()
+ {
+ IRQ (Level, ActiveLow, Shared)
+ { 3, 4, 5, 6, 10, 12, 14, 15 }
+ })
+
+ Method (_CRS, 0, Serialized)
+ {
+ Name (RTLA, ResourceTemplate ()
+ {
+ IRQ (Level, ActiveLow, Shared) {}
+ })
+ CreateWordField (RTLA, 1, IRQ0)
+ Store (Zero, IRQ0)
+
+ /* Set the bit from PIRQ Routing Register */
+ ShiftLeft (1, And (^^PIRF, ^^IREM), IRQ0)
+
+ Return (RTLA)
+ }
+
+ Method (_SRS, 1, Serialized)
+ {
+ CreateWordField (Arg0, 1, IRQ0)
+ FindSetRightBit (IRQ0, Local0)
+ Decrement (Local0)
+ Store (Local0, ^^PIRF)
+ }
+
+ Method (_STA, 0, Serialized)
+ {
+ If (And (^^PIRF, ^^IREN)) {
+ Return (0x9)
+ } Else {
+ Return (0xb)
+ }
+ }
+
+ Method (_DIS, 0, Serialized)
+ {
+ Or (^^PIRF, ^^IREN, ^^PIRF)
+ }
+}
+
+Device (LNKG)
+{
+ Name (_HID, EISAID ("PNP0C0F"))
+ Name (_UID, 7)
+
+ Name (_PRS, ResourceTemplate ()
+ {
+ IRQ (Level, ActiveLow, Shared)
+ { 3, 4, 5, 6, 10, 12, 14, 15 }
+ })
+
+ Method (_CRS, 0, Serialized)
+ {
+ Name (RTLA, ResourceTemplate ()
+ {
+ IRQ (Level, ActiveLow, Shared) {}
+ })
+ CreateWordField (RTLA, 1, IRQ0)
+ Store (Zero, IRQ0)
+
+ /* Set the bit from PIRQ Routing Register */
+ ShiftLeft (1, And (^^PIRG, ^^IREM), IRQ0)
+
+ Return (RTLA)
+ }
+
+ Method (_SRS, 1, Serialized)
+ {
+ CreateWordField (Arg0, 1, IRQ0)
+ FindSetRightBit (IRQ0, Local0)
+ Decrement (Local0)
+ Store (Local0, ^^PIRG)
+ }
+
+ Method (_STA, 0, Serialized)
+ {
+ If (And (^^PIRG, ^^IREN)) {
+ Return (0x9)
+ } Else {
+ Return (0xb)
+ }
+ }
+
+ Method (_DIS, 0, Serialized)
+ {
+ Or (^^PIRG, ^^IREN, ^^PIRG)
+ }
+}
+
+Device (LNKH)
+{
+ Name (_HID, EISAID ("PNP0C0F"))
+ Name (_UID, 1)
+
+ Name (_PRS, ResourceTemplate ()
+ {
+ IRQ (Level, ActiveLow, Shared)
+ { 3, 4, 5, 6, 10, 12, 14, 15 }
+ })
+
+ Method (_CRS, 0, Serialized)
+ {
+ Name (RTLA, ResourceTemplate ()
+ {
+ IRQ (Level, ActiveLow, Shared) {}
+ })
+ CreateWordField (RTLA, 1, IRQ0)
+ Store (Zero, IRQ0)
+
+ /* Set the bit from PIRQ Routing Register */
+ ShiftLeft (1, And (^^PIRH, ^^IREM), IRQ0)
+
+ Return (RTLA)
+ }
+
+ Method (_SRS, 1, Serialized)
+ {
+ CreateWordField (Arg0, 1, IRQ0)
+ FindSetRightBit (IRQ0, Local0)
+ Decrement (Local0)
+ Store (Local0, ^^PIRH)
+ }
+
+ Method (_STA, 0, Serialized)
+ {
+ If (And (^^PIRH, ^^IREN)) {
+ Return (0x9)
+ } Else {
+ Return (0xb)
+ }
+ }
+
+ Method (_DIS, 0, Serialized)
+ {
+ Or (^^PIRH, ^^IREN, ^^PIRH)
+ }
+}
diff --git a/src/soc/intel/kabylake/acpi/lpc.asl b/src/soc/intel/kabylake/acpi/lpc.asl
new file mode 100644
index 0000000..0bc6fae
--- /dev/null
+++ b/src/soc/intel/kabylake/acpi/lpc.asl
@@ -0,0 +1,144 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+Device (LPCB)
+{
+ Name (_ADR, 0x001f0000)
+ Name (_DDN, "LPC Bus Device")
+
+ Device (DMAC)
+ {
+ Name (_HID, EISAID ("PNP0200"))
+ Name (_DDN, "DMA Controller")
+ Name (_CRS, ResourceTemplate ()
+ {
+ IO (Decode16, 0x00, 0x00, 0x01, 0x20)
+ IO (Decode16, 0x81, 0x81, 0x01, 0x11)
+ IO (Decode16, 0x93, 0x93, 0x01, 0x0d)
+ IO (Decode16, 0xc0, 0xc0, 0x01, 0x20)
+ DMA (Compatibility, NotBusMaster, Transfer8_16) { 4 }
+ })
+ }
+
+ Device (FWH)
+ {
+ Name (_HID, EISAID ("INT0800"))
+ Name (_DDN, "Firmware Hub")
+ Name (_CRS, ResourceTemplate ()
+ {
+ Memory32Fixed (ReadOnly, 0xff000000, 0x01000000)
+ })
+ }
+
+ Device (HPET)
+ {
+ Name (_HID, EISAID ("PNP0103"))
+ Name (_DDN, "High Precision Event Timer")
+ Name (_CRS, ResourceTemplate ()
+ {
+ Memory32Fixed (ReadWrite, HPET_BASE_ADDRESS, 0x400)
+ })
+ Method (_STA, 0)
+ {
+ Return (0xf)
+ }
+ }
+
+ Device (PIC)
+ {
+ Name (_HID, EISAID ("PNP0000"))
+ Name (_DDN, "8259 Interrupt Controller")
+ Name (_CRS, ResourceTemplate()
+ {
+ IO (Decode16, 0x20, 0x20, 0x01, 0x02)
+ IO (Decode16, 0x24, 0x24, 0x01, 0x02)
+ IO (Decode16, 0x28, 0x28, 0x01, 0x02)
+ IO (Decode16, 0x2c, 0x2c, 0x01, 0x02)
+ IO (Decode16, 0x30, 0x30, 0x01, 0x02)
+ IO (Decode16, 0x34, 0x34, 0x01, 0x02)
+ IO (Decode16, 0x38, 0x38, 0x01, 0x02)
+ IO (Decode16, 0x3c, 0x3c, 0x01, 0x02)
+ IO (Decode16, 0xa0, 0xa0, 0x01, 0x02)
+ IO (Decode16, 0xa4, 0xa4, 0x01, 0x02)
+ IO (Decode16, 0xa8, 0xa8, 0x01, 0x02)
+ IO (Decode16, 0xac, 0xac, 0x01, 0x02)
+ IO (Decode16, 0xb0, 0xb0, 0x01, 0x02)
+ IO (Decode16, 0xb4, 0xb4, 0x01, 0x02)
+ IO (Decode16, 0xb8, 0xb8, 0x01, 0x02)
+ IO (Decode16, 0xbc, 0xbc, 0x01, 0x02)
+ IO (Decode16, 0x4d0, 0x4d0, 0x01, 0x02)
+ IRQNoFlags () { 2 }
+ })
+ }
+
+ Device (MATH)
+ {
+ Name (_HID, EISAID ("PNP0C04"))
+ Name (_DDN, "Floating Point Unit")
+ Name (_CRS, ResourceTemplate ()
+ {
+ IO (Decode16, 0xf0, 0xf0, 0x01, 0x01)
+ IRQNoFlags () { 13 }
+ })
+ }
+
+ Device (LDRC)
+ {
+ Name (_HID, EISAID ("PNP0C02"))
+ Name (_UID, 2)
+ Name (_DDN, "Legacy Device Resources")
+ Name (_CRS, ResourceTemplate ()
+ {
+ IO (Decode16, 0x2e, 0x2e, 0x1, 0x02) // First SuperIO
+ IO (Decode16, 0x4e, 0x4e, 0x1, 0x02) // Second SuperIO
+ IO (Decode16, 0x61, 0x61, 0x1, 0x01) // NMI Status
+ IO (Decode16, 0x63, 0x63, 0x1, 0x01) // CPU Reserved
+ IO (Decode16, 0x65, 0x65, 0x1, 0x01) // CPU Reserved
+ IO (Decode16, 0x67, 0x67, 0x1, 0x01) // CPU Reserved
+ IO (Decode16, 0x80, 0x80, 0x1, 0x01) // Port 80 Post
+ IO (Decode16, 0x92, 0x92, 0x1, 0x01) // CPU Reserved
+ IO (Decode16, 0xb2, 0xb2, 0x1, 0x02) // SWSMI
+ IO (Decode16, ACPI_BASE_ADDRESS, ACPI_BASE_ADDRESS,
+ 0x1, 0xff)
+ })
+ }
+
+ Device (RTC)
+ {
+ Name (_HID, EISAID ("PNP0B00"))
+ Name (_DDN, "Real Time Clock")
+ Name (_CRS, ResourceTemplate ()
+ {
+ IO (Decode16, 0x70, 0x70, 1, 8)
+ })
+ }
+
+ Device (TIMR)
+ {
+ Name (_HID, EISAID ("PNP0100"))
+ Name (_DDN, "8254 Timer")
+ Name (_CRS, ResourceTemplate ()
+ {
+ IO (Decode16, 0x40, 0x40, 0x01, 0x04)
+ IO (Decode16, 0x50, 0x50, 0x10, 0x04)
+ IRQNoFlags () {0}
+ })
+ }
+
+ #include <acpi/ec.asl>
+ #include <acpi/superio.asl>
+}
diff --git a/src/soc/intel/kabylake/acpi/pch.asl b/src/soc/intel/kabylake/acpi/pch.asl
new file mode 100644
index 0000000..6277c27
--- /dev/null
+++ b/src/soc/intel/kabylake/acpi/pch.asl
@@ -0,0 +1,72 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ * Copyright (C) 2015 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <soc/iomap.h>
+#include <soc/irq.h>
+#include <soc/gpio_defs.h>
+#include <soc/gpe.h>
+#include <soc/pcr.h>
+
+/* GPIO Controller */
+#include "gpio.asl"
+
+/* Interrupt Routing */
+#include "irqlinks.asl"
+
+/* LPC 0:1f.0 */
+#include "lpc.asl"
+
+/* PCH HDA */
+#include "pch_hda.asl"
+
+/* PCIE Ports */
+#include "pcie.asl"
+
+/* PCR Access */
+#include "pcr.asl"
+
+/* PMC 0:1f.2 */
+#include "pmc.asl"
+
+/* Serial IO */
+#include "serialio.asl"
+
+/* SMBus 0:1f.3 */
+#include "smbus.asl"
+
+/* Storage Controllers */
+#include "scs.asl"
+
+/* USB XHCI 0:14.0 */
+#include "xhci.asl"
+
+Method (_OSC, 4)
+{
+ /* Check for proper GUID */
+ If (LEqual (Arg0, ToUUID ("33DB4D5B-1FF7-401C-9657-7441C03DD766")))
+ {
+ /* Let OS control everything */
+ Return (Arg3)
+ }
+ Else
+ {
+ /* Unrecognized UUID */
+ CreateDWordField (Arg3, 0, CDW1)
+ Or (CDW1, 4, CDW1)
+ Return (Arg3)
+ }
+}
diff --git a/src/soc/intel/kabylake/acpi/pch_hda.asl b/src/soc/intel/kabylake/acpi/pch_hda.asl
new file mode 100644
index 0000000..86d5894
--- /dev/null
+++ b/src/soc/intel/kabylake/acpi/pch_hda.asl
@@ -0,0 +1,84 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015-2016 Intel Corporation.
+ * Copyright (C) 2015 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/* Audio Controller - Device 31, Function 3 */
+
+Device (HDAS)
+{
+ Name (_ADR, 0x001F0003)
+ Name (_DDN, "Audio Controller")
+ Name (UUID, ToUUID ("A69F886E-6CEB-4594-A41F-7B5DCE24C553"))
+
+ /* Device is D3 wake capable */
+ Name (_S0W, 3)
+
+ /* NHLT Table Address populated from GNVS values */
+ Name (NBUF, ResourceTemplate () {
+ QWordMemory (ResourceConsumer, PosDecode, MinFixed,
+ MaxFixed, NonCacheable, ReadOnly,
+ 0, 0, 0, 0, 1,,, NHLT, AddressRangeACPI)
+ })
+
+ /*
+ * Device Specific Method
+ * Arg0 - UUID
+ * Arg1 - Revision
+ * Arg2 - Function Index
+ */
+ Method (_DSM, 4)
+ {
+ If (LEqual (Arg0, ^UUID)) {
+ /*
+ * Function 0: Function Support Query
+ * Returns a bitmask of functions supported.
+ */
+ If (LEqual (Arg2, Zero)) {
+ /*
+ * NHLT Query only supported for revision 1 and
+ * if NHLT address and length are set in NVS.
+ */
+ If (LAnd (LEqual (Arg1, One),
+ LAnd (LNotEqual (NHLA, Zero),
+ LNotEqual (NHLL, Zero)))) {
+ Return (Buffer (One) { 0x03 })
+ } Else {
+ Return (Buffer (One) { 0x01 })
+ }
+ }
+
+ /*
+ * Function 1: Query NHLT memory address used by
+ * Intel Offload Engine Driver to discover any non-HDA
+ * devices that are supported by the DSP.
+ *
+ * Returns a pointer to NHLT table in memory.
+ */
+ If (LEqual (Arg2, One)) {
+ CreateQWordField (NBUF, ^NHLT._MIN, NBAS)
+ CreateQWordField (NBUF, ^NHLT._MAX, NMAS)
+ CreateQWordField (NBUF, ^NHLT._LEN, NLEN)
+
+ Store (NHLA, NBAS)
+ Store (NHLA, NMAS)
+ Store (NHLL, NLEN)
+
+ Return (NBUF)
+ }
+ }
+
+ Return (Buffer (One) { 0x00 })
+ }
+}
diff --git a/src/soc/intel/kabylake/acpi/pci_irqs.asl b/src/soc/intel/kabylake/acpi/pci_irqs.asl
new file mode 100644
index 0000000..ec31fb2
--- /dev/null
+++ b/src/soc/intel/kabylake/acpi/pci_irqs.asl
@@ -0,0 +1,133 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <soc/interrupt.h>
+#include <soc/irq.h>
+
+Name (PICP, Package () {
+ /* D31: cAVS, SMBus, GbE, Nothpeak */
+ Package () { 0x001FFFFF, 0, 0, cAVS_INTA_IRQ },
+ Package () { 0x001FFFFF, 1, 0, SMBUS_INTB_IRQ },
+ Package () { 0x001FFFFF, 2, 0, GbE_INTC_IRQ },
+ Package () { 0x001FFFFF, 3, 0, TRACE_HUB_INTD_IRQ },
+ /* D30: SerialIo and SCS */
+ Package () { 0x001EFFFF, 0, 0, LPSS_UART0_IRQ },
+ Package () { 0x001EFFFF, 1, 0, eMMC_IRQ },
+ Package () { 0x001EFFFF, 2, 0, SDIO_IRQ },
+ Package () { 0x001EFFFF, 3, 0, SD_IRQ },
+ /* D29: PCI Express Port 9-16 */
+ Package () { 0x001DFFFF, 0, 0, PCIE_9_IRQ },
+ Package () { 0x001DFFFF, 1, 0, PCIE_10_IRQ },
+ Package () { 0x001DFFFF, 2, 0, PCIE_11_IRQ },
+ Package () { 0x001DFFFF, 3, 0, PCIE_12_IRQ },
+ /* D28: PCI Express Port 1-8 */
+ Package () { 0x001CFFFF, 0, 0, PCIE_1_IRQ },
+ Package () { 0x001CFFFF, 1, 0, PCIE_2_IRQ },
+ Package () { 0x001CFFFF, 2, 0, PCIE_3_IRQ },
+ Package () { 0x001CFFFF, 3, 0, PCIE_4_IRQ },
+ /* D25: SerialIo */
+ Package () { 0x0019FFFF, 0, 0, LPSS_UART2_IRQ },
+ Package () { 0x0019FFFF, 1, 0, LPSS_I2C5_IRQ },
+ Package () { 0x0019FFFF, 2, 0, LPSS_I2C4_IRQ },
+ /* D22: CSME (HECI, IDE-R, KT redirection */
+ Package () { 0x0016FFFF, 0, 0, HECI_1_IRQ },
+ Package () { 0x0016FFFF, 1, 0, HECI_2_IRQ },
+ Package () { 0x0016FFFF, 2, 0, IDER_IRQ },
+ Package () { 0x0016FFFF, 3, 0, KT_IRQ },
+ /* D21: SerialIo */
+ Package () { 0x0015FFFF, 0, 0, LPSS_I2C0_IRQ },
+ Package () { 0x0015FFFF, 1, 0, LPSS_I2C1_IRQ },
+ Package () { 0x0015FFFF, 2, 0, LPSS_I2C2_IRQ },
+ Package () { 0x0015FFFF, 3, 0, LPSS_I2C3_IRQ },
+ /* D20: xHCI, OTG, Thermal, Camera */
+ Package () { 0x0014FFFF, 0, 0, XHCI_IRQ },
+ Package () { 0x0014FFFF, 1, 0, OTG_IRQ },
+ Package () { 0x0014FFFF, 2, 0, THRMAL_IRQ },
+ Package () { 0x0014FFFF, 3, 0, CIO_INTD_IRQ },
+ /* D19: Integrated Sensor Hub */
+ Package () { 0x0013FFFF, 0, 0, ISH_IRQ },
+ /* P.E.G. Root Port D1F0 */
+ Package () { 0x0001FFFF, 0, 0, PEG_RP_INTA_IRQ },
+ Package () { 0x0001FFFF, 1, 0, PEG_RP_INTB_IRQ },
+ Package () { 0x0001FFFF, 2, 0, PEG_RP_INTC_IRQ },
+ Package () { 0x0001FFFF, 3, 0, PEG_RP_INTD_IRQ },
+ /* SA IGFX Device */
+ Package () { 0x0002FFFF, 0, 0, IGFX_IRQ },
+ /* SA Thermal Device */
+ Package () { 0x0004FFFF, 0, 0, SA_THERMAL_IRQ },
+ /* SA SkyCam Device */
+ Package () { 0x0005FFFF, 0, 0, SKYCAM_IRQ },
+ /* SA GMM Device */
+ Package () { 0x0008FFFF, 0, 0, GMM_IRQ },
+})
+
+Name (PICN, Package () {
+ /* D31: cAVS, SMBus, GbE, Nothpeak */
+ Package () { 0x001FFFFF, 0, \_SB.PCI0.LNKA, 0 },
+ Package () { 0x001FFFFF, 1, \_SB.PCI0.LNKB, 0 },
+ Package () { 0x001FFFFF, 2, \_SB.PCI0.LNKC, 0 },
+ Package () { 0x001FFFFF, 3, \_SB.PCI0.LNKD, 0 },
+ /* D29: PCI Express Port 9-16 */
+ Package () { 0x001DFFFF, 0, \_SB.PCI0.LNKA, 0 },
+ Package () { 0x001DFFFF, 1, \_SB.PCI0.LNKB, 0 },
+ Package () { 0x001DFFFF, 2, \_SB.PCI0.LNKC, 0 },
+ Package () { 0x001DFFFF, 3, \_SB.PCI0.LNKD, 0 },
+ /* D28: PCI Express Port 1-8 */
+ Package () { 0x001CFFFF, 0, \_SB.PCI0.LNKA, 0 },
+ Package () { 0x001CFFFF, 1, \_SB.PCI0.LNKB, 0 },
+ Package () { 0x001CFFFF, 2, \_SB.PCI0.LNKC, 0 },
+ Package () { 0x001CFFFF, 3, \_SB.PCI0.LNKD, 0 },
+ /* D27: PCI Express Port 17-20 */
+ Package () { 0x001BFFFF, 0, \_SB.PCI0.LNKA, 0 },
+ Package () { 0x001BFFFF, 1, \_SB.PCI0.LNKB, 0 },
+ Package () { 0x001BFFFF, 2, \_SB.PCI0.LNKC, 0 },
+ Package () { 0x001BFFFF, 3, \_SB.PCI0.LNKD, 0 },
+ /* D23 */
+ Package () { 0x0017FFFF, 0, \_SB.PCI0.LNKA, 0 },
+ /* D22: CSME (HECI, IDE-R, KT redirection */
+ Package () { 0x0016FFFF, 0, \_SB.PCI0.LNKA, 0 },
+ Package () { 0x0016FFFF, 1, \_SB.PCI0.LNKB, 0 },
+ Package () { 0x0016FFFF, 2, \_SB.PCI0.LNKC, 0 },
+ Package () { 0x0016FFFF, 3, \_SB.PCI0.LNKD, 0 },
+ /* D20: xHCI, OTG, Thermal, Camera */
+ Package () { 0x0014FFFF, 0, \_SB.PCI0.LNKA, 0 },
+ Package () { 0x0014FFFF, 1, \_SB.PCI0.LNKB, 0 },
+ Package () { 0x0014FFFF, 2, \_SB.PCI0.LNKC, 0 },
+ Package () { 0x0014FFFF, 3, \_SB.PCI0.LNKD, 0 },
+ /* P.E.G. Root Port D1F0 */
+ Package () { 0x0001FFFF, 0, \_SB.PCI0.LNKA, 0 },
+ Package () { 0x0001FFFF, 1, \_SB.PCI0.LNKB, 0 },
+ Package () { 0x0001FFFF, 2, \_SB.PCI0.LNKC, 0 },
+ Package () { 0x0001FFFF, 3, \_SB.PCI0.LNKD, 0 },
+ /* SA IGFX Device */
+ Package () { 0x0002FFFF, 0, \_SB.PCI0.LNKA, 0 },
+ /* SA Thermal Device */
+ Package () { 0x0004FFFF, 0, \_SB.PCI0.LNKA, 0 },
+ /* SA Skycam Device */
+ Package () { 0x0005FFFF, 0, \_SB.PCI0.LNKA, 0 },
+ /* SA GMM Device */
+ Package () { 0x0008FFFF, 0, \_SB.PCI0.LNKA, 0 },
+})
+
+Method (_PRT)
+{
+ If (PICM) {
+ Return (^PICP)
+ } Else {
+ Return (^PICN)
+ }
+}
diff --git a/src/soc/intel/kabylake/acpi/pcie.asl b/src/soc/intel/kabylake/acpi/pcie.asl
new file mode 100644
index 0000000..71a27d7
--- /dev/null
+++ b/src/soc/intel/kabylake/acpi/pcie.asl
@@ -0,0 +1,316 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/* Intel PCH PCIe support */
+
+Method (IRQM, 1, Serialized) {
+
+ /* Interrupt Map INTA->INTA, INTB->INTB, INTC->INTC, INTD->INTD */
+ Name (IQAA, Package () {
+ Package () { 0x0000ffff, 0, 0, 16 },
+ Package () { 0x0000ffff, 1, 0, 17 },
+ Package () { 0x0000ffff, 2, 0, 18 },
+ Package () { 0x0000ffff, 3, 0, 19 } })
+ Name (IQAP, Package () {
+ Package () { 0x0000ffff, 0, \_SB.PCI0.LNKA, 0 },
+ Package () { 0x0000ffff, 1, \_SB.PCI0.LNKB, 0 },
+ Package () { 0x0000ffff, 2, \_SB.PCI0.LNKC, 0 },
+ Package () { 0x0000ffff, 3, \_SB.PCI0.LNKD, 0 } })
+
+ /* Interrupt Map INTA->INTB, INTB->INTC, INTC->INTD, INTD->INTA */
+ Name (IQBA, Package () {
+ Package () { 0x0000ffff, 0, 0, 17 },
+ Package () { 0x0000ffff, 1, 0, 18 },
+ Package () { 0x0000ffff, 2, 0, 19 },
+ Package () { 0x0000ffff, 3, 0, 16 } })
+ Name (IQBP, Package () {
+ Package () { 0x0000ffff, 0, \_SB.PCI0.LNKB, 0 },
+ Package () { 0x0000ffff, 1, \_SB.PCI0.LNKC, 0 },
+ Package () { 0x0000ffff, 2, \_SB.PCI0.LNKD, 0 },
+ Package () { 0x0000ffff, 3, \_SB.PCI0.LNKA, 0 } })
+
+ /* Interrupt Map INTA->INTC, INTB->INTD, INTC->INTA, INTD->INTB */
+ Name (IQCA, Package () {
+ Package () { 0x0000ffff, 0, 0, 18 },
+ Package () { 0x0000ffff, 1, 0, 19 },
+ Package () { 0x0000ffff, 2, 0, 16 },
+ Package () { 0x0000ffff, 3, 0, 17 } })
+ Name (IQCP, Package () {
+ Package () { 0x0000ffff, 0, \_SB.PCI0.LNKC, 0 },
+ Package () { 0x0000ffff, 1, \_SB.PCI0.LNKD, 0 },
+ Package () { 0x0000ffff, 2, \_SB.PCI0.LNKA, 0 },
+ Package () { 0x0000ffff, 3, \_SB.PCI0.LNKB, 0 } })
+
+ /* Interrupt Map INTA->INTD, INTB->INTA, INTC->INTB, INTD->INTC */
+ Name (IQDA, Package () {
+ Package () { 0x0000ffff, 0, 0, 19 },
+ Package () { 0x0000ffff, 1, 0, 16 },
+ Package () { 0x0000ffff, 2, 0, 17 },
+ Package () { 0x0000ffff, 3, 0, 18 } })
+ Name (IQDP, Package () {
+ Package () { 0x0000ffff, 0, \_SB.PCI0.LNKD, 0 },
+ Package () { 0x0000ffff, 1, \_SB.PCI0.LNKA, 0 },
+ Package () { 0x0000ffff, 2, \_SB.PCI0.LNKB, 0 },
+ Package () { 0x0000ffff, 3, \_SB.PCI0.LNKC, 0 } })
+
+ Switch (ToInteger (Arg0))
+ {
+ Case (Package () { 1, 5, 9 }) {
+ If (PICM) {
+ Return (IQAA)
+ } Else {
+ Return (IQAP)
+ }
+ }
+
+ Case (Package () { 2, 6, 10 }) {
+ If (PICM) {
+ Return (IQBA)
+ } Else {
+ Return (IQBP)
+ }
+ }
+
+ Case (Package () { 3, 7, 11 }) {
+ If (PICM) {
+ Return (IQCA)
+ } Else {
+ Return (IQCP)
+ }
+ }
+
+ Case (Package () { 4, 8, 12 }) {
+ If (PICM) {
+ Return (IQDA)
+ } Else {
+ Return (IQDP)
+ }
+ }
+
+ Default {
+ If (PICM) {
+ Return (IQDA)
+ } Else {
+ Return (IQDP)
+ }
+ }
+ }
+}
+
+Device (RP01)
+{
+ Name (_ADR, 0x001C0000)
+
+ OperationRegion (RPCS, PCI_Config, 0x4c, 4)
+ Field (RPCS, AnyAcc, NoLock, Preserve)
+ {
+ , 24,
+ RPPN, 8, /* Root Port Number */
+ }
+
+ Method (_PRT)
+ {
+ Return (IRQM (RPPN))
+ }
+}
+
+Device (RP02)
+{
+ Name (_ADR, 0x001C0001)
+
+ OperationRegion (RPCS, PCI_Config, 0x4c, 4)
+ Field (RPCS, AnyAcc, NoLock, Preserve)
+ {
+ , 24,
+ RPPN, 8, /* Root Port Number */
+ }
+
+ Method (_PRT)
+ {
+ Return (IRQM (RPPN))
+ }
+}
+
+Device (RP03)
+{
+ Name (_ADR, 0x001C0002)
+
+ OperationRegion (RPCS, PCI_Config, 0x4c, 4)
+ Field (RPCS, AnyAcc, NoLock, Preserve)
+ {
+ , 24,
+ RPPN, 8, /* Root Port Number */
+ }
+
+ Method (_PRT)
+ {
+ Return (IRQM (RPPN))
+ }
+}
+
+Device (RP04)
+{
+ Name (_ADR, 0x001C0003)
+
+ OperationRegion (RPCS, PCI_Config, 0x4c, 4)
+ Field (RPCS, AnyAcc, NoLock, Preserve)
+ {
+ , 24,
+ RPPN, 8, /* Root Port Number */
+ }
+
+ Method (_PRT)
+ {
+ Return (IRQM (RPPN))
+ }
+}
+
+Device (RP05)
+{
+ Name (_ADR, 0x001C0004)
+
+ OperationRegion (RPCS, PCI_Config, 0x4c, 4)
+ Field (RPCS, AnyAcc, NoLock, Preserve)
+ {
+ , 24,
+ RPPN, 8, /* Root Port Number */
+ }
+
+ Method (_PRT)
+ {
+ Return (IRQM (RPPN))
+ }
+}
+
+Device (RP06)
+{
+ Name (_ADR, 0x001C0005)
+
+ OperationRegion (RPCS, PCI_Config, 0x4c, 4)
+ Field (RPCS, AnyAcc, NoLock, Preserve)
+ {
+ , 24,
+ RPPN, 8, /* Root Port Number */
+ }
+
+ Method (_PRT)
+ {
+ Return (IRQM (RPPN))
+ }
+}
+
+Device (RP07)
+{
+ Name (_ADR, 0x001C0006)
+
+ OperationRegion (RPCS, PCI_Config, 0x4c, 4)
+ Field (RPCS, AnyAcc, NoLock, Preserve)
+ {
+ , 24,
+ RPPN, 8, /* Root Port Number */
+ }
+
+ Method (_PRT)
+ {
+ Return (IRQM (RPPN))
+ }
+}
+
+Device (RP08)
+{
+ Name (_ADR, 0x001C0007)
+
+ OperationRegion (RPCS, PCI_Config, 0x4c, 4)
+ Field (RPCS, AnyAcc, NoLock, Preserve)
+ {
+ , 24,
+ RPPN, 8, /* Root Port Number */
+ }
+
+ Method (_PRT)
+ {
+ Return (IRQM (RPPN))
+ }
+}
+
+Device (RP09)
+{
+ Name (_ADR, 0x001D0000)
+
+ OperationRegion (RPCS, PCI_Config, 0x4c, 4)
+ Field (RPCS, AnyAcc, NoLock, Preserve)
+ {
+ , 24,
+ RPPN, 8, /* Root Port Number */
+ }
+
+ Method (_PRT)
+ {
+ Return (IRQM (RPPN))
+ }
+}
+
+Device (RP10)
+{
+ Name (_ADR, 0x001D0001)
+
+ OperationRegion (RPCS, PCI_Config, 0x4c, 4)
+ Field (RPCS, AnyAcc, NoLock, Preserve)
+ {
+ , 24,
+ RPPN, 8, /* Root Port Number */
+ }
+
+ Method (_PRT)
+ {
+ Return (IRQM (RPPN))
+ }
+}
+
+Device (RP11)
+{
+ Name (_ADR, 0x001D0002)
+
+ OperationRegion (RPCS, PCI_Config, 0x4c, 4)
+ Field (RPCS, AnyAcc, NoLock, Preserve)
+ {
+ , 24,
+ RPPN, 8, /* Root Port Number */
+ }
+
+ Method (_PRT)
+ {
+ Return (IRQM (RPPN))
+ }
+}
+
+Device (RP12)
+{
+ Name (_ADR, 0x001D0003)
+
+ OperationRegion (RPCS, PCI_Config, 0x4c, 4)
+ Field (RPCS, AnyAcc, NoLock, Preserve)
+ {
+ , 24,
+ RPPN, 8, /* Root Port Number */
+ }
+
+ Method (_PRT)
+ {
+ Return (IRQM (RPPN))
+ }
+}
diff --git a/src/soc/intel/kabylake/acpi/pcr.asl b/src/soc/intel/kabylake/acpi/pcr.asl
new file mode 100644
index 0000000..38ea4d2
--- /dev/null
+++ b/src/soc/intel/kabylake/acpi/pcr.asl
@@ -0,0 +1,71 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/*
+ * Calculate PCR register base at specified PID
+ * Arg0 - PCR Port ID
+ */
+Method (PCRB, 1, NotSerialized)
+{
+ Return (Add (PCH_PCR_BASE_ADDRESS, ShiftLeft (Arg0, PCR_PORTID_SHIFT)))
+}
+
+/*
+ * Read a PCR register at specified PID and offset
+ * Arg0 - PCR Port ID
+ * Arg1 - Register Offset
+ */
+Method (PCRR, 2, Serialized)
+{
+ OperationRegion (PCRD, SystemMemory, Add (PCRB (Arg0), Arg1), 4)
+ Field (PCRD, DWordAcc, NoLock, Preserve)
+ {
+ DATA, 32
+ }
+ Return (DATA)
+}
+
+/*
+ * AND a value with PCR register at specified PID and offset
+ * Arg0 - PCR Port ID
+ * Arg1 - Register Offset
+ * Arg2 - Value to AND
+ */
+Method (PCRA, 3, Serialized)
+{
+ OperationRegion (PCRD, SystemMemory, Add (PCRB (Arg0), Arg1), 4)
+ Field (PCRD, DWordAcc, NoLock, Preserve)
+ {
+ DATA, 32
+ }
+ And (DATA, Arg2, DATA)
+}
+
+/*
+ * OR a value with PCR register at specified PID and offset
+ * Arg0 - PCR Port ID
+ * Arg1 - Register Offset
+ * Arg2 - Value to OR
+ */
+Method (PCRO, 3, Serialized)
+{
+ OperationRegion (PCRD, SystemMemory, Add (PCRB (Arg0), Arg1), 4)
+ Field (PCRD, DWordAcc, NoLock, Preserve)
+ {
+ DATA, 32
+ }
+ Or (DATA, Arg2, DATA)
+}
diff --git a/src/soc/intel/kabylake/acpi/platform.asl b/src/soc/intel/kabylake/acpi/platform.asl
new file mode 100644
index 0000000..2f62709
--- /dev/null
+++ b/src/soc/intel/kabylake/acpi/platform.asl
@@ -0,0 +1,84 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/* Enable ACPI _SWS methods */
+#include <soc/intel/common/acpi/acpi_wake_source.asl>
+
+/* The APM port can be used for generating software SMIs */
+
+OperationRegion (APMP, SystemIO, 0xb2, 2)
+Field (APMP, ByteAcc, NoLock, Preserve)
+{
+ APMC, 8, // APM command
+ APMS, 8 // APM status
+}
+
+/* Port 80 POST */
+
+OperationRegion (POST, SystemIO, 0x80, 1)
+Field (POST, ByteAcc, Lock, Preserve)
+{
+ DBG0, 8
+}
+
+/* IO-Trap at 0x800.
+ * This is the ACPI->SMI communication interface.
+ */
+OperationRegion (IO_T, SystemIO, 0x800, 0x10)
+Field (IO_T, ByteAcc, NoLock, Preserve)
+{
+ Offset (0x8),
+ TRP0, 8 /* IO-Trap at 0x808 */
+}
+
+/* SMI I/O Trap */
+Method (TRAP, 1, Serialized)
+{
+ Store (Arg0, SMIF) // SMI Function
+ Store (0, TRP0) // Generate trap
+ Return (SMIF) // Return value of SMI handler
+}
+
+/*
+ * The _PIC method is called by the OS to choose between interrupt
+ * routing via the i8259 interrupt controller or the APIC.
+ *
+ * _PIC is called with a parameter of 0 for i8259 configuration and
+ * with a parameter of 1 for Local Apic/IOAPIC configuration.
+ */
+
+Method (_PIC, 1)
+{
+ /* Remember the OS' IRQ routing choice. */
+ Store (Arg0, PICM)
+}
+
+/*
+ * The _PTS method (Prepare To Sleep) is called before the OS is
+ * entering a sleep state. The sleep state number is passed in Arg0
+ */
+
+Method (_PTS, 1)
+{
+}
+
+/* The _WAK method is called on system wakeup */
+
+Method (_WAK, 1)
+{
+ Return (Package (){ 0, 0 })
+}
diff --git a/src/soc/intel/kabylake/acpi/pmc.asl b/src/soc/intel/kabylake/acpi/pmc.asl
new file mode 100644
index 0000000..d097082
--- /dev/null
+++ b/src/soc/intel/kabylake/acpi/pmc.asl
@@ -0,0 +1,41 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+Device (PMC)
+{
+ Name (_ADR, 0x001f0002)
+ Name (_DDN, "Power Management Controller")
+
+ OperationRegion (PMCP, PCI_Config, 0x00, 0x100)
+ Field (PMCP, AnyAcc, NoLock, Preserve)
+ {
+ Offset (0x48),
+ , 12,
+ PWRM, 20, /* PWRMBASE */
+ }
+
+ OperationRegion (PMCM, SystemMemory, ShiftLeft (PWRM, 12), 0x3f)
+ Field (PMCM, DWordAcc, NoLock, Preserve)
+ {
+ Offset (0x1c), /* PCH_PM_STS */
+ , 24,
+ PMFS, 1, /* PMC_MSG_FULL_STS */
+ Offset (0x20),
+ MPMC, 32, /* MTPMC */
+ Offset (0x24), /* PCH_PM_STS2 */
+ , 20,
+ UWAB, 1, /* USB2 Workaround Available */
+ }
+}
diff --git a/src/soc/intel/kabylake/acpi/scs.asl b/src/soc/intel/kabylake/acpi/scs.asl
new file mode 100644
index 0000000..c0b8046
--- /dev/null
+++ b/src/soc/intel/kabylake/acpi/scs.asl
@@ -0,0 +1,127 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/* Intel Storage Controllers */
+
+Device (EMMC)
+{
+ Name (_ADR, 0x001E0004)
+ Name (_DDN, "eMMC Controller")
+
+ OperationRegion (EMCR, PCI_Config, 0x00, 0x100)
+ Field (EMCR, DWordAcc, NoLock, Preserve)
+ {
+ Offset (0x84), /* PMECTRLSTATUS */
+ D0D3, 2, /* POWERSTATE */
+ Offset (0xa2), /* PG_CONFIG */
+ , 2,
+ PGEN, 1, /* PG_ENABLE */
+ }
+
+ Method (_PS0, 0, Serialized)
+ {
+ /* Disable Power Gate */
+ Store (0, ^PGEN)
+
+ /* Clear bits 31, 6, 2, 0 */
+ ^^PCRA (PID_SCS, 0x600, 0x7FFFFFBA)
+ Sleep (2)
+
+ /* Set bits 31, 6, 2, 0 */
+ ^^PCRO (PID_SCS, 0x600, 0x80000045)
+
+ /* Set Power State to D0 */
+ Store (Zero, Local0)
+ Store (Local0, ^D0D3)
+ Store (^D0D3, Local0)
+ }
+
+ Method (_PS3, 0, Serialized)
+ {
+ /* Enable Power Gate */
+ Store (1, ^PGEN)
+
+ /* Set Power State to D0 */
+ Store (3, Local0)
+ Store (Local0, ^D0D3)
+ Store (^D0D3, Local0)
+ }
+
+ Device (CARD)
+ {
+ Name (_ADR, 0x00000008)
+ Method (_RMV, 0, NotSerialized)
+ {
+ Return (0)
+ }
+ }
+}
+
+#if !IS_ENABLED(CONFIG_EXCLUDE_NATIVE_SD_INTERFACE)
+Device (SDXC)
+{
+ Name (_ADR, 0x001E0006)
+ Name (_DDN, "SD Controller")
+
+ OperationRegion (SDCR, PCI_Config, 0x00, 0x100)
+ Field (SDCR, DWordAcc, NoLock, Preserve)
+ {
+ Offset (0x84), /* PMECTRLSTATUS */
+ D0D3, 2, /* POWERSTATE */
+ Offset (0xa2), /* PG_CONFIG */
+ , 2,
+ PGEN, 1, /* PG_ENABLE */
+ }
+
+ Method (_PS0, 0, Serialized)
+ {
+ /* Disable Power Gate */
+ Store (0, ^PGEN)
+
+ /* Clear bits 8, 7, 2, 0 */
+ ^^PCRA (PID_SCS, 0x600, 0xFFFFFE7A)
+ Sleep (2)
+
+ /* Set bits 31, 6, 2, 0 */
+ ^^PCRO (PID_SCS, 0x600, 0x00000185)
+
+ /* Set Power State to D0 */
+ Store (Zero, Local0)
+ Store (Local0, ^D0D3)
+ Store (^D0D3, Local0)
+ }
+
+ Method (_PS3, 0, Serialized)
+ {
+ /* Enable Power Gate */
+ Store (1, ^PGEN)
+
+ /* Set Power State to D0 */
+ Store (3, Local0)
+ Store (Local0, ^D0D3)
+ Store (^D0D3, Local0)
+ }
+
+ Device (CARD)
+ {
+ Name (_ADR, 0x00000008)
+ Method (_RMV, 0, NotSerialized)
+ {
+ Return (1)
+ }
+ }
+}
+#endif
\ No newline at end of file
diff --git a/src/soc/intel/kabylake/acpi/serialio.asl b/src/soc/intel/kabylake/acpi/serialio.asl
new file mode 100644
index 0000000..9e7b24c
--- /dev/null
+++ b/src/soc/intel/kabylake/acpi/serialio.asl
@@ -0,0 +1,83 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/* Intel Serial IO Devices */
+
+Device (I2C0)
+{
+ Name (_ADR, 0x00150000)
+ Name (_DDN, "Serial IO I2C Controller 0")
+}
+
+Device (I2C1)
+{
+ Name (_ADR, 0x00150001)
+ Name (_DDN, "Serial IO I2C Controller 1")
+}
+
+Device (I2C2)
+{
+ Name (_ADR, 0x00150002)
+ Name (_DDN, "Serial IO I2C Controller 2")
+}
+
+Device (I2C3)
+{
+ Name (_ADR, 0x00150003)
+ Name (_DDN, "Serial IO I2C Controller 3")
+}
+
+Device (I2C4)
+{
+ Name (_ADR, 0x00190002)
+ Name (_DDN, "Serial IO I2C Controller 4")
+}
+
+Device (I2C5)
+{
+ Name (_ADR, 0x00190002)
+ Name (_DDN, "Serial IO I2C Controller 5")
+}
+
+Device (SPI0)
+{
+ Name (_ADR, 0x001E0002)
+ Name (_DDN, "Serial IO SPI Controller 0")
+}
+
+Device (SPI1)
+{
+ Name (_ADR, 0x001E0003)
+ Name (_DDN, "Serial IO SPI Controller 1")
+}
+
+Device (UAR0)
+{
+ Name (_ADR, 0x001E0000)
+ Name (_DDN, "Serial IO UART Controller 0")
+}
+
+Device (UAR1)
+{
+ Name (_ADR, 0x001E0001)
+ Name (_DDN, "Serial IO UART Controller 1")
+}
+
+Device (UAR2)
+{
+ Name (_ADR, 0x00190000)
+ Name (_DDN, "Serial IO UART Controller 2")
+}
diff --git a/src/soc/intel/kabylake/acpi/sleepstates.asl b/src/soc/intel/kabylake/acpi/sleepstates.asl
new file mode 100644
index 0000000..cb175f4
--- /dev/null
+++ b/src/soc/intel/kabylake/acpi/sleepstates.asl
@@ -0,0 +1,23 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+Name (\_S0, Package () { 0x0, 0x0, 0x0, 0x0 })
+Name (\_S1, Package () { 0x1, 0x1, 0x0, 0x0 })
+Name (\_S2, Package () { 0x1, 0x1, 0x0, 0x0 })
+Name (\_S3, Package () { 0x5, 0x5, 0x0, 0x0 })
+Name (\_S4, Package () { 0x6, 0x6, 0x0, 0x0 })
+Name (\_S5, Package () { 0x7, 0x7, 0x0, 0x0 })
diff --git a/src/soc/intel/kabylake/acpi/smbus.asl b/src/soc/intel/kabylake/acpi/smbus.asl
new file mode 100644
index 0000000..b71cbda
--- /dev/null
+++ b/src/soc/intel/kabylake/acpi/smbus.asl
@@ -0,0 +1,238 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+// Intel SMBus Controller 0:1f.3
+
+Device (SBUS)
+{
+ Name (_ADR, 0x001f0004)
+
+#ifdef ENABLE_SMBUS_METHODS
+ OperationRegion (SMBP, PCI_Config, 0x00, 0x100)
+ Field(SMBP, DWordAcc, NoLock, Preserve)
+ {
+ Offset(0x40),
+ , 2,
+ I2CE, 1
+ }
+
+ OperationRegion (SMBI, SystemIO, SMBUS_IO_BASE, 0x20)
+ Field (SMBI, ByteAcc, NoLock, Preserve)
+ {
+ HSTS, 8, // Host Status
+ , 8,
+ HCNT, 8, // Host Control
+ HCMD, 8, // Host Command
+ TXSA, 8, // Transmit Slave Address
+ DAT0, 8, // Host Data 0
+ DAT1, 8, // Host Data 1
+ HBDB, 8, // Host Block Data Byte
+ PECK, 8, // Packet Error Check
+ RXSA, 8, // Receive Slave Address
+ RXDA, 16, // Receive Slave Data
+ AUXS, 8, // Auxiliary Status
+ AUXC, 8, // Auxiliary Control
+ SLPC, 8, // SMLink Pin Control
+ SBPC, 8, // SMBus Pin Control
+ SSTS, 8, // Slave Status
+ SCMD, 8, // Slave Command
+ NADR, 8, // Notify Device Address
+ NDLB, 8, // Notify Data Low Byte
+ NDLH, 8, // Notify Data High Byte
+ }
+
+ // Kill all SMBus communication
+ Method (KILL, 0, Serialized)
+ {
+ Or (HCNT, 0x02, HCNT) // Send Kill
+ Or (HSTS, 0xff, HSTS) // Clean Status
+ }
+
+ // Check if last operation completed
+ // return Failure = 0, Success = 1
+ Method (CMPL, 0, Serialized)
+ {
+ Store (4000, Local0) // Timeout 200ms in 50us steps
+ While (Local0) {
+ If (And(HSTS, 0x02)) { // Completion Status?
+ Return (1) // Operation Completed
+ } Else {
+ Stall (50)
+ Decrement (Local0)
+ If (LEqual(Local0, 0)) {
+ KILL()
+ }
+ }
+ }
+
+ Return (0) // Failure
+ }
+
+
+ // Wait for SMBus to become ready
+ Method (SRDY, 0, Serialized)
+ {
+ Store (200, Local0) // Timeout 200ms
+ While (Local0) {
+ If (And(HSTS, 0x40)) { // IN_USE?
+ Sleep(1) // Wait 1ms
+ Decrement(Local0) // timeout--
+ If (LEqual(Local0, 0)) {
+ Return (1)
+ }
+ } Else {
+ Store (0, Local0) // We're ready
+ }
+ }
+
+ Store (4000, Local0) // Timeout 200ms (50us * 4000)
+ While (Local0) {
+ If (And (HSTS, 0x01)) { // Host Busy?
+ Stall(50) // Wait 50us
+ Decrement(Local0) // timeout--
+ If (LEqual(Local0, 0)) {
+ KILL()
+ }
+ } Else {
+ Return (0) // Success
+ }
+ }
+
+ Return (1) // Failure
+ }
+
+ // SMBus Send Byte
+ // Arg0: Address
+ // Arg1: Data
+ // Return: 1 = Success, 0=Failure
+
+ Method (SSXB, 2, Serialized)
+ {
+
+ // Is the SMBus Controller Ready?
+ If (SRDY()) {
+ Return (0)
+ }
+
+ // Send Byte
+ Store (0, I2CE) // SMBus Enable
+ Store (0xbf, HSTS)
+ Store (Arg0, TXSA) // Write Address
+ Store (Arg1, HCMD) // Write Data
+
+ Store (0x48, HCNT) // Start + Byte Data Protocol
+
+ If (CMPL()) {
+ Or (HSTS, 0xff, HSTS) // Clean up
+ Return (1) // Success
+ }
+
+ Return (0)
+ }
+
+
+ // SMBus Receive Byte
+ // Arg0: Address
+ // Return: 0xffff = Failure, Data (8bit) = Success
+
+ Method (SRXB, 2, Serialized)
+ {
+
+ // Is the SMBus Controller Ready?
+ If (SRDY()) {
+ Return (0xffff)
+ }
+
+ // Receive Byte
+ Store (0, I2CE) // SMBus Enable
+ Store (0xbf, HSTS)
+ Store (Or (Arg0, 1), TXSA) // Write Address
+
+ Store (0x44, HCNT) // Start
+
+ If (CMPL()) {
+ Or (HSTS, 0xff, HSTS) // Clean up
+ Return (DAT0) // Success
+ }
+
+ Return (0xffff)
+ }
+
+
+ // SMBus Write Byte
+ // Arg0: Address
+ // Arg1: Command
+ // Arg2: Data
+ // Return: 1 = Success, 0=Failure
+
+ Method (SWRB, 3, Serialized)
+ {
+
+ // Is the SMBus Controller Ready?
+ If (SRDY()) {
+ Return (0)
+ }
+
+ // Send Byte
+ Store (0, I2CE) // SMBus Enable
+ Store (0xbf, HSTS)
+ Store (Arg0, TXSA) // Write Address
+ Store (Arg1, HCMD) // Write Command
+ Store (Arg2, DAT0) // Write Data
+
+ Store (0x48, HCNT) // Start + Byte Protocol
+
+ If (CMPL()) {
+ Or (HSTS, 0xff, HSTS) // Clean up
+ Return (1) // Success
+ }
+
+ Return (0)
+ }
+
+
+ // SMBus Read Byte
+ // Arg0: Address
+ // Arg1: Command
+ // Return: 0xffff = Failure, Data (8bit) = Success
+
+ Method (SRDB, 2, Serialized)
+ {
+
+ // Is the SMBus Controller Ready?
+ If (SRDY()) {
+ Return (0xffff)
+ }
+
+ // Receive Byte
+ Store (0, I2CE) // SMBus Enable
+ Store (0xbf, HSTS)
+ Store (Or (Arg0, 1), TXSA) // Write Address
+ Store (Arg1, HCMD) // Command
+
+ Store (0x48, HCNT) // Start
+
+ If (CMPL()) {
+ Or (HSTS, 0xff, HSTS) // Clean up
+ Return (DAT0) // Success
+ }
+
+ Return (0xffff)
+ }
+#endif
+}
+
diff --git a/src/soc/intel/kabylake/acpi/systemagent.asl b/src/soc/intel/kabylake/acpi/systemagent.asl
new file mode 100644
index 0000000..53a2748
--- /dev/null
+++ b/src/soc/intel/kabylake/acpi/systemagent.asl
@@ -0,0 +1,372 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ * Copyright (C) 2015 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <soc/iomap.h>
+
+#define BASE_32GB 0x800000000
+#define SIZE_16GB 0x400000000
+
+Name (_HID, EISAID ("PNP0A08")) /* PCIe */
+Name (_CID, EISAID ("PNP0A03")) /* PCI */
+
+Name (_ADR, 0)
+Name (_BBN, 0)
+
+Device (MCHC)
+{
+ Name (_ADR, 0x00000000)
+
+ OperationRegion (MCHP, PCI_Config, 0x00, 0x100)
+ Field (MCHP, DWordAcc, NoLock, Preserve)
+ {
+ Offset(0x40), /* EPBAR (0:0:0:40) */
+ EPEN, 1, /* Enable */
+ , 11,
+ EPBR, 20, /* EPBAR [31:12] */
+
+ Offset(0x48), /* MCHBAR (0:0:0:48) */
+ MHEN, 1, /* Enable */
+ , 14,
+ MHBR, 17, /* MCHBAR [31:15] */
+
+ Offset(0x60), /* PCIEXBAR (0:0:0:60) */
+ PXEN, 1, /* Enable */
+ PXSZ, 2, /* PCI Express Size */
+ , 23,
+ PXBR, 6, /* PCI Express BAR [31:26] */
+
+ Offset(0x68), /* DMIBAR (0:0:0:68) */
+ DIEN, 1, /* Enable */
+ , 11,
+ DIBR, 20, /* DMIBAR [31:12] */
+
+ Offset (0x70), /* ME Base Address */
+ MEBA, 64,
+
+ Offset (0xa0), /* Top of Used Memory */
+ TOM, 64,
+
+ Offset (0xa8), /* Top of Upper Used Memory */
+ TUUD, 64,
+
+ Offset (0xbc), /* Top of Low Used Memory */
+ TLUD, 32,
+ }
+}
+
+Name (MCRS, ResourceTemplate ()
+{
+ /* Bus Numbers */
+ WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode,
+ 0x0000, 0x0000, 0x00ff, 0x0000, 0x0100)
+
+ /* IO Region 0 */
+ DWordIO (ResourceProducer, MinFixed, MaxFixed, PosDecode,
+ EntireRange,
+ 0x0000, 0x0000, 0x0cf7, 0x0000, 0x0cf8)
+
+ /* PCI Config Space */
+ Io (Decode16, 0x0cf8, 0x0cf8, 0x0001, 0x0008)
+
+ /* IO Region 1 */
+ DWordIO (ResourceProducer, MinFixed, MaxFixed, PosDecode,
+ EntireRange,
+ 0x0000, 0x0d00, 0xffff, 0x0000, 0xf300)
+
+ /* VGA memory (0xa0000-0xbffff) */
+ DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
+ Cacheable, ReadWrite,
+ 0x00000000, 0x000a0000, 0x000bffff, 0x00000000,
+ 0x00020000)
+
+ /* OPROM reserved (0xc0000-0xc3fff) */
+ DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
+ Cacheable, ReadWrite,
+ 0x00000000, 0x000c0000, 0x000c3fff, 0x00000000,
+ 0x00004000)
+
+ /* OPROM reserved (0xc4000-0xc7fff) */
+ DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
+ Cacheable, ReadWrite,
+ 0x00000000, 0x000c4000, 0x000c7fff, 0x00000000,
+ 0x00004000)
+
+ /* OPROM reserved (0xc8000-0xcbfff) */
+ DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
+ Cacheable, ReadWrite,
+ 0x00000000, 0x000c8000, 0x000cbfff, 0x00000000,
+ 0x00004000)
+
+ /* OPROM reserved (0xcc000-0xcffff) */
+ DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
+ Cacheable, ReadWrite,
+ 0x00000000, 0x000cc000, 0x000cffff, 0x00000000,
+ 0x00004000)
+
+ /* OPROM reserved (0xd0000-0xd3fff) */
+ DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
+ Cacheable, ReadWrite,
+ 0x00000000, 0x000d0000, 0x000d3fff, 0x00000000,
+ 0x00004000)
+
+ /* OPROM reserved (0xd4000-0xd7fff) */
+ DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
+ Cacheable, ReadWrite,
+ 0x00000000, 0x000d4000, 0x000d7fff, 0x00000000,
+ 0x00004000)
+
+ /* OPROM reserved (0xd8000-0xdbfff) */
+ DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
+ Cacheable, ReadWrite,
+ 0x00000000, 0x000d8000, 0x000dbfff, 0x00000000,
+ 0x00004000)
+
+ /* OPROM reserved (0xdc000-0xdffff) */
+ DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
+ Cacheable, ReadWrite,
+ 0x00000000, 0x000dc000, 0x000dffff, 0x00000000,
+ 0x00004000)
+
+ /* BIOS Extension (0xe0000-0xe3fff) */
+ DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
+ Cacheable, ReadWrite,
+ 0x00000000, 0x000e0000, 0x000e3fff, 0x00000000,
+ 0x00004000)
+
+ /* BIOS Extension (0xe4000-0xe7fff) */
+ DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
+ Cacheable, ReadWrite,
+ 0x00000000, 0x000e4000, 0x000e7fff, 0x00000000,
+ 0x00004000)
+
+ /* BIOS Extension (0xe8000-0xebfff) */
+ DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
+ Cacheable, ReadWrite,
+ 0x00000000, 0x000e8000, 0x000ebfff, 0x00000000,
+ 0x00004000)
+
+ /* BIOS Extension (0xec000-0xeffff) */
+ DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
+ Cacheable, ReadWrite,
+ 0x00000000, 0x000ec000, 0x000effff, 0x00000000,
+ 0x00004000)
+
+ /* System BIOS (0xf0000-0xfffff) */
+ DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
+ Cacheable, ReadWrite,
+ 0x00000000, 0x000f0000, 0x000fffff, 0x00000000,
+ 0x00010000)
+
+ /* PCI Memory Region (TOLUD - 0xdfffffff) */
+ DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
+ NonCacheable, ReadWrite,
+ 0x00000000, 0x00000000, 0xdfffffff, 0x00000000,
+ 0xE0000000,,, PM01)
+
+ /* PCI Memory Region (TOUUD - (TOUUD + ABOVE_4G_MMIO_SIZE)) */
+ QWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
+ NonCacheable, ReadWrite,
+ 0x00000000, 0x10000, 0x1ffff, 0x00000000,
+ 0x10000,,, PM02)
+
+ /* PCH reserved resource (0xfd000000-0xfe7fffff) */
+ DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
+ Cacheable, ReadWrite,
+ 0x00000000, 0xfd000000, 0xfe7fffff, 0x00000000,
+ 0x1800000)
+
+ /* TPM Area (0xfed40000-0xfed44fff) */
+ DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
+ Cacheable, ReadWrite,
+ 0x00000000, 0xfed40000, 0xfed44fff, 0x00000000,
+ 0x00005000)
+})
+
+Method (_CRS, 0, Serialized)
+{
+ /* Find PCI resource area in MCRS */
+ CreateDwordField (^MCRS, ^PM01._MIN, PMIN)
+ CreateDwordField (^MCRS, ^PM01._MAX, PMAX)
+ CreateDwordField (^MCRS, ^PM01._LEN, PLEN)
+
+ /*
+ * Fix up PCI memory region
+ * Start with Top of Lower Usable DRAM
+ */
+ Store (^MCHC.TLUD, Local0)
+ Store (^MCHC.MEBA, Local1)
+
+ /* Check if ME base is equal */
+ If (LEqual (Local0, Local1)) {
+ /* Use Top Of Memory instead */
+ Store (^MCHC.TOM, Local0)
+ }
+
+ Store (Local0, PMIN)
+ Add (Subtract (PMAX, PMIN), 1, PLEN)
+
+ /* Patch PM02 range based on Memory Size */
+ CreateQwordField (^MCRS, ^PM02._MIN, MMIN)
+ CreateQwordField (^MCRS, ^PM02._MAX, MMAX)
+ CreateQwordField (^MCRS, ^PM02._LEN, MLEN)
+
+ Store (^MCHC.TUUD, Local0)
+
+ If (LLessEqual (Local0, BASE_32GB)) {
+ Store (BASE_32GB, MMIN)
+ Store (SIZE_16GB, MLEN)
+ } Else {
+ Store (0, MMIN)
+ Store (0, MLEN)
+ }
+ Subtract (Add (MMIN, MLEN), 1, MMAX)
+
+ Return (^MCRS)
+}
+
+Name (EP_B, 0) /* to store EP BAR */
+Name (MH_B, 0) /* to store MCH BAR */
+Name (PC_B, 0) /* to store PCIe BAR */
+Name (PC_L, 0) /* to store PCIe BAR Length */
+Name (DM_B, 0) /* to store DMI BAR */
+
+/* Get MCH BAR */
+Method (GMHB, 0, Serialized)
+{
+ If (LEqual (MH_B, 0)) {
+ ShiftLeft (\_SB.PCI0.MCHC.MHBR, 15, MH_B)
+ }
+ Return (MH_B)
+}
+
+/* Get EP BAR */
+Method (GEPB, 0, Serialized)
+{
+ If (LEqual (EP_B, 0)) {
+ ShiftLeft (\_SB.PCI0.MCHC.EPBR, 12, EP_B)
+ }
+ Return (EP_B)
+}
+
+/* Get PCIe BAR */
+Method (GPCB, 0, Serialized)
+{
+ If (LEqual (PC_B, 0)) {
+ ShiftLeft (\_SB.PCI0.MCHC.PXBR, 26, PC_B)
+ }
+ Return (PC_B)
+}
+
+/* Get PCIe Length */
+Method (GPCL, 0, Serialized)
+{
+ If (LEqual (PC_L, 0)) {
+ ShiftRight (0x10000000, \_SB.PCI0.MCHC.PXSZ, PC_L)
+ }
+ Return (PC_L)
+}
+
+/* Get DMI BAR */
+Method (GDMB, 0, Serialized)
+{
+ If (LEqual (DM_B, 0)) {
+ ShiftLeft (\_SB.PCI0.MCHC.DIBR, 12, DM_B)
+ }
+ Return (DM_B)
+}
+
+/* PCI Device Resource Consumption */
+Device (PDRC)
+{
+ Name (_HID, EISAID ("PNP0C02"))
+ Name (_UID, 1)
+
+ Name (BUF0, ResourceTemplate ()
+ {
+ /* MCH BAR _BAS will be updated in _CRS below according to
+ * B0:D0:F0:Reg.48h
+ */
+ Memory32Fixed (ReadWrite, 0, 0x08000, MCHB)
+
+ /* DMI BAR _BAS will be updated in _CRS below according to
+ * B0:D0:F0:Reg.68h
+ */
+ Memory32Fixed (ReadWrite, 0, 0x01000, DMIB)
+
+ /* EP BAR _BAS will be updated in _CRS below according to
+ * B0:D0:F0:Reg.40h
+ */
+ Memory32Fixed (ReadWrite, 0, 0x01000, EGPB)
+
+ /* PCI Express BAR _BAS and _LEN will be updated in
+ * _CRS below according to B0:D0:F0:Reg.60h
+ */
+ Memory32Fixed (ReadWrite, 0, 0, PCIX)
+
+ /* MISC ICH TTT base address reserved for the
+ * TxT module use.
+ */
+ Memory32Fixed (ReadWrite, 0xFED20000, 0x20000)
+
+ /* VTD engine memory range.
+ * Check if the hard code meets the real configuration.
+ */
+ Memory32Fixed (ReadOnly, 0xFED90000, 0x00004000)
+
+ /* MISC ICH. Check if the hard code meets the
+ * real configuration.
+ */
+ Memory32Fixed (ReadWrite, 0xFED45000, 0x4B000, TPMM)
+
+ /* FLASH range */
+ Memory32Fixed (ReadOnly, 0xFF000000, 0x1000000, FIOH) /* 16MB */
+
+ /* Local APIC range(0xFEE0_0000 to 0xFEEF_FFFF) */
+ Memory32Fixed (ReadOnly, 0xFEE00000, 0x100000, LIOH)
+
+ /* HPET address decode range */
+ Memory32Fixed (ReadWrite, HPET_BASE_ADDRESS, 0x400)
+
+ /* Debug Base Address
+ * Base Address for ACPI debug output memory buffer
+ */
+ Memory32Fixed (ReadWrite, 0, 0, DBAD)
+ })
+
+ Method (_CRS, 0, Serialized)
+ {
+ CreateDwordField (BUF0, ^MCHB._BAS, MBR0)
+ Store (\_SB.PCI0.GMHB (), MBR0)
+
+ CreateDwordField (BUF0, ^DMIB._BAS, DBR0)
+ Store (\_SB.PCI0.GDMB (), DBR0)
+
+ CreateDwordField (BUF0, ^EGPB._BAS, EBR0)
+ Store (\_SB.PCI0.GEPB (), EBR0)
+
+ CreateDwordField (BUF0, ^PCIX._BAS, XBR0)
+ Store (\_SB.PCI0.GPCB (), XBR0)
+
+ CreateDwordField (BUF0, ^PCIX._LEN, XSZ0)
+ Store (\_SB.PCI0.GPCL (), XSZ0)
+
+ Return (BUF0)
+ }
+}
+
+/* PCI IRQ assignment */
+#include "pci_irqs.asl"
diff --git a/src/soc/intel/kabylake/acpi/xhci.asl b/src/soc/intel/kabylake/acpi/xhci.asl
new file mode 100644
index 0000000..7d0618f
--- /dev/null
+++ b/src/soc/intel/kabylake/acpi/xhci.asl
@@ -0,0 +1,185 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ * Copyright (C) 2015 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/* XHCI Controller 0:14.0 */
+
+Device (XHCI)
+{
+ Name (_ADR, 0x00140000)
+
+ Name (_PRW, Package () { GPE0_PME_B0, 3 })
+
+ Method (_DSW, 3)
+ {
+ Store (Arg0, PMEE)
+ }
+
+ Name (_S3D, 3) /* D3 supported in S3 */
+ Name (_S4D, 3) /* D3 supported in S4 */
+ Name (_S0W, 3) /* D3 can wake device in S0 */
+ Name (_S3W, 3) /* D3 can wake system from S3 */
+ Name (_S4W, 3) /* D3 can wake system from S4 */
+
+ OperationRegion (XPRT, PCI_Config, 0x00, 0x100)
+ Field (XPRT, AnyAcc, NoLock, Preserve)
+ {
+ Offset (0x0),
+ DVID, 16, /* VENDORID */
+ Offset (0x10),
+ , 16,
+ XMEM, 16, /* MEM_BASE */
+ Offset (0x74),
+ D0D3, 2, /* POWERSTATE */
+ , 6,
+ PMEE, 1, /* PME_EN */
+ , 6,
+ PMES, 1, /* PME_STS */
+ }
+
+ OperationRegion (XREG, SystemMemory,
+ Add (ShiftLeft (XMEM, 16), 0x8000), 0x200)
+ Field (XREG, DWordAcc, Lock, Preserve)
+ {
+ Offset (0x1c4), /* USB2PMCTRL */
+ , 2,
+ UPSW, 2, /* U2PSUSPGP */
+ }
+
+ Method (_PSC, 0, Serialized)
+ {
+ Return (^D0D3)
+ }
+
+ Method (_PS0, 0, Serialized)
+ {
+ If (LEqual (^DVID, 0xFFFF)) {
+ Return
+ }
+ If (LOr (LEqual (^XMEM, 0xFFFF), LEqual (^XMEM, 0x0000))) {
+ Return
+ }
+
+ /* If device is in D3, set back to D0 */
+ If (LEqual (^D0D3, 3)) {
+ Store (Zero, Local0)
+ Store (Local0, ^D0D3)
+ Store (^D0D3, Local0)
+ }
+
+ /* Disable USB2 PHY SUS Well Power Gating */
+ Store (Zero, ^UPSW)
+
+ /*
+ * Apply USB2 PHPY Power Gating workaround if needed.
+ */
+ If (^^PMC.UWAB) {
+ /* Write to MTPMC to have PMC disable power gating */
+ Store (1, ^^PMC.MPMC)
+
+ /* Wait for PCH_PM_STS.MSG_FULL_STS to be 0 */
+ Store (10, Local0)
+ While (^^PMC.PMFS) {
+ If (LNot (Local0)) {
+ Break
+ }
+ Decrement (Local0)
+ Sleep (10)
+ }
+ }
+ }
+
+ Method (_PS3, 0, Serialized)
+ {
+ If (LEqual (^DVID, 0xFFFF)) {
+ Return
+ }
+ If (LOr (LEqual (^XMEM, 0xFFFF), LEqual (^XMEM, 0x0000))) {
+ Return
+ }
+
+ /* Clear PME Status */
+ Store (1, ^PMES)
+
+ /* Enable PME */
+ Store (1, ^PMEE)
+
+ /* If device is in D3, set back to D0 */
+ If (LEqual (^D0D3, 3)) {
+ Store (Zero, Local0)
+ Store (Local0, ^D0D3)
+ Store (^D0D3, Local0)
+ }
+
+ /* Enable USB2 PHY SUS Well Power Gating in D0/D0i2/D0i3/D3 */
+ Store (3, ^UPSW)
+
+ /* Now put device in D3 */
+ Store (3, Local0)
+ Store (Local0, ^D0D3)
+ Store (^D0D3, Local0)
+
+ /*
+ * Apply USB2 PHPY Power Gating workaround if needed.
+ * This code assumes XDCI is disabled, if it is enabled
+ * then this must also check if it is in D3 state too.
+ */
+ If (^^PMC.UWAB) {
+ /* Write to MTPMC to have PMC enable power gating */
+ Store (3, ^^PMC.MPMC)
+
+ /* Wait for PCH_PM_STS.MSG_FULL_STS to be 0 */
+ Store (10, Local0)
+ While (^^PMC.PMFS) {
+ If (LNot (Local0)) {
+ Break
+ }
+ Decrement (Local0)
+ Sleep (10)
+ }
+ }
+ }
+
+ /* Root Hub for Kabylake-LP PCH */
+ Device (RHUB)
+ {
+ Name (_ADR, Zero)
+
+ /* USB2 */
+ Device (HS01) { Name (_ADR, 1) }
+ Device (HS02) { Name (_ADR, 2) }
+ Device (HS03) { Name (_ADR, 3) }
+ Device (HS04) { Name (_ADR, 4) }
+ Device (HS05) { Name (_ADR, 5) }
+ Device (HS06) { Name (_ADR, 6) }
+ Device (HS07) { Name (_ADR, 7) }
+ Device (HS08) { Name (_ADR, 8) }
+ Device (HS09) { Name (_ADR, 9) }
+ Device (HS10) { Name (_ADR, 10) }
+
+ /* USBr */
+ Device (USR1) { Name (_ADR, 11) }
+ Device (USR2) { Name (_ADR, 12) }
+
+ /* USB3 */
+ Device (SS01) { Name (_ADR, 13) }
+ Device (SS02) { Name (_ADR, 14) }
+ Device (SS03) { Name (_ADR, 15) }
+ Device (SS04) { Name (_ADR, 16) }
+ Device (SS05) { Name (_ADR, 17) }
+ Device (SS06) { Name (_ADR, 18) }
+ }
+}
diff --git a/src/soc/intel/kabylake/bootblock/cpu.c b/src/soc/intel/kabylake/bootblock/cpu.c
new file mode 100644
index 0000000..6d5065a
--- /dev/null
+++ b/src/soc/intel/kabylake/bootblock/cpu.c
@@ -0,0 +1,165 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <stdint.h>
+#include <arch/cpu.h>
+#include <cpu/x86/cache.h>
+#include <cpu/x86/msr.h>
+#include <cpu/x86/mtrr.h>
+#include <device/pci_def.h>
+#include <arch/io.h>
+#include <cpu/intel/microcode/microcode.c>
+#include <reset.h>
+#include <soc/iomap.h>
+#include <soc/msr.h>
+#include <soc/pci_devs.h>
+#include <soc/spi.h>
+
+/* Soft Reset Data Register Bit 12 = MAX Boot Frequency */
+#define SPI_STRAP_MAX_FREQ (1<<12)
+/* Soft Reset Data Register Bit 6-11 = Flex Ratio */
+#define FLEX_RATIO_BIT 6
+
+static void set_var_mtrr(
+ unsigned reg, unsigned base, unsigned size, unsigned type)
+
+{
+ /* Bit Bit 32-35 of MTRRphysMask should be set to 1 */
+ msr_t basem, maskm;
+ basem.lo = base | type;
+ basem.hi = 0;
+ wrmsr(MTRR_PHYS_BASE(reg), basem);
+ maskm.lo = ~(size - 1) | MTRR_PHYS_MASK_VALID;
+ maskm.hi = (1 << (CONFIG_CPU_ADDR_BITS - 32)) - 1;
+ wrmsr(MTRR_PHYS_MASK(reg), maskm);
+}
+
+static void enable_rom_caching(void)
+{
+ msr_t msr;
+
+ disable_cache();
+ set_var_mtrr(1, CACHE_ROM_BASE, CACHE_ROM_SIZE, MTRR_TYPE_WRPROT);
+ enable_cache();
+
+ /* Enable Variable MTRRs */
+ msr.hi = 0x00000000;
+ msr.lo = 0x00000800;
+ wrmsr(MTRR_DEF_TYPE_MSR, msr);
+}
+
+static void bootblock_mdelay(int ms)
+{
+ u32 target = ms * 24 * 1000;
+ msr_t current;
+ msr_t start = rdmsr(MSR_COUNTER_24_MHZ);
+
+ do {
+ current = rdmsr(MSR_COUNTER_24_MHZ);
+ } while ((current.lo - start.lo) < target);
+}
+
+static void set_pch_cpu_strap(u8 flex_ratio)
+{
+ uint8_t *spibar = (void *)SPI_BASE_ADDRESS;
+ u32 ssl, ssms, soft_reset_data;
+
+
+ /* Set Strap Lock Disable */
+ ssl = read32(spibar + SPIBAR_RESET_LOCK);
+ ssl |= SPIBAR_RESET_LOCK_DISABLE;
+ write32(spibar + SPIBAR_RESET_LOCK, ssl);
+
+ /* Soft Reset Data Register Bit 12 = MAX Boot Frequency
+ * Bit 6-11 = Flex Ratio
+ * Soft Reset Data register located at SPIBAR0 offset 0xF8[0:15].
+ */
+ soft_reset_data = SPI_STRAP_MAX_FREQ;
+ soft_reset_data |= (flex_ratio << FLEX_RATIO_BIT);
+ write32(spibar + SPIBAR_RESET_DATA, soft_reset_data);
+
+ /* Set Strap Mux Select set to '1' */
+ ssms = read32(spibar + SPIBAR_RESET_CTRL);
+ ssms |= SPIBAR_RESET_CTRL_SSMC;
+ write32(spibar + SPIBAR_RESET_CTRL, ssms);
+
+ /* Set Strap Lock Enable */
+ ssl = read32(spibar + SPIBAR_RESET_LOCK);
+ ssl |= SPIBAR_RESET_LOCK_ENABLE;
+ write32(spibar + SPIBAR_RESET_LOCK, ssl);
+}
+
+static void set_flex_ratio_to_tdp_nominal(void)
+{
+ msr_t flex_ratio, msr;
+ u8 nominal_ratio;
+
+ /* Check for Flex Ratio support */
+ flex_ratio = rdmsr(MSR_FLEX_RATIO);
+ if (!(flex_ratio.lo & FLEX_RATIO_EN))
+ return;
+
+ /* Check for >0 configurable TDPs */
+ msr = rdmsr(MSR_PLATFORM_INFO);
+ if (((msr.hi >> 1) & 3) == 0)
+ return;
+
+ /* Use nominal TDP ratio for flex ratio */
+ msr = rdmsr(MSR_CONFIG_TDP_NOMINAL);
+ nominal_ratio = msr.lo & 0xff;
+
+ /* See if flex ratio is already set to nominal TDP ratio */
+ if (((flex_ratio.lo >> 8) & 0xff) == nominal_ratio)
+ return;
+
+ /* Set flex ratio to nominal TDP ratio */
+ flex_ratio.lo &= ~0xff00;
+ flex_ratio.lo |= nominal_ratio << 8;
+ flex_ratio.lo |= FLEX_RATIO_LOCK;
+ wrmsr(MSR_FLEX_RATIO, flex_ratio);
+
+ /* Set PCH Soft Reset Data Register with new Flex Ratio */
+ set_pch_cpu_strap(nominal_ratio);
+
+ /* Delay before reset to avoid potential TPM lockout */
+ bootblock_mdelay(30);
+
+ /* Issue soft reset, will be "CPU only" due to soft reset data */
+ soft_reset();
+}
+
+static void check_for_clean_reset(void)
+{
+ msr_t msr;
+ msr = rdmsr(MTRR_DEF_TYPE_MSR);
+
+ /*
+ * Use the MTRR default type MSR as a proxy for detecting INIT#.
+ * Reset the system if any known bits are set in that MSR. That is
+ * an indication of the CPU not being properly reset.
+ */
+ if (msr.lo & (MTRR_DEF_TYPE_EN | MTRR_DEF_TYPE_FIX_EN))
+ soft_reset();
+}
+
+static void bootblock_cpu_init(void)
+{
+ /* Set flex ratio and reset if needed */
+ set_flex_ratio_to_tdp_nominal();
+ check_for_clean_reset();
+ enable_rom_caching();
+ intel_update_microcode_from_cbfs();
+}
diff --git a/src/soc/intel/kabylake/bootblock/pch.c b/src/soc/intel/kabylake/bootblock/pch.c
new file mode 100644
index 0000000..65ad5cf
--- /dev/null
+++ b/src/soc/intel/kabylake/bootblock/pch.c
@@ -0,0 +1,58 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#include <arch/io.h>
+#include <soc/iomap.h>
+#include <soc/lpc.h>
+#include <soc/pci_devs.h>
+#include <soc/spi.h>
+
+/*
+ * Enable Prefetching and Caching.
+ */
+static void enable_spi_prefetch(void)
+{
+ u8 reg8 = pci_read_config8(PCH_DEV_SPI, 0xdc);
+ reg8 &= ~(3 << 2);
+ reg8 |= (2 << 2); /* Prefetching and Caching Enabled */
+ pci_write_config8(PCH_DEV_SPI, 0xdc, reg8);
+}
+
+static void enable_spibar(void)
+{
+ device_t dev = PCH_DEV_SPI;
+ u8 pcireg;
+
+ /* Assign Resources to SPI Controller */
+ /* Clear BIT 1-2 SPI Command Register */
+ pcireg = pci_read_config8(dev, PCI_COMMAND);
+ pcireg &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
+ pci_write_config8(dev, PCI_COMMAND, pcireg);
+
+ /* Program Temporary BAR for SPI */
+ pci_write_config32(dev, PCI_BASE_ADDRESS_0,
+ SPI_BASE_ADDRESS | PCI_BASE_ADDRESS_SPACE_MEMORY);
+
+ /* Enable Bus Master and MMIO Space */
+ pcireg = pci_read_config8(dev, PCI_COMMAND);
+ pcireg |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
+ pci_write_config8(dev, PCI_COMMAND, pcireg);
+}
+
+static void bootblock_southbridge_init(void)
+{
+ enable_spibar();
+ enable_spi_prefetch();
+}
diff --git a/src/soc/intel/kabylake/bootblock/systemagent.c b/src/soc/intel/kabylake/bootblock/systemagent.c
new file mode 100644
index 0000000..12b23a8
--- /dev/null
+++ b/src/soc/intel/kabylake/bootblock/systemagent.c
@@ -0,0 +1,41 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <arch/io.h>
+#include <soc/pci_devs.h>
+#include <soc/systemagent.h>
+
+static void bootblock_northbridge_init(void)
+{
+ uint32_t reg;
+
+ /*
+ * The "io" variant of the config access is explicitly used to
+ * setup the PCIEXBAR because CONFIG_MMCONF_SUPPORT_DEFAULT is set to
+ * to true. That way all subsequent non-explicit config accesses use
+ * MCFG. This code also assumes that bootblock_northbridge_init() is
+ * the first thing called in the non-asm boot block code. The final
+ * assumption is that no assembly code is using the
+ * CONFIG_MMCONF_SUPPORT_DEFAULT option to do PCI config acceses.
+ *
+ * The PCIEXBAR is assumed to live in the memory mapped IO space under
+ * 4GiB.
+ */
+ reg = 0;
+ pci_io_write_config32(SA_DEV_ROOT, PCIEXBAR + 4, reg);
+ reg = CONFIG_MMCONF_BASE_ADDRESS | 4 | 1; /* 64MiB - 0-63 buses. */
+ pci_io_write_config32(SA_DEV_ROOT, PCIEXBAR, reg);
+}
diff --git a/src/soc/intel/kabylake/bootblock/timestamp.inc b/src/soc/intel/kabylake/bootblock/timestamp.inc
new file mode 100644
index 0000000..48986b2
--- /dev/null
+++ b/src/soc/intel/kabylake/bootblock/timestamp.inc
@@ -0,0 +1,35 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/*
+ * Store the initial timestamp for booting in mmx registers. This works
+ * because the bootblock isn't being compiled with MMX support so mm0 and
+ * mm1 will be preserved into romstage.
+ */
+ .code32
+
+.global stash_timestamp
+stash_timestamp:
+
+ /* Save the BIST value */
+ movl %eax, %ebp
+
+ finit
+ rdtsc
+ movd %eax, %mm0
+ movd %edx, %mm1
+
+ /* Restore the BIST value to %eax */
+ movl %ebp, %eax
+
diff --git a/src/soc/intel/kabylake/chip.c b/src/soc/intel/kabylake/chip.c
new file mode 100644
index 0000000..ad0d433
--- /dev/null
+++ b/src/soc/intel/kabylake/chip.c
@@ -0,0 +1,1102 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <arch/acpi.h>
+#include <chip.h>
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <fsp/util.h>
+#include <soc/acpi.h>
+#include <soc/interrupt.h>
+#include <soc/irq.h>
+#include <soc/pci_devs.h>
+#include <soc/ramstage.h>
+#include <string.h>
+
+static const SI_PCH_DEVICE_INTERRUPT_CONFIG devintconfig[] = {
+ /*
+ * cAVS(Audio, Voice, Speach), INTA is default, programmed in
+ * PciCfgSpace 3Dh
+ */
+ DEVICE_INT_CONFIG(PCH_DEV_SLOT_LPC,
+ PCI_FUNC(PCH_DEVFN_HDA), int_A, cAVS_INTA_IRQ),
+ /*
+ * SMBus Controller, no default value, programmed in
+ * PciCfgSpace 3Dh
+ */
+ DEVICE_INT_CONFIG(PCH_DEV_SLOT_LPC,
+ PCI_FUNC(PCH_DEVFN_SMBUS), int_A, SMBUS_INTA_IRQ),
+ /* GbE Controller, INTA is default, programmed in PciCfgSpace 3Dh */
+ DEVICE_INT_CONFIG(PCH_DEV_SLOT_LPC,
+ PCI_FUNC(PCH_DEVFN_GBE), int_A, GbE_INTA_IRQ),
+ /* TraceHub, INTA is default, RO register */
+ DEVICE_INT_CONFIG(PCH_DEV_SLOT_LPC,
+ PCI_FUNC(PCH_DEVFN_TRACEHUB), int_A, TRACE_HUB_INTA_IRQ),
+ /*
+ * SerialIo: UART #0, INTA is default,
+ * programmed in PCR[SERIALIO] + PCICFGCTRL[7]
+ */
+ DEVICE_INT_CONFIG(PCH_DEV_SLOT_STORAGE,
+ PCI_FUNC(PCH_DEVFN_UART0), int_A, LPSS_UART0_IRQ),
+ /*
+ * SerialIo: UART #1, INTA is default,
+ * programmed in PCR[SERIALIO] + PCICFGCTRL[8]
+ */
+ DEVICE_INT_CONFIG(PCH_DEV_SLOT_STORAGE,
+ PCI_FUNC(PCH_DEVFN_UART1), int_B, LPSS_UART1_IRQ),
+ /*
+ * SerialIo: SPI #0, INTA is default,
+ * programmed in PCR[SERIALIO] + PCICFGCTRL[10]
+ */
+ DEVICE_INT_CONFIG(PCH_DEV_SLOT_STORAGE,
+ PCI_FUNC(PCH_DEVFN_GSPI0), int_C, LPSS_SPI0_IRQ),
+ /*
+ * SerialIo: SPI #1, INTA is default,
+ * programmed in PCR[SERIALIO] + PCICFGCTRL[11]
+ */
+ DEVICE_INT_CONFIG(PCH_DEV_SLOT_STORAGE,
+ PCI_FUNC(PCH_DEVFN_GSPI1), int_D, LPSS_SPI1_IRQ),
+ /* SCS: eMMC (SKL PCH-LP Only) */
+ DEVICE_INT_CONFIG(PCH_DEV_SLOT_STORAGE,
+ PCI_FUNC(PCH_DEVFN_EMMC), int_B, eMMC_IRQ),
+ /* SCS: SDIO (SKL PCH-LP Only) */
+ DEVICE_INT_CONFIG(PCH_DEV_SLOT_STORAGE,
+ PCI_FUNC(PCH_DEVFN_SDIO), int_C, SDIO_IRQ),
+ /* SCS: SDCard (SKL PCH-LP Only) */
+ DEVICE_INT_CONFIG(PCH_DEV_SLOT_STORAGE,
+ PCI_FUNC(PCH_DEVFN_SDCARD), int_D, SD_IRQ),
+ /* PCI Express Port 9, INT is default, programmed in PciCfgSpace + FCh */
+ DEVICE_INT_CONFIG(PCH_DEV_SLOT_PCIE_1,
+ PCI_FUNC(PCH_DEVFN_PCIE9), int_A, PCIE_9_IRQ),
+ /* PCI Express Port 10, INT is default, programmed in PciCfgSpace + FCh */
+ DEVICE_INT_CONFIG(PCH_DEV_SLOT_PCIE_1,
+ PCI_FUNC(PCH_DEVFN_PCIE10), int_B, PCIE_10_IRQ),
+ /* PCI Express Port 11, INT is default, programmed in PciCfgSpace + FCh */
+ DEVICE_INT_CONFIG(PCH_DEV_SLOT_PCIE_1,
+ PCI_FUNC(PCH_DEVFN_PCIE11), int_C, PCIE_11_IRQ),
+ /* PCI Express Port 12, INT is default, programmed in PciCfgSpace + FCh */
+ DEVICE_INT_CONFIG(PCH_DEV_SLOT_PCIE_1,
+ PCI_FUNC(PCH_DEVFN_PCIE12), int_D, PCIE_12_IRQ),
+ /*
+ * PCI Express Port 1, INT is default,
+ * programmed in PciCfgSpace + FCh
+ */
+ DEVICE_INT_CONFIG(PCH_DEV_SLOT_PCIE,
+ PCI_FUNC(PCH_DEVFN_PCIE1), int_A, PCIE_1_IRQ),
+ /*
+ * PCI Express Port 2, INT is default,
+ * programmed in PciCfgSpace + FCh
+ */
+ DEVICE_INT_CONFIG(PCH_DEV_SLOT_PCIE,
+ PCI_FUNC(PCH_DEVFN_PCIE2), int_B, PCIE_2_IRQ),
+ /*
+ * PCI Express Port 3, INT is default,
+ * programmed in PciCfgSpace + FCh
+ */
+ DEVICE_INT_CONFIG(PCH_DEV_SLOT_PCIE,
+ PCI_FUNC(PCH_DEVFN_PCIE3), int_C, PCIE_3_IRQ),
+ /*
+ * PCI Express Port 4, INT is default,
+ * programmed in PciCfgSpace + FCh
+ */
+ DEVICE_INT_CONFIG(PCH_DEV_SLOT_PCIE,
+ PCI_FUNC(PCH_DEVFN_PCIE4), int_D, PCIE_4_IRQ),
+ /*
+ * PCI Express Port 5, INT is default,
+ * programmed in PciCfgSpace + FCh
+ */
+ DEVICE_INT_CONFIG(PCH_DEV_SLOT_PCIE,
+ PCI_FUNC(PCH_DEVFN_PCIE5), int_A, PCIE_5_IRQ),
+ /*
+ * PCI Express Port 6, INT is default,
+ * programmed in PciCfgSpace + FCh
+ */
+ DEVICE_INT_CONFIG(PCH_DEV_SLOT_PCIE,
+ PCI_FUNC(PCH_DEVFN_PCIE6), int_B, PCIE_6_IRQ),
+ /*
+ * PCI Express Port 7, INT is default,
+ * programmed in PciCfgSpace + FCh
+ */
+ DEVICE_INT_CONFIG(PCH_DEV_SLOT_PCIE,
+ PCI_FUNC(PCH_DEVFN_PCIE7), int_C, PCIE_7_IRQ),
+ /*
+ * PCI Express Port 8, INT is default,
+ * programmed in PciCfgSpace + FCh
+ */
+ DEVICE_INT_CONFIG(PCH_DEV_SLOT_PCIE,
+ PCI_FUNC(PCH_DEVFN_PCIE8), int_D, PCIE_8_IRQ),
+ /*
+ * SerialIo UART Controller #2, INTA is default,
+ * programmed in PCR[SERIALIO] + PCICFGCTRL[9]
+ */
+ DEVICE_INT_CONFIG(PCH_DEV_SLOT_SIO2,
+ PCI_FUNC(PCH_DEVFN_UART2), int_A, LPSS_UART2_IRQ),
+ /*
+ * SerialIo UART Controller #5, INTA is default,
+ * programmed in PCR[SERIALIO] + PCICFGCTRL[6]
+ */
+ DEVICE_INT_CONFIG(PCH_DEV_SLOT_SIO2,
+ PCI_FUNC(PCH_DEVFN_I2C5), int_B, LPSS_I2C5_IRQ),
+ /*
+ * SerialIo UART Controller #4, INTA is default,
+ * programmed in PCR[SERIALIO] + PCICFGCTRL[5]
+ */
+ DEVICE_INT_CONFIG(PCH_DEV_SLOT_SIO2,
+ PCI_FUNC(PCH_DEVFN_I2C4), int_C, LPSS_I2C4_IRQ),
+ /*
+ * SATA Controller, INTA is default,
+ * programmed in PciCfgSpace + 3Dh
+ */
+ DEVICE_INT_CONFIG(PCH_DEV_SLOT_SATA,
+ PCI_FUNC(PCH_DEVFN_SATA), int_A, SATA_IRQ),
+ /* CSME: HECI #1 */
+ DEVICE_INT_CONFIG(PCH_DEV_SLOT_ME,
+ PCI_FUNC(PCH_DEVFN_ME), int_A, HECI_1_IRQ),
+ /* CSME: HECI #2 */
+ DEVICE_INT_CONFIG(PCH_DEV_SLOT_ME,
+ PCI_FUNC(PCH_DEVFN_ME_2), int_B, HECI_2_IRQ),
+ /* CSME: IDE-Redirection (IDE-R) */
+ DEVICE_INT_CONFIG(PCH_DEV_SLOT_ME,
+ PCI_FUNC(PCH_DEVFN_ME_IDER), int_C, IDER_IRQ),
+ /* CSME: Keyboard and Text (KT) Redirection */
+ DEVICE_INT_CONFIG(PCH_DEV_SLOT_ME,
+ PCI_FUNC(PCH_DEVFN_ME_KT), int_D, KT_IRQ),
+ /* CSME: HECI #3 */
+ DEVICE_INT_CONFIG(PCH_DEV_SLOT_ME,
+ PCI_FUNC(PCH_DEVFN_ME_3), int_A, HECI_3_IRQ),
+ /*
+ * SerialIo I2C Controller #0, INTA is default,
+ * programmed in PCR[SERIALIO] + PCICFGCTRL[1]
+ */
+ DEVICE_INT_CONFIG(PCH_DEV_SLOT_SIO1,
+ PCI_FUNC(PCH_DEVFN_I2C0), int_A, LPSS_I2C0_IRQ),
+ /*
+ * SerialIo I2C Controller #1, INTA is default,
+ * programmed in PCR[SERIALIO] + PCICFGCTRL[2]
+ */
+ DEVICE_INT_CONFIG(PCH_DEV_SLOT_SIO1,
+ PCI_FUNC(PCH_DEVFN_I2C1), int_B, LPSS_I2C1_IRQ),
+ /*
+ * SerialIo I2C Controller #2, INTA is default,
+ * programmed in PCR[SERIALIO] + PCICFGCTRL[3]
+ */
+ DEVICE_INT_CONFIG(PCH_DEV_SLOT_SIO1,
+ PCI_FUNC(PCH_DEVFN_I2C2), int_C, LPSS_I2C2_IRQ),
+ /*
+ * SerialIo I2C Controller #3, INTA is default,
+ * programmed in PCR[SERIALIO] + PCICFGCTRL[4]
+ */
+ DEVICE_INT_CONFIG(PCH_DEV_SLOT_SIO1,
+ PCI_FUNC(PCH_DEVFN_I2C3), int_D, LPSS_I2C3_IRQ),
+ /*
+ * USB 3.0 xHCI Controller, no default value,
+ * programmed in PciCfgSpace 3Dh
+ */
+ DEVICE_INT_CONFIG(PCH_DEV_SLOT_XHCI,
+ PCI_FUNC(PCH_DEVFN_XHCI), int_A, XHCI_IRQ),
+ /* USB Device Controller (OTG) */
+ DEVICE_INT_CONFIG(PCH_DEV_SLOT_XHCI,
+ PCI_FUNC(PCH_DEVFN_USBOTG), int_B, OTG_IRQ),
+ /* Thermal Subsystem */
+ DEVICE_INT_CONFIG(PCH_DEV_SLOT_XHCI,
+ PCI_FUNC(PCH_DEVFN_THERMAL), int_C, THRMAL_IRQ),
+ /* Camera IO Host Controller */
+ DEVICE_INT_CONFIG(PCH_DEV_SLOT_XHCI,
+ PCI_FUNC(PCH_DEVFN_CIO), int_A, CIO_INTA_IRQ),
+ /* Integrated Sensor Hub */
+ DEVICE_INT_CONFIG(PCH_DEV_SLOT_ISH,
+ PCI_FUNC(PCH_DEVFN_ISH), int_A, ISH_IRQ)
+};
+
+#if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES)
+const char *soc_acpi_name(struct device *dev)
+{
+ if (dev->path.type == DEVICE_PATH_DOMAIN)
+ return "PCI0";
+
+ if (dev->path.type != DEVICE_PATH_PCI)
+ return NULL;
+
+ switch (dev->path.pci.devfn) {
+ case SA_DEVFN_ROOT: return "MCHC";
+ case SA_DEVFN_IGD: return "GFX0";
+ case PCH_DEVFN_ISH: return "ISHB";
+ case PCH_DEVFN_XHCI: return "XHCI";
+ case PCH_DEVFN_USBOTG: return "XDCI";
+ case PCH_DEVFN_THERMAL: return "THRM";
+ case PCH_DEVFN_CIO: return "ICIO";
+ case PCH_DEVFN_I2C0: return "I2C0";
+ case PCH_DEVFN_I2C1: return "I2C1";
+ case PCH_DEVFN_I2C2: return "I2C2";
+ case PCH_DEVFN_I2C3: return "I2C3";
+ case PCH_DEVFN_ME: return "MEI1";
+ case PCH_DEVFN_ME_2: return "MEI2";
+ case PCH_DEVFN_ME_IDER: return "MEID";
+ case PCH_DEVFN_ME_KT: return "MEKT";
+ case PCH_DEVFN_ME_3: return "MEI3";
+ case PCH_DEVFN_SATA: return "SATA";
+ case PCH_DEVFN_UART2: return "UAR2";
+ case PCH_DEVFN_I2C4: return "I2C4";
+ case PCH_DEVFN_I2C5: return "I2C5";
+ case PCH_DEVFN_PCIE1: return "RP01";
+ case PCH_DEVFN_PCIE2: return "RP02";
+ case PCH_DEVFN_PCIE3: return "RP03";
+ case PCH_DEVFN_PCIE4: return "RP04";
+ case PCH_DEVFN_PCIE5: return "RP05";
+ case PCH_DEVFN_PCIE6: return "RP06";
+ case PCH_DEVFN_PCIE7: return "RP07";
+ case PCH_DEVFN_PCIE8: return "RP08";
+ case PCH_DEVFN_PCIE9: return "RP09";
+ case PCH_DEVFN_PCIE10: return "RP10";
+ case PCH_DEVFN_PCIE11: return "RP11";
+ case PCH_DEVFN_PCIE12: return "RP12";
+ case PCH_DEVFN_UART0: return "UAR0";
+ case PCH_DEVFN_UART1: return "UAR1";
+ case PCH_DEVFN_GSPI0: return "SPI0";
+ case PCH_DEVFN_GSPI1: return "SPI1";
+ case PCH_DEVFN_EMMC: return "EMMC";
+ case PCH_DEVFN_SDIO: return "SDIO";
+ case PCH_DEVFN_SDCARD: return "SDXC";
+ case PCH_DEVFN_LPC: return "LPCB";
+ case PCH_DEVFN_P2SB: return "P2SB";
+ case PCH_DEVFN_PMC: return "PMC_";
+ case PCH_DEVFN_HDA: return "HDAS";
+ case PCH_DEVFN_SMBUS: return "SBUS";
+ case PCH_DEVFN_SPI: return "FSPI";
+ case PCH_DEVFN_GBE: return "IGBE";
+ case PCH_DEVFN_TRACEHUB:return "THUB";
+ }
+
+ return NULL;
+}
+#endif
+
+static void pci_domain_set_resources(device_t dev)
+{
+ assign_resources(dev->link_list);
+}
+
+static struct device_operations pci_domain_ops = {
+ .read_resources = &pci_domain_read_resources,
+ .set_resources = &pci_domain_set_resources,
+ .scan_bus = &pci_domain_scan_bus,
+ .ops_pci_bus = &pci_bus_default_ops,
+#if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES)
+ .acpi_name = &soc_acpi_name,
+#endif
+};
+
+static struct device_operations cpu_bus_ops = {
+ .init = &soc_init_cpus,
+#if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES)
+ .acpi_fill_ssdt_generator = generate_cpu_entries,
+#endif
+};
+
+static void soc_enable(device_t dev)
+{
+ /* Set the operations if it is a special bus type */
+ if (dev->path.type == DEVICE_PATH_DOMAIN) {
+ dev->ops = &pci_domain_ops;
+ } else if (dev->path.type == DEVICE_PATH_CPU_CLUSTER) {
+ dev->ops = &cpu_bus_ops;
+ } else if (dev->path.type == DEVICE_PATH_PCI) {
+ /* Handle PCH device enable */
+ if (PCI_SLOT(dev->path.pci.devfn) > SA_DEV_SLOT_IGD &&
+ (dev->ops == NULL || dev->ops->enable == NULL)) {
+ pch_enable_dev(dev);
+ }
+ }
+}
+
+struct chip_operations soc_intel_kabylake_ops = {
+ CHIP_NAME("Intel Kabylake")
+ .enable_dev = &soc_enable,
+ .init = &soc_init_pre_device,
+};
+
+/* UPD parameters to be initialized before SiliconInit */
+void soc_silicon_init_params(SILICON_INIT_UPD *params)
+{
+ const struct device *dev = dev_find_slot(0, PCH_DEVFN_LPC);
+ const struct soc_intel_kabylake_config *config = dev->chip_info;
+ u8 irq_config[PCH_MAX_IRQ_CONFIG];
+ int i;
+ int intdeventry;
+
+ memcpy(params->SerialIoDevMode, config->SerialIoDevMode,
+ sizeof(params->SerialIoDevMode));
+
+ for (i = 0; i < ARRAY_SIZE(config->usb2_ports); i++) {
+ params->PortUsb20Enable[i] =
+ config->usb2_ports[i].enable;
+ params->Usb2AfePetxiset[i] =
+ config->usb2_ports[i].pre_emp_bias;
+ params->Usb2AfeTxiset[i] =
+ config->usb2_ports[i].tx_bias;
+ params->Usb2AfePredeemp[i] =
+ config->usb2_ports[i].tx_emp_enable;
+ params->Usb2AfePehalfbit[i] =
+ config->usb2_ports[i].pre_emp_bit;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(config->usb3_ports); i++) {
+ params->PortUsb30Enable[i] = config->usb3_ports[i].enable;
+ if (config->usb3_ports[i].tx_de_emp) {
+ params->Usb3HsioTxDeEmphEnable[i] = 1;
+ params->Usb3HsioTxDeEmph[i] =
+ config->usb3_ports[i].tx_de_emp;
+ }
+ if (config->usb3_ports[i].tx_downscale_amp) {
+ params->Usb3HsioTxDownscaleAmpEnable[i] = 1;
+ params->Usb3HsioTxDownscaleAmp[i] =
+ config->usb3_ports[i].tx_downscale_amp;
+ }
+ }
+
+ memcpy(params->PcieRpEnable, config->PcieRpEnable,
+ sizeof(params->PcieRpEnable));
+ memcpy(params->PcieRpClkReqSupport, config->PcieRpClkReqSupport,
+ sizeof(params->PcieRpClkReqSupport));
+ memcpy(params->PcieRpClkReqNumber, config->PcieRpClkReqNumber,
+ sizeof(params->PcieRpClkReqNumber));
+
+ params->EnableLan = config->EnableLan;
+ params->Cio2Enable = config->Cio2Enable;
+ params->SataSalpSupport = config->SataSalpSupport;
+ params->SataPortsEnable[0] = config->SataPortsEnable[0];
+ params->SsicPortEnable = config->SsicPortEnable;
+ params->SmbusEnable = config->SmbusEnable;
+ params->ScsEmmcEnabled = config->ScsEmmcEnabled;
+ params->ScsEmmcHs400Enabled = config->ScsEmmcHs400Enabled;
+ params->ScsSdCardEnabled = config->ScsSdCardEnabled;
+ params->IshEnable = 0;
+ params->EnableAzalia = config->EnableAzalia;
+ params->IoBufferOwnership = config->IoBufferOwnership;
+ params->DspEnable = config->DspEnable;
+ params->XdciEnable = config->XdciEnable;
+ params->Device4Enable = config->Device4Enable;
+ params->EnableSata = config->EnableSata;
+ params->SataMode = config->SataMode;
+ params->LockDownConfigGlobalSmi = config->LockDownConfigGlobalSmi;
+ params->LockDownConfigBiosInterface = config->LockDownConfigBiosInterface;
+ params->LockDownConfigRtcLock = config->LockDownConfigRtcLock;
+ params->LockDownConfigBiosLock = config->LockDownConfigBiosLock;
+ params->LockDownConfigSpiEiss = config->LockDownConfigSpiEiss;
+ params->PchConfigSubSystemVendorId = config->PchConfigSubSystemVendorId;
+ params->PchConfigSubSystemId = config->PchConfigSubSystemId;
+ params->WakeConfigWolEnableOverride = config->WakeConfigWolEnableOverride;
+ params->WakeConfigPcieWakeFromDeepSx = config->WakeConfigPcieWakeFromDeepSx;
+ params->PmConfigDeepSxPol = config->PmConfigDeepSxPol;
+ params->PmConfigSlpS3MinAssert = config->PmConfigSlpS3MinAssert;
+ params->PmConfigSlpS4MinAssert = config->PmConfigSlpS4MinAssert;
+ params->PmConfigSlpSusMinAssert = config->PmConfigSlpSusMinAssert;
+ params->PmConfigSlpAMinAssert = config->PmConfigSlpAMinAssert;
+ params->PmConfigPciClockRun = config->PmConfigPciClockRun;
+ params->PmConfigSlpStrchSusUp = config->PmConfigSlpStrchSusUp;
+ params->PmConfigPwrBtnOverridePeriod = config->PmConfigPwrBtnOverridePeriod;
+ params->PmConfigPwrCycDur = config->PmConfigPwrCycDur;
+ params->SerialIrqConfigSirqEnable = config->SerialIrqConfigSirqEnable;
+ params->SerialIrqConfigSirqMode = config->SerialIrqConfigSirqMode;
+ params->SerialIrqConfigStartFramePulse = config->SerialIrqConfigStartFramePulse;
+
+ params->SkipMpInit = config->FspSkipMpInit;
+
+ for (i = 0; i < ARRAY_SIZE(config->i2c); i++)
+ params->SerialIoI2cVoltage[i] = config->i2c[i].voltage;
+
+ /*
+ * To disable Heci, the Psf needs to be left unlocked
+ * by FSP after end of post sequence. Based on the devicetree
+ * setting, we set the appropriate PsfUnlock policy in Fsp,
+ * do the changes and then lock it back in Coreboot
+ *
+ */
+ if (config->HeciEnabled == 0)
+ params->PsfUnlock = 1;
+ else
+ params->PsfUnlock = 0;
+
+ for (i = 0; i < ARRAY_SIZE(config->domain_vr_config); i++)
+ fill_vr_domain_config(params, i, &config->domain_vr_config[i]);
+
+ /* Show SPI controller if enabled in devicetree.cb */
+ dev = dev_find_slot(0, PCH_DEVFN_SPI);
+ params->ShowSpiController = dev->enabled;
+
+ /* Get Device Int Count */
+ intdeventry = ARRAY_SIZE(devintconfig);
+ /*update irq table*/
+ memcpy((SI_PCH_DEVICE_INTERRUPT_CONFIG *)(params->DevIntConfigPtr), devintconfig,
+ intdeventry * sizeof(SI_PCH_DEVICE_INTERRUPT_CONFIG));
+
+ params->NumOfDevIntConfig = intdeventry;
+ /* PxRC to IRQ programing */
+ for (i = 0; i < PCH_MAX_IRQ_CONFIG; i++) {
+ switch(i) {
+ case PCH_PARC:
+ case PCH_PCRC:
+ case PCH_PDRC:
+ case PCH_PERC:
+ case PCH_PFRC:
+ case PCH_PGRC:
+ case PCH_PHRC:
+ irq_config[i] = PCH_IRQ11;
+ break;
+ case PCH_PBRC:
+ irq_config[PCH_PBRC] = PCH_IRQ10;
+ break;
+ }
+ }
+ memcpy(params->PxRcConfig, irq_config, PCH_MAX_IRQ_CONFIG);
+ /* GPIO IRQ Route The valid values is 14 or 15*/
+ if(config->GpioIrqSelect == 0)
+ params->GpioIrqRoute = GPIO_IRQ14;
+ else
+ params->GpioIrqRoute = config->GpioIrqSelect;
+ /* SCI IRQ Select The valid values is 9, 10, 11 and 20 21, 22, 23*/
+ if(config->SciIrqSelect == 0)
+ params->SciIrqSelect = SCI_IRQ9;
+ else
+ params->SciIrqSelect = config->SciIrqSelect;
+ /* TCO IRQ Select The valid values is 9, 10, 11, 20 21, 22, 23*/
+ if(config->TcoIrqSelect == 0)
+ params->TcoIrqSelect = TCO_IRQ9;
+ else
+ params->TcoIrqSelect = config->TcoIrqSelect;
+ /* TCO Irq enable/disable */
+ params->TcoIrqEnable = config->TcoIrqEnable;
+ params->SendVrMbxCmd = config->SendVrMbxCmd;
+}
+
+void soc_display_silicon_init_params(const SILICON_INIT_UPD *original,
+ SILICON_INIT_UPD *params)
+{
+ /* Display the parameters for SiliconInit */
+ printk(BIOS_SPEW, "UPD values for SiliconInit:\n");
+ fsp_display_upd_value("LogoPtr", 4,
+ (uint32_t)original->LogoPtr,
+ (uint32_t)params->LogoPtr);
+ fsp_display_upd_value("LogoSize", 4,
+ (uint32_t)original->LogoSize,
+ (uint32_t)params->LogoSize);
+ fsp_display_upd_value("GraphicsConfigPtr", 4,
+ (uint32_t)original->GraphicsConfigPtr,
+ (uint32_t)params->GraphicsConfigPtr);
+ fsp_display_upd_value("MicrocodeRegionBase", 4,
+ (uint32_t)original->MicrocodeRegionBase,
+ (uint32_t)params->MicrocodeRegionBase);
+ fsp_display_upd_value("MicrocodeRegionSize", 4,
+ (uint32_t)original->MicrocodeRegionSize,
+ (uint32_t)params->MicrocodeRegionSize);
+ fsp_display_upd_value("TurboMode", 1,
+ (uint32_t)original->TurboMode,
+ (uint32_t)params->TurboMode);
+ fsp_display_upd_value("Device4Enable", 1,
+ original->Device4Enable,
+ params->Device4Enable);
+ fsp_display_upd_value("PcieRpEnable[0]", 1, original->PcieRpEnable[0],
+ params->PcieRpEnable[0]);
+ fsp_display_upd_value("PcieRpEnable[1]", 1, original->PcieRpEnable[1],
+ params->PcieRpEnable[1]);
+ fsp_display_upd_value("PcieRpEnable[2]", 1, original->PcieRpEnable[2],
+ params->PcieRpEnable[2]);
+ fsp_display_upd_value("PcieRpEnable[3]", 1, original->PcieRpEnable[3],
+ params->PcieRpEnable[3]);
+ fsp_display_upd_value("PcieRpEnable[4]", 1, original->PcieRpEnable[4],
+ params->PcieRpEnable[4]);
+ fsp_display_upd_value("PcieRpEnable[5]", 1, original->PcieRpEnable[5],
+ params->PcieRpEnable[5]);
+ fsp_display_upd_value("PcieRpEnable[6]", 1, original->PcieRpEnable[6],
+ params->PcieRpEnable[6]);
+ fsp_display_upd_value("PcieRpEnable[7]", 1, original->PcieRpEnable[7],
+ params->PcieRpEnable[7]);
+ fsp_display_upd_value("PcieRpEnable[8]", 1, original->PcieRpEnable[8],
+ params->PcieRpEnable[8]);
+ fsp_display_upd_value("PcieRpEnable[9]", 1, original->PcieRpEnable[9],
+ params->PcieRpEnable[9]);
+ fsp_display_upd_value("PcieRpEnable[10]", 1, original->PcieRpEnable[10],
+ params->PcieRpEnable[10]);
+ fsp_display_upd_value("PcieRpEnable[11]", 1, original->PcieRpEnable[11],
+ params->PcieRpEnable[11]);
+ fsp_display_upd_value("PcieRpEnable[12]", 1, original->PcieRpEnable[12],
+ params->PcieRpEnable[12]);
+ fsp_display_upd_value("PcieRpEnable[13]", 1, original->PcieRpEnable[13],
+ params->PcieRpEnable[13]);
+ fsp_display_upd_value("PcieRpEnable[14]", 1, original->PcieRpEnable[14],
+ params->PcieRpEnable[14]);
+ fsp_display_upd_value("PcieRpEnable[15]", 1, original->PcieRpEnable[15],
+ params->PcieRpEnable[15]);
+ fsp_display_upd_value("PcieRpEnable[16]", 1, original->PcieRpEnable[16],
+ params->PcieRpEnable[16]);
+ fsp_display_upd_value("PcieRpEnable[17]", 1, original->PcieRpEnable[17],
+ params->PcieRpEnable[17]);
+ fsp_display_upd_value("PcieRpEnable[18]", 1, original->PcieRpEnable[18],
+ params->PcieRpEnable[18]);
+ fsp_display_upd_value("PcieRpEnable[19]", 1, original->PcieRpEnable[19],
+ params->PcieRpEnable[19]);
+ fsp_display_upd_value("PcieRpClkReqSupport[0]", 1,
+ original->PcieRpClkReqSupport[0],
+ params->PcieRpClkReqSupport[0]);
+ fsp_display_upd_value("PcieRpClkReqSupport[1]", 1,
+ original->PcieRpClkReqSupport[1],
+ params->PcieRpClkReqSupport[1]);
+ fsp_display_upd_value("PcieRpClkReqSupport[2]", 1,
+ original->PcieRpClkReqSupport[2],
+ params->PcieRpClkReqSupport[2]);
+ fsp_display_upd_value("PcieRpClkReqSupport[3]", 1,
+ original->PcieRpClkReqSupport[3],
+ params->PcieRpClkReqSupport[3]);
+ fsp_display_upd_value("PcieRpClkReqSupport[4]", 1,
+ original->PcieRpClkReqSupport[4],
+ params->PcieRpClkReqSupport[4]);
+ fsp_display_upd_value("PcieRpClkReqSupport[5]", 1,
+ original->PcieRpClkReqSupport[5],
+ params->PcieRpClkReqSupport[5]);
+ fsp_display_upd_value("PcieRpClkReqSupport[6]", 1,
+ original->PcieRpClkReqSupport[6],
+ params->PcieRpClkReqSupport[6]);
+ fsp_display_upd_value("PcieRpClkReqSupport[7]", 1,
+ original->PcieRpClkReqSupport[7],
+ params->PcieRpClkReqSupport[7]);
+ fsp_display_upd_value("PcieRpClkReqSupport[8]", 1,
+ original->PcieRpClkReqSupport[8],
+ params->PcieRpClkReqSupport[8]);
+ fsp_display_upd_value("PcieRpClkReqSupport[9]", 1,
+ original->PcieRpClkReqSupport[9],
+ params->PcieRpClkReqSupport[9]);
+ fsp_display_upd_value("PcieRpClkReqSupport[10]", 1,
+ original->PcieRpClkReqSupport[10],
+ params->PcieRpClkReqSupport[10]);
+ fsp_display_upd_value("PcieRpClkReqSupport[11]", 1,
+ original->PcieRpClkReqSupport[11],
+ params->PcieRpClkReqSupport[11]);
+ fsp_display_upd_value("PcieRpClkReqSupport[12]", 1,
+ original->PcieRpClkReqSupport[12],
+ params->PcieRpClkReqSupport[12]);
+ fsp_display_upd_value("PcieRpClkReqSupport[13]", 1,
+ original->PcieRpClkReqSupport[13],
+ params->PcieRpClkReqSupport[13]);
+ fsp_display_upd_value("PcieRpClkReqSupport[14]", 1,
+ original->PcieRpClkReqSupport[14],
+ params->PcieRpClkReqSupport[14]);
+ fsp_display_upd_value("PcieRpClkReqSupport[15]", 1,
+ original->PcieRpClkReqSupport[15],
+ params->PcieRpClkReqSupport[15]);
+ fsp_display_upd_value("PcieRpClkReqSupport[16]", 1,
+ original->PcieRpClkReqSupport[16],
+ params->PcieRpClkReqSupport[16]);
+ fsp_display_upd_value("PcieRpClkReqSupport[17]", 1,
+ original->PcieRpClkReqSupport[17],
+ params->PcieRpClkReqSupport[17]);
+ fsp_display_upd_value("PcieRpClkReqSupport[18]", 1,
+ original->PcieRpClkReqSupport[18],
+ params->PcieRpClkReqSupport[18]);
+ fsp_display_upd_value("PcieRpClkReqSupport[19]", 1,
+ original->PcieRpClkReqSupport[19],
+ params->PcieRpClkReqSupport[19]);
+ fsp_display_upd_value("PcieRpClkReqNumber[0]", 1,
+ original->PcieRpClkReqNumber[0],
+ params->PcieRpClkReqNumber[0]);
+ fsp_display_upd_value("PcieRpClkReqNumber[1]", 1,
+ original->PcieRpClkReqNumber[1],
+ params->PcieRpClkReqNumber[1]);
+ fsp_display_upd_value("PcieRpClkReqNumber[2]", 1,
+ original->PcieRpClkReqNumber[2],
+ params->PcieRpClkReqNumber[2]);
+ fsp_display_upd_value("PcieRpClkReqNumber[3]", 1,
+ original->PcieRpClkReqNumber[3],
+ params->PcieRpClkReqNumber[3]);
+ fsp_display_upd_value("PcieRpClkReqNumber[4]", 1,
+ original->PcieRpClkReqNumber[4],
+ params->PcieRpClkReqNumber[4]);
+ fsp_display_upd_value("PcieRpClkReqNumber[5]", 1,
+ original->PcieRpClkReqNumber[5],
+ params->PcieRpClkReqNumber[5]);
+ fsp_display_upd_value("PcieRpClkReqNumber[6]", 1,
+ original->PcieRpClkReqNumber[6],
+ params->PcieRpClkReqNumber[6]);
+ fsp_display_upd_value("PcieRpClkReqNumber[7]", 1,
+ original->PcieRpClkReqNumber[7],
+ params->PcieRpClkReqNumber[7]);
+ fsp_display_upd_value("PcieRpClkReqNumber[8]", 1,
+ original->PcieRpClkReqNumber[8],
+ params->PcieRpClkReqNumber[8]);
+ fsp_display_upd_value("PcieRpClkReqNumber[9]", 1,
+ original->PcieRpClkReqNumber[9],
+ params->PcieRpClkReqNumber[9]);
+ fsp_display_upd_value("PcieRpClkReqNumber[10]", 1,
+ original->PcieRpClkReqNumber[10],
+ params->PcieRpClkReqNumber[10]);
+ fsp_display_upd_value("PcieRpClkReqNumber[11]", 1,
+ original->PcieRpClkReqNumber[11],
+ params->PcieRpClkReqNumber[11]);
+ fsp_display_upd_value("PcieRpClkReqNumber[12]", 1,
+ original->PcieRpClkReqNumber[12],
+ params->PcieRpClkReqNumber[12]);
+ fsp_display_upd_value("PcieRpClkReqNumber[13]", 1,
+ original->PcieRpClkReqNumber[13],
+ params->PcieRpClkReqNumber[13]);
+ fsp_display_upd_value("PcieRpClkReqNumber[14]", 1,
+ original->PcieRpClkReqNumber[14],
+ params->PcieRpClkReqNumber[14]);
+ fsp_display_upd_value("PcieRpClkReqNumber[15]", 1,
+ original->PcieRpClkReqNumber[15],
+ params->PcieRpClkReqNumber[15]);
+ fsp_display_upd_value("PcieRpClkReqNumber[16]", 1,
+ original->PcieRpClkReqNumber[16],
+ params->PcieRpClkReqNumber[16]);
+ fsp_display_upd_value("PcieRpClkReqNumber[17]", 1,
+ original->PcieRpClkReqNumber[17],
+ params->PcieRpClkReqNumber[17]);
+ fsp_display_upd_value("PcieRpClkReqNumber[18]", 1,
+ original->PcieRpClkReqNumber[18],
+ params->PcieRpClkReqNumber[18]);
+ fsp_display_upd_value("PcieRpClkReqNumber[19]", 1,
+ original->PcieRpClkReqNumber[19],
+ params->PcieRpClkReqNumber[19]);
+ fsp_display_upd_value("EnableLan", 1, original->EnableLan,
+ params->EnableLan);
+ fsp_display_upd_value("Cio2Enable", 1, original->Cio2Enable,
+ params->Cio2Enable);
+ fsp_display_upd_value("SataSalpSupport", 1, original->SataSalpSupport,
+ params->SataSalpSupport);
+ fsp_display_upd_value("SataPortsEnable[0]", 1,
+ original->SataPortsEnable[0], params->SataPortsEnable[0]);
+ fsp_display_upd_value("SataPortsEnable[1]", 1,
+ original->SataPortsEnable[1], params->SataPortsEnable[1]);
+ fsp_display_upd_value("SataPortsEnable[2]", 1,
+ original->SataPortsEnable[2], params->SataPortsEnable[2]);
+ fsp_display_upd_value("SataPortsEnable[3]", 1,
+ original->SataPortsEnable[3], params->SataPortsEnable[3]);
+ fsp_display_upd_value("SataPortsEnable[4]", 1,
+ original->SataPortsEnable[4], params->SataPortsEnable[4]);
+ fsp_display_upd_value("SataPortsEnable[5]", 1,
+ original->SataPortsEnable[5], params->SataPortsEnable[5]);
+ fsp_display_upd_value("SataPortsEnable[6]", 1,
+ original->SataPortsEnable[6], params->SataPortsEnable[6]);
+ fsp_display_upd_value("SataPortsEnable[7]", 1,
+ original->SataPortsEnable[7], params->SataPortsEnable[7]);
+ fsp_display_upd_value("SataPortsDevSlp[0]", 1,
+ original->SataPortsDevSlp[0], params->SataPortsDevSlp[0]);
+ fsp_display_upd_value("SataPortsDevSlp[1]", 1,
+ original->SataPortsDevSlp[1], params->SataPortsDevSlp[1]);
+ fsp_display_upd_value("SataPortsDevSlp[2]", 1,
+ original->SataPortsDevSlp[2], params->SataPortsDevSlp[2]);
+ fsp_display_upd_value("SataPortsDevSlp[3]", 1,
+ original->SataPortsDevSlp[3], params->SataPortsDevSlp[3]);
+ fsp_display_upd_value("SataPortsDevSlp[4]", 1,
+ original->SataPortsDevSlp[4], params->SataPortsDevSlp[4]);
+ fsp_display_upd_value("SataPortsDevSlp[5]", 1,
+ original->SataPortsDevSlp[5], params->SataPortsDevSlp[5]);
+ fsp_display_upd_value("SataPortsDevSlp[6]", 1,
+ original->SataPortsDevSlp[6], params->SataPortsDevSlp[6]);
+ fsp_display_upd_value("SataPortsDevSlp[7]", 1,
+ original->SataPortsDevSlp[7], params->SataPortsDevSlp[7]);
+ fsp_display_upd_value("EnableAzalia", 1,
+ original->EnableAzalia, params->EnableAzalia);
+ fsp_display_upd_value("DspEnable", 1, original->DspEnable,
+ params->DspEnable);
+ fsp_display_upd_value("IoBufferOwnership", 1,
+ original->IoBufferOwnership, params->IoBufferOwnership);
+ fsp_display_upd_value("PortUsb20Enable[0]", 1,
+ original->PortUsb20Enable[0], params->PortUsb20Enable[0]);
+ fsp_display_upd_value("PortUsb20Enable[1]", 1,
+ original->PortUsb20Enable[1], params->PortUsb20Enable[1]);
+ fsp_display_upd_value("PortUsb20Enable[2]", 1,
+ original->PortUsb20Enable[2], params->PortUsb20Enable[2]);
+ fsp_display_upd_value("PortUsb20Enable[3]", 1,
+ original->PortUsb20Enable[3], params->PortUsb20Enable[3]);
+ fsp_display_upd_value("PortUsb20Enable[4]", 1,
+ original->PortUsb20Enable[4], params->PortUsb20Enable[4]);
+ fsp_display_upd_value("PortUsb20Enable[5]", 1,
+ original->PortUsb20Enable[5], params->PortUsb20Enable[5]);
+ fsp_display_upd_value("PortUsb20Enable[6]", 1,
+ original->PortUsb20Enable[6], params->PortUsb20Enable[6]);
+ fsp_display_upd_value("PortUsb20Enable[7]", 1,
+ original->PortUsb20Enable[7], params->PortUsb20Enable[7]);
+ fsp_display_upd_value("PortUsb20Enable[8]", 1,
+ original->PortUsb20Enable[8], params->PortUsb20Enable[8]);
+ fsp_display_upd_value("PortUsb20Enable[9]", 1,
+ original->PortUsb20Enable[9], params->PortUsb20Enable[9]);
+ fsp_display_upd_value("PortUsb20Enable[10]", 1,
+ original->PortUsb20Enable[10], params->PortUsb20Enable[10]);
+ fsp_display_upd_value("PortUsb20Enable[11]", 1,
+ original->PortUsb20Enable[11], params->PortUsb20Enable[11]);
+ fsp_display_upd_value("PortUsb20Enable[12]", 1,
+ original->PortUsb20Enable[12], params->PortUsb20Enable[12]);
+ fsp_display_upd_value("PortUsb20Enable[13]", 1,
+ original->PortUsb20Enable[13], params->PortUsb20Enable[13]);
+ fsp_display_upd_value("PortUsb20Enable[14]", 1,
+ original->PortUsb20Enable[14], params->PortUsb20Enable[14]);
+ fsp_display_upd_value("PortUsb20Enable[15]", 1,
+ original->PortUsb20Enable[15], params->PortUsb20Enable[15]);
+ fsp_display_upd_value("PortUsb30Enable[0]", 1,
+ original->PortUsb30Enable[0], params->PortUsb30Enable[0]);
+ fsp_display_upd_value("PortUsb30Enable[1]", 1,
+ original->PortUsb30Enable[1], params->PortUsb30Enable[1]);
+ fsp_display_upd_value("PortUsb30Enable[2]", 1,
+ original->PortUsb30Enable[2], params->PortUsb30Enable[2]);
+ fsp_display_upd_value("PortUsb30Enable[3]", 1,
+ original->PortUsb30Enable[3], params->PortUsb30Enable[3]);
+ fsp_display_upd_value("PortUsb30Enable[4]", 1,
+ original->PortUsb30Enable[4], params->PortUsb30Enable[4]);
+ fsp_display_upd_value("PortUsb30Enable[5]", 1,
+ original->PortUsb30Enable[5], params->PortUsb30Enable[5]);
+ fsp_display_upd_value("PortUsb30Enable[6]", 1,
+ original->PortUsb30Enable[6], params->PortUsb30Enable[6]);
+ fsp_display_upd_value("PortUsb30Enable[7]", 1,
+ original->PortUsb30Enable[7], params->PortUsb30Enable[7]);
+ fsp_display_upd_value("PortUsb30Enable[8]", 1,
+ original->PortUsb30Enable[8], params->PortUsb30Enable[8]);
+ fsp_display_upd_value("PortUsb30Enable[9]", 1,
+ original->PortUsb30Enable[9], params->PortUsb30Enable[9]);
+ fsp_display_upd_value("XdciEnable", 1, original->XdciEnable,
+ params->XdciEnable);
+ fsp_display_upd_value("SsicPortEnable", 1, original->SsicPortEnable,
+ params->SsicPortEnable);
+ fsp_display_upd_value("SmbusEnable", 1, original->SmbusEnable,
+ params->SmbusEnable);
+ fsp_display_upd_value("SerialIoDevMode[0]", 1,
+ original->SerialIoDevMode[0], params->SerialIoDevMode[0]);
+ fsp_display_upd_value("SerialIoDevMode[1]", 1,
+ original->SerialIoDevMode[1], params->SerialIoDevMode[1]);
+ fsp_display_upd_value("SerialIoDevMode[2]", 1,
+ original->SerialIoDevMode[2], params->SerialIoDevMode[2]);
+ fsp_display_upd_value("SerialIoDevMode[3]", 1,
+ original->SerialIoDevMode[3], params->SerialIoDevMode[3]);
+ fsp_display_upd_value("SerialIoDevMode[4]", 1,
+ original->SerialIoDevMode[4], params->SerialIoDevMode[4]);
+ fsp_display_upd_value("SerialIoDevMode[5]", 1,
+ original->SerialIoDevMode[5], params->SerialIoDevMode[5]);
+ fsp_display_upd_value("SerialIoDevMode[6]", 1,
+ original->SerialIoDevMode[6], params->SerialIoDevMode[6]);
+ fsp_display_upd_value("SerialIoDevMode[7]", 1,
+ original->SerialIoDevMode[7], params->SerialIoDevMode[7]);
+ fsp_display_upd_value("SerialIoDevMode[8]", 1,
+ original->SerialIoDevMode[8], params->SerialIoDevMode[8]);
+ fsp_display_upd_value("SerialIoDevMode[9]", 1,
+ original->SerialIoDevMode[9], params->SerialIoDevMode[9]);
+ fsp_display_upd_value("SerialIoDevMode[10]", 1,
+ original->SerialIoDevMode[10], params->SerialIoDevMode[10]);
+ fsp_display_upd_value("ScsEmmcEnabled", 1, original->ScsEmmcEnabled,
+ params->ScsEmmcEnabled);
+ fsp_display_upd_value("ScsEmmcHs400Enabled", 1,
+ original->ScsEmmcHs400Enabled, params->ScsEmmcHs400Enabled);
+ fsp_display_upd_value("ScsSdCardEnabled", 1, original->ScsSdCardEnabled,
+ params->ScsSdCardEnabled);
+ fsp_display_upd_value("IshEnable", 1, original->IshEnable,
+ params->IshEnable);
+ fsp_display_upd_value("ShowSpiController", 1,
+ original->ShowSpiController, params->ShowSpiController);
+ fsp_display_upd_value("HsioMessaging", 1, original->HsioMessaging,
+ params->HsioMessaging);
+ fsp_display_upd_value("Heci3Enabled", 1, original->Heci3Enabled,
+ params->Heci3Enabled);
+ fsp_display_upd_value("EnableSata", 1, original->EnableSata,
+ params->EnableSata);
+ fsp_display_upd_value("SataMode", 1, original->SataMode,
+ params->SataMode);
+ fsp_display_upd_value("NumOfDevIntConfig", 1,
+ original->NumOfDevIntConfig,
+ params->NumOfDevIntConfig);
+ fsp_display_upd_value("PxRcConfig[PARC]", 1,
+ original->PxRcConfig[PCH_PARC],
+ params->PxRcConfig[PCH_PARC]);
+ fsp_display_upd_value("PxRcConfig[PBRC]", 1,
+ original->PxRcConfig[PCH_PBRC],
+ params->PxRcConfig[PCH_PBRC]);
+ fsp_display_upd_value("PxRcConfig[PCRC]", 1,
+ original->PxRcConfig[PCH_PCRC],
+ params->PxRcConfig[PCH_PCRC]);
+ fsp_display_upd_value("PxRcConfig[PDRC]", 1,
+ original->PxRcConfig[PCH_PDRC],
+ params->PxRcConfig[PCH_PDRC]);
+ fsp_display_upd_value("PxRcConfig[PERC]", 1,
+ original->PxRcConfig[PCH_PERC],
+ params->PxRcConfig[PCH_PERC]);
+ fsp_display_upd_value("PxRcConfig[PFRC]", 1,
+ original->PxRcConfig[PCH_PFRC],
+ params->PxRcConfig[PCH_PFRC]);
+ fsp_display_upd_value("PxRcConfig[PGRC]", 1,
+ original->PxRcConfig[PCH_PGRC],
+ params->PxRcConfig[PCH_PGRC]);
+ fsp_display_upd_value("PxRcConfig[PHRC]", 1,
+ original->PxRcConfig[PCH_PHRC],
+ params->PxRcConfig[PCH_PHRC]);
+ fsp_display_upd_value("GpioIrqRoute", 1,
+ original->GpioIrqRoute,
+ params->GpioIrqRoute);
+ fsp_display_upd_value("SciIrqSelect", 1,
+ original->SciIrqSelect,
+ params->SciIrqSelect);
+ fsp_display_upd_value("TcoIrqSelect", 1,
+ original->TcoIrqSelect,
+ params->TcoIrqSelect);
+ fsp_display_upd_value("TcoIrqEnable", 1,
+ original->TcoIrqEnable,
+ params->TcoIrqEnable);
+ fsp_display_upd_value("LockDownConfigGlobalSmi", 1,
+ original->LockDownConfigGlobalSmi,
+ params->LockDownConfigGlobalSmi);
+ fsp_display_upd_value("LockDownConfigBiosInterface", 1,
+ original->LockDownConfigBiosInterface,
+ params->LockDownConfigBiosInterface);
+ fsp_display_upd_value("LockDownConfigRtcLock", 1,
+ original->LockDownConfigRtcLock,
+ params->LockDownConfigRtcLock);
+ fsp_display_upd_value("LockDownConfigBiosLock", 1,
+ original->LockDownConfigBiosLock,
+ params->LockDownConfigBiosLock);
+ fsp_display_upd_value("LockDownConfigSpiEiss", 1,
+ original->LockDownConfigSpiEiss,
+ params->LockDownConfigSpiEiss);
+ fsp_display_upd_value("PchConfigSubSystemVendorId", 1,
+ original->PchConfigSubSystemVendorId,
+ params->PchConfigSubSystemVendorId);
+ fsp_display_upd_value("PchConfigSubSystemId", 1,
+ original->PchConfigSubSystemId,
+ params->PchConfigSubSystemId);
+ fsp_display_upd_value("WakeConfigWolEnableOverride", 1,
+ original->WakeConfigWolEnableOverride,
+ params->WakeConfigWolEnableOverride);
+ fsp_display_upd_value("WakeConfigPcieWakeFromDeepSx", 1,
+ original->WakeConfigPcieWakeFromDeepSx,
+ params->WakeConfigPcieWakeFromDeepSx);
+ fsp_display_upd_value("PmConfigDeepSxPol", 1,
+ original->PmConfigDeepSxPol,
+ params->PmConfigDeepSxPol);
+ fsp_display_upd_value("PmConfigSlpS3MinAssert", 1,
+ original->PmConfigSlpS3MinAssert,
+ params->PmConfigSlpS3MinAssert);
+ fsp_display_upd_value("PmConfigSlpS4MinAssert", 1,
+ original->PmConfigSlpS4MinAssert,
+ params->PmConfigSlpS4MinAssert);
+ fsp_display_upd_value("PmConfigSlpSusMinAssert", 1,
+ original->PmConfigSlpSusMinAssert,
+ params->PmConfigSlpSusMinAssert);
+ fsp_display_upd_value("PmConfigSlpAMinAssert", 1,
+ original->PmConfigSlpAMinAssert,
+ params->PmConfigSlpAMinAssert);
+ fsp_display_upd_value("PmConfigPciClockRun", 1,
+ original->PmConfigPciClockRun,
+ params->PmConfigPciClockRun);
+ fsp_display_upd_value("PmConfigSlpStrchSusUp", 1,
+ original->PmConfigSlpStrchSusUp,
+ params->PmConfigSlpStrchSusUp);
+ fsp_display_upd_value("PmConfigPwrBtnOverridePeriod", 1,
+ original->PmConfigPwrBtnOverridePeriod,
+ params->PmConfigPwrBtnOverridePeriod);
+ fsp_display_upd_value("PmConfigPwrCycDur", 1,
+ original->PmConfigPwrCycDur,
+ params->PmConfigPwrCycDur);
+ fsp_display_upd_value("SerialIrqConfigSirqEnable", 1,
+ original->SerialIrqConfigSirqEnable,
+ params->SerialIrqConfigSirqEnable);
+ fsp_display_upd_value("SerialIrqConfigSirqMode", 1,
+ original->SerialIrqConfigSirqMode,
+ params->SerialIrqConfigSirqMode);
+ fsp_display_upd_value("SerialIrqConfigStartFramePulse", 1,
+ original->SerialIrqConfigStartFramePulse,
+ params->SerialIrqConfigStartFramePulse);
+
+ fsp_display_upd_value("Psi1Threshold[0]", 1,
+ original->Psi1Threshold[0],
+ params->Psi1Threshold[0]);
+ fsp_display_upd_value("Psi1Threshold[1]", 1,
+ original->Psi1Threshold[1],
+ params->Psi1Threshold[1]);
+ fsp_display_upd_value("Psi1Threshold[2]", 1,
+ original->Psi1Threshold[2],
+ params->Psi1Threshold[2]);
+ fsp_display_upd_value("Psi1Threshold[3]", 1,
+ original->Psi1Threshold[3],
+ params->Psi1Threshold[3]);
+ fsp_display_upd_value("Psi1Threshold[4]", 1,
+ original->Psi1Threshold[4],
+ params->Psi1Threshold[4]);
+ fsp_display_upd_value("Psi2Threshold[0]", 1,
+ original->Psi2Threshold[0],
+ params->Psi2Threshold[0]);
+ fsp_display_upd_value("Psi2Threshold[1]", 1,
+ original->Psi2Threshold[1],
+ params->Psi2Threshold[1]);
+ fsp_display_upd_value("Psi2Threshold[2]", 1,
+ original->Psi2Threshold[2],
+ params->Psi2Threshold[2]);
+ fsp_display_upd_value("Psi2Threshold[3]", 1,
+ original->Psi2Threshold[3],
+ params->Psi2Threshold[3]);
+ fsp_display_upd_value("Psi2Threshold[4]", 1,
+ original->Psi2Threshold[4],
+ params->Psi2Threshold[4]);
+ fsp_display_upd_value("Psi3Threshold[0]", 1,
+ original->Psi3Threshold[0],
+ params->Psi3Threshold[0]);
+ fsp_display_upd_value("Psi3Threshold[1]", 1,
+ original->Psi3Threshold[1],
+ params->Psi3Threshold[1]);
+ fsp_display_upd_value("Psi3Threshold[2]", 1,
+ original->Psi3Threshold[2],
+ params->Psi3Threshold[2]);
+ fsp_display_upd_value("Psi3Threshold[3]", 1,
+ original->Psi3Threshold[3],
+ params->Psi3Threshold[3]);
+ fsp_display_upd_value("Psi3Threshold[4]", 1,
+ original->Psi3Threshold[4],
+ params->Psi3Threshold[4]);
+ fsp_display_upd_value("Psi3Enable[0]", 1,
+ original->Psi3Enable[0],
+ params->Psi3Enable[0]);
+ fsp_display_upd_value("Psi3Enable[1]", 1,
+ original->Psi3Enable[1],
+ params->Psi3Enable[1]);
+ fsp_display_upd_value("Psi3Enable[2]", 1,
+ original->Psi3Enable[2],
+ params->Psi3Enable[2]);
+ fsp_display_upd_value("Psi3Enable[3]", 1,
+ original->Psi3Enable[3],
+ params->Psi3Enable[3]);
+ fsp_display_upd_value("Psi3Enable[4]", 1,
+ original->Psi3Enable[4],
+ params->Psi3Enable[4]);
+ fsp_display_upd_value("Psi4Enable[0]", 1,
+ original->Psi4Enable[0],
+ params->Psi4Enable[0]);
+ fsp_display_upd_value("Psi4Enable[1]", 1,
+ original->Psi4Enable[1],
+ params->Psi4Enable[1]);
+ fsp_display_upd_value("Psi4Enable[2]", 1,
+ original->Psi4Enable[2],
+ params->Psi4Enable[2]);
+ fsp_display_upd_value("Psi4Enable[3]", 1,
+ original->Psi4Enable[3],
+ params->Psi4Enable[3]);
+ fsp_display_upd_value("Psi4Enable[4]", 1,
+ original->Psi4Enable[4],
+ params->Psi4Enable[4]);
+ fsp_display_upd_value("ImonSlope[0]", 1,
+ original->ImonSlope[0],
+ params->ImonSlope[0]);
+ fsp_display_upd_value("ImonSlope[1]", 1,
+ original->ImonSlope[1],
+ params->ImonSlope[1]);
+ fsp_display_upd_value("ImonSlope[2]", 1,
+ original->ImonSlope[2],
+ params->ImonSlope[2]);
+ fsp_display_upd_value("ImonSlope[3]", 1,
+ original->ImonSlope[3],
+ params->ImonSlope[3]);
+ fsp_display_upd_value("ImonSlope[4]", 1,
+ original->ImonSlope[4],
+ params->ImonSlope[4]);
+ fsp_display_upd_value("ImonOffse[0]t", 1,
+ original->ImonOffset[0],
+ params->ImonOffset[0]);
+ fsp_display_upd_value("ImonOffse[1]t", 1,
+ original->ImonOffset[1],
+ params->ImonOffset[1]);
+ fsp_display_upd_value("ImonOffse[2]t", 1,
+ original->ImonOffset[2],
+ params->ImonOffset[2]);
+ fsp_display_upd_value("ImonOffse[3]t", 1,
+ original->ImonOffset[3],
+ params->ImonOffset[3]);
+ fsp_display_upd_value("ImonOffse[4]t", 1,
+ original->ImonOffset[4],
+ params->ImonOffset[4]);
+ fsp_display_upd_value("IccMax[0]", 1,
+ original->IccMax[0],
+ params->IccMax[0]);
+ fsp_display_upd_value("IccMax[1]", 1,
+ original->IccMax[1],
+ params->IccMax[1]);
+ fsp_display_upd_value("IccMax[2]", 1,
+ original->IccMax[2],
+ params->IccMax[2]);
+ fsp_display_upd_value("IccMax[3]", 1,
+ original->IccMax[3],
+ params->IccMax[3]);
+ fsp_display_upd_value("IccMax[4]", 1,
+ original->IccMax[4],
+ params->IccMax[4]);
+ fsp_display_upd_value("VrVoltageLimit[0]", 1,
+ original->VrVoltageLimit[0],
+ params->VrVoltageLimit[0]);
+ fsp_display_upd_value("VrVoltageLimit[1]", 1,
+ original->VrVoltageLimit[1],
+ params->VrVoltageLimit[1]);
+ fsp_display_upd_value("VrVoltageLimit[2]", 1,
+ original->VrVoltageLimit[2],
+ params->VrVoltageLimit[2]);
+ fsp_display_upd_value("VrVoltageLimit[3]", 1,
+ original->VrVoltageLimit[3],
+ params->VrVoltageLimit[3]);
+ fsp_display_upd_value("VrVoltageLimit[4]", 1,
+ original->VrVoltageLimit[4],
+ params->VrVoltageLimit[4]);
+ fsp_display_upd_value("VrConfigEnable[0]", 1,
+ original->VrConfigEnable[0],
+ params->VrConfigEnable[0]);
+ fsp_display_upd_value("VrConfigEnable[1]", 1,
+ original->VrConfigEnable[1],
+ params->VrConfigEnable[1]);
+ fsp_display_upd_value("VrConfigEnable[2]", 1,
+ original->VrConfigEnable[2],
+ params->VrConfigEnable[2]);
+ fsp_display_upd_value("VrConfigEnable[3]", 1,
+ original->VrConfigEnable[3],
+ params->VrConfigEnable[3]);
+ fsp_display_upd_value("VrConfigEnable[4]", 1,
+ original->VrConfigEnable[4],
+ params->VrConfigEnable[4]);
+ fsp_display_upd_value("SerialIoI2cVoltage[0]", 1,
+ original->SerialIoI2cVoltage[0],
+ params->SerialIoI2cVoltage[0]);
+ fsp_display_upd_value("SerialIoI2cVoltage[1]", 1,
+ original->SerialIoI2cVoltage[1],
+ params->SerialIoI2cVoltage[1]);
+ fsp_display_upd_value("SerialIoI2cVoltage[2]", 1,
+ original->SerialIoI2cVoltage[2],
+ params->SerialIoI2cVoltage[2]);
+ fsp_display_upd_value("SerialIoI2cVoltage[3]", 1,
+ original->SerialIoI2cVoltage[3],
+ params->SerialIoI2cVoltage[3]);
+ fsp_display_upd_value("SerialIoI2cVoltage[4]", 1,
+ original->SerialIoI2cVoltage[4],
+ params->SerialIoI2cVoltage[4]);
+ fsp_display_upd_value("SerialIoI2cVoltage[5]", 1,
+ original->SerialIoI2cVoltage[5],
+ params->SerialIoI2cVoltage[5]);
+ fsp_display_upd_value("SendVrMbxCmd", 1,
+ original->SendVrMbxCmd,
+ params->SendVrMbxCmd);
+}
+
+static void pci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+ if (!vendor || !device)
+ pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
+ pci_read_config32(dev, PCI_VENDOR_ID));
+ else
+ pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
+ (device << 16) | vendor);
+}
+
+struct pci_operations soc_pci_ops = {
+ .set_subsystem = &pci_set_subsystem
+};
diff --git a/src/soc/intel/kabylake/chip.h b/src/soc/intel/kabylake/chip.h
new file mode 100644
index 0000000..c1b8a9c
--- /dev/null
+++ b/src/soc/intel/kabylake/chip.h
@@ -0,0 +1,386 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2008 coresystems GmbH
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+
+#ifndef _SOC_CHIP_H_
+#define _SOC_CHIP_H_
+
+#include <arch/acpi_device.h>
+#include <device/i2c.h>
+#include <stdint.h>
+#include <soc/gpio_defs.h>
+#include <soc/gpe.h>
+#include <soc/intel/common/lpss_i2c.h>
+#include <soc/pci_devs.h>
+#include <soc/pmc.h>
+#include <soc/serialio.h>
+#include <soc/usb.h>
+#include <soc/vr_config.h>
+
+#define KABYLAKE_I2C_DEV_MAX 6
+
+enum kabylake_i2c_voltage {
+ I2C_VOLTAGE_3V3,
+ I2C_VOLTAGE_1V8
+};
+
+struct kabylake_i2c_config {
+ /* Bus voltage level, default is 3.3V */
+ enum kabylake_i2c_voltage voltage;
+ /* Bus speed in Hz, default is I2C_SPEED_FAST (400 KHz) */
+ enum i2c_speed speed;
+ /* Bus should be enabled prior to ramstage with temporary base */
+ int early_init;
+ /* Custom bus speed configuration { scl_lcnt, scl_hcnt, sda_hold } */
+ struct lpss_i2c_speed_config speed_config[LPSS_I2C_SPEED_CONFIG_COUNT];
+};
+
+struct soc_intel_kabylake_config {
+ /*
+ * Interrupt Routing configuration
+ * If bit7 is 1, the interrupt is disabled.
+ */
+ uint8_t pirqa_routing;
+ uint8_t pirqb_routing;
+ uint8_t pirqc_routing;
+ uint8_t pirqd_routing;
+ uint8_t pirqe_routing;
+ uint8_t pirqf_routing;
+ uint8_t pirqg_routing;
+ uint8_t pirqh_routing;
+
+ /* GPE configuration */
+ uint32_t gpe0_en_1; /* GPE0_EN_31_0 */
+ uint32_t gpe0_en_2; /* GPE0_EN_63_32 */
+ uint32_t gpe0_en_3; /* GPE0_EN_95_64 */
+ uint32_t gpe0_en_4; /* GPE0_EN_127_96 / GPE_STD */
+ /* Gpio group routed to each dword of the GPE0 block. Values are
+ * of the form GPP_[A:G] or GPD. */
+ uint8_t gpe0_dw0; /* GPE0_31_0 STS/EN */
+ uint8_t gpe0_dw1; /* GPE0_63_32 STS/EN */
+ uint8_t gpe0_dw2; /* GPE0_95_64 STS/EN */
+
+ /* Generic IO decode ranges */
+ uint32_t gen1_dec;
+ uint32_t gen2_dec;
+ uint32_t gen3_dec;
+ uint32_t gen4_dec;
+
+ /* Enable S0iX support */
+ int s0ix_enable;
+
+ /* Enable DPTF support */
+ int dptf_enable;
+
+ /* Deep SX enable for both AC and DC */
+ int deep_s3_enable;
+ int deep_s5_enable;
+
+ /*
+ * Deep Sx Configuration
+ * DSX_EN_WAKE_PIN - Enable WAKE# pin
+ * DSX_EN_LAN_WAKE_PIN - Enable LAN_WAKE# pin
+ * DSX_EN_AC_PRESENT_PIN - Enable AC_PRESENT pin
+ */
+ uint32_t deep_sx_config;
+
+ /* TCC activation offset */
+ int tcc_offset;
+
+ /*
+ * The following fields come from FspUpdVpd.h.
+ * These are configuration values that are passed to FSP during
+ * MemoryInit.
+ */
+ u64 PlatformMemorySize;
+ u8 SmramMask;
+ u8 MrcFastBoot;
+ u32 TsegSize;
+ u16 MmioSize;
+
+ /*
+ * DDR Frequency Limit
+ * 0(Auto), 1067, 1333, 1600, 1867, 2133, 2400
+ */
+ u16 DdrFreqLimit;
+
+ /* Probeless Trace function */
+ u8 ProbelessTrace;
+
+ /*
+ * System Agent dynamic frequency configuration
+ * When enabled memory will be trained at two different frequencies.
+ * 0 = Disabled
+ * 1 = FixedLow
+ * 2 = FixedHigh
+ * 3 = Enabled
+ */
+ u8 SaGv;
+
+ /* Enable/disable Rank Margin Tool */
+ u8 Rmt;
+
+ /* Lan */
+ u8 EnableLan;
+
+ /* SATA related */
+ u8 EnableSata;
+ u8 SataMode;
+ u8 SataSalpSupport;
+ u8 SataPortsEnable[8];
+ u8 SataPortsDevSlp[8];
+
+ /* Audio related */
+ u8 EnableAzalia;
+ u8 DspEnable;
+
+ /*
+ * I/O Buffer Ownership:
+ * 0: HD-A Link
+ * 1 Shared, HD-A Link and I2S Port
+ * 3: I2S Ports
+ */
+ u8 IoBufferOwnership;
+
+ /* Trace Hub function */
+ u8 EnableTraceHub;
+
+ /* Pcie Root Ports */
+ u8 PcieRpEnable[20];
+ u8 PcieRpClkReqSupport[20];
+ u8 PcieRpClkReqNumber[20];
+
+ /* USB related */
+ struct usb2_port_config usb2_ports[16];
+ struct usb3_port_config usb3_ports[10];
+ u8 XdciEnable;
+ u8 SsicPortEnable;
+
+ /* SMBus */
+ u8 SmbusEnable;
+
+ /*
+ * SerialIO device mode selection:
+ *
+ * Device index:
+ * PchSerialIoIndexI2C0
+ * PchSerialIoIndexI2C1
+ * PchSerialIoIndexI2C2
+ * PchSerialIoIndexI2C3
+ * PchSerialIoIndexI2C4
+ * PchSerialIoIndexI2C5
+ * PchSerialIoIndexI2C6
+ * PchSerialIoIndexSpi0
+ * PchSerialIoIndexSpi1
+ * PchSerialIoIndexUart0
+ * PchSerialIoIndexUart1
+ * PchSerialIoIndexUart2
+ *
+ * Mode select:
+ * PchSerialIoDisabled
+ * PchSerialIoAcpi
+ * PchSerialIoPci
+ * PchSerialIoAcpiHidden
+ * PchSerialIoLegacyUart
+ */
+ u8 SerialIoDevMode[PchSerialIoIndexMax];
+
+ /* I2C */
+ struct kabylake_i2c_config i2c[KABYLAKE_I2C_DEV_MAX];
+
+ /* Camera */
+ u8 Cio2Enable;
+
+ /* eMMC and SD */
+ u8 ScsEmmcEnabled;
+ u8 ScsEmmcHs400Enabled;
+ u8 ScsSdCardEnabled;
+
+ /* Integrated Sensor */
+ u8 IshEnable;
+
+ u8 PttSwitch;
+ u8 HeciTimeouts;
+ u8 HsioMessaging;
+ u8 Heci3Enabled;
+
+ /* Gfx related */
+ u8 IgdDvmt50PreAlloc;
+ u8 PrimaryDisplay;
+ u8 InternalGfx;
+ u8 ApertureSize;
+ u8 SkipExtGfxScan;
+ u8 ScanExtGfxForLegacyOpRom;
+
+ /*
+ * The following fields come from fsp_vpd.h
+ * These are configuration values that are passed to FSP during
+ * SiliconInit.
+ */
+ u32 LogoPtr;
+ u32 LogoSize;
+ u32 GraphicsConfigPtr;
+ u8 Device4Enable;
+ u8 RtcLock;
+ /* GPIO IRQ Route The valid values is 14 or 15*/
+ u8 GpioIrqSelect;
+ /* SCI IRQ Select The valid values is 9, 10, 11 and 20 21, 22, 23*/
+ u8 SciIrqSelect;
+ /* TCO IRQ Select The valid values is 9, 10, 11, 20 21, 22, 23*/
+ u8 TcoIrqSelect;
+ u8 TcoIrqEnable;
+ /* Enable SMI_LOCK bit to prevent writes to the Global SMI Enable bit.*/
+ u8 LockDownConfigGlobalSmi;
+ /*
+ * Enable BIOS Interface Lock Down bit to prevent writes to the Backup
+ * Control Register. Top Swap bit and the General Control and Status
+ * Registers Boot BIOS Straps.
+ */
+ u8 LockDownConfigBiosInterface;
+ /*
+ * Enable RTC lower and upper 128 byte Lock bits to lock Bytes 38h-3Fh
+ * in the upper and and lower 128-byte bank of RTC RAM.
+ */
+ u8 LockDownConfigRtcLock;
+ /*
+ * When enabled, the BIOS Region can only be modified from SMM after
+ * EndOfDxe protocol is installed
+ */
+ u8 LockDownConfigBiosLock;
+ /*
+ * Enable InSMM.STS (EISS) in SPI If this bit is set, then WPD must be a
+ * '1' and InSMM.STS must be '1' also in order to write to BIOS regions of
+ * SPI Flash. If this bit is clear, then the InSMM.STS is a don't care. The
+ * BIOS must set the EISS bit while BIOS Guard support is enabled.
+ */
+ u8 LockDownConfigSpiEiss;
+ /* Subsystem Vendor ID of the PCH devices*/
+ u16 PchConfigSubSystemVendorId;
+ /* Subsystem ID of the PCH devices*/
+ u16 PchConfigSubSystemId;
+ /*
+ * Corresponds to the "WOL Enable Override" bit in the General PM
+ * Configuration B (GEN_PMCON_B) register
+ */
+ u8 WakeConfigWolEnableOverride;
+ /* Determine if enable PCIe to wake from deep Sx*/
+ u8 WakeConfigPcieWakeFromDeepSx;
+ /* Deep Sx Policy. Values 0: PchDeepSxPolDisable,
+ * 1: PchDpS5BatteryEn, 2: PchDpS5AlwaysEn, 3: PchDpS4S5BatteryEn,
+ * 4: PchDpS4S5AlwaysEn, 5: PchDpS3S4S5BatteryEn, 6: PchDpS3S4S5AlwaysEn
+ */
+ u8 PmConfigDeepSxPol;
+ /*
+ * SLP_S3 Minimum Assertion Width Policy. Values 0: PchSlpS360us,
+ * 1: PchSlpS31ms, 2: PchSlpS350ms, 3: PchSlpS32s.
+ */
+ u8 PmConfigSlpS3MinAssert;
+ /*
+ * SLP_S4 Minimum Assertion Width Policy. Values 0: PchSlpS4PchTime,
+ * 1: PchSlpS41s, 2: PchSlpS42s, 3: PchSlpS43s, 4: PchSlpS44s.
+ */
+ u8 PmConfigSlpS4MinAssert;
+ /*
+ * SLP_SUS Minimum Assertion Width Policy. Values 0: PchSlpSus0ms,
+ * 1: PchSlpSus500ms, 2: PchSlpSus1s, 3: PchSlpSus4s.
+ */
+ u8 PmConfigSlpSusMinAssert;
+ /*
+ * SLP_A Minimum Assertion Width Policy. Values 0: PchSlpA0ms,
+ * 1: PchSlpA4s, 2: PchSlpA98ms, 3: PchSlpA2s.
+ */
+ u8 PmConfigSlpAMinAssert;
+ /*
+ * This member describes whether or not the PCI ClockRun feature of PCH
+ * should be enabled. Values 0: Disabled, 1: Enabled
+ */
+ u8 PmConfigPciClockRun;
+ /*
+ * SLP_X Stretching After SUS Well Power Up. Values 0: Disabled, 1: Enabled
+ */
+ u8 PmConfigSlpStrchSusUp;
+ /*
+ * PCH power button override period.
+ * Values: 0x0 - 4s, 0x1 - 6s, 0x2 - 8s, 0x3 - 10s, 0x4 - 12s, 0x5 - 14s
+ */
+ u8 PmConfigPwrBtnOverridePeriod;
+ /*
+ * Reset Power Cycle Duration could be customized in the unit of second.
+ * PCH HW default is 4 seconds, and range is 1~4 seconds.
+ * Values: 0x0 - 0s, 0x1 - 1s, 0x2 - 2s, 0x3 - 3s, 0x4 - 4s
+ */
+ u8 PmConfigPwrCycDur;
+ /* Determines if enable Serial IRQ. Values 0: Disabled, 1: Enabled.*/
+ u8 SerialIrqConfigSirqEnable;
+ /* Serial IRQ Mode Select. Values: 0: PchQuietMode, 1: PchContinuousMode.*/
+ u8 SerialIrqConfigSirqMode;
+ /*
+ * Start Frame Pulse Width.
+ * Values: 0: PchSfpw4Clk, 1: PchSfpw6Clk, 2; PchSfpw8Clk.
+ */
+ u8 SerialIrqConfigStartFramePulse;
+ u8 FspSkipMpInit;
+ /*
+ * VrConfig Settings for 5 domains
+ * 0 = System Agent, 1 = IA Core, 2 = Ring,
+ * 3 = GT unsliced, 4 = GT sliced
+ */
+ struct vr_config domain_vr_config[NUM_VR_DOMAINS];
+ /*
+ * HeciEnabled decides the state of Heci1 at end of boot
+ * Setting to 0 (default) disables Heci1 and hides the device from OS
+ */
+ u8 HeciEnabled;
+ /* PL2 Override value in Watts */
+ u32 tdp_pl2_override;
+ u8 PmTimerDisabled;
+ /* Intel Speed Shift Technology */
+ u8 speed_shift_enable;
+ /*
+ * Enable VR specific mailbox command
+ * 000b - Don't Send any VR command
+ * 001b - VR command specifically for the MPS IMPV8 VR will be sent
+ * 010b - VR specific command sent for PS4 exit issue
+ * 011b - VR specific command sent for both MPS IMPV8 & PS4 exit issue
+ */
+ u8 SendVrMbxCmd;
+ /* Statically clock gate 8254 PIT. */
+ u8 clock_gate_8254;
+
+ /*
+ * Use SD card detect GPIO with default config:
+ * - Edge triggered
+ * - No internal pull
+ * - Active both (high + low)
+ * - Can wake device from D3
+ * - 100ms debounce timeout
+ *
+ * GpioInt (Edge, ActiveBoth, SharedAndWake, PullNone, 10000,
+ * "\\_SB.PCI0.GPIO", 0, ResourceConsumer)
+ * { sdcard_cd_gpio_default }
+ */
+ unsigned sdcard_cd_gpio_default;
+
+ /* Use custom SD card detect GPIO configuration */
+ struct acpi_gpio sdcard_cd_gpio;
+};
+
+typedef struct soc_intel_kabylake_config config_t;
+
+extern struct chip_operations soc_ops;
+
+#endif
diff --git a/src/soc/intel/kabylake/cpu.c b/src/soc/intel/kabylake/cpu.c
new file mode 100644
index 0000000..c5687b0
--- /dev/null
+++ b/src/soc/intel/kabylake/cpu.c
@@ -0,0 +1,494 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <string.h>
+#include <chip.h>
+#include <cpu/cpu.h>
+#include <cpu/x86/mtrr.h>
+#include <cpu/x86/msr.h>
+#include <cpu/x86/lapic.h>
+#include <cpu/x86/mp.h>
+#include <cpu/intel/microcode.h>
+#include <cpu/intel/speedstep.h>
+#include <cpu/intel/turbo.h>
+#include <cpu/x86/cache.h>
+#include <cpu/x86/name.h>
+#include <cpu/x86/smm.h>
+#include <delay.h>
+#include <pc80/mc146818rtc.h>
+#include <soc/cpu.h>
+#include <soc/msr.h>
+#include <soc/pci_devs.h>
+#include <soc/ramstage.h>
+#include <soc/smm.h>
+#include <soc/systemagent.h>
+
+/* Convert time in seconds to POWER_LIMIT_1_TIME MSR value */
+static const u8 power_limit_time_sec_to_msr[] = {
+ [0] = 0x00,
+ [1] = 0x0a,
+ [2] = 0x0b,
+ [3] = 0x4b,
+ [4] = 0x0c,
+ [5] = 0x2c,
+ [6] = 0x4c,
+ [7] = 0x6c,
+ [8] = 0x0d,
+ [10] = 0x2d,
+ [12] = 0x4d,
+ [14] = 0x6d,
+ [16] = 0x0e,
+ [20] = 0x2e,
+ [24] = 0x4e,
+ [28] = 0x6e,
+ [32] = 0x0f,
+ [40] = 0x2f,
+ [48] = 0x4f,
+ [56] = 0x6f,
+ [64] = 0x10,
+ [80] = 0x30,
+ [96] = 0x50,
+ [112] = 0x70,
+ [128] = 0x11,
+};
+
+/* Convert POWER_LIMIT_1_TIME MSR value to seconds */
+static const u8 power_limit_time_msr_to_sec[] = {
+ [0x00] = 0,
+ [0x0a] = 1,
+ [0x0b] = 2,
+ [0x4b] = 3,
+ [0x0c] = 4,
+ [0x2c] = 5,
+ [0x4c] = 6,
+ [0x6c] = 7,
+ [0x0d] = 8,
+ [0x2d] = 10,
+ [0x4d] = 12,
+ [0x6d] = 14,
+ [0x0e] = 16,
+ [0x2e] = 20,
+ [0x4e] = 24,
+ [0x6e] = 28,
+ [0x0f] = 32,
+ [0x2f] = 40,
+ [0x4f] = 48,
+ [0x6f] = 56,
+ [0x10] = 64,
+ [0x30] = 80,
+ [0x50] = 96,
+ [0x70] = 112,
+ [0x11] = 128,
+};
+
+int cpu_config_tdp_levels(void)
+{
+ msr_t platform_info;
+
+ /* Bits 34:33 indicate how many levels supported */
+ platform_info = rdmsr(MSR_PLATFORM_INFO);
+ return (platform_info.hi >> 1) & 3;
+}
+
+/*
+ * Configure processor power limits if possible
+ * This must be done AFTER set of BIOS_RESET_CPL
+ */
+void set_power_limits(u8 power_limit_1_time)
+{
+ msr_t msr = rdmsr(MSR_PLATFORM_INFO);
+ msr_t limit;
+ unsigned power_unit;
+ unsigned tdp, min_power, max_power, max_time, tdp_pl2;
+ u8 power_limit_1_val;
+ device_t dev = SA_DEV_ROOT;
+ config_t *conf = dev->chip_info;
+
+ if (power_limit_1_time > ARRAY_SIZE(power_limit_time_sec_to_msr))
+ power_limit_1_time = 28;
+
+ if (!(msr.lo & PLATFORM_INFO_SET_TDP))
+ return;
+
+ /* Get units */
+ msr = rdmsr(MSR_PKG_POWER_SKU_UNIT);
+ power_unit = 1 << (msr.lo & 0xf);
+
+ /* Get power defaults for this SKU */
+ msr = rdmsr(MSR_PKG_POWER_SKU);
+ tdp = msr.lo & 0x7fff;
+ min_power = (msr.lo >> 16) & 0x7fff;
+ max_power = msr.hi & 0x7fff;
+ max_time = (msr.hi >> 16) & 0x7f;
+
+ printk(BIOS_DEBUG, "CPU TDP: %u Watts\n", tdp / power_unit);
+
+ if (power_limit_time_msr_to_sec[max_time] > power_limit_1_time)
+ power_limit_1_time = power_limit_time_msr_to_sec[max_time];
+
+ if (min_power > 0 && tdp < min_power)
+ tdp = min_power;
+
+ if (max_power > 0 && tdp > max_power)
+ tdp = max_power;
+
+ power_limit_1_val = power_limit_time_sec_to_msr[power_limit_1_time];
+
+ /* Set long term power limit to TDP */
+ limit.lo = 0;
+ limit.lo |= tdp & PKG_POWER_LIMIT_MASK;
+
+ /* Set PL1 Pkg Power clamp bit */
+ limit.lo |= PKG_POWER_LIMIT_CLAMP;
+
+ limit.lo |= PKG_POWER_LIMIT_EN;
+ limit.lo |= (power_limit_1_val & PKG_POWER_LIMIT_TIME_MASK) <<
+ PKG_POWER_LIMIT_TIME_SHIFT;
+
+ /* Set short term power limit to 1.25 * TDP */
+ limit.hi = 0;
+ tdp_pl2 = (conf->tdp_pl2_override == 0) ?
+ (tdp * 125) / 100 : (conf->tdp_pl2_override * power_unit);
+ limit.hi |= (tdp_pl2) & PKG_POWER_LIMIT_MASK;
+ limit.hi |= PKG_POWER_LIMIT_CLAMP;
+ limit.hi |= PKG_POWER_LIMIT_EN;
+
+ /* Power limit 2 time is only programmable on server SKU */
+ wrmsr(MSR_PKG_POWER_LIMIT, limit);
+
+ /* Set PL2 power limit values in MCHBAR and disable PL1 */
+ MCHBAR32(MCH_PKG_POWER_LIMIT_LO) = limit.lo & (~(PKG_POWER_LIMIT_EN));
+ MCHBAR32(MCH_PKG_POWER_LIMIT_HI) = limit.hi;
+
+ /* Set DDR RAPL power limit by copying from MMIO to MSR */
+ msr.lo = MCHBAR32(MCH_DDR_POWER_LIMIT_LO);
+ msr.hi = MCHBAR32(MCH_DDR_POWER_LIMIT_HI);
+ wrmsr(MSR_DDR_RAPL_LIMIT, msr);
+
+ /* Use nominal TDP values for CPUs with configurable TDP */
+ if (cpu_config_tdp_levels()) {
+ msr = rdmsr(MSR_CONFIG_TDP_NOMINAL);
+ limit.hi = 0;
+ limit.lo = msr.lo & 0xff;
+ wrmsr(MSR_TURBO_ACTIVATION_RATIO, limit);
+ }
+}
+
+static void configure_thermal_target(void)
+{
+ device_t dev = SA_DEV_ROOT;
+ config_t *conf = dev->chip_info;
+ msr_t msr;
+
+ /* Set TCC activaiton offset if supported */
+ msr = rdmsr(MSR_PLATFORM_INFO);
+ if ((msr.lo & (1 << 30)) && conf->tcc_offset) {
+ msr = rdmsr(MSR_TEMPERATURE_TARGET);
+ msr.lo &= ~(0xf << 24); /* Bits 27:24 */
+ msr.lo |= (conf->tcc_offset & 0xf) << 24;
+ wrmsr(MSR_TEMPERATURE_TARGET, msr);
+ }
+}
+
+static void configure_isst(void)
+{
+ device_t dev = SA_DEV_ROOT;
+ config_t *conf = dev->chip_info;
+ msr_t msr;
+
+ if (conf->speed_shift_enable) {
+ /*
+ * Kernel driver checks CPUID.06h:EAX[Bit 7] to determine if HWP
+ is supported or not. Coreboot needs to configure MSR 0x1AA
+ which is then reflected in the CPUID register.
+ */
+ msr = rdmsr(MSR_MISC_PWR_MGMT);
+ msr.lo |= MISC_PWR_MGMT_ISST_EN; /* Enable Speed Shift */
+ msr.lo |= MISC_PWR_MGMT_ISST_EN_INT; /* Enable Interrupt */
+ msr.lo |= MISC_PWR_MGMT_ISST_EN_EPP; /* Enable EPP */
+ wrmsr(MSR_MISC_PWR_MGMT, msr);
+ } else {
+ msr = rdmsr(MSR_MISC_PWR_MGMT);
+ msr.lo &= ~MISC_PWR_MGMT_ISST_EN; /* Disable Speed Shift */
+ msr.lo &= ~MISC_PWR_MGMT_ISST_EN_INT; /* Disable Interrupt */
+ msr.lo &= ~MISC_PWR_MGMT_ISST_EN_EPP; /* Disable EPP */
+ wrmsr(MSR_MISC_PWR_MGMT, msr);
+ }
+}
+
+static void configure_misc(void)
+{
+ msr_t msr;
+
+ msr = rdmsr(IA32_MISC_ENABLE);
+ msr.lo |= (1 << 0); /* Fast String enable */
+ msr.lo |= (1 << 3); /* TM1/TM2/EMTTM enable */
+ msr.lo |= (1 << 16); /* Enhanced SpeedStep Enable */
+ wrmsr(IA32_MISC_ENABLE, msr);
+
+ /* Disable Thermal interrupts */
+ msr.lo = 0;
+ msr.hi = 0;
+ wrmsr(IA32_THERM_INTERRUPT, msr);
+
+ /* Enable package critical interrupt only */
+ msr.lo = 1 << 4;
+ msr.hi = 0;
+ wrmsr(IA32_PACKAGE_THERM_INTERRUPT, msr);
+
+ /* Enable PROCHOT */
+ msr = rdmsr(MSR_POWER_CTL);
+ msr.lo |= (1 << 0); /* Enable Bi-directional PROCHOT as an input*/
+ msr.lo |= (1 << 23); /* Lock it */
+ wrmsr(MSR_POWER_CTL, msr);
+}
+
+static void enable_lapic_tpr(void)
+{
+ msr_t msr;
+
+ msr = rdmsr(MSR_PIC_MSG_CONTROL);
+ msr.lo &= ~(1 << 10); /* Enable APIC TPR updates */
+ wrmsr(MSR_PIC_MSG_CONTROL, msr);
+}
+
+static void configure_dca_cap(void)
+{
+ struct cpuid_result cpuid_regs;
+ msr_t msr;
+
+ /* Check feature flag in CPUID.(EAX=1):ECX[18]==1 */
+ cpuid_regs = cpuid(1);
+ if (cpuid_regs.ecx & (1 << 18)) {
+ msr = rdmsr(IA32_PLATFORM_DCA_CAP);
+ msr.lo |= 1;
+ wrmsr(IA32_PLATFORM_DCA_CAP, msr);
+ }
+}
+
+static void set_max_ratio(void)
+{
+ msr_t msr, perf_ctl;
+
+ perf_ctl.hi = 0;
+
+ /* Check for configurable TDP option */
+ if (get_turbo_state() == TURBO_ENABLED) {
+ msr = rdmsr(MSR_TURBO_RATIO_LIMIT);
+ perf_ctl.lo = (msr.lo & 0xff) << 8;
+ } else if (cpu_config_tdp_levels()) {
+ /* Set to nominal TDP ratio */
+ msr = rdmsr(MSR_CONFIG_TDP_NOMINAL);
+ perf_ctl.lo = (msr.lo & 0xff) << 8;
+ } else {
+ /* Platform Info bits 15:8 give max ratio */
+ msr = rdmsr(MSR_PLATFORM_INFO);
+ perf_ctl.lo = msr.lo & 0xff00;
+ }
+ wrmsr(IA32_PERF_CTL, perf_ctl);
+
+ printk(BIOS_DEBUG, "cpu: frequency set to %d\n",
+ ((perf_ctl.lo >> 8) & 0xff) * CPU_BCLK);
+}
+
+static void set_energy_perf_bias(u8 policy)
+{
+ msr_t msr;
+ int ecx;
+
+ /* Determine if energy efficient policy is supported. */
+ ecx = cpuid_ecx(0x6);
+ if (!(ecx & (1 << 3)))
+ return;
+
+ /* Energy Policy is bits 3:0 */
+ msr = rdmsr(IA32_ENERGY_PERFORMANCE_BIAS);
+ msr.lo &= ~0xf;
+ msr.lo |= policy & 0xf;
+ wrmsr(IA32_ENERGY_PERFORMANCE_BIAS, msr);
+
+ printk(BIOS_DEBUG, "cpu: energy policy set to %u\n", policy);
+}
+
+static void configure_mca(void)
+{
+ msr_t msr;
+ const unsigned int mcg_cap_msr = 0x179;
+ int i;
+ int num_banks;
+
+ msr = rdmsr(mcg_cap_msr);
+ num_banks = msr.lo & 0xff;
+ msr.lo = msr.hi = 0;
+ /*
+ * TODO(adurbin): This should only be done on a cold boot. Also, some
+ * of these banks are core vs package scope. For now every CPU clears
+ * every bank.
+ */
+ for (i = 0; i < num_banks; i++)
+ wrmsr(IA32_MC0_STATUS + (i * 4), msr);
+}
+
+/* All CPUs including BSP will run the following function. */
+static void cpu_core_init(device_t cpu)
+{
+ /* Clear out pending MCEs */
+ configure_mca();
+
+ /* Enable the local cpu apics */
+ enable_lapic_tpr();
+ setup_lapic();
+
+ /* Configure Enhanced SpeedStep and Thermal Sensors */
+ configure_misc();
+
+ /* Configure Intel Speed Shift */
+ configure_isst();
+
+ /* Thermal throttle activation offset */
+ configure_thermal_target();
+
+ /* Enable Direct Cache Access */
+ configure_dca_cap();
+
+ /* Set energy policy */
+ set_energy_perf_bias(ENERGY_POLICY_NORMAL);
+
+ /* Enable Turbo */
+ enable_turbo();
+}
+
+static struct device_operations cpu_dev_ops = {
+ .init = cpu_core_init,
+};
+
+static struct cpu_device_id cpu_table[] = {
+ { X86_VENDOR_INTEL, CPUID_KABYLAKE_C0 },
+ { X86_VENDOR_INTEL, CPUID_KABYLAKE_D0 },
+ { 0, 0 },
+};
+
+static const struct cpu_driver driver __cpu_driver = {
+ .ops = &cpu_dev_ops,
+ .id_table = cpu_table,
+};
+
+/* MP initialization support. */
+static const void *microcode_patch;
+static int ht_disabled;
+
+static void pre_mp_init(void)
+{
+ /* Setup MTRRs based on physical address size. */
+ x86_setup_mtrrs_with_detect();
+ x86_mtrr_check();
+}
+
+static int get_cpu_count(void)
+{
+ msr_t msr;
+ int num_threads;
+ int num_cores;
+
+ msr = rdmsr(CORE_THREAD_COUNT_MSR);
+ num_threads = (msr.lo >> 0) & 0xffff;
+ num_cores = (msr.lo >> 16) & 0xffff;
+ printk(BIOS_DEBUG, "CPU has %u cores, %u threads enabled.\n",
+ num_cores, num_threads);
+
+ ht_disabled = num_threads == num_cores;
+
+ return num_threads;
+}
+
+static void get_microcode_info(const void **microcode, int *parallel)
+{
+ microcode_patch = intel_microcode_find();
+ *microcode = microcode_patch;
+ *parallel = 1;
+}
+
+static int adjust_apic_id(int index, int apic_id)
+{
+ if (ht_disabled)
+ return 2 * index;
+ else
+ return index;
+}
+
+static void per_cpu_smm_trigger(void)
+{
+ /* Relocate the SMM handler. */
+ smm_relocate();
+
+ /* After SMM relocation a 2nd microcode load is required. */
+ intel_microcode_load_unlocked(microcode_patch);
+}
+
+static void post_mp_init(void)
+{
+ /* Set Max Ratio */
+ set_max_ratio();
+
+ /*
+ * Now that all APs have been relocated as well as the BSP let SMIs
+ * start flowing.
+ */
+ southbridge_smm_enable_smi();
+
+ /* Lock down the SMRAM space. */
+#if IS_ENABLED(CONFIG_HAVE_SMI_HANDLER)
+ smm_lock();
+#endif
+}
+
+static const struct mp_ops mp_ops = {
+ .pre_mp_init = pre_mp_init,
+ .get_cpu_count = get_cpu_count,
+ .get_smm_info = smm_info,
+ .get_microcode_info = get_microcode_info,
+ .adjust_cpu_apic_entry = adjust_apic_id,
+ .pre_mp_smm_init = smm_initialize,
+ .per_cpu_smm_trigger = per_cpu_smm_trigger,
+ .relocation_handler = smm_relocation_handler,
+ .post_mp_init = post_mp_init,
+};
+
+void soc_init_cpus(device_t dev)
+{
+ struct bus *cpu_bus = dev->link_list;
+
+ if (mp_init_with_smm(cpu_bus, &mp_ops)) {
+ printk(BIOS_ERR, "MP initialization failure.\n");
+ }
+}
+
+int soc_skip_ucode_update(u32 current_patch_id, u32 new_patch_id)
+{
+ msr_t msr;
+ /* If PRMRR/SGX is supported the FIT microcode load will set the msr
+ * 0x08b with the Patch revision id one less than the id in the
+ * microcode binary. The PRMRR support is indicated in the MSR
+ * MTRRCAP[12]. Check for this feature and avoid reloading the
+ * same microcode during cpu initialization.
+ */
+ msr = rdmsr(MTRR_CAP_MSR);
+ return (msr.lo & PRMRR_SUPPORTED) && (current_patch_id == new_patch_id - 1);
+}
diff --git a/src/soc/intel/kabylake/cpu_info.c b/src/soc/intel/kabylake/cpu_info.c
new file mode 100644
index 0000000..70b47ea
--- /dev/null
+++ b/src/soc/intel/kabylake/cpu_info.c
@@ -0,0 +1,50 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <console/console.h>
+#include <cpu/cpu.h>
+#include <cpu/x86/msr.h>
+#include <soc/cpu.h>
+#include <soc/msr.h>
+#include <soc/ramstage.h>
+#include <soc/systemagent.h>
+
+u32 cpu_family_model(void)
+{
+ return cpuid_eax(1) & 0x0fff0ff0;
+}
+
+u32 cpu_stepping(void)
+{
+ return cpuid_eax(1) & 0xf;
+}
+
+/* Dynamically determine if the part is ULT. */
+int cpu_is_ult(void)
+{
+ static int ult = -1;
+
+ if (ult < 0) {
+ u32 fm = cpu_family_model();
+ if (fm == KABYLAKE_FAMILY_ULT)
+ ult = 1;
+ else
+ ult = 0;
+ }
+
+ return ult;
+}
diff --git a/src/soc/intel/kabylake/dsp.c b/src/soc/intel/kabylake/dsp.c
new file mode 100644
index 0000000..5297900
--- /dev/null
+++ b/src/soc/intel/kabylake/dsp.c
@@ -0,0 +1,33 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2016 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <soc/ramstage.h>
+
+static struct device_operations dsp_dev_ops = {
+ .read_resources = &pci_dev_read_resources,
+ .set_resources = &pci_dev_set_resources,
+ .enable_resources = &pci_dev_enable_resources,
+ .scan_bus = &scan_static_bus,
+ .ops_pci = &soc_pci_ops,
+};
+
+static const struct pci_driver kabylake_dsp __pci_driver = {
+ .ops = &dsp_dev_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = 0x9d70
+};
diff --git a/src/soc/intel/kabylake/elog.c b/src/soc/intel/kabylake/elog.c
new file mode 100644
index 0000000..18efbeb
--- /dev/null
+++ b/src/soc/intel/kabylake/elog.c
@@ -0,0 +1,125 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <bootstate.h>
+#include <cbmem.h>
+#include <console/console.h>
+#include <stdint.h>
+#include <elog.h>
+#include <soc/pm.h>
+#include <soc/pmc.h>
+
+static void pch_log_gpio_gpe(u32 gpe0_sts, u32 gpe0_en, int start)
+{
+ int i;
+
+ gpe0_sts &= gpe0_en;
+
+ for (i = 0; i <= 31; i++) {
+ if (gpe0_sts & (1 << i))
+ elog_add_event_wake(ELOG_WAKE_SOURCE_GPIO, i + start);
+ }
+}
+
+static void pch_log_wake_source(struct chipset_power_state *ps)
+{
+ /* Power Button */
+ if (ps->pm1_sts & PWRBTN_STS)
+ elog_add_event_wake(ELOG_WAKE_SOURCE_PWRBTN, 0);
+
+ /* RTC */
+ if (ps->pm1_sts & RTC_STS)
+ elog_add_event_wake(ELOG_WAKE_SOURCE_RTC, 0);
+
+ /* PCI Express (TODO: determine wake device) */
+ if (ps->pm1_sts & PCIEXPWAK_STS)
+ elog_add_event_wake(ELOG_WAKE_SOURCE_PCIE, 0);
+
+ /* PME (TODO: determine wake device) */
+ if (ps->gpe0_sts[GPE_STD] & PME_STS)
+ elog_add_event_wake(ELOG_WAKE_SOURCE_PME, 0);
+
+ /* Internal PME (TODO: determine wake device) */
+ if (ps->gpe0_sts[GPE_STD] & PME_B0_STS)
+ elog_add_event_wake(ELOG_WAKE_SOURCE_PME_INTERNAL, 0);
+
+ /* SMBUS Wake */
+ if (ps->gpe0_sts[GPE_STD] & SMB_WAK_STS)
+ elog_add_event_wake(ELOG_WAKE_SOURCE_SMBUS, 0);
+
+ /* Log GPIO events in set 1-3 */
+ pch_log_gpio_gpe(ps->gpe0_sts[GPE_31_0], ps->gpe0_en[GPE_31_0], 0);
+ pch_log_gpio_gpe(ps->gpe0_sts[GPE_63_32], ps->gpe0_en[GPE_63_32], 32);
+ pch_log_gpio_gpe(ps->gpe0_sts[GPE_95_64], ps->gpe0_en[GPE_95_64], 64);
+ /* Treat the STD as an extension of GPIO to obtain visibility. */
+ pch_log_gpio_gpe(ps->gpe0_sts[GPE_STD], ps->gpe0_en[GPE_STD], 96);
+}
+
+static void pch_log_power_and_resets(struct chipset_power_state *ps)
+{
+ /* Thermal Trip */
+ if (ps->gblrst_cause[0] & GBLRST_CAUSE0_THERMTRIP)
+ elog_add_event(ELOG_TYPE_THERM_TRIP);
+
+ /* PWR_FLR Power Failure */
+ if (ps->gen_pmcon_b & PWR_FLR)
+ elog_add_event(ELOG_TYPE_POWER_FAIL);
+
+ /* SUS Well Power Failure */
+ if (ps->gen_pmcon_b & SUS_PWR_FLR)
+ elog_add_event(ELOG_TYPE_SUS_POWER_FAIL);
+
+ /* TCO Timeout */
+ if (ps->prev_sleep_state != ACPI_S3 &&
+ ps->tco2_sts & TCO2_STS_SECOND_TO)
+ elog_add_event(ELOG_TYPE_TCO_RESET);
+
+ /* Power Button Override */
+ if (ps->pm1_sts & PRBTNOR_STS)
+ elog_add_event(ELOG_TYPE_POWER_BUTTON_OVERRIDE);
+
+ /* RTC reset */
+ if (ps->gen_pmcon_b & RTC_BATTERY_DEAD)
+ elog_add_event(ELOG_TYPE_RTC_RESET);
+
+ /* Host Reset Status */
+ if (ps->gen_pmcon_b & HOST_RST_STS)
+ elog_add_event(ELOG_TYPE_SYSTEM_RESET);
+
+ /* ACPI Wake Event */
+ if (ps->prev_sleep_state != ACPI_S0)
+ elog_add_event_byte(ELOG_TYPE_ACPI_WAKE, ps->prev_sleep_state);
+}
+
+static void pch_log_state(void *unused)
+{
+ struct chipset_power_state *ps = cbmem_find(CBMEM_ID_POWER_STATE);
+
+ if (ps == NULL) {
+ printk(BIOS_ERR,
+ "Not logging power state information. Power state not found in cbmem.\n");
+ return;
+ }
+
+ /* Power and Reset */
+ pch_log_power_and_resets(ps);
+
+ /* Wake Sources */
+ if (ps->prev_sleep_state > 0)
+ pch_log_wake_source(ps);
+}
+
+BOOT_STATE_INIT_ENTRY(BS_DEV_INIT, BS_ON_ENTRY, pch_log_state, NULL);
diff --git a/src/soc/intel/kabylake/finalize.c b/src/soc/intel/kabylake/finalize.c
new file mode 100644
index 0000000..7713c03
--- /dev/null
+++ b/src/soc/intel/kabylake/finalize.c
@@ -0,0 +1,221 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <arch/io.h>
+#include <bootstate.h>
+#include <chip.h>
+#include <console/console.h>
+#include <console/post_codes.h>
+#include <cpu/x86/smm.h>
+#include <reg_script.h>
+#include <spi-generic.h>
+#include <stdlib.h>
+#include <soc/lpc.h>
+#include <soc/me.h>
+#include <soc/pci_devs.h>
+#include <soc/pcr.h>
+#include <soc/pm.h>
+#include <soc/pmc.h>
+#include <soc/spi.h>
+#include <soc/systemagent.h>
+#include <device/pci.h>
+#include <chip.h>
+
+#define PCH_P2SB_EPMASK0 0xB0
+#define PCH_P2SB_EPMASK(mask_number) PCH_P2SB_EPMASK0 + (mask_number * 4)
+
+#define PCH_P2SB_E0 0xE0
+#define PCH_PWRM_ACPI_TMR_CTL 0xFC
+
+static void pch_configure_endpoints(device_t dev, int epmask_id, uint32_t mask)
+{
+ uint32_t reg32;
+
+ reg32 = pci_read_config32(dev, PCH_P2SB_EPMASK(epmask_id));
+ pci_write_config32(dev, PCH_P2SB_EPMASK(epmask_id), reg32 | mask);
+}
+
+static void pch_disable_heci(void)
+{
+ device_t dev;
+ u8 reg8;
+ uint32_t mask;
+
+ dev = PCH_DEV_P2SB;
+
+ /*
+ * if p2sb device 1f.1 is not present or hidden in devicetree
+ * p2sb device becomes NULL
+ */
+ if (!dev)
+ return;
+
+ /* unhide p2sb device */
+ pci_write_config8(dev, PCH_P2SB_E0 + 1, 0);
+
+ /* disable heci */
+ pcr_andthenor32(PID_PSF1, PSF_BASE_ADDRESS + PCH_PCR_PSFX_T0_SHDW_PCIEN,
+ ~0, PCH_PCR_PSFX_T0_SHDW_PCIEN_FUNDIS);
+
+ /* Remove the host accessing right to PSF register range. */
+ /* Set p2sb PCI offset EPMASK5 C4h [29, 28, 27, 26] to [1, 1, 1, 1] */
+ mask = (1 << 29) | (1 << 28) | (1 << 27) | (1 << 26);
+ pch_configure_endpoints(dev, 5, mask);
+
+ /* Set the "Endpoint Mask Lock!", P2SB PCI offset E2h bit[1] to 1. */
+ reg8 = pci_read_config8(dev, PCH_P2SB_E0 + 2);
+ pci_write_config8(dev, PCH_P2SB_E0 + 2, reg8 | (1 << 1));
+
+ /* hide p2sb device */
+ pci_write_config8(dev, PCH_P2SB_E0 + 1, 1);
+}
+
+static void pch_finalize_script(void)
+{
+ device_t dev;
+ uint32_t reg32, hsfs;
+ void *spibar = get_spi_bar();
+ u16 tcobase;
+ u16 tcocnt;
+ uint8_t *pmcbase;
+ config_t *config;
+ u32 pmsyncreg;
+ u8 reg8;
+
+ /* Set SPI opcode menu */
+ write16(spibar + SPIBAR_PREOP, SPI_OPPREFIX);
+ write16(spibar + SPIBAR_OPTYPE, SPI_OPTYPE);
+ write32(spibar + SPIBAR_OPMENU_LOWER, SPI_OPMENU_LOWER);
+ write32(spibar + SPIBAR_OPMENU_UPPER, SPI_OPMENU_UPPER);
+ /* Lock SPIBAR */
+ hsfs = read32(spibar + SPIBAR_HSFS);
+ hsfs |= SPIBAR_HSFS_FLOCKDN;
+ write32(spibar + SPIBAR_HSFS, hsfs);
+
+ /*TCO Lock down */
+ tcobase = pmc_tco_regs();
+ tcocnt = inw(tcobase + TCO1_CNT);
+ tcocnt |= TCO_LOCK;
+ outw(tcocnt, tcobase + TCO1_CNT);
+
+ /* Lock down ABASE and sleep stretching policy */
+ dev = PCH_DEV_PMC;
+ reg32 = pci_read_config32(dev, GEN_PMCON_B);
+ reg32 |= (SLP_STR_POL_LOCK | ACPI_BASE_LOCK);
+ pci_write_config32(dev, GEN_PMCON_B, reg32);
+
+ /* PMSYNC */
+ pmcbase = pmc_mmio_regs();
+ pmsyncreg = read32(pmcbase + PMSYNC_TPR_CFG);
+ pmsyncreg |= PMSYNC_LOCK;
+ write32(pmcbase + PMSYNC_TPR_CFG, pmsyncreg);
+
+ /* Display me status before we hide it */
+ intel_me_status();
+
+ /* we should disable Heci1 based on the devicetree policy */
+ config = dev->chip_info;
+
+ /*
+ * Disable ACPI PM timer based on dt policy
+ *
+ * Disabling ACPI PM timer is necessary for XTAL OSC shutdown.
+ * Disabling ACPI PM timer also switches off TCO
+ */
+
+ if (config->PmTimerDisabled) {
+ reg8 = read8(pmcbase + PCH_PWRM_ACPI_TMR_CTL);
+ reg8 |= (1 << 1);
+ write8(pmcbase + PCH_PWRM_ACPI_TMR_CTL, reg8);
+ }
+
+ /* we should disable Heci1 based on the devicetree policy */
+ if (config->HeciEnabled == 0)
+ pch_disable_heci();
+}
+
+static void soc_lockdown(void)
+{
+ u8 reg8;
+ device_t dev;
+ const struct device *dev1 = dev_find_slot(0, PCH_DEVFN_LPC);
+ const struct soc_intel_kabylake_config *config = dev1->chip_info;
+
+ /* Global SMI Lock */
+ if (config->LockDownConfigGlobalSmi == 0) {
+ dev = PCH_DEV_PMC;
+ reg8 = pci_read_config8(dev, GEN_PMCON_A);
+ reg8 |= SMI_LOCK;
+ pci_write_config8(dev, GEN_PMCON_A, reg8);
+ }
+
+ /* Bios Interface Lock */
+ if (config->LockDownConfigBiosInterface == 0) {
+ pci_write_config8(PCH_DEV_LPC, BIOS_CNTL,
+ pci_read_config8(PCH_DEV_LPC,
+ BIOS_CNTL) | LPC_BC_BILD);
+ /* Reads back for posted write to take effect */
+ pci_read_config8(PCH_DEV_LPC, BIOS_CNTL);
+ pci_write_config32(PCH_DEV_SPI, SPIBAR_BIOS_CNTL,
+ pci_read_config32(PCH_DEV_SPI,
+ SPIBAR_BIOS_CNTL) |
+ SPIBAR_BC_BILD);
+ /* Reads back for posted write to take effect */
+ pci_read_config32(PCH_DEV_SPI, SPIBAR_BIOS_CNTL);
+ /* GCS reg of DMI */
+ pcr_andthenor8(PID_DMI, R_PCH_PCR_DMI_GCS, 0xFF,
+ B_PCH_PCR_DMI_GCS_BILD);
+ }
+
+ /* Bios Lock */
+ if (config->LockDownConfigBiosLock == 0) {
+ pci_write_config8(PCH_DEV_LPC, BIOS_CNTL,
+ pci_read_config8(PCH_DEV_LPC,
+ BIOS_CNTL) | LPC_BC_LE);
+ pci_write_config8(PCH_DEV_SPI, BIOS_CNTL,
+ pci_read_config8(PCH_DEV_SPI,
+ BIOS_CNTL) | SPIBAR_BC_LE);
+ }
+
+ /* SPIEiss */
+ if (config->LockDownConfigSpiEiss == 0) {
+ pci_write_config8(PCH_DEV_LPC, BIOS_CNTL,
+ pci_read_config8(PCH_DEV_LPC,
+ BIOS_CNTL) | LPC_BC_EISS);
+ pci_write_config8(PCH_DEV_SPI, BIOS_CNTL,
+ pci_read_config8(PCH_DEV_SPI,
+ SPIBAR_BIOS_CNTL) |
+ SPIBAR_BC_EISS);
+ }
+}
+
+static void soc_finalize(void *unused)
+{
+ printk(BIOS_DEBUG, "Finalizing chipset.\n");
+
+ pch_finalize_script();
+
+ soc_lockdown();
+
+ printk(BIOS_DEBUG, "Finalizing SMM.\n");
+ outb(APM_CNT_FINALIZE, APM_CNT);
+
+ /* Indicate finalize step with post code */
+ post_code(POST_OS_BOOT);
+}
+
+BOOT_STATE_INIT_ENTRY(BS_OS_RESUME, BS_ON_ENTRY, soc_finalize, NULL);
+BOOT_STATE_INIT_ENTRY(BS_PAYLOAD_LOAD, BS_ON_EXIT, soc_finalize, NULL);
diff --git a/src/soc/intel/kabylake/flash_controller.c b/src/soc/intel/kabylake/flash_controller.c
new file mode 100644
index 0000000..388c31a
--- /dev/null
+++ b/src/soc/intel/kabylake/flash_controller.c
@@ -0,0 +1,437 @@
+/*
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/* This file is derived from the flashrom project. */
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <bootstate.h>
+#include <spi_flash.h>
+#include <timer.h>
+#include <soc/flash_controller.h>
+#include <soc/pci_devs.h>
+#include <soc/spi.h>
+
+static inline uint16_t spi_read_hsfs(pch_spi_regs * const regs)
+{
+ return readw_(®s->hsfs);
+}
+
+static inline void spi_clear_status(pch_spi_regs * const regs)
+{
+ /* clear FDONE, FCERR, AEL by writing 1 to them (if they are set) */
+ writew_(spi_read_hsfs(regs), ®s->hsfs);
+}
+
+static inline uint16_t spi_read_hsfc(pch_spi_regs * const regs)
+{
+ return readw_(®s->hsfc);
+}
+
+static inline uint32_t spi_read_faddr(pch_spi_regs * const regs)
+{
+ return readl_(®s->faddr) & SPIBAR_FADDR_MASK;
+}
+
+/*
+ * Polls for Cycle Done Status, Flash Cycle Error
+ * Resets all error flags in HSFS.
+ * Returns 0 if the cycle completes successfully without errors within
+ * timeout, 1 on errors.
+ */
+static int wait_for_completion(pch_spi_regs * const regs, int timeout_ms,
+ size_t len)
+{
+ uint16_t hsfs;
+ uint16_t hsfc;
+ uint32_t addr;
+ struct stopwatch sw;
+ int timeout = 0;
+
+ stopwatch_init_msecs_expire(&sw, timeout_ms);
+
+ do {
+ hsfs = spi_read_hsfs(regs);
+
+ if ((hsfs & (HSFS_FDONE | HSFS_FCERR)))
+ break;
+ } while (!(timeout = stopwatch_expired(&sw)));
+
+ if (timeout) {
+ addr = spi_read_faddr(regs);
+ hsfc = spi_read_hsfc(regs);
+ printk(BIOS_ERR, "%ld ms Transaction timeout between offset "
+ "0x%08x and 0x%08zx (= 0x%08x + %zd) HSFC=%x HSFS=%x!\n",
+ stopwatch_duration_msecs(&sw), addr, addr + len - 1,
+ addr, len - 1, hsfc, hsfs);
+ return 1;
+ }
+
+ if (hsfs & HSFS_FCERR) {
+ addr = spi_read_faddr(regs);
+ hsfc = spi_read_hsfc(regs);
+ printk(BIOS_ERR, "Transaction error between offset 0x%08x and "
+ "0x%08zx (= 0x%08x + %zd) HSFC=%x HSFS=%x!\n",
+ addr, addr + len - 1, addr, len - 1,
+ hsfc, hsfs);
+ return 1;
+ }
+
+ return 0;
+}
+
+/* Start operation returning 0 on success, non-zero on error or timeout. */
+static int spi_do_operation(int op, size_t offset, size_t size, int timeout_ms)
+{
+ uint16_t hsfc;
+ pch_spi_regs * const regs = get_spi_bar();
+
+ /* Clear status prior to operation. */
+ spi_clear_status(regs);
+
+ /* Set the FADDR */
+ writel_(offset & SPIBAR_FADDR_MASK, ®s->faddr);
+
+ hsfc = readw_(®s->hsfc);
+ /* Clear then set the correct op. */
+ hsfc &= ~HSFC_FCYCLE_MASK;
+ hsfc |= op;
+ /* Set the size field */
+ hsfc &= ~HSFC_FDBC_MASK;
+ /* Check for sizes of confirming operations. */
+ if (size && size <= SPI_FDATA_BYTES)
+ hsfc |= ((size - 1) << HSFC_FDBC_SHIFT) & HSFC_FDBC_MASK;
+ /* start operation */
+ hsfc |= HSFC_FGO;
+ writew_(hsfc, ®s->hsfc);
+
+ return wait_for_completion(regs, timeout_ms, size);
+}
+
+unsigned int spi_crop_chunk(unsigned int cmd_len, unsigned int buf_len)
+{
+ return min(SPI_FDATA_BYTES, buf_len);
+}
+
+static size_t spi_get_flash_size(pch_spi_regs *spi_bar)
+{
+ uint32_t flcomp;
+ size_t size;
+
+ writel_(SPIBAR_FDOC_COMPONENT, &spi_bar->fdoc);
+ flcomp = readl_(&spi_bar->fdod);
+
+ switch (flcomp & FLCOMP_C0DEN_MASK) {
+ case FLCOMP_C0DEN_8MB:
+ size = 8*MiB;
+ break;
+ case FLCOMP_C0DEN_16MB:
+ size = 16*MiB;
+ break;
+ case FLCOMP_C0DEN_32MB:
+ size = 32*MiB;
+ break;
+ default:
+ size = 16*MiB;
+ }
+
+ return size;
+}
+
+int spi_xfer(struct spi_slave *slave, const void *dout,
+ unsigned int bytesout, void *din, unsigned int bytesin)
+{
+ /* TODO: Define xfer for hardware sequencing. */
+ return -1;
+}
+
+void spi_init(void)
+{
+ uint8_t bios_cntl;
+ device_t dev = PCH_DEV_SPI;
+
+ /* Disable the BIOS write protect so write commands are allowed. */
+ pci_read_config_byte(dev, SPIBAR_BIOS_CNTL, &bios_cntl);
+ bios_cntl &= ~SPIBAR_BC_EISS;
+ bios_cntl |= SPIBAR_BC_WPD;
+ pci_write_config_byte(dev, SPIBAR_BIOS_CNTL, bios_cntl);
+}
+
+int spi_claim_bus(struct spi_slave *slave)
+{
+ /* Handled by PCH automatically. */
+ return 0;
+}
+
+void spi_release_bus(struct spi_slave *slave)
+{
+ /* Handled by PCH automatically. */
+}
+
+int pch_hwseq_erase(struct spi_flash *flash, u32 offset, size_t len)
+{
+ u32 start, end, erase_size;
+ int ret = 0;
+
+ erase_size = flash->sector_size;
+ if (offset % erase_size || len % erase_size) {
+ printk(BIOS_ERR, "SF: Erase offset/length not multiple of erase size\n");
+ return -1;
+ }
+
+ flash->spi->rw = SPI_WRITE_FLAG;
+
+ start = offset;
+ end = start + len;
+
+ while (offset < end) {
+ if (spi_do_operation(HSFC_FCYCLE_4KE, offset, 0, 5000)) {
+ printk(BIOS_ERR, "SF: Erase failed at %x\n", offset);
+ ret = -1;
+ goto out;
+ }
+
+ offset += erase_size;
+ }
+
+ printk(BIOS_DEBUG, "SF: Successfully erased %zu bytes @ %#x\n",
+ len, start);
+
+out:
+ spi_release_bus(flash->spi);
+ return ret;
+}
+
+static void pch_read_data(uint8_t *data, int len)
+{
+ int i;
+ pch_spi_regs *spi_bar;
+ uint32_t temp32 = 0;
+
+ spi_bar = get_spi_bar();
+
+ for (i = 0; i < len; i++) {
+ if ((i % 4) == 0)
+ temp32 = readl_((uint8_t *)spi_bar->fdata + i);
+
+ data[i] = (temp32 >> ((i % 4) * 8)) & 0xff;
+ }
+}
+
+int pch_hwseq_read(struct spi_flash *flash, u32 addr, size_t len, void *buf)
+{
+ uint8_t block_len;
+
+ if (addr + len > spi_get_flash_size(get_spi_bar())) {
+ printk(BIOS_ERR,
+ "Attempt to read %x-%x which is out of chip\n",
+ (unsigned) addr,
+ (unsigned) addr+(unsigned) len);
+ return -1;
+ }
+
+ while (len > 0) {
+ const int timeout_ms = 6;
+
+ block_len = min(len, SPI_FDATA_BYTES);
+ if (block_len > (~addr & 0xff))
+ block_len = (~addr & 0xff) + 1;
+
+ if (spi_do_operation(HSFC_FCYCLE_RD, addr, block_len,
+ timeout_ms))
+ return -1;
+
+ pch_read_data(buf, block_len);
+ addr += block_len;
+ buf += block_len;
+ len -= block_len;
+ }
+ return 0;
+}
+
+/* Fill len bytes from the data array into the fdata/spid registers.
+ *
+ * Note that using len > flash->pgm->spi.max_data_write will trash the registers
+ * following the data registers.
+ */
+static void pch_fill_data(const uint8_t *data, int len)
+{
+ uint32_t temp32 = 0;
+ int i;
+ pch_spi_regs *spi_bar;
+
+ spi_bar = get_spi_bar();
+ if (len <= 0)
+ return;
+
+ for (i = 0; i < len; i++) {
+ if ((i % 4) == 0)
+ temp32 = 0;
+
+ temp32 |= ((uint32_t) data[i]) << ((i % 4) * 8);
+
+ if ((i % 4) == 3) /* 32 bits are full, write them to regs. */
+ writel_(temp32,
+ (uint8_t *)spi_bar->fdata + (i - (i % 4)));
+ }
+ i--;
+ if ((i % 4) != 3) /* Write remaining data to regs. */
+ writel_(temp32, (uint8_t *)spi_bar->fdata + (i - (i % 4)));
+}
+
+int pch_hwseq_write(struct spi_flash *flash,
+ u32 addr, size_t len, const void *buf)
+{
+ uint8_t block_len;
+ uint32_t start = addr;
+ pch_spi_regs *spi_bar;
+
+ spi_bar = get_spi_bar();
+
+ if (addr + len > spi_get_flash_size(spi_bar)) {
+ printk(BIOS_ERR,
+ "Attempt to write 0x%x-0x%x which is out of chip\n",
+ (unsigned)addr, (unsigned) (addr+len));
+ return -1;
+ }
+
+ while (len > 0) {
+ const int timeout_ms = 6;
+
+ block_len = min(len, sizeof(spi_bar->fdata));
+ if (block_len > (~addr & 0xff))
+ block_len = (~addr & 0xff) + 1;
+
+ pch_fill_data(buf, block_len);
+ if (spi_do_operation(HSFC_FCYCLE_WR, addr, block_len,
+ timeout_ms)) {
+ printk(BIOS_ERR, "SF: write failure at %x\n", addr);
+ return -1;
+ }
+ addr += block_len;
+ buf += block_len;
+ len -= block_len;
+ }
+ printk(BIOS_DEBUG, "SF: Successfully written %u bytes @ %#x\n",
+ (unsigned) (addr - start), start);
+ return 0;
+}
+
+int pch_hwseq_read_status(struct spi_flash *flash, u8 *reg)
+{
+ size_t block_len = SPI_READ_STATUS_LENGTH;
+ const int timeout_ms = 6;
+
+ if (spi_do_operation(HSFC_FCYCLE_RS, 0, block_len, timeout_ms))
+ return -1;
+
+ pch_read_data(reg, block_len);
+
+ return 0;
+}
+
+static struct spi_flash *spi_flash_hwseq_probe(struct spi_slave *spi)
+{
+ struct spi_flash *flash;
+
+ flash = malloc(sizeof(*flash));
+ if (!flash) {
+ printk(BIOS_WARNING, "SF: Failed to allocate memory\n");
+ return NULL;
+ }
+
+ flash->spi = spi;
+ flash->name = "Opaque HW-sequencing";
+
+ flash->write = pch_hwseq_write;
+ flash->erase = pch_hwseq_erase;
+ flash->read = pch_hwseq_read;
+ flash->status = pch_hwseq_read_status;
+
+ /* The hardware sequencing supports 4KiB or 64KiB erase. Use 4KiB. */
+ flash->sector_size = 4*KiB;
+
+ flash->size = spi_get_flash_size(get_spi_bar());
+
+ return flash;
+}
+
+struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs)
+{
+ struct spi_slave *slave = malloc(sizeof(*slave));
+
+ if (!slave) {
+ printk(BIOS_DEBUG, "PCH SPI: Bad allocation\n");
+ return NULL;
+ }
+
+ memset(slave, 0, sizeof(*slave));
+
+ slave->bus = bus;
+ slave->cs = cs;
+ slave->force_programmer_specific = 1;
+ slave->programmer_specific_probe = spi_flash_hwseq_probe;
+
+ return slave;
+}
+
+int spi_flash_protect(u32 start, u32 size)
+{
+ pch_spi_regs *spi_bar = get_spi_bar();
+ u32 end = start + size - 1;
+ u32 reg;
+ int prr;
+
+ if (!spi_bar)
+ return -1;
+
+ /* Find first empty PRR */
+ for (prr = 0; prr < SPI_PRR_MAX; prr++) {
+ reg = read32(&spi_bar->pr[prr]);
+ if (reg == 0)
+ break;
+ }
+ if (prr >= SPI_PRR_MAX) {
+ printk(BIOS_ERR, "ERROR: No SPI PRR free!\n");
+ return -1;
+ }
+
+ /* Set protected range base and limit */
+ reg = SPI_PRR(start, end) | SPI_PRR_WPE;
+
+ /* Set the PRR register and verify it is protected */
+ write32(&spi_bar->pr[prr], reg);
+ reg = read32(&spi_bar->pr[prr]);
+ if (!(reg & SPI_PRR_WPE)) {
+ printk(BIOS_ERR, "ERROR: Unable to set SPI PRR %d\n", prr);
+ return -1;
+ }
+
+ printk(BIOS_INFO, "%s: PRR %d is enabled for range 0x%08x-0x%08x\n",
+ __func__, prr, start, end);
+ return 0;
+}
+
+#if ENV_RAMSTAGE
+/*
+ * spi_init() needs run unconditionally in every boot (including resume) to
+ * allow write protect to be disabled for eventlog and firmware updates.
+ */
+static void spi_init_cb(void *unused)
+{
+ spi_init();
+}
+
+BOOT_STATE_INIT_ENTRY(BS_PRE_DEVICE, BS_ON_ENTRY, spi_init_cb, NULL);
+#endif
diff --git a/src/soc/intel/kabylake/fsp_reset.c b/src/soc/intel/kabylake/fsp_reset.c
new file mode 100644
index 0000000..cb716af
--- /dev/null
+++ b/src/soc/intel/kabylake/fsp_reset.c
@@ -0,0 +1,62 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#include <bootstate.h>
+#include <vendorcode/google/chromeos/vboot_handoff.h>
+
+static int is_recovery; /* flag to identify recovery mode */
+
+/*
+ * coreboot used to clear recovery status towards romstage end after FSP
+ * memory init. Later inside FSP silicon init due to HSIO CRC mismatch
+ * or other silicon related programming may request for an additional
+ * reset. Thus on the next boot the system resumed in normal mode rather than
+ * recovery because it lost its original state due to FSP silicon init reset.
+ * Hence it needs an addition reset to get into old state and continue
+ * booting into recovery mode. This function will set recovery reason
+ * during Silicon init, in case of recovery mode booting,
+ * so, system will not lose its original context.
+ */
+static void set_recovery_request(void *unused)
+{
+ is_recovery = recovery_mode_enabled();
+ /*
+ * Set recovery flag during Recovery Mode Silicon Init
+ * & store recovery request into VBNV
+ */
+ if (is_recovery)
+ set_recovery_mode_into_vbnv(vboot_recovery_reason());
+
+}
+
+static void clear_recovery_request(void *unused)
+{
+ /*
+ * Done with Silicon Init, it's safe to clear
+ * reset request now with assumption that no reset occurs hereafter
+ * so we will not miss original data.
+ */
+ if (is_recovery)
+ set_recovery_mode_into_vbnv(0);
+}
+/*
+ * On Recovery Path Set Recovery Request during early RAMSTAGE
+ * before initiated Silicon Init
+ */
+BOOT_STATE_INIT_ENTRY(BS_PRE_DEVICE, BS_ON_ENTRY, set_recovery_request, NULL);
+/*
+ * On Recovery Path Clear Recovery Request during early RAMSTAGE
+ * end of Silicon Init
+ */
+BOOT_STATE_INIT_ENTRY(BS_DEV_INIT_CHIPS, BS_ON_EXIT, clear_recovery_request, NULL);
diff --git a/src/soc/intel/kabylake/gpio.c b/src/soc/intel/kabylake/gpio.c
new file mode 100644
index 0000000..ad0c1f3
--- /dev/null
+++ b/src/soc/intel/kabylake/gpio.c
@@ -0,0 +1,415 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include <arch/io.h>
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <gpio.h>
+#include <soc/pcr.h>
+#include <soc/iomap.h>
+#include <soc/pm.h>
+
+static const int gpio_debug = 0;
+
+/* There are 4 communities with 8 GPIO groups (GPP_[A:G] and GPD) */
+struct gpio_community {
+ int port_id;
+ /* Inclusive pads within the community. */
+ gpio_t min;
+ gpio_t max;
+};
+
+/* This is ordered to match ACPI and OS driver. */
+static const struct gpio_community communities[] = {
+ {
+ .port_id = PID_GPIOCOM0,
+ .min = GPP_A0,
+ .max = GPP_B23,
+ },
+ {
+ .port_id = PID_GPIOCOM1,
+ .min = GPP_C0,
+ .max = GPP_E23,
+ },
+ {
+ .port_id = PID_GPIOCOM3,
+ .min = GPP_F0,
+ .max = GPP_G7,
+ },
+ {
+ .port_id = PID_GPIOCOM2,
+ .min = GPD0,
+ .max = GPD11,
+ },
+};
+
+static const char *gpio_group_names[GPIO_NUM_GROUPS] = {
+ "GPP_A",
+ "GPP_B",
+ "GPP_C",
+ "GPP_D",
+ "GPP_E",
+ "GPP_F",
+ "GPP_G",
+ "GPD",
+};
+
+static inline size_t gpios_in_community(const struct gpio_community *comm)
+{
+ /* max is inclusive */
+ return comm->max - comm->min + 1;
+}
+
+static inline size_t groups_in_community(const struct gpio_community *comm)
+{
+ size_t n = gpios_in_community(comm) + GPIO_MAX_NUM_PER_GROUP - 1;
+ return n / GPIO_MAX_NUM_PER_GROUP;
+}
+
+static inline int gpio_index_gpd(gpio_t gpio)
+{
+ if (gpio >= GPD0 && gpio <= GPD11)
+ return 1;
+ return 0;
+}
+
+static const struct gpio_community *gpio_get_community(gpio_t pad)
+{
+ size_t i;
+
+ for (i = 0; i < ARRAY_SIZE(communities); i++) {
+ const struct gpio_community *c = &communities[i];
+
+ if (pad >= c->min && pad <= c->max)
+ return c;
+ }
+
+ return NULL;
+}
+
+static size_t community_clr_get_smi_sts(const struct gpio_community *comm,
+ uint32_t *sts)
+{
+ uint8_t *regs;
+ size_t i;
+ uint32_t *gpi_status_reg;
+ uint32_t *gpi_en_reg;
+ const size_t num_grps = groups_in_community(comm);
+
+ /* Not all groups can be routed to SMI. However, the registers
+ * read as 0. In order to simplify the logic read everything from
+ * each community. */
+ regs = pcr_port_regs(comm->port_id);
+ gpi_status_reg = (void *)®s[GPI_SMI_STS_OFFSET];
+ gpi_en_reg = (void *)®s[GPI_SMI_EN_OFFSET];
+ for (i = 0; i < num_grps; i++) {
+ sts[i] = read32(gpi_status_reg + i) & read32(gpi_en_reg + i);
+ /* Clear the enabled and set status bits. */
+ write32(gpi_status_reg + i, sts[i]);
+ }
+
+ return num_grps;
+}
+
+static void print_gpi_status(uint32_t status, const char *grp_name)
+{
+ int i;
+
+ if (!status)
+ return;
+
+ for (i = 31; i >= 0; i--) {
+ if (status & (1 << i))
+ printk(BIOS_DEBUG, "%s%d ", grp_name, i);
+ }
+}
+
+void gpi_clear_get_smi_status(struct gpi_status *sts)
+{
+ int i;
+ int do_print;
+ size_t sts_index = 0;
+
+ for (i = 0; i < ARRAY_SIZE(communities); i++) {
+ const struct gpio_community *comm = &communities[i];
+ sts_index += community_clr_get_smi_sts(comm,
+ &sts->grp[sts_index]);
+ }
+
+ do_print = 0;
+ for (i = 0; i < ARRAY_SIZE(sts->grp); i++) {
+ if (sts->grp[i] == 0)
+ continue;
+ do_print = 1;
+ break;
+ }
+
+ if (!do_print)
+ return;
+
+ printk(BIOS_DEBUG, "GPI_SMI_STS: ");
+ for (i = 0; i < ARRAY_SIZE(sts->grp); i++)
+ print_gpi_status(sts->grp[i], gpio_group_names[i]);
+ printk(BIOS_DEBUG, "\n");
+}
+
+int gpi_status_get(const struct gpi_status *sts, gpio_t gpi)
+{
+ const uint32_t *gpi_sts;
+
+ /* Check if valid gpi */
+ if (gpio_get_community(gpi) == NULL)
+ return 0;
+
+ /* If not in GPD group the index is a linear function based on
+ * GPI number and GPIO_MAX_NUM_PER_GROUP. */
+ if (gpio_index_gpd(gpi))
+ gpi_sts = &sts->grp[GPD];
+ else
+ gpi_sts = &sts->grp[gpi / GPIO_MAX_NUM_PER_GROUP];
+
+ return !!(*gpi_sts & (1 << (gpi % GPIO_MAX_NUM_PER_GROUP)));
+}
+
+void gpio_route_gpe(uint16_t gpe0_route)
+{
+ int i;
+ uint32_t misc_cfg;
+ const uint32_t misc_cfg_reg_mask = GPE_DW_MASK;
+
+ misc_cfg = (uint32_t)gpe0_route << GPE_DW_SHIFT;
+ misc_cfg &= misc_cfg_reg_mask;
+
+ for (i = 0; i < ARRAY_SIZE(communities); i++) {
+ uint8_t *regs;
+ uint32_t reg;
+ const struct gpio_community *comm = &communities[i];
+
+ regs = pcr_port_regs(comm->port_id);
+
+ reg = read32(regs + MISCCFG_OFFSET);
+ reg &= ~misc_cfg_reg_mask;
+ reg |= misc_cfg;
+ write32(regs + MISCCFG_OFFSET, reg);
+ }
+}
+
+static void *gpio_dw_regs(gpio_t pad)
+{
+ const struct gpio_community *comm;
+ uint8_t *regs;
+ size_t pad_relative;
+
+ comm = gpio_get_community(pad);
+
+ if (comm == NULL)
+ return NULL;
+
+ regs = pcr_port_regs(comm->port_id);
+
+ pad_relative = pad - comm->min;
+
+ /* DW0 and DW1 regs are 4 bytes each. */
+ return ®s[PAD_CFG_DW_OFFSET + pad_relative * 8];
+}
+
+static void *gpio_hostsw_reg(gpio_t pad, size_t *bit)
+{
+ const struct gpio_community *comm;
+ uint8_t *regs;
+ size_t pad_relative;
+
+ comm = gpio_get_community(pad);
+
+ if (comm == NULL)
+ return NULL;
+
+ regs = pcr_port_regs(comm->port_id);
+
+ pad_relative = pad - comm->min;
+
+ /* Update the bit for this pad. */
+ *bit = (pad_relative % HOSTSW_OWN_PADS_PER);
+
+ /* HostSw regs are 4 bytes each. */
+ regs = ®s[HOSTSW_OWN_REG_OFFSET];
+ return ®s[(pad_relative / HOSTSW_OWN_PADS_PER) * 4];
+}
+
+static void gpio_handle_pad_mode(const struct pad_config *cfg)
+{
+ size_t bit;
+ uint32_t *hostsw_own_reg;
+ uint32_t reg;
+
+ bit = 0;
+ hostsw_own_reg = gpio_hostsw_reg(cfg->pad, &bit);
+
+ if (hostsw_own_reg == NULL)
+ return;
+
+ reg = read32(hostsw_own_reg);
+ reg &= ~(1U << bit);
+
+ if ((cfg->attrs & PAD_FIELD(HOSTSW, GPIO)) == PAD_FIELD(HOSTSW, GPIO))
+ reg |= (HOSTSW_GPIO << bit);
+ else
+ reg |= (HOSTSW_ACPI << bit);
+
+ write32(hostsw_own_reg, reg);
+}
+
+static void gpi_enable_smi(gpio_t pad)
+{
+ const struct gpio_community *comm;
+ uint8_t *regs;
+ uint32_t *gpi_status_reg;
+ uint32_t *gpi_en_reg;
+ size_t group_offset;
+ uint32_t pad_mask;
+
+ comm = gpio_get_community(pad);
+ if (comm == NULL)
+ return;
+ regs = pcr_port_regs(comm->port_id);
+ gpi_status_reg = (void *)®s[GPI_SMI_STS_OFFSET];
+ gpi_en_reg = (void *)®s[GPI_SMI_EN_OFFSET];
+
+ /* Offset of SMI STS/EN for this pad's group within the community. */
+ group_offset = (pad - comm->min) / GPIO_MAX_NUM_PER_GROUP;
+
+ /* Clear status then set enable. */
+ pad_mask = 1 << ((pad - comm->min) % GPIO_MAX_NUM_PER_GROUP);
+ write32(&gpi_status_reg[group_offset], pad_mask);
+ write32(&gpi_en_reg[group_offset],
+ read32(&gpi_en_reg[group_offset]) | pad_mask);
+}
+
+static void gpio_configure_pad(const struct pad_config *cfg)
+{
+ uint32_t *dw_regs;
+ uint32_t reg;
+ uint32_t dw0;
+ uint32_t mask;
+
+ dw_regs = gpio_dw_regs(cfg->pad);
+
+ if (dw_regs == NULL)
+ return;
+
+ dw0 = cfg->dw0;
+
+ write32(&dw_regs[0], dw0);
+ reg = read32(&dw_regs[1]);
+
+ /* Apply termination field */
+ mask = PAD_TERM_MASK << PAD_TERM_SHIFT;
+ reg &= ~mask;
+ reg |= cfg->attrs & mask;
+
+ /* Apply voltage tolerance field */
+ mask = PAD_TOL_MASK << PAD_TOL_SHIFT;
+ reg &= ~mask;
+ reg |= cfg->attrs & mask;
+ write32(&dw_regs[1], reg);
+
+ gpio_handle_pad_mode(cfg);
+
+ if ((dw0 & PAD_FIELD(GPIROUTSMI, MASK)) == PAD_FIELD(GPIROUTSMI, YES))
+ gpi_enable_smi(cfg->pad);
+
+ if (gpio_debug)
+ printk(BIOS_DEBUG,
+ "Write Pad: Base(%p) - conf0 = %x conf1= %x pad # = %d\n",
+ &dw_regs[0], dw0, reg, cfg->pad);
+}
+
+void gpio_configure_pads(const struct pad_config *cfgs, size_t num)
+{
+ size_t i;
+
+ for (i = 0; i < num; i++)
+ gpio_configure_pad(&cfgs[i]);
+}
+
+void gpio_input_pulldown(gpio_t gpio)
+{
+ struct pad_config cfg = PAD_CFG_GPI(gpio, 5K_PD, DEEP);
+ gpio_configure_pad(&cfg);
+}
+
+void gpio_input_pullup(gpio_t gpio)
+{
+ struct pad_config cfg = PAD_CFG_GPI(gpio, 5K_PU, DEEP);
+ gpio_configure_pad(&cfg);
+}
+
+void gpio_input(gpio_t gpio)
+{
+ struct pad_config cfg = PAD_CFG_GPI(gpio, NONE, DEEP);
+ gpio_configure_pad(&cfg);
+}
+
+void gpio_output(gpio_t gpio, int value)
+{
+ struct pad_config cfg = PAD_CFG_GPO(gpio, value, DEEP);
+ gpio_configure_pad(&cfg);
+}
+
+int gpio_get(gpio_t gpio_num)
+{
+ uint32_t *dw_regs;
+ uint32_t reg;
+
+ dw_regs = gpio_dw_regs(gpio_num);
+
+ if (dw_regs == NULL)
+ return -1;
+
+ reg = read32(&dw_regs[0]);
+
+ return (reg >> GPIORXSTATE_SHIFT) & GPIORXSTATE_MASK;
+}
+
+void gpio_set(gpio_t gpio_num, int value)
+{
+ uint32_t *dw_regs;
+ uint32_t reg;
+
+ dw_regs = gpio_dw_regs(gpio_num);
+
+ if (dw_regs == NULL)
+ return;
+
+ reg = read32(&dw_regs[0]);
+ reg &= ~PAD_FIELD(GPIOTXSTATE, MASK);
+ reg |= PAD_FIELD_VAL(GPIOTXSTATE, value);
+ write32(&dw_regs[0], reg);
+ /* GPIO port ids support posted write semantics. */
+}
+
+const char *gpio_acpi_path(gpio_t gpio_num)
+{
+ return "\\_SB.PCI0.GPIO";
+}
+
+uint16_t gpio_acpi_pin(gpio_t gpio_num)
+{
+ return gpio_num;
+}
diff --git a/src/soc/intel/kabylake/i2c.c b/src/soc/intel/kabylake/i2c.c
new file mode 100644
index 0000000..fe524b2
--- /dev/null
+++ b/src/soc/intel/kabylake/i2c.c
@@ -0,0 +1,116 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2016 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <arch/acpigen.h>
+#include <device/device.h>
+#include <device/i2c.h>
+#include <device/pci.h>
+#include <device/pci_def.h>
+#include <device/pci_ids.h>
+#include <soc/intel/common/lpss_i2c.h>
+#include <soc/ramstage.h>
+
+uintptr_t lpss_i2c_base_address(unsigned bus)
+{
+ unsigned devfn;
+ struct device *dev;
+ struct resource *res;
+
+ /* bus -> devfn */
+ devfn = i2c_bus_to_devfn(bus);
+ if (devfn >= 0) {
+ /* devfn -> dev */
+ dev = dev_find_slot(0, devfn);
+ if (dev) {
+ /* dev -> bar0 */
+ res = find_resource(dev, PCI_BASE_ADDRESS_0);
+ if (res)
+ return res->base;
+ }
+ }
+
+ return (uintptr_t)NULL;
+}
+
+static int i2c_dev_to_bus(struct device *dev)
+{
+ return i2c_devfn_to_bus(dev->path.pci.devfn);
+}
+
+/*
+ * The device should already be enabled and out of reset,
+ * either from early init in coreboot or SiliconInit in FSP.
+ */
+static void i2c_dev_init(struct device *dev)
+{
+ struct soc_intel_kabylake_config *config = dev->chip_info;
+ const struct lpss_i2c_speed_config *sptr;
+ enum i2c_speed speed;
+ int i, bus = i2c_dev_to_bus(dev);
+
+ if (!config || bus < 0)
+ return;
+
+ speed = config->i2c[bus].speed ? : I2C_SPEED_FAST;
+ lpss_i2c_init(bus, speed);
+
+ /* Apply custom speed config if it has been set by the board */
+ for (i = 0; i < LPSS_I2C_SPEED_CONFIG_COUNT; i++) {
+ sptr = &config->i2c[bus].speed_config[i];
+ if (sptr->speed == speed) {
+ lpss_i2c_set_speed_config(bus, sptr);
+ break;
+ }
+ }
+}
+
+/* Generate ACPI I2C device objects */
+static void i2c_fill_ssdt(struct device *dev)
+{
+ struct soc_intel_kabylake_config *config = dev->chip_info;
+ int bus = i2c_dev_to_bus(dev);
+
+ if (!config || bus < 0)
+ return;
+
+ acpigen_write_scope(acpi_device_path(dev));
+ lpss_i2c_acpi_fill_ssdt(config->i2c[bus].speed_config);
+ acpigen_pop_len();
+}
+
+static struct i2c_bus_operations i2c_bus_ops = {
+ .dev_to_bus = &i2c_dev_to_bus,
+};
+
+static struct device_operations i2c_dev_ops = {
+ .read_resources = &pci_dev_read_resources,
+ .set_resources = &pci_dev_set_resources,
+ .enable_resources = &pci_dev_enable_resources,
+ .scan_bus = &scan_smbus,
+ .ops_pci = &soc_pci_ops,
+ .ops_i2c_bus = &i2c_bus_ops,
+ .init = &i2c_dev_init,
+ .acpi_fill_ssdt_generator = &i2c_fill_ssdt,
+};
+
+static const unsigned short pci_device_ids[] = {
+ 0x9d60, 0x9d61, 0x9d62, 0x9d63, 0x9d64, 0x9d65, 0
+};
+
+static const struct pci_driver pch_i2c __pci_driver = {
+ .ops = &i2c_dev_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .devices = pci_device_ids,
+};
diff --git a/src/soc/intel/kabylake/igd.c b/src/soc/intel/kabylake/igd.c
new file mode 100644
index 0000000..01982d7
--- /dev/null
+++ b/src/soc/intel/kabylake/igd.c
@@ -0,0 +1,219 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <arch/acpi.h>
+#include <arch/io.h>
+#include <chip.h>
+#include <console/console.h>
+#include <delay.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <drivers/intel/gma/i915_reg.h>
+#include <fsp/gop.h>
+#include <soc/acpi.h>
+#include <soc/cpu.h>
+#include <soc/pm.h>
+#include <soc/ramstage.h>
+#include <soc/systemagent.h>
+#include <stdlib.h>
+#include <string.h>
+#include <vendorcode/google/chromeos/chromeos.h>
+
+u32 map_oprom_vendev(u32 vendev)
+{
+ return SA_IGD_OPROM_VENDEV;
+}
+
+static struct resource *gtt_res = NULL;
+
+static unsigned long gtt_read(unsigned long reg)
+{
+ u32 val;
+ val = read32((void *)(unsigned int)(gtt_res->base + reg));
+ return val;
+}
+
+static void gtt_write(unsigned long reg, unsigned long data)
+{
+ write32((void *)(unsigned int)(gtt_res->base + reg), data);
+}
+
+static inline void gtt_rmw(u32 reg, u32 andmask, u32 ormask)
+{
+ u32 val = gtt_read(reg);
+ val &= andmask;
+ val |= ormask;
+ gtt_write(reg, val);
+}
+
+static void igd_init(struct device *dev)
+{
+ u32 ddi_buf_ctl;
+
+ gtt_res = find_resource(dev, PCI_BASE_ADDRESS_0);
+ if (!gtt_res || !gtt_res->base)
+ return;
+
+ /*
+ * Enable DDI-A (eDP) 4-lane operation if the link is not up yet.
+ * This will allow the kernel to use 4-lane eDP links properly
+ * if the VBIOS or GOP driver does not execute.
+ */
+ ddi_buf_ctl = gtt_read(DDI_BUF_CTL_A);
+ if (!acpi_is_wakeup_s3() && !(ddi_buf_ctl & DDI_BUF_CTL_ENABLE)) {
+ ddi_buf_ctl |= DDI_A_4_LANES;
+ gtt_write(DDI_BUF_CTL_A, ddi_buf_ctl);
+ }
+
+ if (IS_ENABLED(CONFIG_GOP_SUPPORT))
+ return;
+
+ /* IGD needs to be Bus Master */
+ u32 reg32 = pci_read_config32(dev, PCI_COMMAND);
+ reg32 |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO;
+ pci_write_config32(dev, PCI_COMMAND, reg32);
+
+ /* Wait for any configured pre-graphics delay */
+ if (!acpi_is_wakeup_s3()) {
+#if IS_ENABLED(CONFIG_CHROMEOS)
+ if (developer_mode_enabled() || recovery_mode_enabled() ||
+ vboot_wants_oprom())
+ mdelay(CONFIG_PRE_GRAPHICS_DELAY);
+#else
+ mdelay(CONFIG_PRE_GRAPHICS_DELAY);
+#endif
+ }
+
+ /* Initialize PCI device, load/execute BIOS Option ROM */
+ pci_dev_init(dev);
+
+#if IS_ENABLED(CONFIG_CHROMEOS)
+ if (!gfx_get_init_done() && !acpi_is_wakeup_s3()) {
+ /*
+ * Enable DDI-A if the Option ROM did not execute:
+ *
+ * bit 0: Display detected (RO)
+ * bit 4: DDI A supports 4 lanes and DDI E is not used
+ * bit 7: DDI buffer is idle
+ */
+ gtt_write(DDI_BUF_CTL_A, DDI_BUF_IS_IDLE | DDI_A_4_LANES |
+ DDI_INIT_DISPLAY_DETECTED);
+ }
+#endif
+}
+
+/* Initialize IGD OpRegion, called from ACPI code */
+static int init_igd_opregion(igd_opregion_t *opregion)
+{
+ const optionrom_vbt_t *vbt;
+ uint32_t vbt_len;
+ u16 reg16;
+
+ memset(opregion, 0, sizeof(igd_opregion_t));
+
+ /* Read VBT table from flash */
+ vbt = fsp_get_vbt(&vbt_len);
+ if (!vbt)
+ die("vbt data not found");
+
+ memcpy(&opregion->header.signature, IGD_OPREGION_SIGNATURE,
+ sizeof(IGD_OPREGION_SIGNATURE) - 1);
+ memcpy(opregion->header.vbios_version, vbt->coreblock_biosbuild, sizeof(u32));
+ memcpy(opregion->vbt.gvd1, vbt, vbt->hdr_vbt_size <
+ sizeof(opregion->vbt.gvd1) ? vbt->hdr_vbt_size :
+ sizeof(opregion->vbt.gvd1));
+
+ /* Size, in KB, of the entire OpRegion structure (including header)*/
+ opregion->header.size = sizeof(igd_opregion_t) / KiB;
+ opregion->header.version = IGD_OPREGION_VERSION;
+
+ /* We just assume we're mobile for now */
+ opregion->header.mailboxes = MAILBOXES_MOBILE;
+
+ /* TODO Initialize Mailbox 1 */
+
+ /* Initialize Mailbox 3 */
+ opregion->mailbox3.bclp = IGD_BACKLIGHT_BRIGHTNESS;
+ opregion->mailbox3.pfit = IGD_FIELD_VALID | IGD_PFIT_STRETCH;
+ opregion->mailbox3.pcft = 0; /* should be (IMON << 1) & 0x3e */
+ opregion->mailbox3.cblv = IGD_FIELD_VALID | IGD_INITIAL_BRIGHTNESS;
+ opregion->mailbox3.bclm[0] = IGD_WORD_FIELD_VALID + 0x0000;
+ opregion->mailbox3.bclm[1] = IGD_WORD_FIELD_VALID + 0x0a19;
+ opregion->mailbox3.bclm[2] = IGD_WORD_FIELD_VALID + 0x1433;
+ opregion->mailbox3.bclm[3] = IGD_WORD_FIELD_VALID + 0x1e4c;
+ opregion->mailbox3.bclm[4] = IGD_WORD_FIELD_VALID + 0x2866;
+ opregion->mailbox3.bclm[5] = IGD_WORD_FIELD_VALID + 0x327f;
+ opregion->mailbox3.bclm[6] = IGD_WORD_FIELD_VALID + 0x3c99;
+ opregion->mailbox3.bclm[7] = IGD_WORD_FIELD_VALID + 0x46b2;
+ opregion->mailbox3.bclm[8] = IGD_WORD_FIELD_VALID + 0x50cc;
+ opregion->mailbox3.bclm[9] = IGD_WORD_FIELD_VALID + 0x5ae5;
+ opregion->mailbox3.bclm[10] = IGD_WORD_FIELD_VALID + 0x64ff;
+
+ /* TODO This may need to happen in S3 resume */
+ pci_write_config32(SA_DEV_IGD, ASLS, (u32)opregion);
+ reg16 = pci_read_config16(SA_DEV_IGD, SWSCI);
+ reg16 &= ~GSSCIE;
+ reg16 |= SMISCISEL;
+ pci_write_config16(SA_DEV_IGD, SWSCI, reg16);
+
+ return 0;
+}
+
+static unsigned long write_acpi_igd_opregion(device_t device,
+ unsigned long current, struct acpi_rsdp *rsdp)
+{
+ igd_opregion_t *opregion;
+
+ /* If GOP is not used, exit here */
+ if (!IS_ENABLED(CONFIG_GOP_SUPPORT))
+ return current;
+
+ /* If IGD is disabled, exit here */
+ if (pci_read_config16(device, PCI_VENDOR_ID) == 0xFFFF)
+ return current;
+
+ printk(BIOS_DEBUG, "ACPI: * IGD OpRegion\n");
+ opregion = (igd_opregion_t *)current;
+ init_igd_opregion(opregion);
+ current += sizeof(igd_opregion_t);
+ current = acpi_align_current(current);
+
+ printk(BIOS_DEBUG, "current = %lx\n", current);
+ return current;
+}
+
+static struct device_operations igd_ops = {
+ .read_resources = &pci_dev_read_resources,
+ .set_resources = &pci_dev_set_resources,
+ .enable_resources = &pci_dev_enable_resources,
+ .init = &igd_init,
+ .ops_pci = &soc_pci_ops,
+ .write_acpi_tables = write_acpi_igd_opregion,
+};
+
+static const unsigned short pci_device_ids[] = {
+ IGD_KABYLAKE_GT1_SULTM,
+ IGD_KABYLAKE_GT2_SULXM,
+ IGD_KABYLAKE_GT2_SULTM,
+ 0,
+};
+
+static const struct pci_driver igd_driver __pci_driver = {
+ .ops = &igd_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .devices = pci_device_ids,
+};
diff --git a/src/soc/intel/kabylake/include/soc/acpi.h b/src/soc/intel/kabylake/include/soc/acpi.h
new file mode 100644
index 0000000..8e06ca4
--- /dev/null
+++ b/src/soc/intel/kabylake/include/soc/acpi.h
@@ -0,0 +1,37 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _SOC_ACPI_H_
+#define _SOC_ACPI_H_
+
+#include <arch/acpi.h>
+#include <soc/nvs.h>
+
+/* P-state configuration */
+#define PSS_MAX_ENTRIES 8
+#define PSS_RATIO_STEP 2
+#define PSS_LATENCY_TRANSITION 10
+#define PSS_LATENCY_BUSMASTER 10
+
+void acpi_fill_in_fadt(acpi_fadt_t *fadt);
+unsigned long acpi_madt_irq_overrides(unsigned long current);
+void acpi_mainboard_gnvs(global_nvs_t *gnvs);
+void southcluster_inject_dsdt(device_t device);
+unsigned long southcluster_write_acpi_tables(device_t device,
+ unsigned long current, struct acpi_rsdp *rsdp);
+
+#endif /* _SOC_ACPI_H_ */
+
diff --git a/src/soc/intel/kabylake/include/soc/car_setup.S b/src/soc/intel/kabylake/include/soc/car_setup.S
new file mode 100644
index 0000000..4b881a1
--- /dev/null
+++ b/src/soc/intel/kabylake/include/soc/car_setup.S
@@ -0,0 +1,334 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013-2014 Sage Electronic Engineering, LLC.
+ * Copyright (C) 2016 Intel Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <cpu/x86/mtrr.h>
+#include <cpu/x86/cache.h>
+#include <cpu/x86/post_code.h>
+
+/*
+ * MTRR definitions
+ */
+.equ IA32_MTRR_CAP, 0x00fe
+
+.equ NO_EVICT_MODE, 0x02e0
+
+.equ IA32_PQR_ASSOC, 0x0c8f
+.equ IA32_L3_MASK_1, 0x0c91
+.equ IA32_L3_MASK_2, 0x0c92
+.equ CACHE_INIT_VALUE, 0
+
+/*
+ * See BWG - chapter "Determining Cacheable Code Region Base Addresses and Ranges".
+ *
+ */
+
+ movl %edi, %ebp /* Put BIST value in a safe place */
+ /*
+ * Ensure that all variable-range MTRR valid flags are clear and
+ * IA32_MTRR_DEF_TYPE MSR E flag is clear. Note: This is the default state
+ * after hardware reset.
+ *
+ * Initialize all fixed-range and variable-range MTRR register fields to 0.
+ */
+ mov $(MtrrByteCountFixed), %ebx /* EBX = size of Fixed MTRRs */
+
+ xorl %eax, %eax /* Clear the low dword to write */
+ xorl %edx, %edx /* Clear the high dword to write */
+ xorl %ecx, %ecx
+ /* Clearing Fixed Range MTRRs */
+clear_mtrr_fixed:
+ addl $(-2), %ebx /* need to check it */
+ movw (MtrrInitTable)(%ebx), %cx /* cx <- address of mtrr to zero */
+ wrmsr
+ jnz clear_mtrr_fixed /* loop through the whole table */
+
+ post_code(0x21)
+
+ /* Clearing Variable Range MTRRs */
+ movl $MTRR_CAP_MSR, %ecx
+ rdmsr
+ movzx %al, %ebx
+ clr %eax
+ clr %edx
+ movl $MTRR_PHYS_BASE(0), %ecx
+clear_var_mtrr:
+ wrmsr
+ inc %ecx
+ wrmsr
+ inc %ecx
+ dec %ebx
+ jnz clear_var_mtrr
+
+ post_code(0x22)
+
+ /*
+ * Configure the default memory type to un-cacheable (UC) in the
+ * IA32_MTRR_DEF_TYPE MSR.
+ */
+
+ movl $MTRR_DEF_TYPE_MSR, %ecx /* Load the MTRR default type index */
+ rdmsr
+ andl $0xFFFFF300, %eax /* Clear the enable bits and def type UC. */
+ wrmsr
+
+ /* Configure MTRR_PHYS_MASK_HIGH for proper addressing above 4GB
+ * based on the physical address size supported for this processor
+ * This is based on read from CPUID EAX = 080000008h, EAX bits [7:0]
+ *
+ * Examples:
+ * MTRR_PHYS_MASK_HIGH = 00000000Fh For 36 bit addressing
+ * MTRR_PHYS_MASK_HIGH = 0000000FFh For 40 bit addressing
+ */
+
+ movl $0x80000008, %eax /* Address sizes leaf */
+ cpuid
+ sub $32, %al
+ movzx %al, %eax
+ xorl %esi, %esi
+ bts %eax, %esi
+ dec %esi /* esi <- MTRR_PHYS_MASK_HIGH */
+
+ /*
+ * Configure the DataStack region as write-back (WB) cacheable memory type
+ * using the variable range MTRRs.
+ *
+ *
+ * Set the base address of the DataStack cache range
+ */
+
+ movl $CONFIG_DCACHE_RAM_BASE, %eax
+ orl $MTRR_TYPE_WRBACK, %eax /* Load the write-back cache value */
+ xorl %edx, %edx /* clear upper dword */
+ movl $MTRR_PHYS_BASE(0), %ecx /* Load the MTRR index */
+ wrmsr /* the value in MTRR_PHYS_BASE_0 */
+
+ /*
+ * Set the mask for the DataStack cache range
+ * Compute MTRR mask value: Mask = NOT (Size - 1)
+ */
+ movl $CONFIG_DCACHE_RAM_SIZE_TOTAL, %eax
+ dec %eax
+ not %eax
+ orl $MTRR_PHYS_MASK_VALID, %eax /* turn on the Valid flag */
+ movl %esi, %edx /* edx <- MTRR_PHYS_MASK_HIGH */
+ inc %ecx
+ wrmsr /* the value in MTRR_PHYS_MASK_0 */
+
+ post_code(0x23)
+
+ /*
+ * Enable the MTRRs by setting the IA32_MTRR_DEF_TYPE MSR E flag.
+ */
+ movl $MTRR_DEF_TYPE_MSR, %ecx /* Load the MTRR default type index */
+ rdmsr
+ orl $MTRR_DEF_TYPE_EN, %eax /* Enable variable range MTRRs */
+ wrmsr
+
+ post_code(0x24)
+
+ /*
+ * Enable the logical processor's (BSP) cache: execute INVD and set
+ * CR0.CD = 0, CR0.NW = 0.
+ */
+ movl %cr0, %eax
+ and $(~(CR0_CD + CR0_NW)), %eax
+ invd
+ movl %eax, %cr0
+
+ /*
+ * Enable No-Eviction Mode Setup State by setting
+ * NO_EVICT_MODE MSR 2E0h bit [0] = '1'.
+ */
+ movl $NO_EVICT_MODE, %ecx
+ rdmsr
+ orl $0x01, %eax
+ wrmsr
+
+ /* Create n-way set associativity of cache */
+ xorl %edi, %edi
+Find_LLC_subleaf:
+ movl %edi, %ecx
+ movl $0x04, %eax
+ cpuid
+ inc %edi
+ and $0xe0, %al /* EAX[7:5] = Cache Level */
+ cmp $0x60, %al /* Check to see if it is LLC */
+ jnz Find_LLC_subleaf
+
+ /*
+ * Set MSR 0xC91 IA32_L3_MASK_! = 0xE/0xFE/0xFFE/0xFFFE
+ * for 4/8/16 way of LLC
+ */
+ shr $22, %ebx
+ inc %ebx
+ /* Calculate n-way associativity of LLC */
+ mov %bl, %cl
+
+ /*
+ * Maximizing RO cacheability while locking in the CAR to a
+ * single way since that particular way won't be victim candidate
+ * for evictions.
+ * This has been done after programing LLC_WAY_MASK_1 MSR
+ * with desired LLC way as mentioned below.
+ *
+ * Hence create Code and Data Size as per request
+ * Code Size (RO) : Up to 16M
+ * Data Size (RW) : Up to 256K
+ */
+ movl $0x01, %eax
+ /*
+ * LLC Ways -> LLC_WAY_MASK_1:
+ * 4: 0x000E
+ * 8: 0x00FE
+ * 12: 0x0FFE
+ * 16: 0xFFFE
+ *
+ * These MSRs contain one bit per each way of LLC
+ * - If this bit is '0' - the way is protected from eviction
+ * - If this bit is '1' - the way is not protected from eviction
+ */
+ shl %cl, %eax
+ subl $0x02, %eax
+ movl $IA32_L3_MASK_1, %ecx
+ xorl %edx, %edx
+ wrmsr
+ /*
+ * Set MSR 0xC92 IA32_L3_MASK_2 = 0x1
+ *
+ * For SKL SOC, data size remains 256K consistently.
+ * Hence, creating 1-way associative cache for Data
+ */
+ mov $IA32_L3_MASK_2, %ecx
+ mov $0x01, %eax
+ xorl %edx, %edx
+ wrmsr
+ /*
+ * Set IA32_PQR_ASSOC = 0x02
+ *
+ * Possible values:
+ * 0: Default value, no way mask should be applied
+ * 1: Apply way mask 1 to LLC
+ * 2: Apply way mask 2 to LLC
+ * 3: Shouldn't be use in NEM Mode
+ */
+ movl $IA32_PQR_ASSOC, %ecx
+ movl $0x02, %eax
+ xorl %edx, %edx
+ wrmsr
+
+ movl $CONFIG_DCACHE_RAM_BASE, %edi
+ movl $CONFIG_DCACHE_RAM_SIZE_TOTAL, %ecx
+ shr $0x02, %ecx
+ movl $CACHE_INIT_VALUE, %eax
+ cld
+ rep stosl
+ /*
+ * Set IA32_PQR_ASSOC = 0x01
+ * At this stage we apply LLC_WAY_MASK_1 to the cache.
+ * i.e. way 0 is protected from eviction.
+ */
+ movl $IA32_PQR_ASSOC, %ecx
+ movl $0x01, %eax
+ xorl %edx, %edx
+ wrmsr
+
+ /*
+ * Enable No-Eviction Mode Run State by setting
+ * NO_EVICT_MODE MSR 2E0h bit [1] = '1'.
+ */
+
+ movl $NO_EVICT_MODE, %ecx
+ rdmsr
+ orl $0x02, %eax
+ wrmsr
+
+ post_code(0x25)
+ /*
+ * Configure the BIOS code region as write-protected (WP) cacheable
+ * memory type using a single variable range MTRR.
+ *
+ * Ensure region to cache meets MTRR requirements for
+ * size and alignment.
+ */
+ movl $(0xFFFFFFFF - CONFIG_ROM_SIZE + 1), %edi /* Code region base */
+ movl $CONFIG_ROM_SIZE, %eax /* Code region size */
+ cmpl $0, %edi
+ jz InvalidParameter
+ cmpl $0, %eax
+ jz InvalidParameter
+ jmp CheckPass
+
+InvalidParameter:
+ movl $0x80000002, %eax /* RETURN_INVALID_PARAMETER */
+ jmp .Lhlt
+
+CheckPass:
+
+ post_code(0x26)
+
+ /*
+ * Program base register
+ */
+ xorl %edx, %edx /* clear upper dword */
+ movl $MTRR_PHYS_BASE(1), %ecx /* setup variable mtrr */
+ movl %edi, %eax
+ orl $MTRR_TYPE_WRPROT, %eax /* set type to write protect */
+ wrmsr
+
+ movl $CONFIG_ROM_SIZE, %eax
+
+ /*
+ * Compute MTRR mask value: Mask = NOT (Size - 1)
+ */
+ dec %eax /* eax - size to cache less one byte */
+ not %eax /* eax contains low 32 bits of mask */
+ or $MTRR_PHYS_MASK_VALID, %eax
+ /*
+ * Program mask register
+ */
+ movl $MTRR_PHYS_MASK(1) , %ecx /* setup variable mtrr */
+ movl %esi, %edx /* edx <- MTRR_PHYS_MASK_HIGH */
+ wrmsr
+
+ post_code(0x27)
+
+ /*
+ * edi: BIST value
+ * mm0: low 32-bits of TSC value
+ * mm1: high 32-bits of TSC value
+ */
+ movl %ebp, %edi /* Restore BIST value */
+
+ .section .rodata
+
+MtrrInitTable:
+ .word MTRR_DEF_TYPE_MSR
+ .word MTRR_FIX_64K_00000
+ .word MTRR_FIX_16K_80000
+ .word MTRR_FIX_16K_A0000
+ .word MTRR_FIX_4K_C0000
+ .word MTRR_FIX_4K_C8000
+ .word MTRR_FIX_4K_D0000
+ .word MTRR_FIX_4K_D8000
+ .word MTRR_FIX_4K_E0000
+ .word MTRR_FIX_4K_E8000
+ .word MTRR_FIX_4K_F0000
+ .word MTRR_FIX_4K_F8000
+
+.equ MtrrByteCountFixed, (.-MtrrInitTable)
+
+ .previous
diff --git a/src/soc/intel/kabylake/include/soc/car_teardown.S b/src/soc/intel/kabylake/include/soc/car_teardown.S
new file mode 100644
index 0000000..315b3c1
--- /dev/null
+++ b/src/soc/intel/kabylake/include/soc/car_teardown.S
@@ -0,0 +1,54 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013-2014 Sage Electronic Engineering, LLC.
+ * Copyright (C) 2016 Intel Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+.equ IA32_PQR_ASSOC, 0x0c8f
+
+ /* Disable MTRR by clearing the IA32_MTRR_DEF_TYPE MSR E flag. */
+ movl $MTRR_DEF_TYPE_MSR, %ecx
+ rdmsr
+ andl $(~MTRR_DEF_TYPE_EN), %eax
+ wrmsr
+
+ /* Invalidate Cache */
+ invd
+
+ /*
+ * Disable No-Eviction Mode Run State by clearing
+ * NO_EVICT_MODE MSR 2E0h bit [1] = 0
+ */
+ movl $0x000002E0, %ecx
+ rdmsr
+ andl $~(0x2), %eax
+ wrmsr
+
+ /*
+ * Disable No-Eviction Mode Setup State by clearing
+ * NO_EVICT_MODE MSR 2E0h bit [0] = 0
+ */
+ rdmsr
+ andl $~(0x1), %eax
+ wrmsr
+
+ /*
+ * Set IA32_PQR_ASSOC = 0x00
+ * This step guarantees that no protected way remain in LLC cache,
+ * all the ways are open for the evictions.
+ */
+ movl $IA32_PQR_ASSOC, %ecx
+ movl $0x00, %eax
+ xorl %edx, %edx
+ wrmsr
diff --git a/src/soc/intel/kabylake/include/soc/cpu.h b/src/soc/intel/kabylake/include/soc/cpu.h
new file mode 100644
index 0000000..91fc133
--- /dev/null
+++ b/src/soc/intel/kabylake/include/soc/cpu.h
@@ -0,0 +1,65 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _SOC_CPU_H_
+#define _SOC_CPU_H_
+
+#include <arch/cpu.h>
+#include <device/device.h>
+
+/* CPU types */
+#define KABYLAKE_FAMILY_ULT 0x406e0
+
+/* Supported CPUIDs */
+#define CPUID_KABYLAKE_C0 0x406e2
+#define CPUID_KABYLAKE_D0 0x406e3
+
+/* CPU bus clock is fixed at 100MHz */
+#define CPU_BCLK 100
+
+/* Latency times in units of 1024ns. */
+#define C_STATE_LATENCY_CONTROL_0_LIMIT 0x4e
+#define C_STATE_LATENCY_CONTROL_1_LIMIT 0x76
+#define C_STATE_LATENCY_CONTROL_2_LIMIT 0x94
+#define C_STATE_LATENCY_CONTROL_3_LIMIT 0xfa
+#define C_STATE_LATENCY_CONTROL_4_LIMIT 0x14c
+#define C_STATE_LATENCY_CONTROL_5_LIMIT 0x3f2
+
+/* Power in units of mW */
+#define C1_POWER 0x3e8
+#define C3_POWER 0x1f4
+#define C6_POWER 0x15e
+#define C7_POWER 0xc8
+#define C8_POWER 0xc8
+#define C9_POWER 0xc8
+#define C10_POWER 0xc8
+
+#define C_STATE_LATENCY_MICRO_SECONDS(limit, base) \
+ (((1 << ((base)*5)) * (limit)) / 1000)
+#define C_STATE_LATENCY_FROM_LAT_REG(reg) \
+ C_STATE_LATENCY_MICRO_SECONDS(C_STATE_LATENCY_CONTROL_ ##reg## _LIMIT, \
+ (IRTL_1024_NS >> 10))
+
+/* Configure power limits for turbo mode */
+void set_power_limits(u8 power_limit_1_time);
+int cpu_config_tdp_levels(void);
+
+/* CPU identification */
+u32 cpu_family_model(void);
+u32 cpu_stepping(void);
+int cpu_is_ult(void);
+
+#endif
diff --git a/src/soc/intel/kabylake/include/soc/device_nvs.h b/src/soc/intel/kabylake/include/soc/device_nvs.h
new file mode 100644
index 0000000..d10420b
--- /dev/null
+++ b/src/soc/intel/kabylake/include/soc/device_nvs.h
@@ -0,0 +1,43 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _SOC_DEVICE_NVS_H_
+#define _SOC_DEVICE_NVS_H_
+
+#include <stdint.h>
+
+/* Offset in Global NVS where this structure lives */
+#define DEVICE_NVS_OFFSET 0x1000
+
+#define SIO_NVS_I2C0 0
+#define SIO_NVS_I2C1 1
+#define SIO_NVS_I2C2 2
+#define SIO_NVS_I2C3 3
+#define SIO_NVS_I2C4 4
+#define SIO_NVS_I2C5 5
+#define SIO_NVS_SPI0 6
+#define SIO_NVS_SPI1 7
+#define SIO_NVS_UART0 8
+#define SIO_NVS_UART1 9
+#define SIO_NVS_UART2 10
+
+typedef struct {
+ u8 enable[11];
+ u32 bar0[11];
+ u32 bar1[11];
+} __attribute__((packed)) device_nvs_t;
+
+#endif
diff --git a/src/soc/intel/kabylake/include/soc/flash_controller.h b/src/soc/intel/kabylake/include/soc/flash_controller.h
new file mode 100644
index 0000000..3e08a7f
--- /dev/null
+++ b/src/soc/intel/kabylake/include/soc/flash_controller.h
@@ -0,0 +1,181 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015-2016 Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _SOC_FLASH_CONTROLLER__H_
+#define _SOC_FLASH_CONTROLLER__H_
+
+#include <rules.h>
+#include <arch/io.h>
+#include <console/console.h>
+#include <spi_flash.h>
+
+int pch_hwseq_erase(struct spi_flash *flash, u32 offset, size_t len);
+int pch_hwseq_write(struct spi_flash *flash,
+ u32 addr, size_t len, const void *buf);
+
+int pch_hwseq_read(struct spi_flash *flash,
+ u32 addr, size_t len, void *buf);
+int pch_hwseq_read_status(struct spi_flash *flash, u8 *reg);
+
+
+#if IS_ENABLED(CONFIG_DEBUG_SPI_FLASH)
+static u8 readb_(const void *addr)
+{
+ u8 v = read8(addr);
+ printk(BIOS_DEBUG, "read %2.2x from %4.4x\n",
+ v, ((unsigned) addr & 0xffff) - 0xf020);
+ return v;
+}
+
+static u16 readw_(const void *addr)
+{
+ u16 v = read16(addr);
+ printk(BIOS_DEBUG, "read %4.4x from %4.4x\n",
+ v, ((unsigned) addr & 0xffff) - 0xf020);
+ return v;
+}
+
+static u32 readl_(const void *addr)
+{
+ u32 v = read32(addr);
+ printk(BIOS_DEBUG, "read %8.8x from %4.4x\n",
+ v, ((unsigned) addr & 0xffff) - 0xf020);
+ return v;
+}
+
+static void writeb_(u8 b, void *addr)
+{
+ write8(addr, b);
+ printk(BIOS_DEBUG, "wrote %2.2x to %4.4x\n",
+ b, ((unsigned) addr & 0xffff) - 0xf020);
+}
+
+static void writew_(u16 b, void *addr)
+{
+ write16(addr, b);
+ printk(BIOS_DEBUG, "wrote %4.4x to %4.4x\n",
+ b, ((unsigned) addr & 0xffff) - 0xf020);
+}
+
+static void writel_(u32 b, void *addr)
+{
+ write32(addr, b);
+ printk(BIOS_DEBUG, "wrote %8.8x to %4.4x\n",
+ b, ((unsigned) addr & 0xffff) - 0xf020);
+}
+
+#else /* CONFIG_DEBUG_SPI_FLASH ^^^ enabled vvv NOT enabled */
+
+#define readb_(a) read8(a)
+#define readw_(a) read16(a)
+#define readl_(a) read32(a)
+#define writeb_(val, addr) write8(addr, val)
+#define writew_(val, addr) write16(addr, val)
+#define writel_(val, addr) write32(addr, val)
+
+#endif /* CONFIG_DEBUG_SPI_FLASH ^^^ NOT enabled */
+
+#if ENV_SMM
+#define pci_read_config_byte(dev, reg, targ)\
+ (*(targ) = pci_read_config8(dev, reg))
+#define pci_read_config_word(dev, reg, targ)\
+ (*(targ) = pci_read_config16(dev, reg))
+#define pci_read_config_dword(dev, reg, targ)\
+ (*(targ) = pci_read_config32(dev, reg))
+#define pci_write_config_byte(dev, reg, val)\
+ pci_write_config8(dev, reg, val)
+#define pci_write_config_word(dev, reg, val)\
+ pci_write_config16(dev, reg, val)
+#define pci_write_config_dword(dev, reg, val)\
+ pci_write_config32(dev, reg, val)
+#else /* !ENV_SMM */
+#include <device/device.h>
+#include <device/pci.h>
+#define pci_read_config_byte(dev, reg, targ)\
+ (*(targ) = pci_read_config8(dev, reg))
+#define pci_read_config_word(dev, reg, targ)\
+ (*(targ) = pci_read_config16(dev, reg))
+#define pci_read_config_dword(dev, reg, targ)\
+ (*(targ) = pci_read_config32(dev, reg))
+#define pci_write_config_byte(dev, reg, val)\
+ pci_write_config8(dev, reg, val)
+#define pci_write_config_word(dev, reg, val)\
+ pci_write_config16(dev, reg, val)
+#define pci_write_config_dword(dev, reg, val)\
+ pci_write_config32(dev, reg, val)
+#endif /* ENV_SMM */
+
+#define HSFC_FCYCLE_MASK (0xf << HSFC_FCYCLE_SHIFT)
+#define HSFC_FCYCLE_RD (0x0 << HSFC_FCYCLE_SHIFT)
+#define HSFC_FCYCLE_WR (0x2 << HSFC_FCYCLE_SHIFT)
+#define HSFC_FCYCLE_4KE (0x3 << HSFC_FCYCLE_SHIFT)
+#define HSFC_FCYCLE_64KE (0x4 << HSFC_FCYCLE_SHIFT)
+#define HSFC_FCYCLE_SFDP (0x5 << HSFC_FCYCLE_SHIFT)
+#define HSFC_FCYCLE_JEDECID (0x6 << HSFC_FCYCLE_SHIFT)
+#define HSFC_FCYCLE_WS (0x7 << HSFC_FCYCLE_SHIFT)
+#define HSFC_FCYCLE_RS (0x8 << HSFC_FCYCLE_SHIFT)
+#define HSFC_FDBC_MASK (0x3f << HSFC_FDBC_SHIFT)
+
+#define SPI_READ_STATUS_LENGTH 1 /* Read Status Register 1 */
+
+#define WPSR_MASK_SRP0_BIT 0x80
+
+#define SPI_FDATA_REGS 16
+#define SPI_FDATA_BYTES (SPI_FDATA_REGS * sizeof(uint32_t))
+
+typedef struct pch_spi_regs {
+ uint32_t bfpr;
+ uint16_t hsfs;
+ uint16_t hsfc;
+ uint32_t faddr;
+ uint32_t dlock;
+ uint32_t fdata[SPI_FDATA_REGS];
+ uint32_t frap;
+ uint32_t freg[6];
+ uint32_t _reserved1[6];
+ uint32_t pr[5];
+ uint32_t gpr0;
+ uint32_t _reserved2;
+ uint32_t _reserved3;
+ uint16_t preop;
+ uint16_t optype;
+ uint8_t opmenu[8];
+ uint32_t bbar;
+ uint32_t fdoc;
+ uint32_t fdod;
+ uint8_t _reserved4[8];
+ uint32_t afc;
+ uint32_t lvscc;
+ uint32_t uvscc;
+ uint8_t _reserved5[4];
+ uint32_t fpb;
+ uint8_t _reserved6[28];
+ uint32_t srdl;
+ uint32_t srdc;
+ uint32_t srd;
+} __attribute__((packed)) pch_spi_regs;
+
+enum {
+ HSFS_FDONE = 0x0001,
+ HSFS_FCERR = 0x0002,
+ HSFS_FDV = 0x4000,
+};
+
+enum {
+ HSFC_FGO = 0x0001,
+ HSFC_FCYCLE_SHIFT = 1,
+ HSFC_FDBC_SHIFT = 8,
+};
+#endif /* _SOC_FLASH_CONTROLLER__H_ */
diff --git a/src/soc/intel/kabylake/include/soc/gpe.h b/src/soc/intel/kabylake/include/soc/gpe.h
new file mode 100644
index 0000000..655cc11
--- /dev/null
+++ b/src/soc/intel/kabylake/include/soc/gpe.h
@@ -0,0 +1,133 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2015 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _SOC_GPE_H_
+#define _SOC_GPE_H_
+
+/* GPE_31_0 */
+#define GPE0_DW0_00 0
+#define GPE0_DW0_01 1
+#define GPE0_DW0_02 2
+#define GPE0_DW0_03 3
+#define GPE0_DW0_04 4
+#define GPE0_DW0_05 5
+#define GPE0_DW0_06 6
+#define GPE0_DW0_07 7
+#define GPE0_DW0_08 8
+#define GPE0_DW0_09 9
+#define GPE0_DW0_10 10
+#define GPE0_DW0_11 11
+#define GPE0_DW0_12 12
+#define GPE0_DW0_13 13
+#define GPE0_DW0_14 14
+#define GPE0_DW0_15 15
+#define GPE0_DW0_16 16
+#define GPE0_DW0_17 17
+#define GPE0_DW0_18 18
+#define GPE0_DW0_19 19
+#define GPE0_DW0_20 20
+#define GPE0_DW0_21 21
+#define GPE0_DW0_22 22
+#define GPE0_DW0_23 23
+#define GPE0_DW0_24 24
+#define GPE0_DW0_25 25
+#define GPE0_DW0_26 26
+#define GPE0_DW0_27 27
+#define GPE0_DW0_28 28
+#define GPE0_DW0_29 29
+#define GPE0_DW0_30 30
+#define GPE0_DW0_31 31
+/* GPE_63_32 */
+#define GPE0_DW1_00 32
+#define GPE0_DW1_01 33
+#define GPE0_DW1_02 34
+#define GPE0_DW1_03 36
+#define GPE0_DW1_04 36
+#define GPE0_DW1_05 37
+#define GPE0_DW1_06 38
+#define GPE0_DW1_07 39
+#define GPE0_DW1_08 40
+#define GPE0_DW1_09 41
+#define GPE0_DW1_10 42
+#define GPE0_DW1_11 43
+#define GPE0_DW1_12 44
+#define GPE0_DW1_13 45
+#define GPE0_DW1_14 46
+#define GPE0_DW1_15 47
+#define GPE0_DW1_16 48
+#define GPE0_DW1_17 49
+#define GPE0_DW1_18 50
+#define GPE0_DW1_19 51
+#define GPE0_DW1_20 52
+#define GPE0_DW1_21 53
+#define GPE0_DW1_22 54
+#define GPE0_DW1_23 55
+#define GPE0_DW1_24 56
+#define GPE0_DW1_25 57
+#define GPE0_DW1_26 58
+#define GPE0_DW1_27 59
+#define GPE0_DW1_28 60
+#define GPE0_DW1_29 61
+#define GPE0_DW1_30 62
+#define GPE0_DW1_31 63
+/* GPE_95_64 */
+#define GPE0_DW2_00 64
+#define GPE0_DW2_01 65
+#define GPE0_DW2_02 66
+#define GPE0_DW2_03 67
+#define GPE0_DW2_04 68
+#define GPE0_DW2_05 69
+#define GPE0_DW2_06 70
+#define GPE0_DW2_07 71
+#define GPE0_DW2_08 72
+#define GPE0_DW2_09 73
+#define GPE0_DW2_10 74
+#define GPE0_DW2_11 75
+#define GPE0_DW2_12 76
+#define GPE0_DW2_13 77
+#define GPE0_DW2_14 78
+#define GPE0_DW2_15 79
+#define GPE0_DW2_16 80
+#define GPE0_DW2_17 81
+#define GPE0_DW2_18 82
+#define GPE0_DW2_19 83
+#define GPE0_DW2_20 84
+#define GPE0_DW2_21 85
+#define GPE0_DW2_22 86
+#define GPE0_DW2_23 87
+#define GPE0_DW2_24 88
+#define GPE0_DW2_25 89
+#define GPE0_DW2_26 90
+#define GPE0_DW2_27 91
+#define GPE0_DW2_28 92
+#define GPE0_DW2_29 93
+#define GPE0_DW2_30 94
+#define GPE0_DW2_31 95
+/* GPE_STD */
+#define GPE0_HOT_PLUG 97
+#define GPE0_SWGPE 98
+#define GPE0_TCOSCI 102
+#define GPE0_SMB_WAK 103
+#define GPE0_PCI_EXP 105
+#define GPE0_BATLOW 106
+#define GPE0_PME 107
+#define GPE0_ME_SCI 108
+#define GPE0_PME_B0 109
+#define GPE0_ESPI 110
+#define GPE0_GPIO_T2 111
+#define GPE0_LAN_WAK 112
+#define GPE0_WADT 114
+
+#endif /* _SOC_GPE_H_ */
diff --git a/src/soc/intel/kabylake/include/soc/gpio.h b/src/soc/intel/kabylake/include/soc/gpio.h
new file mode 100644
index 0000000..0c4e40d
--- /dev/null
+++ b/src/soc/intel/kabylake/include/soc/gpio.h
@@ -0,0 +1,174 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _SOC_GPIO_H_
+#define _SOC_GPIO_H_
+
+#include <soc/gpio_defs.h>
+
+#ifndef __ACPI__
+#include <stdint.h>
+#include <stddef.h>
+
+typedef uint32_t gpio_t;
+
+/* Structure to represent GPI status for GPE and SMI. Use helper
+ * functions for interrogating particular GPIs. */
+struct gpi_status {
+ uint32_t grp[GPIO_NUM_GROUPS];
+};
+
+/*
+ * Clear GPI SMI status and fill in the structure representing enabled
+ * and set status.
+ */
+void gpi_clear_get_smi_status(struct gpi_status *sts);
+
+/* Return 1 if gpio is set in the gpi_status struct. Otherwise 0. */
+int gpi_status_get(const struct gpi_status *sts, gpio_t gpi);
+
+/*
+ * Set the GPIO groups for the GPE blocks. The gpe0_route is interpreted
+ * as the packed configuration for GPE0_DW[2:0]:
+ * dw0 = gpe0_route[3:0]
+ * dw1 = gpe0_route[7:4]
+ * dw2 = gpe0_route[11:8].
+ */
+void gpio_route_gpe(uint16_t gpe0_route);
+
+/* Configure the pads according to the pad_config array. */
+struct pad_config;
+void gpio_configure_pads(const struct pad_config *cfgs, size_t num);
+
+#define PAD_FIELD_VAL(field_, val_) \
+ (((val_) & field_ ## _MASK) << field_ ## _SHIFT)
+
+#define PAD_FIELD(field_, setting_) \
+ PAD_FIELD_VAL(field_, field_ ## _ ## setting_)
+
+/*
+ * This encodes all the fields found within the dw0 register for each
+ * pad. It directly follows the register specification:
+ * rst - reset type when pad configuration is reset
+ * rxst - native function routing: raw buffer or internal buffer
+ * rxraw1 - drive fixed '1' for Rx buffer
+ * rxev - event filtering for pad value: level, edge, drive '0'
+ * rxgf - glitch filter enable
+ * rxinv - invert the internal pad state
+ * gpiioapic - route to IOxAPIC
+ * gpisci - route for SCI
+ * gpismi - route for SMI
+ * gpinmi - route for NMI
+ * mode - GPIO vs native function
+ * rxdis - disable Rx buffer
+ * txdis - disable Tx buffer
+ */
+#define _DW0_VALS(rst, rxst, rxraw1, rxev, rxgf, rxinv, gpiioapic, gpisci, \
+ gpismi, gpinmi, mode, rxdis, txdis) \
+ (PAD_FIELD(PADRSTCFG, rst) | \
+ PAD_FIELD(RXPADSTSEL, rxst) | \
+ PAD_FIELD(RXRAW1, rxraw1) | \
+ PAD_FIELD(RXEVCFG, rxev) | \
+ PAD_FIELD(PREGFRXSEL, rxgf) | \
+ PAD_FIELD(RXINV, rxinv) | \
+ PAD_FIELD(GPIROUTIOXAPIC, gpiioapic) | \
+ PAD_FIELD(GPIROUTSCI, gpisci) | \
+ PAD_FIELD(GPIROUTSMI, gpismi) | \
+ PAD_FIELD(GPIROUTNMI, gpinmi) | \
+ PAD_FIELD(PMODE, mode) | \
+ PAD_FIELD(GPIORXDIS, rxdis) | \
+ PAD_FIELD(GPIOTXDIS, txdis))
+
+#define _PAD_CFG_ATTRS(pad_, term_, dw0_, attrs_) \
+ { \
+ .pad = pad_, \
+ .attrs = PAD_FIELD(PAD_TERM, term_) | attrs_, \
+ .dw0 = dw0_, \
+ }
+
+/* Default to ACPI owned. Ownership only matters for GPI pads. */
+#define _PAD_CFG(pad_, term_, dw0_) \
+ _PAD_CFG_ATTRS(pad_, term_, dw0_, PAD_FIELD(HOSTSW, ACPI))
+
+/* Native Function - No Rx buffer manipulation */
+#define PAD_CFG_NF(pad_, term_, rst_, func_) \
+ _PAD_CFG(pad_, term_, \
+ _DW0_VALS(rst_, RAW, NO, LEVEL, NO, NO, NO, NO, NO, NO, func_, NO, NO))
+
+/* Native 1.8V tolerant pad, only applies to some pads like I2C/I2S. */
+#define PAD_CFG_NF_1V8(pad_, term_, rst_, func_) \
+ _PAD_CFG_ATTRS(pad_, term_, \
+ _DW0_VALS(rst_, RAW, NO, LEVEL, NO, NO, \
+ NO, NO, NO, NO, func_, NO, NO), PAD_FIELD(PAD_TOL, 1V8))
+
+/* Unused PINS will be controlled by GPIO controller (PMODE = GPIO) and
+ GPIO TX/RX will be disabled. */
+#define PAD_CFG_NC(pad_) \
+ _PAD_CFG(pad_, NONE, \
+ _DW0_VALS(DEEP, RAW, NO, LEVEL, NO, NO, NO, NO, NO, NO, GPIO, YES, YES))
+
+/* General purpose output with termination. */
+#define PAD_CFG_TERM_GPO(pad_, val_, term_, rst_) \
+ _PAD_CFG(pad_, term_, \
+ _DW0_VALS(rst_, RAW, NO, LEVEL, NO, NO, NO, NO, NO, NO, GPIO, YES, NO) \
+ | PAD_FIELD_VAL(GPIOTXSTATE, val_))
+
+/* General purpose output. By default no termination. */
+#define PAD_CFG_GPO(pad_, val_, rst_) \
+ PAD_CFG_TERM_GPO(pad_, val_, NONE, rst_)
+
+/* General purpose input with no special IRQ routing. */
+#define PAD_CFG_GPI(pad_, term_, rst_) \
+ _PAD_CFG_ATTRS(pad_, term_, \
+ _DW0_VALS(rst_, RAW, NO, LEVEL, NO, NO, NO, NO, NO, NO, GPIO, NO, YES),\
+ PAD_FIELD(HOSTSW, GPIO))
+
+/* General purpose input passed through to IOxAPIC. Assume APIC logic can
+ * handle polarity/edge/level constraints. */
+#define PAD_CFG_GPI_APIC(pad_, term_, rst_) \
+ _PAD_CFG(pad_, term_, \
+ _DW0_VALS(rst_, RAW, NO, LEVEL, NO, NO, YES, NO, NO, NO, GPIO, NO, YES))
+
+/* General purpose input routed to SCI. This assumes edge triggered events. */
+#define PAD_CFG_GPI_ACPI_SCI(pad_, term_, rst_, inv_) \
+ _PAD_CFG_ATTRS(pad_, term_, \
+ _DW0_VALS(rst_, RAW, NO, EDGE, NO, inv_, \
+ NO, YES, NO, NO, GPIO, NO, YES), PAD_FIELD(HOSTSW, ACPI))
+
+/* General purpose input routed to SMI. This assumes edge triggered events. */
+#define PAD_CFG_GPI_ACPI_SMI(pad_, term_, rst_, inv_) \
+ _PAD_CFG_ATTRS(pad_, term_, \
+ _DW0_VALS(rst_, RAW, NO, EDGE, NO, inv_, \
+ NO, NO, YES, NO, GPIO, NO, YES), PAD_FIELD(HOSTSW, ACPI))
+
+/*
+ * The 'attrs' field carries the termination in bits 13:10 and tolerance in bit
+ * 25 to match up with thd DW1 pad configuration register. Additionally, other
+ * attributes can be applied such as the ones below. Bit allocation matters.
+ */
+#define HOSTSW_SHIFT 0
+#define HOSTSW_MASK 1
+#define HOSTSW_ACPI HOSTSW_OWN_ACPI
+#define HOSTSW_GPIO HOSTSW_OWN_GPIO
+
+struct pad_config {
+ uint16_t pad;
+ uint32_t attrs;
+ uint32_t dw0;
+};
+
+#endif /* __ACPI__ */
+#endif
diff --git a/src/soc/intel/kabylake/include/soc/gpio_defs.h b/src/soc/intel/kabylake/include/soc/gpio_defs.h
new file mode 100644
index 0000000..4008dfe
--- /dev/null
+++ b/src/soc/intel/kabylake/include/soc/gpio_defs.h
@@ -0,0 +1,509 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2015 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _SOC_GPIO_DEFS_H_
+#define _SOC_GPIO_DEFS_H_
+
+/*
+ * There are 8 GPIO groups. GPP_A -> GPP_G and GPD. GPD is the special case
+ * where that group is not so generic. So most of the fixed numbers and macros
+ * are based on the GPP groups. The GPIO groups are accessed through register
+ * blocks called communities.
+ */
+#define GPP_A 0
+#define GPP_B 1
+#define GPP_C 2
+#define GPP_D 3
+#define GPP_E 4
+#define GPP_F 5
+#define GPP_G 6
+#define GPD 7
+#define GPIO_NUM_GROUPS 8
+#define GPIO_MAX_NUM_PER_GROUP 24
+
+/*
+ * GPIOs are ordered monotonically increasing to match ACPI/OS driver.
+ */
+
+/* Group A */
+#define GPP_A0 0
+#define GPP_A1 1
+#define GPP_A2 2
+#define GPP_A3 3
+#define GPP_A4 4
+#define GPP_A5 5
+#define GPP_A6 6
+#define GPP_A7 7
+#define GPP_A8 8
+#define GPP_A9 9
+#define GPP_A10 10
+#define GPP_A11 11
+#define GPP_A12 12
+#define GPP_A13 13
+#define GPP_A14 14
+#define GPP_A15 15
+#define GPP_A16 16
+#define GPP_A17 17
+#define GPP_A18 18
+#define GPP_A19 19
+#define GPP_A20 20
+#define GPP_A21 21
+#define GPP_A22 22
+#define GPP_A23 23
+/* Group B */
+#define GPP_B0 24
+#define GPP_B1 25
+#define GPP_B2 26
+#define GPP_B3 27
+#define GPP_B4 28
+#define GPP_B5 29
+#define GPP_B6 30
+#define GPP_B7 31
+#define GPP_B8 32
+#define GPP_B9 33
+#define GPP_B10 34
+#define GPP_B11 35
+#define GPP_B12 36
+#define GPP_B13 37
+#define GPP_B14 38
+#define GPP_B15 39
+#define GPP_B16 40
+#define GPP_B17 41
+#define GPP_B18 42
+#define GPP_B19 43
+#define GPP_B20 44
+#define GPP_B21 45
+#define GPP_B22 46
+#define GPP_B23 47
+/* Group C */
+#define GPP_C0 48
+#define GPP_C1 49
+#define GPP_C2 50
+#define GPP_C3 51
+#define GPP_C4 52
+#define GPP_C5 53
+#define GPP_C6 54
+#define GPP_C7 55
+#define GPP_C8 56
+#define GPP_C9 57
+#define GPP_C10 58
+#define GPP_C11 59
+#define GPP_C12 60
+#define GPP_C13 61
+#define GPP_C14 62
+#define GPP_C15 63
+#define GPP_C16 64
+#define GPP_C17 65
+#define GPP_C18 66
+#define GPP_C19 67
+#define GPP_C20 68
+#define GPP_C21 69
+#define GPP_C22 70
+#define GPP_C23 71
+/* Group D */
+#define GPP_D0 72
+#define GPP_D1 73
+#define GPP_D2 74
+#define GPP_D3 75
+#define GPP_D4 76
+#define GPP_D5 77
+#define GPP_D6 78
+#define GPP_D7 79
+#define GPP_D8 80
+#define GPP_D9 81
+#define GPP_D10 82
+#define GPP_D11 83
+#define GPP_D12 84
+#define GPP_D13 85
+#define GPP_D14 86
+#define GPP_D15 87
+#define GPP_D16 88
+#define GPP_D17 89
+#define GPP_D18 90
+#define GPP_D19 91
+#define GPP_D20 92
+#define GPP_D21 93
+#define GPP_D22 94
+#define GPP_D23 95
+/* Group E */
+#define GPP_E0 96
+#define GPP_E1 97
+#define GPP_E2 98
+#define GPP_E3 99
+#define GPP_E4 100
+#define GPP_E5 101
+#define GPP_E6 102
+#define GPP_E7 103
+#define GPP_E8 104
+#define GPP_E9 105
+#define GPP_E10 106
+#define GPP_E11 107
+#define GPP_E12 108
+#define GPP_E13 109
+#define GPP_E14 110
+#define GPP_E15 111
+#define GPP_E16 112
+#define GPP_E17 113
+#define GPP_E18 114
+#define GPP_E19 115
+#define GPP_E20 116
+#define GPP_E21 117
+#define GPP_E22 118
+#define GPP_E23 119
+/* Group F */
+#define GPP_F0 120
+#define GPP_F1 121
+#define GPP_F2 122
+#define GPP_F3 123
+#define GPP_F4 124
+#define GPP_F5 125
+#define GPP_F6 126
+#define GPP_F7 127
+#define GPP_F8 128
+#define GPP_F9 129
+#define GPP_F10 130
+#define GPP_F11 131
+#define GPP_F12 132
+#define GPP_F13 133
+#define GPP_F14 134
+#define GPP_F15 135
+#define GPP_F16 136
+#define GPP_F17 137
+#define GPP_F18 138
+#define GPP_F19 139
+#define GPP_F20 140
+#define GPP_F21 141
+#define GPP_F22 142
+#define GPP_F23 143
+/* Group G */
+#define GPP_G0 144
+#define GPP_G1 145
+#define GPP_G2 146
+#define GPP_G3 147
+#define GPP_G4 148
+#define GPP_G5 149
+#define GPP_G6 150
+#define GPP_G7 151
+/* Group GPD */
+#define GPD0 152
+#define GPD1 153
+#define GPD2 154
+#define GPD3 155
+#define GPD4 156
+#define GPD5 157
+#define GPD6 158
+#define GPD7 159
+#define GPD8 160
+#define GPD9 161
+#define GPD10 162
+#define GPD11 163
+
+/*
+ * IOxAPIC IRQs for the GPIOs
+ */
+
+/* Group A */
+#define GPP_A0_IRQ 0x18
+#define GPP_A1_IRQ 0x19
+#define GPP_A2_IRQ 0x1a
+#define GPP_A3_IRQ 0x1b
+#define GPP_A4_IRQ 0x1c
+#define GPP_A5_IRQ 0x1d
+#define GPP_A6_IRQ 0x1e
+#define GPP_A7_IRQ 0x1f
+#define GPP_A8_IRQ 0x20
+#define GPP_A9_IRQ 0x21
+#define GPP_A10_IRQ 0x22
+#define GPP_A11_IRQ 0x23
+#define GPP_A12_IRQ 0x24
+#define GPP_A13_IRQ 0x25
+#define GPP_A14_IRQ 0x26
+#define GPP_A15_IRQ 0x27
+#define GPP_A16_IRQ 0x28
+#define GPP_A17_IRQ 0x29
+#define GPP_A18_IRQ 0x2a
+#define GPP_A19_IRQ 0x2b
+#define GPP_A20_IRQ 0x2c
+#define GPP_A21_IRQ 0x2d
+#define GPP_A22_IRQ 0x2e
+#define GPP_A23_IRQ 0x2f
+/* Group B */
+#define GPP_B0_IRQ 0x30
+#define GPP_B1_IRQ 0x31
+#define GPP_B2_IRQ 0x32
+#define GPP_B3_IRQ 0x33
+#define GPP_B4_IRQ 0x34
+#define GPP_B5_IRQ 0x35
+#define GPP_B6_IRQ 0x36
+#define GPP_B7_IRQ 0x37
+#define GPP_B8_IRQ 0x38
+#define GPP_B9_IRQ 0x39
+#define GPP_B10_IRQ 0x3a
+#define GPP_B11_IRQ 0x3b
+#define GPP_B12_IRQ 0x3c
+#define GPP_B13_IRQ 0x3d
+#define GPP_B14_IRQ 0x3e
+#define GPP_B15_IRQ 0x3f
+#define GPP_B16_IRQ 0x40
+#define GPP_B17_IRQ 0x41
+#define GPP_B18_IRQ 0x42
+#define GPP_B19_IRQ 0x43
+#define GPP_B20_IRQ 0x44
+#define GPP_B21_IRQ 0x45
+#define GPP_B22_IRQ 0x46
+#define GPP_B23_IRQ 0x47
+/* Group C */
+#define GPP_C0_IRQ 0x48
+#define GPP_C1_IRQ 0x49
+#define GPP_C2_IRQ 0x4a
+#define GPP_C3_IRQ 0x4b
+#define GPP_C4_IRQ 0x4c
+#define GPP_C5_IRQ 0x4d
+#define GPP_C6_IRQ 0x4e
+#define GPP_C7_IRQ 0x4f
+#define GPP_C8_IRQ 0x50
+#define GPP_C9_IRQ 0x51
+#define GPP_C10_IRQ 0x52
+#define GPP_C11_IRQ 0x53
+#define GPP_C12_IRQ 0x54
+#define GPP_C13_IRQ 0x55
+#define GPP_C14_IRQ 0x56
+#define GPP_C15_IRQ 0x57
+#define GPP_C16_IRQ 0x58
+#define GPP_C17_IRQ 0x59
+#define GPP_C18_IRQ 0x5a
+#define GPP_C19_IRQ 0x5b
+#define GPP_C20_IRQ 0x5c
+#define GPP_C21_IRQ 0x5d
+#define GPP_C22_IRQ 0x5e
+#define GPP_C23_IRQ 0x5f
+/* Group D */
+#define GPP_D0_IRQ 0x60
+#define GPP_D1_IRQ 0x61
+#define GPP_D2_IRQ 0x62
+#define GPP_D3_IRQ 0x63
+#define GPP_D4_IRQ 0x64
+#define GPP_D5_IRQ 0x65
+#define GPP_D6_IRQ 0x66
+#define GPP_D7_IRQ 0x67
+#define GPP_D8_IRQ 0x68
+#define GPP_D9_IRQ 0x69
+#define GPP_D10_IRQ 0x6a
+#define GPP_D11_IRQ 0x6b
+#define GPP_D12_IRQ 0x6c
+#define GPP_D13_IRQ 0x6d
+#define GPP_D14_IRQ 0x6e
+#define GPP_D15_IRQ 0x6f
+#define GPP_D16_IRQ 0x70
+#define GPP_D17_IRQ 0x71
+#define GPP_D18_IRQ 0x72
+#define GPP_D19_IRQ 0x73
+#define GPP_D20_IRQ 0x74
+#define GPP_D21_IRQ 0x75
+#define GPP_D22_IRQ 0x76
+#define GPP_D23_IRQ 0x77
+/* Group E */
+#define GPP_E0_IRQ 0x18
+#define GPP_E1_IRQ 0x19
+#define GPP_E2_IRQ 0x1a
+#define GPP_E3_IRQ 0x1b
+#define GPP_E4_IRQ 0x1c
+#define GPP_E5_IRQ 0x1d
+#define GPP_E6_IRQ 0x1e
+#define GPP_E7_IRQ 0x1f
+#define GPP_E8_IRQ 0x20
+#define GPP_E9_IRQ 0x21
+#define GPP_E10_IRQ 0x22
+#define GPP_E11_IRQ 0x23
+#define GPP_E12_IRQ 0x24
+#define GPP_E13_IRQ 0x25
+#define GPP_E14_IRQ 0x26
+#define GPP_E15_IRQ 0x27
+#define GPP_E16_IRQ 0x28
+#define GPP_E17_IRQ 0x29
+#define GPP_E18_IRQ 0x2a
+#define GPP_E19_IRQ 0x2b
+#define GPP_E20_IRQ 0x2c
+#define GPP_E21_IRQ 0x2d
+#define GPP_E22_IRQ 0x2e
+#define GPP_E23_IRQ 0x2f
+/* Group F */
+#define GPP_F0_IRQ 0x30
+#define GPP_F1_IRQ 0x31
+#define GPP_F2_IRQ 0x32
+#define GPP_F3_IRQ 0x33
+#define GPP_F4_IRQ 0x34
+#define GPP_F5_IRQ 0x35
+#define GPP_F6_IRQ 0x36
+#define GPP_F7_IRQ 0x37
+#define GPP_F8_IRQ 0x38
+#define GPP_F9_IRQ 0x39
+#define GPP_F10_IRQ 0x3a
+#define GPP_F11_IRQ 0x3b
+#define GPP_F12_IRQ 0x3c
+#define GPP_F13_IRQ 0x3d
+#define GPP_F14_IRQ 0x3e
+#define GPP_F15_IRQ 0x3f
+#define GPP_F16_IRQ 0x40
+#define GPP_F17_IRQ 0x41
+#define GPP_F18_IRQ 0x42
+#define GPP_F19_IRQ 0x43
+#define GPP_F20_IRQ 0x44
+#define GPP_F21_IRQ 0x45
+#define GPP_F22_IRQ 0x46
+#define GPP_F23_IRQ 0x47
+/* Group G */
+#define GPP_G0_IRQ 0x48
+#define GPP_G1_IRQ 0x49
+#define GPP_G2_IRQ 0x4a
+#define GPP_G3_IRQ 0x4b
+#define GPP_G4_IRQ 0x4c
+#define GPP_G5_IRQ 0x4d
+#define GPP_G6_IRQ 0x4e
+#define GPP_G7_IRQ 0x4f
+/* Group GPD */
+#define GPD0_IRQ 0x50
+#define GPD1_IRQ 0x51
+#define GPD2_IRQ 0x52
+#define GPD3_IRQ 0x53
+#define GPD4_IRQ 0x54
+#define GPD5_IRQ 0x55
+#define GPD6_IRQ 0x56
+#define GPD7_IRQ 0x57
+#define GPD8_IRQ 0x58
+#define GPD9_IRQ 0x59
+#define GPD10_IRQ 0x5a
+#define GPD11_IRQ 0x5b
+
+/* Register defines. */
+#define MISCCFG_OFFSET 0x10
+#define GPIO_DRIVER_IRQ_ROUTE_MASK 8
+#define GPIO_DRIVER_IRQ_ROUTE_IRQ14 0
+#define GPIO_DRIVER_IRQ_ROUTE_IRQ15 8
+#define GPE_DW_SHIFT 8
+#define GPE_DW_MASK 0xfff00
+#define PAD_OWN_REG_OFFSET 0x20
+#define PAD_OWN_PADS_PER 8
+#define PAD_OWN_WIDTH_PER 4
+#define PAD_OWN_MASK 0x03
+#define PAD_OWN_HOST 0x00
+#define PAD_OWN_ME 0x01
+#define PAD_OWN_ISH 0x02
+#define HOSTSW_OWN_REG_OFFSET 0xd0
+#define HOSTSW_OWN_PADS_PER 24
+#define HOSTSW_OWN_ACPI 0
+#define HOSTSW_OWN_GPIO 1
+#define PAD_CFG_DW_OFFSET 0x400
+ /* PADRSTCFG - when to reset the pad config */
+#define PADRSTCFG_SHIFT 30
+#define PADRSTCFG_MASK 0x3
+#define PADRSTCFG_DSW_PWROK 0
+#define PADRSTCFG_DEEP 1
+#define PADRSTCFG_PLTRST 2
+#define PADRSTCFG_RSMRST 3
+ /* RXPADSTSEL - raw signal or internal state */
+#define RXPADSTSEL_SHIFT 29
+#define RXPADSTSEL_MASK 0x1
+#define RXPADSTSEL_RAW 0
+#define RXPADSTSEL_INTERNAL 1
+ /* RXRAW1 - drive 1 instead instead of pad value */
+#define RXRAW1_SHIFT 28
+#define RXRAW1_MASK 0x1
+#define RXRAW1_NO 0
+#define RXRAW1_YES 1
+ /* RXEVCFG - Interrupt and wake types */
+#define RXEVCFG_SHIFT 25
+#define RXEVCFG_MASK 0x3
+#define RXEVCFG_LEVEL 0
+#define RXEVCFG_EDGE 1
+#define RXEVCFG_DRIVE0 2
+ /* PREGFRXSEL - use filtering on Rx pad */
+#define PREGFRXSEL_SHIFT 24
+#define PREGFRXSEL_MASK 0x1
+#define PREGFRXSEL_NO 0
+#define PREGFRXSEL_YES 1
+ /* RXINV - invert signal to SMI, SCI, NMI, or IRQ routing. */
+#define RXINV_SHIFT 23
+#define RXINV_MASK 0x1
+#define RXINV_NO 0
+#define RXINV_YES 1
+ /* GPIROUTIOXAPIC - route to io-xapic or not */
+#define GPIROUTIOXAPIC_SHIFT 20
+#define GPIROUTIOXAPIC_MASK 0x1
+#define GPIROUTIOXAPIC_NO 0
+#define GPIROUTIOXAPIC_YES 1
+ /* GPIROUTSCI - route to SCI */
+#define GPIROUTSCI_SHIFT 19
+#define GPIROUTSCI_MASK 0x1
+#define GPIROUTSCI_NO 0
+#define GPIROUTSCI_YES 1
+ /* GPIROUTSMI - route to SMI */
+#define GPIROUTSMI_SHIFT 18
+#define GPIROUTSMI_MASK 0x1
+#define GPIROUTSMI_NO 0
+#define GPIROUTSMI_YES 1
+ /* GPIROUTNMI - route to NMI */
+#define GPIROUTNMI_SHIFT 17
+#define GPIROUTNMI_MASK 0x1
+#define GPIROUTNMI_NO 0
+#define GPIROUTNMI_YES 1
+ /* PMODE - mode of pad */
+#define PMODE_SHIFT 10
+#define PMODE_MASK 0x3
+#define PMODE_GPIO 0
+#define PMODE_NF1 1
+#define PMODE_NF2 2
+#define PMODE_NF3 3
+ /* GPIORXDIS - Disable Rx */
+#define GPIORXDIS_SHIFT 9
+#define GPIORXDIS_MASK 0x1
+#define GPIORXDIS_NO 0
+#define GPIORXDIS_YES 1
+ /* GPIOTXDIS - Disable Tx */
+#define GPIOTXDIS_SHIFT 8
+#define GPIOTXDIS_MASK 0x1
+#define GPIOTXDIS_NO 0
+#define GPIOTXDIS_YES 1
+ /* GPIORXSTATE - Internal state after glitch filter */
+#define GPIORXSTATE_SHIFT 1
+#define GPIORXSTATE_MASK 0x1
+ /* GPIOTXSTATE - Drive value onto pad */
+#define GPIOTXSTATE_SHIFT 0
+#define GPIOTXSTATE_MASK 0x1
+#define PAD_CFG_DW_OFFSET 0x400
+ /* TERM - termination control */
+#define PAD_TERM_SHIFT 10
+#define PAD_TERM_MASK 0xf
+#define PAD_TERM_NONE 0
+#define PAD_TERM_5K_PD 2
+#define PAD_TERM_20K_PD 4
+#define PAD_TERM_1K_PU 9
+#define PAD_TERM_2K_PU 11
+#define PAD_TERM_5K_PU 10
+#define PAD_TERM_20K_PU 12
+#define PAD_TERM_667_PU 13
+#define PAD_TERM_NATIVE 15
+ /* TOL - voltage tolerance */
+#define PAD_TOL_SHIFT 25
+#define PAD_TOL_MASK 0x1
+#define PAD_TOL_3V3 0 /* 3.3V default */
+#define PAD_TOL_1V8 1 /* 1.8V tolerant */
+
+#define GPI_GPE_STS_OFFSET 0x140
+#define GPI_GPE_EN_OFFSET 0x160
+#define GPI_SMI_STS_OFFSET 0x180
+#define GPI_SMI_EN_OFFSET 0x1a0
+
+#endif /* _SOC_GPIO_DEFS_H_ */
diff --git a/src/soc/intel/kabylake/include/soc/interrupt.h b/src/soc/intel/kabylake/include/soc/interrupt.h
new file mode 100644
index 0000000..1796a05
--- /dev/null
+++ b/src/soc/intel/kabylake/include/soc/interrupt.h
@@ -0,0 +1,46 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _INTERRUPT_H_
+#define _INTERRUPT_H_
+
+/* Number of all PCH devices */
+#define PCH_MAX_DEV_INT_CONFIG 64
+
+/* Number of PxRC register in ITSS */
+#define PCH_PARC 0
+#define PCH_PBRC 1
+#define PCH_PCRC 2
+#define PCH_PDRC 3
+#define PCH_PERC 4
+#define PCH_PFRC 5
+#define PCH_PGRC 6
+#define PCH_PHRC 7
+#define PCH_MAX_IRQ_CONFIG 8
+
+#define DEVICE_INT_CONFIG(dev, func, line, irqno) {\
+ .Device = dev, \
+ .Function = func, \
+ .IntX = line, \
+ .Irq = irqno }
+
+#define no_int 0
+#define int_A 1
+#define int_B 2
+#define int_C 3
+#define int_D 4
+
+#endif /* _INTERRUPT_H_ */
diff --git a/src/soc/intel/kabylake/include/soc/iomap.h b/src/soc/intel/kabylake/include/soc/iomap.h
new file mode 100644
index 0000000..70365e8
--- /dev/null
+++ b/src/soc/intel/kabylake/include/soc/iomap.h
@@ -0,0 +1,71 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _SOC_IOMAP_H_
+#define _SOC_IOMAP_H_
+
+/*
+ * Memory-mapped I/O registers.
+ */
+#define MCFG_BASE_ADDRESS CONFIG_MMCONF_BASE_ADDRESS
+#define MCFG_BASE_SIZE 0x4000000
+
+#define PCH_PCR_BASE_ADDRESS 0xfd000000
+#define PCH_PCR_BASE_SIZE 0x1000000
+
+#define UART_DEBUG_BASE_ADDRESS 0xfe034000
+#define UART_DEBUG_BASE_SIZE 0x1000
+
+#define EARLY_I2C_BASE_ADDRESS 0xfe040000
+#define EARLY_I2C_BASE(x) (EARLY_I2C_BASE_ADDRESS + (0x1000 * (x)))
+
+#define MCH_BASE_ADDRESS 0xfed10000
+#define MCH_BASE_SIZE 0x8000
+
+#define DMI_BASE_ADDRESS 0xfed18000
+#define DMI_BASE_SIZE 0x1000
+
+#define EP_BASE_ADDRESS 0xfed19000
+#define EP_BASE_SIZE 0x1000
+
+#define EDRAM_BASE_ADDRESS 0xfed80000
+#define EDRAM_BASE_SIZE 0x4000
+
+#define GDXC_BASE_ADDRESS 0xfed84000
+#define GDXC_BASE_SIZE 0x1000
+
+#define HPET_BASE_ADDRESS 0xfed00000
+
+#define PCH_PWRM_BASE_ADDRESS 0xfe000000
+#define PCH_PWRM_BASE_SIZE 0x10000
+
+#define SPI_BASE_ADDRESS 0xfe010000
+
+#define GPIO_BASE_SIZE 0x10000
+
+/*
+ * I/O port address space
+ */
+#define SMBUS_BASE_ADDRESS 0x0efa0
+#define SMBUS_BASE_SIZE 0x20
+
+#define ACPI_BASE_ADDRESS 0x1800
+#define ACPI_BASE_SIZE 0x100
+
+#define TCO_BASE_ADDDRESS 0x400
+#define TCO_BASE_SIZE 0x20
+
+#endif
diff --git a/src/soc/intel/kabylake/include/soc/irq.h b/src/soc/intel/kabylake/include/soc/irq.h
new file mode 100644
index 0000000..dcc3704
--- /dev/null
+++ b/src/soc/intel/kabylake/include/soc/irq.h
@@ -0,0 +1,103 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _SOC_IRQ_H_
+#define _SOC_IRQ_H_
+
+#define GPIO_IRQ14 14
+#define GPIO_IRQ15 15
+
+#define PCH_IRQ10 10
+#define PCH_IRQ11 11
+
+#define SCI_IRQ9 9
+#define SCI_IRQ10 10
+#define SCI_IRQ11 11
+#define SCI_IRQ20 20
+#define SCI_IRQ21 21
+#define SCI_IRQ22 22
+#define SCI_IRQ23 23
+
+#define TCO_IRQ9 9
+#define TCO_IRQ10 10
+#define TCO_IRQ11 11
+#define TCO_IRQ20 20
+#define TCO_IRQ21 21
+#define TCO_IRQ22 22
+#define TCO_IRQ23 23
+
+#define LPSS_I2C0_IRQ 16
+#define LPSS_I2C1_IRQ 17
+#define LPSS_I2C2_IRQ 18
+#define LPSS_I2C3_IRQ 19
+#define LPSS_I2C4_IRQ 34
+#define LPSS_I2C5_IRQ 33
+#define LPSS_SPI0_IRQ 22
+#define LPSS_SPI1_IRQ 23
+#define LPSS_UART0_IRQ 20
+#define LPSS_UART1_IRQ 21
+#define LPSS_UART2_IRQ 32
+#define SDIO_IRQ 22
+
+#define cAVS_INTA_IRQ 16
+#define SMBUS_INTA_IRQ 16
+#define SMBUS_INTB_IRQ 17
+#define GbE_INTA_IRQ 16
+#define GbE_INTC_IRQ 18
+#define TRACE_HUB_INTA_IRQ 16
+#define TRACE_HUB_INTD_IRQ 19
+
+#define eMMC_IRQ 21
+#define SD_IRQ 23
+
+#define PCIE_1_IRQ 16
+#define PCIE_2_IRQ 17
+#define PCIE_3_IRQ 18
+#define PCIE_4_IRQ 19
+#define PCIE_5_IRQ 16
+#define PCIE_6_IRQ 17
+#define PCIE_7_IRQ 18
+#define PCIE_8_IRQ 19
+#define PCIE_9_IRQ 16
+#define PCIE_10_IRQ 17
+#define PCIE_11_IRQ 18
+#define PCIE_12_IRQ 19
+
+#define SATA_IRQ 16
+
+#define HECI_1_IRQ 16
+#define HECI_2_IRQ 17
+#define IDER_IRQ 18
+#define KT_IRQ 19
+#define HECI_3_IRQ 16
+
+#define XHCI_IRQ 16
+#define OTG_IRQ 17
+#define THRMAL_IRQ 18
+#define CIO_INTA_IRQ 16
+#define CIO_INTD_IRQ 19
+#define ISH_IRQ 20
+
+#define PEG_RP_INTA_IRQ 16
+#define PEG_RP_INTB_IRQ 17
+#define PEG_RP_INTC_IRQ 18
+#define PEG_RP_INTD_IRQ 19
+
+#define IGFX_IRQ 16
+#define SA_THERMAL_IRQ 16
+#define SKYCAM_IRQ 16
+#define GMM_IRQ 16
+#endif /* _SOC_IRQ_H_ */
diff --git a/src/soc/intel/kabylake/include/soc/lpc.h b/src/soc/intel/kabylake/include/soc/lpc.h
new file mode 100644
index 0000000..526c710
--- /dev/null
+++ b/src/soc/intel/kabylake/include/soc/lpc.h
@@ -0,0 +1,58 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _SOC_LPC_H_
+#define _SOC_LPC_H_
+
+/* PCI Configuration Space (D31:F0): LPC */
+#define ABASE 0x40
+#define ACNTL 0x44
+#define ACPI_EN (1 << 7)
+#define SCI_IRQ_SEL (7 << 0)
+#define SCIS_IRQ9 0
+#define SCIS_IRQ10 1
+#define SCIS_IRQ11 2
+#define SCIS_IRQ20 4
+#define SCIS_IRQ21 5
+#define SCIS_IRQ22 6
+#define SCIS_IRQ23 7
+#define SERIRQ_CNTL 0x64
+#define LPC_IO_DEC 0x80 /* IO Decode Ranges Register */
+#define COMA_RANGE 0x0 /* 0x3F8 - 0x3FF COM1*/
+#define COMB_RANGE 0x1 /* 0x2F8 - 0x2FF COM2*/
+#define LPC_EN 0x82 /* LPC IF Enables Register */
+#define CNF2_LPC_EN (1 << 13) /* 0x4e/0x4f */
+#define CNF1_LPC_EN (1 << 12) /* 0x2e/0x2f */
+#define MC_LPC_EN (1 << 11) /* 0x62/0x66 */
+#define KBC_LPC_EN (1 << 10) /* 0x60/0x64 */
+#define GAMEH_LPC_EN (1 << 9) /* 0x208/0x20f */
+#define GAMEL_LPC_EN (1 << 8) /* 0x200/0x207 */
+#define FDD_LPC_EN (1 << 3) /* LPC_IO_DEC[12] */
+#define LPT_LPC_EN (1 << 2) /* LPC_IO_DEC[9:8] */
+#define COMB_LPC_EN (1 << 1) /* LPC_IO_DEC[6:4] */
+#define COMA_LPC_EN (1 << 0) /* LPC_IO_DEC[2:0] */
+#define LPC_GEN1_DEC 0x84 /* LPC IF Generic Decode Range 1 */
+#define LPC_GEN2_DEC 0x88 /* LPC IF Generic Decode Range 2 */
+#define LPC_GEN3_DEC 0x8c /* LPC IF Generic Decode Range 3 */
+#define LPC_GEN4_DEC 0x90 /* LPC IF Generic Decode Range 4 */
+#define LGMR 0x98 /* LPC Generic Memory Range */
+#define BIOS_CNTL 0xdc
+#define LPC_BC_BILD (1 << 7) /* BILD */
+#define LPC_BC_LE (1 << 2) /* LE */
+#define LPC_BC_EISS (1 << 5) /* EISS */
+#define PCCTL 0xE0 /* PCI Clock Control */
+#define CLKRUN_EN (1 << 0)
+#endif
diff --git a/src/soc/intel/kabylake/include/soc/me.h b/src/soc/intel/kabylake/include/soc/me.h
new file mode 100644
index 0000000..d92b835
--- /dev/null
+++ b/src/soc/intel/kabylake/include/soc/me.h
@@ -0,0 +1,182 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008-2009 coresystems GmbH
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _KABYLAKE_ME_H_
+#define _KABYLAKE_ME_H_
+
+/*
+ * Management Engine PCI registers
+ */
+#define PCI_ME_HFSTS1 0x40
+#define ME_HFS_CWS_RESET 0
+#define ME_HFS_CWS_INIT 1
+#define ME_HFS_CWS_REC 2
+#define ME_HFS_CWS_NORMAL 5
+#define ME_HFS_CWS_WAIT 6
+#define ME_HFS_CWS_TRANS 7
+#define ME_HFS_CWS_INVALID 8
+#define ME_HFS_STATE_PREBOOT 0
+#define ME_HFS_STATE_M0_UMA 1
+#define ME_HFS_STATE_M3 4
+#define ME_HFS_STATE_M0 5
+#define ME_HFS_STATE_BRINGUP 6
+#define ME_HFS_STATE_ERROR 7
+#define ME_HFS_ERROR_NONE 0
+#define ME_HFS_ERROR_UNCAT 1
+#define ME_HFS_ERROR_IMAGE 3
+#define ME_HFS_ERROR_DEBUG 4
+#define ME_HFS_MODE_NORMAL 0
+#define ME_HFS_MODE_DEBUG 2
+#define ME_HFS_MODE_DIS 3
+#define ME_HFS_MODE_OVER_JMPR 4
+#define ME_HFS_MODE_OVER_MEI 5
+#define ME_HFS_BIOS_DRAM_ACK 1
+#define ME_HFS_POWER_SOURCE_AC 1
+#define ME_HFS_POWER_SOURCE_DC 2
+
+struct me_hfs {
+ u32 working_state: 4;
+ u32 mfg_mode: 1;
+ u32 fpt_bad: 1;
+ u32 operation_state: 3;
+ u32 fw_init_complete: 1;
+ u32 ft_bup_ld_flr: 1;
+ u32 update_in_progress: 1;
+ u32 error_code: 4;
+ u32 operation_mode: 4;
+ u32 reset_count: 4;
+ u32 boot_options_present: 1;
+ u32 reserved1: 1;
+ u32 bist_test_state: 1;
+ u32 bist_reset_request: 1;
+ u32 current_power_source: 2;
+ u32 d3_support_valid: 1;
+ u32 d0i3_support_valid: 1;
+} __attribute__ ((packed));
+
+#define PCI_ME_HFSTS2 0x48
+/* Infrastructure Progress Values */
+#define ME_HFS2_PHASE_ROM 0
+#define ME_HFS2_PHASE_UKERNEL 2
+#define ME_HFS2_PHASE_BUP 3
+#define ME_HFS2_PHASE_HOST_COMM 6
+/* Current State - Based on Infra Progress values. */
+/* ROM State */
+#define ME_HFS2_STATE_ROM_BEGIN 0
+#define ME_HFS2_STATE_ROM_DISABLE 6
+/* BUP State */
+#define ME_HFS2_STATE_BUP_INIT 0
+#define ME_HFS2_STATE_BUP_DIS_HOST_WAKE 1
+#define ME_HFS2_STATE_BUP_CG_ENABLE 2
+#define ME_HFS2_STATE_BUP_PM_HND_EN 3
+#define ME_HFS2_STATE_BUP_FLOW_DET 4
+#define ME_HFS2_STATE_BUP_PMC_PATCHING 5
+#define ME_HFS2_STATE_BUP_GET_FLASH_VSCC 6
+#define ME_HFS2_STATE_BUP_SET_FLASH_VSCC 7
+#define ME_HFS2_STATE_BUP_VSCC_ERR 8
+#define ME_HFS2_STATE_BUP_EFSS_INIT 9
+#define ME_HFS2_STATE_BUP_CHECK_STRAP 0xa
+#define ME_HFS2_STATE_BUP_PWR_OK_TIMEOUT 0xb
+#define ME_HFS2_STATE_BUP_STRAP_DIS 0xc
+#define ME_HFS2_STATE_BUP_MANUF_OVRD_STRAP 0xd
+#define ME_HFS2_STATE_BUP_M3 0x11
+#define ME_HFS2_STATE_BUP_M0 0x12
+#define ME_HFS2_STATE_BUP_FLOW_DET_ERR 0x13
+#define ME_HFS2_STATE_BUP_M3_CLK_ERR 0x15
+#define ME_HFS2_STATE_BUP_CPU_RESET_DID_TIMEOUT_MEM_MISSING 0x17
+#define ME_HFS2_STATE_BUP_M3_KERN_LOAD 0x18
+#define ME_HFS2_STATE_BUP_T32_MISSING 0x1c
+#define ME_HFS2_STATE_BUP_WAIT_DID 0x1f
+#define ME_HFS2_STATE_BUP_WAIT_DID_FAIL 0x20
+#define ME_HFS2_STATE_BUP_DID_NO_FAIL 0x21
+#define ME_HFS2_STATE_BUP_ENABLE_UMA 0x22
+#define ME_HFS2_STATE_BUP_ENABLE_UMA_ERR 0x23
+#define ME_HFS2_STATE_BUP_SEND_DID_ACK 0x24
+#define ME_HFS2_STATE_BUP_SEND_DID_ACK_ERR 0x25
+#define ME_HFS2_STATE_BUP_M0_CLK 0x26
+#define ME_HFS2_STATE_BUP_M0_CLK_ERR 0x27
+#define ME_HFS2_STATE_BUP_TEMP_DIS 0x28
+#define ME_HFS2_STATE_BUP_M0_KERN_LOAD 0x32
+/* Policy Module State */
+#define ME_HFS2_STATE_POLICY_ENTRY 0
+#define ME_HFS2_STATE_POLICY_RCVD_S3 3
+#define ME_HFS2_STATE_POLICY_RCVD_S4 4
+#define ME_HFS2_STATE_POLICY_RCVD_S5 5
+#define ME_HFS2_STATE_POLICY_RCVD_UPD 6
+#define ME_HFS2_STATE_POLICY_RCVD_PCR 7
+#define ME_HFS2_STATE_POLICY_RCVD_NPCR 8
+#define ME_HFS2_STATE_POLICY_RCVD_HOST_WAKE 9
+#define ME_HFS2_STATE_POLICY_RCVD_AC_DC 0xa
+#define ME_HFS2_STATE_POLICY_RCVD_DID 0xb
+#define ME_HFS2_STATE_POLICY_VSCC_NOT_FOUND 0xc
+#define ME_HFS2_STATE_POLICY_VSCC_INVALID 0xd
+#define ME_HFS2_STATE_POLICY_FPB_ERR 0xe
+#define ME_HFS2_STATE_POLICY_DESCRIPTOR_ERR 0xf
+#define ME_HFS2_STATE_POLICY_VSCC_NO_MATCH 0x10
+/* Current PM Event Values */
+#define ME_HFS2_PMEVENT_CLEAN_MOFF_MX_WAKE 0
+#define ME_HFS2_PMEVENT_MOFF_MX_WAKE_ERROR 1
+#define ME_HFS2_PMEVENT_CLEAN_GLOBAL_RESET 2
+#define ME_HFS2_PMEVENT_CLEAN_GLOBAL_RESET_ERROR 3
+#define ME_HFS2_PMEVENT_CLEAN_ME_RESET 4
+#define ME_HFS2_PMEVENT_ME_RESET_EXCEPTION 5
+#define ME_HFS2_PMEVENT_PSEUDO_ME_RESET 6
+#define ME_HFS2_PMEVENT_CM0_CM3 7
+#define ME_HFS2_PMEVENT_CM3_CM0 8
+#define ME_HFS2_PMEVENT_NON_PWR_CYCLE_RESET 9
+#define ME_HFS2_PMEVENT_PWR_CYCLE_RESET_M3 0xa
+#define ME_HFS2_PMEVENT_PWR_CYCLE_RESET_MOFF 0xb
+#define ME_HFS2_PMEVENT_CMX_CMOFF 0xc
+#define ME_HFS2_PMEVENT_CM0_CM0PG 0xd
+#define ME_HFS2_PMEVENT_CM3_CM3PG 0xe
+#define ME_HFS2_PMEVENT_CM0PG_CM0 0xf
+
+struct me_hfs2 {
+ u32 reserved1: 3;
+ u32 invoke_mebx: 1;
+ u32 cpu_replaced_sts: 1;
+ u32 reserved2: 1;
+ u32 mfs_failure: 1;
+ u32 warm_reset_request: 1;
+ u32 cpu_replaced_valid: 1;
+ u32 low_power_state: 1;
+ u32 power_gating_ind: 1;
+ u32 reserved3: 1;
+ u32 fw_upd_forced_sb: 1;
+ u32 reserved4: 3;
+ u32 current_state: 8;
+ u32 current_pmevent: 4;
+ u32 progress_code: 4;
+} __attribute__ ((packed));
+
+#define PCI_ME_HFSTS3 0x60
+#define ME_HFS3_FW_SKU_CONSUMER 0x2
+#define ME_HFS3_FW_SKU_CORPORATE 0x3
+
+struct me_hfs3 {
+ u32 reserved1: 4;
+ u32 fw_sku: 3;
+ u32 encrypt_key_check: 1;
+ u32 pch_config_change: 1;
+ u32 reserved2: 21;
+ u32 encrypt_key_override: 1;
+ u32 power_down_mitigation: 1;
+} __attribute__ ((packed));
+
+void intel_me_status(void);
+
+#endif
diff --git a/src/soc/intel/kabylake/include/soc/msr.h b/src/soc/intel/kabylake/include/soc/msr.h
new file mode 100644
index 0000000..4f7d440
--- /dev/null
+++ b/src/soc/intel/kabylake/include/soc/msr.h
@@ -0,0 +1,109 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _SOC_MSR_H_
+#define _SOC_MSR_H_
+
+#define MSR_PIC_MSG_CONTROL 0x2e
+#define CORE_THREAD_COUNT_MSR 0x35
+#define IA32_FEATURE_CONTROL 0x3a
+#define CPUID_VMX (1 << 5)
+#define CPUID_SMX (1 << 6)
+#define MSR_PLATFORM_INFO 0xce
+#define PLATFORM_INFO_SET_TDP (1 << 29)
+#define MSR_PMG_CST_CONFIG_CONTROL 0xe2
+#define MSR_PMG_IO_CAPTURE_BASE 0xe4
+#define MSR_FEATURE_CONFIG 0x13c
+#define SMM_MCA_CAP_MSR 0x17d
+#define SMM_CPU_SVRSTR_BIT 57
+#define SMM_CPU_SVRSTR_MASK (1 << (SMM_CPU_SVRSTR_BIT - 32))
+#define MSR_FLEX_RATIO 0x194
+#define FLEX_RATIO_LOCK (1 << 20)
+#define FLEX_RATIO_EN (1 << 16)
+#define IA32_MISC_ENABLE 0x1a0
+#define MSR_MISC_PWR_MGMT 0x1aa
+#define MISC_PWR_MGMT_EIST_HW_DIS (1 << 0)
+#define MISC_PWR_MGMT_ISST_EN (1 << 6)
+#define MISC_PWR_MGMT_ISST_EN_INT (1 << 7)
+#define MISC_PWR_MGMT_ISST_EN_EPP (1 << 12)
+#define MSR_TURBO_RATIO_LIMIT 0x1ad
+#define MSR_TEMPERATURE_TARGET 0x1a2
+#define IA32_PERF_CTL 0x199
+#define IA32_THERM_INTERRUPT 0x19b
+#define IA32_ENERGY_PERFORMANCE_BIAS 0x1b0
+#define ENERGY_POLICY_PERFORMANCE 0
+#define ENERGY_POLICY_NORMAL 6
+#define ENERGY_POLICY_POWERSAVE 15
+#define IA32_PACKAGE_THERM_INTERRUPT 0x1b2
+#define EMRR_PHYS_BASE_MSR 0x1f4
+#define EMRR_PHYS_MASK_MSR 0x1f5
+#define IA32_PLATFORM_DCA_CAP 0x1f8
+#define MSR_POWER_CTL 0x1fc
+#define MSR_LT_LOCK_MEMORY 0x2e7
+#define UNCORE_PRMRR_PHYS_BASE_MSR 0x2f4
+#define UNCORE_PRMRR_PHYS_MASK_MSR 0x2f5
+#define IA32_MC0_STATUS 0x401
+#define SMM_FEATURE_CONTROL_MSR 0x4e0
+#define SMM_CPU_SAVE_EN (1 << 1)
+
+#define MSR_C_STATE_LATENCY_CONTROL_0 0x60a
+#define MSR_C_STATE_LATENCY_CONTROL_1 0x60b
+#define MSR_C_STATE_LATENCY_CONTROL_2 0x60c
+#define MSR_C_STATE_LATENCY_CONTROL_3 0x633
+#define MSR_C_STATE_LATENCY_CONTROL_4 0x634
+#define MSR_C_STATE_LATENCY_CONTROL_5 0x635
+#define IRTL_VALID (1 << 15)
+#define IRTL_1_NS (0 << 10)
+#define IRTL_32_NS (1 << 10)
+#define IRTL_1024_NS (2 << 10)
+#define IRTL_32768_NS (3 << 10)
+#define IRTL_1048576_NS (4 << 10)
+#define IRTL_33554432_NS (5 << 10)
+#define IRTL_RESPONSE_MASK (0x3ff)
+#define MSR_COUNTER_24_MHZ 0x637
+
+/* long duration in low dword, short duration in high dword */
+#define MSR_PKG_POWER_LIMIT 0x610
+#define PKG_POWER_LIMIT_MASK 0x7fff
+#define PKG_POWER_LIMIT_EN (1 << 15)
+#define PKG_POWER_LIMIT_CLAMP (1 << 16)
+#define PKG_POWER_LIMIT_TIME_SHIFT 17
+#define PKG_POWER_LIMIT_TIME_MASK 0x7f
+
+#define MSR_VR_CURRENT_CONFIG 0x601
+#define MSR_VR_MISC_CONFIG 0x603
+#define MSR_PKG_POWER_SKU_UNIT 0x606
+#define MSR_PKG_POWER_SKU 0x614
+#define MSR_DDR_RAPL_LIMIT 0x618
+#define MSR_VR_MISC_CONFIG2 0x636
+#define MSR_PP0_POWER_LIMIT 0x638
+#define MSR_PP1_POWER_LIMIT 0x640
+
+#define MSR_CONFIG_TDP_NOMINAL 0x648
+#define MSR_CONFIG_TDP_LEVEL1 0x649
+#define MSR_CONFIG_TDP_LEVEL2 0x64a
+#define MSR_CONFIG_TDP_CONTROL 0x64b
+#define MSR_TURBO_ACTIVATION_RATIO 0x64c
+
+/* SMM save state MSRs */
+#define SMBASE_MSR 0xc20
+#define IEDBASE_MSR 0xc22
+
+/* MTRR_CAP_MSR bits */
+#define SMRR_SUPPORTED (1<<11)
+#define PRMRR_SUPPORTED (1<<12)
+
+#endif
diff --git a/src/soc/intel/kabylake/include/soc/nhlt.h b/src/soc/intel/kabylake/include/soc/nhlt.h
new file mode 100644
index 0000000..ae74f53
--- /dev/null
+++ b/src/soc/intel/kabylake/include/soc/nhlt.h
@@ -0,0 +1,63 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2015 Google, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _SOC_NHLT_H_
+#define _SOC_NHLT_H_
+
+#include <nhlt.h>
+
+#define NHLT_VID 0x8086
+#define NHLT_DID_DMIC 0xae20
+#define NHLT_DID_BT 0xae30
+#define NHLT_DID_SSP 0xae34
+
+/*
+ * Kabylake NHLT link types. These values are to be used for the hwlink
+ * fields in the functions below to specify which link a device is on.
+ */
+
+enum {
+ AUDIO_LINK_SSP0,
+ AUDIO_LINK_SSP1,
+ AUDIO_LINK_SSP2, /* Only Bluetooth supported on SSP2. */
+ AUDIO_LINK_DMIC,
+};
+
+/*
+ * Add a dmic array composed of the provided number of channels. The kabylake
+ * SoC currently only supports dmic arrays on the dmic signals. Either 2
+ * or 4 channel arrays are supported. Returns 0 on success, < 0 on error.
+ */
+int nhlt_soc_add_dmic_array(struct nhlt *nhlt, int num_channels);
+
+/*
+ * Add nau88l25 headset codec on provided SSP link. Return 0 on succes, < 0
+ * on error.
+ */
+int nhlt_soc_add_nau88l25(struct nhlt *nhlt, int hwlink);
+
+/*
+ * Add ssm4567 smart amplifiers in stereo configuration on provided SSP link.
+ * Return 0 on success, < 0 on error.
+ */
+int nhlt_soc_add_ssm4567(struct nhlt *nhlt, int hwlink);
+
+/*
+ * Add max98357a amplifier in stereo configuration on provide SSP link.
+ * Return 0 on success, < 0 on error.
+ */
+int nhlt_soc_add_max98357(struct nhlt *nhlt, int hwlink);
+
+#endif
diff --git a/src/soc/intel/kabylake/include/soc/nvs.h b/src/soc/intel/kabylake/include/soc/nvs.h
new file mode 100644
index 0000000..5af840f
--- /dev/null
+++ b/src/soc/intel/kabylake/include/soc/nvs.h
@@ -0,0 +1,68 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008-2009 coresystems GmbH
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _SOC_NVS_H_
+#define _SOC_NVS_H_
+
+#include <rules.h>
+#include <vendorcode/google/chromeos/gnvs.h>
+
+typedef struct {
+ /* Miscellaneous */
+ u16 osys; /* 0x00 - Operating System */
+ u8 smif; /* 0x02 - SMI function call ("TRAP") */
+ u8 prm0; /* 0x03 - SMI function call parameter */
+ u8 prm1; /* 0x04 - SMI function call parameter */
+ u8 scif; /* 0x05 - SCI function call (via _L00) */
+ u8 prm2; /* 0x06 - SCI function call parameter */
+ u8 prm3; /* 0x07 - SCI function call parameter */
+ u8 lckf; /* 0x08 - Global Lock function for EC */
+ u8 prm4; /* 0x09 - Lock function parameter */
+ u8 prm5; /* 0x0a - Lock function parameter */
+ u8 pcnt; /* 0x0b - Processor Count */
+ u8 ppcm; /* 0x0c - Max PPC State */
+ u8 tmps; /* 0x0d - Temperature Sensor ID */
+ u8 tlvl; /* 0x0e - Throttle Level Limit */
+ u8 flvl; /* 0x0f - Current FAN Level */
+ u8 tcrt; /* 0x10 - Critical Threshold */
+ u8 tpsv; /* 0x11 - Passive Threshold */
+ u8 tmax; /* 0x12 - CPU Tj_max */
+ u8 s5u0; /* 0x13 - Enable USB in S5 */
+ u8 s3u0; /* 0x14 - Enable USB in S3 */
+ u8 s33g; /* 0x15 - Enable 3G in S3 */
+ u8 lids; /* 0x16 - LID State */
+ u8 pwrs; /* 0x17 - AC Power State */
+ u32 cmem; /* 0x18 - 0x1b - CBMEM TOC */
+ u32 cbmc; /* 0x1c - 0x1f - Coreboot Memory Console */
+ u64 pm1i; /* 0x20 - 0x27 - PM1 wake status bit */
+ u64 gpei; /* 0x28 - 0x2f - GPE wake status bit */
+ u8 dpte; /* 0x30 - Enable DPTF */
+ u64 nhla; /* 0x31 - NHLT Address */
+ u32 nhll; /* 0x39 - NHLT Length */
+ u16 cid1; /* 0x3d - Wifi Country Identifier */
+ u8 unused[193];
+
+ /* ChromeOS specific (0x100 - 0xfff) */
+ chromeos_acpi_t chromeos;
+} __attribute__((packed)) global_nvs_t;
+
+#if ENV_SMM
+/* Used in SMM to find the ACPI GNVS address */
+global_nvs_t *smm_get_gnvs(void);
+#endif
+
+#endif
diff --git a/src/soc/intel/kabylake/include/soc/pch.h b/src/soc/intel/kabylake/include/soc/pch.h
new file mode 100644
index 0000000..4a7c85e
--- /dev/null
+++ b/src/soc/intel/kabylake/include/soc/pch.h
@@ -0,0 +1,38 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008-2009 coresystems GmbH
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _SOC_PCH_H_
+#define _SOC_PCH_H_
+
+#include <device/device.h>
+#include <rules.h>
+
+/* PCH (SunRisePoint LP) */
+#define PCH_SPT_LP_SAMPLE 0x9d41
+#define PCH_SPT_LP_U_BASE 0x9d43
+#define PCH_SPT_LP_U_PREMIUM 0x9d48
+#define PCH_SPT_LP_Y_PREMIUM 0x9d46
+
+u8 pch_revision(void);
+u16 pch_type(void);
+u32 pch_read_soft_strap(int id);
+void pch_log_state(void);
+#if ENV_RAMSTAGE
+void pch_disable_devfn(device_t dev);
+#endif
+
+#endif /* _SOC_PCH_H_ */
diff --git a/src/soc/intel/kabylake/include/soc/pci_devs.h b/src/soc/intel/kabylake/include/soc/pci_devs.h
new file mode 100644
index 0000000..5f0b0f9
--- /dev/null
+++ b/src/soc/intel/kabylake/include/soc/pci_devs.h
@@ -0,0 +1,179 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _SOC_PCI_DEVS_H_
+#define _SOC_PCI_DEVS_H_
+
+#include <device/pci_def.h>
+#include <rules.h>
+
+#define _SA_DEVFN(slot) PCI_DEVFN(SA_DEV_SLOT_ ## slot, 0)
+#define _PCH_DEVFN(slot, func) PCI_DEVFN(PCH_DEV_SLOT_ ## slot, func)
+
+#if ENV_RAMSTAGE
+#include <device/device.h>
+#include <device/pci_def.h>
+#define _SA_DEV(slot) dev_find_slot(0, _SA_DEVFN(slot))
+#define _PCH_DEV(slot, func) dev_find_slot(0, _PCH_DEVFN(slot, func))
+#else
+#include <arch/io.h>
+#define _SA_DEV(slot) PCI_DEV(0, SA_DEV_SLOT_ ## slot, 0)
+#define _PCH_DEV(slot, func) PCI_DEV(0, PCH_DEV_SLOT_ ## slot, func)
+#endif
+
+/* System Agent Devices */
+
+#define SA_DEV_SLOT_ROOT 0x00
+#define SA_DEVFN_ROOT _SA_DEVFN(ROOT)
+#define SA_DEV_ROOT _SA_DEV(ROOT)
+
+#define SA_DEV_SLOT_IGD 0x02
+#define SA_DEVFN_IGD _SA_DEVFN(IGD)
+#define SA_DEV_IGD _SA_DEV(IGD)
+
+#define SA_DEV_SLOT_DSP 0x04
+#define SA_DEVFN_DSP _SA_DEVFN(DSP)
+#define SA_DEV_DSP _SA_DEV(DSP)
+
+/* PCH Devices */
+
+#define PCH_DEV_SLOT_ISH 0x13
+#define PCH_DEVFN_ISH _PCH_DEVFN(ISH, 0)
+
+#define PCH_DEV_SLOT_XHCI 0x14
+#define PCH_DEVFN_XHCI _PCH_DEVFN(XHCI, 0)
+#define PCH_DEVFN_USBOTG _PCH_DEVFN(XHCI, 1)
+#define PCH_DEVFN_THERMAL _PCH_DEVFN(XHCI, 2)
+#define PCH_DEVFN_CIO _PCH_DEVFN(XHCI, 3)
+#define PCH_DEV_XHCI _PCH_DEV(XHCI, 0)
+#define PCH_DEV_USBOTG _PCH_DEV(XHCI, 1)
+#define PCH_DEV_THERMAL _PCH_DEV(XHCI, 2)
+
+#define PCH_DEV_SLOT_SIO1 0x15
+#define PCH_DEVFN_I2C0 _PCH_DEVFN(SIO1, 0)
+#define PCH_DEVFN_I2C1 _PCH_DEVFN(SIO1, 1)
+#define PCH_DEVFN_I2C2 _PCH_DEVFN(SIO1, 2)
+#define PCH_DEVFN_I2C3 _PCH_DEVFN(SIO1, 3)
+#define PCH_DEV_I2C0 _PCH_DEV(SIO1, 0)
+#define PCH_DEV_I2C1 _PCH_DEV(SIO1, 1)
+#define PCH_DEV_I2C2 _PCH_DEV(SIO1, 2)
+#define PCH_DEV_I2C3 _PCH_DEV(SIO1, 3)
+
+#define PCH_DEV_SLOT_ME 0x16
+#define PCH_DEVFN_ME _PCH_DEVFN(ME, 0)
+#define PCH_DEVFN_ME_2 _PCH_DEVFN(ME, 1)
+#define PCH_DEVFN_ME_IDER _PCH_DEVFN(ME, 2)
+#define PCH_DEVFN_ME_KT _PCH_DEVFN(ME, 3)
+#define PCH_DEVFN_ME_3 _PCH_DEVFN(ME, 4)
+#define PCH_DEV_ME _PCH_DEV(ME, 0)
+#define PCH_DEV_ME_2 _PCH_DEV(ME, 1)
+#define PCH_DEV_ME_IDER _PCH_DEV(ME, 2)
+#define PCH_DEV_ME_KT _PCH_DEV(ME, 3)
+#define PCH_DEV_ME_3 _PCH_DEV(ME, 4)
+
+#define PCH_DEV_SLOT_SATA 0x17
+#define PCH_DEVFN_SATA _PCH_DEVFN(SATA, 0)
+#define PCH_DEV_SATA _PCH_DEV(SATA, 0)
+
+#define PCH_DEV_SLOT_SIO2 0x19
+#define PCH_DEVFN_UART2 _PCH_DEVFN(SIO2, 0)
+#define PCH_DEVFN_I2C5 _PCH_DEVFN(SIO2, 1)
+#define PCH_DEVFN_I2C4 _PCH_DEVFN(SIO2, 2)
+#define PCH_DEV_UART2 _PCH_DEV(SIO2, 0)
+#define PCH_DEV_I2C5 _PCH_DEV(SIO2, 1)
+#define PCH_DEV_I2C4 _PCH_DEV(SIO2, 2)
+
+#define PCH_DEV_SLOT_PCIE 0x1c
+#define PCH_DEVFN_PCIE1 _PCH_DEVFN(PCIE, 0)
+#define PCH_DEVFN_PCIE2 _PCH_DEVFN(PCIE, 1)
+#define PCH_DEVFN_PCIE3 _PCH_DEVFN(PCIE, 2)
+#define PCH_DEVFN_PCIE4 _PCH_DEVFN(PCIE, 3)
+#define PCH_DEVFN_PCIE5 _PCH_DEVFN(PCIE, 4)
+#define PCH_DEVFN_PCIE6 _PCH_DEVFN(PCIE, 5)
+#define PCH_DEVFN_PCIE7 _PCH_DEVFN(PCIE, 6)
+#define PCH_DEVFN_PCIE8 _PCH_DEVFN(PCIE, 7)
+#define PCH_DEV_PCIE1 _PCH_DEV(PCIE, 0)
+#define PCH_DEV_PCIE2 _PCH_DEV(PCIE, 1)
+#define PCH_DEV_PCIE3 _PCH_DEV(PCIE, 2)
+#define PCH_DEV_PCIE4 _PCH_DEV(PCIE, 3)
+#define PCH_DEV_PCIE5 _PCH_DEV(PCIE, 4)
+#define PCH_DEV_PCIE6 _PCH_DEV(PCIE, 5)
+
+#define PCH_DEV_SLOT_PCIE_1 0x1d
+#define PCH_DEVFN_PCIE9 _PCH_DEVFN(PCIE_1, 0)
+#define PCH_DEVFN_PCIE10 _PCH_DEVFN(PCIE_1, 1)
+#define PCH_DEVFN_PCIE11 _PCH_DEVFN(PCIE_1, 2)
+#define PCH_DEVFN_PCIE12 _PCH_DEVFN(PCIE_1, 3)
+
+#define PCH_DEV_SLOT_STORAGE 0x1e
+#define PCH_DEVFN_UART0 _PCH_DEVFN(STORAGE, 0)
+#define PCH_DEVFN_UART1 _PCH_DEVFN(STORAGE, 1)
+#define PCH_DEVFN_GSPI0 _PCH_DEVFN(STORAGE, 2)
+#define PCH_DEVFN_GSPI1 _PCH_DEVFN(STORAGE, 3)
+#define PCH_DEVFN_EMMC _PCH_DEVFN(STORAGE, 4)
+#define PCH_DEVFN_SDIO _PCH_DEVFN(STORAGE, 5)
+#define PCH_DEVFN_SDCARD _PCH_DEVFN(STORAGE, 6)
+#define PCH_DEV_UART0 _PCH_DEV(STORAGE, 0)
+#define PCH_DEV_UART1 _PCH_DEV(STORAGE, 1)
+#define PCH_DEV_EMMC _PCH_DEV(STORAGE, 4)
+#define PCH_DEV_SDCARD _PCH_DEV(STORAGE, 6)
+
+#define PCH_DEV_SLOT_LPC 0x1f
+#define PCH_DEVFN_LPC _PCH_DEVFN(LPC, 0)
+#define PCH_DEVFN_P2SB _PCH_DEVFN(LPC, 1)
+#define PCH_DEVFN_PMC _PCH_DEVFN(LPC, 2)
+#define PCH_DEVFN_HDA _PCH_DEVFN(LPC, 3)
+#define PCH_DEVFN_SMBUS _PCH_DEVFN(LPC, 4)
+#define PCH_DEVFN_SPI _PCH_DEVFN(LPC, 5)
+#define PCH_DEVFN_GBE _PCH_DEVFN(LPC, 6)
+#define PCH_DEVFN_TRACEHUB _PCH_DEVFN(LPC, 7)
+#define PCH_DEV_LPC _PCH_DEV(LPC, 0)
+#define PCH_DEV_P2SB _PCH_DEV(LPC, 1)
+#define PCH_DEV_PMC _PCH_DEV(LPC, 2)
+#define PCH_DEV_HDA _PCH_DEV(LPC, 3)
+#define PCH_DEV_SMBUS _PCH_DEV(LPC, 4)
+#define PCH_DEV_SPI _PCH_DEV(LPC, 5)
+#define PCH_DEV_GBE _PCH_DEV(LPC, 6)
+
+/* Convert I2C bus number to PCI device and function */
+static inline int i2c_bus_to_devfn(unsigned bus)
+{
+ switch (bus) {
+ case 0: return PCH_DEVFN_I2C0;
+ case 1: return PCH_DEVFN_I2C1;
+ case 2: return PCH_DEVFN_I2C2;
+ case 3: return PCH_DEVFN_I2C3;
+ case 4: return PCH_DEVFN_I2C4;
+ case 5: return PCH_DEVFN_I2C5;
+ }
+ return -1;
+}
+
+/* Convert PCI device and function to I2C bus number */
+static inline int i2c_devfn_to_bus(unsigned devfn)
+{
+ switch (devfn) {
+ case PCH_DEVFN_I2C0: return 0;
+ case PCH_DEVFN_I2C1: return 1;
+ case PCH_DEVFN_I2C2: return 2;
+ case PCH_DEVFN_I2C3: return 3;
+ case PCH_DEVFN_I2C4: return 4;
+ case PCH_DEVFN_I2C5: return 5;
+ }
+ return -1;
+}
+
+#endif
diff --git a/src/soc/intel/kabylake/include/soc/pcr.h b/src/soc/intel/kabylake/include/soc/pcr.h
new file mode 100644
index 0000000..78dd319
--- /dev/null
+++ b/src/soc/intel/kabylake/include/soc/pcr.h
@@ -0,0 +1,120 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _SOC_PCR_H_
+#define _SOC_PCR_H_
+
+/*
+ * Primary to sideband (P2SB) for private configuration registers (PCR).
+ */
+
+/* Port Id lives in bits 23:16 and register offset lives in 15:0 of address. */
+#define PCR_PORTID_SHIFT 16
+#define PCR_OFFSET_SHIFT 0
+
+/* DMI Control Register */
+#define R_PCH_PCR_DMI_DMIC 0x2234
+#define B_PCH_PCR_DMI_DMIC_SRL (1 << 31)
+#define R_PCH_PCR_DMI_LPCLGIR1 0x2730
+#define R_PCH_PCR_DMI_LPCLGIR2 0x2734
+#define R_PCH_PCR_DMI_LPCLGIR3 0x2738
+#define R_PCH_PCR_DMI_LPCLGIR4 0x273c
+#define R_PCH_PCR_DMI_GCS 0x274C
+#define B_PCH_PCR_DMI_GCS_BILD (1 << 0)
+#define R_PCH_PCR_DMI_LPCIOD 0x2770
+#define R_PCH_PCR_DMI_LPCIOE 0x2774
+
+/* RTC configuration */
+#define R_PCH_PCR_RTC_CONF 0x3400
+#define B_PCH_PCR_RTC_CONF_UCMOS_LOCK (1 << 4)
+#define B_PCH_PCR_RTC_CONF_LCMOS_LOCK (1 << 3)
+#define B_PCH_PCR_RTC_CONF_RESERVED (1 << 31)
+#define B_PCH_PCR_RTC_CONF_UCMOS_EN 0x4
+
+/* ITSS PCRs*/
+/* PIRQA Routing Control Register*/
+#define R_PCH_PCR_ITSS_PIRQA_ROUT 0x3100
+/* PIRQB Routing Control Register*/
+#define R_PCH_PCR_ITSS_PIRQB_ROUT 0x3101
+/* PIRQC Routing Control Register*/
+#define R_PCH_PCR_ITSS_PIRQC_ROUT 0x3102
+/* PIRQD Routing Control Register*/
+#define R_PCH_PCR_ITSS_PIRQD_ROUT 0x3103
+/* PIRQE Routing Control Register*/
+#define R_PCH_PCR_ITSS_PIRQE_ROUT 0x3104
+/* PIRQF Routing Control Register*/
+#define R_PCH_PCR_ITSS_PIRQF_ROUT 0x3105
+/* PIRQG Routing Control Register*/
+#define R_PCH_PCR_ITSS_PIRQG_ROUT 0x3106
+/* PIRQH Routing Control Register*/
+#define R_PCH_PCR_ITSS_PIRQH_ROUT 0x3107
+/* ITSS Power reduction control */
+#define R_PCH_PCR_ITSS_ITSSPRC 0x3300
+# define CGE8254 (1 << 2)
+
+/* IO Trap PCRs */
+/* Trap status Register */
+#define R_PCH_PCR_PSTH_TRPST 0x1E00
+/* Trapped cycle */
+#define R_PCH_PCR_PSTH_TRPC 0x1E10
+/* Trapped write data */
+#define R_PCH_PCR_PSTH_TRPD 0x1E18
+
+/* Serial IO UART controller legacy mode */
+#define R_PCH_PCR_SERIAL_IO_GPPRVRW7 0x618
+#define SIO_PCH_LEGACY_UART0 (1 << 0)
+#define SIO_PCH_LEGACY_UART1 (1 << 1)
+#define SIO_PCH_LEGACY_UART2 (1 << 2)
+
+/*
+ * P2SB port ids.
+ */
+#define PID_PSTH 0x89
+#define PID_GPIOCOM3 0xAC
+#define PID_GPIOCOM2 0xAD
+#define PID_GPIOCOM1 0xAE
+#define PID_GPIOCOM0 0xAF
+#define PID_PSF1 0xBA
+#define PID_SCS 0xC0
+#define PID_RTC 0xC3
+#define PID_ITSS 0xC4
+#define PID_LPC 0xC7
+#define PID_SERIALIO 0xCB
+#define PID_DMI 0xEF
+
+#define PCH_PCR_PSFX_T0_SHDW_PCIEN 0x1C
+
+#define PCH_PCR_PSFX_T0_SHDW_PCIEN_FUNDIS (1 << 8)
+#define PSF_BASE_ADDRESS 0xA00
+
+#if !defined(__ASSEMBLER__) && !defined(__ACPI__)
+#include <stdint.h>
+
+/* All these return 0 on success and < 0 on errror. */
+int pcr_read32(u8 pid, u16 offset, u32 *outdata);
+int pcr_read16(u8 pid, u16 offset, u16 *outdata);
+int pcr_read8(u8 pid, u16 offset, u8 *outdata);
+int pcr_write32(u8 pid, u16 offset, u32 indata);
+int pcr_write16(u8 pid, u16 offset, u16 indata);
+int pcr_write8(u8 pid, u16 offset, u8 indata);
+int pcr_andthenor32(u8 pid, u16 offset, u32 anddata, u32 ordata);
+int pcr_andthenor16(u8 pid, u16 offset, u16 anddata, u16 ordata);
+int pcr_andthenor8(u8 pid, u16 offset, u8 anddata, u8 ordata);
+
+/* Get the starting address of the port's registers. */
+uint8_t *pcr_port_regs(u8 pid);
+#endif /* if !defined(__ASSEMBLER__) && !defined(__ACPI__) */
+
+#endif /* _SOC_PCR_H_ */
diff --git a/src/soc/intel/kabylake/include/soc/pei_data.h b/src/soc/intel/kabylake/include/soc/pei_data.h
new file mode 100644
index 0000000..5c94727
--- /dev/null
+++ b/src/soc/intel/kabylake/include/soc/pei_data.h
@@ -0,0 +1,99 @@
+/*
+ * UEFI PEI wrapper
+ *
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Google Inc. nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _PEI_DATA_H_
+#define _PEI_DATA_H_
+
+#include <types.h>
+
+#define PEI_VERSION 22
+
+#define ABI_X86 __attribute__((regparm(0)))
+
+typedef void ABI_X86(*tx_byte_func)(unsigned char byte);
+
+struct pei_data {
+ uint32_t pei_version;
+
+ int boot_mode;
+ int ec_present;
+
+ /* Console output function */
+ tx_byte_func tx_byte;
+
+ /*
+ * DIMM SPD data for memory down configurations
+ * [CHANNEL][SLOT][SPD]
+ */
+ uint8_t spd_data[2][2][512];
+
+ /*
+ * LPDDR3 DQ byte map
+ * [CHANNEL][ITERATION][2]
+ *
+ * Maps which PI clocks are used by what LPDDR DQ Bytes (from CPU side)
+ * DQByteMap[0] - ClkDQByteMap:
+ * - If clock is per rank, program to [0xFF, 0xFF]
+ * - If clock is shared by 2 ranks, program to [0xFF, 0] or [0, 0xFF]
+ * - If clock is shared by 2 ranks but does not go to all bytes,
+ * Entry[i] defines which DQ bytes Group i services
+ * DQByteMap[1] - CmdNDQByteMap: [0] is CmdN/CAA and [1] is CmdN/CAB
+ * DQByteMap[2] - CmdSDQByteMap: [0] is CmdS/CAA and [1] is CmdS/CAB
+ * DQByteMap[3] - CkeDQByteMap : [0] is CKE /CAA and [1] is CKE /CAB
+ * For DDR, DQByteMap[3:1] = [0xFF, 0]
+ * DQByteMap[4] - CtlDQByteMap : Always program to [0xFF, 0]
+ * since we have 1 CTL / rank
+ * DQByteMap[5] - CmdVDQByteMap: Always program to [0xFF, 0]
+ * since we have 1 CA Vref
+ */
+ uint8_t dq_map[2][12];
+
+ /*
+ * LPDDR3 Map from CPU DQS pins to SDRAM DQS pins
+ * [CHANNEL][MAX_BYTES]
+ */
+ uint8_t dqs_map[2][8];
+ uint16_t RcompResistor[3];
+ uint16_t RcompTarget[5];
+ /* Data read from flash and passed into MRC */
+ const void *saved_data;
+ int saved_data_size;
+
+ /* Disable use of saved data (can be set by mainboard) */
+ int disable_saved_data;
+
+ /* Data from MRC that should be saved to flash */
+ void *data_to_save;
+ int data_to_save_size;
+ int mem_cfg_id;
+} __attribute__((packed));
+
+typedef struct pei_data PEI_DATA;
+
+#endif /* _PEI_DATA_H_ */
diff --git a/src/soc/intel/kabylake/include/soc/pei_wrapper.h b/src/soc/intel/kabylake/include/soc/pei_wrapper.h
new file mode 100644
index 0000000..0f52cda
--- /dev/null
+++ b/src/soc/intel/kabylake/include/soc/pei_wrapper.h
@@ -0,0 +1,27 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _SOC_PEI_WRAPPER_H_
+#define _SOC_PEI_WRAPPER_H_
+
+#include <soc/pei_data.h>
+
+typedef int ABI_X86(*pei_wrapper_entry_t)(struct pei_data *pei_data);
+
+void soc_fill_pei_data(struct pei_data *pei_data);
+void mainboard_fill_pei_data(struct pei_data *pei_data);
+
+#endif
diff --git a/src/soc/intel/kabylake/include/soc/pm.h b/src/soc/intel/kabylake/include/soc/pm.h
new file mode 100644
index 0000000..d1aa0b4
--- /dev/null
+++ b/src/soc/intel/kabylake/include/soc/pm.h
@@ -0,0 +1,194 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _SOC_PM_H_
+#define _SOC_PM_H_
+
+#include <arch/acpi.h>
+#include <arch/io.h>
+#include <soc/pmc.h>
+
+/* ACPI_BASE_ADDRESS / PMBASE */
+
+#define PM1_STS 0x00
+#define WAK_STS (1 << 15)
+#define PCIEXPWAK_STS (1 << 14)
+#define PRBTNOR_STS (1 << 11)
+#define RTC_STS (1 << 10)
+#define PWRBTN_STS (1 << 8)
+#define GBL_STS (1 << 5)
+#define BM_STS (1 << 4)
+#define TMROF_STS (1 << 0)
+#define PM1_EN 0x02
+#define PCIEXPWAK_DIS (1 << 14)
+#define RTC_EN (1 << 10)
+#define PWRBTN_EN (1 << 8)
+#define GBL_EN (1 << 5)
+#define TMROF_EN (1 << 0)
+#define PM1_CNT 0x04
+#define GBL_RLS (1 << 2)
+#define BM_RLD (1 << 1)
+#define SCI_EN (1 << 0)
+#define PM1_TMR 0x08
+#define SMI_EN 0x30
+#define XHCI_SMI_EN (1 << 31)
+#define ME_SMI_EN (1 << 30)
+#define GPIO_UNLOCK_SMI_EN (1 << 27)
+#define INTEL_USB2_EN (1 << 18)
+#define LEGACY_USB2_EN (1 << 17)
+#define PERIODIC_EN (1 << 14)
+#define TCO_EN (1 << 13)
+#define MCSMI_EN (1 << 11)
+#define BIOS_RLS (1 << 7)
+#define SWSMI_TMR_EN (1 << 6)
+#define APMC_EN (1 << 5)
+#define SLP_SMI_EN (1 << 4)
+#define LEGACY_USB_EN (1 << 3)
+#define BIOS_EN (1 << 2)
+#define EOS (1 << 1)
+#define GBL_SMI_EN (1 << 0)
+#define SMI_STS 0x34
+#define SMI_STS_BITS 32
+#define XHCI_SMI_STS_BIT 31
+#define ME_SMI_STS_BIT 30
+#define SERIAL_IO_SMI_STS_BIT 29
+#define ESPI_SMI_STS_BIT 28
+#define GPIO_UNLOCK_SMI_STS_BIT 27
+#define SPI_SMI_STS_BIT 26
+#define SCC_SMI_STS_BIT 25
+#define MONITOR_STS_BIT 21
+#define PCI_EXP_SMI_STS_BIT 20
+#define SMBUS_SMI_STS_BIT 16
+#define SERIRQ_SMI_STS_BIT 15
+#define PERIODIC_STS_BIT 14
+#define TCO_STS_BIT 13
+#define DEVMON_STS_BIT 12
+#define MCSMI_STS_BIT 11
+#define GPIO_STS_BIT 10
+#define GPE0_STS_BIT 9
+#define PM1_STS_BIT 8
+#define SWSMI_TMR_STS_BIT 6
+#define APM_STS_BIT 5
+#define SMI_ON_SLP_EN_STS_BIT 4
+#define LEGACY_USB_STS_BIT 3
+#define BIOS_STS_BIT 2
+#define UPWRC 0x3c
+#define UPWRC_WS (1 << 8)
+#define UPWRC_WE (1 << 1)
+#define UPWRC_SMI (1 << 0)
+#define GPE_CNTL 0x42
+#define SWGPE_CTRL (1 << 1)
+#define DEVACT_STS 0x44
+#define PM2_CNT 0x50
+
+#define GPE0_REG_MAX 4
+#define GPE0_REG_SIZE 32
+#define GPE0_STS(x) (0x80 + (x * 4))
+#define GPE_31_0 0 /* 0x80/0x90 = GPE[31:0] */
+#define GPE_63_32 1 /* 0x84/0x94 = GPE[63:32] */
+#define GPE_95_64 2 /* 0x88/0x98 = GPE[95:64] */
+#define GPE_STD 3 /* 0x8c/0x9c = Standard GPE */
+#define WADT_STS (1 << 18)
+#define LAN_WAK_STS (1 << 16)
+#define GPIO_T2_STS (1 << 15)
+#define ESPI_STS (1 << 14)
+#define PME_B0_STS (1 << 13)
+#define ME_SCI_STS (1 << 12)
+#define PME_STS (1 << 11)
+#define BATLOW_STS (1 << 10)
+#define PCI_EXP_STS (1 << 9)
+#define SMB_WAK_STS (1 << 7)
+#define TCOSCI_STS (1 << 6)
+#define SWGPE_STS (1 << 2)
+#define HOT_PLUG_STS (1 << 1)
+#define GPE0_EN(x) (0x90 + (x * 4))
+#define WADT_EN (1 << 18)
+#define LAN_WAK_EN (1 << 16)
+#define GPIO_T2_EN (1 << 15)
+#define ESPI_EN (1 << 14)
+#define PME_B0_EN (1 << 13)
+#define ME_SCI_EN (1 << 12)
+#define PME_EN (1 << 11)
+#define BATLOW_EN (1 << 10)
+#define PCI_EXP_EN (1 << 9)
+#define TCOSCI_EN (1 << 6)
+#define SWGPE_EN (1 << 2)
+#define HOT_PLUG_EN (1 << 1)
+
+#define GBLRST_CAUSE0_THERMTRIP (1 << 5)
+
+#define MAINBOARD_POWER_OFF 0
+#define MAINBOARD_POWER_ON 1
+#define MAINBOARD_POWER_KEEP 2
+
+struct chipset_power_state {
+ uint16_t pm1_sts;
+ uint16_t pm1_en;
+ uint32_t pm1_cnt;
+ uint16_t tco1_sts;
+ uint16_t tco2_sts;
+ uint32_t gpe0_sts[4];
+ uint32_t gpe0_en[4];
+ uint32_t gen_pmcon_a;
+ uint32_t gen_pmcon_b;
+ uint32_t gblrst_cause[2];
+ uint32_t prev_sleep_state;
+} __attribute__ ((packed));
+
+struct chipset_power_state *fill_power_state(void);
+
+/* PM1_CNT */
+void enable_pm1_control(uint32_t mask);
+void disable_pm1_control(uint32_t mask);
+
+/* PM1 */
+uint16_t clear_pm1_status(void);
+void enable_pm1(uint16_t events);
+uint32_t clear_smi_status(void);
+
+/* SMI */
+void enable_smi(uint32_t mask);
+void disable_smi(uint32_t mask);
+
+/* TCO */
+uint32_t clear_tco_status(void);
+void enable_tco_sci(void);
+
+/* GPE0 */
+uint32_t clear_gpe_status(void);
+void clear_gpe_enable(void);
+void enable_all_gpe(uint32_t set1, uint32_t set2, uint32_t set3, uint32_t set4);
+void disable_all_gpe(void);
+void enable_gpe(uint32_t mask);
+void disable_gpe(uint32_t mask);
+
+/* Return the selected ACPI SCI IRQ */
+int acpi_sci_irq(void);
+
+/* Get base address PMC memory mapped registers. */
+uint8_t *pmc_mmio_regs(void);
+/* Get base address of TCO I/O registers. */
+uint16_t pmc_tco_regs(void);
+
+static inline int deep_s3_enabled(void)
+{
+ uint32_t deep_s3_pol;
+
+ deep_s3_pol = read32(pmc_mmio_regs() + S3_PWRGATE_POL);
+ return !!(deep_s3_pol & (S3DC_GATE_SUS | S3AC_GATE_SUS));
+}
+
+#endif
diff --git a/src/soc/intel/kabylake/include/soc/pmc.h b/src/soc/intel/kabylake/include/soc/pmc.h
new file mode 100644
index 0000000..eb14b65
--- /dev/null
+++ b/src/soc/intel/kabylake/include/soc/pmc.h
@@ -0,0 +1,112 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _SOC_PMC_H_
+#define _SOC_PMC_H_
+
+/* PCI Configuration Space (D31:F2): PMC */
+#define ABASE 0x40
+#define ACTL 0x44
+#define PWRM_EN (1 << 8)
+#define ACPI_EN (1 << 7)
+#define SCI_IRQ_SEL (7 << 0)
+#define SCIS_IRQ9 0
+#define SCIS_IRQ10 1
+#define SCIS_IRQ11 2
+#define SCIS_IRQ20 4
+#define SCIS_IRQ21 5
+#define SCIS_IRQ22 6
+#define SCIS_IRQ23 7
+#define PWRMBASE 0x48
+#define GEN_PMCON_A 0xa0
+#define DC_PP_DIS (1 << 30)
+#define DSX_PP_DIS (1 << 29)
+#define AG3_PP_EN (1 << 28)
+#define SX_PP_EN (1 << 27)
+#define DISB (1 << 23)
+#define MEM_SR (1 << 21)
+#define MS4V (1 << 18)
+#define GBL_RST_STS (1 << 16)
+#define ALLOW_ICLK_PLL_SD_INC0 (1 << 15)
+#define MPHY_CRICLK_GATE_OVER (1 << 14)
+#define ALLOW_OPI_PLL_SD_INC0 (1 << 13)
+#define ALLOW_SPXB_CG_INC0 (1 << 12)
+#define BIOS_PCI_EXP_EN (1 << 10)
+#define PWRBTN_LVL (1 << 9)
+#define ALLOW_L1LOW_C0 (1 << 7)
+#define ALLOW_L1LOW_OPI_ON (1 << 6)
+#define SMI_LOCK (1 << 4)
+#define GEN_PMCON_B 0xa4
+#define SLP_STR_POL_LOCK (1 << 18)
+#define ACPI_BASE_LOCK (1 << 17)
+#define SUS_PWR_FLR (1 << 14)
+#define WOL_EN_OVRD (1 << 13)
+#define DIS_SLP_X_STRCH_SUS_UP (1 << 12)
+#define SLP_S3_MIN_ASST_WDTH_MASK (0x3 << 10)
+#define SLP_S3_MIN_ASST_WDTH_60USEC (0 << 10)
+#define SLP_S3_MIN_ASST_WDTH_1MS (1 << 10)
+#define SLP_S3_MIN_ASST_WDTH_50MS (2 << 10)
+#define SLP_S3_MIN_ASST_WDTH_2S (3 << 10)
+#define HOST_RST_STS (1 << 9)
+#define S4MAW_MASK (0x3 << 4)
+#define S4MAW_1S (1 << 4)
+#define S4MAW_2S (2 << 4)
+#define S4MAW_3S (3 << 4)
+#define S4MAW_4S (0 << 4)
+#define S4ASE (1 << 3)
+#define RTC_BATTERY_DEAD (1 << 2)
+#define PWR_FLR (1 << 1)
+#define SLEEP_AFTER_POWER_FAIL (1 << 0)
+#define ETR3 0xac
+#define ETR3_CF9LOCK (1 << 31)
+#define ETR3_CF9GR (1 << 20)
+
+/* Memory mapped IO registers in PMC */
+#define S3_PWRGATE_POL 0x28
+#define S3DC_GATE_SUS (1 << 1)
+#define S3AC_GATE_SUS (1 << 0)
+#define S4_PWRGATE_POL 0x2c
+#define S4DC_GATE_SUS (1 << 1)
+#define S4AC_GATE_SUS (1 << 0)
+#define S5_PWRGATE_POL 0x30
+#define S5DC_GATE_SUS (1 << 15)
+#define S5AC_GATE_SUS (1 << 14)
+#define DSX_CFG 0x34
+#define DSX_CFG_MASK 0x7
+#define DSX_EN_WAKE_PIN (1 << 2)
+#define DSX_EN_AC_PRESENT_PIN (1 << 1)
+#define DSX_EN_LAN_WAKE_PIN (1 << 0)
+#define PMSYNC_TPR_CFG 0xc4
+#define PMSYNC_LOCK (1 << 31)
+#define GPIO_CFG 0x120
+#define GPE0_DWX_MASK 0xf
+#define GPE0_DW0_SHIFT 0
+#define GPE0_DW1_SHIFT 4
+#define GPE0_DW2_SHIFT 8
+#define GBLRST_CAUSE0 0x124
+#define GBLRST_CAUSE1 0x128
+
+
+/* TCO registers and fields live behind TCOBASE I/O bar in SMBus device. */
+#define TCO1_STS 0x04
+#define TCO2_STS 0x06
+#define TCO2_STS_SECOND_TO 0x02
+#define TCO2_STS_BOOT 0x04
+#define TCO1_CNT 0x08
+#define TCO_LOCK (1 << 12)
+#define TCO_TMR_HLT (1 << 11)
+
+#endif
diff --git a/src/soc/intel/kabylake/include/soc/ramstage.h b/src/soc/intel/kabylake/include/soc/ramstage.h
new file mode 100644
index 0000000..27d318f
--- /dev/null
+++ b/src/soc/intel/kabylake/include/soc/ramstage.h
@@ -0,0 +1,31 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _SOC_RAMSTAGE_H_
+#define _SOC_RAMSTAGE_H_
+
+#include <chip.h>
+#include <device/device.h>
+#include <fsp/ramstage.h>
+
+void pch_enable_dev(device_t dev);
+void soc_init_pre_device(void *chip_info);
+void soc_init_cpus(device_t dev);
+const char *soc_acpi_name(struct device *dev);
+
+extern struct pci_operations soc_pci_ops;
+
+#endif
diff --git a/src/soc/intel/kabylake/include/soc/romstage.h b/src/soc/intel/kabylake/include/soc/romstage.h
new file mode 100644
index 0000000..56bace1
--- /dev/null
+++ b/src/soc/intel/kabylake/include/soc/romstage.h
@@ -0,0 +1,36 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _SOC_ROMSTAGE_H_
+#define _SOC_ROMSTAGE_H_
+
+#include <fsp/romstage.h>
+
+void i2c_early_init(void);
+void systemagent_early_init(void);
+void pch_early_init(void);
+void pch_uart_init(void);
+void intel_early_me_status(void);
+void report_platform_info(void);
+void set_max_freq(void);
+
+void enable_smbus(void);
+int smbus_read_byte(unsigned device, unsigned address);
+
+int early_spi_read_wpsr(u8 *sr);
+void mainboard_fill_spd_data(struct pei_data *pei_data);
+
+#endif /* _SOC_ROMSTAGE_H_ */
diff --git a/src/soc/intel/kabylake/include/soc/serialio.h b/src/soc/intel/kabylake/include/soc/serialio.h
new file mode 100644
index 0000000..02d6103
--- /dev/null
+++ b/src/soc/intel/kabylake/include/soc/serialio.h
@@ -0,0 +1,56 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _SERIALIO_H_
+#define _SERIALIO_H_
+
+#define SIO_REG_PPR_CLOCK 0x200
+#define SIO_REG_PPR_CLOCK_EN (1 << 0)
+#define SIO_REG_PPR_CLOCK_UPDATE (1 << 31)
+#define SIO_REG_PPR_CLOCK_N_DIV 0xc35
+#define SIO_REG_PPR_CLOCK_M_DIV 0x30
+
+#define SIO_REG_PPR_RESETS 0x204
+#define SIO_REG_PPR_RESETS_FUNC (1 << 0)
+#define SIO_REG_PPR_RESETS_APB (1 << 1)
+#define SIO_REG_PPR_RESETS_IDMA (1 << 2)
+
+typedef enum {
+ PchSerialIoDisabled,
+ PchSerialIoAcpi,
+ PchSerialIoPci,
+ PchSerialIoAcpiHidden,
+ PchSerialIoLegacyUart,
+ PchSerialIoSkipInit
+} PCH_SERIAL_IO_MODE;
+
+typedef enum {
+ PchSerialIoIndexI2C0,
+ PchSerialIoIndexI2C1,
+ PchSerialIoIndexI2C2,
+ PchSerialIoIndexI2C3,
+ PchSerialIoIndexI2C4,
+ PchSerialIoIndexI2C5,
+ PchSerialIoIndexSpi0,
+ PchSerialIoIndexSpi1,
+ PchSerialIoIndexUart0,
+ PchSerialIoIndexUart1,
+ PchSerialIoIndexUart2,
+ PchSerialIoIndexMax
+} PCH_SERIAL_IO_CONTROLLER;
+
+#endif
+
diff --git a/src/soc/intel/kabylake/include/soc/smbus.h b/src/soc/intel/kabylake/include/soc/smbus.h
new file mode 100644
index 0000000..613fbb3
--- /dev/null
+++ b/src/soc/intel/kabylake/include/soc/smbus.h
@@ -0,0 +1,51 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2005 Yinghai Lu <yinghailu at gmail.com>
+ * Copyright (C) 2009 coresystems GmbH
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _SOC_SMBUS_H_
+#define _SOC_SMBUS_H_
+
+/* PCI Configuration Space (D31:F3): SMBus */
+#define SMB_BASE 0x20
+#define HOSTC 0x40
+#define HST_EN (1 << 0)
+#define SMB_RCV_SLVA 0x09
+/* SMBUS TCO base address. */
+#define TCOBASE 0x50
+
+/* SMBus I/O bits. */
+#define SMBHSTSTAT 0x0
+#define SMBHSTCTL 0x2
+#define SMBHSTCMD 0x3
+#define SMBXMITADD 0x4
+#define SMBHSTDAT0 0x5
+#define SMBHSTDAT1 0x6
+#define SMBBLKDAT 0x7
+#define SMBTRNSADD 0x9
+#define SMBSLVDATA 0xa
+#define SMLINK_PIN_CTL 0xe
+#define SMBUS_PIN_CTL 0xf
+
+#define SMBUS_TIMEOUT (10 * 1000 * 100)
+#define SMBUS_SLAVE_ADDR 0x24
+
+int do_smbus_read_byte(unsigned smbus_base, unsigned device,
+ unsigned address);
+int do_smbus_write_byte(unsigned smbus_base, unsigned device,
+ unsigned address, unsigned data);
+
+#endif
diff --git a/src/soc/intel/kabylake/include/soc/smm.h b/src/soc/intel/kabylake/include/soc/smm.h
new file mode 100644
index 0000000..92095c8
--- /dev/null
+++ b/src/soc/intel/kabylake/include/soc/smm.h
@@ -0,0 +1,88 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _SOC_SMM_H_
+#define _SOC_SMM_H_
+
+#include <stdint.h>
+#include <cpu/x86/msr.h>
+#include <fsp/memmap.h>
+#include <fsp/romstage.h>
+#include <soc/gpio.h>
+
+struct ied_header {
+ char signature[10];
+ u32 size;
+ u8 reserved[34];
+} __attribute__ ((packed));
+
+struct smm_relocation_params {
+ u32 smram_base;
+ u32 smram_size;
+ u32 ied_base;
+ u32 ied_size;
+ msr_t smrr_base;
+ msr_t smrr_mask;
+ msr_t emrr_base;
+ msr_t emrr_mask;
+ msr_t uncore_emrr_base;
+ msr_t uncore_emrr_mask;
+ /*
+ * The smm_save_state_in_msrs field indicates if SMM save state
+ * locations live in MSRs. This indicates to the CPUs how to adjust
+ * the SMMBASE and IEDBASE
+ */
+ int smm_save_state_in_msrs;
+};
+
+/* Mainboard handler for GPI SMIs*/
+void mainboard_smi_gpi_handler(const struct gpi_status *sts);
+
+
+#if IS_ENABLED(CONFIG_HAVE_SMI_HANDLER)
+void smm_relocation_handler(int cpu, uintptr_t curr_smbase,
+ uintptr_t staggered_smbase);
+void smm_info(uintptr_t *perm_smbase, size_t *perm_smsize,
+ size_t *smm_save_state_size);
+void smm_initialize(void);
+void smm_relocate(void);
+
+/* These helpers are for performing SMM relocation. */
+void southbridge_trigger_smi(void);
+void southbridge_clear_smi_status(void);
+
+/*
+ * The initialization of the southbridge is split into 2 compoments. One is
+ * for clearing the state in the SMM registers. The other is for enabling
+ * SMIs.
+ */
+void southbridge_smm_clear_state(void);
+void southbridge_smm_enable_smi(void);
+#else /* CONFIG_HAVE_SMI_HANDLER */
+static inline void smm_relocation_handler(int cpu, uintptr_t curr_smbase,
+ uintptr_t staggered_smbase) {}
+static inline void smm_info(uintptr_t *perm_smbase, size_t *perm_smsize,
+ size_t *smm_save_state_size) {}
+static inline void smm_initialize(void) {}
+
+static inline void smm_relocate(void) {}
+static inline void southbridge_trigger_smi(void) {}
+static inline void southbridge_clear_smi_status(void) {}
+static inline void southbridge_smm_clear_state(void) {}
+static inline void southbridge_smm_enable_smi(void) {}
+#endif /* CONFIG_HAVE_SMI_HANDLER */
+
+#endif
diff --git a/src/soc/intel/kabylake/include/soc/spi.h b/src/soc/intel/kabylake/include/soc/spi.h
new file mode 100644
index 0000000..508e195
--- /dev/null
+++ b/src/soc/intel/kabylake/include/soc/spi.h
@@ -0,0 +1,136 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _SOC_SPI_H_
+#define _SOC_SPI_H_
+
+/*
+ * SPI Opcode Menu setup for SPIBAR lockdown
+ * should support most common flash chips.
+ */
+#define SPIDVID_OFFSET 0x0
+
+/* Reigsters within the SPIBAR */
+#define SPIBAR_SSFC 0xA1
+
+#define SPIBAR_PREOP 0xA4
+#define SPIBAR_OPTYPE 0xA6
+#define SPIBAR_OPMENU_LOWER 0xA8
+#define SPIBAR_OPMENU_UPPER 0xAc
+/* STRAP LOCK Register */
+#define SPIBAR_RESET_LOCK 0xF0
+#define SPIBAR_RESET_LOCK_DISABLE 0
+#define SPIBAR_RESET_LOCK_ENABLE 1
+/* STRAP MSG Control Register*/
+#define SPIBAR_RESET_CTRL 0xF4
+#define SPIBAR_RESET_CTRL_SSMC 1
+/* STRAP Data Register*/
+#define SPIBAR_RESET_DATA 0xF8
+
+#define SPI_PRR_MAX 5
+#define SPI_PRR_SHIFT 12
+#define SPI_PRR_MASK 0x7fff
+#define SPI_PRR_BASE_SHIFT 0
+#define SPI_PRR_LIMIT_SHIFT 16
+#define SPI_PRR_RPE (1 << 15) /* Read Protect */
+#define SPI_PRR_WPE (1 << 31) /* Write Protect */
+#define SPI_PRR(base, limit) \
+ (((((limit) >> SPI_PRR_SHIFT) & SPI_PRR_MASK) << SPI_PRR_LIMIT_SHIFT) |\
+ ((((base) >> SPI_PRR_SHIFT) & SPI_PRR_MASK) << SPI_PRR_BASE_SHIFT))
+
+#define SPI_OPMENU_0 0x01 /* WRSR: Write Status Register */
+#define SPI_OPTYPE_0 0x01 /* Write, no address */
+
+#define SPI_OPMENU_1 0x02 /* BYPR: Byte Program */
+#define SPI_OPTYPE_1 0x03 /* Write, address required */
+
+#define SPI_OPMENU_2 0x03 /* READ: Read Data */
+#define SPI_OPTYPE_2 0x02 /* Read, address required */
+
+#define SPI_OPMENU_3 0x05 /* RDSR: Read Status Register */
+#define SPI_OPTYPE_3 0x00 /* Read, no address */
+
+#define SPI_OPMENU_4 0x20 /* SE20: Sector Erase 0x20 */
+#define SPI_OPTYPE_4 0x03 /* Write, address required */
+
+#define SPI_OPMENU_5 0x9f /* RDID: Read ID */
+#define SPI_OPTYPE_5 0x00 /* Read, no address */
+
+#define SPI_OPMENU_6 0xd8 /* BED8: Block Erase 0xd8 */
+#define SPI_OPTYPE_6 0x03 /* Write, address required */
+
+#define SPI_OPMENU_7 0x0b /* FAST: Fast Read */
+#define SPI_OPTYPE_7 0x02 /* Read, address required */
+
+#define SPI_OPMENU_UPPER ((SPI_OPMENU_7 << 24) | (SPI_OPMENU_6 << 16) | \
+ (SPI_OPMENU_5 << 8) | SPI_OPMENU_4)
+#define SPI_OPMENU_LOWER ((SPI_OPMENU_3 << 24) | (SPI_OPMENU_2 << 16) | \
+ (SPI_OPMENU_1 << 8) | SPI_OPMENU_0)
+
+#define SPI_OPTYPE ((SPI_OPTYPE_7 << 14) | (SPI_OPTYPE_6 << 12) | \
+ (SPI_OPTYPE_5 << 10) | (SPI_OPTYPE_4 << 8) | \
+ (SPI_OPTYPE_3 << 6) | (SPI_OPTYPE_2 << 4) | \
+ (SPI_OPTYPE_1 << 2) | (SPI_OPTYPE_0))
+
+#define SPI_OPPREFIX ((0x50 << 8) | 0x06) /* EWSR and WREN */
+
+#define SPIBAR_HSFS 0x04 /* SPI hardware sequence status */
+#define SPIBAR_HSFS_FLOCKDN (1 << 15)/* Flash Configuration Lock-Down */
+#define SPIBAR_HSFS_SCIP (1 << 5) /* SPI Cycle In Progress */
+#define SPIBAR_HSFS_AEL (1 << 2) /* SPI Access Error Log */
+#define SPIBAR_HSFS_FCERR (1 << 1) /* SPI Flash Cycle Error */
+#define SPIBAR_HSFS_FDONE (1 << 0) /* SPI Flash Cycle Done */
+#define SPIBAR_HSFS_BERASE_MASK 3 /* Block/Sector Erase MASK */
+#define SPIBAR_HSFS_BERASE_OFFSET 3 /* Block/Sector Erase OFFSET */
+#define SPIBAR_HSFC 0x06 /* SPI hardware sequence control */
+#define SPIBAR_HSFC_BYTE_COUNT(c) (((c - 1) & 0x3f) << 8)
+#define SPIBAR_HSFC_CYCLE_READ (0 << 1) /* Read cycle */
+#define SPIBAR_HSFC_CYCLE_WRITE (2 << 1) /* Write cycle */
+#define SPIBAR_HSFC_CYCLE_ERASE (3 << 1) /* Erase cycle */
+#define SPIBAR_HSFC_GO (1 << 0) /* GO: start SPI transaction */
+#define SPIBAR_FADDR 0x08 /* SPI flash address */
+#define SPIBAR_FADDR_MASK 0x7FFFFFF
+
+#define SPIBAR_FDATA(n) (0x10 + (4 * n)) /* SPI flash data */
+#define SPIBAR_FPR(n) (0x84 + (4 * n)) /* SPI flash protected range */
+#define SPIBAR_FPR_WPE (1 << 31) /* Flash Write protected */
+#define SPIBAR_SSFS 0xA0
+#define SPIBAR_SSFS_ERROR (1 << 3)
+#define SPIBAR_SSFS_DONE (1 << 2)
+#define SPIBAR_SSFC 0xA1
+#define SPIBAR_SSFC_DATA (1 << 14)
+#define SPIBAR_SSFC_GO (1 << 1)
+
+#define SPIBAR_FDOC 0xB4
+#define SPIBAR_FDOC_COMPONENT (1 << 12)
+#define SPIBAR_FDOC_FDSI_1 (1 << 2)
+
+#define SPIBAR_FDOD 0xB8
+#define FLCOMP_C0DEN_MASK 0xF
+#define FLCOMP_C0DEN_8MB 4
+#define FLCOMP_C0DEN_16MB 5
+#define FLCOMP_C0DEN_32MB 6
+
+#define SPIBAR_BIOS_CNTL 0xDC
+#define SPIBAR_BC_BILD (1 << 7)
+#define SPIBAR_BC_EISS (1 << 5)
+#define SPIBAR_BC_LE (1 << 2)
+#define SPIBAR_BC_WPD (1 << 0)
+
+void *get_spi_bar(void);
+int spi_flash_protect(u32 start, u32 size);
+
+#endif
diff --git a/src/soc/intel/kabylake/include/soc/systemagent.h b/src/soc/intel/kabylake/include/soc/systemagent.h
new file mode 100644
index 0000000..d75ec9f
--- /dev/null
+++ b/src/soc/intel/kabylake/include/soc/systemagent.h
@@ -0,0 +1,122 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2008 coresystems GmbH
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _SOC_SYSTEMAGENT_H_
+#define _SOC_SYSTEMAGENT_H_
+
+#include <soc/iomap.h>
+
+#define SA_IGD_OPROM_VENDEV 0x80860406
+
+#define IGD_KABYLAKE_GT1_SULTM 0x1906
+#define IGD_KABYLAKE_GT2_SULXM 0x191E
+#define IGD_KABYLAKE_GT2_SULTM 0x1916
+
+#define MCH_KABYLAKE_ID_U 0x1904
+#define MCH_KABYLAKE_ID_Y 0x190c
+#define MCH_KABYLAKE_ID_ULX 0x1924
+
+/* Device 0:0.0 PCI configuration space */
+
+#define EPBAR 0x40
+#define MCHBAR 0x48
+#define PCIEXBAR 0x60
+#define DMIBAR 0x68
+#define GGC 0x50 /* GMCH Graphics Control */
+#define DEVEN 0x54 /* Device Enable */
+#define DEVEN_D7EN (1 << 14)
+#define DEVEN_D4EN (1 << 7)
+#define DEVEN_D3EN (1 << 5)
+#define DEVEN_D2EN (1 << 4)
+#define DEVEN_D1F0EN (1 << 3)
+#define DEVEN_D1F1EN (1 << 2)
+#define DEVEN_D1F2EN (1 << 1)
+#define DEVEN_D0EN (1 << 0)
+#define DPR 0x5c
+#define DPR_EPM (1 << 2)
+#define DPR_PRS (1 << 1)
+#define DPR_SIZE_MASK 0xff0
+
+#define PAM0 0x80
+#define PAM1 0x81
+#define PAM2 0x82
+#define PAM3 0x83
+#define PAM4 0x84
+#define PAM5 0x85
+#define PAM6 0x86
+
+#define SMRAM 0x88 /* System Management RAM Control */
+#define D_OPEN (1 << 6)
+#define D_CLS (1 << 5)
+#define D_LCK (1 << 4)
+#define G_SMRAME (1 << 3)
+#define C_BASE_SEG ((0 << 2) | (1 << 1) | (0 << 0))
+
+#define MESEG_BASE 0x70 /* Management Engine Base. */
+#define MESEG_LIMIT 0x78 /* Management Engine Limit. */
+#define REMAPBASE 0x90 /* Remap base. */
+#define REMAPLIMIT 0x98 /* Remap limit. */
+#define TOM 0xa0 /* Top of DRAM in memory controller space. */
+#define TOUUD 0xa8 /* Top of Upper Usable DRAM */
+#define BDSM 0xb0 /* Base Data Stolen Memory */
+#define BGSM 0xb4 /* Base GTT Stolen Memory */
+#define TSEG 0xb8 /* TSEG base */
+#define TOLUD 0xbc /* Top of Low Used Memory */
+#define SKPAD 0xdc /* Scratchpad Data */
+
+/* MCHBAR */
+
+#define MCHBAR8(x) (*(volatile u8 *)(MCH_BASE_ADDRESS + x))
+#define MCHBAR16(x) (*(volatile u16 *)(MCH_BASE_ADDRESS + x))
+#define MCHBAR32(x) (*(volatile u32 *)(MCH_BASE_ADDRESS + x))
+
+#define MCHBAR_PEI_VERSION 0x5034
+#define BIOS_RESET_CPL 0x5da8
+#define EDRAMBAR 0x5408
+#define MCH_PAIR 0x5418
+#define GDXCBAR 0x5420
+
+#define MCH_PKG_POWER_LIMIT_LO 0x59a0
+#define MCH_PKG_POWER_LIMIT_HI 0x59a4
+#define MCH_DDR_POWER_LIMIT_LO 0x58e0
+#define MCH_DDR_POWER_LIMIT_HI 0x58e4
+
+/* PCODE MMIO communications live in the MCHBAR. */
+#define BIOS_MAILBOX_INTERFACE 0x5da4
+#define MAILBOX_RUN_BUSY (1 << 31)
+/* Errors are returned back in bits 7:0. */
+#define MAILBOX_BIOS_ERROR_NONE 0
+#define MAILBOX_BIOS_ERROR_INVALID_COMMAND 1
+#define MAILBOX_BIOS_ERROR_TIMEOUT 2
+#define MAILBOX_BIOS_ERROR_ILLEGAL_DATA 3
+#define MAILBOX_BIOS_ERROR_RESERVED 4
+#define MAILBOX_BIOS_ERROR_ILLEGAL_VR_ID 5
+#define MAILBOX_BIOS_ERROR_VR_INTERFACE_LOCKED 6
+#define MAILBOX_BIOS_ERROR_VR_ERROR 7
+/* Data is passed through bits 31:0 of the data register. */
+#define BIOS_MAILBOX_DATA 0x5da0
+
+/* CPU Trace reserved memory size */
+#define TRACE_MEMORY_SIZE 0x8000000 /* 128MiB */
+
+/* System Agent identification */
+u8 systemagent_revision(void);
+
+/* Top of 32bit usable memory */
+u32 top_of_32bit_ram(void);
+
+#endif
diff --git a/src/soc/intel/kabylake/include/soc/usb.h b/src/soc/intel/kabylake/include/soc/usb.h
new file mode 100644
index 0000000..93f221c
--- /dev/null
+++ b/src/soc/intel/kabylake/include/soc/usb.h
@@ -0,0 +1,172 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+
+#ifndef _SOC_USB_H_
+#define _SOC_USB_H_
+
+#include <stdint.h>
+
+#define USB2_EMP_OFF 0
+#define USB2_DE_EMP_ON 1
+#define USB2_PRE_EMP_ON 2
+
+#define USB2_FULL_BIT_PRE_EMP 0
+#define USB2_HALF_BIT_PRE_EMP 1
+
+#define USB2_BIAS_0MV 0
+#define USB2_BIAS_11MV 1
+#define USB2_BIAS_17MV 2
+#define USB2_BIAS_28MV 3
+#define USB2_BIAS_28MV2 4
+#define USB2_BIAS_39MV 5
+#define USB2_BIAS_45MV 6
+#define USB2_BIAS_56MV 7
+
+struct usb2_port_config {
+ uint8_t enable;
+ uint8_t tx_bias;
+ uint8_t tx_emp_enable;
+ uint8_t pre_emp_bias;
+ uint8_t pre_emp_bit;
+};
+
+#define USB2_PORT_EMPTY { \
+ .enable = 0, \
+ .tx_bias = USB2_BIAS_0MV, \
+ .tx_emp_enable = USB2_EMP_OFF, \
+ .pre_emp_bias = USB2_BIAS_0MV, \
+ .pre_emp_bit = USB2_HALF_BIT_PRE_EMP, \
+}
+
+/*
+ * Standard USB Port based on length:
+ * - External
+ * - Back Panel
+ * - OTG
+ * - M.2
+ * - Internal device down
+ */
+
+/* Max TX and Pre-emp settings */
+#define USB2_PORT_MAX { \
+ .enable = 1, \
+ .tx_bias = USB2_BIAS_56MV, \
+ .tx_emp_enable = USB2_PRE_EMP_ON, \
+ .pre_emp_bias = USB2_BIAS_56MV, \
+ .pre_emp_bit = USB2_HALF_BIT_PRE_EMP, \
+}
+
+/* 11.5"-12" */
+#define USB2_PORT_LONG { \
+ .enable = 1, \
+ .tx_bias = USB2_BIAS_39MV, \
+ .tx_emp_enable = USB2_PRE_EMP_ON, \
+ .pre_emp_bias = USB2_BIAS_56MV, \
+ .pre_emp_bit = USB2_HALF_BIT_PRE_EMP, \
+}
+
+/* 6"-11.5" */
+#define USB2_PORT_MID { \
+ .enable = 1, \
+ .tx_bias = USB2_BIAS_0MV, \
+ .tx_emp_enable = USB2_PRE_EMP_ON, \
+ .pre_emp_bias = USB2_BIAS_56MV, \
+ .pre_emp_bit = USB2_HALF_BIT_PRE_EMP, \
+}
+
+/* 3"-6" */
+#define USB2_PORT_SHORT { \
+ .enable = 1, \
+ .tx_bias = USB2_BIAS_39MV, \
+ .tx_emp_enable = USB2_PRE_EMP_ON | USB2_DE_EMP_ON, \
+ .pre_emp_bias = USB2_BIAS_39MV, \
+ .pre_emp_bit = USB2_FULL_BIT_PRE_EMP, \
+}
+
+/* Type-C Port, no BC1.2 charge detect module / MUX */
+#define USB2_PORT_TYPE_C { \
+ .enable = 1, \
+ .tx_bias = USB2_BIAS_0MV, \
+ .tx_emp_enable = USB2_PRE_EMP_ON, \
+ .pre_emp_bias = USB2_BIAS_56MV, \
+ .pre_emp_bit = USB2_HALF_BIT_PRE_EMP, \
+}
+
+/* Port with BC1.2 charge detect module / MUX */
+#define USB2_PORT_BC12_MUX { \
+ .enable = 1, \
+ .tx_bias = USB2_BIAS_0MV, \
+ .tx_emp_enable = USB2_PRE_EMP_ON, \
+ .pre_emp_bias = USB2_BIAS_56MV, \
+ .pre_emp_bit = USB2_HALF_BIT_PRE_EMP, \
+}
+
+/* Internal Flex Cable, 3"-5" + cable + 2" card */
+#define USB2_PORT_FLEX { \
+ .enable = 1, \
+ .tx_bias = USB2_BIAS_0MV, \
+ .tx_emp_enable = USB2_PRE_EMP_ON, \
+ .pre_emp_bias = USB2_BIAS_56MV, \
+ .pre_emp_bit = USB2_HALF_BIT_PRE_EMP, \
+}
+
+/* Docking, 3"-9" */
+#define USB2_PORT_DOCKING_LONG { \
+ .enable = 1, \
+ .tx_bias = USB2_BIAS_0MV, \
+ .tx_emp_enable = USB2_PRE_EMP_ON, \
+ .pre_emp_bias = USB2_BIAS_56MV, \
+ .pre_emp_bit = USB2_HALF_BIT_PRE_EMP, \
+}
+
+/* Docking, 3"-6" */
+#define USB2_PORT_DOCKING_SHORT { \
+ .enable = 1, \
+ .tx_bias = USB2_BIAS_17MV, \
+ .tx_emp_enable = USB2_PRE_EMP_ON | USB2_DE_EMP_ON, \
+ .pre_emp_bias = USB2_BIAS_45MV, \
+ .pre_emp_bit = USB2_FULL_BIT_PRE_EMP, \
+}
+
+/* 2:1 Detachable, 2"-4" on tablet + 2"-4" on base */
+#define USB2_PORT_DETACHABLE_TABLET { \
+ .enable = 1, \
+ .tx_bias = USB2_BIAS_56MV, \
+ .tx_emp_enable = USB2_PRE_EMP_ON, \
+ .pre_emp_bias = USB2_BIAS_56MV, \
+ .pre_emp_bit = USB2_HALF_BIT_PRE_EMP, \
+}
+
+struct usb3_port_config {
+ uint8_t enable;
+ uint8_t tx_de_emp;
+ uint8_t tx_downscale_amp;
+};
+
+#define USB3_PORT_EMPTY { \
+ .enable = 0, \
+ .tx_de_emp = 0x00, \
+ .tx_downscale_amp = 0x00, \
+}
+
+#define USB3_PORT_DEFAULT { \
+ .enable = 1, \
+ .tx_de_emp = 0x29, \
+ .tx_downscale_amp = 0x00, \
+}
+
+#endif
diff --git a/src/soc/intel/kabylake/include/soc/vr_config.h b/src/soc/intel/kabylake/include/soc/vr_config.h
new file mode 100644
index 0000000..99b43d2
--- /dev/null
+++ b/src/soc/intel/kabylake/include/soc/vr_config.h
@@ -0,0 +1,80 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/* VR Settings for each domain */
+
+#ifndef _SOC_VR_CONFIG_H_
+#define _SOC_VR_CONFIG_H_
+
+#include <fsp/soc_binding.h>
+
+struct vr_config {
+
+ /*
+ * The below settings will take effect when this is set to 1
+ * for that domain.
+ */
+ int vr_config_enable;
+
+ /* Power State X current cuttof in 1/4 Amp increments
+ * Range is 0-128A
+ */
+ int psi1threshold;
+ int psi2threshold;
+ int psi3threshold;
+
+ /* Enable power state 3/4 for different domains */
+ int psi3enable;
+ int psi4enable;
+
+ /*
+ * Imon slope correction. Specified in 1/100 increment
+ * values. Range is 0-200. 125 = 1.25
+ */
+ int imon_slope;
+
+ /*
+ * Imon offset correction. Units 1/4, Range 0-255.
+ * Value of 100 = 100/4 = 25 offset.
+ */
+ int imon_offset;
+
+ /* VR Icc Max limit. 0-255A in 1/4 A units. 400 = 100A */
+ int icc_max;
+
+ /* VR Voltage Limit. Range is 0-7999mV */
+ int voltage_limit;
+};
+
+#define VR_CFG_AMP(i) ((i) * 4)
+
+/* VrConfig Settings for 5 domains
+ * 0 = System Agent, 1 = IA Core, 2 = Ring,
+ * 3 = GT unsliced, 4 = GT sliced
+ */
+enum vr_domain{
+ VR_SYSTEM_AGENT,
+ VR_IA_CORE,
+ VR_RING,
+ VR_GT_UNSLICED,
+ VR_GT_SLICED,
+ NUM_VR_DOMAINS
+};
+
+void fill_vr_domain_config(SILICON_INIT_UPD *params, int domain,
+ const struct vr_config *cfg);
+
+#endif
diff --git a/src/soc/intel/kabylake/include/soc/xhci.h b/src/soc/intel/kabylake/include/soc/xhci.h
new file mode 100644
index 0000000..6cb0edd
--- /dev/null
+++ b/src/soc/intel/kabylake/include/soc/xhci.h
@@ -0,0 +1,60 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _SOC_XHCI_H_
+#define _SOC_XHCI_H_
+
+#include <rules.h>
+
+/* XHCI PCI Registers */
+#define XHCI_PWR_CTL_STS 0x74
+#define XHCI_PWR_CTL_SET_MASK 0x3
+#define XHCI_PWR_CTL_SET_D0 0x0
+#define XHCI_PWR_CTL_SET_D3 0x3
+#define XHCI_PWR_CTL_ENABLE_PME (1 << 8)
+#define XHCI_PWR_CTL_STATUS_PME (1 << 15)
+#define XHCI_USB2PR 0xd0
+#define XHCI_USB2PRM 0xd4
+#define XHCI_USB2PR_HCSEL 0x7fff
+#define XHCI_USB3PR 0xd8
+#define XHCI_USB3PR_SSEN 0x3f
+#define XHCI_USB3PRM 0xdc
+#define XHCI_USB3FUS 0xe0
+#define XHCI_USB3FUS_SS_MASK 3
+#define XHCI_USB3FUS_SS_SHIFT 3
+#define XHCI_USB3PDO 0xe8
+
+/* XHCI Memory Registers */
+#define XHCI_USB3_PORTSC(port) (0x510 + (port * 0x10))
+#define XHCI_USB3_PORTSC_CHST (0x7f << 17)
+#define XHCI_USB3_PORTSC_WCE (1 << 25) /* Wake on Connect */
+#define XHCI_USB3_PORTSC_WDE (1 << 26) /* Wake on Disconnect */
+#define XHCI_USB3_PORTSC_WOE (1 << 27) /* Wake on Overcurrent */
+#define XHCI_USB3_PORTSC_WRC (1 << 19) /* Warm Reset Complete */
+#define XHCI_USB3_PORTSC_LWS (1 << 16) /* Link Write Strobe */
+#define XHCI_USB3_PORTSC_PED (1 << 1) /* Port Enabled/Disabled */
+#define XHCI_USB3_PORTSC_WPR (1 << 31) /* Warm Port Reset */
+#define XHCI_USB3_PORTSC_PLS (0xf << 5) /* Port Link State */
+#define XHCI_PLSR_DISABLED (4 << 5) /* Port is disabled */
+#define XHCI_PLSR_RXDETECT (5 << 5) /* Port is disconnected */
+#define XHCI_PLSR_POLLING (7 << 5) /* Port is polling */
+#define XHCI_PLSW_ENABLE (5 << 5) /* Transition from disabled */
+
+#if ENV_SMM
+void usb_xhci_sleep_prepare(device_t dev, u8 slp_typ);
+#endif
+
+#endif
diff --git a/src/soc/intel/kabylake/lpc.c b/src/soc/intel/kabylake/lpc.c
new file mode 100644
index 0000000..55598d0
--- /dev/null
+++ b/src/soc/intel/kabylake/lpc.c
@@ -0,0 +1,327 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008-2009 coresystems GmbH
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <arch/acpigen.h>
+#include "chip.h"
+#include <console/console.h>
+#include <delay.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <pc80/isa-dma.h>
+#include <pc80/i8259.h>
+#include <arch/io.h>
+#include <arch/ioapic.h>
+#include <arch/acpi.h>
+#include <cpu/cpu.h>
+#include <cpu/x86/smm.h>
+#include <cbmem.h>
+#include <reg_script.h>
+#include <string.h>
+#include <soc/acpi.h>
+#include <soc/gpio.h>
+#include <soc/iomap.h>
+#include <soc/lpc.h>
+#include <soc/nvs.h>
+#include <soc/pch.h>
+#include <soc/pci_devs.h>
+#include <soc/pm.h>
+#include <soc/pmc.h>
+#include <soc/ramstage.h>
+#include <soc/pcr.h>
+#if IS_ENABLED(CONFIG_CHROMEOS)
+#include <vendorcode/google/chromeos/chromeos.h>
+#endif
+
+static void pch_enable_ioapic(struct device *dev)
+{
+ u32 reg32;
+ /* PCH-LP has 120 redirection entries */
+ const int redir_entries = 120;
+
+ set_ioapic_id((void *)IO_APIC_ADDR, 0x02);
+
+ /* affirm full set of redirection table entries ("write once") */
+ reg32 = io_apic_read((void *)IO_APIC_ADDR, 0x01);
+
+ reg32 &= ~0x00ff0000;
+ reg32 |= (redir_entries - 1) << 16;
+
+ io_apic_write((void *)IO_APIC_ADDR, 0x01, reg32);
+
+ /*
+ * Select Boot Configuration register (0x03) and
+ * use Processor System Bus (0x01) to deliver interrupts.
+ */
+ io_apic_write((void *)IO_APIC_ADDR, 0x03, 0x01);
+}
+
+/*
+ * PIRQ[n]_ROUT[3:0] - PIRQ Routing Control
+ * 0x00 - 0000 = Reserved
+ * 0x01 - 0001 = Reserved
+ * 0x02 - 0010 = Reserved
+ * 0x03 - 0011 = IRQ3
+ * 0x04 - 0100 = IRQ4
+ * 0x05 - 0101 = IRQ5
+ * 0x06 - 0110 = IRQ6
+ * 0x07 - 0111 = IRQ7
+ * 0x08 - 1000 = Reserved
+ * 0x09 - 1001 = IRQ9
+ * 0x0A - 1010 = IRQ10
+ * 0x0B - 1011 = IRQ11
+ * 0x0C - 1100 = IRQ12
+ * 0x0D - 1101 = Reserved
+ * 0x0E - 1110 = IRQ14
+ * 0x0F - 1111 = IRQ15
+ * PIRQ[n]_ROUT[7] - PIRQ Routing Control
+ * 0x80 - The PIRQ is not routed.
+ */
+
+static void pch_pirq_init(device_t dev)
+{
+ device_t irq_dev;
+ config_t *config = dev->chip_info;
+
+ pcr_write8(PID_ITSS, R_PCH_PCR_ITSS_PIRQA_ROUT, config->pirqa_routing);
+ pcr_write8(PID_ITSS, R_PCH_PCR_ITSS_PIRQB_ROUT, config->pirqb_routing);
+ pcr_write8(PID_ITSS, R_PCH_PCR_ITSS_PIRQC_ROUT, config->pirqc_routing);
+ pcr_write8(PID_ITSS, R_PCH_PCR_ITSS_PIRQD_ROUT, config->pirqd_routing);
+ pcr_write8(PID_ITSS, R_PCH_PCR_ITSS_PIRQE_ROUT, config->pirqe_routing);
+ pcr_write8(PID_ITSS, R_PCH_PCR_ITSS_PIRQF_ROUT, config->pirqf_routing);
+ pcr_write8(PID_ITSS, R_PCH_PCR_ITSS_PIRQG_ROUT, config->pirqg_routing);
+ pcr_write8(PID_ITSS, R_PCH_PCR_ITSS_PIRQH_ROUT, config->pirqh_routing);
+
+ for (irq_dev = all_devices; irq_dev; irq_dev = irq_dev->next) {
+ u8 int_pin = 0, int_line = 0;
+
+ if (!irq_dev->enabled || irq_dev->path.type != DEVICE_PATH_PCI)
+ continue;
+
+ int_pin = pci_read_config8(irq_dev, PCI_INTERRUPT_PIN);
+
+ switch (int_pin) {
+ case 1: /* INTA# */
+ int_line = config->pirqa_routing;
+ break;
+ case 2: /* INTB# */
+ int_line = config->pirqb_routing;
+ break;
+ case 3: /* INTC# */
+ int_line = config->pirqc_routing;
+ break;
+ case 4: /* INTD# */
+ int_line = config->pirqd_routing;
+ break;
+ }
+
+ if (!int_line)
+ continue;
+
+ pci_write_config8(irq_dev, PCI_INTERRUPT_LINE, int_line);
+ }
+}
+
+
+static const struct reg_script pch_misc_init_script[] = {
+ /* Setup NMI on errors, disable SERR */
+ REG_IO_RMW8(0x61, ~0xf0, (1 << 2)),
+ /* Disable NMI sources */
+ REG_IO_OR8(0x70, (1 << 7)),
+ /* Enable BIOS updates outside of SMM */
+ REG_PCI_RMW8(0xdc, ~(1 << 5), 0),
+ /* Setup SERIRQ, enable continuous mode */
+ REG_PCI_OR8(SERIRQ_CNTL, (1 << 7) | (1 << 6)),
+#if !IS_ENABLED(CONFIG_SERIRQ_CONTINUOUS_MODE)
+ REG_PCI_RMW8(SERIRQ_CNTL, ~(1 << 6), 0),
+#endif
+ /* Enable CLKRUN_EN for power gating LPC */
+ REG_PCI_OR8(PCCTL, (CLKRUN_EN)),
+ REG_SCRIPT_END
+};
+
+static void clock_gate_8254(struct device *dev)
+{
+ config_t *config = dev->chip_info;
+ const uint32_t cge8254_mask = CGE8254;
+
+ if (!config->clock_gate_8254)
+ return;
+
+ pcr_andthenor32(PID_ITSS, R_PCH_PCR_ITSS_ITSSPRC,
+ ~cge8254_mask, cge8254_mask);
+}
+
+static void lpc_init(struct device *dev)
+{
+ /* Legacy initialization */
+ isa_dma_init();
+ reg_script_run_on_dev(dev, pch_misc_init_script);
+
+ /* Interrupt configuration */
+ pch_enable_ioapic(dev);
+ pch_pirq_init(dev);
+ setup_i8259();
+ i8259_configure_irq_trigger(9, 1);
+ clock_gate_8254(dev);
+}
+
+static void pch_lpc_add_mmio_resources(device_t dev)
+{
+ u32 reg;
+ struct resource *res;
+ /*
+ * As per the BWG, Chapter 5.9.1. "PCH BIOS component will reserve
+ * certain memory range as reserved range for BIOS usage.
+ * For this SOC, the range will be from 0FD000000h till FE7FFFFFh"
+ * Hence, use FD000000h as PCR_BASE
+ */
+ const u32 default_decode_base = PCH_PCR_BASE_ADDRESS;
+
+ res = new_resource(dev, PCI_BASE_ADDRESS_0);
+ res->base = default_decode_base;
+ res->size = 0 - default_decode_base;
+ res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED |
+ IORESOURCE_FIXED | IORESOURCE_RESERVE;
+
+ /* Check LPC Memory Decode register. */
+ reg = pci_read_config32(dev, LGMR);
+ if (reg & 1) {
+ reg &= ~0xffff;
+ if (reg < default_decode_base) {
+ res = new_resource(dev, LGMR);
+ res->base = reg;
+ res->size = 16 * 1024;
+ res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED |
+ IORESOURCE_FIXED | IORESOURCE_RESERVE;
+ }
+ }
+}
+
+/* Default IO range claimed by the LPC device. The upper bound is exclusive. */
+#define LPC_DEFAULT_IO_RANGE_LOWER 0
+#define LPC_DEFAULT_IO_RANGE_UPPER 0x1000
+
+static inline int pch_io_range_in_default(u16 base, u16 size)
+{
+ /* Does it start above the range? */
+ if (base >= LPC_DEFAULT_IO_RANGE_UPPER)
+ return 0;
+
+ /*
+ * Is it entirely contained?
+ * Since LPC_DEFAULT_IO_RANGE_LOWER is Zero,
+ * it need not be checked against lower base.
+ */
+ if ((base + size) < LPC_DEFAULT_IO_RANGE_UPPER)
+ return 1;
+
+ /* This will return not in range for partial overlaps. */
+ return 0;
+}
+
+/*
+ * Note: this function assumes there is no overlap with the default LPC device's
+ * claimed range: LPC_DEFAULT_IO_RANGE_LOWER -> LPC_DEFAULT_IO_RANGE_UPPER.
+ */
+static void pch_lpc_add_io_resource(device_t dev, u16 base, u16 size, int index)
+{
+ struct resource *res;
+
+ if (pch_io_range_in_default(base, size))
+ return;
+
+ res = new_resource(dev, index);
+ res->base = base;
+ res->size = size;
+ res->flags = IORESOURCE_IO | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+}
+
+static void pch_lpc_add_gen_io_resources(device_t dev, int reg_value, int index)
+{
+ /*
+ * Check if the register is enabled. If so and the base exceeds the
+ * device's deafult claim range add the resoure.
+ */
+ if (reg_value & 1) {
+ u16 base = reg_value & 0xfffc;
+ u16 size = (0x3 | ((reg_value >> 16) & 0xfc)) + 1;
+ pch_lpc_add_io_resource(dev, base, size, index);
+ }
+}
+
+static void pch_lpc_add_io_resources(device_t dev)
+{
+ struct resource *res;
+ config_t *config = dev->chip_info;
+
+ /* Add the default claimed IO range for the LPC device. */
+ res = new_resource(dev, 0);
+ res->base = LPC_DEFAULT_IO_RANGE_LOWER;
+ res->size = LPC_DEFAULT_IO_RANGE_UPPER - LPC_DEFAULT_IO_RANGE_LOWER;
+ res->flags = IORESOURCE_IO | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+
+ /* LPC Generic IO Decode range. */
+ pch_lpc_add_gen_io_resources(dev, config->gen1_dec, LPC_GEN1_DEC);
+ pch_lpc_add_gen_io_resources(dev, config->gen2_dec, LPC_GEN2_DEC);
+ pch_lpc_add_gen_io_resources(dev, config->gen3_dec, LPC_GEN3_DEC);
+ pch_lpc_add_gen_io_resources(dev, config->gen4_dec, LPC_GEN4_DEC);
+}
+
+static void pch_lpc_read_resources(device_t dev)
+{
+ global_nvs_t *gnvs;
+
+ /* Get the normal PCI resources of this device. */
+ pci_dev_read_resources(dev);
+
+ /* Add non-standard MMIO resources. */
+ pch_lpc_add_mmio_resources(dev);
+
+ /* Add IO resources. */
+ pch_lpc_add_io_resources(dev);
+
+ /* Allocate ACPI NVS in CBMEM */
+ gnvs = cbmem_add(CBMEM_ID_ACPI_GNVS, sizeof(global_nvs_t));
+ if (!acpi_is_wakeup_s3() && gnvs)
+ memset(gnvs, 0, sizeof(global_nvs_t));
+}
+
+static struct device_operations device_ops = {
+ .read_resources = &pch_lpc_read_resources,
+ .set_resources = &pci_dev_set_resources,
+ .enable_resources = &pci_dev_enable_resources,
+ .acpi_inject_dsdt_generator = southcluster_inject_dsdt,
+ .write_acpi_tables = southcluster_write_acpi_tables,
+ .init = &lpc_init,
+ .scan_bus = &scan_lpc_bus,
+ .ops_pci = &soc_pci_ops,
+};
+
+static const unsigned short pci_device_ids[] = {
+ PCH_SPT_LP_SAMPLE,
+ PCH_SPT_LP_U_BASE,
+ PCH_SPT_LP_U_PREMIUM,
+ PCH_SPT_LP_Y_PREMIUM,
+ 0
+};
+
+static const struct pci_driver pch_lpc __pci_driver = {
+ .ops = &device_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .devices = pci_device_ids,
+};
diff --git a/src/soc/intel/kabylake/me_status.c b/src/soc/intel/kabylake/me_status.c
new file mode 100644
index 0000000..79d4dfb
--- /dev/null
+++ b/src/soc/intel/kabylake/me_status.c
@@ -0,0 +1,324 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008-2009 coresystems GmbH
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <arch/io.h>
+#include <console/console.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <stdlib.h>
+#include <string.h>
+#include <soc/pci_devs.h>
+#include <soc/me.h>
+#include <delay.h>
+
+static inline void me_read_dword_ptr(void *ptr, int offset)
+{
+ u32 dword = pci_read_config32(PCH_DEV_ME, offset);
+ memcpy(ptr, &dword, sizeof(dword));
+}
+
+/* HFSTS1[3:0] Current Working State Values */
+static const char *me_cws_values[] = {
+ [ME_HFS_CWS_RESET] = "Reset",
+ [ME_HFS_CWS_INIT] = "Initializing",
+ [ME_HFS_CWS_REC] = "Recovery",
+ [3] = "Unknown (3)",
+ [4] = "Unknown (4)",
+ [ME_HFS_CWS_NORMAL] = "Normal",
+ [ME_HFS_CWS_WAIT] = "Platform Disable Wait",
+ [ME_HFS_CWS_TRANS] = "OP State Transition",
+ [ME_HFS_CWS_INVALID] = "Invalid CPU Plugged In",
+ [9] = "Unknown (9)",
+ [10] = "Unknown (10)",
+ [11] = "Unknown (11)",
+ [12] = "Unknown (12)",
+ [13] = "Unknown (13)",
+ [14] = "Unknown (14)",
+ [15] = "Unknown (15)",
+};
+
+/* HFSTS1[8:6] Current Operation State Values */
+static const char *me_opstate_values[] = {
+ [ME_HFS_STATE_PREBOOT] = "Preboot",
+ [ME_HFS_STATE_M0_UMA] = "M0 with UMA",
+ [ME_HFS_STATE_M3] = "M3 without UMA",
+ [ME_HFS_STATE_M0] = "M0 without UMA",
+ [ME_HFS_STATE_BRINGUP] = "Bring up",
+ [ME_HFS_STATE_ERROR] = "M0 without UMA but with error"
+};
+
+/* HFSTS1[19:16] Current Operation Mode Values */
+static const char *me_opmode_values[] = {
+ [ME_HFS_MODE_NORMAL] = "Normal",
+ [ME_HFS_MODE_DEBUG] = "Debug",
+ [ME_HFS_MODE_DIS] = "Soft Temporary Disable",
+ [ME_HFS_MODE_OVER_JMPR] = "Security Override via Jumper",
+ [ME_HFS_MODE_OVER_MEI] = "Security Override via MEI Message"
+};
+
+/* HFSTS1[15:12] Error Code Values */
+static const char *me_error_values[] = {
+ [ME_HFS_ERROR_NONE] = "No Error",
+ [ME_HFS_ERROR_UNCAT] = "Uncategorized Failure",
+ [ME_HFS_ERROR_IMAGE] = "Image Failure",
+ [ME_HFS_ERROR_DEBUG] = "Debug Failure"
+};
+
+/* HFSTS2[31:28] ME Progress Code */
+static const char *me_progress_values[] = {
+ [ME_HFS2_PHASE_ROM] = "ROM Phase",
+ [1] = "Unknown (1)",
+ [ME_HFS2_PHASE_UKERNEL] = "uKernel Phase",
+ [ME_HFS2_PHASE_BUP] = "BUP Phase",
+ [4] = "Unknown (4)",
+ [5] = "Unknown (5)",
+ [ME_HFS2_PHASE_HOST_COMM] = "Host Communication",
+ [7] = "Unknown (7)",
+ [8] = "Unknown (8)"
+};
+
+/* HFSTS2[27:24] Power Management Event */
+static const char *me_pmevent_values[] = {
+ [ME_HFS2_PMEVENT_CLEAN_MOFF_MX_WAKE] =
+ "Clean Moff->Mx wake",
+ [ME_HFS2_PMEVENT_MOFF_MX_WAKE_ERROR] =
+ "Moff->Mx wake after an error",
+ [ME_HFS2_PMEVENT_CLEAN_GLOBAL_RESET] =
+ "Clean global reset",
+ [ME_HFS2_PMEVENT_CLEAN_GLOBAL_RESET_ERROR] =
+ "Global reset after an error",
+ [ME_HFS2_PMEVENT_CLEAN_ME_RESET] =
+ "Clean Intel ME reset",
+ [ME_HFS2_PMEVENT_ME_RESET_EXCEPTION] =
+ "Intel ME reset due to exception",
+ [ME_HFS2_PMEVENT_PSEUDO_ME_RESET] =
+ "Pseudo-global reset",
+ [ME_HFS2_PMEVENT_CM0_CM3] =
+ "CM0->CM3",
+ [ME_HFS2_PMEVENT_CM3_CM0] =
+ "CM3->CM0",
+ [ME_HFS2_PMEVENT_NON_PWR_CYCLE_RESET] =
+ "Non-power cycle reset",
+ [ME_HFS2_PMEVENT_PWR_CYCLE_RESET_M3] =
+ "Power cycle reset through M3",
+ [ME_HFS2_PMEVENT_PWR_CYCLE_RESET_MOFF] =
+ "Power cycle reset through Moff",
+ [ME_HFS2_PMEVENT_CMX_CMOFF] =
+ "Cx/Mx->Cx/Moff",
+ [ME_HFS2_PMEVENT_CM0_CM0PG] =
+ "CM0->CM0PG",
+ [ME_HFS2_PMEVENT_CM3_CM3PG] =
+ "CM3->CM3PG",
+ [ME_HFS2_PMEVENT_CM0PG_CM0] =
+ "CM0PG->CM0"
+
+};
+
+/* Progress Code 0 states */
+static const char *me_progress_rom_values[] = {
+ [ME_HFS2_STATE_ROM_BEGIN] = "BEGIN",
+ [ME_HFS2_STATE_ROM_DISABLE] = "DISABLE"
+};
+
+/* Progress Code 1 states */
+static const char *me_progress_bup_values[] = {
+ [ME_HFS2_STATE_BUP_INIT] =
+ "Initialization starts",
+ [ME_HFS2_STATE_BUP_DIS_HOST_WAKE] =
+ "Disable the host wake event",
+ [ME_HFS2_STATE_BUP_CG_ENABLE] =
+ "Enabling CG for cset",
+ [ME_HFS2_STATE_BUP_PM_HND_EN] =
+ "Enabling PM handshaking",
+ [ME_HFS2_STATE_BUP_FLOW_DET] =
+ "Flow determination start process",
+ [ME_HFS2_STATE_BUP_PMC_PATCHING] =
+ "PMC Patching process",
+ [ME_HFS2_STATE_BUP_GET_FLASH_VSCC] =
+ "Get VSCC params",
+ [ME_HFS2_STATE_BUP_SET_FLASH_VSCC] =
+ "Set VSCC params",
+ [ME_HFS2_STATE_BUP_VSCC_ERR] =
+ "Error reading/matching the VSCC table in the descriptor",
+ [ME_HFS2_STATE_BUP_EFSS_INIT] =
+ "Initialize EFFS",
+ [ME_HFS2_STATE_BUP_CHECK_STRAP] =
+ "Check to see if straps say ME DISABLED",
+ [ME_HFS2_STATE_BUP_PWR_OK_TIMEOUT] =
+ "Timeout waiting for PWROK",
+ [ME_HFS2_STATE_BUP_STRAP_DIS] =
+ "EFFS says ME disabled",
+ [ME_HFS2_STATE_BUP_MANUF_OVRD_STRAP] =
+ "Possibly handle BUP manufacturing override strap",
+ [ME_HFS2_STATE_BUP_M3] =
+ "Bringup in M3",
+ [ME_HFS2_STATE_BUP_M0] =
+ "Bringup in M0",
+ [ME_HFS2_STATE_BUP_FLOW_DET_ERR] =
+ "Flow detection error",
+ [ME_HFS2_STATE_BUP_M3_CLK_ERR] =
+ "M3 clock switching error",
+ [ME_HFS2_STATE_BUP_CPU_RESET_DID_TIMEOUT_MEM_MISSING] =
+ "Host error - CPU reset timeout, DID timeout, memory missing",
+ [ME_HFS2_STATE_BUP_M3_KERN_LOAD] =
+ "M3 kernel load",
+ [ME_HFS2_STATE_BUP_T32_MISSING] =
+ "T34 missing - cannot program ICC",
+ [ME_HFS2_STATE_BUP_WAIT_DID] =
+ "Waiting for DID BIOS message",
+ [ME_HFS2_STATE_BUP_WAIT_DID_FAIL] =
+ "Waiting for DID BIOS message failure",
+ [ME_HFS2_STATE_BUP_DID_NO_FAIL] =
+ "DID reported no error",
+ [ME_HFS2_STATE_BUP_ENABLE_UMA] =
+ "Enabling UMA",
+ [ME_HFS2_STATE_BUP_ENABLE_UMA_ERR] =
+ "Enabling UMA error",
+ [ME_HFS2_STATE_BUP_SEND_DID_ACK] =
+ "Sending DID Ack to BIOS",
+ [ME_HFS2_STATE_BUP_SEND_DID_ACK_ERR] =
+ "Sending DID Ack to BIOS error",
+ [ME_HFS2_STATE_BUP_M0_CLK] =
+ "Switching clocks in M0",
+ [ME_HFS2_STATE_BUP_M0_CLK_ERR] =
+ "Switching clocks in M0 error",
+ [ME_HFS2_STATE_BUP_TEMP_DIS] =
+ "ME in temp disable",
+ [ME_HFS2_STATE_BUP_M0_KERN_LOAD] =
+ "M0 kernel load",
+};
+
+void intel_me_status(void)
+{
+ struct me_hfs _hfs, *hfs = &_hfs;
+ struct me_hfs2 _hfs2, *hfs2 = &_hfs2;
+ struct me_hfs3 _hfs3, *hfs3 = &_hfs3;
+
+ me_read_dword_ptr(hfs, PCI_ME_HFSTS1);
+ me_read_dword_ptr(hfs2, PCI_ME_HFSTS2);
+ me_read_dword_ptr(hfs3, PCI_ME_HFSTS3);
+
+ /* Check Current States */
+ printk(BIOS_DEBUG, "ME: FW Partition Table : %s\n",
+ hfs->fpt_bad ? "BAD" : "OK");
+ printk(BIOS_DEBUG, "ME: Bringup Loader Failure : %s\n",
+ hfs->ft_bup_ld_flr ? "YES" : "NO");
+ printk(BIOS_DEBUG, "ME: Firmware Init Complete : %s\n",
+ hfs->fw_init_complete ? "YES" : "NO");
+ printk(BIOS_DEBUG, "ME: Manufacturing Mode : %s\n",
+ hfs->mfg_mode ? "YES" : "NO");
+ printk(BIOS_DEBUG, "ME: Boot Options Present : %s\n",
+ hfs->boot_options_present ? "YES" : "NO");
+ printk(BIOS_DEBUG, "ME: Update In Progress : %s\n",
+ hfs->update_in_progress ? "YES" : "NO");
+ printk(BIOS_DEBUG, "ME: D3 Support : %s\n",
+ hfs->d3_support_valid ? "YES" : "NO");
+ printk(BIOS_DEBUG, "ME: D0i3 Support : %s\n",
+ hfs->d0i3_support_valid ? "YES" : "NO");
+ printk(BIOS_DEBUG, "ME: Low Power State Enabled : %s\n",
+ hfs2->low_power_state ? "YES" : "NO");
+ printk(BIOS_DEBUG, "ME: Power Gated : %s\n",
+ hfs2->power_gating_ind ? "YES" : "NO");
+ printk(BIOS_DEBUG, "ME: CPU Replaced : %s\n",
+ hfs2->cpu_replaced_sts ? "YES" : "NO");
+ printk(BIOS_DEBUG, "ME: CPU Replacement Valid : %s\n",
+ hfs2->cpu_replaced_valid ? "YES" : "NO");
+ printk(BIOS_DEBUG, "ME: Current Working State : %s\n",
+ me_cws_values[hfs->working_state]);
+ printk(BIOS_DEBUG, "ME: Current Operation State : %s\n",
+ me_opstate_values[hfs->operation_state]);
+ printk(BIOS_DEBUG, "ME: Current Operation Mode : %s\n",
+ me_opmode_values[hfs->operation_mode]);
+ printk(BIOS_DEBUG, "ME: Error Code : %s\n",
+ me_error_values[hfs->error_code]);
+ printk(BIOS_DEBUG, "ME: Progress Phase : %s\n",
+ me_progress_values[hfs2->progress_code]);
+ printk(BIOS_DEBUG, "ME: Power Management Event : %s\n",
+ me_pmevent_values[hfs2->current_pmevent]);
+
+ printk(BIOS_DEBUG, "ME: Progress Phase State : ");
+ switch (hfs2->progress_code) {
+ case ME_HFS2_PHASE_ROM: /* ROM Phase */
+ printk(BIOS_DEBUG, "%s",
+ me_progress_rom_values[hfs2->current_state]);
+ break;
+
+ case ME_HFS2_PHASE_UKERNEL: /* uKernel Phase */
+ printk(BIOS_DEBUG, "0x%02x", hfs2->current_state);
+ break;
+
+ case ME_HFS2_PHASE_BUP: /* Bringup Phase */
+ if (hfs2->current_state < ARRAY_SIZE(me_progress_bup_values)
+ && me_progress_bup_values[hfs2->current_state])
+ printk(BIOS_DEBUG, "%s",
+ me_progress_bup_values[hfs2->current_state]);
+ else
+ printk(BIOS_DEBUG, "0x%02x", hfs2->current_state);
+ break;
+
+ case ME_HFS2_PHASE_HOST_COMM: /* Host Communication Phase */
+ if (!hfs2->current_state)
+ printk(BIOS_DEBUG, "Host communication established");
+ else
+ printk(BIOS_DEBUG, "0x%02x", hfs2->current_state);
+ break;
+
+ default:
+ printk(BIOS_DEBUG, "Unknown phase: 0x%02x state: 0x%02x",
+ hfs2->progress_code, hfs2->current_state);
+ }
+ printk(BIOS_DEBUG, "\n");
+
+ /* Power Down Mitigation Status */
+ printk(BIOS_DEBUG, "ME: Power Down Mitigation : %s\n",
+ hfs3->power_down_mitigation ? "YES" : "NO");
+
+ if (hfs3->power_down_mitigation) {
+ printk(BIOS_INFO, "ME: PD Mitigation State : ");
+ if (hfs3->encrypt_key_override == 1 &&
+ hfs3->encrypt_key_check == 0 &&
+ hfs3->pch_config_change == 0)
+ printk(BIOS_INFO, "Normal Operation");
+ else if (hfs3->encrypt_key_override == 1 &&
+ hfs3->encrypt_key_check == 1 &&
+ hfs3->pch_config_change == 0)
+ printk(BIOS_INFO, "Issue Detected and Recovered");
+ else
+ printk(BIOS_INFO, "Issue Detected but not Recovered");
+ printk(BIOS_INFO, "\n");
+
+ printk(BIOS_DEBUG, "ME: Encryption Key Override : %s\n",
+ hfs3->encrypt_key_override ? "Workaround Applied" :
+ "Unable to override");
+ printk(BIOS_DEBUG, "ME: Encryption Key Check : %s\n",
+ hfs3->encrypt_key_check ? "FAIL" : "PASS");
+ printk(BIOS_DEBUG, "ME: PCH Configuration Info : %s\n",
+ hfs3->pch_config_change ? "Changed" : "No Change");
+
+ printk(BIOS_DEBUG, "ME: Firmware SKU : ");
+ switch (hfs3->fw_sku) {
+ case ME_HFS3_FW_SKU_CONSUMER:
+ printk(BIOS_DEBUG, "Consumer\n");
+ break;
+ case ME_HFS3_FW_SKU_CORPORATE:
+ printk(BIOS_DEBUG, "Corporate\n");
+ break;
+ default:
+ printk(BIOS_DEBUG, "Unknown (0x%x)\n", hfs3->fw_sku);
+ }
+ }
+}
diff --git a/src/soc/intel/kabylake/memmap.c b/src/soc/intel/kabylake/memmap.c
new file mode 100644
index 0000000..a4c0c0b
--- /dev/null
+++ b/src/soc/intel/kabylake/memmap.c
@@ -0,0 +1,207 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <arch/io.h>
+#include <cbmem.h>
+#include <chip.h>
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <soc/msr.h>
+#include <soc/pci_devs.h>
+#include <soc/romstage.h>
+#include <soc/smm.h>
+#include <soc/systemagent.h>
+#include <stdlib.h>
+
+size_t mmap_region_granularity(void)
+{
+ if (IS_ENABLED(CONFIG_HAVE_SMI_HANDLER))
+ /* Align to TSEG size when SMM is in use */
+ if (CONFIG_SMM_TSEG_SIZE != 0)
+ return CONFIG_SMM_TSEG_SIZE;
+
+ /* Make it 8MiB by default. */
+ return 8*MiB;
+}
+
+/* Returns base of requested region encoded in the system agent. */
+static inline uintptr_t system_agent_region_base(size_t reg)
+{
+ /* All regions concerned for have 1 MiB alignment. */
+ return ALIGN_DOWN(pci_read_config32(SA_DEV_ROOT, reg), 1*MiB);
+}
+
+static inline uintptr_t smm_region_start(void)
+{
+ return system_agent_region_base(TSEG);
+}
+
+static inline size_t smm_region_size(void)
+{
+ return system_agent_region_base(BGSM) - smm_region_start();
+}
+
+void smm_region(void **start, size_t *size)
+{
+ *start = (void *)smm_region_start();
+ *size = smm_region_size();
+}
+
+/*
+ * Subregions within SMM
+ * +-------------------------+ BGSM
+ * | IED | IED_REGION_SIZE
+ * +-------------------------+
+ * | External Stage Cache | SMM_RESERVED_SIZE
+ * +-------------------------+
+ * | code and data |
+ * | (TSEG) |
+ * +-------------------------+ TSEG
+ */
+int smm_subregion(int sub, void **start, size_t *size)
+{
+ uintptr_t sub_base;
+ size_t sub_size;
+ const size_t ied_size = CONFIG_IED_REGION_SIZE;
+ const size_t cache_size = CONFIG_SMM_RESERVED_SIZE;
+
+ sub_base = smm_region_start();
+ sub_size = smm_region_size();
+
+ switch (sub) {
+ case SMM_SUBREGION_HANDLER:
+ /* Handler starts at the base of TSEG. */
+ sub_size -= ied_size;
+ sub_size -= cache_size;
+ break;
+ case SMM_SUBREGION_CACHE:
+ /* External cache is in the middle of TSEG. */
+ sub_base += sub_size - (ied_size + cache_size);
+ sub_size = cache_size;
+ break;
+ case SMM_SUBREGION_CHIPSET:
+ /* IED is at the top. */
+ sub_base += sub_size - ied_size;
+ sub_size = ied_size;
+ break;
+ default:
+ return -1;
+ }
+
+ *start = (void *)sub_base;
+ *size = sub_size;
+
+ return 0;
+}
+
+/*
+ * Host Memory Map:
+ *
+ * +--------------------------+ TOUUD
+ * | |
+ * +--------------------------+ 4GiB
+ * | PCI Address Space |
+ * +--------------------------+ TOLUD (also maps into MC address space)
+ * | iGD |
+ * +--------------------------+ BDSM
+ * | GTT |
+ * +--------------------------+ BGSM
+ * | TSEG |
+ * +--------------------------+ TSEGMB
+ * | DMA Protected Region |
+ * +--------------------------+ DPR
+ * | PRM (C6DRAM/SGX) |
+ * +--------------------------+ PRMRR
+ * | Trace Memory |
+ * +--------------------------+ top_of_ram
+ * | Reserved - FSP/CBMEM |
+ * +--------------------------+ TOLUM
+ * | Usage DRAM |
+ * +--------------------------+ 0
+ *
+ * Some of the base registers above can be equal making the size of those
+ * regions 0. The reason is because the memory controller internally subtracts
+ * the base registers from each other to determine sizes of the regions. In
+ * other words, the memory map is in a fixed order no matter what.
+ */
+
+u32 top_of_32bit_ram(void)
+{
+ msr_t prmrr_base;
+ u32 top_of_ram;
+ const struct device *dev;
+ const struct soc_intel_kabylake_config *config;
+
+ /*
+ * Check if Tseg has been initialized, we will use this as a flag
+ * to check if the MRC is done, and only then continue to read the
+ * PRMMR_BASE MSR. The system hangs if PRMRR_BASE MSR is read before
+ * PRMRR_MASK MSR lock bit is set.
+ */
+ if (smm_region_start() == 0)
+ return 0;
+
+ dev = dev_find_slot(0, PCI_DEVFN(SA_DEV_SLOT_ROOT, 0));
+ config = dev->chip_info;
+
+ /*
+ * On Kabylake, cbmem_top is offset down from PRMRR_BASE by reserved
+ * memory (128MiB) for CPU trace if enabled, then reserved memory (4KB)
+ * for PTT if enabled. PTT is in fact not used on Kabylake platforms.
+ * Refer to Fsp Integration Guide for the memory mapping layout.
+ */
+ prmrr_base = rdmsr(UNCORE_PRMRR_PHYS_BASE_MSR);
+ top_of_ram = prmrr_base.lo;
+
+ if (config->ProbelessTrace)
+ top_of_ram -= TRACE_MEMORY_SIZE;
+
+ return top_of_ram;
+}
+
+void *cbmem_top(void)
+{
+ /*
+ * +-------------------------+ Top of RAM (aligned)
+ * | System Management Mode |
+ * | code and data | Length: CONFIG_TSEG_SIZE
+ * | (TSEG) |
+ * +-------------------------+ SMM base (aligned)
+ * | |
+ * | Chipset Reserved Memory |
+ * | |
+ * +-------------------------+ top_of_ram (aligned)
+ * | |
+ * | CBMEM Root |
+ * | |
+ * +-------------------------+
+ * | |
+ * | FSP Reserved Memory |
+ * | |
+ * +-------------------------+
+ * | |
+ * | Various CBMEM Entries |
+ * | |
+ * +-------------------------+ top_of_stack (8 byte aligned)
+ * | |
+ * | stack (CBMEM Entry) |
+ * | |
+ * +-------------------------+
+ */
+ return (void *)top_of_32bit_ram();
+}
+
diff --git a/src/soc/intel/kabylake/monotonic_timer.c b/src/soc/intel/kabylake/monotonic_timer.c
new file mode 100644
index 0000000..d2a4879
--- /dev/null
+++ b/src/soc/intel/kabylake/monotonic_timer.c
@@ -0,0 +1,39 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <stdint.h>
+#include <cpu/x86/msr.h>
+#include <timer.h>
+#include <soc/msr.h>
+
+static inline uint32_t read_counter_msr(void)
+{
+ /*
+ * Even though the MSR is 64-bit it is assumed that the hardware
+ * is polled frequently enough to only use the lower 32-bits.
+ */
+ msr_t counter_msr;
+
+ counter_msr = rdmsr(MSR_COUNTER_24_MHZ);
+
+ return counter_msr.lo;
+}
+
+void timer_monotonic_get(struct mono_time *mt)
+{
+ /* Always increases. Don't normalize to 0 between stages. */
+ mono_time_set_usecs(mt, read_counter_msr() / 24);
+}
diff --git a/src/soc/intel/kabylake/nhlt/Makefile.inc b/src/soc/intel/kabylake/nhlt/Makefile.inc
new file mode 100644
index 0000000..9a572d0
--- /dev/null
+++ b/src/soc/intel/kabylake/nhlt/Makefile.inc
@@ -0,0 +1,47 @@
+ramstage-y += dmic.c
+ramstage-y += nau88l25.c
+ramstage-y += max98357.c
+ramstage-y += ssm4567.c
+
+# DSP firmware settings files.
+NHLT_BLOB_PATH = 3rdparty/blobs/soc/intel/kabylake
+DMIC_2CH_48KHZ_16B = dmic-2ch-48khz-16b.bin
+DMIC_2CH_48KHZ_32B = dmic-2ch-48khz-32b.bin
+DMIC_4CH_48KHZ_16B = dmic-4ch-48khz-16b.bin
+DMIC_4CH_48KHZ_32B = dmic-4ch-48khz-32b.bin
+NAU88L25 = nau88l25-2ch-48khz-24b.bin
+MAX98357_RENDER = max98357-render-2ch-48khz-24b.bin
+SSM4567_RENDER = ssm4567-render-2ch-48khz-24b.bin
+SSM4567_CAPTURE = ssm4567-capture-4ch-48khz-32b.bin
+
+cbfs-files-$(CONFIG_NHLT_DMIC_2CH) += $(DMIC_2CH_48KHZ_16B)
+$(DMIC_2CH_48KHZ_16B)-file := $(NHLT_BLOB_PATH)/$(DMIC_2CH_48KHZ_16B)
+$(DMIC_2CH_48KHZ_16B)-type := raw
+
+cbfs-files-$(CONFIG_NHLT_DMIC_2CH) += $(DMIC_2CH_48KHZ_32B)
+$(DMIC_2CH_48KHZ_32B)-file := $(NHLT_BLOB_PATH)/$(DMIC_2CH_48KHZ_32B)
+$(DMIC_2CH_48KHZ_32B)-type := raw
+
+cbfs-files-$(CONFIG_NHLT_DMIC_4CH) += $(DMIC_4CH_48KHZ_16B)
+$(DMIC_4CH_48KHZ_16B)-file := $(NHLT_BLOB_PATH)/$(DMIC_4CH_48KHZ_16B)
+$(DMIC_4CH_48KHZ_16B)-type := raw
+
+cbfs-files-$(CONFIG_NHLT_DMIC_4CH) += $(DMIC_4CH_48KHZ_32B)
+$(DMIC_4CH_48KHZ_32B)-file := $(NHLT_BLOB_PATH)/$(DMIC_4CH_48KHZ_32B)
+$(DMIC_4CH_48KHZ_32B)-type := raw
+
+cbfs-files-$(CONFIG_NHLT_NAU88L25) += $(NAU88L25)
+$(NAU88L25)-file := $(NHLT_BLOB_PATH)/$(NAU88L25)
+$(NAU88L25)-type := raw
+
+cbfs-files-$(CONFIG_NHLT_MAX98357) += $(MAX98357_RENDER)
+$(MAX98357_RENDER)-file := $(NHLT_BLOB_PATH)/$(MAX98357_RENDER)
+$(MAX98357_RENDER)-type := raw
+
+cbfs-files-$(CONFIG_NHLT_SSM4567) += $(SSM4567_RENDER)
+$(SSM4567_RENDER)-file := $(NHLT_BLOB_PATH)/$(SSM4567_RENDER)
+$(SSM4567_RENDER)-type := raw
+
+cbfs-files-$(CONFIG_NHLT_SSM4567) += $(SSM4567_CAPTURE)
+$(SSM4567_CAPTURE)-file := $(NHLT_BLOB_PATH)/$(SSM4567_CAPTURE)
+$(SSM4567_CAPTURE)-type := raw
diff --git a/src/soc/intel/kabylake/nhlt/dmic.c b/src/soc/intel/kabylake/nhlt/dmic.c
new file mode 100644
index 0000000..a7684bd
--- /dev/null
+++ b/src/soc/intel/kabylake/nhlt/dmic.c
@@ -0,0 +1,116 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2015 Google, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <soc/nhlt.h>
+
+static const struct nhlt_format_config dmic_2ch_formats[] = {
+ /* 48 KHz 16-bits per sample. */
+ {
+ .num_channels = 2,
+ .sample_freq_khz = 48,
+ .container_bits_per_sample = 16,
+ .valid_bits_per_sample = 16,
+ .speaker_mask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT,
+ .settings_file = "dmic-2ch-48khz-16b.bin",
+ },
+ /* 48 KHz 32-bits per sample. */
+ {
+ .num_channels = 2,
+ .sample_freq_khz = 48,
+ .container_bits_per_sample = 32,
+ .valid_bits_per_sample = 32,
+ .speaker_mask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT,
+ .settings_file = "dmic-2ch-48khz-32b.bin",
+ },
+};
+
+static const struct nhlt_dmic_array_config dmic_2ch_mic_config = {
+ .tdm_config = {
+ .config_type = NHLT_TDM_MIC_ARRAY,
+ },
+ .array_type = NHLT_MIC_ARRAY_2CH_SMALL,
+};
+
+static const struct nhlt_endp_descriptor dmic_2ch_descriptors[] = {
+ {
+ .link = NHLT_LINK_PDM,
+ .device = NHLT_PDM_DEV,
+ .direction = NHLT_DIR_CAPTURE,
+ .vid = NHLT_VID,
+ .did = NHLT_DID_DMIC,
+ .cfg = &dmic_2ch_mic_config,
+ .cfg_size = sizeof(dmic_2ch_mic_config),
+ .formats = dmic_2ch_formats,
+ .num_formats = ARRAY_SIZE(dmic_2ch_formats),
+ },
+};
+
+static const struct nhlt_format_config dmic_4ch_formats[] = {
+ /* 48 KHz 16-bits per sample. */
+ {
+ .num_channels = 4,
+ .sample_freq_khz = 48,
+ .container_bits_per_sample = 16,
+ .valid_bits_per_sample = 16,
+ .speaker_mask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT |
+ SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT,
+ .settings_file = "dmic-4ch-48khz-16b.bin",
+ },
+ /* 48 KHz 32-bits per sample. */
+ {
+ .num_channels = 4,
+ .sample_freq_khz = 48,
+ .container_bits_per_sample = 32,
+ .valid_bits_per_sample = 32,
+ .speaker_mask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT |
+ SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT,
+ .settings_file = "dmic-4ch-48khz-32b.bin",
+ },
+};
+
+static const struct nhlt_dmic_array_config dmic_4ch_mic_config = {
+ .tdm_config = {
+ .config_type = NHLT_TDM_MIC_ARRAY,
+ },
+ .array_type = NHLT_MIC_ARRAY_4CH_L_SHAPED,
+};
+
+static const struct nhlt_endp_descriptor dmic_4ch_descriptors[] = {
+ {
+ .link = NHLT_LINK_PDM,
+ .device = NHLT_PDM_DEV,
+ .direction = NHLT_DIR_CAPTURE,
+ .vid = NHLT_VID,
+ .did = NHLT_DID_DMIC,
+ .cfg = &dmic_4ch_mic_config,
+ .cfg_size = sizeof(dmic_4ch_mic_config),
+ .formats = dmic_4ch_formats,
+ .num_formats = ARRAY_SIZE(dmic_4ch_formats),
+ },
+};
+
+int nhlt_soc_add_dmic_array(struct nhlt *nhlt, int num_channels)
+{
+ switch (num_channels) {
+ case 2:
+ return nhlt_add_endpoints(nhlt, dmic_2ch_descriptors,
+ ARRAY_SIZE(dmic_2ch_descriptors));
+ case 4:
+ return nhlt_add_endpoints(nhlt, dmic_4ch_descriptors,
+ ARRAY_SIZE(dmic_4ch_descriptors));
+ default:
+ return -1;
+ }
+}
diff --git a/src/soc/intel/kabylake/nhlt/max98357.c b/src/soc/intel/kabylake/nhlt/max98357.c
new file mode 100644
index 0000000..b2abc26
--- /dev/null
+++ b/src/soc/intel/kabylake/nhlt/max98357.c
@@ -0,0 +1,47 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2015 Google, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <soc/nhlt.h>
+
+static const struct nhlt_format_config max98357_render_formats[] = {
+ /* 48 KHz 24-bits per sample. */
+ {
+ .num_channels = 2,
+ .sample_freq_khz = 48,
+ .container_bits_per_sample = 32,
+ .valid_bits_per_sample = 24,
+ .speaker_mask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT,
+ .settings_file = "max98357-render-2ch-48khz-24b.bin",
+ },
+};
+
+static const struct nhlt_endp_descriptor max98357_descriptors[] = {
+ {
+ .link = NHLT_LINK_SSP,
+ .device = NHLT_SSP_DEV_I2S,
+ .direction = NHLT_DIR_RENDER,
+ .vid = NHLT_VID,
+ .did = NHLT_DID_SSP,
+ .formats = max98357_render_formats,
+ .num_formats = ARRAY_SIZE(max98357_render_formats),
+ },
+};
+
+int nhlt_soc_add_max98357(struct nhlt *nhlt, int hwlink)
+{
+ /* Virtual bus id of SSP links are the hardware port ids proper. */
+ return nhlt_add_ssp_endpoints(nhlt, hwlink, max98357_descriptors,
+ ARRAY_SIZE(max98357_descriptors));
+}
diff --git a/src/soc/intel/kabylake/nhlt/nau88l25.c b/src/soc/intel/kabylake/nhlt/nau88l25.c
new file mode 100644
index 0000000..dd91435
--- /dev/null
+++ b/src/soc/intel/kabylake/nhlt/nau88l25.c
@@ -0,0 +1,71 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2015 Google, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <soc/nhlt.h>
+
+/* The same DSP firmware settings are used for both the capture and
+ * render endpoints. */
+static const struct nhlt_format_config nau88l25_formats[] = {
+ /* 48 KHz 24-bits per sample. */
+ {
+ .num_channels = 2,
+ .sample_freq_khz = 48,
+ .container_bits_per_sample = 32,
+ .valid_bits_per_sample = 24,
+ .speaker_mask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT,
+ .settings_file = "nau88l25-2ch-48khz-24b.bin",
+ },
+};
+
+/* The nau88l25 just has headphones and a mic. Both the capture and render
+ * endpoints occupy the same virtual slot. */
+static const struct nhlt_tdm_config tdm_config = {
+ .virtual_slot = 0,
+ .config_type = NHLT_TDM_BASIC,
+};
+
+static const struct nhlt_endp_descriptor nau88l25_descriptors[] = {
+ /* Render Endpoint */
+ {
+ .link = NHLT_LINK_SSP,
+ .device = NHLT_SSP_DEV_I2S,
+ .direction = NHLT_DIR_RENDER,
+ .vid = NHLT_VID,
+ .did = NHLT_DID_SSP,
+ .cfg = &tdm_config,
+ .cfg_size = sizeof(tdm_config),
+ .formats = nau88l25_formats,
+ .num_formats = ARRAY_SIZE(nau88l25_formats),
+ },
+ /* Capture Endpoint */
+ {
+ .link = NHLT_LINK_SSP,
+ .device = NHLT_SSP_DEV_I2S,
+ .direction = NHLT_DIR_CAPTURE,
+ .vid = NHLT_VID,
+ .did = NHLT_DID_SSP,
+ .cfg = &tdm_config,
+ .cfg_size = sizeof(tdm_config),
+ .formats = nau88l25_formats,
+ .num_formats = ARRAY_SIZE(nau88l25_formats),
+ },
+};
+
+int nhlt_soc_add_nau88l25(struct nhlt *nhlt, int hwlink)
+{
+ /* Virtual bus id of SSP links are the hardware port ids proper. */
+ return nhlt_add_ssp_endpoints(nhlt, hwlink, nau88l25_descriptors,
+ ARRAY_SIZE(nau88l25_descriptors));
+}
diff --git a/src/soc/intel/kabylake/nhlt/ssm4567.c b/src/soc/intel/kabylake/nhlt/ssm4567.c
new file mode 100644
index 0000000..6808bff
--- /dev/null
+++ b/src/soc/intel/kabylake/nhlt/ssm4567.c
@@ -0,0 +1,70 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2015 Google, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <soc/nhlt.h>
+
+static const struct nhlt_format_config ssm4567_render_formats[] = {
+ /* 48 KHz 24-bits per sample. */
+ {
+ .num_channels = 2,
+ .sample_freq_khz = 48,
+ .container_bits_per_sample = 32,
+ .valid_bits_per_sample = 24,
+ .speaker_mask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT,
+ .settings_file = "ssm4567-render-2ch-48khz-24b.bin",
+ },
+};
+
+/* Capture Blob used for IV feedback for Speaker Protection Algorithm */
+static const struct nhlt_format_config ssm4567_capture_formats[] = {
+ /* 48 KHz 32-bits per sample. */
+ {
+ .num_channels = 4,
+ .sample_freq_khz = 48,
+ .container_bits_per_sample = 32,
+ .valid_bits_per_sample = 32,
+ .settings_file = "ssm4567-capture-4ch-48khz-32b.bin",
+ },
+};
+
+static const struct nhlt_endp_descriptor ssm4567_descriptors[] = {
+ /* Render Endpoint */
+ {
+ .link = NHLT_LINK_SSP,
+ .device = NHLT_SSP_DEV_I2S,
+ .direction = NHLT_DIR_RENDER,
+ .vid = NHLT_VID,
+ .did = NHLT_DID_SSP,
+ .formats = ssm4567_render_formats,
+ .num_formats = ARRAY_SIZE(ssm4567_render_formats),
+ },
+ /* Capture Endpoint */
+ {
+ .link = NHLT_LINK_SSP,
+ .device = NHLT_SSP_DEV_I2S,
+ .direction = NHLT_DIR_CAPTURE,
+ .vid = NHLT_VID,
+ .did = NHLT_DID_SSP,
+ .formats = ssm4567_capture_formats,
+ .num_formats = ARRAY_SIZE(ssm4567_capture_formats),
+ },
+};
+
+int nhlt_soc_add_ssm4567(struct nhlt *nhlt, int hwlink)
+{
+ /* Virtual bus id of SSP links are the hardware port ids proper. */
+ return nhlt_add_ssp_endpoints(nhlt, hwlink, ssm4567_descriptors,
+ ARRAY_SIZE(ssm4567_descriptors));
+}
diff --git a/src/soc/intel/kabylake/pch.c b/src/soc/intel/kabylake/pch.c
new file mode 100644
index 0000000..cf221ad
--- /dev/null
+++ b/src/soc/intel/kabylake/pch.c
@@ -0,0 +1,97 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008-2009 coresystems GmbH
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <console/console.h>
+#include <delay.h>
+#include <arch/io.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_def.h>
+#include <soc/pch.h>
+#include <soc/pci_devs.h>
+#include <soc/ramstage.h>
+#include <soc/spi.h>
+
+u8 pch_revision(void)
+{
+ return pci_read_config8(PCH_DEV_LPC, PCI_REVISION_ID);
+}
+
+u16 pch_type(void)
+{
+ return pci_read_config16(PCH_DEV_LPC, PCI_DEVICE_ID);
+}
+
+void *get_spi_bar(void)
+{
+ device_t dev = PCH_DEV_SPI;
+ uint32_t bar;
+
+ bar = pci_read_config32(dev, PCI_BASE_ADDRESS_0);
+ /* Bits 31-12 are the base address as per EDS for SPI 1F/5,
+ * Don't care about 0-11 bit
+ */
+ return (void *)(bar & ~PCI_BASE_ADDRESS_MEM_ATTR_MASK);
+}
+
+u32 pch_read_soft_strap(int id)
+{
+ uint32_t fdoc;
+ void *spibar = get_spi_bar();
+
+ fdoc = read32(spibar + SPIBAR_FDOC);
+ fdoc &= ~0x00007ffc;
+ write32(spibar + SPIBAR_FDOC, fdoc);
+
+ fdoc |= 0x00004000;
+ fdoc |= id * 4;
+ write32(spibar + SPIBAR_FDOC, fdoc);
+
+ return read32(spibar + SPIBAR_FDOD);
+}
+
+#if ENV_RAMSTAGE
+void pch_enable_dev(device_t dev)
+{
+ /* FSP should implement routines to disable PCH IPs */
+ u32 reg32;
+
+ /* These devices need special enable/disable handling */
+ switch (PCI_SLOT(dev->path.pci.devfn)) {
+ case PCH_DEV_SLOT_PCIE:
+ return;
+ }
+
+ if (!dev->enabled) {
+ printk(BIOS_DEBUG, "%s: Disabling device\n", dev_path(dev));
+
+ /* Ensure memory, io, and bus master are all disabled */
+ reg32 = pci_read_config32(dev, PCI_COMMAND);
+ reg32 &= ~(PCI_COMMAND_MASTER |
+ PCI_COMMAND_MEMORY | PCI_COMMAND_IO);
+ pci_write_config32(dev, PCI_COMMAND, reg32);
+
+ /* Disable this device if possible */
+ } else {
+ /* Enable SERR */
+ reg32 = pci_read_config32(dev, PCI_COMMAND);
+ reg32 |= PCI_COMMAND_SERR;
+ pci_write_config32(dev, PCI_COMMAND, reg32);
+ }
+}
+
+#endif
diff --git a/src/soc/intel/kabylake/pcie.c b/src/soc/intel/kabylake/pcie.c
new file mode 100644
index 0000000..f594bf1
--- /dev/null
+++ b/src/soc/intel/kabylake/pcie.c
@@ -0,0 +1,106 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008-2009 coresystems GmbH
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <chip.h>
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pciexp.h>
+#include <device/pci_def.h>
+#include <device/pci_ids.h>
+#include <soc/gpio.h>
+#include <soc/lpc.h>
+#include <soc/pch.h>
+#include <soc/pci_devs.h>
+#include <soc/cpu.h>
+#include <delay.h>
+
+static void pch_pcie_init(struct device *dev)
+{
+ u16 reg16;
+ u32 reg32;
+
+ printk(BIOS_DEBUG, "Initializing PCH PCIe bridge.\n");
+
+ /* Enable SERR */
+ reg32 = pci_read_config32(dev, PCI_COMMAND);
+ reg32 |= PCI_COMMAND_SERR;
+ pci_write_config32(dev, PCI_COMMAND, reg32);
+
+ /* Enable Bus Master */
+ reg32 = pci_read_config32(dev, PCI_COMMAND);
+ reg32 |= PCI_COMMAND_MASTER;
+ pci_write_config32(dev, PCI_COMMAND, reg32);
+
+ /* Set Cache Line Size to 0x10 */
+ pci_write_config8(dev, 0x0c, 0x10);
+
+ reg16 = pci_read_config16(dev, 0x3e);
+ reg16 &= ~(1 << 0); /* disable parity error response */
+ reg16 |= (1 << 2); /* ISA enable */
+ pci_write_config16(dev, 0x3e, reg16);
+
+#ifdef EVEN_MORE_DEBUG
+ reg32 = pci_read_config32(dev, 0x20);
+ printk(BIOS_SPEW, " MBL = 0x%08x\n", reg32);
+ reg32 = pci_read_config32(dev, 0x24);
+ printk(BIOS_SPEW, " PMBL = 0x%08x\n", reg32);
+ reg32 = pci_read_config32(dev, 0x28);
+ printk(BIOS_SPEW, " PMBU32 = 0x%08x\n", reg32);
+ reg32 = pci_read_config32(dev, 0x2c);
+ printk(BIOS_SPEW, " PMLU32 = 0x%08x\n", reg32);
+#endif
+
+ /* Clear errors in status registers */
+ reg16 = pci_read_config16(dev, 0x06);
+ pci_write_config16(dev, 0x06, reg16);
+ reg16 = pci_read_config16(dev, 0x1e);
+ pci_write_config16(dev, 0x1e, reg16);
+}
+
+static void pcie_set_L1_ss_max_latency(device_t dev, unsigned int off)
+{
+ /* Set max snoop and non-snoop latency for the SOC */
+ pci_mmio_write_config32(dev, off, 0x10031003);
+}
+
+static struct pci_operations pcie_ops = {
+ .set_L1_ss_latency = pcie_set_L1_ss_max_latency,
+};
+
+static struct device_operations device_ops = {
+ .read_resources = pci_bus_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_bus_enable_resources,
+ .init = pch_pcie_init,
+ .enable = NULL,
+ .scan_bus = pciexp_scan_bridge,
+ .ops_pci = &pcie_ops,
+};
+
+static const unsigned short pcie_device_ids[] = {
+ /* Sunrisepoint-LP */
+ 0x9d10, 0x9d11, 0x9d12, 0x9d13, 0x9d14, 0x9d15, 0x9d16, 0x9d17,
+ 0x9d18, 0x9d19, 0x9d1a, 0x9d1b,
+ 0
+};
+
+static const struct pci_driver pch_pcie __pci_driver = {
+ .ops = &device_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .devices = pcie_device_ids,
+};
diff --git a/src/soc/intel/kabylake/pcr.c b/src/soc/intel/kabylake/pcr.c
new file mode 100644
index 0000000..260cadd
--- /dev/null
+++ b/src/soc/intel/kabylake/pcr.c
@@ -0,0 +1,187 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include <arch/io.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <soc/pcr.h>
+#include <soc/iomap.h>
+#include <console/console.h>
+
+static inline void *pcr_reg_address(u8 pid, u16 offset)
+{
+ uintptr_t reg_addr;
+
+ /* Create an address based off of port id and offset. */
+ reg_addr = PCH_PCR_BASE_ADDRESS;
+ reg_addr += ((uintptr_t)pid) << PCR_PORTID_SHIFT;
+ reg_addr += ((uintptr_t)offset) << PCR_OFFSET_SHIFT;
+
+ return (void *)reg_addr;
+}
+
+uint8_t *pcr_port_regs(u8 pid)
+{
+ return pcr_reg_address(pid, 0);
+}
+
+/*
+ * Read PCR register. (This is internal function)
+ * It returns PCR register and size in 1/2/4 bytes.
+ * The offset should not exceed 0xFFFF and must be aligned with size
+ */
+static int pch_pcr_read(u8 pid, u16 offset, u32 size, void *data)
+{
+ if ((offset & (size - 1)) != 0) {
+ printk(BIOS_DEBUG,
+ "PchPcrRead error. Invalid Offset: %x Size: %x",
+ offset, size);
+ return -1;
+ }
+ switch (size) {
+ case 4:
+ *(u32 *) data = read32(pcr_reg_address(pid, offset));
+ break;
+ case 2:
+ *(u16 *) data = read16(pcr_reg_address(pid, offset));
+ break;
+ case 1:
+ *(u8 *) data = read8(pcr_reg_address(pid, offset));
+ break;
+ default:
+ return -1;
+ }
+ return 0;
+}
+
+int pcr_read32(u8 pid, u16 offset, u32 *outdata)
+{
+ return pch_pcr_read(pid, offset, sizeof(u32), (u32 *)outdata);
+}
+
+int pcr_read16(u8 pid, u16 offset, u16 *outdata)
+{
+ return pch_pcr_read(pid, offset, sizeof(u16), (u32 *)outdata);
+}
+
+int pcr_read8(u8 pid, u16 offset, u8 *outdata)
+{
+ return pch_pcr_read(pid, offset, sizeof(u8), (u32 *)outdata);
+}
+
+/*
+ * After every write one needs to perform a read an innocuous register to
+ * ensure the writes are completed for certain ports. This is done for
+ * all ports so that the callers don't need the per-port knowledge for
+ * each transaction.
+ */
+static inline void complete_write(void)
+{
+ /* Read the general control and function disable register. */
+ const size_t R_PCH_PCR_LPC_GCFD = 0x3418;
+ read32(pcr_reg_address(PID_LPC, R_PCH_PCR_LPC_GCFD));
+}
+
+/*
+ * Write PCR register. (This is internal function)
+ * It returns PCR register and size in 1/2/4 bytes.
+ * The offset should not exceed 0xFFFF and must be aligned with size
+ */
+static int pch_pcr_write(u8 pid, u16 offset, u32 size, u32 data)
+{
+ if ((offset & (size - 1)) != 0) {
+ printk(BIOS_DEBUG,
+ "PchPcrWrite error. Invalid Offset: %x Size: %x",
+ offset, size);
+ return -1;
+ }
+ /* Write the PCR register with provided data
+ * Then read back PCR register to prevent from back to back write.
+ */
+ switch (size) {
+ case 4:
+ write32(pcr_reg_address(pid, offset), (u32) data);
+ break;
+ case 2:
+ write16(pcr_reg_address(pid, offset), (u16) data);
+ break;
+ case 1:
+ write8(pcr_reg_address(pid, offset), (u8) data);
+ break;
+ default:
+ return -1;
+ }
+ /* Ensure the writes complete. */
+ complete_write();
+
+ return 0;
+}
+
+int pcr_write32(u8 pid, u16 offset, u32 indata)
+{
+ return pch_pcr_write(pid, offset, sizeof(u32), indata);
+}
+
+int pcr_write16(u8 pid, u16 offset, u16 indata)
+{
+ return pch_pcr_write(pid, offset, sizeof(u16), indata);
+}
+
+int pcr_write8(u8 pid, u16 offset, u8 indata)
+{
+ return pch_pcr_write(pid, offset, sizeof(u8), indata);
+}
+
+/*
+ * Write PCR register. (This is internal function)
+ * It programs PCR register and size in 1/2/4 bytes.
+ * The offset should not exceed 0xFFFF and must be aligned with size
+ *
+ * u8 defines as 8 bit Port ID that will be used when sending
+ * transaction to sideband.
+ */
+static int pcr_and_then_or(u8 pid, u16 offset, u32 size, u32 anddata,
+ u32 ordata)
+{
+ u8 status;
+ u32 data32 = 0;
+
+ status = pch_pcr_read(pid, offset, size, &data32);
+ if (status != 0)
+ return -1;
+
+ data32 &= anddata;
+ data32 |= ordata;
+
+ status = pch_pcr_write(pid, offset, size, data32);
+ return status;
+}
+
+int pcr_andthenor32(u8 pid, u16 offset, u32 anddata, u32 ordata)
+{
+ return pcr_and_then_or(pid, offset, sizeof(u32), anddata, ordata);
+}
+
+int pcr_andthenor16(u8 pid, u16 offset, u16 anddata, u16 ordata)
+{
+ return pcr_and_then_or(pid, offset, sizeof(u16), anddata, ordata);
+}
+
+int pcr_andthenor8(u8 pid, u16 offset, u8 anddata, u8 ordata)
+{
+ return pcr_and_then_or(pid, offset, sizeof(u8), anddata, ordata);
+}
diff --git a/src/soc/intel/kabylake/pei_data.c b/src/soc/intel/kabylake/pei_data.c
new file mode 100644
index 0000000..789fe09
--- /dev/null
+++ b/src/soc/intel/kabylake/pei_data.c
@@ -0,0 +1,49 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <chip.h>
+#include <console/console.h>
+#include <console/streams.h>
+#include <device/device.h>
+#include <device/pci_def.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <soc/iomap.h>
+#include <soc/pci_devs.h>
+#include <soc/pei_data.h>
+#include <soc/pei_wrapper.h>
+#include <soc/smm.h>
+
+static void ABI_X86 send_to_console(unsigned char b)
+{
+ console_tx_byte(b);
+}
+
+void soc_fill_pei_data(struct pei_data *pei_data)
+{
+ const struct device *dev;
+ const struct soc_intel_kabylake_config *config;
+
+ /* Set the parameters for MemoryInit */
+ dev = dev_find_slot(0, PCH_DEVFN_LPC);
+ config = dev->chip_info;
+
+ pei_data->pei_version = PEI_VERSION;
+ pei_data->tx_byte = &send_to_console;
+
+ /* Force a full memory train if RMT is enabled */
+ pei_data->disable_saved_data = config->Rmt;
+}
diff --git a/src/soc/intel/kabylake/pmc.c b/src/soc/intel/kabylake/pmc.c
new file mode 100644
index 0000000..e4eab6d
--- /dev/null
+++ b/src/soc/intel/kabylake/pmc.c
@@ -0,0 +1,312 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008-2009 coresystems GmbH
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <chip.h>
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <arch/io.h>
+#include <arch/ioapic.h>
+#include <arch/acpi.h>
+#include <cpu/cpu.h>
+#include <pc80/mc146818rtc.h>
+#include <reg_script.h>
+#include <string.h>
+#include <soc/gpio.h>
+#include <soc/iomap.h>
+#include <soc/pci_devs.h>
+#include <soc/pmc.h>
+#include <soc/pm.h>
+#include <cpu/x86/smm.h>
+#include <soc/pcr.h>
+#include <soc/ramstage.h>
+#if IS_ENABLED(CONFIG_CHROMEOS)
+#include <vendorcode/google/chromeos/chromeos.h>
+#include <vendorcode/google/chromeos/vbnv_layout.h>
+#endif
+
+static const struct reg_script pch_pmc_misc_init_script[] = {
+ /* SLP_S4=4s, SLP_S3=50ms, disable SLP_X stretching after SUS loss. */
+ REG_PCI_RMW16(GEN_PMCON_B,
+ ~(S4MAW_MASK | SLP_S3_MIN_ASST_WDTH_MASK),
+ S4MAW_4S | SLP_S3_MIN_ASST_WDTH_50MS |
+ DIS_SLP_X_STRCH_SUS_UP),
+ /* Enable SCI and clear SLP requests. */
+ REG_IO_RMW32(ACPI_BASE_ADDRESS + PM1_CNT, ~SLP_TYP, SCI_EN),
+ REG_SCRIPT_END
+};
+
+static const struct reg_script pmc_write1_to_clear_script[] = {
+ REG_PCI_OR32(GEN_PMCON_A, 0),
+ REG_PCI_OR32(GEN_PMCON_B, 0),
+ REG_PCI_OR32(GEN_PMCON_B, 0),
+ REG_RES_OR32(PWRMBASE, GBLRST_CAUSE0, 0),
+ REG_RES_OR32(PWRMBASE, GBLRST_CAUSE1, 0),
+ REG_SCRIPT_END
+};
+
+static void pch_pmc_add_mmio_resources(device_t dev)
+{
+ struct resource *res;
+
+ /* Memory-mmapped I/O registers. */
+ res = new_resource(dev, PWRMBASE);
+ res->base = PCH_PWRM_BASE_ADDRESS;
+ res->size = PCH_PWRM_BASE_SIZE;
+ res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED |
+ IORESOURCE_FIXED | IORESOURCE_RESERVE;
+}
+
+static void pch_pmc_add_io_resource(device_t dev, u16 base, u16 size, int index)
+{
+ struct resource *res;
+ res = new_resource(dev, index);
+ res->base = base;
+ res->size = size;
+ res->flags = IORESOURCE_IO | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+}
+
+static void pch_pmc_add_io_resources(device_t dev)
+{
+ /* PMBASE */
+ pch_pmc_add_io_resource(dev, ACPI_BASE_ADDRESS, ACPI_BASE_SIZE, ABASE);
+}
+
+static void pch_pmc_read_resources(device_t dev)
+{
+ /* Get the normal PCI resources of this device. */
+ pci_dev_read_resources(dev);
+
+ /* Add non-standard MMIO resources. */
+ pch_pmc_add_mmio_resources(dev);
+
+ /* Add IO resources. */
+ pch_pmc_add_io_resources(dev);
+}
+
+static void pch_set_acpi_mode(void)
+{
+ if (IS_ENABLED(CONFIG_HAVE_SMI_HANDLER) && !acpi_is_wakeup_s3()) {
+ printk(BIOS_DEBUG, "Disabling ACPI via APMC:\n");
+ outb(APM_CNT_ACPI_DISABLE, APM_CNT);
+ printk(BIOS_DEBUG, "done.\n");
+ }
+}
+
+#if IS_ENABLED(CONFIG_CHROMEOS_VBNV_CMOS)
+/*
+ * Preserve Vboot NV data when clearing CMOS as it will
+ * have been re-initialized already by Vboot firmware init.
+ */
+static void pch_cmos_init_preserve(int reset)
+{
+ uint8_t vbnv[VBNV_BLOCK_SIZE];
+ if (reset)
+ read_vbnv(vbnv);
+
+ cmos_init(reset);
+
+ if (reset)
+ save_vbnv(vbnv);
+}
+#endif
+
+static void pch_rtc_init(void)
+{
+ u8 reg8;
+ int rtc_failed;
+ /*PMC Controller Device 0x1F, Func 02*/
+ device_t dev = PCH_DEV_PMC;
+ reg8 = pci_read_config8(dev, GEN_PMCON_B);
+ rtc_failed = reg8 & RTC_BATTERY_DEAD;
+ if (rtc_failed) {
+ reg8 &= ~RTC_BATTERY_DEAD;
+ pci_write_config8(dev, GEN_PMCON_B, reg8);
+ printk(BIOS_DEBUG, "rtc_failed = 0x%x\n", rtc_failed);
+ }
+
+ /* Ensure the date is set including century byte. */
+ cmos_check_update_date();
+
+#if IS_ENABLED(CONFIG_CHROMEOS_VBNV_CMOS)
+ pch_cmos_init_preserve(rtc_failed);
+#else
+ cmos_init(rtc_failed);
+#endif
+}
+
+static void pmc_gpe_init(config_t *config)
+{
+ uint8_t *pmc_regs;
+ uint32_t gpio_cfg;
+ uint32_t gpio_cfg_reg;
+ const uint32_t gpio_cfg_mask =
+ (GPE0_DWX_MASK << GPE0_DW0_SHIFT) |
+ (GPE0_DWX_MASK << GPE0_DW1_SHIFT) |
+ (GPE0_DWX_MASK << GPE0_DW2_SHIFT);
+
+ pmc_regs = pmc_mmio_regs();
+ gpio_cfg = 0;
+
+ /* Route the GPIOs to the GPE0 block. Determine that all values
+ * are different, and if they aren't use the reset values. */
+ if (config->gpe0_dw0 == config->gpe0_dw1 ||
+ config->gpe0_dw1 == config->gpe0_dw2) {
+ printk(BIOS_INFO, "PMC: Using default GPE route.\n");
+ gpio_cfg = read32(pmc_regs + GPIO_CFG);
+ } else {
+ gpio_cfg |= (uint32_t)config->gpe0_dw0 << GPE0_DW0_SHIFT;
+ gpio_cfg |= (uint32_t)config->gpe0_dw1 << GPE0_DW1_SHIFT;
+ gpio_cfg |= (uint32_t)config->gpe0_dw2 << GPE0_DW2_SHIFT;
+ }
+ gpio_cfg_reg = read32(pmc_regs + GPIO_CFG) & ~gpio_cfg_mask;
+ gpio_cfg_reg |= gpio_cfg & gpio_cfg_mask;
+ write32(pmc_regs + GPIO_CFG, gpio_cfg_reg);
+
+ /* Set the routes in the GPIO communities as well. */
+ gpio_route_gpe(gpio_cfg_reg >> GPE0_DW0_SHIFT);
+
+ /* Set GPE enables based on devictree. */
+ enable_all_gpe(config->gpe0_en_1, config->gpe0_en_2,
+ config->gpe0_en_3, config->gpe0_en_4);
+}
+
+static void pch_power_options(void)
+{
+ u16 reg16;
+ const char *state;
+ /*PMC Controller Device 0x1F, Func 02*/
+ device_t dev = PCH_DEV_PMC;
+ /* Get the chip configuration */
+ config_t *config = dev->chip_info;
+ int pwr_on = CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL;
+
+ /*
+ * Which state do we want to goto after g3 (power restored)?
+ * 0 == S0 Full On
+ * 1 == S5 Soft Off
+ *
+ * If the option is not existent (Laptops), use Kconfig setting.
+ */
+ /*TODO: cmos_layout.bin need to verify; cause wrong CMOS setup*/
+ //get_option(&pwr_on, "power_on_after_fail");
+ pwr_on = MAINBOARD_POWER_ON;
+ reg16 = pci_read_config16(dev, GEN_PMCON_B);
+ reg16 &= 0xfffe;
+ switch (pwr_on) {
+ case MAINBOARD_POWER_OFF:
+ reg16 |= 1;
+ state = "off";
+ break;
+ case MAINBOARD_POWER_ON:
+ reg16 &= ~1;
+ state = "on";
+ break;
+ case MAINBOARD_POWER_KEEP:
+ reg16 &= ~1;
+ state = "state keep";
+ break;
+ default:
+ state = "undefined";
+ }
+ pci_write_config16(dev, GEN_PMCON_B, reg16);
+ printk(BIOS_INFO, "Set power %s after power failure.\n", state);
+
+ /* Set up GPE configuration. */
+ pmc_gpe_init(config);
+}
+
+static void config_deep_sX(uint32_t offset, uint32_t mask, int sx, int enable)
+{
+ uint32_t reg;
+ uint8_t *pmcbase = pmc_mmio_regs();
+
+ printk(BIOS_DEBUG, "%sabling Deep S%c\n",
+ enable ? "En" : "Dis", sx + '0');
+ reg = read32(pmcbase + offset);
+ if (enable)
+ reg |= mask;
+ else
+ reg &= ~mask;
+ write32(pmcbase + offset, reg);
+}
+
+static void config_deep_s5(int on)
+{
+ /* Treat S4 the same as S5. */
+ config_deep_sX(S4_PWRGATE_POL, S4DC_GATE_SUS | S4AC_GATE_SUS, 4, on);
+ config_deep_sX(S5_PWRGATE_POL, S5DC_GATE_SUS | S5AC_GATE_SUS, 5, on);
+}
+
+static void config_deep_s3(int on)
+{
+ config_deep_sX(S3_PWRGATE_POL, S3DC_GATE_SUS | S3AC_GATE_SUS, 3, on);
+}
+
+static void config_deep_sx(uint32_t deepsx_config)
+{
+ uint32_t reg;
+ uint8_t *pmcbase = pmc_mmio_regs();
+
+ reg = read32(pmcbase + DSX_CFG);
+ reg &= ~DSX_CFG_MASK;
+ reg |= deepsx_config;
+ write32(pmcbase + DSX_CFG, reg);
+}
+
+static void pmc_init(struct device *dev)
+{
+ config_t *config = dev->chip_info;
+
+ pch_rtc_init();
+
+ /* Initialize power management */
+ pch_power_options();
+
+ /* Note that certain bits may be cleared from running script as
+ * certain bit fields are write 1 to clear. */
+ reg_script_run_on_dev(dev, pch_pmc_misc_init_script);
+ pch_set_acpi_mode();
+
+ config_deep_s3(config->deep_s3_enable);
+ config_deep_s5(config->deep_s5_enable);
+ config_deep_sx(config->deep_sx_config);
+
+ /* Clear registers that contain write-1-to-clear bits. */
+ reg_script_run_on_dev(dev, pmc_write1_to_clear_script);
+}
+
+static struct device_operations device_ops = {
+ .read_resources = &pch_pmc_read_resources,
+ .set_resources = &pci_dev_set_resources,
+ .enable_resources = &pci_dev_enable_resources,
+ .init = &pmc_init,
+ .scan_bus = &scan_lpc_bus,
+ .ops_pci = &soc_pci_ops,
+};
+
+static const unsigned short pci_device_ids[] = {
+ 0x9d21,
+ 0
+};
+
+static const struct pci_driver pch_lpc __pci_driver = {
+ .ops = &device_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .devices = pci_device_ids,
+};
diff --git a/src/soc/intel/kabylake/pmutil.c b/src/soc/intel/kabylake/pmutil.c
new file mode 100644
index 0000000..6b06180
--- /dev/null
+++ b/src/soc/intel/kabylake/pmutil.c
@@ -0,0 +1,439 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/*
+ * Helper functions for dealing with power management registers
+ * and the differences between PCH variants.
+ */
+
+#include <arch/io.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_def.h>
+#include <console/console.h>
+#include <halt.h>
+#include <stdlib.h>
+#include <soc/gpio.h>
+#include <soc/iomap.h>
+#include <soc/lpc.h>
+#include <soc/pci_devs.h>
+#include <soc/pm.h>
+#include <soc/pmc.h>
+#include <soc/smbus.h>
+
+/* Print status bits with descriptive names */
+static void print_status_bits(u32 status, const char *bit_names[])
+{
+ int i;
+
+ if (!status)
+ return;
+
+ for (i = 31; i >= 0; i--) {
+ if (status & (1 << i)) {
+ if (bit_names[i])
+ printk(BIOS_DEBUG, "%s ", bit_names[i]);
+ else
+ printk(BIOS_DEBUG, "BIT%d ", i);
+ }
+ }
+}
+
+/* Print status bits as GPIO numbers */
+static void print_gpio_status(u32 status, int start)
+{
+ int i;
+
+ if (!status)
+ return;
+
+ for (i = 31; i >= 0; i--) {
+ if (status & (1 << i))
+ printk(BIOS_DEBUG, "GPIO%d ", start + i);
+ }
+}
+
+
+/*
+ * PM1_CNT
+ */
+
+/* Enable events in PM1 control register */
+void enable_pm1_control(u32 mask)
+{
+ u32 pm1_cnt = inl(ACPI_BASE_ADDRESS + PM1_CNT);
+ pm1_cnt |= mask;
+ outl(pm1_cnt, ACPI_BASE_ADDRESS + PM1_CNT);
+}
+
+/* Disable events in PM1 control register */
+void disable_pm1_control(u32 mask)
+{
+ u32 pm1_cnt = inl(ACPI_BASE_ADDRESS + PM1_CNT);
+ pm1_cnt &= ~mask;
+ outl(pm1_cnt, ACPI_BASE_ADDRESS + PM1_CNT);
+}
+
+
+/*
+ * PM1
+ */
+
+/* Clear and return PM1 status register */
+static u16 reset_pm1_status(void)
+{
+ u16 pm1_sts = inw(ACPI_BASE_ADDRESS + PM1_STS);
+ outw(pm1_sts, ACPI_BASE_ADDRESS + PM1_STS);
+ return pm1_sts;
+}
+
+/* Print PM1 status bits */
+static u16 print_pm1_status(u16 pm1_sts)
+{
+ const char *pm1_sts_bits[] = {
+ [0] = "TMROF",
+ [4] = "BM",
+ [5] = "GBL",
+ [8] = "PWRBTN",
+ [10] = "RTC",
+ [11] = "PRBTNOR",
+ [14] = "PCIEXPWAK",
+ [15] = "WAK",
+ };
+
+ if (!pm1_sts)
+ return 0;
+
+ printk(BIOS_SPEW, "PM1_STS: ");
+ print_status_bits(pm1_sts, pm1_sts_bits);
+ printk(BIOS_SPEW, "\n");
+
+ return pm1_sts;
+}
+
+/* Print, clear, and return PM1 status */
+u16 clear_pm1_status(void)
+{
+ return print_pm1_status(reset_pm1_status());
+}
+
+/* Set the PM1 register to events */
+void enable_pm1(u16 events)
+{
+ outw(events, ACPI_BASE_ADDRESS + PM1_EN);
+}
+
+
+/*
+ * SMI
+ */
+
+/* Clear and return SMI status register */
+static u32 reset_smi_status(void)
+{
+ u32 smi_sts = inl(ACPI_BASE_ADDRESS + SMI_STS);
+ outl(smi_sts, ACPI_BASE_ADDRESS + SMI_STS);
+ return smi_sts;
+}
+
+/* Print SMI status bits */
+static u32 print_smi_status(u32 smi_sts)
+{
+ const char *smi_sts_bits[] = {
+ [2] = "BIOS",
+ [3] = "LEGACY_USB",
+ [4] = "SLP_SMI",
+ [5] = "APM",
+ [6] = "SWSMI_TMR",
+ [8] = "PM1",
+ [9] = "GPE0",
+ [10] = "GPI",
+ [11] = "MCSMI",
+ [12] = "DEVMON",
+ [13] = "TCO",
+ [14] = "PERIODIC",
+ [15] = "SERIRQ_SMI",
+ [16] = "SMBUS_SMI",
+ [17] = "LEGACY_USB2",
+ [18] = "INTEL_USB2",
+ [20] = "PCI_EXP_SMI",
+ [21] = "MONITOR",
+ [26] = "SPI",
+ [27] = "GPIO_UNLOCK"
+ };
+
+ if (!smi_sts)
+ return 0;
+
+ printk(BIOS_DEBUG, "SMI_STS: ");
+ print_status_bits(smi_sts, smi_sts_bits);
+ printk(BIOS_DEBUG, "\n");
+
+ return smi_sts;
+}
+
+/* Print, clear, and return SMI status */
+u32 clear_smi_status(void)
+{
+ return print_smi_status(reset_smi_status());
+}
+
+/* Enable SMI event */
+void enable_smi(u32 mask)
+{
+ u32 smi_en = inl(ACPI_BASE_ADDRESS + SMI_EN);
+ smi_en |= mask;
+ outl(smi_en, ACPI_BASE_ADDRESS + SMI_EN);
+}
+
+/* Disable SMI event */
+void disable_smi(u32 mask)
+{
+ u32 smi_en = inl(ACPI_BASE_ADDRESS + SMI_EN);
+ smi_en &= ~mask;
+ outl(smi_en, ACPI_BASE_ADDRESS + SMI_EN);
+}
+
+/*
+ * TCO
+ */
+
+/* Clear TCO status and return events that are enabled and active */
+static u32 reset_tco_status(void)
+{
+ u16 tco1_sts;
+ u16 tco2_sts;
+ u16 tcobase;
+
+ tcobase = pmc_tco_regs();
+
+ /* TCO Status 2 register*/
+ tco2_sts = inw(tcobase + TCO2_STS);
+ tco2_sts |= (TCO2_STS_SECOND_TO | TCO2_STS_BOOT);
+ outw(tco2_sts, tcobase + TCO2_STS);
+
+ /* TCO Status 1 register*/
+ tco1_sts = inw(tcobase + TCO1_STS);
+
+ /* Clear SECOND_TO_STS bit */
+ if (tco2_sts & TCO2_STS_SECOND_TO)
+ outw(tco2_sts & ~TCO2_STS_SECOND_TO, tcobase + TCO2_STS);
+
+ return (tco2_sts << 16) | tco1_sts;
+}
+
+/* Print TCO status bits */
+static u32 print_tco_status(u32 tco_sts)
+{
+ const char *tco_sts_bits[] = {
+ [0] = "NMI2SMI",
+ [1] = "SW_TCO",
+ [2] = "TCO_INT",
+ [3] = "TIMEOUT",
+ [7] = "NEWCENTURY",
+ [8] = "BIOSWR",
+ [9] = "DMISCI",
+ [10] = "DMISMI",
+ [12] = "DMISERR",
+ [13] = "SLVSEL",
+ [16] = "INTRD_DET",
+ [17] = "SECOND_TO",
+ [18] = "BOOT",
+ [20] = "SMLINK_SLV"
+ };
+
+ if (!tco_sts)
+ return 0;
+
+ printk(BIOS_DEBUG, "TCO_STS: ");
+ print_status_bits(tco_sts, tco_sts_bits);
+ printk(BIOS_DEBUG, "\n");
+
+ return tco_sts;
+}
+
+/* Print, clear, and return TCO status */
+u32 clear_tco_status(void)
+{
+ return print_tco_status(reset_tco_status());
+}
+
+/* Enable TCO SCI */
+void enable_tco_sci(void)
+{
+ /* Clear pending events */
+ outl(TCOSCI_STS, ACPI_BASE_ADDRESS + GPE0_STS(3));
+
+ /* Enable TCO SCI events */
+ enable_gpe(TCOSCI_EN);
+}
+
+
+/*
+ * GPE0
+ */
+
+/* Clear a GPE0 status and return events that are enabled and active */
+static u32 reset_gpe(u16 sts_reg, u16 en_reg)
+{
+ u32 gpe0_sts = inl(ACPI_BASE_ADDRESS + sts_reg);
+ u32 gpe0_en = inl(ACPI_BASE_ADDRESS + en_reg);
+
+ outl(gpe0_sts, ACPI_BASE_ADDRESS + sts_reg);
+
+ /* Only report enabled events */
+ return gpe0_sts & gpe0_en;
+}
+
+/* Print GPE0 status bits */
+static u32 print_gpe_status(u32 gpe0_sts, const char *bit_names[])
+{
+ if (!gpe0_sts)
+ return 0;
+
+ printk(BIOS_DEBUG, "GPE0_STS: ");
+ print_status_bits(gpe0_sts, bit_names);
+ printk(BIOS_DEBUG, "\n");
+
+ return gpe0_sts;
+}
+
+/* Print GPE0 GPIO status bits */
+static u32 print_gpe_gpio(u32 gpe0_sts, int start)
+{
+ if (!gpe0_sts)
+ return 0;
+
+ printk(BIOS_DEBUG, "GPE0_STS: ");
+ print_gpio_status(gpe0_sts, start);
+ printk(BIOS_DEBUG, "\n");
+
+ return gpe0_sts;
+}
+
+/* Clear all GPE status and return "standard" GPE event status */
+u32 clear_gpe_status(void)
+{
+ const char *gpe0_sts_3_bits[] = {
+ [1] = "HOTPLUG",
+ [2] = "SWGPE",
+ [6] = "TCO_SCI",
+ [7] = "SMB_WAK",
+ [9] = "PCI_EXP",
+ [10] = "BATLOW",
+ [11] = "PME",
+ [12] = "ME",
+ [13] = "PME_B0",
+ [14] = "eSPI",
+ [15] = "GPIO Tier-2",
+ [16] = "LAN_WAKE",
+ [18] = "WADT"
+ };
+
+ print_gpe_gpio(reset_gpe(GPE0_STS(GPE_31_0), GPE0_EN(GPE_31_0)), 0);
+ print_gpe_gpio(reset_gpe(GPE0_STS(GPE_63_32), GPE0_EN(GPE_63_32)), 32);
+ print_gpe_gpio(reset_gpe(GPE0_STS(GPE_95_64), GPE0_EN(GPE_95_64)), 64);
+ return print_gpe_status(reset_gpe(GPE0_STS(GPE_STD), GPE0_EN(GPE_STD)),
+ gpe0_sts_3_bits);
+}
+
+/* Enable all requested GPE */
+void enable_all_gpe(u32 set1, u32 set2, u32 set3, u32 set4)
+{
+ outl(set1, ACPI_BASE_ADDRESS + GPE0_EN(GPE_31_0));
+ outl(set2, ACPI_BASE_ADDRESS + GPE0_EN(GPE_63_32));
+ outl(set3, ACPI_BASE_ADDRESS + GPE0_EN(GPE_95_64));
+ outl(set4, ACPI_BASE_ADDRESS + GPE0_EN(GPE_STD));
+}
+
+/* Disable all GPE */
+void disable_all_gpe(void)
+{
+ enable_all_gpe(0, 0, 0, 0);
+}
+
+/* Enable a standard GPE */
+void enable_gpe(u32 mask)
+{
+ u32 gpe0_en = inl(ACPI_BASE_ADDRESS + GPE0_EN(GPE_STD));
+ gpe0_en |= mask;
+ outl(gpe0_en, ACPI_BASE_ADDRESS + GPE0_EN(GPE_STD));
+}
+
+/* Disable a standard GPE */
+void disable_gpe(u32 mask)
+{
+ u32 gpe0_en = inl(ACPI_BASE_ADDRESS + GPE0_EN(GPE_STD));
+ gpe0_en &= ~mask;
+ outl(gpe0_en, ACPI_BASE_ADDRESS + GPE0_EN(GPE_STD));
+}
+
+int acpi_sci_irq(void)
+{
+ int scis = pci_read_config32(PCH_DEV_PMC, ACTL) & SCI_IRQ_SEL;
+ int sci_irq = 9;
+
+ /* Determine how SCI is routed. */
+ switch (scis) {
+ case SCIS_IRQ9:
+ case SCIS_IRQ10:
+ case SCIS_IRQ11:
+ sci_irq = scis - SCIS_IRQ9 + 9;
+ break;
+ case SCIS_IRQ20:
+ case SCIS_IRQ21:
+ case SCIS_IRQ22:
+ case SCIS_IRQ23:
+ sci_irq = scis - SCIS_IRQ20 + 20;
+ break;
+ default:
+ printk(BIOS_DEBUG, "Invalid SCI route! Defaulting to IRQ9.\n");
+ sci_irq = 9;
+ break;
+ }
+
+ printk(BIOS_DEBUG, "SCI is IRQ%d\n", sci_irq);
+ return sci_irq;
+}
+
+uint8_t *pmc_mmio_regs(void)
+{
+ uint32_t reg32;
+
+ reg32 = pci_read_config32(PCH_DEV_PMC, PWRMBASE);
+
+ /* 4KiB alignment. */
+ reg32 &= ~0xfff;
+
+ return (void *)(uintptr_t)reg32;
+}
+
+uint16_t pmc_tco_regs(void)
+{
+ uint16_t reg16;
+
+ reg16 = pci_read_config16(PCH_DEV_SMBUS, TCOBASE);
+
+ reg16 &= ~0x1f;
+
+ return reg16;
+}
+
+void poweroff(void)
+{
+ enable_pm1_control(SLP_EN | (SLP_TYP_S5 << SLP_TYP_SHIFT));
+ halt();
+}
diff --git a/src/soc/intel/kabylake/ramstage.c b/src/soc/intel/kabylake/ramstage.c
new file mode 100644
index 0000000..bfee655
--- /dev/null
+++ b/src/soc/intel/kabylake/ramstage.c
@@ -0,0 +1,23 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <soc/ramstage.h>
+
+void soc_init_pre_device(void *chip_info)
+{
+ /* Perform silicon specific init. */
+ intel_silicon_init();
+}
diff --git a/src/soc/intel/kabylake/romstage/Makefile.inc b/src/soc/intel/kabylake/romstage/Makefile.inc
new file mode 100644
index 0000000..6ae8137
--- /dev/null
+++ b/src/soc/intel/kabylake/romstage/Makefile.inc
@@ -0,0 +1,21 @@
+verstage-y += cpu.c
+verstage-y += i2c.c
+verstage-y += pch.c
+verstage-y += power_state.c
+verstage-y += report_platform.c
+verstage-y += romstage.c
+verstage-y += smbus.c
+verstage-y += spi.c
+verstage-y += systemagent.c
+verstage-y += uart.c
+
+romstage-y += cpu.c
+romstage-y += i2c.c
+romstage-y += pch.c
+romstage-y += power_state.c
+romstage-y += report_platform.c
+romstage-y += romstage.c
+romstage-y += smbus.c
+romstage-y += spi.c
+romstage-y += systemagent.c
+romstage-y += uart.c
diff --git a/src/soc/intel/kabylake/romstage/cpu.c b/src/soc/intel/kabylake/romstage/cpu.c
new file mode 100644
index 0000000..ab91317
--- /dev/null
+++ b/src/soc/intel/kabylake/romstage/cpu.c
@@ -0,0 +1,52 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <arch/cpu.h>
+#include <stdlib.h>
+#include <console/console.h>
+#include <cpu/x86/msr.h>
+#include <soc/cpu.h>
+#include <soc/msr.h>
+#include <soc/romstage.h>
+
+u32 cpu_family_model(void)
+{
+ return cpuid_eax(1) & 0x0fff0ff0;
+}
+
+void set_max_freq(void)
+{
+ msr_t msr, perf_ctl, platform_info;
+
+ /* Check for configurable TDP option */
+ platform_info = rdmsr(MSR_PLATFORM_INFO);
+
+ if ((platform_info.hi >> 1) & 3) {
+ /* Set to nominal TDP ratio */
+ msr = rdmsr(MSR_CONFIG_TDP_NOMINAL);
+ perf_ctl.lo = (msr.lo & 0xff) << 8;
+ } else {
+ /* Platform Info bits 15:8 give max ratio */
+ msr = rdmsr(MSR_PLATFORM_INFO);
+ perf_ctl.lo = msr.lo & 0xff00;
+ }
+
+ perf_ctl.hi = 0;
+ wrmsr(IA32_PERF_CTL, perf_ctl);
+
+ printk(BIOS_DEBUG, "CPU: frequency set to %d MHz\n",
+ ((perf_ctl.lo >> 8) & 0xff) * CPU_BCLK);
+}
diff --git a/src/soc/intel/kabylake/romstage/i2c.c b/src/soc/intel/kabylake/romstage/i2c.c
new file mode 100644
index 0000000..41f13ce
--- /dev/null
+++ b/src/soc/intel/kabylake/romstage/i2c.c
@@ -0,0 +1,109 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2016 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <arch/io.h>
+#include <commonlib/helpers.h>
+#include <device/device.h>
+#include <device/i2c.h>
+#include <device/pci_def.h>
+#include <soc/intel/common/lpss_i2c.h>
+#include <soc/iomap.h>
+#include <soc/pci_devs.h>
+#include <soc/romstage.h>
+#include <soc/serialio.h>
+#include "chip.h"
+
+uintptr_t lpss_i2c_base_address(unsigned bus)
+{
+ unsigned devfn;
+ pci_devfn_t dev;
+
+ /* Find device+function for this controller */
+ devfn = i2c_bus_to_devfn(bus);
+ if (devfn < 0)
+ return 0;
+
+ /* Form a PCI address for this device */
+ dev = PCI_DEV(0, PCI_SLOT(devfn), PCI_FUNC(devfn));
+
+ /* Read the first base address for this device */
+ return ALIGN_DOWN(pci_read_config32(dev, PCI_BASE_ADDRESS_0), 16);
+}
+
+static void i2c_early_init_bus(unsigned bus)
+{
+ ROMSTAGE_CONST struct soc_intel_kabylake_config *config;
+ ROMSTAGE_CONST struct device *tree_dev;
+ const struct lpss_i2c_speed_config *sptr;
+ enum i2c_speed speed;
+ pci_devfn_t dev;
+ unsigned devfn;
+ uintptr_t base;
+ uint32_t value;
+ void *reg;
+
+ /* Find the PCI device for this bus controller */
+ devfn = i2c_bus_to_devfn(bus);
+ if (devfn < 0)
+ return;
+
+ /* Look up the controller device in the devicetree */
+ dev = PCI_DEV(0, PCI_SLOT(devfn), PCI_FUNC(devfn));
+ tree_dev = dev_find_slot(0, devfn);
+ if (!tree_dev || !tree_dev->enabled)
+ return;
+
+ /* Skip if not enabled for early init */
+ config = tree_dev->chip_info;
+ if (!config)
+ return;
+ if (!config->i2c[bus].early_init)
+ return;
+
+ /* Prepare early base address for access before memory */
+ base = EARLY_I2C_BASE(bus);
+ pci_write_config32(dev, PCI_BASE_ADDRESS_0, base);
+ pci_write_config32(dev, PCI_COMMAND,
+ PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
+
+ /* Take device out of reset */
+ reg = (void *)(base + SIO_REG_PPR_RESETS);
+ value = read32(reg);
+ value |= SIO_REG_PPR_RESETS_FUNC | SIO_REG_PPR_RESETS_APB |
+ SIO_REG_PPR_RESETS_IDMA;
+ write32(reg, value);
+
+ /* Initialize the controller */
+ speed = config->i2c[bus].speed ? : I2C_SPEED_FAST;
+ lpss_i2c_init(bus, speed);
+
+ /* Apply custom speed config if it has been set by the board */
+ for (value = 0; value < LPSS_I2C_SPEED_CONFIG_COUNT; value++) {
+ sptr = &config->i2c[bus].speed_config[value];
+ if (sptr->speed == speed) {
+ lpss_i2c_set_speed_config(bus, sptr);
+ break;
+ }
+ }
+}
+
+void i2c_early_init(void)
+{
+ int bus;
+
+ /* Initialize I2C controllers that are enabled in devicetree */
+ for (bus = 0; bus < KABYLAKE_I2C_DEV_MAX; bus++)
+ i2c_early_init_bus(bus);
+}
diff --git a/src/soc/intel/kabylake/romstage/pch.c b/src/soc/intel/kabylake/romstage/pch.c
new file mode 100644
index 0000000..49022e0
--- /dev/null
+++ b/src/soc/intel/kabylake/romstage/pch.c
@@ -0,0 +1,133 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <arch/io.h>
+#include <chip.h>
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci_def.h>
+#include <reg_script.h>
+#include <soc/iomap.h>
+#include <soc/lpc.h>
+#include <soc/pch.h>
+#include <soc/pcr.h>
+#include <soc/pci_devs.h>
+#include <soc/pm.h>
+#include <soc/pmc.h>
+#include <soc/romstage.h>
+#include <soc/smbus.h>
+
+/* Max PXRC registers in ITSS*/
+#define MAX_PXRC_CONFIG 0x08
+
+static const u8 pch_interrupt_routing[] = {
+ 11, /* PARC: PIRQA -> IRQ11 */
+ 10, /* PBRC: PIRQB -> IRQ10 */
+ 11, /* PCRC: PIRQC -> IRQ11 */
+ 11, /* PDRC: PIRQD -> IRQ11 */
+ 11, /* PERC: PIRQE -> IRQ11 */
+ 11, /* PFRC: PIRQF -> IRQ11 */
+ 11, /* PGRC: PIRQG -> IRQ11 */
+ 11 /* PHRC: PIRQH -> IRQ11 */
+};
+
+static void pch_enable_lpc(void)
+{
+ /* Lookup device tree in romstage */
+ const struct device *dev;
+ const config_t *config;
+ u16 lpc_en;
+
+ /* IO Decode Range */
+ lpc_en = COMA_RANGE | (COMB_RANGE << 4);
+ pci_write_config16(PCH_DEV_LPC, LPC_IO_DEC, lpc_en);
+ pcr_write16(PID_DMI, R_PCH_PCR_DMI_LPCIOD, lpc_en);
+
+ /* IO Decode Enable */
+ lpc_en = CNF1_LPC_EN | CNF2_LPC_EN | GAMEL_LPC_EN | GAMEH_LPC_EN |
+ COMA_LPC_EN | KBC_LPC_EN | MC_LPC_EN;
+ pci_write_config16(PCH_DEV_LPC, LPC_EN, lpc_en);
+ pcr_write16(PID_DMI, R_PCH_PCR_DMI_LPCIOE, lpc_en);
+
+ dev = dev_find_slot(0, PCI_DEVFN(PCH_DEV_SLOT_LPC, 0));
+ if (!dev || !dev->chip_info)
+ return;
+ config = dev->chip_info;
+
+ /* Set in PCI generic decode range registers */
+ pci_write_config32(PCH_DEV_LPC, LPC_GEN1_DEC, config->gen1_dec);
+ pci_write_config32(PCH_DEV_LPC, LPC_GEN2_DEC, config->gen2_dec);
+ pci_write_config32(PCH_DEV_LPC, LPC_GEN3_DEC, config->gen3_dec);
+ pci_write_config32(PCH_DEV_LPC, LPC_GEN4_DEC, config->gen4_dec);
+
+ /* Mirror these same settings in DMI PCR */
+ pcr_write32(PID_DMI, R_PCH_PCR_DMI_LPCLGIR1, config->gen1_dec);
+ pcr_write32(PID_DMI, R_PCH_PCR_DMI_LPCLGIR2, config->gen2_dec);
+ pcr_write32(PID_DMI, R_PCH_PCR_DMI_LPCLGIR3, config->gen3_dec);
+ pcr_write32(PID_DMI, R_PCH_PCR_DMI_LPCLGIR4, config->gen4_dec);
+}
+
+static void pch_device_init(void)
+{
+ device_t dev;
+ u32 reg32;
+ u16 tcobase;
+ u16 tcocnt;
+
+ dev = PCH_DEV_PMC;
+
+ /* Enable ACPI and PMC mmio regs in PMC Config */
+ reg32 = pci_read_config32(dev, ACTL);
+ reg32 |= ACPI_EN | PWRM_EN;
+ pci_write_config32(dev, ACTL, reg32);
+
+ /* TCO timer halt */
+ tcobase = pmc_tco_regs();
+ tcocnt = inw(tcobase + TCO1_CNT);
+ tcocnt |= TCO_TMR_HLT;
+ outw(tcocnt, tcobase + TCO1_CNT);
+
+ /* Enable upper 128 bytes of CMOS */
+ pcr_andthenor32(PID_RTC, R_PCH_PCR_RTC_CONF, (u32)~0,
+ B_PCH_PCR_RTC_CONF_UCMOS_EN);
+}
+
+static void pch_interrupt_init(void)
+{
+ u8 index = 0;
+
+ for (index = 0; index < MAX_PXRC_CONFIG; index++) {
+ if (pch_interrupt_routing[index] < 16 &&
+ pch_interrupt_routing[index] > 2 &&
+ pch_interrupt_routing[index] != 8 &&
+ pch_interrupt_routing[index] != 13) {
+ pcr_write8(PID_ITSS,
+ (R_PCH_PCR_ITSS_PIRQA_ROUT + index),
+ pch_interrupt_routing[index]);
+ }
+ }
+}
+
+void pch_early_init(void)
+{
+ pch_device_init();
+
+ pch_interrupt_init();
+
+ pch_enable_lpc();
+
+ enable_smbus();
+}
diff --git a/src/soc/intel/kabylake/romstage/power_state.c b/src/soc/intel/kabylake/romstage/power_state.c
new file mode 100644
index 0000000..f03c304
--- /dev/null
+++ b/src/soc/intel/kabylake/romstage/power_state.c
@@ -0,0 +1,180 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <arch/early_variables.h>
+#include <arch/io.h>
+#include <cbmem.h>
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_def.h>
+#include <reg_script.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <soc/iomap.h>
+#include <soc/pmc.h>
+#include <soc/pci_devs.h>
+#include <soc/pm.h>
+#include <soc/romstage.h>
+#include <vendorcode/google/chromeos/vboot_common.h>
+
+static struct chipset_power_state power_state CAR_GLOBAL;
+
+static void migrate_power_state(int is_recovery)
+{
+ struct chipset_power_state *ps_cbmem;
+ struct chipset_power_state *ps_car;
+
+ ps_car = car_get_var_ptr(&power_state);
+ ps_cbmem = cbmem_add(CBMEM_ID_POWER_STATE, sizeof(*ps_cbmem));
+
+ if (ps_cbmem == NULL) {
+ printk(BIOS_DEBUG, "Not adding power state to cbmem!\n");
+ return;
+ }
+ memcpy(ps_cbmem, ps_car, sizeof(*ps_cbmem));
+}
+ROMSTAGE_CBMEM_INIT_HOOK(migrate_power_state)
+
+/* Return 0, 3, or 5 to indicate the previous sleep state. */
+static uint32_t prev_sleep_state(struct chipset_power_state *ps)
+{
+ /* Default to S0. */
+ uint32_t prev_sleep_state = ACPI_S0;
+
+ if (ps->pm1_sts & WAK_STS) {
+ switch (acpi_sleep_from_pm1(ps->pm1_cnt)) {
+ case ACPI_S3:
+ if (IS_ENABLED(CONFIG_HAVE_ACPI_RESUME))
+ prev_sleep_state = ACPI_S3;
+ break;
+ case ACPI_S5:
+ prev_sleep_state = ACPI_S5;
+ break;
+ }
+ /* Clear SLP_TYP. */
+ outl(ps->pm1_cnt & ~(SLP_TYP), ACPI_BASE_ADDRESS + PM1_CNT);
+ } else {
+ /*
+ * Check for any power failure to determine if this a wake from
+ * S5 because the PCH does not set the WAK_STS bit when waking
+ * from a true G3 state.
+ */
+ if (ps->gen_pmcon_b & (PWR_FLR | SUS_PWR_FLR))
+ prev_sleep_state = ACPI_S5;
+ }
+
+ /*
+ * If waking from S3 determine if deep S3 is enabled. If not,
+ * need to check both deep sleep well and normal suspend well.
+ * Otherwise just check deep sleep well.
+ */
+ if (prev_sleep_state == ACPI_S3) {
+ /* PWR_FLR represents deep sleep power well loss. */
+ uint32_t mask = PWR_FLR;
+
+ /* If deep s3 isn't enabled check the suspend well too. */
+ if (!deep_s3_enabled())
+ mask |= SUS_PWR_FLR;
+
+ if (ps->gen_pmcon_b & mask)
+ prev_sleep_state = ACPI_S5;
+ }
+
+ return prev_sleep_state;
+}
+
+static void dump_power_state(struct chipset_power_state *ps)
+{
+ printk(BIOS_DEBUG, "PM1_STS: %04x\n", ps->pm1_sts);
+ printk(BIOS_DEBUG, "PM1_EN: %04x\n", ps->pm1_en);
+ printk(BIOS_DEBUG, "PM1_CNT: %08x\n", ps->pm1_cnt);
+ printk(BIOS_DEBUG, "TCO_STS: %04x %04x\n",
+ ps->tco1_sts, ps->tco2_sts);
+
+ printk(BIOS_DEBUG, "GPE0_STS: %08x %08x %08x %08x\n",
+ ps->gpe0_sts[0], ps->gpe0_sts[1],
+ ps->gpe0_sts[2], ps->gpe0_sts[3]);
+ printk(BIOS_DEBUG, "GPE0_EN: %08x %08x %08x %08x\n",
+ ps->gpe0_en[0], ps->gpe0_en[1],
+ ps->gpe0_en[2], ps->gpe0_en[3]);
+
+ printk(BIOS_DEBUG, "GEN_PMCON: %08x %08x\n",
+ ps->gen_pmcon_a, ps->gen_pmcon_b);
+
+ printk(BIOS_DEBUG, "GBLRST_CAUSE: %08x %08x\n",
+ ps->gblrst_cause[0], ps->gblrst_cause[1]);
+
+ printk(BIOS_DEBUG, "Previous Sleep State: S%d\n",
+ ps->prev_sleep_state);
+}
+
+/* Fill power state structure from ACPI PM registers */
+struct chipset_power_state *fill_power_state(void)
+{
+ uint16_t tcobase;
+ uint8_t *pmc;
+ struct chipset_power_state *ps = car_get_var_ptr(&power_state);
+
+ tcobase = pmc_tco_regs();
+
+ ps->pm1_sts = inw(ACPI_BASE_ADDRESS + PM1_STS);
+ ps->pm1_en = inw(ACPI_BASE_ADDRESS + PM1_EN);
+ ps->pm1_cnt = inl(ACPI_BASE_ADDRESS + PM1_CNT);
+ ps->tco1_sts = inw(tcobase + TCO1_STS);
+ ps->tco2_sts = inw(tcobase + TCO2_STS);
+ ps->gpe0_sts[0] = inl(ACPI_BASE_ADDRESS + GPE0_STS(0));
+ ps->gpe0_sts[1] = inl(ACPI_BASE_ADDRESS + GPE0_STS(1));
+ ps->gpe0_sts[2] = inl(ACPI_BASE_ADDRESS + GPE0_STS(2));
+ ps->gpe0_sts[3] = inl(ACPI_BASE_ADDRESS + GPE0_STS(3));
+ ps->gpe0_en[0] = inl(ACPI_BASE_ADDRESS + GPE0_EN(0));
+ ps->gpe0_en[1] = inl(ACPI_BASE_ADDRESS + GPE0_EN(1));
+ ps->gpe0_en[2] = inl(ACPI_BASE_ADDRESS + GPE0_EN(2));
+ ps->gpe0_en[3] = inl(ACPI_BASE_ADDRESS + GPE0_EN(3));
+
+ ps->gen_pmcon_a = pci_read_config32(PCH_DEV_PMC, GEN_PMCON_A);
+ ps->gen_pmcon_b = pci_read_config32(PCH_DEV_PMC, GEN_PMCON_B);
+
+ pmc = pmc_mmio_regs();
+ ps->gblrst_cause[0] = read32(pmc + GBLRST_CAUSE0);
+ ps->gblrst_cause[1] = read32(pmc + GBLRST_CAUSE1);
+
+ ps->prev_sleep_state = prev_sleep_state(ps);
+
+ dump_power_state(ps);
+
+ return ps;
+}
+
+int vboot_platform_is_resuming(void)
+{
+ return acpi_sleep_from_pm1(inl(ACPI_BASE_ADDRESS + PM1_CNT)) == ACPI_S3;
+}
+
+/*
+ * The PM1 control is set to S5 when vboot requests a reboot because the power
+ * state code above may not have collected it's data yet. Therefore, set it to
+ * S5 when vboot requests a reboot. That's necessary if vboot fails in the
+ * resume path and requests a reboot. This prevents a reboot loop where the
+ * error is continually hit on the failing vboot resume path.
+ */
+void vboot_platform_prepare_reboot(void)
+{
+ uint16_t port = ACPI_BASE_ADDRESS + PM1_CNT;
+
+ outl((inl(port) & ~(SLP_TYP)) | (SLP_TYP_S5 << SLP_TYP_SHIFT), port);
+}
diff --git a/src/soc/intel/kabylake/romstage/report_platform.c b/src/soc/intel/kabylake/romstage/report_platform.c
new file mode 100644
index 0000000..eb5f216
--- /dev/null
+++ b/src/soc/intel/kabylake/romstage/report_platform.c
@@ -0,0 +1,216 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <arch/cpu.h>
+#include <arch/io.h>
+#include <console/console.h>
+#include <cpu/x86/msr.h>
+#include <device/pci.h>
+#include <soc/cpu.h>
+#include <soc/pch.h>
+#include <soc/pci_devs.h>
+#include <soc/romstage.h>
+#include <soc/systemagent.h>
+#include <string.h>
+
+static struct {
+ u32 cpuid;
+ const char *name;
+} cpu_table[] = {
+ { CPUID_KABYLAKE_C0, "Kabylake C0" },
+ { CPUID_KABYLAKE_D0, "Kabylake D0" },
+};
+
+static struct {
+ u16 mchid;
+ const char *name;
+} mch_table[] = {
+ { MCH_KABYLAKE_ID_U, "Kabylake-U" },
+ { MCH_KABYLAKE_ID_Y, "Kabylake-Y" },
+ { MCH_KABYLAKE_ID_ULX, "Kabylake-ULX" },
+};
+
+static struct {
+ u16 lpcid;
+ const char *name;
+} pch_table[] = {
+ { PCH_SPT_LP_SAMPLE, "Kabylake LP Sample" },
+ { PCH_SPT_LP_U_BASE, "Kabylake-U Base" },
+ { PCH_SPT_LP_U_PREMIUM, "Kabylake-U Premium" },
+ { PCH_SPT_LP_Y_PREMIUM, "Kabylake-Y Premium" },
+};
+
+static struct {
+ u16 igdid;
+ const char *name;
+} igd_table[] = {
+ { IGD_KABYLAKE_GT1_SULTM, "Kabylake ULT GT1"},
+ { IGD_KABYLAKE_GT2_SULXM, "Kabylake ULX GT2" },
+ { IGD_KABYLAKE_GT2_SULTM, "Kabylake ULT GT2" },
+};
+
+static void report_cpu_info(void)
+{
+ struct cpuid_result cpuidr;
+ u32 i, index;
+ char cpu_string[50], *cpu_name = cpu_string; /* 48 bytes are reported */
+ int vt, txt, aes;
+ msr_t microcode_ver;
+ const char *mode[] = {"NOT ", ""};
+ const char *cpu_type = "Unknown";
+
+ index = 0x80000000;
+ cpuidr = cpuid(index);
+ if (cpuidr.eax < 0x80000004) {
+ strcpy(cpu_string, "Platform info not available");
+ } else {
+ u32 *p = (u32 *) cpu_string;
+ for (i = 2; i <= 4; i++) {
+ cpuidr = cpuid(index + i);
+ *p++ = cpuidr.eax;
+ *p++ = cpuidr.ebx;
+ *p++ = cpuidr.ecx;
+ *p++ = cpuidr.edx;
+ }
+ }
+ /* Skip leading spaces in CPU name string */
+ while (cpu_name[0] == ' ')
+ cpu_name++;
+
+ microcode_ver.lo = 0;
+ microcode_ver.hi = 0;
+ wrmsr(0x8B, microcode_ver);
+ cpuidr = cpuid(1);
+ microcode_ver = rdmsr(0x8b);
+
+ /* Look for string to match the name */
+ for (i = 0; i < ARRAY_SIZE(cpu_table); i++) {
+ if (cpu_table[i].cpuid == cpuidr.eax) {
+ cpu_type = cpu_table[i].name;
+ break;
+ }
+ }
+
+ printk(BIOS_DEBUG, "CPU: %s\n", cpu_name);
+ printk(BIOS_DEBUG, "CPU: ID %x, %s, ucode: %08x\n",
+ cpuidr.eax, cpu_type, microcode_ver.hi);
+
+ aes = (cpuidr.ecx & (1 << 25)) ? 1 : 0;
+ txt = (cpuidr.ecx & (1 << 6)) ? 1 : 0;
+ vt = (cpuidr.ecx & (1 << 5)) ? 1 : 0;
+ printk(BIOS_DEBUG,
+ "CPU: AES %ssupported, TXT %ssupported, VT %ssupported\n",
+ mode[aes], mode[txt], mode[vt]);
+}
+
+static void report_mch_info(void)
+{
+ int i;
+ u16 mchid = pci_read_config16(SA_DEV_ROOT, PCI_DEVICE_ID);
+ u8 mch_revision = pci_read_config8(SA_DEV_ROOT, PCI_REVISION_ID);
+ const char *mch_type = "Unknown";
+
+ for (i = 0; i < ARRAY_SIZE(mch_table); i++) {
+ if (mch_table[i].mchid == mchid) {
+ mch_type = mch_table[i].name;
+ break;
+ }
+ }
+
+ printk(BIOS_DEBUG, "MCH: device id %04x (rev %02x) is %s\n",
+ mchid, mch_revision, mch_type);
+}
+
+static void report_pch_info(void)
+{
+ int i;
+ u16 lpcid = pch_type();
+ const char *pch_type = "Unknown";
+
+ for (i = 0; i < ARRAY_SIZE(pch_table); i++) {
+ if (pch_table[i].lpcid == lpcid) {
+ pch_type = pch_table[i].name;
+ break;
+ }
+ }
+ printk(BIOS_DEBUG, "PCH: device id %04x (rev %02x) is %s\n",
+ lpcid, pch_revision(), pch_type);
+}
+
+static void report_igd_info(void)
+{
+ int i;
+ u16 igdid = pci_read_config16(SA_DEV_IGD, PCI_DEVICE_ID);
+ const char *igd_type = "Unknown";
+
+ for (i = 0; i < ARRAY_SIZE(igd_table); i++) {
+ if (igd_table[i].igdid == igdid) {
+ igd_type = igd_table[i].name;
+ break;
+ }
+ }
+ printk(BIOS_DEBUG, "IGD: device id %04x (rev %02x) is %s\n",
+ igdid, pci_read_config8(SA_DEV_IGD, PCI_REVISION_ID), igd_type);
+}
+
+void report_platform_info(void)
+{
+ report_cpu_info();
+ report_mch_info();
+ report_pch_info();
+ report_igd_info();
+}
+
+/*
+ * Dump in the log memory controller configuration as read from the memory
+ * controller registers.
+ */
+void report_memory_config(void)
+{
+ u32 addr_decoder_common, addr_decode_ch[2];
+ int i;
+
+ addr_decoder_common = MCHBAR32(0x5000);
+ addr_decode_ch[0] = MCHBAR32(0x5004);
+ addr_decode_ch[1] = MCHBAR32(0x5008);
+
+ printk(BIOS_DEBUG, "memcfg DDR3 clock %d MHz\n",
+ (MCHBAR32(0x5e04) * 13333 * 2 + 50)/100);
+ printk(BIOS_DEBUG, "memcfg channel assignment: A: %d, B % d, C % d\n",
+ addr_decoder_common & 3,
+ (addr_decoder_common >> 2) & 3,
+ (addr_decoder_common >> 4) & 3);
+
+ for (i = 0; i < ARRAY_SIZE(addr_decode_ch); i++) {
+ u32 ch_conf = addr_decode_ch[i];
+ printk(BIOS_DEBUG, "memcfg channel[%d] config (%8.8x):\n",
+ i, ch_conf);
+ printk(BIOS_DEBUG, " enhanced interleave mode %s\n",
+ ((ch_conf >> 22) & 1) ? "on" : "off");
+ printk(BIOS_DEBUG, " rank interleave %s\n",
+ ((ch_conf >> 21) & 1) ? "on" : "off");
+ printk(BIOS_DEBUG, " DIMMA %d MB width %s %s rank%s\n",
+ ((ch_conf >> 0) & 0xff) * 256,
+ ((ch_conf >> 19) & 1) ? "x16" : "x8 or x32",
+ ((ch_conf >> 17) & 1) ? "dual" : "single",
+ ((ch_conf >> 16) & 1) ? "" : ", selected");
+ printk(BIOS_DEBUG, " DIMMB %d MB width %s %s rank%s\n",
+ ((ch_conf >> 8) & 0xff) * 256,
+ ((ch_conf >> 19) & 1) ? "x16" : "x8 or x32",
+ ((ch_conf >> 18) & 1) ? "dual" : "single",
+ ((ch_conf >> 16) & 1) ? ", selected" : "");
+ }
+}
diff --git a/src/soc/intel/kabylake/romstage/romstage.c b/src/soc/intel/kabylake/romstage/romstage.c
new file mode 100644
index 0000000..211be43
--- /dev/null
+++ b/src/soc/intel/kabylake/romstage/romstage.c
@@ -0,0 +1,268 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <stddef.h>
+#include <stdint.h>
+#include <arch/cpu.h>
+#include <arch/io.h>
+#include <arch/cbfs.h>
+#include <arch/stages.h>
+#include <arch/early_variables.h>
+#include <cbmem.h>
+#include <chip.h>
+#include <console/console.h>
+#include <cpu/x86/mtrr.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_def.h>
+#include <elog.h>
+#include <reset.h>
+#include <romstage_handoff.h>
+#include <soc/pci_devs.h>
+#include <soc/pei_wrapper.h>
+#include <soc/pm.h>
+#include <soc/pmc.h>
+#include <soc/serialio.h>
+#include <soc/romstage.h>
+#include <soc/spi.h>
+#include <stage_cache.h>
+#include <timestamp.h>
+#include <vendorcode/google/chromeos/chromeos.h>
+
+/* SOC initialization before RAM is enabled */
+void soc_pre_ram_init(struct romstage_params *params)
+{
+ /* Prepare to initialize memory */
+ soc_fill_pei_data(params->pei_data);
+}
+
+/* SOC initialization before the console is enabled. */
+void car_soc_pre_console_init(void)
+{
+ /* System Agent Early Initialization */
+ systemagent_early_init();
+
+ if (IS_ENABLED(CONFIG_UART_DEBUG))
+ pch_uart_init();
+}
+
+void car_soc_post_console_init(void)
+{
+ report_platform_info();
+ set_max_freq();
+ pch_early_init();
+ i2c_early_init();
+}
+
+int get_sw_write_protect_state(void)
+{
+ u8 status;
+
+ /* Return unprotected status if status read fails. */
+ return early_spi_read_wpsr(&status) ? 0 : !!(status & 0x80);
+}
+
+/* UPD parameters to be initialized before MemoryInit */
+void soc_memory_init_params(struct romstage_params *params,
+ MEMORY_INIT_UPD *upd)
+{
+ const struct device *dev;
+ const struct soc_intel_kabylake_config *config;
+
+ /* Set the parameters for MemoryInit */
+ dev = dev_find_slot(0, PCI_DEVFN(PCH_DEV_SLOT_LPC, 0));
+ config = dev->chip_info;
+
+ /*
+ * Set IGD stolen size to 64MB. The FBC hardware for kabylake does not
+ * have access to the bios_reserved range so it always assumes 8MB is
+ * used and so the kernel will avoid the last 8MB of the stolen window.
+ * With the default stolen size of 32MB(-8MB) there is not enough space
+ * for FBC to work with a high resolution panel.
+ */
+ upd->IgdDvmt50PreAlloc = 2;
+
+ upd->MmioSize = 0x800; /* 2GB in MB */
+ upd->TsegSize = CONFIG_SMM_TSEG_SIZE;
+ upd->IedSize = CONFIG_IED_REGION_SIZE;
+ upd->ProbelessTrace = config->ProbelessTrace;
+ upd->EnableTraceHub = config->EnableTraceHub;
+ if (recovery_mode_enabled())
+ upd->SaGv = 0; /* Disable SaGv in recovery mode. */
+ else
+ upd->SaGv = config->SaGv;
+ upd->RMT = config->Rmt;
+ upd->DdrFreqLimit = config->DdrFreqLimit;
+ if (IS_ENABLED(CONFIG_SKIP_FSP_CAR)) {
+ upd->FspCarBase = CONFIG_DCACHE_RAM_BASE;
+ upd->FspCarSize = CONFIG_DCACHE_RAM_SIZE_TOTAL;
+ }
+}
+
+void soc_display_memory_init_params(const MEMORY_INIT_UPD *old,
+ MEMORY_INIT_UPD *new)
+{
+ /* Display the parameters for MemoryInit */
+ printk(BIOS_SPEW, "UPD values for MemoryInit:\n");
+
+ fsp_display_upd_value("PlatformMemorySize", 8,
+ old->PlatformMemorySize, new->PlatformMemorySize);
+ fsp_display_upd_value("MemorySpdPtr00", 4, old->MemorySpdPtr00,
+ new->MemorySpdPtr00);
+ fsp_display_upd_value("MemorySpdPtr01", 4, old->MemorySpdPtr01,
+ new->MemorySpdPtr01);
+ fsp_display_upd_value("MemorySpdPtr10", 4, old->MemorySpdPtr10,
+ new->MemorySpdPtr10);
+ fsp_display_upd_value("MemorySpdPtr11", 4, old->MemorySpdPtr11,
+ new->MemorySpdPtr11);
+ fsp_display_upd_value("MemorySpdDataLen", 2, old->MemorySpdDataLen,
+ new->MemorySpdDataLen);
+ fsp_display_upd_value("DqByteMapCh0[0]", 1, old->DqByteMapCh0[0],
+ new->DqByteMapCh0[0]);
+ fsp_display_upd_value("DqByteMapCh0[1]", 1, old->DqByteMapCh0[1],
+ new->DqByteMapCh0[1]);
+ fsp_display_upd_value("DqByteMapCh0[2]", 1, old->DqByteMapCh0[2],
+ new->DqByteMapCh0[2]);
+ fsp_display_upd_value("DqByteMapCh0[3]", 1, old->DqByteMapCh0[3],
+ new->DqByteMapCh0[3]);
+ fsp_display_upd_value("DqByteMapCh0[4]", 1, old->DqByteMapCh0[4],
+ new->DqByteMapCh0[4]);
+ fsp_display_upd_value("DqByteMapCh0[5]", 1, old->DqByteMapCh0[5],
+ new->DqByteMapCh0[5]);
+ fsp_display_upd_value("DqByteMapCh0[6]", 1, old->DqByteMapCh0[6],
+ new->DqByteMapCh0[6]);
+ fsp_display_upd_value("DqByteMapCh0[7]", 1, old->DqByteMapCh0[7],
+ new->DqByteMapCh0[7]);
+ fsp_display_upd_value("DqByteMapCh0[8]", 1, old->DqByteMapCh0[8],
+ new->DqByteMapCh0[8]);
+ fsp_display_upd_value("DqByteMapCh0[9]", 1, old->DqByteMapCh0[9],
+ new->DqByteMapCh0[9]);
+ fsp_display_upd_value("DqByteMapCh0[10]", 1, old->DqByteMapCh0[10],
+ new->DqByteMapCh0[10]);
+ fsp_display_upd_value("DqByteMapCh0[11]", 1, old->DqByteMapCh0[11],
+ new->DqByteMapCh0[11]);
+ fsp_display_upd_value("DqByteMapCh1[0]", 1, old->DqByteMapCh1[0],
+ new->DqByteMapCh1[0]);
+ fsp_display_upd_value("DqByteMapCh1[1]", 1, old->DqByteMapCh1[1],
+ new->DqByteMapCh1[1]);
+ fsp_display_upd_value("DqByteMapCh1[2]", 1, old->DqByteMapCh1[2],
+ new->DqByteMapCh1[2]);
+ fsp_display_upd_value("DqByteMapCh1[3]", 1, old->DqByteMapCh1[3],
+ new->DqByteMapCh1[3]);
+ fsp_display_upd_value("DqByteMapCh1[4]", 1, old->DqByteMapCh1[4],
+ new->DqByteMapCh1[4]);
+ fsp_display_upd_value("DqByteMapCh1[5]", 1, old->DqByteMapCh1[5],
+ new->DqByteMapCh1[5]);
+ fsp_display_upd_value("DqByteMapCh1[6]", 1, old->DqByteMapCh1[6],
+ new->DqByteMapCh1[6]);
+ fsp_display_upd_value("DqByteMapCh1[7]", 1, old->DqByteMapCh1[7],
+ new->DqByteMapCh1[7]);
+ fsp_display_upd_value("DqByteMapCh1[8]", 1, old->DqByteMapCh1[8],
+ new->DqByteMapCh1[8]);
+ fsp_display_upd_value("DqByteMapCh1[9]", 1, old->DqByteMapCh1[9],
+ new->DqByteMapCh1[9]);
+ fsp_display_upd_value("DqByteMapCh1[10]", 1, old->DqByteMapCh1[10],
+ new->DqByteMapCh1[10]);
+ fsp_display_upd_value("DqByteMapCh1[11]", 1, old->DqByteMapCh1[11],
+ new->DqByteMapCh1[11]);
+ fsp_display_upd_value("DqsMapCpu2DramCh0[0]", 1,
+ old->DqsMapCpu2DramCh0[0], new->DqsMapCpu2DramCh0[0]);
+ fsp_display_upd_value("DqsMapCpu2DramCh0[1]", 1,
+ old->DqsMapCpu2DramCh0[1], new->DqsMapCpu2DramCh0[1]);
+ fsp_display_upd_value("DqsMapCpu2DramCh0[2]", 1,
+ old->DqsMapCpu2DramCh0[2], new->DqsMapCpu2DramCh0[2]);
+ fsp_display_upd_value("DqsMapCpu2DramCh0[3]", 1,
+ old->DqsMapCpu2DramCh0[3], new->DqsMapCpu2DramCh0[3]);
+ fsp_display_upd_value("DqsMapCpu2DramCh0[4]", 1,
+ old->DqsMapCpu2DramCh0[4], new->DqsMapCpu2DramCh0[4]);
+ fsp_display_upd_value("DqsMapCpu2DramCh0[5]", 1,
+ old->DqsMapCpu2DramCh0[5], new->DqsMapCpu2DramCh0[5]);
+ fsp_display_upd_value("DqsMapCpu2DramCh0[6]", 1,
+ old->DqsMapCpu2DramCh0[6], new->DqsMapCpu2DramCh0[6]);
+ fsp_display_upd_value("DqsMapCpu2DramCh0[7]", 1,
+ old->DqsMapCpu2DramCh0[7], new->DqsMapCpu2DramCh0[7]);
+ fsp_display_upd_value("DqsMapCpu2DramCh1[0]", 1,
+ old->DqsMapCpu2DramCh1[0], new->DqsMapCpu2DramCh1[0]);
+ fsp_display_upd_value("DqsMapCpu2DramCh1[1]", 1,
+ old->DqsMapCpu2DramCh1[1], new->DqsMapCpu2DramCh1[1]);
+ fsp_display_upd_value("DqsMapCpu2DramCh1[2]", 1,
+ old->DqsMapCpu2DramCh1[2], new->DqsMapCpu2DramCh1[2]);
+ fsp_display_upd_value("DqsMapCpu2DramCh1[3]", 1,
+ old->DqsMapCpu2DramCh1[3], new->DqsMapCpu2DramCh1[3]);
+ fsp_display_upd_value("DqsMapCpu2DramCh1[4]", 1,
+ old->DqsMapCpu2DramCh1[4], new->DqsMapCpu2DramCh1[4]);
+ fsp_display_upd_value("DqsMapCpu2DramCh1[5]", 1,
+ old->DqsMapCpu2DramCh1[5], new->DqsMapCpu2DramCh1[5]);
+ fsp_display_upd_value("DqsMapCpu2DramCh1[6]", 1,
+ old->DqsMapCpu2DramCh1[6], new->DqsMapCpu2DramCh1[6]);
+ fsp_display_upd_value("DqsMapCpu2DramCh1[7]", 1,
+ old->DqsMapCpu2DramCh1[7], new->DqsMapCpu2DramCh1[7]);
+ fsp_display_upd_value("DqPinsInterleaved", 1,
+ old->DqPinsInterleaved, new->DqPinsInterleaved);
+ fsp_display_upd_value("RcompResistor[0]", 2, old->RcompResistor[0],
+ new->RcompResistor[0]);
+ fsp_display_upd_value("RcompResistor[1]", 2, old->RcompResistor[1],
+ new->RcompResistor[1]);
+ fsp_display_upd_value("RcompResistor[2]", 2, old->RcompResistor[2],
+ new->RcompResistor[2]);
+ fsp_display_upd_value("RcompTarget[0]", 1, old->RcompTarget[0],
+ new->RcompTarget[0]);
+ fsp_display_upd_value("RcompTarget[1]", 1, old->RcompTarget[1],
+ new->RcompTarget[1]);
+ fsp_display_upd_value("RcompTarget[2]", 1, old->RcompTarget[2],
+ new->RcompTarget[2]);
+ fsp_display_upd_value("RcompTarget[3]", 1, old->RcompTarget[3],
+ new->RcompTarget[3]);
+ fsp_display_upd_value("RcompTarget[4]", 1, old->RcompTarget[4],
+ new->RcompTarget[4]);
+ fsp_display_upd_value("CaVrefConfig", 1, old->CaVrefConfig,
+ new->CaVrefConfig);
+ fsp_display_upd_value("SmramMask", 1, old->SmramMask, new->SmramMask);
+ fsp_display_upd_value("MrcFastBoot", 1, old->MrcFastBoot,
+ new->MrcFastBoot);
+ fsp_display_upd_value("IedSize", 4, old->IedSize, new->IedSize);
+ fsp_display_upd_value("TsegSize", 4, old->TsegSize, new->TsegSize);
+ fsp_display_upd_value("MmioSize", 2, old->MmioSize, new->MmioSize);
+ fsp_display_upd_value("EnableTraceHub", 1, old->EnableTraceHub,
+ new->EnableTraceHub);
+ fsp_display_upd_value("IgdDvmt50PreAlloc", 1, old->IgdDvmt50PreAlloc,
+ new->IgdDvmt50PreAlloc);
+ fsp_display_upd_value("InternalGfx", 1, old->InternalGfx,
+ new->InternalGfx);
+ fsp_display_upd_value("ApertureSize", 1, old->ApertureSize,
+ new->ApertureSize);
+ fsp_display_upd_value("SaGv", 1, old->SaGv, new->SaGv);
+ fsp_display_upd_value("RMT", 1, old->RMT, new->RMT);
+ fsp_display_upd_value("FspCarBase", 1, old->FspCarBase,
+ new->FspCarBase);
+ fsp_display_upd_value("FspCarSize", 1, old->FspCarSize,
+ new->FspCarSize);
+}
+
+/* SOC initialization after RAM is enabled. */
+void soc_after_ram_init(struct romstage_params *params)
+{
+ /* Set the DISB as soon as possible after DRAM
+ * init and MRC cache is saved.
+ */
+ u32 disb_val = 0;
+ device_t dev = PCH_DEV_PMC;
+ disb_val = pci_read_config32(dev, GEN_PMCON_A);
+ disb_val |= DISB;
+ /* Preserve bits which get cleared up if written 1 */
+ disb_val &= ~(GBL_RST_STS | MS4V);
+ pci_write_config32(dev, GEN_PMCON_A, disb_val);
+}
diff --git a/src/soc/intel/kabylake/romstage/smbus.c b/src/soc/intel/kabylake/romstage/smbus.c
new file mode 100644
index 0000000..f7e5dab
--- /dev/null
+++ b/src/soc/intel/kabylake/romstage/smbus.c
@@ -0,0 +1,51 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008-2009 coresystems GmbH
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <arch/io.h>
+#include <console/console.h>
+#include <device/pci_ids.h>
+#include <device/pci_def.h>
+#include <reg_script.h>
+#include <soc/iomap.h>
+#include <soc/pci_devs.h>
+#include <soc/smbus.h>
+#include <soc/romstage.h>
+
+static const struct reg_script smbus_init_script[] = {
+ /* Set SMBUS I/O base address */
+ REG_PCI_WRITE32(SMB_BASE, SMBUS_BASE_ADDRESS | 1),
+ /* Set SMBUS enable */
+ REG_PCI_WRITE8(HOSTC, HST_EN),
+ /* Enable I/O access */
+ REG_PCI_WRITE16(PCI_COMMAND, PCI_COMMAND_IO),
+ /* Disable interrupts */
+ REG_IO_WRITE8(SMBUS_BASE_ADDRESS + SMBHSTCTL, 0),
+ /* Clear errors */
+ REG_IO_WRITE8(SMBUS_BASE_ADDRESS + SMBHSTSTAT, 0xff),
+ /* Indicate the end of this array by REG_SCRIPT_END */
+ REG_SCRIPT_END,
+};
+
+void enable_smbus(void)
+{
+ reg_script_run_on_dev(PCH_DEV_SMBUS, smbus_init_script);
+}
+
+int smbus_read_byte(unsigned device, unsigned address)
+{
+ return do_smbus_read_byte(SMBUS_BASE_ADDRESS, device, address);
+}
diff --git a/src/soc/intel/kabylake/romstage/spi.c b/src/soc/intel/kabylake/romstage/spi.c
new file mode 100644
index 0000000..95a07c5
--- /dev/null
+++ b/src/soc/intel/kabylake/romstage/spi.c
@@ -0,0 +1,42 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <soc/flash_controller.h>
+#include <soc/romstage.h>
+
+/*
+ * Minimal set of commands to read WPSR from SPI.
+ * Returns 0 on success, < 0 on failure.
+ */
+int early_spi_read_wpsr(u8 *sr)
+{
+ uint8_t rdsr;
+ int ret = 0;
+
+ spi_init();
+
+ /* sending NULL for spiflash struct parameter since we are not
+ * calling HWSEQ read_status() call via Probe.
+ */
+ ret = pch_hwseq_read_status(NULL, &rdsr);
+ if (ret) {
+ printk(BIOS_ERR, "SPI rdsr failed\n");
+ return ret;
+ }
+ *sr = rdsr & WPSR_MASK_SRP0_BIT;
+
+ return 0;
+}
diff --git a/src/soc/intel/kabylake/romstage/systemagent.c b/src/soc/intel/kabylake/romstage/systemagent.c
new file mode 100644
index 0000000..2b796e3
--- /dev/null
+++ b/src/soc/intel/kabylake/romstage/systemagent.c
@@ -0,0 +1,52 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2010 coresystems GmbH
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <stdlib.h>
+#include <arch/io.h>
+#include <device/pci_def.h>
+#include <reg_script.h>
+#include <soc/iomap.h>
+#include <soc/pci_devs.h>
+#include <soc/romstage.h>
+#include <soc/systemagent.h>
+
+static const struct reg_script systemagent_early_init_script[] = {
+ REG_PCI_WRITE32(MCHBAR, MCH_BASE_ADDRESS | 1),
+ REG_PCI_WRITE32(DMIBAR, DMI_BASE_ADDRESS | 1),
+ REG_PCI_WRITE32(EPBAR, EP_BASE_ADDRESS | 1),
+ REG_MMIO_WRITE32(MCH_BASE_ADDRESS + EDRAMBAR, EDRAM_BASE_ADDRESS | 1),
+ REG_MMIO_WRITE32(MCH_BASE_ADDRESS + GDXCBAR, GDXC_BASE_ADDRESS | 1),
+
+ /* Set C0000-FFFFF to access RAM on both reads and writes */
+ REG_PCI_WRITE8(PAM0, 0x30),
+ REG_PCI_WRITE8(PAM1, 0x33),
+ REG_PCI_WRITE8(PAM2, 0x33),
+ REG_PCI_WRITE8(PAM3, 0x33),
+ REG_PCI_WRITE8(PAM4, 0x33),
+ REG_PCI_WRITE8(PAM5, 0x33),
+ REG_PCI_WRITE8(PAM6, 0x33),
+
+ /* Device enable: IGD and Mini-HD */
+ REG_PCI_WRITE32(DEVEN, DEVEN_D0EN | DEVEN_D2EN | DEVEN_D3EN),
+
+ REG_SCRIPT_END
+};
+
+void systemagent_early_init(void)
+{
+ reg_script_run_on_dev(SA_DEV_ROOT, systemagent_early_init_script);
+}
diff --git a/src/soc/intel/kabylake/romstage/uart.c b/src/soc/intel/kabylake/romstage/uart.c
new file mode 100644
index 0000000..303d99f
--- /dev/null
+++ b/src/soc/intel/kabylake/romstage/uart.c
@@ -0,0 +1,70 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <arch/io.h>
+#include <console/uart.h>
+#include <device/pci_def.h>
+#include <stdint.h>
+#include <soc/pci_devs.h>
+#include <soc/pcr.h>
+#include <soc/romstage.h>
+#include <soc/serialio.h>
+#include <gpio.h>
+
+/* UART2 pad configuration. Support RXD and TXD for now. */
+static const struct pad_config uart2_pads[] = {
+/* UART2_RXD */ PAD_CFG_NF(GPP_C20, NONE, DEEP, NF1),
+/* UART2_TXD */ PAD_CFG_NF(GPP_C21, NONE, DEEP, NF1),
+};
+
+void pch_uart_init(void)
+{
+ device_t dev = PCH_DEV_UART2;
+ u32 tmp;
+ u8 *base = (void *)uart_platform_base(CONFIG_UART_FOR_CONSOLE);
+
+ /* Set configured UART2 base address */
+ pci_write_config32(dev, PCI_BASE_ADDRESS_0, (u32)base);
+
+ /* Enable memory access and bus master */
+ tmp = pci_read_config32(dev, PCI_COMMAND);
+ tmp |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
+ pci_write_config32(dev, PCI_COMMAND, tmp);
+
+ /* Take UART2 out of reset */
+ tmp = read32(base + SIO_REG_PPR_RESETS);
+ tmp |= SIO_REG_PPR_RESETS_FUNC | SIO_REG_PPR_RESETS_APB |
+ SIO_REG_PPR_RESETS_IDMA;
+ write32(base + SIO_REG_PPR_RESETS, tmp);
+
+ /*
+ * Set M and N divisor inputs and enable clock.
+ * Main reference frequency to UART is:
+ * 120MHz * M / N = 120MHz * 48 / 3125 = 1843200Hz
+ */
+ tmp = read32(base + SIO_REG_PPR_CLOCK);
+ tmp |= SIO_REG_PPR_CLOCK_EN | SIO_REG_PPR_CLOCK_UPDATE |
+ (SIO_REG_PPR_CLOCK_N_DIV << 16) |
+ (SIO_REG_PPR_CLOCK_M_DIV << 1);
+ write32(base + SIO_REG_PPR_CLOCK, tmp);
+
+ /* Put UART2 in byte access mode for 16550 compatibility */
+ if (!IS_ENABLED(CONFIG_DRIVERS_UART_8250MEM_32))
+ pcr_andthenor32(PID_SERIALIO,
+ R_PCH_PCR_SERIAL_IO_GPPRVRW7, 0, SIO_PCH_LEGACY_UART2);
+
+ gpio_configure_pads(uart2_pads, ARRAY_SIZE(uart2_pads));
+}
diff --git a/src/soc/intel/kabylake/sd.c b/src/soc/intel/kabylake/sd.c
new file mode 100644
index 0000000..a75cf63
--- /dev/null
+++ b/src/soc/intel/kabylake/sd.c
@@ -0,0 +1,88 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2016 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <arch/acpi_device.h>
+#include <arch/acpigen.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <gpio.h>
+#include <soc/ramstage.h>
+#include "chip.h"
+
+#if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES)
+static void sd_fill_ssdt(struct device *dev)
+{
+ config_t *config = dev->chip_info;
+ const char *path;
+ struct acpi_gpio default_gpio = {
+ .type = ACPI_GPIO_TYPE_INTERRUPT,
+ .pull = ACPI_GPIO_PULL_NONE,
+ .irq.mode = IRQ_EDGE_TRIGGERED,
+ .irq.polarity = IRQ_ACTIVE_BOTH,
+ .irq.shared = IRQ_SHARED,
+ .irq.wake = IRQ_WAKE,
+ .interrupt_debounce_timeout = 10000, /* 100ms */
+ .pin_count = 1,
+ .pins = { config->sdcard_cd_gpio_default }
+ };
+ struct acpi_dp *dp;
+
+ if (!dev->enabled)
+ return;
+
+ /* Nothing to write if GPIO is not set in devicetree */
+ if (!config->sdcard_cd_gpio_default && !config->sdcard_cd_gpio.pins[0])
+ return;
+
+ /* Use device path as the Scope for the SSDT */
+ path = acpi_device_path(dev);
+ if (!path)
+ return;
+ acpigen_write_scope(path);
+ acpigen_write_name("_CRS");
+
+ /* Write GpioInt() as default (if set) or custom from devicetree */
+ acpigen_write_resourcetemplate_header();
+ if (config->sdcard_cd_gpio_default)
+ acpi_device_write_gpio(&default_gpio);
+ else
+ acpi_device_write_gpio(&config->sdcard_cd_gpio);
+ acpigen_write_resourcetemplate_footer();
+
+ /* Bind the cd-gpio name to the GpioInt() resource */
+ dp = acpi_dp_new_table("_DSD");
+ acpi_dp_add_gpio(dp, "cd-gpio", path, 0, 0, 1);
+ acpi_dp_write(dp);
+
+ acpigen_pop_len();
+}
+#endif
+
+static struct device_operations dev_ops = {
+ .read_resources = &pci_dev_read_resources,
+ .set_resources = &pci_dev_set_resources,
+ .enable_resources = &pci_dev_enable_resources,
+ .ops_pci = &soc_pci_ops,
+#if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES)
+ .acpi_fill_ssdt_generator = &sd_fill_ssdt,
+#endif
+};
+
+static const struct pci_driver pch_sd __pci_driver = {
+ .ops = &dev_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = 0x9d2d
+};
diff --git a/src/soc/intel/kabylake/smbus.c b/src/soc/intel/kabylake/smbus.c
new file mode 100644
index 0000000..97d05b6
--- /dev/null
+++ b/src/soc/intel/kabylake/smbus.c
@@ -0,0 +1,109 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008-2009 coresystems GmbH
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <arch/io.h>
+#include <console/console.h>
+#include <device/device.h>
+#include <device/path.h>
+#include <device/smbus.h>
+#include <device/smbus_def.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <soc/iomap.h>
+#include <soc/ramstage.h>
+#include <soc/smbus.h>
+
+static void pch_smbus_init(device_t dev)
+{
+ struct resource *res;
+ u16 reg16;
+
+ /* Enable clock gating */
+ reg16 = pci_read_config32(dev, 0x80);
+ reg16 &= ~((1 << 8)|(1 << 10)|(1 << 12)|(1 << 14));
+ pci_write_config32(dev, 0x80, reg16);
+
+ /* Set Receive Slave Address */
+ res = find_resource(dev, PCI_BASE_ADDRESS_4);
+ if (res)
+ outb(SMBUS_SLAVE_ADDR, res->base + SMB_RCV_SLVA);
+}
+
+static int lsmbus_read_byte(device_t dev, u8 address)
+{
+ u16 device;
+ struct resource *res;
+ struct bus *pbus;
+
+ device = dev->path.i2c.device;
+ pbus = get_pbus_smbus(dev);
+ res = find_resource(pbus->dev, PCI_BASE_ADDRESS_4);
+
+ return do_smbus_read_byte(res->base, device, address);
+}
+
+static int lsmbus_write_byte(device_t dev, u8 address, u8 data)
+{
+ u16 device;
+ struct resource *res;
+ struct bus *pbus;
+
+ device = dev->path.i2c.device;
+ pbus = get_pbus_smbus(dev);
+ res = find_resource(pbus->dev, PCI_BASE_ADDRESS_4);
+ return do_smbus_write_byte(res->base, device, address, data);
+}
+
+static struct smbus_bus_operations lops_smbus_bus = {
+ .read_byte = lsmbus_read_byte,
+ .write_byte = lsmbus_write_byte,
+};
+
+static void smbus_read_resources(device_t dev)
+{
+ struct resource *res = new_resource(dev, PCI_BASE_ADDRESS_4);
+ res->base = SMBUS_BASE_ADDRESS;
+ res->size = 32;
+ res->limit = res->base + res->size - 1;
+ res->flags = IORESOURCE_IO | IORESOURCE_FIXED | IORESOURCE_RESERVE |
+ IORESOURCE_STORED | IORESOURCE_ASSIGNED;
+
+ /* Also add MMIO resource */
+ res = pci_get_resource(dev, PCI_BASE_ADDRESS_0);
+}
+
+static struct device_operations smbus_ops = {
+ .read_resources = &smbus_read_resources,
+ .set_resources = &pci_dev_set_resources,
+ .enable_resources = &pci_dev_enable_resources,
+ .scan_bus = &scan_smbus,
+ .init = &pch_smbus_init,
+ .ops_smbus_bus = &lops_smbus_bus,
+ .ops_pci = &soc_pci_ops,
+};
+
+static const unsigned short pci_device_ids[] = {
+ 0x9d23, /* SunRisePoint LP */
+ 0
+};
+
+static const struct pci_driver pch_smbus __pci_driver = {
+ .ops = &smbus_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .devices = pci_device_ids,
+};
diff --git a/src/soc/intel/kabylake/smbus_common.c b/src/soc/intel/kabylake/smbus_common.c
new file mode 100644
index 0000000..9b1cac8
--- /dev/null
+++ b/src/soc/intel/kabylake/smbus_common.c
@@ -0,0 +1,150 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2005 Yinghai Lu <yinghailu at gmail.com>
+ * Copyright (C) 2008-2009 coresystems GmbH
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <arch/io.h>
+#include <console/console.h>
+#include <device/device.h>
+#include <device/path.h>
+#include <device/smbus_def.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <soc/ramstage.h>
+#include <soc/smbus.h>
+
+static void smbus_delay(void)
+{
+ inb(0x80);
+}
+
+static int smbus_wait_until_ready(u16 smbus_base)
+{
+ unsigned loops = SMBUS_TIMEOUT;
+ unsigned char byte;
+ do {
+ smbus_delay();
+ if (--loops == 0)
+ break;
+ byte = inb(smbus_base + SMBHSTSTAT);
+ } while (byte & 1);
+ return loops ? 0 : -1;
+}
+
+static int smbus_wait_until_done(u16 smbus_base)
+{
+ unsigned loops = SMBUS_TIMEOUT;
+ unsigned char byte;
+ do {
+ smbus_delay();
+ if (--loops == 0)
+ break;
+ byte = inb(smbus_base + SMBHSTSTAT);
+ } while ((byte & 1) || (byte & ~((1 << 6) | (1 << 0))) == 0);
+ return loops ? 0 : -1;
+}
+
+int do_smbus_read_byte(unsigned smbus_base, unsigned device, unsigned address)
+{
+ unsigned char global_status_register;
+ unsigned char byte;
+
+ if (smbus_wait_until_ready(smbus_base) < 0)
+ return SMBUS_WAIT_UNTIL_READY_TIMEOUT;
+
+ /* Setup transaction */
+ /* Disable interrupts */
+ outb(inb(smbus_base + SMBHSTCTL) & (~1), smbus_base + SMBHSTCTL);
+ /* Set the device I'm talking too */
+ outb(((device & 0x7f) << 1) | 1, smbus_base + SMBXMITADD);
+ /* Set the command/address... */
+ outb(address & 0xff, smbus_base + SMBHSTCMD);
+ /* Set up for a byte data read */
+ outb((inb(smbus_base + SMBHSTCTL) & 0xe3) | (0x2 << 2),
+ (smbus_base + SMBHSTCTL));
+ /* Clear any lingering errors, so the transaction will run */
+ outb(inb(smbus_base + SMBHSTSTAT), smbus_base + SMBHSTSTAT);
+
+ /* Clear the data byte... */
+ outb(0, smbus_base + SMBHSTDAT0);
+
+ /* Start the command */
+ outb((inb(smbus_base + SMBHSTCTL) | 0x40),
+ smbus_base + SMBHSTCTL);
+
+ /* Poll for transaction completion */
+ if (smbus_wait_until_done(smbus_base) < 0)
+ return SMBUS_WAIT_UNTIL_DONE_TIMEOUT;
+
+ global_status_register = inb(smbus_base + SMBHSTSTAT);
+
+ /* Ignore the "In Use" status... */
+ global_status_register &= ~(3 << 5);
+
+ /* Read results of transaction */
+ byte = inb(smbus_base + SMBHSTDAT0);
+ if (global_status_register != (1 << 1))
+ return SMBUS_ERROR;
+ return byte;
+}
+
+int do_smbus_write_byte(unsigned smbus_base, unsigned device,
+ unsigned address, unsigned data)
+{
+ unsigned char global_status_register;
+
+ if (smbus_wait_until_ready(smbus_base) < 0)
+ return SMBUS_WAIT_UNTIL_READY_TIMEOUT;
+
+ /* Setup transaction */
+ /* Disable interrupts */
+ outb(inb(smbus_base + SMBHSTCTL) & (~1), smbus_base + SMBHSTCTL);
+ /* Set the device I'm talking too */
+ outb(((device & 0x7f) << 1) & ~0x01, smbus_base + SMBXMITADD);
+ /* Set the command/address... */
+ outb(address & 0xff, smbus_base + SMBHSTCMD);
+ /* Set up for a byte data read */
+ outb((inb(smbus_base + SMBHSTCTL) & 0xe3) | (0x2 << 2),
+ (smbus_base + SMBHSTCTL));
+ /* Clear any lingering errors, so the transaction will run */
+ outb(inb(smbus_base + SMBHSTSTAT), smbus_base + SMBHSTSTAT);
+
+ /* Clear the data byte... */
+ outb(data, smbus_base + SMBHSTDAT0);
+
+ /* Start the command */
+ outb((inb(smbus_base + SMBHSTCTL) | 0x40),
+ smbus_base + SMBHSTCTL);
+
+ /* Poll for transaction completion */
+ if (smbus_wait_until_done(smbus_base) < 0) {
+ printk(BIOS_ERR, "SMBUS transaction timeout\n");
+ return SMBUS_WAIT_UNTIL_DONE_TIMEOUT;
+ }
+
+ global_status_register = inb(smbus_base + SMBHSTSTAT);
+
+ /* Ignore the "In Use" status... */
+ global_status_register &= ~(3 << 5);
+
+ /* Read results of transaction */
+ if (global_status_register != (1 << 1)) {
+ printk(BIOS_ERR, "SMBUS transaction error\n");
+ return SMBUS_ERROR;
+ }
+
+ return 0;
+}
diff --git a/src/soc/intel/kabylake/smi.c b/src/soc/intel/kabylake/smi.c
new file mode 100644
index 0000000..85c4663
--- /dev/null
+++ b/src/soc/intel/kabylake/smi.c
@@ -0,0 +1,121 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008-2009 coresystems GmbH
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <device/device.h>
+#include <device/pci.h>
+#include <console/console.h>
+#include <arch/io.h>
+#include <cpu/cpu.h>
+#include <cpu/x86/cache.h>
+#include <cpu/x86/smm.h>
+#include <string.h>
+#include <soc/iomap.h>
+#include <soc/pch.h>
+#include <soc/pm.h>
+#include <soc/smm.h>
+
+void southbridge_smm_clear_state(void)
+{
+ u32 smi_en;
+
+ printk(BIOS_DEBUG, "Initializing Southbridge SMI...");
+ printk(BIOS_SPEW, " ... pmbase = 0x%04x\n", ACPI_BASE_ADDRESS);
+
+ smi_en = inl(ACPI_BASE_ADDRESS + SMI_EN);
+ if (smi_en & APMC_EN) {
+ printk(BIOS_INFO, "SMI# handler already enabled?\n");
+ return;
+ }
+
+ printk(BIOS_DEBUG, "\n");
+
+ /* Dump and clear status registers */
+ clear_smi_status();
+ clear_pm1_status();
+ clear_tco_status();
+ clear_gpe_status();
+}
+
+void southbridge_smm_enable_smi(void)
+{
+ printk(BIOS_DEBUG, "Enabling SMIs.\n");
+ /* Configure events */
+ enable_pm1(PWRBTN_EN | GBL_EN);
+ disable_gpe(PME_B0_EN);
+
+ /*
+ * Enable SMI generation:
+ * - on APMC writes (io 0xb2)
+ * - on writes to SLP_EN (sleep states)
+ * - on writes to GBL_RLS (bios commands)
+ * No SMIs:
+ * - on microcontroller writes (io 0x62/0x66)
+ * - on TCO events
+ */
+ enable_smi(APMC_EN | SLP_SMI_EN | GBL_SMI_EN | EOS);
+}
+
+void southbridge_trigger_smi(void)
+{
+ /*
+ * There are several methods of raising a controlled SMI# via
+ * software, among them:
+ * - Writes to io 0xb2 (APMC)
+ * - Writes to the Local Apic ICR with Delivery mode SMI.
+ *
+ * Using the local apic is a bit more tricky. According to
+ * AMD Family 11 Processor BKDG no destination shorthand must be
+ * used.
+ * The whole SMM initialization is quite a bit hardware specific, so
+ * I'm not too worried about the better of the methods at the moment
+ */
+
+ /* raise an SMI interrupt */
+ printk(BIOS_SPEW, " ... raise SMI#\n");
+ outb(0x00, 0xb2);
+}
+
+void southbridge_clear_smi_status(void)
+{
+ /* Clear SMI status */
+ clear_smi_status();
+
+ /* Clear PM1 status */
+ clear_pm1_status();
+
+ /* Set EOS bit so other SMIs can occur. */
+ enable_smi(EOS);
+}
+
+void smm_setup_structures(void *gnvs, void *tcg, void *smi1)
+{
+ /*
+ * Issue SMI to set the gnvs pointer in SMM.
+ * tcg and smi1 are unused.
+ *
+ * EAX = APM_CNT_GNVS_UPDATE
+ * EBX = gnvs pointer
+ * EDX = APM_CNT
+ */
+ asm volatile (
+ "outb %%al, %%dx\n\t"
+ : /* ignore result */
+ : "a" (APM_CNT_GNVS_UPDATE),
+ "b" ((u32)gnvs),
+ "d" (APM_CNT)
+ );
+}
diff --git a/src/soc/intel/kabylake/smihandler.c b/src/soc/intel/kabylake/smihandler.c
new file mode 100644
index 0000000..68e86ba
--- /dev/null
+++ b/src/soc/intel/kabylake/smihandler.c
@@ -0,0 +1,517 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008-2009 coresystems GmbH
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <delay.h>
+#include <types.h>
+#include <arch/hlt.h>
+#include <arch/io.h>
+#include <console/console.h>
+#include <cpu/x86/cache.h>
+#include <device/pci_def.h>
+#include <cpu/x86/smm.h>
+#include <spi-generic.h>
+#include <elog.h>
+#include <pc80/mc146818rtc.h>
+#include <soc/iomap.h>
+#include <soc/lpc.h>
+#include <soc/nvs.h>
+#include <soc/pci_devs.h>
+#include <soc/pch.h>
+#include <soc/pcr.h>
+#include <soc/pm.h>
+#include <soc/pmc.h>
+#include <soc/smm.h>
+
+static u8 smm_initialized = 0;
+
+/*
+ * GNVS needs to be updated by an 0xEA PM Trap (B2) after it has been located
+ * by coreboot.
+ */
+static global_nvs_t *gnvs;
+global_nvs_t *smm_get_gnvs(void)
+{
+ return gnvs;
+}
+
+int southbridge_io_trap_handler(int smif)
+{
+ switch (smif) {
+ case 0x32:
+ printk(BIOS_DEBUG, "OS Init\n");
+ /*
+ * gnvs->smif:
+ * - On success, the IO Trap Handler returns 0
+ * - On failure, the IO Trap Handler returns a value != 0
+ */
+ gnvs->smif = 0;
+ return 1; /* IO trap handled */
+ }
+
+ /* Not handled */
+ return 0;
+}
+
+/* Set the EOS bit */
+void southbridge_smi_set_eos(void)
+{
+ enable_smi(EOS);
+}
+
+static void busmaster_disable_on_bus(int bus)
+{
+ int slot, func;
+ unsigned int val;
+ unsigned char hdr;
+
+ for (slot = 0; slot < 0x20; slot++) {
+ for (func = 0; func < 8; func++) {
+ u32 reg32;
+ device_t dev = PCI_DEV(bus, slot, func);
+
+ val = pci_read_config32(dev, PCI_VENDOR_ID);
+
+ if (val == 0xffffffff || val == 0x00000000 ||
+ val == 0x0000ffff || val == 0xffff0000)
+ continue;
+
+ /* Disable Bus Mastering for this one device */
+ reg32 = pci_read_config32(dev, PCI_COMMAND);
+ reg32 &= ~PCI_COMMAND_MASTER;
+ pci_write_config32(dev, PCI_COMMAND, reg32);
+
+ /* If this is a bridge, then follow it. */
+ hdr = pci_read_config8(dev, PCI_HEADER_TYPE);
+ hdr &= 0x7f;
+ if (hdr == PCI_HEADER_TYPE_BRIDGE ||
+ hdr == PCI_HEADER_TYPE_CARDBUS) {
+ unsigned int buses;
+ buses = pci_read_config32(dev, PCI_PRIMARY_BUS);
+ busmaster_disable_on_bus((buses >> 8) & 0xff);
+ }
+ }
+ }
+}
+
+
+static void southbridge_smi_sleep(void)
+{
+ u8 reg8;
+ u32 reg32;
+ u8 slp_typ;
+ u8 s5pwr = CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL;
+
+ /* save and recover RTC port values */
+ u8 tmp70, tmp72;
+ tmp70 = inb(0x70);
+ tmp72 = inb(0x72);
+ get_option(&s5pwr, "power_on_after_fail");
+ outb(tmp70, 0x70);
+ outb(tmp72, 0x72);
+
+ /* First, disable further SMIs */
+ disable_smi(SLP_SMI_EN);
+
+ /* Figure out SLP_TYP */
+ reg32 = inl(ACPI_BASE_ADDRESS + PM1_CNT);
+ printk(BIOS_SPEW, "SMI#: SLP = 0x%08x\n", reg32);
+ slp_typ = acpi_sleep_from_pm1(reg32);
+
+ /* Do any mainboard sleep handling */
+ mainboard_smi_sleep(slp_typ);
+
+ if (IS_ENABLED(CONFIG_ELOG_GSMI))
+ /* Log S3, S4, and S5 entry */
+ if (slp_typ >= ACPI_S3)
+ elog_add_event_byte(ELOG_TYPE_ACPI_ENTER, slp_typ);
+
+ /* Clear pending GPE events */
+ clear_gpe_status();
+
+ /* Next, do the deed. */
+ switch (slp_typ) {
+ case ACPI_S0:
+ printk(BIOS_DEBUG, "SMI#: Entering S0 (On)\n");
+ break;
+ case ACPI_S1:
+ printk(BIOS_DEBUG, "SMI#: Entering S1 (Assert STPCLK#)\n");
+ break;
+ case ACPI_S3:
+ printk(BIOS_DEBUG, "SMI#: Entering S3 (Suspend-To-RAM)\n");
+
+ /* Invalidate the cache before going to S3 */
+ wbinvd();
+ break;
+ case ACPI_S5:
+ printk(BIOS_DEBUG, "SMI#: Entering S5 (Soft Power off)\n");
+ /*TODO: cmos_layout.bin need to verify; cause wrong CMOS setup*/
+ s5pwr = MAINBOARD_POWER_ON;
+ /* Disable all GPE */
+ disable_all_gpe();
+
+ /*
+ * Always set the flag in case CMOS was changed on runtime. For
+ * "KEEP", switch to "OFF" - KEEP is software emulated
+ */
+ reg8 = pci_read_config8(PCH_DEV_PMC, GEN_PMCON_B);
+ if (s5pwr == MAINBOARD_POWER_ON)
+ reg8 &= ~1;
+ else
+ reg8 |= 1;
+ pci_write_config8(PCH_DEV_PMC, GEN_PMCON_B, reg8);
+
+ /* also iterates over all bridges on bus 0 */
+ busmaster_disable_on_bus(0);
+ break;
+ default:
+ printk(BIOS_DEBUG, "SMI#: ERROR: SLP_TYP reserved\n");
+ break;
+ }
+
+ /*
+ * Write back to the SLP register to cause the originally intended
+ * event again. We need to set BIT13 (SLP_EN) though to make the
+ * sleep happen.
+ */
+ enable_pm1_control(SLP_EN);
+
+ /* Make sure to stop executing code here for S3/S4/S5 */
+ if (slp_typ >= ACPI_S3)
+ hlt();
+
+ /*
+ * In most sleep states, the code flow of this function ends at
+ * the line above. However, if we entered sleep state S1 and wake
+ * up again, we will continue to execute code in this function.
+ */
+ reg32 = inl(ACPI_BASE_ADDRESS + PM1_CNT);
+ if (reg32 & SCI_EN) {
+ /* The OS is not an ACPI OS, so we set the state to S0 */
+ disable_pm1_control(SLP_EN | SLP_TYP);
+ }
+}
+
+/*
+ * Look for Synchronous IO SMI and use save state from that
+ * core in case we are not running on the same core that
+ * initiated the IO transaction.
+ */
+static em64t101_smm_state_save_area_t *smi_apmc_find_state_save(u8 cmd)
+{
+ em64t101_smm_state_save_area_t *state;
+ int node;
+
+ /* Check all nodes looking for the one that issued the IO */
+ for (node = 0; node < CONFIG_MAX_CPUS; node++) {
+ state = smm_get_save_state(node);
+
+ /* Check for Synchronous IO (bit0==1) */
+ if (!(state->io_misc_info & (1 << 0)))
+ continue;
+
+ /* Make sure it was a write (bit4==0) */
+ if (state->io_misc_info & (1 << 4))
+ continue;
+
+ /* Check for APMC IO port */
+ if (((state->io_misc_info >> 16) & 0xff) != APM_CNT)
+ continue;
+
+ /* Check AX against the requested command */
+ if ((state->rax & 0xff) != cmd)
+ continue;
+
+ return state;
+ }
+
+ return NULL;
+}
+
+static void southbridge_smi_gsmi(void)
+{
+#if IS_ENABLED(CONFIG_ELOG_GSMI)
+ u32 *ret, *param;
+ u8 sub_command;
+ em64t101_smm_state_save_area_t *io_smi =
+ smi_apmc_find_state_save(ELOG_GSMI_APM_CNT);
+
+ if (!io_smi)
+ return;
+
+ /* Command and return value in EAX */
+ ret = (u32 *)&io_smi->rax;
+ sub_command = (u8)(*ret >> 8);
+
+ /* Parameter buffer in EBX */
+ param = (u32 *)&io_smi->rbx;
+
+ /* drivers/elog/gsmi.c */
+ *ret = gsmi_exec(sub_command, param);
+#endif
+}
+
+static void finalize(void)
+{
+ static int finalize_done;
+
+ if (finalize_done) {
+ printk(BIOS_DEBUG, "SMM already finalized.\n");
+ return;
+ }
+ finalize_done = 1;
+
+ if (IS_ENABLED(CONFIG_SPI_FLASH_SMM))
+ /* Re-init SPI driver to handle locked BAR */
+ spi_init();
+}
+
+static void southbridge_smi_apmc(void)
+{
+ u8 reg8;
+ em64t101_smm_state_save_area_t *state;
+
+ /* Emulate B2 register as the FADT / Linux expects it */
+
+ reg8 = inb(APM_CNT);
+ switch (reg8) {
+ case APM_CNT_PST_CONTROL:
+ printk(BIOS_DEBUG, "P-state control\n");
+ break;
+ case APM_CNT_ACPI_DISABLE:
+ disable_pm1_control(SCI_EN);
+ printk(BIOS_DEBUG, "SMI#: ACPI disabled.\n");
+ break;
+ case APM_CNT_ACPI_ENABLE:
+ enable_pm1_control(SCI_EN);
+ printk(BIOS_DEBUG, "SMI#: ACPI enabled.\n");
+ break;
+ case APM_CNT_FINALIZE:
+ finalize();
+ break;
+ case APM_CNT_GNVS_UPDATE:
+ if (smm_initialized) {
+ printk(BIOS_DEBUG,
+ "SMI#: SMM structures already initialized!\n");
+ return;
+ }
+ state = smi_apmc_find_state_save(reg8);
+ if (state) {
+ /* EBX in the state save contains the GNVS pointer */
+ gnvs = (global_nvs_t *)((u32)state->rbx);
+ smm_initialized = 1;
+ printk(BIOS_DEBUG, "SMI#: Setting GNVS to %p\n", gnvs);
+ }
+ break;
+ case ELOG_GSMI_APM_CNT:
+ if (IS_ENABLED(CONFIG_ELOG_GSMI))
+ southbridge_smi_gsmi();
+ break;
+ }
+
+ mainboard_smi_apmc(reg8);
+}
+
+static void southbridge_smi_pm1(void)
+{
+ u16 pm1_sts = clear_pm1_status();
+
+ /*
+ * While OSPM is not active, poweroff immediately on a power button
+ * event.
+ */
+ if (pm1_sts & PWRBTN_STS) {
+ /* power button pressed */
+ if (IS_ENABLED(CONFIG_ELOG_GSMI))
+ elog_add_event(ELOG_TYPE_POWER_BUTTON);
+ disable_pm1_control(-1UL);
+ enable_pm1_control(SLP_EN | (SLP_TYP_S5 << 10));
+ }
+}
+
+static void southbridge_smi_gpe0(void)
+{
+ clear_gpe_status();
+}
+
+void __attribute__((weak))
+mainboard_smi_gpi_handler(const struct gpi_status *sts) { }
+
+static void southbridge_smi_gpi(void)
+{
+ struct gpi_status smi_sts;
+
+ gpi_clear_get_smi_status(&smi_sts);
+ mainboard_smi_gpi_handler(&smi_sts);
+
+ /* Clear again after mainboard handler */
+ gpi_clear_get_smi_status(&smi_sts);
+}
+
+static void southbridge_smi_mc(void)
+{
+ u32 reg32 = inl(ACPI_BASE_ADDRESS + SMI_EN);
+
+ /* Are microcontroller SMIs enabled? */
+ if ((reg32 & MCSMI_EN) == 0)
+ return;
+
+ printk(BIOS_DEBUG, "Microcontroller SMI.\n");
+}
+
+static void southbridge_smi_tco(void)
+{
+ u32 tco_sts = clear_tco_status();
+
+ /* Any TCO event? */
+ if (!tco_sts)
+ return;
+
+ if (tco_sts & (1 << 8)) { /* BIOSWR */
+ u8 bios_cntl = pci_read_config16(PCH_DEV_SPI, BIOS_CNTL);
+
+ if (bios_cntl & 1) {
+ /*
+ * BWE is RW, so the SMI was caused by a
+ * write to BWE, not by a write to the BIOS
+ *
+ * This is the place where we notice someone
+ * is trying to tinker with the BIOS. We are
+ * trying to be nice and just ignore it. A more
+ * resolute answer would be to power down the
+ * box.
+ */
+ printk(BIOS_DEBUG, "Switching back to RO\n");
+ pci_write_config32(PCH_DEV_SPI, BIOS_CNTL,
+ (bios_cntl & ~1));
+ } /* No else for now? */
+ } else if (tco_sts & (1 << 3)) { /* TIMEOUT */
+ /* Handle TCO timeout */
+ printk(BIOS_DEBUG, "TCO Timeout.\n");
+ }
+}
+
+static void southbridge_smi_periodic(void)
+{
+ u32 reg32 = inl(ACPI_BASE_ADDRESS + SMI_EN);
+
+ /* Are periodic SMIs enabled? */
+ if ((reg32 & PERIODIC_EN) == 0)
+ return;
+
+ printk(BIOS_DEBUG, "Periodic SMI.\n");
+}
+
+static void southbridge_smi_monitor(void)
+{
+#define IOTRAP(x) (trap_sts & (1 << x))
+ u32 trap_sts, trap_cycle;
+ u32 data, mask = 0;
+ int i;
+ /* TRSR - Trap Status Register */
+ pcr_read32(PID_PSTH, R_PCH_PCR_PSTH_TRPST, &trap_sts);
+ /* Clear trap(s) in TRSR */
+ pcr_write8(PID_PSTH, R_PCH_PCR_PSTH_TRPST, trap_sts);
+
+ /* TRPC - Trapped cycle */
+ pcr_read32(PID_PSTH, R_PCH_PCR_PSTH_TRPC, &trap_cycle);
+ for (i = 16; i < 20; i++) {
+ if (trap_cycle & (1 << i))
+ mask |= (0xff << ((i - 16) << 2));
+ }
+
+
+ /* IOTRAP(3) SMI function call */
+ if (IOTRAP(3)) {
+ if (gnvs && gnvs->smif)
+ io_trap_handler(gnvs->smif); /* call function smif */
+ return;
+ }
+
+ /*
+ * IOTRAP(2) currently unused
+ * IOTRAP(1) currently unused
+ */
+
+ /* IOTRAP(0) SMIC */
+ if (IOTRAP(0)) {
+ if (!(trap_cycle & (1 << 24))) { /* It's a write */
+ printk(BIOS_DEBUG, "SMI1 command\n");
+ /* Trapped write data */
+ pcr_read32(PID_PSTH, R_PCH_PCR_PSTH_TRPD, &data);
+ data &= mask;
+ }
+ }
+
+ printk(BIOS_DEBUG, " trapped io address = 0x%x\n",
+ trap_cycle & 0xfffc);
+ for (i = 0; i < 4; i++)
+ if (IOTRAP(i))
+ printk(BIOS_DEBUG, " TRAP = %d\n", i);
+ printk(BIOS_DEBUG, " AHBE = %x\n", (trap_cycle >> 16) & 0xf);
+ printk(BIOS_DEBUG, " MASK = 0x%08x\n", mask);
+ printk(BIOS_DEBUG, " read/write: %s\n",
+ (trap_cycle & (1 << 24)) ? "read" : "write");
+
+ if (!(trap_cycle & (1 << 24))) {
+ /* Write Cycle */
+ pcr_read32(PID_PSTH, R_PCH_PCR_PSTH_TRPD, &data);
+ printk(BIOS_DEBUG, " iotrap written data = 0x%08x\n", data);
+ }
+#undef IOTRAP
+}
+
+typedef void (*smi_handler_t)(void);
+
+static smi_handler_t southbridge_smi[SMI_STS_BITS] = {
+ [SMI_ON_SLP_EN_STS_BIT] = southbridge_smi_sleep,
+ [APM_STS_BIT] = southbridge_smi_apmc,
+ [PM1_STS_BIT] = southbridge_smi_pm1,
+ [GPE0_STS_BIT] = southbridge_smi_gpe0,
+ [GPIO_STS_BIT] = southbridge_smi_gpi,
+ [MCSMI_STS_BIT] = southbridge_smi_mc,
+ [TCO_STS_BIT] = southbridge_smi_tco,
+ [PERIODIC_STS_BIT] = southbridge_smi_periodic,
+ [MONITOR_STS_BIT] = southbridge_smi_monitor,
+};
+
+/*
+ * Interrupt handler for SMI#
+ */
+void southbridge_smi_handler(void)
+{
+ int i;
+ u32 smi_sts;
+
+ /*
+ * We need to clear the SMI status registers, or we won't see what's
+ * happening in the following calls.
+ */
+ smi_sts = clear_smi_status();
+
+ /* Call SMI sub handler for each of the status bits */
+ for (i = 0; i < ARRAY_SIZE(southbridge_smi); i++) {
+ if (smi_sts & (1 << i)) {
+ if (southbridge_smi[i]) {
+ southbridge_smi[i]();
+ } else {
+ printk(BIOS_DEBUG,
+ "SMI_STS[%d] occurred, but no handler available.\n",
+ i);
+ }
+ }
+ }
+}
diff --git a/src/soc/intel/kabylake/smmrelocate.c b/src/soc/intel/kabylake/smmrelocate.c
new file mode 100644
index 0000000..ae59c4f
--- /dev/null
+++ b/src/soc/intel/kabylake/smmrelocate.c
@@ -0,0 +1,317 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <types.h>
+#include <string.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <cpu/cpu.h>
+#include <cpu/x86/cache.h>
+#include <cpu/x86/lapic.h>
+#include <cpu/x86/mp.h>
+#include <cpu/x86/msr.h>
+#include <cpu/x86/mtrr.h>
+#include <cpu/x86/smm.h>
+#include <console/console.h>
+#include <soc/cpu.h>
+#include <soc/msr.h>
+#include <soc/pci_devs.h>
+#include <soc/smm.h>
+#include <soc/systemagent.h>
+#include "chip.h"
+
+/* This gets filled in and used during relocation. */
+static struct smm_relocation_params smm_reloc_params;
+
+static inline void write_smrr(struct smm_relocation_params *relo_params)
+{
+ printk(BIOS_DEBUG, "Writing SMRR. base = 0x%08x, mask=0x%08x\n",
+ relo_params->smrr_base.lo, relo_params->smrr_mask.lo);
+ wrmsr(SMRR_PHYS_BASE, relo_params->smrr_base);
+ wrmsr(SMRR_PHYS_MASK, relo_params->smrr_mask);
+}
+
+static inline void write_uncore_emrr(struct smm_relocation_params *relo_params)
+{
+ printk(BIOS_DEBUG,
+ "Writing UNCORE_EMRR. base = 0x%08x, mask=0x%08x\n",
+ relo_params->uncore_emrr_base.lo,
+ relo_params->uncore_emrr_mask.lo);
+ wrmsr(UNCORE_PRMRR_PHYS_BASE_MSR, relo_params->uncore_emrr_base);
+ wrmsr(UNCORE_PRMRR_PHYS_MASK_MSR, relo_params->uncore_emrr_mask);
+}
+
+static void update_save_state(int cpu, uintptr_t curr_smbase,
+ uintptr_t staggered_smbase,
+ struct smm_relocation_params *relo_params)
+{
+ u32 smbase;
+ u32 iedbase;
+
+ /*
+ * The relocated handler runs with all CPUs concurrently. Therefore
+ * stagger the entry points adjusting SMBASE downwards by save state
+ * size * CPU num.
+ */
+ smbase = staggered_smbase;
+ iedbase = relo_params->ied_base;
+
+ printk(BIOS_DEBUG, "New SMBASE=0x%08x IEDBASE=0x%08x\n",
+ smbase, iedbase);
+
+ /*
+ * All threads need to set IEDBASE and SMBASE to the relocated
+ * handler region. However, the save state location depends on the
+ * smm_save_state_in_msrs field in the relocation parameters. If
+ * smm_save_state_in_msrs is non-zero then the CPUs are relocating
+ * the SMM handler in parallel, and each CPUs save state area is
+ * located in their respective MSR space. If smm_save_state_in_msrs
+ * is zero then the SMM relocation is happening serially so the
+ * save state is at the same default location for all CPUs.
+ */
+ if (relo_params->smm_save_state_in_msrs) {
+ msr_t smbase_msr;
+ msr_t iedbase_msr;
+
+ smbase_msr.lo = smbase;
+ smbase_msr.hi = 0;
+
+ /*
+ * According the BWG the IEDBASE MSR is in bits 63:32. It's
+ * not clear why it differs from the SMBASE MSR.
+ */
+ iedbase_msr.lo = 0;
+ iedbase_msr.hi = iedbase;
+
+ wrmsr(SMBASE_MSR, smbase_msr);
+ wrmsr(IEDBASE_MSR, iedbase_msr);
+ } else {
+ em64t101_smm_state_save_area_t *save_state;
+
+ save_state = (void *)(curr_smbase + SMM_DEFAULT_SIZE -
+ sizeof(*save_state));
+
+ save_state->smbase = smbase;
+ save_state->iedbase = iedbase;
+ }
+}
+
+/* Returns 1 if SMM MSR save state was set. */
+static int bsp_setup_msr_save_state(struct smm_relocation_params *relo_params)
+{
+ msr_t smm_mca_cap;
+
+ smm_mca_cap = rdmsr(SMM_MCA_CAP_MSR);
+ if (smm_mca_cap.hi & SMM_CPU_SVRSTR_MASK) {
+ msr_t smm_feature_control;
+
+ smm_feature_control = rdmsr(SMM_FEATURE_CONTROL_MSR);
+ smm_feature_control.hi = 0;
+ smm_feature_control.lo |= SMM_CPU_SAVE_EN;
+ wrmsr(SMM_FEATURE_CONTROL_MSR, smm_feature_control);
+ relo_params->smm_save_state_in_msrs = 1;
+ }
+ return relo_params->smm_save_state_in_msrs;
+}
+
+/*
+ * The relocation work is actually performed in SMM context, but the code
+ * resides in the ramstage module. This occurs by trampolining from the default
+ * SMRAM entry point to here.
+ */
+void smm_relocation_handler(int cpu, uintptr_t curr_smbase,
+ uintptr_t staggered_smbase)
+{
+ msr_t mtrr_cap;
+ struct smm_relocation_params *relo_params = &smm_reloc_params;
+
+ printk(BIOS_DEBUG, "In relocation handler: cpu %d\n", cpu);
+
+ /*
+ * Determine if the processor supports saving state in MSRs. If so,
+ * enable it before the non-BSPs run so that SMM relocation can occur
+ * in parallel in the non-BSP CPUs.
+ */
+ if (cpu == 0) {
+ /*
+ * If smm_save_state_in_msrs is 1 then that means this is the
+ * 2nd time through the relocation handler for the BSP.
+ * Parallel SMM handler relocation is taking place. However,
+ * it is desired to access other CPUs save state in the real
+ * SMM handler. Therefore, disable the SMM save state in MSRs
+ * feature.
+ */
+ if (relo_params->smm_save_state_in_msrs) {
+ msr_t smm_feature_control;
+
+ smm_feature_control = rdmsr(SMM_FEATURE_CONTROL_MSR);
+ smm_feature_control.lo &= ~SMM_CPU_SAVE_EN;
+ wrmsr(SMM_FEATURE_CONTROL_MSR, smm_feature_control);
+ } else if (bsp_setup_msr_save_state(relo_params))
+ /*
+ * Just return from relocation handler if MSR save
+ * state is enabled. In that case the BSP will come
+ * back into the relocation handler to setup the new
+ * SMBASE as well disabling SMM save state in MSRs.
+ */
+ return;
+ }
+
+ /* Make appropriate changes to the save state map. */
+ update_save_state(cpu, curr_smbase, staggered_smbase, relo_params);
+
+ /* Write EMRR and SMRR MSRs based on indicated support. */
+ mtrr_cap = rdmsr(MTRR_CAP_MSR);
+ if (mtrr_cap.lo & SMRR_SUPPORTED)
+ write_smrr(relo_params);
+}
+
+static void fill_in_relocation_params(device_t dev,
+ struct smm_relocation_params *params)
+{
+ void *handler_base;
+ size_t handler_size;
+ void *ied_base;
+ size_t ied_size;
+ void *tseg_base;
+ size_t tseg_size;
+ u32 emrr_base;
+ u32 emrr_size;
+ int phys_bits;
+ /* All range registers are aligned to 4KiB */
+ const u32 rmask = ~((1 << 12) - 1);
+
+ /*
+ * Some of the range registers are dependent on the number of physical
+ * address bits supported.
+ */
+ phys_bits = cpuid_eax(0x80000008) & 0xff;
+
+ smm_region(&tseg_base, &tseg_size);
+ smm_subregion(SMM_SUBREGION_HANDLER, &handler_base, &handler_size);
+ smm_subregion(SMM_SUBREGION_CHIPSET, &ied_base, &ied_size);
+
+ params->smram_size = handler_size;
+ params->smram_base = (uintptr_t)handler_base;
+
+ params->ied_base = (uintptr_t)ied_base;
+ params->ied_size = ied_size;
+
+ /* SMRR has 32-bits of valid address aligned to 4KiB. */
+ params->smrr_base.lo = (params->smram_base & rmask) | MTRR_TYPE_WRBACK;
+ params->smrr_base.hi = 0;
+ params->smrr_mask.lo = (~(tseg_size - 1) & rmask) | MTRR_PHYS_MASK_VALID;
+ params->smrr_mask.hi = 0;
+
+ /* The EMRR and UNCORE_EMRR are at IEDBASE + 2MiB */
+ emrr_base = (params->ied_base + (2 << 20)) & rmask;
+ emrr_size = params->ied_size - (2 << 20);
+
+ /*
+ * EMRR has 46 bits of valid address aligned to 4KiB. It's dependent
+ * on the number of physical address bits supported.
+ */
+ params->emrr_base.lo = emrr_base | MTRR_TYPE_WRBACK;
+ params->emrr_base.hi = 0;
+ params->emrr_mask.lo = (~(emrr_size - 1) & rmask) | MTRR_PHYS_MASK_VALID;
+ params->emrr_mask.hi = (1 << (phys_bits - 32)) - 1;
+
+ /* UNCORE_EMRR has 39 bits of valid address aligned to 4KiB. */
+ params->uncore_emrr_base.lo = emrr_base;
+ params->uncore_emrr_base.hi = 0;
+ params->uncore_emrr_mask.lo = (~(emrr_size - 1) & rmask) |
+ MTRR_PHYS_MASK_VALID;
+ params->uncore_emrr_mask.hi = (1 << (39 - 32)) - 1;
+}
+
+static void setup_ied_area(struct smm_relocation_params *params)
+{
+ char *ied_base;
+
+ struct ied_header ied = {
+ .signature = "INTEL RSVD",
+ .size = params->ied_size,
+ .reserved = {0},
+ };
+
+ ied_base = (void *)params->ied_base;
+
+ printk(BIOS_DEBUG, "IED base = 0x%08x\n", params->ied_base);
+ printk(BIOS_DEBUG, "IED size = 0x%08x\n", params->ied_size);
+
+ /* Place IED header at IEDBASE. */
+ memcpy(ied_base, &ied, sizeof(ied));
+
+ /* Zero out 32KiB at IEDBASE + 1MiB */
+ memset(ied_base + (1 << 20), 0, (32 << 10));
+}
+
+void smm_info(uintptr_t *perm_smbase, size_t *perm_smsize,
+ size_t *smm_save_state_size)
+{
+ device_t dev = SA_DEV_ROOT;
+
+ printk(BIOS_DEBUG, "Setting up SMI for CPU\n");
+
+ fill_in_relocation_params(dev, &smm_reloc_params);
+
+ if (smm_reloc_params.ied_size)
+ setup_ied_area(&smm_reloc_params);
+
+ *perm_smbase = smm_reloc_params.smram_base;
+ *perm_smsize = smm_reloc_params.smram_size;
+ *smm_save_state_size = sizeof(em64t101_smm_state_save_area_t);
+}
+
+void smm_initialize(void)
+{
+ /* Clear the SMM state in the southbridge. */
+ southbridge_smm_clear_state();
+
+ /*
+ * Run the relocation handler for on the BSP to check and set up
+ * parallel SMM relocation.
+ */
+ smm_initiate_relocation();
+
+ if (smm_reloc_params.smm_save_state_in_msrs)
+ printk(BIOS_DEBUG, "Doing parallel SMM relocation.\n");
+}
+
+void smm_relocate(void)
+{
+ /*
+ * If smm_save_state_in_msrs is non-zero then parallel SMM relocation
+ * shall take place. Run the relocation handler a second time on the
+ * BSP to do * the final move. For APs, a relocation handler always
+ * needs to be run.
+ */
+ if (smm_reloc_params.smm_save_state_in_msrs)
+ smm_initiate_relocation_parallel();
+ else if (!boot_cpu())
+ smm_initiate_relocation();
+}
+
+void smm_lock(void)
+{
+ /*
+ * LOCK the SMM memory window and enable normal SMM.
+ * After running this function, only a full reset can
+ * make the SMM registers writable again.
+ */
+ printk(BIOS_DEBUG, "Locking SMM.\n");
+ pci_write_config8(SA_DEV_ROOT, SMRAM, D_LCK | G_SMRAME | C_BASE_SEG);
+}
diff --git a/src/soc/intel/kabylake/systemagent.c b/src/soc/intel/kabylake/systemagent.c
new file mode 100644
index 0000000..f4f7150
--- /dev/null
+++ b/src/soc/intel/kabylake/systemagent.c
@@ -0,0 +1,424 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <console/console.h>
+#include <arch/acpi.h>
+#include <arch/io.h>
+#include <stdint.h>
+#include <delay.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <stdlib.h>
+#include <string.h>
+#include <cbmem.h>
+#include <romstage_handoff.h>
+#include <vendorcode/google/chromeos/chromeos.h>
+#include <soc/cpu.h>
+#include <soc/iomap.h>
+#include <soc/pci_devs.h>
+#include <soc/ramstage.h>
+#include <soc/systemagent.h>
+
+u8 systemagent_revision(void)
+{
+ return pci_read_config8(SA_DEV_ROOT, PCI_REVISION_ID);
+}
+
+static int get_pcie_bar(device_t dev, unsigned int index, u32 *base, u32 *len)
+{
+ u32 pciexbar_reg;
+
+ *base = 0;
+ *len = 0;
+
+ pciexbar_reg = pci_read_config32(dev, index);
+
+ if (!(pciexbar_reg & (1 << 0)))
+ return 0;
+
+ switch ((pciexbar_reg >> 1) & 3) {
+ case 0: /* 256MB */
+ *base = pciexbar_reg & ((1 << 31)|(1 << 30)|(1 << 29)|
+ (1 << 28));
+ *len = 256 * 1024 * 1024;
+ return 1;
+ case 1: /* 128M */
+ *base = pciexbar_reg & ((1 << 31)|(1 << 30)|(1 << 29)|
+ (1 << 28)|(1 << 27));
+ *len = 128 * 1024 * 1024;
+ return 1;
+ case 2: /* 64M */
+ *base = pciexbar_reg & ((1 << 31)|(1 << 30)|(1 << 29)|
+ (1 << 28)|(1 << 27)|(1 << 26));
+ *len = 64 * 1024 * 1024;
+ return 1;
+ }
+
+ return 0;
+}
+
+static int get_bar(device_t dev, unsigned int index, u32 *base, u32 *len)
+{
+ u32 bar;
+
+ bar = pci_read_config32(dev, index);
+
+ /* If not enabled don't report it. */
+ if (!(bar & 0x1))
+ return 0;
+
+ /* Knock down the enable bit. */
+ *base = bar & ~1;
+
+ return 1;
+}
+
+/*
+ * There are special BARs that actually are programmed in the MCHBAR. These
+ * Intel special features, but they do consume resources that need to be
+ * accounted for.
+ */
+static int get_bar_in_mchbar(device_t dev, unsigned int index, u32 *base,
+ u32 *len)
+{
+ u32 bar;
+
+ bar = MCHBAR32(index);
+
+ /* If not enabled don't report it. */
+ if (!(bar & 0x1))
+ return 0;
+
+ /* Knock down the enable bit. */
+ *base = bar & ~1;
+
+ return 1;
+}
+
+struct fixed_mmio_descriptor {
+ unsigned int index;
+ u32 size;
+ int (*get_resource)(device_t dev, unsigned int index,
+ u32 *base, u32 *size);
+ const char *description;
+};
+
+struct fixed_mmio_descriptor mc_fixed_resources[] = {
+ { PCIEXBAR, 0, get_pcie_bar, "PCIEXBAR" },
+ { MCHBAR, MCH_BASE_SIZE, get_bar, "MCHBAR" },
+ { DMIBAR, DMI_BASE_SIZE, get_bar, "DMIBAR" },
+ { EPBAR, EP_BASE_SIZE, get_bar, "EPBAR" },
+ { GDXCBAR, GDXC_BASE_SIZE, get_bar_in_mchbar, "GDXCBAR" },
+ { EDRAMBAR, EDRAM_BASE_SIZE, get_bar_in_mchbar, "EDRAMBAR" },
+};
+
+/*
+ * Add all known fixed MMIO ranges that hang off the host bridge/memory
+ * controller device.
+ */
+static void mc_add_fixed_mmio_resources(device_t dev)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(mc_fixed_resources); i++) {
+ u32 base;
+ u32 size;
+ struct resource *resource;
+ unsigned int index;
+
+ size = mc_fixed_resources[i].size;
+ index = mc_fixed_resources[i].index;
+ if (!mc_fixed_resources[i].get_resource(dev, index,
+ &base, &size))
+ continue;
+
+ resource = new_resource(dev, mc_fixed_resources[i].index);
+ resource->flags = IORESOURCE_MEM | IORESOURCE_FIXED |
+ IORESOURCE_STORED | IORESOURCE_RESERVE |
+ IORESOURCE_ASSIGNED;
+ resource->base = base;
+ resource->size = size;
+ printk(BIOS_DEBUG, "%s: Adding %s @ %x 0x%08lx-0x%08lx.\n",
+ __func__, mc_fixed_resources[i].description, index,
+ (unsigned long)base, (unsigned long)(base + size - 1));
+ }
+}
+
+struct map_entry {
+ int reg;
+ int is_64_bit;
+ int is_limit;
+ const char *description;
+};
+
+static void read_map_entry(device_t dev, struct map_entry *entry,
+ uint64_t *result)
+{
+ uint64_t value;
+ uint64_t mask;
+
+ /* All registers are on a 1MiB granularity. */
+ mask = ((1ULL<<20)-1);
+ mask = ~mask;
+
+ value = 0;
+
+ if (entry->is_64_bit) {
+ value = pci_read_config32(dev, entry->reg + 4);
+ value <<= 32;
+ }
+
+ value |= (uint64_t) pci_read_config32(dev, entry->reg);
+ value &= mask;
+
+ if (entry->is_limit)
+ value |= ~mask;
+
+ *result = value;
+}
+
+#define MAP_ENTRY(reg_, is_64_, is_limit_, desc_) \
+ { \
+ .reg = reg_, \
+ .is_64_bit = is_64_, \
+ .is_limit = is_limit_, \
+ .description = desc_, \
+ }
+
+#define MAP_ENTRY_BASE_64(reg_, desc_) \
+ MAP_ENTRY(reg_, 1, 0, desc_)
+#define MAP_ENTRY_LIMIT_64(reg_, desc_) \
+ MAP_ENTRY(reg_, 1, 1, desc_)
+#define MAP_ENTRY_BASE_32(reg_, desc_) \
+ MAP_ENTRY(reg_, 0, 0, desc_)
+
+enum {
+ TOM_REG,
+ TOUUD_REG,
+ MESEG_BASE_REG,
+ MESEG_LIMIT_REG,
+ REMAP_BASE_REG,
+ REMAP_LIMIT_REG,
+ TOLUD_REG,
+ BGSM_REG,
+ BDSM_REG,
+ TSEG_REG,
+ /* Must be last. */
+ NUM_MAP_ENTRIES
+};
+
+static struct map_entry memory_map[NUM_MAP_ENTRIES] = {
+ [TOM_REG] = MAP_ENTRY_BASE_64(TOM, "TOM"),
+ [TOUUD_REG] = MAP_ENTRY_BASE_64(TOUUD, "TOUUD"),
+ [MESEG_BASE_REG] = MAP_ENTRY_BASE_64(MESEG_BASE, "MESEG_BASE"),
+ [MESEG_LIMIT_REG] = MAP_ENTRY_LIMIT_64(MESEG_LIMIT, "MESEG_LIMIT"),
+ [REMAP_BASE_REG] = MAP_ENTRY_BASE_64(REMAPBASE, "REMAP_BASE"),
+ [REMAP_LIMIT_REG] = MAP_ENTRY_LIMIT_64(REMAPLIMIT, "REMAP_LIMIT"),
+ [TOLUD_REG] = MAP_ENTRY_BASE_32(TOLUD, "TOLUD"),
+ [BDSM_REG] = MAP_ENTRY_BASE_32(BDSM, "BDSM"),
+ [BGSM_REG] = MAP_ENTRY_BASE_32(BGSM, "BGSM"),
+ [TSEG_REG] = MAP_ENTRY_BASE_32(TSEG, "TESGMB"),
+};
+
+static void mc_read_map_entries(device_t dev, uint64_t *values)
+{
+ int i;
+ for (i = 0; i < NUM_MAP_ENTRIES; i++)
+ read_map_entry(dev, &memory_map[i], &values[i]);
+}
+
+static void mc_report_map_entries(device_t dev, uint64_t *values)
+{
+ int i;
+ for (i = 0; i < NUM_MAP_ENTRIES; i++) {
+ printk(BIOS_DEBUG, "MC MAP: %s: 0x%llx\n",
+ memory_map[i].description, values[i]);
+ }
+ /* One can validate the BDSM and BGSM against the GGC. */
+ printk(BIOS_DEBUG, "MC MAP: GGC: 0x%x\n", pci_read_config16(dev, GGC));
+}
+
+static void mc_add_dram_resources(device_t dev)
+{
+ unsigned long base_k, size_k;
+ unsigned long touud_k;
+ unsigned long index;
+ struct resource *resource;
+ uint64_t mc_values[NUM_MAP_ENTRIES];
+ unsigned long dpr_size = 0;
+ u32 dpr_reg;
+
+ /* Read in the MAP registers and report their values. */
+ mc_read_map_entries(dev, &mc_values[0]);
+ mc_report_map_entries(dev, &mc_values[0]);
+
+ /*
+ * DMA Protected Range can be reserved below TSEG for PCODE patch
+ * or TXT/BootGuard related data. Rather than report a base address
+ * the DPR register reports the TOP of the region, which is the same
+ * as TSEG base. The region size is reported in MiB in bits 11:4.
+ */
+ dpr_reg = pci_read_config32(SA_DEV_ROOT, DPR);
+ if (dpr_reg & DPR_EPM) {
+ dpr_size = (dpr_reg & DPR_SIZE_MASK) << 16;
+ printk(BIOS_INFO, "DPR SIZE: 0x%lx\n", dpr_size);
+ }
+
+ /*
+ * These are the host memory ranges that should be added:
+ * - 0 -> 0xa0000: cacheable
+ * - 0xc0000 -> top_of_ram : cacheable
+ * - top_of_ram -> TSEG - DPR: uncacheable
+ * - TESG - DPR -> BGSM: cacheable with standard MTRRs and reserved
+ * - BGSM -> TOLUD: not cacheable with standard MTRRs and reserved
+ * - 4GiB -> TOUUD: cacheable
+ *
+ * The default SMRAM space is reserved so that the range doesn't
+ * have to be saved during S3 Resume. Once marked reserved the OS
+ * cannot use the memory. This is a bit of an odd place to reserve
+ * the region, but the CPU devices don't have dev_ops->read_resources()
+ * called on them.
+ *
+ * The range 0xa0000 -> 0xc0000 does not have any resources
+ * associated with it to handle legacy VGA memory. If this range
+ * is not omitted the mtrr code will setup the area as cacheable
+ * causing VGA access to not work.
+ *
+ * The TSEG region is mapped as cacheable so that one can perform
+ * SMRAM relocation faster. Once the SMRR is enabled the SMRR takes
+ * precedence over the existing MTRRs covering this region.
+ *
+ * It should be noted that cacheable entry types need to be added in
+ * order. The reason is that the current MTRR code assumes this and
+ * falls over itself if it isn't.
+ *
+ * The resource index starts low and should not meet or exceed
+ * PCI_BASE_ADDRESS_0.
+ */
+ index = 0;
+
+ /* 0 - > 0xa0000 */
+ base_k = 0;
+ size_k = (0xa0000 >> 10) - base_k;
+ ram_resource(dev, index++, base_k, size_k);
+
+ /* 0xc0000 -> top_of_ram */
+ base_k = 0xc0000 >> 10;
+ size_k = (top_of_32bit_ram() >> 10) - base_k;
+ ram_resource(dev, index++, base_k, size_k);
+
+ /* top_of_ram -> TSEG - DPR */
+ resource = new_resource(dev, index++);
+ resource->base = top_of_32bit_ram();
+ resource->size = mc_values[TSEG_REG] - dpr_size - resource->base;
+ resource->flags = IORESOURCE_MEM | IORESOURCE_FIXED |
+ IORESOURCE_STORED | IORESOURCE_RESERVE |
+ IORESOURCE_ASSIGNED;
+
+ /* TSEG - DPR -> BGSM */
+ resource = new_resource(dev, index++);
+ resource->base = mc_values[TSEG_REG] - dpr_size;
+ resource->size = mc_values[BGSM_REG] - resource->base;
+ resource->flags = IORESOURCE_MEM | IORESOURCE_FIXED |
+ IORESOURCE_STORED | IORESOURCE_RESERVE |
+ IORESOURCE_ASSIGNED | IORESOURCE_CACHEABLE;
+
+ /* BGSM -> TOLUD */
+ resource = new_resource(dev, index++);
+ resource->base = mc_values[BGSM_REG];
+ resource->size = mc_values[TOLUD_REG] - resource->base;
+ resource->flags = IORESOURCE_MEM | IORESOURCE_FIXED |
+ IORESOURCE_STORED | IORESOURCE_RESERVE |
+ IORESOURCE_ASSIGNED;
+
+ /* 4GiB -> TOUUD */
+ base_k = 4096 * 1024; /* 4GiB */
+ touud_k = mc_values[TOUUD_REG] >> 10;
+ size_k = touud_k - base_k;
+ if (touud_k > base_k)
+ ram_resource(dev, index++, base_k, size_k);
+
+ /*
+ * Reserve everything between A segment and 1MB:
+ *
+ * 0xa0000 - 0xbffff: legacy VGA
+ * 0xc0000 - 0xfffff: RAM
+ */
+ mmio_resource(dev, index++, (0xa0000 >> 10), (0xc0000 - 0xa0000) >> 10);
+ reserved_ram_resource(dev, index++, (0xc0000 >> 10),
+ (0x100000 - 0xc0000) >> 10);
+
+ chromeos_reserve_ram_oops(dev, index++);
+}
+
+static void systemagent_read_resources(device_t dev)
+{
+ /* Read standard PCI resources. */
+ pci_dev_read_resources(dev);
+
+ /* Add all fixed MMIO resources. */
+ mc_add_fixed_mmio_resources(dev);
+
+ /* Calculate and add DRAM resources. */
+ mc_add_dram_resources(dev);
+}
+
+static void systemagent_init(struct device *dev)
+{
+ u8 bios_reset_cpl, pair;
+
+ /* Enable Power Aware Interrupt Routing */
+ pair = MCHBAR8(MCH_PAIR);
+ pair &= ~0x7; /* Clear 2:0 */
+ pair |= 0x4; /* Fixed Priority */
+ MCHBAR8(MCH_PAIR) = pair;
+
+ /*
+ * Set bits 0+1 of BIOS_RESET_CPL to indicate to the CPU
+ * that BIOS has initialized memory and power management
+ */
+ bios_reset_cpl = MCHBAR8(BIOS_RESET_CPL);
+ bios_reset_cpl |= 3;
+ MCHBAR8(BIOS_RESET_CPL) = bios_reset_cpl;
+ printk(BIOS_DEBUG, "Set BIOS_RESET_CPL\n");
+
+ /* Configure turbo power limits 1ms after reset complete bit */
+ mdelay(1);
+ set_power_limits(28);
+}
+
+static struct device_operations systemagent_ops = {
+ .read_resources = &systemagent_read_resources,
+ .set_resources = &pci_dev_set_resources,
+ .enable_resources = &pci_dev_enable_resources,
+ .init = &systemagent_init,
+ .ops_pci = &soc_pci_ops,
+};
+
+static const unsigned short systemagent_ids[] = {
+ MCH_KABYLAKE_ID_U,
+ MCH_KABYLAKE_ID_Y,
+ MCH_KABYLAKE_ID_ULX,
+ 0
+};
+
+static const struct pci_driver systemagent_driver __pci_driver = {
+ .ops = &systemagent_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .devices = systemagent_ids
+};
diff --git a/src/soc/intel/kabylake/tsc_freq.c b/src/soc/intel/kabylake/tsc_freq.c
new file mode 100644
index 0000000..81ba8ba
--- /dev/null
+++ b/src/soc/intel/kabylake/tsc_freq.c
@@ -0,0 +1,29 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <stdint.h>
+#include <cpu/x86/msr.h>
+#include <cpu/x86/tsc.h>
+#include <soc/cpu.h>
+#include <soc/msr.h>
+
+unsigned long tsc_freq_mhz(void)
+{
+ msr_t platform_info;
+
+ platform_info = rdmsr(MSR_PLATFORM_INFO);
+ return CPU_BCLK * ((platform_info.lo >> 8) & 0xff);
+}
diff --git a/src/soc/intel/kabylake/uart.c b/src/soc/intel/kabylake/uart.c
new file mode 100644
index 0000000..4727a84
--- /dev/null
+++ b/src/soc/intel/kabylake/uart.c
@@ -0,0 +1,63 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <stdlib.h>
+#include <soc/iomap.h>
+#include <soc/pci_devs.h>
+#include <soc/ramstage.h>
+
+static int pch_uart_is_debug(struct device *dev)
+{
+ return dev->path.pci.devfn == PCH_DEVFN_UART2;
+}
+
+static void pch_uart_read_resources(struct device *dev)
+{
+ pci_dev_read_resources(dev);
+
+ /* Set the configured UART base address for the debug port */
+ if (IS_ENABLED(CONFIG_UART_DEBUG) && pch_uart_is_debug(dev)) {
+ struct resource *res = find_resource(dev, PCI_BASE_ADDRESS_0);
+ /* Need to set the base and size for the resource allocator. */
+ res->base = UART_DEBUG_BASE_ADDRESS;
+ res->size = UART_DEBUG_BASE_SIZE;
+ res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED |
+ IORESOURCE_FIXED;
+ }
+}
+
+static struct device_operations device_ops = {
+ .read_resources = &pch_uart_read_resources,
+ .set_resources = &pci_dev_set_resources,
+ .enable_resources = &pci_dev_enable_resources,
+ .ops_pci = &soc_pci_ops,
+};
+
+static const unsigned short pci_device_ids[] = {
+ 0x9d27, /* UART0 */
+ 0x9d28, /* UART1 */
+ 0x9d66, /* UART2 */
+ 0
+};
+
+static const struct pci_driver pch_uart __pci_driver = {
+ .ops = &device_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .devices = pci_device_ids,
+};
diff --git a/src/soc/intel/kabylake/uart_debug.c b/src/soc/intel/kabylake/uart_debug.c
new file mode 100644
index 0000000..f3d576b
--- /dev/null
+++ b/src/soc/intel/kabylake/uart_debug.c
@@ -0,0 +1,26 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2015 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <stddef.h>
+#include <console/uart.h>
+#include <soc/iomap.h>
+#include <soc/serialio.h>
+
+uintptr_t uart_platform_base(int idx)
+{
+ /* Same base address for all debug port usage. In reality UART2
+ * is currently only supported. */
+ return UART_DEBUG_BASE_ADDRESS;
+}
diff --git a/src/soc/intel/kabylake/vr_config.c b/src/soc/intel/kabylake/vr_config.c
new file mode 100644
index 0000000..40223e3
--- /dev/null
+++ b/src/soc/intel/kabylake/vr_config.c
@@ -0,0 +1,107 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2015 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <soc/vr_config.h>
+
+/* Default values for domain configuration. PSI3 and PSI4 are disabled. */
+static const struct vr_config default_configs[NUM_VR_DOMAINS] = {
+ [VR_SYSTEM_AGENT] = {
+ .vr_config_enable = 1,
+ .psi1threshold = VR_CFG_AMP(20),
+ .psi2threshold = VR_CFG_AMP(4),
+ .psi3threshold = VR_CFG_AMP(1),
+ .psi3enable = 0,
+ .psi4enable = 0,
+ .imon_slope = 0x0,
+ .imon_offset = 0x0,
+ .icc_max = VR_CFG_AMP(7),
+ .voltage_limit = 1520,
+ },
+ [VR_IA_CORE] = {
+ .vr_config_enable = 1,
+ .psi1threshold = VR_CFG_AMP(20),
+ .psi2threshold = VR_CFG_AMP(5),
+ .psi3threshold = VR_CFG_AMP(1),
+ .psi3enable = 0,
+ .psi4enable = 0,
+ .imon_slope = 0x0,
+ .imon_offset = 0x0,
+ .icc_max = VR_CFG_AMP(34),
+ .voltage_limit = 1520,
+ },
+ [VR_RING] = {
+ .vr_config_enable = 1,
+ .psi1threshold = VR_CFG_AMP(20),
+ .psi2threshold = VR_CFG_AMP(5),
+ .psi3threshold = VR_CFG_AMP(1),
+ .psi3enable = 0,
+ .psi4enable = 0,
+ .imon_slope = 0x0,
+ .imon_offset = 0x0,
+ .icc_max = VR_CFG_AMP(34),
+ .voltage_limit = 1520,
+ },
+ [VR_GT_UNSLICED] = {
+ .vr_config_enable = 1,
+ .psi1threshold = VR_CFG_AMP(20),
+ .psi2threshold = VR_CFG_AMP(5),
+ .psi3threshold = VR_CFG_AMP(1),
+ .psi3enable = 0,
+ .psi4enable = 0,
+ .imon_slope = 0x0,
+ .imon_offset = 0x0,
+ .icc_max = VR_CFG_AMP(35),
+ .voltage_limit = 1520,
+ },
+ [VR_GT_SLICED] = {
+ .vr_config_enable = 1,
+ .psi1threshold = VR_CFG_AMP(20),
+ .psi2threshold = VR_CFG_AMP(5),
+ .psi3threshold = VR_CFG_AMP(1),
+ .psi3enable = 0,
+ .psi4enable = 0,
+ .imon_slope = 0x0,
+ .imon_offset = 0x0,
+ .icc_max = VR_CFG_AMP(35),
+ .voltage_limit = 1520,
+ },
+};
+
+void fill_vr_domain_config(SILICON_INIT_UPD *params, int domain,
+ const struct vr_config *chip_cfg)
+{
+ const struct vr_config *cfg;
+
+ if (domain < 0 || domain >= NUM_VR_DOMAINS)
+ return;
+
+ /* Use device tree override if requested. */
+ if (chip_cfg->vr_config_enable)
+ cfg = chip_cfg;
+ else
+ cfg = &default_configs[domain];
+
+ params->VrConfigEnable[domain] = cfg->vr_config_enable;
+ params->Psi1Threshold[domain] = cfg->psi1threshold;
+ params->Psi2Threshold[domain] = cfg->psi2threshold;
+ params->Psi3Threshold[domain] = cfg->psi3threshold;
+ params->Psi3Enable[domain] = cfg->psi3enable;
+ params->Psi4Enable[domain] = cfg->psi4enable;
+ params->ImonSlope[domain] = cfg->imon_slope;
+ params->ImonOffset[domain] = cfg->imon_offset;
+ params->IccMax[domain] = cfg->icc_max;
+ params->VrVoltageLimit[domain] = cfg->voltage_limit;
+}
diff --git a/src/soc/intel/kabylake/xhci.c b/src/soc/intel/kabylake/xhci.c
new file mode 100644
index 0000000..1dd91eb
--- /dev/null
+++ b/src/soc/intel/kabylake/xhci.c
@@ -0,0 +1,43 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <console/console.h>
+#include <delay.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <arch/io.h>
+#include <soc/ramstage.h>
+#include <soc/xhci.h>
+#include <soc/cpu.h>
+
+static struct device_operations usb_xhci_ops = {
+ .read_resources = &pci_dev_read_resources,
+ .set_resources = &pci_dev_set_resources,
+ .enable_resources = &pci_dev_enable_resources,
+ .ops_pci = &soc_pci_ops,
+};
+
+static const unsigned short pci_device_ids[] = {
+ 0x9d2f, /* SunRisePoint LP */
+ 0
+};
+
+static const struct pci_driver pch_usb_xhci __pci_driver = {
+ .ops = &usb_xhci_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .devices = pci_device_ids,
+};
More information about the coreboot-gerrit
mailing list