Prechádzať zdrojové kódy

refactor(rfence): remove unnecessary synchronization in rfence extension implementation

guttatus 7 mesiacov pred
rodič
commit
3146873a8b
7 zmenil súbory, kde vykonal 39 pridanie a 76 odobranie
  1. 1 2
      src/clint.rs
  2. 2 2
      src/hsm.rs
  3. 1 5
      src/main.rs
  4. 21 48
      src/rfence.rs
  5. 6 0
      src/riscv_spec.rs
  6. 7 18
      src/trap.rs
  7. 1 1
      src/trap_stack.rs

+ 1 - 2
src/clint.rs

@@ -8,8 +8,7 @@ use core::{
 };
 use rustsbi::SbiRet;
 
-use crate::riscv_spec::stimecmp;
-use crate::current_hartid;
+use crate::riscv_spec::{stimecmp,current_hartid};
 use crate::hsm::remote_hsm;
 
 pub(crate) static SIFIVECLINT: AtomicPtr<SifiveClint> = AtomicPtr::new(null_mut());

+ 2 - 2
src/hsm.rs

@@ -6,8 +6,9 @@ use core::{
 use rustsbi::{spec::hsm::hart_state, SbiRet};
 use riscv::register::mstatus::MPP;
 
-use crate::{NextStage,current_hartid};
+use crate::NextStage;
 use crate::trap_stack::ROOT_STACK;
+use crate::riscv_spec::current_hartid;
 use crate::clint;
 
 const HART_STATE_START_PENDING_EXT: usize = usize::MAX;
@@ -113,7 +114,6 @@ impl<T : core::fmt::Debug> RemoteHsmCell<'_, T> {
             )
             .is_ok()
         {
-            info!("t: {:?}",t);
             unsafe { *self.0.inner.get() = Some(t) };
             self.0
                 .status

+ 1 - 5
src/main.rs

@@ -31,7 +31,7 @@ use crate::clint::SIFIVECLINT;
 use crate::console::{ConsoleDevice, CONSOLE};
 use crate::hsm::{local_remote_hsm, Hsm};
 use crate::rfence::RFence;
-use crate::riscv_spec::menvcfg;
+use crate::riscv_spec::{menvcfg,current_hartid};
 use crate::trap::trap_vec;
 use crate::trap_stack::NUM_HART_MAX;
 
@@ -185,10 +185,6 @@ unsafe extern "C" fn start() -> ! {
     )
 }
 
