xref: /aosp_15_r20/external/coreboot/src/security/intel/txt/getsec_enteraccs.S (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1/* SPDX-License-Identifier: GPL-2.0-only */
2
3#include <cpu/x86/mtrr.h>
4#include <cpu/x86/cr.h>
5#include <cpu/x86/msr.h>
6#include <arch/ram_segs.h>
7
8#include "getsec_mtrr_setup.inc"
9
10.macro PUSH_MSR x
11	movl	$(\x), %ecx
12	rdmsr
13	push	%eax
14	push	%edx
15.endm
16
17.macro POP_MSR x
18	movl	$(\x), %ecx
19	pop	%edx
20	pop	%eax
21	wrmsr
22.endm
23
24.macro CLEAR_MSR x
25	movl	$(\x), %ecx
26	xorl	%edx, %edx
27	xorl	%eax, %eax
28	wrmsr
29.endm
30
31.align 4
32.text
33
34/*
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
38 *
39 * void getsec_enteraccs(uint32_t esi,
40 *                       uint32_t acm_base,
41 *                       uint32_t acm_size);
42 */
43.global getsec_enteraccs
44getsec_enteraccs:
45
46	/* Backup current register state */
47	pushl	%ebp
48	movl	%esp, %ebp
49
50	pushal
51
52	movl	%cr0, %eax
53	pushl	%eax
54	movl	%cr4, %eax
55	pushl	%eax
56
57	/* Pushed 10 32bit registers */
58
59	/* Reserve space on stack for GDT */
60	subl	$8, %esp
61
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
74
75	/* Push variable MTRRs in ascending order */
76
77	xorl	%ebx, %ebx
78	jmp	cond_push_var_mtrrs
79
80body_push_var_mtrrs:
81
82	movl	%ebx, %ecx
83	shll	%ecx
84	addl	$(MTRR_PHYS_BASE(0)), %ecx
85	rdmsr
86	push	%eax
87	push	%edx
88	incl	%ecx	/* MTRR_PHYS_MASK */
89	rdmsr
90	push	%eax
91	push	%edx
92
93	incl	%ebx
94
95cond_push_var_mtrrs:
96
97	movl	$(MTRR_CAP_MSR), %ecx
98	rdmsr
99	andl	$(0xff), %eax
100	cmp	%ebx, %eax
101	jg	body_push_var_mtrrs
102
103	/*
104	 * Disable cache.
105	 * Chapter 2.2.4.3
106	 * Intel TXT Software Development Guide (Document: 315168-015)
107	 */
108	movl	%cr0, %eax
109	orl	$(CR0_CD | CR0_NW), %eax
110	movl	%eax, %cr0
111
112	/* Disable all MTRRs */
113	movl	$(MTRR_DEF_TYPE_MSR), %ecx
114	xorl	%eax, %eax
115	xorl	%edx, %edx
116	wrmsr
117
118	/*
119	 * Clear fixed MTRRs.
120	 * Chapter 2.2.5.1
121	 * Intel TXT Software Development Guide (Document: 315168-015)
122	 */
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
133
134	/*
135	 * Clear variable MTRRs
136	 * Chapter 2.2.5.1
137	 * Intel TXT Software Development Guide (Document: 315168-015)
138	 */
139	movl	$(MTRR_CAP_MSR), %ecx
140	rdmsr
141	andl	$(0xff), %eax
142	movl	%eax, %ebx
143
144	xorl	%eax, %eax
145	xorl	%edx, %edx
146
147	jmp	cond_clear_var_mtrrs
148
149body_clear_var_mtrrs:
150
151	decl	%ebx
152	movl	%ebx, %ecx
153	shll	%ecx
154	addl	$(MTRR_PHYS_BASE(0)), %ecx
155	wrmsr
156	incl	%ecx	/* MTRR_PHYS_MASK */
157	wrmsr
158
159cond_clear_var_mtrrs:
160
161	cmpl	$0, %ebx
162	jnz	body_clear_var_mtrrs
163
164	/*
165	 * Setup BIOS ACM as WB
166	 * Chapter A.1.1
167	 * Intel TXT Software Development Guide (Document: 315168-015)
168	 */
169
170	/* Determine size of AC module */
171	movl	12(%ebp), %eax			/* %eax = acmbase */
172	movl	$1, %ebx
173	movl	16(%ebp), %ebx			/* %ebx = acmsize */
174
175	/* Round up to page size */
176	addl	$(0xfff), %ebx
177	andl	$(~0xfff), %ebx			/* Aligned to a page (4 KiB) */
178
179	/*
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.
182	 */
183	movd	%eax, %xmm0			/* XMM0: Base address of next MTRR */
184	movd	%ebx, %xmm1			/* XMM1: Remaining size to cache */
185
186	/*
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.
190	 *
191	 * The caller must have checked that there are enough variable
192	 * MTRRs to cache the ACM size prior to invoking this routine.
193	 */
194	SET_UP_MTRRS_FOR_BIOS_ACM
195
196	/*
197	 * Now that the variable MTRRs have been set up, enable them.
198	 */
199	movl	$(MTRR_DEF_TYPE_MSR), %ecx
200	rdmsr
201	orl	$(MTRR_DEF_TYPE_EN), %eax
202	wrmsr
203
204	/* Enable cache - GPF# if not done */
205	movl	%cr0, %eax
206	andl	$(~(CR0_CD | CR0_NW)), %eax
207	movl	%eax, %cr0
208
209	/* Enable Numeric error - GPE# if not done */
210	movl	%cr0, %eax
211	orl	$(CR0_NE), %eax
212	movl	%eax, %cr0
213
214	/* Enable SMX and FXSTORE - for getsec */
215	movl	%cr4, %eax
216	orl	$(CR4_SMXE | CR4_OSFXSR), %eax
217	movl	%eax, %cr4
218
219	/*
220	 * Save GDT
221	 * Chapter A.1.2
222	 * Intel TXT Software Development Guide (Document: 315168-015)
223	 */
224	sgdt	-48(%ebp)
225
226	/* Backup stack pointer */
227	movd	%esp, %xmm0
228	movd	%ebp, %xmm1
229
230	/* Backup %gs used by cpu_info() */
231	movl	%gs, %eax
232	movd	%eax, %xmm2
233
234	/*
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
238	 * be power of two.
239	 *
240	 * The following assembly code is based on tboot's tboot/include/txt/smx.h.
241	 */
242	movl	8(%ebp), %esi	/* flags */
243	movl	12(%ebp), %ebx	/* acm_base */
244	movl	16(%ebp), %ecx	/* acm_size */
245
246	movl	$0, %edx	/* reserved, must be zero */
247	movl	$0, %edi	/* must be zero */
248	movl	$2, %eax	/* GetSec[ENTERACCS] */
249
250	getsec
251
252	/* Restore stack pointer */
253	movd	%xmm0, %esp
254	movd	%xmm1, %ebp
255
256	/* Reload GDT */
257	lgdt	-48(%ebp)
258
259	/* Set cs */
260	ljmp	$RAM_CODE_SEG, $1f
2611:
262	/* Fix segment registers */
263	movl	$RAM_DATA_SEG, %eax
264	movl	%eax, %ds
265	movl	%eax, %es
266	movl	%eax, %ss
267	movl	%eax, %fs
268	/* Restore %gs used by cpu_info */
269	movd	%xmm2, %eax
270	movl	%eax, %gs
271
272	/* Disable cache */
273	movl	%cr0, %eax
274	orl	$(CR0_CD | CR0_NW), %eax
275	movl	%eax, %cr0
276
277	/* Pop variable MTRRs in descending order */
278
279	movl	$(MTRR_CAP_MSR), %ecx
280	rdmsr
281	andl	$(0xff), %eax
282	movl	%eax, %ebx
283
284	jmp	cond_pop_var_mtrrs
285
286body_pop_var_mtrrs:
287
288	decl	%ebx
289	movl	%ebx, %ecx
290	shll	%ecx
291	addl	$(MTRR_PHYS_MASK(0)), %ecx
292	pop	%edx
293	pop	%eax
294	wrmsr
295	decl	%ecx	/* MTRR_PHYS_BASE */
296	pop	%edx
297	pop	%eax
298	wrmsr
299
300cond_pop_var_mtrrs:
301
302	cmpl	$0, %ebx
303	jne	body_pop_var_mtrrs
304
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
317
318	/* Enable cache */
319	movl	%cr0, %eax
320	andl	$(~(CR0_CD | CR0_NW)), %eax
321	movl	%eax, %cr0
322
323	/* Pop GDT */
324	addl	$8, %esp
325
326	popl	%eax
327	movl	%eax, %cr4
328	popl	%eax
329	movl	%eax, %cr0
330
331	popal
332
333	movl	%ebp, %esp
334	popl	%ebp
335
336	ret
337