1 /** @file
2   CPU Exception Handler Library common functions.
3 
4   Copyright (c) 2012 - 2019, Intel Corporation. All rights reserved.<BR>
5   SPDX-License-Identifier: BSD-2-Clause-Patent
6 
7 **/
8 
9 #include "CpuExceptionCommon.h"
10 
11 //
12 // Error code flag indicating whether or not an error code will be
13 // pushed on the stack if an exception occurs.
14 //
15 // 1 means an error code will be pushed, otherwise 0
16 //
17 CONST UINT32 mErrorCodeFlag = 0x00227d00;
18 
19 //
20 // Define the maximum message length
21 //
22 #define MAX_DEBUG_MESSAGE_LENGTH  0x100
23 
24 CONST CHAR8 mExceptionReservedStr[] = "Reserved";
25 CONST CHAR8 *mExceptionNameStr[] = {
26   "#DE - Divide Error",
27   "#DB - Debug",
28   "NMI Interrupt",
29   "#BP - Breakpoint",
30   "#OF - Overflow",
31   "#BR - BOUND Range Exceeded",
32   "#UD - Invalid Opcode",
33   "#NM - Device Not Available",
34   "#DF - Double Fault",
35   "Coprocessor Segment Overrun",
36   "#TS - Invalid TSS",
37   "#NP - Segment Not Present",
38   "#SS - Stack Fault Fault",
39   "#GP - General Protection",
40   "#PF - Page-Fault",
41   "Reserved",
42   "#MF - x87 FPU Floating-Point Error",
43   "#AC - Alignment Check",
44   "#MC - Machine-Check",
45   "#XM - SIMD floating-point",
46   "#VE - Virtualization",
47   "#CP - Control Protection"
48 };
49 
50 #define EXCEPTION_KNOWN_NAME_NUM  (sizeof (mExceptionNameStr) / sizeof (CHAR8 *))
51 
52 /**
53   Get ASCII format string exception name by exception type.
54 
55   @param ExceptionType  Exception type.
56 
57   @return  ASCII format string exception name.
58 **/
59 CONST CHAR8 *
GetExceptionNameStr(IN EFI_EXCEPTION_TYPE ExceptionType)60 GetExceptionNameStr (
61   IN EFI_EXCEPTION_TYPE          ExceptionType
62   )
63 {
64   if ((UINTN) ExceptionType < EXCEPTION_KNOWN_NAME_NUM) {
65     return mExceptionNameStr[ExceptionType];
66   } else {
67     return mExceptionReservedStr;
68   }
69 }
70 
71 /**
72   Prints a message to the serial port.
73 
74   @param  Format      Format string for the message to print.
75   @param  ...         Variable argument list whose contents are accessed
76                       based on the format string specified by Format.
77 
78 **/
79 VOID
80 EFIAPI
InternalPrintMessage(IN CONST CHAR8 * Format,...)81 InternalPrintMessage (
82   IN  CONST CHAR8  *Format,
83   ...
84   )
85 {
86   CHAR8    Buffer[MAX_DEBUG_MESSAGE_LENGTH];
87   VA_LIST  Marker;
88 
89   //
90   // Convert the message to an ASCII String
91   //
92   VA_START (Marker, Format);
93   AsciiVSPrint (Buffer, sizeof (Buffer), Format, Marker);
94   VA_END (Marker);
95 
96   //
97   // Send the print string to a Serial Port
98   //
99   SerialPortWrite ((UINT8 *)Buffer, AsciiStrLen (Buffer));
100 }
101 
102 /**
103   Find and display image base address and return image base and its entry point.
104 
105   @param CurrentEip      Current instruction pointer.
106 
107 **/
108 VOID
DumpModuleImageInfo(IN UINTN CurrentEip)109 DumpModuleImageInfo (
110   IN  UINTN              CurrentEip
111   )
112 {
113   EFI_STATUS                           Status;
114   UINTN                                Pe32Data;
115   VOID                                 *PdbPointer;
116   VOID                                 *EntryPoint;
117 
118   Pe32Data = PeCoffSearchImageBase (CurrentEip);
119   if (Pe32Data == 0) {
120     InternalPrintMessage ("!!!! Can't find image information. !!!!\n");
121   } else {
122     //
123     // Find Image Base entry point
124     //
125     Status = PeCoffLoaderGetEntryPoint ((VOID *) Pe32Data, &EntryPoint);
126     if (EFI_ERROR (Status)) {
127       EntryPoint = NULL;
128     }
129     InternalPrintMessage ("!!!! Find image based on IP(0x%x) ", CurrentEip);
130     PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *) Pe32Data);
131     if (PdbPointer != NULL) {
132       InternalPrintMessage ("%a", PdbPointer);
133     } else {
134       InternalPrintMessage ("(No PDB) " );
135     }
136     InternalPrintMessage (
137       " (ImageBase=%016lp, EntryPoint=%016p) !!!!\n",
138       (VOID *) Pe32Data,
139       EntryPoint
140       );
141   }
142 }
143 
144 /**
145   Read and save reserved vector information
146 
147   @param[in]  VectorInfo        Pointer to reserved vector list.
148   @param[out] ReservedVector    Pointer to reserved vector data buffer.
149   @param[in]  VectorCount       Vector number to be updated.
150 
151   @return EFI_SUCCESS           Read and save vector info successfully.
152   @retval EFI_INVALID_PARAMETER VectorInfo includes the invalid content if VectorInfo is not NULL.
153 
154 **/
155 EFI_STATUS
ReadAndVerifyVectorInfo(IN EFI_VECTOR_HANDOFF_INFO * VectorInfo,OUT RESERVED_VECTORS_DATA * ReservedVector,IN UINTN VectorCount)156 ReadAndVerifyVectorInfo (
157   IN  EFI_VECTOR_HANDOFF_INFO       *VectorInfo,
158   OUT RESERVED_VECTORS_DATA         *ReservedVector,
159   IN  UINTN                         VectorCount
160   )
161 {
162   while (VectorInfo->Attribute != EFI_VECTOR_HANDOFF_LAST_ENTRY) {
163     if (VectorInfo->Attribute > EFI_VECTOR_HANDOFF_HOOK_AFTER) {
164       //
165       // If vector attrubute is invalid
166       //
167       return EFI_INVALID_PARAMETER;
168     }
169     if (VectorInfo->VectorNumber < VectorCount) {
170       ReservedVector[VectorInfo->VectorNumber].Attribute = VectorInfo->Attribute;
171     }
172     VectorInfo ++;
173   }
174   return EFI_SUCCESS;
175 }
176