]> git.proxmox.com Git - mirror_edk2.git/blob - UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h
UefiCpuPkg/CpuExceptionHandlerLib: Add stack switch support
[mirror_edk2.git] / UefiCpuPkg / Library / CpuExceptionHandlerLib / CpuExceptionCommon.h
1 /** @file
2 Common header file for CPU Exception Handler Library.
3
4 Copyright (c) 2012 - 2017, 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 #ifndef _CPU_EXCEPTION_COMMON_H_
16 #define _CPU_EXCEPTION_COMMON_H_
17
18 #include <Ppi/VectorHandoffInfo.h>
19 #include <Protocol/Cpu.h>
20 #include <Library/BaseLib.h>
21 #include <Library/SerialPortLib.h>
22 #include <Library/PrintLib.h>
23 #include <Library/LocalApicLib.h>
24 #include <Library/PeCoffGetEntryPointLib.h>
25 #include <Library/BaseMemoryLib.h>
26 #include <Library/SynchronizationLib.h>
27 #include <Library/CpuExceptionHandlerLib.h>
28
29 #define CPU_EXCEPTION_NUM 32
30 #define CPU_INTERRUPT_NUM 256
31 #define HOOKAFTER_STUB_SIZE 16
32
33 //
34 // Exception Error Code of Page-Fault Exception
35 //
36 #define IA32_PF_EC_P BIT0
37 #define IA32_PF_EC_WR BIT1
38 #define IA32_PF_EC_US BIT2
39 #define IA32_PF_EC_RSVD BIT3
40 #define IA32_PF_EC_ID BIT4
41 #define IA32_PF_EC_PK BIT5
42 #define IA32_PF_EC_SGX BIT15
43
44 #include "ArchInterruptDefs.h"
45
46 #define CPU_EXCEPTION_HANDLER_LIB_HOB_GUID \
47 { \
48 0xb21d9148, 0x9211, 0x4d8f, { 0xad, 0xd3, 0x66, 0xb1, 0x89, 0xc9, 0x2c, 0x83 } \
49 }
50
51 #define CPU_STACK_SWITCH_EXCEPTION_NUMBER \
52 FixedPcdGetSize (PcdCpuStackSwitchExceptionList)
53
54 #define CPU_STACK_SWITCH_EXCEPTION_LIST \
55 FixedPcdGetPtr (PcdCpuStackSwitchExceptionList)
56
57 #define CPU_KNOWN_GOOD_STACK_SIZE \
58 FixedPcdGet32 (PcdCpuKnownGoodStackSize)
59
60 #define CPU_TSS_GDT_SIZE (SIZE_2KB + CPU_TSS_DESC_SIZE + CPU_TSS_SIZE)
61
62 //
63 // Record exception handler information
64 //
65 typedef struct {
66 UINTN ExceptionStart;
67 UINTN ExceptionStubHeaderSize;
68 UINTN HookAfterStubHeaderStart;
69 } EXCEPTION_HANDLER_TEMPLATE_MAP;
70
71 typedef struct {
72 UINTN IdtEntryCount;
73 SPIN_LOCK DisplayMessageSpinLock;
74 RESERVED_VECTORS_DATA *ReservedVectors;
75 EFI_CPU_INTERRUPT_HANDLER *ExternalInterruptHandler;
76 } EXCEPTION_HANDLER_DATA;
77
78 extern CONST UINT32 mErrorCodeFlag;
79 extern CONST UINTN mDoFarReturnFlag;
80
81 /**
82 Return address map of exception handler template so that C code can generate
83 exception tables.
84
85 @param AddressMap Pointer to a buffer where the address map is returned.
86 **/
87 VOID
88 EFIAPI
89 AsmGetTemplateAddressMap (
90 OUT EXCEPTION_HANDLER_TEMPLATE_MAP *AddressMap
91 );
92
93 /**
94 Return address map of exception handler template so that C code can generate
95 exception tables.
96
97 @param IdtEntry Pointer to IDT entry to be updated.
98 @param InterruptHandler IDT handler value.
99
100 **/
101 VOID
102 ArchUpdateIdtEntry (
103 IN IA32_IDT_GATE_DESCRIPTOR *IdtEntry,
104 IN UINTN InterruptHandler
105 );
106
107 /**
108 Read IDT handler value from IDT entry.
109
110 @param IdtEntry Pointer to IDT entry to be read.
111
112 **/
113 UINTN
114 ArchGetIdtHandler (
115 IN IA32_IDT_GATE_DESCRIPTOR *IdtEntry
116 );
117
118 /**
119 Prints a message to the serial port.
120
121 @param Format Format string for the message to print.
122 @param ... Variable argument list whose contents are accessed
123 based on the format string specified by Format.
124
125 **/
126 VOID
127 EFIAPI
128 InternalPrintMessage (
129 IN CONST CHAR8 *Format,
130 ...
131 );
132
133 /**
134 Find and display image base address and return image base and its entry point.
135
136 @param CurrentEip Current instruction pointer.
137
138 **/
139 VOID
140 DumpModuleImageInfo (
141 IN UINTN CurrentEip
142 );
143
144 /**
145 Display CPU information.
146
147 @param ExceptionType Exception type.
148 @param SystemContext Pointer to EFI_SYSTEM_CONTEXT.
149 **/
150 VOID
151 DumpImageAndCpuContent (
152 IN EFI_EXCEPTION_TYPE ExceptionType,
153 IN EFI_SYSTEM_CONTEXT SystemContext
154 );
155
156 /**
157 Internal worker function to initialize exception handler.
158
159 @param[in] VectorInfo Pointer to reserved vector list.
160 @param[in, out] ExceptionHandlerData Pointer to exception handler data.
161
162 @retval EFI_SUCCESS CPU Exception Entries have been successfully initialized
163 with default exception handlers.
164 @retval EFI_INVALID_PARAMETER VectorInfo includes the invalid content if VectorInfo is not NULL.
165 @retval EFI_UNSUPPORTED This function is not supported.
166
167 **/
168 EFI_STATUS
169 InitializeCpuExceptionHandlersWorker (
170 IN EFI_VECTOR_HANDOFF_INFO *VectorInfo OPTIONAL,
171 IN OUT EXCEPTION_HANDLER_DATA *ExceptionHandlerData
172 );
173
174 /**
175 Registers a function to be called from the processor interrupt handler.
176
177 @param[in] InterruptType Defines which interrupt or exception to hook.
178 @param[in] InterruptHandler A pointer to a function of type EFI_CPU_INTERRUPT_HANDLER that is called
179 when a processor interrupt occurs. If this parameter is NULL, then the handler
180 will be uninstalled
181 @param[in] ExceptionHandlerData Pointer to exception handler data.
182
183 @retval EFI_SUCCESS The handler for the processor interrupt was successfully installed or uninstalled.
184 @retval EFI_ALREADY_STARTED InterruptHandler is not NULL, and a handler for InterruptType was
185 previously installed.
186 @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler for InterruptType was not
187 previously installed.
188 @retval EFI_UNSUPPORTED The interrupt specified by InterruptType is not supported,
189 or this function is not supported.
190 **/
191 EFI_STATUS
192 RegisterCpuInterruptHandlerWorker (
193 IN EFI_EXCEPTION_TYPE InterruptType,
194 IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler,
195 IN EXCEPTION_HANDLER_DATA *ExceptionHandlerData
196 );
197
198 /**
199 Internal worker function to update IDT entries accordling to vector attributes.
200
201 @param[in] IdtTable Pointer to IDT table.
202 @param[in] TemplateMap Pointer to a buffer where the address map is
203 returned.
204 @param[in] ExceptionHandlerData Pointer to exception handler data.
205
206 **/
207 VOID
208 UpdateIdtTable (
209 IN IA32_IDT_GATE_DESCRIPTOR *IdtTable,
210 IN EXCEPTION_HANDLER_TEMPLATE_MAP *TemplateMap,
211 IN EXCEPTION_HANDLER_DATA *ExceptionHandlerData
212 );
213
214 /**
215 Save CPU exception context when handling EFI_VECTOR_HANDOFF_HOOK_AFTER case.
216
217 @param[in] ExceptionType Exception type.
218 @param[in] SystemContext Pointer to EFI_SYSTEM_CONTEXT.
219 @param[in] ExceptionHandlerData Pointer to exception handler data.
220 **/
221 VOID
222 ArchSaveExceptionContext (
223 IN UINTN ExceptionType,
224 IN EFI_SYSTEM_CONTEXT SystemContext,
225 IN EXCEPTION_HANDLER_DATA *ExceptionHandlerData
226 );
227
228 /**
229 Restore CPU exception context when handling EFI_VECTOR_HANDOFF_HOOK_AFTER case.
230
231 @param[in] ExceptionType Exception type.
232 @param[in] SystemContext Pointer to EFI_SYSTEM_CONTEXT.
233 @param[in] ExceptionHandlerData Pointer to exception handler data.
234 **/
235 VOID
236 ArchRestoreExceptionContext (
237 IN UINTN ExceptionType,
238 IN EFI_SYSTEM_CONTEXT SystemContext,
239 IN EXCEPTION_HANDLER_DATA *ExceptionHandlerData
240 );
241
242 /**
243 Fix up the vector number and function address in the vector code.
244
245 @param[in] NewVectorAddr New vector handler address.
246 @param[in] VectorNum Index of vector.
247 @param[in] OldVectorAddr Old vector handler address.
248
249 **/
250 VOID
251 EFIAPI
252 AsmVectorNumFixup (
253 IN VOID *NewVectorAddr,
254 IN UINT8 VectorNum,
255 IN VOID *OldVectorAddr
256 );
257
258 /**
259 Read and save reserved vector information
260
261 @param[in] VectorInfo Pointer to reserved vector list.
262 @param[out] ReservedVector Pointer to reserved vector data buffer.
263 @param[in] VectorCount Vector number to be updated.
264
265 @return EFI_SUCCESS Read and save vector info successfully.
266 @retval EFI_INVALID_PARAMETER VectorInfo includes the invalid content if VectorInfo is not NULL.
267
268 **/
269 EFI_STATUS
270 ReadAndVerifyVectorInfo (
271 IN EFI_VECTOR_HANDOFF_INFO *VectorInfo,
272 OUT RESERVED_VECTORS_DATA *ReservedVector,
273 IN UINTN VectorCount
274 );
275
276 /**
277 Get ASCII format string exception name by exception type.
278
279 @param ExceptionType Exception type.
280
281 @return ASCII format string exception name.
282 **/
283 CONST CHAR8 *
284 GetExceptionNameStr (
285 IN EFI_EXCEPTION_TYPE ExceptionType
286 );
287
288 /**
289 Internal worker function for common exception handler.
290
291 @param ExceptionType Exception type.
292 @param SystemContext Pointer to EFI_SYSTEM_CONTEXT.
293 @param ExceptionHandlerData Pointer to exception handler data.
294 **/
295 VOID
296 CommonExceptionHandlerWorker (
297 IN EFI_EXCEPTION_TYPE ExceptionType,
298 IN EFI_SYSTEM_CONTEXT SystemContext,
299 IN EXCEPTION_HANDLER_DATA *ExceptionHandlerData
300 );
301
302 /**
303 Setup separate stack for specific exceptions.
304
305 @param[in] StackSwitchData Pointer to data required for setuping up
306 stack switch.
307
308 @retval EFI_SUCCESS The exceptions have been successfully
309 initialized with new stack.
310 @retval EFI_INVALID_PARAMETER StackSwitchData contains invalid content.
311 **/
312 EFI_STATUS
313 ArchSetupExcpetionStack (
314 IN CPU_EXCEPTION_INIT_DATA *StackSwitchData
315 );
316
317 /**
318 Return address map of exception handler template so that C code can generate
319 exception tables. The template is only for exceptions using task gate instead
320 of interrupt gate.
321
322 @param AddressMap Pointer to a buffer where the address map is returned.
323 **/
324 VOID
325 EFIAPI
326 AsmGetTssTemplateMap (
327 OUT EXCEPTION_HANDLER_TEMPLATE_MAP *AddressMap
328 );
329
330 #endif
331