]> git.proxmox.com Git - mirror_edk2.git/blob - SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/X64/AsmFuncs.nasm
SourceLevelDebugPkg DebugAgentLib: Convert X64/AsmFuncs.asm
[mirror_edk2.git] / SourceLevelDebugPkg / Library / DebugAgent / DebugAgentCommon / X64 / AsmFuncs.nasm
1 ;------------------------------------------------------------------------------
2 ;
3 ; Copyright (c) 2016, 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.nasm
15 ;
16 ; Abstract:
17 ;
18 ; Debug interrupt handle functions.
19 ;
20 ;------------------------------------------------------------------------------
21
22 #include "DebugException.h"
23
24 SECTION .data
25
26 extern ASM_PFX(InterruptProcess)
27 global ASM_PFX(Exception0Handle)
28 global ASM_PFX(TimerInterruptHandle)
29 global ASM_PFX(ExceptionStubHeaderSize)
30
31 %macro AGENT_HANDLER_SIGNATURE 0
32 db 0x41, 0x47, 0x54, 0x48 ; SIGNATURE_32('A','G','T','H')
33 %endmacro
34
35 ASM_PFX(ExceptionStubHeaderSize): dd Exception1Handle - ASM_PFX(Exception0Handle) ;
36 CommonEntryAddr: dq CommonEntry ;
37
38 DEFAULT REL
39 SECTION .text
40
41 AGENT_HANDLER_SIGNATURE
42 ASM_PFX(Exception0Handle):
43 cli
44 push rcx
45 mov rcx, dword 0
46 jmp qword [CommonEntryAddr]
47 AGENT_HANDLER_SIGNATURE
48 Exception1Handle:
49 cli
50 push rcx
51 mov rcx, dword 1
52 jmp qword [CommonEntryAddr]
53 AGENT_HANDLER_SIGNATURE
54 Exception2Handle:
55 cli
56 push rcx
57 mov rcx, dword 2
58 jmp qword [CommonEntryAddr]
59 AGENT_HANDLER_SIGNATURE
60 Exception3Handle:
61 cli
62 push rcx
63 mov rcx, dword 3
64 jmp qword [CommonEntryAddr]
65 AGENT_HANDLER_SIGNATURE
66 Exception4Handle:
67 cli
68 push rcx
69 mov rcx, dword 4
70 jmp qword [CommonEntryAddr]
71 AGENT_HANDLER_SIGNATURE
72 Exception5Handle:
73 cli
74 push rcx
75 mov rcx, dword 5
76 jmp qword [CommonEntryAddr]
77 AGENT_HANDLER_SIGNATURE
78 Exception6Handle:
79 cli
80 push rcx
81 mov rcx, dword 6
82 jmp qword [CommonEntryAddr]
83 AGENT_HANDLER_SIGNATURE
84 Exception7Handle:
85 cli
86 push rcx
87 mov rcx, dword 7
88 jmp qword [CommonEntryAddr]
89 AGENT_HANDLER_SIGNATURE
90 Exception8Handle:
91 cli
92 push rcx
93 mov rcx, dword 8
94 jmp qword [CommonEntryAddr]
95 AGENT_HANDLER_SIGNATURE
96 Exception9Handle:
97 cli
98 push rcx
99 mov rcx, dword 9
100 jmp qword [CommonEntryAddr]
101 AGENT_HANDLER_SIGNATURE
102 Exception10Handle:
103 cli
104 push rcx
105 mov rcx, dword 10
106 jmp qword [CommonEntryAddr]
107 AGENT_HANDLER_SIGNATURE
108 Exception11Handle:
109 cli
110 push rcx
111 mov rcx, dword 11
112 jmp qword [CommonEntryAddr]
113 AGENT_HANDLER_SIGNATURE
114 Exception12Handle:
115 cli
116 push rcx
117 mov rcx, dword 12
118 jmp qword [CommonEntryAddr]
119 AGENT_HANDLER_SIGNATURE
120 Exception13Handle:
121 cli
122 push rcx
123 mov rcx, dword 13
124 jmp qword [CommonEntryAddr]
125 AGENT_HANDLER_SIGNATURE
126 Exception14Handle:
127 cli
128 push rcx
129 mov rcx, dword 14
130 jmp qword [CommonEntryAddr]
131 AGENT_HANDLER_SIGNATURE
132 Exception15Handle:
133 cli
134 push rcx
135 mov rcx, dword 15
136 jmp qword [CommonEntryAddr]
137 AGENT_HANDLER_SIGNATURE
138 Exception16Handle:
139 cli
140 push rcx
141 mov rcx, dword 16
142 jmp qword [CommonEntryAddr]
143 AGENT_HANDLER_SIGNATURE
144 Exception17Handle:
145 cli
146 push rcx
147 mov rcx, dword 17
148 jmp qword [CommonEntryAddr]
149 AGENT_HANDLER_SIGNATURE
150 Exception18Handle:
151 cli
152 push rcx
153 mov rcx, dword 18
154 jmp qword [CommonEntryAddr]
155 AGENT_HANDLER_SIGNATURE
156 Exception19Handle:
157 cli
158 push rcx
159 mov rcx, dword 19
160 jmp qword [CommonEntryAddr]
161 AGENT_HANDLER_SIGNATURE
162 ASM_PFX(TimerInterruptHandle):
163 cli
164 push rcx
165 mov rcx, dword 32
166 jmp qword [CommonEntryAddr]
167
168 CommonEntry:
169 ; We need to determine if any extra data was pushed by the exception
170 cmp rcx, DEBUG_EXCEPT_DOUBLE_FAULT
171 je NoExtrPush
172 cmp rcx, DEBUG_EXCEPT_INVALID_TSS
173 je NoExtrPush
174 cmp rcx, DEBUG_EXCEPT_SEG_NOT_PRESENT
175 je NoExtrPush
176 cmp rcx, DEBUG_EXCEPT_STACK_FAULT
177 je NoExtrPush
178 cmp rcx, DEBUG_EXCEPT_GP_FAULT
179 je NoExtrPush
180 cmp rcx, DEBUG_EXCEPT_PAGE_FAULT
181 je NoExtrPush
182 cmp rcx, DEBUG_EXCEPT_ALIGNMENT_CHECK
183 je NoExtrPush
184
185 push qword [rsp]
186 mov qword [rsp + 8], 0
187
188 NoExtrPush:
189 push rbp
190 mov rbp, rsp
191
192 ; store UINT64 r8, r9, r10, r11, r12, r13, r14, r15;
193 push r15
194 push r14
195 push r13
196 push r12
197 push r11
198 push r10
199 push r9
200 push r8
201
202 mov r8, cr8
203 push r8
204
205 ; store UINT64 Rdi, Rsi, Rbp, Rsp, Rdx, Rcx, Rbx, Rax;
206 push rax
207 push rbx
208 push qword [rbp + 8] ; original rcx
209 push rdx
210 push qword [rbp + 6 * 8] ; original rsp
211 push qword [rbp] ; original rbp
212 push rsi
213 push rdi
214
215 ;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;
216 ;; insure FXSAVE/FXRSTOR is enabled in CR4...
217 ;; ... while we're at it, make sure DE is also enabled...
218 mov rax, cr4
219 or rax, 0x208
220 mov cr4, rax
221 push rax
222 mov rax, cr3
223 push rax
224 mov rax, cr2
225 push rax
226 push 0
227 mov rax, cr0
228 push rax
229
230 xor rax, rax
231 mov rax, Ss
232 push rax
233 mov rax, Cs
234 push rax
235 mov rax, Ds
236 push rax
237 mov rax, Es
238 push rax
239 mov rax, Fs
240 push rax
241 mov rax, Gs
242 push rax
243
244 ;; EIP
245 mov rax, [rbp + 8 * 3] ; EIP
246 push rax
247
248 ;; UINT64 Gdtr[2], Idtr[2];
249 sub rsp, 16
250 sidt [rsp]
251 sub rsp, 16
252 sgdt [rsp]
253
254 ;; UINT64 Ldtr, Tr;
255 xor rax, rax
256 str ax
257 push rax
258 sldt ax
259 push rax
260
261 ;; EFlags
262 mov rax, [rbp + 8 * 5]
263 push rax
264
265 ;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
266 mov rax, dr7
267 push rax
268
269 ;; clear Dr7 while executing debugger itself
270 xor rax, rax
271 mov dr7, rax
272
273 ;; Dr6
274 mov rax, dr6
275 push rax
276
277 ;; insure all status bits in dr6 are clear...
278 xor rax, rax
279 mov dr6, rax
280
281 mov rax, dr3
282 push rax
283 mov rax, dr2
284 push rax
285 mov rax, dr1
286 push rax
287 mov rax, dr0
288 push rax
289
290 ;; Clear Direction Flag
291 cld
292
293 sub rsp, 512
294 mov rdi, rsp
295 ;; Clear the buffer
296 xor rax, rax
297 push rcx
298 mov rcx, dword 64 ;= 512 / 8
299 rep stosq
300 pop rcx
301 mov rdi, rsp
302 db 0xf, 0xae, 00000111y ;fxsave [rdi]
303
304 ;; save the exception data
305 push qword [rbp + 16]
306
307 ; call the C interrupt process function
308 mov rdx, rsp ; Structure
309 mov r15, rcx ; save vector in r15
310
311 ;
312 ; Per X64 calling convention, allocate maximum parameter stack space
313 ; and make sure RSP is 16-byte aligned
314 ;
315 sub rsp, 32 + 8
316 call ASM_PFX(InterruptProcess)
317 add rsp, 32 + 8
318
319 ;; skip the exception data
320 add rsp, 8
321
322 mov rsi, rsp
323 db 0xf, 0xae, 00001110y ; fxrstor [rsi]
324 add rsp, 512
325
326 ;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
327 pop rax
328 mov dr0, rax
329 pop rax
330 mov dr1, rax
331 pop rax
332 mov dr2, rax
333 pop rax
334 mov dr3, rax
335 ;; skip restore of dr6. We cleared dr6 during the context save.
336 add rsp, 8
337 pop rax
338 mov dr7, rax
339
340 ;; set EFlags
341 pop qword [rbp + 8 * 5]
342
343 ;; UINT64 Ldtr, Tr;
344 ;; UINT64 Gdtr[2], Idtr[2];
345 ;; Best not let anyone mess with these particular registers...
346 add rsp, 24 * 2
347
348 ;; UINT64 Eip;
349 pop qword [rbp + 8 * 3] ; set EIP in stack
350
351 ;; UINT64 Gs, Fs, Es, Ds, Cs, Ss;
352 ;; NOTE - modified segment registers could hang the debugger... We
353 ;; could attempt to insulate ourselves against this possibility,
354 ;; but that poses risks as well.
355 ;;
356 pop rax
357 pop rax
358 pop rax
359 mov es, rax
360 pop rax
361 mov ds, rax
362 pop qword [rbp + 8 * 4] ; Set CS in stack
363 pop rax
364 mov ss, rax
365
366 ;; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4;
367 pop rax
368 mov cr0, rax
369 add rsp, 8 ; skip for Cr1
370 pop rax
371 mov cr2, rax
372 pop rax
373 mov cr3, rax
374 pop rax
375 mov cr4, rax
376
377 ;; restore general register
378 pop rdi
379 pop rsi
380 add rsp, 8 ; skip rbp
381 add rsp, 8 ; skip rsp
382 pop rdx
383 pop rcx
384 pop rbx
385 pop rax
386
387 pop r8
388 mov cr8, r8
389
390 ; store UINT64 r8, r9, r10, r11, r12, r13, r14, r15;
391 pop r8
392 pop r9
393 pop r10
394 pop r11
395 pop r12
396 pop r13
397 pop r14
398 pop r15
399
400 mov rsp, rbp
401 pop rbp
402 add rsp, 16 ; skip rcx and error code
403
404 iretq
405