2 CPU Exception Handler Library common functions.
4 Copyright (c) 2012 - 2015, 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
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.
15 #include "CpuExceptionCommon.h"
18 // Error code flag indicating whether or not an error code will be
19 // pushed on the stack if an exception occurs.
21 // 1 means an error code will be pushed, otherwise 0
23 CONST UINT32 mErrorCodeFlag
= 0x00027d00;
24 RESERVED_VECTORS_DATA
*mReservedVectors
= NULL
;
27 // Define the maximum message length
29 #define MAX_DEBUG_MESSAGE_LENGTH 0x100
31 CONST CHAR8 mExceptionReservedStr
[] = "Reserved";
32 CONST CHAR8
*mExceptionNameStr
[] = {
38 "#BR - BOUND Range Exceeded",
39 "#UD - Invalid Opcode",
40 "#NM - Device Not Available",
42 "Coprocessor Segment Overrun",
44 "#NP - Segment Not Present",
45 "#SS - Stack Fault Fault",
46 "#GP - General Protection",
49 "#MF - x87 FPU Floating-Point Error",
50 "#AC - Alignment Check",
51 "#MC - Machine-Check",
52 "#XM - SIMD floating-point",
53 "#VE - Virtualization"
56 #define EXCEPTION_KNOWN_NAME_NUM (sizeof (mExceptionNameStr) / sizeof (CHAR8 *))
59 Get ASCII format string exception name by exception type.
61 @param ExceptionType Exception type.
63 @return ASCII format string exception name.
67 IN EFI_EXCEPTION_TYPE ExceptionType
70 if ((UINTN
) ExceptionType
< EXCEPTION_KNOWN_NAME_NUM
) {
71 return mExceptionNameStr
[ExceptionType
];
73 return mExceptionReservedStr
;
78 Prints a message to the serial port.
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.
87 InternalPrintMessage (
88 IN CONST CHAR8
*Format
,
92 CHAR8 Buffer
[MAX_DEBUG_MESSAGE_LENGTH
];
96 // Convert the message to an ASCII String
98 VA_START (Marker
, Format
);
99 AsciiVSPrint (Buffer
, sizeof (Buffer
), Format
, Marker
);
103 // Send the print string to a Serial Port
105 SerialPortWrite ((UINT8
*)Buffer
, AsciiStrLen (Buffer
));
109 Find and display image base address and return image base and its entry point.
111 @param CurrentEip Current instruction pointer.
112 @param EntryPoint Return module entry point if module header is found.
114 @return !0 Image base address.
115 @return 0 Image header cannot be found.
118 FindModuleImageBase (
120 OUT UINTN
*EntryPoint
124 EFI_IMAGE_DOS_HEADER
*DosHdr
;
125 EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr
;
131 Pe32Data
= CurrentEip
& ~(mImageAlignSize
- 1);
132 while (Pe32Data
!= 0) {
133 DosHdr
= (EFI_IMAGE_DOS_HEADER
*) Pe32Data
;
134 if (DosHdr
->e_magic
== EFI_IMAGE_DOS_SIGNATURE
) {
136 // DOS image header is present, so read the PE header after the DOS image header.
138 Hdr
.Pe32
= (EFI_IMAGE_NT_HEADERS32
*)(Pe32Data
+ (UINTN
) ((DosHdr
->e_lfanew
) & 0x0ffff));
140 // Make sure PE header address does not overflow and is less than the initial address.
142 if (((UINTN
)Hdr
.Pe32
> Pe32Data
) && ((UINTN
)Hdr
.Pe32
< CurrentEip
)) {
143 if (Hdr
.Pe32
->Signature
== EFI_IMAGE_NT_SIGNATURE
) {
147 InternalPrintMessage ("!!!! Find PE image ");
148 *EntryPoint
= (UINTN
)Pe32Data
+ (UINTN
)(Hdr
.Pe32
->OptionalHeader
.AddressOfEntryPoint
& 0x0ffffffff);
154 // DOS image header is not present, TE header is at the image base.
156 Hdr
.Pe32
= (EFI_IMAGE_NT_HEADERS32
*)Pe32Data
;
157 if ((Hdr
.Te
->Signature
== EFI_TE_IMAGE_HEADER_SIGNATURE
) &&
158 ((Hdr
.Te
->Machine
== IMAGE_FILE_MACHINE_I386
) || Hdr
.Te
->Machine
== IMAGE_FILE_MACHINE_X64
)) {
160 // It's TE image, it TE header and Machine type match
162 InternalPrintMessage ("!!!! Find TE image ");
163 *EntryPoint
= (UINTN
)Pe32Data
+ (UINTN
)(Hdr
.Te
->AddressOfEntryPoint
& 0x0ffffffff) + sizeof(EFI_TE_IMAGE_HEADER
) - Hdr
.Te
->StrippedSize
;
169 // Not found the image base, check the previous aligned address
171 Pe32Data
-= mImageAlignSize
;
175 PdbPointer
= PeCoffLoaderGetPdbPointer ((VOID
*) Pe32Data
);
176 if (PdbPointer
!= NULL
) {
177 InternalPrintMessage ("%a", PdbPointer
);
179 InternalPrintMessage ("(No PDB) " );
182 InternalPrintMessage ("!!!! Can't find image information. !!!!\n");
189 Read and save reserved vector information
191 @param[in] VectorInfo Pointer to reserved vector list.
192 @param[out] ReservedVector Pointer to reserved vector data buffer.
193 @param[in] VectorCount Vector number to be updated.
195 @return EFI_SUCCESS Read and save vector info successfully.
196 @retval EFI_INVALID_PARAMETER VectorInfo includes the invalid content if VectorInfo is not NULL.
200 ReadAndVerifyVectorInfo (
201 IN EFI_VECTOR_HANDOFF_INFO
*VectorInfo
,
202 OUT RESERVED_VECTORS_DATA
*ReservedVector
,
206 while (VectorInfo
->Attribute
!= EFI_VECTOR_HANDOFF_LAST_ENTRY
) {
207 if (VectorInfo
->Attribute
> EFI_VECTOR_HANDOFF_HOOK_AFTER
) {
209 // If vector attrubute is invalid
211 return EFI_INVALID_PARAMETER
;
213 if (VectorInfo
->VectorNumber
< VectorCount
) {
214 ReservedVector
[VectorInfo
->VectorNumber
].Attribute
= VectorInfo
->Attribute
;