1#------------------------------------------------------------------------------
2#
3# Copyright (c) 2010 - 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
24ASM_GLOBAL ASM_PFX(InterruptProcess)
25ASM_GLOBAL ASM_PFX(Exception0Handle)
26ASM_GLOBAL ASM_PFX(ExceptionStubHeaderSize)
27ASM_GLOBAL ASM_PFX(TimerInterruptHandle)
28ASM_GLOBAL ASM_PFX(CommonEntry)
29
30.macro  AGENT_HANDLER_SIGNATURE
31  .byte 0x41, 0x47, 0x54, 0x48   # AGENT_HANDLER_SIGNATURE     SIGNATURE_32('A','G','T','H')
32.endm
33
34.data
35
36ASM_PFX(ExceptionStubHeaderSize):  .long     ASM_PFX(Exception1Handle) - ASM_PFX(Exception0Handle)
37
38.text
39
40AGENT_HANDLER_SIGNATURE
41ASM_PFX(Exception0Handle):
42   cli
43   pushl %eax
44   mov   $0, %eax
45   jmp   ASM_PFX(CommonEntry)
46AGENT_HANDLER_SIGNATURE
47ASM_PFX(Exception1Handle):
48   cli
49   pushl %eax
50   mov   $1, %eax
51   jmp   ASM_PFX(CommonEntry)
52AGENT_HANDLER_SIGNATURE
53ASM_PFX(Exception2Handle):
54   cli
55   pushl %eax
56   mov   $2, %eax
57   jmp   ASM_PFX(CommonEntry)
58AGENT_HANDLER_SIGNATURE
59ASM_PFX(Exception3Handle):
60   cli
61   pushl %eax
62   mov   $3, %eax
63   jmp   ASM_PFX(CommonEntry)
64AGENT_HANDLER_SIGNATURE
65ASM_PFX(Exception4Handle):
66   cli
67   pushl %eax
68   mov   $4, %eax
69   jmp   ASM_PFX(CommonEntry)
70AGENT_HANDLER_SIGNATURE
71ASM_PFX(Exception5Handle):
72   cli
73   pushl %eax
74   mov   $5, %eax
75   jmp   ASM_PFX(CommonEntry)
76AGENT_HANDLER_SIGNATURE
77ASM_PFX(Exception6Handle):
78   cli
79   pushl %eax
80   mov   $6, %eax
81   jmp   ASM_PFX(CommonEntry)
82AGENT_HANDLER_SIGNATURE
83ASM_PFX(Exception7Handle):
84   cli
85   pushl %eax
86   mov   $7, %eax
87   jmp   ASM_PFX(CommonEntry)
88AGENT_HANDLER_SIGNATURE
89ASM_PFX(Exception8Handle):
90   cli
91   pushl %eax
92   mov   $8, %eax
93   jmp   ASM_PFX(CommonEntry)
94AGENT_HANDLER_SIGNATURE
95ASM_PFX(Exception9Handle):
96   cli
97   pushl %eax
98   mov   $9, %eax
99   jmp   ASM_PFX(CommonEntry)
100AGENT_HANDLER_SIGNATURE
101ASM_PFX(Exception10Handle):
102   cli
103   pushl %eax
104   mov   $10, %eax
105   jmp   ASM_PFX(CommonEntry)
106AGENT_HANDLER_SIGNATURE
107ASM_PFX(Exception11Handle):
108   cli
109   pushl %eax
110   mov   $11, %eax
111   jmp   ASM_PFX(CommonEntry)
112AGENT_HANDLER_SIGNATURE
113ASM_PFX(Exception12Handle):
114   cli
115   pushl %eax
116   mov   $12, %eax
117   jmp   ASM_PFX(CommonEntry)
118AGENT_HANDLER_SIGNATURE
119ASM_PFX(Exception13Handle):
120   cli
121   pushl %eax
122   mov   $13, %eax
123   jmp   ASM_PFX(CommonEntry)
124AGENT_HANDLER_SIGNATURE
125ASM_PFX(Exception14Handle):
126   cli
127   pushl %eax
128   mov   $14, %eax
129   jmp   ASM_PFX(CommonEntry)
130AGENT_HANDLER_SIGNATURE
131ASM_PFX(Exception15Handle):
132   cli
133   pushl %eax
134   mov   $15, %eax
135   jmp   ASM_PFX(CommonEntry)
136AGENT_HANDLER_SIGNATURE
137ASM_PFX(Exception16Handle):
138   cli
139   pushl %eax
140   mov   $16, %eax
141   jmp   ASM_PFX(CommonEntry)
142AGENT_HANDLER_SIGNATURE
143ASM_PFX(Exception17Handle):
144   cli
145   pushl %eax
146   mov   $17, %eax
147   jmp   ASM_PFX(CommonEntry)
148AGENT_HANDLER_SIGNATURE
149ASM_PFX(Exception18Handle):
150   cli
151   pushl %eax
152   mov   $18, %eax
153   jmp   ASM_PFX(CommonEntry)
154AGENT_HANDLER_SIGNATURE
155ASM_PFX(Exception19Handle):
156   cli
157   pushl %eax
158   mov   $19, %eax
159   jmp   ASM_PFX(CommonEntry)
160AGENT_HANDLER_SIGNATURE
161ASM_PFX(TimerInterruptHandle):
162   cli
163   pushl %eax
164   mov   $32, %eax
165   jmp   ASM_PFX(CommonEntry)
166
167
168ASM_PFX(CommonEntry):
169
170#---------------------------------------;
171# _CommonEntry                  ;
172#----------------------------------------------------------------------------;
173# The follow algorithm is used for the common interrupt routine.
174# Entry from each interrupt with a push eax and eax=interrupt number
175#
176# +---------------------+
177# +    EFlags           +
178# +---------------------+
179# +    CS               +
180# +---------------------+
181# +    EIP              +
182# +---------------------+
183# +    Error Code       +
184# +---------------------+
185# + EAX / Vector Number +
186# +---------------------+
187# +    EBP              +
188# +---------------------+ <-- EBP
189#
190
191# We need to determine if any extra data was pushed by the exception
192  cmpl    $DEBUG_EXCEPT_DOUBLE_FAULT, %eax
193  je      NoExtrPush
194  cmpl    $DEBUG_EXCEPT_INVALID_TSS, %eax
195  je      NoExtrPush
196  cmpl    $DEBUG_EXCEPT_SEG_NOT_PRESENT, %eax
197  je      NoExtrPush
198  cmpl    $DEBUG_EXCEPT_STACK_FAULT, %eax
199  je      NoExtrPush
200  cmpl    $DEBUG_EXCEPT_GP_FAULT, %eax
201  je      NoExtrPush
202  cmpl    $DEBUG_EXCEPT_PAGE_FAULT, %eax
203  je      NoExtrPush
204  cmpl    $DEBUG_EXCEPT_ALIGNMENT_CHECK, %eax
205  je      NoExtrPush
206
207  pushl    (%esp)
208  movl     $0, 4(%esp)
209
210NoExtrPush:
211
212  pushl   %ebp
213  movl    %esp,%ebp
214
215  #
216  # Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of EFI_SYSTEM_CONTEXT_IA32
217  # is 16-byte aligned
218  #
219  andl    $0xfffffff0,%esp
220  subl    $12,%esp
221
222## UINT32  Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;
223  pushl   0x4(%ebp)
224  pushl   %ebx
225  pushl   %ecx
226  pushl   %edx
227  mov     %eax, %ebx                   # save vector in ebx
228  leal    24(%ebp),%ecx
229  pushl   %ecx                         # save original ESP
230  pushl   (%ebp)
231  pushl   %esi
232  pushl   %edi
233
234## UINT32  Cr0, Cr1, Cr2, Cr3, Cr4;
235  movl    %cr4, %eax
236  orl     $0x208,%eax
237  movl    %eax, %cr4
238  pushl   %eax
239  movl    %cr3, %eax
240  pushl   %eax
241  movl    %cr2, %eax
242  pushl   %eax
243  xorl    %eax,%eax
244  pushl   %eax
245  movl    %cr0, %eax
246  pushl   %eax
247
248## UINT32  Gs, Fs, Es, Ds, Cs, Ss;
249  movl    %ss,%eax
250  pushl   %eax
251  movzwl  16(%ebp), %eax
252  pushl   %eax
253  movl    %ds,%eax
254  pushl   %eax
255  movl    %es,%eax
256  pushl   %eax
257  movl    %fs,%eax
258  pushl   %eax
259  movl    %gs,%eax
260  pushl   %eax
261
262## UINT32  Eip;
263  pushl   12(%ebp)
264
265## UINT32  Gdtr[2], Idtr[2];
266  subl    $8,%esp
267  sidt    (%esp)
268  subl    $8,%esp
269  sgdt    (%esp)
270
271## UINT32  Ldtr, Tr;
272  xorl    %eax,%eax
273  strl    %eax
274  pushl   %eax
275  sldtl   %eax
276  pushl   %eax
277
278## UINT32  EFlags;
279  pushl   20(%ebp)
280
281## UINT32  Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
282  movl    %dr7, %eax
283  pushl   %eax
284## clear Dr7 while executing debugger itself
285  xorl    %eax,%eax
286  movl    %eax, %dr7
287
288  movl    %dr6, %eax
289  pushl   %eax
290## insure all status bits in dr6 are clear...
291  xorl    %eax,%eax
292  movl    %eax, %dr6
293
294  movl    %dr3, %eax
295  pushl   %eax
296  movl    %dr2, %eax
297  pushl   %eax
298  movl    %dr1, %eax
299  pushl   %eax
300  movl    %dr0, %eax
301  pushl   %eax
302
303## FX_SAVE_STATE_IA32 FxSaveState;
304  subl    $512,%esp
305  movl    %esp,%edi
306  .byte 0x0f, 0xae, 0x07   # fxsave [edi]
307
308## save the exception data
309  pushl   8(%esp)
310
311## Clear Direction Flag
312  cld
313
314## Prepare parameter and call C function
315  pushl   %esp
316  pushl   %ebx
317  call    ASM_PFX(InterruptProcess)
318  addl    $8,%esp
319
320## skip the exception data
321  addl    $4,%esp
322
323## FX_SAVE_STATE_IA32 FxSaveState;
324  movl    %esp,%esi
325  .byte 0x0f, 0xae, 0x0e   # fxrstor [esi]
326  addl    $512,%esp
327
328## UINT32  Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
329  popl    %eax
330  movl    %eax, %dr0
331  popl    %eax
332  movl    %eax, %dr1
333  popl    %eax
334  movl    %eax, %dr2
335  popl    %eax
336  movl    %eax, %dr3
337## skip restore of dr6.  We cleared dr6 during the context save.
338  addl    $4,%esp
339  popl    %eax
340  movl    %eax, %dr7
341
342## UINT32  EFlags;
343  popl    20(%ebp)
344
345## UINT32  Ldtr, Tr;
346## UINT32  Gdtr[2], Idtr[2];
347## Best not let anyone mess with these particular registers...
348  addl     $24,%esp
349
350## UINT32  Eip;
351   pop     12(%ebp)
352
353## UINT32  Gs, Fs, Es, Ds, Cs, Ss;
354## NOTE - modified segment registers could hang the debugger...  We
355##        could attempt to insulate ourselves against this possibility,
356##        but that poses risks as well.
357##
358  popl    %gs
359  popl    %fs
360  popl    %es
361  popl    %ds
362  popl    16(%ebp)
363  popl    %ss
364
365## UINT32  Cr0, Cr1, Cr2, Cr3, Cr4;
366  popl    %eax
367  movl    %eax, %cr0
368  addl    $4,%esp   # not for Cr1
369  popl    %eax
370  movl    %eax, %cr2
371  popl    %eax
372  movl    %eax, %cr3
373  popl    %eax
374  movl    %eax, %cr4
375
376## UINT32  Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;
377  popl    %edi
378  popl    %esi
379  addl    $4,%esp  # not for ebp
380  addl    $4,%esp  # not for esp
381  popl    %edx
382  popl    %ecx
383  popl    %ebx
384  popl    %eax
385
386  movl    %ebp,%esp
387  popl    %ebp
388  addl    $8,%esp   # skip eax
389  iretl
390
391