| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261 |
- .. SPDX-License-Identifier: GPL-2.0+
- Arm FF-A Support
- ================
- Summary
- -------
- FF-A stands for Firmware Framework for Arm A-profile processors.
- FF-A specifies interfaces that enable a pair of software execution environments aka partitions to
- communicate with each other. A partition could be a VM in the Normal or Secure world, an
- application in S-EL0, or a Trusted OS in S-EL1.
- The U-Boot FF-A support (the bus) implements the interfaces to communicate
- with partitions in the Secure world aka Secure partitions (SPs).
- The FF-A support specifically focuses on communicating with SPs that
- isolate portions of EFI runtime services that must run in a protected
- environment which is inaccessible by the Host OS or Hypervisor.
- Examples of such services are set/get variables.
- The FF-A support uses the SMC ABIs defined by the FF-A specification to:
- - Discover the presence of SPs of interest
- - Access an SP's service through communication protocols
- e.g. EFI MM communication protocol
- At this stage of development only EFI boot-time services are supported.
- Runtime support will be added in future developments.
- The U-Boot FF-A support provides the following parts:
- - A Uclass driver providing generic FF-A methods.
- - An Arm FF-A device driver providing Arm-specific methods and reusing the Uclass methods.
- - A sandbox emulator for Arm FF-A, emulates the FF-A side of the Secure World and provides
- FF-A ABIs inspection methods.
- - An FF-A sandbox device driver for FF-A communication with the emulated Secure World.
- The driver leverages the FF-A Uclass to establish FF-A communication.
- - Sandbox FF-A test cases.
- FF-A and SMC specifications
- -------------------------------------------
- The current implementation of the U-Boot FF-A support relies on
- `FF-A v1.0 specification`_ and uses SMC32 calling convention which
- means using the first 32-bit data of the Xn registers.
- At this stage we only need the FF-A v1.0 features.
- The FF-A support has been tested with OP-TEE which supports SMC32 calling
- convention.
- Hypervisors are supported if they are configured to trap SMC calls.
- The FF-A support uses 64-bit registers as per `SMC Calling Convention v1.2 specification`_.
- Supported hardware
- --------------------------------
- Aarch64 plaforms
- Configuration
- ----------------------
- CONFIG_ARM_FFA_TRANSPORT
- Enables the FF-A support. Turn this on if you want to use FF-A
- communication.
- When using an Arm 64-bit platform, the Arm FF-A driver will be used.
- When using sandbox, the sandbox FF-A emulator and FF-A sandbox driver will be used.
- FF-A ABIs under the hood
- ---------------------------------------
- Invoking an FF-A ABI involves providing to the secure world/hypervisor the
- expected arguments from the ABI.
- On an Arm 64-bit platform, the ABI arguments are stored in x0 to x7 registers.
- Then, an SMC instruction is executed.
- At the secure side level or hypervisor the ABI is handled at a higher exception
- level and the arguments are read and processed.
- The response is put back through x0 to x7 registers and control is given back
- to the U-Boot Arm FF-A driver (non-secure world).
- The driver reads the response and processes it accordingly.
- This methodology applies to all the FF-A ABIs.
- FF-A bus discovery on Arm 64-bit platforms
- ---------------------------------------------
- When CONFIG_ARM_FFA_TRANSPORT is enabled, the FF-A bus is considered as
- an architecture feature and discovered using ARM_SMCCC_FEATURES mechanism.
- This discovery mechanism is performed by the PSCI driver.
- The PSCI driver comes with a PSCI device tree node which is the root node for all
- architecture features including FF-A bus.
- ::
- => dm tree
- Class Index Probed Driver Name
- -----------------------------------------------------------
- firmware 0 [ + ] psci |-- psci
- ffa 0 [ ] arm_ffa | `-- arm_ffa
- The PSCI driver is bound to the PSCI device and when probed it tries to discover
- the architecture features by calling a callback the features drivers provide.
- In case of FF-A, the callback is arm_ffa_is_supported() which tries to discover the
- FF-A framework by querying the FF-A framework version from secure world using
- FFA_VERSION ABI. When discovery is successful, the ARM_SMCCC_FEATURES
- mechanism creates a U-Boot device for the FF-A bus and binds the Arm FF-A driver
- with the device using device_bind_driver().
- At this stage the FF-A bus is registered with the DM and can be interacted with using
- the DM APIs.
- Clients are able to probe then use the FF-A bus by calling uclass_first_device().
- Please refer to the armffa command implementation as an example of how to probe
- and interact with the FF-A bus.
- When calling uclass_first_device(), the FF-A driver is probed and ends up calling
- ffa_do_probe() provided by the Uclass which does the following:
- - 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
- When one of the above actions fails, probing fails and the driver stays not active
- and can be probed again if needed.
- Requirements for clients
- -------------------------------------
- When using the FF-A bus with EFI, clients must query the SPs they are looking for
- during EFI boot-time mode using the service UUID.
- The RX/TX buffers are only available at EFI boot-time. Querying partitions is
- done at boot time and data is cached for future use.
- RX/TX buffers should be unmapped before EFI runtime mode starts.
- The driver provides a bus operation for that called ffa_rxtx_unmap().
- The user should call ffa_rxtx_unmap() to unmap the RX/TX buffers when required
- (e.g: at efi_exit_boot_services()).
- The Linux kernel allocates its own RX/TX buffers. To be able to register these kernel buffers
- with secure world, the U-Boot's RX/TX buffers should be unmapped before EFI runtime starts.
- When invoking FF-A direct messaging, clients should specify which ABI protocol
- they want to use (32-bit vs 64-bit). Selecting the protocol means using
- the 32-bit or 64-bit version of FFA_MSG_SEND_DIRECT_{REQ, RESP}.
- The calling convention between U-Boot and the secure world stays the same: SMC32.
- Requirements for user drivers
- -------------------------------------
- Users who want to implement their custom FF-A device driver while reusing the FF-A Uclass can do so
- by implementing their own invoke_ffa_fn() in the user driver.
- The bus driver layer
- ------------------------------
- FF-A support comes on top of the SMCCC layer and is implemented by the FF-A Uclass drivers/firmware/arm-ffa/arm-ffa-uclass.c
- The following features are provided:
- - Support for the 32-bit version of the following ABIs:
- - FFA_VERSION
- - FFA_ID_GET
- - FFA_FEATURES
- - FFA_PARTITION_INFO_GET
- - FFA_RXTX_UNMAP
- - FFA_RX_RELEASE
- - FFA_RUN
- - FFA_ERROR
- - FFA_SUCCESS
- - FFA_INTERRUPT
- - FFA_MSG_SEND_DIRECT_REQ
- - FFA_MSG_SEND_DIRECT_RESP
- - Support for the 64-bit version of the following ABIs:
- - FFA_RXTX_MAP
- - FFA_MSG_SEND_DIRECT_REQ
- - FFA_MSG_SEND_DIRECT_RESP
- - Processing the received data from the secure world/hypervisor and caching it
- - Hiding from upper layers the FF-A protocol and registers details. Upper
- layers focus on exchanged data, FF-A support takes care of how to transport
- that to the secure world/hypervisor using FF-A
- - FF-A support provides driver operations to be used by upper layers:
- - ffa_partition_info_get
- - ffa_sync_send_receive
- - ffa_rxtx_unmap
- - FF-A bus discovery makes sure FF-A framework is responsive and compatible
- with the driver
- - FF-A bus can be compiled and used without EFI
- Relationship between the sandbox emulator and the FF-A device
- ---------------------------------------------------------------
- ::
- => dm tree
- Class Index Probed Driver Name
- -----------------------------------------------------------
- ffa_emul 0 [ + ] sandbox_ffa_emul `-- arm-ffa-emul
- ffa 0 [ ] sandbox_arm_ffa `-- sandbox-arm-ffa
- The armffa command
- -----------------------------------
- armffa is a command showcasing how to use the FF-A bus and how to invoke the driver operations.
- Please refer the command documentation at :doc:`../usage/cmd/armffa`
- Example of boot logs with FF-A enabled
- --------------------------------------
- For example, when using FF-A with Corstone-1000, debug logs enabled, the output is as follows:
- ::
- U-Boot 2023.01 (May 10 2023 - 11:08:07 +0000) corstone1000 aarch64
- DRAM: 2 GiB
- Arm FF-A framework discovery
- FF-A driver 1.0
- FF-A framework 1.0
- FF-A versions are compatible
- ...
- FF-A driver 1.0
- FF-A framework 1.0
- FF-A versions are compatible
- EFI: MM partition ID 0x8003
- ...
- EFI stub: Booting Linux Kernel...
- ...
- Linux version 6.1.9-yocto-standard (oe-user@oe-host) (aarch64-poky-linux-musl-gcc (GCC) 12.2.0, GNU ld (GNU Binutils) 2.40.202301193
- Machine model: ARM Corstone1000 FPGA MPS3 board
- Contributors
- ------------
- * Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
- .. _`FF-A v1.0 specification`: https://documentation-service.arm.com/static/5fb7e8a6ca04df4095c1d65e
- .. _`SMC Calling Convention v1.2 specification`: https://documentation-service.arm.com/static/5f8edaeff86e16515cdbe4c6
|