soc/intel/xeon_sp: Add PCH lockdown

Add SOC_INTEL_COMMON_PCH_LOCKDOWN and PMC_GLOBAL_RESET_ENABLE_LOCK
to meet device security requirements.

LOCKDOWN has dependencies on SOC_INTEL_COMMON_PCH_BASE and
several other common block devices. Add COMMON_PCH_BASE and
COMMON_PCH_SERVER to pick up LOCKDOWN and the dependencies.

COMMON_PCH_SERVER adds the following common devices that were not
previously included by XEON_SP:
SOC_INTEL_COMMON_BLOCK_CHIP_CONFIG
SOC_INTEL_COMMON_BLOCK_CSE
SOC_INTEL_COMMON_BLOCK_GPIO_ITSS_POL_CFG
SOC_INTEL_COMMON_BLOCK_ITSS
SOC_INTEL_COMMON_PCH_LOCKDOWN
SOC_INTEL_COMMON_BLOCK_SATA
SOC_INTEL_COMMON_BLOCK_SMBUS
SOC_INTEL_COMMON_BLOCK_XHCI

Change-Id: Iab97123e487f4f13f874f364a9c51723d234d4f0
Signed-off-by: Marc Jones <marcjones@sysproconsulting.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/49849
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Jay Talbott <JayTalbott@sysproconsulting.com>
Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
diff --git a/src/soc/intel/xeon_sp/Kconfig b/src/soc/intel/xeon_sp/Kconfig
index 929af13..44028be 100644
--- a/src/soc/intel/xeon_sp/Kconfig
+++ b/src/soc/intel/xeon_sp/Kconfig
@@ -36,26 +36,17 @@
 	select POSTCAR_STAGE
 	select IOAPIC
 	select PARALLEL_MP
+	select PMC_GLOBAL_RESET_ENABLE_LOCK
 	select INTEL_DESCRIPTOR_MODE_CAPABLE
 	select SOC_INTEL_COMMON_BLOCK
 	select SOC_INTEL_COMMON_BLOCK_CPU
-	select SOC_INTEL_COMMON_BLOCK_DMI
-	select SOC_INTEL_COMMON_BLOCK_TIMER
-	select SOC_INTEL_COMMON_BLOCK_LPC
-	select SOC_INTEL_COMMON_BLOCK_LPC_MIRROR_TO_DMI
-	select SOC_INTEL_COMMON_BLOCK_RTC
-	select SOC_INTEL_COMMON_BLOCK_SPI
-	select SOC_INTEL_COMMON_BLOCK_FAST_SPI
-	select SOC_INTEL_COMMON_BLOCK_GPIO
 	select SOC_INTEL_COMMON_BLOCK_GPIO_DUAL_ROUTE_SUPPORT
 	select SOC_INTEL_COMMON_BLOCK_GPIO_PADCFG_PADTOL
-	select SOC_INTEL_COMMON_BLOCK_PCR
-	select SOC_INTEL_COMMON_BLOCK_P2SB
-	select SOC_INTEL_COMMON_BLOCK_PMC
 	select SOC_INTEL_COMMON_BLOCK_PMC_DISCOVERABLE
 	select SOC_INTEL_COMMON_BLOCK_SMM
-	select SOC_INTEL_COMMON_BLOCK_TCO
 	select SOC_INTEL_COMMON_BLOCK_ACPI
+	select SOC_INTEL_COMMON_PCH_BASE
+	select SOC_INTEL_COMMON_PCH_SERVER
 	select TSC_MONOTONIC_TIMER
 	select TPM_STARTUP_IGNORE_POSTINIT if INTEL_TXT
 	select UDELAY_TSC
diff --git a/src/soc/intel/xeon_sp/Makefile.inc b/src/soc/intel/xeon_sp/Makefile.inc
index b9ce294..b3d9390 100644
--- a/src/soc/intel/xeon_sp/Makefile.inc
+++ b/src/soc/intel/xeon_sp/Makefile.inc
@@ -9,7 +9,7 @@
 romstage-y += romstage.c reset.c util.c spi.c gpio.c pmutil.c memmap.c
 romstage-y += ../../../cpu/intel/car/romstage.c
 ramstage-y += uncore.c reset.c util.c lpc.c spi.c gpio.c ramstage.c chip_common.c
