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, os::raw::c_void}; 6 7 use qemu_api::{ 8 bindings::*, 9 c_str, declare_properties, define_property, 10 definitions::{Class, ObjectImpl}, 11 device_class, device_class_init, 12 zeroable::Zeroable, 13 }; 14 15 #[test] 16 fn test_device_decl_macros() { 17 // Test that macros can compile. 18 pub static VMSTATE: VMStateDescription = VMStateDescription { 19 name: c_str!("name").as_ptr(), 20 unmigratable: true, 21 ..Zeroable::ZERO 22 }; 23 24 #[derive(qemu_api_macros::offsets)] 25 #[repr(C)] 26 #[derive(qemu_api_macros::Object)] 27 pub struct DummyState { 28 pub _parent: DeviceState, 29 pub migrate_clock: bool, 30 } 31 32 #[repr(C)] 33 pub struct DummyClass { 34 pub _parent: DeviceClass, 35 } 36 37 declare_properties! { 38 DUMMY_PROPERTIES, 39 define_property!( 40 c_str!("migrate-clk"), 41 DummyState, 42 migrate_clock, 43 unsafe { &qdev_prop_bool }, 44 bool 45 ), 46 } 47 48 device_class_init! { 49 dummy_class_init, 50 props => DUMMY_PROPERTIES, 51 realize_fn => None, 52 legacy_reset_fn => None, 53 vmsd => VMSTATE, 54 } 55 56 impl ObjectImpl for DummyState { 57 type Class = DummyClass; 58 const TYPE_INFO: qemu_api::bindings::TypeInfo = qemu_api::type_info! { Self }; 59 const TYPE_NAME: &'static CStr = c_str!("dummy"); 60 const PARENT_TYPE_NAME: Option<&'static CStr> = Some(device_class::TYPE_DEVICE); 61 const ABSTRACT: bool = false; 62 const INSTANCE_INIT: Option<unsafe extern "C" fn(obj: *mut Object)> = None; 63 const INSTANCE_POST_INIT: Option<unsafe extern "C" fn(obj: *mut Object)> = None; 64 const INSTANCE_FINALIZE: Option<unsafe extern "C" fn(obj: *mut Object)> = None; 65 } 66 67 impl Class for DummyClass { 68 const CLASS_INIT: Option<unsafe extern "C" fn(klass: *mut ObjectClass, data: *mut c_void)> = 69 Some(dummy_class_init); 70 const CLASS_BASE_INIT: Option< 71 unsafe extern "C" fn(klass: *mut ObjectClass, data: *mut c_void), 72 > = None; 73 } 74 75 unsafe { 76 module_call_init(module_init_type::MODULE_INIT_QOM); 77 object_unref(object_new(DummyState::TYPE_NAME.as_ptr()) as *mut _); 78 } 79 } 80