]> git.proxmox.com Git - mirror_edk2.git/blame - UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.asm
SourceLevelDebugPkg: Remove X86 ASM and S files
[mirror_edk2.git] / UefiCpuPkg / Library / CpuExceptionHandlerLib / X64 / ExceptionHandlerAsm.asm
CommitLineData
8f07f895 1;------------------------------------------------------------------------------ ;\r
554dddfc 2; Copyright (c) 2012 - 2014, Intel Corporation. All rights reserved.<BR>\r
8f07f895 3; This program and the accompanying materials\r
4; are licensed and made available under the terms and conditions of the BSD License\r
5; which accompanies this distribution. The full text of the license may be found at\r
6; http://opensource.org/licenses/bsd-license.php.\r
7;\r
8; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
9; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
10;\r
11; Module Name:\r
12;\r
13; ExceptionHandlerAsm.Asm\r
14;\r
15; Abstract:\r
16;\r
17; x64 CPU Exception Handler\r
18;\r
19; Notes:\r
20;\r
21;------------------------------------------------------------------------------\r
22\r
23;\r
24; CommonExceptionHandler()\r
25;\r
782e407a 26externdef CommonExceptionHandler:near\r
8f07f895 27\r
e41aad15
JF
28EXTRN mErrorCodeFlag:DWORD ; Error code flags for exceptions\r
29EXTRN mDoFarReturnFlag:QWORD ; Do far return flag\r
8f07f895 30\r
31data SEGMENT\r
32\r
8f07f895 33.code\r
34\r
e41aad15
JF
35ALIGN 8\r
36\r
37AsmIdtVectorBegin:\r
38REPEAT 32\r
39 db 6ah ; push #VectorNum\r
40 db ($ - AsmIdtVectorBegin) / ((AsmIdtVectorEnd - AsmIdtVectorBegin) / 32) ; VectorNum\r
41 push rax\r
42 mov rax, CommonInterruptEntry\r
43 jmp rax\r
44ENDM\r
45AsmIdtVectorEnd:\r
46\r
47HookAfterStubHeaderBegin:\r
48 db 6ah ; push\r
49@VectorNum:\r
dd563742 50 db 0 ; 0 will be fixed\r
e41aad15
JF
51 push rax\r
52 mov rax, HookAfterStubHeaderEnd\r
53 jmp rax\r
54HookAfterStubHeaderEnd:\r
55 mov rax, rsp\r
554dddfc
JF
56 and sp, 0fff0h ; make sure 16-byte aligned for exception context\r
57 sub rsp, 18h ; reserve room for filling exception data later\r
e41aad15
JF
58 push rcx\r
59 mov rcx, [rax + 8]\r
60 bt mErrorCodeFlag, ecx\r
554dddfc 61 jnc @F\r
e41aad15
JF
62 push [rsp] ; push additional rcx to make stack alignment\r
63@@:\r
64 xchg rcx, [rsp] ; restore rcx, save Exception Number in stack\r
65 push [rax] ; push rax into stack to keep code consistence\r
8f07f895 66\r
67;---------------------------------------;\r
68; CommonInterruptEntry ;\r
69;---------------------------------------;\r
70; The follow algorithm is used for the common interrupt routine.\r
e41aad15
JF
71; Entry from each interrupt with a push eax and eax=interrupt number\r
72; Stack frame would be as follows as specified in IA32 manuals:\r
73;\r
74; +---------------------+ <-- 16-byte aligned ensured by processor\r
75; + Old SS +\r
76; +---------------------+\r
77; + Old RSP +\r
78; +---------------------+\r
79; + RFlags +\r
80; +---------------------+\r
81; + CS +\r
82; +---------------------+\r
83; + RIP +\r
84; +---------------------+\r
85; + Error Code +\r
86; +---------------------+\r
87; + Vector Number +\r
88; +---------------------+\r
89; + RBP +\r
90; +---------------------+ <-- RBP, 16-byte aligned\r
91; The follow algorithm is used for the common interrupt routine.\r
dd563742 92CommonInterruptEntry PROC PUBLIC\r
8f07f895 93 cli\r
e41aad15 94 pop rax\r
8f07f895 95 ;\r
96 ; All interrupt handlers are invoked through interrupt gates, so\r
97 ; IF flag automatically cleared at the entry point\r
98 ;\r
e41aad15
JF
99 xchg rcx, [rsp] ; Save rcx into stack and save vector number into rcx\r
100 and rcx, 0FFh\r
8f07f895 101 cmp ecx, 32 ; Intel reserved vector for exceptions?\r
102 jae NoErrorCode\r
103 bt mErrorCodeFlag, ecx\r
104 jc @F\r
105\r
106NoErrorCode:\r
107\r
108 ;\r
109 ; Push a dummy error code on the stack\r
110 ; to maintain coherent stack map\r
111 ;\r
112 push [rsp]\r
113 mov qword ptr [rsp + 8], 0\r
dd563742 114@@:\r
8f07f895 115 push rbp\r
116 mov rbp, rsp\r
e41aad15
JF
117 push 0 ; clear EXCEPTION_HANDLER_CONTEXT.OldIdtHandler\r
118 push 0 ; clear EXCEPTION_HANDLER_CONTEXT.ExceptionDataFlag\r
8f07f895 119\r
120 ;\r
121 ; Stack:\r
122 ; +---------------------+ <-- 16-byte aligned ensured by processor\r
123 ; + Old SS +\r
124 ; +---------------------+\r
125 ; + Old RSP +\r
126 ; +---------------------+\r
127 ; + RFlags +\r
128 ; +---------------------+\r
129 ; + CS +\r
130 ; +---------------------+\r
131 ; + RIP +\r
132 ; +---------------------+\r
133 ; + Error Code +\r
134 ; +---------------------+\r
135 ; + RCX / Vector Number +\r
136 ; +---------------------+\r
137 ; + RBP +\r
138 ; +---------------------+ <-- RBP, 16-byte aligned\r
139 ;\r
140\r
141\r
142 ;\r
143 ; Since here the stack pointer is 16-byte aligned, so\r
144 ; EFI_FX_SAVE_STATE_X64 of EFI_SYSTEM_CONTEXT_x64\r
145 ; is 16-byte aligned\r
146 ;\r
147\r
148;; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;\r
149;; UINT64 R8, R9, R10, R11, R12, R13, R14, R15;\r
150 push r15\r
151 push r14\r
152 push r13\r
153 push r12\r
154 push r11\r
155 push r10\r
156 push r9\r
157 push r8\r
158 push rax\r
159 push qword ptr [rbp + 8] ; RCX\r
160 push rdx\r
161 push rbx\r
162 push qword ptr [rbp + 48] ; RSP\r
163 push qword ptr [rbp] ; RBP\r
164 push rsi\r
165 push rdi\r
166\r
167;; UINT64 Gs, Fs, Es, Ds, Cs, Ss; insure high 16 bits of each is zero\r
168 movzx rax, word ptr [rbp + 56]\r
169 push rax ; for ss\r
170 movzx rax, word ptr [rbp + 32]\r
171 push rax ; for cs\r
172 mov rax, ds\r
173 push rax\r
174 mov rax, es\r
175 push rax\r
176 mov rax, fs\r
177 push rax\r
178 mov rax, gs\r
179 push rax\r
180\r
181 mov [rbp + 8], rcx ; save vector number\r
182\r
183;; UINT64 Rip;\r
184 push qword ptr [rbp + 24]\r
185\r
186;; UINT64 Gdtr[2], Idtr[2];\r
187 xor rax, rax\r
188 push rax\r
189 push rax\r
190 sidt [rsp]\r
191 xchg rax, [rsp + 2]\r
192 xchg rax, [rsp]\r
193 xchg rax, [rsp + 8]\r
194\r
195 xor rax, rax\r
196 push rax\r
197 push rax\r
198 sgdt [rsp]\r
199 xchg rax, [rsp + 2]\r
200 xchg rax, [rsp]\r
201 xchg rax, [rsp + 8]\r
202\r
203;; UINT64 Ldtr, Tr;\r
204 xor rax, rax\r
205 str ax\r
206 push rax\r
207 sldt ax\r
208 push rax\r
209\r
210;; UINT64 RFlags;\r
211 push qword ptr [rbp + 40]\r
212\r
213;; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;\r
214 mov rax, cr8\r
215 push rax\r
216 mov rax, cr4\r
217 or rax, 208h\r
218 mov cr4, rax\r
219 push rax\r
220 mov rax, cr3\r
221 push rax\r
222 mov rax, cr2\r
223 push rax\r
224 xor rax, rax\r
225 push rax\r
226 mov rax, cr0\r
227 push rax\r
228\r
229;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
230 mov rax, dr7\r
231 push rax\r
232 mov rax, dr6\r
233 push rax\r
234 mov rax, dr3\r
235 push rax\r
236 mov rax, dr2\r
237 push rax\r
238 mov rax, dr1\r
239 push rax\r
240 mov rax, dr0\r
241 push rax\r
242\r
243;; FX_SAVE_STATE_X64 FxSaveState;\r
244 sub rsp, 512\r
245 mov rdi, rsp\r
246 db 0fh, 0aeh, 07h ;fxsave [rdi]\r
247\r
248;; UEFI calling convention for x64 requires that Direction flag in EFLAGs is clear\r
249 cld\r
250\r
251;; UINT32 ExceptionData;\r
252 push qword ptr [rbp + 16]\r
253\r
254;; Prepare parameter and call\r
255 mov rcx, [rbp + 8]\r
256 mov rdx, rsp\r
257 ;\r
258 ; Per X64 calling convention, allocate maximum parameter stack space\r
259 ; and make sure RSP is 16-byte aligned\r
260 ;\r
261 sub rsp, 4 * 8 + 8\r
262 mov rax, CommonExceptionHandler\r
263 call rax\r
264 add rsp, 4 * 8 + 8\r
265\r
266 cli\r
267;; UINT64 ExceptionData;\r
268 add rsp, 8\r
269\r
270;; FX_SAVE_STATE_X64 FxSaveState;\r
271\r
272 mov rsi, rsp\r
273 db 0fh, 0aeh, 0Eh ; fxrstor [rsi]\r
274 add rsp, 512\r
275\r
276;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
277;; Skip restoration of DRx registers to support in-circuit emualators\r
278;; or debuggers set breakpoint in interrupt/exception context\r
279 add rsp, 8 * 6\r
280\r
281;; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;\r
282 pop rax\r
283 mov cr0, rax\r
284 add rsp, 8 ; not for Cr1\r
285 pop rax\r
286 mov cr2, rax\r
287 pop rax\r
288 mov cr3, rax\r
289 pop rax\r
290 mov cr4, rax\r
291 pop rax\r
292 mov cr8, rax\r
293\r
294;; UINT64 RFlags;\r
295 pop qword ptr [rbp + 40]\r
296\r
297;; UINT64 Ldtr, Tr;\r
298;; UINT64 Gdtr[2], Idtr[2];\r
299;; Best not let anyone mess with these particular registers...\r
300 add rsp, 48\r
301\r
302;; UINT64 Rip;\r
303 pop qword ptr [rbp + 24]\r
304\r
305;; UINT64 Gs, Fs, Es, Ds, Cs, Ss;\r
306 pop rax\r
307 ; mov gs, rax ; not for gs\r
308 pop rax\r
309 ; mov fs, rax ; not for fs\r
310 ; (X64 will not use fs and gs, so we do not restore it)\r
311 pop rax\r
312 mov es, rax\r
313 pop rax\r
314 mov ds, rax\r
315 pop qword ptr [rbp + 32] ; for cs\r
316 pop qword ptr [rbp + 56] ; for ss\r
317\r
318;; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;\r
319;; UINT64 R8, R9, R10, R11, R12, R13, R14, R15;\r
320 pop rdi\r
321 pop rsi\r
322 add rsp, 8 ; not for rbp\r
323 pop qword ptr [rbp + 48] ; for rsp\r
324 pop rbx\r
325 pop rdx\r
326 pop rcx\r
327 pop rax\r
328 pop r8\r
329 pop r9\r
330 pop r10\r
331 pop r11\r
332 pop r12\r
333 pop r13\r
334 pop r14\r
335 pop r15\r
336\r
337 mov rsp, rbp\r
338 pop rbp\r
339 add rsp, 16\r
e41aad15
JF
340 cmp qword ptr [rsp - 32], 0 ; check EXCEPTION_HANDLER_CONTEXT.OldIdtHandler\r
341 jz DoReturn\r
342 cmp qword ptr [rsp - 40], 1 ; check EXCEPTION_HANDLER_CONTEXT.ExceptionDataFlag\r
343 jz ErrorCode\r
344 jmp qword ptr [rsp - 32]\r
345ErrorCode:\r
346 sub rsp, 8\r
347 jmp qword ptr [rsp - 24]\r
348\r
349DoReturn:\r
350 cmp mDoFarReturnFlag, 0 ; Check if need to do far return instead of IRET\r
351 jz DoIret\r
352 push rax\r
353 mov rax, rsp ; save old RSP to rax\r
dd563742 354 mov rsp, [rsp + 20h]\r
e41aad15
JF
355 push [rax + 10h] ; save CS in new location\r
356 push [rax + 8h] ; save EIP in new location\r
357 push [rax + 18h] ; save EFLAGS in new location\r
358 mov rax, [rax] ; restore rax\r
359 popfq ; restore EFLAGS\r
360 DB 48h ; prefix to composite "retq" with next "retf"\r
361 retf ; far return\r
362DoIret:\r
8f07f895 363 iretq\r
364\r
365CommonInterruptEntry ENDP\r
366\r
367;-------------------------------------------------------------------------------------\r
368; GetTemplateAddressMap (&AddressMap);\r
369;-------------------------------------------------------------------------------------\r
370; comments here for definition of address map\r
e41aad15
JF
371AsmGetTemplateAddressMap PROC\r
372 mov rax, offset AsmIdtVectorBegin\r
373 mov qword ptr [rcx], rax\r
374 mov qword ptr [rcx + 8h], (AsmIdtVectorEnd - AsmIdtVectorBegin) / 32\r
375 mov rax, offset HookAfterStubHeaderBegin\r
376 mov qword ptr [rcx + 10h], rax\r
377 ret\r
378AsmGetTemplateAddressMap ENDP\r
379\r
380;-------------------------------------------------------------------------------------\r
07da1ac8 381; AsmVectorNumFixup (*NewVectorAddr, VectorNum, *OldVectorAddr);\r
e41aad15
JF
382;-------------------------------------------------------------------------------------\r
383AsmVectorNumFixup PROC\r
384 mov rax, rdx\r
385 mov [rcx + (@VectorNum - HookAfterStubHeaderBegin)], al\r
386 ret\r
387AsmVectorNumFixup ENDP\r
8f07f895 388\r
389END\r