]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiDxeSmmCpuException.c
UefiCpuPkg: Apply uncrustify changes
[mirror_edk2.git] / UefiCpuPkg / Library / CpuExceptionHandlerLib / PeiDxeSmmCpuException.c
index c7382804134ff7d5c76751616968c569b93e323c..762ea2460f9191ebe10026e43b97fe540dfe446a 100644 (file)
 /** @file\r
   CPU Exception Library provides PEI/DXE/SMM CPU common exception handler.\r
 \r
-Copyright (c) 2012 - 2016, 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 - 2018, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
-#include "CpuExceptionCommon.h"\r
 #include <Library/DebugLib.h>\r
-\r
-//\r
-// Spinlock for CPU information display\r
-//\r
-SPIN_LOCK        mDisplayMessageSpinLock;\r
-\r
-//\r
-// Image align size for DXE/SMM\r
-//\r
-CONST UINTN      mImageAlignSize = SIZE_4KB;\r
-\r
-RESERVED_VECTORS_DATA       mReservedVectorsData[CPU_EXCEPTION_NUM];\r
-EFI_CPU_INTERRUPT_HANDLER   mExternalInterruptHandlerTable[CPU_EXCEPTION_NUM];\r
-EFI_CPU_INTERRUPT_HANDLER   *mExternalInterruptHandler = NULL;\r
-UINTN                       mEnabledInterruptNum = 0;\r
+#include <Library/VmgExitLib.h>\r
+#include "CpuExceptionCommon.h"\r
 \r
 /**\r
-  Common exception handler.\r
+  Internal worker function for common exception handler.\r
 \r
-  @param ExceptionType  Exception type.\r
-  @param SystemContext  Pointer to EFI_SYSTEM_CONTEXT.\r
+  @param ExceptionType         Exception type.\r
+  @param SystemContext         Pointer to EFI_SYSTEM_CONTEXT.\r
+  @param ExceptionHandlerData  Pointer to exception handler data.\r
 **/\r
 VOID\r
