drivers/wifi: Remove unnecessary data structure copy
[coreboot2.git] / src / security / intel / txt / getsec_sclean.S
blob0944e158e232d67252c2da569aa258386f37ebbb
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
11 .align 4
12 .text
15  * void getsec_sclean(const uint32_t acm_base, const uint32_t acm_size);
16  */
17 .global getsec_sclean
18 getsec_sclean:
19         /*
20          * At this point, it is certain that the BIOS ACM will be run.
21          * This requires tearing down CAR, which cannot be undone.
22          *
23          * From here onwards, the only way out is to reset the system.
24          */
26         /* Enable SMXE, SSE and debug extensions */
27         movl    %cr4, %eax
28         orl     $(CR4_OSFXSR | CR4_DE | CR4_SMXE), %eax
29         movl    %eax, %cr4
31         /*
32          * Save arguments into SSE registers. We need to tear down CAR
33          * before launching the BIOS ACM, which will destroy the stack.
34          */
35         movd    4(%esp), %xmm2                  /* acm_base */
36         movd    8(%esp), %xmm3                  /* acm_size */
38         /* Disable cache */
39         movl    %cr0, %eax
40         orl     $(CR0_CD | CR0_NE), %eax
41         andl    $(~(CR0_NW)), %eax
42         movl    %eax, %cr0
44         /* Invalidate the cache */
45         invd
47         /* Disable MTRRs */
48         movl    $(MTRR_DEF_TYPE_MSR), %ecx
49         xorl    %eax, %eax
50         xorl    %edx, %edx
51         wrmsr
53         /* Disable NEM, needs to be done in two steps */
54         movl    $NO_EVICT_MODE, %ecx
55         rdmsr
56         andl    $~2, %eax                       /* Clear NEM Run bit */
57         wrmsr
58         andl    $~1, %eax                       /* Clear NEM Setup bit */
59         wrmsr
61         /* Invalidate the cache, again */
62         invd
64         /*
65          * Clear variable MTRRs
66          * Chapter 2.2.5.1
67          * Intel TXT Software Development Guide (Document: 315168-015)
68          */
69         movl    $(MTRR_CAP_MSR), %ecx
70         rdmsr
71         andl    $(0xff), %eax
72         movl    %eax, %ebx
74         xorl    %eax, %eax
75         xorl    %edx, %edx
77         jmp     cond_clear_var_mtrrs
79 body_clear_var_mtrrs:
81         decl    %ebx
82         movl    %ebx, %ecx
83         shll    %ecx
84         addl    $(MTRR_PHYS_BASE(0)), %ecx
85         wrmsr
86         incl    %ecx                            /* MTRR_PHYS_MASK */
87         wrmsr
89 cond_clear_var_mtrrs:
91         cmpl    $0, %ebx
92         jnz     body_clear_var_mtrrs
94         /*
95          * Setup BIOS ACM as WB
96          * Chapter A.1.1
97          * Intel TXT Software Development Guide (Document: 315168-015)
98          */
100         /* Determine size of AC module */
101         movd    %xmm2, %eax                     /* acm_base */
102         movd    %xmm3, %ebx                     /* acm_size */
104         /* Round up to page size */
105         addl    $(0xfff), %ebx
106         andl    $(~0xfff), %ebx                 /* Aligned to a page (4 KiB) */
108         /* Use SSE registers to store local variables */
109         movd    %eax, %xmm0
110         movd    %ebx, %xmm1
112         /*
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.
116          *
117          * The caller must have checked that there are enough variable
118          * MTRRs to cache the ACM size prior to invoking this routine.
119          */
120         SET_UP_MTRRS_FOR_BIOS_ACM
122         /* Enable variable MTRRs */
123         movl    $MTRR_DEF_TYPE_MSR, %ecx
124         rdmsr
125         orl     $MTRR_DEF_TYPE_EN, %eax
126         wrmsr
128         /* Enable cache - CR0_NW is and stays clear */
129         movl    %cr0, %eax
130         andl    $~(CR0_CD), %eax
131         movl    %eax, %cr0
133         /*
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
137          * be power of two.
138          *
139          * Note: Do not forget that CAR has been torn down, so the stack doesn't exist.
140          */
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 */
148         getsec
150         /*
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.
155          */
156 #if 1
157         movw    $0xcf8, %dx
158         movl    $0x8000F8AC, %eax
159         outl    %eax, %dx
161         movw    $0xcfc, %dx
162         inl     %dx, %eax
163         andl    $~(1 << 20), %eax
164         outl    %eax, %dx
165 #endif
167         movw    $0xcf9, %dx
168         movb    $0, %al
169         outb    %al, %dx
171         movw    $0xcf9, %dx
172         movb    $0x0e, %al
173         outb    %al, %dx
175         cli
177         hlt
179         ret