Merge "docs(changelog): changelog for v2.9 release" into integration
diff --git a/.readthedocs.yaml b/.readthedocs.yaml
index 450d6be..6207066 100644
--- a/.readthedocs.yaml
+++ b/.readthedocs.yaml
@@ -17,10 +17,10 @@
     - plantuml
   jobs:
     post_create_environment:
-      - pip install poetry
+      - pip install poetry=="1.3.2"
       - poetry config virtualenvs.create false
     post_install:
-      - poetry install --with docs
+      - poetry install --with doc
 
 sphinx:
   configuration: docs/conf.py
diff --git a/docs/about/features.rst b/docs/about/features.rst
index cb8b552..4a2c77e 100644
--- a/docs/about/features.rst
+++ b/docs/about/features.rst
@@ -22,8 +22,8 @@
    Cache Coherent Network (CCN), Network Interconnect (NIC) and TrustZone
    Controller (TZC).
 
--  A generic |SCMI| driver to interface with conforming power controllers, for
-   example the Arm System Control Processor (SCP).
+-  Secure Monitor library code such as world switching, EL2/EL1 context
+   management and interrupt routing.
 
 -  SMC (Secure Monitor Call) handling, conforming to the `SMC Calling
    Convention`_ using an EL3 runtime services framework.
@@ -34,14 +34,22 @@
    is also suitable for integration with other AArch32 EL3 Runtime Software,
    for example an AArch32 Secure OS.
 
+-  A generic |SCMI| driver to interface with conforming power controllers, for
+   example the Arm System Control Processor (SCP).
+
 -  A minimal AArch32 Secure Payload (*SP_MIN*) to demonstrate |PSCI| library
    integration with AArch32 EL3 Runtime Software.
 
--  Secure Monitor library code such as world switching, EL1 context management
-   and interrupt routing.
-   When a Secure-EL1 Payload (SP) is present, for example a Secure OS, the
-   AArch64 EL3 Runtime Software must be integrated with a Secure Payload
-   Dispatcher (SPD) component to customize the interaction with the SP.
+-  Secure partition manager dispatcher(SPMD) with following two configurations:
+
+   -  S-EL2 SPMC implementation, widely compliant with FF-A v1.1 EAC0 and initial
+      support of FF-A v1.2.
+
+   -  EL3 SPMC implementation, compliant with a subset of FF-A v1.1 EAC0.
+
+-  Support for Arm CCA based on FEAT_RME which supports authenticated boot and
+   execution of RMM with the necessary routing of RMI commands as specified in
+   RMM Beta 0 Specification.
 
 -  A Test SP and SPD to demonstrate AArch64 Secure Monitor functionality and SP
    interaction with PSCI.
@@ -50,12 +58,20 @@
    `Trusty Secure OS`_ and `ProvenCore Secure OS`_.
 
 -  A Trusted Board Boot implementation, conforming to all mandatory TBBR
-   requirements. This includes image authentication, Firmware Update (or
-   recovery mode), and packaging of the various firmware images into a
+   requirements. This includes image authentication, Firmware recovery,
+   Firmware encryption and packaging of the various firmware images into a
    Firmware Image Package (FIP).
 
--  Pre-integration of TBB with the Arm CryptoCell product, to take advantage of
-   its hardware Root of Trust and crypto acceleration services.
+-  Measured boot support with PoC to showcase its interaction with firmware TPM
+   (fTPM) service implemneted on top of OP-TEE.
+
+-  Support for Dynamic Root of Trust for Measurement (DRTM).
+
+-  Following firmware update mechanisms available:
+
+   -  PSA Firmware Update (PSA FWU)
+
+   -  TBBR Firmware Update (TBBR FWU)
 
 -  Reliability, Availability, and Serviceability (RAS) functionality, including
 
@@ -81,6 +97,8 @@
    secure system processor, or where a non-TF-A ROM expects BL2 to be loaded
    at EL3.
 
+-  Support for Errata management firmware interface.
+
 -  Support for the GCC, LLVM and Arm Compiler 6 toolchains.
 
 -  Support for combining several libraries into a "romlib" image that may be
@@ -88,27 +106,13 @@
    in ROM but is accessed through a jump-table that may be stored
    in read-write memory, allowing for the library code to be patched.
 
--  Support for the Secure Partition Manager Dispatcher (SPMD) component as a
-   new standard service.
-
--  Support for ARMv8.3 pointer authentication in the normal and secure worlds.
-   The use of pointer authentication in the normal world is enabled whenever
-   architectural support is available, without the need for additional build
-   flags.
-
--  Position-Independent Executable (PIE) support. Currently for BL2, BL31, and
-   TSP, with further support to be added in a future release.
+-  Position-Independent Executable (PIE) support.
 
 Still to come
 -------------
 
 -  Support for additional platforms.
 
--  Refinements to Position Independent Executable (PIE) support.
-
--  Continued support for the FF-A v1.0 (formally known as SPCI) specification, to enable the
-   use of secure partition management in the secure world.
-
 -  Documentation enhancements.
 
 -  Ongoing support for new architectural features, CPUs and System IP.
@@ -125,4 +129,4 @@
 
 --------------
 
-*Copyright (c) 2019-2021, Arm Limited. All rights reserved.*
+*Copyright (c) 2019-2023, Arm Limited. All rights reserved.*
diff --git a/docs/components/secure-partition-manager.rst b/docs/components/secure-partition-manager.rst
index 8dc1c61..e61dc20 100644
--- a/docs/components/secure-partition-manager.rst
+++ b/docs/components/secure-partition-manager.rst
@@ -461,8 +461,15 @@
 - *cpus* node provide the platform topology and allows MPIDR to VMPIDR mapping.
   Note the primary core is declared first, then secondary cores are declared
   in reverse order.
-- The *memory* node provides platform information on the ranges of memory
-  available to the SPMC.
+- The *memory* nodes provide platform information on the ranges of memory
+  available for use by SPs at runtime. These ranges relate to either
+  secure or non-secure memory, depending on the *device_type* field.
+  If the field specifies "memory" the range is secure, else if it specifies
+  "ns-memory" the memory is non-secure. The system integrator must exclude
+  the memory used by other components that are not SPs, such as the monitor,
+  or the SPMC itself, the OS Kernel/Hypervisor, or other NWd VMs. The SPMC
+  limits the SP's address space such that they do not access memory outside
+  of those ranges.
 
 SPMC boot
 ~~~~~~~~~
@@ -562,7 +569,12 @@
 - Memory regions are mapped in the SP EL1&0 Stage-2 translation regime at
   load time (or EL1&0 Stage-1 for an S-EL1 SPMC). A memory region node can
   specify RX/TX buffer regions in which case it is not necessary for an SP
-  to explicitly invoke the ``FFA_RXTX_MAP`` interface.
+  to explicitly invoke the ``FFA_RXTX_MAP`` interface. The memory referred
+  shall be contained within the memory ranges defined in SPMC manifest. The
+  NS bit in the attributes field should be consistent with the security
+  state of the range that it relates to. I.e. non-secure memory shall be
+  part of a non-secure memory range, and secure memory shall be contained
+  in a secure memory range of a given platform.
 - Device regions are mapped in the SP EL1&0 Stage-2 translation regime (or
   EL1&0 Stage-1 for an S-EL1 SPMC) as peripherals and possibly allocate
   additional resources (e.g. interrupts).
@@ -1029,6 +1041,68 @@
 
 This is used in particular to convey power management messages.
 
+Memory Sharing
+--------------
+
+Hafnium implements the following memory sharing interfaces:
+
+ - ``FFA_MEM_SHARE`` - for shared access between lender and borrower.
+ - ``FFA_MEM_LEND`` - borrower to obtain exclusive access, though lender
+   retains ownership of the memory.
+ - ``FFA_MEM_DONATE`` - lender permanently relinquishes ownership of memory
+   to the borrower.
+
+The ``FFA_MEM_RETRIEVE_REQ`` interface is for the borrower to request the
+memory to be mapped into its address space: for S-EL1 partitions the SPM updates
+their stage 2 translation regime; for S-EL0 partitions the SPM updates their
+stage 1 translation regime. On a successful call, the SPMC responds back with
+``FFA_MEM_RETRIEVE_RESP``.
+
+The ``FFA_MEM_RELINQUISH`` interface is for when the borrower is done with using
+a memory region.
+
+The ``FFA_MEM_RECLAIM`` interface is for the owner of the memory to reestablish
+its ownership and exclusive access to the memory shared.
+
+The memory transaction descriptors are transmitted via RX/TX buffers. In
+situations where the size of the memory transaction descriptor exceeds the
+size of the RX/TX buffers, Hafnium provides support for fragmented transmission
+of the full transaction descriptor. The ``FFA_MEM_FRAG_RX`` and ``FFA_MEM_FRAG_TX``
+interfaces are for receiving and transmitting the next fragment, respectively.
+
+If lender and borrower(s) are SPs, all memory sharing operations are supported.
+
+Hafnium also supports memory sharing operations between the normal world and the
+secure world. If there is an SP involved, the SPMC allocates data to track the
+state of the operation.
+
+The SPMC is also the designated allocator for the memory handle. The hypervisor
+or OS kernel has the possibility to rely on the SPMC to maintain the state
+of the operation, thus saving memory.
+A lender SP can only donate NS memory to a borrower from the normal world.
+
+The SPMC supports the hypervisor retrieve request, as defined by the FF-A
+v1.1 EAC0 specification, in section 16.4.3. The intent is to aid with operations
+that the hypervisor must do for a VM retriever. For example, when handling
+an FFA_MEM_RECLAIM, if the hypervisor relies on SPMC to keep the state
+of the operation, the hypervisor retrieve request can be used to obtain
+that state information, do the necessary validations, and update stage 2
+memory translation.
+
+Hafnium also supports memory lend and share targetting multiple borrowers.
+This is the case for a lender SP to multiple SPs, and for a lender VM to
+multiple endpoints (from both secure world and normal world). If there is
+at least one borrower VM, the hypervisor is in charge of managing its
+stage 2 translation on a successful memory retrieve.
+The semantics of ``FFA_MEM_DONATE`` implies ownership transmission,
+which should target only one partition.
+
+The memory share interfaces are backwards compatible with memory transaction
+descriptors from FF-A v1.0. These get translated to FF-A v1.1 descriptors for
+Hafnium's internal processing of the operation. If the FF-A version of a
+borrower is v1.0, Hafnium provides FF-A v1.0 compliant memory transaction
+descriptors on memory retrieve response.
+
 PE MMU configuration
 --------------------
 
diff --git a/docs/design/firmware-design.rst b/docs/design/firmware-design.rst
index 2c9b76a..14b273e 100644
--- a/docs/design/firmware-design.rst
+++ b/docs/design/firmware-design.rst
@@ -2622,16 +2622,29 @@
 section lists the usage of Architecture Extensions, and build flags
 controlling them.
 
-In general, and unless individually mentioned, the build options
-``ARM_ARCH_MAJOR`` and ``ARM_ARCH_MINOR`` select the Architecture Extension to
-target when building TF-A. Subsequent Arm Architecture Extensions are backward
-compatible with previous versions.
+Build options
+~~~~~~~~~~~~~
+
+``ARM_ARCH_MAJOR`` and ``ARM_ARCH_MINOR``
+
+These build options serve dual purpose
+
+- Determine the architecture extension support in TF-A build: All the mandatory
+  architectural features up to ``ARM_ARCH_MAJOR.ARM_ARCH_MINOR`` are included
+  and unconditionally enabled by TF-A build system.
+
+- Passed to compiler via "-march" option to generate binary target : Tell the
+  compiler to emit instructions upto ``ARM_ARCH_MAJOR.ARM_ARCH_MINOR``
+
+The build system requires that the platform provides a valid numeric value based on
+CPU architecture extension, otherwise it defaults to base Armv8.0-A architecture.
+Subsequent Arm Architecture versions also support extensions which were introduced
+in previous versions.
 
-The build system only requires that ``ARM_ARCH_MAJOR`` and ``ARM_ARCH_MINOR`` have a
-valid numeric value. These build options only control whether or not
-Architecture Extension-specific code is included in the build. Otherwise, TF-A
-targets the base Armv8.0-A architecture; i.e. as if ``ARM_ARCH_MAJOR`` == 8
-and ``ARM_ARCH_MINOR`` == 0, which are also their respective default values.
+**TO-DO** : Its planned to decouple the two functionalities and introduce a new macro
+for compiler usage. The requirement for this decoupling arises becasue TF-A code
+always provides support for the latest and greatest architecture features but this
+is not the case for the target compiler.
 
 .. seealso:: :ref:`Build Options`
 
diff --git a/docs/getting_started/prerequisites.rst b/docs/getting_started/prerequisites.rst
index a3f8cc8..f4c3c28 100644
--- a/docs/getting_started/prerequisites.rst
+++ b/docs/getting_started/prerequisites.rst
@@ -14,7 +14,7 @@
 |TF-A| can be built using either a Linux or a Windows machine as the build host.
 
 A relatively recent Linux distribution is recommended for building |TF-A|. We
-have performed tests using Ubuntu 20.04 LTS (64-bit) but other distributions
+have performed tests using Ubuntu 22.04 LTS (64-bit) but other distributions
 should also work fine as a base, provided that the necessary tools and libraries
 can be installed.
 
@@ -77,11 +77,11 @@
 The following libraries are required for Trusted Board Boot and Measured Boot
 support:
 
-- mbed TLS == 2.28.1 (tag: ``mbedtls-2.28.1``)
+- mbed TLS == 3.4.0 (tag: ``mbedtls-3.4.0``)
 
 These tools are optional:
 
-- Device Tree Compiler (DTC) >= 1.4.6
+- Device Tree Compiler (DTC) >= 1.4.7
 
    Needed if you want to rebuild the provided Flattened Device Tree (FDT)
    source files (``.dts`` files). DTC is available for Linux through the package
diff --git a/docs/perf/index.rst b/docs/perf/index.rst
index b83c6e3..0938a17 100644
--- a/docs/perf/index.rst
+++ b/docs/perf/index.rst
@@ -7,6 +7,7 @@
 
    psci-performance-instr
    psci-performance-juno
+   psci-performance-n1sdp
    psci-performance-methodology
    tsp
    performance-monitoring-unit
diff --git a/docs/perf/psci-performance-juno.rst b/docs/perf/psci-performance-juno.rst
index 7418669..7a484b8 100644
--- a/docs/perf/psci-performance-juno.rst
+++ b/docs/perf/psci-performance-juno.rst
@@ -25,62 +25,189 @@
 Juno supports CPU, cluster and system power down states, corresponding to power
 levels 0, 1 and 2 respectively. It does not support any retention states.
 
-We used the upstream `TF master as of 31/01/2017`_, building the platform using
-the ``ENABLE_RUNTIME_INSTRUMENTATION`` option:
+Given that runtime instrumentation using PMF is invasive, there is a small
+(unquantified) overhead on the results. PMF uses the generic counter for
+timestamps, which runs at 50MHz on Juno.
 
-.. code:: shell
+The following source trees and binaries were used:
 
-    make PLAT=juno ENABLE_RUNTIME_INSTRUMENTATION=1 \
-        SCP_BL2=<path/to/scp-fw.bin>                \
-        BL33=<path/to/test-fw.bin>                  \
-        all fip
+- TF-A [`v2.9-rc0`_]
+- TFTF [`v2.9-rc0`_]
 
-When using the debug build of TF, there was no noticeable difference in the
-results.
+Please see the Runtime Instrumentation `Testing Methodology`_ page for more
+details.
 
-The tests are based on an ARM-internal test framework. The release build of this
-framework was used because the results in the debug build became skewed; the
-console output prevented some of the tests from executing in parallel.
+Procedure
+---------
 
