git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@10867 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			361 lines
		
	
	
		
			8.0 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
			
		
		
	
	
			361 lines
		
	
	
		
			8.0 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
#------------------------------------------------------------------------------
 | 
						|
#
 | 
						|
# Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
 | 
						|
# This program and the accompanying materials
 | 
						|
# are licensed and made available under the terms and conditions of the BSD License
 | 
						|
# which accompanies this distribution.  The full text of the license may be found at
 | 
						|
# http://opensource.org/licenses/bsd-license.php.
 | 
						|
#
 | 
						|
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
 | 
						|
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 | 
						|
#
 | 
						|
# Module Name:
 | 
						|
#
 | 
						|
#   AsmFuncs.S
 | 
						|
#
 | 
						|
# Abstract:
 | 
						|
#
 | 
						|
#   Debug interrupt handle functions.
 | 
						|
#
 | 
						|
#------------------------------------------------------------------------------
 | 
						|
 | 
						|
#include "DebugException.h"
 | 
						|
 | 
						|
ASM_GLOBAL ASM_PFX(InterruptProcess)
 | 
						|
ASM_GLOBAL ASM_PFX(Exception0Handle)
 | 
						|
ASM_GLOBAL ASM_PFX(ExceptionStubHeaderSize)
 | 
						|
ASM_GLOBAL ASM_PFX(TimerInterruptHandle)
 | 
						|
ASM_GLOBAL ASM_PFX(CommonEntry)
 | 
						|
 | 
						|
.data
 | 
						|
 | 
						|
ASM_PFX(ExceptionStubHeaderSize):  .word     ASM_PFX(Exception1Handle) - ASM_PFX(Exception0Handle)
 | 
						|
 | 
						|
.text
 | 
						|
 | 
						|
ASM_PFX(Exception0Handle):
 | 
						|
   cli
 | 
						|
   pushl %eax
 | 
						|
   mov   $0, %eax
 | 
						|
   jmp   ASM_PFX(CommonEntry)
 | 
						|
ASM_PFX(Exception1Handle):
 | 
						|
   cli
 | 
						|
   pushl %eax
 | 
						|
   mov   $1, %eax
 | 
						|
   jmp   ASM_PFX(CommonEntry)
 | 
						|
ASM_PFX(Exception2Handle):
 | 
						|
   cli
 | 
						|
   pushl %eax
 | 
						|
   mov   $2, %eax
 | 
						|
   jmp   ASM_PFX(CommonEntry)
 | 
						|
ASM_PFX(Exception3Handle):
 | 
						|
   cli
 | 
						|
   pushl %eax
 | 
						|
   mov   $3, %eax
 | 
						|
   jmp   ASM_PFX(CommonEntry)
 | 
						|
ASM_PFX(Exception4Handle):
 | 
						|
   cli
 | 
						|
   pushl %eax
 | 
						|
   mov   $4, %eax
 | 
						|
   jmp   ASM_PFX(CommonEntry)
 | 
						|
ASM_PFX(Exception5Handle):
 | 
						|
   cli
 | 
						|
   pushl %eax
 | 
						|
   mov   $5, %eax
 | 
						|
   jmp   ASM_PFX(CommonEntry)
 | 
						|
ASM_PFX(Exception6Handle):
 | 
						|
   cli
 | 
						|
   pushl %eax
 | 
						|
   mov   $6, %eax
 | 
						|
   jmp   ASM_PFX(CommonEntry)
 | 
						|
ASM_PFX(Exception7Handle):
 | 
						|
   cli
 | 
						|
   pushl %eax
 | 
						|
   mov   $7, %eax
 | 
						|
   jmp   ASM_PFX(CommonEntry)
 | 
						|
ASM_PFX(Exception8Handle):
 | 
						|
   cli
 | 
						|
   pushl %eax
 | 
						|
   mov   $8, %eax
 | 
						|
   jmp   ASM_PFX(CommonEntry)
 | 
						|
ASM_PFX(Exception9Handle):
 | 
						|
   cli
 | 
						|
   pushl %eax
 | 
						|
   mov   $9, %eax
 | 
						|
   jmp   ASM_PFX(CommonEntry)
 | 
						|