-EFIAPI\r
-CommonExceptionHandler (\r
-  IN EFI_EXCEPTION_TYPE          ExceptionType, \r
-  IN EFI_SYSTEM_CONTEXT          SystemContext\r
+CommonExceptionHandlerWorker (\r
+  IN EFI_EXCEPTION_TYPE      ExceptionType,\r
+  IN EFI_SYSTEM_CONTEXT      SystemContext,\r
+  IN EXCEPTION_HANDLER_DATA  *ExceptionHandlerData\r
   )\r
 {\r
-  EXCEPTION_HANDLER_CONTEXT      *ExceptionHandlerContext;\r
+  EXCEPTION_HANDLER_CONTEXT  *ExceptionHandlerContext;\r
+  RESERVED_VECTORS_DATA      *ReservedVectors;\r
+  EFI_CPU_INTERRUPT_HANDLER  *ExternalInterruptHandler;\r
 \r
-  ExceptionHandlerContext = (EXCEPTION_HANDLER_CONTEXT *) (UINTN) (SystemContext.SystemContextIa32);\r
-\r
-  switch (mReservedVectors[ExceptionType].Attribute) {\r
-  case EFI_VECTOR_HANDOFF_HOOK_BEFORE:\r
+  if (ExceptionType == VC_EXCEPTION) {\r
+    EFI_STATUS  Status;\r
     //\r
-    // Need to jmp to old IDT handler after this exception handler\r
+    // #VC needs to be handled immediately upon enabling exception handling\r
+    // and therefore can't use the RegisterCpuInterruptHandler() interface.\r
     //\r
-    ExceptionHandlerContext->ExceptionDataFlag = (mErrorCodeFlag & (1 << ExceptionType)) ? TRUE : FALSE;\r
-    ExceptionHandlerContext->OldIdtHandler     = mReservedVectors[ExceptionType].ExceptonHandler;\r
-    break;\r
-  case EFI_VECTOR_HANDOFF_HOOK_AFTER:\r
-    while (TRUE) {\r
-      //\r
-      // If if anyone has gotten SPIN_LOCK for owner running hook after\r
-      //\r
-      if (AcquireSpinLockOrFail (&mReservedVectors[ExceptionType].SpinLock)) {\r
-        //\r
-        // Need to execute old IDT handler before running this exception handler\r
-        //\r
-        mReservedVectors[ExceptionType].ApicId = GetApicId ();\r
-        ArchSaveExceptionContext (ExceptionType, SystemContext);\r
-        ExceptionHandlerContext->ExceptionDataFlag = (mErrorCodeFlag & (1 << ExceptionType)) ? TRUE : FALSE;\r
-        ExceptionHandlerContext->OldIdtHandler     = mReservedVectors[ExceptionType].ExceptonHandler;\r
-        return;\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
+\r
+  ExceptionHandlerContext  = (EXCEPTION_HANDLER_CONTEXT *)(UINTN)(SystemContext.SystemContextIa32);\r
+  ReservedVectors          = ExceptionHandlerData->ReservedVectors;\r
+  ExternalInterruptHandler = ExceptionHandlerData->ExternalInterruptHandler;\r
+\r
+  switch (ReservedVectors[ExceptionType].Attribute) {\r
+    case EFI_VECTOR_HANDOFF_HOOK_BEFORE:\r
       //\r
-      // If failed to acquire SPIN_LOCK, check if it was locked by processor itself\r
+      // The new exception handler registered by RegisterCpuInterruptHandler() is executed BEFORE original handler.\r
+      // Save the original handler to stack so the assembly code can jump to it instead of returning from handler.\r
       //\r
-      if (mReservedVectors[ExceptionType].ApicId == GetApicId ()) {\r
+      ExceptionHandlerContext->ExceptionDataFlag = (mErrorCodeFlag & (1 << ExceptionType)) ? TRUE : FALSE;\r
+      ExceptionHandlerContext->OldIdtHandler     = ReservedVectors[ExceptionType].ExceptonHandler;\r
+      break;\r
+    case EFI_VECTOR_HANDOFF_HOOK_AFTER:\r
+      while (TRUE) {\r
         //\r
-        // Old IDT handler has been executed, then retore CPU exception content to\r
-        // run new exception handler.\r
+        // If spin-lock can be acquired, it's the first time entering here.\r
         //\r
-        ArchRestoreExceptionContext (ExceptionType, SystemContext);\r
+        if (AcquireSpinLockOrFail (&ReservedVectors[ExceptionType].SpinLock)) {\r
+          //\r
+          // The new exception handler registered by RegisterCpuInterruptHandler() is executed AFTER original handler.\r
+          // Save the original handler to stack but skip running the new handler so the original handler is executed\r
+          // firstly.\r
+          //\r
+          ReservedVectors[ExceptionType].ApicId = GetApicId ();\r
+          ArchSaveExceptionContext (ExceptionType, SystemContext, ExceptionHandlerData);\r
+          ExceptionHandlerContext->ExceptionDataFlag = (mErrorCodeFlag & (1 << ExceptionType)) ? TRUE : FALSE;\r
+          ExceptionHandlerContext->OldIdtHandler     = ReservedVectors[ExceptionType].ExceptonHandler;\r
+          return;\r
+        }\r
+\r
         //\r
-        // Rlease spin lock for ApicId\r
+        // If spin-lock cannot be acquired, it's the second time entering here.\r
+        // 'break' instead of 'return' is used so the new exception handler can be executed.\r
         //\r
-        ReleaseSpinLock (&mReservedVectors[ExceptionType].SpinLock);\r
-        break;\r
+        if (ReservedVectors[ExceptionType].ApicId == GetApicId ()) {\r
+          //\r
+          // Old IDT handler has been executed, then restore CPU exception content to\r
+          // run new exception handler.\r
+          //\r
+          ArchRestoreExceptionContext (ExceptionType, SystemContext, ExceptionHandlerData);\r
+          //\r
+          // Release spin lock for ApicId\r
+          //\r
+          ReleaseSpinLock (&ReservedVectors[ExceptionType].SpinLock);\r
+          break;\r
+        }\r
+\r
+        CpuPause ();\r
       }\r
-      CpuPause ();\r
-    }\r
-    break;\r
-  case 0xffffffff:\r
-    break;\r
-  default:\r
-    //\r
-    // It should never reach here\r
-    //\r
-    CpuDeadLoop ();\r
-    break;\r
+\r
+      break;\r
+    case 0xffffffff:\r
+      break;\r
+    default:\r
+      //\r
+      // It should never reach here\r
+      //\r
+      CpuDeadLoop ();\r
+      break;\r
   }\r
-  \r
-  if (mExternalInterruptHandler[ExceptionType] != NULL) {\r
-    (mExternalInterruptHandler[ExceptionType]) (ExceptionType, SystemContext);\r
+\r
+  if ((ExternalInterruptHandler != NULL) &&\r
+      (ExternalInterruptHandler[ExceptionType] != NULL))\r
+  {\r
+    (ExternalInterruptHandler[ExceptionType])(ExceptionType, SystemContext);\r
   } else if (ExceptionType < CPU_EXCEPTION_NUM) {\r
     //\r
     // Get Spinlock to display CPU information\r
     //\r
-    while (!AcquireSpinLockOrFail (&mDisplayMessageSpinLock)) {\r
+    while (!AcquireSpinLockOrFail (&ExceptionHandlerData->DisplayMessageSpinLock)) {\r
       CpuPause ();\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
+    DumpImageAndCpuContent (ExceptionType, SystemContext);\r
     //\r
     // Release Spinlock of output message\r
     //\r
-    ReleaseSpinLock (&mDisplayMessageSpinLock);\r
+    ReleaseSpinLock (&ExceptionHandlerData->DisplayMessageSpinLock);\r
     //\r
     // Enter a dead loop if needn't to execute old IDT handler further\r
     //\r
-    if (mReservedVectors[ExceptionType].Attribute != EFI_VECTOR_HANDOFF_HOOK_BEFORE) {\r
+    if (ReservedVectors[ExceptionType].Attribute != EFI_VECTOR_HANDOFF_HOOK_BEFORE) {\r
       CpuDeadLoop ();\r
     }\r
   }\r
@@ -140,10 +156,10 @@ UpdateIdtTable (
   IN EXCEPTION_HANDLER_DATA          *ExceptionHandlerData\r
   )\r
 {\r
-  UINT16                             CodeSegment;\r
-  UINTN                              Index;\r
-  UINTN                              InterruptHandler;\r
-  RESERVED_VECTORS_DATA              *ReservedVectors;\r
+  UINT16                 CodeSegment;\r
+  UINTN                  Index;\r
+  UINTN                  InterruptHandler;\r
+  RESERVED_VECTORS_DATA  *ReservedVectors;\r
 \r
   ReservedVectors = ExceptionHandlerData->ReservedVectors;\r
   //\r
@@ -151,54 +167,49 @@ UpdateIdtTable (
   //\r
   CodeSegment = AsmReadCs ();\r
 \r
-  for (Index = 0; Index < ExceptionHandlerData->IdtEntryCount; Index ++) {\r
+  for (Index = 0; Index < ExceptionHandlerData->IdtEntryCount; Index++) {\r
     IdtTable[Index].Bits.Selector = CodeSegment;\r
     //\r
     // Check reserved vectors attributes\r
     //\r
     switch (ReservedVectors[Index].Attribute) {\r
-    case EFI_VECTOR_HANDOFF_DO_NOT_HOOK:\r
-      //\r
-      // Keep original IDT entry\r
-      //\r
-      continue;\r
-    case EFI_VECTOR_HANDOFF_HOOK_AFTER:\r
-      InitializeSpinLock (&ReservedVectors[Index].SpinLock);\r
-      CopyMem (\r
-        (VOID *) ReservedVectors[Index].HookAfterStubHeaderCode,\r
-        (VOID *) TemplateMap->HookAfterStubHeaderStart,\r
-        TemplateMap->ExceptionStubHeaderSize\r
-        );\r
-      AsmVectorNumFixup (\r
-        (VOID *) ReservedVectors[Index].HookAfterStubHeaderCode,\r
-        (UINT8) Index,\r
-        (VOID *) TemplateMap->HookAfterStubHeaderStart\r
-        );\r
+      case EFI_VECTOR_HANDOFF_DO_NOT_HOOK:\r
+        //\r
+        // Keep original IDT entry\r
+        //\r
+        continue;\r
+      case EFI_VECTOR_HANDOFF_HOOK_AFTER:\r
+        InitializeSpinLock (&ReservedVectors[Index].SpinLock);\r
+        CopyMem (\r
+          (VOID *)ReservedVectors[Index].HookAfterStubHeaderCode,\r
+          (VOID *)TemplateMap->HookAfterStubHeaderStart,\r
+          TemplateMap->ExceptionStubHeaderSize\r
+          );\r
+        AsmVectorNumFixup (\r
+          (VOID *)ReservedVectors[Index].HookAfterStubHeaderCode,\r
+          (UINT8)Index,\r
+          (VOID *)TemplateMap->HookAfterStubHeaderStart\r
+          );\r
       //\r
       // Go on the following code\r
       //\r
-    case EFI_VECTOR_HANDOFF_HOOK_BEFORE:\r
-      //\r
-      // Save original IDT handler address\r
-      //\r
-      ReservedVectors[Index].ExceptonHandler = ArchGetIdtHandler (&IdtTable[Index]);\r
+      case EFI_VECTOR_HANDOFF_HOOK_BEFORE:\r
+        //\r
+        // Save original IDT handler address\r
+        //\r
+        ReservedVectors[Index].ExceptonHandler = ArchGetIdtHandler (&IdtTable[Index]);\r
       //\r
       // Go on the following code\r
       //\r
-    default:\r
-      //\r
-      // Update new IDT entry\r
-      //\r
-      InterruptHandler = TemplateMap->ExceptionStart + Index * TemplateMap->ExceptionStubHeaderSize;\r
-      ArchUpdateIdtEntry (&IdtTable[Index], InterruptHandler);\r
-      break;\r
+      default:\r
+        //\r
+        // Update new IDT entry\r
+        //\r
+        InterruptHandler = TemplateMap->ExceptionStart + Index * TemplateMap->ExceptionStubHeaderSize;\r
+        ArchUpdateIdtEntry (&IdtTable[Index], InterruptHandler);\r
+        break;\r
     }\r
   }\r
\r
-  //\r
-  // Save Interrupt number to global variable used for RegisterCpuInterruptHandler ()\r
-  //\r
-  mEnabledInterruptNum = ExceptionHandlerData->IdtEntryCount;\r
 }\r
 \r
 /**\r
@@ -206,8 +217,8 @@ UpdateIdtTable (
 \r
   @param[in]      VectorInfo            Pointer to reserved vector list.\r
   @param[in, out] ExceptionHandlerData  Pointer to exception handler data.\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
@@ -215,28 +226,26 @@ UpdateIdtTable (
 **/\r
 EFI_STATUS\r
 InitializeCpuExceptionHandlersWorker (\r
-  IN EFI_VECTOR_HANDOFF_INFO       *VectorInfo OPTIONAL,\r
-  IN OUT EXCEPTION_HANDLER_DATA    *ExceptionHandlerData\r
+  IN EFI_VECTOR_HANDOFF_INFO     *VectorInfo OPTIONAL,\r
+  IN OUT EXCEPTION_HANDLER_DATA  *ExceptionHandlerData\r
   )\r
 {\r
-  EFI_STATUS                       Status;\r
-  IA32_DESCRIPTOR                  IdtDescriptor;\r
-  UINTN                            IdtEntryCount;\r
-  EXCEPTION_HANDLER_TEMPLATE_MAP   TemplateMap;\r
-  IA32_IDT_GATE_DESCRIPTOR         *IdtTable;\r
-  RESERVED_VECTORS_DATA            *ReservedVectors;\r
+  EFI_STATUS                      Status;\r
+  IA32_DESCRIPTOR                 IdtDescriptor;\r
+  UINTN                           IdtEntryCount;\r
+  EXCEPTION_HANDLER_TEMPLATE_MAP  TemplateMap;\r
+  IA32_IDT_GATE_DESCRIPTOR        *IdtTable;\r
+  RESERVED_VECTORS_DATA           *ReservedVectors;\r
 \r
   ReservedVectors = ExceptionHandlerData->ReservedVectors;\r
-  SetMem ((VOID *) ReservedVectors, sizeof (RESERVED_VECTORS_DATA) * CPU_EXCEPTION_NUM, 0xff);\r
+  SetMem ((VOID *)ReservedVectors, sizeof (RESERVED_VECTORS_DATA) * CPU_EXCEPTION_NUM, 0xff);\r
   if (VectorInfo != NULL) {\r
     Status = ReadAndVerifyVectorInfo (VectorInfo, ReservedVectors, CPU_EXCEPTION_NUM);\r
     if (EFI_ERROR (Status)) {\r
       return EFI_INVALID_PARAMETER;\r
     }\r
   }\r
-  InitializeSpinLock (&mDisplayMessageSpinLock);\r
 \r
-  mExternalInterruptHandler = mExternalInterruptHandlerTable;\r
   //\r
   // Read IDT descriptor and calculate IDT size\r
   //\r
@@ -244,18 +253,18 @@ InitializeCpuExceptionHandlersWorker (
   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
-  IdtTable = (IA32_IDT_GATE_DESCRIPTOR *) IdtDescriptor.Base;\r
+  IdtTable = (IA32_IDT_GATE_DESCRIPTOR *)IdtDescriptor.Base;\r
   AsmGetTemplateAddressMap (&TemplateMap);\r
   ASSERT (TemplateMap.ExceptionStubHeaderSize <= HOOKAFTER_STUB_SIZE);\r
 \r
   ExceptionHandlerData->IdtEntryCount = IdtEntryCount;\r
   UpdateIdtTable (IdtTable, &TemplateMap, ExceptionHandlerData);\r
-  mEnabledInterruptNum = IdtEntryCount;\r
+\r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -278,33 +287,33 @@ InitializeCpuExceptionHandlersWorker (
 **/\r
 EFI_STATUS\r
 RegisterCpuInterruptHandlerWorker (\r
-  IN EFI_EXCEPTION_TYPE            InterruptType,\r
-  IN EFI_CPU_INTERRUPT_HANDLER     InterruptHandler,\r
-  IN EXCEPTION_HANDLER_DATA        *ExceptionHandlerData\r
+  IN EFI_EXCEPTION_TYPE         InterruptType,\r
+  IN EFI_CPU_INTERRUPT_HANDLER  InterruptHandler,\r
+  IN EXCEPTION_HANDLER_DATA     *ExceptionHandlerData\r
   )\r
 {\r
-  UINTN                          EnabledInterruptNum;\r
-  RESERVED_VECTORS_DATA          *ReservedVectors;\r
-  EFI_CPU_INTERRUPT_HANDLER      *ExternalInterruptHandler;\r
+  UINTN                      EnabledInterruptNum;\r
+  RESERVED_VECTORS_DATA      *ReservedVectors;\r
+  EFI_CPU_INTERRUPT_HANDLER  *ExternalInterruptHandler;\r
 \r
   EnabledInterruptNum      = ExceptionHandlerData->IdtEntryCount;\r
   ReservedVectors          = ExceptionHandlerData->ReservedVectors;\r
   ExternalInterruptHandler = ExceptionHandlerData->ExternalInterruptHandler;\r
 \r
-  if (InterruptType < 0 || InterruptType >= (EFI_EXCEPTION_TYPE)EnabledInterruptNum ||\r
-      ReservedVectors[InterruptType].Attribute == EFI_VECTOR_HANDOFF_DO_NOT_HOOK) {\r
+  if ((InterruptType < 0) || (InterruptType >= (EFI_EXCEPTION_TYPE)EnabledInterruptNum) ||\r
+      (ReservedVectors[InterruptType].Attribute == EFI_VECTOR_HANDOFF_DO_NOT_HOOK))\r
+  {\r
     return EFI_UNSUPPORTED;\r
   }\r
 \r
-  if (InterruptHandler == NULL && ExternalInterruptHandler[InterruptType] == NULL) {\r
+  if ((InterruptHandler == NULL) && (ExternalInterruptHandler[InterruptType] == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  if (InterruptHandler != NULL && ExternalInterruptHandler[InterruptType] != NULL) {\r
+  if ((InterruptHandler != NULL) && (ExternalInterruptHandler[InterruptType] != NULL)) {\r
     return EFI_ALREADY_STARTED;\r
   }\r
 \r
   ExternalInterruptHandler[InterruptType] = InterruptHandler;\r
   return EFI_SUCCESS;\r
 }\r
-\r