forked from Mirrors/opensbi
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 <cleger@rivosinc.com> Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
This commit is contained in:

committed by
Anup Patel

parent
b4464b22e4
commit
3ac49712e3
@@ -33,6 +33,7 @@
|
|||||||
#define MSTATUS_TW _UL(0x00200000)
|
#define MSTATUS_TW _UL(0x00200000)
|
||||||
#define MSTATUS_TSR _UL(0x00400000)
|
#define MSTATUS_TSR _UL(0x00400000)
|
||||||
#define MSTATUS_SPELP _UL(0x00800000)
|
#define MSTATUS_SPELP _UL(0x00800000)
|
||||||
|
#define MSTATUS_SDT _UL(0x01000000)
|
||||||
#define MSTATUS32_SD _UL(0x80000000)
|
#define MSTATUS32_SD _UL(0x80000000)
|
||||||
#if __riscv_xlen == 64
|
#if __riscv_xlen == 64
|
||||||
#define MSTATUS_UXL _ULL(0x0000000300000000)
|
#define MSTATUS_UXL _ULL(0x0000000300000000)
|
||||||
|
@@ -385,6 +385,7 @@ enum sbi_sse_attr_id {
|
|||||||
#define SBI_SSE_ATTR_INTERRUPTED_FLAGS_HSTATUS_SPV BIT(2)
|
#define SBI_SSE_ATTR_INTERRUPTED_FLAGS_HSTATUS_SPV BIT(2)
|
||||||
#define SBI_SSE_ATTR_INTERRUPTED_FLAGS_HSTATUS_SPVP BIT(3)
|
#define SBI_SSE_ATTR_INTERRUPTED_FLAGS_HSTATUS_SPVP BIT(3)
|
||||||
#define SBI_SSE_ATTR_INTERRUPTED_FLAGS_SSTATUS_SPELP BIT(4)
|
#define SBI_SSE_ATTR_INTERRUPTED_FLAGS_SSTATUS_SPELP BIT(4)
|
||||||
|
#define SBI_SSE_ATTR_INTERRUPTED_FLAGS_SSTATUS_SDT BIT(5)
|
||||||
|
|
||||||
enum sbi_sse_state {
|
enum sbi_sse_state {
|
||||||
SBI_SSE_STATE_UNUSED = 0,
|
SBI_SSE_STATE_UNUSED = 0,
|
||||||
|
@@ -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_SSTATUS_SPIE |
|
||||||
SBI_SSE_ATTR_INTERRUPTED_FLAGS_HSTATUS_SPV |
|
SBI_SSE_ATTR_INTERRUPTED_FLAGS_HSTATUS_SPV |
|
||||||
SBI_SSE_ATTR_INTERRUPTED_FLAGS_HSTATUS_SPVP |
|
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;
|
return SBI_EINVAL;
|
||||||
__attribute__((__fallthrough__));
|
__attribute__((__fallthrough__));
|
||||||
case SBI_SSE_ATTR_INTERRUPTED_SEPC:
|
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;
|
flags |= SBI_SSE_ATTR_INTERRUPTED_FLAGS_SSTATUS_SPP;
|
||||||
if (mstatus & MSTATUS_SPELP)
|
if (mstatus & MSTATUS_SPELP)
|
||||||
flags |= SBI_SSE_ATTR_INTERRUPTED_FLAGS_SSTATUS_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')) {
|
if (misa_extension('H')) {
|
||||||
hstatus = csr_read(CSR_HSTATUS);
|
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
|
* 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 &= ~(MSTATUS_MPP | MSTATUS_SIE | MSTATUS_SPELP);
|
||||||
regs->mstatus |= (PRV_S << MSTATUS_MPP_SHIFT);
|
regs->mstatus |= (PRV_S << MSTATUS_MPP_SHIFT);
|
||||||
|
regs->mstatus |= MSTATUS_SDT;
|
||||||
|
|
||||||
#if __riscv_xlen == 64
|
#if __riscv_xlen == 64
|
||||||
regs->mstatus &= ~MSTATUS_MPV;
|
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)
|
if (i_ctx->flags & SBI_SSE_ATTR_INTERRUPTED_FLAGS_SSTATUS_SPELP)
|
||||||
regs->mstatus |= MSTATUS_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->a7 = i_ctx->a7;
|
||||||
regs->a6 = i_ctx->a6;
|
regs->a6 = i_ctx->a6;
|
||||||
csr_write(CSR_SEPC, i_ctx->sepc);
|
csr_write(CSR_SEPC, i_ctx->sepc);
|
||||||
|
Reference in New Issue
Block a user