summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDamien Le Moal <[email protected]>2018-12-21 15:05:33 +0900
committerDamien Le Moal <[email protected]>2018-12-21 15:12:22 +0900
commitd403c70fb11fb55042ca3cef0dbe399ed87cc79b (patch)
tree8c25e1ba267a1e2989164d221f891002b12a1fa8 /lib
parent9c183df632ee91560e160d6011c7ece56ee1f9b0 (diff)
Fix interrupt and exception delegation
When S mode is not supported, simply clear mideleg and medeleg. Otherwise, set delegation from M-mode to S-mode, removing the page fault exceptions as those would not happen in M-mode. Signed-off-by: Damien Le Moal <[email protected]>
Diffstat (limited to 'lib')
-rw-r--r--lib/sbi_hart.c22
1 files changed, 12 insertions, 10 deletions
diff --git a/lib/sbi_hart.c b/lib/sbi_hart.c
index b30250b3..12c5c55b 100644
--- a/lib/sbi_hart.c
+++ b/lib/sbi_hart.c
@@ -77,17 +77,19 @@ static int fp_init(u32 hartid)
static int delegate_traps(u32 hartid)
{
- /* send S-mode interrupts and most exceptions straight to S-mode */
- unsigned long interrupts = MIP_SSIP | MIP_STIP | MIP_SEIP;
- unsigned long exceptions = (1U << CAUSE_MISALIGNED_FETCH) |
- (1U << CAUSE_FETCH_PAGE_FAULT) |
- (1U << CAUSE_BREAKPOINT) |
- (1U << CAUSE_LOAD_PAGE_FAULT) |
- (1U << CAUSE_STORE_PAGE_FAULT) |
- (1U << CAUSE_USER_ECALL);
+ unsigned long interrupts, exceptions;
- if (!misa_extension('S'))
- return 0;
+ if (!misa_extension('S')) {
+ /* No delegation possible */
+ interrupts = 0;
+ exceptions = 0;
+ } else {
+ /* Send M-mode interrupts and most exceptions to S-mode */
+ interrupts = MIP_SSIP | MIP_STIP | MIP_SEIP;
+ exceptions = (1U << CAUSE_MISALIGNED_FETCH) |
+ (1U << CAUSE_BREAKPOINT) |
+ (1U << CAUSE_USER_ECALL);
+ }
csr_write(mideleg, interrupts);
csr_write(medeleg, exceptions);