/** @file\r
Common header file for CPU Exception Handler Library.\r
\r
- Copyright (c) 2012 - 2016, Intel Corporation. All rights reserved.<BR>\r
- This program and the accompanying materials\r
- are licensed and made available under the terms and conditions of the BSD License\r
- which accompanies this distribution. 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 <Library/PeCoffGetEntryPointLib.h>\r
#include <Library/BaseMemoryLib.h>\r
#include <Library/SynchronizationLib.h>\r
+#include <Library/CpuExceptionHandlerLib.h>\r
\r
-#define CPU_EXCEPTION_NUM 32\r
-#define CPU_INTERRUPT_NUM 256\r
-#define HOOKAFTER_STUB_SIZE 16\r
+#define CPU_EXCEPTION_NUM 32\r
+#define CPU_INTERRUPT_NUM 256\r
+#define HOOKAFTER_STUB_SIZE 18\r
+\r
+//\r
+// Exception Error Code of Page-Fault Exception\r
+//\r
+#define IA32_PF_EC_P BIT0\r
+#define IA32_PF_EC_WR BIT1\r
+#define IA32_PF_EC_US BIT2\r
+#define IA32_PF_EC_RSVD BIT3\r
+#define IA32_PF_EC_ID BIT4\r
+#define IA32_PF_EC_PK BIT5\r
+#define IA32_PF_EC_SS BIT6\r
+#define IA32_PF_EC_SGX BIT15\r
\r
#include "ArchInterruptDefs.h"\r
\r
+#define CPU_STACK_SWITCH_EXCEPTION_NUMBER \\r
+ FixedPcdGetSize (PcdCpuStackSwitchExceptionList)\r
+\r
+#define CPU_STACK_SWITCH_EXCEPTION_LIST \\r
+ FixedPcdGetPtr (PcdCpuStackSwitchExceptionList)\r
+\r
+#define CPU_KNOWN_GOOD_STACK_SIZE \\r
+ FixedPcdGet32 (PcdCpuKnownGoodStackSize)\r
+\r
+#define CPU_TSS_GDT_SIZE (SIZE_2KB + CPU_TSS_DESC_SIZE + CPU_TSS_SIZE)\r
+\r
//\r
// Record exception handler information\r
//\r
typedef struct {\r
- UINTN ExceptionStart;\r
- UINTN ExceptionStubHeaderSize;\r
- UINTN HookAfterStubHeaderStart;\r
+ UINTN ExceptionStart;\r
+ UINTN ExceptionStubHeaderSize;\r
+ UINTN HookAfterStubHeaderStart;\r
} EXCEPTION_HANDLER_TEMPLATE_MAP;\r
\r
typedef struct {\r
- UINTN IdtEntryCount;\r
- SPIN_LOCK DisplayMessageSpinLock;\r
- RESERVED_VECTORS_DATA *ReservedVectors;\r
- EFI_CPU_INTERRUPT_HANDLER *ExternalInterruptHandler;\r
+ UINTN IdtEntryCount;\r
+ SPIN_LOCK DisplayMessageSpinLock;\r
+ RESERVED_VECTORS_DATA *ReservedVectors;\r
+ EFI_CPU_INTERRUPT_HANDLER *ExternalInterruptHandler;\r
} EXCEPTION_HANDLER_DATA;\r
\r
-extern CONST UINT32 mErrorCodeFlag;\r
-extern CONST UINTN mImageAlignSize;\r
-extern CONST UINTN mDoFarReturnFlag;\r
-extern RESERVED_VECTORS_DATA *mReservedVectors;\r
+extern CONST UINT32 mErrorCodeFlag;\r
+extern CONST UINTN mDoFarReturnFlag;\r
\r
/**\r
Return address map of exception handler template so that C code can generate\r
VOID\r
EFIAPI\r
AsmGetTemplateAddressMap (\r
- OUT EXCEPTION_HANDLER_TEMPLATE_MAP *AddressMap\r
+ OUT EXCEPTION_HANDLER_TEMPLATE_MAP *AddressMap\r
);\r
\r
/**\r
**/\r
VOID\r
ArchUpdateIdtEntry (\r
- IN IA32_IDT_GATE_DESCRIPTOR *IdtEntry,\r
- IN UINTN InterruptHandler\r
+ OUT IA32_IDT_GATE_DESCRIPTOR *IdtEntry,\r
+ IN UINTN InterruptHandler\r
);\r
\r
/**\r
**/\r
UINTN\r
ArchGetIdtHandler (\r
- IN IA32_IDT_GATE_DESCRIPTOR *IdtEntry\r
+ IN IA32_IDT_GATE_DESCRIPTOR *IdtEntry\r
);\r
\r
/**\r
Prints a message to the serial port.\r
\r
@param Format Format string for the message to print.\r
- @param ... Variable argument list whose contents are accessed \r
+ @param ... Variable argument list whose contents are accessed\r
based on the format string specified by Format.\r
\r
**/\r
\r
/**\r
Find and display image base address and return image base and its entry point.\r
- \r
+\r
@param CurrentEip Current instruction pointer.\r
- @param EntryPoint Return module entry point if module header is found.\r
- \r
- @return !0 Image base address.\r
- @return 0 Image header cannot be found.\r
+\r
**/\r
-UINTN \r
-FindModuleImageBase (\r
- IN UINTN CurrentEip,\r
- OUT UINTN *EntryPoint\r
+VOID\r
+DumpModuleImageInfo (\r
+ IN UINTN CurrentEip\r
);\r
\r
/**\r
@param SystemContext Pointer to EFI_SYSTEM_CONTEXT.\r
**/\r
VOID\r
-DumpCpuContent (\r
- IN EFI_EXCEPTION_TYPE ExceptionType,\r
- IN EFI_SYSTEM_CONTEXT SystemContext\r
+DumpImageAndCpuContent (\r
+ IN EFI_EXCEPTION_TYPE ExceptionType,\r
+ IN EFI_SYSTEM_CONTEXT SystemContext\r
);\r
\r
/**\r
\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
**/\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
/**\r
Registers a function to be called from the processor interrupt handler.\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
- when a processor interrupt occurs. If this parameter is NULL, then the handler\r
- will be uninstalled.\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
+ when a processor interrupt occurs. If this parameter is NULL, then the handler\r
+ will be uninstalled\r
+ @param[in] ExceptionHandlerData Pointer to exception handler data.\r
\r
@retval EFI_SUCCESS The handler for the processor interrupt was successfully installed or uninstalled.\r
@retval EFI_ALREADY_STARTED InterruptHandler is not NULL, and a handler for InterruptType was\r
**/\r
EFI_STATUS\r
RegisterCpuInterruptHandlerWorker (\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
+ IN EXCEPTION_HANDLER_DATA *ExceptionHandlerData\r
);\r
\r
/**\r
Internal worker function to update IDT entries accordling to vector attributes.\r
\r
- @param[in] IdtTable Pointer to IDT table.\r
- @param[in] TemplateMap Pointer to a buffer where the address map is returned.\r
- @param[in] IdtEntryCount IDT entries number to be updated.\r
+ @param[in] IdtTable Pointer to IDT table.\r
+ @param[in] TemplateMap Pointer to a buffer where the address map is\r
+ returned.\r
+ @param[in] ExceptionHandlerData Pointer to exception handler data.\r
\r
**/\r
VOID\r
UpdateIdtTable (\r
IN IA32_IDT_GATE_DESCRIPTOR *IdtTable,\r
IN EXCEPTION_HANDLER_TEMPLATE_MAP *TemplateMap,\r
- IN UINTN IdtEntryCount\r
+ IN EXCEPTION_HANDLER_DATA *ExceptionHandlerData\r
);\r
\r
/**\r
Save CPU exception context when handling EFI_VECTOR_HANDOFF_HOOK_AFTER case.\r
\r
- @param[in] ExceptionType Exception type.\r
- @param[in] SystemContext Pointer to EFI_SYSTEM_CONTEXT.\r
-\r
+ @param[in] ExceptionType Exception type.\r
+ @param[in] SystemContext Pointer to EFI_SYSTEM_CONTEXT.\r
+ @param[in] ExceptionHandlerData Pointer to exception handler data.\r
**/\r
VOID\r
ArchSaveExceptionContext (\r
- IN UINTN ExceptionType,\r
- IN EFI_SYSTEM_CONTEXT SystemContext \r
+ IN UINTN ExceptionType,\r
+ IN EFI_SYSTEM_CONTEXT SystemContext,\r
+ IN EXCEPTION_HANDLER_DATA *ExceptionHandlerData\r
);\r
\r
/**\r
Restore CPU exception context when handling EFI_VECTOR_HANDOFF_HOOK_AFTER case.\r
\r
- @param[in] ExceptionType Exception type.\r
- @param[in] SystemContext Pointer to EFI_SYSTEM_CONTEXT.\r
-\r
+ @param[in] ExceptionType Exception type.\r
+ @param[in] SystemContext Pointer to EFI_SYSTEM_CONTEXT.\r
+ @param[in] ExceptionHandlerData Pointer to exception handler data.\r
**/\r
VOID\r
ArchRestoreExceptionContext (\r
- IN UINTN ExceptionType,\r
- IN EFI_SYSTEM_CONTEXT SystemContext \r
+ IN UINTN ExceptionType,\r
+ IN EFI_SYSTEM_CONTEXT SystemContext,\r
+ IN EXCEPTION_HANDLER_DATA *ExceptionHandlerData\r
);\r
\r
/**\r
Fix up the vector number and function address in the vector code.\r
- \r
+\r
@param[in] NewVectorAddr New vector handler address.\r
@param[in] VectorNum Index of vector.\r
@param[in] OldVectorAddr Old vector handler address.\r
VOID\r
EFIAPI\r
AsmVectorNumFixup (\r
- IN VOID *NewVectorAddr,\r
- IN UINT8 VectorNum,\r
- IN VOID *OldVectorAddr\r
+ IN VOID *NewVectorAddr,\r
+ IN UINT8 VectorNum,\r
+ IN VOID *OldVectorAddr\r
);\r
\r
/**\r
Read and save reserved vector information\r
- \r
+\r
@param[in] VectorInfo Pointer to reserved vector list.\r
@param[out] ReservedVector Pointer to reserved vector data buffer.\r
@param[in] VectorCount Vector number to be updated.\r
- \r
+\r
@return EFI_SUCCESS Read and save vector info successfully.\r
@retval EFI_INVALID_PARAMETER VectorInfo includes the invalid content if VectorInfo is not NULL.\r
\r
**/\r
EFI_STATUS\r
ReadAndVerifyVectorInfo (\r
- IN EFI_VECTOR_HANDOFF_INFO *VectorInfo,\r
- OUT RESERVED_VECTORS_DATA *ReservedVector,\r
- IN UINTN VectorCount\r
+ IN EFI_VECTOR_HANDOFF_INFO *VectorInfo,\r
+ OUT RESERVED_VECTORS_DATA *ReservedVector,\r
+ IN UINTN VectorCount\r
);\r
\r
/**\r
**/\r
CONST CHAR8 *\r
GetExceptionNameStr (\r
- IN EFI_EXCEPTION_TYPE ExceptionType\r
+ IN EFI_EXCEPTION_TYPE ExceptionType\r
);\r
\r
-#endif\r
+/**\r
+ Internal worker function for common exception handler.\r
+\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
+CommonExceptionHandlerWorker (\r
+ IN EFI_EXCEPTION_TYPE ExceptionType,\r
+ IN EFI_SYSTEM_CONTEXT SystemContext,\r
+ IN EXCEPTION_HANDLER_DATA *ExceptionHandlerData\r
+ );\r
+\r
+/**\r
+ Setup separate stacks for certain exception handlers.\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_BUFFER_TOO_SMALL This BufferSize is too small.\r
+ @retval EFI_UNSUPPORTED This function is not supported.\r
+**/\r
+EFI_STATUS\r
+ArchSetupExceptionStack (\r
+ IN VOID *Buffer,\r
+ IN OUT UINTN *BufferSize\r
+ );\r
\r
+/**\r
+ Return address map of exception handler template so that C code can generate\r
+ exception tables. The template is only for exceptions using task gate instead\r
+ of interrupt gate.\r
+\r
+ @param AddressMap Pointer to a buffer where the address map is returned.\r
+**/\r
+VOID\r
+EFIAPI\r
+AsmGetTssTemplateMap (\r
+ OUT EXCEPTION_HANDLER_TEMPLATE_MAP *AddressMap\r
+ );\r
+\r
+#endif\r