浏览代码

rustsbi: pass cargo test on docs

Make test cases on hart mask, fix internal bug

Signed-off-by: luojia65 <[email protected]>
luojia65 3 年之前
父节点
当前提交
d40af8c309
共有 6 个文件被更改,包括 64 次插入15 次删除
  1. 1 3
      CHANGELOG.md
  2. 4 2
      src/ecall.rs
  3. 36 3
      src/hart_mask.rs
  4. 3 0
      src/lib.rs
  5. 2 2
      src/pmu.rs
  6. 18 5
      src/privileged.rs

+ 1 - 3
CHANGELOG.md

@@ -17,18 +17,16 @@ This update fixes a severe bug on IPI module. The previous version of RustSBI di
 module on SBI v0.3 format. Users are encouraged to use 0.2.1 and newer version instead of yanked 0.2.0 version.
 module on SBI v0.3 format. Users are encouraged to use 0.2.1 and newer version instead of yanked 0.2.0 version.
 
 
 ### Modified
 ### Modified
-
 - Internal speed up to new SBI v0.3+ IPI procedure
 - Internal speed up to new SBI v0.3+ IPI procedure
 - Reduce code size by inlining internal functions
 - Reduce code size by inlining internal functions
 
 
 ### Fixed
 ### Fixed
-
 - Severe bug on IPI does not follow new SBI version convention rule
 - Severe bug on IPI does not follow new SBI version convention rule
+- Pass cargo test on docs, add test cases on hart mask
 
 
 ## [0.2.0] - 2022-02-13
 ## [0.2.0] - 2022-02-13
 
 
 ### Added
 ### Added
-
 - Support for RISC-V SBI v0.3 Specification
 - Support for RISC-V SBI v0.3 Specification
 - S-level Illegal instruction exception is now delegated into S-level software handler
 - S-level Illegal instruction exception is now delegated into S-level software handler
 - Support RFENCE extension in RustSBI framework
 - Support RFENCE extension in RustSBI framework

+ 4 - 2
src/ecall.rs

@@ -48,8 +48,10 @@ const LEGACY_SHUTDOWN: usize = 0x08;
 /// A typical usage:
 /// A typical usage:
 ///
 ///
 /// ```no_run
 /// ```no_run
-/// #[exception]
-/// fn handle_exception(ctx: &mut TrapFrame) {
+/// # use riscv::register::{mepc, mcause::{self, Trap, Exception}};
+/// # struct TrapFrame { a0: usize, a1: usize, a2: usize, a3: usize,
+/// # a4: usize, a5: usize, a6: usize, a7: usize }
+/// extern "C" fn rust_handle_exception(ctx: &mut TrapFrame) {
 ///     if mcause::read().cause() == Trap::Exception(Exception::SupervisorEnvCall) {
 ///     if mcause::read().cause() == Trap::Exception(Exception::SupervisorEnvCall) {
 ///         let params = [ctx.a0, ctx.a1, ctx.a2, ctx.a3, ctx.a4, ctx.a5];
 ///         let params = [ctx.a0, ctx.a1, ctx.a2, ctx.a3, ctx.a4, ctx.a5];
 ///         let ans = rustsbi::ecall(ctx.a7, ctx.a6, params);
 ///         let ans = rustsbi::ecall(ctx.a7, ctx.a6, params);

+ 36 - 3
src/hart_mask.rs

@@ -1,5 +1,3 @@
-use core::mem::size_of;
-
 /// Hart mask structure reference
 /// Hart mask structure reference
 #[derive(Debug, Clone)]
 #[derive(Debug, Clone)]
 pub struct HartMask {
 pub struct HartMask {
@@ -33,7 +31,7 @@ impl HartMask {
                     // hart_id < hart_mask_base, not in current mask range
                     // hart_id < hart_mask_base, not in current mask range
                     return false;
                     return false;
                 };
                 };
-                if idx > size_of::<usize>() {
+                if idx >= usize::BITS as usize {
                     // hart_idx >= hart_mask_base + XLEN, not in current mask range
                     // hart_idx >= hart_mask_base + XLEN, not in current mask range
                     return false;
                     return false;
                 }
                 }
@@ -113,3 +111,38 @@ unsafe fn get_vaddr_usize(vaddr_ptr: *const usize) -> usize {
         }
         }
     }
     }
 }
 }
