On Thu, Aug 7, 2025 at 3:10 PM Zhao Liu <zhao1....@intel.com> wrote: > > Add a binding (target_is_big_endian()) to check whether target is big > endian or not. This could help user to adjust endian before calling
s/adjust endian/adjust endianness/ > AddresssSpace::store() or after calling AddressSpace::load(). No strong preference, but maybe we can keep the same name as C, target_big_endian()? Just for consistency. Either way: Reviewed-by: Manos Pitsidianakis <manos.pitsidiana...@linaro.org> > > Add the example in the documentation of AddresssSpace::store() to help > explain how to use it. > > Signed-off-by: Zhao Liu <zhao1....@intel.com> > --- > rust/qemu-api/src/memory.rs | 28 +++++++++++++++++++++++++--- > rust/qemu-api/wrapper.h | 1 + > 2 files changed, 26 insertions(+), 3 deletions(-) > > diff --git a/rust/qemu-api/src/memory.rs b/rust/qemu-api/src/memory.rs > index 42bba23cf3f8..a8eb83c95ead 100644 > --- a/rust/qemu-api/src/memory.rs > +++ b/rust/qemu-api/src/memory.rs > @@ -31,7 +31,7 @@ > memory_region_init_io, section_access_allowed, > section_covers_region_addr, > section_fuzz_dma_read, section_get_host_addr, section_rust_load, > section_rust_read_continue_step, section_rust_store, > section_rust_write_continue_step, > - MEMTX_OK, > + target_big_endian, MEMTX_OK, > }, > callbacks::FnCall, > cell::Opaque, > @@ -1107,9 +1107,25 @@ pub fn read(&self, buf: &mut [u8], addr: GuestAddress) > -> Result<usize> { > /// This function is similar to `address_space_st{size}` in C side. > /// > /// But it only assumes @val follows target-endian by default. So ensure > - /// the endian of `val` aligned with target, before using this method. > + /// the endian of `val` aligned with target, before using this method. > The > + /// taget-endian can be checked with [`target_is_big_endian`]. > /// > /// And it assumes the memory attributes is MEMTXATTRS_UNSPECIFIED. > + /// > + /// # Examples > + /// > + /// ``` > + /// use qemu_api::memory::{ADDRESS_SPACE_MEMORY, target_is_big_endian}; > + /// > + /// let addr = GuestAddress(0x123438000); > + /// let val: u32 = 5; > + /// let val_end = if target_is_big_endian() { > + /// val.to_be() > + /// } else { > + /// val.to_le() > + /// } > + /// > + /// assert!(ADDRESS_SPACE_MEMORY.store(addr, val_end).is_ok()); > pub fn store<T: AtomicAccess>(&self, addr: GuestAddress, val: T) -> > Result<()> { > rcu_read_lock(); > let r = self.memory().deref().store(val, addr, Ordering::Relaxed); > @@ -1122,7 +1138,8 @@ pub fn store<T: AtomicAccess>(&self, addr: > GuestAddress, val: T) -> Result<()> { > /// This function is similar to `address_space_ld{size}` in C side. > /// > /// But it only support target-endian by default. The returned value is > - /// with target-endian. > + /// with target-endian. The taget-endian can be checked with > + /// [`target_is_big_endian`]. > /// > /// And it assumes the memory attributes is MEMTXATTRS_UNSPECIFIED. > pub fn load<T: AtomicAccess>(&self, addr: GuestAddress) -> Result<T> { > @@ -1147,3 +1164,8 @@ pub fn load<T: AtomicAccess>(&self, addr: GuestAddress) > -> Result<T> { > // the whole QEMU life. > &*wrapper_ptr > }; > + > +pub fn target_is_big_endian() -> bool { > + // SAFETY: the return value is boolean, so it is always valid. > + unsafe { target_big_endian() } > +} > diff --git a/rust/qemu-api/wrapper.h b/rust/qemu-api/wrapper.h > index ce0ac8d3f550..c466b93054aa 100644 > --- a/rust/qemu-api/wrapper.h > +++ b/rust/qemu-api/wrapper.h > @@ -70,3 +70,4 @@ typedef enum memory_order { > #include "system/address-spaces.h" > #include "hw/char/pl011.h" > #include "qemu/rcu.h" > +#include "qemu/target-info.h" > -- > 2.34.1 >