-ramstage-y += memmap.c pch.c
+ramstage-y += memmap.c pch.c lockdown.c
 ramstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_PMC) += pmc.c
 ramstage-$(CONFIG_HAVE_ACPI_TABLES) += nb_acpi.c acpi.c
 ramstage-$(CONFIG_HAVE_SMI_HANDLER) += smmrelocate.c
diff --git a/src/soc/intel/xeon_sp/cpx/chip.c b/src/soc/intel/xeon_sp/cpx/chip.c
index 46cb7d0..0c71f22 100644
--- a/src/soc/intel/xeon_sp/cpx/chip.c
+++ b/src/soc/intel/xeon_sp/cpx/chip.c
@@ -5,6 +5,7 @@
 #include <console/debug.h>
 #include <cpu/x86/lapic.h>
 #include <device/pci.h>
+#include <intelblocks/acpi.h>
 #include <intelblocks/gpio.h>
 #include <intelblocks/lpc_lib.h>
 #include <intelblocks/p2sb.h>
@@ -25,7 +26,7 @@
 }
 
 #if CONFIG(HAVE_ACPI_TABLES)
-static const char *soc_acpi_name(const struct device *dev)
+const char *soc_acpi_name(const struct device *dev)
 {
 	if (dev->path.type == DEVICE_PATH_DOMAIN)
 		return "PC00";
diff --git a/src/soc/intel/xeon_sp/include/soc/iomap.h b/src/soc/intel/xeon_sp/include/soc/iomap.h
index a51b58c..2df5f8b 100644
--- a/src/soc/intel/xeon_sp/include/soc/iomap.h
+++ b/src/soc/intel/xeon_sp/include/soc/iomap.h
@@ -29,6 +29,8 @@
 /* High Performance Event Timer */
 #define HPET_BASE_ADDRESS            0xfed00000
 
+#define HECI1_BASE_ADDRESS	0xfed1a000
+
 #define PCH_PWRM_BASE_ADDRESS	0xfe000000
 #define PCH_PWRM_BASE_SIZE	0x10000
 
diff --git a/src/soc/intel/xeon_sp/include/soc/itss.h b/src/soc/intel/xeon_sp/include/soc/itss.h
new file mode 100644
index 0000000..770a7dd
--- /dev/null
+++ b/src/soc/intel/xeon_sp/include/soc/itss.h
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef SOC_INTEL_XEON_SP_ITSS_H
+#define SOC_INTEL_XEONS_P_ITSS_H
+
+#define ITSS_MAX_IRQ	119
+#define IRQS_PER_IPC	32
+#define NUM_IPC_REGS	((ITSS_MAX_IRQ + IRQS_PER_IPC - 1)/IRQS_PER_IPC)
+
+#endif	/* SOC_INTEL_XEON_SP_ITSS_H */
diff --git a/src/soc/intel/xeon_sp/include/soc/me.h b/src/soc/intel/xeon_sp/include/soc/me.h
new file mode 100644
index 0000000..e9791ec
--- /dev/null
+++ b/src/soc/intel/xeon_sp/include/soc/me.h
@@ -0,0 +1,64 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef _XEON_SP_ME_H_
+#define _XEON_SP_ME_H_
+
+/* ME Host Firmware Status register 1 */
+union me_hfsts1 {
+	u32 data;
+	struct {
+		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;
+	} __packed fields;
+};
+
+union me_hfsts2 {
+	u32 data;
+	struct {
+	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;
+	} __packed fields;
+};
+
+union me_hfsts3 {
+	u32 data;
+	struct {
+	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;
+	} __packed fields;
+};
+
+#endif
diff --git a/src/soc/intel/xeon_sp/include/soc/pmc.h b/src/soc/intel/xeon_sp/include/soc/pmc.h
index 40b41c7d..bbdb60b 100644
--- a/src/soc/intel/xeon_sp/include/soc/pmc.h
+++ b/src/soc/intel/xeon_sp/include/soc/pmc.h
@@ -34,6 +34,8 @@
 #define  SLEEP_AFTER_POWER_FAIL	(1 << 0)
 
 /* Memory mapped IO registers in PMC */
+#define PMSYNC_TPR_CFG		0xc8
+#define  PMSYNC_LOCK		(1 << 15)
 #define GPIO_GPE_CFG		0x120
 #define  GPE0_DWX_MASK		0xf
 #define GPE0_DW_SHIFT(x)	(4 * (x))
diff --git a/src/soc/intel/xeon_sp/lockdown.c b/src/soc/intel/xeon_sp/lockdown.c
new file mode 100644
index 0000000..2fa53c9
--- /dev/null
+++ b/src/soc/intel/xeon_sp/lockdown.c
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <device/mmio.h>
+#include <intelblocks/cfg.h>
+#include <intelblocks/lpc_lib.h>
+#include <intelblocks/pmclib.h>
+#include <intelpch/lockdown.h>
+#include <soc/pm.h>
+
+static void lpc_lockdown_config(int chipset_lockdown)
+{
+	/* Set BIOS Interface Lock, BIOS Lock */
+	if (chipset_lockdown == CHIPSET_LOCKDOWN_COREBOOT) {
+		lpc_set_bios_interface_lock_down();
+		lpc_set_lock_enable();
+	}
+}
+
+static void pmc_lockdown_config(void)
+{
+	uint8_t *pmcbase;
+	u32 pmsyncreg;
+
+	/* PMSYNC */
+	pmcbase = pmc_mmio_regs();
+	pmsyncreg = read32(pmcbase + PMSYNC_TPR_CFG);
+	pmsyncreg |= PMSYNC_LOCK;
+	write32(pmcbase + PMSYNC_TPR_CFG, pmsyncreg);
+
+	/* Make sure payload/OS can't trigger global reset */
+	pmc_global_reset_disable_and_lock();
+}
+
+void soc_lockdown_config(int chipset_lockdown)
+{
+	/* LPC lock down configuration */
+	lpc_lockdown_config(chipset_lockdown);
+
+	/* PMC lock down configuration */
+	pmc_lockdown_config();
+}
diff --git a/src/soc/intel/xeon_sp/skx/include/soc/pci_devs.h b/src/soc/intel/xeon_sp/skx/include/soc/pci_devs.h
index 39f6212..3d71045 100644
--- a/src/soc/intel/xeon_sp/skx/include/soc/pci_devs.h
+++ b/src/soc/intel/xeon_sp/skx/include/soc/pci_devs.h
@@ -123,6 +123,9 @@
 #define  XHCI_BUS_NUMBER        0x0
 #define  PCH_DEV_SLOT_XHCI      0x14
 #define  XHCI_FUNC_NUM          0x0
+#define  PCH_DEVFN_XHCI		_PCH_DEVFN(XHCI, 0)
+#define  PCH_DEV_XHCI		_PCH_DEV(XHCI, 0)
+#define   PCH_DEVFN_THERMAL	_PCH_DEVFN(XHCI, 2)
 
 #define HPET_BUS_NUM            0x0
 #define HPET_DEV_NUM            PCH_DEV_SLOT_LPC
@@ -139,6 +142,14 @@
 #define VTD_DEV(bus)		PCI_DEV((bus), VTD_DEV_NUM, VTD_FUNC_NUM)
 #endif
 
+#define PCH_DEV_SLOT_CSE	0x16
+#define  PCH_DEVFN_CSE		_PCH_DEVFN(CSE, 0)
+#define  PCH_DEVFN_CSE_2	_PCH_DEVFN(CSE, 1)
+#define  PCH_DEVFN_CSE_3	_PCH_DEVFN(CSE, 4)
+#define  PCH_DEV_CSE		_PCH_DEV(CSE, 0)
+#define  PCH_DEV_CSE_2		_PCH_DEV(CSE, 1)
+#define  PCH_DEV_CSE_3		_PCH_DEV(CSE, 4)
+
 #define PCH_DEV_SLOT_LPC        0x1f
 #define  PCH_DEVFN_LPC          _PCH_DEVFN(LPC, 0)
 #define  PCH_DEVFN_P2SB         _PCH_DEVFN(LPC, 1)