• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
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[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
ArchSaveExceptionContext(IN UINTN ExceptionType,IN EFI_SYSTEM_CONTEXT SystemContext,IN EXCEPTION_HANDLER_DATA * ExceptionHandlerData)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
ArchRestoreExceptionContext(IN UINTN ExceptionType,IN EFI_SYSTEM_CONTEXT SystemContext,IN EXCEPTION_HANDLER_DATA * ExceptionHandlerData)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
DumpCpuContent(IN EFI_EXCEPTION_TYPE ExceptionType,IN EFI_SYSTEM_CONTEXT SystemContext)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