diff options
author | Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com> | 2023-08-04 14:33:40 +0100 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2023-08-08 10:22:03 -0400 |
commit | 39d383bdace4b39b10665c7df2f1ef17399f6f1e (patch) | |
tree | c24057673a660b67e884927e7f5820bad2e45139 /drivers/firmware/arm-ffa/arm-ffa.c | |
parent | b83dc8df6471f472340b88f1e3f3230e836b1fa9 (diff) |
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>
Diffstat (limited to 'drivers/firmware/arm-ffa/arm-ffa.c')
-rw-r--r-- | drivers/firmware/arm-ffa/arm-ffa.c | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/drivers/firmware/arm-ffa/arm-ffa.c b/drivers/firmware/arm-ffa/arm-ffa.c new file mode 100644 index 00000000000..68df75bd9e5 --- /dev/null +++ b/drivers/firmware/arm-ffa/arm-ffa.c @@ -0,0 +1,104 @@ +// 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, +}; |