From: Jason Lou <yun.lou@...>
The code changes add unit tests based on current UnitTestFramework.
EdkiiPeiMpServices2PpiPeiUnitTest PEIM is used to test
EdkiiPeiMpServices2Ppi and EfiMpServiceProtocolDxeUnitTest DXE driver is
used to test EfiMpServiceProtocol.
Change-Id: I7c48249d5113c172655df5f39cfc254f48aed259
Signed-off-by: Jason Lou <yun.lou@...>
Cc: Ray Ni <ray.ni@...>
Cc: Eric Dong <eric.dong@...>
Cc: Laszlo Ersek <lersek@...>
Cc: Rahul Kumar <rahul1.kumar@...>
---
UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EdkiiPeiMpServices2PpiUn=
itTest.c | 477 ++++++
UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EfiMpServiceProtocolUnit=
Test.c | 244 +++
UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EfiMpServicesUnitTestCom=
mom.c | 1741 ++++++++++++++++++++
UefiCpuPkg/Test/UefiCpuPkgHostTest.dsc =
| 6 +
UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EdkiiPeiMpServices2PpiPe=
iUnitTest.inf | 46 +
UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EfiMpServiceProtocolDxeU=
nitTest.inf | 46 +
UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EfiMpServicesUnitTestCom=
mom.h | 611 +++++++
7 files changed, 3171 insertions(+)
diff --git a/UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EdkiiPeiMpSe=
rvices2PpiUnitTest.c b/UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/Ed=
kiiPeiMpServices2PpiUnitTest.c
new file mode 100644
index 0000000000..1826a6daae
--- /dev/null
+++ b/UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EdkiiPeiMpServices2=
PpiUnitTest.c
@@ -0,0 +1,477 @@
+/** @file=0D
+ PEI Module to test APIs defined in EdkiiPeiMpServices2Ppi.=0D
+=0D
+ Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>=0D
+=0D
+ SPDX-License-Identifier: BSD-2-Clause-Patent=0D
+=0D
+**/=0D
+=0D
+#include <Library/PeimEntryPoint.h>=0D
+#include <Library/PeiServicesLib.h>=0D
+#include "EfiMpServicesUnitTestCommom.h"=0D
+=0D
+#define UNIT_TEST_NAME "EdkiiPeiMpServices2Ppi Unit Test"=0D
+#define UNIT_TEST_VERSION "0.1"=0D
+=0D
+/**=0D
+ Get EDKII_PEI_MP_SERVICES2_PPI pointer.=0D
+=0D
+ @param[out] MpServices Pointer to the buffer where EDKII_PEI_MP_SERVI=
CES2_PPI is stored.=0D
+=0D
+ @retval EFI_SUCCESS EDKII_PEI_MP_SERVICES2_PPI interface is return=
ed=0D
+ @retval EFI_NOT_FOUND EDKII_PEI_MP_SERVICES2_PPI interface is not fo=
und=0D
+**/=0D
+EFI_STATUS=0D
+MpServicesUnitTestGetMpServices (=0D
+ OUT MP_SERVICES *MpServices=0D
+ )=0D
+{=0D
+ return PeiServicesLocatePpi (&gEdkiiPeiMpServices2PpiGuid, 0, NULL, (VO=
ID **)&MpServices->Ppi);=0D
+}=0D
+=0D
+/**=0D
+ Retrieve the number of logical processor in the platform and the number =
of those logical processors that=0D
+ are enabled on this boot.=0D
+=0D
+ @param[in] MpServices MP_SERVICES structure.=0D
+ @param[out] NumberOfProcessors Pointer to the total number of logical p=
rocessors in the system, including=0D
+ the BSP and disabled APs.=0D
+ @param[out] NumberOfEnabledProcessors Pointer to the number of processor=
s in the system that are enabled.=0D
+=0D
+ @retval EFI_SUCCESS Retrieve the number of logical processor succe=
ssfully=0D
+ @retval Others Retrieve the number of logical processor unsuc=
cessfully=0D
+**/=0D
+EFI_STATUS=0D
+MpServicesUnitTestGetNumberOfProcessors (=0D
+ IN MP_SERVICES MpServices,=0D
+ OUT UINTN *NumberOfProcessors,=0D
+ OUT UINTN *NumberOfEnabledProcessors=0D
+ )=0D
+{=0D
+ return MpServices.Ppi->GetNumberOfProcessors (MpServices.Ppi, NumberOfP=
rocessors, NumberOfEnabledProcessors);=0D
+}=0D
+=0D
+/**=0D
+ Get detailed information on the requested logical processor.=0D
+=0D
+ @param[in] MpServices MP_SERVICES structure.=0D
+ @param[in] ProcessorNum The handle number of the processor.=0D
+ @param[out] ProcessorInfo Pointer to the buffer where the processor info=
rmation is stored.=0D
+=0D
+ @retval EFI_SUCCESS Get information on the requested logical proce=
ssor successfully=0D
+ @retval Others Get information on the requested logical proce=
ssor unsuccessfully=0D
+**/=0D
+EFI_STATUS=0D
+MpServicesUnitTestGetProcessorInfo (=0D
+ IN MP_SERVICES MpServices,=0D
+ IN UINTN ProcessorNumber,=0D
+ OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer=0D
+ )=0D
+{=0D
+ return MpServices.Ppi->GetProcessorInfo (MpServices.Ppi, ProcessorNumbe=
r, ProcessorInfoBuffer);=0D
+}=0D
+=0D
+/**=0D
+ Execute a caller provided function on all enabled APs.=0D
+=0D
+ @param[in] MpServices MP_SERVICES structure.=0D
+ @param[in] Procedure Pointer to the function to be run on enabled A=
Ps of the system.=0D
+ @param[in] SingleThread If TRUE, then all the enabled APs execute the =
function specified by Procedure=0D
+ one by one, in ascending order of processor ha=
ndle number.=0D
+ If FALSE, then all the enabled APs execute the=
function specified by Procedure=0D
+ simultaneously.=0D
+ @param[in] TimeoutInMicroseconds Indicates the time limit in microsecon=
ds for APs to return from Procedure,=0D
+ for blocking mode only. Zero means inf=
inity.=0D
+ @param[in] ProcedureArgument The parameter passed into Procedure fo=
r all APs.=0D
+=0D
+ @retval EFI_SUCCESS Execute a caller provided function on all enab=
led APs successfully=0D
+ @retval Others Execute a caller provided function on all enab=
led APs unsuccessfully=0D
+**/=0D
+EFI_STATUS=0D
+MpServicesUnitTestStartupAllAPs (=0D
+ IN MP_SERVICES MpServices,=0D
+ IN EFI_AP_PROCEDURE Procedure,=0D
+ IN BOOLEAN SingleThread,=0D
+ IN UINTN TimeoutInMicroSeconds,=0D
+ IN VOID *ProcedureArgument=0D
+ )=0D
+{=0D
+ return MpServices.Ppi->StartupAllAPs (MpServices.Ppi, Procedure, Single=
Thread, TimeoutInMicroSeconds, ProcedureArgument);=0D
+}=0D
+=0D
+/**=0D
+ Caller gets one enabled AP to execute a caller-provided function.=0D
+=0D
+ @param[in] MpServices MP_SERVICES structure.=0D
+ @param[in] Procedure Pointer to the function to be run on enabled A=
Ps of the system.=0D
+ @param[in] ProcessorNumber The handle number of the AP.=0D
+ @param[in] TimeoutInMicroseconds Indicates the time limit in microsecon=
ds for APs to return from Procedure,=0D
+ for blocking mode only. Zero means inf=
inity.=0D
+ @param[in] ProcedureArgument The parameter passed into Procedure fo=
r all APs.=0D
+=0D
+=0D
+ @retval EFI_SUCCESS Caller gets one enabled AP to execute a caller=
-provided function successfully=0D
+ @retval Others Caller gets one enabled AP to execute a caller=
-provided function unsuccessfully=0D
+**/=0D
+EFI_STATUS=0D
+MpServicesUnitTestStartupThisAP (=0D
+ IN MP_SERVICES MpServices,=0D
+ IN EFI_AP_PROCEDURE Procedure,=0D
+ IN UINTN ProcessorNumber,=0D
+ IN UINTN TimeoutInMicroSeconds,=0D
+ IN VOID *ProcedureArgument=0D
+ )=0D
+{=0D
+ return MpServices.Ppi->StartupThisAP (MpServices.Ppi, Procedure, Proces=
sorNumber, TimeoutInMicroSeconds, ProcedureArgument);=0D
+}=0D
+=0D
+/**=0D
+ Switch the requested AP to be the BSP from that point onward.=0D
+=0D
+ @param[in] MpServices MP_SERVICES structure.=0D
+ @param[in] ProcessorNumber The handle number of AP that is to become th=
e new BSP.=0D
+ @param[in] EnableOldBSP If TRUE, the old BSP will be listed as an enab=
led AP. Otherwise, it will be disabled.=0D
+=0D
+ @retval EFI_SUCCESS Switch the requested AP to be the BSP successf=
ully=0D
+ @retval Others Switch the requested AP to be the BSP unsucces=
sfully=0D
+**/=0D
+EFI_STATUS=0D
+MpServicesUnitTestSwitchBSP (=0D
+ IN MP_SERVICES MpServices,=0D
+ IN UINTN ProcessorNumber,=0D
+ IN BOOLEAN EnableOldBSP=0D
+ )=0D
+{=0D
+ return MpServices.Ppi->SwitchBSP (MpServices.Ppi, ProcessorNumber, Enab=
leOldBSP);=0D
+}=0D
+=0D
+/**=0D
+ Caller enables or disables an AP from this point onward.=0D
+=0D
+ @param[in] MpServices MP_SERVICES structure.=0D
+ @param[in] ProcessorNumber The handle number of the AP.=0D
+ @param[in] EnableAP Specifies the new state for the processor for =
enabled, FALSE for disabled.=0D
+ @param[in] HealthFlag If not NULL, a pointer to a value that specifi=
es the new health status of the AP.=0D
+=0D
+ @retval EFI_SUCCESS Caller enables or disables an AP successfully.=
=0D
+ @retval Others Caller enables or disables an AP unsuccessfull=
y.=0D
+**/=0D
+EFI_STATUS=0D
+MpServicesUnitTestEnableDisableAP (=0D
+ IN MP_SERVICES MpServices,=0D
+ IN UINTN ProcessorNumber,=0D
+ IN BOOLEAN EnableAP,=0D
+ IN UINT32 *HealthFlag=0D
+ )=0D
+{=0D
+ return MpServices.Ppi->EnableDisableAP (MpServices.Ppi, ProcessorNumber=
, EnableAP, HealthFlag);=0D
+}=0D
+=0D
+/**=0D
+ Get the handle number for the calling processor.=0D
+=0D
+ @param[in] MpServices MP_SERVICES structure.=0D
+ @param[out] ProcessorNumber The handle number for the calling processor.=
=0D
+=0D
+ @retval EFI_SUCCESS Get the handle number for the calling processo=
r successfully.=0D
+ @retval Others Get the handle number for the calling processo=
r unsuccessfully.=0D
+**/=0D
+EFI_STATUS=0D
+MpServicesUnitTestWhoAmI (=0D
+ IN MP_SERVICES MpServices,=0D
+ OUT UINTN *ProcessorNumber=0D
+ )=0D
+{=0D
+ return MpServices.Ppi->WhoAmI (MpServices.Ppi, ProcessorNumber);=0D
+}=0D
+=0D
+/**=0D
+ Execute a caller provided function on all enabled CPUs.=0D
+=0D
+ @param[in] MpServices MP_SERVICES structure.=0D
+ @param[in] Procedure Pointer to the function to be run on enabled C=
PUs of the system.=0D
+ @param[in] TimeoutInMicroseconds Indicates the time limit in microsecon=
ds for APs to return from Procedure,=0D
+ for blocking mode only. Zero means inf=
inity.=0D
+ @param[in] ProcedureArgument The parameter passed into Procedure fo=
r all enabled CPUs.=0D
+=0D
+ @retval EFI_SUCCESS Execute a caller provided function on all enab=
led CPUs successfully=0D
+ @retval Others Execute a caller provided function on all enab=
led CPUs unsuccessfully=0D
+**/=0D
+EFI_STATUS=0D
+MpServicesUnitTestStartupAllCPUs (=0D
+ IN MP_SERVICES MpServices,=0D
+ IN EFI_AP_PROCEDURE Procedure,=0D
+ IN UINTN TimeoutInMicroSeconds,=0D
+ IN VOID *ProcedureArgument=0D
+ )=0D
+{=0D
+ return MpServices.Ppi->StartupAllCPUs (MpServices.Ppi, Procedure, Timeo=
utInMicroSeconds, ProcedureArgument);=0D
+}=0D
+=0D
+/**=0D
+ Infinite loop procedure to be run on specified AP.=0D
+=0D
+ @param[in,out] Buffer The pointer to private data buffer.=0D
+**/=0D
+VOID=0D
+ApInfiniteLoopProcedure (=0D
+ IN OUT VOID *Buffer=0D
+ )=0D
+{=0D
+ EFI_STATUS Status;=0D
+ UINTN ProcessorNumber;=0D
+ volatile BOOLEAN InfiniteLoop;=0D
+ MP_SERVICE_UT_CONTEXT *LocalContext;=0D
+=0D
+ LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Buffer;=0D
+=0D
+ Status =3D MpServicesUnitTestWhoAmI (LocalContext->MpServices, &Processo=
rNumber);=0D
+ ASSERT_EFI_ERROR (Status);=0D
+=0D
+ if (ProcessorNumber =3D=3D LocalContext->BspNumber) {=0D
+ InfiniteLoop =3D FALSE;=0D
+ } else {=0D
+ InfiniteLoop =3D TRUE;=0D
+ }=0D
+=0D
+ while (InfiniteLoop);=0D
+}=0D
+=0D
+/**=0D
+ Procedure to run MP service StartupAllCPUs on AP.=0D
+=0D
+ @param[in,out] Buffer The pointer to private data buffer.=0D
+**/=0D
+VOID=0D
+RunMpServiceStartupAllCPUsOnAp (=0D
+ IN OUT VOID *Buffer=0D
+ )=0D
+{=0D
+ MP_SERVICE_UT_CONTEXT *LocalContext;=0D
+=0D
+ LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Buffer;=0D
+=0D
+ LocalContext->ApProcedureReturnStatus =3D MpServicesUnitTestStartupAllCP=
Us (=0D
+ LocalContext->MpServices,=0D
+ (EFI_AP_PROCEDURE) EmptyProcedur=
e,=0D
+ 0,=0D
+ NULL=0D
+ );=0D
+}=0D
+=0D
+/**=0D
+ Unit test of PEI MP service StartupAllCPU.=0D
+ All CPUs should execute the Procedure.=0D
+=0D
+ @param[in] Context Context pointer for this test.=0D
+=0D
+ @retval UNIT_TEST_PASSED The Unit test has completed and th=
e test=0D
+ case was successful.=0D
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.=
=0D
+**/=0D
+UNIT_TEST_STATUS=0D
+TestStartupAllCPUs1 (=0D
+ IN UNIT_TEST_CONTEXT Context=0D
+ )=0D
+{=0D
+ EFI_STATUS Status;=0D
+ UINTN ProcessorIndex;=0D
+ MP_SERVICE_UT_CONTEXT *LocalContext;=0D
+=0D
+ LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Context;=0D
+=0D
+ SetMem (LocalContext->CommonBuffer, LocalContext->NumberOfProcessors * s=
izeof (*LocalContext->CommonBuffer), 0xFF);=0D
+ Status =3D MpServicesUnitTestStartupAllCPUs (=0D
+ LocalContext->MpServices,=0D
+ (EFI_AP_PROCEDURE) StoreCpuNumbers,=0D
+ 0,=0D
+ (VOID *) LocalContext=0D
+ );=0D
+ UT_ASSERT_NOT_EFI_ERROR (Status);=0D
+=0D
+ for (ProcessorIndex =3D 0; ProcessorIndex < LocalContext->NumberOfProces=
sors; ProcessorIndex++) {=0D
+ UT_ASSERT_TRUE (LocalContext->CommonBuffer[ProcessorIndex] =3D=3D Proc=
essorIndex);=0D
+ }=0D
+=0D
+ return UNIT_TEST_PASSED;=0D
+}=0D
+=0D
+/**=0D
+ Unit test of PEI MP service StartupAllCPU.=0D
+ When this service is called from an AP, the return status should be EFI_=
DEVICE_ERROR.=0D
+=0D
+ @param[in] Context Context pointer for this test.=0D
+=0D
+ @retval UNIT_TEST_PASSED The Unit test has completed and th=
e test=0D
+ case was successful.=0D
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.=
=0D
+**/=0D
+UNIT_TEST_STATUS=0D
+TestStartupAllCPUs2 (=0D
+ IN UNIT_TEST_CONTEXT Context=0D
+ )=0D
+{=0D
+ EFI_STATUS Status;=0D
+ UINTN ApNumber;=0D
+ MP_SERVICE_UT_CONTEXT *LocalContext;=0D
+=0D
+ LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Context;=0D
+=0D
+ for (ApNumber =3D 0; ApNumber < LocalContext->NumberOfProcessors; ApNumb=
er++) {=0D
+ LocalContext->ApNumber =3D ApNumber;=0D
+ Status =3D MpServicesUnitTestStartupThisAP (=0D
+ LocalContext->MpServices,=0D
+ (EFI_AP_PROCEDURE) RunMpServiceStartupAllCPUsOnAp,=0D
+ ApNumber,=0D
+ 0,=0D
+ (VOID *) LocalContext=0D
+ );=0D
+=0D
+ if (ApNumber =3D=3D LocalContext->BspNumber) {=0D
+ UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER);=0D
+ } else {=0D
+ UT_ASSERT_NOT_EFI_ERROR (Status);=0D
+ UT_ASSERT_STATUS_EQUAL (LocalContext->ApProcedureReturnStatus, EFI_D=
EVICE_ERROR);=0D
+ }=0D
+ }=0D
+=0D
+ return UNIT_TEST_PASSED;=0D
+}=0D
+=0D
+/**=0D
+ Unit test of PEI MP service StartupAllCPU.=0D
+ When called with all CPUs timeout, the return status should be EFI_TIMEO=
UT.=0D
+=0D
+ @param[in] Context Context pointer for this test.=0D
+=0D
+ @retval UNIT_TEST_PASSED The Unit test has completed and th=
e test=0D
+ case was successful.=0D
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.=
=0D
+**/=0D
+UNIT_TEST_STATUS=0D
+TestStartupAllCPUs3 (=0D
+ IN UNIT_TEST_CONTEXT Context=0D
+ )=0D
+{=0D
+ EFI_STATUS Status;=0D
+ MP_SERVICE_UT_CONTEXT *LocalContext;=0D
+=0D
+ LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Context;=0D
+=0D
+ Status =3D MpServicesUnitTestStartupAllCPUs (=0D
+ LocalContext->MpServices,=0D
+ (EFI_AP_PROCEDURE) ApInfiniteLoopProcedure,=0D
+ RUN_PROCEDURE_TIMEOUT_VALUE,=0D
+ (VOID *) LocalContext=0D
+ );=0D
+ UT_ASSERT_STATUS_EQUAL (Status, EFI_TIMEOUT);=0D
+=0D
+ return UNIT_TEST_PASSED;=0D
+}=0D
+=0D
+/**=0D
+ Create test suite and unit tests only for EdkiiPeiMpServices2Ppi.=0D
+=0D
+ @retval EFI_SUCCESS All test cases were dispatched.=0D
+ @retval EFI_OUT_OF_RESOURCES There are not enough resources available =
to=0D
+ initialize the unit tests.=0D
+=0D
+ @param[in] Framework A pointer to the framework that is being persi=
sted.=0D
+ @param[in] Context A pointer to the private data buffer.=0D
+=0D
+ @retval EFI_SUCCESS Create test suite and unit tests successfully.=
=0D
+ @retval Others Create test suite and unit tests unsuccessfull=
y.=0D
+**/=0D
+EFI_STATUS=0D
+AddTestCaseOnlyForEdkiiPeiMpServices2Ppi (=0D
+ IN UNIT_TEST_FRAMEWORK_HANDLE Framework,=0D
+ IN MP_SERVICE_UT_CONTEXT *Context=0D
+ )=0D
+{=0D
+ EFI_STATUS Status;=0D
+ UNIT_TEST_SUITE_HANDLE MpServiceStartupAllCPUsTestSuite;=0D
+=0D
+ MpServiceStartupAllCPUsTestSuite =3D NULL;=0D
+=0D
+ //=0D
+ // Test StartupAllCPUs function=0D
+ //=0D
+ Status =3D CreateUnitTestSuite (&MpServiceStartupAllCPUsTestSuite, Frame=
work, "Execute a caller provided function on all enabled CPUs", "MpServices=
.StartupAllCPUs", NULL, NULL);=0D
+ if (EFI_ERROR (Status)) {=0D
+ DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for MpServiceStart=
upAllCPUs Test Suite\n"));=0D
+ return Status;=0D
+ }=0D
+=0D
+ AddTestCase (MpServiceStartupAllCPUsTestSuite, "Test StartupAllCPUs 1", =
"TestStartupAllCPUs1", TestStartupAllCPUs1, InitUTContext, CheckUTContext, =
Context);=0D
+ AddTestCase (MpServiceStartupAllCPUsTestSuite, "Test StartupAllCPUs 2", =
"TestStartupAllCPUs2", TestStartupAllCPUs2, InitUTContext, CheckUTContext, =
Context);=0D
+ AddTestCase (MpServiceStartupAllCPUsTestSuite, "Test StartupAllCPUs 3", =
"TestStartupAllCPUs3", TestStartupAllCPUs3, InitUTContext, CheckUTContext, =
Context);=0D
+=0D
+ return EFI_SUCCESS;=0D
+}=0D
+=0D
+/**=0D
+ Standard PEIM entry point for unit test execution from PEI.=0D
+ Initialize the unit test framework, suite, and unit tests for the EdkiiP=
eiMpServices2Ppi and run the unit test.=0D
+=0D
+ @param[in] FileHandle Handle of the file being invoked.=0D
+ @param[in] PeiServices Pointer to PEI Services table.=0D
+=0D
+**/=0D
+EFI_STATUS=0D
+EFIAPI=0D
+PeiEntryPoint (=0D
+ IN EFI_PEI_FILE_HANDLE FileHandle,=0D
+ IN CONST EFI_PEI_SERVICES **PeiServices=0D
+ )=0D
+{=0D
+ EFI_STATUS Status;=0D
+ UNIT_TEST_FRAMEWORK_HANDLE Framework;=0D
+ MP_SERVICE_UT_CONTEXT Context;=0D
+=0D
+ Framework =3D NULL;=0D
+ Context.MpServices.Ppi =3D NULL;=0D
+ Context.CommonBuffer =3D NULL;=0D
+ Context.DisabledApNumber =3D NULL;=0D
+=0D
+ DEBUG ((DEBUG_INFO, "%a v%a\n", UNIT_TEST_NAME, UNIT_TEST_VERSION));=0D
+=0D
+ //=0D
+ // Start setting up the test framework for running the tests.=0D
+ //=0D
+ Status =3D InitUnitTestFramework (&Framework, UNIT_TEST_NAME, gEfiCaller=
BaseName, UNIT_TEST_VERSION);=0D
+ if (EFI_ERROR (Status)) {=0D
+ DEBUG ((DEBUG_ERROR, "Failed in InitUnitTestFramework. Status =3D %r\n=
", Status));=0D
+ goto EXIT;=0D
+ }=0D
+=0D
+ //=0D
+ // Create test suite and unit tests only for EdkiiPeiMpServices2Ppi.=0D
+ //=0D
+ Status =3D AddTestCaseOnlyForEdkiiPeiMpServices2Ppi (Framework, &Context=
);=0D
+ if (EFI_ERROR (Status)) {=0D
+ DEBUG ((DEBUG_ERROR, "Failed in AddTestCaseOnlyForEdkiiPeiMpServices2P=
pi. Status =3D %r\n", Status));=0D
+ goto EXIT;=0D
+ }=0D
+=0D
+ //=0D
+ // Create test suite and unit tests for both EdkiiPeiMpServices2Ppi and =
EfiMpServiceProtocol.=0D
+ //=0D
+ Status =3D AddCommonTestCase (Framework, &Context);=0D
+ if (EFI_ERROR (Status)) {=0D
+ DEBUG ((DEBUG_ERROR, "Failed in AddCommonTestCase. Status =3D %r\n", S=
tatus));=0D
+ goto EXIT;=0D
+ }=0D
+=0D
+ //=0D
+ // Execute the tests.=0D
+ //=0D
+ Status =3D RunAllTestSuites (Framework);=0D
+=0D
+EXIT:=0D
+ if (Framework !=3D NULL) {=0D
+ FreeUnitTestFramework (Framework);=0D
+ }=0D
+=0D
+ return Status;=0D
+}=0D
diff --git a/UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EfiMpService=
ProtocolUnitTest.c b/UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EfiM=
pServiceProtocolUnitTest.c
new file mode 100644
index 0000000000..32ec1792a1
--- /dev/null
+++ b/UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EfiMpServiceProtoco=
lUnitTest.c
@@ -0,0 +1,244 @@
+/** @file=0D
+ PEI Module to test EfiMpServiceProtocol.=0D
+=0D
+ Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>=0D
+=0D
+ SPDX-License-Identifier: BSD-2-Clause-Patent=0D
+=0D
+**/=0D
+=0D
+#include <PiDxe.h>=0D
+#include <Library/UefiBootServicesTableLib.h>=0D
+#include "EfiMpServicesUnitTestCommom.h"=0D
+=0D
+#define UNIT_TEST_NAME "EfiMpServiceProtocol Unit Test"=0D
+#define UNIT_TEST_VERSION "0.1"=0D
+=0D
+/**=0D
+ Get EFI_MP_SERVICES_PROTOCOL pointer.=0D
+=0D
+ @param[out] MpServices Pointer to the buffer where EFI_MP_SERVICES_PR=
OTOCOL is stored=0D
+=0D
+ @retval EFI_SUCCESS EFI_MP_SERVICES_PROTOCOL interface is returned=
=0D
+ @retval EFI_NOT_FOUND EFI_MP_SERVICES_PROTOCOL interface is not foun=
d=0D
+**/=0D
+EFI_STATUS=0D
+MpServicesUnitTestGetMpServices (=0D
+ OUT MP_SERVICES *MpServices=0D
+ )=0D
+{=0D
+ return gBS->LocateProtocol (&gEfiMpServiceProtocolGuid, NULL, (VOID **)=
&MpServices->Protocol);=0D
+}=0D
+=0D
+/**=0D
+ Retrieve the number of logical processor in the platform and the number =
of those logical processors that=0D
+ are enabled on this boot.=0D
+=0D
+ @param[in] MpServices MP_SERVICES structure.=0D
+ @param[out] NumberOfProcessors Pointer to the total number of logical p=
rocessors in the system, including=0D
+ the BSP and disabled APs.=0D
+ @param[out] NumberOfEnabledProcessors Pointer to the number of processor=
s in the system that are enabled.=0D
+=0D
+ @retval EFI_SUCCESS Retrieve the number of logical processor succe=
ssfully=0D
+ @retval Others Retrieve the number of logical processor unsuc=
cessfully=0D
+**/=0D
+EFI_STATUS=0D
+MpServicesUnitTestGetNumberOfProcessors (=0D
+ IN MP_SERVICES MpServices,=0D
+ OUT UINTN *NumberOfProcessors,=0D
+ OUT UINTN *NumberOfEnabledProcessors=0D
+ )=0D
+{=0D
+ return MpServices.Protocol->GetNumberOfProcessors (MpServices.Protocol,=
NumberOfProcessors, NumberOfEnabledProcessors);=0D
+}=0D
+=0D
+/**=0D
+ Get detailed information on the requested logical processor.=0D
+=0D
+ @param[in] MpServices MP_SERVICES structure.=0D
+ @param[in] ProcessorNum The handle number of the processor.=0D
+ @param[out] ProcessorInfo Pointer to the buffer where the processor info=
rmation is stored.=0D
+=0D
+ @retval EFI_SUCCESS Get information on the requested logical proce=
ssor successfully=0D
+ @retval Others Get information on the requested logical proce=
ssor unsuccessfully=0D
+**/=0D
+EFI_STATUS=0D
+MpServicesUnitTestGetProcessorInfo (=0D
+ IN MP_SERVICES MpServices,=0D
+ IN UINTN ProcessorNumber,=0D
+ OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer=0D
+ )=0D
+{=0D
+ return MpServices.Protocol->GetProcessorInfo (MpServices.Protocol, Proc=
essorNumber, ProcessorInfoBuffer);=0D
+}=0D
+=0D
+/**=0D
+ Execute a caller provided function on all enabled APs.=0D
+=0D
+ @param[in] MpServices MP_SERVICES structure.=0D
+ @param[in] Procedure Pointer to the function to be run on enabled A=
Ps of the system.=0D
+ @param[in] SingleThread If TRUE, then all the enabled APs execute the =
function specified by Procedure=0D
+ one by one, in ascending order of processor ha=
ndle number.=0D
+ If FALSE, then all the enabled APs execute the=
function specified by Procedure=0D
+ simultaneously.=0D
+ @param[in] TimeoutInMicroseconds Indicates the time limit in microsecon=
ds for APs to return from Procedure,=0D
+ for blocking mode only. Zero means inf=
inity.=0D
+ @param[in] ProcedureArgument The parameter passed into Procedure fo=
r all APs.=0D
+=0D
+ @retval EFI_SUCCESS Execute a caller provided function on all enab=
led APs successfully=0D
+ @retval Others Execute a caller provided function on all enab=
led APs unsuccessfully=0D
+**/=0D
+EFI_STATUS=0D
+MpServicesUnitTestStartupAllAPs (=0D
+ IN MP_SERVICES MpServices,=0D
+ IN EFI_AP_PROCEDURE Procedure,=0D
+ IN BOOLEAN SingleThread,=0D
+ IN UINTN TimeoutInMicroSeconds,=0D
+ IN VOID *ProcedureArgument=0D
+ )=0D
+{=0D
+ return MpServices.Protocol->StartupAllAPs (MpServices.Protocol, Procedu=
re, SingleThread, NULL, TimeoutInMicroSeconds, ProcedureArgument, NULL);=0D
+}=0D
+=0D
+/**=0D
+ Caller gets one enabled AP to execute a caller-provided function.=0D
+=0D
+ @param[in] MpServices MP_SERVICES structure.=0D
+ @param[in] Procedure Pointer to the function to be run on enabled A=
Ps of the system.=0D
+ @param[in] ProcessorNumber The handle number of the AP.=0D
+ @param[in] TimeoutInMicroseconds Indicates the time limit in microsecon=
ds for APs to return from Procedure,=0D
+ for blocking mode only. Zero means inf=
inity.=0D
+ @param[in] ProcedureArgument The parameter passed into Procedure fo=
r all APs.=0D
+=0D
+=0D
+ @retval EFI_SUCCESS Caller gets one enabled AP to execute a caller=
-provided function successfully=0D
+ @retval Others Caller gets one enabled AP to execute a caller=
-provided function unsuccessfully=0D
+**/=0D
+EFI_STATUS=0D
+MpServicesUnitTestStartupThisAP (=0D
+ IN MP_SERVICES MpServices,=0D
+ IN EFI_AP_PROCEDURE Procedure,=0D
+ IN UINTN ProcessorNumber,=0D
+ IN UINTN TimeoutInMicroSeconds,=0D
+ IN VOID *ProcedureArgument=0D
+ )=0D
+{=0D
+ return MpServices.Protocol->StartupThisAP (MpServices.Protocol, Procedu=
re, ProcessorNumber, NULL, TimeoutInMicroSeconds, ProcedureArgument, NULL);=
=0D
+}=0D
+=0D
+/**=0D
+ Switch the requested AP to be the BSP from that point onward.=0D
+=0D
+ @param[in] MpServices MP_SERVICES structure.=0D
+ @param[in] ProcessorNumber The handle number of AP that is to become th=
e new BSP.=0D
+ @param[in] EnableOldBSP If TRUE, the old BSP will be listed as an enab=
led AP. Otherwise, it will be disabled.=0D
+=0D
+ @retval EFI_SUCCESS Switch the requested AP to be the BSP successf=
ully=0D
+ @retval Others Switch the requested AP to be the BSP unsucces=
sfully=0D
+**/=0D
+EFI_STATUS=0D
+MpServicesUnitTestSwitchBSP (=0D
+ IN MP_SERVICES MpServices,=0D
+ IN UINTN ProcessorNumber,=0D
+ IN BOOLEAN EnableOldBSP=0D
+ )=0D
+{=0D
+ return MpServices.Protocol->SwitchBSP (MpServices.Protocol, ProcessorNu=
mber, EnableOldBSP);=0D
+}=0D
+=0D
+/**=0D
+ Caller enables or disables an AP from this point onward.=0D
+=0D
+ @param[in] MpServices MP_SERVICES structure.=0D
+ @param[in] ProcessorNumber The handle number of the AP.=0D
+ @param[in] EnableAP Specifies the new state for the processor for =
enabled, FALSE for disabled.=0D
+ @param[in] HealthFlag If not NULL, a pointer to a value that specifi=
es the new health status of the AP.=0D
+=0D
+ @retval EFI_SUCCESS Caller enables or disables an AP successfully.=
=0D
+ @retval Others Caller enables or disables an AP unsuccessfull=
y.=0D
+**/=0D
+EFI_STATUS=0D
+MpServicesUnitTestEnableDisableAP (=0D
+ IN MP_SERVICES MpServices,=0D
+ IN UINTN ProcessorNumber,=0D
+ IN BOOLEAN EnableAP,=0D
+ IN UINT32 *HealthFlag=0D
+ )=0D
+{=0D
+ return MpServices.Protocol->EnableDisableAP (MpServices.Protocol, Proce=
ssorNumber, EnableAP, HealthFlag);=0D
+}=0D
+=0D
+/**=0D
+ Get the handle number for the calling processor.=0D
+=0D
+ @param[in] MpServices MP_SERVICES structure.=0D
+ @param[out] ProcessorNumber The handle number for the calling processor.=
=0D
+=0D
+ @retval EFI_SUCCESS Get the handle number for the calling processo=
r successfully.=0D
+ @retval Others Get the handle number for the calling processo=
r unsuccessfully.=0D
+**/=0D
+EFI_STATUS=0D
+MpServicesUnitTestWhoAmI (=0D
+ IN MP_SERVICES MpServices,=0D
+ OUT UINTN *ProcessorNumber=0D
+ )=0D
+{=0D
+ return MpServices.Protocol->WhoAmI (MpServices.Protocol, ProcessorNumbe=
r);=0D
+}=0D
+=0D
+/**=0D
+ Standard DXE driver or UEFI application entry point for unit test execut=
ion from DXE or UEFI Shell.=0D
+ Initialize the unit test framework, suite, and unit tests for the EfiMpS=
erviceProtocol and run the unit test.=0D
+=0D
+ @param[in] ImageHandle The firmware allocated handle for the EFI ima=
ge.=0D
+ @param[in] SystemTable A pointer to the EFI System Table.=0D
+=0D
+**/=0D
+EFI_STATUS=0D
+EFIAPI=0D
+DxeEntryPoint (=0D
+ IN EFI_HANDLE ImageHandle,=0D
+ IN EFI_SYSTEM_TABLE *SystemTable=0D
+ )=0D
+{=0D
+ EFI_STATUS Status;=0D
+ UNIT_TEST_FRAMEWORK_HANDLE Framework;=0D
+ MP_SERVICE_UT_CONTEXT Context;=0D
+=0D
+ Framework =3D NULL;=0D
+ Context.MpServices.Ppi =3D NULL;=0D
+ Context.CommonBuffer =3D NULL;=0D
+ Context.DisabledApNumber =3D NULL;=0D
+=0D
+ DEBUG ((DEBUG_INFO, "%a v%a\n", UNIT_TEST_NAME, UNIT_TEST_VERSION));=0D
+=0D
+ //=0D
+ // Start setting up the test framework for running the tests.=0D
+ //=0D
+ Status =3D InitUnitTestFramework (&Framework, UNIT_TEST_NAME, gEfiCaller=
BaseName, UNIT_TEST_VERSION);=0D
+ if (EFI_ERROR (Status)) {=0D
+ DEBUG ((DEBUG_ERROR, "Failed in InitUnitTestFramework. Status =3D %r\n=
", Status));=0D
+ goto EXIT;=0D
+ }=0D
+=0D
+ //=0D
+ // Create test suite and unit tests for both EdkiiPeiMpServices2Ppi and =
EfiMpServiceProtocol.=0D
+ //=0D
+ Status =3D AddCommonTestCase (Framework, &Context);=0D
+ if (EFI_ERROR (Status)) {=0D
+ DEBUG ((DEBUG_ERROR, "Failed in AddCommonTestCase. Status =3D %r\n", S=
tatus));=0D
+ goto EXIT;=0D
+ }=0D
+=0D
+ //=0D
+ // Execute the tests.=0D
+ //=0D
+ Status =3D RunAllTestSuites (Framework);=0D
+=0D
+EXIT:=0D
+ if (Framework !=3D NULL) {=0D
+ FreeUnitTestFramework (Framework);=0D
+ }=0D
+=0D
+ return Status;=0D
+}=0D
diff --git a/UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EfiMpService=
sUnitTestCommom.c b/UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EfiMp=
ServicesUnitTestCommom.c
new file mode 100644
index 0000000000..1d3f2ccd73
--- /dev/null
+++ b/UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EfiMpServicesUnitTe=
stCommom.c
@@ -0,0 +1,1741 @@
+/** @file=0D
+ Common code to test EdkiiPeiMpServices2Ppi and EfiMpServiceProtocol.=0D
+=0D
+ Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>=0D
+=0D
+ SPDX-License-Identifier: BSD-2-Clause-Patent=0D
+=0D
+**/=0D
+=0D
+#include "EfiMpServicesUnitTestCommom.h"=0D
+=0D
+/**=0D
+ Prep routine for Unit test function.=0D
+ To save the ProcessorNumber of disabled AP and temporarily enable it.=0D
+=0D
+ @param[in] Context Context pointer for this test.=0D
+=0D
+ @retval UNIT_TEST_PASSED Prep routine runs successful.=0D
+ @retval UNIT_TEST_ERROR_TEST_FAILED Prep routine runs unsuccessful.=0D
+**/=0D
+UNIT_TEST_STATUS=0D
+InitUTContext (=0D
+ IN UNIT_TEST_CONTEXT Context=0D
+ )=0D
+{=0D
+ EFI_STATUS Status;=0D
+ UINTN NumberOfProcessors;=0D
+ UINTN NumberOfEnabledProcessors;=0D
+ UINTN NumberOfDisabledAPs;=0D
+ UINTN IndexOfDisabledAPs;=0D
+ UINTN BspNumber;=0D
+ UINTN ProcessorNumber;=0D
+ EFI_PROCESSOR_INFORMATION ProcessorInfoBuffer;=0D
+ MP_SERVICE_UT_CONTEXT *LocalContext;=0D
+=0D
+ LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Context;=0D
+=0D
+ if (LocalContext->MpServices.Ppi !=3D NULL) {=0D
+ return UNIT_TEST_PASSED;=0D
+ }=0D
+=0D
+ Status =3D MpServicesUnitTestGetMpServices (&LocalContext->MpServices);=
=0D
+ UT_ASSERT_NOT_EFI_ERROR (Status);=0D
+=0D
+ Status =3D MpServicesUnitTestWhoAmI (LocalContext->MpServices, &BspNumbe=
r);=0D
+ UT_ASSERT_NOT_EFI_ERROR (Status);=0D
+ DEBUG ((DEBUG_INFO, "%a: BspNumber =3D 0x%x\n", __FUNCTION__, BspNumber)=
);=0D
+=0D
+ Status =3D MpServicesUnitTestGetNumberOfProcessors (=0D
+ LocalContext->MpServices,=0D
+ &NumberOfProcessors,=0D
+ &NumberOfEnabledProcessors=0D
+ );=0D
+ UT_ASSERT_NOT_EFI_ERROR (Status);=0D
+ DEBUG ((DEBUG_INFO, "%a: NumberOfProcessors =3D 0x%x, NumberOfEnabledPro=
cessors =3D 0x%x\n",=0D
+ __FUNCTION__, NumberOfProcessors, NumberOfEnabledProcessors));=0D
+=0D
+ LocalContext->BspNumber =3D BspNumber;=0D
+ LocalContext->NumberOfProcessors =3D NumberOfProcessors;=0D
+ LocalContext->NumberOfEnabledProcessors =3D NumberOfEnabledProcessors;=0D
+=0D
+ LocalContext->CommonBuffer =3D AllocatePages (EFI_SIZE_TO_PAGES (NumberO=
fProcessors * sizeof (*LocalContext->CommonBuffer)));=0D
+ UT_ASSERT_NOT_NULL (LocalContext->CommonBuffer);=0D
+=0D
+ NumberOfDisabledAPs =3D NumberOfProcessors - NumberOfEnabledProcessors;=
=0D
+ if (NumberOfDisabledAPs > 0 && LocalContext->DisabledApNumber =3D=3D NUL=
L) {=0D
+ LocalContext->DisabledApNumber =3D AllocatePages (EFI_SIZE_TO_PAGES (N=
umberOfDisabledAPs * sizeof (*LocalContext->DisabledApNumber)));=0D
+ UT_ASSERT_NOT_NULL (LocalContext->DisabledApNumber);=0D
+ ZeroMem (LocalContext->DisabledApNumber, NumberOfDisabledAPs * sizeof =
(*LocalContext->DisabledApNumber));=0D
+=0D
+ for (ProcessorNumber =3D 0, IndexOfDisabledAPs =3D 0; ProcessorNumber =
< LocalContext->NumberOfProcessors; ProcessorNumber++) {=0D
+ Status =3D MpServicesUnitTestGetProcessorInfo (=0D
+ LocalContext->MpServices,=0D
+ ProcessorNumber,=0D
+ &ProcessorInfoBuffer=0D
+ );=0D
+ UT_ASSERT_NOT_EFI_ERROR (Status);=0D
+=0D
+ if (!(ProcessorInfoBuffer.StatusFlag & PROCESSOR_ENABLED_BIT)) {=0D
+ //=0D
+ // Save ProcessorNumber of disabled AP.=0D
+ //=0D
+ LocalContext->DisabledApNumber[IndexOfDisabledAPs] =3D ProcessorNu=
mber;=0D
+ IndexOfDisabledAPs++;=0D
+=0D
+ DEBUG ((DEBUG_INFO, "%a: AP(0x%x) is disabled and temporarily enab=
le it.\n", __FUNCTION__, ProcessorNumber));=0D
+ Status =3D MpServicesUnitTestEnableDisableAP (=0D
+ LocalContext->MpServices,=0D
+ ProcessorNumber,=0D
+ TRUE,=0D
+ NULL=0D
+ );=0D
+ UT_ASSERT_NOT_EFI_ERROR (Status);=0D
+ }=0D
+ }=0D
+=0D
+ UT_ASSERT_TRUE (IndexOfDisabledAPs =3D=3D NumberOfDisabledAPs);=0D
+ }=0D
+=0D
+ return UNIT_TEST_PASSED;=0D
+}=0D
+=0D
+/**=0D
+ Cleanup routine for Unit test function.=0D
+ If any processor is disabled unexpectedly then reenable it.=0D
+=0D
+ @param[in] Context Context pointer for this test.=0D
+=0D
+ @retval UNIT_TEST_PASSED Cleanup routine runs successful.=0D
+ @retval UNIT_TEST_ERROR_TEST_FAILED Cleanup routine runs unsuccessful.=
=0D
+**/=0D
+UNIT_TEST_STATUS=0D
+CheckUTContext (=0D
+ IN UNIT_TEST_CONTEXT Context=0D
+ )=0D
+{=0D
+ EFI_STATUS Status;=0D
+ UINTN NumberOfProcessors;=0D
+ UINTN NumberOfEnabledProcessors;=0D
+ UINTN BspNumber;=0D
+ UINTN ProcessorNumber;=0D
+ EFI_PROCESSOR_INFORMATION ProcessorInfoBuffer;=0D
+ MP_SERVICE_UT_CONTEXT *LocalContext;=0D
+=0D
+ LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Context;=0D
+=0D
+ UT_ASSERT_NOT_NULL (LocalContext->MpServices.Ppi);=0D
+=0D
+ Status =3D MpServicesUnitTestWhoAmI (LocalContext->MpServices, &BspNumbe=
r);=0D
+ UT_ASSERT_NOT_EFI_ERROR (Status);=0D
+=0D
+ if (BspNumber !=3D LocalContext->BspNumber) {=0D
+ LocalContext->BspNumber =3D BspNumber;=0D
+ DEBUG ((DEBUG_INFO, "%a: New BspNumber =3D 0x%x\n", __FUNCTION__, BspN=
umber));=0D
+ }=0D
+ UT_ASSERT_TRUE (BspNumber =3D=3D LocalContext->BspNumber);=0D
+=0D
+ Status =3D MpServicesUnitTestGetNumberOfProcessors (=0D
+ LocalContext->MpServices,=0D
+ &NumberOfProcessors,=0D
+ &NumberOfEnabledProcessors=0D
+ );=0D
+ UT_ASSERT_NOT_EFI_ERROR (Status);=0D
+=0D
+ if (NumberOfProcessors !=3D LocalContext->NumberOfProcessors) {=0D
+ LocalContext->NumberOfProcessors =3D NumberOfProcessors;=0D
+ DEBUG ((DEBUG_INFO, "%a: New NumberOfProcessors =3D 0x%x\n", __FUNCTIO=
N__, NumberOfProcessors));=0D
+ }=0D
+=0D
+ if (NumberOfEnabledProcessors !=3D LocalContext->NumberOfProcessors) {=0D
+ DEBUG ((DEBUG_INFO, "%a: New NumberOfEnabledProcessors =3D 0x%x\n", __=
FUNCTION__, NumberOfEnabledProcessors));=0D
+=0D
+ for (ProcessorNumber =3D 0; ProcessorNumber < LocalContext->NumberOfPr=
ocessors; ProcessorNumber++) {=0D
+ Status =3D MpServicesUnitTestGetProcessorInfo (=0D
+ LocalContext->MpServices,=0D
+ ProcessorNumber,=0D
+ &ProcessorInfoBuffer=0D
+ );=0D
+ UT_ASSERT_NOT_EFI_ERROR (Status);=0D
+=0D
+ if (!(ProcessorInfoBuffer.StatusFlag & PROCESSOR_ENABLED_BIT)) {=0D
+ DEBUG ((DEBUG_INFO, "%a: AP(0x%x) is disabled unexpectedly and ree=
nable it.\n", __FUNCTION__, ProcessorNumber));=0D
+ Status =3D MpServicesUnitTestEnableDisableAP (=0D
+ LocalContext->MpServices,=0D
+ ProcessorNumber,=0D
+ TRUE,=0D
+ NULL=0D
+ );=0D
+ UT_ASSERT_NOT_EFI_ERROR (Status);=0D
+ }=0D
+ }=0D
+ }=0D
+=0D
+ return UNIT_TEST_PASSED;=0D
+}=0D
+=0D
+/**=0D
+ Cleanup routine for Unit test function.=0D
+ It will be called by the last "AddTestCase" to restore AP state and free=
pointer.=0D
+=0D
+ @param[in] Context Context pointer for this test.=0D
+=0D
+ @retval UNIT_TEST_PASSED Cleanup routine runs successful.=0D
+ @retval UNIT_TEST_ERROR_TEST_FAILED Cleanup routine runs unsuccessful.=
=0D
+**/=0D
+UNIT_TEST_STATUS=0D
+FreeUTContext (=0D
+ IN UNIT_TEST_CONTEXT Context=0D
+ )=0D
+{=0D
+ EFI_STATUS Status;=0D
+ UINTN NumberOfDisabledAPs;=0D
+ UINTN IndexOfDisabledAPs;=0D
+ MP_SERVICE_UT_CONTEXT *LocalContext;=0D
+=0D
+ Status =3D CheckUTContext (Context);=0D
+ UT_ASSERT_NOT_EFI_ERROR (Status);=0D
+=0D
+ LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Context;=0D
+=0D
+ UT_ASSERT_NOT_NULL (LocalContext->MpServices.Ppi);=0D
+=0D
+ if (LocalContext->DisabledApNumber !=3D NULL) {=0D
+ NumberOfDisabledAPs =3D LocalContext->NumberOfProcessors - LocalContex=
t->NumberOfEnabledProcessors;=0D
+ for (IndexOfDisabledAPs =3D 0; IndexOfDisabledAPs < NumberOfDisabledAP=
s; IndexOfDisabledAPs++) {=0D
+ DEBUG ((DEBUG_INFO, "%a: Disable AP(0x%x) to restore its state.\n", =
__FUNCTION__,=0D
+ LocalContext->DisabledApNumber[IndexOfDisabledAPs]));=0D
+=0D
+ Status =3D MpServicesUnitTestEnableDisableAP (=0D
+ LocalContext->MpServices,=0D
+ LocalContext->DisabledApNumber[IndexOfDisabledAPs],=0D
+ FALSE,=0D
+ NULL=0D
+ );=0D
+ UT_ASSERT_NOT_EFI_ERROR (Status);=0D
+ }=0D
+=0D
+ FreePages (LocalContext->DisabledApNumber, EFI_SIZE_TO_PAGES (NumberOf=
DisabledAPs * sizeof (*LocalContext->DisabledApNumber)));=0D
+ }=0D
+=0D
+ if (LocalContext->CommonBuffer !=3D NULL) {=0D
+ FreePages (LocalContext->CommonBuffer, EFI_SIZE_TO_PAGES (LocalContext=
->NumberOfProcessors * sizeof (*LocalContext->CommonBuffer)));=0D
+ }=0D
+=0D
+ return UNIT_TEST_PASSED;=0D
+}=0D
+=0D
+/**=0D
+ Produce to store ProcessorNumber in the corresponding location of Common=
Buffer.=0D
+=0D
+ @param[in,out] Buffer The pointer to private data buffer.=0D
+**/=0D
+VOID=0D
+StoreCpuNumbers (=0D
+ IN OUT VOID *Buffer=0D
+ )=0D
+{=0D
+ EFI_STATUS Status;=0D
+ UINTN ProcessorNumber;=0D
+ MP_SERVICE_UT_CONTEXT *LocalContext;=0D
+=0D
+ LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Buffer;=0D
+=0D
+ Status =3D MpServicesUnitTestWhoAmI (LocalContext->MpServices, &Processo=
rNumber);=0D
+ ASSERT_EFI_ERROR (Status);=0D
+=0D
+ //=0D
+ // The layout of CommonBuffer (E.g. BspNumber =3D 2 and NumberOfProcesso=
rs =3D 6)=0D
+ // Index 00 01 02 03 04 05=0D
+ // Value 00 01 02 03 04 05=0D
+ //=0D
+ LocalContext->CommonBuffer[ProcessorNumber] =3D ProcessorNumber;=0D
+}=0D
+=0D
+/**=0D
+ Produce to store the ProcessorNumber of AP execution order in CommonBuff=
er.=0D
+=0D
+ @param[in,out] Buffer The pointer to private data buffer.=0D
+**/=0D
+VOID=0D
+StoreAPsExecutionOrder (=0D
+ IN OUT VOID *Buffer=0D
+ )=0D
+{=0D
+ EFI_STATUS Status;=0D
+ UINTN ProcessorNumber;=0D
+ UINTN *ApCounter;=0D
+ MP_SERVICE_UT_CONTEXT *LocalContext;=0D
+=0D
+ LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Buffer;=0D
+=0D
+ Status =3D MpServicesUnitTestWhoAmI (LocalContext->MpServices, &Processo=
rNumber);=0D
+ ASSERT_EFI_ERROR (Status);=0D
+=0D
+ //=0D
+ // The layout of CommonBuffer (E.g. BspNumber =3D 2 and NumberOfProcesso=
rs =3D 6)=0D
+ // Index 00 01 02 03 04 05=0D
+ // Value 00 01 03 04 05 ApCounter(5)=0D
+ //=0D
+ ApCounter =3D &(LocalContext->CommonBuffer[LocalContext->NumberOfProcess=
ors - 1]);=0D
+ LocalContext->CommonBuffer[*ApCounter] =3D ProcessorNumber;=0D
+ (*ApCounter) ++;=0D
+}=0D
+=0D
+/**=0D
+ Infinite loop procedure to be run on specified CPU.=0D
+=0D
+ @param[in,out] Buffer The pointer to private data buffer.=0D
+**/=0D
+VOID=0D
+InfiniteLoopProcedure (=0D
+ IN OUT VOID *Buffer=0D
+ )=0D
+{=0D
+ volatile BOOLEAN InfiniteLoop;=0D
+=0D
+ InfiniteLoop =3D TRUE;=0D
+=0D
+ while (InfiniteLoop);=0D
+}=0D
+=0D
+/**=0D
+ Empty procedure to be run on specified CPU.=0D
+=0D
+ @param[in,out] Buffer The pointer to private data buffer.=0D
+**/=0D
+VOID=0D
+EmptyProcedure (=0D
+ IN OUT VOID *Buffer=0D
+ )=0D
+{=0D
+=0D
+}=0D
+=0D
+/**=0D
+ Procedure to run MP service GetNumberOfProcessors on AP.=0D
+=0D
+ @param[in,out] Buffer The pointer to private data buffer.=0D
+**/=0D
+VOID=0D
+RunMpServiceGetNumberOfProcessorsOnAp (=0D
+ IN OUT VOID *Buffer=0D
+ )=0D
+{=0D
+ UINTN NumberOfProcessors;=0D
+ UINTN NumberOfEnabledProcessors;=0D
+ MP_SERVICE_UT_CONTEXT *LocalContext;=0D
+=0D
+ LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Buffer;=0D
+=0D
+ LocalContext->ApProcedureReturnStatus =3D MpServicesUnitTestGetNumberOfP=
rocessors (=0D
+ LocalContext->MpServices,=0D
+ &NumberOfProcessors,=0D
+ &NumberOfEnabledProcessors=0D
+ );=0D
+}=0D
+=0D
+/**=0D
+ Procedure to run MP service GetProcessorInfo on AP.=0D
+=0D
+ @param[in,out] Buffer The pointer to private data buffer.=0D
+**/=0D
+VOID=0D
+RunMpServiceGetProcessorInfoOnAp (=0D
+ IN OUT VOID *Buffer=0D
+ )=0D
+{=0D
+ EFI_PROCESSOR_INFORMATION ProcessorInfoBuffer;=0D
+ MP_SERVICE_UT_CONTEXT *LocalContext;=0D
+=0D
+ LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Buffer;=0D
+=0D
+ LocalContext->ApProcedureReturnStatus =3D MpServicesUnitTestGetProcessor=
Info (=0D
+ LocalContext->MpServices,=0D
+ LocalContext->ApNumber,=0D
+ &ProcessorInfoBuffer=0D
+ );=0D
+}=0D
+=0D
+/**=0D
+ Procedure to run MP service EnableDisableAP on AP.=0D
+=0D
+ @param[in,out] Buffer The pointer to private data buffer.=0D
+**/=0D
+VOID=0D
+RunMpServiceEnableDisableAPOnAp (=0D
+ IN OUT VOID *Buffer=0D
+ )=0D
+{=0D
+ MP_SERVICE_UT_CONTEXT *LocalContext;=0D
+=0D
+ LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Buffer;=0D
+=0D
+ LocalContext->ApProcedureReturnStatus =3D MpServicesUnitTestEnableDisabl=
eAP (=0D
+ LocalContext->MpServices,=0D
+ LocalContext->ApNumber,=0D
+ FALSE,=0D
+ NULL=0D
+ );=0D
+}=0D
+=0D
+/**=0D
+ Procedure to run MP service StartupThisAP on AP.=0D
+=0D
+ @param[in,out] Buffer The pointer to private data buffer.=0D
+**/=0D
+VOID=0D
+RunMpServiceStartupThisAPOnAp (=0D
+ IN OUT VOID *Buffer=0D
+ )=0D
+{=0D
+ MP_SERVICE_UT_CONTEXT *LocalContext;=0D
+=0D
+ LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Buffer;=0D
+=0D
+ LocalContext->ApProcedureReturnStatus =3D MpServicesUnitTestStartupThisA=
P (=0D
+ LocalContext->MpServices,=0D
+ (EFI_AP_PROCEDURE) EmptyProcedur=
e,=0D
+ LocalContext->ApNumber,=0D
+ 0,=0D
+ NULL=0D
+ );=0D
+}=0D
+=0D
+/**=0D
+ Procedure to run MP service StartupAllAPs on AP.=0D
+=0D
+ @param[in,out] Buffer The pointer to private data buffer.=0D
+**/=0D
+VOID=0D
+RunMpServiceStartupAllAPsOnAp (=0D
+ IN OUT VOID *Buffer=0D
+ )=0D
+{=0D
+ MP_SERVICE_UT_CONTEXT *LocalContext;=0D
+=0D
+ LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Buffer;=0D
+=0D
+ LocalContext->ApProcedureReturnStatus =3D MpServicesUnitTestStartupAllAP=
s (=0D
+ LocalContext->MpServices,=0D
+ (EFI_AP_PROCEDURE) EmptyProcedur=
e,=0D
+ FALSE,=0D
+ 0,=0D
+ NULL=0D
+ );=0D
+}=0D
+=0D
+/**=0D
+ Procedure to run MP service SwitchBSP on AP.=0D
+=0D
+ @param[in,out] Buffer The pointer to private data buffer.=0D
+**/=0D
+VOID=0D
+RunMpServiceSwitchBSPOnAp (=0D
+ IN OUT VOID *Buffer=0D
+ )=0D
+{=0D
+ MP_SERVICE_UT_CONTEXT *LocalContext;=0D
+=0D
+ LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Buffer;=0D
+=0D
+ LocalContext->ApProcedureReturnStatus =3D MpServicesUnitTestSwitchBSP (=
=0D
+ LocalContext->MpServices,=0D
+ LocalContext->ApNumber,=0D
+ TRUE=0D
+ );=0D
+}=0D
+=0D
+/**=0D
+ Unit test of MP service WhoAmI.=0D
+ The range of ProcessorNumber should be from 0 to NumberOfCPUs minus 1.=0D
+ The ProcessorNumbers of all CPUs are unique.=0D
+=0D
+ @param[in] Context Context pointer for this test.=0D
+=0D
+ @retval UNIT_TEST_PASSED The Unit test has completed and th=
e test=0D
+ case was successful.=0D
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.=
=0D
+**/=0D
+UNIT_TEST_STATUS=0D
+TestWhoAmI1 (=0D
+ IN UNIT_TEST_CONTEXT Context=0D
+ )=0D
+{=0D
+ EFI_STATUS Status;=0D
+ UINTN ProcessorNumber;=0D
+ UINTN ProcessorIndex;=0D
+ MP_SERVICE_UT_CONTEXT *LocalContext;=0D
+=0D
+ LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Context;=0D
+=0D
+ Status =3D MpServicesUnitTestWhoAmI (=0D
+ LocalContext->MpServices,=0D
+ &ProcessorNumber=0D
+ );=0D
+ UT_ASSERT_NOT_EFI_ERROR (Status);=0D
+ UT_ASSERT_TRUE (ProcessorNumber < LocalContext->NumberOfProcessors);=0D
+=0D
+ SetMem (LocalContext->CommonBuffer, LocalContext->NumberOfProcessors * s=
izeof (*LocalContext->CommonBuffer), 0xFF);=0D
+ LocalContext->CommonBuffer[ProcessorNumber] =3D ProcessorNumber;=0D
+=0D
+ Status =3D MpServicesUnitTestStartupAllAPs (=0D
+ LocalContext->MpServices,=0D
+ (EFI_AP_PROCEDURE) StoreCpuNumbers,=0D
+ FALSE,=0D
+ 0,=0D
+ (VOID *) LocalContext=0D
+ );=0D
+ UT_ASSERT_NOT_EFI_ERROR (Status);=0D
+=0D
+ //=0D
+ // The layout of CommonBuffer (E.g. BspNumber =3D 2 and NumberOfProcesso=
rs =3D 6)=0D
+ // Index 00 01 02 03 04 05=0D
+ // Value 00 01 02 03 04 05=0D
+ //=0D
+ for (ProcessorIndex =3D 0; ProcessorIndex < LocalContext->NumberOfProces=
sors; ProcessorIndex++) {=0D
+ UT_ASSERT_TRUE (LocalContext->CommonBuffer[ProcessorIndex] =3D=3D Proc=
essorIndex);=0D
+ }=0D
+=0D
+ return UNIT_TEST_PASSED;=0D
+}=0D
+=0D
+/**=0D
+ Unit test of MP service GetNumberOfProcessors.=0D
+ NumberOfProcessors should be greater that 0 and not less than NumberOfEn=
abledProcessors.=0D
+=0D
+ @param[in] Context Context pointer for this test.=0D
+=0D
+ @retval UNIT_TEST_PASSED The Unit test has completed and th=
e test=0D
+ case was successful.=0D
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.=
=0D
+**/=0D
+UNIT_TEST_STATUS=0D
+TestGetNumberOfProcessors1 (=0D
+ IN UNIT_TEST_CONTEXT Context=0D
+ )=0D
+{=0D
+ EFI_STATUS Status;=0D
+ UINTN NumberOfProcessors;=0D
+ UINTN NumberOfEnabledProcessors;=0D
+ MP_SERVICE_UT_CONTEXT *LocalContext;=0D
+=0D
+ LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Context;=0D
+=0D
+ Status =3D MpServicesUnitTestGetNumberOfProcessors (=0D
+ LocalContext->MpServices,=0D
+ &NumberOfProcessors,=0D
+ &NumberOfEnabledProcessors=0D
+ );=0D
+ UT_ASSERT_NOT_EFI_ERROR (Status);=0D
+ UT_ASSERT_TRUE (NumberOfProcessors > 0 && NumberOfProcessors >=3D Number=
OfEnabledProcessors);=0D
+=0D
+ return UNIT_TEST_PASSED;=0D
+}=0D
+=0D
+/**=0D
+ Unit test of MP service GetNumberOfProcessors.=0D
+ When this service is called from an AP, the return status should be EFI_=
DEVICE_ERROR.=0D
+=0D
+ @param[in] Context Context pointer for this test.=0D
+=0D
+ @retval UNIT_TEST_PASSED The Unit test has completed and th=
e test=0D
+ case was successful.=0D
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.=
=0D
+**/=0D
+UNIT_TEST_STATUS=0D
+TestGetNumberOfProcessors2 (=0D
+ IN UNIT_TEST_CONTEXT Context=0D
+ )=0D
+{=0D
+ EFI_STATUS Status;=0D
+ UINTN ApNumber;=0D
+ MP_SERVICE_UT_CONTEXT *LocalContext;=0D
+=0D
+ LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Context;=0D
+=0D
+ for (ApNumber =3D 0; ApNumber < LocalContext->NumberOfProcessors; ApNumb=
er++) {=0D
+ LocalContext->ApNumber =3D ApNumber;=0D
+ Status =3D MpServicesUnitTestStartupThisAP (=0D
+ LocalContext->MpServices,=0D
+ (EFI_AP_PROCEDURE) RunMpServiceGetNumberOfProcessorsOnAp,=0D
+ ApNumber,=0D
+ 0,=0D
+ (VOID *) LocalContext=0D
+ );=0D
+=0D
+ if (ApNumber =3D=3D LocalContext->BspNumber) {=0D
+ UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER);=0D
+ } else {=0D
+ UT_ASSERT_NOT_EFI_ERROR (Status);=0D
+ UT_ASSERT_STATUS_EQUAL (LocalContext->ApProcedureReturnStatus, EFI_D=
EVICE_ERROR);=0D
+ }=0D
+ }=0D
+=0D
+ return UNIT_TEST_PASSED;=0D
+}=0D
+=0D
+/**=0D
+ Unit test of MP service GetNumberOfProcessors.=0D
+ Call EnableDisableAP() to change the number of enabled AP.=0D
+=0D
+ @param[in] Context Context pointer for this test.=0D
+=0D
+ @retval UNIT_TEST_PASSED The Unit test has completed and th=
e test=0D
+ case was successful.=0D
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.=
=0D
+**/=0D
+UNIT_TEST_STATUS=0D
+TestGetNumberOfProcessors3 (=0D
+ IN UNIT_TEST_CONTEXT Context=0D
+ )=0D
+{=0D
+ EFI_STATUS Status;=0D
+ UINTN ApNumber;=0D
+ UINTN NumberOfProcessors;=0D
+ UINTN NumberOfEnabledProcessors;=0D
+ MP_SERVICE_UT_CONTEXT *LocalContext;=0D
+=0D
+ LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Context;=0D
+=0D
+ for (ApNumber =3D 0; ApNumber < LocalContext->NumberOfProcessors; ApNumb=
er++) {=0D
+ Status =3D MpServicesUnitTestEnableDisableAP (=0D
+ LocalContext->MpServices,=0D
+ ApNumber,=0D
+ FALSE,=0D
+ NULL=0D
+ );=0D
+=0D
+ if (ApNumber =3D=3D LocalContext->BspNumber) {=0D
+ UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER);=0D
+ } else {=0D
+ UT_ASSERT_NOT_EFI_ERROR (Status);=0D
+=0D
+ Status =3D MpServicesUnitTestGetNumberOfProcessors (=0D
+ LocalContext->MpServices,=0D
+ &NumberOfProcessors,=0D
+ &NumberOfEnabledProcessors=0D
+ );=0D
+ UT_ASSERT_NOT_EFI_ERROR (Status);=0D
+ UT_ASSERT_TRUE (NumberOfProcessors =3D=3D LocalContext->NumberOfProc=
essors);=0D
+=0D
+ if (ApNumber < LocalContext->BspNumber) {=0D
+ UT_ASSERT_TRUE (NumberOfEnabledProcessors =3D=3D LocalContext->Num=
berOfProcessors - (ApNumber + 1));=0D
+ } else {=0D
+ UT_ASSERT_TRUE (NumberOfEnabledProcessors =3D=3D LocalContext->Num=
berOfProcessors - ApNumber);=0D
+ }=0D
+ }=0D
+ }=0D
+=0D
+ for (ApNumber =3D 0; ApNumber < LocalContext->NumberOfProcessors; ApNumb=
er++) {=0D
+ Status =3D MpServicesUnitTestEnableDisableAP (=0D
+ LocalContext->MpServices,=0D
+ ApNumber,=0D
+ TRUE,=0D
+ NULL=0D
+ );=0D
+=0D
+ if (ApNumber =3D=3D LocalContext->BspNumber) {=0D
+ UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER);=0D
+ } else {=0D
+ UT_ASSERT_NOT_EFI_ERROR (Status);=0D
+=0D
+ Status =3D MpServicesUnitTestGetNumberOfProcessors (=0D
+ LocalContext->MpServices,=0D
+ &NumberOfProcessors,=0D
+ &NumberOfEnabledProcessors=0D
+ );=0D
+ UT_ASSERT_NOT_EFI_ERROR (Status);=0D
+ UT_ASSERT_TRUE (NumberOfProcessors =3D=3D LocalContext->NumberOfProc=
essors);=0D
+=0D
+ if (ApNumber < LocalContext->BspNumber) {=0D
+ UT_ASSERT_TRUE (NumberOfEnabledProcessors =3D=3D ApNumber + 2);=0D
+ } else {=0D
+ UT_ASSERT_TRUE (NumberOfEnabledProcessors =3D=3D ApNumber + 1);=0D
+ }=0D
+ }=0D
+ }=0D
+=0D
+ return UNIT_TEST_PASSED;=0D
+}=0D
+=0D
+/**=0D
+ Unit test of MP service GetProcessorInfo.=0D
+ When all the parameters are valid, all reserved bits of StatusFlag in Pr=
ocessorInfoBuffer should be set to zero.=0D
+ When all the parameters are valid, the StatusFlag should not have an inv=
alid value (The BSP can never be in the disabled state.).=0D
+ When called with nonexistent processor handle, the return status should =
be EFI_NOT_FOUND.=0D
+=0D
+ @param[in] Context Context pointer for this test.=0D
+=0D
+ @retval UNIT_TEST_PASSED The Unit test has completed and th=
e test=0D
+ case was successful.=0D
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.=
=0D
+**/=0D
+UNIT_TEST_STATUS=0D
+TestGetProcessorInfo1 (=0D
+ IN UNIT_TEST_CONTEXT Context=0D
+ )=0D
+{=0D
+ EFI_STATUS Status;=0D
+ UINTN ProcessorNumber;=0D
+ EFI_PROCESSOR_INFORMATION ProcessorInfoBuffer;=0D
+ MP_SERVICE_UT_CONTEXT *LocalContext;=0D
+=0D
+ LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Context;=0D
+=0D
+ for (ProcessorNumber =3D 0; ProcessorNumber <=3D LocalContext->NumberOfP=
rocessors; ProcessorNumber++) {=0D
+ Status =3D MpServicesUnitTestGetProcessorInfo (=0D
+ LocalContext->MpServices,=0D
+ ProcessorNumber,=0D
+ &ProcessorInfoBuffer=0D
+ );=0D
+=0D
+ if (ProcessorNumber =3D=3D LocalContext->NumberOfProcessors) {=0D
+ UT_ASSERT_STATUS_EQUAL (Status, EFI_NOT_FOUND);=0D
+ } else {=0D
+ UT_ASSERT_NOT_EFI_ERROR (Status);=0D
+ UT_ASSERT_TRUE (!(ProcessorInfoBuffer.StatusFlag & (UINT32)~(PROCESS=
OR_AS_BSP_BIT|PROCESSOR_ENABLED_BIT|PROCESSOR_HEALTH_STATUS_BIT)));=0D
+=0D
+ if (ProcessorNumber =3D=3D LocalContext->BspNumber) {=0D
+ UT_ASSERT_TRUE ((ProcessorInfoBuffer.StatusFlag & PROCESSOR_AS_BSP=
_BIT) && (ProcessorInfoBuffer.StatusFlag & PROCESSOR_ENABLED_BIT));=0D
+ } else {=0D
+ UT_ASSERT_TRUE (!(ProcessorInfoBuffer.StatusFlag & PROCESSOR_AS_BS=
P_BIT));=0D
+ }=0D
+ }=0D
+ }=0D
+=0D
+ return UNIT_TEST_PASSED;=0D
+}=0D
+=0D
+/**=0D
+ Unit test of MP service GetProcessorInfo.=0D
+ When this service is called from an AP, the return status should be EFI_=
DEVICE_ERROR.=0D
+=0D
+ @param[in] Context Context pointer for this test.=0D
+=0D
+ @retval UNIT_TEST_PASSED The Unit test has completed and th=
e test=0D
+ case was successful.=0D
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.=
=0D
+**/=0D
+UNIT_TEST_STATUS=0D
+TestGetProcessorInfo2 (=0D
+ IN UNIT_TEST_CONTEXT Context=0D
+ )=0D
+{=0D
+ EFI_STATUS Status;=0D
+ UINTN ApNumber;=0D
+ MP_SERVICE_UT_CONTEXT *LocalContext;=0D
+=0D
+ LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Context;=0D
+=0D
+ for (ApNumber =3D 0; ApNumber < LocalContext->NumberOfProcessors; ApNumb=
er++) {=0D
+ LocalContext->ApNumber =3D ApNumber;=0D
+ Status =3D MpServicesUnitTestStartupThisAP (=0D
+ LocalContext->MpServices,=0D
+ (EFI_AP_PROCEDURE) RunMpServiceGetProcessorInfoOnAp,=0D
+ ApNumber,=0D
+ 0,=0D
+ (VOID *) LocalContext=0D
+ );=0D
+=0D
+ if (ApNumber =3D=3D LocalContext->BspNumber) {=0D
+ UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER);=0D
+ } else {=0D
+ UT_ASSERT_NOT_EFI_ERROR (Status);=0D
+ UT_ASSERT_STATUS_EQUAL (LocalContext->ApProcedureReturnStatus, EFI_D=
EVICE_ERROR);=0D
+ }=0D
+ }=0D
+=0D
+ return UNIT_TEST_PASSED;=0D
+}=0D
+=0D
+/**=0D
+ Unit test of MP service EnableDisableAP.=0D
+ When called with BSP number, the return status should be EFI_INVALID_PAR=
AMETER.=0D
+ When called with a nonexistent processor handle, the return status shoul=
d be EFI_NOT_FOUND.=0D
+ The AP should be really Enable/Disabled.=0D
+=0D
+ @param[in] Context Context pointer for this test.=0D
+=0D
+ @retval UNIT_TEST_PASSED The Unit test has completed and th=
e test=0D
+ case was successful.=0D
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.=
=0D
+**/=0D
+UNIT_TEST_STATUS=0D
+TestEnableDisableAP1 (=0D
+ IN UNIT_TEST_CONTEXT Context=0D
+ )=0D
+{=0D
+ EFI_STATUS Status;=0D
+ UINTN ApNumber;=0D
+ MP_SERVICE_UT_CONTEXT *LocalContext;=0D
+=0D
+ LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Context;=0D
+=0D
+ for (ApNumber =3D 0; ApNumber <=3D LocalContext->NumberOfProcessors; ApN=
umber++) {=0D
+ Status =3D MpServicesUnitTestEnableDisableAP (=0D
+ LocalContext->MpServices,=0D
+ ApNumber,=0D
+ FALSE,=0D
+ NULL=0D
+ );=0D
+=0D
+ if (ApNumber =3D=3D LocalContext->BspNumber) {=0D
+ UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER);=0D
+ } else if (ApNumber =3D=3D LocalContext->NumberOfProcessors) {=0D
+ UT_ASSERT_STATUS_EQUAL (Status, EFI_NOT_FOUND);=0D
+ } else {=0D
+ UT_ASSERT_NOT_EFI_ERROR (Status);=0D
+=0D
+ Status =3D MpServicesUnitTestStartupThisAP (=0D
+ LocalContext->MpServices,=0D
+ (EFI_AP_PROCEDURE) EmptyProcedure,=0D
+ ApNumber,=0D
+ 0,=0D
+ NULL=0D
+ );=0D
+ UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER);=0D
+=0D
+ Status =3D MpServicesUnitTestEnableDisableAP (=0D
+ LocalContext->MpServices,=0D
+ ApNumber,=0D
+ TRUE,=0D
+ NULL=0D
+ );=0D
+ UT_ASSERT_NOT_EFI_ERROR (Status);=0D
+=0D
+ Status =3D MpServicesUnitTestStartupThisAP (=0D
+ LocalContext->MpServices,=0D
+ (EFI_AP_PROCEDURE) EmptyProcedure,=0D
+ ApNumber,=0D
+ 0,=0D
+ NULL=0D
+ );=0D
+ UT_ASSERT_NOT_EFI_ERROR (Status);=0D
+ }=0D
+ }=0D
+=0D
+ return UNIT_TEST_PASSED;=0D
+}=0D
+=0D
+/**=0D
+ Unit test of MP service EnableDisableAP.=0D
+ When run this procedure on AP, the return status should be EFI_DEVICE_ER=
ROR.=0D
+=0D
+ @param[in] Context Context pointer for this test.=0D
+=0D
+ @retval UNIT_TEST_PASSED The Unit test has completed and th=
e test=0D
+ case was successful.=0D
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.=
=0D
+**/=0D
+UNIT_TEST_STATUS=0D
+TestEnableDisableAP2 (=0D
+ IN UNIT_TEST_CONTEXT Context=0D
+ )=0D
+{=0D
+ EFI_STATUS Status;=0D
+ UINTN ApNumber;=0D
+ MP_SERVICE_UT_CONTEXT *LocalContext;=0D
+=0D
+ LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Context;=0D
+=0D
+ for (ApNumber =3D 0; ApNumber < LocalContext->NumberOfProcessors; ApNumb=
er++) {=0D
+ LocalContext->ApNumber =3D ApNumber;=0D
+ Status =3D MpServicesUnitTestStartupThisAP (=0D
+ LocalContext->MpServices,=0D
+ (EFI_AP_PROCEDURE) RunMpServiceEnableDisableAPOnAp,=0D
+ ApNumber,=0D
+ 0,=0D
+ (VOID *) LocalContext=0D
+ );=0D
+=0D
+ if (ApNumber =3D=3D LocalContext->BspNumber) {=0D
+ UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER);=0D
+ } else {=0D
+ UT_ASSERT_NOT_EFI_ERROR (Status);=0D
+ UT_ASSERT_STATUS_EQUAL (LocalContext->ApProcedureReturnStatus, EFI_D=
EVICE_ERROR);=0D
+ }=0D
+ }=0D
+=0D
+ return UNIT_TEST_PASSED;=0D
+}=0D
+=0D
+/**=0D
+ Unit test of MP service EnableDisableAP.=0D
+ When run this procedure on AP, the return status should be EFI_DEVICE_ER=
ROR.=0D
+=0D
+ @param[in] Context Context pointer for this test.=0D
+=0D
+ @retval UNIT_TEST_PASSED The Unit test has completed and th=
e test=0D
+ case was successful.=0D
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.=
=0D
+**/=0D
+UNIT_TEST_STATUS=0D
+TestEnableDisableAP3 (=0D
+ IN UNIT_TEST_CONTEXT Context=0D
+ )=0D
+{=0D
+ EFI_STATUS Status;=0D
+ UINTN ApNumber;=0D
+ EFI_PROCESSOR_INFORMATION ProcessorInfoBuffer;=0D
+ UINT32 OldHealthFlag;=0D
+ UINT32 NewHealthFlag;=0D
+ MP_SERVICE_UT_CONTEXT *LocalContext;=0D
+=0D
+ LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Context;=0D
+=0D
+ for (ApNumber =3D 0; ApNumber < LocalContext->NumberOfProcessors; ApNumb=
er++) {=0D
+ Status =3D MpServicesUnitTestGetProcessorInfo (=0D
+ LocalContext->MpServices,=0D
+ ApNumber,=0D
+ &ProcessorInfoBuffer=0D
+ );=0D
+ UT_ASSERT_NOT_EFI_ERROR (Status);=0D
+=0D
+ OldHealthFlag =3D ProcessorInfoBuffer.StatusFlag & PROCESSOR_HEALTH_ST=
ATUS_BIT;=0D
+ NewHealthFlag =3D OldHealthFlag ^ PROCESSOR_HEALTH_STATUS_BIT;=0D
+ Status =3D MpServicesUnitTestEnableDisableAP (=0D
+ LocalContext->MpServices,=0D
+ ApNumber,=0D
+ TRUE,=0D
+ &NewHealthFlag=0D
+ );=0D
+=0D
+ if (ApNumber =3D=3D LocalContext->BspNumber) {=0D
+ UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER);=0D
+ } else {=0D
+ UT_ASSERT_NOT_EFI_ERROR (Status);=0D
+=0D
+ Status =3D MpServicesUnitTestGetProcessorInfo (=0D
+ LocalContext->MpServices,=0D
+ ApNumber,=0D
+ &ProcessorInfoBuffer=0D
+ );=0D
+ UT_ASSERT_NOT_EFI_ERROR (Status);=0D
+ UT_ASSERT_TRUE ((ProcessorInfoBuffer.StatusFlag & PROCESSOR_HEALTH_S=
TATUS_BIT) =3D=3D NewHealthFlag);=0D
+=0D
+ Status =3D MpServicesUnitTestEnableDisableAP (=0D
+ LocalContext->MpServices,=0D
+ ApNumber,=0D
+ TRUE,=0D
+ &OldHealthFlag=0D
+ );=0D
+ UT_ASSERT_NOT_EFI_ERROR (Status);=0D
+ }=0D
+ }=0D
+=0D
+ return UNIT_TEST_PASSED;=0D
+}=0D
+=0D
+/**=0D
+ Unit test of MP service StartupThisAP.=0D
+ When called to startup a BSP, the return status should be EFI_INVALID_PA=
RAMETER.=0D
+ When called with a nonexistent processor handle, the return status shoul=
d be EFI_NOT_FOUND.=0D
+ The requested AP should execute the Procedure when called by StartupThis=
AP.=0D
+=0D
+ @param[in] Context Context pointer for this test.=0D
+=0D
+ @retval UNIT_TEST_PASSED The Unit test has completed and th=
e test=0D
+ case was successful.=0D
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.=
=0D
+**/=0D
+UNIT_TEST_STATUS=0D
+TestStartupThisAP1 (=0D
+ IN UNIT_TEST_CONTEXT Context=0D
+ )=0D
+{=0D
+ EFI_STATUS Status;=0D
+ UINTN ApNumber;=0D
+ UINTN ProcessorIndex;=0D
+ MP_SERVICE_UT_CONTEXT *LocalContext;=0D
+=0D
+ LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Context;=0D
+=0D
+ for (ApNumber =3D 0; ApNumber <=3D LocalContext->NumberOfProcessors; ApN=
umber++) {=0D
+ SetMem (LocalContext->CommonBuffer, LocalContext->NumberOfProcessors *=
sizeof (*LocalContext->CommonBuffer), 0xFF);=0D
+ Status =3D MpServicesUnitTestStartupThisAP (=0D
+ LocalContext->MpServices,=0D
+ (EFI_AP_PROCEDURE) StoreCpuNumbers,=0D
+ ApNumber,=0D
+ 0,=0D
+ (VOID *) LocalContext=0D
+ );=0D
+=0D
+ if (ApNumber =3D=3D LocalContext->BspNumber) {=0D
+ UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER);=0D
+ } else if (ApNumber =3D=3D LocalContext->NumberOfProcessors) {=0D
+ UT_ASSERT_STATUS_EQUAL (Status, EFI_NOT_FOUND);=0D
+ } else {=0D
+ UT_ASSERT_NOT_EFI_ERROR (Status);=0D
+=0D
+ for (ProcessorIndex =3D 0; ProcessorIndex < LocalContext->NumberOfPr=
ocessors; ProcessorIndex++) {=0D
+ UT_ASSERT_TRUE ((ProcessorIndex =3D=3D ApNumber) && LocalContext->=
CommonBuffer[ProcessorIndex] =3D=3D ProcessorIndex ||=0D
+ (ProcessorIndex !=3D ApNumber) && LocalContext->Co=
mmonBuffer[ProcessorIndex] =3D=3D (UINTN) ~0);=0D
+ }=0D
+ }=0D
+ }=0D
+=0D
+ return UNIT_TEST_PASSED;=0D
+}=0D
+=0D
+/**=0D
+ Unit test of MP service StartupThisAP.=0D
+ When this service is called from an AP, the return status should be EFI_=
DEVICE_ERROR.=0D
+=0D
+ @param[in] Context Context pointer for this test.=0D
+=0D
+ @retval UNIT_TEST_PASSED The Unit test has completed and th=
e test=0D
+ case was successful.=0D
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.=
=0D
+**/=0D
+UNIT_TEST_STATUS=0D
+TestStartupThisAP2 (=0D
+ IN UNIT_TEST_CONTEXT Context=0D
+ )=0D
+{=0D
+ EFI_STATUS Status;=0D
+ UINTN ApNumber;=0D
+ MP_SERVICE_UT_CONTEXT *LocalContext;=0D
+=0D
+ LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Context;=0D
+=0D
+ for (ApNumber =3D 0; ApNumber < LocalContext->NumberOfProcessors; ApNumb=
er++) {=0D
+ LocalContext->ApNumber =3D ApNumber;=0D
+ Status =3D MpServicesUnitTestStartupThisAP (=0D
+ LocalContext->MpServices,=0D
+ (EFI_AP_PROCEDURE) RunMpServiceStartupThisAPOnAp,=0D
+ ApNumber,=0D
+ 0,=0D
+ (VOID *) LocalContext=0D
+ );=0D
+=0D
+ if (ApNumber =3D=3D LocalContext->BspNumber) {=0D
+ UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER);=0D
+ } else {=0D
+ UT_ASSERT_NOT_EFI_ERROR (Status);=0D
+ UT_ASSERT_STATUS_EQUAL (LocalContext->ApProcedureReturnStatus, EFI_D=
EVICE_ERROR);=0D
+ }=0D
+ }=0D
+=0D
+ return UNIT_TEST_PASSED;=0D
+}=0D
+=0D
+/**=0D
+ Unit test of MP service StartupThisAP.=0D
+ When timeout expired before the requested AP has finished, the return st=
atus should be EFI_TIMEOUT.=0D
+=0D
+ @param[in] Context Context pointer for this test.=0D
+=0D
+ @retval UNIT_TEST_PASSED The Unit test has completed and th=
e test=0D
+ case was successful.=0D
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.=
=0D
+**/=0D
+UNIT_TEST_STATUS=0D
+TestStartupThisAP3 (=0D
+ IN UNIT_TEST_CONTEXT Context=0D
+ )=0D
+{=0D
+ EFI_STATUS Status;=0D
+ UINTN ApNumber;=0D
+ MP_SERVICE_UT_CONTEXT *LocalContext;=0D
+=0D
+ LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Context;=0D
+=0D
+ for (ApNumber =3D 0; ApNumber < LocalContext->NumberOfProcessors; ApNumb=
er++) {=0D
+ Status =3D MpServicesUnitTestStartupThisAP (=0D
+ LocalContext->MpServices,=0D
+ (EFI_AP_PROCEDURE) InfiniteLoopProcedure,=0D
+ ApNumber,=0D
+ RUN_PROCEDURE_TIMEOUT_VALUE,=0D
+ NULL=0D
+ );=0D
+=0D
+ if (ApNumber =3D=3D LocalContext->BspNumber) {=0D
+ UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER);=0D
+ } else {=0D
+ UT_ASSERT_STATUS_EQUAL (Status, EFI_TIMEOUT);=0D
+ }=0D
+ }=0D
+=0D
+ return UNIT_TEST_PASSED;=0D
+}=0D
+=0D
+/**=0D
+ Unit test of MP service StartupThisAP.=0D
+ When called with disabled AP, the return status should be EFI_INVALID_PA=
RAMETER.=0D
+=0D
+ @param[in] Context Context pointer for this test.=0D
+=0D
+ @retval UNIT_TEST_PASSED The Unit test has completed and th=
e test=0D
+ case was successful.=0D
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.=
=0D
+**/=0D
+UNIT_TEST_STATUS=0D
+TestStartupThisAP4 (=0D
+ IN UNIT_TEST_CONTEXT Context=0D
+ )=0D
+{=0D
+ EFI_STATUS Status;=0D
+ UINTN ApNumber;=0D
+ MP_SERVICE_UT_CONTEXT *LocalContext;=0D
+=0D
+ LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Context;=0D
+=0D
+ for (ApNumber =3D 0; ApNumber < LocalContext->NumberOfProcessors; ApNumb=
er++) {=0D
+ Status =3D MpServicesUnitTestEnableDisableAP (=0D
+ LocalContext->MpServices,=0D
+ ApNumber,=0D
+ FALSE,=0D
+ NULL=0D
+ );=0D
+=0D
+ if (ApNumber =3D=3D LocalContext->BspNumber) {=0D
+ UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER);=0D
+ } else {=0D
+ UT_ASSERT_NOT_EFI_ERROR (Status);=0D
+=0D
+ Status =3D MpServicesUnitTestStartupThisAP (=0D
+ LocalContext->MpServices,=0D
+ (EFI_AP_PROCEDURE) EmptyProcedure,=0D
+ ApNumber,=0D
+ 0,=0D
+ NULL=0D
+ );=0D
+ UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER);=0D
+=0D
+ Status =3D MpServicesUnitTestEnableDisableAP (=0D
+ LocalContext->MpServices,=0D
+ ApNumber,=0D
+ TRUE,=0D
+ NULL=0D
+ );=0D
+ UT_ASSERT_NOT_EFI_ERROR (Status);=0D
+=0D
+ Status =3D MpServicesUnitTestStartupThisAP (=0D
+ LocalContext->MpServices,=0D
+ (EFI_AP_PROCEDURE) EmptyProcedure,=0D
+ ApNumber,=0D
+ 0,=0D
+ NULL=0D
+ );=0D
+ UT_ASSERT_NOT_EFI_ERROR (Status);=0D
+ }=0D
+ }=0D
+=0D
+ return UNIT_TEST_PASSED;=0D
+}=0D
+=0D
+/**=0D
+ Unit test of MP service StartupAllAPs.=0D
+ All APs should execute the Procedure when called by StartupAllAPs.=0D
+=0D
+ @param[in] Context Context pointer for this test.=0D
+=0D
+ @retval UNIT_TEST_PASSED The Unit test has completed and th=
e test=0D
+ case was successful.=0D
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.=
=0D
+**/=0D
+UNIT_TEST_STATUS=0D
+TestStartupAllAPs1 (=0D
+ IN UNIT_TEST_CONTEXT Context=0D
+ )=0D
+{=0D
+ EFI_STATUS Status;=0D
+ UINTN ProcessorIndex;=0D
+ MP_SERVICE_UT_CONTEXT *LocalContext;=0D
+=0D
+ LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Context;=0D
+=0D
+ SetMem (LocalContext->CommonBuffer, LocalContext->NumberOfProcessors * s=
izeof (*LocalContext->CommonBuffer), 0xFF);=0D
+ Status =3D MpServicesUnitTestStartupAllAPs (=0D
+ LocalContext->MpServices,=0D
+ (EFI_AP_PROCEDURE) StoreCpuNumbers,=0D
+ FALSE,=0D
+ 0,=0D
+ (VOID *) LocalContext=0D
+ );=0D
+ UT_ASSERT_NOT_EFI_ERROR (Status);=0D
+=0D
+ for (ProcessorIndex =3D 0; ProcessorIndex < LocalContext->NumberOfProces=
sors; ProcessorIndex++) {=0D
+ UT_ASSERT_TRUE ((ProcessorIndex =3D=3D LocalContext->BspNumber) && Loc=
alContext->CommonBuffer[ProcessorIndex] =3D=3D (UINTN) ~0 ||=0D
+ (ProcessorIndex !=3D LocalContext->BspNumber) && Local=
Context->CommonBuffer[ProcessorIndex] =3D=3D ProcessorIndex);=0D
+ }=0D
+=0D
+ return UNIT_TEST_PASSED;=0D
+}=0D
+=0D
+/**=0D
+ Unit test of MP service StartupAllAPs.=0D
+ When called in single thread, the return status should be EFI_SUCCESS an=
d AP executes in ascending order=0D
+ of processor handle number.=0D
+=0D
+ @param[in] Context Context pointer for this test.=0D
+=0D
+ @retval UNIT_TEST_PASSED The Unit test has completed and th=
e test=0D
+ case was successful.=0D
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.=
=0D
+**/=0D
+UNIT_TEST_STATUS=0D
+TestStartupAllAPs2 (=0D
+ IN UNIT_TEST_CONTEXT Context=0D
+ )=0D
+{=0D
+ EFI_STATUS Status;=0D
+ UINTN ProcessorIndex;=0D
+ MP_SERVICE_UT_CONTEXT *LocalContext;=0D
+=0D
+ LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Context;=0D
+=0D
+ ZeroMem (LocalContext->CommonBuffer, LocalContext->NumberOfProcessors * =
sizeof (*LocalContext->CommonBuffer));=0D
+ Status =3D MpServicesUnitTestStartupAllAPs (=0D
+ LocalContext->MpServices,=0D
+ (EFI_AP_PROCEDURE) StoreAPsExecutionOrder,=0D
+ TRUE,=0D
+ 0,=0D
+ (VOID *) LocalContext=0D
+ );=0D
+ UT_ASSERT_NOT_EFI_ERROR (Status);=0D
+=0D
+ //=0D
+ // The layout of CommonBuffer (E.g. BspNumber =3D 2 and NumberOfProcesso=
rs =3D 6)=0D
+ // Index 00 01 02 03 04 05=0D
+ // Value 00 01 03 04 05 ApCounter(5)=0D
+ //=0D
+ for (ProcessorIndex =3D 0; ProcessorIndex < LocalContext->NumberOfProces=
sors - 2; ProcessorIndex++) {=0D
+ UT_ASSERT_TRUE (LocalContext->CommonBuffer[ProcessorIndex] < LocalCont=
ext->CommonBuffer[ProcessorIndex + 1]);=0D
+ }=0D
+ UT_ASSERT_EQUAL (LocalContext->CommonBuffer[LocalContext->NumberOfProces=
sors - 1], LocalContext->NumberOfProcessors - 1);=0D
+=0D
+ return UNIT_TEST_PASSED;=0D
+}=0D
+=0D
+/**=0D
+ Unit test of MP service StartupAllAPs.=0D
+ When this service is called from an AP, the return status should be EFI_=
DEVICE_ERROR.=0D
+=0D
+ @param[in] Context Context pointer for this test.=0D
+=0D
+ @retval UNIT_TEST_PASSED The Unit test has completed and th=
e test=0D
+ case was successful.=0D
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.=
=0D
+**/=0D
+UNIT_TEST_STATUS=0D
+TestStartupAllAPs3 (=0D
+ IN UNIT_TEST_CONTEXT Context=0D
+ )=0D
+{=0D
+ EFI_STATUS Status;=0D
+ UINTN ApNumber;=0D
+ MP_SERVICE_UT_CONTEXT *LocalContext;=0D
+=0D
+ LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Context;=0D
+=0D
+ for (ApNumber =3D 0; ApNumber < LocalContext->NumberOfProcessors; ApNumb=
er++) {=0D
+ LocalContext->ApNumber =3D ApNumber;=0D
+ Status =3D MpServicesUnitTestStartupThisAP (=0D
+ LocalContext->MpServices,=0D
+ (EFI_AP_PROCEDURE) RunMpServiceStartupAllAPsOnAp,=0D
+ ApNumber,=0D
+ 0,=0D
+ (VOID *) LocalContext=0D
+ );=0D
+=0D
+ if (ApNumber =3D=3D LocalContext->BspNumber) {=0D
+ UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER);=0D
+ } else {=0D
+ UT_ASSERT_NOT_EFI_ERROR (Status);=0D
+ UT_ASSERT_STATUS_EQUAL (LocalContext->ApProcedureReturnStatus, EFI_D=
EVICE_ERROR);=0D
+ }=0D
+ }=0D
+=0D
+ return UNIT_TEST_PASSED;=0D
+}=0D
+=0D
+/**=0D
+ Unit test of MP service StartupAllAPs.=0D
+ When called with all AP timeout, the return status should be EFI_TIMEOUT=
.=0D
+=0D
+ @param[in] Context Context pointer for this test.=0D
+=0D
+ @retval UNIT_TEST_PASSED The Unit test has completed and th=
e test=0D
+ case was successful.=0D
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.=
=0D
+**/=0D
+UNIT_TEST_STATUS=0D
+TestStartupAllAPs4 (=0D
+ IN UNIT_TEST_CONTEXT Context=0D
+ )=0D
+{=0D
+ EFI_STATUS Status;=0D
+ MP_SERVICE_UT_CONTEXT *LocalContext;=0D
+=0D
+ LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Context;=0D
+=0D
+ Status =3D MpServicesUnitTestStartupAllAPs (=0D
+ LocalContext->MpServices,=0D
+ (EFI_AP_PROCEDURE) InfiniteLoopProcedure,=0D
+ TRUE,=0D
+ RUN_PROCEDURE_TIMEOUT_VALUE,=0D
+ NULL=0D
+ );=0D
+ UT_ASSERT_STATUS_EQUAL (Status, EFI_TIMEOUT);=0D
+=0D
+ Status =3D MpServicesUnitTestStartupAllAPs (=0D
+ LocalContext->MpServices,=0D
+ (EFI_AP_PROCEDURE) InfiniteLoopProcedure,=0D
+ FALSE,=0D
+ RUN_PROCEDURE_TIMEOUT_VALUE,=0D
+ NULL=0D
+ );=0D
+ UT_ASSERT_STATUS_EQUAL (Status, EFI_TIMEOUT);=0D
+=0D
+ return UNIT_TEST_PASSED;=0D
+}=0D
+=0D
+/**=0D
+ Unit test of MP service StartupAllAPs.=0D
+ When called with the empty Procedure on all disabled APs, the return sta=
tus should be EFI_NOT_STARTED.=0D
+=0D
+ @param[in] Context Context pointer for this test.=0D
+=0D
+ @retval UNIT_TEST_PASSED The Unit test has completed and th=
e test=0D
+ case was successful.=0D
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.=
=0D
+**/=0D
+UNIT_TEST_STATUS=0D
+TestStartupAllAPs5 (=0D
+ IN UNIT_TEST_CONTEXT Context=0D
+ )=0D
+{=0D
+ EFI_STATUS Status;=0D
+ UINTN ApNumber;=0D
+ MP_SERVICE_UT_CONTEXT *LocalContext;=0D
+=0D
+ LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Context;=0D
+=0D
+ for (ApNumber =3D 0; ApNumber < LocalContext->NumberOfProcessors; ApNumb=
er++) {=0D
+ Status =3D MpServicesUnitTestEnableDisableAP (=0D
+ LocalContext->MpServices,=0D
+ ApNumber,=0D
+ FALSE,=0D
+ NULL=0D
+ );=0D
+=0D
+ if (ApNumber =3D=3D LocalContext->BspNumber) {=0D
+ UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER);=0D
+ } else {=0D
+ UT_ASSERT_NOT_EFI_ERROR (Status);=0D
+ }=0D
+ }=0D
+=0D
+ Status =3D MpServicesUnitTestStartupAllAPs (=0D
+ LocalContext->MpServices,=0D
+ (EFI_AP_PROCEDURE) EmptyProcedure,=0D
+ FALSE,=0D
+ 0,=0D
+ NULL=0D
+ );=0D
+ UT_ASSERT_STATUS_EQUAL (Status, EFI_NOT_STARTED);=0D
+=0D
+ for (ApNumber =3D 0; ApNumber < LocalContext->NumberOfProcessors; ApNumb=
er++) {=0D
+ Status =3D MpServicesUnitTestEnableDisableAP (=0D
+ LocalContext->MpServices,=0D
+ ApNumber,=0D
+ TRUE,=0D
+ NULL=0D
+ );=0D
+=0D
+ if (ApNumber =3D=3D LocalContext->BspNumber) {=0D
+ UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER);=0D
+ } else {=0D
+ UT_ASSERT_NOT_EFI_ERROR (Status);=0D
+ }=0D
+ }=0D
+=0D
+ return UNIT_TEST_PASSED;=0D
+}=0D
+=0D
+/**=0D
+ Unit test of MP service SwitchBSP.=0D
+ When switch current BSP to be BSP, the return status should be EFI_INVAL=
ID_PARAMETER.=0D
+ When switch nonexistent processor to be BSP, the return status should be=
EFI_NOT_FOUND.=0D
+ After switch BSP, all APs(includes new AP) should execute the Procedure =
when called by StartupAllAP.=0D
+=0D
+ @param[in] Context Context pointer for this test.=0D
+=0D
+ @retval UNIT_TEST_PASSED The Unit test has completed and th=
e test=0D
+ case was successful.=0D
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.=
=0D
+**/=0D
+UNIT_TEST_STATUS=0D
+TestSwitchBSP1 (=0D
+ IN UNIT_TEST_CONTEXT Context=0D
+ )=0D
+{=0D
+ EFI_STATUS Status;=0D
+ UINTN NewBspNumber;=0D
+ UINTN ProcessorIndex;=0D
+ MP_SERVICE_UT_CONTEXT *LocalContext;=0D
+=0D
+ LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Context;=0D
+=0D
+ for (NewBspNumber =3D 0; NewBspNumber <=3D LocalContext->NumberOfProcess=
ors; NewBspNumber++) {=0D
+ Status =3D MpServicesUnitTestSwitchBSP (=0D
+ LocalContext->MpServices,=0D
+ NewBspNumber,=0D
+ TRUE=0D
+ );=0D
+=0D
+ if (NewBspNumber =3D=3D LocalContext->BspNumber) {=0D
+ UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER);=0D
+ } else if (NewBspNumber =3D=3D LocalContext->NumberOfProcessors) {=0D
+ UT_ASSERT_STATUS_EQUAL (Status, EFI_NOT_FOUND);=0D
+ } else {=0D
+ UT_ASSERT_NOT_EFI_ERROR (Status);=0D
+=0D
+ SetMem (LocalContext->CommonBuffer, LocalContext->NumberOfProcessors=
* sizeof (*LocalContext->CommonBuffer), 0xFF);=0D
+ Status =3D MpServicesUnitTestStartupAllAPs (=0D
+ LocalContext->MpServices,=0D
+ (EFI_AP_PROCEDURE) StoreCpuNumbers,=0D
+ FALSE,=0D
+ 0,=0D
+ (VOID *) LocalContext=0D
+ );=0D
+ UT_ASSERT_NOT_EFI_ERROR (Status);=0D
+=0D
+ for (ProcessorIndex =3D 0; ProcessorIndex < LocalContext->NumberOfPr=
ocessors; ProcessorIndex++) {=0D
+ UT_ASSERT_TRUE ((ProcessorIndex =3D=3D NewBspNumber) && LocalConte=
xt->CommonBuffer[ProcessorIndex] =3D=3D (UINTN) ~0 ||=0D
+ (ProcessorIndex !=3D NewBspNumber) && LocalContext=
->CommonBuffer[ProcessorIndex] =3D=3D ProcessorIndex);=0D
+ }=0D
+=0D
+ Status =3D MpServicesUnitTestSwitchBSP (=0D
+ LocalContext->MpServices,=0D
+ LocalContext->BspNumber,=0D
+ TRUE=0D
+ );=0D
+ UT_ASSERT_NOT_EFI_ERROR (Status);=0D
+ }=0D
+ }=0D
+=0D
+ return UNIT_TEST_PASSED;=0D
+}=0D
+=0D
+/**=0D
+ Unit test of MP service SwitchBSP.=0D
+ When run this procedure on AP, the return status should be EFI_DEVICE_ER=
ROR.=0D
+=0D
+ @param[in] Context Context pointer for this test.=0D
+=0D
+ @retval UNIT_TEST_PASSED The Unit test has completed and th=
e test=0D
+ case was successful.=0D
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.=
=0D
+**/=0D
+UNIT_TEST_STATUS=0D
+TestSwitchBSP2 (=0D
+ IN UNIT_TEST_CONTEXT Context=0D
+ )=0D
+{=0D
+ EFI_STATUS Status;=0D
+ UINTN ApNumber;=0D
+ MP_SERVICE_UT_CONTEXT *LocalContext;=0D
+=0D
+ LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Context;=0D
+=0D
+ for (ApNumber =3D 0; ApNumber < LocalContext->NumberOfProcessors; ApNumb=
er++) {=0D
+ LocalContext->ApNumber =3D ApNumber;=0D
+ Status =3D MpServicesUnitTestStartupThisAP (=0D
+ LocalContext->MpServices,=0D
+ (EFI_AP_PROCEDURE) RunMpServiceSwitchBSPOnAp,=0D
+ ApNumber,=0D
+ 0,=0D
+ (VOID *) LocalContext=0D
+ );=0D
+=0D
+ if (ApNumber =3D=3D LocalContext->BspNumber) {=0D
+ UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER);=0D
+ } else {=0D
+ UT_ASSERT_NOT_EFI_ERROR (Status);=0D
+ UT_ASSERT_STATUS_EQUAL (LocalContext->ApProcedureReturnStatus, EFI_D=
EVICE_ERROR);=0D
+ }=0D
+ }=0D
+=0D
+ return UNIT_TEST_PASSED;=0D
+}=0D
+=0D
+/**=0D
+ Unit test of MP service SwitchBSP.=0D
+ When switch a disabled AP to be BSP, the return status should be EFI_INV=
ALID_PARAMETER.=0D
+=0D
+ @param[in] Context Context pointer for this test.=0D
+=0D
+ @retval UNIT_TEST_PASSED The Unit test has completed and th=
e test=0D
+ case was successful.=0D
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.=
=0D
+**/=0D
+UNIT_TEST_STATUS=0D
+TestSwitchBSP3 (=0D
+ IN UNIT_TEST_CONTEXT Context=0D
+ )=0D
+{=0D
+ EFI_STATUS Status;=0D
+ UINTN NewBspNumber;=0D
+ MP_SERVICE_UT_CONTEXT *LocalContext;=0D
+=0D
+ LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Context;=0D
+=0D
+ for (NewBspNumber =3D 0; NewBspNumber < LocalContext->NumberOfProcessors=
; NewBspNumber++) {=0D
+ Status =3D MpServicesUnitTestEnableDisableAP (=0D
+ LocalContext->MpServices,=0D
+ NewBspNumber,=0D
+ FALSE,=0D
+ NULL=0D
+ );=0D
+=0D
+ if (NewBspNumber =3D=3D LocalContext->BspNumber) {=0D
+ UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER);=0D
+ } else {=0D
+ UT_ASSERT_NOT_EFI_ERROR (Status);=0D
+=0D
+ Status =3D MpServicesUnitTestSwitchBSP (=0D
+ LocalContext->MpServices,=0D
+ NewBspNumber,=0D
+ TRUE=0D
+ );=0D
+ UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER);=0D
+=0D
+ Status =3D MpServicesUnitTestEnableDisableAP (=0D
+ LocalContext->MpServices,=0D
+ NewBspNumber,=0D
+ TRUE,=0D
+ NULL=0D
+ );=0D
+ UT_ASSERT_NOT_EFI_ERROR (Status);=0D
+ }=0D
+ }=0D
+=0D
+ return UNIT_TEST_PASSED;=0D
+}=0D
+=0D
+/**=0D
+ Unit test of MP service SwitchBSP.=0D
+ When SwitchBSP and EnableOldBSP is TRUE, the new BSP should be in the en=
abled state and the old BSP should=0D
+ be in the enabled state.=0D
+ When SwitchBSP and EnableOldBSP is False, the new BSP should be in the e=
nabled state and the old BSP should=0D
+ be in the disabled state.=0D
+=0D
+ @param[in] Context Context pointer for this test.=0D
+=0D
+ @retval UNIT_TEST_PASSED The Unit test has completed and th=
e test=0D
+ case was successful.=0D
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.=
=0D
+**/=0D
+UNIT_TEST_STATUS=0D
+TestSwitchBSP4 (=0D
+ IN UNIT_TEST_CONTEXT Context=0D
+ )=0D
+{=0D
+ EFI_STATUS Status;=0D
+ UINTN NewBspNumber;=0D
+ EFI_PROCESSOR_INFORMATION ProcessorInfoBuffer;=0D
+ MP_SERVICE_UT_CONTEXT *LocalContext;=0D
+=0D
+ LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Context;=0D
+=0D
+ for (NewBspNumber =3D 0; NewBspNumber < LocalContext->NumberOfProcessors=
; NewBspNumber++) {=0D
+ Status =3D MpServicesUnitTestSwitchBSP (=0D
+ LocalContext->MpServices,=0D
+ NewBspNumber,=0D
+ FALSE=0D
+ );=0D
+=0D
+ if (NewBspNumber =3D=3D LocalContext->BspNumber) {=0D
+ UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER);=0D
+ } else {=0D
+ UT_ASSERT_NOT_EFI_ERROR (Status);=0D
+=0D
+ Status =3D MpServicesUnitTestGetProcessorInfo (=0D
+ LocalContext->MpServices,=0D
+ NewBspNumber,=0D
+ &ProcessorInfoBuffer=0D
+ );=0D
+ UT_ASSERT_NOT_EFI_ERROR (Status);=0D
+ UT_ASSERT_TRUE ((ProcessorInfoBuffer.StatusFlag & PROCESSOR_AS_BSP_B=
IT) &&=0D
+ (ProcessorInfoBuffer.StatusFlag & PROCESSOR_ENABLED_=
BIT));=0D
+=0D
+ Status =3D MpServicesUnitTestGetProcessorInfo (=0D
+ LocalContext->MpServices,=0D
+ LocalContext->BspNumber,=0D
+ &ProcessorInfoBuffer=0D
+ );=0D
+ UT_ASSERT_NOT_EFI_ERROR (Status);=0D
+ UT_ASSERT_TRUE (!(ProcessorInfoBuffer.StatusFlag & PROCESSOR_AS_BSP_=
BIT) &&=0D
+ !(ProcessorInfoBuffer.StatusFlag & PROCESSOR_ENABLED=
_BIT));=0D
+=0D
+ Status =3D MpServicesUnitTestEnableDisableAP (=0D
+ LocalContext->MpServices,=0D
+ LocalContext->BspNumber,=0D
+ TRUE,=0D
+ NULL=0D
+ );=0D
+ UT_ASSERT_NOT_EFI_ERROR (Status);=0D
+=0D
+ Status =3D MpServicesUnitTestSwitchBSP (=0D
+ LocalContext->MpServices,=0D
+ LocalContext->BspNumber,=0D
+ TRUE=0D
+ );=0D
+ UT_ASSERT_NOT_EFI_ERROR (Status);=0D
+=0D
+ Status =3D MpServicesUnitTestGetProcessorInfo (=0D
+ LocalContext->MpServices,=0D
+ LocalContext->BspNumber,=0D
+ &ProcessorInfoBuffer=0D
+ );=0D
+ UT_ASSERT_NOT_EFI_ERROR (Status);=0D
+ UT_ASSERT_TRUE ((ProcessorInfoBuffer.StatusFlag & PROCESSOR_AS_BSP_B=
IT) &&=0D
+ (ProcessorInfoBuffer.StatusFlag & PROCESSOR_ENABLED_=
BIT));=0D
+=0D
+ Status =3D MpServicesUnitTestGetProcessorInfo (=0D
+ LocalContext->MpServices,=0D
+ NewBspNumber,=0D
+ &ProcessorInfoBuffer=0D
+ );=0D
+ UT_ASSERT_NOT_EFI_ERROR (Status);=0D
+ UT_ASSERT_TRUE (!(ProcessorInfoBuffer.StatusFlag & PROCESSOR_AS_BSP_=
BIT) &&=0D
+ (ProcessorInfoBuffer.StatusFlag & PROCESSOR_ENABLED_=
BIT));=0D
+ }=0D
+ }=0D
+=0D
+ return UNIT_TEST_PASSED;=0D
+}=0D
+=0D
+/**=0D
+ Create test suite and unit tests for both EdkiiPeiMpServices2Ppi and Efi=
MpServiceProtocol.=0D
+=0D
+ @retval EFI_SUCCESS All test cases were dispatched.=0D
+ @retval EFI_OUT_OF_RESOURCES There are not enough resources available =
to=0D
+ initialize the unit tests.=0D
+=0D
+ @param[in] Framework A pointer to the framework that is being persi=
sted.=0D
+ @param[in] Context A pointer to the private data buffer.=0D
+=0D
+ @retval EFI_SUCCESS Create test suite and unit tests successfully.=
=0D
+ @retval Others Create test suite and unit tests unsuccessfull=
y.=0D
+**/=0D
+EFI_STATUS=0D
+AddCommonTestCase (=0D
+ IN UNIT_TEST_FRAMEWORK_HANDLE Framework,=0D
+ IN MP_SERVICE_UT_CONTEXT *Context=0D
+ )=0D
+{=0D
+ EFI_STATUS Status;=0D
+ UNIT_TEST_SUITE_HANDLE MpServiceWhoAmITestSuite;=0D
+ UNIT_TEST_SUITE_HANDLE MpServiceGetNumberOfProcessorsTestSuite;=0D
+ UNIT_TEST_SUITE_HANDLE MpServiceGetProcessorInfoTestSuite;=0D
+ UNIT_TEST_SUITE_HANDLE MpServiceEnableDisableAPTestSuite;=0D
+ UNIT_TEST_SUITE_HANDLE MpServiceStartupThisAPTestSuite;=0D
+ UNIT_TEST_SUITE_HANDLE MpServiceStartupAllAPsTestSuite;=0D
+ UNIT_TEST_SUITE_HANDLE MpServiceSwitchBSPTestSuite;=0D
+=0D
+ MpServiceWhoAmITestSuite =3D NULL;=0D
+ MpServiceGetNumberOfProcessorsTestSuite =3D NULL;=0D
+ MpServiceGetProcessorInfoTestSuite =3D NULL;=0D
+ MpServiceEnableDisableAPTestSuite =3D NULL;=0D
+ MpServiceStartupThisAPTestSuite =3D NULL;=0D
+ MpServiceStartupAllAPsTestSuite =3D NULL;=0D
+ MpServiceSwitchBSPTestSuite =3D NULL;=0D
+=0D
+ //=0D
+ // Test WhoAmI function=0D
+ //=0D
+ Status =3D CreateUnitTestSuite (&MpServiceWhoAmITestSuite, Framework, "I=
dentify the currently executing processor", "MpServices.WhoAmI", NULL, NULL=
);=0D
+ if (EFI_ERROR (Status)) {=0D
+ DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for MpServiceWhoAm=
I Test Suite\n"));=0D
+ return Status;=0D
+ }=0D
+=0D
+ AddTestCase (MpServiceWhoAmITestSuite, "Test WhoAmI 1", "TestWhoAmI1", T=
estWhoAmI1, InitUTContext, CheckUTContext, Context);=0D
+=0D
+ //=0D
+ // Test GetNumberOfProcessors function=0D
+ //=0D
+ Status =3D CreateUnitTestSuite (&MpServiceGetNumberOfProcessorsTestSuite=
, Framework, "Retrieve the number of logical processor", "MpServices.GetNum=
berOfProcessors", NULL, NULL);=0D
+ if (EFI_ERROR (Status)) {=0D
+ DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for MpServiceGetNu=
mberOfProcessors Test Suite\n"));=0D
+ return Status;=0D
+ }=0D
+=0D
+ AddTestCase (MpServiceGetNumberOfProcessorsTestSuite, "Test GetNumberOfP=
rocessors 1", "TestGetNumberOfProcessors1", TestGetNumberOfProcessors1, Ini=
tUTContext, CheckUTContext, Context);=0D
+ AddTestCase (MpServiceGetNumberOfProcessorsTestSuite, "Test GetNumberOfP=
rocessors 2", "TestGetNumberOfProcessors2", TestGetNumberOfProcessors2, Ini=
tUTContext, CheckUTContext, Context);=0D
+ AddTestCase (MpServiceGetNumberOfProcessorsTestSuite, "Test GetNumberOfP=
rocessors 3", "TestGetNumberOfProcessors3", TestGetNumberOfProcessors3, Ini=
tUTContext, CheckUTContext, Context);=0D
+=0D
+ //=0D
+ // Test GetProcessorInfo function=0D
+ //=0D
+ Status =3D CreateUnitTestSuite (&MpServiceGetProcessorInfoTestSuite, Fra=
mework, "Get detailed information on the requested logical processor", "MpS=
ervices.GetProcessorInfo", NULL, NULL);=0D
+ if (EFI_ERROR (Status)) {=0D
+ DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for MpServiceGetPr=
ocessorInfo Test Suite\n"));=0D
+ return Status;=0D
+ }=0D
+=0D
+ AddTestCase (MpServiceGetProcessorInfoTestSuite, "Test GetProcessorInfo =
1", "TestGetProcessorInfo1", TestGetProcessorInfo1, InitUTContext, CheckUTC=
ontext, Context);=0D
+ AddTestCase (MpServiceGetProcessorInfoTestSuite, "Test GetProcessorInfo =
2", "TestGetProcessorInfo2", TestGetProcessorInfo2, InitUTContext, CheckUTC=
ontext, Context);=0D
+=0D
+ //=0D
+ // Test EnableDisableAP function=0D
+ //=0D
+ Status =3D CreateUnitTestSuite (&MpServiceEnableDisableAPTestSuite, Fram=
ework, "Caller enables or disables an AP from this point onward", "MpServic=
es.EnableDisableAP", NULL, NULL);=0D
+ if (EFI_ERROR (Status)) {=0D
+ DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for MpServiceEnabl=
eDisableAP Test Suite\n"));=0D
+ return Status;=0D
+ }=0D
+=0D
+ AddTestCase (MpServiceEnableDisableAPTestSuite, "Test EnableDisableAP 1"=
, "TestEnableDisableAP1", TestEnableDisableAP1, InitUTContext, CheckUTConte=
xt, Context);=0D
+ AddTestCase (MpServiceEnableDisableAPTestSuite, "Test EnableDisableAP 2"=
, "TestEnableDisableAP2", TestEnableDisableAP2, InitUTContext, CheckUTConte=
xt, Context);=0D
+ AddTestCase (MpServiceEnableDisableAPTestSuite, "Test EnableDisableAP 3"=
, "TestEnableDisableAP3", TestEnableDisableAP3, InitUTContext, CheckUTConte=
xt, Context);=0D
+=0D
+ //=0D
+ // Test StartupThisAP function=0D
+ //=0D
+ Status =3D CreateUnitTestSuite (&MpServiceStartupThisAPTestSuite, Framew=
ork, "Get the requested AP to execute a caller-provided function", "MpServi=
ces.StartupThisAP", NULL, NULL);=0D
+ if (EFI_ERROR (Status)) {=0D
+ DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for MpServiceStart=
upThisAP Test Suite\n"));=0D
+ return Status;=0D
+ }=0D
+=0D
+ AddTestCase (MpServiceStartupThisAPTestSuite, "Test StartupThisAP 1", "T=
estStartupThisAP1", TestStartupThisAP1, InitUTContext, CheckUTContext, Cont=
ext);=0D
+ AddTestCase (MpServiceStartupThisAPTestSuite, "Test StartupThisAP 2", "T=
estStartupThisAP2", TestStartupThisAP2, InitUTContext, CheckUTContext, Cont=
ext);=0D
+ AddTestCase (MpServiceStartupThisAPTestSuite, "Test StartupThisAP 3", "T=
estStartupThisAP3", TestStartupThisAP3, InitUTContext, CheckUTContext, Cont=
ext);=0D
+ AddTestCase (MpServiceStartupThisAPTestSuite, "Test StartupThisAP 4", "T=
estStartupThisAP4", TestStartupThisAP4, InitUTContext, CheckUTContext, Cont=
ext);=0D
+=0D
+ //=0D
+ // Test StartupAllAPs function=0D
+ //=0D
+ Status =3D CreateUnitTestSuite (&MpServiceStartupAllAPsTestSuite, Framew=
ork, "Execute a caller provided function on all enabled APs", "MpServices.S=
tartupAllAPs", NULL, NULL);=0D
+ if (EFI_ERROR (Status)) {=0D
+ DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for MpServiceStart=
upAllAPs Test Suite\n"));=0D
+ return Status;=0D
+ }=0D
+=0D
+ AddTestCase (MpServiceStartupAllAPsTestSuite, "Test StartupAllAPs 1", "T=
estStartupAllAPs1", TestStartupAllAPs1, InitUTContext, CheckUTContext, Cont=
ext);=0D
+ AddTestCase (MpServiceStartupAllAPsTestSuite, "Test StartupAllAPs 2", "T=
estStartupAllAPs2", TestStartupAllAPs2, InitUTContext, CheckUTContext, Cont=
ext);=0D
+ AddTestCase (MpServiceStartupAllAPsTestSuite, "Test StartupAllAPs 3", "T=
estStartupAllAPs3", TestStartupAllAPs3, InitUTContext, CheckUTContext, Cont=
ext);=0D
+ AddTestCase (MpServiceStartupAllAPsTestSuite, "Test StartupAllAPs 4", "T=
estStartupAllAPs4", TestStartupAllAPs4, InitUTContext, CheckUTContext, Cont=
ext);=0D
+ AddTestCase (MpServiceStartupAllAPsTestSuite, "Test StartupAllAPs 5", "T=
estStartupAllAPs5", TestStartupAllAPs5, InitUTContext, CheckUTContext, Cont=
ext);=0D
+=0D
+ //=0D
+ // Test SwitchBSP function=0D
+ //=0D
+ Status =3D CreateUnitTestSuite (&MpServiceSwitchBSPTestSuite, Framework,=
"Switch the requested AP to be the BSP from that point onward", "MpService=
s.SwitchBSP", NULL, NULL);=0D
+ if (EFI_ERROR (Status)) {=0D
+ DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for MpServiceSwitc=
hBSP Test Suite\n"));=0D
+ return Status;=0D
+ }=0D
+=0D
+ AddTestCase (MpServiceSwitchBSPTestSuite, "Test SwitchBSP 1", "TestSwitc=
hBSP1", TestSwitchBSP1, InitUTContext, CheckUTContext, Context);=0D
+ AddTestCase (MpServiceSwitchBSPTestSuite, "Test SwitchBSP 2", "TestSwitc=
hBSP2", TestSwitchBSP2, InitUTContext, CheckUTContext, Context);=0D
+ AddTestCase (MpServiceSwitchBSPTestSuite, "Test SwitchBSP 3", "TestSwitc=
hBSP3", TestSwitchBSP3, InitUTContext, CheckUTContext, Context);=0D
+ AddTestCase (MpServiceSwitchBSPTestSuite, "Test SwitchBSP 4", "TestSwitc=
hBSP4", TestSwitchBSP4, InitUTContext, FreeUTContext, Context);=0D
+=0D
+ return EFI_SUCCESS;=0D
+}=0D
diff --git a/UefiCpuPkg/Test/UefiCpuPkgHostTest.dsc b/UefiCpuPkg/Test/UefiC=
puPkgHostTest.dsc
index e72e4cd622..269a6697cf 100644
--- a/UefiCpuPkg/Test/UefiCpuPkgHostTest.dsc
+++ b/UefiCpuPkg/Test/UefiCpuPkgHostTest.dsc
@@ -38,3 +38,9 @@
# Build HOST_APPLICATION that tests the CpuPageTableLib=0D
#=0D
UefiCpuPkg/Library/CpuPageTableLib/UnitTest/CpuPageTableLibUnitTestHost.=
inf=0D
+=0D
+ #=0D
+ # Build PEIM and DXE driver that test the MP service PPI & Protocol=0D
+ #=0D
+ UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EdkiiPeiMpServices2Ppi=
PeiUnitTest.inf=0D
+ UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EfiMpServiceProtocolDx=
eUnitTest.inf=0D
diff --git a/UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EdkiiPeiMpSe=
rvices2PpiPeiUnitTest.inf b/UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtoc=
ol/EdkiiPeiMpServices2PpiPeiUnitTest.inf
new file mode 100644
index 0000000000..0b2ddc5585
--- /dev/null
+++ b/UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EdkiiPeiMpServices2=
PpiPeiUnitTest.inf
@@ -0,0 +1,46 @@
+## @file=0D
+# PEIM that unit tests the EdkiiPeiMpServices2Ppi=0D
+#=0D
+# Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>=0D
+# SPDX-License-Identifier: BSD-2-Clause-Patent=0D
+#=0D
+##=0D
+=0D
+[Defines]=0D
+ INF_VERSION =3D 0x00010005=0D
+ BASE_NAME =3D EdkiiPeiMpServices2PpiPeiUnitTest=0D
+ FILE_GUID =3D A4914810-4D1E-445E-BD6F-F6821B852B5D=0D
+ MODULE_TYPE =3D PEIM=0D
+ VERSION_STRING =3D 1.0=0D
+ ENTRY_POINT =3D PeiEntryPoint=0D
+=0D
+#=0D
+# The following information is for reference only and not required by the =
build tools.=0D
+#=0D
+# VALID_ARCHITECTURES =3D IA32 X64=0D
+#=0D
+=0D
+[Sources]=0D
+ EfiMpServicesUnitTestCommom.c=0D
+ EfiMpServicesUnitTestCommom.h=0D
+ EdkiiPeiMpServices2PpiUnitTest.c=0D
+=0D
+[Packages]=0D
+ MdePkg/MdePkg.dec=0D
+ UefiCpuPkg/UefiCpuPkg.dec=0D
+=0D
+[LibraryClasses]=0D
+ BaseLib=0D
+ DebugLib=0D
+ BaseMemoryLib=0D
+ MemoryAllocationLib=0D
+ PeimEntryPoint=0D
+ PeiServicesLib=0D
+ UnitTestPersistenceLib=0D
+ UnitTestLib=0D
+=0D
+[Ppis]=0D
+ gEdkiiPeiMpServices2PpiGuid ## CONSUMES=0D
+=0D
+[Depex]=0D
+ gEdkiiPeiMpServices2PpiGuid=0D
diff --git a/UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EfiMpService=
ProtocolDxeUnitTest.inf b/UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol=
/EfiMpServiceProtocolDxeUnitTest.inf
new file mode 100644
index 0000000000..1389092c06
--- /dev/null
+++ b/UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EfiMpServiceProtoco=
lDxeUnitTest.inf
@@ -0,0 +1,46 @@
+## @file=0D
+# DXE driver that unit tests the EfiMpServiceProtocol=0D
+#=0D
+# Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>=0D
+# SPDX-License-Identifier: BSD-2-Clause-Patent=0D
+#=0D
+##=0D
+=0D
+[Defines]=0D
+ INF_VERSION =3D 0x00010005=0D
+ BASE_NAME =3D EfiMpServiceProtocolDxeUnitTest=0D
+ FILE_GUID =3D F1E468E2-A32D-4574-895D-6D82B27B08BC=0D
+ MODULE_TYPE =3D DXE_DRIVER=0D
+ VERSION_STRING =3D 1.0=0D
+ ENTRY_POINT =3D DxeEntryPoint=0D
+=0D
+#=0D
+# The following information is for reference only and not required by the =
build tools.=0D
+#=0D
+# VALID_ARCHITECTURES =3D IA32 X64=0D
+#=0D
+=0D
+[Sources]=0D
+ EfiMpServicesUnitTestCommom.c=0D
+ EfiMpServicesUnitTestCommom.h=0D
+ EfiMpServiceProtocolUnitTest.c=0D
+=0D
+[Packages]=0D
+ MdePkg/MdePkg.dec=0D
+ UefiCpuPkg/UefiCpuPkg.dec=0D
+=0D
+[LibraryClasses]=0D
+ BaseLib=0D
+ DebugLib=0D
+ BaseMemoryLib=0D
+ MemoryAllocationLib=0D
+ UefiDriverEntryPoint=0D
+ UefiBootServicesTableLib=0D
+ UnitTestPersistenceLib=0D
+ UnitTestLib=0D
+=0D
+[Protocols]=0D
+ gEfiMpServiceProtocolGuid ## CONSUMES=0D
+=0D
+[Depex]=0D
+ gEfiMpServiceProtocolGuid=0D
diff --git a/UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EfiMpService=
sUnitTestCommom.h b/UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EfiMp=
ServicesUnitTestCommom.h
new file mode 100644
index 0000000000..ebd17e0ff3
--- /dev/null
+++ b/UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EfiMpServicesUnitTe=
stCommom.h
@@ -0,0 +1,611 @@
+/** @file=0D
+ Common header file for EfiMpServiceProtocolUnitTest DXE driver.=0D
+=0D
+ Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>=0D
+=0D
+ SPDX-License-Identifier: BSD-2-Clause-Patent=0D
+=0D
+**/=0D
+=0D
+#ifndef _EFI_MP_SERVICES_UNIT_TEST_COMMOM_H_=0D
+#define _EFI_MP_SERVICES_UNIT_TEST_COMMOM_H_=0D
+=0D
+#include <PiPei.h>=0D
+#include <Ppi/MpServices2.h>=0D
+#include <Protocol/MpService.h>=0D
+#include <Library/BaseLib.h>=0D
+#include <Library/DebugLib.h>=0D
+#include <Library/ReportStatusCodeLib.h>=0D
+#include <Library/BaseMemoryLib.h>=0D
+#include <Library/MemoryAllocationLib.h>=0D
+#include <Library/UnitTestLib.h>=0D
+=0D
+#define RUN_PROCEDURE_TIMEOUT_VALUE 100000 // microseconds=0D
+=0D
+typedef union {=0D
+ EDKII_PEI_MP_SERVICES2_PPI *Ppi;=0D
+ EFI_MP_SERVICES_PROTOCOL *Protocol;=0D
+} MP_SERVICES;=0D
+=0D
+typedef struct {=0D
+ MP_SERVICES MpServices;=0D
+ UINTN BspNumber;=0D
+ UINTN ApNumber;=0D
+ UINTN NumberOfProcessors;=0D
+ UINTN NumberOfEnabledProcessors;=0D
+ UINTN *CommonBuffer;=0D
+ EFI_STATUS ApProcedureReturnStatus;=0D
+ UINTN *DisabledApNumber;=0D
+} MP_SERVICE_UT_CONTEXT;=0D
+=0D
+/**=0D
+ Get EFI_MP_SERVICES_PROTOCOL pointer.=0D
+=0D
+ @param[out] MpServices Pointer to the buffer where EFI_MP_SERVICES_PR=
OTOCOL is stored=0D
+=0D
+ @retval EFI_SUCCESS EFI_MP_SERVICES_PROTOCOL interface is returned=
=0D
+ @retval EFI_NOT_FOUND EFI_MP_SERVICES_PROTOCOL interface is not foun=
d=0D
+**/=0D
+EFI_STATUS=0D
+MpServicesUnitTestGetMpServices (=0D
+ OUT MP_SERVICES *MpServices=0D
+ );=0D
+=0D
+/**=0D
+ Retrieve the number of logical processor in the platform and the number =
of those logical processors that=0D
+ are enabled on this boot.=0D
+=0D
+ @param[in] MpServices MP_SERVICES structure.=0D
+ @param[out] NumberOfProcessors Pointer to the total number of logical p=
rocessors in the system, including=0D
+ the BSP and disabled APs.=0D
+ @param[out] NumberOfEnabledProcessors Pointer to the number of processor=
s in the system that are enabled.=0D
+=0D
+ @retval EFI_SUCCESS Retrieve the number of logical processor succe=
ssfully=0D
+ @retval Others Retrieve the number of logical processor unsuc=
cessfully=0D
+**/=0D
+EFI_STATUS=0D
+MpServicesUnitTestGetNumberOfProcessors (=0D
+ IN MP_SERVICES MpServices,=0D
+ OUT UINTN *NumberOfProcessors,=0D
+ OUT UINTN *NumberOfEnabledProcessors=0D
+ );=0D
+=0D
+/**=0D
+ Get detailed information on the requested logical processor.=0D
+=0D
+ @param[in] MpServices MP_SERVICES structure.=0D
+ @param[in] ProcessorNum The handle number of the processor.=0D
+ @param[out] ProcessorInfo Pointer to the buffer where the processor info=
rmation is stored.=0D
+=0D
+ @retval EFI_SUCCESS Get information on the requested logical proce=
ssor successfully=0D
+ @retval Others Get information on the requested logical proce=
ssor unsuccessfully=0D
+**/=0D
+EFI_STATUS=0D
+MpServicesUnitTestGetProcessorInfo (=0D
+ IN MP_SERVICES MpServices,=0D
+ IN UINTN ProcessorNumber,=0D
+ OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer=0D
+ );=0D
+=0D
+/**=0D
+ Execute a caller provided function on all enabled APs.=0D
+=0D
+ @param[in] MpServices MP_SERVICES structure.=0D
+ @param[in] Procedure Pointer to the function to be run on enabled A=
Ps of the system.=0D
+ @param[in] SingleThread If TRUE, then all the enabled APs execute the =
function specified by Procedure=0D
+ one by one, in ascending order of processor ha=
ndle number.=0D
+ If FALSE, then all the enabled APs execute the=
function specified by Procedure=0D
+ simultaneously.=0D
+ @param[in] TimeoutInMicroseconds Indicates the time limit in microsecon=
ds for APs to return from Procedure,=0D
+ for blocking mode only. Zero means inf=
inity.=0D
+ @param[in] ProcedureArgument The parameter passed into Procedure fo=
r all APs.=0D
+=0D
+ @retval EFI_SUCCESS Execute a caller provided function on all enab=
led APs successfully=0D
+ @retval Others Execute a caller provided function on all enab=
led APs unsuccessfully=0D
+**/=0D
+EFI_STATUS=0D
+MpServicesUnitTestStartupAllAPs (=0D
+ IN MP_SERVICES MpServices,=0D
+ IN EFI_AP_PROCEDURE Procedure,=0D
+ IN BOOLEAN SingleThread,=0D
+ IN UINTN TimeoutInMicroSeconds,=0D
+ IN VOID *ProcedureArgument=0D
+ );=0D
+=0D
+/**=0D
+ Caller gets one enabled AP to execute a caller-provided function.=0D
+=0D
+ @param[in] MpServices MP_SERVICES structure.=0D
+ @param[in] Procedure Pointer to the function to be run on enabled A=
Ps of the system.=0D
+ @param[in] ProcessorNumber The handle number of the AP.=0D
+ @param[in] TimeoutInMicroseconds Indicates the time limit in microsecon=
ds for APs to return from Procedure,=0D
+ for blocking mode only. Zero means inf=
inity.=0D
+ @param[in] ProcedureArgument The parameter passed into Procedure fo=
r all APs.=0D
+=0D
+ @retval EFI_SUCCESS Caller gets one enabled AP to execute a caller=
-provided function successfully=0D
+ @retval Others Caller gets one enabled AP to execute a caller=
-provided function unsuccessfully=0D
+**/=0D
+EFI_STATUS=0D
+MpServicesUnitTestStartupThisAP (=0D
+ IN MP_SERVICES MpServices,=0D
+ IN EFI_AP_PROCEDURE Procedure,=0D
+ IN UINTN ProcessorNumber,=0D
+ IN UINTN TimeoutInMicroSeconds,=0D
+ IN VOID *ProcedureArgument=0D
+ );=0D
+=0D
+/**=0D
+ Switch the requested AP to be the BSP from that point onward.=0D
+=0D
+ @param[in] MpServices MP_SERVICES structure.=0D
+ @param[in] ProcessorNumber The handle number of AP that is to become th=
e new BSP.=0D
+ @param[in] EnableOldBSP If TRUE, the old BSP will be listed as an enab=
led AP. Otherwise, it will be disabled.=0D
+=0D
+ @retval EFI_SUCCESS Switch the requested AP to be the BSP successf=
ully=0D
+ @retval Others Switch the requested AP to be the BSP unsucces=
sfully=0D
+**/=0D
+EFI_STATUS=0D
+MpServicesUnitTestSwitchBSP (=0D
+ IN MP_SERVICES MpServices,=0D
+ IN UINTN ProcessorNumber,=0D
+ IN BOOLEAN EnableOldBSP=0D
+ );=0D
+=0D
+/**=0D
+ Caller enables or disables an AP from this point onward.=0D
+=0D
+ @param[in] MpServices MP_SERVICES structure.=0D
+ @param[in] ProcessorNumber The handle number of the AP.=0D
+ @param[in] EnableAP Specifies the new state for the processor for =
enabled, FALSE for disabled.=0D
+ @param[in] HealthFlag If not NULL, a pointer to a value that specifi=
es the new health status of the AP.=0D
+=0D
+ @retval EFI_SUCCESS Caller enables or disables an AP successfully.=
=0D
+ @retval Others Caller enables or disables an AP unsuccessfull=
y.=0D
+**/=0D
+EFI_STATUS=0D
+MpServicesUnitTestEnableDisableAP (=0D
+ IN MP_SERVICES MpServices,=0D
+ IN UINTN ProcessorNumber,=0D
+ IN BOOLEAN EnableAP,=0D
+ IN UINT32 *HealthFlag=0D
+ );=0D
+=0D
+/**=0D
+ Get the handle number for the calling processor.=0D
+=0D
+ @param[in] MpServices MP_SERVICES structure.=0D
+ @param[out] ProcessorNumber The handle number for the calling processor.=
=0D
+=0D
+ @retval EFI_SUCCESS Get the handle number for the calling processo=
r successfully.=0D
+ @retval Others Get the handle number for the calling processo=
r unsuccessfully.=0D
+**/=0D
+EFI_STATUS=0D
+MpServicesUnitTestWhoAmI (=0D
+ IN MP_SERVICES MpServices,=0D
+ OUT UINTN *ProcessorNumber=0D
+ );=0D
+=0D
+/**=0D
+ Empty procedure to be run on specified CPU.=0D
+=0D
+ @param[in,out] Buffer The pointer to private data buffer.=0D
+**/=0D
+VOID=0D
+EmptyProcedure (=0D
+ IN OUT VOID *Buffer=0D
+ );=0D
+=0D
+/**=0D
+ Produce to store ProcessorNumber in CommonBuffer and be run on specified=
CPU.=0D
+=0D
+ @param[in,out] Buffer The pointer to private data buffer.=0D
+**/=0D
+VOID=0D
+StoreCpuNumbers (=0D
+ IN OUT VOID *Buffer=0D
+ );=0D
+=0D
+/**=0D
+ Prep routine for Unit test function.=0D
+ To save the ProcessorNumber of disabled AP and temporarily enable it.=0D
+=0D
+ @param[in] Context Context pointer for this test.=0D
+=0D
+ @retval UNIT_TEST_PASSED Prep routine runs successful.=0D
+ @retval UNIT_TEST_ERROR_TEST_FAILED Prep routine runs unsuccessful.=0D
+**/=0D
+UNIT_TEST_STATUS=0D
+InitUTContext (=0D
+ IN UNIT_TEST_CONTEXT Context=0D
+ );=0D
+=0D
+/**=0D
+ Cleanup routine for Unit test function.=0D
+ If any processor is disabled unexpectedly then reenable it.=0D
+=0D
+ @param[in] Context Context pointer for this test.=0D
+=0D
+ @retval UNIT_TEST_PASSED Cleanup routine runs successful.=0D
+ @retval UNIT_TEST_ERROR_TEST_FAILED Cleanup routine runs unsuccessful.=
=0D
+**/=0D
+UNIT_TEST_STATUS=0D
+CheckUTContext (=0D
+ IN UNIT_TEST_CONTEXT Context=0D
+ );=0D
+=0D
+/**=0D
+ Cleanup routine for Unit test function.=0D
+ It will be called by the last "AddTestCase" to restore AP state and free=
pointer.=0D
+=0D
+ @param[in] Context Context pointer for this test.=0D
+=0D
+ @retval UNIT_TEST_PASSED Cleanup routine runs successful.=0D
+ @retval UNIT_TEST_ERROR_TEST_FAILED Cleanup routine runs unsuccessful.=
=0D
+**/=0D
+UNIT_TEST_STATUS=0D
+FreeUTContext (=0D
+ IN UNIT_TEST_CONTEXT Context=0D
+ );=0D
+=0D
+/**=0D
+ Unit test of MP service WhoAmI.=0D
+ The range of ProcessorNumber should be from 0 to NumberOfCPUs minus 1.=0D
+ The ProcessorNumbers of all CPUs are unique.=0D
+=0D
+ @param[in] Context Context pointer for this test.=0D
+=0D
+ @retval UNIT_TEST_PASSED The Unit test has completed and th=
e test=0D
+ case was successful.=0D
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.=
=0D
+**/=0D
+UNIT_TEST_STATUS=0D
+TestWhoAmI1 (=0D
+ IN UNIT_TEST_CONTEXT Context=0D
+ );=0D
+=0D
+/**=0D
+ Unit test of MP service GetNumberOfProcessors.=0D
+ NumberOfProcessors should be greater that 0 and not less than NumberOfEn=
abledProcessors.=0D
+=0D
+ @param[in] Context Context pointer for this test.=0D
+=0D
+ @retval UNIT_TEST_PASSED The Unit test has completed and th=
e test=0D
+ case was successful.=0D
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.=
=0D
+**/=0D
+UNIT_TEST_STATUS=0D
+TestGetNumberOfProcessors1 (=0D
+ IN UNIT_TEST_CONTEXT Context=0D
+ );=0D
+=0D
+/**=0D
+ Unit test of MP service GetNumberOfProcessors.=0D
+ When this service is called from an AP, the return status should be EFI_=
DEVICE_ERROR.=0D
+=0D
+ @param[in] Context Context pointer for this test.=0D
+=0D
+ @retval UNIT_TEST_PASSED The Unit test has completed and th=
e test=0D
+ case was successful.=0D
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.=
=0D
+**/=0D
+UNIT_TEST_STATUS=0D
+TestGetNumberOfProcessors2 (=0D
+ IN UNIT_TEST_CONTEXT Context=0D
+ );=0D
+=0D
+/**=0D
+ Unit test of MP service GetNumberOfProcessors.=0D
+ Call EnableDisableAP() to change the number of enabled AP.=0D
+=0D
+ @param[in] Context Context pointer for this test.=0D
+=0D
+ @retval UNIT_TEST_PASSED The Unit test has completed and th=
e test=0D
+ case was successful.=0D
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.=
=0D
+**/=0D
+UNIT_TEST_STATUS=0D
+TestGetNumberOfProcessors3 (=0D
+ IN UNIT_TEST_CONTEXT Context=0D
+ );=0D
+=0D
+/**=0D
+ Unit test of MP service GetProcessorInfo.=0D
+ When all the parameters are valid, all reserved bits of StatusFlag in Pr=
ocessorInfoBuffer should be set to zero.=0D
+ When all the parameters are valid, the StatusFlag should not have an inv=
alid value (The BSP can never be in the disabled state.).=0D
+ When called with nonexistent processor handle, the return status should =
be EFI_NOT_FOUND.=0D
+=0D
+ @param[in] Context Context pointer for this test.=0D
+=0D
+ @retval UNIT_TEST_PASSED The Unit test has completed and th=
e test=0D
+ case was successful.=0D
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.=
=0D
+**/=0D
+UNIT_TEST_STATUS=0D
+TestGetProcessorInfo1 (=0D
+ IN UNIT_TEST_CONTEXT Context=0D
+ );=0D
+=0D
+/**=0D
+ Unit test of MP service GetProcessorInfo.=0D
+ When this service is called from an AP, the return status should be EFI_=
DEVICE_ERROR.=0D
+=0D
+ @param[in] Context Context pointer for this test.=0D
+=0D
+ @retval UNIT_TEST_PASSED The Unit test has completed and th=
e test=0D
+ case was successful.=0D
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.=
=0D
+**/=0D
+UNIT_TEST_STATUS=0D
+TestGetProcessorInfo2 (=0D
+ IN UNIT_TEST_CONTEXT Context=0D
+ );=0D
+=0D
+/**=0D
+ Unit test of MP service EnableDisableAP.=0D
+ When called with BSP number, the return status should be EFI_INVALID_PAR=
AMETER.=0D
+ When called with a nonexistent processor handle, the return status shoul=
d be EFI_NOT_FOUND.=0D
+ The AP should be really Enable/Disabled.=0D
+=0D
+ @param[in] Context Context pointer for this test.=0D
+=0D
+ @retval UNIT_TEST_PASSED The Unit test has completed and th=
e test=0D
+ case was successful.=0D
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.=
=0D
+**/=0D
+UNIT_TEST_STATUS=0D
+TestEnableDisableAP1 (=0D
+ IN UNIT_TEST_CONTEXT Context=0D
+ );=0D
+=0D
+/**=0D
+ Unit test of MP service EnableDisableAP.=0D
+ When run this procedure on AP, the return status should be EFI_DEVICE_ER=
ROR.=0D
+=0D
+ @param[in] Context Context pointer for this test.=0D
+=0D
+ @retval UNIT_TEST_PASSED The Unit test has completed and th=
e test=0D
+ case was successful.=0D
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.=
=0D
+**/=0D
+UNIT_TEST_STATUS=0D
+TestEnableDisableAP2 (=0D
+ IN UNIT_TEST_CONTEXT Context=0D
+ );=0D
+=0D
+/**=0D
+ Unit test of MP service EnableDisableAP.=0D
+ When run this procedure on AP, the return status should be EFI_DEVICE_ER=
ROR.=0D
+=0D
+ @param[in] Context Context pointer for this test.=0D
+=0D
+ @retval UNIT_TEST_PASSED The Unit test has completed and th=
e test=0D
+ case was successful.=0D
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.=
=0D
+**/=0D
+UNIT_TEST_STATUS=0D
+TestEnableDisableAP3 (=0D
+ IN UNIT_TEST_CONTEXT Context=0D
+ );=0D
+=0D
+/**=0D
+ Unit test of MP service StartupThisAP.=0D
+ When called to startup a BSP, the return status should be EFI_INVALID_PA=
RAMETER.=0D
+ When called with a nonexistent processor handle, the return status shoul=
d be EFI_NOT_FOUND.=0D
+ The requested AP should execute the Procedure when called by StartupThis=
AP.=0D
+=0D
+ @param[in] Context Context pointer for this test.=0D
+=0D
+ @retval UNIT_TEST_PASSED The Unit test has completed and th=
e test=0D
+ case was successful.=0D
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.=
=0D
+**/=0D
+UNIT_TEST_STATUS=0D
+TestStartupThisAP1 (=0D
+ IN UNIT_TEST_CONTEXT Context=0D
+ );=0D
+=0D
+/**=0D
+ Unit test of MP service StartupThisAP.=0D
+ When this service is called from an AP, the return status should be EFI_=
DEVICE_ERROR.=0D
+=0D
+ @param[in] Context Context pointer for this test.=0D
+=0D
+ @retval UNIT_TEST_PASSED The Unit test has completed and th=
e test=0D
+ case was successful.=0D
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.=
=0D
+**/=0D
+UNIT_TEST_STATUS=0D
+TestStartupThisAP2 (=0D
+ IN UNIT_TEST_CONTEXT Context=0D
+ );=0D
+=0D
+/**=0D
+ Unit test of MP service StartupThisAP.=0D
+ When timeout expired before the requested AP has finished, the return st=
atus should be EFI_TIMEOUT.=0D
+=0D
+ @param[in] Context Context pointer for this test.=0D
+=0D
+ @retval UNIT_TEST_PASSED The Unit test has completed and th=
e test=0D
+ case was successful.=0D
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.=
=0D
+**/=0D
+UNIT_TEST_STATUS=0D
+TestStartupThisAP3 (=0D
+ IN UNIT_TEST_CONTEXT Context=0D
+ );=0D
+=0D
+/**=0D
+ Unit test of MP service StartupThisAP.=0D
+ When called with disabled AP, the return status should be EFI_INVALID_PA=
RAMETER.=0D
+=0D
+ @param[in] Context Context pointer for this test.=0D
+=0D
+ @retval UNIT_TEST_PASSED The Unit test has completed and th=
e test=0D
+ case was successful.=0D
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.=
=0D
+**/=0D
+UNIT_TEST_STATUS=0D
+TestStartupThisAP4 (=0D
+ IN UNIT_TEST_CONTEXT Context=0D
+ );=0D
+=0D
+/**=0D
+ Unit test of MP service StartupAllAPs.=0D
+ All APs should execute the Procedure when called by StartupAllAPs.=0D
+=0D
+ @param[in] Context Context pointer for this test.=0D
+=0D
+ @retval UNIT_TEST_PASSED The Unit test has completed and th=
e test=0D
+ case was successful.=0D
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.=
=0D
+**/=0D
+UNIT_TEST_STATUS=0D
+TestStartupAllAPs1 (=0D
+ IN UNIT_TEST_CONTEXT Context=0D
+ );=0D
+=0D
+/**=0D
+ Unit test of MP service StartupAllAPs.=0D
+ When called in single thread, the return status should be EFI_SUCCESS an=
d AP executes in ascending order=0D
+ of processor handle number.=0D
+=0D
+ @param[in] Context Context pointer for this test.=0D
+=0D
+ @retval UNIT_TEST_PASSED The Unit test has completed and th=
e test=0D
+ case was successful.=0D
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.=
=0D
+**/=0D
+UNIT_TEST_STATUS=0D
+TestStartupAllAPs2 (=0D
+ IN UNIT_TEST_CONTEXT Context=0D
+ );=0D
+=0D
+/**=0D
+ Unit test of MP service StartupAllAPs.=0D
+ When this service is called from an AP, the return status should be EFI_=
DEVICE_ERROR.=0D
+=0D
+ @param[in] Context Context pointer for this test.=0D
+=0D
+ @retval UNIT_TEST_PASSED The Unit test has completed and th=
e test=0D
+ case was successful.=0D
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.=
=0D
+**/=0D
+UNIT_TEST_STATUS=0D
+TestStartupAllAPs3 (=0D
+ IN UNIT_TEST_CONTEXT Context=0D
+ );=0D
+=0D
+/**=0D
+ Unit test of MP service StartupAllAPs.=0D
+ When called with all AP timeout, the return status should be EFI_TIMEOUT=
.=0D
+=0D
+ @param[in] Context Context pointer for this test.=0D
+=0D
+ @retval UNIT_TEST_PASSED The Unit test has completed and th=
e test=0D
+ case was successful.=0D
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.=
=0D
+**/=0D
+UNIT_TEST_STATUS=0D
+TestStartupAllAPs4 (=0D
+ IN UNIT_TEST_CONTEXT Context=0D
+ );=0D
+=0D
+/**=0D
+ Unit test of MP service StartupAllAPs.=0D
+ When called with the empty Procedure on all disabled APs, the return sta=
tus should be EFI_NOT_STARTED.=0D
+=0D
+ @param[in] Context Context pointer for this test.=0D
+=0D
+ @retval UNIT_TEST_PASSED The Unit test has completed and th=
e test=0D
+ case was successful.=0D
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.=
=0D
+**/=0D
+UNIT_TEST_STATUS=0D
+TestStartupAllAPs5 (=0D
+ IN UNIT_TEST_CONTEXT Context=0D
+ );=0D
+=0D
+/**=0D
+ Unit test of MP service SwitchBSP.=0D
+ When switch current BSP to be BSP, the return status should be EFI_INVAL=
ID_PARAMETER.=0D
+ When switch nonexistent processor to be BSP, the return status should be=
EFI_NOT_FOUND.=0D
+ After switch BSP, all APs(includes new AP) should execute the Procedure =
when called by StartupAllAP.=0D
+=0D
+ @param[in] Context Context pointer for this test.=0D
+=0D
+ @retval UNIT_TEST_PASSED The Unit test has completed and th=
e test=0D
+ case was successful.=0D
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.=
=0D
+**/=0D
+UNIT_TEST_STATUS=0D
+TestSwitchBSP1 (=0D
+ IN UNIT_TEST_CONTEXT Context=0D
+ );=0D
+=0D
+/**=0D
+ Unit test of MP service SwitchBSP.=0D
+ When run this procedure on AP, the return status should be EFI_DEVICE_ER=
ROR.=0D
+=0D
+ @param[in] Context Context pointer for this test.=0D
+=0D
+ @retval UNIT_TEST_PASSED The Unit test has completed and th=
e test=0D
+ case was successful.=0D
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.=
=0D
+**/=0D
+UNIT_TEST_STATUS=0D
+TestSwitchBSP2 (=0D
+ IN UNIT_TEST_CONTEXT Context=0D
+ );=0D
+=0D
+/**=0D
+ Unit test of MP service SwitchBSP.=0D
+ When switch a disabled AP to be BSP, the return status should be EFI_INV=
ALID_PARAMETER.=0D
+=0D
+ @param[in] Context Context pointer for this test.=0D
+=0D
+ @retval UNIT_TEST_PASSED The Unit test has completed and th=
e test=0D
+ case was successful.=0D
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.=
=0D
+**/=0D
+UNIT_TEST_STATUS=0D
+TestSwitchBSP3 (=0D
+ IN UNIT_TEST_CONTEXT Context=0D
+ );=0D
+=0D
+/**=0D
+ Unit test of MP service SwitchBSP.=0D
+ When SwitchBSP and EnableOldBSP is TRUE, the new BSP should be in the en=
abled state and the old BSP should=0D
+ be in the enabled state.=0D
+ When SwitchBSP and EnableOldBSP is False, the new BSP should be in the e=
nabled state and the old BSP should=0D
+ be in the disabled state.=0D
+=0D
+ @param[in] Context Context pointer for this test.=0D
+=0D
+ @retval UNIT_TEST_PASSED The Unit test has completed and th=
e test=0D
+ case was successful.=0D
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.=
=0D
+**/=0D
+UNIT_TEST_STATUS=0D
+TestSwitchBSP4 (=0D
+ IN UNIT_TEST_CONTEXT Context=0D
+ );=0D
+=0D
+/**=0D
+ Create test suite and unit tests for both EdkiiPeiMpServices2Ppi and Efi=
MpServiceProtocol.=0D
+=0D
+ @retval EFI_SUCCESS All test cases were dispatched.=0D
+ @retval EFI_OUT_OF_RESOURCES There are not enough resources available =
to=0D
+ initialize the unit tests.=0D
+=0D
+ @param[in] Framework A pointer to the framework that is being persi=
sted.=0D
+ @param[in] Context A pointer to the private data buffer.=0D
+=0D
+ @retval EFI_SUCCESS Create test suite and unit tests successfully.=
=0D
+ @retval Others Create test suite and unit tests unsuccessfull=
y.=0D
+**/=0D
+EFI_STATUS=0D
+AddCommonTestCase (=0D
+ IN UNIT_TEST_FRAMEWORK_HANDLE Framework,=0D
+ IN MP_SERVICE_UT_CONTEXT *Context=0D
+ );=0D
+#endif=0D
--=20
2.28.0.windows.1