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