diff options
author | Tom Rini | 2023-07-24 19:51:05 -0400 |
---|---|---|
committer | Tom Rini | 2023-07-24 19:51:05 -0400 |
commit | 94e7cb181ad6bd25d36a11c58e0df64e9f815888 (patch) | |
tree | ecd308f65b3b7e5f709cb09c9766f1fc8edb7783 /drivers/firmware | |
parent | d927d1a80843e1c3e2a3f0b8f6150790bef83da1 (diff) |
Revert "Merge branch '2023-07-24-introduce-FF-A-suppport'"
This reverts commit d927d1a80843e1c3e2a3f0b8f6150790bef83da1, reversing
changes made to c07ad9520c6190070513016fdb495d4703a4a853.
These changes do not pass CI currently.
Signed-off-by: Tom Rini <trini@konsulko.com>
Diffstat (limited to 'drivers/firmware')
-rw-r--r-- | drivers/firmware/Kconfig | 1 | ||||
-rw-r--r-- | drivers/firmware/arm-ffa/Kconfig | 42 | ||||
-rw-r--r-- | drivers/firmware/arm-ffa/Makefile | 16 | ||||
-rw-r--r-- | drivers/firmware/arm-ffa/arm-ffa-uclass.c | 1065 | ||||
-rw-r--r-- | drivers/firmware/arm-ffa/arm-ffa.c | 104 | ||||
-rw-r--r-- | drivers/firmware/arm-ffa/ffa-emul-uclass.c | 720 | ||||
-rw-r--r-- | drivers/firmware/arm-ffa/sandbox_ffa.c | 110 |
7 files changed, 0 insertions, 2058 deletions
diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig index 8789b1ea141..eae1c8ddc9f 100644 --- a/drivers/firmware/Kconfig +++ b/drivers/firmware/Kconfig @@ -45,5 +45,4 @@ config ARM_SMCCC_FEATURES the PSCI driver is always probed and binds dirvers registered to the Arm SMCCC services if any and reported as supported by the SMCCC firmware. -source "drivers/firmware/arm-ffa/Kconfig" source "drivers/firmware/scmi/Kconfig" diff --git a/drivers/firmware/arm-ffa/Kconfig b/drivers/firmware/arm-ffa/Kconfig deleted file mode 100644 index d75f8b53fd8..00000000000 --- a/drivers/firmware/arm-ffa/Kconfig +++ /dev/null @@ -1,42 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 - -config ARM_FFA_TRANSPORT - bool "Enable Arm Firmware Framework for Armv8-A driver" - depends on DM && (ARM64 || SANDBOX) - select ARM_SMCCC if !SANDBOX - select ARM_SMCCC_FEATURES if !SANDBOX - imply CMD_ARMFFA - select LIB_UUID - select DEVRES - help - The Firmware Framework for Arm A-profile processors (FF-A) - describes interfaces (ABIs) that standardize communication - between the Secure World and Normal World leveraging TrustZone - technology. - - The FF-A support in U-Boot is based on FF-A specification v1.0 and uses SMC32 - calling convention. - - FF-A specification: - - https://developer.arm.com/documentation/den0077/a/?lang=en - - In U-Boot FF-A design, FF-A is considered as a discoverable bus. - FF-A bus is discovered using ARM_SMCCC_FEATURES mechanism performed - by the PSCI driver. - The Secure World is considered as one entity to communicate with - using the FF-A bus. - FF-A communication is handled by one device and one instance (the bus). - The FF-A support on U-Boot takes care of all the interactions between Normal - world and Secure World. - - Generic FF-A methods are implemented in the Uclass (arm-ffa-uclass.c). - Arm specific methods are implemented in the Arm driver (arm-ffa.c). - - FF-A sandbox is provided to run FF-A under sandbox and allows to test the FF-A Uclass. - Sandbox support includes an emulator for Arm FF-A which emulates the FF-A side of - the Secure World and provides FF-A ABIs inspection methods (ffa-emul-uclass.c). - An FF-A sandbox driver is also provided for FF-A communication with the emulated - Secure World (sandbox_ffa.c). - - For more details about the FF-A support, please refer to doc/arch/arm64.ffa.rst diff --git a/drivers/firmware/arm-ffa/Makefile b/drivers/firmware/arm-ffa/Makefile deleted file mode 100644 index 318123a7f42..00000000000 --- a/drivers/firmware/arm-ffa/Makefile +++ /dev/null @@ -1,16 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0+ -# -# Copyright 2022-2023 Arm Limited and/or its affiliates <open-source-office@arm.com> -# -# Authors: -# Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com> - -# build the generic FF-A methods -obj-y += arm-ffa-uclass.o -ifeq ($(CONFIG_SANDBOX),y) -# build the FF-A sandbox emulator and driver -obj-y += ffa-emul-uclass.o sandbox_ffa.o -else -# build the Arm64 FF-A driver -obj-y += arm-ffa.o -endif diff --git a/drivers/firmware/arm-ffa/arm-ffa-uclass.c b/drivers/firmware/arm-ffa/arm-ffa-uclass.c deleted file mode 100644 index ffa9d81fa74..00000000000 --- a/drivers/firmware/arm-ffa/arm-ffa-uclass.c +++ /dev/null @@ -1,1065 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright 2022-2023 Arm Limited and/or its affiliates <open-source-office@arm.com> - * - * Authors: - * Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com> - */ -#include <common.h> -#include <arm_ffa.h> -#include <arm_ffa_priv.h> -#include <dm.h> -#include <log.h> -#include <malloc.h> -#include <string.h> -#include <uuid.h> -#include <asm/global_data.h> -#include <dm/device-internal.h> -#include <dm/devres.h> -#include <dm/root.h> -#include <linux/errno.h> -#include <linux/sizes.h> - -DECLARE_GLOBAL_DATA_PTR; - -/* Error mapping declarations */ - -int ffa_to_std_errmap[MAX_NUMBER_FFA_ERR] = { - [NOT_SUPPORTED] = -EOPNOTSUPP, - [INVALID_PARAMETERS] = -EINVAL, - [NO_MEMORY] = -ENOMEM, - [BUSY] = -EBUSY, - [INTERRUPTED] = -EINTR, - [DENIED] = -EACCES, - [RETRY] = -EAGAIN, - [ABORTED] = -ECANCELED, -}; - -static struct ffa_abi_errmap err_msg_map[FFA_ERRMAP_COUNT] = { - [FFA_ID_TO_ERRMAP_ID(FFA_VERSION)] = { - { - [NOT_SUPPORTED] = - "NOT_SUPPORTED: A Firmware Framework implementation does not exist", - }, - }, - [FFA_ID_TO_ERRMAP_ID(FFA_ID_GET)] = { - { - [NOT_SUPPORTED] = - "NOT_SUPPORTED: This function is not implemented at this FF-A instance", - }, - }, - [FFA_ID_TO_ERRMAP_ID(FFA_FEATURES)] = { - { - [NOT_SUPPORTED] = - "NOT_SUPPORTED: FFA_RXTX_MAP is not implemented at this FF-A instance", - }, - }, - [FFA_ID_TO_ERRMAP_ID(FFA_PARTITION_INFO_GET)] = { - { - [NOT_SUPPORTED] = - "NOT_SUPPORTED: This function is not implemented at this FF-A instance", - [INVALID_PARAMETERS] = - "INVALID_PARAMETERS: Unrecognized UUID", - [NO_MEMORY] = - "NO_MEMORY: Results cannot fit in RX buffer of the caller", - [BUSY] = - "BUSY: RX buffer of the caller is not free", - [DENIED] = - "DENIED: Callee is not in a state to handle this request", - }, - }, - [FFA_ID_TO_ERRMAP_ID(FFA_RXTX_UNMAP)] = { - { - [NOT_SUPPORTED] = - "NOT_SUPPORTED: FFA_RXTX_UNMAP is not implemented at this FF-A instance", - [INVALID_PARAMETERS] = - "INVALID_PARAMETERS: No buffer pair registered on behalf of the caller", - }, - }, - [FFA_ID_TO_ERRMAP_ID(FFA_RX_RELEASE)] = { - { - [NOT_SUPPORTED] = - "NOT_SUPPORTED: FFA_RX_RELEASE is not implemented at this FF-A instance", - [DENIED] = - "DENIED: Caller did not have ownership of the RX buffer", - }, - }, - [FFA_ID_TO_ERRMAP_ID(FFA_RXTX_MAP)] = { - { - [NOT_SUPPORTED] = - "NOT_SUPPORTED: This function is not implemented at this FF-A instance", - [INVALID_PARAMETERS] = - "INVALID_PARAMETERS: Field(s) in input parameters incorrectly encoded", - [NO_MEMORY] = - "NO_MEMORY: Not enough memory", - [DENIED] = - "DENIED: Buffer pair already registered", - }, - }, -}; - -/** - * ffa_to_std_errno() - convert FF-A error code to standard error code - * @ffa_errno: Error code returned by the FF-A ABI - * - * Map the given FF-A error code as specified - * by the spec to a u-boot standard error code. - * - * Return: - * - * The standard error code on success. . Otherwise, failure - */ -static int ffa_to_std_errno(int ffa_errno) -{ - int err_idx = -ffa_errno; - - /* Map the FF-A error code to the standard u-boot error code */ - if (err_idx > 0 && err_idx < MAX_NUMBER_FFA_ERR) - return ffa_to_std_errmap[err_idx]; - return -EINVAL; -} - -/** - * ffa_print_error_log() - print the error log corresponding to the selected FF-A ABI - * @ffa_id: FF-A ABI ID - * @ffa_errno: Error code returned by the FF-A ABI - * - * Map the FF-A error code to the error log relevant to the - * selected FF-A ABI. Then the error log is printed. - * - * Return: - * - * 0 on success. . Otherwise, failure - */ -static int ffa_print_error_log(u32 ffa_id, int ffa_errno) -{ - int err_idx = -ffa_errno, abi_idx = 0; - - /* Map the FF-A error code to the corresponding error log */ - - if (err_idx <= 0 || err_idx >= MAX_NUMBER_FFA_ERR) - return -EINVAL; - - if (ffa_id < FFA_FIRST_ID || ffa_id > FFA_LAST_ID) - return -EINVAL; - - abi_idx = FFA_ID_TO_ERRMAP_ID(ffa_id); - if (abi_idx < 0 || abi_idx >= FFA_ERRMAP_COUNT) - return -EINVAL; - - if (!err_msg_map[abi_idx].err_str[err_idx]) - return -EINVAL; - - log_err("%s\n", err_msg_map[abi_idx].err_str[err_idx]); - - return 0; -} - -/* FF-A ABIs implementation (U-Boot side) */ - -/** - * invoke_ffa_fn() - SMC wrapper - * @args: FF-A ABI arguments to be copied to Xn registers - * @res: FF-A ABI return data to be copied from Xn registers - * - * Calls low level SMC implementation. - * This function should be implemented by the user driver. - */ -void __weak invoke_ffa_fn(ffa_value_t args, ffa_value_t *res) -{ -} - -/** - * ffa_get_version_hdlr() - FFA_VERSION handler function - * @dev: The FF-A bus device - * - * Implement FFA_VERSION FF-A function - * to get from the secure world the FF-A framework version - * FFA_VERSION is used to discover the FF-A framework. - * - * Return: - * - * 0 on success. Otherwise, failure - */ -int ffa_get_version_hdlr(struct udevice *dev) -{ - u16 major, minor; - ffa_value_t res = {0}; - int ffa_errno; - struct ffa_priv *uc_priv; - - invoke_ffa_fn((ffa_value_t){ - .a0 = FFA_SMC_32(FFA_VERSION), .a1 = FFA_VERSION_1_0, - }, &res); - - ffa_errno = res.a0; - if (ffa_errno < 0) { - ffa_print_error_log(FFA_VERSION, ffa_errno); - return ffa_to_std_errno(ffa_errno); - } - - major = GET_FFA_MAJOR_VERSION(res.a0); - minor = GET_FFA_MINOR_VERSION(res.a0); - - log_info("FF-A driver %d.%d\nFF-A framework %d.%d\n", - FFA_MAJOR_VERSION, FFA_MINOR_VERSION, major, minor); - - if (major == FFA_MAJOR_VERSION && minor >= FFA_MINOR_VERSION) { - log_info("FF-A versions are compatible\n"); - - if (dev) { - uc_priv = dev_get_uclass_priv(dev); - if (uc_priv) - uc_priv->fwk_version = res.a0; - } - - return 0; - } - - log_err("versions are incompatible\nExpected: %d.%d , Found: %d.%d\n", - FFA_MAJOR_VERSION, FFA_MINOR_VERSION, major, minor); - - return -EPROTONOSUPPORT; -} - -/** - * ffa_get_endpoint_id() - FFA_ID_GET handler function - * @dev: The FF-A bus device - * - * Implement FFA_ID_GET FF-A function - * to get from the secure world u-boot endpoint ID - * - * Return: - * - * 0 on success. Otherwise, failure - */ -static int ffa_get_endpoint_id(struct udevice *dev) -{ - ffa_value_t res = {0}; - int ffa_errno; - struct ffa_priv *uc_priv = dev_get_uclass_priv(dev); - - invoke_ffa_fn((ffa_value_t){ - .a0 = FFA_SMC_32(FFA_ID_GET), - }, &res); - - if (res.a0 == FFA_SMC_32(FFA_SUCCESS)) { - uc_priv->id = GET_SELF_ENDPOINT_ID((u32)res.a2); - log_debug("FF-A endpoint ID is %u\n", uc_priv->id); - - return 0; - } - - ffa_errno = res.a2; - - ffa_print_error_log(FFA_ID_GET, ffa_errno); - - return ffa_to_std_errno(ffa_errno); -} - -/** - * ffa_set_rxtx_buffers_pages_cnt() - set the minimum number of pages in each of the RX/TX buffers - * @dev: The FF-A bus device - * @prop_field: properties field obtained from FFA_FEATURES ABI - * - * Set the minimum number of pages in each of the RX/TX buffers in uc_priv - * - * Return: - * - * rxtx_min_pages field contains the returned number of pages - * 0 on success. Otherwise, failure - */ -static int ffa_set_rxtx_buffers_pages_cnt(struct udevice *dev, u32 prop_field) -{ - struct ffa_priv *uc_priv = dev_get_uclass_priv(dev); - - switch (prop_field) { - case RXTX_4K: - uc_priv->pair.rxtx_min_pages = 1; - break; - case RXTX_16K: - uc_priv->pair.rxtx_min_pages = 4; - break; - case RXTX_64K: - uc_priv->pair.rxtx_min_pages = 16; - break; - default: - log_err("RX/TX buffer size not supported\n"); - return -EINVAL; - } - - return 0; -} - -/** - * ffa_get_rxtx_map_features_hdlr() - FFA_FEATURES handler function with FFA_RXTX_MAP argument - * @dev: The FF-A bus device - * - * Implement FFA_FEATURES FF-A function to retrieve the FFA_RXTX_MAP features - * - * Return: - * - * 0 on success. Otherwise, failure - */ -static int ffa_get_rxtx_map_features_hdlr(struct udevice *dev) -{ - ffa_value_t res = {0}; - int ffa_errno; - - invoke_ffa_fn((ffa_value_t){ - .a0 = FFA_SMC_32(FFA_FEATURES), - .a1 = FFA_SMC_64(FFA_RXTX_MAP), - }, &res); - - if (res.a0 == FFA_SMC_32(FFA_SUCCESS)) - return ffa_set_rxtx_buffers_pages_cnt(dev, res.a2); - - ffa_errno = res.a2; - ffa_print_error_log(FFA_FEATURES, ffa_errno); - - return ffa_to_std_errno(ffa_errno); -} - -/** - * ffa_free_rxtx_buffers() - free the RX/TX buffers - * @dev: The FF-A bus device - * - * Free the RX/TX buffers - */ -static void ffa_free_rxtx_buffers(struct udevice *dev) -{ - struct ffa_priv *uc_priv = dev_get_uclass_priv(dev); - - log_debug("Freeing FF-A RX/TX buffers\n"); - - if (uc_priv->pair.rxbuf) { - free(uc_priv->pair.rxbuf); - uc_priv->pair.rxbuf = NULL; - } - - if (uc_priv->pair.txbuf) { - free(uc_priv->pair.txbuf); - uc_priv->pair.txbuf = NULL; - } -} - -/** - * ffa_alloc_rxtx_buffers() - allocate the RX/TX buffers - * @dev: The FF-A bus device - * - * Used by ffa_map_rxtx_buffers to allocate - * the RX/TX buffers before mapping them. The allocated memory is physically - * contiguous since memalign ends up calling malloc which allocates - * contiguous memory in u-boot. - * The size of the memory allocated is the minimum allowed. - * - * Return: - * - * 0 on success. Otherwise, failure - */ -static int ffa_alloc_rxtx_buffers(struct udevice *dev) -{ - u64 bytes; - struct ffa_priv *uc_priv = dev_get_uclass_priv(dev); - - log_debug("Using %lu 4KB page(s) for FF-A RX/TX buffers size\n", - uc_priv->pair.rxtx_min_pages); - - bytes = uc_priv->pair.rxtx_min_pages * SZ_4K; - - /* - * The alignment of the RX and TX buffers must be equal - * to the larger translation granule size - * Assumption: Memory allocated with memalign is always physically contiguous - */ - - uc_priv->pair.rxbuf = memalign(bytes, bytes); - if (!uc_priv->pair.rxbuf) { - log_err("failure to allocate RX buffer\n"); - return -ENOBUFS; - } - - log_debug("FF-A RX buffer at virtual address %p\n", uc_priv->pair.rxbuf); - - uc_priv->pair.txbuf = memalign(bytes, bytes); - if (!uc_priv->pair.txbuf) { - free(uc_priv->pair.rxbuf); - uc_priv->pair.rxbuf = NULL; - log_err("failure to allocate the TX buffer\n"); - return -ENOBUFS; - } - - log_debug("FF-A TX buffer at virtual address %p\n", uc_priv->pair.txbuf); - - /* Make sure the buffers are cleared before use */ - memset(uc_priv->pair.rxbuf, 0, bytes); - memset(uc_priv->pair.txbuf, 0, bytes); - - return 0; -} - -/** - * ffa_map_rxtx_buffers_hdlr() - FFA_RXTX_MAP handler function - * @dev: The FF-A bus device - * - * Implement FFA_RXTX_MAP FF-A function to map the RX/TX buffers - * - * Return: - * - * 0 on success. Otherwise, failure - */ -static int ffa_map_rxtx_buffers_hdlr(struct udevice *dev) -{ - int ret; - ffa_value_t res = {0}; - int ffa_errno; - struct ffa_priv *uc_priv = dev_get_uclass_priv(dev); - - ret = ffa_alloc_rxtx_buffers(dev); - if (ret) - return ret; - - /* - * we need to pass the physical addresses of the RX/TX buffers - * in u-boot physical/virtual mapping is 1:1 - * no need to convert from virtual to physical - */ - - invoke_ffa_fn((ffa_value_t){ - .a0 = FFA_SMC_64(FFA_RXTX_MAP), - .a1 = map_to_sysmem(uc_priv->pair.txbuf), - .a2 = map_to_sysmem(uc_priv->pair.rxbuf), - .a3 = uc_priv->pair.rxtx_min_pages, - }, &res); - - if (res.a0 == FFA_SMC_32(FFA_SUCCESS)) { - log_debug("FF-A RX/TX buffers mapped\n"); - return 0; - } - - ffa_errno = res.a2; - ffa_print_error_log(FFA_RXTX_MAP, ffa_errno); - - ffa_free_rxtx_buffers(dev); - - return ffa_to_std_errno(ffa_errno); -} - -/** - * ffa_unmap_rxtx_buffers_hdlr() - FFA_RXTX_UNMAP handler function - * @dev: The FF-A bus device - * - * Implement FFA_RXTX_UNMAP FF-A function to unmap the RX/TX buffers - * - * Return: - * - * 0 on success. Otherwise, failure - */ -int ffa_unmap_rxtx_buffers_hdlr(struct udevice *dev) -{ - ffa_value_t res = {0}; - int ffa_errno; - struct ffa_priv *uc_priv; - - log_debug("unmapping FF-A RX/TX buffers\n"); - - uc_priv = dev_get_uclass_priv(dev); - - invoke_ffa_fn((ffa_value_t){ - .a0 = FFA_SMC_32(FFA_RXTX_UNMAP), - .a1 = PREP_SELF_ENDPOINT_ID(uc_priv->id), - }, &res); - - if (res.a0 == FFA_SMC_32(FFA_SUCCESS)) { - ffa_free_rxtx_buffers(dev); - return 0; - } - - ffa_errno = res.a2; - ffa_print_error_log(FFA_RXTX_UNMAP, ffa_errno); - - return ffa_to_std_errno(ffa_errno); -} - -/** - * ffa_release_rx_buffer_hdlr() - FFA_RX_RELEASE handler function - * @dev: The FF-A bus device - * - * Invoke FFA_RX_RELEASE FF-A function to release the ownership of the RX buffer - * - * Return: - * - * 0 on success. Otherwise, failure - */ -static int ffa_release_rx_buffer_hdlr(struct udevice *dev) -{ - ffa_value_t res = {0}; - int ffa_errno; - - invoke_ffa_fn((ffa_value_t){ - .a0 = FFA_SMC_32(FFA_RX_RELEASE), - }, &res); - - if (res.a0 == FFA_SMC_32(FFA_SUCCESS)) - return 0; - - ffa_errno = res.a2; - ffa_print_error_log(FFA_RX_RELEASE, ffa_errno); - - return ffa_to_std_errno(ffa_errno); -} - -/** - * ffa_uuid_are_identical() - check whether two given UUIDs are identical - * @uuid1: first UUID - * @uuid2: second UUID - * - * Used by ffa_read_partitions_info to search for a UUID in the partitions descriptors table - * - * Return: - * - * 1 when UUIDs match. Otherwise, 0 - */ -static bool ffa_uuid_are_identical(const struct ffa_partition_uuid *uuid1, - const struct ffa_partition_uuid *uuid2) -{ - if (!uuid1 || !uuid2) - return 0; - - return !memcmp(uuid1, uuid2, sizeof(struct ffa_partition_uuid)); -} - -/** - * ffa_read_partitions_info() - read queried partition data - * @dev: The FF-A bus device - * @count: The number of partitions queried - * @part_uuid: Pointer to the partition(s) UUID - * - * Read the partitions information returned by the FFA_PARTITION_INFO_GET and saves it in uc_priv - * - * Return: - * - * uc_priv is updated with the partition(s) information - * 0 is returned on success. Otherwise, failure - */ -static int ffa_read_partitions_info(struct udevice *dev, u32 count, - struct ffa_partition_uuid *part_uuid) -{ - struct ffa_priv *uc_priv = dev_get_uclass_priv(dev); - - if (!count) { - log_err("no partition detected\n"); - return -ENODATA; - } - - log_debug("Reading FF-A partitions data from the RX buffer\n"); - - if (!part_uuid) { - /* Querying information of all partitions */ - u64 buf_bytes; - u64 data_bytes; - u32 desc_idx; - struct ffa_partition_info *parts_info; - - data_bytes = count * sizeof(struct ffa_partition_desc); - - buf_bytes = uc_priv->pair.rxtx_min_pages * SZ_4K; - - if (data_bytes > buf_bytes) { - log_err("partitions data size exceeds the RX buffer size:\n"); - log_err(" sizes in bytes: data %llu , RX buffer %llu\n", - data_bytes, - buf_bytes); - - return -ENOMEM; - } - - uc_priv->partitions.descs = devm_kmalloc(dev, data_bytes, __GFP_ZERO); - if (!uc_priv->partitions.descs) { - log_err("cannot allocate partitions data buffer\n"); - return -ENOMEM; - } - - parts_info = uc_priv->pair.rxbuf; - - for (desc_idx = 0 ; desc_idx < count ; desc_idx++) { - uc_priv->partitions.descs[desc_idx].info = - parts_info[desc_idx]; - - log_debug("FF-A partition ID %x : info cached\n", - uc_priv->partitions.descs[desc_idx].info.id); - } - - uc_priv->partitions.count = count; - - log_debug("%d FF-A partition(s) found and cached\n", count); - - } else { - u32 rx_desc_idx, cached_desc_idx; - struct ffa_partition_info *parts_info; - u8 desc_found; - - parts_info = uc_priv->pair.rxbuf; - - /* - * Search for the SP IDs read from the RX buffer - * in the already cached SPs. - * Update the UUID when ID found. - */ - for (rx_desc_idx = 0; rx_desc_idx < count ; rx_desc_idx++) { - desc_found = 0; - - /* Search the current ID in the cached partitions */ - for (cached_desc_idx = 0; - cached_desc_idx < uc_priv->partitions.count; - cached_desc_idx++) { - /* Save the UUID */ - if (uc_priv->partitions.descs[cached_desc_idx].info.id == - parts_info[rx_desc_idx].id) { - uc_priv->partitions.descs[cached_desc_idx].sp_uuid = - *part_uuid; - - desc_found = 1; - break; - } - } - - if (!desc_found) - return -ENODATA; - } - } - - return 0; -} - -/** - * ffa_query_partitions_info() - invoke FFA_PARTITION_INFO_GET and save partitions data - * @dev: The FF-A bus device - * @part_uuid: Pointer to the partition(s) UUID - * @pcount: Pointer to the number of partitions variable filled when querying - * - * Execute the FFA_PARTITION_INFO_GET to query the partitions data. - * Then, call ffa_read_partitions_info to save the data in uc_priv. - * - * After reading the data the RX buffer is released using ffa_release_rx_buffer - * - * Return: - * - * When part_uuid is NULL, all partitions data are retrieved from secure world - * When part_uuid is non NULL, data for partitions matching the given UUID are - * retrieved and the number of partitions is returned - * 0 is returned on success. Otherwise, failure - */ -static int ffa_query_partitions_info(struct udevice *dev, struct ffa_partition_uuid *part_uuid, - u32 *pcount) -{ - struct ffa_partition_uuid query_uuid = {0}; - ffa_value_t res = {0}; - int ffa_errno; - - /* - * If a UUID is specified. Information for one or more - * partitions in the system is queried. Otherwise, information - * for all installed partitions is queried - */ - - if (part_uuid) { - if (!pcount) - return -EINVAL; - - query_uuid = *part_uuid; - } else if (pcount) { - return -EINVAL; - } - - invoke_ffa_fn((ffa_value_t){ - .a0 = FFA_SMC_32(FFA_PARTITION_INFO_GET), - .a1 = query_uuid.a1, - .a2 = query_uuid.a2, - .a3 = query_uuid.a3, - .a4 = query_uuid.a4, - }, &res); - - if (res.a0 == FFA_SMC_32(FFA_SUCCESS)) { - int ret; - - /* - * res.a2 contains the count of partition information descriptors - * populated in the RX buffer - */ - if (res.a2) { - ret = ffa_read_partitions_info(dev, (u32)res.a2, part_uuid); - if (ret) { - log_err("failed reading SP(s) data , err (%d)\n", ret); - ffa_release_rx_buffer_hdlr(dev); - return -EINVAL; - } - } - - /* Return the SP count (when querying using a UUID) */ - if (pcount) - *pcount = (u32)res.a2; - - /* - * After calling FFA_PARTITION_INFO_GET the buffer ownership - * is assigned to the consumer (u-boot). So, we need to give - * the ownership back to the SPM or hypervisor - */ - ret = ffa_release_rx_buffer_hdlr(dev); - - return ret; - } - - ffa_errno = res.a2; - ffa_print_error_log(FFA_PARTITION_INFO_GET, ffa_errno); - - return ffa_to_std_errno(ffa_errno); -} - -/** - * ffa_get_partitions_info_hdlr() - FFA_PARTITION_INFO_GET handler function - * @uuid_str: pointer to the UUID string - * @sp_count: address of the variable containing the number of partitions matching the UUID - * The variable is set by the driver - * @sp_descs: address of the descriptors of the partitions matching the UUID - * The address is set by the driver - * - * Return the number of partitions and their descriptors matching the UUID - * - * Query the secure partition data from uc_priv. - * If not found, invoke FFA_PARTITION_INFO_GET FF-A function to query the partition information - * from secure world. - * - * A client of the FF-A driver should know the UUID of the service it wants to - * access. It should use the UUID to request the FF-A driver to provide the - * partition(s) information of the service. The FF-A driver uses - * PARTITION_INFO_GET to obtain this information. This is implemented through - * ffa_get_partitions_info_hdlr() function. - * If the partition(s) matching the UUID found, the partition(s) information and the - * number are returned. - * If no partition matching the UUID is found in the cached area, a new FFA_PARTITION_INFO_GET - * call is issued. - * If not done yet, the UUID is updated in the cached area. - * This assumes that partitions data does not change in the secure world. - * Otherwise u-boot will have an outdated partition data. The benefit of caching - * the information in the FF-A driver is to accommodate discovery after - * ExitBootServices(). - * - * Return: - * - * @sp_count: the number of partitions - * @sp_descs: address of the partitions descriptors - * - * On success 0 is returned. Otherwise, failure - */ -int ffa_get_partitions_info_hdlr(struct udevice *dev, const char *uuid_str, - u32 *sp_count, struct ffa_partition_desc **sp_descs) -{ - u32 i; - struct ffa_partition_uuid part_uuid = {0}; - struct ffa_priv *uc_priv; - struct ffa_partition_desc *rx_descs; - - uc_priv = dev_get_uclass_priv(dev); - - if (!uc_priv->partitions.count || !uc_priv->partitions.descs) { - log_err("no partition installed\n"); - return -EINVAL; - } - - if (!uuid_str) { - log_err("no UUID provided\n"); - return -EINVAL; - } - - if (!sp_count) { - log_err("no count argument provided\n"); - return -EINVAL; - } - - if (!sp_descs) { - log_err("no info argument provided\n"); - return -EINVAL; - } - - if (uuid_str_to_le_bin(uuid_str, (unsigned char *)&part_uuid)) { - log_err("invalid UUID\n"); - return -EINVAL; - } - - log_debug("Searching FF-A partitions using the provided UUID\n"); - - *sp_count = 0; - *sp_descs = uc_priv->pair.rxbuf; - rx_descs = *sp_descs; - - /* Search in the cached partitions */ - for (i = 0; i < uc_priv->partitions.count; i++) - if (ffa_uuid_are_identical(&uc_priv->partitions.descs[i].sp_uuid, - &part_uuid)) { - log_debug("FF-A partition ID %x matches the provided UUID\n", - uc_priv->partitions.descs[i].info.id); - - (*sp_count)++; - *rx_descs++ = uc_priv->partitions.descs[i]; - } - - if (!(*sp_count)) { - int ret; - - log_debug("No FF-A partition found. Querying framework ...\n"); - - ret = ffa_query_partitions_info(dev, &part_uuid, sp_count); - - if (!ret) { - log_debug("Number of FF-A partition(s) matching the UUID: %d\n", *sp_count); - - if (*sp_count) - ret = ffa_get_partitions_info_hdlr(dev, uuid_str, sp_count, - sp_descs); - else - ret = -ENODATA; - } - - return ret; - } - - return 0; -} - -/** - * ffa_cache_partitions_info() - Query and saves all secure partitions data - * @dev: The FF-A bus device - * - * Invoke FFA_PARTITION_INFO_GET FF-A function to query from secure world - * all partitions information. - * - * The FFA_PARTITION_INFO_GET call is issued with nil UUID as an argument. - * All installed partitions information are returned. We cache them in uc_priv - * and we keep the UUID field empty (in FF-A 1.0 UUID is not provided by the partition descriptor) - * - * Called at the device probing level. - * ffa_cache_partitions_info uses ffa_query_partitions_info to get the data - * - * Return: - * - * 0 on success. Otherwise, failure - */ -static int ffa_cache_partitions_info(struct udevice *dev) -{ - return ffa_query_partitions_info(dev, NULL, NULL); -} - -/** - * ffa_msg_send_direct_req_hdlr() - FFA_MSG_SEND_DIRECT_{REQ,RESP} handler function - * @dev: The FF-A bus device - * @dst_part_id: destination partition ID - * @msg: pointer to the message data preallocated by the client (in/out) - * @is_smc64: select 64-bit or 32-bit FF-A ABI - * - * Implement FFA_MSG_SEND_DIRECT_{REQ,RESP} - * FF-A functions. - * - * FFA_MSG_SEND_DIRECT_REQ is used to send the data to the secure partition. - * The response from the secure partition is handled by reading the - * FFA_MSG_SEND_DIRECT_RESP arguments. - * - * The maximum size of the data that can be exchanged is 40 bytes which is - * sizeof(struct ffa_send_direct_data) as defined by the FF-A specification 1.0 - * in the section relevant to FFA_MSG_SEND_DIRECT_{REQ,RESP} - * - * Return: - * - * 0 on success. Otherwise, failure - */ -int ffa_msg_send_direct_req_hdlr(struct udevice *dev, u16 dst_part_id, - struct ffa_send_direct_data *msg, bool is_smc64) -{ - ffa_value_t res = {0}; - int ffa_errno; - u64 req_mode, resp_mode; - struct ffa_priv *uc_priv; - - uc_priv = dev_get_uclass_priv(dev); - - /* No partition installed */ - if (!uc_priv->partitions.count || !uc_priv->partitions.descs) - return -ENODEV; - - if (is_smc64) { - req_mode = FFA_SMC_64(FFA_MSG_SEND_DIRECT_REQ); - resp_mode = FFA_SMC_64(FFA_MSG_SEND_DIRECT_RESP); - } else { - req_mode = FFA_SMC_32(FFA_MSG_SEND_DIRECT_REQ); - resp_mode = FFA_SMC_32(FFA_MSG_SEND_DIRECT_RESP); - } - - invoke_ffa_fn((ffa_value_t){ - .a0 = req_mode, - .a1 = PREP_SELF_ENDPOINT_ID(uc_priv->id) | - PREP_PART_ENDPOINT_ID(dst_part_id), - .a2 = 0, - .a3 = msg->data0, - .a4 = msg->data1, - .a5 = msg->data2, - .a6 = msg->data3, - .a7 = msg->data4, - }, &res); - - while (res.a0 == FFA_SMC_32(FFA_INTERRUPT)) - invoke_ffa_fn((ffa_value_t){ - .a0 = FFA_SMC_32(FFA_RUN), - .a1 = res.a1, - }, &res); - - if (res.a0 == FFA_SMC_32(FFA_SUCCESS)) { - /* Message sent with no response */ - return 0; - } - - if (res.a0 == resp_mode) { - /* Message sent with response extract the return data */ - msg->data0 = res.a3; - msg->data1 = res.a4; - msg->data2 = res.a5; - msg->data3 = res.a6; - msg->data4 = res.a7; - - return 0; - } - - ffa_errno = res.a2; - return ffa_to_std_errno(ffa_errno); -} - -/* FF-A driver operations (used by clients for communicating with FF-A)*/ - -/** - * ffa_partition_info_get() - FFA_PARTITION_INFO_GET driver operation - * @uuid_str: pointer to the UUID string - * @sp_count: address of the variable containing the number of partitions matching the UUID - * The variable is set by the driver - * @sp_descs: address of the descriptors of the partitions matching the UUID - * The address is set by the driver - * - * Driver operation for FFA_PARTITION_INFO_GET. - * Please see ffa_get_partitions_info_hdlr() description for more details. - * - * Return: - * - * @sp_count: the number of partitions - * @sp_descs: address of the partitions descriptors - * - * On success 0 is returned. Otherwise, failure - */ -int ffa_partition_info_get(struct udevice *dev, const char *uuid_str, - u32 *sp_count, struct ffa_partition_desc **sp_descs) -{ - struct ffa_bus_ops *ops = ffa_get_ops(dev); - - if (!ops->partition_info_get) - return -ENOSYS; - - return ops->partition_info_get(dev, uuid_str, sp_count, sp_descs); -} - -/** - * ffa_sync_send_receive() - FFA_MSG_SEND_DIRECT_{REQ,RESP} driver operation - * @dev: The FF-A bus device - * @dst_part_id: destination partition ID - * @msg: pointer to the message data preallocated by the client (in/out) - * @is_smc64: select 64-bit or 32-bit FF-A ABI - * - * Driver operation for FFA_MSG_SEND_DIRECT_{REQ,RESP}. - * Please see ffa_msg_send_direct_req_hdlr() description for more details. - * - * Return: - * - * 0 on success. Otherwise, failure - */ -int ffa_sync_send_receive(struct udevice *dev, u16 dst_part_id, - struct ffa_send_direct_data *msg, bool is_smc64) -{ - struct ffa_bus_ops *ops = ffa_get_ops(dev); - - if (!ops->sync_send_receive) - return -ENOSYS; - - return ops->sync_send_receive(dev, dst_part_id, msg, is_smc64); -} - -/** - * ffa_rxtx_unmap() - FFA_RXTX_UNMAP driver operation - * @dev: The FF-A bus device - * - * Driver operation for FFA_RXTX_UNMAP. - * Please see ffa_unmap_rxtx_buffers_hdlr() description for more details. - * - * Return: - * - * 0 on success. Otherwise, failure - */ -int ffa_rxtx_unmap(struct udevice *dev) -{ - struct ffa_bus_ops *ops = ffa_get_ops(dev); - - if (!ops->rxtx_unmap) - return -ENOSYS; - - return ops->rxtx_unmap(dev); -} - -/** - * ffa_do_probe() - probing FF-A framework - * @dev: the FF-A bus device (arm_ffa) - * - * Probing is triggered on demand by clients searching for the uclass. - * At probe level the following actions are done: - * - saving the FF-A framework version in uc_priv - * - querying from secure world the u-boot endpoint ID - * - querying from secure world the supported features of FFA_RXTX_MAP - * - mapping the RX/TX buffers - * - querying from secure world all the partitions information - * - * All data queried from secure world is saved in uc_priv. - * - * Return: - * - * 0 on success. Otherwise, failure - */ -static int ffa_do_probe(struct udevice *dev) -{ - int ret; - - ret = ffa_get_version_hdlr(dev); - if (ret) - return ret; - - ret = ffa_get_endpoint_id(dev); - if (ret) - return ret; - - ret = ffa_get_rxtx_map_features_hdlr(dev); - if (ret) - return ret; - - ret = ffa_map_rxtx_buffers_hdlr(dev); - if (ret) - return ret; - - ret = ffa_cache_partitions_info(dev); - if (ret) { - ffa_unmap_rxtx_buffers_hdlr(dev); - return ret; - } - - return 0; -} - -UCLASS_DRIVER(ffa) = { - .name = "ffa", - .id = UCLASS_FFA, - .pre_probe = ffa_do_probe, - .pre_remove = ffa_unmap_rxtx_buffers_hdlr, - .per_device_auto = sizeof(struct ffa_priv) -}; diff --git a/drivers/firmware/arm-ffa/arm-ffa.c b/drivers/firmware/arm-ffa/arm-ffa.c deleted file mode 100644 index 68df75bd9e5..00000000000 --- a/drivers/firmware/arm-ffa/arm-ffa.c +++ /dev/null @@ -1,104 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright 2022-2023 Arm Limited and/or its affiliates <open-source-office@arm.com> - * - * Authors: - * Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com> - */ - -#include <common.h> -#include <arm_ffa.h> -#include <arm_ffa_priv.h> -#include <dm.h> -#include <log.h> -#include <asm/global_data.h> -#include <dm/device-internal.h> -#include <linux/errno.h> - -DECLARE_GLOBAL_DATA_PTR; - -/** - * invoke_ffa_fn() - SMC wrapper - * @args: FF-A ABI arguments to be copied to Xn registers - * @res: FF-A ABI return data to be copied from Xn registers - * - * Calls low level SMC assembly function - */ -void invoke_ffa_fn(ffa_value_t args, ffa_value_t *res) -{ - arm_smccc_1_2_smc(&args, res); -} - -/** - * arm_ffa_discover() - perform FF-A discovery - * @dev: The Arm FF-A bus device (arm_ffa) - * Try to discover the FF-A framework. Discovery is performed by - * querying the FF-A framework version from secure world using the FFA_VERSION ABI. - * Return: - * - * true on success. Otherwise, false. - */ -static bool arm_ffa_discover(struct udevice *dev) -{ - int ret; - - log_info("Arm FF-A framework discovery\n"); - - ret = ffa_get_version_hdlr(dev); - if (ret) - return false; - - return true; -} - -/** - * arm_ffa_is_supported() - FF-A bus discovery callback - * @invoke_fn: legacy SMC invoke function (not used) - * - * Perform FF-A discovery by calling arm_ffa_discover(). - * Discovery is performed by querying the FF-A framework version from - * secure world using the FFA_VERSION ABI. - * - * The FF-A driver is registered as an SMCCC feature driver. So, features discovery - * callbacks are called by the PSCI driver (PSCI device is the SMCCC features - * root device). - * - * The FF-A driver supports the SMCCCv1.2 extended input/output registers. - * So, the legacy SMC invocation is not used. - * - * Return: - * - * 0 on success. Otherwise, failure - */ -static bool arm_ffa_is_supported(void (*invoke_fn)(ulong a0, ulong a1, - ulong a2, ulong a3, - ulong a4, ulong a5, - ulong a6, ulong a7, - struct arm_smccc_res *res)) -{ - return arm_ffa_discover(NULL); -} - -/* Arm FF-A driver operations */ - -static const struct ffa_bus_ops ffa_ops = { - .partition_info_get = ffa_get_partitions_info_hdlr, - .sync_send_receive = ffa_msg_send_direct_req_hdlr, - .rxtx_unmap = ffa_unmap_rxtx_buffers_hdlr, -}; - -/* Registering the FF-A driver as an SMCCC feature driver */ - -ARM_SMCCC_FEATURE_DRIVER(arm_ffa) = { - .driver_name = FFA_DRV_NAME, - .is_supported = arm_ffa_is_supported, -}; - -/* Declaring the FF-A driver under UCLASS_FFA */ - -U_BOOT_DRIVER(arm_ffa) = { - .name = FFA_DRV_NAME, - .id = UCLASS_FFA, - .flags = DM_REMOVE_OS_PREPARE, - .ops = &ffa_ops, -}; diff --git a/drivers/firmware/arm-ffa/ffa-emul-uclass.c b/drivers/firmware/arm-ffa/ffa-emul-uclass.c deleted file mode 100644 index 5562bbaac3a..00000000000 --- a/drivers/firmware/arm-ffa/ffa-emul-uclass.c +++ /dev/null @@ -1,720 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright 2022-2023 Arm Limited and/or its affiliates <open-source-office@arm.com> - * - * Authors: - * Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com> - */ -#include <common.h> -#include <dm.h> -#include <mapmem.h> -#include <string.h> -#include <asm/global_data.h> -#include <asm/sandbox_arm_ffa.h> -#include <asm/sandbox_arm_ffa_priv.h> -#include <dm/device-internal.h> -#include <dm/lists.h> -#include <dm/root.h> -#include <linux/errno.h> -#include <linux/sizes.h> - -DECLARE_GLOBAL_DATA_PTR; - -/* The partitions (SPs) table */ -static struct ffa_partition_desc sandbox_partitions[SANDBOX_PARTITIONS_CNT] = { - { - .info = { .id = SANDBOX_SP1_ID, .exec_ctxt = 0x5687, .properties = 0x89325621 }, - .sp_uuid = { - .a1 = SANDBOX_SERVICE1_UUID_A1, - .a2 = SANDBOX_SERVICE1_UUID_A2, - .a3 = SANDBOX_SERVICE1_UUID_A3, - .a4 = SANDBOX_SERVICE1_UUID_A4, - } - }, - { - .info = { .id = SANDBOX_SP3_ID, .exec_ctxt = 0x7687, .properties = 0x23325621 }, - .sp_uuid = { - .a1 = SANDBOX_SERVICE2_UUID_A1, - .a2 = SANDBOX_SERVICE2_UUID_A2, - .a3 = SANDBOX_SERVICE2_UUID_A3, - .a4 = SANDBOX_SERVICE2_UUID_A4, - } - }, - { - .info = { .id = SANDBOX_SP2_ID, .exec_ctxt = 0x9587, .properties = 0x45325621 }, - .sp_uuid = { - .a1 = SANDBOX_SERVICE1_UUID_A1, - .a2 = SANDBOX_SERVICE1_UUID_A2, - .a3 = SANDBOX_SERVICE1_UUID_A3, - .a4 = SANDBOX_SERVICE1_UUID_A4, - } - }, - { - .info = { .id = SANDBOX_SP4_ID, .exec_ctxt = 0x1487, .properties = 0x70325621 }, - .sp_uuid = { - .a1 = SANDBOX_SERVICE2_UUID_A1, - .a2 = SANDBOX_SERVICE2_UUID_A2, - .a3 = SANDBOX_SERVICE2_UUID_A3, - .a4 = SANDBOX_SERVICE2_UUID_A4, - } - } - -}; - -/* The emulator functions */ - -/** - * sandbox_ffa_version() - Emulated FFA_VERSION handler function - * @emul: The sandbox FF-A emulator device - * @pargs: The SMC call input arguments a0-a7 - * @res: The SMC return data - * - * Emulate FFA_VERSION FF-A function. - * - * Return: - * - * 0 on success. Otherwise, failure - */ - -static int sandbox_ffa_version(struct udevice *emul, ffa_value_t *pargs, ffa_value_t *res) -{ - struct sandbox_ffa_emul *priv = dev_get_priv(emul); - - priv->fwk_version = FFA_VERSION_1_0; - res->a0 = priv->fwk_version; - - /* x1-x7 MBZ */ - memset(FFA_X1X7_MBZ_REG_START, 0, FFA_X1X7_MBZ_CNT * sizeof(ulong)); - - return 0; -} - -/** - * sandbox_ffa_id_get() - Emulated FFA_ID_GET handler function - * @emul: The sandbox FF-A emulator device - * @pargs: The SMC call input arguments a0-a7 - * @res: The SMC return data - * - * Emulate FFA_ID_GET FF-A function. - * - * Return: - * - * 0 on success. Otherwise, failure - */ -static int sandbox_ffa_id_get(struct udevice *emul, ffa_value_t *pargs, ffa_value_t *res) -{ - struct sandbox_ffa_emul *priv = dev_get_priv(emul); - - res->a0 = FFA_SMC_32(FFA_SUCCESS); - res->a1 = 0; - - priv->id = NS_PHYS_ENDPOINT_ID; - res->a2 = priv->id; - - /* x3-x7 MBZ */ - memset(FFA_X3_MBZ_REG_START, 0, FFA_X3X7_MBZ_CNT * sizeof(ulong)); - - return 0; -} - -/** - * sandbox_ffa_features() - Emulated FFA_FEATURES handler function - * @pargs: The SMC call input arguments a0-a7 - * @res: The SMC return data - * - * Emulate FFA_FEATURES FF-A function. - * - * Return: - * - * 0 on success. Otherwise, failure - */ -static int sandbox_ffa_features(ffa_value_t *pargs, ffa_value_t *res) -{ - res->a1 = 0; - - if (pargs->a1 == FFA_SMC_64(FFA_RXTX_MAP)) { - res->a0 = FFA_SMC_32(FFA_SUCCESS); - res->a2 = RXTX_BUFFERS_MIN_SIZE; - res->a3 = 0; - /* x4-x7 MBZ */ - memset(FFA_X4X7_MBZ_REG_START, 0, FFA_X4X7_MBZ_CNT * sizeof(ulong)); - return 0; - } - - res->a0 = FFA_SMC_32(FFA_ERROR); - res->a2 = -NOT_SUPPORTED; - /* x3-x7 MBZ */ - memset(FFA_X3_MBZ_REG_START, 0, FFA_X3X7_MBZ_CNT * sizeof(ulong)); - log_err("FF-A interface %lx not implemented\n", pargs->a1); - - return ffa_to_std_errmap[NOT_SUPPORTED]; -} - -/** - * sandbox_ffa_partition_info_get() - Emulated FFA_PARTITION_INFO_GET handler - * @emul: The sandbox FF-A emulator device - * @pargs: The SMC call input arguments a0-a7 - * @res: The SMC return data - * - * Emulate FFA_PARTITION_INFO_GET FF-A function. - * - * Return: - * - * 0 on success. Otherwise, failure - */ -static int sandbox_ffa_partition_info_get(struct udevice *emul, ffa_value_t *pargs, - ffa_value_t *res) -{ - struct ffa_partition_info *rxbuf_desc_info = NULL; - u32 descs_cnt; - u32 descs_size_bytes; - int ret; - struct sandbox_ffa_emul *priv = dev_get_priv(emul); - - res->a0 = FFA_SMC_32(FFA_ERROR); - - if (!priv->pair.rxbuf) { - res->a2 = -DENIED; - ret = ffa_to_std_errmap[DENIED]; - goto cleanup; - } - - if (priv->pair_info.rxbuf_owned) { - res->a2 = -BUSY; - ret = ffa_to_std_errmap[BUSY]; - goto cleanup; - } - - if (!priv->partitions.descs) { - priv->partitions.descs = sandbox_partitions; - priv->partitions.count = SANDBOX_PARTITIONS_CNT; - } - - descs_size_bytes = SANDBOX_PARTITIONS_CNT * - sizeof(struct ffa_partition_desc); - - /* Abort if the RX buffer size is smaller than the descs buffer size */ - if ((priv->pair_info.rxtx_buf_size * SZ_4K) < descs_size_bytes) { - res->a2 = -NO_MEMORY; - ret = ffa_to_std_errmap[NO_MEMORY]; - goto cleanup; - } - - rxbuf_desc_info = priv->pair.rxbuf; - - /* No UUID specified. Return the information of all partitions */ - if (!pargs->a1 && !pargs->a2 && !pargs->a3 && !pargs->a4) { - for (descs_cnt = 0; descs_cnt < SANDBOX_PARTITIONS_CNT; descs_cnt++) - *(rxbuf_desc_info++) = priv->partitions.descs[descs_cnt].info; - - res->a0 = FFA_SMC_32(FFA_SUCCESS); - res->a2 = SANDBOX_PARTITIONS_CNT; - /* Transfer ownership to the consumer: the non secure world */ - priv->pair_info.rxbuf_owned = 1; - ret = 0; - - goto cleanup; - } - - /* A UUID specified. Return the info of all SPs matching the UUID */ - - for (descs_cnt = 0 ; descs_cnt < SANDBOX_PARTITIONS_CNT ; descs_cnt++) - if (pargs->a1 == priv->partitions.descs[descs_cnt].sp_uuid.a1 && - pargs->a2 == priv->partitions.descs[descs_cnt].sp_uuid.a2 && - pargs->a3 == priv->partitions.descs[descs_cnt].sp_uuid.a3 && - pargs->a4 == priv->partitions.descs[descs_cnt].sp_uuid.a4) { - *(rxbuf_desc_info++) = priv->partitions.descs[descs_cnt].info; - } - - if (rxbuf_desc_info != priv->pair.rxbuf) { - res->a0 = FFA_SMC_32(FFA_SUCCESS); - /* Store the partitions count */ - res->a2 = (ulong) - (rxbuf_desc_info - (struct ffa_partition_info *) - priv->pair.rxbuf); - ret = 0; - - /* Transfer ownership to the consumer: the non secure world */ - priv->pair_info.rxbuf_owned = 1; - } else { - /* Unrecognized UUID */ - res->a2 = -INVALID_PARAMETERS; - ret = ffa_to_std_errmap[INVALID_PARAMETERS]; - } - -cleanup: - - log_err("FFA_PARTITION_INFO_GET (%ld)\n", res->a2); - - res->a1 = 0; - - /* x3-x7 MBZ */ - memset(FFA_X3_MBZ_REG_START, 0, FFA_X3X7_MBZ_CNT * sizeof(ulong)); - - return ret; -} - -/** - * sandbox_ffa_rxtx_map() - Emulated FFA_RXTX_MAP handler - * @emul: The sandbox FF-A emulator device - * @pargs: The SMC call input arguments a0-a7 - * @res: The SMC return data - * - * Emulate FFA_RXTX_MAP FF-A function. - * - * Return: - * - * 0 on success. Otherwise, failure - */ -static int sandbox_ffa_rxtx_map(struct udevice *emul, ffa_value_t *pargs, ffa_value_t *res) -{ - int ret; - struct sandbox_ffa_emul *priv = dev_get_priv(emul); - - res->a0 = FFA_SMC_32(FFA_ERROR); - - if (priv->pair.txbuf && priv->pair.rxbuf) { - res->a2 = -DENIED; - ret = ffa_to_std_errmap[DENIED]; - goto feedback; - } - - if (pargs->a3 >= RXTX_BUFFERS_MIN_PAGES && pargs->a1 && pargs->a2) { - priv->pair.txbuf = map_sysmem(pargs->a1, 0); - priv->pair.rxbuf = map_sysmem(pargs->a2, 0); - priv->pair_info.rxtx_buf_size = pargs->a3; - priv->pair_info.rxbuf_mapped = 1; - res->a0 = FFA_SMC_32(FFA_SUCCESS); - res->a2 = 0; - ret = 0; - goto feedback; - } - - if (!pargs->a1 || !pargs->a2) { - res->a2 = -INVALID_PARAMETERS; - ret = ffa_to_std_errmap[INVALID_PARAMETERS]; - } else { - res->a2 = -NO_MEMORY; - ret = ffa_to_std_errmap[NO_MEMORY]; - } - - log_err("Error in FFA_RXTX_MAP arguments (%d)\n", - (int)res->a2); - -feedback: - - res->a1 = 0; - - /* x3-x7 MBZ */ - memset(FFA_X3_MBZ_REG_START, 0, FFA_X3X7_MBZ_CNT * sizeof(ulong)); - - return ret; -} - -/** - * sandbox_ffa_rxtx_unmap() - Emulated FFA_RXTX_UNMAP handler - * @emul: The sandbox FF-A emulator device - * @pargs: The SMC call input arguments a0-a7 - * @res: The SMC return data - * - * Emulate FFA_RXTX_UNMAP FF-A function. - * - * Return: - * - * 0 on success. Otherwise, failure - */ -static int sandbox_ffa_rxtx_unmap(struct udevice *emul, ffa_value_t *pargs, ffa_value_t *res) -{ - int ret; - struct sandbox_ffa_emul *priv = dev_get_priv(emul); - - res->a0 = FFA_SMC_32(FFA_ERROR); - res->a2 = -INVALID_PARAMETERS; - ret = ffa_to_std_errmap[INVALID_PARAMETERS]; - - if (GET_NS_PHYS_ENDPOINT_ID(pargs->a1) != priv->id) - goto feedback; - - if (priv->pair.txbuf && priv->pair.rxbuf) { - priv->pair.txbuf = 0; - priv->pair.rxbuf = 0; - priv->pair_info.rxtx_buf_size = 0; - priv->pair_info.rxbuf_mapped = 0; - res->a0 = FFA_SMC_32(FFA_SUCCESS); - res->a2 = 0; - ret = 0; - goto feedback; - } - - log_err("No buffer pair registered on behalf of the caller\n"); - -feedback: - - res->a1 = 0; - - /* x3-x7 MBZ */ - memset(FFA_X3_MBZ_REG_START, 0, FFA_X3X7_MBZ_CNT * sizeof(ulong)); - - return ret; -} - -/** - * sandbox_ffa_rx_release() - Emulated FFA_RX_RELEASE handler - * @emul: The sandbox FF-A emulator device - * @pargs: The SMC call input arguments a0-a7 - * @res: The SMC return data - * - * Emulate FFA_RX_RELEASE FF-A function. - * - * Return: - * - * 0 on success. Otherwise, failure - */ -static int sandbox_ffa_rx_release(struct udevice *emul, ffa_value_t *pargs, ffa_value_t *res) -{ - int ret; - struct sandbox_ffa_emul *priv = dev_get_priv(emul); - - if (!priv->pair_info.rxbuf_owned) { - res->a0 = FFA_SMC_32(FFA_ERROR); - res->a2 = -DENIED; - ret = ffa_to_std_errmap[DENIED]; - } else { - priv->pair_info.rxbuf_owned = 0; - res->a0 = FFA_SMC_32(FFA_SUCCESS); - res->a2 = 0; - ret = 0; - } - - res->a1 = 0; - - /* x3-x7 MBZ */ - memset(FFA_X3_MBZ_REG_START, 0, FFA_X3X7_MBZ_CNT * sizeof(ulong)); - - return ret; -} - -/** - * sandbox_ffa_sp_valid() - Check SP validity - * @emul: The sandbox FF-A emulator device - * @part_id: partition ID to check - * - * Search the input ID in the descriptors table. - * - * Return: - * - * 1 on success (Partition found). Otherwise, failure - */ -static int sandbox_ffa_sp_valid(struct udevice *emul, u16 part_id) -{ - u32 descs_cnt; - struct sandbox_ffa_emul *priv = dev_get_priv(emul); - - for (descs_cnt = 0 ; descs_cnt < SANDBOX_PARTITIONS_CNT ; descs_cnt++) - if (priv->partitions.descs[descs_cnt].info.id == part_id) - return 1; - - return 0; -} - -/** - * sandbox_ffa_msg_send_direct_req() - Emulated FFA_MSG_SEND_DIRECT_{REQ,RESP} handler - * @emul: The sandbox FF-A emulator device - * @pargs: The SMC call input arguments a0-a7 - * @res: The SMC return data - * - * Emulate FFA_MSG_SEND_DIRECT_{REQ,RESP} FF-A ABIs. - * Only SMC 64-bit is supported in Sandbox. - * - * Emulating interrupts is not supported. So, FFA_RUN and FFA_INTERRUPT are not - * supported. In case of success FFA_MSG_SEND_DIRECT_RESP is returned with - * default pattern data (0xff). - * - * Return: - * - * 0 on success. Otherwise, failure - */ -static int sandbox_ffa_msg_send_direct_req(struct udevice *emul, - ffa_value_t *pargs, ffa_value_t *res) -{ - u16 part_id; - struct sandbox_ffa_emul *priv = dev_get_priv(emul); - - part_id = GET_DST_SP_ID(pargs->a1); - - if (GET_NS_PHYS_ENDPOINT_ID(pargs->a1) != priv->id || - !sandbox_ffa_sp_valid(emul, part_id) || pargs->a2) { - res->a0 = FFA_SMC_32(FFA_ERROR); - res->a1 = 0; - res->a2 = -INVALID_PARAMETERS; - - /* x3-x7 MBZ */ - memset(FFA_X3_MBZ_REG_START, 0, FFA_X3X7_MBZ_CNT * sizeof(ulong)); - - return ffa_to_std_errmap[INVALID_PARAMETERS]; - } - - res->a0 = FFA_SMC_64(FFA_MSG_SEND_DIRECT_RESP); - - res->a1 = PREP_SRC_SP_ID(part_id) | - PREP_NS_PHYS_ENDPOINT_ID(priv->id); - - res->a2 = 0; - - /* Return 0xff bytes as a response */ - res->a3 = -1UL; - res->a4 = -1UL; - res->a5 = -1UL; - res->a6 = -1UL; - res->a7 = -1UL; - - return 0; -} - -/** - * sandbox_ffa_get_rxbuf_flags() - Read the mapping/ownership flags - * @emul: The sandbox FF-A emulator device - * @queried_func_id: The FF-A function to be queried - * @func_data: Pointer to the FF-A function arguments container structure - * - * Query the status flags of the following emulated - * ABIs: FFA_RXTX_MAP, FFA_RXTX_UNMAP, FFA_RX_RELEASE. - * - * Return: - * - * 0 on success. Otherwise, failure - */ -static int sandbox_ffa_get_rxbuf_flags(struct udevice *emul, u32 queried_func_id, - struct ffa_sandbox_data *func_data) -{ - struct sandbox_ffa_emul *priv = dev_get_priv(emul); - - if (!func_data) - return -EINVAL; - - if (!func_data->data0 || func_data->data0_size != sizeof(u8)) - return -EINVAL; - - switch (queried_func_id) { - case FFA_RXTX_MAP: - case FFA_RXTX_UNMAP: - *((u8 *)func_data->data0) = priv->pair_info.rxbuf_mapped; - return 0; - case FFA_RX_RELEASE: - *((u8 *)func_data->data0) = priv->pair_info.rxbuf_owned; - return 0; - default: - log_err("The querried FF-A interface flag (%d) undefined\n", - queried_func_id); - return -EINVAL; - } -} - -/** - * sandbox_ffa_get_fwk_version() - Return the FFA framework version - * @emul: The sandbox FF-A emulator device - * @func_data: Pointer to the FF-A function arguments container structure - * - * Return the FFA framework version read from the FF-A emulator data. - * - * Return: - * - * 0 on success. Otherwise, failure - */ -static int sandbox_ffa_get_fwk_version(struct udevice *emul, struct ffa_sandbox_data *func_data) -{ - struct sandbox_ffa_emul *priv = dev_get_priv(emul); - - if (!func_data) - return -EINVAL; - - if (!func_data->data0 || - func_data->data0_size != sizeof(priv->fwk_version)) - return -EINVAL; - - *((u32 *)func_data->data0) = priv->fwk_version; - - return 0; -} - -/** - * sandbox_ffa_get_parts() - Return the address of partitions data - * @emul: The sandbox FF-A emulator device - * @func_data: Pointer to the FF-A function arguments container structure - * - * Return the address of partitions data read from the FF-A emulator data. - * - * Return: - * - * 0 on success. Otherwise, failure - */ -static int sandbox_ffa_get_parts(struct udevice *emul, struct ffa_sandbox_data *func_data) -{ - struct sandbox_ffa_emul *priv = dev_get_priv(emul); - - if (!func_data) - return -EINVAL; - - if (!func_data->data0 || - func_data->data0_size != sizeof(struct ffa_partitions *)) - return -EINVAL; - - *((struct ffa_partitions **)func_data->data0) = &priv->partitions; - - return 0; -} - -/** - * sandbox_query_ffa_emul_state() - Inspect the FF-A ABIs - * @queried_func_id: The FF-A function to be queried - * @func_data: Pointer to the FF-A function arguments container structure - * - * Query the status of FF-A ABI specified in the input argument. - * - * Return: - * - * 0 on success. Otherwise, failure - */ -int sandbox_query_ffa_emul_state(u32 queried_func_id, - struct ffa_sandbox_data *func_data) -{ - struct udevice *emul; - int ret; - - ret = uclass_first_device_err(UCLASS_FFA_EMUL, &emul); - if (ret) { - log_err("Cannot find FF-A emulator during querying state\n"); - return ret; - } - - switch (queried_func_id) { - case FFA_RXTX_MAP: - case FFA_RXTX_UNMAP: - case FFA_RX_RELEASE: - return sandbox_ffa_get_rxbuf_flags(emul, queried_func_id, func_data); - case FFA_VERSION: - return sandbox_ffa_get_fwk_version(emul, func_data); - case FFA_PARTITION_INFO_GET: - return sandbox_ffa_get_parts(emul, func_data); - default: - log_err("Undefined FF-A interface (%d)\n", - queried_func_id); - return -EINVAL; - } -} - -/** - * sandbox_arm_ffa_smccc_smc() - FF-A SMC call emulation - * @args: the SMC call arguments - * @res: the SMC call returned data - * - * Emulate the FF-A ABIs SMC call. - * The emulated FF-A ABI is identified and invoked. - * FF-A emulation is based on the FF-A specification 1.0 - * - * Return: - * - * 0 on success. Otherwise, failure. - * FF-A protocol error codes are returned using the registers arguments as - * described by the specification - */ -void sandbox_arm_ffa_smccc_smc(ffa_value_t *args, ffa_value_t *res) -{ - int ret = 0; - struct udevice *emul; - - ret = uclass_first_device_err(UCLASS_FFA_EMUL, &emul); - if (ret) { - log_err("Cannot find FF-A emulator during SMC emulation\n"); - return; - } - - switch (args->a0) { - case FFA_SMC_32(FFA_VERSION): - ret = sandbox_ffa_version(emul, args, res); - break; - case FFA_SMC_32(FFA_PARTITION_INFO_GET): - ret = sandbox_ffa_partition_info_get(emul, args, res); - break; - case FFA_SMC_32(FFA_RXTX_UNMAP): - ret = sandbox_ffa_rxtx_unmap(emul, args, res); - break; - case FFA_SMC_64(FFA_MSG_SEND_DIRECT_REQ): - ret = sandbox_ffa_msg_send_direct_req(emul, args, res); - break; - case FFA_SMC_32(FFA_ID_GET): - ret = sandbox_ffa_id_get(emul, args, res); - break; - case FFA_SMC_32(FFA_FEATURES): - ret = sandbox_ffa_features(args, res); - break; - case FFA_SMC_64(FFA_RXTX_MAP): - ret = sandbox_ffa_rxtx_map(emul, args, res); - break; - case FFA_SMC_32(FFA_RX_RELEASE): - ret = sandbox_ffa_rx_release(emul, args, res); - break; - default: - log_err("Undefined FF-A interface (%lx)\n", - args->a0); - } - - if (ret != 0) - log_err("FF-A ABI internal failure (%d)\n", ret); -} - -/** - * invoke_ffa_fn() - SMC wrapper - * @args: FF-A ABI arguments to be copied to Xn registers - * @res: FF-A ABI return data to be copied from Xn registers - * - * Calls the emulated SMC call. - */ -void invoke_ffa_fn(ffa_value_t args, ffa_value_t *res) -{ - sandbox_arm_ffa_smccc_smc(&args, res); -} - -/** - * ffa_emul_find() - Find the FF-A emulator - * @dev: the sandbox FF-A device (sandbox-arm-ffa) - * @emulp: the FF-A emulator device (sandbox-ffa-emul) - * - * Search for the FF-A emulator and returns its device pointer. - * - * Return: - * 0 on success. Otherwise, failure - */ -int ffa_emul_find(struct udevice *dev, struct udevice **emulp) -{ - int ret; - - ret = uclass_first_device_err(UCLASS_FFA_EMUL, emulp); - if (ret) { - log_err("Cannot find FF-A emulator\n"); - return ret; - } - - log_info("FF-A emulator ready to use\n"); - - return 0; -} - -UCLASS_DRIVER(ffa_emul) = { - .name = "ffa_emul", - .id = UCLASS_FFA_EMUL, - .post_bind = dm_scan_fdt_dev, -}; - -static const struct udevice_id sandbox_ffa_emul_ids[] = { - { .compatible = "sandbox,arm-ffa-emul" }, - { } -}; - -/* Declaring the sandbox FF-A emulator under UCLASS_FFA_EMUL */ -U_BOOT_DRIVER(sandbox_ffa_emul) = { - .name = "sandbox_ffa_emul", - .id = UCLASS_FFA_EMUL, - .of_match = sandbox_ffa_emul_ids, - .priv_auto = sizeof(struct sandbox_ffa_emul), -}; diff --git a/drivers/firmware/arm-ffa/sandbox_ffa.c b/drivers/firmware/arm-ffa/sandbox_ffa.c deleted file mode 100644 index ef9491ccead..00000000000 --- a/drivers/firmware/arm-ffa/sandbox_ffa.c +++ /dev/null @@ -1,110 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright 2022-2023 Arm Limited and/or its affiliates <open-source-office@arm.com> - * - * Authors: - * Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com> - */ -#include <common.h> -#include <arm_ffa.h> -#include <dm.h> -#include <log.h> -#include <asm/global_data.h> -#include <asm/sandbox_arm_ffa_priv.h> -#include <dm/device-internal.h> -#include <linux/errno.h> - -DECLARE_GLOBAL_DATA_PTR; - -/** - * sandbox_ffa_discover() - perform sandbox FF-A discovery - * @dev: The sandbox FF-A bus device - * Try to discover the FF-A framework. Discovery is performed by - * querying the FF-A framework version from secure world using the FFA_VERSION ABI. - * Return: - * - * 0 on success. Otherwise, failure - */ -static int sandbox_ffa_discover(struct udevice *dev) -{ - int ret; - struct udevice *emul; - - log_info("Emulated FF-A framework discovery\n"); - - ret = ffa_emul_find(dev, &emul); - if (ret) { - log_err("Cannot find FF-A emulator\n"); - return ret; - } - - ret = ffa_get_version_hdlr(dev); - if (ret) - return ret; - - return 0; -} - -/** - * sandbox_ffa_probe() - The sandbox FF-A driver probe function - * @dev: the sandbox-arm-ffa device - * Save the emulator device in uc_priv. - * Return: - * - * 0 on success. - */ -static int sandbox_ffa_probe(struct udevice *dev) -{ - int ret; - struct ffa_priv *uc_priv = dev_get_uclass_priv(dev); - - ret = uclass_first_device_err(UCLASS_FFA_EMUL, &uc_priv->emul); - if (ret) { - log_err("Cannot find FF-A emulator\n"); - return ret; - } - - return 0; -} - -/** - * sandbox_ffa_bind() - The sandbox FF-A driver bind function - * @dev: the sandbox-arm-ffa device - * Try to discover the emulated FF-A bus. - * Return: - * - * 0 on success. - */ -static int sandbox_ffa_bind(struct udevice *dev) -{ - int ret; - - ret = sandbox_ffa_discover(dev); - if (ret) - return ret; - - return 0; -} - -/* Sandbox Arm FF-A emulator operations */ - -static const struct ffa_bus_ops sandbox_ffa_ops = { - .partition_info_get = ffa_get_partitions_info_hdlr, - .sync_send_receive = ffa_msg_send_direct_req_hdlr, - .rxtx_unmap = ffa_unmap_rxtx_buffers_hdlr, -}; - -static const struct udevice_id sandbox_ffa_id[] = { - { "sandbox,arm-ffa", 0 }, - { }, -}; - -/* Declaring the sandbox FF-A driver under UCLASS_FFA */ -U_BOOT_DRIVER(sandbox_arm_ffa) = { - .name = "sandbox_arm_ffa", - .of_match = sandbox_ffa_id, - .id = UCLASS_FFA, - .bind = sandbox_ffa_bind, - .probe = sandbox_ffa_probe, - .ops = &sandbox_ffa_ops, -}; |