xref: /openbmc/qemu/rust/qemu-api/src/definitions.rs (revision 4f752191)
15a5110d2SManos Pitsidianakis // Copyright 2024, Linaro Limited
25a5110d2SManos Pitsidianakis // Author(s): Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
35a5110d2SManos Pitsidianakis // SPDX-License-Identifier: GPL-2.0-or-later
45a5110d2SManos Pitsidianakis 
55a5110d2SManos Pitsidianakis //! Definitions required by QEMU when registering a device.
65a5110d2SManos Pitsidianakis 
75a5110d2SManos Pitsidianakis use ::core::ffi::{c_void, CStr};
85a5110d2SManos Pitsidianakis 
95a5110d2SManos Pitsidianakis use crate::bindings::{Object, ObjectClass, TypeInfo};
105a5110d2SManos Pitsidianakis 
115a5110d2SManos Pitsidianakis /// Trait a type must implement to be registered with QEMU.
125a5110d2SManos Pitsidianakis pub trait ObjectImpl {
135a5110d2SManos Pitsidianakis     type Class;
145a5110d2SManos Pitsidianakis     const TYPE_INFO: TypeInfo;
155a5110d2SManos Pitsidianakis     const TYPE_NAME: &'static CStr;
165a5110d2SManos Pitsidianakis     const PARENT_TYPE_NAME: Option<&'static CStr>;
175a5110d2SManos Pitsidianakis     const ABSTRACT: bool;
185a5110d2SManos Pitsidianakis     const INSTANCE_INIT: Option<unsafe extern "C" fn(obj: *mut Object)>;
195a5110d2SManos Pitsidianakis     const INSTANCE_POST_INIT: Option<unsafe extern "C" fn(obj: *mut Object)>;
205a5110d2SManos Pitsidianakis     const INSTANCE_FINALIZE: Option<unsafe extern "C" fn(obj: *mut Object)>;
215a5110d2SManos Pitsidianakis }
225a5110d2SManos Pitsidianakis 
235a5110d2SManos Pitsidianakis pub trait Class {
245a5110d2SManos Pitsidianakis     const CLASS_INIT: Option<unsafe extern "C" fn(klass: *mut ObjectClass, data: *mut c_void)>;
255a5110d2SManos Pitsidianakis     const CLASS_BASE_INIT: Option<
265a5110d2SManos Pitsidianakis         unsafe extern "C" fn(klass: *mut ObjectClass, data: *mut c_void),
275a5110d2SManos Pitsidianakis     >;
285a5110d2SManos Pitsidianakis }
295a5110d2SManos Pitsidianakis 
305a5110d2SManos Pitsidianakis #[macro_export]
315a5110d2SManos Pitsidianakis macro_rules! module_init {
325a5110d2SManos Pitsidianakis     ($func:expr, $type:expr) => {
335a5110d2SManos Pitsidianakis         #[used]
34*4f752191SPaolo Bonzini         #[cfg_attr(
35*4f752191SPaolo Bonzini             not(any(target_vendor = "apple", target_os = "windows")),
36*4f752191SPaolo Bonzini             link_section = ".init_array"
37*4f752191SPaolo Bonzini         )]
38*4f752191SPaolo Bonzini         #[cfg_attr(target_vendor = "apple", link_section = "__DATA,__mod_init_func")]
395a5110d2SManos Pitsidianakis         #[cfg_attr(target_os = "windows", link_section = ".CRT$XCU")]
405a5110d2SManos Pitsidianakis         pub static LOAD_MODULE: extern "C" fn() = {
415a5110d2SManos Pitsidianakis             extern "C" fn __load() {
425a5110d2SManos Pitsidianakis                 unsafe {
435a5110d2SManos Pitsidianakis                     $crate::bindings::register_module_init(Some($func), $type);
445a5110d2SManos Pitsidianakis                 }
455a5110d2SManos Pitsidianakis             }
465a5110d2SManos Pitsidianakis 
475a5110d2SManos Pitsidianakis             __load
485a5110d2SManos Pitsidianakis         };
495a5110d2SManos Pitsidianakis     };
505a5110d2SManos Pitsidianakis     (qom: $func:ident => $body:block) => {
515a5110d2SManos Pitsidianakis         // NOTE: To have custom identifiers for the ctor func we need to either supply
525a5110d2SManos Pitsidianakis         // them directly as a macro argument or create them with a proc macro.
535a5110d2SManos Pitsidianakis         #[used]
54*4f752191SPaolo Bonzini         #[cfg_attr(
55*4f752191SPaolo Bonzini             not(any(target_vendor = "apple", target_os = "windows")),
56*4f752191SPaolo Bonzini             link_section = ".init_array"
57*4f752191SPaolo Bonzini         )]
58*4f752191SPaolo Bonzini         #[cfg_attr(target_vendor = "apple", link_section = "__DATA,__mod_init_func")]
595a5110d2SManos Pitsidianakis         #[cfg_attr(target_os = "windows", link_section = ".CRT$XCU")]
605a5110d2SManos Pitsidianakis         pub static LOAD_MODULE: extern "C" fn() = {
615a5110d2SManos Pitsidianakis             extern "C" fn __load() {
625a5110d2SManos Pitsidianakis                 unsafe extern "C" fn $func() {
635a5110d2SManos Pitsidianakis                     $body
645a5110d2SManos Pitsidianakis                 }
655a5110d2SManos Pitsidianakis 
665a5110d2SManos Pitsidianakis                 unsafe {
675a5110d2SManos Pitsidianakis                     $crate::bindings::register_module_init(
685a5110d2SManos Pitsidianakis                         Some($func),
695a5110d2SManos Pitsidianakis                         $crate::bindings::module_init_type::MODULE_INIT_QOM,
705a5110d2SManos Pitsidianakis                     );
715a5110d2SManos Pitsidianakis                 }
725a5110d2SManos Pitsidianakis             }
735a5110d2SManos Pitsidianakis 
745a5110d2SManos Pitsidianakis             __load
755a5110d2SManos Pitsidianakis         };
765a5110d2SManos Pitsidianakis     };
775a5110d2SManos Pitsidianakis }
785a5110d2SManos Pitsidianakis 
795a5110d2SManos Pitsidianakis #[macro_export]
805a5110d2SManos Pitsidianakis macro_rules! type_info {
815a5110d2SManos Pitsidianakis     ($t:ty) => {
825a5110d2SManos Pitsidianakis         $crate::bindings::TypeInfo {
835a5110d2SManos Pitsidianakis             name: <$t as $crate::definitions::ObjectImpl>::TYPE_NAME.as_ptr(),
845a5110d2SManos Pitsidianakis             parent: if let Some(pname) = <$t as $crate::definitions::ObjectImpl>::PARENT_TYPE_NAME {
855a5110d2SManos Pitsidianakis                 pname.as_ptr()
865a5110d2SManos Pitsidianakis             } else {
875a5110d2SManos Pitsidianakis                 ::core::ptr::null_mut()
885a5110d2SManos Pitsidianakis             },
8900ed18deSPaolo Bonzini             instance_size: ::core::mem::size_of::<$t>(),
9000ed18deSPaolo Bonzini             instance_align: ::core::mem::align_of::<$t>(),
915a5110d2SManos Pitsidianakis             instance_init: <$t as $crate::definitions::ObjectImpl>::INSTANCE_INIT,
925a5110d2SManos Pitsidianakis             instance_post_init: <$t as $crate::definitions::ObjectImpl>::INSTANCE_POST_INIT,
935a5110d2SManos Pitsidianakis             instance_finalize: <$t as $crate::definitions::ObjectImpl>::INSTANCE_FINALIZE,
945a5110d2SManos Pitsidianakis             abstract_: <$t as $crate::definitions::ObjectImpl>::ABSTRACT,
9500ed18deSPaolo Bonzini             class_size:  ::core::mem::size_of::<<$t as $crate::definitions::ObjectImpl>::Class>(),
965a5110d2SManos Pitsidianakis             class_init: <<$t as $crate::definitions::ObjectImpl>::Class as $crate::definitions::Class>::CLASS_INIT,
975a5110d2SManos Pitsidianakis             class_base_init: <<$t as $crate::definitions::ObjectImpl>::Class as $crate::definitions::Class>::CLASS_BASE_INIT,
985a5110d2SManos Pitsidianakis             class_data: ::core::ptr::null_mut(),
995a5110d2SManos Pitsidianakis             interfaces: ::core::ptr::null_mut(),
1005a5110d2SManos Pitsidianakis         };
1015a5110d2SManos Pitsidianakis     }
1025a5110d2SManos Pitsidianakis }
103