blob: 26ffed09567e4cec733ff23328dc88170a223850 [file] [log] [blame]
Firmware update on A+M systems
------------------------------
Concept
'''''''
Some platforms have both Cortex-A and Cortex-M subsystems and implement the PSA RoT on the M class core. On such systems
the firmware store is usually read-only or not accessible to the Cortex-A cores due to security reasons. In such cases
it may still be beneficial to implement the cloud update client on the Cortex-A subsystem, and a solution is needed to
bridge the Cortex-A and the Cortex-M firmware update implementations. For this purpose TS implements a special firmware
update agent which is documented below.
.. figure:: ../image/psa-fwu-m-block.svg
Components on an A+M system.
Standards and specifications
''''''''''''''''''''''''''''
* `Platform Security Firmware Update for the A-profile Arm Architecture`_ (A class FWU specification)
* `PSA Certified Firmware Update API 1.0`_ (M class FWU specification)
* `Trusted Firmware-M FWU service`_
Update agent implementation
'''''''''''''''''''''''''''
The update agent implements the `Platform Security Firmware Update for the A-profile Arm Architecture`_ API (prefixed
with ``fwu_``) and acts as a `PSA Certified Firmware Update API 1.0`_ client (prefixed with ``psa_fwu_``). The update
agent has to align the slightly different APIs by maintaining an internal registry of image states and image handles.
The differences between the two firmware update protocols are:
* `Platform Security Firmware Update for the A-profile Arm Architecture`_ identifies images by UUID while
`PSA Certified Firmware Update API 1.0`_ identifies component by an 8 bit component ID.
* Although similar calls are implemented, FWU-A operates on images, while FWU-M on the whole image set.
* There is no *image handle* concept in `PSA Certified Firmware Update API 1.0`_
* Differences in the returned details of the image query functions
The solutions to these differences:
* A static UUID to component ID mapping is used. This has to be passed to the agent init function.
* Gathering per image based calls and then make the actual call to the M class side when the operation was called on
each image.
* Implement internal image handle registry.
* Convert the image query result returned by FWU-M to FWU-A format. There are similar field, but this imposes some
limitations.
``fwu_discover()``
``````````````````
This function returns the list of implemented features.
``fwu_begin_staging()``
```````````````````````
Clients can only write images in staging state. In order to switch to staging state, the client must call
``fwu_begin_staging()``. This results in ``psa_fwu_start()`` calls on all selected images. The client can pass a list of
the selected image UUIDs or select all images for staging.
If the agent is already in staging state when ``fwu_begin_staging()`` is called, then the agent first discards all
transient state by calling ``fwu_cancel_staging()`` and ``psa_fwu_clean()`` on all image.
.. uml:: ../uml/psa_fwu_m_update_agent/fwu_begin_staging.puml
``fwu_end_staging()``
`````````````````````
Finishes the staging state when all images that were selected for the update have been updated. If all selected images
are also accepted the agent switches to regular state and the update is completed. If there are not accepted images, the
agent switches to trial state, so the client can validate the new set of images and accept or reject them.
On calling ``fwu_end_staging()`` the agent calls ``psa_fwu_finish()`` on each selected image, then calls
``psa_fwu_install()``. If all images have been accepted (see ``fwu_commit()``) it also calls ``psa_fwu_accept()``.
.. uml:: ../uml/psa_fwu_m_update_agent/fwu_end_staging.puml
``fwu_cancel_staging()``
````````````````````````
Cancels staging state and reverts to original regular state. The function calls ``psa_fwu_cancel()`` on each selected
image.
.. uml:: ../uml/psa_fwu_m_update_agent/fwu_cancel_staging.puml
``fwu_open()``
``````````````
`Platform Security Firmware Update for the A-profile Arm Architecture`_ has a concept of image handles. An image can be
opened via ``fwu_open()``, then accessed by calling ``fwu_write_stream()`` or ``fwu_read_stream()``, and finally it can
be closed by invoking ``fwu_commit()``. However `PSA Certified Firmware Update API 1.0`_ does not have a similar concept
and once the staging process was started for an image by calling ``psa_fwu_start()``, the image can be written through
``psa_fwu_write()``.
The update agent provides an internal registry of opened images and their access rights so it can handle subsequent
calls on the image handle. The open call can open an image for either write or read operations but not for both. The
image is identified by its UUID. Only images which were selected for staging can be opened for write.
There is no actual call made to the M class side on opening a image.
`PSA Certified Firmware Update API 1.0`_ does not provide a function for reading images, so opening images will fail
except for opening the image directory. Only the image directory supports read operations.
``fwu_write_stream()``
``````````````````````
This function writes data into the opened image. The image handle has to be opened for write operations. The agent calls
``psa_fwu_write()`` for doing the actual write and the write offset is tracked internally.
``fwu_read_stream()``
`````````````````````
This function read data from the opened image. The image handle has to be opened for read operations.
This call is only implemented for the image directory which returns the available image list as specified in
`Platform Security Firmware Update for the A-profile Arm Architecture`_. It does not support the partial reading of the
image directory.
``fwu_commit()``
````````````````
The commit call closes the image handle. The client can also mark the image as accepted on commit and this the method
for accepting all images before calling ``fwu_end_staging()``.
There is no actual call made to the M class side on comiting an image.
``fwu_accept_image()``
``````````````````````
`PSA Certified Firmware Update API 1.0`_ only provides a ``psa_fwu_accept()`` function which accepts the whole set of
selected images. In order to align with the ``fwu_accept_image()`` API, it only marks the given image as accepted and
calls ``psa_fwu_accept()`` when all images have been accepted. This results in a state transition to regular state.
.. uml:: ../uml/psa_fwu_m_update_agent/fwu_accept.puml
``fwu_select_previous()``
`````````````````````````
Selects previous working state (i.e. rejects the firmware update) and transitions back to regular state after calling
``psa_fwu_reject()``.
.. uml:: ../uml/psa_fwu_m_update_agent/fwu_select_previous.puml
Image directory
'''''''''''''''
The client can read the image directory by opening and reading an image with dedicated UUID
(``deee58d9-5147-4ad3-a290-77666e2341a5``). On image directory read, the agent will call ``psa_fwu_query()`` on each
image and convert the value of similar fields.
* The UUID is based on the UUID - component ID mapping passed upon agent initialization.
* The images only support write operation due to FWU-M limitation.
* The image maximal size is copied from the component info structure.
* The lowest accepted version is set to 0.
* The image version is converted from the fields of the component info structure into a single 32 bit value. The build
field is dropped due to lack of space in the 32 bit field.
* The images is marked accepted if its state in the component info structure is ``PSA_FWU_UPDATED``.
.. uml:: ../uml/psa_fwu_m_update_agent/image_directory.puml
--------------
.. _`Platform Security Firmware Update for the A-profile Arm Architecture`: https://developer.arm.com/documentation/den0118/latest/
.. _`PSA Certified Firmware Update API 1.0`: https://arm-software.github.io/psa-api/fwu/1.0/
.. _`Trusted Firmware-M FWU service`: https://tf-m-user-guide.trustedfirmware.org/design_docs/services/tfm_fwu_service.html
*Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.*
SPDX-License-Identifier: BSD-3-Clause