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