summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDeepak Gupta <[email protected]>2024-09-16 11:23:55 -0700
committerAnup Patel <[email protected]>2024-09-23 18:58:04 +0530
commitc0804ed49a6ef1d2b757a97baf3f802fd98ae517 (patch)
tree35132ebb2eeee738d4b1539ce8f4ab4fc4b0c4bb /lib
parent6758a756c4185d821611db58b3e839ac70eaba12 (diff)
lib: sbi: add zicfilp/zicfiss and elp cfi state reflect back in status
This patch adds support to check for zicfilp / zicfiss extension. zicfilp record status of hart's ELP state in *status csr. Missing landing pad sets MPELP in mstatus. When SBI is redirecting back to S/VS/HS, SPELP is set in sstatus/vsstatus. Signed-off-by: Deepak Gupta <[email protected]> Reviewed-by: Atish Patra <[email protected]> Reviewed-by: Samuel Holland <[email protected]>
Diffstat (limited to 'lib')
-rw-r--r--lib/sbi/sbi_hart.c2
-rw-r--r--lib/sbi/sbi_trap.c20
2 files changed, 22 insertions, 0 deletions
diff --git a/lib/sbi/sbi_hart.c b/lib/sbi/sbi_hart.c
index f7aed739..73f2c7b1 100644
--- a/lib/sbi/sbi_hart.c
+++ b/lib/sbi/sbi_hart.c
@@ -681,6 +681,8 @@ const struct sbi_hart_ext_data sbi_hart_ext[] = {
__SBI_HART_EXT_DATA(svade, SBI_HART_EXT_SVADE),
__SBI_HART_EXT_DATA(svadu, SBI_HART_EXT_SVADU),
__SBI_HART_EXT_DATA(smnpm, SBI_HART_EXT_SMNPM),
+ __SBI_HART_EXT_DATA(zicfilp, SBI_HART_EXT_ZICFILP),
+ __SBI_HART_EXT_DATA(zicfiss, SBI_HART_EXT_ZICFISS),
};
_Static_assert(SBI_HART_EXT_MAX == array_size(sbi_hart_ext),
diff --git a/lib/sbi/sbi_trap.c b/lib/sbi/sbi_trap.c
index b4f3a176..176e1740 100644
--- a/lib/sbi/sbi_trap.c
+++ b/lib/sbi/sbi_trap.c
@@ -103,6 +103,7 @@ int sbi_trap_redirect(struct sbi_trap_regs *regs,
const struct sbi_trap_info *trap)
{
ulong hstatus, vsstatus, prev_mode;
+ bool elp = false;
#if __riscv_xlen == 32
bool prev_virt = (regs->mstatusH & MSTATUSH_MPV) ? true : false;
#else
@@ -116,6 +117,17 @@ int sbi_trap_redirect(struct sbi_trap_regs *regs,
if (prev_mode != PRV_S && prev_mode != PRV_U)
return SBI_ENOTSUPP;
+ /* If hart support for zicfilp, clear MPELP because redirecting to VS or (H)S */
+ if (sbi_hart_has_extension(sbi_scratch_thishart_ptr(), SBI_HART_EXT_ZICFILP)) {
+#if __riscv_xlen == 32
+ elp = regs->mstatusH & MSTATUSH_MPELP;
+ regs->mstatusH &= ~MSTATUSH_MPELP;
+#else
+ elp = regs->mstatus & MSTATUS_MPELP;
+ regs->mstatus &= ~MSTATUS_MPELP;
+#endif
+ }
+
/* If exceptions came from VS/VU-mode, redirect to VS-mode if
* delegated in hedeleg
*/
@@ -169,6 +181,10 @@ int sbi_trap_redirect(struct sbi_trap_regs *regs,
/* Get VS-mode SSTATUS CSR */
vsstatus = csr_read(CSR_VSSTATUS);
+ /* If elp was set, set it back in vsstatus */
+ if (elp)
+ vsstatus |= MSTATUS_SPELP;
+
/* Set SPP for VS-mode */
vsstatus &= ~SSTATUS_SPP;
if (prev_mode == PRV_S)
@@ -209,6 +225,10 @@ int sbi_trap_redirect(struct sbi_trap_regs *regs,
/* Clear SIE for S-mode */
regs->mstatus &= ~MSTATUS_SIE;
+
+ /* If elp was set, set it back in mstatus */
+ if (elp)
+ regs->mstatus |= MSTATUS_SPELP;
}
return 0;