• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#------------------------------------------------------------------------------
2#
3# Copyright (c) 2010 - 2015, 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## insure FXSAVE/FXRSTOR is enabled in CR4...
236## ... while we're at it, make sure DE is also enabled...
237  mov     $1, %eax
238  pushl   %ebx                         # temporarily save value of ebx on stack
239  cpuid                                # use CPUID to determine if FXSAVE/FXRESTOR
240                                       # and DE are supported
241  popl    %ebx                         # retore value of ebx that was overwritten
242                                       # by CPUID
243  movl    %cr4, %eax
244  pushl   %eax                         # push cr4 firstly
245  testl   $BIT24, %edx                 # Test for FXSAVE/FXRESTOR support
246  jz      L1
247  orl     $BIT9, %eax                  # Set CR4.OSFXSR
248L1:
249  testl   $BIT2, %edx                  # Test for Debugging Extensions support
250  jz      L2
251  orl     $BIT3, %eax                  # Set CR4.DE
252L2:
253  movl    %eax, %cr4
254  movl    %cr3, %eax
255  pushl   %eax
256  movl    %cr2, %eax
257  pushl   %eax
258  xorl    %eax,%eax
259  pushl   %eax
260  movl    %cr0, %eax
261  pushl   %eax
262
263## UINT32  Gs, Fs, Es, Ds, Cs, Ss;
264  movl    %ss,%eax
265  pushl   %eax
266  movzwl  16(%ebp), %eax
267  pushl   %eax
268  movl    %ds,%eax
269  pushl   %eax
270  movl    %es,%eax
271  pushl   %eax
272  movl    %fs,%eax
273  pushl   %eax
274  movl    %gs,%eax
275  pushl   %eax
276
277## UINT32  Eip;
278  pushl   12(%ebp)
279
280## UINT32  Gdtr[2], Idtr[2];
281  subl    $8,%esp
282  sidt    (%esp)
283  subl    $8,%esp
284  sgdt    (%esp)
285
286## UINT32  Ldtr, Tr;
287  xorl    %eax,%eax
288  strl    %eax
289  pushl   %eax
290  sldtl   %eax
291  pushl   %eax
292
293## UINT32  EFlags;
294  pushl   20(%ebp)
295
296## UINT32  Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
297  movl    %dr7, %eax
298  pushl   %eax
299## clear Dr7 while executing debugger itself
300  xorl    %eax,%eax
301  movl    %eax, %dr7
302
303  movl    %dr6, %eax
304  pushl   %eax
305## insure all status bits in dr6 are clear...
306  xorl    %eax,%eax
307  movl    %eax, %dr6
308
309  movl    %dr3, %eax
310  pushl   %eax
311  movl    %dr2, %eax
312  pushl   %eax
313  movl    %dr1, %eax
314  pushl   %eax
315  movl    %dr0, %eax
316  pushl   %eax
317
318## FX_SAVE_STATE_IA32 FxSaveState;
319  subl    $512,%esp
320  movl    %esp,%edi
321  testl   $BIT24, %edx     # Test for FXSAVE/FXRESTOR support.
322                           # edx still contains result from CPUID above
323  jz      L3
324  .byte 0x0f, 0xae, 0x07   # fxsave [edi]
325L3:
326
327## save the exception data
328  pushl   8(%esp)
329
330## Clear Direction Flag
331  cld
332
333## Prepare parameter and call C function
334  pushl   %esp
335  pushl   %ebx
336  call    ASM_PFX(InterruptProcess)
337  addl    $8,%esp
338
339## skip the exception data
340  addl    $4,%esp
341
342## FX_SAVE_STATE_IA32 FxSaveState;
343  movl    %esp,%esi
344  movl    $1, %eax
345  cpuid                    # use CPUID to determine if FXSAVE/FXRESTOR
346                           # are supported
347  testl   $BIT24, %edx     # Test for FXSAVE/FXRESTOR support
348  jz      L4
349  .byte 0x0f, 0xae, 0x0e   # fxrstor [esi]
350L4:
351  addl    $512,%esp
352
353## UINT32  Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
354  popl    %eax
355  movl    %eax, %dr0
356  popl    %eax
357  movl    %eax, %dr1
358  popl    %eax
359  movl    %eax, %dr2
360  popl    %eax
361  movl    %eax, %dr3
362## skip restore of dr6.  We cleared dr6 during the context save.
363  addl    $4,%esp
364  popl    %eax
365  movl    %eax, %dr7
366
367## UINT32  EFlags;
368  popl    20(%ebp)
369
370## UINT32  Ldtr, Tr;
371## UINT32  Gdtr[2], Idtr[2];
372## Best not let anyone mess with these particular registers...
373  addl     $24,%esp
374
375## UINT32  Eip;
376   pop     12(%ebp)
377
378## UINT32  Gs, Fs, Es, Ds, Cs, Ss;
379## NOTE - modified segment registers could hang the debugger...  We
380##        could attempt to insulate ourselves against this possibility,
381##        but that poses risks as well.
382##
383  popl    %gs
384  popl    %fs
385  popl    %es
386  popl    %ds
387  popl    16(%ebp)
388  popl    %ss
389
390## UINT32  Cr0, Cr1, Cr2, Cr3, Cr4;
391  popl    %eax
392  movl    %eax, %cr0
393  addl    $4,%esp   # not for Cr1
394  popl    %eax
395  movl    %eax, %cr2
396  popl    %eax
397  movl    %eax, %cr3
398  popl    %eax
399  movl    %eax, %cr4
400
401## UINT32  Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;
402  popl    %edi
403  popl    %esi
404  addl    $4,%esp  # not for ebp
405  addl    $4,%esp  # not for esp
406  popl    %edx
407  popl    %ecx
408  popl    %ebx
409  popl    %eax
410
411  movl    %ebp,%esp
412  popl    %ebp
413  addl    $8,%esp   # skip eax
414  iretl
415
416