ASM_PFX(Exception10Handle):
 | 
						|
   cli
 | 
						|
   pushl %eax
 | 
						|
   mov   $10, %eax
 | 
						|
   jmp   ASM_PFX(CommonEntry)
 | 
						|
ASM_PFX(Exception11Handle):
 | 
						|
   cli
 | 
						|
   pushl %eax
 | 
						|
   mov   $11, %eax
 | 
						|
   jmp   ASM_PFX(CommonEntry)
 | 
						|
ASM_PFX(Exception12Handle):
 | 
						|
   cli
 | 
						|
   pushl %eax
 | 
						|
   mov   $12, %eax
 | 
						|
   jmp   ASM_PFX(CommonEntry)
 | 
						|
ASM_PFX(Exception13Handle):
 | 
						|
   cli
 | 
						|
   pushl %eax
 | 
						|
   mov   $13, %eax
 | 
						|
   jmp   ASM_PFX(CommonEntry)
 | 
						|
ASM_PFX(Exception14Handle):
 | 
						|
   cli
 | 
						|
   pushl %eax
 | 
						|
   mov   $14, %eax
 | 
						|
   jmp   ASM_PFX(CommonEntry)
 | 
						|
ASM_PFX(Exception15Handle):
 | 
						|
   cli
 | 
						|
   pushl %eax
 | 
						|
   mov   $15, %eax
 | 
						|
   jmp   ASM_PFX(CommonEntry)
 | 
						|
ASM_PFX(Exception16Handle):
 | 
						|
   cli
 | 
						|
   pushl %eax
 | 
						|
   mov   $16, %eax
 | 
						|
   jmp   ASM_PFX(CommonEntry)
 | 
						|
ASM_PFX(Exception17Handle):
 | 
						|
   cli
 | 
						|
   pushl %eax
 | 
						|
   mov   $17, %eax
 | 
						|
   jmp   ASM_PFX(CommonEntry)
 | 
						|
ASM_PFX(Exception18Handle):
 | 
						|
   cli
 | 
						|
   pushl %eax
 | 
						|
   mov   $18, %eax
 | 
						|
   jmp   ASM_PFX(CommonEntry)
 | 
						|
ASM_PFX(Exception19Handle):
 | 
						|
   cli
 | 
						|
   pushl %eax
 | 
						|
   mov   $19, %eax
 | 
						|
   jmp   ASM_PFX(CommonEntry)
 | 
						|
 | 
						|
ASM_PFX(TimerInterruptHandle):
 | 
						|
   cli
 | 
						|
   pushl %eax
 | 
						|
   mov   $32, %eax
 | 
						|
   jmp   ASM_PFX(CommonEntry)
 | 
						|
 | 
						|
 | 
						|
ASM_PFX(CommonEntry):
 | 
						|
 | 
						|
#---------------------------------------;
 | 
						|
# _CommonEntry                  ;
 | 
						|
#----------------------------------------------------------------------------;
 | 
						|
# The follow algorithm is used for the common interrupt routine.
 | 
						|
# Entry from each interrupt with a push eax and eax=interrupt number
 | 
						|
#
 | 
						|
# +---------------------+
 | 
						|
# +    EFlags           +
 | 
						|
# +---------------------+
 | 
						|
# +    CS               +
 | 
						|
# +---------------------+
 | 
						|
# +    EIP              +
 | 
						|
# +---------------------+
 | 
						|
# +    Error Code       +
 | 
						|
# +---------------------+
 | 
						|
# + EAX / Vector Number +
 | 
						|
# +---------------------+
 | 
						|
# +    EBP              +
 | 
						|
# +---------------------+ <-- EBP
 | 
						|
#
 | 
						|
 | 
						|
