diff options
Diffstat (limited to 'rust/qemu-api')
-rw-r--r-- | rust/qemu-api/src/bindings.rs | 6 | ||||
-rw-r--r-- | rust/qemu-api/src/qdev.rs | 68 | ||||
-rw-r--r-- | rust/qemu-api/src/vmstate.rs | 2 |
3 files changed, 49 insertions, 27 deletions
diff --git a/rust/qemu-api/src/bindings.rs b/rust/qemu-api/src/bindings.rs index be6dd68..6e70a75 100644 --- a/rust/qemu-api/src/bindings.rs +++ b/rust/qemu-api/src/bindings.rs @@ -34,12 +34,6 @@ unsafe impl Sync for CharBackend {} unsafe impl Send for Chardev {} unsafe impl Sync for Chardev {} -unsafe impl Send for Clock {} -unsafe impl Sync for Clock {} - -unsafe impl Send for DeviceState {} -unsafe impl Sync for DeviceState {} - unsafe impl Send for MemoryRegion {} unsafe impl Sync for MemoryRegion {} diff --git a/rust/qemu-api/src/qdev.rs b/rust/qemu-api/src/qdev.rs index 1a4d1f3..1c4a67b 100644 --- a/rust/qemu-api/src/qdev.rs +++ b/rust/qemu-api/src/qdev.rs @@ -10,12 +10,12 @@ use std::{ ptr::NonNull, }; -pub use bindings::{Clock, ClockEvent, DeviceClass, DeviceState, Property, ResetType}; +pub use bindings::{ClockEvent, DeviceClass, Property, ResetType}; use crate::{ bindings::{self, qdev_init_gpio_in, qdev_init_gpio_out, Error, ResettableClass}, callbacks::FnCall, - cell::bql_locked, + cell::{bql_locked, Opaque}, chardev::Chardev, irq::InterruptSource, prelude::*, @@ -23,6 +23,22 @@ use crate::{ vmstate::VMStateDescription, }; +/// A safe wrapper around [`bindings::Clock`]. +#[repr(transparent)] +#[derive(Debug, qemu_api_macros::Wrapper)] +pub struct Clock(Opaque<bindings::Clock>); + +unsafe impl Send for Clock {} +unsafe impl Sync for Clock {} + +/// A safe wrapper around [`bindings::DeviceState`]. +#[repr(transparent)] +#[derive(Debug, qemu_api_macros::Wrapper)] +pub struct DeviceState(Opaque<bindings::DeviceState>); + +unsafe impl Send for DeviceState {} +unsafe impl Sync for DeviceState {} + /// Trait providing the contents of the `ResettablePhases` struct, /// which is part of the QOM `Resettable` interface. pub trait ResettablePhasesImpl { @@ -117,7 +133,10 @@ pub trait DeviceImpl: ObjectImpl + ResettablePhasesImpl + IsA<DeviceState> { /// We expect the FFI user of this function to pass a valid pointer that /// can be downcasted to type `T`. We also expect the device is /// readable/writeable from one thread at any time. -unsafe extern "C" fn rust_realize_fn<T: DeviceImpl>(dev: *mut DeviceState, _errp: *mut *mut Error) { +unsafe extern "C" fn rust_realize_fn<T: DeviceImpl>( + dev: *mut bindings::DeviceState, + _errp: *mut *mut Error, +) { let state = NonNull::new(dev).unwrap().cast::<T>(); T::REALIZE.unwrap()(unsafe { state.as_ref() }); } @@ -251,7 +270,7 @@ where events: ClockEvent, ) -> Owned<Clock> { fn do_init_clock_in( - dev: *mut DeviceState, + dev: &DeviceState, name: &str, cb: Option<unsafe extern "C" fn(*mut c_void, ClockEvent)>, events: ClockEvent, @@ -265,14 +284,15 @@ where unsafe { let cstr = CString::new(name).unwrap(); let clk = bindings::qdev_init_clock_in( - dev, + dev.as_mut_ptr(), cstr.as_ptr(), cb, - dev.cast::<c_void>(), + dev.as_void_ptr(), events.0, ); - Owned::from(&*clk) + let clk: &Clock = Clock::from_raw(clk); + Owned::from(clk) } } @@ -289,7 +309,7 @@ where None }; - do_init_clock_in(self.as_mut_ptr(), name, cb, events) + do_init_clock_in(self.upcast(), name, cb, events) } /// Add an output clock named `name`. @@ -304,9 +324,10 @@ where fn init_clock_out(&self, name: &str) -> Owned<Clock> { unsafe { let cstr = CString::new(name).unwrap(); - let clk = bindings::qdev_init_clock_out(self.as_mut_ptr(), cstr.as_ptr()); + let clk = bindings::qdev_init_clock_out(self.upcast().as_mut_ptr(), cstr.as_ptr()); - Owned::from(&*clk) + let clk: &Clock = Clock::from_raw(clk); + Owned::from(clk) } } @@ -314,7 +335,11 @@ where assert!(bql_locked()); let c_propname = CString::new(propname).unwrap(); unsafe { - bindings::qdev_prop_set_chr(self.as_mut_ptr(), c_propname.as_ptr(), chr.as_mut_ptr()); + bindings::qdev_prop_set_chr( + self.upcast().as_mut_ptr(), + c_propname.as_ptr(), + chr.as_mut_ptr(), + ); } } @@ -323,8 +348,17 @@ where num_lines: u32, _cb: F, ) { - let _: () = F::ASSERT_IS_SOME; + fn do_init_gpio_in( + dev: &DeviceState, + num_lines: u32, + gpio_in_cb: unsafe extern "C" fn(*mut c_void, c_int, c_int), + ) { + unsafe { + qdev_init_gpio_in(dev.as_mut_ptr(), Some(gpio_in_cb), num_lines as c_int); + } + } + let _: () = F::ASSERT_IS_SOME; unsafe extern "C" fn rust_irq_handler<T, F: for<'a> FnCall<(&'a T, u32, u32)>>( opaque: *mut c_void, line: c_int, @@ -337,19 +371,13 @@ where let gpio_in_cb: unsafe extern "C" fn(*mut c_void, c_int, c_int) = rust_irq_handler::<Self::Target, F>; - unsafe { - qdev_init_gpio_in( - self.as_mut_ptr::<DeviceState>(), - Some(gpio_in_cb), - num_lines as c_int, - ); - } + do_init_gpio_in(self.upcast(), num_lines, gpio_in_cb); } fn init_gpio_out(&self, pins: &[InterruptSource]) { unsafe { qdev_init_gpio_out( - self.as_mut_ptr::<DeviceState>(), + self.upcast().as_mut_ptr(), InterruptSource::slice_as_ptr(pins), pins.len() as c_int, ); diff --git a/rust/qemu-api/src/vmstate.rs b/rust/qemu-api/src/vmstate.rs index 1e7ba53..f0510ae 100644 --- a/rust/qemu-api/src/vmstate.rs +++ b/rust/qemu-api/src/vmstate.rs @@ -470,7 +470,7 @@ macro_rules! vmstate_clock { $crate::assert_field_type!( $struct_name, $field_name, - $crate::qom::Owned<$crate::bindings::Clock> + $crate::qom::Owned<$crate::qdev::Clock> ); $crate::offset_of!($struct_name, $field_name) }, |