diff options
Diffstat (limited to 'src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c')
-rw-r--r-- | src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c | 183 |
1 files changed, 183 insertions, 0 deletions
diff --git a/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c b/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c new file mode 100644 index 00000000..82823bb6 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c @@ -0,0 +1,183 @@ +/** @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; +} |