xref: /openbmc/qemu/rust/qemu-api/src/device_class.rs (revision e50a24ea)
1 // Copyright 2024, Linaro Limited
2 // Author(s): Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
3 // SPDX-License-Identifier: GPL-2.0-or-later
4 
5 use std::ffi::CStr;
6 
7 use crate::bindings;
8 
9 #[macro_export]
10 macro_rules! device_class_init {
11     ($func:ident, props => $props:ident, realize_fn => $realize_fn:expr, legacy_reset_fn => $legacy_reset_fn:expr, vmsd => $vmsd:ident$(,)*) => {
12         pub unsafe extern "C" fn $func(
13             klass: *mut $crate::bindings::ObjectClass,
14             _: *mut ::std::os::raw::c_void,
15         ) {
16             let mut dc =
17                 ::core::ptr::NonNull::new(klass.cast::<$crate::bindings::DeviceClass>()).unwrap();
18             unsafe {
19                 dc.as_mut().realize = $realize_fn;
20                 dc.as_mut().vmsd = &$vmsd;
21                 $crate::bindings::device_class_set_legacy_reset(dc.as_mut(), $legacy_reset_fn);
22                 $crate::bindings::device_class_set_props(dc.as_mut(), $props.as_ptr());
23             }
24         }
25     };
26 }
27 
28 #[macro_export]
29 macro_rules! define_property {
30     ($name:expr, $state:ty, $field:ident, $prop:expr, $type:expr, default = $defval:expr$(,)*) => {
31         $crate::bindings::Property {
32             // use associated function syntax for type checking
33             name: ::std::ffi::CStr::as_ptr($name),
34             info: $prop,
35             offset: $crate::offset_of!($state, $field) as isize,
36             set_default: true,
37             defval: $crate::bindings::Property__bindgen_ty_1 { u: $defval as u64 },
38             ..$crate::zeroable::Zeroable::ZERO
39         }
40     };
41     ($name:expr, $state:ty, $field:ident, $prop:expr, $type:expr$(,)*) => {
42         $crate::bindings::Property {
43             // use associated function syntax for type checking
44             name: ::std::ffi::CStr::as_ptr($name),
45             info: $prop,
46             offset: $crate::offset_of!($state, $field) as isize,
47             set_default: false,
48             ..$crate::zeroable::Zeroable::ZERO
49         }
50     };
51 }
52 
53 #[macro_export]
54 macro_rules! declare_properties {
55     ($ident:ident, $($prop:expr),*$(,)*) => {
56         pub static $ident: [$crate::bindings::Property; {
57             let mut len = 1;
58             $({
59                 _ = stringify!($prop);
60                 len += 1;
61             })*
62             len
63         }] = [
64             $($prop),*,
65             $crate::zeroable::Zeroable::ZERO,
66         ];
67     };
68 }
69 
70 // workaround until we can use --generate-cstr in bindgen.
71 pub const TYPE_DEVICE: &CStr =
72     unsafe { CStr::from_bytes_with_nul_unchecked(bindings::TYPE_DEVICE) };
73 pub const TYPE_SYS_BUS_DEVICE: &CStr =
74     unsafe { CStr::from_bytes_with_nul_unchecked(bindings::TYPE_SYS_BUS_DEVICE) };
75