# We need to determine if any extra data was pushed by the exception
 | 
						|
  cmpl    $DEBUG_EXCEPT_DOUBLE_FAULT, %eax
 | 
						|
  je      NoExtrPush
 | 
						|
  cmpl    $DEBUG_EXCEPT_INVALID_TSS, %eax
 | 
						|
  je      NoExtrPush
 | 
						|
  cmpl    $DEBUG_EXCEPT_SEG_NOT_PRESENT, %eax
 | 
						|
  je      NoExtrPush
 | 
						|
  cmpl    $DEBUG_EXCEPT_STACK_FAULT, %eax
 | 
						|
  je      NoExtrPush
 | 
						|
  cmpl    $DEBUG_EXCEPT_GP_FAULT, %eax
 | 
						|
  je      NoExtrPush
 | 
						|
  cmpl    $DEBUG_EXCEPT_PAGE_FAULT, %eax
 | 
						|
  je      NoExtrPush
 | 
						|
  cmpl    $DEBUG_EXCEPT_ALIGNMENT_CHECK, %eax
 | 
						|
  je      NoExtrPush
 | 
						|
 | 
						|
  pushl    (%esp)
 | 
						|
  movl     $0, 4(%esp)
 | 
						|
 | 
						|
NoExtrPush:
 | 
						|
 | 
						|
  pushl   %ebp
 | 
						|
  movl    %esp,%ebp
 | 
						|
 | 
						|
  #
 | 
						|
  # Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of EFI_SYSTEM_CONTEXT_IA32
 | 
						|
  # is 16-byte aligned
 | 
						|
  #
 | 
						|
  andl    $0xfffffff0,%esp
 | 
						|
  subl    $12,%esp
 | 
						|
 | 
						|
## UINT32  Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;
 | 
						|
  pushl   0x4(%ebp)
 | 
						|
  pushl   %ebx
 | 
						|
  pushl   %ecx
 | 
						|
  pushl   %edx
 | 
						|
  mov     %eax, %ebx                   # save vector in ebx
 | 
						|
  leal    24(%ebp),%ecx
 | 
						|
  pushl   %ecx                         # save original ESP
 | 
						|
  pushl   (%ebp)
 | 
						|
  pushl   %esi
 | 
						|
  pushl   %edi
 | 
						|
 | 
						|
## UINT32  Cr0, Cr1, Cr2, Cr3, Cr4;
 | 
						|
  movl    %cr4, %eax
 | 
						|
  orl     $0x208,%eax
 | 
						|
  movl    %eax, %cr4
 | 
						|
  pushl   %eax
 | 
						|
  movl    %cr3, %eax
 | 
						|
  pushl   %eax
 | 
						|
  movl    %cr2, %eax
 | 
						|
  pushl   %eax
 | 
						|
  xorl    %eax,%eax
 | 
						|
  pushl   %eax
 | 
						|
  movl    %cr0, %eax
 | 
						|
  pushl   %eax
 | 
						|
 | 
						|
## UINT32  Gs, Fs, Es, Ds, Cs, Ss;
 | 
						|
  movl    %ss,%eax
 | 
						|
  pushl   %eax
 | 
						|
  movzwl  16(%ebp), %eax
 | 
						|
  pushl   %eax
 | 
						|
  movl    %ds,%eax
 | 
						|
  pushl   %eax
 | 
						|
  movl    %es,%eax
 | 
						|
  pushl   %eax
 | 
						|
  movl    %fs,%eax
 | 
						|
  pushl   %eax
 | 
						|
  movl    %gs,%eax
 | 
						|
  pushl   %eax
 | 
						|
 | 
						|
## UINT32  Eip;
 | 
						|
  pushl   12(%ebp)
 | 
						|
 | 
						|
## UINT32  Gdtr[2], Idtr[2];
 | 
						|
  subl    $8,%esp
 | 
						|
  sidt    (%esp)
 | 
						|
  subl    $8,%esp
 | 
						|
  sgdt    (%esp)
 | 
						|
 | 
						|
## UINT32  Ldtr, Tr;
 | 
						|
  xorl    %eax,%eax
 | 
						|
  strl    %eax
 | 
						|
  pushl   %eax
 | 
						|
  sldtl   %eax
 | 
						|
  pushl   %eax
 | 
						|
 | 
						|
## UINT32  EFlags;
 | 
						|
  pushl   20(%ebp)
 | 
						|
 | 
						|
## UINT32  Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
 | 
						|
  movl    %dr7, %eax
 | 
						|
  pushl   %eax
 | 
						|
## clear Dr7 while executing debugger itself
 | 
						|
  xorl    %eax,%eax
 | 
						|
#  movl    %eax, %dr7
 | 
						|
 | 
						|
  movl    %dr6, %eax
 | 
						|
  pushl   %eax
 | 
						|
