mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-07-27 04:13:53 -06:00
rust: qdev: wrap Clock and DeviceState with Opaque<>
Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
7fb4a99df1
commit
fc22d650d5
3 changed files with 49 additions and 27 deletions
|
@ -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 {}
|
||||
|
||||
|
|
|
@ -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,
|
||||
);
|
||||
|
|
|
@ -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)
|
||||
},
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue