1*0a65e412SManos Pitsidianakis // Copyright 2024, Linaro Limited 2*0a65e412SManos Pitsidianakis // Author(s): Manos Pitsidianakis <manos.pitsidianakis@linaro.org> 3*0a65e412SManos Pitsidianakis // SPDX-License-Identifier: GPL-2.0-or-later 4*0a65e412SManos Pitsidianakis 5*0a65e412SManos Pitsidianakis //! Helper macros to declare migration state for device models. 6*0a65e412SManos Pitsidianakis //! 7*0a65e412SManos Pitsidianakis //! Some macros are direct equivalents to the C macros declared in 8*0a65e412SManos Pitsidianakis //! `include/migration/vmstate.h` while 9*0a65e412SManos Pitsidianakis //! [`vmstate_subsections`](crate::vmstate_subsections) and 10*0a65e412SManos Pitsidianakis //! [`vmstate_fields`](crate::vmstate_fields) are meant to be used when 11*0a65e412SManos Pitsidianakis //! declaring a device model state struct. 12*0a65e412SManos Pitsidianakis 13*0a65e412SManos Pitsidianakis #[doc(alias = "VMSTATE_UNUSED_BUFFER")] 14*0a65e412SManos Pitsidianakis #[macro_export] 15*0a65e412SManos Pitsidianakis macro_rules! vmstate_unused_buffer { 16*0a65e412SManos Pitsidianakis ($field_exists_fn:expr, $version_id:expr, $size:expr) => {{ 17*0a65e412SManos Pitsidianakis $crate::bindings::VMStateField { 18*0a65e412SManos Pitsidianakis name: c"unused".as_ptr(), 19*0a65e412SManos Pitsidianakis err_hint: ::core::ptr::null(), 20*0a65e412SManos Pitsidianakis offset: 0, 21*0a65e412SManos Pitsidianakis size: $size, 22*0a65e412SManos Pitsidianakis start: 0, 23*0a65e412SManos Pitsidianakis num: 0, 24*0a65e412SManos Pitsidianakis num_offset: 0, 25*0a65e412SManos Pitsidianakis size_offset: 0, 26*0a65e412SManos Pitsidianakis info: unsafe { ::core::ptr::addr_of!($crate::bindings::vmstate_info_unused_buffer) }, 27*0a65e412SManos Pitsidianakis flags: VMStateFlags::VMS_BUFFER, 28*0a65e412SManos Pitsidianakis vmsd: ::core::ptr::null(), 29*0a65e412SManos Pitsidianakis version_id: $version_id, 30*0a65e412SManos Pitsidianakis struct_version_id: 0, 31*0a65e412SManos Pitsidianakis field_exists: $field_exists_fn, 32*0a65e412SManos Pitsidianakis } 33*0a65e412SManos Pitsidianakis }}; 34*0a65e412SManos Pitsidianakis } 35*0a65e412SManos Pitsidianakis 36*0a65e412SManos Pitsidianakis #[doc(alias = "VMSTATE_UNUSED_V")] 37*0a65e412SManos Pitsidianakis #[macro_export] 38*0a65e412SManos Pitsidianakis macro_rules! vmstate_unused_v { 39*0a65e412SManos Pitsidianakis ($version_id:expr, $size:expr) => {{ 40*0a65e412SManos Pitsidianakis $crate::vmstate_unused_buffer!(None, $version_id, $size) 41*0a65e412SManos Pitsidianakis }}; 42*0a65e412SManos Pitsidianakis } 43*0a65e412SManos Pitsidianakis 44*0a65e412SManos Pitsidianakis #[doc(alias = "VMSTATE_UNUSED")] 45*0a65e412SManos Pitsidianakis #[macro_export] 46*0a65e412SManos Pitsidianakis macro_rules! vmstate_unused { 47*0a65e412SManos Pitsidianakis ($size:expr) => {{ 48*0a65e412SManos Pitsidianakis $crate::vmstate_unused_v!(0, $size) 49*0a65e412SManos Pitsidianakis }}; 50*0a65e412SManos Pitsidianakis } 51*0a65e412SManos Pitsidianakis 52*0a65e412SManos Pitsidianakis #[doc(alias = "VMSTATE_SINGLE_TEST")] 53*0a65e412SManos Pitsidianakis #[macro_export] 54*0a65e412SManos Pitsidianakis macro_rules! vmstate_single_test { 55*0a65e412SManos Pitsidianakis ($field_name:ident, $struct_name:ty, $field_exists_fn:expr, $version_id:expr, $info:expr, $size:expr) => {{ 56*0a65e412SManos Pitsidianakis $crate::bindings::VMStateField { 57*0a65e412SManos Pitsidianakis name: ::core::concat!(::core::stringify!($field_name), 0) 58*0a65e412SManos Pitsidianakis .as_bytes() 59*0a65e412SManos Pitsidianakis .as_ptr() as *const ::core::ffi::c_char, 60*0a65e412SManos Pitsidianakis err_hint: ::core::ptr::null(), 61*0a65e412SManos Pitsidianakis offset: ::core::mem::offset_of!($struct_name, $field_name), 62*0a65e412SManos Pitsidianakis size: $size, 63*0a65e412SManos Pitsidianakis start: 0, 64*0a65e412SManos Pitsidianakis num: 0, 65*0a65e412SManos Pitsidianakis num_offset: 0, 66*0a65e412SManos Pitsidianakis size_offset: 0, 67*0a65e412SManos Pitsidianakis info: unsafe { $info }, 68*0a65e412SManos Pitsidianakis flags: VMStateFlags::VMS_SINGLE, 69*0a65e412SManos Pitsidianakis vmsd: ::core::ptr::null(), 70*0a65e412SManos Pitsidianakis version_id: $version_id, 71*0a65e412SManos Pitsidianakis struct_version_id: 0, 72*0a65e412SManos Pitsidianakis field_exists: $field_exists_fn, 73*0a65e412SManos Pitsidianakis } 74*0a65e412SManos Pitsidianakis }}; 75*0a65e412SManos Pitsidianakis } 76*0a65e412SManos Pitsidianakis 77*0a65e412SManos Pitsidianakis #[doc(alias = "VMSTATE_SINGLE")] 78*0a65e412SManos Pitsidianakis #[macro_export] 79*0a65e412SManos Pitsidianakis macro_rules! vmstate_single { 80*0a65e412SManos Pitsidianakis ($field_name:ident, $struct_name:ty, $version_id:expr, $info:expr, $size:expr) => {{ 81*0a65e412SManos Pitsidianakis $crate::vmstate_single_test!($field_name, $struct_name, None, $version_id, $info, $size) 82*0a65e412SManos Pitsidianakis }}; 83*0a65e412SManos Pitsidianakis } 84*0a65e412SManos Pitsidianakis 85*0a65e412SManos Pitsidianakis #[doc(alias = "VMSTATE_UINT32_V")] 86*0a65e412SManos Pitsidianakis #[macro_export] 87*0a65e412SManos Pitsidianakis macro_rules! vmstate_uint32_v { 88*0a65e412SManos Pitsidianakis ($field_name:ident, $struct_name:ty, $version_id:expr) => {{ 89*0a65e412SManos Pitsidianakis $crate::vmstate_single!( 90*0a65e412SManos Pitsidianakis $field_name, 91*0a65e412SManos Pitsidianakis $struct_name, 92*0a65e412SManos Pitsidianakis $version_id, 93*0a65e412SManos Pitsidianakis ::core::ptr::addr_of!($crate::bindings::vmstate_info_uint32), 94*0a65e412SManos Pitsidianakis ::core::mem::size_of::<u32>() 95*0a65e412SManos Pitsidianakis ) 96*0a65e412SManos Pitsidianakis }}; 97*0a65e412SManos Pitsidianakis } 98*0a65e412SManos Pitsidianakis 99*0a65e412SManos Pitsidianakis #[doc(alias = "VMSTATE_UINT32")] 100*0a65e412SManos Pitsidianakis #[macro_export] 101*0a65e412SManos Pitsidianakis macro_rules! vmstate_uint32 { 102*0a65e412SManos Pitsidianakis ($field_name:ident, $struct_name:ty) => {{ 103*0a65e412SManos Pitsidianakis $crate::vmstate_uint32_v!($field_name, $struct_name, 0) 104*0a65e412SManos Pitsidianakis }}; 105*0a65e412SManos Pitsidianakis } 106*0a65e412SManos Pitsidianakis 107*0a65e412SManos Pitsidianakis #[doc(alias = "VMSTATE_INT32_V")] 108*0a65e412SManos Pitsidianakis #[macro_export] 109*0a65e412SManos Pitsidianakis macro_rules! vmstate_int32_v { 110*0a65e412SManos Pitsidianakis ($field_name:ident, $struct_name:ty, $version_id:expr) => {{ 111*0a65e412SManos Pitsidianakis $crate::vmstate_single!( 112*0a65e412SManos Pitsidianakis $field_name, 113*0a65e412SManos Pitsidianakis $struct_name, 114*0a65e412SManos Pitsidianakis $version_id, 115*0a65e412SManos Pitsidianakis ::core::ptr::addr_of!($crate::bindings::vmstate_info_int32), 116*0a65e412SManos Pitsidianakis ::core::mem::size_of::<i32>() 117*0a65e412SManos Pitsidianakis ) 118*0a65e412SManos Pitsidianakis }}; 119*0a65e412SManos Pitsidianakis } 120*0a65e412SManos Pitsidianakis 121*0a65e412SManos Pitsidianakis #[doc(alias = "VMSTATE_INT32")] 122*0a65e412SManos Pitsidianakis #[macro_export] 123*0a65e412SManos Pitsidianakis macro_rules! vmstate_int32 { 124*0a65e412SManos Pitsidianakis ($field_name:ident, $struct_name:ty) => {{ 125*0a65e412SManos Pitsidianakis $crate::vmstate_int32_v!($field_name, $struct_name, 0) 126*0a65e412SManos Pitsidianakis }}; 127*0a65e412SManos Pitsidianakis } 128*0a65e412SManos Pitsidianakis 129*0a65e412SManos Pitsidianakis #[doc(alias = "VMSTATE_ARRAY")] 130*0a65e412SManos Pitsidianakis #[macro_export] 131*0a65e412SManos Pitsidianakis macro_rules! vmstate_array { 132*0a65e412SManos Pitsidianakis ($field_name:ident, $struct_name:ty, $length:expr, $version_id:expr, $info:expr, $size:expr) => {{ 133*0a65e412SManos Pitsidianakis $crate::bindings::VMStateField { 134*0a65e412SManos Pitsidianakis name: ::core::concat!(::core::stringify!($field_name), 0) 135*0a65e412SManos Pitsidianakis .as_bytes() 136*0a65e412SManos Pitsidianakis .as_ptr() as *const ::core::ffi::c_char, 137*0a65e412SManos Pitsidianakis err_hint: ::core::ptr::null(), 138*0a65e412SManos Pitsidianakis offset: ::core::mem::offset_of!($struct_name, $field_name), 139*0a65e412SManos Pitsidianakis size: $size, 140*0a65e412SManos Pitsidianakis start: 0, 141*0a65e412SManos Pitsidianakis num: $length as _, 142*0a65e412SManos Pitsidianakis num_offset: 0, 143*0a65e412SManos Pitsidianakis size_offset: 0, 144*0a65e412SManos Pitsidianakis info: unsafe { $info }, 145*0a65e412SManos Pitsidianakis flags: VMStateFlags::VMS_ARRAY, 146*0a65e412SManos Pitsidianakis vmsd: ::core::ptr::null(), 147*0a65e412SManos Pitsidianakis version_id: $version_id, 148*0a65e412SManos Pitsidianakis struct_version_id: 0, 149*0a65e412SManos Pitsidianakis field_exists: None, 150*0a65e412SManos Pitsidianakis } 151*0a65e412SManos Pitsidianakis }}; 152*0a65e412SManos Pitsidianakis } 153*0a65e412SManos Pitsidianakis 154*0a65e412SManos Pitsidianakis #[doc(alias = "VMSTATE_UINT32_ARRAY_V")] 155*0a65e412SManos Pitsidianakis #[macro_export] 156*0a65e412SManos Pitsidianakis macro_rules! vmstate_uint32_array_v { 157*0a65e412SManos Pitsidianakis ($field_name:ident, $struct_name:ty, $length:expr, $version_id:expr) => {{ 158*0a65e412SManos Pitsidianakis $crate::vmstate_array!( 159*0a65e412SManos Pitsidianakis $field_name, 160*0a65e412SManos Pitsidianakis $struct_name, 161*0a65e412SManos Pitsidianakis $length, 162*0a65e412SManos Pitsidianakis $version_id, 163*0a65e412SManos Pitsidianakis ::core::ptr::addr_of!($crate::bindings::vmstate_info_uint32), 164*0a65e412SManos Pitsidianakis ::core::mem::size_of::<u32>() 165*0a65e412SManos Pitsidianakis ) 166*0a65e412SManos Pitsidianakis }}; 167*0a65e412SManos Pitsidianakis } 168*0a65e412SManos Pitsidianakis 169*0a65e412SManos Pitsidianakis #[doc(alias = "VMSTATE_UINT32_ARRAY")] 170*0a65e412SManos Pitsidianakis #[macro_export] 171*0a65e412SManos Pitsidianakis macro_rules! vmstate_uint32_array { 172*0a65e412SManos Pitsidianakis ($field_name:ident, $struct_name:ty, $length:expr) => {{ 173*0a65e412SManos Pitsidianakis $crate::vmstate_uint32_array_v!($field_name, $struct_name, $length, 0) 174*0a65e412SManos Pitsidianakis }}; 175*0a65e412SManos Pitsidianakis } 176*0a65e412SManos Pitsidianakis 177*0a65e412SManos Pitsidianakis #[doc(alias = "VMSTATE_STRUCT_POINTER_V")] 178*0a65e412SManos Pitsidianakis #[macro_export] 179*0a65e412SManos Pitsidianakis macro_rules! vmstate_struct_pointer_v { 180*0a65e412SManos Pitsidianakis ($field_name:ident, $struct_name:ty, $version_id:expr, $vmsd:expr, $type:ty) => {{ 181*0a65e412SManos Pitsidianakis $crate::bindings::VMStateField { 182*0a65e412SManos Pitsidianakis name: ::core::concat!(::core::stringify!($field_name), 0) 183*0a65e412SManos Pitsidianakis .as_bytes() 184*0a65e412SManos Pitsidianakis .as_ptr() as *const ::core::ffi::c_char, 185*0a65e412SManos Pitsidianakis err_hint: ::core::ptr::null(), 186*0a65e412SManos Pitsidianakis offset: ::core::mem::offset_of!($struct_name, $field_name), 187*0a65e412SManos Pitsidianakis size: ::core::mem::size_of::<*const $type>(), 188*0a65e412SManos Pitsidianakis start: 0, 189*0a65e412SManos Pitsidianakis num: 0, 190*0a65e412SManos Pitsidianakis num_offset: 0, 191*0a65e412SManos Pitsidianakis size_offset: 0, 192*0a65e412SManos Pitsidianakis info: ::core::ptr::null(), 193*0a65e412SManos Pitsidianakis flags: VMStateFlags(VMStateFlags::VMS_STRUCT.0 | VMStateFlags::VMS_POINTER.0), 194*0a65e412SManos Pitsidianakis vmsd: unsafe { $vmsd }, 195*0a65e412SManos Pitsidianakis version_id: $version_id, 196*0a65e412SManos Pitsidianakis struct_version_id: 0, 197*0a65e412SManos Pitsidianakis field_exists: None, 198*0a65e412SManos Pitsidianakis } 199*0a65e412SManos Pitsidianakis }}; 200*0a65e412SManos Pitsidianakis } 201*0a65e412SManos Pitsidianakis 202*0a65e412SManos Pitsidianakis #[doc(alias = "VMSTATE_ARRAY_OF_POINTER")] 203*0a65e412SManos Pitsidianakis #[macro_export] 204*0a65e412SManos Pitsidianakis macro_rules! vmstate_array_of_pointer { 205*0a65e412SManos Pitsidianakis ($field_name:ident, $struct_name:ty, $num:expr, $version_id:expr, $info:expr, $type:ty) => {{ 206*0a65e412SManos Pitsidianakis $crate::bindings::VMStateField { 207*0a65e412SManos Pitsidianakis name: ::core::concat!(::core::stringify!($field_name), 0) 208*0a65e412SManos Pitsidianakis .as_bytes() 209*0a65e412SManos Pitsidianakis .as_ptr() as *const ::core::ffi::c_char, 210*0a65e412SManos Pitsidianakis version_id: $version_id, 211*0a65e412SManos Pitsidianakis num: $num as _, 212*0a65e412SManos Pitsidianakis info: unsafe { $info }, 213*0a65e412SManos Pitsidianakis size: ::core::mem::size_of::<*const $type>(), 214*0a65e412SManos Pitsidianakis flags: VMStateFlags(VMStateFlags::VMS_ARRAY.0 | VMStateFlags::VMS_ARRAY_OF_POINTER.0), 215*0a65e412SManos Pitsidianakis offset: ::core::mem::offset_of!($struct_name, $field_name), 216*0a65e412SManos Pitsidianakis err_hint: ::core::ptr::null(), 217*0a65e412SManos Pitsidianakis start: 0, 218*0a65e412SManos Pitsidianakis num_offset: 0, 219*0a65e412SManos Pitsidianakis size_offset: 0, 220*0a65e412SManos Pitsidianakis vmsd: ::core::ptr::null(), 221*0a65e412SManos Pitsidianakis struct_version_id: 0, 222*0a65e412SManos Pitsidianakis field_exists: None, 223*0a65e412SManos Pitsidianakis } 224*0a65e412SManos Pitsidianakis }}; 225*0a65e412SManos Pitsidianakis } 226*0a65e412SManos Pitsidianakis 227*0a65e412SManos Pitsidianakis #[doc(alias = "VMSTATE_ARRAY_OF_POINTER_TO_STRUCT")] 228*0a65e412SManos Pitsidianakis #[macro_export] 229*0a65e412SManos Pitsidianakis macro_rules! vmstate_array_of_pointer_to_struct { 230*0a65e412SManos Pitsidianakis ($field_name:ident, $struct_name:ty, $num:expr, $version_id:expr, $vmsd:expr, $type:ty) => {{ 231*0a65e412SManos Pitsidianakis $crate::bindings::VMStateField { 232*0a65e412SManos Pitsidianakis name: ::core::concat!(::core::stringify!($field_name), 0) 233*0a65e412SManos Pitsidianakis .as_bytes() 234*0a65e412SManos Pitsidianakis .as_ptr() as *const ::core::ffi::c_char, 235*0a65e412SManos Pitsidianakis version_id: $version_id, 236*0a65e412SManos Pitsidianakis num: $num as _, 237*0a65e412SManos Pitsidianakis vmsd: unsafe { $vmsd }, 238*0a65e412SManos Pitsidianakis size: ::core::mem::size_of::<*const $type>(), 239*0a65e412SManos Pitsidianakis flags: VMStateFlags( 240*0a65e412SManos Pitsidianakis VMStateFlags::VMS_ARRAY.0 241*0a65e412SManos Pitsidianakis | VMStateFlags::VMS_STRUCT.0 242*0a65e412SManos Pitsidianakis | VMStateFlags::VMS_ARRAY_OF_POINTER.0, 243*0a65e412SManos Pitsidianakis ), 244*0a65e412SManos Pitsidianakis offset: ::core::mem::offset_of!($struct_name, $field_name), 245*0a65e412SManos Pitsidianakis err_hint: ::core::ptr::null(), 246*0a65e412SManos Pitsidianakis start: 0, 247*0a65e412SManos Pitsidianakis num_offset: 0, 248*0a65e412SManos Pitsidianakis size_offset: 0, 249*0a65e412SManos Pitsidianakis vmsd: ::core::ptr::null(), 250*0a65e412SManos Pitsidianakis struct_version_id: 0, 251*0a65e412SManos Pitsidianakis field_exists: None, 252*0a65e412SManos Pitsidianakis } 253*0a65e412SManos Pitsidianakis }}; 254*0a65e412SManos Pitsidianakis } 255*0a65e412SManos Pitsidianakis 256*0a65e412SManos Pitsidianakis #[doc(alias = "VMSTATE_CLOCK_V")] 257*0a65e412SManos Pitsidianakis #[macro_export] 258*0a65e412SManos Pitsidianakis macro_rules! vmstate_clock_v { 259*0a65e412SManos Pitsidianakis ($field_name:ident, $struct_name:ty, $version_id:expr) => {{ 260*0a65e412SManos Pitsidianakis $crate::vmstate_struct_pointer_v!( 261*0a65e412SManos Pitsidianakis $field_name, 262*0a65e412SManos Pitsidianakis $struct_name, 263*0a65e412SManos Pitsidianakis $version_id, 264*0a65e412SManos Pitsidianakis ::core::ptr::addr_of!($crate::bindings::vmstate_clock), 265*0a65e412SManos Pitsidianakis $crate::bindings::Clock 266*0a65e412SManos Pitsidianakis ) 267*0a65e412SManos Pitsidianakis }}; 268*0a65e412SManos Pitsidianakis } 269*0a65e412SManos Pitsidianakis 270*0a65e412SManos Pitsidianakis #[doc(alias = "VMSTATE_CLOCK")] 271*0a65e412SManos Pitsidianakis #[macro_export] 272*0a65e412SManos Pitsidianakis macro_rules! vmstate_clock { 273*0a65e412SManos Pitsidianakis ($field_name:ident, $struct_name:ty) => {{ 274*0a65e412SManos Pitsidianakis $crate::vmstate_clock_v!($field_name, $struct_name, 0) 275*0a65e412SManos Pitsidianakis }}; 276*0a65e412SManos Pitsidianakis } 277*0a65e412SManos Pitsidianakis 278*0a65e412SManos Pitsidianakis #[doc(alias = "VMSTATE_ARRAY_CLOCK_V")] 279*0a65e412SManos Pitsidianakis #[macro_export] 280*0a65e412SManos Pitsidianakis macro_rules! vmstate_array_clock_v { 281*0a65e412SManos Pitsidianakis ($field_name:ident, $struct_name:ty, $num:expr, $version_id:expr) => {{ 282*0a65e412SManos Pitsidianakis $crate::vmstate_array_of_pointer_to_struct!( 283*0a65e412SManos Pitsidianakis $field_name, 284*0a65e412SManos Pitsidianakis $struct_name, 285*0a65e412SManos Pitsidianakis $num, 286*0a65e412SManos Pitsidianakis $version_id, 287*0a65e412SManos Pitsidianakis ::core::ptr::addr_of!($crate::bindings::vmstate_clock), 288*0a65e412SManos Pitsidianakis $crate::bindings::Clock 289*0a65e412SManos Pitsidianakis ) 290*0a65e412SManos Pitsidianakis }}; 291*0a65e412SManos Pitsidianakis } 292*0a65e412SManos Pitsidianakis 293*0a65e412SManos Pitsidianakis #[doc(alias = "VMSTATE_ARRAY_CLOCK")] 294*0a65e412SManos Pitsidianakis #[macro_export] 295*0a65e412SManos Pitsidianakis macro_rules! vmstate_array_clock { 296*0a65e412SManos Pitsidianakis ($field_name:ident, $struct_name:ty, $num:expr) => {{ 297*0a65e412SManos Pitsidianakis $crate::vmstate_array_clock_v!($field_name, $struct_name, $name, 0) 298*0a65e412SManos Pitsidianakis }}; 299*0a65e412SManos Pitsidianakis } 300*0a65e412SManos Pitsidianakis 301*0a65e412SManos Pitsidianakis /// Helper macro to declare a list of 302*0a65e412SManos Pitsidianakis /// ([`VMStateField`](`crate::bindings::VMStateField`)) into a static and return 303*0a65e412SManos Pitsidianakis /// a pointer to the array of values it created. 304*0a65e412SManos Pitsidianakis #[macro_export] 305*0a65e412SManos Pitsidianakis macro_rules! vmstate_fields { 306*0a65e412SManos Pitsidianakis ($($field:expr),*$(,)*) => {{ 307*0a65e412SManos Pitsidianakis static _FIELDS: &[$crate::bindings::VMStateField] = &[ 308*0a65e412SManos Pitsidianakis $($field),*, 309*0a65e412SManos Pitsidianakis $crate::bindings::VMStateField { 310*0a65e412SManos Pitsidianakis name: ::core::ptr::null(), 311*0a65e412SManos Pitsidianakis err_hint: ::core::ptr::null(), 312*0a65e412SManos Pitsidianakis offset: 0, 313*0a65e412SManos Pitsidianakis size: 0, 314*0a65e412SManos Pitsidianakis start: 0, 315*0a65e412SManos Pitsidianakis num: 0, 316*0a65e412SManos Pitsidianakis num_offset: 0, 317*0a65e412SManos Pitsidianakis size_offset: 0, 318*0a65e412SManos Pitsidianakis info: ::core::ptr::null(), 319*0a65e412SManos Pitsidianakis flags: VMStateFlags::VMS_END, 320*0a65e412SManos Pitsidianakis vmsd: ::core::ptr::null(), 321*0a65e412SManos Pitsidianakis version_id: 0, 322*0a65e412SManos Pitsidianakis struct_version_id: 0, 323*0a65e412SManos Pitsidianakis field_exists: None, 324*0a65e412SManos Pitsidianakis } 325*0a65e412SManos Pitsidianakis ]; 326*0a65e412SManos Pitsidianakis _FIELDS.as_ptr() 327*0a65e412SManos Pitsidianakis }} 328*0a65e412SManos Pitsidianakis } 329*0a65e412SManos Pitsidianakis 330*0a65e412SManos Pitsidianakis /// A transparent wrapper type for the `subsections` field of 331*0a65e412SManos Pitsidianakis /// [`VMStateDescription`](crate::bindings::VMStateDescription). 332*0a65e412SManos Pitsidianakis /// 333*0a65e412SManos Pitsidianakis /// This is necessary to be able to declare subsection descriptions as statics, 334*0a65e412SManos Pitsidianakis /// because the only way to implement `Sync` for a foreign type (and `*const` 335*0a65e412SManos Pitsidianakis /// pointers are foreign types in Rust) is to create a wrapper struct and 336*0a65e412SManos Pitsidianakis /// `unsafe impl Sync` for it. 337*0a65e412SManos Pitsidianakis /// 338*0a65e412SManos Pitsidianakis /// This struct is used in the 339*0a65e412SManos Pitsidianakis /// [`vm_state_subsections`](crate::vmstate_subsections) macro implementation. 340*0a65e412SManos Pitsidianakis #[repr(transparent)] 341*0a65e412SManos Pitsidianakis pub struct VMStateSubsectionsWrapper(pub &'static [*const crate::bindings::VMStateDescription]); 342*0a65e412SManos Pitsidianakis 343*0a65e412SManos Pitsidianakis unsafe impl Sync for VMStateSubsectionsWrapper {} 344*0a65e412SManos Pitsidianakis 345*0a65e412SManos Pitsidianakis /// Helper macro to declare a list of subsections 346*0a65e412SManos Pitsidianakis /// ([`VMStateDescription`](`crate::bindings::VMStateDescription`)) into a 347*0a65e412SManos Pitsidianakis /// static and return a pointer to the array of pointers it created. 348*0a65e412SManos Pitsidianakis #[macro_export] 349*0a65e412SManos Pitsidianakis macro_rules! vmstate_subsections { 350*0a65e412SManos Pitsidianakis ($($subsection:expr),*$(,)*) => {{ 351*0a65e412SManos Pitsidianakis static _SUBSECTIONS: $crate::vmstate::VMStateSubsectionsWrapper = $crate::vmstate::VMStateSubsectionsWrapper(&[ 352*0a65e412SManos Pitsidianakis $({ 353*0a65e412SManos Pitsidianakis static _SUBSECTION: $crate::bindings::VMStateDescription = $subsection; 354*0a65e412SManos Pitsidianakis ::core::ptr::addr_of!(_SUBSECTION) 355*0a65e412SManos Pitsidianakis }),*, 356*0a65e412SManos Pitsidianakis ::core::ptr::null() 357*0a65e412SManos Pitsidianakis ]); 358*0a65e412SManos Pitsidianakis _SUBSECTIONS.0.as_ptr() 359*0a65e412SManos Pitsidianakis }} 360*0a65e412SManos Pitsidianakis } 361