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