Reviewed-by: Ray Ni <ray...@intel.com> > -----Original Message----- > From: Lou, Yun <yun....@intel.com> > Sent: Monday, October 10, 2022 9:53 PM > To: devel@edk2.groups.io > Cc: Lou, Yun <yun....@intel.com>; Ni, Ray <ray...@intel.com>; Dong, Eric > <eric.d...@intel.com>; Laszlo Ersek > <ler...@redhat.com>; Kumar, Rahul R <rahul.r.ku...@intel.com> > Subject: [PATCH v2] UefiCpuPkg/Test: Add unit tests for MP service PPI and > Protocol > > From: Jason Lou <yun....@intel.com> > > The code changes add unit tests based on current UnitTestFramework. > EdkiiPeiMpServices2PpiPeiUnitTest PEI module is used to test > EdkiiPeiMpServices2Ppi and EfiMpServiceProtocolDxeUnitTest DXE driver is > used to test EfiMpServiceProtocol. > > Signed-off-by: Jason Lou <yun....@intel.com> > Cc: Ray Ni <ray...@intel.com> > Cc: Eric Dong <eric.d...@intel.com> > Cc: Laszlo Ersek <ler...@redhat.com> > Cc: Rahul Kumar <rahul1.ku...@intel.com> > --- > > UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EdkiiPeiMpServices2PpiUnitTest.c > | 477 ++++++ > > UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EfiMpServiceProtocolUnitTest.c > | 244 +++ > > UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EfiMpServicesUnitTestCommom.c > | 1776 > ++++++++++++++++++++ > > UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EdkiiPeiMpServices2PpiPeiUnitTest.inf > | 46 + > > UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EfiMpServiceProtocolDxeUnitTest.inf > | 46 + > > UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EfiMpServicesUnitTestCommom.h > | 627 +++++++ > UefiCpuPkg/UefiCpuPkg.dsc > | 5 + > 7 files changed, 3221 insertions(+) > > diff --git > a/UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EdkiiPeiMpServices2PpiUnitTest.c > b/UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EdkiiPeiMpServices2PpiUnitTest.c > new file mode 100644 > index 0000000000..5c42a81d29 > --- /dev/null > +++ > b/UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EdkiiPeiMpServices2PpiUnitTest.c > @@ -0,0 +1,477 @@ > +/** @file > > + PEI Module to test APIs defined in EdkiiPeiMpServices2Ppi. > > + > > + Copyright (c) 2022, Intel Corporation. All rights reserved.<BR> > > + > > + SPDX-License-Identifier: BSD-2-Clause-Patent > > + > > +**/ > > + > > +#include <Library/PeimEntryPoint.h> > > +#include <Library/PeiServicesLib.h> > > +#include "EfiMpServicesUnitTestCommom.h" > > + > > +#define UNIT_TEST_NAME "EdkiiPeiMpServices2Ppi Unit Test" > > +#define UNIT_TEST_VERSION "0.1" > > + > > +/** > > + 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 > > +MpServicesUnitTestGetMpServices ( > > + OUT MP_SERVICES *MpServices > > + ) > > +{ > > + return PeiServicesLocatePpi (&gEdkiiPeiMpServices2PpiGuid, 0, NULL, (VOID > **)&MpServices->Ppi); > > +} > > + > > +/** > > + 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); > > +} > > + > > +/** > > + Get detailed information on the requested logical processor. > > + > > + @param[in] MpServices MP_SERVICES structure. > > + @param[in] ProcessorNumber The handle number of the processor. > > + @param[out] ProcessorInfoBuffer Pointer to the buffer where the processor > information is stored. > > + > > + @retval EFI_SUCCESS Get information on the requested logical > processor successfully > > + @retval Others Get information on the requested logical > processor unsuccessfully > > +**/ > > +EFI_STATUS > > +MpServicesUnitTestGetProcessorInfo ( > > + IN MP_SERVICES MpServices, > > + IN UINTN ProcessorNumber, > > + OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer > > + ) > > +{ > > + return MpServices.Ppi->GetProcessorInfo (MpServices.Ppi, ProcessorNumber, > ProcessorInfoBuffer); > > +} > > + > > +/** > > + 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); > > +} > > + > > +/** > > + 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); > > +} > > + > > +/** > > + Switch the requested AP to be the BSP from that point onward. > > + > > + @param[in] MpServices MP_SERVICES structure. > > + @param[in] ProcessorNumber The handle number of AP that is to become the > new BSP. > > + @param[in] EnableOldBSP If TRUE, the old BSP will be listed as an > enabled AP. Otherwise, it will be disabled. > > + > > + @retval EFI_SUCCESS Switch the requested AP to be the BSP > successfully > > + @retval Others Switch the requested AP to be the BSP > unsuccessfully > > +**/ > > +EFI_STATUS > > +MpServicesUnitTestSwitchBSP ( > > + IN MP_SERVICES MpServices, > > + IN UINTN ProcessorNumber, > > + IN BOOLEAN EnableOldBSP > > + ) > > +{ > > + return MpServices.Ppi->SwitchBSP (MpServices.Ppi, ProcessorNumber, > EnableOldBSP); > > +} > > + > > +/** > > + Caller enables or disables an AP from this point onward. > > + > > + @param[in] MpServices MP_SERVICES structure. > > + @param[in] ProcessorNumber The handle number of the AP. > > + @param[in] EnableAP Specifies the new state for the processor for > enabled, FALSE for disabled. > > + @param[in] HealthFlag If not NULL, a pointer to a value that specifies > the new health status of the AP. > > + > > + @retval EFI_SUCCESS Caller enables or disables an AP successfully. > > + @retval Others Caller enables or disables an AP unsuccessfully. > > +**/ > > +EFI_STATUS > > +MpServicesUnitTestEnableDisableAP ( > > + IN MP_SERVICES MpServices, > > + IN UINTN ProcessorNumber, > > + IN BOOLEAN EnableAP, > > + IN UINT32 *HealthFlag > > + ) > > +{ > > + return MpServices.Ppi->EnableDisableAP (MpServices.Ppi, ProcessorNumber, > EnableAP, HealthFlag); > > +} > > + > > +/** > > + 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); > > +} > > + > > +/** > > + Execute a caller provided function on all enabled CPUs. > > + > > + @param[in] MpServices MP_SERVICES structure. > > + @param[in] Procedure Pointer to the function to be run on enabled > CPUs of the system. > > + @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 enabled CPUs. > > + > > + @retval EFI_SUCCESS Execute a caller provided function on all > enabled CPUs successfully > > + @retval Others Execute a caller provided function on all > enabled CPUs unsuccessfully > > +**/ > > +EFI_STATUS > > +MpServicesUnitTestStartupAllCPUs ( > > + IN MP_SERVICES MpServices, > > + IN EFI_AP_PROCEDURE Procedure, > > + IN UINTN TimeoutInMicroSeconds, > > + IN VOID *ProcedureArgument > > + ) > > +{ > > + return MpServices.Ppi->StartupAllCPUs (MpServices.Ppi, Procedure, > TimeoutInMicroSeconds, ProcedureArgument); > > +} > > + > > +/** > > + Infinite loop procedure to be run on specified AP. > > + > > + @param[in,out] Buffer The pointer to private data buffer. > > +**/ > > +VOID > > +ApInfiniteLoopProcedure ( > > + IN OUT VOID *Buffer > > + ) > > +{ > > + EFI_STATUS Status; > > + UINTN ProcessorNumber; > > + volatile BOOLEAN InfiniteLoop; > > + MP_SERVICE_UT_CONTEXT *LocalContext; > > + > > + LocalContext = (MP_SERVICE_UT_CONTEXT *)Buffer; > > + > > + Status = MpServicesUnitTestWhoAmI (LocalContext->MpServices, > &ProcessorNumber); > > + ASSERT_EFI_ERROR (Status); > > + > > + if (ProcessorNumber == LocalContext->BspNumber) { > > + InfiniteLoop = FALSE; > > + } else { > > + InfiniteLoop = TRUE; > > + } > > + > > + while (InfiniteLoop) { > > + } > > +} > > + > > +/** > > + Procedure to run MP service StartupAllCPUs on AP. > > + > > + @param[in,out] Buffer The pointer to private data buffer. > > +**/ > > +VOID > > +RunMpServiceStartupAllCPUsOnAp ( > > + IN OUT VOID *Buffer > > + ) > > +{ > > + MP_SERVICE_UT_CONTEXT *LocalContext; > > + > > + LocalContext = (MP_SERVICE_UT_CONTEXT *)Buffer; > > + > > + LocalContext->ApProcedureReturnStatus = MpServicesUnitTestStartupAllCPUs ( > > + LocalContext->MpServices, > > + (EFI_AP_PROCEDURE)EmptyProcedure, > > + 0, > > + NULL > > + ); > > +} > > + > > +/** > > + Unit test of PEI MP service StartupAllCPU. > > + All CPUs should execute the Procedure. > > + > > + @param[in] Context Context pointer for this test. > > + > > + @retval UNIT_TEST_PASSED The Unit test has completed and the > test > > + case was successful. > > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed. > > +**/ > > +UNIT_TEST_STATUS > > +EFIAPI > > +TestStartupAllCPUs1 ( > > + IN UNIT_TEST_CONTEXT Context > > + ) > > +{ > > + EFI_STATUS Status; > > + UINTN ProcessorIndex; > > + MP_SERVICE_UT_CONTEXT *LocalContext; > > + > > + LocalContext = (MP_SERVICE_UT_CONTEXT *)Context; > > + > > + SetMem (LocalContext->CommonBuffer, LocalContext->NumberOfProcessors * > sizeof (*LocalContext- > >CommonBuffer), 0xFF); > > + Status = MpServicesUnitTestStartupAllCPUs ( > > + LocalContext->MpServices, > > + (EFI_AP_PROCEDURE)StoreCpuNumbers, > > + 0, > > + (VOID *)LocalContext > > + ); > > + UT_ASSERT_NOT_EFI_ERROR (Status); > > + > > + for (ProcessorIndex = 0; ProcessorIndex < > LocalContext->NumberOfProcessors; ProcessorIndex++) { > > + UT_ASSERT_TRUE (LocalContext->CommonBuffer[ProcessorIndex] == > ProcessorIndex); > > + } > > + > > + return UNIT_TEST_PASSED; > > +} > > + > > +/** > > + Unit test of PEI MP service StartupAllCPU. > > + When this service is called from an AP, the return status should be > EFI_DEVICE_ERROR. > > + > > + @param[in] Context Context pointer for this test. > > + > > + @retval UNIT_TEST_PASSED The Unit test has completed and the > test > > + case was successful. > > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed. > > +**/ > > +UNIT_TEST_STATUS > > +EFIAPI > > +TestStartupAllCPUs2 ( > > + IN UNIT_TEST_CONTEXT Context > > + ) > > +{ > > + EFI_STATUS Status; > > + UINTN ApNumber; > > + MP_SERVICE_UT_CONTEXT *LocalContext; > > + > > + LocalContext = (MP_SERVICE_UT_CONTEXT *)Context; > > + > > + for (ApNumber = 0; ApNumber < LocalContext->NumberOfProcessors; > ApNumber++) { > > + LocalContext->ApNumber = ApNumber; > > + Status = MpServicesUnitTestStartupThisAP ( > > + LocalContext->MpServices, > > + > (EFI_AP_PROCEDURE)RunMpServiceStartupAllCPUsOnAp, > > + ApNumber, > > + 0, > > + (VOID *)LocalContext > > + ); > > + > > + if (ApNumber == LocalContext->BspNumber) { > > + UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER); > > + } else { > > + UT_ASSERT_NOT_EFI_ERROR (Status); > > + UT_ASSERT_STATUS_EQUAL (LocalContext->ApProcedureReturnStatus, > EFI_DEVICE_ERROR); > > + } > > + } > > + > > + return UNIT_TEST_PASSED; > > +} > > + > > +/** > > + Unit test of PEI MP service StartupAllCPU. > > + When called with all CPUs timeout, the return status should be EFI_TIMEOUT. > > + > > + @param[in] Context Context pointer for this test. > > + > > + @retval UNIT_TEST_PASSED The Unit test has completed and the > test > > + case was successful. > > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed. > > +**/ > > +UNIT_TEST_STATUS > > +EFIAPI > > +TestStartupAllCPUs3 ( > > + IN UNIT_TEST_CONTEXT Context > > + ) > > +{ > > + EFI_STATUS Status; > > + MP_SERVICE_UT_CONTEXT *LocalContext; > > + > > + LocalContext = (MP_SERVICE_UT_CONTEXT *)Context; > > + > > + Status = MpServicesUnitTestStartupAllCPUs ( > > + LocalContext->MpServices, > > + (EFI_AP_PROCEDURE)ApInfiniteLoopProcedure, > > + RUN_PROCEDURE_TIMEOUT_VALUE, > > + (VOID *)LocalContext > > + ); > > + UT_ASSERT_STATUS_EQUAL (Status, EFI_TIMEOUT); > > + > > + return UNIT_TEST_PASSED; > > +} > > + > > +/** > > + Create test suite and unit tests only for EdkiiPeiMpServices2Ppi. > > + > > + @param[in] Framework A pointer to the framework that is being > persisted. > > + @param[in] Context A pointer to the private data buffer. > > + > > + @retval EFI_SUCCESS Create test suite and unit tests successfully. > > + @retval Others Create test suite and unit tests unsuccessfully. > > +**/ > > +EFI_STATUS > > +AddTestCaseOnlyForEdkiiPeiMpServices2Ppi ( > > + IN UNIT_TEST_FRAMEWORK_HANDLE Framework, > > + IN MP_SERVICE_UT_CONTEXT *Context > > + ) > > +{ > > + EFI_STATUS Status; > > + UNIT_TEST_SUITE_HANDLE MpServiceStartupAllCPUsTestSuite; > > + > > + MpServiceStartupAllCPUsTestSuite = NULL; > > + > > + // > > + // Test StartupAllCPUs function > > + // > > + Status = CreateUnitTestSuite (&MpServiceStartupAllCPUsTestSuite, > Framework, "Execute a caller provided function on > all enabled CPUs", "MpServices.StartupAllCPUs", NULL, NULL); > > + if (EFI_ERROR (Status)) { > > + DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for > MpServiceStartupAllCPUs Test Suite\n")); > > + return Status; > > + } > > + > > + AddTestCase (MpServiceStartupAllCPUsTestSuite, "Test StartupAllCPUs 1", > "TestStartupAllCPUs1", TestStartupAllCPUs1, > InitUTContext, CheckUTContext, Context); > > + AddTestCase (MpServiceStartupAllCPUsTestSuite, "Test StartupAllCPUs 2", > "TestStartupAllCPUs2", TestStartupAllCPUs2, > InitUTContext, CheckUTContext, Context); > > + AddTestCase (MpServiceStartupAllCPUsTestSuite, "Test StartupAllCPUs 3", > "TestStartupAllCPUs3", TestStartupAllCPUs3, > InitUTContext, CheckUTContext, Context); > > + > > + return EFI_SUCCESS; > > +} > > + > > +/** > > + Standard PEIM entry point for unit test execution from PEI. > > + Initialize the unit test framework, suite, and unit tests for the > EdkiiPeiMpServices2Ppi and run the unit test. > > + > > + @param[in] FileHandle Handle of the file being invoked. > > + @param[in] PeiServices Pointer to PEI Services table. > > + > > +**/ > > +EFI_STATUS > > +EFIAPI > > +PeiEntryPoint ( > > + IN EFI_PEI_FILE_HANDLE FileHandle, > > + IN CONST EFI_PEI_SERVICES **PeiServices > > + ) > > +{ > > + EFI_STATUS Status; > > + UNIT_TEST_FRAMEWORK_HANDLE Framework; > > + MP_SERVICE_UT_CONTEXT Context; > > + > > + Framework = NULL; > > + Context.MpServices.Ppi = NULL; > > + Context.CommonBuffer = NULL; > > + Context.DisabledApNumber = NULL; > > + > > + DEBUG ((DEBUG_INFO, "%a v%a\n", UNIT_TEST_NAME, UNIT_TEST_VERSION)); > > + > > + // > > + // Start setting up the test framework for running the tests. > > + // > > + Status = InitUnitTestFramework (&Framework, UNIT_TEST_NAME, > gEfiCallerBaseName, UNIT_TEST_VERSION); > > + if (EFI_ERROR (Status)) { > > + DEBUG ((DEBUG_ERROR, "Failed in InitUnitTestFramework. Status = %r\n", > Status)); > > + goto EXIT; > > + } > > + > > + // > > + // Create test suite and unit tests only for EdkiiPeiMpServices2Ppi. > > + // > > + Status = AddTestCaseOnlyForEdkiiPeiMpServices2Ppi (Framework, &Context); > > + if (EFI_ERROR (Status)) { > > + DEBUG ((DEBUG_ERROR, "Failed in > AddTestCaseOnlyForEdkiiPeiMpServices2Ppi. Status = %r\n", Status)); > > + goto EXIT; > > + } > > + > > + // > > + // Create test suite and unit tests for both EdkiiPeiMpServices2Ppi and > EfiMpServiceProtocol. > > + // > > + Status = AddCommonTestCase (Framework, &Context); > > + 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 != NULL) { > > + FreeUnitTestFramework (Framework); > > + } > > + > > + return Status; > > +} > > diff --git > a/UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EfiMpServiceProtocolUnitTest.c > b/UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EfiMpServiceProtocolUnitTest.c > new file mode 100644 > index 0000000000..57f8ba3c06 > --- /dev/null > +++ > b/UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EfiMpServiceProtocolUnitTest.c > @@ -0,0 +1,244 @@ > +/** @file > > + PEI Module to test EfiMpServiceProtocol. > > + > > + Copyright (c) 2022, Intel Corporation. All rights reserved.<BR> > > + > > + SPDX-License-Identifier: BSD-2-Clause-Patent > > + > > +**/ > > + > > +#include <PiDxe.h> > > +#include <Library/UefiBootServicesTableLib.h> > > +#include "EfiMpServicesUnitTestCommom.h" > > + > > +#define UNIT_TEST_NAME "EfiMpServiceProtocol Unit Test" > > +#define UNIT_TEST_VERSION "0.1" > > + > > +/** > > + Get EFI_MP_SERVICES_PROTOCOL pointer. > > + > > + @param[out] MpServices Pointer to the buffer where > EFI_MP_SERVICES_PROTOCOL is stored > > + > > + @retval EFI_SUCCESS EFI_MP_SERVICES_PROTOCOL interface is returned > > + @retval EFI_NOT_FOUND EFI_MP_SERVICES_PROTOCOL interface is not found > > +**/ > > +EFI_STATUS > > +MpServicesUnitTestGetMpServices ( > > + OUT MP_SERVICES *MpServices > > + ) > > +{ > > + return gBS->LocateProtocol (&gEfiMpServiceProtocolGuid, NULL, (VOID > **)&MpServices->Protocol); > > +} > > + > > +/** > > + 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.Protocol->GetNumberOfProcessors (MpServices.Protocol, > NumberOfProcessors, > NumberOfEnabledProcessors); > > +} > > + > > +/** > > + Get detailed information on the requested logical processor. > > + > > + @param[in] MpServices MP_SERVICES structure. > > + @param[in] ProcessorNumber The handle number of the processor. > > + @param[out] ProcessorInfoBuffer Pointer to the buffer where the processor > information is stored. > > + > > + @retval EFI_SUCCESS Get information on the requested logical > processor successfully > > + @retval Others Get information on the requested logical > processor unsuccessfully > > +**/ > > +EFI_STATUS > > +MpServicesUnitTestGetProcessorInfo ( > > + IN MP_SERVICES MpServices, > > + IN UINTN ProcessorNumber, > > + OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer > > + ) > > +{ > > + return MpServices.Protocol->GetProcessorInfo (MpServices.Protocol, > ProcessorNumber, ProcessorInfoBuffer); > > +} > > + > > +/** > > + 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.Protocol->StartupAllAPs (MpServices.Protocol, Procedure, > SingleThread, NULL, > TimeoutInMicroSeconds, ProcedureArgument, NULL); > > +} > > + > > +/** > > + 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.Protocol->StartupThisAP (MpServices.Protocol, Procedure, > ProcessorNumber, NULL, > TimeoutInMicroSeconds, ProcedureArgument, NULL); > > +} > > + > > +/** > > + Switch the requested AP to be the BSP from that point onward. > > + > > + @param[in] MpServices MP_SERVICES structure. > > + @param[in] ProcessorNumber The handle number of AP that is to become the > new BSP. > > + @param[in] EnableOldBSP If TRUE, the old BSP will be listed as an > enabled AP. Otherwise, it will be disabled. > > + > > + @retval EFI_SUCCESS Switch the requested AP to be the BSP > successfully > > + @retval Others Switch the requested AP to be the BSP > unsuccessfully > > +**/ > > +EFI_STATUS > > +MpServicesUnitTestSwitchBSP ( > > + IN MP_SERVICES MpServices, > > + IN UINTN ProcessorNumber, > > + IN BOOLEAN EnableOldBSP > > + ) > > +{ > > + return MpServices.Protocol->SwitchBSP (MpServices.Protocol, > ProcessorNumber, EnableOldBSP); > > +} > > + > > +/** > > + Caller enables or disables an AP from this point onward. > > + > > + @param[in] MpServices MP_SERVICES structure. > > + @param[in] ProcessorNumber The handle number of the AP. > > + @param[in] EnableAP Specifies the new state for the processor for > enabled, FALSE for disabled. > > + @param[in] HealthFlag If not NULL, a pointer to a value that specifies > the new health status of the AP. > > + > > + @retval EFI_SUCCESS Caller enables or disables an AP successfully. > > + @retval Others Caller enables or disables an AP unsuccessfully. > > +**/ > > +EFI_STATUS > > +MpServicesUnitTestEnableDisableAP ( > > + IN MP_SERVICES MpServices, > > + IN UINTN ProcessorNumber, > > + IN BOOLEAN EnableAP, > > + IN UINT32 *HealthFlag > > + ) > > +{ > > + return MpServices.Protocol->EnableDisableAP (MpServices.Protocol, > ProcessorNumber, EnableAP, HealthFlag); > > +} > > + > > +/** > > + 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.Protocol->WhoAmI (MpServices.Protocol, ProcessorNumber); > > +} > > + > > +/** > > + Standard DXE driver or UEFI application entry point for unit test > execution from DXE or UEFI Shell. > > + Initialize the unit test framework, suite, and unit tests for the > EfiMpServiceProtocol and run the unit test. > > + > > + @param[in] ImageHandle The firmware allocated handle for the EFI image. > > + @param[in] SystemTable A pointer to the EFI System Table. > > + > > +**/ > > +EFI_STATUS > > +EFIAPI > > +DxeEntryPoint ( > > + IN EFI_HANDLE ImageHandle, > > + IN EFI_SYSTEM_TABLE *SystemTable > > + ) > > +{ > > + EFI_STATUS Status; > > + UNIT_TEST_FRAMEWORK_HANDLE Framework; > > + MP_SERVICE_UT_CONTEXT Context; > > + > > + Framework = NULL; > > + Context.MpServices.Ppi = NULL; > > + Context.CommonBuffer = NULL; > > + Context.DisabledApNumber = NULL; > > + > > + DEBUG ((DEBUG_INFO, "%a v%a\n", UNIT_TEST_NAME, UNIT_TEST_VERSION)); > > + > > + // > > + // Start setting up the test framework for running the tests. > > + // > > + Status = InitUnitTestFramework (&Framework, UNIT_TEST_NAME, > gEfiCallerBaseName, UNIT_TEST_VERSION); > > + if (EFI_ERROR (Status)) { > > + DEBUG ((DEBUG_ERROR, "Failed in InitUnitTestFramework. Status = %r\n", > Status)); > > + goto EXIT; > > + } > > + > > + // > > + // Create test suite and unit tests for both EdkiiPeiMpServices2Ppi and > EfiMpServiceProtocol. > > + // > > + Status = AddCommonTestCase (Framework, &Context); > > + 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 != NULL) { > > + FreeUnitTestFramework (Framework); > > + } > > + > > + return Status; > > +} > > diff --git > a/UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EfiMpServicesUnitTestCommom.c > b/UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EfiMpServicesUnitTestCommom.c > new file mode 100644 > index 0000000000..ff79c5e8d4 > --- /dev/null > +++ > b/UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EfiMpServicesUnitTestCommom.c > @@ -0,0 +1,1776 @@ > +/** @file > > + Common code to test EdkiiPeiMpServices2Ppi and EfiMpServiceProtocol. > > + > > + Copyright (c) 2022, Intel Corporation. All rights reserved.<BR> > > + > > + SPDX-License-Identifier: BSD-2-Clause-Patent > > + > > +**/ > > + > > +#include "EfiMpServicesUnitTestCommom.h" > > + > > +/** > > + Prep routine for Unit test function. > > + To save the ProcessorNumber of disabled AP and temporarily enable it. > > + > > + @param[in] Context Context pointer for this test. > > + > > + @retval UNIT_TEST_PASSED Prep routine runs successful. > > + @retval UNIT_TEST_ERROR_TEST_FAILED Prep routine runs unsuccessful. > > +**/ > > +UNIT_TEST_STATUS > > +EFIAPI > > +InitUTContext ( > > + IN UNIT_TEST_CONTEXT Context > > + ) > > +{ > > + EFI_STATUS Status; > > + UINTN NumberOfProcessors; > > + UINTN NumberOfEnabledProcessors; > > + UINTN NumberOfDisabledAPs; > > + UINTN IndexOfDisabledAPs; > > + UINTN BspNumber; > > + UINTN ProcessorNumber; > > + EFI_PROCESSOR_INFORMATION ProcessorInfoBuffer; > > + MP_SERVICE_UT_CONTEXT *LocalContext; > > + > > + LocalContext = (MP_SERVICE_UT_CONTEXT *)Context; > > + > > + if (LocalContext->MpServices.Ppi != NULL) { > > + return UNIT_TEST_PASSED; > > + } > > + > > + Status = MpServicesUnitTestGetMpServices (&LocalContext->MpServices); > > + UT_ASSERT_NOT_EFI_ERROR (Status); > > + > > + Status = MpServicesUnitTestWhoAmI (LocalContext->MpServices, &BspNumber); > > + UT_ASSERT_NOT_EFI_ERROR (Status); > > + DEBUG ((DEBUG_INFO, "%a: BspNumber = 0x%x\n", __FUNCTION__, BspNumber)); > > + > > + Status = MpServicesUnitTestGetNumberOfProcessors ( > > + LocalContext->MpServices, > > + &NumberOfProcessors, > > + &NumberOfEnabledProcessors > > + ); > > + UT_ASSERT_NOT_EFI_ERROR (Status); > > + DEBUG (( > > + DEBUG_INFO, > > + "%a: NumberOfProcessors = 0x%x, NumberOfEnabledProcessors = 0x%x\n", > > + __FUNCTION__, > > + NumberOfProcessors, > > + NumberOfEnabledProcessors > > + )); > > + > > + LocalContext->BspNumber = BspNumber; > > + LocalContext->NumberOfProcessors = NumberOfProcessors; > > + LocalContext->NumberOfEnabledProcessors = NumberOfEnabledProcessors; > > + > > + LocalContext->CommonBuffer = AllocatePages (EFI_SIZE_TO_PAGES > (NumberOfProcessors * sizeof (*LocalContext- > >CommonBuffer))); > > + UT_ASSERT_NOT_NULL (LocalContext->CommonBuffer); > > + > > + NumberOfDisabledAPs = NumberOfProcessors - NumberOfEnabledProcessors; > > + if ((NumberOfDisabledAPs > 0) && (LocalContext->DisabledApNumber == NULL)) > { > > + LocalContext->DisabledApNumber = AllocatePages (EFI_SIZE_TO_PAGES > (NumberOfDisabledAPs * sizeof > (*LocalContext->DisabledApNumber))); > > + UT_ASSERT_NOT_NULL (LocalContext->DisabledApNumber); > > + ZeroMem (LocalContext->DisabledApNumber, NumberOfDisabledAPs * sizeof > (*LocalContext->DisabledApNumber)); > > + > > + for (ProcessorNumber = 0, IndexOfDisabledAPs = 0; ProcessorNumber < > LocalContext->NumberOfProcessors; > ProcessorNumber++) { > > + Status = MpServicesUnitTestGetProcessorInfo ( > > + LocalContext->MpServices, > > + ProcessorNumber, > > + &ProcessorInfoBuffer > > + ); > > + UT_ASSERT_NOT_EFI_ERROR (Status); > > + > > + if (!(ProcessorInfoBuffer.StatusFlag & PROCESSOR_ENABLED_BIT)) { > > + // > > + // Save ProcessorNumber of disabled AP. > > + // > > + LocalContext->DisabledApNumber[IndexOfDisabledAPs] = ProcessorNumber; > > + IndexOfDisabledAPs++; > > + > > + DEBUG ((DEBUG_INFO, "%a: AP(0x%x) is disabled and temporarily enable > it.\n", __FUNCTION__, ProcessorNumber)); > > + Status = MpServicesUnitTestEnableDisableAP ( > > + LocalContext->MpServices, > > + ProcessorNumber, > > + TRUE, > > + NULL > > + ); > > + UT_ASSERT_NOT_EFI_ERROR (Status); > > + } > > + } > > + > > + UT_ASSERT_TRUE (IndexOfDisabledAPs == NumberOfDisabledAPs); > > + } > > + > > + return UNIT_TEST_PASSED; > > +} > > + > > +/** > > + Cleanup routine for Unit test function. > > + If any processor is disabled unexpectedly then reenable it. > > + > > + @param[in] Context Context pointer for this test. > > +**/ > > +VOID > > +EFIAPI > > +CheckUTContext ( > > + IN UNIT_TEST_CONTEXT Context > > + ) > > +{ > > + EFI_STATUS Status; > > + UINTN NumberOfProcessors; > > + UINTN NumberOfEnabledProcessors; > > + UINTN BspNumber; > > + UINTN ProcessorNumber; > > + EFI_PROCESSOR_INFORMATION ProcessorInfoBuffer; > > + MP_SERVICE_UT_CONTEXT *LocalContext; > > + > > + LocalContext = (MP_SERVICE_UT_CONTEXT *)Context; > > + ASSERT (LocalContext->MpServices.Ppi != NULL); > > + > > + Status = MpServicesUnitTestWhoAmI (LocalContext->MpServices, &BspNumber); > > + ASSERT_EFI_ERROR (Status); > > + > > + if (BspNumber != LocalContext->BspNumber) { > > + LocalContext->BspNumber = BspNumber; > > + DEBUG ((DEBUG_INFO, "%a: New BspNumber = 0x%x\n", __FUNCTION__, > BspNumber)); > > + } > > + > > + ASSERT (BspNumber == LocalContext->BspNumber); > > + > > + Status = MpServicesUnitTestGetNumberOfProcessors ( > > + LocalContext->MpServices, > > + &NumberOfProcessors, > > + &NumberOfEnabledProcessors > > + ); > > + ASSERT_EFI_ERROR (Status); > > + > > + if (NumberOfProcessors != LocalContext->NumberOfProcessors) { > > + LocalContext->NumberOfProcessors = NumberOfProcessors; > > + DEBUG ((DEBUG_INFO, "%a: New NumberOfProcessors = 0x%x\n", __FUNCTION__, > NumberOfProcessors)); > > + } > > + > > + if (NumberOfEnabledProcessors != LocalContext->NumberOfProcessors) { > > + DEBUG ((DEBUG_INFO, "%a: New NumberOfEnabledProcessors = 0x%x\n", > __FUNCTION__, > NumberOfEnabledProcessors)); > > + > > + for (ProcessorNumber = 0; ProcessorNumber < > LocalContext->NumberOfProcessors; ProcessorNumber++) { > > + Status = MpServicesUnitTestGetProcessorInfo ( > > + LocalContext->MpServices, > > + ProcessorNumber, > > + &ProcessorInfoBuffer > > + ); > > + ASSERT_EFI_ERROR (Status); > > + > > + if (!(ProcessorInfoBuffer.StatusFlag & PROCESSOR_ENABLED_BIT)) { > > + DEBUG ((DEBUG_INFO, "%a: AP(0x%x) is disabled unexpectedly and > reenable it.\n", __FUNCTION__, > ProcessorNumber)); > > + Status = MpServicesUnitTestEnableDisableAP ( > > + LocalContext->MpServices, > > + ProcessorNumber, > > + TRUE, > > + NULL > > + ); > > + ASSERT_EFI_ERROR (Status); > > + } > > + } > > + } > > +} > > + > > +/** > > + Cleanup routine for Unit test function. > > + It will be called by the last "AddTestCase" to restore AP state and free > pointer. > > + > > + @param[in] Context Context pointer for this test. > > +**/ > > +VOID > > +EFIAPI > > +FreeUTContext ( > > + IN UNIT_TEST_CONTEXT Context > > + ) > > +{ > > + EFI_STATUS Status; > > + UINTN NumberOfDisabledAPs; > > + UINTN IndexOfDisabledAPs; > > + MP_SERVICE_UT_CONTEXT *LocalContext; > > + > > + CheckUTContext (Context); > > + > > + LocalContext = (MP_SERVICE_UT_CONTEXT *)Context; > > + ASSERT (LocalContext->MpServices.Ppi != NULL); > > + > > + if (LocalContext->DisabledApNumber != NULL) { > > + NumberOfDisabledAPs = LocalContext->NumberOfProcessors - > LocalContext->NumberOfEnabledProcessors; > > + for (IndexOfDisabledAPs = 0; IndexOfDisabledAPs < NumberOfDisabledAPs; > IndexOfDisabledAPs++) { > > + DEBUG (( > > + DEBUG_INFO, > > + "%a: Disable AP(0x%x) to restore its state.\n", > > + __FUNCTION__, > > + LocalContext->DisabledApNumber[IndexOfDisabledAPs] > > + )); > > + > > + Status = MpServicesUnitTestEnableDisableAP ( > > + LocalContext->MpServices, > > + LocalContext->DisabledApNumber[IndexOfDisabledAPs], > > + FALSE, > > + NULL > > + ); > > + ASSERT_EFI_ERROR (Status); > > + } > > + > > + FreePages (LocalContext->DisabledApNumber, EFI_SIZE_TO_PAGES > (NumberOfDisabledAPs * sizeof (*LocalContext- > >DisabledApNumber))); > > + } > > + > > + if (LocalContext->CommonBuffer != NULL) { > > + FreePages (LocalContext->CommonBuffer, EFI_SIZE_TO_PAGES > (LocalContext->NumberOfProcessors * sizeof > (*LocalContext->CommonBuffer))); > > + } > > +} > > + > > +/** > > + Produce to store ProcessorNumber in the corresponding location of > CommonBuffer. > > + > > + @param[in,out] Buffer The pointer to private data buffer. > > +**/ > > +VOID > > +StoreCpuNumbers ( > > + IN OUT VOID *Buffer > > + ) > > +{ > > + EFI_STATUS Status; > > + UINTN ProcessorNumber; > > + MP_SERVICE_UT_CONTEXT *LocalContext; > > + > > + LocalContext = (MP_SERVICE_UT_CONTEXT *)Buffer; > > + > > + Status = MpServicesUnitTestWhoAmI (LocalContext->MpServices, > &ProcessorNumber); > > + ASSERT_EFI_ERROR (Status); > > + > > + // > > + // The layout of CommonBuffer (E.g. BspNumber = 2 and NumberOfProcessors = > 6) > > + // Index 00 01 02 03 04 05 > > + // Value 00 01 02 03 04 05 > > + // > > + if (ProcessorNumber < LocalContext->NumberOfProcessors) { > > + LocalContext->CommonBuffer[ProcessorNumber] = ProcessorNumber; > > + } > > +} > > + > > +/** > > + Produce to store the ProcessorNumber of AP execution order in CommonBuffer. > > + > > + @param[in,out] Buffer The pointer to private data buffer. > > +**/ > > +VOID > > +StoreAPsExecutionOrder ( > > + IN OUT VOID *Buffer > > + ) > > +{ > > + EFI_STATUS Status; > > + UINTN ProcessorNumber; > > + UINTN *ApCounter; > > + MP_SERVICE_UT_CONTEXT *LocalContext; > > + > > + LocalContext = (MP_SERVICE_UT_CONTEXT *)Buffer; > > + > > + Status = MpServicesUnitTestWhoAmI (LocalContext->MpServices, > &ProcessorNumber); > > + ASSERT_EFI_ERROR (Status); > > + > > + // > > + // The layout of CommonBuffer (E.g. BspNumber = 2 and NumberOfProcessors = > 6) > > + // Index 00 01 02 03 04 05 > > + // Value 00 01 03 04 05 ApCounter(5) > > + // > > + ApCounter = > &(LocalContext->CommonBuffer[LocalContext->NumberOfProcessors - 1]); > > + LocalContext->CommonBuffer[*ApCounter] = ProcessorNumber; > > + (*ApCounter)++; > > +} > > + > > +/** > > + Infinite loop procedure to be run on specified CPU. > > + > > + @param[in,out] Buffer The pointer to private data buffer. > > +**/ > > +VOID > > +InfiniteLoopProcedure ( > > + IN OUT VOID *Buffer > > + ) > > +{ > > + volatile BOOLEAN InfiniteLoop; > > + > > + InfiniteLoop = TRUE; > > + > > + while (InfiniteLoop) { > > + } > > +} > > + > > +/** > > + Empty procedure to be run on specified CPU. > > + > > + @param[in,out] Buffer The pointer to private data buffer. > > +**/ > > +VOID > > +EmptyProcedure ( > > + IN OUT VOID *Buffer > > + ) > > +{ > > +} > > + > > +/** > > + Procedure to run MP service GetNumberOfProcessors on AP. > > + > > + @param[in,out] Buffer The pointer to private data buffer. > > +**/ > > +VOID > > +RunMpServiceGetNumberOfProcessorsOnAp ( > > + IN OUT VOID *Buffer > > + ) > > +{ > > + UINTN NumberOfProcessors; > > + UINTN NumberOfEnabledProcessors; > > + MP_SERVICE_UT_CONTEXT *LocalContext; > > + > > + LocalContext = (MP_SERVICE_UT_CONTEXT *)Buffer; > > + > > + LocalContext->ApProcedureReturnStatus = > MpServicesUnitTestGetNumberOfProcessors ( > > + LocalContext->MpServices, > > + &NumberOfProcessors, > > + &NumberOfEnabledProcessors > > + ); > > +} > > + > > +/** > > + Procedure to run MP service GetProcessorInfo on AP. > > + > > + @param[in,out] Buffer The pointer to private data buffer. > > +**/ > > +VOID > > +RunMpServiceGetProcessorInfoOnAp ( > > + IN OUT VOID *Buffer > > + ) > > +{ > > + EFI_PROCESSOR_INFORMATION ProcessorInfoBuffer; > > + MP_SERVICE_UT_CONTEXT *LocalContext; > > + > > + LocalContext = (MP_SERVICE_UT_CONTEXT *)Buffer; > > + > > + LocalContext->ApProcedureReturnStatus = MpServicesUnitTestGetProcessorInfo > ( > > + LocalContext->MpServices, > > + LocalContext->ApNumber, > > + &ProcessorInfoBuffer > > + ); > > +} > > + > > +/** > > + Procedure to run MP service EnableDisableAP on AP. > > + > > + @param[in,out] Buffer The pointer to private data buffer. > > +**/ > > +VOID > > +RunMpServiceEnableDisableAPOnAp ( > > + IN OUT VOID *Buffer > > + ) > > +{ > > + MP_SERVICE_UT_CONTEXT *LocalContext; > > + > > + LocalContext = (MP_SERVICE_UT_CONTEXT *)Buffer; > > + > > + LocalContext->ApProcedureReturnStatus = MpServicesUnitTestEnableDisableAP ( > > + LocalContext->MpServices, > > + LocalContext->ApNumber, > > + FALSE, > > + NULL > > + ); > > +} > > + > > +/** > > + Procedure to run MP service StartupThisAP on AP. > > + > > + @param[in,out] Buffer The pointer to private data buffer. > > +**/ > > +VOID > > +RunMpServiceStartupThisAPOnAp ( > > + IN OUT VOID *Buffer > > + ) > > +{ > > + MP_SERVICE_UT_CONTEXT *LocalContext; > > + > > + LocalContext = (MP_SERVICE_UT_CONTEXT *)Buffer; > > + > > + LocalContext->ApProcedureReturnStatus = MpServicesUnitTestStartupThisAP ( > > + LocalContext->MpServices, > > + (EFI_AP_PROCEDURE)EmptyProcedure, > > + LocalContext->ApNumber, > > + 0, > > + NULL > > + ); > > +} > > + > > +/** > > + Procedure to run MP service StartupAllAPs on AP. > > + > > + @param[in,out] Buffer The pointer to private data buffer. > > +**/ > > +VOID > > +RunMpServiceStartupAllAPsOnAp ( > > + IN OUT VOID *Buffer > > + ) > > +{ > > + MP_SERVICE_UT_CONTEXT *LocalContext; > > + > > + LocalContext = (MP_SERVICE_UT_CONTEXT *)Buffer; > > + > > + LocalContext->ApProcedureReturnStatus = MpServicesUnitTestStartupAllAPs ( > > + LocalContext->MpServices, > > + (EFI_AP_PROCEDURE)EmptyProcedure, > > + FALSE, > > + 0, > > + NULL > > + ); > > +} > > + > > +/** > > + Procedure to run MP service SwitchBSP on AP. > > + > > + @param[in,out] Buffer The pointer to private data buffer. > > +**/ > > +VOID > > +RunMpServiceSwitchBSPOnAp ( > > + IN OUT VOID *Buffer > > + ) > > +{ > > + MP_SERVICE_UT_CONTEXT *LocalContext; > > + > > + LocalContext = (MP_SERVICE_UT_CONTEXT *)Buffer; > > + > > + LocalContext->ApProcedureReturnStatus = MpServicesUnitTestSwitchBSP ( > > + LocalContext->MpServices, > > + LocalContext->ApNumber, > > + TRUE > > + ); > > +} > > + > > +/** > > + Unit test of MP service WhoAmI. > > + The range of ProcessorNumber should be from 0 to NumberOfCPUs minus 1. > > + The ProcessorNumbers of all CPUs are unique. > > + > > + @param[in] Context Context pointer for this test. > > + > > + @retval UNIT_TEST_PASSED The Unit test has completed and the > test > > + case was successful. > > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed. > > +**/ > > +UNIT_TEST_STATUS > > +EFIAPI > > +TestWhoAmI1 ( > > + IN UNIT_TEST_CONTEXT Context > > + ) > > +{ > > + EFI_STATUS Status; > > + UINTN ProcessorNumber; > > + UINTN ProcessorIndex; > > + MP_SERVICE_UT_CONTEXT *LocalContext; > > + > > + LocalContext = (MP_SERVICE_UT_CONTEXT *)Context; > > + > > + Status = MpServicesUnitTestWhoAmI ( > > + LocalContext->MpServices, > > + &ProcessorNumber > > + ); > > + UT_ASSERT_NOT_EFI_ERROR (Status); > > + UT_ASSERT_TRUE (ProcessorNumber < LocalContext->NumberOfProcessors); > > + > > + SetMem (LocalContext->CommonBuffer, LocalContext->NumberOfProcessors * > sizeof (*LocalContext- > >CommonBuffer), 0xFF); > > + LocalContext->CommonBuffer[ProcessorNumber] = ProcessorNumber; > > + > > + Status = MpServicesUnitTestStartupAllAPs ( > > + LocalContext->MpServices, > > + (EFI_AP_PROCEDURE)StoreCpuNumbers, > > + FALSE, > > + 0, > > + (VOID *)LocalContext > > + ); > > + UT_ASSERT_NOT_EFI_ERROR (Status); > > + > > + // > > + // The layout of CommonBuffer (E.g. BspNumber = 2 and NumberOfProcessors = > 6) > > + // Index 00 01 02 03 04 05 > > + // Value 00 01 02 03 04 05 > > + // > > + for (ProcessorIndex = 0; ProcessorIndex < > LocalContext->NumberOfProcessors; ProcessorIndex++) { > > + UT_ASSERT_TRUE (LocalContext->CommonBuffer[ProcessorIndex] == > ProcessorIndex); > > + } > > + > > + return UNIT_TEST_PASSED; > > +} > > + > > +/** > > + Unit test of MP service GetNumberOfProcessors. > > + NumberOfProcessors should be greater that 0 and not less than > NumberOfEnabledProcessors. > > + > > + @param[in] Context Context pointer for this test. > > + > > + @retval UNIT_TEST_PASSED The Unit test has completed and the > test > > + case was successful. > > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed. > > +**/ > > +UNIT_TEST_STATUS > > +EFIAPI > > +TestGetNumberOfProcessors1 ( > > + IN UNIT_TEST_CONTEXT Context > > + ) > > +{ > > + EFI_STATUS Status; > > + UINTN NumberOfProcessors; > > + UINTN NumberOfEnabledProcessors; > > + MP_SERVICE_UT_CONTEXT *LocalContext; > > + > > + LocalContext = (MP_SERVICE_UT_CONTEXT *)Context; > > + > > + Status = MpServicesUnitTestGetNumberOfProcessors ( > > + LocalContext->MpServices, > > + &NumberOfProcessors, > > + &NumberOfEnabledProcessors > > + ); > > + UT_ASSERT_NOT_EFI_ERROR (Status); > > + UT_ASSERT_TRUE (NumberOfProcessors > 0 && NumberOfProcessors >= > NumberOfEnabledProcessors); > > + > > + return UNIT_TEST_PASSED; > > +} > > + > > +/** > > + Unit test of MP service GetNumberOfProcessors. > > + When this service is called from an AP, the return status should be > EFI_DEVICE_ERROR. > > + > > + @param[in] Context Context pointer for this test. > > + > > + @retval UNIT_TEST_PASSED The Unit test has completed and the > test > > + case was successful. > > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed. > > +**/ > > +UNIT_TEST_STATUS > > +EFIAPI > > +TestGetNumberOfProcessors2 ( > > + IN UNIT_TEST_CONTEXT Context > > + ) > > +{ > > + EFI_STATUS Status; > > + UINTN ApNumber; > > + MP_SERVICE_UT_CONTEXT *LocalContext; > > + > > + LocalContext = (MP_SERVICE_UT_CONTEXT *)Context; > > + > > + for (ApNumber = 0; ApNumber < LocalContext->NumberOfProcessors; > ApNumber++) { > > + LocalContext->ApNumber = ApNumber; > > + Status = MpServicesUnitTestStartupThisAP ( > > + LocalContext->MpServices, > > + > (EFI_AP_PROCEDURE)RunMpServiceGetNumberOfProcessorsOnAp, > > + ApNumber, > > + 0, > > + (VOID *)LocalContext > > + ); > > + > > + if (ApNumber == LocalContext->BspNumber) { > > + UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER); > > + } else { > > + UT_ASSERT_NOT_EFI_ERROR (Status); > > + UT_ASSERT_STATUS_EQUAL (LocalContext->ApProcedureReturnStatus, > EFI_DEVICE_ERROR); > > + } > > + } > > + > > + return UNIT_TEST_PASSED; > > +} > > + > > +/** > > + Unit test of MP service GetNumberOfProcessors. > > + Call EnableDisableAP() to change the number of enabled AP. > > + > > + @param[in] Context Context pointer for this test. > > + > > + @retval UNIT_TEST_PASSED The Unit test has completed and the > test > > + case was successful. > > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed. > > +**/ > > +UNIT_TEST_STATUS > > +EFIAPI > > +TestGetNumberOfProcessors3 ( > > + IN UNIT_TEST_CONTEXT Context > > + ) > > +{ > > + EFI_STATUS Status; > > + UINTN ApNumber; > > + UINTN NumberOfProcessors; > > + UINTN NumberOfEnabledProcessors; > > + MP_SERVICE_UT_CONTEXT *LocalContext; > > + > > + LocalContext = (MP_SERVICE_UT_CONTEXT *)Context; > > + > > + for (ApNumber = 0; ApNumber < LocalContext->NumberOfProcessors; > ApNumber++) { > > + Status = MpServicesUnitTestEnableDisableAP ( > > + LocalContext->MpServices, > > + ApNumber, > > + FALSE, > > + NULL > > + ); > > + > > + if (ApNumber == LocalContext->BspNumber) { > > + UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER); > > + } else { > > + UT_ASSERT_NOT_EFI_ERROR (Status); > > + > > + Status = MpServicesUnitTestGetNumberOfProcessors ( > > + LocalContext->MpServices, > > + &NumberOfProcessors, > > + &NumberOfEnabledProcessors > > + ); > > + UT_ASSERT_NOT_EFI_ERROR (Status); > > + UT_ASSERT_TRUE (NumberOfProcessors == > LocalContext->NumberOfProcessors); > > + > > + if (ApNumber < LocalContext->BspNumber) { > > + UT_ASSERT_TRUE (NumberOfEnabledProcessors == > LocalContext->NumberOfProcessors - (ApNumber + 1)); > > + } else { > > + UT_ASSERT_TRUE (NumberOfEnabledProcessors == > LocalContext->NumberOfProcessors - ApNumber); > > + } > > + } > > + } > > + > > + for (ApNumber = 0; ApNumber < LocalContext->NumberOfProcessors; > ApNumber++) { > > + Status = MpServicesUnitTestEnableDisableAP ( > > + LocalContext->MpServices, > > + ApNumber, > > + TRUE, > > + NULL > > + ); > > + > > + if (ApNumber == LocalContext->BspNumber) { > > + UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER); > > + } else { > > + UT_ASSERT_NOT_EFI_ERROR (Status); > > + > > + Status = MpServicesUnitTestGetNumberOfProcessors ( > > + LocalContext->MpServices, > > + &NumberOfProcessors, > > + &NumberOfEnabledProcessors > > + ); > > + UT_ASSERT_NOT_EFI_ERROR (Status); > > + UT_ASSERT_TRUE (NumberOfProcessors == > LocalContext->NumberOfProcessors); > > + > > + if (ApNumber < LocalContext->BspNumber) { > > + UT_ASSERT_TRUE (NumberOfEnabledProcessors == ApNumber + 2); > > + } else { > > + UT_ASSERT_TRUE (NumberOfEnabledProcessors == ApNumber + 1); > > + } > > + } > > + } > > + > > + return UNIT_TEST_PASSED; > > +} > > + > > +/** > > + Unit test of MP service GetProcessorInfo. > > + When all the parameters are valid, all reserved bits of StatusFlag in > ProcessorInfoBuffer should be set to zero. > > + When all the parameters are valid, the StatusFlag should not have an > invalid value (The BSP can never be in the disabled > state.). > > + When called with nonexistent processor handle, the return status should be > EFI_NOT_FOUND. > > + > > + @param[in] Context Context pointer for this test. > > + > > + @retval UNIT_TEST_PASSED The Unit test has completed and the > test > > + case was successful. > > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed. > > +**/ > > +UNIT_TEST_STATUS > > +EFIAPI > > +TestGetProcessorInfo1 ( > > + IN UNIT_TEST_CONTEXT Context > > + ) > > +{ > > + EFI_STATUS Status; > > + UINTN ProcessorNumber; > > + EFI_PROCESSOR_INFORMATION ProcessorInfoBuffer; > > + MP_SERVICE_UT_CONTEXT *LocalContext; > > + > > + LocalContext = (MP_SERVICE_UT_CONTEXT *)Context; > > + > > + for (ProcessorNumber = 0; ProcessorNumber <= > LocalContext->NumberOfProcessors; ProcessorNumber++) { > > + Status = MpServicesUnitTestGetProcessorInfo ( > > + LocalContext->MpServices, > > + ProcessorNumber, > > + &ProcessorInfoBuffer > > + ); > > + > > + if (ProcessorNumber == LocalContext->NumberOfProcessors) { > > + UT_ASSERT_STATUS_EQUAL (Status, EFI_NOT_FOUND); > > + } else { > > + UT_ASSERT_NOT_EFI_ERROR (Status); > > + UT_ASSERT_TRUE ((ProcessorInfoBuffer.StatusFlag & (UINT32) > ~(PROCESSOR_AS_BSP_BIT|PROCESSOR_ENABLED_BIT|PROCESSOR_HEALTH_STATUS_BIT)) == > 0); > > + > > + if (ProcessorNumber == LocalContext->BspNumber) { > > + UT_ASSERT_TRUE ((ProcessorInfoBuffer.StatusFlag & > PROCESSOR_AS_BSP_BIT) && (ProcessorInfoBuffer.StatusFlag > & PROCESSOR_ENABLED_BIT)); > > + } else { > > + UT_ASSERT_TRUE (!(ProcessorInfoBuffer.StatusFlag & > PROCESSOR_AS_BSP_BIT)); > > + } > > + } > > + } > > + > > + return UNIT_TEST_PASSED; > > +} > > + > > +/** > > + Unit test of MP service GetProcessorInfo. > > + When this service is called from an AP, the return status should be > EFI_DEVICE_ERROR. > > + > > + @param[in] Context Context pointer for this test. > > + > > + @retval UNIT_TEST_PASSED The Unit test has completed and the > test > > + case was successful. > > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed. > > +**/ > > +UNIT_TEST_STATUS > > +EFIAPI > > +TestGetProcessorInfo2 ( > > + IN UNIT_TEST_CONTEXT Context > > + ) > > +{ > > + EFI_STATUS Status; > > + UINTN ApNumber; > > + MP_SERVICE_UT_CONTEXT *LocalContext; > > + > > + LocalContext = (MP_SERVICE_UT_CONTEXT *)Context; > > + > > + for (ApNumber = 0; ApNumber < LocalContext->NumberOfProcessors; > ApNumber++) { > > + LocalContext->ApNumber = ApNumber; > > + Status = MpServicesUnitTestStartupThisAP ( > > + LocalContext->MpServices, > > + > (EFI_AP_PROCEDURE)RunMpServiceGetProcessorInfoOnAp, > > + ApNumber, > > + 0, > > + (VOID *)LocalContext > > + ); > > + > > + if (ApNumber == LocalContext->BspNumber) { > > + UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER); > > + } else { > > + UT_ASSERT_NOT_EFI_ERROR (Status); > > + UT_ASSERT_STATUS_EQUAL (LocalContext->ApProcedureReturnStatus, > EFI_DEVICE_ERROR); > > + } > > + } > > + > > + return UNIT_TEST_PASSED; > > +} > > + > > +/** > > + Unit test of MP service EnableDisableAP. > > + When called with BSP number, the return status should be > EFI_INVALID_PARAMETER. > > + When called with a nonexistent processor handle, the return status should > be EFI_NOT_FOUND. > > + The AP should be really Enable/Disabled. > > + > > + @param[in] Context Context pointer for this test. > > + > > + @retval UNIT_TEST_PASSED The Unit test has completed and the > test > > + case was successful. > > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed. > > +**/ > > +UNIT_TEST_STATUS > > +EFIAPI > > +TestEnableDisableAP1 ( > > + IN UNIT_TEST_CONTEXT Context > > + ) > > +{ > > + EFI_STATUS Status; > > + UINTN ApNumber; > > + MP_SERVICE_UT_CONTEXT *LocalContext; > > + > > + LocalContext = (MP_SERVICE_UT_CONTEXT *)Context; > > + > > + for (ApNumber = 0; ApNumber <= LocalContext->NumberOfProcessors; > ApNumber++) { > > + Status = MpServicesUnitTestEnableDisableAP ( > > + LocalContext->MpServices, > > + ApNumber, > > + FALSE, > > + NULL > > + ); > > + > > + if (ApNumber == LocalContext->BspNumber) { > > + UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER); > > + } else if (ApNumber == LocalContext->NumberOfProcessors) { > > + UT_ASSERT_STATUS_EQUAL (Status, EFI_NOT_FOUND); > > + } else { > > + UT_ASSERT_NOT_EFI_ERROR (Status); > > + > > + Status = MpServicesUnitTestStartupThisAP ( > > + LocalContext->MpServices, > > + (EFI_AP_PROCEDURE)EmptyProcedure, > > + ApNumber, > > + 0, > > + NULL > > + ); > > + UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER); > > + > > + Status = MpServicesUnitTestEnableDisableAP ( > > + LocalContext->MpServices, > > + ApNumber, > > + TRUE, > > + NULL > > + ); > > + UT_ASSERT_NOT_EFI_ERROR (Status); > > + > > + Status = MpServicesUnitTestStartupThisAP ( > > + LocalContext->MpServices, > > + (EFI_AP_PROCEDURE)EmptyProcedure, > > + ApNumber, > > + 0, > > + NULL > > + ); > > + UT_ASSERT_NOT_EFI_ERROR (Status); > > + } > > + } > > + > > + return UNIT_TEST_PASSED; > > +} > > + > > +/** > > + Unit test of MP service EnableDisableAP. > > + When run this procedure on AP, the return status should be > EFI_DEVICE_ERROR. > > + > > + @param[in] Context Context pointer for this test. > > + > > + @retval UNIT_TEST_PASSED The Unit test has completed and the > test > > + case was successful. > > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed. > > +**/ > > +UNIT_TEST_STATUS > > +EFIAPI > > +TestEnableDisableAP2 ( > > + IN UNIT_TEST_CONTEXT Context > > + ) > > +{ > > + EFI_STATUS Status; > > + UINTN ApNumber; > > + MP_SERVICE_UT_CONTEXT *LocalContext; > > + > > + LocalContext = (MP_SERVICE_UT_CONTEXT *)Context; > > + > > + for (ApNumber = 0; ApNumber < LocalContext->NumberOfProcessors; > ApNumber++) { > > + LocalContext->ApNumber = ApNumber; > > + Status = MpServicesUnitTestStartupThisAP ( > > + LocalContext->MpServices, > > + > (EFI_AP_PROCEDURE)RunMpServiceEnableDisableAPOnAp, > > + ApNumber, > > + 0, > > + (VOID *)LocalContext > > + ); > > + > > + if (ApNumber == LocalContext->BspNumber) { > > + UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER); > > + } else { > > + UT_ASSERT_NOT_EFI_ERROR (Status); > > + UT_ASSERT_STATUS_EQUAL (LocalContext->ApProcedureReturnStatus, > EFI_DEVICE_ERROR); > > + } > > + } > > + > > + return UNIT_TEST_PASSED; > > +} > > + > > +/** > > + Unit test of MP service EnableDisableAP. > > + When run this procedure on AP, the return status should be > EFI_DEVICE_ERROR. > > + > > + @param[in] Context Context pointer for this test. > > + > > + @retval UNIT_TEST_PASSED The Unit test has completed and the > test > > + case was successful. > > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed. > > +**/ > > +UNIT_TEST_STATUS > > +EFIAPI > > +TestEnableDisableAP3 ( > > + IN UNIT_TEST_CONTEXT Context > > + ) > > +{ > > + EFI_STATUS Status; > > + UINTN ApNumber; > > + EFI_PROCESSOR_INFORMATION ProcessorInfoBuffer; > > + UINT32 OldHealthFlag; > > + UINT32 NewHealthFlag; > > + MP_SERVICE_UT_CONTEXT *LocalContext; > > + > > + LocalContext = (MP_SERVICE_UT_CONTEXT *)Context; > > + > > + for (ApNumber = 0; ApNumber < LocalContext->NumberOfProcessors; > ApNumber++) { > > + Status = MpServicesUnitTestGetProcessorInfo ( > > + LocalContext->MpServices, > > + ApNumber, > > + &ProcessorInfoBuffer > > + ); > > + UT_ASSERT_NOT_EFI_ERROR (Status); > > + > > + OldHealthFlag = ProcessorInfoBuffer.StatusFlag & > PROCESSOR_HEALTH_STATUS_BIT; > > + NewHealthFlag = OldHealthFlag ^ PROCESSOR_HEALTH_STATUS_BIT; > > + Status = MpServicesUnitTestEnableDisableAP ( > > + LocalContext->MpServices, > > + ApNumber, > > + TRUE, > > + &NewHealthFlag > > + ); > > + > > + if (ApNumber == LocalContext->BspNumber) { > > + UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER); > > + } else { > > + UT_ASSERT_NOT_EFI_ERROR (Status); > > + > > + Status = MpServicesUnitTestGetProcessorInfo ( > > + LocalContext->MpServices, > > + ApNumber, > > + &ProcessorInfoBuffer > > + ); > > + UT_ASSERT_NOT_EFI_ERROR (Status); > > + UT_ASSERT_TRUE ((ProcessorInfoBuffer.StatusFlag & > PROCESSOR_HEALTH_STATUS_BIT) == NewHealthFlag); > > + > > + Status = MpServicesUnitTestEnableDisableAP ( > > + LocalContext->MpServices, > > + ApNumber, > > + TRUE, > > + &OldHealthFlag > > + ); > > + UT_ASSERT_NOT_EFI_ERROR (Status); > > + } > > + } > > + > > + return UNIT_TEST_PASSED; > > +} > > + > > +/** > > + Unit test of MP service StartupThisAP. > > + When called to startup a BSP, the return status should be > EFI_INVALID_PARAMETER. > > + When called with a nonexistent processor handle, the return status should > be EFI_NOT_FOUND. > > + The requested AP should execute the Procedure when called by StartupThisAP. > > + > > + @param[in] Context Context pointer for this test. > > + > > + @retval UNIT_TEST_PASSED The Unit test has completed and the > test > > + case was successful. > > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed. > > +**/ > > +UNIT_TEST_STATUS > > +EFIAPI > > +TestStartupThisAP1 ( > > + IN UNIT_TEST_CONTEXT Context > > + ) > > +{ > > + EFI_STATUS Status; > > + UINTN ApNumber; > > + UINTN ProcessorIndex; > > + MP_SERVICE_UT_CONTEXT *LocalContext; > > + > > + LocalContext = (MP_SERVICE_UT_CONTEXT *)Context; > > + > > + for (ApNumber = 0; ApNumber <= LocalContext->NumberOfProcessors; > ApNumber++) { > > + SetMem (LocalContext->CommonBuffer, LocalContext->NumberOfProcessors * > sizeof (*LocalContext- > >CommonBuffer), 0xFF); > > + Status = MpServicesUnitTestStartupThisAP ( > > + LocalContext->MpServices, > > + (EFI_AP_PROCEDURE)StoreCpuNumbers, > > + ApNumber, > > + 0, > > + (VOID *)LocalContext > > + ); > > + > > + if (ApNumber == LocalContext->BspNumber) { > > + UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER); > > + } else if (ApNumber == LocalContext->NumberOfProcessors) { > > + UT_ASSERT_STATUS_EQUAL (Status, EFI_NOT_FOUND); > > + } else { > > + UT_ASSERT_NOT_EFI_ERROR (Status); > > + > > + for (ProcessorIndex = 0; ProcessorIndex < > LocalContext->NumberOfProcessors; ProcessorIndex++) { > > + UT_ASSERT_TRUE ( > > + ((ProcessorIndex == ApNumber) && > (LocalContext->CommonBuffer[ProcessorIndex] == ProcessorIndex)) || > > + ((ProcessorIndex != ApNumber) && > (LocalContext->CommonBuffer[ProcessorIndex] == (UINTN) ~0)) > > + ); > > + } > > + } > > + } > > + > > + return UNIT_TEST_PASSED; > > +} > > + > > +/** > > + Unit test of MP service StartupThisAP. > > + When this service is called from an AP, the return status should be > EFI_DEVICE_ERROR. > > + > > + @param[in] Context Context pointer for this test. > > + > > + @retval UNIT_TEST_PASSED The Unit test has completed and the > test > > + case was successful. > > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed. > > +**/ > > +UNIT_TEST_STATUS > > +EFIAPI > > +TestStartupThisAP2 ( > > + IN UNIT_TEST_CONTEXT Context > > + ) > > +{ > > + EFI_STATUS Status; > > + UINTN ApNumber; > > + MP_SERVICE_UT_CONTEXT *LocalContext; > > + > > + LocalContext = (MP_SERVICE_UT_CONTEXT *)Context; > > + > > + for (ApNumber = 0; ApNumber < LocalContext->NumberOfProcessors; > ApNumber++) { > > + LocalContext->ApNumber = ApNumber; > > + Status = MpServicesUnitTestStartupThisAP ( > > + LocalContext->MpServices, > > + > (EFI_AP_PROCEDURE)RunMpServiceStartupThisAPOnAp, > > + ApNumber, > > + 0, > > + (VOID *)LocalContext > > + ); > > + > > + if (ApNumber == LocalContext->BspNumber) { > > + UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER); > > + } else { > > + UT_ASSERT_NOT_EFI_ERROR (Status); > > + UT_ASSERT_STATUS_EQUAL (LocalContext->ApProcedureReturnStatus, > EFI_DEVICE_ERROR); > > + } > > + } > > + > > + return UNIT_TEST_PASSED; > > +} > > + > > +/** > > + Unit test of MP service StartupThisAP. > > + When timeout expired before the requested AP has finished, the return > status should be EFI_TIMEOUT. > > + > > + @param[in] Context Context pointer for this test. > > + > > + @retval UNIT_TEST_PASSED The Unit test has completed and the > test > > + case was successful. > > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed. > > +**/ > > +UNIT_TEST_STATUS > > +EFIAPI > > +TestStartupThisAP3 ( > > + IN UNIT_TEST_CONTEXT Context > > + ) > > +{ > > + EFI_STATUS Status; > > + UINTN ApNumber; > > + MP_SERVICE_UT_CONTEXT *LocalContext; > > + > > + LocalContext = (MP_SERVICE_UT_CONTEXT *)Context; > > + > > + for (ApNumber = 0; ApNumber < LocalContext->NumberOfProcessors; > ApNumber++) { > > + Status = MpServicesUnitTestStartupThisAP ( > > + LocalContext->MpServices, > > + (EFI_AP_PROCEDURE)InfiniteLoopProcedure, > > + ApNumber, > > + RUN_PROCEDURE_TIMEOUT_VALUE, > > + NULL > > + ); > > + > > + if (ApNumber == LocalContext->BspNumber) { > > + UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER); > > + } else { > > + UT_ASSERT_STATUS_EQUAL (Status, EFI_TIMEOUT); > > + } > > + } > > + > > + return UNIT_TEST_PASSED; > > +} > > + > > +/** > > + Unit test of MP service StartupThisAP. > > + When called with disabled AP, the return status should be > EFI_INVALID_PARAMETER. > > + > > + @param[in] Context Context pointer for this test. > > + > > + @retval UNIT_TEST_PASSED The Unit test has completed and the > test > > + case was successful. > > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed. > > +**/ > > +UNIT_TEST_STATUS > > +EFIAPI > > +TestStartupThisAP4 ( > > + IN UNIT_TEST_CONTEXT Context > > + ) > > +{ > > + EFI_STATUS Status; > > + UINTN ApNumber; > > + MP_SERVICE_UT_CONTEXT *LocalContext; > > + > > + LocalContext = (MP_SERVICE_UT_CONTEXT *)Context; > > + > > + for (ApNumber = 0; ApNumber < LocalContext->NumberOfProcessors; > ApNumber++) { > > + Status = MpServicesUnitTestEnableDisableAP ( > > + LocalContext->MpServices, > > + ApNumber, > > + FALSE, > > + NULL > > + ); > > + > > + if (ApNumber == LocalContext->BspNumber) { > > + UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER); > > + } else { > > + UT_ASSERT_NOT_EFI_ERROR (Status); > > + > > + Status = MpServicesUnitTestStartupThisAP ( > > + LocalContext->MpServices, > > + (EFI_AP_PROCEDURE)EmptyProcedure, > > + ApNumber, > > + 0, > > + NULL > > + ); > > + UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER); > > + > > + Status = MpServicesUnitTestEnableDisableAP ( > > + LocalContext->MpServices, > > + ApNumber, > > + TRUE, > > + NULL > > + ); > > + UT_ASSERT_NOT_EFI_ERROR (Status); > > + > > + Status = MpServicesUnitTestStartupThisAP ( > > + LocalContext->MpServices, > > + (EFI_AP_PROCEDURE)EmptyProcedure, > > + ApNumber, > > + 0, > > + NULL > > + ); > > + UT_ASSERT_NOT_EFI_ERROR (Status); > > + } > > + } > > + > > + return UNIT_TEST_PASSED; > > +} > > + > > +/** > > + Unit test of MP service StartupAllAPs. > > + All APs should execute the Procedure when called by StartupAllAPs. > > + > > + @param[in] Context Context pointer for this test. > > + > > + @retval UNIT_TEST_PASSED The Unit test has completed and the > test > > + case was successful. > > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed. > > +**/ > > +UNIT_TEST_STATUS > > +EFIAPI > > +TestStartupAllAPs1 ( > > + IN UNIT_TEST_CONTEXT Context > > + ) > > +{ > > + EFI_STATUS Status; > > + UINTN ProcessorIndex; > > + MP_SERVICE_UT_CONTEXT *LocalContext; > > + > > + LocalContext = (MP_SERVICE_UT_CONTEXT *)Context; > > + > > + SetMem (LocalContext->CommonBuffer, LocalContext->NumberOfProcessors * > sizeof (*LocalContext- > >CommonBuffer), 0xFF); > > + Status = MpServicesUnitTestStartupAllAPs ( > > + LocalContext->MpServices, > > + (EFI_AP_PROCEDURE)StoreCpuNumbers, > > + FALSE, > > + 0, > > + (VOID *)LocalContext > > + ); > > + UT_ASSERT_NOT_EFI_ERROR (Status); > > + > > + for (ProcessorIndex = 0; ProcessorIndex < > LocalContext->NumberOfProcessors; ProcessorIndex++) { > > + UT_ASSERT_TRUE ( > > + ((ProcessorIndex == LocalContext->BspNumber) && > (LocalContext->CommonBuffer[ProcessorIndex] == (UINTN) ~0)) > || > > + ((ProcessorIndex != LocalContext->BspNumber) && > (LocalContext->CommonBuffer[ProcessorIndex] == > ProcessorIndex)) > > + ); > > + } > > + > > + return UNIT_TEST_PASSED; > > +} > > + > > +/** > > + Unit test of MP service StartupAllAPs. > > + When called in single thread, the return status should be EFI_SUCCESS and > AP executes in ascending order > > + of processor handle number. > > + > > + @param[in] Context Context pointer for this test. > > + > > + @retval UNIT_TEST_PASSED The Unit test has completed and the > test > > + case was successful. > > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed. > > +**/ > > +UNIT_TEST_STATUS > > +EFIAPI > > +TestStartupAllAPs2 ( > > + IN UNIT_TEST_CONTEXT Context > > + ) > > +{ > > + EFI_STATUS Status; > > + UINTN ProcessorIndex; > > + MP_SERVICE_UT_CONTEXT *LocalContext; > > + > > + LocalContext = (MP_SERVICE_UT_CONTEXT *)Context; > > + > > + ZeroMem (LocalContext->CommonBuffer, LocalContext->NumberOfProcessors * > sizeof (*LocalContext- > >CommonBuffer)); > > + Status = MpServicesUnitTestStartupAllAPs ( > > + LocalContext->MpServices, > > + (EFI_AP_PROCEDURE)StoreAPsExecutionOrder, > > + TRUE, > > + 0, > > + (VOID *)LocalContext > > + ); > > + UT_ASSERT_NOT_EFI_ERROR (Status); > > + > > + // > > + // The layout of CommonBuffer (E.g. BspNumber = 2 and NumberOfProcessors = > 6) > > + // Index 00 01 02 03 04 05 > > + // Value 00 01 03 04 05 ApCounter(5) > > + // > > + for (ProcessorIndex = 0; ProcessorIndex < LocalContext->NumberOfProcessors > - 2; ProcessorIndex++) { > > + UT_ASSERT_TRUE (LocalContext->CommonBuffer[ProcessorIndex] < > LocalContext->CommonBuffer[ProcessorIndex + > 1]); > > + } > > + > > + UT_ASSERT_EQUAL > (LocalContext->CommonBuffer[LocalContext->NumberOfProcessors - 1], > LocalContext- > >NumberOfProcessors - 1); > > + > > + return UNIT_TEST_PASSED; > > +} > > + > > +/** > > + Unit test of MP service StartupAllAPs. > > + When this service is called from an AP, the return status should be > EFI_DEVICE_ERROR. > > + > > + @param[in] Context Context pointer for this test. > > + > > + @retval UNIT_TEST_PASSED The Unit test has completed and the > test > > + case was successful. > > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed. > > +**/ > > +UNIT_TEST_STATUS > > +EFIAPI > > +TestStartupAllAPs3 ( > > + IN UNIT_TEST_CONTEXT Context > > + ) > > +{ > > + EFI_STATUS Status; > > + UINTN ApNumber; > > + MP_SERVICE_UT_CONTEXT *LocalContext; > > + > > + LocalContext = (MP_SERVICE_UT_CONTEXT *)Context; > > + > > + for (ApNumber = 0; ApNumber < LocalContext->NumberOfProcessors; > ApNumber++) { > > + LocalContext->ApNumber = ApNumber; > > + Status = MpServicesUnitTestStartupThisAP ( > > + LocalContext->MpServices, > > + > (EFI_AP_PROCEDURE)RunMpServiceStartupAllAPsOnAp, > > + ApNumber, > > + 0, > > + (VOID *)LocalContext > > + ); > > + > > + if (ApNumber == LocalContext->BspNumber) { > > + UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER); > > + } else { > > + UT_ASSERT_NOT_EFI_ERROR (Status); > > + UT_ASSERT_STATUS_EQUAL (LocalContext->ApProcedureReturnStatus, > EFI_DEVICE_ERROR); > > + } > > + } > > + > > + return UNIT_TEST_PASSED; > > +} > > + > > +/** > > + Unit test of MP service StartupAllAPs. > > + When called with all AP timeout, the return status should be EFI_TIMEOUT. > > + > > + @param[in] Context Context pointer for this test. > > + > > + @retval UNIT_TEST_PASSED The Unit test has completed and the > test > > + case was successful. > > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed. > > +**/ > > +UNIT_TEST_STATUS > > +EFIAPI > > +TestStartupAllAPs4 ( > > + IN UNIT_TEST_CONTEXT Context > > + ) > > +{ > > + EFI_STATUS Status; > > + MP_SERVICE_UT_CONTEXT *LocalContext; > > + > > + LocalContext = (MP_SERVICE_UT_CONTEXT *)Context; > > + > > + Status = MpServicesUnitTestStartupAllAPs ( > > + LocalContext->MpServices, > > + (EFI_AP_PROCEDURE)InfiniteLoopProcedure, > > + TRUE, > > + RUN_PROCEDURE_TIMEOUT_VALUE, > > + NULL > > + ); > > + UT_ASSERT_STATUS_EQUAL (Status, EFI_TIMEOUT); > > + > > + Status = MpServicesUnitTestStartupAllAPs ( > > + LocalContext->MpServices, > > + (EFI_AP_PROCEDURE)InfiniteLoopProcedure, > > + FALSE, > > + RUN_PROCEDURE_TIMEOUT_VALUE, > > + NULL > > + ); > > + UT_ASSERT_STATUS_EQUAL (Status, EFI_TIMEOUT); > > + > > + return UNIT_TEST_PASSED; > > +} > > + > > +/** > > + Unit test of MP service StartupAllAPs. > > + When called with the empty Procedure on all disabled APs, the return > status should be EFI_NOT_STARTED. > > + > > + @param[in] Context Context pointer for this test. > > + > > + @retval UNIT_TEST_PASSED The Unit test has completed and the > test > > + case was successful. > > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed. > > +**/ > > +UNIT_TEST_STATUS > > +EFIAPI > > +TestStartupAllAPs5 ( > > + IN UNIT_TEST_CONTEXT Context > > + ) > > +{ > > + EFI_STATUS Status; > > + UINTN ApNumber; > > + MP_SERVICE_UT_CONTEXT *LocalContext; > > + > > + LocalContext = (MP_SERVICE_UT_CONTEXT *)Context; > > + > > + for (ApNumber = 0; ApNumber < LocalContext->NumberOfProcessors; > ApNumber++) { > > + Status = MpServicesUnitTestEnableDisableAP ( > > + LocalContext->MpServices, > > + ApNumber, > > + FALSE, > > + NULL > > + ); > > + > > + if (ApNumber == LocalContext->BspNumber) { > > + UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER); > > + } else { > > + UT_ASSERT_NOT_EFI_ERROR (Status); > > + } > > + } > > + > > + Status = MpServicesUnitTestStartupAllAPs ( > > + LocalContext->MpServices, > > + (EFI_AP_PROCEDURE)EmptyProcedure, > > + FALSE, > > + 0, > > + NULL > > + ); > > + UT_ASSERT_STATUS_EQUAL (Status, EFI_NOT_STARTED); > > + > > + for (ApNumber = 0; ApNumber < LocalContext->NumberOfProcessors; > ApNumber++) { > > + Status = MpServicesUnitTestEnableDisableAP ( > > + LocalContext->MpServices, > > + ApNumber, > > + TRUE, > > + NULL > > + ); > > + > > + if (ApNumber == LocalContext->BspNumber) { > > + UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER); > > + } else { > > + UT_ASSERT_NOT_EFI_ERROR (Status); > > + } > > + } > > + > > + return UNIT_TEST_PASSED; > > +} > > + > > +/** > > + Unit test of MP service SwitchBSP. > > + When switch current BSP to be BSP, the return status should be > EFI_INVALID_PARAMETER. > > + When switch nonexistent processor to be BSP, the return status should be > EFI_NOT_FOUND. > > + After switch BSP, all APs(includes new AP) should execute the Procedure > when called by StartupAllAP. > > + > > + @param[in] Context Context pointer for this test. > > + > > + @retval UNIT_TEST_PASSED The Unit test has completed and the > test > > + case was successful. > > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed. > > +**/ > > +UNIT_TEST_STATUS > > +EFIAPI > > +TestSwitchBSP1 ( > > + IN UNIT_TEST_CONTEXT Context > > + ) > > +{ > > + EFI_STATUS Status; > > + UINTN NewBspNumber; > > + UINTN ProcessorIndex; > > + MP_SERVICE_UT_CONTEXT *LocalContext; > > + > > + LocalContext = (MP_SERVICE_UT_CONTEXT *)Context; > > + > > + for (NewBspNumber = 0; NewBspNumber <= LocalContext->NumberOfProcessors; > NewBspNumber++) { > > + Status = MpServicesUnitTestSwitchBSP ( > > + LocalContext->MpServices, > > + NewBspNumber, > > + TRUE > > + ); > > + > > + if (NewBspNumber == LocalContext->BspNumber) { > > + UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER); > > + } else if (NewBspNumber == LocalContext->NumberOfProcessors) { > > + UT_ASSERT_STATUS_EQUAL (Status, EFI_NOT_FOUND); > > + } else { > > + UT_ASSERT_NOT_EFI_ERROR (Status); > > + > > + SetMem (LocalContext->CommonBuffer, LocalContext->NumberOfProcessors * > sizeof (*LocalContext- > >CommonBuffer), 0xFF); > > + Status = MpServicesUnitTestStartupAllAPs ( > > + LocalContext->MpServices, > > + (EFI_AP_PROCEDURE)StoreCpuNumbers, > > + FALSE, > > + 0, > > + (VOID *)LocalContext > > + ); > > + UT_ASSERT_NOT_EFI_ERROR (Status); > > + > > + for (ProcessorIndex = 0; ProcessorIndex < > LocalContext->NumberOfProcessors; ProcessorIndex++) { > > + UT_ASSERT_TRUE ( > > + ((ProcessorIndex == NewBspNumber) && > (LocalContext->CommonBuffer[ProcessorIndex] == (UINTN) ~0)) || > > + ((ProcessorIndex != NewBspNumber) && > (LocalContext->CommonBuffer[ProcessorIndex] == ProcessorIndex)) > > + ); > > + } > > + > > + Status = MpServicesUnitTestSwitchBSP ( > > + LocalContext->MpServices, > > + LocalContext->BspNumber, > > + TRUE > > + ); > > + UT_ASSERT_NOT_EFI_ERROR (Status); > > + } > > + } > > + > > + return UNIT_TEST_PASSED; > > +} > > + > > +/** > > + Unit test of MP service SwitchBSP. > > + When run this procedure on AP, the return status should be > EFI_DEVICE_ERROR. > > + > > + @param[in] Context Context pointer for this test. > > + > > + @retval UNIT_TEST_PASSED The Unit test has completed and the > test > > + case was successful. > > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed. > > +**/ > > +UNIT_TEST_STATUS > > +EFIAPI > > +TestSwitchBSP2 ( > > + IN UNIT_TEST_CONTEXT Context > > + ) > > +{ > > + EFI_STATUS Status; > > + UINTN ApNumber; > > + MP_SERVICE_UT_CONTEXT *LocalContext; > > + > > + LocalContext = (MP_SERVICE_UT_CONTEXT *)Context; > > + > > + for (ApNumber = 0; ApNumber < LocalContext->NumberOfProcessors; > ApNumber++) { > > + LocalContext->ApNumber = ApNumber; > > + Status = MpServicesUnitTestStartupThisAP ( > > + LocalContext->MpServices, > > + (EFI_AP_PROCEDURE)RunMpServiceSwitchBSPOnAp, > > + ApNumber, > > + 0, > > + (VOID *)LocalContext > > + ); > > + > > + if (ApNumber == LocalContext->BspNumber) { > > + UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER); > > + } else { > > + UT_ASSERT_NOT_EFI_ERROR (Status); > > + UT_ASSERT_STATUS_EQUAL (LocalContext->ApProcedureReturnStatus, > EFI_DEVICE_ERROR); > > + } > > + } > > + > > + return UNIT_TEST_PASSED; > > +} > > + > > +/** > > + Unit test of MP service SwitchBSP. > > + When switch a disabled AP to be BSP, the return status should be > EFI_INVALID_PARAMETER. > > + > > + @param[in] Context Context pointer for this test. > > + > > + @retval UNIT_TEST_PASSED The Unit test has completed and the > test > > + case was successful. > > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed. > > +**/ > > +UNIT_TEST_STATUS > > +EFIAPI > > +TestSwitchBSP3 ( > > + IN UNIT_TEST_CONTEXT Context > > + ) > > +{ > > + EFI_STATUS Status; > > + UINTN NewBspNumber; > > + MP_SERVICE_UT_CONTEXT *LocalContext; > > + > > + LocalContext = (MP_SERVICE_UT_CONTEXT *)Context; > > + > > + for (NewBspNumber = 0; NewBspNumber < LocalContext->NumberOfProcessors; > NewBspNumber++) { > > + Status = MpServicesUnitTestEnableDisableAP ( > > + LocalContext->MpServices, > > + NewBspNumber, > > + FALSE, > > + NULL > > + ); > > + > > + if (NewBspNumber == LocalContext->BspNumber) { > > + UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER); > > + } else { > > + UT_ASSERT_NOT_EFI_ERROR (Status); > > + > > + Status = MpServicesUnitTestSwitchBSP ( > > + LocalContext->MpServices, > > + NewBspNumber, > > + TRUE > > + ); > > + UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER); > > + > > + Status = MpServicesUnitTestEnableDisableAP ( > > + LocalContext->MpServices, > > + NewBspNumber, > > + TRUE, > > + NULL > > + ); > > + UT_ASSERT_NOT_EFI_ERROR (Status); > > + } > > + } > > + > > + return UNIT_TEST_PASSED; > > +} > > + > > +/** > > + Unit test of MP service SwitchBSP. > > + When SwitchBSP and EnableOldBSP is TRUE, the new BSP should be in the > enabled state and the old BSP should > > + be in the enabled state. > > + When SwitchBSP and EnableOldBSP is False, the new BSP should be in the > enabled state and the old BSP should > > + be in the disabled state. > > + > > + @param[in] Context Context pointer for this test. > > + > > + @retval UNIT_TEST_PASSED The Unit test has completed and the > test > > + case was successful. > > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed. > > +**/ > > +UNIT_TEST_STATUS > > +EFIAPI > > +TestSwitchBSP4 ( > > + IN UNIT_TEST_CONTEXT Context > > + ) > > +{ > > + EFI_STATUS Status; > > + UINTN NewBspNumber; > > + EFI_PROCESSOR_INFORMATION ProcessorInfoBuffer; > > + MP_SERVICE_UT_CONTEXT *LocalContext; > > + > > + LocalContext = (MP_SERVICE_UT_CONTEXT *)Context; > > + > > + for (NewBspNumber = 0; NewBspNumber < LocalContext->NumberOfProcessors; > NewBspNumber++) { > > + Status = MpServicesUnitTestSwitchBSP ( > > + LocalContext->MpServices, > > + NewBspNumber, > > + FALSE > > + ); > > + > > + if (NewBspNumber == LocalContext->BspNumber) { > > + UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER); > > + } else { > > + UT_ASSERT_NOT_EFI_ERROR (Status); > > + > > + Status = MpServicesUnitTestGetProcessorInfo ( > > + LocalContext->MpServices, > > + NewBspNumber, > > + &ProcessorInfoBuffer > > + ); > > + UT_ASSERT_NOT_EFI_ERROR (Status); > > + UT_ASSERT_TRUE ( > > + (ProcessorInfoBuffer.StatusFlag & PROCESSOR_AS_BSP_BIT) && > > + (ProcessorInfoBuffer.StatusFlag & PROCESSOR_ENABLED_BIT) > > + ); > > + > > + Status = MpServicesUnitTestGetProcessorInfo ( > > + LocalContext->MpServices, > > + LocalContext->BspNumber, > > + &ProcessorInfoBuffer > > + ); > > + UT_ASSERT_NOT_EFI_ERROR (Status); > > + UT_ASSERT_TRUE ( > > + !(ProcessorInfoBuffer.StatusFlag & PROCESSOR_AS_BSP_BIT) && > > + !(ProcessorInfoBuffer.StatusFlag & PROCESSOR_ENABLED_BIT) > > + ); > > + > > + Status = MpServicesUnitTestEnableDisableAP ( > > + LocalContext->MpServices, > > + LocalContext->BspNumber, > > + TRUE, > > + NULL > > + ); > > + UT_ASSERT_NOT_EFI_ERROR (Status); > > + > > + Status = MpServicesUnitTestSwitchBSP ( > > + LocalContext->MpServices, > > + LocalContext->BspNumber, > > + TRUE > > + ); > > + UT_ASSERT_NOT_EFI_ERROR (Status); > > + > > + Status = MpServicesUnitTestGetProcessorInfo ( > > + LocalContext->MpServices, > > + LocalContext->BspNumber, > > + &ProcessorInfoBuffer > > + ); > > + UT_ASSERT_NOT_EFI_ERROR (Status); > > + UT_ASSERT_TRUE ( > > + (ProcessorInfoBuffer.StatusFlag & PROCESSOR_AS_BSP_BIT) && > > + (ProcessorInfoBuffer.StatusFlag & PROCESSOR_ENABLED_BIT) > > + ); > > + > > + Status = MpServicesUnitTestGetProcessorInfo ( > > + LocalContext->MpServices, > > + NewBspNumber, > > + &ProcessorInfoBuffer > > + ); > > + UT_ASSERT_NOT_EFI_ERROR (Status); > > + UT_ASSERT_TRUE ( > > + !(ProcessorInfoBuffer.StatusFlag & PROCESSOR_AS_BSP_BIT) && > > + (ProcessorInfoBuffer.StatusFlag & PROCESSOR_ENABLED_BIT) > > + ); > > + } > > + } > > + > > + return UNIT_TEST_PASSED; > > +} > > + > > +/** > > + Create test suite and unit tests for both EdkiiPeiMpServices2Ppi and > EfiMpServiceProtocol. > > + > > + @param[in] Framework A pointer to the framework that is being > persisted. > > + @param[in] Context A pointer to the private data buffer. > > + > > + @retval EFI_SUCCESS Create test suite and unit tests successfully. > > + @retval Others Create test suite and unit tests unsuccessfully. > > +**/ > > +EFI_STATUS > > +AddCommonTestCase ( > > + IN UNIT_TEST_FRAMEWORK_HANDLE Framework, > > + IN MP_SERVICE_UT_CONTEXT *Context > > + ) > > +{ > > + EFI_STATUS Status; > > + UNIT_TEST_SUITE_HANDLE MpServiceWhoAmITestSuite; > > + UNIT_TEST_SUITE_HANDLE MpServiceGetNumberOfProcessorsTestSuite; > > + UNIT_TEST_SUITE_HANDLE MpServiceGetProcessorInfoTestSuite; > > + UNIT_TEST_SUITE_HANDLE MpServiceEnableDisableAPTestSuite; > > + UNIT_TEST_SUITE_HANDLE MpServiceStartupThisAPTestSuite; > > + UNIT_TEST_SUITE_HANDLE MpServiceStartupAllAPsTestSuite; > > + UNIT_TEST_SUITE_HANDLE MpServiceSwitchBSPTestSuite; > > + > > + MpServiceWhoAmITestSuite = NULL; > > + MpServiceGetNumberOfProcessorsTestSuite = NULL; > > + MpServiceGetProcessorInfoTestSuite = NULL; > > + MpServiceEnableDisableAPTestSuite = NULL; > > + MpServiceStartupThisAPTestSuite = NULL; > > + MpServiceStartupAllAPsTestSuite = NULL; > > + MpServiceSwitchBSPTestSuite = NULL; > > + > > + // > > + // Test WhoAmI function > > + // > > + Status = CreateUnitTestSuite (&MpServiceWhoAmITestSuite, Framework, > "Identify the currently executing processor", > "MpServices.WhoAmI", NULL, NULL); > > + if (EFI_ERROR (Status)) { > > + DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for MpServiceWhoAmI > Test Suite\n")); > > + return Status; > > + } > > + > > + AddTestCase (MpServiceWhoAmITestSuite, "Test WhoAmI 1", "TestWhoAmI1", > TestWhoAmI1, InitUTContext, > CheckUTContext, Context); > > + > > + // > > + // Test GetNumberOfProcessors function > > + // > > + Status = CreateUnitTestSuite (&MpServiceGetNumberOfProcessorsTestSuite, > Framework, "Retrieve the number of > logical processor", "MpServices.GetNumberOfProcessors", NULL, NULL); > > + if (EFI_ERROR (Status)) { > > + DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for > MpServiceGetNumberOfProcessors Test Suite\n")); > > + return Status; > > + } > > + > > + AddTestCase (MpServiceGetNumberOfProcessorsTestSuite, "Test > GetNumberOfProcessors 1", > "TestGetNumberOfProcessors1", TestGetNumberOfProcessors1, InitUTContext, > CheckUTContext, Context); > > + AddTestCase (MpServiceGetNumberOfProcessorsTestSuite, "Test > GetNumberOfProcessors 2", > "TestGetNumberOfProcessors2", TestGetNumberOfProcessors2, InitUTContext, > CheckUTContext, Context); > > + AddTestCase (MpServiceGetNumberOfProcessorsTestSuite, "Test > GetNumberOfProcessors 3", > "TestGetNumberOfProcessors3", TestGetNumberOfProcessors3, InitUTContext, > CheckUTContext, Context); > > + > > + // > > + // Test GetProcessorInfo function > > + // > > + Status = CreateUnitTestSuite (&MpServiceGetProcessorInfoTestSuite, > Framework, "Get detailed information on the > requested logical processor", "MpServices.GetProcessorInfo", NULL, NULL); > > + if (EFI_ERROR (Status)) { > > + DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for > MpServiceGetProcessorInfo Test Suite\n")); > > + return Status; > > + } > > + > > + AddTestCase (MpServiceGetProcessorInfoTestSuite, "Test GetProcessorInfo > 1", "TestGetProcessorInfo1", > TestGetProcessorInfo1, InitUTContext, CheckUTContext, Context); > > + AddTestCase (MpServiceGetProcessorInfoTestSuite, "Test GetProcessorInfo > 2", "TestGetProcessorInfo2", > TestGetProcessorInfo2, InitUTContext, CheckUTContext, Context); > > + > > + // > > + // Test EnableDisableAP function > > + // > > + Status = CreateUnitTestSuite (&MpServiceEnableDisableAPTestSuite, > Framework, "Caller enables or disables an AP from > this point onward", "MpServices.EnableDisableAP", NULL, NULL); > > + if (EFI_ERROR (Status)) { > > + DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for > MpServiceEnableDisableAP Test Suite\n")); > > + return Status; > > + } > > + > > + AddTestCase (MpServiceEnableDisableAPTestSuite, "Test EnableDisableAP 1", > "TestEnableDisableAP1", > TestEnableDisableAP1, InitUTContext, CheckUTContext, Context); > > + AddTestCase (MpServiceEnableDisableAPTestSuite, "Test EnableDisableAP 2", > "TestEnableDisableAP2", > TestEnableDisableAP2, InitUTContext, CheckUTContext, Context); > > + AddTestCase (MpServiceEnableDisableAPTestSuite, "Test EnableDisableAP 3", > "TestEnableDisableAP3", > TestEnableDisableAP3, InitUTContext, CheckUTContext, Context); > > + > > + // > > + // Test StartupThisAP function > > + // > > + Status = CreateUnitTestSuite (&MpServiceStartupThisAPTestSuite, Framework, > "Get the requested AP to execute a > caller-provided function", "MpServices.StartupThisAP", NULL, NULL); > > + if (EFI_ERROR (Status)) { > > + DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for > MpServiceStartupThisAP Test Suite\n")); > > + return Status; > > + } > > + > > + AddTestCase (MpServiceStartupThisAPTestSuite, "Test StartupThisAP 1", > "TestStartupThisAP1", TestStartupThisAP1, > InitUTContext, CheckUTContext, Context); > > + AddTestCase (MpServiceStartupThisAPTestSuite, "Test StartupThisAP 2", > "TestStartupThisAP2", TestStartupThisAP2, > InitUTContext, CheckUTContext, Context); > > + AddTestCase (MpServiceStartupThisAPTestSuite, "Test StartupThisAP 3", > "TestStartupThisAP3", TestStartupThisAP3, > InitUTContext, CheckUTContext, Context); > > + AddTestCase (MpServiceStartupThisAPTestSuite, "Test StartupThisAP 4", > "TestStartupThisAP4", TestStartupThisAP4, > InitUTContext, CheckUTContext, Context); > > + > > + // > > + // Test StartupAllAPs function > > + // > > + Status = CreateUnitTestSuite (&MpServiceStartupAllAPsTestSuite, Framework, > "Execute a caller provided function on all > enabled APs", "MpServices.StartupAllAPs", NULL, NULL); > > + if (EFI_ERROR (Status)) { > > + DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for > MpServiceStartupAllAPs Test Suite\n")); > > + return Status; > > + } > > + > > + AddTestCase (MpServiceStartupAllAPsTestSuite, "Test StartupAllAPs 1", > "TestStartupAllAPs1", TestStartupAllAPs1, > InitUTContext, CheckUTContext, Context); > > + AddTestCase (MpServiceStartupAllAPsTestSuite, "Test StartupAllAPs 2", > "TestStartupAllAPs2", TestStartupAllAPs2, > InitUTContext, CheckUTContext, Context); > > + AddTestCase (MpServiceStartupAllAPsTestSuite, "Test StartupAllAPs 3", > "TestStartupAllAPs3", TestStartupAllAPs3, > InitUTContext, CheckUTContext, Context); > > + AddTestCase (MpServiceStartupAllAPsTestSuite, "Test StartupAllAPs 4", > "TestStartupAllAPs4", TestStartupAllAPs4, > InitUTContext, CheckUTContext, Context); > > + AddTestCase (MpServiceStartupAllAPsTestSuite, "Test StartupAllAPs 5", > "TestStartupAllAPs5", TestStartupAllAPs5, > InitUTContext, CheckUTContext, Context); > > + > > + // > > + // Test SwitchBSP function > > + // > > + Status = CreateUnitTestSuite (&MpServiceSwitchBSPTestSuite, Framework, > "Switch the requested AP to be the BSP > from that point onward", "MpServices.SwitchBSP", NULL, NULL); > > + if (EFI_ERROR (Status)) { > > + DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for > MpServiceSwitchBSP Test Suite\n")); > > + return Status; > > + } > > + > > + AddTestCase (MpServiceSwitchBSPTestSuite, "Test SwitchBSP 1", > "TestSwitchBSP1", TestSwitchBSP1, InitUTContext, > CheckUTContext, Context); > > + AddTestCase (MpServiceSwitchBSPTestSuite, "Test SwitchBSP 2", > "TestSwitchBSP2", TestSwitchBSP2, InitUTContext, > CheckUTContext, Context); > > + AddTestCase (MpServiceSwitchBSPTestSuite, "Test SwitchBSP 3", > "TestSwitchBSP3", TestSwitchBSP3, InitUTContext, > CheckUTContext, Context); > > + AddTestCase (MpServiceSwitchBSPTestSuite, "Test SwitchBSP 4", > "TestSwitchBSP4", TestSwitchBSP4, InitUTContext, > FreeUTContext, Context); > > + > > + return EFI_SUCCESS; > > +} > > diff --git > a/UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EdkiiPeiMpServices2PpiPeiUnitTest.inf > b/UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EdkiiPeiMpServices2PpiPeiUnitTest.inf > new file mode 100644 > index 0000000000..0b2ddc5585 > --- /dev/null > +++ > b/UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EdkiiPeiMpServices2PpiPeiUnitTest.inf > @@ -0,0 +1,46 @@ > +## @file > > +# PEIM that unit tests the EdkiiPeiMpServices2Ppi > > +# > > +# Copyright (c) 2022, Intel Corporation. All rights reserved.<BR> > > +# SPDX-License-Identifier: BSD-2-Clause-Patent > > +# > > +## > > + > > +[Defines] > > + INF_VERSION = 0x00010005 > > + BASE_NAME = EdkiiPeiMpServices2PpiPeiUnitTest > > + FILE_GUID = A4914810-4D1E-445E-BD6F-F6821B852B5D > > + 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] > > + EfiMpServicesUnitTestCommom.c > > + EfiMpServicesUnitTestCommom.h > > + EdkiiPeiMpServices2PpiUnitTest.c > > + > > +[Packages] > > + MdePkg/MdePkg.dec > > + UefiCpuPkg/UefiCpuPkg.dec > > + > > +[LibraryClasses] > > + BaseLib > > + DebugLib > > + BaseMemoryLib > > + MemoryAllocationLib > > + PeimEntryPoint > > + PeiServicesLib > > + UnitTestPersistenceLib > > + UnitTestLib > > + > > +[Ppis] > > + gEdkiiPeiMpServices2PpiGuid ## CONSUMES > > + > > +[Depex] > > + gEdkiiPeiMpServices2PpiGuid > > diff --git > a/UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EfiMpServiceProtocolDxeUnitTest.inf > b/UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EfiMpServiceProtocolDxeUnitTest.inf > new file mode 100644 > index 0000000000..1389092c06 > --- /dev/null > +++ > b/UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EfiMpServiceProtocolDxeUnitTest.inf > @@ -0,0 +1,46 @@ > +## @file > > +# DXE driver that unit tests the EfiMpServiceProtocol > > +# > > +# Copyright (c) 2022, Intel Corporation. All rights reserved.<BR> > > +# SPDX-License-Identifier: BSD-2-Clause-Patent > > +# > > +## > > + > > +[Defines] > > + INF_VERSION = 0x00010005 > > + BASE_NAME = EfiMpServiceProtocolDxeUnitTest > > + FILE_GUID = F1E468E2-A32D-4574-895D-6D82B27B08BC > > + MODULE_TYPE = DXE_DRIVER > > + VERSION_STRING = 1.0 > > + ENTRY_POINT = DxeEntryPoint > > + > > +# > > +# The following information is for reference only and not required by the > build tools. > > +# > > +# VALID_ARCHITECTURES = IA32 X64 > > +# > > + > > +[Sources] > > + EfiMpServicesUnitTestCommom.c > > + EfiMpServicesUnitTestCommom.h > > + EfiMpServiceProtocolUnitTest.c > > + > > +[Packages] > > + MdePkg/MdePkg.dec > > + UefiCpuPkg/UefiCpuPkg.dec > > + > > +[LibraryClasses] > > + BaseLib > > + DebugLib > > + BaseMemoryLib > > + MemoryAllocationLib > > + UefiDriverEntryPoint > > + UefiBootServicesTableLib > > + UnitTestPersistenceLib > > + UnitTestLib > > + > > +[Protocols] > > + gEfiMpServiceProtocolGuid ## CONSUMES > > + > > +[Depex] > > + gEfiMpServiceProtocolGuid > > diff --git > a/UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EfiMpServicesUnitTestCommom.h > b/UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EfiMpServicesUnitTestCommom.h > new file mode 100644 > index 0000000000..abbbd2faba > --- /dev/null > +++ > b/UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EfiMpServicesUnitTestCommom.h > @@ -0,0 +1,627 @@ > +/** @file > > + Common header file for EfiMpServiceProtocolUnitTest DXE driver. > > + > > + Copyright (c) 2022, Intel Corporation. All rights reserved.<BR> > > + > > + SPDX-License-Identifier: BSD-2-Clause-Patent > > + > > +**/ > > + > > +#ifndef EFI_MP_SERVICES_UNIT_TEST_COMMOM_H_ > > +#define EFI_MP_SERVICES_UNIT_TEST_COMMOM_H_ > > + > > +#include <PiPei.h> > > +#include <Ppi/MpServices2.h> > > +#include <Protocol/MpService.h> > > +#include <Library/BaseLib.h> > > +#include <Library/DebugLib.h> > > +#include <Library/ReportStatusCodeLib.h> > > +#include <Library/BaseMemoryLib.h> > > +#include <Library/MemoryAllocationLib.h> > > +#include <Library/UnitTestLib.h> > > + > > +#define RUN_PROCEDURE_TIMEOUT_VALUE 100000 // microseconds > > + > > +typedef union { > > + EDKII_PEI_MP_SERVICES2_PPI *Ppi; > > + EFI_MP_SERVICES_PROTOCOL *Protocol; > > +} MP_SERVICES; > > + > > +typedef struct { > > + MP_SERVICES MpServices; > > + UINTN BspNumber; > > + UINTN ApNumber; > > + UINTN NumberOfProcessors; > > + UINTN NumberOfEnabledProcessors; > > + UINTN *CommonBuffer; > > + EFI_STATUS ApProcedureReturnStatus; > > + UINTN *DisabledApNumber; > > +} MP_SERVICE_UT_CONTEXT; > > + > > +/** > > + Get EFI_MP_SERVICES_PROTOCOL pointer. > > + > > + @param[out] MpServices Pointer to the buffer where > EFI_MP_SERVICES_PROTOCOL is stored > > + > > + @retval EFI_SUCCESS EFI_MP_SERVICES_PROTOCOL interface is returned > > + @retval EFI_NOT_FOUND EFI_MP_SERVICES_PROTOCOL interface is not found > > +**/ > > +EFI_STATUS > > +MpServicesUnitTestGetMpServices ( > > + OUT MP_SERVICES *MpServices > > + ); > > + > > +/** > > + 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 > > + ); > > + > > +/** > > + Get detailed information on the requested logical processor. > > + > > + @param[in] MpServices MP_SERVICES structure. > > + @param[in] ProcessorNumber The handle number of the processor. > > + @param[out] ProcessorInfoBuffer Pointer to the buffer where the processor > information is stored. > > + > > + @retval EFI_SUCCESS Get information on the requested logical > processor successfully > > + @retval Others Get information on the requested logical > processor unsuccessfully > > +**/ > > +EFI_STATUS > > +MpServicesUnitTestGetProcessorInfo ( > > + IN MP_SERVICES MpServices, > > + IN UINTN ProcessorNumber, > > + OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer > > + ); > > + > > +/** > > + 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 > > + ); > > + > > +/** > > + 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 > > + ); > > + > > +/** > > + Switch the requested AP to be the BSP from that point onward. > > + > > + @param[in] MpServices MP_SERVICES structure. > > + @param[in] ProcessorNumber The handle number of AP that is to become the > new BSP. > > + @param[in] EnableOldBSP If TRUE, the old BSP will be listed as an > enabled AP. Otherwise, it will be disabled. > > + > > + @retval EFI_SUCCESS Switch the requested AP to be the BSP > successfully > > + @retval Others Switch the requested AP to be the BSP > unsuccessfully > > +**/ > > +EFI_STATUS > > +MpServicesUnitTestSwitchBSP ( > > + IN MP_SERVICES MpServices, > > + IN UINTN ProcessorNumber, > > + IN BOOLEAN EnableOldBSP > > + ); > > + > > +/** > > + Caller enables or disables an AP from this point onward. > > + > > + @param[in] MpServices MP_SERVICES structure. > > + @param[in] ProcessorNumber The handle number of the AP. > > + @param[in] EnableAP Specifies the new state for the processor for > enabled, FALSE for disabled. > > + @param[in] HealthFlag If not NULL, a pointer to a value that specifies > the new health status of the AP. > > + > > + @retval EFI_SUCCESS Caller enables or disables an AP successfully. > > + @retval Others Caller enables or disables an AP unsuccessfully. > > +**/ > > +EFI_STATUS > > +MpServicesUnitTestEnableDisableAP ( > > + IN MP_SERVICES MpServices, > > + IN UINTN ProcessorNumber, > > + IN BOOLEAN EnableAP, > > + IN UINT32 *HealthFlag > > + ); > > + > > +/** > > + 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 > > + ); > > + > > +/** > > + Empty procedure to be run on specified CPU. > > + > > + @param[in,out] Buffer The pointer to private data buffer. > > +**/ > > +VOID > > +EmptyProcedure ( > > + IN OUT VOID *Buffer > > + ); > > + > > +/** > > + Produce to store ProcessorNumber in CommonBuffer and be run on specified > CPU. > > + > > + @param[in,out] Buffer The pointer to private data buffer. > > +**/ > > +VOID > > +StoreCpuNumbers ( > > + IN OUT VOID *Buffer > > + ); > > + > > +/** > > + Prep routine for Unit test function. > > + To save the ProcessorNumber of disabled AP and temporarily enable it. > > + > > + @param[in] Context Context pointer for this test. > > + > > + @retval UNIT_TEST_PASSED Prep routine runs successful. > > + @retval UNIT_TEST_ERROR_TEST_FAILED Prep routine runs unsuccessful. > > +**/ > > +UNIT_TEST_STATUS > > +EFIAPI > > +InitUTContext ( > > + IN UNIT_TEST_CONTEXT Context > > + ); > > + > > +/** > > + Cleanup routine for Unit test function. > > + If any processor is disabled unexpectedly then reenable it. > > + > > + @param[in] Context Context pointer for this test. > > +**/ > > +VOID > > +EFIAPI > > +CheckUTContext ( > > + IN UNIT_TEST_CONTEXT Context > > + ); > > + > > +/** > > + Cleanup routine for Unit test function. > > + It will be called by the last "AddTestCase" to restore AP state and free > pointer. > > + > > + @param[in] Context Context pointer for this test. > > +**/ > > +VOID > > +EFIAPI > > +FreeUTContext ( > > + IN UNIT_TEST_CONTEXT Context > > + ); > > + > > +/** > > + Unit test of MP service WhoAmI. > > + The range of ProcessorNumber should be from 0 to NumberOfCPUs minus 1. > > + The ProcessorNumbers of all CPUs are unique. > > + > > + @param[in] Context Context pointer for this test. > > + > > + @retval UNIT_TEST_PASSED The Unit test has completed and the > test > > + case was successful. > > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed. > > +**/ > > +UNIT_TEST_STATUS > > +EFIAPI > > +TestWhoAmI1 ( > > + IN UNIT_TEST_CONTEXT Context > > + ); > > + > > +/** > > + Unit test of MP service GetNumberOfProcessors. > > + NumberOfProcessors should be greater that 0 and not less than > NumberOfEnabledProcessors. > > + > > + @param[in] Context Context pointer for this test. > > + > > + @retval UNIT_TEST_PASSED The Unit test has completed and the > test > > + case was successful. > > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed. > > +**/ > > +UNIT_TEST_STATUS > > +EFIAPI > > +TestGetNumberOfProcessors1 ( > > + IN UNIT_TEST_CONTEXT Context > > + ); > > + > > +/** > > + Unit test of MP service GetNumberOfProcessors. > > + When this service is called from an AP, the return status should be > EFI_DEVICE_ERROR. > > + > > + @param[in] Context Context pointer for this test. > > + > > + @retval UNIT_TEST_PASSED The Unit test has completed and the > test > > + case was successful. > > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed. > > +**/ > > +UNIT_TEST_STATUS > > +EFIAPI > > +TestGetNumberOfProcessors2 ( > > + IN UNIT_TEST_CONTEXT Context > > + ); > > + > > +/** > > + Unit test of MP service GetNumberOfProcessors. > > + Call EnableDisableAP() to change the number of enabled AP. > > + > > + @param[in] Context Context pointer for this test. > > + > > + @retval UNIT_TEST_PASSED The Unit test has completed and the > test > > + case was successful. > > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed. > > +**/ > > +UNIT_TEST_STATUS > > +EFIAPI > > +TestGetNumberOfProcessors3 ( > > + IN UNIT_TEST_CONTEXT Context > > + ); > > + > > +/** > > + Unit test of MP service GetProcessorInfo. > > + When all the parameters are valid, all reserved bits of StatusFlag in > ProcessorInfoBuffer should be set to zero. > > + When all the parameters are valid, the StatusFlag should not have an > invalid value (The BSP can never be in the disabled > state.). > > + When called with nonexistent processor handle, the return status should be > EFI_NOT_FOUND. > > + > > + @param[in] Context Context pointer for this test. > > + > > + @retval UNIT_TEST_PASSED The Unit test has completed and the > test > > + case was successful. > > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed. > > +**/ > > +UNIT_TEST_STATUS > > +EFIAPI > > +TestGetProcessorInfo1 ( > > + IN UNIT_TEST_CONTEXT Context > > + ); > > + > > +/** > > + Unit test of MP service GetProcessorInfo. > > + When this service is called from an AP, the return status should be > EFI_DEVICE_ERROR. > > + > > + @param[in] Context Context pointer for this test. > > + > > + @retval UNIT_TEST_PASSED The Unit test has completed and the > test > > + case was successful. > > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed. > > +**/ > > +UNIT_TEST_STATUS > > +EFIAPI > > +TestGetProcessorInfo2 ( > > + IN UNIT_TEST_CONTEXT Context > > + ); > > + > > +/** > > + Unit test of MP service EnableDisableAP. > > + When called with BSP number, the return status should be > EFI_INVALID_PARAMETER. > > + When called with a nonexistent processor handle, the return status should > be EFI_NOT_FOUND. > > + The AP should be really Enable/Disabled. > > + > > + @param[in] Context Context pointer for this test. > > + > > + @retval UNIT_TEST_PASSED The Unit test has completed and the > test > > + case was successful. > > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed. > > +**/ > > +UNIT_TEST_STATUS > > +EFIAPI > > +TestEnableDisableAP1 ( > > + IN UNIT_TEST_CONTEXT Context > > + ); > > + > > +/** > > + Unit test of MP service EnableDisableAP. > > + When run this procedure on AP, the return status should be > EFI_DEVICE_ERROR. > > + > > + @param[in] Context Context pointer for this test. > > + > > + @retval UNIT_TEST_PASSED The Unit test has completed and the > test > > + case was successful. > > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed. > > +**/ > > +UNIT_TEST_STATUS > > +EFIAPI > > +TestEnableDisableAP2 ( > > + IN UNIT_TEST_CONTEXT Context > > + ); > > + > > +/** > > + Unit test of MP service EnableDisableAP. > > + When run this procedure on AP, the return status should be > EFI_DEVICE_ERROR. > > + > > + @param[in] Context Context pointer for this test. > > + > > + @retval UNIT_TEST_PASSED The Unit test has completed and the > test > > + case was successful. > > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed. > > +**/ > > +UNIT_TEST_STATUS > > +EFIAPI > > +TestEnableDisableAP3 ( > > + IN UNIT_TEST_CONTEXT Context > > + ); > > + > > +/** > > + Unit test of MP service StartupThisAP. > > + When called to startup a BSP, the return status should be > EFI_INVALID_PARAMETER. > > + When called with a nonexistent processor handle, the return status should > be EFI_NOT_FOUND. > > + The requested AP should execute the Procedure when called by StartupThisAP. > > + > > + @param[in] Context Context pointer for this test. > > + > > + @retval UNIT_TEST_PASSED The Unit test has completed and the > test > > + case was successful. > > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed. > > +**/ > > +UNIT_TEST_STATUS > > +EFIAPI > > +TestStartupThisAP1 ( > > + IN UNIT_TEST_CONTEXT Context > > + ); > > + > > +/** > > + Unit test of MP service StartupThisAP. > > + When this service is called from an AP, the return status should be > EFI_DEVICE_ERROR. > > + > > + @param[in] Context Context pointer for this test. > > + > > + @retval UNIT_TEST_PASSED The Unit test has completed and the > test > > + case was successful. > > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed. > > +**/ > > +UNIT_TEST_STATUS > > +EFIAPI > > +TestStartupThisAP2 ( > > + IN UNIT_TEST_CONTEXT Context > > + ); > > + > > +/** > > + Unit test of MP service StartupThisAP. > > + When timeout expired before the requested AP has finished, the return > status should be EFI_TIMEOUT. > > + > > + @param[in] Context Context pointer for this test. > > + > > + @retval UNIT_TEST_PASSED The Unit test has completed and the > test > > + case was successful. > > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed. > > +**/ > > +UNIT_TEST_STATUS > > +EFIAPI > > +TestStartupThisAP3 ( > > + IN UNIT_TEST_CONTEXT Context > > + ); > > + > > +/** > > + Unit test of MP service StartupThisAP. > > + When called with disabled AP, the return status should be > EFI_INVALID_PARAMETER. > > + > > + @param[in] Context Context pointer for this test. > > + > > + @retval UNIT_TEST_PASSED The Unit test has completed and the > test > > + case was successful. > > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed. > > +**/ > > +UNIT_TEST_STATUS > > +EFIAPI > > +TestStartupThisAP4 ( > > + IN UNIT_TEST_CONTEXT Context > > + ); > > + > > +/** > > + Unit test of MP service StartupAllAPs. > > + All APs should execute the Procedure when called by StartupAllAPs. > > + > > + @param[in] Context Context pointer for this test. > > + > > + @retval UNIT_TEST_PASSED The Unit test has completed and the > test > > + case was successful. > > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed. > > +**/ > > +UNIT_TEST_STATUS > > +EFIAPI > > +TestStartupAllAPs1 ( > > + IN UNIT_TEST_CONTEXT Context > > + ); > > + > > +/** > > + Unit test of MP service StartupAllAPs. > > + When called in single thread, the return status should be EFI_SUCCESS and > AP executes in ascending order > > + of processor handle number. > > + > > + @param[in] Context Context pointer for this test. > > + > > + @retval UNIT_TEST_PASSED The Unit test has completed and the > test > > + case was successful. > > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed. > > +**/ > > +UNIT_TEST_STATUS > > +EFIAPI > > +TestStartupAllAPs2 ( > > + IN UNIT_TEST_CONTEXT Context > > + ); > > + > > +/** > > + Unit test of MP service StartupAllAPs. > > + When this service is called from an AP, the return status should be > EFI_DEVICE_ERROR. > > + > > + @param[in] Context Context pointer for this test. > > + > > + @retval UNIT_TEST_PASSED The Unit test has completed and the > test > > + case was successful. > > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed. > > +**/ > > +UNIT_TEST_STATUS > > +EFIAPI > > +TestStartupAllAPs3 ( > > + IN UNIT_TEST_CONTEXT Context > > + ); > > + > > +/** > > + Unit test of MP service StartupAllAPs. > > + When called with all AP timeout, the return status should be EFI_TIMEOUT. > > + > > + @param[in] Context Context pointer for this test. > > + > > + @retval UNIT_TEST_PASSED The Unit test has completed and the > test > > + case was successful. > > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed. > > +**/ > > +UNIT_TEST_STATUS > > +EFIAPI > > +TestStartupAllAPs4 ( > > + IN UNIT_TEST_CONTEXT Context > > + ); > > + > > +/** > > + Unit test of MP service StartupAllAPs. > > + When called with the empty Procedure on all disabled APs, the return > status should be EFI_NOT_STARTED. > > + > > + @param[in] Context Context pointer for this test. > > + > > + @retval UNIT_TEST_PASSED The Unit test has completed and the > test > > + case was successful. > > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed. > > +**/ > > +UNIT_TEST_STATUS > > +EFIAPI > > +TestStartupAllAPs5 ( > > + IN UNIT_TEST_CONTEXT Context > > + ); > > + > > +/** > > + Unit test of MP service SwitchBSP. > > + When switch current BSP to be BSP, the return status should be > EFI_INVALID_PARAMETER. > > + When switch nonexistent processor to be BSP, the return status should be > EFI_NOT_FOUND. > > + After switch BSP, all APs(includes new AP) should execute the Procedure > when called by StartupAllAP. > > + > > + @param[in] Context Context pointer for this test. > > + > > + @retval UNIT_TEST_PASSED The Unit test has completed and the > test > > + case was successful. > > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed. > > +**/ > > +UNIT_TEST_STATUS > > +EFIAPI > > +TestSwitchBSP1 ( > > + IN UNIT_TEST_CONTEXT Context > > + ); > > + > > +/** > > + Unit test of MP service SwitchBSP. > > + When run this procedure on AP, the return status should be > EFI_DEVICE_ERROR. > > + > > + @param[in] Context Context pointer for this test. > > + > > + @retval UNIT_TEST_PASSED The Unit test has completed and the > test > > + case was successful. > > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed. > > +**/ > > +UNIT_TEST_STATUS > > +EFIAPI > > +TestSwitchBSP2 ( > > + IN UNIT_TEST_CONTEXT Context > > + ); > > + > > +/** > > + Unit test of MP service SwitchBSP. > > + When switch a disabled AP to be BSP, the return status should be > EFI_INVALID_PARAMETER. > > + > > + @param[in] Context Context pointer for this test. > > + > > + @retval UNIT_TEST_PASSED The Unit test has completed and the > test > > + case was successful. > > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed. > > +**/ > > +UNIT_TEST_STATUS > > +EFIAPI > > +TestSwitchBSP3 ( > > + IN UNIT_TEST_CONTEXT Context > > + ); > > + > > +/** > > + Unit test of MP service SwitchBSP. > > + When SwitchBSP and EnableOldBSP is TRUE, the new BSP should be in the > enabled state and the old BSP should > > + be in the enabled state. > > + When SwitchBSP and EnableOldBSP is False, the new BSP should be in the > enabled state and the old BSP should > > + be in the disabled state. > > + > > + @param[in] Context Context pointer for this test. > > + > > + @retval UNIT_TEST_PASSED The Unit test has completed and the > test > > + case was successful. > > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed. > > +**/ > > +UNIT_TEST_STATUS > > +EFIAPI > > +TestSwitchBSP4 ( > > + IN UNIT_TEST_CONTEXT Context > > + ); > > + > > +/** > > + Create test suite and unit tests for both EdkiiPeiMpServices2Ppi and > EfiMpServiceProtocol. > > + > > + @param[in] Framework A pointer to the framework that is being > persisted. > > + @param[in] Context A pointer to the private data buffer. > > + > > + @retval EFI_SUCCESS Create test suite and unit tests successfully. > > + @retval Others Create test suite and unit tests unsuccessfully. > > +**/ > > +EFI_STATUS > > +AddCommonTestCase ( > > + IN UNIT_TEST_FRAMEWORK_HANDLE Framework, > > + IN MP_SERVICE_UT_CONTEXT *Context > > + ); > > + > > +#endif > > diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc > index f694b3a77c..db5fe654b5 100644 > --- a/UefiCpuPkg/UefiCpuPkg.dsc > +++ b/UefiCpuPkg/UefiCpuPkg.dsc > @@ -63,6 +63,9 @@ > MicrocodeLib|UefiCpuPkg/Library/MicrocodeLib/MicrocodeLib.inf > > > SmmCpuRendezvousLib|UefiCpuPkg/Library/SmmCpuRendezvousLib/SmmCpuRendezvousLib.inf > > CpuPageTableLib|UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableLib.inf > > + > UnitTestPersistenceLib|UnitTestFrameworkPkg/Library/UnitTestPersistenceLibNull/UnitTestPersistenceLibNull.inf > > + UnitTestLib|UnitTestFrameworkPkg/Library/UnitTestLib/UnitTestLib.inf > > + > UnitTestResultReportLib|UnitTestFrameworkPkg/Library/UnitTestResultReportLib/UnitTestResultReportLibDebugLib.inf > > > > [LibraryClasses.common.SEC] > > PlatformSecLib|UefiCpuPkg/Library/PlatformSecLibNull/PlatformSecLibNull.inf > > @@ -177,6 +180,8 @@ > UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.inf > > UefiCpuPkg/Library/SmmCpuRendezvousLib/SmmCpuRendezvousLib.inf > > UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableLib.inf > > + > UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EdkiiPeiMpServices2PpiPeiUnitTest.inf > > + > UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EfiMpServiceProtocolDxeUnitTest.inf > > > > [BuildOptions] > > *_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES > > -- > 2.28.0.windows.1
-=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#95195): https://edk2.groups.io/g/devel/message/95195 Mute This Topic: https://groups.io/mt/94236483/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-