]> git.proxmox.com Git - mirror_edk2.git/blob - UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiException.nasm
UefiCpuPkg/PiSmmCpuDxeSmm: patch "gSmbase" with PatchInstructionX86()
[mirror_edk2.git] / UefiCpuPkg / PiSmmCpuDxeSmm / X64 / SmiException.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 ; SmiException.nasm
14 ;
15 ; Abstract:
16 ;
17 ; Exception handlers used in SM mode
18 ;
19 ;-------------------------------------------------------------------------------
20
21 extern ASM_PFX(SmiPFHandler)
22
23 global ASM_PFX(gcSmiIdtr)
24 global ASM_PFX(gcSmiGdtr)
25 global ASM_PFX(gcPsd)
26
27 SECTION .data
28
29 NullSeg: DQ 0 ; reserved by architecture
30 CodeSeg32:
31 DW -1 ; LimitLow
32 DW 0 ; BaseLow
33 DB 0 ; BaseMid
34 DB 0x9b
35 DB 0xcf ; LimitHigh
36 DB 0 ; BaseHigh
37 ProtModeCodeSeg32:
38 DW -1 ; LimitLow
39 DW 0 ; BaseLow
40 DB 0 ; BaseMid
41 DB 0x9b
42 DB 0xcf ; LimitHigh
43 DB 0 ; BaseHigh
44 ProtModeSsSeg32:
45 DW -1 ; LimitLow
46 DW 0 ; BaseLow
47 DB 0 ; BaseMid
48 DB 0x93
49 DB 0xcf ; LimitHigh
50 DB 0 ; BaseHigh
51 DataSeg32:
52 DW -1 ; LimitLow
53 DW 0 ; BaseLow
54 DB 0 ; BaseMid
55 DB 0x93
56 DB 0xcf ; LimitHigh
57 DB 0 ; BaseHigh
58 CodeSeg16:
59 DW -1
60 DW 0
61 DB 0
62 DB 0x9b
63 DB 0x8f
64 DB 0
65 DataSeg16:
66 DW -1
67 DW 0
68 DB 0
69 DB 0x93
70 DB 0x8f
71 DB 0
72 CodeSeg64:
73 DW -1 ; LimitLow
74 DW 0 ; BaseLow
75 DB 0 ; BaseMid
76 DB 0x9b
77 DB 0xaf ; LimitHigh
78 DB 0 ; BaseHigh
79 ; TSS Segment for X64 specially
80 TssSeg:
81 DW TSS_DESC_SIZE ; LimitLow
82 DW 0 ; BaseLow
83 DB 0 ; BaseMid
84 DB 0x89
85 DB 0x80 ; LimitHigh
86 DB 0 ; BaseHigh
87 DD 0 ; BaseUpper
88 DD 0 ; Reserved
89 GDT_SIZE equ $ - NullSeg
90
91 ; Create TSS Descriptor just after GDT
92 TssDescriptor:
93 DD 0 ; Reserved
94 DQ 0 ; RSP0
95 DQ 0 ; RSP1
96 DQ 0 ; RSP2
97 DD 0 ; Reserved
98 DD 0 ; Reserved
99 DQ 0 ; IST1
100 DQ 0 ; IST2
101 DQ 0 ; IST3
102 DQ 0 ; IST4
103 DQ 0 ; IST5
104 DQ 0 ; IST6
105 DQ 0 ; IST7
106 DD 0 ; Reserved
107 DD 0 ; Reserved
108 DW 0 ; Reserved
109 DW 0 ; I/O Map Base Address
110 TSS_DESC_SIZE equ $ - TssDescriptor
111
112 ;
113 ; This structure serves as a template for all processors.
114 ;
115 ASM_PFX(gcPsd):
116 DB 'PSDSIG '
117 DW PSD_SIZE
118 DW 2
119 DW 1 << 2
120 DW CODE_SEL
121 DW DATA_SEL
122 DW DATA_SEL
123 DW DATA_SEL
124 DW 0
125 DQ 0
126 DQ 0
127 DQ 0 ; fixed in InitializeMpServiceData()
128 DQ NullSeg
129 DD GDT_SIZE
130 DD 0
131 times 24 DB 0
132 DQ 0
133 PSD_SIZE equ $ - ASM_PFX(gcPsd)
134
135 ;
136 ; CODE & DATA segments for SMM runtime
137 ;
138 CODE_SEL equ CodeSeg64 - NullSeg
139 DATA_SEL equ DataSeg32 - NullSeg
140 CODE32_SEL equ CodeSeg32 - NullSeg
141
142 ASM_PFX(gcSmiGdtr):
143 DW GDT_SIZE - 1
144 DQ NullSeg
145
146 ASM_PFX(gcSmiIdtr):
147 DW 0
148 DQ 0
149
150 DEFAULT REL
151 SECTION .text
152
153 ;------------------------------------------------------------------------------
154 ; _SmiExceptionEntryPoints is the collection of exception entrypoints followed
155 ; by a common exception handler.
156 ;
157 ; Stack frame would be as follows as specified in IA32 manuals:
158 ;
159 ; +---------------------+ <-- 16-byte aligned ensured by processor
160 ; + Old SS +
161 ; +---------------------+
162 ; + Old RSP +
163 ; +---------------------+
164 ; + RFlags +
165 ; +---------------------+
166 ; + CS +
167 ; +---------------------+
168 ; + RIP +
169 ; +---------------------+
170 ; + Error Code +
171 ; +---------------------+
172 ; + Vector Number +
173 ; +---------------------+
174 ; + RBP +
175 ; +---------------------+ <-- RBP, 16-byte aligned
176 ;
177 ; RSP set to odd multiple of 8 at @CommonEntryPoint means ErrCode PRESENT
178 ;------------------------------------------------------------------------------
179 global ASM_PFX(PageFaultIdtHandlerSmmProfile)
180 ASM_PFX(PageFaultIdtHandlerSmmProfile):
181 push 0xe ; Page Fault
182 test spl, 8 ; odd multiple of 8 => ErrCode present
183 jnz .0
184 push qword [rsp] ; duplicate INT# if no ErrCode
185 mov qword [rsp + 8], 0
186 .0:
187 push rbp
188 mov rbp, rsp
189
190 ;
191 ; Since here the stack pointer is 16-byte aligned, so
192 ; EFI_FX_SAVE_STATE_X64 of EFI_SYSTEM_CONTEXT_x64
193 ; is 16-byte aligned
194 ;
195
196 ;; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;
197 ;; UINT64 R8, R9, R10, R11, R12, R13, R14, R15;
198 push r15
199 push r14
200 push r13
201 push r12
202 push r11
203 push r10
204 push r9
205 push r8
206 push rax
207 push rcx
208 push rdx
209 push rbx
210 push qword [rbp + 48] ; RSP
211 push qword [rbp] ; RBP
212 push rsi
213 push rdi
214
215 ;; UINT64 Gs, Fs, Es, Ds, Cs, Ss; insure high 16 bits of each is zero
216 movzx rax, word [rbp + 56]
217 push rax ; for ss
218 movzx rax, word [rbp + 32]
219 push rax ; for cs
220 mov rax, ds
221 push rax
222 mov rax, es
223 push rax
224 mov rax, fs
225 push rax
226 mov rax, gs
227 push rax
228
229 ;; UINT64 Rip;
230 push qword [rbp + 24]
231
232 ;; UINT64 Gdtr[2], Idtr[2];
233 sub rsp, 16
234 sidt [rsp]
235 sub rsp, 16
236 sgdt [rsp]
237
238 ;; UINT64 Ldtr, Tr;
239 xor rax, rax
240 str ax
241 push rax
242 sldt ax
243 push rax
244
245 ;; UINT64 RFlags;
246 push qword [rbp + 40]
247
248 ;; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;
249 mov rax, cr8
250 push rax
251 mov rax, cr4
252 or rax, 0x208
253 mov cr4, rax
254 push rax
255 mov rax, cr3
256 push rax
257 mov rax, cr2
258 push rax
259 xor rax, rax
260 push rax
261 mov rax, cr0
262 push rax
263
264 ;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
265 mov rax, dr7
266 push rax
267 mov rax, dr6
268 push rax
269 mov rax, dr3
270 push rax
271 mov rax, dr2
272 push rax
273 mov rax, dr1
274 push rax
275 mov rax, dr0
276 push rax
277
278 ;; FX_SAVE_STATE_X64 FxSaveState;
279
280 sub rsp, 512
281 mov rdi, rsp
282 db 0xf, 0xae, 00000111y ;fxsave [rdi]
283
284 ; UEFI calling convention for x64 requires that Direction flag in EFLAGs is clear
285 cld
286
287 ;; UINT32 ExceptionData;
288 push qword [rbp + 16]
289
290 ;; call into exception handler
291 mov rcx, [rbp + 8]
292 lea rax, [ASM_PFX(SmiPFHandler)]
293
294 ;; Prepare parameter and call
295 mov rdx, rsp
296 ;
297 ; Per X64 calling convention, allocate maximum parameter stack space
298 ; and make sure RSP is 16-byte aligned
299 ;
300 sub rsp, 4 * 8 + 8
301 call rax
302 add rsp, 4 * 8 + 8
303 jmp .1
304
305 .1:
306 ;; UINT64 ExceptionData;
307 add rsp, 8
308
309 ;; FX_SAVE_STATE_X64 FxSaveState;
310
311 mov rsi, rsp
312 db 0xf, 0xae, 00001110y ; fxrstor [rsi]
313 add rsp, 512
314
315 ;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
316 ;; Skip restoration of DRx registers to support debuggers
317 ;; that set breakpoints in interrupt/exception context
318 add rsp, 8 * 6
319
320 ;; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;
321 pop rax
322 mov cr0, rax
323 add rsp, 8 ; not for Cr1
324 pop rax
325 mov cr2, rax
326 pop rax
327 mov cr3, rax
328 pop rax
329 mov cr4, rax
330 pop rax
331 mov cr8, rax
332
333 ;; UINT64 RFlags;
334 pop qword [rbp + 40]
335
336 ;; UINT64 Ldtr, Tr;
337 ;; UINT64 Gdtr[2], Idtr[2];
338 ;; Best not let anyone mess with these particular registers...
339 add rsp, 48
340
341 ;; UINT64 Rip;
342 pop qword [rbp + 24]
343
344 ;; UINT64 Gs, Fs, Es, Ds, Cs, Ss;
345 pop rax
346 ; mov gs, rax ; not for gs
347 pop rax
348 ; mov fs, rax ; not for fs
349 ; (X64 will not use fs and gs, so we do not restore it)
350 pop rax
351 mov es, rax
352 pop rax
353 mov ds, rax
354 pop qword [rbp + 32] ; for cs
355 pop qword [rbp + 56] ; for ss
356
357 ;; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;
358 ;; UINT64 R8, R9, R10, R11, R12, R13, R14, R15;
359 pop rdi
360 pop rsi
361 add rsp, 8 ; not for rbp
362 pop qword [rbp + 48] ; for rsp
363 pop rbx
364 pop rdx
365 pop rcx
366 pop rax
367 pop r8
368 pop r9
369 pop r10
370 pop r11
371 pop r12
372 pop r13
373 pop r14
374 pop r15
375
376 mov rsp, rbp
377
378 ; Enable TF bit after page fault handler runs
379 bts dword [rsp + 40], 8 ;RFLAGS
380
381 pop rbp
382 add rsp, 16 ; skip INT# & ErrCode
383 iretq
384