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 7*9f7d4520SPaolo Bonzini use std::{ffi::CStr, os::raw::c_void}; 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 { 32e90d4707SPaolo Bonzini ($type:ident => $body:block) => { 33e90d4707SPaolo Bonzini const _: () = { 345a5110d2SManos Pitsidianakis #[used] 354f752191SPaolo Bonzini #[cfg_attr( 364f752191SPaolo Bonzini not(any(target_vendor = "apple", target_os = "windows")), 374f752191SPaolo Bonzini link_section = ".init_array" 384f752191SPaolo Bonzini )] 394f752191SPaolo Bonzini #[cfg_attr(target_vendor = "apple", link_section = "__DATA,__mod_init_func")] 405a5110d2SManos Pitsidianakis #[cfg_attr(target_os = "windows", link_section = ".CRT$XCU")] 415a5110d2SManos Pitsidianakis pub static LOAD_MODULE: extern "C" fn() = { 42e90d4707SPaolo Bonzini extern "C" fn init_fn() { 435a5110d2SManos Pitsidianakis $body 445a5110d2SManos Pitsidianakis } 455a5110d2SManos Pitsidianakis 46e90d4707SPaolo Bonzini extern "C" fn ctor_fn() { 475a5110d2SManos Pitsidianakis unsafe { 485a5110d2SManos Pitsidianakis $crate::bindings::register_module_init( 49e90d4707SPaolo Bonzini Some(init_fn), 50e90d4707SPaolo Bonzini $crate::bindings::module_init_type::$type, 515a5110d2SManos Pitsidianakis ); 525a5110d2SManos Pitsidianakis } 535a5110d2SManos Pitsidianakis } 545a5110d2SManos Pitsidianakis 55e90d4707SPaolo Bonzini ctor_fn 565a5110d2SManos Pitsidianakis }; 575a5110d2SManos Pitsidianakis }; 58e90d4707SPaolo Bonzini }; 59e90d4707SPaolo Bonzini 60e90d4707SPaolo Bonzini // shortcut because it's quite common that $body needs unsafe {} 61e90d4707SPaolo Bonzini ($type:ident => unsafe $body:block) => { 62e90d4707SPaolo Bonzini $crate::module_init! { 63e90d4707SPaolo Bonzini $type => { unsafe { $body } } 64e90d4707SPaolo Bonzini } 65e90d4707SPaolo Bonzini }; 665a5110d2SManos Pitsidianakis } 675a5110d2SManos Pitsidianakis 685a5110d2SManos Pitsidianakis #[macro_export] 695a5110d2SManos Pitsidianakis macro_rules! type_info { 705a5110d2SManos Pitsidianakis ($t:ty) => { 715a5110d2SManos Pitsidianakis $crate::bindings::TypeInfo { 725a5110d2SManos Pitsidianakis name: <$t as $crate::definitions::ObjectImpl>::TYPE_NAME.as_ptr(), 735a5110d2SManos Pitsidianakis parent: if let Some(pname) = <$t as $crate::definitions::ObjectImpl>::PARENT_TYPE_NAME { 745a5110d2SManos Pitsidianakis pname.as_ptr() 755a5110d2SManos Pitsidianakis } else { 765a5110d2SManos Pitsidianakis ::core::ptr::null_mut() 775a5110d2SManos Pitsidianakis }, 7800ed18deSPaolo Bonzini instance_size: ::core::mem::size_of::<$t>(), 7900ed18deSPaolo Bonzini instance_align: ::core::mem::align_of::<$t>(), 805a5110d2SManos Pitsidianakis instance_init: <$t as $crate::definitions::ObjectImpl>::INSTANCE_INIT, 815a5110d2SManos Pitsidianakis instance_post_init: <$t as $crate::definitions::ObjectImpl>::INSTANCE_POST_INIT, 825a5110d2SManos Pitsidianakis instance_finalize: <$t as $crate::definitions::ObjectImpl>::INSTANCE_FINALIZE, 835a5110d2SManos Pitsidianakis abstract_: <$t as $crate::definitions::ObjectImpl>::ABSTRACT, 8400ed18deSPaolo Bonzini class_size: ::core::mem::size_of::<<$t as $crate::definitions::ObjectImpl>::Class>(), 855a5110d2SManos Pitsidianakis class_init: <<$t as $crate::definitions::ObjectImpl>::Class as $crate::definitions::Class>::CLASS_INIT, 865a5110d2SManos Pitsidianakis class_base_init: <<$t as $crate::definitions::ObjectImpl>::Class as $crate::definitions::Class>::CLASS_BASE_INIT, 875a5110d2SManos Pitsidianakis class_data: ::core::ptr::null_mut(), 885a5110d2SManos Pitsidianakis interfaces: ::core::ptr::null_mut(), 895a5110d2SManos Pitsidianakis }; 905a5110d2SManos Pitsidianakis } 915a5110d2SManos Pitsidianakis } 92