summaryrefslogtreecommitdiff
path: root/arch/riscv/lib
diff options
context:
space:
mode:
authorAnup Patel <anup@brainfault.org>2018-12-03 10:57:40 +0530
committerAndes <uboot@andestech.com>2018-12-05 14:13:53 +0800
commitd2db2a8fa4f190d6d78ee7e9e642a180664cbccf (patch)
tree065e64b9073f659188b32040bdaeba90dc33776b /arch/riscv/lib
parent2e2a2a5d4f0c2e2642326d9000ce1f1553632e6a (diff)
riscv: Add kconfig option to run U-Boot in S-mode
This patch adds kconfig option RISCV_SMODE to run U-Boot in S-mode. When this opition is enabled we use s<xyz> CSRs instead of m<xyz> CSRs. It is important to note that there is no equivalent S-mode CSR for misa and mhartid CSRs so we expect M-mode runtime firmware (BBL or equivalent) to emulate misa and mhartid CSR read. In-future, we will have more patches to avoid accessing misa and mhartid CSRs from S-mode. Signed-off-by: Anup Patel <anup@brainfault.org> Reviewed-by: Bin Meng <bmeng.cn@gmail.com> Tested-by: Bin Meng <bmeng.cn@gmail.com> Reviewed-by: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
Diffstat (limited to 'arch/riscv/lib')
-rw-r--r--arch/riscv/lib/interrupts.c31
1 files changed, 22 insertions, 9 deletions
diff --git a/arch/riscv/lib/interrupts.c b/arch/riscv/lib/interrupts.c
index 903a1c4cd55..3aff0069773 100644
--- a/arch/riscv/lib/interrupts.c
+++ b/arch/riscv/lib/interrupts.c
@@ -34,17 +34,30 @@ int disable_interrupts(void)
return 0;
}
-ulong handle_trap(ulong mcause, ulong epc, struct pt_regs *regs)
+ulong handle_trap(ulong cause, ulong epc, struct pt_regs *regs)
{
- ulong is_int;
+ ulong is_irq, irq;
- is_int = (mcause & MCAUSE_INT);
- if ((is_int) && ((mcause & MCAUSE_CAUSE) == IRQ_M_EXT))
- external_interrupt(0); /* handle_m_ext_interrupt */
- else if ((is_int) && ((mcause & MCAUSE_CAUSE) == IRQ_M_TIMER))
- timer_interrupt(0); /* handle_m_timer_interrupt */
- else
- _exit_trap(mcause, epc, regs);
+ is_irq = (cause & MCAUSE_INT);
+ irq = (cause & ~MCAUSE_INT);
+
+ if (is_irq) {
+ switch (irq) {
+ case IRQ_M_EXT:
+ case IRQ_S_EXT:
+ external_interrupt(0); /* handle external interrupt */
+ break;
+ case IRQ_M_TIMER:
+ case IRQ_S_TIMER:
+ timer_interrupt(0); /* handle timer interrupt */
+ break;
+ default:
+ _exit_trap(cause, epc, regs);
+ break;
+ };
+ } else {
+ _exit_trap(cause, epc, regs);
+ }
return epc;
}