Merge changes from topic "cot-dt2c" into integration

* changes:
  feat(arm): update documentation for cot-dt2c
  feat(arm): remove the bl2 static c file
  feat(arm): generate tbbr c file CoT dt2c
  feat(arm): makefile invoke CoT dt2c
  feat(auth): standalone CoT dt2c tool
  refactor(auth): separate bl1 and bl2 CoT
  refactor(st): align the NV counter naming
  refactor(fvp): align the NV counter naming
diff --git a/docs/components/ffa-manifest-binding.rst b/docs/components/ffa-manifest-binding.rst
index ee322ac..29b89b2 100644
--- a/docs/components/ffa-manifest-binding.rst
+++ b/docs/components/ffa-manifest-binding.rst
@@ -1,5 +1,5 @@
 FF-A manifest binding to device tree
-========================================
+====================================
 
 This document defines the nodes and properties used to define a partition,
 according to the FF-A specification.
@@ -82,7 +82,7 @@
      the partition. Absence of this field indicates that the entry point is at
      offset 0x0 from the base of the partition's binary.
 
-- xlat-granule [mandatory]
+- xlat-granule
    - value type: <u32>
    - Translation granule used with the partition:
 
@@ -91,10 +91,10 @@
       - 0x2: 64k
 
 - boot-order
-   - value type: <u16>
+   - value type: <u32>
    - A unique number amongst all partitions that specifies if this partition
      must be booted before others. The partition with the smaller number will be
-     booted first.
+     booted first. Highest vlue allowed for this field is 0xFFFF.
 
 - rx-tx-buffer
    - value type: "memory-regions" node
@@ -103,13 +103,15 @@
      The "compatible" must be the string "arm,ffa-manifest-rx_tx-buffer".
 
 - messaging-method [mandatory]
-   - value type: <u8>
+   - value type: <u32>
    - Specifies which messaging methods are supported by the partition, set bit
      means the feature is supported, clear bit - not supported:
 
-      - Bit[0]: partition can receive direct requests if set
-      - Bit[1]: partition can send direct requests if set
+      - Bit[0]: partition can receive direct requests via FFA_MSG_SEND_DIRECT_REQ ABI if set
+      - Bit[1]: partition can send direct requests via FFA_MSG_SEND_DIRECT_REQ ABI if set
       - Bit[2]: partition can send and receive indirect messages
+      - Bit[9]: partition can receive direct requests via FFA_MSG_SEND_DIRECT_REQ2 ABI if set
+      - Bit[10]: partition can send direct requests via FFA_MSG_SEND_DIRECT_REQ2 ABI if set
 
 - managed-exit
    - value type: <empty>
@@ -117,6 +119,11 @@
    - This field is deprecated in favor of ns-interrupts-action field in the FF-A
      v1.1 EAC0 spec.
 
+- managed-exit-virq
+   - value type: <empty>
+   - Indicates if the partition needs managed exit, if supported, to be signaled
+     through vFIQ signal.
+
 - ns-interrupts-action [mandatory]
    - value type: <u32>
    - Specifies the action that the SPMC must take in response to a Non-secure
@@ -136,6 +143,12 @@
       - 0x0: Other-Secure interrupt is queued
       - 0x1: Other-Secure interrupt is signaled
 
+- runtime-model
+   - value type: <u32>
+   - Indicates whether the SP execution can be preempted.
+   - This field is deprecated in favor of other-s-interrupts-action and
+     ns-interrupts-action fields in the FF-A v1.1 spec.
+
 - has-primary-scheduler
    - value type: <empty>
    - Presence of this field indicates that the partition implements the primary
@@ -157,11 +170,6 @@
      the FF-A boot information blob to be passed in the specified general purpose
      register.
 
-- stream-endpoint-ids
-   - value type: <prop-encoded-array>
-   - List of <u32> tuples, identifying the IDs this partition is acting as
-     proxy for.
-
 - power-management-messages
    - value type: <u32>
    - Specifies which power management messages a partition subscribes to.
@@ -172,6 +180,17 @@
       - Bit[1]: CPU_SUSPEND
       - Bit[2]: CPU_SUSPEND_RESUME
 
+- vm-availability-messages
+   - value type: <u32>
+   - Specifies which VM availability messages a partition subscribes to. A set
+     bit means the partition should be informed of the event, clear bit - should
+     not be informed of event:
+
+      - Bit[0]: VM created
+      - Bit[1]: VM destroyed
+
+.. _memory_region_node:
+
 Memory Regions
 --------------
 
@@ -209,6 +228,25 @@
      then communicate the region properties (including the base address chosen
      by the partition manager) to the partition.
 
+- stream-ids
+   - value type: <prop-encoded-array>
+   - List of IDs belonging to a DMA capable peripheral device that has access to
+     the memory region represented by current node.
+   - Each ID must have been declared in exactly one device region node.
+
+- smmu-id
+   - value type: <u32>
+   - Identifies the SMMU IP that enforces the access control for the DMA device
+     that owns the above stream-ids.
+
+- stream-ids-access-permissions
+   - value type: <prop-encoded-array>
+   - List of attributes representing the instruction and data access permissions
+     used by the DMA device streams to access the memory region represented by
+     current node.
+
+.. _device_region_node:
+
 Device Regions
 --------------
 
@@ -251,11 +289,10 @@
 
 - stream-ids
    - value type: <prop-encoded-array>
-   - A list of (id, mem-manage) pair, where:
+   - List of IDs where an ID is a unique <u32> value amongst all devices assigned
+     to the partition.
 
-      - id: A unique <u32> value amongst all devices assigned to the partition.
-
-- interrupts [mandatory]
+- interrupts
    - value type: <prop-encoded-array>
    - A list of (id, attributes) pair describing the device interrupts, where:
 
@@ -306,4 +343,4 @@
 
 --------------
 
-*Copyright (c) 2019-2022, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2019-2024, Arm Limited and Contributors. All rights reserved.*
diff --git a/docs/components/secure-partition-manager.rst b/docs/components/secure-partition-manager.rst
index b6f4219..220c3ce 100644
--- a/docs/components/secure-partition-manager.rst
+++ b/docs/components/secure-partition-manager.rst
@@ -10,42 +10,12 @@
 ========
 
 +--------+--------------------------------------+
-| CoT    | Chain of Trust                       |
-+--------+--------------------------------------+
-| DMA    | Direct Memory Access                 |
-+--------+--------------------------------------+
-| DTB    | Device Tree Blob                     |
-+--------+--------------------------------------+
 | DTS    | Device Tree Source                   |
 +--------+--------------------------------------+
-| EC     | Execution Context                    |
-+--------+--------------------------------------+
-| FIP    | Firmware Image Package               |
-+--------+--------------------------------------+
 | FF-A   | Firmware Framework for Arm A-profile |
 +--------+--------------------------------------+
-| IPA    | Intermediate Physical Address        |
-+--------+--------------------------------------+
-| JOP    | Jump-Oriented Programming            |
-+--------+--------------------------------------+
 | NWd    | Normal World                         |
 +--------+--------------------------------------+
-| ODM    | Original Design Manufacturer         |
-+--------+--------------------------------------+
-| OEM    | Original Equipment Manufacturer      |
-+--------+--------------------------------------+
-| PA     | Physical Address                     |
-+--------+--------------------------------------+
-| PE     | Processing Element                   |
-+--------+--------------------------------------+
-| PM     | Power Management                     |
-+--------+--------------------------------------+
-| PVM    | Primary VM                           |
-+--------+--------------------------------------+
-| ROP    | Return-Oriented Programming          |
-+--------+--------------------------------------+
-| SMMU   | System Memory Management Unit        |
-+--------+--------------------------------------+
 | SP     | Secure Partition                     |
 +--------+--------------------------------------+
 | SPD    | Secure Payload Dispatcher            |
@@ -56,16 +26,8 @@
 +--------+--------------------------------------+
 | SPMD   | SPM Dispatcher                       |
 +--------+--------------------------------------+
-| SiP    | Silicon Provider                     |
-+--------+--------------------------------------+
 | SWd    | Secure World                         |
 +--------+--------------------------------------+
-| TLV    | Tag-Length-Value                     |
-+--------+--------------------------------------+
-| TOS    | Trusted Operating System             |
-+--------+--------------------------------------+
-| VM     | Virtual Machine                      |
-+--------+--------------------------------------+
 
 Foreword
 ========
@@ -74,34 +36,14 @@
 codebase:
 
 #. S-EL2 SPMC based on the FF-A specification `[1]`_, enabling virtualization in
-   the secure world, managing multiple S-EL1 or S-EL0 partitions.
+   the secure world, managing multiple S-EL1 or S-EL0 partitions `[5]`_.
 #. EL3 SPMC based on the FF-A specification, managing a single S-EL1 partition
-   without virtualization in the secure world.
+   without virtualization in the secure world `[6]`_.
 #. EL3 SPM based on the MM specification, legacy implementation managing a
    single S-EL0 partition `[2]`_.
 
 These implementations differ in their respective SW architecture and only one
-can be selected at build time. This document:
-
-- describes the implementation from bullet 1. when the SPMC resides at S-EL2.
-- is not an architecture specification and it might provide assumptions
-  on sections mandated as implementation-defined in the specification.
-- covers the implications to TF-A used as a bootloader, and Hafnium used as a
-  reference code base for an S-EL2/SPMC secure firmware on platforms
-  implementing the FEAT_SEL2 architecture extension.
-
-Terminology
------------
-
-- The term Hypervisor refers to the NS-EL2 component managing Virtual Machines
-  (or partitions) in the normal world.
-- The term SPMC refers to the S-EL2 component managing secure partitions in
-  the secure world when the FEAT_SEL2 architecture extension is implemented.
-- Alternatively, SPMC can refer to an S-EL1 component, itself being a secure
-  partition and implementing the FF-A ABI on platforms not implementing the
-  FEAT_SEL2 architecture extension.
-- The term VM refers to a normal world Virtual Machine managed by an Hypervisor.
-- The term SP refers to a secure world "Virtual Machine" managed by an SPMC.
+can be selected at build time.
 
 Support for legacy platforms
 ----------------------------
@@ -123,16 +65,6 @@
 - S-EL2 SPMC for platforms implementing the FEAT_SEL2 architecture
   extension. The SPMD relays the FF-A protocol from EL3 to S-EL2.
 
-Sample reference stack
-======================
-
-The following diagram illustrates a possible configuration when the
-FEAT_SEL2 architecture extension is implemented, showing the SPMD
-and SPMC, one or multiple secure partitions, with an optional
-Hypervisor:
-
-.. image:: ../resources/diagrams/ff-a-spm-sel2.png
-
 TF-A build options
 ==================
 
@@ -147,16 +79,15 @@
   level to being at S-EL2. It defaults to enabled (value 1) when
   SPD=spmd is chosen.
 - **SPMC_AT_EL3**: this option adjusts the SPMC exception level to being
-  at EL3.
-- If neither ``SPMD_SPM_AT_SEL2`` or ``SPMC_AT_EL3`` are enabled the SPMC
-  exception level is set to S-EL1.
+  at EL3. If neither ``SPMD_SPM_AT_SEL2`` or ``SPMC_AT_EL3`` are enabled the
+  SPMC exception level is set to S-EL1.
   ``SPMD_SPM_AT_SEL2`` is enabled. The context save/restore routine
   and exhaustive list of registers is visible at `[4]`_.
 - **SPMC_AT_EL3_SEL0_SP**: this option enables the support to load SEL0 SP
   when SPMC at EL3 support is enabled.
 - **SP_LAYOUT_FILE**: this option specifies a text description file
   providing paths to SP binary images and manifests in DTS format
-  (see `Describing secure partitions`_). It
+  (see `[3]`_). It
   is required when ``SPMD_SPM_AT_SEL2`` is enabled hence when multiple
   secure partitions are to be loaded by BL2 on behalf of the SPMC.
 
@@ -275,1358 +206,28 @@
     PLAT=fvp \
     all fip
 
-FVP model invocation
-====================
-
-The FVP command line needs the following options to exercise the S-EL2 SPMC:
-
-+---------------------------------------------------+------------------------------------+
-| - cluster0.has_arm_v8-5=1                         | Implements FEAT_SEL2, FEAT_PAuth,  |
-| - cluster1.has_arm_v8-5=1                         | and FEAT_BTI.                      |
-+---------------------------------------------------+------------------------------------+
-| - pci.pci_smmuv3.mmu.SMMU_AIDR=2                  | Parameters required for the        |
-| - pci.pci_smmuv3.mmu.SMMU_IDR0=0x0046123B         | SMMUv3.2 modeling.                 |
-| - pci.pci_smmuv3.mmu.SMMU_IDR1=0x00600002         |                                    |
-| - pci.pci_smmuv3.mmu.SMMU_IDR3=0x1714             |                                    |
-| - pci.pci_smmuv3.mmu.SMMU_IDR5=0xFFFF0472         |                                    |
-| - pci.pci_smmuv3.mmu.SMMU_S_IDR1=0xA0000002       |                                    |
-| - pci.pci_smmuv3.mmu.SMMU_S_IDR2=0                |                                    |
-| - pci.pci_smmuv3.mmu.SMMU_S_IDR3=0                |                                    |
-+---------------------------------------------------+------------------------------------+
-| - cluster0.has_branch_target_exception=1          | Implements FEAT_BTI.               |
-| - cluster1.has_branch_target_exception=1          |                                    |
-+---------------------------------------------------+------------------------------------+
-| - cluster0.has_pointer_authentication=2           | Implements FEAT_PAuth              |
-| - cluster1.has_pointer_authentication=2           |                                    |
-+---------------------------------------------------+------------------------------------+
-| - cluster0.memory_tagging_support_level=2         | Implements FEAT_MTE2               |
-| - cluster1.memory_tagging_support_level=2         |                                    |
-| - bp.dram_metadata.is_enabled=1                   |                                    |
-+---------------------------------------------------+------------------------------------+
-
-Sample FVP command line invocation:
-
-.. code:: shell
-
-    <path-to-fvp-model>/FVP_Base_RevC-2xAEMvA -C pctl.startup=0.0.0.0 \
-    -C cluster0.NUM_CORES=4 -C cluster1.NUM_CORES=4 -C bp.secure_memory=1 \
-    -C bp.secureflashloader.fname=trusted-firmware-a/build/fvp/debug/bl1.bin \
-    -C bp.flashloader0.fname=trusted-firmware-a/build/fvp/debug/fip.bin \
-    -C bp.pl011_uart0.out_file=fvp-uart0.log -C bp.pl011_uart1.out_file=fvp-uart1.log \
-    -C bp.pl011_uart2.out_file=fvp-uart2.log \
-    -C cluster0.has_arm_v8-5=1 -C cluster1.has_arm_v8-5=1 \
-    -C cluster0.has_pointer_authentication=2 -C cluster1.has_pointer_authentication=2 \
-    -C cluster0.has_branch_target_exception=1 -C cluster1.has_branch_target_exception=1 \
-    -C cluster0.memory_tagging_support_level=2 -C cluster1.memory_tagging_support_level=2 \
-    -C bp.dram_metadata.is_enabled=1 \
-    -C pci.pci_smmuv3.mmu.SMMU_AIDR=2 -C pci.pci_smmuv3.mmu.SMMU_IDR0=0x0046123B \
-    -C pci.pci_smmuv3.mmu.SMMU_IDR1=0x00600002 -C pci.pci_smmuv3.mmu.SMMU_IDR3=0x1714 \
-    -C pci.pci_smmuv3.mmu.SMMU_IDR5=0xFFFF0472 -C pci.pci_smmuv3.mmu.SMMU_S_IDR1=0xA0000002 \
-    -C pci.pci_smmuv3.mmu.SMMU_S_IDR2=0 -C pci.pci_smmuv3.mmu.SMMU_S_IDR3=0
-
 Boot process
 ============
 
-Loading Hafnium and secure partitions in the secure world
----------------------------------------------------------
-
-TF-A BL2 is the bootlader for the SPMC and SPs in the secure world.
-
-SPs may be signed by different parties (SiP, OEM/ODM, TOS vendor, etc.).
-Thus they are supplied as distinct signed entities within the FIP flash
-image. The FIP image itself is not signed hence this provides the ability
-to upgrade SPs in the field.
-
-Booting through TF-A
---------------------
-
-SP manifests
-~~~~~~~~~~~~
-
-An SP manifest describes SP attributes as defined in `[1]`_
-(partition manifest at virtual FF-A instance) in DTS format. It is
-represented as a single file associated with the SP. A sample is
-provided by `[5]`_. A binding document is provided by `[6]`_.
-
-Secure Partition packages
-~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Secure partitions are bundled as independent package files consisting
-of:
-
-- a header
-- a DTB
-- an image payload
-
-The header starts with a magic value and offset values to SP DTB and
-image payload. Each SP package is loaded independently by BL2 loader
-and verified for authenticity and integrity.
-
-The SP package identified by its UUID (matching FF-A uuid property) is
-inserted as a single entry into the FIP at end of the TF-A build flow
-as shown:
-
-.. code:: shell
-
-    Trusted Boot Firmware BL2: offset=0x1F0, size=0x8AE1, cmdline="--tb-fw"
-    EL3 Runtime Firmware BL31: offset=0x8CD1, size=0x13000, cmdline="--soc-fw"
-    Secure Payload BL32 (Trusted OS): offset=0x1BCD1, size=0x15270, cmdline="--tos-fw"
-    Non-Trusted Firmware BL33: offset=0x30F41, size=0x92E0, cmdline="--nt-fw"
-    HW_CONFIG: offset=0x3A221, size=0x2348, cmdline="--hw-config"
-    TB_FW_CONFIG: offset=0x3C569, size=0x37A, cmdline="--tb-fw-config"
-    SOC_FW_CONFIG: offset=0x3C8E3, size=0x48, cmdline="--soc-fw-config"
-    TOS_FW_CONFIG: offset=0x3C92B, size=0x427, cmdline="--tos-fw-config"
-    NT_FW_CONFIG: offset=0x3CD52, size=0x48, cmdline="--nt-fw-config"
-    B4B5671E-4A90-4FE1-B81F-FB13DAE1DACB: offset=0x3CD9A, size=0xC168, cmdline="--blob"
-    D1582309-F023-47B9-827C-4464F5578FC8: offset=0x48F02, size=0xC168, cmdline="--blob"
-
-.. uml:: ../resources/diagrams/plantuml/fip-secure-partitions.puml
-
-Describing secure partitions
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-A json-formatted description file is passed to the build flow specifying paths
-to the SP binary image and associated DTS partition manifest file. The latter
-is processed by the dtc compiler to generate a DTB fed into the SP package.
-Optionally, the partition's json description can contain offsets for both
-the image and partition manifest within the SP package. Both offsets need to be
-4KB aligned, because it is the translation granule supported by Hafnium SPMC.
-These fields can be leveraged to support SPs with S1 translation granules that
-differ from 4KB, and to configure the regions allocated within the SP package,
-as well as to comply with the requirements for the implementation of the boot
-information protocol (see `Passing boot data to the SP`_ for more details). In
-case the offsets are absent in their json node, they default to 0x1000 and
-0x4000 for the manifest offset and image offset respectively.
-This file also specifies the SP owner (as an optional field) identifying the
-signing domain in case of dual root CoT.
-The SP owner can either be the silicon or the platform provider. The
-corresponding "owner" field value can either take the value of "SiP" or "Plat".
-In absence of "owner" field, it defaults to "SiP" owner.
-The UUID of the partition can be specified as a field in the description file or
-if it does not exist there the UUID is extracted from the DTS partition
-manifest.
-
-.. code:: shell
-
-    {
-        "tee1" : {
-            "image": "tee1.bin",
-             "pm": "tee1.dts",
-             "owner": "SiP",
-             "uuid": "1b1820fe-48f7-4175-8999-d51da00b7c9f"
-        },
-
-        "tee2" : {
-            "image": "tee2.bin",
-            "pm": "tee2.dts",
-            "owner": "Plat"
-        },
-
-        "tee3" : {
-            "image": {
-                "file": "tee3.bin",
-                "offset":"0x2000"
-             },
-            "pm": {
-                "file": "tee3.dts",
-                "offset":"0x6000"
-             },
-            "owner": "Plat"
-        },
-    }
-
-SPMC manifest
-~~~~~~~~~~~~~
-
-This manifest contains the SPMC *attribute* node consumed by the SPMD at boot
-time. It implements `[1]`_ (SP manifest at physical FF-A instance) and serves
-two different cases:
-
-- The SPMC resides at S-EL1: the SPMC manifest is used by the SPMD to setup a
-  SP that co-resides with the SPMC and executes at S-EL1 or Secure Supervisor
-  mode.
-- The SPMC resides at S-EL2: the SPMC manifest is used by the SPMD to setup
-  the environment required by the SPMC to run at S-EL2. SPs run at S-EL1 or
-  S-EL0.
-
-.. code:: shell
-
-    attribute {
-        spmc_id = <0x8000>;
-        maj_ver = <0x1>;
-        min_ver = <0x1>;
-        exec_state = <0x0>;
-        load_address = <0x0 0x6000000>;
-        entrypoint = <0x0 0x6000000>;
-        binary_size = <0x60000>;
-    };
-
-- *spmc_id* defines the endpoint ID value that SPMC can query through
-  ``FFA_ID_GET``.
-- *maj_ver/min_ver*. SPMD checks provided version versus its internal
-  version and aborts if not matching.
-- *exec_state* defines the SPMC execution state (AArch64 or AArch32).
-  Notice Hafnium used as a SPMC only supports AArch64.
-- *load_address* and *binary_size* are mostly used to verify secondary
-  entry points fit into the loaded binary image.
-- *entrypoint* defines the cold boot primary core entry point used by
-  SPMD (currently matches ``BL32_BASE``) to enter the SPMC.
-
-Other nodes in the manifest are consumed by Hafnium in the secure world.
-A sample can be found at `[7]`_:
-
-- The *hypervisor* node describes SPs. *is_ffa_partition* boolean attribute
-  indicates a FF-A compliant SP. The *load_address* field specifies the load
-  address at which BL2 loaded the SP package.
-- *cpus* node provide the platform topology and allows MPIDR to VMPIDR mapping.
-  Note the primary core is declared first, then secondary cores are declared
-  in reverse order.
-- The *memory* nodes provide platform information on the ranges of memory
-  available for use by SPs at runtime. These ranges relate to either
-  secure or non-secure memory, depending on the *device_type* field.
-  If the field specifies "memory" the range is secure, else if it specifies
-  "ns-memory" the memory is non-secure. The system integrator must exclude
-  the memory used by other components that are not SPs, such as the monitor,
-  or the SPMC itself, the OS Kernel/Hypervisor, or other NWd VMs. The SPMC
-  limits the SP's address space such that they do not access memory outside
-  of those ranges.
+The boot process involving SPMC is highly dependent on the SPMC implementation.
+It is recommended to refer to corresponding SPMC documentation for further
+details. Some aspects of boot process are described here in the greater interest
+of the project.
 
 SPMC boot
