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