MemoryRegionOps (and its builder type) only support read/write
callbacks.
Add the ability to define {read,write}_with_attrs callbacks for devices
that need them.
Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
---
rust/qemu-api/meson.build | 1 +
rust/qemu-api/src/memory.rs | 52 ++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 52 insertions(+), 1 deletion(-)
diff --git a/rust/qemu-api/meson.build b/rust/qemu-api/meson.build
index a090297c458b1a282211b9e241c0e447dd594167..95c097ec8f8dd31a863339d58eaa8bfc4d4dea18 100644
--- a/rust/qemu-api/meson.build
+++ b/rust/qemu-api/meson.build
@@ -26,6 +26,7 @@ foreach enum : c_enums
endforeach
c_bitfields = [
'ClockEvent',
+ 'MemTxResult',
'VMStateFlags',
]
foreach enum : c_bitfields
diff --git a/rust/qemu-api/src/memory.rs b/rust/qemu-api/src/memory.rs
index b1907aa01300a3fac8e1f3b69c5d50da631a556d..98d1e116147aba2c9034a61159492382b1ee0e5e 100644
--- a/rust/qemu-api/src/memory.rs
+++ b/rust/qemu-api/src/memory.rs
@@ -9,7 +9,7 @@
marker::PhantomData,
};
-pub use bindings::{hwaddr, MemTxAttrs};
+pub use bindings::{hwaddr, MemTxAttrs, MemTxResult};
use crate::{
bindings::{self, device_endian, memory_region_init_io},
@@ -59,6 +59,20 @@ unsafe impl<T: Sync> Sync for MemoryRegionOps<T> {}
F::call((unsafe { &*(opaque.cast::<T>()) }, addr, size))
}
+unsafe extern "C" fn memory_region_ops_read_with_attrs_cb<
+ T,
+ F: for<'a> FnCall<(&'a T, hwaddr, *mut u64, Bits, MemTxAttrs), MemTxResult>,
+>(
+ opaque: *mut c_void,
+ addr: hwaddr,
+ data: *mut u64,
+ size: c_uint,
+ attrs: MemTxAttrs,
+) -> MemTxResult {
+ let size = Bits::try_from(size).expect("invalid size argument");
+ F::call((unsafe { &*(opaque.cast::<T>()) }, addr, data, size, attrs))
+}
+
unsafe extern "C" fn memory_region_ops_write_cb<
T,
F: for<'a> FnCall<(&'a T, hwaddr, u64, Bits)>,
@@ -72,6 +86,20 @@ unsafe impl<T: Sync> Sync for MemoryRegionOps<T> {}
F::call((unsafe { &*(opaque.cast::<T>()) }, addr, data, size))
}
+unsafe extern "C" fn memory_region_ops_write_with_attrs_cb<
+ T,
+ F: for<'a> FnCall<(&'a T, hwaddr, u64, Bits, MemTxAttrs), MemTxResult>,
+>(
+ opaque: *mut c_void,
+ addr: hwaddr,
+ data: u64,
+ size: c_uint,
+ attrs: MemTxAttrs,
+) -> MemTxResult {
+ let size = Bits::try_from(size).expect("invalid size argument");
+ F::call((unsafe { &*(opaque.cast::<T>()) }, addr, data, size, attrs))
+}
+
impl<T> MemoryRegionOpsBuilder<T> {
#[must_use]
pub const fn read<F: for<'a> FnCall<(&'a T, hwaddr, Bits), u64>>(mut self, _f: &F) -> Self {
@@ -86,6 +114,28 @@ pub const fn write<F: for<'a> FnCall<(&'a T, hwaddr, u64, Bits)>>(mut self, _f:
}
#[must_use]
+ pub const fn read_with_attrs<
+ F: for<'a> FnCall<(&'a T, hwaddr, *mut u64, Bits, MemTxAttrs), MemTxResult>,
+ >(
+ mut self,
+ _f: &F,
+ ) -> Self {
+ self.0.read_with_attrs = Some(memory_region_ops_read_with_attrs_cb::<T, F>);
+ self
+ }
+
+ #[must_use]
+ pub const fn write_with_attrs<
+ F: for<'a> FnCall<(&'a T, hwaddr, u64, Bits, MemTxAttrs), MemTxResult>,
+ >(
+ mut self,
+ _f: &F,
+ ) -> Self {
+ self.0.write_with_attrs = Some(memory_region_ops_write_with_attrs_cb::<T, F>);
+ self
+ }
+
+ #[must_use]
pub const fn big_endian(mut self) -> Self {
self.0.endianness = device_endian::DEVICE_BIG_ENDIAN;
self
--
2.47.2
On Thu, Jul 03, 2025 at 04:58:13PM +0300, Manos Pitsidianakis wrote:
> Date: Thu, 03 Jul 2025 16:58:13 +0300
> From: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
> Subject: [PATCH 3/3] rust: add *_with_attrs methods to MemoryRegionOps
> X-Mailer: b4 0.14.2
>
> MemoryRegionOps (and its builder type) only support read/write
> callbacks.
>
> Add the ability to define {read,write}_with_attrs callbacks for devices
> that need them.
>
> Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
> ---
> rust/qemu-api/meson.build | 1 +
> rust/qemu-api/src/memory.rs | 52 ++++++++++++++++++++++++++++++++++++++++++++-
> 2 files changed, 52 insertions(+), 1 deletion(-)
Fine for me,
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
© 2016 - 2025 Red Hat, Inc.