-~~~~~~~~~
+---------
 
-The SPMC is loaded by BL2 as the BL32 image.
+When SPMC resides at a lower EL i.e., S-EL1 or S-EL2, it is loaded by BL2 as the
+BL32 image. The SPMC manifest is loaded by BL2 as the ``TOS_FW_CONFIG`` image `[7]`_.
 
-The SPMC manifest is loaded by BL2 as the ``TOS_FW_CONFIG`` image `[9]`_.
-
-BL2 passes the SPMC manifest address to BL31 through a register.
-
-At boot time, the SPMD in BL31 runs from the primary core, initializes the core
-contexts and launches the SPMC (BL32) passing the following information through
-registers:
+BL2 passes the SPMC manifest address to BL31 through a register. At boot time,
+the SPMD in BL31 runs from the primary core, initializes the core contexts and
+launches the SPMC (BL32) passing the following information through registers:
 
 - X0 holds the ``TOS_FW_CONFIG`` physical address (or SPMC manifest blob).
 - X1 holds the ``HW_CONFIG`` physical address.
 - X4 holds the currently running core linear id.
 
-Loading of SPs
-~~~~~~~~~~~~~~
-
-At boot time, BL2 loads SPs sequentially in addition to the SPMC as depicted
-below:
-
-.. uml:: ../resources/diagrams/plantuml/bl2-loading-sp.puml
-
-Note this boot flow is an implementation sample on Arm's FVP platform.
-Platforms not using TF-A's *Firmware CONFiguration* framework would adjust to a
-different boot flow. The flow restricts to a maximum of 8 secure partitions.
-
-Secure boot
-~~~~~~~~~~~
-
-The SP content certificate is inserted as a separate FIP item so that BL2 loads SPMC,
-SPMC manifest, secure partitions and verifies them for authenticity and integrity.
-Refer to TBBR specification `[3]`_.
-
-The multiple-signing domain feature (in current state dual signing domain `[8]`_) allows
-the use of two root keys namely S-ROTPK and NS-ROTPK:
-
-- SPMC (BL32) and SPMC manifest are signed by the SiP using the S-ROTPK.
-- BL33 may be signed by the OEM using NS-ROTPK.
-- An SP may be signed either by SiP (using S-ROTPK) or by OEM (using NS-ROTPK).
-- A maximum of 4 partitions can be signed with the S-ROTPK key and 4 partitions
-  signed with the NS-ROTPK key.
-
-Also refer to `Describing secure partitions`_ and `TF-A build options`_ sections.
-
-Hafnium in the secure world
-===========================
-
-General considerations
-----------------------
-
-Build platform for the secure world
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-In the Hafnium reference implementation specific code parts are only relevant to
-the secure world. Such portions are isolated in architecture specific files
-and/or enclosed by a ``SECURE_WORLD`` macro.
-
-Secure partitions scheduling
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The FF-A specification `[1]`_ provides two ways to relinquinsh CPU time to
-secure partitions. For this a VM (Hypervisor or OS kernel), or SP invokes one of:
-
-- the FFA_MSG_SEND_DIRECT_REQ interface.
-- the FFA_RUN interface.
-
-Additionally a secure interrupt can pre-empt the normal world execution and give
-CPU cycles by transitioning to EL3 and S-EL2.
-
-Platform topology
-~~~~~~~~~~~~~~~~~
-
-The *execution-ctx-count* SP manifest field can take the value of one or the
-total number of PEs. The FF-A specification `[1]`_  recommends the
-following SP types:
-
-- Pinned MP SPs: an execution context matches a physical PE. MP SPs must
-  implement the same number of ECs as the number of PEs in the platform.
-- Migratable UP SPs: a single execution context can run and be migrated on any
-  physical PE. Such SP declares a single EC in its SP manifest. An UP SP can
-  receive a direct message request originating from any physical core targeting
-  the single execution context.
-
-Parsing SP partition manifests
-------------------------------
-
-Hafnium consumes SP manifests as defined in `[1]`_ and `SP manifests`_.
-Note the current implementation may not implement all optional fields.
-
-The SP manifest may contain memory and device regions nodes. In case of
-an S-EL2 SPMC:
-
-- Memory regions are mapped in the SP EL1&0 Stage-2 translation regime at
-  load time (or EL1&0 Stage-1 for an S-EL1 SPMC). A memory region node can
-  specify RX/TX buffer regions in which case it is not necessary for an SP
-  to explicitly invoke the ``FFA_RXTX_MAP`` interface. The memory referred
-  shall be contained within the memory ranges defined in SPMC manifest. The
-  NS bit in the attributes field should be consistent with the security
-  state of the range that it relates to. I.e. non-secure memory shall be
-  part of a non-secure memory range, and secure memory shall be contained
-  in a secure memory range of a given platform.
-- Device regions are mapped in the SP EL1&0 Stage-2 translation regime (or
-  EL1&0 Stage-1 for an S-EL1 SPMC) as peripherals and possibly allocate
-  additional resources (e.g. interrupts).
-
-For the S-EL2 SPMC, base addresses for memory and device region nodes are IPAs
-provided the SPMC identity maps IPAs to PAs within SP EL1&0 Stage-2 translation
-regime.
-
-Note: in the current implementation both VTTBR_EL2 and VSTTBR_EL2 point to the
-same set of page tables. It is still open whether two sets of page tables shall
-be provided per SP. The memory region node as defined in the specification
-provides a memory security attribute hinting to map either to the secure or
-non-secure EL1&0 Stage-2 table if it exists.
-
-Passing boot data to the SP
----------------------------
-
-In `[1]`_ , the section  "Boot information protocol" defines a method for passing
-data to the SPs at boot time. It specifies the format for the boot information
-descriptor and boot information header structures, which describe the data to be
-exchanged between SPMC and SP.
-The specification also defines the types of data that can be passed.
-The aggregate of both the boot info structures and the data itself is designated
-the boot information blob, and is passed to a Partition as a contiguous memory
-region.
-
-Currently, the SPM implementation supports the FDT type which is used to pass the
-partition's DTB manifest.
-
-The region for the boot information blob is allocated through the SP package.
-
-.. image:: ../resources/diagrams/partition-package.png
-
-To adjust the space allocated for the boot information blob, the json description
-of the SP (see section `Describing secure partitions`_) shall be updated to contain
-the manifest offset. If no offset is provided the manifest offset defaults to 0x1000,
-which is the page size in the Hafnium SPMC.
-
-The configuration of the boot protocol is done in the SPs manifest. As defined by
-the specification, the manifest field 'gp-register-num' configures the GP register
-which shall be used to pass the address to the partitions boot information blob when
-booting the partition.
-In addition, the Hafnium SPMC implementation requires the boot information arguments
-to be listed in a designated DT node:
-
-.. code:: shell
-
-  boot-info {
-      compatible = "arm,ffa-manifest-boot-info";
-      ffa_manifest;
-  };
-
-The whole secure partition package image (see `Secure Partition packages`_) is
-mapped to the SP secure EL1&0 Stage-2 translation regime. As such, the SP can
-retrieve the address for the boot information blob in the designated GP register,
-process the boot information header and descriptors, access its own manifest
-DTB blob and extract its partition manifest properties.
-
-SP Boot order
--------------
-
-SP manifests provide an optional boot order attribute meant to resolve
-dependencies such as an SP providing a service required to properly boot
-another SP. SPMC boots the SPs in accordance to the boot order attribute,
-lowest to the highest value. If the boot order attribute is absent from the FF-A
-manifest, the SP is treated as if it had the highest boot order value
-(i.e. lowest booting priority).
-
-It is possible for an SP to call into another SP through a direct request
-provided the latter SP has already been booted.
-
-Boot phases
------------
-
-Primary core boot-up
-~~~~~~~~~~~~~~~~~~~~
-
-Upon boot-up, BL31 hands over to the SPMC (BL32) on the primary boot physical
-core. The SPMC performs its platform initializations and registers the SPMC
-secondary physical core entry point physical address by the use of the
-`FFA_SECONDARY_EP_REGISTER`_ interface (SMC invocation from the SPMC to the SPMD
-at secure physical FF-A instance).
-
-The SPMC then creates secure partitions based on SP packages and manifests. Each
-secure partition is launched in sequence (`SP Boot order`_) on their "primary"
-execution context. If the primary boot physical core linear id is N, an MP SP is
-started using EC[N] on PE[N] (see `Platform topology`_). If the partition is a
-UP SP, it is started using its unique EC0 on PE[N].
-
-The SP primary EC (or the EC used when the partition is booted as described
-above):
-
-- Performs the overall SP boot time initialization, and in case of a MP SP,
-  prepares the SP environment for other execution contexts.
-- In the case of a MP SP, it invokes the FFA_SECONDARY_EP_REGISTER at secure
-  virtual FF-A instance (SMC invocation from SP to SPMC) to provide the IPA
-  entry point for other execution contexts.
-- Exits through ``FFA_MSG_WAIT`` to indicate successful initialization or
-  ``FFA_ERROR`` in case of failure.
-
-Secondary cores boot-up
-~~~~~~~~~~~~~~~~~~~~~~~
-
-Once the system is started and NWd brought up, a secondary physical core is
-woken up by the ``PSCI_CPU_ON`` service invocation. The TF-A SPD hook mechanism
-calls into the SPMD on the newly woken up physical core. Then the SPMC is
-entered at the secondary physical core entry point.
-
-In the current implementation, the first SP is resumed on the coresponding EC
-(the virtual CPU which matches the physical core). The implication is that the
-first SP must be a MP SP.
-
-In a linux based system, once secure and normal worlds are booted but prior to
-a NWd FF-A driver has been loaded:
-
-- The first SP has initialized all its ECs in response to primary core boot up
-  (at system initialization) and secondary core boot up (as a result of linux
-  invoking PSCI_CPU_ON for all secondary cores).
-- Other SPs have their first execution context initialized as a result of secure
-  world initialization on the primary boot core. Other ECs for those SPs have to
-  be run first through ffa_run to complete their initialization (which results
-  in the EC completing with FFA_MSG_WAIT).
-
-Refer to `Power management`_ for further details.
-
-Notifications
--------------
-
-The FF-A v1.1 specification `[1]`_ defines notifications as an asynchronous
-communication mechanism with non-blocking semantics. It allows for one FF-A
-endpoint to signal another for service provision, without hindering its current
-progress.
-
-Hafnium currently supports 64 notifications. The IDs of each notification define
-a position in a 64-bit bitmap.
-
-The signaling of notifications can interchangeably happen between NWd and SWd
-FF-A endpoints.
-
-The SPMC is in charge of managing notifications from SPs to SPs, from SPs to
-VMs, and from VMs to SPs. An hypervisor component would only manage
-notifications from VMs to VMs. Given the SPMC has no visibility of the endpoints
-deployed in NWd, the Hypervisor or OS kernel must invoke the interface
-FFA_NOTIFICATION_BITMAP_CREATE to allocate the notifications bitmap per FF-A
-endpoint in the NWd that supports it.
-
-A sender can signal notifications once the receiver has provided it with
-permissions. Permissions are provided by invoking the interface
-FFA_NOTIFICATION_BIND.
-
-Notifications are signaled by invoking FFA_NOTIFICATION_SET. Henceforth
-they are considered to be in a pending sate. The receiver can retrieve its
-pending notifications invoking FFA_NOTIFICATION_GET, which, from that moment,
-are considered to be handled.
-
-Per the FF-A v1.1 spec, each FF-A endpoint must be associated with a scheduler
-that is in charge of donating CPU cycles for notifications handling. The
-FF-A driver calls FFA_NOTIFICATION_INFO_GET to retrieve the information about
-which FF-A endpoints have pending notifications. The receiver scheduler is
-called and informed by the FF-A driver, and it should allocate CPU cycles to the
-receiver.
-
-There are two types of notifications supported:
-
-- Global, which are targeted to a FF-A endpoint and can be handled within any of
-  its execution contexts, as determined by the scheduler of the system.
-- Per-vCPU, which are targeted to a FF-A endpoint and to be handled within a
-  a specific execution context, as determined by the sender.
-
-The type of a notification is set when invoking FFA_NOTIFICATION_BIND to give
-permissions to the sender.
-
-Notification signaling resorts to two interrupts:
-
-- Schedule Receiver Interrupt: non-secure physical interrupt to be handled by
-  the FF-A driver within the receiver scheduler. At initialization the SPMC
-  donates a SGI ID chosen from the secure SGI IDs range and configures it as
-  non-secure. The SPMC triggers this SGI on the currently running core when
-  there are pending notifications, and the respective receivers need CPU cycles
-  to handle them.
-- Notifications Pending Interrupt: virtual interrupt to be handled by the
-  receiver of the notification. Set when there are pending notifications for the
-  given secure partition. The NPI is pended when the NWd relinquishes CPU cycles
-  to an SP.
-
-The notifications receipt support is enabled in the partition FF-A manifest.
-
-Mandatory interfaces
---------------------
-
-The following interfaces are exposed to SPs:
-
--  ``FFA_VERSION``
--  ``FFA_FEATURES``
--  ``FFA_RX_RELEASE``
--  ``FFA_RXTX_MAP``
--  ``FFA_RXTX_UNMAP``
--  ``FFA_PARTITION_INFO_GET``
--  ``FFA_ID_GET``
--  ``FFA_MSG_WAIT``
--  ``FFA_MSG_SEND_DIRECT_REQ``
--  ``FFA_MSG_SEND_DIRECT_RESP``
--  ``FFA_MEM_DONATE``
--  ``FFA_MEM_LEND``
--  ``FFA_MEM_SHARE``
--  ``FFA_MEM_RETRIEVE_REQ``
--  ``FFA_MEM_RETRIEVE_RESP``
--  ``FFA_MEM_RELINQUISH``
--  ``FFA_MEM_FRAG_RX``
--  ``FFA_MEM_FRAG_TX``
--  ``FFA_MEM_RECLAIM``
--  ``FFA_RUN``
-
-As part of the FF-A v1.1 support, the following interfaces were added:
-
- - ``FFA_NOTIFICATION_BITMAP_CREATE``
- - ``FFA_NOTIFICATION_BITMAP_DESTROY``
- - ``FFA_NOTIFICATION_BIND``
- - ``FFA_NOTIFICATION_UNBIND``
- - ``FFA_NOTIFICATION_SET``
- - ``FFA_NOTIFICATION_GET``
- - ``FFA_NOTIFICATION_INFO_GET``
- - ``FFA_SPM_ID_GET``
- - ``FFA_SECONDARY_EP_REGISTER``
- - ``FFA_MEM_PERM_GET``
- - ``FFA_MEM_PERM_SET``
- - ``FFA_MSG_SEND2``
- - ``FFA_RX_ACQUIRE``
-
-FFA_VERSION
-~~~~~~~~~~~
-
-``FFA_VERSION`` requires a *requested_version* parameter from the caller.
-The returned value depends on the caller:
-
-- Hypervisor or OS kernel in NS-EL1/EL2: the SPMD returns the SPMC version
-  specified in the SPMC manifest.
-- SP: the SPMC returns its own implemented version.
-- SPMC at S-EL1/S-EL2: the SPMD returns its own implemented version.
-
-FFA_FEATURES
-~~~~~~~~~~~~
-
-FF-A features supported by the SPMC may be discovered by secure partitions at
-boot (that is prior to NWd is booted) or run-time.
-
-The SPMC calling FFA_FEATURES at secure physical FF-A instance always get
-FFA_SUCCESS from the SPMD.
-
-The request made by an Hypervisor or OS kernel is forwarded to the SPMC and
-the response relayed back to the NWd.
-
-FFA_RXTX_MAP/FFA_RXTX_UNMAP
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-When invoked from a secure partition FFA_RXTX_MAP maps the provided send and
-receive buffers described by their IPAs to the SP EL1&0 Stage-2 translation
-regime as secure buffers in the MMU descriptors.
-
-When invoked from the Hypervisor or OS kernel, the buffers are mapped into the
-SPMC EL2 Stage-1 translation regime and marked as NS buffers in the MMU
-descriptors. The provided addresses may be owned by a VM in the normal world,
-which is expected to receive messages from the secure world. The SPMC will in
-this case allocate internal state structures to facilitate RX buffer access
-synchronization (through FFA_RX_ACQUIRE interface), and to permit SPs to send
-messages.
-
-The FFA_RXTX_UNMAP unmaps the RX/TX pair from the translation regime of the
-caller, either it being the Hypervisor or OS kernel, as well as a secure
-partition.
-
-FFA_PARTITION_INFO_GET
-~~~~~~~~~~~~~~~~~~~~~~
-
-Partition info get call can originate:
-
-- from SP to SPMC
-- from Hypervisor or OS kernel to SPMC. The request is relayed by the SPMD.
-
-FFA_ID_GET
-~~~~~~~~~~
-
-The FF-A id space is split into a non-secure space and secure space:
-
-- FF-A ID with bit 15 clear relates to VMs.
-- FF-A ID with bit 15 set related to SPs.
-- FF-A IDs 0, 0xffff, 0x8000 are assigned respectively to the Hypervisor, SPMD
-  and SPMC.
-
-The SPMD returns:
-
-- The default zero value on invocation from the Hypervisor.
-- The ``spmc_id`` value specified in the SPMC manifest on invocation from
-  the SPMC (see `SPMC manifest`_)
-
-This convention helps the SPMC to determine the origin and destination worlds in
-an FF-A ABI invocation. In particular the SPMC shall filter unauthorized
-transactions in its world switch routine. It must not be permitted for a VM to
-use a secure FF-A ID as origin world by spoofing:
-
-- A VM-to-SP direct request/response shall set the origin world to be non-secure
-  (FF-A ID bit 15 clear) and destination world to be secure (FF-A ID bit 15
-  set).
-- Similarly, an SP-to-SP direct request/response shall set the FF-A ID bit 15
-  for both origin and destination IDs.
-
-An incoming direct message request arriving at SPMD from NWd is forwarded to
-SPMC without a specific check. The SPMC is resumed through eret and "knows" the
-message is coming from normal world in this specific code path. Thus the origin
-endpoint ID must be checked by SPMC for being a normal world ID.
-
-An SP sending a direct message request must have bit 15 set in its origin
-endpoint ID and this can be checked by the SPMC when the SP invokes the ABI.
-
-The SPMC shall reject the direct message if the claimed world in origin endpoint
-ID is not consistent:
-
--  It is either forwarded by SPMD and thus origin endpoint ID must be a "normal
-   world ID",
--  or initiated by an SP and thus origin endpoint ID must be a "secure world ID".
-
-
-FFA_MSG_SEND_DIRECT_REQ/FFA_MSG_SEND_DIRECT_RESP
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-This is a mandatory interface for secure partitions consisting in direct request
-and responses with the following rules:
-
-- An SP can send a direct request to another SP.
-- An SP can receive a direct request from another SP.
-- An SP can send a direct response to another SP.
-- An SP cannot send a direct request to an Hypervisor or OS kernel.
-- An Hypervisor or OS kernel can send a direct request to an SP.
-- An SP can send a direct response to an Hypervisor or OS kernel.
-
-FFA_NOTIFICATION_BITMAP_CREATE/FFA_NOTIFICATION_BITMAP_DESTROY
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The secure partitions notifications bitmap are statically allocated by the SPMC.
-Hence, this interface is not to be issued by secure partitions.
-
-At initialization, the SPMC is not aware of VMs/partitions deployed in the
-normal world. Hence, the Hypervisor or OS kernel must use both ABIs for SPMC
-to be prepared to handle notifications for the provided VM ID.
-
-FFA_NOTIFICATION_BIND/FFA_NOTIFICATION_UNBIND
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Pair of interfaces to manage permissions to signal notifications. Prior to
-handling notifications, an FF-A endpoint must allow a given sender to signal a
-bitmap of notifications.
-
-If the receiver doesn't have notification support enabled in its FF-A manifest,
-it won't be able to bind notifications, hence forbidding it to receive any
-notifications.
-
-FFA_NOTIFICATION_SET/FFA_NOTIFICATION_GET
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-FFA_NOTIFICATION_GET retrieves all pending global notifications and
-per-vCPU notifications targeted to the current vCPU.
-
-Hafnium maintains a global count of pending notifications which gets incremented
-and decremented when handling FFA_NOTIFICATION_SET and FFA_NOTIFICATION_GET
-respectively. A delayed SRI is triggered if the counter is non-zero when the
-SPMC returns to normal world.
-
-FFA_NOTIFICATION_INFO_GET
-~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Hafnium maintains a global count of pending notifications whose information
-has been retrieved by this interface. The count is incremented and decremented
-when handling FFA_NOTIFICATION_INFO_GET and FFA_NOTIFICATION_GET respectively.
-It also tracks notifications whose information has been retrieved individually,
-such that it avoids duplicating returned information for subsequent calls to
-FFA_NOTIFICATION_INFO_GET. For each notification, this state information is
-reset when receiver called FFA_NOTIFICATION_GET to retrieve them.
-
-FFA_SPM_ID_GET
-~~~~~~~~~~~~~~
-
-Returns the FF-A ID allocated to an SPM component which can be one of SPMD
-or SPMC.
-
-At initialization, the SPMC queries the SPMD for the SPMC ID, using the
-FFA_ID_GET interface, and records it. The SPMC can also query the SPMD ID using
-the FFA_SPM_ID_GET interface at the secure physical FF-A instance.
-
-Secure partitions call this interface at the virtual FF-A instance, to which
-the SPMC returns the priorly retrieved SPMC ID.
-
-The Hypervisor or OS kernel can issue the FFA_SPM_ID_GET call handled by the
-SPMD, which returns the SPMC ID.
-
-FFA_SECONDARY_EP_REGISTER
-~~~~~~~~~~~~~~~~~~~~~~~~~
-
-When the SPMC boots, all secure partitions are initialized on their primary
-Execution Context.
-
-The FFA_SECONDARY_EP_REGISTER interface is to be used by a secure partition
-from its first execution context, to provide the entry point address for
-secondary execution contexts.
-
-A secondary EC is first resumed either upon invocation of PSCI_CPU_ON from
-the NWd or by invocation of FFA_RUN.
-
-FFA_RX_ACQUIRE/FFA_RX_RELEASE
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The RX buffers can be used to pass information to an FF-A endpoint in the
-following scenarios:
-
- - When it was targetted by a FFA_MSG_SEND2 invokation from another endpoint.
- - Return the result of calling ``FFA_PARTITION_INFO_GET``.
- - In a memory share operation, as part of the ``FFA_MEM_RETRIEVE_RESP``,
-   with the memory descriptor of the shared memory.
-
-If a normal world VM is expected to exchange messages with secure world,
-its RX/TX buffer addresses are forwarded to the SPMC via FFA_RXTX_MAP ABI,
-and are from this moment owned by the SPMC.
-The hypervisor must call the FFA_RX_ACQUIRE interface before attempting
-to use the RX buffer, in any of the aforementioned scenarios. A successful
-call to FFA_RX_ACQUIRE transfers ownership of RX buffer to hypervisor, such
-that it can be safely used.
-
-The FFA_RX_RELEASE interface is used after the FF-A endpoint is done with
-processing the data received in its RX buffer. If the RX buffer has been
-acquired by the hypervisor, the FFA_RX_RELEASE call must be forwarded to
-the SPMC to reestablish SPMC's RX ownership.
-
-An attempt from an SP to send a message to a normal world VM whose RX buffer
-was acquired by the hypervisor fails with error code FFA_BUSY, to preserve
-the RX buffer integrity.
-The operation could then be conducted after FFA_RX_RELEASE.
-
-FFA_MSG_SEND2
-~~~~~~~~~~~~~
-
-Hafnium copies a message from the sender TX buffer into receiver's RX buffer.
-For messages from SPs to VMs, operation is only possible if the SPMC owns
-the receiver's RX buffer.
-
-Both receiver and sender need to enable support for indirect messaging,
-in their respective partition manifest. The discovery of support
-of such feature can be done via FFA_PARTITION_INFO_GET.
-
-On a successful message send, Hafnium pends an RX buffer full framework
-notification for the receiver, to inform it about a message in the RX buffer.
-
-The handling of framework notifications is similar to that of
-global notifications. Binding of these is not necessary, as these are
-reserved to be used by the hypervisor or SPMC.
-
-SPMC-SPMD direct requests/responses
------------------------------------
-
-Implementation-defined FF-A IDs are allocated to the SPMC and SPMD.
-Using those IDs in source/destination fields of a direct request/response
-permits SPMD to SPMC communication and either way.
-
-- SPMC to SPMD direct request/response uses SMC conduit.
-- SPMD to SPMC direct request/response uses ERET conduit.
-
-This is used in particular to convey power management messages.
-
-Memory Sharing
---------------
-
-Hafnium implements the following memory sharing interfaces:
-
- - ``FFA_MEM_SHARE`` - for shared access between lender and borrower.
- - ``FFA_MEM_LEND`` - borrower to obtain exclusive access, though lender
-   retains ownership of the memory.
- - ``FFA_MEM_DONATE`` - lender permanently relinquishes ownership of memory
-   to the borrower.
-
-The ``FFA_MEM_RETRIEVE_REQ`` interface is for the borrower to request the
-memory to be mapped into its address space: for S-EL1 partitions the SPM updates
-their stage 2 translation regime; for S-EL0 partitions the SPM updates their
-stage 1 translation regime. On a successful call, the SPMC responds back with
-``FFA_MEM_RETRIEVE_RESP``.
-
-The ``FFA_MEM_RELINQUISH`` interface is for when the borrower is done with using
-a memory region.
-
-The ``FFA_MEM_RECLAIM`` interface is for the owner of the memory to reestablish
-its ownership and exclusive access to the memory shared.
-
-The memory transaction descriptors are transmitted via RX/TX buffers. In
-situations where the size of the memory transaction descriptor exceeds the
-size of the RX/TX buffers, Hafnium provides support for fragmented transmission
-of the full transaction descriptor. The ``FFA_MEM_FRAG_RX`` and ``FFA_MEM_FRAG_TX``
-interfaces are for receiving and transmitting the next fragment, respectively.
-
-If lender and borrower(s) are SPs, all memory sharing operations are supported.
-
-Hafnium also supports memory sharing operations between the normal world and the
-secure world. If there is an SP involved, the SPMC allocates data to track the
-state of the operation.
-
-The SPMC is also the designated allocator for the memory handle. The hypervisor
-or OS kernel has the possibility to rely on the SPMC to maintain the state
-of the operation, thus saving memory.
-A lender SP can only donate NS memory to a borrower from the normal world.
-
-The SPMC supports the hypervisor retrieve request, as defined by the FF-A
-v1.1 EAC0 specification, in section 16.4.3. The intent is to aid with operations
-that the hypervisor must do for a VM retriever. For example, when handling
-an FFA_MEM_RECLAIM, if the hypervisor relies on SPMC to keep the state
-of the operation, the hypervisor retrieve request can be used to obtain
-that state information, do the necessary validations, and update stage 2
-memory translation.
-
-Hafnium also supports memory lend and share targetting multiple borrowers.
-This is the case for a lender SP to multiple SPs, and for a lender VM to
-multiple endpoints (from both secure world and normal world). If there is
-at least one borrower VM, the hypervisor is in charge of managing its
-stage 2 translation on a successful memory retrieve.
-The semantics of ``FFA_MEM_DONATE`` implies ownership transmission,
-which should target only one partition.
-
-The memory share interfaces are backwards compatible with memory transaction
-descriptors from FF-A v1.0. These get translated to FF-A v1.1 descriptors for
-Hafnium's internal processing of the operation. If the FF-A version of a
-borrower is v1.0, Hafnium provides FF-A v1.0 compliant memory transaction
-descriptors on memory retrieve response.
-
-PE MMU configuration
---------------------
-
-With secure virtualization enabled (``HCR_EL2.VM = 1``) and for S-EL1
-partitions, two IPA spaces (secure and non-secure) are output from the
-secure EL1&0 Stage-1 translation.
-The EL1&0 Stage-2 translation hardware is fed by:
-
-- A secure IPA when the SP EL1&0 Stage-1 MMU is disabled.
-- One of secure or non-secure IPA when the secure EL1&0 Stage-1 MMU is enabled.
-
-``VTCR_EL2`` and ``VSTCR_EL2`` provide configuration bits for controlling the
-NS/S IPA translations. The following controls are set up:
-``VSTCR_EL2.SW = 0`` , ``VSTCR_EL2.SA = 0``, ``VTCR_EL2.NSW = 0``,
-``VTCR_EL2.NSA = 1``:
-
-- Stage-2 translations for the NS IPA space access the NS PA space.
-- Stage-2 translation table walks for the NS IPA space are to the secure PA space.
-
-Secure and non-secure IPA regions (rooted to by ``VTTBR_EL2`` and ``VSTTBR_EL2``)
-use the same set of Stage-2 page tables within a SP.
-
-The ``VTCR_EL2/VSTCR_EL2/VTTBR_EL2/VSTTBR_EL2`` virtual address space
-configuration is made part of a vCPU context.
-
-For S-EL0 partitions with VHE enabled, a single secure EL2&0 Stage-1 translation
-regime is used for both Hafnium and the partition.
-
-Schedule modes and SP Call chains
----------------------------------
-
-An SP execution context is said to be in SPMC scheduled mode if CPU cycles are
-allocated to it by SPMC. Correspondingly, an SP execution context is said to be
-in Normal world scheduled mode if CPU cycles are allocated by the normal world.
-
-A call chain represents all SPs in a sequence of invocations of a direct message
-request. When execution on a PE is in the secure state, only a single call chain
-that runs in the Normal World scheduled mode can exist. FF-A v1.1 spec allows
-any number of call chains to run in the SPMC scheduled mode but the Hafnium
-SPMC restricts the number of call chains in SPMC scheduled mode to only one for
-keeping the implementation simple.
-
-Partition runtime models
-------------------------
-
-The runtime model of an endpoint describes the transitions permitted for an
-execution context between various states. These are the four partition runtime
-models supported (refer to `[1]`_ section 7):
-
-  - RTM_FFA_RUN: runtime model presented to an execution context that is
-    allocated CPU cycles through FFA_RUN interface.
-  - RTM_FFA_DIR_REQ: runtime model presented to an execution context that is
-    allocated CPU cycles through FFA_MSG_SEND_DIRECT_REQ interface.
-  - RTM_SEC_INTERRUPT: runtime model presented to an execution context that is
-    allocated CPU cycles by SPMC to handle a secure interrupt.
-  - RTM_SP_INIT: runtime model presented to an execution context that is
-    allocated CPU cycles by SPMC to initialize its state.
-
-If an endpoint execution context attempts to make an invalid transition or a
-valid transition that could lead to a loop in the call chain, SPMC denies the
-transition with the help of above runtime models.
-
-Interrupt management
---------------------
-
-GIC ownership
-~~~~~~~~~~~~~
-
-The SPMC owns the GIC configuration. Secure and non-secure interrupts are
-trapped at S-EL2. The SPMC manages interrupt resources and allocates interrupt
-IDs based on SP manifests. The SPMC acknowledges physical interrupts and injects
-virtual interrupts by setting the use of vIRQ/vFIQ bits before resuming a SP.
-
-Abbreviations:
-
-  - NS-Int: A non-secure physical interrupt. It requires a switch to the normal
-    world to be handled if it triggers while execution is in secure world.
-  - Other S-Int: A secure physical interrupt targeted to an SP different from
-    the one that is currently running.
-  - Self S-Int: A secure physical interrupt targeted to the SP that is currently
-    running.
-
-Non-secure interrupt handling
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-This section documents the actions supported in SPMC in response to a non-secure
-interrupt as per the guidance provided by FF-A v1.1 EAC0 specification.
-An SP specifies one of the following actions in its partition manifest:
-
-  - Non-secure interrupt is signaled.
-  - Non-secure interrupt is signaled after a managed exit.
-  - Non-secure interrupt is queued.
-
-An SP execution context in a call chain could specify a less permissive action
-than subsequent SP execution contexts in the same call chain. The less
-permissive action takes precedence over the more permissive actions specified
-by the subsequent execution contexts. Please refer to FF-A v1.1 EAC0 section
-8.3.1 for further explanation.
-
-Secure interrupt handling
-~~~~~~~~~~~~~~~~~~~~~~~~~
-
-This section documents the support implemented for secure interrupt handling in
-SPMC as per the guidance provided by FF-A v1.1 EAC0 specification.
-The following assumptions are made about the system configuration:
-
-  - In the current implementation, S-EL1 SPs are expected to use the para
-    virtualized ABIs for interrupt management rather than accessing the virtual
-    GIC interface.
-  - Unless explicitly stated otherwise, this support is applicable only for
-    S-EL1 SPs managed by SPMC.
-  - Secure interrupts are configured as G1S or G0 interrupts.
-  - All physical interrupts are routed to SPMC when running a secure partition
-    execution context.
-  - All endpoints with multiple execution contexts have their contexts pinned
-    to corresponding CPUs. Hence, a secure virtual interrupt cannot be signaled
-    to a target vCPU that is currently running or blocked on a different
-    physical CPU.
-
-A physical secure interrupt could trigger while CPU is executing in normal world
-or secure world.
-The action of SPMC for a secure interrupt depends on: the state of the target
-execution context of the SP that is responsible for handling the interrupt;
-whether the interrupt triggered while execution was in normal world or secure
-world.
-
-Secure interrupt signaling mechanisms
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Signaling refers to the mechanisms used by SPMC to indicate to the SP execution
-context that it has a pending virtual interrupt and to further run the SP
-execution context, such that it can handle the virtual interrupt. SPMC uses
-either the FFA_INTERRUPT interface with ERET conduit or vIRQ signal for signaling
-to S-EL1 SPs. When normal world execution is preempted by a secure interrupt,
-the SPMD uses the FFA_INTERRUPT ABI with ERET conduit to signal interrupt to SPMC
-running in S-EL2.
-
-+-----------+---------+---------------+---------------------------------------+
-| SP State  | Conduit | Interface and | Description                           |
-|           |         | parameters    |                                       |
-+-----------+---------+---------------+---------------------------------------+
-| WAITING   | ERET,   | FFA_INTERRUPT,| SPMC signals to SP the ID of pending  |
-|           | vIRQ    | Interrupt ID  | interrupt. It pends vIRQ signal and   |
-|           |         |               | resumes execution context of SP       |
-|           |         |               | through ERET.                         |
-+-----------+---------+---------------+---------------------------------------+
-| BLOCKED   | ERET,   | FFA_INTERRUPT | SPMC signals to SP that an interrupt  |
-|           | vIRQ    |               | is pending. It pends vIRQ signal and  |
-|           |         |               | resumes execution context of SP       |
-|           |         |               | through ERET.                         |
-+-----------+---------+---------------+---------------------------------------+
-| PREEMPTED | vIRQ    | NA            | SPMC pends the vIRQ signal but does   |
-|           |         |               | not resume execution context of SP.   |
-+-----------+---------+---------------+---------------------------------------+
-| RUNNING   | ERET,   | NA            | SPMC pends the vIRQ signal and resumes|
-|           | vIRQ    |               | execution context of SP through ERET. |
-+-----------+---------+---------------+---------------------------------------+
-
-Secure interrupt completion mechanisms
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-A SP signals secure interrupt handling completion to the SPMC through the
-following mechanisms:
-
-  - ``FFA_MSG_WAIT`` ABI if it was in WAITING state.
-  - ``FFA_RUN`` ABI if its was in BLOCKED state.
-
-This is a remnant of SPMC implementation based on the FF-A v1.0 specification.
-In the current implementation, S-EL1 SPs use the para-virtualized HVC interface
-implemented by SPMC to perform priority drop and interrupt deactivation (SPMC
-configures EOImode = 0, i.e. priority drop and deactivation are done together).
-The SPMC performs checks to deny the state transition upon invocation of
-either FFA_MSG_WAIT or FFA_RUN interface if the SP didn't perform the
-deactivation of the secure virtual interrupt.
-
-If the current SP execution context was preempted by a secure interrupt to be
-handled by execution context of target SP, SPMC resumes current SP after signal
-completion by target SP execution context.
-
-Actions for a secure interrupt triggered while execution is in normal world
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-+-------------------+----------+-----------------------------------------------+
-| State of target   | Action   | Description                                   |
-| execution context |          |                                               |
-+-------------------+----------+-----------------------------------------------+
-| WAITING           | Signaled | This starts a new call chain in SPMC scheduled|
-|                   |          | mode.                                         |
-+-------------------+----------+-----------------------------------------------+
-| PREEMPTED         | Queued   | The target execution must have been preempted |
-|                   |          | by a non-secure interrupt. SPMC queues the    |
-|                   |          | secure virtual interrupt now. It is signaled  |
-|                   |          | when the target execution context next enters |
-|                   |          | the RUNNING state.                            |
-+-------------------+----------+-----------------------------------------------+
-| BLOCKED, RUNNING  | NA       | The target execution context is blocked or    |
-|                   |          | running on a different CPU. This is not       |
-|                   |          | supported by current SPMC implementation and  |
-|                   |          | execution hits panic.                         |
-+-------------------+----------+-----------------------------------------------+
-
-If normal world execution was preempted by a secure interrupt, SPMC uses
-FFA_NORMAL_WORLD_RESUME ABI to indicate completion of secure interrupt handling
-and further returns execution to normal world.
-
-The following figure describes interrupt handling flow when a secure interrupt
-triggers while execution is in normal world:
-
-.. image:: ../resources/diagrams/ffa-secure-interrupt-handling-nwd.png
-
-A brief description of the events:
-
-  - 1) Secure interrupt triggers while normal world is running.
-  - 2) FIQ gets trapped to EL3.
-  - 3) SPMD signals secure interrupt to SPMC at S-EL2 using FFA_INTERRUPT ABI.
-  - 4) SPMC identifies target vCPU of SP and injects virtual interrupt (pends
-       vIRQ).
-  - 5) Assuming SP1 vCPU is in WAITING state, SPMC signals virtual interrupt
-       using FFA_INTERRUPT with interrupt id as an argument and resumes the SP1
-       vCPU using ERET in SPMC scheduled mode.
-  - 6) Execution traps to vIRQ handler in SP1 provided that the virtual
-       interrupt is not masked i.e., PSTATE.I = 0
-  - 7) SP1 queries for the pending virtual interrupt id using a paravirtualized
-       HVC call. SPMC clears the pending virtual interrupt state management
-       and returns the pending virtual interrupt id.
-  - 8) SP1 services the virtual interrupt and invokes the paravirtualized
-       de-activation HVC call. SPMC de-activates the physical interrupt,
-       clears the fields tracking the secure interrupt and resumes SP1 vCPU.
-  - 9) SP1 performs secure interrupt completion through FFA_MSG_WAIT ABI.
-  - 10) SPMC returns control to EL3 using FFA_NORMAL_WORLD_RESUME.
-  - 11) EL3 resumes normal world execution.
-
-Actions for a secure interrupt triggered while execution is in secure world
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-+-------------------+----------+------------------------------------------------+
-| State of target   | Action   | Description                                    |
-| execution context |          |                                                |
-+-------------------+----------+------------------------------------------------+
-| WAITING           | Signaled | This starts a new call chain in SPMC scheduled |
-|                   |          | mode.                                          |
-+-------------------+----------+------------------------------------------------+
-| PREEMPTED by Self | Signaled | The target execution context reenters the      |
-| S-Int             |          | RUNNING state to handle the secure virtual     |
-|                   |          | interrupt.                                     |
-+-------------------+----------+------------------------------------------------+
-| PREEMPTED by      | Queued   | SPMC queues the secure virtual interrupt now.  |
-| NS-Int            |          | It is signaled when the target execution       |
-|                   |          | context next enters the RUNNING state.         |
-+-------------------+----------+------------------------------------------------+
-| BLOCKED           | Signaled | Both preempted and target execution contexts   |
-|                   |          | must have been part of the Normal world        |
-|                   |          | scheduled call chain. Refer scenario 1 of      |
-|                   |          | Table 8.4 in the FF-A v1.1 EAC0 spec.          |
-+-------------------+----------+------------------------------------------------+
-| RUNNING           | NA       | The target execution context is running on a   |
-|                   |          | different CPU. This scenario is not supported  |
-|                   |          | by current SPMC implementation and execution   |
-|                   |          | hits panic.                                    |
-+-------------------+----------+------------------------------------------------+
-
-The following figure describes interrupt handling flow when a secure interrupt
-triggers while execution is in secure world. We assume OS kernel sends a direct
-request message to SP1. Further, SP1 sends a direct request message to SP2. SP1
-enters BLOCKED state and SPMC resumes SP2.
-
-.. image:: ../resources/diagrams/ffa-secure-interrupt-handling-swd.png
-
-A brief description of the events:
-
-  - 1) Secure interrupt triggers while SP2 is running.
-  - 2) SP2 gets preempted and execution traps to SPMC as IRQ.
-  - 3) SPMC finds the target vCPU of secure partition responsible for handling
-       this secure interrupt. In this scenario, it is SP1.
-  - 4) SPMC pends vIRQ for SP1 and signals through FFA_INTERRUPT interface.
-       SPMC further resumes SP1 through ERET conduit. Note that SP1 remains in
-       Normal world schedule mode.
-  - 6) Execution traps to vIRQ handler in SP1 provided that the virtual
-       interrupt is not masked i.e., PSTATE.I = 0
-  - 7) SP1 queries for the pending virtual interrupt id using a paravirtualized
-       HVC call. SPMC clears the pending virtual interrupt state management
-       and returns the pending virtual interrupt id.
-  - 8) SP1 services the virtual interrupt and invokes the paravirtualized
-       de-activation HVC call. SPMC de-activates the physical interrupt and
-       clears the fields tracking the secure interrupt and resumes SP1 vCPU.
-  - 9) Since SP1 direct request completed with FFA_INTERRUPT, it resumes the
-       direct request to SP2 by invoking FFA_RUN.
-  - 9) SPMC resumes the pre-empted vCPU of SP2.
-
-EL3 interrupt handling
-~~~~~~~~~~~~~~~~~~~~~~
-
-In GICv3 based systems, EL3 interrupts are configured as Group0 secure
-interrupts. Execution traps to SPMC when a Group0 interrupt triggers while an
-SP is running. Further, SPMC running at S-EL2 uses FFA_EL3_INTR_HANDLE ABI to
-request EL3 platform firmware to handle a pending Group0 interrupt.
-Similarly, SPMD registers a handler with interrupt management framework to
-delegate handling of Group0 interrupt to the platform if the interrupt triggers
-in normal world.
-
- - Platform hook
-
-   - plat_spmd_handle_group0_interrupt
-
-     SPMD provides platform hook to handle Group0 secure interrupts. In the
-     current design, SPMD expects the platform not to delegate handling to the
-     NWd (such as through SDEI) while processing Group0 interrupts.
-
-Power management
-----------------
-
-In platforms with or without secure virtualization:
-
-- The NWd owns the platform PM policy.
-- The Hypervisor or OS kernel is the component initiating PSCI service calls.
-- The EL3 PSCI library is in charge of the PM coordination and control
-  (eventually writing to platform registers).
-- While coordinating PM events, the PSCI library calls backs into the Secure
-  Payload Dispatcher for events the latter has statically registered to.
-
-When using the SPMD as a Secure Payload Dispatcher:
-
-- A power management event is relayed through the SPD hook to the SPMC.
-- In the current implementation only cpu on (svc_on_finish) and cpu off
-  (svc_off) hooks are registered.
-- The behavior for the cpu on event is described in `Secondary cores boot-up`_.
-  The SPMC is entered through its secondary physical core entry point.
-- The cpu off event occurs when the NWd calls PSCI_CPU_OFF. The PM event is
-  signaled to the SPMC through a power management framework message.
-  It consists in a SPMD-to-SPMC direct request/response (`SPMC-SPMD direct
-  requests/responses`_) conveying the event details and SPMC response.
-  The SPMD performs a synchronous entry into the SPMC. The SPMC is entered and
-  updates its internal state to reflect the physical core is being turned off.
-  In the current implementation no SP is resumed as a consequence. This behavior
-  ensures a minimal support for CPU hotplug e.g. when initiated by the NWd linux
-  userspace.
-
-Arm architecture extensions for security hardening
-==================================================
-
-Hafnium supports the following architecture extensions for security hardening:
-
-- Pointer authentication (FEAT_PAuth): the extension permits detection of forged
-  pointers used by ROP type of attacks through the signing of the pointer
-  value. Hafnium is built with the compiler branch protection option to permit
-  generation of a pointer authentication code for return addresses (pointer
-  authentication for instructions). The APIA key is used while Hafnium runs.
-  A random key is generated at boot time and restored upon entry into Hafnium
-  at run-time. APIA and other keys (APIB, APDA, APDB, APGA) are saved/restored
-  in vCPU contexts permitting to enable pointer authentication in VMs/SPs.
-- Branch Target Identification (FEAT_BTI): the extension permits detection of
-  unexpected indirect branches used by JOP type of attacks. Hafnium is built
-  with the compiler branch protection option, inserting land pads at function
-  prologues that are reached by indirect branch instructions (BR/BLR).
-  Hafnium code pages are marked as guarded in the EL2 Stage-1 MMU descriptors
-  such that an indirect branch must always target a landpad. A fault is
-  triggered otherwise. VMs/SPs can (independently) mark their code pages as
-  guarded in the EL1&0 Stage-1 translation regime.
-- Memory Tagging Extension (FEAT_MTE): the option permits detection of out of
-  bound memory array accesses or re-use of an already freed memory region.
-  Hafnium enables the compiler option permitting to leverage MTE stack tagging
-  applied to core stacks. Core stacks are marked as normal tagged memory in the
-  EL2 Stage-1 translation regime. A synchronous data abort is generated upon tag
-  check failure on load/stores. A random seed is generated at boot time and
-  restored upon entry into Hafnium. MTE system registers are saved/restored in
-  vCPU contexts permitting MTE usage from VMs/SPs.
-
-SMMUv3 support in Hafnium
-=========================
-
-An SMMU is analogous to an MMU in a CPU. It performs address translations for
-Direct Memory Access (DMA) requests from system I/O devices.
-The responsibilities of an SMMU include:
-
--  Translation: Incoming DMA requests are translated from bus address space to
-   system physical address space using translation tables compliant to
-   Armv8/Armv7 VMSA descriptor format.
--  Protection: An I/O device can be prohibited from read, write access to a
-   memory region or allowed.
--  Isolation: Traffic from each individial device can be independently managed.
-   The devices are differentiated from each other using unique translation
-   tables.
-
-The following diagram illustrates a typical SMMU IP integrated in a SoC with
-several I/O devices along with Interconnect and Memory system.
-
-.. image:: ../resources/diagrams/MMU-600.png
-
-SMMU has several versions including SMMUv1, SMMUv2 and SMMUv3. Hafnium provides
-support for SMMUv3 driver in both normal and secure world. A brief introduction
-of SMMUv3 functionality and the corresponding software support in Hafnium is
-provided here.
-
-SMMUv3 features
----------------
-
--  SMMUv3 provides Stage1, Stage2 translation as well as nested (Stage1 + Stage2)
-   translation support. It can either bypass or abort incoming translations as
-   well.
--  Traffic (memory transactions) from each upstream I/O peripheral device,
-   referred to as Stream, can be independently managed using a combination of
-   several memory based configuration structures. This allows the SMMUv3 to
-   support a large number of streams with each stream assigned to a unique
-   translation context.
--  Support for Armv8.1 VMSA where the SMMU shares the translation tables with
-   a Processing Element. AArch32(LPAE) and AArch64 translation table format
-   are supported by SMMUv3.
--  SMMUv3 offers non-secure stream support with secure stream support being
-   optional. Logically, SMMUv3 behaves as if there is an indepdendent SMMU
-   instance for secure and non-secure stream support.
--  It also supports sub-streams to differentiate traffic from a virtualized
-   peripheral associated with a VM/SP.
--  Additionally, SMMUv3.2 provides support for PEs implementing Armv8.4-A
-   extensions. Consequently, SPM depends on Secure EL2 support in SMMUv3.2
-   for providing Secure Stage2 translation support to upstream peripheral
-   devices.
-
-SMMUv3 Programming Interfaces
------------------------------
-
-SMMUv3 has three software interfaces that are used by the Hafnium driver to
-configure the behaviour of SMMUv3 and manage the streams.
-
--  Memory based data strutures that provide unique translation context for
-   each stream.
--  Memory based circular buffers for command queue and event queue.
--  A large number of SMMU configuration registers that are memory mapped during
-   boot time by Hafnium driver. Except a few registers, all configuration
-   registers have independent secure and non-secure versions to configure the
-   behaviour of SMMUv3 for translation of secure and non-secure streams
-   respectively.
-
-Peripheral device manifest
---------------------------
-
-Currently, SMMUv3 driver in Hafnium only supports dependent peripheral devices.
-These devices are dependent on PE endpoint to initiate and receive memory
-management transactions on their behalf. The acccess to the MMIO regions of
-any such device is assigned to the endpoint during boot. Moreover, SMMUv3 driver
-uses the same stage 2 translations for the device as those used by partition
-manager on behalf of the PE endpoint. This ensures that the peripheral device
-has the same visibility of the physical address space as the endpoint. The
-device node of the corresponding partition manifest (refer to `[1]`_ section 3.2
-) must specify these additional properties for each peripheral device in the
-system :
-
--  smmu-id: This field helps to identify the SMMU instance that this device is
-   upstream of.
--  stream-ids: List of stream IDs assigned to this device.
-
-.. code:: shell
-
-    smmuv3-testengine {
-        base-address = <0x00000000 0x2bfe0000>;
-        pages-count = <32>;
-        attributes = <0x3>;
-        smmu-id = <0>;
-        stream-ids = <0x0 0x1>;
-        interrupts = <0x2 0x3>, <0x4 0x5>;
-        exclusive-access;
-    };
-
-SMMUv3 driver limitations
--------------------------
-
-The primary design goal for the Hafnium SMMU driver is to support secure
-streams.
-
--  Currently, the driver only supports Stage2 translations. No support for
-   Stage1 or nested translations.
--  Supports only AArch64 translation format.
--  No support for features such as PCI Express (PASIDs, ATS, PRI), MSI, RAS,
-   Fault handling, Performance Monitor Extensions, Event Handling, MPAM.
--  No support for independent peripheral devices.
-
-S-EL0 Partition support
-=======================
-The SPMC (Hafnium) has limited capability to run S-EL0 FF-A partitions using
-FEAT_VHE (mandatory with ARMv8.1 in non-secure state, and in secure world
-with ARMv8.4 and FEAT_SEL2).
-
-S-EL0 partitions are useful for simple partitions that don't require full
-Trusted OS functionality. It is also useful to reduce jitter and cycle
-stealing from normal world since they are more lightweight than VMs.
-
-S-EL0 partitions are presented, loaded and initialized the same as S-EL1 VMs by
-the SPMC. They are differentiated primarily by the 'exception-level' property
-and the 'execution-ctx-count' property in the SP manifest. They are host apps
-under the single EL2&0 Stage-1 translation regime controlled by the SPMC and
-call into the SPMC through SVCs as opposed to HVCs and SMCs. These partitions
-can use FF-A defined services (FFA_MEM_PERM_*) to update or change permissions
-for memory regions.
-
-S-EL0 partitions are required by the FF-A specification to be UP endpoints,
-capable of migrating, and the SPMC enforces this requirement. The SPMC allows
-a S-EL0 partition to accept a direct message from secure world and normal world,
-and generate direct responses to them.
-All S-EL0 partitions must use AArch64. AArch32 S-EL0 partitions are not supported.
-
-Memory sharing, indirect messaging, and notifications functionality with S-EL0
-partitions is supported.
-
-Interrupt handling is not supported with S-EL0 partitions and is work in
-progress.
 
 References
 ==========
