Skip to content

Commit

Permalink
arch: riscv: handle interrupt level for CLIC
Browse files Browse the repository at this point in the history
CLIC supports mintstatus.MIL (RO) and mcause.MPIL (RW) for the current
interrupt level and the previous interrut level before a trap.
Each ISR must execute MRET to set mcause.MPIL back to mintstatus.MIL.
Save mcause.MPIL for nested interrupt, and use
CONFIG_RISCV_ALWAYS_SWITCH_THROUGH_ECALL to ensure ISR doesn't switch out
without MRET.
e.g.
  With CONFIG_RISCV_ALWAYS_SWITCH_THROUGH_ECALL=n, a context-switch in
  ISR may skip MRET in this flow:
  IRQ -> _isr_wrapper -> z_riscv_switch() -> retrun to arch_switch()

Signed-off-by: Jimmy Zheng <[email protected]>
  • Loading branch information
jimmyzhe committed Jul 8, 2024
1 parent dcfc3e7 commit a39bcbd
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 0 deletions.
1 change: 1 addition & 0 deletions arch/riscv/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ config RISCV_HAS_PLIC
config RISCV_HAS_CLIC
bool
depends on RISCV_PRIVILEGED
select RISCV_ALWAYS_SWITCH_THROUGH_ECALL if MULTITHREADING
help
Does the SOC provide support for a Core-Local Interrupt Controller (CLIC).

Expand Down
18 changes: 18 additions & 0 deletions arch/riscv/core/isr.S
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,12 @@ SECTION_FUNC(exception.entry, _isr_wrapper)
sr s0, __struct_arch_esf_s0_OFFSET(sp)
get_current_cpu s0

#ifdef CONFIG_RISCV_HAS_CLIC
/* Save mcause register */
csrr t0, mcause
sr t0, __struct_arch_esf_mcause_OFFSET(sp)
#endif /* CONFIG_RISCV_HAS_CLIC */

/* Save MEPC register */
csrr t0, mepc
sr t0, __struct_arch_esf_mepc_OFFSET(sp)
Expand Down Expand Up @@ -682,6 +688,18 @@ no_reschedule:
fp_trap_exit:
#endif

#ifdef CONFIG_RISCV_HAS_CLIC
/* Restore MCAUSE.MPIL fields (previous interrupt level) */
li t2, MCAUSE_MPIL
lr t0, __struct_arch_esf_mcause_OFFSET(sp)
and t0, t0, t2
not t2, t2
csrr t1, mcause
and t1, t1, t2
or t0, t0, t1
csrw mcause, t0
#endif /* CONFIG_RISCV_HAS_CLIC */

/* Restore MEPC and MSTATUS registers */
lr t0, __struct_arch_esf_mepc_OFFSET(sp)
lr t2, __struct_arch_esf_mstatus_OFFSET(sp)
Expand Down
4 changes: 4 additions & 0 deletions arch/riscv/core/offsets/offsets.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,10 @@ GEN_OFFSET_STRUCT(arch_esf, a7);
GEN_OFFSET_STRUCT(arch_esf, mepc);
GEN_OFFSET_STRUCT(arch_esf, mstatus);

#ifdef CONFIG_RISCV_HAS_CLIC
GEN_OFFSET_STRUCT(arch_esf, mcause);
#endif /* CONFIG_RISCV_HAS_CLIC */

GEN_OFFSET_STRUCT(arch_esf, s0);

#ifdef CONFIG_USERSPACE
Expand Down
5 changes: 5 additions & 0 deletions arch/riscv/core/thread.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,11 @@ void arch_new_thread(struct k_thread *thread, k_thread_stack_t *stack,
stack_init->soc_context = soc_esf_init;
#endif

#ifdef CONFIG_RISCV_HAS_CLIC
/* Clear the previous interrupt level. */
stack_init->mcause = 0;
#endif

thread->callee_saved.sp = (unsigned long)stack_init;

/* where to go when returning from z_riscv_switch() */
Expand Down
4 changes: 4 additions & 0 deletions include/zephyr/arch/riscv/csr.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@
#define SSTATUS_UXL 0x0000000300000000
#define SSTATUS64_SD 0x8000000000000000

#define MCAUSE_MPIL 0x00FF0000
#define MCAUSE_MPIE 0x08000000
#define MCAUSE_MPP 0x30000000

#define DCSR_XDEBUGVER (3U<<30)
#define DCSR_NDRESET (1<<29)
#define DCSR_FULLRESET (1<<28)
Expand Down
4 changes: 4 additions & 0 deletions include/zephyr/arch/riscv/exception.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@ struct arch_esf {
unsigned long a7; /* function argument */
#endif /* !CONFIG_RISCV_ISA_RV32E */

#ifdef CONFIG_RISCV_HAS_CLIC
unsigned long mcause; /* machine cause register */
#endif /* CONFIG_RISCV_HAS_CLIC */

unsigned long mepc; /* machine exception program counter */
unsigned long mstatus; /* machine status register */

Expand Down

0 comments on commit a39bcbd

Please sign in to comment.