1 ;------------------------------------------------------------------------------ ;
2 ; Copyright (c) 2016 - 2018, 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 %include "StuffRsb.inc"
24 ; Variables referrenced by C code
27 %define MSR_IA32_MISC_ENABLE 0x1A0
28 %define MSR_EFER 0xc0000080
29 %define MSR_EFER_XD 0x800
32 ; Constants relating to PROCESSOR_SMM_DESCRIPTOR
34 %define DSC_OFFSET 0xfb00
35 %define DSC_GDTPTR 0x30
36 %define DSC_GDTSIZ 0x38
40 %define DSC_OTHERSEG 20
42 ; Constants relating to CPU State Save Area
44 %define SSM_DR6 0xffd0
45 %define SSM_DR7 0xffc8
47 %define PROTECT_MODE_CS 0x8
48 %define PROTECT_MODE_DS 0x20
49 %define LONG_MODE_CS 0x38
50 %define TSS_SEGMENT 0x40
53 extern ASM_PFX(SmiRendezvous)
54 extern ASM_PFX(gSmiHandlerIdtr)
55 extern ASM_PFX(CpuSmmDebugEntry)
56 extern ASM_PFX(CpuSmmDebugExit)
58 global ASM_PFX(gPatchSmbase)
59 extern ASM_PFX(mXdSupported)
60 global ASM_PFX(gPatchXdSupported)
61 global ASM_PFX(gPatchSmiStack)
62 global ASM_PFX(gPatchSmiCr3)
63 global ASM_PFX(gcSmiHandlerTemplate)
64 global ASM_PFX(gcSmiHandlerSize)
70 ASM_PFX(gcSmiHandlerTemplate):
72 mov bx, _GdtDesc - _SmiEntryPoint + 0x8000
73 mov ax,[cs:DSC_OFFSET + DSC_GDTSIZ]
76 mov eax, [cs:DSC_OFFSET + DSC_GDTPTR]
78 o32 lgdt [cs:bx] ; lgdt fword ptr cs:[bx]
79 mov ax, PROTECT_MODE_CS
81 mov edi, strict dword 0 ; source operand will be patched
82 ASM_PFX(gPatchSmbase):
83 lea eax, [edi + (@ProtectedMode - _SmiEntryPoint) + 0x8000]
96 mov ax, PROTECT_MODE_DS
102 mov esp, strict dword 0 ; source operand will be patched
103 ASM_PFX(gPatchSmiStack):
108 mov eax, strict dword 0 ; source operand will be patched
109 ASM_PFX(gPatchSmiCr3):
111 mov eax, 0x668 ; as cr4.PGE is not set here, refresh cr3
112 mov cr4, rax ; in PreModifyMtrrs() to flush TLB.
114 sub esp, 8 ; reserve room in stack
116 mov eax, [rsp + 2] ; eax = GDT base
119 mov [rax + TSS_SEGMENT + 5], dl ; clear busy flag
123 ; enable NXE if supported
124 mov al, strict byte 1 ; source operand may be patched
125 ASM_PFX(gPatchXdSupported):
129 ; Check XD disable bit
131 mov ecx, MSR_IA32_MISC_ENABLE
134 push rdx ; save MSR_IA32_MISC_ENABLE[63-32]
135 test edx, BIT2 ; MSR_IA32_MISC_ENABLE[34]
137 and dx, 0xFFFB ; clear XD Disable bit if it is set
142 or ax, MSR_EFER_XD ; enable NXE
149 ; Switch into @LongMode
150 push LONG_MODE_CS ; push cs hardcore here
151 call Base ; push return address for retf later
153 add dword [rsp], @LongMode - Base; offset for far retf, seg is the 1st arg
157 or ah, 1 ; enable LME
160 or ebx, 0x80010023 ; enable paging + WP + NE + MP + PE
163 @LongMode: ; long mode (64-bit code) starts here
164 mov rax, strict qword 0 ; mov rax, ASM_PFX(gSmiHandlerIdtr)
165 SmiHandlerIdtrAbsAddr:
167 lea ebx, [rdi + DSC_OFFSET]
168 mov ax, [rbx + DSC_DS]
170 mov ax, [rbx + DSC_OTHERSEG]
174 mov ax, [rbx + DSC_SS]
176 mov rax, strict qword 0 ; mov rax, _SmiHandler
181 mov rbx, [rsp + 0x8] ; rcx <- CpuIndex
192 call ASM_PFX(CpuSmmDebugEntry)
195 call ASM_PFX(SmiRendezvous)
198 call ASM_PFX(CpuSmmDebugExit)
203 ; Restore FP registers
209 lea rax, [ASM_PFX(mXdSupported)]
213 pop rdx ; get saved MSR_IA32_MISC_ENABLE[63-32]
216 mov ecx, MSR_IA32_MISC_ENABLE
218 or dx, BIT2 ; set XD Disable bit if it was set before entering into SMM
225 ASM_PFX(gcSmiHandlerSize) DW $ - _SmiEntryPoint
227 global ASM_PFX(PiSmmCpuSmiEntryFixupAddress)
228 ASM_PFX(PiSmmCpuSmiEntryFixupAddress):
229 lea rax, [ASM_PFX(gSmiHandlerIdtr)]
230 lea rcx, [SmiHandlerIdtrAbsAddr]
231 mov qword [rcx - 8], rax
233 lea rax, [_SmiHandler]
234 lea rcx, [_SmiHandlerAbsAddr]
235 mov qword [rcx - 8], rax