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