]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / UefiCpuPkg / Library / CpuExceptionHandlerLib / SecPeiCpuException.c
index 7e94e38ae1f50e30da355056d89e0616f5fb5584..497cd1649930d341da29022ce97a2dd0415ed0eb 100644 (file)
@@ -1,25 +1,16 @@
 /** @file\r
   CPU exception handler library implemenation for SEC/PEIM modules.\r
 \r
-Copyright (c) 2012 - 2013, 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
+Copyright (c) 2012 - 2022, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
 #include <PiPei.h>\r
+#include <Library/CcExitLib.h>\r
 #include "CpuExceptionCommon.h"\r
 \r
-//\r
-// Image Aglinment size for SEC/PEI phase\r
-//\r
-CONST UINTN    mImageAlignSize   = 4;\r
-CONST UINTN    mDoFarReturnFlag  = 0;\r
+CONST UINTN  mDoFarReturnFlag = 0;\r
 \r
 /**\r
   Common exception handler.\r
@@ -30,15 +21,62 @@ 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 = CcExitHandleVc (&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 = CcExitHandleVe (&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
+  SerialPortInitialize ();\r
   //\r
   // Display ExceptionType, CPU information and Image information\r
-  //  \r
-  DumpCpuContent (ExceptionType, SystemContext);\r
-  \r
+  //\r
+  DumpImageAndCpuContent (ExceptionType, SystemContext);\r
+\r
   //\r
   // Enter a dead loop.\r
   //\r
@@ -47,17 +85,17 @@ CommonExceptionHandler (
 \r
 /**\r
   Initializes all CPU exceptions entries and provides the default exception handlers.\r
-  \r
+\r
   Caller should try to get an array of interrupt and/or exception vectors that are in use and need to\r
   persist by EFI_VECTOR_HANDOFF_INFO defined in PI 1.3 specification.\r
-  If caller cannot get reserved vector list or it does not exists, set VectorInfo to NULL. \r
+  If caller cannot get reserved vector list or it does not exists, set VectorInfo to NULL.\r
   If VectorInfo is not NULL, the exception vectors will be initialized per vector attribute accordingly.\r
-  Note: Before invoking this API, caller must allocate memory for IDT table and load \r
+  Note: Before invoking this API, caller must allocate memory for IDT table and load\r
         IDTR by AsmWriteIdtr().\r
 \r
   @param[in]  VectorInfo    Pointer to reserved vector list.\r
-  \r
-  @retval EFI_SUCCESS           CPU Exception Entries have been successfully initialized \r
+\r
+  @retval EFI_SUCCESS           CPU Exception Entries have been successfully initialized\r
                                 with default exception handlers.\r
   @retval EFI_INVALID_PARAMETER VectorInfo includes the invalid content if VectorInfo is not NULL.\r
   @retval EFI_UNSUPPORTED       This function is not supported.\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,49 +155,26 @@ 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
-  return EFI_SUCCESS;\r
-}\r
 \r
-/**\r
-  Initializes all CPU interrupt/exceptions entries and provides the default interrupt/exception handlers.\r
-  \r
-  Caller should try to get an array of interrupt and/or exception vectors that are in use and need to\r
-  persist by EFI_VECTOR_HANDOFF_INFO defined in PI 1.3 specification.\r
-  If caller cannot get reserved vector list or it does not exists, set VectorInfo to NULL. \r
-  If VectorInfo is not NULL, the exception vectors will be initialized per vector attribute accordingly.\r
-\r
-  @param[in]  VectorInfo    Pointer to reserved vector list.\r
-  \r
-  @retval EFI_SUCCESS           All CPU interrupt/exception entries have been successfully initialized \r
-                                with default interrupt/exception handlers.\r
-  @retval EFI_INVALID_PARAMETER VectorInfo includes the invalid content if VectorInfo is not NULL.\r
-  @retval EFI_UNSUPPORTED       This function is not supported.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-InitializeCpuInterruptHandlers (\r
-  IN EFI_VECTOR_HANDOFF_INFO       *VectorInfo OPTIONAL\r
-  )\r
-{\r
-  return EFI_UNSUPPORTED;\r
+  return EFI_SUCCESS;\r
 }\r
 \r
 /**\r
   Registers a function to be called from the processor interrupt handler.\r
 \r
-  This function registers and enables the handler specified by InterruptHandler for a processor \r
-  interrupt or exception type specified by InterruptType. If InterruptHandler is NULL, then the \r
-  handler for the processor interrupt or exception type specified by InterruptType is uninstalled. \r
+  This function registers and enables the handler specified by InterruptHandler for a processor\r
+  interrupt or exception type specified by InterruptType. If InterruptHandler is NULL, then the\r
+  handler for the processor interrupt or exception type specified by InterruptType is uninstalled.\r
   The installed handler is called once for each processor interrupt or exception.\r
-  NOTE: This function should be invoked after InitializeCpuExceptionHandlers() or\r
-  InitializeCpuInterruptHandlers() invoked, otherwise EFI_UNSUPPORTED returned.\r
+  NOTE: This function should be invoked after InitializeCpuExceptionHandlers() is invoked,\r
+  otherwise EFI_UNSUPPORTED returned.\r
 \r
   @param[in]  InterruptType     Defines which interrupt or exception to hook.\r
   @param[in]  InterruptHandler  A pointer to a function of type EFI_CPU_INTERRUPT_HANDLER that is called\r
@@ -175,9 +192,33 @@ 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
-}
\ No newline at end of file
+}\r
+\r
+/**\r
+  Setup separate stacks for certain exception handlers.\r
+  If the input Buffer and BufferSize are both NULL, use global variable if possible.\r
+\r
+  @param[in]       Buffer        Point to buffer used to separate exception stack.\r
+  @param[in, out]  BufferSize    On input, it indicates the byte size of Buffer.\r
+                                 If the size is not enough, the return status will\r
+                                 be EFI_BUFFER_TOO_SMALL, and output BufferSize\r
+                                 will be the size it needs.\r
+\r
+  @retval EFI_SUCCESS             The stacks are assigned successfully.\r
+  @retval EFI_UNSUPPORTED         This function is not supported.\r
+  @retval EFI_BUFFER_TOO_SMALL    This BufferSize is too small.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+InitializeSeparateExceptionStacks (\r
+  IN     VOID   *Buffer,\r
+  IN OUT UINTN  *BufferSize\r
+  )\r
+{\r
+  return EFI_UNSUPPORTED;\r
+}\r