summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorClément Léger <[email protected]>2025-03-25 11:26:14 +0100
committerAnup Patel <[email protected]>2025-03-27 18:16:44 +0530
commit3ac49712e3bcfd8d64cd17511e27b7836821e41c (patch)
tree24692dfb03dde6cf11067c9058fa99402ab1373f /lib
parentb4464b22e4d3780ad73318af6091cea1d72404d1 (diff)
lib: sbi: sse: Add support for SSTATUS.SDT
Similarly to what is done for SPELP, handle SSTATUS.SDT upon event injection. In order to mimick an interrupt, set SDT to 1 for injection and save its previous value in interrupted_flags[5:5]. Restore it upon completion. Signed-off-by: Clément Léger <[email protected]> Reviewed-by: Andrew Jones <[email protected]>
Diffstat (limited to 'lib')
-rw-r--r--lib/sbi/sbi_sse.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/lib/sbi/sbi_sse.c b/lib/sbi/sbi_sse.c
index ce4c31e0..986b7701 100644
--- a/lib/sbi/sbi_sse.c
+++ b/lib/sbi/sbi_sse.c
@@ -431,7 +431,8 @@ static int sse_event_set_attr_check(struct sbi_sse_event *e, uint32_t attr_id,
SBI_SSE_ATTR_INTERRUPTED_FLAGS_SSTATUS_SPIE |
SBI_SSE_ATTR_INTERRUPTED_FLAGS_HSTATUS_SPV |
SBI_SSE_ATTR_INTERRUPTED_FLAGS_HSTATUS_SPVP |
- SBI_SSE_ATTR_INTERRUPTED_FLAGS_SSTATUS_SPELP))
+ SBI_SSE_ATTR_INTERRUPTED_FLAGS_SSTATUS_SPELP |
+ SBI_SSE_ATTR_INTERRUPTED_FLAGS_SSTATUS_SDT))
return SBI_EINVAL;
__attribute__((__fallthrough__));
case SBI_SSE_ATTR_INTERRUPTED_SEPC:
@@ -525,6 +526,8 @@ static unsigned long sse_interrupted_flags(unsigned long mstatus)
flags |= SBI_SSE_ATTR_INTERRUPTED_FLAGS_SSTATUS_SPP;
if (mstatus & MSTATUS_SPELP)
flags |= SBI_SSE_ATTR_INTERRUPTED_FLAGS_SSTATUS_SPELP;
+ if (mstatus & MSTATUS_SDT)
+ flags |= SBI_SSE_ATTR_INTERRUPTED_FLAGS_SSTATUS_SDT;
if (misa_extension('H')) {
hstatus = csr_read(CSR_HSTATUS);
@@ -584,10 +587,11 @@ static void sse_event_inject(struct sbi_sse_event *e,
/*
* Return to S-mode with virtualization disabled, not expected landing
- * pad.
+ * pad, supervisor trap disabled.
*/
regs->mstatus &= ~(MSTATUS_MPP | MSTATUS_SIE | MSTATUS_SPELP);
regs->mstatus |= (PRV_S << MSTATUS_MPP_SHIFT);
+ regs->mstatus |= MSTATUS_SDT;
#if __riscv_xlen == 64
regs->mstatus &= ~MSTATUS_MPV;
@@ -649,6 +653,10 @@ static void sse_event_resume(struct sbi_sse_event *e,
if (i_ctx->flags & SBI_SSE_ATTR_INTERRUPTED_FLAGS_SSTATUS_SPELP)
regs->mstatus |= MSTATUS_SPELP;
+ regs->mstatus &= ~MSTATUS_SDT;
+ if (i_ctx->flags & SBI_SSE_ATTR_INTERRUPTED_FLAGS_SSTATUS_SDT)
+ regs->mstatus |= MSTATUS_SDT;
+
regs->a7 = i_ctx->a7;
regs->a6 = i_ctx->a6;
csr_write(CSR_SEPC, i_ctx->sepc);