]> git.proxmox.com Git - mirror_edk2.git/blame - UefiCpuPkg/Library/SmmCpuFeaturesLib/Ia32/SmiEntry.nasm
UefiCpuPkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / UefiCpuPkg / Library / SmmCpuFeaturesLib / Ia32 / 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
MK
17%define MSR_IA32_MISC_ENABLE 0x1A0\r
18%define MSR_EFER 0xc0000080\r
19%define MSR_EFER_XD 0x800\r
20\r
21;\r
22; Constants relating to TXT_PROCESSOR_SMM_DESCRIPTOR\r
23;\r
24%define DSC_OFFSET 0xfb00\r
25%define DSC_GDTPTR 0x48\r
26%define DSC_GDTSIZ 0x50\r
27%define DSC_CS 0x14\r
28%define DSC_DS 0x16\r
29%define DSC_SS 0x18\r
30%define DSC_OTHERSEG 0x1a\r
31\r
32%define PROTECT_MODE_CS 0x8\r
33%define PROTECT_MODE_DS 0x20\r
34%define TSS_SEGMENT 0x40\r
35\r
36extern ASM_PFX(SmiRendezvous)\r
37extern ASM_PFX(FeaturePcdGet (PcdCpuSmmStackGuard))\r
38extern ASM_PFX(CpuSmmDebugEntry)\r
39extern ASM_PFX(CpuSmmDebugExit)\r
40\r
41global ASM_PFX(gcStmSmiHandlerTemplate)\r
42global ASM_PFX(gcStmSmiHandlerSize)\r
43global ASM_PFX(gcStmSmiHandlerOffset)\r
44global ASM_PFX(gStmSmiCr3)\r
45global ASM_PFX(gStmSmiStack)\r
46global ASM_PFX(gStmSmbase)\r
47global ASM_PFX(gStmXdSupported)\r
48extern ASM_PFX(gStmSmiHandlerIdtr)\r
49\r
4c34a8ea
CR
50ASM_PFX(gStmSmiCr3) EQU StmSmiCr3Patch - 4\r
51ASM_PFX(gStmSmiStack) EQU StmSmiStackPatch - 4\r
52ASM_PFX(gStmSmbase) EQU StmSmbasePatch - 4\r
53ASM_PFX(gStmXdSupported) EQU StmXdSupportedPatch - 1\r
54\r
09119a00
MK
55 SECTION .text\r
56\r
57BITS 16\r
58ASM_PFX(gcStmSmiHandlerTemplate):\r
59_StmSmiEntryPoint:\r
60 mov bx, _StmGdtDesc - _StmSmiEntryPoint + 0x8000\r
61 mov ax,[cs:DSC_OFFSET + DSC_GDTSIZ]\r
62 dec ax\r
63 mov [cs:bx], ax\r
64 mov eax, [cs:DSC_OFFSET + DSC_GDTPTR]\r
65 mov [cs:bx + 2], eax\r
66 mov ebp, eax ; ebp = GDT base\r
67o32 lgdt [cs:bx] ; lgdt fword ptr cs:[bx]\r
68 mov ax, PROTECT_MODE_CS\r
69 mov [cs:bx-0x2],ax\r
4c34a8ea
CR
70o32 mov edi, strict dword 0\r
71StmSmbasePatch:\r
09119a00
MK
72 lea eax, [edi + (@32bit - _StmSmiEntryPoint) + 0x8000]\r
73 mov [cs:bx-0x6],eax\r
74 mov ebx, cr0\r
75 and ebx, 0x9ffafff3\r
76 or ebx, 0x23\r
77 mov cr0, ebx\r
78 jmp dword 0x0:0x0\r
79_StmGdtDesc:\r
80 DW 0\r
81 DD 0\r
82\r
83BITS 32\r
84@32bit:\r
85 mov ax, PROTECT_MODE_DS\r
86o16 mov ds, ax\r
87o16 mov es, ax\r
88o16 mov fs, ax\r
89o16 mov gs, ax\r
90o16 mov ss, ax\r
4c34a8ea
CR
91 mov esp, strict dword 0\r
92StmSmiStackPatch:\r
09119a00
MK
93 mov eax, ASM_PFX(gStmSmiHandlerIdtr)\r
94 lidt [eax]\r
95 jmp ProtFlatMode\r
96\r
97ProtFlatMode:\r
4c34a8ea
CR
98 mov eax, strict dword 0\r
99StmSmiCr3Patch:\r
09119a00
MK
100 mov cr3, eax\r
101;\r
102; Need to test for CR4 specific bit support\r
103;\r
104 mov eax, 1\r
105 cpuid ; use CPUID to determine if specific CR4 bits are supported\r
106 xor eax, eax ; Clear EAX\r
107 test edx, BIT2 ; Check for DE capabilities\r
108 jz .0\r
109 or eax, BIT3\r
110.0:\r
111 test edx, BIT6 ; Check for PAE capabilities\r
112 jz .1\r
113 or eax, BIT5\r
114.1:\r
115 test edx, BIT7 ; Check for MCE capabilities\r
116 jz .2\r
117 or eax, BIT6\r
118.2:\r
119 test edx, BIT24 ; Check for FXSR capabilities\r
120 jz .3\r
121 or eax, BIT9\r
122.3:\r
123 test edx, BIT25 ; Check for SSE capabilities\r
124 jz .4\r
125 or eax, BIT10\r
126.4: ; as cr4.PGE is not set here, refresh cr3\r
127 mov cr4, eax ; in PreModifyMtrrs() to flush TLB.\r
128\r
129 cmp byte [dword ASM_PFX(FeaturePcdGet (PcdCpuSmmStackGuard))], 0\r
130 jz .6\r
131; Load TSS\r
132 mov byte [ebp + TSS_SEGMENT + 5], 0x89 ; clear busy flag\r
133 mov eax, TSS_SEGMENT\r
134 ltr ax\r
135.6:\r
136\r
137; enable NXE if supported\r
4c34a8ea
CR
138 mov al, strict byte 1\r
139StmXdSupportedPatch:\r
09119a00
MK
140 cmp al, 0\r
141 jz @SkipXd\r
142;\r
143; Check XD disable bit\r
144;\r
145 mov ecx, MSR_IA32_MISC_ENABLE\r
146 rdmsr\r
147 push edx ; save MSR_IA32_MISC_ENABLE[63-32]\r
148 test edx, BIT2 ; MSR_IA32_MISC_ENABLE[34]\r
149 jz .5\r
150 and dx, 0xFFFB ; clear XD Disable bit if it is set\r
151 wrmsr\r
152.5:\r
153 mov ecx, MSR_EFER\r
154 rdmsr\r
155 or ax, MSR_EFER_XD ; enable NXE\r
156 wrmsr\r
157 jmp @XdDone\r
158@SkipXd:\r
159 sub esp, 4\r
160@XdDone:\r
161\r
162 mov ebx, cr0\r
163 or ebx, 0x80010023 ; enable paging + WP + NE + MP + PE\r
164 mov cr0, ebx\r
165 lea ebx, [edi + DSC_OFFSET]\r
166 mov ax, [ebx + DSC_DS]\r
167 mov ds, eax\r
168 mov ax, [ebx + DSC_OTHERSEG]\r
169 mov es, eax\r
170 mov fs, eax\r
171 mov gs, eax\r
172 mov ax, [ebx + DSC_SS]\r
173 mov ss, eax\r
174\r
175CommonHandler:\r
176 mov ebx, [esp + 4] ; CPU Index\r
177 push ebx\r
178 mov eax, ASM_PFX(CpuSmmDebugEntry)\r
179 call eax\r
180 add esp, 4\r
181\r
182 push ebx\r
183 mov eax, ASM_PFX(SmiRendezvous)\r
184 call eax\r
185 add esp, 4\r
186\r
187 push ebx\r
188 mov eax, ASM_PFX(CpuSmmDebugExit)\r
189 call eax\r
190 add esp, 4\r
191\r
192 mov eax, ASM_PFX(gStmXdSupported)\r
193 mov al, [eax]\r
194 cmp al, 0\r
195 jz .7\r
196 pop edx ; get saved MSR_IA32_MISC_ENABLE[63-32]\r
197 test edx, BIT2\r
198 jz .7\r
199 mov ecx, MSR_IA32_MISC_ENABLE\r
200 rdmsr\r
201 or dx, BIT2 ; set XD Disable bit if it was set before entering into SMM\r
202 wrmsr\r
203\r
204.7:\r
0df50560 205 StuffRsb32\r
09119a00
MK
206 rsm\r
207\r
208\r
209_StmSmiHandler:\r
210;\r
211; Check XD disable bit\r
212;\r
213 xor esi, esi\r
214 mov eax, ASM_PFX(gStmXdSupported)\r
215 mov al, [eax]\r
216 cmp al, 0\r
217 jz @StmXdDone\r
218 mov ecx, MSR_IA32_MISC_ENABLE\r
219 rdmsr\r
220 mov esi, edx ; save MSR_IA32_MISC_ENABLE[63-32]\r
221 test edx, BIT2 ; MSR_IA32_MISC_ENABLE[34]\r
222 jz .5\r
223 and dx, 0xFFFB ; clear XD Disable bit if it is set\r
224 wrmsr\r
225.5:\r
226 mov ecx, MSR_EFER\r
227 rdmsr\r
228 or ax, MSR_EFER_XD ; enable NXE\r
229 wrmsr\r
230@StmXdDone:\r
231 push esi\r
232\r
233 ; below step is needed, because STM does not run above code.\r
234 ; we have to run below code to set IDT/CR0/CR4\r
235 mov eax, ASM_PFX(gStmSmiHandlerIdtr)\r
236 lidt [eax]\r
237\r
238 mov eax, cr0\r
239 or eax, 0x80010023 ; enable paging + WP + NE + MP + PE\r
240 mov cr0, eax\r
241;\r
242; Need to test for CR4 specific bit support\r
243;\r
244 mov eax, 1\r
245 cpuid ; use CPUID to determine if specific CR4 bits are supported\r
246 mov eax, cr4 ; init EAX\r
247 test edx, BIT2 ; Check for DE capabilities\r
248 jz .0\r
249 or eax, BIT3\r
250.0:\r
251 test edx, BIT6 ; Check for PAE capabilities\r
252 jz .1\r
253 or eax, BIT5\r
254.1:\r
255 test edx, BIT7 ; Check for MCE capabilities\r
256 jz .2\r
257 or eax, BIT6\r
258.2:\r
259 test edx, BIT24 ; Check for FXSR capabilities\r
260 jz .3\r
261 or eax, BIT9\r
262.3:\r
263 test edx, BIT25 ; Check for SSE capabilities\r
264 jz .4\r
265 or eax, BIT10\r
266.4: ; as cr4.PGE is not set here, refresh cr3\r
267 mov cr4, eax ; in PreModifyMtrrs() to flush TLB.\r
268 ; STM init finish\r
269 jmp CommonHandler\r
270\r
271ASM_PFX(gcStmSmiHandlerSize) : DW $ - _StmSmiEntryPoint\r
272ASM_PFX(gcStmSmiHandlerOffset) : DW _StmSmiHandler - _StmSmiEntryPoint\r
1c7a65eb
LG
273\r
274global ASM_PFX(SmmCpuFeaturesLibStmSmiEntryFixupAddress)\r
275ASM_PFX(SmmCpuFeaturesLibStmSmiEntryFixupAddress):\r
276 ret\r