@@ -1641,8 +242,7 @@
 
 .. _[3]:
 
-[3] `Trusted Boot Board Requirements
-Client <https://developer.arm.com/documentation/den0006/d/>`__
+[3] https://hafnium.readthedocs.io/en/latest/secure-partition-manager/secure-partition-manager.html#secure-partitions-layout-file
 
 .. _[4]:
 
@@ -1650,23 +250,15 @@
 
 .. _[5]:
 
-[5] https://git.trustedfirmware.org/TF-A/tf-a-tests.git/tree/spm/cactus/plat/arm/fvp/fdts/cactus.dts
+[5] https://hafnium.readthedocs.io/en/latest/secure-partition-manager/index.html
 
 .. _[6]:
 
-[6] https://trustedfirmware-a.readthedocs.io/en/latest/components/ffa-manifest-binding.html
+[6] :ref:`EL3 Secure Partition Manager<EL3 Secure Partition Manager>`
 
 .. _[7]:
 
-[7] https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/tree/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts
-
-.. _[8]:
-
-[8] https://lists.trustedfirmware.org/archives/list/tf-a@lists.trustedfirmware.org/thread/CFQFGU6H2D5GZYMUYGTGUSXIU3OYZP6U/
-
-.. _[9]:
-
-[9] https://trustedfirmware-a.readthedocs.io/en/latest/design/firmware-design.html#dynamic-configuration-during-cold-boot
+[7] https://trustedfirmware-a.readthedocs.io/en/latest/design/firmware-design.html#dynamic-configuration-during-cold-boot
 
 --------------
 
