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