+
+#[cfg(test)]
+mod tests {
+    use super::HartMask;
+
+    #[test]
+    fn rustsbi_hart_mask() {
+        let mask = HartMask::from_mask_base(0b1, 400);
+        assert!(!mask.has_bit(0));
+        assert!(mask.has_bit(400));
+        assert!(!mask.has_bit(401));
+        let mask = HartMask::from_mask_base(0b110, 500);
+        assert!(!mask.has_bit(0));
+        assert!(!mask.has_bit(500));
+        assert!(mask.has_bit(501));
+        assert!(mask.has_bit(502));
+        assert!(!mask.has_bit(500 + (usize::BITS as usize)));
+        let max_bit = 1 << (usize::BITS - 1);
+        let mask = HartMask::from_mask_base(max_bit, 600);
+        assert!(mask.has_bit(600 + (usize::BITS as usize) - 1));
+        assert!(!mask.has_bit(600 + (usize::BITS as usize)));
+        let mask = HartMask::from_mask_base(0b11, usize::MAX - 1);
+        assert!(!mask.has_bit(usize::MAX - 2));
+        assert!(mask.has_bit(usize::MAX - 1));
+        assert!(mask.has_bit(usize::MAX));
+        assert!(!mask.has_bit(0));
+        // hart_mask_base == usize::MAX is special, it means hart_mask should be ignored
+        // and this hart mask contains all harts available
+        let mask = HartMask::from_mask_base(0, usize::MAX);
+        for i in 0..5 {
+            assert!(mask.has_bit(i));
+        }
+        assert!(mask.has_bit(usize::MAX));
+    }
+}

+ 3 - 0
src/lib.rs

@@ -45,6 +45,9 @@
 //! In Rust, here is an example to call SBI functions using inline assembly:
 //! In Rust, here is an example to call SBI functions using inline assembly:
 //!
 //!
 //! ```no_run
 //! ```no_run
+//! # #[repr(C)] struct SbiRet { error: usize, value: usize }
+//! # const EXTENSION_BASE: usize = 0x10;
+//! # const FUNCTION_BASE_GET_SPEC_VERSION: usize = 0x0;
 //! #[inline(always)]
 //! #[inline(always)]
 //! fn sbi_call(extension: usize, function: usize, arg0: usize, arg1: usize) -> SbiRet {
 //! fn sbi_call(extension: usize, function: usize, arg0: usize, arg1: usize) -> SbiRet {
 //!     let (error, value);
 //!     let (error, value);

+ 2 - 2
src/pmu.rs

@@ -33,7 +33,7 @@ use alloc::boxed::Box;
 ///
 ///
 /// The event_idx is a 20 bits wide number encoded as follows:
 /// The event_idx is a 20 bits wide number encoded as follows:
 ///
 ///
-/// ```rust
+/// ```text
 ///    event_idx[19:16] = type;
 ///    event_idx[19:16] = type;
 ///    event_idx[15:0] = code;
 ///    event_idx[15:0] = code;
 /// ```
 /// ```
@@ -47,7 +47,7 @@ pub trait Pmu: Send {
     ///
     ///
     /// The `counter_info` returned by this SBI call is encoded as follows:
     /// The `counter_info` returned by this SBI call is encoded as follows:
     ///
     ///
-    /// ```rust
+    /// ```text
     ///     counter_info[11:0] = CSR; // (12bit CSR number)
     ///     counter_info[11:0] = CSR; // (12bit CSR number)
     ///     counter_info[17:12] = Width; // (One less than number of bits in CSR)
     ///     counter_info[17:12] = Width; // (One less than number of bits in CSR)
     ///     counter_info[XLEN-2:18] = Reserved; // Reserved for future use
     ///     counter_info[XLEN-2:18] = Reserved; // Reserved for future use

+ 18 - 5
src/privileged.rs

@@ -16,20 +16,33 @@
 ///
 ///
 /// # Example
 /// # Example
 ///
 ///
-/// ```rust
+/// ```no_run
+/// # use riscv::register::{mepc, mstatus::{self, MPP}, mhartid};
+/// # extern "C" fn rust_main(hart_id: usize, opauqe: usize) {
+/// # fn read_address_from_boot_media() -> usize { 0 /* */ }
+/// # let s_mode_start = read_address_from_boot_media(); // read from boot media
 /// unsafe {
 /// unsafe {
-///     mepc::write(_s_mode_start as usize);
+///     mepc::write(s_mode_start);
 ///     mstatus::set_mpp(MPP::Supervisor);
 ///     mstatus::set_mpp(MPP::Supervisor);
-///     enter_privileged(mhartid::read(), dtb_pa);
+///     rustsbi::enter_privileged(mhartid::read(), opauqe);
 /// }
 /// }
+/// # }
 /// ```
 /// ```
 #[inline]
 #[inline]
 pub unsafe fn enter_privileged(mhartid: usize, opaque: usize) -> ! {
 pub unsafe fn enter_privileged(mhartid: usize, opaque: usize) -> ! {
-    core::arch::asm!(
+    match () {
+        #[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] // pass cargo test
+        () => core::arch::asm!(
         "csrrw  sp, mscratch, sp",
         "csrrw  sp, mscratch, sp",
         "mret",
         "mret",
         in("a0") mhartid,
         in("a0") mhartid,
         in("a1") opaque,
         in("a1") opaque,
         options(nomem, noreturn)
         options(nomem, noreturn)
-    )
+        ),
+        #[cfg(not(any(target_arch = "riscv32", target_arch = "riscv64")))]
+        () => {
+            let _ = (mhartid, opaque);
+            unimplemented!("not RISC-V architecture")
+        },
+    }
 }
 }