Abdellatif El Khlifi | 39d383b | 2023-08-04 14:33:40 +0100 | [diff] [blame^] | 1 | .. SPDX-License-Identifier: GPL-2.0+ |
| 2 | |
| 3 | Arm FF-A Support |
| 4 | ================ |
| 5 | |
| 6 | Summary |
| 7 | ------- |
| 8 | |
| 9 | FF-A stands for Firmware Framework for Arm A-profile processors. |
| 10 | |
| 11 | FF-A specifies interfaces that enable a pair of software execution environments aka partitions to |
| 12 | communicate with each other. A partition could be a VM in the Normal or Secure world, an |
| 13 | application in S-EL0, or a Trusted OS in S-EL1. |
| 14 | |
| 15 | The U-Boot FF-A support (the bus) implements the interfaces to communicate |
| 16 | with partitions in the Secure world aka Secure partitions (SPs). |
| 17 | |
| 18 | The FF-A support specifically focuses on communicating with SPs that |
| 19 | isolate portions of EFI runtime services that must run in a protected |
| 20 | environment which is inaccessible by the Host OS or Hypervisor. |
| 21 | Examples of such services are set/get variables. |
| 22 | |
| 23 | The FF-A support uses the SMC ABIs defined by the FF-A specification to: |
| 24 | |
| 25 | - Discover the presence of SPs of interest |
| 26 | - Access an SP's service through communication protocols |
| 27 | e.g. EFI MM communication protocol |
| 28 | |
| 29 | At this stage of development only EFI boot-time services are supported. |
| 30 | Runtime support will be added in future developments. |
| 31 | |
| 32 | The U-Boot FF-A support provides the following parts: |
| 33 | |
| 34 | - A Uclass driver providing generic FF-A methods. |
| 35 | - An Arm FF-A device driver providing Arm-specific methods and reusing the Uclass methods. |
| 36 | |
| 37 | FF-A and SMC specifications |
| 38 | ------------------------------------------- |
| 39 | |
| 40 | The current implementation of the U-Boot FF-A support relies on |
| 41 | `FF-A v1.0 specification`_ and uses SMC32 calling convention which |
| 42 | means using the first 32-bit data of the Xn registers. |
| 43 | |
| 44 | At this stage we only need the FF-A v1.0 features. |
| 45 | |
| 46 | The FF-A support has been tested with OP-TEE which supports SMC32 calling |
| 47 | convention. |
| 48 | |
| 49 | Hypervisors are supported if they are configured to trap SMC calls. |
| 50 | |
| 51 | The FF-A support uses 64-bit registers as per `SMC Calling Convention v1.2 specification`_. |
| 52 | |
| 53 | Supported hardware |
| 54 | -------------------------------- |
| 55 | |
| 56 | Aarch64 plaforms |
| 57 | |
| 58 | Configuration |
| 59 | ---------------------- |
| 60 | |
| 61 | CONFIG_ARM_FFA_TRANSPORT |
| 62 | Enables the FF-A support. Turn this on if you want to use FF-A |
| 63 | communication. |
| 64 | When using an Arm 64-bit platform, the Arm FF-A driver will be used. |
| 65 | |
| 66 | FF-A ABIs under the hood |
| 67 | --------------------------------------- |
| 68 | |
| 69 | Invoking an FF-A ABI involves providing to the secure world/hypervisor the |
| 70 | expected arguments from the ABI. |
| 71 | |
| 72 | On an Arm 64-bit platform, the ABI arguments are stored in x0 to x7 registers. |
| 73 | Then, an SMC instruction is executed. |
| 74 | |
| 75 | At the secure side level or hypervisor the ABI is handled at a higher exception |
| 76 | level and the arguments are read and processed. |
| 77 | |
| 78 | The response is put back through x0 to x7 registers and control is given back |
| 79 | to the U-Boot Arm FF-A driver (non-secure world). |
| 80 | |
| 81 | The driver reads the response and processes it accordingly. |
| 82 | |
| 83 | This methodology applies to all the FF-A ABIs. |
| 84 | |
| 85 | FF-A bus discovery on Arm 64-bit platforms |
| 86 | --------------------------------------------- |
| 87 | |
| 88 | When CONFIG_ARM_FFA_TRANSPORT is enabled, the FF-A bus is considered as |
| 89 | an architecture feature and discovered using ARM_SMCCC_FEATURES mechanism. |
| 90 | This discovery mechanism is performed by the PSCI driver. |
| 91 | |
| 92 | The PSCI driver comes with a PSCI device tree node which is the root node for all |
| 93 | architecture features including FF-A bus. |
| 94 | |
| 95 | :: |
| 96 | |
| 97 | => dm tree |
| 98 | |
| 99 | Class Index Probed Driver Name |
| 100 | ----------------------------------------------------------- |
| 101 | ... |
| 102 | firmware 0 [ + ] psci |-- psci |
| 103 | ffa 0 [ ] arm_ffa | `-- arm_ffa |
| 104 | ... |
| 105 | |
| 106 | The PSCI driver is bound to the PSCI device and when probed it tries to discover |
| 107 | the architecture features by calling a callback the features drivers provide. |
| 108 | |
| 109 | In case of FF-A, the callback is arm_ffa_is_supported() which tries to discover the |
| 110 | FF-A framework by querying the FF-A framework version from secure world using |
| 111 | FFA_VERSION ABI. When discovery is successful, the ARM_SMCCC_FEATURES |
| 112 | mechanism creates a U-Boot device for the FF-A bus and binds the Arm FF-A driver |
| 113 | with the device using device_bind_driver(). |
| 114 | |
| 115 | At this stage the FF-A bus is registered with the DM and can be interacted with using |
| 116 | the DM APIs. |
| 117 | |
| 118 | Clients are able to probe then use the FF-A bus by calling uclass_first_device(). |
| 119 | |
| 120 | When calling uclass_first_device(), the FF-A driver is probed and ends up calling |
| 121 | ffa_do_probe() provided by the Uclass which does the following: |
| 122 | |
| 123 | - saving the FF-A framework version in uc_priv |
| 124 | - querying from secure world the u-boot endpoint ID |
| 125 | - querying from secure world the supported features of FFA_RXTX_MAP |
| 126 | - mapping the RX/TX buffers |
| 127 | - querying from secure world all the partitions information |
| 128 | |
| 129 | When one of the above actions fails, probing fails and the driver stays not active |
| 130 | and can be probed again if needed. |
| 131 | |
| 132 | Requirements for clients |
| 133 | ------------------------------------- |
| 134 | |
| 135 | When using the FF-A bus with EFI, clients must query the SPs they are looking for |
| 136 | during EFI boot-time mode using the service UUID. |
| 137 | |
| 138 | The RX/TX buffers are only available at EFI boot-time. Querying partitions is |
| 139 | done at boot time and data is cached for future use. |
| 140 | |
| 141 | RX/TX buffers should be unmapped before EFI runtime mode starts. |
| 142 | The driver provides a bus operation for that called ffa_rxtx_unmap(). |
| 143 | |
| 144 | The user should call ffa_rxtx_unmap() to unmap the RX/TX buffers when required |
| 145 | (e.g: at efi_exit_boot_services()). |
| 146 | |
| 147 | The Linux kernel allocates its own RX/TX buffers. To be able to register these kernel buffers |
| 148 | with secure world, the U-Boot's RX/TX buffers should be unmapped before EFI runtime starts. |
| 149 | |
| 150 | When invoking FF-A direct messaging, clients should specify which ABI protocol |
| 151 | they want to use (32-bit vs 64-bit). Selecting the protocol means using |
| 152 | the 32-bit or 64-bit version of FFA_MSG_SEND_DIRECT_{REQ, RESP}. |
| 153 | The calling convention between U-Boot and the secure world stays the same: SMC32. |
| 154 | |
| 155 | Requirements for user drivers |
| 156 | ------------------------------------- |
| 157 | |
| 158 | Users who want to implement their custom FF-A device driver while reusing the FF-A Uclass can do so |
| 159 | by implementing their own invoke_ffa_fn() in the user driver. |
| 160 | |
| 161 | The bus driver layer |
| 162 | ------------------------------ |
| 163 | |
| 164 | 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 |
| 165 | |
| 166 | The following features are provided: |
| 167 | |
| 168 | - Support for the 32-bit version of the following ABIs: |
| 169 | |
| 170 | - FFA_VERSION |
| 171 | - FFA_ID_GET |
| 172 | - FFA_FEATURES |
| 173 | - FFA_PARTITION_INFO_GET |
| 174 | - FFA_RXTX_UNMAP |
| 175 | - FFA_RX_RELEASE |
| 176 | - FFA_RUN |
| 177 | - FFA_ERROR |
| 178 | - FFA_SUCCESS |
| 179 | - FFA_INTERRUPT |
| 180 | - FFA_MSG_SEND_DIRECT_REQ |
| 181 | - FFA_MSG_SEND_DIRECT_RESP |
| 182 | |
| 183 | - Support for the 64-bit version of the following ABIs: |
| 184 | |
| 185 | - FFA_RXTX_MAP |
| 186 | - FFA_MSG_SEND_DIRECT_REQ |
| 187 | - FFA_MSG_SEND_DIRECT_RESP |
| 188 | |
| 189 | - Processing the received data from the secure world/hypervisor and caching it |
| 190 | |
| 191 | - Hiding from upper layers the FF-A protocol and registers details. Upper |
| 192 | layers focus on exchanged data, FF-A support takes care of how to transport |
| 193 | that to the secure world/hypervisor using FF-A |
| 194 | |
| 195 | - FF-A support provides driver operations to be used by upper layers: |
| 196 | |
| 197 | - ffa_partition_info_get |
| 198 | - ffa_sync_send_receive |
| 199 | - ffa_rxtx_unmap |
| 200 | |
| 201 | - FF-A bus discovery makes sure FF-A framework is responsive and compatible |
| 202 | with the driver |
| 203 | |
| 204 | - FF-A bus can be compiled and used without EFI |
| 205 | |
| 206 | Example of boot logs with FF-A enabled |
| 207 | -------------------------------------- |
| 208 | |
| 209 | For example, when using FF-A with Corstone-1000 the logs are as follows: |
| 210 | |
| 211 | :: |
| 212 | |
| 213 | U-Boot 2023.01 (May 10 2023 - 11:08:07 +0000) corstone1000 aarch64 |
| 214 | |
| 215 | DRAM: 2 GiB |
| 216 | Arm FF-A framework discovery |
| 217 | FF-A driver 1.0 |
| 218 | FF-A framework 1.0 |
| 219 | FF-A versions are compatible |
| 220 | ... |
| 221 | FF-A driver 1.0 |
| 222 | FF-A framework 1.0 |
| 223 | FF-A versions are compatible |
| 224 | EFI: MM partition ID 0x8003 |
| 225 | ... |
| 226 | EFI stub: Booting Linux Kernel... |
| 227 | ... |
| 228 | 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 |
| 229 | Machine model: ARM Corstone1000 FPGA MPS3 board |
| 230 | |
| 231 | Contributors |
| 232 | ------------ |
| 233 | * Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com> |
| 234 | |
| 235 | .. _`FF-A v1.0 specification`: https://documentation-service.arm.com/static/5fb7e8a6ca04df4095c1d65e |
| 236 | .. _`SMC Calling Convention v1.2 specification`: https://documentation-service.arm.com/static/5f8edaeff86e16515cdbe4c6 |