Kaynağa Gözat

docs: add instructions for derive macro usage

Signed-off-by: DongQing <placebo27@hust.edu.cn>
DongQing 11 ay önce
ebeveyn
işleme
c26897bf53
1 değiştirilmiş dosya ile 46 ekleme ve 0 silme
  1. 46 0
      src/lib.rs

+ 46 - 0
src/lib.rs

@@ -774,6 +774,52 @@ pub use sbi_spec::binary::{HartMask, Physical, SbiRet, SharedPtr};
 /// Finally, when the context restores, the supervisor mode software (kernels, etc.) could get the
 /// SBI call result from register values.
 ///
+/// Additionally, the macro also provides a dynamic way of building `RustSBI` trait implementations.
+/// It allows developers to dynamically choose which device to use in the actual RustSBI implementation.
+/// To use this feature, consider two structs namely `FenceOne` and `FenceTwo`, both implementing
+/// RISC-V SBI Remote Fence extension. We can now derive `RustSBI` macro on `MySBI` wrapping those
+/// two structs with `Option` type, annotated with `#[rustsbi(dynamic)]`:
+/// ``
+///
+/// ```rust
+/// # use rustsbi::RustSBI;
+/// #[derive(RustSBI)]
+/// #[rustsbi(dynamic)]
+/// struct MySBI {
+///     fence: Option<FenceOne>,
+///     rfnc: Option<FenceTwo>,
+/// #   info: MyEnvInfo,
+/// }
+///
+/// struct FenceOne { /* fields */ }
+///
+/// struct FenceTwo { /* fields */ }
+///
+/// // Both `FenceOne` and `FenceTwo` implements `rustsbi::Fence`.
+///
+/// # use sbi_spec::binary::{SbiRet, HartMask};
+/// # impl rustsbi::Fence for FenceOne {
+/// #     fn remote_fence_i(&self, _: HartMask) -> SbiRet { unimplemented!() }
+/// #     fn remote_sfence_vma(&self, _: HartMask, _: usize, _: usize) -> SbiRet { unimplemented!() }
+/// #     fn remote_sfence_vma_asid(&self, _: HartMask, _: usize, _: usize, _: usize) -> SbiRet { unimplemented!() }
+/// # }
+/// # impl rustsbi::Fence for FenceTwo {
+/// #     fn remote_fence_i(&self, _: HartMask) -> SbiRet { unimplemented!() }
+/// #     fn remote_sfence_vma(&self, _: HartMask, _: usize, _: usize) -> SbiRet { unimplemented!() }
+/// #     fn remote_sfence_vma_asid(&self, _: HartMask, _: usize, _: usize, _: usize) -> SbiRet { unimplemented!() }
+/// # }
+/// # struct MyEnvInfo;
+/// # impl rustsbi::EnvInfo for MyEnvInfo {
+/// #     fn mvendorid(&self) -> usize { unimplemented!() }
+/// #     fn marchid(&self) -> usize { unimplemented!() }
+/// #     fn mimpid(&self) -> usize { unimplemented!() }
+/// # }
+/// ```
+///
+/// We have declared two fields, `fence` and `rfnc`, both of which are recognized by RustSBI as potential
+/// candidates for the SBI Remote Fence extension. Dynamic RustSBI will probe both fields to determine
+/// which field it should use for the SBI calls on the Remote Fence extension.
+///
 /// Now we have learned basic usages of the derive-macro `RustSBI`. We can dive deeper and use RustSBI
 /// in real cases with ease. Congratulations!
 ///