/** @file CPU Exception Handler Library common functions. Copyright (c) 2012 - 2019, Intel Corporation. All rights reserved.
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; }