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 //! Definitions required by QEMU when registering a device. 6 7 use std::{ffi::CStr, os::raw::c_void}; 8 9 use crate::bindings::{Object, ObjectClass, TypeInfo}; 10 11 /// Trait a type must implement to be registered with QEMU. 12 pub trait ObjectImpl { 13 type Class; 14 const TYPE_INFO: TypeInfo; 15 const TYPE_NAME: &'static CStr; 16 const PARENT_TYPE_NAME: Option<&'static CStr>; 17 const ABSTRACT: bool = false; 18 const INSTANCE_INIT: Option<unsafe extern "C" fn(obj: *mut Object)> = None; 19 const INSTANCE_POST_INIT: Option<unsafe extern "C" fn(obj: *mut Object)> = None; 20 const INSTANCE_FINALIZE: Option<unsafe extern "C" fn(obj: *mut Object)> = None; 21 } 22 23 /// Trait used to fill in a class struct. 24 /// 25 /// Each QOM class that has virtual methods describes them in a 26 /// _class struct_. Class structs include a parent field corresponding 27 /// to the vtable of the parent class, all the way up to [`ObjectClass`]. 28 /// Each QOM type has one such class struct. 29 /// 30 /// The Rust implementation of methods will usually come from a trait 31 /// like [`ObjectImpl`]. 32 pub trait ClassInitImpl { 33 /// Function that is called after all parent class initialization 34 /// has occurred. On entry, the virtual method pointers are set to 35 /// the default values coming from the parent classes; the function 36 /// can change them to override virtual methods of a parent class. 37 const CLASS_INIT: Option<unsafe extern "C" fn(klass: *mut ObjectClass, data: *mut c_void)>; 38 39 /// Called on descendent classes after all parent class initialization 40 /// has occurred, but before the class itself is initialized. This 41 /// is only useful if a class is not a leaf, and can be used to undo 42 /// the effects of copying the contents of the parent's class struct 43 /// to the descendants. 44 const CLASS_BASE_INIT: Option< 45 unsafe extern "C" fn(klass: *mut ObjectClass, data: *mut c_void), 46 >; 47 } 48 49 #[macro_export] 50 macro_rules! module_init { 51 ($type:ident => $body:block) => { 52 const _: () = { 53 #[used] 54 #[cfg_attr( 55 not(any(target_vendor = "apple", target_os = "windows")), 56 link_section = ".init_array" 57 )] 58 #[cfg_attr(target_vendor = "apple", link_section = "__DATA,__mod_init_func")] 59 #[cfg_attr(target_os = "windows", link_section = ".CRT$XCU")] 60 pub static LOAD_MODULE: extern "C" fn() = { 61 extern "C" fn init_fn() { 62 $body 63 } 64 65 extern "C" fn ctor_fn() { 66 unsafe { 67 $crate::bindings::register_module_init( 68 Some(init_fn), 69 $crate::bindings::module_init_type::$type, 70 ); 71 } 72 } 73 74 ctor_fn 75 }; 76 }; 77 }; 78 79 // shortcut because it's quite common that $body needs unsafe {} 80 ($type:ident => unsafe $body:block) => { 81 $crate::module_init! { 82 $type => { unsafe { $body } } 83 } 84 }; 85 } 86 87 #[macro_export] 88 macro_rules! type_info { 89 ($t:ty) => { 90 $crate::bindings::TypeInfo { 91 name: <$t as $crate::definitions::ObjectImpl>::TYPE_NAME.as_ptr(), 92 parent: if let Some(pname) = <$t as $crate::definitions::ObjectImpl>::PARENT_TYPE_NAME { 93 pname.as_ptr() 94 } else { 95 ::core::ptr::null_mut() 96 }, 97 instance_size: ::core::mem::size_of::<$t>(), 98 instance_align: ::core::mem::align_of::<$t>(), 99 instance_init: <$t as $crate::definitions::ObjectImpl>::INSTANCE_INIT, 100 instance_post_init: <$t as $crate::definitions::ObjectImpl>::INSTANCE_POST_INIT, 101 instance_finalize: <$t as $crate::definitions::ObjectImpl>::INSTANCE_FINALIZE, 102 abstract_: <$t as $crate::definitions::ObjectImpl>::ABSTRACT, 103 class_size: ::core::mem::size_of::<<$t as $crate::definitions::ObjectImpl>::Class>(), 104 class_init: <<$t as $crate::definitions::ObjectImpl>::Class as $crate::definitions::ClassInitImpl>::CLASS_INIT, 105 class_base_init: <<$t as $crate::definitions::ObjectImpl>::Class as $crate::definitions::ClassInitImpl>::CLASS_BASE_INIT, 106 class_data: ::core::ptr::null_mut(), 107 interfaces: ::core::ptr::null_mut(), 108 }; 109 } 110 } 111