]> git.proxmox.com Git - mirror_edk2.git/blame - UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c
1. Separated DxeSmmCpuExceptionHandlerLib.inf into 2 instance DxeCpuExceptionHandlerL...
[mirror_edk2.git] / UefiCpuPkg / Library / CpuExceptionHandlerLib / CpuExceptionCommon.c
CommitLineData
8f07f895 1/** @file\r
2 CPU Exception Hanlder Library common functions.\r
3\r
e41aad15 4 Copyright (c) 2012 - 2013, 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
27// Define the maximum message length \r
28//\r
29#define MAX_DEBUG_MESSAGE_LENGTH 0x100\r
30\r
31/**\r
32 Prints a message to the serial port.\r
33\r
34 @param Format Format string for the message to print.\r
35 @param ... Variable argument list whose contents are accessed \r
36 based on the format string specified by Format.\r
37\r
38**/\r
39VOID\r
40EFIAPI\r
41InternalPrintMessage (\r
42 IN CONST CHAR8 *Format,\r
43 ...\r
44 )\r
45{\r
46 CHAR8 Buffer[MAX_DEBUG_MESSAGE_LENGTH];\r
47 VA_LIST Marker;\r
48\r
49 //\r
50 // Convert the message to an ASCII String\r
51 //\r
52 VA_START (Marker, Format);\r
53 AsciiVSPrint (Buffer, sizeof (Buffer), Format, Marker);\r
54 VA_END (Marker);\r
55\r
56 //\r
57 // Send the print string to a Serial Port \r
58 //\r
59 SerialPortWrite ((UINT8 *)Buffer, AsciiStrLen (Buffer));\r
60}\r
61\r
62/**\r
63 Find and display image base address and return image base and its entry point.\r
64 \r
a9c7ab95 65 @param CurrentEip Current instruction pointer.\r
66 @param EntryPoint Return module entry point if module header is found.\r
67 \r
68 @return !0 Image base address.\r
69 @return 0 Image header cannot be found.\r
8f07f895 70**/\r
71UINTN \r
72FindModuleImageBase (\r
73 IN UINTN CurrentEip,\r
74 OUT UINTN *EntryPoint\r
75 )\r
76{\r
77 UINTN Pe32Data;\r
78 EFI_IMAGE_DOS_HEADER *DosHdr;\r
79 EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;\r
80 VOID *PdbPointer;\r
81\r
82 //\r
83 // Find Image Base\r
84 //\r
85 Pe32Data = CurrentEip & ~(mImageAlignSize - 1);\r
86 while (Pe32Data != 0) {\r
87 DosHdr = (EFI_IMAGE_DOS_HEADER *) Pe32Data;\r
88 if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {\r
89 //\r
90 // DOS image header is present, so read the PE header after the DOS image header.\r
91 //\r
92 Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)(Pe32Data + (UINTN) ((DosHdr->e_lfanew) & 0x0ffff));\r
93 if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) {\r
94 //\r
95 // It's PE image.\r
96 //\r
97 InternalPrintMessage ("!!!! Find PE image ");\r
98 *EntryPoint = (UINTN)Pe32Data + (UINTN)(Hdr.Pe32->OptionalHeader.AddressOfEntryPoint & 0x0ffffffff);\r
99 break;\r
100 }\r
101 } else {\r
102 //\r
103 // DOS image header is not present, TE header is at the image base.\r
104 //\r
105 Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)Pe32Data;\r
106 if ((Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) &&\r
107 ((Hdr.Te->Machine == IMAGE_FILE_MACHINE_I386) || Hdr.Te->Machine == IMAGE_FILE_MACHINE_X64)) {\r
108 //\r
109 // It's TE image, it TE header and Machine type match\r
110 //\r
111 InternalPrintMessage ("!!!! Find TE image ");\r
112 *EntryPoint = (UINTN)Pe32Data + (UINTN)(Hdr.Te->AddressOfEntryPoint & 0x0ffffffff) + sizeof(EFI_TE_IMAGE_HEADER) - Hdr.Te->StrippedSize;\r
113 break;\r
114 }\r
115 }\r
116\r
117 //\r
118 // Not found the image base, check the previous aligned address\r
119 // \r
120 Pe32Data -= mImageAlignSize;\r
121 }\r
122\r
123 if (Pe32Data != 0) {\r
124 PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *) Pe32Data);\r
125 if (PdbPointer != NULL) {\r
126 InternalPrintMessage ("%a", PdbPointer);\r
127 } else {\r
128 InternalPrintMessage ("(No PDB) " );\r
129 }\r
130 } else {\r
131 InternalPrintMessage ("!!!! Can't find image information. !!!!\n");\r
132 }\r
133\r
134 return Pe32Data;\r
135}\r
136\r
e41aad15
JF
137/**\r
138 Read and save reserved vector information\r
139 \r
140 @param[in] VectorInfo Pointer to reserved vector list.\r
141 @param[out] ReservedVector Pointer to reserved vector data buffer.\r
142 @param[in] VectorCount Vector number to be updated.\r
143 \r
144 @return EFI_SUCCESS Read and save vector info successfully.\r
145 @retval EFI_INVALID_PARAMETER VectorInfo includes the invalid content if VectorInfo is not NULL.\r
146\r
147**/\r
148EFI_STATUS\r
149ReadAndVerifyVectorInfo (\r
150 IN EFI_VECTOR_HANDOFF_INFO *VectorInfo,\r
151 OUT RESERVED_VECTORS_DATA *ReservedVector,\r
152 IN UINTN VectorCount\r
153 )\r
154{\r
155 while (VectorInfo->Attribute != EFI_VECTOR_HANDOFF_LAST_ENTRY) {\r
156 if (VectorInfo->Attribute > EFI_VECTOR_HANDOFF_HOOK_AFTER) {\r
157 //\r
158 // If vector attrubute is invalid\r
159 //\r
160 return EFI_INVALID_PARAMETER;\r
161 }\r
162 if (VectorInfo->VectorNumber < VectorCount) {\r
163 ReservedVector[VectorInfo->VectorNumber].Attribute = VectorInfo->Attribute;\r
164 }\r
165 VectorInfo ++;\r
166 }\r
167 return EFI_SUCCESS;\r
168}