UefiCpuPkg/PiSmmCpuDxeSmm: patch "gSmiStack" 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
717fb604 57global ASM_PFX(mXdSupported)\r
fc504fde 58global ASM_PFX(gPatchSmiStack)\r
9a36d4dc
LG
59global ASM_PFX(gSmiCr3)\r
60global ASM_PFX(gcSmiHandlerTemplate)\r
61global ASM_PFX(gcSmiHandlerSize)\r
62\r
63 DEFAULT REL\r
64 SECTION .text\r
65\r
66BITS 16\r
67ASM_PFX(gcSmiHandlerTemplate):\r
68_SmiEntryPoint:\r
69 mov bx, _GdtDesc - _SmiEntryPoint + 0x8000\r
70 mov ax,[cs:DSC_OFFSET + DSC_GDTSIZ]\r
71 dec ax\r
72 mov [cs:bx], ax\r
73 mov eax, [cs:DSC_OFFSET + DSC_GDTPTR]\r
74 mov [cs:bx + 2], eax\r
75o32 lgdt [cs:bx] ; lgdt fword ptr cs:[bx]\r
76 mov ax, PROTECT_MODE_CS\r
717fb604 77 mov [cs:bx-0x2],ax\r
5a1bfda4
LE
78 mov edi, strict dword 0 ; source operand will be patched\r
79ASM_PFX(gPatchSmbase):\r
9a36d4dc
LG
80 lea eax, [edi + (@ProtectedMode - _SmiEntryPoint) + 0x8000]\r
81 mov [cs:bx-0x6],eax\r
82 mov ebx, cr0\r
83 and ebx, 0x9ffafff3\r
84 or ebx, 0x23\r
85 mov cr0, ebx\r
86 jmp dword 0x0:0x0\r
717fb604 87_GdtDesc:\r
9a36d4dc
LG
88 DW 0\r
89 DD 0\r
90\r
91BITS 32\r
92@ProtectedMode:\r
93 mov ax, PROTECT_MODE_DS\r
94o16 mov ds, ax\r
95o16 mov es, ax\r
96o16 mov fs, ax\r
97o16 mov gs, ax\r
98o16 mov ss, ax\r
fc504fde
LE
99 mov esp, strict dword 0 ; source operand will be patched\r
100ASM_PFX(gPatchSmiStack):\r
9a36d4dc
LG
101 jmp ProtFlatMode\r
102\r
103BITS 64\r
104ProtFlatMode:\r
105 DB 0xb8 ; mov eax, offset gSmiCr3\r
106ASM_PFX(gSmiCr3): DD 0\r
107 mov cr3, rax\r
108 mov eax, 0x668 ; as cr4.PGE is not set here, refresh cr3\r
109 mov cr4, rax ; in PreModifyMtrrs() to flush TLB.\r
110; Load TSS\r
111 sub esp, 8 ; reserve room in stack\r
112 sgdt [rsp]\r
113 mov eax, [rsp + 2] ; eax = GDT base\r
114 add esp, 8\r
115 mov dl, 0x89\r
116 mov [rax + TSS_SEGMENT + 5], dl ; clear busy flag\r
117 mov eax, TSS_SEGMENT\r
118 ltr ax\r
119\r
717fb604
JY
120; enable NXE if supported\r
121 DB 0xb0 ; mov al, imm8\r
122ASM_PFX(mXdSupported): DB 1\r
123 cmp al, 0\r
124 jz @SkipXd\r
125;\r
126; Check XD disable bit\r
127;\r
128 mov ecx, MSR_IA32_MISC_ENABLE\r
129 rdmsr\r
130 sub esp, 4\r
131 push rdx ; save MSR_IA32_MISC_ENABLE[63-32]\r
132 test edx, BIT2 ; MSR_IA32_MISC_ENABLE[34]\r
133 jz .0\r
134 and dx, 0xFFFB ; clear XD Disable bit if it is set\r
135 wrmsr\r
136.0:\r
137 mov ecx, MSR_EFER\r
138 rdmsr\r
139 or ax, MSR_EFER_XD ; enable NXE\r
140 wrmsr\r
141 jmp @XdDone\r
142@SkipXd:\r
143 sub esp, 8\r
144@XdDone:\r
145\r
9a36d4dc
LG
146; Switch into @LongMode\r
147 push LONG_MODE_CS ; push cs hardcore here\r
717fb604 148 call Base ; push return address for retf later\r
9a36d4dc
LG
149Base:\r
150 add dword [rsp], @LongMode - Base; offset for far retf, seg is the 1st arg\r
717fb604
JY
151\r
152 mov ecx, MSR_EFER\r
9a36d4dc 153 rdmsr\r
717fb604 154 or ah, 1 ; enable LME\r
9a36d4dc
LG
155 wrmsr\r
156 mov rbx, cr0\r
717fb604 157 or ebx, 0x80010023 ; enable paging + WP + NE + MP + PE\r
9a36d4dc
LG
158 mov cr0, rbx\r
159 retf\r
160@LongMode: ; long mode (64-bit code) starts here\r
e21e355e
LG
161 mov rax, strict qword 0 ; mov rax, ASM_PFX(gSmiHandlerIdtr)\r
162SmiHandlerIdtrAbsAddr:\r
9a36d4dc
LG
163 lidt [rax]\r
164 lea ebx, [rdi + DSC_OFFSET]\r
165 mov ax, [rbx + DSC_DS]\r
166 mov ds, eax\r
167 mov ax, [rbx + DSC_OTHERSEG]\r
168 mov es, eax\r
169 mov fs, eax\r
170 mov gs, eax\r
171 mov ax, [rbx + DSC_SS]\r
172 mov ss, eax\r
e21e355e
LG
173 mov rax, strict qword 0 ; mov rax, _SmiHandler\r
174_SmiHandlerAbsAddr:\r
175 jmp rax\r
9a36d4dc
LG
176\r
177_SmiHandler:\r
717fb604 178 mov rbx, [rsp + 0x8] ; rcx <- CpuIndex\r
9a36d4dc
LG
179\r
180 ;\r
181 ; Save FP registers\r
182 ;\r
717fb604 183 sub rsp, 0x200\r
9a36d4dc
LG
184 DB 0x48 ; FXSAVE64\r
185 fxsave [rsp]\r
186\r
187 add rsp, -0x20\r
188\r
189 mov rcx, rbx\r
e21e355e 190 call ASM_PFX(CpuSmmDebugEntry)\r
717fb604 191\r
9a36d4dc 192 mov rcx, rbx\r
e21e355e 193 call ASM_PFX(SmiRendezvous)\r
717fb604 194\r
9a36d4dc 195 mov rcx, rbx\r
e21e355e 196 call ASM_PFX(CpuSmmDebugExit)\r
717fb604 197\r
9a36d4dc
LG
198 add rsp, 0x20\r
199\r
200 ;\r
201 ; Restore FP registers\r
202 ;\r
203 DB 0x48 ; FXRSTOR64\r
204 fxrstor [rsp]\r
205\r
717fb604
JY
206 add rsp, 0x200\r
207\r
e21e355e 208 lea rax, [ASM_PFX(mXdSupported)]\r
717fb604
JY
209 mov al, [rax]\r
210 cmp al, 0\r
211 jz .1\r
212 pop rdx ; get saved MSR_IA32_MISC_ENABLE[63-32]\r
213 test edx, BIT2\r
214 jz .1\r
215 mov ecx, MSR_IA32_MISC_ENABLE\r
216 rdmsr\r
217 or dx, BIT2 ; set XD Disable bit if it was set before entering into SMM\r
218 wrmsr\r
219\r
220.1:\r
9a36d4dc
LG
221 rsm\r
222\r
8764ed57 223ASM_PFX(gcSmiHandlerSize) DW $ - _SmiEntryPoint\r
9a36d4dc 224\r
e21e355e
LG
225global ASM_PFX(PiSmmCpuSmiEntryFixupAddress)\r
226ASM_PFX(PiSmmCpuSmiEntryFixupAddress):\r
227 lea rax, [ASM_PFX(gSmiHandlerIdtr)]\r
228 lea rcx, [SmiHandlerIdtrAbsAddr]\r
229 mov qword [rcx - 8], rax\r
230\r
231 lea rax, [_SmiHandler]\r
232 lea rcx, [_SmiHandlerAbsAddr]\r
233 mov qword [rcx - 8], rax\r
234 ret\r