]> git.proxmox.com Git - mirror_edk2.git/blob - UefiCpuPkg/Library/SmmCpuFeaturesLib/Ia32/SmiEntry.nasm
UefiCpuPkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / UefiCpuPkg / Library / SmmCpuFeaturesLib / Ia32 / SmiEntry.nasm
1 ;------------------------------------------------------------------------------ ;
2 ; Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
3 ; SPDX-License-Identifier: BSD-2-Clause-Patent
4 ;
5 ; Module Name:
6 ;
7 ; SmiEntry.nasm
8 ;
9 ; Abstract:
10 ;
11 ; Code template of the SMI handler for a particular processor
12 ;
13 ;-------------------------------------------------------------------------------
14
15 %include "StuffRsbNasm.inc"
16
17 %define MSR_IA32_MISC_ENABLE 0x1A0
18 %define MSR_EFER 0xc0000080
19 %define MSR_EFER_XD 0x800
20
21 ;
22 ; Constants relating to TXT_PROCESSOR_SMM_DESCRIPTOR
23 ;
24 %define DSC_OFFSET 0xfb00
25 %define DSC_GDTPTR 0x48
26 %define DSC_GDTSIZ 0x50
27 %define DSC_CS 0x14
28 %define DSC_DS 0x16
29 %define DSC_SS 0x18
30 %define DSC_OTHERSEG 0x1a
31
32 %define PROTECT_MODE_CS 0x8
33 %define PROTECT_MODE_DS 0x20
34 %define TSS_SEGMENT 0x40
35
36 extern ASM_PFX(SmiRendezvous)
37 extern ASM_PFX(FeaturePcdGet (PcdCpuSmmStackGuard))
38 extern ASM_PFX(CpuSmmDebugEntry)
39 extern ASM_PFX(CpuSmmDebugExit)
40
41 global ASM_PFX(gcStmSmiHandlerTemplate)
42 global ASM_PFX(gcStmSmiHandlerSize)
43 global ASM_PFX(gcStmSmiHandlerOffset)
44 global ASM_PFX(gStmSmiCr3)
45 global ASM_PFX(gStmSmiStack)
46 global ASM_PFX(gStmSmbase)
47 global ASM_PFX(gStmXdSupported)
48 extern ASM_PFX(gStmSmiHandlerIdtr)
49
50 ASM_PFX(gStmSmiCr3) EQU StmSmiCr3Patch - 4
51 ASM_PFX(gStmSmiStack) EQU StmSmiStackPatch - 4
52 ASM_PFX(gStmSmbase) EQU StmSmbasePatch - 4
53 ASM_PFX(gStmXdSupported) EQU StmXdSupportedPatch - 1
54
55 SECTION .text
56
57 BITS 16
58 ASM_PFX(gcStmSmiHandlerTemplate):
59 _StmSmiEntryPoint:
60 mov bx, _StmGdtDesc - _StmSmiEntryPoint + 0x8000
61 mov ax,[cs:DSC_OFFSET + DSC_GDTSIZ]
62 dec ax
63 mov [cs:bx], ax
64 mov eax, [cs:DSC_OFFSET + DSC_GDTPTR]
65 mov [cs:bx + 2], eax
66 mov ebp, eax ; ebp = GDT base
67 o32 lgdt [cs:bx] ; lgdt fword ptr cs:[bx]
68 mov ax, PROTECT_MODE_CS
69 mov [cs:bx-0x2],ax
70 o32 mov edi, strict dword 0
71 StmSmbasePatch:
72 lea eax, [edi + (@32bit - _StmSmiEntryPoint) + 0x8000]
73 mov [cs:bx-0x6],eax
74 mov ebx, cr0
75 and ebx, 0x9ffafff3
76 or ebx, 0x23
77 mov cr0, ebx
78 jmp dword 0x0:0x0
79 _StmGdtDesc:
80 DW 0
81 DD 0
82
83 BITS 32
84 @32bit:
85 mov ax, PROTECT_MODE_DS
86 o16 mov ds, ax
87 o16 mov es, ax
88 o16 mov fs, ax
89 o16 mov gs, ax
90 o16 mov ss, ax
91 mov esp, strict dword 0
92 StmSmiStackPatch:
93 mov eax, ASM_PFX(gStmSmiHandlerIdtr)
94 lidt [eax]
95 jmp ProtFlatMode
96
97 ProtFlatMode:
98 mov eax, strict dword 0
99 StmSmiCr3Patch:
100 mov cr3, eax
101 ;
102 ; Need to test for CR4 specific bit support
103 ;
104 mov eax, 1
105 cpuid ; use CPUID to determine if specific CR4 bits are supported
106 xor eax, eax ; Clear EAX
107 test edx, BIT2 ; Check for DE capabilities
108 jz .0
109 or eax, BIT3
110 .0:
111 test edx, BIT6 ; Check for PAE capabilities
112 jz .1
113 or eax, BIT5
114 .1:
115 test edx, BIT7 ; Check for MCE capabilities
116 jz .2
117 or eax, BIT6
118 .2:
119 test edx, BIT24 ; Check for FXSR capabilities
120 jz .3
121 or eax, BIT9
122 .3:
123 test edx, BIT25 ; Check for SSE capabilities
124 jz .4
125 or eax, BIT10
126 .4: ; as cr4.PGE is not set here, refresh cr3
127 mov cr4, eax ; in PreModifyMtrrs() to flush TLB.
128
129 cmp byte [dword ASM_PFX(FeaturePcdGet (PcdCpuSmmStackGuard))], 0
130 jz .6
131 ; Load TSS
132 mov byte [ebp + TSS_SEGMENT + 5], 0x89 ; clear busy flag
133 mov eax, TSS_SEGMENT
134 ltr ax
135 .6:
136
137 ; enable NXE if supported
138 mov al, strict byte 1
139 StmXdSupportedPatch:
140 cmp al, 0
141 jz @SkipXd
142 ;
143 ; Check XD disable bit
144 ;
145 mov ecx, MSR_IA32_MISC_ENABLE
146 rdmsr
147 push edx ; save MSR_IA32_MISC_ENABLE[63-32]
148 test edx, BIT2 ; MSR_IA32_MISC_ENABLE[34]
149 jz .5
150 and dx, 0xFFFB ; clear XD Disable bit if it is set
151 wrmsr
152 .5:
153 mov ecx, MSR_EFER
154 rdmsr
155 or ax, MSR_EFER_XD ; enable NXE
156 wrmsr
157 jmp @XdDone
158 @SkipXd:
159 sub esp, 4
160 @XdDone:
161
162 mov ebx, cr0
163 or ebx, 0x80010023 ; enable paging + WP + NE + MP + PE
164 mov cr0, ebx
165 lea ebx, [edi + DSC_OFFSET]
166 mov ax, [ebx + DSC_DS]
167 mov ds, eax
168 mov ax, [ebx + DSC_OTHERSEG]
169 mov es, eax
170 mov fs, eax
171 mov gs, eax
172 mov ax, [ebx + DSC_SS]
173 mov ss, eax
174
175 CommonHandler:
176 mov ebx, [esp + 4] ; CPU Index
177 push ebx
178 mov eax, ASM_PFX(CpuSmmDebugEntry)
179 call eax
180 add esp, 4
181
182 push ebx
183 mov eax, ASM_PFX(SmiRendezvous)
184 call eax
185 add esp, 4
186
187 push ebx
188 mov eax, ASM_PFX(CpuSmmDebugExit)
189 call eax
190 add esp, 4
191
192 mov eax, ASM_PFX(gStmXdSupported)
193 mov al, [eax]
194 cmp al, 0
195 jz .7
196 pop edx ; get saved MSR_IA32_MISC_ENABLE[63-32]
197 test edx, BIT2
198 jz .7
199 mov ecx, MSR_IA32_MISC_ENABLE
200 rdmsr
201 or dx, BIT2 ; set XD Disable bit if it was set before entering into SMM
202 wrmsr
203
204 .7:
205 StuffRsb32
206 rsm
207
208
209 _StmSmiHandler:
210 ;
211 ; Check XD disable bit
212 ;
213 xor esi, esi
214 mov eax, ASM_PFX(gStmXdSupported)
215 mov al, [eax]
216 cmp al, 0
217 jz @StmXdDone
218 mov ecx, MSR_IA32_MISC_ENABLE
219 rdmsr
220 mov esi, edx ; save MSR_IA32_MISC_ENABLE[63-32]
221 test edx, BIT2 ; MSR_IA32_MISC_ENABLE[34]
222 jz .5
223 and dx, 0xFFFB ; clear XD Disable bit if it is set
224 wrmsr
225 .5:
226 mov ecx, MSR_EFER
227 rdmsr
228 or ax, MSR_EFER_XD ; enable NXE
229 wrmsr
230 @StmXdDone:
231 push esi
232
233 ; below step is needed, because STM does not run above code.
234 ; we have to run below code to set IDT/CR0/CR4
235 mov eax, ASM_PFX(gStmSmiHandlerIdtr)
236 lidt [eax]
237
238 mov eax, cr0
239 or eax, 0x80010023 ; enable paging + WP + NE + MP + PE
240 mov cr0, eax
241 ;
242 ; Need to test for CR4 specific bit support
243 ;
244 mov eax, 1
245 cpuid ; use CPUID to determine if specific CR4 bits are supported
246 mov eax, cr4 ; init EAX
247 test edx, BIT2 ; Check for DE capabilities
248 jz .0
249 or eax, BIT3
250 .0:
251 test edx, BIT6 ; Check for PAE capabilities
252 jz .1
253 or eax, BIT5
254 .1:
255 test edx, BIT7 ; Check for MCE capabilities
256 jz .2
257 or eax, BIT6
258 .2:
259 test edx, BIT24 ; Check for FXSR capabilities
260 jz .3
261 or eax, BIT9
262 .3:
263 test edx, BIT25 ; Check for SSE capabilities
264 jz .4
265 or eax, BIT10
266 .4: ; as cr4.PGE is not set here, refresh cr3
267 mov cr4, eax ; in PreModifyMtrrs() to flush TLB.
268 ; STM init finish
269 jmp CommonHandler
270
271 ASM_PFX(gcStmSmiHandlerSize) : DW $ - _StmSmiEntryPoint
272 ASM_PFX(gcStmSmiHandlerOffset) : DW _StmSmiHandler - _StmSmiEntryPoint
273
274 global ASM_PFX(SmmCpuFeaturesLibStmSmiEntryFixupAddress)
275 ASM_PFX(SmmCpuFeaturesLibStmSmiEntryFixupAddress):
276 ret