-The tests consist of both parallel and sequential tests, which are broadly
-described as follows:
+#. Build TFTF with runtime instrumentation enabled:
 
-- **Parallel Tests** This type of test powers on all the non-lead CPUs and
-  brings them and the lead CPU to a common synchronization point.  The lead CPU
-  then initiates the test on all CPUs in parallel.
+    .. code:: shell
 
-- **Sequential Tests** This type of test powers on each non-lead CPU in
-  sequence. The lead CPU initiates the test on a non-lead CPU then waits for the
-  test to complete before proceeding to the next non-lead CPU. The lead CPU then
-  executes the test on itself.
+        make CROSS_COMPILE=aarch64-none-elf- PLAT=juno \
+            TESTS=runtime-instrumentation all
 
-In the results below, CPUs 0-3 refer to CPUs in the little cluster (A53) and
-CPUs 4-5 refer to CPUs in the big cluster (A57). In all cases CPU 4 is the lead
-CPU.
+#. Fetch Juno's SCP binary from TF-A's archive:
 
-``PSCI_ENTRY`` refers to the time taken from entering the TF PSCI implementation
-to the point the hardware enters the low power state (WFI). Referring to the TF
-runtime instrumentation points, this corresponds to:
-``(RT_INSTR_ENTER_HW_LOW_PWR - RT_INSTR_ENTER_PSCI)``.
+    .. code:: shell
 
-``PSCI_EXIT`` refers to the time taken from the point the hardware exits the low
-power state to exiting the TF PSCI implementation. This corresponds to:
-``(RT_INSTR_EXIT_PSCI - RT_INSTR_EXIT_HW_LOW_PWR)``.
+        curl --fail --connect-timeout 5 --retry 5 -sLS -o scp_bl2.bin \
+            https://downloads.trustedfirmware.org/tf-a/css_scp_2.12.0/juno/release/juno-bl2.bin
 
-``CFLUSH_OVERHEAD`` refers to the part of ``PSCI_ENTRY`` taken to flush the
-caches. This corresponds to: ``(RT_INSTR_EXIT_CFLUSH - RT_INSTR_ENTER_CFLUSH)``.
+#. Build TF-A with the following build options:
 
-Note there is very little variance observed in the values given (~1us), although
-the values for each CPU are sometimes interchanged, depending on the order in
-which locks are acquired. Also, there is very little variance observed between
-executing the tests sequentially in a single boot or rebooting between tests.
+    .. code:: shell
 
-Given that runtime instrumentation using PMF is invasive, there is a small
-(unquantified) overhead on the results. PMF uses the generic counter for
-timestamps, which runs at 50MHz on Juno.
+        make CROSS_COMPILE=aarch64-none-elf- PLAT=juno \
+            BL33="/path/to/tftf.bin" SCP_BL2="scp_bl2.bin" \
+            ENABLE_RUNTIME_INSTRUMENTATION=1 fiptool all fip
+
+#. Load the following images onto the development board: ``fip.bin``,
+   ``scp_bl2.bin``.
+
+Results
+-------
+
+``CPU_SUSPEND`` to deepest power level
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. table:: ``CPU_SUSPEND`` latencies (µs) to deepest power level in
+        parallel
+
+    +---------+------+-----------+---------+-------------+
+    | Cluster | Core | Powerdown | Wakekup | Cache Flush |
+    +=========+======+===========+=========+=============+
+    |    0    |  0   |   243.76  |  239.92 |     6.32    |
+    +---------+------+-----------+---------+-------------+
+    |    0    |  1   |   663.5   |  30.32  |    167.82   |
+    +---------+------+-----------+---------+-------------+
+    |    1    |  0   |   105.12  |  22.84  |     5.88    |
+    +---------+------+-----------+---------+-------------+
+    |    1    |  1   |   384.16  |  19.06  |     4.7     |
+    +---------+------+-----------+---------+-------------+
+    |    1    |  2   |   523.98  |  270.46 |     4.74    |
+    +---------+------+-----------+---------+-------------+
+    |    1    |  3   |   950.54  |  220.9  |     89.2    |
+    +---------+------+-----------+---------+-------------+
+
+.. table:: ``CPU_SUSPEND`` latencies (µs) to deepest power level in
+        serial
+
+    +---------+------+-----------+---------+-------------+
+    | Cluster | Core | Powerdown | Wakekup | Cache Flush |
+    +=========+======+===========+=========+=============+
+    |    0    |  0   |   266.96  |  31.74  |    167.92   |
+    +---------+------+-----------+---------+-------------+
+    |    0    |  1   |   266.9   |  31.52  |    167.82   |
+    +---------+------+-----------+---------+-------------+
+    |    1    |  0   |   279.86  |  23.42  |    87.52    |
+    +---------+------+-----------+---------+-------------+
+    |    1    |  1   |   101.38  |   18.8  |     4.64    |
+    +---------+------+-----------+---------+-------------+
+    |    1    |  2   |   101.18  |  19.28  |     4.64    |
+    +---------+------+-----------+---------+-------------+
+    |    1    |  3   |   101.32  |  19.02  |     4.62    |
+    +---------+------+-----------+---------+-------------+
+
+``CPU_SUSPEND`` to power level 0
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-Results and Commentary
-----------------------
+.. table:: ``CPU_SUSPEND`` latencies (µs) to power level 0 in
+        parallel
+
+    +---------+------+-----------+---------+-------------+
+    | Cluster | Core | Powerdown | Wakekup | Cache Flush |
+    +=========+======+===========+=========+=============+
+    +---------+------+-----------+---------+-------------+
+    |    0    |  0   |   661.94  |  22.88  |     9.66    |
+    +---------+------+-----------+---------+-------------+
+    |    0    |  1   |   801.64  |  23.38  |     9.62    |
+    +---------+------+-----------+---------+-------------+
+    |    1    |  0   |   105.56  |  16.02  |     8.12    |
+    +---------+------+-----------+---------+-------------+
+    |    1    |  1   |   245.42  |  16.26  |     7.78    |
+    +---------+------+-----------+---------+-------------+
+    |    1    |  2   |   384.42  |   16.1  |     7.84    |
+    +---------+------+-----------+---------+-------------+
+    |    1    |  3   |   523.74  |   15.4  |     8.02    |
+    +---------+------+-----------+---------+-------------+
+
+.. table:: ``CPU_SUSPEND`` latencies (µs) to power level 0 in serial
+
+    +---------+------+-----------+---------+-------------+
+    | Cluster | Core | Powerdown | Wakekup | Cache Flush |
+    +=========+======+===========+=========+=============+
+    |    0    |  0   |   102.16  |  23.64  |     6.7     |
+    +---------+------+-----------+---------+-------------+
+    |    0    |  1   |   101.66  |  23.78  |     6.6     |
+    +---------+------+-----------+---------+-------------+
+    |    1    |  0   |   277.74  |  15.96  |     4.66    |
+    +---------+------+-----------+---------+-------------+
+    |    1    |  1   |    98.0   |  15.88  |     4.64    |
+    +---------+------+-----------+---------+-------------+
+    |    1    |  2   |   97.66   |  15.88  |     4.62    |
+    +---------+------+-----------+---------+-------------+
+    |    1    |  3   |   97.76   |  15.38  |     4.64    |
+    +---------+------+-----------+---------+-------------+
+
+``CPU_OFF`` on all non-lead CPUs
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+``CPU_OFF`` on all non-lead CPUs in sequence then, ``CPU_SUSPEND`` on the lead
+core to the deepest power level.
+
+.. table:: ``CPU_OFF`` latencies (µs) on all non-lead CPUs
+
+    +---------+------+-----------+---------+-------------+
+    | Cluster | Core | Powerdown | Wakekup | Cache Flush |
+    +=========+======+===========+=========+=============+
+    |    0    |  0   |   265.38  |  34.12  |    167.36   |
+    +---------+------+-----------+---------+-------------+
+    |    0    |  1   |   265.72  |  33.98  |    167.48   |
+    +---------+------+-----------+---------+-------------+
+    |    1    |  0   |   185.3   |  23.18  |    87.42    |
+    +---------+------+-----------+---------+-------------+
+    |    1    |  1   |   101.58  |  23.46  |     4.48    |
+    +---------+------+-----------+---------+-------------+
+    |    1    |  2   |   101.66  |  22.02  |     4.72    |
+    +---------+------+-----------+---------+-------------+
+    |    1    |  3   |   101.48  |  22.22  |     4.52    |
+    +---------+------+-----------+---------+-------------+
+
+``CPU_VERSION`` in parallel
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. table:: ``CPU_VERSION`` latency (µs) in parallel on all cores
+
+    +-------------+--------+--------------+
+    |   Cluster   |  Core  |   Latency    |
+    +=============+========+==============+
+    |      0      |   0    |     1.22     |
+    +-------------+--------+--------------+
+    |      0      |   1    |     1.2      |
+    +-------------+--------+--------------+
+    |      1      |   0    |     0.6      |
+    +-------------+--------+--------------+
+    |      1      |   1    |     1.08     |
+    +-------------+--------+--------------+
+    |      1      |   2    |     1.04     |
+    +-------------+--------+--------------+
+    |      1      |   3    |     1.04     |
+    +-------------+--------+--------------+
+
+Annotated Historic Results
+--------------------------
+
+The following results are based on the upstream `TF master as of 31/01/2017`_.
+TF-A was built using the same build instructions as detailed in the procedure
+above.
+
+In the results below, CPUs 0-3 refer to CPUs in the little cluster (A53) and
+CPUs 4-5 refer to CPUs in the big cluster (A57). In all cases CPU 4 is the lead
+CPU.
+
+``PSCI_ENTRY`` corresponds to the powerdown latency, ``PSCI_EXIT`` the wakeup latency, and
+``CFLUSH_OVERHEAD`` the latency of the cache flush operation.
 
 ``CPU_SUSPEND`` to deepest power level on all CPUs in parallel
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -290,3 +417,5 @@
 
 .. _Juno R1 platform: https://developer.arm.com/documentation/100122/latest/
 .. _TF master as of 31/01/2017: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/tree/?id=c38b36d
