From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by mx.groups.io with SMTP id smtpd.web10.16773.1664111262069356054 for ; Sun, 25 Sep 2022 06:07:42 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="unable to parse pub key" header.i=@intel.com header.s=intel header.b=QY8daeKE; spf=pass (domain: intel.com, ip: 134.134.136.20, mailfrom: yun.lou@intel.com) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1664111262; x=1695647262; h=from:to:cc:subject:date:message-id:mime-version: content-transfer-encoding; bh=YDt0Bwzb42JrI80W0Ov4Sulj0ES8RHttGPoaE6pQ1rg=; b=QY8daeKEt+q9U02UpZ/vl0Y2F8qnQw+PnrXQLz1B5cxBMe2Sx+ik7XWY D3cU/M+oUTMG/pV++8Z5MY5xUbqOWCkx+oIBf+zeznRjuF4hGXoatP4f2 2uVygK43imz1XsBSMc3k1plHrEjljEk9dWkUcA35TvpDxiEZimSGthaDV QfNl9QLQNkaHxJqXLlLJgqhTh0Mu9HuV+sim+mZpr/kKvnQU5dBqQoDB5 hjiQTXWW5X9QZ5DvZegFRUAkNnJddVCZO5zCS8cekpe1xf/HvW6+xY5jR r0liUPwsXHbobhrzqIYz+nh+kyz8ahNP+ONkSIA+vkaptJiTfNWEn7eVI Q==; X-IronPort-AV: E=McAfee;i="6500,9779,10481"; a="287993322" X-IronPort-AV: E=Sophos;i="5.93,344,1654585200"; d="scan'208";a="287993322" Received: from fmsmga006.fm.intel.com ([10.253.24.20]) by orsmga101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 25 Sep 2022 06:07:40 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.93,344,1654585200"; d="scan'208";a="865826216" Received: from shwdeopenlab102.ccr.corp.intel.com ([10.239.56.236]) by fmsmga006.fm.intel.com with ESMTP; 25 Sep 2022 06:07:37 -0700 From: "Jason Lou" To: devel@edk2.groups.io Cc: Jason Lou , Ray Ni , Eric Dong , Laszlo Ersek , Rahul Kumar Subject: [PATCH v1] UefiCpuPkg/Test: Add unit tests for MP service PPI and Protocol Date: Sun, 25 Sep 2022 21:07:30 +0800 Message-Id: <20220925130730.4217-1-yun.lou@intel.com> X-Mailer: git-send-email 2.31.1.windows.1 MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: Jason 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 Cc: Ray Ni Cc: Eric Dong Cc: Laszlo Ersek Cc: Rahul 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.
=0D +=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +=0D +**/=0D +=0D +#include =0D +#include =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.
=0D +=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +=0D +**/=0D +=0D +#include =0D +#include =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.
=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.
=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.
=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.
=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 =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =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