1 ;------------------------------------------------------------------------------ ;
2 ; Copyright (c) 2016, 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 ;-------------------------------------------------------------------------------
22 ; Variables referrenced by C code
25 %define MSR_IA32_MISC_ENABLE 0x1A0
26 %define MSR_EFER 0xc0000080
27 %define MSR_EFER_XD 0x800
30 ; Constants relating to TXT_PROCESSOR_SMM_DESCRIPTOR
32 %define DSC_OFFSET 0xfb00
33 %define DSC_GDTPTR 0x48
34 %define DSC_GDTSIZ 0x50
38 %define DSC_OTHERSEG 0x1a
40 ; Constants relating to CPU State Save Area
42 %define SSM_DR6 0xffd0
43 %define SSM_DR7 0xffc8
45 %define PROTECT_MODE_CS 0x8
46 %define PROTECT_MODE_DS 0x20
47 %define LONG_MODE_CS 0x38
48 %define TSS_SEGMENT 0x40
51 extern ASM_PFX(SmiRendezvous)
52 extern ASM_PFX(gStmSmiHandlerIdtr)
53 extern ASM_PFX(CpuSmmDebugEntry)
54 extern ASM_PFX(CpuSmmDebugExit)
56 global ASM_PFX(gStmSmbase)
57 global ASM_PFX(gStmXdSupported)
58 global ASM_PFX(gStmSmiStack)
59 global ASM_PFX(gStmSmiCr3)
60 global ASM_PFX(gcStmSmiHandlerTemplate)
61 global ASM_PFX(gcStmSmiHandlerSize)
62 global ASM_PFX(gcStmSmiHandlerOffset)
68 ASM_PFX(gcStmSmiHandlerTemplate):
70 mov bx, _StmGdtDesc - _StmSmiEntryPoint + 0x8000
71 mov ax,[cs:DSC_OFFSET + DSC_GDTSIZ]
74 mov eax, [cs:DSC_OFFSET + DSC_GDTPTR]
76 o32 lgdt [cs:bx] ; lgdt fword ptr cs:[bx]
77 mov ax, PROTECT_MODE_CS
79 DB 0x66, 0xbf ; mov edi, SMBASE
80 ASM_PFX(gStmSmbase): DD 0
81 lea eax, [edi + (@ProtectedMode - _StmSmiEntryPoint) + 0x8000]
94 mov ax, PROTECT_MODE_DS
100 DB 0xbc ; mov esp, imm32
101 ASM_PFX(gStmSmiStack): DD 0
106 DB 0xb8 ; mov eax, offset gStmSmiCr3
107 ASM_PFX(gStmSmiCr3): DD 0
109 mov eax, 0x668 ; as cr4.PGE is not set here, refresh cr3
110 mov cr4, rax ; in PreModifyMtrrs() to flush TLB.
112 sub esp, 8 ; reserve room in stack
114 mov eax, [rsp + 2] ; eax = GDT base
117 mov [rax + TSS_SEGMENT + 5], dl ; clear busy flag
121 ; enable NXE if supported
122 DB 0xb0 ; mov al, imm8
123 ASM_PFX(gStmXdSupported): DB 1
127 ; Check XD disable bit
129 mov ecx, MSR_IA32_MISC_ENABLE
132 push rdx ; save MSR_IA32_MISC_ENABLE[63-32]
133 test edx, BIT2 ; MSR_IA32_MISC_ENABLE[34]
135 and dx, 0xFFFB ; clear XD Disable bit if it is set
140 or ax, MSR_EFER_XD ; enable NXE
147 ; Switch into @LongMode
148 push LONG_MODE_CS ; push cs hardcore here
149 call Base ; push return address for retf later
151 add dword [rsp], @LongMode - Base; offset for far retf, seg is the 1st arg
155 or ah, 1 ; enable LME
158 or ebx, 0x80010023 ; enable paging + WP + NE + MP + PE
161 @LongMode: ; long mode (64-bit code) starts here
162 mov rax, ASM_PFX(gStmSmiHandlerIdtr)
164 lea ebx, [rdi + DSC_OFFSET]
165 mov ax, [rbx + DSC_DS]
167 mov ax, [rbx + DSC_OTHERSEG]
171 mov ax, [rbx + DSC_SS]
175 mov rbx, [rsp + 0x08] ; rbx <- CpuIndex
187 mov rax, CpuSmmDebugEntry
191 mov rax, SmiRendezvous ; rax <- absolute addr of SmiRedezvous
195 mov rax, CpuSmmDebugExit
201 ; Restore FP registers
208 mov rax, ASM_PFX(gStmXdSupported)
212 pop rdx ; get saved MSR_IA32_MISC_ENABLE[63-32]
215 mov ecx, MSR_IA32_MISC_ENABLE
217 or dx, BIT2 ; set XD Disable bit if it was set before entering into SMM
225 ; Check XD disable bit
228 mov rax, ASM_PFX(gStmXdSupported)
232 mov ecx, MSR_IA32_MISC_ENABLE
234 mov r8, rdx ; save MSR_IA32_MISC_ENABLE[63-32]
235 test edx, BIT2 ; MSR_IA32_MISC_ENABLE[34]
237 and dx, 0xFFFB ; clear XD Disable bit if it is set
242 or ax, MSR_EFER_XD ; enable NXE
247 ; below step is needed, because STM does not run above code.
248 ; we have to run below code to set IDT/CR0/CR4
250 mov rax, ASM_PFX(gStmSmiHandlerIdtr)
254 or eax, 0x80010023 ; enable paging + WP + NE + MP + PE
257 mov eax, 0x668 ; as cr4.PGE is not set here, refresh cr3
258 mov cr4, rax ; in PreModifyMtrrs() to flush TLB.
262 ASM_PFX(gcStmSmiHandlerSize) : DW $ - _StmSmiEntryPoint
263 ASM_PFX(gcStmSmiHandlerOffset) : DW _StmSmiHandler - _StmSmiEntryPoint