1 /** @file
2   IA32 CPU Exception Handler functons.
3 
4   Copyright (c) 2012 - 2015, 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 **/
25 VOID
ArchUpdateIdtEntry(IN IA32_IDT_GATE_DESCRIPTOR * IdtEntry,IN UINTN InterruptHandler)26 ArchUpdateIdtEntry (
27   IN IA32_IDT_GATE_DESCRIPTOR        *IdtEntry,
28   IN UINTN                           InterruptHandler
29   )
30 {
31   IdtEntry->Bits.OffsetLow   = (UINT16)(UINTN)InterruptHandler;
32   IdtEntry->Bits.OffsetHigh  = (UINT16)((UINTN)InterruptHandler >> 16);
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 (UINTN)IdtEntry->Bits.OffsetLow + (((UINTN)IdtEntry->Bits.OffsetHigh) << 16);
48 }
49 
50 /**
51   Save CPU exception context when handling EFI_VECTOR_HANDOFF_HOOK_AFTER case.
52 
53   @param ExceptionType  Exception type.
54   @param SystemContext  Pointer to EFI_SYSTEM_CONTEXT.
55 
56 **/
57 VOID
ArchSaveExceptionContext(IN UINTN ExceptionType,IN EFI_SYSTEM_CONTEXT SystemContext)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].OldFlags      = SystemContext.SystemContextIa32->Eflags;
68   mReservedVectors[ExceptionType].OldCs         = SystemContext.SystemContextIa32->Cs;
69   mReservedVectors[ExceptionType].OldIp         = SystemContext.SystemContextIa32->Eip;
70   mReservedVectors[ExceptionType].ExceptionData = SystemContext.SystemContextIa32->ExceptionData;
71   //
72   // Clear IF flag to avoid old IDT handler enable interrupt by IRET
73   //
74   Eflags.UintN = SystemContext.SystemContextIa32->Eflags;
75   Eflags.Bits.IF = 0;
76   SystemContext.SystemContextIa32->Eflags = Eflags.UintN;
77   //
78   // Modify the EIP in stack, then old IDT handler will return to the stub code
79   //
80   SystemContext.SystemContextIa32->Eip    = (UINTN) mReservedVectors[ExceptionType].HookAfterStubHeaderCode;
81 }
82 
83 /**
84   Restore CPU exception context when handling EFI_VECTOR_HANDOFF_HOOK_AFTER case.
85 
86   @param ExceptionType  Exception type.
87   @param SystemContext  Pointer to EFI_SYSTEM_CONTEXT.
88 **/
89 VOID
ArchRestoreExceptionContext(IN UINTN ExceptionType,IN EFI_SYSTEM_CONTEXT SystemContext)90 ArchRestoreExceptionContext (
91   IN UINTN                ExceptionType,
92   IN EFI_SYSTEM_CONTEXT   SystemContext
93   )
94 {
95   SystemContext.SystemContextIa32->Eflags        = mReservedVectors[ExceptionType].OldFlags;
96   SystemContext.SystemContextIa32->Cs            = mReservedVectors[ExceptionType].OldCs;
97   SystemContext.SystemContextIa32->Eip           = mReservedVectors[ExceptionType].OldIp;
98   SystemContext.SystemContextIa32->ExceptionData = mReservedVectors[ExceptionType].ExceptionData;
99 }
100 
101 /**
102   Display CPU information.
103 
104   @param ExceptionType  Exception type.
105   @param SystemContext  Pointer to EFI_SYSTEM_CONTEXT.
106 **/
107 VOID
DumpCpuContent(IN EFI_EXCEPTION_TYPE ExceptionType,IN EFI_SYSTEM_CONTEXT SystemContext)108 DumpCpuContent (
109   IN EFI_EXCEPTION_TYPE   ExceptionType,
110   IN EFI_SYSTEM_CONTEXT   SystemContext
111   )
112 {
113   UINTN                   ImageBase;
114   UINTN                   EntryPoint;
115 
116   InternalPrintMessage (
117     "!!!! IA32 Exception Type - %02x(%a)  CPU Apic ID - %08x !!!!\n",
118     ExceptionType,
119     GetExceptionNameStr (ExceptionType),
120     GetApicId ()
121     );
122 
123   InternalPrintMessage (
124     "EIP  - %08x, CS  - %08x, EFLAGS - %08x\n",
125     SystemContext.SystemContextIa32->Eip,
126     SystemContext.SystemContextIa32->Cs,
127     SystemContext.SystemContextIa32->Eflags
128     );
129   if ((mErrorCodeFlag & (1 << ExceptionType)) != 0) {
130     InternalPrintMessage (
131       "ExceptionData - %08x\n",
132       SystemContext.SystemContextIa32->ExceptionData
133       );
134   }
135   InternalPrintMessage (
136     "EAX  - %08x, ECX - %08x, EDX - %08x, EBX - %08x\n",
137     SystemContext.SystemContextIa32->Eax,
138     SystemContext.SystemContextIa32->Ecx,
139     SystemContext.SystemContextIa32->Edx,
140     SystemContext.SystemContextIa32->Ebx
141     );
142   InternalPrintMessage (
143     "ESP  - %08x, EBP - %08x, ESI - %08x, EDI - %08x\n",
144     SystemContext.SystemContextIa32->Esp,
145     SystemContext.SystemContextIa32->Ebp,
146     SystemContext.SystemContextIa32->Esi,
147     SystemContext.SystemContextIa32->Edi
148     );
149   InternalPrintMessage (
150     "DS   - %08x, ES  - %08x, FS  - %08x, GS  - %08x, SS - %08x\n",
151     SystemContext.SystemContextIa32->Ds,
152     SystemContext.SystemContextIa32->Es,
153     SystemContext.SystemContextIa32->Fs,
154     SystemContext.SystemContextIa32->Gs,
155     SystemContext.SystemContextIa32->Ss
156     );
157   InternalPrintMessage (
158     "CR0  - %08x, CR2 - %08x, CR3 - %08x, CR4 - %08x\n",
159     SystemContext.SystemContextIa32->Cr0,
160     SystemContext.SystemContextIa32->Cr2,
161     SystemContext.SystemContextIa32->Cr3,
162     SystemContext.SystemContextIa32->Cr4
163     );
164   InternalPrintMessage (
165     "DR0  - %08x, DR1 - %08x, DR2 - %08x, DR3 - %08x\n",
166     SystemContext.SystemContextIa32->Dr0,
167     SystemContext.SystemContextIa32->Dr1,
168     SystemContext.SystemContextIa32->Dr2,
169     SystemContext.SystemContextIa32->Dr3
170     );
171   InternalPrintMessage (
172     "DR6  - %08x, DR7 - %08x\n",
173     SystemContext.SystemContextIa32->Dr6,
174     SystemContext.SystemContextIa32->Dr7
175     );
176   InternalPrintMessage (
177     "GDTR - %08x %08x, IDTR - %08x %08x\n",
178     SystemContext.SystemContextIa32->Gdtr[0],
179     SystemContext.SystemContextIa32->Gdtr[1],
180     SystemContext.SystemContextIa32->Idtr[0],
181     SystemContext.SystemContextIa32->Idtr[1]
182     );
183   InternalPrintMessage (
184     "LDTR - %08x, TR - %08x\n",
185     SystemContext.SystemContextIa32->Ldtr,
186     SystemContext.SystemContextIa32->Tr
187     );
188   InternalPrintMessage (
189     "FXSAVE_STATE - %08x\n",
190     &SystemContext.SystemContextIa32->FxSaveState
191     );
192 
193   //
194   // Find module image base and module entry point by RIP
195   //
196   ImageBase = FindModuleImageBase (SystemContext.SystemContextIa32->Eip, &EntryPoint);
197   if (ImageBase != 0) {
198     InternalPrintMessage (
199       " (ImageBase=%08x, EntryPoint=%08x) !!!!\n",
200       ImageBase,
201       EntryPoint
202       );
203   }
204 }
205