/** @file\r
CPU Exception Library provides PEI/DXE/SMM CPU common exception handler.\r
\r
-Copyright (c) 2012 - 2017, 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
switch (ReservedVectors[ExceptionType].Attribute) {\r
case EFI_VECTOR_HANDOFF_HOOK_BEFORE:\r
//\r
- // Need to jmp to old IDT handler after this exception handler\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
ExceptionHandlerContext->ExceptionDataFlag = (mErrorCodeFlag & (1 << ExceptionType)) ? TRUE : FALSE;\r
ExceptionHandlerContext->OldIdtHandler = ReservedVectors[ExceptionType].ExceptonHandler;\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
+ // If spin-lock can be acquired, it's the first time entering here.\r
//\r
if (AcquireSpinLockOrFail (&ReservedVectors[ExceptionType].SpinLock)) {\r
//\r
- // Need to execute old IDT handler before running this exception handler\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
return;\r
}\r
//\r
- // If failed to acquire SPIN_LOCK, check if it was locked by processor itself\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
if (ReservedVectors[ExceptionType].ApicId == GetApicId ()) {\r
//\r
CpuPause ();\r
}\r
//\r
+ // Initialize the serial port before dumping.\r
+ //\r
+ SerialPortInitialize ();\r
+ //\r
// Display ExceptionType, CPU information and Image information\r
//\r
DumpImageAndCpuContent (ExceptionType, SystemContext);\r