kernel/arch/riscv64/interrupt/mod.rs
1//! RISC-V specific interrupt control functions
2//!
3//! This module provides architecture-specific interrupt management functions
4//! for the RISC-V architecture.
5
6/// Enable interrupts globally on RISC-V
7///
8/// Sets the SIE (Supervisor Interrupt Enable) bit in the sstatus register.
9pub fn enable_interrupts() {
10 unsafe {
11 core::arch::asm!("csrs sstatus, {}", in(reg) 1 << 1);
12 }
13}
14
15/// Disable interrupts globally on RISC-V
16///
17/// Clears the SIE (Supervisor Interrupt Enable) bit in the sstatus register.
18pub fn disable_interrupts() {
19 unsafe {
20 core::arch::asm!("csrc sstatus, {}", in(reg) 1 << 1);
21 }
22}
23
24/// Check if interrupts are currently enabled on RISC-V
25///
26/// Returns true if the SIE bit is set in the sstatus register.
27pub fn are_interrupts_enabled() -> bool {
28 let sstatus: usize;
29 unsafe {
30 core::arch::asm!("csrr {}, sstatus", out(reg) sstatus);
31 }
32 (sstatus & (1 << 1)) != 0
33}
34
35/// Execute a closure with interrupts disabled
36///
37/// This is a convenience function that saves the current interrupt state,
38/// disables interrupts, executes the closure, and restores the interrupt state.
39pub fn with_interrupts_disabled<F, R>(f: F) -> R
40where
41 F: FnOnce() -> R,
42{
43 let old_state = are_interrupts_enabled();
44 disable_interrupts();
45 let result = f();
46 if old_state {
47 enable_interrupts();
48 }
49 result
50}
51
52/// Enable timer interrupts
53///
54/// Enables the timer interrupt by setting the STIE (Supervisor Timer Interrupt Enable) bit in the sie register.
55pub fn enable_timer_interrupts() {
56 unsafe {
57 core::arch::asm!(
58 "csrs sie, {0}",
59 in(reg) 1 << 5, // Set STIE bit
60 options(nostack)
61 );
62 }
63}
64
65/// Disable timer interrupts
66///
67/// Disables the timer interrupt by clearing the STIE (Supervisor Timer Interrupt Enable) bit in the sie register.
68pub fn disable_timer_interrupts() {
69 unsafe {
70 core::arch::asm!(
71 "csrc sie, {0}",
72 in(reg) 1 << 5, // Clear STIE bit
73 options(nostack)
74 );
75 }
76}
77
78/// Check if timer interrupts are enabled
79///
80/// Returns true if the STIE (Supervisor Timer Interrupt Enable) bit is set in the sie register.
81pub fn are_timer_interrupts_enabled() -> bool {
82 let sie: usize;
83 unsafe {
84 core::arch::asm!("csrr {}, sie", out(reg) sie);
85 }
86 (sie & (1 << 5)) != 0
87}
88
89/// Enable software interrupts
90///
91/// Enables the software interrupt by setting the SSIE (Supervisor Software Interrupt Enable) bit in the sie register.
92pub fn enable_software_interrupts() {
93 unsafe {
94 core::arch::asm!(
95 "csrs sie, {0}",
96 in(reg) 1 << 1, // Set SSIE bit
97 options(nostack)
98 );
99 }
100}
101/// Disable software interrupts
102///
103/// Disables the software interrupt by clearing the SSIE (Supervisor Software Interrupt Enable) bit in the sie register.
104pub fn disable_software_interrupts() {
105 unsafe {
106 core::arch::asm!(
107 "csrc sie, {0}",
108 in(reg) 1 << 1, // Clear SSIE bit
109 options(nostack)
110 );
111 }
112}
113
114/// Check if software interrupts are enabled
115///
116/// Returns true if the SSIE (Supervisor Software Interrupt Enable) bit is set in the sie register.
117pub fn are_software_interrupts_enabled() -> bool {
118 let sie: usize;
119 unsafe {
120 core::arch::asm!("csrr {}, sie", out(reg) sie);
121 }
122 (sie & (1 << 1)) != 0
123}
124
125/// Enable external interrupts
126///
127/// Enables the external interrupt by setting the SEIE (Supervisor External Interrupt Enable) bit in the sie register.
128pub fn enable_external_interrupts() {
129 unsafe {
130 core::arch::asm!(
131 "csrs sie, {0}",
132 in(reg) 1 << 9, // Set SEIE bit
133 options(nostack)
134 );
135 }
136}
137
138/// Disable external interrupts
139///
140/// Disables the external interrupt by clearing the SEIE (Supervisor External Interrupt Enable) bit in the sie register.
141pub fn disable_external_interrupts() {
142 unsafe {
143 core::arch::asm!(
144 "csrc sie, {0}",
145 in(reg) 1 << 9, // Clear SEIE bit
146 options(nostack)
147 );
148 }
149}
150
151/// Check if external interrupts are enabled
152///
153/// Returns true if the SEIE (Supervisor External Interrupt Enable) bit is set in the sie register.
154pub fn are_external_interrupts_enabled() -> bool {
155 let sie: usize;
156 unsafe {
157 core::arch::asm!("csrr {}, sie", out(reg) sie);
158 }
159 (sie & (1 << 9)) != 0
160}