1 ;------------------------------------------------------------------------------ ;
2 ; Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.<BR>
3 ; This program and the accompanying materials
4 ; are licensed and made available under the terms and conditions of the BSD License
5 ; which accompanies this distribution. The full text of the license may be found at
6 ; http://opensource.org/licenses/bsd-license.php.
8 ; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
9 ; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 ; Code template of the SMI handler for a particular processor
19 ;-------------------------------------------------------------------------------
21 %define MSR_IA32_MISC_ENABLE 0x1A0
22 %define MSR_EFER 0xc0000080
23 %define MSR_EFER_XD 0x800
26 ; Constants relating to TXT_PROCESSOR_SMM_DESCRIPTOR
28 %define DSC_OFFSET 0xfb00
29 %define DSC_GDTPTR 0x48
30 %define DSC_GDTSIZ 0x50
34 %define DSC_OTHERSEG 0x1a
36 %define PROTECT_MODE_CS 0x8
37 %define PROTECT_MODE_DS 0x20
38 %define TSS_SEGMENT 0x40
40 extern ASM_PFX(SmiRendezvous)
41 extern ASM_PFX(FeaturePcdGet (PcdCpuSmmStackGuard))
42 extern ASM_PFX(CpuSmmDebugEntry)
43 extern ASM_PFX(CpuSmmDebugExit)
45 global ASM_PFX(gcStmSmiHandlerTemplate)
46 global ASM_PFX(gcStmSmiHandlerSize)
47 global ASM_PFX(gcStmSmiHandlerOffset)
48 global ASM_PFX(gStmSmiCr3)
49 global ASM_PFX(gStmSmiStack)
50 global ASM_PFX(gStmSmbase)
51 global ASM_PFX(gStmXdSupported)
52 extern ASM_PFX(gStmSmiHandlerIdtr)
54 ASM_PFX(gStmSmiCr3) EQU StmSmiCr3Patch - 4
55 ASM_PFX(gStmSmiStack) EQU StmSmiStackPatch - 4
56 ASM_PFX(gStmSmbase) EQU StmSmbasePatch - 4
57 ASM_PFX(gStmXdSupported) EQU StmXdSupportedPatch - 1
62 ASM_PFX(gcStmSmiHandlerTemplate):
64 mov bx, _StmGdtDesc - _StmSmiEntryPoint + 0x8000
65 mov ax,[cs:DSC_OFFSET + DSC_GDTSIZ]
68 mov eax, [cs:DSC_OFFSET + DSC_GDTPTR]
70 mov ebp, eax ; ebp = GDT base
71 o32 lgdt [cs:bx] ; lgdt fword ptr cs:[bx]
72 mov ax, PROTECT_MODE_CS
74 o32 mov edi, strict dword 0
76 lea eax, [edi + (@32bit - _StmSmiEntryPoint) + 0x8000]
89 mov ax, PROTECT_MODE_DS
95 mov esp, strict dword 0
97 mov eax, ASM_PFX(gStmSmiHandlerIdtr)
102 mov eax, strict dword 0
106 ; Need to test for CR4 specific bit support
109 cpuid ; use CPUID to determine if specific CR4 bits are supported
110 xor eax, eax ; Clear EAX
111 test edx, BIT2 ; Check for DE capabilities
115 test edx, BIT6 ; Check for PAE capabilities
119 test edx, BIT7 ; Check for MCE capabilities
123 test edx, BIT24 ; Check for FXSR capabilities
127 test edx, BIT25 ; Check for SSE capabilities
130 .4: ; as cr4.PGE is not set here, refresh cr3
131 mov cr4, eax ; in PreModifyMtrrs() to flush TLB.
133 cmp byte [dword ASM_PFX(FeaturePcdGet (PcdCpuSmmStackGuard))], 0
136 mov byte [ebp + TSS_SEGMENT + 5], 0x89 ; clear busy flag
141 ; enable NXE if supported
142 mov al, strict byte 1
147 ; Check XD disable bit
149 mov ecx, MSR_IA32_MISC_ENABLE
151 push edx ; save MSR_IA32_MISC_ENABLE[63-32]
152 test edx, BIT2 ; MSR_IA32_MISC_ENABLE[34]
154 and dx, 0xFFFB ; clear XD Disable bit if it is set
159 or ax, MSR_EFER_XD ; enable NXE
167 or ebx, 0x80010023 ; enable paging + WP + NE + MP + PE
169 lea ebx, [edi + DSC_OFFSET]
170 mov ax, [ebx + DSC_DS]
172 mov ax, [ebx + DSC_OTHERSEG]
176 mov ax, [ebx + DSC_SS]
180 mov ebx, [esp + 4] ; CPU Index
182 mov eax, ASM_PFX(CpuSmmDebugEntry)
187 mov eax, ASM_PFX(SmiRendezvous)
192 mov eax, ASM_PFX(CpuSmmDebugExit)
196 mov eax, ASM_PFX(gStmXdSupported)
200 pop edx ; get saved MSR_IA32_MISC_ENABLE[63-32]
203 mov ecx, MSR_IA32_MISC_ENABLE
205 or dx, BIT2 ; set XD Disable bit if it was set before entering into SMM
214 ; Check XD disable bit
217 mov eax, ASM_PFX(gStmXdSupported)
221 mov ecx, MSR_IA32_MISC_ENABLE
223 mov esi, edx ; save MSR_IA32_MISC_ENABLE[63-32]
224 test edx, BIT2 ; MSR_IA32_MISC_ENABLE[34]
226 and dx, 0xFFFB ; clear XD Disable bit if it is set
231 or ax, MSR_EFER_XD ; enable NXE
236 ; below step is needed, because STM does not run above code.
237 ; we have to run below code to set IDT/CR0/CR4
238 mov eax, ASM_PFX(gStmSmiHandlerIdtr)
242 or eax, 0x80010023 ; enable paging + WP + NE + MP + PE
245 ; Need to test for CR4 specific bit support
248 cpuid ; use CPUID to determine if specific CR4 bits are supported
249 mov eax, cr4 ; init EAX
250 test edx, BIT2 ; Check for DE capabilities
254 test edx, BIT6 ; Check for PAE capabilities
258 test edx, BIT7 ; Check for MCE capabilities
262 test edx, BIT24 ; Check for FXSR capabilities
266 test edx, BIT25 ; Check for SSE capabilities
269 .4: ; as cr4.PGE is not set here, refresh cr3
270 mov cr4, eax ; in PreModifyMtrrs() to flush TLB.
274 ASM_PFX(gcStmSmiHandlerSize) : DW $ - _StmSmiEntryPoint
275 ASM_PFX(gcStmSmiHandlerOffset) : DW _StmSmiHandler - _StmSmiEntryPoint