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