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]
test_device_decl_macros()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