From: Abdellatif El Khlifi <abdellatif.elkhl...@arm.com>

Add to the FF-A bus FFA_MEM_RECLAIM ABI

The FFA_MEM_RECLAIM is a memory management ABI described in the FF-A
v1.0 specification [1].

This ABI restores exclusive access to a memory region back to its Owner.

This work is based on the implementation in Linux [2].

[1]: https://developer.arm.com/documentation/den0077/a/?lang=en
[2]: commit cc2195fe536c28e192df5d07e6dd277af36814b4
     File: drivers/firmware/arm_ffa/driver.c

Signed-off-by: Abdellatif El Khlifi <abdellatif.elkhl...@arm.com>
---
 doc/arch/arm64.ffa.rst                    |  2 +
 drivers/firmware/arm-ffa/arm-ffa-uclass.c | 70 +++++++++++++++++++++++
 drivers/firmware/arm-ffa/arm-ffa.c        |  1 +
 include/arm_ffa.h                         | 25 +++++++-
 include/arm_ffa_priv.h                    |  3 +-
 5 files changed, 99 insertions(+), 2 deletions(-)

diff --git a/doc/arch/arm64.ffa.rst b/doc/arch/arm64.ffa.rst
index 3eec735d741..d2c4fb49f79 100644
--- a/doc/arch/arm64.ffa.rst
+++ b/doc/arch/arm64.ffa.rst
@@ -186,6 +186,7 @@ The following features are provided:
     - FFA_MSG_SEND_DIRECT_REQ
     - FFA_MSG_SEND_DIRECT_RESP
     - FFA_MEM_SHARE
+    - FFA_MEM_RECLAIM
 
 - Support for the 64-bit version of the following ABIs:
 
@@ -205,6 +206,7 @@ The following features are provided:
     - ffa_sync_send_receive
     - ffa_rxtx_unmap
     - ffa_memory_share
+    - ffa_memory_reclaim
 
 - FF-A bus discovery makes sure FF-A framework is responsive and compatible
   with the driver
diff --git a/drivers/firmware/arm-ffa/arm-ffa-uclass.c 
b/drivers/firmware/arm-ffa/arm-ffa-uclass.c
index 8ff666c3757..5eae28386ae 100644
--- a/drivers/firmware/arm-ffa/arm-ffa-uclass.c
+++ b/drivers/firmware/arm-ffa/arm-ffa-uclass.c
@@ -109,6 +109,18 @@ static struct ffa_abi_errmap err_msg_map[FFA_ERRMAP_COUNT] 
= {
                        "DENIED: Memory region ownership, permission, access or 
attributes error",
                },
        },
+       [FFA_ID_TO_ERRMAP_ID(FFA_MEM_RECLAIM)] = {
+               {
+                       [ABORTED] =
+                       "ABORTED: ABI invocation failure",
+                       [INVALID_PARAMETERS] =
+                       "INVALID_PARAMETERS: Invalid handle or flags",
+                       [NO_MEMORY] =
+                       "NO_MEMORY: Failure to create the Owner's mapping",
+                       [DENIED] =
+                       "DENIED: Memory region state issue",
+               },
+       },
 };
 
 /**
@@ -1115,6 +1127,41 @@ int ffa_memory_share_hdlr(struct udevice *dev, struct 
ffa_mem_ops_args *args)
        return ffa_memory_ops(dev, FFA_MEM_SHARE, args);
 }
 
+/**
+ * ffa_memory_reclaim_hdlr() - FFA_MEM_RECLAIM handler function
+ * @dev: The FF-A bus device
+ * @g_handle: The memory region globally unique Handle
+ * @flags: Zero memory and time slicing flags
+ *
+ * Implement FFA_MEM_RECLAIM FF-A function
+ * to restore exclusive access to a memory region back to its Owner.
+ *
+ * Return:
+ *
+ * 0 on success. Otherwise, failure
+ */
+int ffa_memory_reclaim_hdlr(struct udevice *dev, u64 g_handle, u32 flags)
+{
+       ffa_value_t res;
+       int ffa_errno;
+
+       invoke_ffa_fn((ffa_value_t){
+                       .a0 = FFA_SMC_32(FFA_MEM_RECLAIM),
+                       .a1 = HANDLE_LOW(g_handle), .a2 = HANDLE_HIGH(g_handle),
+                       .a3 = flags,
+                       },
+                       &res
+       );
+
+       if (res.a0 != FFA_SMC_32(FFA_SUCCESS)) {
+               ffa_errno = res.a2;
+               ffa_print_error_log(FFA_MEM_RECLAIM, ffa_errno);
+               return ffa_to_std_errno(ffa_errno);
+       }
+
+       return 0;
+}
+
 /* FF-A driver operations (used by clients for communicating with FF-A)*/
 
 /**
@@ -1214,6 +1261,29 @@ int ffa_memory_share(struct udevice *dev, struct 
ffa_mem_ops_args *args)
        return ops->memory_share(dev, args);
 }
 
+/**
+ * ffa_memory_reclaim() - FFA_MEM_RECLAIM driver operation
+ * @dev: The FF-A bus device
+ * @g_handle: The memory region globally unique Handle
+ * @flags: Zero memory and time slicing flags
+ *
+ * Driver operation for FFA_MEM_RECLAIM.
+ * Please see ffa_memory_reclaim_hdlr() description for more details.
+ *
+ * Return:
+ *
+ * 0 on success. Otherwise, failure
+ */
+int ffa_memory_reclaim(struct udevice *dev, u64 g_handle, u32 flags)
+{
+       struct ffa_bus_ops *ops = ffa_get_ops(dev);
+
+       if (!ops || !ops->memory_reclaim)
+               return -ENOSYS;
+
+       return ops->memory_reclaim(dev, g_handle, flags);
+}
+
 /**
  * ffa_do_probe() - probing FF-A framework
  * @dev:       the FF-A bus device (arm_ffa)
diff --git a/drivers/firmware/arm-ffa/arm-ffa.c 
b/drivers/firmware/arm-ffa/arm-ffa.c
index c4211c953ef..b7e751e3821 100644
--- a/drivers/firmware/arm-ffa/arm-ffa.c
+++ b/drivers/firmware/arm-ffa/arm-ffa.c
@@ -85,6 +85,7 @@ static const struct ffa_bus_ops ffa_ops = {
        .sync_send_receive = ffa_msg_send_direct_req_hdlr,
        .rxtx_unmap = ffa_unmap_rxtx_buffers_hdlr,
        .memory_share = ffa_memory_share_hdlr,
+       .memory_reclaim = ffa_memory_reclaim_hdlr,
 };
 
 /* Registering the FF-A driver as an SMCCC feature driver */
