u-boot/drivers/firmware/arm-ffa/arm-ffa.c

105 lines
2.6 KiB
C
Raw Normal View History

arm_ffa: introduce Arm FF-A support Add Arm FF-A support implementing Arm Firmware Framework for Armv8-A v1.0 The Firmware Framework for Arm A-profile processors (FF-A v1.0) [1] describes interfaces (ABIs) that standardize communication between the Secure World and Normal World leveraging TrustZone technology. This driver uses 64-bit registers as per SMCCCv1.2 spec and comes on top of the SMCCC layer. The driver provides the FF-A ABIs needed for querying the FF-A framework from the secure world. The driver uses SMC32 calling convention which means using the first 32-bit data of the Xn registers. All supported ABIs come with their 32-bit version except FFA_RXTX_MAP which has 64-bit version supported. Both 32-bit and 64-bit direct messaging are supported which allows both 32-bit and 64-bit clients to use the FF-A bus. FF-A is a discoverable bus and similar to architecture features. FF-A bus is discovered using ARM_SMCCC_FEATURES mechanism performed by the PSCI driver. Clients are able to probe then use the FF-A bus by calling the DM class searching APIs (e.g: uclass_first_device). 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). This FF-A driver takes care of all the interactions between Normal world and Secure World. The driver exports its operations to be used by upper layers. Exported operations: - ffa_partition_info_get - ffa_sync_send_receive - ffa_rxtx_unmap 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). For more details please refer to the driver documentation [2]. [1]: https://developer.arm.com/documentation/den0077/latest/ [2]: doc/arch/arm64.ffa.rst Signed-off-by: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com> Reviewed-by: Simon Glass <sjg@chromium.org> Reviewed-by: Ilias Apalodimas <ilias.apalodimas@linaro.org> Cc: Tom Rini <trini@konsulko.com> Cc: Jens Wiklander <jens.wiklander@linaro.org> Cc: Heinrich Schuchardt <xypron.glpk@gmx.de>
2023-08-04 13:33:40 +00:00
// 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_debug("Arm FF-A framework discovery\n");
arm_ffa: introduce Arm FF-A support Add Arm FF-A support implementing Arm Firmware Framework for Armv8-A v1.0 The Firmware Framework for Arm A-profile processors (FF-A v1.0) [1] describes interfaces (ABIs) that standardize communication between the Secure World and Normal World leveraging TrustZone technology. This driver uses 64-bit registers as per SMCCCv1.2 spec and comes on top of the SMCCC layer. The driver provides the FF-A ABIs needed for querying the FF-A framework from the secure world. The driver uses SMC32 calling convention which means using the first 32-bit data of the Xn registers. All supported ABIs come with their 32-bit version except FFA_RXTX_MAP which has 64-bit version supported. Both 32-bit and 64-bit direct messaging are supported which allows both 32-bit and 64-bit clients to use the FF-A bus. FF-A is a discoverable bus and similar to architecture features. FF-A bus is discovered using ARM_SMCCC_FEATURES mechanism performed by the PSCI driver. Clients are able to probe then use the FF-A bus by calling the DM class searching APIs (e.g: uclass_first_device). 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). This FF-A driver takes care of all the interactions between Normal world and Secure World. The driver exports its operations to be used by upper layers. Exported operations: - ffa_partition_info_get - ffa_sync_send_receive - ffa_rxtx_unmap 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). For more details please refer to the driver documentation [2]. [1]: https://developer.arm.com/documentation/den0077/latest/ [2]: doc/arch/arm64.ffa.rst Signed-off-by: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com> Reviewed-by: Simon Glass <sjg@chromium.org> Reviewed-by: Ilias Apalodimas <ilias.apalodimas@linaro.org> Cc: Tom Rini <trini@konsulko.com> Cc: Jens Wiklander <jens.wiklander@linaro.org> Cc: Heinrich Schuchardt <xypron.glpk@gmx.de>
2023-08-04 13:33:40 +00:00
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,
};