--- /dev/null
+/** @file\r
+ Common code to test EdkiiPeiMpServices2Ppi and EfiMpServiceProtocol.\r
+\r
+ Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>\r
+\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#include "EfiMpServicesUnitTestCommom.h"\r
+\r
+/**\r
+ Prep routine for Unit test function.\r
+ To save the ProcessorNumber of disabled AP and temporarily enable it.\r
+\r
+ @param[in] Context Context pointer for this test.\r
+\r
+ @retval UNIT_TEST_PASSED Prep routine runs successful.\r
+ @retval UNIT_TEST_ERROR_TEST_FAILED Prep routine runs unsuccessful.\r
+**/\r
+UNIT_TEST_STATUS\r
+EFIAPI\r
+InitUTContext (\r
+ IN UNIT_TEST_CONTEXT Context\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN NumberOfProcessors;\r
+ UINTN NumberOfEnabledProcessors;\r
+ UINTN NumberOfDisabledAPs;\r
+ UINTN IndexOfDisabledAPs;\r
+ UINTN BspNumber;\r
+ UINTN ProcessorNumber;\r
+ EFI_PROCESSOR_INFORMATION ProcessorInfoBuffer;\r
+ MP_SERVICE_UT_CONTEXT *LocalContext;\r
+\r
+ LocalContext = (MP_SERVICE_UT_CONTEXT *)Context;\r
+\r
+ if (LocalContext->MpServices.Ppi != NULL) {\r
+ return UNIT_TEST_PASSED;\r
+ }\r
+\r
+ Status = MpServicesUnitTestGetMpServices (&LocalContext->MpServices);\r
+ UT_ASSERT_NOT_EFI_ERROR (Status);\r
+\r
+ Status = MpServicesUnitTestWhoAmI (LocalContext->MpServices, &BspNumber);\r
+ UT_ASSERT_NOT_EFI_ERROR (Status);\r
+ DEBUG ((DEBUG_INFO, "%a: BspNumber = 0x%x\n", __FUNCTION__, BspNumber));\r
+\r
+ Status = MpServicesUnitTestGetNumberOfProcessors (\r
+ LocalContext->MpServices,\r
+ &NumberOfProcessors,\r
+ &NumberOfEnabledProcessors\r
+ );\r
+ UT_ASSERT_NOT_EFI_ERROR (Status);\r
+ DEBUG ((\r
+ DEBUG_INFO,\r
+ "%a: NumberOfProcessors = 0x%x, NumberOfEnabledProcessors = 0x%x\n",\r
+ __FUNCTION__,\r
+ NumberOfProcessors,\r
+ NumberOfEnabledProcessors\r
+ ));\r
+\r
+ LocalContext->BspNumber = BspNumber;\r
+ LocalContext->NumberOfProcessors = NumberOfProcessors;\r
+ LocalContext->NumberOfEnabledProcessors = NumberOfEnabledProcessors;\r
+\r
+ LocalContext->CommonBuffer = AllocatePages (EFI_SIZE_TO_PAGES (NumberOfProcessors * sizeof (*LocalContext->CommonBuffer)));\r
+ UT_ASSERT_NOT_NULL (LocalContext->CommonBuffer);\r
+\r
+ NumberOfDisabledAPs = NumberOfProcessors - NumberOfEnabledProcessors;\r
+ if ((NumberOfDisabledAPs > 0) && (LocalContext->DisabledApNumber == NULL)) {\r
+ LocalContext->DisabledApNumber = AllocatePages (EFI_SIZE_TO_PAGES (NumberOfDisabledAPs * sizeof (*LocalContext->DisabledApNumber)));\r
+ UT_ASSERT_NOT_NULL (LocalContext->DisabledApNumber);\r
+ ZeroMem (LocalContext->DisabledApNumber, NumberOfDisabledAPs * sizeof (*LocalContext->DisabledApNumber));\r
+\r
+ for (ProcessorNumber = 0, IndexOfDisabledAPs = 0; ProcessorNumber < LocalContext->NumberOfProcessors; ProcessorNumber++) {\r
+ Status = MpServicesUnitTestGetProcessorInfo (\r
+ LocalContext->MpServices,\r
+ ProcessorNumber,\r
+ &ProcessorInfoBuffer\r
+ );\r
+ UT_ASSERT_NOT_EFI_ERROR (Status);\r
+\r
+ if (!(ProcessorInfoBuffer.StatusFlag & PROCESSOR_ENABLED_BIT)) {\r
+ //\r
+ // Save ProcessorNumber of disabled AP.\r
+ //\r
+ LocalContext->DisabledApNumber[IndexOfDisabledAPs] = ProcessorNumber;\r
+ IndexOfDisabledAPs++;\r
+\r
+ DEBUG ((DEBUG_INFO, "%a: AP(0x%x) is disabled and temporarily enable it.\n", __FUNCTION__, ProcessorNumber));\r
+ Status = MpServicesUnitTestEnableDisableAP (\r
+ LocalContext->MpServices,\r
+ ProcessorNumber,\r
+ TRUE,\r
+ NULL\r
+ );\r
+ UT_ASSERT_NOT_EFI_ERROR (Status);\r
+ }\r
+ }\r
+\r
+ UT_ASSERT_TRUE (IndexOfDisabledAPs == NumberOfDisabledAPs);\r
+ }\r
+\r
+ return UNIT_TEST_PASSED;\r
+}\r
+\r
+/**\r
+ Cleanup routine for Unit test function.\r
+ If any processor is disabled unexpectedly then reenable it.\r
+\r
+ @param[in] Context Context pointer for this test.\r
+**/\r
+VOID\r
+EFIAPI\r
+CheckUTContext (\r
+ IN UNIT_TEST_CONTEXT Context\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN NumberOfProcessors;\r
+ UINTN NumberOfEnabledProcessors;\r
+ UINTN BspNumber;\r
+ UINTN ProcessorNumber;\r
+ EFI_PROCESSOR_INFORMATION ProcessorInfoBuffer;\r
+ MP_SERVICE_UT_CONTEXT *LocalContext;\r
+\r
+ LocalContext = (MP_SERVICE_UT_CONTEXT *)Context;\r
+ ASSERT (LocalContext->MpServices.Ppi != NULL);\r
+\r
+ Status = MpServicesUnitTestWhoAmI (LocalContext->MpServices, &BspNumber);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ if (BspNumber != LocalContext->BspNumber) {\r
+ LocalContext->BspNumber = BspNumber;\r
+ DEBUG ((DEBUG_INFO, "%a: New BspNumber = 0x%x\n", __FUNCTION__, BspNumber));\r
+ }\r
+\r
+ ASSERT (BspNumber == LocalContext->BspNumber);\r
+\r
+ Status = MpServicesUnitTestGetNumberOfProcessors (\r
+ LocalContext->MpServices,\r
+ &NumberOfProcessors,\r
+ &NumberOfEnabledProcessors\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ if (NumberOfProcessors != LocalContext->NumberOfProcessors) {\r
+ LocalContext->NumberOfProcessors = NumberOfProcessors;\r
+ DEBUG ((DEBUG_INFO, "%a: New NumberOfProcessors = 0x%x\n", __FUNCTION__, NumberOfProcessors));\r
+ }\r
+\r
+ if (NumberOfEnabledProcessors != LocalContext->NumberOfProcessors) {\r
+ DEBUG ((DEBUG_INFO, "%a: New NumberOfEnabledProcessors = 0x%x\n", __FUNCTION__, NumberOfEnabledProcessors));\r
+\r
+ for (ProcessorNumber = 0; ProcessorNumber < LocalContext->NumberOfProcessors; ProcessorNumber++) {\r
+ Status = MpServicesUnitTestGetProcessorInfo (\r
+ LocalContext->MpServices,\r
+ ProcessorNumber,\r
+ &ProcessorInfoBuffer\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ if (!(ProcessorInfoBuffer.StatusFlag & PROCESSOR_ENABLED_BIT)) {\r
+ DEBUG ((DEBUG_INFO, "%a: AP(0x%x) is disabled unexpectedly and reenable it.\n", __FUNCTION__, ProcessorNumber));\r
+ Status = MpServicesUnitTestEnableDisableAP (\r
+ LocalContext->MpServices,\r
+ ProcessorNumber,\r
+ TRUE,\r
+ NULL\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+ }\r
+ }\r
+ }\r
+}\r
+\r
+/**\r
+ Cleanup routine for Unit test function.\r
+ It will be called by the last "AddTestCase" to restore AP state and free pointer.\r
+\r
+ @param[in] Context Context pointer for this test.\r
+**/\r
+VOID\r
+EFIAPI\r
+FreeUTContext (\r
+ IN UNIT_TEST_CONTEXT Context\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN NumberOfDisabledAPs;\r
+ UINTN IndexOfDisabledAPs;\r
+ MP_SERVICE_UT_CONTEXT *LocalContext;\r
+\r
+ CheckUTContext (Context);\r
+\r
+ LocalContext = (MP_SERVICE_UT_CONTEXT *)Context;\r
+ ASSERT (LocalContext->MpServices.Ppi != NULL);\r
+\r
+ if (LocalContext->DisabledApNumber != NULL) {\r
+ NumberOfDisabledAPs = LocalContext->NumberOfProcessors - LocalContext->NumberOfEnabledProcessors;\r
+ for (IndexOfDisabledAPs = 0; IndexOfDisabledAPs < NumberOfDisabledAPs; IndexOfDisabledAPs++) {\r
+ DEBUG ((\r
+ DEBUG_INFO,\r
+ "%a: Disable AP(0x%x) to restore its state.\n",\r
+ __FUNCTION__,\r
+ LocalContext->DisabledApNumber[IndexOfDisabledAPs]\r
+ ));\r
+\r
+ Status = MpServicesUnitTestEnableDisableAP (\r
+ LocalContext->MpServices,\r
+ LocalContext->DisabledApNumber[IndexOfDisabledAPs],\r
+ FALSE,\r
+ NULL\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+ }\r
+\r
+ FreePages (LocalContext->DisabledApNumber, EFI_SIZE_TO_PAGES (NumberOfDisabledAPs * sizeof (*LocalContext->DisabledApNumber)));\r
+ }\r
+\r
+ if (LocalContext->CommonBuffer != NULL) {\r
+ FreePages (LocalContext->CommonBuffer, EFI_SIZE_TO_PAGES (LocalContext->NumberOfProcessors * sizeof (*LocalContext->CommonBuffer)));\r
+ }\r
+}\r
+\r
+/**\r
+ Produce to store ProcessorNumber in the corresponding location of CommonBuffer.\r
+\r
+ @param[in,out] Buffer The pointer to private data buffer.\r
+**/\r
+VOID\r
+StoreCpuNumbers (\r
+ IN OUT VOID *Buffer\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN ProcessorNumber;\r
+ MP_SERVICE_UT_CONTEXT *LocalContext;\r
+\r
+ LocalContext = (MP_SERVICE_UT_CONTEXT *)Buffer;\r
+\r
+ Status = MpServicesUnitTestWhoAmI (LocalContext->MpServices, &ProcessorNumber);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ //\r
+ // The layout of CommonBuffer (E.g. BspNumber = 2 and NumberOfProcessors = 6)\r
+ // Index 00 01 02 03 04 05\r
+ // Value 00 01 02 03 04 05\r
+ //\r
+ if (ProcessorNumber < LocalContext->NumberOfProcessors) {\r
+ LocalContext->CommonBuffer[ProcessorNumber] = ProcessorNumber;\r
+ }\r
+}\r
+\r
+/**\r
+ Produce to store the ProcessorNumber of AP execution order in CommonBuffer.\r
+\r
+ @param[in,out] Buffer The pointer to private data buffer.\r
+**/\r
+VOID\r
+StoreAPsExecutionOrder (\r
+ IN OUT VOID *Buffer\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN ProcessorNumber;\r
+ UINTN *ApCounter;\r
+ MP_SERVICE_UT_CONTEXT *LocalContext;\r
+\r
+ LocalContext = (MP_SERVICE_UT_CONTEXT *)Buffer;\r
+\r
+ Status = MpServicesUnitTestWhoAmI (LocalContext->MpServices, &ProcessorNumber);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ //\r
+ // The layout of CommonBuffer (E.g. BspNumber = 2 and NumberOfProcessors = 6)\r
+ // Index 00 01 02 03 04 05\r
+ // Value 00 01 03 04 05 ApCounter(5)\r
+ //\r
+ ApCounter = &(LocalContext->CommonBuffer[LocalContext->NumberOfProcessors - 1]);\r
+ LocalContext->CommonBuffer[*ApCounter] = ProcessorNumber;\r
+ (*ApCounter)++;\r
+}\r
+\r
+/**\r
+ Infinite loop procedure to be run on specified CPU.\r
+\r
+ @param[in,out] Buffer The pointer to private data buffer.\r
+**/\r
+VOID\r
+InfiniteLoopProcedure (\r
+ IN OUT VOID *Buffer\r
+ )\r
+{\r
+ volatile BOOLEAN InfiniteLoop;\r
+\r
+ InfiniteLoop = TRUE;\r
+\r
+ while (InfiniteLoop) {\r
+ }\r
+}\r
+\r
+/**\r
+ Empty procedure to be run on specified CPU.\r
+\r
+ @param[in,out] Buffer The pointer to private data buffer.\r
+**/\r
+VOID\r
+EmptyProcedure (\r
+ IN OUT VOID *Buffer\r
+ )\r
+{\r
+}\r
+\r
+/**\r
+ Procedure to run MP service GetNumberOfProcessors on AP.\r
+\r
+ @param[in,out] Buffer The pointer to private data buffer.\r
+**/\r
+VOID\r
+RunMpServiceGetNumberOfProcessorsOnAp (\r
+ IN OUT VOID *Buffer\r
+ )\r
+{\r
+ UINTN NumberOfProcessors;\r
+ UINTN NumberOfEnabledProcessors;\r
+ MP_SERVICE_UT_CONTEXT *LocalContext;\r
+\r
+ LocalContext = (MP_SERVICE_UT_CONTEXT *)Buffer;\r
+\r
+ LocalContext->ApProcedureReturnStatus = MpServicesUnitTestGetNumberOfProcessors (\r
+ LocalContext->MpServices,\r
+ &NumberOfProcessors,\r
+ &NumberOfEnabledProcessors\r
+ );\r
+}\r
+\r
+/**\r
+ Procedure to run MP service GetProcessorInfo on AP.\r
+\r
+ @param[in,out] Buffer The pointer to private data buffer.\r
+**/\r
+VOID\r
+RunMpServiceGetProcessorInfoOnAp (\r
+ IN OUT VOID *Buffer\r
+ )\r
+{\r
+ EFI_PROCESSOR_INFORMATION ProcessorInfoBuffer;\r
+ MP_SERVICE_UT_CONTEXT *LocalContext;\r
+\r
+ LocalContext = (MP_SERVICE_UT_CONTEXT *)Buffer;\r
+\r
+ LocalContext->ApProcedureReturnStatus = MpServicesUnitTestGetProcessorInfo (\r
+ LocalContext->MpServices,\r
+ LocalContext->ApNumber,\r
+ &ProcessorInfoBuffer\r
+ );\r
+}\r
+\r
+/**\r
+ Procedure to run MP service EnableDisableAP on AP.\r
+\r
+ @param[in,out] Buffer The pointer to private data buffer.\r
+**/\r
+VOID\r
+RunMpServiceEnableDisableAPOnAp (\r
+ IN OUT VOID *Buffer\r
+ )\r
+{\r
+ MP_SERVICE_UT_CONTEXT *LocalContext;\r
+\r
+ LocalContext = (MP_SERVICE_UT_CONTEXT *)Buffer;\r
+\r
+ LocalContext->ApProcedureReturnStatus = MpServicesUnitTestEnableDisableAP (\r
+ LocalContext->MpServices,\r
+ LocalContext->ApNumber,\r
+ FALSE,\r
+ NULL\r
+ );\r
+}\r
+\r
+/**\r
+ Procedure to run MP service StartupThisAP on AP.\r
+\r
+ @param[in,out] Buffer The pointer to private data buffer.\r
+**/\r
+VOID\r
+RunMpServiceStartupThisAPOnAp (\r
+ IN OUT VOID *Buffer\r
+ )\r
+{\r
+ MP_SERVICE_UT_CONTEXT *LocalContext;\r
+\r
+ LocalContext = (MP_SERVICE_UT_CONTEXT *)Buffer;\r
+\r
+ LocalContext->ApProcedureReturnStatus = MpServicesUnitTestStartupThisAP (\r
+ LocalContext->MpServices,\r
+ (EFI_AP_PROCEDURE)EmptyProcedure,\r
+ LocalContext->ApNumber,\r
+ 0,\r
+ NULL\r
+ );\r
+}\r
+\r
+/**\r
+ Procedure to run MP service StartupAllAPs on AP.\r
+\r
+ @param[in,out] Buffer The pointer to private data buffer.\r
+**/\r
+VOID\r
+RunMpServiceStartupAllAPsOnAp (\r
+ IN OUT VOID *Buffer\r
+ )\r
+{\r
+ MP_SERVICE_UT_CONTEXT *LocalContext;\r
+\r
+ LocalContext = (MP_SERVICE_UT_CONTEXT *)Buffer;\r
+\r
+ LocalContext->ApProcedureReturnStatus = MpServicesUnitTestStartupAllAPs (\r
+ LocalContext->MpServices,\r
+ (EFI_AP_PROCEDURE)EmptyProcedure,\r
+ FALSE,\r
+ 0,\r
+ NULL\r
+ );\r
+}\r
+\r
+/**\r
+ Procedure to run MP service SwitchBSP on AP.\r
+\r
+ @param[in,out] Buffer The pointer to private data buffer.\r
+**/\r
+VOID\r
+RunMpServiceSwitchBSPOnAp (\r
+ IN OUT VOID *Buffer\r
+ )\r
+{\r
+ MP_SERVICE_UT_CONTEXT *LocalContext;\r
+\r
+ LocalContext = (MP_SERVICE_UT_CONTEXT *)Buffer;\r
+\r
+ LocalContext->ApProcedureReturnStatus = MpServicesUnitTestSwitchBSP (\r
+ LocalContext->MpServices,\r
+ LocalContext->ApNumber,\r
+ TRUE\r
+ );\r
+}\r
+\r
+/**\r
+ Unit test of MP service WhoAmI.\r
+ The range of ProcessorNumber should be from 0 to NumberOfCPUs minus 1.\r
+ The ProcessorNumbers of all CPUs are unique.\r
+\r
+ @param[in] Context Context pointer for this test.\r
+\r
+ @retval UNIT_TEST_PASSED The Unit test has completed and the test\r
+ case was successful.\r
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.\r
+**/\r
+UNIT_TEST_STATUS\r
+EFIAPI\r
+TestWhoAmI1 (\r
+ IN UNIT_TEST_CONTEXT Context\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN ProcessorNumber;\r
+ UINTN ProcessorIndex;\r
+ MP_SERVICE_UT_CONTEXT *LocalContext;\r
+\r
+ LocalContext = (MP_SERVICE_UT_CONTEXT *)Context;\r
+\r
+ Status = MpServicesUnitTestWhoAmI (\r
+ LocalContext->MpServices,\r
+ &ProcessorNumber\r
+ );\r
+ UT_ASSERT_NOT_EFI_ERROR (Status);\r
+ UT_ASSERT_TRUE (ProcessorNumber < LocalContext->NumberOfProcessors);\r
+\r
+ SetMem (LocalContext->CommonBuffer, LocalContext->NumberOfProcessors * sizeof (*LocalContext->CommonBuffer), 0xFF);\r
+ LocalContext->CommonBuffer[ProcessorNumber] = ProcessorNumber;\r
+\r
+ Status = MpServicesUnitTestStartupAllAPs (\r
+ LocalContext->MpServices,\r
+ (EFI_AP_PROCEDURE)StoreCpuNumbers,\r
+ FALSE,\r
+ 0,\r
+ (VOID *)LocalContext\r
+ );\r
+ UT_ASSERT_NOT_EFI_ERROR (Status);\r
+\r
+ //\r
+ // The layout of CommonBuffer (E.g. BspNumber = 2 and NumberOfProcessors = 6)\r
+ // Index 00 01 02 03 04 05\r
+ // Value 00 01 02 03 04 05\r
+ //\r
+ for (ProcessorIndex = 0; ProcessorIndex < LocalContext->NumberOfProcessors; ProcessorIndex++) {\r
+ UT_ASSERT_TRUE (LocalContext->CommonBuffer[ProcessorIndex] == ProcessorIndex);\r
+ }\r
+\r
+ return UNIT_TEST_PASSED;\r
+}\r
+\r
+/**\r
+ Unit test of MP service GetNumberOfProcessors.\r
+ NumberOfProcessors should be greater that 0 and not less than NumberOfEnabledProcessors.\r
+\r
+ @param[in] Context Context pointer for this test.\r
+\r
+ @retval UNIT_TEST_PASSED The Unit test has completed and the test\r
+ case was successful.\r
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.\r
+**/\r
+UNIT_TEST_STATUS\r
+EFIAPI\r
+TestGetNumberOfProcessors1 (\r
+ IN UNIT_TEST_CONTEXT Context\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN NumberOfProcessors;\r
+ UINTN NumberOfEnabledProcessors;\r
+ MP_SERVICE_UT_CONTEXT *LocalContext;\r
+\r
+ LocalContext = (MP_SERVICE_UT_CONTEXT *)Context;\r
+\r
+ Status = MpServicesUnitTestGetNumberOfProcessors (\r
+ LocalContext->MpServices,\r
+ &NumberOfProcessors,\r
+ &NumberOfEnabledProcessors\r
+ );\r
+ UT_ASSERT_NOT_EFI_ERROR (Status);\r
+ UT_ASSERT_TRUE (NumberOfProcessors > 0 && NumberOfProcessors >= NumberOfEnabledProcessors);\r
+\r
+ return UNIT_TEST_PASSED;\r
+}\r
+\r
+/**\r
+ Unit test of MP service GetNumberOfProcessors.\r
+ When this service is called from an AP, the return status should be EFI_DEVICE_ERROR.\r
+\r
+ @param[in] Context Context pointer for this test.\r
+\r
+ @retval UNIT_TEST_PASSED The Unit test has completed and the test\r
+ case was successful.\r
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.\r
+**/\r
+UNIT_TEST_STATUS\r
+EFIAPI\r
+TestGetNumberOfProcessors2 (\r
+ IN UNIT_TEST_CONTEXT Context\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN ApNumber;\r
+ MP_SERVICE_UT_CONTEXT *LocalContext;\r
+\r
+ LocalContext = (MP_SERVICE_UT_CONTEXT *)Context;\r
+\r
+ for (ApNumber = 0; ApNumber < LocalContext->NumberOfProcessors; ApNumber++) {\r
+ LocalContext->ApNumber = ApNumber;\r
+ Status = MpServicesUnitTestStartupThisAP (\r
+ LocalContext->MpServices,\r
+ (EFI_AP_PROCEDURE)RunMpServiceGetNumberOfProcessorsOnAp,\r
+ ApNumber,\r
+ 0,\r
+ (VOID *)LocalContext\r
+ );\r
+\r
+ if (ApNumber == LocalContext->BspNumber) {\r
+ UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER);\r
+ } else {\r
+ UT_ASSERT_NOT_EFI_ERROR (Status);\r
+ UT_ASSERT_STATUS_EQUAL (LocalContext->ApProcedureReturnStatus, EFI_DEVICE_ERROR);\r
+ }\r
+ }\r
+\r
+ return UNIT_TEST_PASSED;\r
+}\r
+\r
+/**\r
+ Unit test of MP service GetNumberOfProcessors.\r
+ Call EnableDisableAP() to change the number of enabled AP.\r
+\r
+ @param[in] Context Context pointer for this test.\r
+\r
+ @retval UNIT_TEST_PASSED The Unit test has completed and the test\r
+ case was successful.\r
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.\r
+**/\r
+UNIT_TEST_STATUS\r
+EFIAPI\r
+TestGetNumberOfProcessors3 (\r
+ IN UNIT_TEST_CONTEXT Context\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN ApNumber;\r
+ UINTN NumberOfProcessors;\r
+ UINTN NumberOfEnabledProcessors;\r
+ MP_SERVICE_UT_CONTEXT *LocalContext;\r
+\r
+ LocalContext = (MP_SERVICE_UT_CONTEXT *)Context;\r
+\r
+ for (ApNumber = 0; ApNumber < LocalContext->NumberOfProcessors; ApNumber++) {\r
+ Status = MpServicesUnitTestEnableDisableAP (\r
+ LocalContext->MpServices,\r
+ ApNumber,\r
+ FALSE,\r
+ NULL\r
+ );\r
+\r
+ if (ApNumber == LocalContext->BspNumber) {\r
+ UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER);\r
+ } else {\r
+ UT_ASSERT_NOT_EFI_ERROR (Status);\r
+\r
+ Status = MpServicesUnitTestGetNumberOfProcessors (\r
+ LocalContext->MpServices,\r
+ &NumberOfProcessors,\r
+ &NumberOfEnabledProcessors\r
+ );\r
+ UT_ASSERT_NOT_EFI_ERROR (Status);\r
+ UT_ASSERT_TRUE (NumberOfProcessors == LocalContext->NumberOfProcessors);\r
+\r
+ if (ApNumber < LocalContext->BspNumber) {\r
+ UT_ASSERT_TRUE (NumberOfEnabledProcessors == LocalContext->NumberOfProcessors - (ApNumber + 1));\r
+ } else {\r
+ UT_ASSERT_TRUE (NumberOfEnabledProcessors == LocalContext->NumberOfProcessors - ApNumber);\r
+ }\r
+ }\r
+ }\r
+\r
+ for (ApNumber = 0; ApNumber < LocalContext->NumberOfProcessors; ApNumber++) {\r
+ Status = MpServicesUnitTestEnableDisableAP (\r
+ LocalContext->MpServices,\r
+ ApNumber,\r
+ TRUE,\r
+ NULL\r
+ );\r
+\r
+ if (ApNumber == LocalContext->BspNumber) {\r
+ UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER);\r
+ } else {\r
+ UT_ASSERT_NOT_EFI_ERROR (Status);\r
+\r
+ Status = MpServicesUnitTestGetNumberOfProcessors (\r
+ LocalContext->MpServices,\r
+ &NumberOfProcessors,\r
+ &NumberOfEnabledProcessors\r
+ );\r
+ UT_ASSERT_NOT_EFI_ERROR (Status);\r
+ UT_ASSERT_TRUE (NumberOfProcessors == LocalContext->NumberOfProcessors);\r
+\r
+ if (ApNumber < LocalContext->BspNumber) {\r
+ UT_ASSERT_TRUE (NumberOfEnabledProcessors == ApNumber + 2);\r
+ } else {\r
+ UT_ASSERT_TRUE (NumberOfEnabledProcessors == ApNumber + 1);\r
+ }\r
+ }\r
+ }\r
+\r
+ return UNIT_TEST_PASSED;\r
+}\r
+\r
+/**\r
+ Unit test of MP service GetProcessorInfo.\r
+ When all the parameters are valid, all reserved bits of StatusFlag in ProcessorInfoBuffer should be set to zero.\r
+ When all the parameters are valid, the StatusFlag should not have an invalid value (The BSP can never be in the disabled state.).\r
+ When called with nonexistent processor handle, the return status should be EFI_NOT_FOUND.\r
+\r
+ @param[in] Context Context pointer for this test.\r
+\r
+ @retval UNIT_TEST_PASSED The Unit test has completed and the test\r
+ case was successful.\r
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.\r
+**/\r
+UNIT_TEST_STATUS\r
+EFIAPI\r
+TestGetProcessorInfo1 (\r
+ IN UNIT_TEST_CONTEXT Context\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN ProcessorNumber;\r
+ EFI_PROCESSOR_INFORMATION ProcessorInfoBuffer;\r
+ MP_SERVICE_UT_CONTEXT *LocalContext;\r
+\r
+ LocalContext = (MP_SERVICE_UT_CONTEXT *)Context;\r
+\r
+ for (ProcessorNumber = 0; ProcessorNumber <= LocalContext->NumberOfProcessors; ProcessorNumber++) {\r
+ Status = MpServicesUnitTestGetProcessorInfo (\r
+ LocalContext->MpServices,\r
+ ProcessorNumber,\r
+ &ProcessorInfoBuffer\r
+ );\r
+\r
+ if (ProcessorNumber == LocalContext->NumberOfProcessors) {\r
+ UT_ASSERT_STATUS_EQUAL (Status, EFI_NOT_FOUND);\r
+ } else {\r
+ UT_ASSERT_NOT_EFI_ERROR (Status);\r
+ UT_ASSERT_TRUE ((ProcessorInfoBuffer.StatusFlag & (UINT32) ~(PROCESSOR_AS_BSP_BIT|PROCESSOR_ENABLED_BIT|PROCESSOR_HEALTH_STATUS_BIT)) == 0);\r
+\r
+ if (ProcessorNumber == LocalContext->BspNumber) {\r
+ UT_ASSERT_TRUE ((ProcessorInfoBuffer.StatusFlag & PROCESSOR_AS_BSP_BIT) && (ProcessorInfoBuffer.StatusFlag & PROCESSOR_ENABLED_BIT));\r
+ } else {\r
+ UT_ASSERT_TRUE (!(ProcessorInfoBuffer.StatusFlag & PROCESSOR_AS_BSP_BIT));\r
+ }\r
+ }\r
+ }\r
+\r
+ return UNIT_TEST_PASSED;\r
+}\r
+\r
+/**\r
+ Unit test of MP service GetProcessorInfo.\r
+ When this service is called from an AP, the return status should be EFI_DEVICE_ERROR.\r
+\r
+ @param[in] Context Context pointer for this test.\r
+\r
+ @retval UNIT_TEST_PASSED The Unit test has completed and the test\r
+ case was successful.\r
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.\r
+**/\r
+UNIT_TEST_STATUS\r
+EFIAPI\r
+TestGetProcessorInfo2 (\r
+ IN UNIT_TEST_CONTEXT Context\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN ApNumber;\r
+ MP_SERVICE_UT_CONTEXT *LocalContext;\r
+\r
+ LocalContext = (MP_SERVICE_UT_CONTEXT *)Context;\r
+\r
+ for (ApNumber = 0; ApNumber < LocalContext->NumberOfProcessors; ApNumber++) {\r
+ LocalContext->ApNumber = ApNumber;\r
+ Status = MpServicesUnitTestStartupThisAP (\r
+ LocalContext->MpServices,\r
+ (EFI_AP_PROCEDURE)RunMpServiceGetProcessorInfoOnAp,\r
+ ApNumber,\r
+ 0,\r
+ (VOID *)LocalContext\r
+ );\r
+\r
+ if (ApNumber == LocalContext->BspNumber) {\r
+ UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER);\r
+ } else {\r
+ UT_ASSERT_NOT_EFI_ERROR (Status);\r
+ UT_ASSERT_STATUS_EQUAL (LocalContext->ApProcedureReturnStatus, EFI_DEVICE_ERROR);\r
+ }\r
+ }\r
+\r
+ return UNIT_TEST_PASSED;\r
+}\r
+\r
+/**\r
+ Unit test of MP service EnableDisableAP.\r
+ When called with BSP number, the return status should be EFI_INVALID_PARAMETER.\r
+ When called with a nonexistent processor handle, the return status should be EFI_NOT_FOUND.\r
+ The AP should be really Enable/Disabled.\r
+\r
+ @param[in] Context Context pointer for this test.\r
+\r
+ @retval UNIT_TEST_PASSED The Unit test has completed and the test\r
+ case was successful.\r
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.\r
+**/\r
+UNIT_TEST_STATUS\r
+EFIAPI\r
+TestEnableDisableAP1 (\r
+ IN UNIT_TEST_CONTEXT Context\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN ApNumber;\r
+ MP_SERVICE_UT_CONTEXT *LocalContext;\r
+\r
+ LocalContext = (MP_SERVICE_UT_CONTEXT *)Context;\r
+\r
+ for (ApNumber = 0; ApNumber <= LocalContext->NumberOfProcessors; ApNumber++) {\r
+ Status = MpServicesUnitTestEnableDisableAP (\r
+ LocalContext->MpServices,\r
+ ApNumber,\r
+ FALSE,\r
+ NULL\r
+ );\r
+\r
+ if (ApNumber == LocalContext->BspNumber) {\r
+ UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER);\r
+ } else if (ApNumber == LocalContext->NumberOfProcessors) {\r
+ UT_ASSERT_STATUS_EQUAL (Status, EFI_NOT_FOUND);\r
+ } else {\r
+ UT_ASSERT_NOT_EFI_ERROR (Status);\r
+\r
+ Status = MpServicesUnitTestStartupThisAP (\r
+ LocalContext->MpServices,\r
+ (EFI_AP_PROCEDURE)EmptyProcedure,\r
+ ApNumber,\r
+ 0,\r
+ NULL\r
+ );\r
+ UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER);\r
+\r
+ Status = MpServicesUnitTestEnableDisableAP (\r
+ LocalContext->MpServices,\r
+ ApNumber,\r
+ TRUE,\r
+ NULL\r
+ );\r
+ UT_ASSERT_NOT_EFI_ERROR (Status);\r
+\r
+ Status = MpServicesUnitTestStartupThisAP (\r
+ LocalContext->MpServices,\r
+ (EFI_AP_PROCEDURE)EmptyProcedure,\r
+ ApNumber,\r
+ 0,\r
+ NULL\r
+ );\r
+ UT_ASSERT_NOT_EFI_ERROR (Status);\r
+ }\r
+ }\r
+\r
+ return UNIT_TEST_PASSED;\r
+}\r
+\r
+/**\r
+ Unit test of MP service EnableDisableAP.\r
+ When run this procedure on AP, the return status should be EFI_DEVICE_ERROR.\r
+\r
+ @param[in] Context Context pointer for this test.\r
+\r
+ @retval UNIT_TEST_PASSED The Unit test has completed and the test\r
+ case was successful.\r
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.\r
+**/\r
+UNIT_TEST_STATUS\r
+EFIAPI\r
+TestEnableDisableAP2 (\r
+ IN UNIT_TEST_CONTEXT Context\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN ApNumber;\r
+ MP_SERVICE_UT_CONTEXT *LocalContext;\r
+\r
+ LocalContext = (MP_SERVICE_UT_CONTEXT *)Context;\r
+\r
+ for (ApNumber = 0; ApNumber < LocalContext->NumberOfProcessors; ApNumber++) {\r
+ LocalContext->ApNumber = ApNumber;\r
+ Status = MpServicesUnitTestStartupThisAP (\r
+ LocalContext->MpServices,\r
+ (EFI_AP_PROCEDURE)RunMpServiceEnableDisableAPOnAp,\r
+ ApNumber,\r
+ 0,\r
+ (VOID *)LocalContext\r
+ );\r
+\r
+ if (ApNumber == LocalContext->BspNumber) {\r
+ UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER);\r
+ } else {\r
+ UT_ASSERT_NOT_EFI_ERROR (Status);\r
+ UT_ASSERT_STATUS_EQUAL (LocalContext->ApProcedureReturnStatus, EFI_DEVICE_ERROR);\r
+ }\r
+ }\r
+\r
+ return UNIT_TEST_PASSED;\r
+}\r
+\r
+/**\r
+ Unit test of MP service EnableDisableAP.\r
+ When run this procedure on AP, the return status should be EFI_DEVICE_ERROR.\r
+\r
+ @param[in] Context Context pointer for this test.\r
+\r
+ @retval UNIT_TEST_PASSED The Unit test has completed and the test\r
+ case was successful.\r
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.\r
+**/\r
+UNIT_TEST_STATUS\r
+EFIAPI\r
+TestEnableDisableAP3 (\r
+ IN UNIT_TEST_CONTEXT Context\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN ApNumber;\r
+ EFI_PROCESSOR_INFORMATION ProcessorInfoBuffer;\r
+ UINT32 OldHealthFlag;\r
+ UINT32 NewHealthFlag;\r
+ MP_SERVICE_UT_CONTEXT *LocalContext;\r
+\r
+ LocalContext = (MP_SERVICE_UT_CONTEXT *)Context;\r
+\r
+ for (ApNumber = 0; ApNumber < LocalContext->NumberOfProcessors; ApNumber++) {\r
+ Status = MpServicesUnitTestGetProcessorInfo (\r
+ LocalContext->MpServices,\r
+ ApNumber,\r
+ &ProcessorInfoBuffer\r
+ );\r
+ UT_ASSERT_NOT_EFI_ERROR (Status);\r
+\r
+ OldHealthFlag = ProcessorInfoBuffer.StatusFlag & PROCESSOR_HEALTH_STATUS_BIT;\r
+ NewHealthFlag = OldHealthFlag ^ PROCESSOR_HEALTH_STATUS_BIT;\r
+ Status = MpServicesUnitTestEnableDisableAP (\r
+ LocalContext->MpServices,\r
+ ApNumber,\r
+ TRUE,\r
+ &NewHealthFlag\r
+ );\r
+\r
+ if (ApNumber == LocalContext->BspNumber) {\r
+ UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER);\r
+ } else {\r
+ UT_ASSERT_NOT_EFI_ERROR (Status);\r
+\r
+ Status = MpServicesUnitTestGetProcessorInfo (\r
+ LocalContext->MpServices,\r
+ ApNumber,\r
+ &ProcessorInfoBuffer\r
+ );\r
+ UT_ASSERT_NOT_EFI_ERROR (Status);\r
+ UT_ASSERT_TRUE ((ProcessorInfoBuffer.StatusFlag & PROCESSOR_HEALTH_STATUS_BIT) == NewHealthFlag);\r
+\r
+ Status = MpServicesUnitTestEnableDisableAP (\r
+ LocalContext->MpServices,\r
+ ApNumber,\r
+ TRUE,\r
+ &OldHealthFlag\r
+ );\r
+ UT_ASSERT_NOT_EFI_ERROR (Status);\r
+ }\r
+ }\r
+\r
+ return UNIT_TEST_PASSED;\r
+}\r
+\r
+/**\r
+ Unit test of MP service StartupThisAP.\r
+ When called to startup a BSP, the return status should be EFI_INVALID_PARAMETER.\r
+ When called with a nonexistent processor handle, the return status should be EFI_NOT_FOUND.\r
+ The requested AP should execute the Procedure when called by StartupThisAP.\r
+\r
+ @param[in] Context Context pointer for this test.\r
+\r
+ @retval UNIT_TEST_PASSED The Unit test has completed and the test\r
+ case was successful.\r
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.\r
+**/\r
+UNIT_TEST_STATUS\r
+EFIAPI\r
+TestStartupThisAP1 (\r
+ IN UNIT_TEST_CONTEXT Context\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN ApNumber;\r
+ UINTN ProcessorIndex;\r
+ MP_SERVICE_UT_CONTEXT *LocalContext;\r
+\r
+ LocalContext = (MP_SERVICE_UT_CONTEXT *)Context;\r
+\r
+ for (ApNumber = 0; ApNumber <= LocalContext->NumberOfProcessors; ApNumber++) {\r
+ SetMem (LocalContext->CommonBuffer, LocalContext->NumberOfProcessors * sizeof (*LocalContext->CommonBuffer), 0xFF);\r
+ Status = MpServicesUnitTestStartupThisAP (\r
+ LocalContext->MpServices,\r
+ (EFI_AP_PROCEDURE)StoreCpuNumbers,\r
+ ApNumber,\r
+ 0,\r
+ (VOID *)LocalContext\r
+ );\r
+\r
+ if (ApNumber == LocalContext->BspNumber) {\r
+ UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER);\r
+ } else if (ApNumber == LocalContext->NumberOfProcessors) {\r
+ UT_ASSERT_STATUS_EQUAL (Status, EFI_NOT_FOUND);\r
+ } else {\r
+ UT_ASSERT_NOT_EFI_ERROR (Status);\r
+\r
+ for (ProcessorIndex = 0; ProcessorIndex < LocalContext->NumberOfProcessors; ProcessorIndex++) {\r
+ UT_ASSERT_TRUE (\r
+ ((ProcessorIndex == ApNumber) && (LocalContext->CommonBuffer[ProcessorIndex] == ProcessorIndex)) ||\r
+ ((ProcessorIndex != ApNumber) && (LocalContext->CommonBuffer[ProcessorIndex] == (UINTN) ~0))\r
+ );\r
+ }\r
+ }\r
+ }\r
+\r
+ return UNIT_TEST_PASSED;\r
+}\r
+\r
+/**\r
+ Unit test of MP service StartupThisAP.\r
+ When this service is called from an AP, the return status should be EFI_DEVICE_ERROR.\r
+\r
+ @param[in] Context Context pointer for this test.\r
+\r
+ @retval UNIT_TEST_PASSED The Unit test has completed and the test\r
+ case was successful.\r
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.\r
+**/\r
+UNIT_TEST_STATUS\r
+EFIAPI\r
+TestStartupThisAP2 (\r
+ IN UNIT_TEST_CONTEXT Context\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN ApNumber;\r
+ MP_SERVICE_UT_CONTEXT *LocalContext;\r
+\r
+ LocalContext = (MP_SERVICE_UT_CONTEXT *)Context;\r
+\r
+ for (ApNumber = 0; ApNumber < LocalContext->NumberOfProcessors; ApNumber++) {\r
+ LocalContext->ApNumber = ApNumber;\r
+ Status = MpServicesUnitTestStartupThisAP (\r
+ LocalContext->MpServices,\r
+ (EFI_AP_PROCEDURE)RunMpServiceStartupThisAPOnAp,\r
+ ApNumber,\r
+ 0,\r
+ (VOID *)LocalContext\r
+ );\r
+\r
+ if (ApNumber == LocalContext->BspNumber) {\r
+ UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER);\r
+ } else {\r
+ UT_ASSERT_NOT_EFI_ERROR (Status);\r
+ UT_ASSERT_STATUS_EQUAL (LocalContext->ApProcedureReturnStatus, EFI_DEVICE_ERROR);\r
+ }\r
+ }\r
+\r
+ return UNIT_TEST_PASSED;\r
+}\r
+\r
+/**\r
+ Unit test of MP service StartupThisAP.\r
+ When timeout expired before the requested AP has finished, the return status should be EFI_TIMEOUT.\r
+\r
+ @param[in] Context Context pointer for this test.\r
+\r
+ @retval UNIT_TEST_PASSED The Unit test has completed and the test\r
+ case was successful.\r
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.\r
+**/\r
+UNIT_TEST_STATUS\r
+EFIAPI\r
+TestStartupThisAP3 (\r
+ IN UNIT_TEST_CONTEXT Context\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN ApNumber;\r
+ MP_SERVICE_UT_CONTEXT *LocalContext;\r
+\r
+ LocalContext = (MP_SERVICE_UT_CONTEXT *)Context;\r
+\r
+ for (ApNumber = 0; ApNumber < LocalContext->NumberOfProcessors; ApNumber++) {\r
+ Status = MpServicesUnitTestStartupThisAP (\r
+ LocalContext->MpServices,\r
+ (EFI_AP_PROCEDURE)InfiniteLoopProcedure,\r
+ ApNumber,\r
+ RUN_PROCEDURE_TIMEOUT_VALUE,\r
+ NULL\r
+ );\r
+\r
+ if (ApNumber == LocalContext->BspNumber) {\r
+ UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER);\r
+ } else {\r
+ UT_ASSERT_STATUS_EQUAL (Status, EFI_TIMEOUT);\r
+ }\r
+ }\r
+\r
+ return UNIT_TEST_PASSED;\r
+}\r
+\r
+/**\r
+ Unit test of MP service StartupThisAP.\r
+ When called with disabled AP, the return status should be EFI_INVALID_PARAMETER.\r
+\r
+ @param[in] Context Context pointer for this test.\r
+\r
+ @retval UNIT_TEST_PASSED The Unit test has completed and the test\r
+ case was successful.\r
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.\r
+**/\r
+UNIT_TEST_STATUS\r
+EFIAPI\r
+TestStartupThisAP4 (\r
+ IN UNIT_TEST_CONTEXT Context\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN ApNumber;\r
+ MP_SERVICE_UT_CONTEXT *LocalContext;\r
+\r
+ LocalContext = (MP_SERVICE_UT_CONTEXT *)Context;\r
+\r
+ for (ApNumber = 0; ApNumber < LocalContext->NumberOfProcessors; ApNumber++) {\r
+ Status = MpServicesUnitTestEnableDisableAP (\r
+ LocalContext->MpServices,\r
+ ApNumber,\r
+ FALSE,\r
+ NULL\r
+ );\r
+\r
+ if (ApNumber == LocalContext->BspNumber) {\r
+ UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER);\r
+ } else {\r
+ UT_ASSERT_NOT_EFI_ERROR (Status);\r
+\r
+ Status = MpServicesUnitTestStartupThisAP (\r
+ LocalContext->MpServices,\r
+ (EFI_AP_PROCEDURE)EmptyProcedure,\r
+ ApNumber,\r
+ 0,\r
+ NULL\r
+ );\r
+ UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER);\r
+\r
+ Status = MpServicesUnitTestEnableDisableAP (\r
+ LocalContext->MpServices,\r
+ ApNumber,\r
+ TRUE,\r
+ NULL\r
+ );\r
+ UT_ASSERT_NOT_EFI_ERROR (Status);\r
+\r
+ Status = MpServicesUnitTestStartupThisAP (\r
+ LocalContext->MpServices,\r
+ (EFI_AP_PROCEDURE)EmptyProcedure,\r
+ ApNumber,\r
+ 0,\r
+ NULL\r
+ );\r
+ UT_ASSERT_NOT_EFI_ERROR (Status);\r
+ }\r
+ }\r
+\r
+ return UNIT_TEST_PASSED;\r
+}\r
+\r
+/**\r
+ Unit test of MP service StartupAllAPs.\r
+ All APs should execute the Procedure when called by StartupAllAPs.\r
+\r
+ @param[in] Context Context pointer for this test.\r
+\r
+ @retval UNIT_TEST_PASSED The Unit test has completed and the test\r
+ case was successful.\r
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.\r
+**/\r
+UNIT_TEST_STATUS\r
+EFIAPI\r
+TestStartupAllAPs1 (\r
+ IN UNIT_TEST_CONTEXT Context\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN ProcessorIndex;\r
+ MP_SERVICE_UT_CONTEXT *LocalContext;\r
+\r
+ LocalContext = (MP_SERVICE_UT_CONTEXT *)Context;\r
+\r
+ SetMem (LocalContext->CommonBuffer, LocalContext->NumberOfProcessors * sizeof (*LocalContext->CommonBuffer), 0xFF);\r
+ Status = MpServicesUnitTestStartupAllAPs (\r
+ LocalContext->MpServices,\r
+ (EFI_AP_PROCEDURE)StoreCpuNumbers,\r
+ FALSE,\r
+ 0,\r
+ (VOID *)LocalContext\r
+ );\r
+ UT_ASSERT_NOT_EFI_ERROR (Status);\r
+\r
+ for (ProcessorIndex = 0; ProcessorIndex < LocalContext->NumberOfProcessors; ProcessorIndex++) {\r
+ UT_ASSERT_TRUE (\r
+ ((ProcessorIndex == LocalContext->BspNumber) && (LocalContext->CommonBuffer[ProcessorIndex] == (UINTN) ~0)) ||\r
+ ((ProcessorIndex != LocalContext->BspNumber) && (LocalContext->CommonBuffer[ProcessorIndex] == ProcessorIndex))\r
+ );\r
+ }\r
+\r
+ return UNIT_TEST_PASSED;\r
+}\r
+\r
+/**\r
+ Unit test of MP service StartupAllAPs.\r
+ When called in single thread, the return status should be EFI_SUCCESS and AP executes in ascending order\r
+ of processor handle number.\r
+\r
+ @param[in] Context Context pointer for this test.\r
+\r
+ @retval UNIT_TEST_PASSED The Unit test has completed and the test\r
+ case was successful.\r
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.\r
+**/\r
+UNIT_TEST_STATUS\r
+EFIAPI\r
+TestStartupAllAPs2 (\r
+ IN UNIT_TEST_CONTEXT Context\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN ProcessorIndex;\r
+ MP_SERVICE_UT_CONTEXT *LocalContext;\r
+\r
+ LocalContext = (MP_SERVICE_UT_CONTEXT *)Context;\r
+\r
+ ZeroMem (LocalContext->CommonBuffer, LocalContext->NumberOfProcessors * sizeof (*LocalContext->CommonBuffer));\r
+ Status = MpServicesUnitTestStartupAllAPs (\r
+ LocalContext->MpServices,\r
+ (EFI_AP_PROCEDURE)StoreAPsExecutionOrder,\r
+ TRUE,\r
+ 0,\r
+ (VOID *)LocalContext\r
+ );\r
+ UT_ASSERT_NOT_EFI_ERROR (Status);\r
+\r
+ //\r
+ // The layout of CommonBuffer (E.g. BspNumber = 2 and NumberOfProcessors = 6)\r
+ // Index 00 01 02 03 04 05\r
+ // Value 00 01 03 04 05 ApCounter(5)\r
+ //\r
+ for (ProcessorIndex = 0; ProcessorIndex < LocalContext->NumberOfProcessors - 2; ProcessorIndex++) {\r
+ UT_ASSERT_TRUE (LocalContext->CommonBuffer[ProcessorIndex] < LocalContext->CommonBuffer[ProcessorIndex + 1]);\r
+ }\r
+\r
+ UT_ASSERT_EQUAL (LocalContext->CommonBuffer[LocalContext->NumberOfProcessors - 1], LocalContext->NumberOfProcessors - 1);\r
+\r
+ return UNIT_TEST_PASSED;\r
+}\r
+\r
+/**\r
+ Unit test of MP service StartupAllAPs.\r
+ When this service is called from an AP, the return status should be EFI_DEVICE_ERROR.\r
+\r
+ @param[in] Context Context pointer for this test.\r
+\r
+ @retval UNIT_TEST_PASSED The Unit test has completed and the test\r
+ case was successful.\r
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.\r
+**/\r
+UNIT_TEST_STATUS\r
+EFIAPI\r
+TestStartupAllAPs3 (\r
+ IN UNIT_TEST_CONTEXT Context\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN ApNumber;\r
+ MP_SERVICE_UT_CONTEXT *LocalContext;\r
+\r
+ LocalContext = (MP_SERVICE_UT_CONTEXT *)Context;\r
+\r
+ for (ApNumber = 0; ApNumber < LocalContext->NumberOfProcessors; ApNumber++) {\r
+ LocalContext->ApNumber = ApNumber;\r
+ Status = MpServicesUnitTestStartupThisAP (\r
+ LocalContext->MpServices,\r
+ (EFI_AP_PROCEDURE)RunMpServiceStartupAllAPsOnAp,\r
+ ApNumber,\r
+ 0,\r
+ (VOID *)LocalContext\r
+ );\r
+\r
+ if (ApNumber == LocalContext->BspNumber) {\r
+ UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER);\r
+ } else {\r
+ UT_ASSERT_NOT_EFI_ERROR (Status);\r
+ UT_ASSERT_STATUS_EQUAL (LocalContext->ApProcedureReturnStatus, EFI_DEVICE_ERROR);\r
+ }\r
+ }\r
+\r
+ return UNIT_TEST_PASSED;\r
+}\r
+\r
+/**\r
+ Unit test of MP service StartupAllAPs.\r
+ When called with all AP timeout, the return status should be EFI_TIMEOUT.\r
+\r
+ @param[in] Context Context pointer for this test.\r
+\r
+ @retval UNIT_TEST_PASSED The Unit test has completed and the test\r
+ case was successful.\r
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.\r
+**/\r
+UNIT_TEST_STATUS\r
+EFIAPI\r
+TestStartupAllAPs4 (\r
+ IN UNIT_TEST_CONTEXT Context\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ MP_SERVICE_UT_CONTEXT *LocalContext;\r
+\r
+ LocalContext = (MP_SERVICE_UT_CONTEXT *)Context;\r
+\r
+ Status = MpServicesUnitTestStartupAllAPs (\r
+ LocalContext->MpServices,\r
+ (EFI_AP_PROCEDURE)InfiniteLoopProcedure,\r
+ TRUE,\r
+ RUN_PROCEDURE_TIMEOUT_VALUE,\r
+ NULL\r
+ );\r
+ UT_ASSERT_STATUS_EQUAL (Status, EFI_TIMEOUT);\r
+\r
+ Status = MpServicesUnitTestStartupAllAPs (\r
+ LocalContext->MpServices,\r
+ (EFI_AP_PROCEDURE)InfiniteLoopProcedure,\r
+ FALSE,\r
+ RUN_PROCEDURE_TIMEOUT_VALUE,\r
+ NULL\r
+ );\r
+ UT_ASSERT_STATUS_EQUAL (Status, EFI_TIMEOUT);\r
+\r
+ return UNIT_TEST_PASSED;\r
+}\r
+\r
+/**\r
+ Unit test of MP service StartupAllAPs.\r
+ When called with the empty Procedure on all disabled APs, the return status should be EFI_NOT_STARTED.\r
+\r
+ @param[in] Context Context pointer for this test.\r
+\r
+ @retval UNIT_TEST_PASSED The Unit test has completed and the test\r
+ case was successful.\r
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.\r
+**/\r
+UNIT_TEST_STATUS\r
+EFIAPI\r
+TestStartupAllAPs5 (\r
+ IN UNIT_TEST_CONTEXT Context\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN ApNumber;\r
+ MP_SERVICE_UT_CONTEXT *LocalContext;\r
+\r
+ LocalContext = (MP_SERVICE_UT_CONTEXT *)Context;\r
+\r
+ for (ApNumber = 0; ApNumber < LocalContext->NumberOfProcessors; ApNumber++) {\r
+ Status = MpServicesUnitTestEnableDisableAP (\r
+ LocalContext->MpServices,\r
+ ApNumber,\r
+ FALSE,\r
+ NULL\r
+ );\r
+\r
+ if (ApNumber == LocalContext->BspNumber) {\r
+ UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER);\r
+ } else {\r
+ UT_ASSERT_NOT_EFI_ERROR (Status);\r
+ }\r
+ }\r
+\r
+ Status = MpServicesUnitTestStartupAllAPs (\r
+ LocalContext->MpServices,\r
+ (EFI_AP_PROCEDURE)EmptyProcedure,\r
+ FALSE,\r
+ 0,\r
+ NULL\r
+ );\r
+ UT_ASSERT_STATUS_EQUAL (Status, EFI_NOT_STARTED);\r
+\r
+ for (ApNumber = 0; ApNumber < LocalContext->NumberOfProcessors; ApNumber++) {\r
+ Status = MpServicesUnitTestEnableDisableAP (\r
+ LocalContext->MpServices,\r
+ ApNumber,\r
+ TRUE,\r
+ NULL\r
+ );\r
+\r
+ if (ApNumber == LocalContext->BspNumber) {\r
+ UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER);\r
+ } else {\r
+ UT_ASSERT_NOT_EFI_ERROR (Status);\r
+ }\r
+ }\r
+\r
+ return UNIT_TEST_PASSED;\r
+}\r
+\r
+/**\r
+ Unit test of MP service SwitchBSP.\r
+ When switch current BSP to be BSP, the return status should be EFI_INVALID_PARAMETER.\r
+ When switch nonexistent processor to be BSP, the return status should be EFI_NOT_FOUND.\r
+ After switch BSP, all APs(includes new AP) should execute the Procedure when called by StartupAllAP.\r
+\r
+ @param[in] Context Context pointer for this test.\r
+\r
+ @retval UNIT_TEST_PASSED The Unit test has completed and the test\r
+ case was successful.\r
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.\r
+**/\r
+UNIT_TEST_STATUS\r
+EFIAPI\r
+TestSwitchBSP1 (\r
+ IN UNIT_TEST_CONTEXT Context\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN NewBspNumber;\r
+ UINTN ProcessorIndex;\r
+ MP_SERVICE_UT_CONTEXT *LocalContext;\r
+\r
+ LocalContext = (MP_SERVICE_UT_CONTEXT *)Context;\r
+\r
+ for (NewBspNumber = 0; NewBspNumber <= LocalContext->NumberOfProcessors; NewBspNumber++) {\r
+ Status = MpServicesUnitTestSwitchBSP (\r
+ LocalContext->MpServices,\r
+ NewBspNumber,\r
+ TRUE\r
+ );\r
+\r
+ if (NewBspNumber == LocalContext->BspNumber) {\r
+ UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER);\r
+ } else if (NewBspNumber == LocalContext->NumberOfProcessors) {\r
+ UT_ASSERT_STATUS_EQUAL (Status, EFI_NOT_FOUND);\r
+ } else {\r
+ UT_ASSERT_NOT_EFI_ERROR (Status);\r
+\r
+ SetMem (LocalContext->CommonBuffer, LocalContext->NumberOfProcessors * sizeof (*LocalContext->CommonBuffer), 0xFF);\r
+ Status = MpServicesUnitTestStartupAllAPs (\r
+ LocalContext->MpServices,\r
+ (EFI_AP_PROCEDURE)StoreCpuNumbers,\r
+ FALSE,\r
+ 0,\r
+ (VOID *)LocalContext\r
+ );\r
+ UT_ASSERT_NOT_EFI_ERROR (Status);\r
+\r
+ for (ProcessorIndex = 0; ProcessorIndex < LocalContext->NumberOfProcessors; ProcessorIndex++) {\r
+ UT_ASSERT_TRUE (\r
+ ((ProcessorIndex == NewBspNumber) && (LocalContext->CommonBuffer[ProcessorIndex] == (UINTN) ~0)) ||\r
+ ((ProcessorIndex != NewBspNumber) && (LocalContext->CommonBuffer[ProcessorIndex] == ProcessorIndex))\r
+ );\r
+ }\r
+\r
+ Status = MpServicesUnitTestSwitchBSP (\r
+ LocalContext->MpServices,\r
+ LocalContext->BspNumber,\r
+ TRUE\r
+ );\r
+ UT_ASSERT_NOT_EFI_ERROR (Status);\r
+ }\r
+ }\r
+\r
+ return UNIT_TEST_PASSED;\r
+}\r
+\r
+/**\r
+ Unit test of MP service SwitchBSP.\r
+ When run this procedure on AP, the return status should be EFI_DEVICE_ERROR.\r
+\r
+ @param[in] Context Context pointer for this test.\r
+\r
+ @retval UNIT_TEST_PASSED The Unit test has completed and the test\r
+ case was successful.\r
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.\r
+**/\r
+UNIT_TEST_STATUS\r
+EFIAPI\r
+TestSwitchBSP2 (\r
+ IN UNIT_TEST_CONTEXT Context\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN ApNumber;\r
+ MP_SERVICE_UT_CONTEXT *LocalContext;\r
+\r
+ LocalContext = (MP_SERVICE_UT_CONTEXT *)Context;\r
+\r
+ for (ApNumber = 0; ApNumber < LocalContext->NumberOfProcessors; ApNumber++) {\r
+ LocalContext->ApNumber = ApNumber;\r
+ Status = MpServicesUnitTestStartupThisAP (\r
+ LocalContext->MpServices,\r
+ (EFI_AP_PROCEDURE)RunMpServiceSwitchBSPOnAp,\r
+ ApNumber,\r
+ 0,\r
+ (VOID *)LocalContext\r
+ );\r
+\r
+ if (ApNumber == LocalContext->BspNumber) {\r
+ UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER);\r
+ } else {\r
+ UT_ASSERT_NOT_EFI_ERROR (Status);\r
+ UT_ASSERT_STATUS_EQUAL (LocalContext->ApProcedureReturnStatus, EFI_DEVICE_ERROR);\r
+ }\r
+ }\r
+\r
+ return UNIT_TEST_PASSED;\r
+}\r
+\r
+/**\r
+ Unit test of MP service SwitchBSP.\r
+ When switch a disabled AP to be BSP, the return status should be EFI_INVALID_PARAMETER.\r
+\r
+ @param[in] Context Context pointer for this test.\r
+\r
+ @retval UNIT_TEST_PASSED The Unit test has completed and the test\r
+ case was successful.\r
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.\r
+**/\r
+UNIT_TEST_STATUS\r
+EFIAPI\r
+TestSwitchBSP3 (\r
+ IN UNIT_TEST_CONTEXT Context\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN NewBspNumber;\r
+ MP_SERVICE_UT_CONTEXT *LocalContext;\r
+\r
+ LocalContext = (MP_SERVICE_UT_CONTEXT *)Context;\r
+\r
+ for (NewBspNumber = 0; NewBspNumber < LocalContext->NumberOfProcessors; NewBspNumber++) {\r
+ Status = MpServicesUnitTestEnableDisableAP (\r
+ LocalContext->MpServices,\r
+ NewBspNumber,\r
+ FALSE,\r
+ NULL\r
+ );\r
+\r
+ if (NewBspNumber == LocalContext->BspNumber) {\r
+ UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER);\r
+ } else {\r
+ UT_ASSERT_NOT_EFI_ERROR (Status);\r
+\r
+ Status = MpServicesUnitTestSwitchBSP (\r
+ LocalContext->MpServices,\r
+ NewBspNumber,\r
+ TRUE\r
+ );\r
+ UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER);\r
+\r
+ Status = MpServicesUnitTestEnableDisableAP (\r
+ LocalContext->MpServices,\r
+ NewBspNumber,\r
+ TRUE,\r
+ NULL\r
+ );\r
+ UT_ASSERT_NOT_EFI_ERROR (Status);\r
+ }\r
+ }\r
+\r
+ return UNIT_TEST_PASSED;\r
+}\r
+\r
+/**\r
+ Unit test of MP service SwitchBSP.\r
+ When SwitchBSP and EnableOldBSP is TRUE, the new BSP should be in the enabled state and the old BSP should\r
+ be in the enabled state.\r
+ When SwitchBSP and EnableOldBSP is False, the new BSP should be in the enabled state and the old BSP should\r
+ be in the disabled state.\r
+\r
+ @param[in] Context Context pointer for this test.\r
+\r
+ @retval UNIT_TEST_PASSED The Unit test has completed and the test\r
+ case was successful.\r
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.\r
+**/\r
+UNIT_TEST_STATUS\r
+EFIAPI\r
+TestSwitchBSP4 (\r
+ IN UNIT_TEST_CONTEXT Context\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN NewBspNumber;\r
+ EFI_PROCESSOR_INFORMATION ProcessorInfoBuffer;\r
+ MP_SERVICE_UT_CONTEXT *LocalContext;\r
+\r
+ LocalContext = (MP_SERVICE_UT_CONTEXT *)Context;\r
+\r
+ for (NewBspNumber = 0; NewBspNumber < LocalContext->NumberOfProcessors; NewBspNumber++) {\r
+ Status = MpServicesUnitTestSwitchBSP (\r
+ LocalContext->MpServices,\r
+ NewBspNumber,\r
+ FALSE\r
+ );\r
+\r
+ if (NewBspNumber == LocalContext->BspNumber) {\r
+ UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER);\r
+ } else {\r
+ UT_ASSERT_NOT_EFI_ERROR (Status);\r
+\r
+ Status = MpServicesUnitTestGetProcessorInfo (\r
+ LocalContext->MpServices,\r
+ NewBspNumber,\r
+ &ProcessorInfoBuffer\r
+ );\r
+ UT_ASSERT_NOT_EFI_ERROR (Status);\r
+ UT_ASSERT_TRUE (\r
+ (ProcessorInfoBuffer.StatusFlag & PROCESSOR_AS_BSP_BIT) &&\r
+ (ProcessorInfoBuffer.StatusFlag & PROCESSOR_ENABLED_BIT)\r
+ );\r
+\r
+ Status = MpServicesUnitTestGetProcessorInfo (\r
+ LocalContext->MpServices,\r
+ LocalContext->BspNumber,\r
+ &ProcessorInfoBuffer\r
+ );\r
+ UT_ASSERT_NOT_EFI_ERROR (Status);\r
+ UT_ASSERT_TRUE (\r
+ !(ProcessorInfoBuffer.StatusFlag & PROCESSOR_AS_BSP_BIT) &&\r
+ !(ProcessorInfoBuffer.StatusFlag & PROCESSOR_ENABLED_BIT)\r
+ );\r
+\r
+ Status = MpServicesUnitTestEnableDisableAP (\r
+ LocalContext->MpServices,\r
+ LocalContext->BspNumber,\r
+ TRUE,\r
+ NULL\r
+ );\r
+ UT_ASSERT_NOT_EFI_ERROR (Status);\r
+\r
+ Status = MpServicesUnitTestSwitchBSP (\r
+ LocalContext->MpServices,\r
+ LocalContext->BspNumber,\r
+ TRUE\r
+ );\r
+ UT_ASSERT_NOT_EFI_ERROR (Status);\r
+\r
+ Status = MpServicesUnitTestGetProcessorInfo (\r
+ LocalContext->MpServices,\r
+ LocalContext->BspNumber,\r
+ &ProcessorInfoBuffer\r
+ );\r
+ UT_ASSERT_NOT_EFI_ERROR (Status);\r
+ UT_ASSERT_TRUE (\r
+ (ProcessorInfoBuffer.StatusFlag & PROCESSOR_AS_BSP_BIT) &&\r
+ (ProcessorInfoBuffer.StatusFlag & PROCESSOR_ENABLED_BIT)\r
+ );\r
+\r
+ Status = MpServicesUnitTestGetProcessorInfo (\r
+ LocalContext->MpServices,\r
+ NewBspNumber,\r
+ &ProcessorInfoBuffer\r
+ );\r
+ UT_ASSERT_NOT_EFI_ERROR (Status);\r
+ UT_ASSERT_TRUE (\r
+ !(ProcessorInfoBuffer.StatusFlag & PROCESSOR_AS_BSP_BIT) &&\r
+ (ProcessorInfoBuffer.StatusFlag & PROCESSOR_ENABLED_BIT)\r
+ );\r
+ }\r
+ }\r
+\r
+ return UNIT_TEST_PASSED;\r
+}\r
+\r
+/**\r
+ Create test suite and unit tests for both EdkiiPeiMpServices2Ppi and EfiMpServiceProtocol.\r
+\r
+ @param[in] Framework A pointer to the framework that is being persisted.\r
+ @param[in] Context A pointer to the private data buffer.\r
+\r
+ @retval EFI_SUCCESS Create test suite and unit tests successfully.\r
+ @retval Others Create test suite and unit tests unsuccessfully.\r
+**/\r
+EFI_STATUS\r
+AddCommonTestCase (\r
+ IN UNIT_TEST_FRAMEWORK_HANDLE Framework,\r
+ IN MP_SERVICE_UT_CONTEXT *Context\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UNIT_TEST_SUITE_HANDLE MpServiceWhoAmITestSuite;\r
+ UNIT_TEST_SUITE_HANDLE MpServiceGetNumberOfProcessorsTestSuite;\r
+ UNIT_TEST_SUITE_HANDLE MpServiceGetProcessorInfoTestSuite;\r
+ UNIT_TEST_SUITE_HANDLE MpServiceEnableDisableAPTestSuite;\r
+ UNIT_TEST_SUITE_HANDLE MpServiceStartupThisAPTestSuite;\r
+ UNIT_TEST_SUITE_HANDLE MpServiceStartupAllAPsTestSuite;\r
+ UNIT_TEST_SUITE_HANDLE MpServiceSwitchBSPTestSuite;\r
+\r
+ MpServiceWhoAmITestSuite = NULL;\r
+ MpServiceGetNumberOfProcessorsTestSuite = NULL;\r
+ MpServiceGetProcessorInfoTestSuite = NULL;\r
+ MpServiceEnableDisableAPTestSuite = NULL;\r
+ MpServiceStartupThisAPTestSuite = NULL;\r
+ MpServiceStartupAllAPsTestSuite = NULL;\r
+ MpServiceSwitchBSPTestSuite = NULL;\r
+\r
+ //\r
+ // Test WhoAmI function\r
+ //\r
+ Status = CreateUnitTestSuite (&MpServiceWhoAmITestSuite, Framework, "Identify the currently executing processor", "MpServices.WhoAmI", NULL, NULL);\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for MpServiceWhoAmI Test Suite\n"));\r
+ return Status;\r
+ }\r
+\r
+ AddTestCase (MpServiceWhoAmITestSuite, "Test WhoAmI 1", "TestWhoAmI1", TestWhoAmI1, InitUTContext, CheckUTContext, Context);\r
+\r
+ //\r
+ // Test GetNumberOfProcessors function\r
+ //\r
+ Status = CreateUnitTestSuite (&MpServiceGetNumberOfProcessorsTestSuite, Framework, "Retrieve the number of logical processor", "MpServices.GetNumberOfProcessors", NULL, NULL);\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for MpServiceGetNumberOfProcessors Test Suite\n"));\r
+ return Status;\r
+ }\r
+\r
+ AddTestCase (MpServiceGetNumberOfProcessorsTestSuite, "Test GetNumberOfProcessors 1", "TestGetNumberOfProcessors1", TestGetNumberOfProcessors1, InitUTContext, CheckUTContext, Context);\r
+ AddTestCase (MpServiceGetNumberOfProcessorsTestSuite, "Test GetNumberOfProcessors 2", "TestGetNumberOfProcessors2", TestGetNumberOfProcessors2, InitUTContext, CheckUTContext, Context);\r
+ AddTestCase (MpServiceGetNumberOfProcessorsTestSuite, "Test GetNumberOfProcessors 3", "TestGetNumberOfProcessors3", TestGetNumberOfProcessors3, InitUTContext, CheckUTContext, Context);\r
+\r
+ //\r
+ // Test GetProcessorInfo function\r
+ //\r
+ Status = CreateUnitTestSuite (&MpServiceGetProcessorInfoTestSuite, Framework, "Get detailed information on the requested logical processor", "MpServices.GetProcessorInfo", NULL, NULL);\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for MpServiceGetProcessorInfo Test Suite\n"));\r
+ return Status;\r
+ }\r
+\r
+ AddTestCase (MpServiceGetProcessorInfoTestSuite, "Test GetProcessorInfo 1", "TestGetProcessorInfo1", TestGetProcessorInfo1, InitUTContext, CheckUTContext, Context);\r
+ AddTestCase (MpServiceGetProcessorInfoTestSuite, "Test GetProcessorInfo 2", "TestGetProcessorInfo2", TestGetProcessorInfo2, InitUTContext, CheckUTContext, Context);\r
+\r
+ //\r
+ // Test EnableDisableAP function\r
+ //\r
+ Status = CreateUnitTestSuite (&MpServiceEnableDisableAPTestSuite, Framework, "Caller enables or disables an AP from this point onward", "MpServices.EnableDisableAP", NULL, NULL);\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for MpServiceEnableDisableAP Test Suite\n"));\r
+ return Status;\r
+ }\r
+\r
+ AddTestCase (MpServiceEnableDisableAPTestSuite, "Test EnableDisableAP 1", "TestEnableDisableAP1", TestEnableDisableAP1, InitUTContext, CheckUTContext, Context);\r
+ AddTestCase (MpServiceEnableDisableAPTestSuite, "Test EnableDisableAP 2", "TestEnableDisableAP2", TestEnableDisableAP2, InitUTContext, CheckUTContext, Context);\r
+ AddTestCase (MpServiceEnableDisableAPTestSuite, "Test EnableDisableAP 3", "TestEnableDisableAP3", TestEnableDisableAP3, InitUTContext, CheckUTContext, Context);\r
+\r
+ //\r
+ // Test StartupThisAP function\r
+ //\r
+ Status = CreateUnitTestSuite (&MpServiceStartupThisAPTestSuite, Framework, "Get the requested AP to execute a caller-provided function", "MpServices.StartupThisAP", NULL, NULL);\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for MpServiceStartupThisAP Test Suite\n"));\r
+ return Status;\r
+ }\r
+\r
+ AddTestCase (MpServiceStartupThisAPTestSuite, "Test StartupThisAP 1", "TestStartupThisAP1", TestStartupThisAP1, InitUTContext, CheckUTContext, Context);\r
+ AddTestCase (MpServiceStartupThisAPTestSuite, "Test StartupThisAP 2", "TestStartupThisAP2", TestStartupThisAP2, InitUTContext, CheckUTContext, Context);\r
+ AddTestCase (MpServiceStartupThisAPTestSuite, "Test StartupThisAP 3", "TestStartupThisAP3", TestStartupThisAP3, InitUTContext, CheckUTContext, Context);\r
+ AddTestCase (MpServiceStartupThisAPTestSuite, "Test StartupThisAP 4", "TestStartupThisAP4", TestStartupThisAP4, InitUTContext, CheckUTContext, Context);\r
+\r
+ //\r
+ // Test StartupAllAPs function\r
+ //\r
+ Status = CreateUnitTestSuite (&MpServiceStartupAllAPsTestSuite, Framework, "Execute a caller provided function on all enabled APs", "MpServices.StartupAllAPs", NULL, NULL);\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for MpServiceStartupAllAPs Test Suite\n"));\r
+ return Status;\r
+ }\r
+\r
+ AddTestCase (MpServiceStartupAllAPsTestSuite, "Test StartupAllAPs 1", "TestStartupAllAPs1", TestStartupAllAPs1, InitUTContext, CheckUTContext, Context);\r
+ AddTestCase (MpServiceStartupAllAPsTestSuite, "Test StartupAllAPs 2", "TestStartupAllAPs2", TestStartupAllAPs2, InitUTContext, CheckUTContext, Context);\r
+ AddTestCase (MpServiceStartupAllAPsTestSuite, "Test StartupAllAPs 3", "TestStartupAllAPs3", TestStartupAllAPs3, InitUTContext, CheckUTContext, Context);\r
+ AddTestCase (MpServiceStartupAllAPsTestSuite, "Test StartupAllAPs 4", "TestStartupAllAPs4", TestStartupAllAPs4, InitUTContext, CheckUTContext, Context);\r
+ AddTestCase (MpServiceStartupAllAPsTestSuite, "Test StartupAllAPs 5", "TestStartupAllAPs5", TestStartupAllAPs5, InitUTContext, CheckUTContext, Context);\r
+\r
+ //\r
+ // Test SwitchBSP function\r
+ //\r
+ Status = CreateUnitTestSuite (&MpServiceSwitchBSPTestSuite, Framework, "Switch the requested AP to be the BSP from that point onward", "MpServices.SwitchBSP", NULL, NULL);\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for MpServiceSwitchBSP Test Suite\n"));\r
+ return Status;\r
+ }\r
+\r
+ AddTestCase (MpServiceSwitchBSPTestSuite, "Test SwitchBSP 1", "TestSwitchBSP1", TestSwitchBSP1, InitUTContext, CheckUTContext, Context);\r
+ AddTestCase (MpServiceSwitchBSPTestSuite, "Test SwitchBSP 2", "TestSwitchBSP2", TestSwitchBSP2, InitUTContext, CheckUTContext, Context);\r
+ AddTestCase (MpServiceSwitchBSPTestSuite, "Test SwitchBSP 3", "TestSwitchBSP3", TestSwitchBSP3, InitUTContext, CheckUTContext, Context);\r
+ AddTestCase (MpServiceSwitchBSPTestSuite, "Test SwitchBSP 4", "TestSwitchBSP4", TestSwitchBSP4, InitUTContext, FreeUTContext, Context);\r
+\r
+ return EFI_SUCCESS;\r
+}\r