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