]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/Library/CpuExceptionHandlerLib/UnitTest/DxeCpuExceptionHandlerUnitTest.c
UefiCpuPkg: Add Unit tests for DxeCpuExceptionHandlerLib
[mirror_edk2.git] / UefiCpuPkg / Library / CpuExceptionHandlerLib / UnitTest / DxeCpuExceptionHandlerUnitTest.c
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/UnitTest/DxeCpuExceptionHandlerUnitTest.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/UnitTest/DxeCpuExceptionHandlerUnitTest.c
new file mode 100644 (file)
index 0000000..917fc54
--- /dev/null
@@ -0,0 +1,196 @@
+/** @file\r
+  Unit tests of the CpuExceptionHandlerLib.\r
+\r
+  Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#include "CpuExceptionHandlerTest.h"\r
+#include <Library/UefiBootServicesTableLib.h>\r
+\r
+/**\r
+  Initialize Bsp Idt with a new Idt table and return the IA32_DESCRIPTOR buffer.\r
+  In PEIM, store original PeiServicePointer before new Idt table.\r
+\r
+  @return Pointer to the allocated IA32_DESCRIPTOR buffer.\r
+**/\r
+VOID *\r
+InitializeBspIdt (\r
+  VOID\r
+  )\r
+{\r
+  UINTN            *NewIdtTable;\r
+  IA32_DESCRIPTOR  *Idtr;\r
+\r
+  Idtr = AllocateZeroPool (sizeof (IA32_DESCRIPTOR));\r
+  ASSERT (Idtr != NULL);\r
+  NewIdtTable = AllocateZeroPool (sizeof (IA32_IDT_GATE_DESCRIPTOR) * CPU_INTERRUPT_NUM);\r
+  ASSERT (NewIdtTable != NULL);\r
+  Idtr->Base  = (UINTN)NewIdtTable;\r
+  Idtr->Limit = (UINT16)(sizeof (IA32_IDT_GATE_DESCRIPTOR) * CPU_INTERRUPT_NUM - 1);\r
+\r
+  AsmWriteIdtr (Idtr);\r
+  return Idtr;\r
+}\r
+\r
+/**\r
+  Retrieve the number of logical processor in the platform and the number of those logical processors that\r
+  are enabled on this boot.\r
+\r
+  @param[in]  MpServices          MP_SERVICES structure.\r
+  @param[out] NumberOfProcessors  Pointer to the total number of logical processors in the system, including\r
+                                  the BSP and disabled APs.\r
+  @param[out] NumberOfEnabledProcessors Pointer to the number of processors in the system that are enabled.\r
+\r
+  @retval EFI_SUCCESS       Retrieve the number of logical processor successfully\r
+  @retval Others            Retrieve the number of logical processor unsuccessfully\r
+**/\r
+EFI_STATUS\r
+MpServicesUnitTestGetNumberOfProcessors (\r
+  IN MP_SERVICES  MpServices,\r
+  OUT UINTN       *NumberOfProcessors,\r
+  OUT UINTN       *NumberOfEnabledProcessors\r
+  )\r
+{\r
+  return MpServices.Protocol->GetNumberOfProcessors (MpServices.Protocol, NumberOfProcessors, NumberOfEnabledProcessors);\r
+}\r
+\r
+/**\r
+  Get the handle number for the calling processor.\r
+\r
+  @param[in]  MpServices      MP_SERVICES structure.\r
+  @param[out] ProcessorNumber The handle number for the calling processor.\r
+\r
+  @retval EFI_SUCCESS       Get the handle number for the calling processor successfully.\r
+  @retval Others            Get the handle number for the calling processor unsuccessfully.\r
+**/\r
+EFI_STATUS\r
+MpServicesUnitTestWhoAmI (\r
+  IN MP_SERVICES  MpServices,\r
+  OUT UINTN       *ProcessorNumber\r
+  )\r
+{\r
+  return MpServices.Protocol->WhoAmI (MpServices.Protocol, ProcessorNumber);\r
+}\r
+\r
+/**\r
+  Caller gets one enabled AP to execute a caller-provided function.\r
+\r
+  @param[in]  MpServices    MP_SERVICES structure.\r
+  @param[in]  Procedure     Pointer to the function to be run on enabled APs of the system.\r
+  @param[in]  ProcessorNumber       The handle number of the AP.\r
+  @param[in]  TimeoutInMicroSeconds Indicates the time limit in microseconds for APs to return from Procedure,\r
+                                    for blocking mode only. Zero means infinity.\r
+  @param[in]  ProcedureArgument     The parameter passed into Procedure for all APs.\r
+\r
+\r
+  @retval EFI_SUCCESS       Caller gets one enabled AP to execute a caller-provided function successfully\r
+  @retval Others            Caller gets one enabled AP to execute a caller-provided function unsuccessfully\r
+**/\r
+EFI_STATUS\r
+MpServicesUnitTestStartupThisAP (\r
+  IN MP_SERVICES       MpServices,\r
+  IN EFI_AP_PROCEDURE  Procedure,\r
+  IN UINTN             ProcessorNumber,\r
+  IN UINTN             TimeoutInMicroSeconds,\r
+  IN VOID              *ProcedureArgument\r
+  )\r
+{\r
+  return MpServices.Protocol->StartupThisAP (MpServices.Protocol, Procedure, ProcessorNumber, NULL, TimeoutInMicroSeconds, ProcedureArgument, NULL);\r
+}\r
+\r
+/**\r
+  Execute a caller provided function on all enabled APs.\r
+\r
+  @param[in]  MpServices    MP_SERVICES structure.\r
+  @param[in]  Procedure     Pointer to the function to be run on enabled APs of the system.\r
+  @param[in]  SingleThread  If TRUE, then all the enabled APs execute the function specified by Procedure\r
+                            one by one, in ascending order of processor handle number.\r
+                            If FALSE, then all the enabled APs execute the function specified by Procedure\r
+                            simultaneously.\r
+  @param[in]  TimeoutInMicroSeconds Indicates the time limit in microseconds for APs to return from Procedure,\r
+                                    for blocking mode only. Zero means infinity.\r
+  @param[in]  ProcedureArgument     The parameter passed into Procedure for all APs.\r
+\r
+  @retval EFI_SUCCESS       Execute a caller provided function on all enabled APs successfully\r
+  @retval Others            Execute a caller provided function on all enabled APs unsuccessfully\r
+**/\r
+EFI_STATUS\r
+MpServicesUnitTestStartupAllAPs (\r
+  IN MP_SERVICES       MpServices,\r
+  IN EFI_AP_PROCEDURE  Procedure,\r
+  IN BOOLEAN           SingleThread,\r
+  IN UINTN             TimeoutInMicroSeconds,\r
+  IN VOID              *ProcedureArgument\r
+  )\r
+{\r
+  return MpServices.Protocol->StartupAllAPs (MpServices.Protocol, Procedure, SingleThread, NULL, TimeoutInMicroSeconds, ProcedureArgument, NULL);\r
+}\r
+\r
+/**\r
+  Get EFI_MP_SERVICES_PROTOCOL pointer.\r
+\r
+  @param[out] MpServices    Pointer to the buffer where EFI_MP_SERVICES_PROTOCOL is stored\r
+\r
+  @retval EFI_SUCCESS       EFI_MP_SERVICES_PROTOCOL interface is returned\r
+  @retval EFI_NOT_FOUND     EFI_MP_SERVICES_PROTOCOL interface is not found\r
+**/\r
+EFI_STATUS\r
+GetMpServices (\r
+  OUT MP_SERVICES  *MpServices\r
+  )\r
+{\r
+  return gBS->LocateProtocol (&gEfiMpServiceProtocolGuid, NULL, (VOID **)&MpServices->Protocol);\r
+}\r
+\r
+/**\r
+  Entry for CpuExceptionHandlerDxeTest driver.\r
+\r
+  @param ImageHandle     Image handle this driver.\r
+  @param SystemTable     Pointer to the System Table.\r
+\r
+  @retval EFI_SUCCESS    The driver executed normally.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+CpuExceptionHandlerTestEntry (\r
+  IN EFI_HANDLE        ImageHandle,\r
+  IN EFI_SYSTEM_TABLE  *SystemTable\r
+  )\r
+{\r
+  EFI_STATUS                  Status;\r
+  UNIT_TEST_FRAMEWORK_HANDLE  Framework;\r
+\r
+  Framework = NULL;\r
+\r
+  DEBUG ((DEBUG_INFO, "%a v%a\n", UNIT_TEST_APP_NAME, UNIT_TEST_APP_VERSION));\r
+\r
+  //\r
+  // Start setting up the test framework for running the tests.\r
+  //\r
+  Status = InitUnitTestFramework (&Framework, UNIT_TEST_APP_NAME, gEfiCallerBaseName, UNIT_TEST_APP_VERSION);\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((DEBUG_ERROR, "Failed in InitUnitTestFramework. Status = %r\n", Status));\r
+    goto EXIT;\r
+  }\r
+\r
+  Status = AddCommonTestCase (Framework);\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((DEBUG_ERROR, "Failed in AddCommonTestCase. Status = %r\n", Status));\r
+    goto EXIT;\r
+  }\r
+\r
+  //\r
+  // Execute the tests.\r
+  //\r
+  Status = RunAllTestSuites (Framework);\r
+\r
+EXIT:\r
+  if (Framework) {\r
+    FreeUnitTestFramework (Framework);\r
+  }\r
+\r
+  return Status;\r
+}\r