Docs: Move the design documents a level up
Signed-off-by: Anton Komlev <anton.komlev@arm.com>
Change-Id: Ib366994121b7c57c5f4966499c2364f339d11b05
diff --git a/docs/design_docs/bl1.rst b/docs/design_docs/bl1.rst
new file mode 100644
index 0000000..831d019
--- /dev/null
+++ b/docs/design_docs/bl1.rst
@@ -0,0 +1,302 @@
+########################
+BL1 Immutable bootloader
+########################
+
+:Author: Raef Coles
+:Organization: Arm Limited
+:Contact: raef.coles@arm.com
+
+************
+Introduction
+************
+
+Some devices that use TF-M will require initial boot code that is stored in ROM.
+There are a variety of reasons that this might happen:
+
+- The device cannot access flash memory without a driver, so needs some setup
+ to be done before main images on flash can be booted.
+- The device has no on-chip secure flash, and therefore cannot otherwise
+ maintain a tamper-resistant root of trust.
+- The device has a security model that requires an immutable root of trust
+
+Henceforth any bootloader stored in ROM will be referred to as BL1, as it would
+necessarily be the first stage in the boot chain.
+
+TF-M provides a reference second-stage flash bootloader BL2, in order to allow
+easier integration. This bootloader implements all secure boot functionality
+needed to provide a secure chain of trust.
+
+A reference ROM bootloader BL1 has now being added with the same motivation -
+allowing easier integration of TF-M for platforms that do not have their own
+BL1 and require one.
+
+****************************
+BL1 Features and Motivations
+****************************
+
+The reference ROM bootloader provides the following features:
+
+- A split between code being stored in ROM and in other non-volatile memory.
+
+ - This can allow significant cost reduction in fixing bugs compared to
+ ROM-only bootloaders.
+
+- A secure boot mechanism that allows upgrading the next boot stage (which
+ would usually be BL2).
+
+ - This allows for the fixing of any bugs in the BL2 image.
+ - Alternately, this could allow the removal of BL2 in some devices that are
+ constrained in flash space but have ROM.
+
+- A post-quantum resistant asymmetric signature scheme for verifying the next
+ boot stage image.
+
+ - This can allow devices to be securely updated even if attacks
+ involving quantum computers become viable. This could extend the lifespans
+ of devices that might be deployed in the field for many years.
+
+- A mechanism for passing boot measurements to the TF-M runtime so that they
+ can be attested.
+- Tooling to create and sign images.
+- Fault Injection (FI) and Differential Power Analysis (DPA) mitigations.
+
+*********************************
+BL1_1 and BL1_2 split bootloaders
+*********************************
+
+BL1 is split into two distinct boot stages, BL1_1 which is stored in ROM and
+BL1_2 which is stored in other non-volatile storage. This would usually be
+either trusted or untrusted flash, but on platforms without flash memory can be
+OTP. As BL1_2 is verified against a hash stored in OTP, it is immutable after
+provisioning even if stored in mutable storage.
+
+Bugs in ROM bootloaders usually cannot be fixed once a device is provisioned /
+in the field, as ROM code is immutable the only option is fixing the bug in
+newly manufactured devices.
+
+However, it can be very expensive to change the ROM code of devices once
+manufacturing has begun, as it requires changes to the photolithography masks
+that are used to create the device. This cost varies depending on the complexity
+of the device and of the process node that it is being fabricated on, but can be
+large, both in engineering time and material/process costs.
+
+By placing the majority of the immutable bootloader in other storage, we can
+mitigate the costs associated with changing ROM code, as a new BL1_2 image can
+be used at provisioning time with minimal changeover cost. BL1_1 contains a
+minimal codebase responsible mainly for the verification of the BL1_2 image.
+
+The bootflow is as follows. For simplicity this assumes that the boot stage
+after BL1 is BL2, though this is not necessarily the case:
+
+1) BL1_1 begins executing in place from ROM
+2) BL1_1 copies BL1_2 into RAM
+3) BL1_1 verifies BL1_2 against the hash stored in OTP
+4) BL1_1 jumps to BL1_2, if the hash verification has succeeded
+5) BL1_2 copies the primary BL2 image from flash into RAM
+6) BL1_2 verifies the BL2 image using asymmetric cryptography
+7) If verification fails, BL1_2 repeats 5 and 6 with the secondary BL2 image
+8) BL1_2 jumps to BL2, if either image has successfully verified
+
+.. Note::
+ The BL1_2 image is not encrypted, so if it is placed in untrusted flash it
+ will be possible to read the data in the image.
+
+Some optimizations have been made specifically for the case where BL1_2 has been
+stored in OTP:
+
+OTP can be very expensive in terms of chip area, though new technologies like
+antifuse OTP decrease this cost. Because of this, the code size of BL1_2 has
+been minimized. Code-sharing has been configured so that BL1_2 can call
+functions stored in ROM. Care should be taken that OTP is sized such that it is
+possible to include versions of the functions used via code-sharing, in case the
+ROM functions contain bugs, though less space is needed than if all code is
+duplicated as it is assumed that most functions will not contain bugs.
+
+As OTP memory frequently has low performance, BL1_2 is copied into RAM before it
+it is executed. It also copies the next image stage into RAM before
+authenticating it, which allows the next stage to be stored in untrusted flash.
+This requires that the device have sufficient RAM to contain both the BL1_2
+image and the next stage image at the same time. Note that this is done even if
+BL1_2 is located in XIP-capable flash, as it both allows the use of untrusted
+flash and simplifies the image upgrade logic.
+
+.. Note::
+ BL1_2 enables TF-M to be used on devices that contain no secure flash, though
+ the ITS service will not be available. Other services that depend on ITS will
+ not be available without modification.
+
+*************************************
+Secure boot / Image upgrade mechanism
+*************************************
+
+BL1_2 verifies the authenticity of the next stage image via asymmetric
+cryptography, using a public key that is provisioned into OTP.
+
+BL1_2 implements a rollback protection counter in OTP, which is used to prevent
+the next stage image being downgraded to a less secure version.
+
+BL1_2 has two image slots, which allows image upgrades to be performed. The
+primary slot is always booted first, and then if verification of this fails
+(either due to an invalid signature or due to a version lower than the rollback
+protection counter) the secondary slot is then booted (subject to the same
+checks).
+
+BL1_2 contains no image upgrade logic, in order for OTA of the next stage image
+to be implemented, a later stage in the system must handle downloading new
+images and placing them in the required slot.
+
+********************************************
+Post-Quantum signature verification in BL1_2
+********************************************
+
+BL1_2 uses a post-quantum asymmetric signature scheme to verify the next stage.
+The scheme used is Leighton-Michaeli Signatures (henceforth LMS). LMS is
+standardised in `NIST SP800-208
+<https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-208.pdf>`_
+and `IETF RFC8554. <https://datatracker.ietf.org/doc/html/rfc8554>`_
+
+LMS is a stateful-hash signature scheme, meaning that:
+
+ 1) It is constructed from a cryptographic hash function, in this case SHA256.
+
+ - This function can be accelerated by existing hardware accelerators, which
+ can make LMS verification relatively fast compared to other post-quantum
+ signature schemes that cannot be accelerated in hardware yet.
+
+ 2) Each private key can only be used to sign a certain number of images.
+
+ - BL1_2 uses the SHA256_H10 parameter set, meaning each key can sign 1024
+ images.
+
+The main downside, the limited amount of possible signatures, can be mitigated
+by limiting the amount of image upgrades that are done. As BL2 is often
+currently not upgradable, it is not anticipated that this limit will be
+problematic. If BL1 is being used to directly boot a TF-M/NS combined image, the
+limit is more likely to be problematic, and care should be taken to examine the
+likely update amount.
+
+LMS public keys are 32 bytes in size, and LMS signatures are 1912 bytes in size.
+The signature size is larger than some asymmetric schemes, though most devices
+should have enough space in flash to accommodate this.
+
+The main upside of LMS, aside from the security against attacks involving
+quantum computers, is that it is relatively simple to implement. The software
+implementation that is used by BL1 is ~3KiB in size, which is considerably
+smaller than the corresponding RSA implementation which is at least 6.5K. This
+simplicity of implementation is useful to avoid bugs.
+
+BL1 will use MbedTLS as the source for its implementation of LMS.
+
+.. Note::
+ As of the time of writing, the LMS code is still in the process of being
+ merged into MbedTLS, so BL1 currently does not support asymmetric
+ verification of the next boot stage. Currently, the next boot stage is
+ hash-locked, so cannot be upgraded.
+
+ The Github pull request for LMS can be found `here
+ <https://github.com/ARMmbed/mbedtls/pull/4826>`_
+
+*********************
+BL1 boot measurements
+*********************
+
+BL1 outputs boot measurements in the same format as BL2, utilising the same
+shared memory area. These measurements can then be included in the attestation
+token, allowing the attestation of the version of the boot stage after BL1.
+
+***********
+BL1 tooling
+***********
+
+Image signing scripts are provided for BL1_1 and BL1_2. While the script is
+named ``create_bl2_img.py``, it can be used for any next stage image.
+
+- ``bl1/bl1_1/scripts/create_bl1_2_img.py``
+- ``bl1/bl1_2/scripts/create_bl2_img.py``
+
+These sign (and encrypt in the case of ``create_bl2_img.py``) a given image file
+and append the required headers.
+
+**************************
+BL1 FI and DPA mitigations
+**************************
+
+BL1 reuses the FI countermeasures used in the TF-M runtime, which are found in
+``lib/fih/``.
+
+BL1 implements countermeasures against DPA, which are primarily targeted
+towards being able to handle cryptographic material without leaking its
+contents. The functions with these countermeasures are found in
+``bl1/bl1_1/shared_lib/util.c``
+
+``bl_secure_memeql`` tests if memory regions have the same value
+
+- It does not perform early exits to prevent timing attacks.
+- It compares chunks in random orders to prevent DPA trace correlation analysis
+- It inserts random delays to prevent DPA trace correlation analysis
+- It performs loop integrity checks
+- It uses FIH constructs
+
+``bl_secure_memcpy`` copies memory regions
+
+- It copies chunks in random orders to prevent DPA trace correlation analysis
+- It inserts random delays to prevent DPA trace correlation analysis
+- It performs loop integrity checks
+- It uses FIH constructs
+
+**************************
+Using BL1 on new platforms
+**************************
+
+New platforms must define the following macros in their ``region_defs.h``:
+
+- ``BL1_1_HEAP_SIZE``
+- ``BL1_1_STACK_SIZE``
+- ``BL1_2_HEAP_SIZE``
+- ``BL1_2_STACK_SIZE``
+- ``BL1_1_CODE_START``
+- ``BL1_1_CODE_LIMIT``
+- ``BL1_1_CODE_SIZE``
+- ``BL1_2_CODE_START``
+- ``BL1_2_CODE_LIMIT``
+- ``BL1_2_CODE_SIZE``
+- ``PROVISIONING_DATA_START``
+- ``PROVISIONING_DATA_LIMIT``
+- ``PROVISIONING_DATA_SIZE``
+
+The ``PROVISIONING_DATA_*`` defines are used to locate where the data to be
+provisioned into OTP can be found. These are required as the provisioning bundle
+needs to contain the entire BL1_2 image, usually >= 8KiB in size, which is too
+large to be placed in the static data area as is done for all other dummy
+provisioning data. On development platforms with reprogrammable ROM, this is
+often placed in unused ROM. On production platforms, this should be located in
+RAM and then filled with provisioning data. The format of the provisioning data
+that should be located in the ``PROVISIONING_DATA_*`` region can be found in
+``bl1/bl1_1/lib/provisioning.c`` in the struct
+``bl1_assembly_and_test_provisioning_data_t``
+
+If the platform is storing BL1_2 in flash, it must set
+``BL1_2_IMAGE_FLASH_OFFSET`` to the flash offset of the start of BL1_2.
+
+The platform must also implement the HAL functions defined in the following
+headers:
+
+- ``bl1/bl1_1/shared_lib/interface/trng.h``
+- ``bl1/bl1_1/shared_lib/interface/crypto.h``
+- ``bl1/bl1_1/shared_lib/interface/otp.h``
+
+If the platform integrates a CryptoCell-312, then it can reuse the existing
+implementation.
+
+***********
+BL1 Testing
+***********
+
+New tests have been written to test both the HAL implementation, and the
+integration of those functions for verifying images. These tests are stored in
+the ``tf-m-tests`` repository, under the ``test/bl1/`` directory, and further
+subdivided into BL1_1 and BL1_2 tests.
+
+--------------
+
+*Copyright (c) 2022, Arm Limited. All rights reserved.*
diff --git a/docs/design_docs/code_sharing.rst b/docs/design_docs/code_sharing.rst
new file mode 100644
index 0000000..5f11bb5
--- /dev/null
+++ b/docs/design_docs/code_sharing.rst
@@ -0,0 +1,367 @@
+######################################################
+Code sharing between independently linked XIP binaries
+######################################################
+
+:Author: Tamas Ban
+:Organization: Arm Limited
+:Contact: tamas.ban@arm.com
+
+**********
+Motivation
+**********
+Cortex-M devices are usually constrained in terms of flash and RAM. Therefore,
+it is often challenging to fit bigger projects in the available memory. The PSA
+specifications require a device to both have a secure boot process in place at
+device boot-up time, and to have a partition in the SPE which provides
+cryptographic services at runtime. These two entities have some overlapping
+functionality. Some cryptographic primitives (e.g. hash calculation and digital
+signature verification) are required both in the bootloader and the runtime
+environment. In the current TF-M code base, both firmware components use the
+mbed-crypto library to implement these requirements. During the build process,
+the mbed-crpyto library is built twice, with different configurations (the
+bootloader requires less functionality) and then linked to the corresponding
+firmware component. As a result of this workflow, the same code is placed in the
+flash twice. For example, the code for the SHA-256 algorithm is included in
+MCUboot, but the exact same code is duplicated in the SPE cryptography
+partition. In most cases, there is no memory isolation between the bootloader
+and the SPE, because both are part of the PRoT code and run in the secure
+domain. So, in theory, the code of the common cryptographic algorithms could be
+reused among these firmware components. This could result in a big reduction in
+code footprint, because the cryptographic algorithms are usually flash hungry.
+Code size reduction can be a good opportunity for very constrained devices,
+which might need to use TF-M Profile Small anyway.
+
+*******************
+Technical challenge
+*******************
+Code sharing in a regular OS environment is easily achievable with dynamically
+linked libraries. However, this is not the case in Cortex-M systems where
+applications might run bare-metal, or on top of an RTOS, which usually lacks
+dynamic loading functionality. One major challenge to be solved in the Cortex-M
+space is how to share code between independently linked XIP applications that
+are tied to a certain memory address range to be executable and have absolute
+function and global data memory addresses. In this case, the code is not
+relocatable, and in most cases, there is no loader functionality in the system
+that can perform code relocation. Also, the lack of an MMU makes the address
+space flat, constant and not reconfigurable at runtime by privileged code.
+
+One other difficulty is that the bootloader and the runtime use the same RAM
+area during execution. The runtime firmware is executed strictly after the
+bootloader, so normally, it can reuse the whole secure RAM area, as it would be
+the exclusive user. No attention needs to be paid as to where global data is
+placed by the linker. The bootloader does not need to retain its state. The low
+level startup of the runtime firmware can freely overwrite the RAM with its data
+without corrupting bootloader functionality. However, with code sharing between
+bootloader and runtime firmware, these statements are no longer true. Global
+variables used by the shared code must either retain their value or must be
+reinitialised during low level startup of the runtime firmware. The startup code
+is not allowed to overwrite the shared global variables with arbitrary data. The
+following design proposal provides a solution to these challenges.
+
+**************
+Design concept
+**************
+The bootloader is sometimes implemented as ROM code (BL1) or stored in a region
+of the flash which is lockable, to prevent tampering. In a secure system, the
+bootloader is immutable code and thus implements a part of the Root of Trust
+anchor in the device, which is trusted implicitly. The shared code is primarily
+part of the bootloader, and is reused by the runtime SPE firmware at a later
+stage. Not all of the bootloader code is reused by the runtime SPE, only some
+cryptographic functions.
+
+Simplified steps of building with code sharing enabled:
+
+ - Complete the bootloader build process to have a final image that contains
+ the absolute addresses of the shared functions, and the global variables
+ used by these functions.
+ - Extract the addresses of the functions and related global variables that are
+ intended to be shared from the bootloader executable.
+ - When building runtime firmware, provide the absolute addresses of the shared
+ symbols to the linker, so that it can pick them up, instead of instantiating
+ them again.
+
+The execution flow looks like this:
+
+.. code-block:: bash
+
+ SPE MCUboot func1() MCUboot func2() MCUboot func3()
+ |
+ | Hash()
+ |------------->|
+ |----------------->|
+ |
+ Return |
+ Return |<-----------------|
+ |<-------------|
+ |
+ |
+ |----------------------------------------------------->|
+ |
+ Function pointer in shared global data() |
+ |<-----------------------------------------------------|
+ |
+ | Return
+ |----------------------------------------------------->|
+ |
+ Return |
+ |<-----------------------------------------------------|
+ |
+ |
+
+The execution flow usually returns from a shared function back to the SPE with
+an ordinary function return. So usually, once a shared function is called in the
+call path, all further functions in the call chain will be shared as well.
+However, this is not always the case, as it is possible for a shared function to
+call a non-shared function in SPE code through a global function pointer.
+
+For shared global variables, a dedicated data section must be allocated in the
+linker configuration file. This area must have the same memory address in both
+MCUboot's and the SPE's linker files, to ensure the integrity of the variables.
+For simplicity's sake, this section is placed at the very beginning of the RAM
+area. Also, the RAM wiping functionality at the end of the secure boot flow
+(that is intended to remove any possible secrets from the RAM) must not clear
+this area. Furthermore, it must be ensured that the linker places shared globals
+into this data section. There are two way to achieve this:
+
+ - Put a filter pattern in the section body that matches the shared global
+ variables.
+ - Mark the global variables in the source code with special attribute
+ `__attribute__((section(<NAME_OF_SHARED_SYMBOL_SECTION>)))`
+
+RAM memory layout in MCUboot with code sharing enabled:
+
+.. code-block:: bash
+
+ +------------------+
+ | Shared symbols |
+ +------------------+
+ | Shared boot data |
+ +------------------+
+ | Data |
+ +------------------+
+ | Stack (MSP) |
+ +------------------+
+ | Heap |
+ +------------------+
+
+RAM memory layout in SPE with code sharing enabled:
+
+.. code-block:: bash
+
+ +-------------------+
+ | Shared symbols |
+ +-------------------+
+ | Shared boot data |
+ +-------------------+
+ | Stack (MSP) |
+ +-------------------+
+ | Stack (PSP) |
+ +-------------------+
+ | Partition X Data |
+ +-------------------+
+ | Partition X Stack |
+ +-------------------+
+ .
+ .
+ .
+ +-------------------+
+ | Partition Z Data |
+ +-------------------+
+ | Partition Z Stack |
+ +-------------------+
+ | PRoT Data |
+ +-------------------+
+ | Heap |
+ +-------------------+
+
+Patching mbedTLS
+================
+In order to share some global function pointers from mbed-crypto that are
+related to dynamic memory allocation, their scope must be extended from private
+to global. This is needed because some compiler toolchain only extract the
+addresses of public functions and global variables, and extraction of addresses
+is a requirement to share them among binaries. Therefore, a short patch was
+created for the mbed-crypto library, which "globalises" these function pointers:
+
+`lib/ext/mbedcrypto/0002-Enable-crypto-code-sharing-between-independent-binar.patch`
+
+The patch need to manually applied in the mbedtls repo, if code sharing is
+enabled. The patch has no effect on the functional behaviour of the
+cryptographic library, it only extends the scope of some variables.
+
+*************
+Tools support
+*************
+All the currently supported compilers provide a way to achieve the above
+objectives. However, there is no standard way, which means that the code sharing
+functionality must be implemented on a per compiler basis. The following steps
+are needed:
+
+ - Extraction of the addresses of all global symbols.
+ - The filtering out of the addresses of symbols that aren't shared. The goal is
+ to not need to list all the shared symbols by name. Only a simple pattern
+ has to be provided, which matches the beginning of the symbol's name.
+ Matching symbols will be shared. Examples are in :
+ `bl2/shared_symbol_template.txt`
+ - Provision of the addresses of shared symbols to the linker during the SPE
+ build process.
+ - The resolution of symbol collisions during SPE linking. Because mbed-crypto
+ is linked to both firmware components as a static library, the external
+ shared symbols will conflict with the same symbols found within it. In order
+ to prioritize the external symbol, the symbol with the same name in
+ mbed-crypto must be marked as weak in the symbol table.
+
+The above functionalities are implemented in the toolchain specific CMake files:
+
+ - `toolchain_ARMCLANG.cmake`
+ - `toolchain_GNUARM.cmake`
+
+By the following two functions:
+
+ - `target_share_symbols()`: Extract and filter shared symbol addresses
+ from MCUboot.
+ - `target_link_shared_code()`: Link shared code to the SPE and resolve symbol
+ conflict issues.
+
+ARMCLANG
+========
+The toolchain specific steps are:
+
+ - Extract all symbols from MCUboot: add `-symdefs` to the compiler command line
+ - Filter shared symbols: call CMake script `FilterSharedSymbols.cmake`
+ - Weaken duplicated (shared) symbols in the mbed-crypto static library that are
+ linked to the SPE: `arm-none-eabi-objcopy`
+ - Link shared code to SPE: Add the filtered output of `-symdefs` to the SPE
+ source file list.
+
+GNUARM
+======
+The toolchain specific steps are:
+
+ - Extract all symbols from MCUboot: `arm-none-eabi-nm`
+ - Filter shared symbols: call CMake script: `FilterSharedSymbols.cmake`
+ - Strip unshared code from MCUboot: `arm-none-eabi-strip`
+ - Weaken duplicated (shared) symbols in the mbed-crypto static library that are
+ linked to the SPE: `arm-none-eabi-objcopy`
+ - Link shared code to SPE: Add `-Wl -R <SHARED_STRIPPED_CODE.axf>` to the
+ compiler command line
+
+IAR
+===
+Functionality currently not implemented, but the toolchain supports doing it.
+
+**************************
+Memory footprint reduction
+**************************
+Build type: MinSizeRel
+Platform: mps2/an521
+Version: TF-Mv1.2.0 + code sharing patches
+MCUboot image encryption support is disabled.
+
++------------------+-------------------+-------------------+-------------------+
+| | ConfigDefault | ConfigProfile-M | ConfigProfile-S |
++------------------+----------+--------+----------+--------+----------+--------+
+| | ARMCLANG | GNUARM | ARMCLANG | GNUARM | ARMCLANG | GNUARM |
++------------------+----------+--------+----------+--------+----------+--------+
+| CODE_SHARING=OFF | 122268 | 124572 | 75936 | 75996 | 50336 | 50224 |
++------------------+----------+--------+----------+--------+----------+--------+
+| CODE_SHARING=ON | 113264 | 115500 | 70400 | 70336 | 48840 | 48988 |
++------------------+----------+--------+----------+--------+----------+--------+
+| Difference | 9004 | 9072 | 5536 | 5660 | 1496 | 1236 |
++------------------+----------+--------+----------+--------+----------+--------+
+
+If MCUboot image encryption support is enabled then saving could be up to
+~13-15KB.
+
+.. Note::
+
+ Code sharing on Musca-B1 was tested only with SW only crypto, so crypto
+ hardware acceleration must be turned off: -DCRYPTO_HW_ACCELERATOR=OFF
+
+
+*************************
+Useability considerations
+*************************
+Functions that only use local variables can be shared easily. However, functions
+that rely on global variables are a bit tricky. They can still be shared, but
+all global variables must be placed in the shared symbol section, to prevent
+overwriting and to enable the retention of their values.
+
+Some global variables might need to be reinitialised to their original values by
+runtime firmware, if they have been used by the bootloader, but need to have
+their original value when runtime firmware starts to use them. If so, the
+reinitialising functionality must be implemented explicitly, because the low
+level startup code in the SPE does not initialise the shared variables, which
+means they retain their value after MCUboot stops running.
+
+If a bug is discovered in the shared code, it cannot be fixed with a firmware
+upgrade, if the bootloader code is immutable. If this is the case, disabling
+code sharing might be a solution, as the new runtime firmware could contain the
+fixed code instead of relying on the unfixed shared code. However, this would
+increase code footprint.
+
+API backward compatibility also can be an issue. If the API has changed in newer
+version of the shared code. Then new code cannot rely on the shared version.
+The changed code and all the other shared code where it is referenced from must
+be ignored and the updated version of the functions must be compiled in the
+SPE binary. The mbedTLS library is API compatible with its current version
+(``v2.24.0``) since the ``mbedtls-2.7.0 release`` (2018-02-03).
+
+To minimise the risk of incompatibility, use the same compiler flags to build
+both firmware components.
+
+The artifacts of the shared code extraction steps must be preserved so as to
+remain available if new SPE firmware (that relies on shared code) is built and
+released. Those files are necessary to know the address of shared symbols when
+linking the SPE.
+
+************************
+How to use code sharing?
+************************
+Considering the above, code sharing is an optional feature, which is disabled
+by default. It can be enabled from the command line with a compile time switch:
+
+ - `TFM_CODE_SHARING`: Set to `ON` to enable code sharing.
+
+With the default settings, only the common part of the mbed-crypto library is
+shared, between MCUboot and the SPE. However, there might be other device
+specific code (e.g. device drivers) that could be shared. The shared
+cryptography code consists mainly of the SHA-256 algorithm, the `bignum` library
+and some RSA related functions. If image encryption support is enabled in
+MCUboot, then AES algorithms can be shared as well.
+
+Sharing code between the SPE and an external project is possible, even if
+MCUboot isn't used as the bootloader. For example, a custom bootloader can also
+be built in such a way as to create the necessary artifacts to share some of its
+code with the SPE. The same artifacts must be created like the case of MCUboot:
+
+ - `shared_symbols_name.txt`: Contains the name of the shared symbols. Used by
+ the script that prevents symbol collision.
+ - `shared_symbols_address.txt`: Contains the type, address and name of shared
+ symbols. Used by the linker when linking runtime SPE.
+ - `shared_code.axf`: GNUARM specific. The stripped version of the firmware
+ component, only contains the shared code. It is used by the linker when
+ linking the SPE.
+
+.. Note::
+
+ The artifacts of the shared code extraction steps must be preserved to be
+ able to link them to any future SPE version.
+
+When an external project is sharing code with the SPE, the `SHARED_CODE_PATH`
+compile time switch must be set to the path of the artifacts mentioned above.
+
+********************
+Further improvements
+********************
+This design focuses only on sharing the cryptography code. However, other code
+could be shared as well. Some possibilities:
+
+- Flash driver
+- Serial driver
+- Image metadata parsing code
+- etc.
+
+--------------
+
+*Copyright (c) 2020-2022, Arm Limited. All rights reserved.*
\ No newline at end of file
diff --git a/docs/design_docs/dual-cpu/booting_a_dual_core_system.rst b/docs/design_docs/dual-cpu/booting_a_dual_core_system.rst
new file mode 100644
index 0000000..1894b28
--- /dev/null
+++ b/docs/design_docs/dual-cpu/booting_a_dual_core_system.rst
@@ -0,0 +1,141 @@
+##########################
+Booting a Dual-Core System
+##########################
+
+:Author: Chris Brand
+:Organization: Cypress Semiconductor Corporation
+:Contact: chris.brand@cypress.com
+
+*******************
+System Architecture
+*******************
+There are many possibly ways to design a dual core system. Some important
+considerations from a boot perspective are:
+
+- Which core has access to which areas of Flash?
+
+ - It is possible that the secure core has no access to the Flash from which
+ the non-secure core will boot, in which case the non-secure core will
+ presumably have a separate root of trust and perform its own integrity
+ checks on boot.
+
+- How does the non-secure core behave on power-up? Is it held in reset,
+ does it jump to a set address, …?
+
+- What are the performance characteristics of the two core?
+
+ - There could be a great disparity in performance
+
+**********************
+TF-M Twin Core Booting
+**********************
+In an effort to make the problem manageable, as well as to provide a system
+with good performance, that is flexible enough to work for a variety of dual
+core systems, the following design decisions have been made:
+
+- TF-M will (for now) only support systems where the secure core has full
+ access to the Flash that the non-secure core will boot from
+
+ - This keeps the boot flow as close as possible to the single core design,
+ with the secure core responsible for maintaining the chain of trust for
+ the entire system, and for upgrade of the entire system
+
+- The secure code will make a platform-specific call immediately after setting
+ up hardware protection to (potentially) start the non-secure core running
+
+ - This is the earliest point at which it is safe to allow the non-secure
+ code to start running, so starting it here ensures system integrity while
+ also giving the non-secure code the maximum amount of time to perform its
+ initialization
+
+ - Note that this is after the bootloader has validated the non-secure image,
+ which is the other key part to maintain security
+
+ - This also means that only tfm_s and tfm_ns have to change, and not mcuboot
+
+- Both the secure and non-secure code will make platform-specific calls to
+ establish a synchronization point. This will be after both sides have done
+ any initialization that is required, including setting up inter-core
+ communications. On a single core system, this would be the point at which the
+ secure code jumps to the non-secure code, and at the very start of the
+ non-secure code.
+
+- After completing initialization on the secure core (at the point where on a
+ single core system, it would jump to the non-secure code), the main thread on
+ the secure core will be allowed to die
+
+ - The scheduler has been started at this point, and an idle thread exists.
+ Any additional work that is only required in the dual core case will be
+ interrupt-driven.
+
+ - All work related to the non-secure core will take place from a
+ ``ns_agent_mailbox`` partition, which will establish communication with
+ the non-secure core and then act on its behalf
+
+- Because both cores may be booting in parallel, executing different
+ initialization code, at different speeds, the design must be resilient if
+ either core attempts to communicate with the other before the latter is ready.
+ For example, the client (non-secure) side of the IPC mechanism must be able
+ to handle the situation where it has to wait for the server (secure) side to
+ finish setting up the IPC mechanism.
+
+ - This relates to the synchronization calls mentioned above. It means that
+ those calls cannot utilise the IPC mechanism, but must instead use some
+ platform-specific mechanism to establish this synchronization. This could
+ be as simple as setting aside a small area of shared memory and having
+ both sides set a “ready” flag, but may well also involve the use of
+ interrupts.
+
+ - This also means that the synchronization call must take place after the
+ IPC mechanism has been set up but before any attempt (by either side) to
+ use it.
+
+*************
+API Additions
+*************
+Three new HAL functions are required:
+
+.. code-block:: c
+
+ void tfm_hal_boot_ns_cpu(uintptr_t start_addr);
+
+- Called on the secure core from ``ns_agent_mailbox`` partition when it first
+ runs (after protections have been configured).
+
+- Performs the necessary actions to start the non-secure core running the code
+ at the specified address.
+
+.. code-block:: c
+
+ void tfm_hal_wait_for_ns_cpu_ready(void);
+
+- Called on the secure core from ``ns_agent_mailbox`` partition after making the
+ above call.
+
+- Flags that the secure core has completed its initialization, including setting
+ up the IPC mechanism.
+
+- Waits, if necessary, for the non-secure core to flag that it has completed its
+ initialisation
+
+.. code-block:: c
+
+ void tfm_ns_wait_for_s_cpu_ready(void);
+
+- Called on the non-secure core from ``main()`` after the dual-core-specific
+ initialization (on a single core system, this would be the start of the
+ non-secure code), before the first use of the IPC mechanism.
+
+- Flags that the non-secure side has completed its initialization.
+
+- Waits, if necessary, for the secure core to flag that it has completed its
+ initialization.
+
+For all three, an empty implementation will be provided with a weak symbol so
+that platforms only have to provide the new functions if they are required.
+
+---------------
+
+Copyright (c) 2019-2022 Cypress Semiconductor Corporation. All rights reserved.
+Copyright (c) 2021, Arm Limited. All rights reserved.
+
diff --git a/docs/design_docs/dual-cpu/communication_prototype_between_nspe_and_spe_in_dual_core_systems.rst b/docs/design_docs/dual-cpu/communication_prototype_between_nspe_and_spe_in_dual_core_systems.rst
new file mode 100644
index 0000000..62d02ba
--- /dev/null
+++ b/docs/design_docs/dual-cpu/communication_prototype_between_nspe_and_spe_in_dual_core_systems.rst
@@ -0,0 +1,708 @@
+################################################################
+Communication Prototype Between NSPE And SPE In Dual Core System
+################################################################
+
+:Author: David Hu
+:Organization: Arm Limited
+:Contact: david.hu@arm.com
+
+************
+Introduction
+************
+
+This document proposes a generic prototype of the communication between NSPE
+(Non-secure Processing Environment) and SPE (Secure Processing Environment) in
+TF-M on a dual core system.
+
+The dual core system should satisfy the following requirements
+
+- NSPE and SPE are properly isolated and protected following PSA
+- An Arm M-profile core locates in SPE and acts as the Secure core
+- An Inter-Processor Communication hardware module in system for communication
+ between NSPE core and SPE core
+- TF-M runs on the Secure core with platform specific drivers support.
+
+Scope
+=====
+
+This design document focuses on the dual core communication design inside TF-M.
+Some changes to TF-M core/Secure Partition Manager (SPM) are listed to support
+the dual core communication. This document only discuss about the implementation
+in TF-M Inter-Process Communication (IPC) model.
+The TF-M non-secure interface library depends on mailbox and NS RTOS
+implementation. The related changes to TF-M non-secure interface library are not
+discussed in detail in this document.
+
+Some requirements to mailbox functionalities are defined in this document. The
+detailed mailbox design or implementations is not specified in this document.
+Please refer to mailbox dedicate document [1]_.
+
+Organization of the document
+============================
+
+- `Overall workflow in dual core communication`_ provides an overall workflow of
+ dual core communication between NSPE and SPE.
+- `Requirements on mailbox communication`_ lists general requirements of
+ mailbox, from the perspective of dual core communication.
+- `PSA client call handling flow in TF-M`_ discusses about the detailed sequence
+ and key modules of handling PSA client call in TF-M.
+- `Summary of changes to TF-M core/SPM`_ summarizes the potential changes to
+ TF-M core/SPM to support dual core communication.
+
+*******************************************
+Overall workflow in dual core communication
+*******************************************
+
+The overall workflow in dual-core scenario can be described as follows
+
+1. Non-secure application calls TF-M non-secure interface library to request
+ Secure service. The TF-M non-secure interface library translates the Secure
+ service into PSA Client calls.
+2. TF-M non-secure interface library notifies TF-M of the PSA client call
+ request, via mailbox. Proper generic mailbox APIs in HAL should be defined
+ so that TF-M non-secure interface library can co-work with diverse platform
+ specific Inter-Processor Communication implementations.
+3. Inter-Processor Communication interrupt handler and mailbox handling in TF-M
+ deal with the inbound mailbox event(s) and deliver the PSA client call
+ request to TF-M SPM.
+4. TF-M SPM processes the PSA client call request. The PSA client call is
+ eventually handled in target Secure Partition or corresponding handler.
+5. After the PSA Client call is completed, the return value is returned to NSPE
+ via mailbox.
+6. TF-M non-secure interface library fetches return value from mailbox.
+7. The return value is returned to non-secure application.
+
+The interfaces between NSPE app and TF-M NSPE interface library are unchanged
+so the underlying platform specific details are transparent to NSPE
+application.
+
+Step 3 ~ step 5 are covered in `PSA client call handling flow in TF-M`_ in
+detail.
+
+*************************************
+Requirements on mailbox communication
+*************************************
+
+The communication between NSPE and SPE relies on mailbox communication
+implementation. The mailbox functionalities are eventually implemented by
+platform specific Inter-Processor Communication drivers.
+This section lists some general requirements on mailbox communication between
+NSPE and SPE.
+
+Data transferred between NPSE and SPE
+=====================================
+
+A mailbox message should contain the information and parameters of a PSA client
+call. After SPE is notified by a mailbox event, SPE fetches the parameters from
+NSPE for PSA Client call processing.
+The mailbox design document [1]_ defines the structure of the mailbox message.
+
+The information and parameters of PSA Client call in the mailbox message include
+
+- PSA Client API
+
+- Parameters required in PSA Client call. The parameters can include the
+ following, according to PSA client call type
+
+ - Service ID (SID)
+ - Handle
+ - Request type
+ - Input vectors and the lengths
+ - Output vectors and the lengths
+ - Requested version of secure service
+
+- NSPE Client ID. Optional. The NSPE Client ID is required when NSPE RTOS
+ enforces non-secure task isolation.
+
+The mailbox implementation may define additional members in mailbox message to
+accomplish mailbox communication between NSPE and SPE.
+
+When the PSA Client call is completed in TF-M, the return result, such as
+PSA_SUCCESS or a handle, should be returned from SPE to NSPE via mailbox.
+
+Mailbox synchronization between NSPE and SPE
+============================================
+
+Synchronization and protection between NSPE and SPE accesses to shared mailbox
+objects and variables should be implemented.
+
+When a core accesses shared mailbox objects or variables, proper mechanisms
+should protect concurrent operations from the other core.
+
+Support of multiple ongoing NS PSA client calls (informative)
+=============================================================
+
+If the support of multiple ongoing NS PSA client calls in TF-M is required
+in dual-core systems, an optional queue can be maintained in TF-M core to store
+multiple mailbox objects received from NSPE.
+To identify NS PSA client calls, additional fields can be added in TF-M SPM
+objects to store the NS PSA Client request identification.
+
+Note that when just a single outstanding PSA client call is allowed, multiple
+NSPE OS threads can run concurrently and call PSA client functions. The first
+PSA client call will be processed first, and any other OS threads will be
+blocked from submitting PSA client calls until the first is completed.
+
+*************************************
+PSA client call handling flow in TF-M
+*************************************
+
+This section provides more details about the flow of PSA client call handing in
+TF-M.
+
+The sequence of handling PSA Client call request in TF-M is listed as below
+
+1. Platform specific Inter-Processor Communication interrupt handler is
+ triggered after the mailbox event is asserted by NSPE. The interrupt handler
+ should call ``spm_handle_interrupt()``
+2. SPM will send a ``SIGNAL_MAILBOX`` to ``ns_agent_mailbox`` partition
+3. ``ns_agent_mailbox`` partition deals with the mailbox message(s) which
+ contain(s) the PSA client call information and parameters.
+ Then the PSA client call request is dispatched to dedicated PSA client call
+ handler in TF-M SPM.
+4. After the PSA client call is completed, the return value is transmitted to
+ NSPE via mailbox.
+
+Several key modules in the whole process are covered in detail in following
+sections.
+
+- `Inter-Processor Communication interrupt handler`_ discusses about the
+ Inter-Processor Communication interrupt handler
+- `TF-M Remote Procedure Call (RPC) layer`_ introduces TF-M Remote Procedure
+ Call layer to support dual-core communication.
+- `ns_agent_mailbox partition`_ describes the mailbox agent partition.
+- `Return value replying routine in TF-M`_ proposes the routine to reply the
+ return value to NSPE.
+
+Inter-Processor Communication interrupt handler
+===============================================
+
+Platform specific driver should implement the Inter-Processor Communication
+interrupt handler to deal with the Inter-Processor Communication interrupt
+asserted by NSPE.
+The platform specific interrupt handler should complete the interrupt
+operations, such as interrupt EOI or acknowledge.
+
+The interrupt handler should call ``spm_handle_interrupt()`` to notify SPM of
+the interrupt.
+
+The platform's ``region_defs.h`` file should define a macro ``MAILBOX_IRQ`` that
+identifies the interrupt being used. The platform must also provide a function
+``mailbox_irq_init()`` that initialises the interrupt as described in [2]_.
+
+Platform specific driver should put Inter-Processor Communication interrupt into
+a proper exception priority, according to system and application requirements.
+The proper priority setting should guarantee that
+
+- TF-M can respond to a PSA client call request in time according to system and
+ application requirements.
+- Other exceptions, which are more latency sensitive or require higher
+ priorities, are not blocked by Inter-Processor Communication interrupt ISR.
+
+The exception priority setting is IMPLEMENTATION DEFINED.
+
+TF-M Remote Procedure Call (RPC) layer
+======================================
+
+This design brings up a concept of Remote Procedure Call layer in TF-M.
+
+The RPC layer sits between TF-M SPM and mailbox implementation. The purpose of
+RPC layer is to decouple mailbox implementation and TF-M SPM and enhance the
+generality of entire dual-core communication.
+
+The RPC layer provides a set of APIs to TF-M SPM to handle and reply PSA client
+call from NSPE in dual-core scenario. Please refer to
+`TF-M RPC definitions to TF-M SPM`_ for API details.
+It hides the details of specific mailbox implementation from TF-M SPM. It avoids
+modifying TF-M SPM to fit mailbox development and changes.
+It can keep a unified PSA client call process in TF-M SPM in both single
+Armv8-M scenario and dual core scenario.
+
+The RPC layer defines a set callback functions for mailbox implementation to
+hook its specific mailbox operations. When TF-M SPM invokes RPC APIs to deal
+with NSPE PSA client call, RPC layer eventually calls the callbacks to execute
+mailbox operations.
+RPC layer also defines a set of PSA client call handler APIs for mailbox
+implementation. RPC specific client call handlers parse the PSA client call
+parameters and invoke common TF-M PSA client call handlers. Please refer to
+`TF-M RPC definitions for mailbox`_ for the details.
+
+ns_agent_mailbox partition
+==========================
+
+A partition will be dedicated to interacting with the NSPE through the mailbox.
+This partition will call ``tfm_hal_boot_ns_cpu()`` and
+tfm_hal_wait_for_ns_cpu_ready() to ensure that the non-secure core is running.
+It will then initialise the SPE mailbox and enable the IPC interrupt. Once these
+tasks are complete, it will enter an infinite loop waiting for a MAILBOX_SIGNAL
+signal indicating that a mailbox message has arrived.
+
+Mailbox handling will be done in the context of the ``ns_agent_mailbox``
+partition, which will make any necessary calls to other partitions on behalf of
+the non-secure code.
+
+``ns_agent_mailbox`` should call RPC API ``tfm_rpc_client_call_handler()`` to
+check and handle PSA client call request from NSPE.
+``tfm_rpc_client_call_handler()`` invokes request handling callback function to
+eventually execute specific mailbox message handling operations. The mailbox
+APIs are defined in mailbox design document [1]_.
+
+The handling process in mailbox operation consists of the following steps.
+
+1. SPE mailbox fetches the PSA client call parameters from NSPE mailbox.
+ Proper protection and synchronization should be implemented in mailbox to
+ guarantee that the operations are not interfered by NSPE mailbox operations
+ or Inter-Processor Communication interrupt handler.
+ If a queue is maintained inside TF-M core, SPE mailbox can fetch multiple
+ PSA client calls together into the queue, to save the time of synchronization
+ between two cores.
+
+2. SPE mailbox parses the PSA client call parameters copied from NSPE, including
+ the PSA client call type.
+
+3. The PSA client call request is dispatched to the dedicated TF-M RPC PSA
+ client call handler. The PSA client call request is processed in the
+ corresponding handler.
+
+ - For ``psa_framework_version()`` and ``psa_version()``, the PSA client call
+ can be completed in the handlers ``tfm_rpc_psa_framework_version()`` and
+ ``tfm_rpc_psa_version()`` respectively.
+
+ - For ``psa_connect()``, ``psa_call()`` and ``psa_close()``, the handlers
+ ``tfm_rpc_psa_connect()``, ``tfm_rpc_psa_call()`` and
+ ``tfm_rpc_psa_close()`` create the PSA message and trigger target Secure
+ partition respectively. The target Secure partition will be woken up to
+ handle the PSA message.
+
+The dual-core scenario and single Armv8-M scenario in TF-M IPC implementation
+should share the same PSA client call routines inside TF-M SPM. The current
+handler definitions can be adjusted to be more generic for dual-core scenario
+and single Armv8-M implementation. Please refer to
+`Summary of changes to TF-M core/SPM`_ for details.
+
+If there are multiple NSPE PSA client call requests pending, SPE mailbox can
+process mailbox messages one by one.
+
+Return value replying routine in TF-M
+=====================================
+
+Diverse PSA client calls can be implemented with different return value replying
+routines.
+
+- `Replying routine for psa_framework_version() and psa_version()`_ describes
+ the routine for ``psa_framework_version()`` and ``psa_version()``.
+- `Replying routine for psa_connect(), psa_call() and psa_close()`_ describes
+ the routine for ``psa_connect()``, ``psa_call()`` and ``psa_close()``.
+
+Replying routine for psa_framework_version() and psa_version()
+--------------------------------------------------------------
+
+For ``psa_framework_version()`` and ``psa_version()``, the return value can be
+directly returned from the dedicated TF-M RPC PSA client call handlers.
+Therefore, the return value can be directly replied in mailbox handling process.
+
+A compile flag should be defined to enable replying routine via mailbox in
+dual-core scenario during building.
+
+Replying routine for psa_connect(), psa_call() and psa_close()
+--------------------------------------------------------------
+
+For ``psa_connect()``, ``psa_call()`` and ``psa_close()``, the PSA client call
+is completed in the target Secure Partition. The target Secure Partition calls
+``psa_reply()`` to reply the return value to TF-M SPM. In the SVC handler of
+``psa_reply()`` in TF-M SPM, TF-M SPM should call TF-M RPC API
+``tfm_rpc_client_call_reply()`` to return the value to NSPE via mailbox.
+``tfm_rpc_client_call_reply()`` invokes reply callbacks to execute specific
+mailbox reply operations. The mailbox reply functions must not trigger context
+switch inside SVC handler.
+
+If an error occurs in the handlers, the TF-M RPC handlers,
+``tfm_rpc_psa_call()``, ``tfm_rpc_psa_connect()`` and ``tfm_rpc_psa_close()``,
+may terminate and return the error, without triggering the target Secure
+Partition. The mailbox implementation should return the error code to NSPE.
+
+***********************************
+Summary of changes to TF-M core/SPM
+***********************************
+
+This section discusses the general changes related to NSPE and SPE
+communication to current TF-M core/SPM implementations.
+
+The detailed mailbox implementations are not covered in this section. Please
+refer to mailbox dedicated document [1]_.
+The platform specific implementations are also not covered in this section,
+including the Inter-Processor Communication interrupt or its interrupt handler.
+
+Common PSA client call handlers
+===============================
+
+Common PSA client call handlers should be extracted from current PSA client
+call handlers implementation in TF-M.
+Common PSA client call handlers are shared by both TF-M RPC layer in dual-core
+scenario and SVCall handlers in single Armv8-M scenario.
+
+TF-M RPC layer
+==============
+
+This section describes the TF-M RPC data types and APIs.
+
+- `TF-M RPC definitions to TF-M SPM`_ lists the data types and APIs to be
+ invoked by TF-M SPM.
+- `TF-M RPC definitions for mailbox`_ lists the data types and APIs to be
+ referred by mailbox implementation
+
+TF-M RPC definitions to TF-M SPM
+--------------------------------
+
+TFM_RPC_SUCCESS
+^^^^^^^^^^^^^^^
+
+``TFM_RPC_SUCCESS`` is a general return value to indicate that the RPC operation
+succeeds.
+
+.. code-block:: c
+
+ #define TFM_RPC_SUCCESS (0)
+
+TFM_RPC_INVAL_PARAM
+^^^^^^^^^^^^^^^^^^^
+
+``TFM_RPC_INVAL_PARAM`` is a return value to indicate that the input parameters
+are invalid.
+
+.. code-block:: c
+
+ #define TFM_RPC_INVAL_PARAM (INT32_MIN + 1)
+
+TFM_RPC_CONFLICT_CALLBACK
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Currently one and only one mailbox implementation is supported in dual core
+communication. This flag indicates that callback functions from one mailbox
+implementation are already registered and no more implementations are accepted.
+
+.. code-block:: c
+
+ #define TFM_RPC_CONFLICT_CALLBACK (INT32_MIN + 2)
+
+``tfm_rpc_client_call_handler()``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+TF-M PendSV handler calls this function to handle NSPE PSA client call request.
+
+.. code-block:: c
+
+ void tfm_rpc_client_call_handler(void);
+
+**Usage**
+
+``tfm_rpc_client_call_handler()`` invokes callback function ``handle_req()`` to
+execute specific mailbox handling.
+Please note that ``tfm_rpc_client_call_handler()`` doesn't return the status of
+underlying mailbox handling.
+
+``tfm_rpc_client_call_reply()``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+TF-M ``psa_reply()`` handler calls this function to reply PSA client call return
+result to NSPE.
+
+.. code-block:: c
+
+ void tfm_rpc_client_call_reply(const void *owner, int32_t ret);
+
+**Parameters**
+
++-----------+--------------------------------------------------------------+
+| ``owner`` | A handle to identify the owner of the PSA client call return |
+| | value. |
++-----------+--------------------------------------------------------------+
+| ``ret`` | PSA client call return result value. |
++-----------+--------------------------------------------------------------+
+
+**Usage**
+
+``tfm_rpc_client_call_reply()`` invokes callback function ``reply()`` to execute
+specific mailbox reply.
+Please note that ``tfm_rpc_client_call_reply()`` doesn't return the status of
+underlying mailbox reply process.
+
+``tfm_rpc_set_caller_data()``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This function sets the private data of the NS caller in TF-M message to identify
+the caller after PSA client call is completed.
+
+.. code-block:: c
+
+ void tfm_rpc_set_caller_data(struct conn_handle_t *handle, int32_t client_id);
+
+**Parameters**
+
++---------------+--------------------------------------------------------------+
+| ``handle`` | The connection handle to be set with NS caller private data. |
++---------------+--------------------------------------------------------------+
+| ``client_id`` | The client ID of the NS caller. |
++---------------+--------------------------------------------------------------+
+
+**Usage**
+
+``tfm_rpc_set_caller_data()`` invokes callback function ``get_caller_data()`` to
+fetch the private data of caller of PSA client call and set it into TF-M message
+structure.
+
+TF-M RPC definitions for mailbox
+--------------------------------
+
+PSA client call parameters
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This data structure holds the parameters used in a PSA client call. The
+parameters are passed from non-secure core to secure core via mailbox.
+
+.. code-block:: c
+
+ struct client_call_params_t {
+ uint32_t sid;
+ psa_handle_t handle;
+ int32_t type;
+ const psa_invec *in_vec;
+ size_t in_len;
+ psa_outvec *out_vec;
+ size_t out_len;
+ uint32_t version;
+ };
+
+Mailbox operations callbacks
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This structures contains the callback functions for specific mailbox operations.
+
+.. code-block:: c
+
+ struct tfm_rpc_ops_t {
+ void (*handle_req)(void);
+ void (*reply)(const void *owner, int32_t ret);
+ const void * (*get_caller_data)(int32_t client_id);
+ };
+
+``tfm_rpc_register_ops()``
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This function registers underlying mailbox operations into TF-M RPC callbacks.
+
+.. code-block:: c
+
+ int32_t tfm_rpc_register_ops(const struct tfm_rpc_ops_t *ops_ptr);
+
+**Parameters**
+
++-------------+----------------------------------------------+
+| ``ops_ptr`` | Pointer to the specific operation structure. |
++-------------+----------------------------------------------+
+
+**Return**
+
++----------------------+-----------------------------------------+
+| ``TFM_RPC_SUCCESS`` | Operations are successfully registered. |
++----------------------+-----------------------------------------+
+| ``Other error code`` | Fail to register operations. |
++----------------------+-----------------------------------------+
+
+**Usage**
+
+Mailbox should register TF-M RPC callbacks during mailbox initialization, before
+enabling secure services for NSPE.
+
+Currently one and only one underlying mailbox communication implementation is
+allowed in runtime.
+
+``tfm_rpc_unregister_ops()``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This function unregisters underlying mailbox operations from TF-M RPC callbacks.
+
+.. code-block:: c
+
+ void tfm_rpc_unregister_ops(void);
+
+**Usage**
+
+Currently one and only one underlying mailbox communication implementation is
+allowed in runtime.
+
+``tfm_rpc_psa_framework_version()``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+TF-M RPC handler for psa_framework_version().
+
+.. code-block:: c
+
+ uint32_t tfm_rpc_psa_framework_version(void);
+
+**Return**
+
++-------------+---------------------------------------------------------+
+| ``version`` | The version of the PSA Framework implementation that is |
+| | providing the runtime services. |
++-------------+---------------------------------------------------------+
+
+**Usage**
+
+``tfm_rpc_psa_framework_version()`` invokes common ``psa_framework_version()``
+handler in TF-M.
+
+``tfm_rpc_psa_version()``
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+TF-M RPC handler for psa_version().
+
+.. code-block:: c
+
+ uint32_t tfm_rpc_psa_version(const struct client_call_params_t *params,
+ bool ns_caller);
+
+**Parameters**
+
++---------------+-----------------------------------+
+| ``params`` | Base address of parameters. |
++---------------+-----------------------------------+
+| ``ns_caller`` | Whether the caller is non-secure. |
++---------------+-----------------------------------+
+
+**Return**
+
++----------------------+------------------------------------------------------+
+| ``PSA_VERSION_NONE`` | The RoT Service is not implemented, or the caller is |
+| | not permitted to access the service. |
++----------------------+------------------------------------------------------+
+| ``> 0`` | The minor version of the implemented RoT Service. |
++----------------------+------------------------------------------------------+
+
+**Usage**
+
+``tfm_rpc_psa_version()`` invokes common ``psa_version()`` handler in TF-M.
+The parameters in params should be prepared before calling
+``tfm_rpc_psa_version()``.
+
+``tfm_rpc_psa_connect()``
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+TF-M RPC handler for ``psa_connect()``.
+
+.. code-block:: c
+
+ psa_status_t tfm_rpc_psa_connect(const struct client_call_params_t *params,
+ bool ns_caller);
+
+**Parameters**
+
++---------------+-----------------------------------+
+| ``params`` | Base address of parameters. |
++---------------+-----------------------------------+
+| ``ns_caller`` | Whether the caller is non-secure. |
++---------------+-----------------------------------+
+
+**Return**
+
++-------------------------+---------------------------------------------------+
+| ``PSA_SUCCESS`` | Success. |
++-------------------------+---------------------------------------------------+
+| ``PSA_CONNECTION_BUSY`` | The SPM cannot make the connection at the moment. |
++-------------------------+---------------------------------------------------+
+| ``Does not return`` | The RoT Service ID and version are not supported, |
+| | or the caller is not permitted to access the |
+| | service. |
++-------------------------+---------------------------------------------------+
+
+**Usage**
+
+``tfm_rpc_psa_connect()`` invokes common ``psa_connect()`` handler in TF-M.
+The parameters in params should be prepared before calling
+``tfm_rpc_psa_connect()``.
+
+``tfm_rpc_psa_call()``
+^^^^^^^^^^^^^^^^^^^^^^
+
+TF-M RPC handler for ``psa_call()``.
+
+.. code-block:: c
+
+ psa_status_t tfm_rpc_psa_call(const struct client_call_params_t *params,
+ bool ns_caller);
+
+**Parameters**
+
++---------------+-----------------------------------+
+| ``params`` | Base address of parameters. |
++---------------+-----------------------------------+
+| ``ns_caller`` | Whether the caller is non-secure. |
++---------------+-----------------------------------+
+
+**Return**
+
++---------------------+---------------------------------------------+
+| ``PSA_SUCCESS`` | Success. |
++---------------------+---------------------------------------------+
+| ``Does not return`` | The call is invalid, or invalid parameters. |
++---------------------+---------------------------------------------+
+
+**Usage**
+
+``tfm_rpc_psa_call()`` invokes common ``psa_call()`` handler in TF-M.
+The parameters in params should be prepared before calling
+``tfm_rpc_psa_call()``.
+
+``tfm_rpc_psa_close()``
+^^^^^^^^^^^^^^^^^^^^^^^
+
+TF-M RPC ``psa_close()`` handler
+
+.. code-block:: c
+
+ void tfm_rpc_psa_close(const struct client_call_params_t *params,
+ bool ns_caller);
+
+**Parameters**
+
++---------------+-----------------------------------+
+| ``params`` | Base address of parameters. |
++---------------+-----------------------------------+
+| ``ns_caller`` | Whether the caller is non-secure. |
++---------------+-----------------------------------+
+
+**Return**
+
++---------------------+---------------------------------------------+
+| ``void`` | Success. |
++---------------------+---------------------------------------------+
+| ``Does not return`` | The call is invalid, or invalid parameters. |
++---------------------+---------------------------------------------+
+
+**Usage**
+
+``tfm_rpc_psa_close()`` invokes common ``psa_close()`` handler in TF-M.
+The parameters in params should be prepared before calling
+``tfm_rpc_psa_close()``.
+
+Other modifications
+===================
+
+The following mandatory changes are also required.
+
+- One or more compile flag(s) should be defined to select corresponding
+ execution routines in dual-core scenario or single Armv8-M scenario during
+ building.
+
+*********
+Reference
+*********
+
+.. [1] :doc:`Mailbox Design in TF-M on Dual-core System <./mailbox_design_on_dual_core_system>`
+.. [2] :doc:`Secure Interrupt Integration Guide </integration_guide/tfm_secure_irq_integration_guide>`
+
+----------------
+
+*Copyright (c) 2019-2022 Arm Limited. All Rights Reserved.*
+
+*Copyright (c) 2020-2022 Cypress Semiconductor Corporation. All Rights Reserved.*
diff --git a/docs/design_docs/dual-cpu/dual_core_mailbox_arch.png b/docs/design_docs/dual-cpu/dual_core_mailbox_arch.png
new file mode 100644
index 0000000..79f5654
--- /dev/null
+++ b/docs/design_docs/dual-cpu/dual_core_mailbox_arch.png
Binary files differ
diff --git a/docs/design_docs/dual-cpu/index.rst b/docs/design_docs/dual-cpu/index.rst
new file mode 100644
index 0000000..f302748
--- /dev/null
+++ b/docs/design_docs/dual-cpu/index.rst
@@ -0,0 +1,12 @@
+Dual-CPU
+========
+
+.. toctree::
+ :maxdepth: 1
+ :glob:
+
+ *
+
+--------------
+
+*Copyright (c) 2020, Arm Limited. All rights reserved.*
diff --git a/docs/design_docs/dual-cpu/mailbox_design_on_dual_core_system.rst b/docs/design_docs/dual-cpu/mailbox_design_on_dual_core_system.rst
new file mode 100644
index 0000000..318600b
--- /dev/null
+++ b/docs/design_docs/dual-cpu/mailbox_design_on_dual_core_system.rst
@@ -0,0 +1,1462 @@
+##########################################
+Mailbox Design in TF-M on Dual-core System
+##########################################
+
+:Author: David Hu
+:Organization: Arm Limited
+:Contact: david.hu@arm.com
+
+************
+Introduction
+************
+
+This document proposes a generic design of the mailbox communication for Trusted
+Firmware-M (TF-M) on a dual-core system. The mailbox functionalities transfer
+PSA Client requests and results between Non-secure Processing Environment (NSPE)
+and Secure Processing Environment (SPE).
+
+The dual-core system should satisfy the following requirements
+
+- NSPE and SPE are properly isolated and protected following PSA specifications.
+- An Arm M-profile core locates in SPE and acts as the Secure core.
+- TF-M runs on the Secure core with platform specific drivers support.
+- Inter-Processor Communication hardware module in system for communication
+ between Secure core and Non-secure core. Mailbox communication calls the
+ Inter-Processor Communication to transfer notifications.
+- Non-secure memory shared by NSPE and SPE.
+
+Scope
+=====
+
+This design document focuses on the mailbox functionalities in NSPE and SPE on a
+dual-core system. The mailbox functionalities include the initialization of
+mailbox in NSPE and SPE, and the transfer of PSA Client requests and replies
+between NSPE and SPE.
+
+Data types and mailbox APIs are defined in this document.
+
+Some details of interactions between mailbox and other modules are specified in
+other documents.
+Communication prototype design [1]_ defines a general communication prototype
+between NSPE and SPE on a dual-core system. It describes how TF-M interacts with
+mailbox functionalities and the general requirements on mailbox.
+Dual-core booting sequence [2]_ describes a synchronization step of mailbox
+between NSPE and SPE during system booting.
+
+Organization of the document
+============================
+
+- `Mailbox architecture`_ provides an overview on the mailbox architecture.
+- `Mailbox communication for PSA Client calls`_ discusses about the mailbox
+ communication for PSA Client calls.
+- `Mailbox initialization`_ introduces the initialization of mailbox.
+- `Mailbox APIs and data structures`_ lists mailbox data types and APIs.
+
+********************
+Mailbox architecture
+********************
+
+The mailbox consists of two parts sitting in NSPE and SPE respectively.
+NSPE mailbox provides mailbox functionalities in NSPE and SPE mailbox provides
+mailbox functionalities in TF-M in SPE.
+
+PSA Client APIs called in NSPE are implemented by NSPE mailbox functions on
+dual-core systems, to send PSA Client request and receive the result. The
+implementation can vary in diverse NSPE OSs or use cases.
+
+TF-M provides a reference implementation of NSPE mailbox. The NSPE mailbox
+delivers the PSA Client requests to SPE mailbox. After the PSA Client result is
+replied from SPE, NSPE mailbox fetches the result and returns it to PSA Client
+APIs.
+
+NSPE mailbox objects are managed by NSPE mailbox in non-secure memory to hold
+PSA Client call parameters, return result and other mailbox data.
+NSPE mailbox relies on platform specific Inter-Process Communication to process
+notifications between NSPE and SPE.
+
+The SPE mailbox in TF-M receives PSA Client requests from NSPE mailbox. It
+parses the requests and invokes TF-M Remote Procedure Call (RPC) layer.
+RPC layer delivers the requests to TF-M core/Secure Partition Manager (SPM).
+After the PSA Client call is completed, TF-M core/SPM invokes RPC layer to
+return results to NSPE, via SPE mailbox.
+SPE mailbox objects are managed by SPE mailbox in secure memory.
+SPE mailbox relies on platform specific Inter-Process Communication to process
+notifications between SPE and NSPE.
+
+The architecture is showed in following figure.
+
+.. figure:: dual_core_mailbox_arch.png
+
+******************************************
+Mailbox communication for PSA Client calls
+******************************************
+
+This section describes the transfer of PSA Client request and reply between NSPE
+and SPE via mailbox.
+
+Mailbox objects
+===============
+
+This section lists the mailbox objects required in NSPE and SPE.
+
+NSPE mailbox objects are managed by NSPE mailbox in non-secure memory. But NSPE
+mailbox objects can be accessed by both NSPE mailbox and SPE mailbox.
+
+SPE mailbox objects are managed by SPE mailbox in secure memory. SPE mailbox
+objects should be protected from NSPE accesses by system specific isolation.
+
+NSPE Mailbox queue
+------------------
+
+NSPE mailbox maintains a mailbox queue in non-secure memory. Please refer to the
+structure definition in `NSPE mailbox queue structure`_.
+
+NSPE mailbox queue contains one or more slots. The number of slots should be
+aligned with that in SPE mailbox queue.
+
+Each slot in NSPE mailbox queue consists of a pair of a mailbox message
+structure and a mailbox reply structure. Each slot might contain additional
+fields, such as identification of non-secure task which initiates the PSA Client
+request. Each slot serves a PSA Client call from non-secure task.
+
+The parameters of PSA Client request are hosted in the mailbox message inside
+the slot. `Mailbox messages`_ describes the details of mailbox message.
+
+The mailbox reply structure is used to receive the PSA Client result from SPE.
+`Mailbox replies`_ describes the details of mailbox reply.
+
+Mailbox messages
+----------------
+
+A mailbox message contains the parameters of a PSA Client request from a
+non-secure task. Please refer to the structure definition in
+`Mailbox message structure`_.
+
+Inside PSA Client API implementation, NSPE mailbox selects an empty mailbox
+queue slot for the PSA Client request. The parameters of that PSA Client request
+are organized into the mailbox message belonging to the selected slot.
+SPE mailbox will parse those parameters from the mailbox message.
+
+More fields can be defined in mailbox message to transfer additional information
+from NSPE to SPE for processing in TF-M.
+
+Mailbox replies
+---------------
+
+A mailbox reply structure in non-secure memory receives the PSA Client result
+replied from SPE mailbox. Please refer to the structure definition in
+`Mailbox reply structure`_.
+
+SPE Mailbox queue
+-----------------
+
+SPE mailbox maintains a mailbox queue to store SPE mailbox objects.
+Please refer to the structure definition in `SPE mailbox queue structure`_.
+
+SPE mailbox queue contains one or more slots. The number of slots should be
+aligned with that in NSPE mailbox queue. After SPE is notified that a PSA Client
+request is pending, SPE mailbox can assign an empty slot, copy the corresponding
+PSA Client call parameters from non-secure memory to that slot and parse the
+parameters.
+
+Each slot in SPE mailbox queue can contain the following fields
+
+- An optional field to hold mailbox message content copied from non-secure
+ memory.
+- Index of NSPE mailbox queue slot containing the mailbox message.
+- A handle to the mailbox message. Optional. Identify the owner slot of PSA
+ Client result when multiple mailbox messages are under processing.
+
+More fields can be defined in the slot structure to support mailbox processing
+in SPE.
+
+Overall workflow
+================
+
+The overall workflow of transferring PSA Client requests and results between
+NSPE and SPE via mailbox is shown below.
+
+#. Non-secure task initiates a service request by calling PSA Developer APIs,
+ which eventually invoke PSA Client APIs.
+ PSA Client APIs call NSPE mailbox functions to transmit PSA Client call to
+ SPE.
+
+#. NSPE mailbox assigns an empty slot from NSPE mailbox queue for that PSA
+ client call.
+
+#. NSPE mailbox prepares the parameters of PSA Client call in the dedicated
+ mailbox message inside the assigned slot.
+
+#. After the mailbox message is ready, NSPE mailbox invokes platform specific
+ Inter-Processor Communication driver to notify SPE.
+ The notification mechanism of Inter-Processor Communication is platform
+ specific.
+
+#. After the notification is completed, non-secure task waits for the reply from
+ SPE.
+
+#. Platform specific Inter-Processor Communication interrupt for mailbox is
+ asserted in SPE. The interrupt handler activates SPE mailbox to process the
+ request(s).
+
+#. During mailbox processing in TF-M, the handling routine can include the
+ following steps:
+
+ #. SPE mailbox checks and validates NSPE mailbox queue status.
+ #. SPE mailbox fetches PSA Client call parameters from NSPE mailbox queue.
+ #. SPE mailbox parses the parameters.
+ #. SPE mailbox invokes the TF-M RPC APIs to deliver the PSA Client
+ request to TF-M SPM.
+ #. The PSA Client call is handled in TF-M SPM and target Secure Partition if
+ necessary.
+
+ If multiple ongoing mailbox messages are pending in the SPE, SPE mailbox can
+ process mailbox messages one by one.
+
+#. After the PSA Client call is completed, TF-M RPC layer notifies SPE mailbox
+ to reply PSA Client result to NSPE.
+
+#. SPE mailbox writes the PSA Client result to the dedicated mailbox reply
+ structure in non-secure memory. The related SPE mailbox objects should be
+ invalidated or cleaned.
+
+#. SPE mailbox notifies NSPE by invoking Inter-Processor Communication driver to
+ send a notification to NSPE.
+ The notification mechanism of Inter-Processor Communication is platform
+ specific.
+
+#. NSPE mailbox is activated to handle the PSA Client result in the mailbox
+ reply structure. Related mailbox objects should be invalidated or cleaned by
+ NSPE mailbox after the return results is extracted out.
+
+#. NSPE mailbox returns the result to PSA Client API implementation.
+ The result is eventually returned to the non-secure task.
+
+The following sections discuss more details of key steps in above sequence.
+
+Mailbox notifications between NSPE and SPE
+==========================================
+
+As shown in `Overall workflow`_, NSPE mailbox asserts mailbox notification to
+trigger SPE to handle PSA Client request. SPE mailbox asserts mailbox
+notification to notify NSPE that PSA Client result is written. The notification
+implementation is based on platform specific Inter-Processor Communication.
+
+It is recommended to assign one independent set of Inter-Processor Communication
+channel to each notification routine respectively, to implement a *full-duplex*
+notification mechanism between NSPE and SPE.
+If both notification routines share the same Inter-Processor Communication
+channel, proper synchronization should be implemented to prevent conflicts
+between two notification routines.
+
+In SPE, the Inter-Processor Communication interrupt handler should deal with the
+incoming notification from NSPE and activate the subsequent mailbox handling in
+SPE. Communication prototype design [1]_ defines the behavior of Inter-Processor
+Communication interrupt handler.
+
+NSPE can implement an interrupt handler or a polling of notification status to
+handle Inter-Processor Communication notification from SPE.
+
+Implement PSA Client API with NSPE Mailbox
+==========================================
+
+PSA Client APIs are implemented with NSPE mailbox API
+``tfm_ns_mailbox_client_call()``.
+
+The pseudo code below shows a reference implementation of
+``psa_framework_version()``.
+
+.. code-block:: c
+
+ uint32_t psa_framework_version(void)
+ {
+ ...
+ int32_t ret;
+
+ ret = tfm_ns_mailbox_client_call(...);
+ if (ret != MAILBOX_SUCCESS) {
+ version = PSA_VERSION_NONE;
+ }
+
+ ...
+ }
+
+``tfm_ns_mailbox_client_call()`` implementation can vary according to usage
+scenario. TF-M reference implementation provides implementations for NS OS and
+NS bare metal environment respectively. Refer to
+`TF-M reference implementation of NSPE mailbox`_ for details.
+
+As PSA Firmware Framework-M (FF-M) requests, a PSA Client API function should be
+blocked until the result is returned. To comply with FF-M, NSPE mailbox requires
+proper mechanism(s) to keep current caller waiting for PSA Client result or an
+empty mailbox queue slot.
+
+.. note::
+
+ ``tfm_ns_mailbox_client_call()`` may trap the current exception in sleep and
+ therefore it must not be called in interrupt service routine.
+
+Refer to `Mailbox APIs and data structures`_ for details of
+``tfm_ns_mailbox_client_call()``.
+
+TF-M reference implementation of NSPE mailbox
+=============================================
+
+TF-M NS interface provides a reference implementation of NS mailbox.
+
+This reference implementation defines several NS mailbox HAL APIs. Please refer
+to `NSPE mailbox HAL APIs`_ for details.
+
+Integration with NSPE
+---------------------
+
+TF-M reference implementation provides several mailbox build flags to control
+the integration with NS software.
+
+ .. _mailbox_os_flag:
+
+ - ``TFM_MULTI_CORE_NS_OS``
+
+ When integrating NS mailbox with NS OS, such as NS RTOS, that flag can be
+ selected to enable NS OS support in NS mailbox, such as thread management
+ to fulfill thread wait and wake-up.
+ Please refer to `NSPE mailbox RTOS abstraction APIs`_ for NS OS support
+ details.
+
+ With NS OS support, multiple outstanding PSA Client calls can be supported
+ in NS mailbox when number of mailbox queue slots configured in
+ ``NUM_MAILBOX_QUEUE_SLOT`` is greater than 1.
+
+ If ``TFM_MULTI_CORE_NS_OS`` is enabled, when a NS client starts a PSA Client
+ call:
+
+ - ``tfm_ns_mailbox_client_call()`` selects an empty NSPE mailbox queue slot
+ to organize received PSA client call parameters into a mailbox message.
+
+ - Then it sends those parameters to SPE mailbox and waits for results from
+ SPE. During waiting for the result, the NS client thread may be switched
+ out by NS OS scheduler.
+
+ - When the result arrives, the NS client thread will be woken up inside
+ NS mailbox interrupt handler.
+
+ - The result is then written back to NS client finally.
+
+ When that flag is disabled, NS mailbox runs as being integrated with NS bare
+ metal environment. NS mailbox simply loops mailbox message status while
+ waiting for results.
+
+ .. _mailbox_os_thread_flag:
+
+ - ``TFM_MULTI_CORE_NS_OS_MAILBOX_THREAD``
+
+ When ``TFM_MULTI_CORE_NS_OS`` is enabled, this flag can be selected to
+ enable another NS mailbox thread model which relies on a NS mailbox
+ dedicated thread.
+
+ - It requires NS OS to create a dedicated thread to perform NS mailbox
+ functionalities. This dedicated thread invokes
+ ``tfm_ns_mailbox_thread_runner()`` to handle PSA Client calls.
+ ``tfm_ns_mailbox_thread_runner()`` constructs mailbox messages and sends
+ them to SPE mailbox.
+
+ - ``tfm_ns_mailbox_client_call()`` sends PSA Client calls to the dedicated
+ mailbox thread. It doesn't directly deal with mailbox messages.
+
+ - It also relies on NS OS to provide thread management and inter-thread
+ communication. Please refer to `NSPE mailbox RTOS abstraction APIs`_ for
+ details.
+
+ - It also requires dual-cpu platform to implement NS Inter-Processor
+ Communication interrupts. The interrupt handler invokes
+ ``tfm_ns_mailbox_wake_reply_owner_isr()`` to deal with PSA Client call
+ replies and notify the waiting threads.
+
+Multiple outstanding PSA Client call feature
+--------------------------------------------
+
+Multiple outstanding PSA Client call feature can enable dual-cpu platform to
+issue multiple PSA Client calls in NS OS and those PSA Client calls can be
+served simultaneously.
+
+Without this feature, only a single PSA Client call can be issued and served.
+A new PSA Client call cannot be started until the previous one is completed.
+
+When multiple outstanding PSA Client call feature is enabled, while a NS
+application is waiting for its PSA Client result, another NS application can be
+switched in by NS OS to prepare another PSA Client call or deal with its PSA
+client result. It can decrease the CPU idle time of waiting for PSA Client call
+completion.
+
+If multiple NS applications request secure services in NS OS, it is recommended
+to enable this feature.
+
+To implement this feature in NS OS:
+
+ - Platform should set the number of mailbox queue slots in
+ ``NUM_MAILBOX_QUEUE_SLOT`` in platform's ``config.cmake``.
+ It will use more data area with multiple mailbox queue slots.
+
+ NSPE and SPE share the same ``NUM_MAILBOX_QUEUE_SLOT`` value.
+
+ - Enable ``TFM_MULTI_CORE_NS_OS``
+
+ For more details, refer to
+ :ref:`TFM_MULTI_CORE_NS_OS<mailbox_os_flag>`.
+
+ ``TFM_MULTI_CORE_NS_OS_MAILBOX_THREAD`` can be enabled to select another NS
+ mailbox working model.
+ See :ref:`TFM_MULTI_CORE_NS_OS_MAILBOX_THREAD<mailbox_os_thread_flag>` for
+ details.
+
+Critical section protection between cores
+=========================================
+
+Proper protection should be implemented to protect the critical accesses to
+shared mailbox resources. The critical sections can include atomic reading and
+modifying NSPE mailbox queue status, slot status and other critical operations.
+
+The implementation should protect a critical access to those shared mailbox
+resource from corruptions caused by accesses from the peer core. SPE mailbox
+also accesses NSPE mailbox queue. Therefore, it is essential to implement
+synchronization or protection on NSPE mailbox queue between Secure core and
+Non-secure core. NSPE mailbox and SPE mailbox define corresponding critical
+section protection APIs respectively. The implementation of those APIs can be
+platform specific. Please see more details in `NSPE mailbox APIs`_ and
+`SPE mailbox APIs`_.
+
+It is recommended to rely on both hardware and software to implement the
+synchronization and protection.
+
+Protection of local mailbox objects can be implemented as static functions
+inside NSPE mailbox and SPE mailbox.
+
+Mailbox handling in TF-M
+========================
+
+According to communication prototype design [1]_, mailbox implementation should
+invoke ``tfm_rpc_register_ops()`` to hook its operations to TF-M RPC module
+callbacks during initialization. Mailbox message handling should call TF-M RPC
+PSA Client call handlers to deliver PSA Client request to TF-M SPM.
+
+If multiple outstanding NS PSA Client calls should be supported, TF-M SPM can
+store the mailbox message handle in a specific field in PSA message structure to
+identify the mailbox message, while creating a PSA message. While replying the
+PSA Client result, TF-M SPM can extract the mailbox message handle from PSA
+message and pass it back to mailbox reply function. SPE mailbox can identify
+which mailbox message is completed according to the handle and write the result
+to corresponding NSPE mailbox queue slot.
+
+Platform specific Inter-Processor Communication interrupt handler in SPE should
+call ``spm_handle_interrupt()`` to notify SPM of the interrupt. SPM will then
+send the ``SIGNAL_MAILBOX`` signal to the ``ns_agent_mailbox`` partition, which
+will call ``tfm_rpc_client_call_handler()``.
+
+**********************
+Mailbox initialization
+**********************
+
+It should be guaranteed that NSPE mailbox should not initiate PSA Client request
+until SPE mailbox initialization completes.
+Refer to dual-core booting sequence [2]_ for more details on the synchronization
+between NSPE and SPE during booting.
+
+In current design, the base address of NSPE mailbox queue should be pre-defined
+and shared between NSPE mailbox and SPE mailbox.
+
+SPE mailbox initialization
+==========================
+
+The SPE mailbox queue memory should be allocated before calling
+``tfm_mailbox_init()``. ``tfm_mailbox_init()`` initializes the memory and
+variables.
+``tfm_mailbox_init()`` calls ``tfm_mailbox_hal_init()`` to perform platform
+specific initialization. The base address of NSPE mailbox queue can be
+received via ``tfm_mailbox_hal_init()``.
+
+SPE mailbox dedicated Inter-Processor Communication initialization can also be
+enabled during SPE mailbox initialization.
+
+After SPE mailbox initialization completes, SPE notifies NSPE that SPE mailbox
+functionalities are ready.
+
+NSPE mailbox initialization
+===========================
+
+The NSPE mailbox queue memory should be allocated before calling
+``tfm_ns_mailbox_init()``. ``tfm_ns_mailbox_init()`` initializes the memory and
+variables.
+``tfm_ns_mailbox_init()`` calls ``tfm_ns_mailbox_hal_init()`` to perform
+platform specific initialization. The base address of NSPE mailbox queue can be
+passed to SPE mailbox via ``tfm_ns_mailbox_hal_init()``.
+
+NSPE mailbox dedicated Inter-Processor Communication initialization can also be
+enabled during NSPE mailbox initialization.
+
+********************************
+Mailbox APIs and data structures
+********************************
+
+Data types
+==========
+
+Constants
+---------
+
+``MAILBOX_SUCCESS``
+^^^^^^^^^^^^^^^^^^^
+
+``MAILBOX_SUCCESS`` is a generic return value to indicate success of mailbox
+operation.
+
+.. code-block:: c
+
+ #define MAILBOX_SUCCESS (0)
+
+``MAILBOX_QUEUE_FULL``
+^^^^^^^^^^^^^^^^^^^^^^
+
+``MAILBOX_QUEUE_FULL`` is a return value from mailbox function if mailbox queue
+is full.
+
+.. code-block:: c
+
+ #define MAILBOX_QUEUE_FULL (INT32_MIN + 1)
+
+``MAILBOX_INVAL_PARAMS``
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+``MAILBOX_INVAL_PARAMS`` is a return value from mailbox function if any
+parameter is invalid.
+
+.. code-block:: c
+
+ #define MAILBOX_INVAL_PARAMS (INT32_MIN + 2)
+
+``MAILBOX_NO_PERMS``
+^^^^^^^^^^^^^^^^^^^^
+
+``MAILBOX_NO_PERMS`` is a return value from mailbox function if the caller
+doesn't own a proper permission to execute the operation.
+
+.. code-block:: c
+
+ #define MAILBOX_NO_PERMS (INT32_MIN + 3)
+
+``MAILBOX_NO_PEND_EVENT``
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+``MAILBOX_NO_PEND_EVENT`` is a return value from mailbox function if the
+expected event doesn't occur yet.
+
+.. code-block:: c
+
+ #define MAILBOX_NO_PEND_EVENT (INT32_MIN + 4)
+
+``MAILBOX_CHAN_BUSY``
+^^^^^^^^^^^^^^^^^^^^^
+
+``MAILBOX_CHAN_BUSY`` is a return value from mailbox function if the underlying
+Inter-Processor Communication resource is busy.
+
+.. code-block:: c
+
+ #define MAILBOX_CHAN_BUSY (INT32_MIN + 5)
+
+``MAILBOX_CALLBACK_REG_ERROR``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+``MAILBOX_CALLBACK_REG_ERROR`` is a return value from mailbox function if the
+registration of mailbox callback functions failed.
+
+.. code-block:: c
+
+ #define MAILBOX_CALLBACK_REG_ERROR (INT32_MIN + 6)
+
+``MAILBOX_INIT_ERROR``
+^^^^^^^^^^^^^^^^^^^^^^
+
+``MAILBOX_INIT_ERROR`` is a return value from mailbox function if the mailbox
+initialization failed.
+
+.. code-block:: c
+
+ #define MAILBOX_INIT_ERROR (INT32_MIN + 7)
+
+``MAILBOX_GENERIC_ERROR``
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+``MAILBOX_GENERIC_ERROR`` indicates mailbox generic errors which cannot be
+indicated by the codes above.
+
+.. code-block:: c
+
+ #define MAILBOX_GENERIC_ERROR (INT32_MIN + 8)
+
+PSA Client API types
+^^^^^^^^^^^^^^^^^^^^
+
+The following constants define the PSA Client API type values shared between
+NSPE and SPE
+
+.. code-block:: c
+
+ #define MAILBOX_PSA_FRAMEWORK_VERSION (0x1)
+ #define MAILBOX_PSA_VERSION (0x2)
+ #define MAILBOX_PSA_CONNECT (0x3)
+ #define MAILBOX_PSA_CALL (0x4)
+ #define MAILBOX_PSA_CLOSE (0x5)
+
+Mailbox message structure
+-------------------------
+
+``psa_client_params_t`` lists the parameters passed from NSPE to SPE required by
+a PSA Client call.
+
+.. code-block:: c
+
+ struct psa_client_params_t {
+ union {
+ struct {
+ uint32_t sid;
+ } psa_version_params;
+
+ struct {
+ uint32_t sid;
+ uint32_t minor_version;
+ } psa_connect_params;
+
+ struct {
+ psa_handle_t handle;
+ int32_t type;
+ const psa_invec *in_vec;
+ size_t in_len;
+ psa_outvec *out_vec;
+ size_t out_len;
+ } psa_call_params;
+
+ struct {
+ psa_handle_t handle;
+ } psa_close_params;
+ };
+ };
+
+The following structure describe a mailbox message and its members.
+
+- ``call_type`` indicates the PSA Client API type.
+- ``params`` stores the PSA Client call parameters.
+- ``client_id`` records the client ID of the non-secure client. Optional.
+ It is used to identify the non-secure tasks in TF-M when NSPE OS enforces
+ non-secure task isolation.
+
+.. code-block:: c
+
+ struct mailbox_msg_t {
+ uint32_t call_type;
+ struct psa_client_params_t params;
+
+ int32_t client_id;
+ };
+
+Mailbox reply structure
+-----------------------
+
+This structure describes a mailbox reply structure, which is managed by NSPE
+mailbox in non-secure memory.
+
+.. code-block:: c
+
+ struct mailbox_reply_t {
+ int32_t return_val;
+ const void *owner;
+ int32_t *reply;
+ uint8_t *woken_flag;
+ };
+
+Mailbox queue status bitmask
+----------------------------
+
+``mailbox_queue_status_t`` defines a bitmask to indicate a status of slots in
+mailbox queues.
+
+.. code-block:: c
+
+ typedef uint32_t mailbox_queue_status_t;
+
+NSPE mailbox queue structure
+----------------------------
+
+``ns_mailbox_slot_t`` defines a non-secure mailbox queue slot.
+
+.. code-block:: c
+
+ /* A single slot structure in NSPE mailbox queue */
+ struct ns_mailbox_slot_t {
+ struct mailbox_msg_t msg;
+ struct mailbox_reply_t reply;
+ };
+
+``ns_mailbox_queue_t`` describes the NSPE mailbox queue and its members in
+non-secure memory.
+
+- ``empty_slots`` is the bitmask of empty slots.
+- ``pend_slots`` is the bitmask of slots whose PSA Client call is not replied
+ yet.
+- ``replied_slots`` is the bitmask of slots whose PSA Client result is returned
+ but not extracted yet.
+- ``queue`` is the NSPE mailbox queue of slots.
+- ``is_full`` indicates whether NS mailbox queue is full.
+
+.. code-block:: c
+
+ struct ns_mailbox_queue_t {
+ mailbox_queue_status_t empty_slots;
+ mailbox_queue_status_t pend_slots;
+ mailbox_queue_status_t replied_slots;
+
+ struct ns_mailbox_slot_t queue[NUM_MAILBOX_QUEUE_SLOT];
+
+ bool is_full;
+ };
+
+SPE mailbox queue structure
+---------------------------
+
+``secure_mailbox_slot_t`` defines a single slot structure in SPE mailbox queue.
+
+- ``ns_slot_idx`` records the index of NSPE mailbox slot containing the mailbox
+ message under processing. SPE mailbox determines the reply structure address
+ according to this index.
+- ``msg_handle`` contains the handle to the mailbox message under processing.
+ The handle can be delivered to TF-M SPM while creating PSA message to identify
+ the mailbox message.
+
+.. code-block:: c
+
+ /* A handle to a mailbox message in use */
+ typedef int32_t mailbox_msg_handle_t;
+
+ struct secure_mailbox_slot_t {
+ uint8_t ns_slot_idx;
+ mailbox_msg_handle_t msg_handle;
+ };
+
+``secure_mailbox_queue_t`` describes the SPE mailbox queue in secure memory.
+
+- ``empty_slots`` is the bitmask of empty slots.
+- ``queue`` is the SPE mailbox queue of slots.
+- ``ns_queue`` stores the address of NSPE mailbox queue structure.
+- ``cur_proc_slot_idx`` indicates the index of mailbox queue slot currently
+ under processing.
+
+.. code-block:: c
+
+ struct secure_mailbox_queue_t {
+ mailbox_queue_status_t empty_slots;
+
+ struct secure_mailbox_slot_t queue[NUM_MAILBOX_QUEUE_SLOT];
+ /* Base address of NSPE mailbox queue in non-secure memory */
+ struct ns_mailbox_queue_t *ns_queue;
+ uint8_t cur_proc_slot_idx;
+ };
+
+NSPE mailbox APIs
+=================
+
+NSPE mailbox interface APIs
+---------------------------
+
+APIs defined in this section are called by NS software and PSA Client APIs
+implementations.
+
+``tfm_ns_mailbox_init()``
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This function initializes NSPE mailbox.
+
+.. code-block:: c
+
+ int32_t tfm_ns_mailbox_init(struct ns_mailbox_queue_t *queue);
+
+**Parameters**
+
++-----------+-----------------------------------------+
+| ``queue`` | The base address of NSPE mailbox queue. |
++-----------+-----------------------------------------+
+
+**Return**
+
++---------------------+------------------------------------------+
+| ``MAILBOX_SUCCESS`` | Initialization succeeds. |
++---------------------+------------------------------------------+
+| Other return codes | Initialization fails with an error code. |
++---------------------+------------------------------------------+
+
+**Usage**
+
+``tfm_ns_mailbox_init()`` invokes ``tfm_ns_mailbox_hal_init()`` to complete
+platform specific mailbox and Inter-Processor Communication initialization.
+The non-secure memory area for NSPE mailbox queue structure should be statically
+or dynamically pre-allocated before calling ``tfm_ns_mailbox_init()``.
+
+``tfm_ns_mailbox_client_call()``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This function sends the PSA Client request to SPE, waits and fetches PSA Client
+result.
+
+.. code-block:: c
+
+ int32_t tfm_ns_mailbox_client_call(uint32_t call_type,
+ const struct psa_client_params_t *params,
+ int32_t client_id,
+ int32_t *reply);
+
+**Parameters**
+
++---------------+--------------------------------------------------+
+| ``call_type`` | Type of PSA Client call |
++---------------+--------------------------------------------------+
+| ``params`` | Address of PSA Client call parameters structure. |
++---------------+--------------------------------------------------+
+| ``client_id`` | ID of non-secure task. |
++---------------+--------------------------------------------------+
+| ``reply`` | The NS client task private buffer written with |
+| | PSA Client result |
++---------------+--------------------------------------------------+
+
+**Return**
+
++---------------------+--------------------------------------------+
+| ``MAILBOX_SUCCESS`` | PSA Client call is completed successfully. |
++---------------------+--------------------------------------------+
+| Other return code | Operation failed with an error code. |
++---------------------+--------------------------------------------+
+
+**Usage**
+
+If ``TFM_MULTI_CORE_NS_OS_MAILBOX_THREAD`` is enabled,
+``tfm_ns_mailbox_client_call()`` will forward PSA Client calls to the dedicated
+mailbox thread via NS OS message queue.
+Otherwise, ``tfm_ns_mailbox_client_call()`` directly deals with PSA Client calls
+and perform NS mailbox functionalities.
+
+``tfm_ns_mailbox_thread_runner()``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This function handles PSA Client call inside a dedicated NS mailbox thread.
+It constructs mailbox messages and transmits them to SPE mailbox.
+
+.. code-block:: c
+
+ void tfm_ns_mailbox_thread_runner(void *args);
+
+**Parameters**
+
++----------+-------------------------------------------------------------+
+| ``args`` | The pointer to the structure of PSA Client call parameters. |
++----------+-------------------------------------------------------------+
+
+**Usage**
+
+``tfm_ns_mailbox_thread_runner()`` should be executed inside the dedicated
+mailbox thread.
+
+.. note::
+
+ ``tfm_ns_mailbox_thread_runner()`` is implemented as an empty function when
+ ``TFM_MULTI_CORE_NS_OS_MAILBOX_THREAD`` is disabled.
+
+``tfm_ns_mailbox_wake_reply_owner_isr()``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This function wakes up the owner task(s) of the returned PSA Client result(s).
+
+.. code-block:: c
+
+ int32_t tfm_ns_mailbox_wake_reply_owner_isr(void);
+
+**Return**
+
++---------------------------+--------------------------------------------+
+| ``MAILBOX_SUCCESS`` | The tasks of replied mailbox messages were |
+| | found and wake-up signals were sent. |
++---------------------------+--------------------------------------------+
+| ``MAILBOX_NO_PEND_EVENT`` | No replied mailbox message is found. |
++---------------------------+--------------------------------------------+
+| Other return codes | Operation failed with an error code |
++---------------------------+--------------------------------------------+
+
+**Usage**
+
+``tfm_ns_mailbox_wake_reply_owner_isr()`` should be called from platform
+specific Inter-Processor Communication interrupt handler.
+
+.. note::
+
+ ``tfm_ns_mailbox_wake_reply_owner_isr()`` is implemented as a dummy function
+ when ``TFM_MULTI_CORE_NS_OS`` is disabled.
+
+NSPE mailbox HAL APIs
+---------------------
+
+The HAL APIs defined in this section should be implemented by platform-specific
+implementation.
+
+This section describes a *reference design* of NSPE mailbox HAL APIs. Developers
+can define and implement different APIs.
+
+``tfm_ns_mailbox_hal_init()``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This function executes platform-specific NSPE mailbox initialization.
+
+.. code-block:: c
+
+ int32_t tfm_ns_mailbox_hal_init(struct ns_mailbox_queue_t *queue);
+
+**Parameters**
+
++-----------+-----------------------------------------+
+| ``queue`` | The base address of NSPE mailbox queue. |
++-----------+-----------------------------------------+
+
+**Return**
+
++---------------------+------------------------------------------+
+| ``MAILBOX_SUCCESS`` | Initialization succeeds. |
++---------------------+------------------------------------------+
+| Other return codes | Initialization fails with an error code. |
++---------------------+------------------------------------------+
+
+**Usage**
+
+``tfm_ns_mailbox_hal_init()`` performs platform specific mailbox and
+Inter-Processor Communication initialization. ``tfm_ns_mailbox_hal_init()`` can
+also share the address of NSPE mailbox queue with SPE mailbox via platform
+specific implementation.
+
+``tfm_ns_mailbox_hal_notify_peer()``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This function invokes platform specific Inter-Processor Communication drivers to
+send notification to SPE.
+
+.. code-block:: c
+
+ int32_t tfm_ns_mailbox_hal_notify_peer(void);
+
+**Return**
+
++---------------------+---------------------------------------+
+| ``MAILBOX_SUCCESS`` | The operation completes successfully. |
++---------------------+---------------------------------------+
+| Other return codes | Operation fails with an error code. |
++---------------------+---------------------------------------+
+
+**Usage**
+
+``tfm_ns_mailbox_hal_notify_peer()`` should be implemented by platform specific
+Inter-Processor Communication drivers.
+
+``tfm_ns_mailbox_hal_notify_peer()`` should not be exported outside NSPE
+mailbox.
+
+``tfm_ns_mailbox_hal_enter_critical()``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This function enters the critical section of NSPE mailbox queue access.
+
+.. code-block:: c
+
+ void tfm_ns_mailbox_hal_enter_critical(void);
+
+**Usage**
+
+NSPE mailbox invokes ``tfm_ns_mailbox_hal_enter_critical()`` before entering
+critical section of NSPE mailbox queue.
+``tfm_ns_mailbox_hal_enter_critical()`` implementation is platform specific.
+
+``tfm_ns_mailbox_hal_enter_critical()`` should not be called in any interrupt
+service routine.
+
+``tfm_ns_mailbox_hal_exit_critical()``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This function exits the critical section of NSPE mailbox queue access.
+
+.. code-block:: c
+
+ void tfm_ns_mailbox_hal_exit_critical(void);
+
+**Usage**
+
+NSPE mailbox invokes ``tfm_ns_mailbox_hal_exit_critical()`` after exiting
+critical section of NSPE mailbox queue.
+``tfm_ns_mailbox_hal_exit_critical()`` implementation is platform specific.
+
+``tfm_ns_mailbox_hal_exit_critical()`` should not be called in any interrupt
+service routine.
+
+``tfm_ns_mailbox_hal_enter_critical_isr()``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This function enters the critical section of NSPE mailbox queue access in an
+IRQ handler.
+
+.. code-block:: c
+
+ void tfm_ns_mailbox_hal_enter_critical(void);
+
+**Usage**
+
+NSPE mailbox invokes ``tfm_ns_mailbox_hal_enter_critical_isr()`` before entering
+critical section of NSPE mailbox queue in an IRQ handler.
+``tfm_ns_mailbox_hal_enter_critical_isr()`` implementation is platform specific.
+
+``tfm_ns_mailbox_hal_exit_critical_isr()``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This function exits the critical section of NSPE mailbox queue access in an IRQ
+handler
+
+.. code-block:: c
+
+ void tfm_ns_mailbox_hal_exit_critical_isr(void);
+
+**Usage**
+
+NSPE mailbox invokes ``tfm_ns_mailbox_hal_exit_critical_isr()`` after exiting
+critical section of NSPE mailbox queue in an IRQ handler.
+``tfm_ns_mailbox_hal_exit_critical_isr()`` implementation is platform specific.
+
+NSPE mailbox RTOS abstraction APIs
+----------------------------------
+
+The APIs defined in this section should be implemented by RTOS-specific
+implementation when ``TFM_MULTI_CORE_NS_OS`` is enabled.
+
+.. note::
+
+ If ``TFM_MULTI_CORE_NS_OS`` is set to ``OFF``, the following APIs are defined
+ as dummy functions or empty functions.
+
+``tfm_ns_mailbox_os_lock_init()``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This function initializes the multi-core lock for synchronizing PSA client
+call(s). The actual implementation depends on the non-secure use scenario.
+
+.. code-block:: c
+
+ int32_t tfm_ns_mailbox_os_lock_init(void);
+
+**Return**
+
++---------------------------+---------------------------+
+| ``MAILBOX_SUCCESS`` | Initialization succeeded. |
++---------------------------+---------------------------+
+| ``MAILBOX_GENERIC_ERROR`` | Initialization failed. |
++---------------------------+---------------------------+
+
+**Usage**
+
+``tfm_ns_mailbox_init()`` invokes this function to initialize the lock.
+If ``TFM_MULTI_CORE_NS_OS_MAILBOX_THREAD`` is enabled,
+``tfm_ns_mailbox_os_lock_init()`` is defined as a dummy one.
+
+``tfm_ns_mailbox_os_lock_acquire()``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This function acquires the multi-core lock for synchronizing PSA client call(s).
+The actual implementation depends on the non-secure use scenario.
+
+.. code-block:: c
+
+ int32_t tfm_ns_mailbox_os_lock_acquire(void);
+
+**Return**
+
++---------------------------+--------------------------------+
+| ``MAILBOX_SUCCESS`` | Succeeded to acquire the lock. |
++---------------------------+--------------------------------+
+| ``MAILBOX_GENERIC_ERROR`` | Failed to acquire the lock. |
++---------------------------+--------------------------------+
+
+**Usage**
+
+``tfm_ns_mailbox_client_call()`` invokes this function to acquire the lock when
+``TFM_MULTI_CORE_NS_OS_MAILBOX_THREAD`` is disabled
+If ``TFM_MULTI_CORE_NS_OS_MAILBOX_THREAD`` is enabled,
+``tfm_ns_mailbox_os_lock_acquire()`` is defined as a dummy one.
+
+``tfm_ns_mailbox_os_lock_release()``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This function releases the multi-core lock for synchronizing PSA client call(s).
+The actual implementation depends on the non-secure use scenario.
+
+.. code-block:: c
+
+ int32_t tfm_ns_mailbox_os_lock_release(void);
+
+**Return**
+
++---------------------------+--------------------------------+
+| ``MAILBOX_SUCCESS`` | Succeeded to release the lock. |
++---------------------------+--------------------------------+
+| ``MAILBOX_GENERIC_ERROR`` | Failed to release the lock. |
++---------------------------+--------------------------------+
+
+**Usage**
+
+``tfm_ns_mailbox_client_call()`` invokes this function to release the lock when
+``TFM_MULTI_CORE_NS_OS_MAILBOX_THREAD`` is disabled
+If ``TFM_MULTI_CORE_NS_OS_MAILBOX_THREAD`` is enabled,
+``tfm_ns_mailbox_os_lock_release()`` is defined as a dummy one.
+
+``tfm_ns_mailbox_os_get_task_handle()``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This function gets the handle of the current non-secure task executing mailbox
+functionalities.
+
+.. code-block:: c
+
+ void *tfm_ns_mailbox_os_get_task_handle(void);
+
+**Return**
+
++-------------+-----------------------------------------------------------+
+| Task handle | The non-secure task handle waiting for PSA Client result. |
++-------------+-----------------------------------------------------------+
+
+``tfm_ns_mailbox_os_wait_reply()``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This function performs use scenario and NS OS specific waiting mechanism to wait
+for the reply of the specified mailbox message to be returned from SPE.
+
+.. code-block:: c
+
+ void tfm_ns_mailbox_os_wait_reply(void);
+
+**Usage**
+
+The PSA Client API implementations call ``tfm_ns_mailbox_os_wait_reply()`` to
+fall into sleep to wait for PSA Client result.
+
+``tfm_ns_mailbox_os_wake_task_isr()``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This function wakes up the dedicated task which is waiting for PSA Client
+result, via RTOS-specific wake-up mechanism.
+
+.. code-block:: c
+
+ void tfm_ns_mailbox_hal_wait_reply(const void *task_handle);
+
+**Parameters**
+
++-----------------+----------------------------------------+
+| ``task_handle`` | The handle to the task to be woken up. |
++-----------------+----------------------------------------+
+
+``tfm_ns_mailbox_os_mq_create()``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This function creates and initializes a NS OS message queue.
+
+.. code-block:: c
+
+ void *tfm_ns_mailbox_os_mq_create(ize_t msg_size, uint8_t msg_count);
+
+**Parameters**
+
++---------------+------------------------------------------+
+| ``msg_size`` | The maximum message size in bytes. |
++---------------+------------------------------------------+
+| ``msg_count`` | The maximum number of messages in queue. |
++---------------+------------------------------------------+
+
+**Return**
+
++----------------------+-----------------------------------------------------+
+| message queue handle | The handle of the message queue created, or NULL in |
+| | case of error. |
++----------------------+-----------------------------------------------------+
+
+**Usage**
+
+If ``TFM_MULTI_CORE_NS_OS_MAILBOX_THREAD`` is disabled,
+``tfm_ns_mailbox_os_mq_create()`` is defined as a dummy one.
+
+``tfm_ns_mailbox_os_mq_send()``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This function sends PSA Client call request via NS OS message queue.
+
+.. code-block:: c
+
+ int32_t tfm_ns_mailbox_os_mq_send(void *mq_handle,
+ const void *msg_ptr);
+
+**Parameters**
+
++---------------+----------------------------------------+
+| ``mq_handle`` | The handle of message queue. |
++---------------+----------------------------------------+
+| ``msg_ptr`` | The pointer to the message to be sent. |
++---------------+----------------------------------------+
+
+**Return**
+
++---------------------+-------------------------------------+
+| ``MAILBOX_SUCCESS`` | The message is successfully sent. |
++---------------------+-------------------------------------+
+| Other return code | Operation fails with an error code. |
++---------------------+-------------------------------------+
+
+**Usage**
+
+If ``TFM_MULTI_CORE_NS_OS_MAILBOX_THREAD`` is disabled,
+``tfm_ns_mailbox_os_mq_send()`` is defined as a dummy one.
+
+``tfm_ns_mailbox_os_mq_receive()``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This function receives PSA Client call requests via NS OS message queue.
+
+.. code-block:: c
+
+ int32_t tfm_ns_mailbox_os_mq_receive(void *mq_handle,
+ void *msg_ptr);
+
+**Parameters**
+
++---------------+---------------------------------------------------+
+| ``mq_handle`` | The handle of message queue. |
++---------------+---------------------------------------------------+
+| ``msg_ptr`` | The pointer to buffer for message to be received. |
++---------------+---------------------------------------------------+
+
+**Return**
+
++---------------------+-------------------------------------+
+| ``MAILBOX_SUCCESS`` | A message is successfully received. |
++---------------------+-------------------------------------+
+| Other return code | Operation fails with an error code. |
++---------------------+-------------------------------------+
+
+**Usage**
+
+The buffer size must be large enough to contain the request whose size is set
+in ``msg_size `` in ``tfm_ns_mailbox_os_mq_create()``.
+
+If ``TFM_MULTI_CORE_NS_OS_MAILBOX_THREAD`` is disabled,
+``tfm_ns_mailbox_os_mq_receive()`` is defined as a dummy one.
+
+.. note::
+
+ The function caller should be blocked until a PSA Client call request is
+ received from message queue, unless a fatal error occurs.
+
+SPE mailbox APIs
+================
+
+SPE mailbox interface APIs
+--------------------------
+
+The APIs defined in this section are called in TF-M routines and platform
+specific secure interrupt handler.
+
+``tfm_mailbox_handle_msg()``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This function completes the handling of mailbox messages from NSPE.
+
+.. code-block:: c
+
+ int32_t tfm_mailbox_handle_msg(void);
+
+**Return**
+
++---------------------+---------------------------------------+
+| ``MAILBOX_SUCCESS`` | The operation completes successfully. |
++---------------------+---------------------------------------+
+| Other return codes | Operation fails with an error code. |
++---------------------+---------------------------------------+
+
+**Usage**
+
+``tfm_mailbox_handle_msg()`` is registered to RPC callback function
+``handle_req``.
+
+``tfm_mailbox_handle_msg()`` executes the following tasks:
+
+- Check NSPE mailbox queue status.
+- Copy mailbox message(s) from NSPE. Optional.
+- Checks and validations if necessary
+- Parse mailbox message
+- Call TF-M RPC APIs to pass PSA Client request to TF-M SPM.
+
+``tfm_mailbox_reply_msg()``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This function replies the PSA Client result to NSPE.
+
+.. code-block:: c
+
+ int32_t tfm_mailbox_reply_msg(mailbox_msg_handle_t handle, int32_t reply);
+
+**Parameters**
+
++------------+-----------------------------------------------------------------+
+| ``handle`` | The handle to mailbox message related to the PSA Client result. |
++------------+-----------------------------------------------------------------+
+| ``reply`` | The PSA Client result value to be replied. |
++------------+-----------------------------------------------------------------+
+
+**Return**
+
++---------------------+---------------------------------------+
+| ``MAILBOX_SUCCESS`` | The operation completes successfully. |
++---------------------+---------------------------------------+
+| Other return codes | Operation fails with an error code. |
++---------------------+---------------------------------------+
+
+**Usage**
+
+``tfm_mailbox_reply_msg()`` is registered to RPC callback ``reply``.
+It is invoked inside handler of ``psa_reply()`` to return the PSA Client result
+to NSPE.
+
+``handle`` determines which mailbox message in SPE mailbox queue contains the
+PSA Client call. If ``handle`` is set as ``MAILBOX_MSG_NULL_HANDLE``, the return
+result is replied to the mailbox message in the first SPE mailbox queue slot.
+
+``tfm_mailbox_init()``
+^^^^^^^^^^^^^^^^^^^^^^
+
+This function initializes SPE mailbox.
+
+.. code-block:: c
+
+ int32_t tfm_mailbox_init(void);
+
+**Return**
+
++---------------------+-------------------------------------------+
+| ``MAILBOX_SUCCESS`` | Initialization succeeds. |
++---------------------+-------------------------------------------+
+| Other return codes | Initialization failed with an error code. |
++---------------------+-------------------------------------------+
+
+**Usage**
+
+``tfm_mailbox_init()`` invokes ``tfm_mailbox_hal_init()`` to execute platform
+specific initialization.
+
+SPE mailbox HAL APIs
+--------------------
+
+``tfm_mailbox_hal_notify_peer()``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This function invokes platform specific Inter-Processor Communication drivers to
+send notification to NSPE.
+
+.. code-block:: c
+
+ int32_t tfm_mailbox_hal_notify_peer(void);
+
+**Return**
+
++---------------------+---------------------------------------+
+| ``MAILBOX_SUCCESS`` | The operation completes successfully. |
++---------------------+---------------------------------------+
+| Other return codes | Operation fails with an error code. |
++---------------------+---------------------------------------+
+
+**Usage**
+
+``tfm_mailbox_hal_notify_peer()`` should be implemented by platform specific
+Inter-Processor Communication drivers.
+
+``tfm_mailbox_hal_notify_peer()`` should not be exported outside SPE mailbox.
+
+
+``tfm_mailbox_hal_init()``
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This function is implemented by platform support in TF-M. It completes platform
+specific mailbox initialization, including receiving the the address of NSPE
+mailbox queue and Inter-Processor Communication initialization.
+
+.. code-block:: c
+
+ int32_t tfm_mailbox_hal_init(struct secure_mailbox_queue_t *s_queue);
+
+**Parameters**
+
++-------------+----------------------------------------+
+| ``s_queue`` | The base address of SPE mailbox queue. |
++-------------+----------------------------------------+
+
+**Return**
+
++---------------------+-------------------------------------------+
+| ``MAILBOX_SUCCESS`` | Initialization succeeds. |
++---------------------+-------------------------------------------+
+| Other return codes | Initialization failed with an error code. |
++---------------------+-------------------------------------------+
+
+``tfm_mailbox_hal_enter_critical()``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This function enters the critical section of NSPE mailbox queue access in SPE.
+
+.. code-block:: c
+
+ void tfm_mailbox_hal_enter_critical(void);
+
+**Usage**
+
+SPE mailbox invokes ``tfm_mailbox_hal_enter_critical()`` before entering
+critical section of NSPE mailbox queue.
+``tfm_mailbox_hal_enter_critical()`` implementation is platform specific.
+
+``tfm_mailbox_hal_enter_critical()`` can be called in an interrupt service
+routine.
+
+``tfm_mailbox_hal_exit_critical()``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This function exits from the critical section of NSPE mailbox queue access in
+SPE.
+
+.. code-block:: c
+
+ void tfm_mailbox_hal_exit_critical(void);
+
+**Usage**
+
+SPE mailbox invokes ``tfm_mailbox_hal_exit_critical()`` when exiting from
+critical section of NSPE mailbox queue.
+``tfm_mailbox_hal_exit_critical()`` implementation is platform specific.
+
+``tfm_mailbox_hal_exit_critical()`` can be called in an interrupt service
+routine.
+
+*********
+Reference
+*********
+
+.. [1] :doc:`Communication prototype between NSPE and SPE in Dual-core systems <./communication_prototype_between_nspe_and_spe_in_dual_core_systems>`
+
+.. [2] :doc:`Booting a Dual-core system <booting_a_dual_core_system>`
+
+--------------------
+
+*Copyright (c) 2019-2021 Arm Limited. All Rights Reserved.*
+*Copyright (c) 2022 Cypress Semiconductor Corporation. All rights reserved.*
diff --git a/docs/design_docs/dual-cpu/tfm_multi_core_access_check.rst b/docs/design_docs/dual-cpu/tfm_multi_core_access_check.rst
new file mode 100644
index 0000000..f8f33f1
--- /dev/null
+++ b/docs/design_docs/dual-cpu/tfm_multi_core_access_check.rst
@@ -0,0 +1,512 @@
+################################################################
+Memory Access Check of Trusted Firmware-M in Multi-Core Topology
+################################################################
+
+:Author: David Hu
+:Organization: Arm Limited
+:Contact: david.hu@arm.com
+
+************
+Introduction
+************
+
+TF-M memory access check functions ``tfm_core_has_read_access_to_region()`` and
+``tfm_core_has_write_access_to_region()`` check whether an access has proper
+permission to read or write the target memory region.
+
+On single Armv8-M core platform, TF-M memory access check implementation relies
+on `Armv8-M Security Extension`_ (CMSE) intrinsic
+``cmse_check_address_range()``.
+The secure core may not implement CMSE on multi-core platforms. Even if CMSE is
+implemented on a multi-core platform, additional check on system-level security
+and memory access management units are still necessary since CMSE intrinsics and
+TT instructions are only aware of MPU/SAU/IDAU inside the core.
+
+As a result, TF-M in multi-core topology requires a dedicated access check
+process which can work without CMSE support. This document discuss about the
+design of the memory access check in multi-core topology.
+
+.. _Armv8-M Security Extension: https://developer.arm.com/architectures/cpu-architecture/m-profile/docs/100720/0100/secure-software-guidelines/armv8m-security-extension
+
+**************
+Overall Design
+**************
+
+Memory Access Check Policy
+==========================
+
+The policies vary in diverse Isolation Levels.
+
+When TF-M works in Isolation Level 1, the access check in multi-core topology
+checks
+
+- Memory region is valid according to system settings
+- Non-secure client call request should not access secure memory.
+- Secure services should not directly access non-secure memory. According to PSA
+ Firmware Framework, Secure services should call Secure Partition APIs to ask
+ TF-M SPM to fetch non-secure input/output buffer for them.
+- Whether read/write attribute match between access and memory region
+
+When TF-M works in Isolation Level 2, the access check in multi-core topology
+checks:
+
+- Memory region is valid according to system settings
+- Non-secure client call request should not access secure memory.
+- Secure services should not directly access non-secure memory. According to PSA
+ Firmware Framework, Secure services should call Secure Partition APIs to ask
+ TF-M SPM to fetch non-secure input/outputs buffer for them.
+- Whether read/write attribute match between access and memory region
+- Unprivileged secure access should not access privileged secure memory region
+
+The check policy in Isolation Level 3 will be defined according to TF-M future
+implementation.
+
+The above policies will be adjusted according to TF-M implementation and PSA
+specs.
+
+General Check Process in TF-M Core
+==================================
+
+In multi-core topology, ``tfm_core_has_read_access_to_region()`` and
+``tfm_core_has_write_access_to_region()`` are still invoked to keep an uniform
+interface to TF-M Core/SPM.
+
+Multi-core topology specific implementations of
+``tfm_core_has_read_access_to_region()`` and
+``tfm_core_has_write_access_to_region()`` are similar to those in single Armv8-M
+scenario.
+Both functions set corresponding flags according to the parameters and
+invoke static function ``has_access_to_region()`` to execute the check process.
+Both implementations should be placed in multi-core topology specific files
+separated from single Armv8-M access check.
+
+A reference code of ``tfm_core_has_read_access_to_region()`` implementation is
+shown below.
+
+.. code-block:: c
+
+ int32_t tfm_core_has_read_access_to_region(const void *p, size_t s,
+ bool ns_caller,
+ uint32_t privileged)
+ {
+ uint8_t flags = MEM_CHECK_MPU_READ;
+
+ if (privileged == TFM_PARTITION_UNPRIVILEGED_MODE) {
+ flags |= MEM_CHECK_MPU_UNPRIV;
+ }
+
+ if (ns_caller) {
+ flags |= MEM_CHECK_NONSECURE;
+ }
+
+ return has_access_to_region(p, s, flags);
+ }
+
+
+A reference code of ``tfm_core_has_write_access_to_region()`` implementation is
+shown below.
+
+.. code-block:: c
+
+ int32_t tfm_core_has_write_access_to_region(void *p, size_t s,
+ bool ns_caller,
+ uint32_t privileged)
+ {
+ uint8_t flags = MEM_CHECK_MPU_READWRITE;
+
+ if (privileged == TFM_PARTITION_UNPRIVILEGED_MODE) {
+ flags |= MEM_CHECK_MPU_UNPRIV;
+ }
+
+ if (ns_caller) {
+ flags |= MEM_CHECK_NONSECURE;
+ }
+
+ return has_access_to_region(p, s, flags);
+ }
+
+
+The flags ``MEM_CHECK_MPU_READ``, ``MEM_CHECK_MPU_UNPRIV``,
+``MEM_CHECK_MPU_READWRITE`` and ``MEM_CHECK_NONSECURE`` above will be described
+in the section `Access Permission Flags`_.
+
+The prototype of static function ``has_access_to_region()`` follows that in
+single Armv8-M. The multi-core topology specific ``has_access_to_region()``
+executes a general process to check if the access can access the target region.
+
+During the check process, ``has_access_to_region()`` invokes three HAL APIs
+``tfm_spm_hal_get_mem_security_attr()``, ``tfm_spm_hal_get_ns_access_attr()``
+and ``tfm_spm_hal_get_secure_access_attr()`` to retrieve the attributes of
+target memory region. ``has_access_to_region()`` compares the access permission
+with memory region attributes and determines whether the access is allowed to
+access the region according to policy described in `Memory Access Check Policy`_
+above.
+
+| ``tfm_spm_hal_get_mem_security_attr()`` retrieves the security attributes of
+ the target memory region.
+| ``tfm_spm_hal_get_secure_access_attr()`` retrieves secure access attributes of
+ the target memory region.
+| ``tfm_spm_hal_get_ns_access_attr()`` retrieves non-secure access attributes of
+ the target memory region.
+| All three functions are implemented by multi-core platform support. The
+ definitions are specified in the section `HAL APIs`_ below.
+
+The pseudo code of ``has_access_to_region()`` is shown below.
+
+.. code-block:: c
+ :linenos:
+ :emphasize-lines: 19,36,46
+
+ static int32_t has_access_to_region(const void *p, size_t s, uint8_t flags)
+ {
+ struct security_attr_info_t security_attr;
+ struct mem_attr_info_t mem_attr;
+
+ /* The memory access check should be executed inside TF-M PSA RoT */
+ if (not in privileged level) {
+ abort;
+ }
+
+ if (memory region exceeds memory space limitation) {
+ return TFM_ERROR_GENERIC;
+ }
+
+ /* Set initial value */
+ security_attr_init(&security_attr);
+
+ /* Retrieve security attributes of memory region */
+ tfm_spm_hal_get_mem_security_attr(p, s, &security_attr);
+
+ if (!security_attr.is_valid) {
+ /* Invalid memory region */
+ return TFM_ERROR_GENERIC;
+ }
+
+ /* Compare according to current Isolation Level */
+ if (Parameter flags mismatch security attributes) {
+ return TFM_ERROR_GENERIC;
+ }
+
+ /* Set initial value */
+ mem_attr_init(&mem_attr);
+
+ if (security_attr.is_secure) {
+ /* Retrieve access attributes of secure memory region */
+ tfm_spm_hal_get_secure_access_attr(p, s, &mem_attr);
+
+ if (Not in Isolation Level 1) {
+ /* Secure MPU must be enabled in Isolation Level 2 and 3 */
+ if (!mem_attr->is_mpu_enabled) {
+ abort;
+ }
+ }
+ } else {
+ /* Retrieve access attributes of non-secure memory region. */
+ tfm_spm_hal_get_ns_access_attr(p, s, &mem_attr);
+ }
+
+ if (!mem_attr.is_valid) {
+ /* Invalid memory region */
+ return TFM_ERROR_GENERIC;
+ }
+
+ /*
+ * Compare according to current Isolation Level and non-secure/secure
+ * access.
+ */
+ if (access flags matches MPU attributes) {
+ return TFM_SUCCESS;
+ }
+
+ return TFM_ERROR_GENERIC;
+ }
+
+.. note::
+ It cannot be guaranteed that TF-M provides a comprehensive memory access
+ check on non-secure memory for NSPE client call If non-secure memory
+ protection or isolation is required in a multi-core system, NSPE software
+ should implement and execute the check functionalities in NSPE, rather than
+ relying on TF-M access check.
+
+ For example, all the access from NSPE client calls to non-secure memory are
+ classified as unprivileged in current TF-M implementation. Multi-core access
+ check may skip the privileged/unprivileged permission check for non-secure
+ access.
+
+ If a multi-core system enforces the privileged/unprivileged isolation and
+ protection of non-secure area, NSPE software should execute the corresponding
+ check functionalities before submitting the NSPE client call request to SPE.
+
+
+*******************
+Data Types and APIs
+*******************
+
+Data Types
+==========
+
+Access Permission Flags
+-----------------------
+
+The following flags are defined to indicate the access permission attributes.
+Each flag is mapped to the corresponding CMSE macro. Please refer to
+`ARMv8-M Security Extensions: Requirements on Development Tools
+<http://infocenter.arm.com/help/topic/com.arm.doc.ecm0359818/ECM0359818_armv8m_security_extensions_reqs_on_dev_tools_1_0.pdf>`_
+for details of each CMSE macro.
+
+``MEM_CHECK_MPU_READWRITE``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Mapped to CMSE macro ``CMSE_MPU_READWRITE`` to indicate that the access requires
+both read and write permission to the target memory region.
+
+.. code-block:: c
+
+ #define MEM_CHECK_MPU_READWRITE (1 << 0x0)
+
+
+``MEM_CHECK_MPU_UNPRIV``
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+Mapped to CMSE macro ``CMSE_MPU_UNPRIV`` to indicate that it is an unprivileged
+access.
+
+.. code-block:: c
+
+ #define MEM_CHECK_MPU_UNPRIV (1 << 0x2)
+
+
+``MEM_CHECK_MPU_READ``
+^^^^^^^^^^^^^^^^^^^^^^
+
+Mapped to CMSE macro ``CMSE_MPU_READ``. It indicates that it is a read-only
+access to target memory region.
+
+.. code-block:: c
+
+ #define MEM_CHECK_MPU_READ (1 << 0x3)
+
+
+``MEM_CHECK_NONSECURE``
+^^^^^^^^^^^^^^^^^^^^^^^
+
+Mapped to CSME macro ``CMSE_NONSECURE`` to indicate that it is a access from
+non-secure client call request.
+If this flag is unset, it indicates the access is required from SPE.
+
+.. code-block:: c
+
+ #define MEM_CHECK_AU_NONSECURE (1 << 0x1)
+ #define MEM_CHECK_MPU_NONSECURE (1 << 0x4)
+ #define MEM_CHECK_NONSECURE (MEM_CHECK_AU_NONSECURE | \
+ MEM_CHECK_MPU_NONSECURE)
+
+
+Security Attributes Information
+-------------------------------
+
+The structure ``security_attr_info_t`` contains the security attributes
+information of the target memory region.
+``tfm_spm_hal_get_mem_security_attr()`` implementation should fill the structure
+fields according to the platform specific secure isolation setting.
+
+.. code-block:: c
+
+ struct security_attr_info_t {
+ bool is_valid;
+ bool is_secure;
+ };
+
+| ``is_valid`` indicates whether the target memory region is valid according to
+ platform resource assignment and security isolation configurations.
+| ``is_secure`` indicates the target memory region is secure or non-secure. The
+ value is only valid when ``is_valid`` is ``true``.
+
+
+Memory Attributes Information
+-----------------------------
+
+The structure ``mem_attr_info_t`` contains the memory access attributes
+information of the target memory region.
+``tfm_spm_hal_get_secure_access_attr()`` and
+``tfm_spm_hal_get_ns_access_attr()`` implementations should fill the structure
+fields according to the memory protection settings.
+
+.. code-block:: c
+
+ struct mem_attr_info_t {
+ bool is_mpu_enabled;
+ bool is_valid;
+ bool is_xn;
+ bool is_priv_rd_allow;
+ bool is_priv_wr_allow;
+ bool is_unpriv_rd_allow;
+ bool is_unpriv_wr_allow;
+ };
+
+| ``is_mpu_enabled`` indicates whether the MPU and other management unit are
+ enabled and work normally.
+| ``is_valid`` indicates whether the target memory region is valid according to
+ platform resource assignment and memory protection configurations.
+| ``is_xn`` indicates whether the target memory region is Execute Never. This
+ field is only valid when ``is_valid`` is ``true``.
+| ``is_priv_rd_allow`` and ``is_priv_wr_allow`` indicates whether the target
+ memory region allows privileged read/write. Both the fields are valid only
+ when ``is_valid`` is ``true``.
+| ``is_unpriv_rd_allow`` and ``is_unpriv_wr_allow`` indicates whether the target
+ memory region allows unprivileged read/write. Both the fields are valid only
+ when ``is_valid`` is ``true``.
+
+
+HAL APIs
+========
+
+``tfm_spm_hal_get_mem_security_attr()``
+---------------------------------------
+
+``tfm_spm_hal_get_mem_security_attr()`` retrieves the current active security
+configuration information and fills the ``security_attr_info_t``.
+
+.. code-block:: c
+
+ void tfm_spm_hal_get_mem_security_attr(const void *p, size_t s,
+ struct security_attr_info_t *p_attr);
+
++--------------------------------------------------------------------+
+|**Paramters** |
++-------------+------------------------------------------------------+
+|``p`` |Base address of the target memory region |
++-------------+------------------------------------------------------+
+|``s`` |Size of the target memory region |
++-------------+------------------------------------------------------+
+|``p_attr`` |Pointer to the ``security_attr_info_t`` to be filled |
++-------------+------------------------------------------------------+
+|**Return** |
++-------------+------------------------------------------------------+
+|``void`` |None |
++-------------+------------------------------------------------------+
+
+The implementation should be decoupled from TF-M current isolation level or
+access check policy.
+
+All the fields in ``security_attr_info_t`` should be explicitly set in
+``tfm_spm_hal_get_mem_security_attr()``.
+
+If the target memory region crosses boundaries of different security regions or
+levels in security isolation configuration,
+``tfm_spm_hal_get_mem_security_attr()`` should determine whether the memory
+region violates current security isolation.
+It is recommended to mark the target memory region as invalid in such case, even
+if the adjoining regions or levels may have the same security configuration.
+
+If the target memory region is not explicitly specified in memory security
+configuration, ``tfm_spm_hal_get_mem_security_attr()`` can return the following
+values according to actual use case:
+
+- Either set ``is_valid = false``
+- Or set ``is_valid = true`` and set ``is_secure`` according to platform
+ specific policy.
+
+
+``tfm_spm_hal_get_secure_access_attr()``
+----------------------------------------
+
+``tfm_spm_hal_get_secure_access_attr()`` retrieves the secure memory protection
+configuration information and fills the ``mem_attr_info_t``.
+
+.. code-block:: c
+
+ void tfm_spm_hal_get_secure_access_attr(const void *p, size_t s,
+ struct mem_attr_info_t *p_attr);
+
++--------------------------------------------------------------------+
+|**Paramters** |
++-------------+------------------------------------------------------+
+|``p`` |Base address of the target memory region |
++-------------+------------------------------------------------------+
+|``s`` |Size of the target memory region |
++-------------+------------------------------------------------------+
+|``p_attr`` |Pointer to the ``mem_attr_info_t`` to be filled |
++-------------+------------------------------------------------------+
+|**Return** |
++-------------+------------------------------------------------------+
+|``void`` |None |
++-------------+------------------------------------------------------+
+
+The implementation should be decoupled from TF-M current isolation level or
+access check policy.
+
+All the fields in ``mem_attr_info_t`` should be explicitly set in
+``tfm_spm_hal_get_secure_access_attr()``, according to current active memory
+protection configuration. It is recommended to retrieve the attributes from
+secure MPU and other hardware memory protection unit(s). But the implementation
+can be simplified by checking system-level memory region layout setting.
+
+If the target memory region is not specified in current active secure memory
+protection configuration, ``tfm_spm_hal_get_secure_access_attr()`` can select
+the following values according to actual use case.
+
+- Either directly set ``is_valid`` to ``false``
+- Or set ``is_valid`` to ``true`` and set other fields according to other memory
+ assignment information, such as system-level memory region layout.
+
+If secure memory protection unit(s) is *disabled* and the target memory
+region is a valid area according to platform resource assignment,
+``tfm_spm_hal_get_secure_access_attr()`` must set ``is_mpu_enabled`` to
+``false`` and set other fields according to current system-level memory region
+layout.
+
+
+``tfm_spm_hal_get_ns_access_attr()``
+------------------------------------
+
+``tfm_spm_hal_get_ns_access_attr()`` retrieves the non-secure memory protection
+configuration information and fills the ``mem_attr_info_t``.
+
+.. code-block:: c
+
+ void tfm_spm_hal_get_ns_access_attr(const void *p, size_t s,
+ struct mem_attr_info_t *p_attr);
+
++--------------------------------------------------------------------+
+|**Paramters** |
++-------------+------------------------------------------------------+
+|``p`` |Base address of the target memory region |
++-------------+------------------------------------------------------+
+|``s`` |Size of the target memory region |
++-------------+------------------------------------------------------+
+|``p_attr`` |Pointer to the ``mem_attr_info_t`` to be filled |
++-------------+------------------------------------------------------+
+|**Return** |
++-------------+------------------------------------------------------+
+|``void`` |None |
++-------------+------------------------------------------------------+
+
+The implementation should be decoupled from TF-M current isolation level or
+access check policy.
+
+Since non-secure core runs asynchronously, the non-secure MPU setting may be
+modified by NSPE OS and the attributes of the target memory region can be
+unavailable during ``tfm_spm_hal_get_ns_access_attr()`` execution in TF-M.
+When the target memory region is not specified in non-secure MPU,
+``tfm_spm_hal_get_ns_access_attr()`` can set the fields according to other
+memory setting information, such as system-level memory region layout.
+
+If non-secure memory protection unit(s) is *disabled* and the target memory
+region is a valid area according to platform resource assignment,
+``tfm_spm_hal_get_ns_access_attr()`` can set the following fields in
+``mem_attr_info_t`` to default values:
+
+- ``is_mpu_enabled = false``
+- ``is_valid = true``
+- ``is_xn = true``
+- ``is_priv_rd_allow = true``
+- ``is_unpriv_rd_allow = true``
+
+``is_priv_wr_allow`` and ``is_unpriv_wr_allow`` can be set according to current
+system-level memory region layout, such as whether it is in code section or data
+section.
+
+--------------
+
+*Copyright (c) 2019-2020, Arm Limited. All rights reserved.*
diff --git a/docs/design_docs/enum_implicit_casting.rst b/docs/design_docs/enum_implicit_casting.rst
new file mode 100644
index 0000000..3c1e453
--- /dev/null
+++ b/docs/design_docs/enum_implicit_casting.rst
@@ -0,0 +1,189 @@
+################################################
+Fixing implicit casting for C enumeration values
+################################################
+
+:Author: Hugues de Valon
+:Organization: Arm Limited
+:Contact: hugues.devalon@arm.com
+
+********
+Abstract
+********
+
+C enumerations provide a nice way to increase readability by creating new
+enumerated types but the developer should take extra care when mixing
+enumeration and integer values.
+This document investigates C enumerations safety and proposes strategies on how
+to fix the implicit casting of the enumeration values of TF-M with other types.
+
+**************************
+C99 Standard point of view
+**************************
+
+In TF-M many implicit casts are done between integer types (``uint32_t``,
+``int32_t``, ``size_t``, etc), enumerated types (``enum foobar``) and
+enumeration constants (``FOOBAR_ENUM_1``).
+
+According to the C99 standard [1]_:
+
+ **§6.2.5, 16**:
+ An enumeration comprises a set of named integer constant values. Each
+ distinct enumeration constitutes a different numerated type.
+
+ **§6.7.2.2, 2**:
+ The expression that defines the value of an enumeration constant shall be an
+ integer constant expression that has a value representable as an int.
+
+ **§6.7.2.2, 3**:
+ The identifiers in an enumerator list are declared as constants that have
+ type int and may appear wherever such are permitted.
+
+ **§6.7.2.2, 4**:
+ Each enumerated type shall be compatible with char, a signed integer type,
+ or an unsigned integer type. The choice of type is implementation-defined,
+ but shall be capable of representing the values of all the members of the
+ enumeration.
+
+From these four quotes from the C99 standard [1]_, the following conclusions can
+be made:
+
+* an enumeration defines a new type and should be treated as such
+* the enumeration constants must only contains value representable as an ``int``
+* the enumeration constants have type ``int``
+* the actual type of the enumeration can be between ``char``, signed and
+ unsigned ``int``. The compiler chooses the type it wants among those that can
+ represent all declared constants of the enumeration.
+
+Example::
+
+ enum french_cities {
+ MARSEILLE,
+ PARIS,
+ LILLE,
+ LYON
+ };
+
+In that example, ``MARSEILLE``, ``PARIS``, ``LILLE`` and ``LYON`` are
+enumeration constants of type ``int`` and ``enum french_cities`` is a enumerated
+type which can be of actual type ``char``, ``unsigned int`` or ``int``
+(the compiler chooses!).
+
+For these reasons, doing an implicit cast between an enumeration and another
+type is the same as doing an implicit cast between two different types. From a
+defensive programming point of view, it should be checked that the destination
+type can represent the values from the origin type. In this specific case it
+means four things for enumerations:
+
+* it is always safe to assign an enumeration constant to an int, but might be
+ better to cast to show intent.
+* when casting an enumeration constant to another type, it should be checked
+ that the constant can fit into the destination type.
+* when casting from an integer type (``uint32_t``, ``int32_t``, etc) to an
+ enumeration type, it should be checked that the integer's value is one of the
+ enumeration constants. The comparison needs to be done on the biggest type of
+ the two so that no information is lost. C integer promotion should
+ automatically do that for the programmer (check §6.3.1.8, 1 for the rules).
+* when casting from an enumeration type to an integer type, it should be checked
+ that the enumeration type value fits into the integer type. The value of a
+ variable which has the type of an enumeration type is not limited to the
+ enumeration constants of the type. An enumeration constant will always fit
+ into an ``int``.
+
+*****************
+Strategies to fix
+*****************
+
+0. Replace the enumerated type with an integer type and replace the enumeration
+ constant with preprocessor constants.
+1. Whenever possible, try to use matching types to avoid implicit casting.
+ It happens, for example, for arithmetic operations, function calls and
+ function returns. This strategy always have the lowest performance impact.
+2. When using an enumeration constant in an arithmetic operation with another
+ type, verify that the constant can fit in the other type and cast it.
+3. When converting an integer to an enumeration type, use a conversion function
+ to check if the integer matches an enumeration constant. To not impact
+ performance too much, this function should be an inline function. If it does
+ not match, use (or add) the error constant or return an error value.
+4. When converting an enumeration type to an integer, use a conversion function
+ to check that the integer type can contain the enumeration value.
+
+************************
+Design proposal for TF-M
+************************
+
+In TF-M, an action will be taken for all enumerated types and enumeration
+constants that are used for implicit casting. The goal of this proposal is to
+remove all implicit casting of enumeration values in TF-M.
+
+The following enumerated types will be removed and replaced with preprocessor
+constants (strategy 0). These enumerated types are not used in TF-M
+but only the constants they declare.
+
+* ``enum spm_part_state_t``
+* ``enum spm_part_flag_mask_t``
+* ``enum tfm_partition_priority``
+
+The following enumerated types will be kept because they are used in the
+prototypes of functions and are useful for debugging. Whenever possible,
+strategy 1 will be applied to remove implicit casting related with those
+enumerations but dynamic conversions will be used if the first option would
+create too much change in the code base.
+
+* ``enum tfm_status_e``: the return type of the following functions will be
+ changed to return the ``enum tfm_status_e`` type. These functions are already
+ returning the enumeration constants, but implicitly casted to an integer type
+ like ``int32_t``.
+
+ * ``int32_t check_address_range``
+ * ``int32_t has_access_to_region``
+ * ``int32_t tfm_core_check_sfn_parameters``
+ * ``int32_t tfm_start_partition``
+ * ``int32_t tfm_return_from_partition``
+ * ``int32_t tfm_check_sfn_req_integrity``
+ * ``int32_t tfm_core_check_sfn_req_rules``
+ * ``int32_t tfm_spm_sfn_request_handler``
+ * ``int32_t tfm_spm_sfn_request_thread_mode``
+* ``enum tfm_buffer_share_region_e``: the following function prototypes will be
+ changed:
+
+ * ``tfm_spm_partition_set_share(uint32_t partition_idx, uint32_t share)`` -> ``tfm_spm_partition_set_share(uint32_t partition_idx, enum tfm_buffer_share_region_e share)``
+* ``enum tfm_memory_access_e``
+* ``enum attest_memory_access_t``
+* ``enum engine_cipher_mode_t``
+* ``mbedtls_cipher_type_t``
+
+The following enumerated types are used for error code values of Secure service
+calls. They should be kept as they are part of the interface and might be used
+by external parties in Non-Secure code. For the Initial Attestation service,
+the enumeration is defined in the PSA Attestation API specifications.
+
+* ``enum psa_attest_err_t``
+* ``enum psa_audit_err``
+* ``enum tfm_platform_err_t``
+
+Implicit casting related with these enumerations is happening in two locations
+of TF-M and need conversion functions in those locations, because the types can
+not be changed:
+
+* In the Non-Secure Client library, all of the Secure Service functions
+ implicitly cast the ``uint32_t`` returned by ``tfm_ns_lock_dispatch`` to
+ these enumerated types. Strategy 3 is needed here.
+* In all of the veneer functions, there is an implicit cast from the ``int32_t``
+ value returned by the SVC request function (``tfm_core_*_request``) to these
+ enumerated types. Strategy 3 is needed here as well. The implicit cast will
+ eventually be removed if all of the services are using the Uniform Signatures
+ Prototypes so that the veneer functions all return ``psa_status_t`` which is
+ an ``int32_t``.
+
+If the interface of those services can be changed, these enumerations could be
+removed and replaced with the ``psa_status_t`` type to remove the implicit
+casting.
+
+.. [1] C99 standard: http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf
+
+
+--------------
+
+
+*Copyright (c) 2019-2020, Arm Limited. All rights reserved.*
+
diff --git a/docs/design_docs/ff_isolation.rst b/docs/design_docs/ff_isolation.rst
new file mode 100644
index 0000000..e637c65
--- /dev/null
+++ b/docs/design_docs/ff_isolation.rst
@@ -0,0 +1,416 @@
+##############
+FF-M Isolation
+##############
+
+:Organization: Arm Limited
+:Contact: tf-m@lists.trustedfirmware.org
+
+This document analyzes the isolation rules of implementing ``FF-M 1.0``
+isolation and introduces the reference implementation in TF-M, which
+complies the rules by operating the hardware and software resources.
+
+.. note::
+ Reference the document :doc:`Glossary </glossary>` for terms
+ and abbreviations.
+
+************
+Introduction
+************
+This chapter describes the definitions from ``FF-M`` and analyzes
+the possible implementation keypoints.
+
+Isolation Levels
+================
+There are 3 isolation levels (1-3) defined in ``FF-M``, the greater level
+number has more isolation boundaries.
+
+The definition for Isolation Level 1:
+
+- L1.1 NPSE needs protection from nobody.
+- L1.2 SPE needs protection from NSPE.
+
+The definition for Isolation Level 2:
+
+- L2.1 NPSE needs protection from nobody.
+- L2.2 Application Root of Trust (ARoT) needs protection from NSPE.
+- L2.3 PSA Root of Trust (PRoT) needs protection from NSPE and ARoT.
+
+The definition for Isolation Level 3:
+
+- L3.1 NPSE needs protection from nobody.
+- L3.2 Secure Partition needs protection from NSPE and other Secure Partitions.
+- L3.3 PSA Root of Trust (RoT) domain needs protection from NSPE and all Secure
+ Partitions.
+
+.. important::
+ A Secure Partition RoT Service is a Root of Trust Service implemented within
+ a Secure Partition. An Application RoT Service must be implemented as
+ a Secure Partition RoT Service. But it is implementation-defined whether a
+ PSA RoT Service is a Secure Partition RoT Service.
+
+ Here listed several possible PSA RoT Service implementation mechanisms:
+
+ 1. Implement PSA RoT Services in Secure Partitions with respective
+ boundaries.
+ 2. Implement PSA RoT Services in Secure Partitions, but no boundaries between
+ these Secure Partitions as they are in the PSA RoT Domain.
+ 3. Implement PSA RoT Services in a customized way instead of Secure
+ Partitions, an internal library of PSA RoT domain e.g.
+
+ TF-M chooses the 2nd option to balance performance and complexity.
+
+Isolation Rules
+===============
+The essence of isolation is to protect the assets of one protection domain from
+being accessed from other domains. The isolation levels define where the
+isolation boundaries should be placed, the isolation rules define the strength
+of the isolation the boundaries should offer.
+
+.. note::
+ Refer to chapter `Memory Assets` in `Firmware Framework for M (FF-M)`_ to
+ know asset class items. Assets are represented by memory addresses in the
+ system memory map, which makes assets named `Memory Assets`. The often-seen
+ asset items are ROM, RAM, and memory-mapped peripherals.
+
+Memory Asset Class
+------------------
+There are 3 memory asset classes defined in `Firmware Framework for M (FF-M)`_:
+
+- Code
+- Constant data
+- Private data
+
+There are 6 isolation rules for protecting assets. Here lists the simplified
+description for the rules, check chapter ``3.1.2`` of ``FF-M 1.0`` for the
+original description:
+
+- I1. Only Code is executable.
+- I2. Only private data is writable.
+- I3. If domain A needs protection from domain B, then Private data in domain A
+ cannot be accessed by domain B.
+- I4. (Optional) If domain A needs protection from domain B, then Code and
+ Constant data in domain A is not readable or executable by domain B.
+- I5. (Optional) Code in a domain is not executable by any other domain.
+- I6. (Optional) All assets in a domain are private to that domain and cannot be
+ accessed by any other domain, with the following exception:
+ The domain containing the SPM can only access Private data and Constant data
+ assets of other domains when required to implement the PSA Firmware Framework
+ API.
+- I7. (Optional, added in FF-M 1.1) Constant data is not executable.
+
+ The first 3 rules from ``I1`` to ``I3`` defines the mandatory rules to comply
+ the isolation, while ``I4`` to ``I6`` are optional rules to enhance the
+ isolation boundaries.
+
+ .. important::
+ There is a table in the chapter ``3.1.2`` of ``FF-M 1.0`` under ``I1`` lists
+ the asset types and allowed access method. Preventing executable access on
+ constant data costs more hardware resources, so there is an optional rule
+ I7 created in `FF-M Extensions (FF-M 1.1)`_ to comfort implementations with
+ constrained hardware resources.
+
+Hardware Infrastructure
+=======================
+To implement a secure system, the hardware security framework (TrustZone or
+multiple-core e.g.) and their auxiliary components (SAU e.g.) are required
+to ensure the isolation between SPE and NSPE. The requirements:
+
+.. important::
+ The interface between secure and non-secure states needs to be fully
+ enumerated and audited to prove the integrity of the secure state
+ isolation.
+
+Besides this SPE and NSPE isolation mechanism, the following analyzes the
+implementation rules to find out the hardware requirements for isolation inside
+SPE domains:
+
+- I1 and I2: The assets can be categorized into 3 `Memory Asset Class`_, each
+ type has the specific access rules.
+- I3: The private data access from the prevented domain needs to be blocked.
+- I4: All the assets access from the prevented domain needs to be blocked.
+- I5: Code execution from all other domains (even the domain not prevented
+ from) needs to be blocked.
+- I6: All the assets access from all other domains (includes non-prevented
+ domain) needs to be blocked, but, SPM is an exception, which can access the
+ private data and constant data of the current domain.
+
+The above items list the requirements for memory access, here are two more
+points:
+
+- If the memory device or the peripheral are shared between multiple hosts
+ (Such as multiple CPU or DMA, etc), specific hardware protection units need
+ to be available for validating accesses to that device or peripheral.
+- The MMIO range for Secure Partitions is not allowed to be overlapped, which
+ means each partition should have exclusive memory-mapped region if they
+ require a peripheral device. The memory-mapped region is regarded as
+ the private data so access to this area needs to be validated.
+
+************************
+Reference Implementation
+************************
+This chapter describes the isolation implementation inside SPE by using the
+Armv8m architecture component - Memory Protection Unit (MPU). The MPU can
+isolate CPU execution and data access.
+
+.. note::
+ Previous version M-profile architecture MPU setting is similar in concept but
+ the difference in practical register formats, which is not described in this
+ document.
+
+The MPU protects memory assets by regions. Each region represents a memory
+range with specific access attributes.
+
+.. note::
+ The maximum numbers of MPU regions are platform-specific.
+
+The SPM is running under the privileged mode for handling access from services.
+The MPU region for SPM needs to be available all the time since SPM controls
+the MPU setting while scheduling.
+
+Since partitions are scheduled by SPM, the MPU regions corresponding to the
+partitions can be configured dynamically while scheduling. Since there is only
+one running at a time and all others are deactivated, the SPM needs to set up
+necessary regions for each asset type in one partition only.
+
+There is re-usable code like the C-Runtime and RoT Service API which are same
+across different partitions. TF-M creates a Secure Partition Runtime Library
+(SPRTL) as a specific library shared by the Secure Partition. Please refer to
+:doc:`Secure Partition Runtime Library <tfm_secure_partition_runtime_library>`
+for more detail.
+
+.. note::
+ Enable SPRTL makes it hard to comply with the rules I4, I5 and I6,
+ duplicating the library code can be one solution but it is not "shared"
+ library anymore.
+
+As mentioned in the last chapter, MMIO needs extra MPU regions as private data.
+
+MPU Region Access Permission
+============================
+The following content would mention the memory access permission to represent
+the corresponded asset classes.
+
+These access permissions are available on Armv8m MPU:
+
+- Privileged Read-Only (RO)
+- All RO
+- Privileged Read-Write (RW)
+- All RW
+- Execution Never (XN)
+
+And one more Armv8.1M access permssion:
+
+- Privileged Execution Never (PXN)
+
+The available regions type list:
+
+======== =========== =============== ========================================
+Type Attributes Privilege Level Asset
+======== =========== =============== ========================================
+P_RO RO Privileged PRoT Code
+P_ROXN RO + XN Privileged PRoT Constant Data
+P_RWXN RW + XN Privileged PRoT Private Data/Peripheral
+A_RO RO Any privilege Partition/SPRTL Code
+A_ROXN RO + XN Any privilege Partition/SPRTL Constant Data
+A_RWXN RW + XN Any privilege Partition/SPRTL Private Data/Peripheral
+A_ROPXN RO + PXN Any privilege Armv8.1M Partition/SPRTL Code
+======== =========== =============== ========================================
+
+Example Image Layout
+====================
+The secure firmware image contains components such as partitions, SPM and the
+shared code and data. Each component may have different class assets. There
+would be advantages if placing the assets from all components with the same
+access attributes into one same region:
+
+- The data relocating or clearing when booting can be done in one step instead
+ of breaking into fragments.
+- Assets with statically assigned access attribute can share the same MPU
+ region which saves regions.
+
+Take the TF-M existing implementation image layout as an example::
+
+ Level 1 Level 2 Level 3
+ Boundaries Boundaries Boundaries
+ +------------+----------+------------------------------------+
+ | | | PRoT SPM Code |
+ | | PRoT +------------------------------------+
+ | | Code | PRoT Service Code |
+ | Code +----------+------------------------------------+
+ | (ROM) | | Partition 1 Code |
+ | | +------------------------------------+
+ | | ARoT | Partition N Code |
+ | | Code +------------------------------------+
+ | | | SPRTL Code |
+ +------------+----------+------------------------------------+
+ Check [4] for more details between Code and Constant Data.
+ +------------+----------+------------------------------------+
+ | | PRoT | PRoT SPM Constant Data |
+ | | Constant +------------------------------------+
+ | | Data | PRoT Service Constant Data |
+ | Constant +----------+------------------------------------+
+ | Data | ARoT | Partition 1 Constant Data |
+ | (ROM) | Constant +------------------------------------+
+ | | Data | Partition N Constant Data |
+ | | +------------------------------------+
+ | | | SPRTL Constant Data |
+ +------------+----------+------------------------------------+
+
+ +------------+----------+------------------------------------+
+ | | PRoT | PRoT SPM Private Data |
+ | | Private +------------------------------------+
+ | | Data | PRoT Service Private Data |
+ | Private +----------+------------------------------------+
+ | Data | | Partition 1 Private Data |
+ | (RAM) | ARoT +------------------------------------+
+ | | Private | Partition N Private Data |
+ | | Data +------------------------------------+
+ | | | SPRTL Private Data |
+ +------------+----------+------------------------------------+
+
+.. note::
+ 1. Multiple binaries image implementation could also reference this layout if
+ its hardware protection unit can cover the exact boundaries mentioned
+ above.
+ 2. Private data includes both initialized and non-initialized (ZI) sections.
+ Check chapter ``3.1.1`` of ``FF-M`` for the details.
+ 3. This diagram shows the boundaries but not orders. The order of regions
+ inside one upper region can be adjusted freely.
+ 4. As described in the ``important`` of `Memory Asset Class`_, the setting
+ between Code and Constant Data can be skipped if the executable access
+ method is not applied to constant data. In this case, the groups of Code
+ and Constant Data can be combined or even mixed -- but the boundary
+ between PRoT and ARoT are still required under level higher than 1.
+
+Example Region Numbers under Isolation Level 3
+==============================================
+The following table lists the required regions while complying the rules for
+implementing isolation level 3. The level 1 and level 2 can be exported by
+simplifying the items in level 3 table.
+
+.. important::
+ The table described below is trying to be shared between all supported
+ platforms in Trusted Firmware - M. It is obvious that some platforms have
+ special characteristics. In that case, the specific layout table for a
+ particular platform can be totally redesigned but need to fulfil the
+ isolation level requirements.
+
+- Care only the running partitions assets since deactivated partition does not
+ need regions.
+- `X` indicates the existence of this region can't comply with the rule.
+- An `ATTR + n` represent extra ``n`` regions are necessary.
+- Here assumes the rules with a greater number covers the requirements in the
+ rules with less number.
+
+Here lists the required regions while complying with the rules:
+
++------------------+-------------+-------------+-------------+-------------+
+| Region Purpose | I1 I2 I3 | I4 | I5 | I6 |
++==================+=============+=============+=============+=============+
+| PRoT SPM Code | A_RO | P_RO | P_RO | P_RO |
++------------------+ | | +-------------+
+| PRoT Service Code| | | | A_ROPXN |
++------------------+ +-------------+-------------+ |
+| Active Partition | | A_RO | A_ROPXN | |
+| Code | | | | |
++------------------+ +-------------+-------------+-------------+
+| SPRTL Code | | ``X`` | ``X`` | ``X`` |
++------------------+-------------+-------------+-------------+-------------+
+| PRoT SPM RO | A_ROXN | P_ROXN | P_ROXN | P_ROXN |
++------------------+ | | +-------------+
+| PRoT Service RO | | | | A_ROXN |
++------------------+ +-------------+-------------+ |
+| Active Partition | | A_ROXN | A_ROXN | |
+| RO | | | | |
++------------------+ +-------------+-------------+-------------+
+| SPRTL RO | | ``X`` | ``X`` | ``X`` |
++------------------+-------------+-------------+-------------+-------------+
+| PRoT SPM RW | P_RWXN | P_RWXN | P_RWXN | P_RWXN |
++------------------+ | | +-------------+
+| PRoT Service RW | | | | A_RWXN |
++------------------+-------------+-------------+-------------+ |
+| Active Partition | A_RWXN | A_RWXN | A_RWXN | |
+| RW | | | | |
++------------------+-------------+-------------+-------------+-------------+
+| SPRTL RW [5] | A_RWXN + 1 | ``X`` | ``X`` | ``X`` |
++------------------+-------------+-------------+-------------+-------------+
+| Partition Peri | A_RWXN + n | A_RWXN + n | A_RWXN + n | A_RWXN + n |
++------------------+-------------+-------------+-------------+-------------+
+| Total Numbers | [1] | [2] | [3] | [4] |
++------------------+-------------+-------------+-------------+-------------+
+
+.. note::
+ 1. Total number = A_RO + A_ROXN + P_RWXN + A_RWXN + (1 + n)A_RWXN, while
+ n equals the maximum peripheral numbers needed by one partition. This is
+ the configuration chosen by the reference implementation.
+ 2. Total number = P_RO + P_ROXN + P_RWXN + A_RO + A_ROXN + (1 + n)A_RWXN,
+ the minimal result is `6`, and SPRTL can not be applied.
+ 3. Total number = P_RO + P_ROXN + P_RWXN + A_ROXN + (1 + n)A_RWXN +
+ A_ROPXN, the minimal result is `6`, SPRTL can not be applied, and PXN
+ is required.
+ 4. Total number = P_RO + P_ROXN + P_RWXN + A_ROXN + (1 + n)A_RWXN +
+ A_ROPXN, the minimal result is `6`, SPRTL can not be applied, and PXN
+ is required. To comply with this rule, the PSA RoT Service needs
+ to be implemented as Secure Partitions.
+ 5. This data belongs to SPRTL RW but it is set as Read-Only and only SPM
+ can update this region with the activate partition's metadata for
+ implementing functions with owner SP's context, such as heap functions.
+ This region can be skipped if there is no metadata required (such as no
+ heap functionalities required).
+
+ The memory-mapped regions for peripherals have different memory access
+ attributes in general, they are standalone regions in MPU even their
+ attributes covers 'A_RWXN'.
+
+.. important::
+ The default memory map grants PSA RoT domain components the ability to
+ access the place not covered in an explicitly defined region. This
+ characteristic can be used for saving regions. In the case when the default
+ memory map is applied, the uncovered regions need to be audited to make
+ sure all assets are placed properly.
+
+Interfaces
+==========
+The isolation implementation is based on the HAL framework. The SPM relies on
+the HAL API to perform the necessary isolation related operations.
+
+The requirement the software need to do are these:
+
+- Create enough isolation protection at the early stage of system booting, just
+ need to focus on the SPM domain.
+- Create an isolation domain between secure and non-secure before the jump to
+ the non-secure world.
+- Create an isolation domain for each Secure Partition after the Secure
+ Partition is loaded and before jumping to its entry point. The isolation
+ domain should cover all the assets of the Secure Partition, include all its
+ memory, interrupts, and peripherals.
+- Switch isolation domains when scheduling different Secure Partitions.
+- It is also a requirement that the platform needs to help to check if the
+ caller of the PSA APIs is permitted to access some memory ranges.
+
+
+The design document
+:doc:`TF-M Hardware Abstraction Layer <hardware_abstraction_layer>`
+gives a detail design, include the platform initialization, isolation
+interfaces. Please refer to it for more detail.
+
+Appendix
+========
+| `Firmware Framework for M (FF-M)`_
+
+.. _Firmware Framework for M (FF-M):
+ https://www.arm.com/architecture/security-features/platform-security
+
+| `FF-M Extensions (FF-M 1.1)`_
+
+.. _FF-M Extensions (FF-M 1.1):
+ https://developer.arm.com/documentation/aes0039/latest
+
+| `Trusted Base System Architecture for M (TBSA-M)`_
+
+.. _Trusted Base System Architecture for M (TBSA-M):
+ https://www.arm.com/architecture/security-features/platform-security
+
+--------------
+
+*Copyright (c) 2020-2022, Arm Limited. All rights reserved.*
diff --git a/docs/design_docs/hardware_abstraction_layer.rst b/docs/design_docs/hardware_abstraction_layer.rst
new file mode 100644
index 0000000..89b7092
--- /dev/null
+++ b/docs/design_docs/hardware_abstraction_layer.rst
@@ -0,0 +1,921 @@
+##########################
+Hardware Abstraction Layer
+##########################
+
+:Organization: Arm Limited
+:Contact: tf-m@lists.trustedfirmware.org
+
+:API Version: 0.9
+
+************
+Introduction
+************
+:term:`TF-M` :term:`HAL` abstracts the hardware-oriented and platform specific
+operations on the :term:`SPE` side and provides a set of APIs to the upper
+layers such as :term:`SPM`, :term:`RoT Service`.
+The :term:`HAL` aims to cover the platform different aspects whereas common
+architecturally defined aspects are done generically within the common
+:term:`SPE`.
+In some cases, although the operations are defined architecturally,
+it may not be possible to generalize implementations because lots of information
+is only known to platforms.
+It is more efficient to define a :term:`HAL` API for those architectural
+operations as well.
+
+.. note::
+ :term:`TBSA-M` provides the hardware requirements for security purposes.
+ :term:`TF-M` :term:`HAL` tries to reference :term:`TBSA-M` recommendations in
+ the interfaces from the software perspective only. Please reference
+ :term:`TBSA-M` for your security hardware design.
+
+Design Goals
+============
+:term:`TF-M` :term:`HAL` is designed to simplify the integration efforts on
+different platforms.
+
+:term:`TF-M` :term:`HAL` is designed to make it easy to use the hardware and
+develop the :term:`SPM` and :term:`RoT Service` which need to access the
+devices.
+
+:term:`TF-M` :term:`HAL` is designed to make the structure clearer and let the
+:term:`TF-M` mainly focus on :term:`PSA` implementation.
+
+********
+Overview
+********
+This section provides an overview of the abstraction layer structure.
+
+.. figure:: media/hal_structure.png
+
+Here lists a minimal set of necessary functionalities:
+
+ - **Isolation API**: Provides the necessary isolation functionalities required
+ by the :term:`PSA-FF-M` and :term:`TBSA-M`, and provides APIs to :term:`SPM`
+ to check the permissions of memory access.
+ - **Platform API**: Provides the platform initialization, platform-specific
+ memory information, system reset, etc.
+ - **Log dev API**: Provides the log system functions.
+ - **Interrupt API**: Provides the interrupt functions.
+
+.. note::
+ - There is a non-secure :term:`HAL` that focuses on the mailbox operation API
+ for Dual-core topology. For more information about it, please refer to
+ :doc:`Mailbox Design in TF-M on Dual-core System
+ </design_docs/dual-cpu/mailbox_design_on_dual_core_system>`.
+ - The minimal set of :term:`TF-M` :term:`HAL` is sufficient for Secure
+ Partitions by using customized peripheral interfaces. To provide easier
+ portability for the Secure Partitions, a Secure Partition :term:`HAL` is
+ provided in this design too.
+ - The debug mechanisms give the external entity the corresponding right to
+ access the system assets. :term:`TF-M` ensures that the external entity is
+ permitted access to those assets. Currently, :term:`TF-M` only needs the
+ debug authentication. The whole debug mechanism and related :term:`HAL` will
+ be enhanced in the future. Please refer to the :doc:`Debug authentication
+ settings section </integration_guide/platform/platform_folder>` for more
+ details.
+
+*****************
+Design Principles
+*****************
+As :term:`TF-M` runs on resource-constrained devices, the :term:`HAL` tries to
+avoid multiple level abstractions which cost more resources.
+
+Part of the :term:`HAL` interfaces does not focus on exact hardware operations
+such as power on/off or PIN manipulation.
+Instead, the :term:`HAL` abstracts higher-level interfaces to reserve the
+implementation flexibility for the platform vendors.
+
+The :term:`TF-M` :term:`HAL` should be easy to deprecate APIs and provide
+compatibilities.
+Any API incompatibility should be detected during building.
+
+:term:`TF-M` relies on the :term:`HAL` APIs to be implemented correctly and
+trusts the :term:`HAL` APIs.
+:term:`TFM` can provide assertions to detect common programming errors but
+essentially no further extensive checks will be provided.
+
+************
+Source Files
+************
+This section describes the source file of the :term:`TF-M` :term:`HAL`,
+including the header and c files.
+
+tfm_hal_defs.h
+==============
+This header file contains the definitions of common macros and types used by all
+:term:`HAL` APIs. Please refer to `Status Codes`_ for detailed definitions.
+
+tfm_hal_[module].[h/c]
+======================
+All other headers and c files are classified by the modules, such as isolation,
+platform, interrupt, devices, etc.
+
+.. note::
+ There are common files in the platform folder include the implemented
+ :term:`HAL` APIs. The platform vendors can use them directly but need to
+ implement all the sub APIs.
+
+************
+Status Codes
+************
+These are common status and error codes for all :term:`HAL` APIs.
+
+Types
+=====
+tfm_hal_status_t
+----------------
+This is a status code to be used as the return type of :term:`HAL` APIs.
+
+.. code-block:: c
+
+ enum tfm_hal_status_t {
+ TFM_HAL_ERROR_MEM_FAULT = SCHAR_MIN,
+ TFM_HAL_ERROR_MAX_VALUE,
+ TFM_HAL_ERROR_BAD_STATE,
+ TFM_HAL_ERROR_NOT_SUPPORTED,
+ TFM_HAL_ERROR_INVALID_INPUT,
+ TFM_HAL_ERROR_NOT_INIT,
+ TFM_HAL_ERROR_GENERIC,
+ TFM_HAL_SUCCESS = 0
+ };
+
+Error Codes
+===========
+Negative values indicate an error. Zero and positive values indicate success.
+
+Here is the general list. The detailed usages for each error code are described
+in the API introduction sections.
+
+TFM_HAL_SUCCESS
+---------------
+Status code to indicate general success.
+
+TFM_HAL_ERROR_GENERIC
+---------------------
+Status code to indicate an error that does not correspond to any defined failure
+cause.
+
+TFM_HAL_ERROR_NOT_INIT
+----------------------
+Status code to indicate that the module is not initialed.
+
+TFM_HAL_ERROR_INVALID_INPUT
+---------------------------
+Status code to indicate that the input is invalid.
+
+TFM_HAL_ERROR_NOT_SUPPORTED
+---------------------------
+Status code to indicate that the requested operation or a parameter is not
+supported.
+
+TFM_HAL_ERROR_BAD_STATE
+-----------------------
+Status code to indicate that the requested action cannot be performed in the
+current state.
+
+TFM_HAL_ERROR_MAX_VALUE
+-----------------------
+Status code to indicate that the current number has got the max value.
+
+TFM_HAL_ERROR_MEM_FAULT
+-----------------------
+Status code to indicate that the memory check failed.
+
+***************************
+API Definition for TF-M SPM
+***************************
+This section describes the APIs defined for :term:`TF-M` :term:`SPM`.
+
+Platform API
+============
+The platform API is a higher-level abstraction layer of the platform, other than
+a dedicated API set for the special hardware devices.
+
+APIs
+----
+tfm_hal_platform_init()
+^^^^^^^^^^^^^^^^^^^^^^^
+**Prototype**
+
+.. code-block:: c
+
+ enum tfm_hal_status_t tfm_hal_platform_init(void)
+
+**Description**
+
+This API performs the platform initializations **before** the :term:`SPM`
+initialization.
+
+The initializations could include but not limited to:
+- Fault handlers
+- Reset configurations
+- Debug init
+- NVIC init
+
+**Parameter**
+
+- ``void`` - None.
+
+**Return Values**
+
+- ``TFM_HAL_SUCCESS`` - Init success.
+- ``TFM_HAL_ERROR_GENERIC`` - Generic errors.
+
+tfm_hal_system_reset()
+^^^^^^^^^^^^^^^^^^^^^^
+**Prototype**
+
+.. code-block:: c
+
+ void tfm_hal_system_reset(void)
+
+**Description**
+
+This API performs a system reset.
+
+The platform can uninitialize some resources before reset.
+
+When ``CONFIG_TFM_HALT_ON_CORE_PANIC`` is disabled this function is called to reset
+the system when a fatal error occurs.
+
+**Parameter**
+
+- ``void`` - None
+
+**Return Values**
+
+- ``void`` - None
+
+**Note**
+
+This API should not return.
+
+tfm_hal_system_halt()
+^^^^^^^^^^^^^^^^^^^^^
+**Prototype**
+
+.. code-block:: c
+
+ void tfm_hal_system_halt(void)
+
+**Description**
+
+This API enters the CPU into an infinite loop.
+
+The platform can uninitialize some resources before looping forever.
+
+When ``CONFIG_TFM_HALT_ON_CORE_PANIC`` is enabled this function is called to halt the
+system when a fatal error occurs.
+
+**Parameter**
+
+- ``void`` - None
+
+**Return Values**
+
+- ``void`` - None
+
+**Note**
+
+This API should not return.
+
+Isolation API
+=============
+The :term:`PSA-FF-M` defines three isolation levels and a memory access rule to
+provide diverse levels of securitiy. The isolation API provides the functions to
+implement these requirements.
+
+The Isolation API operates on boundaries. A boundary represents a set of
+protection settings that isolates components and domains. Below are the
+boundary examples in the current implementation:
+
+ - Boundaries between SPM and Secure Partitions.
+ - Boundaries between ARoT domain and PRoT domain.
+
+There are two types of boundaries:
+
+ - Static boundaries: Set up when the system is initializing and
+ persistent after the initialization. This type of boundary needs the
+ set-up operations only.
+ - Partition boundaries: Keeps switching from one to another when the system
+ is running. This type of boundary needs both set-up and switching
+ operations.
+
+The boundary operations are abstracted as HAL interfaces because isolation
+hardwares can be different for platforms:
+
+ - The set-up HAL interface creates a partition boundary based on given
+ partition information. This created boundary is bound with the partition
+ for subsequent usage. The binding is done by storing the boundary into
+ partition runtime data.
+ - The activation HAL interface activates the partition boundary to secure
+ the execution for the partition to be switched. The target partition's
+ information and boundary are given to the activation HAL to accomplish
+ the operation.
+
+The data representing the partition boundary in runtime is defined with the
+opaque type ``uintptr_t``:
+
+ - It is required that one value represents one boundary. The different values
+ represent different boundaries.
+ - The value is created by HAL implementation with its own-defined encoding
+ scheme.
+
+The HAL implementation defined encoding scheme can be designed for
+implementation convenience. For example:
+
+ - The implementation scheme can encode attribute flags into integer bits.
+ This could help the activation HAL to extract the protection settings
+ quickly from this encoded value, or even write to hardware registers
+ directly in the most ideal case. The initial TF-M Isolation HAL reference
+ implementation applies this scheme.
+ - The implementation scheme can reference the addresses of isolation
+ hardware description data. This could help the activation HAL to reference
+ the protection settings directly by pointers.
+
+Multiple Secure Partitions can bind with the same boundary value. This
+flexibility is useful for specific configurations. Take Isolation Level 2 as
+an example, assigning PRoT and ARoT domain boundaries to respective partitions
+can make execution more efficient, because switching two partitions in the
+same domain does not need to change the activated boundary.
+
+The boundary contains the partition's memory accessibility information, hence
+memory access check shall be performed based on boundary.
+
+Memory Access Attributes
+------------------------
+The memory access attributes are encoded as bit fields, you can logic OR them to
+have a combination of the atrributes, for example
+``TFM_HAL_ACCESS_UNPRIVILEGED | TFM_HAL_ACCESS_READABLE`` is unprivileged
+readable. The data type is `uint32_t`.
+
+TFM_HAL_ACCESS_EXECUTABLE
+^^^^^^^^^^^^^^^^^^^^^^^^^
+The memory is executable.
+
+.. code-block:: c
+
+ #define TFM_HAL_ACCESS_EXECUTABLE (1UL << 0)
+
+TFM_HAL_ACCESS_READABLE
+^^^^^^^^^^^^^^^^^^^^^^^
+The memory is readable.
+
+.. code-block:: c
+
+ #define TFM_HAL_ACCESS_READABLE (1UL << 1)
+
+TFM_HAL_ACCESS_WRITABLE
+^^^^^^^^^^^^^^^^^^^^^^^
+The memory is writable.
+
+.. code-block:: c
+
+ #define TFM_HAL_ACCESS_WRITABLE (1UL << 2)
+
+TFM_HAL_ACCESS_UNPRIVILEGED
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+The memory is unprivileged mode accessible.
+
+.. code-block:: c
+
+ #define TFM_HAL_ACCESS_UNPRIVILEGED (1UL << 3)
+
+TFM_HAL_ACCESS_DEVICE
+^^^^^^^^^^^^^^^^^^^^^
+The memory is a MMIO device.
+
+.. code-block:: c
+
+ #define TFM_HAL_ACCESS_DEVICE (1UL << 4)
+
+TFM_HAL_ACCESS_NS
+^^^^^^^^^^^^^^^^^
+The memory is accessible from :term:`NSPE`
+
+.. code-block:: c
+
+ #define TFM_HAL_ACCESS_NS (1UL << 5)
+
+APIs
+----
+
+tfm_hal_set_up_static_boundaries()
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+**Prototype**
+
+.. code-block:: c
+
+ enum tfm_hal_status_t tfm_hal_set_up_static_boundaries(void)
+
+**Description**
+
+This API sets up the static isolation boundaries which are constant throughout
+the system runtime.
+
+These boundaries include:
+
+- The boundary between the :term:`SPE` and the :term:`NSPE`
+- The boundary to protect the SPM execution. For example, the PSA RoT
+ isolation boundary between the PSA Root of Trust and the Application Root of
+ Trust which is for isolation level 2 and 3 only.
+
+Refer to the :term:`PSA-FF-M` for the definitions of the isolation boundaries.
+
+**Return Values**
+
+- ``TFM_HAL_SUCCESS`` - Isolation boundaries have been set up.
+- ``TFM_HAL_ERROR_GENERIC`` - Failed to set up the static boundaries.
+
+tfm_hal_bind_boundary()
+^^^^^^^^^^^^^^^^^^^^^^^^^
+**Prototype**
+
+.. code-block:: c
+
+ enum tfm_hal_status_t tfm_hal_bind_boundary(
+ const struct partition_load_info_t *p_ldinf,
+ uintptr_t *p_boundary);
+
+**Description**
+
+This API binds partition with a platform-generated boundary. The boundary is
+bound by writing the generated value into ``p_boundary``. And this bound
+boundary is used in subsequent calls to `tfm_hal_activate_boundary()`_ when
+boundary's owner partition get scheduled for running.
+
+**Parameter**
+
+- ``p_ldinf`` - Load information of the partition that is under loading.
+- ``p_boundary`` - Pointer for holding a partition's boundary.
+
+**Return Values**
+
+- ``TFM_HAL_SUCCESS`` - The boundary has been bound successfully.
+- ``TFM_HAL_ERROR_GENERIC`` - Failed to bind the handle.
+
+tfm_hal_activate_boundary()
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+**Prototype**
+
+.. code-block:: c
+
+ enum tfm_hal_status_t tfm_hal_activate_boundary(
+ const struct partition_load_info_t *p_ldinf,
+ uintptr_t boundary);
+
+**Description**
+
+This API requires the platform to activate the boundary to ensure the given
+Secure Partition can run successfully.
+
+The access permissions outside the boundary is platform-dependent.
+
+**Parameter**
+
+- ``p_ldinf`` - The load information of the partition that is going to be run.
+- ``boundary`` - The boundary for the owner partition of ``p_ldinf``. This
+ value is bound in function ``tfm_hal_bind_boundary``.
+
+**Return Values**
+
+- ``TFM_HAL_SUCCESS`` - the isolation boundary has been set up.
+- ``TFM_HAL_ERROR_GENERIC`` - failed to set upthe isolation boundary.
+
+tfm_hal_memory_check()
+^^^^^^^^^^^^^^^^^^^^^^
+**Prototype**
+
+.. code-block:: c
+
+ tfm_hal_status_t tfm_hal_memory_check(uintptr_t boundary,
+ uintptr_t base,
+ size_t size,
+ uint32_t access_type)
+
+**Description**
+
+This API checks if a given range of memory can be accessed with specified
+access types in boundary. The boundary belongs to a partition which
+contains asset info.
+
+**Parameter**
+
+- ``boundary`` - Boundary of a Secure Partition.
+ Check `tfm_hal_bind_boundary` for details.
+- ``base`` - The base address of the region.
+- ``size`` - The size of the region.
+- ``access_type`` - The memory access types to be checked between given memory
+ and boundaries. The `Memory Access Attributes`_.
+
+**Return Values**
+
+- ``TFM_HAL_SUCCESS`` - The memory region has the access permissions.
+- ``TFM_HAL_ERROR_MEM_FAULT`` - The memory region does not have the access
+ permissions.
+- ``TFM_HAL_ERROR_INVALID_INPUT`` - Invalid inputs.
+- ``TFM_HAL_ERROR_GENERIC`` - An error occurred.
+
+**Note**
+
+If the implementation chooses to encode a pointer as the boundary,
+a platform-specific pointer validation needs to be considered before
+referencing the content in this pointer.
+
+Log API
+=======
+The log API is used by the :term:`TF-M` :doc:`log system <tfm_log_system_design_document>`.
+The log device could be uart, memory, usb, etc.
+
+APIs
+----
+tfm_hal_output_partition_log()
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+**Prototype**
+
+.. code-block:: c
+
+ int32_t tfm_hal_output_partition_log(const unsigned char *str, uint32_t len)
+
+**Description**
+
+This API is called by Secure Partition to output logs.
+
+**Parameter**
+
+- ``str`` - The string to output.
+- ``len`` - Length of the string in bytes.
+
+**Return Values**
+
+- Positive values - Number of bytes output.
+- ``TFM_HAL_ERROR_NOT_INIT`` - The log device has not been initialized.
+- ``TFM_HAL_ERROR_INVALID_INPUT`` - Invalid inputs when ``str`` is ``NULL`` or
+ ``len`` is zero.
+
+**Note**
+
+None.
+
+tfm_hal_output_spm_log()
+^^^^^^^^^^^^^^^^^^^^^^^^
+**Prototype**
+
+.. code-block:: c
+
+ int32_t tfm_hal_output_spm_log(const unsigned char *str, uint32_t len)
+
+**Description**
+
+This API is called by :term:`SPM` to output logs.
+
+**Parameter**
+
+- ``str`` - The string to output.
+- ``len`` - Length of the string in bytes.
+
+**Return Values**
+
+- Positive numbers - Number of bytes output.
+- ``TFM_HAL_ERROR_NOT_INIT`` - The log device has not been initialized.
+- ``TFM_HAL_ERROR_INVALID_INPUT`` - Invalid inputs when ``str`` is ``NULL``
+ or ``len`` is zero.
+
+**Note**
+
+Please check :doc:`TF-M log system <tfm_log_system_design_document>` for more
+information.
+
+Interrupt APIs
+==============
+
+The SPM HAL interrupt APIs are intended for operations on Interrupt Controllers
+of platforms.
+
+APIs for control registers of interrupt sources are not in the scope of this set
+of APIs.
+Secure Partitions should define the APIs for managing interrupts with those MMIO
+registers.
+
+APIs
+----
+
+tfm_hal_irq_enable()
+^^^^^^^^^^^^^^^^^^^^
+
+**Prototype**
+
+.. code-block:: c
+
+ enum tfm_hal_status_t tfm_hal_irq_enable(uint32_t irq_num)
+
+**Description**
+
+This API enables an interrupt from the Interrupt Controller of the platform.
+
+**Parameter**
+
+- ``irq_num`` - the interrupt to be enabled with a number
+
+**Return Values**
+
+- ``TFM_HAL_ERROR_INVALID_INPUT`` - the ``irq_num`` exceeds The maximum
+ supported number of external interrupts.
+- ``TFM_HAL_ERROR_GENERIC`` - failed to enable the interrupt.
+- ``TFM_HAL_SUCCESS`` - the interrupt is successfully enabled.
+
+tfm_hal_irq_disable()
+^^^^^^^^^^^^^^^^^^^^^
+
+**Prototype**
+
+.. code-block:: c
+
+ enum tfm_hal_status_t tfm_hal_irq_disable(uint32_t irq_num)
+
+**Description**
+
+This API disables an interrupt from the Interrupt Controller of the platform.
+
+**Parameter**
+
+- ``irq_num`` - the interrupt to be disabled with a number
+
+**Return Values**
+
+- ``TFM_HAL_ERROR_INVALID_INPUT`` - the ``irq_num`` exceeds The maximum
+ supported number of external interrupts.
+- ``TFM_HAL_ERROR_GENERIC`` - failed to disable the interrupt.
+- ``TFM_HAL_SUCCESS`` - the interrupt is successfully disabled.
+
+tfm_hal_irq_clear_pending()
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+**Prototype**
+
+.. code-block:: c
+
+ enum tfm_hal_status_t tfm_hal_irq_clear_pending(uint32_t irq_num)
+
+**Description**
+
+This API clears an active and pending interrupt.
+
+**Parameter**
+
+- ``irq_num`` - the interrupt to be disabled with a number
+
+**Return Values**
+
+- ``TFM_HAL_ERROR_INVALID_INPUT`` - the ``irq_num`` exceeds The maximum
+ supported number of external interrupts.
+- ``TFM_HAL_ERROR_GENERIC`` - failed to clear the pending interrupt.
+- ``TFM_HAL_SUCCESS`` - the pending interrupt has been cleared.
+
+Initializations
+^^^^^^^^^^^^^^^
+
+**Prototype**
+
+.. code-block:: c
+
+ enum tfm_hal_status_t {source_symbol}_init(void *p_pt,
+ const struct irq_load_info_t *p_ildi)
+
+The ``{source_symbol}`` is:
+
+- ``irq_{source}``, if the ``source`` attribute of the IRQ in Partition manifest
+ is a number
+- Lowercase of ``source`` attribute, if ``source`` is a symbolic name
+
+**Description**
+
+Each interrupt has an initialization function individually.
+The :term:`SPM` calls the functions while loading the Partitions.
+
+The following initializations are required for each interrupt:
+
+- Setting the priority. The value must between 0 to 0x80 exclusively.
+- Ensuring that the interrupt targets the Secure State.
+- Saving the input parameters for future use.
+
+Platforms can have extra initializations as well.
+
+**Parameter**
+
+- ``p_pt`` - pointer to Partition runtime struct of the owner Partition
+- ``p_ildi`` - pointer to ``irq_load_info_t`` struct of the interrupt
+
+**Note**
+
+Please refer to the
+:doc: `IRQ intergration guide<tfm_secure_irq_integration_guide>`
+for more information.
+
+************************************
+API Definition for Secure Partitions
+************************************
+The Secure Partition (SP) :term:`HAL` mainly focuses on two parts:
+
+ - Peripheral devices. The peripherals accessed by the :term:`TF-M` default
+ Secure Partitions.
+ - Secure Partition abstraction support. The Secure Partition data that must be
+ provided by the platform.
+
+The Secure Partition abstraction support will be introduced in the peripheral
+API definition.
+
+ITS and PS flash API
+====================
+There are two kinds of flash:
+
+ - Internal flash. Accessed by the PSA Internal Trusted Storage (ITS) service.
+ - External flash. Accessed by the PSA Protected Storage (PS) service.
+
+The ITS HAL for the internal flash device is defined in the ``tfm_hal_its.h``
+header and the PS HAL in the ``tfm_hal_ps.h`` header.
+
+Macros
+------
+Internal Trusted Storage
+^^^^^^^^^^^^^^^^^^^^^^^^
+TFM_HAL_ITS_FLASH_DRIVER
+~~~~~~~~~~~~~~~~~~~~~~~~
+Defines the identifier of the CMSIS Flash ARM_DRIVER_FLASH object to use for
+ITS. It must have been allocated by the platform and will be declared extern in
+the HAL header.
+
+TFM_HAL_ITS_PROGRAM_UNIT
+~~~~~~~~~~~~~~~~~~~~~~~~
+Defines the size of the ITS flash device's physical program unit (the smallest
+unit of data that can be individually programmed to flash). It must be equal to
+TFM_HAL_ITS_FLASH_DRIVER.GetInfo()->program_unit, but made available at compile
+time so that filesystem structures can be statically sized.
+
+TFM_HAL_ITS_FLASH_AREA_ADDR
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Defines the base address of the dedicated flash area for ITS.
+
+TFM_HAL_ITS_FLASH_AREA_SIZE
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Defines the size of the dedicated flash area for ITS in bytes.
+
+TFM_HAL_ITS_SECTORS_PER_BLOCK
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Defines the number of contiguous physical flash erase sectors that form a
+logical filesystem erase block.
+
+Protected Storage
+^^^^^^^^^^^^^^^^^
+TFM_HAL_PS_FLASH_DRIVER
+~~~~~~~~~~~~~~~~~~~~~~~
+Defines the identifier of the CMSIS Flash ARM_DRIVER_FLASH object to use for
+PS. It must have been allocated by the platform and will be declared extern in
+the HAL header.
+
+TFM_HAL_PS_PROGRAM_UNIT
+~~~~~~~~~~~~~~~~~~~~~~~~
+Defines the size of the PS flash device's physical program unit (the smallest
+unit of data that can be individually programmed to flash). It must be equal to
+TFM_HAL_PS_FLASH_DRIVER.GetInfo()->program_unit, but made available at compile
+time so that filesystem structures can be statically sized.
+
+TFM_HAL_PS_FLASH_AREA_ADDR
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Defines the base address of the dedicated flash area for PS.
+
+TFM_HAL_PS_FLASH_AREA_SIZE
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Defines the size of the dedicated flash area for PS in bytes.
+
+TFM_HAL_PS_SECTORS_PER_BLOCK
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Defines the number of contiguous physical flash erase sectors that form a
+logical filesystem erase block.
+
+Optional definitions
+--------------------
+The ``TFM_HAL_ITS_FLASH_AREA_ADDR``, ``TFM_HAL_ITS_FLASH_AREA_SIZE`` and
+``TFM_HAL_ITS_SECTORS_PER_BLOCK`` definitions are optional. If not defined, the
+platform must implement ``tfm_hal_its_fs_info()`` instead.
+
+Equivalently, ``tfm_hal_its_ps_info()`` must be implemented by the platform if
+``TFM_HAL_ITS_FLASH_AREA_ADDR``, ``TFM_HAL_ITS_FLASH_AREA_SIZE`` or
+``TFM_HAL_ITS_SECTORS_PER_BLOCK`` is not defined.
+
+Objects
+-------
+ARM_DRIVER_FLASH
+^^^^^^^^^^^^^^^^
+The ITS and PS HAL headers each expose a CMSIS Flash Driver instance.
+
+.. code-block:: c
+
+ extern ARM_DRIVER_FLASH TFM_HAL_ITS_FLASH_DRIVER
+
+ extern ARM_DRIVER_FLASH TFM_HAL_PS_FLASH_DRIVER
+
+The CMSIS Flash Driver provides the flash primitives ReadData(), ProgramData()
+and EraseSector() as well as GetInfo() to access flash device properties such
+as the sector size.
+
+Types
+-----
+tfm_hal_its_fs_info_t
+^^^^^^^^^^^^^^^^^^^^^
+Struct containing information required from the platform at runtime to configure
+the ITS filesystem.
+
+.. code-block:: c
+
+ struct tfm_hal_its_fs_info_t {
+ uint32_t flash_area_addr;
+ size_t flash_area_size;
+ uint8_t sectors_per_block;
+ };
+
+Each attribute is described below:
+
+ - ``flash_area_addr`` - Location of the block of flash to use for ITS
+ - ``flash_area_size`` - Number of bytes of flash to use for ITS
+ - ``sectors_per_block`` - Number of erase sectors per logical FS block
+
+tfm_hal_ps_fs_info_t
+^^^^^^^^^^^^^^^^^^^^^
+Struct containing information required from the platform at runtime to configure
+the PS filesystem.
+
+.. code-block:: c
+
+ struct tfm_hal_ps_fs_info_t {
+ uint32_t flash_area_addr;
+ size_t flash_area_size;
+ uint8_t sectors_per_block;
+ };
+
+Each attribute is described below:
+
+ - ``flash_area_addr`` - Location of the block of flash to use for PS
+ - ``flash_area_size`` - Number of bytes of flash to use for PS
+ - ``sectors_per_block`` - Number of erase sectors per logical FS block
+
+Functions
+---------
+tfm_hal_its_fs_info()
+^^^^^^^^^^^^^^^^^^^^^
+**Prototype**
+
+.. code-block:: c
+
+ enum tfm_hal_status_t tfm_hal_its_fs_info(struct tfm_hal_its_fs_info_t *fs_info);
+
+**Description**
+
+Retrieves the filesystem configuration parameters for ITS.
+
+**Parameter**
+
+- ``fs_info`` - Filesystem config information
+
+**Return values**
+
+- ``TFM_HAL_SUCCESS`` - The operation completed successfully
+- ``TFM_HAL_ERROR_INVALID_INPUT`` - Invalid parameter
+
+**Note**
+
+This function should ensure that the values returned do not result in a security
+compromise. The block of flash supplied must meet the security requirements of
+Internal Trusted Storage.
+
+tfm_hal_ps_fs_info()
+^^^^^^^^^^^^^^^^^^^^
+**Prototype**
+
+.. code-block:: c
+
+ enum tfm_hal_status_t tfm_hal_ps_fs_info(struct tfm_hal_ps_fs_info_t *fs_info);
+
+**Description**
+
+Retrieves the filesystem configuration parameters for PS.
+
+**Parameter**
+
+- ``fs_info`` - Filesystem config information
+
+**Return values**
+
+- ``TFM_HAL_SUCCESS`` - The operation completed successfully
+- ``TFM_HAL_ERROR_INVALID_INPUT`` - Invalid parameter
+
+**Note**
+
+This function should ensure that the values returned do not result in a security
+compromise.
+
+--------------
+
+*Copyright (c) 2020-2022, Arm Limited. All rights reserved.*
+*Copyright (c) 2022 Cypress Semiconductor Corporation (an Infineon company)
+or an affiliate of Cypress Semiconductor Corporation. All rights reserved.*
diff --git a/docs/design_docs/index.rst b/docs/design_docs/index.rst
new file mode 100644
index 0000000..e091bbb
--- /dev/null
+++ b/docs/design_docs/index.rst
@@ -0,0 +1,13 @@
+Design Documents
+================
+
+.. toctree::
+ :maxdepth: 1
+ :glob:
+
+ */index
+ *
+
+--------------
+
+*Copyright (c) 2021, Arm Limited. All rights reserved.*
diff --git a/docs/design_docs/mailbox_ns_agent_update.rst b/docs/design_docs/mailbox_ns_agent_update.rst
new file mode 100644
index 0000000..116b2a6
--- /dev/null
+++ b/docs/design_docs/mailbox_ns_agent_update.rst
@@ -0,0 +1,277 @@
+##############################
+Mailbox NS Agent Design Update
+##############################
+
+:Organization: Arm Limited
+:Contact: tf-m@lists.trustedfirmware.org
+
+**********
+Background
+**********
+The SPE component that maintains the non-secure clients' request is called
+'NS Agent' in TF-M. Besides the Trustzone-based isolation mechanism, there is
+one other isolation mechanism that implements individual PEs in physically
+isolated cores respectively. NSPE and SPE transfer non-secure client requests
+via inter-processor communication based on mailboxes. The component that
+handles inter-processor communication messages is called ``mailbox NS Agent``.
+
+.. note::
+ There may be hardware components and software solutions containing 'mailbox'
+ in their names. The concept ``mailbox`` in this document represent the
+ mechanism described above, which is not referring to the external concepts.
+
+When the first version ``mailbox NS Agent`` was introduced, the generic FFM
+interrupt handling was not ready. Hence a customized solution
+``Multiple Core`` is implemented. This customized implementation:
+
+- Perform customized operations on SPM internal data in a deferred interrupt
+ handler.
+- Process mailbox operations as special cases in SPM common logic.
+
+These behaviours couple SPM tightly with mailbox logic, which bring issues for
+maintenance. To address the issue, an updated design shall:
+
+- Make SPM manage other components in a unified way (For example, it is
+ simpler for SPM if all non-SPM components under the IPC model act as
+ ``processes``.)
+- Can use FF-M compliant interrupt mechanism and APIs.
+
+Following the above guidelines makes the ``mailbox NS agent`` work like a
+``partition``. The agent has an endless loop and waits for signals, calls FFM
+API based on the parsing result on the communication messages. But there are
+still issues after looking closer to the requirements of the agent:
+
+- SPM treats FFM Client API caller's ID as the client ID. While the mailbox NS
+ agent may represent multiple non-secure clients. Hence it needs to tell
+ SPM which non-secure client it is representing, and the default FFM Client
+ API does not have such capability.
+- FFM Client API blocks caller before the call is replied; while the
+ mailbox NS Agent needs to respond to the non-secure interrupts in time.
+ Blocking while waiting for a reply may cause the non-secure communication
+ message not to be handled in time.
+
+Extra design items need to be added to address the issues.
+
+*************
+Design Update
+*************
+The below figure shows the overall design to cover various component types.
+NS Agents are the implementation-defined components that provide FF-M compliant
+Client API to the non-secure clients. Hence from the view of the non-secure
+clients, the FF-M client API behaviour follows the FF-M definition. And NS
+Agent needs customization in SPM since it has extra requirements compared to
+a generic secure partition.
+
+.. figure:: media/mailbox_ns_agent1.*
+ :align: center
+ :name: fig-mailbox1
+ :width: 70%
+
+ Component types and the callable API set
+
+.. note::
+ 3 non-SPM component types here: FFM-compliant Secure Partition
+ (aka ``partition``), Trustzone-based NS Agent (aka ``Trustzone NS agent``)
+ and mailbox-based NS Agent (aka ``mailbox NS agent``).
+ ``Trustzone NS agent`` is mentioned here for the comparison purpose. The
+ implementation details for this NS agent type is not introduced here.
+
+To make the programming model close to the FFM compliance, the
+``mailbox NS agent`` is designed as:
+
+- Working like a standard Secure Partition under the IPC model, has one
+ single thread, can call FFM standard API.
+- Having a manifest file to describe the attributes and resources and a
+ positive valued ``Partition ID`` in the manifest.
+
+Services rely on the ``client_id`` to apply policy-checking, hence SPM
+needs to know which ``client_id`` the mailbox NS Agent is representing when
+mailbox API is calling Client API. The standard API treats the caller as the
+client of the service, which means that an extended API is needed to support
+identifying the non-secure client that is represented. SPM sets the
+non-secure ``client_id`` into the message right at the moment the message is
+going to be sent. Before this point, SPM performs the call based on the
+agent's ID.
+
+These ``Extended APIs`` are non-blocking, unlike the standard FF-M Client
+APIs. This can improve the communication efficiency between NS clients and
+mailbox NS agents. With this mechanism, extra signals and APIs for message
+acknowledges are also required.
+
+.. note::
+ A standard Secure Partition gets errors when calling the ``Extended API``.
+
+The secure mapped memory for mailbox communication is one of the agent's
+assets. As the agent has the capability to forward and represent non-secure
+clients, it is the agent's duty to identify the non-secure clients it is
+representing.
+
+Updated Programming Items
+=========================
+These Client APIs are the expansion based on the standard Client APIs:
+
+- ``agent_psa_connect`` is extended from ``psa_connect``.
+- ``agent_psa_call`` is extended from ``psa_call``.
+
+And to cooperate with the changed behaviour of these APIs, extra defined
+signals and types are also involved.
+
+.. note::
+ Namespace ``agent`` is involved for NS Agent callable API; namespace ``tfm``
+ is involved for TF-M specific concepts. Even though ``agent`` is TF-M
+ specific at the current stage, it is proposed to be a common concept for
+ general FF-M compliant implementations, hence assigning ``agent`` for
+ proposed API and data structures.
+
+Agent-specific Client API
+=========================
+``agent_psa_connect`` is the API added to support agent forwarding NS
+requests.
+
+.. code-block:: c
+
+ psa_handle_t agent_psa_connect(uint32_t sid, uint32_t version,
+ int32_t ns_client_id, void *client_data);
+
+One extra parameter ``ns_client_id`` added to tell SPM which NS client the
+agent is representing when API gets called. It is recorded in the handle
+association data in SPM and requires to be a negative value; ZERO or positive
+values are invalid non-secure client IDs, SPM does not use these invalid IDs
+in the message. Instead, it puts the agent's ID into the messaging in this
+case. This mechanism can provide chances for the agents calling APIs for their
+own service accessing and API works asynchronously.
+
+As mentioned, the standard FFM Client service accessing API are blocked until
+the IPC message gets replied to. This API returns immediately without waiting
+for acknowledgement. A ``psa_handle_t`` is allocated and returned if no error
+occurred because a unique value is needed to help the agent manage the
+non-secure clients and the requests. The subsequent ``agent_psa_call``
+or ``agent_psa_close`` with this allocated but not acknowledged handle gets
+an ``In progress`` status code.
+
+.. code-block:: c
+
+ typedef struct {
+ psa_invec in_vecs[PSA_MAX_IOVEC];
+ psa_outvec out_vecs[PSA_MAX_IOVEC];
+ } client_vectors_t;
+
+ typedef struct {
+ int32_t ns_client_id;
+ void *client_data;
+ } client_param_t;
+
+ psa_status_t agent_psa_call(psa_handle_t handle, int32_t type,
+ client_vectors_t *vecs, client_param_t *params);
+
+Compared to the standard ``psa_call``, this API:
+
+- Is asynchronous.
+- Squashes the ``psa_invec_t`` and ``psa_outvec_t`` into a new composited
+ parameter ``vecs`` to make the ABI APCS compliant.
+- one extra parameter ``params`` for ``agent_psa_call`` stands for the
+ auxiliary data added. This member is ignored for connection-based services
+ because ``agent_psa_connect`` already assigned one hence this member is for
+ stateless services only. And the same, ZERO or positive values are ignored
+ during the ``agent_psa_call`` lifecycle.
+
+.. note::
+ For stateless services, a temporary ``psa_handle_t`` is allocated and
+ returned. This handle is freed after the agent read the acknowledgement by
+ ``psa_get``. This is also introduced in the subsequent introduction on
+ `Agent-specific signal`_.
+
+Agent-specific signal
+=====================
+To cooperate with the agent-specific API, one extra acknowledgement signal is
+defined:
+
+.. code-block:: c
+
+ #define PSA_MSG_ACK (0x00000004u)
+
+This signal can be sent to agent type component only. An agent can call
+``psa_get`` with this signal to get one acknowledged message. This signal is
+cleared when all queued messages for the agent have been retrieved using
+``psa_get``. SPM assembles the information into agent provided message object.
+For the stateless handle, the internal handle object is freed after this
+``psa_get`` call. The agent can know what kind of message is acknowledged by
+the ``type`` member in the ``psa_msg_t``, and the ``client_data`` passed in is
+put in member ``rhandle``. If no 'PSA_MSG_ACK' signals pending, calling
+``psa_get`` gets an state representing ``not ready`` to the caller. This
+state is to be defined.
+
+Code Example
+============
+
+.. code-block:: c
+
+ /*
+ * The actual implementation can change this __customized_t freely, or
+ * discard this type and apply some in-house mechanism - the example
+ * here is to introduce how an agent works only.
+ */
+ struct __customized_t {
+ int32_t type;
+ int32_t client_id;
+ psa_handle_t handle;
+ psa_handle_t status;
+ };
+
+ void mailbox_main(void)
+ {
+ psa_signal_t signals;
+ psa_status_t status;
+ psa_msg_t msg;
+ client_param_t client_param;
+ struct __customized_t ns_msg;
+
+ while (1) {
+ signals = psa_wait(ALL, BLOCK);
+
+ if (signals & MAILBOX_INTERRUPT_SIGNAL) {
+ /* NS memory check needs to be performed. */
+ __customized_platform_get_mail(&ns_msg);
+
+ /*
+ * MACRO 'SID', 'VER', 'NSID' and 'VECTORS' represents necessary
+ * information extraction from 'ns_msg', put MACRO names here
+ * and leave the details to the implementation.
+ */
+ if (ns_msg.type == PSA_IPC_CONNECT) {
+ ns_msg.handle = agent_psa_connect(SID(ns_msg), VER(ns_msg),
+ NSID(ns_msg), &ns_msg);
+ } else if (ns_msg.type == PSA_IPC_CLOSE) {
+ psa_close(ns_msg.handle);
+ } else {
+ /* Other types as call type and let API check errors. */
+ client_param.ns_client_id = ns_msg.client_id;
+ client_param.client_data = &ns_msg;
+
+ ns_msg.status = agent_psa_call(ns_msg.handle,
+ ns_msg.type,
+ VECTORS(ns_msg),
+ &client_param);
+ /* Handle the stateless service case. */
+ if (ns_msg.handle == NULL &&
+ ns_msg.status != PSA_ERROR_IN_PROGRESS) {
+ ns_msg.handle = (psa_handle_t)ns_msg.status;
+ }
+ }
+ } else if (signals & PSA_MSG_ACK) {
+ /* The handle is freed for stateless service after 'psa_get'. */
+ status = psa_get(PSA_MSG_ACK, &msg);
+ ms_msg = msg.rhandle;
+ ns_msg.status = status;
+ __customized_platform__send_mail(&ns_msg);
+ }
+ }
+ }
+
+.. note::
+ ``__customized*`` API are implementation-specific APIs to be implemented by
+ the mailbox Agent developer.
+
+--------------
+
+*Copyright (c) 2022, Arm Limited. All rights reserved.*
diff --git a/docs/design_docs/media/abi_scheduler.svg b/docs/design_docs/media/abi_scheduler.svg
new file mode 100644
index 0000000..34d7f40
--- /dev/null
+++ b/docs/design_docs/media/abi_scheduler.svg
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Do not edit this file with editors other than diagrams.net -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="423px" height="182px" viewBox="-0.5 -0.5 423 182" content="<mxfile host="app.diagrams.net" modified="2021-09-26T06:40:48.327Z" agent="5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.61 Safari/537.36" etag="BVD9jAIebmczNn1dO7Ma" version="15.2.9" type="device"><diagram id="pE8yNmrzc9lT-nbtH71B" name="Page-1">5VnRcuI2FP0aZtoHMraEMTwSAmEnWUqWTJs8ZVRbsdXYFitEwP36yljCxhKOmwK7Sf2QsY6ka+mec69uRAsO4801Q4vwK/Vx1AKWv2nBqxYA0AXibwakOQAsCQSM+DlkF8Cc/I0laEl0RXy83BvIKY04WeyDHk0S7PE9DDFG1/vDnmm0/9UFCrAGzD0U6egfxOdhjvaAW+ATTIJQfdnu9vOeGKnBcifLEPl0XYLgqAWHjFKev8WbIY4y3ym/5PPGB3p3C2M44U0mjMa4P8Cb9M5aezztwm/TCLbV4l5RtJI7nojd4CUX4IwRyghPhc25F2J/hZlAb6n3InfEU+UmjjdiEZcoIkEiEE+sSQyGl6+YcSK8OZAdnC4Eyugq8XG2Lku0nmnC59KULdtjFJMok8w9CmmMJDqkEWXbD0LL6opH4EvO6Ave68ke0eOjZbj9iDIq1WVnnbr3pEOzFeNNCZLevMY0xpwJZ1iqtyOdJ6XtKGeuC6EAS2JhWSRqIpLiDHa2C/7Ei6TQTKcT9J8mT9e3zuTGGa4HNzSdt9tQIwb7Qs6ySRkPaUATFI0KtEJGMeaWZlxtnfcX5jyV3kMrTgUU8jgq8WfmSzkc6PyNt8+OPxVb0Myo5FpwxdIH+dlt4zFrXDiqebUpd16lqrUh/EHuJXsvzRKtYlLWUHMOCmRJV8zDNSR0ZJpCLMBy6l18+926/hPfP7uol45upsmUtaW9jKFauTEcIU5e9xOSSTpy6oyShBey7FoVteUbkKPKCUNNPKTvXsVQvkPN0Fa5u/W/X8wdLTUNI4Llt8oaLxRsa4IChthvlnCqqSsmvr8NGMQ8aQ10a4T9TKLIJOIjZJ4KMd2Onnh6hrxzsrRj2xpVc8xeiQgTYVd4CcCt42dIuJQTmvxEFLo/hkLY/XEcpu1gOr9Dv5OXb0/f06eH+9FvkYnDweyLACYoEU5j7z7yd04/z6lf4Sxj0jrWgd+rcObonNnAQBo4AmnG8q2ncTYef60JLssQSuZgO3Cglwg7yPMxPO1Ujh63WXQ4p3J0X3P0JfJecOKXstsv8/FUGP8yG/76CSgAPxsFKkF97OK2KGEv3F3Z+qhq0wY1rHUBVOH6WK5bjUWsIU0OxdO0vK09KMr1bV1yOll9q4RqV7Ky/c56VzNUPWuPV++aBQ4+hcDNOrVrdXowKqw3ouI/Crwu15f1XRsIJxc4rOiyWk40Frj7RqScWuCdTyHwQqvgX2m1iAz3bBm8LjG/mcD7Z9I3qMiyes/QWN9VQ7CZvgeMobQ0bJENWDY/cRzHql+XWztevOQrOG6w9T9DsH2gu0DjHV/nTCFUvU1w+hdO731RBMXcfvl50/Lxjo26e9LyxcRldjGh/z/wIa8ktH/JDEpr/BuE6Uqic6IbiTrBa2Tpte3/jyxonY0s0Sx+WcwDsfh5Fo7+AQ==</diagram></mxfile>"><defs/><g><rect x="111" y="10" width="200" height="140" fill="none" stroke="#000000" stroke-dasharray="3 3" pointer-events="all"/><g fill="#006666" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="10px"><text x="210.5" y="25.5">Highest Priority/Scheduer Lock</text></g><path d="M 91 150 L 100.9 150" fill="none" stroke="#006666" stroke-width="3" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 107.65 150 L 98.65 154.5 L 100.9 150 L 98.65 145.5 Z" fill="#006666" stroke="#006666" stroke-width="3" stroke-miterlimit="10" pointer-events="all"/><rect x="11" y="130" width="80" height="40" rx="10.4" ry="10.4" fill="#006666" stroke="#000000" stroke-width="2" pointer-events="all"/><g fill="#FFFFFF" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="10px"><text x="50.5" y="153.5">Client</text></g><rect x="331" y="130" width="80" height="40" rx="10.8" ry="10.8" fill="#006666" stroke="#000000" stroke-width="2" pointer-events="all"/><g fill="#FFFFFF" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="10px"><text x="370.5" y="147.5">Service/</text><text x="370.5" y="159.5">Partition</text></g><rect x="151" y="140" width="120" height="20" fill="#ffff00" stroke="#000000" pointer-events="all"/><g fill="#006666" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="12px"><text x="210.5" y="154.5">API Handler</text></g><rect x="121" y="60" width="80" height="50" fill="#ffffff" stroke="#000000" stroke-width="2" pointer-events="all"/><g fill="#000000" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="10px"><text x="160.5" y="88.5">FFM</text></g><rect x="221" y="60" width="80" height="50" fill="#ffffff" stroke="#000000" stroke-width="2" pointer-events="all"/><g fill="#000000" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="10px"><text x="260.5" y="82.5">Backend</text><text x="260.5" y="94.5">(SFN/IPC)</text></g><path d="M 181 140 L 181 120.1" fill="none" stroke="#00cccc" stroke-width="3" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 181 113.35 L 185.5 122.35 L 181 120.1 L 176.5 122.35 Z" fill="#00cccc" stroke="#00cccc" stroke-width="3" stroke-miterlimit="10" pointer-events="all"/><path d="M 241 110 L 241 129.9" fill="none" stroke="#00cccc" stroke-width="3" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 241 136.65 L 236.5 127.65 L 241 129.9 L 245.5 127.65 Z" fill="#00cccc" stroke="#00cccc" stroke-width="3" stroke-miterlimit="10" pointer-events="all"/><path d="M 181 60 L 181 40 L 241 40 L 241 49.9" fill="none" stroke="#00cccc" stroke-width="3" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 241 56.65 L 236.5 47.65 L 241 49.9 L 245.5 47.65 Z" fill="#00cccc" stroke="#00cccc" stroke-width="3" stroke-miterlimit="10" pointer-events="all"/><path d="M 311 150 L 320.9 150" fill="none" stroke="#006666" stroke-width="3" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 327.65 150 L 318.65 154.5 L 320.9 150 L 318.65 145.5 Z" fill="#006666" stroke="#006666" stroke-width="3" stroke-miterlimit="10" pointer-events="all"/><rect x="111" y="140" width="40" height="20" fill="#ffff00" stroke="#000000" pointer-events="all"/><g fill="#006666" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="12px"><text x="130.5" y="154.5">ABI 1</text></g><rect x="271" y="140" width="40" height="20" fill="#ffff00" stroke="#000000" pointer-events="all"/><g fill="#006666" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="12px"><text x="290.5" y="154.5">ABI 2</text></g></g></svg>
\ No newline at end of file
diff --git a/docs/design_docs/media/fwu-states.svg b/docs/design_docs/media/fwu-states.svg
new file mode 100755
index 0000000..8039f14
--- /dev/null
+++ b/docs/design_docs/media/fwu-states.svg
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentStyleType="text/css" height="869px" preserveAspectRatio="none" style="width:403px;height:869px;background:#FFFFFF;" version="1.1" viewBox="0 0 403 869" width="403px" zoomAndPan="magnify"><defs/><g><rect fill="#FFFFFF" height="40" rx="12.5" ry="12.5" style="stroke:#000000;stroke-width:1.0;" width="50" x="105.5" y="7"/><text fill="#000000" font-family="Lato,sans-serif" font-size="12" lengthAdjust="spacing" textLength="40" x="110.5" y="31.6414">READY</text><rect fill="#FFFFFF" height="40" rx="12.5" ry="12.5" style="stroke:#000000;stroke-width:1.0;" width="63" x="15" y="123"/><text fill="#000000" font-family="Lato,sans-serif" font-size="12" lengthAdjust="spacing" textLength="53" x="20" y="147.6414">WRITING</text><rect fill="#FFFFFF" height="40" rx="12.5" ry="12.5" style="stroke:#000000;stroke-width:1.0;" width="79" x="7" y="239"/><text fill="#000000" font-family="Lato,sans-serif" font-size="12" lengthAdjust="spacing" textLength="69" x="12" y="263.6414">CANDIDATE</text><rect fill="#FFFFFF" height="40" rx="12.5" ry="12.5" style="stroke:#000000;stroke-width:1.0;" width="63" x="100" y="369"/><text fill="#000000" font-family="Lato,sans-serif" font-size="12" lengthAdjust="spacing" textLength="53" x="105" y="393.6414">STAGED *</text><rect fill="#FFFFFF" height="40" rx="12.5" ry="12.5" style="stroke:#000000;stroke-width:1.0;" width="51" x="173" y="239"/><text fill="#000000" font-family="Lato,sans-serif" font-size="12" lengthAdjust="spacing" textLength="41" x="178" y="263.6414">FAILED</text><rect fill="#FFFFFF" height="40" rx="12.5" ry="12.5" style="stroke:#000000;stroke-width:1.0;" width="75" x="226" y="369"/><text fill="#000000" font-family="Lato,sans-serif" font-size="12" lengthAdjust="spacing" textLength="65" x="231" y="393.6414">REJECTED *</text><rect fill="#FFFFFF" height="40" rx="12.5" ry="12.5" style="stroke:#000000;stroke-width:1.0;" width="50" x="179.5" y="499"/><text fill="#000000" font-family="Lato,sans-serif" font-size="12" lengthAdjust="spacing" textLength="40" x="184.5" y="523.6414">TRIAL *</text><rect fill="#FFFFFF" height="40" rx="12.5" ry="12.5" style="stroke:#000000;stroke-width:1.0;" width="66" x="171.5" y="615"/><text fill="#000000" font-family="Lato,sans-serif" font-size="12" lengthAdjust="spacing" textLength="56" x="176.5" y="639.6414">UPDATED</text><rect fill="#FFFFFF" height="40" rx="12.5" ry="12.5" style="stroke:#000000;stroke-width:1.0;" width="50" x="179.5" y="731"/><text fill="#000000" font-family="Lato,sans-serif" font-size="12" lengthAdjust="spacing" textLength="40" x="184.5" y="755.6414">READY</text><!--MD5=[28b091a9324bc665227cbdd5c64568c5]
+link Start to Writing--><g id="link_Start_Writing"><path d="M116.44,47.08 C101.9,66.81 79.19,97.63 63.62,118.76 " fill="none" id="Start-to-Writing" style="stroke:#0000FF;stroke-width:1.0;"/><polygon fill="#0000FF" points="60.61,122.86,69.1714,117.9914,63.5779,118.8362,62.7332,113.2427,60.61,122.86" style="stroke:#0000FF;stroke-width:1.0;"/><text fill="#000000" font-family="Consolas,Menlo,monospace" font-size="12" lengthAdjust="spacing" textLength="35" x="95.5" y="89.9883">start</text></g><!--MD5=[809ec20dfa1295c4642186e63aa045f8]
+link Writing to Writing--><g id="link_Writing_Writing"><path d="M78.32,132.68 C96.33,130.67 113,134.11 113,143 C113,151.06 99.31,154.64 83.33,153.74 " fill="none" id="Writing-to-Writing" style="stroke:#0000FF;stroke-width:1.0;"/><polygon fill="#0000FF" points="78.32,153.32,86.9444,158.0761,83.3016,153.7482,87.6295,150.1055,78.32,153.32" style="stroke:#0000FF;stroke-width:1.0;"/><text fill="#000000" font-family="Consolas,Menlo,monospace" font-size="12" lengthAdjust="spacing" textLength="35" x="119" y="147.9883">write</text></g><!--MD5=[c452d5c1487cc0f2a16ec09e1ebeb498]
+link Writing to Candidate--><g id="link_Writing_Candidate"><path d="M46.5,163.08 C46.5,182.48 46.5,212.61 46.5,233.7 " fill="none" id="Writing-to-Candidate" style="stroke:#0000FF;stroke-width:1.0;"/><polygon fill="#0000FF" points="46.5,238.86,50.5,229.86,46.5,233.86,42.5,229.86,46.5,238.86" style="stroke:#0000FF;stroke-width:1.0;"/><text fill="#000000" font-family="Consolas,Menlo,monospace" font-size="12" lengthAdjust="spacing" textLength="42" x="47.5" y="205.9883">finish</text></g><!--MD5=[1e580f2a5c35a06e4aed74591dc8f2d0]
+link Writing to Failed--><g id="link_Writing_Failed"><path d="M71.94,163.08 C98.68,183.14 140.71,214.66 168.92,235.81 " fill="none" id="Writing-to-Failed" style="stroke:#0000FF;stroke-width:1.0;"/><polygon fill="#0000FF" points="172.98,238.86,168.18,230.26,168.98,235.86,163.38,236.66,172.98,238.86" style="stroke:#0000FF;stroke-width:1.0;"/><text fill="#000000" font-family="Consolas,Menlo,monospace" font-size="12" lengthAdjust="spacing" textLength="42" x="133.5" y="205.9883">cancel</text></g><!--MD5=[86e4efad9860276429e6c81242466072]
+link Candidate to Staged--><g id="link_Candidate_Staged"><path d="M43.01,279.33 C40.98,296.29 40.65,320.99 51.5,339 C61.41,355.45 79.16,367.14 95.43,374.97 " fill="none" id="Candidate-to-Staged" style="stroke:#8B0000;stroke-width:1.0;"/><polygon fill="#8B0000" points="99.97,377.07,93.479,369.6628,95.4315,374.972,90.1222,376.9244,99.97,377.07" style="stroke:#8B0000;stroke-width:1.0;"/><text fill="#000000" font-family="Consolas,Menlo,monospace" font-size="12" lengthAdjust="spacing" textLength="49" x="52.5" y="328.9883">install</text></g><!--MD5=[6e8b06a321fbf587dbbb055d0b4e0f9e]
+link Candidate to Failed--><g id="link_Candidate_Failed"><path d="M86.04,259 C111.55,259 144.25,259 167.81,259 " fill="none" id="Candidate-to-Failed" style="stroke:#0000FF;stroke-width:1.0;"/><polygon fill="#0000FF" points="172.99,259,163.99,255,167.99,259,163.99,263,172.99,259" style="stroke:#0000FF;stroke-width:1.0;"/><text fill="#000000" font-family="Consolas,Menlo,monospace" font-size="12" lengthAdjust="spacing" textLength="42" x="108.5" y="252.9883">cancel</text></g><!--MD5=[d4d7d25629e036e3232ad0960ebf72b6]
+link Staged to Trial--><g id="link_Staged_Trial"><path d="M132.91,409.06 C134.86,425.84 139.5,450.43 150.5,469 C156.82,479.67 166.22,489.36 175.41,497.24 " fill="none" id="Staged-to-Trial" style="stroke:#8B0000;stroke-width:1.0;stroke-dasharray:7.0,7.0;"/><polygon fill="#8B0000" points="179.33,500.51,174.9929,491.6675,175.4947,497.3021,169.8602,497.8039,179.33,500.51" style="stroke:#8B0000;stroke-width:1.0;"/><text fill="#000000" font-family="Consolas,Menlo,monospace" font-size="12" lengthAdjust="spacing" textLength="42" x="163.5" y="452.3296">reboot</text><text fill="#000000" font-family="Lato,sans-serif" font-size="12" lengthAdjust="spacing" textLength="3" x="205.5" y="451.8375">:</text><text fill="#000000" font-family="Lato,sans-serif" font-size="12" font-style="italic" lengthAdjust="spacing" textLength="69" x="151.5" y="466.2296">install success</text></g><!--MD5=[6b849a9d54236769877241b12840d8d2]
+reverse link Failed to Staged--><g id="link_Failed_Staged"><path d="M190.93,283.94 C185.42,299.99 177.23,321.34 167.5,339 C161.79,349.35 154.19,360.03 147.44,368.76 " fill="none" id="Failed-backto-Staged" style="stroke:#8B0000;stroke-width:1.0;stroke-dasharray:7.0,7.0;"/><polygon fill="#8B0000" points="192.55,279.14,185.883,286.3892,190.9517,283.8777,193.4633,288.9464,192.55,279.14" style="stroke:#8B0000;stroke-width:1.0;"/><text fill="#000000" font-family="Consolas,Menlo,monospace" font-size="12" lengthAdjust="spacing" textLength="42" x="190" y="322.3296">reboot</text><text fill="#000000" font-family="Lato,sans-serif" font-size="12" lengthAdjust="spacing" textLength="3" x="232" y="321.8375">:</text><text fill="#000000" font-family="Lato,sans-serif" font-size="12" font-style="italic" lengthAdjust="spacing" textLength="60" x="182.5" y="336.2296">install failed</text></g><!--MD5=[6b849a9d54236769877241b12840d8d2]
+reverse link Failed to Staged--><g id="link_Failed_Staged"><path d="M168.12,269.26 C149.34,276.73 126.74,289.31 115.5,309 C104.88,327.59 112.67,352.18 120.66,368.95 " fill="none" id="Failed-backto-Staged-1" style="stroke:#8B0000;stroke-width:1.0;"/><polygon fill="#8B0000" points="172.81,267.47,162.975,266.9473,168.1396,269.2553,165.8315,274.4199,172.81,267.47" style="stroke:#8B0000;stroke-width:1.0;"/><text fill="#000000" font-family="Consolas,Menlo,monospace" font-size="12" lengthAdjust="spacing" textLength="42" x="116.5" y="328.9883">reject</text></g><!--MD5=[4d415c9b773123c37ce42f12237de1fc]
+link Trial to Updated--><g id="link_Trial_Updated"><path d="M204.5,539.08 C204.5,558.48 204.5,588.61 204.5,609.7 " fill="none" id="Trial-to-Updated" style="stroke:#8B0000;stroke-width:1.0;"/><polygon fill="#8B0000" points="204.5,614.86,208.5,605.86,204.5,609.86,200.5,605.86,204.5,614.86" style="stroke:#8B0000;stroke-width:1.0;"/><text fill="#000000" font-family="Consolas,Menlo,monospace" font-size="12" lengthAdjust="spacing" textLength="42" x="205.5" y="581.9883">accept</text></g><!--MD5=[71ab68107f7e180decc84935bd3705da]
+reverse link Start to Failed--><g id="link_Start_Failed"><path d="M139.23,52 C150.63,83.9 170.75,142.18 184.5,193 C188.63,208.27 192.35,225.81 194.91,238.82 " fill="none" id="Start-backto-Failed" style="stroke:#0000FF;stroke-width:1.0;"/><polygon fill="#0000FF" points="137.47,47.11,136.7338,56.9313,139.1535,51.8181,144.2667,54.2377,137.47,47.11" style="stroke:#0000FF;stroke-width:1.0;"/><text fill="#000000" font-family="Consolas,Menlo,monospace" font-size="12" lengthAdjust="spacing" textLength="35" x="177.5" y="147.9883">clean</text></g><!--MD5=[5b18d785e1ed9c85922a1d1dbb6dfde5]
+reverse link Rejected to Trial--><g id="link_Rejected_Trial"><path d="M252.49,413.88 C241.2,438.38 223.85,476.03 213.39,498.71 " fill="none" id="Rejected-backto-Trial" style="stroke:#8B0000;stroke-width:1.0;"/><polygon fill="#8B0000" points="254.67,409.16,247.2628,415.651,252.572,413.6985,254.5244,419.0078,254.67,409.16" style="stroke:#8B0000;stroke-width:1.0;"/><text fill="#000000" font-family="Consolas,Menlo,monospace" font-size="12" lengthAdjust="spacing" textLength="42" x="240.5" y="458.9883">reject</text></g><!--MD5=[8730496acf69e4d93e6ebba34c197634]
+reverse link Failed to Rejected--><g id="link_Failed_Rejected"><path d="M228.72,272.5 C243.9,280.52 260.86,292.54 269.5,309 C279.28,327.63 275.23,352.21 270.38,368.97 " fill="none" id="Failed-backto-Rejected" style="stroke:#8B0000;stroke-width:1.0;stroke-dasharray:7.0,7.0;"/><polygon fill="#8B0000" points="224.08,270.14,230.2826,277.7904,228.5349,272.4103,233.915,270.6626,224.08,270.14" style="stroke:#8B0000;stroke-width:1.0;"/><text fill="#000000" font-family="Consolas,Menlo,monospace" font-size="12" lengthAdjust="spacing" textLength="42" x="276.5" y="322.3296">reboot</text><text fill="#000000" font-family="Lato,sans-serif" font-size="12" lengthAdjust="spacing" textLength="3" x="318.5" y="321.8375">:</text><text fill="#000000" font-family="Lato,sans-serif" font-size="12" font-style="italic" lengthAdjust="spacing" textLength="39" x="279.5" y="336.2296">rollback</text></g><!--MD5=[91632b8e9666b14c55229d961249920f]
+link Trial to Failed--><g id="link_Trial_Failed"><path d="M229.82,508.82 C248.89,500.81 274.54,487.56 291.5,469 C340.87,414.97 372.29,369.09 330.5,309 C307.81,276.37 260.69,265.42 229.33,261.78 " fill="none" id="Trial-to-Failed" style="stroke:#8B0000;stroke-width:1.0;stroke-dasharray:7.0,7.0;"/><polygon fill="#8B0000" points="224.06,261.22,232.5867,266.1491,229.032,261.7486,233.4325,258.194,224.06,261.22" style="stroke:#8B0000;stroke-width:1.0;"/><text fill="#000000" font-family="Consolas,Menlo,monospace" font-size="12" lengthAdjust="spacing" textLength="42" x="350.5" y="387.3296">reboot</text><text fill="#000000" font-family="Lato,sans-serif" font-size="12" lengthAdjust="spacing" textLength="3" x="392.5" y="386.8375">:</text><text fill="#000000" font-family="Lato,sans-serif" font-size="12" font-style="italic" lengthAdjust="spacing" textLength="39" x="353.5" y="401.2296">rollback</text></g><!--MD5=[43a8c4662c8a2715cf5aeba88f635b26]
+link Updated to End--><g id="link_Updated_End"><path d="M204.5,655.08 C204.5,674.48 204.5,704.61 204.5,725.7 " fill="none" id="Updated-to-End" style="stroke:#0000FF;stroke-width:1.0;"/><polygon fill="#0000FF" points="204.5,730.86,208.5,721.86,204.5,725.86,200.5,721.86,204.5,730.86" style="stroke:#0000FF;stroke-width:1.0;"/><text fill="#000000" font-family="Consolas,Menlo,monospace" font-size="12" lengthAdjust="spacing" textLength="35" x="205.5" y="697.9883">clean</text></g><rect fill="#DDDDDD" height="69.5684" id="_legend" rx="7.5" ry="7.5" style="stroke:#000000;stroke-width:1.0;" width="281" x="54.25" y="784"/><text fill="#000000" font-family="Consolas,Menlo,monospace" font-size="12" lengthAdjust="spacing" textLength="7" x="67.25" y="802.3296">*</text><text fill="#000000" font-family="Lato,sans-serif" font-size="12" lengthAdjust="spacing" textLength="207" x="83.25" y="801.8375">Transient states that always transition at</text><text fill="#000000" font-family="Lato,sans-serif" font-size="12" font-weight="bold" lengthAdjust="spacing" textLength="37" x="292.25" y="801.8375">reboot</text><text fill="#0000FF" font-family="Consolas,Menlo,monospace" font-size="12" lengthAdjust="spacing" text-decoration="line-through" textLength="21" x="60.25" y="816.7217">———</text><text fill="#000000" font-family="Lato,sans-serif" font-size="12" lengthAdjust="spacing" textLength="229" x="83.25" y="816.2296">Blue transitions apply to a single component</text><text fill="#8B0000" font-family="Consolas,Menlo,monospace" font-size="12" lengthAdjust="spacing" text-decoration="line-through" textLength="21" x="60.25" y="831.1138">———</text><text fill="#000000" font-family="Lato,sans-serif" font-size="12" lengthAdjust="spacing" textLength="208" x="83.25" y="830.6217">Red transitions apply to all compoments</text><text fill="#000000" font-family="Consolas,Menlo,monospace" font-size="12" lengthAdjust="spacing" textLength="21" x="60.25" y="845.5059">---</text><text fill="#000000" font-family="Lato,sans-serif" font-size="12" lengthAdjust="spacing" textLength="197" x="83.25" y="845.0138">Dashed lines indicate a transition over</text><text fill="#000000" font-family="Lato,sans-serif" font-size="12" font-weight="bold" lengthAdjust="spacing" textLength="37" x="282.25" y="845.0138">reboot</text></g></svg>
\ No newline at end of file
diff --git a/docs/design_docs/media/hal_structure.png b/docs/design_docs/media/hal_structure.png
new file mode 100644
index 0000000..0f4c4c0
--- /dev/null
+++ b/docs/design_docs/media/hal_structure.png
Binary files differ
diff --git a/docs/design_docs/media/hybridruntime.svg b/docs/design_docs/media/hybridruntime.svg
new file mode 100644
index 0000000..1a485d6
--- /dev/null
+++ b/docs/design_docs/media/hybridruntime.svg
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="362px" height="203px" viewBox="-0.5 -0.5 362 203" content="<mxfile host="app.diagrams.net" modified="2021-09-06T03:17:02.086Z" agent="5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36" etag="i12WVWij0c3EiUyQtPTn" version="14.9.8" type="device"><diagram id="pE8yNmrzc9lT-nbtH71B" name="Page-1">7Vpdk6I4FP01PvYUEMD2UW3tnprZng+7dmeeulKSBnbQODG2sr9+E7kIJIG2abUtd3mwzCU3JPecc7lJ0UHD2eaW4UX0Bw1I0nGsYNNBNx3H8VBP/EpDmhmcHsoMIYuDzGQXhkn8DwGjBdZVHJBlpSOnNOHxomqc0vmcTHnFhhmj62q3J5pUn7rAIdEMkylOdOtfccCjzHrtdAv7HYnDKH+y7cOCZzjvDCtZRjig65IJjTpoyCjl2b/ZZkgSGbs8LpnfuObubmKMzPk+Dl7Ye7x7vP3s3X3yhuv+J5pOrq6cbJRnnKxgwR+/DmG+PM2DwOhqHhA5jt1BgyVn9NcuGmIdgyc65wCdwA3a4G5De4xncSJJ8IAjOsPC+kwYj0Wk+0kczsWNWRwE0mWA2RRGc3zwHtKEsu1k0Hh7SXucJCW7ZfniEnY9MBAr+UCyKZkgULeEzghnqegCd8VomQuw1s/puC444IMpKsHvgg0D68LdyAUw4g9g8wqckIYJCQRPoUkZj2hI5zgZFdZBgZrEpOjzmdIFAPM34TyFWOMVp8IU8VkCLmbYymA7DfBUaYJ2FhNkAimW/pCP/eDlzZ8wx23jZgNzylpp3trEvOQmWj9Ldwon2ch9aumxpCs2JQ0guJB/MAsJb+hnA1oSoka2MZJgHj9XU42JO+D6lcZizgUrLYVu2QqgVzkV5I5Ab4Xd7rUyTrZCbZwtc3fTb09mV0s695OOkLqDttmjHxJ47n86B9n2meUg29ZwO6+XRfd9gELeuQGFNKAm4/sGoCwDLGbgal4HJfhqgTqCJDz3vSOtp7LLiLTKabd7ukinV+H95Bv+M/71/fF3+vjjYfQlyd8ZF1sAtShk2hZNexVAozHp9ckm/Watpzz10ff7BF35+xZA7pELoJzD170PvfJV4Wy3bXlku0qacY5WHxm57l8C13NG22U+79hdx+igL/fscpUipWaWcSyjVyomKvoZiquihbISSsJ4ixYaX7IvisE5jRaQWi52W7J/l9ffif3di2D/yZncRm/t2e/s+yawT8N+p6eQ1m/N/qZXiof204LAHqelbgvZYfkK8SKrcZYv9Bd/shkcVJiG/V9/8FFTq6gwudyXQVU6FdwirKlcNVTHL24HFSXu6iiDruSlbwClcq1GDexfLKvcu3aF7tRq2TVUy2pmPVi1bNgBPkSM4OBM0IJcV4dJPYoHQMvueoqmXQ0s70hgGatq/Qz+YmSloWLArn4PqurK1oE6lqqMQOmi+h8oI1AnTYBGqPRzmUvKf29Cy+lV859vmdA6aQb0NbTO5hTtbcJQTtFOeV5pDPRF7K3O6RRN2de0PErIP2wo7abqdXL4UzSVpV7bczN1oIOdHIhm8aFE1r342gSN/gU=</diagram></mxfile>"><defs/><g><rect x="150" y="151" width="60" height="40" rx="10.4" ry="10.4" fill="#006666" stroke="#000000" stroke-width="2" pointer-events="all"/><g fill="#FFFFFF" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="10px"><text x="179.5" y="174.5">IPC</text></g><path d="M 60 151 L 60 131.1" fill="none" stroke="#006666" stroke-width="3" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 60 124.35 L 64.5 133.35 L 60 131.1 L 55.5 133.35 Z" fill="#006666" stroke="#006666" stroke-width="3" stroke-miterlimit="10" pointer-events="all"/><rect x="30" y="151" width="60" height="40" rx="10.4" ry="10.4" fill="#006666" stroke="#000000" stroke-width="2" pointer-events="all"/><g fill="#FFFFFF" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="10px"><text x="59.5" y="168.5">NS</text><text x="59.5" y="180.5">Agent</text></g><rect x="270" y="151" width="60" height="40" rx="10.8" ry="10.8" fill="#006666" stroke="#000000" stroke-width="2" pointer-events="all"/><g fill="#FFFFFF" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="10px"><text x="299.5" y="174.5">IPC</text></g><rect x="30" y="81" width="60" height="40" fill="#ffffff" stroke="#000000" stroke-width="2" pointer-events="all"/><g fill="#000000" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="10px"><text x="59.5" y="104.5">SFN</text></g><rect x="270" y="11" width="60" height="40" fill="#ffffff" stroke="#000000" stroke-width="2" pointer-events="all"/><g fill="#000000" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="10px"><text x="299.5" y="34.5">SFN</text></g><path d="M 300 81 L 300 61.1" fill="none" stroke="#006666" stroke-width="3" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 300 54.35 L 304.5 63.35 L 300 61.1 L 295.5 63.35 Z" fill="#006666" stroke="#006666" stroke-width="3" stroke-miterlimit="10" pointer-events="all"/><path d="M 90 101 L 120.03 101.03 L 120.03 171.03 L 147 171" fill="none" stroke="#00cccc" stroke-width="3" stroke-miterlimit="10" pointer-events="stroke"/><ellipse cx="150" cy="171" rx="3" ry="3" fill="#00cccc" stroke="#00cccc" stroke-width="3" pointer-events="all"/><path d="M 210 171 L 230.03 171.03 L 267 171" fill="none" stroke="#00cccc" stroke-width="3" stroke-miterlimit="10" pointer-events="stroke"/><ellipse cx="270" cy="171" rx="3" ry="3" fill="#00cccc" stroke="#00cccc" stroke-width="3" pointer-events="all"/><rect x="10" y="125.5" width="40" height="20" fill="#ffff00" stroke="#000000" pointer-events="all"/><g fill="#006666" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="12px"><text x="29.5" y="140">ABI</text></g><rect x="95" y="75" width="50" height="20" fill="#ffff00" stroke="#000000" pointer-events="all"/><g fill="#00CCCC" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="12px"><text x="119.5" y="89.5">Thread</text></g><rect x="310" y="55" width="40" height="20" fill="#ffff00" stroke="#000000" pointer-events="all"/><g fill="#006666" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="12px"><text x="329.5" y="69.5">ABI</text></g><rect x="310" y="125.5" width="40" height="20" fill="#ffff00" stroke="#000000" pointer-events="all"/><g fill="#006666" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="12px"><text x="329.5" y="140">ABI</text></g><rect x="215" y="145.5" width="50" height="20" fill="#ffff00" stroke="#000000" pointer-events="all"/><g fill="#00CCCC" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="12px"><text x="239.5" y="160">Thread</text></g><rect x="270" y="81" width="60" height="40" fill="#ffffff" stroke="#000000" stroke-width="2" pointer-events="all"/><g fill="#000000" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="10px"><text x="299.5" y="104.5">SFN</text></g><path d="M 300 151 L 300 131.1" fill="none" stroke="#006666" stroke-width="3" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 300 124.35 L 304.5 133.35 L 300 131.1 L 295.5 133.35 Z" fill="#006666" stroke="#006666" stroke-width="3" stroke-miterlimit="10" pointer-events="all"/></g></svg>
\ No newline at end of file
diff --git a/docs/design_docs/media/mailbox_ns_agent1.svg b/docs/design_docs/media/mailbox_ns_agent1.svg
new file mode 100644
index 0000000..5c799bd
--- /dev/null
+++ b/docs/design_docs/media/mailbox_ns_agent1.svg
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Do not edit this file with editors other than diagrams.net -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="464px" height="222px" viewBox="-0.5 -0.5 464 222" content="<mxfile host="app.diagrams.net" modified="2022-03-01T01:46:51.777Z" agent="5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36" etag="ZlGN284FfhJiTgM44jcv" version="16.6.4" type="device"><diagram id="0CR0-B0AtPDSijsltwSn" name="Page-1">7Zhdb9owFIZ/DZdMiR2guSwUWFXRMaXr6KVJTGLNiZkxX/31sxPnCwOjtHTVNpAQfp2c2M97fGxowF68GXI0j0YswLQBrGDTgDcNANotID+VsM0Ex9JCyEmQSXYpeOQZa9HS6pIEeFG7UDBGBZnXRZ8lCfZFTUOcs3X9shmj9afOUYgNwfMRNdXvJBBRpl6BTql/xiSM8ifbbTfriVF+sZ7JIkIBW1ck2G/AHmdMZN/iTQ9TxS7nkt03ONBbDIzjRJxyg8ud5sT/ApLp7eTRm6xa7vq2abeyMCtEl3rGerRimyPASXCtSMpWwhIpdgO0iLAKa8vGQnD2o4Ajp9XlbJkEab8lWzOWiB6jjKfRoJW+pG6OX08JBzVL9GyGmMVY8K28YF0a0dJwo4oHucYxRYKs6kYinQ9hEa54wpgRORJg6dSFHfcT1Hfp5AUdtx5lwZbcx/rGKvvdWFdWLVDezOMIxEMsjDjyS2XipZQ6+xKX4X+XDzgDoPs2FsvK9k4Wf717+PnU7W/96ZPdbjrDb8O7+2Y+84rFg0FzJJXr8a1hdumdrb0boJhQNfQHFLEYSRVxX5fj1lEjV5gLvDlqZd5r1xHZOaOK1RDs8RpYh22tgXwpNQcY1B74ciGe1QoAljfHPpkRP6doeVgYLOXkRbFA8iWgl9CMULojIUrCRDZ9yRFLvav4EbnhXOuOmASBir1ngZkmXcAV0DZdcS9kyt5qZXqiM7nH4jklKF113nh0VlZXHanWqZ36NUhfF0p7aAJ2rD2EnUsRNreDESJ0yjZSvPdUtoc4MTN9h2+dpHOj3oe5X44vdHcS2Db52pcqK3v5Ogbf/ka8ohQfQ70P6tuXbsf5fenuvCdi89zqYX/JVdUeI1lQBWHJWazfAFZxNvkwCdk5us2dvuRPyc5+W73PORK+Ys/644TttoE4y0OVhn/x6aE4LXyU04Nt5nq5uf0TBzoHvJslsln+gZH9lCn/BYL9Xw==</diagram></mxfile>"><defs/><g><path d="M 303.31 210 L 304 11" fill="none" stroke="rgb(0, 0, 0)" stroke-width="2" stroke-miterlimit="10" stroke-dasharray="6 6" pointer-events="stroke"/><path d="M 163 210 L 164 11" fill="none" stroke="rgb(0, 0, 0)" stroke-width="2" stroke-miterlimit="10" stroke-dasharray="6 6" pointer-events="stroke"/><rect x="34" y="111" width="320" height="20" rx="10" ry="10" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g fill="rgb(0, 0, 0)" font-family="Tahoma" text-anchor="middle" font-size="12px"><text x="193.5" y="125.5">FF-M API</text></g><rect x="34" y="191" width="90" height="20" fill="none" stroke="none" pointer-events="all"/><g fill="rgb(0, 0, 0)" font-family="Tahoma" text-anchor="middle" font-size="12px"><text x="78.5" y="205.5">Trustzone Specific API Set</text></g><rect x="34" y="61" width="400" height="40" rx="6" ry="6" fill="#000000" stroke="rgb(0, 0, 0)" pointer-events="all"/><g fill="#FFFFFF" font-family="Tahoma" text-anchor="middle" font-size="12px"><text x="233.5" y="85.5">FF-M Compliant SPM</text></g><rect x="314" y="141" width="120" height="20" rx="3" ry="3" fill="#4d4d4d" stroke="rgb(0, 0, 0)" pointer-events="all"/><g fill="#FFFFFF" font-family="Tahoma" text-anchor="middle" font-size="12px"><text x="373.5" y="155.5">Mailbox NS Agent</text></g><rect x="364" y="111" width="70" height="20" rx="10" ry="10" fill="#4d4d4d" stroke="rgb(0, 0, 0)" pointer-events="all"/><g fill="#FFFFFF" font-family="Tahoma" text-anchor="middle" font-size="12px"><text x="398.5" y="125.5">Ext API</text></g><rect x="174" y="141" width="120" height="20" rx="3" ry="3" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g fill="rgb(0, 0, 0)" font-family="Tahoma" text-anchor="middle" font-size="12px"><text x="233.5" y="155.5">Secure Partition</text></g><rect x="34" y="141" width="120" height="20" rx="3" ry="3" fill="#e6e6e6" stroke="rgb(0, 0, 0)" pointer-events="all"/><g fill="#000000" font-family="Tahoma" text-anchor="middle" font-size="12px"><text x="93.5" y="155.5">Trustzone NS Agent</text></g><rect x="184" y="191" width="90" height="20" fill="none" stroke="none" pointer-events="all"/><g fill="rgb(0, 0, 0)" font-family="Tahoma" text-anchor="middle" font-size="12px"><text x="228.5" y="205.5">Partiton API Set</text></g><rect x="344" y="191" width="90" height="20" fill="none" stroke="none" pointer-events="all"/><g fill="rgb(0, 0, 0)" font-family="Tahoma" text-anchor="middle" font-size="12px"><text x="388.5" y="205.5">Mailbox Specific API Set</text></g></g></svg>
\ No newline at end of file
diff --git a/docs/design_docs/media/modelisolation.svg b/docs/design_docs/media/modelisolation.svg
new file mode 100644
index 0000000..05bc071
--- /dev/null
+++ b/docs/design_docs/media/modelisolation.svg
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Do not edit this file with editors other than diagrams.net -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="462px" height="342px" viewBox="-0.5 -0.5 462 342" content="<mxfile host="app.diagrams.net" modified="2021-09-17T06:56:27.058Z" agent="5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36" etag="a4te_vN3EQJEAzAJBS9K" version="15.2.9" type="device"><diagram id="z2eWvvA0n7qyoBdv0BDn" name="Page-1">3Zptc6I6FIB/jR/b4S2oH6t92Z3bdb3X3bm3+6WTStRMkTgQre6vvwkEhCRY1kJRccaBQxLIec45OQnp2MPl9iGEq8U34iG/YxnetmPfdiyr27PYPxfsEoFjgUQwD7GXiMy9YIJ/IyE0hHSNPRQVClJCfIpXReGUBAGa0oIMhiF5KxabEb/41BWcI0UwmUJflf6LPbpIpD2ru5d/QXi+SJ9suv3kzhKmhUVPogX0yFtOZN917GFICE3Oltsh8rnuUr0k9e5L7mYvFqKAVqnwPNiYj2Tw7P4MwrkFX3+N3OcrQWcD/bXo8GjCroc+5q0m7013qTJCsg48xNszOvbAhy/IH5MIU0wCJpuyKihkNzYopJip8FEqsMSex5saQB/PtTVuxI2s5IwEdCJewOTX2PeHxCdh/EL2DPCfKHcPl9jnZvYDLsgSMmlEQ/KK0vIBCVAmTGGaonKu0eRgclXDQun8ddE2JxIaf0BkiWi4Y0XE3Yx+av5AXL/tjclMyyxyhmTZQgiFAc+ztveM2YnArEc+enjaztbfHbCK/v7Lfvr+tvPWV46CvD3OlKx0kLUwJUoGO/r9MsiSnQziXz1IgVsBqaFBajaG1FaQjv8hP5jklqkOB+3xfSGUkmVlxHqUJdwbRJwhFYhBV0WcjVAFxGZTiNVAfflee+fyXz1Ibed9pObnIjUVpDen4bWXwFcXlS3dQJuNvh/hq82tVL4KUhR4NzxJLUa7ssCY5iyOol+h+eGQ3UFbTP/jRnINxNWTMBl+frvNX+zERSmAiKzDKTrUSZHOI6+QR6ucchyABkMqC5EPKd4Us28dGvGEMcE8Uc3MwCyagduT6CYdErXy2bLckGxPjtQQheEcUaWh2FKybh9vPOqQngQHtxP30R6MIXPa2LUPx4nYjZNpVV+xJOugX+e9v3Rk92C0iB9miosxpCysBLHEMky9rbrsqGms7kqgeqrj9zQGJxtGbW6v5tcSuQkKN3jKJrWVwcXV9POW98jVoOCeNHIaqoJdjYLryHa1CgZ1uIZm3mfER6mP5Jyo2tBY6jIwnIrGLHACHmRLExrQtge5F+ZBthSiQL97Ddr1oa6iYr7ukyn4Zn54+edo7zGNo91nvyZUMvHLuZV7gm7V+sDUU5hPxt8+5ELHpw9lMDMrkqzrPj7K5hUVUDeQabQeJ/sK0PGF5IiCaw3QwKlBSyco5dTObHQDUn7otp0fmurE+wi/OOcEsTn3aX0QM9WF0Mtyn9anV6a69DAZ3ynaZN2jVdb5hChddPTRjB7KB1RIJQgEOqvE23QrY3UkddKXAcdSaTkaWs0tMqrLDaMacYVJF86Wl9U/NV7q6sXXiPA1Tz4aGY9oE++f4HF9wFULxTNrYPn+1/YTh2lLH9Pdftsw1Wm0DqZ1FjDNKjDrmx4DG5yYZ6rz469j1pQh9jQdlSlqCDa+PrLPHu1eTVFUcryuhpUuC2yOlTr1ndyPKrD69DWN+lJxOfq1DiFtuP4PnFZjy3cn8plS/qbSlbP5qp8pHVs2in66tPxJHyotdbatGwPtQ2MgpxJvV/iTiQKK8G/4EjfBvXjFOxh3GQw64LYkU1EtT95HIWe8pdso4ooDOH2dx+HlvV1LpZZ52Lfk8JDtdBVd7+Q3k+rCxpVx7dRis2mNnbY+mc0i9FED026TUYflClFG3TChjgE6PGccUkBJcvynIUXZ31hx5wMjAHe5YsIhK79wutRU9b2k8uwkeYOKxscu93uvk+L7Dez23f8=</diagram></mxfile>"><defs/><g><rect x="11" y="40" width="120" height="230" fill="#f5f5f5" stroke="none" pointer-events="all"/><g fill="#333333" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="12px"><text x="70.5" y="159.5">NS Client</text></g><rect x="351" y="40" width="100" height="130" fill="#b3b3b3" stroke="none" pointer-events="all"/><rect x="241" y="160" width="210" height="110" fill="#b3b3b3" stroke="none" pointer-events="all"/><g fill="#000099" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="12px"><text x="345.5" y="264.5">PRoT Domain</text></g><rect x="131" y="160" width="110" height="110" fill="#e6e6e6" stroke="none" pointer-events="all"/><rect x="131" y="40" width="220" height="120" fill="#e6e6e6" stroke="none" pointer-events="all"/><g fill="#000099" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="12px"><text x="240.5" y="57.5">ARoT Domain</text></g><path d="M 131 280 L 131 30" fill="none" stroke="#0000cc" stroke-width="4" stroke-miterlimit="10" pointer-events="stroke"/><rect x="261" y="70" width="80" height="80" fill="#ffffff" stroke="#006666" stroke-width="2" stroke-dasharray="2 2" pointer-events="all"/><g fill="#000000" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="9px"><text x="300.5" y="133.5">ARoT</text><text x="300.5" y="144.5">Partition</text></g><rect x="271" y="90" width="60" height="30" fill="#ffffff" stroke="#000000" pointer-events="all"/><g fill="#000000" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="10px"><text x="300.5" y="102.5">ARoT</text><text x="300.5" y="114.5">Services</text></g><rect x="151" y="170" width="80" height="80" rx="20" ry="20" fill="#ffffff" stroke="#006666" stroke-width="2" stroke-dasharray="2 2" pointer-events="all"/><g fill="#000000" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="9px"><text x="190.5" y="233.5">ARoT</text><text x="190.5" y="244.5">Partition</text></g><rect x="161" y="187.5" width="60" height="30" fill="#ffffff" stroke="#000000" pointer-events="all"/><g fill="#000000" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="10px"><text x="190.5" y="200">ARoT</text><text x="190.5" y="212">Services</text></g><rect x="151" y="70" width="80" height="80" rx="20.8" ry="20.8" fill="#b3b3b3" stroke="#006666" stroke-width="2" stroke-dasharray="2 2" pointer-events="all"/><g fill="#000000" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="10px"><text x="190.5" y="107.5">NS</text><text x="190.5" y="119.5">Agent</text></g><rect x="261" y="170" width="80" height="80" fill="#000000" stroke="none" pointer-events="all"/><g fill="#FFFFFF" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="10px"><text x="300.5" y="213.5">SPM</text></g><rect x="361" y="170" width="80" height="80" fill="#ffffff" stroke="none" pointer-events="all"/><g fill="#000000" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="9px"><text x="400.5" y="233.5">PRoT</text><text x="400.5" y="244.5">Partition</text></g><rect x="371" y="190" width="60" height="30" fill="#ffffff" stroke="#000000" pointer-events="all"/><g fill="#000000" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="10px"><text x="400.5" y="202.5">PRoT</text><text x="400.5" y="214.5">Services</text></g><rect x="361" y="70" width="80" height="80" rx="20" ry="20" fill="#ffffff" stroke="none" pointer-events="all"/><g fill="#000000" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="9px"><text x="400.5" y="133.5">PRoT</text><text x="400.5" y="144.5">Partition</text></g><rect x="371" y="90" width="60" height="30" fill="#ffffff" stroke="#000000" pointer-events="all"/><g fill="#000000" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="10px"><text x="400.5" y="102.5">PRoT</text><text x="400.5" y="114.5">Services</text></g><rect x="141" y="10" width="40" height="20" fill="none" stroke="none" pointer-events="all"/><g fill="#0000CC" font-family="Tahoma" font-weight="bold" font-size="12px"><text x="142.5" y="24.5">SPE</text></g><rect x="81" y="10" width="40" height="20" fill="none" stroke="none" pointer-events="all"/><g fill="#0000CC" font-family="Tahoma" font-weight="bold" text-anchor="end" font-size="12px"><text x="118.5" y="24.5">NSPE</text></g><rect x="111" y="280" width="40" height="20" fill="none" stroke="none" pointer-events="all"/><g fill="#0000CC" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="12px"><text x="130.5" y="294.5">Isolation Level 1 Boundary</text></g><rect x="326" y="10" width="40" height="20" fill="none" stroke="none" pointer-events="all"/><g fill="#006666" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="11px"><text x="345.5" y="24">Isolation Level 2 Boundary</text></g><rect x="11" y="310" width="80" height="20" rx="7.6" ry="7.6" fill="none" stroke="#000000" stroke-width="2" pointer-events="all"/><g fill="#000000" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="10px"><text x="50.5" y="323.5">IPC Model</text></g><rect x="111" y="310" width="80" height="20" fill="none" stroke="#000000" stroke-width="2" pointer-events="all"/><g fill="#000000" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="10px"><text x="150.5" y="323.5">SFN Model</text></g><path d="M 271 320 L 221 319.5" fill="none" stroke="#006666" stroke-width="2" stroke-miterlimit="10" stroke-dasharray="2 2" pointer-events="stroke"/><g fill="#006666" font-family="Tahoma" font-size="12px"><text x="278.5" y="325.85">Isolation Level 3 Boundary</text></g><path d="M 241 280 L 241 160 L 351 160 L 351 30" fill="none" stroke="#006666" stroke-width="4" stroke-miterlimit="10" pointer-events="stroke"/></g></svg>
\ No newline at end of file
diff --git a/docs/design_docs/media/spestate.svg b/docs/design_docs/media/spestate.svg
new file mode 100644
index 0000000..9b436f9
--- /dev/null
+++ b/docs/design_docs/media/spestate.svg
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Do not edit this file with editors other than diagrams.net -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="545px" height="352px" viewBox="-0.5 -0.5 545 352" content="<mxfile host="app.diagrams.net" modified="2021-09-17T08:07:56.757Z" agent="5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36" etag="jj3Jf5IRjsPlaCu4d2ZX" version="15.2.9" type="device"><diagram id="pE8yNmrzc9lT-nbtH71B" name="Page-1">7ZpZc6M4EIB/jR+dAoTAPPrMJjvZ8awnm+NNA7IhAeQRsmPy60eAMIfwMVnbSWXsVKVQ02oa9ddNI7sF+sHqkqK5e0Mc7Lc0xVm1wKClaWZH4/8TQZwJdA1mghn1nEykFoKJ94qFUBHShefgqKLICPGZN68KbRKG2GYVGaKUvFTVpsSvXnWOZlgSTGzky9I7z2FuJu1oZiH/C3szN7+yaljZmQDlyuJOIhc55KUkAsMW6FNCWHYUrPrYT9YuX5ds3mjD2bVjFIdsnwmPwLa+tr89IP2bFY+uHpUXMGyDzMoS+Qtxw1ehxzzke69eOBOOszhfDUoWoYMTg0oL9Hz0A/tjEvEJJOQym3uCKT+xxJR5fA2/1BQCz3ESUz1uf9Y4oytOrDUjRsnzeun5ovWmJGQT4ZIqxiMUeH5C2HfkkgDlvvUIdTDtE5/wawxCEhYWa8Kp5/u5qKWBjpL8CeMl+Sj95E5ksKo6H8vBEPFJbgyvSiIRnEtMAsxozFXEWc0UoOSZ0hHjl4I7NU8Lt8wcFEIkWJ+tbRc48ANBRDMdN/eXbt8O4O2j/7P7avm3NrluqxIA2OHZIYZi6ewFXaZIJMEglLlkRkIee0LmQviEGYvFaqEFI1zkssAXFOGVx+6FZnL8kMgvoBgNViW1QSwGtbAo6UeiBUjRTnUN/kkMhnyJ7nPryaB05WRYXDod5dfeGOqILKiNdycbQ3SGxVRwtxqz0bI9vRwOei566PZX17lestZbwaHYR8xbVitVEwRi6ph43OU1cLpeBQ5C64KvTMVKdk9iYrm41G1pG+DNDWU3LRlKsVzf0l6k/kSd57v+7Xfn6cd/T+140b6OwrYp1bGt6BaYDgtpr1rd9kU557dg9qFEczO/BXsFbutZW9jbVI5+h/u9+G3kUn1XfruUorikME9YijbjbRiwgqRhKtsRtrbq84PMg7dyu21Jy8/fwZfh+bl7wueuob7nc7eRCk2ioofs51lKwZmNE7IBamwAU2ZjLSuzYR4LDblhn2C6PPfqp+Wi3jp9gJqhn3v1N/bq2/JsZ6+jnqZXh6DWqyvWBXxbqw7Nett/tFa9y66m0fWgfb1U9RhMHx1g2g0tTy/ZA9GUxVxCmKcj26cMCNH+papaHJvLUrV4HeAFX6ktvAqloqE31AztACWjMRLb35EOVDI+ZPofO12lUMM3Jmt9UwhCvZ73R07XhoZjfMMFyT5hSzNaaY8EeoOElk+dvsCqp6/8zG9KX3Cs9NWlyPwzGQ9LMfkXIyf+3EGBxgcLirEhKErapvOWQ1O6to2j6JPHpbYfaDS8OKnaKQMj7xCOKcbBPH3d+dSx0OsbHLoci84pQ2H9saGAnfcLxeTvHoYhQJMhHNx+JV4MYT8vVx+/BXy3Vg7s+mZj31YOgB2GNjRyv7vvLTmsb9/3lvyq6v/vfe9G7swzd7u+nbMOxB1UTsOd5PAO7iS/TsFd58zdDu4M40DcGZt+z3Bg7iSHd3An+XUK7v7clkerb5Ufr+Xhw+LnVFnkit+kgeEv</diagram></mxfile>"><defs/><g><rect x="83" y="121" width="110" height="150" fill="#808080" stroke="none" pointer-events="all"/><g fill="#FFFFFF" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="14px"><text x="137.5" y="201.5">Initializing</text></g><path d="M 193 196 Q 193 196 242.9 196" fill="none" stroke="#006666" stroke-width="3" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 249.65 196 L 240.65 200.5 L 242.9 196 L 240.65 191.5 Z" fill="#006666" stroke="#006666" stroke-width="3" stroke-miterlimit="10" pointer-events="all"/><path d="M 478 271 L 478 311 L 308 311 L 308 281.1" fill="none" stroke="#006666" stroke-width="3" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 308 274.35 L 312.5 283.35 L 308 281.1 L 303.5 283.35 Z" fill="#006666" stroke="#006666" stroke-width="3" stroke-miterlimit="10" pointer-events="all"/><rect x="423" y="121" width="110" height="150" fill="#808080" stroke="none" pointer-events="all"/><g fill="#FFFFFF" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="14px"><text x="477.5" y="201.5">IDLE</text></g><rect x="123" y="11" width="370" height="70" fill="#808080" stroke="none" pointer-events="all"/><g fill="#FFFFFF" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="14px"><text x="307.5" y="51.5">Background</text></g><rect x="253" y="121" width="110" height="150" fill="#808080" stroke="none" pointer-events="all"/><g fill="#FFFFFF" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="14px"><text x="307.5" y="201.5">Serving</text></g><path d="M 363 196 Q 363 196 412.9 196" fill="none" stroke="#006666" stroke-width="3" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 419.65 196 L 410.65 200.5 L 412.9 196 L 410.65 191.5 Z" fill="#006666" stroke="#006666" stroke-width="3" stroke-miterlimit="10" pointer-events="all"/><rect x="13" y="156" width="40" height="20" fill="none" stroke="none" pointer-events="all"/><g fill="#000000" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="12px"><text x="32.5" y="170.5">Boot up</text></g><path d="M 13 196 Q 13 196 72.9 195.57" fill="none" stroke="#006666" stroke-width="3" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 79.65 195.52 L 70.68 200.09 L 72.9 195.57 L 70.61 191.09 Z" fill="#006666" stroke="#006666" stroke-width="3" stroke-miterlimit="10" pointer-events="all"/><rect x="203" y="151" width="40" height="30" fill="none" stroke="none" pointer-events="all"/><g fill="#000000" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="12px"><text x="222.5" y="163.5">SPM Init</text><text x="222.5" y="177.5">Done</text></g><rect x="373" y="151" width="40" height="30" fill="none" stroke="none" pointer-events="all"/><g fill="#000000" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="12px"><text x="392.5" y="163.5">NSPE</text><text x="392.5" y="177.5">Ready</text></g><rect x="333" y="311" width="120" height="30" fill="none" stroke="none" pointer-events="all"/><g fill="#000000" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="12px"><text x="392.5" y="330.5">NSPE Service Access</text></g><rect x="223" y="81" width="80" height="30" fill="none" stroke="none" pointer-events="all"/><g fill="#000000" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="12px"><text x="262.5" y="100.5">Preemption</text></g><rect x="393" y="81" width="80" height="30" fill="none" stroke="none" pointer-events="all"/><g fill="#000000" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="12px"><text x="432.5" y="100.5">Preemption</text></g><path d="M 133 121 Q 133 81 138 81 Q 143 81 143 110.9" fill="none" stroke="#006666" stroke-width="3" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 143 117.65 L 138.5 108.65 L 143 110.9 L 147.5 108.65 Z" fill="#006666" stroke="#006666" stroke-width="3" stroke-miterlimit="10" pointer-events="all"/><path d="M 303 121 Q 303 81 308 81 Q 313 81 313 110.9" fill="none" stroke="#006666" stroke-width="3" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 313 117.65 L 308.5 108.65 L 313 110.9 L 317.5 108.65 Z" fill="#006666" stroke="#006666" stroke-width="3" stroke-miterlimit="10" pointer-events="all"/><path d="M 473 121 Q 473 81 478 81 Q 483 81 483 110.9" fill="none" stroke="#006666" stroke-width="3" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 483 117.65 L 478.5 108.65 L 483 110.9 L 487.5 108.65 Z" fill="#006666" stroke="#006666" stroke-width="3" stroke-miterlimit="10" pointer-events="all"/><rect x="53" y="81" width="80" height="30" fill="none" stroke="none" pointer-events="all"/><g fill="#000000" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="12px"><text x="92.5" y="100.5">Preemption</text></g></g></svg>
\ No newline at end of file
diff --git a/docs/design_docs/media/spmabitypes.svg b/docs/design_docs/media/spmabitypes.svg
new file mode 100644
index 0000000..e0e45e5
--- /dev/null
+++ b/docs/design_docs/media/spmabitypes.svg
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="423px" height="303px" viewBox="-0.5 -0.5 423 303" content="<mxfile host="app.diagrams.net" modified="2021-09-10T10:28:55.524Z" agent="5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36" etag="_JZ6fR9ln1KZGVaMcIWN" version="15.0.6" type="device"><diagram id="z2eWvvA0n7qyoBdv0BDn" name="Page-1">7Ztfc6o4FMA/DY91IPyTx2rr9u703nHW7tzZvnRyIQJbJE6Mtt5PvwkGFAKKFapboTMdOYRDOL+Tc05iVPTh7P0PAufBd+yhSAGq967odwoAlgnYfy5YbwS6aWwEPgm9jUjbCibhbySEqpAuQw8tcg0pxhEN53mhi+MYuTQng4Tgt3yzKY7yT51DH0mCiQsjWfoz9GiwkfaBvZU/oNAP0idrlrO5MoNpY/EmiwB6+G1HpN8r+pBgTDefZu9DFHHbpXbZ3DequJp1jKCY1rkheH64+xP8tHz96duSjh60++d/boDAs4LRUryx6C1dpyYgeBl7iGtRFX0wxTEVmBx2uqAEv2amAaLBCM7CiBN/ggGewfQ2oVNj5ytEaMjMfBuFfsxks9Dz+MXBNIyiIY4wSR6uq+qQHdmD0isxjnlj0XmmC71XmkXLjM2cFOEZomTNmqQeqgo+69Rj1Z4hjPC2Q1y0CnZgG0IGhY/5mfItBvZBkDiGitZRyVOxjfNT0Zxrp2IYhbGS2v8AEk1tjUm/Y5JnYqo1mVgNMHkZrLRHPHix/o6JD+Dr8w/r5caUkNz+hZ8UYDFzaBzBGDLb0RDHe1BpwuY5U/KjktkO1CKscqSVCCFxhTJgslMPLoKsT/xkDClFJE4kQNUkuElfLXZkhCWcJdArCetWgbBVj3ATgbAUsC0B/jHZwXvr83dtAa2mns62MDwHyV+euXWJzGuO6taYa3JJMu5GdYOE6+bS1sobOZN+IGx/RoZtgNxJGVciB85MLp0rnzY2rxGdbZwZHZDRXVn9Wpzp1a5fVbOlVCcHwsn4e30qWnUyOwVLPmuOkqMKi8SwubRlgo/hyoTNDyFdYoM8H6VWFSZxl2SVRR5MaIB9HMPoEeO5EP6LKF0LhnBJMRMFdBbtAD5cteg1Ahjv3LFjhaAI0nCVv6/MkuLWMQ55CV45R9ScntnPa1ngJXGRuHF3GbGgS3KAEl0UEh9RSVeCN3urE4ibHfFjidsNEi/R1TZxeco5JHix2ClxBjweQ26T7UR08K3UUR7hLxTxGYEIsi6Dgci+6EvQIvwNfyVKuOY5f9Hk1c2BYt4xScR1DqD76ieJoRiQawX/qhhfmWXFlx6iY0r2VcOuf+0ZQZVBXu0Je5/ohTegn/OcbOSmKvB0ukDteIzVxYgjY4SlNxcjynS1HSP6HfFjiTuMku1sj4bg71fbth84nR8c6Qe26fQcp3E/OKC2ZT/Q5an1aBm7ySrIECi36hByJWepFsrrgcM1xJmqBedAtWCofb2Q6JupHzS7oBZ8Vv2gy+swXRTJ05FWbgDoqR+sH7LV7z262o4X3azyWOIN5Y0i/DPnDetr543m84N+aDb5FfOD3UWLI6OFZbUSLQ6obTtayN8WXNjK1IXGDPsKY0Y3Mz26puwbTaxQSOXlfrUtxwxDnplO3AB5S+YG/6eo8HkzUP0KZ6DpduduQ87BLQTFiuACtvBr8i7Ybk9OLXoXsdW/kbH3tXY7Ngq59n7WBjb5lBPWmxifHeFqwpbZ1hhmp9ufzW3S7fa3h/r9fw==</diagram></mxfile>"><defs/><g><rect x="251" y="161.42" width="80" height="40" fill="#00cccc" stroke="none" pointer-events="all"/><rect x="251" y="251.42" width="80" height="40" fill="#00cccc" stroke="none" pointer-events="all"/><rect x="91" y="191" width="80" height="100" fill="#00cccc" stroke="none" pointer-events="all"/><rect x="91" y="11" width="80" height="160" fill="#00cccc" stroke="none" pointer-events="all"/><rect x="11" y="71" width="80" height="40" rx="10" ry="10" fill="#ffffff" stroke="#006666" stroke-width="2" stroke-dasharray="2 2" pointer-events="all"/><g fill="#000000" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="9px"><text x="50.5" y="88.5">ARoT</text><text x="50.5" y="99.5">Partition</text></g><rect x="11" y="11" width="80" height="40" rx="10.4" ry="10.4" fill="#b3b3b3" stroke="#006666" stroke-width="2" stroke-dasharray="2 2" pointer-events="all"/><g fill="#000000" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="10px"><text x="50.5" y="28.5">NS</text><text x="50.5" y="40.5">Agent</text></g><rect x="11" y="191" width="80" height="40" rx="10" ry="10" fill="#ffffff" stroke="#006666" stroke-width="2" stroke-dasharray="2 2" pointer-events="all"/><g fill="#000000" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="9px"><text x="50.5" y="208.5">PRoT</text><text x="50.5" y="219.5">Partition</text></g><rect x="11" y="131" width="80" height="40" fill="#ffffff" stroke="#006666" stroke-width="2" stroke-dasharray="2 2" pointer-events="all"/><g fill="#000000" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="9px"><text x="50.5" y="148.5">ARoT</text><text x="50.5" y="159.5">Partition</text></g><rect x="11" y="251" width="80" height="40" fill="#ffffff" stroke="#006666" stroke-width="2" stroke-dasharray="2 2" pointer-events="all"/><g fill="#000000" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="9px"><text x="50.5" y="268.5">PRoT</text><text x="50.5" y="279.5">Partition</text></g><rect x="251" y="11" width="80" height="105" fill="#00cccc" stroke="none" pointer-events="all"/><rect x="171" y="11" width="80" height="280" fill="#006666" stroke="none" pointer-events="all"/><g fill="#FFFFFF" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="10px"><text x="210.5" y="154.5">SPM</text></g><path d="M 91 30.58 Q 91 30.58 160.9 30.58" fill="none" stroke="#006666" stroke-width="3" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 167.65 30.58 L 158.65 35.08 L 160.9 30.58 L 158.65 26.08 Z" fill="#006666" stroke="#006666" stroke-width="3" stroke-miterlimit="10" pointer-events="all"/><path d="M 91 90.58 Q 91 90.58 160.9 90.58" fill="none" stroke="#006666" stroke-width="3" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 167.65 90.58 L 158.65 95.08 L 160.9 90.58 L 158.65 86.08 Z" fill="#006666" stroke="#006666" stroke-width="3" stroke-miterlimit="10" pointer-events="all"/><g fill="#FFFFFF" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="11px"><text x="131.25" y="57">Cross</text><text x="131.25" y="70">Boundary</text><text x="131.25" y="83">ABI</text></g><path d="M 91 150.58 Q 91 150.58 160.9 150.58" fill="none" stroke="#006666" stroke-width="3" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 167.65 150.58 L 158.65 155.08 L 160.9 150.58 L 158.65 146.08 Z" fill="#006666" stroke="#006666" stroke-width="3" stroke-miterlimit="10" pointer-events="all"/><path d="M 91 210.58 Q 91 210.58 160.9 210.58" fill="none" stroke="#006666" stroke-width="3" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 167.65 210.58 L 158.65 215.08 L 160.9 210.58 L 158.65 206.08 Z" fill="#006666" stroke="#006666" stroke-width="3" stroke-miterlimit="10" pointer-events="all"/><path d="M 91 271 Q 91 271 160.9 271" fill="none" stroke="#006666" stroke-width="3" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 167.65 271 L 158.65 275.5 L 160.9 271 L 158.65 266.5 Z" fill="#006666" stroke="#006666" stroke-width="3" stroke-miterlimit="10" pointer-events="all"/><g fill="#FFFFFF" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="11px"><text x="130.58" y="248.92">Function Call</text><text x="130.58" y="261.92">ABI</text></g><path d="M 251 33.08 Q 251 33.08 320.9 33.08" fill="none" stroke="#006666" stroke-width="3" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 327.65 33.08 L 318.65 37.58 L 320.9 33.08 L 318.65 28.58 Z" fill="#006666" stroke="#006666" stroke-width="3" stroke-miterlimit="10" pointer-events="all"/><path d="M 251 271 Q 251 271 320.9 271" fill="none" stroke="#006666" stroke-width="3" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 327.65 271 L 318.65 275.5 L 320.9 271 L 318.65 266.5 Z" fill="#006666" stroke="#006666" stroke-width="3" stroke-miterlimit="10" pointer-events="all"/><g fill="#000000" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="11px"><text x="290.58" y="248.92">Function Call</text><text x="290.58" y="261.92">ABI</text></g><path d="M 251 181 Q 251 181 320.9 181" fill="none" stroke="#006666" stroke-width="3" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 327.65 181 L 318.65 185.5 L 320.9 181 L 318.65 176.5 Z" fill="#006666" stroke="#006666" stroke-width="3" stroke-miterlimit="10" pointer-events="all"/><g fill="#000000" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="11px"><text x="290.58" y="152.42">Cross</text><text x="290.58" y="165.42">Boundary</text><text x="290.58" y="178.42">ABI</text></g><path d="M 251 95.58 Q 251 95.58 320.9 95.58" fill="none" stroke="#006666" stroke-width="3" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 327.65 95.58 L 318.65 100.08 L 320.9 95.58 L 318.65 91.08 Z" fill="#006666" stroke="#006666" stroke-width="3" stroke-miterlimit="10" pointer-events="all"/><g fill="#FFFFFF" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="11px"><text x="290.58" y="80">Schedule</text></g><rect x="331" y="161.42" width="80" height="40" fill="#ffffff" stroke="#006666" stroke-width="2" stroke-dasharray="2 2" pointer-events="all"/><g fill="#000000" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="9px"><text x="370.5" y="178.92">ARoT</text><text x="370.5" y="189.92">Partition</text></g><rect x="331" y="251.42" width="80" height="40" fill="#ffffff" stroke="#006666" stroke-width="2" stroke-dasharray="2 2" pointer-events="all"/><g fill="#000000" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="9px"><text x="370.5" y="268.92">PRoT</text><text x="370.5" y="279.92">Partition</text></g><rect x="331" y="11" width="80" height="45" rx="11.25" ry="11.25" fill="#ffffff" stroke="#006666" stroke-width="2" stroke-dasharray="2 2" pointer-events="all"/><g fill="#000000" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="9px"><text x="370.5" y="31">ARoT</text><text x="370.5" y="42">Partition</text></g><rect x="331" y="76" width="80" height="40" rx="10" ry="10" fill="#ffffff" stroke="#006666" stroke-width="2" stroke-dasharray="2 2" pointer-events="all"/><g fill="#000000" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="9px"><text x="370.5" y="93.5">PRoT</text><text x="370.5" y="104.5">Partition</text></g></g></svg>
\ No newline at end of file
diff --git a/docs/design_docs/media/symmetric_initial_attest/attest_token_finish.png b/docs/design_docs/media/symmetric_initial_attest/attest_token_finish.png
new file mode 100644
index 0000000..548e79d
--- /dev/null
+++ b/docs/design_docs/media/symmetric_initial_attest/attest_token_finish.png
Binary files differ
diff --git a/docs/design_docs/media/symmetric_initial_attest/attest_token_start.png b/docs/design_docs/media/symmetric_initial_attest/attest_token_start.png
new file mode 100644
index 0000000..ac39cf2
--- /dev/null
+++ b/docs/design_docs/media/symmetric_initial_attest/attest_token_start.png
Binary files differ
diff --git a/docs/design_docs/media/symmetric_initial_attest/ia_service_flow.png b/docs/design_docs/media/symmetric_initial_attest/ia_service_flow.png
new file mode 100644
index 0000000..288bc53
--- /dev/null
+++ b/docs/design_docs/media/symmetric_initial_attest/ia_service_flow.png
Binary files differ
diff --git a/docs/design_docs/media/symmetric_initial_attest/iat_decode.png b/docs/design_docs/media/symmetric_initial_attest/iat_decode.png
new file mode 100644
index 0000000..e35183b
--- /dev/null
+++ b/docs/design_docs/media/symmetric_initial_attest/iat_decode.png
Binary files differ
diff --git a/docs/design_docs/media/symmetric_initial_attest/overall_diagram.png b/docs/design_docs/media/symmetric_initial_attest/overall_diagram.png
new file mode 100644
index 0000000..893c62e
--- /dev/null
+++ b/docs/design_docs/media/symmetric_initial_attest/overall_diagram.png
Binary files differ
diff --git a/docs/design_docs/media/tfm_crypto_design.png b/docs/design_docs/media/tfm_crypto_design.png
new file mode 100644
index 0000000..6e8d48b
--- /dev/null
+++ b/docs/design_docs/media/tfm_crypto_design.png
Binary files differ
diff --git a/docs/design_docs/media/tfmdev.svg b/docs/design_docs/media/tfmdev.svg
new file mode 100644
index 0000000..fc072f3
--- /dev/null
+++ b/docs/design_docs/media/tfmdev.svg
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="482px" height="181px" viewBox="-0.5 -0.5 482 181" content="<mxfile host="app.diagrams.net" modified="2021-06-10T08:17:08.793Z" agent="5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36" etag="bcO4cmytDhasP_7HJr2A" version="14.7.3" type="device"><diagram id="pE8yNmrzc9lT-nbtH71B" name="Page-1">7Vlbc6IwFP41PtoBIoiP9dbL9GLHdtv6lkIK2Q3EjfFCf/0GCMpVra66syPOdMjHyTHnfN9JjrQGOt7iisGxe09tRGqaYi9qoFvTNEPXxN8QCGIA6I0YcBi2Y0hdAUP8hSSoSHSKbTTJGHJKCcfjLGhR30cWz2CQMTrPmn1Skv3WMXRQARhakBTRV2xzN0ZNrbnCrxF23OSbVaMVP/FgYiwjmbjQpvMUBHo10GGU8vjOW3QQCXOX5CWe1694ulwYQz7fZsL925XbsTz9ZUR+X361yItFb+syjBkkUxnwADKOOaa+gCV3Ex4k6WB06tso9KjUQJvAD0QGdBLbg64lloKYeDBDwolI4l3OwMO2HbpqQ4Kd0hmX8sEH5Zx64sEn9flQLkANx5iQDiWURQsC7egj7frQwyQU2jN0qQcFOuGM/kKJvU99JE1TLvrRJXCZC7EStKhMsrqkTkgeUQ9xFgiTRO9NybaUeyMZz1PikZCb1o0hQSj16ixdrygVN5LVbzBsrGVYPTP8TYYbrRMy/ENVPx/v6nedJz14eDUfApN263qB4YfhoPd/ElvBVgmnlQRqpyRwBKzWY/3pHTaeWkH/ZqTMQa+uNgpkIVucQnIoQ7embBbRF6aSMu5Sh/qCJ0rHEvyJOA/kEQqnnArI5R6RjKMF5m/SMrx/D/ELXY66i5RZN0gGvojvLT1IzQqHq2nRKJmXqz8lupacJgcpKLAc2RriWkf1hE6ZJfP0cUuIPrp87hvXffPRmUMNT+synRwyB/E1eZeHX5jrtcJhiECOZ9mOYB8VrFt1qoyHiM2wiFQTezhQw/xdbqjqqOJiAajFfGuVtbahUnP7517lpyu58jOL5WeUlZ92sPIrtjnn8tuu/ErzqW1ZfuBU5bdu1any6xAcxn6giquosHwlHuoUBP9cGYJKAlbb3+DmdG3N0rKc4sz2WUp5tDaxddiI5fgs72GzCjGV8LOxt91LFA11syj0o4qi+Pv0LIoji8LYYqc4rijMLTql9lE6pb+QXfOE+3DpC4PiK4FzN9QubVV2a49AsT2q/j2wRzckpw4oDrfL5RbfyOpN11sXhpH1EocgJ6bfKOZ9mZt9xWEWfEXKXEa1u1jPrfthxdrcspc3DyJWw8gJTGldNHcUa1PZ7GtnsYrh6kV+bL76bwjo/QE=</diagram></mxfile>"><defs/><g><rect x="388" y="8" width="80" height="160" fill="#b3b3b3" stroke="none" pointer-events="all"/><g fill="#FFFFFF" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="12px"><text x="427.5" y="162.5">Partition 2</text></g><rect x="208" y="8" width="80" height="160" fill="#b3b3b3" stroke="none" pointer-events="all"/><g fill="#FFFFFF" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="12px"><text x="247.5" y="162.5">Partition 1</text></g><rect x="8" y="8" width="80" height="160" fill="#b3b3b3" stroke="none" pointer-events="all"/><g fill="#000000" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="12px"><text x="47.5" y="162.5">NSPE</text></g><path d="M 278 78 Q 278 78 307.9 78" fill="none" stroke="#006666" stroke-width="3" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 314.65 78 L 305.65 82.5 L 307.9 78 L 305.65 73.5 Z" fill="#006666" stroke="#006666" stroke-width="3" stroke-miterlimit="10" pointer-events="all"/><rect x="218" y="18" width="60" height="120" fill="#ffffff" stroke="#000000" stroke-width="2" pointer-events="all"/><g fill="#000000" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="10px"><text x="247.5" y="75.5">Service</text><text x="247.5" y="87.5">A</text></g><path d="M 78 78 Q 78 78 117.9 78" fill="none" stroke="#006666" stroke-width="3" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 124.65 78 L 115.65 82.5 L 117.9 78 L 115.65 73.5 Z" fill="#006666" stroke="#006666" stroke-width="3" stroke-miterlimit="10" pointer-events="all"/><rect x="18" y="18" width="60" height="120" fill="#ffffff" stroke="none" pointer-events="all"/><g fill="#000000" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="10px"><text x="47.5" y="81.5">Client</text></g><rect x="128" y="18" width="50" height="120" fill="#808080" stroke="none" pointer-events="all"/><g fill="#FFFFFF" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="12px"><text x="152.5" y="75.5">Client</text><text x="152.5" y="89.5">API</text></g><rect x="318" y="18" width="50" height="120" fill="#808080" stroke="none" pointer-events="all"/><g fill="#FFFFFF" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="12px"><text x="342.5" y="75.5">Client</text><text x="342.5" y="89.5">API</text></g><rect x="398" y="18" width="60" height="120" fill="#ffffff" stroke="#000000" stroke-width="2" pointer-events="all"/><g fill="#000000" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="10px"><text x="427.5" y="75.5">Service</text><text x="427.5" y="87.5">B</text></g><path d="M 178 78 Q 178 78 207.9 78" fill="none" stroke="#006666" stroke-width="3" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 214.65 78 L 205.65 82.5 L 207.9 78 L 205.65 73.5 Z" fill="#006666" stroke="#006666" stroke-width="3" stroke-miterlimit="10" pointer-events="all"/><path d="M 368 78 Q 368 78 387.9 78" fill="none" stroke="#006666" stroke-width="3" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 394.65 78 L 385.65 82.5 L 387.9 78 L 385.65 73.5 Z" fill="#006666" stroke="#006666" stroke-width="3" stroke-miterlimit="10" pointer-events="all"/></g></svg>
\ No newline at end of file
diff --git a/docs/design_docs/media/twocalltypes.svg b/docs/design_docs/media/twocalltypes.svg
new file mode 100644
index 0000000..b1432b6
--- /dev/null
+++ b/docs/design_docs/media/twocalltypes.svg
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="316px" height="139px" viewBox="-0.5 -0.5 316 139" content="<mxfile host="app.diagrams.net" modified="2021-06-21T13:51:31.836Z" agent="5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36" etag="zDoxWHAhn_gRFZadqpOB" version="14.8.0" type="device"><diagram id="oEx5C9R192mbNw7mWCni" name="Page-1">5Zhdd6IwEIZ/jZfuCVCpXiq17X50S9eetreRRMhpIG4IVvvrN5QgQvzArS26y4WHvIZhmGcmGWhZTji/4nAa3DCEacsEaN6yLlqmaXdM+ZsKi0ywDDsTfE5QJhmFMCKvWIlAqQlBOC5NFIxRQaZl0WNRhD1R0iDn7KU8bcJo+a5T6GNNGHmQ6uojQSLI1K55XujXmPhBfmfD7mX/hDCfrJ4kDiBiLyuSNWxZDmdMZGfh3ME0jV0el+y6yw3/Lh3jOBJ1LnDv/Nfby2dw/QifkxmekdH0qa2szCBN1AMrZ8UijwCOUD8NpBx5FMYx8VrWAME4wKlhQw50T5RZjErBVX5dYRZiwRdywksR0o4KU7ASzVzjmEJBZmUkUJH1l+aWd3AZkZ6YQCVhV5lRKWiegbKFmCXcw+qi1QhW7Fj2DkMCch8LzZA8WXnqQnoDtAes871gRSyS4mDCInEJQ0JTp+9hwEIoVTlP1ZotR7F0XJTGnD0v871QHEYZf7uRBYAtjxOAb4AD0Td2pdEH0+82Q18uxGvxA+A4J4Df3FWztYv/rFn8+b55JNXvOCeBf2fR1sW/M48Oh394m/zkwbenVz72JgSMo2nfbPc0+iP3Rgp996v8HTC00LJB4LnQ4OV5QSitSJASP5JDiifpZTPMBZF9UF/JIUEotTzgLInQ294PNiZYqqqMMox8rDzLx3utJqk3eL41oTaByjvJlYTrrkk4E2zOrRLMLeTC30+PUw+5P3zbe/g+uJslyUXb0sjJpi+O2+M0jpCfNrfSMqBBWoNyIzfjvMKto3PrfSa3M41b/xe7l4orl0siCItOmlypfXsfuWqH1XTFdfbaKbe+1FS2sVphaeSlxqpGs3Zf0+l96a0e280ebptbi67BJmfTnrSr9z3eFKkW5l/nSLWL+uysaOjFt9arz/HiN/er7NoLhnVMC8b/1Be/a5fW+uJew7u0oX97dP+lButw6LQG6+PQyWHxRTqr0eKzvjX8Aw==</diagram></mxfile>"><defs/><g><path d="M 15 38 L 288.63 38" fill="none" stroke="#000000" stroke-miterlimit="10" stroke-dasharray="3 3" pointer-events="stroke"/><path d="M 293.88 38 L 286.88 41.5 L 288.63 38 L 286.88 34.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><path d="M 35 38 L 115 38" fill="none" stroke="#006666" stroke-width="6" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 195 38 L 275 38" fill="none" stroke="#0000cc" stroke-width="10" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 115 38 L 195 38" fill="none" stroke="#00cccc" stroke-width="6" stroke-miterlimit="10" pointer-events="stroke"/><rect x="195" y="8" width="80" height="20" fill="none" stroke="none" pointer-events="all"/><g fill="#0000CC" font-family="Tahoma" font-weight="bold" font-size="11px"><text x="196.5" y="22">SPM API Body</text></g><rect x="105" y="48" width="90" height="20" fill="none" stroke="none" pointer-events="all"/><g fill="#00CCCC" font-family="Tahoma" font-weight="bold" font-size="11px"><text x="106.5" y="62">Cross-boundary</text></g><rect x="35" y="8" width="80" height="20" fill="none" stroke="none" pointer-events="all"/><g fill="#006666" font-family="Tahoma" font-weight="bold" font-size="11px"><text x="36.5" y="22">ARoT Partition</text></g><path d="M 15 118 L 288.63 118" fill="none" stroke="#000000" stroke-miterlimit="10" stroke-dasharray="3 3" pointer-events="stroke"/><path d="M 293.88 118 L 286.88 121.5 L 288.63 118 L 286.88 114.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><path d="M 35 118 L 115 118" fill="none" stroke="#0000cc" stroke-width="6" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 195 118 L 275 118" fill="none" stroke="#0000cc" stroke-width="10" stroke-miterlimit="10" pointer-events="stroke"/><rect x="195" y="88" width="80" height="20" fill="none" stroke="none" pointer-events="all"/><g fill="#0000CC" font-family="Tahoma" font-weight="bold" font-size="11px"><text x="196.5" y="102">SPM API Body</text></g><rect x="35" y="88" width="80" height="20" fill="none" stroke="none" pointer-events="all"/><g fill="#0000CC" font-family="Tahoma" font-weight="bold" font-size="11px"><text x="36.5" y="102">PRoT Partition</text></g></g></svg>
\ No newline at end of file
diff --git a/docs/design_docs/media/tzcontext.svg b/docs/design_docs/media/tzcontext.svg
new file mode 100644
index 0000000..e4132a3
--- /dev/null
+++ b/docs/design_docs/media/tzcontext.svg
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="232px" height="242px" viewBox="-0.5 -0.5 232 242" content="<mxfile host="app.diagrams.net" modified="2021-09-06T06:23:14.559Z" agent="5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36" etag="1QsfdRuMsY_wf8lx7K3Z" version="14.9.8" type="device"><diagram id="pE8yNmrzc9lT-nbtH71B" name="Page-1">vVbbctowEP0aP9LBV+hjMCQ8gEPrTJP2paPYwlYjexkhLu7XV4rXN0wKnbaBGUY62l1pz1mtMGw/O94JskmXEFNuWMP4aNhTw7JGY0v9aqAoAcdySyARLC4hswFC9pMiOER0x2K67RhKAC7ZpgtGkOc0kh2MCAGHrtkaeHfXDUloDwgjwvvoI4tlWqJja9Tgc8qStNrZ9D6WKxmpjDGTbUpiOLQge2bYvgCQ5Sg7+pRr7ipeSr/bN1brgwmay2scvpjm+n4xWPif3CJ4HAfFGKYDVGdP+A4TfvhmWJ5h2UoAe+JDLulRtpCQij2LKKYki4onAbs8pnorbbVWfqilqRKdbKWAl5pACy1uSca4rosHkkJGNMo494GDeA1qzzz9reLhZmcSR2hPhTptC0Ii7ihkVIpCmeCqU5UXVqVXzQ+NxmYlXNrS10WMYFkldeiGeTVA8v9ACLsnRBCq+U2ik3xfsjWNTN2AG86SXK09g5SQvYMKjnOlCqbzv2TwejKEq+UF/jl5pnwFWyYZaL4ixQgVLSIXJwYZi2MdakKQ4Z5Hj/rzmjZi/P7q9LX/B+q53mX1vDPi1Q3xb8TLv3/mwXz2Yt3P52GwDhZLPx6YPaForJo5TkHIFBLICZ816KQrZWOzANggsz+olAVeMLKToKBUZhxd6JHJJz3+4OLsK/rp8fTYMpsWV9/YEmnpORz66lMrpxN78x2oeICdiOilntPXV1BOJNt3458TC11XwHSPquvCOemtjtsNUZ4LvdoP1kkgZ3TapO1uIElEQmUv0Gvt1PmcKyc1bd7d0rz582LPfgE=</diagram></mxfile>"><defs/><g><rect x="11" y="181" width="120" height="50" fill="#e6e6e6" stroke="#000000" stroke-width="2" pointer-events="all"/><g fill="#000000" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="12px"><text x="70.5" y="196.5">TZ</text><text x="70.5" y="210.5">Context</text><text x="70.5" y="224.5">Service</text></g><rect x="11" y="11" width="120" height="140" fill="#e6e6e6" stroke="#000000" stroke-width="2" pointer-events="all"/><g fill="#000000" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="12px"><text x="70.5" y="145.5">NS Agent</text></g><rect x="161" y="11" width="60" height="220" fill="#e6e6e6" stroke="#000000" stroke-width="2" pointer-events="all"/><g fill="#000000" font-family="Tahoma" font-weight="bold" text-anchor="middle" font-size="12px"><text x="190.5" y="225.5">SPM</text></g><path d="M 71 151 L 71 175.76" fill="none" stroke="#00cccc" stroke-width="2" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 71 181.76 L 67 173.76 L 71 175.76 L 75 173.76 Z" fill="#00cccc" stroke="#00cccc" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/></g></svg>
\ No newline at end of file
diff --git a/docs/design_docs/ps_key_management.rst b/docs/design_docs/ps_key_management.rst
new file mode 100644
index 0000000..6ce540f
--- /dev/null
+++ b/docs/design_docs/ps_key_management.rst
@@ -0,0 +1,128 @@
+========================================
+Protected Storage service key management
+========================================
+
+:Author: Jamie Fox
+:Organization: Arm Limited
+:Contact: Jamie Fox <jamie.fox@arm.com>
+
+Background
+==========
+The PSA Protected Storage API requires confidentiality for external storage to
+be provided by:
+
+ **cryptographic ciphers using device-bound keys**, a tamper resistant
+ enclosure, or an inaccessible deployment location, depending on the threat
+ model of the deployed system.
+
+A TBSA-M-compliant device must embed a Hardware Unique Key (HUK), which provides
+the root of trust (RoT) for confidentiality in the system. It must have at least
+128 bits of entropy (and a 128 bit data size), and be accessible only to Trusted
+code or Trusted hardware that acts on behalf of Trusted code. [TBSA-M]_
+
+Design description
+==================
+Each time the system boots, PS will request that the Crypto service uses a key
+derivation function (KDF) to derive a storage key from the HUK, by referring to
+the builtin key handle for the HUK. The storage key could be kept in on-chip
+volatile memory private to the Crypto partition, or it could remain inside a
+secure element. Either way it will not be returned to PS.
+
+For each call to the PSA Protected Storage APIs, PS will make requests to the
+Crypto service to perform AEAD encryption and/or decryption operations using the
+storage key (providing a fresh nonce for each encryption).
+
+At no point will PS access the key material itself, only referring to the HUK
+and storage key by their handles in the Crypto service.
+
+Key derivation
+==============
+PS will make key derivation requests to the Crypto service with calls to the
+PSA Crypto APIs. In order to derive the storage key, the following calls are
+required:
+
+.. code-block:: c
+
+ status = psa_key_derivation_setup(&op, PSA_ALG_HKDF(PSA_ALG_SHA_256));
+
+ /* Set up a key derivation operation with HUK */
+ status = psa_key_derivation_input_key(&op, PSA_KEY_DERIVATION_INPUT_SECRET,
+ TFM_BUILTIN_KEY_ID_HUK);
+
+ /* Supply the PS key label as an input to the key derivation */
+ status = psa_key_derivation_input_bytes(&op, PSA_KEY_DERIVATION_INPUT_INFO,
+ key_label,
+ key_label_len);
+
+ /* Create the storage key from the key derivation operation */
+ status = psa_key_derivation_output_key(&attributes, &op, &ps_key);
+
+.. note::
+ ``TFM_BUILTIN_KEY_ID_HUK`` is a static key ID that is used to identify the
+ HUK. It has an arbitrary value defined in ``tfm_crypto_defs.h``
+
+ ``ps_key`` is a PSA Crypto key handle to a volatile key, set by the
+ derivation operation. After the call to ``psa_key_derivation_output_key``,
+ it can be used to refer the storage key.
+
+ ``key_label`` can be any string that is independent of the input key
+ material and different to the label used in any other derivation from the
+ same input key. It prevents two different contexts from deriving the same
+ output key from the same input key.
+
+The key derivation function used by the crypto service to derive the storage key
+will be HKDF, with SHA-256 as the underlying hash function. HKDF is suitable
+because:
+
+- It is simple and efficient, requiring only two HMAC operations when the length
+ of the output key material is less than or equal to the hash length (as is the
+ case here).
+- The trade-off is that HKDF is only suitable when the input key material has at
+ least as much entropy as required for the output key material. But this is the
+ case here, as the HUK has 128 bits of entropy, the same as required by PS.
+- HKDF is standardised in RFC 5869 [RFC5869]_ and its security has been formally
+ analysed. [HKDF]_
+- It is supported by the TF-M Crypto service.
+
+The choice of underlying hash function is fairly straightforward: it needs to be
+a modern standardised algorithm, considered to be secure and supported by TF-M
+Crypto. This narrows it down to just the SHA-2 family. Of the hash functions in
+the family, SHA-256 is the simplest and provides more than enough output length.
+
+Keeping the storage key private to PS
+-------------------------------------
+
+The Crypto service derives a platform key from the HUK, using the partition ID
+as the input to that derivation, and that platform key is used for the key
+derivation by PS. This happens transparently, and to PS is indistinguishable
+from deriving from the HUK except that other partitions cannot derive the
+storage key even if they know the derivation parameters.
+
+Key use
+=======
+To encrypt and decrypt data, PS will call the PSA Crypto AEAD APIs in the same
+way as the current implementation, but ``ps_key`` will refer to the storage key,
+rather than the imported HUK. For each encryption operation, the following call
+is made (and analogously for decryption):
+
+.. code-block:: c
+
+ psa_aead_encrypt(ps_key, PS_CRYPTO_ALG,
+ crypto->ref.iv, PS_IV_LEN_BYTES,
+ add, add_len,
+ in, in_len,
+ out, out_size, out_len);
+
+References
+==========
+.. [TBSA-M] Arm Platform Security Architecture Trusted Base System Architecture
+ for Armv6-M, Armv7-M and Armv8-M, version 1.0
+.. [HKDF] Hugo Krawczyk. 2010. Cryptographic extraction and key derivation: the
+ HKDF scheme. In Proceedings of the 30th annual conference on Advances in
+ cryptology (CRYPTO'10)
+.. [RFC5869] IETF RFC 5869: HMAC-based Extract-and-Expand Key Derivation
+ Function (HKDF)
+
+--------------
+
+*Copyright (c) 2019-2022, Arm Limited. All rights reserved.*
diff --git a/docs/design_docs/secure_boot_hw_key_integration.rst b/docs/design_docs/secure_boot_hw_key_integration.rst
new file mode 100644
index 0000000..7d8afdd
--- /dev/null
+++ b/docs/design_docs/secure_boot_hw_key_integration.rst
@@ -0,0 +1,165 @@
+HW crypto key integration in TF-M secure boot
+=============================================
+
+:Author: Tamas Ban
+:Organization: Arm Limited
+:Contact: Tamas Ban <tamas.ban@arm.com>
+
+Abstract
+--------
+
+`PSA Trusted Boot and Firmware Update <https://pages.arm.com/psa-resources-tbfu.html>`__
+specification requires the support of at least one immutable root of trust
+public key (ROTPK) for firmware verification. This can be stored using a locked
+on-chip flash memory, a secure-element or on-chip OTP memory. It also beneficial
+to be able to provision these keys during the factory life-cycle of the device
+independently from any software components. The current key handling solution
+in TF-M secure boot does not supports this key provisioning process. MCUBoot
+requires compile time built-in public key(s) for image verification. This
+limitation does not fit well with a scenario with multiple vendors where
+multiple MCU software components might be deployed by different vendors in
+different points in the life-cycle of the device and they do not want to share
+the keys in-advance for embedding in the bootloader code. The goal of this
+document to propose a solution to decouple MCUBoot from public key(s) and
+enable the independent deployment of ROTPK.
+
+Existing key handling solution
+------------------------------
+
+MCUBoot code contains a compile-time built-in key array which can store any
+number of key(s) for firmware verification: ``bl2/ext/mcuboot/keys.c``. These
+public key(s) must be available when MCUBoot image is built. There is a script
+``bl2/ext/mcuboot/scipt/imgtool.py`` which can generate a new key pair, and
+extract the public key part in the expected ASN.1 format and encode it as C
+structure. The script is also capable of signing the image with the private key.
+In order to identify and validate the corresponding public key during image
+verification the hash of the public key is appended to the image manifest area
+(TLV encoded metadata). During image verification the bootloader retrieves the
+hash of the public key from the manifest area and compare against the on-the-fly
+calculated hash value of the built-in public keys. An exact match identifies and
+validates the public key which must be used for image verification.
+
+Current memory layout::
+
+ |----------------------|
+ | |
+ | MCUBoot code |
+ | |
+ | Full public key |
+ | |
+ |----------------------|
+ | |
+ | Image |
+ | |
+ |----------------------|
+ | Image Manifest(TLV) |
+ | |
+ | Hash of public key |
+ |----------------------|
+ | |
+ | Rest of memory |
+ | |
+
+Requirements
+------------
+
+- Multiple independent vendor scenario must be supported, when more than one
+ ROTPK is provisioned to the device.
+- The corresponding public key for image verification must be identifiable and
+ verifiable.
+- Key identity must be immutable and anchored to the device itself.
+- Key(s) can be provisioned independently from bootloader.
+
+Design proposal
+---------------
+HW key(s) might stored in OTP memory which is an expensive resource, so
+storing a large key (such as RSA) is inefficient. Therefore, it is assumed that
+only the hash of the ROTPK will be stored in the HW. If only the hash of the
+public key is stored in the HW then the whole public key must be transfered to
+the device, because it must be available during image verification. This
+transfer can be done in the same way as how the hash of the key is transfered
+to the device with the current solution. A new TLV type (TLV_KEY) can be
+introduced to carry the whole public key. The corresponding public key will be
+appended to the image itself in the manifest area. It has the drawback that the
+image will be bigger, but it is assumed that the additional cost of the bigger
+image (extra flash area + power for download) is less than the cost of the OTP
+area.
+
+The verification flow:
+
+ - Look up the TLV_KEY field to get the public key.
+ - Calculates its hash(SHA256) value.
+ - Get the hash of ROTPK from the platform layer (stored in HW)
+ - Compare the two hash values, if they match then the key can be used to
+ validate the image. In case of failure consider the images as unauthenticated.
+
+Proposed memory layout::
+
+ |----------------------|
+ | |
+ | MCUBoot code |
+ | |
+ | NO PUBLIC KEY |
+ | |
+ |----------------------|
+ | |
+ | Image |
+ | |
+ |----------------------|
+ | Image Manifest(TLV) |
+ | |
+ | Full public key |
+ |----------------------|
+ | |
+ | |
+ | Rest of memory |
+ | |
+ | |
+ |----------------------|
+ | Immutable memory |
+ | |
+ | Hash of public key |
+ |----------------------|
+ | |
+
+Platform support
+----------------
+
+A new platform API used by the bootloader must be introduced to retrieve the
+image corresponding hash of ROTPK:
+
+``enum tfm_plat_err_t tfm_plat_get_rotpk_hash(uint8_t image_id,
+uint8_t *rotpk_hash, uint32_t *rotpk_hash_size);``
+
+The mapping between image identity and public key can be hard-code in the
+platform layer. This simplifies the validation of the public key, because no
+look-up would be needed. It is assumed that the memory area of the ROTPK hash is
+not directly accessible, therefore a buffer is allocated by the caller to store
+the hash there.
+
+Compile time configurability
+----------------------------
+
+The solution must be compile time configurable in order to be able to switch
+between built-in key(s) and HW key(s) support, and also due to backwards
+compatibility.
+
+Tooling
+-------
+
+``bl2/ext/mcuboot/scipt/imgtool.py`` will be modified to include the whole
+public key to the TLV area (instead of the hash).
+
+Table to compare the current and proposed solution::
+
+ |---------|-----------------------|-------------------|--------------------|
+ | |Key format in manifest |Key in MCUBoot code| Key in HW |
+ |---------|-----------------------|-------------------|--------------------|
+ |Proposed | Full public key | No key embedded | Hash of public key |
+ |---------|-----------------------|-------------------|--------------------|
+ |Current | Hash of public key | Full public key | No key in HW |
+ |---------|-----------------------|-------------------|--------------------|
+
+--------------
+
+*Copyright (c) 2019, Arm Limited. All rights reserved.*
diff --git a/docs/design_docs/secure_boot_rollback_protection.rst b/docs/design_docs/secure_boot_rollback_protection.rst
new file mode 100644
index 0000000..8fc66f4
--- /dev/null
+++ b/docs/design_docs/secure_boot_rollback_protection.rst
@@ -0,0 +1,202 @@
+#######################################
+Rollback protection in TF-M secure boot
+#######################################
+
+:Author: Tamas Ban
+:Organization: Arm Limited
+:Contact: Tamas Ban <tamas.ban@arm.com>
+
+Anti-rollback protection
+========================
+The goal of anti-rollback protection is to prevent downgrading of the device to
+an older version of its software, which has been deprecated due to security
+concerns.
+
+Elements of software upgrade
+============================
+During a software upgrade the following entities are involved:
+
+ - Boot loader
+ - Manifest data: Metadata of the software image: size, version, hash,
+ signature, etc.
+ - Software image: binary data, elf, etc.
+
+Validation of new image
+=======================
+Boot loader is responsible to authenticate the new image according to the
+required policies and decide whether the new image is fulfilling all the
+requirements. Boot loader verifies the image integrity (hash calculation) and
+the origination (signature validation), and might verify other requirements as
+well. If the new image is successfully authenticated then the boot loader is in
+charge to do the necessary steps (load to execute address, etc.) to enable the
+new image to be executed. During the validation process the image and the
+manifest data is checked.
+
+Manifest format in MCUBoot
+==========================
+MCUBoot has a custom manifest format, which is composed of two parts:
+
+ - Image header: Prepended to the beginning of the image.
+ It is integrity protected:
+ - TLV section: Appended to the end of the image. It is not integrity protected:
+
+ - Hash of public key, hash of image, signature of image
+
+.. code-block:: c
+
+ struct image_header {
+ uint32_t ih_magic;
+ uint32_t ih_load_addr;
+ uint16_t ih_hdr_size;
+ uint16_t _pad1;
+ uint32_t ih_img_size;
+ uint32_t ih_flags;
+ struct image_version ih_ver;
+ uint32_t _pad2;
+ };
+
+Security counter
+================
+The aim of a security counter is to have an independent (from the image version)
+counter in the image manifest to ensure anti-rollback protection. During
+software release the value of this counter must be increased if a security flaw
+was fixed in the current version. Later when this image is installed on the
+device then it is not allowed to go back to earlier versions. It is beneficial
+to handle this counter independently from image main version number:
+
+ - It does not need to increase with each software release
+ - It makes it possible to do software downgrade to some extent: if the security
+ counter has the same value in the older image then it is accepted.
+ - If the boot loader verifies multiple images then these can be handled
+ independently.
+
+However, as an alternative solution the image version number also could serve
+as the security counter of the image. Even the version number itself could be
+checked during the anti-rollback verification or the value of the security
+counter could be derived from the image main version. It is the responsibility
+of the software issuer to define which policy to apply.
+
+Implementation of security counter
+==================================
+The value of the security counter is a security critical data. Any change in
+its value has a security implication. Therefore it must be in the integrity
+protected part of the image manifest. Because the image header is almost fully
+utilized (few unused fields) and the change of image header structure could
+lead to compatibility issues between boot loader and runtime software, it is
+proposed to extend the integrity protection to some part of the TLV section.
+One of the unused fields in the image header can be used to store the size of
+the integrity protected area of the TLV section. This is necessary to know how
+to calculate properly the image hash and signature. With this extension of the
+integrity protected area other attributes that require integrity protection
+can easily be added to the image manifest.
+
+Trusted non-volatile (NV) counters
+==================================
+The Trusted Base System Architecture (TBSA-M) defines non-volatile (NV) counters
+or version counters as a counter with the following properties:
+
+ - It must only be possible to increment a version counter through a Trusted
+ access.
+ - It must only be possible to increment a version counter. It must not be
+ possible to decrement it.
+ - When a version counter reaches its maximum value, it must not roll over,
+ and no further changes must be possible.
+ - A version counter must be non-volatile, and the stored value must survive
+ a power down period up to the lifetime of the device.
+
+Trusted non-volatile counters can be used to store the value of security
+counters per updatable software image. Ideally all independently updatable
+software images should have a separate security counter. In current TF-M
+implementation the BL2 is not updatable and the secure and non-secure images
+are updated together as a single binary. Therefore, one counter is enough to
+implement rollback protection. In future the secure and non-secure binaries
+will be handled independently; at that time the introduction of a second
+counter will be necessary.
+
+Currently the NV counters can be manipulated through the interface described
+in ``tfm_plat_nv_counters.h``.
+
+NV counters and anti-rollback protection
+========================================
+Trusted non-volatile counters might not be supported by a hardware platform.
+In this case anti-rollback protection might still be feasible.
+
+The device threat model needs to consider the following aspects:
+
+ - What is the trust level of the boot loader towards the active software
+
+ - If the boot loader cannot protect the anti-rollback mechanism from the
+ secure image then the following threat is unmitigated: The content of the
+ memory area which holds the active image could be replaced with a valid but
+ an older version of the software with software only attack, i.e.: remote
+ code execution.
+ - If the boot loader does not trust the loaded image at all then security
+ counter must have a copy in NV counter area.
+
+ - Another aspect to consider is where the active image is stored
+
+ - Trusted memory: i.e. on-chip flash (eFlash). The threat that a malicious
+ actor can modify the content of trusted memory with HW attack is out of
+ scope for the current implementation. It is assumed that if an active image
+ and related manifest data is stored in trusted memory then the included
+ security counter cannot be compromised.
+ - Untrusted memory: i.e. external (off-chip) storage, where malicious actor
+ can physically access it so it is possible to modify its content, therefore
+ the value of included security counter is unreliable.
+
+If the active image is stored in untrusted storage and it is feasible to modify
+its content (i.e. replace the whole image to an older version including
+corresponding manifest) then the value of security counter must be copied to
+the NV counter area. During software validation the boot loader must compare
+the new image's security counters against the security counter stored in
+non-volatile counters.
+
+If the active image is stored in trusted memory and boot loader trusts in the
+active software then it is not mandatory to store the security counter to
+non-volatile counter area. During software validation the boot loader is
+allowed to compare the new image's security counters against active image's
+security counter.
+
+The evaluation of trusted and untrusted memory must be done per target platform
+during threat modelling.
+
+For the most robust implementation the following principles should be applied:
+
+ - Always use NV counters for storing security counter value if supported by
+ the hardware.
+ - Each software stage must not be able to decrease their corresponding NV
+ counter.
+
+Boot flow with anti-rollback protection
+=======================================
+During software upgrade as part of the image validation process the new and
+active image security counters must be compared. The new image can be accepted
+if its security counter has a greater or equal value than the active image
+security counter. From where to extract the active image security counter it
+can be platform dependent. It might read out directly from active image
+manifest data (only if it is in trusted memory) or the corresponding
+non-volatile counter is read.
+
+If non-volatile counters are used to save security counters then their value
+must be updated:
+
+ - If the boot loader does not support to revert previous images (just
+ overwrites the previously active image with the new one) in case of faulty
+ update then the non-volatile counter can be updated to be equal with the
+ new image security counter after successful authentication of the new image.
+ - If revert is supported then non-volatile counter can be updated just after
+ a test run of the new software when its health check is done. Just in case
+ of successful health check can the counter updated to avoid the prevention
+ of the revert. This might require a secondary restart of the device.
+
+Tool support
+============
+There is a Python script, ``imgtool.py`` which is used to prepare the new image
+for upgrade (add header, sign the image, append TLV section). This script must
+be modified to get an additional command line argument which serves as security
+counter. The security counter must be included in the integrity protected part
+of the TLV section.
+
+--------------
+
+*Copyright (c) 2019-2020, Arm Limited. All rights reserved.*
diff --git a/docs/design_docs/secure_partition_manager.rst b/docs/design_docs/secure_partition_manager.rst
new file mode 100644
index 0000000..eddec2e
--- /dev/null
+++ b/docs/design_docs/secure_partition_manager.rst
@@ -0,0 +1,811 @@
+########################
+Secure Partition Manager
+########################
+This document describes the Secure Partition Manager(`SPM`) implementation
+design in Trusted Firmware-M (`TF-M`).
+
+.. note::
+ - The FF-M in this document refers to the accumulated result of two
+ specifications:
+ `FF-M v1.1 Update <https://developer.arm.com/documentation/aes0039/latest>`_
+ on
+ `FF-M v1.0 <https://developer.arm.com/-/media/Files/pdf/PlatformSecurityArchitecture/Architect/DEN0063-PSA_Firmware_Framework-1.0.0-2.pdf?revision=2d1429fa-4b5b-461a-a60e-4ef3d8f7f4b4&la=en&hash=BE8C59DBC98212591E1F935C2312D497011CD8C7>`_.
+ - The words marked as `interpreted` are defined terms. Find the terms in
+ referenced documents if it is not described in this document.
+
+************
+Introduction
+************
+The service access process of FF-M:
+
+.. figure:: media/tfmdev.*
+ :align: center
+ :name: fig-tfmdev
+ :width: 80%
+
+ FF-M service access process
+
+Secure services (aka `Service`) is the component providing secure
+functionalities in `SPE`, and `Client` is the user of the `Service`. A service
+act as a client when it is accessing its depending services.
+
+Services are grouped into `Secure Partition` (aka `partition`). A partition:
+
+- Contains services with the same purpose.
+- Provides implementation required isolation boundaries.
+- Is a software development unit.
+
+Each service exposes its `Service ID` (`SID`) and `Handle` for client access
+usage. Clients access services by `SID` or `Handle` through FF-M `Client API`.
+Partitions use FF-M `Secure Partition API` when it needs to operate on client
+data or reply to a client.
+
+`SPM` is the centre of an FF-M compliant implementation, which set up and
+maintains a firmware framework that:
+
+- Implements `Client API` and `Secure Partition API`.
+- Manages partition runtime to follow FF-M.
+- Involves necessary implementation-defined items to support the
+ implementation.
+
+SPM interfaces are consist of these two categories:
+
+- FF-M defined API.
+- Extended API to support the implementation.
+
+Both API categories are compliant with FF-M concepts and guidelines. The core
+concept of TF-M SPM surrounds the FF-M defined service management and access
+process. Besides this, another important implementation part is partition
+runtime management.
+
+Partition runtime model
+=======================
+One partition must work under as `ONE` of the runtime models:
+`Inter-process communication` (`IPC`) model or `Secure Function` (`SFN`)
+model.
+
+A partition that runs under the `IPC` model looks like a classic `process`.
+There is `ONE` thread inside the partition keeps waiting for signals. SPM
+converts the service accessing info from the `Client API` call into messages
+and assert a signal to the partition. The partition calls corresponded service
+function indicated by the signal and its bound message, and reply service
+returned result to the client. The advantages of this model:
+
+- It provides better isolation by limiting the interfaces on data interactive.
+ Data are preferred to be processed in a local buffer.
+- It provides a mechanism for handling multiple service access. There is no
+ memory mapping mechanism in the MCU system, hence it is hard to provide
+ multiple function call contexts when serving multiple-threaded clients if
+ the service access is implemented in a function-call based mechanism. This
+ model converts multiple service accesses into messages, let the partition
+ handles the service access in messages one by one.
+
+The `Secure Function` (`SFN`) model partition is close to a `library`. Each
+service is provided as a function entry inside the partition. SPM launches
+the target service function after the service is found. The whole procedure
+(from client to service function) is a function call. This model:
+
+- Saves the workloads spent on `IPC` scheduling.
+
+Meanwhile, it relaxes the data interactive mechanism, for example, allow
+direct memory access (MMIOVEC). And it is hard to enable multiple-threaded
+clients service access because of multiple call context-maintenance
+difficulties.
+
+An implementation contains only `SFN` partitions fits better in the
+resource-constrained devices, it is called an `SFN model implementation`. And
+it is an `IPC model implementation` when `IPC` partitions exist in the system.
+
+.. note::
+ `IPC model implementation` can handle access to the services in the `SFN`
+ partition.
+
+Components and isolation levels
+===============================
+There are `THREE` isolation levels defined in `FF-M`. These levels can
+fulfil different security requirements by defining different isolation
+boundaries.
+
+.. figure:: media/modelisolation.*
+ :align: center
+ :name: fig-modelisolation
+ :width: 80%
+
+ Components and isolation boundaries
+
+.. note::
+ Concept `ARoT`, `PRoT`, `domain`, and boundaries are in the `FF-M`
+ specification.
+
+Not like an `SPE` client that can call `Client API` to access the secure
+services in one step, an `NSPE` client needs to cross the secure boundaries
+first before calling `Client API`. The component `NS Agent` in
+:numref:`fig-modelisolation` represents `NSPE` clients after they crossed
+the secure boundaries. This could help `SPM` handles the request in a
+unified way instead of care about the special boundaries.
+
+.. note::
+ `NS Agent` is a necessary implementation-defined component out of FF-M
+ specification. `NS Agent` has a dedicated stack because secure and
+ non-secure can not share the stack. It also has dedicated execution bodies.
+ For example, RPC-based `NS Agent` has a while loop that keeps waiting for
+ messages; and Trustzone-based `NS Agent` has veneer code to take over `NSPE`
+ secure call. This makes `NS Agent` is a component more like a `process`.
+ Hence in the simplest implementation (`SFN model implementation` mentioned
+ above), `NS Agent` is the only process in the system, the scheduling
+ logic can be extremely simplified since no other process execution needs to
+ be scheduled. But the scheduling interface is still necessary to SPM, this
+ could help SPM treat both `SFN` and `IPC` model implementation in a unified
+ way.
+
+ Check `NS Agent`_ for details.
+
+Implementation principle
+========================
+The principles for TF-M SPM implementation:
+
+.. important::
+ - SPM can treat these components as the client: NS Agent, SFN Partition,
+ and IPC partition.
+ - These components can provide services: SFN Partition, IPC partition, and
+ built-in services. A built-in service is built up with SPM together.
+ - All partition services must be accessed by `Client API`.
+ - Partitions interact with client data by `Secure Partition API`.
+ - Built-in services are strongly recommended to be accessed by `Client API`.
+ Customized interfaces are restricted.
+ - Built-in services can call SPM internal interfaces directly.
+
+******************
+Runtime management
+******************
+The runtime execution runs among the components, there are **4** runtime
+states:
+
+- `Initializing` state, to set up the SPM runtime environment after system
+ powers up
+- `IDLE` state, when SPM runtime environment is set up and partitions are
+ ready for service access.
+- `Serving` state, when partition is under initializing or service access
+ handling.
+- `Background` state, such as the arrival of secure interrupt or unexpected
+ faults. `Background` state returns to the state it preempts. `Background`
+ state can be nested.
+
+The state transition diagram:
+
+.. figure:: media/spestate.*
+ :align: center
+ :name: fig-spestate
+ :width: 70%
+
+ SPE runtime execution states
+
+Initializing
+============
+The goal of TF-M initializing is to perform necessary initialization and
+move to the `Serving`_ state. This state starts with platform-specific power
+on sequence, then `SPM` takes over the execution to perform these operations:
+
+#. A preparation initialization process before SPM runtime initialization.
+#. SPM runtime initialization.
+#. A post initialization happens after the SPM runtime initialization and
+ before the first partition gets launched.
+
+.. note::
+ These procedures and their sub-routines are recommended to be applied with
+ execution measurement mechansim to mitigate the `Hardware Fault Injection`
+ attack.
+
+Preparation initialization
+--------------------------
+The purpose of this preparation initialization is to provide a chance for
+performing those security required but generic platform power-on skipped
+operations, such as:
+
+- Restrict `SPM` execution, for example, set up memory overflow settings for
+ SPM runtime memory, or set code out of SPM as un-executable, even though
+ SPM is a privileged component in general.
+
+.. note::
+ The ``logging``-related peripheral can be set up **AT THIS STEP**, if
+ logging is enabled and it needs peripheral support. There is no standalone
+ initializing HAL API proposed for logging, so here is an ideal place for
+ initializing them.
+
+This procedure is abstracted into one `HAL`, and a few example procedures
+are implemented as its sub-routines for reference:
+
+- Architecture extensions initialization, Check chapter
+ `Architecture security settings`_ for detailed information.
+- Isolation and lifecycle initialization.
+
+The load isolation boundaries need to be set up here, such as SPE/NSPE
+boundary, and ARoT/PRoT boundary if isolation level 2 is applied.
+
+The lifecycle is initiated by a secure bootloader usually. And in this stage
+of SPM initializing, SPM double-checks the lifecycle set up status (following
+a specific lifecycle management guidelines). Note that the hardware debugger
+setting can be part of lifecycle settings.
+
+.. important::
+ Double-check debugger setting when performing a product release.
+
+SPM runtime initialization
+--------------------------
+This procedure initializes necessary runtime operations such as memory
+allocator, loading partitions and partition-specific initialization
+(binding partitions with platform resources).
+
+The general processes:
+
+#. Initialize runtime functionalities, such as memory allocator.
+#. Load partitions by repeating below steps:
+
+ * Find a partition load information.
+ * Allocate runtime objects for this partition.
+ * Link the runtime objects with load information.
+ * Init partition contexts (Thread and call context).
+ * Init partition isolation boundaries (MMIO e.g.).
+ * Init partition interrupts.
+
+After no more partitions to be loaded, the SPM runtime is set up but
+partitions' initialization routines have not run yet - the partition runtime
+context is initialized for the routine call.
+
+The partition initialization routine is a special service that serves SPM
+only, because:
+
+- SPM needs to call the initialization routine, just like it calls into
+ the service routine.
+- The partition initialization routine can access its depending services.
+ Putting initialization routine in the same runtime environment as common
+ service routines can avoid special operations.
+
+Hence a `Partition initialization client` needs to be created to initialize
+the SFN partitions, because:
+
+- `SPM runtime initialization` happen inside a special runtime environment
+ compare to the partition runtime execution, then an environment switching
+ is needed.
+- IPC partitions are initialized by the scheduler and dependencies are
+ handled by signals and messages asynchronously, hence IPC partitions can
+ process the dependencies by their own.
+
+The `Partition initialization client` is created differently based on the
+implementation runtime model:
+
+- A SFN client is created under the SFN model implementation.
+- A IPC client is created under the IPC model implementation. This client
+ thread has the highest priority.
+
+As the other partitions, the client is created with context standby, and it
+is executed after the `Post initialization`_ stage.
+
+Post initialization
+-------------------
+Platform code can change specific partition settings in this procedure before
+partitions start. A few SPM API is callable at this stage, such as set a
+signal into a specific partition, or customized peripheral settings.
+
+Serving
+=======
+Two execution categories work under this state:
+
+- `Partition initialization routine execution`_.
+- `Secure service access`_.
+
+This state indicates the serving is ongoing. It is mainly the service routine
+execution, plus a few SPM executions when SPM API gets called.
+
+.. important::
+ The service access process introduce in this chapter
+ (Such as `Secure service access`_) is abstracted from the FF-M
+ specification. Reference the FF-M specification for the details of each
+ step.
+
+Partition initialization routine execution
+------------------------------------------
+The partition initialization routines get called. One partition may access its
+depending services during initializing, then this procedure is a
+`Secure service access`_.
+
+The initialization routine gets called initially by
+`Partition initialization client`, also can be called by Client API before
+service access, if the target partition is not initialized but a service
+access request is raised by one client.
+
+Secure service access
+---------------------
+The process of service access:
+
+#. A `client` calls an FF-M Client API.
+#. `SPM` validates inputs and looks up for the targeted service.
+#. `SPM` constructs the request to be delivered under a proper runtime
+ mechanism.
+#. The target service gets executed. It can perform internal executions or
+ access depending services to prepare the response. It also can wait for
+ specific signals.
+#. The target service calls FF-M Secure Partition API to request a reply to
+ the client.
+#. SPM delivers the response to the client, and the API called by the client
+ returns.
+
+The mechanism of how SPM interact with the target partition depends on the
+partition runtime model.
+
+- Access to a service in an SFN partition is a function call, which does not
+ switch the current process indicator.
+- Access to a service in an IPC partition leads to scheduling, which switches
+ the current process indicator.
+- When the execution roams between components because of a function call or
+ scheduling, the isolation boundaries NEED to be switched if there are
+ boundaries between components.
+
+.. figure:: media/hybridruntime.*
+ :align: center
+ :name: fig-hybridruntime
+ :width: 60%
+
+No matter what kind of partition a client is trying to access, the SPM API is
+called firstly as it is the interface for service access. There are two ABI
+types when calling SPM API: Cross-boundary or No-cross-boundary.
+
+Calling SPM API
+---------------
+SPM is placed in the PRoT domain. It MAY have isolation boundaries under
+particular isolation levels. For example:
+
+- There are boundaries between ARoT components and SPM under isolated level 2
+ and 3.
+
+Then API SPM provided needs to support the function call (no boundary
+switching) and cross-boundary call. A direct call reaches the API entrance
+directly, while a cross-boundary call needs a mechanism (Supervisor call e.g.)
+to cross the boundary first before reaching the API entrance.
+
+.. figure:: media/twocalltypes.*
+ :align: center
+ :name: fig-twocalltypes
+ :width: 60%
+
+ SPM call types
+
+SPM internal execution flow
+---------------------------
+SPM internal execution flow as shown in diagram:
+
+.. figure:: media/abi_scheduler.*
+ :align: center
+ :name: fig-abi_scheduler
+ :width: 60%
+
+ SPM API runtime
+
+The process:
+
+- PSA API gets called by one of the ABI mentioned in the last chapter as
+ `ABI 1` in the diagram.
+- The unified API Handler calls FF-M and backend subroutines in sequence.
+- The `FF-M` subroutine performs `FF-M` defined operations.
+- The backend operations perform target partition runtime model decided
+ operations. For example, enqueue message into the target partition under
+ the IPC runtime model, or prepare to call context with the message as the
+ parameters under the SFN runtime model.
+- API Handler triggers different ABI based on the result of the backends.
+
+The API handler:
+
+- Can process the `PROGRAMMER_ERROR` in a unified place.
+- Can see the prepared caller and callee context, with exited SPM context. It
+ is an ideal place for subsequent operations such as context switching.
+
+A example code:
+
+.. code-block:: c
+
+ void abi(void *p)
+ {
+ status = spm_api(p);
+ /*
+ * Now both the caller and calle context are
+ * managed by spm_api.
+ */
+ if (status == ACTION1) {
+ /*
+ * Check if extra operations are required
+ * instead of a direct return.
+ */
+ exit_action1();
+ }
+ }
+
+The explanation about `Scheduler Lock`:
+
+Some FF-M API runs as a generic thread to prevent long time exclusive
+execution. When a preemption happens, a new partition thread can call SPM API
+again, makes SPM API nested. It needs extra memory in SPM to be allocated to
+store the preempted context. Lock the scheduler while SPM API is executing can
+ensure SPM API complete execution after preemption is handled. There can be
+multiple ways to lock the scheduler:
+
+- Set a scheduler lock.
+- Set SPM API thread priority as the highest.
+
+Backend service messaging
+-------------------------
+A message to service is created after the target service is found and the
+target partition runtime model is known. The preparation before ABI triggers
+the final accessing:
+
+- The message is pushed into partition memory under a specific ABI mechanism
+ if the target partition model is `SFN` and there are boundaries between SPM
+ and the target partition. After this, requests a specific call type to the
+ SPM ABI module.
+- The target service routine is get called with the message parameter if
+ there are no boundaries between SPM and the target partition and the
+ partition runtime is `SFN`.
+- The message is queued into the partition message list if the target
+ partition runtime model is `IPC`.
+- IPC partition replies to the client by `psa_reply`, which is another SPM API
+ call procedure.
+- SFN partition return triggers an implied `psa_reply`, which is also another
+ SPM API call procedure.
+
+.. note::
+ The backends also handle the isolation boundary switching.
+
+Sessions and contexts
+---------------------
+FF-M API allows multiple sessions for a service if the service is classic
+connection-based. The service can maintain multiple local session data and use
+`rhande` in the message body to identify which client this session is bound
+with.
+
+But this does not mean when an ongoing service accessing is preempted,
+another service access request can get a chance for new access. This is
+because of the limited context storage - supporting multiple contexts in a
+common service costs much memory, and runtime operations(allocation and
+re-location). Limited the context content in the stack only can mitigate the
+effort, but this requirement requires too much for the service development.
+
+The implementation-decisions are:
+
+- IPC partitions handles messages one by one, the client get blocked before
+ the service replying to the client.
+- The client is blocked when accessing services are handling a service
+ request in an SFN partition.
+
+ABI type summary
+----------------
+The interface type is decided by the runtime model of the target component.
+Hence PSA API has two types of ABI: `Cross-boundary ABI` and
+`Function call ABI`. After SPM operations, one more component runtime type
+shows up: The IPC partition, hence `schedule` is the mechanism when accessing
+services inside an IPC partition.
+
+.. figure:: media/spmabitypes.*
+ :align: center
+ :name: fig-spmabi
+ :width: 60%
+
+ ABI types
+
+.. note::
+ The API that does not switch context returns directly, which is not
+ covered in the above diagram.
+
+IDLE state
+==========
+The `IDLE state` can be represented by the `NS Agent` action:
+
+- Launching NSPE software (Trustzone case, e.g.), or send a signal to NSPE
+ software (RPC case, e.g.).
+
+It is because `NS Agent` is the last component being initialized in the
+system. Its execution indicates other partitions' initialization has
+accomplished.
+
+Background state
+================
+Background execution can happen at any time when the arrival of interrupts or
+execution faults. An ongoing background execution indicates the state is a
+`Background state`. The characteristics:
+
+- The background state has a higher execution priority than other states -
+ other states stall when the background state is executing.
+- Background execution can be nested. For example, an
+ interrupt handler can preempt an ongoing interrupt execution.
+- Particular partition code can be involved in the background state, for
+ example, the `First Level Interrupt Handler (FLIH)` of one partition.
+- Background state MUST return to the state it preempts.
+
+.. note::
+ Interrupt handling is a common background state example. Check Interrupt
+ design document for details.
+
+******************************
+Practical implementation items
+******************************
+This chapter describes the practical implementation contents.
+
+.. important::
+ Arm M-profile architecture is the default hardware architecture when
+ describing architecture-specific items.
+
+The general M-profile programming is not involved in this document. The
+following chapters introduce the mandatory settings for security
+requirements.
+
+Architecture security settings
+==============================
+When an `Armv8m Security Extension` (Aka `Trustzone-M`) is available in the
+system, these settings are required to be set:
+
+- The MSPLIM needs to be set correctly to prevent stack overflow.
+- The exception handler priority needs to be decided.
+- Boost the secure handler mode priority to prevent NSPE from preempting SPE
+ handler mode execution(`AIRCR.PRIS`).
+- Disable NSPE hardware faults when a secure fault is happening. Trap in the
+ secure fault with the highest priority can be a valid option.
+- Push seals on the stack top when a stack is allocated (`TFMV-1`). Also
+ check `Stack seal`_ chapter for details.
+
+Besides `Armv8m Security Extension`, these settings need to care when
+`Floatpoint Extension` is enabled for partition usage:
+
+- `FPCCR.TS`, `FPCCR.CLRONRET` and `FPCCR.CLRONRETS` need to be set when
+ booting.
+- `CPACR.CP10` and `CPACR.CP11` need to be set when booting.
+
+.. important::
+ Floatpoint usage is prohibited in SPM and background execution.
+
+Stack seal
+----------
+When Trustzone-M is applied, the architecture specification recommends sealing
+the secure stack by:
+
+- Push two `SEAL` values (`0xFEF5EDA5`) at the stack bottom, when a stack is
+ allocated.
+- Push two `SEAL` values on the stack pointer which is going to be switched
+ out.
+
+Check architecture specification and vulnerability `TFMV-1` for details.
+
+Trustzone-M reentrant
+---------------------
+The Trustzone-M has characteristics that:
+
+- SPE keeps the last assigned stack pointer value when execution leaves SPE.
+- SPE execution can be preempted by NSPE which causes an execution left.
+
+It is possible that NSPE preemption caused a second thread calls into SPE and
+re-uses the secure stack contains the first thread's context, which obviously
+causes information leakage and runtime state inconsistent.
+
+Armv8.1-M provides the hardware setting `CCR_S.TRD` to prevent the reentrant.
+On an Armv8.0-M architecture, extra software logic needs to be added at the
+veneer entry:
+
+- Check if the local stack points to a `SEAL` when veneer code get executed.
+
+.. code-block:: c
+
+ /* This is a theoretical code that is not in a real project. */
+ veneer() {
+ content = get_sp_value();
+ if (context != SEAL) /* Error if reentrant detected */
+ error();
+ }
+
+SPM Runtime ABI
+===============
+This chapter describes the runtime implementation of SPM.
+
+Scheduling
+----------
+The scheduling logic is put inside the PendSV mode. PendSV mode's priority
+is set as one level higher than the default thread mode priority. If
+`Trustzone-M` is present, the priority is set as the lowest just above NS
+exception priority to prevent a preemption in secure exceptions.
+
+PendSV is an ideal place for scheduling logic, because:
+
+- An interrupt triggered scheduling during PendSV execution lead to another
+ PendSV execution before exception return to the thread mode, which can find
+ the latest run-able thread.
+
+Function call ABI
+-----------------
+In the diagram :numref:`fig-abi_scheduler`, the ABI can have two basic
+types: cross-boundary and direct call (No-cross-boundary).
+
+When applying `SVCall` (`SVC`) as the cross-boundary mechanism, the
+implementation can be straight like:
+
+- The SVC handler calls SPM internal routines, and eventually back to the
+ handler before an exit.
+
+Under the IPC model implementation, to re-use `ABI 2` in `No-cross-boundary`,
+a software ABI needs to be provided.
+
+While under the SFN model plus isolation level 1, both `ABI 1` and `ABI 2` can
+be a direct function call.
+
+NS Agent
+========
+The `NS Agent`(`NSA`) forwards NSPE service access request to SPM. It is a
+special `partition` that:
+
+- It does not provide FF-M aligned secure services.
+- It runs with the second-lowest priority under `IPC model implementation`
+ (The IDLE thread has the lowest priority).
+- It has isolation boundaries and an individual stacks.
+- It requires specific services and mechanisms compared to common partitions.
+
+There are two known types for NS Agent:
+
+- Trustzone-M based.
+- Remote Procedure Call (RPC) based.
+
+This process is put inside the ARoT domain, to prevent assign unnecessary
+PRoT permissions to the NSPE request parsing logic.
+
+Trustzone-M specific
+--------------------
+The functionalities of a Truszone-M specific NSA is:
+
+- Launch NSPE when booting.
+- Wait in the veneer code, and get executed when NSPE accesses services.
+
+As there may be multiple NSPE threads calling into SPE, and SPM wants to
+identify them, special mechanisms can be proposed to provide the identification.
+Check specific NS ID client ID or context related documents for details.
+
+.. figure:: media/tzcontext.*
+ :align: center
+ :name: fig-tzcontext
+ :width: 40%
+
+ TZ NSA and specific service
+
+RPC specific
+------------
+Compare to Trustzone-M NSA, RPC NSA looks closer to a generic partition:
+
+- It has a message loop, keep waiting for RPC events.
+- It converts received RPC events into FF-M API call to target services.
+
+And compared to generic partitions, the differences are:
+
+- It parses RPC messages to know which NSPE thread is accessing services.
+ Hence it needs special interfaces to help SPM to identify the NSPE clients.
+- It needs to check NSPE client memory and map to local before calling SPM API.
+- It cannot be blocked during API calls, which affects handling the RPC
+ requests.
+
+Partition
+=========
+A partition is a set of services in the same scope. Services are generally
+implemented as functions, and the partition exposes the services in different
+ways bases on the partition model: `IPC` or `SFN`.
+
+A partition build generates these outputs:
+
+- A partition load information, used by SPM.
+- A partition program containing service interface and logic, typically a
+ library.
+- An optional service API set for easier client usage, by encapsulating
+ the low-level `FF-M` Client API. These API needs to be integrated
+ into client space.
+
+Partition loading
+-----------------
+SPM needs to set up runtime objects to manage partitions by parsing the load
+information of partitions. In general, the partition load information is
+stored in a const memory are can be random read directly, hence SPM can direct
+link runtime objects to the load information without a copy operation. This
+is called a `Static Load` mechanism.
+
+Each partition has different numbers of dependencies and services, this makes
+the load information size of each partition is different, it would be hard
+to put such variable size elements in an array. The solution here is putting
+these elements in a dedicated section, for SPM enumerating while loading.
+Each partition can define variable size load information type bases on the
+common load info type.
+
+The common load information:
+
+.. code-block:: c
+
+ struct partition_load_info_t {
+ uint32_t psa_ff_ver; /* Encode the version with magic */
+ int32_t pid; /* Partition ID */
+ uint32_t flags; /* ARoT/PRoT, SFN/IPC, priority */
+ uintptr_t entry; /* Entry point */
+ size_t stack_size; /* Stack size */
+ size_t heap_size; /* Heap size */
+ uint32_t ndeps; /* Dependency number */
+ uint32_t nservices; /* Service number */
+ uint32_t nassets; /* Asset numbers */
+ uint32_t nirqs; /* Number of IRQ owned by Partition */
+ };
+
+ And the example for a specific partition load info:
+ struct partition_example_load_info_t {
+ struct partition_load_info_t ldi; /* Common info info */
+ uint32_t deps[10]; /* Dependencies */
+ /* ... other infos ... */
+ };
+
+Peripheral binding
+------------------
+A partition can declare multiple peripherals (Interrupts are part of
+peripherals). The peripherals binding process:
+
+- The tooling references symbols in a fixed pattern in the partition load
+ information.
+- The HAL implementation needs to provide the symbols being referenced.
+- SPM calls HAL API to bind the partition info with devices When the partition
+ gets loading.
+- The platform HAL acknowledges the binding if validation pass on SPM given
+ load information.
+
+***************************
+Integration and development
+***************************
+These modules are expected to be object/library level modularised, each
+module should be generated into object/library at build time:
+
+.. list-table:: Object level modularization
+ :header-rows: 1
+ :widths: 40 60
+
+ * - Name
+ - Description
+ * - SPM
+ - All SPM related modules such as SPM, system, and so on.
+ * - Platform
+ - Platform sources are switchable.
+ * - Services and Secure Partition
+ - These items should be standalone.
+ * - Service Runtime Library
+ - This is a shared runtime library.
+
+HAL
+===
+The HAL here mainly refers to the SPM HAL. The SPM HAL implementation is
+running with the same privilege level and hardware mode with SPM. The
+implementation is object level modularized with SPM.
+
+Check the `HAL` design document for details.
+
+Configurations
+==============
+The same TF-M code base is flexible to address different implementation
+requirements, from the simplest device with isolation level 1 to the most
+complicated device with isolation level 3 and optional isolation rules.
+
+These configurations are set by switches, during the build time, as runtime
+support costs extra resources. The common configurations are named `profile`.
+There are several profiles defined.
+
+*******
+History
+*******
+
+.. list-table:: Revision
+ :header-rows: 1
+ :widths: 20 80
+
+ * - Date
+ - Description
+ * - 2021 Apr-Sep
+ - Updated to cover the implementation for `FF-M v1.1` features.
+ * - 2018
+ - Created as 'TF-M Inter-Process Communication' which is deprecated as
+ this document covers whole SPM content.
+
+--------------
+
+*Copyright (c) 2021, Arm Limited. All rights reserved.*
diff --git a/docs/design_docs/source_structure.rst b/docs/design_docs/source_structure.rst
new file mode 100644
index 0000000..89d7205
--- /dev/null
+++ b/docs/design_docs/source_structure.rst
@@ -0,0 +1,164 @@
+###################################
+Trusted Firmware-M Source Structure
+###################################
+
+:Organization: Arm Limited
+:Contact: tf-m@lists.trustedfirmware.org
+
+.. note::
+ Reference the document :doc:`Glossary </glossary>` for terms
+ and abbreviations.
+
+************
+Introduction
+************
+TF-M is designed to provide a user-friendly source structure to ease
+integration and service development. This document introduces the source
+structure and its design intention of TF-M.
+
+.. note::
+ - This document goes ahead of the implementation so the existing source
+ structure may be different from the description listed here. It is
+ recommended to refer to this document for ongoing code structure changes.
+ - By getting feedback from the practical implementation, this document is
+ updated continuously before it is detailed enough to be a user guide.
+
+****************
+Source Structure
+****************
+The description of the source structure is broken down into subsections, each
+subsection introduces one detailed folder.
+
+Root Directory
+==============
+This table describes the structure under the root directory with part of
+possible folders. Note that the ``Detailed`` field indicates if the folder is
+described in details here in this document:
+
+============= ==================================== ====================
+Folder name Purpose Detailed
+============= ==================================== ====================
+bl2 The 2nd stage bootloader. No.
+cmake Cmake files. No.
+configs Configuration system files. No.
+docs The documentations. No.
+lib The 3rd party library. No.
+**platform** Platform intermedia files. See `'platform'`_.
+**secure_fw** The secure firmware. See `'secure_fw'`_.
+tools Tools in scripts for building. No.
+============= ==================================== ====================
+
+'platform'
+==========
+The platform sources contain necessary platform sources or intermedia files
+pointing to the sources out of TF-M folder.
+
+========================= =============================================
+Folder name Purpose
+========================= =============================================
+common/\* Common HAL implementation.
+include/\* Platform public headers.
+<vendor> Vendor specific folders.
+========================= =============================================
+
+.. note::
+ The ``common`` folder contains the example implementation of the ``HAL`` API
+ bases on common ``system`` (CMSIS e.g.). The platform could reference to
+ sources in the ``common`` folder directly if applicable or apply a
+ customized HAL implementation.
+ A ``system`` can have a standalone folder under ``common``, depends on how
+ 'common' this system is. Each ``platform vendor`` is assigned with one
+ folder for usage. As the content of the ``vendor`` folder comes by the
+ contribution of vendors, the ``vendor`` manages the structure inside it.
+
+'secure_fw'
+===========
+This folder contains components needed by secure firmware, and the exported
+interfaces for application, service development and HAL integration:
+
+================= ===================================== ======================
+Folder name Purpose Detailed
+================= ===================================== ======================
+**include** Public headers of 'secure_fw'. See `'include'`_
+**partitions** Default services and supportings. See `'partitions'`_
+**spm** PSA-FF-M SPM implementation. [1] See `'spm'`_
+================= ===================================== ======================
+
+.. note::
+ 1. A PSA-FF-M complied SPM implementation.
+
+ The headers referenced by other modules are public headers and put under the
+ 'include' folder of the current module. Do not put headers not referenced by
+ other modules in this 'include' folder.
+
+'include'
+---------
+This folder holds headers for client, services and platform integration usage.
+
+=========================== ===================================================
+Folder name Purpose
+=========================== ===================================================
+psa/\* PSA FF Client API.
+=========================== ===================================================
+
+.. note::
+ TFM applies an explicit including policy. Each module's headers are put into
+ a specific folder which follows the pattern '\*/inc', this folder needs to be
+ added into the project's searching path if this project needs to include
+ headers in this folder. The 'inc' in a path indicates the end of
+ including-path. If there are subfolders under folder 'inc', apply a
+ hierarchy including.
+
+'partitions'
+------------
+This folder contains default services implemented as partitions and necessary
+partition runtime utilities provided by TF-M.
+
+================================= =============================================
+Folder name Purpose
+================================= =============================================
+lib/runtime/\* The SPRTL sources and intermedia files. [1]
+lib/runtime/shared\* Sources can be shared by out of SPRTL. [2]
+<partition_x>/\* Files for 'partition_x'.
+<partition_x>/include/\* RoT Service API headers of 'partition_x'. [3]
+<partition_y>/\* Files for 'partition_y'.
+<partition_y>/include/\* RoT Service API headers of 'partition_y'. [3]
+================================= =============================================
+
+.. note::
+ 1. The SPRTL sources and intermediate files. SPRTL contains sources from
+ other folders, such as necessary RoT Service API implementation from
+ 'partitions' folder.
+ 2. The sources here can be referenced by the building system out of SPRTL.
+ Generally, they are runtime and PSA APIs.
+ 3. Here takes 'partition_x' and 'partition_y' as an example, and showcases
+ a detailed structure of them. The `<interface>` contains the RoT Service
+ API for client calls. The folder name of this client-orient folder is
+ decided by the service developer.
+
+'spm'
+-----
+The SPM is the core component to provide a mechanism for providing secure
+services.
+
+=================================== ===========================================
+Folder name Purpose
+=================================== ===========================================
+include/\* SPM public headers.
+ffm/\* SPM logic complies with PSA-FF-M and
+ its necessary supporting functionalities,
+ such as the runtime API and the thread
+ operation, etc.
+cmsis_psa/\* CMSIS implementation for PSA-FF-M SPM. [1]
+\* Implementation sources.
+=================================== ===========================================
+
+.. note::
+ 1. CMSIS is the first implementation system.
+ 2. This folder contains a function call based secure firmware implementation.
+ This model is the prototype model which would be updated after the PSA
+ model. Create a standalone folder to hold it.
+
+--------------
+
+*Copyright (c) 2020-2022, Arm Limited. All rights reserved.*
diff --git a/docs/design_docs/stateless_rot_service.rst b/docs/design_docs/stateless_rot_service.rst
new file mode 100644
index 0000000..964c18c
--- /dev/null
+++ b/docs/design_docs/stateless_rot_service.rst
@@ -0,0 +1,228 @@
+##########################################
+Stateless Root of Trust Services Reference
+##########################################
+
+:Author: Mingyang Sun
+:Organization: Arm Limited
+:Contact: mingyang.sun@arm.com
+
+
+************
+Introduction
+************
+
+This document describes the implementation for the FF-M v1.1 feature -
+'Stateless RoT Service', and the related references when developing RoT
+services.
+
+It is recommended to refer to the FF-M v1.0 specification [1]_ and FF-M v1.1
+extension [2]_ for background and rationale details.
+
+
+**********************
+Implementation Details
+**********************
+
+This chapter describes the implementation-defined items, including stateless
+handle value definition, tooling update, and programming API changes.
+
+Stateless Handle Value Definition
+=================================
+
+The index, stateless indicator, and service version information are encoded into
+a handle by the manifest tooling, and then generated to header file ``sid.h``.
+
+.. list-table:: Bit Fields of Stateless Handle
+ :header-rows: 1
+ :widths: 20 80
+
+ * - Bits
+ - Field Description
+ * - bit 31
+ - reserved
+ * - bit 30
+ - stateless handle indicator bit, always 1
+ * - bit 29 - bit 16
+ - reserved
+ * - bit 15 - bit 8
+ - service version requested by client - for client version check
+ * - bit 7 - bit 0
+ - the handle index, [0, 31]
+
+Since connection-based services and stateless services share the same PSA API
+``psa_call()``, an indicator bit is set in the handle indicate the type of the
+handle. If it is set, the handle is stateless, and definition is as described
+in the table above. Maximum connection-based handle is 0x3FFFFFFF, thus the
+indicator bit is always 0.
+
+The index is used for organizing stateless services in manifest tool and
+locating a stateless service in SPM logic. A range of index [0, 31] is the
+initial implementation. Future expansion is possible.
+
+Tooling Support
+===============
+
+TF-M provides a tool (``tools/tfm_parse_manifest_list.py``) to generate source
+header files required by partition and services. For example, the generated
+``sid.h`` contains service ID and version. The tooling is extended to generate
+stateless handle from partition manifests automatically.
+
+The ``stateless_handle`` attribute in manifest is only supported by partitions
+with firmware framework version 1.1.
+
+- If ``stateless_handle`` in manifest is set to an integer, the index is
+ ``stateless_handle - 1``.
+- If it is ``auto`` or not set, the first empty index in range [0, 31] is
+ assigned.
+- Other settings - tooling reports an error.
+
+Finally, the tooling encodes the handle according to definitions in
+`Stateless Handle Value Definition`_ section, and writes them to ``sid.h``
+header file.
+
+Changes in Programming API
+==========================
+
+This chapter describes the changes in programming API for stateless services.
+The following APIs' bebavious and message data structure members are updated to
+support the stateless service.
+
+psa_connect()
+-------------
+
+According to FF-M v1.1, client calling ``psa_connect()`` with the SID of a
+stateless RoT Service is a ``PROGRAMMER_ERROR``.
+
+psa_close()
+-----------
+
+According to FF-M v1.1, client passing a stateless handle to call this API is a
+``PROGRAMMER_ERROR``.
+
+psa_call()
+----------
+
+.. code-block:: c
+
+ psa_status_t psa_call(psa_handle_t handle, int32_t type,
+ const psa_invec *in_vec, size_t in_len,
+ psa_outvec *out_vec, size_t out_len)
+
+API parameters and behaviour change:
+
+1. The ``handle`` parameter must be a stateless handle defined in
+ ``psa_manifest/sid.h`` when requesting a stateless service.
+2. This API validates stateless handle, decodes index and service version
+ information from it. SPM uses the index to know which stateless service is
+ requested.
+3. This API performs some operations as ``psa_connect()`` does, such as the
+ authorization check, service and client version check, and handle space
+ allocation.
+
+Service behaviour change during a "psa_call":
+
+Service does not accept connection and disconnection messages. After a
+"psa_call" request is serviced, it calls ``psa_reply()``, frees the connection
+handle to handle pool.
+
+psa_set_rhandle()
+-----------------
+
+According to FF-M v1.1, stateless service calling this API on a message is a
+``PROGRAMMER_ERROR`` and it will never return.
+
+psa_msg_t type
+--------------
+
+The ``rhandle`` member of a ``psa_msg_t`` type received by a stateless RoT
+Service is always ``NULL``.
+
+
+**************************
+Application Recommendation
+**************************
+
+There are particular services that do not need sessions. The access to the
+service is a one-shot connection. These services provide standalone operations
+that do not require any non-volatile state of resources to be maintained by the
+RoT service itself or do not expose any kind of context or session to the
+caller. Such services are recommended to be implemented as stateless, to provide
+quick access and to avoid extra overheads.
+
+In this case, ``rhandle`` access would be prohibited as it is used for saving
+state or non-volatile resources while stateless services do not need them.
+
+Update Feasibility of Existing Services
+=======================================
+
+TF-M native services are used widely. They only need standalone operations and
+do not need to keep state between sessions. For example, the service in Crypto
+partition does not do anything during ``psa_connect()`` or ``psa_close()``
+process. Same for services in other partitions, thus all of them can be
+implemented as stateless.
+
+Analysis for them:
+
+.. list-table:: TF-M Partition Services Update Possibility
+ :header-rows: 1
+ :widths: 30 30 40
+
+ * - Partition
+ - Number of Services
+ - Can be Stateless
+ * - ITS
+ - 4
+ - All
+ * - PS
+ - 5
+ - All
+ * - Crypto
+ - 1
+ - All
+ * - FWU
+ - 6
+ - All
+ * - Platform
+ - 4
+ - All
+ * - Initial Attestation
+ - 2
+ - All
+
+Other services are not analyzed here.
+
+Grouping Services
+=================
+
+Stateless service table is stored statically, and TF-M supports 32 stateless
+services currently.
+
+Similar stateless services in a partition could be grouped, and assign one
+``SID`` for the group. The ``type`` parameter in ``psa_call()`` could be
+extended to identify the service in group. In this case, it is recommended to
+use consecutive value for ``type``.
+
+It is recommended that each Seccure Partition declares one stateless service
+and uses the type parameter to distinguish different stateless services.
+Therefore, more stateless services can be supported.
+
+Migrating to Stateless Services
+===============================
+
+Please refer to Chapter 4 "Stateless Root of Trust services", Appendix B.3.2
+"Using a stateless RoT Service", and Appendix D "Implementing session-less RoT
+Services" in FF-M v1.1 document for details on which kind of service can be
+stateless and how to implement a stateless service.
+
+
+*********
+Reference
+*********
+
+.. [1] `FF-M v1.0 Specification <https://developer.arm.com/-/media/Files/pdf/PlatformSecurityArchitecture/Architect/DEN0063-PSA_Firmware_Framework-1.0.0-2.pdf?revision=2d1429fa-4b5b-461a-a60e-4ef3d8f7f4b4>`__
+
+.. [2] `FF-M v1.1 Extention <https://documentation-service.arm.com/static/600067c09b9c2d1bb22cd1c5?token=>`__
+
+--------------
+
+*Copyright (c) 2021, Arm Limited. All rights reserved.*
diff --git a/docs/design_docs/symmetric_initial_attest.rst b/docs/design_docs/symmetric_initial_attest.rst
new file mode 100644
index 0000000..02b23cd
--- /dev/null
+++ b/docs/design_docs/symmetric_initial_attest.rst
@@ -0,0 +1,564 @@
+#################################################
+Symmetric key algorithm based Initial Attestation
+#################################################
+
+:Author: David Hu
+:Organization: Arm Limited
+:Contact: david.hu@arm.com
+
+************
+Introduction
+************
+
+This document proposes a design of symmetric key algorithm based Initial
+Attestation in TF-M.
+
+Symmetric key algorithm based Initial Attestation
+(*symmetric Initial Attestation* for short) signs and verifies Initial
+Attestation Token (IAT) with a symmetric cryptography signature scheme, such as
+HMAC.
+It can reduce TF-M binary size and memory footprint on ultra-constrained devices
+without integrating asymmetric ciphers.
+
+This proposal follows PSA Attestation API document [1]_.
+
+.. note ::
+
+ As pointed out by PSA Attestation API [1]_, the use cases of Initial
+ Attestation based on symmetric key algorithms can be limited due to
+ the associated infrastructure costs for key management and operational
+ complexities. It may also restrict the ability to interoperate with
+ scenarios that involve third parties.
+
+***************
+Design overview
+***************
+
+The symmetric Initial Attestation follows the existing IAT generation sequence
+for Initial Attestation based on asymmetric key algorithm
+(*asymmetric Initial Attestation* for short).
+
+As Profile Small design [2]_ requests, a configuration flag
+``SYMMETRIC_INITIAL_ATTESTATION`` selects symmetric initial attestation during
+build.
+
+The top-level design is shown in :ref:`overall-diagram-figure` below.
+
+.. _overall-diagram-figure:
+
+.. figure:: media/symmetric_initial_attest/overall_diagram.png
+ :align: center
+
+ Overall design diagram
+
+Symmetric Initial Attestation adds its own implementations of some steps in IAT
+generation in Initial Attestation secure service. More details are covered in
+`IAT generation in Initial Attestation secure service`_.
+
+The interfaces and procedures of Initial Attestation secure service are not
+affected. Refer to Initial Attestation Service Integration Guide [3]_ for
+details of the implementation of Initial Attestation secure service.
+
+Symmetric Initial Attestation invokes ``t_cose`` library to build up
+``COSE_Mac0`` structure.
+``COSE_Mac0`` support is added to ``t_cose`` library in TF-M since official
+``t_cose`` hasn't supported ``COSE_Mac0`` yet. The design of ``COSE_Mac0``
+support is covered in `COSE_Mac0 support in t_cose`_.
+
+.. note ::
+
+ The ``COSE_Mac0`` implementation in this proposal is a prototype only for
+ Proof of Concept so far. It may be replaced after ``t_cose`` officially
+ supports ``COSE_Mac0`` message.
+
+Several HAL APIs are defined to fetch platform specific assets required by
+Symmetric Initial Attestation. For example, ``tfm_plat_get_symmetric_iak()``
+fetches symmetric Initial Attestation Key (IAK). Those HAL APIs are summarized
+in `HAL APIs`_.
+
+Decoding and verification of symmetric Initial Attestation is also included in
+this proposal for regression test.
+The test suites and IAT decoding are discussed in `TF-M Test suite`_.
+
+``QCBOR`` library and Crypto service are also invoked. But this proposal doesn't
+require any modification to either ``QCBOR`` or Crypto service. Therefore,
+descriptions of ``QCBOR`` and Crypto service are skipped in this document.
+
+****************************************************
+IAT generation in Initial Attestation secure service
+****************************************************
+
+The sequence of IAT generation of symmetric Initial Attestation is shown in
+:ref:`ia-service-figure` below. Note that the ``Register symmetric IAK`` stage
+is no longer required due to changes in the Crypto partition
+(``attest_symmetric_key.c`` is now responsible only for calculating the instance
+ID).
+
+.. _ia-service-figure:
+
+.. figure:: media/symmetric_initial_attest/ia_service_flow.png
+ :align: center
+
+ Symmetric IAT generation flow in Initial Attestation secure service
+
+In Initial Attestation secure service, symmetric Initial Attestation implements
+the following steps in ``attest_create_token()``, which are different from those
+of asymmetric Initial Attestation.
+
+ - ``attest_token_start()``
+ - Instance ID claims
+ - ``attest_token_finish()``
+
+If ``SYMMETRIC_INITIAL_ATTESTATION`` is selected, symmetric Initial Attestation
+dedicated implementations of those steps are included in build.
+Otherwise, asymmetric Initial Attestation dedicated implementations are included
+instead.
+
+Symmetric Initial Attestation implementation resides a new file
+``attest_symmetric_key.c`` to handle symmetric Instance ID related operations.
+Symmetric Initial Attestation dedicated ``attest_token_start()`` and
+``attest_token_finish()`` are added in ``attestation_token.c``.
+
+The details are covered in following sections.
+
+Symmetric Instance ID
+=====================
+
+Symmetric Initial Attestation dedicated ``attest_symmetric_key.c`` implements
+the ``attest_get_instance_id()`` function. This function returns the Instance ID
+value, calculating it if it has not already been calculated. Refer to
+`Instance ID claim_` for more details.
+
+.. note ::
+
+ Only symmetric IAK for HMAC algorithm is allowed so far.
+
+Instance ID calculation
+-----------------------
+
+In symmetric Initial Attestation, Instance ID is also calculated the first time
+it is requested. It can protect critical symmetric IAK from being frequently
+fetched, which increases the risk of asset disclosure.
+
+The Instance ID value is the output of hashing symmetric IAK raw data *twice*,
+as requested in PSA Attestation API [1]_. HMAC-SHA256 may be hard-coded as the
+hash algorithm of Instance ID calculation.
+
+.. note ::
+
+ According to RFC2104 [4]_, if a HMAC key is longer than the HMAC block size,
+ the key will be first hashed. The hash output is used as the key in HMAC
+ computation.
+
+ In current design, HMAC is used to calculate the authentication tag of
+ ``COSE_Mac0``. Assume that symmetric IAK is longer than HMAC block size
+ (HMAC-SHA256 by default), the Instance ID is actually the HMAC key for
+ ``COSE_Mac0`` authentication tag generation, if Instance ID value is the
+ output of hashing IAK only *once*.
+ Therefore, attackers may request an valid IAT from device and fake malicious
+ ones by using Instance ID to calculate valid authentication tags, to cheat
+ others.
+
+ As a result, symmetric IAK raw data should be hashed *twice* to generate the
+ Instance ID value.
+
+The Instance ID calculation result is stored in a static buffer.
+Token generation process can call ``attest_get_instance_id()`` to
+fetch the data from that static buffer.
+
+attest_token_start()
+====================
+
+Symmetric Initial Attestation dedicated ``attest_token_start()`` initializes the
+``COSE_Mac0`` signing context and builds up the ``COSE_Mac0`` Header.
+
+The workflow inside ``attest_token_start()`` is shown in
+:ref:`attest-token-start-figure` below.
+
+.. _attest-token-start-figure:
+
+.. figure:: media/symmetric_initial_attest/attest_token_start.png
+ :align: center
+
+ Workflow in symmetric Initial Attestation ``attest_token_start()``
+
+Descriptions of each step are listed below:
+
+#. ``t_cose_mac0_sign_init()`` is invoked to initialize ``COSE_Mac0`` signing
+ context in ``t_cose``.
+
+#. The symmetric IAK handle is set into ``COSE_Mac0`` signing context via
+ ``t_cose_mac0_set_signing_key()``.
+
+#. Initialize ``QCBOR`` encoder.
+
+#. The header parameters are encoded into ``COSE_Mac0`` structure in
+ ``t_cose_mac0_encode_parameters()``.
+
+#. ``QCBOREncode_OpenMap()`` prepares for encoding the ``COSE_Mac0`` payload,
+ which is filled with IAT claims.
+
+All the ``COSE_Mac0`` functionalities in ``t_cose`` are covered in
+`COSE_Mac0 support in t_cose`_.
+
+Instance ID claim
+=================
+
+Symmetric Initial Attestation also implements Instance ID claims in
+``attest_add_instance_id_claim()``.
+
+The Instance ID value is fetched via ``attest_get_instance_id()``.
+The value has already been calculated during symmetric IAK registration. See
+`Instance ID calculation`_ for details.
+
+The other steps are the same as those in asymmetric Initial Attestation
+implementation. The UEID type byte is set to 0x01.
+
+attest_token_finish()
+=====================
+
+Symmetric Initial Attestation dedicated ``attest_token_finish()`` calls
+``t_cose_mac0_encode_tag()`` to calculate and encode the authentication tag of
+``COSE_Mac0`` structure.
+
+The whole COSE and CBOR encoding are completed in ``attest_token_finish()``.
+
+The simplified flow in ``attest_token_finish()`` is shown in
+:ref:`attest-token-finish-figure` below.
+
+.. _attest-token-finish-figure:
+
+.. figure:: media/symmetric_initial_attest/attest_token_finish.png
+ :align: center
+
+ Workflow in symmetric Initial Attestation ``attest_token_finish()``
+
+***************************
+COSE_Mac0 support in t_cose
+***************************
+
+``COSE_Mac0`` supports in ``t_cose`` in TF-M include the following major
+functionalities:
+
+ - Encoding ``COSE_Mac0`` structure
+ - Decoding and verifying ``COSE_Mac0`` structure
+ - HMAC computation to generate and verify authentication tag
+ - Short-circuit tagging for test mode
+
+According to RFC8152 [5]_, ``COSE_Mac0`` and ``COSE_Sign1`` have similar
+structures. Therefore, the prototype follows ``COSE_Sign1`` implementation to
+build up ``COSE_Mac0`` file structure and implement ``COSE_Mac0`` encoding and
+decoding.
+
+Although ``COSE_Mac0`` can share lots of data types, APIs and encoding/decoding
+steps with ``COSE_Sign1`` in implementation, this prototype separates
+``COSE_Mac0`` implementation from ``COSE_Sign1``. ``COSE_Mac0`` owns its
+dedicated signing/verification contexts, APIs and encoding/decoding process.
+The purposes of separating ``COSE_Mac0`` and ``COSE_Sign1`` are listed below
+
+- It can keep changes to ``COSE_Sign1`` as small as possible and avoid conflicts
+ with development in ``COSE_Sign1```. It can decrease conflicts if ``t_cose``
+ in TF-M is synchronized with original ``t_cose`` repository later.
+- ``COSE_Mac0`` and ``COSE_Sign1`` are exclusive in TF-M use cases.
+ It cannot decrease TF-M memory footprint by extracting the common components
+ shared by ``COSE_Mac0`` and ``COSE_Sign1`` but can make the design
+ over-complicated.
+
+.. note ::
+
+ Only HMAC is supported in current ``COSE_Mac0`` prototype.
+
+File structure
+==============
+
+New files are added to implement the functionalities listed above. The structure
+of files is shown in the table below.
+
+.. table:: New files in ``t_cose``
+ :widths: auto
+ :align: center
+
+ +---------------------+--------------------------------+----------------------------------------------+
+ | Directory | Files | Descriptions |
+ +=====================+================================+==============================================+
+ | ``src`` | ``t_cose_mac0_sign.c`` | Encode ``COSE_Mac0`` structure |
+ | +--------------------------------+----------------------------------------------+
+ | | ``t_cose_mac0_verify.c`` | Decode and verify ``COSE_Mac0`` structure. |
+ +---------------------+--------------------------------+----------------------------------------------+
+ | ``inc`` | ``t_cose_mac0_sign.h`` | Data type definitions and function |
+ | | | declarations of encoding and signing |
+ | | | ``COSE_Mac0`` message. |
+ | +--------------------------------+----------------------------------------------+
+ | | ``t_cose_mac0_verify.h`` | Data type definitions and function |
+ | | | declarations of verifying ``COSE_Mac0`` |
+ | | | message. |
+ +---------------------+--------------------------------+----------------------------------------------+
+
+Other ``t_cose`` files may also be changed to add ``COSE_Mac0`` associated data
+types and function declarations.
+
+HMAC operations are added in ``crypto_adapters/t_cose_psa_crypto.c``.
+Preprocessor flags are added to select corresponding crypto for COSE message
+signing and verification.
+
+ - ``T_COSE_ENABLE_SIGN1`` selects ECDSA and Hash operations for
+ ``COSE_Sign1``.
+ - ``T_COSE_ENABLE_MAC0`` selects HMAC operations for ``COSE_Mac0``.
+
+Encoding COSE_Mac0
+==================
+
+Following ``COSE_Sign1`` implementation, ``COSE_Mac0`` encoding exports similar
+functions to Initial Attestation secure service.
+The major functions are listed below.
+
+Initialize signing context
+--------------------------
+
+``t_cose_mac0_sign_init()`` initializes ``COSE_Mac0`` signing context and
+configures option flags and algorithm used in signing.
+
+.. code-block:: c
+
+ static void
+ t_cose_mac0_sign_init(struct t_cose_mac0_sign_ctx *me,
+ int32_t option_flags,
+ int32_t cose_algorithm_id);
+
+The ``COSE_Mac0`` signing context is defined as
+
+.. code-block:: c
+
+ struct t_cose_mac0_sign_ctx {
+ /* Private data structure */
+ uint8_t protected_parameters_buffer[
+ T_COSE_MAC0_MAX_SIZE_PROTECTED_PARAMETERS];
+ struct q_useful_buf_c protected_parameters; /* The encoded protected parameters */
+ int32_t cose_algorithm_id;
+ struct t_cose_key signing_key;
+ int32_t option_flags;
+ struct q_useful_buf_c kid;
+ ...
+ };
+
+Set signing key
+---------------
+
+``t_cose_mac0_set_signing_key()`` sets the key used in ``COSE_Mac0`` signing.
+Optional ``kid``, as a key identifer, will be encoded into ``COSE_Mac0`` Header
+unprotected bucket.
+
+.. code-block:: c
+
+ static void
+ t_cose_mac0_set_signing_key(struct t_cose_mac0_sign_ctx *me,
+ struct t_cose_key signing_key,
+ struct q_useful_buf_c kid);
+
+Encode Header parameters
+------------------------
+
+``t_cose_mac0_encode_parameters()`` encodes the ``COSE_Mac0`` Header parameters
+and outputs the encoded context to ``cbor_encode_ctx``.
+
+.. code-block:: c
+
+ enum t_cose_err_t
+ t_cose_mac0_encode_parameters(struct t_cose_mac0_sign_ctx *context,
+ QCBOREncodeContext *cbor_encode_ctx);
+
+Calculate and add authentication tag
+------------------------------------
+
+``t_cose_mac0_encode_tag()`` calculates the authentication tag and finishes the
+``COSE_Mac0`` message.
+
+.. code-block:: c
+
+ enum t_cose_err_t
+ t_cose_mac0_encode_tag(struct t_cose_mac0_sign_ctx *context,
+ QCBOREncodeContext *cbor_encode_ctx);
+
+Decoding COSE_Mac0
+==================
+
+Following ``COSE_Sign1`` implementation, ``COSE_Mac0`` decoding exports similar
+functions to test suite of Initial Attestation.
+The major functions are listed below.
+
+Initialize verification context
+-------------------------------
+
+``t_cose_mac0_verify_init()`` initializes ``COSE_Mac0`` verification context and
+configures option flags in verification.
+
+.. code-block:: c
+
+ static void
+ t_cose_mac0_verify_init(struct t_cose_mac0_verify_ctx *context,
+ int32_t option_flags);
+
+The ``COSE_Mac0`` verification context is defined as
+
+.. code-block:: c
+
+ struct t_cose_mac0_verify_ctx {
+ /* Private data structure */
+ struct t_cose_key verification_key;
+ int32_t option_flags;
+ };
+
+Set verification key
+--------------------
+
+``t_cose_mac0_set_verify_key()`` sets the key for verifying ``COSE_Mac0``
+authentication tag.
+
+.. code-block:: c
+
+ static void
+ t_cose_mac0_set_verify_key(struct t_cose_mac0_verify_ctx *context,
+ struct t_cose_key verify_key);
+
+Decode and verify COSE_Mac0
+---------------------------
+
+``t_cose_mac0_verify()`` decodes the ``COSE_Mac0`` structure and verifies the
+authentication tag.
+
+.. code-block:: c
+
+ enum t_cose_err_t
+ t_cose_mac0_verify(struct t_cose_mac0_verify_ctx *context,
+ struct q_useful_buf_c cose_mac0,
+ struct q_useful_buf_c *payload,
+ struct t_cose_parameters *parameters);
+
+Short-circuit tagging
+=====================
+
+If ``T_COSE_OPT_SHORT_CIRCUIT_TAG`` option is enabled, ``COSE_Mac0`` encoding
+will hash the ``COSE_Mac0`` content and add the hash output as an authentication
+tag. It is useful when critical symmetric IAK is unavailable or cannot be
+accessed, perhaps because it has not been provisioned or configured for the
+particular device. It is only for test and must not be used in actual use case.
+The ``kid`` parameter will either be skipped in ``COSE_Mac0`` Header.
+
+If ``T_COSE_OPT_ALLOW_SHORT_CIRCUIT`` option is enabled, ``COSE_Mac0`` decoding
+will only verify the hash output, without requiring symmetric key for
+authentication tag verification.
+
+***************
+TF-M Test suite
+***************
+
+Symmetric Initial Attestation adds dedicated non-secure and secure test suites.
+The test suites also follow asymmetric Initial Attestation test suites
+implementation but optimize the memory footprint.
+Symmetric Initial Attestation non-secure and secure test suites request Initial
+Attestation secure service to generate IATs. After IATs are generated
+successfully, test suites decode IATs and parse the claims.
+Secure test suite also verifies the authentication tag in ``COSE_Mac0``
+structure.
+
+Symmetric Initial Attestation implements its dedicated
+``attest_token_decode_validate_token()`` in ``attest_symmetric_iat_decoded.c``
+to perform IAT decoding required by test suites.
+If ``SYMMETRIC_INITIAL_ATTESTATION`` is selected,
+``attest_symmetric_iat_decoded.c`` is included in build.
+Otherwise, asymmetric Initial Attestation dedicated implementations are included
+instead.
+
+The workflow of symmetric Initial Attestation dedicated
+``attest_token_decode_validate_token()`` is shown below.
+
+.. _iat-decode-figure:
+
+.. figure:: media/symmetric_initial_attest/iat_decode.png
+ :align: center
+
+ Workflow in symmetric Initial Attestation ``attest_token_decode_validate_token()``
+
+If the decoding is required from secure test suite,
+``attest_token_decode_validate_token()`` will fetch symmetric IAK to verify the
+authentication tag in ``COSE_Mac0`` structure.
+If the decoding is required from non-secure test suite,
+``attest_token_decode_validate_token()`` will decode ``COSE_Mac0`` only by
+setting ``T_COSE_OPT_DECODE_ONLY`` option flag. Non-secure must not access the
+symmetric IAK.
+
+********
+HAL APIs
+********
+
+HAL APIs are summarized below.
+
+Fetch device symmetric IAK
+==========================
+
+``tfm_plat_get_symmetric_iak()`` fetches device symmetric IAK.
+
+ .. code-block:: c
+
+ enum tfm_plat_err_t tfm_plat_get_symmetric_iak(uint8_t *key_buf,
+ size_t buf_len,
+ size_t *key_len,
+ psa_algorithm_t *key_alg);
+
+ **Parameters:**
+
+ +-------------+-----------------------------------------------------------+
+ | ``key_buf`` | Buffer to store the symmetric IAK. |
+ +-------------+-----------------------------------------------------------+
+ | ``buf_len`` | The length of ``key_buf``. |
+ +-------------+-----------------------------------------------------------+
+ | ``key_len`` | The length of the symmetric IAK. |
+ +-------------+-----------------------------------------------------------+
+ | ``key_alg`` | The key algorithm. Only HMAC SHA-256 is supported so far. |
+ +-------------+-----------------------------------------------------------+
+
+It returns error code specified in ``enum tfm_plat_err_t``.
+
+Get symmetric IAK key identifier
+================================
+
+``attest_plat_get_symmetric_iak_id()`` gets the key identifier of the symmetric
+IAK as the ``kid`` parameter in COSE Header.
+
+Optional if device doesn't install a key identifier for symmetric IAK.
+
+ .. code-block:: c
+
+ enum tfm_plat_err_t attest_plat_get_symmetric_iak_id(void *kid_buf,
+ size_t buf_len,
+ size_t *kid_len);
+
+ **Parameters:**
+
+ +-------------+-------------------------------------+
+ | ``kid_buf`` | Buffer to store the IAK identifier. |
+ +-------------+-------------------------------------+
+ | ``buf_len`` | The length of ``kid_buf``. |
+ +-------------+-------------------------------------+
+ | ``kid_len`` | The length of the IAK identifier. |
+ +-------------+-------------------------------------+
+
+It returns error code specified in ``enum tfm_plat_err_t``.
+
+*********
+Reference
+*********
+
+.. [1] `PSA Attestation API 1.0 (ARM IHI 0085) <https://developer.arm.com/-/media/Files/pdf/PlatformSecurityArchitecture/Implement/IHI0085-PSA_Attestation_API-1.0.2.pdf?revision=eef78753-c77e-4b24-bcf0-65596213b4c1&la=en&hash=E5E0353D612077AFDCE3F2F3708A50C77A74B2A3>`_
+
+.. [2] :doc:`Trusted Firmware-M Profile Small Design </configuration/profiles/tfm_profile_small>`
+
+.. [3] :doc:`Initial Attestation Service Integration Guide </integration_guide/services/tfm_attestation_integration_guide>`
+
+.. [4] `HMAC: Keyed-Hashing for Message Authentication <https://tools.ietf.org/html/rfc2104>`_
+
+.. [5] `CBOR Object Signing and Encryption (COSE) <https://tools.ietf.org/html/rfc8152>`_
+
+----------------
+
+*Copyright (c) 2020-2022 Arm Limited. All Rights Reserved.*
diff --git a/docs/design_docs/tfm_builtin_keys.rst b/docs/design_docs/tfm_builtin_keys.rst
new file mode 100644
index 0000000..c27d2ca
--- /dev/null
+++ b/docs/design_docs/tfm_builtin_keys.rst
@@ -0,0 +1,171 @@
+#################
+TF-M builtin keys
+#################
+
+:Author: Raef Coles
+:Organization: Arm Limited
+:Contact: raef.coles@arm.com
+
+************
+Introduction
+************
+
+TF-M has several keys that are bound to the device itself instead of a secure
+partition. These keys must be accessed through a HAL function, either loading
+them from OTP or another platform-specific location. These keys are henceforth
+referred to as "builtin keys", and include (but are not limited to):
+
+1) The Hardware Unique Key (HUK)
+2) The Initial Attestation Key (IAK)
+
+Currently, the IAK is loaded by the attestation partition as a transient key,
+which requires some key-loading logic to be implemented by that partition. The
+HUK is not loaded in the crypto service, and is instead used by an
+implementation of a TF-M specific KDF algorithm which then loads the key and
+invokes Mbed TLS directly.
+
+****************
+PSA builtin keys
+****************
+
+The PSA Cryptographic API provides a mechanism for accessing keys that are
+stored in platform-specific locations (often hardware accelerators or OTP). One
+of the properties of builtin keys is that they are accessed via a predefined
+handle, which can be leveraged to allow TF-M to define a set of handles for the
+builtin keys that it provides.
+
+Defining these constant handles allows these keys to be used by secure partition
+and non-secure callers (subject to access policy), via the standard PSA crypto
+interfaces.
+
+Ideally, it would be possible to just have PSA builtin keys that are stored in
+crypto service RAM, in the same way that volatile keys are. Mbed TLS does not
+support this and only supports builtin keys as part of the code flow that
+interfaces with hardware accelerators.
+
+*********************
+PSA crypto driver API
+*********************
+
+The PSA crypto driver API allows most PSA Crypto APIs to defer their operation
+to an accelerator driver in preference of the software implementation. It also
+adds the concept of storage locations for keys, which is used to access keys
+stored on hardware accelerators.
+
+The TF-M builtin keys code leverages the PSA crypto driver API by creating a new
+driver that provides no acceleration, only a key storage location. This storage
+location is not backed by hardware, but is instead inside the RAM of the crypto
+partition.
+
+This is done by hooking two functions into the
+``library/psa_crypto_driver_wrappers.c`` file. These functions are:
+
+1) ``tfm_key_loader_get_builtin_key``
+2) ``tfm_key_loader_get_builtin_key_len``
+
+The flow for these functions being used is:
+
+1) A request is made to a PSA Crypto API that references a key by a key
+ handle.
+2) The PSA Crypto core layer checks that the handle is inside the builtin keys
+ region, and then if the key has not yet been loaded into a transient Mbed
+ TLS keyslot calls ``tfm_plat_builtin_key_get_lifetime_and_slot`` (which is a
+ wrapper around ``mbedtls_psa_platform_get_builtin_key``), which is defined
+ in ``crypto_keys.h``. This function maps each builtin key to a driver, which
+ in most cases is the default ``tfm_builtin_key_loader`` via
+ ``TFM_BUILTIN_KEY_LOADER_KEY_LOCATION``. The function also returns a slot
+ number, which is a driver-specific index to specify the key.
+3) This location and slot index then calls
+ ``psa_driver_wrapper_get_builtin_key``, which for the key location
+ ``TFM_BUILTIN_KEY_LOADER_KEY_LOCATION`` (the new location value that is bound
+ to the TF-M builtin keys driver) calls the previously hooked function
+ ``tfm_key_loader_get_builtin_key``.
+4) This function, along with its counterpart
+ ``tfm_key_loader_get_builtin_key_len``, allow Mbed TLS to copy the
+ key material into an internal keyslot, which is then used whenever further
+ calls to using that same builtin key ID are made.
+
+In order to load the keys into the tfm_key_loader memory (in the crypto
+partition), ``crypto_keys.h`` defines a function ``tfm_plat_load_builtin_keys``
+which is responsible for loading all builtin keys into and driver that requires
+loading.
+
+*****************
+Technical details
+*****************
+
+------------------------------
+Builtin key IDs and overriding
+------------------------------
+
+TF-M builtin key IDs are defined in ``interface/include/tfm_crypto_defs.h`` by
+the enum ``tfm_key_id_builtin_t``. They are allocated inside the range that PSA
+considers to be builtin keys. A platform can specify extra builtin key IDs by
+setting the ``PLATFORM_DEFAULT_CRYPTO_KEYS`` variable to ``OFF``, creating the
+header ``platform_builtin_key_ids.h``, and specifying new keys and IDs.
+
+--------------------------
+Builtin key access control
+--------------------------
+
+Builtin keys by default can be used by any caller since the key handle is
+public information. TF-M must mediate access to the keys, which is done in the
+function ``tfm_plat_builtin_key_get_usage`` (part of ``crypto_keys.h``). This
+function maps the caller ID to a particular key usage, which allows granular key
+permissions. The function returns ``PSA_ERROR_NOT_PERMITTED`` if a caller does
+not have permission to use the key.
+
+------------------------------
+Multi-partition key derivation
+------------------------------
+
+The HUK is used for key derivation by any secure partition or NS caller that
+requires keys that are bound to a particular context. For example, Protected
+Storage derives keys uniquely for each user of the service which are used to
+encrypt each user's files. In order to provide HUK derivation to every secure
+partition / NS caller, it must be ensured that no service that utilises HUK
+derivation can derive the same key as another service (simply by inputting the
+same KDF inputs).
+
+This is accomplished by deriving a further "platform key" for each builtin key
+that can be used for key derivation. These platform keys are derived from the
+builtin key, using the partition ID as a KDF input, and can then be used for
+further derivation by the partition (or NS caller) with the further derived keys
+being unique for each partition even if the KDF inputs are the same.
+
+.. Note::
+ If the NS client ID feature is disabled, all NS callers share a partition ID
+ of ``-1``, and therefore will share a platform key and be therefore be able
+ to derive the same keys as other NS callers.
+
+For keys that are not exposed outside the device, this is transparent to the
+service that is using the key derivation, as they have no access to the builtin
+key material and cannot distinguish between keys derived directly from it and
+keys derived from the platform key. For some builtin keys, deriving platform
+keys is not acceptable, as the key is used outside the device (i.e. the IAK
+public key is used to verify attestation tokens) so the actual builtin key is
+used.
+
+The decision has been taken to derive platform keys for any key that can be used
+for key derivation (``PSA_KEY_USAGE_DERIVE``), and not derive platform keys
+otherwise. For builtin keys that do not derive platform keys but are directly
+used, care must be taken with access control where multiple partitions have
+access.
+
+---------------------------------
+Mbed TLS transparent builtin keys
+---------------------------------
+
+Mbed TLS does not natively support transparent builtin keys (transparent keys
+are keys where the key material is directly accessible to the PSA Crypto core),
+so some modifications had to be made. Opaque keyslots have the same basic
+structure as standard transparent keyslots, and can be passed to the functions
+usually reserved for transparent keys, though this behaviour is not defined and
+may not continue to work in future versions. Therefore, the only modification
+required currently is to force keys that have the location
+``TFM_BUILTIN_KEY_LOADER_KEY_LOCATION`` to be passed to the functions that only
+usually accept keys with the location ``PSA_KEY_LOCATION_LOCAL_STORAGE``.
+
+--------------
+
+*Copyright (c) 2022, Arm Limited. All rights reserved.*
diff --git a/docs/design_docs/tfm_code_generation_with_jinja2.rst b/docs/design_docs/tfm_code_generation_with_jinja2.rst
new file mode 100644
index 0000000..fbdfbbc
--- /dev/null
+++ b/docs/design_docs/tfm_code_generation_with_jinja2.rst
@@ -0,0 +1,78 @@
+###########################
+Code Generation With Jinja2
+###########################
+
+:Author: Mate Toth-Pal
+:Organization: Arm Limited
+:Contact: Mate Toth-Pal <mate.toth-pal@arm.com>
+
+***************************************
+Generating files from templates in TF-M
+***************************************
+
+Some of the files in TF-M are generated from template files. The files to be
+generated are listed in ``tools/tfm_generated_file_list.yaml``. For each
+generated file ``<path_to_file>/<filename>`` the template file is
+``<path_to_file>/<filename>.template``. The templates are populated with
+partition information from the partition manifests. The manifests to be used for
+the generation are listed in ``tools/tfm_manifest_list.yaml``.
+
+****************************************
+Custom generator script - Current method
+****************************************
+
+``tools/tfm_parse_manifest_list.py`` Python script is used to generate files
+from the templates. This script calls the ``tools/generate_from_template.py`` to
+parse the template files, and uses ``tools/keyword_substitution.py`` to
+substitute the keychains with actual values from the manifest files.
+
+*************************************
+Use Jinja2 template engine - proposal
+*************************************
+
+The proposal is to eliminate the template parser and substituter scripts, and
+call the Jinja2 template engine library from
+``tools/tfm_parse_manifest_list.py`` to do the substitution.
+
+More information on jinja2: http://jinja.pocoo.org/
+
+Changes needed:
+===============
+
+- ``tools/tfm_parse_manifest_list.py`` have to be modified to call the Jinja2
+ library instead of the custom scripts. The data structure required by the
+ library is very similar to the one required by the current scripts.
+- template files needs to be rewritten to the Jinja syntax: The control
+ characters to be replaced (like ``@!`` -> ``{%``) and ``for`` statements to be
+ added to iterate over the substitutions.
+
+Improvements over the current solution
+======================================
+
+- Compatible with Python 2.7 and Python 3, while current solution only supports
+ Python 2.7
+- More advanced functionality: direct control over the list of items for a
+ keychain, meta information on that list (like length)
+- Well documented (see website)
+- Jinja2 is free and open-source software, BSD licensed, just like TF-M. It is a
+ well established software in contrast with the current proprietary solution.
+
+*******
+Example
+*******
+
+Below code snippet enumerates services in Secure Partitions:
+
+.. code-block:: jinja
+
+ {% for partition in partitions %}
+ {% if partition.manifest.services %}
+ {% for service in partition.manifest.services %}
+ {do something for the service}
+ {% endfor %}
+ {% endif %}
+ {% endfor %}
+
+--------------
+
+*Copyright (c) 2019-2021, Arm Limited. All rights reserved.*
diff --git a/docs/design_docs/tfm_cooperative_scheduling_rules.rst b/docs/design_docs/tfm_cooperative_scheduling_rules.rst
new file mode 100644
index 0000000..37270da
--- /dev/null
+++ b/docs/design_docs/tfm_cooperative_scheduling_rules.rst
@@ -0,0 +1,210 @@
+############################
+Cooperative Scheduling Rules
+############################
+
+:Author: Ashutosh Singh
+:Organization: Arm Limited
+:Contact: Ashutosh Singh <ashutosh.singh@arm.com>
+
+TF-M Scheduler - Rules
+======================
+
+On ArmV8-M CPUs, NSPE and SPE share the same physical processing element(PE). A
+TF-M enabled system need to be able to handle asynchronous events (interrupts)
+regardless of current security state of the PE, and that may lead to scheduling
+decisions. This introduces significant complexity into TF-M. To keep the
+integrity of (NSPE and SPE) schedulers and call paths between NSPE and SPE,
+following set of rules are imposed on the TF-M scheduler design.
+
+Objectives and Requirements
+===========================
+
+1. Decoupling of scheduling decisions between NSPE and SPE
+2. Efficient interrupt handling by SPE as well as NSPE
+3. Reduce critical sections on the secure side to not block interrupts
+ unnecessarily
+4. Scalability to allow simplification/reduction of overheads to scale down the
+ design for constrained devices
+5. Reduce impact on NSPE software design
+
+ a. NSPE interrupt handling implementation should be independent
+ b. Impact on the NSPE scheduler should be minimal
+ c. No assumptions should be made about NSPE's scheduling capabilities
+
+Scheduler Rules for context switching between SPE and NSPE
+==========================================================
+
+To allow coherent cooperative scheduling, following set of rules are imposed on
+security state changes.
+The switching between SPE and NSPE can be triggered in multiple ways.
+
+`Involuntary security state switch`; when the software has no control over the
+switch:
+
+- A NSPE interrupt take control into NSPE from SPE
+- A SPE interrupt takes control into SPE from NSPE
+
+`Voluntary security state switch`; when software programmatically makes the
+switch:
+
+- A NSPE exception handler returns from NSPE to pre-empted SPE context
+- A SPE exception handler returns from SPE to pre-empted NSPE context
+- NSPE makes a function call into SPE
+- SPE returns a call from NSPE
+- SPE makes a function call into NSPE (not covered in current design)
+- NSPE returns a call from SPE (not covered in current design)
+
+In order to maintain the call stack integrity across NSPE and SPE, following
+rules are imposed on all security state switches.
+
+Rules for NSPE Exception handling
+---------------------------------
+
+1. **The NSPE exception handler is allowed to trigger a NSPE context switch**
+ **(regardless of security state of the preempted context.**
+
+This is expected behaviour of any (RT)OS.
+
+2. **The NSPE scheduler must eventually 'restore' the preempted (by**
+ **exception) context.**
+
+This is expected behaviour of any (RT)OS.
+
+3. **If NSPE exception results in a NSPE context switch, SPM must be informed**
+ **of the scheduling decision; this must be done BEFORE the execution of**
+ **newly scheduled-in context.**
+
+This is to ensures integrity of the call stack when SPE is ready to return a
+previous function call from NSPE.
+
+Rules for SPE Exception handling
+--------------------------------
+
+1. **All of the SPE interrupts must have higher priority than NSPE interrupts**
+
+This is rule is primarily for simplifying the SPM design.
+
+2. **The SPE interrupt handler is allowed to trigger a SPE context switch**
+ **(regardless of security state of the pre-empted context)**
+
+If the SPE context targeted by the interrupt is not same as current SPE context,
+the SPM may choose to switch the current running SPE context based on priority.
+
+3. **SPE scheduler must treat pre-empted context as one of the SPE contexts**
+
+ a. If the pre-empted SPE context is SP1, the TCB for SP1 should be used for
+ saving the context. i.e. the context of SP1 should be saved before
+ scheduling anything other secure partition.
+ b. If SP1 was pre-empted by a NSPE interrupt, and subsequent NSPE execution is
+ pre-empted by SPE exception (before NSPE scheduling decision is communicated
+ back to SPM) -- SP1 TCB must be used for saving the context
+ In this case SPM is not yet aware of the NSPE context switch, from SPM's
+ standpoint SP1 is still executing, so SPM assumes that the preempted context
+ is SP1.
+ c. If SP1 was pre-empted by a NSPE interrupt, and subsequent NSPE execution is
+ pre-empted by SPE exception `after` NSPE scheduling decision is
+ communicated back to SPM) - a TCB dedicated to NSPE should be used for
+ saving the context.
+
+ When NSPE scheduler communicates the scheduling decision to SPM, SPM must save
+ the SP1 context, if a SPE interrupt preempts the currently running NSPE context,
+ SPM should save the context to a dedicated NSPE TCB.
+
+ d. The SPE scheduler must eventually 'restore' the pre-empted context.
+ This is an expected behaviour of any scheduler.
+
+4. **All of the interrupts belonging to a partition must have same priority.**
+
+This serializes ISR execution targeted for same partition.
+
+5. **In case of nested interrupts, all of the ISRs must run to finish before**
+ **any service code is allowed to run**
+
+This is an expected behaviour of any scheduler.
+
+6. **If the previously preempted context was a NSPE ISR context, SPE ISR**
+ **handler must return to preempted NSPE context.**
+
+This is an expected behaviour of any scheduler to return to preempted context.
+
+Rules for NSPE to SPM function call (and NSPE scheduler)
+--------------------------------------------------------
+
+1. Current NSPE context must have been communicated to SPM, otherwise SPM cannot
+ guarantee NSPE function calling stack integrity.
+
+Rules for Function Return from SPE to NSPE with result
+------------------------------------------------------
+
+1. **The result available on SPE side are for currently active NSPE context.**
+
+To maintain call stack integrity, if SPE is ready to return to NSPE, it can do
+function return only if the SPE return path corresponds to currently active NSPE
+context.
+
+2. **Last entry into secure world happened programmatically (Voluntary**
+ **security state switch into SPE)**
+
+i.e. control is voluntarily given back by NSPE, either through a function call,
+or a context restore via 'return to SPE from NSPE'. As opposed to a SPE
+interrupt bringing back the execution into SPE.
+
+3. **The current NSPE call stack has not already been returned with SPM_IDLE.**
+
+This rule applies if following optional feature is enabled.
+
+Rules for Return from SPE to NSPE with SPM_IDLE
+-----------------------------------------------
+
+This is optional part of the design as it introduces significant complexity on
+both sides of the security boundary.
+It allows yielding of the CPU to NSPE when SPE has not CPU execution to do but
+it has not yet finished the previous request(s) from NSPE; i.e. SPE is waiting
+on arrival of a SPE interrupt.
+
+1. **Last entry into secure world happens programmatically (Voluntary**
+ **security context switch into SPE)**
+
+i.e. control is voluntarily given back by NSPE, either through a function call,
+or a context restore via 'return to SPE from NSPE'. As opposed to a SPE
+interrupt bringing back the execution into SPE.
+
+2. **The result for the currently active NSPE entity is not yet available,**
+ **the called service is waiting (on interrupt/event).**
+
+SPE request corresponding to currently active NSPE caller is not yet completed
+and is waiting on an ISR.
+
+3. **The current NSPE call stack has not already been returned with SPM_IDLE.**
+
+Rules for NSPE pend irq based return from SPE to NSPE
+-----------------------------------------------------
+
+This is optional part of the design as it introduces significant complexity on
+both sides. This works in conjunction with [Rules for Return from SPE to NSPE
+with SPM_IDLE](#rules-for-return-from-spe-to-nspe-with-spm_idle).
+In this scenario, when SPE is ready with result for a previous call from NSPE,
+it raises a pended IRQ to NSPE instead of returning the function call path.
+
+1. **The SPE has finished a NSPE request.**
+
+2. **The corresponding NSPE context has already been returned with SPM_IDLE.**
+
+Rules for ISR pre-emption
+-------------------------
+
+1. **A higher priority NSPE interrupt is allowed to preempt a lower priority**
+ **NSPE ISR**
+
+2. **A higher priority SPE interrupt is allowed to preempt a lower priority**
+ **SPE ISR**
+
+3. **A SPE interrupt is allowed to preempt NSPE ISR**
+
+4. **A NSPE interrupt is not allowed to preempt SPE ISR**
+
+5. **All interrupts belonging to a service must have same priority**
+
+--------------
+
+*Copyright (c) 2019, Arm Limited. All rights reserved.*
diff --git a/docs/design_docs/tfm_crypto_design.rst b/docs/design_docs/tfm_crypto_design.rst
new file mode 100644
index 0000000..cf2cbe0
--- /dev/null
+++ b/docs/design_docs/tfm_crypto_design.rst
@@ -0,0 +1,192 @@
+Crypto Service design
+=====================
+
+:Author: Antonio de Angelis
+:Organization: Arm Limited
+:Contact: Antonio de Angelis <antonio.deangelis@arm.com>
+
+.. contents:: Table of Contents
+
+Abstract
+--------
+
+This document describes the design of the TF-M Cryptographic Secure Service
+(in short, TF-M Crypto service).
+
+Introduction
+------------
+
+The TF-M Crypto service provides an implementation of the PSA Crypto API
+in a PSA RoT secure partition in TF-M. It is based on Mbed Crypto, which
+is a reference implementation of the PSA Crypto API. For more details on
+the PSA Crypto API or the Mbed Crypto implementation, please refer
+directly to the ``mbed-crypto`` GitHub repository [1]_ .
+
+The service can be used by other services running in the SPE, or by
+applications running in the NSPE, to provide cryptographic
+functionalities.
+
+Components
+----------
+
+The TF-M Crypto service is implemented by a number of different software
+components, which are listed below:
+
+.. table:: Components table
+ :widths: auto
+
+ +-----------------------------+---------------------------------------------------------------+----------------------------------------------------------------------+
+ | **Component name** | **Description** | **Location** |
+ +=============================+===============================================================+======================================================================+
+ | Client API interface | This module exports the client API of PSA Crypto to the users.| ``./interface/src/tfm_crypto_api.c`` |
+ +-----------------------------+---------------------------------------------------------------+----------------------------------------------------------------------+
+ | Mbed Crypto | The Mbed Crypto library is used in the service as a | Needed as dependency at the same level of the TF-M folder, |
+ | | cryptographic library exposing the PSA Crypto API interface. | i.e. ``../mbed-crypto`` |
+ +-----------------------------+---------------------------------------------------------------+----------------------------------------------------------------------+
+ | Init module | This module handles the initialisation of the service objects | ``./secure_fw/partitions/crypto/crypto_init.c`` |
+ | | during TF-M boot and provides the infrastructure to service | |
+ | | requests when TF-M is built for IPC model. | |
+ | | The dispatching mechanism of IPC requests is based on a look | |
+ | | up table of function pointers. | |
+ | | This design allows for better scalability and support of a | |
+ | | higher number of Secure functions with minimal overhead and | |
+ | | duplication of code. | |
+ +-----------------------------+---------------------------------------------------------------+----------------------------------------------------------------------+
+ | Alloc module | This module handles the allocation of contexts for multipart | ``./secure_fw/partitions/crypto/crypto_alloc.c`` |
+ | | operations in the Secure world. | |
+ +-----------------------------+---------------------------------------------------------------+----------------------------------------------------------------------+
+ | Service modules | These modules (AEAD, Asymmetric, Cipher, Key Deriv, Hash, Key,| ``./secure_fw/partitions/crypto/crypto_aead.c`` |
+ | | MAC) represent a thin layer which is in charge of servicing | ``./secure_fw/partitions/crypto/crypto_asymmetric.c`` |
+ | | the calls from the SPE/NSPE client API interfaces. | ``./secure_fw/partitions/crypto/crypto_cipher.c`` |
+ | | They provide parameter sanitation and context retrieval for | ``./secure_fw/partitions/crypto/crypto_key_derivation.c`` |
+ | | multipart operations, and dispatching to the corresponding | ``./secure_fw/partitions/crypto/crypto_hash.c`` |
+ | | library function exposed by Mbed Crypto for the desired | ``./secure_fw/partitions/crypto/crypto_key.c`` |
+ | | functionality. | ``./secure_fw/partitions/crypto/crypto_mac.c`` |
+ | | | ''./secure_fw/partitions/crypto/crypto_key_management.c'' |
+ +-----------------------------+---------------------------------------------------------------+----------------------------------------------------------------------+
+ | Manifest | The manifest file is a description of the service components. | ``./secure_fw/partitions/crypto/manifest.yaml`` |
+ +-----------------------------+---------------------------------------------------------------+----------------------------------------------------------------------+
+ | CMake files and headers | The CMake files are used by the TF-M CMake build system to | ``./secure_fw/partitions/crypto/CMakeLists.inc`` |
+ | | build the service as part of the Secure FW build. The service | ``./secure_fw/partitions/crypto/CMakeLists.txt`` |
+ | | is built as a static library (``tfm_crypto.a``). | ``./interface/include/tfm_crypto_defs.h`` |
+ | | The build system allows to build as well the Mbed Crypto | ``./secure_fw/partitions/crypto/tfm_crypto_api.h`` |
+ | | library as part of the Secure FW build process and archive it | ``./secure_fw/partitions/crypto/tfm_crypto_signal.h`` |
+ | | with the static library of the Crypto service. | ``./secure_fw/partitions/crypto/spe_crypto.h`` |
+ | | The headers are used to export the public prototypes of the | |
+ | | functions in the Service modules ``tfm_crypto_api.h``, and | |
+ | | to provide the necessary defines (i.e. ``TFM_CRYPTO_SIG``). | |
+ | | In particular ``TFM_CRYPTO_SIG`` identifies the signal on | |
+ | | which the service handler waits for requests when the service | |
+ | | is built for IPC model. | |
+ | | The header available in the interface, ``tfm_crypto_defs.h`` | |
+ | | , contains types and defines for building the NSPE interface | |
+ | | as part of a Non-Secure application. | |
+ | | Finally, the ``crypto_spe.h`` header is used during the | |
+ | | build of the Mbed Crypto library, when the Mbed Crypto config | |
+ | | option ``MBEDTLS_PSA_CRYPTO_SPM`` is defined, to add a | |
+ | | custom prefix to the PSA API symbols so that duplication of | |
+ | | symbol names is avoided. | |
+ | | The prefix used for the PSA API symbols of the Mbed Crypto | |
+ | | library is chosen to be ``mbedcrypto__``. | |
+ +-----------------------------+---------------------------------------------------------------+----------------------------------------------------------------------+
+ | Documentation | The integration guide contains the description of the TF-M | ``./user_guides/services/tfm_crypto_integration_guide.rst`` |
+ | | Crypto service modules and interfaces. | |
+ +-----------------------------+---------------------------------------------------------------+----------------------------------------------------------------------+
+
+The interaction between the different components is described by the
+following block diagram:
+
+.. figure:: media/tfm_crypto_design.png
+
+ Block diagram of the different components of the TF-M Crypto service. A
+ dotted line is used to indicate the interaction with a library.
+
+Note: in IPC model, the interaction between components is slightly
+different, as the Service modules are not called directly through the
+TF-M Secure Partition Manager but through the IPC handler which resides
+in the Init module.
+
+Service API description
+-----------------------
+
+Most of the APIs exported by the TF-M Crypto service (i.e. from the Service
+modules) have a direct correspondence with the PSA Crypto API. The Alloc and
+Init modules instead export some APIs which are specific to the TF-M Crypto
+service, and are available only to the Service modules or the SPM. For a
+detailed description of the prototypes please refer to the ``tfm_crypto_api.h``
+header.
+
+.. table:: Init and Alloc modules APIs
+ :widths: auto
+
+ +--------------------------------+--------------+-----------------+------------------------------------------------------+
+ | **Function** | **Module** | **Caller** | **Scope** |
+ +================================+==============+=================+======================================================+
+ | tfm_crypto_init() | Init | SPM | Called during TF-M boot for initialisation. In IPC |
+ | | | | model, it calls the IPC service request handler. |
+ +--------------------------------+--------------+-----------------+------------------------------------------------------+
+ | tfm_crypto_init_alloc() | Alloc | Init | Called by tfm_crypto_init(), it initialises the |
+ | | | | concurrent operation contexts storage area. |
+ +--------------------------------+--------------+-----------------+------------------------------------------------------+
+ | tfm_crypto_operation_alloc() | Alloc | Service modules | It allocates a new operation context for a multipart |
+ | | | | operation. It returns an handle to the allocated |
+ | | | | context in secure memory. |
+ +--------------------------------+--------------+-----------------+------------------------------------------------------+
+ | tfm_crypto_operation_lookup() | Alloc | Service modules | It retrieves a previously allocated operation context|
+ | | | | of a multipart operation, based on the handle given |
+ | | | | as input. |
+ +--------------------------------+--------------+-----------------+------------------------------------------------------+
+ | tfm_crypto_operation_release() | Alloc | Service modules | It releases a previously allocated operation context |
+ | | | | of a multipart operation, based on the handle given |
+ | | | | as input. |
+ +--------------------------------+--------------+-----------------+------------------------------------------------------+
+
+Configuration parameters
+------------------------
+
+The TF-M Crypto service exposes some configuration parameters to tailor
+the service configuration in terms of supported functionalities and
+hence FLASH/RAM size to meet the requirements of different platforms and
+use cases. These parameters can be provided via CMake parameters during
+the CMake configuration step and as a configuration header to allow the
+configuration of the Mbed Crypto library.
+
+.. table:: Configuration parameters table
+ :widths: auto
+
+ +------------------------------------+---------------------------+----------------------------------------------------------------+-----------------------------------------+----------------------------------------------------------------------------+
+ | **Parameter** | **Type** | **Description** | **Scope** | **Default** |
+ +====================================+===========================+================================================================+=========================================+============================================================================+
+ | ``CRYPTO_ENGINE_BUF_SIZE`` | CMake build | Buffer used by Mbed Crypto for its own allocations at runtime. | To be configured based on the desired | 8096 (bytes) |
+ | | configuration parameter | This is a buffer allocated in static memory. | use case and application requirements. | |
+ +------------------------------------+---------------------------+----------------------------------------------------------------+-----------------------------------------+----------------------------------------------------------------------------+
+ | ``CRYPTO_CONC_OPER_NUM`` | CMake build | This parameter defines the maximum number of possible | To be configured based on the desire | 8 |
+ | | configuration parameter | concurrent operation contexts (cipher, MAC, hash and key deriv)| use case and platform requirements. | |
+ | | | for multi-part operations, that can be allocated simultaneously| | |
+ | | | at any time. | | |
+ +------------------------------------+---------------------------+----------------------------------------------------------------+-----------------------------------------+----------------------------------------------------------------------------+
+ | ``CRYPTO_IOVEC_BUFFER_SIZE`` | CMake build | This parameter applies only to IPC model builds. In IPC model, | To be configured based on the desired | 5120 (bytes) |
+ | | configuration parameter | during a Service call, input and outputs are allocated | use case and application requirements. | |
+ | | | temporarily in an internal scratch buffer whose size is | | |
+ | | | determined by this parameter. | | |
+ +------------------------------------+---------------------------+----------------------------------------------------------------+-----------------------------------------+----------------------------------------------------------------------------+
+ | ``MBEDTLS_CONFIG_FILE`` | Configuration header | The Mbed Crypto library can be configured to support different | To be configured based on the | ``./lib/ext/mbedcrypto/mbedcrypto_config/tfm_mbedcrypto_config_default.h`` |
+ | | | algorithms through the usage of a a configuration header file | application and platform requirements. | |
+ | | | at build time. This allows for tailoring FLASH/RAM requirements| | |
+ | | | for different platforms and use cases. | | |
+ +------------------------------------+---------------------------+----------------------------------------------------------------+-----------------------------------------+----------------------------------------------------------------------------+
+ | ``MBEDTLS_PSA_CRYPTO_CONFIG_FILE`` | Configuration header | This header file specifies which cryptographic mechanisms are | To be configured based on the | ``./lib/ext/mbedcrypto/mbedcrypto_config/crypto_config_default.h`` |
+ | | | available through the PSA API when #MBEDTLS_PSA_CRYPTO_CONFIG | application and platform requirements. | |
+ | | | is enabled, and is not used when #MBEDTLS_PSA_CRYPTO_CONFIG is | | |
+ | | | disabled. | | |
+ +------------------------------------+---------------------------+----------------------------------------------------------------+-----------------------------------------+----------------------------------------------------------------------------+
+
+References
+----------
+
+.. [1] ``mbed-crypto`` repository which holds the PSA Crypto API specification and the Mbed Crypto reference implementation: \ https://github.com/Mbed-TLS
+
+
+--------------
+
+*Copyright (c) 2019-2022, Arm Limited. All rights reserved.*
diff --git a/docs/design_docs/tfm_fwu_service.rst b/docs/design_docs/tfm_fwu_service.rst
new file mode 100644
index 0000000..ab3c294
--- /dev/null
+++ b/docs/design_docs/tfm_fwu_service.rst
@@ -0,0 +1,368 @@
+#######################
+Firmware Update Service
+#######################
+
+:Author: Sherry Zhang
+:Organization: Arm Limited
+:Contact: Sherry Zhang <Sherry.Zhang2@arm.com>
+
+.. contents:: Table of Contents
+ :depth: 3
+
+***************************************
+Introduction of Firmware Update service
+***************************************
+The Firmware Update(FWU) service provides the functionality of updating firmware
+images. It provides a standard interface for updating firmware and it is
+platform independent. TF-M defines a shim layer to support cooperation between
+bootloader and FWU service.
+
+This partition supports the following features:
+
+- Query the firmware store information.
+- Image preparation: prepare a new firmware image in the component's firmware store.
+- Image installation: install prepared firmware images on all components that have been prepared for installation.
+- Image trial: manage a trial of new firmware images atomically on all components that are in TRIAL state.
+
+A typical flow through the component states is shown below [1]_.
+
+.. figure:: media/fwu-states.svg
+ :scale: 65 %
+ :align: center
+ :name: The component state model transitions.
+
+**********
+Components
+**********
+The structure of the TF-M Firmware Update service is listed below:
+ +-----------------------------+---------------------------------------------------------------+---------------------------------------------------------------------------------------+
+ | **Component name** | **Description** | **Location** |
+ +=============================+===============================================================+=======================================================================================+
+ | Client API interface | This module exports the client API of PSA Firmware Update to | ``./interface/src/tfm_fwu_api.c`` |
+ | | the users. | |
+ +-----------------------------+---------------------------------------------------------------+---------------------------------------------------------------------------------------+
+ | Manifest | The manifest file is a description of the service components. | ``./secure_fw/partitions/firmware_update/tfm_firmware_update.yaml`` |
+ +-----------------------------+---------------------------------------------------------------+---------------------------------------------------------------------------------------+
+ | NSPE client API interface | This module exports the client API of PSA Firmware Update to | ``./interface/src/tfm_fwu_api.c`` |
+ | | the NSPE(i.e. to the applications). | |
+ +-----------------------------+---------------------------------------------------------------+---------------------------------------------------------------------------------------+
+ | IPC request handlers | This module handles all the secure requests in IPC model. | ``./secure_fw/partitions/firmware_update/tfm_fwu_req_mngr.c`` |
+ | | It maitains the image state context and calls the image ID | |
+ | | converter to achieve the firmware update functionalities. | |
+ +-----------------------------+---------------------------------------------------------------+---------------------------------------------------------------------------------------+
+ | Shim layer between FWU and | This module provides the APIs with the functionality of | ``./secure_fw/partitions/firmware_update/bootloader/tfm_bootloader_fwu_abstraction.h``|
+ | bootloader | operating the bootloader to cooperate with the Firmware Update| |
+ | | service | |
+ +-----------------------------+---------------------------------------------------------------+---------------------------------------------------------------------------------------+
+ | Shim layer example based on | This module is the implementation of the shim layer between | ``./secure_fw/partitions/firmware_update/bootloader/mcuboot/tfm_mcuboot_fwu.c`` |
+ | MCUboot | FWU and bootloader based on MCUboot. | |
+ | | | |
+ +-----------------------------+---------------------------------------------------------------+---------------------------------------------------------------------------------------+
+
+***********************
+Service API description
+***********************
+This service follows the PSA Firmware Update API spec of version 1.0 [1]_. Please refer to
+Firmware Update spec for the detailed description.
+
+*************************************
+Shim Layer between FWU and bootloader
+*************************************
+The firmware update operations are achieved by calling the shim layer APIs
+between bootloader and FWU.
+
+Shim layer introduction
+=======================
+This shim layer provides the APIs with the functionality of operating the
+bootloader to cooperate with the Firmware Update service. This shim layer
+is decoupled from bootloader implementation. Users can specify a specific
+bootloader by setting ``TFM_FWU_BOOTLOADER_LIB`` build configuration and
+adding the specific build scripts into that file. By default, the MCUboot
+is chosen as the bootloader.
+
+Interfaces of the shim Layer
+============================
+
+fwu_bootloader_init(function)
+-----------------------------
+Prototype
+^^^^^^^^^
+.. code-block:: c
+
+ psa_status_t fwu_bootloader_init(void);
+
+Description
+^^^^^^^^^^^
+Bootloader related initialization for the firmware update. It reads
+some necessary shared data from the memory if needed. It initializes
+the flash drivers defined in FLASH_DRIVER_LIST. Platform can define
+FLASH_DRIVER_LIST in flash_layout.h to overload the default driver list.
+
+Parameters
+^^^^^^^^^^
+ N/A
+
+fwu_bootloader_staging_area_init(function)
+------------------------------------------
+**Prototype**
+
+.. code-block:: c
+
+ psa_status_t fwu_bootloader_staging_area_init(psa_fwu_component_t component,
+ const void *manifest,
+ size_t manifest_size);
+
+**Description**
+
+The component is in READY state. Prepare the staging area of the component for image download.
+For example, initialize the staging area, open the flash area, and so on.
+
+**Parameters**
+
+- ``component``: The identifier of the target component in bootloader.
+- ``manifest``: A pointer to a buffer containing a detached manifest for the update.
+ If the manifest is bundled with the firmware image, manifest must be NULL.
+- ``manifest_size``: Size of the manifest buffer in bytes.
+
+fwu_bootloader_load_image(function)
+-----------------------------------
+**Prototype**
+
+.. code-block:: c
+
+ psa_status_t fwu_bootloader_load_image(psa_fwu_component_t component,
+ size_t image_offset,
+ const void *block,
+ size_t block_size);
+
+**Description**
+
+Load the image into the target component.
+
+**Parameters**
+
+- ``component``: The identifier of the target component in bootloader.
+- ``image_offset``: The offset of the image being passed into block, in bytes.
+- ``block``: A buffer containing a block of image data. This might be a complete image or a subset.
+- ``block_size``: Size of block.
+
+fwu_bootloader_install_image(function)
+---------------------------------------------
+**Prototype**
+
+.. code-block:: c
+
+ psa_status_t fwu_bootloader_install_image(psa_fwu_component_t *candidates,
+ uint8_t number);
+
+**Description**
+
+Check the authenticity and integrity of the image. If a reboot is required to
+complete the check, then mark this image as a candidate so that the next time
+bootloader runs it will take this image as a candidate one to bootup. Return
+the error code PSA_SUCCESS_REBOOT.
+
+**Parameters**
+
+- ``candidates``: A list of components in CANDIDATE state.
+- ``number``: Number of components in CANDIDATE state.
+
+fwu_bootloader_mark_image_accepted(function)
+--------------------------------------------
+**Prototype**
+
+.. code-block:: c
+
+ psa_status_t fwu_bootloader_mark_image_accepted(const psa_fwu_component_t *trials,
+ uint8_t number);
+
+**Description**
+
+Call this API to mark the TRIAL(running) image in component as confirmed to avoid
+revert when next time bootup. Usually, this API is called after the running
+images have been verified as valid.
+
+**Parameters**
+
+- ``trials``: A list of components in TRIAL state.
+- ``number``: Number of components in TRIAL state.
+
+fwu_bootloader_reject_staged_image(function)
+--------------------------------------------
+**Prototype**
+
+.. code-block:: c
+
+ psa_status_t fwu_bootloader_reject_staged_image(psa_fwu_component_t component);
+
+**Description**
+
+The component is in STAGED state. Call this API to Uninstall the staged image in the
+component so that this image will not be treated as a candidate next time bootup.
+
+**Parameters**
+
+- ``component``: The identifier of the target component in bootloader.
+
+fwu_bootloader_reject_trial_image(function)
+--------------------------------------------
+**Prototype**
+
+.. code-block:: c
+
+ psa_status_t fwu_bootloader_reject_trial_image(psa_fwu_component_t component);
+
+**Description**
+
+The component is in TRIAL state. Mark the running image in the component as rejected.
+
+**Parameters**
+
+- ``component``: The identifier of the target component in bootloader.
+
+fwu_bootloader_clean_component(function)
+----------------------------------------
+**Prototype**
+
+.. code-block:: c
+
+ psa_status_t fwu_bootloader_clean_component(psa_fwu_component_t component);
+
+**Description**
+
+The component is in FAILED or UPDATED state. Clean the staging area of the component.
+
+**Parameters**
+
+- ``component``: The identifier of the target component in bootloader.
+
+fwu_bootloader_get_image_info(function)
+---------------------------------------
+**Prototype**
+
+.. code-block:: c
+
+ psa_status_t fwu_bootloader_get_image_info(psa_fwu_component_t component,
+ bool query_state,
+ bool query_impl_info,
+ psa_fwu_component_info_t *info);
+
+**Description**
+
+Get the image information of the given bootloader_image_id in the staging area
+or the running area.
+
+**Parameters**
+
+ - ``component``: The identifier of the target component in bootloader.
+ - ``query_state``: Whether query the 'state' field of psa_fwu_component_info_t.
+ - ``query_impl_info``: Whether Query 'impl' field of psa_fwu_component_info_t.
+ - ``info``: Buffer containing return the component information.
+
+******************************************
+Additional shared data between BL2 and SPE
+******************************************
+An additional TLV area "image version" is added into the shared memory between
+BL2 and TF-M. So that the firmware update partition can get the image version.
+Even though the image version information is also included in the ``BOOT RECORD``
+TLV area which is encoded by CBOR, adding a dedicated ``image version`` TLV area
+is preferred to avoid involving the CBOR encoder which can increase the code
+size. The FWU partition will read the shared data at the partition
+initialization.
+
+*********************************************
+Build configurations related to FWU partition
+*********************************************
+- ``TFM_PARTITION_FIRMWARE_UPDATE`` Controls whether FWU partition is enabled or not.
+- ``TFM_FWU_BOOTLOADER_LIB`` Bootloader configure file for FWU partition.
+- ``TFM_CONFIG_FWU_MAX_WRITE_SIZE`` The maximum permitted size for block in psa_fwu_write, in bytes.
+- ``TFM_FWU_BUF_SIZE`` Size of the FWU internal data transfer buffer (defaults to
+ TFM_CONFIG_FWU_MAX_WRITE_SIZE if not set).
+- ``FWU_STACK_SIZE`` The stack size of FWU Partition.
+- ``FWU_DEVICE_CONFIG_FILE`` The device configuration file for FWU partition. The default value is
+ the configuration file generated for MCUboot. The following macros should be defined in the
+ configuration file:
+
+ - ``FWU_COMPONENT_NUMBER`` The number of components on the device.
+
+ .. Note::
+
+ In this design, component ID ranges from 0 to ``FWU_COMPONENT_NUMBER`` - 1.
+
+ - ``FWU_SUPPORT_TRIAL_STATE`` Whether TRIAL component state is supported.
+- ``TEST_NS_FWU`` FWU nonsecure tests switch.
+- ``TEST_S_FWU`` FWU secure tests switch.
+
+ .. Note::
+
+ The running image which supports revert mechanism should be confirmed before initiating a
+ firmware update process. For example, if the running image is built with
+ ``-DMCUBOOT_UPGRADE_STRATEGY=SWAP_USING_MOVE``, the image should be confirmed either by
+ adding ``-DMCUBOOT_CONFIRM_IMAGE=ON`` build option or by calling ``psa_fwu_accept()`` API
+ before initiating a firmware update process. Otherwise, ``PSA_ERROR_BAD_STATE`` will be
+ returned by ``psa_fwu_start()``.
+
+*************************************
+Limitations of current implementation
+*************************************
+Currently, the MCUboot based implementation does not record image update results like failure or
+success. And FWU partition does not detect failure errors in bootloader installation. If an image
+installation fails in the bootloader and the old image still runs after reboot, ``PSA_FWU_READY``
+state will be returned by ``psa_fwu_query()`` after reboot.
+
+Currently, image download recovery after a reboot is not supported. If a reboot happens in image
+preparation, the downloaded image data will be ignored after the reboot.
+
+***********************************
+Benefits Analysis on this Partition
+***********************************
+
+Implement the FWU functionality in the non-secure side
+======================================================
+The APIs listed in PSA Firmware Update API spec [1]_ can also be implemented in
+the non-secure side.
+
+Pros and Cons for implementing FWU APIs in secure side
+======================================================
+
+Pros
+----
+- It protects the image in the passive or staging area from being tampered with
+ by the NSPE. Otherwise, a malicious actor from NSPE can tamper the image
+ stored in the non-secure area to break image update.
+
+- It protects secure image information from disclosure. In some cases, the
+ non-secure side shall not be permitted to get secure image information.
+
+- It protects the active image from being manipulated by NSPE. Some bootloader
+ supports testing the image. After the image is successfully installed and
+ starts to run, the user should set the image as permanent image if the image
+ passes the test. To achieve this, the area of the active image needs to be
+ accessed. In this case, implementing FWU service in SPE can prevent NSPE
+ from manipulating the active image area.
+
+- On some devices, such as the Arm Musca-B1 board, the passive or staging area
+ is restricted as secure access only. In this case, the FWU partition should
+ be implemented in the secure side.
+
+Cons
+----
+- It increases the image size of the secure image.
+- It increases the execution latency and footprint. Compared to implementing
+ FWU in NSPE directly, calling the Firmware Update APIs which are implemented
+ in the secure side increases the execution latency and footprint.
+- It can increase the attack surface of the secure runtime.
+
+Users can decide whether to call the FWU service in TF-M directly or implement
+the Firmware Update APIs in the non-secure side based on the pros and cons
+analysis above.
+
+*********
+Reference
+*********
+
+.. [1] `PSA Firwmare Update API <https://arm-software.github.io/psa-api/fwu/1.0/>`_
+
+--------------
+
+*Copyright (c) 2021-2022, Arm Limited. All rights reserved.*
diff --git a/docs/design_docs/tfm_its_512_flash.rst b/docs/design_docs/tfm_its_512_flash.rst
new file mode 100644
index 0000000..205375a
--- /dev/null
+++ b/docs/design_docs/tfm_its_512_flash.rst
@@ -0,0 +1,103 @@
+###############################################################
+Add support for block-aligned flash in Internal Trusted Storage
+###############################################################
+
+:Author: Minos Galanakis
+:Organization: Arm Limited
+:Contact: Minos Galanakis <minos.galanakis@arm.com>
+
+Abstract
+========
+
+The proposal is describing a mechanism to enable the use of larger flash
+devices, imposing a requirement for word-aligned full-block program operations,
+in Trusted Firmware-M.
+
+
+Requirements
+============
+
+- Allow page-aligned writes for up to 512 Bytes per page.
+- Guarantee data integrity and power-failure reliability.
+- Do not alter existing supported platform behaviour.
+
+Current implementation
+======================
+
+In the current ITS filesystem design, each filesystem create or write operation
+requires two flash blocks to be updated: first the data block and then the
+metadata block. Buffering is avoided as much as possible to reduce
+RAM requirements.
+
+However, if the ITS_FLASH_PROGRAM_UNIT is 512 Bytes then the data will have to
+stored in a temporary memory location in order to be able to write
+that much data in one-shot.
+
+Proposed implementation overview
+================================
+
+1. A new block-sized static buffer should be added to its_flash.c when
+ ``ITS_FLASH_PROGRAM_UNIT`` is larger than currently supported.
+2. Methods calling the flash API such as ``its_flash_write()`` or
+ ``its_flash_block_to_block_move()`` will populate the buffer instead of
+ directly programming the flash.
+3. A new method ``its_flash_flush()``, should be provided in order to flush
+ the block buffer to the device.
+4. ``its_flash_flush()`` should be called twice: Once after a data block
+ update and once more after the metadata block update is completed.
+5. The proposed design should require that the data block update is always
+ completed before the metadata block update starts
+6. Writes to the block buffer should be atomic, and guarded against corruption
+ by data from different blocks.
+
+Considerations
+==============
+
+- The proposed implementation will increase the RAM usage of ITS by the size
+ of a block, only for platforms which require block-aligned writes.
+- Currently power-failure is detected by software by incrementing an 8-bit
+ metadata header field (``swap_count``), as the last written byte. When the
+ proposed block-buffer is used, the block is programmed in one-shot and the
+ order the bytes are written on the physical device, is hardware dependent.
+- A set of guarantees are required by the supported flash ECC devices.
+ The device's flash APIs should provide a mechanism to capture and raise
+ incomplete program operations, as well as write bytes in a sequential order.
+
+For example, if a board powers down through a 512 page program operation, the
+next read operation should return an error rather than read invalid data.
+
+Functional flow diagram
+=======================
+
+The logic of the proposal is described in the following diagram
+
+.. code-block:: rst
+
+ |----------------------|
+ | data write() |
+ |----------------------|
+ | | |------------------------------|
+ |-> | its_flash_write | ---> | data[] -> its_block_buffer[] |
+ | | | |------------------------------|
+ | |----------------------|
+ | | | |------------------------------------|
+ | | its_flash_flush | ---> | its_block_buffer[] -> flash dev IO |
+ | | | |------------------------------------|
+ | |----------------------|
+ | |
+ | ------------------------------------
+ | |
+ | V
+ | |----------------------| |--------------------------|
+ | | data write() complete| | metadata write() complete|
+ | |----------------------| |--------------------------|
+ | <-| Metadata write() | |
+ |----------------------| |
+ V
+ |--------------------------|
+ | Operation Complete |
+ |--------------------------|
+
+--------------
+
+*Copyright (c) 2019-2020, Arm Limited. All rights reserved.*
diff --git a/docs/design_docs/tfm_its_service.rst b/docs/design_docs/tfm_its_service.rst
new file mode 100644
index 0000000..06c2ceb
--- /dev/null
+++ b/docs/design_docs/tfm_its_service.rst
@@ -0,0 +1,280 @@
+======================================
+Internal Trusted Storage (ITS) Service
+======================================
+
+:Author: Jamie Fox
+:Organization: Arm Limited
+:Contact: Jamie Fox <jamie.fox@arm.com>
+
+PSA Internal Trusted Storage
+============================
+PSA Internal Trusted Storage (ITS) is a PSA RoT Service for storing the most
+security-critical device data (e.g. cryptographic keys) in internal storage,
+which is trusted to provide data confidentiality and authenticity. This
+contrasts with PSA Protected Storage, which is an Application RoT service that
+allows larger data sets to be stored securely in external flash, with the option
+for encryption, authentication and rollback protection to protect the
+data-at-rest.
+
+Current TF-M Secure Storage
+===========================
+Currently, the TF-M Secure Storage service implements PSA Protected Storage
+version 1.0-beta2. There is not yet an implementation of PSA Internal Trusted
+Storage in TF-M.
+
+New TF-M service
+================
+The proposal is to implement the *PSA Internal Trusted Storage API* with the
+*TF-M Internal Trusted Storage service*. It can be abbreviated to *TF-M ITS
+service* in general and to ``its`` in code. This name has the advantage of
+making clear the correspondence between the service and the API it implements.
+
+If this name is adopted, then it may make sense to rename the *Secure Storage
+service* to the *Protected Storage service* in the future to match. Then "secure
+storage" could refer to the two services as a collective.
+
+The TF-M ITS service will implement PSA ITS version 1.0. It will be provided by
+a separate partition to Protected Storage, for a couple of reasons:
+
+- To permit isolation between the services.
+
+ - ITS is a PSA RoT Service, while Protected Storage is an Application RoT
+ Service.
+
+- To avoid circular dependencies.
+
+ - The PSA Firmware Framework does not permit circular dependencies between
+ partitions, which would occur if Protected Storage and ITS were provided by
+ the same partition. Protected Storage depends on Crypto, which in turn
+ depends on ITS.
+
+The existing SST filesystem will be reused to provide the backend of the
+service, with the flash layer modified to direct storage to internal flash,
+rather than external.
+
+Compared to Protected Storage, encryption, authentication and rollback
+protection are not required, so the SST encrypted object layer and the crypto
+and NV counter interfaces are not required. The rollback protection feature of
+the object table is also not required.
+
+Code structure
+==============
+The code structure of the service will be as follows:
+
+TF-M repo:
+
+``interface/``
+
+- ``include/psa/internal_trusted_storage.h`` - PSA ITS API
+- ``src/tfm_its_api.c`` - PSA ITS API implementation for NSPE
+
+``secure_fw/ns_callable/tfm_veneers.c`` - ITS veneers (auto-generated from
+manifest)
+
+``secure_fw/partitions/internal_trusted_storage/``
+
+- ``tfm_internal_trusted_storage.yaml`` - Partition manifest
+- ``tfm_its_secure_api.c`` - PSA ITS API implementation for SPE
+- ``tfm_its_req_mngr.c`` - Uniform secure functions and IPC request handlers
+- ``tfm_internal_trusted_storage.h`` - TF-M ITS API (with client_id parameter)
+- ``tfm_internal_trusted_storage.c`` - TF-M ITS implementation, using the
+ flash_fs as a backend
+- ``flash_fs/`` - Filesystem
+- ``flash/`` - Flash interface
+
+tf-m-tests repo:
+
+``test/secure_fw/suites/its/``
+
+- ``non_secure/psa_its_ns_interface_testsuite.c`` - Non-secure interface tests
+- ``secure/psa_its_s_interface_testsuite.c`` - Secure interface tests
+
+TF-M ITS implementation
+-----------------------
+The following APIs will be exposed by ``tfm_internal_trusted_storage.h``::
+
+ psa_status_t tfm_its_init(void);
+
+ psa_status_t tfm_its_set(int32_t client_id,
+ psa_storage_uid_t uid,
+ size_t data_length,
+ const void *p_data,
+ psa_storage_create_flags_t create_flags);
+
+ psa_status_t tfm_its_get(int32_t client_id,
+ psa_storage_uid_t uid,
+ size_t data_offset,
+ size_t data_size,
+ void *p_data,
+ size_t *p_data_length);
+
+ psa_status_t tfm_its_get_info(int32_t client_id,
+ psa_storage_uid_t uid,
+ struct psa_storage_info_t *p_info);
+
+ psa_status_t tfm_its_remove(int32_t client_id,
+ psa_storage_uid_t uid);
+
+That is, the TF-M ITS APIs will have the same prototypes as the PSA ITS APIs,
+but with the addition of a ``client_id`` parameter, which will be passed from
+the ITS request manager. A ``tfm_its_init`` function will also be present, which
+will be called at initialisation time and not exposed through a veneer or SID.
+
+The implementation in ``tfm_internal_trusted_storage.c`` must validate the
+parameters (excepting memory references, which are validated by the SPM),
+translate the UID and client ID into a file ID and then make appropriate calls
+to the filesystem layer. It must also take care ensure that any PSA Storage
+flags associated with the UID are honoured.
+
+Filesystem
+----------
+The ITS filesystem will be copied and modified from the SST filesystem. The
+modifications required will be to rename symbols from ``sst`` to ``its`` and to
+update the implementation to be aligned with the latest version of the PSA
+Storage spec (which consists mainly of moving to the ``psa_status_t`` error type
+and using common error codes from ``psa/error.h``).
+
+The filesystem will also be modified to align the size of each file stored to
+the alignment requirement exposed by the flash interface, by adding appropriate
+padding.
+
+The filesystem code will be de-duplicated again once the ITS service is
+implemented (see below).
+
+Flash layer
+-----------
+The flash layer will be copied from SST, and modified to direct writes to the
+internal flash device. It too needs to be updated to use ``psa_status_t`` error
+types.
+
+Platform layer
+--------------
+The TF-M platform layer must be be updated to distinguish between the external
+flash device used for Protected Storage and internal flash device used for ITS.
+A flash region for the relevant storage service needs to be allocated in each.
+
+On test platforms these may just be two distinct regions of the same flash
+device, but in general they will separate devices with their own drivers.
+
+Detailed design considerations
+==============================
+
+Mapping UID onto file ID
+------------------------
+The ITS APIs identify assets with 64-bit UIDs, to which the ITS service must
+append the 32-bit client ID of the calling partition for access control. The
+existing filesystem uses 32-bit file IDs to identify files, so some mapping
+would be required to convert between the identifiers.
+
+SST uses the object table to do the mapping from client ID, UID pairs to file
+IDs, which means making an extra filesystem read/write for each get/set
+operation. This mapping has minimal overhead for SST though, because object
+table lookups are already required for rollback protection.
+
+For ITS, no rollback protection feature is required, so there are two options:
+
+- Keep a simplified version of the SST object table that just maps from
+ (client ID, UID) to file ID
+
+- Modify the filesystem to take (at least) 96-bit file IDs, in the form of a
+ fixed-length char buffer.
+
+The advantage of the former is that it would require no extra modification to
+the existing filesystem code, and the existing SST object table could be cut
+down for ITS. However, it would mean that every ITS request would invoke twice
+the number of filesystem operations, increasing latency and flash wear. The code
+size of the ITS partition would be increased, as would RAM usage as the table
+would need to be read into RAM.
+
+The latter option would make the filesystem slightly more complex: the size of a
+metadata entry would be increased by 64-bits and the 96-bit fids would need to
+be copied and compared with ``memcpy`` and ``memcmp`` calls. On the other hand,
+mapping onto file IDs would incur only the cost of copying the UID and client ID
+values into the file ID buffer.
+
+A third, even more general, solution would be to use arbitrary-length
+null-terminated strings as the file IDs. This is the standard solution in
+full-featured filesystems, but we do not currently require this level of
+complexity in secure storage.
+
+With this in mind, the proposed option is the second.
+
+Storing create flags
+--------------------
+The ITS APIs provide a 32-bit ``create_flags`` parameter, which contains bit
+flags that determine the properties of the stored data. Only one flag is
+currently defined for ITS: ``PSA_STORAGE_FLAG_WRITE_ONCE``, which prevents a UID
+from being modified or deleted after it is set for the first time.
+
+There are two places that these flags could be stored: in the file data or as
+part of the file metadata.
+
+For the first option, the ITS implementation would need to copy to the flags
+into the buffer containing the data, and adjust the size accordingly, for each
+set operation, and the reverse for each get. Every get_info operation would need
+to read some of the file data, rather than just the metadata, implying a second
+flash read. A potential downside is that many of the cryptographic assets stored
+in ITS will be aligned to power-of-two sizes; adding an extra 32-bits would
+misalign the size, which may reduce flash performance or necessitate adding
+padding to align to the flash page size.
+
+To implement the second option, a 32-bit ``flag`` field would be added to the
+filesystem's metadata structure, whose interpretation is defined by the user.
+This field would clearly be catered towards the PSA Storage APIs, even if
+nominally generic, and alternative filesystems may not have any such field.
+However, it is a more intuitive solution and would simplify both flash alignment
+and get_info operations.
+
+Overall, it seems more beneficial to store the flags in the metadata, so this is
+the proposed solution.
+
+Code sharing between Protected Storage and ITS
+----------------------------------------------
+To de-duplicate the filesystem code used by both Protected Storage and ITS, it
+is proposed that Protected Storage calls ITS APIs as its backend filesystem.
+
+Protected Storage essentially becomes an encryption, authentication and rollback
+protection layer on top of ITS. It makes IPC requests or secure function calls
+to the ITS service to do filesystem operations on its behalf.
+
+This has a couple of advantages:
+
+- It shrinks Protected Storage's stack size, because the filesystem and flash
+ layer stack is only in ITS.
+
+- It automatically solves the problem of ensuring mutual exclusion in the
+ filesystem and flash layers when Protected Storage and ITS are called
+ concurrently. The second request to ITS will just be made to wait by the SPM.
+
+The disadvantage of this approach is that it will increase the latency of
+Protected Storage requests, due to the extra overhead associated with making a
+second IPC request or secure function call. It also limits Protected Storage to
+using only the ITS APIs, unless extra veneers are added solely for Protected
+Storage to use. This, for example, prevents Protected Storage from doing partial
+writes to file without reading and re-writing the whole file.
+
+ITS will need to be modified to direct calls from Protected Storage to a
+different flash device. It can use the client ID to detect when the caller is
+Protected Storage, and pass down the identity of the flash device to use to the
+flash layer, which then calls the appropriate driver.
+
+An open question is what to do if Protected Storage itself wants to store
+something in internal storage in the future (e.g. rollback counters, hash
+tree/table or top hash). A couple of possible solutions would be:
+
+- Divide up the UIDs, so certain UIDs from Protected Storage refer to assets in
+ internal storage, and others to ones in external storage.
+
+- Use the ``type`` field of ``psa_call`` in IPC model to distinguish between
+ internal and external storage requests.
+
+The other option for code sharing would be for Protected Storage and ITS to
+directly share filesystem code, which would be placed in a shared code region.
+With this approach, mutual exclusion to the flash device would need to be
+implemented separately, as would some way of isolating static memory belonging
+to each partition but not the code. Because of these complications, this option
+has not been considered further at this time.
+
+--------------
+
+*Copyright (c) 2019-2022, Arm Limited. All rights reserved.*
diff --git a/docs/design_docs/tfm_log_system_design_document.rst b/docs/design_docs/tfm_log_system_design_document.rst
new file mode 100644
index 0000000..bf9a364
--- /dev/null
+++ b/docs/design_docs/tfm_log_system_design_document.rst
@@ -0,0 +1,209 @@
+##########################
+Log system design document
+##########################
+
+:Author: Shawn Shan
+:Organization: Arm Limited
+:Contact: shawn.shan@arm.com
+
+**********
+Background
+**********
+
+In current TF-M log system, the SPM and Secure partitions share the same log
+APIs and implementations. While TF-M is keep evolving, the requirements for the
+log system has changed:
+
+ - Log level is required for both SPM and SP sides to output message in
+ different scenarios.
+ - SPM only needs simple log format such as hex and string, while SP needs rich
+ formatting.
+ - Distinctions on log output between SPM and SP are required.
+
+A new log system is needed to separate the SPM and Secure partitions and to
+meet their different requirements.
+
+******
+Design
+******
+
+To allow customizable configurations, the log interfaces are defined as macros.
+The macros are easy to be forwarded or even empty. When SPM trying to output
+message and a value, it relies on a wrapper function, and finally output the
+formatted message by the HAL API.
+
+The design principles of TF-M log system:
+
+ - Configurable log levels.
+ - Separated SPM and SP log implementations.
+ - Platforms provide log HAL implementations.
+
+SPM Log System
+==============
+
+Level Control
+-------------
+Three log levels for SPM log system are defined:
+
+ - TFM_SPM_LOG_LEVEL_DEBUG
+ - TFM_SPM_LOG_LEVEL_INFO
+ - TFM_SPM_LOG_LEVEL_ERROR
+ - TFM_SPM_LOG_LEVEL_SILENCE
+
+Then a macro ``TFM_SPM_LOG_LEVEL`` is defined as an indicator, it should
+be equal to one of the four log levels.
+
+API Definition
+--------------
+The following three APIs LOG APIs output the given 'msg' with hexadecimal
+formatted 'val' together. These APIs provide constrained ability to output
+numbers inside SPM. The 'msg' can be skipped with giving an empty string like
+"". And these APIs supports constant 'msg' string only, giving a runtime string
+as parameter 'msg' would potentially cause a runtime error.
+
+ SPMLOG_DBGMSGVAL(msg, val);
+
+ SPMLOG_INFMSGVAL(msg, val);
+
+ SPMLOG_ERRMSGVAL(msg, val);
+
+A C-function needs to work as an underlayer for these APIs as string formatting
+is required. Check 'spm_log_msgval' for details.
+
+.. code-block:: c
+
+ /**
+ * brief Output the given message plus one value as hexadecimal. The message
+ * can be skipped if the 'msg' is 'NULL' or 'len' equals 0. The
+ * formatted hexadecimal string for 'value' has a '0x' prefix and
+ * leading zeros are not stripped. This function rely on HAL API
+ * 'tfm_hal_output_spm_log' to output the formatted string.
+ *
+ * \param[in] msg A string message
+ * \param[in] len The length of the message
+ * \param[in] value A value need to be output
+ *
+ * \retval >=0 Number of chars output.
+ * \retval <0 TFM HAL error code.
+ */
+ int32_t spm_log_msgval(const char *msg, size_t len, uint32_t value)
+
+The following three APIs output a message in string.
+
+ SPMLOG_DBGMSG(msg);
+
+ SPMLOG_INFMSG(msg);
+
+ SPMLOG_ERRMSG(msg);
+
+Here is a table about the effective APIs with different SPM log level.
+
++------------------+-------------------------+---------------------------+---------------------------+-----------------------------+
+| | TFM_SPM_LOG_LEVEL_DEBUG | TFM_SPM_LOG_LEVEL_INFO | TFM_SPM_LOG_LEVEL_ERROR | TFM_SPM_LOG_LEVEL_SILENCE |
++==================+=========================+===========================+===========================+=============================+
+| SPMLOG_DBGMSGVAL | Yes | No | No | No |
++------------------+-------------------------+---------------------------+---------------------------+-----------------------------+
+| SPMLOG_INFMSGVAL | Yes | Yes | No | No |
++------------------+-------------------------+---------------------------+---------------------------+-----------------------------+
+| SPMLOG_ERRMSGVAL | Yes | Yes | Yes | No |
++------------------+-------------------------+---------------------------+---------------------------+-----------------------------+
+| SPMLOG_DBGMSG | Yes | No | No | No |
++------------------+-------------------------+---------------------------+---------------------------+-----------------------------+
+| SPMLOG_INFMSG | Yes | Yes | No | No |
++------------------+-------------------------+---------------------------+---------------------------+-----------------------------+
+| SPMLOG_ERRMSG | Yes | Yes | Yes | No |
++------------------+-------------------------+---------------------------+---------------------------+-----------------------------+
+
+HAL API
+-------
+Define HAL API for SPM log system:
+
+.. code-block:: c
+
+ /* SPM log HAL API */
+ int32_t tfm_hal_output_spm_log(const char *str, uint32_t len);
+
+Take debug message as an example:
+
+.. code-block:: c
+
+ /* For debug message */
+ #define SPMLOG_DBGMSG(msg) tfm_hal_output_spm_log(msg, sizeof(msg))
+ /* For debug message with a value */
+ #define SPMLOG_DBGMSGVAL(msg, val) spm_log_msgval(msg, sizeof(msg), val)
+
+Partition Log System
+====================
+Partition log outputting required rich formatting in particular cases. There is
+a customized print inside TF-M(``printf``), and it is wrapped as macro.
+
+Level Control
+-------------
+Three log levels for partition log system are defined:
+
+ - TFM_PARTITION_LOG_LEVEL_DEBUG
+ - TFM_PARTITION_LOG_LEVEL_INFO
+ - TFM_PARTITION_LOG_LEVEL_ERROR
+ - TFM_PARTITION_LOG_LEVEL_SILENCE
+
+Then a macro ``TFM_PARTITION_LOG_LEVEL`` is defined as an indicator. It should
+be equal to one of the four log levels and it is an overall setting for all
+partitions.
+
+Log Format
+----------
+Compared to SPM, SP log API supports formatting. Similar to ``printf``, these
+log APIs use a format outputting to output various type of data:
+
+.. code-block:: c
+
+ %d - decimal signed integer
+ %u - decimal unsigned integer
+ %x - hex(hexadecimal)
+ %c - char(character)
+ %s - string
+
+API Definition
+--------------
+Define partition log APIs:
+
+ LOG_DBGFMT(...);
+
+ LOG_INFFMT(...);
+
+ LOG_ERRFMT(...);
+
+Here is a table about the effective APIs with different partition log level.
+
++------------+-------------------------------+---------------------------------+---------------------------------+---------------------------------+
+| | TFM_PARTITION_LOG_LEVEL_DEBUG | TFM_PARTITION_LOG_LEVEL_INFO | TFM_PARTITION_LOG_LEVEL_ERROR | TFM_PARTITION_LOG_LEVEL_SILENCE |
++============+===============================+=================================+=================================+=================================+
+| LOG_DBGFMT | Yes | No | No | No |
++------------+-------------------------------+---------------------------------+---------------------------------+---------------------------------+
+| LOG_INFFMT | Yes | Yes | No | No |
++------------+-------------------------------+---------------------------------+---------------------------------+---------------------------------+
+| LOG_ERRFMT | Yes | Yes | Yes | No |
++------------+-------------------------------+---------------------------------+---------------------------------+---------------------------------+
+
+HAL API
+-------
+Please refers to the HAL design document.
+
+***********
+Log Devices
+***********
+In most of the cases, a serial device could be used as a log device. And in
+other particular cases, a memory-based log device could be applied as well.
+These log device interfaces are abstracted into HAL APIs.
+
+.. note::
+
+ It is not recommended to re-use the same HAL for both SPM and SP log
+ outputting especially when SPM and SP run under different privileged level,
+ which makes them have a different information confidential level. Unless:
+
+ - The SPM log outputting would be disabled as silence in the release version.
+
+--------------
+
+*Copyright (c) 2020, Arm Limited. All rights reserved.*
diff --git a/docs/design_docs/tfm_physical_attack_mitigation.rst b/docs/design_docs/tfm_physical_attack_mitigation.rst
new file mode 100644
index 0000000..29630ea
--- /dev/null
+++ b/docs/design_docs/tfm_physical_attack_mitigation.rst
@@ -0,0 +1,634 @@
+#################################################
+Physical attack mitigation in Trusted Firmware-M
+#################################################
+
+:Authors: Tamas Ban; David Hu
+:Organization: Arm Limited
+:Contact: tamas.ban@arm.com; david.hu@arm.com
+
+************
+Requirements
+************
+PSA Certified Level 3 Lightweight Protection Profile [1]_ requires protection
+against physical attacks. This includes protection against manipulation of the
+hardware and any data, undetected manipulation of memory contents, physical
+probing on the chip's surface. The RoT detects or prevents its operation outside
+the normal operating conditions (such as voltage, clock frequency, temperature,
+or external energy fields) where reliability and secure operation has not been
+proven or tested.
+
+.. note::
+
+ Mitigation against certain level of physical attacks is a mandatory
+ requirement for PSA Level 3 certification.
+ The :ref:`tf-m-against-physical-attacks` discussed below
+ doesn't provide mitigation against all the physical attacks considered in
+ scope for PSA L3 certification. Please check the Protection Profile document
+ for an exhaustive list of requirements.
+
+****************
+Physical attacks
+****************
+The goal of physical attacks is to alter the expected behavior of a circuit.
+This can be achieved by changing the device's normal operating conditions to
+untested operating conditions. As a result a hazard might be triggered on the
+circuit level, whose impact is unpredictable in advance but its effect can be
+observed. With frequent attempts, a weak point of the system could be identified
+and the attacker could gain access to the entire device. There is a wide variety
+of physical attacks, the following is not a comprehensive list rather just give
+a taste of the possibilities:
+
+ - Inject a glitch into the device power supply or clock line.
+ - Operate the device outside its temperature range: cool down or warm it up.
+ - Shoot the chip with an electromagnetic field. This can be done by passing
+ current through a small coil close to the chip surface, no physical contact
+ or modification of the PCB (soldering) is necessary.
+ - Point a laser beam on the chip surface. It could flip bits in memory or a
+ register, but precise knowledge of chip layout and design is necessary.
+
+The required equipment and cost of these attacks varies. There are commercial
+products to perform such attacks. Furthermore, they are shipped with a scripting
+environment, good documentation, and a lot of examples. In general, there is a
+ton of videos, research paper and blogs about fault injection attacks. As a
+result the threshold, that even non-proficient can successfully perform such
+attack, gets lower over time.
+
+*****************************************************************
+Effects of physical attacks in hardware and in software execution
+*****************************************************************
+The change in the behavior of the hardware and software cannot be seen in
+advance when performing a physical attack. On circuit-level they manifest
+in bit faults. These bit faults can cause varied effects in the behavior of
+the device micro-architecture:
+
+ - Instruction decoding pipeline is flushed.
+ - Altering instructions when decoding.
+ - Altering data when fetching or storing.
+ - Altering register content, and the program counter.
+ - Flip bits in register or memory.
+
+These phenomenons happen at random and cannot be observed directly but the
+effect can be traced in software execution. On the software level the following
+can happen:
+
+ - A few instructions are skipped. This can lead to taking different branch
+ than normal.
+ - Corrupted CPU register or data fetch could alter the result of a comparison
+ instruction. Or change the value returned from a function.
+ - Corrupted data store could alter the config of peripherals.
+ - Very precise attacks with laser can flip bits in any register or in memory.
+
+This is a complex domain. Faults are not well-understood. Different fault models
+exist but all of them target a specific aspect of fault injection. One of the
+most common and probably the easily applicable fault model is the instruction
+skip.
+
+***********************************
+Mitigation against physical attacks
+***********************************
+The applicability of these attacks highly depends on the device. Some
+devices are more sensitive than others. Protection is possible at hardware and
+software levels as well.
+
+On the hardware level, there are chip design principles and system IPs that are
+resistant to fault injection attacks. These can make it harder to perform a
+successful attack and as a result the chip might reset or erase sensitive
+content. The device maker needs to consider what level of physical attack is in
+scope and choose a SoC accordingly.
+
+On top of hardware-level protection, a secondary protection layer can be
+implemented in software. This approach is known as "defence in depth".
+
+Neither hardware nor software level protection is perfect because both can be
+bypassed. The combination of them provides the maximum level of protection.
+However, even when both are in place, it is not certain that they provide 100%
+protection against physical attacks. The best of what is to achievable to harden
+the system to increase the cost of a successful attack (in terms of time and
+equipment), thereby making it non profitable to perform them.
+
+.. _phy-att-countermeasures:
+
+Software countermeasures against physical attacks
+=================================================
+There are practical coding techniques which can be applied to harden software
+against fault injection attacks. They significantly decrease the probability of
+a successful attack:
+
+ - Control flow monitor
+
+ To catch malicious modification of the expected control flow. When an
+ important portion of a program is executed, a flow monitor counter is
+ incremented. The program moves to the next stage only if the accumulated
+ flow monitor counter is equal to an expected value.
+
+ - Default failure
+
+ The return value variable should always contain a value indicating
+ failure. Changing its value to success is done only under one protected
+ flow (preferably protected by double checks).
+
+ - Complex constant
+
+ It is hard to change a memory region or register to a pre-defined value, but
+ usual boolean values (0 or 1) are easier to manipulate.
+
+ - Redundant variables and condition checks
+
+ To make branch condition attack harder it is recommended to check the
+ relevant condition twice (it is better to have a random delay between the
+ two comparisons).
+
+ - Random delay
+
+ Successful fault injection attacks require very precise timing. Adding
+ random delay to the code execution makes the timing of an attack much
+ harder.
+
+ - Loop integrity check
+
+ To avoid to skip critical loop iterations. It can weaken the cryptographic
+ algorithms. After a loop has executed, check the loop counter whether it
+ indeed has the expected value.
+
+ - Duplicated execution
+
+ Execute a critical step multiple times to prevent fault injection from
+ skipping the step. To mitigate multiple consecutive fault injections, random
+ delay can be inserted between duplicated executions.
+
+These techniques should be applied in a thoughtful way. If it is applied
+everywhere then it can result in messy code that makes the maintenance harder.
+Code must be analysed and sensitive parts and critical call path must be
+identified. Furthermore, these techniques increase the overall code size which
+might be an issue on the constrained devices.
+
+Currently, compilers are not providing any support to implement these
+countermeasures automatically. On the contrary, they can eliminate the
+protection code during optimization. As a result, the C level protection does
+not add any guarantee about the final behavior of the system. The effectiveness
+of these protections highly depends on the actual compiler and the optimization
+level. The compiled assembly code must be visually inspected and tested to make
+sure that proper countermeasures are in-place and perform as expected.
+
+.. _phy-att-threat-model:
+
+******************************************
+TF-M Threat Model against physical attacks
+******************************************
+
+Physical attack target
+======================
+A malicious actor performs physical attack against TF-M to retrieve assets from
+device. These assets can be sensitive data, credentials, crypto keys. These
+assets are protected in TF-M by proper isolation.
+
+For example, a malicious actor can perform the following attacks:
+
+ - Reopen the debug port or hinder the closure of it then connect to the device
+ with a debugger and dump memory.
+ - Bypass secure boot to replace authentic firmware with a malicious image.
+ Then arbitrary memory can be read.
+ - Assuming that secure boot cannot be bypassed then an attacker can try to
+ hinder the setup of the memory isolation hardware by TF-M
+ :term:`Secure Partition Manager` (SPM) and manage to execute the non-secure
+ image in secure state. If this is achieved then still an exploitable
+ vulnerability is needed in the non-secure code which can be used to inject
+ and execute arbitrary code to read the assets.
+ - Device might contain unsigned binary blob next to the official firmware.
+ This can be any data, not necessarily code. If an attacker manages to
+ replace this data with arbitrary content (e.g. a NOP slide leading to a
+ malicious code) then they can try to manipulate the program counter to jump
+ to this area before setting up the memory isolation.
+
+.. _attacker-capability:
+
+Assumptions on attacker capability
+==================================
+It is assumed that the attacker owns the following capabilities to perform
+physical attack against devices protected by TF-M.
+
+ - Has physical access to the device.
+ - Able to access external memory, read and possibly tamper it.
+ - Able to load arbitrary candidate images for firmware upgrade.
+ - Able to manage that bootloader tries to upgrade the arbitrary image from
+ staging area.
+ - Able to inject faults on hardware level (voltage or power glitch, EM pulse,
+ etc.) to the system.
+ - Precise timing of fault injection is possible once or a few times, but in
+ general the more intervention is required for a successful attack the harder
+ will be to succeed.
+
+It is out of the scope of TF-M mitigation if an attacker is able to directly
+tamper or disclose the assets. It is assumed that an attacker has the following
+technical limitations.
+
+ - No knowledge of the image signing key. Not able to sign an arbitrary image.
+ - Not able to directly access to the chip through debug port.
+ - Not able to directly access internal memory.
+ - No knowledge of the layout of the die or the memory arrangement of the
+ secure code, so precise attack against specific registers or memory
+ addresses are out of scope.
+
+Physical attack scenarios against TF-M
+======================================
+Based on the analysis above, a malicious actor may perform physical attacks
+against critical operations in :term:`SPE` workflow and critical modules in
+TF-M, to indirectly gain unauthenticated accesses to assets.
+
+Those critical operations and modules either directly access the assets or
+protect the assets from disclosure. Those operations and modules can include:
+
+ - Image validation in bootloader
+ - Isolation management in TF-M, including platform specific configuration
+ - Cryptographic operations
+ - TF-M Secure Storage operations
+ - PSA client permission check in TF-M
+
+The detailed scenarios are discussed in following sections.
+
+Physical attacks against bootloader
+-----------------------------------
+Physical attacks may bypass secure image validation in bootloader and a
+malicious image can be installed.
+
+The countermeasures is bootloader specific implementation and out of the scope
+of this document. TF-M relies on MCUboot by default. MCUboot has already
+implemented countermeasures against fault injection attacks [3]_.
+
+.. _physical-attacks-spm:
+
+Physical attacks against TF-M SPM
+---------------------------------
+TF-M SPM initializes and manages the isolation configuration. It also performs
+permission check against secure service requests from PSA clients.
+
+Static isolation configuration
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+It is TF-M SPM's responsibility to build up isolation during the initialization
+phase. If this is missed or not done correctly then it might be possible for
+non-secure code to access some secure memory area or an external device can
+access assets in the device through a debug port.
+
+Therefore, hindering the setup of memory or peripheral isolation hardware is an
+obvious candidate for physical attacks. The initialization phase has a constant
+time execution (like the previous boot-up state), therefore the timing of the
+attack is simpler, compared to cases when secure and non-secure runtime firmware
+is up-and-running for a while and IRQs make timing unpredictable.
+
+Some examples of attacking isolation configuration are shown in the list below.
+
+ - Hinder the setting of security regions. Try to execute non-secure code as
+ secure.
+ - Manipulate the setting of secure regions, try to extend the non-secure
+ regions to cover a memory area which otherwise is intended to be secure
+ area.
+ - Hinder the setting of isolation boundary. In this case vulnerable ARoT code
+ has access to all memory.
+ - Manipulate peripheral configuration to give access to non-secure code to a
+ peripheral which is intended to be secure.
+
+PSA client permission checks
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+TF-M SPM performs several permission checks against secure service requests from
+a PSA client, such as:
+
+- Check whether the PSA client is a non-secure client or a secure client
+
+ NS client's PSA client ID is negative. NS client is not allowed to directly
+ access secure areas. A malicious actor can inject faults when TF-M SPM
+ authenticates a NS client. It may manipulate TF-M to accept it as a secure
+ client and allow the NS client to access assets.
+
+- Memory access checks
+
+ TF-M SPM checks whether the request has correct permission to access a secure
+ memory area. A malicious actor can inject faults when TF-M SPM checks memory
+ access permission. It may skip critical check steps or corrupt the check
+ result. Thereby a malicious service request may pass TF-M memory access check
+ and accesses assets which it is not allowed to.
+
+The physical attacks mentioned above relies on the a malicious NS application or
+a vulnerable RoT service to start a malicious secure service request to access
+the assets. The malicious actor has to be aware of the accurate timing of
+dealing with the malicious request in TF-M SPM. The timing can be affected by
+other clients and interrupts.
+It should be more difficult than pure fault injection.
+
+Dynamic isolation boundary configuration
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Physical attack may affect the isolation boundary setting during TF-M context
+switch, especially in Isolation Level 3. For example:
+
+ - A fault injection may cause TF-M SPM to skip clear privileged state before
+ switching in an ARoT service.
+ - A fault injection may cause TF-M SPM to skip updating MPU regions and
+ therefore the next RoT service may access assets belonging to a previous
+ one.
+
+However, it is much more difficult to find out the accurate timing of TF-M
+context switch, compared to other scenarios in TF-M SPM. It also requires a
+vulnerable RoT service to access assets after fault injection.
+
+Physical attacks against TF-M Crypto service
+--------------------------------------------
+Since crypto operations are done by mbedTLS library or by a custom crypto
+accelerator engine and its related software driver stack, the analysis of
+physical attacks against crypto operations is out-of-scope for this document.
+However, in general the same requirements are applicable for the crypto, to be
+compliant with PSA Level 3 certification. That is, it must be resistant against
+physical attacks. So crypto software and hardware must be hardened against
+side-channel and physical attacks.
+
+Physical attacks against Secure Storage
+---------------------------------------
+Physical attacks against Internal Trusted Storage
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Based on the assumption in :ref:`attacker-capability`, a malicious actor is
+unable to directly retrieve assets via physical attacks against
+:term:`Internal Trusted Storage` (ITS).
+
+Instead, a malicious actor can inject faults into isolation configuration of ITS
+area in TF-M SPM to gain the access to assets stored in ITS. Refer to
+:ref:`physical-attacks-spm` for details.
+
+Physical attacks against Protected Storage
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Based on the assumption in :ref:`attacker-capability`, a malicious actor can be
+able to directly access external storage device.
+Therefore :term:`Protected Storage` (PS) shall enable encryption and
+authentication by default to detect tampering with the content in external
+storage device.
+
+A malicious actor can also inject faults into isolation configuration of PS and
+external storage device peripherals in TF-M SPM to gain the access to assets
+stored in PS. Refer to :ref:`physical-attacks-spm` for details.
+
+It is out of the scope of TF-M to fully prevent malicious actors from directly
+tampering with or retrieving content stored in external storage devices.
+
+Physical attacks against platform specific implementation
+---------------------------------------------------------
+Platform specific implementation includes critical TF-M HAL implementations.
+A malicious actor can perform physical attack against those platform specific
+implementations to bypass the countermeasures in TF-M common code.
+
+Platform early initialization
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+TFM provides a HAL API for platforms to perform HW initialization before SPM
+initialization starts.
+The system integrator is responsible to implement this API on a particular SoC
+and harden it against physical attacks:
+
+.. code-block:: c
+
+ enum tfm_hal_status_t tfm_hal_platform_init(void);
+
+The API can have several initializations on different modules. The system
+integrator can choose to even harden some of these initializations functions
+within this platform init API. One of the examples is the debug access setting.
+
+Debug access setting
+********************
+TF-M configures debug access according to device lifecycle and accessible debug
+certificates. In general, TF-M locks down the debug port if the device is in
+secure production state.
+The system integrator can put the settings into an API and harden it against
+physical attacks.
+
+Platform specific isolation configuration
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+TFM SPM exposes a HAL API for static and dynamic isolation configuration. The
+system integrator is responsible to implement these API on a particular SoC and
+harden it against physical attacks.
+
+.. code-block:: c
+
+ enum tfm_hal_status_t tfm_hal_set_up_static_boundaries(void);
+ enum tfm_hal_status_t tfm_hal_bind_boundary(const struct partition_load_info_t *p_ldinf,
+ uintptr_t *p_boundary);
+
+Memory access check
+^^^^^^^^^^^^^^^^^^^
+TFM SPM exposes a HAL API for platform specific memory access check. The
+system integrator is responsible to implement this API on a particular SoC and
+harden it against physical attacks.
+
+.. code-block:: c
+
+ tfm_hal_status_t tfm_hal_memory_check(uintptr_t boundary,
+ uintptr_t base,
+ size_t size,
+ uint32_t access_type);
+
+.. _tf-m-against-physical-attacks:
+
+*********************************************
+TF-M countermeasures against physical attacks
+*********************************************
+This section propose a design of software countermeasures against physical
+attacks.
+
+Fault injection hardening library
+=================================
+There is no open-source library which implements generic mitigation techniques
+listed in :ref:`phy-att-countermeasures`.
+TF-M project implements a portion of these techniques. TF-M software
+countermeasures are implemented as a small library Fault Injection Hardening
+(FIH) in TF-M code base. A similar library was first introduced and tested in
+the MCUboot project (version 1.7.0) [2]_ which TF-M relies on.
+
+The FIH library is put under TF-M ``lib/fih/``.
+
+The implementation of the different techniques was assigned to fault injection
+protection profiles. Four profiles (OFF, LOW, MEDIUM, HIGH) were introduced to fit
+better to the device capability (memory size, TRNG availability) and to
+protection requirements mandated by the device threat model. Fault injection
+protection profile is configurable at compile-time, default value: OFF.
+
+Countermeasure profiles and corresponding techniques are listed in the table
+below.
+
++--------------------------------+-------------+----------------+--------------+------------------+
+| Countermeasure | Profile LOW | Profile MEDIUM | Profile HIGH | Comments |
++================================+=============+================+==============+==================+
+| Control flow monitor | Y | Y | Y | |
++--------------------------------+-------------+----------------+--------------+------------------+
+| Failure loop hardening | Y | Y | Y | |
++--------------------------------+-------------+----------------+--------------+------------------+
+| Complex constant | | Y | Y | |
++--------------------------------+-------------+----------------+--------------+------------------+
+| Redundant variables and checks | | Y | Y | |
++--------------------------------+-------------+----------------+--------------+------------------+
+| Random delay | | | Y | Implemented, but |
+| | | | | depends on HW |
+| | | | | capability |
++--------------------------------+-------------+----------------+--------------+------------------+
+
+Similar to MCUboot, four profiles are supported. It can be configured at build
+time by setting (default is OFF):
+
+ ``-DTFM_FIH_PROFILE=<OFF, LOW, MEDIUM, HIGH>``
+
+How to use FIH library
+======================
+As analyzed in :ref:`phy-att-threat-model`, this section focuses on integrating
+FIH library in TF-M SPM to mitigate physical attacks.
+
+ - Identify critical function call path which is mandatory for configuring
+ isolation or debug access. Change their return types to ``FIH_RET_TYPE`` and
+ make them return with ``FIH_RET``. Then call them with ``FIH_CALL``. These macros
+ are providing the extra checking functionality (control flow monitor, redundant
+ checks and variables, random delay, complex constant) according to the profile
+ settings. More details about usage can be found here:
+ ``trusted-firmware-m/lib/fih/inc/fih.h``
+
+ Take simplified TF-M SPM initialization flow as an example:
+
+ .. code-block:: c
+
+ main()
+ |
+ |--> tfm_core_init()
+ | |
+ | |--> tfm_hal_set_up_static_boundaries()
+ | | |
+ | | |--> platform specific isolation impl.
+ | |
+ | |--> tfm_hal_platform_init()
+ | |
+ | |--> platform specific init
+ |
+ |--> During each partition initialization
+ |
+ |--> tfm_hal_bind_boundary()
+ |
+ |--> platform specific peripheral isolation impl.
+
+ - Might make the important setting of peripheral config register redundant
+ and verify them to match expectations before continue.
+
+ - Implements an extra verification function which checks the critical hardware
+ config before secure code switches to non-secure. Proposed API for this
+ purpose:
+
+ .. code-block:: c
+
+ fih_int tfm_hal_verify_static_boundaries(void);
+
+ This function is intended to be called just after the static boundaries are
+ set up and is responsible for checking all critical hardware configurations.
+ The goal is to catch if something is missed and act according
+ to system policy. The introduction of one more checking point requires one
+ more intervention with precise timing. The system integrator is responsible
+ to implement this API on a particular SoC and harden it against physical
+ attacks. Make sure that all platform dependent security feature is properly
+ configured.
+
+ - The most powerful mitigation technique is to add random delay to the code
+ execution. This makes the timing of the attack much harder. However it
+ requires an entropy source. It is recommended to use the ``HIGH`` profile
+ when hardware support is available. There is a porting API layer to fetch
+ random numbers in FIH library:
+
+ .. code-block:: c
+
+ void fih_delay_init(void);
+ uint8_t fih_delay_random(void);
+
+ - Similar countermeasures can be implemented in critical steps in platform
+ specific implementation.
+
+ Take memory isolation settings on AN521 platform as an example.
+ The following hardware components are responsible for memory isolation in a
+ SoC, which is based on SSE-200 subsystem.
+ System integrators must examine the chip specific memory isolation solution,
+ identify the key components and harden the configuration of those.
+ This list just serves as an example here for easier understanding:
+
+ - Implementation Defined Attribution Unit (IDAU): Implementation defined,
+ it can be a static config or dynamic.
+ Contains the default security access permissions of the memory map.
+ - SAU: The main module in the CPU to determine the security settings of
+ the memory.
+ - :term:`MPC`: External module from the CPU point of view. It protects the
+ non security aware memories from unauthenticated access. Having a
+ properly configured MPC significantly increases the security of the
+ system.
+ - :term:`PPC`: External module from the CPU
+ point of view. Protects the non security aware peripherals from
+ unauthenticated access.
+ - MPU: Protects memory from unprivileged access. ARoT code has only a
+ restricted access in secure domain. It mitigates that a vulnerable or
+ malicious ARoT partition can access to device assets.
+
+ The following AN521 specific isolation configuration functions
+ shall be hardened against physical attacks.
+
+ .. code-block:: c
+
+ sau_and_idau_cfg()
+ mpc_init_cfg()
+ ppc_init_cfg()
+
+ Some platform specific implementation rely on platform standard device
+ driver libraries. It can become much more difficult to maintain drivers if
+ the standard libraries are modified with FIH library. Platform specific
+ implementation can implement duplicated execution and redundant variables/
+ condition check when calling platform standard device driver libraries
+ according to usage scenarios.
+
+Impact on memory footprint
+==========================
+The addition of protection code against physical attacks increases the memory
+footprint. The actual increase depends on the selected profile and where the
+mitigation code is added.
+
+Attack experiment with SPM
+==========================
+The goal is to bypass the setting of memory isolation hardware with simulated
+instruction skips in fast model execution (FVP_MPS2_AEMv8M) in order to execute
+the regular non-secure test code in secure state. This is done by identifying
+the configuration steps which must be bypassed to make this happen. The
+instruction skip simulation is achieved by breakpoints and manual manipulation
+of the program counter. The following steps are done on AN521 target, but this
+can be different on another target:
+
+ - Bypass the configuration of isolation HW: SAU, MPC.
+ - Bypass the setting of the PSP limit register. Otherwise, a stack overflow
+ exception will happen. Because the secure PSP will be overwritten by the
+ address of the non-secure stack and on this particular target the non-secure
+ stack is on lower address than the value in the secure PSP_LIMIT register.
+ - Avoid the clearing of the least significant bit in the non-secure entry
+ point, where BLXNS/BXNS is jumping to non-secure code. Having the least
+ significant bit cleared indicates to the hardware to switch security state.
+
+The previous steps are enough to execute the non-secure Reset_Handler() in
+secure state. Usually, RTOS is executing on the non-secure side. In order to
+properly boot it up further steps are needed:
+
+ - Set the S_VTOR system register to point the address of the NS Vector table.
+ Code is executed in secure state therefore when an IRQ hit then the handler
+ address is fetched from the table pointed by S_VTOR register. RTOS usually
+ do an SVC call at start-up. If S_VTOR is not modified then SPM's SVC handler
+ will be executed.
+ - TBC: RTX osKernelStart still failing.
+
+The bottom line is that in order to execute the regular non-secure code in
+secure state the attacker need to interfere with the execution flow at many
+places. Successful attack can be made even harder by adding the described
+mitigation techniques and some random delays.
+
+
+*********
+Reference
+*********
+
+.. [1] `PSA Certified Level 3 Lightweight Protection Profile <https://www.psacertified.org/app/uploads/2020/11/JSADEN009-PSA_Certified_Level_3_LW_PP-1.0-ALP02.pdf>`_
+
+.. [2] `MCUboot project <https://github.com/mcu-tools/mcuboot/blob/master/boot/bootutil/include/bootutil/fault_injection_hardening.h>`_
+
+.. [3] `MCUboot fault injection mitigation <https://www.trustedfirmware.org/docs/TF-M_fault_injection_mitigation.pdf>`_
+
+--------------------------------
+
+*Copyright (c) 2021-2022, Arm Limited. All rights reserved.*
diff --git a/docs/design_docs/tfm_psa_inter_process_communication.rst b/docs/design_docs/tfm_psa_inter_process_communication.rst
new file mode 100644
index 0000000..312d6ae
--- /dev/null
+++ b/docs/design_docs/tfm_psa_inter_process_communication.rst
@@ -0,0 +1,228 @@
+################################
+TF-M Inter-Process Communication
+################################
+
+:Authors: Ken Liu, Mingyang Sun
+:Organization: Arm Limited
+:Contact: ken.liu@arm.com, mingyang.sun@arm.com
+
+***********
+Terminology
+***********
+
+IPC - Inter-Process Communication
+
+For more terminology please check Reference_ document.
+
+***************
+Design Overview
+***************
+Components for implementing IPC:
+
+- SPM – for partition information and isolation actions
+- Core – for exception handling
+- Memory pool
+- Message manager
+- Thread
+- Synchronization objects
+- PSA API
+
+**********************
+Implementation Details
+**********************
+Listed modules are all internal modules except PSA API. Prototypes and
+definitions are not listed for internal modules in this document. For PSA
+API definitions, check them in PSA Firmware Framework specification in the
+reference chapter.
+
+SPM and Core
+============
+SPM manages Secure Partition information. Enhancements need to be done in SPM
+data structure for Secure Partition for IPC due to:
+
+- IPC model requires each Secure Partition has its own stack area.
+- Multiple services are holding in same Secure Partition and each service
+ has its own information like message queue, SID and priority.
+- Changed information related manifest items need to be changed, too.
+
+Modifications in Core:
+
+- More SVC calls need to be added into list since PSA API are implemented as
+ SVC calls in TF-M.
+- New PendSV handler for thread scheduling.
+- Arch-related context stacking and switching.
+
+Memory Pool
+===========
+Handles of connection and messages for Secure Partition needs to be allocated
+dynamically. A memory pool is provided in the system to handle dynamic
+allocation. Each memory pool item contains below information:
+
+- A list iterator to chain all of memory pool items.
+- An information member to record information like size and types.
+- The memory item body for caller usage.
+
+A memory area needs to be provided in SPM for the memory pool. It could be an
+array of memory areas defined in the linker script. Two chains are available to
+manage the items: free chain and used chain. And an LRU (Last recent used)
+mechanism is applied for fast seeking while item allocating and destroying.
+
+Message Manager
+===============
+Message Manager handles message creating, pushing, retrieving and destroy. A
+message contains below information:
+
+- Message sender and destination
+- Message status
+- IO vectors for service
+- 'psa_msg_t' for service
+
+A checking needs to be performed in SPM before creating a message to detect if
+a message with the same sender and destination is ongoing. This avoids repeat
+messages are available in the queue.
+
+Thread
+======
+Each Secure Partition has a thread as execution environment. Secure Partition
+is defined statically in TF-M manifest, which indicates that a number of
+threads are statically defined. Threads are chained in SPM and sorted with
+its priority, and there is an extra indicator point to first running thread
+with the highest priority. This helps fast seeking of running threads while
+the scheduler is switching threads.
+
+Thread context contains below information:
+
+- Priority
+- Status
+- Stack pointer
+- Stack pointer limitation
+- Entry
+- Parameter
+- Entry return value
+- Context
+- List iterator
+
+Thread API provides below functions:
+
+- Thread creating and destroying
+- Thread status retrieving and changing
+- Current thread retrieving
+- Thread context switching
+
+PendSV exception in TF-M core is the place thread context APIs been called.
+Before thread switching taking place, isolation status needs to be changed
+based on Secure Partition change and current isolation level – a thread is a
+member of partition which means thread switching caused a partition switching.
+
+Synchronization API
+===================
+A first synchronization object is an event. This could be applied into event
+waiting in the partition, and message response handling in IPC. The event
+object contains below members:
+
+- Owner thread who is waiting for this event
+- Event status (Ready or Not-Ready)
+- List iterator for synchronization objects management
+
+Event API Limitation: could be waited by one thread only.
+
+PSA API
+=======
+This chapter describes the PSA API in an implementation manner.
+
+- API type: could be Client API and Service Partition API
+- Block-able: Block-able API may block caller thread; Non-Block API does not
+ block caller thread.
+- Description: The functionality description and important comments.
+
+.. code-block:: c
+
+ uint32_t psa_framework_version(void);
+ uint32_t psa_version(uint32_t sid);
+
+- Client API
+- Non-Block API
+- These 2 functions are finally handled in SPM and return the framework version
+ or version to the caller.
+
+.. code-block:: c
+
+ psa_handle_t psa_connect(uint32_t sid, uint32_t version);
+ psa_status_t psa_call(psa_handle_t handle, int32_t type,
+ const psa_invec *in_vec, size_t in_len,
+ psa_outvec *out_vec, size_t out_len);
+ void psa_close(psa_handle_t handle);
+
+- Client API
+- Block-able API
+- These 3 APIs are implemented in the same manner and just different
+ parameters. SPM converts each call into a corresponding message with a
+ parameter in the message body and pushes the message into service queue to
+ wait for the response. Scheduler switches to a specified thread (partition)
+ and makes Secure Partition to have chance retrieving and process message.
+ After a message response is returned to the caller, the waiting caller gets
+ to go and get the result.
+
+.. code-block:: c
+
+ psa_signal_t psa_wait(psa_signal_t signal_mask, uint32_t timeout);
+
+- Secure Partition API
+- Block-able API
+- This API blocks caller partition if there is no expected event for it. This
+ function is implemented based on event API.
+
+.. code-block:: c
+
+ void psa_set_rhandle(psa_handle_t msg_handle, void *rhandle);
+ psa_status_t psa_get(psa_signal_t signal, psa_msg_t *msg);
+ size_t psa_read(psa_handle_t msg_handle, uint32_t invec_idx,
+ void *buffer, size_t num_bytes);
+ size_t psa_skip(psa_handle_t msg_handle, uint32_t invec_idx,
+ size_t num_bytes);
+ void psa_write(psa_handle_t msg_handle, uint32_t outvec_idx,
+ const void *buffer, size_t num_bytes);
+ void psa_reply(psa_handle_t msg_handle, psa_status_t status);
+ void psa_clear(void);
+ void psa_eoi(psa_signal_t irq_signal);
+
+- Secure Partition API
+- Non-Block
+- These APIs do not take the initiative to change caller status. They process
+ data and return the processed data back to the caller.
+
+.. code-block:: c
+
+ void psa_notify(int32_t partition_id);
+
+- Secure Partition API
+- Non-Block
+- This API sets DOORBELL bit in destination partition's event. This API does
+ not take the initiative to change caller status.
+
+.. code-block:: c
+
+ void psa_panic(void);
+
+- Secure Partition API
+- Block-able API
+- This function will terminate execution within the calling Secure Partition
+ and will not return.
+
+*********
+Reference
+*********
+
+| `PSA Firmware Framework specification URL`_
+| `Slides includes IPC basic introduction URL`_
+| `IPC model implementation URL`_
+
+.. _PSA Firmware Framework specification URL:
+ https://www.arm.com/architecture/security-features/platform-security
+.. _Slides includes IPC basic introduction URL: https://connect.linaro.org/
+ resources/yvr18/sessions/yvr18-108/
+.. _IPC model implementation URL: https://www.youtube.com/watch?v=6wEFoq49qUw
+
+--------------
+
+*Copyright (c) 2019-2022, Arm Limited. All rights reserved.*
diff --git a/docs/design_docs/tfm_secure_boot.rst b/docs/design_docs/tfm_secure_boot.rst
new file mode 100644
index 0000000..043af16
--- /dev/null
+++ b/docs/design_docs/tfm_secure_boot.rst
@@ -0,0 +1,818 @@
+###########
+Secure boot
+###########
+For secure devices it is security critical to enforce firmware authenticity to
+protect against execution of malicious software. This is implemented by building
+a trust chain where each step in the execution chain authenticates the next
+step before execution. The chain of trust in based on a "Root of Trust" which
+is implemented using asymmetric cryptography. The Root of Trust is a combination
+of an immutable bootloader and a public key (ROTPK).
+
+.. Warning::
+ In order to implement a proper chain of trust functionality, it is
+ mandatory that the first stage bootloader and ROTPK is stored in an
+ **immutable** way. To achieve this the bootloader code must be stored and
+ executed from ROM or such part of flash memory which supports write
+ protection. ROTPK can be stored in a one-time-programmable (OTP) memory. If
+ the SoC has a built-in BL1 (immutable) bootloader and the immutability of
+ TF-M secure boot code is not guaranteed then TF-M secure boot code must be
+ authenticated by BL1 bootloader before execution. If immutability of root
+ of trust (first stage bootloader + ROTPK) is not ensured then there is a
+ risk that the secure boot process could be bypassed, which could lead to
+ arbitrary code execution on the device. Current TF-M secure boot code is
+ intended to be a second stage bootloader, therefore it requires
+ authentication before execution. If TF-M secure boot code is used as a first
+ stage bootloader then it must be stored according to the above requirements.
+
+*******************************
+Second stage bootloader in TF-M
+*******************************
+By default, the MCUboot project from
+`GitHub <https://github.com/mcu-tools/mcuboot>`__ is used as the secure
+bootloader in TF-M. The repository is going to be automatically downloaded by
+CMake. The version downloaded can be controlled by the ``MCUBOOT_VERSION``
+CMake variable. If you wish to use a locally downloaded copy, the CMake variable
+``MCUBOOT_PATH`` can be set to its location. This document contains information
+about how MCUboot has been integrated to TF-M. For further information about
+MCUboot design please refer to the `MCUBoot homepage <https://www.mcuboot.com/>`__.
+
+Bootloader is started when CPU is released from reset. It runs in secure mode.
+It authenticates the firmware image by hash (SHA-256) and digital signature
+(RSA-3072) validation. Public key, that the checks happens against, can be built
+into the bootloader image or can be provisioned to the SoC during manufacturing.
+Metadata of the image is delivered together with the image itself in a header
+and trailer section. In case of successful authentication, bootloader passes
+execution to the secure image. Execution never returns to bootloader until
+next reset.
+
+A default RSA key pair is stored in the repository, public key is in ``keys.c``
+and private key is in ``root-RSA-3072.pem``.
+
+.. Danger::
+ DO NOT use the default keys in a production code, they are exclusively
+ for testing!
+
+The private key must be stored in a safe place outside of the repository.
+``imgtool.py`` (found in the ``scripts`` directory in the MCUBoot repository,
+or installed through the pip package manager) can be used to generate new key
+pairs.
+
+The bootloader can handle the secure and non-secure images independently
+(multiple image boot) or together (single image boot). In case of multiple image
+boot they are signed independently with different keys and they can be updated
+separately. In case of single image boot the secure and non-secure image is
+handled as a single blob, therefore they must be contiguous in the device
+memory. In this case they are signed together and also they can be updated only
+together. In order to have the same artefacts at the end of the build regardless
+of how the images are handled (independently or together) the images are always
+concatenated. In case of single image boot they are concatenated first and then
+signed. In case of multiple image boot they are separately signed first and then
+concatenated. Preparation of payload is done by Python scripts:
+``bl2/ext/mcuboot/scripts/``. At the end of a successful build the signed TF-M
+payload can be found in: ``<build_dir>/bin/tfm_s_ns_signed.bin``
+
+*********************
+Integration with TF-M
+*********************
+MCUBoot assumes a predefined memory layout which is described below (applicable
+for AN521). It is mandatory to define the primary slot and the secondary slot
+partitions, but their size and location can be changed::
+
+ - 0x0000_0000 - 0x0007_FFFF: BL2 bootloader - MCUBoot
+ - 0x0008_0000 - 0x000F_FFFF: Primary slot : Single binary blob:
+ Secure + Non-Secure image;
+ Primary memory partition
+ - 0x0008_0000 - 0x0008_03FF: Common image header
+ - 0x0008_0400 - 0x0008_xxxx: Secure image
+ - 0x0008_xxxx - 0x0010_03FF: Padding (with 0xFF)
+ - 0x0010_0400 - 0x0010_xxxx: Non-secure image
+ - 0x0010_xxxx - 0x0010_xxxx: Hash value(SHA256), RSA signature and other
+ metadata of combined image
+
+ - 0x0018_0000 - 0x0027_FFFF: Secondary slot : Secure + Non-Secure image;
+ Secondary memory partition, structured
+ identically to the primary slot
+ - 0x0028_0000 - 0x0037_FFFF: Scratch area, only used during image
+ swapping
+
+Multiple image boot requires a slightly different layout::
+
+ - 0x0000_0000 - 0x0007_FFFF: BL2 bootloader - MCUBoot
+ - 0x0008_0000 - 0x000F_FFFF: Primary slot : Secure image
+ - 0x0008_0000 - 0x0008_03FF: Secure image header
+ - 0x0008_0400 - 0x000x_xxxx: Secure image
+ - 0x000x_xxxx - 0x000x_xxxx: Hash value(SHA256), RSA signature and other
+ metadata of secure image
+
+ - 0x0010_0000 - 0x0017_FFFF: Primary slot : Non-secure image
+ - 0x0010_0000 - 0x0010_03FF: Non-secure image header
+ - 0x0010_0400 - 0x001x_xxxx: Non-secure image
+ - 0x001x_xxxx - 0x001x_xxxx: Hash value(SHA256), RSA signature and other
+ metadata of non-secure image
+
+ - 0x0018_0000 - 0x001F_FFFF: Secondary slot : Secure image
+ - 0x0020_0000 - 0x0027_FFFF: Secondary slot : Non-secure image
+
+ - 0x0028_0000 - 0x002F_FFFF: Scratch area, only used during image
+ swapping, used for secure and non-secure
+ image as well
+
+**************************
+Firmware upgrade operation
+**************************
+MCUBoot handles only the firmware authenticity check after start-up and the
+firmware switch part of the firmware update process. Downloading the new version
+of the firmware is out-of-scope for MCUBoot. MCUBoot supports three different
+ways to switch to the new firmware and it is assumed that firmware images are
+executed-in-place (XIP). The default behaviour is the overwrite-based image
+upgrade. In this case the active firmware is always executed from the primary
+slot and the secondary slot is a staging area for new images. Before executing
+the new firmware image, the content of the primary slot must be overwritten with
+the content of the secondary slot (the new firmware image). The second option is
+the image swapping strategy when the content of the two memory slots must be
+physically swapped. This needs the scratch area to be defined in the memory
+layout. The third option is the direct execute-in-place version, which
+eliminates the complexity of image swapping and its administration. Active image
+can be executed from either memory slot, but new firmware must be linked to the
+address space of the proper (currently inactive) memory slot.
+
+Overwrite operation
+===================
+Active image is stored in the primary slot, and this image is started always by
+the bootloader. Therefore images must be linked to the primary slot. If the
+bootloader finds a valid image in the secondary slot, which is marked for
+upgrade, then the content of the primary slot will be simply overwritten with
+the content of the secondary slot, before starting the new image from the
+primary slot. After the content of the primary slot has been successfully
+overwritten, the header and trailer of the new image in the secondary slot is
+erased to prevent the triggering of another unnecessary image upgrade after a
+restart. The overwrite operation is fail-safe and resistant to power-cut
+failures. For more details please refer to the MCUBoot
+`documentation <https://www.mcuboot.com/mcuboot/design.html>`__.
+
+Swapping operation
+==================
+This operation can be set with the ``MCUBOOT_UPGRADE_STRATEGY`` compile time
+switch (see `Build time configuration`_). With swapping image upgrade strategy
+the active image is also stored in the primary slot and it will always be
+started by the bootloader. If the bootloader finds a valid image in the
+secondary slot, which is marked for upgrade, then contents of the primary slot
+and the secondary slot will be swapped, before starting the new image from the
+primary slot. Scratch area is used as a temporary storage place during image
+swapping. Update mark from the secondary slot is removed when the swapping is
+successful. The boot loader can revert the swapping as a fall-back mechanism to
+recover the previous working firmware version after a faulty update. The swap
+operation is fail-safe and resistant to power-cut failures. For more details
+please refer to the MCUBoot
+`documentation <https://www.mcuboot.com/mcuboot/design.html>`__.
+
+.. Note::
+
+ After a successful image upgrade the firmware can mark itself as "OK" at
+ runtime by setting the image_ok flag in the flash. When this happens, the
+ swap is made "permanent" and MCUBoot will then still choose to run it
+ during the next boot. Currently TF-M does not set the image_ok flag,
+ therefore the bootloader will always perform a "revert" (swap the images
+ back) during the next boot.
+
+Direct execute-in-place operation
+=================================
+This operation can be set with the ``MCUBOOT_UPGRADE_STRATEGY`` compile time
+switch (see `Build time configuration`_). When enabling direct-xip operation
+then the active image flag is moved between slots during firmware upgrade. If
+firmware is executed-in-place (XIP), then two firmware images must be generated.
+One of them is linked to be executed from the primary slot memory region and the
+other from the secondary slot. The firmware upgrade client, which downloads the
+new image, must be aware, which slot hosts the active firmware and which acts as
+a staging area and it is responsible for downloading the proper firmware image.
+At boot time MCUBoot inspects the version number in the image header and passes
+execution to the newer firmware version. New image must be marked for upgrade
+which is automatically done by Python scripts at compile time. Image
+verification is done the same way in all operational modes. If new image fails
+during authentication then MCUBoot erases the memory slot and starts the other
+image, after successful authentication.
+
+To select which slot the image is to be executed from, set
+``MCUBOOT_EXECUTION_SLOT`` to the desired index. It is suggested that you create
+two build directories when building images using this mode, as intermediate
+dependencies cannot be reused due to changes in the flash layout.
+
+.. Note::
+
+ Only single image boot is supported with direct-xip upgrade mode.
+
+RAM Loading firmware upgrade
+============================
+Musca-S supports an image upgrade mode that is separate to the other (overwrite,
+swapping and dirext-xip) modes. This is the ``RAM load`` mode (please refer
+to the table below). Like the direct-xip mode, this selects the newest image
+by reading the image version numbers in the image headers, but instead of
+executing it in place, the newest image is copied to RAM for execution. The load
+address, the location in RAM where the image is copied to, is stored in the
+image header.
+
+Summary of different modes for image upgrade
+============================================
+Different implementations of the image upgrade operation (whether through
+overwriting, swapping, direct-xip or loading into RAM and executing from
+there) are supported by the platforms. The table below shows which of these
+modes are supported by which platforms:
+
++---------------------+-----------------+----------------------------------------------------------+
+| | Without BL2 [1]_| With BL2 [2]_ |
++=====================+=================+===============+==========+================+==============+
+| | XIP | XIP | XIP | XIP | Not XIP |
++---------------------+-----------------+---------------+----------+----------------+--------------+
+| | | Overwrite [3]_| Swap [4]_| direct-xip [5]_| RAM load [6]_|
++---------------------+-----------------+---------------+----------+----------------+--------------+
+| AN521 | Yes | Yes | Yes | Yes | No |
++---------------------+-----------------+---------------+----------+----------------+--------------+
+| AN519 | Yes | Yes | Yes | Yes | No |
++---------------------+-----------------+---------------+----------+----------------+--------------+
+| FVP_SSE300_MPS3 | No | Yes | Yes | Yes | No |
++---------------------+-----------------+---------------+----------+----------------+--------------+
+| Corstone-310 FVP | Yes | Yes | Yes | Yes | No |
++---------------------+-----------------+---------------+----------+----------------+--------------+
+| LPC55S69 | Yes | Yes | No | Yes | No |
++---------------------+-----------------+---------------+----------+----------------+--------------+
+| Musca-B1 | Yes | Yes | Yes | Yes | No |
++---------------------+-----------------+---------------+----------+----------------+--------------+
+| Musca-S1 | Yes | Yes | Yes | Yes | No |
++---------------------+-----------------+---------------+----------+----------------+--------------+
+| AN524 | Yes | No | No | Yes | No |
++---------------------+-----------------+---------------+----------+----------------+--------------+
+| AN547 | No | Yes | Yes | Yes | No |
++---------------------+-----------------+---------------+----------+----------------+--------------+
+| AN552 | No | Yes | Yes | Yes | No |
++---------------------+-----------------+---------------+----------+----------------+--------------+
+| PSoC64 | Yes | No | No | No | No |
++---------------------+-----------------+---------------+----------+----------------+--------------+
+| STM_DISCO_L562QE | No | Yes | No | No | No |
++---------------------+-----------------+---------------+----------+----------------+--------------+
+| STM_NUCLEO_L552ZE_Q | No | Yes | No | No | No |
++---------------------+-----------------+---------------+----------+----------------+--------------+
+| nRF9160 DK | Yes | Yes | No | No | No |
++---------------------+-----------------+---------------+----------+----------------+--------------+
+| nRF5340 DK | Yes | Yes | No | No | No |
++---------------------+-----------------+---------------+----------+----------------+--------------+
+| BL5340 DVK | Yes | Yes | Yes | No | No |
++---------------------+-----------------+---------------+----------+----------------+--------------+
+| RSS | No | No | No | No | Yes |
++---------------------+-----------------+---------------+----------+----------------+--------------+
+
+.. [1] To disable BL2, please set the ``BL2`` cmake option to ``OFF``
+
+.. [2] BL2 is enabled by default
+
+.. [3] The image executes in-place (XIP) and is in Overwrite mode for image
+ update by default
+
+.. [4] To enable XIP Swap mode, assign the "SWAP_USING_SCRATCH" or
+ "SWAP_USING_MOVE" string to the ``MCUBOOT_UPGRADE_STRATEGY``
+ configuration variable in the build configuration file, or include this
+ macro definition in the command line
+
+.. [5] To enable direct-xip, assign the "DIRECT_XIP" string to the
+ ``MCUBOOT_UPGRADE_STRATEGY`` configuration variable in the build
+ configuration file, or include this macro definition in the command line
+
+.. [6] To enable RAM load, assign the "RAM_LOAD" string to the
+ ``MCUBOOT_UPGRADE_STRATEGY`` configuration variable in the build
+ configuration file, or include this macro definition in the command line
+
+*******************
+Multiple image boot
+*******************
+It is possible to update the firmware images independently to support the
+scenario when secure and non-secure images are provided by different vendors.
+Multiple image boot is supported only together with the overwrite and swap
+firmware upgrade modes.
+
+It is possible to describe the dependencies of the images on each other in
+order to avoid a faulty upgrade when incompatible versions would be installed.
+These dependencies are part of the image manifest area.
+The dependencies are composed from two parts:
+
+ - **Image identifier:** The number of the image which the current image (whose
+ manifest area contains the dependency entry) depends on. The image identifier
+ starts from 0.
+
+ - **Minimum version:** The minimum version of other image must be present on
+ the device by the end of the upgrade (both images might be updated at the
+ same time).
+
+Dependencies can be added to the images at compile time with the following
+compile time switches:
+
+ - ``MCUBOOT_S_IMAGE_MIN_VER`` It is added to the non-secure image and specifies the
+ minimum required version of the secure image.
+ - ``MCUBOOT_NS_IMAGE_MIN_VER`` It is added to the secure image and specifies the
+ minimum required version of the non-secure image.
+
+Example of how to provide the secure image minimum version::
+
+ cmake -DTFM_PLATFORM=arm/musca_b1 -DMCUBOOT_S_IMAGE_MIN_VER=1.2.3+4 ..
+
+********************
+Signature algorithms
+********************
+MbedTLS library is used to sign the images. The list of supported signing
+algorithms:
+
+ - `RSA-2048`
+ - `RSA-3072`: default
+
+Example keys stored in:
+
+ - ``root-RSA-2048.pem`` : Used to sign single image (S+NS) or secure image
+ in case of multiple image boot
+ - ``root-RSA-2048_1.pem`` : Used to sign non-secure image in case of multiple
+ image boot
+ - ``root-RSA-3072.pem`` : Used to sign single image (S+NS) or secure image
+ in case of multiple image boot
+ - ``root-RSA-3072_1.pem`` : Used to sign non-secure image in case of multiple
+ image boot
+
+************************
+Build time configuration
+************************
+MCUBoot related compile time switches can be set by cmake variables.
+
+- BL2 (default: True):
+ - **True:** TF-M built together with bootloader. MCUBoot is executed after
+ reset and it authenticates TF-M and starts secure code.
+ - **False:** TF-M built without bootloader. Secure image linked to the
+ beginning of the device memory and executed after reset. If it is false
+ then using any of the further compile time switches is invalid.
+- MCUBOOT_UPGRADE_STRATEGY (default: "OVERWRITE_ONLY"):
+ - **"OVERWRITE_ONLY":** Default firmware upgrade operation with overwrite.
+ - **"SWAP_USING_SCRATCH":** Activate swapping firmware upgrade operation
+ with a scratch area in flash
+ - **"SWAP_USING_MOVE":** Activate swapping firmware upgrade operation
+ without a scratch area in flash
+ - **"DIRECT_XIP":** Activate direct execute-in-place firmware upgrade
+ operation.
+ - **"RAM_LOAD":** Activate RAM loading firmware upgrade operation, where
+ the latest image is copied to RAM and runs from there instead of being
+ executed in-place.
+- MCUBOOT_SIGNATURE_TYPE (default: RSA):
+ - **RSA:** Image is signed with RSA algorithm
+- MCUBOOT_SIGNATURE_KEY_LEN (default: 3072):
+ - **2048:** Image is signed with 2048 bit key.
+ - **3072:** Image is signed with 3072 bit key.
+- MCUBOOT_IMAGE_NUMBER (default: 2):
+ - **1:** Single image boot, secure and non-secure images are signed and
+ updated together.
+ - **2:** Multiple image boot, secure and non-secure images are signed and
+ updatable independently.
+- MCUBOOT_HW_KEY (default: True):
+ - **True:** The hash of public key is provisioned to the SoC and the image
+ manifest contains the whole public key (imgtool uses
+ ``--public_key_format=full``). MCUBoot validates the key before using it
+ for firmware authentication, it calculates the hash of public key from the
+ manifest and compare against the retrieved key-hash from the hardware.
+ This way MCUBoot is independent from the public key(s). Key(s) can be
+ provisioned any time and by different parties.
+ - **False:** The whole public key is embedded to the bootloader code and the
+ image manifest contains only the hash of the public key (imgtool uses
+ ``--public_key_format=hash``). MCUBoot validates the key before using it
+ for firmware authentication, it calculates the hash of built-in public key
+ and compare against the retrieved key-hash from the image manifest. After
+ this the bootloader can verify that the image was signed with a private
+ key that corresponds to the retrieved key-hash (it can have more public
+ keys embedded in and it may have to look for the matching one). All the
+ public key(s) must be known at MCUBoot build time.
+- MCUBOOT_LOG_LEVEL:
+ Can be used to configure the level of logging in MCUBoot. The possible
+ values are the following:
+
+ - **OFF**
+ - **ERROR**
+ - **WARNING**
+ - **INFO**
+ - **DEBUG**
+
+ The logging in MCUBoot can be disabled and thus the code size can be reduced
+ by setting it to ``OFF``. Its value depends on the build type. If the build
+ type is ``Debug`` then default value is ``INFO``. In case of different kinds
+ of ``Release`` builds the default value is ``OFF``. The default value can
+ be overridden through the command line or in the CMake GUI regardless of the
+ build type.
+- MCUBOOT_ENC_IMAGES (default: False):
+ - **True:** Adds encrypted image support in the source and encrypts the
+ resulting image using the ``enc-rsa2048-pub.pem`` key found in the MCUBoot
+ repository.
+ - **False:** Doesn't add encrypted image support and doesn't encrypt the
+ image.
+
+ .. Note::
+ The decryption takes place during the upgrade process, when the images
+ are being moved between the slots. This means that boards that don't
+ already have an image on them with MCUBoot that has been compiled with
+ ``MCUBOOT_ENCRYPT_RSA`` enabled need special treatment. In order to load
+ an encrypted image to such boards, an upgrade needs to be executed. This
+ can be done by using MCUBoot, putting an image in the secondary image
+ area, and setting ``MCUBOOT_ENCRYPT_RSA`` to ``ON``. When using the
+ ``OVERWRITE_ONLY`` upgrade strategy, this is enough. When using
+ ``SWAP_USING_SCRATCH`` or ``SWAP_USING_MOVE``, an image is needed in
+ the primary image area as well, to trigger the update.
+
+ .. Danger::
+ DO NOT use the ``enc-rsa2048-pub.pem`` key in production code, it is
+ exclusively for testing!
+
+Image versioning
+================
+An image version number is written to its header by one of the Python scripts,
+and this number is used by the bootloader when the direct execute-in-place or
+the RAM loading mode is enabled. It is also used in case of multiple image boot
+when the bootloader checks the image dependencies if any have been added to the
+images.
+
+The version number of the image (single image boot) can manually be passed in
+through the command line in the cmake configuration step::
+
+ cmake -DTFM_PLATFORM=arm/musca_b1 -DIMAGE_VERSION_S=1.2.3+4 ..
+
+Alternatively, the version number can be less specific (e.g 1, 1.2, or 1.2.3),
+where the missing numbers are automatically set to zero. The image version
+number argument is optional, and if it is left out, then the version numbers of
+the image(s) being built in the same directory will automatically change. In
+this case, the last component (the build number) automatically increments from
+the previous one: 0.0.0+1 -> 0.0.0+2, for as many times as the build is re-ran,
+**until a number is explicitly provided**. If automatic versioning is in place
+and then an image version number is provided for the first time, the new number
+will take precedence and be used instead. All subsequent image versions are
+then set to the last number that has been specified, and the build number would
+stop incrementing. Any new version numbers that are provided will overwrite
+the previous one: 0.0.0+1 -> 0.0.0+2. Note: To re-apply automatic image
+versioning, please start a clean build without specifying the image version
+number at all. In case of multiple image boot there are separate compile time
+switches for both images to provide their version: ``IMAGE_VERSION_S`` and
+``IMAGE_VERSION_NS``. These must be used instead of ``IMAGE_VERSION_S``.
+
+Security counter
+================
+Each signed image contains a security counter in its manifest. It is used by the
+bootloader and its aim is to have an independent (from the image version)
+counter to ensure rollback protection by comparing the new image's security
+counter against the original (currently active) image's security counter during
+the image upgrade process. It is added to the manifest (to the TLV area that is
+appended to the end of the image) by one of the Python scripts when signing the
+image. The value of the security counter is security critical data and it is in
+the integrity protected part of the image. The last valid security counter
+should always be stored in a non-volatile and trusted component of the device
+and its value should always be increased if a security flaw was fixed in the
+current image version. The value of the security counter (single image boot) can
+be specified at build time in the cmake configuration step::
+
+ cmake -DTFM_PLATFORM=arm/musca_b1 -DSECURITY_COUNTER_S=42 ../
+
+The security counter can be independent from the image version, but not
+necessarily. Alternatively, if it is not specified at build time with the
+``SECURITY_COUNTER`` option the Python script will automatically generate it
+from the image version number (not including the build number) and this value
+will be added to the signed image. In case of multiple image boot there are
+separate compile time switches for both images to provide their security counter
+value: ``SECURITY_COUNTER_S`` and ``SECURITY_COUNTER_NS``. These must be used
+instead of ``SECURITY_COUNTER_S``. If these are not defined then the security
+counter values will be derived from the corresponding image version similar to
+the single image boot.
+
+***************************
+Signing the images manually
+***************************
+Normally the build system handles the signing (computing hash over the image
+and security critical manifest data and then signing the hash) of the firmware
+images. However, the images also can be signed manually by using the ``imgtool``
+Python program which is located in the MCUboot repository in the ``scripts``
+folder or can be installed with the pip package manager.
+Issue the ``python3 imgtool.py sign --help`` command in the directory for more
+information about the mandatory and optional arguments. The tool takes an image
+in binary or Intel Hex format and adds a header and trailer that MCUBoot is
+expecting. In case of single image boot after a successful build the
+``tfm_s_ns.bin`` build artifact (contains the concatenated secure and non-secure
+images) must be passed to the script and in case of multiple image boot the
+``tfm_s.bin`` and ``tfm_ns.bin`` binaries can be passed to prepare the signed
+images.
+
+Signing the secure image manually in case of multiple image boot
+================================================================
+
+::
+
+ python3 bl2/ext/mcuboot/scripts/imgtool.py sign \
+ --layout <build_dir>/bl2/ext/mcuboot/CMakeFiles/signing_layout_s.dir/signing_layout_s.c.obj \
+ -k <tfm_dir>/bl2/ext/mcuboot/root-RSA-3072.pem \
+ --public-key-format full \
+ --align 1 \
+ -v 1.2.3+4 \
+ -d "(1,1.2.3+0)" \
+ -s 42 \
+ -H 0x400 \
+ <build_dir>/bin/tfm_s.bin \
+ <build_dir>/bin/tfm_s_signed.bin
+
+************************
+Testing firmware upgrade
+************************
+As downloading the new firmware image is out of scope for MCUBoot, the update
+process is started from a state where the original and the new image are already
+programmed to the appropriate memory slots. To generate the original and a new
+firmware package, TF-M is built twice with different build configurations.
+
+Overwriting firmware upgrade
+============================
+Run TF-M build twice with ``MCUBOOT_IMAGE_NUMBER`` set to "1" in both cases
+(single image boot), but with two different build configurations: default and
+regression. Save the artifacts between builds, because second run can overwrite
+original binaries. Download default build to the primary slot and regression
+build to the secondary slot.
+
+Executing firmware upgrade on FVP_MPS2_AEMv8M
+---------------------------------------------
+.. code-block:: bash
+
+ <ARM_DS_PATH>/sw/models/bin/FVP_MPS2_AEMv8M \
+ --parameter fvp_mps2.platform_type=2 \
+ --parameter cpu0.baseline=0 \
+ --parameter cpu0.INITVTOR_S=0x10000000 \
+ --parameter cpu0.semihosting-enable=0 \
+ --parameter fvp_mps2.DISABLE_GATING=0 \
+ --parameter fvp_mps2.telnetterminal0.start_telnet=1 \
+ --parameter fvp_mps2.telnetterminal1.start_telnet=0 \
+ --parameter fvp_mps2.telnetterminal2.start_telnet=0 \
+ --parameter fvp_mps2.telnetterminal0.quiet=0 \
+ --parameter fvp_mps2.telnetterminal1.quiet=1 \
+ --parameter fvp_mps2.telnetterminal2.quiet=1 \
+ --application cpu0=<build_dir>/bin/bl2.axf \
+ --data cpu0=<default_build_dir>/bin/tfm_s_ns_signed.bin@0x10080000 \
+ --data cpu0=<regresssion_build_dir>/bin/tfm_s_ns_signed.bin@0x10180000
+
+Executing firmware upgrade on SSE 200 FPGA on MPS2 board
+--------------------------------------------------------
+
+::
+
+ TITLE: Versatile Express Images Configuration File
+ [IMAGES]
+ TOTALIMAGES: 3 ;Number of Images (Max: 32)
+ IMAGE0ADDRESS: 0x00000000
+ IMAGE0FILE: \Software\bl2.axf ; BL2 bootloader
+ IMAGE1ADDRESS: 0x10080000
+ IMAGE1FILE: \Software\tfm_sig1.bin ; TF-M default test binary blob
+ IMAGE2ADDRESS: 0x10180000
+ IMAGE2FILE: \Software\tfm_sig2.bin ; TF-M regression test binary blob
+
+The following message will be shown in case of successful firmware upgrade:
+
+::
+
+ [INF] Starting bootloader
+ [INF] Swap type: test
+ [INF] Image upgrade secondary slot -> primary slot
+ [INF] Erasing the primary slot
+ [INF] Copying the secondary slot to the primary slot: 0x100000 bytes
+ [INF] Bootloader chainload address offset: 0x80000
+ [INF] Jumping to the first image slot
+ [Sec Thread] Secure image initializing!
+
+ #### Execute test suites for the Secure area ####
+ Running Test Suite PSA protected storage S interface tests (TFM_PS_TEST_2XXX)...
+ ...
+
+To update the secure and non-secure images separately (multiple image boot),
+set the ``MCUBOOT_IMAGE_NUMBER`` switch to "2" (this is the default
+configuration value) and follow the same instructions as in case of single image
+boot.
+
+Executing multiple firmware upgrades on SSE 200 FPGA on MPS2 board
+------------------------------------------------------------------
+
+::
+
+ TITLE: Versatile Express Images Configuration File
+ [IMAGES]
+ TOTALIMAGES: 4 ;Number of Images (Max: 32)
+ IMAGE0ADDRESS: 0x00000000
+ IMAGE0FILE: \Software\bl2.axf ; BL2 bootloader
+ IMAGE1ADDRESS: 0x10080000
+ IMAGE1FILE: \Software\tfm_sign.bin ; TF-M default test binary blob
+ IMAGE2ADDRESS: 0x10180000
+ IMAGE2FILE: \Software\tfm_ss1.bin ; TF-M regression test secure (signed) image
+ IMAGE3ADDRESS: 0x10200000
+ IMAGE3FILE: \Software\tfm_nss1.bin ; TF-M regression test non-secure (signed) image
+
+Note that both the concatenated binary blob (the images are signed separately
+and then concatenated) and the separate signed images can be downloaded to the
+device because on this platform (AN521) both the primary slots and the secondary
+slots are contiguous areas in the Flash (see `Integration with TF-M`_). The
+following message will be shown in case of successful firmware upgrades:
+
+::
+
+ [INF] Starting bootloader
+ [INF] Swap type: test
+ [INF] Swap type: test
+ [INF] Image upgrade secondary slot -> primary slot
+ [INF] Erasing the primary slot
+ [INF] Copying the secondary slot to the primary slot: 0x80000 bytes
+ [INF] Image upgrade secondary slot -> primary slot
+ [INF] Erasing the primary slot
+ [INF] Copying the secondary slot to the primary slot: 0x80000 bytes
+ [INF] Bootloader chainload address offset: 0x80000
+ [INF] Jumping to the first image slot
+ [Sec Thread] Secure image initializing!
+ TFM level is: 1
+ [Sec Thread] Jumping to non-secure code...
+
+ #### Execute test suites for the Secure area ####
+ Running Test Suite PSA protected storage S interface tests (TFM_PS_TEST_2XXX)...
+ ...
+
+Swapping firmware upgrade
+=============================
+Follow the same instructions and platform related configurations as in case of
+overwriting build including these changes:
+
+- Set the ``MCUBOOT_UPGRADE_STRATEGY`` compile time switch to "SWAP"
+ before build.
+- Set the ``MCUBOOT_IMAGE_NUMBER`` compile time switch to "1" (single image
+ boot) or "2" (multiple image boot) before build.
+
+During single image boot the following message will be shown in case of
+successful firmware upgrade, ``Swap type: test`` indicates that images were
+swapped:
+
+::
+
+ [INF] Starting bootloader
+ [INF] Image 0: magic= good, copy_done=0x3, image_ok=0x3
+ [INF] Scratch: magic= bad, copy_done=0x0, image_ok=0x2
+ [INF] Boot source: primary slot
+ [INF] Swap type: test
+ [INF] Bootloader chainload address offset: 0x80000
+ [INF] Jumping to the first image slot
+ [Sec Thread] Secure image initializing!
+
+ #### Execute test suites for the Secure area ####
+ Running Test Suite PSA protected storage S interface tests (TFM_PS_TEST_2XXX)...
+ ...
+
+Direct execute-in-place firmware upgrade
+========================================
+Follow the same instructions and platform related configurations as in case of
+overwriting build including these changes:
+
+- Set the ``MCUBOOT_UPGRADE_STRATEGY`` compile time switch to "DIRECT_XIP"
+ before build.
+- set ``MCUBOOT_EXECUTION_SLOT`` to ``1`` in the regression build dir.
+- Make sure the image version number was increased between the two build runs
+ either by specifying it manually or by checking in the build log that it was
+ incremented automatically.
+
+Executing firmware upgrade on FVP_MPS2_AEMv8M
+---------------------------------------------
+
+.. code-block:: bash
+
+ <ARM_DS_PATH>/sw/models/bin/FVP_MPS2_AEMv8M \
+ --parameter fvp_mps2.platform_type=2 \
+ --parameter cpu0.baseline=0 \
+ --parameter cpu0.INITVTOR_S=0x10000000 \
+ --parameter cpu0.semihosting-enable=0 \
+ --parameter fvp_mps2.DISABLE_GATING=0 \
+ --parameter fvp_mps2.telnetterminal0.start_telnet=1 \
+ --parameter fvp_mps2.telnetterminal1.start_telnet=0 \
+ --parameter fvp_mps2.telnetterminal2.start_telnet=0 \
+ --parameter fvp_mps2.telnetterminal0.quiet=0 \
+ --parameter fvp_mps2.telnetterminal1.quiet=1 \
+ --parameter fvp_mps2.telnetterminal2.quiet=1 \
+ --application cpu0=<build_dir>/bin/bl2.axf \
+ --data cpu0=<default_build_dir>/bin/tfm_s_ns_signed.bin@0x10080000 \
+ --data cpu0=<regresssion_build_dir>/bin/tfm_s_ns_signed.bin@0x10180000
+
+Executing firmware upgrade on SSE 200 FPGA on MPS2 board
+--------------------------------------------------------
+
+::
+
+ TITLE: Versatile Express Images Configuration File
+ [IMAGES]
+ TOTALIMAGES: 3 ;Number of Images (Max: 32)
+ IMAGE0ADDRESS: 0x00000000
+ IMAGE0FILE: \Software\bl2.axf ; BL2 bootloader
+ IMAGE1ADDRESS: 0x10080000
+ IMAGE1FILE: \Software\tfm_sign.bin ; TF-M default test binary blob
+ IMAGE2ADDRESS: 0x10180000
+ IMAGE2FILE: \Software\tfm_sig1.bin ; TF-M regression test binary blob
+
+Executing firmware upgrade on Musca-B1 and Musca-S1 boards
+----------------------------------------------------------
+After the two images have been built, they can be concatenated to create the
+combined image using ``srec_cat``:
+
+- Linux::
+
+ srec_cat bin/bl2.bin -Binary -offset 0xA000000 tfm_sign.bin -Binary -offset 0xA020000 tfm_sign_1.bin -Binary -offset 0xA100000 -o tfm.hex -Intel
+
+- Windows::
+
+ srec_cat.exe bin\bl2.bin -Binary -offset 0xA000000 tfm_sign.bin -Binary -offset 0xA020000 tfm_sign_1.bin -Binary -offset 0xA100000 -o tfm.hex -Intel
+
+The following message will be shown in case of successful firmware upgrade,
+notice that image with higher version number (``version=1.2.3.5``) is executed:
+
+::
+
+ [INF] Starting bootloader
+ [INF] Image 0: version=1.2.3.4, magic= good, image_ok=0x3
+ [INF] Image 1: version=1.2.3.5, magic= good, image_ok=0x3
+ [INF] Booting image from the secondary slot
+ [INF] Bootloader chainload address offset: 0xa0000
+ [INF] Jumping to the first image slot
+ [Sec Thread] Secure image initializing!
+
+ #### Execute test suites for the Secure area ####
+ Running Test Suite PSA protected storage S interface tests (TFM_PS_TEST_2XXX)...
+ ...
+
+Executing firmware upgrade on CoreLink SSE-200 Subsystem for MPS3 (AN524)
+-------------------------------------------------------------------------
+
+::
+
+ TITLE: Arm MPS3 FPGA prototyping board Images Configuration File
+
+ [IMAGES]
+ TOTALIMAGES: 3 ;Number of Images (Max: 32)
+
+ IMAGE0UPDATE: AUTO ;Image Update:NONE/AUTO/FORCE
+ IMAGE0ADDRESS: 0x00000000
+ IMAGE0FILE: \SOFTWARE\bl2.bin ;BL2 bootloader
+ IMAGE1UPDATE: AUTO
+ IMAGE1ADDRESS: 0x00040000
+ IMAGE1FILE: \SOFTWARE\tfm_sig0.bin ;TF-M example application binary blob
+ IMAGE2UPDATE: AUTO
+ IMAGE2ADDRESS: 0x000C0000
+ IMAGE2FILE: \SOFTWARE\tfm_sig1.bin ;TF-M regression test binary blob
+
+RAM loading firmware upgrade
+============================
+To enable RAM loading, please set ``MCUBOOT_UPGRADE_STRATEGY`` to "RAM_LOAD"
+(either in the configuration file or through the command line), and then specify
+a destination load address in RAM where the image can be copied to and executed
+from. The ``S_IMAGE_LOAD_ADDRESS`` macro must be specified in the target
+dependent files, and if multiple image boot is enabled then
+``NS_IMAGE_LOAD_ADDRESS`` must also be defined. For example with Musca-S, its
+``flash_layout.h`` file in the ``platform`` folder should include ``#define
+S_IMAGE_LOAD_ADDRESS #0xA0020000``
+
+Executing firmware upgrade on Musca-S board
+--------------------------------------------
+After two images have been built, they can be concatenated to create the
+combined image using ``srec_cat``:
+
+- Linux::
+
+ srec_cat bin/bl2.bin -Binary -offset 0xA000000 tfm_sign_old.bin -Binary -offset 0xA020000 tfm_sign_new.bin -Binary -offset 0xA100000 -o tfm.hex -Intel
+
+- Windows::
+
+ srec_cat.exe bin\bl2.bin -Binary -offset 0xA000000 tfm_sign_old.bin -Binary -offset 0xA020000 tfm_sign_new.bin -Binary -offset 0xA100000 -o tfm.hex -Intel
+
+The following message will be shown in case of successful firmware upgrade when,
+RAM loading is enabled, notice that image with higher version number
+(``version=0.0.0.2``) is executed:
+
+::
+
+ [INF] Starting bootloader
+ [INF] Image 0: version=0.0.0.1, magic= good, image_ok=0x3
+ [INF] Image 1: version=0.0.0.2, magic= good, image_ok=0x3
+ [INF] Image has been copied from the secondary slot in flash to SRAM address 0xA0020000
+ [INF] Booting image from SRAM at address 0xA0020000
+ [INF] Bootloader chainload address offset: 0x20000
+ [INF] Jumping to the first image slot
+ [Sec Thread] Secure image initializing!
+
+--------------
+
+****************************************
+Integration with Firmware Update service
+****************************************
+The shim layer of the Firmware Update partition calls the APIs in
+bootutil_misc.c to control the image status.
+
+- Call ``boot_set_pending_multi()`` to make the image as a candidate image for
+ booting.
+- Call ``boot_set_confirmed_multi()`` to make the image as a permanent image.
+
+.. Note::
+ Currently, in direct-xip mode and ram-load mode, TF-M cannot get the
+ information of which slot contains the running image from the bootloader.
+ So the Firmware Update partition cannot decide where to write the new
+ image. As a result, the firmware update service is not supported in
+ direct-xip mode and ram-load mode.
+
+*Copyright (c) 2018-2022, Arm Limited. All rights reserved.*
diff --git a/docs/design_docs/tfm_secure_partition_runtime_library.rst b/docs/design_docs/tfm_secure_partition_runtime_library.rst
new file mode 100644
index 0000000..6df1c28
--- /dev/null
+++ b/docs/design_docs/tfm_secure_partition_runtime_library.rst
@@ -0,0 +1,361 @@
+################################
+Secure Partition Runtime Library
+################################
+
+:Organization: Arm Limited
+:Contact: tf-m@lists.trustedfirmware.org
+
+**********
+Background
+**********
+Trusted Firmware - M (TF-M) uses a toolchain provided runtime library and
+supervisor calls to easily implement the PSA Firmware Framework (PSA FF) API.
+This working model works well under isolation level 1 since there are no data
+isolation requirements. While TF-M is evolving, this model is not suitable
+because:
+
+ - The high-level isolation requires isolating data but some toolchain library
+ interfaces have their own global data which cannot be shared between the
+ Secure Partitions.
+ - The toolchain libraries are designed without taking security as a core
+ design principle.
+
+A TF-M specific runtime library is needed for the following reasons:
+
+ - Easier evaluation or certification by security standards.
+ - Source code transparency.
+ - Sharing code to save ROM and RAM space for TF-M.
+
+PSA FF specification also describes the requirements of C runtime API for Secure
+Partitions.
+
+This runtime library is named the ``Secure Partition Runtime Library``, and the
+abbreviation is ``SPRTL``.
+
+****************
+Design Principal
+****************
+The following requirements are mandatory for SPRTL implementation:
+
+.. important::
+ - **CODE ONLY** - No read-write data should be introduced into runtime library
+ implementation.
+ - **Thread safe** - All functions are designed with thread-safe consideration.
+ These APIs access caller stack and caller provided memory only.
+ - **Isolation** - Runtime API code is set as executable and read-only in
+ higher isolation levels.
+ - **Security first** - SPRTL is designed for security and it may come with
+ some performance loss.
+
+API Categories
+==============
+Several known types of functions are included in SPRTL:
+
+ - C runtime API.
+ - RoT Service API.
+ - PSA Client and Service API.
+ - [Future expansion, to be detailed later] other secure API.
+
+Security Implementation Requirements
+------------------------------------
+If ``malloc/realloc/free`` are provided, they must obey additional requirements
+compared to the C standard: newly allocated memory must be initialized to
+ZERO, and freed memory must be wiped immediately in case the block contains
+sensitive data.
+
+The comparison API ('memcmp' e.g.), they should not return immediately when the
+fault case is detected. The implementation should execute in linear time based
+on input to avoid execution timing side channel attack.
+
+The pointer validation needs to be considered. In general, at least the
+'non-NULL' checking is mandatory. A detection for invalid pointer leads to a
+``psa_panic()``.
+
+The following section describes the first 3 API types and the implementation
+requirements.
+
+C Runtime API
+-------------
+PSA FF describes a small set of the C standard library. Part of toolchain
+library API can be used as default if these APIs meet the `Design Principal`_
+and `Security Implementation Requirements`_. The toolchain 'header' and 'types'
+can be reused to simplify the implementation.
+
+These APIs can take the toolchain provided version, or separately implemented
+in case there are extra requirements:
+
+.. note::
+ - 'memcpy()/memmove()/memset()'
+ - String API
+
+These APIs are proposed to be implemented with the security consideration
+mentioned in `Security Implementation Requirements`_:
+
+.. note::
+ - 'memcmp()'
+ - Other comparison API if referenced ('strcmp' e.g.).
+
+The following functions are optional, but if present, they must conform to
+additional `Security Implementation Requirements`_:
+
+.. note::
+ - 'malloc()/free()/realloc()'
+ - 'assert()/printf()'
+
+The following APIs are coupled with toolchain library much so applying toolchain
+library implementation is recommended:
+
+.. note::
+ - Division and modulo - arithmetic operations.
+ - Other low level or compiler specific functions (such as 'va_list').
+
+Besides the APIs mentioned above, the following runtime APIs are required for
+runtime APIs with private runtime context ('malloc' e.g.):
+
+.. note::
+ - '__sprtmain()' - partition entry runtime wrapper.
+
+RoT Service API
+---------------
+The description of RoT Service API in PSA FF:
+
+.. note::
+ Arm recommends that the RoT Service developer also defines an RoT Service API
+ and implementation to encapsulate the use of the IPC protocol, and improve the
+ usability of the service for client firmware.
+
+Part of the RoT Service API have proposed specifications, such as the PSA
+Cryptography API, PSA Storage API, and PSA Attestation API. It is suggested that
+the service developer create documents of their RoT Service API and make them
+publicly available.
+
+The RoT Service API has a large amount and it is the main part of SPRTL. This
+chapter describes the general implementation of the RoT Service API and the
+reason for putting them into SPRTL.
+
+In general, a client uses the PSA Client API to access a secure service.
+For example:
+
+.. code-block:: c
+
+ /* Example, not a real implementation */
+ caller_status_t psa_example_service(void)
+ {
+ ...
+ handle = psa_connect(SERVICE_SID, SERVICE_VERSION);
+ if (INVALID_HANDLE(handle)) {
+ return INVALID_RETURN;
+ }
+
+ status = psa_call(handle, type, invecs, inlen, outvecs, outlen);
+
+ psa_close(handle);
+
+ return TO_CALLER_STATUS(status);
+ }
+
+This example encapsulates the PSA Client API, and can be provided as a simpler
+and more generic API for clients to call. It is not possible to statically link
+this API to each Secure Partition because of the limited storage space. The
+ideal solution is to put it inside SPRTL and share it to all Secure Partitions.
+This would simplify the caller logic into this:
+
+.. code-block:: c
+
+ if (psa_example_service() != STATUS_SUCCESS) {
+ /* do something */
+ }
+
+This is the simplest case of encapsulating PSA Client API. If a RoT Service API
+is connect heavy, then, the encapsulation can be changed to include a connection
+handle inside a context data structure. This context data structure type is
+defined in RoT Service headers and the instance is allocated by API caller since
+API implementation does not have private data.
+
+.. note::
+ - Even the RoT Service APIs are provided in SPRTL for all clients, the SPM
+ performs the access check eventually and decides if the access to service
+ can be processed.
+ - For those RoT Service APIs only get called by a specific client, they can be
+ implemented inside the caller client, instead of putting it into SPRTL.
+
+PSA Client and Service API
+--------------------------
+Most of the PSA APIs can be called directly with supervisor calls. The only
+special function is ``psa_call``, because it has **6** parameters. This makes
+the supervisor call handler complex because it has to extract the parameters
+from the stack. The definition of psa_call is the following:
+
+.. code-block:: c
+
+ psa_status_t psa_call(psa_handle_t handle, int32_t type,
+ const psa_invec *in_vec, size_t in_len,
+ psa_outvec *out_vec, size_t out_len);
+
+The parameters need to be packed to avoid passing parameters on the stack, and
+the supervisor call needs to unpack the parameters back to **6** for subsequent
+processing.
+
+Privileged Access Supporting
+============================
+Due to specified API (printf, e.g.) need to access privileged resources, TF-M
+Core needs to provide interface for the resources accessing. The permission
+checking must happen in Core while caller is calling these interface.
+
+Secure Partition Scratch Area
+=============================
+For the API needs partition specific private data, there needs to be a way to
+pass the partition specific data for the API. Use C language preprocessor to
+forward the existing prototype declaration can work, but it has the risks of
+breaking the build since this method needs compilers support ('-include' e.g.).
+Furthermore, no valid runtime tricks can work due to these limitations on
+M-profile architecture:
+
+.. note::
+ - We cannot apply the aligned mask on a stack address to get stack bottom
+ where the private data pointer stands. This is because aligned stack bottom
+ is not supported.
+ - We cannot read special registers such as 'PSPLIMIT' for retrieving the
+ private data pointer while executing in unprivileged mode.
+ - Furthermore, some earlier versions of the ARM architecture do not have
+ certain special-purpose registers ('PSPLIMIT' etc.).
+
+A system-provided scratch area is a precondition for implementing APIs that need
+to access private data (such as 'malloc'). The requirements for implementing
+such an area are:
+
+.. important::
+ - The area must be ``READ-ONLY`` for the running Secure Partition.
+ - The SPM must put the running Secure Partition's metadata into this area
+ while scheduling.
+
+With these requirements, the passed parameters can be retrieved by SPRTL easily
+with a read operation on the fixed memory address.
+
+Tooling Support on Partition Entry
+==================================
+PSA FF requires each Secure Partition to have an entry point. For example:
+
+.. code-block:: c
+
+ /* The entry point function must not return. */
+ void entry_point(void);
+
+Each partition has its own dedicated metadata for heap tracking and other
+runtime state. The metadata is designed to be saved at the read-write data area
+of a partition with a specific name. A generic entry point needs to be available
+to get partition metadata and do initialization before calling into the actual
+partition entry. This generic entry point is defined as '__sprtmain':
+
+.. code-block:: c
+
+ void __sprtmain(void)
+ {
+ /* Get current SP private data from scratch area */
+ struct sprt_meta_t *m = (struct sprt_meta_t *)tfm_sprt_scratch_data;
+
+ /* Potential heap init - check later chapter */
+ if (m->heap_size) {
+ m->heap_instance = tfm_sprt_heap_init(m->heap_sa, m->heap_sz);
+ }
+
+ /* Call thread entry 'entry_point' */
+ m->thread_entry();
+
+ /* SVC back to tell Core end this thread */
+ SVC(THREAD_EXIT);
+ }
+
+Since SPM is not aware of the '__sprtmain' in SPRTL, it just calls into the
+entry point listed in partition runtime data structure. And the partition writer
+may be not aware of running of '__sprtmain' as the generic wrapper entry,
+tooling support needs to happen to support this magic. Here is an example of
+partition manifest:
+
+.. code-block:: sh
+
+ {
+ "name": "TFM_SP_SERVICE",
+ "type": "PSA-ROT",
+ "priority": "NORMAL",
+ "entry_point": "tfm_service_entry",
+ "stack_size": "0x1800",
+ "heap_size": "0x1000",
+ ...
+ }
+
+Tooling would do manipulation to tell SPM the partition entry as '__sprtmain',
+and TF-M SPM would switch the activated metadata into the scratch area. Finally,
+the partition entry point gets called and run, tooling helps on the decoupling
+of SPM and SPRTL implementation. The pseudo code of a tooling result:
+
+.. code-block:: c
+
+ struct partition_t sp1 {
+ .name = "TFM_SP_SERVICE",
+ .type = PSA_ROT,
+ .priority = NORMAL,
+ .id = 0x00000100,
+ .entry_point = __sprtmain, /* Tell SPM entry is '__sprtmain' */
+ .metadata = { /* struct sprt_meta_t */
+ .heap_sa = sp1_heap_buf,
+ .heap_sz = sizeof(sp1_heap_buf),
+ .thread_entry = sp1_entry, /* Actual Partition Entry */
+ .heap_instance = NULL,
+ },
+ }
+
+Implementation
+==============
+The SPRTL C Runtime sources are put under:
+'$TFM_ROOT/secure_fw/partitions/lib/runtime/'
+
+The output of this folder is a static library named as 'libtfm_sprt.a'. The code
+of 'libtfm_sprt.a' is put into a dedicated section so that a hardware protected
+region can be applied to contain it.
+
+The RoT Service API are put under service interface folder. These APIs are
+marked with the same section attribute where 'libtfm_sprt.a' is put.
+
+The Formatting API - 'printf' and variants
+------------------------------------------
+The 'printf' and its variants need special parameters passing mechanism. To
+implement these APIs, the toolchain provided builtin macro 'va_list', 'va_start'
+and 'va_end' cannot be avoided. This is because of some scenarios such as when
+'stack canaries' are enabled, only the compiler knows the format of the 'canary'
+in order to extract the parameters correctly.
+
+To provide a simple implementation, the following requirements are defined for
+'printf':
+
+- Format keyword 'xXduscp' needs to be supported.
+- Take '%' as escape flag, '%%' shows a '%' in the formatted string.
+- To save heap usage, 32 bytes buffer in the stack for collecting formatted
+ string.
+- Flush string outputting due to: a) buffer full b) function ends.
+
+The interface for flushing can be a logging device.
+
+Function with Implied Parameters
+--------------------------------
+Take 'malloc' as an example. There is only one parameter for 'malloc' in
+the prototype. Heap management code is put in the SPRTL for sharing with caller
+partitions. The heap instance belongs to each partition, which means this
+instance needs to be passed into the heap management code as a parameter. For
+allocation API in heap management, it needs two parameters - 'size' and
+'instance', while for 'malloc' caller it needs a 'malloc' with one parameter
+'size' only. As mentioned in the upper chapter, this instance can be retrieved
+from the Secure Partition scratch area. The implementation can be:
+
+.. code-block:: c
+
+ void *malloc(size_t sz)
+ {
+ struct sprt_meta_t *m = (struct sprt_meta_t *)tfm_sprt_scratch_data;
+
+ return tfm_sprt_alloc(m->heap_instance, sz);
+ }
+
+--------------
+
+*Copyright (c) 2019-2020, Arm Limited. All rights reserved.*
diff --git a/docs/design_docs/tfm_uniform_secure_service_signature.rst b/docs/design_docs/tfm_uniform_secure_service_signature.rst
new file mode 100644
index 0000000..28e3d8f
--- /dev/null
+++ b/docs/design_docs/tfm_uniform_secure_service_signature.rst
@@ -0,0 +1,113 @@
+################################
+Uniform Secure Service Signature
+################################
+
+:Author: Miklos Balint
+:Organization: Arm Limited
+:Contact: Miklos Balint <miklos.balint@arm.com>
+
+**********************************
+Declaring secure service interface
+**********************************
+
+The following alternative secure service signature is proposed as an
+amendment to existing implementation.
+
+Individual signatures - current method
+======================================
+
+A ``<service_name>_veneers.c`` file is created in the ``secure_fw/ns_callable``
+directory, that specifies the signature for each veneer function, and calls the
+secure function from the veneers. The respective
+``interface/include/<service_name>_veneers.h`` file with the veneer declarations
+have to be created and maintained manually.
+Note that at present TF-M framework limits the range of valid return values a
+secure service can provide, reserving a range for framework error codes.
+
+Uniform signatures - proposal
+=============================
+
+The proposal is to use a uniform signature for all the secure functions of the
+secure service. There are multiple advantages of this method:
+
+- TF-M Core can do a sanity check on the access rights of the veneer
+ parameters, and there is no need for the secure services to make these checks
+ individually. Please note that in the present implementation sanity check is
+ only fully supported for level 1 isolation.
+
+- The veneer declarations and implementations for the secure functions can be
+ generated automatically from a template (using the secure function list in the
+ secure service's manifest)
+
+The signature for such secure services would look like this:
+
+.. code-block:: c
+
+ psa_status_t secure_function_name(struct psa_invec *in_vec, size_t in_len,
+ struct psa_outvec *out_vec, size_t out_len);
+
+where
+
+Return value:
+-------------
+
+``psa_status_t`` is a status code whose values are described in PSA Firmware
+Framework (as in version 1.0-beta-0 chapter 4.3.3).
+
+Note:
+-----
+The return value limitations imposed by TF-M framework for proprietary
+secure service veneers would not apply to secure services using the uniform
+signature. This is analogous to how PSA Firmware Framework handles values
+returned by ``psa_reply()`` function.
+
+Arguments:
+----------
+
+.. code-block:: c
+
+ /**
+ * A read-only input memory region provided to a RoT Service.
+ */
+ typedef struct psa_invec {
+ const void *base; /*!< the start address of the memory buffer */
+ size_t len; /*!< the size in bytes */
+ } psa_invec;
+
+ /**
+ * A writable output memory region provided to a RoT Service.
+ */
+ typedef struct psa_outvec {
+ void *base; /*!< the start address of the memory buffer */
+ size_t len; /*!< the size in bytes */
+ } psa_outvec;
+
+ /**
+ * in_len: the number of input parameters, i.e. psa_invecs
+ * out_len: the number of output parameters, i.e. psa_outvecs
+ */
+
+The number of vectors that can be passed to a secure service is constrained:
+
+.. code-block:: c
+
+ in_len + out_len <= PSA_MAX_IOVEC
+
+The veneer function declarations and implementations are generated in the
+``interface/include/tfm_veneers.h`` and ``secure_fw\ns_callable\tfm_veneers.c``
+files respectively. The veneer functions are created with the name
+``tfm_<secure_function_name>_veneer``
+
+Services that implement the uniform signature do not need to manually fill
+the template veneer function to call ``TFM_CORE_SFN_REQUEST`` macro.
+
+*************
+Compatibility
+*************
+
+Note that the proposal is for the two types of services (those with proprietary
+signatures and those with uniform signatures) to co-exist, with the intention of
+eventually phasing out proprietary signatures in favour of the more robust,
+uniform signature.
+
+*Copyright (c) 2019-2020, Arm Limited. All rights reserved.*
\ No newline at end of file