UefiCpuPkg: Add Unit tests for PeiCpuExceptionHandlerLib
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>
This commit is contained in:
@@ -0,0 +1,208 @@
|
||||
;------------------------------------------------------------------------------
|
||||
;
|
||||
; 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
|
Reference in New Issue
Block a user