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="&lt;mxfile host=&quot;app.diagrams.net&quot; modified=&quot;2021-09-26T06:40:48.327Z&quot; agent=&quot;5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.61 Safari/537.36&quot; etag=&quot;BVD9jAIebmczNn1dO7Ma&quot; version=&quot;15.2.9&quot; type=&quot;device&quot;&gt;&lt;diagram id=&quot;pE8yNmrzc9lT-nbtH71B&quot; name=&quot;Page-1&quot;&gt;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==&lt;/diagram&gt;&lt;/mxfile&gt;"><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="&lt;mxfile host=&quot;app.diagrams.net&quot; modified=&quot;2021-09-06T03:17:02.086Z&quot; agent=&quot;5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36&quot; etag=&quot;i12WVWij0c3EiUyQtPTn&quot; version=&quot;14.9.8&quot; type=&quot;device&quot;&gt;&lt;diagram id=&quot;pE8yNmrzc9lT-nbtH71B&quot; name=&quot;Page-1&quot;&gt;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=&lt;/diagram&gt;&lt;/mxfile&gt;"><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="&lt;mxfile host=&quot;app.diagrams.net&quot; modified=&quot;2022-03-01T01:46:51.777Z&quot; agent=&quot;5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36&quot; etag=&quot;ZlGN284FfhJiTgM44jcv&quot; version=&quot;16.6.4&quot; type=&quot;device&quot;&gt;&lt;diagram id=&quot;0CR0-B0AtPDSijsltwSn&quot; name=&quot;Page-1&quot;&gt;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==&lt;/diagram&gt;&lt;/mxfile&gt;"><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="&lt;mxfile host=&quot;app.diagrams.net&quot; modified=&quot;2021-09-17T06:56:27.058Z&quot; agent=&quot;5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36&quot; etag=&quot;a4te_vN3EQJEAzAJBS9K&quot; version=&quot;15.2.9&quot; type=&quot;device&quot;&gt;&lt;diagram id=&quot;z2eWvvA0n7qyoBdv0BDn&quot; name=&quot;Page-1&quot;&gt;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=&lt;/diagram&gt;&lt;/mxfile&gt;"><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="&lt;mxfile host=&quot;app.diagrams.net&quot; modified=&quot;2021-09-17T08:07:56.757Z&quot; agent=&quot;5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36&quot; etag=&quot;jj3Jf5IRjsPlaCu4d2ZX&quot; version=&quot;15.2.9&quot; type=&quot;device&quot;&gt;&lt;diagram id=&quot;pE8yNmrzc9lT-nbtH71B&quot; name=&quot;Page-1&quot;&gt;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&lt;/diagram&gt;&lt;/mxfile&gt;"><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="&lt;mxfile host=&quot;app.diagrams.net&quot; modified=&quot;2021-09-10T10:28:55.524Z&quot; agent=&quot;5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36&quot; etag=&quot;_JZ6fR9ln1KZGVaMcIWN&quot; version=&quot;15.0.6&quot; type=&quot;device&quot;&gt;&lt;diagram id=&quot;z2eWvvA0n7qyoBdv0BDn&quot; name=&quot;Page-1&quot;&gt;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==&lt;/diagram&gt;&lt;/mxfile&gt;"><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="&lt;mxfile host=&quot;app.diagrams.net&quot; modified=&quot;2021-06-10T08:17:08.793Z&quot; agent=&quot;5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36&quot; etag=&quot;bcO4cmytDhasP_7HJr2A&quot; version=&quot;14.7.3&quot; type=&quot;device&quot;&gt;&lt;diagram id=&quot;pE8yNmrzc9lT-nbtH71B&quot; name=&quot;Page-1&quot;&gt;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=&lt;/diagram&gt;&lt;/mxfile&gt;"><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="&lt;mxfile host=&quot;app.diagrams.net&quot; modified=&quot;2021-06-21T13:51:31.836Z&quot; agent=&quot;5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36&quot; etag=&quot;zDoxWHAhn_gRFZadqpOB&quot; version=&quot;14.8.0&quot; type=&quot;device&quot;&gt;&lt;diagram id=&quot;oEx5C9R192mbNw7mWCni&quot; name=&quot;Page-1&quot;&gt;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==&lt;/diagram&gt;&lt;/mxfile&gt;"><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="&lt;mxfile host=&quot;app.diagrams.net&quot; modified=&quot;2021-09-06T06:23:14.559Z&quot; agent=&quot;5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36&quot; etag=&quot;1QsfdRuMsY_wf8lx7K3Z&quot; version=&quot;14.9.8&quot; type=&quot;device&quot;&gt;&lt;diagram id=&quot;pE8yNmrzc9lT-nbtH71B&quot; name=&quot;Page-1&quot;&gt;vVbbctowEP0aP9LBV+hjMCQ8gEPrTJP2paPYwlYjexkhLu7XV4rXN0wKnbaBGUY62l1pz1mtMGw/O94JskmXEFNuWMP4aNhTw7JGY0v9aqAoAcdySyARLC4hswFC9pMiOER0x2K67RhKAC7ZpgtGkOc0kh2MCAGHrtkaeHfXDUloDwgjwvvoI4tlWqJja9Tgc8qStNrZ9D6WKxmpjDGTbUpiOLQge2bYvgCQ5Sg7+pRr7ipeSr/bN1brgwmay2scvpjm+n4xWPif3CJ4HAfFGKYDVGdP+A4TfvhmWJ5h2UoAe+JDLulRtpCQij2LKKYki4onAbs8pnorbbVWfqilqRKdbKWAl5pACy1uSca4rosHkkJGNMo494GDeA1qzzz9reLhZmcSR2hPhTptC0Ii7ihkVIpCmeCqU5UXVqVXzQ+NxmYlXNrS10WMYFkldeiGeTVA8v9ACLsnRBCq+U2ik3xfsjWNTN2AG86SXK09g5SQvYMKjnOlCqbzv2TwejKEq+UF/jl5pnwFWyYZaL4ixQgVLSIXJwYZi2MdakKQ4Z5Hj/rzmjZi/P7q9LX/B+q53mX1vDPi1Q3xb8TLv3/mwXz2Yt3P52GwDhZLPx6YPaForJo5TkHIFBLICZ816KQrZWOzANggsz+olAVeMLKToKBUZhxd6JHJJz3+4OLsK/rp8fTYMpsWV9/YEmnpORz66lMrpxN78x2oeICdiOilntPXV1BOJNt3458TC11XwHSPquvCOemtjtsNUZ4LvdoP1kkgZ3TapO1uIElEQmUv0Gvt1PmcKyc1bd7d0rz582LPfgE=&lt;/diagram&gt;&lt;/mxfile&gt;"><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