Browse Source

macros: support nacl and sta extensions

Signed-off-by: Zhouqi Jiang <[email protected]>
Zhouqi Jiang 1 year ago
parent
commit
17f4490ff3
3 changed files with 85 additions and 29 deletions
  1. 47 23
      macros/src/lib.rs
  2. 2 2
      src/lib.rs
  3. 36 4
      src/traits.rs

+ 47 - 23
macros/src/lib.rs

@@ -2,17 +2,19 @@ use proc_macro::TokenStream;
 use quote::quote;
 use syn::{parse_macro_input, punctuated::Punctuated, Data, DeriveInput, Fields, Ident};
 
-#[derive(Default)]
-struct RustSBIImp {
-    fence: Option<Ident>,
-    hsm: Option<Ident>,
-    ipi: Option<Ident>,
-    reset: Option<Ident>,
-    timer: Option<Ident>,
-    pmu: Option<Ident>,
-    console: Option<Ident>,
-    susp: Option<Ident>,
-    cppc: Option<Ident>,
+#[derive(Clone, Default)]
+struct RustSBIImp<'a> {
+    fence: Option<&'a Ident>,
+    hsm: Option<&'a Ident>,
+    ipi: Option<&'a Ident>,
+    reset: Option<&'a Ident>,
+    timer: Option<&'a Ident>,
+    pmu: Option<&'a Ident>,
+    console: Option<&'a Ident>,
+    susp: Option<&'a Ident>,
+    cppc: Option<&'a Ident>,
+    nacl: Option<&'a Ident>,
+    sta: Option<&'a Ident>,
 }
 
 /// Implement RustSBI trait for structure of each extensions.
@@ -31,7 +33,7 @@ pub fn derive_rustsbi(input: TokenStream) -> TokenStream {
     };
 
     let mut imp = RustSBIImp::default();
