]> git.proxmox.com Git - mirror_edk2.git/blame - UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.asm
Fix build issue on DDK3790 tool chain.
[mirror_edk2.git] / UefiCpuPkg / Library / CpuExceptionHandlerLib / X64 / ExceptionHandlerAsm.asm
CommitLineData
8f07f895 1;------------------------------------------------------------------------------ ;\r
782e407a 2; Copyright (c) 2012 - 2013, 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
28EXTRN mErrorCodeFlag:DWORD ; Error code flags for exceptions\r
29\r
30data SEGMENT\r
31\r
32CommonEntryAddr dq CommonInterruptEntry;\r
33\r
34.code\r
35\r
36Exception0Handle:\r
37 push 0\r
38 jmp qword ptr [CommonEntryAddr]\r
39Exception1Handle:\r
40 push 1\r
41 jmp qword ptr [CommonEntryAddr]\r
42Exception2Handle:\r
43 push 2\r
44 jmp qword ptr [CommonEntryAddr]\r
45Exception3Handle:\r
46 push 3\r
47 jmp qword ptr [CommonEntryAddr]\r
48Exception4Handle:\r
49 push 4\r
50 jmp qword ptr [CommonEntryAddr]\r
51Exception5Handle:\r
52 push 5\r
53 jmp qword ptr [CommonEntryAddr]\r
54Exception6Handle:\r
55 push 6\r
56 jmp qword ptr [CommonEntryAddr]\r
57Exception7Handle:\r
58 push 7\r
59 jmp qword ptr [CommonEntryAddr]\r
60Exception8Handle:\r
61 push 8\r
62 jmp qword ptr [CommonEntryAddr]\r
63Exception9Handle:\r
64 push 9\r
65 jmp qword ptr [CommonEntryAddr]\r
66Exception10Handle:\r
67 push 10\r
68 jmp qword ptr [CommonEntryAddr]\r
69Exception11Handle:\r
70 push 11\r
71 jmp qword ptr [CommonEntryAddr]\r
72Exception12Handle:\r
73 push 12\r
74 jmp qword ptr [CommonEntryAddr]\r
75Exception13Handle:\r
76 push 13\r
77 jmp qword ptr [CommonEntryAddr]\r
78Exception14Handle:\r
79 push 14\r
80 jmp qword ptr [CommonEntryAddr]\r
81Exception15Handle:\r
82 push 15\r
83 jmp qword ptr [CommonEntryAddr]\r
84Exception16Handle:\r
85 push 16\r
86 jmp qword ptr [CommonEntryAddr]\r
87Exception17Handle:\r
88 push 17\r
89 jmp qword ptr [CommonEntryAddr]\r
90Exception18Handle:\r
91 push 18\r
92 jmp qword ptr [CommonEntryAddr]\r
93Exception19Handle:\r
94 push 19\r
95 jmp qword ptr [CommonEntryAddr]\r
96Exception20Handle:\r
97 push 20\r
98 jmp qword ptr [CommonEntryAddr]\r
99Exception21Handle:\r
100 push 21\r
101 jmp qword ptr [CommonEntryAddr]\r
102Exception22Handle:\r
103 push 22\r
104 jmp qword ptr [CommonEntryAddr]\r
105Exception23Handle:\r
106 push 23\r
107 jmp qword ptr [CommonEntryAddr]\r
108Exception24Handle:\r
109 push 24\r
110 jmp qword ptr [CommonEntryAddr]\r
111Exception25Handle:\r
112 push 25\r
113 jmp qword ptr [CommonEntryAddr]\r
114Exception26Handle:\r
115 push 26\r
116 jmp qword ptr [CommonEntryAddr]\r
117Exception27Handle:\r
118 push 27\r
119 jmp qword ptr [CommonEntryAddr]\r
120Exception28Handle:\r
121 push 28\r
122 jmp qword ptr [CommonEntryAddr]\r
123Exception29Handle:\r
124 push 29\r
125 jmp qword ptr [CommonEntryAddr]\r
126Exception30Handle:\r
127 push 30\r
128 jmp qword ptr [CommonEntryAddr]\r
129Exception31Handle:\r
130 push 31\r
131 jmp qword ptr [CommonEntryAddr]\r
132\r
133;CommonInterruptEntrypoint:\r
134;---------------------------------------;\r
135; _CommonEntry ;\r
136;----------------------------------------------------------------------------;\r
137; The follow algorithm is used for the common interrupt routine.\r
138; Entry from each interrupt with a push eax and eax=interrupt number\r
139\r
140;---------------------------------------;\r
141; CommonInterruptEntry ;\r
142;---------------------------------------;\r
143; The follow algorithm is used for the common interrupt routine.\r
144\r
145CommonInterruptEntry PROC PUBLIC \r
146 cli\r
147 ;\r
148 ; All interrupt handlers are invoked through interrupt gates, so\r
149 ; IF flag automatically cleared at the entry point\r
150 ;\r
151 ;\r
152 ; Calculate vector number\r
153 ;\r
154 xchg rcx, [rsp] ; get the return address of call, actually, it is the address of vector number.\r
155 cmp ecx, 32 ; Intel reserved vector for exceptions?\r
156 jae NoErrorCode\r
157 bt mErrorCodeFlag, ecx\r
158 jc @F\r
159\r
160NoErrorCode:\r
161\r
162 ;\r
163 ; Push a dummy error code on the stack\r
164 ; to maintain coherent stack map\r
165 ;\r
166 push [rsp]\r
167 mov qword ptr [rsp + 8], 0\r
168@@: \r
169 push rbp\r
170 mov rbp, rsp\r
171\r
172 ;\r
173 ; Stack:\r
174 ; +---------------------+ <-- 16-byte aligned ensured by processor\r
175 ; + Old SS +\r
176 ; +---------------------+\r
177 ; + Old RSP +\r
178 ; +---------------------+\r
179 ; + RFlags +\r
180 ; +---------------------+\r
181 ; + CS +\r
182 ; +---------------------+\r
183 ; + RIP +\r
184 ; +---------------------+\r
185 ; + Error Code +\r
186 ; +---------------------+\r
187 ; + RCX / Vector Number +\r
188 ; +---------------------+\r
189 ; + RBP +\r
190 ; +---------------------+ <-- RBP, 16-byte aligned\r
191 ;\r
192\r
193\r
194 ;\r
195 ; Since here the stack pointer is 16-byte aligned, so\r
196 ; EFI_FX_SAVE_STATE_X64 of EFI_SYSTEM_CONTEXT_x64\r
197 ; is 16-byte aligned\r
198 ;\r
199\r
200;; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;\r
201;; UINT64 R8, R9, R10, R11, R12, R13, R14, R15;\r
202 push r15\r
203 push r14\r
204 push r13\r
205 push r12\r
206 push r11\r
207 push r10\r
208 push r9\r
209 push r8\r
210 push rax\r
211 push qword ptr [rbp + 8] ; RCX\r
212 push rdx\r
213 push rbx\r
214 push qword ptr [rbp + 48] ; RSP\r
215 push qword ptr [rbp] ; RBP\r
216 push rsi\r
217 push rdi\r
218\r
219;; UINT64 Gs, Fs, Es, Ds, Cs, Ss; insure high 16 bits of each is zero\r
220 movzx rax, word ptr [rbp + 56]\r
221 push rax ; for ss\r
222 movzx rax, word ptr [rbp + 32]\r
223 push rax ; for cs\r
224 mov rax, ds\r
225 push rax\r
226 mov rax, es\r
227 push rax\r
228 mov rax, fs\r
229 push rax\r
230 mov rax, gs\r
231 push rax\r
232\r
233 mov [rbp + 8], rcx ; save vector number\r
234\r
235;; UINT64 Rip;\r
236 push qword ptr [rbp + 24]\r
237\r
238;; UINT64 Gdtr[2], Idtr[2];\r
239 xor rax, rax\r
240 push rax\r
241 push rax\r
242 sidt [rsp]\r
243 xchg rax, [rsp + 2]\r
244 xchg rax, [rsp]\r
245 xchg rax, [rsp + 8]\r
246\r
247 xor rax, rax\r
248 push rax\r
249 push rax\r
250 sgdt [rsp]\r
251 xchg rax, [rsp + 2]\r
252 xchg rax, [rsp]\r
253 xchg rax, [rsp + 8]\r
254\r
255;; UINT64 Ldtr, Tr;\r
256 xor rax, rax\r
257 str ax\r
258 push rax\r
259 sldt ax\r
260 push rax\r
261\r
262;; UINT64 RFlags;\r
263 push qword ptr [rbp + 40]\r
264\r
265;; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;\r
266 mov rax, cr8\r
267 push rax\r
268 mov rax, cr4\r
269 or rax, 208h\r
270 mov cr4, rax\r
271 push rax\r
272 mov rax, cr3\r
273 push rax\r
274 mov rax, cr2\r
275 push rax\r
276 xor rax, rax\r
277 push rax\r
278 mov rax, cr0\r
279 push rax\r
280\r
281;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
282 mov rax, dr7\r
283 push rax\r
284 mov rax, dr6\r
285 push rax\r
286 mov rax, dr3\r
287 push rax\r
288 mov rax, dr2\r
289 push rax\r
290 mov rax, dr1\r
291 push rax\r
292 mov rax, dr0\r
293 push rax\r
294\r
295;; FX_SAVE_STATE_X64 FxSaveState;\r
296 sub rsp, 512\r
297 mov rdi, rsp\r
298 db 0fh, 0aeh, 07h ;fxsave [rdi]\r
299\r
300;; UEFI calling convention for x64 requires that Direction flag in EFLAGs is clear\r
301 cld\r
302\r
303;; UINT32 ExceptionData;\r
304 push qword ptr [rbp + 16]\r
305\r
306;; Prepare parameter and call\r
307 mov rcx, [rbp + 8]\r
308 mov rdx, rsp\r
309 ;\r
310 ; Per X64 calling convention, allocate maximum parameter stack space\r
311 ; and make sure RSP is 16-byte aligned\r
312 ;\r
313 sub rsp, 4 * 8 + 8\r
314 mov rax, CommonExceptionHandler\r
315 call rax\r
316 add rsp, 4 * 8 + 8\r
317\r
318 cli\r
319;; UINT64 ExceptionData;\r
320 add rsp, 8\r
321\r
322;; FX_SAVE_STATE_X64 FxSaveState;\r
323\r
324 mov rsi, rsp\r
325 db 0fh, 0aeh, 0Eh ; fxrstor [rsi]\r
326 add rsp, 512\r
327\r
328;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
329;; Skip restoration of DRx registers to support in-circuit emualators\r
330;; or debuggers set breakpoint in interrupt/exception context\r
331 add rsp, 8 * 6\r
332\r
333;; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;\r
334 pop rax\r
335 mov cr0, rax\r
336 add rsp, 8 ; not for Cr1\r
337 pop rax\r
338 mov cr2, rax\r
339 pop rax\r
340 mov cr3, rax\r
341 pop rax\r
342 mov cr4, rax\r
343 pop rax\r
344 mov cr8, rax\r
345\r
346;; UINT64 RFlags;\r
347 pop qword ptr [rbp + 40]\r
348\r
349;; UINT64 Ldtr, Tr;\r
350;; UINT64 Gdtr[2], Idtr[2];\r
351;; Best not let anyone mess with these particular registers...\r
352 add rsp, 48\r
353\r
354;; UINT64 Rip;\r
355 pop qword ptr [rbp + 24]\r
356\r
357;; UINT64 Gs, Fs, Es, Ds, Cs, Ss;\r
358 pop rax\r
359 ; mov gs, rax ; not for gs\r
360 pop rax\r
361 ; mov fs, rax ; not for fs\r
362 ; (X64 will not use fs and gs, so we do not restore it)\r
363 pop rax\r
364 mov es, rax\r
365 pop rax\r
366 mov ds, rax\r
367 pop qword ptr [rbp + 32] ; for cs\r
368 pop qword ptr [rbp + 56] ; for ss\r
369\r
370;; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;\r
371;; UINT64 R8, R9, R10, R11, R12, R13, R14, R15;\r
372 pop rdi\r
373 pop rsi\r
374 add rsp, 8 ; not for rbp\r
375 pop qword ptr [rbp + 48] ; for rsp\r
376 pop rbx\r
377 pop rdx\r
378 pop rcx\r
379 pop rax\r
380 pop r8\r
381 pop r9\r
382 pop r10\r
383 pop r11\r
384 pop r12\r
385 pop r13\r
386 pop r14\r
387 pop r15\r
388\r
389 mov rsp, rbp\r
390 pop rbp\r
391 add rsp, 16\r
392 iretq\r
393\r
394CommonInterruptEntry ENDP\r
395\r
396;-------------------------------------------------------------------------------------\r
397; GetTemplateAddressMap (&AddressMap);\r
398;-------------------------------------------------------------------------------------\r
399; comments here for definition of address map\r
400GetTemplateAddressMap PROC\r
401 mov rax, offset Exception0Handle\r
402 mov qword ptr [rcx], rax\r
403 mov qword ptr [rcx+8h], Exception1Handle - Exception0Handle\r
404 ret\r
405GetTemplateAddressMap ENDP\r
406\r
407END\r