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