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