Merge changes from topic "errata" into integration

* changes:
  fix(cpus): workaround for Cortex-A78C erratum 2683027
  fix(cpus): workaround for Cortex-X3 erratum 2266875
  fix(cpus): workaround for Cortex-X3 erratum 2302506
diff --git a/.husky/pre-commit.copyright b/.husky/pre-commit.copyright
index a4dfee8..5f838a6 100755
--- a/.husky/pre-commit.copyright
+++ b/.husky/pre-commit.copyright
@@ -17,10 +17,24 @@
 
 exit_code=0
 
+PLATPROV=
+ORG=`echo "$GIT_AUTHOR_EMAIL" | awk -F '[@]' '{ print $2;}'`
+
+case $ORG in
+	amd.com)
+		PLATPROV="Advanced Micro Devices, Inc. All rights reserved."
+		;;
+	*arm.com)
+		PLATPROV="$ARM_RGX"
+		;;
+	*)
+		;;
+esac
+
 function user_warning() {
 	echo -e "Copyright of $RED$FILE$BLANK is out of date/incorrect"
 	echo -e "Updated copyright to"
-	grep -nr "opyright.*$YEAR_RGX.*$ARM_RGX" "$FILE"
+	grep -nr "opyright.*$YEAR_RGX.*$PLATPROV" "$FILE"
 	echo
 }
 
@@ -29,31 +43,45 @@
 	then
 		break
 	fi
-	# Check if correct copyright notice is in file.
-	# To reduce false positives, we assume files with no
-	# copyright notice do not require it.
-	if ! grep "opyright.*$YEAR_NOW.*$ARM_RGX" "$FILE">/dev/null 2>&1
+
+	# Check if copyright header exists for the org
+	if ! grep "opyright.*$YEAR_RGX.*$PLATPROV" "$FILE">/dev/null 2>&1 && [[ $ORG != *arm* ]]
 	then
-		# If it is "from_date - to_date" type of entry - change to_date entry.
-		if grep "opyright.*$YEAR_RGX.*-.*$YEAR_RGX.*$ARM_RGX" "$FILE" >/dev/null 2>&1
-		then
-			exit_code=1
-			sed -i "s/\(opyright.*\)$YEAR_RGX\(.*$ARM_RGX\)/\1$(date +"%Y"), Arm/" $FILE
-			user_warning
-		# If it is single "date" type of entry - add the copyright extension to current year.
-		elif grep "opyright.*$YEAR_RGX.*$ARM_RGX" "$FILE" >/dev/null 2>&1
+		echo -e "Copyright header ""$RED""$PLATPROV""$BLANK"" is missing in ""$YELLOW""$FILE""$BLANK"
+	fi
+
+	# Check if the copyright year is updated for the org  and update it
+	if [ ! -z "$PLATPROV" ]
+	then
+		if ! grep "opyright.*$YEAR_NOW.*$PLATPROV" "$FILE">/dev/null 2>&1
 		then
-			exit_code=1
-			sed -i "s/\(opyright.*$YEAR_RGX\)\(.*$ARM_RGX\)/\1-$(date +"%Y"), Arm/" $FILE
-			user_warning
+			# If it is "from_date - to_date" type of entry - change to_date entry.
+			if grep "opyright.*$YEAR_RGX.*-.*$YEAR_RGX.*$PLATPROV" "$FILE" >/dev/null 2>&1
+			then
+				exit_code=1
+				sed -i "s/\(opyright.*\)$YEAR_RGX\(.*$PLATPROV\)/\1$(date +"%Y")\2/" $FILE
+				user_warning
+			# If it is single "date" type of entry - add the copyright extension to current year.
+			elif grep "opyright.*$YEAR_RGX.*$PLATPROV" "$FILE" >/dev/null 2>&1
+			then
+				exit_code=1
+				sed -i "s/\(opyright.*$YEAR_RGX\)\(.*$PLATPROV\)/\1-$(date +"%Y")\2/" $FILE
+				user_warning
+			fi
+
+			# Even if the year is correct - verify that Arm copyright is formatted correctly.
+			if [[ $ORG == *arm* ]]
+			then
+				if grep "opyright.*\(ARM\|arm\)" "$FILE">/dev/null 2>&1
+				then
+					exit_code=1
+					sed -i "s/\(opyright.*\)\(ARM\|arm\)/\1Arm/" $FILE
+					user_warning
+				fi
+			fi
 		fi
-	# Even if the year is correct - verify that Arm copyright is formatted correctly.
-	elif grep "opyright.*\(ARM\|arm\)" "$FILE">/dev/null 2>&1
-	then
-		exit_code=1
-		sed -i "s/\(opyright.*\)\(ARM\|arm\)/\1Arm/" $FILE
-		user_warning
 	fi
+
 done <<< "$FILES"
 
 if [ $exit_code -eq 1 ]
diff --git a/changelog.yaml b/changelog.yaml
index c5e157d..f67ad29 100644
--- a/changelog.yaml
+++ b/changelog.yaml
@@ -1369,6 +1369,9 @@
         deprecated:
           - cert_create
 
+      - title: Marvell Tools
+        scope: marvell-tools
+
   - title: Dependencies
     scope: deps
 
diff --git a/docs/components/cot-binding.rst b/docs/components/cot-binding.rst
index 4f8c8b7..702bb56 100644
--- a/docs/components/cot-binding.rst
+++ b/docs/components/cot-binding.rst
@@ -67,14 +67,16 @@
         - signing-key
                 Usage:
 
-                This property is used to refer public key node present in
-                parent certificate node and it is required property for all
-                non-root certificates which are authenticated using public-key
-                present in parent certificate.
+                For non-root certificates, this property is used to refer
+                public key node present in parent certificate node and it is
+                required property for all non-root certificates which are
+                authenticated using public-key present in parent certificate.
 
-                This property is not required for root-certificates
-                as root-certificates are validated using root of trust
-                public key provided by platform.
+                This property is not required for all root-certificates. If
+                omitted, the root certificate will be validated using the
+                default platform ROTPK. If instead the root certificate needs
+                validating using a different ROTPK, the signing-key property
+                should provide a reference to the ROTPK node to use.
 
                 Value type: <phandle>
 
@@ -323,10 +325,50 @@
         };
    };
 
+rot_keys node binding definition
+---------------------------------
+
+- rot_keys node
+        Description: Contains root-of-trust keys for the root certificates.
+
+        SUBNODES
+            - Description:
+
+              Root of trust key information present in the root certificates
+              are shown by these nodes.
+
+            - rot key node
+                  Description: Provide ROT key information in the certificate.
+
+                  PROPERTIES
+
+                  - oid
+                     Usage:
+
+                     This property provides the Object ID of ROT key provided
+                     in the certificate.
+
+                     Value type: <string>
+
+Example:
+Below is rot_keys example for CCA platform
+
+.. code:: c
+
+   rot_keys {
+        swd_rot_pk: swd_rot_pk {
+           oid = SWD_ROT_PK_OID;
+        };
+
+        prot_pk: prot_pk {
+           oid = PROT_PK_OID;
+        };
+   };
+
 Future update to chain of trust binding
 ---------------------------------------
 
 This binding document needs to be revisited to generalise some terminologies
 which are currently specific to X.509 certificates for e.g. Object IDs.
 
-*Copyright (c) 2020, Arm Limited. All rights reserved.*
+*Copyright (c) 2020-2024, Arm Limited. All rights reserved.*
diff --git a/docs/glossary.rst b/docs/glossary.rst
index 58b7d99..679de2b 100644
--- a/docs/glossary.rst
+++ b/docs/glossary.rst
@@ -142,6 +142,9 @@
    PSA
       Platform Security Architecture
 
+   PSR
+     Platform Security Requirements
+
    PSCI
       Power State Coordination Interface
 
diff --git a/docs/plat/xilinx-versal-net.rst b/docs/plat/xilinx-versal-net.rst
index 1db7695..3f31d40 100644
--- a/docs/plat/xilinx-versal-net.rst
+++ b/docs/plat/xilinx-versal-net.rst
@@ -40,3 +40,16 @@
 *   `TFA_NO_PM` : Platform Management support.
     -    0 : Enable Platform Management (Default)
     -    1 : Disable Platform Management
+
+*   `CPU_PWRDWN_SGI`: Select the SGI for triggering CPU power down request to
+                      secondary cores on receiving power down callback from
+                      firmware. Options:
+
+    -   `0`   : SGI 0
+    -   `1`   : SGI 1
+    -   `2`   : SGI 2
+    -   `3`   : SGI 3
+    -   `4`   : SGI 4
+    -   `5`   : SGI 5
+    -   `6`   : SGI 6 (Default)
+    -   `7`   : SGI 7
diff --git a/docs/plat/xilinx-versal.rst b/docs/plat/xilinx-versal.rst
index e76b955..aa094f7 100644
--- a/docs/plat/xilinx-versal.rst
+++ b/docs/plat/xilinx-versal.rst
@@ -56,6 +56,19 @@
     -   `spp_itr6`	: SPP ITR6
     -   `emu_itr6`	: EMU ITR6
 
+*   `CPU_PWRDWN_SGI`: Select the SGI for triggering CPU power down request to
+                      secondary cores on receiving power down callback from
+                      firmware. Options:
+
+    -   `0`   : SGI 0
+    -   `1`   : SGI 1
+    -   `2`   : SGI 2
+    -   `3`   : SGI 3
+    -   `4`   : SGI 4
+    -   `5`   : SGI 5
+    -   `6`   : SGI 6 (Default)
+    -   `7`   : SGI 7
+
 # PLM->TF-A Parameter Passing
 ------------------------------
 The PLM populates a data structure with image information for the TF-A. The TF-A
diff --git a/docs/process/security.rst b/docs/process/security.rst
index bbc939a..c49ca6e 100644
--- a/docs/process/security.rst
+++ b/docs/process/security.rst
@@ -73,6 +73,8 @@
 |  |TFV-10| | Incorrect validation of X.509 certificate extensions can result  |
 |           | in an out-of-bounds read                                         |
 +-----------+------------------------------------------------------------------+
+|  |TFV-11| |  A Malformed SDEI SMC can cause out of bound memory read         |
++-----------+------------------------------------------------------------------+
 
 .. _issue tracker: https://developer.trustedfirmware.org/project/board/1/
 .. _mailing list: https://lists.trustedfirmware.org/mailman3/lists/tf-a.lists.trustedfirmware.org/
@@ -87,6 +89,7 @@
 .. |TFV-8| replace:: :ref:`Advisory TFV-8 (CVE-2018-19440)`
 .. |TFV-9| replace:: :ref:`Advisory TFV-9 (CVE-2022-23960)`
 .. |TFV-10| replace:: :ref:`Advisory TFV-10 (CVE-2022-47630)`
+.. |TFV-11| replace:: :ref:`Advisory TFV-11 (CVE-2023-49100)`
 
 .. _TrustedFirmware.org security incident process: https://trusted-firmware-docs.readthedocs.io/en/latest/security_center/
 
diff --git a/docs/resources/diagrams/tf-a_attack_tree.png b/docs/resources/diagrams/tf-a_attack_tree.png
new file mode 100755
index 0000000..0ade8e8
--- /dev/null
+++ b/docs/resources/diagrams/tf-a_attack_tree.png
Binary files differ
diff --git a/docs/resources/diagrams/tf-a_data_flow_diagram.png b/docs/resources/diagrams/tf-a_data_flow_diagram.png
new file mode 100755
index 0000000..f65da01
--- /dev/null
+++ b/docs/resources/diagrams/tf-a_data_flow_diagram.png
Binary files differ
diff --git a/docs/resources/diagrams/tf-a_system_diagram.png b/docs/resources/diagrams/tf-a_system_diagram.png
new file mode 100755
index 0000000..f9bb9e9
--- /dev/null
+++ b/docs/resources/diagrams/tf-a_system_diagram.png
Binary files differ
diff --git a/docs/security_advisories/index.rst b/docs/security_advisories/index.rst
index c9b0f78..ad55546 100644
--- a/docs/security_advisories/index.rst
+++ b/docs/security_advisories/index.rst
@@ -15,3 +15,4 @@
    security-advisory-tfv-8.rst
    security-advisory-tfv-9.rst
    security-advisory-tfv-10.rst
+   security-advisory-tfv-11.rst
diff --git a/docs/security_advisories/security-advisory-tfv-10.rst b/docs/security_advisories/security-advisory-tfv-10.rst
index 91dba07..f53bae1 100644
--- a/docs/security_advisories/security-advisory-tfv-10.rst
+++ b/docs/security_advisories/security-advisory-tfv-10.rst
@@ -98,7 +98,7 @@
 ``drivers/auth/``) require that the certificate's signature has already been
 validated prior to calling ``get_ext()``, or any function that calls ``get_ext()``.
 Platforms taking their chain of trust from a dynamic configuration file (such as
-``fdts/cot_descriptors.dtsi``) are also safe, as signature verification will
+``fdts/tbbr_cot_descriptors.dtsi``) are also safe, as signature verification will
 always be done prior to any calls to ``get_ext()`` or ``auth_nvctr()`` in this
 case, no matter the order of the properties in the file.  Therefore, it is not
 possible to exploit this vulnerability pre-authentication in upstream TF-A.