diff --git a/docs/plat/xilinx-versal-net.rst b/docs/plat/xilinx-versal-net.rst
index e9dd772..d22a46d 100644
--- a/docs/plat/xilinx-versal-net.rst
+++ b/docs/plat/xilinx-versal-net.rst
@@ -75,7 +75,7 @@
 | 0xc2001000-0xc2001FFF     | Fast SMC64 SiP Service call range used for AMD-Xilinx IPI |
 +---------------------------+-----------------------------------------------------------+
 
-PM SMC call ranges
+PM SMC call ranges for SiP SVC version 0.1
 --------------------------------------------------------
 
 +---------------------------+---------------------------------------------------------------------------+
@@ -84,6 +84,19 @@
 | 0xc2000000-0xc2000FFF     | Fast SMC64 SiP Service call range used for AMD-Xilinx Platform Management |
 +---------------------------+---------------------------------------------------------------------------+
 
+PM SMC call ranges for SiP SVC version 0.2
+--------------------------------------------------------
+
++---------------------------+---------------------------------------------------------------------------+
+|   SMC Function Identifier |  Service type                                                             |
++---------------------------+---------------------------------------------------------------------------+
+| 0xc2000FFF                | Fast SMC64 SiP Service call used for pass-through of AMD-Xilinx Platform  |
+|                           | Management APIs to firmware                                               |
++---------------------------+---------------------------------------------------------------------------+
+| 0xc2000A00-0xc2000AFF     | Fast SMC64 SiP Service call range used for AMD-Xilinx Platform Management |
+|                           | specific TF-A APIs                                                        |
++---------------------------+---------------------------------------------------------------------------+
+
 SMC function IDs for SiP Service queries
 ----------------------------------------------
 
