diff options
Diffstat (limited to 'src/soc/intel/common')
-rw-r--r-- | src/soc/intel/common/block/include/intelblocks/msr.h | 8 | ||||
-rw-r--r-- | src/soc/intel/common/block/include/intelblocks/sgx.h | 30 | ||||
-rw-r--r-- | src/soc/intel/common/block/sgx/Kconfig | 7 | ||||
-rw-r--r-- | src/soc/intel/common/block/sgx/Makefile.inc | 1 | ||||
-rw-r--r-- | src/soc/intel/common/block/sgx/sgx.c | 158 |
5 files changed, 204 insertions, 0 deletions
diff --git a/src/soc/intel/common/block/include/intelblocks/msr.h b/src/soc/intel/common/block/include/intelblocks/msr.h index 6d78ed8c2f..1025c28e92 100644 --- a/src/soc/intel/common/block/include/intelblocks/msr.h +++ b/src/soc/intel/common/block/include/intelblocks/msr.h @@ -18,8 +18,10 @@ #define MSR_CORE_THREAD_COUNT 0x35 #define IA32_FEATURE_CONTROL 0x3a +#define FEATURE_CONTROL_LOCK (1) #define CPUID_VMX (1 << 5) #define CPUID_SMX (1 << 6) +#define SGX_GLOBAL_ENABLE (1 << 18) #define PLATFORM_INFO_SET_TDP (1 << 29) #define MSR_PLATFORM_INFO 0xce #define MSR_PMG_CST_CONFIG_CONTROL 0xe2 @@ -31,6 +33,8 @@ #define IO_MWAIT_REDIRECT_MASK 0x400 /* Set MSR_PMG_CST_CONFIG_CONTROL[15] to lock CST_CFG [0-15] bits */ #define CST_CFG_LOCK_MASK 0x8000 +#define MSR_BIOS_UPGD_TRIG 0x7a +#define SGX_ACTIVATE_BIT (1) #define MSR_PMG_IO_CAPTURE_BASE 0xe4 #define MSR_POWER_MISC 0x120 #define ENABLE_IA_UNTRUSTED (1 << 6) @@ -62,6 +66,7 @@ #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 PRMRR_PHYS_BASE_MSR 0x1f4 #define PRMRR_PHYS_MASK_MSR 0x1f5 #define PRMRR_PHYS_MASK_LOCK (1 << 10) #define PRMRR_PHYS_MASK_VALID (1 << 11) @@ -69,6 +74,8 @@ #define MSR_EVICT_CTL 0x2e0 #define UNCORE_PRMRR_PHYS_BASE_MSR 0x2f4 #define UNCORE_PRMRR_PHYS_MASK_MSR 0x2f5 +#define MSR_SGX_OWNEREPOCH0 0x300 +#define MSR_SGX_OWNEREPOCH1 0x301 #define IA32_MC0_CTL 0x400 #define IA32_MC0_STATUS 0x401 #define SMM_FEATURE_CONTROL_MSR 0x4e0 @@ -124,5 +131,6 @@ #define SMRR_SUPPORTED (1<<11) #define PRMRR_SUPPORTED (1<<12) +#define SGX_SUPPORTED (1<<2) #endif /* SOC_INTEL_COMMON_MSR_H */ diff --git a/src/soc/intel/common/block/include/intelblocks/sgx.h b/src/soc/intel/common/block/include/intelblocks/sgx.h new file mode 100644 index 0000000000..03d4ab5123 --- /dev/null +++ b/src/soc/intel/common/block/include/intelblocks/sgx.h @@ -0,0 +1,30 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2017 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef SOC_INTEL_COMMON_BLOCK_SGX_H +#define SOC_INTEL_COMMON_BLOCK_SGX_H + +/* + * Lock SGX memory. + * CPU specific code needs to provide the implementation. + */ +void cpu_lock_sgx_memory(void); + +/* + * Configure SGX. + */ +void sgx_configure(const void *microcode_patch); + +#endif /* SOC_INTEL_COMMON_BLOCK_SGX_H */ diff --git a/src/soc/intel/common/block/sgx/Kconfig b/src/soc/intel/common/block/sgx/Kconfig new file mode 100644 index 0000000000..7889582007 --- /dev/null +++ b/src/soc/intel/common/block/sgx/Kconfig @@ -0,0 +1,7 @@ +config SOC_INTEL_COMMON_BLOCK_SGX + bool + default n + help + Software Guard eXtension(SGX) Feature. Intel SGX is a set of new CPU + instructions that can be used by applications to set aside privat + regions of code and data. diff --git a/src/soc/intel/common/block/sgx/Makefile.inc b/src/soc/intel/common/block/sgx/Makefile.inc new file mode 100644 index 0000000000..3fa18d8873 --- /dev/null +++ b/src/soc/intel/common/block/sgx/Makefile.inc @@ -0,0 +1 @@ +ramstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_SGX) += sgx.c diff --git a/src/soc/intel/common/block/sgx/sgx.c b/src/soc/intel/common/block/sgx/sgx.c new file mode 100644 index 0000000000..5a0b61dda6 --- /dev/null +++ b/src/soc/intel/common/block/sgx/sgx.c @@ -0,0 +1,158 @@ +/* + * 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 <intelblocks/sgx.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 & SGX_SUPPORTED) && (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 |= MTRR_TYPE_WRBACK; /* cache writeback mem attrib */ + 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 & FEATURE_CONTROL_LOCK) == 0) { + msr.lo |= SGX_GLOBAL_ENABLE; /* 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 & SGX_ACTIVATE_BIT) { + wrmsr(MSR_BIOS_UPGD_TRIG, + (msr_t) {.lo = SGX_ACTIVATE_BIT, .hi = 0}); + /* Read back to verify it is activated */ + msr = rdmsr(MSR_BIOS_UPGD_TRIG); + if (msr.lo & SGX_ACTIVATE_BIT) + 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 sgx_configure(const void *microcode_patch) +{ + device_t dev = SA_DEV_ROOT; + config_t *conf = dev->chip_info; + + 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 */ + cpu_lock_sgx_memory(); + + /* Reload the microcode patch */ + intel_microcode_load_unlocked(microcode_patch); + + /* Lock the SGX feature */ + lock_sgx(); + + /* Activate the SGX feature */ + activate_sgx(); +} |