UefiCpuPkg/PiSmmCpuDxeSmm: patch "gSmiStack" with PatchInstructionX86()
[mirror_edk2.git] / UefiCpuPkg / PiSmmCpuDxeSmm / Ia32 / SmiEntry.nasm
CommitLineData
63a4f460 1;------------------------------------------------------------------------------ ;\r
e21e355e 2; Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>\r
63a4f460
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
717fb604
JY
21%define MSR_IA32_MISC_ENABLE 0x1A0\r
22%define MSR_EFER 0xc0000080\r
23%define MSR_EFER_XD 0x800\r
24\r
f12367a0
MK
25;\r
26; Constants relating to PROCESSOR_SMM_DESCRIPTOR\r
27;\r
63a4f460
LG
28%define DSC_OFFSET 0xfb00\r
29%define DSC_GDTPTR 0x30\r
30%define DSC_GDTSIZ 0x38\r
31%define DSC_CS 14\r
32%define DSC_DS 16\r
33%define DSC_SS 18\r
34%define DSC_OTHERSEG 20\r
35\r
36%define PROTECT_MODE_CS 0x8\r
37%define PROTECT_MODE_DS 0x20\r
38%define TSS_SEGMENT 0x40\r
39\r
40extern ASM_PFX(SmiRendezvous)\r
41extern ASM_PFX(FeaturePcdGet (PcdCpuSmmStackGuard))\r
42extern ASM_PFX(CpuSmmDebugEntry)\r
43extern ASM_PFX(CpuSmmDebugExit)\r
44\r
45global ASM_PFX(gcSmiHandlerTemplate)\r
46global ASM_PFX(gcSmiHandlerSize)\r
47global ASM_PFX(gSmiCr3)\r
fc504fde 48global ASM_PFX(gPatchSmiStack)\r
5a1bfda4 49global ASM_PFX(gPatchSmbase)\r
717fb604 50global ASM_PFX(mXdSupported)\r
63a4f460
LG
51extern ASM_PFX(gSmiHandlerIdtr)\r
52\r
53 SECTION .text\r
54\r
55BITS 16\r
56ASM_PFX(gcSmiHandlerTemplate):\r
57_SmiEntryPoint:\r
58 mov bx, _GdtDesc - _SmiEntryPoint + 0x8000\r
59 mov ax,[cs:DSC_OFFSET + DSC_GDTSIZ]\r
60 dec ax\r
61 mov [cs:bx], ax\r
62 mov eax, [cs:DSC_OFFSET + DSC_GDTPTR]\r
63 mov [cs:bx + 2], eax\r
64 mov ebp, eax ; ebp = GDT base\r
65o32 lgdt [cs:bx] ; lgdt fword ptr cs:[bx]\r
66 mov ax, PROTECT_MODE_CS\r
717fb604 67 mov [cs:bx-0x2],ax\r
5a1bfda4
LE
68 mov edi, strict dword 0 ; source operand will be patched\r
69ASM_PFX(gPatchSmbase):\r
63a4f460
LG
70 lea eax, [edi + (@32bit - _SmiEntryPoint) + 0x8000]\r
71 mov [cs:bx-0x6],eax\r
72 mov ebx, cr0\r
73 and ebx, 0x9ffafff3\r
74 or ebx, 0x23\r
75 mov cr0, ebx\r
76 jmp dword 0x0:0x0\r
717fb604 77_GdtDesc:\r
63a4f460
LG
78 DW 0\r
79 DD 0\r
80\r
81BITS 32\r
82@32bit:\r
83 mov ax, PROTECT_MODE_DS\r
84o16 mov ds, ax\r
85o16 mov es, ax\r
86o16 mov fs, ax\r
87o16 mov gs, ax\r
88o16 mov ss, ax\r
fc504fde
LE
89 mov esp, strict dword 0 ; source operand will be patched\r
90ASM_PFX(gPatchSmiStack):\r
63a4f460
LG
91 mov eax, ASM_PFX(gSmiHandlerIdtr)\r
92 lidt [eax]\r
93 jmp ProtFlatMode\r
94\r
95ProtFlatMode:\r
96 DB 0xb8 ; mov eax, imm32\r
97ASM_PFX(gSmiCr3): DD 0\r
98 mov cr3, eax\r
99;\r
100; Need to test for CR4 specific bit support\r
101;\r
102 mov eax, 1\r
103 cpuid ; use CPUID to determine if specific CR4 bits are supported\r
104 xor eax, eax ; Clear EAX\r
105 test edx, BIT2 ; Check for DE capabilities\r
106 jz .0\r
107 or eax, BIT3\r
108.0:\r
109 test edx, BIT6 ; Check for PAE capabilities\r
110 jz .1\r
111 or eax, BIT5\r
112.1:\r
113 test edx, BIT7 ; Check for MCE capabilities\r
114 jz .2\r
115 or eax, BIT6\r
116.2:\r
117 test edx, BIT24 ; Check for FXSR capabilities\r
118 jz .3\r
119 or eax, BIT9\r
120.3:\r
121 test edx, BIT25 ; Check for SSE capabilities\r
122 jz .4\r
123 or eax, BIT10\r
124.4: ; as cr4.PGE is not set here, refresh cr3\r
125 mov cr4, eax ; in PreModifyMtrrs() to flush TLB.\r
717fb604
JY
126\r
127 cmp byte [dword ASM_PFX(FeaturePcdGet (PcdCpuSmmStackGuard))], 0\r
128 jz .6\r
129; Load TSS\r
130 mov byte [ebp + TSS_SEGMENT + 5], 0x89 ; clear busy flag\r
131 mov eax, TSS_SEGMENT\r
132 ltr ax\r
133.6:\r
134\r
135; enable NXE if supported\r
136 DB 0b0h ; mov al, imm8\r
137ASM_PFX(mXdSupported): DB 1\r
138 cmp al, 0\r
139 jz @SkipXd\r
140;\r
141; Check XD disable bit\r
142;\r
143 mov ecx, MSR_IA32_MISC_ENABLE\r
144 rdmsr\r
145 push edx ; save MSR_IA32_MISC_ENABLE[63-32]\r
146 test edx, BIT2 ; MSR_IA32_MISC_ENABLE[34]\r
147 jz .5\r
148 and dx, 0xFFFB ; clear XD Disable bit if it is set\r
149 wrmsr\r
150.5:\r
151 mov ecx, MSR_EFER\r
152 rdmsr\r
153 or ax, MSR_EFER_XD ; enable NXE\r
154 wrmsr\r
155 jmp @XdDone\r
156@SkipXd:\r
157 sub esp, 4\r
158@XdDone:\r
159\r
63a4f460 160 mov ebx, cr0\r
717fb604 161 or ebx, 0x80010023 ; enable paging + WP + NE + MP + PE\r
63a4f460
LG
162 mov cr0, ebx\r
163 lea ebx, [edi + DSC_OFFSET]\r
164 mov ax, [ebx + DSC_DS]\r
165 mov ds, eax\r
166 mov ax, [ebx + DSC_OTHERSEG]\r
167 mov es, eax\r
168 mov fs, eax\r
169 mov gs, eax\r
170 mov ax, [ebx + DSC_SS]\r
171 mov ss, eax\r
172\r
63a4f460
LG
173; jmp _SmiHandler ; instruction is not needed\r
174\r
175global ASM_PFX(SmiHandler)\r
176ASM_PFX(SmiHandler):\r
717fb604 177 mov ebx, [esp + 4] ; CPU Index\r
63a4f460
LG
178 push ebx\r
179 mov eax, ASM_PFX(CpuSmmDebugEntry)\r
180 call eax\r
717fb604 181 add esp, 4\r
63a4f460
LG
182\r
183 push ebx\r
184 mov eax, ASM_PFX(SmiRendezvous)\r
185 call eax\r
717fb604
JY
186 add esp, 4\r
187\r
63a4f460
LG
188 push ebx\r
189 mov eax, ASM_PFX(CpuSmmDebugExit)\r
190 call eax\r
717fb604
JY
191 add esp, 4\r
192\r
193 mov eax, ASM_PFX(mXdSupported)\r
194 mov al, [eax]\r
195 cmp al, 0\r
196 jz .7\r
197 pop edx ; get saved MSR_IA32_MISC_ENABLE[63-32]\r
198 test edx, BIT2\r
199 jz .7\r
200 mov ecx, MSR_IA32_MISC_ENABLE\r
201 rdmsr\r
202 or dx, BIT2 ; set XD Disable bit if it was set before entering into SMM\r
203 wrmsr\r
204\r
205.7:\r
63a4f460
LG
206 rsm\r
207\r
208ASM_PFX(gcSmiHandlerSize): DW $ - _SmiEntryPoint\r
209\r
e21e355e
LG
210global ASM_PFX(PiSmmCpuSmiEntryFixupAddress)\r
211ASM_PFX(PiSmmCpuSmiEntryFixupAddress):\r
212 ret\r