diff --git a/docs/plat/xilinx-versal.rst b/docs/plat/xilinx-versal.rst
index 072329a..7185d91 100644
--- a/docs/plat/xilinx-versal.rst
+++ b/docs/plat/xilinx-versal.rst
@@ -14,11 +14,6 @@
 make RESET_TO_BL31=1 CROSS_COMPILE=aarch64-none-elf- PLAT=versal bl31
 ```
 
-To build ATF for different platform (supported are "silicon"(default) and "versal_virt")
-```bash
-make RESET_TO_BL31=1 CROSS_COMPILE=aarch64-none-elf- PLAT=versal VERSAL_PLATFORM=versal_virt bl31
-```
-
 To build bl32 TSP you have to rebuild bl31 too
 ```bash
 make CROSS_COMPILE=aarch64-none-elf- PLAT=versal SPD=tspd RESET_TO_BL31=1 bl31 bl32
@@ -51,11 +46,6 @@
     -   `pl011`, `pl011_0`: ARM pl011 UART 0
     -   `pl011_1`         : ARM pl011 UART 1
 
-*   `VERSAL_PLATFORM`: Select the platform. Options:
-    -   `versal_virt`	: Versal Virtual platform
-    -   `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:
@@ -98,8 +88,8 @@
 | 0xc2001000-0xc2001FFF     | Fast SMC64 SiP Service call range used for AMD-Xilinx IPI |
 +---------------------------+-----------------------------------------------------------+
 
-PM SMC call ranges
-------------------
+PM SMC call ranges for SiP SVC version 0.1
+--------------------------------------------------------
 
 +---------------------------+---------------------------------------------------------------------------+
 |   SMC Function Identifier |  Service type                                                             |
@@ -107,6 +97,19 @@
 | 0xc2000000-0xc2000FFF     | Fast SMC64 SiP Service call range used for AMD-Xilinx Platform Management |
 +---------------------------+---------------------------------------------------------------------------+
 
+PM SMC call ranges for SiP SVC version 0.2
+--------------------------------------------------------
+
++---------------------------+---------------------------------------------------------------------------+
+|   SMC Function Identifier |  Service type                                                             |
++---------------------------+---------------------------------------------------------------------------+
+| 0xc2000FFF                | Fast SMC64 SiP Service call used for pass-through of AMD-Xilinx Platform  |
+|                           | Management APIs to firmware                                               |
++---------------------------+---------------------------------------------------------------------------+
+| 0xc2000A00-0xc2000AFF     | Fast SMC64 SiP Service call range used for AMD-Xilinx Platform Management |
+|                           | specific TF-A APIs                                                        |
++---------------------------+---------------------------------------------------------------------------+
+
 SMC function IDs for SiP Service queries
 ----------------------------------------
 
diff --git a/drivers/arm/gic/v3/arm_gicv3_common.c b/drivers/arm/gic/v3/arm_gicv3_common.c
index 4489892..cc82ddb 100644
--- a/drivers/arm/gic/v3/arm_gicv3_common.c
+++ b/drivers/arm/gic/v3/arm_gicv3_common.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -28,10 +28,13 @@
 void arm_gicv3_distif_pre_save(unsigned int rdist_proc_num)
 {
 	uintptr_t gicr_base = 0;
+	unsigned int typer_reg;
 
 	assert(gicv3_driver_data);
 	assert(gicv3_driver_data->rdistif_base_addrs);
+	assert(gicv3_driver_data->gicd_base != 0U);
 
+	typer_reg = gicd_read_typer(gicv3_driver_data->gicd_base);
 	/*
 	 * The GICR_WAKER.Sleep bit should be set only when both
 	 * GICR_WAKER.ChildrenAsleep and GICR_WAKER.ProcessorSleep are set on
@@ -60,9 +63,14 @@
 	 */
 	gicr_write_waker(gicr_base, gicr_read_waker(gicr_base) | WAKER_SL_BIT);
 
-	/* Wait until the GICR_WAKER.Quiescent bit is set */
-	while (!(gicr_read_waker(gicr_base) & WAKER_QSC_BIT))
-		;
+	/*
+	 * If LPIs are supported, wait until the GICR_WAKER.Quiescent bit is
+	 * set.
+	 */
+	if ((typer_reg & TYPER_LPIS) != 0U) {
+		while (!(gicr_read_waker(gicr_base) & WAKER_QSC_BIT))
+			;
+	}
 }
 
 /*
diff --git a/drivers/arm/gic/v3/gicv3_main.c b/drivers/arm/gic/v3/gicv3_main.c
index 8ea164c..2be19db 100644
--- a/drivers/arm/gic/v3/gicv3_main.c
+++ b/drivers/arm/gic/v3/gicv3_main.c
@@ -686,6 +686,8 @@
 	gicr_write_ctlr(gicr_base,
 			rdist_ctx->gicr_ctlr & ~(GICR_CTLR_EN_LPIS_BIT));
 
+	gicr_wait_for_pending_write(gicr_base);
+
 	/* Restore registers' content */
 	gicr_write_propbaser(gicr_base, rdist_ctx->gicr_propbaser);
 	gicr_write_pendbaser(gicr_base, rdist_ctx->gicr_pendbaser);
diff --git a/drivers/nxp/clk/s32cc/include/s32cc-clk-regs.h b/drivers/nxp/clk/s32cc/include/s32cc-clk-regs.h
index 7205232..d62eed7 100644
--- a/drivers/nxp/clk/s32cc/include/s32cc-clk-regs.h
+++ b/drivers/nxp/clk/s32cc/include/s32cc-clk-regs.h
@@ -9,6 +9,8 @@
 
 #define FXOSC_BASE_ADDR			(0x40050000UL)
 #define ARMPLL_BASE_ADDR		(0x40038000UL)
+#define ARM_DFS_BASE_ADDR		(0x40054000UL)
+#define CGM0_BASE_ADDR			(0x40030000UL)
 #define CGM1_BASE_ADDR			(0x40034000UL)
 
 /* FXOSC */
@@ -83,4 +85,25 @@
 #define MC_CGM_MUXn_CSS_SWIP		BIT_32(16U)
 #define MC_CGM_MUXn_CSS_SAFE_SW		BIT_32(3U)
 
+/* DFS */
+#define DFS_PORTSR(DFS_ADDR)		((DFS_ADDR) + 0xCUL)
+#define DFS_PORTOLSR(DFS_ADDR)		((DFS_ADDR) + 0x10UL)
+#define DFS_PORTOLSR_LOL(N)		(BIT_32(N) & GENMASK_32(5U, 0U))
+#define DFS_PORTRESET(DFS_ADDR)		((DFS_ADDR) + 0x14UL)
+#define DFS_PORTRESET_MASK		GENMASK_32(5U, 0U)
+#define DFS_PORTRESET_SET(VAL)		(((VAL) & DFS_PORTRESET_MASK))
+
+#define DFS_CTL(DFS_ADDR)		((DFS_ADDR) + 0x18UL)
+#define DFS_CTL_RESET			BIT_32(1U)
+
+#define DFS_DVPORTn(DFS_ADDR, PORT)	((DFS_ADDR) + 0x1CUL + ((PORT) * 0x4UL))
+#define DFS_DVPORTn_MFI_MASK		GENMASK_32(15U, 8U)
+#define DFS_DVPORTn_MFI_SHIFT		8U
+#define DFS_DVPORTn_MFN_MASK		GENMASK_32(7U, 0U)
+#define DFS_DVPORTn_MFN_SHIFT		0U
+#define DFS_DVPORTn_MFI(MFI)		(((MFI) & DFS_DVPORTn_MFI_MASK) >> DFS_DVPORTn_MFI_SHIFT)
+#define DFS_DVPORTn_MFN(MFN)		(((MFN) & DFS_DVPORTn_MFN_MASK) >> DFS_DVPORTn_MFN_SHIFT)
+#define DFS_DVPORTn_MFI_SET(VAL)	(((VAL) << DFS_DVPORTn_MFI_SHIFT) & DFS_DVPORTn_MFI_MASK)
+#define DFS_DVPORTn_MFN_SET(VAL)	(((VAL) << DFS_DVPORTn_MFN_SHIFT) & DFS_DVPORTn_MFN_MASK)
+
 #endif /* S32CC_CLK_REGS_H */
diff --git a/drivers/nxp/clk/s32cc/s32cc_clk_drv.c b/drivers/nxp/clk/s32cc/s32cc_clk_drv.c
index 6f18dd3..e23d928 100644
--- a/drivers/nxp/clk/s32cc/s32cc_clk_drv.c
+++ b/drivers/nxp/clk/s32cc/s32cc_clk_drv.c
@@ -22,6 +22,8 @@
 struct s32cc_clk_drv {
 	uintptr_t fxosc_base;
 	uintptr_t armpll_base;
+	uintptr_t armdfs_base;
+	uintptr_t cgm0_base;
 	uintptr_t cgm1_base;
 };
 
@@ -40,6 +42,8 @@
 	static struct s32cc_clk_drv driver = {
 		.fxosc_base = FXOSC_BASE_ADDR,
 		.armpll_base = ARMPLL_BASE_ADDR,
+		.armdfs_base = ARM_DFS_BASE_ADDR,
+		.cgm0_base = CGM0_BASE_ADDR,
 		.cgm1_base = CGM1_BASE_ADDR,
 	};
 
@@ -87,6 +91,12 @@
 	case S32CC_ARM_PLL:
 		*base = drv->armpll_base;
 		break;
+	case S32CC_ARM_DFS:
+		*base = drv->armdfs_base;
+		break;
+	case S32CC_CGM0:
+		*base = drv->cgm0_base;
+		break;
 	case S32CC_CGM1:
 		*base = drv->cgm1_base;
 		break;
@@ -542,6 +552,9 @@
 	case S32CC_CGM1:
 		ret = enable_cgm_mux(mux, drv);
 		break;
+	case S32CC_CGM0:
+		ret = enable_cgm_mux(mux, drv);
+		break;
 	default:
 		ERROR("Unknown mux parent type: %d\n", mux->module);
 		ret = -EINVAL;
@@ -551,6 +564,199 @@
 	return ret;
 }
 
+static int enable_dfs(const struct s32cc_clk_obj *module,
+		      const struct s32cc_clk_drv *drv,
+		      unsigned int *depth)
+{
+	int ret = 0;
+
+	ret = update_stack_depth(depth);
+	if (ret != 0) {
+		return ret;
+	}
+
+	return 0;
+}
+
+static struct s32cc_dfs *get_div_dfs(const struct s32cc_dfs_div *dfs_div)
+{
+	const struct s32cc_clk_obj *parent = dfs_div->parent;
+
+	if (parent->type != s32cc_dfs_t) {
+		ERROR("DFS DIV doesn't have a DFS as parent\n");
+		return NULL;
+	}
+
+	return s32cc_obj2dfs(parent);
+}
+
+static struct s32cc_pll *dfsdiv2pll(const struct s32cc_dfs_div *dfs_div)
+{
+	const struct s32cc_clk_obj *parent;
+	const struct s32cc_dfs *dfs;
+
+	dfs = get_div_dfs(dfs_div);
+	if (dfs == NULL) {
+		return NULL;
+	}
+
+	parent = dfs->parent;
+	if (parent->type != s32cc_pll_t) {
+		return NULL;
+	}
+
+	return s32cc_obj2pll(parent);
+}
+
+static int get_dfs_mfi_mfn(unsigned long dfs_freq, const struct s32cc_dfs_div *dfs_div,
+			   uint32_t *mfi, uint32_t *mfn)
+{
+	uint64_t factor64, tmp64, ofreq;
+	uint32_t factor32;
+
+	unsigned long in = dfs_freq;
+	unsigned long out = dfs_div->freq;
+
+	/**
+	 * factor = (IN / OUT) / 2
+	 * MFI = integer(factor)
+	 * MFN = (factor - MFI) * 36
+	 */
+	factor64 = ((((uint64_t)in) * FP_PRECISION) / ((uint64_t)out)) / 2ULL;
+	tmp64 = factor64 / FP_PRECISION;
+	if (tmp64 > UINT32_MAX) {
+		return -EINVAL;
+	}
+
+	factor32 = (uint32_t)tmp64;
+	*mfi = factor32;
+
+	tmp64 = ((factor64 - ((uint64_t)*mfi * FP_PRECISION)) * 36UL) / FP_PRECISION;
+	if (tmp64 > UINT32_MAX) {
+		return -EINVAL;
+	}
+
+	*mfn = (uint32_t)tmp64;
+
+	/* div_freq = in / (2 * (*mfi + *mfn / 36.0)) */
+	factor64 = (((uint64_t)*mfn) * FP_PRECISION) / 36ULL;
+	factor64 += ((uint64_t)*mfi) * FP_PRECISION;
+	factor64 *= 2ULL;
+	ofreq = (((uint64_t)in) * FP_PRECISION) / factor64;
+
+	if (ofreq != dfs_div->freq) {
+		ERROR("Failed to find MFI and MFN settings for DFS DIV freq %lu\n",
+		      dfs_div->freq);
+		ERROR("Nearest freq = %" PRIx64 "\n", ofreq);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int init_dfs_port(uintptr_t dfs_addr, uint32_t port,
+			 uint32_t mfi, uint32_t mfn)
+{
+	uint32_t portsr, portolsr;
+	uint32_t mask, old_mfi, old_mfn;
+	uint32_t dvport;
+	bool init_dfs;
+
+	dvport = mmio_read_32(DFS_DVPORTn(dfs_addr, port));
+
+	old_mfi = DFS_DVPORTn_MFI(dvport);
+	old_mfn = DFS_DVPORTn_MFN(dvport);
+
+	portsr = mmio_read_32(DFS_PORTSR(dfs_addr));
+	portolsr = mmio_read_32(DFS_PORTOLSR(dfs_addr));
+
+	/* Skip configuration if it's not needed */
+	if (((portsr & BIT_32(port)) != 0U) &&
+	    ((portolsr & BIT_32(port)) == 0U) &&
+	    (mfi == old_mfi) && (mfn == old_mfn)) {
+		return 0;
+	}
+
+	init_dfs = (portsr == 0U);
+
+	if (init_dfs) {
+		mask = DFS_PORTRESET_MASK;
+	} else {
+		mask = DFS_PORTRESET_SET(BIT_32(port));
+	}
+
+	mmio_write_32(DFS_PORTOLSR(dfs_addr), mask);
+	mmio_write_32(DFS_PORTRESET(dfs_addr), mask);
+
+	while ((mmio_read_32(DFS_PORTSR(dfs_addr)) & mask) != 0U) {
+	}
+
+	if (init_dfs) {
+		mmio_write_32(DFS_CTL(dfs_addr), DFS_CTL_RESET);
+	}
+
+	mmio_write_32(DFS_DVPORTn(dfs_addr, port),
+		      DFS_DVPORTn_MFI_SET(mfi) | DFS_DVPORTn_MFN_SET(mfn));
+
+	if (init_dfs) {
+		/* DFS clk enable programming */
+		mmio_clrbits_32(DFS_CTL(dfs_addr), DFS_CTL_RESET);
+	}
+
+	mmio_clrbits_32(DFS_PORTRESET(dfs_addr), BIT_32(port));
+
+	while ((mmio_read_32(DFS_PORTSR(dfs_addr)) & BIT_32(port)) != BIT_32(port)) {
+	}
+
+	portolsr = mmio_read_32(DFS_PORTOLSR(dfs_addr));
+	if ((portolsr & DFS_PORTOLSR_LOL(port)) != 0U) {
+		ERROR("Failed to lock DFS divider\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int enable_dfs_div(const struct s32cc_clk_obj *module,
+			  const struct s32cc_clk_drv *drv,
+			  unsigned int *depth)
+{
+	const struct s32cc_dfs_div *dfs_div = s32cc_obj2dfsdiv(module);
+	const struct s32cc_pll *pll;
+	const struct s32cc_dfs *dfs;
+	uintptr_t dfs_addr = 0UL;
+	uint32_t mfi, mfn;
+	int ret = 0;
+
+	ret = update_stack_depth(depth);
+	if (ret != 0) {
+		return ret;
+	}
+
+	dfs = get_div_dfs(dfs_div);
+	if (dfs == NULL) {
+		return -EINVAL;
+	}
+
+	pll = dfsdiv2pll(dfs_div);
+	if (pll == NULL) {
+		ERROR("Failed to identify DFS divider's parent\n");
+		return -EINVAL;
+	}
+
+	ret = get_base_addr(dfs->instance, drv, &dfs_addr);
+	if ((ret != 0) || (dfs_addr == 0UL)) {
+		return -EINVAL;
+	}
+
+	ret = get_dfs_mfi_mfn(pll->vco_freq, dfs_div, &mfi, &mfn);
+	if (ret != 0) {
+		return -EINVAL;
+	}
+
+	return init_dfs_port(dfs_addr, dfs_div->index, mfi, mfn);
+}
+
 static int enable_module(const struct s32cc_clk_obj *module, unsigned int *depth)
 {
 	const struct s32cc_clk_drv *drv = get_drv();
@@ -587,6 +793,12 @@
 	case s32cc_fixed_div_t:
 		ret = -ENOTSUP;
 		break;
+	case s32cc_dfs_t:
+		ret = enable_dfs(module, drv, depth);
+		break;
+	case s32cc_dfs_div_t:
+		ret = enable_dfs_div(module, drv, depth);
+		break;
 	default:
 		ret = -EINVAL;
 		break;
@@ -793,6 +1005,42 @@
 	return set_module_rate(&clk->desc, rate, orate, depth);
 }
 
+static int set_dfs_div_freq(const struct s32cc_clk_obj *module, unsigned long rate,
+			    unsigned long *orate, unsigned int *depth)
+{
+	struct s32cc_dfs_div *dfs_div = s32cc_obj2dfsdiv(module);
+	const struct s32cc_dfs *dfs;
+	int ret;
+
+	ret = update_stack_depth(depth);
+	if (ret != 0) {
+		return ret;
+	}
+
+	if (dfs_div->parent == NULL) {
+		ERROR("Failed to identify DFS divider's parent\n");
+		return -EINVAL;
+	}
+
+	/* Sanity check */
+	dfs = s32cc_obj2dfs(dfs_div->parent);
+	if (dfs->parent == NULL) {
+		ERROR("Failed to identify DFS's parent\n");
+		return -EINVAL;
+	}
+
+	if ((dfs_div->freq != 0U) && (dfs_div->freq != rate)) {
+		ERROR("DFS DIV frequency was already set to %lu\n",
+		      dfs_div->freq);
+		return -EINVAL;
+	}
+
+	dfs_div->freq = rate;
+	*orate = rate;
+
+	return ret;
+}
+
 static int set_module_rate(const struct s32cc_clk_obj *module,
 			   unsigned long rate, unsigned long *orate,
 			   unsigned int *depth)
@@ -804,6 +1052,8 @@
 		return ret;
 	}
 
+	ret = -EINVAL;
+
 	switch (module->type) {
 	case s32cc_clk_t:
 		ret = set_clk_freq(module, rate, orate, depth);
@@ -826,8 +1076,13 @@
 	case s32cc_shared_clkmux_t:
 		ret = set_mux_freq(module, rate, orate, depth);
 		break;
+	case s32cc_dfs_t:
+		ERROR("Setting the frequency of a DFS is not allowed!");
+		break;
+	case s32cc_dfs_div_t:
+		ret = set_dfs_div_freq(module, rate, orate, depth);
+		break;
 	default:
-		ret = -EINVAL;
 		break;
 	}
 
diff --git a/drivers/nxp/clk/s32cc/s32cc_clk_modules.c b/drivers/nxp/clk/s32cc/s32cc_clk_modules.c
index 039db2a..c4c73c7 100644
--- a/drivers/nxp/clk/s32cc/s32cc_clk_modules.c
+++ b/drivers/nxp/clk/s32cc/s32cc_clk_modules.c
@@ -43,6 +43,45 @@
 static struct s32cc_clk arm_pll_phi0_clk =
 	S32CC_FREQ_MODULE_CLK(arm_pll_phi0_div, 0, GHZ);
 
+/* ARM DFS */
+static struct s32cc_dfs armdfs =
+	S32CC_DFS_INIT(armpll, S32CC_ARM_DFS);
+static struct s32cc_dfs_div arm_dfs1_div =
+	S32CC_DFS_DIV_INIT(armdfs, 0);
+static struct s32cc_clk arm_dfs1_clk =
+	S32CC_FREQ_MODULE_CLK(arm_dfs1_div, 0, 800 * MHZ);
+
+/* MC_CGM0 */
+static struct s32cc_clkmux cgm0_mux0 =
+	S32CC_SHARED_CLKMUX_INIT(S32CC_CGM0, 0, 2,
+				 S32CC_CLK_FIRC,
+				 S32CC_CLK_ARM_PLL_DFS1, 0, 0, 0);
+static struct s32cc_clk cgm0_mux0_clk = S32CC_MODULE_CLK(cgm0_mux0);
+
+/* XBAR */
+static struct s32cc_clk xbar_2x_clk =
+	S32CC_CHILD_CLK(cgm0_mux0_clk, 48 * MHZ, 800 * MHZ);
+static struct s32cc_fixed_div xbar_div2 =
+	S32CC_FIXED_DIV_INIT(cgm0_mux0_clk, 2);
+static struct s32cc_clk xbar_clk =
+	S32CC_FREQ_MODULE_CLK(xbar_div2, 24 * MHZ, 400 * MHZ);
+static struct s32cc_fixed_div xbar_div4 =
+	S32CC_FIXED_DIV_INIT(cgm0_mux0_clk, 4);
+static struct s32cc_clk xbar_div2_clk =
+	S32CC_FREQ_MODULE_CLK(xbar_div4, 12 * MHZ, 200 * MHZ);
+static struct s32cc_fixed_div xbar_div6 =
+	S32CC_FIXED_DIV_INIT(cgm0_mux0_clk, 6);
+static struct s32cc_clk xbar_div3_clk =
+	S32CC_FREQ_MODULE_CLK(xbar_div6, 8 * MHZ, 133333333);
+static struct s32cc_fixed_div xbar_div8 =
+	S32CC_FIXED_DIV_INIT(cgm0_mux0_clk, 8);
+static struct s32cc_clk xbar_div4_clk =
+	S32CC_FREQ_MODULE_CLK(xbar_div8, 6 * MHZ, 100 * MHZ);
+static struct s32cc_fixed_div xbar_div12 =
+	S32CC_FIXED_DIV_INIT(cgm0_mux0_clk, 12);
+static struct s32cc_clk xbar_div6_clk =
+	S32CC_FREQ_MODULE_CLK(xbar_div12, 4 * MHZ, 66666666);
+
 /* MC_CGM1 */
 static struct s32cc_clkmux cgm1_mux0 =
 	S32CC_SHARED_CLKMUX_INIT(S32CC_CGM1, 0, 3,
@@ -68,13 +107,15 @@
 	S32CC_FREQ_MODULE_CLK(a53_core_div10, S32CC_A53_MIN_FREQ / 10,
 			      S32CC_A53_MAX_FREQ / 10);
 
-static struct s32cc_clk *s32cc_hw_clk_list[5] = {
+static struct s32cc_clk *s32cc_hw_clk_list[13] = {
 	/* Oscillators */
 	[S32CC_CLK_ID(S32CC_CLK_FIRC)] = &firc_clk,
 	[S32CC_CLK_ID(S32CC_CLK_SIRC)] = &sirc_clk,
 	[S32CC_CLK_ID(S32CC_CLK_FXOSC)] = &fxosc_clk,
 	/* ARM PLL */
 	[S32CC_CLK_ID(S32CC_CLK_ARM_PLL_PHI0)] = &arm_pll_phi0_clk,
+	/* ARM DFS */
+	[S32CC_CLK_ID(S32CC_CLK_ARM_PLL_DFS1)] = &arm_dfs1_clk,
 };
 
 static struct s32cc_clk_array s32cc_hw_clocks = {
@@ -83,10 +124,19 @@
 	.n_clks = ARRAY_SIZE(s32cc_hw_clk_list),
 };
 
-static struct s32cc_clk *s32cc_arch_clk_list[6] = {
+static struct s32cc_clk *s32cc_arch_clk_list[13] = {
 	/* ARM PLL */
 	[S32CC_CLK_ID(S32CC_CLK_ARM_PLL_MUX)] = &arm_pll_mux_clk,
 	[S32CC_CLK_ID(S32CC_CLK_ARM_PLL_VCO)] = &arm_pll_vco_clk,
+	/* MC_CGM0 */
+	[S32CC_CLK_ID(S32CC_CLK_MC_CGM0_MUX0)] = &cgm0_mux0_clk,
+	/* XBAR */
+	[S32CC_CLK_ID(S32CC_CLK_XBAR_2X)] = &xbar_2x_clk,
+	[S32CC_CLK_ID(S32CC_CLK_XBAR)] = &xbar_clk,
+	[S32CC_CLK_ID(S32CC_CLK_XBAR_DIV2)] = &xbar_div2_clk,
+	[S32CC_CLK_ID(S32CC_CLK_XBAR_DIV3)] = &xbar_div3_clk,
+	[S32CC_CLK_ID(S32CC_CLK_XBAR_DIV4)] = &xbar_div4_clk,
+	[S32CC_CLK_ID(S32CC_CLK_XBAR_DIV6)] = &xbar_div6_clk,
 	/* MC_CGM1 */
 	[S32CC_CLK_ID(S32CC_CLK_MC_CGM1_MUX0)] = &cgm1_mux0_clk,
 	/* A53 */
diff --git a/drivers/nxp/clk/s32cc/s32cc_early_clks.c b/drivers/nxp/clk/s32cc/s32cc_early_clks.c
index 560f8bc..2c256a5 100644
--- a/drivers/nxp/clk/s32cc/s32cc_early_clks.c
+++ b/drivers/nxp/clk/s32cc/s32cc_early_clks.c
@@ -12,24 +12,30 @@
 #define S32CC_ARM_PLL_VCO_FREQ	(2U * GHZ)
 #define S32CC_ARM_PLL_PHI0_FREQ	(1U * GHZ)
 #define S32CC_A53_FREQ		(1U * GHZ)
+#define S32CC_XBAR_2X_FREQ	(800U * MHZ)
 
-int s32cc_init_early_clks(void)
+static int enable_fxosc_clk(void)
 {
 	int ret;
 
-	s32cc_clk_register_drv();
-
-	ret = clk_set_parent(S32CC_CLK_ARM_PLL_MUX, S32CC_CLK_FXOSC);
+	ret = clk_set_rate(S32CC_CLK_FXOSC, S32CC_FXOSC_FREQ, NULL);
 	if (ret != 0) {
 		return ret;
 	}
 
-	ret = clk_set_parent(S32CC_CLK_MC_CGM1_MUX0, S32CC_CLK_ARM_PLL_PHI0);
+	ret = clk_enable(S32CC_CLK_FXOSC);
 	if (ret != 0) {
 		return ret;
 	}
 
-	ret = clk_set_rate(S32CC_CLK_FXOSC, S32CC_FXOSC_FREQ, NULL);
+	return ret;
+}
+
+static int enable_arm_pll(void)
+{
+	int ret;
+
+	ret = clk_set_parent(S32CC_CLK_ARM_PLL_MUX, S32CC_CLK_FXOSC);
 	if (ret != 0) {
 		return ret;
 	}
@@ -44,22 +50,29 @@
 		return ret;
 	}
 
-	ret = clk_set_rate(S32CC_CLK_A53_CORE, S32CC_A53_FREQ, NULL);
+	ret = clk_enable(S32CC_CLK_ARM_PLL_VCO);
 	if (ret != 0) {
 		return ret;
 	}
 
-	ret = clk_enable(S32CC_CLK_FXOSC);
+	ret = clk_enable(S32CC_CLK_ARM_PLL_PHI0);
 	if (ret != 0) {
 		return ret;
 	}
 
-	ret = clk_enable(S32CC_CLK_ARM_PLL_VCO);
+	return ret;
+}
+
+static int enable_a53_clk(void)
+{
+	int ret;
+
+	ret = clk_set_parent(S32CC_CLK_MC_CGM1_MUX0, S32CC_CLK_ARM_PLL_PHI0);
 	if (ret != 0) {
 		return ret;
 	}
 
-	ret = clk_enable(S32CC_CLK_ARM_PLL_PHI0);
+	ret = clk_set_rate(S32CC_CLK_A53_CORE, S32CC_A53_FREQ, NULL);
 	if (ret != 0) {
 		return ret;
 	}
@@ -71,3 +84,59 @@
 
 	return ret;
 }
+
+static int enable_xbar_clk(void)
+{
+	int ret;
+
+	ret = clk_set_parent(S32CC_CLK_MC_CGM0_MUX0, S32CC_CLK_ARM_PLL_DFS1);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = clk_set_rate(S32CC_CLK_XBAR_2X, S32CC_XBAR_2X_FREQ, NULL);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = clk_enable(S32CC_CLK_ARM_PLL_DFS1);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = clk_enable(S32CC_CLK_XBAR_2X);
+	if (ret != 0) {
+		return ret;
+	}
+
+	return ret;
+}
+
+int s32cc_init_early_clks(void)
+{
+	int ret;
+
+	s32cc_clk_register_drv();
+
+	ret = enable_fxosc_clk();
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = enable_arm_pll();
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = enable_a53_clk();
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = enable_xbar_clk();
+	if (ret != 0) {
+		return ret;
+	}
+
+	return ret;
+}
diff --git a/include/drivers/arm/gicv3.h b/include/drivers/arm/gicv3.h
index bfda31b..ca46eb1 100644
--- a/include/drivers/arm/gicv3.h
+++ b/include/drivers/arm/gicv3.h
@@ -150,6 +150,7 @@
 /* GICD_TYPER shifts and masks */
 #define	TYPER_ESPI		U(1 << 8)
 #define	TYPER_DVIS		U(1 << 18)
+#define	TYPER_LPIS		U(1 << 17)
 #define	TYPER_ESPI_RANGE_MASK	U(0x1f)
 #define	TYPER_ESPI_RANGE_SHIFT	U(27)
 #define	TYPER_ESPI_RANGE	U(TYPER_ESPI_MASK << TYPER_ESPI_SHIFT)
diff --git a/include/drivers/nxp/clk/s32cc/s32cc-clk-ids.h b/include/drivers/nxp/clk/s32cc/s32cc-clk-ids.h
index 633f173..b95cd32 100644
--- a/include/drivers/nxp/clk/s32cc/s32cc-clk-ids.h
+++ b/include/drivers/nxp/clk/s32cc/s32cc-clk-ids.h
@@ -78,4 +78,13 @@
 #define S32CC_CLK_A53_CORE_DIV2			S32CC_ARCH_CLK(4)
 #define S32CC_CLK_A53_CORE_DIV10		S32CC_ARCH_CLK(5)
 
+/* XBAR clock*/
+#define S32CC_CLK_MC_CGM0_MUX0			S32CC_ARCH_CLK(6)
+#define S32CC_CLK_XBAR_2X			S32CC_ARCH_CLK(7)
+#define S32CC_CLK_XBAR				S32CC_ARCH_CLK(8)
+#define S32CC_CLK_XBAR_DIV2			S32CC_ARCH_CLK(9)
+#define S32CC_CLK_XBAR_DIV3			S32CC_ARCH_CLK(10)
+#define S32CC_CLK_XBAR_DIV4			S32CC_ARCH_CLK(11)
+#define S32CC_CLK_XBAR_DIV6			S32CC_ARCH_CLK(12)
+
 #endif /* S32CC_CLK_IDS_H */
diff --git a/include/drivers/nxp/clk/s32cc/s32cc-clk-modules.h b/include/drivers/nxp/clk/s32cc/s32cc-clk-modules.h
index 41fc6f4..703713b 100644
--- a/include/drivers/nxp/clk/s32cc/s32cc-clk-modules.h
+++ b/include/drivers/nxp/clk/s32cc/s32cc-clk-modules.h
@@ -17,6 +17,8 @@
 	s32cc_clk_t,
 	s32cc_pll_t,
 	s32cc_pll_out_div_t,
+	s32cc_dfs_t,
+	s32cc_dfs_div_t,
 	s32cc_clkmux_t,
 	s32cc_shared_clkmux_t,
 	s32cc_fixed_div_t,
@@ -27,6 +29,8 @@
 	S32CC_FXOSC,
 	S32CC_SIRC,
 	S32CC_ARM_PLL,
+	S32CC_ARM_DFS,
+	S32CC_CGM0,
 	S32CC_CGM1,
 };
 
@@ -122,6 +126,38 @@
 	.index = (INDEX),                      \
 }
 
+struct s32cc_dfs {
+	struct s32cc_clk_obj desc;
+	struct s32cc_clk_obj *parent;
+	enum s32cc_clk_source instance;
+	uintptr_t base;
+};
+
+#define S32CC_DFS_INIT(PARENT, INSTANCE) \
+{                                        \
+	.desc = {                        \
+		.type = s32cc_dfs_t,     \
+	},                               \
+	.parent = &(PARENT).desc,        \
+	.instance = (INSTANCE),          \
+}
+
+struct s32cc_dfs_div {
+	struct s32cc_clk_obj desc;
+	struct s32cc_clk_obj *parent;
+	uint32_t index;
+	unsigned long freq;
+};
+
+#define S32CC_DFS_DIV_INIT(PARENT, INDEX) \
+{                                         \
+	.desc = {                         \
+		.type = s32cc_dfs_div_t,  \
+	},                                \
+	.parent = &(PARENT).desc,         \
+	.index = (INDEX),                 \
+}
+
 struct s32cc_fixed_div {
 	struct s32cc_clk_obj desc;
 	struct s32cc_clk_obj *parent;
@@ -151,22 +187,26 @@
 	size_t n_clks;
 };
 
-#define S32CC_FREQ_MODULE(PARENT_MODULE, MIN_F, MAX_F) \
-{                                                      \
-	.desc = {                                      \
-		.type = s32cc_clk_t,                   \
-	},                                             \
-	.module = &(PARENT_MODULE).desc,               \
-	.min_freq = (MIN_F),                           \
-	.max_freq = (MAX_F),                           \
+#define S32CC_FREQ_CLK(PARENT_MODULE, PARENT, MIN_F, MAX_F) \
+{                                                           \
+	.desc = {                                           \
+		.type = s32cc_clk_t,                        \
+	},                                                  \
+	.pclock = (PARENT),                                 \
+	.module = (PARENT_MODULE),                          \
+	.min_freq = (MIN_F),                                \
+	.max_freq = (MAX_F),                                \
 }
 
 #define S32CC_FREQ_MODULE_CLK(PARENT_MODULE, MIN_F, MAX_F) \
-	S32CC_FREQ_MODULE(PARENT_MODULE, MIN_F, MAX_F)
+	S32CC_FREQ_CLK(&(PARENT_MODULE).desc, NULL, MIN_F, MAX_F)
 
 #define S32CC_MODULE_CLK(PARENT_MODULE) \
 	S32CC_FREQ_MODULE_CLK(PARENT_MODULE, 0, 0)
 
+#define S32CC_CHILD_CLK(PARENT, MIN_F, MAX_F) \
+	S32CC_FREQ_CLK(NULL, &(PARENT), MIN_F, MAX_F)
+
 static inline struct s32cc_osc *s32cc_obj2osc(const struct s32cc_clk_obj *mod)
 {
 	uintptr_t osc_addr;
@@ -237,4 +277,20 @@
 	return (struct s32cc_fixed_div *)fdiv_addr;
 }
 
+static inline struct s32cc_dfs *s32cc_obj2dfs(const struct s32cc_clk_obj *mod)
+{
+	uintptr_t dfs_addr;
+
+	dfs_addr = ((uintptr_t)mod) - offsetof(struct s32cc_dfs, desc);
+	return (struct s32cc_dfs *)dfs_addr;
+}
+
+static inline struct s32cc_dfs_div *s32cc_obj2dfsdiv(const struct s32cc_clk_obj *mod)
+{
+	uintptr_t dfs_div_addr;
+
+	dfs_div_addr = ((uintptr_t)mod) - offsetof(struct s32cc_dfs_div, desc);
+	return (struct s32cc_dfs_div *)dfs_div_addr;
+}
+
 #endif /* S32CC_CLK_MODULES_H */
diff --git a/lib/psci/psci_common.c b/lib/psci/psci_common.c
index 9f0b190..375cdba 100644
--- a/lib/psci/psci_common.c
+++ b/lib/psci/psci_common.c
@@ -182,9 +182,9 @@
 	}
 
 	my_idx = plat_my_core_pos();
-
-	for (lvl = PSCI_CPU_PWR_LVL; lvl <= end_pwrlvl; lvl++) {
-		parent_idx = psci_cpu_pd_nodes[my_idx].parent_node;
+	parent_idx = psci_cpu_pd_nodes[my_idx].parent_node;
+	for (lvl = PSCI_CPU_PWR_LVL + U(1); lvl < end_pwrlvl; lvl++) {
+		parent_idx = psci_non_cpu_pd_nodes[parent_idx].parent_node;
 	}
 
 	cpu_start_idx = psci_non_cpu_pd_nodes[parent_idx].cpu_start_idx;
diff --git a/plat/amd/versal2/include/def.h b/plat/amd/versal2/include/def.h
index a8cbaaf..67244a4 100644
--- a/plat/amd/versal2/include/def.h
+++ b/plat/amd/versal2/include/def.h
@@ -125,6 +125,10 @@
 #define APU_CLUSTER_STEP	U(0x100000)
 
 #define SLCR_OSPI_QSPI_IOU_AXI_MUX_SEL	U(0xF1060504)
+#define PMXC_IOU_SLCR_SRAM_CSR	U(0xF106104C)
+#define PMXC_IOU_SLCR_PHY_RESET	U(0xF1061050)
+#define PMXC_IOU_SLCR_TX_RX_CONFIG_RDY	U(0xF1061054)
+#define PMXC_CRP_RST_UFS	U(0xF1260340)
 
 /*******************************************************************************
  * IRQ constants
diff --git a/plat/amd/versal2/include/versal2-scmi.h b/plat/amd/versal2/include/versal2-scmi.h
index 4d581e4..c08b4b1 100644
--- a/plat/amd/versal2/include/versal2-scmi.h
+++ b/plat/amd/versal2/include/versal2-scmi.h
@@ -136,5 +136,9 @@
 #define RESET_I3C6_0	32
 #define RESET_I3C7_0	33
 #define RESET_I3C8_0	34
+#define RESET_UFSPHY_0  35
+
+#define PD_USB0		0
+#define PD_USB1		1
 
 #endif /* _VERSAL2_SCMI_H */
diff --git a/plat/amd/versal2/plat_psci.c b/plat/amd/versal2/plat_psci.c
index 4faa434..6f0cbcb 100644
--- a/plat/amd/versal2/plat_psci.c
+++ b/plat/amd/versal2/plat_psci.c
@@ -161,12 +161,29 @@
 static int32_t no_pm_ioctl(uint32_t device_id, uint32_t ioctl_id,
 			   uint32_t arg1, uint32_t arg2)
 {
+	int32_t ret = 0;
 	VERBOSE("%s: ioctl_id: %x, arg1: %x\n", __func__, ioctl_id, arg1);
-	if (ioctl_id == IOCTL_OSPI_MUX_SELECT) {
+
+	switch (ioctl_id) {
+	case IOCTL_OSPI_MUX_SELECT:
 		mmio_write_32(SLCR_OSPI_QSPI_IOU_AXI_MUX_SEL, arg1);
-		return 0;
+		break;
+	case IOCTL_UFS_TXRX_CFGRDY_GET:
+		ret = (int32_t) mmio_read_32(PMXC_IOU_SLCR_TX_RX_CONFIG_RDY);
+		break;
+	case IOCTL_UFS_SRAM_CSR_SEL:
+		if (arg1 == 1) {
+			ret = (int32_t) mmio_read_32(PMXC_IOU_SLCR_SRAM_CSR);
+		} else if (arg1 == 0) {
+			mmio_write_32(PMXC_IOU_SLCR_SRAM_CSR, arg2);
+		}
+		break;
+	default:
+		ret = PM_RET_ERROR_NOFEATURE;
+		break;
 	}
-	return PM_RET_ERROR_NOFEATURE;
+
+	return ret;
 }
 
 static uint64_t no_pm_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
@@ -187,7 +204,13 @@
 	case PM_IOCTL:
 	{
 		ret = no_pm_ioctl(arg[0], arg[1], arg[2], arg[3]);
-		SMC_RET1(handle, (uint64_t)ret);
+		/* Firmware driver expects return code in upper 32 bits and
+		 * status in lower 32 bits.
+		 * status is always SUCCESS(0) for mmio low level register
+		 * r/w calls and return value is the value returned from
+		 * no_pm_ioctl
+		 */
+		SMC_RET1(handle, ((uint64_t)ret << 32));
 	}
 	case PM_GET_CHIPID:
 	{
diff --git a/plat/amd/versal2/scmi.c b/plat/amd/versal2/scmi.c
index c3c517a..7f4b6df 100644
--- a/plat/amd/versal2/scmi.c
+++ b/plat/amd/versal2/scmi.c
@@ -10,6 +10,7 @@
 
 #include <drivers/scmi-msg.h>
 #include <drivers/scmi.h>
+#include <lib/mmio.h>
 #include <lib/utils_def.h>
 #include <platform_def.h>
 #include <scmi.h>
@@ -179,14 +180,40 @@
 	RESET_CELL(RESET_I3C6_0, RESET_I3C6_0, "i3c6"),
 	RESET_CELL(RESET_I3C7_0, RESET_I3C7_0, "i3c7"),
 	RESET_CELL(RESET_I3C8_0, RESET_I3C8_0, "i3c8"),
+	RESET_CELL(RESET_UFSPHY_0, RESET_UFSPHY_0, "ufsphy0"),
 };
 
+/**
+ * struct scmi_pd - Data for the exposed power domain controller
+ * @pd_id: pd identifier in RCC reset driver
+ * @name: pd string ID exposed to agent
+ * @state: keep state setting
+ */
+struct scmi_pd {
+	unsigned long pd_id;
+	const char *name;
+	unsigned int state;
+};
+
+#define PD_CELL(_scmi_id, _id, _name, _state) \
+	[_scmi_id] = { \
+		.pd_id = _id, \
+		.name = _name, \
+		.state = _state, \
+	}
+
+static struct scmi_pd scmi0_pd[] = {
+	PD_CELL(PD_USB0, PD_USB0, "usb0", 0),
+	PD_CELL(PD_USB1, PD_USB1, "usb1", 0),
+};
+
 struct scmi_resources {
 	struct scmi_clk *clock;
 	size_t clock_count;
 	struct scmi_reset *reset;
 	size_t reset_count;
-
+	struct scmi_pd *pd;
+	size_t pd_count;
 };
 
 static const struct scmi_resources resources[] = {
@@ -195,6 +222,8 @@
 		.clock_count = ARRAY_SIZE(scmi0_clock),
 		.reset = scmi0_reset,
 		.reset_count = ARRAY_SIZE(scmi0_reset),
+		.pd = scmi0_pd,
+		.pd_count = ARRAY_SIZE(scmi0_pd),
 	},
 };
 
@@ -433,14 +462,122 @@
 	if (assert_not_deassert) {
 		NOTICE("SCMI reset %lu/%s set\n",
 		       reset->reset_id, plat_scmi_rstd_get_name(agent_id, scmi_id));
+
+		switch (scmi_id) {
+		case RESET_UFS0_0:
+			mmio_write_32(PMXC_CRP_RST_UFS, 1);
+			break;
+		case RESET_UFSPHY_0:
+			mmio_write_32(PMXC_IOU_SLCR_PHY_RESET, 1);
+			break;
+		default:
+			break;
+		}
 	} else {
 		NOTICE("SCMI reset %lu/%s release\n",
 		       reset->reset_id, plat_scmi_rstd_get_name(agent_id, scmi_id));
+
+		switch (scmi_id) {
+		case RESET_UFS0_0:
+			mmio_write_32(PMXC_CRP_RST_UFS, 0);
+			break;
+		case RESET_UFSPHY_0:
+			mmio_write_32(PMXC_IOU_SLCR_PHY_RESET, 0);
+			break;
+		default:
+			break;
+		}
 	}
 
 	return SCMI_SUCCESS;
 }
 
+/*
+ * Platform SCMI reset domains
+ */
+static struct scmi_pd *find_pd(unsigned int agent_id, unsigned int pd_id)
+{
+	const struct scmi_resources *resource = find_resource(agent_id);
+	size_t n;
+
+	if (resource != NULL) {
+		for (n = 0U; n < resource->pd_count; n++) {
+			if (n == pd_id) {
+				return &resource->pd[n];
+			}
+		}
+	}
+
+	return NULL;
+}
+
+size_t plat_scmi_pd_count(unsigned int agent_id)
+{
+	const struct scmi_resources *resource = find_resource(agent_id);
+	size_t ret;
+
+	if (resource == NULL) {
+		ret = 0U;
+	} else {
+		ret = resource->pd_count;
+
+		NOTICE("SCMI: PD: %d\n", (unsigned int)ret);
+	}
+	return ret;
+}
+
+const char *plat_scmi_pd_get_name(unsigned int agent_id, unsigned int pd_id)
+{
+	const struct scmi_pd *pd = find_pd(agent_id, pd_id);
+
+	if (pd == NULL) {
+		return NULL;
+	}
+
+	return pd->name;
+}
+
+unsigned int plat_scmi_pd_statistics(unsigned int agent_id, unsigned long *pd_id)
+{
+	return 0U;
+}
+
+unsigned int plat_scmi_pd_get_attributes(unsigned int agent_id, unsigned int pd_id)
+{
+	return 0U;
+}
+
+unsigned int plat_scmi_pd_get_state(unsigned int agent_id, unsigned int pd_id)
+{
+	const struct scmi_pd *pd = find_pd(agent_id, pd_id);
+
+	if (pd == NULL) {
+		return SCMI_NOT_SUPPORTED;
+	}
+
+	NOTICE("SCMI: PD: get id: %d, state: %x\n", pd_id, pd->state);
+
+	return pd->state;
+}
+
+int32_t plat_scmi_pd_set_state(unsigned int agent_id, unsigned int flags, unsigned int pd_id,
+			       unsigned int state)
+{
+	struct scmi_pd *pd = find_pd(agent_id, pd_id);
+
+	if (pd == NULL) {
+		return SCMI_NOT_SUPPORTED;
+	}
+
+	NOTICE("SCMI: PD: set id: %d, orig state: %x, new state: %x,  flags: %x\n",
+	       pd_id, pd->state, state, flags);
+
+	pd->state = state;
+
+	return 0U;
+}
+
+
 /* Currently only one channel is supported. Expectation is that channel 0 is used by NS SW */
 static struct scmi_msg_channel scmi_channel[] = {
 	[0] = {
@@ -475,10 +612,8 @@
 	SCMI_PROTOCOL_ID_BASE,
 	SCMI_PROTOCOL_ID_CLOCK,
 	SCMI_PROTOCOL_ID_RESET_DOMAIN,
-	/*
-	 *SCMI_PROTOCOL_ID_POWER_DOMAIN,
-	 *SCMI_PROTOCOL_ID_SENSOR,
-	 */
+	SCMI_PROTOCOL_ID_POWER_DOMAIN,
+	/* SCMI_PROTOCOL_ID_SENSOR, */
 	0U /* Null termination */
 };
 
diff --git a/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts
index 9fba4af..bf0e7f3 100644
--- a/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts
+++ b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts
@@ -99,12 +99,17 @@
 
 	memory@2 {
 		device_type = "device-memory";
-		reg = <0x0 0x1c090000 0x0 0x40000>, /* UART */
+		reg = <0x0 0x1c0b0000 0x0 0x20000>, /* UART 2-3 */
 		      <0x0 0x2bfe0000 0x0 0x20000>, /* SMMUv3TestEngine */
 		      <0x0 0x2a490000 0x0 0x20000>, /* SP805 Trusted Watchdog */
 		      <0x0 0x1c130000 0x0 0x10000>; /* Virtio block device */
 	};
 
+	memory@3 {
+		device_type = "ns-device-memory";
+		reg = <0x0 0x1c090000 0x0 0x20000>; /* UART 0-1 */
+	};
+
 
 #if MEASURED_BOOT
 #include "event_log.dtsi"
diff --git a/plat/xilinx/common/include/pm_api_sys.h b/plat/xilinx/common/include/pm_api_sys.h
index ffee805..029bb43 100644
--- a/plat/xilinx/common/include/pm_api_sys.h
+++ b/plat/xilinx/common/include/pm_api_sys.h
@@ -64,6 +64,7 @@
 					uint32_t wake, uint32_t enable,
 					uint32_t flag);
 enum pm_ret_status pm_get_chipid(uint32_t *value);
+enum pm_ret_status eemi_feature_check(uint32_t api_id, uint32_t *ret_payload);
 
 /*
  * Assigning of argument values into array elements.
@@ -97,4 +98,9 @@
 	PM_PACK_PAYLOAD5(pl, (mid), (flag), (arg0), (arg1), (arg2), (arg3), (arg4));		\
 }
 
+#define PM_PACK_PAYLOAD7(pl, mid, flag, arg0, arg1, arg2, arg3, arg4, arg5, arg6) {	\
+	pl[6] = (uint32_t)(arg6);							\
+	PM_PACK_PAYLOAD6(pl, (mid), (flag), (arg0), (arg1), (arg2), (arg3), (arg4), (arg5));	\
+}
+
 #endif /* PM_API_SYS_H */
diff --git a/plat/xilinx/common/include/pm_common.h b/plat/xilinx/common/include/pm_common.h
index c0308ab..c38cdef 100644
--- a/plat/xilinx/common/include/pm_common.h
+++ b/plat/xilinx/common/include/pm_common.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2013-2018, Arm Limited and Contributors. All rights reserved.
- * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -18,13 +18,15 @@
 
 #if IPI_CRC_CHECK
 #define PAYLOAD_ARG_CNT         8U
+#define RET_PAYLOAD_ARG_CNT	7U
 #define IPI_W0_TO_W6_SIZE       28U
 #define PAYLOAD_CRC_POS         7U
 #define CRC_INIT_VALUE          0x4F4EU
 #define CRC_ORDER               16U
 #define CRC_POLYNOM             0x8005U
 #else
-#define PAYLOAD_ARG_CNT         6U
+#define PAYLOAD_ARG_CNT		7U
+#define RET_PAYLOAD_ARG_CNT	6U
 #endif
 #define PAYLOAD_ARG_SIZE	4U	/* size in bytes */
 
diff --git a/plat/xilinx/common/include/pm_defs.h b/plat/xilinx/common/include/pm_defs.h
index 055fa3d..9920611 100644
--- a/plat/xilinx/common/include/pm_defs.h
+++ b/plat/xilinx/common/include/pm_defs.h
@@ -35,6 +35,7 @@
 				       (uint32_t)XPM_NODESUBCL_DEV_PERIPH, \
 				       (uint32_t)XPM_NODETYPE_DEV_PERIPH, (IDX))
 
+#define TF_A_FEATURE_CHECK		0xa00U
 #define PM_GET_CALLBACK_DATA		0xa01U
 #define PM_GET_TRUSTZONE_VERSION	0xa03U
 #define TF_A_PM_REGISTER_SGI		0xa04U
@@ -95,6 +96,8 @@
 	IOCTL_GET_LAST_RESET_REASON = 23,
 	/* AI engine NPI ISR clear */
 	IOCTL_AIE_ISR_CLEAR = 24,
+	IOCTL_UFS_TXRX_CFGRDY_GET = 40,
+	IOCTL_UFS_SRAM_CSR_SEL = 41,
 };
 
 /**
diff --git a/plat/xilinx/common/include/pm_svc_main.h b/plat/xilinx/common/include/pm_svc_main.h
index 67fbeae..000f198 100644
--- a/plat/xilinx/common/include/pm_svc_main.h
+++ b/plat/xilinx/common/include/pm_svc_main.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
- * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -12,6 +12,8 @@
 
 extern bool pwrdwn_req_received;
 
+#define PASS_THROUGH_FW_CMD_ID	U(0xfff)
+
 /******************************************************************************/
 /**
  * SECURE_REDUNDANT_CALL() - Adds redundancy to the function call. This is to
diff --git a/plat/xilinx/common/pm_service/pm_api_sys.c b/plat/xilinx/common/pm_service/pm_api_sys.c
index 0a6e810..e9c5f13 100644
--- a/plat/xilinx/common/pm_service/pm_api_sys.c
+++ b/plat/xilinx/common/pm_service/pm_api_sys.c
@@ -122,7 +122,7 @@
 	}
 
 	PM_PACK_PAYLOAD6(payload, module_id, flag, x0, x1, x2, x3, x4, x5);
-	return pm_ipi_send_sync(primary_proc, payload, (uint32_t *)result, PAYLOAD_ARG_CNT);
+	return pm_ipi_send_sync(primary_proc, payload, (uint32_t *)result, RET_PAYLOAD_ARG_CNT);
 }
 
 /**
@@ -364,6 +364,37 @@
 }
 
 /**
+ * eemi_feature_check() - Returns the supported API version if supported.
+ * @api_id: API ID to check.
+ * @ret_payload: pointer to array of PAYLOAD_ARG_CNT number of
+ *               words Returned supported API version
+ *
+ * Return: Returns status, either success or error+reason.
+ */
+enum pm_ret_status eemi_feature_check(uint32_t api_id, uint32_t *ret_payload)
+{
+	enum pm_ret_status ret;
+
+	/* Return version of API which are implemented in TF-A only */
+	switch (api_id) {
+	case PM_GET_CALLBACK_DATA:
+	case PM_GET_TRUSTZONE_VERSION:
+		ret_payload[0] = PM_API_VERSION_2;
+		ret = PM_RET_SUCCESS;
+		break;
+	case TF_A_PM_REGISTER_SGI:
+	case TF_A_FEATURE_CHECK:
+		ret_payload[0] = PM_API_BASE_VERSION;
+		ret = PM_RET_SUCCESS;
+		break;
+	default:
+		ret = PM_RET_ERROR_NO_FEATURE;
+	}
+
+	return ret;
+}
+
+/**
  * pm_feature_check() - Returns the supported API version if supported.
  * @api_id: API ID to check.
  * @flag: 0 - Call from secure source.
@@ -406,7 +437,7 @@
 
 	PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag,
 			 PM_FEATURE_CHECK, api_id);
-	return pm_ipi_send_sync(primary_proc, payload, ret_payload, PAYLOAD_ARG_CNT);
+	return pm_ipi_send_sync(primary_proc, payload, ret_payload, RET_PAYLOAD_ARG_CNT);
 }
 
 /**
diff --git a/plat/xilinx/common/pm_service/pm_ipi.c b/plat/xilinx/common/pm_service/pm_ipi.c
index 56567dd..205877c 100644
--- a/plat/xilinx/common/pm_service/pm_ipi.c
+++ b/plat/xilinx/common/pm_service/pm_ipi.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2013-2020, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
- * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -164,15 +164,10 @@
  *
  */
 static enum pm_ret_status pm_ipi_buff_read(const struct pm_proc *proc,
-					   uint32_t *value, size_t count)
+					   uint32_t value[PAYLOAD_ARG_CNT])
 {
 	size_t i;
 	enum pm_ret_status ret;
-#if IPI_CRC_CHECK
-	uint32_t *payload_ptr = value;
-	size_t j;
-	uint32_t response_payload[PAYLOAD_ARG_CNT];
-#endif
 	uintptr_t buffer_base = proc->ipi->buffer_base +
 				IPI_BUFFER_TARGET_REMOTE_OFFSET +
 				IPI_BUFFER_RESP_OFFSET;
@@ -184,27 +179,21 @@
 	 * buf-2: unused
 	 * buf-3: unused
 	 */
-	for (i = 1; i <= count; i++) {
-		*value = mmio_read_32(buffer_base + (i * PAYLOAD_ARG_SIZE));
-		value++;
+	for (i = 0; i < PAYLOAD_ARG_CNT; i++) {
+		value[i] = mmio_read_32(buffer_base + (i * PAYLOAD_ARG_SIZE));
 	}
 
-	ret = mmio_read_32(buffer_base);
+	ret = value[0];
 #if IPI_CRC_CHECK
-	for (j = 0; j < PAYLOAD_ARG_CNT; j++) {
-		response_payload[j] = mmio_read_32(buffer_base +
-						(j * PAYLOAD_ARG_SIZE));
-	}
-
-	if (response_payload[PAYLOAD_CRC_POS] !=
-			calculate_crc(response_payload, IPI_W0_TO_W6_SIZE)) {
+	if (value[PAYLOAD_CRC_POS] !=
+			calculate_crc(value, IPI_W0_TO_W6_SIZE)) {
 		NOTICE("ERROR in CRC response payload value:0x%x\n",
-					response_payload[PAYLOAD_CRC_POS]);
+					value[PAYLOAD_CRC_POS]);
 		ret = PM_RET_ERROR_INVALID_CRC;
 		/* Payload data is invalid as CRC validation failed
 		 * Clear the payload to avoid leakage of data to upper layers
 		 */
-		memset(payload_ptr, 0, count);
+		memset(value, 0, PAYLOAD_ARG_CNT);
 	}
 #endif
 
@@ -240,7 +229,7 @@
 		count = IPI_BUFFER_MAX_WORDS;
 	}
 
-	for (i = 0; i <= count; i++) {
+	for (i = 0; i < count; i++) {
 		*value = mmio_read_32(buffer_base + (i * PAYLOAD_ARG_SIZE));
 		value++;
 	}
@@ -282,6 +271,7 @@
 				    uint32_t *value, size_t count)
 {
 	enum pm_ret_status ret;
+	uint32_t i, ret_payload[PAYLOAD_ARG_CNT] = {0U};
 
 	pm_ipi_lock_get();
 
@@ -290,7 +280,12 @@
 		goto unlock;
 	}
 
+	ret = ERROR_CODE_MASK & (pm_ipi_buff_read(proc, ret_payload));
+
-	ret = ERROR_CODE_MASK & (pm_ipi_buff_read(proc, value, count));
+	for (i = 1U; i <= count; i++) {
+		*value = ret_payload[i];
+		value++;
+	}
 
 unlock:
 	pm_ipi_lock_release();
diff --git a/plat/xilinx/common/pm_service/pm_svc_main.c b/plat/xilinx/common/pm_service/pm_svc_main.c
index 7ac0ac1..b431a6c 100644
--- a/plat/xilinx/common/pm_service/pm_svc_main.c
+++ b/plat/xilinx/common/pm_service/pm_svc_main.c
@@ -36,6 +36,32 @@
 #define EVENT_CPU_PWRDWN	(4U)
 #define MBOX_SGI_SHARED_IPI	(7U)
 
+/**
+ * upper_32_bits - return bits 32-63 of a number
+ * @n: the number we're accessing
+ */
+#define upper_32_bits(n)	((uint32_t)((n) >> 32U))
+
+/**
+ * lower_32_bits - return bits 0-31 of a number
+ * @n: the number we're accessing
+ */
+#define lower_32_bits(n)	((uint32_t)((n) & 0xffffffffU))
+
+/**
+ * EXTRACT_SMC_ARGS - extracts 32-bit payloads from 64-bit SMC arguments
+ * @pm_arg: array of 32-bit payloads
+ * @x: array of 64-bit SMC arguments
+ */
+#define EXTRACT_ARGS(pm_arg, x)						\
+	for (uint32_t i = 0U; i < (PAYLOAD_ARG_CNT - 1U); i++) {	\
+		if ((i % 2U) != 0U) {					\
+			pm_arg[i] = lower_32_bits(x[(i / 2U) + 1U]);	\
+		} else {						\
+			pm_arg[i] = upper_32_bits(x[i / 2U]);		\
+		}							\
+	}
+
 /* 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)
@@ -278,7 +304,7 @@
 
 	case (uint32_t)PM_FEATURE_CHECK:
 	{
-		uint32_t result[PAYLOAD_ARG_CNT] = {0U};
+		uint32_t result[RET_PAYLOAD_ARG_CNT] = {0U};
 
 		ret = pm_feature_check(pm_arg[0], result, security_flag);
 		SMC_RET2(handle, (uint64_t)ret | ((uint64_t)result[0] << 32U),
@@ -367,6 +393,15 @@
 {
 	switch (api_id) {
 
+	case TF_A_FEATURE_CHECK:
+	{
+		enum pm_ret_status ret;
+		uint32_t result[PAYLOAD_ARG_CNT] = {0U};
+
+		ret = eemi_feature_check(pm_arg[0], result);
+		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)result[0] << 32U));
+	}
+
 	case TF_A_PM_REGISTER_SGI:
 	{
 		int32_t ret;
@@ -424,7 +459,7 @@
 			      void *handle, uint32_t security_flag)
 {
 	enum pm_ret_status ret;
-	uint32_t buf[PAYLOAD_ARG_CNT] = {0};
+	uint32_t buf[RET_PAYLOAD_ARG_CNT] = {0};
 
 	ret = pm_handle_eemi_call(security_flag, api_id, pm_arg[0], pm_arg[1],
 				  pm_arg[2], pm_arg[3], pm_arg[4],
@@ -449,6 +484,45 @@
 }
 
 /**
+ * eemi_api_handler() - Prepare EEMI payload and perform IPI transaction.
+ * @api_id: identifier for the API being called.
+ * @pm_arg: pointer to the argument data for the API call.
+ * @handle: Pointer to caller's context structure.
+ * @security_flag: SECURE_FLAG or NON_SECURE_FLAG.
+ *
+ * EEMI - Embedded Energy Management Interface is AMD-Xilinx proprietary
+ * protocol to allow communication between power management controller and
+ * different processing clusters.
+ *
+ * This handler prepares EEMI protocol payload received from kernel and performs
+ * IPI transaction.
+ *
+ * Return: If EEMI API found then, uintptr_t type address, else 0
+ */
+static uintptr_t eemi_api_handler(uint32_t api_id, const uint32_t *pm_arg,
+				  void *handle, uint32_t security_flag)
+{
+	enum pm_ret_status ret;
+	uint32_t buf[PAYLOAD_ARG_CNT] = {0};
+	uint32_t payload[PAYLOAD_ARG_CNT] = {0};
+	uint32_t module_id;
+
+	module_id = (api_id & MODULE_ID_MASK) >> 8U;
+
+	PM_PACK_PAYLOAD7(payload, module_id, security_flag, api_id,
+			 pm_arg[0], pm_arg[1], pm_arg[2], pm_arg[3],
+			 pm_arg[4], pm_arg[5]);
+
+	ret = pm_ipi_send_sync(primary_proc, payload, (uint32_t *)buf,
+			       PAYLOAD_ARG_CNT);
+
+	SMC_RET4(handle, (uint64_t)ret | ((uint64_t)buf[0] << 32U),
+		 (uint64_t)buf[1] | ((uint64_t)buf[2] << 32U),
+		 (uint64_t)buf[3] | ((uint64_t)buf[4] << 32U),
+		 (uint64_t)buf[5]);
+}
+
+/**
  * pm_smc_handler() - SMC handler for PM-API calls coming from EL1/EL2.
  * @smc_fid: Function Identifier.
  * @x1: SMC64 Arguments from kernel.
@@ -477,6 +551,7 @@
 	uint32_t security_flag = NON_SECURE_FLAG;
 	uint32_t api_id;
 	bool status = false, status_tmp = false;
+	uint64_t x[4] = {x1, x2, x3, x4};
 
 	/* Handle case where PM wasn't initialized properly */
 	if (pm_up == false) {
@@ -494,6 +569,14 @@
 		security_flag = SECURE_FLAG;
 	}
 
+	if ((smc_fid & FUNCID_NUM_MASK) == PASS_THROUGH_FW_CMD_ID) {
+		api_id = lower_32_bits(x[0]);
+
+		EXTRACT_ARGS(pm_arg, x);
+
+		return eemi_api_handler(api_id, pm_arg, handle, security_flag);
+	}
+
 	pm_arg[0] = (uint32_t)x1;
 	pm_arg[1] = (uint32_t)(x1 >> 32U);
 	pm_arg[2] = (uint32_t)x2;
diff --git a/plat/xilinx/versal/aarch64/versal_common.c b/plat/xilinx/versal/aarch64/versal_common.c
index 772477f..9e8134a 100644
--- a/plat/xilinx/versal/aarch64/versal_common.c
+++ b/plat/xilinx/versal/aarch64/versal_common.c
@@ -1,12 +1,11 @@
 /*
  * Copyright (c) 2018-2020, Arm Limited and Contributors. All rights reserved.
- * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <common/debug.h>
-#include <drivers/generic_delay_timer.h>
 #include <lib/mmio.h>
 #include <lib/xlat_tables/xlat_tables_v2.h>
 #include <plat/common/platform.h>
@@ -18,7 +17,7 @@
 #include <versal_def.h>
 
 uint32_t platform_id, platform_version;
-uint32_t cpu_clock = VERSAL_CPU_CLOCK;
+uint32_t cpu_clock;
 
 /*
  * Table of regions to map using the MMU.
@@ -39,19 +38,10 @@
 	return plat_versal_mmap;
 }
 
-static void versal_print_platform_name(void)
-{
-	NOTICE("TF-A running on %s\n", PLATFORM_NAME);
-}
-
 void versal_config_setup(void)
 {
 	/* Configure IPI data for versal */
 	versal_ipi_config_table_init();
-
-	versal_print_platform_name();
-
-	generic_delay_timer_init();
 }
 
 void board_detection(void)
@@ -70,7 +60,50 @@
 	platform_version = FIELD_GET(PLATFORM_VERSION_MASK, plat_info[1]);
 }
 
+const char *board_name_decode(void)
+{
+	const char *platform;
+
+	switch (platform_id) {
+	case VERSAL_SPP:
+		platform = "IPP";
+		break;
+	case VERSAL_EMU:
+		platform = "EMU";
+		break;
+	case VERSAL_QEMU:
+		platform = "QEMU";
+		break;
+	case VERSAL_SILICON:
+		platform = "SILICON";
+		break;
+	default:
+		platform = "unknown";
+	}
+
+	return platform;
+}
+
 uint32_t get_uart_clk(void)
 {
-	return UART_CLOCK;
+	uint32_t uart_clock;
+
+	switch (platform_id) {
+	case VERSAL_SPP:
+		uart_clock = 25000000;
+		break;
+	case VERSAL_EMU:
+		uart_clock = 212000;
+		break;
+	case VERSAL_QEMU:
+		uart_clock = 25000000;
+		break;
+	case VERSAL_SILICON:
+		uart_clock = 100000000;
+		break;
+	default:
+		panic();
+	}
+
+	return uart_clock;
 }
diff --git a/plat/xilinx/versal/bl31_versal_setup.c b/plat/xilinx/versal/bl31_versal_setup.c
index 594784f..0e4ec1c 100644
--- a/plat/xilinx/versal/bl31_versal_setup.c
+++ b/plat/xilinx/versal/bl31_versal_setup.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2018-2024, 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.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -12,6 +12,7 @@
 #include <bl31/bl31.h>
 #include <common/bl_common.h>
 #include <common/debug.h>
+#include <drivers/generic_delay_timer.h>
 #include <lib/mmio.h>
 #include <lib/xlat_tables/xlat_tables_v2.h>
 #include <plat/common/platform.h>
@@ -73,22 +74,41 @@
 	enum pm_ret_status ret_status;
 	uint64_t addr[HANDOFF_PARAMS_MAX_SIZE];
 
-	set_cnt_freq();
-
-	setup_console();
-
-	/* Initialize the platform config for future decision making */
-	versal_config_setup();
-
-	/* Get platform related information */
-	board_detection();
-
 	/*
 	 * Do initial security configuration to allow DRAM/device access. On
 	 * Base VERSAL only DRAM security is programmable (via TrustZone), but
 	 * other platforms might have more programmable security devices
 	 * present.
 	 */
+	versal_config_setup();
+
+	/* Initialize the platform config for future decision making */
+	board_detection();
+
+	switch (platform_id) {
+	case VERSAL_SPP:
+		cpu_clock = 2720000;
+		break;
+	case VERSAL_EMU:
+		cpu_clock = 212000;
+		break;
+	case VERSAL_QEMU:
+		/* Random values now */
+		cpu_clock = 2720000;
+		break;
+	case VERSAL_SILICON:
+		cpu_clock = 100000000;
+		break;
+	default:
+		panic();
+	}
+	set_cnt_freq();
+
+	generic_delay_timer_init();
+
+	setup_console();
+
+	NOTICE("TF-A running on %s %d\n", board_name_decode(), platform_version);
 
 	/* Populate common information for BL32 and BL33 */
 	SET_PARAM_HEAD(&bl32_image_ep_info, PARAM_EP, VERSION_1, 0);
diff --git a/plat/xilinx/versal/include/plat_private.h b/plat/xilinx/versal/include/plat_private.h
index 932c6de..4b2b6cf 100644
--- a/plat/xilinx/versal/include/plat_private.h
+++ b/plat/xilinx/versal/include/plat_private.h
@@ -1,7 +1,7 @@
 /*
  * 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.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -25,6 +25,8 @@
 extern uint32_t cpu_clock, platform_id, platform_version;
 
 void board_detection(void);
+const char *board_name_decode(void);
+
 void plat_versal_gic_driver_init(void);
 void plat_versal_gic_init(void);
 void plat_versal_gic_cpuif_enable(void);
diff --git a/plat/xilinx/versal/include/versal_def.h b/plat/xilinx/versal/include/versal_def.h
index f21d409..b7691ad 100644
--- a/plat/xilinx/versal/include/versal_def.h
+++ b/plat/xilinx/versal/include/versal_def.h
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2018-2022, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
- * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -25,13 +25,11 @@
 
 #define CONSOLE_IS(con)	(VERSAL_CONSOLE_ID_ ## con == VERSAL_CONSOLE)
 
-/* List all supported platforms */
-#define VERSAL_PLATFORM_ID_versal_virt	1
-#define VERSAL_PLATFORM_ID_spp_itr6	2
-#define VERSAL_PLATFORM_ID_emu_itr6	3
-#define VERSAL_PLATFORM_ID_silicon	4
-
-#define VERSAL_PLATFORM_IS(con)	(VERSAL_PLATFORM_ID_ ## con == VERSAL_PLATFORM)
+/* List of platforms */
+#define VERSAL_SILICON              U(0)
+#define VERSAL_SPP                  U(1)
+#define VERSAL_EMU                  U(2)
+#define VERSAL_QEMU                 U(3)
 
 /* Firmware Image Package */
 #define VERSAL_PRIMARY_CPU	0
@@ -75,27 +73,7 @@
 /*******************************************************************************
  * Platform related constants
  ******************************************************************************/
-#if VERSAL_PLATFORM_IS(versal_virt)
-# define PLATFORM_NAME		"Versal Virt"
-# define UART_CLOCK	25000000
-# define UART_BAUDRATE	115200
-# define VERSAL_CPU_CLOCK	2720000
-#elif VERSAL_PLATFORM_IS(silicon)
-# define PLATFORM_NAME		"Versal Silicon"
-# define UART_CLOCK	100000000
-# define UART_BAUDRATE	115200
-# define VERSAL_CPU_CLOCK	100000000
-#elif VERSAL_PLATFORM_IS(spp_itr6)
-# define PLATFORM_NAME		"SPP ITR6"
-# define UART_CLOCK	25000000
-# define UART_BAUDRATE	115200
-# define VERSAL_CPU_CLOCK	2720000
-#elif VERSAL_PLATFORM_IS(emu_itr6)
-# define PLATFORM_NAME		"EMU ITR6"
-# define UART_CLOCK	212000
-# define UART_BAUDRATE	9600
-# define VERSAL_CPU_CLOCK	212000
-#endif
+#define UART_BAUDRATE  115200
 
 /* Access control register defines */
 #define ACTLR_EL3_L2ACTLR_BIT	(1 << 6)
diff --git a/plat/xilinx/versal/plat_psci.c b/plat/xilinx/versal/plat_psci.c
index 4cf1ed1..74c5bf3 100644
--- a/plat/xilinx/versal/plat_psci.c
+++ b/plat/xilinx/versal/plat_psci.c
@@ -197,7 +197,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 ret, fw_api_version, version[RET_PAYLOAD_ARG_CNT] = {0U};
 	uint32_t cpu_id = plat_my_core_pos();
 	const struct pm_proc *proc = pm_get_proc(cpu_id);
 
diff --git a/plat/xilinx/versal/platform.mk b/plat/xilinx/versal/platform.mk
index 2f07996..6cc28e1 100644
--- a/plat/xilinx/versal/platform.mk
+++ b/plat/xilinx/versal/platform.mk
@@ -1,5 +1,5 @@
 # Copyright (c) 2018-2021, Arm Limited and Contributors. All rights reserved.
-# Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+# Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 
@@ -44,8 +44,9 @@
     $(eval $(call add_define,IPI_CRC_CHECK))
 endif
 
-VERSAL_PLATFORM ?= silicon
-$(eval $(call add_define_val,VERSAL_PLATFORM,VERSAL_PLATFORM_ID_${VERSAL_PLATFORM}))
+ifdef VERSAL_PLATFORM
+    $(warning "VERSAL_PLATFORM has been deprecated")
+endif
 
 ifdef XILINX_OF_BOARD_DTB_ADDR
 $(eval $(call add_define,XILINX_OF_BOARD_DTB_ADDR))
diff --git a/plat/xilinx/versal/sip_svc_setup.c b/plat/xilinx/versal/sip_svc_setup.c
index 4441d3e..3c0bd63 100644
--- a/plat/xilinx/versal/sip_svc_setup.c
+++ b/plat/xilinx/versal/sip_svc_setup.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2018-2021, Arm Limited and Contributors. All rights reserved.
- * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -22,7 +22,7 @@
 
 /* SiP Service Calls version numbers */
 #define SIP_SVC_VERSION_MAJOR	U(0)
-#define SIP_SVC_VERSION_MINOR	U(1)
+#define SIP_SVC_VERSION_MINOR	U(2)
 
 /* These macros are used to identify PM calls from the SMC function ID */
 #define SIP_FID_MASK	GENMASK(23, 16)
diff --git a/plat/xilinx/versal_net/plat_psci_pm.c b/plat/xilinx/versal_net/plat_psci_pm.c
index e5a5235..fb2005d 100644
--- a/plat/xilinx/versal_net/plat_psci_pm.c
+++ b/plat/xilinx/versal_net/plat_psci_pm.c
@@ -59,7 +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 ret, fw_api_version, version[RET_PAYLOAD_ARG_CNT] = {0U};
 	uint32_t cpu_id = plat_my_core_pos();
 	const struct pm_proc *proc = pm_get_proc(cpu_id);
 
diff --git a/plat/xilinx/versal_net/sip_svc_setup.c b/plat/xilinx/versal_net/sip_svc_setup.c
index 80d5a53..c974810 100644
--- a/plat/xilinx/versal_net/sip_svc_setup.c
+++ b/plat/xilinx/versal_net/sip_svc_setup.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2018-2019, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2018-2022, Xilinx, Inc. All rights reserved.
- * Copyright (c) 2022, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -25,7 +25,7 @@
 
 /* SiP Service Calls version numbers */
 #define SIP_SVC_VERSION_MAJOR		(0U)
-#define SIP_SVC_VERSION_MINOR		(1U)
+#define SIP_SVC_VERSION_MINOR		(2U)
 
 /* These macros are used to identify PM calls from the SMC function ID */
 #define SIP_FID_MASK	GENMASK(23, 16)
diff --git a/plat/xilinx/zynqmp/pm_service/zynqmp_pm_api_sys.c b/plat/xilinx/zynqmp/pm_service/zynqmp_pm_api_sys.c
index 3d546b3..66f011a 100644
--- a/plat/xilinx/zynqmp/pm_service/zynqmp_pm_api_sys.c
+++ b/plat/xilinx/zynqmp/pm_service/zynqmp_pm_api_sys.c
@@ -919,7 +919,7 @@
 enum pm_ret_status pm_feature_check(uint32_t api_id, uint32_t *version,
 				    uint32_t *bit_mask, uint8_t len)
 {
-	uint32_t ret_payload[PAYLOAD_ARG_CNT] = {0U};
+	uint32_t ret_payload[RET_PAYLOAD_ARG_CNT] = {0U};
 	uint32_t status;
 
 	/* Get API version implemented in TF-A */
diff --git a/plat/xilinx/zynqmp/pm_service/zynqmp_pm_svc_main.c b/plat/xilinx/zynqmp/pm_service/zynqmp_pm_svc_main.c
index 5a6a9f8..bf17ea4 100644
--- a/plat/xilinx/zynqmp/pm_service/zynqmp_pm_svc_main.c
+++ b/plat/xilinx/zynqmp/pm_service/zynqmp_pm_svc_main.c
@@ -285,7 +285,7 @@
 	uint32_t payload[PAYLOAD_ARG_CNT];
 
 	uint32_t pm_arg[5];
-	uint32_t result[PAYLOAD_ARG_CNT] = {0};
+	uint32_t result[RET_PAYLOAD_ARG_CNT] = {0};
 	uint32_t api_id;
 
 	/* Handle case where PM wasn't initialized properly */
@@ -566,7 +566,7 @@
 		PM_PACK_PAYLOAD6(payload, api_id, pm_arg[0], pm_arg[1],
 				 pm_arg[2], pm_arg[3], pm_arg[4]);
 		ret = pm_ipi_send_sync(primary_proc, payload, result,
-				       PAYLOAD_ARG_CNT);
+				       RET_PAYLOAD_ARG_CNT);
 		SMC_RET2(handle, (uint64_t)ret | ((uint64_t)result[0] << 32U),
 			 (uint64_t)result[1] | ((uint64_t)result[2] << 32U));
 	}