diff --git a/docs/security_advisories/security-advisory-tfv-11.rst b/docs/security_advisories/security-advisory-tfv-11.rst
new file mode 100644
index 0000000..b5063f0
--- /dev/null
+++ b/docs/security_advisories/security-advisory-tfv-11.rst
@@ -0,0 +1,86 @@
+Advisory TFV-11 (CVE-2023-49100)
+================================
+
++----------------+-------------------------------------------------------------+
+| Title          | A Malformed SDEI SMC can cause out of bound memory read.    |
++================+=============================================================+
+| CVE ID         | `CVE-2023-49100`_                                           |
++----------------+-------------------------------------------------------------+
+| Date           | Reported on 12 Oct 2023                                     |
++----------------+-------------------------------------------------------------+
+| Versions       | TF-A releases v1.5 to v2.9                                  |
+| Affected       | LTS releases  lts-v2.8.0 to lts-v2.8.11                     |
++----------------+-------------------------------------------------------------+
+| Configurations | Platforms with SDEI support                                 |
+| Affected       |                                                             |
++----------------+-------------------------------------------------------------+
+| Impact         | Denial of Service (secure world panic)                      |
++----------------+-------------------------------------------------------------+
+| Fix Version    | `a7eff3477`_ "fix(sdei): ensure that interrupt ID is valid" |
++----------------+-------------------------------------------------------------+
+| Credit         | Christian Lindenmeier `@_chli_`_                            |
+|                | Marcel Busch `@0ddc0de`_                                    |
+|                | `IT Security Infrastructures Lab`_                          |
++----------------+-------------------------------------------------------------+
+
+This security advisory describes a vulnerability in the SDEI services, where a
+rogue Non-secure caller invoking a SDEI_INTERRUPT_BIND SMC call with an invalid
+interrupt ID causes out of bound memory read.
+
+SDEI_INTERRUPT_BIND is used to bind any physical interrupt into a normal
+priority SDEI event. The interrupt can be a private peripheral interrupt
+(PPI) or a shared peripheral interrupt (SPI).
+Refer to SDEI_INTERRUPT_BIND in the `SDEI Specification`_ for further details.
+
+The vulnerability exists when the SDEI client passes an interrupt ID which
+is not implemented by the GIC. This will result in a data abort exception
+or a EL3 panic depending on the GIC version used in the system.
+
+- **GICv2 systems:**
+
+.. code:: c
+
+  Call stack:
+        sdei_interrupt_bind(interrupt ID)
+         -> plat_ic_get_interrupt_type(interrupt ID)
+           -> gicv2_get_interrupt_group(interrupt ID)
+             -> gicd_get_igroupr(distributor base, interrupt ID)
+               -> gicd_read_igroupr(distributor base, interrupt ID).
+
+  gicd_read_igroupr() will eventually do a MMIO read to an unimplemented IGROUPR
+  register. Which may cause a data abort or an access to a random EL3 memory region.
+
+- **GICv3 systems:**
+
+.. code:: c
+
+   Call stack:
+        sdei_interrupt_bind(interrupt ID)
+          -> plat_ic_get_interrupt_type(interrupt ID)
+            -> gicv3_get_interrupt_group(interrupt ID, core ID)
+              -> is_sgi_ppi(interrupt ID)
+
+   is_sgi_ppi() will end up in an EL3 panic on encountering an invalid interrupt ID.
+
+The vulnerability is fixed by ensuring that the Interrupt ID provided by the
+SDEI client is a valid PPI or SPI, otherwise return an error code indicating
+that the parameter is invalid.
+
+.. code:: c
+
+   /* Bind an SDEI event to an interrupt */
+   static int sdei_interrupt_bind(unsigned int intr_num)
+   {
+        sdei_ev_map_t *map;
+        bool retry = true, shared_mapping;
+
+        /* Interrupt must be either PPI or SPI */
+        if (!(plat_ic_is_ppi(intr_num) || plat_ic_is_spi(intr_num)))
+              return SDEI_EINVAL;
+
+.. _CVE-2023-49100: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-49100
+.. _a7eff3477: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/commit/?id=a7eff3477dcf3624c74f5217419b1a27b7ebd2aa
+.. _IT Security Infrastructures Lab: https://www.cs1.tf.fau.de/
+.. _SDEI Specification: https://developer.arm.com/documentation/den0054/latest/
+.. _@_chli_: https://twitter.com/_chli_
+.. _@0ddc0de: https://twitter.com/0ddc0de
diff --git a/docs/threat_model/firmware_threat_model/index.rst b/docs/threat_model/firmware_threat_model/index.rst
new file mode 100644
index 0000000..05b6710
--- /dev/null
+++ b/docs/threat_model/firmware_threat_model/index.rst
@@ -0,0 +1,41 @@
+TF-A Firmware Threat Model
+==========================
+
+As the TF-A codebase is highly configurable to allow tailoring it best for each
+platform's needs, providing a holistic threat model covering all of its features
+is not necessarily the best approach. Instead, we provide a collection of
+documents which, together, form the project's threat model. These are
+articulated around a core document, called the :ref:`Generic Threat Model`,
+which focuses on the most common configuration we expect to see. The other
+documents typically focus on specific features not covered in the core document.
+
+As the TF-A codebase evolves and new features get added, these threat model
+documents will be updated and extended in parallel to reflect at best the
+current status of the code from a security standpoint.
+
+   .. note::
+
+      Although our aim is eventually to provide threat model material for all
+      features within the project, we have not reached that point yet. We expect
+      to gradually fill these gaps over time.
+
+Each of these documents give a description of the target of evaluation using a
+data flow diagram, as well as a list of threats we have identified using the
+`STRIDE threat modeling technique`_ and corresponding mitigations.
+
+.. toctree::
+   :maxdepth: 1
+   :caption: Contents
+
+   threat_model
+   threat_model_el3_spm
+   threat_model_fvp_r
+   threat_model_rss_interface
+   threat_model_arm_cca
+   threat_model_fw_update_and_recovery
+
+--------------
+
+*Copyright (c) 2021-2024, Arm Limited and Contributors. All rights reserved.*
+
+.. _STRIDE threat modeling technique: https://docs.microsoft.com/en-us/azure/security/develop/threat-modeling-tool-threats#stride-model
diff --git a/docs/threat_model/threat_model.rst b/docs/threat_model/firmware_threat_model/threat_model.rst
similarity index 99%
rename from docs/threat_model/threat_model.rst
rename to docs/threat_model/firmware_threat_model/threat_model.rst
index 0da2558..d93547f 100644
--- a/docs/threat_model/threat_model.rst
+++ b/docs/threat_model/firmware_threat_model/threat_model.rst
@@ -42,6 +42,8 @@
 - No experimental features are enabled. We do not consider threats that may come
   from them.
 
+- The platform's hardware complies with the `PSR specification`_, defining the
+  bare-minimum security prerequisites for System-on-Chips (SoC).
 
 Data Flow Diagram
 =================
@@ -53,7 +55,7 @@
 trust boundaries. Components outside of the broken lines
 are considered untrusted by TF-A.
 
-.. uml:: ../resources/diagrams/plantuml/tfa_dfd.puml
+.. uml:: ../../resources/diagrams/plantuml/tfa_dfd.puml
   :caption: Figure 1: TF-A Data Flow Diagram
 
 .. table:: Table 1: TF-A Data Flow Diagram Description
@@ -1088,7 +1090,7 @@
 
 --------------
 
-*Copyright (c) 2021-2023, Arm Limited. All rights reserved.*
+*Copyright (c) 2021-2024, Arm Limited. All rights reserved.*
 
 
 .. _STRIDE threat analysis technique: https://docs.microsoft.com/en-us/azure/security/develop/threat-modeling-tool-threats#stride-model
@@ -1101,3 +1103,4 @@
 .. _Secure Development Guidelines: https://trustedfirmware-a.readthedocs.io/en/latest/process/security-hardening.html#secure-development-guidelines
 .. _Trusted Firmware-A Tests: https://git.trustedfirmware.org/TF-A/tf-a-tests.git/about/
 .. _OP-TEE Dispatcher: https://github.com/ARM-software/arm-trusted-firmware/blob/master/docs/components/spd/optee-dispatcher.rst
+.. _PSR Specification: https://developer.arm.com/documentation/den0106/0100
diff --git a/docs/threat_model/threat_model_arm_cca.rst b/docs/threat_model/firmware_threat_model/threat_model_arm_cca.rst
similarity index 98%
rename from docs/threat_model/threat_model_arm_cca.rst
rename to docs/threat_model/firmware_threat_model/threat_model_arm_cca.rst
index fbf3327..af38ea3 100644
--- a/docs/threat_model/threat_model_arm_cca.rst
+++ b/docs/threat_model/firmware_threat_model/threat_model_arm_cca.rst
@@ -86,7 +86,7 @@
 diagram, the red broken lines indicate trust boundaries. Components outside of
 the broken lines are considered untrusted by TF-A.
 
-.. uml:: ../resources/diagrams/plantuml/tfa_arm_cca_dfd.puml
+.. uml:: ../../resources/diagrams/plantuml/tfa_arm_cca_dfd.puml
   :caption: Figure 1: Data Flow Diagram
 
 .. table:: Table 1: Data Flow Diagram Description
@@ -220,6 +220,6 @@
   | 14 |     Yes     |                                                       |
   +----+-------------+-------------------------------------------------------+
 
-*Copyright (c) 2023, Arm Limited. All rights reserved.*
+*Copyright (c) 2023-2024, Arm Limited. All rights reserved.*
 
 .. _Arm CCA Security Model: https://developer.arm.com/documentation/DEN0096/A_a
diff --git a/docs/threat_model/threat_model_el3_spm.rst b/docs/threat_model/firmware_threat_model/threat_model_el3_spm.rst
similarity index 99%
rename from docs/threat_model/threat_model_el3_spm.rst
rename to docs/threat_model/firmware_threat_model/threat_model_el3_spm.rst
index 8adf3df..a2d6798 100644
--- a/docs/threat_model/threat_model_el3_spm.rst
+++ b/docs/threat_model/firmware_threat_model/threat_model_el3_spm.rst
@@ -37,7 +37,7 @@
 
 Components outside of the broken lines are considered untrusted.
 
-.. uml:: ../resources/diagrams/plantuml/el3_spm_dfd.puml
+.. uml:: ../../resources/diagrams/plantuml/el3_spm_dfd.puml
   :caption: Figure 1: EL3 SPMC Data Flow Diagram
 
 .. table:: Table 1: EL3 SPMC Data Flow Diagram Description
@@ -644,7 +644,7 @@
 
 ---------------
 
-*Copyright (c) 2022-2023, Arm Limited. All rights reserved.*
+*Copyright (c) 2022-2024, Arm Limited. All rights reserved.*
 
 .. _Arm Firmware Framework for Arm A-profile: https://developer.arm.com/docs/den0077/latest
 .. _FF-A ACS: https://github.com/ARM-software/ff-a-acs/releases
diff --git a/docs/threat_model/threat_model_fvp_r.rst b/docs/threat_model/firmware_threat_model/threat_model_fvp_r.rst
similarity index 98%
rename from docs/threat_model/threat_model_fvp_r.rst
rename to docs/threat_model/firmware_threat_model/threat_model_fvp_r.rst
index 725eeed..0b71bf0 100644
--- a/docs/threat_model/threat_model_fvp_r.rst
+++ b/docs/threat_model/firmware_threat_model/threat_model_fvp_r.rst
@@ -96,4 +96,4 @@
 
 --------------
 
-*Copyright (c) 2021-2023, Arm Limited. All rights reserved.*
+*Copyright (c) 2021-2024, Arm Limited. All rights reserved.*
diff --git a/docs/threat_model/firmware_threat_model/threat_model_fw_update_and_recovery.rst b/docs/threat_model/firmware_threat_model/threat_model_fw_update_and_recovery.rst
new file mode 100644
index 0000000..7b55c74
--- /dev/null
+++ b/docs/threat_model/firmware_threat_model/threat_model_fw_update_and_recovery.rst
@@ -0,0 +1,103 @@
+Threat Model for TF-A with PSA FWU or TBBR FWU support
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Introduction
+************
+
+This document provides a threat model of TF-A firmware for platforms with
+the feature PSA firmware update or TBBR firmware update or both enabled.
+To understand the design of the firmware update refer
+:ref:`Firmware Update (FWU)`.
+
+Although it is a separate document, it references the :ref:`Generic Threat
+Model` in a number of places, as some of the contents are applicable to this
+threat model.
+
+Target of Evaluation
+********************
+
+In this threat model, the target of evaluation is the Trusted Firmware for
+A-class Processors (TF-A) when PSA FWU support is enabled or TBBR FWU mode
+is enabled. This includes the boot ROM (BL1), the trusted boot firmware (BL2).
+
+Threat Assessment
+*****************
+
+For this section, please reference the Threat Assessment under the
+:ref:`Generic Threat Model`. Here only the differences are highlighted.
+
+PSA FWU
+*******
+
+Threats to be Mitigated by the Boot Firmware
+--------------------------------------------
+
+The following table analyses the :ref:`Boot Firmware Threats` in the context
+of this threat model. Only additional details are pointed out.
+
++----+-------------+-------------------------------------------------------+
+| ID | Applicable? | Comments                                              |
++====+=============+=======================================================+
+| 01 |     Yes     | | Attacker can use arbitrary images to update the     |
+|    |             |   system.                                             |
++----+-------------+-------------------------------------------------------+
+| 02 |     Yes     | | Attacker tries to update the system with the        |
+|    |             |   vulnerable/older firmware.                          |
++----+-------------+-------------------------------------------------------+
+| 03 |     Yes     |                                                       |
++----+-------------+-------------------------------------------------------+
+| 04 |     Yes     |                                                       |
++----+-------------+-------------------------------------------------------+
+
+
+Threats to be mitigated by platform design
+------------------------------------------
+
+PSA FWU is driven by metadata stored in non-volatile storage. This metadata
+is not cryptographically signed. Also, depending on the hardware design,
+it may be stored in untrusted storage, which makes it possible for software
+outside of TF-A security boundary or for a physical attacker to modify it
+in order to change the behaviour of the FWU process.
+
+Below we provide some possible FWU metadata corruption scenarios:
+
+1. The FWU metadata includes the firmware bank for booting; the attacker
+   tries to modify it to prevent the execution of the updated firmware.
+2. The FWU metadata features a field indicating the firmware's status, either
+   in trial run or accepted run. The attacker tries to manipulate this field,
+   ensuring the updated firmware consistently runs in trial mode, with the
+   intention of preventing the anti-rollback update.
+
+By design, no software mitigations exist to prevent this. The safeguarding
+of FWU metadata relies on the platform's hardware design to mitigate potential
+attacks on it, if this is a concern in the platform's threat model.
+For example, FWU metadata may be stored in secure storage under exclusive
+access from secure software, protecting it from physical, unauthenticated
+accesses and from non-secure software accesses.
+
+TBBR FWU - Firmware Recovery
+****************************
+
+Threats to be Mitigated by the Boot Firmware
+--------------------------------------------
+
+The following table analyses the :ref:`Boot Firmware Threats` in the context
+of this threat model. Only additional details are pointed out.
+
++----+-------------+-------------------------------------------------------+
+| ID | Applicable? | Comments                                              |
++====+=============+=======================================================+
+| 01 |     Yes     | | Attacker can use arbitrary images to recover the    |
+|    |             |   system.                                             |
++----+-------------+-------------------------------------------------------+
+| 02 |     Yes     | | Attacker tries to recover the system with the       |
+|    |             |   vulnerable/older firmware.                          |
++----+-------------+-------------------------------------------------------+
+| 03 |     Yes     |                                                       |
++----+-------------+-------------------------------------------------------+
+| 04 |     Yes     |                                                       |
++----+-------------+-------------------------------------------------------+
+
+--------------
+
+*Copyright (c) 2024, Arm Limited. All rights reserved.*
diff --git a/docs/threat_model/threat_model_rss_interface.rst b/docs/threat_model/firmware_threat_model/threat_model_rss_interface.rst
similarity index 95%
rename from docs/threat_model/threat_model_rss_interface.rst
rename to docs/threat_model/firmware_threat_model/threat_model_rss_interface.rst
index 4bceb63..025d2d9 100644
--- a/docs/threat_model/threat_model_rss_interface.rst
+++ b/docs/threat_model/firmware_threat_model/threat_model_rss_interface.rst
@@ -24,7 +24,7 @@
 cores. The interface description only focuses on the AP-RSS interface the rest
 is the same as in the general TF-A threat-model document.
 
-.. uml:: ../resources/diagrams/plantuml/tfa_rss_dfd.puml
+.. uml:: ../../resources/diagrams/plantuml/tfa_rss_dfd.puml
   :caption: Figure 1: TF-A Data Flow Diagram including RSS
 
 .. table:: Table 1: TF-A - RSS data flow diagram
@@ -56,4 +56,4 @@
 
 --------------
 
-*Copyright (c) 2022, Arm Limited. All rights reserved.*
\ No newline at end of file
+*Copyright (c) 2022-2024, Arm Limited. All rights reserved.*
diff --git a/docs/threat_model/index.rst b/docs/threat_model/index.rst
index e22378b..446e610 100644
--- a/docs/threat_model/index.rst
+++ b/docs/threat_model/index.rst
@@ -4,40 +4,14 @@
 Threat modeling is an important part of Secure Development Lifecycle (SDL)
 that helps us identify potential threats and mitigations affecting a system.
 
-As the TF-A codebase is highly configurable to allow tailoring it best for each
-platform's needs, providing a holistic threat model covering all of its features
-is not necessarily the best approach. Instead, we provide a collection of
-documents which, together, form the project's threat model. These are
-articulated around a core document, called the :ref:`Generic Threat Model`,
-which focuses on the most common configuration we expect to see. The other
-documents typically focus on specific features not covered in the core document.
-
-As the TF-A codebase evolves and new features get added, these threat model
-documents will be updated and extended in parallel to reflect at best the
-current status of the code from a security standpoint.
-
-   .. note::
-
-      Although our aim is eventually to provide threat model material for all
-      features within the project, we have not reached that point yet. We expect
-      to gradually fill these gaps over time.
-
-Each of these documents give a description of the target of evaluation using a
-data flow diagram, as well as a list of threats we have identified using the
-`STRIDE threat modeling technique`_ and corresponding mitigations.
 
 .. toctree::
    :maxdepth: 1
    :caption: Contents
 
-   threat_model
-   threat_model_el3_spm
-   threat_model_fvp_r
-   threat_model_rss_interface
-   threat_model_arm_cca
+   firmware_threat_model/index
+   supply_chain_threat_model
 
 --------------
 
-*Copyright (c) 2021-2023, Arm Limited and Contributors. All rights reserved.*
-
-.. _STRIDE threat modeling technique: https://docs.microsoft.com/en-us/azure/security/develop/threat-modeling-tool-threats#stride-model
+*Copyright (c) 2021-2024, Arm Limited and Contributors. All rights reserved.*
diff --git a/docs/threat_model/supply_chain_threat_model.rst b/docs/threat_model/supply_chain_threat_model.rst
new file mode 100644
index 0000000..386a4b0
--- /dev/null
+++ b/docs/threat_model/supply_chain_threat_model.rst
@@ -0,0 +1,760 @@
+TF-A Supply Chain Threat Model
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Introduction
+************
+
+Software supply chain attacks aim to inject malicious code into a software
+product. There are several ways a malicious code can be injected into a
+software product (open-source project). These include:
+
+- Malicious code commits: This attack directly injects code into a project
+  repository. This can happen for example through developer/maintainer
+  credential hijacks, or malicious external contributors.
+
+- Malicious dependencies:  In this case malicious code is introduced into a
+  project through other piece of code or packages the project depends on. This
+  can happen through for example typosquatting attack where an attacker creates
+  a malicious package with a very similar name to a popular package and hosts
+  it on popular package repositories.
+
+- Malicious toolchains:  This involves malicious code introduced by compromised
+  resources used throughout the development and/or build process such as
+  compilers and IDEs.
+
+This document provides analysis of software supply chain attack threats for the
+TF-A project.
+
+TF-A Overview
+*************
+
+Figure 1 shows the different software components surrounding the TF-A project.
+A brief description of each component is provided below.
+
+TF-A Repository
+===============
+
+The TF-A repository contains generic and platform code contributed by TF-A
+contributors as well as libraries imported from other open-source projects,
+referred to as internal dependencies on Figure 1. These libraries include:
+
+- *libfdt*: libfdt is a utility library for reading and manipulating Device
+  Tree Binary (DTB) files. It is part of the Device Tree Compiler (DTC)
+  toolchain [1]_. DTC is used as part of the build process on the host machine
+  to build DTB files. libfdt is used to parse the DTB files at boot time.
+
+- *zlib*: zlib is a data compression library imported from [2]_.
+
+- *compiler-rt*: This is a collection of runtime libraries from the LLVM
+  compiler infrastructure project [3]_. We import the builtins library which
+  provides low-level, target-specific compiler builtins from compiler-rt.
+
+The TF-A repository also includes source code for host tools that supplement
+the TF-A build process. These tools include:
+
+- *fiptool*: This tool is used to create a Firmware Image Package (FIP) which
+  allows for packing bootloader images into a single archive that can be
+  loaded by TF-A from non-volatile platform storage.
+
+- *cert_create*: This tool is used to generate certificates for binary images.
+
+- *encrypt_fw*: This tool takes the plain firmware image as input and generates
+  the encrypted firmware image which can then be passed as input to the fiptool
+  utility for creating the FIP.
+
+- *sptool*: This tool is used to build the secure partition packages.
+
+|TF-A System Diagram|
+*Figure 1: TF-A System Diagram*
+
+External Dependencies
+=====================
+
+These are software components that are not part of the TF-A repository but are
+required to build TF-A binaries and host tools.
+
+- *Mbed TLS Library*: This is a cryptography library from trustedfirmware.org
+  (tf.org). It is required to build TF-A binaries where cryptography features
+  are needed, such as Trusted Board Boot (TBB).
+
+- *OpenSSL Library*: This is another cryptography library used by TF-A host
+  tools: fiptool, cert_create, and encrypt_fw.
+
+The following table lists TF-A dependencies including the sources of the
+dependencies.
+
+.. table:: Table 1: TF-A Dependencies
+
+  +-------------+------------------------+------------------------------------+
+  | Dependency  | Location of Dependency | Original Source                    |
+  +=============+========================+====================================+
+  | libfdt      | Local copy             | [1]_                               |
+  +-------------+------------------------+------------------------------------+
+  | zlib        | Local copy             | [2]_                               |
+  +-------------+------------------------+------------------------------------+
+  | compiler-rt | Local copy             | [3]_                               |
+  +-------------+------------------------+------------------------------------+
+  | Mbed TLS    | External               | [4]_                               |
+  +-------------+------------------------+------------------------------------+
+  | OpenSSL     | External               | [5]_                               |
+  +-------------+------------------------+------------------------------------+
+
+Supplementary Binaries
+======================
+
+These are binaries used to test TF-A based systems. Below is a brief
+description of each component and where they are sourced from.
+
+- *SCP-firmware*: For our tests, we use SCP-firmware binaries supplied by the
+  Arm SCP team built from the source from the GitHub repository [6]_.
+
+- *OP-TEE*: Trusted Execution Environment (TEE) from tf.org that runs as
+  Secure EL1. We use OP-TEE built from source or binaries supplied with Arm
+  Reference Platforms depending on the test configuration.
+
+- *EDK2 UEFI*: Normal world bootloader from the EDK2 project [7]_. We use EDK2
+  UEFI binaries hosted on tf.org servers for testing [8]_.
+
+Other software components used to test TF-A include U-Boot, Linux kernel, RSS,
+MCP, and file systems, all sourced from the Arm Reference Platforms teams.
+
+TF-A Toolchain
+==============
+
+The TF-A project uses several tools to build, analyze and test the TF-A source
+code.
+
+Node.js Tools
+-------------
+
+These are optional quality assurance and developer utility tools that are
+installed through the use of the Node.js package manager. They are pinned to
+specific versions described by the package.json file in the root of the TF-A
+repository, and their dependencies are downloaded from the internet at the
+point of installation. These tools may be installed locally on the developer
+machine and are installed within a Docker container in certain CI jobs. At
+present, these are:
+
+- Commitlint
+
+- Commitizen
+
+- Husky
+
+Infrastructure
+==============
+
+TF-A uses trustedfirmware.org (tf.org) and Arm infrastructures to host the
+source code, review code and run tests. Appendix A provides a security analysis
+of tf.org infrastructure.
+
+TF-A Data Flow
+**************
+
+Figure 2 below shows the data flow diagram for TF-A. The broken red lines
+indicate trust boundaries.
+
+|TF-A Data Flow Diagram|
+*Figure 2: TF-A Data Flow Diagram*
+
+Attack Tree
+***********
+
+|TF-A Attack Tree|
+*Figure 3: TF-A Attack Tree*
+
+Threat Assessment and Mitigations
+*********************************
+
+Impact and Likelihood Ratings
+=============================
+
+  +--------+------------------------------+-----------------------------------+
+  | Rating | Impact                       | Likelihood                        |
+  +========+==============================+===================================+
+  | HIGH   | Major impact to entire       | Threat is relatively easy to      |
+  |        | organization or single line  | exploit by an attacker with       |
+  |        | of business if exploited.    | little effort and skill.          |
+  +--------+------------------------------+-----------------------------------+
+  | MEDIUM | Noticeable impact to line of | An expert attacker could exploit  |
+  |        | business if exploited.       | the threat without much           |
+  |        |                              | difficulty.                       |
+  +--------+------------------------------+-----------------------------------+
+  | LOW    | Minor damage if exploited or | Exploiting the threat would       |
+  |        | could be used in conjunction | require considerable effort and   |
+  |        | with other vulnerabilities   | resources.                        |
+  |        | to perform a more serious    |                                   |
+  |        | attack.                      |                                   |
+  +--------+------------------------------+-----------------------------------+
+
+Threats and Mitigations
+=======================
+
+Threat naming convention key
+
+- SC – Supply Chain
+
+- SRC – Source
+
+- DEP – Dependency
+
+- TOOL – Toolchain
+
+- REPO – Repository
+
+- MAIN – Maintainer
+
+- CONT – Contributor
+
+  +---------------------------------------------------------------------------+
+  | Threat: TFA-SC-SRC-MAIN-01                                                |
+  +=============+=============================================================+
+  | Description | An attacker can submit and merge malicious code by posing   |
+  |             | as a maintainer after compromising maintainers’             |
+  |             | credentials.                                                |
+  +-------------+-------------------------------------------------------------+
+  | Impact      | HIGH                                                        |
+  +-------------+-------------------------------------------------------------+
+  | Likelihood  | MEDIUM                                                      |
+  +-------------+-------------------------------------------------------------+
+  | Threat and  | | In the TF-A code review process all submitted changes     |
+  | impact      |   undergo review by a code owner and a maintainer. If the   |
+  |             |   change is accepted, it will be merged (integrated) into   |
+  |             |   an integration branch by a maintainer. A maintainer has   |
+  |             |   the right to give a code owner review, a maintainer       |
+  |             |   review and merge the submitted change.                    |
+  |             |                                                             |
+  |             | | tf.org users (including maintainers) are authenticated    |
+  |             |   through GitHub. The likelihood of a credential compromise |
+  |             |   depends on multiple factors. The authentication mechanism |
+  |             |   of GitHub is strong if the recommended best practices are |
+  |             |   followed [9]_ making credential compromise unlikely.      |
+  |             |   GitHub (therefore tf.org) allows logins with two-factor   |
+  |             |   authentication, requiring both a password and access to   |
+  |             |   the user's authentication code. Depending on the strength |
+  |             |   of the password and factors such as whether the           |
+  |             |   maintainer reuses passwords across services, the          |
+  |             |   likelihood of a compromise can be higher.                 |
+  |             |                                                             |
+  |             | | If an attacker manages to compromise a maintainer’s       |
+  |             |   credentials, posing as the maintainer, they can in theory |
+  |             |   submit a malicious change (as a maintainer or as a        |
+  |             |   contributor), give all the necessary reviews and merge    |
+  |             |   the change.                                               |
+  +-------------+-------------------------------------------------------------+
+  | Mitigations | | - Enforce best practices recommended by GitHub [9]_       |
+  |             |                                                             |
+  |             | | - Not allowing a committer to both self-review and merge  |
+  |             |     patches they have submitted. To achieve the commit the  |
+  |             |     attacker would be required to compromise at least two   |
+  |             |     credentials (reviewers and maintainer).                 |
+  +-------------+-------------------------------------------------------------+
+  | Mitigations | We have not disallowed self-review/merge of patches         |
+  | implemented?|                                                             |
+  +-------------+-------------------------------------------------------------+
+
+  +---------------------------------------------------------------------------+
+  | Threat: TFA-SC-SRC-MAIN-02                                                |
+  +=============+=============================================================+
+  | Description | An attacker can submit and merge malicious code after       |
+  |             | becoming a maintainer through social engineering            |
+  |             | techniques.                                                 |
+  +-------------+-------------------------------------------------------------+
+  | Impact      | HIGH                                                        |
+  +-------------+-------------------------------------------------------------+
+  | Likelihood  | LOW                                                         |
+  +-------------+-------------------------------------------------------------+
+  | Threat and  | | According to the TF project maintenance process [10]_,    |
+  | impact      |   maintainers of TF-A are selected by their peers based on  |
+  |             |   merit. Some of the criteria of becoming a maintainer      |
+  |             |   include being an active member of the project for a       |
+  |             |   minimum duration and contributing a substantial number of |
+  |             |   non-trivial and high-quality patches. However, there are  |
+  |             |   some weaknesses in the process:                           |
+  |             |                                                             |
+  |             | | - There is no structured mechanism to establish trust     |
+  |             |     with a maintainer other than the recommendations by     |
+  |             |     peers                                                   |
+  |             | | - There is no continuous monitoring of the status of a    |
+  |             |     maintainer (e.g. maintainer can move from one           |
+  |             |     organization to another)                                |
+  |             |                                                             |
+  |             | | To perform such an attack, in addition to becoming a      |
+  |             |   maintainer, an attacker also must deal with all           |
+  |             |   restrictions put on maintainers.                          |
+  +-------------+-------------------------------------------------------------+
+  | Mitigations | | - Structured mechanism to establish trust with            |
+  |             |     maintainers                                             |
+  |             |                                                             |
+  |             | | - Not allowing a committer to both self-review and merge  |
+  |             |     patches they have submitted. To achieve the commit the  |
+  |             |     attacker would be required to compromise at least two   |
+  |             |     credentials (reviewers and maintainer).                 |
+  +-------------+-------------------------------------------------------------+
+  | Mitigations | There is a structured mechanism to establish trust with     |
+  | implemented?| maintainers, but self-review/merge of patches is not        |
+  |             | disallowed                                                  |
+  +-------------+-------------------------------------------------------------+
+
+  +---------------------------------------------------------------------------+
+  | Threat: TFA-SC-SRC-CONT-01                                                |
+  +=============+=============================================================+
+  | Description | An attacker can submit malicious code patch as a            |
+  |             | contributor.                                                |
+  +-------------+-------------------------------------------------------------+
+  | Impact      | HIGH                                                        |
+  +-------------+-------------------------------------------------------------+
+  | Likelihood  | LOW                                                         |
+  +-------------+-------------------------------------------------------------+
+  | Threat and  | | TF-A accepts external contributions to both the generic   |
+  | impact      |   and platform code. Unlike maintainers, contributors do    |
+  |             |   not have maintainer review or merging privileges,         |
+  |             |   therefore the likelihood of injecting malicious code as a |
+  |             |   contributor is lower. However, even though unlikely, it   |
+  |             |   is still possible for a malicious commit to go unnoticed  |
+  |             |   through the code review and verification processes.       |
+  |             |                                                             |
+  |             | | If successful, the impact can range from low to high      |
+  |             |   depending on the injected code. For example, an attacker  |
+  |             |   can potentially deliberately insert a memory corruption   |
+  |             |   vulnerability that is hard to notice on code review and   |
+  |             |   will not be detected by the verification process. This    |
+  |             |   vulnerability by itself may have a low impact but can     |
+  |             |   have a major impact if used in combination with other     |
+  |             |   vulnerabilities.                                          |
+  +-------------+-------------------------------------------------------------+
+  | Proposed    | - Code review and verification                              |
+  | Mitigations | - Static analysis to try to pick up issues that typically   |
+  |             |   end in some form of attack vector                         |
+  +-------------+-------------------------------------------------------------+
+  | Mitigations | Yes, contributions go through the thorough review,          |
+  | implemented?| verification, and static analysis process automated through |
+  |             | CI                                                          |
+  +-------------+-------------------------------------------------------------+
+
+  +---------------------------------------------------------------------------+
+  | Threat: TFA-SC-DEP-01                                                     |
+  +=============+=============================================================+
+  | Description | An attacker can inject malicious code into TF-A internal    |
+  |             | dependencies.                                               |
+  +-------------+-------------------------------------------------------------+
+  | Impact      | HIGH                                                        |
+  +-------------+-------------------------------------------------------------+
+  | Likelihood  | LOW                                                         |
+  +-------------+-------------------------------------------------------------+
+  | Threat and  | | TF-A has two types of dependencies: those that are copied |
+  | impact      |   into the TF-A repository and shipped as part of TF-A code |
+  |             |   (referred to as *internal dependencies* here) and those   |
+  |             |   that are downloaded from external repositories and used   |
+  |             |   when building TF-A (referred to as                        |
+  |             |   *external dependencies* here).                            |
+  |             |                                                             |
+  |             | | Currently TF-A has three internal dependencies: *libfdt*  |
+  |             |   [1]_, *zlib* [2]_ and *compiler-rt* [3]_ libraries. These |
+  |             |   libraries are periodically updated by copying them from   |
+  |             |   their source repositories. Although unlikely, it is       |
+  |             |   possible for a contributor to copy the libraries from the |
+  |             |   wrong (and potentially malicious) repositories. For       |
+  |             |   example, there are already multiple forks of *libfdt*     |
+  |             |   (DTC) on GitHub. In addition to this, the official        |
+  |             |   repositories are not immune to threats described above    |
+  |             |   (TFA-SC-SRC-MAIN-01, TFA-SC-SRC-MAIN-02 and               |
+  |             |   TFA-SC-SRC-CONT-01).                                      |
+  |             |                                                             |
+  |             | | The likelihood of an attack on TF-A through internal      |
+  |             |   dependencies is lower than external dependencies for the  |
+  |             |   following reasons:                                        |
+  |             |                                                             |
+  |             | | - Internal dependencies go through the normal code review |
+  |             |     process during upgrade                                  |
+  |             | | - Once upgraded internal dependencies stay unchanged      |
+  |             |     until the next upgrade. The upgrade window is typically |
+  |             |     long (for example *libfdt* has only changed 4 times     |
+  |             |     over the past 4 years). This reduces the window of      |
+  |             |     opportunity for an attacker to inject malicious code    |
+  |             |     into the dependencies                                   |
+  +-------------+-------------------------------------------------------------+
+  | Proposed    | - Explicitly document versions and official sources of      |
+  | Mitigations |   dependencies                                              |
+  |             | - Keep a copy of a pinned version of the source code inside |
+  |             |   the TF-A tree so that the risk of getting malicious code  |
+  |             |   from dependencies only arises when we upgrade them        |
+  |             | - Monitor alerts for vulnerable dependencies from GitHub    |
+  |             |   [11]_                                                     |
+  +-------------+-------------------------------------------------------------+
+  | Mitigations | Yes, we explicitly document versions and official sources   |
+  | implemented?| of dependencies, keep a copy of pinned versions of the      |
+  |             | source code, and monitor alerts for vulnerable dependencies |
+  |             | for Python and Node.js, but we aren't able to do this for C |
+  |             | dependencies                                                |
+  +-------------+-------------------------------------------------------------+
+
+  +---------------------------------------------------------------------------+
+  | Threat: TFA-SC-DEP-02                                                     |
+  +=============+=============================================================+
+  | Description | An attacker can inject malicious code into TF-A external    |
+  |             | dependencies.                                               |
+  +-------------+-------------------------------------------------------------+
+  | Impact      | HIGH                                                        |
+  +-------------+-------------------------------------------------------------+
+  | Likelihood  | MEDIUM                                                      |
+  +-------------+-------------------------------------------------------------+
+  | Threat and  | | Unlike internal dependencies, external dependencies are   |
+  | impact      |   downloaded from external repositories by end-users.       |
+  |             |   Although the TF-A documentation provides information      |
+  |             |   about the versions of dependencies used for testing and   |
+  |             |   links to repositories, it is up to the end-user to decide |
+  |             |   where to get the dependencies from. As such, the          |
+  |             |   likelihood of an attack through an external dependency is |
+  |             |   higher compared to an internal dependency.                |
+  |             |                                                             |
+  |             | | The impact of an attack ranges from low to critical       |
+  |             |   depending on which dependency and what part of the        |
+  |             |   dependency is affected. For example, a malicious code     |
+  |             |   that affects the signature verification functions in      |
+  |             |   MbedTLS is considered critical as it can be used to       |
+  |             |   bypass the TBB process of TF-A.                           |
+  +-------------+-------------------------------------------------------------+
+  | Proposed    | - Explicitly document versions and official sources of      |
+  | Mitigations |   dependencies                                              |
+  |             | - Provide scripts and build options to automatically fetch  |
+  |             |   the latest stable release of external dependencies        |
+  +-------------+-------------------------------------------------------------+
+  | Mitigations | We explicitly document versions and official sources of     |
+  | implemented?| dependencies, but do not yet provide scripts and build      |
+  |             | options to automatically fetch the latest stable release of |
+  |             | external dependencies                                       |
+  +-------------+-------------------------------------------------------------+
+
+  +---------------------------------------------------------------------------+
+  | Threat: TFA-SC-REPO-01                                                    |
+  +=============+=============================================================+
+  | Description | An attacker can upload malicious versions of TF-A by        |
+  |             | compromising credentials of administrator accounts on       |
+  |             | tf.org or GitHub.                                           |
+  +-------------+-------------------------------------------------------------+
+  | Impact      | HIGH                                                        |
+  +-------------+-------------------------------------------------------------+
+  | Likelihood  | LOW                                                         |
+  +-------------+-------------------------------------------------------------+
+  | Threat and  | | This attack is like TFA-SC-SRC-MAIN-01, but the           |
+  | impact      |   likelihood and impact of the two attacks are different.   |
+  |             |                                                             |
+  |             | | The likelihood of compromising administrator credentials  |
+  |             |   is lower than that of a maintainer’s (assuming both use   |
+  |             |   authentication methods of similar strength) as there are  |
+  |             |   smaller number of administrators than maintainers. On the |
+  |             |   other hand, the impact is higher since an administrator   |
+  |             |   has more privileges than a maintainer:                    |
+  |             |                                                             |
+  |             | | - An administrator can upload a malicious TF-A            |
+  |             |     contribution unnoticed by other reviewers               |
+  |             |   - An administrator can potentially rewrite the history of |
+  |             |     the repository to evade detection                       |
+  +-------------+-------------------------------------------------------------+
+  | Proposed    | Strong authentication (Follow best practices recommended by |
+  | Mitigations | GitHub [9]_)                                                |
+  +-------------+-------------------------------------------------------------+
+  | Mitigations | Yes, strong authentication is implemented through           |
+  | implemented?| recommended best practices                                  |
+  +-------------+-------------------------------------------------------------+
+
+  +---------------------------------------------------------------------------+
+  | Threat: TFA-SC-REPO-02                                                    |
+  +=============+=============================================================+
+  | Description | An attacker can upload malicious versions of TF-A after     |
+  |             | getting write access to the repository by exploiting a      |
+  |             | vulnerability on tf.org or GitHub.                          |
+  +-------------+-------------------------------------------------------------+
+  | Impact      | HIGH                                                        |
+  +-------------+-------------------------------------------------------------+
+  | Likelihood  | LOW                                                         |
+  +-------------+-------------------------------------------------------------+
+  | Threat and  | | There are no reports of someone exploiting a              |
+  | impact      |   vulnerability on GitHub or tf.org to upload malicious     |
+  |             |   contributions. However, there are examples of             |
+  |             |   vulnerabilities that allowed arbitrary code execution on  |
+  |             |   popular hosting services [12]_. Such vulnerabilities can  |
+  |             |   potentially be used to upload malicious packages. In      |
+  |             |   addition to being hard to exploit, vulnerabilities on     |
+  |             |   popular hosting sites such as GitHub are typically        |
+  |             |   detected quickly, making the window of opportunity for    |
+  |             |   such attack small.                                        |
+  +-------------+-------------------------------------------------------------+
+  | Proposed    | - Monitor alerts of any vulnerabilities that might affect   |
+  | Mitigations |   TF-A repository                                           |
+  |             | - Ensure tf.org is up to date with latest security patches  |
+  +-------------+-------------------------------------------------------------+
+  | Mitigations | Yes, alerts of vulnerabilities are monitored and tf.org is  |
+  | implemented?| ensured to be up to date with the latest security patches   |
+  +-------------+-------------------------------------------------------------+
+
+  +---------------------------------------------------------------------------+
+  | Threat: TFA-SC-REPO-03                                                    |
+  +=============+=============================================================+
+  | Description | An attacker can host a malicious version of TF-A on an      |
+  |             | attacker-controlled repository, and trick end-users into    |
+  |             | downloading from that repository.                           |
+  +-------------+-------------------------------------------------------------+
+  | Impact      | HIGH                                                        |
+  +-------------+-------------------------------------------------------------+
+  | Likelihood  | MEDIUM                                                      |
+  +-------------+-------------------------------------------------------------+
+  | Threat and  | | It is not difficult for an attacker to create a website   |
+  | impact      |   with a similar domain name and look as tf.org (website    |
+  |             |   spoofing) and host a malicious TF-A source repository.    |
+  |             |   Similarly, an attacker can create a mirror of the TF-A    |
+  |             |   repository on GitHub with malicious code in it. However,  |
+  |             |   for this attack to succeed the attacker needs to trick    |
+  |             |   the end-user into using the attacker-controlled           |
+  |             |   repositories.                                             |
+  +-------------+-------------------------------------------------------------+
+  | Proposed    | - Users should carefully check the URL of the website       |
+  | Mitigations |   before visiting it and the URL of the repository before   |
+  |             |   checking it out                                           |
+  |             | - Accept reports of spoofing attacks on tf.org and          |
+  |             |   broadcast a warning to partners                           |
+  +-------------+-------------------------------------------------------------+
+  | Mitigations | We accept reports of spoofing attacks on tf.org and will    |
+  | implemented?| broadcast a warning to partners                             |
+  +-------------+-------------------------------------------------------------+
+
+  +---------------------------------------------------------------------------+
+  | Threat: TFA-SC-TOOL-01                                                    |
+  +=============+=============================================================+
+  | Description | Malicious code can be injected at build time through        |
+  |             | malicious tools.                                            |
+  +-------------+-------------------------------------------------------------+
+  | Impact      | HIGH                                                        |
+  +-------------+-------------------------------------------------------------+
+  | Likelihood  | LOW                                                         |
+  +-------------+-------------------------------------------------------------+
+  | Threat and  | | End-users of TF-A use make (or cmake), compilers and      |
+  | impact      |   linkers (armgcc, armclang or LLVM) to build TF-A          |
+  |             |   binaries. Although TF-A documentation specifies versions  |
+  |             |   and official sources of tools used to build TF-A, users   |
+  |             |   can potentially be tricked into using unofficial,         |
+  |             |   malicious toolchains. Similar attacks have been used in   |
+  |             |   the past to inject malicious code into final products     |
+  |             |   [13]_.                                                    |
+  +-------------+-------------------------------------------------------------+
+  | Proposed    | - Explicitly document versions and official sources of      |
+  | Mitigations |   toolchains                                                |
+  |             | - Provide scripts to automatically fetch the latest stable  |
+  |             |   release of toolchains                                     |
+  +-------------+-------------------------------------------------------------+
+  | Mitigations | We explicitly document versions and official sources of     |
+  | implemented?| toolchains, but have not yet provided scripts to            |
+  |             | automatically fetch the latest stable release of toolchains |
+  +-------------+-------------------------------------------------------------+
+
+  +---------------------------------------------------------------------------+
+  | Threat: TFA-SC-TOOL-02                                                    |
+  +=============+=============================================================+
+  | Description | Malicious code can be executed by developer’s tools at      |
+  |             | installation time through malicious Node.js dependencies.   |
+  +-------------+-------------------------------------------------------------+
+  | Impact      | HIGH                                                        |
+  +-------------+-------------------------------------------------------------+
+  | Likelihood  | LOW                                                         |
+  +-------------+-------------------------------------------------------------+
+  | Threat and  | | Users of the Node.js tools, including the CI, may be      |
+  | impact      |   exposed to malicious dependencies that have been missed   |
+  |             |   by the Node.js dependency auditor. Users of these tools   |
+  |             |   could potentially be executing malicious code when using  |
+  |             |   these tools, which could potentially allow a malicious    |
+  |             |   actor to make silent modifications to the repository or   |
+  |             |   enable retrieval of user credentials.                     |
+  |             |                                                             |
+  |             | | If successful, the impact can range from low to high      |
+  |             |   depending on the user's credentials. If the user is an    |
+  |             |   administrator, this could imply TFA-SC-REPO-01.           |
+  +-------------+-------------------------------------------------------------+
+  | Proposed    | - Limit Node.js tools to a minimal set of trusted packages  |
+  | Mitigations | - Pin Node.js packages to known versions                    |
+  |             | - Update dependencies for which Node.js’s auditor reports   |
+  |             |   known CVEs                                                |
+  |             | - Execute Node.js tools in the CI only from within a        |
+  |             |   trusted container                                         |
+  +-------------+-------------------------------------------------------------+
+  | Mitigations | Yes, Node.js tools are limited to a minimal set of trusted  |
+  | implemented?| packages, packages are pinned to known versions,            |
+  |             | dependencies are updated when there are known CVEs          |
+  |             | reported, and Node.js tools are only executed within a      |
+  |             | trusted container in CI                                     |
+  +-------------+-------------------------------------------------------------+
+
+Appendix A
+**********
+
+Summary of trustedfirmware.org security:
+
+.. table:: Table 2: Security information of  trustedfirmware.org
+
+  +------------+--------------------+--------------------+--------------------+
+  | Software/  | Source and         | Credential and     | Security incident  |
+  | System     | integrity          | permission         | response plan      |
+  |            |                    | management         |                    |
+  +============+====================+====================+====================+
+  | Jenkins    | - Jenkins is built | - Use oauth from   | - Monitor CVE’s    |
+  | (including |   using Dockerfile |   Github only      |   and update       |
+  | plugins)   |   which is based   | - The password     |   Jenkins LTS on a |
+  |            |   on the official  |   strength follows |   monthly cycle    |
+  |            |   Jenkins docker   |   Github policy    | - Keep plugins up- |
+  |            |   image            | - Do not enforce   |   to-date. But it  |
+  |            | - Jenkins plugins  |   using two-factor |   is up to the     |
+  |            |   are built using  |   authentication   |   plugin owner to  |
+  |            |   the official     | - Jenkins uses     |   maintain said    |
+  |            |   install-         |   matrix auth      |   plugin           |
+  |            |   plugins.sh       |   which allows     |                    |
+  |            |                    |   users to manage  |                    |
+  |            |                    |   "job" level ACL  |                    |
+  |            |                    |   using Jenkins    |                    |
+  |            |                    |   Job Builder      |                    |
+  |            |                    | - No API token     |                    |
+  |            |                    |   enabled          |                    |
+  |            |                    | - Jenkins uses the |                    |
+  |            |                    |   inbuilt          |                    |
+  |            |                    |   credential store |                    |
+  |            |                    |   where we store   |                    |
+  |            |                    |   credentials for  |                    |
+  |            |                    |   LAVA, Jenkins    |                    |
+  |            |                    |   Job Builder,     |                    |
+  |            |                    |   DockerHub, AWS   |                    |
+  |            |                    |   and Gerrit       |                    |
+  |            |                    |   tokens. The      |                    |
+  |            |                    |   credentials are  |                    |
+  |            |                    |   stored as a      |                    |
+  |            |                    |   secret in        |                    |
+  |            |                    |   Jenkins          |                    |
+  |            |                    |   credential       |                    |
+  |            |                    |   store. These     |                    |
+  |            |                    |   credentials      |                    |
+  |            |                    |   can be accessed  |                    |
+  |            |                    |   via a Jenkins    |                    |
+  |            |                    |   job, but someone |                    |
+  |            |                    |   would have to    |                    |
+  |            |                    |   push a Jenkins   |                    |
+  |            |                    |   Job through a    |                    |
+  |            |                    |   Gerrit review to |                    |
+  |            |                    |   do this. Gerrit  |                    |
+  |            |                    |   maintains the    |                    |
+  |            |                    |   ACL for this and |                    |
+  |            |                    |   only admins and  |                    |
+  |            |                    |   project approver |                    |
+  |            |                    |   can +2 a review. |                    |
+  +------------+--------------------+--------------------+--------------------+
+  | Gerrit     | - Gerrit package   | - Use oauth from   | - Keep plugins up- |
+  | (including |   is installed     |   Github only      |   to-date. But it  |
+  | plugins)   |   from Linaro top  | - The password     |   is up to the     |
+  |            |   level role,      |   strength follows |   plugin owner to  |
+  |            |   which has a      |   Github policy    |   maintain said    |
+  |            |   md5sum check     | - Do not enforce   |   plugin           |
+  |            | - Gerrit Plugins   |   using two-factor |                    |
+  |            |   are installed    |   authentication   |                    |
+  |            |   from Ansible     | - Gerrit has ACL   |                    |
+  |            |   playbook, from   |   setup within the |                    |
+  |            |   the official     |   UI per-project   |                    |
+  |            |   Gerrit CI. The   |   level            |                    |
+  |            |   plugins are      | - No API token     |                    |
+  |            |   downloaded from  |   enabled          |                    |
+  |            |   https://gerrit-  | - A ci-bot-user    |                    |
+  |            |   ci.gerritforge.  |   created for      |                    |
+  |            |   com/             |   getting comments |                    |
+  |            | - Do not check     |   from Jenkins     |                    |
+  |            |   md5sum for every |                    |                    |
+  |            |   plugin           |                    |                    |
+  +------------+--------------------+--------------------+--------------------+
+  | Git        | - Package is from  | - All credentials  | - Monitor all      |
+  |            |   Linaro OBS (Open |   use GitHub. So   |   CVE's and apply  |
+  |            |   Build Service)   |   password         |   them immediately |
+  |            |   with a couple of |   strength etc are |   and keep servers |
+  |            |   “Linaro          |   based on GitHub  |   up-to-date       |
+  |            |   modifications”.  |   policy           |   monthly          |
+  |            |   (reference:      |                    | - The security     |
+  |            |   Ansible playbook |                    |   incident         |
+  |            |   and cgit repo)   |                    |   response plan is |
+  |            | - No special       |                    |   working in       |
+  |            |   integrity check  |                    |   progress         |
+  +------------+--------------------+--------------------+--------------------+
+  | Mailman    | - Installed from   | - It has           | - Plan to monitor  |
+  |            |   Ubuntu-          |   administrator    |   the CVE’s but no |
+  |            |   distributed      |   passwords for    |   timetable at the |
+  |            |   package          |   the various      |   moment           |
+  |            | - No special       |   mailing lists    |                    |
+  |            |   integrity check  | - The password     |                    |
+  |            |   (reply on APT    |   strength is not  |                    |
+  |            |   security)        |   specified        |                    |
+  +------------+--------------------+--------------------+--------------------+
+  | Website    | The website is     | There are no       | - The websites     |
+  |            | built on the IT    | credentials        |   themselves are   |
+  |            | Services' CI/CD    | associated with    |   static files     |
+  |            | server,            | the website        |   hosted on AWS S3 |
+  |            | bamboo.linaro.org, | itself. Any        |   and cached by    |
+  |            | from a Jekyll git  | permissions        |   AWS CloudFront   |
+  |            | repository stored  | required by bamboo | - The software     |
+  |            | on GitHub          | to carry out its   |   used to build    |
+  |            |                    | tasks are provided |   the website is   |
+  |            |                    | through AWS        |   all open source  |
+  |            |                    | instance role      |   and Linaro       |
+  |            |                    | permissions        |   occasionally     |
+  |            |                    |                    |   gets reports     |
+  |            |                    |                    |   from GitHub when |
+  |            |                    |                    |   an issue is      |
+  |            |                    |                    |   detected. Apply  |
+  |            |                    |                    |   a fix if it is   |
+  |            |                    |                    |   available. This  |
+  |            |                    |                    |   includes any     |
+  |            |                    |                    |   Javascript       |
+  |            |                    |                    |   frameworks that  |
+  |            |                    |                    |   might be used    |
+  |            |                    |                    |   within the web   |
+  |            |                    |                    |   pages            |
+  +------------+--------------------+--------------------+--------------------+
+  | ReadTheDocs| - One webhook ID   | - One TF-A account | - Keep database    |
+  |            |   per project is   |   with password    |   access list up   |
+  |            |   used by TF CI    |   stored in        |   to date          |
+  |            |   for building     |   engineering      | - Monitor security |
+  |            |   documentation    |   password         |   advisories       |
+  |            |   hosted by        |   database is used |                    |
+  |            |   ReadTheDocs      |   to manage        |                    |
+  |            | - Secret token     |   documentation    |                    |
+  |            |   supplied as part | - Access request   |                    |
+  |            |   of the webhook   |   is required      |                    |
+  |            |   post build       |   for database     |                    |
+  |            | - Updated content  |   access           |                    |
+  |            |   goes live        | - Token for        |                    |
+  |            |   automatically    |   Jenkins webhook  |                    |
+  |            |                    |   for CI uses      |                    |
+  |            |                    |   secret           |                    |
+  |            |                    |   credential       |                    |
+  |            |                    |   storage in       |                    |
+  |            |                    |   internal Jenkins |                    |
+  |            |                    |   and viewable     |                    |
+  |            |                    |   only through     |                    |
+  |            |                    |   ReadTheDocs      |                    |
+  |            |                    |   admin page       |                    |
+  +------------+--------------------+--------------------+--------------------+
+
+References
+**********
+
+.. [1] https://git.kernel.org/pub/scm/utils/dtc/dtc.git
+.. [2] http://zlib.net/
+.. [3] https://compiler-rt.llvm.org/
+.. [4] https://tls.mbed.org/
+.. [5] https://www.openssl.org/
+.. [6] https://github.com/ARM-software/SCP-firmware
+.. [7] https://github.com/tianocore/edk2
+.. [8] https://downloads.trustedfirmware.org/tf-a/
+.. [9] https://docs.github.com/en/github/authenticating-to-github/creating-a-strong-password
+.. [10] https://trustedfirmware-a.readthedocs.io/en/latest/process/maintenance.html#how-to-become-a-maintainer
+.. [11] https://docs.github.com/en/github/managing-security-vulnerabilities/about-alerts-for-vulnerable-dependencies
+.. [12] "Backstabber’s Knife Collection: A Review of Open Source Software Supply Chain Attacks"
+.. [13] https://www.wired.com/story/supply-chain-hackers-videogames-asus-ccleaner/
+
+*Copyright (c) 2024, Arm Limited. All rights reserved.*
+
+.. |TF-A System Diagram| image:: ../resources/diagrams/tf-a_system_diagram.png
+.. |TF-A Data Flow Diagram| image:: ../resources/diagrams/tf-a_data_flow_diagram.png
+.. |TF-A Attack Tree| image:: ../resources/diagrams/tf-a_attack_tree.png
diff --git a/drivers/cadence/nand/cdns_nand.c b/drivers/cadence/nand/cdns_nand.c
index 5a66262..20147d0 100644
--- a/drivers/cadence/nand/cdns_nand.c
+++ b/drivers/cadence/nand/cdns_nand.c
@@ -20,8 +20,12 @@
 /* NAND flash device information struct */
 static cnf_dev_info_t dev_info;
 
-/* Scratch buffers for read and write operations */
-static uint8_t scratch_buff[PLATFORM_MTD_MAX_PAGE_SIZE];
+/*
+ * Scratch buffers for read and write operations
+ * DMA transfer of Cadence NAND expects data 8 bytes aligned
+ * to be written to register
+ */
+static uint8_t scratch_buff[PLATFORM_MTD_MAX_PAGE_SIZE] __aligned(8);
 
 /* Wait for controller to be in idle state */
 static inline void cdns_nand_wait_idle(void)
@@ -111,7 +115,8 @@
 	cdns_nand_wait_thread_ready(thread_id);
 
 	/* Select memory */
-	mmio_write_32(CNF_CMDREG(CMD_REG4), (CNF_DEF_DEVICE << CNF_CMDREG4_MEM));
+	mmio_write_32(CNF_CMDREG(CMD_REG4),
+			(CNF_DEF_DEVICE << CNF_CMDREG4_MEM));
 
 	/* Issue reset command */
 	uint32_t reg = (CNF_WORK_MODE_PIO << CNF_CMDREG0_CT);
@@ -150,21 +155,19 @@
 
 		/* Async mode timing settings */
 		mmio_write_32(CNF_MINICTRL(ASYNC_TOGGLE_TIMINGS),
-								(2 << CNF_ASYNC_TIMINGS_TRH) |
-								(4 << CNF_ASYNC_TIMINGS_TRP) |
-								(2 << CNF_ASYNC_TIMINGS_TWH) |
-								(4 << CNF_ASYNC_TIMINGS_TWP));
+				(2 << CNF_ASYNC_TIMINGS_TRH) |
+				(4 << CNF_ASYNC_TIMINGS_TRP) |
+				(2 << CNF_ASYNC_TIMINGS_TWH) |
+				(4 << CNF_ASYNC_TIMINGS_TWP));
 
 		/* Set extended read and write mode */
 		reg |= (1 << CNF_DLL_PHY_EXT_RD_MODE);
 		reg |= (1 << CNF_DLL_PHY_EXT_WR_MODE);
 
 		/* Set operation work mode in common settings */
