| /** @file | |
| Common header file for CPU Exception Handler Library. | |
| Copyright (c) 2012 - 2022, Intel Corporation. All rights reserved.<BR> | |
| SPDX-License-Identifier: BSD-2-Clause-Patent | |
| **/ | |
| #ifndef _CPU_EXCEPTION_COMMON_H_ | |
| #define _CPU_EXCEPTION_COMMON_H_ | |
| #include <Ppi/VectorHandoffInfo.h> | |
| #include <Protocol/Cpu.h> | |
| #include <Library/BaseLib.h> | |
| #include <Library/SerialPortLib.h> | |
| #include <Library/PrintLib.h> | |
| #include <Library/LocalApicLib.h> | |
| #include <Library/PeCoffGetEntryPointLib.h> | |
| #include <Library/BaseMemoryLib.h> | |
| #include <Library/SynchronizationLib.h> | |
| #include <Library/CpuExceptionHandlerLib.h> | |
| #define CPU_EXCEPTION_NUM 32 | |
| #define CPU_INTERRUPT_NUM 256 | |
| #define HOOKAFTER_STUB_SIZE 18 | |
| // | |
| // Exception Error Code of Page-Fault Exception | |
| // | |
| #define IA32_PF_EC_P BIT0 | |
| #define IA32_PF_EC_WR BIT1 | |
| #define IA32_PF_EC_US BIT2 | |
| #define IA32_PF_EC_RSVD BIT3 | |
| #define IA32_PF_EC_ID BIT4 | |
| #define IA32_PF_EC_PK BIT5 | |
| #define IA32_PF_EC_SS BIT6 | |
| #define IA32_PF_EC_SGX BIT15 | |
| #include "ArchInterruptDefs.h" | |
| #define CPU_STACK_SWITCH_EXCEPTION_NUMBER \ | |
| FixedPcdGetSize (PcdCpuStackSwitchExceptionList) | |
| #define CPU_STACK_SWITCH_EXCEPTION_LIST \ | |
| FixedPcdGetPtr (PcdCpuStackSwitchExceptionList) | |
| #define CPU_KNOWN_GOOD_STACK_SIZE \ | |
| FixedPcdGet32 (PcdCpuKnownGoodStackSize) | |
| #define CPU_TSS_GDT_SIZE (SIZE_2KB + CPU_TSS_DESC_SIZE + CPU_TSS_SIZE) | |
| // | |
| // Record exception handler information | |
| // | |
| typedef struct { | |
| UINTN ExceptionStart; | |
| UINTN ExceptionStubHeaderSize; | |
| UINTN HookAfterStubHeaderStart; | |
| } EXCEPTION_HANDLER_TEMPLATE_MAP; | |
| typedef struct { | |
| UINTN IdtEntryCount; | |
| SPIN_LOCK DisplayMessageSpinLock; | |
| RESERVED_VECTORS_DATA *ReservedVectors; | |
| EFI_CPU_INTERRUPT_HANDLER *ExternalInterruptHandler; | |
| } EXCEPTION_HANDLER_DATA; | |
| extern CONST UINT32 mErrorCodeFlag; | |
| extern CONST UINTN mDoFarReturnFlag; | |
| /** | |
| Return address map of exception handler template so that C code can generate | |
| exception tables. | |
| @param AddressMap Pointer to a buffer where the address map is returned. | |
| **/ | |
| VOID | |
| EFIAPI | |
| AsmGetTemplateAddressMap ( | |
| OUT EXCEPTION_HANDLER_TEMPLATE_MAP *AddressMap | |
| ); | |
| /** | |
| Return address map of exception handler template so that C code can generate | |
| exception tables. | |
| @param IdtEntry Pointer to IDT entry to be updated. | |
| @param InterruptHandler IDT handler value. | |
| **/ | |
| VOID | |
| ArchUpdateIdtEntry ( | |
| OUT IA32_IDT_GATE_DESCRIPTOR *IdtEntry, | |
| IN UINTN InterruptHandler | |
| ); | |
| /** | |
| Read IDT handler value from IDT entry. | |
| @param IdtEntry Pointer to IDT entry to be read. | |
| **/ | |
| UINTN | |
| ArchGetIdtHandler ( | |
| IN IA32_IDT_GATE_DESCRIPTOR *IdtEntry | |
| ); | |
| /** | |
| Prints a message to the serial port. | |
| @param Format Format string for the message to print. | |
| @param ... Variable argument list whose contents are accessed | |
| based on the format string specified by Format. | |
| **/ | |
| VOID | |
| EFIAPI | |
| InternalPrintMessage ( | |
| IN CONST CHAR8 *Format, | |
| ... | |
| ); | |
| /** | |
| Find and display image base address and return image base and its entry point. | |
| @param CurrentEip Current instruction pointer. | |
| **/ | |
| VOID | |
| DumpModuleImageInfo ( | |
| IN UINTN CurrentEip | |
| ); | |
| /** | |
| Display CPU information. | |
| @param ExceptionType Exception type. | |
| @param SystemContext Pointer to EFI_SYSTEM_CONTEXT. | |
| **/ | |
| VOID | |
| DumpImageAndCpuContent ( | |
| IN EFI_EXCEPTION_TYPE ExceptionType, | |
| IN EFI_SYSTEM_CONTEXT SystemContext | |
| ); | |
| /** | |
| Internal worker function to initialize exception handler. | |
| @param[in] VectorInfo Pointer to reserved vector list. | |
| @param[in, out] ExceptionHandlerData Pointer to exception handler data. | |
| @retval EFI_SUCCESS CPU Exception Entries have been successfully initialized | |
| with default exception handlers. | |
| @retval EFI_INVALID_PARAMETER VectorInfo includes the invalid content if VectorInfo is not NULL. | |
| @retval EFI_UNSUPPORTED This function is not supported. | |
| **/ | |
| EFI_STATUS | |
| InitializeCpuExceptionHandlersWorker ( | |
| IN EFI_VECTOR_HANDOFF_INFO *VectorInfo OPTIONAL, | |
| IN OUT EXCEPTION_HANDLER_DATA *ExceptionHandlerData | |
| ); | |
| /** | |
| Registers a function to be called from the processor interrupt handler. | |
| @param[in] InterruptType Defines which interrupt or exception to hook. | |
| @param[in] InterruptHandler A pointer to a function of type EFI_CPU_INTERRUPT_HANDLER that is called | |
| when a processor interrupt occurs. If this parameter is NULL, then the handler | |
| will be uninstalled | |
| @param[in] ExceptionHandlerData Pointer to exception handler data. | |
| @retval EFI_SUCCESS The handler for the processor interrupt was successfully installed or uninstalled. | |
| @retval EFI_ALREADY_STARTED InterruptHandler is not NULL, and a handler for InterruptType was | |
| previously installed. | |
| @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler for InterruptType was not | |
| previously installed. | |
| @retval EFI_UNSUPPORTED The interrupt specified by InterruptType is not supported, | |
| or this function is not supported. | |
| **/ | |
| EFI_STATUS | |
| RegisterCpuInterruptHandlerWorker ( | |
| IN EFI_EXCEPTION_TYPE InterruptType, | |
| IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler, | |
| IN EXCEPTION_HANDLER_DATA *ExceptionHandlerData | |
| ); | |
| /** | |
| Internal worker function to update IDT entries accordling to vector attributes. | |
| @param[in] IdtTable Pointer to IDT table. | |
| @param[in] TemplateMap Pointer to a buffer where the address map is | |
| returned. | |
| @param[in] ExceptionHandlerData Pointer to exception handler data. | |
| **/ | |
| VOID | |
| UpdateIdtTable ( | |
| IN IA32_IDT_GATE_DESCRIPTOR *IdtTable, | |
| IN EXCEPTION_HANDLER_TEMPLATE_MAP *TemplateMap, | |
| IN EXCEPTION_HANDLER_DATA *ExceptionHandlerData | |
| ); | |
| /** | |
| Save CPU exception context when handling EFI_VECTOR_HANDOFF_HOOK_AFTER case. | |
| @param[in] ExceptionType Exception type. | |
| @param[in] SystemContext Pointer to EFI_SYSTEM_CONTEXT. | |
| @param[in] ExceptionHandlerData Pointer to exception handler data. | |
| **/ | |
| VOID | |
| ArchSaveExceptionContext ( | |
| IN UINTN ExceptionType, | |
| IN EFI_SYSTEM_CONTEXT SystemContext, | |
| IN EXCEPTION_HANDLER_DATA *ExceptionHandlerData | |
| ); | |
| /** | |
| Restore CPU exception context when handling EFI_VECTOR_HANDOFF_HOOK_AFTER case. | |
| @param[in] ExceptionType Exception type. | |
| @param[in] SystemContext Pointer to EFI_SYSTEM_CONTEXT. | |
| @param[in] ExceptionHandlerData Pointer to exception handler data. | |
| **/ | |
| VOID | |
| ArchRestoreExceptionContext ( | |
| IN UINTN ExceptionType, | |
| IN EFI_SYSTEM_CONTEXT SystemContext, | |
| IN EXCEPTION_HANDLER_DATA *ExceptionHandlerData | |
| ); | |
| /** | |
| Fix up the vector number and function address in the vector code. | |
| @param[in] NewVectorAddr New vector handler address. | |
| @param[in] VectorNum Index of vector. | |
| @param[in] OldVectorAddr Old vector handler address. | |
| **/ | |
| VOID | |
| EFIAPI | |
| AsmVectorNumFixup ( | |
| IN VOID *NewVectorAddr, | |
| IN UINT8 VectorNum, | |
| IN VOID *OldVectorAddr | |
| ); | |
| /** | |
| Read and save reserved vector information | |
| @param[in] VectorInfo Pointer to reserved vector list. | |
| @param[out] ReservedVector Pointer to reserved vector data buffer. | |
| @param[in] VectorCount Vector number to be updated. | |
| @return EFI_SUCCESS Read and save vector info successfully. | |
| @retval EFI_INVALID_PARAMETER VectorInfo includes the invalid content if VectorInfo is not NULL. | |
| **/ | |
| EFI_STATUS | |
| ReadAndVerifyVectorInfo ( | |
| IN EFI_VECTOR_HANDOFF_INFO *VectorInfo, | |
| OUT RESERVED_VECTORS_DATA *ReservedVector, | |
| IN UINTN VectorCount | |
| ); | |
| /** | |
| Get ASCII format string exception name by exception type. | |
| @param ExceptionType Exception type. | |
| @return ASCII format string exception name. | |
| **/ | |
| CONST CHAR8 * | |
| GetExceptionNameStr ( | |
| IN EFI_EXCEPTION_TYPE ExceptionType | |
| ); | |
| /** | |
| Internal worker function for common exception handler. | |
| @param ExceptionType Exception type. | |
| @param SystemContext Pointer to EFI_SYSTEM_CONTEXT. | |
| @param ExceptionHandlerData Pointer to exception handler data. | |
| **/ | |
| VOID | |
| CommonExceptionHandlerWorker ( | |
| IN EFI_EXCEPTION_TYPE ExceptionType, | |
| IN EFI_SYSTEM_CONTEXT SystemContext, | |
| IN EXCEPTION_HANDLER_DATA *ExceptionHandlerData | |
| ); | |
| /** | |
| Setup separate stacks for certain exception handlers. | |
| @param[in] Buffer Point to buffer used to separate exception stack. | |
| @param[in, out] BufferSize On input, it indicates the byte size of Buffer. | |
| If the size is not enough, the return status will | |
| be EFI_BUFFER_TOO_SMALL, and output BufferSize | |
| will be the size it needs. | |
| @retval EFI_SUCCESS The stacks are assigned successfully. | |
| @retval EFI_BUFFER_TOO_SMALL This BufferSize is too small. | |
| @retval EFI_UNSUPPORTED This function is not supported. | |
| **/ | |
| EFI_STATUS | |
| ArchSetupExceptionStack ( | |
| IN VOID *Buffer, | |
| IN OUT UINTN *BufferSize | |
| ); | |
| /** | |
| Return address map of exception handler template so that C code can generate | |
| exception tables. The template is only for exceptions using task gate instead | |
| of interrupt gate. | |
| @param AddressMap Pointer to a buffer where the address map is returned. | |
| **/ | |
| VOID | |
| EFIAPI | |
| AsmGetTssTemplateMap ( | |
| OUT EXCEPTION_HANDLER_TEMPLATE_MAP *AddressMap | |
| ); | |
| #endif |