ソースを参照

fix: implement all rustsbi traits for `Option<T>`

Signed-off-by: DongQing <placebo27@hust.edu.cn>
DongQing 1 週間 前
コミット
293db697b3
10 ファイル変更301 行追加0 行削除
  1. 28 0
      src/console.rs
  2. 34 0
      src/cppc.rs
  3. 34 0
      src/hsm.rs
  4. 16 0
      src/ipi.rs
  5. 40 0
      src/nacl.rs
  6. 85 0
      src/pmu.rs
  7. 16 0
      src/reset.rs
  8. 16 0
      src/sta.rs
  9. 16 0
      src/susp.rs
  10. 16 0
      src/timer.rs

+ 28 - 0
src/console.rs

@@ -106,3 +106,31 @@ impl<T: Console> Console for &T {
         T::write_byte(self, byte)
     }
 }
+
+impl<T: Console> Console for Option<T> {
+    #[inline]
+    fn write(&self, bytes: Physical<&[u8]>) -> SbiRet {
+        self.as_ref()
+            .map(|inner| T::write(inner, bytes))
+            .unwrap_or(SbiRet::not_supported())
+    }
+    #[inline]
+    fn read(&self, bytes: Physical<&mut [u8]>) -> SbiRet {
+        self.as_ref()
+            .map(|inner| T::read(inner, bytes))
+            .unwrap_or(SbiRet::not_supported())
+    }
+    #[inline]
+    fn write_byte(&self, byte: u8) -> SbiRet {
+        self.as_ref()
+            .map(|inner| T::write_byte(inner, byte))
+            .unwrap_or(SbiRet::not_supported())
+    }
+    #[inline]
+    fn _rustsbi_probe(&self) -> usize {
+        match self {
+            Some(_) => sbi_spec::base::UNAVAILABLE_EXTENSION.wrapping_add(1),
+            None => sbi_spec::base::UNAVAILABLE_EXTENSION,
+        }
+    }
+}

+ 34 - 0
src/cppc.rs

@@ -139,3 +139,37 @@ impl<T: Cppc> Cppc for &T {
         T::write(self, reg_id, val)
     }
 }
+
+impl<T: Cppc> Cppc for Option<T> {
+    #[inline]
+    fn probe(&self, reg_id: u32) -> SbiRet {
+        self.as_ref()
+            .map(|inner| T::probe(inner, reg_id))
+            .unwrap_or(SbiRet::not_supported())
+    }
+    #[inline]
+    fn read(&self, reg_id: u32) -> SbiRet {
+        self.as_ref()
+            .map(|inner| T::read(inner, reg_id))
+            .unwrap_or(SbiRet::not_supported())
+    }
+    #[inline]
+    fn read_hi(&self, reg_id: u32) -> SbiRet {
+        self.as_ref()
+            .map(|inner| T::read_hi(inner, reg_id))
+            .unwrap_or(SbiRet::not_supported())
+    }
+    #[inline]
+    fn write(&self, reg_id: u32, val: u64) -> SbiRet {
+        self.as_ref()
+            .map(|inner| T::write(inner, reg_id, val))
+            .unwrap_or(SbiRet::not_supported())
+    }
+    #[inline]
+    fn _rustsbi_probe(&self) -> usize {
+        match self {
+            Some(_) => sbi_spec::base::UNAVAILABLE_EXTENSION.wrapping_add(1),
+            None => sbi_spec::base::UNAVAILABLE_EXTENSION,
+        }
+    }
+}

+ 34 - 0
src/hsm.rs

@@ -227,3 +227,37 @@ impl<T: Hsm> Hsm for &T {
         T::hart_suspend(self, suspend_type, resume_addr, opaque)
     }
 }
+
+impl<T: Hsm> Hsm for Option<T> {
+    #[inline]
+    fn hart_start(&self, hartid: usize, start_addr: usize, opaque: usize) -> SbiRet {
+        self.as_ref()
+            .map(|inner| T::hart_start(inner, hartid, start_addr, opaque))
+            .unwrap_or(SbiRet::not_supported())
+    }
+    #[inline]
+    fn hart_stop(&self) -> SbiRet {
+        self.as_ref()
+            .map(|inner| T::hart_stop(inner))
+            .unwrap_or(SbiRet::not_supported())
+    }
+    #[inline]
+    fn hart_get_status(&self, hartid: usize) -> SbiRet {
+        self.as_ref()
+            .map(|inner| T::hart_get_status(inner, hartid))
+            .unwrap_or(SbiRet::not_supported())
+    }
+    #[inline]
+    fn hart_suspend(&self, suspend_type: u32, resume_addr: usize, opaque: usize) -> SbiRet {
+        self.as_ref()
+            .map(|inner| T::hart_suspend(inner, suspend_type, resume_addr, opaque))
+            .unwrap_or(SbiRet::not_supported())
+    }
+    #[inline]
+    fn _rustsbi_probe(&self) -> usize {
+        match self {
+            Some(_) => sbi_spec::base::UNAVAILABLE_EXTENSION.wrapping_add(1),
+            None => sbi_spec::base::UNAVAILABLE_EXTENSION,
+        }
+    }
+}

