--- /dev/null
+## @file\r
+# RISC-V CPU Exception Handler Library\r
+#\r
+# Copyright (c) 2022-2023, Ventana Micro Systems Inc. All rights reserved.<BR>\r
+#\r
+# SPDX-License-Identifier: BSD-2-Clause-Patent\r
+#\r
+##\r
+\r
+[Defines]\r
+ INF_VERSION = 0x0001001B\r
+ BASE_NAME = BaseRiscV64CpuExceptionHandlerLib\r
+ MODULE_UNI_FILE = BaseRiscV64CpuExceptionHandlerLib.uni\r
+ FILE_GUID = 6AB0D5FD-E615-45A3-9374-E284FB061FC9\r
+ MODULE_TYPE = BASE\r
+ VERSION_STRING = 1.0\r
+ LIBRARY_CLASS = CpuExceptionHandlerLib\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+# VALID_ARCHITECTURES = RISCV64\r
+#\r
+\r
+[Sources]\r
+ SupervisorTrapHandler.S\r
+ CpuExceptionHandlerLib.c\r
+ CpuExceptionHandlerLib.h\r
+\r
+[Packages]\r
+ MdePkg/MdePkg.dec\r
+ MdeModulePkg/MdeModulePkg.dec\r
+ UefiCpuPkg/UefiCpuPkg.dec\r
+\r
+[LibraryClasses]\r
+ BaseLib\r
+ SerialPortLib\r
+ PrintLib\r
+ SynchronizationLib\r
+ PeCoffGetEntryPointLib\r
+ MemoryAllocationLib\r
+ DebugLib\r
--- /dev/null
+// /** @file\r
+//\r
+// Copyright (c) 2016 - 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>\r
+//\r
+// SPDX-License-Identifier: BSD-2-Clause-Patent\r
+//\r
+// **/\r
+\r
+\r
+#string STR_MODULE_ABSTRACT #language en-US "RISC-V CPU Exception Handler Librarys."\r
+\r
+#string STR_MODULE_DESCRIPTION #language en-US "RISC-V CPU Exception Handler Librarys."\r
+\r
--- /dev/null
+/** @file\r
+ RISC-V Exception Handler library implementation.\r
+\r
+ Copyright (c) 2016 - 2022, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>\r
+\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#include <PiPei.h>\r
+#include <Library/CpuExceptionHandlerLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Register/RiscV64/RiscVEncoding.h>\r
+\r
+#include "CpuExceptionHandlerLib.h"\r
+\r
+STATIC EFI_CPU_INTERRUPT_HANDLER mInterruptHandlers[2];\r
+\r
+/**\r
+ Initializes all CPU exceptions entries and provides the default exception handlers.\r
+\r
+ Caller should try to get an array of interrupt and/or exception vectors that are in use and need to\r
+ persist by EFI_VECTOR_HANDOFF_INFO defined in PI 1.3 specification.\r
+ If caller cannot get reserved vector list or it does not exists, set VectorInfo to NULL.\r
+ If VectorInfo is not NULL, the exception vectors will be initialized per vector attribute accordingly.\r
+\r
+ @param[in] VectorInfo Pointer to reserved vector list.\r
+\r
+ @retval EFI_SUCCESS CPU Exception Entries have been successfully initialized\r
+ with default exception handlers.\r
+ @retval EFI_INVALID_PARAMETER VectorInfo includes the invalid content if VectorInfo is not NULL.\r
+ @retval EFI_UNSUPPORTED This function is not supported.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+InitializeCpuExceptionHandlers (\r
+ IN EFI_VECTOR_HANDOFF_INFO *VectorInfo OPTIONAL\r
+ )\r
+{\r
+ RiscVSetSupervisorStvec ((UINT64)SupervisorModeTrap);\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Registers a function to be called from the processor interrupt handler.\r
+\r
+ This function registers and enables the handler specified by InterruptHandler for a processor\r
+ interrupt or exception type specified by InterruptType. If InterruptHandler is NULL, then the\r
+ handler for the processor interrupt or exception type specified by InterruptType is uninstalled.\r
+ The installed handler is called once for each processor interrupt or exception.\r
+ NOTE: This function should be invoked after InitializeCpuExceptionHandlers() or\r
+ InitializeCpuInterruptHandlers() invoked, otherwise EFI_UNSUPPORTED returned.\r
+\r
+ @param[in] InterruptType Defines which interrupt or exception to hook.\r
+ @param[in] InterruptHandler A pointer to a function of type EFI_CPU_INTERRUPT_HANDLER that is called\r
+ when a processor interrupt occurs. If this parameter is NULL, then the handler\r
+ will be uninstalled.\r
+\r
+ @retval EFI_SUCCESS The handler for the processor interrupt was successfully installed or uninstalled.\r
+ @retval EFI_ALREADY_STARTED InterruptHandler is not NULL, and a handler for InterruptType was\r
+ previously installed.\r
+ @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler for InterruptType was not\r
+ previously installed.\r
+ @retval EFI_UNSUPPORTED The interrupt specified by InterruptType is not supported,\r
+ or this function is not supported.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RegisterCpuInterruptHandler (\r
+ IN EFI_EXCEPTION_TYPE InterruptType,\r
+ IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler\r
+ )\r
+{\r
+ DEBUG ((DEBUG_INFO, "%a: Type:%x Handler: %x\n", __FUNCTION__, InterruptType, InterruptHandler));\r
+ mInterruptHandlers[InterruptType] = InterruptHandler;\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Setup separate stacks for certain exception handlers.\r
+ If the input Buffer and BufferSize are both NULL, use global variable if possible.\r
+\r
+ @param[in] Buffer Point to buffer used to separate exception stack.\r
+ @param[in, out] BufferSize On input, it indicates the byte size of Buffer.\r
+ If the size is not enough, the return status will\r
+ be EFI_BUFFER_TOO_SMALL, and output BufferSize\r
+ will be the size it needs.\r
+\r
+ @retval EFI_SUCCESS The stacks are assigned successfully.\r
+ @retval EFI_UNSUPPORTED This function is not supported.\r
+ @retval EFI_BUFFER_TOO_SMALL This BufferSize is too small.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+InitializeSeparateExceptionStacks (\r
+ IN VOID *Buffer,\r
+ IN OUT UINTN *BufferSize\r
+ )\r
+{\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Supervisor mode trap handler.\r
+\r
+ @param[in] SmodeTrapReg Registers before trap occurred.\r
+\r
+**/\r
+VOID\r
+RiscVSupervisorModeTrapHandler (\r
+ SMODE_TRAP_REGISTERS *SmodeTrapReg\r
+ )\r
+{\r
+ UINTN SCause;\r
+ EFI_SYSTEM_CONTEXT RiscVSystemContext;\r
+\r
+ RiscVSystemContext.SystemContextRiscV64 = (EFI_SYSTEM_CONTEXT_RISCV64 *)SmodeTrapReg;\r
+ //\r
+ // Check scasue register.\r
+ //\r
+ SCause = (UINTN)RiscVGetSupervisorTrapCause ();\r
+ if ((SCause & (1UL << (sizeof (UINTN) * 8- 1))) != 0) {\r
+ //\r
+ // This is interrupt event.\r
+ //\r
+ SCause &= ~(1UL << (sizeof (UINTN) * 8- 1));\r
+ if ((SCause == IRQ_S_TIMER) && (mInterruptHandlers[EXCEPT_RISCV_TIMER_INT] != NULL)) {\r
+ mInterruptHandlers[EXCEPT_RISCV_TIMER_INT](EXCEPT_RISCV_TIMER_INT, RiscVSystemContext);\r
+ }\r
+ }\r
+}\r
--- /dev/null
+/** @file\r
+\r
+ RISC-V Exception Handler library definition file.\r
+\r
+ Copyright (c) 2019-2022, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>\r
+\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#ifndef RISCV_CPU_EXECPTION_HANDLER_LIB_H_\r
+#define RISCV_CPU_EXECPTION_HANDLER_LIB_H_\r
+\r
+#include <Register/RiscV64/RiscVImpl.h>\r
+\r
+/**\r
+ Trap Handler for S-mode\r
+\r
+**/\r
+VOID\r
+SupervisorModeTrap (\r
+ VOID\r
+ );\r
+\r
+//\r
+// Index of SMode trap register\r
+//\r
+#define SMODE_TRAP_REGS_zero 0\r
+#define SMODE_TRAP_REGS_ra 1\r
+#define SMODE_TRAP_REGS_sp 2\r
+#define SMODE_TRAP_REGS_gp 3\r
+#define SMODE_TRAP_REGS_tp 4\r
+#define SMODE_TRAP_REGS_t0 5\r
+#define SMODE_TRAP_REGS_t1 6\r
+#define SMODE_TRAP_REGS_t2 7\r
+#define SMODE_TRAP_REGS_s0 8\r
+#define SMODE_TRAP_REGS_s1 9\r
+#define SMODE_TRAP_REGS_a0 10\r
+#define SMODE_TRAP_REGS_a1 11\r
+#define SMODE_TRAP_REGS_a2 12\r
+#define SMODE_TRAP_REGS_a3 13\r
+#define SMODE_TRAP_REGS_a4 14\r
+#define SMODE_TRAP_REGS_a5 15\r
+#define SMODE_TRAP_REGS_a6 16\r
+#define SMODE_TRAP_REGS_a7 17\r
+#define SMODE_TRAP_REGS_s2 18\r
+#define SMODE_TRAP_REGS_s3 19\r
+#define SMODE_TRAP_REGS_s4 20\r
+#define SMODE_TRAP_REGS_s5 21\r
+#define SMODE_TRAP_REGS_s6 22\r
+#define SMODE_TRAP_REGS_s7 23\r
+#define SMODE_TRAP_REGS_s8 24\r
+#define SMODE_TRAP_REGS_s9 25\r
+#define SMODE_TRAP_REGS_s10 26\r
+#define SMODE_TRAP_REGS_s11 27\r
+#define SMODE_TRAP_REGS_t3 28\r
+#define SMODE_TRAP_REGS_t4 29\r
+#define SMODE_TRAP_REGS_t5 30\r
+#define SMODE_TRAP_REGS_t6 31\r
+#define SMODE_TRAP_REGS_sepc 32\r
+#define SMODE_TRAP_REGS_sstatus 33\r
+#define SMODE_TRAP_REGS_sie 34\r
+#define SMODE_TRAP_REGS_last 35\r
+\r
+#define SMODE_TRAP_REGS_OFFSET(x) ((SMODE_TRAP_REGS_##x) * __SIZEOF_POINTER__)\r
+#define SMODE_TRAP_REGS_SIZE SMODE_TRAP_REGS_OFFSET(last)\r
+\r
+#pragma pack(1)\r
+typedef struct {\r
+ //\r
+ // Below are follow the format of EFI_SYSTEM_CONTEXT\r
+ //\r
+ UINT64 zero;\r
+ UINT64 ra;\r
+ UINT64 sp;\r
+ UINT64 gp;\r
+ UINT64 tp;\r
+ UINT64 t0;\r
+ UINT64 t1;\r
+ UINT64 t2;\r
+ UINT64 s0;\r
+ UINT64 s1;\r
+ UINT64 a0;\r
+ UINT64 a1;\r
+ UINT64 a2;\r
+ UINT64 a3;\r
+ UINT64 a4;\r
+ UINT64 a5;\r
+ UINT64 a6;\r
+ UINT64 a7;\r
+ UINT64 s2;\r
+ UINT64 s3;\r
+ UINT64 s4;\r
+ UINT64 s5;\r
+ UINT64 s6;\r
+ UINT64 s7;\r
+ UINT64 s8;\r
+ UINT64 s9;\r
+ UINT64 s10;\r
+ UINT64 s11;\r
+ UINT64 t3;\r
+ UINT64 t4;\r
+ UINT64 t5;\r
+ UINT64 t6;\r
+ //\r
+ // Below are the additional information to\r
+ // EFI_SYSTEM_CONTEXT, private to supervisor mode trap\r
+ // and not public to EFI environment.\r
+ //\r
+ UINT64 sepc;\r
+ UINT64 sstatus;\r
+ UINT64 sie;\r
+} SMODE_TRAP_REGISTERS;\r
+#pragma pack()\r
+\r
+#endif\r
--- /dev/null
+/** @file\r
+ RISC-V Processor supervisor mode trap handler\r
+\r
+ Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>\r
+\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#include <Base.h>\r
+#include "CpuExceptionHandlerLib.h"\r
+\r
+ .align 3\r
+ .section .entry, "ax", %progbits\r
+ .globl SupervisorModeTrap\r
+SupervisorModeTrap:\r
+ addi sp, sp, -SMODE_TRAP_REGS_SIZE\r
+\r
+ /* Save all general regisers except SP */\r
+ sd t0, SMODE_TRAP_REGS_OFFSET(t0)(sp)\r
+\r
+ csrr t0, CSR_SSTATUS\r
+ and t0, t0, (SSTATUS_SIE | SSTATUS_SPIE)\r
+ sd t0, SMODE_TRAP_REGS_OFFSET(sstatus)(sp)\r
+ csrr t0, CSR_SEPC\r
+ sd t0, SMODE_TRAP_REGS_OFFSET(sepc)(sp)\r
+ csrr t0, CSR_SIE\r
+ sd t0, SMODE_TRAP_REGS_OFFSET(sie)(sp)\r
+ ld t0, SMODE_TRAP_REGS_OFFSET(t0)(sp)\r
+\r
+ sd ra, SMODE_TRAP_REGS_OFFSET(ra)(sp)\r
+ sd gp, SMODE_TRAP_REGS_OFFSET(gp)(sp)\r
+ sd tp, SMODE_TRAP_REGS_OFFSET(tp)(sp)\r
+ sd t1, SMODE_TRAP_REGS_OFFSET(t1)(sp)\r
+ sd t2, SMODE_TRAP_REGS_OFFSET(t2)(sp)\r
+ sd s0, SMODE_TRAP_REGS_OFFSET(s0)(sp)\r
+ sd s1, SMODE_TRAP_REGS_OFFSET(s1)(sp)\r
+ sd a0, SMODE_TRAP_REGS_OFFSET(a0)(sp)\r
+ sd a1, SMODE_TRAP_REGS_OFFSET(a1)(sp)\r
+ sd a2, SMODE_TRAP_REGS_OFFSET(a2)(sp)\r
+ sd a3, SMODE_TRAP_REGS_OFFSET(a3)(sp)\r
+ sd a4, SMODE_TRAP_REGS_OFFSET(a4)(sp)\r
+ sd a5, SMODE_TRAP_REGS_OFFSET(a5)(sp)\r
+ sd a6, SMODE_TRAP_REGS_OFFSET(a6)(sp)\r
+ sd a7, SMODE_TRAP_REGS_OFFSET(a7)(sp)\r
+ sd s2, SMODE_TRAP_REGS_OFFSET(s2)(sp)\r
+ sd s3, SMODE_TRAP_REGS_OFFSET(s3)(sp)\r
+ sd s4, SMODE_TRAP_REGS_OFFSET(s4)(sp)\r
+ sd s5, SMODE_TRAP_REGS_OFFSET(s5)(sp)\r
+ sd s6, SMODE_TRAP_REGS_OFFSET(s6)(sp)\r
+ sd s7, SMODE_TRAP_REGS_OFFSET(s7)(sp)\r
+ sd s8, SMODE_TRAP_REGS_OFFSET(s8)(sp)\r
+ sd s9, SMODE_TRAP_REGS_OFFSET(s9)(sp)\r
+ sd s10, SMODE_TRAP_REGS_OFFSET(s10)(sp)\r
+ sd s11, SMODE_TRAP_REGS_OFFSET(s11)(sp)\r
+ sd t3, SMODE_TRAP_REGS_OFFSET(t3)(sp)\r
+ sd t4, SMODE_TRAP_REGS_OFFSET(t4)(sp)\r
+ sd t5, SMODE_TRAP_REGS_OFFSET(t5)(sp)\r
+ sd t6, SMODE_TRAP_REGS_OFFSET(t6)(sp)\r
+\r
+ /* Call to Supervisor mode trap handler in CpuExceptionHandlerLib.c */\r
+ call RiscVSupervisorModeTrapHandler\r
+\r
+ /* Restore all general regisers except SP */\r
+ ld ra, SMODE_TRAP_REGS_OFFSET(ra)(sp)\r
+ ld gp, SMODE_TRAP_REGS_OFFSET(gp)(sp)\r
+ ld tp, SMODE_TRAP_REGS_OFFSET(tp)(sp)\r
+ ld t2, SMODE_TRAP_REGS_OFFSET(t2)(sp)\r
+ ld s0, SMODE_TRAP_REGS_OFFSET(s0)(sp)\r
+ ld s1, SMODE_TRAP_REGS_OFFSET(s1)(sp)\r
+ ld a0, SMODE_TRAP_REGS_OFFSET(a0)(sp)\r
+ ld a1, SMODE_TRAP_REGS_OFFSET(a1)(sp)\r
+ ld a2, SMODE_TRAP_REGS_OFFSET(a2)(sp)\r
+ ld a3, SMODE_TRAP_REGS_OFFSET(a3)(sp)\r
+ ld a4, SMODE_TRAP_REGS_OFFSET(a4)(sp)\r
+ ld a5, SMODE_TRAP_REGS_OFFSET(a5)(sp)\r
+ ld a6, SMODE_TRAP_REGS_OFFSET(a6)(sp)\r
+ ld a7, SMODE_TRAP_REGS_OFFSET(a7)(sp)\r
+ ld s2, SMODE_TRAP_REGS_OFFSET(s2)(sp)\r
+ ld s3, SMODE_TRAP_REGS_OFFSET(s3)(sp)\r
+ ld s4, SMODE_TRAP_REGS_OFFSET(s4)(sp)\r
+ ld s5, SMODE_TRAP_REGS_OFFSET(s5)(sp)\r
+ ld s6, SMODE_TRAP_REGS_OFFSET(s6)(sp)\r
+ ld s7, SMODE_TRAP_REGS_OFFSET(s7)(sp)\r
+ ld s8, SMODE_TRAP_REGS_OFFSET(s8)(sp)\r
+ ld s9, SMODE_TRAP_REGS_OFFSET(s9)(sp)\r
+ ld s10, SMODE_TRAP_REGS_OFFSET(s10)(sp)\r
+ ld s11, SMODE_TRAP_REGS_OFFSET(s11)(sp)\r
+ ld t3, SMODE_TRAP_REGS_OFFSET(t3)(sp)\r
+ ld t4, SMODE_TRAP_REGS_OFFSET(t4)(sp)\r
+ ld t5, SMODE_TRAP_REGS_OFFSET(t5)(sp)\r
+ ld t6, SMODE_TRAP_REGS_OFFSET(t6)(sp)\r
+\r
+ ld t0, SMODE_TRAP_REGS_OFFSET(sepc)(sp)\r
+ csrw CSR_SEPC, t0\r
+ ld t0, SMODE_TRAP_REGS_OFFSET(sie)(sp)\r
+ csrw CSR_SIE, t0\r
+ csrr t0, CSR_SSTATUS\r
+ ld t1, SMODE_TRAP_REGS_OFFSET(sstatus)(sp)\r
+ or t0, t0, t1\r
+ csrw CSR_SSTATUS, t0\r
+ ld t1, SMODE_TRAP_REGS_OFFSET(t1)(sp)\r
+ ld t0, SMODE_TRAP_REGS_OFFSET(t0)(sp)\r
+ addi sp, sp, SMODE_TRAP_REGS_SIZE\r
+ sret\r
[Components.X64]\r
UefiCpuPkg/Library/CpuExceptionHandlerLib/UnitTest/DxeCpuExceptionHandlerLibUnitTest.inf\r
\r
+[Components.RISCV64]\r
+ UefiCpuPkg/Library/BaseRiscV64CpuExceptionHandlerLib/BaseRiscV64CpuExceptionHandlerLib.inf\r
+\r
[BuildOptions]\r
*_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES\r