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
>

Reply via email to