Skip to content

Commit

Permalink
CSR stopei/mtopei: Supervisor/Machine top external interrupt (#9)
Browse files Browse the repository at this point in the history
Implement external interrupt CSRs stopei/mtopei:

- stopei: Supervisor top external interrupt
- mtopei: Machine top external interrupt

These CSRs are specified in the RISC-V Advanced Interrupt Architecture
(AIA) (https://github.com/riscv/riscv-aia/releases).
  • Loading branch information
ted-logan authored Nov 2, 2022
1 parent 2231b77 commit 1f44bf6
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 0 deletions.
25 changes: 25 additions & 0 deletions src/register/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,31 @@ macro_rules! write_csr_as_usize_rv32 {
};
}

macro_rules! claim_csr_as {
($register:ident, $csr_number:literal) => {
/// Claim and return the highest-priority interrupt pending on this hart
/// # Safety
/// This function mutates system state by claiming a pending interrupt.
/// The caller must handle this interrupt otherwise it will be lost.
pub unsafe fn claim() -> $register {
match () {
#[cfg(riscv)]
() => {
let r: usize;
core::arch::asm!(concat!(
"csrrw {0}, ", stringify!($csr_number), ", x0"),
out(reg) r);

$register { bits: r }
}

#[cfg(not(riscv))]
() => unimplemented!(),
}
}
};
}

macro_rules! set {
($csr_number:literal) => {
/// Set the CSR
Expand Down
6 changes: 6 additions & 0 deletions src/register/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ pub mod satp;
pub mod stimecmp;
pub mod stimecmph;

// Supervisor-Level Interrupts
pub mod stopei;

// Machine Information Registers
pub mod marchid;
pub mod mhartid;
Expand All @@ -83,6 +86,9 @@ pub mod mip;
pub mod mscratch;
pub mod mtval;

// Machine-Level Interrupts
pub mod mtopei;

// Machine Configuration
pub mod menvcfg;
pub mod menvcfgh;
Expand Down
39 changes: 39 additions & 0 deletions src/register/mtopei.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
//! mtopei register
//!
//! The `mtopei` CSR is defined in "The RISC-V Advanced Interrupt
//! Architecture" Version 0.3.2-draft
//!
//! The primary interface to the mtopei CSR should be the `claim()`
//! function, which will atomically claim the highest-priority pending
//! interrupt and allow the interrupt handler to process it.
use bit_field::BitField;

/// mtopei register
#[derive(Clone, Copy, Debug)]
pub struct Mtopei {
bits: usize,
}

impl Mtopei {
/// Returns the contents of the register as raw bits
#[inline]
pub fn bits(&self) -> usize {
self.bits
}

/// Interrupt identity
#[inline]
pub fn identity(&self) -> usize {
self.bits.get_bits(16..26)
}

/// Interrupt priority
#[inline]
pub fn priority(&self) -> usize {
self.bits.get_bits(0..10)
}
}

read_csr_as!(Mtopei, 0x35C);
claim_csr_as!(Mtopei, 0x35C);
39 changes: 39 additions & 0 deletions src/register/stopei.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
//! stopei register
//!
//! The `stopei` CSR is defined in "The RISC-V Advanced Interrupt
//! Architecture" Version 0.3.2-draft
//!
//! The primary interface to the stopei CSR should be the `claim()`
//! function, which will atomically claim the highest-priority pending
//! interrupt and allow the interrupt handler to process it.
use bit_field::BitField;

/// stopei register
#[derive(Clone, Copy, Debug)]
pub struct Stopei {
bits: usize,
}

impl Stopei {
/// Returns the contents of the register as raw bits
#[inline]
pub fn bits(&self) -> usize {
self.bits
}

/// Interrupt identity
#[inline]
pub fn identity(&self) -> usize {
self.bits.get_bits(16..26)
}

/// Interrupt priority
#[inline]
pub fn priority(&self) -> usize {
self.bits.get_bits(0..10)
}
}

read_csr_as!(Stopei, 0x15C);
claim_csr_as!(Stopei, 0x15C);

0 comments on commit 1f44bf6

Please sign in to comment.