+ 16 - 0
src/ipi.rs

@@ -24,3 +24,19 @@ impl<T: Ipi> Ipi for &T {
         T::send_ipi(self, hart_mask)
     }
 }
+
+impl<T: Ipi> Ipi for Option<T> {
+    #[inline]
+    fn send_ipi(&self, hart_mask: HartMask) -> SbiRet {
+        self.as_ref()
+            .map(|inner| T::send_ipi(inner, hart_mask))
+            .unwrap_or(SbiRet::not_supported())
+    }
+    #[inline]
+    fn _rustsbi_probe(&self) -> usize {
+        match self {
+            Some(_) => sbi_spec::base::UNAVAILABLE_EXTENSION.wrapping_add(1),
+            None => sbi_spec::base::UNAVAILABLE_EXTENSION,
+        }
+    }
+}

+ 40 - 0
src/nacl.rs

@@ -171,3 +171,43 @@ impl<T: Nacl> Nacl for &T {
         T::sync_sret(self)
     }
 }
+
+impl<T: Nacl> Nacl for Option<T> {
+    #[inline]
+    fn probe_feature(&self, feature_id: u32) -> SbiRet {
+        self.as_ref()
+            .map(|inner| T::probe_feature(inner, feature_id))
+            .unwrap_or(SbiRet::not_supported())
+    }
+    #[inline]
+    fn set_shmem(&self, shmem: SharedPtr<[u8; NATIVE]>, flags: usize) -> SbiRet {
+        self.as_ref()
+            .map(|inner| T::set_shmem(inner, shmem, flags))
+            .unwrap_or(SbiRet::not_supported())
+    }
+    #[inline]
+    fn sync_csr(&self, csr_num: usize) -> SbiRet {
+        self.as_ref()
+            .map(|inner| T::sync_csr(inner, csr_num))
+            .unwrap_or(SbiRet::not_supported())
+    }
+    #[inline]
+    fn sync_hfence(&self, entry_index: usize) -> SbiRet {
+        self.as_ref()
+            .map(|inner| T::sync_hfence(inner, entry_index))
+            .unwrap_or(SbiRet::not_supported())
+    }
+    #[inline]
+    fn sync_sret(&self) -> SbiRet {
+        self.as_ref()
+            .map(|inner| T::sync_sret(inner))
+            .unwrap_or(SbiRet::not_supported())
+    }
+    #[inline]
+    fn _rustsbi_probe(&self) -> usize {
+        match self {
+            Some(_) => sbi_spec::base::UNAVAILABLE_EXTENSION.wrapping_add(1),
+            None => sbi_spec::base::UNAVAILABLE_EXTENSION,
+        }
+    }
+}

+ 85 - 0
src/pmu.rs

@@ -293,3 +293,88 @@ impl<T: Pmu> Pmu for &T {
         T::counter_fw_read_hi(self, counter_idx)
     }
 }
+
+impl<T: Pmu> Pmu for Option<T> {
+    #[inline]
+    fn num_counters(&self) -> usize {
+        self.as_ref()
+            .map(|inner| T::num_counters(inner))
+            .unwrap_or(0)
+    }
+    #[inline]
+    fn counter_get_info(&self, counter_idx: usize) -> SbiRet {
+        self.as_ref()
+            .map(|inner| T::counter_get_info(inner, counter_idx))
+            .unwrap_or(SbiRet::not_supported())
+    }
+    #[inline]
+    fn counter_config_matching(
+        &self,
+        counter_idx_base: usize,
+        counter_idx_mask: usize,
+        config_flags: usize,
+        event_idx: usize,
+        event_data: u64,
+    ) -> SbiRet {
+        self.as_ref().map_or(SbiRet::not_supported(), |inner| {
+            T::counter_config_matching(
+                inner,
+                counter_idx_base,
+                counter_idx_mask,
+                config_flags,
+                event_idx,
+                event_data,
+            )
+        })
+    }
+    #[inline]
+    fn counter_start(
+        &self,
+        counter_idx_base: usize,
+        counter_idx_mask: usize,
+        start_flags: usize,
+        initial_value: u64,
+    ) -> SbiRet {
+        self.as_ref()
+            .map(|inner| {
+                T::counter_start(
+                    inner,
+                    counter_idx_base,
+                    counter_idx_mask,
+                    start_flags,
+                    initial_value,
+                )
+            })
+            .unwrap_or(SbiRet::not_supported())
+    }
+    #[inline]
+    fn counter_stop(
+        &self,
+        counter_idx_base: usize,
+        counter_idx_mask: usize,
+        stop_flags: usize,
+    ) -> SbiRet {
+        self.as_ref()
+            .map(|inner| T::counter_stop(inner, counter_idx_base, counter_idx_mask, stop_flags))
+            .unwrap_or(SbiRet::not_supported())
+    }
+    #[inline]
+    fn counter_fw_read(&self, counter_idx: usize) -> SbiRet {
+        self.as_ref()
+            .map(|inner| T::counter_fw_read(inner, counter_idx))
+            .unwrap_or(SbiRet::not_supported())
+    }
+    #[inline]
+    fn counter_fw_read_hi(&self, counter_idx: usize) -> SbiRet {
+        self.as_ref()
+            .map(|inner| T::counter_fw_read_hi(inner, counter_idx))
+            .unwrap_or(SbiRet::not_supported())
+    }
+    #[inline]
+    fn _rustsbi_probe(&self) -> usize {
+        match self {
+            Some(_) => sbi_spec::base::UNAVAILABLE_EXTENSION.wrapping_add(1),
+            None => sbi_spec::base::UNAVAILABLE_EXTENSION,
+        }
+    }
+}

