Skip to main content

PagedBuffer

Struct PagedBuffer 

Source
pub struct PagedBuffer { /* private fields */ }
Expand description

A paged DMA buffer consisting of one or more pinned pages that are contiguous in virtual memory (Mapping), but may be discontiguous in physical memory.

Implementations§

Source§

impl PagedBuffer

Source

pub fn new(bti: &Bti, size: usize) -> Result<Self, Status>

Creates a new paged DMA buffer of size bytes (rounded up to the system page size) mapped in the root VMAR with CPU caching enabled.

Source

pub fn new_with_vmar( bti: &Bti, vmar: &Vmar, size: usize, ) -> Result<Self, Status>

Creates a new paged DMA buffer of size bytes (rounded up to the system page size) mapped in vmar with CPU caching enabled.

Source

pub fn new_with_options( bti: &Bti, vmar: &Vmar, size: usize, cache_options: CacheOptions, ) -> Result<Self, Status>

Creates a new paged DMA buffer of size bytes (rounded up to the system page size) mapped in vmar with the specified cache_options.

Source

pub fn buffer(&self) -> &Buffer

Returns a reference to the underlying Buffer.

Source

pub fn phys(&self) -> &[zx_paddr_t] ⓘ

Returns the slice of pinned page physical addresses backing the buffer.

Source

pub unsafe fn unpin(self) -> Result<(), Status>

Unpins the DMA buffer’s physical memory token, consuming the buffer so its physical addresses and mapping cannot be accessed after unpinning.

§Safety

The caller must ensure that hardware is no longer accessing the pinned memory (e.g. after resetting or quiescing the device).

Methods from Deref<Target = Buffer>§

Source

pub fn size(&self) -> usize

Returns the size of the mapped DMA buffer in bytes.

Source

pub fn vmo(&self) -> &Vmo

Returns a reference to the underlying VMO.

Source

pub fn mapping(&self) -> &Mapping

Returns a reference to the underlying Mapping.

Source

pub fn mapping_mut(&mut self) -> &mut Mapping

Returns a mutable reference to the underlying Mapping.

Source

pub fn is_cache_enabled(&self) -> bool

Returns whether CPU caching is enabled for this DMA buffer.

Source

pub fn cache_options(&self) -> CacheOptions

Returns the CacheOptions configured for this DMA buffer.

Source

pub fn cache_flush(&self, offset: usize, length: usize) -> Result<(), Status>

Flushes CPU data cache lines (clean to memory) for the given byte range.

Use after CPU writes to the buffer so that DMA hardware can read from physical RAM (DMA_TO_DEVICE).

Source

pub fn cache_flush_invalidate( &self, offset: usize, length: usize, ) -> Result<(), Status>

Flushes and invalidates CPU data cache lines for the given byte range.

Use before CPU reads from the buffer after DMA hardware writes to physical RAM (DMA_FROM_DEVICE).

Source

pub fn write(&self, offset: usize, src: &[u8]) -> Result<(), Status>

Writes src into the DMA buffer at offset and flushes the CPU cache if caching is enabled.

Source

pub fn read(&self, offset: usize, dst: &mut [u8]) -> Result<(), Status>

Invalidates the CPU cache if caching is enabled and reads from the DMA buffer at offset into dst.

Source

pub fn write_struct<T: IntoBytes + Immutable>( &self, offset: usize, val: &T, ) -> Result<(), Status>

Writes a value of type T at byte offset with automatic cache flush.

Source

pub fn read_struct<T: FromBytes + IntoBytes + KnownLayout + Immutable>( &self, offset: usize, ) -> Result<T, Status>

Reads a value of type T from byte offset with automatic cache invalidation.

Source

pub fn read_element<T: FromBytes + IntoBytes + KnownLayout + Immutable>( &self, index: usize, ) -> T

Reads the index-th element of type T (at byte offset index * size_of::<T>()) from the mapped buffer.

§Panics

Panics if index * size_of::<T>() + size_of::<T>() overflows or exceeds self.size().

Source

pub fn write_element<T: IntoBytes + Immutable>(&self, index: usize, value: &T)

Writes value as the index-th element of type T (at byte offset index * size_of::<T>()) in the mapped buffer.

§Panics

Panics if index * size_of::<T>() + size_of::<T>() overflows or exceeds self.size().

Methods from Deref<Target = Mapping>§

Source

pub fn len(&self) -> usize

Return the size of the mapping.

Methods from Deref<Target = SharedBuffer>§

pub fn read(&self, dst: &mut [u8]) -> usize

Read bytes from the buffer.

Read up to dst.len() bytes from the buffer, returning how many bytes were read. The only thing that can cause fewer bytes to be read than requested is if dst is larger than the buffer itself.

A call to read is only guaranteed to happen after an operation in another thread or process if the mechanism used to signal the other process has well-defined memory ordering semantics. Otherwise, the acquire_writes method must be called before read and after receiving a signal from the other process in order to provide such ordering guarantees. In practice, this means that acquire_writes should be the first read operation that happens after receiving a signal from another process that the memory may be read. See the acquire_writes documentation for more details.

pub fn read_at(&self, offset: usize, dst: &mut [u8]) -> usize

Read bytes from the buffer at an offset.

Read up to dst.len() bytes starting at offset into the buffer, returning how many bytes were read. The only thing that can cause fewer bytes to be read than requested is if there are fewer than dst.len() bytes available starting at offset within the buffer.

