From 3f8b00c4c3770081ca7796a492b0823e0d35ead8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rom=C3=A1n=20C=C3=A1rdenas=20Rodr=C3=ADguez?= Date: Fri, 19 Jul 2024 16:48:46 +0200 Subject: [PATCH] adapt to master --- riscv-pac/Cargo.toml | 9 -- riscv-pac/src/lib.rs | 102 ++++++++---------- riscv-pac/tests/ui/fail_empty_macro.stderr | 7 -- riscv-pac/tests/ui/fail_no_unsafe.stderr | 5 - riscv-peripheral/Cargo.toml | 5 +- riscv-peripheral/examples/e310x.rs | 26 ++--- riscv-peripheral/src/aclint/mswi.rs | 13 --- riscv-peripheral/src/aclint/sswi.rs | 31 ------ riscv-peripheral/src/lib.rs | 1 + riscv-peripheral/src/macros.rs | 54 +++++++--- riscv-peripheral/src/plic.rs | 73 +++++++------ riscv/Cargo.toml | 8 +- {riscv-pac => riscv}/macros/Cargo.toml | 6 +- {riscv-pac => riscv}/macros/src/lib.rs | 11 +- riscv/src/interrupt.rs | 19 ++-- riscv/src/interrupt/machine.rs | 35 +++--- riscv/src/interrupt/supervisor.rs | 43 ++++---- riscv/src/lib.rs | 4 + {riscv-pac => riscv}/tests/test.rs | 0 .../tests/ui/fail_empty_macro.rs | 2 +- riscv/tests/ui/fail_empty_macro.stderr | 7 ++ .../tests/ui/fail_no_unsafe.rs | 2 +- riscv/tests/ui/fail_no_unsafe.stderr | 5 + .../tests/ui/fail_unknown_trait.rs | 2 +- .../tests/ui/fail_unknown_trait.stderr | 6 +- {riscv-pac => riscv}/tests/ui/pass_test.rs | 25 ++--- 26 files changed, 232 insertions(+), 269 deletions(-) delete mode 100644 riscv-pac/tests/ui/fail_empty_macro.stderr delete mode 100644 riscv-pac/tests/ui/fail_no_unsafe.stderr rename {riscv-pac => riscv}/macros/Cargo.toml (75%) rename {riscv-pac => riscv}/macros/src/lib.rs (96%) rename {riscv-pac => riscv}/tests/test.rs (100%) rename {riscv-pac => riscv}/tests/ui/fail_empty_macro.rs (82%) create mode 100644 riscv/tests/ui/fail_empty_macro.stderr rename {riscv-pac => riscv}/tests/ui/fail_no_unsafe.rs (73%) create mode 100644 riscv/tests/ui/fail_no_unsafe.stderr rename {riscv-pac => riscv}/tests/ui/fail_unknown_trait.rs (70%) rename {riscv-pac => riscv}/tests/ui/fail_unknown_trait.stderr (50%) rename {riscv-pac => riscv}/tests/ui/pass_test.rs (79%) diff --git a/riscv-pac/Cargo.toml b/riscv-pac/Cargo.toml index 61c300c1..6a5c6210 100644 --- a/riscv-pac/Cargo.toml +++ b/riscv-pac/Cargo.toml @@ -17,12 +17,3 @@ targets = [ "riscv32i-unknown-none-elf", "riscv32imc-unknown-none-elf", "riscv32imac-unknown-none-elf", "riscv64imac-unknown-none-elf", "riscv64gc-unknown-none-elf", ] - -[dependencies] -riscv-pac-macros = { path = "macros", version = "0.1.0", optional = true } - -[features] -default = ["riscv-pac-macros"] - -[dev-dependencies] -trybuild = "1.0" diff --git a/riscv-pac/src/lib.rs b/riscv-pac/src/lib.rs index 51ed272f..935d5200 100644 --- a/riscv-pac/src/lib.rs +++ b/riscv-pac/src/lib.rs @@ -4,9 +4,6 @@ pub mod result; use result::Result; -#[cfg(feature = "riscv-pac-macros")] -pub use riscv_pac_macros::*; - /// Trait for enums of target-specific exception numbers. /// /// This trait should be implemented by a peripheral access crate (PAC) on its enum of available @@ -136,24 +133,22 @@ pub unsafe trait HartIdNumber: Copy { #[cfg(test)] mod test { use super::*; + use crate::result::Error; - #[derive(Clone, Copy, Debug, Eq, PartialEq, ExceptionNumber)] - #[repr(u16)] + #[derive(Clone, Copy, Debug, Eq, PartialEq)] enum Exception { E1 = 1, E3 = 3, } - #[derive(Clone, Copy, Debug, Eq, PartialEq, InterruptNumber)] - #[repr(u16)] + #[derive(Clone, Copy, Debug, Eq, PartialEq)] enum Interrupt { I1 = 1, I2 = 2, I4 = 4, } - #[derive(Clone, Copy, Debug, Eq, PartialEq, PriorityNumber)] - #[repr(u8)] + #[derive(Clone, Copy, Debug, Eq, PartialEq)] enum Priority { P0 = 0, P1 = 1, @@ -161,50 +156,46 @@ mod test { P3 = 3, } - #[derive(Clone, Copy, Debug, Eq, PartialEq, HartIdNumber)] - #[repr(u16)] - enum Context { - C0 = 0, - C1 = 1, - C2 = 2, + #[derive(Clone, Copy, Debug, Eq, PartialEq)] + enum HartId { + H0 = 0, + H1 = 1, + H2 = 2, } unsafe impl ExceptionNumber for Exception { - const MAX_EXCEPTION_NUMBER: u16 = Self::E3 as u16; + const MAX_EXCEPTION_NUMBER: usize = Self::E3 as usize; #[inline] - fn number(self) -> u16 { + fn number(self) -> usize { self as _ } #[inline] - fn from_number(number: u16) -> Result { - if number > Self::MAX_EXCEPTION_NUMBER || number == 0 { - Err(number) - } else if number == 1 || number == 3 { - // SAFETY: valid exception number - Ok(unsafe { core::mem::transmute(number) }) - } else { - Err(number) + fn from_number(number: usize) -> Result { + match number { + 1 => Ok(Exception::E1), + 3 => Ok(Exception::E3), + _ => Err(Error::InvalidVariant(number)), } } } unsafe impl InterruptNumber for Interrupt { - const MAX_INTERRUPT_NUMBER: u16 = Self::I4 as u16; + const MAX_INTERRUPT_NUMBER: usize = Self::I4 as usize; #[inline] - fn number(self) -> u16 { + fn number(self) -> usize { self as _ } #[inline] - fn from_number(number: u16) -> Result { - if number > Self::MAX_INTERRUPT_NUMBER || number == 0 { - Err(number) - } else { - // SAFETY: valid interrupt number - Ok(unsafe { core::mem::transmute(number) }) + fn from_number(number: usize) -> Result { + match number { + 1 => Ok(Interrupt::I1), + 2 => Ok(Interrupt::I2), + 4 => Ok(Interrupt::I4), + _ => Err(Error::InvalidVariant(number)), } } } @@ -218,18 +209,19 @@ mod test { } #[inline] - fn from_number(number: u8) -> Result { - if number > Self::MAX_PRIORITY_NUMBER { - Err(number) - } else { - // SAFETY: valid priority number - Ok(unsafe { core::mem::transmute(number) }) + fn from_number(number: u8) -> Result { + match number { + 0 => Ok(Priority::P0), + 1 => Ok(Priority::P1), + 2 => Ok(Priority::P2), + 3 => Ok(Priority::P3), + _ => Err(Error::InvalidVariant(number as _)), } } } - unsafe impl HartIdNumber for Context { - const MAX_HART_ID_NUMBER: u16 = Self::C2 as u16; + unsafe impl HartIdNumber for HartId { + const MAX_HART_ID_NUMBER: u16 = Self::H2 as u16; #[inline] fn number(self) -> u16 { @@ -237,12 +229,12 @@ mod test { } #[inline] - fn from_number(number: u16) -> Result { - if number > Self::MAX_HART_ID_NUMBER { - Err(number) - } else { - // SAFETY: valid context number - Ok(unsafe { core::mem::transmute(number) }) + fn from_number(number: u16) -> Result { + match number { + 0 => Ok(HartId::H0), + 1 => Ok(HartId::H1), + 2 => Ok(HartId::H2), + _ => Err(Error::InvalidVariant(number as _)), } } } @@ -252,11 +244,11 @@ mod test { assert_eq!(Exception::E1.number(), 1); assert_eq!(Exception::E3.number(), 3); - assert_eq!(Exception::from_number(0), Err(0)); + assert_eq!(Exception::from_number(0), Err(Error::InvalidVariant(0))); assert_eq!(Exception::from_number(1), Ok(Exception::E1)); - assert_eq!(Exception::from_number(2), Err(2)); + assert_eq!(Exception::from_number(2), Err(Error::InvalidVariant(2))); assert_eq!(Exception::from_number(3), Ok(Exception::E3)); - assert_eq!(Exception::from_number(4), Err(4)); + assert_eq!(Exception::from_number(4), Err(Error::InvalidVariant(4))); } #[test] @@ -265,12 +257,12 @@ mod test { assert_eq!(Interrupt::I2.number(), 2); assert_eq!(Interrupt::I4.number(), 4); - assert_eq!(Interrupt::from_number(0), Err(0)); + assert_eq!(Interrupt::from_number(0), Err(Error::InvalidVariant(0))); assert_eq!(Interrupt::from_number(1), Ok(Interrupt::I1)); assert_eq!(Interrupt::from_number(2), Ok(Interrupt::I2)); - assert_eq!(Interrupt::from_number(3), Err(3)); + assert_eq!(Interrupt::from_number(3), Err(Error::InvalidVariant(3))); assert_eq!(Interrupt::from_number(4), Ok(Interrupt::I4)); - assert_eq!(Interrupt::from_number(5), Err(5)); + assert_eq!(Interrupt::from_number(5), Err(Error::InvalidVariant(5))); } #[test] @@ -284,7 +276,7 @@ mod test { assert_eq!(Priority::from_number(1), Ok(Priority::P1)); assert_eq!(Priority::from_number(2), Ok(Priority::P2)); assert_eq!(Priority::from_number(3), Ok(Priority::P3)); - assert_eq!(Priority::from_number(4), Err(4)); + assert_eq!(Priority::from_number(4), Err(Error::InvalidVariant(4))); } #[test] @@ -296,6 +288,6 @@ mod test { assert_eq!(HartId::from_number(0), Ok(HartId::H0)); assert_eq!(HartId::from_number(1), Ok(HartId::H1)); assert_eq!(HartId::from_number(2), Ok(HartId::H2)); - assert_eq!(HartId::from_number(3), Err(3)); + assert_eq!(HartId::from_number(3), Err(Error::InvalidVariant(3))); } } diff --git a/riscv-pac/tests/ui/fail_empty_macro.stderr b/riscv-pac/tests/ui/fail_empty_macro.stderr deleted file mode 100644 index 22211826..00000000 --- a/riscv-pac/tests/ui/fail_empty_macro.stderr +++ /dev/null @@ -1,7 +0,0 @@ -error: unexpected end of input, expected `unsafe` - --> tests/ui/fail_empty_macro.rs:1:1 - | -1 | #[riscv_pac::pac_enum] - | ^^^^^^^^^^^^^^^^^^^^^^ - | - = note: this error originates in the attribute macro `riscv_pac::pac_enum` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/riscv-pac/tests/ui/fail_no_unsafe.stderr b/riscv-pac/tests/ui/fail_no_unsafe.stderr deleted file mode 100644 index a12dfad7..00000000 --- a/riscv-pac/tests/ui/fail_no_unsafe.stderr +++ /dev/null @@ -1,5 +0,0 @@ -error: expected `unsafe` - --> tests/ui/fail_no_unsafe.rs:1:23 - | -1 | #[riscv_pac::pac_enum(InterruptNumber)] - | ^^^^^^^^^^^^^^^ diff --git a/riscv-peripheral/Cargo.toml b/riscv-peripheral/Cargo.toml index c4461641..b719e73d 100644 --- a/riscv-peripheral/Cargo.toml +++ b/riscv-peripheral/Cargo.toml @@ -16,12 +16,11 @@ license = "ISC" [dependencies] embedded-hal = "1.0.0" embedded-hal-async = { version = "1.0.0", optional = true } -riscv = { path = "../riscv", version = "0.11.2" } -riscv-pac = { path = "../riscv-pac", version = "0.1.2", default-features = false } +riscv = { path = "../riscv", version = "0.11.2", default-features = false } +riscv-pac = { path = "../riscv-pac", version = "0.1.2" } [dev-dependencies] heapless = "0.8.0" -riscv-pac = { path = "../riscv-pac", version = "0.1.2", default-features = true } [features] aclint-hal-async = ["embedded-hal-async"] diff --git a/riscv-peripheral/examples/e310x.rs b/riscv-peripheral/examples/e310x.rs index 970108c1..65d237e8 100644 --- a/riscv-peripheral/examples/e310x.rs +++ b/riscv-peripheral/examples/e310x.rs @@ -2,11 +2,11 @@ //! This is a simple example of how to use the `riscv-peripheral` crate to generate //! peripheral definitions for a target. -use riscv_pac::pac_enum; -use riscv_pac::result::{Error, Result}; +use riscv_pac::{ + result::{Error, Result}, + ExternalInterruptNumber, HartIdNumber, InterruptNumber, PriorityNumber, +}; -#[repr(u16)] -#[pac_enum(unsafe HartIdNumber)] #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum HartId { H0 = 0, @@ -22,11 +22,9 @@ unsafe impl HartIdNumber for HartId { #[inline] fn from_number(number: u16) -> Result { - if number > Self::MAX_HART_ID_NUMBER { - Err(Error::InvalidVariant(number as usize)) - } else { - // SAFETY: valid context number - Ok(unsafe { core::mem::transmute(number) }) + match number { + 0 => Ok(HartId::H0), + _ => Err(Error::InvalidVariant(number as usize)), } } } @@ -88,28 +86,26 @@ pub enum Interrupt { } unsafe impl InterruptNumber for Interrupt { - const MAX_INTERRUPT_NUMBER: u16 = Self::I2C0 as u16; + const MAX_INTERRUPT_NUMBER: usize = Self::I2C0 as usize; #[inline] - fn number(self) -> u16 { + fn number(self) -> usize { self as _ } #[inline] - fn from_number(number: u16) -> Result { + fn from_number(number: usize) -> Result { if number == 0 || number > Self::MAX_INTERRUPT_NUMBER { Err(Error::InvalidVariant(number as usize)) } else { // SAFETY: valid interrupt number - Ok(unsafe { core::mem::transmute(number) }) + Ok(unsafe { core::mem::transmute(number as u8) }) } } } unsafe impl ExternalInterruptNumber for Interrupt {} -#[repr(u8)] -#[pac_enum(unsafe PriorityNumber)] #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub enum Priority { P0 = 0, diff --git a/riscv-peripheral/src/aclint/mswi.rs b/riscv-peripheral/src/aclint/mswi.rs index 4e85121a..3af4af75 100644 --- a/riscv-peripheral/src/aclint/mswi.rs +++ b/riscv-peripheral/src/aclint/mswi.rs @@ -35,19 +35,6 @@ impl MSWI { // SAFETY: `hart_id` is valid for the target unsafe { MSIP::new(self.msip0.get_ptr().offset(hart_id.number() as _) as _) } } - - /// Returns the `MSIP` register for the current HART. - /// - /// # Note - /// - /// This function determines the current HART ID by reading the [`riscv::register::mhartid`] CSR. - /// Thus, it can only be used in M-mode. For S-mode, use [`MSWI::msip`] instead. - #[inline] - pub fn msip_mhartid(&self) -> MSIP { - let hart_id = riscv::register::mhartid::read(); - // SAFETY: `hart_id` is valid for the target and is the current hart - unsafe { MSIP::new(self.msip0.get_ptr().add(hart_id) as _) } - } } unsafe_peripheral!(MSIP, u32, RW); diff --git a/riscv-peripheral/src/aclint/sswi.rs b/riscv-peripheral/src/aclint/sswi.rs index 51072d66..01cf137d 100644 --- a/riscv-peripheral/src/aclint/sswi.rs +++ b/riscv-peripheral/src/aclint/sswi.rs @@ -25,37 +25,6 @@ impl SSWI { } } - /// Returns `true` if a supervisor software interrupt is pending. - #[inline] - pub fn is_interrupting() -> bool { - riscv::register::sip::read().ssoft() - } - - /// Returns `true` if Supervisor Software Interrupts are enabled. - #[inline] - pub fn is_enabled() -> bool { - riscv::register::mie::read().ssoft() - } - - /// Sets the Supervisor Software Interrupt bit of the `mie` CSR. - /// This bit must be set for the `SSWI` to trigger supervisor software interrupts. - /// - /// # Safety - /// - /// Enabling the `SSWI` may break mask-based critical sections. - #[inline] - pub unsafe fn enable() { - riscv::register::mie::set_ssoft(); - } - - /// Clears the Supervisor Software Interrupt bit of the `mie` CSR. - /// When cleared, the `SSWI` cannot trigger supervisor software interrupts. - #[inline] - pub fn disable() { - // SAFETY: it is safe to disable interrupts - unsafe { riscv::register::mie::clear_ssoft() }; - } - /// Returns the `SETSSIP` register for the HART which ID is `hart_id`. /// /// # Note diff --git a/riscv-peripheral/src/lib.rs b/riscv-peripheral/src/lib.rs index ca33cd19..b34b63a8 100644 --- a/riscv-peripheral/src/lib.rs +++ b/riscv-peripheral/src/lib.rs @@ -9,6 +9,7 @@ #![no_std] pub use riscv; // re-export riscv crate to allow macros to use it +pub use riscv_pac::result; // re-export the result module pub mod common; // common definitions for all peripherals pub mod hal; // trait implementations for embedded-hal diff --git a/riscv-peripheral/src/macros.rs b/riscv-peripheral/src/macros.rs index eec2ac27..4f74569a 100644 --- a/riscv-peripheral/src/macros.rs +++ b/riscv-peripheral/src/macros.rs @@ -1,12 +1,14 @@ -//! Utility macros for generating standard peripherals-related code in RISC-V PACs. +//! macros for easing the definition of peripherals in PACs /// Macro to create interfaces to CLINT peripherals in PACs. /// The resulting struct will be named `CLINT`, and will provide safe access to the CLINT registers. /// -/// This macro expects 4 different argument types: +/// This macro expects 5 different argument types: /// /// - Base address (**MANDATORY**): base address of the CLINT peripheral of the target. /// - Frequency (**OPTIONAL**): clock frequency (in Hz) of the `MTIME` register. It enables the `delay` method of the `CLINT` struct. +/// - Async flag (**OPTIONAL**): It enables the `async_delay` method of the `CLINT struct`. +/// You must activate the `embedded-hal-async` feature to use this flag. /// - Per-HART mtimecmp registers (**OPTIONAL**): a list of `mtimecmp` registers for easing access to per-HART mtimecmp regs. /// - Per-HART msip registers (**OPTIONAL**): a list of `msip` registers for easing access to per-HART msip regs. /// @@ -17,24 +19,20 @@ /// ## Base address only /// /// ``` -/// use riscv_peripheral::clint_codegen; -/// -/// clint_codegen!(base 0x0200_0000, freq 32_768,); // do not forget the ending comma! +/// riscv_peripheral::clint_codegen!(base 0x0200_0000, freq 32_768,); // do not forget the ending comma! /// -/// let mswi = CLINT::mswi(); // MSWI peripheral +/// let mswi = CLINT::mswi(); // MSWI peripheral /// let mtimer = CLINT::mtimer(); // MTIMER peripheral -/// let delay = CLINT::delay(); // For the `embedded_hal::delay::DelayNs` trait +/// let delay = CLINT::delay(); // For the `embedded_hal::delay::DelayNs` trait /// ``` /// /// ## Base address and per-HART mtimecmp registers /// /// ``` -/// use riscv_peripheral::clint_codegen; /// use riscv_pac::result::{Error, Result}; /// /// /// HART IDs for the target CLINT peripheral /// #[derive(Clone, Copy, Debug, Eq, PartialEq)] -/// #[repr(u16)] /// pub enum HartId { H0 = 0, H1 = 1, H2 = 2 } /// /// // Implement `HartIdNumber` for `HartId` @@ -42,16 +40,16 @@ /// const MAX_HART_ID_NUMBER: u16 = 2; /// fn number(self) -> u16 { self as _ } /// fn from_number(number: u16) -> Result { -/// if number > Self::MAX_HART_ID_NUMBER { -/// Err(Error::InvalidVariant(number as usize)) -/// } else { -/// // SAFETY: valid context number -/// Ok(unsafe { core::mem::transmute(number) }) +/// match number { +/// 0 => Ok(HartId::H0), +/// 1 => Ok(HartId::H1), +/// 2 => Ok(HartId::H2), +/// _ => Err(Error::InvalidVariant(number as _)), /// } /// } /// } /// -/// clint_codegen!( +/// riscv_peripheral::clint_codegen!( /// base 0x0200_0000, /// mtimecmps [mtimecmp0 = (HartId::H0, "`H0`"), mtimecmp1 = (HartId::H1, "`H1`"), mtimecmp2 = (HartId::H2, "`H2`")], /// msips [msip0=(HartId::H0,"`H0`"), msip1=(HartId::H1,"`H1`"), msip2=(HartId::H2,"`H2`")], // do not forget the ending comma! @@ -206,7 +204,7 @@ macro_rules! clint_codegen { /// /// # Note /// - /// You must export the `riscv_peripheral::hal::delay::DelayNs` trait in order to use delay methods. + /// You must export the [`embedded_hal::delay::DelayNs`] trait in order to use delay methods. #[inline] pub const fn delay() -> $crate::hal::aclint::Delay { $crate::hal::aclint::Delay::new(Self::mtime(), Self::freq()) @@ -220,7 +218,7 @@ macro_rules! clint_codegen { /// /// # Note /// - /// You must export the `riscv_peripheral::hal_async::delay::DelayNs` trait in order to use delay methods. + /// You must export the [`embedded_hal_async::delay::DelayNs`] trait in order to use delay methods. /// /// This implementation relies on the machine-level timer interrupts to wake futures. /// Therefore, it needs to schedule the machine-level timer interrupts via the `MTIMECMP` register assigned to the current HART. @@ -264,6 +262,28 @@ macro_rules! clint_codegen { } /// Macro to create interfaces to PLIC peripherals in PACs. +/// The resulting struct will be named `PLIC`, and will provide safe access to the PLIC registers. +/// +/// This macro expects 5 different argument types: +/// +/// - Base address (**MANDATORY**): base address of the PLIC peripheral of the target. +/// - Per-HART mtimecmp registers (**OPTIONAL**): a list of `mtimecmp` registers for easing access to per-HART mtimecmp regs. +/// - Per-HART msip registers (**OPTIONAL**): a list of `msip` registers for easing access to per-HART msip regs. +/// +/// Check the examples below for more details about the usage and syntax of this macro. +/// +/// # Example +/// +/// ## Base address only +/// +/// ``` +/// use riscv_peripheral::clint_codegen; +/// +/// riscv_peripheral::plic_codegen!(base 0x0C00_0000,); // do not forget the ending comma! +/// +/// let priorities = PLIC::priorities(); // MSWI peripheral +/// let pendings = PLIC::pendings(); // MTIMER peripheral +/// ``` #[macro_export] macro_rules! plic_codegen { () => { diff --git a/riscv-peripheral/src/plic.rs b/riscv-peripheral/src/plic.rs index d8e32ffc..6f5ee98f 100644 --- a/riscv-peripheral/src/plic.rs +++ b/riscv-peripheral/src/plic.rs @@ -148,7 +148,6 @@ pub(crate) mod test { use riscv_pac::result::{Error, Result}; use riscv_pac::{ExternalInterruptNumber, HartIdNumber, InterruptNumber, PriorityNumber}; - #[pac_enum(unsafe ExternalInterruptNumber)] #[derive(Clone, Copy, Debug, Eq, PartialEq)] #[repr(usize)] pub(crate) enum Interrupt { @@ -158,7 +157,6 @@ pub(crate) mod test { I4 = 4, } - #[pac_enum(unsafe PriorityNumber)] #[derive(Clone, Copy, Debug, Eq, PartialEq)] #[repr(u8)] pub(crate) enum Priority { @@ -168,7 +166,6 @@ pub(crate) mod test { P3 = 3, } - #[pac_enum(unsafe HartIdNumber)] #[derive(Clone, Copy, Debug, Eq, PartialEq)] #[repr(u16)] pub(crate) enum Context { @@ -177,61 +174,63 @@ pub(crate) mod test { C2 = 2, } - // unsafe impl InterruptNumber for Interrupt { - // const MAX_INTERRUPT_NUMBER: u16 = 4; + unsafe impl InterruptNumber for Interrupt { + const MAX_INTERRUPT_NUMBER: usize = 4; - // #[inline] - // fn number(self) -> u16 { - // self as _ - // } + #[inline] + fn number(self) -> usize { + self as _ + } #[inline] - fn from_number(number: u16) -> Result { - if number > Self::MAX_INTERRUPT_NUMBER || number == 0 { - Err(Error::InvalidVariant(number as usize)) - } else { - // SAFETY: valid interrupt number - Ok(unsafe { core::mem::transmute(number) }) + fn from_number(number: usize) -> Result { + match number { + 1 => Ok(Interrupt::I1), + 2 => Ok(Interrupt::I2), + 3 => Ok(Interrupt::I3), + 4 => Ok(Interrupt::I4), + _ => Err(Error::InvalidVariant(number)), } } } unsafe impl ExternalInterruptNumber for Interrupt {} - // unsafe impl PriorityNumber for Priority { - // const MAX_PRIORITY_NUMBER: u8 = 3; + unsafe impl PriorityNumber for Priority { + const MAX_PRIORITY_NUMBER: u8 = 3; - // #[inline] - // fn number(self) -> u8 { - // self as _ - // } + #[inline] + fn number(self) -> u8 { + self as _ + } #[inline] fn from_number(number: u8) -> Result { - if number > Self::MAX_PRIORITY_NUMBER { - Err(Error::InvalidVariant(number as usize)) - } else { - // SAFETY: valid priority number - Ok(unsafe { core::mem::transmute(number) }) + match number { + 0 => Ok(Priority::P0), + 1 => Ok(Priority::P1), + 2 => Ok(Priority::P2), + 3 => Ok(Priority::P3), + _ => Err(Error::InvalidVariant(number as usize)), } } } - // unsafe impl HartIdNumber for Context { - // const MAX_HART_ID_NUMBER: u16 = 2; + unsafe impl HartIdNumber for Context { + const MAX_HART_ID_NUMBER: u16 = 2; - // #[inline] - // fn number(self) -> u16 { - // self as _ - // } + #[inline] + fn number(self) -> u16 { + self as _ + } #[inline] fn from_number(number: u16) -> Result { - if number > Self::MAX_HART_ID_NUMBER { - Err(Error::InvalidVariant(number as usize)) - } else { - // SAFETY: valid context number - Ok(unsafe { core::mem::transmute(number) }) + match number { + 0 => Ok(Context::C0), + 1 => Ok(Context::C1), + 2 => Ok(Context::C2), + _ => Err(Error::InvalidVariant(number as usize)), } } } diff --git a/riscv/Cargo.toml b/riscv/Cargo.toml index 20b10518..cf27d5e2 100644 --- a/riscv/Cargo.toml +++ b/riscv/Cargo.toml @@ -20,11 +20,15 @@ targets = [ ] [features] -default = ["riscv-pac/default"] +default = ["riscv-macros"] s-mode = [] critical-section-single-hart = ["critical-section/restore-state-bool"] [dependencies] critical-section = "1.1.2" embedded-hal = "1.0.0" -riscv-pac = { path = "../riscv-pac", version = "0.1.2", default-features = false } +riscv-pac = { path = "../riscv-pac", version = "0.1.2" } +riscv-macros = { path = "macros", version = "0.1.0", optional = true } + +[dev-dependencies] +trybuild = "1.0" diff --git a/riscv-pac/macros/Cargo.toml b/riscv/macros/Cargo.toml similarity index 75% rename from riscv-pac/macros/Cargo.toml rename to riscv/macros/Cargo.toml index c559182f..94ef7090 100644 --- a/riscv-pac/macros/Cargo.toml +++ b/riscv/macros/Cargo.toml @@ -3,11 +3,11 @@ authors = [ "The RISC-V Team ", ] categories = ["embedded", "no-std"] -description = "Derive macros re-exported in `riscv-pac`" -documentation = "https://docs.rs/riscv-rt" +description = "Procedural macros re-exported in `riscv`" +documentation = "https://docs.rs/riscv" keywords = ["riscv", "register", "peripheral"] license = "MIT OR Apache-2.0" -name = "riscv-pac-macros" +name = "riscv-macros" repository = "https://github.com/rust-embedded/riscv" version = "0.1.0" edition = "2021" diff --git a/riscv-pac/macros/src/lib.rs b/riscv/macros/src/lib.rs similarity index 96% rename from riscv-pac/macros/src/lib.rs rename to riscv/macros/src/lib.rs index 7924372a..898856cb 100644 --- a/riscv-pac/macros/src/lib.rs +++ b/riscv/macros/src/lib.rs @@ -195,6 +195,7 @@ impl PacEnumItem { fn vector_table(&self) -> TokenStream2 { let mut asm = String::from( r#" +#[cfg(all(feature = "v-trap", any(target_arch = "riscv32", target_arch = "riscv64")))] core::arch::global_asm!(" .section .trap, \"ax\" .global _vector_table @@ -245,7 +246,7 @@ core::arch::global_asm!(" // Push the trait implementation res.push(quote! { - unsafe impl riscv_pac::#trait_name for #name { + unsafe impl riscv::#trait_name for #name { const #const_name: #num_type = #max_discriminant; #[inline] @@ -254,10 +255,10 @@ core::arch::global_asm!(" } #[inline] - fn from_number(number: #num_type) -> Result { + fn from_number(number: #num_type) -> riscv::result::Result { match number { #(#valid_matches,)* - _ => Err(number), + _ => Err(riscv::result::Error::InvalidVariant(number as _)), } } } @@ -271,7 +272,7 @@ core::arch::global_asm!(" let dispatch_fn_name = interrupt_type.dispatch_fn_name(); // Push the marker trait implementation - res.push(quote! { unsafe impl riscv_pac::#marker_trait_name for #name {} }); + res.push(quote! { unsafe impl riscv::#marker_trait_name for #name {} }); let interrupt_handlers = self.interrupt_handlers(); let interrupt_array = self.interrupt_array(); @@ -330,7 +331,7 @@ core::arch::global_asm!(" /// # Example /// /// ```rust -/// use riscv_pac::*; +/// use riscv::*; /// /// #[repr(usize)] /// #[pac_enum(unsafe ExceptionNumber)] diff --git a/riscv/src/interrupt.rs b/riscv/src/interrupt.rs index 90d9a1da..697d0345 100644 --- a/riscv/src/interrupt.rs +++ b/riscv/src/interrupt.rs @@ -2,7 +2,10 @@ // NOTE: Adapted from cortex-m/src/interrupt.rs -pub use riscv_pac::{CoreInterruptNumber, ExceptionNumber, InterruptNumber}; // re-export useful riscv-pac traits +use crate::result::Result; + +// re-export useful riscv-pac traits +pub use riscv_pac::{CoreInterruptNumber, ExceptionNumber, InterruptNumber}; pub mod machine; pub mod supervisor; @@ -38,20 +41,14 @@ impl Trap { /// Tries to convert the generic trap cause to a target-specific trap cause #[inline] - pub fn try_into(self) -> Result, TrapError> + pub fn try_into(self) -> Result> where I: CoreInterruptNumber, E: ExceptionNumber, { match self { - Trap::Interrupt(code) => match I::from_number(code) { - Ok(interrupt) => Ok(Trap::Interrupt(interrupt)), - Err(code) => Err(TrapError::InvalidInterrupt(code)), - }, - Trap::Exception(code) => match E::from_number(code) { - Ok(exception) => Ok(Trap::Exception(exception)), - Err(code) => Err(TrapError::InvalidException(code)), - }, + Trap::Interrupt(code) => Ok(Trap::Interrupt(I::from_number(code)?)), + Trap::Exception(code) => Ok(Trap::Exception(E::from_number(code)?)), } } } @@ -65,7 +62,7 @@ impl Trap { /// Tries to convert the generic trap cause to a target-specific trap cause #[inline] - pub fn try_from(trap: Trap) -> Result { + pub fn try_from(trap: Trap) -> Result { trap.try_into() } } diff --git a/riscv/src/interrupt/machine.rs b/riscv/src/interrupt/machine.rs index 40233f56..d88ceb46 100644 --- a/riscv/src/interrupt/machine.rs +++ b/riscv/src/interrupt/machine.rs @@ -1,8 +1,11 @@ use crate::{ - interrupt::{Trap, TrapError}, + interrupt::Trap, register::{mcause, mepc, mstatus}, }; -use riscv_pac::{CoreInterruptNumber, ExceptionNumber, InterruptNumber}; +use riscv_pac::{ + result::{Error, Result}, + CoreInterruptNumber, ExceptionNumber, InterruptNumber, +}; /// Standard M-mode RISC-V interrupts #[derive(Copy, Clone, Debug, PartialEq, Eq)] @@ -26,7 +29,7 @@ unsafe impl InterruptNumber for Interrupt { } #[inline] - fn from_number(value: usize) -> Result { + fn from_number(value: usize) -> Result { match value { 1 => Ok(Self::SupervisorSoft), 3 => Ok(Self::MachineSoft), @@ -34,7 +37,7 @@ unsafe impl InterruptNumber for Interrupt { 7 => Ok(Self::MachineTimer), 9 => Ok(Self::SupervisorExternal), 11 => Ok(Self::MachineExternal), - _ => Err(value), + _ => Err(Error::InvalidVariant(value)), } } } @@ -72,7 +75,7 @@ unsafe impl ExceptionNumber for Exception { } #[inline] - fn from_number(value: usize) -> Result { + fn from_number(value: usize) -> Result { match value { 0 => Ok(Self::InstructionMisaligned), 1 => Ok(Self::InstructionFault), @@ -88,7 +91,7 @@ unsafe impl ExceptionNumber for Exception { 12 => Ok(Self::InstructionPageFault), 13 => Ok(Self::LoadPageFault), 15 => Ok(Self::StorePageFault), - _ => Err(value), + _ => Err(Error::InvalidVariant(value)), } } } @@ -115,7 +118,7 @@ pub unsafe fn enable() { /// This function expects the target-specific interrupt and exception types. /// If the raw cause is not a valid interrupt or exception for the target, it returns an error. #[inline] -pub fn try_cause() -> Result, TrapError> { +pub fn try_cause() -> Result> { mcause::read().cause().try_into() } @@ -207,17 +210,17 @@ mod test { #[test] fn test_interrupt() { assert_eq!(Interrupt::from_number(1), Ok(SupervisorSoft)); - assert_eq!(Interrupt::from_number(2), Err(2)); + assert_eq!(Interrupt::from_number(2), Err(Error::InvalidVariant(2))); assert_eq!(Interrupt::from_number(3), Ok(MachineSoft)); - assert_eq!(Interrupt::from_number(4), Err(4)); + assert_eq!(Interrupt::from_number(4), Err(Error::InvalidVariant(4))); assert_eq!(Interrupt::from_number(5), Ok(SupervisorTimer)); - assert_eq!(Interrupt::from_number(6), Err(6)); + assert_eq!(Interrupt::from_number(6), Err(Error::InvalidVariant(6))); assert_eq!(Interrupt::from_number(7), Ok(MachineTimer)); - assert_eq!(Interrupt::from_number(8), Err(8)); + assert_eq!(Interrupt::from_number(8), Err(Error::InvalidVariant(8))); assert_eq!(Interrupt::from_number(9), Ok(SupervisorExternal)); - assert_eq!(Interrupt::from_number(10), Err(10)); + assert_eq!(Interrupt::from_number(10), Err(Error::InvalidVariant(10))); assert_eq!(Interrupt::from_number(11), Ok(MachineExternal)); - assert_eq!(Interrupt::from_number(12), Err(12)); + assert_eq!(Interrupt::from_number(12), Err(Error::InvalidVariant(12))); assert_eq!(SupervisorSoft.number(), 1); assert_eq!(MachineSoft.number(), 3); @@ -241,13 +244,13 @@ mod test { assert_eq!(Exception::from_number(7), Ok(StoreFault)); assert_eq!(Exception::from_number(8), Ok(UserEnvCall)); assert_eq!(Exception::from_number(9), Ok(SupervisorEnvCall)); - assert_eq!(Exception::from_number(10), Err(10)); + assert_eq!(Exception::from_number(10), Err(Error::InvalidVariant(10))); assert_eq!(Exception::from_number(11), Ok(MachineEnvCall)); assert_eq!(Exception::from_number(12), Ok(InstructionPageFault)); assert_eq!(Exception::from_number(13), Ok(LoadPageFault)); - assert_eq!(Exception::from_number(14), Err(14)); + assert_eq!(Exception::from_number(14), Err(Error::InvalidVariant(14))); assert_eq!(Exception::from_number(15), Ok(StorePageFault)); - assert_eq!(Exception::from_number(16), Err(16)); + assert_eq!(Exception::from_number(16), Err(Error::InvalidVariant(16))); assert_eq!(InstructionMisaligned.number(), 0); assert_eq!(InstructionFault.number(), 1); diff --git a/riscv/src/interrupt/supervisor.rs b/riscv/src/interrupt/supervisor.rs index 1d032e6f..ed25d236 100644 --- a/riscv/src/interrupt/supervisor.rs +++ b/riscv/src/interrupt/supervisor.rs @@ -1,8 +1,11 @@ use crate::{ - interrupt::{Trap, TrapError}, + interrupt::Trap, register::{scause, sepc, sstatus}, }; -use riscv_pac::{CoreInterruptNumber, ExceptionNumber, InterruptNumber}; +use riscv_pac::{ + result::{Error, Result}, + CoreInterruptNumber, ExceptionNumber, InterruptNumber, +}; /// Interrupt #[derive(Copy, Clone, Debug, Eq, PartialEq)] @@ -23,12 +26,12 @@ unsafe impl InterruptNumber for Interrupt { } #[inline] - fn from_number(value: usize) -> Result { + fn from_number(value: usize) -> Result { match value { 1 => Ok(Self::SupervisorSoft), 5 => Ok(Self::SupervisorTimer), 9 => Ok(Self::SupervisorExternal), - _ => Err(value), + _ => Err(Error::InvalidVariant(value)), } } } @@ -65,7 +68,7 @@ unsafe impl ExceptionNumber for Exception { } #[inline] - fn from_number(value: usize) -> Result { + fn from_number(value: usize) -> Result { match value { 0 => Ok(Self::InstructionMisaligned), 1 => Ok(Self::InstructionFault), @@ -80,7 +83,7 @@ unsafe impl ExceptionNumber for Exception { 12 => Ok(Self::InstructionPageFault), 13 => Ok(Self::LoadPageFault), 15 => Ok(Self::StorePageFault), - _ => Err(value), + _ => Err(Error::InvalidVariant(value)), } } } @@ -107,7 +110,7 @@ pub unsafe fn enable() { /// This function expects the target-specific interrupt and exception types. /// If the raw cause is not a valid interrupt or exception for the target, it returns an error. #[inline] -pub fn try_cause() -> Result, TrapError> { +pub fn try_cause() -> Result> { scause::read().cause().try_into() } @@ -198,17 +201,17 @@ mod test { #[test] fn test_interrupt() { assert_eq!(Interrupt::from_number(1), Ok(SupervisorSoft)); - assert_eq!(Interrupt::from_number(2), Err(2)); - assert_eq!(Interrupt::from_number(3), Err(3)); - assert_eq!(Interrupt::from_number(4), Err(4)); + assert_eq!(Interrupt::from_number(2), Err(Error::InvalidVariant(2))); + assert_eq!(Interrupt::from_number(3), Err(Error::InvalidVariant(3))); + assert_eq!(Interrupt::from_number(4), Err(Error::InvalidVariant(4))); assert_eq!(Interrupt::from_number(5), Ok(SupervisorTimer)); - assert_eq!(Interrupt::from_number(6), Err(6)); - assert_eq!(Interrupt::from_number(7), Err(7)); - assert_eq!(Interrupt::from_number(8), Err(8)); + assert_eq!(Interrupt::from_number(6), Err(Error::InvalidVariant(6))); + assert_eq!(Interrupt::from_number(7), Err(Error::InvalidVariant(7))); + assert_eq!(Interrupt::from_number(8), Err(Error::InvalidVariant(8))); assert_eq!(Interrupt::from_number(9), Ok(SupervisorExternal)); - assert_eq!(Interrupt::from_number(10), Err(10)); - assert_eq!(Interrupt::from_number(11), Err(11)); - assert_eq!(Interrupt::from_number(12), Err(12)); + assert_eq!(Interrupt::from_number(10), Err(Error::InvalidVariant(10))); + assert_eq!(Interrupt::from_number(11), Err(Error::InvalidVariant(11))); + assert_eq!(Interrupt::from_number(12), Err(Error::InvalidVariant(12))); assert_eq!(SupervisorSoft.number(), 1); assert_eq!(SupervisorTimer.number(), 5); @@ -229,13 +232,13 @@ mod test { assert_eq!(Exception::from_number(7), Ok(StoreFault)); assert_eq!(Exception::from_number(8), Ok(UserEnvCall)); assert_eq!(Exception::from_number(9), Ok(SupervisorEnvCall)); - assert_eq!(Exception::from_number(10), Err(10)); - assert_eq!(Exception::from_number(11), Err(11)); + assert_eq!(Exception::from_number(10), Err(Error::InvalidVariant(10))); + assert_eq!(Exception::from_number(11), Err(Error::InvalidVariant(11))); assert_eq!(Exception::from_number(12), Ok(InstructionPageFault)); assert_eq!(Exception::from_number(13), Ok(LoadPageFault)); - assert_eq!(Exception::from_number(14), Err(14)); + assert_eq!(Exception::from_number(14), Err(Error::InvalidVariant(14))); assert_eq!(Exception::from_number(15), Ok(StorePageFault)); - assert_eq!(Exception::from_number(16), Err(16)); + assert_eq!(Exception::from_number(16), Err(Error::InvalidVariant(16))); assert_eq!(InstructionMisaligned.number(), 0); assert_eq!(InstructionFault.number(), 1); diff --git a/riscv/src/lib.rs b/riscv/src/lib.rs index daa859f5..6290c18c 100644 --- a/riscv/src/lib.rs +++ b/riscv/src/lib.rs @@ -40,6 +40,10 @@ pub(crate) mod bits; pub mod delay; pub mod interrupt; pub mod register; + +// Re-export crates of the RISC-V ecosystem +#[cfg(feature = "riscv-macros")] +pub use riscv_macros::*; pub use riscv_pac::*; #[macro_use] diff --git a/riscv-pac/tests/test.rs b/riscv/tests/test.rs similarity index 100% rename from riscv-pac/tests/test.rs rename to riscv/tests/test.rs diff --git a/riscv-pac/tests/ui/fail_empty_macro.rs b/riscv/tests/ui/fail_empty_macro.rs similarity index 82% rename from riscv-pac/tests/ui/fail_empty_macro.rs rename to riscv/tests/ui/fail_empty_macro.rs index a47a5711..8891da0a 100644 --- a/riscv-pac/tests/ui/fail_empty_macro.rs +++ b/riscv/tests/ui/fail_empty_macro.rs @@ -1,4 +1,4 @@ -#[riscv_pac::pac_enum] +#[riscv::pac_enum] #[derive(Clone, Copy, Debug, PartialEq)] enum Interrupt { I1 = 1, diff --git a/riscv/tests/ui/fail_empty_macro.stderr b/riscv/tests/ui/fail_empty_macro.stderr new file mode 100644 index 00000000..28c594b7 --- /dev/null +++ b/riscv/tests/ui/fail_empty_macro.stderr @@ -0,0 +1,7 @@ +error: unexpected end of input, expected `unsafe` + --> tests/ui/fail_empty_macro.rs:1:1 + | +1 | #[riscv::pac_enum] + | ^^^^^^^^^^^^^^^^^^ + | + = note: this error originates in the attribute macro `riscv::pac_enum` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/riscv-pac/tests/ui/fail_no_unsafe.rs b/riscv/tests/ui/fail_no_unsafe.rs similarity index 73% rename from riscv-pac/tests/ui/fail_no_unsafe.rs rename to riscv/tests/ui/fail_no_unsafe.rs index 865a68fd..a304fa9e 100644 --- a/riscv-pac/tests/ui/fail_no_unsafe.rs +++ b/riscv/tests/ui/fail_no_unsafe.rs @@ -1,4 +1,4 @@ -#[riscv_pac::pac_enum(InterruptNumber)] +#[riscv::pac_enum(InterruptNumber)] #[derive(Clone, Copy, Debug, PartialEq)] enum Interrupt { I1 = 1, diff --git a/riscv/tests/ui/fail_no_unsafe.stderr b/riscv/tests/ui/fail_no_unsafe.stderr new file mode 100644 index 00000000..68fec6f8 --- /dev/null +++ b/riscv/tests/ui/fail_no_unsafe.stderr @@ -0,0 +1,5 @@ +error: expected `unsafe` + --> tests/ui/fail_no_unsafe.rs:1:19 + | +1 | #[riscv::pac_enum(InterruptNumber)] + | ^^^^^^^^^^^^^^^ diff --git a/riscv-pac/tests/ui/fail_unknown_trait.rs b/riscv/tests/ui/fail_unknown_trait.rs similarity index 70% rename from riscv-pac/tests/ui/fail_unknown_trait.rs rename to riscv/tests/ui/fail_unknown_trait.rs index 82ebdc52..dc6c5d44 100644 --- a/riscv-pac/tests/ui/fail_unknown_trait.rs +++ b/riscv/tests/ui/fail_unknown_trait.rs @@ -1,4 +1,4 @@ -#[riscv_pac::pac_enum(unsafe InterruptNumber)] +#[riscv::pac_enum(unsafe InterruptNumber)] #[derive(Clone, Copy, Debug, PartialEq)] enum Interrupt { I1 = 1, diff --git a/riscv-pac/tests/ui/fail_unknown_trait.stderr b/riscv/tests/ui/fail_unknown_trait.stderr similarity index 50% rename from riscv-pac/tests/ui/fail_unknown_trait.stderr rename to riscv/tests/ui/fail_unknown_trait.stderr index 4f03439d..337f8548 100644 --- a/riscv-pac/tests/ui/fail_unknown_trait.stderr +++ b/riscv/tests/ui/fail_unknown_trait.stderr @@ -1,5 +1,5 @@ error: Unknown trait name. Expected: 'ExceptionNumber', 'CoreInterruptNumber', 'ExternalInterruptNumber', 'PriorityNumber', or 'HartIdNumber' - --> tests/ui/fail_unknown_trait.rs:1:30 + --> tests/ui/fail_unknown_trait.rs:1:26 | -1 | #[riscv_pac::pac_enum(unsafe InterruptNumber)] - | ^^^^^^^^^^^^^^^ +1 | #[riscv::pac_enum(unsafe InterruptNumber)] + | ^^^^^^^^^^^^^^^ diff --git a/riscv-pac/tests/ui/pass_test.rs b/riscv/tests/ui/pass_test.rs similarity index 79% rename from riscv-pac/tests/ui/pass_test.rs rename to riscv/tests/ui/pass_test.rs index 07141391..c80ead3e 100644 --- a/riscv-pac/tests/ui/pass_test.rs +++ b/riscv/tests/ui/pass_test.rs @@ -1,6 +1,6 @@ -use riscv_pac::*; +use riscv::result::Error; +use riscv::*; -#[repr(usize)] #[pac_enum(unsafe ExceptionNumber)] #[derive(Clone, Copy, Debug, Eq, PartialEq)] enum Exception { @@ -8,7 +8,6 @@ enum Exception { E3 = 3, } -#[repr(usize)] #[pac_enum(unsafe CoreInterruptNumber)] #[derive(Clone, Copy, Debug, Eq, PartialEq)] enum Interrupt { @@ -18,7 +17,6 @@ enum Interrupt { I7 = 7, } -#[repr(u8)] #[pac_enum(unsafe PriorityNumber)] #[derive(Clone, Copy, Debug, Eq, PartialEq)] enum Priority { @@ -28,7 +26,6 @@ enum Priority { P3 = 3, } -#[repr(u16)] #[pac_enum(unsafe HartIdNumber)] #[derive(Clone, Copy, Debug, Eq, PartialEq)] enum HartId { @@ -58,11 +55,11 @@ fn main() { assert_eq!(Exception::E1.number(), 1); assert_eq!(Exception::E3.number(), 3); - assert_eq!(Exception::from_number(0), Err(0)); + assert_eq!(Exception::from_number(0), Err(Error::InvalidVariant(0))); assert_eq!(Exception::from_number(1), Ok(Exception::E1)); - assert_eq!(Exception::from_number(2), Err(2)); + assert_eq!(Exception::from_number(2), Err(Error::InvalidVariant(2))); assert_eq!(Exception::from_number(3), Ok(Exception::E3)); - assert_eq!(Exception::from_number(4), Err(4)); + assert_eq!(Exception::from_number(4), Err(Error::InvalidVariant(4))); assert_eq!(Exception::MAX_EXCEPTION_NUMBER, 3); @@ -71,13 +68,13 @@ fn main() { assert_eq!(Interrupt::I4.number(), 4); assert_eq!(Interrupt::I7.number(), 7); - assert_eq!(Interrupt::from_number(0), Err(0)); + assert_eq!(Interrupt::from_number(0), Err(Error::InvalidVariant(0))); assert_eq!(Interrupt::from_number(1), Ok(Interrupt::I1)); assert_eq!(Interrupt::from_number(2), Ok(Interrupt::I2)); - assert_eq!(Interrupt::from_number(3), Err(3)); + assert_eq!(Interrupt::from_number(3), Err(Error::InvalidVariant(3))); assert_eq!(Interrupt::from_number(4), Ok(Interrupt::I4)); - assert_eq!(Interrupt::from_number(5), Err(5)); - assert_eq!(Interrupt::from_number(6), Err(6)); + assert_eq!(Interrupt::from_number(5), Err(Error::InvalidVariant(5))); + assert_eq!(Interrupt::from_number(6), Err(Error::InvalidVariant(6))); assert_eq!(Interrupt::from_number(7), Ok(Interrupt::I7)); assert_eq!(Interrupt::MAX_INTERRUPT_NUMBER, 7); @@ -102,7 +99,7 @@ fn main() { assert_eq!(Priority::from_number(1), Ok(Priority::P1)); assert_eq!(Priority::from_number(2), Ok(Priority::P2)); assert_eq!(Priority::from_number(3), Ok(Priority::P3)); - assert_eq!(Priority::from_number(4), Err(4)); + assert_eq!(Priority::from_number(4), Err(Error::InvalidVariant(4))); assert_eq!(Priority::MAX_PRIORITY_NUMBER, 3); @@ -113,7 +110,7 @@ fn main() { assert_eq!(HartId::from_number(0), Ok(HartId::H0)); assert_eq!(HartId::from_number(1), Ok(HartId::H1)); assert_eq!(HartId::from_number(2), Ok(HartId::H2)); - assert_eq!(HartId::from_number(3), Err(3)); + assert_eq!(HartId::from_number(3), Err(Error::InvalidVariant(3))); assert_eq!(HartId::MAX_HART_ID_NUMBER, 2); }