aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Waterman <waterman@cs.berkeley.edu>2016-02-05 18:07:07 -0800
committerAndrew Waterman <waterman@cs.berkeley.edu>2016-02-19 13:01:11 -0800
commitd340b4271b2f0fda1a4d824b1e09540947240048 (patch)
tree05ded55d2960ce60e72d3e157b67d7ce129dc129
parent7016bac5dfb70a63c5041edc0c2922b9d6e3fd89 (diff)
downloadriscv-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.S2
-rw-r--r--pk/sbi.h3
-rw-r--r--pk/sbi_entry.S8
-rw-r--r--pk/sbi_impl.c20
4 files changed, 33 insertions, 0 deletions
diff --git a/pk/sbi.S b/pk/sbi.S
index 7c3bfcc..59a282e 100644
--- a/pk/sbi.S
+++ b/pk/sbi.S
@@ -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
diff --git a/pk/sbi.h b/pk/sbi.h
index 2d8daeb..0a2b880 100644
--- a/pk/sbi.h
+++ b/pk/sbi.h
@@ -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;
+}