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 } 246