]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c
UefiCpuPkg/CpuExceptionHandler: Add base support for the #VE exception
[mirror_edk2.git] / UefiCpuPkg / Library / CpuExceptionHandlerLib / SecPeiCpuException.c
index 68b159e0abfccd115af807e10e8389620558e955..6e5216380da83acf8507ea6423bb105fb82a28a7 100644 (file)
@@ -2,20 +2,15 @@
   CPU exception handler library implemenation for SEC/PEIM modules.\r
 \r
 Copyright (c) 2012 - 2018, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials are licensed and made available under\r
-the terms and conditions of the BSD License that accompanies this distribution.\r
-The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php.\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
 #include <PiPei.h>\r
+#include <Library/VmgExitLib.h>\r
 #include "CpuExceptionCommon.h"\r
 \r
-CONST UINTN    mDoFarReturnFlag  = 0;\r
+CONST UINTN  mDoFarReturnFlag = 0;\r
 \r
 /**\r
   Common exception handler.\r
@@ -26,10 +21,53 @@ CONST UINTN    mDoFarReturnFlag  = 0;
 VOID\r
 EFIAPI\r
 CommonExceptionHandler (\r
-  IN EFI_EXCEPTION_TYPE   ExceptionType,\r
-  IN EFI_SYSTEM_CONTEXT   SystemContext\r
+  IN EFI_EXCEPTION_TYPE  ExceptionType,\r
+  IN EFI_SYSTEM_CONTEXT  SystemContext\r
   )\r
 {\r
+  EFI_STATUS  Status;\r
+\r
+  switch (ExceptionType) {\r
+    case VC_EXCEPTION:\r
+      //\r
+      // #VC needs to be handled immediately upon enabling exception handling\r
+      // and therefore can't use the RegisterCpuInterruptHandler() interface\r
+      // (which isn't supported under Sec and Pei anyway).\r
+      //\r
+      // Handle the #VC:\r
+      //   On EFI_SUCCESS - Exception has been handled, return\r
+      //   On other       - ExceptionType contains (possibly new) exception\r
+      //                    value\r
+      //\r
+      Status = VmgExitHandleVc (&ExceptionType, SystemContext);\r
+      if (!EFI_ERROR (Status)) {\r
+        return;\r
+      }\r
+\r
+      break;\r
+\r
+    case VE_EXCEPTION:\r
+      //\r
+      // #VE needs to be handled immediately upon enabling exception handling\r
+      // and therefore can't use the RegisterCpuInterruptHandler() interface\r
+      // (which isn't supported under Sec and Pei anyway).\r
+      //\r
+      // Handle the #VE:\r
+      //   On EFI_SUCCESS - Exception has been handled, return\r
+      //   On other       - ExceptionType contains (possibly new) exception\r
+      //                    value\r
+      //\r
+      Status = VmTdExitHandleVe (&ExceptionType, SystemContext);\r
+      if (!EFI_ERROR (Status)) {\r
+        return;\r
+      }\r
+\r
+      break;\r
+\r
+    default:\r
+      break;\r
+  }\r
+\r
   //\r
   // Initialize the serial port before dumping.\r
   //\r
@@ -66,26 +104,27 @@ CommonExceptionHandler (
 EFI_STATUS\r
 EFIAPI\r
 InitializeCpuExceptionHandlers (\r
-  IN EFI_VECTOR_HANDOFF_INFO       *VectorInfo OPTIONAL\r
+  IN EFI_VECTOR_HANDOFF_INFO  *VectorInfo OPTIONAL\r
   )\r
 {\r
-  EFI_STATUS                       Status;\r
-  RESERVED_VECTORS_DATA            ReservedVectorData[CPU_EXCEPTION_NUM];\r
-  IA32_DESCRIPTOR                  IdtDescriptor;\r
-  UINTN                            IdtEntryCount;\r
-  UINT16                           CodeSegment;\r
-  EXCEPTION_HANDLER_TEMPLATE_MAP   TemplateMap;\r
-  IA32_IDT_GATE_DESCRIPTOR         *IdtTable;\r
-  UINTN                            Index;\r
-  UINTN                            InterruptHandler;\r
+  EFI_STATUS                      Status;\r
+  RESERVED_VECTORS_DATA           ReservedVectorData[CPU_EXCEPTION_NUM];\r
+  IA32_DESCRIPTOR                 IdtDescriptor;\r
+  UINTN                           IdtEntryCount;\r
+  UINT16                          CodeSegment;\r
+  EXCEPTION_HANDLER_TEMPLATE_MAP  TemplateMap;\r
+  IA32_IDT_GATE_DESCRIPTOR        *IdtTable;\r
+  UINTN                           Index;\r
+  UINTN                           InterruptHandler;\r
 \r
   if (VectorInfo != NULL) {\r
-    SetMem ((VOID *) ReservedVectorData, sizeof (RESERVED_VECTORS_DATA) * CPU_EXCEPTION_NUM, 0xff);\r
+    SetMem ((VOID *)ReservedVectorData, sizeof (RESERVED_VECTORS_DATA) * CPU_EXCEPTION_NUM, 0xff);\r
     Status = ReadAndVerifyVectorInfo (VectorInfo, ReservedVectorData, CPU_EXCEPTION_NUM);\r
     if (EFI_ERROR (Status)) {\r
       return EFI_INVALID_PARAMETER;\r
     }\r
   }\r
+\r
   //\r
   // Read IDT descriptor and calculate IDT size\r
   //\r
@@ -93,10 +132,11 @@ InitializeCpuExceptionHandlers (
   IdtEntryCount = (IdtDescriptor.Limit + 1) / sizeof (IA32_IDT_GATE_DESCRIPTOR);\r
   if (IdtEntryCount > CPU_EXCEPTION_NUM) {\r
     //\r
-    // CPU exeption library only setup CPU_EXCEPTION_NUM exception handler at most\r
+    // CPU exception library only setup CPU_EXCEPTION_NUM exception handler at most\r
     //\r
     IdtEntryCount = CPU_EXCEPTION_NUM;\r
   }\r
+\r
   //\r
   // Use current CS as the segment selector of interrupt gate in IDT\r
   //\r
@@ -104,7 +144,7 @@ InitializeCpuExceptionHandlers (
 \r
   AsmGetTemplateAddressMap (&TemplateMap);\r
   IdtTable = (IA32_IDT_GATE_DESCRIPTOR *)IdtDescriptor.Base;\r
-  for (Index = 0; Index < IdtEntryCount; Index ++) {\r
+  for (Index = 0; Index < IdtEntryCount; Index++) {\r
     IdtTable[Index].Bits.Selector = CodeSegment;\r
     //\r
     // Check reserved vectors attributes if has, only EFI_VECTOR_HANDOFF_DO_NOT_HOOK\r
@@ -115,12 +155,14 @@ InitializeCpuExceptionHandlers (
         continue;\r
       }\r
     }\r
+\r
     //\r
     // Update IDT entry\r
     //\r
     InterruptHandler = TemplateMap.ExceptionStart + Index * TemplateMap.ExceptionStubHeaderSize;\r
     ArchUpdateIdtEntry (&IdtTable[Index], InterruptHandler);\r
   }\r
+\r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -143,7 +185,7 @@ InitializeCpuExceptionHandlers (
 EFI_STATUS\r
 EFIAPI\r
 InitializeCpuInterruptHandlers (\r
-  IN EFI_VECTOR_HANDOFF_INFO       *VectorInfo OPTIONAL\r
+  IN EFI_VECTOR_HANDOFF_INFO  *VectorInfo OPTIONAL\r
   )\r
 {\r
   return EFI_UNSUPPORTED;\r
@@ -175,8 +217,8 @@ InitializeCpuInterruptHandlers (
 EFI_STATUS\r
 EFIAPI\r
 RegisterCpuInterruptHandler (\r
-  IN EFI_EXCEPTION_TYPE            InterruptType,\r
-  IN EFI_CPU_INTERRUPT_HANDLER     InterruptHandler\r
+  IN EFI_EXCEPTION_TYPE         InterruptType,\r
+  IN EFI_CPU_INTERRUPT_HANDLER  InterruptHandler\r
   )\r
 {\r
   return EFI_UNSUPPORTED;\r
@@ -207,8 +249,8 @@ RegisterCpuInterruptHandler (
 EFI_STATUS\r
 EFIAPI\r
 InitializeCpuExceptionHandlersEx (\r
-  IN EFI_VECTOR_HANDOFF_INFO            *VectorInfo OPTIONAL,\r
-  IN CPU_EXCEPTION_INIT_DATA            *InitData OPTIONAL\r
+  IN EFI_VECTOR_HANDOFF_INFO  *VectorInfo OPTIONAL,\r
+  IN CPU_EXCEPTION_INIT_DATA  *InitData OPTIONAL\r
   )\r
 {\r
   return InitializeCpuExceptionHandlers (VectorInfo);\r