Docs: Move design documents into a dedicated folder

Collect all the design documents under a dedicated design_docs folder.
Update the links in other documents.

Change-Id: I2da761a11317144185e960c539f2245d3d46fd2a
Signed-off-by: David Hu <david.hu@arm.com>
diff --git a/docs/technical_references/design_docs/code_sharing.rst b/docs/technical_references/design_docs/code_sharing.rst
new file mode 100644
index 0000000..322d7ed
--- /dev/null
+++ b/docs/technical_references/design_docs/code_sharing.rst
@@ -0,0 +1,367 @@
+######################################################
+Code sharing between independently linked XIP binaries
+######################################################
+
+:Authors: 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/0005-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/src/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:
+
+ - `compiler_create_shared_code()`: Extract and filter shared symbol addresses
+   from MCUboot.
+ - `compiler_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, Arm Limited. All rights reserved.*
\ No newline at end of file
diff --git a/docs/technical_references/design_docs/dual-cpu/booting_a_dual_core_system.rst b/docs/technical_references/design_docs/dual-cpu/booting_a_dual_core_system.rst
new file mode 100644
index 0000000..0a88ab3
--- /dev/null
+++ b/docs/technical_references/design_docs/dual-cpu/booting_a_dual_core_system.rst
@@ -0,0 +1,136 @@
+##########################
+Booting a Dual-Core System
+##########################
+
+:Authors: Chris Brand
+:Organization: Cypress Semiconductor Corporation
+:Contact: chris.brand@cypress.com
+:Status: Accepted
+
+*******************
+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.
+
+- 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_spm_hal_boot_ns_cpu(uintptr_t start_addr);
+
+- Called on the secure core from ``tfm_core_init()`` after hardware 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_spm_hal_wait_for_ns_cpu_ready(void);
+
+- Called on the secure core from the end of ``tfm_core_init()`` where on a
+  single core system the secure code calls into the non-secure code.
+
+- 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 Cypress Semiconductor Corporation
diff --git a/docs/technical_references/design_docs/dual-cpu/communication_prototype_between_nspe_and_spe_in_dual_core_systems.rst b/docs/technical_references/design_docs/dual-cpu/communication_prototype_between_nspe_and_spe_in_dual_core_systems.rst
new file mode 100644
index 0000000..1ab1413
--- /dev/null
+++ b/docs/technical_references/design_docs/dual-cpu/communication_prototype_between_nspe_and_spe_in_dual_core_systems.rst
@@ -0,0 +1,744 @@
+################################################################
+Communication Prototype Between NSPE And SPE In Dual Core System
+################################################################
+
+:Authors: 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 assert a PendSV.
+2. In the top half of PendSV handler, the scheduler selects the next thread to
+   run and executes normal context switch if necessary.
+3. In the bottom half of PendSV handler, mailbox handling 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.
+- `PendSV handler`_ specifies the mailbox tasks in PendSV handler.
+- `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 SPE mailbox API(s) to deal with the inbound
+mailbox event. The SPE mailbox may assert a PendSV.
+
+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.
+
+PendSV handler
+==============
+
+The mailbox handling should be added to PendSV handler in current TF-M single
+Armv8-M implementation in IPC model. Mailbox handling processes the inbound
+mailbox event(s) in the bottom half of PendSV handler. The top half of PendSV
+contains the original scheduling.
+
+Mailbox handling must be executed after the original scheduling to make sure
+that the status of sleeping secure service has been updated in scheduling when
+mailbox handling triggers the sleeping secure service.
+
+A compile flag can be defined to disable mailbox handling in PendSV handler in
+single Armv8-M scenario during building.
+
+This section only discusses about the mailbox handling in the bottom half of
+PendSV handler. The TF-M scheduling and context switch should keep unchanged as
+current single Armv8-M implementation.
+
+Mailbox handling in bottom half of PendSV handler
+-------------------------------------------------
+
+PendSV handler 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 paramters 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.
+
+Implementation details in PendSV handler
+----------------------------------------
+
+Some more details should be taken care of in actual implementation.
+
+- PendSV priority should be configured as low enough, to prevent blocking or
+  preempting other latency sensitive interrupts.
+- All the mailbox implementations inside PendSV handler must not directly
+  execute context switch.
+- To simplify the interrupt handling inside TF-M, the mailbox handling
+  implementation inside PendSV handle should avoid triggering additional
+  Inter-Processor Communication interrupts in TF-M, unless it is explicitly
+  required in mailbox design.
+- If Inter-Processor Communication interrupt handler and PendSV handler access
+  shared mailbox objects, proper protection and synchronization should be
+  implemented in both handlers. For example, the Inter-Processor Communication
+  interrupt can be temporarily disabled on secure core while PendSV handler
+  accesses mailbox objects in TF-M.
+
+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.
+
+The mailbox reply functions must not trigger context switch inside PendSV
+handler.
+
+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.
+
+A compile flag should be defined to enable replying routine via mailbox in
+dual-core scenario during building.
+
+***********************************
+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 tfm_msg_body_t *msg, int32_t client_id);
+
+**Parameters**
+
++---------------+-----------------------------------------------------+
+| ``msg``       | TF-M message 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.
+- PendSV priority should be configured in TF-M initialization.
+
+Some optional changes or optimizations are listed below.
+
+- The PSA client call handlers of ``psa_connect()``, ``psa_call()`` and
+  ``psa_close()`` can be optimized to skip asserting PendSV in dual-core
+  scenario.
+
+*********
+Reference
+*********
+
+.. [1] :doc:`Mailbox Design in TF-M on Dual-core System <./mailbox_design_on_dual_core_system>`
+
+----------------
+
+*Copyright (c) 2019-2021 Arm Limited. All Rights Reserved.*
+
+*Copyright (c) 2020 Cypress Semiconductor Corporation.*
diff --git a/docs/technical_references/design_docs/dual-cpu/dual_core_mailbox_arch.png b/docs/technical_references/design_docs/dual-cpu/dual_core_mailbox_arch.png
new file mode 100644
index 0000000..79f5654
--- /dev/null
+++ b/docs/technical_references/design_docs/dual-cpu/dual_core_mailbox_arch.png
Binary files differ
diff --git a/docs/technical_references/design_docs/dual-cpu/index.rst b/docs/technical_references/design_docs/dual-cpu/index.rst
new file mode 100644
index 0000000..f302748
--- /dev/null
+++ b/docs/technical_references/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/technical_references/design_docs/dual-cpu/mailbox_design_on_dual_core_system.rst b/docs/technical_references/design_docs/dual-cpu/mailbox_design_on_dual_core_system.rst
new file mode 100644
index 0000000..60ac467
--- /dev/null
+++ b/docs/technical_references/design_docs/dual-cpu/mailbox_design_on_dual_core_system.rst
@@ -0,0 +1,1475 @@
+##########################################
+Mailbox Design in TF-M on Dual-core System
+##########################################
+
+:Authors: 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 ``tfm_mailbox_msg_irq_handler()`` to notify SPE mailbox to deal with
+received PSA Client call(s) from NSPE. ``tfm_mailbox_msg_irq_handler()`` will
+assert PendSV. Please refer to `tfm_mailbox_msg_irq_handler()`_ for details.
+
+**********************
+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.
+
+``tfm_mailbox_msg_irq_handler()``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+A general IRQ handler to deal with notification from NSPE mailbox.
+
+.. code-block:: c
+
+  void tfm_mailbox_msg_irq_handler(void);
+
+**Usage**
+
+``tfm_mailbox_msg_irq_handler()`` is called in platform-specific Inter-Processor
+Communication interrupt handler when a notification from NSPE mailbox arrives.
+
+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.*
diff --git a/docs/technical_references/design_docs/dual-cpu/tfm_multi_core_access_check.rst b/docs/technical_references/design_docs/dual-cpu/tfm_multi_core_access_check.rst
new file mode 100644
index 0000000..9ea9afd
--- /dev/null
+++ b/docs/technical_references/design_docs/dual-cpu/tfm_multi_core_access_check.rst
@@ -0,0 +1,513 @@
+################################################################
+Memory Access Check of Trusted Firmware-M in Multi-Core Topology
+################################################################
+
+:Authors: David Hu
+:Organization: Arm Limited
+:Contact: david.hu@arm.com
+:Status: Accepted
+
+************
+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/technical_references/design_docs/enum_implicit_casting.rst b/docs/technical_references/design_docs/enum_implicit_casting.rst
new file mode 100644
index 0000000..01c8ce7
--- /dev/null
+++ b/docs/technical_references/design_docs/enum_implicit_casting.rst
@@ -0,0 +1,190 @@
+################################################
+Fixing implicit casting for C enumeration values
+################################################
+
+:Authors: Hugues de Valon
+:Organization: Arm Limited
+:Contact: hugues.devalon@arm.com
+:Status: Accepted
+
+********
+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/technical_references/design_docs/ff_isolation.rst b/docs/technical_references/design_docs/ff_isolation.rst
new file mode 100644
index 0000000..41dd4fc
--- /dev/null
+++ b/docs/technical_references/design_docs/ff_isolation.rst
@@ -0,0 +1,401 @@
+##############
+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 </docs/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::
+  The PSA RoT Services can be implemented directly within the SPM, or as RoT
+  Services within one or more PSA RoT Secure Partitions. But if the PSA RoT
+  Services needs to be accessed by NSPE or Application RoT of Trust Services
+  must be implemented in a Secure Partitions (Please refer to chapter 2.4 -
+  "RoT Services" of `PSA Firmware_Framework for M`_).
+  The implementation in this design treats the PSA RoT Secure Partition in the
+  PSA RoT domain to follow `L3.3` above and relax `L3.2` for PSA RoT Secure
+  Partition under isolation level 3.
+
+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::
+  In general, assets include not only ROM/RAM and peripherals. For the detail
+  information about the memory assets and peripheral, please
+  refer to `PSA Firmware_Framework for M`_.
+
+Memory Asset Class
+------------------
+There are 3 memory asset classes defined in `PSA Firmware_Framework for 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.
+
+ 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 the requirement in the table
+   about constant data can be regarded as a recommendation instead of a
+   mandatory item under some hardware resource-constrained cases.
+
+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 is not involved in this example, because it grants PSA
+  RoT domain program (especially SPM) the ability to access the place not
+  covered in an explicitly defined region. In a system lack of enough MPU
+  regions, the default memory map can be applied, in this case, the whole image
+  layout needs to be audited to find out if the uncovered region contains
+  garbage or gadget data which could provide an attack.
+
+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
+========
+| `PSA Firmware_Framework for M`_
+
+.. _PSA Firmware_Framework for M: https://pages.arm.com/psa-resources-ff.html
+
+| `Trusted Base System Architecture for Armv6-M, Armv7-M and Armv8-M`_
+
+.. _Trusted Base System Architecture for Armv6-M, Armv7-M and Armv8-M: https://pages.arm.com/psa-resources-tbsa-m.html
+
+--------------
+
+*Copyright (c) 2020-2021, Arm Limited. All rights reserved.*
diff --git a/docs/technical_references/design_docs/hardware_abstraction_layer.rst b/docs/technical_references/design_docs/hardware_abstraction_layer.rst
new file mode 100644
index 0000000..b574a3d
--- /dev/null
+++ b/docs/technical_references/design_docs/hardware_abstraction_layer.rst
@@ -0,0 +1,671 @@
+##########################
+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
+    </docs/technical_references/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 </platform/readme>` for more detail.
+
+*****************
+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-specific initialization.
+
+This API is called after architecture and platform common initialization has
+finished during system early startup.
+
+**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.
+
+**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.
+
+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_MEM_ATTR_UNPRIVILEGED | TFM_HAL_MEM_ATTR_READABLE`` is unprivileged
+readable. The data type is `uint32_t`.
+
+TFM_HAL_MEM_ATTR_EXECUTABLE
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+The memory is executable.
+
+.. code-block:: c
+
+  #define TFM_HAL_MEM_ATTR_EXECUTABLE (1UL << 0)
+
+TFM_HAL_MEM_ATTR_READABLE
+^^^^^^^^^^^^^^^^^^^^^^^^^
+The memory is readable.
+
+.. code-block:: c
+
+  #define TFM_HAL_MEM_ATTR_READABLE (1UL << 1)
+
+TFM_HAL_MEM_ATTR_WRITABLE
+^^^^^^^^^^^^^^^^^^^^^^^^^
+The memory is writable.
+
+.. code-block:: c
+
+  #define TFM_HAL_MEM_ATTR_WRITABLE (1UL << 2)
+
+TFM_HAL_MEM_ATTR_UNPRIVILEGED
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+The memory is unprivileged mode accessible.
+
+.. code-block:: c
+
+  #define TFM_HAL_MEM_ATTR_UNPRIVILEGED (1UL << 3)
+
+TFM_HAL_MEM_ATTR_DEVICE
+^^^^^^^^^^^^^^^^^^^^^^^
+The memory is a MMIO device.
+
+.. code-block:: c
+
+  #define TFM_HAL_MEM_ATTR_DEVICE (1UL << 4)
+
+TFM_HAL_MEM_ATTR_NS
+^^^^^^^^^^^^^^^^^^^
+The memory is accessible from :term:`NSPE`
+
+.. code-block:: c
+
+  #define TFM_HAL_MEM_ATTR_NS (1UL << 5)
+
+APIs
+----
+tfm_hal_set_up_static_boundaries()
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+**Prototype**
+
+.. code-block:: c
+
+  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 runtime of the system.
+
+The boundaries include:
+
+- The SPE boundary between the :term:`SPE` and the :term:`NSPE`
+- 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.
+
+Please refer to the :term:`PSA-FF-M` for the definitions of the isolation
+boundaries.
+
+**Return Values**
+
+- ``TFM_HAL_SUCCESS`` - the isolation boundaries have been set up.
+- ``TFM_HAL_ERROR_GENERIC`` - failed to set up the isolation boundaries.
+
+tfm_hal_mpu_update_partition_boundary
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+**Prototype**
+
+.. code-block:: c
+
+  enum tfm_hal_status_t tfm_hal_mpu_update_partition_boundary(uintptr_t start,
+                                                              uintptr_t end);
+
+**Description**
+
+This API updates the partition isolation boundary for isolation level 3.
+Inside the partition isolation boundary is the private data of the running
+Secure Partition.
+This boundary is updated dynamically when :term:`SPM` switches Partitions in
+isolation level 3.
+
+The access permissions of the boundary is all privileged mode read-write.
+
+Platforms decide which :term:`MPU` region the paritition boundary uses.
+
+**Parameter**
+
+- ``start`` - start address of the partition boundary.
+- ``end`` - end address of the partition boundary.
+
+**Return Values**
+
+- ``TFM_HAL_SUCCESS`` - the isolation boundary has been set up.
+- ``TFM_HAL_ERROR_GENERIC`` - failed to set upthe isolation boundary.
+
+**Note**
+
+This API is only for platforms using :term:`MPU` as isolation hardwares.
+A generic API for all platforms will be introduced in future versions.
+
+tfm_hal_memory_has_access()
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+**Prototype**
+
+.. code-block:: c
+
+  tfm_hal_status_t tfm_hal_memory_has_access(const uintptr_t base,
+                                             size_t size,
+                                             uint32_t attr)
+
+**Description**
+
+This API checks if the memory region defined by ``base`` and ``size`` has the
+given access atrributes - ``attr``.
+
+The Attributes include :term:`NSPE` access, privileged mode, and read-write
+permissions.
+
+**Parameter**
+
+- ``base`` - The base address of the region.
+- ``size`` - The size of the region.
+- ``attr`` - 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.
+
+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.
+
+************************************
+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-2021, Arm Limited. All rights reserved.*
diff --git a/docs/technical_references/design_docs/index.rst b/docs/technical_references/design_docs/index.rst
new file mode 100644
index 0000000..3566e03
--- /dev/null
+++ b/docs/technical_references/design_docs/index.rst
@@ -0,0 +1,13 @@
+Design documents
+================
+
+.. toctree::
+    :maxdepth: 2
+    :glob:
+
+    */index
+    *
+
+--------------
+
+*Copyright (c) 2021, Arm Limited. All rights reserved.*
diff --git a/docs/technical_references/design_docs/media/hal_structure.png b/docs/technical_references/design_docs/media/hal_structure.png
new file mode 100644
index 0000000..0f4c4c0
--- /dev/null
+++ b/docs/technical_references/design_docs/media/hal_structure.png
Binary files differ
diff --git a/docs/technical_references/design_docs/media/symmetric_initial_attest/attest_token_finish.png b/docs/technical_references/design_docs/media/symmetric_initial_attest/attest_token_finish.png
new file mode 100644
index 0000000..548e79d
--- /dev/null
+++ b/docs/technical_references/design_docs/media/symmetric_initial_attest/attest_token_finish.png
Binary files differ
diff --git a/docs/technical_references/design_docs/media/symmetric_initial_attest/attest_token_start.png b/docs/technical_references/design_docs/media/symmetric_initial_attest/attest_token_start.png
new file mode 100644
index 0000000..ac39cf2
--- /dev/null
+++ b/docs/technical_references/design_docs/media/symmetric_initial_attest/attest_token_start.png
Binary files differ
diff --git a/docs/technical_references/design_docs/media/symmetric_initial_attest/ia_service_flow.png b/docs/technical_references/design_docs/media/symmetric_initial_attest/ia_service_flow.png
new file mode 100644
index 0000000..288bc53
--- /dev/null
+++ b/docs/technical_references/design_docs/media/symmetric_initial_attest/ia_service_flow.png
Binary files differ
diff --git a/docs/technical_references/design_docs/media/symmetric_initial_attest/iat_decode.png b/docs/technical_references/design_docs/media/symmetric_initial_attest/iat_decode.png
new file mode 100644
index 0000000..e35183b
--- /dev/null
+++ b/docs/technical_references/design_docs/media/symmetric_initial_attest/iat_decode.png
Binary files differ
diff --git a/docs/technical_references/design_docs/media/symmetric_initial_attest/overall_diagram.png b/docs/technical_references/design_docs/media/symmetric_initial_attest/overall_diagram.png
new file mode 100644
index 0000000..893c62e
--- /dev/null
+++ b/docs/technical_references/design_docs/media/symmetric_initial_attest/overall_diagram.png
Binary files differ
diff --git a/docs/technical_references/design_docs/media/tfm_crypto_design.png b/docs/technical_references/design_docs/media/tfm_crypto_design.png
new file mode 100644
index 0000000..6e8d48b
--- /dev/null
+++ b/docs/technical_references/design_docs/media/tfm_crypto_design.png
Binary files differ
diff --git a/docs/technical_references/design_docs/profiles/index.rst b/docs/technical_references/design_docs/profiles/index.rst
new file mode 100644
index 0000000..e856cf8
--- /dev/null
+++ b/docs/technical_references/design_docs/profiles/index.rst
@@ -0,0 +1,12 @@
+TF-M Profiles
+=============
+
+.. toctree::
+    :maxdepth: 1
+    :glob:
+
+    *
+
+--------------
+
+*Copyright (c) 2020, Arm Limited. All rights reserved.*
diff --git a/docs/technical_references/design_docs/profiles/tfm_profile_large.rst b/docs/technical_references/design_docs/profiles/tfm_profile_large.rst
new file mode 100644
index 0000000..d59ae61
--- /dev/null
+++ b/docs/technical_references/design_docs/profiles/tfm_profile_large.rst
@@ -0,0 +1,459 @@
+#######################################
+Trusted Firmware-M Profile Large Design
+#######################################
+
+:Authors: David Hu
+:Organization: Arm Limited
+:Contact: david.hu@arm.com
+
+************
+Introduction
+************
+
+TF-M Profiles defines 3 profiles: Profile Small, Profile Medium and Profile
+Large. Each profile provides a predefined list of TF-M configurations to meet
+the security requirement of typical use cases with device hardware constraints.
+TF-M Profiles align with PSA specifications and certification requirements.
+
+As one of TF-M Profiles, Profile Large protects less resource-constrained Arm
+Cortex-M devices.
+
+Compared to Profile Small [1]_ and Profile Medium [2]_, Profile Large aims to
+enable more secure features to support higher level of security required in more
+complex usage scenarios.
+
+    - Isolation level 3 enables additional isolation between
+      :term:`Application RoT` (App RoT) services.
+    - More crypto algorithms and cipher suites are selected to securely connect
+      devices to remote services offered by various major Cloud Service
+      Providers (CSP)
+    - Basic software countermeasures against physical attacks can be enabled.
+
+Profile Large can be aligned as a reference implementation with the requirements
+defined in PSA Certified Level 3 Lightweight Protection Profile [3]_.
+
+**************
+Overall design
+**************
+
+TF-M Profile Large defines the following feature set:
+
+    - Firmware Framework
+
+        - Inter-Process Communication (IPC) model [4]_
+        - Isolation level 3 [4]_
+
+    - Internal Trusted Storage (ITS)
+
+    - Crypto
+
+        - Support both symmetric ciphers and asymmetric ciphers
+        - Asymmetric key based cipher suites defined in TLS 1.2 [5]_ to support
+          direct secure connection to major CSPs, including
+
+            - Authenticated Encryption with Associated Data (AEAD) algorithm
+            - Asymmetric key algorithm based signature and verification
+            - Public-key cryptography based key exchange
+            - Hash function
+            - HMAC for default Pseudorandom Function (PRF)
+
+        - Asymmetric digital signature and verification for Initial Attestation
+          Token (IAT)
+        - Asymmetric algorithms for firmware image signature verification
+        - Key derivation
+
+    - Initial Attestation
+
+        - Asymmetric key algorithm based Initial Attestation
+
+    - Secure boot
+
+        - Anti-rollback protection
+        - Multiple image boot
+
+    - Protected Storage (PS) if off-chip storage device is integrated
+
+        - Data confidentiality
+        - Data integrity
+        - Rollback protection
+
+    - Software countermeasures against physical attacks
+
+**************
+Design details
+**************
+
+More details of TF-M Profile Large design are described in following sections.
+
+Firmware framework
+==================
+
+Profile Large selects IPC model and isolation level 3 by default.
+
+Isolation level 3 supports additional isolation between App RoT services,
+compared to isolation level 2. It can protect :term:`RoT` services from each
+other when their vendors don't trust each other.
+
+Crypto service
+==============
+
+Profile Large supports direct connection to Cloud services via common protocols,
+such as TLS 1.2.
+
+In some usage scenarios, PSA RoT can be managed by device manufacturer or other
+vendors and is out of control of application developers.
+Profile Large selects alternative crypto algorithms for each crypto function to
+support multiple common cipher suites required by various major CSPs. Therefore,
+application developers can support services for diverse CSPs on same devices
+with Profile Large, without relying on PSA RoT upgrades of crypto.
+
+Devices meeting Profile Large should be in a position to offer at least two
+alternatives to every cryptographic primitive for symmetric, asymmetric and
+hash, and be able to use them for encryption, AEAD, signature and verification.
+
+It will cost more resource in Profile Large to support more crypto algorithms
+and cipher suites, compared to Profile Medium [2]_.
+
+Boot loader
+===========
+
+BL2 implementation can be device specific. Devices may implement diverse
+boot processes with different features and configurations.
+However, the boot loader must support anti-rollback protection. Boot loader must
+be able to prevent unauthorized rollback, to protect devices from being
+downgraded to earlier versions with known vulnerabilities.
+
+MCUBoot in TF-M is configured as multiple image boot by default in Profile
+Large. In multiple image boot, secure and non-secure images can be signed
+independently with different keys and they can be updated separately. It can
+support multiple vendors scenarios, in which non-secure and secure images are
+generated and updated by different vendors.
+Multiple image boot may cost larger memory footprint compared with single image
+boot.
+
+Boot loader can implement software countermeasures to mitigate physical attacks.
+
+Protected Storage
+=================
+
+PS service is required if an off-chip storage device is integrated and used on
+the platform.
+
+Anti-rollback protection in PS relies on non-volatile counter(s) provided by
+TF-M Platform :term:`Secure Partition` (SP).
+
+TF-M audit logging service
+==========================
+
+TF-M audit logging service allows secure services in the system to log TF-M
+events and information.
+
+TF-M audit logging service is not enabled in Profile Large since its IPC model
+dedicated interface is not ready yet.
+
+.. note ::
+
+    **Implementation note**
+
+    Please note that there is no dedicated PSA specification for Audit Logging
+    yet.
+    The design, interfaces and implementation of TF-M audit logging service may
+    change.
+
+Software countermeasures against physical attacks
+=================================================
+
+TF-M Profile Large enables TF-M Fault Injection Hardening (FIH) library Profile
+Medium by default. It enables the following countermeasure techniques:
+
+    - Control flow monitor
+    - Failure loop hardening
+    - Complex constants
+    - Redundant variables and condition checks
+
+Refer to TF-M physical attack mitigation design document [6]_ for FIH library
+details.
+
+.. note ::
+
+    **TF-M FIH library is still under development**.
+
+    TF-M FIH library hardens TF-M critical execution steps to make physical
+    attacks more difficult, together with device hardware countermeasures.
+    It is not guaranteed that TF-M FIH library is able to mitigate all kinds of
+    physical attacks.
+
+.. note ::
+
+    **Implementation note**
+
+    TF-M FIH library doesn't cover platform specific critical configurations.
+    Platforms shall implement software countermeasures against physical attacks
+    to protect platform specific implementation.
+
+**************
+Implementation
+**************
+
+Overview
+========
+
+The basic idea is to add dedicated profile CMake configuration files under
+folder ``config/profile`` for TF-M Profile Large default configuration, the
+same as other TF-M Profiles do.
+
+The top-level Profile Large config file collects all the necessary configuration
+flags and set them to default values, to explicitly enable the features required
+in Profile Large and disable the unnecessary ones, during TF-M build.
+
+A platform/use case can provide a configuration extension file to overwrite
+Profile Large default setting and append other configurations.
+This configuration extension file can be added via parameter
+``TFM_EXTRA_CONFIG_PATH`` in build command line.
+
+The behaviour of the Profile Large build flow (particularly the order of
+configuration loading and overriding) can be found at
+:ref:`tfm_cmake_configuration`
+
+The details of configurations will be covered in each module in
+`Implementation details`_.
+
+Implementation details
+======================
+
+This section discusses the details of Profile Large implementation.
+
+Top-level configuration files
+-----------------------------
+
+The firmware framework configurations in ``config/profile/profile_large`` are
+shown below.
+
+.. table:: Config flags in Profile Large top-level CMake config file
+   :widths: auto
+   :align: center
+
+   +--------------------------------------------+------------------------------------+----------------------------------------------------------------------------------------------------+
+   | Configs                                    | Descriptions                       | Default value                                                                                      |
+   +============================================+====================================+====================================================================================================+
+   | ``TFM_ISOLATION_LEVEL``                    | Select level 3 isolation           | ``3``                                                                                              |
+   +--------------------------------------------+------------------------------------+----------------------------------------------------------------------------------------------------+
+   | ``TFM_PSA_API``                            | Select IPC model                   | ``ON``                                                                                             |
+   +--------------------------------------------+------------------------------------+----------------------------------------------------------------------------------------------------+
+   | ``TFM_PARTITION_INTERNAL_TRUSTED_STORAGE`` | Enable ITS SP                      | ``ON``                                                                                             |
+   +--------------------------------------------+------------------------------------+----------------------------------------------------------------------------------------------------+
+   | ``ITS_BUF_SIZE``                           | ITS internal transient buffer size | ``64``                                                                                             |
+   +--------------------------------------------+------------------------------------+----------------------------------------------------------------------------------------------------+
+   | ``TFM_PARTITION_CRYPTO``                   | Enable Crypto service              | ``ON``                                                                                             |
+   +--------------------------------------------+------------------------------------+----------------------------------------------------------------------------------------------------+
+   | ``TFM_MBEDCRYPTO_CONFIG_PATH``             | MbedTLS config file path           | ``${CMAKE_SOURCE_DIR}/lib/ext/mbedcrypto/mbedcrypto_config/tfm_mbedcrypto_config_profile_large.h`` |
+   +--------------------------------------------+------------------------------------+----------------------------------------------------------------------------------------------------+
+   | ``TFM_PARTITION_INITIAL_ATTESTATION``      | Enable Initial Attestation service | ``ON``                                                                                             |
+   +--------------------------------------------+------------------------------------+----------------------------------------------------------------------------------------------------+
+   | ``TFM_PARTITION_PROTECTED_STORAGE`` [a]_   | Enable PS service                  | ``ON``                                                                                             |
+   +--------------------------------------------+------------------------------------+----------------------------------------------------------------------------------------------------+
+   | ``TFM_PARTITION_PLATFORM``                 | Enable TF-M Platform SP            | ``ON``                                                                                             |
+   +--------------------------------------------+------------------------------------+----------------------------------------------------------------------------------------------------+
+   | ``TFM_PARTITION_AUDIT_LOG``                | Disable TF-M audit logging service | ``OFF``                                                                                            |
+   +--------------------------------------------+------------------------------------+----------------------------------------------------------------------------------------------------+
+
+.. [a] PS service is enabled by default. Platforms without off-chip storage
+       devices can turn off ``TFM_PARTITION_PROTECTED_STORAGE`` to disable PS
+       service. See `Protected Storage Secure Partition`_ for details.
+
+Crypto service configurations
+-----------------------------
+
+Crypto Secure Partition
+^^^^^^^^^^^^^^^^^^^^^^^
+
+TF-M Profile Large enables Crypto SP in top-level CMake config file and selects
+all the Crypto modules.
+
+MbedTLS configurations
+^^^^^^^^^^^^^^^^^^^^^^
+
+TF-M Profile Large adds a dedicated MbedTLS config file
+``tfm_mbedcrypto_config_profile_large.h`` under
+``/lib/ext/mbedcrypto/mbedcrypto_config`` folder, instead of the common one
+``tfm_mbedcrypto_config_default.h`` [7]_.
+
+Major MbedTLS configurations are set as listed below:
+
+    - Enable SHA256 and SHA512
+    - Enable generic message digest wrappers
+    - Enable AES
+    - Enable CCM mode, GCM mode and CBC mode for symmetric ciphers
+    - Disable other modes for symmetric ciphers
+    - Enable ECDH
+    - Enable ECDSA
+    - Enable RSA
+    - Select ECC curve ``secp256r1`` and ``secp384r1``
+    - Enable HMAC-based key derivation function
+    - Other configurations required by selected option above
+
+A device/use case can append an extra config header to the Profile Large default
+MbedTLS config file to override the default settings. This can be done by
+setting the ``TFM_MBEDCRYPTO_PLATFORM_EXTRA_CONFIG_PATH`` cmake variable in the
+platform config file ``platform/ext<TFM_PLATFORM>/config.cmake``.
+This cmake variable is a wrapper around the ``MBEDTLS_USER_CONFIG_FILE``
+options, but is preferred as it keeps all configuration in cmake.
+
+Internal Trusted Storage configurations
+---------------------------------------
+
+ITS service is enabled in top-level Profile Large CMake config file by default.
+
+The internal transient buffer size ``ITS_BUF_SIZE`` [8]_ is set to 64 bytes by
+default. A platform/use case can overwrite the buffer size in its specific
+configuration extension according to its actual requirement of assets and Flash
+attributes.
+
+Profile Large CMake config file won't touch the configurations of device
+specific Flash hardware attributes.
+
+Protected Storage Secure Partition
+----------------------------------
+
+Data confidentiality, integrity and anti-rollback protection are enabled by
+default in PS.
+
+If PS is selected, AES-CCM is used as AEAD algorithm by default. If platform
+hardware crypto accelerator supports the AEAD algorithm, the AEAD operations can
+be executed in hardware crypto accelerator.
+
+If platforms don't integrate any off-chip storage device, platforms can disable
+PS in platform specific configuration extension file via
+``platform/ext<TFM_PLATFORM>/config.cmake``.
+
+BL2 setting
+-----------
+
+Profile Large enables MCUBoot provided by TF-M by default. A platform can
+overwrite this configuration by disabling MCUBoot in its configuration extension
+file ``platform/ext<TFM_PLATFORM>/config.cmake``.
+
+If MCUBoot provided by TF-M is enabled, multiple image boot is selected by
+default.
+
+If a device implements its own boot loader, the configurations are
+implementation defined.
+
+Software countermeasure against physical attacks
+------------------------------------------------
+
+Profile Large selects TF-M FIH library Profile Medium by specifying
+``-DTFM_FIH_PROFILE=MEDIUM`` in top-level CMake config file.
+
+System integrators shall implement software countermeasures in platform specific
+implementations.
+
+Device configuration extension
+------------------------------
+
+To change default configurations and add platform specific configurations,
+a platform can add a platform configuration file at
+``platform/ext<TFM_PLATFORM>/config.cmake``
+
+Test configuration
+------------------
+
+Some cryptography tests are disabled due to the reduced MbedTLS config.
+Profile Large specific test configurations are also specified in Profile Large
+top-level CMake config file ``config/profile/profile_large``.
+
+.. table:: Profile Large crypto test configuration
+   :widths: auto
+   :align: center
+
+   +--------------------------------------------+---------------+-----------------------------------------+
+   | Configs                                    | Default value | Descriptions                            |
+   +============================================+===============+=========================================+
+   | ``TFM_CRYPTO_TEST_ALG_CBC``                | ``ON``        | Test CBC cryptography mode              |
+   +--------------------------------------------+---------------+-----------------------------------------+
+   | ``TFM_CRYPTO_TEST_ALG_CCM``                | ``ON``        | Test CCM cryptography mode              |
+   +--------------------------------------------+---------------+-----------------------------------------+
+   | ``TFM_CRYPTO_TEST_ALG_GCM``                | ``ON``        | Test GCM cryptography mode              |
+   +--------------------------------------------+---------------+-----------------------------------------+
+   | ``TFM_CRYPTO_TEST_ALG_SHA_512``            | ``ON``        | Test SHA-512 cryptography algorithm     |
+   +--------------------------------------------+---------------+-----------------------------------------+
+   | ``TFM_CRYPTO_TEST_HKDF``                   | ``ON``        | Test HMAC-based key derivation function |
+   +--------------------------------------------+---------------+-----------------------------------------+
+   | ``TFM_CRYPTO_TEST_ALG_CFB``                | ``OFF``       | Test CFB cryptography mode              |
+   +--------------------------------------------+---------------+-----------------------------------------+
+   | ``TFM_CRYPTO_TEST_ALG_CTR``                | ``OFF``       | Test CTR cryptography mode              |
+   +--------------------------------------------+---------------+-----------------------------------------+
+
+****************
+Platform support
+****************
+
+To enable Profile Large on a platform, the platform specific CMake file should
+be added into the platform support list in top-level Profile Large CMake config
+file.
+
+Building Profile Large
+======================
+
+To build Profile Large, argument ``TFM_PROFILE`` in build command line should be
+set to ``profile_large``.
+
+Take AN521 as an example:
+
+The following commands build Profile Large without test cases on **AN521** with
+build type **MinSizeRel**, built by **Armclang**.
+
+.. code-block:: bash
+
+   cd <TFM root dir>
+   mkdir build && cd build
+   cmake -DTFM_PLATFORM=arm/mps2/an521 \
+         -DTFM_TOOLCHAIN_FILE=../toolchain_ARMCLANG.cmake \
+         -DTFM_PROFILE=profile_large \
+         -DCMAKE_BUILD_TYPE=MinSizeRel \
+         ../
+   cmake --build ./ -- install
+
+The following commands build Profile Large with regression test cases on
+**AN521** with build type **MinSizeRel**, built by **Armclang**.
+
+.. code-block:: bash
+
+   cd <TFM root dir>
+   mkdir build && cd build
+   cmake -DTFM_PLATFORM=arm/mps2/an521 \
+         -DTFM_TOOLCHAIN_FILE=../toolchain_ARMCLANG.cmake \
+         -DTFM_PROFILE=profile_large \
+         -DCMAKE_BUILD_TYPE=MinSizeRel \
+         -DTEST_S=ON -DTEST_NS=ON \
+         ../
+   cmake --build ./ -- install
+
+More details of building instructions and parameters can be found TF-M build
+instruction guide [9]_.
+
+*********
+Reference
+*********
+
+.. [1] :doc:`Trusted Firmware-M Profile Small Design </docs/technical_references/design_docs/profiles/tfm_profile_small>`
+
+.. [2] :doc:`Trusted Firmware-M Profile Medium Design </docs/technical_references/design_docs/profiles/tfm_profile_medium>`
+
+.. [3] `PSA Certified Level 3 Lightweight Protection Profile <https://www.psacertified.org/app/uploads/2020/12/JSADEN009-PSA_Certified_Level_3_LW_PP-1.0-BET02.pdf>`_
+
+.. [4] `Arm Platform Security Architecture Firmware Framework 1.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>`_
+
+.. [5] `The Transport Layer Security (TLS) Protocol Version 1.2 <https://tools.ietf.org/html/rfc5246>`_
+
+.. [6] :doc:`Physical attack mitigation in Trusted Firmware-M </docs/technical_references/design_docs/tfm_physical_attack_mitigation>`
+
+.. [7] :doc:`Crypto design </docs/technical_references/design_docs/tfm_crypto_design>`
+
+.. [8] :doc:`ITS integration guide </docs/integration_guide/services/tfm_its_integration_guide>`
+
+.. [9] :doc:`TF-M build instruction </docs/technical_references/instructions/tfm_build_instruction>`
+
+--------------
+
+*Copyright (c) 2021, Arm Limited. All rights reserved.*
diff --git a/docs/technical_references/design_docs/profiles/tfm_profile_medium.rst b/docs/technical_references/design_docs/profiles/tfm_profile_medium.rst
new file mode 100644
index 0000000..5bc4d57
--- /dev/null
+++ b/docs/technical_references/design_docs/profiles/tfm_profile_medium.rst
@@ -0,0 +1,489 @@
+########################################
+Trusted Firmware-M Profile Medium Design
+########################################
+
+:Authors: David Hu
+:Organization: Arm Limited
+:Contact: david.hu@arm.com
+
+************
+Introduction
+************
+
+Compared with Profile Small, Profile Medium aims to securely connect devices to
+Cloud services with asymmetric cipher support.
+Profile Medium target devices need more resources for more cipher algorithms
+and higher isolation levels.
+
+For more descriptions and background of TF-M Profile, please refer to Profile
+Small design document [PROFILE-S]_.
+
+**************
+Overall design
+**************
+
+TF-M Profile Medium defines the following feature set:
+
+    - Firmware Framework
+
+        - Inter-Process Communication (IPC) model [PSA-FF-M]_
+        - Isolation level 2 [PSA-FF-M]_
+
+    - Internal Trusted Storage (ITS)
+
+    - Crypto
+
+        - Support both symmetric cryptography and asymmetric cryptography
+        - Asymmetric key based cipher suite suggested in TLS/DTLS profiles for
+          IoT [RFC7925]_ and CoAP [RFC7252]_, including
+
+            - Authenticated Encryption with Associated Data (AEAD) algorithm
+            - Asymmetric key algorithm based signature and verification
+            - Public-key cryptography based key exchange
+            - Hash function
+            - HMAC for default Pseudorandom Function (PRF)
+
+        - Asymmetric digital signature and verification for Initial Attestation
+          Token (IAT)
+
+    - Initial Attestation
+
+        - Asymmetric key algorithm based Initial Attestation
+
+    - Lightweight boot
+
+        - Anti-rollback protection
+        - Multiple image boot
+
+    - Protected Storage (PS) if off-chip storage device is integrated
+
+        - Data confidentiality
+        - Data integrity
+        - Rollback protection
+
+**************
+Design details
+**************
+
+More details of TF-M Profile Medium design are described in following sections.
+
+Firmware framework
+==================
+
+Profile Medium with IPC model and isolation level 2 aims to support usage
+scenarios which require more complicated secure service model and additional
+protection to PSA RoT.
+
+Level 2 isolation
+-----------------
+
+Profile Medium selects isolation level 2 by default. In addition to isolation
+level 1, the PSA Root of Trust (PSA RoT) is also protected from access by the
+Application Root of Trust (App RoT) in level 2 isolation.
+
+IPC model
+---------
+
+Profile Medium enables IPC model by default. IPC model can achieve a more
+flexible framework and higher levels of isolation, but may require more memory
+footprint and bring in longer latency, compared to Library model.
+
+TF-M IPC model implementation follows the PSA Firmware Framework for M
+(PSA-FF-M) [PSA-FF-M]_.
+
+Crypto service
+==============
+
+Compared to Profile Small, Profile Medium includes asymmetric cryptography to
+support direct connection to Cloud services via common protocols, such as
+TLS/DTLS 1.2.
+
+As suggested in CoAP [RFC7252]_ and [RFC7925]_, TF-M Profile Medium by default
+selects ``TLS_ECDHE_ECDSA_WITH_AES_128_CCM`` as reference, which requires:
+
+    - ECDHE_ECDSA as key exchange algorithm.
+    - AES-128-CCM (AES CCM mode with 128-bit key) as AEAD algorithm.
+      Platforms can implement AES-128-CCM with truncated authentication tag to
+      achieve less network bandwidth [RFC7925]_.
+    - SHA256 as Hash function.
+    - HMAC as Message Authentication Code algorithm.
+
+Applications can also support TLS PSK [RFC4279]_ cipher suites, such as
+``TLS_PSK_WITH_AES_128_CCM`` [RFC7925]_.
+
+.. note ::
+
+    **Implementation note**
+
+    Developers can replace default algorithms with others or implement more
+    algorithms according to actual usage scenarios and device capabilities.
+
+    If a Crypto hardware accelerator is integrated, the cipher suites and
+    algorithms also depend on those accelerator features.
+
+More details of cipher suite are described below.
+
+Digital signature and verification
+----------------------------------
+
+ECDSA is selected by default in Profile Medium.
+ECDSA requires much shorter keys compared with RSA at the same security level.
+Therefore, ECDSA can cost less storage area for assets and less network
+bandwidth to setup a TLS connection.
+ECDSA is also preferred for forward compatibility of future TLS versions.
+
+As requested in [RFC7251]_, ECC curve ``secp256r1`` should be supported. More
+ECC curves can be added based on the requirements in production.
+
+If usage scenarios require RSA algorithm for backward compatibility and legacy
+applications, platforms can add RSA support or replace ECDSA with RSA. The
+cipher suite should be switched accordingly.
+
+AEAD algorithm
+--------------
+
+If Protected Storage (PS) is implemented, it is recommended to select the same
+AEAD algorithm for PS service as the one used by TLS/DTLS cipher suite.
+
+Internal Trusted Storage
+========================
+
+The configuration of ITS is the same as those in Profile Small [PROFILE-S]_.
+
+Lightweight boot
+================
+
+BL2 implementation can be device specific. Devices may implement diverse
+boot processes with different features and configurations.
+However, the boot loader must support anti-rollback protection. Boot loader must
+be able to prevent unauthorized rollback, to protect devices from being
+downgraded to earlier versions with known vulnerabilities.
+
+MCUBoot in TF-M is configured as multiple image boot by default in Profile
+Medium. In multiple image boot, secure and non-secure images can be signed
+independently with different keys and they can be updated separately. It can
+support multiple vendors scenarios, in which non-secure and secure images are
+generated and updated by different vendors.
+Multiple image boot may require more storage area compared with single image
+boot.
+
+Protected Storage
+=================
+
+PS service is required if an off-chip storage device is integrated and used on
+the platform.
+
+TF-M PS service relies on an AEAD algorithm to ensure data confidentiality and
+integrity. It is recommended to select the same AEAD algorithm as the one used
+for TLS/DTLS cipher suite.
+
+Anti-rollback protection in PS relies on non-volatile counter(s) provided by
+TF-M Platform Secure Partition (SP).
+
+TF-M audit logging service
+==========================
+
+TF-M audit logging service allows secure services in the system to log critical
+system events and information.
+
+TF-M audit logging service is not enabled in Profile Medium since its IPC model
+dedicated interface is not ready yet.
+
+.. note ::
+
+    **Implementation note**
+
+    Please note that there is no dedicated PSA specification for Audit Logging
+    yet.
+    The design, interfaces and implementation of TF-M audit logging service may
+    change.
+
+**************
+Implementation
+**************
+
+Overview
+========
+
+The basic idea is to add dedicated profile CMake configuration files under
+folder ``config/profile`` for TF-M Profile Medium default configuration, the
+same as Profile Small does.
+
+The top-level Profile Medium config file collects all the necessary
+configuration flags and set them to default values, to explicitly enable the
+features required in Profile Medium and disable the unnecessary ones, during
+TF-M build.
+
+A platform/use case can provide a configuration extension file to overwrite
+Profile Medium default setting and append other configurations.
+This configuration extension file can be added via parameter
+``TFM_EXTRA_CONFIG_PATH`` in build command line.
+
+The behaviour of the Profile Medium build flow (particularly the order of
+configuration loading and overriding) can be found at
+:ref:`tfm_cmake_configuration`
+
+The details of configurations will be covered in each module in
+`Implementation details`_.
+
+Implementation details
+======================
+
+This section discusses the details of Profile Medium implementation.
+
+Top-level configuration files
+-----------------------------
+
+The firmware framework configurations in ``config/profile/profile_medium`` are
+shown below.
+
+.. table:: Config flags in Profile Medium top-level CMake config file
+   :widths: auto
+   :align: center
+
+   +--------------------------------------------+-----------------------------------------------------------------------------------------------------+-------------------------------------+
+   | Configs                                    | Default value                                                                                       | Descriptions                        |
+   +============================================+=====================================================================================================+=====================================+
+   | ``TFM_ISOLATION_LEVEL``                    | ``2``                                                                                               | Select level 2 isolation            |
+   +--------------------------------------------+-----------------------------------------------------------------------------------------------------+-------------------------------------+
+   | ``TFM_PSA_API``                            | ``True``                                                                                            | Select IPC model                    |
+   +--------------------------------------------+-----------------------------------------------------------------------------------------------------+-------------------------------------+
+   | ``TFM_PARTITION_INTERNAL_TRUSTED_STORAGE`` | ``ON``                                                                                              | Enable ITS SP                       |
+   +--------------------------------------------+-----------------------------------------------------------------------------------------------------+-------------------------------------+
+   | ``ITS_BUF_SIZE``                           | ``32``                                                                                              | ITS internal transient buffer size  |
+   +--------------------------------------------+-----------------------------------------------------------------------------------------------------+-------------------------------------+
+   | ``TFM_PARTITION_CRYPTO``                   | ``ON``                                                                                              | Enable Crypto service               |
+   +--------------------------------------------+-----------------------------------------------------------------------------------------------------+-------------------------------------+
+   | ``CRYPTO_ASYM_ENCRYPT_MODULE_DISABLED``    | ``ON``                                                                                              | Disable Crypto asymmetric           |
+   |                                            |                                                                                                     | encryption operations               |
+   +--------------------------------------------+-----------------------------------------------------------------------------------------------------+-------------------------------------+
+   | ``TFM_MBEDCRYPTO_CONFIG_PATH``             | ``${CMAKE_SOURCE_DIR}/lib/ext/mbedcrypto/mbedcrypto_config/tfm_mbedcrypto_config_profile_medium.h`` | Mbed Crypto config file path        |
+   +--------------------------------------------+-----------------------------------------------------------------------------------------------------+-------------------------------------+
+   | ``TFM_PARTITION_INITIAL_ATTESTATION``      | ``ON``                                                                                              | Enable Initial Attestation service  |
+   +--------------------------------------------+-----------------------------------------------------------------------------------------------------+-------------------------------------+
+   | ``TFM_PARTITION_PROTECTED_STORAGE`` [1]_   | ``ON``                                                                                              | Enable PS service                   |
+   +--------------------------------------------+-----------------------------------------------------------------------------------------------------+-------------------------------------+
+   | ``TFM_PARTITION_PLATFORM``                 | ``ON``                                                                                              | Enable TF-M Platform SP             |
+   +--------------------------------------------+-----------------------------------------------------------------------------------------------------+-------------------------------------+
+   | ``TFM_PARTITION_AUDIT_LOG``                | ``OFF``                                                                                             | Disable TF-M audit logging service  |
+   +--------------------------------------------+-----------------------------------------------------------------------------------------------------+-------------------------------------+
+
+.. [1] PS service is enabled by default. Platforms without off-chip storage
+       devices can turn off ``TFM_PARTITION_PROTECTED_STORAGE`` to disable PS
+       service. See `Protected Storage Secure Partition`_ for details.
+
+.. Note::
+
+   Where a configuration is the same as the default in
+   ``config/config_default.cmake``, it is omitted from the profile configuration
+   file.
+
+Test configuration
+^^^^^^^^^^^^^^^^^^
+
+Standard regression test configuration applies. This means that enabling
+regression testing via
+
+``-DTEST_S=ON -DTEST_NS=ON``
+
+Will enable testing for all enabled partitions. See above for details of enabled
+partitions. Because Profile Medium enables IPC mode, the IPC tests are also
+enabled.
+
+Some cryptography tests are disabled due to the reduced Mbed Crypto config.
+
+.. table:: TFM options in Profile Medium top-level CMake config file
+   :widths: auto
+   :align: center
+
+   +--------------------------------------------+---------------+--------------------------------+
+   | Configs                                    | Default value | Descriptions                   |
+   +============================================+===============+================================+
+   | ``TFM_CRYPTO_TEST_ALG_CBC``                | ``OFF``       | Disable CBC mode test          |
+   +--------------------------------------------+---------------+--------------------------------+
+   | ``TFM_CRYPTO_TEST_ALG_CCM``                | ``ON``        | Enable CCM mode test           |
+   +--------------------------------------------+---------------+--------------------------------+
+   | ``TFM_CRYPTO_TEST_ALG_CFB``                | ``OFF``       | Disable CFB mode test          |
+   +--------------------------------------------+---------------+--------------------------------+
+   | ``TFM_CRYPTO_TEST_ALG_CTR``                | ``OFF``       | Disable CTR mode test          |
+   +--------------------------------------------+---------------+--------------------------------+
+   | ``TFM_CRYPTO_TEST_ALG_GCM``                | ``OFF``       | Disable GCM mode test          |
+   +--------------------------------------------+---------------+--------------------------------+
+   | ``TFM_CRYPTO_TEST_ALG_SHA_512``            | ``OFF``       | Disable SHA-512 algorithm test |
+   +--------------------------------------------+---------------+--------------------------------+
+   | ``TFM_CRYPTO_TEST_HKDF``                   | ``OFF``       | Disable HKDF algorithm test    |
+   +--------------------------------------------+---------------+--------------------------------+
+
+Device configuration extension
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+To change default configurations and add platform specific configurations,
+a platform can add a platform configuration file at
+``platform/ext<TFM_PLATFORM>/config.cmake``
+
+Crypto service configurations
+-----------------------------
+
+Crypto Secure Partition
+^^^^^^^^^^^^^^^^^^^^^^^
+
+TF-M Profile Medium enables Crypto SP in top-level CMake config file.
+The following PSA Crypto operationts are enabled by default.
+
+   - Hash operations
+   - Message authentication codes
+   - Symmetric ciphers
+   - AEAD operations
+   - Asymmetric key algorithm based signature and verification
+   - Key derivation
+   - Key management
+
+Mbed Crypto configurations
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+TF-M Profile Medium adds a dedicated Mbed Crypto config file
+``tfm_mbedcrypto_config_profile_medium.h`` at
+``/lib/ext/mbedcrypto/mbedcrypto_config`` folder, instead of the common one
+``tfm_mbedcrypto_config_default.h`` [CRYPTO-DESIGN]_.
+
+Major Mbed Crypto configurations are set as listed below:
+
+    - Enable SHA256
+    - Enable generic message digest wrappers
+    - Enable AES
+    - Enable CCM mode for symmetric ciphers
+    - Disable other modes for symmetric ciphers
+    - Enable ECDH
+    - Enable ECDSA
+    - Select ECC curve ``secp256r1``
+    - Other configurations required by selected option above
+
+Other configurations can be selected to optimize the memory footprint of Crypto
+module.
+
+A device/use case can append an extra config header to the  Profile Medium
+default Mbed Crypto config file. This can be done by setting the
+``TFM_MBEDCRYPTO_PLATFORM_EXTRA_CONFIG_PATH`` cmake variable in the platform
+config file ``platform/ext<TFM_PLATFORM>/config.cmake``. This cmake variable is
+a wrapper around the ``MBEDTLS_USER_CONFIG_FILE`` options, but is preferred as
+it keeps all configuration in cmake.
+
+Internal Trusted Storage configurations
+---------------------------------------
+
+ITS service is enabled in top-level Profile Medium CMake config file by default.
+
+The internal transient buffer size ``ITS_BUF_SIZE`` [ITS-INTEGRATE]_ is set to
+32 bytes by default. A platform/use case can overwrite the buffer size in its
+specific configuration extension according to its actual requirement of assets
+and Flash attributes.
+
+Profile Medium CMake config file won't touch the configurations of device
+specific Flash hardware attributes [ITS-INTEGRATE]_.
+
+Protected Storage Secure Partition
+----------------------------------
+
+Data confidentiality, integrity and anti-rollback protection are enabled by
+default in PS.
+
+If PS is selected, AES-CCM is used as AEAD algorithm by default. It requires to
+enable PS implementation to select diverse AEAD algorithm.
+
+If platforms don't integrate any off-chip storage device, platforms can disable
+PS in platform specific configuration extension file via
+``platform/ext<TFM_PLATFORM>/config.cmake``.
+
+BL2 setting
+-----------
+
+Profile Medium enables MCUBoot provided by TF-M by default. A platform can
+overwrite this configuration by disabling MCUBoot in its configuration extension
+file ``platform/ext<TFM_PLATFORM>/config.cmake``.
+
+If MCUBoot provided by TF-M is enabled, multiple image boot is selected by
+default in TF-M Profile Medium top-level CMake config file.
+
+If a device implements its own boot loader, the configurations are
+implementation defined.
+
+****************
+Platform support
+****************
+
+To enable Profile Medium on a platform, the platform specific CMake file should
+be added into the platform support list in top-level Profile Medium CMake config
+file.
+
+Building Profile Medium
+=======================
+
+To build Profile Medium, argument ``TFM_PROFILE`` in build command line should be
+set to ``profile_medium``.
+
+Take AN521 as an example:
+
+The following commands build Profile Medium without test cases on **AN521** with
+build type **MinSizeRel**, built by **Armclang**.
+
+.. code-block:: bash
+
+   cd <TFM root dir>
+   mkdir build && cd build
+   cmake -DTFM_PLATFORM=arm/mps2/an521 \
+         -DTFM_TOOLCHAIN_FILE=../toolchain_ARMCLANG.cmake \
+         -DTFM_PROFILE=profile_medium \
+         -DCMAKE_BUILD_TYPE=MinSizeRel \
+         ../
+   cmake --build ./ -- install
+
+The following commands build Profile Medium with regression test cases on
+**AN521** with build type **MinSizeRel**, built by **Armclang**.
+
+.. code-block:: bash
+
+   cd <TFM root dir>
+   mkdir build && cd build
+   cmake -DTFM_PLATFORM=arm/mps2/an521 \
+         -DTFM_TOOLCHAIN_FILE=../toolchain_ARMCLANG.cmake \
+         -DTFM_PROFILE=profile_medium \
+         -DCMAKE_BUILD_TYPE=MinSizeRel \
+         -DTEST_S=ON -DTEST_NS=ON \
+         ../
+   cmake --build ./ -- install
+
+.. Note::
+
+ - For devices with more contrained memory and flash requirements, it is
+   possible to build with either only TEST_S enabled or only TEST_NS enabled.
+   This will decrease the size of the test images. Note that both test suites
+   must still be run to ensure correct operation.
+
+More details of building instructions and parameters can be found TF-M build
+instruction guide [TFM-BUILD]_.
+
+*********
+Reference
+*********
+
+.. [PSA-FF-M] `Arm Platform Security Architecture Firmware Framework 1.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>`_
+
+.. [RFC7925] `Transport Layer Security (TLS) / Datagram Transport Layer Security (DTLS) Profiles for the Internet of Things <https://tools.ietf.org/html/rfc7925>`_
+
+.. [PROFILE-S] :doc:`Trusted Firmware-M Profile Small Design </docs/technical_references/design_docs/profiles/tfm_profile_small>`
+
+.. [RFC7252] `The Constrained Application Protocol (CoAP) <https://tools.ietf.org/html/rfc7252>`_
+
+.. [RFC4279] `Pre-Shared Key Ciphersuites for Transport Layer Security (TLS) <https://tools.ietf.org/html/rfc4279>`_
+
+.. [RFC7251] `AES-CCM Elliptic Curve Cryptography (ECC) Cipher Suites for TLS <https://tools.ietf.org/html/rfc7251>`_
+
+.. [CRYPTO-DESIGN] :doc:`Crypto design </docs/technical_references/design_docs/tfm_crypto_design>`
+
+.. [ITS-INTEGRATE] :doc:`ITS integration guide </docs/integration_guide/services/tfm_its_integration_guide>`
+
+.. [TFM-BUILD] :doc:`TF-M build instruction </docs/technical_references/instructions/tfm_build_instruction>`
+
+--------------
+
+*Copyright (c) 2020-2021, Arm Limited. All rights reserved.*
diff --git a/docs/technical_references/design_docs/profiles/tfm_profile_small.rst b/docs/technical_references/design_docs/profiles/tfm_profile_small.rst
new file mode 100644
index 0000000..51d78f2
--- /dev/null
+++ b/docs/technical_references/design_docs/profiles/tfm_profile_small.rst
@@ -0,0 +1,647 @@
+#######################################
+Trusted Firmware-M Profile Small Design
+#######################################
+
+:Authors: David Hu
+:Organization: Arm Limited
+:Contact: david.hu@arm.com
+
+************
+Introduction
+************
+
+The capabilities and resources may dramatically vary on different IoT devices.
+Some IoT devices may have very limited memory resource. The program on those
+devices should keep small memory footprint and basic functionalities.
+On the other hand, some devices may consist of more memory and extended storage,
+to support stronger software capabilities.
+
+Diverse IoT use cases also require different levels of security and requirements
+on device resource. For example, use cases require different cipher
+capabilities. Selecting cipher suites can be sensitive to memory footprint on
+devices with constrained resource.
+
+Trusted Firmware-M (TF-M) defines 3 general profiles, Profile Small,
+Profile Medium and Profile Large, to provide different levels of security to fit
+diverse device capabilities and use cases.
+Each profile specifies a predefined list of features, targeting typical use
+cases with specific hardware constraints. Profiles can serve as reference
+designs, based on which developers can continue further development and
+configurations, according to use case.
+
+As one of the TF-M Profiles, TF-M Profile Small (Profile S) consists of
+lightweight TF-M framework and basic Secure Services to keep smallest memory
+footprint, supporting fundamental security features on devices with ultra
+constrained resource.
+
+This profile enables connecting with Edge Gateways and IoT Cloud Services
+supporting secure connection based solely on symmetric cryptography.
+
+This document summarizes and discusses the features specified in TF-M Profile
+Small.
+
+**************
+Overall design
+**************
+
+TF-M Profile Small defines the following features:
+
+    - Lightweight framework
+
+        - Library model
+        - Level 1 isolation
+        - Buffer sharing allowed
+        - Single secure context
+
+    - Crypto
+
+        - Symmetric cipher only
+        - Cipher suite for symmetric-key algorithms based protocols, such as
+          cipher suites defined in TLS pre-shared key (TLS-PSK) [1]_.
+
+            - Advanced Encryption Standard (AES) as symmetric crypto algorithm
+            - SHA256 as Hash function
+            - HMAC as Message Authentication Code algorithm
+
+    - Internal Trusted Storage (ITS)
+
+        - No encryption
+        - No rollback protection
+        - Decrease internal transient buffer size
+
+    - Initial Attestation
+
+        - Based on symmetric key algorithms
+
+    - Lightweight boot
+
+        - Single image boot
+        - Anti-rollback protection is enabled
+
+
+Protected Storage, audit logging and other Secure Services provided by TF-M are
+disabled by default.
+
+**************
+Design details
+**************
+
+More details of TF-M Profile Small design are discussed in following sections.
+
+Lightweight framework
+=====================
+
+Library model
+-------------
+
+Profile Small selects Library model in TF-M. Library model implements secure
+function calls, via which clients directly call secure services. It provides a
+more simple implementation of TF-M framework and may reduce memory footprint,
+compared with Inter-Process Communication (IPC) model [2]_.
+
+.. note ::
+
+    **Implementation note**
+
+    Please note that there is no public dedicated specification for Library
+    model.
+    The design, interfaces and implementation of Library model in TF-M may
+    change.
+
+Level 1 isolation
+-----------------
+
+So far, TF-M Library model only supports level 1 isolation [2]_, which isolates
+Secure Processing Environment (SPE) from Non-secure Processing Environment
+(NSPE). Neither level 2 nor level 3 isolation [2]_ is implemented in TF-M
+Library model.
+
+PSA Root of Trust (PSA RoT) and Application Root of Trust (ARoT) are isolated
+from each other in level 2 isolation.
+Individual secure partitions are isolated from each other even within a
+particular security domain (PSA RoT, ARoT), in level 3 isolation.
+
+Profile Small dedicated use cases with simple service model may not require
+level 2 or level 3 isolation. Devices which Profile Small aims at may be unable
+to implement stricter isolation, limited by hardware capabilities.
+
+Level 1 isolation reduces requirements enforced by hardware isolation and cost
+of software for management.
+
+.. note ::
+
+    **Security note**
+
+    If a device or a use case enforces level 2 or level 3 isolation, it is
+    suggested to apply other configurations, other than TF-M Profile Small.
+
+Buffer sharing allowed
+----------------------
+
+To simplify interface and reduce memory footprint, TF-M Library model directly
+handles client call input vectors from non-secure client buffers and later
+writes results back to those buffers, without keeping a copy in a transient
+buffer inside TF-M.
+
+.. note ::
+
+    **Security note**
+
+    There can be security vulnerabilities if non-secure client buffers are
+    directly shared between NSPE and SPE, such as Time-of-check to time-of-use
+    (TOCTOU) attack.
+
+    Developers need to check if this can meet the Security Functional
+    Requirements (SFR) of the integration of their devices.
+    Some SFRs are listed in a set of example Threat Models and Security Analyses
+    (TMSA) offered by PSA for common IoT use cases. [3]_
+
+Single secure context
+---------------------
+
+TF-M Library model only supports single secure context.
+
+It cannot support multiple contexts or the scheduling implemented in IPC model.
+It neither can support multiple outstanding PSA client calls.
+
+But correspondingly, it can save memory footprint and runtime complexity in
+context management and scheduling.
+
+.. note ::
+
+    **Security note**
+
+    Non-secure software should prevent triggering multiple outstanding PSA
+    client calls concurrently. Otherwise, it may crash current running secure
+    context.
+
+Crypto service
+==============
+
+TF-M Profile Small only requires symmetric crypto since symmetric algorithms
+require shorter keys and less computational burden, compared with asymmetric
+crypto.
+
+By default, TF-M Profile Small requires the same capabilities as defined in
+TLS-PSK, to support symmetric key algorithms based protocols.
+
+.. note ::
+
+    **Implementation note**
+
+    Please note that TF-M Profile Small doesn't require that TLS-PSK is
+    mandatory in applications. Instead, Profile Small only requires the same
+    capabilities as defined in TLS-PSK, such as one symmetric cipher algorithm
+    and one hash function.
+
+TF-M Profile Small selects TLS-PSK cipher suite TLS_PSK_WITH_AES_128_CCM [4]_
+as reference, which requires:
+
+    - AES-128-CCM (AES CCM mode with 128-bit key) as symmetric crypto algorithm
+    - SHA256 as Hash function
+    - HMAC as Message Authentication Code algorithm
+
+TLS_PSK_WITH_AES_128_CCM is selected since it requires small key length and less
+hardware capabilities, while keeping enough level of security.
+
+.. note ::
+
+    **Implementation note**
+
+    Developers can replace default algorithms with others or implement more
+    algorithms.
+
+    Proper symmetric key algorithms and cipher suites should be selected
+    according to device capabilities, the use case and the requirement of peers
+    in connection.
+
+    Refer to `Crypto service configuration`_ for implementation details of
+    configuring algorithms and cipher suites.
+
+.. note ::
+
+    **Security note**
+
+    It is recommended not to use MD5 or SHA-1 for message digests as they are
+    subject to collision attacks [5]_ [6]_.
+
+Secure Storage
+==============
+
+TF-M Profile Small assumes that extremely constrained devices only contain basic
+on-chip storage, without external or removable storage.
+As a result, TF-M Profile Small includes ITS service and disables Protected
+Storage service.
+
+Encryption and rollback protection
+----------------------------------
+
+Neither encryption nor rollback protection is enabled in current ITS
+implementation.
+
+It is expected that ITS relies solely on the physical inaccessibility property
+of on-chip storage, together with PSA isolation, without requiring additional
+cryptographic protection.
+
+Internal transient buffer
+-------------------------
+
+ITS implements a internal transient buffer [7]_ to hold the data read
+from/written to storage, especially for flash, to solve the alignment and
+security issues.
+
+The internal transient buffer is aligned to the flash device’s program unit.
+Copying data to it from the caller can align all write requests to the flash
+device’s program unit.
+The internal transient buffer can help protect Flash access from some attacks,
+such as TOCTOU attack.
+
+Although removing this internal buffer can save some memory consumption,
+typically 512 bytes, it may bring alignment or security issues.
+Therefore, to achieve a better trade-off between memory footprint and security,
+TF-M Profile Small optimizes the internal buffer size to 32 bytes by default.
+
+As discussed in `Crypto service`_, TF-M Profile Small requires AES-128 and
+SHA-256, which use 128-bit key and 256-bit key respectively.
+Besides, either long public/private keys or PKI-based certificates should be
+very rare as asymmetric crypto is not supported in Profile Small.
+Therefore, a 32-byte internal buffer should cover the assets in TF-M Profile
+Small use cases.
+
+The buffer size can be adjusted according to use case and device Flash
+attributes. Refer to `Internal Trusted Storage configurations`_ for more
+details.
+
+Initial Attestation
+===================
+
+Profile Small requires an Initial Attestation secure service based on symmetric
+key algorithms. Refer to PSA Attestation API document [8]_ for details of
+Initial Attestation based on symmetric key algorithms.
+
+It can heavily increase memory footprint to support Initial Attestation based on
+asymmetric key algorithms, due to asymmetric ciphers and related PKI modules.
+
+.. note ::
+
+    **Implementation note**
+
+    As pointed out by PSA Attestation API document [8]_, 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.
+
+    If asymmetric key algorithms based Initial Attestation is required in use
+    scenarios, it is recommended to select other TF-M Profiles which support
+    asymmetric key algorithms.
+
+.. note ::
+
+    **Implementation note**
+
+    It is recommended to utilize the same MAC algorithm supported in Crypto
+    service to complete the signing in ``COSE_Mac0``, to minimize memory
+    footprint.
+
+Lightweight boot
+================
+
+If MCUBoot provided by TF-M is enabled, single image boot [9]_ is selected by
+default in Profile Small.
+In case of single image boot, secure and non-secure images are handled as a
+single blob and signed together during image generation.
+
+However, secure and non-secure images must be updated together in single image
+boot. It may decrease the flexibility of image update and cost longer update
+process. Since the image sizes should usually be small with limited
+functionalities in Profile Small dedicated use case, the cost may still be
+reasonable.
+
+BL2 implementation can be device specific. Devices may implement diverse
+boot processes with different features and configurations.
+However, anti-rollback protection is required as a mandatory feature of boot
+loader. Boot loader should be able to prevent unauthorized rollback, to protect
+devices from being downgraded to earlier versions with known vulnerabilities.
+
+**************
+Implementation
+**************
+
+Overview
+========
+
+The basic idea is to add dedicated profile CMake configuration files under
+folder ``config/profile`` for TF-M Profile Small default configuration.
+
+The top-level Profile Small config file collects all the necessary
+configuration flags and set them to default values, to explicitly enable the
+features required in Profile Small and disable the unnecessary ones, during
+TF-M build.
+
+A platform/use case can provide a configuration extension file to overwrite
+Profile Small default setting and append other configurations.
+This configuration extension file can be added via parameter
+``TFM_EXTRA_CONFIG_PATH`` in build command line.
+
+The behaviour of the Profile Small build flow (particularly the order of
+configuration loading and overriding) can be found at
+:ref:`tfm_cmake_configuration`
+
+The details of configurations will be covered in each module in
+`Implementation details`_.
+
+Implementation details
+======================
+
+This section discusses the details of Profile Small implementation.
+
+Top-level configuration files
+-----------------------------
+
+The firmware framework configurations in ``config/profile/profile_small`` are
+shown below.
+
+.. table:: TFM options in Profile Small top-level CMake config file
+   :widths: auto
+   :align: center
+
+   +--------------------------------------------+-----------------------------------------------------------------------------------------------------+-------------------------------------+
+   | Configs                                    | Default value                                                                                       | Descriptions                        |
+   +============================================+=====================================================================================================+=====================================+
+   | ``TFM_ISOLATION_LEVEL``                    | ``1``                                                                                               | Select level 2 isolation            |
+   +--------------------------------------------+-----------------------------------------------------------------------------------------------------+-------------------------------------+
+   | ``TFM_PSA_API``                            | ``FALSE``                                                                                           | Select IPC model                    |
+   +--------------------------------------------+-----------------------------------------------------------------------------------------------------+-------------------------------------+
+   | ``TFM_PARTITION_INTERNAL_TRUSTED_STORAGE`` | ``ON``                                                                                              | Enable ITS SP                       |
+   +--------------------------------------------+-----------------------------------------------------------------------------------------------------+-------------------------------------+
+   | ``ITS_BUF_SIZE``                           | ``32``                                                                                              | ITS internal transient buffer size  |
+   +--------------------------------------------+-----------------------------------------------------------------------------------------------------+-------------------------------------+
+   | ``TFM_PARTITION_CRYPTO``                   | ``ON``                                                                                              | Enable Crypto service               |
+   +--------------------------------------------+-----------------------------------------------------------------------------------------------------+-------------------------------------+
+   | ``TFM_MBEDCRYPTO_CONFIG_PATH``             | ``${CMAKE_SOURCE_DIR}/lib/ext/mbedcrypto/mbedcrypto_config/tfm_mbedcrypto_config_profile_small.h``  | Mbed Crypto config file path        |
+   +--------------------------------------------+-----------------------------------------------------------------------------------------------------+-------------------------------------+
+   | ``CRYPTO_ASYM_SIGN_MODULE_DISABLED``       | ``ON``                                                                                              | Disable asymmetric signature        |
+   +--------------------------------------------+-----------------------------------------------------------------------------------------------------+-------------------------------------+
+   | ``CRYPTO_ASYM_ENCRYPT_MODULE_DISABLED``    | ``ON``                                                                                              | Disable asymmetric encryption       |
+   +--------------------------------------------+-----------------------------------------------------------------------------------------------------+-------------------------------------+
+   | ``TFM_PARTITION_INITIAL_ATTESTATION``      | ``ON``                                                                                              | Enable Initial Attestation service  |
+   +--------------------------------------------+-----------------------------------------------------------------------------------------------------+-------------------------------------+
+   | ``SYMMETRIC_INITIAL_ATTESTATION``          | ``ON``                                                                                              | Enable symmetric attestation        |
+   +--------------------------------------------+-----------------------------------------------------------------------------------------------------+-------------------------------------+
+   | ``TFM_PARTITION_PROTECTED_STORAGE``        | ``OFF``                                                                                             | Enable PS service                   |
+   +--------------------------------------------+-----------------------------------------------------------------------------------------------------+-------------------------------------+
+   | ``TFM_PARTITION_PLATFORM``                 | ``OFF``                                                                                             | Enable TF-M Platform SP             |
+   +--------------------------------------------+-----------------------------------------------------------------------------------------------------+-------------------------------------+
+   | ``TFM_PARTITION_AUDIT_LOG``                | ``OFF``                                                                                             | Disable TF-M audit logging service  |
+   +--------------------------------------------+-----------------------------------------------------------------------------------------------------+-------------------------------------+
+
+.. note ::
+
+    **Implementation note**
+
+    The following sections focus on the feature selection via configuration
+    setting.
+    Dedicated optimization on memory footprint is not covered in this document.
+
+Test configuration
+^^^^^^^^^^^^^^^^^^
+
+Standard regression test configuration applies. This means that enabling
+regression testing via
+
+``-DTEST_S=ON -DTEST_NS=ON``
+
+Will enable testing for all enabled partitions. See above for details of enabled
+partitions. Because Profile Small does not enable IPC mode, the IPC tests are
+not enabled.
+
+Some cryptography tests are disabled due to the reduced Mbed Crypto config.
+
+.. table:: TFM options in Profile Small top-level CMake config file
+   :widths: auto
+   :align: center
+
+   +--------------------------------------------+-----------------------------------------------------------------------------------------------------+-------------------------------------+
+   | Configs                                    | Default value                                                                                       | Descriptions                        |
+   +============================================+=====================================================================================================+=====================================+
+   | ``TFM_CRYPTO_TEST_ALG_CBC``                | ``OFF``                                                                                             | Test CBC cryptography mode          |
+   +--------------------------------------------+-----------------------------------------------------------------------------------------------------+-------------------------------------+
+   | ``TFM_CRYPTO_TEST_ALG_CCM``                | ``ON``                                                                                              | Test CCM cryptography mode          |
+   +--------------------------------------------+-----------------------------------------------------------------------------------------------------+-------------------------------------+
+   | ``TFM_CRYPTO_TEST_ALG_CFB``                | ``OFF``                                                                                             | Test CFB cryptography mode          |
+   +--------------------------------------------+-----------------------------------------------------------------------------------------------------+-------------------------------------+
+   | ``TFM_CRYPTO_TEST_ALG_CTR``                | ``OFF``                                                                                             | Test CTR cryptography mode          |
+   +--------------------------------------------+-----------------------------------------------------------------------------------------------------+-------------------------------------+
+   | ``TFM_CRYPTO_TEST_ALG_GCM``                | ``OFF``                                                                                             | Test GCM cryptography mode          |
+   +--------------------------------------------+-----------------------------------------------------------------------------------------------------+-------------------------------------+
+   | ``TFM_CRYPTO_TEST_ALG_SHA_512``            | ``OFF``                                                                                             | Test SHA-512 cryptography algorithm |
+   +--------------------------------------------+-----------------------------------------------------------------------------------------------------+-------------------------------------+
+   | ``TFM_CRYPTO_TEST_HKDF``                   | ``OFF``                                                                                             | Test SHA-512 cryptography algorithm |
+   +--------------------------------------------+-----------------------------------------------------------------------------------------------------+-------------------------------------+
+
+Device configuration extension
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+To change default configurations and add platform specific configurations,
+a platform can add a platform configuration file at
+``platform/ext<TFM_PLATFORM>/config.cmake``
+
+TF-M framework setting
+----------------------
+
+The top-level Profile Small CMake config file selects Library model and level 1
+isolation.
+
+Crypto service configuration
+----------------------------
+
+Crypto Secure Partition
+^^^^^^^^^^^^^^^^^^^^^^^
+
+TF-M Profile Small enables Crypto Secure Partition (SP) in its top-level CMake
+config file. Crypto SP modules not supported in TF-M Profile Small are disabled.
+The disabled modules are shown below.
+
+    - Disable asymmetric cipher
+
+Other modules and configurations [10]_ are kept as default values.
+
+Additional configuration flags with more fine granularity can be added to
+control building of specific crypto algorithms and corresponding test cases.
+
+Mbed Crypto configurations
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+TF-M Profile Small adds a dedicated Mbed Crypto config file
+``tfm_mbedcrypto_config_profile_small.h`` at
+``/lib/ext/mbedcrypto/mbedcrypto_config``
+file, instead of the common one ``tfm_mbedcrypto_config_default.h`` [10]_.
+
+Major Mbed Crypto configurations are set as listed below:
+
+    - Enable SHA256
+    - Enable generic message digest wrappers
+    - Enable AES
+    - Enable CCM mode for symmetric ciphers
+    - Disable other modes for symmetric ciphers
+    - Disable asymmetric ciphers
+    - Disable HMAC-based key derivation function (HKDF)
+
+Other configurations can be selected to optimize the memory footprint of Crypto
+module.
+
+A device/use case can append an extra config header to the  Profile Small
+default Mbed Crypto config file. This can be done by setting the
+``TFM_MBEDCRYPTO_PLATFORM_EXTRA_CONFIG_PATH`` cmake variable in the platform
+config file ``platform/ext<TFM_PLATFORM>/config.cmake``. This cmake variable is
+a wrapper around the ``MBEDTLS_USER_CONFIG_FILE`` options, but is preferred as
+it keeps all configuration in cmake.
+
+Internal Trusted Storage configurations
+---------------------------------------
+
+ITS service is enabled in top-level Profile Small CMake config file.
+
+The internal transient buffer size ``ITS_BUF_SIZE`` [7]_ is set to 32 bytes by
+default. A platform/use case can overwrite the buffer size in its specific
+configuration extension according to its actual requirement of assets and Flash
+attributes.
+
+Profile Small CMake config file won't touch the configurations of device
+specific Flash hardware attributes [7]_.
+
+Initial Attestation secure service
+----------------------------------
+
+TF-M Profile Small provides a reference implementation of symmetric key
+algorithms based Initial Attestation, using HMAC SHA-256 as MAC algorithm in
+``COSE_Mac0`` structure. The implementation follows PSA Attestation API document
+[8]_.
+
+Profile Small top-level config file enables Initial Attestation secure service
+and selects symmetric key algorithms based Initial Attestation by default.
+
+    - Set ``TFM_PARTITION_INITIAL_ATTESTATION`` to ``ON``
+    - Set ``SYMMETRIC_INITIAL_ATTESTATION`` to ``ON``
+
+Symmetric and asymmetric key algorithms based Initial Attestation can share the
+same generations of token claims, except Instance ID claim.
+
+Profile Small may implement the procedure or rely on a 3rd-party tool to
+construct and sign ``COSE_Mac0`` structure.
+
+Details of symmetric key algorithms based Initial Attestation design will be
+covered in a dedicated document.
+
+Disabled secure services
+------------------------
+
+Audit logging, Protected Storage, and Platform Service are disabled by default
+in Profile Small top-level CMake config file.
+
+BL2 setting
+-----------
+
+Profile Small enables MCUBoot provided by TF-M by default. A platform can
+overwrite this configuration by disabling MCUBoot in its configuration extension
+file ``platform/ext<TFM_PLATFORM>/config.cmake``.
+
+If MCUBoot provided by TF-M is enabled, single image boot is selected in TF-M
+Profile Small top-level CMake config file.
+
+If a device implements its own boot loader, the configurations are
+implementation defined.
+
+.. table:: BL2 options in Profile Small top-level CMake config file
+   :widths: auto
+   :align: center
+
+   +--------------------------------------------+-----------------------------------------------------------------------------------------------------+-------------------------------------+
+   | Configs                                    | Default value                                                                                       | Descriptions                        |
+   +============================================+=====================================================================================================+=====================================+
+   | ``BL2``                                    | ``ON``                                                                                              | Enable MCUBoot bootloader           |
+   +--------------------------------------------+-----------------------------------------------------------------------------------------------------+-------------------------------------+
+   | ``MCUBOOT_IMAGE_NUMBER``                   | ``1``                                                                                               | Combine S and NS images             |
+   +--------------------------------------------+-----------------------------------------------------------------------------------------------------+-------------------------------------+
+
+****************
+Platform support
+****************
+
+Building Profile Small
+======================
+
+To build Profile Small, argument ``TFM_PROFILE`` in build command line should be
+set to ``profile_small``.
+
+Take AN521 as an example.
+
+The following commands build Profile Small without test cases on **AN521** with
+build type **MinSizeRel**, built by **Armclang**.
+
+.. code-block:: bash
+
+   cd <TFM root dir>
+   mkdir build && cd build
+   cmake -DTFM_PLATFORM=arm/mps2/an521 \
+         -DTFM_TOOLCHAIN_FILE=../toolchain_ARMCLANG.cmake \
+         -DTFM_PROFILE=profile_small \
+         -DCMAKE_BUILD_TYPE=MinSizeRel \
+         ../
+   cmake --build ./ -- install
+
+The following commands build Profile Small with regression test cases on **AN521**
+with build type **MinSizeRel**, built by **Armclang**.
+
+.. code-block:: bash
+
+   cd <TFM root dir>
+   mkdir build && cd build
+   cmake -DTFM_PLATFORM=arm/mps2/an521 \
+         -DTFM_TOOLCHAIN_FILE=../toolchain_ARMCLANG.cmake \
+         -DTFM_PROFILE=profile_small \
+         -DCMAKE_BUILD_TYPE=MinSizeRel \
+         -DTEST_S=ON -DTEST_NS=ON \
+         ../
+   cmake --build ./ -- install
+
+.. Note::
+
+ - For devices with more contrained memory and flash requirements, it is
+   possible to build with either only TEST_S enabled or only TEST_NS enabled.
+   This will decrease the size of the test images. Note that both test suites
+   must still be run to ensure correct operation.
+
+More details of building instructions and parameters can be found TF-M build
+instruction guide [11]_.
+
+*********
+Reference
+*********
+
+.. [1] `Pre-Shared Key Ciphersuites for Transport Layer Security (TLS) <https://tools.ietf.org/html/rfc4279>`_
+
+.. [2] `DEN0063 Arm Platform Security Architecture Firmware Framework 1.0 <https://developer.arm.com/-/media/Files/pdf/DeviceSecurityArchitecture/Architect/DEN0063-PSA_Firmware_Framework-1.0.0-2.pdf?revision=2d1429fa-4b5b-461a-a60e-4ef3d8f7f4b4>`_
+
+.. [3] `PSA analyze stage <https://developer.arm.com/architectures/security-architectures/platform-security-architecture#analyze>`_
+
+.. [4] `AES-CCM Cipher Suites for Transport Layer Security (TLS) <https://tools.ietf.org/html/rfc6655>`_
+
+.. [5] `Updated Security Considerations for the MD5 Message-Digest and the HMAC-MD5 Algorithms <https://tools.ietf.org/html/rfc6151>`_
+
+.. [6] `Transitioning the Use of Cryptographic Algorithms and Key Lengths <https://www.nist.gov/publications/transitioning-use-cryptographic-algorithms-and-key-lengths>`_
+
+.. [7] :doc:`ITS integration guide </docs/integration_guide/services/tfm_its_integration_guide>`
+
+.. [8] `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>`_
+
+.. [9] :doc:`Secure boot </docs/technical_references/design_docs/tfm_secure_boot>`
+
+.. [10] :doc:`Crypto design </docs/technical_references/design_docs/tfm_crypto_design>`
+
+.. [11] :doc:`TF-M build instruction </docs/technical_references/instructions/tfm_build_instruction>`
+
+--------------
+
+*Copyright (c) 2020-2021, Arm Limited. All rights reserved.*
diff --git a/docs/technical_references/design_docs/ps_key_management.rst b/docs/technical_references/design_docs/ps_key_management.rst
new file mode 100644
index 0000000..80a39be
--- /dev/null
+++ b/docs/technical_references/design_docs/ps_key_management.rst
@@ -0,0 +1,183 @@
+========================================
+Protected Storage service key management
+========================================
+
+:Author: Jamie Fox
+:Organization: Arm Limited
+:Contact: Jamie Fox <jamie.fox@arm.com>
+:Status: Accepted
+
+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]_
+
+In the current implementation, the Protected Storage (PS) service reads the HUK
+directly and imports it into the Crypto partition for further use. This has
+multiple drawbacks:
+
+- If there were a flaw in PS that allowed an attacker to obtain its key, then
+  the HUK would be exposed, and so the attacker would be able to decrypt not
+  just protected storage but also anything else encrypted with the HUK or a key
+  derived from the HUK.
+- Using the same key for two or more different cryptographic algorithms may
+  reduce the security provided by one or more of them.
+- It is not possible to re-key if the HUK is used directly, for example in the
+  case of a lost key.
+- It is incompatible with devices where the HUK is in an enclave and cannot be
+  read directly.
+
+Proposal
+========
+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. 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 will be
+made::
+
+    /* Open a handle to the HUK */
+    psa_open_key(PSA_KEY_LIFETIME_PERSISTENT,
+                 TFM_CRYPTO_KEY_ID_HUK,
+                 &huk_key_handle)
+
+    /* Set up a key derivation operation with the HUK as the input key */
+    psa_key_derivation(&ps_key_generator,
+                       huk_key_handle,
+                       TFM_CRYPTO_ALG_HUK_DERIVATION,
+                       PS_KEY_SALT, PS_KEY_SALT_LEN_BYTES,
+                       PS_KEY_LABEL, PS_KEY_LABEL_LEN_BYTES,
+                       PS_KEY_LEN_BYTES)
+
+    /* Create the storage key from the key generator */
+    psa_generator_import_key(ps_key_handle,
+                             PS_KEY_TYPE,
+                             PSA_BYTES_TO_BITS(PS_KEY_LEN_BYTES),
+                             &ps_key_generator)
+
+.. note:: ``TFM_CRYPTO_KEY_ID_HUK`` is a PSA Crypto key ID that is assumed in
+          this design to identify the hardware unique key.
+
+          ``ps_key_handle`` is a PSA Crypto key handle to a volatile key, set
+          up in the normal way. After the call to ``psa_generator_import_key``,
+          it contains the storage key.
+
+          ``PS_KEY_SALT`` can be ``NULL``, as it is only used in the 'extract'
+          step of HKDF, which is redundant when the input key material is a
+          cryptographically strong key. [RFC5869]_ It must be constant so that
+          the same key can be derived each boot, to decrypt previously-stored
+          data.
+
+          ``PS_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.
+
+In the call to ``psa_key_derivation()``, ``TFM_CRYPTO_ALG_HUK_DERIVATION`` is
+supplied as the key derivation algorithm argument. This indicates that the key
+derivation should be done from the HUK, and allows it to be implemented in a
+platform-defined way (e.g. using a crypto accelerator). The system integrator
+should choose the most optimal algorithm for the platform, or fall back to the
+software implementation if none is available.
+
+When implemented in software, 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 salt and label fields are not generally secret, so an Application RoT
+service could request the Crypto service to derive the same storage key from the
+HUK, which violates isolation between Application RoT partitions to some extent.
+This could be fixed in a number of ways:
+
+- Only PSA RoT partitions can request Crypto to derive keys from the HUK.
+
+  - But then either PS has to be in the PSA RoT or request a service in the PSA
+    RoT to do the derivation on its behalf.
+
+- PS has a secret (pseudo)random salt, accessible only to it, that it uses to
+  derive the storage key.
+
+  - Where would this salt be stored? It cannot be generated fresh each boot
+    because the storage key must stay the same across reboots.
+
+- The Crypto service appends the partition ID to the label, so that no two
+  partitions can derive the same key.
+
+  - Still need to make sure only PSA RoT partitions can directly access the HUK
+    or Secure Enclave. The label is not secret, so any actor that can access the
+    HUK could simply perform the derivation itself, rather than making a request
+    to the Crypto service.
+
+The third option would solve the issue with the fewest drawbacks, so this option
+is the one that is proposed.
+
+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_handle`` will refer to the
+storage key, rather than the imported HUK. For each encryption operation, the
+following call is made (and analogously for decryption)::
+
+    psa_aead_encrypt(ps_key_handle, PS_CRYPTO_ALG,
+                     crypto->ref.iv, PS_IV_LEN_BYTES,
+                     add, add_len,
+                     in, in_len,
+                     out, out_size, out_len)
+
+Future changes
+==============
+In the future, the client's partition ID and the asset's UID could be used to
+derive a key that is unique to that asset, each time the Protected Storage APIs
+are called (*key diversification*). To achieve this, the key derivation must use
+a ``label`` parameter that is unique to each client ID, UID pair.
+
+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-2020, Arm Limited. All rights reserved.*
diff --git a/docs/technical_references/design_docs/secure_boot_hw_key_integration.rst b/docs/technical_references/design_docs/secure_boot_hw_key_integration.rst
new file mode 100644
index 0000000..186e4a6
--- /dev/null
+++ b/docs/technical_references/design_docs/secure_boot_hw_key_integration.rst
@@ -0,0 +1,166 @@
+HW crypto key integration in TF-M secure boot
+=============================================
+
+:Author: Tamas Ban
+:Organization: Arm Limited
+:Contact: Tamas Ban <tamas.ban@arm.com>
+:Status: Accepted
+
+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/technical_references/design_docs/secure_boot_rollback_protection.rst b/docs/technical_references/design_docs/secure_boot_rollback_protection.rst
new file mode 100644
index 0000000..711fac3
--- /dev/null
+++ b/docs/technical_references/design_docs/secure_boot_rollback_protection.rst
@@ -0,0 +1,203 @@
+#######################################
+Rollback protection in TF-M secure boot
+#######################################
+
+:Author: Tamas Ban
+:Organization: Arm Limited
+:Contact: Tamas Ban <tamas.ban@arm.com>
+:Status: Accepted
+
+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/technical_references/design_docs/secure_enclave_solution.rst b/docs/technical_references/design_docs/secure_enclave_solution.rst
new file mode 100644
index 0000000..1f4ecc6
--- /dev/null
+++ b/docs/technical_references/design_docs/secure_enclave_solution.rst
@@ -0,0 +1,121 @@
+##############################################
+Secure Enclave solution for Trusted Firmware-M
+##############################################
+
+:Author: Mark Horvath
+:Organization: Arm Limited
+:Contact: Mark Horvath <mark.horvath@arm.com>
+
+********
+Abstract
+********
+
+This document summarizes the design goals and one possible implementation
+of the TF-M Secure Enclave solution.
+
+************
+Introduction
+************
+
+If a separate subsystem can provide the PSA Root of Trust (RoT) in a system
+then an additional physical separation exists between the most trusted and
+other domains. In such a system at least two subsystems are present, a Secure
+Enclave (SE) whose only task is to provide PSA RoT and an application core
+where any other application specific functionality can be placed. The latter
+core (or cores) are referred as *Host* in this document.
+
+The current design assumes that Host is a v8-m core with security extension.
+
+************
+Requirements
+************
+
+- Secure Enclave shall implement secure boot-flow (start-up first at reset and
+  validate its own and the Host image or images before release Host from reset)
+- Secure Enclave shall provide the PSA RoT services
+- Host shall provide not just the non-secure context but the Application RoT as
+  well
+- It shall be transparent to the (secure or non-secure) applications running on
+  host whether the RoT services are provided by the same subsystem or by a
+  Secure Enclave.
+
+.. Note::
+
+   In comparison, in a Dual Core system the whole secure context is placed on a
+   separate subsystem, while a Secure Enclave only implements the PSA RoT
+   security domain.
+
+***************
+Proposed design
+***************
+
+As the clients and the services are running on different cores only the IPC
+model can be used on both Secure Enclave and Host.
+
+Secure Enclave
+==============
+
+To provide the required functionality it is enough to run the current PSA RoT
+secure partitions on the Secure Enclave, so no need for non-secure context
+there. (It is enough if the Secure Enclave's architecture is v6-m, v7-m or v8-m
+without the security extension.)
+
+Secure Enclave can treat all clients running on Host as non-secure (even the
+services running on Host's secure side). This means that fom Secure Enclave's
+point of view all Host images, Host's RAM and shared memory between Host and
+Secure Enclave if present are treated as non-secure. (Just like in the Dual CPU
+solution.) But the clients need to be distinguished, otherwise some
+functionalities are not working, for example:
+- Protected Storage partition shall run on Host, but the PS area is handled by
+Internal Trusted Storage partition (running on Secure Enclave). ITS partition
+decides whether it should work on PS or ITS assets by checking the client ID.
+- If a secure partition on host creates a crypto key, no other client shall be
+able to destroy it.
+
+Communication
+=============
+
+To communicate between Host and Secure Enclave, the existing mailbox solution
+can be reused as it is.
+
+Host
+====
+
+On Host the current TF-M software architecture can be placed to provide
+non-secure context and Application RoT domain.
+
+One solution to forward a PSA RoT IPC message from a client running on Host to
+the Secure Enclave is to add a proxy partition to the secure side. This PSA
+Proxy partition can provide all the RoT services to the system by forwarding
+the messages over the mailbox solution.
+
+If the new partition's manifest contains all the PSA RoT service IDs SPM will
+deliver all IPC messages there. Then the messages just must be blindly copied
+into the mailbox. PSA proxy can use the non-secure interface of the mailbox,
+but it is placed on the secure side of Host. (From SE's point of view this is
+in fact the non-secure side of the mailbox as whole Host is treated as
+non-secure.)
+
+It is important to verify IOVECs before forwarding them to SE, otherwise a
+malicous actor could use SE to access a memory area otherwise unaccessable. If
+PSA proxy uses the current secure partition interface then this is ensured by
+Host's SPM.
+
+SE treats all clients of Host as non-secure, so all PSA messages shall have a
+negative client ID when pushed into SE's SPM. This is given for the clients on
+the non-secure side of Host, but the secure side clients of Host have positive
+client IDs. The straightforward solution is to translate the positive client
+IDs into a predefined negative range in PSA proxy, and push the translated
+values into the mailbox. Of course this range shall be reserved for this use
+only and no clients on non-secure side of Host shall have client ID from this
+range.
+
+To avoid blocking Host when a message is sent PSA Proxy shall handle the
+service requests in non-blocking mode. And to maximize bandwidth PSA Proxy
+shall be able to push new messages into the mailbox, while others still not
+answered. To achieve these the mailbox interrupts needs to be handled in the
+PSA Proxy partition.
+
+--------------
+
+*Copyright (c) 2020, Arm Limited. All rights reserved.*
diff --git a/docs/technical_references/design_docs/source_structure.rst b/docs/technical_references/design_docs/source_structure.rst
new file mode 100644
index 0000000..b2de0dd
--- /dev/null
+++ b/docs/technical_references/design_docs/source_structure.rst
@@ -0,0 +1,165 @@
+###################################
+Trusted Firmware-M Source Structure
+###################################
+
+:Organization: Arm Limited
+:Contact: tf-m@lists.trustedfirmware.org
+
+.. note::
+  Reference the document :doc:`Glossary </docs/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/sprt/\*                       The SPRTL sources and intermedia files. [1]
+lib/sprt/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]
+cmsis_func/\*                       The library model implementation. [2]
+\*                                  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-2021, Arm Limited. All rights reserved.*
diff --git a/docs/technical_references/design_docs/stateless_rot_service.rst b/docs/technical_references/design_docs/stateless_rot_service.rst
new file mode 100644
index 0000000..964c18c
--- /dev/null
+++ b/docs/technical_references/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/technical_references/design_docs/symmetric_initial_attest.rst b/docs/technical_references/design_docs/symmetric_initial_attest.rst
new file mode 100644
index 0000000..c139d64
--- /dev/null
+++ b/docs/technical_references/design_docs/symmetric_initial_attest.rst
@@ -0,0 +1,601 @@
+#################################################
+Symmetric key algorithm based Initial Attestation
+#################################################
+
+:Authors: 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.
+
+.. _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.
+
+    - Fetch and register IAK
+    - ``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 IAK and 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.
+
+Register symmetric IAK
+======================
+
+Symmetric Initial Attestation dedicated ``attest_symmetric_key.c`` implements 4
+major functions. The functions are listed in the table below.
+
+.. table:: Functions in ``attest_symmetric_key.c``
+    :widths: auto
+    :align: center
+
+    +-------------------------------------------------+----------------------------------------------------+
+    | Functions                                       | Descriptions                                       |
+    +=================================================+====================================================+
+    | ``attest_register_initial_attestation_key()``   | Fetches device symmetric IAK, imports it into      |
+    |                                                 | Crypto service and get the handle.                 |
+    |                                                 | The handle will be used to compute the             |
+    |                                                 | authentication tag of IAT.                         |
+    |                                                 | Invokes HAL API ``tfm_plat_get_symmetric_iak()``   |
+    |                                                 | to fetch symmetric IAK from device.                |
+    |                                                 |                                                    |
+    |                                                 | Refer to `HAL APIs`_ for more details.             |
+    +-------------------------------------------------+----------------------------------------------------+
+    | ``attest_unregister_initial_attestation_key()`` | Destroys the symmetric IAK handle after IAT        |
+    |                                                 | generation completes.                              |
+    +-------------------------------------------------+----------------------------------------------------+
+    | ``attest_get_signing_key_handle()``             | Return the IAK handle registered in                |
+    |                                                 | ``attest_register_initial_attestation_key()``.     |
+    +-------------------------------------------------+----------------------------------------------------+
+    | ``attest_get_instance_id()``                    | Return the Instance ID value calculated in         |
+    |                                                 | ``attest_register_initial_attestation_key()``.     |
+    |                                                 |                                                    |
+    |                                                 | Refer to `Instance ID claim`_ for more details.    |
+    +-------------------------------------------------+----------------------------------------------------+
+
+``attest_register_initial_attestation_key()`` and
+``attest_unregister_initial_attestation_key()`` share the same API declarations
+with asymmetric Initial Attestation.
+
+``attest_get_signing_key_handle()`` and ``attest_get_instance_id()`` are defined
+by symmetric Initial Attestation but can be shared with asymmetric Initial
+Attestation later.
+
+.. note ::
+
+    Only symmetric IAK for HMAC algorithm is allowed so far.
+
+Instance ID calculation
+-----------------------
+
+In symmetric Initial Attestation, Instance ID is also calculated in
+``attest_register_initial_attestation_key()``, after IAK handle is registered.
+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 returned by ``attest_get_signing_key_handle()``.
+   See the details in `Register symmetric IAK`_.
+
+#. 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 </docs/technical_references/design_docs/profiles/tfm_profile_small>`
+
+.. [3] :doc:`Initial Attestation Service Integration Guide </docs/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-2021 Arm Limited. All Rights Reserved.*
diff --git a/docs/technical_references/design_docs/tfm_code_generation_with_jinja2.rst b/docs/technical_references/design_docs/tfm_code_generation_with_jinja2.rst
new file mode 100644
index 0000000..f16fc29
--- /dev/null
+++ b/docs/technical_references/design_docs/tfm_code_generation_with_jinja2.rst
@@ -0,0 +1,79 @@
+###########################
+Code Generation With Jinja2
+###########################
+
+:Author: Mate Toth-Pal
+:Organization: Arm Limited
+:Contact: Mate Toth-Pal <mate.toth-pal@arm.com>
+:Status: Accepted
+
+***************************************
+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/technical_references/design_docs/tfm_cooperative_scheduling_rules.rst b/docs/technical_references/design_docs/tfm_cooperative_scheduling_rules.rst
new file mode 100644
index 0000000..b1c4e76
--- /dev/null
+++ b/docs/technical_references/design_docs/tfm_cooperative_scheduling_rules.rst
@@ -0,0 +1,211 @@
+############################
+Cooperative Scheduling Rules
+############################
+
+:Author: Ashutosh Singh
+:Organization: Arm Limited
+:Contact: Ashutosh Singh <ashutosh.singh@arm.com>
+:Status: Accepted
+
+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/technical_references/design_docs/tfm_crypto_design.rst b/docs/technical_references/design_docs/tfm_crypto_design.rst
new file mode 100644
index 0000000..e2785a5
--- /dev/null
+++ b/docs/technical_references/design_docs/tfm_crypto_design.rst
@@ -0,0 +1,198 @@
+Crypto Service design
+=====================
+
+:Author: Antonio de Angelis
+:Organization: Arm Limited
+:Contact: Antonio de Angelis <antonio.deangelis@arm.com>
+:Status: Accepted
+
+.. 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**                                                         |
+   +=============================+===============================================================+======================================================================+
+   | SPE client API interface    | This module exports the client API of PSA Crypto to the other | ``./secure_fw/partitions/crypto/tfm_crypto_secure_api.c``            |
+   |                             | services available in TF-M.                                   |                                                                      |
+   +-----------------------------+---------------------------------------------------------------+----------------------------------------------------------------------+
+   | NSPE client API interface   | This module exports the client API of PSA Crypto to the NSPE  | ``./interface/src/tfm_crypto_api.c``                                 |
+   |                             | (i.e. to the applications).                                   |                                                                      |
+   +-----------------------------+---------------------------------------------------------------+----------------------------------------------------------------------+
+   | 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 mode.                     |                                                                      |
+   |                             | Due to the fact that the functions available in the Service   |                                                                      |
+   |                             | modules use the Uniform Signature prototype [2]_ , 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``                       |
+   |                             | All the functions in the Service modules are based on the     |                                                                      |
+   |                             | Uniform Signature prototype [2]_ .                            |                                                                      |
+   +-----------------------------+---------------------------------------------------------------+----------------------------------------------------------------------+
+   | Manifest                    | The manifest file is a description of the service components  | ``./secure_fw/partitions/crypto/manifest.yaml``                      |
+   |                             | for both library mode and IPC mode.                           |                                                                      |
+   +-----------------------------+---------------------------------------------------------------+----------------------------------------------------------------------+
+   | 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 mode.                                        |                                                                      |
+   |                             | 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    | ``./docs/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 mode, 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) is based on the Uniform Signature prototypes [2]_ and 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   |
+   |                                |              |                 | mode, 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 mode builds. In IPC mode,   | 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           | ``./platform/ext/common/tfm_mbedcrypto_config.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.                         |                                         |                                                    |
+   +-------------------------------+---------------------------+----------------------------------------------------------------+-----------------------------------------+----------------------------------------------------+
+
+References
+----------
+
+.. [1] ``mbed-crypto`` repository which holds the PSA Crypto API specification and the Mbed Crypto reference implementation: \ https://github.com/ARMmbed/mbed-crypto
+
+.. [2] Uniform Signature prototypes: \ https://developer.trustedfirmware.org/w/tf_m/design/uniform_secure_service_signature/
+
+
+--------------
+
+*Copyright (c) 2019-2020, Arm Limited. All rights reserved.*
diff --git a/docs/technical_references/design_docs/tfm_fwu_service.rst b/docs/technical_references/design_docs/tfm_fwu_service.rst
new file mode 100644
index 0000000..46c98f3
--- /dev/null
+++ b/docs/technical_references/design_docs/tfm_fwu_service.rst
@@ -0,0 +1,315 @@
+#######################
+Firmware Update Service
+#######################
+
+:Author: Sherry Zhang
+:Organization: Arm Limited
+:Contact: Sherry Zhang <Sherry.Zhang2@arm.com>
+
+.. contents:: Table of Contents
+
+***************************************
+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 image information
+  Fetch information about the firmware images on the device. This covers the
+  images in the running area and also the staging area.
+- Store image
+  Write a candidate image to its staging area.
+- Validate image
+  Starts the validation of the image.
+- Trigger reboot
+  Trigger a reboot to restart the platform.
+
+**********
+Components
+**********
+The structure of the TF-M Firmware Update service is listed below:
+   +-----------------------------+---------------------------------------------------------------+----------------------------------------------------------------------------------+
+   | **Component name**          | **Description**                                               | **Location**                                                                     |
+   +=============================+===============================================================+==================================================================================+
+   | SPE client API interface    | This module exports the client API of PSA Firmware Update to  | ``./secure_fw/partitions/firmware_update/tfm_fwu_secure_api.c``                  |
+   |                             | the other services available in TF-M.                         |                                                                                  |
+   +-----------------------------+---------------------------------------------------------------+----------------------------------------------------------------------------------+
+   | NSPE client API interface   | This module exports the client API of PSA Firmware Update to  | ``./interface/src/tfm_firmware_update_func_api.c``                               |
+   |                             | the NSPE(i.e. to the applications).                           | ``./interface/src/tfm_firmware_update_ipc_api.c``                                |
+   +-----------------------------+---------------------------------------------------------------+----------------------------------------------------------------------------------+
+   | Manifest                    | The manifest file is a description of the service components  | ``./secure_fw/partitions/firmware_update/tfm_firmware_update.yaml``              |
+   |                             | for both library mode and IPC mode.                           |                                                                                  |
+   +-----------------------------+---------------------------------------------------------------+----------------------------------------------------------------------------------+
+   | Secure functions and IPC    | This module handles all the secure function requests in       | ``./secure_fw/partitions/firmware_update/tfm_fwu_req_mngr.c``                    |
+   | request handlers            | library model and all the service requests in IPC model.      |                                                                                  |
+   |                             | It maitains the image state context and calls the image ID    |                                                                                  |
+   |                             | converter to achieve the firmware update functionalities.     |                                                                                  |
+   +-----------------------------+---------------------------------------------------------------+----------------------------------------------------------------------------------+
+   | Image ID Converter          | This module converts the image ID between psa_image_id_t,     | ``./secure_fw/partitions/firmware_update/tfm_fwu_internal.c``                    |
+   |                             | which is the image ID structure in user interfaces, and       |                                                                                  |
+   |                             | bl_image_id_t which is the image ID structure in bootloader.  |                                                                                  |
+   +-----------------------------+---------------------------------------------------------------+----------------------------------------------------------------------------------+
+   | Shim layer between FWU and  | This module provides the APIs with the functionality of       | ``./secure_fw/partitions/firmware_update/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 0.7 [1]_.
+It implements the mandatory interface functions listed in section 5.1 and the
+optional interface ``psa_fwu_accept()``. 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, such as reading
+some necessary shared data from the memory if needed.
+
+Parameters
+^^^^^^^^^^
+    N/A
+
+fwu_bootloader_staging_area_init(function)
+------------------------------------------
+**Prototype**
+
+.. code-block:: c
+
+    psa_status_t fwu_bootloader_staging_area_init(bl_image_id_t bootloader_image_id);
+
+**Description**
+
+Prepare the staging area of the image with the given ID for image download.
+For example, initialize the staging area, open the flash area, and so on.
+The image will be written into the staging area later.
+
+**Parameters**
+
+- ``bootloader_image_id``: The identifier of the target image in bootloader.
+
+fwu_bootloader_load_image(function)
+-----------------------------------
+**Prototype**
+
+.. code-block:: c
+
+    psa_status_t fwu_bootloader_load_image(bl_image_id_t bootloader_image_id,
+                                           size_t        image_offset,
+                                           const void    *block,
+                                           size_t        block_size);
+
+**Description**
+
+Load the image to its staging area.
+
+**Parameters**
+
+- ``bootloader_image_id``: The identifier of the target image 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(bl_image_id_t bootloader_image_id,
+                                              bl_image_id_t       *dependency,
+                                              psa_image_version_t *dependency_version);
+
+**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**
+
+- ``bootloader_image_id``: The identifier of the target image in bootloader.
+- ``dependency``: Bootloader image ID of dependency if needed.
+- ``dependency_version``: Bootloader image version of dependency if needed.
+
+fwu_bootloader_mark_image_accepted(function)
+--------------------------------------------
+**Prototype**
+
+.. code-block:: c
+
+    psa_status_t fwu_bootloader_mark_image_accepted(bl_image_id_t bootloader_image_id);
+
+**Description**
+
+Call this API to mark the running images as permanent/accepted to avoid
+revert when next time bootup. Usually, this API is called after the running
+images have been verified as valid.
+
+**Parameters**
+
+    N/A
+
+fwu_bootloader_abort(function)
+------------------------------
+**Prototype**
+
+.. code-block:: c
+
+    psa_status_t fwu_bootloader_abort(void);
+
+**Description**
+
+Abort the current image download process.
+
+**Parameters**
+
+    N/A
+
+fwu_bootloader_get_image_info(function)
+---------------------------------------
+**Prototype**
+
+.. code-block:: c
+
+    psa_status_t fwu_bootloader_get_image_info(bl_image_id_t    bootloader_image_id,
+                                               bool             staging_area,
+                                               tfm_image_info_t *info);
+
+**Description**
+
+Get the image information of the given bootloader_image_id in the staging area
+or the running area.
+
+**Parameters**
+
+    - ``bootloader_image_id``: The identifier of the target image in bootloader.
+    - ``active_image``: Indicates image location.
+
+        - ``True``: the running image.
+        - ``False``: the image in the passive(or staging) slot.
+
+    - ``info``: Buffer containing the image 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.
+
+******************
+Image ID structure
+******************
+The structure of image ID is:
+    image_id[7:0]: slot.
+    image_id[15:8]: image type.
+    image_id[31:16]: specific image ID.
+
+Three image types are defined in this partition.
+- FWU_IMAGE_TYPE_NONSECURE: the non_secure image
+- FWU_IMAGE_TYPE_SECURE: the secure image
+- FWU_IMAGE_TYPE_FULL: the secure + non_secure image
+
+Macros **FWU_CALCULATE_IMAGE_ID**, **FWU_IMAGE_ID_GET_TYPE** and
+**FWU_IMAGE_ID_GET_SLOT** are dedicated to converting the image id, type, and
+slot. The service users can call these macros to get the image ID.
+
+.. Note::
+
+    The image ID structure, as well as the macros listed here, is TF-M specific implementation.
+
+***********************************
+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. The library model implementation can be referred to for the
+non-secure side implementation.
+
+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://developer.arm.com/documentation/ihi0093/0000/>`_
+
+--------------
+
+*Copyright (c) 2021, Arm Limited. All rights reserved.*
diff --git a/docs/technical_references/design_docs/tfm_its_512_flash.rst b/docs/technical_references/design_docs/tfm_its_512_flash.rst
new file mode 100644
index 0000000..00f60f8
--- /dev/null
+++ b/docs/technical_references/design_docs/tfm_its_512_flash.rst
@@ -0,0 +1,104 @@
+###############################################################
+Add support for block-aligned flash in Internal Trusted Storage
+###############################################################
+
+:Author: Minos Galanakis
+:Organization: Arm Limited
+:Contact: Minos Galanakis <minos.galanakis@arm.com>
+:Status: Accepted
+
+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/technical_references/design_docs/tfm_its_service.rst b/docs/technical_references/design_docs/tfm_its_service.rst
new file mode 100644
index 0000000..a9c71b7
--- /dev/null
+++ b/docs/technical_references/design_docs/tfm_its_service.rst
@@ -0,0 +1,281 @@
+======================================
+Internal Trusted Storage (ITS) Service
+======================================
+
+:Author: Jamie Fox
+:Organization: Arm Limited
+:Contact: Jamie Fox <jamie.fox@arm.com>
+:Status: Accepted
+
+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/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 and extra veneers in
+  library 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, Arm Limited. All rights reserved.*
diff --git a/docs/technical_references/design_docs/tfm_log_system_design_document.rst b/docs/technical_references/design_docs/tfm_log_system_design_document.rst
new file mode 100644
index 0000000..269bcfc
--- /dev/null
+++ b/docs/technical_references/design_docs/tfm_log_system_design_document.rst
@@ -0,0 +1,209 @@
+##########################
+Log system design document
+##########################
+
+:Authors: 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(``tfm_log_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/technical_references/design_docs/tfm_non_secure_client_management.rst b/docs/technical_references/design_docs/tfm_non_secure_client_management.rst
new file mode 100644
index 0000000..133ae92
--- /dev/null
+++ b/docs/technical_references/design_docs/tfm_non_secure_client_management.rst
@@ -0,0 +1,366 @@
+############################
+Non-secure Client Management
+############################
+
+:Author: Miklos Balint
+:Organization: Arm Limited
+:Contact: Miklos Balint <miklos.balint@arm.com>
+:Status: Accepted
+
+***********
+Terminology
+***********
+
+**Secure service call**: request to a secure partition by a secure or non-secure
+client thread
+
+**Secure function call**: any function call from NSPE to SPE
+
+**TrustZone (TZ) API**: the set of functions defined by CMSIS for RTOS secure
+context management
+
+**Client ID**: the identifier defining a single entity within the system,
+determining its access policies for any given secure assets
+
+*************************
+Assumptions, restrictions
+*************************
+
+This design considers as its baseline the current operation of TF-M: an
+operating mode where at any given time only a single non-secure access is
+permitted to call a secure service.
+
+If a non-secure RTOS/bare-metal application does not use the API calls defined
+in this design, that non-secure application is still able to use secure services
+using a single, default non-secure client context. That remains a supported use
+case and use of this API is optional and is only needed if multiple access
+policies and/or concurrent secure contexts initiated by non-secure threads are
+required.
+
+Investigation is ongoing to address the option of enabling multiple concurrent
+calls by non-secure threads without the use of the context management API below.
+
+******
+Issues
+******
+
+The topics being discussed in this document:
+
+- NS client/thread awareness in TF-M Core
+- "Known client" list
+
+Improvements, alternatives, investigations
+
+- Concurrent secure service requests
+- NS to S priority inheritance
+- NS privilege to be derived from CONTROL_NS register
+
+**************
+Design details
+**************
+
+NS thread awareness in TF-M Core
+================================
+
+Description
+-----------
+
+TrustZone context management API defines a set of secure function calls from NS
+RTOS handler mode to TF-M Core to get notification of context switch.
+
+While CMSIS context management can be used to directly expose secure context
+management to the non-secure OS, TF-M has a proprietary implementation: the
+context management API is used to get notification of NS context switches and
+to track various non-secure clients.
+
+.. _`API definition`:
+
+API definition
+--------------
+
+TZ_MemoryId_t data type
+^^^^^^^^^^^^^^^^^^^^^^^
+
+TZ Memory ID identifies an allocated memory slot.
+
+**TF-M usage**
+
+``TZ_MemoryId_t`` is used for an index into an array containing active NS client
+IDs. The memory ID is required by CMSIS to be a positive integer, so it is
+mapped to the array index by being decremented by 1.
+
+**Signature**
+
+.. code-block:: c
+
+    typedef uint32_t TZ_MemoryId_t;
+
+Context management initialization: TZ_InitContextSystem_S
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Initialize secure context memory system.
+
+**Return value**
+
+This function returns execution status: 1 for success, 0 for error.
+
+**TF-M usage**
+
+This function call is used to identify a non-secure RTOS that has TZ context
+management capabilities, as this function is expected to be called before any
+other TZ API function is used.
+
+**Signature**
+
+.. code-block:: c
+
+    uint32_t TZ_InitContextSystem_S (void);
+
+Context allocation: TZ_AllocModuleContext_S
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Allocate context memory for calling secure software modules in TrustZone.
+
+**Parameters**
+
+``module`` [input]: identifies software modules called from non-secure mode
+
+**Return value**
+
+``value != 0`` TrustZone memory slot identifier
+``value == 0`` no memory available or internal error
+
+**TF-M usage**
+
+This function is used to identify a new non-secure thread that may be identified
+as a client in the non-secure domain. The ``module`` parameter is unused. The
+returned ``TZ_MemoryId_t`` value is the index in the ``NsClientIdList`` array
+where the client ID for the newly allocated context is stored.
+
+**Signature**
+
+.. code-block:: c
+
+    TZ_MemoryId_t TZ_AllocModuleContext_S (TZ_ModuleId_t module);
+
+Context freeing: TZ_FreeModuleContext_S
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Free context memory that was previously allocated with TZ_AllocModuleContext_S
+
+**Parameters**
+
+``id`` [input]: TrustZone memory slot identifier
+
+**Return value**
+
+Execution status (1: success, 0: error)
+
+**TF-M usage**
+
+This function indicates that a non-secure client is inactive, meaning that any
+subsequent references to the client ID are considered erroneous. In effect, the
+client ID indexed by ``(id – 1)`` is cleared and the memory slot flagged as
+free.
+
+**Signature**
+
+.. code-block:: c
+
+    uint32_t TZ_FreeModuleContext_S (TZ_MemoryId_t id);
+
+Context activation: TZ_LoadContext_S
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Load secure context (called on RTOS thread context switch)
+
+**Parameters**
+
+``id`` [input]: TrustZone memory slot identifier
+
+**Return value**
+
+Execution status (1: success, 0: error)
+
+**TF-M usage**
+
+The client ID indexed by ``(id – 1)`` becomes the active NS client. Any
+subsequent secure service requests coming from non-secure domain will be
+associated with this client ID.
+
+**Signature**
+
+.. code-block:: c
+
+    uint32_t TZ_LoadContext_S (TZ_MemoryId_t id);
+
+Context deactivation: TZ_StoreContext_S
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Store secure context (called on RTOS thread context switch)
+
+**Parameters**
+
+``id`` [input]: TrustZone memory slot identifier
+
+**Return value**
+
+Execution status (1: success, 0: error)
+
+**TF-M usage**
+
+The client ID indexed by ``(id – 1)`` becomes inactive. Any subsequent secure
+service requests coming from non-secure domain will be invalid until a new NS
+context is loaded.
+
+**Signature**
+
+.. code-block:: c
+
+    uint32_t TZ_StoreContext_S (TZ_MemoryId_t id);
+
+Security implications (to be assessed separately if needed)
+-----------------------------------------------------------
+
+If NS RTOS / NS handler mode is compromised, NS clients’ data can be disclosed
+to unauthorised non-secure actors, as it’s not in the scope of TF-M to guarantee
+non-secure client isolation. Support for this API is only an enabler for a
+non-secure RTOS feature.
+
+Vulnerabilities of the NS handler mode cannot and will not lead to disclosure of
+assets owned by secure entities to non-secure actors after the introduction of
+this feature as a malicious NS handler can only ever assume the identity of
+another non-secure client and cannot elevate its access privileges to those of
+secure clients.
+
+Known client list
+=================
+
+Description
+-----------
+
+A different – but related – API to that defined by CMSIS is proposed in this
+design to register a specific client ID to the active non-secure thread.
+
+The purpose of this API is to provide non-secure privileged code with the
+ability to associate the active non-secure context with a pre-defined identity.
+This enables the application of a pre-set access policy on the secure side to be
+applied to the non-secure thread.
+
+Use cases
+---------
+
+It is valid for non-secure privileged code to only support the TF-M-specific API
+defined below and not the CMSIS TZ API defined previously. In this case the
+single non-secure client is still able to access resources based on a
+pre-defined access policy in secure services without relying on the default
+non-secure identity configured in TF-M.
+
+If used in conjunction with the TZ API, this function can provide a means to
+assign and identify multiple non-secure client IDs based on the active context,
+overriding TF-M’s default non-secure client identity assignment policy.
+
+API definition
+--------------
+
+NS RTOS client registration API – secure function calls from NS handler mode to
+TF-M Core to associate a “known” Client ID to the active non-secure thread.
+
+Register specific client ID: ``tfm_register_client_id``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Assign client ID to the current TZ context.
+
+**Note**: This function must be called from handler mode so that TF-M can verify
+that it was sent by a privileged entity.
+
+This function call must follow all TZ_AllocModuleContext_S function calls to
+override the default NS client IDs allocated by TF-M.
+
+Secure and non-secure client IDs are allocated from different ranges (negative
+IDs for non-secure clients, positive for secure clients). The function call is
+rejected if called with a secure ID.
+
+**Parameters**
+
+``ns_client_id`` [input]: The client ID to be assigned to the current context
+
+**Return value**
+
+``TFM_SUCCESS`` (0) if the client ID assigned successfully, a non-zero error
+code in case of error.
+
+**Signature**
+
+.. code-block:: c
+
+    enum tfm_status_e tfm_register_client_id (int32_t ns_client_id);
+
+********************
+Implementation notes
+********************
+
+Option to reduce required context switch notifications
+======================================================
+
+According to TrustZone API definition ``TZ_StoreContext_S()`` is to be called
+"at thread context switch after running a thread" and ``TZ_LoadContext_S`` "at
+thread context switch before running a thread". The API definition does not
+define the course of action to be taken if two ``TZ_LoadContext_S()`` calls are
+made without an interleaving StoreContext.
+
+The proposal for TF-M is to accept this as a valid scenario where the second
+``TZ_LoadContext_S()`` call is taken to imply a ``TZ_StoreContext_S()`` with
+the previous active Memory_Id.
+
+This assumption does not alter the intended use of ``TZ_StoreContext_S()``,
+which remains a valid call with the behaviour as defined in the
+`API definition`_ section above.
+
+******************************************
+Investigations, improvements, alternatives
+******************************************
+
+Concurrent secure service requests
+==================================
+
+If there are concurrent services requests, TF-M needs to identify the client for
+each request and should make their corresponding context available in the secure
+domain. Client ID needs to be associated with the secure service request so that
+a NS context switch does not break client identification.
+
+If a non-secure client is blocked on an asynchronous secure service completion,
+the NS TFM library must provide a semaphore the NS thread can wait on, whereby
+NS RTOS can schedule a different context.
+
+Should a secure service completion happen for an inactive NS context, a
+notification mechanism needs to be created to activate the given NS context.
+
+The proposal is for the NS TFM library to include a NS IRQ handler for a
+reserved interrupt signal. The ISR would identify the context to be activated
+and release the corresponding semaphore.
+
+NS to S priority inheritance
+============================
+
+Whether or not NS thread priorities should be influencing secure service
+prioritization needs to be analysed. It is raised as a topic of discussion and
+is not detailed in this document further at this stage.
+
+NS privilege check for secure function calls
+============================================
+
+Non-secure privilege can be derived from CONTROL_NS instead of requiring NS to
+call context management veneers in handler mode. This can be a more generic
+approach, but implications are to be investigated.
+
+**********
+References
+**********
+
+Description of the TZ API:
+https://www.keil.com/pack/doc/CMSIS/Core/html/group__context__trustzone__functions.html
+
+--------------
+
+*Copyright (c) 2019-2021, Arm Limited. All rights reserved.*
diff --git a/docs/technical_references/design_docs/tfm_ns_client_identification.rst b/docs/technical_references/design_docs/tfm_ns_client_identification.rst
new file mode 100644
index 0000000..4ef8e90
--- /dev/null
+++ b/docs/technical_references/design_docs/tfm_ns_client_identification.rst
@@ -0,0 +1,26 @@
+###########################
+Non-Secure Identity Manager
+###########################
+The ID of the current application/thread is known by TF-M, and the PS service
+queries the ID of the currently running client via a dedicated API.
+
+The identity of secure clients can be tracked by TF-M core, because it also
+manages the contexts of the partitions. However to differentiate NS clients, it
+relies on the services provided by the NS OS.
+
+Tracking of context changes are possible by relying on the NS OS calling the
+Thread Context Management for Armv8-M TrustZone APIs, as described
+`here <https://www.keil.com/pack/doc/CMSIS/Core/html/group__context__trustzone__functions.html>`__
+
+However TF-M needs an extra API, to assign a client ID to the TZ context created
+as a result of the
+``TZ_MemoryId_t TZ_AllocModuleContext_S (TZ_ModuleId_t module)`` call.
+See ``interface/include/ext/tz_context.h`` for details of API declarations.
+
+In case the NS OS doesn't use the Thread Context Management for Armv8-M
+TrustZone APIs, then TF-M considers the NS SW as a single client, and assigns a
+client ID to it automatically.
+
+--------------
+
+*Copyright (c) 2018-2021, Arm Limited. All rights reserved.*
diff --git a/docs/technical_references/design_docs/tfm_partition_and_service_design_document.rst b/docs/technical_references/design_docs/tfm_partition_and_service_design_document.rst
new file mode 100644
index 0000000..223e212
--- /dev/null
+++ b/docs/technical_references/design_docs/tfm_partition_and_service_design_document.rst
@@ -0,0 +1,150 @@
+#####################################
+Partition and Service Design Document
+#####################################
+
+:Authors: Summer Qin
+:Organization: Arm Limited
+:Contact: summer.qin@arm.com
+:Status: Accepted
+
+***********
+Terminology
+***********
+Secure Partition - A thread of execution with protected runtime state within the
+Secure Processing Environment. Container for the implementation of one or more
+RoT Services. Multiple Secure Partitions are allowed in a platform.
+SPM - Secure Partition Manager.
+
+***************
+Design Overview
+***************
+As the PSA Firmware Framework described: "A Secure Partition is one execution
+environment. Partition provides access to resources, protection of its own code
+and data and mechanisms to interact with other components in the system. Each
+Secure Partition is a single thread of execution and is the smallest unit of
+isolation: if the strongest isolation level is implemented, every Secure
+Partition is isolated from every other Secure Partition.
+Security functionality is exposed by PSA as a collection of Root of Trust
+Services. Each RoT Service is a set of related security functionality. RoT
+Service are typically implemented within a Secure Partition."
+
+******************
+Partition Database
+******************
+Partition Database collects partition information of all existing partitions.
+These partitions are built together as built-in partitions at the current stage.
+Partition's code and private date are put into dedicated regions, while
+Partition Database are put in TF-M SPM region. There is a defined structure for
+partition information:
+
+.. code-block:: c
+
+    struct spm_partition_desc_t {
+        struct spm_partition_runtime_data_t runtime_data;
+        const struct spm_partition_static_data_t *static_data;
+        const struct platform_data_t *platform_data;
+    };
+
+The structure describes the partition information from four aspects and every
+structure member has its own detailed members. These members can be recorded in
+partition information:
+
+- Runtime data contains runtime change-able members like context, stack and so
+  on.
+- Static data contains partition id, flags, priority and init function entry.
+- Platform data contains a single peripheral's information this partition owns.
+  This is a little different from the PSA Firmware Framework defines.
+- Memory data contains partition memory region address and size.
+
+These data types with different names also have different accessing attribute
+requirements and can be put in memory with different attributes. The listed four
+types of data can be defined with a different qualifier to indicate the
+accessing attribute and finally, these data are linked into a global structure
+type 'spm_partition_desc_t' for usage. Define the global partition_list array to
+store all the partitions information and all members are set to zero so that
+partition_list will be stored in bss segment. For static information, like
+static member, platform member, and some memory data, assign this information
+with 'const' qualifier. This would avoid involving unnecessary read-only data
+into the read-write area and cause storage waste. The partition's database is
+managed by the following steps:
+
+#. The four types of data are defined with different qualifier in
+   'tfm_spm_db.inc'. For example, static data is qualified with 'const' to
+   indicate it is a read-only data.
+#. Include partition predefined static information in spm_api.c by adding the
+   tfm_spm_db.inc file.
+#. Initialize the partition runtime information
+#. Assign the static data, platform data and memory data to corresponding
+   partition.
+
+Partition Database Generating
+=============================
+Partition Database is represented as a global array that contains objects of
+type spm_partition_desc_t. The include file named tfm_spm_db.inc contains this
+array which is auto-generated from tfm_spm_db.inc.template by a tool script
+named as 'tfm_parse_manifest_list.py'. This tool parses partition manifests and
+converts members in manifest into the array member.
+
+Partition Database Initialization
+=================================
+The dedicated partition information file will be added into spm initialization
+file to initialize the global spm data array g_spm_partition_db.
+
+.. code-block:: c
+
+    #include "secure_fw/partitions/tfm_spm_db.inc"
+
+Built-in Partitions
+===================
+Currently, there are two built-in internal partitions which have no manifest,
+and all the information is statically defined. These two partitions are:
+non-secure partition and core partition. They are added to the first and second
+position of the array.
+
+****************
+Service Database
+****************
+Each Secure Partition can host one or more RoT Services. Typically, related
+services that share underlying functionality or data would be implemented within
+the same Secure Partition.
+All the services are registered in every partition's manifest. There is a
+defined structure for service information:
+
+.. code-block:: c
+
+    struct tfm_spm_service_t {
+        const struct tfm_spm_service_db_t *p_ldinf;
+        struct spm_partition_desc_t *partition;
+        struct bi_list_node_t handle_list;
+        struct tfm_msg_queue_t msg_queue;
+        struct bi_list_node_t list;
+    };
+
+These members are necessary for a service and the following bullets explain the
+members:
+
+- Service database contains service name, partition id, service signal, service
+  identifier, non-secure client(if it can be called by non-secure client),
+  version and version_policy.
+- Partition points to the secure partition data.
+- Handle list contains the handle connected to the service.
+- Message queue contains the message for the service.
+- List is the service list indicator. It is a double-chain list node.
+
+The member tfm_spm_service_db_t contains statically defined service information.
+This variable can be defined statically with a qualifier 'const' to put it into
+the read-only data.
+The service information is managed by the following steps:
+
+#. Define five types of data with different qualifiers in
+   'tfm_service_list.inc'. For example, service db is qualified with 'const' to
+   indicate it is a read-only data.
+#. Include service predefined static information in spm_api_ipc.c by adding the
+   tfm_service_list.inc file.
+#. Assign the service db to the corresponding service.
+#. Get the corresponding partition information and link with the service.
+#. Initialize the handle_list of every service.
+
+--------------
+
+*Copyright (c) 2019, Arm Limited. All rights reserved.*
diff --git a/docs/technical_references/design_docs/tfm_physical_attack_mitigation.rst b/docs/technical_references/design_docs/tfm_physical_attack_mitigation.rst
new file mode 100644
index 0000000..ee0734e
--- /dev/null
+++ b/docs/technical_references/design_docs/tfm_physical_attack_mitigation.rst
@@ -0,0 +1,629 @@
+#################################################
+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.
+
+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. TF-M exposed a HAL API for this purpose.
+The system integrator is responsible to implement this API on a particular SoC
+and harden it against physical attacks:
+
+.. code-block:: c
+
+  enum tfm_plat_err_t tfm_spm_hal_init_debug(void);
+
+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_plat_err_t tfm_spm_hal_configure_default_isolation(
+                 bool privileged,
+                 const struct platform_data_t *platform_data);
+  enum tfm_hal_status_t tfm_hal_mpu_update_partition_boundary(uintptr_t start,
+                                                              uintptr_t end);
+
+Memory access check
+^^^^^^^^^^^^^^^^^^^
+TFM SPM exposes a HAL API for platform specific memory access check. The
+system integrator is responsible to implement these API on a particular SoC and
+harden it against physical attacks.
+
+.. code-block:: c
+
+  tfm_hal_status_t tfm_hal_memory_has_access(const uintptr_t base,
+                                             size_t size,
+                                             uint32_t attr);
+
+.. _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 profile (OFF, LOW, MEDIUM, HIGH) was 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. Transfer them to ``fih_int`` functions with the
+    usage of ``FIH_CALL`` and ``FIH_RET`` macros. These 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:
+    ``tf-m/lib/fih/inc/fault_injection_hardening.h``
+
+    Take simplified TF-M SPM initialization flow as an example:
+
+    .. code-block:: c
+
+      main()
+        |
+        |--> tfm_core_init()
+        |           |
+        |           |--> tfm_spm_hal_init_debug()
+        |           |                  |
+        |           |                  |--> platform specific debug init
+        |           |
+        |           |--> tfm_hal_set_up_static_boundaries()
+        |                              |
+        |                              |--> platform specific isolation impl.
+        |
+        |--> During each partition initialization
+                    |
+                    |--> tfm_spm_hal_configure_default_isolation()
+                                       |
+                                       |--> 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_spm_hal_verify_isolation_hw(void);
+
+    This function is intended to be called just before the security state
+    transition and is responsible for checking all critical hardware
+    configuration. 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
+
+      int fih_delay_init(void);
+      unsigned char fih_delay_random_uchar(void);
+
+  - Similar countermeasures can be implemented in critical steps in platform
+    specific implementation.
+
+    Take memory isolation settings on AN521 and Musca-B1 platforms 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/Musca-B1 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 code size
+===================
+The addition of protection code against physical attacks increases the code
+size. 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 tfm_spm_hal_nvic_interrupt_enable: The state of the MPC is checked
+    here whether is it initialized or not.
+  - 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, Arm Limited. All rights reserved.*
diff --git a/docs/technical_references/design_docs/tfm_psa_inter_process_communication.rst b/docs/technical_references/design_docs/tfm_psa_inter_process_communication.rst
new file mode 100644
index 0000000..1969171
--- /dev/null
+++ b/docs/technical_references/design_docs/tfm_psa_inter_process_communication.rst
@@ -0,0 +1,234 @@
+################################
+TF-M Inter-Process Communication
+################################
+
+:Authors: Ken Liu, Mingyang Sun
+:Organization: Arm Limited
+:Contact: ken.liu@arm.com, mingyang.sun@arm.com
+:Status: Accepted
+
+***********
+Terminology
+***********
+
+IPC - Inter-Process Communication
+
+For more terminology please check Reference_ document.
+
+***************
+Design Overview
+***************
+IPC re-uses existed components in library model:
+
+- SPM – for partition information and isolation actions
+- Core – for exception handling
+
+Extra components for implementing IPC:
+
+- 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 while
+  isolation level 1 of library model makes all partition shares same stack
+  pointer. This needs to be changed while implementing IPC.
+- 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://pages.arm.com/psa-
+  resources-ff.html?_ga=2.156169596.61580709.1542617040-1290528876.1541647333
+.. _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, Arm Limited. All rights reserved.*
diff --git a/docs/technical_references/design_docs/tfm_secure_boot.rst b/docs/technical_references/design_docs/tfm_secure_boot.rst
new file mode 100644
index 0000000..61bdcb5
--- /dev/null
+++ b/docs/technical_references/design_docs/tfm_secure_boot.rst
@@ -0,0 +1,811 @@
+###########
+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``.
+
+.. Warning::
+    DO NOT use them in 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.
+
+.. Note::
+
+    Only single image boot is supported with ``RAM load`` upgrade mode.
+
+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_MPS2     | No              | Yes           | Yes      | Yes            | No           |
++---------------------+-----------------+---------------+----------+----------------+--------------+
+| FVP_SSE300_MPS3     | No              | 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           |
++---------------------+-----------------+---------------+----------+----------------+--------------+
+| 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           |
++---------------------+-----------------+---------------+----------+----------------+--------------+
+
+.. [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" 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/sse_200 -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":** Activate swapping firmware upgrade operation.
+    - **"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``, an image is needed in the primary image area as well, to
+        trigger the update.
+
+    .. Warning::
+        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/sse_200 -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/sse_200 -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 ``IMAGE_LOAD_ADDRESS`` macro must be specified in the target dependent
+files, for example with Musca-S, its ``flash_layout.h`` file in the ``platform``
+folder should include ``#define 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-2021, Arm Limited. All rights reserved.*
diff --git a/docs/technical_references/design_docs/tfm_secure_irq_handling.rst b/docs/technical_references/design_docs/tfm_secure_irq_handling.rst
new file mode 100644
index 0000000..b9baae9
--- /dev/null
+++ b/docs/technical_references/design_docs/tfm_secure_irq_handling.rst
@@ -0,0 +1,178 @@
+###################
+Secure IRQ handling
+###################
+
+The Armv8-M Architecture makes it possible to configure interrupts to target
+secure state.
+
+TF-M makes it possible for secure partitions to get notified of secure
+interrupts.
+
+By default TF-M sets up interrupts to target NS state. To configure an interrupt
+to target secure state and assign a handler to it, the manifest of the partition
+must be edited.
+
+See the following example:
+
+
+.. code-block:: yaml
+
+    {
+      "name": "...",
+      "type": "...",
+      "priority": "...",
+
+      ...
+
+      "irqs": [
+        {
+          "source": "5",
+          "signal": "DUAL_TIMER"
+        },
+        {
+          "source": "TFM_IRQ_LINE_TIMER_1",
+          "signal": "TIMER_1"
+        }
+      ],
+
+      ...
+
+    }
+
+To set up a handler in a partition, the ``irqs`` node must be added. A single
+secure partition can have handlers registered for multiple IRQs, in this case
+the list ``irqs`` has multiple elements in it.
+
+An IRQ handler is defined by the following nodes:
+
+- ``source``: The IRQ number or the name of the IRQ line. With the name of the
+  IRQ line, there must be defined a macro in ``tfm_peripherals_def.h`` which is
+  substituted to the IRQ line num. The IRQ line nums and sources are defined by
+  each platform: for example, they are defined in ``platform_irq.h`` for the
+  Musca-S1 platform. When defining new macros in ``tfm_peripherals_def.h``, it
+  is important the macro name matches the platform's handler function for that
+  IRQ source.
+- ``signal``: The name of the signal for this IRQ.
+
+.. important::
+
+  The name of the privileged interrupt handler is derived from the node
+  specifying the IRQ line number.
+
+  - In case ``source`` is IRQ number, the name of the handler becomes
+    ``void irq_<number>_Handler(void)``.
+  - In case ``source`` is defined IRQ macro, the name of the handler becomes
+    ``void <macro>_Handler(void)``.
+
+  This is important, because the derived name has to be present in the vector
+  table as the handler of the IRQ. The platform startup functions are specified
+  in the vector table defined in the platform secure startup file. The user
+  should verify the names of the generated handlers match for a given platform
+  IRQ.
+
+.. Note::
+
+  ``signal`` and ``source`` are mandatory.
+
+If an IRQ handler is registered, TF-M will:
+
+- Set the IRQ with number or macro to target secure state
+- Set the priority of IRQ, the number is platform dependent. Platforms can
+  decide the priorities of each IRQ.
+
+.. Note::
+
+  The priority value for IRQ must be smaller than the value of PendSV, which is
+  0x80.
+
+TF-M configures the interrupt lines to be disabled by default. Interrupts for a
+service can be enabled by the secure service by calling
+``void tfm_enable_irq(psa_signal_t irq_signal)``. The function can be called in
+the service init function.
+
+Library model
+=============
+
+In Library model a function with the name derived from the value of the
+``source`` property is generated. This function will be put in the vector table
+by the linker (as the handlers in the startup assembly are defined as weak
+symbols). The code generated for this function will forward the call to the
+function with the name of the value of the ``signal`` property post-fixed with
+``_isr``.
+
+.. hint::
+
+  for a signal ``"signal": "DUAL_TIMER"`` the name of the handler function is
+  ``DUAL_TIMER_isr``
+
+The signature of the IRQ handler in the partition must be the following:
+
+.. code-block:: c
+
+    void partition_irq_handler(void);
+
+The detailed description on how secure interrupt handling works in the Library
+model see
+`Secure Partition Interrupt Handling design document <https://developer.trustedfirmware.org/w/tf_m/design/secure_partition_interrupt_handling/>`_.
+
+IPC model
+=========
+
+The detailed description on how secure interrupt handling works in the IPC
+model, see the
+`PSA Firmware Framework and RoT Services specification <https://pages.arm.com/psa-resources-ff.html>`_.
+
+**********************
+Implementation details
+**********************
+
+Library model implementation
+============================
+
+As a result of the function call like behaviour of secure services in library
+model, some information that is critical for the SPM to keep track of partition
+states, is stored on the stack of the active partitions. When an interrupt
+happens, and a handler partition is set to running state, it has access to its
+whole stack, and could corrupt the data stacked by the SPM. To prevent this, a
+separate Context stack is introduced for each secure partition, that is used by
+the SPM to save this information before starting to execute secure partition
+code.
+
+A stack frame to this context stack is pushed when the execution in the
+partition is interrupted, and when a handler in the partition interrupts another
+service. So the maximal stack usage can happen in the following situation:
+
+Consider secure partition 'A'. 'A' is running, and then it is interrupted by
+an other partition. Then the lowest priority interrupt of 'A' is triggered.
+Then before the handler returns, the partition is interrupted by another
+partition's handler. Then before the running handler returns, the second
+lowest interrupt of 'A' is triggered. This can go until the highest priority
+interrupt of 'A' is triggered, and then this last handler is interrupted. At
+this point the context stack looks like this:
+
+.. code-block:: rst
+
+  +------------+
+  | [intr_ctx] |
+  | [hndl_ctx] |
+  | .          |
+  | .          |
+  | .          |
+  | [intr_ctx] |
+  | [hndl_ctx] |
+  | [intr_ctx] |
+  +------------+
+
+  Legend:
+    [intr_ctx]: Frame pushed when the partition is interrupted
+    [hndl_ctx]: Frame pushed when the partition is handling an interrupt
+
+So the max stack size can be calculated as a function of the IRQ count of 'A':
+
+.. code-block:: c
+
+  max_stack_size = intr_ctx_size + (IRQ_CNT * (intr_ctx_size + hndl_ctx_size))
+
+--------------
+
+*Copyright (c) 2018-2021, Arm Limited. All rights reserved.*
diff --git a/docs/technical_references/design_docs/tfm_secure_partition_interrupt_handling.rst b/docs/technical_references/design_docs/tfm_secure_partition_interrupt_handling.rst
new file mode 100644
index 0000000..f58fb96
--- /dev/null
+++ b/docs/technical_references/design_docs/tfm_secure_partition_interrupt_handling.rst
@@ -0,0 +1,225 @@
+###################################
+Secure Partition Interrupt Handling
+###################################
+
+:Author: Miklos Balint
+:Organization: Arm Limited
+:Contact: Miklos Balint <miklos.balint@arm.com>
+:Status: Accepted
+
+Secure Partitions that implement peripheral drivers may need to use interrupts
+to efficiently manage PE utilization.
+
+************************
+Partition implementation
+************************
+
+IRQ lines declared in manifest files for Secure Partitions are assigned IRQ
+signals as described in PSA Firmware Framework.
+
+Interrupt handling is implemented as interrupt service routines (Partition ISR)
+that are executed in the partition context.
+
+Partitions that are owners of IRQ must define interrupt service routines for
+them.
+
+manifest file IRQ declaration example
+=====================================
+
+.. code-block:: json
+
+    {"irqs": [
+    {
+        "line_num": 17,
+        "signal": "RTC"
+    },
+    {
+        "line_name": "UART1_IRQ",
+        "signal": "UART1"
+    }
+    ]}
+
+See
+:doc:`secure IRQ handling </docs/technical_references/design_docs/tfm_secure_irq_handling>`
+for further information on IRQ source and signal.
+
+Partition ISR function
+======================
+
+The symbol name of the ISR implemented for a given interrupt must be
+``manifest[‘irqs’][idx].signal`` attribute post-fixed with "_isr".
+
+Partition ISR has the signature of a regular interrupt service routine, e.g.:
+
+.. code-block:: c
+
+    void UART1_isr(void);
+
+*************
+SPM behaviour
+*************
+
+In the vector table, each interrupt that has an associated partition ISR is
+assigned to an SPM interrupt handler (SPM ISR) that delegates handling to a
+Partition ISR.
+
+Each partition is allocated an asserted signal mask. Every IRQ associated with
+the partition is assigned a position in the signal mask.
+
+When a secure hardware interrupt is asserted, the SPM:
+
+- Acknowledges the interrupt and masks the hardware interrupt line.
+
+- Identifies the Secure Partition which has registered the interrupt (in the
+  manifest). This identification can happen either
+
+  - using a runtime lookup or
+
+  - by registering different instances of the SPM ISR for each interrupt, so the
+    runtime lookup is avoided both for the partition Id and the ISR function
+    location.
+
+- Sets up execution environment for the secure partition that has registered the
+  interrupt.
+
+- Asserts the IRQ signal for the interrupt in the partition's signal mask.
+
+- Execute Partition ISR. If the partition’s stack is active at the time of
+  pre-emption by the interrupt (i.e. the Secure Partition is not in idle state),
+  the Partition ISR stack frame will be amended to that. If the Secure Partition
+  had been idle, a stack frame will be reserved for the duration of the
+  Partition ISR execution. The Secure Partition state is changed to running for
+  the duration of the Partition ISR.
+
+When the Secure Partition ISR returns, execution is returned to the context
+pre-empted by the IRQ.
+
+Implementation notes
+====================
+
+Interrupts can pre-empt NSPE or secure service execution. Pre-emption of an
+interrupt is only possible by an interrupt of a higher priority, ensuring
+deterministic nesting/un-nesting of stack frames.
+
+*************
+API functions
+*************
+
+psa_wait()
+==========
+
+A call to ``psa_wait()`` from a secure service yields execution to the framework
+and becomes blocked waiting for the assertion of a signal. In the meantime, SPM
+will schedule other contexts that are ready to run. The client remains blocked
+until the service function returns.
+
+If an IRQ signal matching one in ``signal_mask`` to ``psa_wait()`` is asserted,
+the Secure Partition becomes ready to run. When the scheduler activates the
+Secure Partition, the IRQ signal(s) that had been asserted are returned by
+``psa_wait()``. When the service function completes its execution and returns,
+control is taken back to client.
+
+.. Note::
+
+    The only signals implemented in the current TF-M implementation are
+    interrupt signals.
+
+**Signature**
+
+.. code-block:: c
+
+    psa_signal_t psa_wait(psa_signal_t signal_mask, uint32_t timeout);
+
+**Parameters**
+
+``psa_signal_t signal_mask`` defines the set of interrupt signals that can
+resume execution of the secure service.
+
+``uint32_t timeout`` defines timeout for the function, as defined in PSA
+Firmware Framework 1.0-beta-0 (Chapter 4.3.3).
+
+**Return**
+
+The return value indicates the signal(s) that triggered the resumption of the
+service; i.e. If multiple interrupt events have been handled, it will be
+indicated by the mask value in the return code.
+
+tfm_enable_irq()
+================
+
+A call to ``tfm_enable_irq()`` from a secure service enables an irq.
+
+**Signature**
+
+.. code-block:: c
+
+    void tfm_enable_irq(psa_signal_t irq_signal);
+
+**Parameters**
+
+``psa_signal_t irq_signal`` defines the interrupt signal to be enabled.
+
+**Return**
+
+``void`` Success.
+
+Does not return: The call is invalid, one or more of the following are true:
+
+- irq_signal is not an interrupt signal.
+- irq_signal indicates more than one signal.
+
+tfm_disable_irq()
+=================
+
+A call to ``tfm_disable_irq()`` from a secure service disables an irq.
+
+**Signature**
+
+.. code-block:: c
+
+    void tfm_disable_irq(psa_signal_t irq_signal);
+
+**Parameters**
+
+``psa_signal_t irq_signal`` defines the interrupt signal to be disabled.
+
+**Return**
+
+``void``: Success.
+
+Does not return: The call is invalid, one or more of the following are true:
+
+- irq_signal is not an interrupt signal.
+- irq_signal indicates more than one signal.
+
+psa_eoi()
+=========
+
+A call ``to psa_eoi()`` from a secure service function or a Partition ISR
+informs SPM that an interrupt has been processed. This clears the IRQ signal in
+the asserted signal mask associated with the partition.
+
+**Signature**
+
+.. code-block:: c
+
+    void psa_eoi(psa_signal_t irq_signal);
+
+**Parameters**
+
+``psa_signal_t irq_signal`` defines the interrupt signal that has been
+processed.
+
+**Return**
+
+``void``: Success.
+
+Does not return: The call is invalid, one or more of the following are true:
+
+- ``irq_signal`` is not an interrupt signal.
+- ``irq_signal`` indicates more than one signal.
+- ``irq_signal`` is not currently asserted.
+
+--------------
+
+*Copyright (c) 2019-2021, Arm Limited. All rights reserved.*
diff --git a/docs/technical_references/design_docs/tfm_secure_partition_runtime_library.rst b/docs/technical_references/design_docs/tfm_secure_partition_runtime_library.rst
new file mode 100644
index 0000000..97e8444
--- /dev/null
+++ b/docs/technical_references/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/sprt/'
+
+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/technical_references/design_docs/tfm_uniform_secure_service_signature.rst b/docs/technical_references/design_docs/tfm_uniform_secure_service_signature.rst
new file mode 100644
index 0000000..70c6c60
--- /dev/null
+++ b/docs/technical_references/design_docs/tfm_uniform_secure_service_signature.rst
@@ -0,0 +1,114 @@
+################################
+Uniform Secure Service Signature
+################################
+
+:Author: Miklos Balint
+:Organization: Arm Limited
+:Contact: Miklos Balint <miklos.balint@arm.com>
+:Status: Accepted
+
+**********************************
+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