Jelle Sels | 3ef999a | 2021-03-29 09:35:37 +0200 | [diff] [blame] | 1 | ==== |
| 2 | SPMC |
| 3 | ==== |
| 4 | |
| 5 | This document describes the SPMC (S-EL1) implementation for OP-TEE. |
| 6 | More information on the SPMC can be found in the FF-A specification can be |
| 7 | found in the |
| 8 | `FF-A spec <https://developer.arm.com/documentation/den0077/latest>`_. |
| 9 | |
| 10 | .. toctree:: |
| 11 | :numbered: |
| 12 | |
| 13 | SPMC Responsibilities |
| 14 | ===================== |
| 15 | |
| 16 | The SPMC is a critical component in the FF-A flow. Some of its major |
| 17 | responsibilities are: |
| 18 | |
| 19 | - Initialisation and run-time management of the SPs: |
| 20 | The SPMC component is responsible for initialisation of the |
| 21 | Secure Partitions (loading the image, setting up the stack, heap, ...). |
| 22 | - Routing messages between endpoints: |
| 23 | The SPMC is responsible for passing FF-A messages from normal world |
| 24 | to SPs and back. It also responsible for passing FF-A messages between |
| 25 | SPs. |
| 26 | - Memory management: |
| 27 | The SPMC is responsible for the memory management of the SPs. Memory |
| 28 | can be shared between SPs and between a SP to the normal world. |
| 29 | |
| 30 | This document describes OP-TEE as a S-EL1 SPMC. |
| 31 | |
| 32 | Secure Partitions |
| 33 | ================= |
| 34 | Secure Partitions (SPs) are the endpoints used in the FF-A protocol. When |
| 35 | OP-TEE is used as a SPMC SPs run primarily inside S-EL0. |
| 36 | |
| 37 | OP-TEE will use FF-A for it transport layer when the OP-TEE ``CFG_CORE_FFA=y`` |
| 38 | configuration flag is enabled. |
| 39 | The SPMC will expose the OP-TEE core, privileged mode, as an secure endpoint |
| 40 | itself. This is used to handle all GlobalPlaform programming mode operations. |
| 41 | All GlobalPlatform messages are encapsulated inside FF-A messages. |
| 42 | The OP-TEE endpoint will unpack the messages and afterwards handle them as |
| 43 | standard OP-TEE calls. This is needed as TF-A (S-EL3) does only allow |
| 44 | FF-A messages to be passed to the secure world when the SPMD is enabled. |
| 45 | |
| 46 | SPs run from the initial boot of the system until power down and don't have any |
| 47 | built-in session management compared to GPD TEE TAs. The only means of |
| 48 | communicating with the outside world is through messages defined in the FF-A |
| 49 | specification. The context of a SP is saved between executions. |
| 50 | |
| 51 | The |
| 52 | `Trusted Service <https://www.trustedfirmware.org/projects/trusted-services/>`_ |
| 53 | repository includes the libsp libary which export all needed functions to build |
| 54 | a S-EL0 SP. It also includes many examples of how to create and implement a SP. |
| 55 | |
Imre Kis | c235158 | 2022-11-22 17:16:38 +0100 | [diff] [blame] | 56 | Secure Partition formats |
| 57 | ======================== |
| 58 | |
| 59 | OP-TEE specific ELF format |
| 60 | -------------------------- |
| 61 | |
| 62 | OP-TEE uses an ELF format for its :ref:`trusted_applications`. It has an OP-TEE |
| 63 | specific section which contains a header structure for describing the Trusted |
| 64 | Application. A very similar format can be used for Secure Partitions. The same |
| 65 | ELF format allows OP-TEE to use the built-in ELF loader (``ldelf``) with all its |
| 66 | features like handling relocations or ASLR. In this case a different section is |
| 67 | used for the header structure to distinguish between Trusted Applications and |
| 68 | Secure Partitions. |
| 69 | |
| 70 | SPMC agnostic flat binary format |
| 71 | -------------------------------- |
| 72 | |
| 73 | This simple binary format aims for maximum portability between SPMC |
| 74 | implementations by removing the dependency on an ELF loader and implementation |
| 75 | specific metadata in the SP image. The SPMC can simply copy the binary into the |
| 76 | memory and start running it. The relocations, the stack setup and any further |
| 77 | initialization steps should be handled by the startup code of the secure |
| 78 | partition. The access rights for different sections of the binary can be |
| 79 | configured either by adding load relative memory regions to the SP manifest or |
| 80 | by using the ``FFA_MEM_PERM_SET`` interface in the startup code. |
| 81 | |
Jelle Sels | 3ef999a | 2021-03-29 09:35:37 +0200 | [diff] [blame] | 82 | SPMC Program Flow |
| 83 | ================= |
Balint Dobszay | fe29e2b | 2022-09-27 15:41:30 +0200 | [diff] [blame] | 84 | SP images are either embedded into the OP-TEE image or loaded from the FIP by |
| 85 | BL2. This makes it possible to start SPs during boot, before the rich OS is |
Imre Kis | c235158 | 2022-11-22 17:16:38 +0100 | [diff] [blame] | 86 | available in the normal world. |
Jelle Sels | 3ef999a | 2021-03-29 09:35:37 +0200 | [diff] [blame] | 87 | |
| 88 | Starting SPs |
| 89 | ------------ |
| 90 | SPs are loaded and started as the last step in OP-TEE's initialisation process. |
| 91 | This is done by adding ``sp_init_all()`` to the ``boot_final`` initcall level. |
| 92 | |
| 93 | .. uml:: |
| 94 | :width: 800 |
| 95 | |
| 96 | autoactivate on |
| 97 | thread_optee_smc_a64.s -> boot_final |
| 98 | boot_final -> secure_partition.c: sp_init_all() |
| 99 | loop for each SP |
| 100 | secure_partition.c -> secure_partition.c: sp_init_uuid() |
| 101 | return |
| 102 | end |
| 103 | return |
| 104 | return |
| 105 | autoactivate off |
| 106 | thread_optee_smc_a64.s -> thread_optee_smc_a64.s: thread_ffa_msg_wait() |
| 107 | thread_optee_smc_a64.s -> thread_optee_smc_a64.s: ffa_msg_loop() |
| 108 | autoactivate off |
| 109 | thread_optee_smc_a64.s -> SPMD: SMC |
| 110 | |
| 111 | :``sp_init_all()``: Initialise all SPs which have been added by the |
| 112 | ``SP_PATHS`` compiler option and run them |
| 113 | :``thread_ffa_msg_wait()``: All SPs are loaded and started. A |
| 114 | ``FFA_MSG_WAIT`` message is sent to the Normal |
| 115 | World. |
| 116 | |
| 117 | |
Imre Kis | c235158 | 2022-11-22 17:16:38 +0100 | [diff] [blame] | 118 | Each ELF format SP is loaded into the system using ``ldelf`` and started. This |
| 119 | is based around the same process as loading the early TAs. |
| 120 | For each binary format SP a simpler method is used to copy the binary into a |
| 121 | suitable memory area. |
Jelle Sels | 3ef999a | 2021-03-29 09:35:37 +0200 | [diff] [blame] | 122 | All SPs are run after they are loaded and run until a ``FFA_MSG_WAIT`` is sent |
| 123 | by the SP. |
| 124 | |
| 125 | |
| 126 | .. uml:: |
| 127 | |
| 128 | autoactivate on |
| 129 | secure_partition.c -> secure_partition.c: sp_init_uuid() |
| 130 | secure_partition.c -> secure_partition.c: sp_open_session() |
| 131 | secure_partition.c -> secure_partition.c: find_sp() |
| 132 | return |
| 133 | secure_partition.c -> secure_partition.c: sp_create_session() |
| 134 | return |
Imre Kis | c235158 | 2022-11-22 17:16:38 +0100 | [diff] [blame] | 135 | alt OP-TEE specific ELF format |
| 136 | secure_partition.c -> secure_partition.c:ldelf_load_ldelf() |
| 137 | return |
| 138 | secure_partition.c -> secure_partition.c:ldlelf_init_with_ldelf() |
| 139 | return |
| 140 | else SPMC agnostic flat binary format |
| 141 | secure_partition.c -> secure_partition.c:load_binary_sp() |
| 142 | return |
| 143 | end |
Jelle Sels | 3ef999a | 2021-03-29 09:35:37 +0200 | [diff] [blame] | 144 | secure_partition.c -> secure_partition.c: sp_init_set_registers() |
| 145 | return |
| 146 | return |
| 147 | secure_partition.c -> secure_partition.c: enter_sp() |
| 148 | return |
| 149 | secure_partition.c -> secure_partition.c: sp_msg_handler() |
| 150 | return |
| 151 | return |
| 152 | |
Imre Kis | c235158 | 2022-11-22 17:16:38 +0100 | [diff] [blame] | 153 | :``init_with_ldelf()``: Load the OP-TEE specific ELF format SP |
| 154 | :``load_binary_sp()``: Load the SPMC agnostic flat binary format SP |
Jelle Sels | 3ef999a | 2021-03-29 09:35:37 +0200 | [diff] [blame] | 155 | :``sp_init_info()``: Initialise the ``struct ffa_init_info``. The |
| 156 | ``struct ffa_init_info`` is passed to the SP |
| 157 | during it first run. |
| 158 | :``sp_init_set_registers()``: Initialise the registers of the SP |
| 159 | :``sp_msg_handler()``: Handle the SPs FF-A message |
| 160 | |
| 161 | Once all SPs are loaded and started we return to the SPMD and the Normal World |
| 162 | is booted. |
| 163 | |
| 164 | |
| 165 | SP message handling |
| 166 | ------------------- |
| 167 | |
| 168 | The SPMC is split into 2 main message handlers: |
| 169 | |
| 170 | :``thread_spmc_msg_recv()`` thread_spmc.c: Used to handle message coming |
| 171 | from the Normal World. |
| 172 | :``sp_msg_handler()`` spmc_sp_handler.c: Used to handle message where |
| 173 | the source or the destination |
| 174 | is a SP. |
| 175 | |
| 176 | When a ``FFA_MSG_SEND_DIRECT_REQ`` message is received by the SPMC from the |
| 177 | Normal World, a new thread is started. |
| 178 | The FF-A message is passed to the thread and it will call the |
| 179 | ``sp_msg_handler()`` function. |
| 180 | |
| 181 | Whenever the SPMC (``sp_msg_handler()``) receives a message not intended for |
| 182 | one of the SPs, it will exit the thread and return to the Normal World |
| 183 | passing the FF-A message. |
| 184 | |
| 185 | Currently only a ``FFA_MSG_SEND_DIRECT_REQ`` can be passed from the Normal |
| 186 | World to a SP. |
| 187 | |
| 188 | .. uml:: |
| 189 | :width: 800 |
| 190 | |
| 191 | skinparam backgroundcolor transparent |
| 192 | participant "None-secure world" as None_secure_world |
| 193 | |
| 194 | box "S-EL3" |
| 195 | participant SPMD |
| 196 | end box |
| 197 | |
| 198 | box "S-EL1" |
| 199 | participant thread_spmc |
| 200 | participant spmc_sp_handler |
| 201 | end box |
| 202 | |
| 203 | |
| 204 | box "S-EL0" |
| 205 | participant SP |
| 206 | end box |
| 207 | |
| 208 | autoactivate on |
| 209 | None_secure_world -> SPMD: FFA_MSG_SEND_DIRECT_REQ \n <font color=red>SMC |
| 210 | SPMD -> thread_spmc: thread_spmc_msg_recv() \n <font color=red>ERET |
| 211 | |
| 212 | thread_spmc -> spmc_sp_handler : spmc_sp_start_thread() |
| 213 | == thread == |
| 214 | spmc_sp_handler -> spmc_sp_handler : sp_msg_handler() |
| 215 | |
| 216 | loop FF-A dst != NSW |
| 217 | spmc_sp_handler -> spmc_sp_handler: ffa_handle_sp_direct_req() |
| 218 | spmc_sp_handler -> spmc_sp_handler: enter_sp() |
| 219 | spmc_sp_handler -> spmc_sp_handler: sp_enter_invoke_cmd() |
| 220 | autoactivate off |
| 221 | spmc_sp_handler -> SP: __thread_enter_user_mode() \n <font color=red>ERET |
| 222 | activate SP |
| 223 | |
| 224 | SP -> spmc_sp_handler : (FF-A message) sp_handle_svc() \n <font color=red>SVC |
| 225 | deactivate SP |
| 226 | activate spmc_sp_handler |
| 227 | spmc_sp_handler -> spmc_sp_handler: Store SP context |
| 228 | spmc_sp_handler -> spmc_sp_handler: return to sp_enter_invoke_cmd() |
| 229 | deactivate spmc_sp_handler |
| 230 | spmc_sp_handler -> spmc_sp_handler: Retrieve FF-A message from SP context |
| 231 | return |
| 232 | return |
| 233 | return |
| 234 | end |
| 235 | return |
| 236 | == End of thread == |
| 237 | return |
| 238 | return \n <font color=red>SMC |
| 239 | return FFA_MSG_SEND_DIRECT_RESP \n <font color=red>ERET |
| 240 | |
| 241 | |
| 242 | Every message received by the SPMC from the Normal World is handled in the |
| 243 | ``thread_spmc_msg_recv()`` function. |
| 244 | |
| 245 | When entering a SP we need to be running in a OP-TEE thread. This is needed to |
| 246 | be able to push the TS session (We push the TS session to get access to the SP |
| 247 | memory). |
| 248 | Currently the only possibility to enter a SP from the Normal world is via a |
| 249 | ``FFA_MSG_SEND_DIRECT_REQ``. Whenever we receive a ``FFA_MSG_SEND_DIRECT_REQ`` |
| 250 | message which doesn't have OP-TEE as the endpoint-id, we start a thread and |
| 251 | forward the FF-A message to the ``sp_msg_handler()``. |
| 252 | |
| 253 | The ``sp_msg_handler()`` is responsible for all messages coming or going |
| 254 | to/from a SP. It runs in a while loop and will handle every message until it |
| 255 | comes across a messages which is not intended for the secure world. |
| 256 | After a message is handled by the SPMC or when it needs to be forwarded to a SP, |
| 257 | ``sp_enter()`` is called. |
| 258 | ``sp_enter()`` will copy the FF-A arguments and resume the SP. |
| 259 | |
| 260 | When the SPMC needs to have access to the SPs memory, it will call |
| 261 | ``ts_push_current_session()`` to gain access and ``ts_pop_current_session()`` |
| 262 | to release the access. |
| 263 | |
| 264 | Running and exiting SPs |
| 265 | ----------------------- |
| 266 | |
| 267 | The SPMC resumes/starts the SP by calling the ``sp_enter()``. This will set up |
| 268 | the SP context and jump into S-EL0. |
| 269 | Whenever the SP performs a system call it will end up in ``sp_handle_svc()``. |
| 270 | ``sp_handle_svc()`` stores the current context of the SP and makes sure that we |
| 271 | don't return to S-EL0 but instead returns to S-EL1 back to ``sp_enter()``. |
| 272 | ``sp_enter()`` will pass the FF-A registers (x0-x7) to |
| 273 | ``spmc_sp_msg_handler()``. This will process the FF-A message. |
| 274 | |
| 275 | |
| 276 | RxTx buffer managment |
| 277 | --------------------- |
| 278 | RxTx buffers are used by the SPMC to exchange information between an endpoint |
| 279 | and the SPMC. The rxtx_buf struct is used by the SPMC for abstracting buffer |
| 280 | management. |
| 281 | Every SP has a ``struct rxtx_buf`` wich will be passed to every function that |
| 282 | needs access to the rxtx buffer. |
| 283 | A separate ``struct rxtx_buf`` is defined for the Normal World, which gives |
| 284 | access to the Normal World buffers. |
| 285 | |
Imre Kis | 9d7e104 | 2023-02-10 18:13:09 +0100 | [diff] [blame] | 286 | FF-A compliance |
| 287 | =============== |
| 288 | |
| 289 | .. |ffa_fs| replace:: :opticon:`check-circle-fill` |
| 290 | .. |ffa_ps| replace:: :opticon:`check-circle` |
| 291 | .. |ffa_ns| replace:: :opticon:`x` |
| 292 | .. |ffa_na| replace:: :opticon:`horizontal-rule` |
| 293 | |
| 294 | Legend |
| 295 | ------ |
| 296 | |
| 297 | * |ffa_fs| Fully supported |
| 298 | * |ffa_ps| Partially implemented |
| 299 | * |ffa_ns| Not supported |
| 300 | * |ffa_na| Does not apply for the FF-A instance or version |
| 301 | |
| 302 | Partition boot protocol |
| 303 | ----------------------- |
| 304 | |
| 305 | Only FF-A v1.0 partition boot protocol is supported by the SPMC. |
| 306 | |
| 307 | Supported partition manifest fields |
| 308 | ----------------------------------- |
| 309 | |
| 310 | +--------------------------------+-----------+-----------+-----------+ |
| 311 | | Field | Mandatory | FF-A v1.0 | FF-A v1.1 | |
| 312 | +================================+===========+===========+===========+ |
| 313 | | FF-A version | Yes | |ffa_ns| | |ffa_ns| | |
| 314 | +--------------------------------+-----------+-----------+-----------+ |
| 315 | | UUID | Yes | |ffa_fs| | |ffa_fs| | |
| 316 | +--------------------------------+-----------+-----------+-----------+ |
| 317 | | Partition ID | No | |ffa_fs| | |ffa_fs| | |
| 318 | +--------------------------------+-----------+-----------+-----------+ |
| 319 | | Auxiliary IDs | No | |ffa_ns| | |ffa_ns| | |
| 320 | +--------------------------------+-----------+-----------+-----------+ |
| 321 | | Name (description) | No | |ffa_fs| | |ffa_fs| | |
| 322 | +--------------------------------+-----------+-----------+-----------+ |
| 323 | | Number of execution contexts | Yes | |ffa_ns| | |ffa_ns| | |
| 324 | +--------------------------------+-----------+-----------+-----------+ |
| 325 | | Run-time EL | Yes | |ffa_ns| | |ffa_ns| | |
| 326 | +--------------------------------+-----------+-----------+-----------+ |
| 327 | | Execution state | Yes | |ffa_ns| | |ffa_ns| | |
| 328 | +--------------------------------+-----------+-----------+-----------+ |
| 329 | | Load address | No | |ffa_ns| | |ffa_ns| | |
| 330 | +--------------------------------+-----------+-----------+-----------+ |
| 331 | | Entry point offset | No | |ffa_ns| | |ffa_ns| | |
| 332 | +--------------------------------+-----------+-----------+-----------+ |
| 333 | | Translation granule | No | |ffa_ns| | |ffa_ns| | |
| 334 | +--------------------------------+-----------+-----------+-----------+ |
| 335 | | Boot order | No | |ffa_ns| | |ffa_ns| | |
| 336 | +--------------------------------+-----------+-----------+-----------+ |
| 337 | | RX/TX information | No | |ffa_ns| | |ffa_ns| | |
| 338 | +--------------------------------+-----------+-----------+-----------+ |
| 339 | | Messaging method | Yes | |ffa_ns| | |ffa_ns| | |
| 340 | +--------------------------------+-----------+-----------+-----------+ |
| 341 | | Primary scheduler implemented | No | |ffa_na| | |ffa_na| | |
| 342 | +--------------------------------+-----------+-----------+-----------+ |
| 343 | | Run-time model | No | |ffa_ns| | |ffa_ns| | |
| 344 | +--------------------------------+-----------+-----------+-----------+ |
| 345 | | Tuples | No | |ffa_ns| | |ffa_ns| | |
| 346 | +--------------------------------+-----------+-----------+-----------+ |
| 347 | | **Memory regions** | |
| 348 | +--------------------------------+-----------+-----------+-----------+ |
| 349 | | Base address | No | |ffa_fs| | |ffa_fs| | |
| 350 | +--------------------------------+-----------+-----------+-----------+ |
| 351 | | Load address relative offset | No | |ffa_na| | |ffa_fs| | |
| 352 | +--------------------------------+-----------+-----------+-----------+ |
| 353 | | Page count | Yes | |ffa_fs| | |ffa_fs| | |
| 354 | +--------------------------------+-----------+-----------+-----------+ |
| 355 | | Attributes | Yes | |ffa_ps| | |ffa_ps| | |
| 356 | +--------------------------------+-----------+-----------+-----------+ |
| 357 | | Name | No | |ffa_ns| | |ffa_ns| | |
| 358 | +--------------------------------+-----------+-----------+-----------+ |
| 359 | | Stream & SMMU IDs | No | |ffa_na| | |ffa_ns| | |
| 360 | +--------------------------------+-----------+-----------+-----------+ |
| 361 | | Stream ID access permissions | No | |ffa_na| | |ffa_ns| | |
| 362 | +--------------------------------+-----------+-----------+-----------+ |
| 363 | | **Device regions** | |
| 364 | +--------------------------------+-----------+-----------+-----------+ |
| 365 | | Physical base address | Yes | |ffa_fs| | |ffa_fs| | |
| 366 | +--------------------------------+-----------+-----------+-----------+ |
| 367 | | Page count | Yes | |ffa_fs| | |ffa_fs| | |
| 368 | +--------------------------------+-----------+-----------+-----------+ |
| 369 | | Attributes | Yes | |ffa_fs| | |ffa_fs| | |
| 370 | +--------------------------------+-----------+-----------+-----------+ |
| 371 | | Interrupts | No | |ffa_ns| | |ffa_ns| | |
| 372 | +--------------------------------+-----------+-----------+-----------+ |
| 373 | | SMMU IDs | No | |ffa_ns| | |ffa_ns| | |
| 374 | +--------------------------------+-----------+-----------+-----------+ |
| 375 | | Stream IDs | No | |ffa_ns| | |ffa_ns| | |
| 376 | +--------------------------------+-----------+-----------+-----------+ |
| 377 | | Exclusive access and ownership | No | |ffa_ns| | |ffa_ns| | |
| 378 | +--------------------------------+-----------+-----------+-----------+ |
| 379 | | Name | No | |ffa_ns| | |ffa_ns| | |
| 380 | +--------------------------------+-----------+-----------+-----------+ |
| 381 | |
| 382 | Limitations |
| 383 | ^^^^^^^^^^^ |
| 384 | |
| 385 | * The values of mandatory but not supported fields are ignored by the SP loader. |
| 386 | This means all values are accepted but the SPMC might behave differently than |
| 387 | expected. |
| 388 | * Memory region attributes doesn't support shareability and cacheability flags. |
| 389 | |
| 390 | Supported FF-A interfaces |
| 391 | ------------------------- |
| 392 | |
| 393 | The table below describes the implementation level of each FF-A interface on |
| 394 | different FF-A instances. The two instances are between OP-TEE SPMC and the SPMC |
| 395 | and between OP-TEE SPMC and its S-EL0 secure partitions. The FF-A specification |
| 396 | uses 'Secure Phyisical' and 'Secure Virtual' terms for these instances. |
| 397 | |
| 398 | +--------------------------+-----------------------+-----------------------+ |
| 399 | | | OP-TEE <-> SPMD | OP-TEE <-> S-EL0 SPs | |
| 400 | | Interface +-----------+-----------+-----------+-----------+ |
| 401 | | | FF-A v1.0 | FF-A v1.1 | FF-A v1.0 | FF-A v1.1 | |
| 402 | +==========================+===========+===========+===========+===========+ |
| 403 | | FFA_ERROR | |ffa_fs| | |ffa_ps| | |ffa_fs| | |ffa_ps| | |
| 404 | +--------------------------+-----------+-----------+-----------+-----------+ |
| 405 | | FFA_SUCCESS | |ffa_fs| | |ffa_fs| | |ffa_ps| | |ffa_ps| | |
| 406 | +--------------------------+-----------+-----------+-----------+-----------+ |
| 407 | | FFA_INTERRUPT | |ffa_ps| | |ffa_ps| | |ffa_ns| | |ffa_ns| | |
| 408 | +--------------------------+-----------+-----------+-----------+-----------+ |
| 409 | | FFA_VERSION | |ffa_fs| | |ffa_fs| | |ffa_fs| | |ffa_fs| | |
| 410 | +--------------------------+-----------+-----------+-----------+-----------+ |
| 411 | | FFA_FEATURES | |ffa_ps| | |ffa_ns| | |ffa_ps| | |ffa_ns| | |
| 412 | +--------------------------+-----------+-----------+-----------+-----------+ |
| 413 | | FFA_RX_ACQUIRE | |ffa_na| | |ffa_ns| | |ffa_na| | |ffa_ns| | |
| 414 | +--------------------------+-----------+-----------+-----------+-----------+ |
| 415 | | FFA_RX_RELEASE | |ffa_fs| | |ffa_fs| | |ffa_fs| | |ffa_fs| | |
| 416 | +--------------------------+-----------+-----------+-----------+-----------+ |
| 417 | | FFA_RXTX_MAP | |ffa_fs| | |ffa_fs| | |ffa_fs| | |ffa_fs| | |
| 418 | +--------------------------+-----------+-----------+-----------+-----------+ |
| 419 | | FFA_RXTX_UNMAP | |ffa_fs| | |ffa_fs| | |ffa_fs| | |ffa_fs| | |
| 420 | +--------------------------+-----------+-----------+-----------+-----------+ |
| 421 | | FFA_PARTITION_INFO_GET | |ffa_fs| | |ffa_ns| | |ffa_fs| | |ffa_ns| | |
| 422 | +--------------------------+-----------+-----------+-----------+-----------+ |
| 423 | | FFA_ID_GET | |ffa_fs| | |ffa_fs| | |ffa_fs| | |ffa_fs| | |
| 424 | +--------------------------+-----------+-----------+-----------+-----------+ |
| 425 | | FFA_SPM_ID_GET | |ffa_na| | |ffa_ns| | |ffa_na| | |ffa_ns| | |
| 426 | +--------------------------+-----------+-----------+-----------+-----------+ |
| 427 | | FFA_MSG_WAIT | |ffa_fs| | |ffa_fs| | |ffa_fs| | |ffa_fs| | |
| 428 | +--------------------------+-----------+-----------+-----------+-----------+ |
| 429 | | FFA_YIELD | |ffa_na| | |ffa_ns| | |ffa_na| | |ffa_ns| | |
| 430 | +--------------------------+-----------+-----------+-----------+-----------+ |
| 431 | | FFA_RUN | |ffa_ns| | |ffa_ns| | |ffa_ns| | |ffa_ns| | |
| 432 | +--------------------------+-----------+-----------+-----------+-----------+ |
| 433 | | FFA_NORMAL_WORLD_RESUME | |ffa_ns| | |ffa_ns| | |ffa_ns| | |ffa_ns| | |
| 434 | +--------------------------+-----------+-----------+-----------+-----------+ |
| 435 | | FFA_MSG_SEND | |ffa_na| | |ffa_na| | |ffa_na| | |ffa_na| | |
| 436 | +--------------------------+-----------+-----------+-----------+-----------+ |
| 437 | | FFA_MSG_SEND2 | |ffa_na| | |ffa_ns| | |ffa_na| | |ffa_ns| | |
| 438 | +--------------------------+-----------+-----------+-----------+-----------+ |
| 439 | | FFA_MSG_SEND_DIRECT_REQ | |ffa_fs| | |ffa_ps| | |ffa_fs| | |ffa_ps| | |
| 440 | +--------------------------+-----------+-----------+-----------+-----------+ |
| 441 | | FFA_MSG_SEND_DIRECT_RESP | |ffa_fs| | |ffa_ps| | |ffa_fs| | |ffa_ps| | |
| 442 | +--------------------------+-----------+-----------+-----------+-----------+ |
| 443 | | FFA_MSG_POLL | |ffa_na| | |ffa_na| | |ffa_na| | |ffa_na| | |
| 444 | +--------------------------+-----------+-----------+-----------+-----------+ |
| 445 | | FFA_MEM_DONATE | |ffa_ns| | |ffa_ns| | |ffa_ns| | |ffa_ns| | |
| 446 | +--------------------------+-----------+-----------+-----------+-----------+ |
| 447 | | FFA_MEM_LEND | |ffa_ns| | |ffa_ns| | |ffa_ns| | |ffa_ns| | |
| 448 | +--------------------------+-----------+-----------+-----------+-----------+ |
| 449 | | FFA_MEM_SHARE | |ffa_ps| | |ffa_ps| | |ffa_ps| | |ffa_ps| | |
| 450 | +--------------------------+-----------+-----------+-----------+-----------+ |
| 451 | | FFA_MEM_RETRIEVE_REQ | |ffa_ps| | |ffa_ps| | |ffa_ps| | |ffa_ps| | |
| 452 | +--------------------------+-----------+-----------+-----------+-----------+ |
| 453 | | FFA_MEM_RETRIEVE_RESP | |ffa_ps| | |ffa_ps| | |ffa_ps| | |ffa_ps| | |
| 454 | +--------------------------+-----------+-----------+-----------+-----------+ |
| 455 | | FFA_MEM_RELINQUISH | |ffa_ps| | |ffa_ps| | |ffa_ps| | |ffa_ps| | |
| 456 | +--------------------------+-----------+-----------+-----------+-----------+ |
| 457 | | FFA_MEM_RECLAIM | |ffa_fs| | |ffa_fs| | |ffa_fs| | |ffa_fs| | |
| 458 | +--------------------------+-----------+-----------+-----------+-----------+ |
| 459 | | FFA_MEM_PERM_GET | |ffa_na| | |ffa_na| | |ffa_fs| | |ffa_fs| | |
| 460 | +--------------------------+-----------+-----------+-----------+-----------+ |
| 461 | | FFA_MEM_PERM_SET | |ffa_na| | |ffa_na| | |ffa_fs| | |ffa_fs| | |
| 462 | +--------------------------+-----------+-----------+-----------+-----------+ |
| 463 | | FFA_MEM_FRAG_RX | |ffa_fs| | |ffa_fs| | |ffa_ns| | |ffa_ns| | |
| 464 | +--------------------------+-----------+-----------+-----------+-----------+ |
| 465 | | FFA_MEM_FRAG_TX | |ffa_fs| | |ffa_fs| | |ffa_ns| | |ffa_ns| | |
| 466 | +--------------------------+-----------+-----------+-----------+-----------+ |
| 467 | | FFA_MEM_OP_PAUSE | |ffa_ns| | |ffa_ns| | |ffa_ns| | |ffa_ns| | |
| 468 | +--------------------------+-----------+-----------+-----------+-----------+ |
| 469 | | FFA_MEM_OP_RESUME | |ffa_ns| | |ffa_ns| | |ffa_ns| | |ffa_ns| | |
| 470 | +--------------------------+-----------+-----------+-----------+-----------+ |
| 471 | |
| 472 | Limitations |
| 473 | ^^^^^^^^^^^ |
| 474 | |
| 475 | * FF-A v1.1 error code ``NO_DATA`` is not supported. |
| 476 | * ``FFA_SUCCESS`` is not supported as a response to an |
| 477 | ``FFA_MSG_SEND_DIRECT_REQ`` message. |
| 478 | * Non-secure interrupts are not forwarded to the normal world via |
| 479 | ``FFA_INTERRUPT``. |
| 480 | * Interrupts cannot be forwarded to S-EL0 secure partitions. |
| 481 | * Only ``FFA_RXTX_MAP`` feature query is supported by the ``FFA_FEATURES`` |
| 482 | interface. ``FFA_MEM_DONATE``, ``FFA_MEM_LEND``, ``FFA_MEM_SHARE`` and |
| 483 | ``FFA_MEM_RETRIEVE_REQ`` feature query is not implemented. |
| 484 | * FF-A v1.1 ``Flags`` field in ``FFA_MSG_SEND_DIRECT_REQ`` and |
| 485 | ``FFA_MSG_SEND_DIRECT_RESP`` calls is not supported. |
| 486 | * Transferring memory transaction descriptors in a buffer distinct from the TX |
| 487 | buffer is not supported by the secure virtual instance. |
| 488 | * Transferring fragmented memory transaction descriptors is not supported by the |
| 489 | secure virtual instance. |
| 490 | * The only supported 'Memory region attributes descriptor' value is normal |
| 491 | memory, write-back cacheability and inner shareable. All other values are |
| 492 | denied on the secure physical instance. The secure virtual instance's |
| 493 | implementation ignores the value of this descriptor but uses the same |
| 494 | attributes for the region. |
| 495 | * The NS flag support in not implemented for 'Memory region attributes |
| 496 | descriptor'. |
| 497 | * Only read-write non-executable value can be used in the 'Memory access |
| 498 | permissions descriptor' at the secure phyisical instance. |
| 499 | * The ``Flags`` field of ``FFA_MEM_RELINQUISH`` is ignored. |
| 500 | * The secure phyisical instanced doesn't implemented the receiving of |
| 501 | ``FFA_MEM_RELINQUISH``. |
| 502 | * Time slicing of memory management operations is not supported. |
Jelle Sels | 3ef999a | 2021-03-29 09:35:37 +0200 | [diff] [blame] | 503 | |
| 504 | Configuration |
| 505 | ============= |
| 506 | |
Balint Dobszay | fe29e2b | 2022-09-27 15:41:30 +0200 | [diff] [blame] | 507 | SPMC config options |
| 508 | --------------------------- |
Jelle Sels | 3ef999a | 2021-03-29 09:35:37 +0200 | [diff] [blame] | 509 | |
Balint Dobszay | fe29e2b | 2022-09-27 15:41:30 +0200 | [diff] [blame] | 510 | To configure OP-TEE as a S-EL1 SPMC with Secure Partition support, the following |
| 511 | flags should be set for optee_os: |
Jelle Sels | 3ef999a | 2021-03-29 09:35:37 +0200 | [diff] [blame] | 512 | |
Balint Dobszay | fe29e2b | 2022-09-27 15:41:30 +0200 | [diff] [blame] | 513 | - ``CFG_CORE_SEL1_SPMC=y`` |
| 514 | - ``CFG_SECURE_PARTITION=y`` |
| 515 | - ``CFG_DT=y`` |
| 516 | - ``CFG_MAP_EXT_DT_SECURE=y`` |
Jelle Sels | 3ef999a | 2021-03-29 09:35:37 +0200 | [diff] [blame] | 517 | |
Balint Dobszay | fe29e2b | 2022-09-27 15:41:30 +0200 | [diff] [blame] | 518 | Furthermore TF-A should be configured as the SPMD, expecting a S-EL1 SPMC: |
Jelle Sels | 3ef999a | 2021-03-29 09:35:37 +0200 | [diff] [blame] | 519 | |
Balint Dobszay | fe29e2b | 2022-09-27 15:41:30 +0200 | [diff] [blame] | 520 | - ``SPD=spmd`` |
| 521 | - ``SPMD_SPM_AT_SEL2=0`` |
| 522 | - ``ARM_SPMC_MANIFEST_DTS=<path to SPMC manifest dts>`` |
| 523 | |
| 524 | SP loading mechanism |
| 525 | --------------------- |
| 526 | |
| 527 | OP-TEE SPMC supports two methods for finding and loading the SP executable |
| 528 | images. Currently only ELF executables are supported. In the build repo the |
| 529 | loading method can be selected with the SP_PACKAGING_METHOD option. |
| 530 | |
| 531 | Embedded SP |
| 532 | ^^^^^^^^^^^ |
| 533 | |
| 534 | In this case the early TA mechanism of optee_os is reused: the SP ELF files are |
| 535 | embedded into the main OP-TEE binary. Each ELF should start with a specific |
| 536 | section (.sp_head) containing a struct which describes the SP (UUID, stack size, |
| 537 | etc.). The images can be added to optee_os using the ``SP_PATHS`` config option, |
| 538 | the build repo will set this up automatically when |
| 539 | ``SP_PACKAGING_METHOD=embedded`` is selected. The images passed in ``SP_PATHS`` |
| 540 | are processed by ``ts_bin_to_c.py`` in optee_os and linked into the main binary. |
| 541 | At runtime the ``for_each_secure_partition()`` macro can iterate through these |
Imre Kis | c235158 | 2022-11-22 17:16:38 +0100 | [diff] [blame] | 542 | images, so a particular SP can be found by UUID and then loaded. |
Balint Dobszay | fe29e2b | 2022-09-27 15:41:30 +0200 | [diff] [blame] | 543 | |
| 544 | The SP manifest file `[1]`_ used by the SPMC to setup SPs is also handled by |
| 545 | ``ts_bin_to_c.py``, it will be concatenated to the end of the SP ELF. |
| 546 | |
| 547 | FIP SP |
| 548 | ^^^^^^ |
| 549 | |
| 550 | In this case the SP ELF files and the corresponding SP manifest DTs are |
| 551 | encapsulated into SP packages and packed into the FIP. The goal of providing |
| 552 | this alternative flow is to make updating SPs easier (independent of the main |
| 553 | OP-TEE binary) and to get aligned with Hafnium (S-EL2 SPMC). For more |
| 554 | information about the FIP, please refer to the TF-A documentation `[2]`_. The SP |
| 555 | packaging process and the package format is provided by TF-A, detailed |
| 556 | description is available at `[3]`_. In the build repo this method can be |
| 557 | selected by ``SP_PACKAGING_METHOD=fip``, it covers all the necessary setup |
| 558 | automatically. In case of using another buildsystem, the following steps should |
| 559 | be implemented: |
| 560 | |
| 561 | - TF-A config ``SP_LAYOUT_FILE``: provide a JSON file which describes the SPs |
| 562 | (path to SP executable and corresponding DT, example `[4]`_). The TF-A |
| 563 | buildsystem will create the SP packages (using sptool) based on this and pack |
| 564 | them into the FIP. |
| 565 | |
| 566 | - TF-A config ``ARM_BL2_SP_LIST_DTS``: provide a DT snippet which describes the |
| 567 | SPs' UUIDs and load addresses (example: `[5]`_). This will be injected into |
| 568 | the SP list in ``TB_FW_CONFIG`` DT of TF-A, and BL2 will load the SP packages |
| 569 | based on this. Note that BL2 doesn't automatically load all images from the |
| 570 | FIP: it's necessary to explicitly define them in ``TB_FW_CONFIG`` (using this |
| 571 | injected snippet or manually editing the DT). |
| 572 | |
| 573 | - TF-A config ``ARM_SPMC_MANIFEST_DTS``: provide the SPMC manifest (example: |
| 574 | `[6]`_). This DT is passed to the SPMC as a boot argument (in the TF-A naming |
| 575 | convention this is the ``TOS_FW_CONFIG``). It should contain the list of SP |
| 576 | packages and their load addresses in the ``compatible = "arm,sp_pkg"`` node. |
| 577 | |
| 578 | At boot optee_os will parse the SP package load addresses from the SPMC manifest |
| 579 | and find the SP packages already loaded by BL2. Iterating through the SP |
| 580 | packages, based on the SP package header in each package it will map the SP |
| 581 | executable image and the corresponding manifest DT and collect these to the |
| 582 | ``fip_sp_list`` list. Later when initialising the SPs, the ``for_each_fip_sp`` |
Imre Kis | c235158 | 2022-11-22 17:16:38 +0100 | [diff] [blame] | 583 | macro is used to iterate this list and load the executables, just like for the |
| 584 | embedded SP case. |
Balint Dobszay | fe29e2b | 2022-09-27 15:41:30 +0200 | [diff] [blame] | 585 | |
| 586 | .. _[1]: |
| 587 | |
| 588 | [1] https://trustedfirmware-a.readthedocs.io/en/v2.6/components/ffa-manifest-binding.html |
| 589 | |
| 590 | .. _[2]: |
| 591 | |
| 592 | [2] https://trustedfirmware-a.readthedocs.io/en/v2.6/design/firmware-design.html#firmware-image-package-fip |
| 593 | |
| 594 | .. _[3]: |
| 595 | |
| 596 | [3] https://trustedfirmware-a.readthedocs.io/en/v2.6/components/secure-partition-manager.html#secure-partition-packages |
| 597 | |
| 598 | .. _[4]: |
| 599 | |
| 600 | [4] https://trustedfirmware-a.readthedocs.io/en/v2.6/components/secure-partition-manager.html#describing-secure-partitions |
| 601 | |
| 602 | .. _[5]: |
| 603 | |
| 604 | [5] https://github.com/OP-TEE/build/blob/master/fvp/bl2_sp_list.dtsi |
| 605 | |
| 606 | .. _[6]: |
| 607 | |
| 608 | [6] https://github.com/OP-TEE/build/blob/master/fvp/spmc_manifest.dts |