]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/Library/CpuExceptionHandlerLib/UnitTest/X64/ArchExceptionHandlerTest.c
UefiCpuPkg: Add Unit tests for DxeCpuExceptionHandlerLib
[mirror_edk2.git] / UefiCpuPkg / Library / CpuExceptionHandlerLib / UnitTest / X64 / ArchExceptionHandlerTest.c
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/UnitTest/X64/ArchExceptionHandlerTest.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/UnitTest/X64/ArchExceptionHandlerTest.c
new file mode 100644 (file)
index 0000000..c0d962f
--- /dev/null
@@ -0,0 +1,166 @@
+/** @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
+\r
+GENERAL_REGISTER  mActualContextInHandler;\r
+GENERAL_REGISTER  mActualContextAfterException;\r
+\r
+//\r
+// In TestCpuContextConsistency, Cpu registers will be set to mExpectedContextInHandler/mExpectedContextAfterException.\r
+// Rcx in mExpectedContextInHandler is set runtime since Rcx is needed in assembly code.\r
+// For GP and PF, Rcx is set to FaultParameter. For other exception triggered by INTn, Rcx is set to ExceptionType.\r
+//\r
+GENERAL_REGISTER  mExpectedContextInHandler      = { 1, 2, 3, 4, 5, 0, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe };\r
+GENERAL_REGISTER  mExpectedContextAfterException = { 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e };\r
+\r
+/**\r
+  Special handler for fault exception.\r
+  Rip/Eip in SystemContext will be modified to the instruction after the exception instruction.\r
+\r
+  @param ExceptionType  Exception type.\r
+  @param SystemContext  Pointer to EFI_SYSTEM_CONTEXT.\r
+**/\r
+VOID\r
+EFIAPI\r
+AdjustRipForFaultHandler (\r
+  IN EFI_EXCEPTION_TYPE  ExceptionType,\r
+  IN EFI_SYSTEM_CONTEXT  SystemContext\r
+  )\r
+{\r
+  mExceptionType                       = ExceptionType;\r
+  SystemContext.SystemContextX64->Rip += mFaultInstructionLength;\r
+}\r
+\r
+/**\r
+  Special handler for ConsistencyOfCpuContext test case.\r
+\r
+  @param ExceptionType  Exception type.\r
+  @param SystemContext  Pointer to EFI_SYSTEM_CONTEXT.\r
+**/\r
+VOID\r
+EFIAPI\r
+AdjustCpuContextHandler (\r
+  IN EFI_EXCEPTION_TYPE  ExceptionType,\r
+  IN EFI_SYSTEM_CONTEXT  SystemContext\r
+  )\r
+{\r
+  //\r
+  // Store SystemContext in mActualContextInHandler.\r
+  //\r
+  mActualContextInHandler.Rdi = SystemContext.SystemContextX64->Rdi;\r
+  mActualContextInHandler.Rsi = SystemContext.SystemContextX64->Rsi;\r
+  mActualContextInHandler.Rbx = SystemContext.SystemContextX64->Rbx;\r
+  mActualContextInHandler.Rdx = SystemContext.SystemContextX64->Rdx;\r
+  mActualContextInHandler.Rcx = SystemContext.SystemContextX64->Rcx;\r
+  mActualContextInHandler.Rax = SystemContext.SystemContextX64->Rax;\r
+  mActualContextInHandler.R8  = SystemContext.SystemContextX64->R8;\r
+  mActualContextInHandler.R9  = SystemContext.SystemContextX64->R9;\r
+  mActualContextInHandler.R10 = SystemContext.SystemContextX64->R10;\r
+  mActualContextInHandler.R11 = SystemContext.SystemContextX64->R11;\r
+  mActualContextInHandler.R12 = SystemContext.SystemContextX64->R12;\r
+  mActualContextInHandler.R13 = SystemContext.SystemContextX64->R13;\r
+  mActualContextInHandler.R14 = SystemContext.SystemContextX64->R14;\r
+  mActualContextInHandler.R15 = SystemContext.SystemContextX64->R15;\r
+\r
+  //\r
+  // Modify cpu context. These registers will be stored in mActualContextAfterException.\r
+  // Do not handle Rsp and Rbp. CpuExceptionHandlerLib doesn't set Rsp and Rbp register\r
+  // to the value in SystemContext.\r
+  //\r
+  SystemContext.SystemContextX64->Rdi = mExpectedContextAfterException.Rdi;\r
+  SystemContext.SystemContextX64->Rsi = mExpectedContextAfterException.Rsi;\r
+  SystemContext.SystemContextX64->Rbx = mExpectedContextAfterException.Rbx;\r
+  SystemContext.SystemContextX64->Rdx = mExpectedContextAfterException.Rdx;\r
+  SystemContext.SystemContextX64->Rcx = mExpectedContextAfterException.Rcx;\r
+  SystemContext.SystemContextX64->Rax = mExpectedContextAfterException.Rax;\r
+  SystemContext.SystemContextX64->R8  = mExpectedContextAfterException.R8;\r
+  SystemContext.SystemContextX64->R9  = mExpectedContextAfterException.R9;\r
+  SystemContext.SystemContextX64->R10 = mExpectedContextAfterException.R10;\r
+  SystemContext.SystemContextX64->R11 = mExpectedContextAfterException.R11;\r
+  SystemContext.SystemContextX64->R12 = mExpectedContextAfterException.R12;\r
+  SystemContext.SystemContextX64->R13 = mExpectedContextAfterException.R13;\r
+  SystemContext.SystemContextX64->R14 = mExpectedContextAfterException.R14;\r
+  SystemContext.SystemContextX64->R15 = mExpectedContextAfterException.R15;\r
+\r
+  //\r
+  // When fault exception happens, eip/rip points to the faulting instruction.\r
+  // For now, olny GP and PF are tested in fault exception.\r
+  //\r
+  if ((ExceptionType == EXCEPT_IA32_PAGE_FAULT) || (ExceptionType == EXCEPT_IA32_GP_FAULT)) {\r
+    AdjustRipForFaultHandler (ExceptionType, SystemContext);\r
+  }\r
+}\r
+\r
+/**\r
+  Compare cpu context in ConsistencyOfCpuContext test case.\r
+  1.Compare mActualContextInHandler with mExpectedContextInHandler.\r
+  2.Compare mActualContextAfterException with mActualContextAfterException.\r
+\r
+  @retval  UNIT_TEST_PASSED             The Unit test has completed and it was successful.\r
+  @retval  UNIT_TEST_ERROR_TEST_FAILED  A test case assertion has failed.\r
+**/\r
+UNIT_TEST_STATUS\r
+CompareCpuContext (\r
+  VOID\r
+  )\r
+{\r
+  UT_ASSERT_EQUAL (mActualContextInHandler.Rdi, mExpectedContextInHandler.Rdi);\r
+  UT_ASSERT_EQUAL (mActualContextInHandler.Rsi, mExpectedContextInHandler.Rsi);\r
+  UT_ASSERT_EQUAL (mActualContextInHandler.Rbx, mExpectedContextInHandler.Rbx);\r
+  UT_ASSERT_EQUAL (mActualContextInHandler.Rdx, mExpectedContextInHandler.Rdx);\r
+  UT_ASSERT_EQUAL (mActualContextInHandler.Rcx, mExpectedContextInHandler.Rcx);\r
+  UT_ASSERT_EQUAL (mActualContextInHandler.Rax, mExpectedContextInHandler.Rax);\r
+  UT_ASSERT_EQUAL (mActualContextInHandler.R8, mExpectedContextInHandler.R8);\r
+  UT_ASSERT_EQUAL (mActualContextInHandler.R9, mExpectedContextInHandler.R9);\r
+  UT_ASSERT_EQUAL (mActualContextInHandler.R10, mExpectedContextInHandler.R10);\r
+  UT_ASSERT_EQUAL (mActualContextInHandler.R11, mExpectedContextInHandler.R11);\r
+  UT_ASSERT_EQUAL (mActualContextInHandler.R12, mExpectedContextInHandler.R12);\r
+  UT_ASSERT_EQUAL (mActualContextInHandler.R13, mExpectedContextInHandler.R13);\r
+  UT_ASSERT_EQUAL (mActualContextInHandler.R14, mExpectedContextInHandler.R14);\r
+  UT_ASSERT_EQUAL (mActualContextInHandler.R15, mExpectedContextInHandler.R15);\r
+\r
+  UT_ASSERT_EQUAL (mActualContextAfterException.Rdi, mExpectedContextAfterException.Rdi);\r
+  UT_ASSERT_EQUAL (mActualContextAfterException.Rsi, mExpectedContextAfterException.Rsi);\r
+  UT_ASSERT_EQUAL (mActualContextAfterException.Rbx, mExpectedContextAfterException.Rbx);\r
+  UT_ASSERT_EQUAL (mActualContextAfterException.Rdx, mExpectedContextAfterException.Rdx);\r
+  UT_ASSERT_EQUAL (mActualContextAfterException.Rcx, mExpectedContextAfterException.Rcx);\r
+  UT_ASSERT_EQUAL (mActualContextAfterException.Rax, mExpectedContextAfterException.Rax);\r
+  UT_ASSERT_EQUAL (mActualContextAfterException.R8, mExpectedContextAfterException.R8);\r
+  UT_ASSERT_EQUAL (mActualContextAfterException.R9, mExpectedContextAfterException.R9);\r
+  UT_ASSERT_EQUAL (mActualContextAfterException.R10, mExpectedContextAfterException.R10);\r
+  UT_ASSERT_EQUAL (mActualContextAfterException.R11, mExpectedContextAfterException.R11);\r
+  UT_ASSERT_EQUAL (mActualContextAfterException.R12, mExpectedContextAfterException.R12);\r
+  UT_ASSERT_EQUAL (mActualContextAfterException.R13, mExpectedContextAfterException.R13);\r
+  UT_ASSERT_EQUAL (mActualContextAfterException.R14, mExpectedContextAfterException.R14);\r
+  UT_ASSERT_EQUAL (mActualContextAfterException.R15, mExpectedContextAfterException.R15);\r
+  return UNIT_TEST_PASSED;\r
+}\r
+\r
+/**\r
+  Special handler for CpuStackGuard test case.\r
+\r
+  @param ExceptionType  Exception type.\r
+  @param SystemContext  Pointer to EFI_SYSTEM_CONTEXT.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+CpuStackGuardExceptionHandler (\r
+  IN EFI_EXCEPTION_TYPE  ExceptionType,\r
+  IN EFI_SYSTEM_CONTEXT  SystemContext\r
+  )\r
+{\r
+  UINTN  LocalVariable;\r
+\r
+  AdjustRipForFaultHandler (ExceptionType, SystemContext);\r
+  mRspAddress[0] = (UINTN)SystemContext.SystemContextX64->Rsp;\r
+  mRspAddress[1] = (UINTN)(&LocalVariable);\r
+\r
+  return;\r
+}\r