+.. _v2.9-rc0: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/tree/?h=v2.9-rc0
+.. _Testing Methodology: ../perf/psci-performance-methodology.html
diff --git a/docs/perf/psci-performance-n1sdp.rst b/docs/perf/psci-performance-n1sdp.rst
new file mode 100644
index 0000000..70a1436
--- /dev/null
+++ b/docs/perf/psci-performance-n1sdp.rst
@@ -0,0 +1,203 @@
+Runtime Instrumentation Testing - N1SDP
+=======================================
+
+For this test we used the N1 System Development Platform (`N1SDP`_), which
+contains an SoC consisting of two dual-core Arm N1 clusters.
+
+The following source trees and binaries were used:
+
+- TF-A [`v2.9-rc0-16-g666aec401`_]
+- TFTF [`v2.9-rc0`_]
+- SCP/MCP `Prebuilt Images`_
+
+Please see the Runtime Instrumentation `Testing Methodology`_ page for more
+details.
+
+Procedure
+---------
+
+#. Build TFTF with runtime instrumentation enabled:
+
+    .. code:: shell
+
+        make CROSS_COMPILE=aarch64-none-elf- PLAT=n1sdp \
+            TESTS=runtime-instrumentation all
+
+#. Build TF-A with the following build options:
+
+    .. code:: shell
+
+        make CROSS_COMPILE=aarch64-none-elf- PLAT=n1sdp \
+            ENABLE_RUNTIME_INSTRUMENTATION=1 fiptool all
+
+#. Fetch the SCP firmware images:
+
+    .. code:: shell
+
+        curl --fail --connect-timeout 5 --retry 5 \
+            -sLS -o build/n1sdp/release/scp_rom.bin \
+            https://downloads.trustedfirmware.org/tf-a/css_scp_2.12.0/n1sdp/release/n1sdp-bl1.bin
+        curl --fail --connect-timeout 5 \
+            --retry 5 -sLS -o build/n1sdp/release/scp_ram.bin \
+            https://downloads.trustedfirmware.org/tf-a/css_scp_2.12.0/n1sdp/release/n1sdp-bl2.bin
+
+#. Fetch the MCP firmware images:
+
+    .. code:: shell
+
+        curl --fail --connect-timeout 5 --retry 5 \
+            -sLS -o build/n1sdp/release/mcp_rom.bin \
+            https://downloads.trustedfirmware.org/tf-a/css_scp_2.12.0/n1sdp/release/n1sdp-mcp-bl1.bin
+        curl --fail --connect-timeout 5 --retry 5 \
+            -sLS -o build/n1sdp/release/mcp_ram.bin \
+            https://downloads.trustedfirmware.org/tf-a/css_scp_2.12.0/n1sdp/release/n1sdp-mcp-bl2.bin
+
+#. Using the fiptool, create a new FIP package and append the SCP ram image onto
+   it.
+
+    .. code:: shell
+
+        ./tools/fiptool/fiptool create --blob \
+                uuid=cfacc2c4-15e8-4668-82be-430a38fad705,file=build/n1sdp/release/bl1.bin \
+                --scp-fw build/n1sdp/release/scp_ram.bin build/n1sdp/release/scp_fw.bin
+
+#. Append the MCP image to the FIP.
+
+    .. code:: shell
+
+        ./tools/fiptool/fiptool create \
+            --blob uuid=54464222-a4cf-4bf8-b1b6-cee7dade539e,file=build/n1sdp/release/mcp_ram.bin \
+            build/n1sdp/release/mcp_fw.bin
+
+#. Then, add TFTF as the Non-Secure workload in the FIP image:
+
+    .. code:: shell
+
+        make CROSS_COMPILE=aarch64-none-elf- PLAT=n1sdp \
+            ENABLE_RUNTIME_INSTRUMENTATION=1 SCP_BL2=/dev/null \
+            BL33=<path/to/tftf.bin>  fip
+
+#. Load the following images onto the development board: ``fip.bin``,
+   ``scp_rom.bin``, ``scp_ram.bin``, ``mcp_rom.bin``, and ``mcp_ram.bin``.
+
+.. note::
+
+    These instructions presume you have a complete firmware stack. The N1SDP
+    `user guide`_ provides a detailed explanation on how to get setup from
+    scratch.
+
+Results
+-------
+
+``CPU_SUSPEND`` to deepest power level
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. table:: ``CPU_SUSPEND`` latencies (µs) to deepest power level in
+        parallel
+
+    +---------+------+-----------+---------+-------------+
+    | Cluster | Core | Powerdown | Wakekup | Cache Flush |
+    +=========+======+===========+=========+=============+
+    |    0    |  0   |    3.44   |  10.04  |     0.4     |
+    +---------+------+-----------+---------+-------------+
+    |    0    |  1   |    4.98   |  12.72  |     0.16    |
+    +---------+------+-----------+---------+-------------+
+    |    1    |  0   |    3.58   |  15.42  |     0.2     |
+    +---------+------+-----------+---------+-------------+
+    |    1    |  1   |    5.24   |  17.78  |     0.18    |
+    +---------+------+-----------+---------+-------------+
+
+.. table:: ``CPU_SUSPEND`` latencies (µs) to deepest power level in
+        serial
+
+    +---------+------+-----------+---------+-------------+
+    | Cluster | Core | Powerdown | Wakekup | Cache Flush |
+    +=========+======+===========+=========+=============+
+    |    0    |  0   |    1.82   |   9.98  |     0.32    |
+    +---------+------+-----------+---------+-------------+
+    |    0    |  1   |    1.96   |   9.96  |     0.18    |
+    +---------+------+-----------+---------+-------------+
+    |    1    |  0   |    2.0    |   10.5  |     0.16    |
+    +---------+------+-----------+---------+-------------+
+    |    1    |  1   |    2.22   |  10.56  |     0.16    |
+    +---------+------+-----------+---------+-------------+
+
+``CPU_SUSPEND`` to power level 0
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. table:: ``CPU_SUSPEND`` latencies (µs) to power level 0 in
+        parallel
+
+    +---------+------+-----------+---------+-------------+
+    | Cluster | Core | Powerdown | Wakekup | Cache Flush |
+    +=========+======+===========+=========+=============+
+    |    0    |  0   |    1.52   |  11.84  |     0.34    |
+    +---------+------+-----------+---------+-------------+
+    |    0    |  1   |    1.1    |  13.66  |     0.14    |
+    +---------+------+-----------+---------+-------------+
+    |    1    |  0   |    2.18   |   9.48  |     0.18    |
+    +---------+------+-----------+---------+-------------+
+    |    1    |  1   |    2.06   |   14.4  |     0.16    |
+    +---------+------+-----------+---------+-------------+
+
+.. table:: ``CPU_SUSPEND`` latencies (µs) to power level 0 in serial
+
+    +---------+------+-----------+---------+-------------+
+    | Cluster | Core | Powerdown | Wakekup | Cache Flush |
+    +=========+======+===========+=========+=============+
+    |    0    |  0   |    1.54   |   9.34  |     0.3     |
+    +---------+------+-----------+---------+-------------+
+    |    0    |  1   |    1.88   |   9.5   |     0.16    |
+    +---------+------+-----------+---------+-------------+
+    |    1    |  0   |    1.86   |   9.86  |     0.2     |
+    +---------+------+-----------+---------+-------------+
+    |    1    |  1   |    2.02   |   9.64  |     0.18    |
+    +---------+------+-----------+---------+-------------+
+
+``CPU_OFF`` on all non-lead CPUs
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+``CPU_OFF`` on all non-lead CPUs in sequence then, ``CPU_SUSPEND`` on the lead
+core to the deepest power level.
+
+.. table:: ``CPU_OFF`` latencies (µs) on all non-lead CPUs
+
+    +---------+------+-----------+---------+-------------+
+    | Cluster | Core | Powerdown | Wakekup | Cache Flush |
+    +=========+======+===========+=========+=============+
+    |    0    |  0   |    1.86   |   9.88  |     0.32    |
+    +---------+------+-----------+---------+-------------+
+    |    0    |  1   |    21.1   |  12.44  |     0.42    |
+    +---------+------+-----------+---------+-------------+
+    |    1    |  0   |   21.22   |   13.2  |     0.32    |
+    +---------+------+-----------+---------+-------------+
+    |    1    |  1   |   21.56   |  13.18  |     0.54    |
+    +---------+------+-----------+---------+-------------+
+
+``CPU_VERSION`` in parallel
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. table:: ``CPU_VERSION`` latency (µs) in parallel on all cores
+
+    +-------------+--------+--------------+
+    |   Cluster   |  Core  |   Latency    |
+    +=============+========+==============+
+    |      0      |   0    |     0.08     |
+    +-------------+--------+--------------+
+    |      0      |   1    |     0.22     |
+    +-------------+--------+--------------+
+    |      1      |   0    |     0.28     |
+    +-------------+--------+--------------+
+    |      1      |   1    |     0.26     |
+    +-------------+--------+--------------+
+
+--------------
+
+*Copyright (c) 2023, Arm Limited. All rights reserved.*
+
+.. _v2.9-rc0-16-g666aec401: https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/refs/heads/v2.9-rc0-16-g666aec401
+.. _v2.9-rc0: https://review.trustedfirmware.org/plugins/gitiles/TF-A/tf-a-tests/+/refs/tags/v2.9-rc0
+.. _user guide: https://gitlab.arm.com/arm-reference-solutions/arm-reference-solutions-docs/-/blob/master/docs/n1sdp/user-guide.rst
+.. _Prebuilt Images:  https://downloads.trustedfirmware.org/tf-a/css_scp_2.11.0/n1sdp/release/
+.. _N1SDP: https://developer.arm.com/documentation/101489/latest
+.. _Testing Methodology: ../perf/psci-performance-methodology.html
\ No newline at end of file
diff --git a/docs/threat_model/threat_model_spm.rst b/docs/threat_model/threat_model_spm.rst
index 98dbf76..9458a9f 100644
--- a/docs/threat_model/threat_model_spm.rst
+++ b/docs/threat_model/threat_model_spm.rst
@@ -35,7 +35,7 @@
 - The TF-A implementation for the S-EL2 SPMC based on the Hafnium hypervisor
   running in the secure world of TrustZone (at S-EL2 exception level).
   The threat model is not related to the normal world Hypervisor or VMs.
-  The S-EL1 SPMC solution is not covered.
+  The S-EL1 and EL3 SPMC solutions are not covered.
 - The implementation complies with the FF-A v1.0 specification, and a few
   features of FF-A v1.1 specification.
 - Secure partitions are statically provisioned at boot time.
@@ -235,8 +235,8 @@
 +------------------------+------------------+-----------------+---------------+
 | ``Total Risk Rating``  | High (16)        | High (16)       |               |
 +------------------------+------------------+-----------------+---------------+
-| ``Mitigations``        | In context of FF-A v1.0 this is the case of sharing|
-|                        | the RX/TX buffer pair and usage in the             |
+| ``Mitigations``        | In context of FF-A v1.0 and v1.1 this is the case  |
+|                        | of sharing the RX/TX buffer pair and usage in the  |
 |                        | PARTITION_INFO_GET or mem sharing primitives.      |
 |                        | The SPMC must copy the contents of the TX buffer   |
 |                        | to an internal temporary buffer before processing  |
@@ -1151,11 +1151,189 @@
 |                        | interrupted.                                       |
 +------------------------+----------------------------------------------------+
 
++------------------------+----------------------------------------------------+
+| ID                     | 25                                                 |
++========================+====================================================+
+| ``Threat``             | **A rogue FF-A endpoint can use memory sharing     |
+|                        | calls to exhaust SPMC resources.**                 |
+|                        | For each on-going operation that involves an SP,   |
+|                        | the SPMC allocates resources to track its state.   |
+|                        | If the operation is never concluded, the resources |
+|                        | are never freed.                                   |
+|                        | In the worst scenario, multiple operations that    |
+|                        | never conclude may exhaust the SPMC resources to a |
+|                        | point in which renders memory sharing operations   |
+|                        | impossible. This could affect other, non-harmful   |
+|                        | FF-A endpoints, from legitimately using memory     |
+|                        | share functionality. The intent might even be      |
+|                        | to cause the SPMC to consume excessive CPU cycles, |
+|                        | attempting to make it deny its service to the NWd. |
++------------------------+----------------------------------------------------+
+| ``Diagram Elements``   | DF1, DF2                                           |
++------------------------+----------------------------------------------------+
+| ``Affected TF-A        | SPMC, SPMD                                         |
+| Components``           |                                                    |
++------------------------+----------------------------------------------------+
+| ``Assets``             | SPMC state                                         |
++------------------------+----------------------------------------------------+
+| ``Threat Agent``       | NS-Endpoint, S-Endpoint                            |
++------------------------+----------------------------------------------------+
+| ``Threat Type``        | Denial of Service                                  |
++------------------------+------------------+-----------------+---------------+
+| ``Application``        |   ``Server``     |   ``Mobile``    |               |
++------------------------+------------------+-----------------+---------------+
+| ``Impact``             | High (4)         | Medium (3)      |               |
++------------------------+------------------+-----------------+---------------+
+| ``Likelihood``         | High (4)         | Medium (3)      |               |
++------------------------+------------------+-----------------+---------------+
+| ``Total Risk Rating``  | High (16)        | Medium (9)      |               |
++------------------------+------------------+-----------------+---------------+
+| ``Mitigations``        | The TF-A SPMC uses a statically allocated pool of  |
+|                        | memory to keep track of on-going memory sharing    |
+|                        | operations. After a possible attack, this could    |
+|                        | fail due to insufficient memory, and return an     |
+|                        | error to the caller. At this point, any other      |
+|                        | endpoint that requires use of memory sharing for   |
+|                        | its operation could get itself in an unusable      |
+|                        | state.                                             |
+|                        | Regarding CPU cycles starving threat, the SPMC     |
+|                        | doesn't provide any mitigation for this, as any    |
+|                        | FF-A endpoint, at the virtual FF-A instance is     |
+|                        | allowed to invoke memory share/lend/donate.        |
++------------------------+----------------------------------------------------+
+
++------------------------+----------------------------------------------------+
+| ID                     | 26                                                 |
++========================+====================================================+
+| ``Threat``             | **A borrower may interfere with lender's           |
+|                        | operation, if it terminates due to a fatal error   |
+|                        | condition without releasing the memory             |
+|                        | shared/lent.**                                     |
+|                        | Such scenario may render the lender inoperable.    |
++------------------------+----------------------------------------------------+
+| ``Diagram Elements``   | DF1, DF2                                           |
++------------------------+----------------------------------------------------+
+| ``Affected TF-A        | SPMC                                               |
+| Components``           |                                                    |
++------------------------+----------------------------------------------------+
+| ``Assets``             | SP state                                           |
++------------------------+----------------------------------------------------+
+| ``Threat Agent``       | NS-Endpoint, S-Endpoint                            |
++------------------------+----------------------------------------------------+
+| ``Threat Type``        | Denial of Service                                  |
++------------------------+------------------+-----------------+---------------+
+| ``Application``        |   ``Server``     |   ``Mobile``    |               |
++------------------------+------------------+-----------------+---------------+
+| ``Impact``             | High (4)         | Low (2)         |               |
++------------------------+------------------+-----------------+---------------+
+| ``Likelihood``         | Medium (3)       | Medium (3)      |               |
++------------------------+------------------+-----------------+---------------+
+| ``Total Risk Rating``  | High (12)        | Medium(6)       |               |
++------------------------+------------------+-----------------+---------------+
+| ``Mitigations``        | The TF-A SPMC does not provide mitigation for such |
+|                        | scenario. The FF-A endpoints must attempt to       |
+|                        | relinquish memory shared/lent themselves in        |
+|                        | case of failure. The memory used to track the      |
+|                        | operation in the SPMC will also remain usuable.    |
++------------------------+----------------------------------------------------+
+
++------------------------+----------------------------------------------------+
+| ID                     | 27                                                 |
++========================+====================================================+
+| ``Threat``             | **A rogue FF-A endpoint may attempt to tamper with |
+|                        | the content of the memory shared/lent, whilst      |
+|                        | being accessed by other FF-A endpoints.**          |
+|                        | It might attempt to do so: using one of the clear  |
+|                        | flags, when either retrieving or relinquishing     |
+|                        | access to the memory via the respective FF-A       |
+|                        | calls; or directly accessing memory without        |
+|                        | respecting the synchronization protocol between    |
+|                        | all involved endpoints.                            |
++------------------------+----------------------------------------------------+
+| ``Diagram Elements``   | DF1, DF2                                           |
++------------------------+----------------------------------------------------+
+| ``Affected TF-A        | SPMC, FF-A endpoint                                |
+| Components``           |                                                    |
++------------------------+----------------------------------------------------+
+| ``Assets``             | SP state                                           |
++------------------------+----------------------------------------------------+
+| ``Threat Agent``       | NS-Endpoint, S-Endpoint                            |
++------------------------+----------------------------------------------------+
+| ``Threat Type``        | Denial of Service, Tampering                       |
++------------------------+------------------+-----------------+---------------+
+| ``Application``        |   ``Server``     |   ``Mobile``    |               |
++------------------------+------------------+-----------------+---------------+
+| ``Impact``             | Low (2)          | Low (2)         |               |
++------------------------+------------------+-----------------+---------------+
+| ``Likelihood``         | Medium (3)       | Medium (3)      |               |
++------------------------+------------------+-----------------+---------------+
+| ``Total Risk Rating``  | Medium (6)       | Medium(6)       |               |
++------------------------+------------------+-----------------+---------------+
+| ``Mitigations``        | The first case defined in the threat, the TF-A     |
+|                        | SPMC mitigates it, by ensuring a memory is cleared |
+|                        | only when all borrowers have relinquished access   |
+|                        | to the memory, in a scenario involving multiple    |
+|                        | borrowers. Also, if the receiver is granted RO,    |
+|                        | permissions, the SPMC will reject any request      |
+|                        | to clear memory on behalf of the borrower, by      |
+|                        | returning an error to the respective FF-A call.    |
+|                        | The second case defined in the threat can't be     |
+|                        | mitigated by the SPMC. It is up to the NS/S FF-A   |
+|                        | endpoints to establish a robust protocol for using |
+|                        | the shared memory.                                 |
++------------------------+----------------------------------------------------+
+
++------------------------+----------------------------------------------------+
+| ID                     | 28                                                 |
++========================+====================================================+
+| ``Threat``             | **A rogue FF-A endpoint may attempt to share       |
+|                        | memory that is not in its translation regime, or   |
+|                        | attempt to specify attributes more permissive than |
+|                        | those it possesses at a given time.**              |
+|                        | Both ways could be an attempt for escalating its   |
+|                        | privileges.                                        |
++------------------------+----------------------------------------------------+
+| ``Diagram Elements``   | DF1, DF2                                           |
++------------------------+----------------------------------------------------+
+| ``Affected TF-A        | SPMC, FF-A endpoint                                |
+| Components``           |                                                    |
++------------------------+----------------------------------------------------+
+| ``Assets``             | SP state                                           |
++------------------------+----------------------------------------------------+
+| ``Threat Agent``       | NS-Endpoint, S-Endpoint                            |
++------------------------+----------------------------------------------------+
+| ``Threat Type``        | Denial of Service, Tampering                       |
++------------------------+------------------+-----------------+---------------+
+| ``Application``        |   ``Server``     |   ``Mobile``    |               |
++------------------------+------------------+-----------------+---------------+
+| ``Impact``             | High (4)         | Low (2)         |               |
++------------------------+------------------+-----------------+---------------+
+| ``Likelihood``         | Medium (3)       | Low (2)         |               |
++------------------------+------------------+-----------------+---------------+
+| ``Total Risk Rating``  | High (12)        | Low (2)         |               |
++------------------------+------------------+-----------------+---------------+
+| ``Mitigations``        | The TF-A SPMC mitigates this threat by performing  |
+|                        | sanity checks to the provided memory region        |
+|                        | descriptor.                                        |
+|                        | For operations at the virtual FF-A instance, and   |
+|                        | once the full memory descriptor is provided,       |
+|                        | the SPMC validates that the memory is part of the  |
+|                        | caller's translation regime. The SPMC also checks  |
+|                        | that the memory attributes provided are within     |
+|                        | those the owner possesses, in terms of             |
+|                        | permissiveness. If more permissive attributes are  |
+|                        | specified, the SPMC returns an error               |
+|                        | FFA_INVALID_PARAMETERS. The permissiveness rules   |
+|                        | are enforced in any call to share/lend or donate   |
+|                        | the memory, and in retrieve requests.              |
++------------------------+----------------------------------------------------+
+
 --------------
 
-*Copyright (c) 2021-2022, Arm Limited. All rights reserved.*
+*Copyright (c) 2021-2023, Arm Limited. All rights reserved.*
 
 .. _Arm Firmware Framework for Arm A-profile: https://developer.arm.com/docs/den0077/latest
 .. _Secure Partition Manager: ../components/secure-partition-manager.html
 .. _Generic TF-A threat model: ./threat_model.html#threat-analysis
 .. _FF-A ACS: https://github.com/ARM-software/ff-a-acs/releases
+
diff --git a/plat/arm/board/morello/morello_bl31_setup.c b/plat/arm/board/morello/morello_bl31_setup.c
index e13a38b..8469cd1 100644
--- a/plat/arm/board/morello/morello_bl31_setup.c
+++ b/plat/arm/board/morello/morello_bl31_setup.c
@@ -35,7 +35,6 @@
 const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops)
 {
 	ops->pwr_domain_off = morello_pwr_domain_off;
-	ops->pwr_domain_suspend = morello_pwr_domain_suspend;
 	return css_scmi_override_pm_ops(ops);
 }
 
diff --git a/plat/arm/board/morello/morello_pm.c b/plat/arm/board/morello/morello_pm.c
index dda006e..fa7bd1d 100644
--- a/plat/arm/board/morello/morello_pm.c
+++ b/plat/arm/board/morello/morello_pm.c
@@ -11,19 +11,13 @@
 #include "morello_private.h"
 
 /*******************************************************************************
- * Morello specific functions called when turning off or suspending a power
- * domain. Both additionally disable the GIC redistributor interface as cores
- * are disabled to let cluster-PPU state transition to completion when a
- * cluster is powered down.
+ * Morello specific function called when turning off a power domain.
+ * Additionally disables the GIC redistributor interface as cores are disabled
+ * to let cluster-PPU state transition to completion when a cluster is
+ * powered down.
  ******************************************************************************/
 void morello_pwr_domain_off(const psci_power_state_t *target_state)
 {
 	css_pwr_domain_off(target_state);
 	plat_arm_gic_redistif_off();
 }
