Add README and doc comments
Signed-off-by: Balint Dobszay <balint.dobszay@arm.com>
Change-Id: Ie4cf762558b181139e1456887a0e4687b0243564
diff --git a/src/memory_management.rs b/src/memory_management.rs
index 777a399..e81a5ca 100644
--- a/src/memory_management.rs
+++ b/src/memory_management.rs
@@ -1,6 +1,17 @@
// SPDX-FileCopyrightText: Copyright 2023 Arm Limited and/or its affiliates <open-source-office@arm.com>
// SPDX-License-Identifier: MIT OR Apache-2.0
+//! Implementation of the FF-A Memory Management protocol.
+//!
+//! FF-A describes mechanisms and interfaces that enable FF-A components to manage access and
+//! ownership of memory regions in the physical address space. FF-A components can use a combination
+//! of Framework and Partition messages to manage memory regions in the following ways:
+//! - The Owner of a memory region can transfer its ownership to another FF-A endpoint.
+//! - The Owner of a memory region can transfer its access to one or more FF-A endpoints.
+//! - The Owner of a memory region can share access to it with one or more FF-A endpoints.
+//! - The Owner can reclaim access to a memory region after the FF-A endpoints that were granted
+//! access to that memory region have relinquished their access.
+
use crate::ffa_v1_1::{
composite_memory_region_descriptor, constituent_memory_region_descriptor,
endpoint_memory_access_descriptor, memory_access_permission_descriptor,
@@ -10,6 +21,8 @@
use thiserror::Error;
use zerocopy::{FromBytes, IntoBytes};
+/// Rich error types returned by this module. Should be converted to [`crate::FfaError`] when used
+/// with the `FFA_ERROR` interface.
#[derive(Debug, Error)]
pub enum Error {
#[error("Invalid cacheability attribute {0}")]
@@ -42,6 +55,7 @@
}
}
+/// Memory region handle, used to identify a composite memory region description.
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct Handle(pub u64);
@@ -61,6 +75,7 @@
pub const INVALID: u64 = 0xffff_ffff_ffff_ffff;
}
+/// Cacheability attribute of a memory region. Only valid for normal memory.
#[derive(Debug, Default, Clone, Copy, PartialEq)]
#[repr(u16)]
pub enum Cacheability {
@@ -88,6 +103,7 @@
const WRITE_BACK: u16 = 0b11;
}
+/// Shareability attribute of a memory region. Only valid for normal memory.
#[derive(Debug, Default, Clone, Copy, PartialEq)]
#[repr(u16)]
pub enum Shareability {
@@ -118,6 +134,7 @@
const INNER: u16 = 0b11;
}
+/// Device memory attributes.
#[derive(Debug, Default, Clone, Copy)]
#[repr(u16)]
pub enum DeviceMemAttributes {
@@ -151,6 +168,7 @@
const DEV_GRE: u16 = 0b11;
}
+/// Memory region type.
#[derive(Debug, Default, Clone, Copy)]
pub enum MemType {
#[default]
@@ -199,6 +217,7 @@
const NORMAL: u16 = 0b10;
}
+/// Memory region security attribute.
#[derive(Debug, Default, Clone, Copy, PartialEq)]
#[repr(u16)]
pub enum MemRegionSecurity {
@@ -224,6 +243,7 @@
const NON_SECURE: u16 = 0b1;
}
+/// Memory region attributes descriptor.
#[derive(Debug, Default, Clone, Copy)]
pub struct MemRegionAttributes {
pub security: MemRegionSecurity,
@@ -252,6 +272,7 @@
}
}
+/// Instruction access permissions of a memory region.
#[derive(Debug, Default, Clone, Copy)]
#[repr(u8)]
pub enum InstuctionAccessPerm {
@@ -282,6 +303,7 @@
const EXECUTABLE: u8 = 0b10;
}
+/// Data access permissions of a memory region.
#[derive(Debug, Default, Clone, Copy)]
#[repr(u8)]
pub enum DataAccessPerm {
@@ -312,6 +334,7 @@
const READ_WRITE: u8 = 0b10;
}
+/// Endpoint memory access permissions descriptor.
#[derive(Debug, Default, Clone, Copy)]
pub struct MemAccessPerm {
pub endpoint_id: u16,
@@ -320,6 +343,7 @@
pub flags: u8, // TODO
}
+/// Iterator of endpoint memory access permission descriptors.
pub struct MemAccessPermIterator<'a> {
buf: &'a [u8],
offset: usize,
@@ -327,6 +351,7 @@
}
impl<'a> MemAccessPermIterator<'a> {
+ /// Create an iterator of endpoint memory access permission descriptors from a buffer.
fn new(buf: &'a [u8], count: usize, offset: usize) -> Result<Self, Error> {
let Some(total_size) = count
.checked_mul(size_of::<endpoint_memory_access_descriptor>())
@@ -390,12 +415,14 @@
}
}
+/// Constituent memory region descriptor.
#[derive(Debug, Default, Clone, Copy)]
pub struct ConstituentMemRegion {
pub address: u64,
pub page_cnt: u32,
}
+/// Iterator of constituent memory region descriptors.
pub struct ConstituentMemRegionIterator<'a> {
buf: &'a [u8],
offset: usize,
@@ -403,6 +430,7 @@
}
impl<'a> ConstituentMemRegionIterator<'a> {
+ /// Create an iterator of constituent memory region descriptors from a buffer.
fn new(buf: &'a [u8], count: usize, offset: usize) -> Result<Self, Error> {
let Some(total_size) = count
.checked_mul(size_of::<constituent_memory_region_descriptor>())
@@ -446,6 +474,7 @@
}
}
+/// Flags of a memory management transaction.
#[derive(Debug, Default, Clone, Copy)]
pub struct MemTransactionFlags(pub u32);
@@ -463,6 +492,8 @@
pub const HINT_VALID: u32 = 0b1 << 9;
}
+/// Memory transaction decriptor. Used by an Owner/Lender and a Borrower/Receiver in a transaction
+/// to donate, lend or share a memory region.
#[derive(Debug, Default)]
pub struct MemTransactionDesc {
pub sender_id: u16,
@@ -483,6 +514,8 @@
// region descriptor
const CONSTITUENT_ARRAY_OFFSET: usize = size_of::<composite_memory_region_descriptor>();
+ /// Serialize a memory transaction descriptor and the related constituent memory region
+ /// descriptors and endpoint memory access permission descriptors into a buffer.
pub fn pack(
&self,
constituents: &[ConstituentMemRegion],
@@ -562,6 +595,9 @@
offset
}
+ /// Deserialize a memory transaction descriptor from a buffer and return an interator of the
+ /// related endpoint memory access permission descriptors and constituent memory region
+ /// descriptors, if any.
pub fn unpack(
buf: &[u8],
) -> Result<
@@ -663,6 +699,7 @@
}
}
+/// Descriptor to relinquish a memory region. Currently only supports specifying a single endpoint.
#[derive(Debug, Default)]
pub struct MemRelinquishDesc {
pub handle: Handle,