The previous change adds unit test for DxeCpuExeptionHandlerLib in 64bit mode. This change create a PEIM to add unit test for PeiCpuExceptionHandlerLib based on previous change.It can run in both 32bit and 64bit modes. Signed-off-by: Dun Tan <dun.tan@intel.com> Cc: Eric Dong <eric.dong@intel.com> Reviewed-by: Ray Ni <ray.ni@intel.com> Cc: Rahul Kumar <rahul1.kumar@intel.com>
		
			
				
	
	
		
			209 lines
		
	
	
		
			6.4 KiB
		
	
	
	
		
			NASM
		
	
	
	
	
	
			
		
		
	
	
			209 lines
		
	
	
		
			6.4 KiB
		
	
	
	
		
			NASM
		
	
	
	
	
	
| ;------------------------------------------------------------------------------
 | |
| ;
 | |
| ; Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
 | |
| ; SPDX-License-Identifier: BSD-2-Clause-Patent
 | |
| ;
 | |
| ; Module Name:
 | |
| ;
 | |
| ;   ArchExceptionHandlerTestAsm.nasm
 | |
| ;
 | |
| ; Abstract:
 | |
| ;
 | |
| ;   ia32 CPU Exception Handler Lib Unit test
 | |
| ;
 | |
| ;------------------------------------------------------------------------------
 | |
| 
 | |
|     SECTION .text
 | |
| 
 | |
| struc GENERAL_REGISTER_IA32
 | |
|   .Edi:    resd    1
 | |
|   .Esi:    resd    1
 | |
|   .Ebx:    resd    1
 | |
|   .Edx:    resd    1
 | |
|   .Ecx:    resd    1
 | |
|   .Eax:    resd    1
 | |
| 
 | |
| endstruc
 | |
| 
 | |
| extern ASM_PFX(mExpectedContextInHandler)
 | |
| extern ASM_PFX(mActualContextAfterException)
 | |
| extern ASM_PFX(mFaultInstructionLength)
 | |
| 
 | |
| ;------------------------------------------------------------------------------
 | |
| ; VOID
 | |
| ; EFIAPI
 | |
| ; TriggerGPException (
 | |
| ;  UINTN  Cr4ReservedBit
 | |
| ;  );
 | |
| ;------------------------------------------------------------------------------
 | |
| global ASM_PFX(TriggerGPException)
 | |
| ASM_PFX(TriggerGPException):
 | |
|     ;
 | |
|     ; Set reserved bit 15 of cr4 to 1
 | |
|     ;
 | |
|     lea  ecx, [ASM_PFX(mFaultInstructionLength)]
 | |
|     mov  dword[ecx], TriggerGPExceptionAfter - TriggerGPExceptionBefore
 | |
|     mov  ecx, dword [esp + 0x4]
 | |
| TriggerGPExceptionBefore:
 | |
|     mov  cr4, ecx
 | |
| TriggerGPExceptionAfter:
 | |
|     ret
 | |
| 
 | |
| ;------------------------------------------------------------------------------
 | |
| ; VOID
 | |
| ; EFIAPI
 | |
| ; TriggerPFException (
 | |
| ;  UINTN  PfAddress
 | |
| ;  );
 | |
| ;------------------------------------------------------------------------------
 | |
| global ASM_PFX(TriggerPFException)
 | |
| ASM_PFX(TriggerPFException):
 | |
|     lea  ecx, [ASM_PFX(mFaultInstructionLength)]
 | |
|     mov  dword[ecx], TriggerPFExceptionAfter - TriggerPFExceptionBefore
 | |
|     mov  ecx, dword [esp + 0x4]
 | |
| TriggerPFExceptionBefore:
 | |
|     mov  dword[ecx], 0x1
 | |
| TriggerPFExceptionAfter:
 | |
|     ret
 | |
| 
 | |
| ;------------------------------------------------------------------------------
 | |
| ; ModifyEcxInGlobalBeforeException;
 | |
| ; This function is writed by assebly code because it's only called in this file.
 | |
| ; It's used to set Ecx in mExpectedContextInHandler for different exception.
 | |
| ;------------------------------------------------------------------------------
 | |
| global ASM_PFX(ModifyEcxInGlobalBeforeException)
 | |
| ASM_PFX(ModifyEcxInGlobalBeforeException):
 | |
|     push eax
 | |
|     lea  eax, [ASM_PFX(mExpectedContextInHandler)]
 | |
|     mov  [eax + GENERAL_REGISTER_IA32.Ecx], ecx
 | |
|     pop  eax
 | |
|     ret
 | |
| 
 | |
| ;------------------------------------------------------------------------------
 | |
| ;VOID
 | |
| ;EFIAPI
 | |
| ;AsmTestConsistencyOfCpuContext (
 | |
| ;  IN  EFI_EXCEPTION_TYPE ExceptionType
 | |
| ;  IN  UINTN              FaultParameter   OPTIONAL
 | |
| ;  );
 | |
| ;------------------------------------------------------------------------------
 | |
| global ASM_PFX(AsmTestConsistencyOfCpuContext)
 | |
| ASM_PFX(AsmTestConsistencyOfCpuContext):
 | |
|     ;
 | |
|     ; push 7 general register plus 4 bytes
 | |
|     ;
 | |
|     pushad
 | |
| 
 | |
|     ;
 | |
|     ; Modify register to mExpectedContextInHandler. Do not handle Esp and Ebp.
 | |
|     ; CpuExceptionHandlerLib doesn't set Esp and Esp register to the value in SystemContext.
 | |
|     ;
 | |
