VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/SecPeiExceptionHandlerAsm.nasm

最後變更 在這個檔案是 101291,由 vboxsync 提交於 18 月 前

EFI/FirmwareNew: Make edk2-stable202308 build on all supported platforms (using gcc at least, msvc not tested yet), bugref:4643

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:mime-type 設為 text/x-asm
檔案大小: 10.4 KB
 
1;------------------------------------------------------------------------------ ;
2; Copyright (c) 2012 - 2022, Intel Corporation. All rights reserved.<BR>
3; SPDX-License-Identifier: BSD-2-Clause-Patent
4;
5; Module Name:
6;
7; ExceptionHandlerAsm.Asm
8;
9; Abstract:
10;
11; x64 CPU Exception Handler
12;
13; Notes:
14;
15;------------------------------------------------------------------------------
16
17;
18; CommonExceptionHandler()
19;
20
21%define VC_EXCEPTION 29
22
23extern ASM_PFX(mErrorCodeFlag) ; Error code flags for exceptions
24extern ASM_PFX(mDoFarReturnFlag) ; Do far return flag
25extern ASM_PFX(CommonExceptionHandler)
26
27SECTION .data
28
29DEFAULT REL
30%ifndef NO_ABSOLUTE_RELOCS_IN_TEXT
31SECTION .text
32%endif
33
34ALIGN 8
35
36; Generate 32 IDT vectors.
37; 32 IDT vectors are enough because interrupts (32+) are not enabled in SEC and PEI phase.
38AsmIdtVectorBegin:
39%assign Vector 0
40%rep 32
41 push byte %[Vector]
42 push rax
43 mov rax, ASM_PFX(CommonInterruptEntry)
44 jmp rax
45%assign Vector Vector+1
46%endrep
47AsmIdtVectorEnd:
48
49HookAfterStubHeaderBegin:
50 db 0x6a ; push
51@VectorNum:
52 db 0 ; 0 will be fixed
53 push rax
54 mov rax, HookAfterStubHeaderEnd
55 jmp rax
56
57SECTION .text
58
59HookAfterStubHeaderEnd:
60 mov rax, rsp
61 and sp, 0xfff0 ; make sure 16-byte aligned for exception context
62 sub rsp, 0x18 ; reserve room for filling exception data later
63 push rcx
64 mov rcx, [rax + 8]
65 bt [ASM_PFX(mErrorCodeFlag)], ecx
66 jnc .0
67 push qword [rsp] ; push additional rcx to make stack alignment
68.0:
69 xchg rcx, [rsp] ; restore rcx, save Exception Number in stack
70 push qword [rax] ; push rax into stack to keep code consistence
71
72;---------------------------------------;
73; CommonInterruptEntry ;
74;---------------------------------------;
75; The follow algorithm is used for the common interrupt routine.
76; Entry from each interrupt with a push eax and eax=interrupt number
77; Stack frame would be as follows as specified in IA32 manuals:
78;
79; +---------------------+ <-- 16-byte aligned ensured by processor
80; + Old SS +
81; +---------------------+
82; + Old RSP +
83; +---------------------+
84; + RFlags +
85; +---------------------+
86; + CS +
87; +---------------------+
88; + RIP +
89; +---------------------+
90; + Error Code +
91; +---------------------+
92; + Vector Number +
93; +---------------------+
94; + RBP +
95; +---------------------+ <-- RBP, 16-byte aligned
96; The follow algorithm is used for the common interrupt routine.
97global ASM_PFX(CommonInterruptEntry)
98ASM_PFX(CommonInterruptEntry):
99 cli
100 pop rax
101 ;
102 ; All interrupt handlers are invoked through interrupt gates, so
103 ; IF flag automatically cleared at the entry point
104 ;
105 xchg rcx, [rsp] ; Save rcx into stack and save vector number into rcx
106 and rcx, 0xFF
107 cmp ecx, 32 ; Intel reserved vector for exceptions?
108 jae NoErrorCode
109 bt [ASM_PFX(mErrorCodeFlag)], ecx
110 jc HasErrorCode
111
112NoErrorCode:
113
114 ;
115 ; Push a dummy error code on the stack
116 ; to maintain coherent stack map
117 ;
118 push qword [rsp]
119 mov qword [rsp + 8], 0
120HasErrorCode:
121 push rbp
122 mov rbp, rsp
123 push 0 ; clear EXCEPTION_HANDLER_CONTEXT.OldIdtHandler
124 push 0 ; clear EXCEPTION_HANDLER_CONTEXT.ExceptionDataFlag
125
126 ;
127 ; Stack:
128 ; +---------------------+ <-- 16-byte aligned ensured by processor
129 ; + Old SS +
130 ; +---------------------+
131 ; + Old RSP +
132 ; +---------------------+
133 ; + RFlags +
134 ; +---------------------+
135 ; + CS +
136 ; +---------------------+
137 ; + RIP +
138 ; +---------------------+
139 ; + Error Code +
140 ; +---------------------+
141 ; + RCX / Vector Number +
142 ; +---------------------+
143 ; + RBP +
144 ; +---------------------+ <-- RBP, 16-byte aligned
145 ;
146
147 ;
148 ; Since here the stack pointer is 16-byte aligned, so
149 ; EFI_FX_SAVE_STATE_X64 of EFI_SYSTEM_CONTEXT_x64
150 ; is 16-byte aligned
151 ;
152
153;; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;
154;; UINT64 R8, R9, R10, R11, R12, R13, R14, R15;
155 push r15
156 push r14
157 push r13
158 push r12
159 push r11
160 push r10
161 push r9
162 push r8
163 push rax
164 push qword [rbp + 8] ; RCX
165 push rdx
166 push rbx
167 push qword [rbp + 48] ; RSP
168 push qword [rbp] ; RBP
169 push rsi
170 push rdi
171
172;; UINT64 Gs, Fs, Es, Ds, Cs, Ss; insure high 16 bits of each is zero
173 movzx rax, word [rbp + 56]
174 push rax ; for ss
175 movzx rax, word [rbp + 32]
176 push rax ; for cs
177 mov rax, ds
178 push rax
179 mov rax, es
180 push rax
181 mov rax, fs
182 push rax
183 mov rax, gs
184 push rax
185
186 mov [rbp + 8], rcx ; save vector number
187
188;; UINT64 Rip;
189 push qword [rbp + 24]
190
191;; UINT64 Gdtr[2], Idtr[2];
192 xor rax, rax
193 push rax
194 push rax
195 sidt [rsp]
196 mov bx, word [rsp]
197 mov rax, qword [rsp + 2]
198 mov qword [rsp], rax
199 mov word [rsp + 8], bx
200
201 xor rax, rax
202 push rax
203 push rax
204 sgdt [rsp]
205 mov bx, word [rsp]
206 mov rax, qword [rsp + 2]
207 mov qword [rsp], rax
208 mov word [rsp + 8], bx
209
210;; UINT64 Ldtr, Tr;
211 xor rax, rax
212 str ax
213 push rax
214 sldt ax
215 push rax
216
217;; UINT64 RFlags;
218 push qword [rbp + 40]
219
220;; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;
221 mov rax, cr8
222 push rax
223 mov rax, cr4
224 or rax, 0x208
225 mov cr4, rax
226 push rax
227 mov rax, cr3
228 push rax
229 mov rax, cr2
230 push rax
231 xor rax, rax
232 push rax
233 mov rax, cr0
234 push rax
235
236;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
237 cmp qword [rbp + 8], VC_EXCEPTION
238 je VcDebugRegs ; For SEV-ES (#VC) Debug registers ignored
239
240 mov rax, dr7
241 push rax
242 mov rax, dr6
243 push rax
244 mov rax, dr3
245 push rax
246 mov rax, dr2
247 push rax
248 mov rax, dr1
249 push rax
250 mov rax, dr0
251 push rax
252 jmp DrFinish
253
254VcDebugRegs:
255;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7 are skipped for #VC to avoid exception recursion
256 xor rax, rax
257 push rax
258 push rax
259 push rax
260 push rax
261 push rax
262 push rax
263
264DrFinish:
265;; FX_SAVE_STATE_X64 FxSaveState;
266 sub rsp, 512
267 mov rdi, rsp
268 fxsave [rdi]
269
270;; UEFI calling convention for x64 requires that Direction flag in EFLAGs is clear
271 cld
272
273;; UINT32 ExceptionData;
274 push qword [rbp + 16]
275
276;; Prepare parameter and call
277 mov rcx, [rbp + 8]
278 mov rdx, rsp
279 ;
280 ; Per X64 calling convention, allocate maximum parameter stack space
281 ; and make sure RSP is 16-byte aligned
282 ;
283 sub rsp, 4 * 8 + 8
284 call ASM_PFX(CommonExceptionHandler)
285 add rsp, 4 * 8 + 8
286
287 cli
288;; UINT64 ExceptionData;
289 add rsp, 8
290
291;; FX_SAVE_STATE_X64 FxSaveState;
292
293 mov rsi, rsp
294 fxrstor [rsi]
295 add rsp, 512
296
297;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
298;; Skip restoration of DRx registers to support in-circuit emualators
299;; or debuggers set breakpoint in interrupt/exception context
300 add rsp, 8 * 6
301
302;; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;
303 pop rax
304 mov cr0, rax
305 add rsp, 8 ; not for Cr1
306 pop rax
307 mov cr2, rax
308 pop rax
309 mov cr3, rax
310 pop rax
311 mov cr4, rax
312 pop rax
313 mov cr8, rax
314
315;; UINT64 RFlags;
316 pop qword [rbp + 40]
317
318;; UINT64 Ldtr, Tr;
319;; UINT64 Gdtr[2], Idtr[2];
320;; Best not let anyone mess with these particular registers...
321 add rsp, 48
322
323;; UINT64 Rip;
324 pop qword [rbp + 24]
325
326;; UINT64 Gs, Fs, Es, Ds, Cs, Ss;
327 pop rax
328 ; mov gs, rax ; not for gs
329 pop rax
330 ; mov fs, rax ; not for fs
331 ; (X64 will not use fs and gs, so we do not restore it)
332 pop rax
333 mov es, rax
334 pop rax
335 mov ds, rax
336 pop qword [rbp + 32] ; for cs
337 pop qword [rbp + 56] ; for ss
338
339;; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;
340;; UINT64 R8, R9, R10, R11, R12, R13, R14, R15;
341 pop rdi
342 pop rsi
343 add rsp, 8 ; not for rbp
344 pop qword [rbp + 48] ; for rsp
345 pop rbx
346 pop rdx
347 pop rcx
348 pop rax
349 pop r8
350 pop r9
351 pop r10
352 pop r11
353 pop r12
354 pop r13
355 pop r14
356 pop r15
357
358 mov rsp, rbp
359 pop rbp
360 add rsp, 16
361 cmp qword [rsp - 32], 0 ; check EXCEPTION_HANDLER_CONTEXT.OldIdtHandler
362 jz DoReturn
363 cmp qword [rsp - 40], 1 ; check EXCEPTION_HANDLER_CONTEXT.ExceptionDataFlag
364 jz ErrorCode
365 jmp qword [rsp - 32]
366ErrorCode:
367 sub rsp, 8
368 jmp qword [rsp - 24]
369
370DoReturn:
371 cmp qword [ASM_PFX(mDoFarReturnFlag)], 0 ; Check if need to do far return instead of IRET
372 jz DoIret
373 push rax
374 mov rax, rsp ; save old RSP to rax
375 mov rsp, [rsp + 0x20]
376 push qword [rax + 0x10] ; save CS in new location
377 push qword [rax + 0x8] ; save EIP in new location
378 push qword [rax + 0x18] ; save EFLAGS in new location
379 mov rax, [rax] ; restore rax
380 popfq ; restore EFLAGS
381 retfq
382DoIret:
383 iretq
384
385;-------------------------------------------------------------------------------------
386; GetTemplateAddressMap (&AddressMap);
387;-------------------------------------------------------------------------------------
388; comments here for definition of address map
389global ASM_PFX(AsmGetTemplateAddressMap)
390ASM_PFX(AsmGetTemplateAddressMap):
391 lea rax, [AsmIdtVectorBegin]
392 mov qword [rcx], rax
393 mov qword [rcx + 0x8], (AsmIdtVectorEnd - AsmIdtVectorBegin) / 32
394 lea rax, [HookAfterStubHeaderBegin]
395 mov qword [rcx + 0x10], rax
396 ret
397
398;-------------------------------------------------------------------------------------
399; AsmVectorNumFixup (*NewVectorAddr, VectorNum, *OldVectorAddr);
400;-------------------------------------------------------------------------------------
401global ASM_PFX(AsmVectorNumFixup)
402ASM_PFX(AsmVectorNumFixup):
403 mov rax, rdx
404 mov [rcx + (@VectorNum - HookAfterStubHeaderBegin)], al
405 ret
406
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette