]> git.proxmox.com Git - mirror_edk2.git/blob - UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c
65f0cff6805f07dd5df96b375694a62faf894bfe
[mirror_edk2.git] / UefiCpuPkg / Library / CpuExceptionHandlerLib / X64 / ArchExceptionHandler.c
1 /** @file
2 x64 CPU Exception Handler.
3
4 Copyright (c) 2012 - 2017, 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
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
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[in] ExceptionType Exception type.
55 @param[in] SystemContext Pointer to EFI_SYSTEM_CONTEXT.
56 @param[in] ExceptionHandlerData Pointer to exception handler data.
57 **/
58 VOID
59 ArchSaveExceptionContext (
60 IN UINTN ExceptionType,
61 IN EFI_SYSTEM_CONTEXT SystemContext,
62 IN EXCEPTION_HANDLER_DATA *ExceptionHandlerData
63 )
64 {
65 IA32_EFLAGS32 Eflags;
66 RESERVED_VECTORS_DATA *ReservedVectors;
67
68 ReservedVectors = ExceptionHandlerData->ReservedVectors;
69 //
70 // Save Exception context in global variable
71 //
72 ReservedVectors[ExceptionType].OldSs = SystemContext.SystemContextX64->Ss;
73 ReservedVectors[ExceptionType].OldSp = SystemContext.SystemContextX64->Rsp;
74 ReservedVectors[ExceptionType].OldFlags = SystemContext.SystemContextX64->Rflags;
75 ReservedVectors[ExceptionType].OldCs = SystemContext.SystemContextX64->Cs;
76 ReservedVectors[ExceptionType].OldIp = SystemContext.SystemContextX64->Rip;
77 ReservedVectors[ExceptionType].ExceptionData = SystemContext.SystemContextX64->ExceptionData;
78 //
79 // Clear IF flag to avoid old IDT handler enable interrupt by IRET
80 //
81 Eflags.UintN = SystemContext.SystemContextX64->Rflags;
82 Eflags.Bits.IF = 0;
83 SystemContext.SystemContextX64->Rflags = Eflags.UintN;
84 //
85 // Modify the EIP in stack, then old IDT handler will return to the stub code
86 //
87 SystemContext.SystemContextX64->Rip = (UINTN) ReservedVectors[ExceptionType].HookAfterStubHeaderCode;
88 }
89
90 /**
91 Restore CPU exception context when handling EFI_VECTOR_HANDOFF_HOOK_AFTER case.
92
93 @param[in] ExceptionType Exception type.
94 @param[in] SystemContext Pointer to EFI_SYSTEM_CONTEXT.
95 @param[in] ExceptionHandlerData Pointer to exception handler data.
96 **/
97 VOID
98 ArchRestoreExceptionContext (
99 IN UINTN ExceptionType,
100 IN EFI_SYSTEM_CONTEXT SystemContext,
101 IN EXCEPTION_HANDLER_DATA *ExceptionHandlerData
102 )
103 {
104 RESERVED_VECTORS_DATA *ReservedVectors;
105
106 ReservedVectors = ExceptionHandlerData->ReservedVectors;
107 SystemContext.SystemContextX64->Ss = ReservedVectors[ExceptionType].OldSs;
108 SystemContext.SystemContextX64->Rsp = ReservedVectors[ExceptionType].OldSp;
109 SystemContext.SystemContextX64->Rflags = ReservedVectors[ExceptionType].OldFlags;
110 SystemContext.SystemContextX64->Cs = ReservedVectors[ExceptionType].OldCs;
111 SystemContext.SystemContextX64->Rip = ReservedVectors[ExceptionType].OldIp;
112 SystemContext.SystemContextX64->ExceptionData = ReservedVectors[ExceptionType].ExceptionData;
113 }
114
115 /**
116 Display CPU information.
117
118 @param ExceptionType Exception type.
119 @param SystemContext Pointer to EFI_SYSTEM_CONTEXT.
120 **/
121 VOID
122 EFIAPI
123 DumpCpuContext (
124 IN EFI_EXCEPTION_TYPE ExceptionType,
125 IN EFI_SYSTEM_CONTEXT SystemContext
126 )
127 {
128 InternalPrintMessage (
129 "!!!! X64 Exception Type - %02x(%a) CPU Apic ID - %08x !!!!\n",
130 ExceptionType,
131 GetExceptionNameStr (ExceptionType),
132 GetApicId ()
133 );
134 if ((mErrorCodeFlag & (1 << ExceptionType)) != 0) {
135 InternalPrintMessage (
136 "ExceptionData - %016lx",
137 SystemContext.SystemContextX64->ExceptionData
138 );
139 if (ExceptionType == EXCEPT_IA32_PAGE_FAULT) {
140 InternalPrintMessage (
141 " I:%x R:%x U:%x W:%x P:%x PK:%x S:%x",
142 (SystemContext.SystemContextX64->ExceptionData & IA32_PF_EC_ID) != 0,
143 (SystemContext.SystemContextX64->ExceptionData & IA32_PF_EC_RSVD) != 0,
144 (SystemContext.SystemContextX64->ExceptionData & IA32_PF_EC_US) != 0,
145 (SystemContext.SystemContextX64->ExceptionData & IA32_PF_EC_WR) != 0,
146 (SystemContext.SystemContextX64->ExceptionData & IA32_PF_EC_P) != 0,
147 (SystemContext.SystemContextX64->ExceptionData & IA32_PF_EC_PK) != 0,
148 (SystemContext.SystemContextX64->ExceptionData & IA32_PF_EC_SGX) != 0
149 );
150 }
151 InternalPrintMessage ("\n");
152 }
153 InternalPrintMessage (
154 "RIP - %016lx, CS - %016lx, RFLAGS - %016lx\n",
155 SystemContext.SystemContextX64->Rip,
156 SystemContext.SystemContextX64->Cs,
157 SystemContext.SystemContextX64->Rflags
158 );
159 InternalPrintMessage (
160 "RAX - %016lx, RCX - %016lx, RDX - %016lx\n",
161 SystemContext.SystemContextX64->Rax,
162 SystemContext.SystemContextX64->Rcx,
163 SystemContext.SystemContextX64->Rdx
164 );
165 InternalPrintMessage (
166 "RBX - %016lx, RSP - %016lx, RBP - %016lx\n",
167 SystemContext.SystemContextX64->Rbx,
168 SystemContext.SystemContextX64->Rsp,
169 SystemContext.SystemContextX64->Rbp
170 );
171 InternalPrintMessage (
172 "RSI - %016lx, RDI - %016lx\n",
173 SystemContext.SystemContextX64->Rsi,
174 SystemContext.SystemContextX64->Rdi
175 );
176 InternalPrintMessage (
177 "R8 - %016lx, R9 - %016lx, R10 - %016lx\n",
178 SystemContext.SystemContextX64->R8,
179 SystemContext.SystemContextX64->R9,
180 SystemContext.SystemContextX64->R10
181 );
182 InternalPrintMessage (
183 "R11 - %016lx, R12 - %016lx, R13 - %016lx\n",
184 SystemContext.SystemContextX64->R11,
185 SystemContext.SystemContextX64->R12,
186 SystemContext.SystemContextX64->R13
187 );
188 InternalPrintMessage (
189 "R14 - %016lx, R15 - %016lx\n",
190 SystemContext.SystemContextX64->R14,
191 SystemContext.SystemContextX64->R15
192 );
193 InternalPrintMessage (
194 "DS - %016lx, ES - %016lx, FS - %016lx\n",
195 SystemContext.SystemContextX64->Ds,
196 SystemContext.SystemContextX64->Es,
197 SystemContext.SystemContextX64->Fs
198 );
199 InternalPrintMessage (
200 "GS - %016lx, SS - %016lx\n",
201 SystemContext.SystemContextX64->Gs,
202 SystemContext.SystemContextX64->Ss
203 );
204 InternalPrintMessage (
205 "CR0 - %016lx, CR2 - %016lx, CR3 - %016lx\n",
206 SystemContext.SystemContextX64->Cr0,
207 SystemContext.SystemContextX64->Cr2,
208 SystemContext.SystemContextX64->Cr3
209 );
210 InternalPrintMessage (
211 "CR4 - %016lx, CR8 - %016lx\n",
212 SystemContext.SystemContextX64->Cr4,
213 SystemContext.SystemContextX64->Cr8
214 );
215 InternalPrintMessage (
216 "DR0 - %016lx, DR1 - %016lx, DR2 - %016lx\n",
217 SystemContext.SystemContextX64->Dr0,
218 SystemContext.SystemContextX64->Dr1,
219 SystemContext.SystemContextX64->Dr2
220 );
221 InternalPrintMessage (
222 "DR3 - %016lx, DR6 - %016lx, DR7 - %016lx\n",
223 SystemContext.SystemContextX64->Dr3,
224 SystemContext.SystemContextX64->Dr6,
225 SystemContext.SystemContextX64->Dr7
226 );
227 InternalPrintMessage (
228 "GDTR - %016lx %016lx, LDTR - %016lx\n",
229 SystemContext.SystemContextX64->Gdtr[0],
230 SystemContext.SystemContextX64->Gdtr[1],
231 SystemContext.SystemContextX64->Ldtr
232 );
233 InternalPrintMessage (
234 "IDTR - %016lx %016lx, TR - %016lx\n",
235 SystemContext.SystemContextX64->Idtr[0],
236 SystemContext.SystemContextX64->Idtr[1],
237 SystemContext.SystemContextX64->Tr
238 );
239 InternalPrintMessage (
240 "FXSAVE_STATE - %016lx\n",
241 &SystemContext.SystemContextX64->FxSaveState
242 );
243 }
244
245 /**
246 Display CPU information.
247
248 @param ExceptionType Exception type.
249 @param SystemContext Pointer to EFI_SYSTEM_CONTEXT.
250 **/
251 VOID
252 DumpImageAndCpuContent (
253 IN EFI_EXCEPTION_TYPE ExceptionType,
254 IN EFI_SYSTEM_CONTEXT SystemContext
255 )
256 {
257 DumpCpuContext (ExceptionType, SystemContext);
258 //
259 // Dump module image base and module entry point by RIP
260 //
261 DumpModuleImageInfo (SystemContext.SystemContextX64->Rip);
262 }