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