1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <cpu/x86/mtrr.h>
4 #include <cpu/x86/cr.h>
5 #include <cpu/x86/msr.h>
6 #include <arch/ram_segs.h>
8 #include "getsec_mtrr_setup.inc"
35 * See "SAFER MODE EXTENSIONS REFERENCE."
36 * Chapter "GETSEC[ENTERACCS] - Execute Authenticated Chipset Code" for reference.
37 * Intel 64 and IA-32 Architectures Software Developer Manuals Vol 2D
39 * void getsec_enteraccs(uint32_t esi,
43 .global getsec_enteraccs
46 /* Backup current register state */
57 /* Pushed 10 32bit registers */
59 /* Reserve space on stack for GDT */
62 PUSH_MSR MTRR_DEF_TYPE_MSR
63 PUSH_MSR IA32_MISC_ENABLE
64 PUSH_MSR MTRR_FIX_64K_00000
65 PUSH_MSR MTRR_FIX_16K_80000
66 PUSH_MSR MTRR_FIX_16K_A0000
67 PUSH_MSR MTRR_FIX_4K_C0000
68 PUSH_MSR MTRR_FIX_4K_C8000
69 PUSH_MSR MTRR_FIX_4K_D0000
70 PUSH_MSR MTRR_FIX_4K_D8000
71 PUSH_MSR MTRR_FIX_4K_E0000
72 PUSH_MSR MTRR_FIX_4K_F0000
73 PUSH_MSR MTRR_FIX_4K_F8000
75 /* Push variable MTRRs in ascending order */
78 jmp cond_push_var_mtrrs
84 addl $(MTRR_PHYS_BASE(0)), %ecx
88 incl %ecx /* MTRR_PHYS_MASK */
97 movl $(MTRR_CAP_MSR), %ecx
101 jg body_push_var_mtrrs
106 * Intel TXT Software Development Guide (Document: 315168-015)
109 orl $(CR0_CD | CR0_NW), %eax
112 /* Disable all MTRRs */
113 movl $(MTRR_DEF_TYPE_MSR), %ecx
121 * Intel TXT Software Development Guide (Document: 315168-015)
123 CLEAR_MSR MTRR_FIX_64K_00000
124 CLEAR_MSR MTRR_FIX_16K_80000
125 CLEAR_MSR MTRR_FIX_16K_A0000
126 CLEAR_MSR MTRR_FIX_4K_C0000
127 CLEAR_MSR MTRR_FIX_4K_C8000
128 CLEAR_MSR MTRR_FIX_4K_D0000
129 CLEAR_MSR MTRR_FIX_4K_D8000
130 CLEAR_MSR MTRR_FIX_4K_E0000
131 CLEAR_MSR MTRR_FIX_4K_F0000
132 CLEAR_MSR MTRR_FIX_4K_F8000
135 * Clear variable MTRRs
137 * Intel TXT Software Development Guide (Document: 315168-015)
139 movl $(MTRR_CAP_MSR), %ecx
147 jmp cond_clear_var_mtrrs
149 body_clear_var_mtrrs:
154 addl $(MTRR_PHYS_BASE(0)), %ecx
156 incl %ecx /* MTRR_PHYS_MASK */
159 cond_clear_var_mtrrs:
162 jnz body_clear_var_mtrrs
165 * Setup BIOS ACM as WB
167 * Intel TXT Software Development Guide (Document: 315168-015)
170 /* Determine size of AC module */
171 movl 12(%ebp), %eax /* %eax = acmbase */
173 movl 16(%ebp), %ebx /* %ebx = acmsize */
175 /* Round up to page size */
177 andl $(~0xfff), %ebx /* Aligned to a page (4 KiB) */
180 * Use XMM to store local variables. This code will need to be
181 * used in romstage, and CAR will have been torn down by then.
183 movd %eax, %xmm0 /* XMM0: Base address of next MTRR */
184 movd %ebx, %xmm1 /* XMM1: Remaining size to cache */
187 * Important note: The MTRRs must cache less than a page (4 KiB)
188 * of unused memory after the BIOS ACM. Failure to do so will
189 * result in a TXT reset with Class Code 5, Major Error Code 2.
191 * The caller must have checked that there are enough variable
192 * MTRRs to cache the ACM size prior to invoking this routine.
194 SET_UP_MTRRS_FOR_BIOS_ACM
197 * Now that the variable MTRRs have been set up, enable them.
199 movl $(MTRR_DEF_TYPE_MSR), %ecx
201 orl $(MTRR_DEF_TYPE_EN), %eax
204 /* Enable cache - GPF# if not done */
206 andl $(~(CR0_CD | CR0_NW)), %eax
209 /* Enable Numeric error - GPE# if not done */
214 /* Enable SMX and FXSTORE - for getsec */
216 orl $(CR4_SMXE | CR4_OSFXSR), %eax
222 * Intel TXT Software Development Guide (Document: 315168-015)
226 /* Backup stack pointer */
230 /* Backup %gs used by cpu_info() */
235 * Get function arguments.
236 * It's important to pass the exact ACM size as it's used by getsec to verify
237 * the integrity of ACM. Unlike the size for MTRR programming, which needs to
240 * The following assembly code is based on tboot's tboot/include/txt/smx.h.
242 movl 8(%ebp), %esi /* flags */
243 movl 12(%ebp), %ebx /* acm_base */
244 movl 16(%ebp), %ecx /* acm_size */
246 movl $0, %edx /* reserved, must be zero */
247 movl $0, %edi /* must be zero */
248 movl $2, %eax /* GetSec[ENTERACCS] */
252 /* Restore stack pointer */
260 ljmp $RAM_CODE_SEG, $1f
262 /* Fix segment registers */
263 movl $RAM_DATA_SEG, %eax
268 /* Restore %gs used by cpu_info */
274 orl $(CR0_CD | CR0_NW), %eax
277 /* Pop variable MTRRs in descending order */
279 movl $(MTRR_CAP_MSR), %ecx
284 jmp cond_pop_var_mtrrs
291 addl $(MTRR_PHYS_MASK(0)), %ecx
295 decl %ecx /* MTRR_PHYS_BASE */
303 jne body_pop_var_mtrrs
305 POP_MSR MTRR_FIX_4K_F8000
306 POP_MSR MTRR_FIX_4K_F0000
307 POP_MSR MTRR_FIX_4K_E0000
308 POP_MSR MTRR_FIX_4K_D8000
309 POP_MSR MTRR_FIX_4K_D0000
310 POP_MSR MTRR_FIX_4K_C8000
311 POP_MSR MTRR_FIX_4K_C0000
312 POP_MSR MTRR_FIX_16K_A0000
313 POP_MSR MTRR_FIX_16K_80000
314 POP_MSR MTRR_FIX_64K_00000
315 POP_MSR IA32_MISC_ENABLE
316 POP_MSR MTRR_DEF_TYPE_MSR
320 andl $(~(CR0_CD | CR0_NW)), %eax