Files
system76-edk2/UefiCpuPkg/Library/BaseRiscV64CpuExceptionHandlerLib/SupervisorTrapHandler.S
Andrei Warkentin 69da506c92 UefiCpuPkg: BaseRiscV64CpuExceptionHandlerLib: clean up
RegisterCpuInterruptHandler did not allow setting
exception handlers for anything beyond the timer IRQ.
Beyond that, it didn't meet the spec around handling
of inputs.

RiscVSupervisorModeTrapHandler now will invoke
set handlers for both exceptions and interrupts.
Two arrays of handlers are maintained - one for exceptions
and one for interrupts.

For unhandled traps, RiscVSupervisorModeTrapHandler dumps
state using the now implemented DumpCpuContext.

For EFI_SYSTEM_CONTEXT_RISCV64, extend this with the trapped
PC address (SEPC), just like on AArch64 (ELR). This is
necessary for X86EmulatorPkg to work as it allows a trap
handler to return execution to a different place. Add
SSTATUS/STVAL as well, at least for debugging purposes. There
is no value in hiding this.

Fix nested exception handling. Handler code should not
be saving SIE (the value is saved in SSTATUS.SPIE) or
directly restored (that's done by SRET). Save and
restore the entire SSTATUS and STVAL, too.

Cc: Daniel Schaefer <git@danielschaefer.me>
Reviewed-by: Sunil V L <sunilvl@ventanamicro.com>
Signed-off-by: Andrei Warkentin <andrei.warkentin@intel.com>
2023-03-08 18:10:34 +00:00

105 lines
3.8 KiB
ArmAsm

/** @file
RISC-V Processor supervisor mode trap handler
Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <Base.h>
#include "CpuExceptionHandlerLib.h"
.align 3
.section .entry, "ax", %progbits
.globl SupervisorModeTrap
SupervisorModeTrap:
addi sp, sp, -SMODE_TRAP_REGS_SIZE
/* Save all general regisers except SP */
sd t0, SMODE_TRAP_REGS_OFFSET(t0)(sp)
csrr t0, CSR_SSTATUS
sd t0, SMODE_TRAP_REGS_OFFSET(sstatus)(sp)
csrr t0, CSR_SEPC
sd t0, SMODE_TRAP_REGS_OFFSET(sepc)(sp)
csrr t0, CSR_STVAL
sd t0, SMODE_TRAP_REGS_OFFSET(stval)(sp)
ld t0, SMODE_TRAP_REGS_OFFSET(t0)(sp)
sd zero, SMODE_TRAP_REGS_OFFSET(zero)(sp)
sd ra, SMODE_TRAP_REGS_OFFSET(ra)(sp)
sd gp, SMODE_TRAP_REGS_OFFSET(gp)(sp)
sd tp, SMODE_TRAP_REGS_OFFSET(tp)(sp)
sd t1, SMODE_TRAP_REGS_OFFSET(t1)(sp)
sd t2, SMODE_TRAP_REGS_OFFSET(t2)(sp)
sd s0, SMODE_TRAP_REGS_OFFSET(s0)(sp)
sd s1, SMODE_TRAP_REGS_OFFSET(s1)(sp)
sd a0, SMODE_TRAP_REGS_OFFSET(a0)(sp)
sd a1, SMODE_TRAP_REGS_OFFSET(a1)(sp)
sd a2, SMODE_TRAP_REGS_OFFSET(a2)(sp)
sd a3, SMODE_TRAP_REGS_OFFSET(a3)(sp)
sd a4, SMODE_TRAP_REGS_OFFSET(a4)(sp)
sd a5, SMODE_TRAP_REGS_OFFSET(a5)(sp)
sd a6, SMODE_TRAP_REGS_OFFSET(a6)(sp)
sd a7, SMODE_TRAP_REGS_OFFSET(a7)(sp)
sd s2, SMODE_TRAP_REGS_OFFSET(s2)(sp)
sd s3, SMODE_TRAP_REGS_OFFSET(s3)(sp)
sd s4, SMODE_TRAP_REGS_OFFSET(s4)(sp)
sd s5, SMODE_TRAP_REGS_OFFSET(s5)(sp)
sd s6, SMODE_TRAP_REGS_OFFSET(s6)(sp)
sd s7, SMODE_TRAP_REGS_OFFSET(s7)(sp)
sd s8, SMODE_TRAP_REGS_OFFSET(s8)(sp)
sd s9, SMODE_TRAP_REGS_OFFSET(s9)(sp)
sd s10, SMODE_TRAP_REGS_OFFSET(s10)(sp)
sd s11, SMODE_TRAP_REGS_OFFSET(s11)(sp)
sd t3, SMODE_TRAP_REGS_OFFSET(t3)(sp)
sd t4, SMODE_TRAP_REGS_OFFSET(t4)(sp)
sd t5, SMODE_TRAP_REGS_OFFSET(t5)(sp)
sd t6, SMODE_TRAP_REGS_OFFSET(t6)(sp)
/* Call to Supervisor mode trap handler in CpuExceptionHandlerLib.c */
mv a0, sp
call RiscVSupervisorModeTrapHandler
/* Restore all general regisers except SP */
ld ra, SMODE_TRAP_REGS_OFFSET(ra)(sp)
ld gp, SMODE_TRAP_REGS_OFFSET(gp)(sp)
ld tp, SMODE_TRAP_REGS_OFFSET(tp)(sp)
ld t2, SMODE_TRAP_REGS_OFFSET(t2)(sp)
ld t1, SMODE_TRAP_REGS_OFFSET(t1)(sp)
ld s0, SMODE_TRAP_REGS_OFFSET(s0)(sp)
ld s1, SMODE_TRAP_REGS_OFFSET(s1)(sp)
ld a0, SMODE_TRAP_REGS_OFFSET(a0)(sp)
ld a1, SMODE_TRAP_REGS_OFFSET(a1)(sp)
ld a2, SMODE_TRAP_REGS_OFFSET(a2)(sp)
ld a3, SMODE_TRAP_REGS_OFFSET(a3)(sp)
ld a4, SMODE_TRAP_REGS_OFFSET(a4)(sp)
ld a5, SMODE_TRAP_REGS_OFFSET(a5)(sp)
ld a6, SMODE_TRAP_REGS_OFFSET(a6)(sp)
ld a7, SMODE_TRAP_REGS_OFFSET(a7)(sp)
ld s2, SMODE_TRAP_REGS_OFFSET(s2)(sp)
ld s3, SMODE_TRAP_REGS_OFFSET(s3)(sp)
ld s4, SMODE_TRAP_REGS_OFFSET(s4)(sp)
ld s5, SMODE_TRAP_REGS_OFFSET(s5)(sp)
ld s6, SMODE_TRAP_REGS_OFFSET(s6)(sp)
ld s7, SMODE_TRAP_REGS_OFFSET(s7)(sp)
ld s8, SMODE_TRAP_REGS_OFFSET(s8)(sp)
ld s9, SMODE_TRAP_REGS_OFFSET(s9)(sp)
ld s10, SMODE_TRAP_REGS_OFFSET(s10)(sp)
ld s11, SMODE_TRAP_REGS_OFFSET(s11)(sp)
ld t3, SMODE_TRAP_REGS_OFFSET(t3)(sp)
ld t4, SMODE_TRAP_REGS_OFFSET(t4)(sp)
ld t5, SMODE_TRAP_REGS_OFFSET(t5)(sp)
ld t6, SMODE_TRAP_REGS_OFFSET(t6)(sp)
ld t0, SMODE_TRAP_REGS_OFFSET(sepc)(sp)
csrw CSR_SEPC, t0
ld t0, SMODE_TRAP_REGS_OFFSET(sstatus)(sp)
csrw CSR_SSTATUS, t0
ld t0, SMODE_TRAP_REGS_OFFSET(stval)(sp)
csrw CSR_STVAL, t0
ld t0, SMODE_TRAP_REGS_OFFSET(t0)(sp)
addi sp, sp, SMODE_TRAP_REGS_SIZE
sret