sgx: Move SGX code to intel/common/block

CONFIG_SOC_INTEL_COMMON_BLOCK_SGX controls building. The SGX feature
is still enabled from devicetree.cb. As of now this SGX init supports
only KBL (SKL not tested). Support of SGX for new SOCs would be added
incrementally in this common code base.

Change-Id: I0fbba364b7342e686a2287ea1a910ef9a4eed595
Signed-off-by: Pratik Prajapati <pratikkumar.v.prajapati@intel.com>
Reviewed-on: https://review.coreboot.org/20173
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
diff --git a/src/soc/intel/skylake/Kconfig b/src/soc/intel/skylake/Kconfig
index 1dc8055..c558886 100644
--- a/src/soc/intel/skylake/Kconfig
+++ b/src/soc/intel/skylake/Kconfig
@@ -65,6 +65,7 @@
 	select SOC_INTEL_COMMON_BLOCK_SA
 	select SOC_INTEL_COMMON_BLOCK_SATA
 	select SOC_INTEL_COMMON_BLOCK_SCS
+	select SOC_INTEL_COMMON_BLOCK_SGX
 	select SOC_INTEL_COMMON_BLOCK_SMBUS
 	select SOC_INTEL_COMMON_BLOCK_TIMER
 	select SOC_INTEL_COMMON_BLOCK_UART
diff --git a/src/soc/intel/skylake/Makefile.inc b/src/soc/intel/skylake/Makefile.inc
index 75d57a9..0a8d105 100644
--- a/src/soc/intel/skylake/Makefile.inc
+++ b/src/soc/intel/skylake/Makefile.inc
@@ -63,7 +63,6 @@
 ramstage-y += pmutil.c
 ramstage-$(CONFIG_PLATFORM_USES_FSP2_0) += reset.c
 ramstage-y += sd.c
-ramstage-y += sgx.c
 ramstage-y += smi.c
 ramstage-y += smmrelocate.c
 ramstage-y += spi.c
diff --git a/src/soc/intel/skylake/cpu.c b/src/soc/intel/skylake/cpu.c
index e3be738..7f455e0 100644
--- a/src/soc/intel/skylake/cpu.c
+++ b/src/soc/intel/skylake/cpu.c
@@ -37,6 +37,7 @@
 #include <intelblocks/cpulib.h>
 #include <intelblocks/fast_spi.h>
 #include <intelblocks/mp_init.h>
+#include <intelblocks/sgx.h>
 #include <pc80/mc146818rtc.h>
 #include <soc/cpu.h>
 #include <soc/msr.h>
@@ -422,7 +423,7 @@
 	enable_turbo();
 
 	/* Configure SGX */
-	configure_sgx(microcode);
+	sgx_configure(microcode);
 }
 
 static int adjust_apic_id(int index, int apic_id)
@@ -489,7 +490,7 @@
 	 * here to get SGX enabled on BSP. This behavior needs to root-caused
 	 * and we shall not have this redundant call.
 	 */
-	configure_sgx(microcode);
+	sgx_configure(microcode);
 }
 
 int soc_skip_ucode_update(u32 current_patch_id, u32 new_patch_id)
@@ -514,3 +515,14 @@
 		return (msr1.lo & PRMRR_SUPPORTED) &&
 			(current_patch_id == new_patch_id - 1);
 }
+
+void cpu_lock_sgx_memory(void)
+{
+	msr_t msr;
+
+	msr = rdmsr(MSR_LT_LOCK_MEMORY);
+	if ((msr.lo & 1) == 0) {
+		msr.lo |= 1; /* Lock it */
+		wrmsr(MSR_LT_LOCK_MEMORY, msr);
+	}
+}
diff --git a/src/soc/intel/skylake/include/soc/cpu.h b/src/soc/intel/skylake/include/soc/cpu.h
index 059367a..8073fcd 100644
--- a/src/soc/intel/skylake/include/soc/cpu.h
+++ b/src/soc/intel/skylake/include/soc/cpu.h
@@ -56,6 +56,5 @@
 u32 cpu_family_model(void);
 u32 cpu_stepping(void);
 int cpu_is_ult(void);
-void configure_sgx(const void *microcode_patch);
 
 #endif
diff --git a/src/soc/intel/skylake/include/soc/msr.h b/src/soc/intel/skylake/include/soc/msr.h
index bb4b8e7..81b6cc9 100644
--- a/src/soc/intel/skylake/include/soc/msr.h
+++ b/src/soc/intel/skylake/include/soc/msr.h
@@ -20,7 +20,6 @@
 #include <intelblocks/msr.h>
 
 #define MSR_PIC_MSG_CONTROL		0x2e
-#define MSR_BIOS_UPGD_TRIG		0x7a
 #define MSR_EMULATE_PM_TIMER		0x121
 #define  EMULATE_PM_TMR_EN		(1 << 16)
 #define  EMULATE_DELAY_OFFSET_VALUE	20
@@ -31,11 +30,8 @@
 #define  ENERGY_POLICY_NORMAL		6
 #define  ENERGY_POLICY_POWERSAVE	15
 #define IA32_PACKAGE_THERM_INTERRUPT	0x1b2
-#define PRMRR_PHYS_BASE_MSR		0x1f4
 #define IA32_PLATFORM_DCA_CAP		0x1f8
 #define MSR_LT_LOCK_MEMORY		0x2e7
-#define MSR_SGX_OWNEREPOCH0		0x300
-#define MSR_SGX_OWNEREPOCH1		0x301
 #define MSR_VR_CURRENT_CONFIG		0x601
 #define MSR_VR_MISC_CONFIG		0x603
 #define MSR_VR_MISC_CONFIG2		0x636