+ 16 - 0
src/reset.rs

@@ -55,3 +55,19 @@ impl<T: Reset> Reset for &T {
         T::system_reset(self, reset_type, reset_reason)
     }
 }
+
+impl<T: Reset> Reset for Option<T> {
+    #[inline]
+    fn system_reset(&self, reset_type: u32, reset_reason: u32) -> SbiRet {
+        self.as_ref()
+            .map(|inner| T::system_reset(inner, reset_type, reset_reason))
+            .unwrap_or(SbiRet::not_supported())
+    }
+    #[inline]
+    fn _rustsbi_probe(&self) -> usize {
+        match self {
+            Some(_) => sbi_spec::base::UNAVAILABLE_EXTENSION.wrapping_add(1),
+            None => sbi_spec::base::UNAVAILABLE_EXTENSION,
+        }
+    }
+}

+ 16 - 0
src/sta.rs

@@ -71,3 +71,19 @@ impl<T: Sta> Sta for &T {
         T::set_shmem(self, shmem, flags)
     }
 }
+
+impl<T: Sta> Sta for Option<T> {
+    #[inline]
+    fn set_shmem(&self, shmem: SharedPtr<[u8; 64]>, flags: usize) -> SbiRet {
+        self.as_ref()
+            .map(|inner| T::set_shmem(inner, shmem, flags))
+            .unwrap_or(SbiRet::not_supported())
+    }
+    #[inline]
+    fn _rustsbi_probe(&self) -> usize {
+        match self {
+            Some(_) => sbi_spec::base::UNAVAILABLE_EXTENSION.wrapping_add(1),
+            None => sbi_spec::base::UNAVAILABLE_EXTENSION,
+        }
+    }
+}

+ 16 - 0
src/susp.rs

@@ -98,3 +98,19 @@ impl<T: Susp> Susp for &T {
         T::system_suspend(self, sleep_type, resume_addr, opaque)
     }
 }
+
+impl<T: Susp> Susp for Option<T> {
+    #[inline]
+    fn system_suspend(&self, sleep_type: u32, resume_addr: usize, opaque: usize) -> SbiRet {
+        self.as_ref()
+            .map(|inner| T::system_suspend(inner, sleep_type, resume_addr, opaque))
+            .unwrap_or(SbiRet::not_supported())
+    }
+    #[inline]
+    fn _rustsbi_probe(&self) -> usize {
+        match self {
+            Some(_) => sbi_spec::base::UNAVAILABLE_EXTENSION.wrapping_add(1),
+            None => sbi_spec::base::UNAVAILABLE_EXTENSION,
+        }
+    }
+}

+ 16 - 0
src/timer.rs

@@ -22,3 +22,19 @@ impl<T: Timer> Timer for &T {
         T::set_timer(self, stime_value)
     }
 }
+
+impl<T: Timer> Timer for Option<T> {
+    #[inline]
+    fn set_timer(&self, stime_value: u64) {
+        self.as_ref()
+            .map(|inner| T::set_timer(inner, stime_value))
+            .unwrap_or(())
+    }
+    #[inline]
+    fn _rustsbi_probe(&self) -> usize {
+        match self {
+            Some(_) => sbi_spec::base::UNAVAILABLE_EXTENSION.wrapping_add(1),
+            None => sbi_spec::base::UNAVAILABLE_EXTENSION,
+        }
+    }
+}