|     lea eax, [ASM_PFX(mExpectedContextInHandler)]
 | |
|     mov edi, [eax + GENERAL_REGISTER_IA32.Edi]
 | |
|     mov esi, [eax + GENERAL_REGISTER_IA32.Esi]
 | |
|     mov ebx, [eax + GENERAL_REGISTER_IA32.Ebx]
 | |
|     mov edx, [eax + GENERAL_REGISTER_IA32.Edx]
 | |
|     ;
 | |
|     ; Set ecx to ExceptionType
 | |
|     ;
 | |
|     mov ecx, dword [esp + 0x24]
 | |
|     mov eax, [eax + GENERAL_REGISTER_IA32.Eax]
 | |
| 
 | |
|     cmp  ecx, 0xd
 | |
|     jz   GPException
 | |
|     cmp  ecx, 0xe
 | |
|     jz   PFException
 | |
|     jmp  INTnException
 | |
| 
 | |
| PFException:
 | |
|     mov  ecx, dword [esp + 0x28]                    ; Set ecx to PFAddress.
 | |
|     call ASM_PFX(ModifyEcxInGlobalBeforeException)  ; Set mExpectedContextInHandler.Ecx to PFAddress.
 | |
|     push ecx                                        ; Push PfAddress into stack.
 | |
|     call ASM_PFX(TriggerPFException)
 | |
|     jmp  AfterException
 | |
| 
 | |
| GPException:
 | |
|     mov  ecx, dword [esp + 0x28]                    ; Set ecx to CR4_RESERVED_BIT.
 | |
|     call ASM_PFX(ModifyEcxInGlobalBeforeException)  ; Set mExpectedContextInHandler.Ecx to CR4_RESERVED_BIT.
 | |
|     push ecx                                        ; Push CR4_RESERVED_BIT into stack.
 | |
|     call ASM_PFX(TriggerGPException)
 | |
|     jmp  AfterException
 | |
| 
 | |
| INTnException:
 | |
|     call ASM_PFX(ModifyEcxInGlobalBeforeException)  ; Set mExpectedContextInHandler.Ecx to ExceptionType.
 | |
|     push ecx                                        ; Push ExceptionType into stack.
 | |
|     call ASM_PFX(TriggerINTnException)
 | |
| 
 | |
| AfterException:
 | |
|     ;
 | |
|     ; Save register in mActualContextAfterException.
 | |
|     ;
 | |
|     push eax
 | |
|     lea  eax, [ASM_PFX(mActualContextAfterException)]
 | |
|     mov  [eax + GENERAL_REGISTER_IA32.Edi], edi
 | |
|     mov  [eax + GENERAL_REGISTER_IA32.Esi], esi
 | |
|     mov  [eax + GENERAL_REGISTER_IA32.Ebx], ebx
 | |
|     mov  [eax + GENERAL_REGISTER_IA32.Edx], edx
 | |
|     mov  [eax + GENERAL_REGISTER_IA32.Ecx], ecx
 | |
|     pop  ecx
 | |
|     mov  [eax + GENERAL_REGISTER_IA32.Eax], ecx
 | |
|     add  esp, 4
 | |
| 
 | |
|     ;
 | |
|     ; restore original register
 | |
|     ;
 | |
|     popad
 | |
|     ret
 | |
| 
 | |
| ;------------------------------------------------------------------------------
 | |
| ; VOID
 | |
| ; EFIAPI
 | |
| ; TriggerStackOverflow (
 | |
| ;  VOID
 | |
| ;  );
 | |
| ;------------------------------------------------------------------------------
 | |
| global ASM_PFX(TriggerStackOverflow)
 | |
| ASM_PFX(TriggerStackOverflow):
 | |
|     lea  ecx, [ASM_PFX(mFaultInstructionLength)]
 | |
|     mov  dword[ecx], TriggerCpuStackGuardAfter - TriggerCpuStackGuardBefore
 | |
| TriggerCpuStackGuardBefore:
 | |
|     ;
 | |
|     ; Clear CR0.TS since it is set after return from a nested DF
 | |
|     ;
 | |
|     call TriggerCpuStackGuardBefore
 | |
|     clts
 | |
| TriggerCpuStackGuardAfter:
 | |
|     ret
 | |
| 
 | |
| ;------------------------------------------------------------------------------
 | |
| ; VOID
 | |
| ; EFIAPI
 | |
| ; TriggerINTnException (
 | |
| ;  IN  EFI_EXCEPTION_TYPE ExceptionType
 | |
| ;  );
 | |
| ;------------------------------------------------------------------------------
 | |
| global ASM_PFX(TriggerINTnException)
 | |
| ASM_PFX(TriggerINTnException):
 | |
|     push eax
 | |
|     push edx
 | |
|     lea  eax, [AsmTriggerException1 - AsmTriggerException0]
 | |
|     mov  ecx, dword [esp + 0xc]
 | |
|     push ecx
 | |
|     mul  ecx
 | |
|     mov  ecx, AsmTriggerException0
 | |
|     add  eax, ecx
 | |
|     pop  ecx
 | |
|     pop  edx
 | |
|     jmp  eax
 | |
|     ;
 | |
|     ; eax = AsmTriggerException0 + (AsmTriggerException1 - AsmTriggerException0) * ecx
 | |
|     ;
 | |
| %assign Vector 0
 | |
| %rep  22
 | |
| AsmTriggerException %+ Vector:
 | |
|     pop eax
 | |
|     INT Vector
 | |
|     ret
 | |
| %assign Vector Vector+1
 | |
| %endrep
 |