]> git.proxmox.com Git - mirror_edk2.git/blob - UefiCpuPkg/Library/SmmCpuFeaturesLib/X64/SmiEntry.nasm
MdeModulePkg: Remove PcdPeiCoreMaxXXX PCDs
[mirror_edk2.git] / UefiCpuPkg / Library / SmmCpuFeaturesLib / X64 / SmiEntry.nasm
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.
7 ;
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.
10 ;
11 ; Module Name:
12 ;
13 ; SmiEntry.nasm
14 ;
15 ; Abstract:
16 ;
17 ; Code template of the SMI handler for a particular processor
18 ;
19 ;-------------------------------------------------------------------------------
20
21 %include "StuffRsb.inc"
22
23 ;
24 ; Variables referrenced by C code
25 ;
26
27 %define MSR_IA32_MISC_ENABLE 0x1A0
28 %define MSR_EFER 0xc0000080
29 %define MSR_EFER_XD 0x800
30
31 ;
32 ; Constants relating to TXT_PROCESSOR_SMM_DESCRIPTOR
33 ;
34 %define DSC_OFFSET 0xfb00
35 %define DSC_GDTPTR 0x48
36 %define DSC_GDTSIZ 0x50
37 %define DSC_CS 0x14
38 %define DSC_DS 0x16
39 %define DSC_SS 0x18
40 %define DSC_OTHERSEG 0x1a
41 ;
42 ; Constants relating to CPU State Save Area
43 ;
44 %define SSM_DR6 0xffd0
45 %define SSM_DR7 0xffc8
46
47 %define PROTECT_MODE_CS 0x8
48 %define PROTECT_MODE_DS 0x20
49 %define LONG_MODE_CS 0x38
50 %define TSS_SEGMENT 0x40
51 %define GDT_SIZE 0x50
52
53 extern ASM_PFX(SmiRendezvous)
54 extern ASM_PFX(gStmSmiHandlerIdtr)
55 extern ASM_PFX(CpuSmmDebugEntry)
56 extern ASM_PFX(CpuSmmDebugExit)
57
58 global ASM_PFX(gStmSmbase)
59 global ASM_PFX(gStmXdSupported)
60 global ASM_PFX(gStmSmiStack)
61 global ASM_PFX(gStmSmiCr3)
62 global ASM_PFX(gcStmSmiHandlerTemplate)
63 global ASM_PFX(gcStmSmiHandlerSize)
64 global ASM_PFX(gcStmSmiHandlerOffset)
65
66 ASM_PFX(gStmSmbase) EQU StmSmbasePatch - 4
67 ASM_PFX(gStmSmiStack) EQU StmSmiStackPatch - 4
68 ASM_PFX(gStmSmiCr3) EQU StmSmiCr3Patch - 4
69 ASM_PFX(gStmXdSupported) EQU StmXdSupportedPatch - 1
70
71 DEFAULT REL
72 SECTION .text
73
74 BITS 16
75 ASM_PFX(gcStmSmiHandlerTemplate):
76 _StmSmiEntryPoint:
77 mov bx, _StmGdtDesc - _StmSmiEntryPoint + 0x8000
78 mov ax,[cs:DSC_OFFSET + DSC_GDTSIZ]
79 dec ax
80 mov [cs:bx], ax
81 mov eax, [cs:DSC_OFFSET + DSC_GDTPTR]
82 mov [cs:bx + 2], eax
83 o32 lgdt [cs:bx] ; lgdt fword ptr cs:[bx]
84 mov ax, PROTECT_MODE_CS
85 mov [cs:bx-0x2],ax
86 o32 mov edi, strict dword 0
87 StmSmbasePatch:
88 lea eax, [edi + (@ProtectedMode - _StmSmiEntryPoint) + 0x8000]
89 mov [cs:bx-0x6],eax
90 mov ebx, cr0
91 and ebx, 0x9ffafff3
92 or ebx, 0x23
93 mov cr0, ebx
94 jmp dword 0x0:0x0
95 _StmGdtDesc:
96 DW 0
97 DD 0
98
99 BITS 32
100 @ProtectedMode:
101 mov ax, PROTECT_MODE_DS
102 o16 mov ds, ax
103 o16 mov es, ax
104 o16 mov fs, ax
105 o16 mov gs, ax
106 o16 mov ss, ax
107 mov esp, strict dword 0
108 StmSmiStackPatch:
109 jmp ProtFlatMode
110
111 BITS 64
112 ProtFlatMode:
113 mov eax, strict dword 0
114 StmSmiCr3Patch:
115 mov cr3, rax
116 mov eax, 0x668 ; as cr4.PGE is not set here, refresh cr3
117 mov cr4, rax ; in PreModifyMtrrs() to flush TLB.
118 ; Load TSS
119 sub esp, 8 ; reserve room in stack
120 sgdt [rsp]
121 mov eax, [rsp + 2] ; eax = GDT base
122 add esp, 8
123 mov dl, 0x89
124 mov [rax + TSS_SEGMENT + 5], dl ; clear busy flag
125 mov eax, TSS_SEGMENT
126 ltr ax
127
128 ; enable NXE if supported
129 mov al, strict byte 1
130 StmXdSupportedPatch:
131 cmp al, 0
132 jz @SkipXd
133 ;
134 ; Check XD disable bit
135 ;
136 mov ecx, MSR_IA32_MISC_ENABLE
137 rdmsr
138 sub esp, 4
139 push rdx ; save MSR_IA32_MISC_ENABLE[63-32]
140 test edx, BIT2 ; MSR_IA32_MISC_ENABLE[34]
141 jz .0
142 and dx, 0xFFFB ; clear XD Disable bit if it is set
143 wrmsr
144 .0:
145 mov ecx, MSR_EFER
146 rdmsr
147 or ax, MSR_EFER_XD ; enable NXE
148 wrmsr
149 jmp @XdDone
150 @SkipXd:
151 sub esp, 8
152 @XdDone:
153
154 ; Switch into @LongMode
155 push LONG_MODE_CS ; push cs hardcore here
156 call Base ; push return address for retf later
157 Base:
158 add dword [rsp], @LongMode - Base; offset for far retf, seg is the 1st arg
159
160 mov ecx, MSR_EFER
161 rdmsr
162 or ah, 1 ; enable LME
163 wrmsr
164 mov rbx, cr0
165 or ebx, 0x80010023 ; enable paging + WP + NE + MP + PE
166 mov cr0, rbx
167 retf
168 @LongMode: ; long mode (64-bit code) starts here
169 mov rax, strict qword 0 ; mov rax, ASM_PFX(gStmSmiHandlerIdtr)
170 StmSmiEntrySmiHandlerIdtrAbsAddr:
171 lidt [rax]
172 lea ebx, [rdi + DSC_OFFSET]
173 mov ax, [rbx + DSC_DS]
174 mov ds, eax
175 mov ax, [rbx + DSC_OTHERSEG]
176 mov es, eax
177 mov fs, eax
178 mov gs, eax
179 mov ax, [rbx + DSC_SS]
180 mov ss, eax
181 mov rax, strict qword 0 ; mov rax, CommonHandler
182 StmSmiEntryCommonHandlerAbsAddr:
183 jmp rax
184 CommonHandler:
185 mov rbx, [rsp + 0x08] ; rbx <- CpuIndex
186
187 ;
188 ; Save FP registers
189 ;
190 sub rsp, 0x200
191 fxsave64 [rsp]
192
193 add rsp, -0x20
194
195 mov rcx, rbx
196 call ASM_PFX(CpuSmmDebugEntry)
197
198 mov rcx, rbx
199 call ASM_PFX(SmiRendezvous)
200
201 mov rcx, rbx
202 call ASM_PFX(CpuSmmDebugExit)
203
204 add rsp, 0x20
205
206 ;
207 ; Restore FP registers
208 ;
209 fxrstor64 [rsp]
210
211 add rsp, 0x200
212
213 lea rax, [ASM_PFX(gStmXdSupported)]
214 mov al, [rax]
215 cmp al, 0
216 jz .1
217 pop rdx ; get saved MSR_IA32_MISC_ENABLE[63-32]
218 test edx, BIT2
219 jz .1
220 mov ecx, MSR_IA32_MISC_ENABLE
221 rdmsr
222 or dx, BIT2 ; set XD Disable bit if it was set before entering into SMM
223 wrmsr
224
225 .1:
226 StuffRsb64
227 rsm
228
229 _StmSmiHandler:
230 ;
231 ; Check XD disable bit
232 ;
233 xor r8, r8
234 lea rax, [ASM_PFX(gStmXdSupported)]
235 mov al, [rax]
236 cmp al, 0
237 jz @StmXdDone
238 mov ecx, MSR_IA32_MISC_ENABLE
239 rdmsr
240 mov r8, rdx ; save MSR_IA32_MISC_ENABLE[63-32]
241 test edx, BIT2 ; MSR_IA32_MISC_ENABLE[34]
242 jz .0
243 and dx, 0xFFFB ; clear XD Disable bit if it is set
244 wrmsr
245 .0:
246 mov ecx, MSR_EFER
247 rdmsr
248 or ax, MSR_EFER_XD ; enable NXE
249 wrmsr
250 @StmXdDone:
251 push r8
252
253 ; below step is needed, because STM does not run above code.
254 ; we have to run below code to set IDT/CR0/CR4
255 mov rax, strict qword 0 ; mov rax, ASM_PFX(gStmSmiHandlerIdtr)
256 StmSmiHandlerIdtrAbsAddr:
257 lidt [rax]
258
259 mov rax, cr0
260 or eax, 0x80010023 ; enable paging + WP + NE + MP + PE
261 mov cr0, rax
262 mov rax, cr4
263 mov eax, 0x668 ; as cr4.PGE is not set here, refresh cr3
264 mov cr4, rax ; in PreModifyMtrrs() to flush TLB.
265 ; STM init finish
266 jmp CommonHandler
267
268 ASM_PFX(gcStmSmiHandlerSize) : DW $ - _StmSmiEntryPoint
269 ASM_PFX(gcStmSmiHandlerOffset) : DW _StmSmiHandler - _StmSmiEntryPoint
270
271 global ASM_PFX(SmmCpuFeaturesLibStmSmiEntryFixupAddress)
272 ASM_PFX(SmmCpuFeaturesLibStmSmiEntryFixupAddress):
273 lea rax, [ASM_PFX(gStmSmiHandlerIdtr)]
274 lea rcx, [StmSmiEntrySmiHandlerIdtrAbsAddr]
275 mov qword [rcx - 8], rax
276 lea rcx, [StmSmiHandlerIdtrAbsAddr]
277 mov qword [rcx - 8], rax
278
279 lea rax, [CommonHandler]
280 lea rcx, [StmSmiEntryCommonHandlerAbsAddr]
281 mov qword [rcx - 8], rax
282 ret