-		uint32_t data = mmio_read_32(CNF_MINICTRL(CMN_SETTINGS));
-
-		data |= (CNF_OPR_WORK_MODE_SDR << CNF_CMN_SETTINGS_OPR);
-		mmio_write_32(CNF_MINICTRL(CMN_SETTINGS), data);
-
+		mmio_clrsetbits_32(CNF_MINICTRL(CMN_SETTINGS),
+				CNF_CMN_SETTINGS_OPR_MASK,
+				CNF_OPR_WORK_MODE_SDR);
 	} else if (opr_mode == CNF_OPR_WORK_MODE_NVDDR) {
 		; /* ToDo: add DDR mode settings also once available on SIMICS */
 	} else {
@@ -189,13 +192,13 @@
 
 	/* DMA burst select */
 	mmio_write_32(CNF_CTRLCFG(DMA_SETTINGS),
-					(CNF_DMA_BURST_SIZE_MAX << CNF_DMA_SETTINGS_BURST) |
-					(1 << CNF_DMA_SETTINGS_OTE));
+			(CNF_DMA_BURST_SIZE_MAX << CNF_DMA_SETTINGS_BURST) |
+			(1 << CNF_DMA_SETTINGS_OTE));
 
 	/* Enable pre-fetching for 1K */
 	mmio_write_32(CNF_CTRLCFG(FIFO_TLEVEL),
-					(CNF_DMA_PREFETCH_SIZE << CNF_FIFO_TLEVEL_POS) |
-					(CNF_DMA_PREFETCH_SIZE << CNF_FIFO_TLEVEL_DMA_SIZE));
+			(CNF_DMA_PREFETCH_SIZE << CNF_FIFO_TLEVEL_POS) |
+			(CNF_DMA_PREFETCH_SIZE << CNF_FIFO_TLEVEL_DMA_SIZE));
 
 	/* Select access type */
 	mmio_write_32(CNF_CTRLCFG(MULTIPLANE_CFG), 0);
@@ -235,12 +238,13 @@
 
 	/* Calculate block size and total device size */
 	dev_info.block_size = (dev_info.npages_per_block * dev_info.page_size);
-	dev_info.total_size = (dev_info.block_size * dev_info.nblocks_per_lun *
-							dev_info.nluns);
+	dev_info.total_size = ((unsigned long long)dev_info.block_size *
+				(unsigned long long)dev_info.nblocks_per_lun *
+				dev_info.nluns);
 
-	VERBOSE("CNF params: page %d, spare %d, block %d, total %lld\n",
-				dev_info.page_size, dev_info.spare_size,
-				dev_info.block_size, dev_info.total_size);
+	VERBOSE("CNF params: page_size %d, spare_size %d, block_size %u, total_size %llu\n",
+		dev_info.page_size, dev_info.spare_size,
+		dev_info.block_size, dev_info.total_size);
 
 	return 0;
 }
@@ -323,25 +327,44 @@
 	return 0;
 }
 
+static uint32_t cdns_nand_get_row_address(uint32_t page, uint32_t block)
+{
+	uint32_t row_address = 0U;
+	uint32_t req_bits = 0U;
+
+	/* The device info is not populated yet. */
+	if (dev_info.npages_per_block == 0U)
+		return 0;
+
+	for (uint32_t i = 0U; i < sizeof(uint32_t) * 8; i++) {
+		if ((1U << i) & dev_info.npages_per_block)
+			req_bits = i;
+	}
+
+	row_address = ((page & GENMASK_32((req_bits - 1), 0)) |
+			(block << req_bits));
+
+	return row_address;
+}
+
 /* NAND Flash page read */
 static int cdns_nand_read_page(uint32_t block, uint32_t page, uintptr_t buffer)
 {
+
 	/* Wait for thread to be ready */
 	cdns_nand_wait_thread_ready(CNF_DEF_TRD);
 
 	/* Select device */
 	mmio_write_32(CNF_CMDREG(CMD_REG4),
-					(CNF_DEF_DEVICE << CNF_CMDREG4_MEM));
+			(CNF_DEF_DEVICE << CNF_CMDREG4_MEM));
 
 	/* Set host memory address for DMA transfers */
-	mmio_write_32(CNF_CMDREG(CMD_REG2), (buffer & 0xFFFF));
-	mmio_write_32(CNF_CMDREG(CMD_REG3), ((buffer >> 32) & 0xFFFF));
+	mmio_write_32(CNF_CMDREG(CMD_REG2), (buffer & UINT32_MAX));
+	mmio_write_32(CNF_CMDREG(CMD_REG3), ((buffer >> 32) & UINT32_MAX));
 
 	/* Set row address */
-	uint32_t row_address = 0U;
-
-	row_address |= ((page & 0x3F) | (block << 6));
-	mmio_write_32(CNF_CMDREG(CMD_REG1), row_address);
+	mmio_write_32(CNF_CMDREG(CMD_REG1),
+			cdns_nand_get_row_address(page, block));
 
 	/* Page read command */
 	uint32_t reg = (CNF_WORK_MODE_PIO << CNF_CMDREG0_CT);
@@ -375,8 +398,8 @@
 	uint32_t page = 0U;
 	int result = 0;
 
-	VERBOSE("CNF: block %u-%u, page_start %u, len %zu, offset %u\n",
-				block, end_block, page_start, length, offset);
+	INFO("CNF: %s: block %u-%u, page_start %u, len %zu, offset %u\n",
+		__func__, block, end_block, page_start, length, offset);
 
 	if ((offset >= dev_info.total_size) ||
 		(offset + length-1 >= dev_info.total_size) ||
@@ -392,7 +415,7 @@
 			if ((start_offset != 0U) || (length < dev_info.page_size)) {
 				/* Partial page read */
 				result = cdns_nand_read_page(block, page,
-				(uintptr_t)scratch_buff);
+							(uintptr_t)scratch_buff);
 				if (result != 0) {
 					return result;
 				}
diff --git a/drivers/st/bsec/bsec2.c b/drivers/st/bsec/bsec2.c
index 68d3a5b..a6e5220 100644
--- a/drivers/st/bsec/bsec2.c
+++ b/drivers/st/bsec/bsec2.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2022, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2017-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -21,15 +21,26 @@
 #define BSEC_IP_VERSION_2_0	U(0x20)
 #define BSEC_IP_ID_2		U(0x100032)
 
+/*
+ * IP configuration
+ */
+#define BSEC_OTP_MASK			GENMASK(4, 0)
+#define BSEC_OTP_BANK_SHIFT		5
+#define BSEC_TIMEOUT_VALUE		U(0xFFFF)
+
 #define OTP_ACCESS_SIZE (round_up(OTP_MAX_SIZE, __WORD_BIT) / __WORD_BIT)
 
-static uint32_t otp_nsec_access[OTP_ACCESS_SIZE] __unused;
+static uint32_t otp_nsec_access[OTP_ACCESS_SIZE] __maybe_unused;
 
+static uint32_t bsec_shadow_register(uint32_t otp);
 static uint32_t bsec_power_safmem(bool power);
+static uint32_t bsec_get_version(void);
+static uint32_t bsec_get_id(void);
+static uint32_t bsec_get_status(void);
+static uint32_t bsec_read_permanent_lock(uint32_t otp, bool *value);
 
 /* BSEC access protection */
 static spinlock_t bsec_spinlock;
-static uintptr_t bsec_base;
 
 static void bsec_lock(void)
 {
@@ -47,7 +58,7 @@
 
 static bool is_otp_invalid_mode(void)
 {
-	bool ret = ((bsec_get_status() & BSEC_MODE_INVALID) == BSEC_MODE_INVALID);
+	bool ret = ((bsec_get_status() & BSEC_OTP_STATUS_INVALID) == BSEC_OTP_STATUS_INVALID);
 
 	if (ret) {
 		ERROR("OTP mode is OTP-INVALID\n");
@@ -163,7 +174,7 @@
 		panic();
 	}
 
-	assert(bsec_base == bsec_info.base);
+	assert(bsec_info.base == BSEC_BASE);
 
 	bsec_dt_otp_nsec_access(fdt, node);
 }
@@ -177,6 +188,11 @@
 	       sizeof(uint32_t);
 }
 
+static uint32_t otp_bit_mask(uint32_t otp)
+{
+	return BIT(otp & BSEC_OTP_MASK);
+}
+
 /*
  * bsec_check_error: check BSEC error status.
  * otp: OTP number.
@@ -186,10 +202,10 @@
  */
 static uint32_t bsec_check_error(uint32_t otp, bool check_disturbed)
 {
-	uint32_t bit = BIT(otp & BSEC_OTP_MASK);
+	uint32_t bit = otp_bit_mask(otp);
 	uint32_t bank = otp_bank_offset(otp);
 
-	if ((mmio_read_32(bsec_base + BSEC_ERROR_OFF + bank) & bit) != 0U) {
+	if ((mmio_read_32(BSEC_BASE + BSEC_ERROR_OFF + bank) & bit) != 0U) {
 		return BSEC_ERROR;
 	}
 
@@ -197,7 +213,7 @@
 		return BSEC_OK;
 	}
 
-	if ((mmio_read_32(bsec_base + BSEC_DISTURBED_OFF + bank) & bit) != 0U) {
+	if ((mmio_read_32(BSEC_BASE + BSEC_DISTURBED_OFF + bank) & bit) != 0U) {
 		return BSEC_DISTURBED;
 	}
 
@@ -210,14 +226,12 @@
  */
 uint32_t bsec_probe(void)
 {
-	bsec_base = BSEC_BASE;
-
 	if (is_otp_invalid_mode()) {
 		return BSEC_ERROR;
 	}
 
-	if ((((bsec_get_version() & BSEC_IPVR_MSK) != BSEC_IP_VERSION_1_1) &&
-	     ((bsec_get_version() & BSEC_IPVR_MSK) != BSEC_IP_VERSION_2_0)) ||
+	if (((bsec_get_version() != BSEC_IP_VERSION_1_1) &&
+	     (bsec_get_version() != BSEC_IP_VERSION_2_0)) ||
 	    (bsec_get_id() != BSEC_IP_ID_2)) {
 		panic();
 	}
@@ -229,102 +243,11 @@
 }
 
 /*
- * bsec_get_base: return BSEC base address.
- */
-uint32_t bsec_get_base(void)
-{
-	return bsec_base;
-}
-
-/*
- * bsec_set_config: enable and configure BSEC.
- * cfg: pointer to param structure used to set register.
- * return value: BSEC_OK if no error.
- */
-uint32_t bsec_set_config(struct bsec_config *cfg)
-{
-	uint32_t value;
-	uint32_t result;
-
-	if (is_otp_invalid_mode()) {
-		return BSEC_ERROR;
-	}
-
-	value = ((((uint32_t)cfg->freq << BSEC_CONF_FRQ_SHIFT) &
-						BSEC_CONF_FRQ_MASK) |
-		 (((uint32_t)cfg->pulse_width << BSEC_CONF_PRG_WIDTH_SHIFT) &
-						BSEC_CONF_PRG_WIDTH_MASK) |
-		 (((uint32_t)cfg->tread << BSEC_CONF_TREAD_SHIFT) &
-						BSEC_CONF_TREAD_MASK));
-
-	bsec_lock();
-
-	mmio_write_32(bsec_base + BSEC_OTP_CONF_OFF, value);
-
-	bsec_unlock();
-
-	result = bsec_power_safmem((bool)cfg->power &
-				   BSEC_CONF_POWER_UP_MASK);
-	if (result != BSEC_OK) {
-		return result;
-	}
-
-	value = ((((uint32_t)cfg->upper_otp_lock << UPPER_OTP_LOCK_SHIFT) &
-						UPPER_OTP_LOCK_MASK) |
-		 (((uint32_t)cfg->den_lock << DENREG_LOCK_SHIFT) &
-						DENREG_LOCK_MASK) |
-		 (((uint32_t)cfg->prog_lock << GPLOCK_LOCK_SHIFT) &
-						GPLOCK_LOCK_MASK));
-
-	bsec_lock();
-
-	mmio_write_32(bsec_base + BSEC_OTP_LOCK_OFF, value);
-
-	bsec_unlock();
-
-	return BSEC_OK;
-}
-
-/*
- * bsec_get_config: return config parameters set in BSEC registers.
- * cfg: config param return.
- * return value: BSEC_OK if no error.
- */
-uint32_t bsec_get_config(struct bsec_config *cfg)
-{
-	uint32_t value;
-
-	if (cfg == NULL) {
-		return BSEC_INVALID_PARAM;
-	}
-
-	value = mmio_read_32(bsec_base + BSEC_OTP_CONF_OFF);
-	cfg->power = (uint8_t)((value & BSEC_CONF_POWER_UP_MASK) >>
-						BSEC_CONF_POWER_UP_SHIFT);
-	cfg->freq = (uint8_t)((value & BSEC_CONF_FRQ_MASK) >>
-						BSEC_CONF_FRQ_SHIFT);
-	cfg->pulse_width = (uint8_t)((value & BSEC_CONF_PRG_WIDTH_MASK) >>
-						BSEC_CONF_PRG_WIDTH_SHIFT);
-	cfg->tread = (uint8_t)((value & BSEC_CONF_TREAD_MASK) >>
-						BSEC_CONF_TREAD_SHIFT);
-
-	value = mmio_read_32(bsec_base + BSEC_OTP_LOCK_OFF);
-	cfg->upper_otp_lock = (uint8_t)((value & UPPER_OTP_LOCK_MASK) >>
-						UPPER_OTP_LOCK_SHIFT);
-	cfg->den_lock = (uint8_t)((value & DENREG_LOCK_MASK) >>
-						DENREG_LOCK_SHIFT);
-	cfg->prog_lock = (uint8_t)((value & GPLOCK_LOCK_MASK) >>
-						GPLOCK_LOCK_SHIFT);
-
-	return BSEC_OK;
-}
-
-/*
  * bsec_shadow_register: copy SAFMEM OTP to BSEC data.
  * otp: OTP number.
  * return value: BSEC_OK if no error.
  */
-uint32_t bsec_shadow_register(uint32_t otp)
+static uint32_t bsec_shadow_register(uint32_t otp)
 {
 	uint32_t result;
 	bool value;
@@ -345,7 +268,7 @@
 			otp);
 	}
 
-	if ((bsec_get_status() & BSEC_MODE_PWR_MASK) == 0U) {
+	if ((bsec_get_status() & BSEC_OTP_STATUS_PWRON) == 0U) {
 		result = bsec_power_safmem(true);
 
 		if (result != BSEC_OK) {
@@ -357,9 +280,9 @@
 
 	bsec_lock();
 
-	mmio_write_32(bsec_base + BSEC_OTP_CTRL_OFF, otp | BSEC_READ);
+	mmio_write_32(BSEC_BASE + BSEC_OTP_CTRL_OFF, otp | BSEC_READ);
 
-	while ((bsec_get_status() & BSEC_MODE_BUSY_MASK) != 0U) {
+	while ((bsec_get_status() & BSEC_OTP_STATUS_BUSY) != 0U) {
 		;
 	}
 
@@ -392,7 +315,7 @@
 		return BSEC_INVALID_PARAM;
 	}
 
-	*val = mmio_read_32(bsec_base + BSEC_OTP_DATA_OFF +
+	*val = mmio_read_32(BSEC_BASE + BSEC_OTP_DATA_OFF +
 			    (otp * sizeof(uint32_t)));
 
 	return BSEC_OK;
@@ -427,7 +350,7 @@
 	/* Ensure integrity of each register access sequence */
 	bsec_lock();
 
-	mmio_write_32(bsec_base + BSEC_OTP_DATA_OFF +
+	mmio_write_32(BSEC_BASE + BSEC_OTP_DATA_OFF +
 		      (otp * sizeof(uint32_t)), val);
 
 	bsec_unlock();
@@ -470,12 +393,11 @@
 		return BSEC_PROG_FAIL;
 	}
 
-	if ((mmio_read_32(bsec_base + BSEC_OTP_LOCK_OFF) &
-	     BIT(BSEC_LOCK_PROGRAM)) != 0U) {
+	if ((mmio_read_32(BSEC_BASE + BSEC_OTP_LOCK_OFF) & GPLOCK_LOCK_MASK) != 0U) {
 		WARN("BSEC: GPLOCK activated, prog will be ignored\n");
 	}
 
-	if ((bsec_get_status() & BSEC_MODE_PWR_MASK) == 0U) {
+	if ((bsec_get_status() & BSEC_OTP_STATUS_PWRON) == 0U) {
 		result = bsec_power_safmem(true);
 
 		if (result != BSEC_OK) {
@@ -487,15 +409,15 @@
 
 	bsec_lock();
 
-	mmio_write_32(bsec_base + BSEC_OTP_WRDATA_OFF, val);
+	mmio_write_32(BSEC_BASE + BSEC_OTP_WRDATA_OFF, val);
 
-	mmio_write_32(bsec_base + BSEC_OTP_CTRL_OFF, otp | BSEC_WRITE);
+	mmio_write_32(BSEC_BASE + BSEC_OTP_CTRL_OFF, otp | BSEC_WRITE);
 
-	while ((bsec_get_status() & BSEC_MODE_BUSY_MASK) != 0U) {
+	while ((bsec_get_status() & BSEC_OTP_STATUS_BUSY) != 0U) {
 		;
 	}
 
-	if ((bsec_get_status() & BSEC_MODE_PROGFAIL_MASK) != 0U) {
+	if ((bsec_get_status() & BSEC_OTP_STATUS_PROGFAIL) != 0U) {
 		result = BSEC_PROG_FAIL;
 	} else {
 		result = bsec_check_error(otp, true);
@@ -517,6 +439,7 @@
  * otp: OTP number.
  * return value: BSEC_OK if no error.
  */
+#if defined(IMAGE_BL32)
 uint32_t bsec_permanent_lock_otp(uint32_t otp)
 {
 	uint32_t result;
@@ -532,7 +455,7 @@
 		return BSEC_INVALID_PARAM;
 	}
 
-	if ((bsec_get_status() & BSEC_MODE_PWR_MASK) == 0U) {
+	if ((bsec_get_status() & BSEC_OTP_STATUS_PWRON) == 0U) {
 		result = bsec_power_safmem(true);
 
 		if (result != BSEC_OK) {
@@ -554,16 +477,16 @@
 
 	bsec_lock();
 
-	mmio_write_32(bsec_base + BSEC_OTP_WRDATA_OFF, data);
+	mmio_write_32(BSEC_BASE + BSEC_OTP_WRDATA_OFF, data);
 
-	mmio_write_32(bsec_base + BSEC_OTP_CTRL_OFF,
+	mmio_write_32(BSEC_BASE + BSEC_OTP_CTRL_OFF,
 		      addr | BSEC_WRITE | BSEC_LOCK);
 
-	while ((bsec_get_status() & BSEC_MODE_BUSY_MASK) != 0U) {
+	while ((bsec_get_status() & BSEC_OTP_STATUS_BUSY) != 0U) {
 		;
 	}
 
-	if ((bsec_get_status() & BSEC_MODE_PROGFAIL_MASK) != 0U) {
+	if ((bsec_get_status() & BSEC_OTP_STATUS_PROGFAIL) != 0U) {
 		result = BSEC_PROG_FAIL;
 	} else {
 		result = bsec_check_error(otp, false);
@@ -579,30 +502,14 @@
 
 	return result;
 }
-
-/*
- * bsec_write_debug_conf: write value in debug feature.
- *	to enable/disable debug service.
- * val: value to write.
- * return value: none.
- */
-void bsec_write_debug_conf(uint32_t val)
-{
-	if (is_otp_invalid_mode()) {
-		return;
-	}
-
-	bsec_lock();
-	mmio_write_32(bsec_base + BSEC_DEN_OFF, val & BSEC_DEN_ALL_MSK);
-	bsec_unlock();
-}
+#endif
 
 /*
  * bsec_read_debug_conf: return debug configuration register value.
  */
 uint32_t bsec_read_debug_conf(void)
 {
-	return mmio_read_32(bsec_base + BSEC_DEN_OFF);
+	return mmio_read_32(BSEC_BASE + BSEC_DEN_OFF);
 }
 
 /*
@@ -618,7 +525,7 @@
 	}
 
 	bsec_lock();
-	mmio_write_32(bsec_base + BSEC_SCRATCH_OFF, val);
+	mmio_write_32(BSEC_BASE + BSEC_SCRATCH_OFF, val);
 	bsec_unlock();
 #else
 	mmio_write_32(BSEC_BASE + BSEC_SCRATCH_OFF, val);
@@ -626,54 +533,30 @@
 }
 
 /*
- * bsec_read_scratch: return scratch register value.
- */
-uint32_t bsec_read_scratch(void)
-{
-	return mmio_read_32(bsec_base + BSEC_SCRATCH_OFF);
-}
-
-/*
  * bsec_get_status: return status register value.
  */
-uint32_t bsec_get_status(void)
-{
-	return mmio_read_32(bsec_base + BSEC_OTP_STATUS_OFF);
-}
-
-/*
- * bsec_get_hw_conf: return hardware configuration register value.
- */
-uint32_t bsec_get_hw_conf(void)
+static uint32_t bsec_get_status(void)
 {
-	return mmio_read_32(bsec_base + BSEC_IPHW_CFG_OFF);
+	return mmio_read_32(BSEC_BASE + BSEC_OTP_STATUS_OFF);
 }
 
 /*
  * bsec_get_version: return BSEC version register value.
  */
-uint32_t bsec_get_version(void)
+static uint32_t bsec_get_version(void)
 {
-	return mmio_read_32(bsec_base + BSEC_IPVR_OFF);
+	return mmio_read_32(BSEC_BASE + BSEC_IPVR_OFF) & BSEC_IPVR_MSK;
 }
 
 /*
  * bsec_get_id: return BSEC ID register value.
  */
-uint32_t bsec_get_id(void)
+static uint32_t bsec_get_id(void)
 {
-	return mmio_read_32(bsec_base + BSEC_IP_ID_OFF);
+	return mmio_read_32(BSEC_BASE + BSEC_IP_ID_OFF);
 }
 
 /*
- * bsec_get_magic_id: return BSEC magic number register value.
- */
-uint32_t bsec_get_magic_id(void)
-{
-	return mmio_read_32(bsec_base + BSEC_IP_MAGIC_ID_OFF);
-}
-
-/*
  * bsec_set_sr_lock: set shadow-read lock.
  * otp: OTP number.
  * return value: BSEC_OK if no error.
@@ -681,7 +564,7 @@
 uint32_t bsec_set_sr_lock(uint32_t otp)
 {
 	uint32_t bank = otp_bank_offset(otp);
-	uint32_t otp_mask = BIT(otp & BSEC_OTP_MASK);
+	uint32_t otp_mask = otp_bit_mask(otp);
 
 	if (is_otp_invalid_mode()) {
 		return BSEC_ERROR;
@@ -692,7 +575,7 @@
 	}
 
 	bsec_lock();
-	mmio_write_32(bsec_base + BSEC_SRLOCK_OFF + bank, otp_mask);
+	mmio_write_32(BSEC_BASE + BSEC_SRLOCK_OFF + bank, otp_mask);
 	bsec_unlock();
 
 	return BSEC_OK;
@@ -707,14 +590,14 @@
 uint32_t bsec_read_sr_lock(uint32_t otp, bool *value)
 {
 	uint32_t bank = otp_bank_offset(otp);
-	uint32_t otp_mask = BIT(otp & BSEC_OTP_MASK);
+	uint32_t otp_mask = otp_bit_mask(otp);
 	uint32_t bank_value;
 
 	if (otp > STM32MP1_OTP_MAX_ID) {
 		return BSEC_INVALID_PARAM;
 	}
 
-	bank_value = mmio_read_32(bsec_base + BSEC_SRLOCK_OFF + bank);
+	bank_value = mmio_read_32(BSEC_BASE + BSEC_SRLOCK_OFF + bank);
 
 	*value = ((bank_value & otp_mask) != 0U);
 
@@ -729,7 +612,7 @@
 uint32_t bsec_set_sw_lock(uint32_t otp)
 {
 	uint32_t bank = otp_bank_offset(otp);
-	uint32_t otp_mask = BIT(otp & BSEC_OTP_MASK);
+	uint32_t otp_mask = otp_bit_mask(otp);
 
 	if (is_otp_invalid_mode()) {
 		return BSEC_ERROR;
@@ -740,7 +623,7 @@
 	}
 
 	bsec_lock();
-	mmio_write_32(bsec_base + BSEC_SWLOCK_OFF + bank, otp_mask);
+	mmio_write_32(BSEC_BASE + BSEC_SWLOCK_OFF + bank, otp_mask);
 	bsec_unlock();
 
 	return BSEC_OK;
@@ -762,7 +645,7 @@
 		return BSEC_INVALID_PARAM;
 	}
 
-	bank_value = mmio_read_32(bsec_base + BSEC_SWLOCK_OFF + bank);
+	bank_value = mmio_read_32(BSEC_BASE + BSEC_SWLOCK_OFF + bank);
 
 	*value = ((bank_value & otp_mask) != 0U);
 
@@ -777,7 +660,7 @@
 uint32_t bsec_set_sp_lock(uint32_t otp)
 {
 	uint32_t bank = otp_bank_offset(otp);
-	uint32_t otp_mask = BIT(otp & BSEC_OTP_MASK);
+	uint32_t otp_mask = otp_bit_mask(otp);
 
 	if (is_otp_invalid_mode()) {
 		return BSEC_ERROR;
@@ -788,7 +671,7 @@
 	}
 
 	bsec_lock();
-	mmio_write_32(bsec_base + BSEC_SPLOCK_OFF + bank, otp_mask);
+	mmio_write_32(BSEC_BASE + BSEC_SPLOCK_OFF + bank, otp_mask);
 	bsec_unlock();
 
 	return BSEC_OK;
@@ -810,7 +693,7 @@
 		return BSEC_INVALID_PARAM;
 	}
 
-	bank_value = mmio_read_32(bsec_base + BSEC_SPLOCK_OFF + bank);
+	bank_value = mmio_read_32(BSEC_BASE + BSEC_SPLOCK_OFF + bank);
 
 	*value = ((bank_value & otp_mask) != 0U);
 
@@ -823,17 +706,17 @@
  * value: read value (true or false).
  * return value: BSEC_OK if no error.
  */
-uint32_t bsec_read_permanent_lock(uint32_t otp, bool *value)
+static uint32_t bsec_read_permanent_lock(uint32_t otp, bool *value)
 {
 	uint32_t bank = otp_bank_offset(otp);
-	uint32_t otp_mask = BIT(otp & BSEC_OTP_MASK);
+	uint32_t otp_mask = otp_bit_mask(otp);
 	uint32_t bank_value;
 
 	if (otp > STM32MP1_OTP_MAX_ID) {
 		return BSEC_INVALID_PARAM;
 	}
 
-	bank_value = mmio_read_32(bsec_base + BSEC_WRLOCK_OFF + bank);
+	bank_value = mmio_read_32(BSEC_BASE + BSEC_WRLOCK_OFF + bank);
 
 	*value = ((bank_value & otp_mask) != 0U);
 
@@ -841,36 +724,6 @@
 }
 
 /*
- * bsec_otp_lock: Lock Upper OTP or Global Programming or Debug Enable.
- * service: Service to lock, see header file.
- * return value: BSEC_OK if no error.
- */
-uint32_t bsec_otp_lock(uint32_t service)
-{
-	uintptr_t reg = bsec_base + BSEC_OTP_LOCK_OFF;
-
-	if (is_otp_invalid_mode()) {
-		return BSEC_ERROR;
-	}
-
-	switch (service) {
-	case BSEC_LOCK_UPPER_OTP:
-		mmio_write_32(reg, BIT(BSEC_LOCK_UPPER_OTP));
-		break;
-	case BSEC_LOCK_DEBUG:
-		mmio_write_32(reg, BIT(BSEC_LOCK_DEBUG));
-		break;
-	case BSEC_LOCK_PROGRAM:
-		mmio_write_32(reg, BIT(BSEC_LOCK_PROGRAM));
-		break;
-	default:
-		return BSEC_INVALID_PARAM;
-	}
-
-	return BSEC_OK;
-}
-
-/*
  * bsec_power_safmem: Activate or deactivate SAFMEM power.
  * power: true to power up, false to power down.
  * return value: BSEC_OK if no error.
@@ -882,7 +735,7 @@
 
 	bsec_lock();
 
-	register_val = mmio_read_32(bsec_base + BSEC_OTP_CONF_OFF);
+	register_val = mmio_read_32(BSEC_BASE + BSEC_OTP_CONF_OFF);
 
 	if (power) {
 		register_val |= BSEC_CONF_POWER_UP_MASK;
@@ -890,15 +743,15 @@
 		register_val &= ~BSEC_CONF_POWER_UP_MASK;
 	}
 
-	mmio_write_32(bsec_base + BSEC_OTP_CONF_OFF, register_val);
+	mmio_write_32(BSEC_BASE + BSEC_OTP_CONF_OFF, register_val);
 
 	if (power) {
-		while (((bsec_get_status() & BSEC_MODE_PWR_MASK) == 0U) &&
+		while (((bsec_get_status() & BSEC_OTP_STATUS_PWRON) == 0U) &&
 		       (timeout != 0U)) {
 			timeout--;
 		}
 	} else {
-		while (((bsec_get_status() & BSEC_MODE_PWR_MASK) != 0U) &&
+		while (((bsec_get_status() & BSEC_OTP_STATUS_PWRON) != 0U) &&
 		       (timeout != 0U)) {
 			timeout--;
 		}
@@ -915,28 +768,29 @@
 
 /*
  * bsec_shadow_read_otp: Load OTP from SAFMEM and provide its value.
- * otp_value: read value.
- * word: OTP number.
+ * val: read value.
+ * otp: OTP number.
  * return value: BSEC_OK if no error.
  */
-uint32_t bsec_shadow_read_otp(uint32_t *otp_value, uint32_t word)
+uint32_t bsec_shadow_read_otp(uint32_t *val, uint32_t otp)
 {
 	uint32_t result;
 
-	result = bsec_shadow_register(word);
+	result = bsec_shadow_register(otp);
 	if (result != BSEC_OK) {
-		ERROR("BSEC: %u Shadowing Error %u\n", word, result);
+		ERROR("BSEC: %u Shadowing Error %u\n", otp, result);
 		return result;
 	}
 
-	result = bsec_read_otp(otp_value, word);
+	result = bsec_read_otp(val, otp);
 	if (result != BSEC_OK) {
-		ERROR("BSEC: %u Read Error %u\n", word, result);
+		ERROR("BSEC: %u Read Error %u\n", otp, result);
 	}
 
 	return result;
 }
 
+#if defined(IMAGE_BL32)
 /*
  * bsec_check_nsec_access_rights: check non-secure access rights to target OTP.
  * otp: OTP number.
@@ -944,7 +798,6 @@
  */
 uint32_t bsec_check_nsec_access_rights(uint32_t otp)
 {
-#if defined(IMAGE_BL32)
 	if (otp > STM32MP1_OTP_MAX_ID) {
 		return BSEC_INVALID_PARAM;
 	}
@@ -954,8 +807,33 @@
 			return BSEC_ERROR;
 		}
 	}
-#endif
 
 	return BSEC_OK;
 }
+#endif
+
+uint32_t bsec_get_secure_state(void)
+{
+	uint32_t status = bsec_get_status();
+	uint32_t result = BSEC_STATE_INVALID;
+	uint32_t otp_enc_id __maybe_unused;
+	uint32_t otp_bit_len __maybe_unused;
+	int res __maybe_unused;
 
+	if ((status & BSEC_OTP_STATUS_INVALID) != 0U) {
+		result = BSEC_STATE_INVALID;
+	} else {
+		if ((status & BSEC_OTP_STATUS_SECURE) != 0U) {
+			if (stm32mp_check_closed_device() == STM32MP_CHIP_SEC_CLOSED) {
+				result = BSEC_STATE_SEC_CLOSED;
+			} else {
+				result = BSEC_STATE_SEC_OPEN;
+			}
+		} else {
+			/* OTP modes OPEN1 and OPEN2 are not supported */
+			result = BSEC_STATE_INVALID;
+		}
+	}
+
+	return result;
+}
diff --git a/fdts/cca_cot_descriptors.dtsi b/fdts/cca_cot_descriptors.dtsi
new file mode 100644
index 0000000..d52431b
--- /dev/null
+++ b/fdts/cca_cot_descriptors.dtsi
@@ -0,0 +1,287 @@
+/*
+ * Copyright (c) 2023-2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <tools_share/cca_oid.h>
+#include <common/tbbr/tbbr_img_def.h>
+#include <common/nv_cntr_ids.h>
+
+cot {
+	manifests {
+		compatible = "arm, cert-descs";
+
+		cca_content_cert: cca_content_cert {
+			root-certificate;
+			image-id =<CCA_CONTENT_CERT_ID>;
+			antirollback-counter = <&cca_nv_counter>;
+
+			tb_fw_hash: tb_fw_hash {
+				oid = TRUSTED_BOOT_FW_HASH_OID;
+			};
+			tb_fw_config_hash: tb_fw_config_hash {
+				oid = TRUSTED_BOOT_FW_CONFIG_HASH_OID;
+			};
+			hw_config_hash: hw_config_hash {
+				oid = HW_CONFIG_HASH_OID;
+			};
+			fw_config_hash: fw_config_hash {
+				oid = FW_CONFIG_HASH_OID;
+			};
+			soc_fw_hash: soc_fw_hash {
+				oid = SOC_AP_FW_HASH_OID;
+			};
+			soc_fw_config_hash: soc_fw_config_hash {
+				oid = SOC_FW_CONFIG_HASH_OID;
+			};
+			rmm_hash: rmm_hash {
+				oid = RMM_HASH_OID;
+			};
+		};
+
+		core_swd_key_cert: core_swd_key_cert {
+			root-certificate;
+			image-id = <CORE_SWD_KEY_CERT_ID>;
+			signing-key = <&swd_rot_pk>;
+			antirollback-counter = <&trusted_nv_counter>;
+
+			core_swd_pk: core_swd_pk {
+				oid = CORE_SWD_PK_OID;
+			};
+		};
+
+		trusted_os_fw_content_cert: trusted_os_fw_content_cert {
+			image-id = <TRUSTED_OS_FW_CONTENT_CERT_ID>;
+			parent = <&core_swd_key_cert>;
+			signing-key = <&core_swd_pk>;
+			antirollback-counter = <&trusted_nv_counter>;
+
+			tos_fw_hash: tos_fw_hash {
+				oid = TRUSTED_OS_FW_HASH_OID;
+			};
+			tos_fw_config_hash: tos_fw_config_hash {
+				oid = TRUSTED_OS_FW_CONFIG_HASH_OID;
+			};
+		};
+
+		plat_key_cert: plat_key_cert {
+			root-certificate;
+			image-id = <PLAT_KEY_CERT_ID>;
+			signing-key = <&prot_pk>;
+			antirollback-counter = <&non_trusted_nv_counter>;
+
+			plat_pk: plat_pk {
+				oid = PLAT_PK_OID;
+			};
+		};
+
+		non_trusted_fw_content_cert: non_trusted_fw_content_cert {
+			image-id = <NON_TRUSTED_FW_CONTENT_CERT_ID>;
+			parent = <&plat_key_cert>;
+			signing-key = <&plat_pk>;
+			antirollback-counter = <&non_trusted_nv_counter>;
+
+			nt_world_bl_hash: nt_world_bl_hash {
+				oid = NON_TRUSTED_WORLD_BOOTLOADER_HASH_OID;
+			};
+			nt_fw_config_hash: nt_fw_config_hash {
+				oid = NON_TRUSTED_FW_CONFIG_HASH_OID;
+			};
+		};
+
+#if defined(SPD_spmd)
+		sip_sp_content_cert: sip_sp_content_cert {
+			image-id = <SIP_SP_CONTENT_CERT_ID>;
+			parent = <&core_swd_key_cert>;
+			signing-key = <&core_swd_pk>;
+			antirollback-counter = <&trusted_nv_counter>;
+
+			sp_pkg1_hash: sp_pkg1_hash {
+				oid = SP_PKG1_HASH_OID;
+			};
+			sp_pkg2_hash: sp_pkg2_hash {
+				oid = SP_PKG2_HASH_OID;
+			};
+			sp_pkg3_hash: sp_pkg3_hash {
+				oid = SP_PKG3_HASH_OID;
+			};
+			sp_pkg4_hash: sp_pkg4_hash {
+				oid = SP_PKG4_HASH_OID;
+			};
+		};
+
+		plat_sp_content_cert: plat_sp_content_cert {
+			image-id = <PLAT_SP_CONTENT_CERT_ID>;
+			parent = <&plat_key_cert>;
+			signing-key = <&plat_pk>;
+			antirollback-counter = <&non_trusted_nv_counter>;
+
+			sp_pkg5_hash: sp_pkg5_hash {
+				oid = SP_PKG5_HASH_OID;
+			};
+			sp_pkg6_hash: sp_pkg6_hash {
+				oid = SP_PKG6_HASH_OID;
+			};
+			sp_pkg7_hash: sp_pkg7_hash {
+				oid = SP_PKG7_HASH_OID;
+			};
+			sp_pkg8_hash: sp_pkg8_hash {
+				oid = SP_PKG8_HASH_OID;
+			};
+		};
+#endif
+	};
+
+	images {
+		compatible = "arm, img-descs";
+
+		fw_config {
+			image-id = <FW_CONFIG_ID>;
+			parent = <&cca_content_cert>;
+			hash = <&fw_config_hash>;
+		};
+
+		hw_config {
+			image-id = <HW_CONFIG_ID>;
+			parent = <&cca_content_cert>;
+			hash = <&hw_config_hash>;
+		};
+
+		tb_fw_hash {
+			image-id = <BL2_IMAGE_ID>;
+			parent = <&cca_content_cert>;
+			hash = <&tb_fw_hash>;
+		};
+
+		tb_fw_config {
+			image-id = <TB_FW_CONFIG_ID>;
+			parent = <&cca_content_cert>;
+			hash = <&tb_fw_config_hash>;
+		};
+
+		bl31_image {
+			image-id = <BL31_IMAGE_ID>;
+			parent = <&cca_content_cert>;
+			hash = <&soc_fw_hash>;
+		};
+
+		soc_fw_config {
+			image-id = <SOC_FW_CONFIG_ID>;
+			parent = <&cca_content_cert>;
+			hash = <&soc_fw_config_hash>;
+		};
+
+		rmm_image {
+			image-id = <RMM_IMAGE_ID>;
+			parent = <&cca_content_cert>;
+			hash = <&rmm_hash>;
+		};
+
+		bl32_image {
+			image-id = <BL32_IMAGE_ID>;
+			parent = <&trusted_os_fw_content_cert>;
+			hash = <&tos_fw_hash>;
+		};
+
+		tos_fw_config {
+			image-id = <TOS_FW_CONFIG_ID>;
+			parent = <&trusted_os_fw_content_cert>;
+			hash = <&tos_fw_config_hash>;
+		};
+
+		bl33_image {
+			image-id = <BL33_IMAGE_ID>;
+			parent = <&non_trusted_fw_content_cert>;
+			hash = <&nt_world_bl_hash>;
+		};
+
+		nt_fw_config {
+			image-id = <NT_FW_CONFIG_ID>;
+			parent = <&non_trusted_fw_content_cert>;
+			hash = <&nt_fw_config_hash>;
+		};
+
+#if defined(SPD_spmd)
+		sp_pkg1 {
+			image-id = <SP_PKG1_ID>;
+			parent = <&sip_sp_content_cert>;
+			hash = <&sp_pkg1_hash>;
+		};
+
+		sp_pkg2 {
+			image-id = <SP_PKG2_ID>;
+			parent = <&sip_sp_content_cert>;
+			hash = <&sp_pkg2_hash>;
+		};
+
+		sp_pkg3 {
+			image-id = <SP_PKG3_ID>;
+			parent = <&sip_sp_content_cert>;
+			hash = <&sp_pkg3_hash>;
+		};
+
+		sp_pkg4 {
+			image-id = <SP_PKG4_ID>;
+			parent = <&sip_sp_content_cert>;
+			hash = <&sp_pkg4_hash>;
+		};
+
+		sp_pkg5 {
+			image-id = <SP_PKG5_ID>;
+			parent = <&plat_sp_content_cert>;
+			hash = <&sp_pkg5_hash>;
+		};
+
+		sp_pkg6 {
+			image-id = <SP_PKG6_ID>;
+			parent = <&plat_sp_content_cert>;
+			hash = <&sp_pkg6_hash>;
+		};
+
+		sp_pkg7 {
+			image-id = <SP_PKG7_ID>;
+			parent = <&plat_sp_content_cert>;
+			hash = <&sp_pkg7_hash>;
+		};
+
+		sp_pkg8 {
+			image-id = <SP_PKG8_ID>;
+			parent = <&plat_sp_content_cert>;
+			hash = <&sp_pkg8_hash>;
+		};
+#endif
+	};
+};
+
+non_volatile_counters: non_volatile_counters {
+	compatible = "arm, non-volatile-counter";
+
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	cca_nv_counter: cca_nv_counter {
+		id  = <TRUSTED_NV_CTR_ID>;
+		oid = CCA_FW_NVCOUNTER_OID;
+	};
+
+	trusted_nv_counter: trusted_nv_counter {
+		id  = <TRUSTED_NV_CTR_ID>;
+		oid = TRUSTED_FW_NVCOUNTER_OID;
+	};
+
+	non_trusted_nv_counter: non_trusted_nv_counter {
+		id  = <NON_TRUSTED_NV_CTR_ID>;
+		oid = NON_TRUSTED_FW_NVCOUNTER_OID;
+	};
+};
+
+rot_keys {
+	swd_rot_pk: swd_rot_pk {
+		oid = SWD_ROT_PK_OID;
+	};
+
+	prot_pk: prot_pk {
+		oid = PROT_PK_OID;
+	};
+};
diff --git a/fdts/stm32mp131.dtsi b/fdts/stm32mp131.dtsi
index 8bcf363..520d90b 100644
--- a/fdts/stm32mp131.dtsi
+++ b/fdts/stm32mp131.dtsi
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
 /*
- * Copyright (C) 2022-2023, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2022-2024, STMicroelectronics - All Rights Reserved
  * Author: Alexandre Torgue <alexandre.torgue@foss.st.com> for STMicroelectronics.
  */
 #include <dt-bindings/clock/stm32mp13-clks.h>
@@ -420,25 +420,25 @@
 			#address-cells = <1>;
 			#size-cells = <1>;
 
-			cfg0_otp: cfg0_otp@0 {
+			cfg0_otp: cfg0-otp@0 {
 				reg = <0x0 0x2>;
 			};
 			part_number_otp: part-number-otp@4 {
 				reg = <0x4 0x2>;
 			};
-			monotonic_otp: monotonic_otp@10 {
+			monotonic_otp: monotonic-otp@10 {
 				reg = <0x10 0x4>;
 			};
-			nand_otp: cfg9_otp@24 {
+			nand_otp: cfg9-otp@24 {
 				reg = <0x24 0x4>;
 			};
-			nand2_otp: cfg10_otp@28 {
+			nand2_otp: cfg10-otp@28 {
 				reg = <0x28 0x4>;
 			};
-			uid_otp: uid_otp@34 {
+			uid_otp: uid-otp@34 {
 				reg = <0x34 0xc>;
 			};
-			hw2_otp: hw2_otp@48 {
+			hw2_otp: hw2-otp@48 {
 				reg = <0x48 0x4>;
 			};
 			ts_cal1: calib@5c {
@@ -447,14 +447,14 @@
 			ts_cal2: calib@5e {
 				reg = <0x5e 0x2>;
 			};
-			pkh_otp: pkh_otp@60 {
+			pkh_otp: pkh-otp@60 {
 				reg = <0x60 0x20>;
 			};
-			mac_addr: mac_addr@e4 {
+			mac_addr: mac@e4 {
 				reg = <0xe4 0xc>;
 				st,non-secure-otp;
 			};
-			enckey_otp: enckey_otp@170 {
+			oem_enc_key: oem-enc-key@170 {
 				reg = <0x170 0x10>;
 			};
 		};
diff --git a/fdts/stm32mp135f-dk.dts b/fdts/stm32mp135f-dk.dts
index 1204692..7a7d461 100644
--- a/fdts/stm32mp135f-dk.dts
+++ b/fdts/stm32mp135f-dk.dts
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
 /*
- * Copyright (C) STMicroelectronics 2022 - All Rights Reserved
+ * Copyright (C) 2022-2024, STMicroelectronics - All Rights Reserved
  * Author: Alexandre Torgue <alexandre.torgue@foss.st.com> for STMicroelectronics.
  */
 
@@ -50,7 +50,7 @@
 };
 
 &bsec {
-	board_id: board_id@f0 {
+	board_id: board-id@f0 {
 		reg = <0xf0 0x4>;
 		st,non-secure-otp;
 	};
diff --git a/fdts/stm32mp151.dtsi b/fdts/stm32mp151.dtsi
index 7a22a1c..449ddbb 100644
--- a/fdts/stm32mp151.dtsi
+++ b/fdts/stm32mp151.dtsi
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
 /*
- * Copyright (c) 2017-2023, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2017-2024, STMicroelectronics - All Rights Reserved
  * Author: Ludovic Barre <ludovic.barre@st.com> for STMicroelectronics.
  */
 #include <dt-bindings/interrupt-controller/arm-gic.h>
@@ -458,25 +458,25 @@
 			#address-cells = <1>;
 			#size-cells = <1>;
 
-			cfg0_otp: cfg0_otp@0 {
+			cfg0_otp: cfg0-otp@0 {
 				reg = <0x0 0x1>;
 			};
 			part_number_otp: part-number-otp@4 {
 				reg = <0x4 0x1>;
 			};
-			monotonic_otp: monotonic_otp@10 {
+			monotonic_otp: monotonic-otp@10 {
 				reg = <0x10 0x4>;
 			};
-			nand_otp: nand_otp@24 {
+			nand_otp: nand-otp@24 {
 				reg = <0x24 0x4>;
 			};
-			uid_otp: uid_otp@34 {
+			uid_otp: uid-otp@34 {
 				reg = <0x34 0xc>;
 			};
-			package_otp: package_otp@40 {
+			package_otp: package-otp@40 {
 				reg = <0x40 0x4>;
 			};
-			hw2_otp: hw2_otp@48 {
+			hw2_otp: hw2-otp@48 {
 				reg = <0x48 0x4>;
 			};
 			ts_cal1: calib@5c {
@@ -485,10 +485,10 @@
 			ts_cal2: calib@5e {
 				reg = <0x5e 0x2>;
 			};
-			pkh_otp: pkh_otp@60 {
+			pkh_otp: pkh-otp@60 {
 				reg = <0x60 0x20>;
 			};
-			mac_addr: mac_addr@e4 {
+			ethernet_mac_address: mac@e4 {
 				reg = <0xe4 0x8>;
 				st,non-secure-otp;
 			};
diff --git a/fdts/stm32mp157c-ed1.dts b/fdts/stm32mp157c-ed1.dts
index 949c929..d7bcc84 100644
--- a/fdts/stm32mp157c-ed1.dts
+++ b/fdts/stm32mp157c-ed1.dts
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
 /*
- * Copyright (c) 2017-2023, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2017-2024, STMicroelectronics - All Rights Reserved
  * Author: Ludovic Barre <ludovic.barre@st.com> for STMicroelectronics.
  */
 /dts-v1/;
@@ -31,7 +31,7 @@
 };
 
 &bsec {
-	board_id: board_id@ec {
+	board_id: board-id@ec {
 		reg = <0xec 0x4>;
 		st,non-secure-otp;
 	};
diff --git a/fdts/stm32mp157c-odyssey-som.dtsi b/fdts/stm32mp157c-odyssey-som.dtsi
index 091e327..a0be718 100644
--- a/fdts/stm32mp157c-odyssey-som.dtsi
+++ b/fdts/stm32mp157c-odyssey-som.dtsi
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019, STMicroelectronics. All Rights Reserved.
+ * Copyright (C) 2019-2024, STMicroelectronics. All Rights Reserved.
  * Copyright (C) 2021, Grzegorz Szymaszek.
  *
  * SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-3-Clause)
@@ -28,7 +28,7 @@
 };
 
 &bsec {
-	board_id: board_id@ec {
+	board_id: board-id@ec {
 		reg = <0xec 0x4>;
 		st,non-secure-otp;
 	};
diff --git a/fdts/stm32mp15xx-dhcom-som.dtsi b/fdts/stm32mp15xx-dhcom-som.dtsi
index 7737a44..5138868 100644
--- a/fdts/stm32mp15xx-dhcom-som.dtsi
+++ b/fdts/stm32mp15xx-dhcom-som.dtsi
@@ -2,7 +2,7 @@
 /*
  * Copyright (C) 2019-2020 Marek Vasut <marex@denx.de>
  * Copyright (C) 2022 DH electronics GmbH
- * Copyright (C) 2023, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2023-2024, STMicroelectronics - All Rights Reserved
  */
 
 #include "stm32mp15-pinctrl.dtsi"
@@ -18,7 +18,7 @@
 };
 
 &bsec {
-	board_id: board_id@ec {
+	board_id: board-id@ec {
 		reg = <0xec 0x4>;
 		st,non-secure-otp;
 	};
diff --git a/fdts/stm32mp15xx-dkx.dtsi b/fdts/stm32mp15xx-dkx.dtsi
index f8baa9d..d8b7c48 100644
--- a/fdts/stm32mp15xx-dkx.dtsi
+++ b/fdts/stm32mp15xx-dkx.dtsi
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
 /*
- * Copyright (c) 2019-2022, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2019-2024, STMicroelectronics - All Rights Reserved
  * Author: Alexandre Torgue <alexandre.torgue@st.com> for STMicroelectronics.
  */
 
@@ -29,7 +29,7 @@
 };
 
 &bsec {
-	board_id: board_id@ec {
+	board_id: board-id@ec {
 		reg = <0xec 0x4>;
 		st,non-secure-otp;
 	};
diff --git a/fdts/stm32mp15xx-osd32.dtsi b/fdts/stm32mp15xx-osd32.dtsi
index 52a5d38..ef4c3c0 100644
--- a/fdts/stm32mp15xx-osd32.dtsi
+++ b/fdts/stm32mp15xx-osd32.dtsi
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-3-Clause) */
 /*
- * Copyright (C) 2020 STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2020-2024 STMicroelectronics - All Rights Reserved
  * Copyright (C) 2020 Ahmad Fatoum, Pengutronix
  */
 
@@ -157,7 +157,7 @@
 };
 
 &bsec {
-	board_id: board_id@ec {
+	board_id: board-id@ec {
 		reg = <0xec 0x4>;
 		st,non-secure-otp;
 	};
diff --git a/fdts/stm32mp251.dtsi b/fdts/stm32mp251.dtsi
index f55a3b9..6e262bb 100644
--- a/fdts/stm32mp251.dtsi
+++ b/fdts/stm32mp251.dtsi
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-3-Clause)
 /*
- * Copyright (C) 2023, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2023-2024, STMicroelectronics - All Rights Reserved
  * Author: Alexandre Torgue <alexandre.torgue@foss.st.com> for STMicroelectronics.
  */
 
@@ -99,6 +99,41 @@
 			};
 		};
 
+		bsec: efuse@44000000 {
+			compatible = "st,stm32mp25-bsec";
+			reg = <0x44000000 0x400>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			uid_otp: uid-otp@14 {
+				reg = <0x14 0xc>;
+			};
+			part_number_otp: part-number-otp@24 {
+				reg = <0x24 0x4>;
+			};
+			nand_otp: otp16@40 {
+				reg = <0x40 0x4>;
+			};
+			lifecycle2_otp: otp18@48 {
+				reg = <0x48 0x4>;
+			};
+			nand2_otp: otp20@50 {
+				reg = <0x50 0x4>;
+			};
+			package_otp: package-otp@1e8 {
+				reg = <0x1e8 0x1>;
+			};
+			hconf1_otp: otp124@1f0 {
+				reg = <0x1f0 0x4>;
+			};
+			pkh_otp: otp144@240 {
+				reg = <0x240 0x20>;
+			};
+			oem_fip_enc_key: otp260@410 {
+				reg = <0x410 0x20>;
+			};
+		};
+
 		rcc: rcc@44200000 {
 			compatible = "st,stm32mp25-rcc";
 			reg = <0x44200000 0x10000>;
diff --git a/fdts/stm32mp257f-ev1.dts b/fdts/stm32mp257f-ev1.dts
index b7e92e4..09e83d8 100644
--- a/fdts/stm32mp257f-ev1.dts
+++ b/fdts/stm32mp257f-ev1.dts
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-3-Clause)
 /*
- * Copyright (C) 2023, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2023-2024, STMicroelectronics - All Rights Reserved
  * Author: Alexandre Torgue <alexandre.torgue@foss.st.com> for STMicroelectronics.
  */
 
@@ -29,6 +29,12 @@
 	};
 };
 
+&bsec {
+	board_id: board-id@3d8 {
+		reg = <0x3d8 0x4>;
+	};
+};
+
 &usart2 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&usart2_pins_a>;
diff --git a/fdts/cot_descriptors.dtsi b/fdts/tbbr_cot_descriptors.dtsi
similarity index 99%
rename from fdts/cot_descriptors.dtsi
rename to fdts/tbbr_cot_descriptors.dtsi
index 411bae6..ac39e4e 100644
--- a/fdts/cot_descriptors.dtsi
+++ b/fdts/tbbr_cot_descriptors.dtsi
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, ARM Limited. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/include/drivers/cadence/cdns_nand.h b/include/drivers/cadence/cdns_nand.h
index 64ba267..f20627b 100644
--- a/include/drivers/cadence/cdns_nand.h
+++ b/include/drivers/cadence/cdns_nand.h
@@ -198,6 +198,7 @@
 #define CNF_OPR_WORK_MODE_RES				3
 
 /* Mini controller common settings register field offsets */
+#define CNF_CMN_SETTINGS_OPR_MASK			0x00000003
 #define CNF_CMN_SETTINGS_WR_WUP				20
 #define CNF_CMN_SETTINGS_RD_WUP				16
 #define CNF_CMN_SETTINGS_DEV16				8
diff --git a/include/drivers/st/bsec.h b/include/drivers/st/bsec.h
index 60dcf3c..4a1517a 100644
--- a/include/drivers/st/bsec.h
+++ b/include/drivers/st/bsec.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2022, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2017-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,13 +13,6 @@
 #include <lib/utils_def.h>
 
 /*
- * IP configuration
- */
-#define BSEC_OTP_MASK			GENMASK(4, 0)
-#define BSEC_OTP_BANK_SHIFT		5
-#define BSEC_TIMEOUT_VALUE		0xFFFF
-
-/*
  * Return status
  */
 #define BSEC_OK				0U
@@ -32,98 +25,49 @@
 #define BSEC_RETRY			0xFFFFFFF8U
 #define BSEC_NOT_SUPPORTED		0xFFFFFFF7U
 #define BSEC_WRITE_LOCKED		0xFFFFFFF6U
-#define BSEC_ERROR_INVALID_FVR		0xFFFFFFF5U
-
-/*
- * OTP MODE
- */
-#define BSEC_MODE_OPEN1			0x00U
-#define BSEC_MODE_SECURED		0x01U
-#define BSEC_MODE_OPEN2			0x02U
-#define BSEC_MODE_INVALID		0x04U
-
-/*
- * OTP Lock services definition.
- * Value must corresponding to the bit number in the register.
- * Special case: (bit number << 1) for BSEC3.
- */
-#define BSEC_LOCK_UPPER_OTP		0x00
-#define BSEC_LOCK_GWLOCK		0x01
-#define BSEC_LOCK_DEBUG			0x02
-#define BSEC_LOCK_PROGRAM		0x03
-#define BSEC_LOCK_KVLOCK		0x04
 
 /*
- * Values for struct bsec_config::freq
+ * get BSEC global state: result for bsec_get_secure_state()
+ * @state: global state
+ *           [1:0] BSEC state
+ *             00b: Sec Open
+ *             01b: Sec Closed
+ *             11b: Invalid
+ *           [8]: Hardware Key set = 1b
  */
-#define FREQ_10_20_MHZ			0x0
-#define FREQ_20_30_MHZ			0x1
-#define FREQ_30_45_MHZ			0x2
-#define FREQ_45_67_MHZ			0x3
-
-/*
- * Device info structure, providing device-specific functions and a means of
- * adding driver-specific state.
- */
-struct bsec_config {
-	uint8_t den_lock;	/*
-				 * Debug enable sticky lock
-				 * 1 debug enable is locked until next reset
-				 */
-
-	/*  BSEC2 only */
-	uint8_t tread;		/* SAFMEM Reading current level default 0 */
-	uint8_t pulse_width;	/* SAFMEM Programming pulse width default 1 */
-	uint8_t freq;		/*
-				 * SAFMEM CLOCK see freq value define
-				 * default FREQ_45_67_MHZ
-				 */
-	uint8_t power;		/* Power up SAFMEM. 1 power up, 0 power off */
-	uint8_t prog_lock;	/*
-				 * Programming Sticky lock
-				 * 1 programming is locked until next reset
-				 */
-	uint8_t upper_otp_lock;	/*
-				 * Shadowing of upper OTP sticky lock
-				 * 1 shadowing of upper OTP is locked
-				 * until next reset
-				 */
-};
+#define BSEC_STATE_SEC_OPEN		U(0x0)
+#define BSEC_STATE_SEC_CLOSED		U(0x1)
+#define BSEC_STATE_INVALID		U(0x3)
+#define BSEC_STATE_MASK			GENMASK_32(1, 0)
 
 uint32_t bsec_probe(void);
-uint32_t bsec_get_base(void);
 
-uint32_t bsec_set_config(struct bsec_config *cfg);
-uint32_t bsec_get_config(struct bsec_config *cfg);
-
-uint32_t bsec_shadow_register(uint32_t otp);
 uint32_t bsec_read_otp(uint32_t *val, uint32_t otp);
+uint32_t bsec_shadow_read_otp(uint32_t *val, uint32_t otp);
 uint32_t bsec_write_otp(uint32_t val, uint32_t otp);
 uint32_t bsec_program_otp(uint32_t val, uint32_t otp);
-uint32_t bsec_permanent_lock_otp(uint32_t otp);
 
-void bsec_write_debug_conf(uint32_t val);
 uint32_t bsec_read_debug_conf(void);
 
 void bsec_write_scratch(uint32_t val);
-uint32_t bsec_read_scratch(void);
-
-uint32_t bsec_get_status(void);
-uint32_t bsec_get_hw_conf(void);
-uint32_t bsec_get_version(void);
-uint32_t bsec_get_id(void);
-uint32_t bsec_get_magic_id(void);
 
+/* Sticky lock support */
 uint32_t bsec_set_sr_lock(uint32_t otp);
 uint32_t bsec_read_sr_lock(uint32_t otp, bool *value);
 uint32_t bsec_set_sw_lock(uint32_t otp);
 uint32_t bsec_read_sw_lock(uint32_t otp, bool *value);
 uint32_t bsec_set_sp_lock(uint32_t otp);
 uint32_t bsec_read_sp_lock(uint32_t otp, bool *value);
-uint32_t bsec_read_permanent_lock(uint32_t otp, bool *value);
-uint32_t bsec_otp_lock(uint32_t service);
 
-uint32_t bsec_shadow_read_otp(uint32_t *otp_value, uint32_t word);
+uint32_t bsec_get_secure_state(void);
+static inline bool bsec_mode_is_closed_device(void)
+{
+	return (bsec_get_secure_state() & BSEC_STATE_MASK) == BSEC_STATE_SEC_CLOSED;
+}
+
+#if defined(IMAGE_BL32)
+uint32_t bsec_permanent_lock_otp(uint32_t otp);
 uint32_t bsec_check_nsec_access_rights(uint32_t otp);
+#endif
 
 #endif /* BSEC_H */
diff --git a/include/drivers/st/bsec2_reg.h b/include/drivers/st/bsec2_reg.h
index f895020..fa44cf1 100644
--- a/include/drivers/st/bsec2_reg.h
+++ b/include/drivers/st/bsec2_reg.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2022-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -80,22 +80,17 @@
 #define GPLOCK_LOCK_SHIFT		4
 
 /* BSEC_OTP_STATUS Register */
-#define BSEC_MODE_STATUS_MASK		GENMASK(2, 0)
-#define BSEC_MODE_SECURE_MASK		BIT(0)
-#define BSEC_MODE_FULLDBG_MASK		BIT(1)
-#define BSEC_MODE_INVALID_MASK		BIT(2)
-#define BSEC_MODE_BUSY_MASK		BIT(3)
-#define BSEC_MODE_PROGFAIL_MASK		BIT(4)
-#define BSEC_MODE_PWR_MASK		BIT(5)
-#define BSEC_MODE_BIST1_LOCK_MASK	BIT(6)
-#define BSEC_MODE_BIST2_LOCK_MASK	BIT(7)
+#define BSEC_OTP_STATUS_SECURE		BIT(0)
+#define BSEC_OTP_STATUS_INVALID		BIT(2)
+#define BSEC_OTP_STATUS_BUSY		BIT(3)
+#define BSEC_OTP_STATUS_PROGFAIL	BIT(4)
+#define BSEC_OTP_STATUS_PWRON		BIT(5)
 
 /* BSEC_DENABLE Register */
 #define BSEC_HDPEN			BIT(4)
 #define BSEC_SPIDEN			BIT(5)
 #define BSEC_SPINDEN			BIT(6)
 #define BSEC_DBGSWGEN			BIT(10)
-#define BSEC_DEN_ALL_MSK		GENMASK(10, 0)
 
 /* BSEC_FENABLE Register */
 #define BSEC_FEN_ALL_MSK		GENMASK(14, 0)
diff --git a/include/services/ffa_svc.h b/include/services/ffa_svc.h
index 9ed6a8b..01dbea9 100644
--- a/include/services/ffa_svc.h
+++ b/include/services/ffa_svc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -24,7 +24,7 @@
 
 /* The macros below are used to identify FFA calls from the SMC function ID */
 #define FFA_FNUM_MIN_VALUE	U(0x60)
-#define FFA_FNUM_MAX_VALUE	U(0x8C)
+#define FFA_FNUM_MAX_VALUE	U(0x8E)
 #define is_ffa_fid(fid) __extension__ ({		\
 	__typeof__(fid) _fid = (fid);			\
 	((GET_SMC_NUM(_fid) >= FFA_FNUM_MIN_VALUE) &&	\
@@ -123,6 +123,10 @@
 /* FF-A v1.2 */
 #define FFA_FNUM_PARTITION_INFO_GET_REGS	U(0x8B)
 #define FFA_FNUM_EL3_INTR_HANDLE		U(0x8C)
+#define FFA_FNUM_MSG_SEND_DIRECT_REQ2		U(0x8D)
+#define FFA_FNUM_MSG_SEND_DIRECT_RESP2		U(0x8E)
+
+#define FFA_FNUM_CONSOLE_LOG			U(0x8A)
 
 /* FFA SMC32 FIDs */
 #define FFA_ERROR		FFA_FID(SMC_32, FFA_FNUM_ERROR)
@@ -171,6 +175,7 @@
 #define FFA_EL3_INTR_HANDLE	FFA_FID(SMC_32, FFA_FNUM_EL3_INTR_HANDLE)
 #define FFA_MEM_PERM_GET	FFA_FID(SMC_32, FFA_FNUM_MEM_PERM_GET)
 #define FFA_MEM_PERM_SET	FFA_FID(SMC_32, FFA_FNUM_MEM_PERM_SET)
+#define FFA_CONSOLE_LOG_SMC32 FFA_FID(SMC_32, FFA_FNUM_CONSOLE_LOG)
 
 /* FFA SMC64 FIDs */
 #define FFA_ERROR_SMC64		FFA_FID(SMC_64, FFA_FNUM_ERROR)
@@ -191,6 +196,11 @@
 	FFA_FID(SMC_64, FFA_FNUM_NOTIFICATION_INFO_GET)
 #define FFA_PARTITION_INFO_GET_REGS_SMC64 \
 	FFA_FID(SMC_64, FFA_FNUM_PARTITION_INFO_GET_REGS)
+#define FFA_CONSOLE_LOG_SMC64 FFA_FID(SMC_64, FFA_FNUM_CONSOLE_LOG)
+#define FFA_MSG_SEND_DIRECT_REQ2_SMC64 \
+	FFA_FID(SMC_64, FFA_FNUM_MSG_SEND_DIRECT_REQ2)
+#define FFA_MSG_SEND_DIRECT_RESP2_SMC64	\
+	FFA_FID(SMC_64, FFA_FNUM_MSG_SEND_DIRECT_RESP2)
 
 /*
  * FF-A partition properties values.
diff --git a/lib/fconf/fconf_cot_getter.c b/lib/fconf/fconf_cot_getter.c
index 1033018..b9bc9de 100644
--- a/lib/fconf/fconf_cot_getter.c
+++ b/lib/fconf/fconf_cot_getter.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -237,13 +237,17 @@
 	 * verified by signature and images are verified by hash.
 	 */
 	if (type == IMG_CERT) {
-		if (root_certificate) {
-			oid = NULL;
-		} else {
-			rc = get_oid(dtb, node, "signing-key", &oid);
-			if (rc < 0) {
+		rc = get_oid(dtb, node, "signing-key", &oid);
+		if (rc < 0) {
+			/*
+			 * The signing-key property is optional in root
+			 * certificates, mandatory otherwise.
+			 */
+			if (root_certificate) {
+				oid = NULL;
+			} else {
 				ERROR("FCONF: Can't read %s property\n",
-					"signing-key");
+						"signing-key");
 				return rc;
 			}
 		}
diff --git a/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts b/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts
index 6ba76db..9eb2177 100644
--- a/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts
+++ b/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2023, ARM Limited. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -104,7 +104,11 @@
 	};
 
 #if COT_DESC_IN_DTB
-	#include "cot_descriptors.dtsi"
+	#if defined(ARM_COT_cca)
+		#include "cca_cot_descriptors.dtsi"
+	#elif defined(ARM_COT_tbbr)
+		#include "tbbr_cot_descriptors.dtsi"
+	#endif
 #endif
 
 #if MEASURED_BOOT
@@ -117,6 +121,13 @@
 
 #include "../fvp_def.h"
 
+#if defined(ARM_COT_cca)
+/* FVP does not support the CCA NV Counter so use the Trusted one. */
+&cca_nv_counter {
+	reg = <TFW_NVCTR_BASE>;
+};
+#endif
+
 &trusted_nv_counter {
 	reg = <TFW_NVCTR_BASE>;
 };
diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk
index ae0d85d..5084ea9 100644
--- a/plat/arm/common/arm_common.mk
+++ b/plat/arm/common/arm_common.mk
@@ -383,7 +383,12 @@
     else ifeq (${COT},dualroot)
         AUTH_SOURCES	+=	drivers/auth/dualroot/cot.c
     else ifeq (${COT},cca)
-        AUTH_SOURCES	+=	drivers/auth/cca/cot.c
+        BL1_SOURCES	+=	drivers/auth/cca/cot.c
+        ifneq (${COT_DESC_IN_DTB},0)
+            BL2_SOURCES	+=	lib/fconf/fconf_cot_getter.c
+        else
+            BL2_SOURCES	+=	drivers/auth/cca/cot.c
+        endif
     else
         $(error Unknown chain of trust ${COT})
     endif
diff --git a/plat/intel/soc/agilex/bl2_plat_setup.c b/plat/intel/soc/agilex/bl2_plat_setup.c
index 211a7b7..61c0ef2 100644
--- a/plat/intel/soc/agilex/bl2_plat_setup.c
+++ b/plat/intel/soc/agilex/bl2_plat_setup.c
@@ -28,6 +28,7 @@
 #include "socfpga_mailbox.h"
 #include "socfpga_private.h"
 #include "socfpga_reset_manager.h"
+#include "socfpga_ros.h"
 #include "socfpga_system_manager.h"
 #include "wdt/watchdog.h"
 
@@ -92,6 +93,7 @@
 void bl2_el3_plat_arch_setup(void)
 {
 
+	unsigned long offset = 0;
 	const mmap_region_t bl_regions[] = {
 		MAP_REGION_FLAT(BL2_BASE, BL2_END - BL2_BASE,
 			MT_MEMORY | MT_RW | MT_SECURE),
@@ -123,14 +125,17 @@
 	switch (boot_source) {
 	case BOOT_SOURCE_SDMMC:
 		dw_mmc_init(&params, &mmc_info);
-		socfpga_io_setup(boot_source);
+		socfpga_io_setup(boot_source, PLAT_SDMMC_DATA_BASE);
 		break;
 
 	case BOOT_SOURCE_QSPI:
 		cad_qspi_init(0, QSPI_CONFIG_CPHA, QSPI_CONFIG_CPOL,
 			QSPI_CONFIG_CSDA, QSPI_CONFIG_CSDADS,
 			QSPI_CONFIG_CSEOT, QSPI_CONFIG_CSSOT, 0);
-		socfpga_io_setup(boot_source);
+		if (ros_qspi_get_ssbl_offset(&offset) != ROS_RET_OK) {
+			offset = PLAT_QSPI_DATA_BASE;
+		}
+		socfpga_io_setup(boot_source, offset);
 		break;
 
 	default:
diff --git a/plat/intel/soc/agilex/platform.mk b/plat/intel/soc/agilex/platform.mk
index f81480d..6780845 100644
--- a/plat/intel/soc/agilex/platform.mk
+++ b/plat/intel/soc/agilex/platform.mk
@@ -47,6 +47,7 @@
 		plat/intel/soc/agilex/soc/agilex_pinmux.c		\
 		plat/intel/soc/common/bl2_plat_mem_params_desc.c	\
 		plat/intel/soc/common/socfpga_image_load.c		\
+		plat/intel/soc/common/socfpga_ros.c			\
 		plat/intel/soc/common/socfpga_storage.c			\
 		plat/intel/soc/common/soc/socfpga_emac.c		\
 		plat/intel/soc/common/soc/socfpga_firewall.c	\
@@ -77,6 +78,8 @@
 		plat/intel/soc/common/soc/socfpga_mailbox.c		\
 		plat/intel/soc/common/soc/socfpga_reset_manager.c
 
+$(eval $(call add_define,ARM_PRELOADED_DTB_BASE))
+
 PROGRAMMABLE_RESET_ADDRESS	:= 0
 RESET_TO_BL2			:= 1
 BL2_INV_DCACHE			:= 0
diff --git a/plat/intel/soc/agilex5/bl2_plat_setup.c b/plat/intel/soc/agilex5/bl2_plat_setup.c
index 5c15148..c74d799 100644
--- a/plat/intel/soc/agilex5/bl2_plat_setup.c
+++ b/plat/intel/soc/agilex5/bl2_plat_setup.c
@@ -34,6 +34,7 @@
 #include "socfpga_mailbox.h"
 #include "socfpga_private.h"
 #include "socfpga_reset_manager.h"
+#include "socfpga_ros.h"
 #include "wdt/watchdog.h"
 
 
@@ -96,6 +97,7 @@
 void bl2_el3_plat_arch_setup(void)
 {
 	handoff reverse_handoff_ptr;
+	unsigned long offset = 0;
 
 	struct cdns_sdmmc_params params = EMMC_INIT_PARAMS((uintptr_t) &cdns_desc, get_mmc_clk());
 
@@ -109,7 +111,7 @@
 	case BOOT_SOURCE_SDMMC:
 		NOTICE("SDMMC boot\n");
 		sdmmc_init(&reverse_handoff_ptr, &params, &mmc_info);
-		socfpga_io_setup(boot_source);
+		socfpga_io_setup(boot_source, PLAT_SDMMC_DATA_BASE);
 		break;
 
 	case BOOT_SOURCE_QSPI:
@@ -117,13 +119,16 @@
 		cad_qspi_init(0, QSPI_CONFIG_CPHA, QSPI_CONFIG_CPOL,
 			QSPI_CONFIG_CSDA, QSPI_CONFIG_CSDADS,
 			QSPI_CONFIG_CSEOT, QSPI_CONFIG_CSSOT, 0);
-		socfpga_io_setup(boot_source);
+		if (ros_qspi_get_ssbl_offset(&offset) != ROS_RET_OK) {
+			offset = PLAT_QSPI_DATA_BASE;
+		}
+		socfpga_io_setup(boot_source, offset);
 		break;
 
 	case BOOT_SOURCE_NAND:
 		NOTICE("NAND boot\n");
 		nand_init(&reverse_handoff_ptr);
-		socfpga_io_setup(boot_source);
+		socfpga_io_setup(boot_source, PLAT_NAND_DATA_BASE);
 		break;
 
 	default:
diff --git a/plat/intel/soc/agilex5/include/socfpga_plat_def.h b/plat/intel/soc/agilex5/include/socfpga_plat_def.h
index 1ce1cff..acdbe17 100644
--- a/plat/intel/soc/agilex5/include/socfpga_plat_def.h
+++ b/plat/intel/soc/agilex5/include/socfpga_plat_def.h
@@ -56,7 +56,7 @@
 #define SOCFPGA_LWSOC2FPGA_SCR_REG_BASE				0x10d21300
 
 /* Define maximum page size for NAND flash devices */
-#define PLATFORM_MTD_MAX_PAGE_SIZE				U(0x1000)
+#define PLATFORM_MTD_MAX_PAGE_SIZE				U(0x2000)
 
 /*******************************************************************************
  * Platform memory map related constants
diff --git a/plat/intel/soc/agilex5/platform.mk b/plat/intel/soc/agilex5/platform.mk
index b42253b..7302164 100644
--- a/plat/intel/soc/agilex5/platform.mk
+++ b/plat/intel/soc/agilex5/platform.mk
@@ -60,6 +60,7 @@
 		plat/intel/soc/agilex5/soc/agilex5_power_manager.c	\
 		plat/intel/soc/common/bl2_plat_mem_params_desc.c	\
 		plat/intel/soc/common/socfpga_image_load.c		\
+		plat/intel/soc/common/socfpga_ros.c			\
 		plat/intel/soc/common/socfpga_storage.c			\
 		plat/intel/soc/common/socfpga_vab.c				\
 		plat/intel/soc/common/soc/socfpga_emac.c		\
@@ -100,6 +101,10 @@
 CTX_INCLUDE_AARCH32_REGS := 0
 ERRATA_A55_1530923 := 1
 
+# Don't have the Linux kernel as a BL33 image by default
+ARM_LINUX_KERNEL_AS_BL33	:=	0
+$(eval $(call assert_boolean,ARM_LINUX_KERNEL_AS_BL33))
+$(eval $(call add_define,ARM_LINUX_KERNEL_AS_BL33))
 $(eval $(call add_define,ARM_PRELOADED_DTB_BASE))
 
 PROGRAMMABLE_RESET_ADDRESS	:= 0
diff --git a/plat/intel/soc/common/bl2_plat_mem_params_desc.c b/plat/intel/soc/common/bl2_plat_mem_params_desc.c
index 187c53a..a09fb70 100644
--- a/plat/intel/soc/common/bl2_plat_mem_params_desc.c
+++ b/plat/intel/soc/common/bl2_plat_mem_params_desc.c
@@ -88,9 +88,27 @@
 		.image_info.image_base = PLAT_NS_IMAGE_OFFSET,
 		.image_info.image_max_size =
 			0x0 + 0x40000000 - PLAT_NS_IMAGE_OFFSET,
+# if ARM_LINUX_KERNEL_AS_BL33 != 0
+		.next_handoff_image_id = NT_FW_CONFIG_ID,
+	},
+
+	{
+		.image_id = NT_FW_CONFIG_ID,
+		SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY,
+			VERSION_2, entry_point_info_t,
+			NON_SECURE | NON_EXECUTABLE),
+		SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
+			VERSION_2, image_info_t, 0),
+		.image_info.image_base = ARM_PRELOADED_DTB_BASE,
+		.image_info.image_max_size =
+			0x0 + 0x40000000 - ARM_PRELOADED_DTB_BASE,
 
 		.next_handoff_image_id = INVALID_IMAGE_ID,
 	},
+#else
+	.next_handoff_image_id = INVALID_IMAGE_ID,
+	},
+# endif
 };
 
 REGISTER_BL_IMAGE_DESCS(bl2_mem_params_descs)
diff --git a/plat/intel/soc/common/drivers/nand/nand.c b/plat/intel/soc/common/drivers/nand/nand.c
index c6acbe3..7fd955a 100644
--- a/plat/intel/soc/common/drivers/nand/nand.c
+++ b/plat/intel/soc/common/drivers/nand/nand.c
@@ -38,18 +38,12 @@
 	mmio_write_32(SOCFPGA_PINMUX(PIN12SEL), SOCFPGA_PINMUX_SEL_NAND);
 	mmio_write_32(SOCFPGA_PINMUX(PIN13SEL), SOCFPGA_PINMUX_SEL_NAND);
 	mmio_write_32(SOCFPGA_PINMUX(PIN14SEL), SOCFPGA_PINMUX_SEL_NAND);
-	mmio_write_32(SOCFPGA_PINMUX(PIN16SEL), SOCFPGA_PINMUX_SEL_NAND);
-	mmio_write_32(SOCFPGA_PINMUX(PIN17SEL), SOCFPGA_PINMUX_SEL_NAND);
-	mmio_write_32(SOCFPGA_PINMUX(PIN18SEL), SOCFPGA_PINMUX_SEL_NAND);
-	mmio_write_32(SOCFPGA_PINMUX(PIN19SEL), SOCFPGA_PINMUX_SEL_NAND);
-	mmio_write_32(SOCFPGA_PINMUX(PIN20SEL), SOCFPGA_PINMUX_SEL_NAND);
-	mmio_write_32(SOCFPGA_PINMUX(PIN21SEL), SOCFPGA_PINMUX_SEL_NAND);
-	mmio_write_32(SOCFPGA_PINMUX(PIN22SEL), SOCFPGA_PINMUX_SEL_NAND);
-	mmio_write_32(SOCFPGA_PINMUX(PIN23SEL), SOCFPGA_PINMUX_SEL_NAND);
 }
 
 int nand_init(handoff *hoff_ptr)
 {
+	(void)(hoff_ptr);
+
 	/* NAND pin mux configuration */
 	nand_pinmux_config();
 
diff --git a/plat/intel/soc/common/include/platform_def.h b/plat/intel/soc/common/include/platform_def.h
index 49fc567..1946898 100644
--- a/plat/intel/soc/common/include/platform_def.h
+++ b/plat/intel/soc/common/include/platform_def.h
@@ -44,6 +44,10 @@
 #define PLAT_HANDOFF_OFFSET			0xFFE3F000
 #endif
 
+#define PLAT_QSPI_DATA_BASE			(0x3C00000)
+#define PLAT_NAND_DATA_BASE			(0x0200000)
+#define PLAT_SDMMC_DATA_BASE			(0x0)
+
 /*******************************************************************************
  * Platform binary types for linking
  ******************************************************************************/
diff --git a/plat/intel/soc/common/include/socfpga_private.h b/plat/intel/soc/common/include/socfpga_private.h
index 242dd73..041c282 100644
--- a/plat/intel/soc/common/include/socfpga_private.h
+++ b/plat/intel/soc/common/include/socfpga_private.h
@@ -33,7 +33,7 @@
 
 void enable_nonsecure_access(void);
 
-void socfpga_io_setup(int boot_source);
+void socfpga_io_setup(int boot_source, unsigned long offset);
 
 void socfgpa_configure_mmu_el3(unsigned long total_base,
 			unsigned long total_size,
diff --git a/plat/intel/soc/common/include/socfpga_ros.h b/plat/intel/soc/common/include/socfpga_ros.h
new file mode 100644
index 0000000..10cabd3
--- /dev/null
+++ b/plat/intel/soc/common/include/socfpga_ros.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2024, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SOCFPGA_ROS_H
+#define SOCFPGA_ROS_H
+
+#include <arch_helpers.h>
+#include <lib/utils_def.h>
+
+/** status response*/
+#define ROS_RET_OK			(0x00U)
+#define ROS_RET_INVALID			(0x01U)
+#define ROS_RET_NOT_RSU_MODE		(0x02U)
+#define ROS_QSPI_READ_ERROR		(0x03U)
+#define ROS_SPT_BAD_MAGIC_NUM		(0x04U)
+#define ROS_SPT_CRC_ERROR		(0x05U)
+#define ROS_IMAGE_INDEX_ERR		(0x06U)
+#define ROS_IMAGE_PARTNUM_OVFL		(0x07U)
+
+#define ADDR_64(h, l)			(((((unsigned long)(h)) & 0xffffffff) << 32) | \
+						(((unsigned long)(l)) & 0xffffffff))
+
+#define RSU_GET_SPT_RESP_SIZE		(4U)
+
+#define RSU_STATUS_RES_SIZE		(9U)
+
+#define SPT_MAGIC_NUMBER		(0x57713427U)
+#define SPT_VERSION			(0U)
+#define SPT_FLAG_RESERVED		(1U)
+#define SPT_FLAG_READONLY		(2U)
+
+#define SPT_MAX_PARTITIONS		(127U)
+#define SPT_PARTITION_NAME_LENGTH	(16U)
+#define SPT_RSVD_LENGTH			(4U)
+#define SPT_SIZE			(4096U)
+/*BOOT_INFO + FACTORY_IMAGE + SPT0 + SPT1 + CPB0 + CPB1 + FACTORY_IM.SSBL+ *APP* + *APP*.SSBL*/
+#define SPT_MIN_PARTITIONS		(9U)
+
+#define FACTORY_IMAGE			"FACTORY_IMAGE"
+#define FACTORY_SSBL			"FACTORY_IM.SSBL"
+#define SSBL_SUFFIX			".SSBL"
+
+typedef struct {
+	const uint32_t magic_number;
+	const uint32_t version;
+	const uint32_t partitions;
+	uint32_t checksum;
+	const uint32_t __RSVD[SPT_RSVD_LENGTH];
+	struct {
+		const char name[SPT_PARTITION_NAME_LENGTH];
+		const uint64_t offset;
+		const uint32_t length;
+		const uint32_t flags;
+	} partition[SPT_MAX_PARTITIONS];
+} __packed spt_table_t;
+
+uint32_t ros_qspi_get_ssbl_offset(unsigned long *offset);
+
+#endif /* SOCFPGA_ROS_H */
diff --git a/plat/intel/soc/common/socfpga_ros.c b/plat/intel/soc/common/socfpga_ros.c
new file mode 100644
index 0000000..ea37384
--- /dev/null
+++ b/plat/intel/soc/common/socfpga_ros.c
@@ -0,0 +1,188 @@
+/*
+ * Copyright (c) 2024, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/* system header files*/
+#include <assert.h>
+#include <endian.h>
+#include <string.h>
+
+/* CRC function header */
+#include <common/tf_crc32.h>
+
+/* Cadense qspi driver*/
+#include <qspi/cadence_qspi.h>
+
+/* Mailbox driver*/
+#include <socfpga_mailbox.h>
+
+#include <socfpga_ros.h>
+
+static void swap_bits(char *const data, uint32_t len)
+{
+	uint32_t x, y;
+	char tmp;
+
+	for (x = 0U; x < len; x++) {
+		tmp = 0U;
+		for (y = 0U; y < 8; y++) {
+			tmp <<= 1;
+			if (data[x] & 1) {
+				tmp |= 1;
+			}
+			data[x] >>= 1;
+		}
+		data[x] = tmp;
+	}
+}
+
+static uint32_t get_current_image_index(spt_table_t *spt_buf, uint32_t *const img_index)
+{
+	if (spt_buf == NULL || img_index == NULL) {
+		return ROS_RET_INVALID;
+	}
+
+	uint32_t ret;
+	unsigned long current_image;
+	uint32_t rsu_status[RSU_STATUS_RES_SIZE];
+
+	if (spt_buf->partitions < SPT_MIN_PARTITIONS || spt_buf->partitions > SPT_MAX_PARTITIONS) {
+		return ROS_IMAGE_PARTNUM_OVFL;
+	}
+
+	ret = mailbox_rsu_status(rsu_status, RSU_STATUS_RES_SIZE);
+	if (ret != MBOX_RET_OK) {
+		return ROS_RET_NOT_RSU_MODE;
+	}
+
+	current_image = ADDR_64(rsu_status[1], rsu_status[0]);
+	NOTICE("ROS: Current image is at 0x%08lx\n", current_image);
+
+	*img_index = 0U;
+	for (uint32_t index = 0U ; index < spt_buf->partitions; index++) {
+		if (spt_buf->partition[index].offset == current_image) {
+			*img_index = index;
+			break;
+		}
+	}
+
+	if (*img_index == 0U) {
+		return ROS_IMAGE_INDEX_ERR;
+	}
+
+	return ROS_RET_OK;
+}
+
+static uint32_t load_and_check_spt(spt_table_t *spt_ptr, size_t offset)
+{
+
+	if (spt_ptr == NULL || offset == 0U) {
+		return ROS_RET_INVALID;
+	}
+
+	int ret;
+	uint32_t calc_crc;
+	static spt_table_t spt_data;
+
+	ret = cad_qspi_read(spt_ptr, offset, SPT_SIZE);
+	if (ret != 0U) {
+		return ROS_QSPI_READ_ERROR;
+	}
+
+	if (spt_ptr->magic_number != SPT_MAGIC_NUMBER) {
+		return ROS_SPT_BAD_MAGIC_NUM;
+	}
+
+	if (spt_ptr->partitions < SPT_MIN_PARTITIONS || spt_ptr->partitions > SPT_MAX_PARTITIONS) {
+		return ROS_IMAGE_PARTNUM_OVFL;
+	}
+
+	memcpy_s(&spt_data, SPT_SIZE, spt_ptr, SPT_SIZE);
+	spt_data.checksum = 0U;
+	swap_bits((char *)&spt_data, SPT_SIZE);
+
+	calc_crc = tf_crc32(0, (uint8_t *)&spt_data, SPT_SIZE);
+	if (bswap32(spt_ptr->checksum) != calc_crc) {
+		return ROS_SPT_CRC_ERROR;
+	}
+
+	NOTICE("ROS: SPT table at 0x%08lx is verified\n", offset);
+	return ROS_RET_OK;
+}
+
+static uint32_t get_spt(spt_table_t *spt_buf)
+{
+	if (spt_buf == NULL) {
+		return ROS_RET_INVALID;
+	}
+
+	uint32_t ret;
+	uint32_t spt_offset[RSU_GET_SPT_RESP_SIZE];
+
+	/* Get SPT offset from SDM via mailbox commands */
+	ret = mailbox_rsu_get_spt_offset(spt_offset, RSU_GET_SPT_RESP_SIZE);
+	if (ret != MBOX_RET_OK) {
+		WARN("ROS: Not booted in RSU mode\n");
+		return ROS_RET_NOT_RSU_MODE;
+	}
+
+	/* Print the SPT table addresses */
+	VERBOSE("ROS: SPT0 0x%08lx\n", ADDR_64(spt_offset[0], spt_offset[1]));
+	VERBOSE("ROS: SPT1 0x%08lx\n", ADDR_64(spt_offset[2], spt_offset[3]));
+
+	/* Load and validate SPT1*/
+	ret = load_and_check_spt(spt_buf, ADDR_64(spt_offset[2], spt_offset[3]));
+	if (ret != ROS_RET_OK) {
+		/* Load and validate SPT0*/
+		ret = load_and_check_spt(spt_buf, ADDR_64(spt_offset[0], spt_offset[1]));
+		if (ret != ROS_RET_OK) {
+			WARN("Both SPT tables are unusable\n");
+			return ret;
+		}
+	}
+
+	return ROS_RET_OK;
+}
+
+uint32_t ros_qspi_get_ssbl_offset(unsigned long *offset)
+{
+	if (offset == NULL) {
+		return ROS_RET_INVALID;
+	}
+
+	uint32_t ret, img_index;
+	char ssbl_name[SPT_PARTITION_NAME_LENGTH];
+	static spt_table_t spt;
+
+	ret = get_spt(&spt);
+	if (ret != ROS_RET_OK) {
+		return ret;
+	}
+
+	ret = get_current_image_index(&spt, &img_index);
+	if (ret != ROS_RET_OK) {
+		return ret;
+	}
+
+	if (strncmp(spt.partition[img_index].name, FACTORY_IMAGE,
+		SPT_PARTITION_NAME_LENGTH) == 0U) {
+		strlcpy(ssbl_name, FACTORY_SSBL, SPT_PARTITION_NAME_LENGTH);
+	} else {
+		strlcpy(ssbl_name, spt.partition[img_index].name,
+			SPT_PARTITION_NAME_LENGTH);
+		strlcat(ssbl_name, SSBL_SUFFIX, SPT_PARTITION_NAME_LENGTH);
+	}
+
+	for (uint32_t index = 0U; index < spt.partitions; index++) {
+		if (strncmp(spt.partition[index].name, ssbl_name,
+			SPT_PARTITION_NAME_LENGTH) == 0U) {
+			*offset = spt.partition[index].offset;
+			NOTICE("ROS: Corresponding SSBL is at 0x%08lx\n", *offset);
+			return ROS_RET_OK;
+		}
+	}
+
+	return ROS_IMAGE_INDEX_ERR;
+}
diff --git a/plat/intel/soc/common/socfpga_storage.c b/plat/intel/soc/common/socfpga_storage.c
index e80f074..d250d9e 100644
--- a/plat/intel/soc/common/socfpga_storage.c
+++ b/plat/intel/soc/common/socfpga_storage.c
@@ -24,16 +24,13 @@
 
 #include "drivers/sdmmc/sdmmc.h"
 #include "socfpga_private.h"
+#include "socfpga_ros.h"
 
 
 #define PLAT_FIP_BASE		(0)
 #define PLAT_FIP_MAX_SIZE	(0x1000000)
 #define PLAT_MMC_DATA_BASE	(0xffe3c000)
 #define PLAT_MMC_DATA_SIZE	(0x2000)
-#define PLAT_QSPI_DATA_BASE	(0x3C00000)
-#define PLAT_QSPI_DATA_SIZE	(0x1000000)
-#define PLAT_NAND_DATA_BASE	(0x0200000)
-#define PLAT_NAND_DATA_SIZE	(0x1000000)
 
 static const io_dev_connector_t *fip_dev_con;
 static const io_dev_connector_t *boot_dev_con;
@@ -55,6 +52,12 @@
 	.uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
 };
 
+# if ARM_LINUX_KERNEL_AS_BL33 != 0
+static const io_uuid_spec_t nt_fw_config_uuid_spec = {
+	.uuid = UUID_NT_FW_CONFIG,
+};
+# endif
+
 uintptr_t a2_lba_offset;
 const char a2[] = {0xa2, 0x0};
 
@@ -101,6 +104,13 @@
 		(uintptr_t) &bl33_uuid_spec,
 		check_fip
 	},
+# if ARM_LINUX_KERNEL_AS_BL33 != 0
+	[NT_FW_CONFIG_ID] = {
+		&fip_dev_handle,
+		(uintptr_t)&nt_fw_config_uuid_spec,
+		check_fip
+	},
+# endif
 	[GPT_IMAGE_ID] = {
 		&boot_dev_handle,
 		(uintptr_t) &gpt_block_spec,
@@ -136,9 +146,10 @@
 	return result;
 }
 
-void socfpga_io_setup(int boot_source)
+void socfpga_io_setup(int boot_source, unsigned long offset)
 {
 	int result;
+	fip_spec.offset = offset;
 
 	switch (boot_source) {
 	case BOOT_SOURCE_SDMMC:
@@ -152,7 +163,6 @@
 
 	case BOOT_SOURCE_QSPI:
 		register_io_dev = &register_io_dev_memmap;
-		fip_spec.offset = PLAT_QSPI_DATA_BASE;
 		break;
 
 #if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
@@ -161,7 +171,6 @@
 		nand_dev_spec.ops.init = cdns_nand_init_mtd;
 		nand_dev_spec.ops.read = cdns_nand_read;
 		nand_dev_spec.ops.write = NULL;
-		fip_spec.offset = PLAT_NAND_DATA_BASE;
 		break;
 #endif
 
diff --git a/plat/intel/soc/n5x/platform.mk b/plat/intel/soc/n5x/platform.mk
index 95f076f..29fd0eb 100644
--- a/plat/intel/soc/n5x/platform.mk
+++ b/plat/intel/soc/n5x/platform.mk
@@ -46,6 +46,8 @@
 		plat/intel/soc/common/soc/socfpga_mailbox.c		\
 		plat/intel/soc/common/soc/socfpga_reset_manager.c
 
+$(eval $(call add_define,ARM_PRELOADED_DTB_BASE))
+
 PROGRAMMABLE_RESET_ADDRESS	:= 0
 RESET_TO_BL2			:= 1
 BL2_INV_DCACHE			:= 0
diff --git a/plat/intel/soc/stratix10/bl2_plat_setup.c b/plat/intel/soc/stratix10/bl2_plat_setup.c
index 73e3216..d140394 100644
--- a/plat/intel/soc/stratix10/bl2_plat_setup.c
+++ b/plat/intel/soc/stratix10/bl2_plat_setup.c
@@ -122,14 +122,14 @@
 	switch (boot_source) {
 	case BOOT_SOURCE_SDMMC:
 		dw_mmc_init(&params, &mmc_info);
-		socfpga_io_setup(boot_source);
+		socfpga_io_setup(boot_source, PLAT_SDMMC_DATA_BASE);
 		break;
 
 	case BOOT_SOURCE_QSPI:
 		cad_qspi_init(0, QSPI_CONFIG_CPHA, QSPI_CONFIG_CPOL,
 			QSPI_CONFIG_CSDA, QSPI_CONFIG_CSDADS,
 			QSPI_CONFIG_CSEOT, QSPI_CONFIG_CSSOT, 0);
-		socfpga_io_setup(boot_source);
+		socfpga_io_setup(boot_source, PLAT_QSPI_DATA_BASE);
 		break;
 
 	default:
diff --git a/plat/intel/soc/stratix10/platform.mk b/plat/intel/soc/stratix10/platform.mk
index 9567c45..afcf514 100644
--- a/plat/intel/soc/stratix10/platform.mk
+++ b/plat/intel/soc/stratix10/platform.mk
@@ -76,6 +76,8 @@
 		plat/intel/soc/common/soc/socfpga_mailbox.c		\
 		plat/intel/soc/common/soc/socfpga_reset_manager.c
 
+$(eval $(call add_define,ARM_PRELOADED_DTB_BASE))
+
 PROGRAMMABLE_RESET_ADDRESS	:= 0
 RESET_TO_BL2			:= 1
 USE_COHERENT_MEM		:= 1
diff --git a/plat/qemu/common/qemu_bl2_setup.c b/plat/qemu/common/qemu_bl2_setup.c
index 8c7518d..cd83a98 100644
--- a/plat/qemu/common/qemu_bl2_setup.c
+++ b/plat/qemu/common/qemu_bl2_setup.c
@@ -19,9 +19,7 @@
 #include <common/fdt_fixup.h>
 #include <common/fdt_wrappers.h>
 #include <lib/optee_utils.h>
-#if TRANSFER_LIST
 #include <lib/transfer_list.h>
-#endif
 #include <lib/utils.h>
 #include <plat/common/platform.h>
 #if ENABLE_RME
@@ -55,9 +53,7 @@
 
 /* Data structure which holds the extents of the trusted SRAM for BL2 */
 static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE);
-#if TRANSFER_LIST
 static struct transfer_list_header *bl2_tl;
-#endif
 
 void bl2_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 			       u_register_t arg2, u_register_t arg3)
@@ -122,7 +118,7 @@
 		ERROR("Failed to pack Device Tree at %p: error %d\n", fdt, ret);
 
 #if TRANSFER_LIST
-	// create a TE
+	/* create a TE */
 	te = transfer_list_add(bl2_tl, TL_TAG_FDT, fdt_totalsize(fdt), fdt);
 	if (!te) {
 		ERROR("Failed to add FDT entry to Transfer List\n");
@@ -321,6 +317,23 @@
 }
 #endif /*defined(SPD_spmd) && SPMD_SPM_AT_SEL2*/
 
+#if defined(SPD_opteed) || defined(AARCH32_SP_OPTEE) || defined(SPMC_OPTEE)
+static int handoff_pageable_part(uint64_t pagable_part)
+{
+#if TRANSFER_LIST
+	struct transfer_list_entry *te;
+
+	te = transfer_list_add(bl2_tl, TL_TAG_OPTEE_PAGABLE_PART,
+			       sizeof(pagable_part), &pagable_part);
+	if (!te) {
+		INFO("Cannot add TE for pageable part\n");
+		return -1;
+	}
+#endif
+	return 0;
+}
+#endif
+
 static int qemu_bl2_handle_post_image_load(unsigned int image_id)
 {
 	int err = 0;
@@ -334,12 +347,24 @@
 #endif
 #if TRANSFER_LIST
 	struct transfer_list_header *ns_tl = NULL;
-	struct transfer_list_entry *te = NULL;
 #endif
 
 	assert(bl_mem_params);
 
 	switch (image_id) {
+#if TRANSFER_LIST
+	case BL31_IMAGE_ID:
+		/*
+		 * arg0 is a bl_params_t reserved for bl31_early_platform_setup2
+		 * we just need arg1 and arg3 for BL31 to update th TL from S
+		 * to NS memory before it exits
+		 */
+		bl_mem_params->ep_info.args.arg1 =
+			TRANSFER_LIST_SIGNATURE |
+			REGISTER_CONVENTION_VERSION_MASK;
+		bl_mem_params->ep_info.args.arg3 = (uintptr_t)bl2_tl;
+		break;
+#endif
 	case BL32_IMAGE_ID:
 #if defined(SPD_opteed) || defined(AARCH32_SP_OPTEE) || defined(SPMC_OPTEE)
 		pager_mem_params = get_bl_mem_params_node(BL32_EXTRA1_IMAGE_ID);
@@ -354,8 +379,21 @@
 		if (err != 0) {
 			WARN("OPTEE header parse error.\n");
 		}
+
+		/* add TL_TAG_OPTEE_PAGABLE_PART entry to the TL */
+		if (handoff_pageable_part(bl_mem_params->ep_info.args.arg1)) {
+			return -1;
+		}
 #endif
 
+		INFO("Handoff to BL32\n");
+		bl_mem_params->ep_info.spsr = qemu_get_spsr_for_bl32_entry();
+		if (TRANSFER_LIST &&
+			transfer_list_set_handoff_args(bl2_tl,
+				&bl_mem_params->ep_info))
+			break;
+
+		INFO("Using default arguments\n");
 #if defined(SPMC_OPTEE)
 		/*
 		 * Explicit zeroes to unused registers since they may have
@@ -379,7 +417,6 @@
 		bl_mem_params->ep_info.args.arg2 = ARM_PRELOADED_DTB_BASE;
 		bl_mem_params->ep_info.args.arg3 = 0;
 #endif
-		bl_mem_params->ep_info.spsr = qemu_get_spsr_for_bl32_entry();
 		break;
 
 	case BL33_IMAGE_ID:
@@ -406,7 +443,7 @@
 		bl_mem_params->ep_info.args.arg3 = 0U;
 #elif TRANSFER_LIST
 		if (bl2_tl) {
-			// relocate the tl to pre-allocate NS memory
+			/* relocate the tl to pre-allocate NS memory */
 			ns_tl = transfer_list_relocate(bl2_tl,
 					(void *)(uintptr_t)FW_NS_HANDOFF_BASE,
 					bl2_tl->max_size);
@@ -415,37 +452,18 @@
 					(unsigned long)FW_NS_HANDOFF_BASE);
 				return -1;
 			}
-			NOTICE("Transfer list handoff to BL33\n");
-			transfer_list_dump(ns_tl);
-
-			te = transfer_list_find(ns_tl, TL_TAG_FDT);
-
-			bl_mem_params->ep_info.args.arg1 =
-				TRANSFER_LIST_SIGNATURE |
-				REGISTER_CONVENTION_VERSION_MASK;
-			bl_mem_params->ep_info.args.arg3 = (uintptr_t)ns_tl;
+		}
 
-			if (GET_RW(bl_mem_params->ep_info.spsr) == MODE_RW_32) {
-				// aarch32
-				bl_mem_params->ep_info.args.arg0 = 0;
-				bl_mem_params->ep_info.args.arg2 = te ?
-					(uintptr_t)transfer_list_entry_data(te)
-					: 0;
-			} else {
-				// aarch64
-				bl_mem_params->ep_info.args.arg0 = te ?
-					(uintptr_t)transfer_list_entry_data(te)
-					: 0;
-				bl_mem_params->ep_info.args.arg2 = 0;
-			}
-		} else {
-			// Legacy handoff
+		INFO("Handoff to BL33\n");
+		if (!transfer_list_set_handoff_args(ns_tl,
+						    &bl_mem_params->ep_info)) {
+			INFO("Invalid TL, fallback to default arguments\n");
 			bl_mem_params->ep_info.args.arg0 = 0xffff & read_mpidr();
 		}
 #else
 		/* BL33 expects to receive the primary CPU MPID (through r0) */
 		bl_mem_params->ep_info.args.arg0 = 0xffff & read_mpidr();
-#endif // ARM_LINUX_KERNEL_AS_BL33
+#endif /* ARM_LINUX_KERNEL_AS_BL33 */
 
 		break;
 #ifdef SPD_spmd
diff --git a/plat/qemu/common/qemu_bl31_setup.c b/plat/qemu/common/qemu_bl31_setup.c
index 894b842..eb88b12 100644
--- a/plat/qemu/common/qemu_bl31_setup.c
+++ b/plat/qemu/common/qemu_bl31_setup.c
@@ -9,6 +9,7 @@
 #include <common/bl_common.h>
 #include <drivers/arm/pl061_gpio.h>
 #include <lib/gpt_rme/gpt_rme.h>
+#include <lib/transfer_list.h>
 #include <plat/common/platform.h>
 
 #include "qemu_private.h"
@@ -44,6 +45,7 @@
 #if ENABLE_RME
 static entry_point_info_t rmm_image_ep_info;
 #endif
+static struct transfer_list_header *bl31_tl;
 
 /*******************************************************************************
  * Perform any BL3-1 early platform setup.  Here is an opportunity to copy
@@ -100,6 +102,12 @@
 	if (!rmm_image_ep_info.pc)
 		panic();
 #endif
+
+	if (TRANSFER_LIST && arg1 == (TRANSFER_LIST_SIGNATURE |
+				      REGISTER_CONVENTION_VERSION_MASK) &&
+	    transfer_list_check_header((void *)arg3) != TL_OPS_NON) {
+		bl31_tl = (void *)arg3; /* saved TL address from BL2 */
+	}
 }
 
 void bl31_plat_arch_setup(void)
@@ -188,3 +196,18 @@
 	else
 		return NULL;
 }
+
+void bl31_plat_runtime_setup(void)
+{
+	console_switch_state(CONSOLE_FLAG_RUNTIME);
+
+#if TRANSFER_LIST
+	if (bl31_tl) {
+		/*
+		 * update the TL from S to NS memory before jump to BL33
+		 * to reflect all changes in TL done by BL32
+		 */
+		memcpy((void *)FW_NS_HANDOFF_BASE, bl31_tl, bl31_tl->max_size);
+	}
+#endif
+}
diff --git a/plat/renesas/common/aarch64/plat_helpers.S b/plat/renesas/common/aarch64/plat_helpers.S
index a7fdfa0..572620d 100644
--- a/plat/renesas/common/aarch64/plat_helpers.S
+++ b/plat/renesas/common/aarch64/plat_helpers.S
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
- * Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2015-2023, Renesas Electronics Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -172,15 +172,16 @@
          * BL31 will initialize the address space according to its
          * own requirement.
          */
-#if RCAR_BL2_DCACHE == 1
 	/* Disable mmu and data cache */
 	bl	disable_mmu_el3
+#if RCAR_BL2_DCACHE == 1
 	/* Data cache clean and invalidate */
 	mov	x0, #DCCISW
 	bl	dcsw_op_all
+#endif /* RCAR_BL2_DCACHE == 1 */
 	/* TLB invalidate all, EL3 */
 	tlbi	alle3
-#endif /* RCAR_BL2_DCACHE == 1 */
+
 	bl	disable_mmu_icache_el3
 	/* Invalidate instruction cache */
 	ic	iallu
diff --git a/plat/renesas/common/aarch64/platform_common.c b/plat/renesas/common/aarch64/platform_common.c
index 17ccb28..9e7d526 100644
--- a/plat/renesas/common/aarch64/platform_common.c
+++ b/plat/renesas/common/aarch64/platform_common.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2015-2023, Renesas Electronics Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -30,13 +30,19 @@
 const uint8_t version_of_renesas[VERSION_OF_RENESAS_MAXLEN]
 		__attribute__ ((__section__(".ro"))) = VERSION_OF_RENESAS;
 
+#if (IMAGE_BL2) && (RCAR_BL2_DCACHE != 1)
+#define RCAR_DCACHE MT_NON_CACHEABLE
+#else
+#define RCAR_DCACHE MT_MEMORY
+#endif
+
 #define MAP_SHARED_RAM		MAP_REGION_FLAT(RCAR_SHARED_MEM_BASE,	\
 					RCAR_SHARED_MEM_SIZE,		\
 					MT_MEMORY | MT_RW | MT_SECURE)
 
 #define MAP_FLASH0		MAP_REGION_FLAT(FLASH0_BASE,		\
 					FLASH0_SIZE,			\
-					MT_MEMORY | MT_RO | MT_SECURE)
+					RCAR_DCACHE | MT_RO | MT_SECURE)
 
 #define MAP_DRAM1_NS		MAP_REGION_FLAT(DRAM1_NS_BASE,		\
 					DRAM1_NS_SIZE,			\
@@ -68,7 +74,7 @@
 #if IMAGE_BL2
 #define MAP_DRAM0		MAP_REGION_FLAT(DRAM1_BASE,		\
 					DRAM1_SIZE,			\
-					MT_MEMORY | MT_RW | MT_SECURE)
+					RCAR_DCACHE | MT_RW | MT_SECURE)
 
 #define MAP_REG0		MAP_REGION_FLAT(DEVICE_RCAR_BASE,	\
 					DEVICE_RCAR_SIZE,		\
@@ -76,7 +82,7 @@
 
 #define MAP_RAM0		MAP_REGION_FLAT(RCAR_SYSRAM_BASE,	\
 					RCAR_SYSRAM_SIZE,		\
-					MT_MEMORY | MT_RW | MT_SECURE)
+					RCAR_DCACHE | MT_RW | MT_SECURE)
 
 #define MAP_REG1		MAP_REGION_FLAT(REG1_BASE,		\
 					REG1_SIZE,			\
@@ -84,7 +90,7 @@
 
 #define MAP_ROM			MAP_REGION_FLAT(ROM0_BASE,		\
 					ROM0_SIZE,			\
-					MT_MEMORY | MT_RO | MT_SECURE)
+					RCAR_DCACHE | MT_RO | MT_SECURE)
 
 #define MAP_REG2		MAP_REGION_FLAT(REG2_BASE,		\
 					REG2_SIZE,			\
@@ -92,7 +98,7 @@
 
 #define MAP_DRAM1		MAP_REGION_FLAT(DRAM_40BIT_BASE,	\
 					DRAM_40BIT_SIZE,		\
-					MT_MEMORY | MT_RW | MT_SECURE)
+					RCAR_DCACHE | MT_RW | MT_SECURE)
 #endif
 
 #ifdef BL32_BASE
@@ -152,9 +158,9 @@
 			    unsigned long coh_limit)
 {
 	mmap_add_region(total_base, total_base, total_size,
-			MT_MEMORY | MT_RW | MT_SECURE);
+			RCAR_DCACHE | MT_RW | MT_SECURE);
 	mmap_add_region(ro_start, ro_start, ro_limit - ro_start,
-			MT_MEMORY | MT_RO | MT_SECURE);
+			RCAR_DCACHE | MT_RO | MT_SECURE);
 	mmap_add_region(coh_start, coh_start, coh_limit - coh_start,
 			MT_DEVICE | MT_RW | MT_SECURE);
 	mmap_add(rcar_mmap);
@@ -169,9 +175,9 @@
 			    unsigned long ro_limit)
 {
 	mmap_add_region(total_base, total_base, total_size,
-			MT_MEMORY | MT_RW | MT_SECURE);
+			RCAR_DCACHE | MT_RW | MT_SECURE);
 	mmap_add_region(ro_start, ro_start, ro_limit - ro_start,
-			MT_MEMORY | MT_RO | MT_SECURE);
+			RCAR_DCACHE | MT_RO | MT_SECURE);
 	mmap_add(rcar_mmap);
 
 	init_xlat_tables();
diff --git a/plat/renesas/common/include/rcar_version.h b/plat/renesas/common/include/rcar_version.h
index 5a0ca31..777ec6a 100644
--- a/plat/renesas/common/include/rcar_version.h
+++ b/plat/renesas/common/include/rcar_version.h
@@ -9,7 +9,7 @@
 
 #include <arch_helpers.h>
 
-#define VERSION_OF_RENESAS		"3.0.3"
+#define VERSION_OF_RENESAS		"4.0.0"
 #define VERSION_OF_RENESAS_MAXLEN	128
 
 extern const uint8_t version_of_renesas[VERSION_OF_RENESAS_MAXLEN];
diff --git a/plat/renesas/rcar/bl2_plat_setup.c b/plat/renesas/rcar/bl2_plat_setup.c
index cf77da2..41031d6 100644
--- a/plat/renesas/rcar/bl2_plat_setup.c
+++ b/plat/renesas/rcar/bl2_plat_setup.c
@@ -48,10 +48,8 @@
 #include "rcar_version.h"
 #include "rom_api.h"
 
-#if RCAR_BL2_DCACHE == 1
 /*
- * Following symbols are only used during plat_arch_setup() only
- * when RCAR_BL2_DCACHE is enabled.
+ * Following symbols are only used during plat_arch_setup()
  */
 static const uint64_t BL2_RO_BASE		= BL_CODE_BASE;
 static const uint64_t BL2_RO_LIMIT		= BL_CODE_END;
@@ -61,8 +59,6 @@
 static const uint64_t BL2_COHERENT_RAM_LIMIT	= BL_COHERENT_RAM_END;
 #endif
 
-#endif
-
 extern void plat_rcar_gic_driver_init(void);
 extern void plat_rcar_gic_init(void);
 extern void bl2_enter_bl31(const struct entry_point_info *bl_ep_info);
@@ -372,10 +368,16 @@
 	rcar_swdt_release();
 	bl2_system_cpg_init();
 
-#if RCAR_BL2_DCACHE == 1
 	/* Disable data cache (clean and invalidate) */
 	disable_mmu_el3();
+#if RCAR_BL2_DCACHE == 1
+	dcsw_op_all(DCCISW);
 #endif
+	tlbialle3();
+	disable_mmu_icache_el3();
+	plat_invalidate_icache();
+	dsbsy();
+	isb();
 }
 
 static uint32_t is_ddr_backup_mode(void)
@@ -1274,8 +1276,6 @@
 
 void bl2_el3_plat_arch_setup(void)
 {
-#if RCAR_BL2_DCACHE == 1
-	NOTICE("BL2: D-Cache enable\n");
 	rcar_configure_mmu_el3(BL2_BASE,
 			       BL2_END - BL2_BASE,
 			       BL2_RO_BASE, BL2_RO_LIMIT
@@ -1283,7 +1283,6 @@
 			       , BL2_COHERENT_RAM_BASE, BL2_COHERENT_RAM_LIMIT
 #endif
 	    );
-#endif
 }
 
 void bl2_el3_plat_prepare_exit(void)
diff --git a/plat/renesas/rcar/platform.mk b/plat/renesas/rcar/platform.mk
index 670d499..c95590d 100644
--- a/plat/renesas/rcar/platform.mk
+++ b/plat/renesas/rcar/platform.mk
@@ -6,6 +6,8 @@
 
 include plat/renesas/common/common.mk
 
+ENABLE_STACK_PROTECTOR	:= strong
+
 ifndef LSI
   $(error "Error: Unknown LSI. Please use LSI=<LSI name> to specify the LSI")
 else
@@ -333,6 +335,10 @@
 			$(ZLIB_SOURCES)
 endif
 
+ifneq (${ENABLE_STACK_PROTECTOR},0)
+BL_COMMON_SOURCES	+=	plat/renesas/rcar/rcar_stack_protector.c
+endif
+
 ifeq (${RCAR_GEN3_ULCB},1)
 BL31_SOURCES		+=	drivers/renesas/rcar/cpld/ulcb_cpld.c
 endif
diff --git a/plat/renesas/rcar/rcar_stack_protector.c b/plat/renesas/rcar/rcar_stack_protector.c
new file mode 100644
index 0000000..ecceef4
--- /dev/null
+++ b/plat/renesas/rcar/rcar_stack_protector.c
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2021-2023, Renesas Electronics Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+
+#define RANDOM_CANARY_VALUE ((u_register_t)0xDFF5FC8A720E205EULL)
+
+u_register_t plat_get_stack_protector_canary(void)
+{
+	u_register_t cnt;
+	u_register_t seed;
+	u_register_t mul;
+	u_register_t ret;
+	uintptr_t val1 = (uintptr_t)__builtin_return_address(0U);
+	uintptr_t val2 = (uintptr_t)__builtin_frame_address(0U);
+
+	cnt = read_cntpct_el0();
+	seed = (cnt ^ RANDOM_CANARY_VALUE) & ULONG_MAX;
+	ret = seed;
+
+	if ((ULONG_MAX/val1) > seed) {
+		mul = (u_register_t)(val1 * seed);
+		if ((mul < ULONG_MAX) &&
+				((ULONG_MAX - (u_register_t)mul) > val2)) {
+			ret = mul + val2;
+		}
+	}
+
+	return ret;
+}
diff --git a/plat/st/common/include/stm32mp_common.h b/plat/st/common/include/stm32mp_common.h
index e334f22..66b9310 100644
--- a/plat/st/common/include/stm32mp_common.h
+++ b/plat/st/common/include/stm32mp_common.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018-2023, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2018-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,6 +14,9 @@
 #define JEDEC_ST_BKID U(0x0)
 #define JEDEC_ST_MFID U(0x20)
 
+#define STM32MP_CHIP_SEC_CLOSED		U(0x34D9CCC5)
+#define STM32MP_CHIP_SEC_OPEN		U(0xA764D182)
+
 /* FWU configuration (max supported value is 15) */
 #define FWU_MAX_TRIAL_REBOOT		U(3)
 
@@ -23,8 +26,8 @@
 uint16_t stm32mp_get_boot_itf_selected(void);
 
 bool stm32mp_is_single_core(void);
-bool stm32mp_is_closed_device(void);
 bool stm32mp_is_auth_supported(void);
+uint32_t stm32mp_check_closed_device(void);
 
 /* Return the base address of the DDR controller */
 uintptr_t stm32mp_ddrctrl_base(void);
diff --git a/plat/st/common/stm32mp_common.c b/plat/st/common/stm32mp_common.c
index 2163aaf..a1d1c49 100644
--- a/plat/st/common/stm32mp_common.c
+++ b/plat/st/common/stm32mp_common.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -168,9 +168,9 @@
 	assert(otp_val != NULL);
 
 #if defined(IMAGE_BL2)
-	ret = bsec_shadow_read_otp(otp_val, otp_idx);
-#elif defined(IMAGE_BL32)
-	ret = bsec_read_otp(otp_val, otp_idx);
+	ret = stm32_otp_shadow_read(otp_val, otp_idx);
+#elif defined(IMAGE_BL31) || defined(IMAGE_BL32)
+	ret = stm32_otp_read(otp_val, otp_idx);
 #else
 #error "Not supported"
 #endif
diff --git a/plat/st/common/stm32mp_crypto_lib.c b/plat/st/common/stm32mp_crypto_lib.c
index e282115..7223022 100644
--- a/plat/st/common/stm32mp_crypto_lib.c
+++ b/plat/st/common/stm32mp_crypto_lib.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022-2023, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2022-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -11,7 +11,6 @@
 #include <common/debug.h>
 #include <drivers/auth/crypto_mod.h>
 #include <drivers/io/io_storage.h>
-#include <drivers/st/bsec.h>
 #include <drivers/st/stm32_hash.h>
 #include <drivers/st/stm32_pka.h>
 #include <drivers/st/stm32_rng.h>
@@ -58,7 +57,8 @@
 		panic();
 	}
 
-	if (stm32mp_is_closed_device() || stm32mp_is_auth_supported()) {
+	if ((stm32mp_check_closed_device() == STM32MP_CHIP_SEC_CLOSED) ||
+	    stm32mp_is_auth_supported()) {
 #if STM32MP_CRYPTO_ROM_LIB
 		boot_context = (boot_api_context_t *)stm32mp_get_boot_ctx_address();
 		auth_ops.verify_signature = boot_context->bootrom_ecdsa_verify_signature;
@@ -322,7 +322,8 @@
 	size_t bignum_len = sizeof(sig) / 2U;
 	unsigned int seq_num = 0U;
 
-	if (!stm32mp_is_closed_device() && !stm32mp_is_auth_supported()) {
+	if ((stm32mp_check_closed_device() == STM32MP_CHIP_SEC_OPEN) &&
+	    !stm32mp_is_auth_supported()) {
 		return CRYPTO_SUCCESS;
 	}
 
diff --git a/plat/st/common/stm32mp_trusted_boot.c b/plat/st/common/stm32mp_trusted_boot.c
index 6d89290..d40fc55 100644
--- a/plat/st/common/stm32mp_trusted_boot.c
+++ b/plat/st/common/stm32mp_trusted_boot.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2022-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -67,14 +67,14 @@
 		 * Check if key hash values in OTP are 0 or 0xFFFFFFFFF
 		 * programmed : Invalid Key
 		 */
-		if (!stm32mp_is_closed_device() && !valid) {
+		if ((stm32mp_check_closed_device() == STM32MP_CHIP_SEC_OPEN) && !valid) {
 			if ((tmp != 0U) && (tmp != 0xFFFFFFFFU) && (tmp != first)) {
 				valid = true;
 			}
 		}
 	}
 
-	if (!stm32mp_is_closed_device() && !valid) {
+	if ((stm32mp_check_closed_device() == STM32MP_CHIP_SEC_OPEN) && !valid) {
 		return 0;
 	}
 
@@ -163,7 +163,7 @@
 	*key_ptr = &root_pk_hash;
 	*flags = ROTPK_IS_HASH;
 
-	if ((res == 0) && !stm32mp_is_closed_device()) {
+	if ((res == 0) && (stm32mp_check_closed_device() == STM32MP_CHIP_SEC_OPEN)) {
 		*flags |= ROTPK_NOT_DEPLOYED;
 	}
 
diff --git a/plat/st/stm32mp1/bl2_plat_setup.c b/plat/st/stm32mp1/bl2_plat_setup.c
index eeabd09..321b8c5 100644
--- a/plat/st/stm32mp1/bl2_plat_setup.c
+++ b/plat/st/stm32mp1/bl2_plat_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -318,7 +318,7 @@
 
 skip_console_init:
 #if !TRUSTED_BOARD_BOOT
-	if (stm32mp_is_closed_device()) {
+	if (stm32mp_check_closed_device() == STM32MP_CHIP_SEC_CLOSED) {
 		/* Closed chip mandates authentication */
 		ERROR("Secure chip: TRUSTED_BOARD_BOOT must be enabled\n");
 		panic();
@@ -347,7 +347,7 @@
 	stm32_iwdg_refresh();
 
 	if (bsec_read_debug_conf() != 0U) {
-		if (stm32mp_is_closed_device()) {
+		if (stm32mp_check_closed_device() == STM32MP_CHIP_SEC_CLOSED) {
 #if DEBUG
 			WARN("\n%s", debug_msg);
 #else
diff --git a/plat/st/stm32mp1/include/stm32mp1_private.h b/plat/st/stm32mp1/include/stm32mp1_private.h
index 4a52255..f6e5a8f 100644
--- a/plat/st/stm32mp1/include/stm32mp1_private.h
+++ b/plat/st/stm32mp1/include/stm32mp1_private.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -32,4 +32,31 @@
 void stm32mp1_deconfigure_uart_pins(void);
 
 void stm32mp1_init_scmi_server(void);
+
+/* Wrappers for OTP / BSEC functions */
+static inline uint32_t stm32_otp_read(uint32_t *val, uint32_t otp)
+{
+	return bsec_read_otp(val, otp);
+}
+
+static inline uint32_t stm32_otp_shadow_read(uint32_t *val, uint32_t otp)
+{
+	return bsec_shadow_read_otp(val, otp);
+}
+
+static inline uint32_t stm32_otp_write(uint32_t val, uint32_t otp)
+{
+	return bsec_write_otp(val, otp);
+}
+
+static inline uint32_t stm32_otp_set_sr_lock(uint32_t otp)
+{
+	return bsec_set_sr_lock(otp);
+}
+
+static inline uint32_t stm32_otp_read_sw_lock(uint32_t otp, bool *value)
+{
+	return bsec_read_sw_lock(otp, value);
+}
+
 #endif /* STM32MP1_PRIVATE_H */
diff --git a/plat/st/stm32mp1/services/bsec_svc.c b/plat/st/stm32mp1/services/bsec_svc.c
index 1fb44b4..7cc0013 100644
--- a/plat/st/stm32mp1/services/bsec_svc.c
+++ b/plat/st/stm32mp1/services/bsec_svc.c
@@ -1,15 +1,15 @@
 /*
- * Copyright (c) 2016-2022, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2016-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <platform_def.h>
 
 #include <common/debug.h>
 #include <drivers/st/bsec.h>
 #include <drivers/st/bsec2_reg.h>
 
+#include <platform_def.h>
 #include <stm32mp1_smc.h>
 
 #include "bsec_svc.h"
@@ -39,12 +39,7 @@
 			break;
 		}
 
-		result = bsec_shadow_register(x2);
-		if (result != BSEC_OK) {
-			break;
-		}
-
-		result = bsec_read_otp(ret_otp_value, x2);
+		result = bsec_shadow_read_otp(ret_otp_value, x2);
 		if (result != BSEC_OK) {
 			break;
 		}
diff --git a/plat/st/stm32mp1/stm32mp1_def.h b/plat/st/stm32mp1/stm32mp1_def.h
index 6530957..8fc8c89 100644
--- a/plat/st/stm32mp1/stm32mp1_def.h
+++ b/plat/st/stm32mp1/stm32mp1_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -426,24 +426,24 @@
 #define OTP_MAX_SIZE			(STM32MP1_OTP_MAX_ID + 1U)
 
 /* OTP labels */
-#define CFG0_OTP			"cfg0_otp"
+#define CFG0_OTP			"cfg0-otp"
 #define PART_NUMBER_OTP			"part-number-otp"
 #if STM32MP15
-#define PACKAGE_OTP			"package_otp"
+#define PACKAGE_OTP			"package-otp"
 #endif
-#define HW2_OTP				"hw2_otp"
+#define HW2_OTP				"hw2-otp"
 #if STM32MP13
-#define NAND_OTP			"cfg9_otp"
-#define NAND2_OTP			"cfg10_otp"
+#define NAND_OTP			"cfg9-otp"
+#define NAND2_OTP			"cfg10-otp"
 #endif
 #if STM32MP15
-#define NAND_OTP			"nand_otp"
+#define NAND_OTP			"nand-otp"
 #endif
-#define MONOTONIC_OTP			"monotonic_otp"
-#define UID_OTP				"uid_otp"
-#define PKH_OTP				"pkh_otp"
-#define ENCKEY_OTP			"enckey_otp"
-#define BOARD_ID_OTP			"board_id"
+#define MONOTONIC_OTP			"monotonic-otp"
+#define UID_OTP				"uid-otp"
+#define PKH_OTP				"pkh-otp"
+#define ENCKEY_OTP			"oem-enc-key"
+#define BOARD_ID_OTP			"board-id"
 
 /* OTP mask */
 /* CFG0 */
diff --git a/plat/st/stm32mp1/stm32mp1_private.c b/plat/st/stm32mp1/stm32mp1_private.c
index ea35055..0e69513 100644
--- a/plat/st/stm32mp1/stm32mp1_private.c
+++ b/plat/st/stm32mp1/stm32mp1_private.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -531,12 +531,12 @@
 }
 
 /* Return true when device is in closed state */
-bool stm32mp_is_closed_device(void)
+uint32_t stm32mp_check_closed_device(void)
 {
 	uint32_t value;
 
 	if (stm32_get_otp_value(CFG0_OTP, &value) != 0) {
-		return true;
+		return STM32MP_CHIP_SEC_CLOSED;
 	}
 
 #if STM32MP13
@@ -544,17 +544,22 @@
 
 	switch (value) {
 	case CFG0_OPEN_DEVICE:
-		return false;
+		return STM32MP_CHIP_SEC_OPEN;
 	case CFG0_CLOSED_DEVICE:
 	case CFG0_CLOSED_DEVICE_NO_BOUNDARY_SCAN:
 	case CFG0_CLOSED_DEVICE_NO_JTAG:
-		return true;
+		return STM32MP_CHIP_SEC_CLOSED;
 	default:
 		panic();
 	}
 #endif
 #if STM32MP15
-	return (value & CFG0_CLOSED_DEVICE) == CFG0_CLOSED_DEVICE;
+	if ((value & CFG0_CLOSED_DEVICE) == CFG0_CLOSED_DEVICE) {
+		return STM32MP_CHIP_SEC_CLOSED;
+	} else {
+		return STM32MP_CHIP_SEC_OPEN;
+	}
+
 #endif
 }
 
diff --git a/plat/st/stm32mp2/aarch64/stm32mp2_helper.S b/plat/st/stm32mp2/aarch64/stm32mp2_helper.S
index 66333ad..0df3e08 100644
--- a/plat/st/stm32mp2/aarch64/stm32mp2_helper.S
+++ b/plat/st/stm32mp2/aarch64/stm32mp2_helper.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2023-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,6 +14,7 @@
 	.globl	platform_mem_init
 	.globl	plat_secondary_cold_boot_setup
 	.globl	plat_is_my_cpu_primary
+	.globl	plat_my_core_pos
 	.globl	plat_crash_console_init
 	.globl	plat_crash_console_flush
 	.globl	plat_crash_console_putc
@@ -32,9 +33,14 @@
 	 */
 func plat_secondary_cold_boot_setup
 	dsb	sy
+1:
 	wfi
-	/* This shouldn't be reached */
-	b	.
+	/*
+	 * This shouldn't be reached, but when a debugger halts the
+	 * secondary core it causes exit from wfi.
+	 * Put back the core in wfi.
+	 */
+	b	1b
 endfunc plat_secondary_cold_boot_setup
 
 	/* ----------------------------------------------
@@ -50,6 +56,31 @@
 	ret
 endfunc plat_is_my_cpu_primary
 
+	/* -----------------------------------------------------------
+	 *  unsigned int plat_stm32mp_get_core_pos(u_register_t mpidr)
+	 *  Helper function to calculate the core position.
+	 *  With this function: CorePos = (ClusterId * 4) +
+	 *  				  CoreId
+	 * -----------------------------------------------------------
+	 */
+func plat_stm32mp_get_core_pos
+	and	x1, x0, #MPIDR_CPU_MASK
+	and	x0, x0, #MPIDR_CLUSTER_MASK
+	add	x0, x1, x0, LSR #6
+	ret
+endfunc plat_stm32mp_get_core_pos
+
+	/* -----------------------------------------------------
+	 *  unsigned int plat_my_core_pos(void)
+	 *  This function uses the plat_stm32mp_get_core_pos()
+	 *  definition to get the index of the calling CPU.
+	 * -----------------------------------------------------
+	 */
+func plat_my_core_pos
+	mrs	x0, mpidr_el1
+	b	plat_stm32mp_get_core_pos
+endfunc plat_my_core_pos
+
 	/* ---------------------------------------------
 	 * int plat_crash_console_init(void)
 	 *
@@ -65,13 +96,13 @@
 	str	x0, [x1]
 1:
 	ldr	x0, [x1]
-	ands	x2, x0, x2
+	tst	x0, #DEBUG_UART_RST_BIT
 	beq	1b
-	bic	x2, x2, #DEBUG_UART_RST_BIT
-	str	x2, [x1]
+	bic	x0, x0, #DEBUG_UART_RST_BIT
+	str	x0, [x1]
 2:
 	ldr	x0, [x1]
-	ands	x2, x0, x2
+	tst	x0, #DEBUG_UART_RST_BIT
 	bne	2b
 	/* Enable GPIOs for UART TX */
 	mov_imm	x1, (RCC_BASE + DEBUG_UART_TX_GPIO_BANK_CLK_REG)
diff --git a/plat/st/stm32mp2/bl2_plat_setup.c b/plat/st/stm32mp2/bl2_plat_setup.c
index 0805756..5f05f63 100644
--- a/plat/st/stm32mp2/bl2_plat_setup.c
+++ b/plat/st/stm32mp2/bl2_plat_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2023-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,6 +7,8 @@
 #include <cdefs.h>
 #include <stdint.h>
 
+#include <plat/common/platform.h>
+
 #include <stm32mp_common.h>
 
 void bl2_el3_early_platform_setup(u_register_t arg0 __unused,
diff --git a/plat/st/stm32mp2/include/stm32mp2_private.h b/plat/st/stm32mp2/include/stm32mp2_private.h
new file mode 100644
index 0000000..e1403d2
--- /dev/null
+++ b/plat/st/stm32mp2/include/stm32mp2_private.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef STM32MP2_PRIVATE_H
+#define STM32MP2_PRIVATE_H
+
+/* Wrappers for OTP / BSEC functions */
+static inline uint32_t stm32_otp_probe(void)
+{
+	return bsec_probe();
+}
+
+static inline uint32_t stm32_otp_read(uint32_t *val, uint32_t otp)
+{
+	return bsec_read_otp(val, otp);
+}
+
+static inline uint32_t stm32_otp_shadow_read(uint32_t *val, uint32_t otp)
+{
+	return bsec_shadow_read_otp(val, otp);
+}
+
+static inline uint32_t stm32_otp_write(uint32_t val, uint32_t otp)
+{
+	return bsec_write_otp(val, otp);
+}
+
+static inline uint32_t stm32_otp_set_sr_lock(uint32_t otp)
+{
+	return bsec_set_sr_lock(otp);
+}
+
+static inline uint32_t stm32_otp_read_sw_lock(uint32_t otp, bool *value)
+{
+	return bsec_read_sw_lock(otp, value);
+}
+
+static inline bool stm32_otp_is_closed_device(void)
+{
+	return bsec_mode_is_closed_device();
+}
+
+#endif /* STM32MP2_PRIVATE_H */
diff --git a/plat/st/stm32mp2/stm32mp2_def.h b/plat/st/stm32mp2/stm32mp2_def.h
index 66514fc..ee105de 100644
--- a/plat/st/stm32mp2/stm32mp2_def.h
+++ b/plat/st/stm32mp2/stm32mp2_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2023-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -18,6 +18,7 @@
 
 #ifndef __ASSEMBLER__
 #include <boot_api.h>
+#include <stm32mp2_private.h>
 #include <stm32mp_common.h>
 #include <stm32mp_dt.h>
 #include <stm32mp_shared_resources.h>
diff --git a/plat/ti/k3/common/plat_common.mk b/plat/ti/k3/common/plat_common.mk
index 23efa31..8db732c 100644
--- a/plat/ti/k3/common/plat_common.mk
+++ b/plat/ti/k3/common/plat_common.mk
@@ -28,6 +28,8 @@
 
 CRASH_REPORTING		:= 1
 
+NS_TIMER_SWITCH		:=	0
+
 # Split out RO data into a non-executable section
 SEPARATE_CODE_AND_RODATA :=    1
 
diff --git a/plat/xilinx/common/include/plat_common.h b/plat/xilinx/common/include/plat_common.h
index 676baa2..2958868 100644
--- a/plat/xilinx/common/include/plat_common.h
+++ b/plat/xilinx/common/include/plat_common.h
@@ -14,4 +14,16 @@
 		(typeof(_mask))(((_reg) & (_mask)) >> __bf_shf(_mask));	\
 	})
 
+/*******************************************************************************
+ * interrupt handling related constants
+ ******************************************************************************/
+#define ARM_IRQ_SEC_SGI_0	8U
+#define ARM_IRQ_SEC_SGI_1	9U
+#define ARM_IRQ_SEC_SGI_2	10U
+#define ARM_IRQ_SEC_SGI_3	11U
+#define ARM_IRQ_SEC_SGI_4	12U
+#define ARM_IRQ_SEC_SGI_5	13U
+#define ARM_IRQ_SEC_SGI_6	14U
+#define ARM_IRQ_SEC_SGI_7	15U
+
 #endif /* PLAT_COMMON_H */
diff --git a/plat/xilinx/common/include/pm_defs.h b/plat/xilinx/common/include/pm_defs.h
index 9cdb0ba..c1872d0 100644
--- a/plat/xilinx/common/include/pm_defs.h
+++ b/plat/xilinx/common/include/pm_defs.h
@@ -18,6 +18,7 @@
 
 /* State arguments of the self suspend */
 #define PM_STATE_CPU_IDLE	0x0U
+#define PM_STATE_CPU_OFF	0x1U
 #define PM_STATE_SUSPEND_TO_RAM	0xFU
 
 #define MAX_LATENCY		(~0U)
diff --git a/plat/xilinx/common/include/pm_svc_main.h b/plat/xilinx/common/include/pm_svc_main.h
index 4cf7727..67fbeae 100644
--- a/plat/xilinx/common/include/pm_svc_main.h
+++ b/plat/xilinx/common/include/pm_svc_main.h
@@ -10,6 +10,8 @@
 
 #include <pm_common.h>
 
+extern bool pwrdwn_req_received;
+
 /******************************************************************************/
 /**
  * SECURE_REDUNDANT_CALL() - Adds redundancy to the function call. This is to
@@ -30,6 +32,7 @@
 		status_tmp = function(__VA_ARGS__); \
 	}
 
+void request_cpu_pwrdwn(void);
 int32_t pm_setup(void);
 uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
 			uint64_t x4, const void *cookie, void *handle,
diff --git a/plat/xilinx/common/pm_service/pm_api_sys.c b/plat/xilinx/common/pm_service/pm_api_sys.c
index ffc39bb..36ea8ed 100644
--- a/plat/xilinx/common/pm_service/pm_api_sys.c
+++ b/plat/xilinx/common/pm_service/pm_api_sys.c
@@ -50,7 +50,7 @@
 {
 	uint32_t reg_num, device_id;
 	uint8_t pm_wakeup_nodes_set[XPM_NODEIDX_DEV_MAX] = {0U};
-	uint32_t isenabler1 = PLAT_GICD_BASE_VALUE + GICD_ISENABLER + 4U;
+	uint32_t isenabler1 = PLAT_ARM_GICD_BASE + GICD_ISENABLER + 4U;
 
 	zeromem(&pm_wakeup_nodes_set, (u_register_t)sizeof(pm_wakeup_nodes_set));
 
diff --git a/plat/xilinx/common/pm_service/pm_svc_main.c b/plat/xilinx/common/pm_service/pm_svc_main.c
index 1e5808c..f9917a0 100644
--- a/plat/xilinx/common/pm_service/pm_svc_main.c
+++ b/plat/xilinx/common/pm_service/pm_svc_main.c
@@ -17,6 +17,8 @@
 
 #include <common/runtime_svc.h>
 #include <drivers/arm/gicv3.h>
+#include <lib/psci/psci.h>
+#include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 
 #include <plat_private.h>
@@ -31,23 +33,65 @@
 #define INVALID_SGI    0xFFU
 #define PM_INIT_SUSPEND_CB	(30U)
 #define PM_NOTIFY_CB		(32U)
+#define EVENT_CPU_PWRDWN	(4U)
+/* 1 sec of wait timeout for secondary core down */
+#define PWRDWN_WAIT_TIMEOUT	(1000U)
 DEFINE_RENAME_SYSREG_RW_FUNCS(icc_asgi1r_el1, S3_0_C12_C11_6)
 
 /* pm_up = true - UP, pm_up = false - DOWN */
 static bool pm_up;
 static uint32_t sgi = (uint32_t)INVALID_SGI;
+bool pwrdwn_req_received;
 
 static void notify_os(void)
 {
-	int32_t cpu;
-	uint32_t reg;
+	plat_ic_raise_ns_sgi(sgi, read_mpidr_el1());
+}
+
+static uint64_t cpu_pwrdwn_req_handler(uint32_t id, uint32_t flags,
+				       void *handle, void *cookie)
+{
+	uint32_t cpu_id = plat_my_core_pos();
+
+	VERBOSE("Powering down CPU %d\n", cpu_id);
 
-	cpu = plat_my_core_pos() + 1U;
+	/* Deactivate CPU power down SGI */
+	plat_ic_end_of_interrupt(CPU_PWR_DOWN_REQ_INTR);
 
-	reg = (cpu | (sgi << XSCUGIC_SGIR_EL1_INITID_SHIFT));
-	write_icc_asgi1r_el1(reg);
+	return psci_cpu_off();
 }
 
+/**
+ * raise_pwr_down_interrupt() - Callback function to raise SGI.
+ * @mpidr: MPIDR for the target CPU.
+ *
+ * Raise SGI interrupt to trigger the CPU power down sequence on all the
+ * online secondary cores.
+ */
+static void raise_pwr_down_interrupt(u_register_t mpidr)
+{
+	plat_ic_raise_el3_sgi(CPU_PWR_DOWN_REQ_INTR, mpidr);
+}
+
+void request_cpu_pwrdwn(void)
+{
+	enum pm_ret_status ret;
+
+	VERBOSE("CPU power down request received\n");
+
+	/* Send powerdown request to online secondary core(s) */
+	ret = psci_stop_other_cores(PWRDWN_WAIT_TIMEOUT, raise_pwr_down_interrupt);
+	if (ret != PSCI_E_SUCCESS) {
+		ERROR("Failed to powerdown secondary core(s)\n");
+	}
+
+	/* Clear IPI IRQ */
+	pm_ipi_irq_clear(primary_proc);
+
+	/* Deactivate IPI IRQ */
+	plat_ic_end_of_interrupt(PLAT_VERSAL_IPI_IRQ);
+}
+
 static uint64_t ipi_fiq_handler(uint32_t id, uint32_t flags, void *handle,
 				void *cookie)
 {
@@ -56,6 +100,7 @@
 
 	VERBOSE("Received IPI FIQ from firmware\n");
 
+	console_flush();
 	(void)plat_ic_acknowledge_interrupt();
 
 	ret = pm_get_callbackdata(payload, ARRAY_SIZE(payload), 0, 0);
@@ -65,8 +110,22 @@
 
 	switch (payload[0]) {
 	case PM_INIT_SUSPEND_CB:
+		if (sgi != INVALID_SGI) {
+			notify_os();
+		}
+		break;
 	case PM_NOTIFY_CB:
 		if (sgi != INVALID_SGI) {
+			if (payload[2] == EVENT_CPU_PWRDWN) {
+				if (pwrdwn_req_received) {
+					pwrdwn_req_received = false;
+					request_cpu_pwrdwn();
+					(void)psci_cpu_off();
+					break;
+				} else {
+					pwrdwn_req_received = true;
+				}
+			}
 			notify_os();
 		}
 		break;
@@ -139,6 +198,12 @@
 	pm_ipi_init(primary_proc);
 	pm_up = true;
 
+	/* register SGI handler for CPU power down request */
+	ret = request_intr_type_el3(CPU_PWR_DOWN_REQ_INTR, cpu_pwrdwn_req_handler);
+	if (ret != 0) {
+		WARN("BL31: registering SGI interrupt failed\n");
+	}
+
 	/*
 	 * Enable IPI IRQ
 	 * assume the rich OS is OK to handle callback IRQs now.
diff --git a/plat/xilinx/versal/include/plat_macros.S b/plat/xilinx/versal/include/plat_macros.S
index 41193a5..38f47f6 100644
--- a/plat/xilinx/versal/include/plat_macros.S
+++ b/plat/xilinx/versal/include/plat_macros.S
@@ -103,8 +103,8 @@
 	 * ---------------------------------------------
 	 */
 	.macro plat_crash_print_regs
-	mov_imm	x17, PLAT_GICD_BASE_VALUE
-	mov_imm	x16, PLAT_GICR_BASE_VALUE
+	mov_imm	x17, PLAT_ARM_GICD_BASE
+	mov_imm	x16, PLAT_ARM_GICR_BASE
 	versal_print_gic_regs
 	.endm
 
diff --git a/plat/xilinx/versal/include/platform_def.h b/plat/xilinx/versal/include/platform_def.h
index 286a706..8cf8de0 100644
--- a/plat/xilinx/versal/include/platform_def.h
+++ b/plat/xilinx/versal/include/platform_def.h
@@ -9,6 +9,7 @@
 #define PLATFORM_DEF_H
 
 #include <arch.h>
+#include <plat_common.h>
 #include "versal_def.h"
 
 /*******************************************************************************
@@ -74,8 +75,17 @@
 /*******************************************************************************
  * Platform specific page table and MMU setup constants
  ******************************************************************************/
-#define PLAT_PHY_ADDR_SPACE_SIZE	(1ull << 32)
-#define PLAT_VIRT_ADDR_SPACE_SIZE	(1ull << 32)
+
+#if (BL31_BASE >= (1ULL << 32U))
+/* Address range in High DDR and HBM memory range */
+#define PLAT_ADDR_SPACE_SHIFT		U(42)
+#else
+/* Address range in OCM and Low DDR memory range */
+#define PLAT_ADDR_SPACE_SHIFT		U(32)
+#endif
+
+#define PLAT_PHY_ADDR_SPACE_SIZE        (1ull << PLAT_ADDR_SPACE_SHIFT)
+#define PLAT_VIRT_ADDR_SPACE_SIZE       (1ull << PLAT_ADDR_SPACE_SHIFT)
 
 #define XILINX_OF_BOARD_DTB_MAX_SIZE	U(0x200000)
 
@@ -103,8 +113,8 @@
 #define CACHE_WRITEBACK_SHIFT	6
 #define CACHE_WRITEBACK_GRANULE	(1 << CACHE_WRITEBACK_SHIFT)
 
-#define PLAT_GICD_BASE_VALUE	U(0xF9000000)
-#define PLAT_GICR_BASE_VALUE	U(0xF9080000)
+#define PLAT_ARM_GICD_BASE	U(0xF9000000)
+#define PLAT_ARM_GICR_BASE	U(0xF9080000)
 
 /*
  * Define a list of Group 1 Secure and Group 0 interrupts as per GICv3
@@ -122,6 +132,8 @@
 #define PLAT_VERSAL_G0_IRQ_PROPS(grp) \
 	INTR_PROP_DESC(PLAT_VERSAL_IPI_IRQ, GIC_HIGHEST_SEC_PRIORITY, grp, \
 			GIC_INTR_CFG_EDGE), \
+	INTR_PROP_DESC(CPU_PWR_DOWN_REQ_INTR, GIC_HIGHEST_SEC_PRIORITY, grp, \
+			GIC_INTR_CFG_EDGE)
 
 #define IRQ_MAX		142U
 
diff --git a/plat/xilinx/versal/plat_psci.c b/plat/xilinx/versal/plat_psci.c
index 56d98f7..45b1f1c 100644
--- a/plat/xilinx/versal/plat_psci.c
+++ b/plat/xilinx/versal/plat_psci.c
@@ -14,10 +14,13 @@
 #include <plat/common/platform.h>
 #include <plat_arm.h>
 
+#include "drivers/delay_timer.h"
 #include <plat_private.h>
 #include "pm_api_sys.h"
 #include "pm_client.h"
 #include <pm_common.h>
+#include "pm_ipi.h"
+#include "pm_svc_main.h"
 
 static uintptr_t versal_sec_entry;
 
@@ -145,9 +148,31 @@
  */
 static void __dead2 versal_system_reset(void)
 {
-	/* Send the system reset request to the PMC */
-	(void)pm_system_shutdown(XPM_SHUTDOWN_TYPE_RESET,
-				 pm_get_shutdown_scope(), SECURE_FLAG);
+	uint32_t ret, timeout = 10000U;
+
+	request_cpu_pwrdwn();
+
+	/*
+	 * Send the system reset request to the firmware if power down request
+	 * is not received from firmware.
+	 */
+	if (!pwrdwn_req_received) {
+		(void)pm_system_shutdown(XPM_SHUTDOWN_TYPE_RESET,
+					 pm_get_shutdown_scope(), SECURE_FLAG);
+
+		/*
+		 * Wait for system shutdown request completed and idle callback
+		 * not received.
+		 */
+		do {
+			ret = ipi_mb_enquire_status(primary_proc->ipi->local_ipi_id,
+						    primary_proc->ipi->remote_ipi_id);
+			udelay(100);
+			timeout--;
+		} while ((ret != IPI_MB_STATUS_RECV_PENDING) && (timeout > 0U));
+	}
+
+	(void)psci_cpu_off();
 
 	while (1) {
 		wfi();
@@ -161,6 +186,7 @@
  */
 static void versal_pwr_domain_off(const psci_power_state_t *target_state)
 {
+	uint32_t ret, fw_api_version, version[PAYLOAD_ARG_CNT] = {0U};
 	uint32_t cpu_id = plat_my_core_pos();
 	const struct pm_proc *proc = pm_get_proc(cpu_id);
 
@@ -180,8 +206,17 @@
 	 * invoking CPU_on function, during which resume address will
 	 * be set.
 	 */
-	(void)pm_self_suspend(proc->node_id, MAX_LATENCY, PM_STATE_CPU_IDLE, 0,
-			      SECURE_FLAG);
+	ret = pm_feature_check((uint32_t)PM_SELF_SUSPEND, &version[0], SECURE_FLAG);
+	if (ret == PM_RET_SUCCESS) {
+		fw_api_version = version[0] & 0xFFFFU;
+		if (fw_api_version >= 3U) {
+			(void)pm_self_suspend(proc->node_id, MAX_LATENCY, PM_STATE_CPU_OFF, 0,
+					      SECURE_FLAG);
+		} else {
+			(void)pm_self_suspend(proc->node_id, MAX_LATENCY, PM_STATE_CPU_IDLE, 0,
+					      SECURE_FLAG);
+		}
+	}
 }
 
 /**
diff --git a/plat/xilinx/versal/platform.mk b/plat/xilinx/versal/platform.mk
index 35d6bc7..2f07996 100644
--- a/plat/xilinx/versal/platform.mk
+++ b/plat/xilinx/versal/platform.mk
@@ -11,6 +11,8 @@
 PL011_GENERIC_UART := 1
 IPI_CRC_CHECK := 0
 HARDEN_SLS_ALL := 0
+CPU_PWRDWN_SGI ?= 6
+$(eval $(call add_define_val,CPU_PWR_DOWN_REQ_INTR,ARM_IRQ_SEC_SGI_${CPU_PWRDWN_SGI}))
 
 # A72 Erratum for SoC
 ERRATA_A72_859971 := 1
diff --git a/plat/xilinx/versal/sip_svc_setup.c b/plat/xilinx/versal/sip_svc_setup.c
index b30254d..4441d3e 100644
--- a/plat/xilinx/versal/sip_svc_setup.c
+++ b/plat/xilinx/versal/sip_svc_setup.c
@@ -17,7 +17,6 @@
 #include "pm_svc_main.h"
 
 /* SMC function IDs for SiP Service queries */
-#define VERSAL_SIP_SVC_CALL_COUNT	U(0x8200ff00)
 #define VERSAL_SIP_SVC_UID		U(0x8200ff01)
 #define VERSAL_SIP_SVC_VERSION		U(0x8200ff03)
 
@@ -100,10 +99,6 @@
 
 	/* Let PM SMC handler deal with PM-related requests */
 	switch (smc_fid) {
-	case VERSAL_SIP_SVC_CALL_COUNT:
-		/* PM functions + default functions */
-		SMC_RET1(handle, 2);
-
 	case VERSAL_SIP_SVC_UID:
 		SMC_UUID_RET(handle, versal_sip_uuid);
 
diff --git a/plat/xilinx/versal/versal_gicv3.c b/plat/xilinx/versal/versal_gicv3.c
index 197d047..1750d35 100644
--- a/plat/xilinx/versal/versal_gicv3.c
+++ b/plat/xilinx/versal/versal_gicv3.c
@@ -62,8 +62,8 @@
 }
 
 static const gicv3_driver_data_t versal_gic_data __unused = {
-	.gicd_base = PLAT_GICD_BASE_VALUE,
-	.gicr_base = PLAT_GICR_BASE_VALUE,
+	.gicd_base = PLAT_ARM_GICD_BASE,
+	.gicr_base = PLAT_ARM_GICR_BASE,
 	.interrupt_props = versal_interrupt_props,
 	.interrupt_props_num = ARRAY_SIZE(versal_interrupt_props),
 	.rdistif_num = PLATFORM_CORE_COUNT,
diff --git a/plat/xilinx/versal_net/aarch64/versal_net_helpers.S b/plat/xilinx/versal_net/aarch64/versal_net_helpers.S
index dab8717..1ae879f 100644
--- a/plat/xilinx/versal_net/aarch64/versal_net_helpers.S
+++ b/plat/xilinx/versal_net/aarch64/versal_net_helpers.S
@@ -12,6 +12,7 @@
 
 #include <platform_def.h>
 
+	.globl	plat_arm_calc_core_pos
 	.globl	plat_secondary_cold_boot_setup
 	.globl	plat_is_my_cpu_primary
 	.globl	platform_mem_init
@@ -58,6 +59,16 @@
 	b	plat_core_pos_by_mpidr
 endfunc plat_my_core_pos
 
+	 /* -----------------------------------------------------
+	  * unsigned int plat_arm_calc_core_pos(u_register_t mpidr)
+	  * This function uses the plat_core_pos_by_mpidr()
+	  * definition to get the index of the calling CPU.
+	  * -----------------------------------------------------
+	  */
+func plat_arm_calc_core_pos
+	b	plat_core_pos_by_mpidr
+endfunc plat_arm_calc_core_pos
+
 	/* ---------------------------------------------------------------------
 	 * We don't need to carry out any memory initialization on Versal NET
 	 * platform. The Secure RAM is accessible straight away.
diff --git a/plat/xilinx/versal_net/bl31_versal_net_setup.c b/plat/xilinx/versal_net/bl31_versal_net_setup.c
index 283fee3..614d6d2 100644
--- a/plat/xilinx/versal_net/bl31_versal_net_setup.c
+++ b/plat/xilinx/versal_net/bl31_versal_net_setup.c
@@ -216,8 +216,8 @@
 	prepare_dtb();
 
 	/* Initialize the gic cpu and distributor interfaces */
-	plat_versal_net_gic_driver_init();
-	plat_versal_net_gic_init();
+	plat_arm_gic_driver_init();
+	plat_arm_gic_init();
 }
 
 void bl31_plat_runtime_setup(void)
diff --git a/plat/xilinx/versal_net/include/plat_macros.S b/plat/xilinx/versal_net/include/plat_macros.S
index db7e42b..57f8336 100644
--- a/plat/xilinx/versal_net/include/plat_macros.S
+++ b/plat/xilinx/versal_net/include/plat_macros.S
@@ -109,8 +109,8 @@
 	 * Uncomment it when versions are stable
 	 */
 	/*
-	mov_imm	x17, PLAT_GICD_BASE_VALUE
-	mov_imm	x16, PLAT_GICR_BASE_VALUE
+	mov_imm	x17, PLAT_ARM_GICD_BASE
+	mov_imm	x16, PLAT_ARM_GICR_BASE
 	versal_net_print_gic_regs
 	*/
 	.endm
diff --git a/plat/xilinx/versal_net/include/platform_def.h b/plat/xilinx/versal_net/include/platform_def.h
index 872b6ee..8cb7deb 100644
--- a/plat/xilinx/versal_net/include/platform_def.h
+++ b/plat/xilinx/versal_net/include/platform_def.h
@@ -10,6 +10,7 @@
 #define PLATFORM_DEF_H
 
 #include <arch.h>
+#include <plat_common.h>
 #include "versal_net_def.h"
 
 /*******************************************************************************
@@ -107,8 +108,8 @@
 #define CACHE_WRITEBACK_SHIFT	U(6)
 #define CACHE_WRITEBACK_GRANULE	(1 << CACHE_WRITEBACK_SHIFT)
 
-#define PLAT_GICD_BASE_VALUE	U(0xE2000000)
-#define PLAT_GICR_BASE_VALUE	U(0xE2060000)
+#define PLAT_ARM_GICD_BASE	U(0xE2000000)
+#define PLAT_ARM_GICR_BASE	U(0xE2060000)
 
 /*
  * Define a list of Group 1 Secure and Group 0 interrupts as per GICv3
@@ -118,13 +119,15 @@
 #define PLAT_VERSAL_NET_IPI_IRQ	89
 #define PLAT_VERSAL_IPI_IRQ	PLAT_VERSAL_NET_IPI_IRQ
 
-#define PLAT_VERSAL_NET_G1S_IRQ_PROPS(grp) \
+#define PLAT_ARM_G1S_IRQ_PROPS(grp) \
 	INTR_PROP_DESC(VERSAL_NET_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, grp, \
 			GIC_INTR_CFG_LEVEL)
 
-#define PLAT_VERSAL_NET_G0_IRQ_PROPS(grp) \
+#define PLAT_ARM_G0_IRQ_PROPS(grp) \
 	INTR_PROP_DESC(PLAT_VERSAL_IPI_IRQ, GIC_HIGHEST_SEC_PRIORITY, grp, \
 			GIC_INTR_CFG_EDGE), \
+	INTR_PROP_DESC(CPU_PWR_DOWN_REQ_INTR, GIC_HIGHEST_SEC_PRIORITY, grp, \
+			GIC_INTR_CFG_EDGE)
 
 #define IRQ_MAX		200U
 
diff --git a/plat/xilinx/versal_net/plat_psci.c b/plat/xilinx/versal_net/plat_psci.c
index 6e556cd..fcb32b9 100644
--- a/plat/xilinx/versal_net/plat_psci.c
+++ b/plat/xilinx/versal_net/plat_psci.c
@@ -108,8 +108,8 @@
 
 static void zynqmp_pwr_domain_on_finish(const psci_power_state_t *target_state)
 {
-	plat_versal_net_gic_pcpu_init();
-	plat_versal_net_gic_cpuif_enable();
+	plat_arm_gic_pcpu_init();
+	plat_arm_gic_cpuif_enable();
 }
 
 static void zynqmp_pwr_domain_suspend_finish(const psci_power_state_t *target_state)
diff --git a/plat/xilinx/versal_net/plat_psci_pm.c b/plat/xilinx/versal_net/plat_psci_pm.c
index 87e25bc..94cb7f5 100644
--- a/plat/xilinx/versal_net/plat_psci_pm.c
+++ b/plat/xilinx/versal_net/plat_psci_pm.c
@@ -14,10 +14,12 @@
 #include <plat/common/platform.h>
 #include <plat_arm.h>
 
+#include <drivers/delay_timer.h>
 #include <plat_private.h>
 #include "pm_api_sys.h"
 #include "pm_client.h"
 #include <pm_common.h>
+#include "pm_ipi.h"
 #include "pm_svc_main.h"
 #include "versal_net_def.h"
 
@@ -57,6 +59,7 @@
  */
 static void versal_net_pwr_domain_off(const psci_power_state_t *target_state)
 {
+	uint32_t ret, fw_api_version, version[PAYLOAD_ARG_CNT] = {0U};
 	uint32_t cpu_id = plat_my_core_pos();
 	const struct pm_proc *proc = pm_get_proc(cpu_id);
 
@@ -66,7 +69,7 @@
 	}
 
 	/* Prevent interrupts from spuriously waking up this cpu */
-	plat_versal_net_gic_cpuif_disable();
+	plat_arm_gic_cpuif_disable();
 
 	/*
 	 * Send request to PMC to power down the appropriate APU CPU
@@ -76,8 +79,17 @@
 	 * invoking CPU_on function, during which resume address will
 	 * be set.
 	 */
-	pm_self_suspend(proc->node_id, MAX_LATENCY, PM_STATE_CPU_IDLE, 0,
-			SECURE_FLAG);
+	ret = pm_feature_check((uint32_t)PM_SELF_SUSPEND, &version[0], SECURE_FLAG);
+	if (ret == PM_RET_SUCCESS) {
+		fw_api_version = version[0] & 0xFFFFU;
+		if (fw_api_version >= 3U) {
+			(void)pm_self_suspend(proc->node_id, MAX_LATENCY, PM_STATE_CPU_OFF, 0,
+					      SECURE_FLAG);
+		} else {
+			(void)pm_self_suspend(proc->node_id, MAX_LATENCY, PM_STATE_CPU_IDLE, 0,
+					      SECURE_FLAG);
+		}
+	}
 }
 
 /**
@@ -88,9 +100,31 @@
  */
 static void __dead2 versal_net_system_reset(void)
 {
-	/* Send the system reset request to the PMC */
-	pm_system_shutdown(XPM_SHUTDOWN_TYPE_RESET,
-			  pm_get_shutdown_scope(), SECURE_FLAG);
+	uint32_t ret, timeout = 10000U;
+
+	request_cpu_pwrdwn();
+
+	/*
+	 * Send the system reset request to the firmware if power down request
+	 * is not received from firmware.
+	 */
+	if (!pwrdwn_req_received) {
+		(void)pm_system_shutdown(XPM_SHUTDOWN_TYPE_RESET,
+					 pm_get_shutdown_scope(), SECURE_FLAG);
+
+		/*
+		 * Wait for system shutdown request completed and idle callback
+		 * not received.
+		 */
+		do {
+			ret = ipi_mb_enquire_status(primary_proc->ipi->local_ipi_id,
+						    primary_proc->ipi->remote_ipi_id);
+			udelay(100);
+			timeout--;
+		} while ((ret != IPI_MB_STATUS_RECV_PENDING) && (timeout > 0U));
+	}
+
+	(void)psci_cpu_off();
 
 	while (1) {
 		wfi();
@@ -114,10 +148,10 @@
 			__func__, i, target_state->pwr_domain_state[i]);
 	}
 
-	plat_versal_net_gic_cpuif_disable();
+	plat_arm_gic_cpuif_disable();
 
 	if (target_state->pwr_domain_state[1] > PLAT_MAX_RET_STATE) {
-		plat_versal_net_gic_save();
+		plat_arm_gic_save();
 	}
 
 	state = target_state->pwr_domain_state[1] > PLAT_MAX_RET_STATE ?
@@ -135,10 +169,10 @@
 	(void)target_state;
 
 	/* Enable the gic cpu interface */
-	plat_versal_net_gic_pcpu_init();
+	plat_arm_gic_pcpu_init();
 
 	/* Program the gic per-cpu distributor or re-distributor interface */
-	plat_versal_net_gic_cpuif_enable();
+	plat_arm_gic_cpuif_enable();
 }
 
 /**
@@ -163,10 +197,10 @@
 
 	/* APU was turned off, so restore GIC context */
 	if (target_state->pwr_domain_state[1] > PLAT_MAX_RET_STATE) {
-		plat_versal_net_gic_resume();
+		plat_arm_gic_resume();
 	}
 
-	plat_versal_net_gic_cpuif_enable();
+	plat_arm_gic_cpuif_enable();
 }
 
 /**
diff --git a/plat/xilinx/versal_net/platform.mk b/plat/xilinx/versal_net/platform.mk
index ad1ee2b..da91abc 100644
--- a/plat/xilinx/versal_net/platform.mk
+++ b/plat/xilinx/versal_net/platform.mk
@@ -21,6 +21,8 @@
 GIC_ENABLE_V4_EXTN :=  0
 GICV3_SUPPORT_GIC600 := 1
 TFA_NO_PM := 0
+CPU_PWRDWN_SGI ?= 6
+$(eval $(call add_define_val,CPU_PWR_DOWN_REQ_INTR,ARM_IRQ_SEC_SGI_${CPU_PWRDWN_SGI}))
 
 override CTX_INCLUDE_AARCH32_REGS    := 0
 
@@ -121,6 +123,7 @@
 				${PLAT_PATH}/bl31_versal_net_setup.c		\
 				common/fdt_fixup.c				\
 				common/fdt_wrappers.c				\
+				plat/arm/common/arm_gicv3.c 			\
 				${LIBFDT_SRCS}					\
 				${PLAT_PATH}/sip_svc_setup.c			\
-				${PLAT_PATH}/versal_net_gicv3.c
+				${XLAT_TABLES_LIB_SRCS}
diff --git a/plat/xilinx/versal_net/sip_svc_setup.c b/plat/xilinx/versal_net/sip_svc_setup.c
index 0c27dec..80d5a53 100644
--- a/plat/xilinx/versal_net/sip_svc_setup.c
+++ b/plat/xilinx/versal_net/sip_svc_setup.c
@@ -20,7 +20,6 @@
 #include "pm_svc_main.h"
 
 /* SMC function IDs for SiP Service queries */
-#define VERSAL_NET_SIP_SVC_CALL_COUNT	(0x8200ff00U)
 #define VERSAL_NET_SIP_SVC_UID		(0x8200ff01U)
 #define VERSAL_NET_SIP_SVC_VERSION	(0x8200ff03U)
 
@@ -88,10 +87,6 @@
 
 	/* Let PM SMC handler deal with PM-related requests */
 	switch (smc_fid) {
-	case VERSAL_NET_SIP_SVC_CALL_COUNT:
-		/* PM functions + default functions */
-		SMC_RET1(handle, 2);
-
 	case VERSAL_NET_SIP_SVC_UID:
 		SMC_UUID_RET(handle, versal_net_sip_uuid);
 
diff --git a/plat/xilinx/versal_net/versal_net_gicv3.c b/plat/xilinx/versal_net/versal_net_gicv3.c
deleted file mode 100644
index 2fdef12..0000000
--- a/plat/xilinx/versal_net/versal_net_gicv3.c
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * Copyright (c) 2018-2019, Arm Limited and Contributors. All rights reserved.
- * Copyright (c) 2018-2022, Xilinx, Inc. All rights reserved.
- * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <common/debug.h>
-#include <common/interrupt_props.h>
-#include <drivers/arm/gicv3.h>
-#include <lib/utils.h>
-#include <plat/common/platform.h>
-
-#include <plat_private.h>
-#include <platform_def.h>
-
-/******************************************************************************
- * The following functions are defined as weak to allow a platform to override
- * the way the GICv3 driver is initialised and used.
- *****************************************************************************/
-#pragma weak plat_versal_net_gic_driver_init
-#pragma weak plat_versal_net_gic_init
-#pragma weak plat_versal_net_gic_cpuif_enable
-#pragma weak plat_versal_net_gic_cpuif_disable
-#pragma weak plat_versal_net_gic_pcpu_init
-#pragma weak plat_versal_net_gic_redistif_on
-#pragma weak plat_versal_net_gic_redistif_off
-
-/* The GICv3 driver only needs to be initialized in EL3 */
-static uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT];
-
-static const interrupt_prop_t versal_net_interrupt_props[] = {
-	PLAT_VERSAL_NET_G1S_IRQ_PROPS(INTR_GROUP1S),
-	PLAT_VERSAL_NET_G0_IRQ_PROPS(INTR_GROUP0)
-};
-
-/*
- * We save and restore the GICv3 context on system suspend. Allocate the
- * data in the designated EL3 Secure carve-out memory.
- */
-static gicv3_redist_ctx_t rdist_ctx __section(".versal_net_el3_tzc_dram");
-static gicv3_dist_ctx_t dist_ctx __section(".versal_net_el3_tzc_dram");
-
-/*
- * MPIDR hashing function for translating MPIDRs read from GICR_TYPER register
- * to core position.
- *
- * Calculating core position is dependent on MPIDR_EL1.MT bit. However, affinity
- * values read from GICR_TYPER don't have an MT field. To reuse the same
- * translation used for CPUs, we insert MT bit read from the PE's MPIDR into
- * that read from GICR_TYPER.
- *
- * Assumptions:
- *
- *   - All CPUs implemented in the system have MPIDR_EL1.MT bit set;
- *   - No CPUs implemented in the system use affinity level 3.
- */
-static uint32_t versal_net_gicv3_mpidr_hash(u_register_t mpidr)
-{
-	mpidr |= (read_mpidr_el1() & MPIDR_MT_MASK);
-	return plat_core_pos_by_mpidr(mpidr);
-}
-
-static const gicv3_driver_data_t versal_net_gic_data __unused = {
-	.gicd_base = PLAT_GICD_BASE_VALUE,
-	.gicr_base = PLAT_GICR_BASE_VALUE,
-	.interrupt_props = versal_net_interrupt_props,
-	.interrupt_props_num = ARRAY_SIZE(versal_net_interrupt_props),
-	.rdistif_num = PLATFORM_CORE_COUNT,
-	.rdistif_base_addrs = rdistif_base_addrs,
-	.mpidr_to_core_pos = versal_net_gicv3_mpidr_hash
-};
-
-void __init plat_versal_net_gic_driver_init(void)
-{
-	/*
-	 * The GICv3 driver is initialized in EL3 and does not need
-	 * to be initialized again in SEL1. This is because the S-EL1
-	 * can use GIC system registers to manage interrupts and does
-	 * not need GIC interface base addresses to be configured.
-	 */
-#if IMAGE_BL31
-	gicv3_driver_init(&versal_net_gic_data);
-#endif
-}
-
-/******************************************************************************
- * Versal NET common helper to initialize the GIC. Only invoked by BL31
- *****************************************************************************/
-void __init plat_versal_net_gic_init(void)
-{
-	gicv3_distif_init();
-	gicv3_rdistif_init(plat_my_core_pos());
-	gicv3_cpuif_enable(plat_my_core_pos());
-}
-
-/******************************************************************************
- * Versal NET common helper to enable the GIC CPU interface
- *****************************************************************************/
-void plat_versal_net_gic_cpuif_enable(void)
-{
-	gicv3_cpuif_enable(plat_my_core_pos());
-}
-
-/******************************************************************************
- * Versal NET common helper to disable the GIC CPU interface
- *****************************************************************************/
-void plat_versal_net_gic_cpuif_disable(void)
-{
-	gicv3_cpuif_disable(plat_my_core_pos());
-}
-
-/******************************************************************************
- * Versal NET common helper to initialize the per-cpu redistributor interface in
- * GICv3
- *****************************************************************************/
-void plat_versal_net_gic_pcpu_init(void)
-{
-	gicv3_rdistif_init(plat_my_core_pos());
-}
-
-/******************************************************************************
- * Versal NET common helpers to power GIC redistributor interface
- *****************************************************************************/
-void plat_versal_net_gic_redistif_on(void)
-{
-	gicv3_rdistif_on(plat_my_core_pos());
-}
-
-void plat_versal_net_gic_redistif_off(void)
-{
-	gicv3_rdistif_off(plat_my_core_pos());
-}
-
-/******************************************************************************
- * Versal NET common helper to save & restore the GICv3 on resume from system
- * suspend
- *****************************************************************************/
-void plat_versal_net_gic_save(void)
-{
-	/*
-	 * If an ITS is available, save its context before
-	 * the Redistributor using:
-	 * gicv3_its_save_disable(gits_base, &its_ctx[i])
-	 * Additionnaly, an implementation-defined sequence may
-	 * be required to save the whole ITS state.
-	 */
-
-	/*
-	 * Save the GIC Redistributors and ITS contexts before the
-	 * Distributor context. As we only handle SYSTEM SUSPEND API,
-	 * we only need to save the context of the CPU that is issuing
-	 * the SYSTEM SUSPEND call, i.e. the current CPU.
-	 */
-	gicv3_rdistif_save(plat_my_core_pos(), &rdist_ctx);
-
-	/* Save the GIC Distributor context */
-	gicv3_distif_save(&dist_ctx);
-
-	/*
-	 * From here, all the components of the GIC can be safely powered down
-	 * as long as there is an alternate way to handle wakeup interrupt
-	 * sources.
-	 */
-}
-
-void plat_versal_net_gic_resume(void)
-{
-	/* Restore the GIC Distributor context */
-	gicv3_distif_init_restore(&dist_ctx);
-
-	/*
-	 * Restore the GIC Redistributor and ITS contexts after the
-	 * Distributor context. As we only handle SYSTEM SUSPEND API,
-	 * we only need to restore the context of the CPU that issued
-	 * the SYSTEM SUSPEND call.
-	 */
-	gicv3_rdistif_init_restore(plat_my_core_pos(), &rdist_ctx);
-
-	/*
-	 * If an ITS is available, restore its context after
-	 * the Redistributor using:
-	 * gicv3_its_restore(gits_base, &its_ctx[i])
-	 * An implementation-defined sequence may be required to
-	 * restore the whole ITS state. The ITS must also be
-	 * re-enabled after this sequence has been executed.
-	 */
-}
diff --git a/plat/xilinx/zynqmp/sip_svc_setup.c b/plat/xilinx/zynqmp/sip_svc_setup.c
index 6a8555e..f5990ca 100644
--- a/plat/xilinx/zynqmp/sip_svc_setup.c
+++ b/plat/xilinx/zynqmp/sip_svc_setup.c
@@ -18,7 +18,6 @@
 #include "zynqmp_pm_svc_main.h"
 
 /* SMC function IDs for SiP Service queries */
-#define ZYNQMP_SIP_SVC_CALL_COUNT	U(0x8200ff00)
 #define ZYNQMP_SIP_SVC_UID		U(0x8200ff01)
 #define ZYNQMP_SIP_SVC_VERSION		U(0x8200ff03)
 
@@ -100,10 +99,6 @@
 	}
 
 	switch (smc_fid) {
-	case ZYNQMP_SIP_SVC_CALL_COUNT:
-		/* PM functions + default functions */
-		SMC_RET1(handle, PM_API_MAX + 2);
-
 	case ZYNQMP_SIP_SVC_UID:
 		SMC_UUID_RET(handle, zynqmp_sip_uuid);
 
diff --git a/services/spd/opteed/opteed_common.c b/services/spd/opteed/opteed_common.c
index 9aa19c5..8a769fb 100644
--- a/services/spd/opteed/opteed_common.c
+++ b/services/spd/opteed/opteed_common.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -20,9 +20,9 @@
  * initialize OPTEE context and entry point info for OPTEE.
  ******************************************************************************/
 void opteed_init_optee_ep_state(struct entry_point_info *optee_entry_point,
-				uint32_t rw, uint64_t pc,
-				uint64_t pageable_part, uint64_t mem_limit,
-				uint64_t dt_addr, optee_context_t *optee_ctx)
+				uint32_t rw, uint64_t pc, uint64_t arg0,
+				uint64_t arg1, uint64_t arg2, uint64_t arg3,
+				optee_context_t *optee_ctx)
 {
 	uint32_t ep_attr;
 
@@ -54,9 +54,10 @@
 							DAIF_IRQ_BIT |
 							DAIF_ABT_BIT);
 	zeromem(&optee_entry_point->args, sizeof(optee_entry_point->args));
-	optee_entry_point->args.arg0 = pageable_part;
-	optee_entry_point->args.arg1 = mem_limit;
-	optee_entry_point->args.arg2 = dt_addr;
+	optee_entry_point->args.arg0 = arg0;
+	optee_entry_point->args.arg1 = arg1;
+	optee_entry_point->args.arg2 = arg2;
+	optee_entry_point->args.arg3 = arg3;
 }
 
 /*******************************************************************************
diff --git a/services/spd/opteed/opteed_main.c b/services/spd/opteed/opteed_main.c
index 4d055db..ab9896e 100644
--- a/services/spd/opteed/opteed_main.c
+++ b/services/spd/opteed/opteed_main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -27,6 +27,7 @@
 #include <lib/coreboot.h>
 #include <lib/el3_runtime/context_mgmt.h>
 #include <lib/optee_utils.h>
+#include <lib/transfer_list.h>
 #include <lib/xlat_tables/xlat_tables_v2.h>
 #if OPTEE_ALLOW_SMC_LOAD
 #include <libfdt.h>
@@ -37,6 +38,10 @@
 #include "opteed_private.h"
 #include "teesmc_opteed.h"
 
+#if OPTEE_ALLOW_SMC_LOAD
+static struct transfer_list_header *bl31_tl;
+#endif
+
 /*******************************************************************************
  * Address of the entrypoint vector table in OPTEE. It is
  * initialised once on the primary core after a cold boot.
@@ -123,9 +128,13 @@
 #else
 	entry_point_info_t *optee_ep_info;
 	uint32_t linear_id;
-	uint64_t opteed_pageable_part;
-	uint64_t opteed_mem_limit;
-	uint64_t dt_addr;
+	uint64_t arg0;
+	uint64_t arg1;
+	uint64_t arg2;
+	uint64_t arg3;
+	struct transfer_list_header *tl = NULL;
+	struct transfer_list_entry *te = NULL;
+	void *dt = NULL;
 
 	linear_id = plat_my_core_pos();
 
@@ -150,17 +159,39 @@
 	if (!optee_ep_info->pc)
 		return 1;
 
-	opteed_rw = optee_ep_info->args.arg0;
-	opteed_pageable_part = optee_ep_info->args.arg1;
-	opteed_mem_limit = optee_ep_info->args.arg2;
-	dt_addr = optee_ep_info->args.arg3;
+	if (TRANSFER_LIST &&
+		optee_ep_info->args.arg1 == (TRANSFER_LIST_SIGNATURE |
+					REGISTER_CONVENTION_VERSION_MASK)) {
+		tl = (void *)optee_ep_info->args.arg3;
+		if (transfer_list_check_header(tl) == TL_OPS_NON) {
+			return 1;
+		}
 
-	opteed_init_optee_ep_state(optee_ep_info,
-				opteed_rw,
-				optee_ep_info->pc,
-				opteed_pageable_part,
-				opteed_mem_limit,
-				dt_addr,
+		opteed_rw = GET_RW(optee_ep_info->spsr);
+		te = transfer_list_find(tl, TL_TAG_FDT);
+		dt = transfer_list_entry_data(te);
+
+		if (opteed_rw == OPTEE_AARCH64) {
+			arg0 = (uint64_t)dt;
+			arg2 = 0;
+		} else {
+			arg2 = (uint64_t)dt;
+			arg0 = 0;
+		}
+
+		arg1 = optee_ep_info->args.arg1;
+		arg3 = optee_ep_info->args.arg3;
+	} else {
+		/* Default handoff arguments */
+		opteed_rw = optee_ep_info->args.arg0;
+		arg0 = optee_ep_info->args.arg1; /* opteed_pageable_part */
+		arg1 = optee_ep_info->args.arg2; /* opteed_mem_limit */
+		arg2 = optee_ep_info->args.arg3; /* dt_addr */
+		arg3 = 0;
+	}
+
+	opteed_init_optee_ep_state(optee_ep_info, opteed_rw, optee_ep_info->pc,
+				arg0, arg1, arg2, arg3,
 				&opteed_sp_context[linear_id]);
 
 	/*
@@ -302,6 +333,26 @@
 	return fdt_finish(fdt_buf);
 }
 
+static int32_t create_smc_tl(const void *fdt, uint32_t fdt_sz)
+{
+#if TRANSFER_LIST
+	bl31_tl = transfer_list_init((void *)(uintptr_t)FW_HANDOFF_BASE,
+				FW_HANDOFF_SIZE);
+	if (!bl31_tl) {
+		ERROR("Failed to initialize Transfer List at 0x%lx\n",
+		(unsigned long)FW_HANDOFF_BASE);
+		return -1;
+	}
+
+	if (!transfer_list_add(bl31_tl, TL_TAG_FDT, fdt_sz, fdt)) {
+		return -1;
+	}
+	return 0;
+#else
+	return -1;
+#endif
+}
+
 /*******************************************************************************
  * This function is responsible for handling the SMC that loads the OP-TEE
  * binary image via a non-secure SMC call. It takes the size and physical
@@ -326,6 +377,10 @@
 	entry_point_info_t optee_ep_info;
 	uint32_t linear_id = plat_my_core_pos();
 	uint64_t dt_addr = 0;
+	uint64_t arg0 = 0;
+	uint64_t arg1 = 0;
+	uint64_t arg2 = 0;
+	uint64_t arg3 = 0;
 
 	mapped_data_pa = page_align(data_pa, DOWN);
 	mapped_data_va = mapped_data_pa;
@@ -394,12 +449,36 @@
 	dt_addr = (uint64_t)fdt_buf;
 	flush_dcache_range(dt_addr, OPTEED_FDT_SIZE);
 
+	if (TRANSFER_LIST &&
+	    !create_smc_tl((void *)dt_addr, OPTEED_FDT_SIZE)) {
+		struct transfer_list_entry *te = NULL;
+		void *dt = NULL;
+
+		te = transfer_list_find(bl31_tl, TL_TAG_FDT);
+		dt = transfer_list_entry_data(te);
+
+		if (opteed_rw == OPTEE_AARCH64) {
+			arg0 = (uint64_t)dt;
+			arg2 = 0;
+		} else {
+			arg2 = (uint64_t)dt;
+			arg0 = 0;
+		}
+		arg1 = TRANSFER_LIST_SIGNATURE |
+			REGISTER_CONVENTION_VERSION_MASK;
+		arg3 = (uint64_t)bl31_tl;
+	} else {
+		/* Default handoff arguments */
+		arg2 = dt_addr;
+	}
+
 	opteed_init_optee_ep_state(&optee_ep_info,
 				   opteed_rw,
 				   image_pa,
-				   0,
-				   0,
-				   dt_addr,
+				   arg0,
+				   arg1,
+				   arg2,
+				   arg3,
 				   &opteed_sp_context[linear_id]);
 	if (opteed_init_with_entry_point(&optee_ep_info) == 0) {
 		rc = -EFAULT;
diff --git a/services/spd/opteed/opteed_pm.c b/services/spd/opteed/opteed_pm.c
index fa724a1..c949823 100644
--- a/services/spd/opteed/opteed_pm.c
+++ b/services/spd/opteed/opteed_pm.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -113,7 +113,7 @@
 
 	opteed_init_optee_ep_state(&optee_on_entrypoint, opteed_rw,
 				(uint64_t)&optee_vector_table->cpu_on_entry,
-				0, 0, 0, optee_ctx);
+				0, 0, 0, 0, optee_ctx);
 
 	/* Initialise this cpu's secure context */
 	cm_init_my_context(&optee_on_entrypoint);
diff --git a/services/spd/opteed/opteed_private.h b/services/spd/opteed/opteed_private.h
index c8fbc22..c484516 100644
--- a/services/spd/opteed/opteed_private.h
+++ b/services/spd/opteed/opteed_private.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -148,11 +148,8 @@
 uint64_t opteed_synchronous_sp_entry(optee_context_t *optee_ctx);
 void __dead2 opteed_synchronous_sp_exit(optee_context_t *optee_ctx, uint64_t ret);
 void opteed_init_optee_ep_state(struct entry_point_info *optee_entry_point,
-				uint32_t rw,
-				uint64_t pc,
-				uint64_t pageable_part,
-				uint64_t mem_limit,
-				uint64_t dt_addr,
+				uint32_t rw, uint64_t pc, uint64_t arg0,
+				uint64_t arg1, uint64_t arg2, uint64_t arg3,
 				optee_context_t *optee_ctx);
 void opteed_cpu_on_finish_handler(u_register_t unused);
 
diff --git a/services/std_svc/spm/el3_spmc/spmc_main.c b/services/std_svc/spm/el3_spmc/spmc_main.c
index 7978f08..9cfcd87 100644
--- a/services/std_svc/spm/el3_spmc/spmc_main.c
+++ b/services/std_svc/spm/el3_spmc/spmc_main.c
@@ -1,11 +1,12 @@
 /*
- * Copyright (c) 2022-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2024, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <assert.h>
 #include <errno.h>
+#include <stdio.h>
 
 #include <arch_helpers.h>
 #include <bl31/bl31.h>
@@ -1290,6 +1291,8 @@
 	case FFA_MSG_SEND_DIRECT_RESP_SMC64:
 	case FFA_MEM_RELINQUISH:
 	case FFA_MSG_WAIT:
+	case FFA_CONSOLE_LOG_SMC32:
+	case FFA_CONSOLE_LOG_SMC64:
 
 		if (!secure_origin) {
 			return spmc_ffa_error_return(handle,
@@ -1476,6 +1479,61 @@
 	SMC_RET1(handle, FFA_SUCCESS_SMC32);
 }
 
+static uint64_t spmc_ffa_console_log(uint32_t smc_fid,
+				     bool secure_origin,
+				     uint64_t x1,
+				     uint64_t x2,
+				     uint64_t x3,
+				     uint64_t x4,
+				     void *cookie,
+				     void *handle,
+				     uint64_t flags)
+{
+	char *chars;
+	size_t chars_max;
+	size_t chars_count = x1;
+
+	/* Does not support request from Nwd. */
+	if (!secure_origin) {
+		return spmc_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED);
+	}
+
+	assert(smc_fid == FFA_CONSOLE_LOG_SMC32 || smc_fid == FFA_CONSOLE_LOG_SMC64);
+	if (smc_fid == FFA_CONSOLE_LOG_SMC32) {
+		uint32_t registers[] = {
+			(uint32_t)x2,
+			(uint32_t)x3,
+			(uint32_t)x4,
+			(uint32_t)SMC_GET_GP(handle, CTX_GPREG_X5),
+			(uint32_t)SMC_GET_GP(handle, CTX_GPREG_X6),
+			(uint32_t)SMC_GET_GP(handle, CTX_GPREG_X7),
+		};
+		chars_max = ARRAY_SIZE(registers) * sizeof(uint32_t);
+		chars = (char *)registers;
+	} else {
+		uint64_t registers[] = {
+			x2,
+			x3,
+			x4,
+			SMC_GET_GP(handle, CTX_GPREG_X5),
+			SMC_GET_GP(handle, CTX_GPREG_X6),
+			SMC_GET_GP(handle, CTX_GPREG_X7),
+		};
+		chars_max = ARRAY_SIZE(registers) * sizeof(uint64_t);
+		chars = (char *)registers;
+	}
+
+	if ((chars_count == 0) || (chars_count > chars_max)) {
+		return spmc_ffa_error_return(handle, FFA_ERROR_INVALID_PARAMETER);
+	}
+
+	for (size_t i = 0; (i < chars_count) && (chars[i] != '\0'); i++) {
+		putchar(chars[i]);
+	}
+
+	SMC_RET1(handle, FFA_SUCCESS_SMC32);
+}
+
 /*
  * Perform initial validation on the provided secondary entry point.
  * For now ensure it does not lie within the BL31 Image or the SP's
@@ -2365,7 +2423,11 @@
 
 	case FFA_MEM_RECLAIM:
 		return spmc_ffa_mem_reclaim(smc_fid, secure_origin, x1, x2, x3,
-					    x4, cookie, handle, flags);
+						x4, cookie, handle, flags);
+	case FFA_CONSOLE_LOG_SMC32:
+	case FFA_CONSOLE_LOG_SMC64:
+		return spmc_ffa_console_log(smc_fid, secure_origin, x1, x2, x3,
+						x4, cookie, handle, flags);
 
 	case FFA_MEM_PERM_GET:
 		return ffa_mem_perm_get_handler(smc_fid, secure_origin, x1, x2,
diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c
index 066571e..5d19868 100644
--- a/services/std_svc/spmd/spmd_main.c
+++ b/services/std_svc/spmd/spmd_main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -1151,6 +1151,25 @@
 		}
 		break; /* Not reached */
 
+	case FFA_MSG_SEND_DIRECT_REQ2_SMC64:
+		if (!secure_origin) {
+			/* Validate source endpoint is non-secure for non-secure caller. */
+			if (ffa_is_secure_world_id(ffa_endpoint_source(x1))) {
+				return spmd_ffa_error_return(handle,
+						FFA_ERROR_INVALID_PARAMETER);
+			}
+		}
+		/* FFA_MSG_SEND_DIRECT_REQ2 not used for framework messages. */
+		if (secure_origin && spmd_is_spmc_message(x1)) {
+			return spmd_ffa_error_return(handle, FFA_ERROR_INVALID_PARAMETER);
+		} else {
+			/* Forward direct message to the other world */
+			return spmd_smc_forward(smc_fid, secure_origin,
+						x1, x2, x3, x4, cookie,
+						handle, flags);
+		}
+		break; /* Not reached */
+
 	case FFA_MSG_SEND_DIRECT_RESP_SMC32:
 	case FFA_MSG_SEND_DIRECT_RESP_SMC64:
 		if (secure_origin && (spmd_is_spmc_message(x1) ||
@@ -1163,7 +1182,12 @@
 						handle, flags);
 		}
 		break; /* Not reached */
-
+	case FFA_MSG_SEND_DIRECT_RESP2_SMC64:
+		/* Forward direct message to the other world */
+		return spmd_smc_forward(smc_fid, secure_origin,
+					x1, x2, x3, x4, cookie,
+					handle, flags);
+		break; /* Not reached */
 	case FFA_RX_RELEASE:
 	case FFA_RXTX_MAP_SMC32:
 	case FFA_RXTX_MAP_SMC64:
@@ -1279,6 +1303,12 @@
 					handle, flags);
 		break; /* Not reached */
 #endif
+	case FFA_CONSOLE_LOG_SMC32:
+	case FFA_CONSOLE_LOG_SMC64:
+		/* This interface must not be forwarded to other worlds. */
+		return spmd_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED);
+		break; /* not reached */
+
 	case FFA_EL3_INTR_HANDLE:
 		if (secure_origin) {
 			return spmd_handle_group0_intr_swd(handle);
diff --git a/plat/arm/board/juno/fip/plat_def_uuid_config.c b/tools/fiptool/plat_fiptool/arm/board/juno/plat_def_uuid_config.c
similarity index 100%
rename from plat/arm/board/juno/fip/plat_def_uuid_config.c
rename to tools/fiptool/plat_fiptool/arm/board/juno/plat_def_uuid_config.c
diff --git a/tools/fiptool/plat_fiptool/arm/board/juno/plat_fiptool.mk b/tools/fiptool/plat_fiptool/arm/board/juno/plat_fiptool.mk
index fef2116..5549b0d 100644
--- a/tools/fiptool/plat_fiptool/arm/board/juno/plat_fiptool.mk
+++ b/tools/fiptool/plat_fiptool/arm/board/juno/plat_fiptool.mk
@@ -11,6 +11,6 @@
 ifeq (${ETHOSN_NPU_TZMP1},1)
 HOSTCCFLAGS += -DETHOSN_NPU_TZMP1
 endif
-INCLUDE_PATHS += -I./ -I${PLAT_DIR}fip -I../../include/
-OBJECTS += ${PLAT_DIR}fip/plat_def_uuid_config.o
+INCLUDE_PATHS += -I./ -I../../plat/arm/board/juno/fip -I../../include
+OBJECTS += plat_fiptool/arm/board/juno/plat_def_uuid_config.o
 endif
diff --git a/tools/marvell/doimage/doimage.c b/tools/marvell/doimage/doimage.c
index 513f33f..1f0985c 100644
--- a/tools/marvell/doimage/doimage.c
+++ b/tools/marvell/doimage/doimage.c
@@ -18,6 +18,7 @@
 #include <libconfig.h>	/* for parsing config file */
 
 /* mbedTLS stuff */
+#include <mbedtls/version.h>
 #if defined(MBEDTLS_BIGNUM_C) && defined(MBEDTLS_ENTROPY_C) && \
 	defined(MBEDTLS_SHA256_C) && \
 	defined(MBEDTLS_PK_PARSE_C) && defined(MBEDTLS_FS_IO) && \
@@ -28,7 +29,6 @@
 #include <mbedtls/md.h>
 #include <mbedtls/pk.h>
 #include <mbedtls/sha256.h>
-#include <mbedtls/version.h>
 #include <mbedtls/x509.h>
 #else
 #error "Bad mbedTLS configuration!"
diff --git a/tools/memory/memory/memmap.py b/tools/memory/memory/memmap.py
index 99149b5..34f5069 100755
--- a/tools/memory/memory/memmap.py
+++ b/tools/memory/memory/memmap.py
@@ -1,7 +1,7 @@
 #!/usr/bin/env python3
 
 #
-# Copyright (c) 2023, Arm Limited. All rights reserved.
+# Copyright (c) 2023-2024, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -99,7 +99,7 @@
 
     if symbols:
         expr = (
-            r"(.*)(TEXT|BSS|RODATA|STACKS|_OPS|PMF|XLAT|GOT|FCONF"
+            r"(.*)(TEXT|BSS|RO|RODATA|STACKS|_OPS|PMF|XLAT|GOT|FCONF|RELA"
             r"|R.M)(.*)(START|UNALIGNED|END)__$"
         )
         printer.print_symbol_table(
diff --git a/tools/sptool/sp_mk_generator.py b/tools/sptool/sp_mk_generator.py
index 06fa520..1edb77d 100644
--- a/tools/sptool/sp_mk_generator.py
+++ b/tools/sptool/sp_mk_generator.py
@@ -137,7 +137,7 @@
     with open(get_sp_manifest_full_path(sp_layout[sp], args), "r") as pm_f:
         load_address_lines = [l for l in pm_f if 'load-address' in l]
 
-    if len(load_address_lines) is not 1:
+    if len(load_address_lines) != 1:
         return None
 
     load_address_parsed = re.search("(0x[0-9a-f]+)", load_address_lines[0])