drivers/wifi: Remove unnecessary data structure copy
[coreboot2.git] / src / security / intel / txt / getsec_enteraccs.S
blobff9db05f060879ad23518af20905e9416cf0cc64
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"
10 .macro PUSH_MSR x
11         movl    $(\x), %ecx
12         rdmsr
13         push    %eax
14         push    %edx
15 .endm
17 .macro POP_MSR x
18         movl    $(\x), %ecx
19         pop     %edx
20         pop     %eax
21         wrmsr
22 .endm
24 .macro CLEAR_MSR x
25         movl    $(\x), %ecx
26         xorl    %edx, %edx
27         xorl    %eax, %eax
28         wrmsr
29 .endm
31 .align 4
32 .text
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
44 getsec_enteraccs:
46         /* Backup current register state */
47         pushl   %ebp
48         movl    %esp, %ebp
50         pushal
52         movl    %cr0, %eax
53         pushl   %eax
54         movl    %cr4, %eax
55         pushl   %eax
57         /* Pushed 10 32bit registers */
59         /* Reserve space on stack for GDT */
60         subl    $8, %esp
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 */
77         xorl    %ebx, %ebx
78         jmp     cond_push_var_mtrrs
80 body_push_var_mtrrs:
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
93         incl    %ebx
95 cond_push_var_mtrrs:
97         movl    $(MTRR_CAP_MSR), %ecx
98         rdmsr
99         andl    $(0xff), %eax
100         cmp     %ebx, %eax
101         jg      body_push_var_mtrrs
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
112         /* Disable all MTRRs */
113         movl    $(MTRR_DEF_TYPE_MSR), %ecx
114         xorl    %eax, %eax
115         xorl    %edx, %edx
116         wrmsr
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
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
144         xorl    %eax, %eax
145         xorl    %edx, %edx
147         jmp     cond_clear_var_mtrrs
149 body_clear_var_mtrrs:
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
159 cond_clear_var_mtrrs:
161         cmpl    $0, %ebx
162         jnz     body_clear_var_mtrrs
164         /*
165          * Setup BIOS ACM as WB
166          * Chapter A.1.1
167          * Intel TXT Software Development Guide (Document: 315168-015)
168          */
170         /* Determine size of AC module */
171         movl    12(%ebp), %eax                  /* %eax = acmbase */
172         movl    $1, %ebx
173         movl    16(%ebp), %ebx                  /* %ebx = acmsize */
175         /* Round up to page size */
176         addl    $(0xfff), %ebx
177         andl    $(~0xfff), %ebx                 /* Aligned to a page (4 KiB) */
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 */
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
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
204         /* Enable cache - GPF# if not done */
205         movl    %cr0, %eax
206         andl    $(~(CR0_CD | CR0_NW)), %eax
207         movl    %eax, %cr0
209         /* Enable Numeric error - GPE# if not done */
210         movl    %cr0, %eax
211         orl     $(CR0_NE), %eax
212         movl    %eax, %cr0
214         /* Enable SMX and FXSTORE - for getsec */
215         movl    %cr4, %eax
216         orl     $(CR4_SMXE | CR4_OSFXSR), %eax
217         movl    %eax, %cr4
219         /*
220          * Save GDT
221          * Chapter A.1.2
222          * Intel TXT Software Development Guide (Document: 315168-015)
223          */
224         sgdt    -48(%ebp)
226         /* Backup stack pointer */
227         movd    %esp, %xmm0
228         movd    %ebp, %xmm1
230         /* Backup %gs used by cpu_info() */
231         movl    %gs, %eax
232         movd    %eax, %xmm2
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 */
246         movl    $0, %edx        /* reserved, must be zero */
247         movl    $0, %edi        /* must be zero */
248         movl    $2, %eax        /* GetSec[ENTERACCS] */
250         getsec
252         /* Restore stack pointer */
253         movd    %xmm0, %esp
254         movd    %xmm1, %ebp
256         /* Reload GDT */
257         lgdt    -48(%ebp)
259         /* Set cs */
260         ljmp    $RAM_CODE_SEG, $1f
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
272         /* Disable cache */
273         movl    %cr0, %eax
274         orl     $(CR0_CD | CR0_NW), %eax
275         movl    %eax, %cr0
277         /* Pop variable MTRRs in descending order */
279         movl    $(MTRR_CAP_MSR), %ecx
280         rdmsr
281         andl    $(0xff), %eax
282         movl    %eax, %ebx
284         jmp     cond_pop_var_mtrrs
286 body_pop_var_mtrrs:
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
300 cond_pop_var_mtrrs:
302         cmpl    $0, %ebx
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
318         /* Enable cache */
319         movl    %cr0, %eax
320         andl    $(~(CR0_CD | CR0_NW)), %eax
321         movl    %eax, %cr0
323         /* Pop GDT */
324         addl    $8, %esp
326         popl    %eax
327         movl    %eax, %cr4
328         popl    %eax
329         movl    %eax, %cr0
331         popal
333         movl    %ebp, %esp
334         popl    %ebp
336         ret