From 8f71204b92c4789dc9ddfeda69fa486e9d1a8419 Mon Sep 17 00:00:00 2001 From: KushalMeghani1644 Date: Thu, 7 May 2026 15:25:14 +0530 Subject: [PATCH 1/4] Add mtopei CSR --- riscv/src/register.rs | 1 + riscv/src/register/mtopei.rs | 70 ++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 riscv/src/register/mtopei.rs diff --git a/riscv/src/register.rs b/riscv/src/register.rs index cdf83f83..e2025298 100644 --- a/riscv/src/register.rs +++ b/riscv/src/register.rs @@ -92,6 +92,7 @@ pub mod mip; pub mod mscratch; pub mod mtinst; pub mod mtopi; +pub mod mtopei; pub mod mtval; pub mod mtval2; pub mod mvien; diff --git a/riscv/src/register/mtopei.rs b/riscv/src/register/mtopei.rs new file mode 100644 index 00000000..dd28cc1b --- /dev/null +++ b/riscv/src/register/mtopei.rs @@ -0,0 +1,70 @@ +//! `mtopei` register — Machine Top External Interrupt (0x35C) +//! +//! This CSR is part of the RISC-V Advanced Interrupt Architecture (AIA). Its layout mirrors +//! `mtopi`, exposing the interrupt identity and priority of the top pending machine external +//! interrupt. + +read_write_csr! { + /// Machine Top External Interrupt Register + Mtopei: 0x35C, + mask: 0x0FFF_00FF, +} + +read_write_csr_field! { + Mtopei, + /// Interrupt ID (bits 16..27) + /// + /// Identifies the specific interrupt source. A value of 0 indicates no interrupt is pending. + iid: [16:27], +} + +read_write_csr_field! { + Mtopei, + /// Interrupt Priority ID (bits 0..7) + /// + /// Represents the priority level of the pending interrupt. + /// Lower numerical values indicate higher priority interrupts. + iprio: [0:7], +} + +impl Mtopei { + /// Returns true if there is a valid interrupt pending. + #[inline] + pub fn is_interrupt_pending(&self) -> bool { + self.iid() != 0 + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_mtopei_fields() { + let mut mtopei = Mtopei::from_bits(0); + test_csr_field!(mtopei, iid: [16, 27], 0x0); + test_csr_field!(mtopei, iprio: [0, 7], 0x0); + + let mut mtopei = Mtopei::from_bits((0xB << 16) | 5); + test_csr_field!(mtopei, iid: [16, 27], 0xB); + test_csr_field!(mtopei, iprio: [0, 7], 0x5); + + let mut mtopei = Mtopei::from_bits((0xFFF << 16) | 0xFF); + test_csr_field!(mtopei, iid: [16, 27], 0xFFF); + test_csr_field!(mtopei, iprio: [0, 7], 0xFF); + + let mut mtopei = Mtopei::from_bits(1 << 16); + test_csr_field!(mtopei, iid: [16, 27], 0x1); + test_csr_field!(mtopei, iprio: [0, 7], 0x0); + + let mut mtopei = Mtopei::from_bits(1); + test_csr_field!(mtopei, iid: [16, 27], 0x0); + test_csr_field!(mtopei, iprio: [0, 7], 0x1); + } + + #[test] + fn test_mtopei_bitmask() { + let mtopei = Mtopei::from_bits(usize::MAX); + assert_eq!(mtopei.bits(), 0x0FFF_00FFusize); + } +} From 44c6c8f109e739edf15cd19ae71dab5e9cfde07b Mon Sep 17 00:00:00 2001 From: KushalMeghani1644 Date: Thu, 7 May 2026 15:30:07 +0530 Subject: [PATCH 2/4] update CHANGELOG.md --- riscv/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/riscv/CHANGELOG.md b/riscv/CHANGELOG.md index 33cd2395..46fcfc97 100644 --- a/riscv/CHANGELOG.md +++ b/riscv/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Added +- Add `mtopei` CSR - Add `mstatus` and `sstatus` CSRs helpers for UBE, VS, UXL and SXL, and the corresponding tests - Add `pmpaddr16` ~ `pmpaddr63` CSRs - Add `siselect` CSR From 87dbdd19adecfffadedc1cdec1f0497f9fb50d90 Mon Sep 17 00:00:00 2001 From: KushalMeghani1644 Date: Thu, 7 May 2026 15:31:06 +0530 Subject: [PATCH 3/4] Fix formatting --- riscv/src/register.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/riscv/src/register.rs b/riscv/src/register.rs index e2025298..65eaedf6 100644 --- a/riscv/src/register.rs +++ b/riscv/src/register.rs @@ -91,8 +91,8 @@ pub mod mepc; pub mod mip; pub mod mscratch; pub mod mtinst; -pub mod mtopi; pub mod mtopei; +pub mod mtopi; pub mod mtval; pub mod mtval2; pub mod mvien; From ed881145fe7471b94a63391102a48efb9177183c Mon Sep 17 00:00:00 2001 From: KushalMeghani1644 Date: Thu, 21 May 2026 16:41:28 +0530 Subject: [PATCH 4/4] Address review --- riscv/src/register/mtopei.rs | 40 ++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/riscv/src/register/mtopei.rs b/riscv/src/register/mtopei.rs index dd28cc1b..8f97cae2 100644 --- a/riscv/src/register/mtopei.rs +++ b/riscv/src/register/mtopei.rs @@ -1,30 +1,30 @@ //! `mtopei` register — Machine Top External Interrupt (0x35C) //! -//! This CSR is part of the RISC-V Advanced Interrupt Architecture (AIA). Its layout mirrors -//! `mtopi`, exposing the interrupt identity and priority of the top pending machine external -//! interrupt. +//! This CSR is part of the RISC-V Advanced Interrupt Architecture (AIA). It reports the +//! highest-priority pending-and-enabled interrupt from the IMSIC machine-level interrupt file. +//! The interrupt identity is in bits 26:16 and the interrupt priority (same value) in bits 10:0. read_write_csr! { /// Machine Top External Interrupt Register Mtopei: 0x35C, - mask: 0x0FFF_00FF, + mask: 0x07FF_07FF, } read_write_csr_field! { Mtopei, - /// Interrupt ID (bits 16..27) + /// Interrupt ID (bits 16..26) /// /// Identifies the specific interrupt source. A value of 0 indicates no interrupt is pending. - iid: [16:27], + iid: [16:26], } read_write_csr_field! { Mtopei, - /// Interrupt Priority ID (bits 0..7) + /// Interrupt Priority ID (bits 0..10) /// /// Represents the priority level of the pending interrupt. /// Lower numerical values indicate higher priority interrupts. - iprio: [0:7], + iprio: [0:10], } impl Mtopei { @@ -42,29 +42,29 @@ mod tests { #[test] fn test_mtopei_fields() { let mut mtopei = Mtopei::from_bits(0); - test_csr_field!(mtopei, iid: [16, 27], 0x0); - test_csr_field!(mtopei, iprio: [0, 7], 0x0); + test_csr_field!(mtopei, iid: [16, 26], 0x0); + test_csr_field!(mtopei, iprio: [0, 10], 0x0); let mut mtopei = Mtopei::from_bits((0xB << 16) | 5); - test_csr_field!(mtopei, iid: [16, 27], 0xB); - test_csr_field!(mtopei, iprio: [0, 7], 0x5); + test_csr_field!(mtopei, iid: [16, 26], 0xB); + test_csr_field!(mtopei, iprio: [0, 10], 0x5); - let mut mtopei = Mtopei::from_bits((0xFFF << 16) | 0xFF); - test_csr_field!(mtopei, iid: [16, 27], 0xFFF); - test_csr_field!(mtopei, iprio: [0, 7], 0xFF); + let mut mtopei = Mtopei::from_bits((0x7FF << 16) | 0x7FF); + test_csr_field!(mtopei, iid: [16, 26], 0x7FF); + test_csr_field!(mtopei, iprio: [0, 10], 0x7FF); let mut mtopei = Mtopei::from_bits(1 << 16); - test_csr_field!(mtopei, iid: [16, 27], 0x1); - test_csr_field!(mtopei, iprio: [0, 7], 0x0); + test_csr_field!(mtopei, iid: [16, 26], 0x1); + test_csr_field!(mtopei, iprio: [0, 10], 0x0); let mut mtopei = Mtopei::from_bits(1); - test_csr_field!(mtopei, iid: [16, 27], 0x0); - test_csr_field!(mtopei, iprio: [0, 7], 0x1); + test_csr_field!(mtopei, iid: [16, 26], 0x0); + test_csr_field!(mtopei, iprio: [0, 10], 0x1); } #[test] fn test_mtopei_bitmask() { let mtopei = Mtopei::from_bits(usize::MAX); - assert_eq!(mtopei.bits(), 0x0FFF_00FFusize); + assert_eq!(mtopei.bits(), 0x07FF_07FFusize); } }