diff options
author | Anup Patel <anup@brainfault.org> | 2018-12-03 10:57:40 +0530 |
---|---|---|
committer | Andes <uboot@andestech.com> | 2018-12-05 14:13:53 +0800 |
commit | d2db2a8fa4f190d6d78ee7e9e642a180664cbccf (patch) | |
tree | 065e64b9073f659188b32040bdaeba90dc33776b /arch/riscv/lib/interrupts.c | |
parent | 2e2a2a5d4f0c2e2642326d9000ce1f1553632e6a (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/interrupts.c')
-rw-r--r-- | arch/riscv/lib/interrupts.c | 31 |
1 files changed, 22 insertions, 9 deletions
diff --git a/arch/riscv/lib/interrupts.c b/arch/riscv/lib/interrupts.c index 903a1c4cd5..3aff006977 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; } |