Jelajahi Sumber

rustsbi: pass cargo test on docs

Make test cases on hart mask, fix internal bug

Signed-off-by: luojia65 <[email protected]>
luojia65 3 tahun lalu
induk
melakukan
d40af8c309
6 mengubah file dengan 64 tambahan dan 15 penghapusan
  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.
 
 ### Modified
-
 - Internal speed up to new SBI v0.3+ IPI procedure
 - Reduce code size by inlining internal functions
 
 ### Fixed
-
 - 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
 
 ### Added
-
 - Support for RISC-V SBI v0.3 Specification
 - S-level Illegal instruction exception is now delegated into S-level software handler
 - Support RFENCE extension in RustSBI framework

+ 4 - 2
src/ecall.rs

@@ -48,8 +48,10 @@ const LEGACY_SHUTDOWN: usize = 0x08;
 /// A typical usage:
 ///
 /// ```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) {
 ///         let params = [ctx.a0, ctx.a1, ctx.a2, ctx.a3, ctx.a4, ctx.a5];
 ///         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
 #[derive(Debug, Clone)]
 pub struct HartMask {
@@ -33,7 +31,7 @@ impl HartMask {
                     // hart_id < hart_mask_base, not in current mask range
                     return false;
                 };
-                if idx > size_of::<usize>() {
+                if idx >= usize::BITS as usize {
                     // hart_idx >= hart_mask_base + XLEN, not in current mask range
                     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:
 //!
 //! ```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)]
 //! fn sbi_call(extension: usize, function: usize, arg0: usize, arg1: usize) -> SbiRet {
 //!     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:
 ///
-/// ```rust
+/// ```text
 ///    event_idx[19:16] = type;
 ///    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:
     ///
-    /// ```rust
+    /// ```text
     ///     counter_info[11:0] = CSR; // (12bit CSR number)
     ///     counter_info[17:12] = Width; // (One less than number of bits in CSR)
     ///     counter_info[XLEN-2:18] = Reserved; // Reserved for future use

+ 18 - 5
src/privileged.rs

@@ -16,20 +16,33 @@
 ///
 /// # 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 {
-///     mepc::write(_s_mode_start as usize);
+///     mepc::write(s_mode_start);
 ///     mstatus::set_mpp(MPP::Supervisor);
-///     enter_privileged(mhartid::read(), dtb_pa);
+///     rustsbi::enter_privileged(mhartid::read(), opauqe);
 /// }
+/// # }
 /// ```
 #[inline]
 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",
         "mret",
         in("a0") mhartid,
         in("a1") opaque,
         options(nomem, noreturn)
-    )
+        ),
+        #[cfg(not(any(target_arch = "riscv32", target_arch = "riscv64")))]
+        () => {
+            let _ = (mhartid, opaque);
+            unimplemented!("not RISC-V architecture")
+        },
+    }
 }