Prepare for having ObjectClass, DeviceClass and SysbusDeviceClass
defined outside the hwcore and qom crates. It then becomes
impossible to add a method to them.
Extracted from a patch by Marc-André Lureau.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
rust/hw/core/src/prelude.rs | 3 +++
rust/hw/core/src/qdev.rs | 25 +++++++++++++++----------
rust/hw/core/src/sysbus.rs | 10 +++++++---
rust/qom/src/prelude.rs | 1 +
rust/qom/src/qom.rs | 8 ++++++--
5 files changed, 32 insertions(+), 15 deletions(-)
diff --git a/rust/hw/core/src/prelude.rs b/rust/hw/core/src/prelude.rs
index c544c317b39..13f7dfc6809 100644
--- a/rust/hw/core/src/prelude.rs
+++ b/rust/hw/core/src/prelude.rs
@@ -1,6 +1,8 @@
//! Essential types and traits intended for blanket imports.
pub use crate::qdev::Clock;
+
+pub use crate::qdev::DeviceClassExt;
pub use crate::qdev::DeviceState;
pub use crate::qdev::DeviceImpl;
pub use crate::qdev::DeviceMethods;
@@ -8,6 +10,7 @@
pub use crate::qdev::ResetType;
pub use crate::sysbus::SysBusDevice;
+pub use crate::sysbus::SysBusDeviceClassExt;
pub use crate::sysbus::SysBusDeviceImpl;
pub use crate::sysbus::SysBusDeviceMethods;
diff --git a/rust/hw/core/src/qdev.rs b/rust/hw/core/src/qdev.rs
index 87232becbad..f6037fbdcae 100644
--- a/rust/hw/core/src/qdev.rs
+++ b/rust/hw/core/src/qdev.rs
@@ -15,9 +15,9 @@
use qom::{prelude::*, ObjectClass};
use util::{Error, Result};
-pub use crate::bindings::{ClockEvent, DeviceClass, Property, ResetType};
+pub use crate::bindings::{ClockEvent, ResetType};
use crate::{
- bindings::{self, qdev_init_gpio_in, qdev_init_gpio_out, ResettableClass},
+ bindings::{self, qdev_init_gpio_in, qdev_init_gpio_out, DeviceClass, Property},
irq::InterruptSource,
};
@@ -206,6 +206,9 @@ pub trait DeviceImpl:
}
}
+#[repr(transparent)]
+pub struct ResettableClass(bindings::ResettableClass);
+
unsafe impl InterfaceType for ResettableClass {
const TYPE_NAME: &'static CStr =
unsafe { CStr::from_bytes_with_nul_unchecked(bindings::TYPE_RESETTABLE_INTERFACE) };
@@ -214,23 +217,25 @@ unsafe impl InterfaceType for ResettableClass {
impl ResettableClass {
/// Fill in the virtual methods of `ResettableClass` based on the
/// definitions in the `ResettablePhasesImpl` trait.
- pub fn class_init<T: ResettablePhasesImpl>(&mut self) {
+ fn class_init<T: ResettablePhasesImpl>(&mut self) {
if <T as ResettablePhasesImpl>::ENTER.is_some() {
- self.phases.enter = Some(rust_resettable_enter_fn::<T>);
+ self.0.phases.enter = Some(rust_resettable_enter_fn::<T>);
}
if <T as ResettablePhasesImpl>::HOLD.is_some() {
- self.phases.hold = Some(rust_resettable_hold_fn::<T>);
+ self.0.phases.hold = Some(rust_resettable_hold_fn::<T>);
}
if <T as ResettablePhasesImpl>::EXIT.is_some() {
- self.phases.exit = Some(rust_resettable_exit_fn::<T>);
+ self.0.phases.exit = Some(rust_resettable_exit_fn::<T>);
}
}
}
-impl DeviceClass {
- /// Fill in the virtual methods of `DeviceClass` based on the definitions in
- /// the `DeviceImpl` trait.
- pub fn class_init<T: DeviceImpl>(&mut self) {
+pub trait DeviceClassExt {
+ fn class_init<T: DeviceImpl>(&mut self);
+}
+
+impl DeviceClassExt for DeviceClass {
+ fn class_init<T: DeviceImpl>(&mut self) {
if <T as DeviceImpl>::REALIZE.is_some() {
self.realize = Some(rust_realize_fn::<T>);
}
diff --git a/rust/hw/core/src/sysbus.rs b/rust/hw/core/src/sysbus.rs
index 071fccff1e6..81fab3f1910 100644
--- a/rust/hw/core/src/sysbus.rs
+++ b/rust/hw/core/src/sysbus.rs
@@ -15,7 +15,7 @@
use crate::{
bindings,
irq::{IRQState, InterruptSource},
- qdev::{DeviceImpl, DeviceState},
+ qdev::{DeviceClassExt, DeviceImpl, DeviceState},
};
/// A safe wrapper around [`bindings::SysBusDevice`].
@@ -37,10 +37,14 @@ unsafe impl ObjectType for SysBusDevice {
// TODO: add virtual methods
pub trait SysBusDeviceImpl: DeviceImpl + IsA<SysBusDevice> {}
-impl SysBusDeviceClass {
+pub trait SysBusDeviceClassExt {
+ fn class_init<T: SysBusDeviceImpl>(&mut self);
+}
+
+impl SysBusDeviceClassExt for SysBusDeviceClass {
/// Fill in the virtual methods of `SysBusDeviceClass` based on the
/// definitions in the `SysBusDeviceImpl` trait.
- pub fn class_init<T: SysBusDeviceImpl>(self: &mut SysBusDeviceClass) {
+ fn class_init<T: SysBusDeviceImpl>(&mut self) {
self.parent_class.class_init::<T>();
}
}
diff --git a/rust/qom/src/prelude.rs b/rust/qom/src/prelude.rs
index 6a1ecaef2a7..1d1177f1e0d 100644
--- a/rust/qom/src/prelude.rs
+++ b/rust/qom/src/prelude.rs
@@ -4,6 +4,7 @@
pub use crate::qom::IsA;
pub use crate::qom::Object;
pub use crate::qom::ObjectCast;
+pub use crate::qom::ObjectClassExt;
pub use crate::qom::ObjectClassMethods;
pub use crate::qom::ObjectDeref;
pub use crate::qom::ObjectImpl;
diff --git a/rust/qom/src/qom.rs b/rust/qom/src/qom.rs
index 84455cea79b..cc00ddcfc98 100644
--- a/rust/qom/src/qom.rs
+++ b/rust/qom/src/qom.rs
@@ -729,10 +729,14 @@ pub trait ObjectImpl: ObjectType + IsA<Object> {
T::UNPARENT.unwrap()(unsafe { state.as_ref() });
}
-impl ObjectClass {
+pub trait ObjectClassExt {
+ fn class_init<T: ObjectImpl>(&mut self);
+}
+
+impl ObjectClassExt for ObjectClass {
/// Fill in the virtual methods of `ObjectClass` based on the definitions in
/// the `ObjectImpl` trait.
- pub fn class_init<T: ObjectImpl>(&mut self) {
+ fn class_init<T: ObjectImpl>(&mut self) {
if <T as ObjectImpl>::UNPARENT.is_some() {
self.unparent = Some(rust_unparent_fn::<T>);
}
--
2.52.0
© 2016 - 2026 Red Hat, Inc.