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