1 /* SPDX-License-Identifier: GPL-2.0-only */
4 #include <console/console.h>
5 #include <cpu/x86/cr.h>
6 #include <cpu/x86/mp.h>
7 #include <cpu/x86/msr.h>
8 #include <cpu/x86/mtrr.h>
9 #include <device/mmio.h>
15 #if CONFIG(SOC_INTEL_COMMON_BLOCK_SA)
16 #include <soc/intel/common/reset.h>
18 #if CONFIG(SOUTHBRIDGE_INTEL_COMMON_ME)
19 #include <southbridge/intel/common/me.h>
21 #include <cf9_reset.h>
25 #include "txt_register.h"
26 #include "txt_getsec.h"
28 /* Usual security practice: if an unexpected error happens, reboot */
29 void __noreturn
txt_reset_platform(void)
31 #if CONFIG(SOC_INTEL_COMMON_BLOCK_SA)
34 #if CONFIG(SOUTHBRIDGE_INTEL_COMMON_ME)
42 * Dump the ACM error status bits.
44 * @param acm_error The status register to dump
45 * @return -1 on error (register is not valid)
46 * 0 on error (Class > 0 and Major > 0)
47 * 1 on success (Class == 0 and Major == 0 and progress > 0)
49 int intel_txt_log_acm_error(const uint32_t acm_error
)
51 if (!(acm_error
& ACMERROR_TXT_VALID
))
54 const uint8_t type
= (acm_error
& ACMERROR_TXT_TYPE_CODE
)
55 >> ACMERROR_TXT_TYPE_SHIFT
;
58 case ACMERROR_TXT_AC_MODULE_TYPE_BIOS
:
59 printk(BIOS_ERR
, "BIOSACM");
61 case ACMERROR_TXT_AC_MODULE_TYPE_SINIT
:
62 printk(BIOS_ERR
, "SINIT");
65 printk(BIOS_ERR
, "ACM");
68 printk(BIOS_ERR
, ": Error code valid\n");
70 if (acm_error
& ACMERROR_TXT_EXTERNAL
)
71 printk(BIOS_ERR
, " Caused by: External\n");
73 printk(BIOS_ERR
, " Caused by: Processor\n");
75 const uint32_t class = (acm_error
& ACMERROR_TXT_CLASS_CODE
)
76 >> ACMERROR_TXT_CLASS_SHIFT
;
77 const uint32_t major
= (acm_error
& ACMERROR_TXT_MAJOR_CODE
)
78 >> ACMERROR_TXT_MAJOR_SHIFT
;
79 const uint32_t minor
= (acm_error
& ACMERROR_TXT_MINOR_CODE
)
80 >> ACMERROR_TXT_MINOR_SHIFT
;
81 const uint32_t progress
= (acm_error
& ACMERROR_TXT_PROGRESS_CODE
)
82 >> ACMERROR_TXT_PROGRESS_SHIFT
;
85 if (class == 0 && major
== 0 && progress
> 0) {
86 printk(BIOS_ERR
, " Execution successful\n");
87 printk(BIOS_ERR
, " Progress code 0x%x\n", progress
);
89 printk(BIOS_ERR
, " Error Class: %x\n", class);
90 printk(BIOS_ERR
, " Error: %x.%x\n", major
, progress
);
93 printk(BIOS_ERR
, " ACM didn't start\n");
94 printk(BIOS_ERR
, " Error Type: 0x%x\n", acm_error
& 0xffffff);
98 return (acm_error
& ACMERROR_TXT_EXTERNAL
) && class == 0 && major
== 0 && progress
> 0;
101 void intel_txt_log_spad(void)
103 const uint64_t acm_status
= read64p(TXT_SPAD
);
105 printk(BIOS_INFO
, "TXT-STS: ACM verification ");
107 if (acm_status
& ACMSTS_VERIFICATION_ERROR
)
108 printk(BIOS_INFO
, "error\n");
110 printk(BIOS_INFO
, "successful\n");
112 printk(BIOS_INFO
, "TXT-STS: IBB ");
114 if (acm_status
& ACMSTS_IBB_MEASURED
)
115 printk(BIOS_INFO
, "measured\n");
117 printk(BIOS_INFO
, "not measured\n");
119 printk(BIOS_INFO
, "TXT-STS: TXT is ");
121 if (acm_status
& ACMSTS_TXT_DISABLED
)
122 printk(BIOS_INFO
, "disabled\n");
124 printk(BIOS_INFO
, "not disabled\n");
126 printk(BIOS_INFO
, "TXT-STS: BIOS is ");
128 if (acm_status
& ACMSTS_BIOS_TRUSTED
)
129 printk(BIOS_INFO
, "trusted\n");
131 printk(BIOS_INFO
, "not trusted\n");
134 /* Returns true if secrets might be in memory */
135 bool intel_txt_memory_has_secrets(void)
138 if (!CONFIG(INTEL_TXT
))
141 ret
= (read8p(TXT_ESTS
) & TXT_ESTS_WAKE_ERROR_STS
) ||
142 (read64p(TXT_E2STS
) & TXT_E2STS_SECRET_STS
);
145 printk(BIOS_CRIT
, "TXT-STS: Secrets in memory!\n");
149 bool intel_txt_chipset_is_production_fused(void)
152 * Certain chipsets report production fused information in either
153 * TXT.VER.FSBIF or TXT.VER.EMIF/TXT.VER.QPIIF.
154 * Chapter B.1.7 and B.1.9
155 * Intel TXT Software Development Guide (Document: 315168-015)
157 uint32_t reg
= read32p(TXT_VER_FSBIF
);
159 if (reg
== 0 || reg
== UINT32_MAX
)
160 reg
= read32p(TXT_VER_QPIIF
);
162 return (reg
& TXT_VER_PRODUCTION_FUSED
) ? true : false;
165 static struct acm_info_table
*find_info_table(const void *ptr
)
167 const struct acm_header_v0
*acm_header
= (struct acm_header_v0
*)ptr
;
169 return (struct acm_info_table
*)(ptr
+
170 (acm_header
->header_len
+ acm_header
->scratch_size
) * sizeof(uint32_t));
174 * Validate that the provided ACM is usable on this platform.
176 static int validate_acm(const void *ptr
)
178 const struct acm_header_v0
*acm_header
= (struct acm_header_v0
*)ptr
;
179 uint32_t max_size_acm_area
= 0;
181 if (acm_header
->module_type
!= CHIPSET_ACM
)
182 return ACM_E_TYPE_NOT_MATCH
;
184 /* Seems inconsistent across generations. */
185 if (acm_header
->module_sub_type
!= 0 && acm_header
->module_sub_type
!= 1)
186 return ACM_E_MODULE_SUB_TYPE_WRONG
;
188 if (acm_header
->module_vendor
!= INTEL_ACM_VENDOR
)
189 return ACM_E_MODULE_VENDOR_NOT_INTEL
;
191 if (acm_header
->size
== 0)
192 return ACM_E_SIZE_INCORRECT
;
194 if (((acm_header
->header_len
+ acm_header
->scratch_size
) * sizeof(uint32_t) +
195 sizeof(struct acm_info_table
)) > (acm_header
->size
& 0xffffff) * sizeof(uint32_t)) {
196 return ACM_E_SIZE_INCORRECT
;
199 if (!getsec_parameter(NULL
, NULL
, &max_size_acm_area
, NULL
, NULL
, NULL
))
200 return ACM_E_CANT_CALL_GETSEC
;
203 * Causes #GP if acm_header->size > processor internal authenticated
204 * code area capacity.
205 * SAFER MODE EXTENSIONS REFERENCE.
206 * Intel 64 and IA-32 Architectures Software Developer Manuals Vol 2D
208 const size_t acm_len
= 1UL << log2_ceil((acm_header
->size
& 0xffffff) << 2);
209 if (max_size_acm_area
< acm_len
) {
210 printk(BIOS_ERR
, "TEE-TXT: BIOS ACM doesn't fit into AC execution region\n");
211 return ACM_E_NOT_FIT_INTO_CPU_ACM_MEM
;
214 struct acm_info_table
*info
= find_info_table(ptr
);
216 return ACM_E_NO_INFO_TABLE
;
217 if (info
->chipset_acm_type
!= BIOS
)
218 return ACM_E_NOT_BIOS_ACM
;
220 static const u8 acm_uuid
[] = {
221 0xaa, 0x3a, 0xc0, 0x7f, 0xa7, 0x46, 0xdb, 0x18,
222 0x2e, 0xac, 0x69, 0x8f, 0x8d, 0x41, 0x7f, 0x5a,
224 if (memcmp(acm_uuid
, info
->uuid
, sizeof(acm_uuid
)) != 0)
225 return ACM_E_UUID_NOT_MATCH
;
227 const bool production_acm
= !(acm_header
->flags
& ACM_FORMAT_FLAGS_DEBUG
);
228 if (production_acm
!= intel_txt_chipset_is_production_fused())
229 return ACM_E_PLATFORM_IS_NOT_PROD
;
235 * Prepare to run the BIOS ACM: mmap it from the CBFS and verify that it
236 * can be launched. Returns pointer to ACM on success, NULL on failure.
238 static void *intel_txt_prepare_bios_acm(size_t *acm_len
)
240 void *acm_data
= NULL
;
245 acm_data
= cbfs_map(CONFIG_INTEL_TXT_CBFS_BIOS_ACM
, acm_len
);
247 printk(BIOS_ERR
, "TEE-TXT: Couldn't locate BIOS ACM in CBFS.\n");
252 * CPU enforces only 4KiB alignment.
254 * Intel TXT Software Development Guide (Document: 315168-015)
256 if (!IS_ALIGNED((uintptr_t)acm_data
, 4096)) {
257 printk(BIOS_ERR
, "TEE-TXT: BIOS ACM isn't mapped at page boundary.\n");
258 cbfs_unmap(acm_data
);
263 * Causes #GP if not multiple of 64.
264 * SAFER MODE EXTENSIONS REFERENCE.
265 * Intel 64 and IA-32 Architectures Software Developer Manuals Vol 2D
267 if (!IS_ALIGNED(*acm_len
, 64)) {
268 printk(BIOS_ERR
, "TEE-TXT: BIOS ACM size isn't multiple of 64.\n");
269 cbfs_unmap(acm_data
);
274 * The ACM should be aligned to it's size, but that's not possible, as
275 * some ACMs are not power of two. Use the next power of two for verification.
277 if (!IS_ALIGNED((uintptr_t)acm_data
, (1UL << log2_ceil(*acm_len
)))) {
278 printk(BIOS_ERR
, "TEE-TXT: BIOS ACM isn't aligned to its size.\n");
279 cbfs_unmap(acm_data
);
284 * When setting up the MTRRs to cache the BIOS ACM, one must cache less than
285 * a page (4 KiB) of unused memory after the BIOS ACM. On Haswell, failure
286 * to do so will cause a TXT reset with Class Code 5, Major Error Code 2.
288 if (popcnt(ALIGN_UP(*acm_len
, 4096)) > get_var_mtrr_count()) {
289 printk(BIOS_ERR
, "TEE-TXT: Not enough MTRRs to cache this BIOS ACM's size.\n");
290 cbfs_unmap(acm_data
);
294 if (CONFIG(INTEL_TXT_LOGGING
))
295 txt_dump_acm_info(acm_data
);
297 const int ret
= validate_acm(acm_data
);
299 printk(BIOS_ERR
, "TEE-TXT: Validation of ACM failed with: %d\n", ret
);
300 cbfs_unmap(acm_data
);
307 #define MCU_BASE_ADDR (TXT_BASE + 0x278)
308 #define BIOACM_ADDR (TXT_BASE + 0x27c)
309 #define APINIT_ADDR (TXT_BASE + 0x290)
310 #define SEMAPHORE (TXT_BASE + 0x294)
312 /* Returns on failure, resets the computer on success */
313 void intel_txt_run_sclean(void)
317 void *acm_data
= intel_txt_prepare_bios_acm(&acm_len
);
322 /* FIXME: Do we need to program these two? */
323 //write32p(MCU_BASE_ADDR, 0xffe1a990);
324 //write32p(APINIT_ADDR, 0xfffffff0);
326 write32p(BIOACM_ADDR
, (uintptr_t)acm_data
);
327 write32p(SEMAPHORE
, 0);
330 * The time SCLEAN will take depends on the installed RAM size.
331 * On Haswell with 8 GiB of DDR3, it takes five or ten minutes. (rough estimate)
333 printk(BIOS_ALERT
, "TEE-TXT: Invoking SCLEAN. This can take several minutes.\n");
336 * Invoke the BIOS ACM. If successful, the system will reset with memory unlocked.
338 getsec_sclean((uintptr_t)acm_data
, acm_len
);
341 * However, if this function returns, the BIOS ACM could not be invoked. This is bad.
343 printk(BIOS_CRIT
, "TEE-TXT: getsec_sclean could not launch the BIOS ACM.\n");
345 cbfs_unmap(acm_data
);
349 * Test all bits for TXT execution.
351 * @return 0 on success
353 int intel_txt_run_bios_acm(const u8 input_params
)
357 void *acm_data
= intel_txt_prepare_bios_acm(&acm_len
);
362 /* Call into assembly which invokes the referenced ACM */
363 getsec_enteraccs(input_params
, (uintptr_t)acm_data
, acm_len
);
365 cbfs_unmap(acm_data
);
367 const uint64_t acm_status
= read64p(TXT_SPAD
);
368 if (acm_status
& ACMERROR_TXT_VALID
) {
369 printk(BIOS_ERR
, "TEE-TXT: FATAL ACM launch error !\n");
372 * To clear TXT.BIOSACM.ERRORCODE you must issue a cold reboot!
374 intel_txt_log_acm_error(read32p(TXT_BIOSACM_ERRORCODE
));
381 /* Returns true if cond is not met */
382 static bool check_precondition(const int cond
)
384 printk(BIOS_DEBUG
, "%s\n", cond
? "true" : "false");
389 * Test all bits that are required for Intel TXT.
390 * Enable SMX if available.
392 * @return 0 on success
394 bool intel_txt_prepare_txt_env(void)
396 bool failure
= false;
397 uint32_t txt_feature_flags
= 0;
399 unsigned int ecx
= cpuid_ecx(1);
401 printk(BIOS_DEBUG
, "TEE-TXT: CPU supports SMX: ");
402 failure
|= check_precondition(ecx
& CPUID_SMX
);
404 printk(BIOS_DEBUG
, "TEE-TXT: CPU supports VMX: ");
405 failure
|= check_precondition(ecx
& CPUID_VMX
);
407 msr_t msr
= rdmsr(IA32_FEATURE_CONTROL
);
408 if (!(msr
.lo
& BIT(0))) {
409 printk(BIOS_ERR
, "TEE-TXT: IA32_FEATURE_CONTROL is not locked\n");
410 txt_reset_platform();
413 printk(BIOS_DEBUG
, "TEE-TXT: IA32_FEATURE_CONTROL\n");
414 printk(BIOS_DEBUG
, " VMXON in SMX enable: ");
415 failure
|= check_precondition(msr
.lo
& BIT(1));
417 printk(BIOS_DEBUG
, " VMXON outside SMX enable: ");
418 failure
|= check_precondition(msr
.lo
& FEATURE_ENABLE_VMX
);
420 printk(BIOS_DEBUG
, " register is locked: ");
421 failure
|= check_precondition(msr
.lo
& BIT(0));
423 /* IA32_FEATURE_CONTROL enables getsec instructions */
424 printk(BIOS_DEBUG
, " GETSEC (all instructions) is enabled: ");
425 failure
|= check_precondition((msr
.lo
& 0xff00) == 0xff00);
427 /* Prevent crash and opt out early */
433 * GetSec[CAPABILITIES]
434 * SAFER MODE EXTENSIONS REFERENCE.
435 * Intel 64 and IA-32 Architectures Software Developer Manuals Vol 2D
436 * Must check BIT0 of TXT chipset has been detected by CPU.
438 if (!getsec_capabilities(&eax
))
441 printk(BIOS_DEBUG
, "TEE-TXT: GETSEC[CAPABILITIES] returned:\n");
442 printk(BIOS_DEBUG
, " TXT capable chipset: %s\n", (eax
& BIT(0)) ? "true" : "false");
444 printk(BIOS_DEBUG
, " ENTERACCS available: %s\n", (eax
& BIT(2)) ? "true" : "false");
445 printk(BIOS_DEBUG
, " EXITAC available: %s\n", (eax
& BIT(3)) ? "true" : "false");
446 printk(BIOS_DEBUG
, " SENTER available: %s\n", (eax
& BIT(4)) ? "true" : "false");
447 printk(BIOS_DEBUG
, " SEXIT available: %s\n", (eax
& BIT(5)) ? "true" : "false");
448 printk(BIOS_DEBUG
, " PARAMETERS available: %s\n", (eax
& BIT(6)) ? "true" : "false");
449 printk(BIOS_DEBUG
, " SMCTRL available: %s\n", (eax
& BIT(7)) ? "true" : "false");
450 printk(BIOS_DEBUG
, " WAKEUP available: %s\n", (eax
& BIT(8)) ? "true" : "false");
452 txt_dump_getsec_parameters();
455 * Causes #GP if function is not supported by getsec.
456 * SAFER MODE EXTENSIONS REFERENCE.
457 * Intel 64 and IA-32 Architectures Software Developer Manuals Vol 2D
458 * Order Number: 325383-060US
460 if ((eax
& 0x7d) != 0x7d)
463 const uint64_t status
= read64p(TXT_SPAD
);
465 if (status
& ACMSTS_TXT_DISABLED
) {
466 printk(BIOS_INFO
, "TEE-TXT: TXT disabled by BIOS policy in FIT.\n");
471 * Only the BSP must call getsec[ENTERACCS].
472 * SAFER MODE EXTENSIONS REFERENCE.
473 * Intel 64 and IA-32 Architectures Software Developer Manuals Vol 2D
474 * Order Number: 325383-060US
477 printk(BIOS_ERR
, "TEE-TXT: BSP flag not set in APICBASE_MSR.\n");
482 * There must be no MCEs pending.
483 * Intel 64 and IA-32 Architectures Software Developer Manuals Vol 2D
484 * Order Number: 325383-060US
486 msr
= rdmsr(IA32_MCG_STATUS
);
488 printk(BIOS_ERR
, "TEE-TXT: IA32_MCG_STATUS.MCIP is set.\n");
492 if (!getsec_parameter(NULL
, NULL
, NULL
, NULL
, NULL
, &txt_feature_flags
))
495 printk(BIOS_DEBUG
, "TEE-TXT: Machine Check Register: ");
496 if (txt_feature_flags
& GETSEC_PARAMS_TXT_EXT_MACHINE_CHECK
)
497 printk(BIOS_DEBUG
, "preserved\n");
499 printk(BIOS_DEBUG
, "must be clear\n");
501 if (!(txt_feature_flags
& GETSEC_PARAMS_TXT_EXT_MACHINE_CHECK
)) {
503 * Make sure there are no uncorrectable MCE errors.
504 * Intel 64 and IA-32 Architectures Software Developer Manuals Vol 2D
506 size_t max_mc_msr
= mca_get_bank_count();
507 for (size_t i
= 0; i
< max_mc_msr
; i
++) {
508 msr
= rdmsr(IA32_MC_STATUS(i
));
509 if (!(msr
.hi
& MCA_STATUS_HI_UC
))
512 printk(BIOS_ERR
, "TEE-TXT: IA32_MC%zd_STATUS.UC is set.\n", i
);
518 /* Need to park all APs. */
519 if (CONFIG(PARALLEL_MP_AP_WORK
))