## insure all status bits in dr6 are clear...
 | 
						|
  xorl    %eax,%eax
 | 
						|
  movl    %eax, %dr6
 | 
						|
 | 
						|
  movl    %dr3, %eax
 | 
						|
  pushl   %eax
 | 
						|
  movl    %dr2, %eax
 | 
						|
  pushl   %eax
 | 
						|
  movl    %dr1, %eax
 | 
						|
  pushl   %eax
 | 
						|
  movl    %dr0, %eax
 | 
						|
  pushl   %eax
 | 
						|
 | 
						|
## FX_SAVE_STATE_IA32 FxSaveState;
 | 
						|
  subl    $512,%esp
 | 
						|
  movl    %esp,%edi
 | 
						|
  .byte 0x0f, 0xae, 0x07   # fxsave [edi]
 | 
						|
 | 
						|
## Clear Direction Flag
 | 
						|
  cld
 | 
						|
	
 | 
						|
## Prepare parameter and call C function
 | 
						|
  pushl   %esp
 | 
						|
  pushl   %ebx
 | 
						|
  call    ASM_PFX(InterruptProcess)
 | 
						|
  addl    $8,%esp
 | 
						|
 | 
						|
## FX_SAVE_STATE_IA32 FxSaveState;
 | 
						|
  movl    %esp,%esi
 | 
						|
  .byte 0x0f, 0xae, 0x0e   # fxrstor [esi]
 | 
						|
  addl    $512,%esp
 | 
						|
 | 
						|
## UINT32  Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
 | 
						|
  popl    %eax
 | 
						|
  movl    %eax, %dr0
 | 
						|
  popl    %eax
 | 
						|
  movl    %eax, %dr1
 | 
						|
  popl    %eax
 | 
						|
  movl    %eax, %dr2
 | 
						|
  popl    %eax
 | 
						|
  movl    %eax, %dr3
 | 
						|
## skip restore of dr6.  We cleared dr6 during the context save.
 | 
						|
  addl    $4,%esp
 | 
						|
  popl    %eax
 | 
						|
  movl    %eax, %dr7
 | 
						|
 | 
						|
## UINT32  EFlags;
 | 
						|
  popl    20(%ebp)
 | 
						|
 | 
						|
## UINT32  Ldtr, Tr;
 | 
						|
## UINT32  Gdtr[2], Idtr[2];
 | 
						|
## Best not let anyone mess with these particular registers...
 | 
						|
  addl     $24,%esp
 | 
						|
 | 
						|
## UINT32  Eip;
 | 
						|
   pop     12(%ebp)
 | 
						|
 | 
						|
## UINT32  Gs, Fs, Es, Ds, Cs, Ss;
 | 
						|
## NOTE - modified segment registers could hang the debugger...  We
 | 
						|
##        could attempt to insulate ourselves against this possibility,
 | 
						|
##        but that poses risks as well.
 | 
						|
##
 | 
						|
  popl    %gs
 | 
						|
  popl    %fs
 | 
						|
  popl    %es
 | 
						|
  popl    %ds
 | 
						|
  popl    16(%ebp)
 | 
						|
  popl    %ss
 | 
						|
 | 
						|
## UINT32  Cr0, Cr1, Cr2, Cr3, Cr4;
 | 
						|
  popl    %eax
 | 
						|
  movl    %eax, %cr0
 | 
						|
  addl    $4,%esp   # not for Cr1
 | 
						|
  popl    %eax
 | 
						|
  movl    %eax, %cr2
 | 
						|
  popl    %eax
 | 
						|
  movl    %eax, %cr3
 | 
						|
  popl    %eax
 | 
						|
  movl    %eax, %cr4
 | 
						|
 | 
						|
## UINT32  Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;
 | 
						|
  popl    %edi
 | 
						|
  popl    %esi
 | 
						|
  addl    $4,%esp  # not for ebp
 | 
						|
  addl    $4,%esp  # not for esp
 | 
						|
  popl    %edx
 | 
						|
  popl    %ecx
 | 
						|
  popl    %ebx
 | 
						|
  popl    %eax
 | 
						|
 | 
						|
  movl    %ebp,%esp
 | 
						|
  popl    %ebp
 | 
						|
  addl    $8,%esp   # skip eax
 | 
						|
  iretl
 | 
						|
  
 |