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