diff --git a/include/arm_ffa.h b/include/arm_ffa.h
index ce4a3d7f440..965139b166a 100644
--- a/include/arm_ffa.h
+++ b/include/arm_ffa.h
@@ -147,8 +147,9 @@ struct ffa_mem_ops_args {
  * struct ffa_bus_ops - Operations for FF-A
  * @partition_info_get:        callback for the FFA_PARTITION_INFO_GET
  * @sync_send_receive: callback for the FFA_MSG_SEND_DIRECT_REQ
- * @rxtx_unmap:        callback for the FFA_RXTX_UNMAP
+ * @rxtx_unmap:                callback for the FFA_RXTX_UNMAP
  * @memory_share:      callback for the FFA_MEM_SHARE
+ * @memory_reclaim:    callback for the FFA_MEM_RECLAIM
  *
  * The data structure providing all the operations supported by the driver.
  * This structure is EFI runtime resident.
@@ -161,6 +162,7 @@ struct ffa_bus_ops {
                                 bool is_smc64);
        int (*rxtx_unmap)(struct udevice *dev);
        int (*memory_share)(struct udevice *dev, struct ffa_mem_ops_args *args);
+       int (*memory_reclaim)(struct udevice *dev, u64 g_handle, u32 flags);
 };
 
 #define ffa_get_ops(dev)        ((struct ffa_bus_ops *)(dev)->driver->ops)
@@ -280,6 +282,27 @@ int ffa_memory_share(struct udevice *dev, struct 
ffa_mem_ops_args *args);
  */
 int ffa_memory_share_hdlr(struct udevice *dev, struct ffa_mem_ops_args *args);
 
+/**
+ * ffa_memory_reclaim() - FFA_MEM_RECLAIM driver operation
+ * Please see ffa_memory_reclaim_hdlr() description for more details.
+ */
+int ffa_memory_reclaim(struct udevice *dev, u64 g_handle, u32 flags);
+
+/**
+ * ffa_memory_reclaim_hdlr() - FFA_MEM_RECLAIM handler function
+ * @dev: The FF-A bus device
+ * @g_handle: The memory region globally unique Handle
+ * @flags: Zero memory and time slicing flags
+ *
+ * Implement FFA_MEM_RECLAIM FF-A function
+ * to restore exclusive access to a memory region back to its Owner.
+ *
+ * Return:
+ *
+ * 0 on success. Otherwise, failure
+ */
+int ffa_memory_reclaim_hdlr(struct udevice *dev, u64 g_handle, u32 flags);
+
 struct ffa_priv;
 
 /**
diff --git a/include/arm_ffa_priv.h b/include/arm_ffa_priv.h
index 02e2cd89937..09205f40907 100644
--- a/include/arm_ffa_priv.h
+++ b/include/arm_ffa_priv.h
@@ -133,10 +133,11 @@ enum ffa_abis {
        FFA_MSG_SEND_DIRECT_REQ   = 0x6f,
        FFA_MSG_SEND_DIRECT_RESP  = 0x70,
        FFA_MEM_SHARE             = 0x73,
+       FFA_MEM_RECLAIM           = 0x77,
 
        /* To be updated when adding new FFA IDs */
        FFA_FIRST_ID              = FFA_ERROR, /* Lowest number ID */
-       FFA_LAST_ID               = FFA_MEM_SHARE, /* Highest number ID */
+       FFA_LAST_ID               = FFA_MEM_RECLAIM, /* Highest number ID */
 };
 
 enum ffa_abi_errcode {
-- 
2.25.1

Reply via email to