TianoCore EDK2 master
Loading...
Searching...
No Matches
CpuExceptionHandlerLib.c
Go to the documentation of this file.
1
10#include <PiPei.h>
12#include <Library/DebugLib.h>
13#include <Library/BaseLib.h>
15#include <Library/PrintLib.h>
18
19//
20// Define the maximum message length
21//
22#define MAX_DEBUG_MESSAGE_LENGTH 0x100
23
24STATIC EFI_CPU_INTERRUPT_HANDLER mExceptionHandlers[EXCEPT_RISCV_MAX_EXCEPTIONS + 1];
25STATIC EFI_CPU_INTERRUPT_HANDLER mIrqHandlers[EXCEPT_RISCV_MAX_IRQS + 1];
26
27STATIC CONST CHAR8 mExceptionOrIrqUnknown[] = "Unknown";
28STATIC CONST CHAR8 *mExceptionNameStr[EXCEPT_RISCV_MAX_EXCEPTIONS + 1] = {
29 "EXCEPT_RISCV_INST_MISALIGNED",
30 "EXCEPT_RISCV_INST_ACCESS_FAULT",
31 "EXCEPT_RISCV_ILLEGAL_INST",
32 "EXCEPT_RISCV_BREAKPOINT",
33 "EXCEPT_RISCV_LOAD_ADDRESS_MISALIGNED",
34 "EXCEPT_RISCV_LOAD_ACCESS_FAULT",
35 "EXCEPT_RISCV_STORE_AMO_ADDRESS_MISALIGNED",
36 "EXCEPT_RISCV_STORE_AMO_ACCESS_FAULT",
37 "EXCEPT_RISCV_ENV_CALL_FROM_UMODE",
38 "EXCEPT_RISCV_ENV_CALL_FROM_SMODE",
39 "EXCEPT_RISCV_ENV_CALL_FROM_VS_MODE",
40 "EXCEPT_RISCV_ENV_CALL_FROM_MMODE",
41 "EXCEPT_RISCV_INST_ACCESS_PAGE_FAULT",
42 "EXCEPT_RISCV_LOAD_ACCESS_PAGE_FAULT",
43 "EXCEPT_RISCV_14",
44 "EXCEPT_RISCV_STORE_ACCESS_PAGE_FAULT",
45 "EXCEPT_RISCV_16",
46 "EXCEPT_RISCV_17",
47 "EXCEPT_RISCV_18",
48 "EXCEPT_RISCV_19",
49 "EXCEPT_RISCV_INST_GUEST_PAGE_FAULT",
50 "EXCEPT_RISCV_LOAD_GUEST_PAGE_FAULT",
51 "EXCEPT_RISCV_VIRTUAL_INSTRUCTION",
52 "EXCEPT_RISCV_STORE_GUEST_PAGE_FAULT"
53};
54
55STATIC CONST CHAR8 *mIrqNameStr[EXCEPT_RISCV_MAX_IRQS + 1] = {
56 "EXCEPT_RISCV_IRQ_0",
57 "EXCEPT_RISCV_IRQ_SOFT_FROM_SMODE",
58 "EXCEPT_RISCV_IRQ_SOFT_FROM_VSMODE",
59 "EXCEPT_RISCV_IRQ_SOFT_FROM_MMODE",
60 "EXCEPT_RISCV_IRQ_4",
61 "EXCEPT_RISCV_IRQ_TIMER_FROM_SMODE",
62};
63
73VOID
74EFIAPI
76 IN CONST CHAR8 *Format,
77 ...
78 )
79{
80 CHAR8 Buffer[MAX_DEBUG_MESSAGE_LENGTH];
81 VA_LIST Marker;
82
83 //
84 // Convert the message to an ASCII String
85 //
86 VA_START (Marker, Format);
87 AsciiVSPrint (Buffer, sizeof (Buffer), Format, Marker);
88 VA_END (Marker);
89
90 //
91 // Send the print string to a Serial Port
92 //
93 SerialPortWrite ((UINT8 *)Buffer, AsciiStrLen (Buffer));
94}
95
103STATIC
104CONST CHAR8 *
106 IN EFI_EXCEPTION_TYPE ExceptionType
107 )
108{
109 if (EXCEPT_RISCV_IS_IRQ (ExceptionType)) {
110 if (EXCEPT_RISCV_IRQ_INDEX (ExceptionType) > EXCEPT_RISCV_MAX_IRQS) {
111 return mExceptionOrIrqUnknown;
112 }
113
114 return mIrqNameStr[EXCEPT_RISCV_IRQ_INDEX (ExceptionType)];
115 }
116
117 if (ExceptionType > EXCEPT_RISCV_MAX_EXCEPTIONS) {
118 return mExceptionOrIrqUnknown;
119 }
120
121 return mExceptionNameStr[ExceptionType];
122}
123
131VOID
132EFIAPI
134 IN EFI_EXCEPTION_TYPE ExceptionType,
135 IN EFI_SYSTEM_CONTEXT SystemContext
136 )
137{
138 UINTN Printed;
140
141 Printed = 0;
142 Regs = (SMODE_TRAP_REGISTERS *)SystemContext.SystemContextRiscV64;
143
145 "!!!! RISCV64 Exception Type - %016x(%a) !!!!\n",
146 ExceptionType,
147 GetExceptionNameStr (ExceptionType)
148 );
149
151
152 #define REGS() \
153 REG (t0); REG (t1); REG (t2); REG (t3); REG (t4); REG (t5); REG (t6); \
154 REG (s0); REG (s1); REG (s2); REG (s3); REG (s4); REG (s5); REG (s6); \
155 REG (s7); REG (s8); REG (s9); REG (s10); REG (s11); \
156 REG (a0); REG (a1); REG (a2); REG (a3); REG (a4); REG (a5); REG (a6); \
157 REG (a7); \
158 REG (zero); REG (ra); REG (sp); REG (gp); REG (tp); \
159 REG (sepc); REG (sstatus); REG (stval);
160
161 #define REG(x) do { \
162 InternalPrintMessage ("%7a = 0x%017lx%c", #x, Regs->x, \
163 (++Printed % 2) ? L'\t' : L'\n'); \
164 } while (0);
165
166 REGS ();
167 if (Printed % 2 != 0) {
169 }
170
171 #undef REG
172 #undef REGS
173
175}
176
194EFIAPI
196 IN EFI_VECTOR_HANDOFF_INFO *VectorInfo OPTIONAL
197 )
198{
199 RiscVSetSupervisorStvec ((UINT64)SupervisorModeTrap);
200 return EFI_SUCCESS;
201}
202
227EFIAPI
229 IN EFI_EXCEPTION_TYPE ExceptionType,
230 IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
231 )
232{
233 DEBUG ((DEBUG_INFO, "%a: Type:%x Handler: %x\n", __func__, ExceptionType, InterruptHandler));
234 if (EXCEPT_RISCV_IS_IRQ (ExceptionType)) {
235 if (EXCEPT_RISCV_IRQ_INDEX (ExceptionType) > EXCEPT_RISCV_MAX_IRQS) {
236 return EFI_UNSUPPORTED;
237 }
238
239 if (mIrqHandlers[EXCEPT_RISCV_IRQ_INDEX (ExceptionType)] != NULL) {
240 return EFI_ALREADY_STARTED;
241 } else if (InterruptHandler == NULL) {
242 return EFI_INVALID_PARAMETER;
243 }
244
245 mIrqHandlers[EXCEPT_RISCV_IRQ_INDEX (ExceptionType)] = InterruptHandler;
246 } else {
247 if (ExceptionType > EXCEPT_RISCV_MAX_EXCEPTIONS) {
248 return EFI_UNSUPPORTED;
249 }
250
251 if (mExceptionHandlers[ExceptionType] != NULL) {
252 return EFI_ALREADY_STARTED;
253 } else if (InterruptHandler == NULL) {
254 return EFI_INVALID_PARAMETER;
255 }
256
257 mExceptionHandlers[ExceptionType] = InterruptHandler;
258 }
259
260 return EFI_SUCCESS;
261}
262
278EFIAPI
280 IN VOID *Buffer,
281 IN OUT UINTN *BufferSize
282 )
283{
284 return EFI_SUCCESS;
285}
286
293VOID
295 SMODE_TRAP_REGISTERS *SmodeTrapReg
296 )
297{
298 EFI_EXCEPTION_TYPE ExceptionType;
299 EFI_SYSTEM_CONTEXT RiscVSystemContext;
300 UINTN IrqIndex;
301
302 RiscVSystemContext.SystemContextRiscV64 = (EFI_SYSTEM_CONTEXT_RISCV64 *)SmodeTrapReg;
303 ExceptionType = (UINTN)RiscVGetSupervisorTrapCause ();
304
305 if (EXCEPT_RISCV_IS_IRQ (ExceptionType)) {
306 IrqIndex = EXCEPT_RISCV_IRQ_INDEX (ExceptionType);
307
308 if ((IrqIndex <= EXCEPT_RISCV_MAX_IRQS) &&
309 (mIrqHandlers[IrqIndex] != NULL))
310 {
311 mIrqHandlers[IrqIndex](ExceptionType, RiscVSystemContext);
312 return;
313 }
314 } else {
315 if ((ExceptionType <= EXCEPT_RISCV_MAX_EXCEPTIONS) &&
316 (mExceptionHandlers[ExceptionType] != 0))
317 {
318 mExceptionHandlers[ExceptionType](ExceptionType, RiscVSystemContext);
319 return;
320 }
321 }
322
323 DumpCpuContext (ExceptionType, RiscVSystemContext);
324 CpuDeadLoop ();
325}
UINT64 UINTN
UINTN EFIAPI SerialPortWrite(IN UINT8 *Buffer, IN UINTN NumberOfBytes)
Definition: SerialPortLib.c:52
UINTN EFIAPI AsciiStrLen(IN CONST CHAR8 *String)
Definition: String.c:641
VOID EFIAPI CpuDeadLoop(VOID)
Definition: CpuDeadLoop.c:25
VOID(EFIAPI * EFI_CPU_INTERRUPT_HANDLER)(IN CONST EFI_EXCEPTION_TYPE InterruptType, IN CONST EFI_SYSTEM_CONTEXT SystemContext)
Definition: Cpu.h:52
EFI_STATUS EFIAPI InitializeSeparateExceptionStacks(IN VOID *Buffer, IN OUT UINTN *BufferSize)
EFI_STATUS EFIAPI InitializeCpuExceptionHandlers(IN EFI_VECTOR_HANDOFF_INFO *VectorInfo OPTIONAL)
STATIC CONST CHAR8 * GetExceptionNameStr(IN EFI_EXCEPTION_TYPE ExceptionType)
VOID EFIAPI DumpCpuContext(IN EFI_EXCEPTION_TYPE ExceptionType, IN EFI_SYSTEM_CONTEXT SystemContext)
EFI_STATUS EFIAPI RegisterCpuInterruptHandler(IN EFI_EXCEPTION_TYPE ExceptionType, IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler)
STATIC VOID EFIAPI InternalPrintMessage(IN CONST CHAR8 *Format,...)
VOID RiscVSupervisorModeTrapHandler(SMODE_TRAP_REGISTERS *SmodeTrapReg)
UINTN EFIAPI AsciiVSPrint(OUT CHAR8 *StartOfBuffer, IN UINTN BufferSize, IN CONST CHAR8 *FormatString, IN VA_LIST Marker)
Definition: PrintLib.c:702
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define STATIC
Definition: Base.h:264
#define VA_START(Marker, Parameter)
Definition: Base.h:661
CHAR8 * VA_LIST
Definition: Base.h:643
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define VA_END(Marker)
Definition: Base.h:691
#define DEBUG_CODE_BEGIN()
Definition: DebugLib.h:564
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define DEBUG_CODE_END()
Definition: DebugLib.h:578
INTN EFI_EXCEPTION_TYPE
Definition: DebugSupport.h:35
#define EXCEPT_RISCV_IS_IRQ(x)
Definition: DebugSupport.h:635
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
VOID SupervisorModeTrap(VOID)