]> git.proxmox.com Git - mirror_edk2.git/blame - UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c
UefiCpuPkg: LocalApicLib: Add API to set SoftwareEnable bit
[mirror_edk2.git] / UefiCpuPkg / Library / CpuExceptionHandlerLib / CpuExceptionCommon.c
CommitLineData
8f07f895 1/** @file\r
e3644786 2 CPU Exception Handler Library common functions.\r
8f07f895 3\r
a51ee144 4 Copyright (c) 2012 - 2015, Intel Corporation. All rights reserved.<BR>\r
8f07f895 5 This program and the accompanying materials\r
6 are licensed and made available under the terms and conditions of the BSD License\r
7 which accompanies this distribution. The full text of the license may be found at\r
8 http://opensource.org/licenses/bsd-license.php\r
9\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include "CpuExceptionCommon.h"\r
16\r
17//\r
e41aad15 18// Error code flag indicating whether or not an error code will be\r
8f07f895 19// pushed on the stack if an exception occurs.\r
20//\r
21// 1 means an error code will be pushed, otherwise 0\r
22//\r
e41aad15
JF
23CONST UINT32 mErrorCodeFlag = 0x00027d00;\r
24RESERVED_VECTORS_DATA *mReservedVectors = NULL;\r
8f07f895 25\r
26//\r
a51ee144 27// Define the maximum message length\r
8f07f895 28//\r
29#define MAX_DEBUG_MESSAGE_LENGTH 0x100\r
30\r
a51ee144
JF
31CONST CHAR8 mExceptionReservedStr[] = "Reserved";\r
32CONST CHAR8 *mExceptionNameStr[] = {\r
33 "#DE - Divide Error",\r
34 "#DB - Debug",\r
35 "NMI Interrupt",\r
36 "#BP - Breakpoint",\r
37 "#OF - Overflow",\r
38 "#BR - BOUND Range Exceeded",\r
39 "#UD - Invalid Opcode",\r
40 "#NM - Device Not Available",\r
41 "#DF - Double Fault",\r
42 "Coprocessor Segment Overrun",\r
43 "#TS - Invalid TSS",\r
44 "#NP - Segment Not Present",\r
45 "#SS - Stack Fault Fault",\r
46 "#GP - General Protection",\r
47 "#PF - Page-Fault",\r
48 "Reserved",\r
49 "#MF - x87 FPU Floating-Point Error",\r
50 "#AC - Alignment Check",\r
51 "#MC - Machine-Check",\r
52 "#XM - SIMD floating-point",\r
53 "#VE - Virtualization"\r
54};\r
55\r
56#define EXCEPTION_KNOWN_NAME_NUM (sizeof (mExceptionNameStr) / sizeof (CHAR8 *))\r
57\r
58/**\r
59 Get ASCII format string exception name by exception type.\r
60\r
61 @param ExceptionType Exception type.\r
62\r
63 @return ASCII format string exception name.\r
64**/\r
65CONST CHAR8 *\r
66GetExceptionNameStr (\r
67 IN EFI_EXCEPTION_TYPE ExceptionType\r
68 )\r
69{\r
70 if ((UINTN) ExceptionType < EXCEPTION_KNOWN_NAME_NUM) {\r
71 return mExceptionNameStr[ExceptionType];\r
72 } else {\r
73 return mExceptionReservedStr;\r
74 }\r
75}\r
76\r
8f07f895 77/**\r
78 Prints a message to the serial port.\r
79\r
80 @param Format Format string for the message to print.\r
a51ee144 81 @param ... Variable argument list whose contents are accessed\r
8f07f895 82 based on the format string specified by Format.\r
83\r
84**/\r
85VOID\r
86EFIAPI\r
87InternalPrintMessage (\r
88 IN CONST CHAR8 *Format,\r
89 ...\r
90 )\r
91{\r
92 CHAR8 Buffer[MAX_DEBUG_MESSAGE_LENGTH];\r
93 VA_LIST Marker;\r
94\r
95 //\r
96 // Convert the message to an ASCII String\r
97 //\r
98 VA_START (Marker, Format);\r
99 AsciiVSPrint (Buffer, sizeof (Buffer), Format, Marker);\r
100 VA_END (Marker);\r
101\r
102 //\r
a51ee144 103 // Send the print string to a Serial Port\r
8f07f895 104 //\r
105 SerialPortWrite ((UINT8 *)Buffer, AsciiStrLen (Buffer));\r
106}\r
107\r
108/**\r
109 Find and display image base address and return image base and its entry point.\r
a51ee144 110\r
a9c7ab95 111 @param CurrentEip Current instruction pointer.\r
112 @param EntryPoint Return module entry point if module header is found.\r
a51ee144 113\r
a9c7ab95 114 @return !0 Image base address.\r
115 @return 0 Image header cannot be found.\r
8f07f895 116**/\r
a51ee144 117UINTN\r
8f07f895 118FindModuleImageBase (\r
119 IN UINTN CurrentEip,\r
120 OUT UINTN *EntryPoint\r
121 )\r
122{\r
123 UINTN Pe32Data;\r
124 EFI_IMAGE_DOS_HEADER *DosHdr;\r
125 EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;\r
126 VOID *PdbPointer;\r
127\r
128 //\r
129 // Find Image Base\r
130 //\r
131 Pe32Data = CurrentEip & ~(mImageAlignSize - 1);\r
132 while (Pe32Data != 0) {\r
133 DosHdr = (EFI_IMAGE_DOS_HEADER *) Pe32Data;\r
134 if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {\r
135 //\r
136 // DOS image header is present, so read the PE header after the DOS image header.\r
137 //\r
138 Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)(Pe32Data + (UINTN) ((DosHdr->e_lfanew) & 0x0ffff));\r
9e2364ef
JF
139 //\r
140 // Make sure PE header address does not overflow and is less than the initial address.\r
141 //\r
142 if (((UINTN)Hdr.Pe32 > Pe32Data) && ((UINTN)Hdr.Pe32 < CurrentEip)) {\r
143 if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) {\r
144 //\r
145 // It's PE image.\r
146 //\r
147 InternalPrintMessage ("!!!! Find PE image ");\r
148 *EntryPoint = (UINTN)Pe32Data + (UINTN)(Hdr.Pe32->OptionalHeader.AddressOfEntryPoint & 0x0ffffffff);\r
149 break;\r
150 }\r
8f07f895 151 }\r
152 } else {\r
153 //\r
154 // DOS image header is not present, TE header is at the image base.\r
155 //\r
156 Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)Pe32Data;\r
157 if ((Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) &&\r
158 ((Hdr.Te->Machine == IMAGE_FILE_MACHINE_I386) || Hdr.Te->Machine == IMAGE_FILE_MACHINE_X64)) {\r
159 //\r
160 // It's TE image, it TE header and Machine type match\r
161 //\r
162 InternalPrintMessage ("!!!! Find TE image ");\r
163 *EntryPoint = (UINTN)Pe32Data + (UINTN)(Hdr.Te->AddressOfEntryPoint & 0x0ffffffff) + sizeof(EFI_TE_IMAGE_HEADER) - Hdr.Te->StrippedSize;\r
164 break;\r
165 }\r
166 }\r
167\r
168 //\r
169 // Not found the image base, check the previous aligned address\r
a51ee144 170 //\r
8f07f895 171 Pe32Data -= mImageAlignSize;\r
172 }\r
173\r
174 if (Pe32Data != 0) {\r
175 PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *) Pe32Data);\r
176 if (PdbPointer != NULL) {\r
177 InternalPrintMessage ("%a", PdbPointer);\r
178 } else {\r
179 InternalPrintMessage ("(No PDB) " );\r
180 }\r
181 } else {\r
182 InternalPrintMessage ("!!!! Can't find image information. !!!!\n");\r
183 }\r
184\r
185 return Pe32Data;\r
186}\r
187\r
e41aad15
JF
188/**\r
189 Read and save reserved vector information\r
a51ee144 190\r
e41aad15
JF
191 @param[in] VectorInfo Pointer to reserved vector list.\r
192 @param[out] ReservedVector Pointer to reserved vector data buffer.\r
193 @param[in] VectorCount Vector number to be updated.\r
a51ee144 194\r
e41aad15
JF
195 @return EFI_SUCCESS Read and save vector info successfully.\r
196 @retval EFI_INVALID_PARAMETER VectorInfo includes the invalid content if VectorInfo is not NULL.\r
197\r
198**/\r
199EFI_STATUS\r
200ReadAndVerifyVectorInfo (\r
201 IN EFI_VECTOR_HANDOFF_INFO *VectorInfo,\r
202 OUT RESERVED_VECTORS_DATA *ReservedVector,\r
203 IN UINTN VectorCount\r
204 )\r
205{\r
206 while (VectorInfo->Attribute != EFI_VECTOR_HANDOFF_LAST_ENTRY) {\r
207 if (VectorInfo->Attribute > EFI_VECTOR_HANDOFF_HOOK_AFTER) {\r
208 //\r
209 // If vector attrubute is invalid\r
210 //\r
211 return EFI_INVALID_PARAMETER;\r
212 }\r
213 if (VectorInfo->VectorNumber < VectorCount) {\r
214 ReservedVector[VectorInfo->VectorNumber].Attribute = VectorInfo->Attribute;\r
215 }\r
216 VectorInfo ++;\r
217 }\r
218 return EFI_SUCCESS;\r
219}