/** @file | |
CPU Exception Handler Library common functions. | |
Copyright (c) 2012 - 2019, Intel Corporation. All rights reserved.<BR> | |
SPDX-License-Identifier: BSD-2-Clause-Patent | |
**/ | |
#include "CpuExceptionCommon.h" | |
// | |
// Error code flag indicating whether or not an error code will be | |
// pushed on the stack if an exception occurs. | |
// | |
// 1 means an error code will be pushed, otherwise 0 | |
// | |
CONST UINT32 mErrorCodeFlag = 0x20227d00; | |
// | |
// Define the maximum message length | |
// | |
#define MAX_DEBUG_MESSAGE_LENGTH 0x100 | |
CONST CHAR8 mExceptionReservedStr[] = "Reserved"; | |
CONST CHAR8 *mExceptionNameStr[] = { | |
"#DE - Divide Error", | |
"#DB - Debug", | |
"NMI Interrupt", | |
"#BP - Breakpoint", | |
"#OF - Overflow", | |
"#BR - BOUND Range Exceeded", | |
"#UD - Invalid Opcode", | |
"#NM - Device Not Available", | |
"#DF - Double Fault", | |
"Coprocessor Segment Overrun", | |
"#TS - Invalid TSS", | |
"#NP - Segment Not Present", | |
"#SS - Stack Fault Fault", | |
"#GP - General Protection", | |
"#PF - Page-Fault", | |
"Reserved", | |
"#MF - x87 FPU Floating-Point Error", | |
"#AC - Alignment Check", | |
"#MC - Machine-Check", | |
"#XM - SIMD floating-point", | |
"#VE - Virtualization", | |
"#CP - Control Protection", | |
"Reserved", | |
"Reserved", | |
"Reserved", | |
"Reserved", | |
"Reserved", | |
"Reserved", | |
"Reserved", | |
"#VC - VMM Communication", | |
}; | |
#define EXCEPTION_KNOWN_NAME_NUM (sizeof (mExceptionNameStr) / sizeof (CHAR8 *)) | |
/** | |
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 | |
) | |
{ | |
if ((UINTN)ExceptionType < EXCEPTION_KNOWN_NAME_NUM) { | |
return mExceptionNameStr[ExceptionType]; | |
} else { | |
return mExceptionReservedStr; | |
} | |
} | |
/** | |
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, | |
... | |
) | |
{ | |
CHAR8 Buffer[MAX_DEBUG_MESSAGE_LENGTH]; | |
VA_LIST Marker; | |
// | |
// Convert the message to an ASCII String | |
// | |
VA_START (Marker, Format); | |
AsciiVSPrint (Buffer, sizeof (Buffer), Format, Marker); | |
VA_END (Marker); | |
// | |
// Send the print string to a Serial Port | |
// | |
SerialPortWrite ((UINT8 *)Buffer, AsciiStrLen (Buffer)); | |
} | |
/** | |
Find and display image base address and return image base and its entry point. | |
@param CurrentEip Current instruction pointer. | |
**/ | |
VOID | |
DumpModuleImageInfo ( | |
IN UINTN CurrentEip | |
) | |
{ | |
EFI_STATUS Status; | |
UINTN Pe32Data; | |
VOID *PdbPointer; | |
VOID *EntryPoint; | |
Pe32Data = PeCoffSearchImageBase (CurrentEip); | |
if (Pe32Data == 0) { | |
InternalPrintMessage ("!!!! Can't find image information. !!!!\n"); | |
} else { | |
// | |
// Find Image Base entry point | |
// | |
Status = PeCoffLoaderGetEntryPoint ((VOID *)Pe32Data, &EntryPoint); | |
if (EFI_ERROR (Status)) { | |
EntryPoint = NULL; | |
} | |
InternalPrintMessage ("!!!! Find image based on IP(0x%x) ", CurrentEip); | |
PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *)Pe32Data); | |
if (PdbPointer != NULL) { | |
InternalPrintMessage ("%a", PdbPointer); | |
} else { | |
InternalPrintMessage ("(No PDB) "); | |
} | |
InternalPrintMessage ( | |
" (ImageBase=%016lp, EntryPoint=%016p) !!!!\n", | |
(VOID *)Pe32Data, | |
EntryPoint | |
); | |
} | |
} | |
/** | |
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 | |
) | |
{ | |
while (VectorInfo->Attribute != EFI_VECTOR_HANDOFF_LAST_ENTRY) { | |
if (VectorInfo->Attribute > EFI_VECTOR_HANDOFF_HOOK_AFTER) { | |
// | |
// If vector attrubute is invalid | |
// | |
return EFI_INVALID_PARAMETER; | |
} | |
if (VectorInfo->VectorNumber < VectorCount) { | |
ReservedVector[VectorInfo->VectorNumber].Attribute = VectorInfo->Attribute; | |
} | |
VectorInfo++; | |
} | |
return EFI_SUCCESS; | |
} |