diff options
| author | Damien Le Moal <[email protected]> | 2018-12-21 15:05:33 +0900 |
|---|---|---|
| committer | Damien Le Moal <[email protected]> | 2018-12-21 15:12:22 +0900 |
| commit | d403c70fb11fb55042ca3cef0dbe399ed87cc79b (patch) | |
| tree | 8c25e1ba267a1e2989164d221f891002b12a1fa8 /lib | |
| parent | 9c183df632ee91560e160d6011c7ece56ee1f9b0 (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.c | 22 |
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); |
