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