UefiCpuPkg/PiSmmCpuDxeSmm: patch "XdSupported" with PatchInstructionX86()
[mirror_edk2.git] / UefiCpuPkg / PiSmmCpuDxeSmm / X64 / SmiEntry.nasm
CommitLineData
9a36d4dc 1;------------------------------------------------------------------------------ ;\r
e21e355e 2; Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>\r
9a36d4dc
LG
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
21;\r
22; Variables referrenced by C code\r
23;\r
24\r
717fb604
JY
25%define MSR_IA32_MISC_ENABLE 0x1A0\r
26%define MSR_EFER 0xc0000080\r
27%define MSR_EFER_XD 0x800\r
28\r
9a36d4dc
LG
29;\r
30; Constants relating to PROCESSOR_SMM_DESCRIPTOR\r
31;\r
32%define DSC_OFFSET 0xfb00\r
33%define DSC_GDTPTR 0x30\r
34%define DSC_GDTSIZ 0x38\r
35%define DSC_CS 14\r
36%define DSC_DS 16\r
37%define DSC_SS 18\r
38%define DSC_OTHERSEG 20\r
39;\r
40; Constants relating to CPU State Save Area\r
41;\r
42%define SSM_DR6 0xffd0\r
43%define SSM_DR7 0xffc8\r
44\r
45%define PROTECT_MODE_CS 0x8\r
46%define PROTECT_MODE_DS 0x20\r
47%define LONG_MODE_CS 0x38\r
48%define TSS_SEGMENT 0x40\r
49%define GDT_SIZE 0x50\r
50\r
51extern ASM_PFX(SmiRendezvous)\r
52extern ASM_PFX(gSmiHandlerIdtr)\r
53extern ASM_PFX(CpuSmmDebugEntry)\r
54extern ASM_PFX(CpuSmmDebugExit)\r
55\r
5a1bfda4 56global ASM_PFX(gPatchSmbase)\r
3c5ce64f
LE
57extern ASM_PFX(mXdSupported)\r
58global ASM_PFX(gPatchXdSupported)\r
fc504fde 59global ASM_PFX(gPatchSmiStack)\r
c455687f 60global ASM_PFX(gPatchSmiCr3)\r
9a36d4dc
LG
61global ASM_PFX(gcSmiHandlerTemplate)\r
62global ASM_PFX(gcSmiHandlerSize)\r
63\r
64 DEFAULT REL\r
65 SECTION .text\r
66\r
67BITS 16\r
68ASM_PFX(gcSmiHandlerTemplate):\r
69_SmiEntryPoint:\r
70 mov bx, _GdtDesc - _SmiEntryPoint + 0x8000\r
71 mov ax,[cs:DSC_OFFSET + DSC_GDTSIZ]\r
72 dec ax\r
73 mov [cs:bx], ax\r
74 mov eax, [cs:DSC_OFFSET + DSC_GDTPTR]\r
75 mov [cs:bx + 2], eax\r
76o32 lgdt [cs:bx] ; lgdt fword ptr cs:[bx]\r
77 mov ax, PROTECT_MODE_CS\r
717fb604 78 mov [cs:bx-0x2],ax\r
5a1bfda4
LE
79 mov edi, strict dword 0 ; source operand will be patched\r
80ASM_PFX(gPatchSmbase):\r
9a36d4dc
LG
81 lea eax, [edi + (@ProtectedMode - _SmiEntryPoint) + 0x8000]\r
82 mov [cs:bx-0x6],eax\r
83 mov ebx, cr0\r
84 and ebx, 0x9ffafff3\r
85 or ebx, 0x23\r
86 mov cr0, ebx\r
87 jmp dword 0x0:0x0\r
717fb604 88_GdtDesc:\r
9a36d4dc
LG
89 DW 0\r
90 DD 0\r
91\r
92BITS 32\r
93@ProtectedMode:\r
94 mov ax, PROTECT_MODE_DS\r
95o16 mov ds, ax\r
96o16 mov es, ax\r
97o16 mov fs, ax\r
98o16 mov gs, ax\r
99o16 mov ss, ax\r
fc504fde
LE
100 mov esp, strict dword 0 ; source operand will be patched\r
101ASM_PFX(gPatchSmiStack):\r
9a36d4dc
LG
102 jmp ProtFlatMode\r
103\r
104BITS 64\r
105ProtFlatMode:\r
c455687f
LE
106 mov eax, strict dword 0 ; source operand will be patched\r
107ASM_PFX(gPatchSmiCr3):\r
9a36d4dc
LG
108 mov cr3, rax\r
109 mov eax, 0x668 ; as cr4.PGE is not set here, refresh cr3\r
110 mov cr4, rax ; in PreModifyMtrrs() to flush TLB.\r
111; Load TSS\r
112 sub esp, 8 ; reserve room in stack\r
113 sgdt [rsp]\r
114 mov eax, [rsp + 2] ; eax = GDT base\r
115 add esp, 8\r
116 mov dl, 0x89\r
117 mov [rax + TSS_SEGMENT + 5], dl ; clear busy flag\r
118 mov eax, TSS_SEGMENT\r
119 ltr ax\r
120\r
717fb604 121; enable NXE if supported\r
3c5ce64f
LE
122 mov al, strict byte 1 ; source operand may be patched\r
123ASM_PFX(gPatchXdSupported):\r
717fb604
JY
124 cmp al, 0\r
125 jz @SkipXd\r
126;\r
127; Check XD disable bit\r
128;\r
129 mov ecx, MSR_IA32_MISC_ENABLE\r
130 rdmsr\r
131 sub esp, 4\r
132 push rdx ; save MSR_IA32_MISC_ENABLE[63-32]\r
133 test edx, BIT2 ; MSR_IA32_MISC_ENABLE[34]\r
134 jz .0\r
135 and dx, 0xFFFB ; clear XD Disable bit if it is set\r
136 wrmsr\r
137.0:\r
138 mov ecx, MSR_EFER\r
139 rdmsr\r
140 or ax, MSR_EFER_XD ; enable NXE\r
141 wrmsr\r
142 jmp @XdDone\r
143@SkipXd:\r
144 sub esp, 8\r
145@XdDone:\r
146\r
9a36d4dc
LG
147; Switch into @LongMode\r
148 push LONG_MODE_CS ; push cs hardcore here\r
717fb604 149 call Base ; push return address for retf later\r
9a36d4dc
LG
150Base:\r
151 add dword [rsp], @LongMode - Base; offset for far retf, seg is the 1st arg\r
717fb604
JY
152\r
153 mov ecx, MSR_EFER\r
9a36d4dc 154 rdmsr\r
717fb604 155 or ah, 1 ; enable LME\r
9a36d4dc
LG
156 wrmsr\r
157 mov rbx, cr0\r
717fb604 158 or ebx, 0x80010023 ; enable paging + WP + NE + MP + PE\r
9a36d4dc
LG
159 mov cr0, rbx\r
160 retf\r
161@LongMode: ; long mode (64-bit code) starts here\r
e21e355e
LG
162 mov rax, strict qword 0 ; mov rax, ASM_PFX(gSmiHandlerIdtr)\r
163SmiHandlerIdtrAbsAddr:\r
9a36d4dc
LG
164 lidt [rax]\r
165 lea ebx, [rdi + DSC_OFFSET]\r
166 mov ax, [rbx + DSC_DS]\r
167 mov ds, eax\r
168 mov ax, [rbx + DSC_OTHERSEG]\r
169 mov es, eax\r
170 mov fs, eax\r
171 mov gs, eax\r
172 mov ax, [rbx + DSC_SS]\r
173 mov ss, eax\r
e21e355e
LG
174 mov rax, strict qword 0 ; mov rax, _SmiHandler\r
175_SmiHandlerAbsAddr:\r
176 jmp rax\r
9a36d4dc
LG
177\r
178_SmiHandler:\r
717fb604 179 mov rbx, [rsp + 0x8] ; rcx <- CpuIndex\r
9a36d4dc
LG
180\r
181 ;\r
182 ; Save FP registers\r
183 ;\r
717fb604 184 sub rsp, 0x200\r
9a36d4dc
LG
185 DB 0x48 ; FXSAVE64\r
186 fxsave [rsp]\r
187\r
188 add rsp, -0x20\r
189\r
190 mov rcx, rbx\r
e21e355e 191 call ASM_PFX(CpuSmmDebugEntry)\r
717fb604 192\r
9a36d4dc 193 mov rcx, rbx\r
e21e355e 194 call ASM_PFX(SmiRendezvous)\r
717fb604 195\r
9a36d4dc 196 mov rcx, rbx\r
e21e355e 197 call ASM_PFX(CpuSmmDebugExit)\r
717fb604 198\r
9a36d4dc
LG
199 add rsp, 0x20\r
200\r
201 ;\r
202 ; Restore FP registers\r
203 ;\r
204 DB 0x48 ; FXRSTOR64\r
205 fxrstor [rsp]\r
206\r
717fb604
JY
207 add rsp, 0x200\r
208\r
e21e355e 209 lea rax, [ASM_PFX(mXdSupported)]\r
717fb604
JY
210 mov al, [rax]\r
211 cmp al, 0\r
212 jz .1\r
213 pop rdx ; get saved MSR_IA32_MISC_ENABLE[63-32]\r
214 test edx, BIT2\r
215 jz .1\r
216 mov ecx, MSR_IA32_MISC_ENABLE\r
217 rdmsr\r
218 or dx, BIT2 ; set XD Disable bit if it was set before entering into SMM\r
219 wrmsr\r
220\r
221.1:\r
9a36d4dc
LG
222 rsm\r
223\r
8764ed57 224ASM_PFX(gcSmiHandlerSize) DW $ - _SmiEntryPoint\r
9a36d4dc 225\r
e21e355e
LG
226global ASM_PFX(PiSmmCpuSmiEntryFixupAddress)\r
227ASM_PFX(PiSmmCpuSmiEntryFixupAddress):\r
228 lea rax, [ASM_PFX(gSmiHandlerIdtr)]\r
229 lea rcx, [SmiHandlerIdtrAbsAddr]\r
230 mov qword [rcx - 8], rax\r
231\r
232 lea rax, [_SmiHandler]\r
233 lea rcx, [_SmiHandlerAbsAddr]\r
234 mov qword [rcx - 8], rax\r
235 ret\r