aboutsummaryrefslogtreecommitdiff
path: root/rust/qemu-api/src/irq.rs
diff options
context:
space:
mode:
Diffstat (limited to 'rust/qemu-api/src/irq.rs')
-rw-r--r--rust/qemu-api/src/irq.rs38
1 files changed, 31 insertions, 7 deletions
diff --git a/rust/qemu-api/src/irq.rs b/rust/qemu-api/src/irq.rs
index 6258141..1526e6f 100644
--- a/rust/qemu-api/src/irq.rs
+++ b/rust/qemu-api/src/irq.rs
@@ -4,14 +4,24 @@
//! Bindings for interrupt sources
-use core::ptr;
-use std::{marker::PhantomData, os::raw::c_int};
+use std::{
+ ffi::{c_int, CStr},
+ marker::PhantomData,
+ ptr,
+};
use crate::{
- bindings::{qemu_set_irq, IRQState},
+ bindings::{self, qemu_set_irq},
+ cell::Opaque,
prelude::*,
+ qom::ObjectClass,
};
+/// An opaque wrapper around [`bindings::IRQState`].
+#[repr(transparent)]
+#[derive(Debug, qemu_api_macros::Wrapper)]
+pub struct IRQState(Opaque<bindings::IRQState>);
+
/// Interrupt sources are used by devices to pass changes to a value (typically
/// a boolean). The interrupt sink is usually an interrupt controller or
/// GPIO controller.
@@ -24,8 +34,7 @@ use crate::{
///
/// Interrupts are implemented as a pointer to the interrupt "sink", which has
/// type [`IRQState`]. A device exposes its source as a QOM link property using
-/// a function such as
-/// [`SysBusDevice::init_irq`](crate::sysbus::SysBusDevice::init_irq), and
+/// a function such as [`SysBusDeviceMethods::init_irq`], and
/// initially leaves the pointer to a NULL value, representing an unconnected
/// interrupt. To connect it, whoever creates the device fills the pointer with
/// the sink's `IRQState *`, for example using `sysbus_connect_irq`. Because
@@ -40,10 +49,13 @@ pub struct InterruptSource<T = bool>
where
c_int: From<T>,
{
- cell: BqlCell<*mut IRQState>,
+ cell: BqlCell<*mut bindings::IRQState>,
_marker: PhantomData<T>,
}
+// SAFETY: the implementation asserts via `BqlCell` that the BQL is taken
+unsafe impl<T> Sync for InterruptSource<T> where c_int: From<T> {}
+
impl InterruptSource<bool> {
/// Send a low (`false`) value to the interrupt sink.
pub fn lower(&self) {
@@ -76,9 +88,14 @@ where
}
}
- pub(crate) const fn as_ptr(&self) -> *mut *mut IRQState {
+ pub(crate) const fn as_ptr(&self) -> *mut *mut bindings::IRQState {
self.cell.as_ptr()
}
+
+ pub(crate) const fn slice_as_ptr(slice: &[Self]) -> *mut *mut bindings::IRQState {
+ assert!(!slice.is_empty());
+ slice[0].as_ptr()
+ }
}
impl Default for InterruptSource {
@@ -89,3 +106,10 @@ impl Default for InterruptSource {
}
}
}
+
+unsafe impl ObjectType for IRQState {
+ type Class = ObjectClass;
+ const TYPE_NAME: &'static CStr =
+ unsafe { CStr::from_bytes_with_nul_unchecked(bindings::TYPE_IRQ) };
+}
+qom_isa!(IRQState: Object);