blob: 9f30b928462f3def50f348079a73e7831901225b [file] [log] [blame]
Angel Pons0612b272020-04-05 15:46:56 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Robbie Zhang7de03172017-02-21 14:00:31 -08002
3#include <console/console.h>
Robbie Zhang7de03172017-02-21 14:00:31 -08004#include <cpu/x86/msr.h>
5#include <cpu/x86/mtrr.h>
6#include <cpu/intel/microcode.h>
Patrick Rudolph05bad432019-09-26 10:30:22 +02007#include <cpu/intel/common/common.h>
Michael Niewöhnerc5fc7532019-09-22 21:56:17 +02008#include <intelblocks/cpulib.h>
Pratik Prajapatib45b22f2017-09-13 13:45:31 -07009#include <intelblocks/msr.h>
Pratik Prajapatia04aa3d2017-06-12 23:02:36 -070010#include <intelblocks/sgx.h>
Pratik Prajapati57c5af32017-08-28 15:21:52 -070011#include <intelblocks/systemagent.h>
Robbie Zhang7de03172017-02-21 14:00:31 -080012#include <soc/cpu.h>
Robbie Zhang7de03172017-02-21 14:00:31 -080013#include <soc/pci_devs.h>
Pratik Prajapatib45b22f2017-09-13 13:45:31 -070014
Pratik Prajapati53d68b42017-08-14 11:46:47 -070015void prmrr_core_configure(void)
Robbie Zhang7de03172017-02-21 14:00:31 -080016{
Arthur Heymans407e00d2022-10-19 20:06:42 +020017 msr_t prmrr_base, prmrr_mask;
Robbie Zhang7de03172017-02-21 14:00:31 -080018
Patrick Rudolph05bad432019-09-26 10:30:22 +020019 /*
20 * Software Developer's Manual Volume 4:
21 * Order Number: 335592-068US
22 * Chapter 2.16.1
23 * MSR_PRMRR_PHYS_MASK is in scope "Core"
24 * MSR_PRMRR_PHYS_BASE is in scope "Core"
25 * Return if Hyper-Threading is enabled and not thread 0
26 */
27 if (!is_sgx_supported() || intel_ht_sibling())
Pratik Prajapati53d68b42017-08-14 11:46:47 -070028 return;
29
Patrick Rudolph05bad432019-09-26 10:30:22 +020030 /* PRMRR_PHYS_MASK is in scope "Core" */
Arthur Heymans407e00d2022-10-19 20:06:42 +020031 prmrr_mask = rdmsr(MSR_PRMRR_PHYS_MASK);
Robbie Zhang7de03172017-02-21 14:00:31 -080032 /* If it is locked don't attempt to write PRMRR MSRs. */
Arthur Heymans407e00d2022-10-19 20:06:42 +020033 if (prmrr_mask.lo & PRMRR_PHYS_MASK_LOCK)
Pratik Prajapati53d68b42017-08-14 11:46:47 -070034 return;
Robbie Zhang7de03172017-02-21 14:00:31 -080035
Pratik Prajapati57c5af32017-08-28 15:21:52 -070036 /* PRMRR base and mask are read from the UNCORE PRMRR MSRs
37 * that are already set in FSP-M. */
Arthur Heymans407e00d2022-10-19 20:06:42 +020038 if (soc_get_uncore_prmmr_base_and_mask(&prmrr_base.raw,
39 &prmrr_mask.raw) < 0) {
Pratik Prajapati57c5af32017-08-28 15:21:52 -070040 printk(BIOS_ERR, "SGX: Failed to get PRMRR base and mask\n");
41 return;
42 }
43
Arthur Heymans407e00d2022-10-19 20:06:42 +020044 if (!prmrr_base.lo) {
Pratik Prajapati57c5af32017-08-28 15:21:52 -070045 printk(BIOS_ERR, "SGX Error: Uncore PRMRR is not set!\n");
46 return;
47 }
48
Arthur Heymans407e00d2022-10-19 20:06:42 +020049 printk(BIOS_INFO, "SGX: prmrr_base = 0x%llx\n", prmrr_base.raw);
50 printk(BIOS_INFO, "SGX: prmrr_mask = 0x%llx\n", prmrr_mask.raw);
Pratik Prajapati57c5af32017-08-28 15:21:52 -070051
52 /* Program core PRMRR MSRs.
53 * - Set cache writeback mem attrib in PRMRR base MSR
54 * - Clear the valid bit in PRMRR mask MSR
55 * - Lock PRMRR MASK MSR */
Arthur Heymans407e00d2022-10-19 20:06:42 +020056 prmrr_base.lo |= MTRR_TYPE_WRBACK;
57 wrmsr(MSR_PRMRR_PHYS_BASE, prmrr_base);
58 prmrr_mask.lo &= ~PRMRR_PHYS_MASK_VALID;
59 prmrr_mask.lo |= PRMRR_PHYS_MASK_LOCK;
60 wrmsr(MSR_PRMRR_PHYS_MASK, prmrr_mask);
Pratik Prajapati53d68b42017-08-14 11:46:47 -070061}
62
63static int is_prmrr_set(void)
64{
65 msr_t prmrr_base, prmrr_mask;
Elyes HAOUASf212cf32018-12-18 10:24:55 +010066 prmrr_base = rdmsr(MSR_PRMRR_PHYS_BASE);
67 prmrr_mask = rdmsr(MSR_PRMRR_PHYS_MASK);
Pratik Prajapati53d68b42017-08-14 11:46:47 -070068
69 /* If PRMRR base is zero and PRMRR mask is locked
70 * then PRMRR is not set */
71 if ((prmrr_base.hi == 0) && (prmrr_base.lo == 0)
72 && (prmrr_mask.lo & PRMRR_PHYS_MASK_LOCK))
73 return 0;
74 return 1;
Robbie Zhang7de03172017-02-21 14:00:31 -080075}
76
77static void enable_sgx(void)
78{
79 msr_t msr;
80
Patrick Rudolph05bad432019-09-26 10:30:22 +020081 /*
82 * Intel 64 and IA-32 ArchitecturesSoftware Developer's ManualVolume 3C
83 * Order Number: 326019-060US
84 * Chapter 35.10.2 "Additional MSRs Supported by Intel"
85 * IA32_FEATURE_CONTROL is in scope "Thread"
86 */
Robbie Zhang7de03172017-02-21 14:00:31 -080087 msr = rdmsr(IA32_FEATURE_CONTROL);
88 /* Only enable it when it is not locked */
Elyes HAOUAS419bfbc2018-10-01 08:47:51 +020089 if ((msr.lo & FEATURE_CONTROL_LOCK_BIT) == 0) {
Pratik Prajapatia04aa3d2017-06-12 23:02:36 -070090 msr.lo |= SGX_GLOBAL_ENABLE; /* Enable it */
Robbie Zhang7de03172017-02-21 14:00:31 -080091 wrmsr(IA32_FEATURE_CONTROL, msr);
92 }
93}
94
95static void lock_sgx(void)
96{
97 msr_t msr;
98
Patrick Rudolph05bad432019-09-26 10:30:22 +020099 /*
100 * Intel 64 and IA-32 ArchitecturesSoftware Developer's ManualVolume 3C
101 * Order Number: 326019-060US
102 * Chapter 35.10.2 "Additional MSRs Supported by Intel"
103 * IA32_FEATURE_CONTROL is in scope "Thread"
104 */
Robbie Zhang7de03172017-02-21 14:00:31 -0800105 msr = rdmsr(IA32_FEATURE_CONTROL);
106 /* If it is locked don't attempt to lock it again. */
107 if ((msr.lo & 1) == 0) {
108 msr.lo |= 1; /* Lock it */
109 wrmsr(IA32_FEATURE_CONTROL, msr);
110 }
111}
112
113static int owner_epoch_update(void)
114{
Pratik Prajapati53d68b42017-08-14 11:46:47 -0700115 /* TODO - the Owner Epoch update mechanism is not determined yet,
116 * for PoC just write '0's to the MSRs. */
Arthur Heymans407e00d2022-10-19 20:06:42 +0200117 msr_t msr = { .raw = 0 };
Robbie Zhang7de03172017-02-21 14:00:31 -0800118
Patrick Rudolph05bad432019-09-26 10:30:22 +0200119 /* SGX_OWNEREPOCH is in scope "Package" */
Robbie Zhang7de03172017-02-21 14:00:31 -0800120 wrmsr(MSR_SGX_OWNEREPOCH0, msr);
121 wrmsr(MSR_SGX_OWNEREPOCH1, msr);
122 return 0;
123}
124
125static void activate_sgx(void)
126{
127 msr_t msr;
128
Pratik Prajapati53d68b42017-08-14 11:46:47 -0700129 /* Activate SGX feature by writing 1b to MSR 0x7A on all threads.
Robbie Zhang7de03172017-02-21 14:00:31 -0800130 * BIOS must ensure bit 0 is set prior to writing to it, then read it
Pratik Prajapati53d68b42017-08-14 11:46:47 -0700131 * back and verify the bit is cleared to confirm SGX activation. */
Robbie Zhang7de03172017-02-21 14:00:31 -0800132 msr = rdmsr(MSR_BIOS_UPGD_TRIG);
Pratik Prajapatia04aa3d2017-06-12 23:02:36 -0700133 if (msr.lo & SGX_ACTIVATE_BIT) {
134 wrmsr(MSR_BIOS_UPGD_TRIG,
135 (msr_t) {.lo = SGX_ACTIVATE_BIT, .hi = 0});
Robbie Zhang7de03172017-02-21 14:00:31 -0800136 /* Read back to verify it is activated */
137 msr = rdmsr(MSR_BIOS_UPGD_TRIG);
Pratik Prajapatia04aa3d2017-06-12 23:02:36 -0700138 if (msr.lo & SGX_ACTIVATE_BIT)
Robbie Zhang7de03172017-02-21 14:00:31 -0800139 printk(BIOS_ERR, "SGX activation failed.\n");
140 else
141 printk(BIOS_INFO, "SGX activation was successful.\n");
142 } else {
143 printk(BIOS_ERR, "SGX feature is deactivated.\n");
144 }
145}
146
Pratik Prajapati53d68b42017-08-14 11:46:47 -0700147static int is_prmrr_approved(void)
148{
149 msr_t msr;
Elyes HAOUASf212cf32018-12-18 10:24:55 +0100150 msr = rdmsr(MSR_PRMRR_PHYS_MASK);
Pratik Prajapati53d68b42017-08-14 11:46:47 -0700151 if (msr.lo & PRMRR_PHYS_MASK_VALID) {
Jonathan Neuschäfer5268b762018-02-12 12:24:25 +0100152 printk(BIOS_INFO, "SGX: MCHECK approved SGX PRMRR\n");
Pratik Prajapati53d68b42017-08-14 11:46:47 -0700153 return 1;
154 }
155
Jonathan Neuschäfer5268b762018-02-12 12:24:25 +0100156 printk(BIOS_INFO, "SGX: MCHECK did not approve SGX PRMRR\n");
Pratik Prajapati53d68b42017-08-14 11:46:47 -0700157 return 0;
158}
159
Patrick Rudolph05bad432019-09-26 10:30:22 +0200160/*
161 * Configures SGX according to "Intel Software Guard Extensions Technology"
162 * Document Number: 565432
163 */
Subrata Banik33374972018-04-24 13:45:30 +0530164void sgx_configure(void *unused)
Robbie Zhang7de03172017-02-21 14:00:31 -0800165{
Michael Niewöhner6e66d7b2019-10-08 12:00:24 +0200166 if (!is_sgx_supported() || !is_prmrr_set()) {
Michael Niewöhner7736bfc2019-10-22 23:05:06 +0200167 printk(BIOS_ERR, "SGX: not supported or pre-conditions not met\n");
Robbie Zhang7de03172017-02-21 14:00:31 -0800168 return;
Pratik Prajapati53d68b42017-08-14 11:46:47 -0700169 }
Robbie Zhang7de03172017-02-21 14:00:31 -0800170
Patrick Rudolph05bad432019-09-26 10:30:22 +0200171 /* Enable the SGX feature on all threads. */
Robbie Zhang7de03172017-02-21 14:00:31 -0800172 enable_sgx();
173
174 /* Update the owner epoch value */
175 if (owner_epoch_update() < 0)
176 return;
177
Michael Niewöhner6e64c1a2020-08-05 21:36:11 +0200178 /* Ensure to lock memory before reloading microcode patch */
Michael Niewöhnerc5fc7532019-09-22 21:56:17 +0200179 if (CONFIG(SOC_INTEL_COMMON_BLOCK_SGX_LOCK_MEMORY))
Michael Niewöhner6e64c1a2020-08-05 21:36:11 +0200180 cpu_lt_lock_memory();
Robbie Zhang7de03172017-02-21 14:00:31 -0800181
Patrick Rudolph05bad432019-09-26 10:30:22 +0200182 /*
183 * Update just on the first CPU in the core. Other siblings
184 * get the update automatically according to Document: 253668-060US
185 * Intel SDM Chapter 9.11.6.3
186 * "Update in a System Supporting Intel Hyper-Threading Technology"
187 * Intel Hyper-Threading Technology has implications on the loading of the
188 * microcode update. The update must be loaded for each core in a physical
189 * processor. Thus, for a processor supporting Intel Hyper-Threading
190 * Technology, only one logical processor per core is required to load the
191 * microcode update. Each individual logical processor can independently
192 * load the update. However, MP initialization must provide some mechanism
193 * (e.g. a software semaphore) to force serialization of microcode update
194 * loads and to prevent simultaneous load attempts to the same core.
195 */
196 if (!intel_ht_sibling()) {
Patrick Rudolph3fa23b82021-01-25 09:42:08 +0100197 const void *microcode_patch = intel_microcode_find();
Patrick Rudolph05bad432019-09-26 10:30:22 +0200198 intel_microcode_load_unlocked(microcode_patch);
199 }
Robbie Zhang7de03172017-02-21 14:00:31 -0800200
Patrick Rudolph05bad432019-09-26 10:30:22 +0200201 /* Lock the SGX feature on all threads. */
Robbie Zhang7de03172017-02-21 14:00:31 -0800202 lock_sgx();
203
Jonathan Neuschäfer5268b762018-02-12 12:24:25 +0100204 /* Activate the SGX feature, if PRMRR config was approved by MCHECK */
Pratik Prajapati53d68b42017-08-14 11:46:47 -0700205 if (is_prmrr_approved())
206 activate_sgx();
Robbie Zhang7de03172017-02-21 14:00:31 -0800207}