diff options
author | Andrew Waterman <waterman@cs.berkeley.edu> | 2016-02-05 18:07:07 -0800 |
---|---|---|
committer | Andrew Waterman <waterman@cs.berkeley.edu> | 2016-02-19 13:01:11 -0800 |
commit | d340b4271b2f0fda1a4d824b1e09540947240048 (patch) | |
tree | 05ded55d2960ce60e72d3e157b67d7ce129dc129 | |
parent | 7016bac5dfb70a63c5041edc0c2922b9d6e3fd89 (diff) | |
download | riscv-pk-d340b4271b2f0fda1a4d824b1e09540947240048.zip riscv-pk-d340b4271b2f0fda1a4d824b1e09540947240048.tar.gz riscv-pk-d340b4271b2f0fda1a4d824b1e09540947240048.tar.bz2 |
Add SBI calls for IRQ mask/unmask
-rw-r--r-- | pk/sbi.S | 2 | ||||
-rw-r--r-- | pk/sbi.h | 3 | ||||
-rw-r--r-- | pk/sbi_entry.S | 8 | ||||
-rw-r--r-- | pk/sbi_impl.c | 20 |
4 files changed, 33 insertions, 0 deletions
@@ -9,3 +9,5 @@ .globl sbi_timebase; sbi_timebase = -1920 .globl sbi_shutdown; sbi_shutdown = -1904 .globl sbi_set_timer; sbi_set_timer = -1888 +.globl sbi_mask_interrupt; sbi_mask_interrupt = -1872 +.globl sbi_unmask_interrupt; sbi_unmask_interrupt = -1856 @@ -28,4 +28,7 @@ typedef struct { unsigned long sbi_send_device_request(unsigned long req); unsigned long sbi_receive_device_response(void); +unsigned long sbi_mask_interrupt(unsigned long which); +unsigned long sbi_unmask_interrupt(unsigned long which); + #endif diff --git a/pk/sbi_entry.S b/pk/sbi_entry.S index 8b066d0..de33186 100644 --- a/pk/sbi_entry.S +++ b/pk/sbi_entry.S @@ -72,6 +72,14 @@ sbi_base: ecall ret + # mask_interrupt + .align 4 + j __sbi_mask_interrupt + + # unmask_interrupt + .align 4 + j __sbi_unmask_interrupt + # end of SBI trampolines .globl do_mcall diff --git a/pk/sbi_impl.c b/pk/sbi_impl.c index 03a56bc..c386be4 100644 --- a/pk/sbi_impl.c +++ b/pk/sbi_impl.c @@ -21,3 +21,23 @@ uintptr_t __sbi_query_memory(uintptr_t id, memory_block_info *p) return -1; } + +#define LOW_IRQ_OK(n) ((n) == IRQ_S_SOFT || (n) == IRQ_S_TIMER) + +uintptr_t __sbi_mask_interrupt(uintptr_t which) +{ + if (!LOW_IRQ_OK(which)) + return -1; + + clear_csr(sie, 1UL << which); + return 0; +} + +uintptr_t __sbi_unmask_interrupt(uintptr_t which) +{ + if (!LOW_IRQ_OK(which)) + return -1; + + set_csr(sie, 1UL << which); + return 0; +} |