Skip to content

Conversation

@0xllx0
Copy link
Contributor

@0xllx0 0xllx0 commented Oct 31, 2025

Adds the mvien + mvienh CSR to represent the Machine Virtual Interrupt Enable registers.

Related: #1, #226

@0xllx0 0xllx0 requested a review from a team as a code owner October 31, 2025 12:56
Adds the `mvien` + `mvienh` CSR to represent the `Machine Virtual
Interrupt Enable` registers.
Comment on lines 33 to 37
read_write_csr_field! {
Mvien,
/// Represents the enable status of a virtual major interrupt.
interrupt: 13..=31,
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure about this. Take a look at mie: https://github.com/rust-embedded/riscv/blob/master/riscv/src/register/mie.rs

As each bit is a field, we probably prefer to use something like that.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, for composite registers, we might want to use this:

read_composite_csr!(super::instreth::read(), read());

Copy link
Contributor Author

@0xllx0 0xllx0 Nov 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As each bit is a field, we probably prefer to use something like that.

Thanks, I applied the naming, and patterns from mie. It's not a 1-to-1, since some of mie fields are not valid in mvien.

I also applied the changes as fixup commits. After final review, I'll squash all the commits down to one.

Also, for composite registers, we might want to use this

Thanks for the suggestion, but I don't think this applies. Since we aren't reading the value as a usize/u64, using this will throw a compile error.

However, I did add the field helpers from Mvien to the Mvienh type. If we still want to read the raw u64 value, I guess we could use the unsafe _read() read().bits() methods.

Copy link
Contributor

@romancardenas romancardenas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about returning results to notify users about potential issues with their interrupt enum?


/// Enable a specific core interrupt source.
#[inline]
pub fn enable<I: InterruptNumber>(&mut self, interrupt: I) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We might prefer to return a riscv::Result<()> to notify users that the interrupt has been effectively enabled. What do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SGTM, I'll switch the methods to be fallible, and document the error conditions.


/// Disable a specific core interrupt source.
#[inline]
pub fn disable<I: InterruptNumber>(&mut self, interrupt: I) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here


/// Enable a specific core interrupt source.
#[inline]
pub fn enable<I: InterruptNumber>(&mut self, interrupt: I) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here


/// Disable a specific core interrupt source.
#[inline]
pub fn disable<I: InterruptNumber>(&mut self, interrupt: I) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here

@0xllx0
Copy link
Contributor Author

0xllx0 commented Nov 5, 2025

What do you think about returning results to notify users about potential issues with their interrupt enum?

I think this is a good idea. Do you think we should also provide an example VirtualInterrupt enum, something like:

pub struct VirtualInterrupt {
    SupervisorSoftware = 1,
    SupervisorTimer = 5,
    SupervisorExternal = 9,
    Interrupt(RangedUsize<13, 63>),
}

/// SAFETY: `Interrupt` represents the virtual RISC-V interrupts
unsafe impl InterruptNumber for VirtualInterrupt {
    const MAX_INTERRUPT_NUMBER: usize = Mvien::MAX_INTERRUPT;

    #[inline]
    fn number(self) -> usize {
        match self {
            Self::SupervisorSoftware => 1,
            Self::SupervisorTimer => 5,
            Self::SupervisorExternal => 9,
            Self::Interrupt(int) => int.inner(),
        }
    }

    #[inline]
    fn from_number(value: usize) -> Result<Self> {
        match value {
            1 => Ok(Self::SupervisorSoftware),
            5 => Ok(Self::SupervisorTimer),
            9 => Ok(Self::SupervisorExternal),
            _ => RangedUsize::try_from(value).map(Self::Interrupt),
        }
    }
}

Maybe this is better left to higher-level libraries?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants