TianoCore EDK2 master
Loading...
Searching...
No Matches
PeiCpuException.c
Go to the documentation of this file.
1
9#include <PiPei.h>
10#include "CpuExceptionCommon.h"
11#include <Library/DebugLib.h>
12#include <Library/HobLib.h>
14#include <Library/PcdLib.h>
15
16CONST UINTN mDoFarReturnFlag = 0;
17
18typedef struct {
19 UINT8 ExceptionStubHeader[HOOKAFTER_STUB_SIZE];
20 EXCEPTION_HANDLER_DATA *ExceptionHandlerData;
22
34 VOID
35 )
36{
37 IA32_DESCRIPTOR IdtDescriptor;
38 IA32_IDT_GATE_DESCRIPTOR *IdtTable;
39 EXCEPTION0_STUB_HEADER *Exception0StubHeader;
40
41 AsmReadIdtr (&IdtDescriptor);
42 IdtTable = (IA32_IDT_GATE_DESCRIPTOR *)IdtDescriptor.Base;
43
44 Exception0StubHeader = (EXCEPTION0_STUB_HEADER *)ArchGetIdtHandler (&IdtTable[0]);
45 return Exception0StubHeader->ExceptionHandlerData;
46}
47
57VOID
59 IN EXCEPTION_HANDLER_DATA *ExceptionHandlerData
60 )
61{
62 EXCEPTION0_STUB_HEADER *Exception0StubHeader;
63 IA32_DESCRIPTOR IdtDescriptor;
64 IA32_IDT_GATE_DESCRIPTOR *IdtTable;
65
66 //
67 // Duplicate the exception #0 stub header in pool and cache the ExceptionHandlerData just after the stub header.
68 // So AP can get the ExceptionHandlerData by reading the IDT[0].
69 //
70 AsmReadIdtr (&IdtDescriptor);
71 IdtTable = (IA32_IDT_GATE_DESCRIPTOR *)IdtDescriptor.Base;
72
73 Exception0StubHeader = AllocatePool (sizeof (*Exception0StubHeader));
74 if (Exception0StubHeader == NULL) {
75 ASSERT (Exception0StubHeader != NULL);
76 return;
77 }
78
79 CopyMem (
80 Exception0StubHeader->ExceptionStubHeader,
81 (VOID *)ArchGetIdtHandler (&IdtTable[0]),
82 sizeof (Exception0StubHeader->ExceptionStubHeader)
83 );
84 Exception0StubHeader->ExceptionHandlerData = ExceptionHandlerData;
85 ArchUpdateIdtEntry (&IdtTable[0], (UINTN)Exception0StubHeader->ExceptionStubHeader);
86}
87
94VOID
95EFIAPI
97 IN EFI_EXCEPTION_TYPE ExceptionType,
98 IN EFI_SYSTEM_CONTEXT SystemContext
99 )
100{
101 EXCEPTION_HANDLER_DATA *ExceptionHandlerData;
102
103 ExceptionHandlerData = GetExceptionHandlerData ();
104 CommonExceptionHandlerWorker (ExceptionType, SystemContext, ExceptionHandlerData);
105}
106
131EFIAPI
133 IN EFI_EXCEPTION_TYPE InterruptType,
134 IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
135 )
136{
137 EXCEPTION_HANDLER_DATA *ExceptionHandlerData;
138
139 ExceptionHandlerData = GetExceptionHandlerData ();
140 return RegisterCpuInterruptHandlerWorker (InterruptType, InterruptHandler, ExceptionHandlerData);
141}
142
162EFIAPI
164 IN EFI_VECTOR_HANDOFF_INFO *VectorInfo OPTIONAL
165 )
166{
167 EFI_STATUS Status;
168 EXCEPTION_HANDLER_DATA *ExceptionHandlerData;
169 RESERVED_VECTORS_DATA *ReservedVectors;
170
171 ReservedVectors = AllocatePool (sizeof (RESERVED_VECTORS_DATA) * CPU_EXCEPTION_NUM);
172 if (ReservedVectors == NULL) {
173 ASSERT (ReservedVectors != NULL);
174 return EFI_OUT_OF_RESOURCES;
175 }
176
177 ExceptionHandlerData = AllocatePool (sizeof (EXCEPTION_HANDLER_DATA));
178 if (ExceptionHandlerData == NULL) {
179 ASSERT (ExceptionHandlerData != NULL);
180 FreePool (ReservedVectors);
181 return EFI_OUT_OF_RESOURCES;
182 }
183
184 ExceptionHandlerData->IdtEntryCount = CPU_EXCEPTION_NUM;
185 ExceptionHandlerData->ReservedVectors = ReservedVectors;
186 ExceptionHandlerData->ExternalInterruptHandler = AllocateZeroPool (sizeof (EFI_CPU_INTERRUPT_HANDLER) * ExceptionHandlerData->IdtEntryCount);
187 InitializeSpinLock (&ExceptionHandlerData->DisplayMessageSpinLock);
188
189 Status = InitializeCpuExceptionHandlersWorker (VectorInfo, ExceptionHandlerData);
190 if (EFI_ERROR (Status)) {
191 FreePool (ReservedVectors);
192 FreePool (ExceptionHandlerData);
193 return Status;
194 }
195
196 SetExceptionHandlerData (ExceptionHandlerData);
197 return EFI_SUCCESS;
198}
199
215EFIAPI
217 IN VOID *Buffer,
218 IN OUT UINTN *BufferSize
219 )
220{
221 if ((Buffer == NULL) && (BufferSize == NULL)) {
222 return EFI_UNSUPPORTED;
223 }
224
225 return ArchSetupExceptionStack (Buffer, BufferSize);
226}
UINT64 UINTN
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID(EFIAPI * EFI_CPU_INTERRUPT_HANDLER)(IN CONST EFI_EXCEPTION_TYPE InterruptType, IN CONST EFI_SYSTEM_CONTEXT SystemContext)
Definition: Cpu.h:52
UINTN ArchGetIdtHandler(IN IA32_IDT_GATE_DESCRIPTOR *IdtEntry)
EFI_STATUS ArchSetupExceptionStack(IN VOID *Buffer, IN OUT UINTN *BufferSize)
EFI_STATUS RegisterCpuInterruptHandlerWorker(IN EFI_EXCEPTION_TYPE InterruptType, IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler, IN EXCEPTION_HANDLER_DATA *ExceptionHandlerData)
EFI_STATUS InitializeCpuExceptionHandlersWorker(IN EFI_VECTOR_HANDOFF_INFO *VectorInfo OPTIONAL, IN OUT EXCEPTION_HANDLER_DATA *ExceptionHandlerData)
VOID ArchUpdateIdtEntry(OUT IA32_IDT_GATE_DESCRIPTOR *IdtEntry, IN UINTN InterruptHandler)
VOID CommonExceptionHandlerWorker(IN EFI_EXCEPTION_TYPE ExceptionType, IN EFI_SYSTEM_CONTEXT SystemContext, IN EXCEPTION_HANDLER_DATA *ExceptionHandlerData)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
INTN EFI_EXCEPTION_TYPE
Definition: DebugSupport.h:35
EFI_STATUS EFIAPI InitializeSeparateExceptionStacks(IN VOID *Buffer, IN OUT UINTN *BufferSize)
EFI_STATUS EFIAPI InitializeCpuExceptionHandlers(IN EFI_VECTOR_HANDOFF_INFO *VectorInfo OPTIONAL)
VOID SetExceptionHandlerData(IN EXCEPTION_HANDLER_DATA *ExceptionHandlerData)
EXCEPTION_HANDLER_DATA * GetExceptionHandlerData(VOID)
EFI_STATUS EFIAPI RegisterCpuInterruptHandler(IN EFI_EXCEPTION_TYPE InterruptType, IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler)
VOID EFIAPI CommonExceptionHandler(IN EFI_EXCEPTION_TYPE ExceptionType, IN EFI_SYSTEM_CONTEXT SystemContext)
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
SPIN_LOCK *EFIAPI InitializeSpinLock(OUT SPIN_LOCK *SpinLock)
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
VOID EFIAPI AsmReadIdtr(OUT IA32_DESCRIPTOR *Idtr)
Definition: X86ReadIdtr.c:24