A call to read_at is only guaranteed to happen after an operation in another thread or process if the mechanism used to signal the other process has well-defined memory ordering semantics. Otherwise, the acquire_writes method must be called before read_at and after receiving a signal from the other process in order to provide such ordering guarantees. In practice, this means that acquire_writes should be the first read operation that happens after receiving a signal from another process that the memory may be read. See the acquire_writes documentation for more details.

§Panics

read_at panics if offset is greater than the length of the buffer.

pub fn write(&self, src: &[u8]) -> usize

Write bytes to the buffer.

Write up to src.len() bytes into the buffer, returning how many bytes were written. The only thing that can cause fewer bytes to be written than requested is if src is larger than the buffer itself.

A call to write is only guaranteed to happen before an operation in another thread or process if the mechanism used to signal the other process has well-defined memory ordering semantics. Otherwise, the release_writes method must be called after write and before signalling the other process in order to provide such ordering guarantees. In practice, this means that release_writes should be the last write operation that happens before signalling another process that the memory may be read. See the release_writes documentation for more details.

pub fn write_at(&self, offset: usize, src: &[u8]) -> usize

Write bytes to the buffer at an offset.

Write up to src.len() bytes starting at offset into the buffer, returning how many bytes were written. The only thing that can cause fewer bytes to be written than requested is if there are fewer than src.len() bytes available starting at offset within the buffer.

A call to write_at is only guaranteed to happen before an operation in another thread or process if the mechanism used to signal the other process has well-defined memory ordering semantics. Otherwise, the release_writes method must be called after write_at and before signalling the other process in order to provide such ordering guarantees. In practice, this means that release_writes should be the last write operation that happens before signalling another process that the memory may be read. See the release_writes documentation for more details.

§Panics

write_at panics if offset is greater than the length of the buffer.

pub fn copy_from_at<B>( &self, dst_offset: usize, src: &B, src_offset: usize, len: usize, ) -> usize
where B: AsSharedBuffer + ?Sized,

Copy bytes from a SharedBuffer or slice into this buffer at an offset.

Copy up to len bytes starting at src_offset in src into self starting at dst_offset, returning how many bytes were copied. src may refer to the same underlying memory as self (overlapping regions are handled safely). The only thing that can cause fewer bytes to be copied than requested is if there are fewer than len bytes available starting at dst_offset in self or starting at src_offset in src.

Since copy_from_at reads from src and writes to self, a call to copy_from_at is only guaranteed to happen after an operation on src or before an operation on self in another thread or process if the mechanism used to signal the other process has well-defined memory ordering semantics. Otherwise, src.acquire_writes() must be called before copy_from_at (after receiving a signal from the other process that src may be read) and self.release_writes() must be called after copy_from_at (before signalling the other process that self may be read). See the acquire_writes and release_writes documentation for more details.

§Panics

copy_from_at panics if dst_offset is greater than the length of self or src_offset is greater than the length of src.

pub fn acquire_writes(&self)

Acquire all writes performed by the other process.

On some systems (such as Fuchsia, currently), the communication mechanism used for signalling a process that memory is readable does not have well-defined synchronization semantics. On those systems, this method MUST be called after receiving such a signal, or else writes performed before that signal are not guaranteed to be observed by this process.

acquire_writes acquires any writes performed on this buffer or any slice within the buffer.

§Note on Fuchsia

Zircon, the Fuchsia kernel, will likely eventually have well-defined semantics around the synchronization behavior of various syscalls. Once that happens, calling this method in Fuchsia programs may become optional. This work is tracked in https://fxbug.dev/42107145.

pub fn len(&self) -> usize

The number of bytes in this SharedBuffer.

pub fn slice<'a, R>(&'a self, range: R) -> SharedBufferSlice<'a>
where R: RangeBounds<usize>,

Create a slice of the original SharedBuffer.

Just like the slicing operation on array and slice references, slice constructs a SharedBufferSlice which points to the same memory as the original SharedBuffer, but starting and index from (inclusive) and ending at index to (exclusive).

§Panics

slice panics if range is out of bounds of self or if range is nonsensical (its lower bound is larger than its upper bound).

pub fn split_at<'a>( &'a self, idx: usize, ) -> (SharedBufferSlice<'a>, SharedBufferSlice<'a>)

Create two non-overlapping slices of the original SharedBuffer.

Just like the split_at method on array and slice references, split_at constructs one SharedBufferSlice which represents bytes [0, idx), and one which represents bytes [idx, len), where len is the length of the buffer.

§Panics

split_at panics if idx > self.len().

Trait Implementations§

Source§

impl Debug for PagedBuffer

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Deref for PagedBuffer

Source§

type Target = Buffer

The resulting type after dereferencing.
Source§

fn deref(&self) -> &Self::Target

Dereferences the value.
Source§

impl DerefMut for PagedBuffer

Source§

fn deref_mut(&mut self) -> &mut Self::Target

Mutably dereferences the value.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

impl<T> AsSharedBuffer for T
where T: Deref + ?Sized, <T as Deref>::Target: AsSharedBuffer,

Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<P, T> Receiver for P
where P: Deref<Target = T> + ?Sized, T: ?Sized,

Source§

type Target = T

🔬This is a nightly-only experimental API. (arbitrary_self_types)
The target type on which the method may be called.
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.