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