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**/
25VOID
26ArchUpdateIdtEntry (
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**/
42UINTN
43ArchGetIdtHandler (
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**/
57VOID
58ArchSaveExceptionContext (
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**/
89VOID
90ArchRestoreExceptionContext (
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**/
107VOID
108DumpCpuContent (
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