]> git.proxmox.com Git - mirror_edk2.git/blame - UefiCpuPkg/Library/SmmCpuFeaturesLib/Ia32/SmiEntry.asm
UefiCpuPkg/SmmCpuFeaturesLibStm: Add STM library instance
[mirror_edk2.git] / UefiCpuPkg / Library / SmmCpuFeaturesLib / Ia32 / SmiEntry.asm
CommitLineData
09119a00
MK
1;------------------------------------------------------------------------------ ;\r
2; Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>\r
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.asm\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 .686p\r
22 .model flat,C\r
23 .xmm\r
24\r
25MSR_IA32_MISC_ENABLE EQU 1A0h\r
26MSR_EFER EQU 0c0000080h\r
27MSR_EFER_XD EQU 0800h\r
28\r
29;\r
30; Constants relating to TXT_PROCESSOR_SMM_DESCRIPTOR\r
31;\r
32DSC_OFFSET EQU 0fb00h\r
33DSC_GDTPTR EQU 48h\r
34DSC_GDTSIZ EQU 50h\r
35DSC_CS EQU 14h\r
36DSC_DS EQU 16h\r
37DSC_SS EQU 18h\r
38DSC_OTHERSEG EQU 1Ah\r
39\r
40PROTECT_MODE_CS EQU 08h\r
41PROTECT_MODE_DS EQU 20h\r
42TSS_SEGMENT EQU 40h\r
43\r
44SmiRendezvous PROTO C\r
45CpuSmmDebugEntry PROTO C\r
46CpuSmmDebugExit PROTO C\r
47\r
48EXTERNDEF gcStmSmiHandlerTemplate:BYTE\r
49EXTERNDEF gcStmSmiHandlerSize:WORD\r
50EXTERNDEF gcStmSmiHandlerOffset:WORD\r
51EXTERNDEF gStmSmiCr3:DWORD\r
52EXTERNDEF gStmSmiStack:DWORD\r
53EXTERNDEF gStmSmbase:DWORD\r
54EXTERNDEF gStmXdSupported:BYTE\r
55EXTERNDEF FeaturePcdGet (PcdCpuSmmStackGuard):BYTE\r
56EXTERNDEF gStmSmiHandlerIdtr:FWORD\r
57\r
58 .code\r
59\r
60gcStmSmiHandlerTemplate LABEL BYTE\r
61\r
62_StmSmiEntryPoint:\r
63 DB 0bbh ; mov bx, imm16\r
64 DW offset _StmGdtDesc - _StmSmiEntryPoint + 8000h\r
65 DB 2eh, 0a1h ; mov ax, cs:[offset16]\r
66 DW DSC_OFFSET + DSC_GDTSIZ\r
67 dec eax\r
68 mov cs:[edi], eax ; mov cs:[bx], ax\r
69 DB 66h, 2eh, 0a1h ; mov eax, cs:[offset16]\r
70 DW DSC_OFFSET + DSC_GDTPTR\r
71 mov cs:[edi + 2], ax ; mov cs:[bx + 2], eax\r
72 mov bp, ax ; ebp = GDT base\r
73 DB 66h\r
74 lgdt fword ptr cs:[edi] ; lgdt fword ptr cs:[bx]\r
75; Patch ProtectedMode Segment\r
76 DB 0b8h ; mov ax, imm16\r
77 DW PROTECT_MODE_CS ; set AX for segment directly\r
78 mov cs:[edi - 2], eax ; mov cs:[bx - 2], ax\r
79; Patch ProtectedMode entry\r
80 DB 66h, 0bfh ; mov edi, SMBASE\r
81gStmSmbase DD ?\r
82 DB 67h\r
83 lea ax, [edi + (@32bit - _StmSmiEntryPoint) + 8000h]\r
84 mov cs:[edi - 6], ax ; mov cs:[bx - 6], eax\r
85 mov ebx, cr0\r
86 DB 66h\r
87 and ebx, 9ffafff3h\r
88 DB 66h\r
89 or ebx, 23h\r
90 mov cr0, ebx\r
91 DB 66h, 0eah\r
92 DD ?\r
93 DW ?\r
94_StmGdtDesc FWORD ?\r
95\r
96@32bit:\r
97 mov ax, PROTECT_MODE_DS\r
98 mov ds, ax\r
99 mov es, ax\r
100 mov fs, ax\r
101 mov gs, ax\r
102 mov ss, ax\r
103 DB 0bch ; mov esp, imm32\r
104gStmSmiStack DD ?\r
105 mov eax, offset gStmSmiHandlerIdtr\r
106 lidt fword ptr [eax]\r
107 jmp ProtFlatMode\r
108\r
109ProtFlatMode:\r
110 DB 0b8h ; mov eax, imm32\r
111gStmSmiCr3 DD ?\r
112 mov cr3, eax\r
113;\r
114; Need to test for CR4 specific bit support\r
115;\r
116 mov eax, 1\r
117 cpuid ; use CPUID to determine if specific CR4 bits are supported\r
118 xor eax, eax ; Clear EAX\r
119 test edx, BIT2 ; Check for DE capabilities\r
120 jz @f\r
121 or eax, BIT3\r
122@@:\r
123 test edx, BIT6 ; Check for PAE capabilities\r
124 jz @f\r
125 or eax, BIT5\r
126@@:\r
127 test edx, BIT7 ; Check for MCE capabilities\r
128 jz @f\r
129 or eax, BIT6\r
130@@:\r
131 test edx, BIT24 ; Check for FXSR capabilities\r
132 jz @f\r
133 or eax, BIT9\r
134@@:\r
135 test edx, BIT25 ; Check for SSE capabilities\r
136 jz @f\r
137 or eax, BIT10\r
138@@: ; as cr4.PGE is not set here, refresh cr3\r
139 mov cr4, eax ; in PreModifyMtrrs() to flush TLB.\r
140\r
141 cmp FeaturePcdGet (PcdCpuSmmStackGuard), 0\r
142 jz @F\r
143; Load TSS\r
144 mov byte ptr [ebp + TSS_SEGMENT + 5], 89h ; clear busy flag\r
145 mov eax, TSS_SEGMENT\r
146 ltr ax\r
147@@:\r
148\r
149; enable NXE if supported\r
150 DB 0b0h ; mov al, imm8\r
151gStmXdSupported DB 1\r
152 cmp al, 0\r
153 jz @SkipXd\r
154;\r
155; Check XD disable bit\r
156;\r
157 mov ecx, MSR_IA32_MISC_ENABLE\r
158 rdmsr\r
159 push edx ; save MSR_IA32_MISC_ENABLE[63-32]\r
160 test edx, BIT2 ; MSR_IA32_MISC_ENABLE[34]\r
161 jz @f\r
162 and dx, 0FFFBh ; clear XD Disable bit if it is set\r
163 wrmsr\r
164@@:\r
165 mov ecx, MSR_EFER\r
166 rdmsr\r
167 or ax, MSR_EFER_XD ; enable NXE\r
168 wrmsr\r
169 jmp @XdDone\r
170@SkipXd:\r
171 sub esp, 4\r
172@XdDone:\r
173\r
174 mov ebx, cr0\r
175 or ebx, 080010023h ; enable paging + WP + NE + MP + PE\r
176 mov cr0, ebx\r
177 lea ebx, [edi + DSC_OFFSET]\r
178 mov ax, [ebx + DSC_DS]\r
179 mov ds, eax\r
180 mov ax, [ebx + DSC_OTHERSEG]\r
181 mov es, eax\r
182 mov fs, eax\r
183 mov gs, eax\r
184 mov ax, [ebx + DSC_SS]\r
185 mov ss, eax\r
186\r
187CommonHandler:\r
188 mov ebx, [esp + 4] ; CPU Index\r
189 push ebx\r
190 mov eax, CpuSmmDebugEntry\r
191 call eax\r
192 add esp, 4\r
193\r
194 push ebx\r
195 mov eax, SmiRendezvous\r
196 call eax\r
197 add esp, 4\r
198\r
199 push ebx\r
200 mov eax, CpuSmmDebugExit\r
201 call eax\r
202 add esp, 4\r
203\r
204 mov eax, gStmXdSupported\r
205 mov al, [eax]\r
206 cmp al, 0\r
207 jz @f\r
208 pop edx ; get saved MSR_IA32_MISC_ENABLE[63-32]\r
209 test edx, BIT2\r
210 jz @f\r
211 mov ecx, MSR_IA32_MISC_ENABLE\r
212 rdmsr\r
213 or dx, BIT2 ; set XD Disable bit if it was set before entering into SMM\r
214 wrmsr\r
215\r
216@@:\r
217 rsm\r
218\r
219_StmSmiHandler:\r
220;\r
221; Check XD disable bit\r
222;\r
223 xor esi, esi\r
224 mov eax, gStmXdSupported\r
225 mov al, [eax]\r
226 cmp al, 0\r
227 jz @StmXdDone\r
228 mov ecx, MSR_IA32_MISC_ENABLE\r
229 rdmsr\r
230 mov esi, edx ; save MSR_IA32_MISC_ENABLE[63-32]\r
231 test edx, BIT2 ; MSR_IA32_MISC_ENABLE[34]\r
232 jz @f\r
233 and dx, 0FFFBh ; clear XD Disable bit if it is set\r
234 wrmsr\r
235@@:\r
236 mov ecx, MSR_EFER\r
237 rdmsr\r
238 or ax, MSR_EFER_XD ; enable NXE\r
239 wrmsr\r
240@StmXdDone:\r
241 push esi\r
242\r
243 ; below step is needed, because STM does not run above code.\r
244 ; we have to run below code to set IDT/CR0/CR4\r
245 mov eax, offset gStmSmiHandlerIdtr\r
246 lidt fword ptr [eax]\r
247\r
248\r
249 mov eax, cr0\r
250 or eax, 80010023h ; enable paging + WP + NE + MP + PE\r
251 mov cr0, eax\r
252;\r
253; Need to test for CR4 specific bit support\r
254;\r
255 mov eax, 1\r
256 cpuid ; use CPUID to determine if specific CR4 bits are supported\r
257 mov eax, cr4 ; init EAX\r
258 test edx, BIT2 ; Check for DE capabilities\r
259 jz @f\r
260 or eax, BIT3\r
261@@:\r
262 test edx, BIT6 ; Check for PAE capabilities\r
263 jz @f\r
264 or eax, BIT5\r
265@@:\r
266 test edx, BIT7 ; Check for MCE capabilities\r
267 jz @f\r
268 or eax, BIT6\r
269@@:\r
270 test edx, BIT24 ; Check for FXSR capabilities\r
271 jz @f\r
272 or eax, BIT9\r
273@@:\r
274 test edx, BIT25 ; Check for SSE capabilities\r
275 jz @f\r
276 or eax, BIT10\r
277@@: ; as cr4.PGE is not set here, refresh cr3\r
278 mov cr4, eax ; in PreModifyMtrrs() to flush TLB.\r
279 ; STM init finish\r
280 jmp CommonHandler\r
281\r
282gcStmSmiHandlerSize DW $ - _StmSmiEntryPoint\r
283gcStmSmiHandlerOffset DW _StmSmiHandler - _StmSmiEntryPoint\r
284\r
285 END\r