1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <cpu/x86/cr.h>
4 #include <cpu/x86/mtrr.h>
5 #include <cpu/x86/msr.h>
7 #include "getsec_mtrr_setup.inc"
9 #define NO_EVICT_MODE 0x2e0
15 * void getsec_sclean(const uint32_t acm_base, const uint32_t acm_size);
20 * At this point, it is certain that the BIOS ACM will be run.
21 * This requires tearing down CAR, which cannot be undone.
23 * From here onwards, the only way out is to reset the system.
26 /* Enable SMXE, SSE and debug extensions */
28 orl $(CR4_OSFXSR | CR4_DE | CR4_SMXE), %eax
32 * Save arguments into SSE registers. We need to tear down CAR
33 * before launching the BIOS ACM, which will destroy the stack.
35 movd 4(%esp), %xmm2 /* acm_base */
36 movd 8(%esp), %xmm3 /* acm_size */
40 orl $(CR0_CD | CR0_NE), %eax
41 andl $(~(CR0_NW)), %eax
44 /* Invalidate the cache */
48 movl $(MTRR_DEF_TYPE_MSR), %ecx
53 /* Disable NEM, needs to be done in two steps */
54 movl $NO_EVICT_MODE, %ecx
56 andl $~2, %eax /* Clear NEM Run bit */
58 andl $~1, %eax /* Clear NEM Setup bit */
61 /* Invalidate the cache, again */
65 * Clear variable MTRRs
67 * Intel TXT Software Development Guide (Document: 315168-015)
69 movl $(MTRR_CAP_MSR), %ecx
77 jmp cond_clear_var_mtrrs
84 addl $(MTRR_PHYS_BASE(0)), %ecx
86 incl %ecx /* MTRR_PHYS_MASK */
92 jnz body_clear_var_mtrrs
95 * Setup BIOS ACM as WB
97 * Intel TXT Software Development Guide (Document: 315168-015)
100 /* Determine size of AC module */
101 movd %xmm2, %eax /* acm_base */
102 movd %xmm3, %ebx /* acm_size */
104 /* Round up to page size */
106 andl $(~0xfff), %ebx /* Aligned to a page (4 KiB) */
108 /* Use SSE registers to store local variables */
113 * Important note: The MTRRs must cache less than a page (4 KiB)
114 * of unused memory after the BIOS ACM. Not doing so on Haswell
115 * will cause a TXT reset with Class Code 5, Major Error Code 2.
117 * The caller must have checked that there are enough variable
118 * MTRRs to cache the ACM size prior to invoking this routine.
120 SET_UP_MTRRS_FOR_BIOS_ACM
122 /* Enable variable MTRRs */
123 movl $MTRR_DEF_TYPE_MSR, %ecx
125 orl $MTRR_DEF_TYPE_EN, %eax
128 /* Enable cache - CR0_NW is and stays clear */
130 andl $~(CR0_CD), %eax
134 * Get function arguments.
135 * It's important to pass the exact ACM size as it's used by getsec to verify
136 * the integrity of ACM. Unlike the size for MTRR programming, which needs to
139 * Note: Do not forget that CAR has been torn down, so the stack doesn't exist.
141 movl $2, %eax /* GETSEC[ENTERACCS] */
142 movd %xmm2, %ebx /* acm_base */
143 movd %xmm3, %ecx /* acm_size */
144 movl $0, %edx /* reserved, must be zero */
145 movl $0, %edi /* must be zero */
146 movl $0, %esi /* SCLEAN */
151 * The platform state after SCLEAN is undefined. The only sane
152 * thing to do afterwards is to reset the platform. Note that
153 * the BIOS ACM should already reset the platform, so this code
154 * may not always be reached, but keep it here just to be sure.
158 movl $0x8000F8AC, %eax
163 andl $~(1 << 20), %eax