1 /** @file
2 x64 CPU Exception Handler.
3
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
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 Return address map of exception handler template so that C code can generate
19 exception tables.
20
21 @param IdtEntry Pointer to IDT entry to be updated.
22 @param InterruptHandler IDT handler value.
23 **/
24 VOID
ArchUpdateIdtEntry(IN IA32_IDT_GATE_DESCRIPTOR * IdtEntry,IN UINTN InterruptHandler)25 ArchUpdateIdtEntry (
26 IN IA32_IDT_GATE_DESCRIPTOR *IdtEntry,
27 IN UINTN InterruptHandler
28 )
29 {
30 IdtEntry->Bits.OffsetLow = (UINT16)(UINTN)InterruptHandler;
31 IdtEntry->Bits.OffsetHigh = (UINT16)((UINTN)InterruptHandler >> 16);
32 IdtEntry->Bits.OffsetUpper = (UINT32)((UINTN)InterruptHandler >> 32);
33 IdtEntry->Bits.GateType = IA32_IDT_GATE_TYPE_INTERRUPT_32;
34 }
35
36 /**
37 Read IDT handler value from IDT entry.
38
39 @param IdtEntry Pointer to IDT entry to be read.
40
41 **/
42 UINTN
ArchGetIdtHandler(IN IA32_IDT_GATE_DESCRIPTOR * IdtEntry)43 ArchGetIdtHandler (
44 IN IA32_IDT_GATE_DESCRIPTOR *IdtEntry
45 )
46 {
47 return IdtEntry->Bits.OffsetLow + (((UINTN) IdtEntry->Bits.OffsetHigh) << 16) +
48 (((UINTN) IdtEntry->Bits.OffsetUpper) << 32);
49 }
50
51 /**
52 Save CPU exception context when handling EFI_VECTOR_HANDOFF_HOOK_AFTER case.
53
54 @param ExceptionType Exception type.
55 @param SystemContext Pointer to EFI_SYSTEM_CONTEXT.
56 **/
57 VOID
ArchSaveExceptionContext(IN UINTN ExceptionType,IN EFI_SYSTEM_CONTEXT SystemContext)58 ArchSaveExceptionContext (
59 IN UINTN ExceptionType,
60 IN EFI_SYSTEM_CONTEXT SystemContext
61 )
62 {
63 IA32_EFLAGS32 Eflags;
64 //
65 // Save Exception context in global variable
66 //
67 mReservedVectors[ExceptionType].OldSs = SystemContext.SystemContextX64->Ss;
68 mReservedVectors[ExceptionType].OldSp = SystemContext.SystemContextX64->Rsp;
69 mReservedVectors[ExceptionType].OldFlags = SystemContext.SystemContextX64->Rflags;
70 mReservedVectors[ExceptionType].OldCs = SystemContext.SystemContextX64->Cs;
71 mReservedVectors[ExceptionType].OldIp = SystemContext.SystemContextX64->Rip;
72 mReservedVectors[ExceptionType].ExceptionData = SystemContext.SystemContextX64->ExceptionData;
73 //
74 // Clear IF flag to avoid old IDT handler enable interrupt by IRET
75 //
76 Eflags.UintN = SystemContext.SystemContextX64->Rflags;
77 Eflags.Bits.IF = 0;
78 SystemContext.SystemContextX64->Rflags = Eflags.UintN;
79 //
80 // Modify the EIP in stack, then old IDT handler will return to the stub code
81 //
82 SystemContext.SystemContextX64->Rip = (UINTN) mReservedVectors[ExceptionType].HookAfterStubHeaderCode;
83 }
84
85 /**
86 Restore CPU exception context when handling EFI_VECTOR_HANDOFF_HOOK_AFTER case.
87
88 @param ExceptionType Exception type.
89 @param SystemContext Pointer to EFI_SYSTEM_CONTEXT.
90 **/
91 VOID
ArchRestoreExceptionContext(IN UINTN ExceptionType,IN EFI_SYSTEM_CONTEXT SystemContext)92 ArchRestoreExceptionContext (
93 IN UINTN ExceptionType,
94 IN EFI_SYSTEM_CONTEXT SystemContext
95 )
96 {
97 SystemContext.SystemContextX64->Ss = mReservedVectors[ExceptionType].OldSs;
98 SystemContext.SystemContextX64->Rsp = mReservedVectors[ExceptionType].OldSp;
99 SystemContext.SystemContextX64->Rflags = mReservedVectors[ExceptionType].OldFlags;
100 SystemContext.SystemContextX64->Cs = mReservedVectors[ExceptionType].OldCs;
101 SystemContext.SystemContextX64->Rip = mReservedVectors[ExceptionType].OldIp;
102 SystemContext.SystemContextX64->ExceptionData = mReservedVectors[ExceptionType].ExceptionData;
103 }
104
105 /**
106 Display CPU information.
107
108 @param ExceptionType Exception type.
109 @param SystemContext Pointer to EFI_SYSTEM_CONTEXT.
110 **/
111 VOID
DumpCpuContent(IN EFI_EXCEPTION_TYPE ExceptionType,IN EFI_SYSTEM_CONTEXT SystemContext)112 DumpCpuContent (
113 IN EFI_EXCEPTION_TYPE ExceptionType,
114 IN EFI_SYSTEM_CONTEXT SystemContext
115 )
116 {
117 UINTN ImageBase;
118 UINTN EntryPoint;
119
120 InternalPrintMessage (
121 "!!!! X64 Exception Type - %02x(%a) CPU Apic ID - %08x !!!!\n",
122 ExceptionType,
123 GetExceptionNameStr (ExceptionType),
124 GetApicId ()
125 );
126
127 InternalPrintMessage (
128 "RIP - %016lx, CS - %016lx, RFLAGS - %016lx\n",
129 SystemContext.SystemContextX64->Rip,
130 SystemContext.SystemContextX64->Cs,
131 SystemContext.SystemContextX64->Rflags
132 );
133 if (mErrorCodeFlag & (1 << ExceptionType)) {
134 InternalPrintMessage (
135 "ExceptionData - %016lx\n",
136 SystemContext.SystemContextX64->ExceptionData
137 );
138 }
139 InternalPrintMessage (
140 "RAX - %016lx, RCX - %016lx, RDX - %016lx\n",
141 SystemContext.SystemContextX64->Rax,
142 SystemContext.SystemContextX64->Rcx,
143 SystemContext.SystemContextX64->Rdx
144 );
145 InternalPrintMessage (
146 "RBX - %016lx, RSP - %016lx, RBP - %016lx\n",
147 SystemContext.SystemContextX64->Rbx,
148 SystemContext.SystemContextX64->Rsp,
149 SystemContext.SystemContextX64->Rbp
150 );
151 InternalPrintMessage (
152 "RSI - %016lx, RDI - %016lx\n",
153 SystemContext.SystemContextX64->Rsi,
154 SystemContext.SystemContextX64->Rdi
155 );
156 InternalPrintMessage (
157 "R8 - %016lx, R9 - %016lx, R10 - %016lx\n",
158 SystemContext.SystemContextX64->R8,
159 SystemContext.SystemContextX64->R9,
160 SystemContext.SystemContextX64->R10
161 );
162 InternalPrintMessage (
163 "R11 - %016lx, R12 - %016lx, R13 - %016lx\n",
164 SystemContext.SystemContextX64->R11,
165 SystemContext.SystemContextX64->R12,
166 SystemContext.SystemContextX64->R13
167 );
168 InternalPrintMessage (
169 "R14 - %016lx, R15 - %016lx\n",
170 SystemContext.SystemContextX64->R14,
171 SystemContext.SystemContextX64->R15
172 );
173 InternalPrintMessage (
174 "DS - %016lx, ES - %016lx, FS - %016lx\n",
175 SystemContext.SystemContextX64->Ds,
176 SystemContext.SystemContextX64->Es,
177 SystemContext.SystemContextX64->Fs
178 );
179 InternalPrintMessage (
180 "GS - %016lx, SS - %016lx\n",
181 SystemContext.SystemContextX64->Gs,
182 SystemContext.SystemContextX64->Ss
183 );
184 InternalPrintMessage (
185 "CR0 - %016lx, CR2 - %016lx, CR3 - %016lx\n",
186 SystemContext.SystemContextX64->Cr0,
187 SystemContext.SystemContextX64->Cr2,
188 SystemContext.SystemContextX64->Cr3
189 );
190 InternalPrintMessage (
191 "CR4 - %016lx, CR8 - %016lx\n",
192 SystemContext.SystemContextX64->Cr4,
193 SystemContext.SystemContextX64->Cr8
194 );
195 InternalPrintMessage (
196 "DR0 - %016lx, DR1 - %016lx, DR2 - %016lx\n",
197 SystemContext.SystemContextX64->Dr0,
198 SystemContext.SystemContextX64->Dr1,
199 SystemContext.SystemContextX64->Dr2
200 );
201 InternalPrintMessage (
202 "DR3 - %016lx, DR6 - %016lx, DR7 - %016lx\n",
203 SystemContext.SystemContextX64->Dr3,
204 SystemContext.SystemContextX64->Dr6,
205 SystemContext.SystemContextX64->Dr7
206 );
207 InternalPrintMessage (
208 "GDTR - %016lx %016lx, LDTR - %016lx\n",
209 SystemContext.SystemContextX64->Gdtr[0],
210 SystemContext.SystemContextX64->Gdtr[1],
211 SystemContext.SystemContextX64->Ldtr
212 );
213 InternalPrintMessage (
214 "IDTR - %016lx %016lx, TR - %016lx\n",
215 SystemContext.SystemContextX64->Idtr[0],
216 SystemContext.SystemContextX64->Idtr[1],
217 SystemContext.SystemContextX64->Tr
218 );
219 InternalPrintMessage (
220 "FXSAVE_STATE - %016lx\n",
221 &SystemContext.SystemContextX64->FxSaveState
222 );
223
224 //
225 // Find module image base and module entry point by RIP
226 //
227 ImageBase = FindModuleImageBase (SystemContext.SystemContextX64->Rip, &EntryPoint);
228 if (ImageBase != 0) {
229 InternalPrintMessage (
230 " (ImageBase=%016lx, EntryPoint=%016lx) !!!!\n",
231 ImageBase,
232 EntryPoint
233 );
234 }
235 }
236