-#[inline]
-pub fn current_hartid() -> usize {
-    riscv::register::mhartid::read()
-}
 
 #[derive(Debug)]
 pub struct NextStage {

+ 21 - 48
src/rfence.rs

@@ -1,18 +1,16 @@
 use rustsbi::Ipi;
 use rustsbi::{HartMask, SbiRet};
 use spin::Mutex;
-use spin::RwLock;
 
 use crate::board::SBI;
-use crate::current_hartid;
 use crate::hsm::remote_hsm;
+use crate::riscv_spec::current_hartid;
 use crate::trap::msoft_rfence_handler;
 use crate::trap_stack::NUM_HART_MAX;
 use crate::trap_stack::ROOT_STACK;
 
 pub(crate) struct RFenceCell {
     inner: Mutex<Option<RFenceCTX>>,
-    sync: RwLock<bool>,
 }
 
 #[repr(C)]
@@ -25,20 +23,8 @@ pub(crate) struct RFenceCTX {
     pub op: RFenceType,
 }
 
-// impl RFenceCTX {
-//     pub fn new() -> Self {
-//         Self {
-//             start_addr: 0,
-//             size: 0,
-//             asid: 0,
-//             vmid: 0,
-//             op: RFenceType::None,
-//         }
-//     }
-// }
-
 #[allow(unused)]
-#[derive(Clone, Copy)]
+#[derive(Clone, Copy, Debug)]
 pub(crate) enum RFenceType {
     FenceI,
     SFenceVma,
@@ -53,7 +39,6 @@ impl RFenceCell {
     pub fn new() -> Self {
         Self {
             inner: Mutex::new(None),
-            sync: RwLock::new(false),
         }
     }
 
@@ -72,13 +57,13 @@ impl RFenceCell {
 unsafe impl Sync for RFenceCell {}
 unsafe impl Send for RFenceCell {}
 
-/// 当前硬件线程的RFence上下文。
+/// 当前硬件线程的rfence上下文。
 pub struct LocalRFenceCell<'a>(&'a RFenceCell);
 
-/// 任意硬件线程的RFence上下文。
+/// 任意硬件线程的rfence上下文。
 pub struct RemoteRFenceCell<'a>(&'a RFenceCell);
 
-/// 获取此 hart 的 rfence 上下文
+/// 获取当前hart的rfence上下文
 pub(crate) fn local_rfence() -> LocalRFenceCell<'static> {
     unsafe {
         ROOT_STACK
@@ -89,7 +74,7 @@ pub(crate) fn local_rfence() -> LocalRFenceCell<'static> {
     }
 }
 
-/// 获取任意 hart  remote rfence 上下文
+/// 获取任意hart的rfence上下文
 pub(crate) fn remote_rfence(hart_id: usize) -> Option<RemoteRFenceCell<'static>> {
     unsafe {
         ROOT_STACK
@@ -100,16 +85,14 @@ pub(crate) fn remote_rfence(hart_id: usize) -> Option<RemoteRFenceCell<'static>>
 
 #[allow(unused)]
 impl LocalRFenceCell<'_> {
-    pub fn sync(&self) {
+    pub fn clear(&self) {
         *self.0.inner.lock() = None;
-        *self.0.sync.write() = true;
     }
     pub fn get(&self) -> Option<RFenceCTX> {
-        (*self.0.inner.lock()).clone()
+        (*self.0.inner.lock())
     }
     pub fn set(&self, ctx: RFenceCTX) {
         *self.0.inner.lock() = Some(ctx);
-        *self.0.sync.write() = false;
     }
 }
 
@@ -117,15 +100,6 @@ impl LocalRFenceCell<'_> {
 impl RemoteRFenceCell<'_> {
     pub fn set(&self, ctx: RFenceCTX) {
         *self.0.inner.lock() = Some(ctx);
-        *self.0.sync.write() = false;
-    }
-
-    pub fn is_sync(&self) -> bool {
-        // info!("is sync");
-        match self.0.sync.try_read() {
-            Some(value) => *value,
-            None => false,
-        }
     }
 }
 
@@ -153,12 +127,7 @@ fn remote_fence_process(rfence_ctx: RFenceCTX, hart_mask: HartMask) -> SbiRet {
         msoft_rfence_handler();
     }
 
-    // for hart_id in 0..=NUM_HART_MAX {
-    //     if hart_mask_hsm.has_bit(hart_id) {
-    //         while !remote_rfence(hart_id).unwrap().is_sync() {}
-    //     }
-    // }
-    return sbi_ret;
+    sbi_ret
 }
 
 impl rustsbi::Fence for RFence {
@@ -176,11 +145,15 @@ impl rustsbi::Fence for RFence {
     }
 
     fn remote_sfence_vma(&self, hart_mask: HartMask, start_addr: usize, size: usize) -> SbiRet {
-        // TODO: check start_addr and size
+        // TODO: return SBI_ERR_INVALID_ADDRESS, when start_addr or size is not valid.
+        let flush_size = match start_addr.checked_add(size) {
+            None => usize::MAX,
+            Some(_) => size,
+        };
         remote_fence_process(
             RFenceCTX {
                 start_addr,
-                size,
+                size: flush_size,
                 asid: 0,
                 vmid: 0,
                 op: RFenceType::SFenceVma,
@@ -196,11 +169,15 @@ impl rustsbi::Fence for RFence {
         size: usize,
         asid: usize,
     ) -> SbiRet {
-        // TODO: check start_addr and size
+        // TODO: return SBI_ERR_INVALID_ADDRESS, when start_addr or size is not valid.
+        let flush_size = match start_addr.checked_add(size) {
+            None => usize::MAX,
+            Some(_) => size,
+        };
         remote_fence_process(
             RFenceCTX {
                 start_addr,
-                size,
+                size: flush_size,
                 asid,
                 vmid: 0,
                 op: RFenceType::SFenceVmaAsid,
@@ -213,16 +190,12 @@ impl rustsbi::Fence for RFence {
 pub fn hart_mask_clear(hart_mask: HartMask, hart_id: usize) -> HartMask {
     let (mask, mask_base) = hart_mask.into_inner();
     if mask_base == usize::MAX {
-        // If `hart_mask_base` equals `usize::MAX`, that means `hart_mask` is ignored
-        // and all available harts must be considered.
         return HartMask::from_mask_base(mask & (!(1 << hart_id)), 0);
     }
     let Some(idx) = hart_id.checked_sub(mask_base) else {
-        // hart_id < hart_mask_base, not in current mask range
         return hart_mask;
     };
     if idx >= usize::BITS as usize {
-        // hart_idx >= hart_mask_base + XLEN, not in current mask range
         return hart_mask;
     }
     HartMask::from_mask_base(mask & (!(1 << hart_id)), mask_base)

+ 6 - 0
src/riscv_spec.rs

@@ -35,3 +35,9 @@ pub mod stimecmp {
         unsafe { asm!("csrrs zero, stimecmp, {}", in(reg) value, options(nomem)); }
     }
 }
+
+
+#[inline]
+pub fn current_hartid() -> usize {
+    riscv::register::mhartid::read()
+}

+ 7 - 18
src/trap.rs

@@ -10,10 +10,9 @@ use rustsbi::RustSBI;
 use crate::board::SBI;
 use crate::clint::{self, SIFIVECLINT};
 use crate::console::{MachineConsole, CONSOLE};
-use crate::current_hartid;
 use crate::hsm::local_hsm;
 use crate::rfence::{local_rfence, RFenceType};
-use crate::riscv_spec::{CSR_TIME, CSR_TIMEH};
+use crate::riscv_spec::{CSR_TIME, CSR_TIMEH, current_hartid};
 
 const PAGE_SIZE: usize = 4096;
 
@@ -200,11 +199,6 @@ pub extern "C" fn msoft_hanlder(ctx: &mut SupervisorContext) {
                 mie::set_msoft();
                 mie::set_mtimer();
             }
-            info!(
-                "hart {} => start_addr : 0x{:16x}",
-                current_hartid(),
-                next_stage.start_addr
-            );
             boot(ctx, next_stage.start_addr, next_stage.opaque);
         }
         Err(rustsbi::spec::hsm::HART_STOP) => {
@@ -227,7 +221,7 @@ pub fn msoft_rfence_handler() {
         Some(ctx) => match ctx.op {
             RFenceType::FenceI => unsafe {
                 asm!("fence.i");
-                local_rfence().sync();
+                local_rfence().clear();
                 clint::clear_msip();
             },
             RFenceType::SFenceVma => {
@@ -243,7 +237,7 @@ pub fn msoft_rfence_handler() {
                         }
                     }
                 }
-                local_rfence().sync();
+                local_rfence().clear();
                 clint::clear_msip();
             }
             RFenceType::SFenceVmaAsid => {
@@ -260,12 +254,12 @@ pub fn msoft_rfence_handler() {
                         }
                     }
                 }
-                local_rfence().sync();
+                local_rfence().clear();
                 clint::clear_msip();
             }
-            _ => {
-                error!("Unsupported RFence Type!");
-                local_rfence().sync();
+            rfencetype => {
+                error!("Unsupported RFence Type: {:?}!", rfencetype);
+                local_rfence().clear();
                 clint::clear_msip();
             }
         },
@@ -310,11 +304,6 @@ pub extern "C" fn fast_handler(
                     mie::set_msoft();
                     mie::set_mtimer();
                 }
-                info!(
-                    "hart {} => start_addr : 0x{:16x}",
-                    current_hartid(),
-                    next_stage.start_addr
-                );
                 break boot(ctx, next_stage.start_addr, next_stage.opaque);
             }
             Err(rustsbi::spec::hsm::HART_STOP) => {

+ 1 - 1
src/trap_stack.rs

@@ -3,7 +3,7 @@ use fast_trap::FreeTrapStack;
 
 use crate::hart_context::HartContext;
 use crate::trap::fast_handler;
-use crate::current_hartid;
+use crate::riscv_spec::current_hartid;
 
 const LEN_STACK_PER_HART: usize = 16 * 1024;
 pub const NUM_HART_MAX: usize = 8;