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