]> git.proxmox.com Git - mirror_edk2.git/blob - UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c
7495b14530865d315e8a219ecaeedfaf7491bbe3
[mirror_edk2.git] / UefiCpuPkg / Library / CpuExceptionHandlerLib / X64 / ArchExceptionHandler.c
1 /** @file
2 x64 CPU Exception Handler.
3
4 Copyright (c) 2012 - 2016, 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 DumpCpuContent (
123 IN EFI_EXCEPTION_TYPE ExceptionType,
124 IN EFI_SYSTEM_CONTEXT SystemContext
125 )
126 {
127 UINTN ImageBase;
128 UINTN EntryPoint;
129
130 InternalPrintMessage (
131 "!!!! X64 Exception Type - %02x(%a) CPU Apic ID - %08x !!!!\n",
132 ExceptionType,
133 GetExceptionNameStr (ExceptionType),
134 GetApicId ()
135 );
136
137 InternalPrintMessage (
138 "RIP - %016lx, CS - %016lx, RFLAGS - %016lx\n",
139 SystemContext.SystemContextX64->Rip,
140 SystemContext.SystemContextX64->Cs,
141 SystemContext.SystemContextX64->Rflags
142 );
143 if (mErrorCodeFlag & (1 << ExceptionType)) {
144 InternalPrintMessage (
145 "ExceptionData - %016lx\n",
146 SystemContext.SystemContextX64->ExceptionData
147 );
148 }
149 InternalPrintMessage (
150 "RAX - %016lx, RCX - %016lx, RDX - %016lx\n",
151 SystemContext.SystemContextX64->Rax,
152 SystemContext.SystemContextX64->Rcx,
153 SystemContext.SystemContextX64->Rdx
154 );
155 InternalPrintMessage (
156 "RBX - %016lx, RSP - %016lx, RBP - %016lx\n",
157 SystemContext.SystemContextX64->Rbx,
158 SystemContext.SystemContextX64->Rsp,
159 SystemContext.SystemContextX64->Rbp
160 );
161 InternalPrintMessage (
162 "RSI - %016lx, RDI - %016lx\n",
163 SystemContext.SystemContextX64->Rsi,
164 SystemContext.SystemContextX64->Rdi
165 );
166 InternalPrintMessage (
167 "R8 - %016lx, R9 - %016lx, R10 - %016lx\n",
168 SystemContext.SystemContextX64->R8,
169 SystemContext.SystemContextX64->R9,
170 SystemContext.SystemContextX64->R10
171 );
172 InternalPrintMessage (
173 "R11 - %016lx, R12 - %016lx, R13 - %016lx\n",
174 SystemContext.SystemContextX64->R11,
175 SystemContext.SystemContextX64->R12,
176 SystemContext.SystemContextX64->R13
177 );
178 InternalPrintMessage (
179 "R14 - %016lx, R15 - %016lx\n",
180 SystemContext.SystemContextX64->R14,
181 SystemContext.SystemContextX64->R15
182 );
183 InternalPrintMessage (
184 "DS - %016lx, ES - %016lx, FS - %016lx\n",
185 SystemContext.SystemContextX64->Ds,
186 SystemContext.SystemContextX64->Es,
187 SystemContext.SystemContextX64->Fs
188 );
189 InternalPrintMessage (
190 "GS - %016lx, SS - %016lx\n",
191 SystemContext.SystemContextX64->Gs,
192 SystemContext.SystemContextX64->Ss
193 );
194 InternalPrintMessage (
195 "CR0 - %016lx, CR2 - %016lx, CR3 - %016lx\n",
196 SystemContext.SystemContextX64->Cr0,
197 SystemContext.SystemContextX64->Cr2,
198 SystemContext.SystemContextX64->Cr3
199 );
200 InternalPrintMessage (
201 "CR4 - %016lx, CR8 - %016lx\n",
202 SystemContext.SystemContextX64->Cr4,
203 SystemContext.SystemContextX64->Cr8
204 );
205 InternalPrintMessage (
206 "DR0 - %016lx, DR1 - %016lx, DR2 - %016lx\n",
207 SystemContext.SystemContextX64->Dr0,
208 SystemContext.SystemContextX64->Dr1,
209 SystemContext.SystemContextX64->Dr2
210 );
211 InternalPrintMessage (
212 "DR3 - %016lx, DR6 - %016lx, DR7 - %016lx\n",
213 SystemContext.SystemContextX64->Dr3,
214 SystemContext.SystemContextX64->Dr6,
215 SystemContext.SystemContextX64->Dr7
216 );
217 InternalPrintMessage (
218 "GDTR - %016lx %016lx, LDTR - %016lx\n",
219 SystemContext.SystemContextX64->Gdtr[0],
220 SystemContext.SystemContextX64->Gdtr[1],
221 SystemContext.SystemContextX64->Ldtr
222 );
223 InternalPrintMessage (
224 "IDTR - %016lx %016lx, TR - %016lx\n",
225 SystemContext.SystemContextX64->Idtr[0],
226 SystemContext.SystemContextX64->Idtr[1],
227 SystemContext.SystemContextX64->Tr
228 );
229 InternalPrintMessage (
230 "FXSAVE_STATE - %016lx\n",
231 &SystemContext.SystemContextX64->FxSaveState
232 );
233
234 //
235 // Find module image base and module entry point by RIP
236 //
237 ImageBase = FindModuleImageBase (SystemContext.SystemContextX64->Rip, &EntryPoint);
238 if (ImageBase != 0) {
239 InternalPrintMessage (
240 " (ImageBase=%016lx, EntryPoint=%016lx) !!!!\n",
241 ImageBase,
242 EntryPoint
243 );
244 }
245 }