/** @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
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
\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
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
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
\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
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
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