123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477 |
- /** @file
- PEI Module to test APIs defined in EdkiiPeiMpServices2Ppi.
- Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
- **/
- #include <Library/PeimEntryPoint.h>
- #include <Library/PeiServicesLib.h>
- #include "EfiMpServicesUnitTestCommom.h"
- #define UNIT_TEST_NAME "EdkiiPeiMpServices2Ppi Unit Test"
- #define UNIT_TEST_VERSION "0.1"
- /**
- Get EDKII_PEI_MP_SERVICES2_PPI pointer.
- @param[out] MpServices Pointer to the buffer where EDKII_PEI_MP_SERVICES2_PPI is stored.
- @retval EFI_SUCCESS EDKII_PEI_MP_SERVICES2_PPI interface is returned
- @retval EFI_NOT_FOUND EDKII_PEI_MP_SERVICES2_PPI interface is not found
- **/
- EFI_STATUS
- MpServicesUnitTestGetMpServices (
- OUT MP_SERVICES *MpServices
- )
- {
- return PeiServicesLocatePpi (&gEdkiiPeiMpServices2PpiGuid, 0, NULL, (VOID **)&MpServices->Ppi);
- }
- /**
- Retrieve the number of logical processor in the platform and the number of those logical processors that
- are enabled on this boot.
- @param[in] MpServices MP_SERVICES structure.
- @param[out] NumberOfProcessors Pointer to the total number of logical processors in the system, including
- the BSP and disabled APs.
- @param[out] NumberOfEnabledProcessors Pointer to the number of processors in the system that are enabled.
- @retval EFI_SUCCESS Retrieve the number of logical processor successfully
- @retval Others Retrieve the number of logical processor unsuccessfully
- **/
- EFI_STATUS
- MpServicesUnitTestGetNumberOfProcessors (
- IN MP_SERVICES MpServices,
- OUT UINTN *NumberOfProcessors,
- OUT UINTN *NumberOfEnabledProcessors
- )
- {
- return MpServices.Ppi->GetNumberOfProcessors (MpServices.Ppi, NumberOfProcessors, NumberOfEnabledProcessors);
- }
- /**
- Get detailed information on the requested logical processor.
- @param[in] MpServices MP_SERVICES structure.
- @param[in] ProcessorNumber The handle number of the processor.
- @param[out] ProcessorInfoBuffer Pointer to the buffer where the processor information is stored.
- @retval EFI_SUCCESS Get information on the requested logical processor successfully
- @retval Others Get information on the requested logical processor unsuccessfully
- **/
- EFI_STATUS
- MpServicesUnitTestGetProcessorInfo (
- IN MP_SERVICES MpServices,
- IN UINTN ProcessorNumber,
- OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer
- )
- {
- return MpServices.Ppi->GetProcessorInfo (MpServices.Ppi, ProcessorNumber, ProcessorInfoBuffer);
- }
- /**
- Execute a caller provided function on all enabled APs.
- @param[in] MpServices MP_SERVICES structure.
- @param[in] Procedure Pointer to the function to be run on enabled APs of the system.
- @param[in] SingleThread If TRUE, then all the enabled APs execute the function specified by Procedure
- one by one, in ascending order of processor handle number.
- If FALSE, then all the enabled APs execute the function specified by Procedure
- simultaneously.
- @param[in] TimeoutInMicroSeconds Indicates the time limit in microseconds for APs to return from Procedure,
- for blocking mode only. Zero means infinity.
- @param[in] ProcedureArgument The parameter passed into Procedure for all APs.
- @retval EFI_SUCCESS Execute a caller provided function on all enabled APs successfully
- @retval Others Execute a caller provided function on all enabled APs unsuccessfully
- **/
- EFI_STATUS
- MpServicesUnitTestStartupAllAPs (
- IN MP_SERVICES MpServices,
- IN EFI_AP_PROCEDURE Procedure,
- IN BOOLEAN SingleThread,
- IN UINTN TimeoutInMicroSeconds,
- IN VOID *ProcedureArgument
- )
- {
- return MpServices.Ppi->StartupAllAPs (MpServices.Ppi, Procedure, SingleThread, TimeoutInMicroSeconds, ProcedureArgument);
- }
- /**
- Caller gets one enabled AP to execute a caller-provided function.
- @param[in] MpServices MP_SERVICES structure.
- @param[in] Procedure Pointer to the function to be run on enabled APs of the system.
- @param[in] ProcessorNumber The handle number of the AP.
- @param[in] TimeoutInMicroSeconds Indicates the time limit in microseconds for APs to return from Procedure,
- for blocking mode only. Zero means infinity.
- @param[in] ProcedureArgument The parameter passed into Procedure for all APs.
- @retval EFI_SUCCESS Caller gets one enabled AP to execute a caller-provided function successfully
- @retval Others Caller gets one enabled AP to execute a caller-provided function unsuccessfully
- **/
- EFI_STATUS
- MpServicesUnitTestStartupThisAP (
- IN MP_SERVICES MpServices,
- IN EFI_AP_PROCEDURE Procedure,
- IN UINTN ProcessorNumber,
- IN UINTN TimeoutInMicroSeconds,
- IN VOID *ProcedureArgument
- )
- {
- return MpServices.Ppi->StartupThisAP (MpServices.Ppi, Procedure, ProcessorNumber, TimeoutInMicroSeconds, ProcedureArgument);
- }
- /**
- Switch the requested AP to be the BSP from that point onward.
- @param[in] MpServices MP_SERVICES structure.
- @param[in] ProcessorNumber The handle number of AP that is to become the new BSP.
- @param[in] EnableOldBSP If TRUE, the old BSP will be listed as an enabled AP. Otherwise, it will be disabled.
- @retval EFI_SUCCESS Switch the requested AP to be the BSP successfully
- @retval Others Switch the requested AP to be the BSP unsuccessfully
- **/
- EFI_STATUS
- MpServicesUnitTestSwitchBSP (
- IN MP_SERVICES MpServices,
- IN UINTN ProcessorNumber,
- IN BOOLEAN EnableOldBSP
- )
- {
- return MpServices.Ppi->SwitchBSP (MpServices.Ppi, ProcessorNumber, EnableOldBSP);
- }
- /**
- Caller enables or disables an AP from this point onward.
- @param[in] MpServices MP_SERVICES structure.
- @param[in] ProcessorNumber The handle number of the AP.
- @param[in] EnableAP Specifies the new state for the processor for enabled, FALSE for disabled.
- @param[in] HealthFlag If not NULL, a pointer to a value that specifies the new health status of the AP.
- @retval EFI_SUCCESS Caller enables or disables an AP successfully.
- @retval Others Caller enables or disables an AP unsuccessfully.
- **/
- EFI_STATUS
- MpServicesUnitTestEnableDisableAP (
- IN MP_SERVICES MpServices,
- IN UINTN ProcessorNumber,
- IN BOOLEAN EnableAP,
- IN UINT32 *HealthFlag
- )
- {
- return MpServices.Ppi->EnableDisableAP (MpServices.Ppi, ProcessorNumber, EnableAP, HealthFlag);
- }
- /**
- Get the handle number for the calling processor.
- @param[in] MpServices MP_SERVICES structure.
- @param[out] ProcessorNumber The handle number for the calling processor.
- @retval EFI_SUCCESS Get the handle number for the calling processor successfully.
- @retval Others Get the handle number for the calling processor unsuccessfully.
- **/
- EFI_STATUS
- MpServicesUnitTestWhoAmI (
- IN MP_SERVICES MpServices,
- OUT UINTN *ProcessorNumber
- )
- {
- return MpServices.Ppi->WhoAmI (MpServices.Ppi, ProcessorNumber);
- }
- /**
- Execute a caller provided function on all enabled CPUs.
- @param[in] MpServices MP_SERVICES structure.
- @param[in] Procedure Pointer to the function to be run on enabled CPUs of the system.
- @param[in] TimeoutInMicroSeconds Indicates the time limit in microseconds for APs to return from Procedure,
- for blocking mode only. Zero means infinity.
- @param[in] ProcedureArgument The parameter passed into Procedure for all enabled CPUs.
- @retval EFI_SUCCESS Execute a caller provided function on all enabled CPUs successfully
- @retval Others Execute a caller provided function on all enabled CPUs unsuccessfully
- **/
- EFI_STATUS
- MpServicesUnitTestStartupAllCPUs (
- IN MP_SERVICES MpServices,
- IN EFI_AP_PROCEDURE Procedure,
- IN UINTN TimeoutInMicroSeconds,
- IN VOID *ProcedureArgument
- )
- {
- return MpServices.Ppi->StartupAllCPUs (MpServices.Ppi, Procedure, TimeoutInMicroSeconds, ProcedureArgument);
- }
- /**
- Infinite loop procedure to be run on specified AP.
- @param[in,out] Buffer The pointer to private data buffer.
- **/
- VOID
- ApInfiniteLoopProcedure (
- IN OUT VOID *Buffer
- )
- {
- EFI_STATUS Status;
- UINTN ProcessorNumber;
- volatile BOOLEAN InfiniteLoop;
- MP_SERVICE_UT_CONTEXT *LocalContext;
- LocalContext = (MP_SERVICE_UT_CONTEXT *)Buffer;
- Status = MpServicesUnitTestWhoAmI (LocalContext->MpServices, &ProcessorNumber);
- ASSERT_EFI_ERROR (Status);
- if (ProcessorNumber == LocalContext->BspNumber) {
- InfiniteLoop = FALSE;
- } else {
- InfiniteLoop = TRUE;
- }
- while (InfiniteLoop) {
- }
- }
- /**
- Procedure to run MP service StartupAllCPUs on AP.
- @param[in,out] Buffer The pointer to private data buffer.
- **/
- VOID
- RunMpServiceStartupAllCPUsOnAp (
- IN OUT VOID *Buffer
- )
- {
- MP_SERVICE_UT_CONTEXT *LocalContext;
- LocalContext = (MP_SERVICE_UT_CONTEXT *)Buffer;
- LocalContext->ApProcedureReturnStatus = MpServicesUnitTestStartupAllCPUs (
- LocalContext->MpServices,
- (EFI_AP_PROCEDURE)EmptyProcedure,
- 0,
- NULL
- );
- }
- /**
- Unit test of PEI MP service StartupAllCPU.
- All CPUs should execute the Procedure.
- @param[in] Context Context pointer for this test.
- @retval UNIT_TEST_PASSED The Unit test has completed and the test
- case was successful.
- @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.
- **/
- UNIT_TEST_STATUS
- EFIAPI
- TestStartupAllCPUs1 (
- IN UNIT_TEST_CONTEXT Context
- )
- {
- EFI_STATUS Status;
- UINTN ProcessorIndex;
- MP_SERVICE_UT_CONTEXT *LocalContext;
- LocalContext = (MP_SERVICE_UT_CONTEXT *)Context;
- SetMem (LocalContext->CommonBuffer, LocalContext->NumberOfProcessors * sizeof (*LocalContext->CommonBuffer), 0xFF);
- Status = MpServicesUnitTestStartupAllCPUs (
- LocalContext->MpServices,
- (EFI_AP_PROCEDURE)StoreCpuNumbers,
- 0,
- (VOID *)LocalContext
- );
- UT_ASSERT_NOT_EFI_ERROR (Status);
- for (ProcessorIndex = 0; ProcessorIndex < LocalContext->NumberOfProcessors; ProcessorIndex++) {
- UT_ASSERT_TRUE (LocalContext->CommonBuffer[ProcessorIndex] == ProcessorIndex);
- }
- return UNIT_TEST_PASSED;
- }
- /**
- Unit test of PEI MP service StartupAllCPU.
- When this service is called from an AP, the return status should be EFI_DEVICE_ERROR.
- @param[in] Context Context pointer for this test.
- @retval UNIT_TEST_PASSED The Unit test has completed and the test
- case was successful.
- @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.
- **/
- UNIT_TEST_STATUS
- EFIAPI
- TestStartupAllCPUs2 (
- IN UNIT_TEST_CONTEXT Context
- )
- {
- EFI_STATUS Status;
- UINTN ApNumber;
- MP_SERVICE_UT_CONTEXT *LocalContext;
- LocalContext = (MP_SERVICE_UT_CONTEXT *)Context;
- for (ApNumber = 0; ApNumber < LocalContext->NumberOfProcessors; ApNumber++) {
- LocalContext->ApNumber = ApNumber;
- Status = MpServicesUnitTestStartupThisAP (
- LocalContext->MpServices,
- (EFI_AP_PROCEDURE)RunMpServiceStartupAllCPUsOnAp,
- ApNumber,
- 0,
- (VOID *)LocalContext
- );
- if (ApNumber == LocalContext->BspNumber) {
- UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER);
- } else {
- UT_ASSERT_NOT_EFI_ERROR (Status);
- UT_ASSERT_STATUS_EQUAL (LocalContext->ApProcedureReturnStatus, EFI_DEVICE_ERROR);
- }
- }
- return UNIT_TEST_PASSED;
- }
- /**
- Unit test of PEI MP service StartupAllCPU.
- When called with all CPUs timeout, the return status should be EFI_TIMEOUT.
- @param[in] Context Context pointer for this test.
- @retval UNIT_TEST_PASSED The Unit test has completed and the test
- case was successful.
- @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.
- **/
- UNIT_TEST_STATUS
- EFIAPI
- TestStartupAllCPUs3 (
- IN UNIT_TEST_CONTEXT Context
- )
- {
- EFI_STATUS Status;
- MP_SERVICE_UT_CONTEXT *LocalContext;
- LocalContext = (MP_SERVICE_UT_CONTEXT *)Context;
- Status = MpServicesUnitTestStartupAllCPUs (
- LocalContext->MpServices,
- (EFI_AP_PROCEDURE)ApInfiniteLoopProcedure,
- RUN_PROCEDURE_TIMEOUT_VALUE,
- (VOID *)LocalContext
- );
- UT_ASSERT_STATUS_EQUAL (Status, EFI_TIMEOUT);
- return UNIT_TEST_PASSED;
- }
- /**
- Create test suite and unit tests only for EdkiiPeiMpServices2Ppi.
- @param[in] Framework A pointer to the framework that is being persisted.
- @param[in] Context A pointer to the private data buffer.
- @retval EFI_SUCCESS Create test suite and unit tests successfully.
- @retval Others Create test suite and unit tests unsuccessfully.
- **/
- EFI_STATUS
- AddTestCaseOnlyForEdkiiPeiMpServices2Ppi (
- IN UNIT_TEST_FRAMEWORK_HANDLE Framework,
- IN MP_SERVICE_UT_CONTEXT *Context
- )
- {
- EFI_STATUS Status;
- UNIT_TEST_SUITE_HANDLE MpServiceStartupAllCPUsTestSuite;
- MpServiceStartupAllCPUsTestSuite = NULL;
- //
- // Test StartupAllCPUs function
- //
- Status = CreateUnitTestSuite (&MpServiceStartupAllCPUsTestSuite, Framework, "Execute a caller provided function on all enabled CPUs", "MpServices.StartupAllCPUs", NULL, NULL);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for MpServiceStartupAllCPUs Test Suite\n"));
- return Status;
- }
- AddTestCase (MpServiceStartupAllCPUsTestSuite, "Test StartupAllCPUs 1", "TestStartupAllCPUs1", TestStartupAllCPUs1, InitUTContext, CheckUTContext, Context);
- AddTestCase (MpServiceStartupAllCPUsTestSuite, "Test StartupAllCPUs 2", "TestStartupAllCPUs2", TestStartupAllCPUs2, InitUTContext, CheckUTContext, Context);
- AddTestCase (MpServiceStartupAllCPUsTestSuite, "Test StartupAllCPUs 3", "TestStartupAllCPUs3", TestStartupAllCPUs3, InitUTContext, CheckUTContext, Context);
- return EFI_SUCCESS;
- }
- /**
- Standard PEIM entry point for unit test execution from PEI.
- Initialize the unit test framework, suite, and unit tests for the EdkiiPeiMpServices2Ppi and run the unit test.
- @param[in] FileHandle Handle of the file being invoked.
- @param[in] PeiServices Pointer to PEI Services table.
- **/
- EFI_STATUS
- EFIAPI
- PeiEntryPoint (
- IN EFI_PEI_FILE_HANDLE FileHandle,
- IN CONST EFI_PEI_SERVICES **PeiServices
- )
- {
- EFI_STATUS Status;
- UNIT_TEST_FRAMEWORK_HANDLE Framework;
- MP_SERVICE_UT_CONTEXT Context;
- Framework = NULL;
- Context.MpServices.Ppi = NULL;
- Context.CommonBuffer = NULL;
- Context.DisabledApNumber = NULL;
- DEBUG ((DEBUG_INFO, "%a v%a\n", UNIT_TEST_NAME, UNIT_TEST_VERSION));
- //
- // Start setting up the test framework for running the tests.
- //
- Status = InitUnitTestFramework (&Framework, UNIT_TEST_NAME, gEfiCallerBaseName, UNIT_TEST_VERSION);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "Failed in InitUnitTestFramework. Status = %r\n", Status));
- goto EXIT;
- }
- //
- // Create test suite and unit tests only for EdkiiPeiMpServices2Ppi.
- //
- Status = AddTestCaseOnlyForEdkiiPeiMpServices2Ppi (Framework, &Context);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "Failed in AddTestCaseOnlyForEdkiiPeiMpServices2Ppi. Status = %r\n", Status));
- goto EXIT;
- }
- //
- // Create test suite and unit tests for both EdkiiPeiMpServices2Ppi and EfiMpServiceProtocol.
- //
- Status = AddCommonTestCase (Framework, &Context);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "Failed in AddCommonTestCase. Status = %r\n", Status));
- goto EXIT;
- }
- //
- // Execute the tests.
- //
- Status = RunAllTestSuites (Framework);
- EXIT:
- if (Framework != NULL) {
- FreeUnitTestFramework (Framework);
- }
- return Status;
- }
|