1use proc_macro::TokenStream;
6use proc_macro2::Span;
7use quote::{quote, ToTokens};
8use syn::{
9 parse_macro_input, Data, DeriveInput, GenericParam, Generics, Ident, Lifetime, LifetimeParam,
10 Member,
11};
12
13#[derive(Clone)]
14enum ParseMode {
15 Static,
16 Dynamic,
17}
18
19#[derive(Clone, Default)]
20struct StaticImpl {
21 fence: Option<Member>,
22 hsm: Option<Member>,
23 ipi: Option<Member>,
24 reset: Option<Member>,
25 timer: Option<Member>,
26 pmu: Option<Member>,
27 console: Option<Member>,
28 susp: Option<Member>,
29 cppc: Option<Member>,
30 nacl: Option<Member>,
31 sta: Option<Member>,
32 env_info: Option<Member>,
33}
34
35impl StaticImpl {
36 fn replace_sbi_extension_ident(
37 &mut self,
38 extension_name: &str,
39 member: Member,
40 ) -> (bool, Option<Member>) {
41 match extension_name {
42 "rfnc" | "fence" => (true, self.fence.replace(member)),
43 "hsm" => (true, self.hsm.replace(member)),
44 "spi" | "ipi" => (true, self.ipi.replace(member)),
45 "srst" | "reset" => (true, self.reset.replace(member)),
46 "time" | "timer" => (true, self.timer.replace(member)),
47 "pmu" => (true, self.pmu.replace(member)),
48 "dbcn" | "console" => (true, self.console.replace(member)),
49 "susp" => (true, self.susp.replace(member)),
50 "cppc" => (true, self.cppc.replace(member)),
51 "nacl" => (true, self.nacl.replace(member)),
52 "sta" => (true, self.sta.replace(member)),
53 "info" | "env_info" => (true, self.env_info.replace(member)),
54 _ => (false, None),
55 }
56 }
57}
58
59#[derive(Clone, Default)]
60struct DynamicImpl {
61 fence: Vec<Member>,
62 hsm: Vec<Member>,
63 ipi: Vec<Member>,
64 reset: Vec<Member>,
65 timer: Vec<Member>,
66 pmu: Vec<Member>,
67 console: Vec<Member>,
68 susp: Vec<Member>,
69 cppc: Vec<Member>,
70 nacl: Vec<Member>,
71 sta: Vec<Member>,
72 env_info: Option<Member>,
73}
74
75impl DynamicImpl {
76 fn push_sbi_extension_ident(&mut self, extension_name: &str, member: Member) -> bool {
77 match extension_name {
78 "rfnc" | "fence" => self.fence.push(member),
79 "hsm" => self.hsm.push(member),
80 "spi" | "ipi" => self.ipi.push(member),
81 "srst" | "reset" => self.reset.push(member),
82 "time" | "timer" => self.timer.push(member),
83 "pmu" => self.pmu.push(member),
84 "dbcn" | "console" => self.console.push(member),
85 "susp" => self.susp.push(member),
86 "cppc" => self.cppc.push(member),
87 "nacl" => self.nacl.push(member),
88 "sta" => self.sta.push(member),
89 "info" | "env_info" => return self.env_info.replace(member).is_none(),
90 _ => return false,
91 }
92 true
93 }
94}
95
96#[proc_macro_derive(RustSBI, attributes(rustsbi))]
98pub fn derive_rustsbi(input: TokenStream) -> TokenStream {
99 let input = parse_macro_input!(input as DeriveInput);
100
101 let Data::Struct(strukt) = &input.data else {
102 panic!("#[derive(RustSBI)] must be used on structs");
103 };
104
105 let mut ans = TokenStream::new();
106 let mut parse_mode = ParseMode::Static;
107
108 for attr in &input.attrs {
109 if !attr.path().is_ident("rustsbi") {
110 continue;
111 }
112 let parsed = attr.parse_nested_meta(|meta| {
113 if meta.path.is_ident("dynamic") {
114 parse_mode = ParseMode::Dynamic;
115 Ok(())
116 } else {
117 let path = meta.path.to_token_stream().to_string().replace(' ', "");
118 Err(meta.error(format_args!("unknown RustSBI struct attribute `{}`", path)))
119 }
120 });
121 if let Err(err) = parsed {
122 ans.extend(TokenStream::from(err.to_compile_error()));
123 }
124 }
125
126 let mut static_impl = StaticImpl::default();
127 let mut dynamic_impl = DynamicImpl::default();
128
129 for (i, field) in strukt.fields.iter().enumerate() {
130 let member = match &field.ident {
131 Some(ident) => Member::Named(ident.clone()),
132 None => Member::Unnamed(i.into()),
133 };
134 let mut field_already_parsed = false;
135 for attr in &field.attrs {
136 if !attr.path().is_ident("rustsbi") {
137 continue;
138 }
139 let parsed = attr.parse_nested_meta(|meta| {
140 let mut current_meta_accepted = false;
141 if meta.path.is_ident("skip") {
142 current_meta_accepted = true;
144 } else if let Some(meta_path_ident) = meta.path.get_ident() {
145 let extension_name = &meta_path_ident.to_string();
146 match parse_mode {
147 ParseMode::Static => {
148 let (replaced, origin) = static_impl
149 .replace_sbi_extension_ident(extension_name, member.clone());
150 if replaced {
151 check_already_exists(field, extension_name, origin, &mut ans);
152 current_meta_accepted = true;
153 }
154 }
155 ParseMode::Dynamic => {
156 let replaced = dynamic_impl
157 .push_sbi_extension_ident(extension_name, member.clone());
158 if replaced {
159 current_meta_accepted = true;
160 }
161 }
162 }
163 }
164 if current_meta_accepted {
165 field_already_parsed = true;
166 Ok(())
167 } else {
168 let path = meta.path.to_token_stream().to_string().replace(' ', "");
169 Err(meta.error(format_args!("unknown RustSBI variant attribute `{}`", path)))
170 }
171 });
172 if let Err(err) = parsed {
173 ans.extend(TokenStream::from(err.to_compile_error()));
174 }
175 }
176 if field_already_parsed {
179 continue;
180 }
181 if let Some(field_ident) = &field.ident {
182 match parse_mode {
183 ParseMode::Static => {
184 let (_replaced, origin) = static_impl
185 .replace_sbi_extension_ident(field_ident.to_string().as_str(), member);
186 check_already_exists(field, &field_ident.to_string(), origin, &mut ans);
187 }
188 ParseMode::Dynamic => {
189 let _replaced = dynamic_impl
190 .push_sbi_extension_ident(field_ident.to_string().as_str(), member);
191 }
192 }
193 }
194 }
195 match parse_mode {
196 ParseMode::Static => ans.extend(impl_derive_rustsbi_static(
197 &input.ident,
198 static_impl,
199 &input.generics,
200 )),
201 ParseMode::Dynamic => ans.extend(impl_derive_rustsbi_dynamic(
202 &input.ident,
203 dynamic_impl,
204 &input.generics,
205 )),
206 };
207 ans
208}
209
210fn check_already_exists(
211 field: &syn::Field,
212 extension_name: &str,
213 origin: Option<Member>,
214 ans: &mut TokenStream,
215) {
216 if let Some(_origin) = origin {
217 let error = syn::Error::new_spanned(
222 field,
223 format!(
224 "more than one field defined SBI extension '{}'. \
225 At most one fields should define the same SBI extension; consider using \
226 #[rustsbi(skip)] to ignore fields that shouldn't be treated as an extension.",
227 extension_name
228 ),
229 );
230 ans.extend(TokenStream::from(error.to_compile_error()));
231 }
232}
233
234fn impl_derive_rustsbi_static(name: &Ident, imp: StaticImpl, generics: &Generics) -> TokenStream {
235 let base_probe: usize = 1;
236 let fence_probe: usize = if imp.fence.is_some() { 1 } else { 0 };
237 let hsm_probe: usize = if imp.hsm.is_some() { 1 } else { 0 };
238 let ipi_probe: usize = if imp.ipi.is_some() { 1 } else { 0 };
239 let reset_probe: usize = if imp.reset.is_some() { 1 } else { 0 };
240 let timer_probe: usize = if imp.timer.is_some() { 1 } else { 0 };
241 let pmu_probe: usize = if imp.pmu.is_some() { 1 } else { 0 };
242 let console_probe: usize = if imp.console.is_some() { 1 } else { 0 };
243 let susp_probe: usize = if imp.susp.is_some() { 1 } else { 0 };
244 let cppc_probe: usize = if imp.cppc.is_some() { 1 } else { 0 };
245 let nacl_probe: usize = if imp.nacl.is_some() { 1 } else { 0 };
246 let sta_probe: usize = if imp.sta.is_some() { 1 } else { 0 };
247 let probe = quote! {
248 ::rustsbi::_StandardExtensionProbe {
249 base: #base_probe,
250 fence: #fence_probe,
251 hsm: #hsm_probe,
252 ipi: #ipi_probe,
253 reset: #reset_probe,
254 timer: #timer_probe,
255 pmu: #pmu_probe,
256 console: #console_probe,
257 susp: #susp_probe,
258 cppc: #cppc_probe,
259 nacl: #nacl_probe,
260 sta: #sta_probe,
261 }
262 };
263 let mut match_arms = quote! {};
264 let base_procedure = if let Some(env_info) = imp.env_info {
265 quote! {
266 ::rustsbi::spec::base::EID_BASE => ::rustsbi::_rustsbi_base_env_info(param, function, &self.#env_info, #probe),
267 }
268 } else {
269 match () {
270 #[cfg(not(feature = "machine"))]
271 () => quote! {
272 ::rustsbi::spec::base::EID_BASE => compile_error!(
273 "can't derive RustSBI: #[cfg(feature = \"machine\")] is needed to derive RustSBI with no extra `EnvInfo` provided; \
274 consider adding an `info` parameter to provide machine environment information implementing `rustsbi::EnvInfo`\
275 if RustSBI is not run on machine mode."
276 ),
277 },
278 #[cfg(feature = "machine")]
279 () => quote! {
280 ::rustsbi::spec::base::EID_BASE => ::rustsbi::_rustsbi_base_bare(param, function, #probe),
281 },
282 }
283 };
284 match_arms.extend(base_procedure);
285 if let Some(fence) = &imp.fence {
286 match_arms.extend(quote! {
287 ::rustsbi::spec::rfnc::EID_RFNC => ::rustsbi::_rustsbi_fence(&self.#fence, param, function),
288 })
289 };
290 if let Some(timer) = &imp.timer {
291 match_arms.extend(quote! {
292 ::rustsbi::spec::time::EID_TIME => ::rustsbi::_rustsbi_timer(&self.#timer, param, function),
293 })
294 };
295 if let Some(ipi) = &imp.ipi {
296 match_arms.extend(quote! {
297 ::rustsbi::spec::spi::EID_SPI => ::rustsbi::_rustsbi_ipi(&self.#ipi, param, function),
298 })
299 }
300 if let Some(hsm) = &imp.hsm {
301 match_arms.extend(quote! {
302 ::rustsbi::spec::hsm::EID_HSM => ::rustsbi::_rustsbi_hsm(&self.#hsm, param, function),
303 })
304 }
305 if let Some(reset) = &imp.reset {
306 match_arms.extend(quote! {
307 ::rustsbi::spec::srst::EID_SRST => ::rustsbi::_rustsbi_reset(&self.#reset, param, function),
308 })
309 }
310 if let Some(pmu) = &imp.pmu {
311 match_arms.extend(quote! {
312 ::rustsbi::spec::pmu::EID_PMU => ::rustsbi::_rustsbi_pmu(&self.#pmu, param, function),
313 })
314 }
315 if let Some(console) = &imp.console {
316 match_arms.extend(quote! {
317 ::rustsbi::spec::dbcn::EID_DBCN => ::rustsbi::_rustsbi_console(&self.#console, param, function),
318 })
319 }
320 if let Some(susp) = &imp.susp {
321 match_arms.extend(quote! {
322 ::rustsbi::spec::susp::EID_SUSP => ::rustsbi::_rustsbi_susp(&self.#susp, param, function),
323 })
324 }
325 if let Some(cppc) = &imp.cppc {
326 match_arms.extend(quote! {
327 ::rustsbi::spec::cppc::EID_CPPC => ::rustsbi::_rustsbi_cppc(&self.#cppc, param, function),
328 })
329 }
330 if let Some(nacl) = &imp.nacl {
331 match_arms.extend(quote! {
332 ::rustsbi::spec::nacl::EID_NACL => ::rustsbi::_rustsbi_nacl(&self.#nacl, param, function),
333 })
334 }
335 if let Some(sta) = &imp.sta {
336 match_arms.extend(quote! {
337 ::rustsbi::spec::sta::EID_STA => ::rustsbi::_rustsbi_sta(&self.#sta, param, function),
338 })
339 }
340 let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
341 let gen = quote! {
342 impl #impl_generics ::rustsbi::RustSBI for #name #ty_generics #where_clause {
343 #[inline]
344 fn handle_ecall(&self, extension: usize, function: usize, param: [usize; 6]) -> ::rustsbi::SbiRet {
345 match extension {
346 #match_arms
347 _ => ::rustsbi::SbiRet::not_supported(),
348 }
349 }
350 }
351 };
352 gen.into()
353}
354
355fn impl_derive_rustsbi_dynamic(name: &Ident, imp: DynamicImpl, generics: &Generics) -> TokenStream {
356 let mut fence_contents = quote! {};
357 let mut prober_fence = quote! {};
358 for fence in &imp.fence {
359 fence_contents.extend(quote! {
360 if ::rustsbi::_rustsbi_fence_probe(&self.#fence) != ::rustsbi::spec::base::UNAVAILABLE_EXTENSION {
361 return ::rustsbi::_rustsbi_fence(&self.#fence, param, function)
362 }
363 });
364 prober_fence.extend(quote! {
365 let value = ::rustsbi::_rustsbi_fence_probe(&self.0.#fence);
366 if value != ::rustsbi::spec::base::UNAVAILABLE_EXTENSION {
367 return value
368 }
369 });
370 }
371 let mut timer_contents = quote! {};
372 let mut prober_timer = quote! {};
373 for timer in &imp.timer {
374 timer_contents.extend(quote! {
375 if ::rustsbi::_rustsbi_timer_probe(&self.#timer) != ::rustsbi::spec::base::UNAVAILABLE_EXTENSION {
376 return ::rustsbi::_rustsbi_timer(&self.#timer, param, function)
377 }
378 });
379 prober_timer.extend(quote! {
380 let value = ::rustsbi::_rustsbi_timer_probe(&self.0.#timer);
381 if value != ::rustsbi::spec::base::UNAVAILABLE_EXTENSION {
382 return value
383 }
384 });
385 }
386 let mut ipi_contents = quote! {};
387 let mut prober_ipi = quote! {};
388 for ipi in &imp.ipi {
389 ipi_contents.extend(quote! {
390 if ::rustsbi::_rustsbi_ipi_probe(&self.#ipi) != ::rustsbi::spec::base::UNAVAILABLE_EXTENSION {
391 return ::rustsbi::_rustsbi_ipi(&self.#ipi, param, function)
392 }
393 });
394 prober_ipi.extend(quote! {
395 let value = ::rustsbi::_rustsbi_ipi_probe(&self.0.#ipi);
396 if value != ::rustsbi::spec::base::UNAVAILABLE_EXTENSION {
397 return value
398 }
399 });
400 }
401 let mut hsm_contents = quote! {};
402 let mut prober_hsm = quote! {};
403 for hsm in &imp.hsm {
404 hsm_contents.extend(quote! {
405 if ::rustsbi::_rustsbi_hsm_probe(&self.#hsm) != ::rustsbi::spec::base::UNAVAILABLE_EXTENSION {
406 return ::rustsbi::_rustsbi_hsm(&self.#hsm, param, function)
407 }
408 });
409 prober_hsm.extend(quote! {
410 let value = ::rustsbi::_rustsbi_hsm_probe(&self.0.#hsm);
411 if value != ::rustsbi::spec::base::UNAVAILABLE_EXTENSION {
412 return value
413 }
414 });
415 }
416 let mut reset_contents = quote! {};
417 let mut prober_reset = quote! {};
418 for reset in &imp.reset {
419 reset_contents.extend(quote! {
420 if ::rustsbi::_rustsbi_reset_probe(&self.#reset) != ::rustsbi::spec::base::UNAVAILABLE_EXTENSION {
421 return ::rustsbi::_rustsbi_reset(&self.#reset, param, function)
422 }
423 });
424 prober_reset.extend(quote! {
425 let value = ::rustsbi::_rustsbi_reset_probe(&self.0.#reset);
426 if value != ::rustsbi::spec::base::UNAVAILABLE_EXTENSION {
427 return value
428 }
429 });
430 }
431 let mut pmu_contents = quote! {};
432 let mut prober_pmu = quote! {};
433 for pmu in &imp.pmu {
434 pmu_contents.extend(quote! {
435 if ::rustsbi::_rustsbi_pmu_probe(&self.#pmu) != ::rustsbi::spec::base::UNAVAILABLE_EXTENSION {
436 return ::rustsbi::_rustsbi_pmu(&self.#pmu, param, function)
437 }
438 });
439 prober_pmu.extend(quote! {
440 let value = ::rustsbi::_rustsbi_pmu_probe(&self.0.#pmu);
441 if value != ::rustsbi::spec::base::UNAVAILABLE_EXTENSION {
442 return value
443 }
444 });
445 }
446 let mut console_contents = quote! {};
447 let mut prober_console = quote! {};
448 for console in &imp.console {
449 console_contents.extend(quote! {
450 if ::rustsbi::_rustsbi_console_probe(&self.#console) != ::rustsbi::spec::base::UNAVAILABLE_EXTENSION {
451 return ::rustsbi::_rustsbi_console(&self.#console, param, function)
452 }
453 });
454 prober_console.extend(quote! {
455 let value = ::rustsbi::_rustsbi_console_probe(&self.0.#console);
456 if value != ::rustsbi::spec::base::UNAVAILABLE_EXTENSION {
457 return value
458 }
459 });
460 }
461 let mut susp_contents = quote! {};
462 let mut prober_susp = quote! {};
463 for susp in &imp.susp {
464 susp_contents.extend(quote! {
465 if ::rustsbi::_rustsbi_susp_probe(&self.#susp) != ::rustsbi::spec::base::UNAVAILABLE_EXTENSION {
466 return ::rustsbi::_rustsbi_susp(&self.#susp, param, function)
467 }
468 });
469 prober_susp.extend(quote! {
470 let value = ::rustsbi::_rustsbi_susp_probe(&self.0.#susp);
471 if value != ::rustsbi::spec::base::UNAVAILABLE_EXTENSION {
472 return value
473 }
474 });
475 }
476 let mut cppc_contents = quote! {};
477 let mut prober_cppc = quote! {};
478 for cppc in &imp.cppc {
479 cppc_contents.extend(quote! {
480 if ::rustsbi::_rustsbi_cppc_probe(&self.#cppc) != ::rustsbi::spec::base::UNAVAILABLE_EXTENSION {
481 return ::rustsbi::_rustsbi_cppc(&self.#cppc, param, function)
482 }
483 });
484 prober_cppc.extend(quote! {
485 let value = ::rustsbi::_rustsbi_cppc_probe(&self.0.#cppc);
486 if value != ::rustsbi::spec::base::UNAVAILABLE_EXTENSION {
487 return value
488 }
489 });
490 }
491 let mut nacl_contents = quote! {};
492 let mut prober_nacl = quote! {};
493 for nacl in &imp.nacl {
494 nacl_contents.extend(quote! {
495 if ::rustsbi::_rustsbi_nacl_probe(&self.#nacl) != ::rustsbi::spec::base::UNAVAILABLE_EXTENSION {
496 return ::rustsbi::_rustsbi_nacl(&self.#nacl, param, function)
497 }
498 });
499 prober_nacl.extend(quote! {
500 let value = ::rustsbi::_rustsbi_nacl_probe(&self.0.#nacl);
501 if value != ::rustsbi::spec::base::UNAVAILABLE_EXTENSION {
502 return value
503 }
504 });
505 }
506 let mut sta_contents = quote! {};
507 let mut prober_sta = quote! {};
508 for sta in &imp.sta {
509 sta_contents.extend(quote! {
510 if ::rustsbi::_rustsbi_sta_probe(&self.#sta) != ::rustsbi::spec::base::UNAVAILABLE_EXTENSION {
511 return ::rustsbi::_rustsbi_sta(&self.#sta, param, function)
512 }
513 });
514 prober_sta.extend(quote! {
515 let value = ::rustsbi::_rustsbi_sta_probe(&self.0.#sta);
516 if value != ::rustsbi::spec::base::UNAVAILABLE_EXTENSION {
517 return value
518 }
519 });
520 }
521
522 let (_, origin_ty_generics, _) = generics.split_for_impl();
523 let prober_generics = {
524 let mut ans = generics.clone();
525 let lifetime = Lifetime::new("'_lt", Span::mixed_site());
526 ans.params
527 .insert(0, GenericParam::Lifetime(LifetimeParam::new(lifetime)));
528 ans
529 };
530 let (impl_generics, ty_generics, where_clause) = prober_generics.split_for_impl();
531
532 let define_prober = quote! {
533 struct _Prober #impl_generics (&'_lt #name #origin_ty_generics) #where_clause;
534 impl #impl_generics ::rustsbi::_ExtensionProbe for _Prober #ty_generics #where_clause {
535 #[inline(always)]
536 fn probe_extension(&self, extension: usize) -> usize {
537 match extension {
538 ::rustsbi::spec::base::EID_BASE => 1,
539 ::rustsbi::spec::time::EID_TIME => { #prober_timer ::rustsbi::spec::base::UNAVAILABLE_EXTENSION },
540 ::rustsbi::spec::spi::EID_SPI => { #prober_ipi ::rustsbi::spec::base::UNAVAILABLE_EXTENSION },
541 ::rustsbi::spec::rfnc::EID_RFNC => { #prober_fence ::rustsbi::spec::base::UNAVAILABLE_EXTENSION },
542 ::rustsbi::spec::srst::EID_SRST => { #prober_reset ::rustsbi::spec::base::UNAVAILABLE_EXTENSION },
543 ::rustsbi::spec::hsm::EID_HSM => { #prober_hsm ::rustsbi::spec::base::UNAVAILABLE_EXTENSION },
544 ::rustsbi::spec::pmu::EID_PMU => { #prober_pmu ::rustsbi::spec::base::UNAVAILABLE_EXTENSION },
545 ::rustsbi::spec::dbcn::EID_DBCN => { #prober_console ::rustsbi::spec::base::UNAVAILABLE_EXTENSION },
546 ::rustsbi::spec::susp::EID_SUSP => { #prober_susp ::rustsbi::spec::base::UNAVAILABLE_EXTENSION },
547 ::rustsbi::spec::cppc::EID_CPPC => { #prober_cppc ::rustsbi::spec::base::UNAVAILABLE_EXTENSION },
548 ::rustsbi::spec::nacl::EID_NACL => { #prober_nacl ::rustsbi::spec::base::UNAVAILABLE_EXTENSION },
549 ::rustsbi::spec::sta::EID_STA => { #prober_sta ::rustsbi::spec::base::UNAVAILABLE_EXTENSION}
550 _ => ::rustsbi::spec::base::UNAVAILABLE_EXTENSION,
551 }
552 }
553 }
554 };
555 let base_result = if let Some(env_info) = imp.env_info {
556 quote! {
557 ::rustsbi::_rustsbi_base_env_info(param, function, &self.#env_info, prober)
558 }
559 } else {
560 match () {
561 #[cfg(not(feature = "machine"))]
562 () => quote! {
563 compile_error!(
564 "can't derive RustSBI: #[cfg(feature = \"machine\")] is needed to derive RustSBI with no extra `EnvInfo` provided; \
565 consider adding an `info` parameter to provide machine environment information implementing `rustsbi::EnvInfo`\
566 if RustSBI is not run on machine mode."
567 )
568 },
569 #[cfg(feature = "machine")]
570 () => quote! {
571 ::rustsbi::_rustsbi_base_bare(param, function, prober)
572 },
573 }
574 };
575 let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
576 let gen = quote! {
577 impl #impl_generics ::rustsbi::RustSBI for #name #ty_generics #where_clause {
578 #[inline]
579 fn handle_ecall(&self, extension: usize, function: usize, param: [usize; 6]) -> ::rustsbi::SbiRet {
580 match extension {
581 ::rustsbi::spec::rfnc::EID_RFNC => { #fence_contents ::rustsbi::SbiRet::not_supported() },
582 ::rustsbi::spec::time::EID_TIME => { #timer_contents ::rustsbi::SbiRet::not_supported() },
583 ::rustsbi::spec::spi::EID_SPI => { #ipi_contents ::rustsbi::SbiRet::not_supported() },
584 ::rustsbi::spec::hsm::EID_HSM => { #hsm_contents ::rustsbi::SbiRet::not_supported() },
585 ::rustsbi::spec::srst::EID_SRST => { #reset_contents ::rustsbi::SbiRet::not_supported() },
586 ::rustsbi::spec::pmu::EID_PMU => { #pmu_contents ::rustsbi::SbiRet::not_supported() },
587 ::rustsbi::spec::dbcn::EID_DBCN => { #console_contents ::rustsbi::SbiRet::not_supported() },
588 ::rustsbi::spec::susp::EID_SUSP => { #susp_contents ::rustsbi::SbiRet::not_supported() },
589 ::rustsbi::spec::cppc::EID_CPPC => { #cppc_contents ::rustsbi::SbiRet::not_supported() },
590 ::rustsbi::spec::nacl::EID_NACL => { #nacl_contents ::rustsbi::SbiRet::not_supported() },
591 ::rustsbi::spec::sta::EID_STA => { #sta_contents ::rustsbi::SbiRet::not_supported() },
592 ::rustsbi::spec::base::EID_BASE => {
593 #define_prober
594 let prober = _Prober(&self);
595 #base_result
596 }
597 _ => ::rustsbi::SbiRet::not_supported(),
598 }
599 }
600 }
601 };
602 gen.into()
603}