mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-01 14:53:54 -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 Send for Chardev {}
|
||||||
unsafe impl Sync 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 Send for MemoryRegion {}
|
||||||
unsafe impl Sync for MemoryRegion {}
|
unsafe impl Sync for MemoryRegion {}
|
||||||
|
|
||||||
|
|
|
@ -10,12 +10,12 @@ use std::{
|
||||||
ptr::NonNull,
|
ptr::NonNull,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub use bindings::{Clock, ClockEvent, DeviceClass, DeviceState, Property, ResetType};
|
pub use bindings::{ClockEvent, DeviceClass, Property, ResetType};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
bindings::{self, qdev_init_gpio_in, qdev_init_gpio_out, Error, ResettableClass},
|
bindings::{self, qdev_init_gpio_in, qdev_init_gpio_out, Error, ResettableClass},
|
||||||
callbacks::FnCall,
|
callbacks::FnCall,
|
||||||
cell::bql_locked,
|
cell::{bql_locked, Opaque},
|
||||||
chardev::Chardev,
|
chardev::Chardev,
|
||||||
irq::InterruptSource,
|
irq::InterruptSource,
|
||||||
prelude::*,
|
prelude::*,
|
||||||
|
@ -23,6 +23,22 @@ use crate::{
|
||||||
vmstate::VMStateDescription,
|
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,
|
/// Trait providing the contents of the `ResettablePhases` struct,
|
||||||
/// which is part of the QOM `Resettable` interface.
|
/// which is part of the QOM `Resettable` interface.
|
||||||
pub trait ResettablePhasesImpl {
|
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
|
/// 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
|
/// can be downcasted to type `T`. We also expect the device is
|
||||||
/// readable/writeable from one thread at any time.
|
/// 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>();
|
let state = NonNull::new(dev).unwrap().cast::<T>();
|
||||||
T::REALIZE.unwrap()(unsafe { state.as_ref() });
|
T::REALIZE.unwrap()(unsafe { state.as_ref() });
|
||||||
}
|
}
|
||||||
|
@ -251,7 +270,7 @@ where
|
||||||
events: ClockEvent,
|
events: ClockEvent,
|
||||||
) -> Owned<Clock> {
|
) -> Owned<Clock> {
|
||||||
fn do_init_clock_in(
|
fn do_init_clock_in(
|
||||||
dev: *mut DeviceState,
|
dev: &DeviceState,
|
||||||
name: &str,
|
name: &str,
|
||||||
cb: Option<unsafe extern "C" fn(*mut c_void, ClockEvent)>,
|
cb: Option<unsafe extern "C" fn(*mut c_void, ClockEvent)>,
|
||||||
events: ClockEvent,
|
events: ClockEvent,
|
||||||
|
@ -265,14 +284,15 @@ where
|
||||||
unsafe {
|
unsafe {
|
||||||
let cstr = CString::new(name).unwrap();
|
let cstr = CString::new(name).unwrap();
|
||||||
let clk = bindings::qdev_init_clock_in(
|
let clk = bindings::qdev_init_clock_in(
|
||||||
dev,
|
dev.as_mut_ptr(),
|
||||||
cstr.as_ptr(),
|
cstr.as_ptr(),
|
||||||
cb,
|
cb,
|
||||||
dev.cast::<c_void>(),
|
dev.as_void_ptr(),
|
||||||
events.0,
|
events.0,
|
||||||
);
|
);
|
||||||
|
|
||||||
Owned::from(&*clk)
|
let clk: &Clock = Clock::from_raw(clk);
|
||||||
|
Owned::from(clk)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -289,7 +309,7 @@ where
|
||||||
None
|
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`.
|
/// Add an output clock named `name`.
|
||||||
|
@ -304,9 +324,10 @@ where
|
||||||
fn init_clock_out(&self, name: &str) -> Owned<Clock> {
|
fn init_clock_out(&self, name: &str) -> Owned<Clock> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let cstr = CString::new(name).unwrap();
|
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());
|
assert!(bql_locked());
|
||||||
let c_propname = CString::new(propname).unwrap();
|
let c_propname = CString::new(propname).unwrap();
|
||||||
unsafe {
|
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,
|
num_lines: u32,
|
||||||
_cb: F,
|
_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)>>(
|
unsafe extern "C" fn rust_irq_handler<T, F: for<'a> FnCall<(&'a T, u32, u32)>>(
|
||||||
opaque: *mut c_void,
|
opaque: *mut c_void,
|
||||||
line: c_int,
|
line: c_int,
|
||||||
|
@ -337,19 +371,13 @@ where
|
||||||
let gpio_in_cb: unsafe extern "C" fn(*mut c_void, c_int, c_int) =
|
let gpio_in_cb: unsafe extern "C" fn(*mut c_void, c_int, c_int) =
|
||||||
rust_irq_handler::<Self::Target, F>;
|
rust_irq_handler::<Self::Target, F>;
|
||||||
|
|
||||||
unsafe {
|
do_init_gpio_in(self.upcast(), num_lines, gpio_in_cb);
|
||||||
qdev_init_gpio_in(
|
|
||||||
self.as_mut_ptr::<DeviceState>(),
|
|
||||||
Some(gpio_in_cb),
|
|
||||||
num_lines as c_int,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init_gpio_out(&self, pins: &[InterruptSource]) {
|
fn init_gpio_out(&self, pins: &[InterruptSource]) {
|
||||||
unsafe {
|
unsafe {
|
||||||
qdev_init_gpio_out(
|
qdev_init_gpio_out(
|
||||||
self.as_mut_ptr::<DeviceState>(),
|
self.upcast().as_mut_ptr(),
|
||||||
InterruptSource::slice_as_ptr(pins),
|
InterruptSource::slice_as_ptr(pins),
|
||||||
pins.len() as c_int,
|
pins.len() as c_int,
|
||||||
);
|
);
|
||||||
|
|
|
@ -470,7 +470,7 @@ macro_rules! vmstate_clock {
|
||||||
$crate::assert_field_type!(
|
$crate::assert_field_type!(
|
||||||
$struct_name,
|
$struct_name,
|
||||||
$field_name,
|
$field_name,
|
||||||
$crate::qom::Owned<$crate::bindings::Clock>
|
$crate::qom::Owned<$crate::qdev::Clock>
|
||||||
);
|
);
|
||||||
$crate::offset_of!($struct_name, $field_name)
|
$crate::offset_of!($struct_name, $field_name)
|
||||||
},
|
},
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue