soc/intel/xeon_sp: Call SMM finalize

Call the SMM finalize SMI. Adds SMM_FEATURE_CONTROL setting to enable
MCHK on code fetch outside SMRR and the register lock as recommended
by the BWG.

Change-Id: Ie3b58d35c7a62509e39e393514012d1055232d32
Signed-off-by: Marc Jones <marcjones@sysproconsulting.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/51651
Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
Reviewed-by: Rocky Phagura
Reviewed-by: Jay Talbott <JayTalbott@sysproconsulting.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
diff --git a/src/soc/intel/xeon_sp/Makefile.inc b/src/soc/intel/xeon_sp/Makefile.inc
index b3d9390..768daaf 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 lockdown.c
+ramstage-y += memmap.c pch.c lockdown.c finalize.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/include/soc/pci_devs.h b/src/soc/intel/xeon_sp/cpx/include/soc/pci_devs.h
index f29991d..122a376 100644
--- a/src/soc/intel/xeon_sp/cpx/include/soc/pci_devs.h
+++ b/src/soc/intel/xeon_sp/cpx/include/soc/pci_devs.h
@@ -68,6 +68,23 @@
 #define PCU_CR3_CONFIG_TDP_CONTROL                         0x60
 #define TDP_LOCK                                           BIT(31)
 
+#if !defined(__SIMPLE_DEVICE__)
+#define _UBOX_DEV(func)		pcidev_path_on_root_debug(PCI_DEVFN(UBOX_DEV, func), __func__)
+#else
+#define _UBOX_DEV(func)		PCI_DEV(0, UBOX_DEV, func)
+#endif
+
+#define UBOX_DEV			8
+
+#define UBOX_PMON_BUS			0
+#define UBOX_PMON_DEV			8
+#define UBOX_PMON_FUNC			1
+#define UBOX_DEV_PMON			_UBOX_DEV(UBOX_PMON_FUNC)
+#define SMM_FEATURE_CONTROL		0x7c
+#define SMM_CODE_CHK_EN			BIT(2)
+#define SMM_FEATURE_CONTROL_LOCK	BIT(0)
+
+
 #define UBOX_DECS_BUS			0
 #define UBOX_DECS_DEV			8
 #define UBOX_DECS_FUNC			2
diff --git a/src/soc/intel/xeon_sp/finalize.c b/src/soc/intel/xeon_sp/finalize.c
new file mode 100644
index 0000000..bfcf212
--- /dev/null
+++ b/src/soc/intel/xeon_sp/finalize.c
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <bootstate.h>
+#include <console/console.h>
+#include <console/debug.h>
+#include <cpu/x86/smm.h>
+
+static void soc_finalize(void *unused)
+{
+	printk(BIOS_DEBUG, "Finalizing chipset.\n");
+
+	apm_control(APM_CNT_FINALIZE);
+
+	post_code(POST_OS_BOOT);
+}
+
+BOOT_STATE_INIT_ENTRY(BS_PAYLOAD_LOAD, BS_ON_ENTRY, soc_finalize, NULL);
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 525ec3c..c7af810 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
@@ -63,6 +63,22 @@
 #define PCU_CR1_DESIRED_CORES_CFG2_REG                     0xa0
 #define PCU_CR1_DESIRED_CORES_CFG2_REG_LOCK_MASK           BIT(31)
 
+#if !defined(__SIMPLE_DEVICE__)
+#define _UBOX_DEV(func)		pcidev_path_on_root_debug(PCI_DEVFN(UBOX_DEV, func), __func__)
+#else
+#define _UBOX_DEV(func)		PCI_DEV(0, UBOX_DEV, func)
+#endif
+
+#define UBOX_DEV			8
+
+#define UBOX_PMON_BUS			0
+#define UBOX_PMON_DEV			8
+#define UBOX_PMON_FUNC			1
+#define UBOX_DEV_PMON			_UBOX_DEV(UBOX_PMON_FUNC)
+#define SMM_FEATURE_CONTROL		0x7c
+#define SMM_CODE_CHK_EN			BIT(2)
+#define SMM_FEATURE_CONTROL_LOCK	BIT(0)
+
 #define UBOX_DECS_BUS			0
 #define UBOX_DECS_DEV			8
 #define UBOX_DECS_FUNC			2
diff --git a/src/soc/intel/xeon_sp/smihandler.c b/src/soc/intel/xeon_sp/smihandler.c
index db3b429..1c04b95 100644
--- a/src/soc/intel/xeon_sp/smihandler.c
+++ b/src/soc/intel/xeon_sp/smihandler.c
@@ -1,8 +1,24 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 
-#include <intelblocks/smihandler.h>
-#include <soc/pm.h>
+#include <console/console.h>
 #include <cpu/x86/smm.h>
+#include <device/pci.h>
+#include <intelblocks/smihandler.h>
+#include <soc/pci_devs.h>
+#include <soc/pm.h>
+
+/*
+ * Specific SOC SMI handler during ramstage finalize phase
+ */
+void smihandler_soc_at_finalize(void)
+{
+	/* SMM_FEATURE_CONTROL can only be written within SMM. */
+	printk(BIOS_DEBUG, "Lock SMM_FEATURE_CONTROL\n");
+	const pci_devfn_t dev = UBOX_DEV_PMON;
+	pci_or_config32(dev, SMM_FEATURE_CONTROL,
+			SMM_CODE_CHK_EN | SMM_FEATURE_CONTROL_LOCK);
+
+}
 
 /* This is needed by common SMM code */
 const smi_handler_t southbridge_smi[SMI_STS_BITS] = {