]> git.proxmox.com Git - mirror_edk2.git/blame - SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/X64/AsmFuncs.S
This revision can only work with Intel(c) UDK Debugger Tool version 1.2 or greater...
[mirror_edk2.git] / SourceLevelDebugPkg / Library / DebugAgent / DebugAgentCommon / X64 / AsmFuncs.S
CommitLineData
18b144ea 1#------------------------------------------------------------------------------\r
2#\r
93c0bdec 3# Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>\r
18b144ea 4# This program and the accompanying materials\r
5# are licensed and made available under the terms and conditions of the BSD License\r
6# which accompanies this distribution. The full text of the license may be found at\r
7# http://opensource.org/licenses/bsd-license.php.\r
8#\r
9# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
10# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
11#\r
12# Module Name:\r
13#\r
14# AsmFuncs.S\r
15#\r
16# Abstract:\r
17#\r
18# Debug interrupt handle functions.\r
19#\r
20#------------------------------------------------------------------------------\r
21\r
22#include "DebugException.h"\r
23\r
24ASM_GLOBAL ASM_PFX(InterruptProcess)\r
25\r
26ASM_GLOBAL ASM_PFX(Exception0Handle)\r
27ASM_GLOBAL ASM_PFX(ExceptionStubHeaderSize)\r
28ASM_GLOBAL ASM_PFX(TimerInterruptHandle)\r
29ASM_GLOBAL ASM_PFX(CommonEntry)\r
30\r
31.data
32\r
33ASM_PFX(ExceptionStubHeaderSize): .word ASM_PFX(Exception1Handle) - ASM_PFX(Exception0Handle)
34\r
35\r
36.text\r
37\r
38ASM_PFX(Exception0Handle):\r
39 cli\r
40 pushq %rcx\r
41 mov $0, %rcx\r
42 jmp ASM_PFX(CommonEntry)\r
43ASM_PFX(Exception1Handle):\r
44 cli\r
45 pushq %rcx\r
46 mov $1, %rcx\r
47 jmp ASM_PFX(CommonEntry)\r
48ASM_PFX(Exception2Handle):\r
49 cli\r
50 pushq %rcx\r
51 mov $2, %rcx\r
52 jmp ASM_PFX(CommonEntry)\r
53ASM_PFX(Exception3Handle):\r
54 cli\r
55 pushq %rcx\r
56 mov $3, %rcx\r
57 jmp ASM_PFX(CommonEntry)\r
58ASM_PFX(Exception4Handle):\r
59 cli\r
60 pushq %rcx\r
61 mov $4, %rcx\r
62 jmp ASM_PFX(CommonEntry)\r
63ASM_PFX(Exception5Handle):\r
64 cli\r
65 pushq %rcx\r
66 mov $5, %rcx\r
67 jmp ASM_PFX(CommonEntry)\r
68ASM_PFX(Exception6Handle):\r
69 cli\r
70 pushq %rcx\r
71 mov $6, %rcx\r
72 jmp ASM_PFX(CommonEntry)\r
73ASM_PFX(Exception7Handle):\r
74 cli\r
75 pushq %rcx\r
76 mov $7, %rcx\r
77 jmp ASM_PFX(CommonEntry)\r
78ASM_PFX(Exception8Handle):\r
79 cli\r
80 pushq %rcx\r
81 mov $8, %rcx\r
82 jmp ASM_PFX(CommonEntry)\r
83ASM_PFX(Exception9Handle):\r
84 cli\r
85 pushq %rcx\r
86 mov $9, %rcx\r
87 jmp ASM_PFX(CommonEntry)\r
88ASM_PFX(Exception10Handle):\r
89 cli\r
90 pushq %rcx\r
91 mov $10, %rcx\r
92 jmp ASM_PFX(CommonEntry)\r
93ASM_PFX(Exception11Handle):\r
94 cli\r
95 pushq %rcx\r
96 mov $11, %rcx\r
97 jmp ASM_PFX(CommonEntry)\r
98ASM_PFX(Exception12Handle):\r
99 cli\r
100 pushq %rcx\r
101 mov $12, %rcx\r
102 jmp ASM_PFX(CommonEntry)\r
103ASM_PFX(Exception13Handle):\r
104 cli\r
105 pushq %rcx\r
106 mov $13, %rcx\r
107 jmp ASM_PFX(CommonEntry)\r
108ASM_PFX(Exception14Handle):\r
109 cli\r
110 pushq %rcx\r
111 mov $14, %rcx\r
112 jmp ASM_PFX(CommonEntry)\r
113ASM_PFX(Exception15Handle):\r
114 cli\r
115 pushq %rcx\r
116 mov $15, %rcx\r
117 jmp ASM_PFX(CommonEntry)\r
118ASM_PFX(Exception16Handle):\r
119 cli\r
120 pushq %rcx\r
121 mov $16, %rcx\r
122 jmp ASM_PFX(CommonEntry)\r
123ASM_PFX(Exception17Handle):\r
124 cli\r
125 pushq %rcx\r
126 mov $17, %rcx\r
127 jmp ASM_PFX(CommonEntry)\r
128ASM_PFX(Exception18Handle):\r
129 cli\r
130 pushq %rcx\r
131 mov $18, %rcx\r
132 jmp ASM_PFX(CommonEntry)\r
133ASM_PFX(Exception19Handle):\r
134 cli\r
135 pushq %rcx\r
136 mov $19, %rcx\r
137 jmp ASM_PFX(CommonEntry)\r
138\r
139ASM_PFX(TimerInterruptHandle):\r
140 cli\r
141 pushq %rcx\r
142 mov $32, %rcx\r
143 jmp ASM_PFX(CommonEntry)\r
144\r
145\r
146ASM_PFX(CommonEntry):\r
147\r
148#---------------------------------------;\r
149# CommonInterruptEntry ;\r
150#---------------------------------------;\r
151# The follow algorithm is used for the common interrupt routine.\r
152\r
153#\r
154# +---------------------+ <-- 16-byte aligned ensured by processor\r
155# + Old SS +\r
156# +---------------------+\r
157# + Old RSP +\r
158# +---------------------+\r
159# + RFlags +\r
160# +---------------------+\r
161# + CS +\r
162# +---------------------+\r
163# + RIP +\r
164# +---------------------+\r
165# + Error Code +\r
166# +---------------------+\r
167# + RCX / Vector Number +\r
168# +---------------------+\r
169# + RBP +\r
170# +---------------------+ <-- RBP, 16-byte aligned\r
171#\r
172\r
173# We need to determine if any extra data was pushed by the exception\r
174 cmpq $DEBUG_EXCEPT_DOUBLE_FAULT, %rcx\r
175 je NoExtrPush\r
176 cmpq $DEBUG_EXCEPT_INVALID_TSS, %rcx\r
177 je NoExtrPush\r
178 cmpq $DEBUG_EXCEPT_SEG_NOT_PRESENT, %rcx\r
179 je NoExtrPush\r
180 cmpq $DEBUG_EXCEPT_STACK_FAULT, %rcx\r
181 je NoExtrPush\r
182 cmpq $DEBUG_EXCEPT_GP_FAULT, %rcx\r
183 je NoExtrPush\r
184 cmpq $DEBUG_EXCEPT_PAGE_FAULT, %rcx\r
185 je NoExtrPush\r
186 cmpq $DEBUG_EXCEPT_ALIGNMENT_CHECK, %rcx\r
187 je NoExtrPush\r
188\r
189 pushq (%rsp)\r
190 movq $0, 8(%rsp)\r
191\r
192NoExtrPush:\r
193 #\r
194 # All interrupt handlers are invoked through interrupt gates, so\r
195 # IF flag automatically cleared at the entry point\r
196 pushq %rbp\r
197 movq %rsp, %rbp\r
198\r
199 #\r
200 # Since here the stack pointer is 16-byte aligned, so\r
201 # EFI_FX_SAVE_STATE_X64 of EFI_SYSTEM_CONTEXT_x64\r
202 # is 16-byte aligned\r
203 #\r
204\r
205## UINT64 R8, R9, R10, R11, R12, R13, R14, R15;\r
206 pushq %r15\r
207 pushq %r14\r
208 pushq %r13\r
209 pushq %r12\r
210 pushq %r11\r
211 pushq %r10\r
212 pushq %r9\r
213 pushq %r8\r
214\r
215 movq %cr8, %r8\r
216 pushq %r8\r
217\r
218## UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;\r
219 pushq %rax\r
220 pushq %rbx\r
221 pushq 8(%rbp) # original rcx\r
222 pushq %rdx\r
223 pushq 48(%rbp) # original rsp\r
224 pushq (%rbp) # original rbp\r
225 pushq %rsi\r
226 pushq %rdi\r
227\r
228## UINT64 Cr0, Cr1, Cr2, Cr3, Cr4;\r
229 movq %cr4, %rax\r
230 orq $0x208, %rax\r
231 movq %rax, %cr4\r
232 pushq %rax\r
233 movq %cr3, %rax\r
234 pushq %rax\r
235 movq %cr2, %rax\r
236 pushq %rax\r
237 xorq %rax, %rax\r
238 pushq %rax\r
239 movq %cr0, %rax\r
240 pushq %rax\r
241\r
242## UINT64 Gs, Fs, Es, Ds, Cs, Ss; insure high 16 bits of each is zero\r
243 xorq %rax, %rax # set rax to 0\r
244 movzwq 56(%rbp), %rax\r
245# movq %ss, %rax\r
246 pushq %rax\r
247 movzwq 32(%rbp), %rax\r
248# movq %cs, %rax\r
249 pushq %rax\r
250 movq %ds, %rax\r
251 pushq %rax\r
252 movq %es, %rax\r
253 pushq %rax\r
254 movq %fs, %rax\r
255 pushq %rax\r
256 movq %gs, %rax\r
257 pushq %rax\r
258\r
259## UINT64 Rip;\r
260 pushq 24(%rbp)\r
261\r
262## UINT64 Gdtr[2], Idtr[2];\r
263 subq $16, %rsp\r
264 sidt (%rsp)\r
265 subq $16, %rsp\r
266 sgdt (%rsp)\r
267\r
268## UINT64 Ldtr, Tr;\r
269 xorq %rax, %rax\r
270 strw %ax\r
271 pushq %rax\r
272 sldtw %ax\r
273 pushq %rax\r
274\r
275## UINT64 RFlags;\r
276 pushq 40(%rbp)\r
277\r
278## UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
279 movq %dr7, %rax\r
280 pushq %rax\r
281## clear Dr7 while executing debugger itself\r
282 xorq %rax, %rax\r
283#debug movq %rax, %dr7\r
284\r
285 movq %dr6, %rax\r
286 pushq %rax\r
287## insure all status bits in dr6 are clear...\r
288 xorq %rax, %rax\r
289 movq %rax, %dr6\r
290\r
291 movq %dr3, %rax\r
292 pushq %rax\r
293 movq %dr2, %rax\r
294 pushq %rax\r
295 movq %dr1, %rax\r
296 pushq %rax\r
297 movq %dr0, %rax\r
298 pushq %rax\r
299\r
300## FX_SAVE_STATE_X64 FxSaveState;\r
301 subq $512, %rsp\r
302 movq %rsp, %rdi\r
303 .byte 0x0f, 0xae, 0b00000111\r
304\r
93c0bdec 305## save the exception data;\r
306 pushq 16(%rbp)\r
307\r
18b144ea 308## Clear Direction Flag\r
309 cld\r
310\r
311## Prepare parameter and call\r
312# movq 8(%rbp), %rcx\r
313 movq %rsp, %rdx\r
314 movq %rcx, %r15 # save vector in r15\r
315 #\r
316 # Per X64 calling convention, allocate maximum parameter stack space\r
317 # and make sure RSP is 16-byte aligned\r
318 #\r
93c0bdec 319 subq $(32 + 8), %rsp\r
18b144ea 320 call ASM_PFX(InterruptProcess)\r
93c0bdec 321 addq $(32 + 8), %rsp\r
322\r
323## skip the exception data;\r
324 addq $8, %rsp\r
18b144ea 325\r
326## FX_SAVE_STATE_X64 FxSaveState;\r
327\r
328 movq %rsp, %rsi\r
329 .byte 0x0f, 0xae, 0b00001110\r
330 addq $512, %rsp\r
331\r
332## UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
333 popq %rax\r
334 movq %rax, %dr0\r
335 popq %rax\r
336 movq %rax, %dr1\r
337 popq %rax\r
338 movq %rax, %dr2\r
339 popq %rax\r
340 movq %rax, %dr3\r
341## skip restore of dr6. We cleared dr6 during the context save.\r
342 addq $8, %rsp\r
343 popq %rax\r
344 movq %rax, %dr7\r
345\r
346## UINT64 RFlags;\r
347 popq 40(%rbp)\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 addq $48, %rsp\r
353\r
354## UINT64 Rip;\r
355 popq 24(%rbp)\r
356\r
357## UINT64 Gs, Fs, Es, Ds, Cs, Ss;\r
358 popq %rax\r
359 # mov gs, rax ; not for gs\r
360 popq %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 popq %rax\r
364 movw %rax, %es\r
365 popq %rax\r
366 movw %rax, %ds\r
367 popq 32(%rbp)\r
368 popq 56(%rbp)\r
369\r
370## UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;\r
371 popq %rax\r
372 movq %rax, %cr0\r
373 addq $8, %rsp\r
374 popq %rax\r
375 movq %rax, %cr2\r
376 popq %rax\r
377 movq %rax, %cr3\r
378 popq %rax\r
379 movq %rax, %cr4\r
380\r
381## UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;\r
382## UINT64 R8, R9, R10, R11, R12, R13, R14, R15;\r
383 popq %rdi\r
384 popq %rsi\r
385 addq $8, %rsp\r
386 addq $8, %rsp\r
387 popq %rdx\r
388 popq %rcx\r
389 popq %rbx\r
390 popq %rax\r
391\r
392 popq %r8\r
393 movq %r8, %cr8\r
394\r
395 popq %r8\r
396 popq %r9\r
397 popq %r10\r
398 popq %r11\r
399 popq %r12\r
400 popq %r13\r
401 popq %r14\r
402 popq %r15\r
403\r
404 movq %rbp, %rsp\r
405 popq %rbp\r
406 addq $16, %rsp\r
407 iretq\r