-    for field in fields {
+    for field in &fields {
         // for attr in field.attrs {
         //     if let Meta::List(list) = attr.meta {
         //         let vars =
@@ -42,26 +44,28 @@ pub fn derive_rustsbi(input: TokenStream) -> TokenStream {
         // }
         if let Some(name) = &field.ident {
             match name.to_string().as_str() {
-                "rfnc" | "fence" => imp.fence = Some(name.clone()),
-                "hsm" => imp.hsm = Some(name.clone()),
-                "spi" | "ipi" => imp.ipi = Some(name.clone()),
-                "srst" | "reset" => imp.reset = Some(name.clone()),
-                "timer" => imp.timer = Some(name.clone()),
-                "pmu" => imp.pmu = Some(name.clone()),
-                "dbcn" | "console" => imp.console = Some(name.clone()),
-                "susp" => imp.susp = Some(name.clone()),
-                "cppc" => imp.cppc = Some(name.clone()),
+                "rfnc" | "fence" => imp.fence = Some(name),
+                "hsm" => imp.hsm = Some(name),
+                "spi" | "ipi" => imp.ipi = Some(name),
+                "srst" | "reset" => imp.reset = Some(name),
+                "timer" => imp.timer = Some(name),
+                "pmu" => imp.pmu = Some(name),
+                "dbcn" | "console" => imp.console = Some(name),
+                "susp" => imp.susp = Some(name),
+                "cppc" => imp.cppc = Some(name),
+                "nacl" => imp.nacl = Some(name),
+                "sta" => imp.sta = Some(name),
                 _ => {}
             }
         }
     }
 
     let mut ans = TokenStream::new();
-    ans.extend(impl_derive_rustsbi(&input.ident, &imp));
+    ans.extend(impl_derive_rustsbi(&input.ident, imp));
     ans
 }
 
-fn impl_derive_rustsbi(name: &Ident, imp: &RustSBIImp) -> TokenStream {
+fn impl_derive_rustsbi(name: &Ident, imp: RustSBIImp) -> TokenStream {
     let base_probe: usize = 1;
     let fence_probe: usize = if imp.fence.is_some() { 1 } else { 0 };
     let hsm_probe: usize = if imp.hsm.is_some() { 1 } else { 0 };
@@ -72,6 +76,8 @@ fn impl_derive_rustsbi(name: &Ident, imp: &RustSBIImp) -> TokenStream {
     let console_probe: usize = if imp.console.is_some() { 1 } else { 0 };
     let susp_probe: usize = if imp.susp.is_some() { 1 } else { 0 };
     let cppc_probe: usize = if imp.cppc.is_some() { 1 } else { 0 };
+    let nacl_probe: usize = if imp.nacl.is_some() { 1 } else { 0 };
+    let sta_probe: usize = if imp.sta.is_some() { 1 } else { 0 };
     let base_procedure = quote! {
         ::rustsbi::spec::base::EID_BASE => ::rustsbi::_rustsbi_base_machine(param, function,
             ::rustsbi::_StandardExtensionProbe {
@@ -85,6 +91,8 @@ fn impl_derive_rustsbi(name: &Ident, imp: &RustSBIImp) -> TokenStream {
                 console: #console_probe,
                 susp: #susp_probe,
                 cppc: #cppc_probe,
+                nacl: #nacl_probe,
+                sta: #sta_probe,
             }),
     };
     let fence_procedure = if let Some(fence) = &imp.fence {
@@ -150,6 +158,20 @@ fn impl_derive_rustsbi(name: &Ident, imp: &RustSBIImp) -> TokenStream {
     } else {
         quote! {}
     };
+    let nacl_procedure = if let Some(nacl) = &imp.nacl {
+        quote! {
+            ::rustsbi::spec::nacl::EID_NACL => ::rustsbi::_rustsbi_nacl(&self.#nacl, param, function),
+        }
+    } else {
+        quote! {}
+    };
+    let sta_procedure = if let Some(sta) = &imp.sta {
+        quote! {
+            ::rustsbi::spec::sta::EID_STA => ::rustsbi::_rustsbi_sta(&self.#sta, param, function),
+        }
+    } else {
+        quote! {}
+    };
     let gen = quote! {
     impl rustsbi::RustSBI for #name {
         #[inline]
@@ -165,6 +187,8 @@ fn impl_derive_rustsbi(name: &Ident, imp: &RustSBIImp) -> TokenStream {
                 #console_procedure
                 #susp_procedure
                 #cppc_procedure
+                #nacl_procedure
+                #sta_procedure
                 _ => SbiRet::not_supported(),
             }
         }

+ 2 - 2
src/lib.rs

@@ -567,8 +567,8 @@ pub use traits::RustSBI;
 #[doc(hidden)]
 pub use traits::{
     _StandardExtensionProbe, _rustsbi_base_machine, _rustsbi_console, _rustsbi_cppc,
-    _rustsbi_fence, _rustsbi_hsm, _rustsbi_ipi, _rustsbi_pmu, _rustsbi_reset, _rustsbi_susp,
-    _rustsbi_timer,
+    _rustsbi_fence, _rustsbi_hsm, _rustsbi_ipi, _rustsbi_nacl, _rustsbi_pmu, _rustsbi_reset,
+    _rustsbi_sta, _rustsbi_susp, _rustsbi_timer,
 };
 
 // #[cfg(not(feature = "machine"))]

+ 36 - 4
src/traits.rs

@@ -1,6 +1,6 @@
 use crate::HartMask;
 use riscv::register::{marchid, mimpid, mvendorid};
-use spec::binary::{Physical, SbiRet};
+use spec::binary::{Physical, SbiRet, SharedPtr};
 
 /// RustSBI trait including standard extensions.
 pub trait RustSBI {
@@ -22,6 +22,9 @@ pub struct _StandardExtensionProbe {
     pub console: usize,
     pub susp: usize,
     pub cppc: usize,
+    pub nacl: usize,
+    pub sta: usize,
+    // NOTE: don't forget to add to `fn probe_extension` as well
 }
 
 #[doc(hidden)]
@@ -59,9 +62,11 @@ fn probe_extension(extension: usize, probe: _StandardExtensionProbe) -> usize {
         spec::srst::EID_SRST => probe.reset,
         spec::hsm::EID_HSM => probe.hsm,
         spec::pmu::EID_PMU => probe.pmu,
-        // spec::dbcn::EID_DBCN => self.dbcn.is_some(),
-        // spec::susp::EID_SUSP => self.susp.is_some(),
-        // spec::cppc::EID_CPPC => self.cppc.is_some(),
+        spec::dbcn::EID_DBCN => probe.console,
+        spec::susp::EID_SUSP => probe.susp,
+        spec::cppc::EID_CPPC => probe.cppc,
+        spec::nacl::EID_NACL => probe.nacl,
+        spec::sta::EID_STA => probe.sta,
         _ => spec::base::UNAVAILABLE_EXTENSION,
     }
 }
@@ -283,3 +288,30 @@ pub fn _rustsbi_cppc<T: crate::Cppc>(cppc: T, param: [usize; 6], function: usize
         }
     }
 }
+
+#[doc(hidden)]
+#[inline(always)]
+pub fn _rustsbi_nacl<T: crate::Nacl>(nacl: T, param: [usize; 6], function: usize) -> SbiRet {
+    let [param0, param1, param2] = [param[0], param[1], param[2]];
+    match function {
+        spec::nacl::PROBE_FEATURE => match u32::try_from(param0) {
+            Ok(feature_id) => nacl.probe_feature(feature_id),
+            _ => SbiRet::invalid_param(),
+        },
+        spec::nacl::SET_SHMEM => nacl.set_shmem(SharedPtr::new(param0, param1), param2),
+        spec::nacl::SYNC_CSR => nacl.sync_csr(param0),
+        spec::nacl::SYNC_HFENCE => nacl.sync_hfence(param0),
+        spec::nacl::SYNC_SRET => nacl.sync_sret(),
+        _ => SbiRet::not_supported(),
+    }
+}
+
+#[doc(hidden)]
+#[inline(always)]
+pub fn _rustsbi_sta<T: crate::Sta>(sta: T, param: [usize; 6], function: usize) -> SbiRet {
+    let [param0, param1, param2] = [param[0], param[1], param[2]];
+    match function {
+        spec::sta::SET_SHMEM => sta.set_shmem(SharedPtr::new(param0, param1), param2),
+        _ => SbiRet::not_supported(),
+    }
+}