From: "Ni, Ray" <ray.ni@intel.com>
To: "Tan, Dun" <dun.tan@intel.com>,
"devel@edk2.groups.io" <devel@edk2.groups.io>
Cc: "Dong, Eric" <eric.dong@intel.com>,
"Kumar, Rahul R" <rahul.r.kumar@intel.com>
Subject: Re: [Patch V3 2/4] UefiCpuPkg: Add Unit tests for PeiCpuExceptionHandlerLib
Date: Fri, 14 Oct 2022 11:58:06 +0000 [thread overview]
Message-ID: <MWHPR11MB16315A5BAF09921007EAF5C48C249@MWHPR11MB1631.namprd11.prod.outlook.com> (raw)
In-Reply-To: <20221014091931.847-3-dun.tan@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
> -----Original Message-----
> From: Tan, Dun <dun.tan@intel.com>
> Sent: Friday, October 14, 2022 5:19 PM
> To: devel@edk2.groups.io
> Cc: Dong, Eric <eric.dong@intel.com>; Ni, Ray <ray.ni@intel.com>; Kumar, Rahul R <rahul.r.kumar@intel.com>
> Subject: [Patch V3 2/4] 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>
> Cc: Ray Ni <ray.ni@intel.com>
> Cc: Rahul Kumar <rahul1.kumar@intel.com>
> ---
> UefiCpuPkg/CpuExceptionHandlerUnitTest/CpuExceptionHandlerTest.h | 9 +++++++++
> UefiCpuPkg/CpuExceptionHandlerUnitTest/Ia32/ArchExceptionHandlerTest.c | 135
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++
> UefiCpuPkg/CpuExceptionHandlerUnitTest/Ia32/ArchExceptionHandlerTestAsm.nasm | 208
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++
> UefiCpuPkg/CpuExceptionHandlerUnitTest/PeiCpuExceptionHandlerLibUnitTest.inf | 61
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> UefiCpuPkg/CpuExceptionHandlerUnitTest/PeiCpuExceptionHandlerUnitTest.c | 204
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++
> 5 files changed, 617 insertions(+)
>
> diff --git a/UefiCpuPkg/CpuExceptionHandlerUnitTest/CpuExceptionHandlerTest.h
> b/UefiCpuPkg/CpuExceptionHandlerUnitTest/CpuExceptionHandlerTest.h
> index 936098fde8..bad3387db5 100644
> --- a/UefiCpuPkg/CpuExceptionHandlerUnitTest/CpuExceptionHandlerTest.h
> +++ b/UefiCpuPkg/CpuExceptionHandlerUnitTest/CpuExceptionHandlerTest.h
> @@ -93,6 +93,15 @@ typedef struct {
> UINT64 R15;
> } GENERAL_REGISTER;
>
> +typedef struct {
> + UINT32 Edi;
> + UINT32 Esi;
> + UINT32 Ebx;
> + UINT32 Edx;
> + UINT32 Ecx;
> + UINT32 Eax;
> +} GENERAL_REGISTER_IA32;
> +
> extern UINTN mFaultInstructionLength;
> extern EFI_EXCEPTION_TYPE mExceptionType;
> extern UINTN mRspAddress[];
> diff --git a/UefiCpuPkg/CpuExceptionHandlerUnitTest/Ia32/ArchExceptionHandlerTest.c
> b/UefiCpuPkg/CpuExceptionHandlerUnitTest/Ia32/ArchExceptionHandlerTest.c
> new file mode 100644
> index 0000000000..8bb27249dc
> --- /dev/null
> +++ b/UefiCpuPkg/CpuExceptionHandlerUnitTest/Ia32/ArchExceptionHandlerTest.c
> @@ -0,0 +1,135 @@
> +/** @file
> + Unit tests of the CpuExceptionHandlerLib.
> +
> + Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "CpuExceptionHandlerTest.h"
> +
> +GENERAL_REGISTER_IA32 mActualContextInHandler;
> +GENERAL_REGISTER_IA32 mActualContextAfterException;
> +
> +//
> +// In TestCpuContextConsistency, Cpu registers will be set to
> mExpectedContextInHandler/mExpectedContextAfterException.
> +// Ecx in mExpectedContextInHandler is set runtime since Ecx is needed in assembly code.
> +// For GP and PF, Ecx is set to FaultParameter. For other exception triggered by INTn, Ecx is set to ExceptionType.
> +//
> +GENERAL_REGISTER_IA32 mExpectedContextInHandler = { 1, 2, 3, 4, 5, 0 };
> +GENERAL_REGISTER_IA32 mExpectedContextAfterException = { 11, 12, 13, 14, 15, 16 };
> +
> +/**
> + Special handler for fault exception.
> + Rip/Eip in SystemContext will be modified to the instruction after the exception instruction.
> +
> + @param ExceptionType Exception type.
> + @param SystemContext Pointer to EFI_SYSTEM_CONTEXT.
> +
> +**/
> +VOID
> +EFIAPI
> +AdjustRipForFaultHandler (
> + IN EFI_EXCEPTION_TYPE ExceptionType,
> + IN EFI_SYSTEM_CONTEXT SystemContext
> + )
> +{
> + mExceptionType = ExceptionType;
> + SystemContext.SystemContextIa32->Eip += mFaultInstructionLength;
> +}
> +
> +/**
> + Special handler for ConsistencyOfCpuContext test case.
> +
> + @param ExceptionType Exception type.
> + @param SystemContext Pointer to EFI_SYSTEM_CONTEXT.
> +**/
> +VOID
> +EFIAPI
> +AdjustCpuContextHandler (
> + IN EFI_EXCEPTION_TYPE ExceptionType,
> + IN EFI_SYSTEM_CONTEXT SystemContext
> + )
> +{
> + //
> + // Store SystemContext in exception handler.
> + //
> + mActualContextInHandler.Edi = SystemContext.SystemContextIa32->Edi;
> + mActualContextInHandler.Esi = SystemContext.SystemContextIa32->Esi;
> + mActualContextInHandler.Ebx = SystemContext.SystemContextIa32->Ebx;
> + mActualContextInHandler.Edx = SystemContext.SystemContextIa32->Edx;
> + mActualContextInHandler.Ecx = SystemContext.SystemContextIa32->Ecx;
> + mActualContextInHandler.Eax = SystemContext.SystemContextIa32->Eax;
> +
> + //
> + // Modify cpu context. These registers will be stored in mActualContextAfterException.
> + // Do not handle Esp and Ebp in SystemContext. CpuExceptionHandlerLib doesn't set Esp and
> + // Esp register to the value in SystemContext.
> + //
> + SystemContext.SystemContextIa32->Edi = mExpectedContextAfterException.Edi;
> + SystemContext.SystemContextIa32->Esi = mExpectedContextAfterException.Esi;
> + SystemContext.SystemContextIa32->Ebx = mExpectedContextAfterException.Ebx;
> + SystemContext.SystemContextIa32->Edx = mExpectedContextAfterException.Edx;
> + SystemContext.SystemContextIa32->Ecx = mExpectedContextAfterException.Ecx;
> + SystemContext.SystemContextIa32->Eax = mExpectedContextAfterException.Eax;
> +
> + //
> + // When fault exception happens, eip/rip points to the faulting instruction.
> + // For now, olny GP and PF are tested in fault exception.
> + //
> + if ((ExceptionType == EXCEPT_IA32_PAGE_FAULT) || (ExceptionType == EXCEPT_IA32_GP_FAULT)) {
> + AdjustRipForFaultHandler (ExceptionType, SystemContext);
> + }
> +}
> +
> +/**
> + Compare cpu context in ConsistencyOfCpuContext test case.
> + 1.Compare mActualContextInHandler with mExpectedContextInHandler.
> + 2.Compare mActualContextAfterException with mExpectedContextAfterException.
> +
> + @retval UNIT_TEST_PASSED The Unit test has completed and it was successful.
> + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.
> +**/
> +UNIT_TEST_STATUS
> +CompareCpuContext (
> + VOID
> + )
> +{
> + UT_ASSERT_EQUAL (mActualContextInHandler.Edi, mExpectedContextInHandler.Edi);
> + UT_ASSERT_EQUAL (mActualContextInHandler.Esi, mExpectedContextInHandler.Esi);
> + UT_ASSERT_EQUAL (mActualContextInHandler.Ebx, mExpectedContextInHandler.Ebx);
> + UT_ASSERT_EQUAL (mActualContextInHandler.Edx, mExpectedContextInHandler.Edx);
> + UT_ASSERT_EQUAL (mActualContextInHandler.Ecx, mExpectedContextInHandler.Ecx);
> + UT_ASSERT_EQUAL (mActualContextInHandler.Eax, mExpectedContextInHandler.Eax);
> +
> + UT_ASSERT_EQUAL (mActualContextAfterException.Edi, mExpectedContextAfterException.Edi);
> + UT_ASSERT_EQUAL (mActualContextAfterException.Esi, mExpectedContextAfterException.Esi);
> + UT_ASSERT_EQUAL (mActualContextAfterException.Ebx, mExpectedContextAfterException.Ebx);
> + UT_ASSERT_EQUAL (mActualContextAfterException.Edx, mExpectedContextAfterException.Edx);
> + UT_ASSERT_EQUAL (mActualContextAfterException.Ecx, mExpectedContextAfterException.Ecx);
> + UT_ASSERT_EQUAL (mActualContextAfterException.Eax, mExpectedContextAfterException.Eax);
> + return UNIT_TEST_PASSED;
> +}
> +
> +/**
> + Special handler for CpuStackGuard test case.
> +
> + @param ExceptionType Exception type.
> + @param SystemContext Pointer to EFI_SYSTEM_CONTEXT.
> +
> +**/
> +VOID
> +EFIAPI
> +CpuStackGuardExceptionHandler (
> + IN EFI_EXCEPTION_TYPE ExceptionType,
> + IN EFI_SYSTEM_CONTEXT SystemContext
> + )
> +{
> + UINTN LocalVariable;
> +
> + AdjustRipForFaultHandler (ExceptionType, SystemContext);
> + mRspAddress[0] = (UINTN)SystemContext.SystemContextIa32->Esp;
> + mRspAddress[1] = (UINTN)(&LocalVariable);
> +
> + return;
> +}
> diff --git a/UefiCpuPkg/CpuExceptionHandlerUnitTest/Ia32/ArchExceptionHandlerTestAsm.nasm
> b/UefiCpuPkg/CpuExceptionHandlerUnitTest/Ia32/ArchExceptionHandlerTestAsm.nasm
> new file mode 100644
> index 0000000000..48031a5109
> --- /dev/null
> +++ b/UefiCpuPkg/CpuExceptionHandlerUnitTest/Ia32/ArchExceptionHandlerTestAsm.nasm
> @@ -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
> diff --git a/UefiCpuPkg/CpuExceptionHandlerUnitTest/PeiCpuExceptionHandlerLibUnitTest.inf
> b/UefiCpuPkg/CpuExceptionHandlerUnitTest/PeiCpuExceptionHandlerLibUnitTest.inf
> new file mode 100644
> index 0000000000..25f8f8dbe0
> --- /dev/null
> +++ b/UefiCpuPkg/CpuExceptionHandlerUnitTest/PeiCpuExceptionHandlerLibUnitTest.inf
> @@ -0,0 +1,61 @@
> +## @file
> +# Unit tests of the PeiCpuExceptionHandlerLib instance.
> +#
> +# Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> +
> +[Defines]
> + INF_VERSION = 0x00010006
> + BASE_NAME = CpuExceptionHandlerPeiTest
> + FILE_GUID = 39A96CF7-F369-4357-9234-4B52F98A007F
> + MODULE_TYPE = PEIM
> + VERSION_STRING = 1.0
> + ENTRY_POINT = PeiEntryPoint
> +
> +#
> +# The following information is for reference only and not required by the build tools.
> +#
> +# VALID_ARCHITECTURES = IA32 X64
> +#
> +[Sources.Ia32]
> + Ia32/ArchExceptionHandlerTestAsm.nasm
> + Ia32/ArchExceptionHandlerTest.c
> +
> +[Sources.X64]
> + X64/ArchExceptionHandlerTestAsm.nasm
> + X64/ArchExceptionHandlerTest.c
> +
> +[Sources.common]
> + CpuExceptionHandlerTest.h
> + CpuExceptionHandlerTestCommon.c
> + PeiCpuExceptionHandlerUnitTest.c
> +
> +[Packages]
> + MdePkg/MdePkg.dec
> + MdeModulePkg/MdeModulePkg.dec
> + UefiCpuPkg/UefiCpuPkg.dec
> +
> +[LibraryClasses]
> + BaseLib
> + BaseMemoryLib
> + DebugLib
> + UnitTestLib
> + MemoryAllocationLib
> + CpuExceptionHandlerLib
> + PeimEntryPoint
> + HobLib
> + PeiServicesLib
> + CpuPageTableLib
> + PeiServicesTablePointerLib
> +
> +[Pcd]
> + gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard ## CONSUMES
> + gUefiCpuPkgTokenSpaceGuid.PcdCpuApStackSize ## CONSUMES
> +
> +[Ppis]
> + gEdkiiPeiMpServices2PpiGuid ## CONSUMES
> +
> +[Depex]
> + gEdkiiPeiMpServices2PpiGuid AND
> + gEfiPeiMemoryDiscoveredPpiGuid
> diff --git a/UefiCpuPkg/CpuExceptionHandlerUnitTest/PeiCpuExceptionHandlerUnitTest.c
> b/UefiCpuPkg/CpuExceptionHandlerUnitTest/PeiCpuExceptionHandlerUnitTest.c
> new file mode 100644
> index 0000000000..d9408d2f5e
> --- /dev/null
> +++ b/UefiCpuPkg/CpuExceptionHandlerUnitTest/PeiCpuExceptionHandlerUnitTest.c
> @@ -0,0 +1,204 @@
> +/** @file
> + Unit tests of the CpuExceptionHandlerLib.
> +
> + Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "CpuExceptionHandlerTest.h"
> +#include <Library/PeimEntryPoint.h>
> +#include <Library/PeiServicesLib.h>
> +#include <Library/PeiServicesTablePointerLib.h>
> +
> +/**
> + Initialize Bsp Idt with a new Idt table and return the IA32_DESCRIPTOR buffer.
> + In PEIM, store original PeiServicePointer before new Idt table.
> +
> + @return Pointer to the allocated IA32_DESCRIPTOR buffer.
> +**/
> +VOID *
> +InitializeBspIdt (
> + VOID
> + )
> +{
> + UINTN *NewIdtTable;
> + IA32_DESCRIPTOR *Idtr;
> +
> + Idtr = AllocateZeroPool (sizeof (IA32_DESCRIPTOR));
> + ASSERT (Idtr != NULL);
> + NewIdtTable = AllocateZeroPool (sizeof (IA32_IDT_GATE_DESCRIPTOR) * CPU_INTERRUPT_NUM + sizeof (UINTN));
> + ASSERT (NewIdtTable != NULL);
> + //
> + // Store original PeiServicePointer before new Idt table
> + //
> + *NewIdtTable = (UINTN)GetPeiServicesTablePointer ();
> + NewIdtTable = (UINTN *)((UINTN)NewIdtTable + sizeof (UINTN));
> +
> + Idtr->Base = (UINTN)NewIdtTable;
> + Idtr->Limit = (UINT16)(sizeof (IA32_IDT_GATE_DESCRIPTOR) * CPU_INTERRUPT_NUM - 1);
> +
> + AsmWriteIdtr (Idtr);
> + return Idtr;
> +}
> +
> +/**
> + Retrieve the number of logical processor in the platform and the number of those logical processors that
> + are enabled on this boot.
> +
> + @param[in] MpServices MP_SERVICES structure.
> + @param[out] NumberOfProcessors Pointer to the total number of logical processors in the system, including
> + the BSP and disabled APs.
> + @param[out] NumberOfEnabledProcessors Pointer to the number of processors in the system that are enabled.
> +
> + @retval EFI_SUCCESS Retrieve the number of logical processor successfully
> + @retval Others Retrieve the number of logical processor unsuccessfully
> +**/
> +EFI_STATUS
> +MpServicesUnitTestGetNumberOfProcessors (
> + IN MP_SERVICES MpServices,
> + OUT UINTN *NumberOfProcessors,
> + OUT UINTN *NumberOfEnabledProcessors
> + )
> +{
> + return MpServices.Ppi->GetNumberOfProcessors (MpServices.Ppi, NumberOfProcessors,
> NumberOfEnabledProcessors);
> +}
> +
> +/**
> + Caller gets one enabled AP to execute a caller-provided function.
> +
> + @param[in] MpServices MP_SERVICES structure.
> + @param[in] Procedure Pointer to the function to be run on enabled APs of the system.
> + @param[in] ProcessorNumber The handle number of the AP.
> + @param[in] TimeoutInMicroSeconds Indicates the time limit in microseconds for APs to return from Procedure,
> + for blocking mode only. Zero means infinity.
> + @param[in] ProcedureArgument The parameter passed into Procedure for all APs.
> +
> +
> + @retval EFI_SUCCESS Caller gets one enabled AP to execute a caller-provided function successfully
> + @retval Others Caller gets one enabled AP to execute a caller-provided function unsuccessfully
> +**/
> +EFI_STATUS
> +MpServicesUnitTestStartupThisAP (
> + IN MP_SERVICES MpServices,
> + IN EFI_AP_PROCEDURE Procedure,
> + IN UINTN ProcessorNumber,
> + IN UINTN TimeoutInMicroSeconds,
> + IN VOID *ProcedureArgument
> + )
> +{
> + return MpServices.Ppi->StartupThisAP (MpServices.Ppi, Procedure, ProcessorNumber, TimeoutInMicroSeconds,
> ProcedureArgument);
> +}
> +
> +/**
> + Execute a caller provided function on all enabled APs.
> +
> + @param[in] MpServices MP_SERVICES structure.
> + @param[in] Procedure Pointer to the function to be run on enabled APs of the system.
> + @param[in] SingleThread If TRUE, then all the enabled APs execute the function specified by Procedure
> + one by one, in ascending order of processor handle number.
> + If FALSE, then all the enabled APs execute the function specified by Procedure
> + simultaneously.
> + @param[in] TimeoutInMicroSeconds Indicates the time limit in microseconds for APs to return from Procedure,
> + for blocking mode only. Zero means infinity.
> + @param[in] ProcedureArgument The parameter passed into Procedure for all APs.
> +
> + @retval EFI_SUCCESS Execute a caller provided function on all enabled APs successfully
> + @retval Others Execute a caller provided function on all enabled APs unsuccessfully
> +**/
> +EFI_STATUS
> +MpServicesUnitTestStartupAllAPs (
> + IN MP_SERVICES MpServices,
> + IN EFI_AP_PROCEDURE Procedure,
> + IN BOOLEAN SingleThread,
> + IN UINTN TimeoutInMicroSeconds,
> + IN VOID *ProcedureArgument
> + )
> +{
> + return MpServices.Ppi->StartupAllAPs (MpServices.Ppi, Procedure, SingleThread, TimeoutInMicroSeconds,
> ProcedureArgument);
> +}
> +
> +/**
> + Get the handle number for the calling processor.
> +
> + @param[in] MpServices MP_SERVICES structure.
> + @param[out] ProcessorNumber The handle number for the calling processor.
> +
> + @retval EFI_SUCCESS Get the handle number for the calling processor successfully.
> + @retval Others Get the handle number for the calling processor unsuccessfully.
> +**/
> +EFI_STATUS
> +MpServicesUnitTestWhoAmI (
> + IN MP_SERVICES MpServices,
> + OUT UINTN *ProcessorNumber
> + )
> +{
> + return MpServices.Ppi->WhoAmI (MpServices.Ppi, ProcessorNumber);
> +}
> +
> +/**
> + Get EDKII_PEI_MP_SERVICES2_PPI pointer.
> +
> + @param[out] MpServices Pointer to the buffer where EDKII_PEI_MP_SERVICES2_PPI is stored
> +
> + @retval EFI_SUCCESS EDKII_PEI_MP_SERVICES2_PPI interface is returned
> + @retval EFI_NOT_FOUND EDKII_PEI_MP_SERVICES2_PPI interface is not found
> +**/
> +EFI_STATUS
> +GetMpServices (
> + OUT MP_SERVICES *MpServices
> + )
> +{
> + return PeiServicesLocatePpi (&gEdkiiPeiMpServices2PpiGuid, 0, NULL, (VOID **)&MpServices->Ppi);
> +}
> +
> +/**
> + Entry point of CpuExceptionHandlerPeiTest PEIM.
> +
> + @param[in] FileHandle Handle of the file being invoked.
> + @param[in] PeiServices Describes the list of possible PEI Services.
> +
> + @retval EFI_SUCCESS The PEIM executed normally.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +PeiEntryPoint (
> + IN EFI_PEI_FILE_HANDLE FileHandle,
> + IN CONST EFI_PEI_SERVICES **PeiServices
> + )
> +{
> + EFI_STATUS Status;
> + UNIT_TEST_FRAMEWORK_HANDLE Framework;
> +
> + Framework = NULL;
> +
> + DEBUG ((DEBUG_INFO, "%a v%a\n", UNIT_TEST_APP_NAME, UNIT_TEST_APP_VERSION));
> +
> + //
> + // Start setting up the test framework for running the tests.
> + //
> + Status = InitUnitTestFramework (&Framework, UNIT_TEST_APP_NAME, gEfiCallerBaseName,
> UNIT_TEST_APP_VERSION);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "Failed in InitUnitTestFramework. Status = %r\n", Status));
> + goto EXIT;
> + }
> +
> + Status = AddCommonTestCase (Framework);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "Failed in AddCommonTestCase. Status = %r\n", Status));
> + goto EXIT;
> + }
> +
> + //
> + // Execute the tests.
> + //
> + Status = RunAllTestSuites (Framework);
> +
> +EXIT:
> + if (Framework) {
> + FreeUnitTestFramework (Framework);
> + }
> +
> + return Status;
> +}
> --
> 2.31.1.windows.1
next prev parent reply other threads:[~2022-10-14 11:58 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-10-14 9:19 [Patch V3 0/4] Add Unit tests for Pei/DxeCpuExceptionHandlerLib duntan
2022-10-14 9:19 ` [Patch V3 1/4] UefiCpuPkg: Add Unit tests for DxeCpuExceptionHandlerLib duntan
2022-10-14 11:57 ` Ni, Ray
2022-10-14 9:19 ` [Patch V3 2/4] UefiCpuPkg: Add Unit tests for PeiCpuExceptionHandlerLib duntan
2022-10-14 11:58 ` Ni, Ray [this message]
2022-10-14 9:19 ` [Patch V3 3/4] UefiCpuPkg: Add Pei/DxeCpuExceptionHandlerLibUnitTest in dsc duntan
2022-10-14 9:19 ` [Patch V3 4/4] UefiCpuPkg: Add CpuExceptionHandlerTest.h in ECC IgnoreFile duntan
2022-10-14 9:39 ` Ni, Ray
2022-10-14 10:01 ` duntan
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=MWHPR11MB16315A5BAF09921007EAF5C48C249@MWHPR11MB1631.namprd11.prod.outlook.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox