1 /* SPDX-License-Identifier: GPL-2.0-only */
4 #include <console/console.h>
5 #include <cpu/intel/common/common.h>
6 #include <cpu/x86/cr.h>
7 #include <cpu/x86/cache.h>
8 #include <cpu/x86/mp.h>
9 #include <cpu/x86/msr.h>
12 #include "txt_register.h"
13 #include "txt_getsec.h"
16 * Check for SMX support and enable it if possible.
18 * Returns false on error, true on success.
20 static bool getsec_enabled(void)
22 unsigned int ecx
= cpuid_ecx(1);
24 * Check if SMX and VMX is supported by CPU.
26 if (!(ecx
& CPUID_SMX
) || !(ecx
& CPUID_VMX
)) {
27 printk(BIOS_ERR
, "SMX/VMX not supported by CPU\n");
31 * This requirement is not needed for ENTERACCS, but for SENTER (see SDM).
32 * Skip check in romstage because IA32_FEATURE_CONTROL cannot be unlocked
33 * even after a global reset e.g. on Sandy/IvyBridge. However the register
34 * gets set properly in ramstage where all CPUs are already initialized.
36 if (!ENV_ROMSTAGE_OR_BEFORE
) {
38 * Check if SMX, VMX and GetSec instructions haven't been disabled.
40 msr_t msr
= rdmsr(IA32_FEATURE_CONTROL
);
41 if ((msr
.lo
& 0xff06) != 0xff06) {
42 printk(BIOS_ERR
, "GETSEC not enabled in IA32_FEATURE_CONTROL MSR\n");
47 * Enable SMX. Required to execute GetSec instruction.
49 * Intel TXT Software Development Guide (Document: 315168-015)
51 write_cr4(read_cr4() | CR4_SMXE
);
56 void enable_getsec_or_reset(void)
58 msr_t msr
= rdmsr(IA32_FEATURE_CONTROL
);
60 if (!(msr
.lo
& FEATURE_CONTROL_LOCK_BIT
)) {
62 * MSR not locked, enable necessary GETSEC and VMX settings.
63 * We do not lock this MSR here, though.
66 wrmsr(IA32_FEATURE_CONTROL
, msr
);
68 } else if ((msr
.lo
& 0xff06) != 0xff06) {
70 * MSR is locked without necessary GETSEC and VMX settings.
71 * This can happen after internally reflashing a coreboot
72 * image with different settings, and then doing a warm
73 * reboot. Perform a full reset in order to unlock the MSR.
76 "IA32_FEATURE_CONTROL MSR locked with GETSEC and/or VMX disabled.\n"
77 "Will perform a full reset to unlock this MSR.\n");
84 * Get information as returned by getsec[PARAMETER].
85 * Arguments can be set to NULL if not needed.
87 * Returns false on error, true on success.
89 bool getsec_parameter(uint32_t *version_mask
,
90 uint32_t *version_numbers_supported
,
91 uint32_t *max_size_acm_area
,
92 uint32_t *memory_type_mask
,
93 uint32_t *senter_function_disable
,
94 uint32_t *txt_feature_flags
)
96 uint32_t i
, eax
, ebx
, ecx
;
98 if (!getsec_enabled())
102 * SAFER MODE EXTENSIONS REFERENCE.
103 * Intel 64 and IA-32 Architectures Software Developer Manuals Vol 2D
105 for (i
= 0; i
< 0x1f; i
++) {
106 /* Getsec[PARAMETERS] */
107 asm volatile ("getsec\n"
108 : "=a" (eax
), "=b" (ebx
), "=c" (ecx
)
109 : "a" (IA32_GETSEC_PARAMETERS
), "b" (i
) :);
110 switch (eax
& 0x1f) {
111 case 0: /* NULL - Exit marker */
113 case 1: /* Supported AC module versions */
116 if (version_numbers_supported
)
117 *version_numbers_supported
= ecx
;
119 case 2: /* Max size of authenticated code execution area */
120 if (max_size_acm_area
)
121 *max_size_acm_area
= eax
& ~0x1f;
123 case 3: /* External memory types supported during AC mode */
124 if (memory_type_mask
)
125 *memory_type_mask
= eax
;
127 case 4: /* Selective SENTER functionality control */
128 if (senter_function_disable
)
129 *senter_function_disable
= eax
& (0x3f00);
131 case 5: /* TXT extensions support */
132 if (txt_feature_flags
)
133 *txt_feature_flags
= eax
& (0x60);
142 * Get capabilities as returned by getsec[CAPABILITIES].
144 * Returns false on error, true on success.
147 bool getsec_capabilities(uint32_t *eax
)
149 if (!getsec_enabled())
152 asm volatile ("getsec\n"
154 : "a" (IA32_GETSEC_CAPABILITIES
), "b" (0) :);