Skip to content

Commit

Permalink
SailBugfix: Modifies only mie in write Sie when the interrupt is dele…
Browse files Browse the repository at this point in the history
…gated

Before modifying each specific interrupt enable bit (e.g., SEIE, STIE, or SSIE), the code checks whether the corresponding bit in Mideleg is set. Mideleg determines whether a specific interrupt is delegated to the supervisor level, so this ensures that only interrupts managed by the supervisor are updated.
  • Loading branch information
francois141 committed Jan 27, 2025
1 parent cb74bea commit 62d478c
Showing 1 changed file with 13 additions and 4 deletions.
17 changes: 13 additions & 4 deletions src/virt/csr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
//! specification.
use super::{VirtContext, VirtCsr};
use crate::arch::mie::{LCOFIE_FILTER, SEIE_FILTER, SSIE_FILTER, STIE_FILTER};
use crate::arch::mstatus::{MBE_FILTER, SBE_FILTER, UBE_FILTER};
use crate::arch::pmp::pmpcfg;
use crate::arch::{hstatus, menvcfg, mie, misa, mstatus, Arch, Architecture, Csr, Register};
Expand Down Expand Up @@ -540,10 +541,18 @@ impl HwRegisterContextSetter<Csr> for VirtContext {
);
}
Csr::Sie => {
// Clear S bits
let mie = self.get(Csr::Mie) & !mie::SIE_FILTER;
// Set S bits to new value
self.set_csr(Csr::Mie, mie | (value & mie::SIE_FILTER), mctx);
if SEIE_FILTER & self.get(Csr::Mideleg) != 0 {
self.csr.mie = (self.csr.mie & !SEIE_FILTER) | (SEIE_FILTER & value);
}
if STIE_FILTER & self.get(Csr::Mideleg) != 0 {
self.csr.mie = (self.csr.mie & !STIE_FILTER) | (STIE_FILTER & value);
}
if SSIE_FILTER & self.get(Csr::Mideleg) != 0 {
self.csr.mie = (self.csr.mie & !SSIE_FILTER) | (SSIE_FILTER & value);
}
if LCOFIE_FILTER & self.get(Csr::Mideleg) != 0 {
self.csr.mie = (self.csr.mie & !LCOFIE_FILTER) | (LCOFIE_FILTER & value);
}
}
Csr::Stvec => {
match value & 0b11 {
Expand Down

0 comments on commit 62d478c

Please sign in to comment.