Docs: Restructuring and new layout
This patch implements a set of user-experiences aimed
changes.It modifies the documentation structure and
switches to a more reactive design for the rtd theme.
* The documentation layout has been redesigned to be more
intuitive,easier to maintain and and scale.
* The landing page introduces a new dashboard.
* Introduced dedicated space for release documents, and
changelog has been modified to directly source content
from referenced documents.
* Added quick-link navigation for items that need emphasis.
* Relevant design documents can now be grouped in suf-folders.
* There is dedicated space for custom platform, and third
party tools documents.
* Wildcard and regex matching has been introduced to indexes.
Change-Id: Ib02d17d5d26187d397ba17317788cf2a01401b07
Signed-off-by: Minos Galanakis <minos.galanakis@arm.com>
diff --git a/docs/design_documents/dual-cpu/booting_a_dual_core_system.rst b/docs/design_documents/dual-cpu/booting_a_dual_core_system.rst
new file mode 100644
index 0000000..0a88ab3
--- /dev/null
+++ b/docs/design_documents/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/design_documents/dual-cpu/communication_prototype_between_nspe_and_spe_in_dual_core_systems.rst b/docs/design_documents/dual-cpu/communication_prototype_between_nspe_and_spe_in_dual_core_systems.rst
new file mode 100644
index 0000000..46c9277
--- /dev/null
+++ b/docs/design_documents/dual-cpu/communication_prototype_between_nspe_and_spe_in_dual_core_systems.rst
@@ -0,0 +1,761 @@
+################################################################
+Communication Prototype Between NSPE And SPE In Dual Core System
+################################################################
+
+:Authors: David Hu
+:Organization: Arm Limited
+:Contact: david.hu@arm.com
+:Status: Accepted
+
+************
+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 is tightly coupled with mailbox and 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 documents.
+
+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 mailbox message
+from NSPE for PSA Client call processing.
+The mailbox design document should define 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 design document can 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 the 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)
+=============================================================
+
+Current TF-M implementation (git tag TF-Mv1.0-RC3) only supports single
+outstanding PSA client call from NSPE.
+
+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) module`_ introduces TF-M Remote Procedure
+ Call module 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 generic mailbox API(s) to check whether an
+inbound mailbox event has occurred. Mailbox functions should be implemented in
+platform vendor driver to check mailbox status in NSPE and distinguish spurious
+events.
+The interrupt handler should assert a PendSV after the inbound mailbox event is
+confirmed. The triggered PendSV handler will deal with the mailbox events.
+
+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.
+
+It is recommended to implement mailbox time-consuming operations in PendSV
+handler, such as mailbox message copying from NSPE to SPE. This can decrease the
+response latency for other interrupts, compared with putting all the mailbox
+operations in interrupt handler. Refer to `PendSV handler`_ for more details of
+PendSV handler.
+
+In actual mailbox implementation, Inter-Processor Communication interrupt
+handler can execute more mailbox processing, such as mailbox message parsing and
+copying, to simplify the synchronization. It may increase the time consumption
+in interrupt handling. Therefore, it might block the handling of other
+interrupts whose priorities are lower or equal to Inter-Processor Communication
+interrupt. As a result, it becomes more important to adjust the
+Interrupt-Processor Communication interrupt priority in TF-M, according to
+specific system and implementation requirements.
+
+TF-M Remote Procedure Call (RPC) module
+=======================================
+
+This design brings up a concept of Remote Procedure Call module in TF-M.
+
+The RPC module sits between TF-M SPM and mailbox implementation. The purpose of
+RPC module is to decouple mailbox implementation and TF-M SPM and enhance the
+generality of entire dual-core communication.
+
+The RPC module 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 module 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 module eventually calls the callbacks to execute
+mailbox operations.
+RPC module 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 when mailbox handling triggers the sleeping secure service, the status of
+sleeping secure service has been updated in scheduling.
+
+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
+
+The handling process in mailbox operation consists of the following steps.
+
+1. If copy operations are not done in Inter-Processor Communication interrupt
+ handler, the mailbox handling should fetch the mailbox message(s) containing
+ PSA client call request from NSPE. 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, mailbox
+ handling can fetch multiple mailbox messages together into the queue, to save
+ the time of synchronization between two cores.
+
+2. Mailbox handling parses the mailbox message copied in SPE and fetches the
+ information of the PSA client call, including the PSA client call type.
+ Additional checks can be executed to make sure that the mailbox message is
+ valid. It may require additional information carried in the mailbox message.
+
+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, the mailbox
+handling can process mailbox messages one by one. Mailbox handling can complete
+all the mailbox messages processing before running to the bottom half of the
+PendSV handler.
+
+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 errors 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 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 related specific documents.
+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 module in dual-core
+scenario and SVCall handlers in single Armv8-M scenario.
+
+TF-M RPC module
+===============
+
+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.
+
+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);
+ };
+
+``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.
+
+----------------
+
+Copyright (c) 2019-2020 Arm Limited. All Rights Reserved.
+Copyright (c) 2020 Cypress Semiconductor Corporation
diff --git a/docs/design_documents/dual-cpu/dual_core_mailbox_arch.png b/docs/design_documents/dual-cpu/dual_core_mailbox_arch.png
new file mode 100644
index 0000000..79f5654
--- /dev/null
+++ b/docs/design_documents/dual-cpu/dual_core_mailbox_arch.png
Binary files differ
diff --git a/docs/design_documents/dual-cpu/index.rst b/docs/design_documents/dual-cpu/index.rst
new file mode 100644
index 0000000..f302748
--- /dev/null
+++ b/docs/design_documents/dual-cpu/index.rst
@@ -0,0 +1,12 @@
+Dual-CPU
+========
+
+.. toctree::
+ :maxdepth: 1
+ :glob:
+
+ *
+
+--------------
+
+*Copyright (c) 2020, Arm Limited. All rights reserved.*
diff --git a/docs/design_documents/dual-cpu/mailbox_design_on_dual_core_system.rst b/docs/design_documents/dual-cpu/mailbox_design_on_dual_core_system.rst
new file mode 100644
index 0000000..baa2e71
--- /dev/null
+++ b/docs/design_documents/dual-cpu/mailbox_design_on_dual_core_system.rst
@@ -0,0 +1,1415 @@
+##########################################
+Mailbox Design in TF-M on Dual-core System
+##########################################
+
+:Authors: David Hu
+:Organization: Arm Limited
+:Contact: david.hu@arm.com
+:Status: Accepted
+
+************
+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) module.
+RPC module delivers the requests to TF-M core/Secure Partition Manager (SPM).
+After the PSA Client call is completed, TF-M core/SPM invokes RPC module 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
+is 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
+
+- either assign an empty slot, copy the corresponding mailbox message from
+ non-secure memory to that slot and parse the message.
+- or directly parse the corresponding mailbox message in non-secure memory
+
+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 and returns the assignment result.
+
+#. 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. The mechanism of waiting and waking may vary in different NSPE OS and on
+ diverse platforms. Please refer to `Mechanism of waiting for PSA Client reply in NSPE (Informative)`_
+ for more details.
+
+#. 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, if multiple ongoing mailbox messages are
+ pending in the SPE, SPE mailbox can process mailbox messages one by one.
+ The handling routine can include the following steps:
+
+ #. SPE mailbox checks and validates NSPE mailbox queue status.
+ #. If necessary, SPE mailbox can copy mailbox message(s) from non-secure
+ memory, into SPE mailbox queue. If mailbox supports multiple outstanding
+ NS PSA Client call requests, it is recommended to copy multiple mailbox
+ message(s) together to save time consumption.
+ #. SPE mailbox parses a mailbox message.
+ #. 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.
+
+#. After the PSA Client call is completed, TF-M RPC module 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 OS 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 (Informative)
+========================================================
+
+PSA Client APIs are implemented with NSPE mailbox functions with NS software
+specific support. The implementation is platform and NS OS specific.
+
+The pseudo code of a reference implementation of a PSA Client API is shown below.
+
+.. code-block:: c
+
+ ... psa_xxx(...)
+ {
+ mailbox_msg_handle_t handle;
+
+ ...
+
+ /*
+ * Select an empty slot from NSPE mailbox queue and send PSA Client
+ * request to SPE.
+ * When NSPE mailbox queue is full, a proper waiting mechanism should
+ * block current non-secure thread until an empty slot is available.
+ */
+ handle = tfm_ns_mailbox_tx_client_req(...);
+
+ /* Platform/NSPE OS specific waiting for PSA client call reply */
+ wait_for_event(mailbox_reply_event, ...);
+ /* Stop waiting after woken up or reply event is detectd */
+
+ /* Fetch PSA client call return result */
+ tfm_ns_mailbox_rx_client_reply(handle, ...);
+
+ ...
+ }
+
+As PSA Firmware Framework requests, a PSA Client API function should be blocked
+until the result is returned. To comply with PSA specs, the PSA Client APIs
+implementation should include a proper mechanism to keep current caller
+thread waiting for an empty mailbox queue slot when NSPE mailbox queue is full.
+The caller thread can be switched out by NS OS scheduler to release CPU time to
+dother threads. The waiting mechanism can be platform and NS OS specific or a
+general implementation.
+
+For example, PSA Client function can rely on a counting semaphore in which the
+number of resource is the same as that of mailbox queue slots. Such a counting
+semaphore can keep current non-secure thread waiting for an empty slot if the
+queue is full.
+
+A PSA Client function should invoke ``tfm_ns_mailbox_tx_client_req()`` to send
+the request to SPE.
+``tfm_ns_mailbox_tx_client_req()`` selects an empty NSPE mailbox queue slot,
+fills the mailbox message and notifies SPE mailbox. The details are described
+in `tfm_ns_mailbox_tx_client_req()`_.
+
+After ``tfm_ns_mailbox_tx_client_req()`` completes, PSA Client function should
+invoke platform and NS OS specific functions to wait for the reply. It is
+recommended to force PSA Client function to exclusively wait for the reply
+event. Other events irrelevant to mailbox or PSA Client call should be ignored,
+unless the dual-core system has special requirements on thread management.
+The mechanism to wait for result and wake the waiting thread is discussed in
+`Mechanism of waiting for PSA Client reply in NSPE (Informative)`_.
+
+If the implementation performs a simple polling on a single mailbox message, it
+can call ``tfm_ns_mailbox_is_msg_replied()`` to wait for the deidcated message
+result.
+If the implementation performs a waiting/waking mechanism, it can call
+``tfm_ns_mailbox_wait_reply()`` which calls ``tfm_ns_mailbox_hal_wait_reply()``
+implemented by platform and NS OS specific mechanism.
+
+After the reply is returned, the PSA Client function invokes
+``tfm_ns_mailbox_rx_client_reply()`` to fetch return result and release NSPE
+mailbox queue resource.
+The details of the API will be described in `tfm_ns_mailbox_rx_client_reply()`_.
+
+Mechanism of waiting for PSA Client reply in NSPE (Informative)
+===============================================================
+
+As discussed above, PSA Client function should wait for the mailbox reply event
+after the PSA Client request is submit. When the result is returned to NSPE
+mailbox, the waiting non-secure thread is triggered to handle the result.
+
+To support multiple outstanding NS PSA Client calls feature on dual-core system,
+NSPE software should be able to identify the owner thread of the incoming PSA
+Client result. A field ``owner`` is defined in NSPE mailbox queue slot structure
+to hold the handle to the non-secure thread owner. The ``owner`` filed maps a
+mailbox queue slot containing the PSA Client result, to the non-secure task.
+
+The following pseudo-code shows an example implementation.
+
+After ``non_secure_task()`` calls PSA Client API ``psa_xxx()``, it falls into
+sleep in ``psa_xxx()`` until the result is returned.
+
+``tfm_ns_mailbox_tx_client_req()`` sets the owner non-secure thread handle in
+the mailbox queue slot. Then ``tfm_ns_mailbox_wait_reply()`` calls
+``tfm_ns_mailbox_hal_wait_reply()`` to let NS OS put current caller thread into
+waiting state. ``tfm_ns_mailbox_hal_wait_reply()`` is implemented by platform or
+NS OS specific thread management.
+
+After SPE notifies NSPE that PSA Client result is replied,
+``notification_handler()`` in NSPE determins the waiting non-secure owener
+thread of the PSA Client result. Then the waiting non-secure thread is woken up
+by NS OS.
+
+The owener thread is woken up from ``tfm_ns_mailbox_wait_reply()`` and fetches
+the result by calling ``tfm_ns_mailbox_rx_client_reply()``.
+
+.. code-block:: c
+
+ int32_t tfm_ns_mailbox_wait_reply(handle)
+ {
+ ...
+
+ /*
+ * Implemented by platform/NS OS specific waiting mechanism.
+ * Woken up by ns_os_wake_task() below.
+ */
+ tfm_ns_mailbox_hal_wait_reply(handle);
+
+ ...
+ }
+
+ ... psa_xxx(...)
+ {
+ ...
+
+ /* The owner information is also set during filling mailbox message */
+ handle = tfm_ns_mailbox_tx_client_req(...);
+
+ /* Trapped in sleep and wait for reply */
+ tfm_ns_mailbox_wait_reply(handle);
+ /* Wake up and continue */
+
+ tfm_ns_mailbox_rx_client_reply(handle, ...);
+
+ ...
+ }
+
+ /* non-secure task requests secure services */
+ void non_secure_task(...)
+ {
+ ...
+
+ /*
+ * Blocked and waiting in PSA Client API until the result is returned from
+ * SPE
+ */
+ psa_xxx(...);
+
+ ...
+ }
+
+ /* NSPE handler of Inter-Processor Communication notification interrupt */
+ void notification_handler(...)
+ {
+ mailbox_msg_handle_t handle;
+ void *task_handle;
+
+ /* Deal with notification from SPE */
+ ...
+
+ /* Check and fetch the handle to the mailbox message replied */
+ handle = tfm_ns_mailbox_fetch_reply_msg_isr();
+
+ if (handle) {
+ /*
+ * Get the handle of non-secure task whose mailbox message is replied.
+ * The owner information is set in tfm_ns_mailbox_tx_client_req().
+ */
+ task_handle = tfm_ns_mailbox_get_msg_owner(handle);
+
+ /*
+ * Wake up the waiting non-secure task from
+ * tfm_ns_mailbox_hal_wait_reply() above.
+ * Implemented by platform/NS OS specific mechanism.
+ */
+ ns_os_wake_task(task_handle);
+ }
+
+ ...
+ }
+
+NSPE mailbox APIs ``tfm_ns_mailbox_wait_reply()``,
+``tfm_ns_mailbox_hal_wait_reply()`` and ``tfm_ns_mailbox_fetch_reply_msg_isr()``
+are described in details `NSPE mailbox APIs`_ below.
+
+Critical section protection of NSPE mailbox queue
+=================================================
+
+Proper protection should be implemented to protect the critical accesses to NSPE
+mailbox queue. The critical sections can include atomic reading and modifying
+slot status, and other critical operations on NSPE mailbox queue.
+
+NSPE mailbox and SPE mailbox define corresponding critical section APIs. The
+implementation of those APIs can be platform specific. Please see more details
+in `NSPE mailbox APIs`_ and `SPE mailbox APIs`_.
+
+The implementation should protect a critical access to NSPE mailbox queue from
+corruptions caused by
+
+- Other non-secure tasks or exception service routines in NS OS
+- Accesses from the Secure core. SPE mailbox also accesses NSPE mailbox queue to
+ parse mailbox message. Therefore, it is essential to implement synchronization
+ or protection on NSPE mailbox queue between Secure core and Non-secure core.
+
+It is recommended to rely on both hardware and software to implement the
+synchronization and protection.
+
+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 call 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.
+
+**********************
+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
+---------
+
+``NUM_MAILBOX_QUEUE_SLOT``
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+``NUM_MAILBOX_QUEUE_SLOT`` sets the number of slots in NSPE and SPE mailbox
+queues.
+In current design, both NSPE and SPE mailbox should refer to the same
+``NUM_MAILBOX_QUEUE_SLOT`` definition.
+
+The following example configures 4 slots in mailbox queues.
+
+.. code-block:: c
+
+ #define NUM_MAILBOX_QUEUE_SLOT (4)
+
+``MAILBOX_MSG_NULL_HANDLE``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+``MAILBOX_MSG_NULL_HANDLE`` is a zero-value null handle of a mailbox message.
+
+.. code-block:: c
+
+ #define MAILBOX_MSG_NULL_HANDLE ((mailbox_msg_handle_t)0)
+
+``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)
+
+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 caller. 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;
+ };
+
+Mailbox message handle
+----------------------
+
+This data type is an opaque reference to an active mailbox message in use.
+
+.. code-block:: c
+
+ typedef int32_t mailbox_msg_handle_t;
+
+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;
+
+ /* Identification of the owner task of this slot */
+ const void *owner;
+ };
+
+``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.
+
+.. 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];
+ };
+
+SPE mailbox queue structure
+---------------------------
+
+``secure_mailbox_slot_t`` defines a single slot structure in SPE mailbox queue.
+
+- ``msg`` stores the mailbox message content copied from NSPE mailbox queue. It
+ is optional if the actual SPE implementation skips the mailbox message copy
+ operation to save time and memory consumption.
+- ``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
+
+ struct secure_mailbox_slot_t {
+ struct mailbox_msg_t msg;
+
+ 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.
+
+.. 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;
+ };
+
+Mailbox APIs
+============
+
+NSPE mailbox APIs
+-----------------
+
+This section describes a *reference design* of NSPE mailbox APIs. Vendor can
+define and implement different NSPE mailbox APIs.
+
+SPE must not invoke these NSPE mailbox APIs.
+
+``tfm_ns_mailbox_tx_client_req()``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This function sends the PSA Client request to SPE.
+
+.. code-block:: c
+
+ mailbox_msg_handle_t tfm_ns_mailbox_tx_client_req(uint32_t call_type,
+ const struct psa_client_params_t *params,
+ int32_t client_id);
+
+**Parameters**
+
++---------------+--------------------------------------------------+
+| ``call_type`` | Type of PSA client call |
++---------------+--------------------------------------------------+
+| ``params`` | Address of PSA Client call parameters structure. |
++---------------+--------------------------------------------------+
+| ``client_id`` | ID of non-secure task. |
++---------------+--------------------------------------------------+
+
+**Return**
+
++------+----------------------------------------------------------+
+| >= 0 | The handle to the mailbox message successfully assigned. |
++------+----------------------------------------------------------+
+| < 0 | Operation failed with an error code. |
++------+----------------------------------------------------------+
+
+**Usage**
+
+``tfm_ns_mailbox_tx_client_req()`` executes the following tasks:
+
+- Select an empty NSPE mailbox queue slot.
+- receives the PSA client call parameters
+- prepares the mailbox message.
+- notifies SPE via Inter-Processor Communication
+
+In ``tfm_ns_mailbox_tx_client_req()``, it can set the owner of the mailbox
+message to identify the non-secure caller thread to support multiple outstanding
+NS PSA Client calls.
+
+``tfm_ns_mailbox_rx_client_reply()``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This function fetches the PSA Client results returned from SPE.
+
+.. code-block:: c
+
+ int32_t tfm_ns_mailbox_rx_client_reply(mailbox_msg_handle_t handle,
+ int32_t *reply);
+
+**Parameters**
+
++------------+-----------------------------------------------+
+| ``handle`` | The handle to the mailbox message replied. |
++------------+-----------------------------------------------+
+| ``reply`` | The address to be written with return result. |
++------------+-----------------------------------------------+
+
+**Return**
+
++---------------------+--------------------------------------------+
+| ``MAILBOX_SUCCESS`` | Successfully get PSA Client return result. |
++---------------------+--------------------------------------------+
+| Other return codes | Operation failed with an error code |
++---------------------+--------------------------------------------+
+
+**Usage**
+
+A correct ``handle`` should be passed to ``tfm_ns_mailbox_rx_client_reply()`` to
+determine the target mailbox message which sent the PSA Client request.
+
+Before exiting ``tfm_ns_mailbox_rx_client_reply()``, the mailbox objects related
+to that completed PSA Client call are invalidated or cleaned.
+
+``tfm_ns_mailbox_is_msg_replied()``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This function checks if the PSA Client result is returned from SPE to a specific
+mailbox message.
+
+.. code-block:: c
+
+ bool tfm_ns_mailbox_is_msg_replied(mailbox_msg_handle_t handle);
+
+**Parameters**
+
++------------+-------------------------------------------+
+| ``handle`` | The handle to the target mailbox message. |
++------------+-------------------------------------------+
+
+**Return**
+
++-----------+-------------------------------------------------+
+| ``true`` | The PSA Client return value is replied. |
++-----------+-------------------------------------------------+
+| ``false`` | The PSA Client return value is not replied yet. |
++-----------+-------------------------------------------------+
+
+``tfm_ns_mailbox_get_task_handle()``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This function gets the handle of the current non-secure task executing mailbox
+functionalities.
+
+.. code-block:: c
+
+ void *tfm_ns_mailbox_get_task_handle(void);
+
+**Return**
+
++-------------+-----------------------------------------------------------+
+| Task handle | The non-secure task handle waiting for PSA Client result. |
++-------------+-----------------------------------------------------------+
+
+**Usage**
+
+``tfm_ns_mailbox_get_task_handle()`` is implemented by NS OS specific thread
+management. If the dual-core system doesn't require multiple outstanding NS PSA
+Client calls feature, ``tfm_ns_mailbox_get_task_handle()`` can return ``NULL``.
+
+If NSPE OS enforces non-secure tasks isolation, it is recommended to invoke
+``tfm_ns_mailbox_get_task_handle()`` in privileged mode to protect owner value
+from disclosure or tampering.
+
+``tfm_ns_mailbox_get_msg_owner()``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This function returns the owner of the mailbox message.
+
+.. code-block:: c
+
+ void *tfm_ns_mailbox_get_msg_owner(mailbox_msg_handle_t handle);
+
+**Parameters**
+
++------------+-------------------------------------------+
+| ``handle`` | The handle to the target mailbox message. |
++------------+-------------------------------------------+
+
+**Return**
+
++-------------------+--------------------------------------------------------+
+| Owner task handle | The handle to the non-secure owner task of the mailbox |
+| | message |
++-------------------+--------------------------------------------------------+
+
+**Usage**
+
+The owner task handle is get via ``tfm_ns_mailbox_get_task_handle()`` and set
+into NSPE mailbox queue slot inside ``tfm_ns_mailbox_tx_client_req()``.
+
+If multiple outstanding NS PSA Client calls feature is not supported in a
+dual-core system, ``tfm_ns_mailbox_get_msg_owner()`` can return ``NULL``.
+
+If NSPE OS enforces non-secure tasks isolation, it is recommended to invoke
+``tfm_ns_mailbox_get_msg_owner()`` in privileged mode to protect owner value
+from disclosure or tampering.
+
+``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_fetch_reply_msg_isr()``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This function fetches the first mailbox message which got PSA Client results in
+an IRQ handler.
+
+.. code-block:: c
+
+ mailbox_msg_handle_t tfm_ns_mailbox_fetch_reply_msg_isr(void);
+
+**Return**
+
++-----------------------------+---------------------------------------------+
+| ``MAILBOX_MSG_NULL_HANDLE`` | No mailbox message has been replied. |
++-----------------------------+---------------------------------------------+
+| Mailbox message handle | The handle to the first mailbox message got |
+| | PSA Client result. |
++-----------------------------+---------------------------------------------+
+
+**Usage**
+
+The Inter-Processor Communication notification interrupt handler can invoke
+``tfm_ns_mailbox_fetch_reply_msg_isr()`` to fetch the first mailbox message
+which receives the PSA Client result and then call
+``tfm_ns_mailbox_get_msg_owner()`` to determine the waiting owner thread.
+``tfm_ns_mailbox_hal_enter_critical_isr()`` and
+``tfm_ns_mailbox_hal_exit_critical_isr()`` are called inside
+``tfm_ns_mailbox_fetch_reply_msg_isr()``.
+
+``tfm_ns_mailbox_wait_reply()``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This function forces current non-secure caller thread to sleep and wait for the
+PSA Client result of the specified mailbox message.
+
+.. code-block:: c
+
+ int32_t tfm_ns_mailbox_wait_reply(mailbox_msg_handle_t handle);
+
+**Parameters**
+
++------------+---------------------------------------------------+
+| ``handle`` | The handle to mailbox message waiting for result. |
++------------+---------------------------------------------------+
+
+**Return**
+
++---------------------+------------------------------------+
+| ``MAILBOX_SUCCESS`` | Return from waiting successfully. |
++---------------------+------------------------------------+
+| Other return codes | Failed to wait with an error code. |
++---------------------+------------------------------------+
+
+**Usage**
+
+The PSA Client API implementations call ``tfm_ns_mailbox_wait_reply()`` to fall
+into sleep to wait for PSA Client result.
+
+``tfm_ns_mailbox_wait_reply()`` calls ``tfm_ns_mailbox_hal_wait_reply()`` to
+execute platform/NS OS specific sleeping operation.
+
+``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.
+
+``tfm_ns_mailbox_hal_wait_reply()``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This function performs platform and NS OS specific waiting mechanism to wait for
+PSA Client result of the specified mailbox message.
+
+.. code-block:: c
+
+ int32_t tfm_ns_mailbox_hal_wait_reply(mailbox_msg_handle_t handle);
+
+**Parameters**
+
++------------+---------------------------------------------------+
+| ``handle`` | The handle to mailbox message waiting for result. |
++------------+---------------------------------------------------+
+
+**Return**
+
++---------------------+------------------------------------+
+| ``MAILBOX_SUCCESS`` | Return from waiting successfully. |
++---------------------+------------------------------------+
+| Other return codes | Failed to wait with an error code. |
++---------------------+------------------------------------+
+
+SPE mailbox APIs
+----------------
+
+NSPE should not invoke these SPE mailbox APIs.
+
+``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_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:`Botting a Dual-core system <booting_a_dual_core_system>`
+
+--------------------
+
+*Copyright (c) 2019-2020 Arm Limited. All Rights Reserved.*
diff --git a/docs/design_documents/dual-cpu/tfm_multi_core_access_check.rst b/docs/design_documents/dual-cpu/tfm_multi_core_access_check.rst
new file mode 100644
index 0000000..c19f0bc
--- /dev/null
+++ b/docs/design_documents/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 SPM */
+ if (not in Handler mode) {
+ 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, Arm Limited. All rights reserved.*