diff --git a/src/soc/intel/skylake/sgx.c b/src/soc/intel/skylake/sgx.c
deleted file mode 100644
index 0e887de..0000000
--- a/src/soc/intel/skylake/sgx.c
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2017 Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#include <console/console.h>
-#include <chip.h>
-#include <cpu/x86/msr.h>
-#include <cpu/x86/mtrr.h>
-#include <cpu/intel/microcode.h>
-#include <soc/cpu.h>
-#include <soc/msr.h>
-#include <soc/pci_devs.h>
-
-static int is_sgx_supported(void)
-{
-	struct cpuid_result cpuid_regs;
-	msr_t msr;
-
-	cpuid_regs = cpuid_ext(0x7, 0x0); /* EBX[2] is feature capability */
-	msr = rdmsr(MTRR_CAP_MSR); /* Bit 12 is PRMRR enablement */
-	return ((cpuid_regs.ebx & 0x4) && (msr.lo & PRMRR_SUPPORTED));
-}
-
-static int configure_core_prmrr(void)
-{
-	msr_t prmrr_base;
-	msr_t prmrr_mask;
-	msr_t msr;
-
-	/*
-	 * PRMRR base and mask are read from the UNCORE PRMRR MSRs
-	 * that are already set in FSP-M.
-	 */
-	prmrr_base = rdmsr(UNCORE_PRMRR_PHYS_BASE_MSR);
-	prmrr_mask = rdmsr(UNCORE_PRMRR_PHYS_MASK_MSR);
-	if (!prmrr_base.lo) {
-		printk(BIOS_ERR, "SGX Error: Uncore PRMRR is not set!\n");
-		return -1;
-	}
-
-	msr = rdmsr(PRMRR_PHYS_MASK_MSR);
-	/* If it is locked don't attempt to write PRMRR MSRs. */
-	if (msr.lo & PRMRR_PHYS_MASK_LOCK)
-		return 0;
-
-	/* Program core PRMRR MSRs */
-	prmrr_base.lo |= 0x6; /* Set memory attribute to cache writeback */
-	wrmsr(PRMRR_PHYS_BASE_MSR, prmrr_base);
-	prmrr_mask.lo &= ~PRMRR_PHYS_MASK_VALID; /* Do not set the valid bit */
-	prmrr_mask.lo |= PRMRR_PHYS_MASK_LOCK; /* Lock it */
-	wrmsr(PRMRR_PHYS_MASK_MSR, prmrr_mask);
-	return 0;
-}
-
-static void enable_sgx(void)
-{
-	msr_t msr;
-
-	msr = rdmsr(IA32_FEATURE_CONTROL);
-	/* Only enable it when it is not locked */
-	if ((msr.lo & 1) == 0) {
-		msr.lo |= (1 << 18); /* Enable it */
-		wrmsr(IA32_FEATURE_CONTROL, msr);
-	}
-}
-
-static void lock_sgx(void)
-{
-	msr_t msr;
-
-	msr = rdmsr(IA32_FEATURE_CONTROL);
-	/* If it is locked don't attempt to lock it again. */
-	if ((msr.lo & 1) == 0) {
-		msr.lo |= 1; /* Lock it */
-		wrmsr(IA32_FEATURE_CONTROL, msr);
-	}
-}
-
-static int owner_epoch_update(void)
-{
-	/*
-	 * TODO - the Owner Epoch update mechanism is not determined yet,
-	 * for PoC just write '0's to the MSRs.
-	 */
-	msr_t msr = {0, 0};
-
-	wrmsr(MSR_SGX_OWNEREPOCH0, msr);
-	wrmsr(MSR_SGX_OWNEREPOCH1, msr);
-	return 0;
-}
-
-static void activate_sgx(void)
-{
-	msr_t msr;
-
-	/*
-	 * Activate SGX feature by writing 1b to MSR 0x7A on all threads.
-	 * BIOS must ensure bit 0 is set prior to writing to it, then read it
-	 * back and verify the bit is cleared to confirm SGX activation.
-	 */
-	msr = rdmsr(MSR_BIOS_UPGD_TRIG);
-	if (msr.lo & 0x1) {
-		wrmsr(MSR_BIOS_UPGD_TRIG, (msr_t) {.lo = 0x1, .hi = 0});
-		/* Read back to verify it is activated */
-		msr = rdmsr(MSR_BIOS_UPGD_TRIG);
-		if (msr.lo & 0x1)
-			printk(BIOS_ERR, "SGX activation failed.\n");
-		else
-			printk(BIOS_INFO, "SGX activation was successful.\n");
-	} else {
-		printk(BIOS_ERR, "SGX feature is deactivated.\n");
-	}
-}
-
-void configure_sgx(const void *microcode_patch)
-{
-	device_t dev = SA_DEV_ROOT;
-	config_t *conf = dev->chip_info;
-	msr_t msr;
-
-	if (!conf->sgx_enable || !is_sgx_supported())
-		return;
-
-	/* Initialize PRMRR core MSRs */
-	if (configure_core_prmrr() < 0)
-		return;
-
-	/* Enable the SGX feature */
-	enable_sgx();
-
-	/* Update the owner epoch value */
-	if (owner_epoch_update() < 0)
-		return;
-
-	/* Ensure to lock memory before reload microcode patch */
-	msr = rdmsr(MSR_LT_LOCK_MEMORY);
-	if ((msr.lo & 1) == 0) {
-		msr.lo |= 1; /* Lock it */
-		wrmsr(MSR_LT_LOCK_MEMORY, msr);
-	}
-
-	/* Reload the microcode patch */
-	intel_microcode_load_unlocked(microcode_patch);
-
-	/* Lock the SGX feature */
-	lock_sgx();
-
-	/* Activate the SGX feature */
-	activate_sgx();
-}