-
-void morello_pwr_domain_suspend(const psci_power_state_t *target_state)
-{
-	css_pwr_domain_suspend(target_state);
-	plat_arm_gic_redistif_off();
-}
diff --git a/plat/arm/board/morello/morello_private.h b/plat/arm/board/morello/morello_private.h
index ea2fce9..dea70fb 100644
--- a/plat/arm/board/morello/morello_private.h
+++ b/plat/arm/board/morello/morello_private.h
@@ -10,6 +10,5 @@
 #include <lib/psci/psci.h>
 
 void morello_pwr_domain_off(const psci_power_state_t *target_state);
-void morello_pwr_domain_suspend(const psci_power_state_t *target_state);
 
 #endif /* MORELLO_PRIVATE_H */
diff --git a/plat/arm/board/n1sdp/n1sdp_bl31_setup.c b/plat/arm/board/n1sdp/n1sdp_bl31_setup.c
index db7215f..2b9ed25 100644
--- a/plat/arm/board/n1sdp/n1sdp_bl31_setup.c
+++ b/plat/arm/board/n1sdp/n1sdp_bl31_setup.c
@@ -71,7 +71,6 @@
 const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops)
 {
 	ops->pwr_domain_off = n1sdp_pwr_domain_off;
-	ops->pwr_domain_suspend = n1sdp_pwr_domain_suspend;
 	return css_scmi_override_pm_ops(ops);
 }
 
diff --git a/plat/arm/board/n1sdp/n1sdp_pm.c b/plat/arm/board/n1sdp/n1sdp_pm.c
index e43832a..8d45354 100644
--- a/plat/arm/board/n1sdp/n1sdp_pm.c
+++ b/plat/arm/board/n1sdp/n1sdp_pm.c
@@ -11,19 +11,13 @@
 #include "n1sdp_private.h"
 
 /*******************************************************************************
- * N1SDP specific functions called when turning off or suspending a power
- * domain. Both additionally disable the GIC redistributor interface as cores
- * are disabled to let cluster-PPU state transition to completion when a
- * cluster is powered down.
+ * N1SDP specific function called when turning off a power domain. Additionally
+ * disables the GIC redistributor interface as cores are disabled to
+ * let cluster-PPU state transition to completion when a cluster is powered
+ * down.
  ******************************************************************************/
 void n1sdp_pwr_domain_off(const psci_power_state_t *target_state)
 {
 	css_pwr_domain_off(target_state);
 	plat_arm_gic_redistif_off();
 }
-
-void n1sdp_pwr_domain_suspend(const psci_power_state_t *target_state)
-{
-	css_pwr_domain_suspend(target_state);
-	plat_arm_gic_redistif_off();
-}
diff --git a/plat/arm/board/n1sdp/n1sdp_private.h b/plat/arm/board/n1sdp/n1sdp_private.h
index 7a5c51d..4e48c0f 100644
--- a/plat/arm/board/n1sdp/n1sdp_private.h
+++ b/plat/arm/board/n1sdp/n1sdp_private.h
@@ -10,6 +10,5 @@
 #include <lib/psci/psci.h>
 
 void n1sdp_pwr_domain_off(const psci_power_state_t *target_state);
-void n1sdp_pwr_domain_suspend(const psci_power_state_t *target_state);
 
 #endif /* N1SDP_PRIVATE_H */
diff --git a/plat/arm/board/tc/include/tc_plat.h b/plat/arm/board/tc/include/tc_plat.h
index 195366e..117fbb4 100644
--- a/plat/arm/board/tc/include/tc_plat.h
+++ b/plat/arm/board/tc/include/tc_plat.h
@@ -10,10 +10,11 @@
 void tc_bl31_common_platform_setup(void);
 
 #ifdef PLATFORM_TEST_TFM_TESTSUITE
-void run_platform_tests(void);
+int run_platform_tests(void);
 #endif
+
 #ifdef PLATFORM_TEST_NV_COUNTERS
-void nv_counter_test(void);
+int nv_counter_test(void);
 #endif
 
 #endif /* TC_PLAT_H */
diff --git a/plat/arm/board/tc/nv_counter_test.c b/plat/arm/board/tc/nv_counter_test.c
index 76c9915..f9e001e 100644
--- a/plat/arm/board/tc/nv_counter_test.c
+++ b/plat/arm/board/tc/nv_counter_test.c
@@ -13,7 +13,7 @@
 
 #include <platform_def.h>
 
-void nv_counter_test(void)
+int nv_counter_test(void)
 {
 	psa_status_t status;
 	uint32_t old_val;
@@ -23,7 +23,7 @@
 	status = rss_comms_init(PLAT_RSS_AP_SND_MHU_BASE, PLAT_RSS_AP_RCV_MHU_BASE);
 	if (status != PSA_SUCCESS) {
 		printf("Failed to initialize RSS communication channel\n");
-		plat_error_handler(-1);
+		return -1;
 	}
 
 	for (id = 0; id < 3; id++) {
@@ -31,28 +31,30 @@
 		if (status != PSA_SUCCESS) {
 			printf("Failed during first id=(%d) rss_platform_nv_counter_read\n",
 				       id);
-			plat_error_handler(-1);
+			return -1;
 		}
 
 		status = rss_platform_nv_counter_increment(id);
 		if (status != PSA_SUCCESS) {
 			printf("Failed during id=(%d) rss_platform_nv_counter_increment\n",
 					id);
-			plat_error_handler(-1);
+			return -1;
 		}
 
 		status = rss_platform_nv_counter_read(id, sizeof(new_val), (uint8_t *)&new_val);
 		if (status != PSA_SUCCESS) {
 			printf("Failed during second id=(%d) rss_platform_nv_counter_read\n",
 					id);
-			plat_error_handler(-1);
+			return -1;
 		}
 
 		if (old_val + 1 != new_val) {
 			printf("Failed nv_counter_test: old_val (%d) + 1 != new_val (%d)\n",
 					old_val, new_val);
-			plat_error_handler(-1);
+			return -1;
 		}
 	}
 	printf("Passed nv_counter_test\n");
+
+	return 0;
 }
diff --git a/plat/arm/board/tc/platform.mk b/plat/arm/board/tc/platform.mk
index 98c2e0e..c29537c 100644
--- a/plat/arm/board/tc/platform.mk
+++ b/plat/arm/board/tc/platform.mk
@@ -196,28 +196,32 @@
 
 endif
 
-ifeq (${PLATFORM_TEST},rss-nv-counters)
-    include drivers/arm/rss/rss_comms.mk
+ifneq (${PLATFORM_TEST},)
+    $(eval $(call add_define,PLATFORM_TESTS))
 
