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