-    # Test code.
-    BL31_SOURCES	+=	plat/arm/board/tc/nv_counter_test.c
+    ifeq (${PLATFORM_TEST},rss-nv-counters)
+        include drivers/arm/rss/rss_comms.mk
 
-    # Code under testing.
-    BL31_SOURCES	+=	lib/psa/rss_platform.c \
+        # Test code.
+        BL31_SOURCES	+=	plat/arm/board/tc/nv_counter_test.c
+
+        # Code under testing.
+        BL31_SOURCES	+=	lib/psa/rss_platform.c \
 				drivers/arm/rss/rss_comms.c \
 				${RSS_COMMS_SOURCES}
 
-    PLAT_INCLUDES	+=	-Iinclude/lib/psa
+        PLAT_INCLUDES	+=	-Iinclude/lib/psa
 
-    $(eval $(call add_define,PLATFORM_TEST_NV_COUNTERS))
-else ifeq (${PLATFORM_TEST},tfm-testsuite)
-    # Add this include as first, before arm_common.mk. This is necessary
-    # because arm_common.mk builds Mbed TLS, and platform_test.mk can
-    # change the list of Mbed TLS files that are to be compiled
-    # (LIBMBEDTLS_SRCS).
-    include plat/arm/board/tc/platform_test.mk
-else ifneq (${PLATFORM_TEST},)
-    $(error "Unsupported PLATFORM_TEST value")
+        $(eval $(call add_define,PLATFORM_TEST_NV_COUNTERS))
+    else ifeq (${PLATFORM_TEST},tfm-testsuite)
+        # Add this include as first, before arm_common.mk. This is necessary
+        # because arm_common.mk builds Mbed TLS, and platform_test.mk can
+        # change the list of Mbed TLS files that are to be compiled
+        # (LIBMBEDTLS_SRCS).
+        include plat/arm/board/tc/platform_test.mk
+    else
+        $(error "Unsupported PLATFORM_TEST value")
+    endif
 endif
 
 
diff --git a/plat/arm/board/tc/rss_ap_tests.c b/plat/arm/board/tc/rss_ap_tests.c
index b62043e..8c40271 100644
--- a/plat/arm/board/tc/rss_ap_tests.c
+++ b/plat/arm/board/tc/rss_ap_tests.c
@@ -19,21 +19,28 @@
 	{.freg = register_testsuite_measured_boot},
 };
 
-static void run_tests(void)
+/*
+ * Return 0 if we could run all tests.
+ * Note that this does not mean that all tests passed - only that they all run.
+ * One should then look at each individual test result inside the
+ * test_suites[].val field.
+ */
+static int run_tests(void)
 {
 	enum test_suite_err_t ret;
 	psa_status_t status;
 	size_t i;
 
+	/* Initialize test environment. */
 	rss_comms_init(PLAT_RSS_AP_SND_MHU_BASE, PLAT_RSS_AP_RCV_MHU_BASE);
 	mbedtls_init();
 	status = psa_crypto_init();
 	if (status != PSA_SUCCESS) {
 		printf("\n\npsa_crypto_init failed (status = %d)\n", status);
-		assert(false);
-		plat_error_handler(-1);
+		return -1;
 	}
 
+	/* Run all tests. */
 	for (i = 0; i < ARRAY_SIZE(test_suites); ++i) {
 		struct test_suite_t *suite = &(test_suites[i]);
 
@@ -41,22 +48,33 @@
 		ret = run_testsuite(suite);
 		if (ret != TEST_SUITE_ERR_NO_ERROR) {
 			printf("\n\nError during executing testsuite '%s'.\n", suite->name);
-			assert(false);
-			plat_error_handler(-1);
+			return -1;
 		}
 	}
 	printf("\nAll tests are run.\n");
+
+	return 0;
 }
 
 void run_platform_tests(void)
 {
 	size_t i;
+	int ret;
+	int failures = 0;
 
-	run_tests();
+	ret = run_tests();
+	if (ret != 0) {
+		/* For some reason, we could not run all tests. */
+		return ret;
+	}
 
 	printf("\n\n");
 
-	/* Print a summary of all the tests that had been run. */
+	/*
+	 * Print a summary of all the tests that had been run.
+	 * Also count the number of tests failure and report that back to the
+	 * caller.
+	 */
 	printf("SUMMARY:\n");
 	for (i = 0; i < ARRAY_SIZE(test_suites); ++i) {
 
@@ -67,6 +85,7 @@
 			printf("    %s PASSED.\n", suite->name);
 			break;
 		case TEST_FAILED:
+			failures++;
 			printf("    %s FAILED.\n", suite->name);
 			break;
 		case TEST_SKIPPED:
@@ -79,4 +98,6 @@
 	}
 
 	printf("\n\n");
+
+	return failures;
 }
diff --git a/plat/arm/board/tc/tc_bl31_setup.c b/plat/arm/board/tc/tc_bl31_setup.c
index 6afbd99..ca3a032 100644
--- a/plat/arm/board/tc/tc_bl31_setup.c
+++ b/plat/arm/board/tc/tc_bl31_setup.c
@@ -50,18 +50,34 @@
 	fconf_populate("FW_CONFIG", arg1);
 }
 
-void tc_bl31_common_platform_setup(void)
+#ifdef PLATFORM_TESTS
+static __dead2 void tc_run_platform_tests(void)
 {
-	arm_bl31_platform_setup();
+	int tests_failed;
+
+	printf("\nStarting platform tests...\n");
 
-#if defined(PLATFORM_TEST_NV_COUNTERS) || defined(PLATFORM_TEST_TFM_TESTSUITE)
 #ifdef PLATFORM_TEST_NV_COUNTERS
-	nv_counter_test();
+	tests_failed = nv_counter_test();
 #elif PLATFORM_TEST_TFM_TESTSUITE
-	run_platform_tests();
+	tests_failed = run_platform_tests();
 #endif
-	/* Suspend booting */
+
+	printf("Platform tests %s.\n",
+	       (tests_failed != 0) ? "failed" : "succeeded");
+
+	/* Suspend booting, no matter the tests outcome. */
+	printf("Suspend booting...\n");
 	plat_error_handler(-1);
+}
+#endif
+
+void tc_bl31_common_platform_setup(void)
+{
+	arm_bl31_platform_setup();
+
+#ifdef PLATFORM_TESTS
+	tc_run_platform_tests();
 #endif
 }
 
diff --git a/plat/nvidia/tegra/soc/t210/plat_sip_calls.c b/plat/nvidia/tegra/soc/t210/plat_sip_calls.c
index 93d1283..f3ebd4b 100644
--- a/plat/nvidia/tegra/soc/t210/plat_sip_calls.c
+++ b/plat/nvidia/tegra/soc/t210/plat_sip_calls.c
@@ -33,8 +33,7 @@
 /*******************************************************************************
  * Tegra210 SiP SMCs
  ******************************************************************************/
-#define TEGRA_SIP_PMC_COMMANDS_LEGACY	U(0xC2FEFE00)
-#define TEGRA_SIP_PMC_COMMANDS		U(0xC2FFFE00)
+#define TEGRA_SIP_PMC_COMMANDS		U(0xC200FE00)
 
 /*******************************************************************************
  * This function is responsible for handling all T210 SiP calls
@@ -55,10 +54,12 @@
 	if (!ns)
 		SMC_RET1(handle, SMC_UNK);
 
-	if ((smc_fid == TEGRA_SIP_PMC_COMMANDS) || (smc_fid == TEGRA_SIP_PMC_COMMANDS_LEGACY)) {
+	if (smc_fid == TEGRA_SIP_PMC_COMMANDS) {
+
 		/* check the address is within PMC range and is 4byte aligned */
-		if ((x2 >= TEGRA_PMC_SIZE) || (x2 & 0x3))
+		if ((x2 >= TEGRA_PMC_SIZE) || (x2 & 0x3)) {
 			return -EINVAL;
+		}
 
 		switch (x2) {
 		/* Black listed PMC registers */