Merge "docs(spm): document s-el0 partition support" into integration
diff --git a/Makefile b/Makefile
index 2a1d4d8..4905291 100644
--- a/Makefile
+++ b/Makefile
@@ -777,6 +777,52 @@
     endif
 endif
 
+# SME/SVE only supported on AArch64
+ifeq (${ARCH},aarch32)
+    ifeq (${ENABLE_SME_FOR_NS},1)
+        $(error "ENABLE_SME_FOR_NS cannot be used with ARCH=aarch32")
+    endif
+    ifeq (${ENABLE_SVE_FOR_NS},1)
+        # Warning instead of error due to CI dependency on this
+        $(warning "ENABLE_SVE_FOR_NS cannot be used with ARCH=aarch32")
+        $(warning "Forced ENABLE_SVE_FOR_NS=0")
+        override ENABLE_SVE_FOR_NS	:= 0
+    endif
+endif
+
+# Ensure ENABLE_RME is not used with SME
+ifeq (${ENABLE_RME},1)
+    ifeq (${ENABLE_SME_FOR_NS},1)
+        $(error "ENABLE_SME_FOR_NS cannot be used with ENABLE_RME")
+    endif
+endif
+
+# Secure SME/SVE requires the non-secure component as well
+ifeq (${ENABLE_SME_FOR_SWD},1)
+    ifeq (${ENABLE_SME_FOR_NS},0)
+        $(error "ENABLE_SME_FOR_SWD requires ENABLE_SME_FOR_NS")
+    endif
+endif
+ifeq (${ENABLE_SVE_FOR_SWD},1)
+    ifeq (${ENABLE_SVE_FOR_NS},0)
+        $(error "ENABLE_SVE_FOR_SWD requires ENABLE_SVE_FOR_NS")
+    endif
+endif
+
+# SVE and SME cannot be used with CTX_INCLUDE_FPREGS since secure manager does
+# its own context management including FPU registers.
+ifeq (${CTX_INCLUDE_FPREGS},1)
+    ifeq (${ENABLE_SME_FOR_NS},1)
+        $(error "ENABLE_SME_FOR_NS cannot be used with CTX_INCLUDE_FPREGS")
+    endif
+    ifeq (${ENABLE_SVE_FOR_NS},1)
+        # Warning instead of error due to CI dependency on this
+        $(warning "ENABLE_SVE_FOR_NS cannot be used with CTX_INCLUDE_FPREGS")
+        $(warning "Forced ENABLE_SVE_FOR_NS=0")
+        override ENABLE_SVE_FOR_NS	:= 0
+    endif
+endif
+
 ################################################################################
 # Process platform overrideable behaviour
 ################################################################################
@@ -941,6 +987,8 @@
         ENABLE_PSCI_STAT \
         ENABLE_RME \
         ENABLE_RUNTIME_INSTRUMENTATION \
+        ENABLE_SME_FOR_NS \
+        ENABLE_SME_FOR_SWD \
         ENABLE_SPE_FOR_LOWER_ELS \
         ENABLE_SVE_FOR_NS \
         ENABLE_SVE_FOR_SWD \
@@ -1048,6 +1096,8 @@
         ENABLE_PSCI_STAT \
         ENABLE_RME \
         ENABLE_RUNTIME_INSTRUMENTATION \
+        ENABLE_SME_FOR_NS \
+        ENABLE_SME_FOR_SWD \
         ENABLE_SPE_FOR_LOWER_ELS \
         ENABLE_SVE_FOR_NS \
         ENABLE_SVE_FOR_SWD \
diff --git a/bl31/bl31.mk b/bl31/bl31.mk
index 9baa0c2..e751824 100644
--- a/bl31/bl31.mk
+++ b/bl31/bl31.mk
@@ -87,9 +87,14 @@
 BL31_SOURCES		+=	${MPMM_SOURCES}
 endif
 
+ifeq (${ENABLE_SME_FOR_NS},1)
+BL31_SOURCES		+=	lib/extensions/sme/sme.c
+BL31_SOURCES		+=	lib/extensions/sve/sve.c
+else
 ifeq (${ENABLE_SVE_FOR_NS},1)
 BL31_SOURCES		+=	lib/extensions/sve/sve.c
 endif
+endif
 
 ifeq (${ENABLE_MPAM_FOR_LOWER_ELS},1)
 BL31_SOURCES		+=	lib/extensions/mpam/mpam.c
diff --git a/bl32/tsp/tsp_interrupt.c b/bl32/tsp/tsp_interrupt.c
index 4e500b3..430b5dd 100644
--- a/bl32/tsp/tsp_interrupt.c
+++ b/bl32/tsp/tsp_interrupt.c
@@ -5,6 +5,7 @@
  */
 
 #include <assert.h>
+#include <inttypes.h>
 
 #include <platform_def.h>
 
@@ -36,7 +37,7 @@
 
 #if LOG_LEVEL >= LOG_LEVEL_VERBOSE
 	spin_lock(&console_lock);
-	VERBOSE("TSP: cpu 0x%lx sync s-el1 interrupt request from 0x%llx\n",
+	VERBOSE("TSP: cpu 0x%lx sync s-el1 interrupt request from 0x%" PRIx64 "\n",
 		read_mpidr(), elr_el3);
 	VERBOSE("TSP: cpu 0x%lx: %d sync s-el1 interrupt requests,"
 		" %d sync s-el1 interrupt returns\n",
diff --git a/bl32/tsp/tsp_main.c b/bl32/tsp/tsp_main.c
index 01c9ec5..55e1532 100644
--- a/bl32/tsp/tsp_main.c
+++ b/bl32/tsp/tsp_main.c
@@ -5,6 +5,8 @@
  */
 
 #include <assert.h>
+#include <inttypes.h>
+#include <stdint.h>
 
 #include <arch_features.h>
 #include <arch_helpers.h>
@@ -271,7 +273,7 @@
 
 #if LOG_LEVEL >= LOG_LEVEL_INFO
 	spin_lock(&console_lock);
-	INFO("TSP: cpu 0x%lx resumed. maximum off power level %lld\n",
+	INFO("TSP: cpu 0x%lx resumed. maximum off power level %" PRId64 "\n",
 	     read_mpidr(), max_off_pwrlvl);
 	INFO("TSP: cpu 0x%lx: %d smcs, %d erets %d cpu resume requests\n",
 		read_mpidr(),
@@ -375,7 +377,7 @@
 
 #if LOG_LEVEL >= LOG_LEVEL_INFO
 	spin_lock(&console_lock);
-	INFO("TSP: cpu 0x%lx received %s smc 0x%llx\n", read_mpidr(),
+	INFO("TSP: cpu 0x%lx received %s smc 0x%" PRIx64 "\n", read_mpidr(),
 		((func >> 31) & 1) == 1 ? "fast" : "yielding",
 		func);
 	INFO("TSP: cpu 0x%lx: %d smcs, %d erets\n", read_mpidr(),
diff --git a/common/fdt_fixup.c b/common/fdt_fixup.c
index 46606fb..de02b46 100644
--- a/common/fdt_fixup.c
+++ b/common/fdt_fixup.c
@@ -398,6 +398,7 @@
  * fdt_adjust_gic_redist() - Adjust GICv3 redistributor size
  * @dtb: Pointer to the DT blob in memory
  * @nr_cores: Number of CPU cores on this system.
+ * @gicr_base: Base address of the first GICR frame, or ~0 if unchanged
  * @gicr_frame_size: Size of the GICR frame per core
  *
  * On a GICv3 compatible interrupt controller, the redistributor provides
@@ -410,17 +411,19 @@
  * A GICv4 compatible redistributor uses four 64K pages per core, whereas GICs
  * without support for direct injection of virtual interrupts use two 64K pages.
  * The @gicr_frame_size parameter should be 262144 and 131072, respectively.
+ * Also optionally allow adjusting the GICR frame base address, when this is
+ * different due to ITS frames between distributor and redistributor.
  *
  * Return: 0 on success, negative error value otherwise.
  */
 int fdt_adjust_gic_redist(void *dtb, unsigned int nr_cores,
-			  unsigned int gicr_frame_size)
+			  uintptr_t gicr_base, unsigned int gicr_frame_size)
 {
 	int offset = fdt_node_offset_by_compatible(dtb, 0, "arm,gic-v3");
-	uint64_t redist_size_64;
-	uint32_t redist_size_32;
+	uint64_t reg_64;
+	uint32_t reg_32;
 	void *val;
-	int parent;
+	int parent, ret;
 	int ac, sc;
 
 	if (offset < 0) {
@@ -437,13 +440,34 @@
 		return -EINVAL;
 	}
 
+	if (gicr_base != INVALID_BASE_ADDR) {
+		if (ac == 1) {
+			reg_32 = cpu_to_fdt32(gicr_base);
+			val = &reg_32;
+		} else {
+			reg_64 = cpu_to_fdt64(gicr_base);
+			val = &reg_64;
+		}
+		/*
+		 * The redistributor base address is the second address in
+		 * the "reg" entry, so we have to skip one address and one
+		 * size cell.
+		 */
+		ret = fdt_setprop_inplace_namelen_partial(dtb, offset,
+							  "reg", 3,
+							  (ac + sc) * 4,
+							  val, ac * 4);
+		if (ret < 0) {
+			return ret;
+		}
+	}
+
 	if (sc == 1) {
-		redist_size_32 = cpu_to_fdt32(nr_cores * gicr_frame_size);
-		val = &redist_size_32;
+		reg_32 = cpu_to_fdt32(nr_cores * gicr_frame_size);
+		val = &reg_32;
 	} else {
-		redist_size_64 = cpu_to_fdt64(nr_cores *
-					      (uint64_t)gicr_frame_size);
-		val = &redist_size_64;
+		reg_64 = cpu_to_fdt64(nr_cores * (uint64_t)gicr_frame_size);
+		val = &reg_64;
 	}
 
 	/*
diff --git a/common/fdt_wrappers.c b/common/fdt_wrappers.c
index 64e01ea..2a9673f 100644
--- a/common/fdt_wrappers.c
+++ b/common/fdt_wrappers.c
@@ -8,6 +8,8 @@
 
 #include <assert.h>
 #include <errno.h>
+#include <inttypes.h>
+#include <stdint.h>
 #include <string.h>
 
 #include <libfdt.h>
@@ -35,7 +37,7 @@
 	/* Access property and obtain its length (in bytes) */
 	prop = fdt_getprop(dtb, node, prop_name, &value_len);
 	if (prop == NULL) {
-		WARN("Couldn't find property %s in dtb\n", prop_name);
+		VERBOSE("Couldn't find property %s in dtb\n", prop_name);
 		return -FDT_ERR_NOTFOUND;
 	}
 
@@ -402,7 +404,7 @@
 	addr_range = fdt_read_prop_cells(value + child_addr_size +
 				parent_addr_size,
 				range_size);
-	VERBOSE("DT: Address %llx mapped to %llx with range %llx\n",
+	VERBOSE("DT: Address %" PRIx64 " mapped to %" PRIx64 " with range %" PRIx64 "\n",
 		local_address, parent_address, addr_range);
 
 	/* Perform range check */
@@ -413,8 +415,8 @@
 
 	/* Found hit for the addr range that needs to be translated */
 	*translated_addr = parent_address + (base_address - local_address);
-	VERBOSE("DT: child address %llx mapped to %llx in parent bus\n",
-			local_address, parent_address);
+	VERBOSE("DT: child address %" PRIx64 "mapped to %" PRIx64 " in parent bus\n",
+		local_address, parent_address);
 	return true;
 }
 
@@ -470,8 +472,8 @@
 		next_entry = next_entry + ncells_xlat;
 	}
 
-	INFO("DT: No translation found for address %llx in node %s\n",
-		base_address, fdt_get_name(dtb, local_bus, NULL));
+	INFO("DT: No translation found for address %" PRIx64 " in node %s\n",
+	     base_address, fdt_get_name(dtb, local_bus, NULL));
 	return ILLEGAL_ADDR;
 }
 
diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst
index 337dde6..7a48601 100644
--- a/docs/about/maintainers.rst
+++ b/docs/about/maintainers.rst
@@ -75,7 +75,7 @@
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 :|M|: Mark Dykes <mark.dykes@arm.com>
 :|G|: `mardyk01`_
-:|M|: John Powell <John.Powell@arm.com>
+:|M|: John Powell <john.powell@arm.com>
 :|G|: `john-powell-arm`_
 :|F|: services/std_svc/sdei/
 
@@ -105,7 +105,7 @@
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 :|M|: Manish Badarkhe <manish.badarkhe@arm.com>
 :|G|: `ManishVB-Arm`_
-:|M|: John Powell <John.Powell@arm.com>
+:|M|: John Powell <john.powell@arm.com>
 :|G|: `john-powell-arm`_
 :|F|: bl31/ehf.c
 
@@ -115,7 +115,7 @@
 :|G|: `bipinravi-arm`_
 :|M|: Mark Dykes <mark.dykes@arm.com>
 :|G|: `mardyk01`_
-:|M|: John Powell <John.Powell@arm.com>
+:|M|: John Powell <john.powell@arm.com>
 :|G|: `john-powell-arm`_
 :|M|: Zelalem Aweke <Zelalem.Aweke@arm.com>
 :|G|: `zelalem-aweke`_
@@ -201,7 +201,7 @@
 ^^^^^^^^^^^^^^^^^
 :|M|: Lauren Wehrmeister <Lauren.Wehrmeister@arm.com>
 :|G|: `laurenw-arm`_
-:|M|: John Powell <John.Powell@arm.com>
+:|M|: John Powell <john.powell@arm.com>
 :|G|: `john-powell-arm`_
 :|F|: lib/cpus/
 
@@ -255,7 +255,7 @@
 ^^^^^^^^^^^^^^^^^^
 :|M|: Alexei Fedorov <Alexei.Fedorov@arm.com>
 :|G|: `AlexeiFedorov`_
-:|M|: John Powell <John.Powell@arm.com>
+:|M|: John Powell <john.powell@arm.com>
 :|G|: `john-powell-arm`_
 :|F|: lib/libc/
 
@@ -335,6 +335,15 @@
 :|F|: include/lib/mpmm/
 :|F|: lib/mpmm/
 
+Granule Protection Tables Library (GPT-RME)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+:|M|: Mark Dykes <mark.dykes@arm.com>
+:|G|: `mardyk01`_
+:|M|: John Powell <john.powell@arm.com>
+:|G|: `john-powell-arm`_
+:|F|: lib/gpt_rme
+:|F|: include/lib/gpt_rme
+
 Platform Ports
 ~~~~~~~~~~~~~~
 
diff --git a/docs/components/granule-protection-tables-design.rst b/docs/components/granule-protection-tables-design.rst
new file mode 100644
index 0000000..07637dd
--- /dev/null
+++ b/docs/components/granule-protection-tables-design.rst
@@ -0,0 +1,235 @@
+Granule Protection Tables Library
+=================================
+
+This document describes the design of the granule protection tables (GPT)
+library used by Trusted Firmware-A (TF-A). This library provides the APIs needed
+to initialize the GPTs based on a data structure containing information about
+the systems memory layout, configure the system registers to enable granule
+protection checks based on these tables, and transition granules between
+different PAS (physical address spaces) at runtime.
+
+Arm CCA adds two new security states for a total of four: root, realm, secure, and
+non-secure. In addition to new security states, corresponding physical address
+spaces have been added to control memory access for each state. The PAS access
+allowed to each security state can be seen in the table below.
+
+.. list-table:: Security states and PAS access rights
+   :widths: 25 25 25 25 25
+   :header-rows: 1
+
+   * -
+     - Root state
+     - Realm state
+     - Secure state
+     - Non-secure state
+   * - Root PAS
+     - yes
+     - no
+     - no
+     - no
+   * - Realm PAS
+     - yes
+     - yes
+     - no
+     - no
+   * - Secure PAS
+     - yes
+     - no
+     - yes
+     - no
+   * - Non-secure PAS
+     - yes
+     - yes
+     - yes
+     - yes
+
+The GPT can function as either a 1 level or 2 level lookup depending on how a
+PAS region is configured. The first step is the level 0 table, each entry in the
+level 0 table controls access to a relatively large region in memory (block
+descriptor), and the entire region can belong to a single PAS when a one step
+mapping is used, or a level 0 entry can link to a level 1 table where relatively
+small regions (granules) of memory can be assigned to different PAS with a 2
+step mapping. The type of mapping used for each PAS is determined by the user
+when setting up the configuration structure.
+
+Design Concepts and Interfaces
+------------------------------
+
+This section covers some important concepts and data structures used in the GPT
+library.
+
+There are three main parameters that determine how the tables are organized and
+function: the PPS (protected physical space) which is the total amount of
+protected physical address space in the system, PGS (physical granule size)
+which is how large each level 1 granule is, and L0GPTSZ (level 0 GPT size) which
+determines how much physical memory is governed by each level 0 entry. A granule
+is the smallest unit of memory that can be independently assigned to a PAS.
+
+L0GPTSZ is determined by the hardware and is read from the GPCCR_EL3 register.
+PPS and PGS are passed into the APIs at runtime and can be determined in
+whatever way is best for a given platform, either through some algorithm or hard
+coded in the firmware.
+
+GPT setup is split into two parts: table creation and runtime initialization. In
+the table creation step, a data structure containing information about the
+desired PAS regions is passed into the library which validates the mappings,
+creates the tables in memory, and enables granule protection checks. In the
+runtime initialization step, the runtime firmware locates the existing tables in
+memory using the GPT register configuration and saves important data to a
+structure used by the granule transition service which will be covered more
+below.
+
+In the reference implementation for FVP models, you can find an example of PAS
+region definitions in the file ``include/plat/arm/common/arm_pas_def.h``. Table
+creation API calls can be found in ``plat/arm/common/arm_bl2_setup.c`` and
+runtime initialization API calls can be seen in
+``plat/arm/common/arm_bl31_setup.c``.
+
+Defining PAS regions
+~~~~~~~~~~~~~~~~~~~~
+
+A ``pas_region_t`` structure is a way to represent a physical address space and
+its attributes that can be used by the GPT library to initialize the tables.
+
+This structure is composed of the following:
+
+#. The base physical address
+#. The region size
+#. The desired attributes of this memory region (mapping type, PAS type)
+
+See the ``pas_region_t`` type in ``include/lib/gpt_rme/gpt_rme.h``.
+
+The programmer should provide the API with an array containing ``pas_region_t``
+structures, then the library will check the desired memory access layout for
+validity and create tables to implement it.
+
+``pas_region_t`` is a public type, however it is recommended that the macros
+``GPT_MAP_REGION_BLOCK`` and ``GPT_MAP_REGION_GRANULE`` be used to populate
+these structures instead of doing it manually to reduce the risk of future
+compatibility issues. These macros take the base physical address, region size,
+and PAS type as arguments to generate the pas_region_t structure. As the names
+imply, ``GPT_MAP_REGION_BLOCK`` creates a region using only L0 mapping while
+``GPT_MAP_REGION_GRANULE`` creates a region using L0 and L1 mappings.
+
+Level 0 and Level 1 Tables
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The GPT initialization APIs require memory to be passed in for the tables to be
+constructed, ``gpt_init_l0_tables`` takes a memory address and size for building
+the level 0 tables and ``gpt_init_pas_l1_tables`` takes an address and size for
+building the level 1 tables which are linked from level 0 descriptors. The
+tables should have PAS type ``GPT_GPI_ROOT`` and a typical system might place
+its level 0 table in SRAM and its level 1 table(s) in DRAM.
+
+Granule Transition Service
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The Granule Transition Service allows memory mapped with GPT_MAP_REGION_GRANULE
+ownership to be changed using SMC calls. Non-secure granules can be transitioned
+to either realm or secure space, and realm and secure granules can be
+transitioned back to non-secure. This library only allows memory mapped as
+granules to be transitioned, memory mapped as blocks have their GPIs fixed after
+table creation.
+
+Library APIs
+------------
+
+The public APIs and types can be found in ``include/lib/gpt_rme/gpt_rme.h`` and this
+section is intended to provide additional details and clarifications.
+
+To create the GPTs and enable granule protection checks the APIs need to be
+called in the correct order and at the correct time during the system boot
+process.
+
+#. Firmware must enable the MMU.
+#. Firmware must call ``gpt_init_l0_tables`` to initialize the level 0 tables to
+   a default state, that is, initializing all of the L0 descriptors to allow all
+   accesses to all memory. The PPS is provided to this function as an argument.
+#. DDR discovery and initialization by the system, the discovered DDR region(s)
+   are then added to the L1 PAS regions to be initialized in the next step and
+   used by the GTSI at runtime.
+#. Firmware must call ``gpt_init_pas_l1_tables`` with a pointer to an array of
+   ``pas_region_t`` structures containing the desired memory access layout. The
+   PGS is provided to this function as an argument.
+#. Firmware must call ``gpt_enable`` to enable granule protection checks by
+   setting the correct register values.
+#. In systems that make use of the granule transition service, runtime
+   firmware must call ``gpt_runtime_init`` to set up the data structures needed
+   by the GTSI to find the tables and transition granules between PAS types.
+
+API Constraints
+~~~~~~~~~~~~~~~
+
+The values allowed by the API for PPS and PGS are enumerated types
+defined in the file ``include/lib/gpt_rme/gpt_rme.h``.
+
+Allowable values for PPS along with their corresponding size.
+
+* ``GPCCR_PPS_4GB`` (4GB protected space, 0x100000000 bytes)
+* ``GPCCR_PPS_64GB`` (64GB protected space, 0x1000000000 bytes)
+* ``GPCCR_PPS_1TB`` (1TB protected space, 0x10000000000 bytes)
+* ``GPCCR_PPS_4TB`` (4TB protected space, 0x40000000000 bytes)
+* ``GPCCR_PPS_16TB`` (16TB protected space, 0x100000000000 bytes)
+* ``GPCCR_PPS_256TB`` (256TB protected space, 0x1000000000000 bytes)
+* ``GPCCR_PPS_4PB`` (4PB protected space, 0x10000000000000 bytes)
+
+Allowable values for PGS along with their corresponding size.
+
+* ``GPCCR_PGS_4K`` (4KB granules, 0x1000 bytes)
+* ``GPCCR_PGS_16K`` (16KB granules, 0x4000 bytes)
+* ``GPCCR_PGS_64K`` (64KB granules, 0x10000 bytes)
+
+Allowable values for L0GPTSZ along with the corresponding size.
+
+* ``GPCCR_L0GPTSZ_30BITS`` (1GB regions, 0x40000000 bytes)
+* ``GPCCR_L0GPTSZ_34BITS`` (16GB regions, 0x400000000 bytes)
+* ``GPCCR_L0GPTSZ_36BITS`` (64GB regions, 0x1000000000 bytes)
+* ``GPCCR_L0GPTSZ_39BITS`` (512GB regions, 0x8000000000 bytes)
+
+Note that the value of the PPS, PGS, and L0GPTSZ definitions is an encoded value
+corresponding to the size, not the size itself. The decoded hex representations
+of the sizes have been provided for convenience.
+
+The L0 table memory has some constraints that must be taken into account.
+
+* The L0 table must be aligned to either the table size or 4096 bytes, whichever
+  is greater. L0 table size is the total protected space (PPS) divided by the
+  size of each L0 region (L0GPTSZ) multiplied by the size of each L0 descriptor
+  (8 bytes). ((PPS / L0GPTSZ) * 8)
+* The L0 memory size must be greater than or equal to the table size.
+* The L0 memory must fall within a PAS of type GPT_GPI_ROOT.
+
+The L1 memory also has some constraints.
+
+* The L1 tables must be aligned to their size. The size of each L1 table is the
+  size of each L0 region (L0GPTSZ) divided by the granule size (PGS) divided by
+  the granules controlled in each byte (2). ((L0GPTSZ / PGS) / 2)
+* There must be enough L1 memory supplied to build all requested L1 tables.
+* The L1 memory must fall within a PAS of type GPT_GPI_ROOT.
+
+If an invalid combination of parameters is supplied, the APIs will print an
+error message and return a negative value. The return values of APIs should be
+checked to ensure successful configuration.
+
+Sample Calculation for L0 memory size and alignment
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Let PPS=GPCCR_PPS_4GB and L0GPTSZ=GPCCR_L0GPTSZ_30BITS
+
+We can find the total L0 table size with ((PPS / L0GPTSZ) * 8)
+
+Substitute values to get this: ((0x100000000 / 0x40000000) * 8)
+
+And solve to get 32 bytes. In this case, 4096 is greater than 32, so the L0
+tables must be aligned to 4096 bytes.
+
+Sample calculation for L1 table size and alignment
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Let PGS=GPCCR_PGS_4K and L0GPTSZ=GPCCR_L0GPTSZ_30BITS
+
+We can find the size of each L1 table with ((L0GPTSZ / PGS) / 2).
+
+Substitute values: ((0x40000000 / 0x1000) / 2)
+
+And solve to get 0x20000 bytes per L1 table.
diff --git a/docs/components/index.rst b/docs/components/index.rst
index 754526d..95fe42c 100644
--- a/docs/components/index.rst
+++ b/docs/components/index.rst
@@ -25,3 +25,4 @@
    xlat-tables-lib-v2-design
    cot-binding
    realm-management-extension
+   granule-protection-tables-design
diff --git a/docs/components/realm-management-extension.rst b/docs/components/realm-management-extension.rst
index 5c580f3..2c4e0b8 100644
--- a/docs/components/realm-management-extension.rst
+++ b/docs/components/realm-management-extension.rst
@@ -4,8 +4,82 @@
 
 FEAT_RME (or RME for short) is an Armv9-A extension and is one component of the
 `Arm Confidential Compute Architecture (Arm CCA)`_. TF-A supports RME starting
-from version 2.6. This document provides instructions on how to build and run
-TF-A with RME.
+from version 2.6. This chapter discusses the changes to TF-A to support RME and
+provides instructions on how to build and run TF-A with RME.
+
+RME support in TF-A
+---------------------
+
+The following diagram shows an Arm CCA software architecture with TF-A as the
+EL3 firmware. In the Arm CCA architecture there are two additional security
+states and address spaces: ``Root`` and ``Realm``. TF-A firmware runs in the
+Root world. In the realm world, a Realm Management Monitor firmware (RMM)
+manages the execution of Realm VMs and their interaction with the hypervisor.
+
+.. image:: ../resources/diagrams/arm-cca-software-arch.png
+
+RME is the hardware extension to support Arm CCA. To support RME, various
+changes have been introduced to TF-A. We discuss those changes below.
+
+Changes to translation tables library
+***************************************
+RME adds Root and Realm Physical address spaces. To support this, two new
+memory type macros, ``MT_ROOT`` and ``MT_REALM``, have been added to the
+:ref:`Translation (XLAT) Tables Library`. These macros are used to configure
+memory regions as Root or Realm respectively.
+
+.. note::
+
+ Only version 2 of the translation tables library supports the new memory
+ types.
+
+Changes to context management
+*******************************
+A new CPU context for the Realm world has been added. The existing
+:ref:`CPU context management API<PSCI Library Integration guide for Armv8-A
+AArch32 systems>` can be used to manage Realm context.
+
+Boot flow changes
+*******************
+In a typical TF-A boot flow, BL2 runs at Secure-EL1. However when RME is
+enabled, TF-A runs in the Root world at EL3. Therefore, the boot flow is
+modified to run BL2 at EL3 when RME is enabled. In addition to this, a
+Realm-world firmware (RMM) is loaded by BL2 in the Realm physical address
+space.
+
+The boot flow when RME is enabled looks like the following:
+
+1. BL1 loads and executes BL2 at EL3
+2. BL2 loads images including RMM
+3. BL2 transfers control to BL31
+4. BL31 initializes SPM (if SPM is enabled)
+5. BL31 initializes RMM
+6. BL31 transfers control to Normal-world software
+
+Granule Protection Tables (GPT) library
+*****************************************
+Isolation between the four physical address spaces is enforced by a process
+called Granule Protection Check (GPC) performed by the MMU downstream any
+address translation. GPC makes use of Granule Protection Table (GPT) in the
+Root world that describes the physical address space assignment of every
+page (granule). A GPT library that provides APIs to initialize GPTs and to
+transition granules between different physical address spaces has been added.
+More information about the GPT library can be found in the
+:ref:`Granule Protection Tables Library` chapter.
+
+RMM Dispatcher (RMMD)
+************************
+RMMD is a new standard runtime service that handles the switch to the Realm
+world. It initializes the RMM and handles Realm Management Interface (RMI)
+SMC calls from Non-secure and Realm worlds.
+
+Test Realm Payload (TRP)
+*************************
+TRP is a small test payload that runs at R-EL2 and implements a subset of
+the Realm Management Interface (RMI) commands to primarily test EL3 firmware
+and the interface between R-EL2 and EL3. When building TF-A with RME enabled,
+if a path to an RMM image is not provided, TF-A builds the TRP by default
+and uses it as RMM image.
 
 Building and running TF-A with RME
 ------------------------------------
@@ -25,11 +99,8 @@
 
  git clone https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git
 
-To run the tests, you need an FVP model. You can download a model that supports
-RME from the `Arm Architecture Models website`_. Please select the
-*Base RevC AEM FVP* model. After extracting the downloaded file, you should be able to
-find the *FVP_Base_RevC-2xAEMvA* binary. The instructions below have been tested
-with model version 11.15 revision 18.
+To run the tests, you need an FVP model. Please use the :ref:`latest version
+<Arm Fixed Virtual Platforms (FVP)>` of *FVP_Base_RevC-2xAEMvA* model.
 
 .. note::
 
@@ -64,9 +135,7 @@
  all fip
 
 This produces *bl1.bin* and *fip.bin* binaries in the *build/fvp/debug* directory.
-The above command also builds a Test Realm Payload (TRP), which is a small test
-payload that implements Realm Monitor Management (RMM) functionalities and runs
-in the realm world (R-EL2). The TRP binary is packaged in *fip.bin*.
+The above command also builds TRP. The TRP binary is packaged in *fip.bin*.
 
 Four-world execution with Hafnium and TF-A Tests
 ****************************************************
diff --git a/docs/components/secure-partition-manager-mm.rst b/docs/components/secure-partition-manager-mm.rst
index 30312ee..4cdb96c 100644
--- a/docs/components/secure-partition-manager-mm.rst
+++ b/docs/components/secure-partition-manager-mm.rst
@@ -134,8 +134,8 @@
 the rest of this document.
 
 To enable SPM support in TF-A, the source code must be compiled with the build
-flag ``SPM_MM=1``, along with ``EL3_EXCEPTION_HANDLING=1``. On Arm
-platforms the build option ``ARM_BL31_IN_DRAM`` must be set to 1. Also, the
+flag ``SPM_MM=1``, along with ``EL3_EXCEPTION_HANDLING=1`` and ``ENABLE_SVE_FOR_NS=0``.
+On Arm platforms the build option ``ARM_BL31_IN_DRAM`` must be set to 1. Also, the
 location of the binary that contains the BL32 image
 (``BL32=path/to/image.bin``) must be specified.
 
@@ -148,7 +148,7 @@
 .. code:: shell
 
     BL32=path/to/standalone/mm/sp BL33=path/to/bl33.bin \
-    make PLAT=fvp SPM_MM=1 EL3_EXCEPTION_HANDLING=1 ARM_BL31_IN_DRAM=1 all fip
+    make PLAT=fvp SPM_MM=1 EL3_EXCEPTION_HANDLING=1 ENABLE_SVE_FOR_NS=0 ARM_BL31_IN_DRAM=1 all fip
 
 Describing Secure Partition resources
 -------------------------------------
diff --git a/docs/components/secure-partition-manager.rst b/docs/components/secure-partition-manager.rst
index 89fea9a..68bb6f2 100644
--- a/docs/components/secure-partition-manager.rst
+++ b/docs/components/secure-partition-manager.rst
@@ -776,11 +776,155 @@
 .. image:: ../resources/diagrams/ffa-ns-interrupt-handling-sp-preemption.png
 
 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 Beta0 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 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.
+
+A physical secure interrupt could preempt normal world execution. Moreover, when
+the execution is in secure world, it is highly likely that the target of a
+secure interrupt is not the currently running execution context of an SP. It
+could be targeted to another FF-A component. Consequently, secure interrupt
+management depends on the state of the target execution context of the SP that
+is responsible for handling the interrupt. Hence, the spec provides guidance on
+how to signal start and completion of secure interrupt handling as discussed in
+further sections.
+
+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.
+
+In the current implementation, S-EL1 SPs use para-virtualized HVC interface
+implemented by SPMC to perform priority drop and interrupt deactivation (we
+assume EOImode = 0, i.e. priority drop and deactivation are done together).
+
+If normal world execution was preempted by secure interrupt, SPMC uses
+FFA_NORMAL_WORLD_RESUME ABI to indicate completion of secure interrupt handling
+and further return execution to normal world. 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.
+
+An action is broadly a set of steps taken by the SPMC in response to a physical
+interrupt. In order to simplify the design, the current version of secure
+interrupt management support in SPMC (Hafnium) does not fully implement the
+Scheduling models and Partition runtime models. However, the current
+implementation loosely maps to the following actions that are legally allowed
+by the specification. Please refer to the Table 8.4 in the spec for further
+description of actions. The action specified for a type of interrupt when the
+SP is in the message processing running state cannot be less permissive than the
+action specified for the same type of interrupt when the SP is in the interrupt
+handling running state.
+
++--------------------+--------------------+------------+-------------+
+| Runtime Model      | NS-Int             | Self S-Int | Other S-Int |
++--------------------+--------------------+------------+-------------+
+| Message Processing | Signalable with ME | Signalable | Signalable  |
++--------------------+--------------------+------------+-------------+
+| Interrupt Handling | Queued             | Queued     | Queued      |
++--------------------+--------------------+------------+-------------+
+
+Abbreviations:
+
+  - NS-Int: A Non-secure physical interrupt. It requires a switch to the Normal
+    world to be handled.
+  - 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.
+
+The following figure describes interrupt handling flow when secure interrupt
+triggers while 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) Since SP1 vCPU is in WAITING state, SPMC signals using FFA_INTERRUPT with
+       interrupt id as argument and resume it using ERET.
+  - 6) Execution traps to vIRQ handler in SP1 provided that interrupt is not
+       masked i.e., PSTATE.I = 0
+  - 7) SP1 services the interrupt and invokes the de-activation HVC call.
+  - 8) SPMC does internal state management and further de-activates the physical
+       interrupt and resumes SP vCPU.
+  - 9) SP 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.
+
+The following figure describes interrupt handling flow when secure interrupt
+triggers while in secure world:
+
+.. image:: ../resources/diagrams/ffa-secure-interrupt-handling-swd.png
+
+A brief description of the events:
+
+  - 1) Secure interrupt triggers while SP2 is running and SP1 is blocked.
+  - 2) Gets trapped 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.
+  - 5) Execution traps to vIRQ handler in SP1 provided that interrupt is not
+       masked i.e., PSTATE.I = 0
+  - 6) SP1 services the secure interrupt and invokes the de-activation HVC call.
+  - 7) SPMC does internal state management, de-activates the physical interrupt
+       and resumes SP1 vCPU.
+  - 8) Assuming SP1 is in BLOCKED state, SP1 performs secure interrupt completion
+       through FFA_RUN ABI.
+  - 9) SPMC resumes the pre-empted vCPU of SP2.
 
-The current implementation does not support handling of secure interrupts
-trapped by the SPMC at S-EL2. This is work in progress planned for future
-releases.
 
 Power management
 ----------------
diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst
index eebeaa2..9d0dd5e 100644
--- a/docs/design/cpu-specific-build-macros.rst
+++ b/docs/design/cpu-specific-build-macros.rst
@@ -288,6 +288,10 @@
    CPU. This needs to be enabled for revisions r0p0, r1p0, r1p1, and r1p2. It
    is still open.
 
+-  ``ERRATA_A78_2242635``: This applies errata 2242635 workaround to Cortex-A78
+   CPU. This needs to be enabled for revisions r1p0, r1p1, and r1p2. The issue
+   is present in r0p0 but there is no workaround. It is still open.
+
 For Cortex-A78 AE, the following errata build flags are defined :
 
 - ``ERRATA_A78_AE_1941500`` : This applies errata 1941500 workaround to Cortex-A78
@@ -340,11 +344,6 @@
    CPU. This needs to be enabled for revisions r3p0, r3p1, r4p0, and r4p1, for
    revisions r0p0, r1p0, and r2p0 there is no workaround.
 
-For Neoverse N2, the following errata build flags are defined :
-
--  ``ERRATA_N2_2002655``: This applies errata 2002655 workaround to Neoverse-N2
-   CPU. This needs to be enabled for revision r0p0 of the CPU, it is still open.
-
 For Neoverse V1, the following errata build flags are defined :
 
 -  ``ERRATA_V1_1774420``: This applies errata 1774420 workaround to Neoverse-V1
@@ -379,6 +378,11 @@
    CPU. This needs to be enabled for revisions r0p0, r1p0, and r1p1 of the CPU.
    It is still open.
 
+-  ``ERRATA_V1_2216392``: This applies errata 2216392 workaround to Neoverse-V1
+   CPU. This needs to be enabled for revisions r1p0 and r1p1 of the CPU, the
+   issue is present in r0p0 as well but there is no workaround for that
+   revision.  It is still open.
+
 For Cortex-A710, the following errata build flags are defined :
 
 -  ``ERRATA_A710_1987031``: This applies errata 1987031 workaround to
@@ -407,6 +411,9 @@
 
 For Neoverse N2, the following errata build flags are defined :
 
+-  ``ERRATA_N2_2002655``: This applies errata 2002655 workaround to Neoverse-N2
+   CPU. This needs to be enabled for revision r0p0 of the CPU, it is still open.
+
 -  ``ERRATA_N2_2067956``: This applies errata 2067956 workaround to Neoverse-N2
    CPU. This needs to be enabled for revision r0p0 of the CPU and is still open.
 
@@ -422,6 +429,18 @@
 -  ``ERRATA_N2_2138953``: This applies errata 2138953 workaround to Neoverse-N2
    CPU. This needs to be enabled for revision r0p0 of the CPU and is still open.
 
+-  ``ERRATA_N2_2242415``: This applies errata 2242415 workaround to Neoverse-N2
+   CPU. This needs to be enabled for revision r0p0 of the CPU and is still open.
+
+-  ``ERRATA_N2_2138958``: This applies errata 2138958 workaround to Neoverse-N2
+   CPU. This needs to be enabled for revision r0p0 of the CPU and is still open.
+
+-  ``ERRATA_N2_2242400``: This applies errata 2242400 workaround to Neoverse-N2
+   CPU. This needs to be enabled for revision r0p0 of the CPU and is still open.
+
+-  ``ERRATA_N2_2280757``: This applies errata 2280757 workaround to Neoverse-N2
+   CPU. This needs to be enabled for revision r0p0 of the CPU and is still open.
+
 DSU Errata Workarounds
 ----------------------
 
diff --git a/docs/design/firmware-design.rst b/docs/design/firmware-design.rst
index ef500ff..0831dc0 100644
--- a/docs/design/firmware-design.rst
+++ b/docs/design/firmware-design.rst
@@ -26,6 +26,13 @@
 
 TF-A can be built to support either AArch64 or AArch32 execution state.
 
+.. note::
+
+ The descriptions in this chapter are for the Arm TrustZone architecture.
+ For changes to the firmware design for the
+ `Arm Confidential Compute Architecture (Arm CCA)`_ please refer to the
+ chapter :ref:`Realm Management Extension (RME)`.
+
 Cold boot
 ---------
 
@@ -2722,7 +2729,7 @@
 
 --------------
 
-*Copyright (c) 2013-2020, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2013-2021, Arm Limited and Contributors. All rights reserved.*
 
 .. _Power State Coordination Interface PDD: http://infocenter.arm.com/help/topic/com.arm.doc.den0022d/Power_State_Coordination_Interface_PDD_v1_1_DEN0022D.pdf
 .. _SMCCC: https://developer.arm.com/docs/den0028/latest
@@ -2731,5 +2738,6 @@
 .. _Arm ARM: https://developer.arm.com/docs/ddi0487/latest
 .. _SMC Calling Convention: https://developer.arm.com/docs/den0028/latest
 .. _Trusted Board Boot Requirements CLIENT (TBBR-CLIENT) Armv8-A (ARM DEN0006D): https://developer.arm.com/docs/den0006/latest/trusted-board-boot-requirements-client-tbbr-client-armv8-a
+.. _Arm Confidential Compute Architecture (Arm CCA): https://www.arm.com/why-arm/architecture/security-features/arm-confidential-compute-architecture
 
 .. |Image 1| image:: ../resources/diagrams/rt-svc-descs-layout.png
diff --git a/docs/design_documents/index.rst b/docs/design_documents/index.rst
index 187510a..c82d2ee 100644
--- a/docs/design_documents/index.rst
+++ b/docs/design_documents/index.rst
@@ -7,6 +7,7 @@
    :numbered:
 
    cmake_framework
+   measured_boot_poc
 
 --------------
 
diff --git a/docs/design_documents/measured_boot_poc.rst b/docs/design_documents/measured_boot_poc.rst
new file mode 100644
index 0000000..3ae539b
--- /dev/null
+++ b/docs/design_documents/measured_boot_poc.rst
@@ -0,0 +1,507 @@
+Interaction between Measured Boot and an fTPM (PoC)
+===================================================
+
+Measured Boot is the process of cryptographically measuring the code and
+critical data used at boot time, for example using a TPM, so that the
+security state can be attested later.
+
+The current implementation of the driver included in Trusted Firmware-A
+(TF-A) stores the measurements into a `TGC event log`_ in secure
+memory. No other means of recording measurements (such as a discrete TPM) is
+supported right now.
+
+The driver also provides mechanisms to pass the Event Log to normal world if
+needed.
+
+This manual provides instructions to build a proof of concept (PoC) with the
+sole intention of showing how Measured Boot can be used in conjunction with
+a firmware TPM (fTPM) service implemented on top of OP-TEE.
+
+.. note::
+   The instructions given in this document are meant to be used to build
+   a PoC to show how Measured Boot on TF-A can interact with a third
+   party (f)TPM service and they try to be as general as possible. Different
+   platforms might have different needs and configurations (e.g. different
+   SHA algorithms) and they might also use different types of TPM services
+   (or even a different type of service to provide the attestation)
+   and therefore the instuctions given here might not apply in such scenarios.
+
+Components
+~~~~~~~~~~
+
+The PoC is built on top of the `OP-TEE Toolkit`_, which has support to build
+TF-A with support for Measured Boot enabled (and run it on a Foundation Model)
+since commit cf56848.
+
+The aforementioned toolkit builds a set of images that contain all the components
+needed to test that the Event Log was properly created. One of these images will
+contain a third party fTPM service which in turn will be used to process the
+Event Log.
+
+The reason to choose OP-TEE Toolkit to build our PoC around it is mostly
+for convenience. As the fTPM service used is an OP-TEE TA, it was easy to add
+build support for it to the toolkit and then build the PoC around it.
+
+The most relevant components installed in the image that are closely related to
+Measured Boot/fTPM functionality are:
+
+   - **OP-TEE**: As stated earlier, the fTPM service used in this PoC is built as an
+     OP-TEE TA and therefore we need to include the OP-TEE OS image.
+     Support to interfacing with Measured Boot was added to version 3.9.0 of
+     OP-TEE by implementing the ``PTA_SYSTEM_GET_TPM_EVENT_LOG`` syscall, which
+     allows the former to pass a copy of the Event Log to any TA requesting it.
+     OP-TEE knows the location of the Event Log by reading the DTB bindings
+     received from TF-A. Visit :ref:`DTB binding for Event Log properties`
+     for more details on this.
+
+   - **fTPM Service**: We use a third party fTPM service in order to validate
+     the Measured Boot functionality. The chosen fTPM service is a sample
+     implementation for Aarch32 architecture included on the `ms-tpm-20-ref`_
+     reference implementation from Microsoft. The service was updated in order
+     to extend the Measured Boot Event Log at boot up and it uses the
+     aforementioned ``PTA_SYSTEM_GET_TPM_EVENT_LOG`` call to retrieve a copy
+     of the former.
+
+   .. note::
+      Arm does not provide an fTPM implementation. The fTPM service used here
+      is a third party one which has been updated to support Measured Boot
+      service as provided by TF-A. As such, it is beyond the scope of this
+      manual to test and verify the correctness of the output generated by the
+      fTPM service.
+
+   - **TPM Kernel module**: In order to interact with the fTPM service, we need
+     a kernel module to forward the request from user space to the secure world.
+
+   - `tpm2-tools`_: This is a set of tools that allow to interact with the
+     fTPM service. We use this in order to read the PCRs with the measurements.
+
+Building the PoC for the Arm FVP platform
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+As mentioned before, this PoC is based on the OP-TEE Toolkit with some
+extensions to enable Measured Boot and an fTPM service. Therefore, we can rely
+on the instructions to build the original OP-TEE Toolkit. As a general rule,
+the following steps should suffice:
+
+(1) Start by following the `Get and build the solution`_ instructions to build
+    the OP-TEE toolkit. On step 3, you need to get the manifest for FVP
+    platform from the main branch:
+
+    .. code:: shell
+
+       $ repo init -u https://github.com/OP-TEE/manifest.git -m fvp.xml
+
+    Then proceed synching the repos as stated in step 3. Continue following
+    the instructions and stop before step 5.
+
+(2) Next you should obtain the `Armv8-A Foundation Platform (For Linux Hosts Only)`_.
+    The binary should be untar'ed to the root of the repo tree, i.e., like
+    this: ``<fvp-project>/Foundation_Platformpkg``. In the end, after cloning
+    all source code, getting the toolchains and "installing"
+    Foundation_Platformpkg, you should have a folder structure that looks like
+    this:
+
+    .. code:: shell
+
+       $ ls -la
+       total 80
+       drwxrwxr-x 20 tf-a_user tf-a_user 4096 Jul  1 12:16 .
+       drwxr-xr-x 23 tf-a_user tf-a_user 4096 Jul  1 10:40 ..
+       drwxrwxr-x 12 tf-a_user tf-a_user 4096 Jul  1 10:45 build
+       drwxrwxr-x 16 tf-a_user tf-a_user 4096 Jul  1 12:16 buildroot
+       drwxrwxr-x 51 tf-a_user tf-a_user 4096 Jul  1 10:45 edk2
+       drwxrwxr-x  6 tf-a_user tf-a_user 4096 Jul  1 12:14 edk2-platforms
+       drwxr-xr-x  7 tf-a_user tf-a_user 4096 Jul  1 10:52 Foundation_Platformpkg
+       drwxrwxr-x 17 tf-a_user tf-a_user 4096 Jul  2 10:40 grub
+       drwxrwxr-x 25 tf-a_user tf-a_user 4096 Jul  2 10:39 linux
+       drwxrwxr-x 15 tf-a_user tf-a_user 4096 Jul  1 10:45 mbedtls
+       drwxrwxr-x  6 tf-a_user tf-a_user 4096 Jul  1 10:45 ms-tpm-20-ref
+       drwxrwxr-x  8 tf-a_user tf-a_user 4096 Jul  1 10:45 optee_client
+       drwxrwxr-x 10 tf-a_user tf-a_user 4096 Jul  1 10:45 optee_examples
+       drwxrwxr-x 12 tf-a_user tf-a_user 4096 Jul  1 12:13 optee_os
+       drwxrwxr-x  8 tf-a_user tf-a_user 4096 Jul  1 10:45 optee_test
+       drwxrwxr-x  7 tf-a_user tf-a_user 4096 Jul  1 10:45 .repo
+       drwxrwxr-x  4 tf-a_user tf-a_user 4096 Jul  1 12:12 toolchains
+       drwxrwxr-x 21 tf-a_user tf-a_user 4096 Jul  1 12:15 trusted-firmware-a
+
+(3) Now enter into ``ms-tpm-20-ref`` and get its dependencies:
+
+   .. code:: shell
+
+      $ cd ms-tpm-20-ref
+      $ git submodule init
+      $ git submodule update
+      Submodule path 'external/wolfssl': checked out '9c87f979a7f1d3a6d786b260653d566c1d31a1c4'
+
+(4) Now, you should be able to continue with step 5 in "`Get and build the solution`_"
+    instructions. In order to enable support for Measured Boot, you need to
+    set the ``MEASURED_BOOT`` build option:
+
+    .. code:: shell
+
+       $ MEASURED_BOOT=y make -j `nproc`
+
+    .. note::
+       The build process will likely take a long time. It is strongly recommended to
+       pass the ``-j`` option to make to run the process faster.
+
+   After this step, you should be ready to run the image.
+
+Running and using the PoC on the Armv8-A Foundation AEM FVP
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+With everything built, you can now run the image:
+
+.. code:: shell
+
+   $ make run-only
+
+.. note::
+   Using ``make run`` will build and run the image and it can be used instead
+   of simply ``make``. However, once the image is built, it is recommended to
+   use ``make run-only`` to avoid re-running all the building rules, which
+   would take time.
+
+When FVP is launched, two terminal windows will appear. ``FVP terminal_0``
+is the userspace terminal whereas ``FVP terminal_1`` is the counterpart for
+the secure world (where TAs will print their logs, for instance).
+
+Log into the image shell with user ``root``, no password will be required.
+Then we can issue the ``ftpm`` command, which is an alias that
+
+(1) loads the ftpm kernel module and
+
+(2) calls ``tpm2_pcrread``, which will access the fTPM service to read the
+    PCRs.
+
+When loading the ftpm kernel module, the fTPM TA is loaded into the secure
+world. This TA then requests a copy of the Event Log generated during the
+booting process so it can retrieve all the entries on the log and record them
+first thing.
+
+.. note::
+   For this PoC, nothing loaded after BL33 and NT_FW_CONFIG is recorded
+   in the Event Log.
+
+The secure world terminal should show the debug logs for the fTPM service,
+including all the measurements available in the Event Log as they are being
+processed:
+
+.. code:: shell
+
+	M/TA: Preparing to extend the following TPM Event Log:
+	M/TA: TCG_EfiSpecIDEvent:
+	M/TA:   PCRIndex           : 0
+	M/TA:   EventType          : 3
+	M/TA:   Digest             : 00
+	M/TA: 			   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+	M/TA: 			   : 00 00 00
+	M/TA:   EventSize          : 33
+	M/TA:   Signature          : Spec ID Event03
+	M/TA:   PlatformClass      : 0
+	M/TA:   SpecVersion        : 2.0.2
+	M/TA:   UintnSize          : 1
+	M/TA:   NumberOfAlgorithms : 1
+	M/TA:   DigestSizes        :
+	M/TA:     #0 AlgorithmId   : SHA256
+	M/TA:        DigestSize    : 32
+	M/TA:   VendorInfoSize     : 0
+	M/TA: PCR_Event2:
+	M/TA:   PCRIndex           : 0
+	M/TA:   EventType          : 3
+	M/TA:   Digests Count      : 1
+	M/TA:     #0 AlgorithmId   : SHA256
+	M/TA:        Digest        : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+	M/TA: 			   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+	M/TA:   EventSize          : 17
+	M/TA:   Signature          : StartupLocality
+	M/TA:   StartupLocality    : 0
+	M/TA: PCR_Event2:
+	M/TA:   PCRIndex           : 0
+	M/TA:   EventType          : 1
+	M/TA:   Digests Count      : 1
+	M/TA:     #0 AlgorithmId   : SHA256
+	M/TA:        Digest        : 58 26 32 6e 64 45 64 da 45 de 35 db 96 fd ed 63
+	M/TA: 			   : 2a 6a d4 0d aa 94 b0 b1 55 e4 72 e7 1f 0a e0 d5
+	M/TA:   EventSize          : 5
+	M/TA:   Event              : BL_2
+	M/TA: PCR_Event2:
+	M/TA:   PCRIndex           : 0
+	M/TA:   EventType          : 1
+	M/TA:   Digests Count      : 1
+	M/TA:     #0 AlgorithmId   : SHA256
+	M/TA:        Digest        : cf f9 7d a3 5c 73 ac cb 7b a0 25 80 6a 6e 50 a5
+	M/TA: 			   : 6b 2e d2 8c c9 36 92 7d 46 c5 b9 c3 a4 6c 51 7c
+	M/TA:   EventSize          : 6
+	M/TA:   Event              : BL_31
+	M/TA: PCR_Event2:
+	M/TA:   PCRIndex           : 0
+	M/TA:   EventType          : 1
+	M/TA:   Digests Count      : 1
+	M/TA:     #0 AlgorithmId   : SHA256
+	M/TA:        Digest        : 23 b0 a3 5d 54 d9 43 1a 5c b9 89 63 1c da 06 c2
+	M/TA: 			   : e5 de e7 7e 99 17 52 12 7d f7 45 ca 4f 4a 39 c0
+	M/TA:   EventSize          : 10
+	M/TA:   Event              : HW_CONFIG
+	M/TA: PCR_Event2:
+	M/TA:   PCRIndex           : 0
+	M/TA:   EventType          : 1
+	M/TA:   Digests Count      : 1
+	M/TA:     #0 AlgorithmId   : SHA256
+	M/TA:        Digest        : 4e e4 8e 5a e6 50 ed e0 b5 a3 54 8a 1f d6 0e 8a
+	M/TA: 			   : ea 0e 71 75 0e a4 3f 82 76 ce af cd 7c b0 91 e0
+	M/TA:   EventSize          : 14
+	M/TA:   Event              : SOC_FW_CONFIG
+	M/TA: PCR_Event2:
+	M/TA:   PCRIndex           : 0
+	M/TA:   EventType          : 1
+	M/TA:   Digests Count      : 1
+	M/TA:     #0 AlgorithmId   : SHA256
+	M/TA:        Digest        : 01 b0 80 47 a1 ce 86 cd df 89 d2 1f 2e fc 6c 22
+	M/TA: 			   : f8 19 ec 6e 1e ec 73 ba 5a be d0 96 e3 5f 6d 75
+	M/TA:   EventSize          : 6
+	M/TA:   Event              : BL_32
+	M/TA: PCR_Event2:
+	M/TA:   PCRIndex           : 0
+	M/TA:   EventType          : 1
+	M/TA:   Digests Count      : 1
+	M/TA:     #0 AlgorithmId   : SHA256
+	M/TA:        Digest        : 5d c6 ef 35 5a 90 81 b4 37 e6 3b 52 da 92 ab 8e
+	M/TA: 			   : d9 6e 93 98 2d 40 87 96 1b 5a a7 ee f1 f4 40 63
+	M/TA:   EventSize          : 18
+	M/TA:   Event              : BL32_EXTRA1_IMAGE
+	M/TA: PCR_Event2:
+	M/TA:   PCRIndex           : 0
+	M/TA:   EventType          : 1
+	M/TA:   Digests Count      : 1
+	M/TA:     #0 AlgorithmId   : SHA256
+	M/TA:        Digest        : 39 b7 13 b9 93 db 32 2f 1b 48 30 eb 2c f2 5c 25
+	M/TA: 			   : 00 0f 38 dc 8e c8 02 cd 79 f2 48 d2 2c 25 ab e2
+	M/TA:   EventSize          : 6
+	M/TA:   Event              : BL_33
+	M/TA: PCR_Event2:
+	M/TA:   PCRIndex           : 0
+	M/TA:   EventType          : 1
+	M/TA:   Digests Count      : 1
+	M/TA:     #0 AlgorithmId   : SHA256
+	M/TA:        Digest        : 25 10 60 5d d4 bc 9d 82 7a 16 9f 8a cc 47 95 a6
+	M/TA: 			   : fd ca a0 c1 2b c9 99 8f 51 20 ff c6 ed 74 68 5a
+	M/TA:   EventSize          : 13
+	M/TA:   Event              : NT_FW_CONFIG
+
+These logs correspond to the measurements stored by TF-A during the measured
+boot process and therefore, they should match the logs dumped by the former
+during the boot up process. These can be seen on the terminal_0:
+
+.. code:: shell
+
+	NOTICE:  Booting Trusted Firmware
+	NOTICE:  BL1: v2.5(release):v2.5
+	NOTICE:  BL1: Built : 10:41:20, Jul  2 2021
+	NOTICE:  BL1: Booting BL2
+	NOTICE:  BL2: v2.5(release):v2.5
+	NOTICE:  BL2: Built : 10:41:20, Jul  2 2021
+	NOTICE:  TCG_EfiSpecIDEvent:
+	NOTICE:    PCRIndex           : 0
+	NOTICE:    EventType          : 3
+	NOTICE:    Digest             : 00
+	NOTICE:  		      : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+	NOTICE:  		      : 00 00 00
+	NOTICE:    EventSize          : 33
+	NOTICE:    Signature          : Spec ID Event03
+	NOTICE:    PlatformClass      : 0
+	NOTICE:    SpecVersion        : 2.0.2
+	NOTICE:    UintnSize          : 1
+	NOTICE:    NumberOfAlgorithms : 1
+	NOTICE:    DigestSizes        :
+	NOTICE:      #0 AlgorithmId   : SHA256
+	NOTICE:         DigestSize    : 32
+	NOTICE:    VendorInfoSize     : 0
+	NOTICE:  PCR_Event2:
+	NOTICE:    PCRIndex           : 0
+	NOTICE:    EventType          : 3
+	NOTICE:    Digests Count      : 1
+	NOTICE:      #0 AlgorithmId   : SHA256
+	NOTICE:         Digest        : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+	NOTICE:  		      : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+	NOTICE:    EventSize          : 17
+	NOTICE:    Signature          : StartupLocality
+	NOTICE:    StartupLocality    : 0
+	NOTICE:  PCR_Event2:
+	NOTICE:    PCRIndex           : 0
+	NOTICE:    EventType          : 1
+	NOTICE:    Digests Count      : 1
+	NOTICE:      #0 AlgorithmId   : SHA256
+	NOTICE:         Digest        : 58 26 32 6e 64 45 64 da 45 de 35 db 96 fd ed 63
+	NOTICE:  		      : 2a 6a d4 0d aa 94 b0 b1 55 e4 72 e7 1f 0a e0 d5
+	NOTICE:    EventSize          : 5
+	NOTICE:    Event              : BL_2
+	NOTICE:  PCR_Event2:
+	NOTICE:    PCRIndex           : 0
+	NOTICE:    EventType          : 1
+	NOTICE:    Digests Count      : 1
+	NOTICE:      #0 AlgorithmId   : SHA256
+	NOTICE:         Digest        : cf f9 7d a3 5c 73 ac cb 7b a0 25 80 6a 6e 50 a5
+	NOTICE:  		      : 6b 2e d2 8c c9 36 92 7d 46 c5 b9 c3 a4 6c 51 7c
+	NOTICE:    EventSize          : 6
+	NOTICE:    Event              : BL_31
+	NOTICE:  PCR_Event2:
+	NOTICE:    PCRIndex           : 0
+	NOTICE:    EventType          : 1
+	NOTICE:    Digests Count      : 1
+	NOTICE:      #0 AlgorithmId   : SHA256
+	NOTICE:         Digest        : 23 b0 a3 5d 54 d9 43 1a 5c b9 89 63 1c da 06 c2
+	NOTICE:  		      : e5 de e7 7e 99 17 52 12 7d f7 45 ca 4f 4a 39 c0
+	NOTICE:    EventSize          : 10
+	NOTICE:    Event              : HW_CONFIG
+	NOTICE:  PCR_Event2:
+	NOTICE:    PCRIndex           : 0
+	NOTICE:    EventType          : 1
+	NOTICE:    Digests Count      : 1
+	NOTICE:      #0 AlgorithmId   : SHA256
+	NOTICE:         Digest        : 4e e4 8e 5a e6 50 ed e0 b5 a3 54 8a 1f d6 0e 8a
+	NOTICE:  		      : ea 0e 71 75 0e a4 3f 82 76 ce af cd 7c b0 91 e0
+	NOTICE:    EventSize          : 14
+	NOTICE:    Event              : SOC_FW_CONFIG
+	NOTICE:  PCR_Event2:
+	NOTICE:    PCRIndex           : 0
+	NOTICE:    EventType          : 1
+	NOTICE:    Digests Count      : 1
+	NOTICE:      #0 AlgorithmId   : SHA256
+	NOTICE:         Digest        : 01 b0 80 47 a1 ce 86 cd df 89 d2 1f 2e fc 6c 22
+	NOTICE:  		      : f8 19 ec 6e 1e ec 73 ba 5a be d0 96 e3 5f 6d 75
+	NOTICE:    EventSize          : 6
+	NOTICE:    Event              : BL_32
+	NOTICE:  PCR_Event2:
+	NOTICE:    PCRIndex           : 0
+	NOTICE:    EventType          : 1
+	NOTICE:    Digests Count      : 1
+	NOTICE:      #0 AlgorithmId   : SHA256
+	NOTICE:         Digest        : 5d c6 ef 35 5a 90 81 b4 37 e6 3b 52 da 92 ab 8e
+	NOTICE:  		      : d9 6e 93 98 2d 40 87 96 1b 5a a7 ee f1 f4 40 63
+	NOTICE:    EventSize          : 18
+	NOTICE:    Event              : BL32_EXTRA1_IMAGE
+	NOTICE:  PCR_Event2:
+	NOTICE:    PCRIndex           : 0
+	NOTICE:    EventType          : 1
+	NOTICE:    Digests Count      : 1
+	NOTICE:      #0 AlgorithmId   : SHA256
+	NOTICE:         Digest        : 39 b7 13 b9 93 db 32 2f 1b 48 30 eb 2c f2 5c 25
+	NOTICE:  		      : 00 0f 38 dc 8e c8 02 cd 79 f2 48 d2 2c 25 ab e2
+	NOTICE:    EventSize          : 6
+	NOTICE:    Event              : BL_33
+	NOTICE:  PCR_Event2:
+	NOTICE:    PCRIndex           : 0
+	NOTICE:    EventType          : 1
+	NOTICE:    Digests Count      : 1
+	NOTICE:      #0 AlgorithmId   : SHA256
+	NOTICE:         Digest        : 25 10 60 5d d4 bc 9d 82 7a 16 9f 8a cc 47 95 a6
+	NOTICE:  		      : fd ca a0 c1 2b c9 99 8f 51 20 ff c6 ed 74 68 5a
+	NOTICE:    EventSize          : 13
+	NOTICE:    Event              : NT_FW_CONFIG
+	NOTICE:  BL1: Booting BL31
+	NOTICE:  BL31: v2.5(release):v2.5
+	NOTICE:  BL31: Built : 10:41:20, Jul  2 2021
+
+Following up with the fTPM startup process, we can see that all the
+measurements in the Event Log are extended and recorded in the appropriate PCR:
+
+.. code:: shell
+
+	M/TA: TPM2_PCR_EXTEND_COMMAND returned value:
+	M/TA: 	ret_tag = 0x8002, size = 0x00000013, rc = 0x00000000
+	M/TA: TPM2_PCR_EXTEND_COMMAND returned value:
+	M/TA: 	ret_tag = 0x8002, size = 0x00000013, rc = 0x00000000
+	M/TA: TPM2_PCR_EXTEND_COMMAND returned value:
+	M/TA: 	ret_tag = 0x8002, size = 0x00000013, rc = 0x00000000
+	M/TA: TPM2_PCR_EXTEND_COMMAND returned value:
+	M/TA: 	ret_tag = 0x8002, size = 0x00000013, rc = 0x00000000
+	M/TA: TPM2_PCR_EXTEND_COMMAND returned value:
+	M/TA: 	ret_tag = 0x8002, size = 0x00000013, rc = 0x00000000
+	M/TA: TPM2_PCR_EXTEND_COMMAND returned value:
+	M/TA: 	ret_tag = 0x8002, size = 0x00000013, rc = 0x00000000
+	M/TA: TPM2_PCR_EXTEND_COMMAND returned value:
+	M/TA: 	ret_tag = 0x8002, size = 0x00000013, rc = 0x00000000
+	M/TA: TPM2_PCR_EXTEND_COMMAND returned value:
+	M/TA: 	ret_tag = 0x8002, size = 0x00000013, rc = 0x00000000
+	M/TA: TPM2_PCR_EXTEND_COMMAND returned value:
+	M/TA: 	ret_tag = 0x8002, size = 0x00000013, rc = 0x00000000
+	M/TA: 9 Event logs processed
+
+After the fTPM TA is loaded, the call to ``insmod`` issued by the ``ftpm``
+alias to load the ftpm kernel module returns, and then the TPM PCRs are read
+by means of ``tpm_pcrread`` command. Note that we are only interested in the
+SHA256 logs here, as this is the algorithm we used on TF-A for the measurements
+(see the field ``AlgorithmId`` on the logs above):
+
+.. code:: shell
+
+	sha256:
+	0 : 0xA6EB3A7417B8CFA9EBA2E7C22AD5A4C03CDB8F3FBDD7667F9C3EF2EA285A8C9F
+	1 : 0x0000000000000000000000000000000000000000000000000000000000000000
+	2 : 0x0000000000000000000000000000000000000000000000000000000000000000
+	3 : 0x0000000000000000000000000000000000000000000000000000000000000000
+	4 : 0x0000000000000000000000000000000000000000000000000000000000000000
+	5 : 0x0000000000000000000000000000000000000000000000000000000000000000
+	6 : 0x0000000000000000000000000000000000000000000000000000000000000000
+	7 : 0x0000000000000000000000000000000000000000000000000000000000000000
+	8 : 0x0000000000000000000000000000000000000000000000000000000000000000
+	9 : 0x0000000000000000000000000000000000000000000000000000000000000000
+	10: 0x0000000000000000000000000000000000000000000000000000000000000000
+	11: 0x0000000000000000000000000000000000000000000000000000000000000000
+	12: 0x0000000000000000000000000000000000000000000000000000000000000000
+	13: 0x0000000000000000000000000000000000000000000000000000000000000000
+	14: 0x0000000000000000000000000000000000000000000000000000000000000000
+	15: 0x0000000000000000000000000000000000000000000000000000000000000000
+	16: 0x0000000000000000000000000000000000000000000000000000000000000000
+	17: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+	18: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+	19: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+	20: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+	21: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+	22: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+	23: 0x0000000000000000000000000000000000000000000000000000000000000000
+
+In this PoC we are only interested in PCR0, which must be non-null. This is
+because the boot process records all the images in this PCR (see field ``PCRIndex``
+on the Event Log above). The rest of the records must be 0 at this point.
+
+.. note::
+   The fTPM service used has support only for 16 PCRs, therefore the content
+   of PCRs above 15 can be ignored.
+
+.. note::
+   As stated earlier, Arm does not provide an fTPM implementation and therefore
+   we do not validate here if the content of PCR0 is correct or not. For this
+   PoC, we are only focused on the fact that the event log could be passed to a third
+   party fTPM and its records were properly extended.
+
+Fine-tuning the fTPM TA
+~~~~~~~~~~~~~~~~~~~~~~~
+
+As stated earlier, the OP-TEE Toolkit includes support to build a third party fTPM
+service. The build options for this service are tailored for the PoC and defined in
+the build environment variable ``FTPM_FLAGS`` (see ``<toolkit_home>/build/common.mk``)
+but they can be modified if needed to better adapt it to a specific scenario.
+
+The most relevant options for Measured Boot support are:
+
+   - **CFG_TA_DEBUG**: Enables debug logs in the Terminal_1 console.
+   - **CFG_TEE_TA_LOG_LEVEL**: Defines the log level used for the debug messages.
+   - **CFG_TA_MEASURED_BOOT**: Enables support for measured boot on the fTPM.
+   - **CFG_TA_EVENT_LOG_SIZE**: Defines the size, in bytes, of the larger event log that
+     the fTPM is able to store, as this buffer is allocated at build time. This must be at
+     least the same as the size of the event log generated by TF-A. If this build option
+     is not defined, the fTPM falls back to a default value of 1024 bytes, which is enough
+     for this PoC, so this variable is not defined in FTPM_FLAGS.
+
+--------------
+
+*Copyright (c) 2021, Arm Limited. All rights reserved.*
+
+.. _OP-TEE Toolkit: https://github.com/OP-TEE/build
+.. _ms-tpm-20-ref: https://github.com/microsoft/ms-tpm-20-ref
+.. _Get and build the solution: https://optee.readthedocs.io/en/latest/building/gits/build.html#get-and-build-the-solution
+.. _Armv8-A Foundation Platform (For Linux Hosts Only): https://developer.arm.com/tools-and-software/simulation-models/fixed-virtual-platforms/arm-ecosystem-models
+.. _tpm2-tools: https://github.com/tpm2-software/tpm2-tools
+.. _TGC event log: https://trustedcomputinggroup.org/resource/tcg-efi-platform-specification/
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index 04e3c0b..7662a14 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -299,6 +299,21 @@
    instrumented. Enabling this option enables the ``ENABLE_PMF`` build option
    as well. Default is 0.
 
+-  ``ENABLE_SME_FOR_NS``: Boolean option to enable Scalable Matrix Extension
+   (SME), SVE, and FPU/SIMD for the non-secure world only. These features share
+   registers so are enabled together. Using this option without
+   ENABLE_SME_FOR_SWD=1 will cause SME, SVE, and FPU/SIMD instructions in secure
+   world to trap to EL3. SME is an optional architectural feature for AArch64
+   and TF-A support is experimental. At this time, this build option cannot be
+   used on systems that have SPD=spmd/SPM_MM or ENABLE_RME, and attempting to
+   build with these options will fail. Default is 0.
+
+-  ``ENABLE_SME_FOR_SWD``: Boolean option to enable the Scalable Matrix
+   Extension for secure world use along with SVE and FPU/SIMD, ENABLE_SME_FOR_NS
+   must also be set to use this. If enabling this, the secure world MUST
+   handle context switching for SME, SVE, and FPU/SIMD registers to ensure that
+   no data is leaked to non-secure world. This is experimental. Default is 0.
+
 -  ``ENABLE_SPE_FOR_LOWER_ELS`` : Boolean option to enable Statistical Profiling
    extensions. This is an optional architectural feature for AArch64.
    The default is 1 but is automatically disabled when the target architecture
@@ -313,8 +328,9 @@
    which are aliased by the SIMD and FP registers. The build option is not
    compatible with the ``CTX_INCLUDE_FPREGS`` build option, and will raise an
    assert on platforms where SVE is implemented and ``ENABLE_SVE_FOR_NS`` set to
-   1. The default is 1 but is automatically disabled when the target
-   architecture is AArch32.
+   1. The default is 1 but is automatically disabled when ENABLE_SME_FOR_NS=1
+   since SME encompasses SVE. At this time, this build option cannot be used on
+   systems that have SPM_MM enabled.
 
 -  ``ENABLE_SVE_FOR_SWD``: Boolean option to enable SVE for the Secure world.
    SVE is an optional architectural feature for AArch64. Note that this option
diff --git a/docs/getting_started/image-terminology.rst b/docs/getting_started/image-terminology.rst
index 5993d6e..a90ec0b 100644
--- a/docs/getting_started/image-terminology.rst
+++ b/docs/getting_started/image-terminology.rst
@@ -92,6 +92,14 @@
 abbreviated name should identify the vendor as well as the image
 function. For example, ``AP_BL3_ARM_RAS``.
 
+Realm Monitor Management Firmware: ``RMM``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This is the Realm-EL2 firmware. It is required if
+:ref:`Realm Management Extension (RME)` feature is enabled. If a path to RMM
+image is not provided, TF-A builds Test Realm Payload (TRP) image by default
+and uses it as the RMM image.
+
 SCP Boot ROM: ``SCP_BL1`` (previously ``BL0``)
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/docs/getting_started/rt-svc-writers-guide.rst b/docs/getting_started/rt-svc-writers-guide.rst
index b3758b8..5a4be4d 100644
--- a/docs/getting_started/rt-svc-writers-guide.rst
+++ b/docs/getting_started/rt-svc-writers-guide.rst
@@ -200,13 +200,13 @@
        SMC_RET1(handle, SMC_UNK);
 
 #. Determining if the requested function is valid for the calling security
-   state. SMC Calls can be made from both the normal and trusted worlds and
+   state. SMC Calls can be made from Non-secure, Secure or Realm worlds and
    the framework will forward all calls to the service handler.
 
    The ``flags`` parameter to this function indicates the caller security state
-   in bit[0], where a value of ``1`` indicates a non-secure caller. The
-   ``is_caller_secure(flags)`` and ``is_caller_non_secure(flags)`` can be used to
-   test this condition.
+   in bits 0 and 5. The ``is_caller_secure(flags)``, ``is_caller_non_secure(flags)``
+   and ``is_caller_realm(flags)`` helper functions can be used to determine whether
+   the caller's security state is Secure, Non-secure or Realm respectively.
 
    If invalid, the request should be completed with:
 
@@ -314,7 +314,7 @@
 
 --------------
 
-*Copyright (c) 2014-2020, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2014-2021, Arm Limited and Contributors. All rights reserved.*
 
 .. _SMCCC: https://developer.arm.com/docs/den0028/latest
 .. _PSCI: http://infocenter.arm.com/help/topic/com.arm.doc.den0022c/DEN0022C_Power_State_Coordination_Interface.pdf
diff --git a/docs/resources/diagrams/arm-cca-software-arch.png b/docs/resources/diagrams/arm-cca-software-arch.png
new file mode 100755
index 0000000..979e083
--- /dev/null
+++ b/docs/resources/diagrams/arm-cca-software-arch.png
Binary files differ
diff --git a/docs/resources/diagrams/ffa-secure-interrupt-handling-nwd.png b/docs/resources/diagrams/ffa-secure-interrupt-handling-nwd.png
new file mode 100755
index 0000000..c318610
--- /dev/null
+++ b/docs/resources/diagrams/ffa-secure-interrupt-handling-nwd.png
Binary files differ
diff --git a/docs/resources/diagrams/ffa-secure-interrupt-handling-swd.png b/docs/resources/diagrams/ffa-secure-interrupt-handling-swd.png
new file mode 100755
index 0000000..b62000d
--- /dev/null
+++ b/docs/resources/diagrams/ffa-secure-interrupt-handling-swd.png
Binary files differ
diff --git a/docs/threat_model/threat_model.rst b/docs/threat_model/threat_model.rst
index 9f26487..4a31e79 100644
--- a/docs/threat_model/threat_model.rst
+++ b/docs/threat_model/threat_model.rst
@@ -6,6 +6,11 @@
 ************************
 This document provides a generic threat model for TF-A firmware.
 
+.. note::
+
+ This threat model doesn't consider Root and Realm worlds introduced by
+ :ref:`Realm Management Extension (RME)`.
+
 ************************
 Target of Evaluation
 ************************
@@ -22,8 +27,10 @@
 - All TF-A images are run from either ROM or on-chip trusted SRAM. This means
   TF-A is not vulnerable to an attacker that can probe or tamper with off-chip
   memory.
+
 - Trusted boot is enabled. This means an attacker can't boot arbitrary images
   that are not approved by platform providers.
+
 - There is no Secure-EL2. We don't consider threats that may come with
   Secure-EL2 software.
 
diff --git a/drivers/arm/gic/v3/gicv3_helpers.c b/drivers/arm/gic/v3/gicv3_helpers.c
index d752013..753d995 100644
--- a/drivers/arm/gic/v3/gicv3_helpers.c
+++ b/drivers/arm/gic/v3/gicv3_helpers.c
@@ -393,3 +393,18 @@
 
 	return count;
 }
+
+unsigned int gicv3_get_component_partnum(const uintptr_t gic_frame)
+{
+	unsigned int part_id;
+
+	/*
+	 * The lower 8 bits of PIDR0, complemented by the lower 4 bits of
+	 * PIDR1 contain a part number identifying the GIC component at a
+	 * particular base address.
+	 */
+	part_id = mmio_read_32(gic_frame + GICD_PIDR0_GICV3) & 0xff;
+	part_id |= (mmio_read_32(gic_frame + GICD_PIDR1_GICV3) << 8) & 0xf00;
+
+	return part_id;
+}
diff --git a/drivers/brcm/emmc/emmc_csl_sdcard.c b/drivers/brcm/emmc/emmc_csl_sdcard.c
index d6ad4bc..9e2c618 100644
--- a/drivers/brcm/emmc/emmc_csl_sdcard.c
+++ b/drivers/brcm/emmc/emmc_csl_sdcard.c
@@ -4,9 +4,11 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <inttypes.h>
+#include <stddef.h>
+#include <stdint.h>
 #include <stdlib.h>
 #include <string.h>
-#include <stddef.h>
 
 #include <arch_helpers.h>
 #include <lib/mmio.h>
@@ -521,7 +523,7 @@
 {
 	int rc = SD_OK;
 
-	VERBOSE("XFER: dest: 0x%llx, addr: 0x%x, size: 0x%x bytes\n",
+	VERBOSE("XFER: dest: 0x%" PRIx64 ", addr: 0x%x, size: 0x%x bytes\n",
 		(uint64_t)base, addr, length);
 
 	if ((length / handle->device->cfg.blockSize) > 1) {
diff --git a/drivers/marvell/amb_adec.c b/drivers/marvell/amb_adec.c
index 1f67105..d78fa25 100644
--- a/drivers/marvell/amb_adec.c
+++ b/drivers/marvell/amb_adec.c
@@ -7,6 +7,9 @@
 
 /* AXI to M-Bridge decoding unit driver for Marvell Armada 8K and 8K+ SoCs */
 
+#include <inttypes.h>
+#include <stdint.h>
+
 #include <common/debug.h>
 #include <lib/mmio.h>
 
@@ -44,10 +47,10 @@
 
 	/* make sure the base address is in 16-bit range */
 	if (win->base_addr > AMB_BASE_ADDR_MASK) {
-		WARN("Window %d: base address is too big 0x%llx\n",
+		WARN("Window %d: base address is too big 0x%" PRIx64 "\n",
 		       win_num, win->base_addr);
 		win->base_addr = AMB_BASE_ADDR_MASK;
-		WARN("Set the base address to 0x%llx\n", win->base_addr);
+		WARN("Set the base address to 0x%" PRIx64 "\n", win->base_addr);
 	}
 
 	base_addr  = win->base_addr << AMB_BASE_OFFSET;
@@ -57,15 +60,15 @@
 		win->base_addr = ALIGN_UP(base_addr, AMB_WIN_ALIGNMENT_1M);
 		WARN("Window %d: base address unaligned to 0x%x\n",
 		       win_num, AMB_WIN_ALIGNMENT_1M);
-		WARN("Align up the base address to 0x%llx\n", win->base_addr);
+		WARN("Align up the base address to 0x%" PRIx64 "\n", win->base_addr);
 	}
 
 	/* size parameter validity check */
 	if (!IS_POWER_OF_2(win->win_size)) {
-		WARN("Window %d: window size is not power of 2 (0x%llx)\n",
+		WARN("Window %d: window size is not power of 2 (0x%" PRIx64 ")\n",
 		       win_num, win->win_size);
 		win->win_size = ROUND_UP_TO_POW_OF_2(win->win_size);
-		WARN("Rounding size to 0x%llx\n", win->win_size);
+		WARN("Rounding size to 0x%" PRIx64 "\n", win->win_size);
 	}
 }
 
diff --git a/drivers/marvell/ccu.c b/drivers/marvell/ccu.c
index b4251f4..c206f11 100644
--- a/drivers/marvell/ccu.c
+++ b/drivers/marvell/ccu.c
@@ -7,6 +7,9 @@
 
 /* CCU unit device driver for Marvell AP807, AP807 and AP810 SoCs */
 
+#include <inttypes.h>
+#include <stdint.h>
+
 #include <common/debug.h>
 #include <drivers/marvell/ccu.h>
 #include <lib/mmio.h>
@@ -84,7 +87,7 @@
 							      win_id));
 			start = ((uint64_t)alr << ADDRESS_SHIFT);
 			end = (((uint64_t)ahr + 0x10) << ADDRESS_SHIFT);
-			printf("\tccu%d    %02x     0x%016llx 0x%016llx\n",
+			printf("\tccu%d    %02x     0x%016" PRIx64 " 0x%016" PRIx64 "\n",
 			       win_id, target_id, start, end);
 		}
 	}
@@ -99,14 +102,14 @@
 	/* check if address is aligned to 1M */
 	if (IS_NOT_ALIGN(win->base_addr, CCU_WIN_ALIGNMENT)) {
 		win->base_addr = ALIGN_UP(win->base_addr, CCU_WIN_ALIGNMENT);
-		NOTICE("%s: Align up the base address to 0x%llx\n",
+		NOTICE("%s: Align up the base address to 0x%" PRIx64 "\n",
 		       __func__, win->base_addr);
 	}
 
 	/* size parameter validity check */
 	if (IS_NOT_ALIGN(win->win_size, CCU_WIN_ALIGNMENT)) {
 		win->win_size = ALIGN_UP(win->win_size, CCU_WIN_ALIGNMENT);
-		NOTICE("%s: Aligning size to 0x%llx\n",
+		NOTICE("%s: Aligning size to 0x%" PRIx64 "\n",
 		       __func__, win->win_size);
 	}
 }
diff --git a/drivers/marvell/comphy/phy-comphy-cp110.c b/drivers/marvell/comphy/phy-comphy-cp110.c
index e7cde75..fa9fe41 100644
--- a/drivers/marvell/comphy/phy-comphy-cp110.c
+++ b/drivers/marvell/comphy/phy-comphy-cp110.c
@@ -8,6 +8,8 @@
 /* Marvell CP110 SoC COMPHY unit driver */
 
 #include <errno.h>
+#include <inttypes.h>
+#include <stdint.h>
 
 #include <common/debug.h>
 #include <drivers/delay_timer.h>
@@ -102,7 +104,7 @@
 	*cp_nr = (((comphy_base & ~0xffffff) - MVEBU_AP_IO_BASE(*ap_nr)) /
 		 MVEBU_CP_OFFSET);
 
-	debug("cp_base 0x%llx, ap_io_base 0x%lx, cp_offset 0x%lx\n",
+	debug("cp_base 0x%" PRIx64 ", ap_io_base 0x%lx, cp_offset 0x%lx\n",
 	       comphy_base, (unsigned long)MVEBU_AP_IO_BASE(*ap_nr),
 	       (unsigned long)MVEBU_CP_OFFSET);
 }
diff --git a/drivers/marvell/gwin.c b/drivers/marvell/gwin.c
index 9d94308..fa59cb0 100644
--- a/drivers/marvell/gwin.c
+++ b/drivers/marvell/gwin.c
@@ -7,6 +7,9 @@
 
 /* GWIN unit device driver for Marvell AP810 SoC */
 
+#include <inttypes.h>
+#include <stdint.h>
+
 #include <common/debug.h>
 #include <drivers/marvell/gwin.h>
 #include <lib/mmio.h>
@@ -49,14 +52,14 @@
 	/* The base is always 64M aligned */
 	if (IS_NOT_ALIGN(win->base_addr, GWIN_ALIGNMENT_64M)) {
 		win->base_addr &= ~(GWIN_ALIGNMENT_64M - 1);
-		NOTICE("%s: Align the base address to 0x%llx\n",
+		NOTICE("%s: Align the base address to 0x%" PRIx64 "\n",
 		       __func__, win->base_addr);
 	}
 
 	/* size parameter validity check */
 	if (IS_NOT_ALIGN(win->win_size, GWIN_ALIGNMENT_64M)) {
 		win->win_size = ALIGN_UP(win->win_size, GWIN_ALIGNMENT_64M);
-		NOTICE("%s: Aligning window size to 0x%llx\n",
+		NOTICE("%s: Aligning window size to 0x%" PRIx64 "\n",
 		       __func__, win->win_size);
 	}
 }
@@ -167,7 +170,7 @@
 			alr = (alr >> ADDRESS_LSHIFT) << ADDRESS_RSHIFT;
 			ahr = mmio_read_32(GWIN_AHR_OFFSET(ap_index, win_num));
 			ahr = (ahr >> ADDRESS_LSHIFT) << ADDRESS_RSHIFT;
-			printf("\tgwin   %d     0x%016llx 0x%016llx\n",
+			printf("\tgwin   %d     0x%016" PRIx64 " 0x%016" PRIx64 "\n",
 			       (cr >> 8) & 0xF, alr, ahr);
 		}
 	}
diff --git a/drivers/marvell/io_win.c b/drivers/marvell/io_win.c
index c4257fa..124382a 100644
--- a/drivers/marvell/io_win.c
+++ b/drivers/marvell/io_win.c
@@ -7,6 +7,9 @@
 
 /* IO Window unit device driver for Marvell AP807, AP807 and AP810 SoCs */
 
+#include <inttypes.h>
+#include <stdint.h>
+
 #include <common/debug.h>
 #include <drivers/marvell/io_win.h>
 #include <lib/mmio.h>
@@ -44,14 +47,14 @@
 	/* check if address is aligned to 1M */
 	if (IS_NOT_ALIGN(win->base_addr, IO_WIN_ALIGNMENT_1M)) {
 		win->base_addr = ALIGN_UP(win->base_addr, IO_WIN_ALIGNMENT_1M);
-		NOTICE("%s: Align up the base address to 0x%llx\n",
+		NOTICE("%s: Align up the base address to 0x%" PRIx64 "\n",
 		       __func__, win->base_addr);
 	}
 
 	/* size parameter validity check */
 	if (IS_NOT_ALIGN(win->win_size, IO_WIN_ALIGNMENT_1M)) {
 		win->win_size = ALIGN_UP(win->win_size, IO_WIN_ALIGNMENT_1M);
-		NOTICE("%s: Aligning size to 0x%llx\n",
+		NOTICE("%s: Aligning size to 0x%" PRIx64 "\n",
 		       __func__, win->win_size);
 	}
 }
@@ -170,7 +173,7 @@
 								win_id));
 			start = ((uint64_t)alr << ADDRESS_SHIFT);
 			end = (((uint64_t)ahr + 0x10) << ADDRESS_SHIFT);
-			printf("\tio-win %d     0x%016llx 0x%016llx\n",
+			printf("\tio-win %d     0x%016" PRIx64 " 0x%016" PRIx64 "\n",
 			       trgt_id, start, end);
 		}
 	}
diff --git a/drivers/marvell/iob.c b/drivers/marvell/iob.c
index 29088aa..1f39395 100644
--- a/drivers/marvell/iob.c
+++ b/drivers/marvell/iob.c
@@ -7,6 +7,9 @@
 
 /* IOW unit device driver for Marvell CP110 and CP115 SoCs */
 
+#include <inttypes.h>
+#include <stdint.h>
+
 #include <arch_helpers.h>
 #include <common/debug.h>
 #include <drivers/marvell/iob.h>
@@ -57,7 +60,7 @@
 		win->base_addr = ALIGN_UP(win->base_addr, IOB_WIN_ALIGNMENT);
 		ERROR("Window %d: base address unaligned to 0x%x\n",
 		      win_num, IOB_WIN_ALIGNMENT);
-		printf("Align up the base address to 0x%llx\n",
+		printf("Align up the base address to 0x%" PRIx64 "\n",
 		       win->base_addr);
 	}
 
@@ -66,7 +69,7 @@
 		win->win_size = ALIGN_UP(win->win_size, IOB_WIN_ALIGNMENT);
 		ERROR("Window %d: window size unaligned to 0x%x\n", win_num,
 		      IOB_WIN_ALIGNMENT);
-		printf("Aligning size to 0x%llx\n", win->win_size);
+		printf("Aligning size to 0x%" PRIx64 "\n", win->win_size);
 	}
 }
 
@@ -130,7 +133,7 @@
 				 */
 				end = start + (16 << 20);
 			}
-			printf("iob   %02d %s   0x%016llx 0x%016llx\n",
+			printf("iob   %02d %s   0x%016" PRIx64 " 0x%016" PRIx64 "\n",
 			       win_id, iob_target_name[target_id],
 			       start, end);
 		}
diff --git a/drivers/marvell/mc_trustzone/mc_trustzone.c b/drivers/marvell/mc_trustzone/mc_trustzone.c
index 52b3006..648bd0e 100644
--- a/drivers/marvell/mc_trustzone/mc_trustzone.c
+++ b/drivers/marvell/mc_trustzone/mc_trustzone.c
@@ -5,6 +5,9 @@
  * https://spdx.org/licenses
  */
 
+#include <inttypes.h>
+#include <stdint.h>
+
 #include <common/debug.h>
 #include <drivers/marvell/addr_map.h>
 #include <lib/mmio.h>
@@ -39,7 +42,7 @@
 	/* map the window size to trustzone register convention */
 	tz_size = fls(TZ_SIZE(win->win_size));
 
-	VERBOSE("%s: window size = 0x%llx maps to tz_size %d\n",
+	VERBOSE("%s: window size = 0x%" PRIx64 " maps to tz_size %d\n",
 		__func__, win->win_size, tz_size);
 	if (tz_size < 0 || tz_size > 31) {
 		ERROR("Using not allowed size for MC TrustZone window %d!\n",
@@ -49,7 +52,7 @@
 
 	if (base & 0xfff) {
 		base = base & ~0xfff;
-		WARN("Attempt to open MC TZ win. at 0x%llx, truncate to 0x%x\n",
+		WARN("Attempt to open MC TZ win. at 0x%" PRIx64 ", truncate to 0x%x\n",
 		     win->base_addr, base);
 	}
 
diff --git a/drivers/mtd/spi-mem/spi_mem.c b/drivers/mtd/spi-mem/spi_mem.c
index 63ea769..010e8b6 100644
--- a/drivers/mtd/spi-mem/spi_mem.c
+++ b/drivers/mtd/spi-mem/spi_mem.c
@@ -5,6 +5,8 @@
  */
 
 #include <assert.h>
+#include <inttypes.h>
+#include <stdint.h>
 
 #include <libfdt.h>
 
@@ -150,7 +152,7 @@
 	const struct spi_bus_ops *ops = spi_slave.ops;
 	int ret;
 
-	VERBOSE("%s: cmd:%x mode:%d.%d.%d.%d addqr:%llx len:%x\n",
+	VERBOSE("%s: cmd:%x mode:%d.%d.%d.%d addqr:%" PRIx64 " len:%x\n",
 		__func__, op->cmd.opcode, op->cmd.buswidth, op->addr.buswidth,
 		op->dummy.buswidth, op->data.buswidth,
 		op->addr.val, op->data.nbytes);
diff --git a/drivers/nxp/ddr/nxp-ddr/ddr.c b/drivers/nxp/ddr/nxp-ddr/ddr.c
index 216e05c..c051b3b 100644
--- a/drivers/nxp/ddr/nxp-ddr/ddr.c
+++ b/drivers/nxp/ddr/nxp-ddr/ddr.c
@@ -5,6 +5,7 @@
  */
 
 #include <errno.h>
+#include <inttypes.h>
 #include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -850,7 +851,7 @@
 	priv->ip_rev = ip_rev;
 
 #ifndef CONFIG_STATIC_DDR
-	INFO("time base %llu ms\n", time_base);
+	INFO("time base %" PRIu64 " ms\n", time_base);
 	debug("Parse DIMM SPD(s)\n");
 	valid_spd_mask = parse_spd(priv);
 
@@ -870,7 +871,7 @@
 #endif
 
 	time = get_timer_val(time_base);
-	INFO("Time after parsing SPD %llu ms\n", time);
+	INFO("Time after parsing SPD %" PRIu64 " ms\n", time);
 	debug("Synthesize configurations\n");
 	ret = synthesize_ctlr(priv);
 	if (ret != 0) {
@@ -911,7 +912,7 @@
 	}
 
 	time = get_timer_val(time_base);
-	INFO("Time before programming controller %llu ms\n", time);
+	INFO("Time before programming controller %" PRIu64 " ms\n", time);
 	debug("Program controller registers\n");
 	ret = write_ddrc_regs(priv);
 	if (ret != 0) {
@@ -924,7 +925,7 @@
 	print_ddr_info(priv->ddr[0]);
 
 	time = get_timer_val(time_base);
-	INFO("Time used by DDR driver %llu ms\n", time);
+	INFO("Time used by DDR driver %" PRIu64 " ms\n", time);
 
 	return dram_size;
 }
diff --git a/drivers/partition/partition.c b/drivers/partition/partition.c
index 68133ea..fdea10d 100644
--- a/drivers/partition/partition.c
+++ b/drivers/partition/partition.c
@@ -5,6 +5,7 @@
  */
 
 #include <assert.h>
+#include <inttypes.h>
 #include <stdio.h>
 #include <string.h>
 
@@ -31,7 +32,7 @@
 			name[len + j] = ' ';
 		}
 		name[EFI_NAMELEN - 1] = '\0';
-		VERBOSE("%d: %s %llx-%llx\n", i + 1, name, list.list[i].start,
+		VERBOSE("%d: %s %" PRIx64 "-%" PRIx64 "\n", i + 1, name, list.list[i].start,
 			list.list[i].start + list.list[i].length - 4);
 	}
 }
diff --git a/drivers/st/spi/stm32_qspi.c b/drivers/st/spi/stm32_qspi.c
index d67f831..4b1a029 100644
--- a/drivers/st/spi/stm32_qspi.c
+++ b/drivers/st/spi/stm32_qspi.c
@@ -4,6 +4,7 @@
  * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
  */
 
+#include <inttypes.h>
 #include <libfdt.h>
 
 #include <platform_def.h>
@@ -244,7 +245,7 @@
 	uint8_t mode = QSPI_CCR_IND_WRITE;
 	int ret;
 
-	VERBOSE("%s: cmd:%x mode:%d.%d.%d.%d addr:%llx len:%x\n",
+	VERBOSE("%s: cmd:%x mode:%d.%d.%d.%d addr:%" PRIx64 " len:%x\n",
 		__func__, op->cmd.opcode, op->cmd.buswidth, op->addr.buswidth,
 		op->dummy.buswidth, op->data.buswidth,
 		op->addr.val, op->data.nbytes);
diff --git a/drivers/usb/usb_device.c b/drivers/usb/usb_device.c
index 8f73a6b..031e678 100644
--- a/drivers/usb/usb_device.c
+++ b/drivers/usb/usb_device.c
@@ -73,8 +73,7 @@
 		break;
 
 	case USB_DESC_TYPE_CONFIGURATION:
-		pbuf = (uint8_t *)pdev->desc->get_config_desc(&len);
-		pbuf[1] = USB_DESC_TYPE_CONFIGURATION;
+		pbuf = pdev->desc->get_config_desc(&len);
 		break;
 
 	case USB_DESC_TYPE_STRING:
@@ -112,12 +111,15 @@
 		break;
 
 	case USB_DESC_TYPE_DEVICE_QUALIFIER:
-		pbuf = (uint8_t *)pdev->desc->get_device_qualifier_desc(&len);
+		pbuf = pdev->desc->get_device_qualifier_desc(&len);
 		break;
 
 	case USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION:
-		pbuf = (uint8_t *)pdev->desc->get_config_desc(&len);
-		pbuf[1] = USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION;
+		if (pdev->desc->get_other_speed_config_desc == NULL) {
+			usb_core_ctl_error(pdev);
+			return;
+		}
+		pbuf = pdev->desc->get_other_speed_config_desc(&len);
 		break;
 
 	default:
diff --git a/fdts/arm_fpga.dts b/fdts/arm_fpga.dts
index b7b4f0e..c0efd09 100644
--- a/fdts/arm_fpga.dts
+++ b/fdts/arm_fpga.dts
@@ -40,7 +40,6 @@
 
 	timer {
 		compatible = "arm,armv8-timer";
-		clock-frequency = <10000000>;
 		interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
 			     <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
 			     <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
@@ -82,7 +81,7 @@
 	dbg_uart: serial@7ff80000 {
 		compatible = "arm,pl011", "arm,primecell";
 		reg = <0x0 0x7ff80000 0x0 0x00001000>;
-		interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>;
+		interrupts = <GIC_SPI 415 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&uartclk>, <&bus_refclk>;
 		clock-names = "uartclk", "apb_pclk";
 	};
@@ -98,5 +97,12 @@
 	/* The GICR size will be adjusted at runtime to match the cores. */
 		      <0x0 0x30040000 0x0 0x00020000>;	/* GICR for one core */
 		interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+
+		its: msi-controller@30040000 {
+			compatible = "arm,gic-v3-its";
+			reg = <0x0 0x30040000 0x0 0x40000>;
+			#msi-cells = <1>;
+			msi-controller;
+		};
 	};
 };
diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h
index 5408acf..0fb4e74 100644
--- a/include/arch/aarch64/arch.h
+++ b/include/arch/aarch64/arch.h
@@ -218,8 +218,8 @@
 #define ID_AA64DFR0_MTPMU_SUPPORTED	ULL(1)
 
 /* ID_AA64ISAR0_EL1 definitions */
-#define ID_AA64ISAR0_RNDR_SHIFT U(60)
-#define ID_AA64ISAR0_RNDR_MASK  ULL(0xf)
+#define ID_AA64ISAR0_RNDR_SHIFT	U(60)
+#define ID_AA64ISAR0_RNDR_MASK	ULL(0xf)
 
 /* ID_AA64ISAR1_EL1 definitions */
 #define ID_AA64ISAR1_EL1	S3_0_C0_C6_1
@@ -286,10 +286,10 @@
 #define ID_AA64MMFR1_EL1_VHE_SHIFT		U(8)
 #define ID_AA64MMFR1_EL1_VHE_MASK		ULL(0xf)
 
-#define ID_AA64MMFR1_EL1_HCX_SHIFT              U(40)
-#define ID_AA64MMFR1_EL1_HCX_MASK               ULL(0xf)
-#define ID_AA64MMFR1_EL1_HCX_SUPPORTED          ULL(0x1)
-#define ID_AA64MMFR1_EL1_HCX_NOT_SUPPORTED      ULL(0x0)
+#define ID_AA64MMFR1_EL1_HCX_SHIFT		U(40)
+#define ID_AA64MMFR1_EL1_HCX_MASK		ULL(0xf)
+#define ID_AA64MMFR1_EL1_HCX_SUPPORTED		ULL(0x1)
+#define ID_AA64MMFR1_EL1_HCX_NOT_SUPPORTED	ULL(0x0)
 
 /* ID_AA64MMFR2_EL1 definitions */
 #define ID_AA64MMFR2_EL1		S3_0_C0_C7_2
@@ -329,6 +329,9 @@
 #define ID_AA64PFR1_MPAM_FRAC_SHIFT	ULL(16)
 #define ID_AA64PFR1_MPAM_FRAC_MASK	ULL(0xf)
 
+#define ID_AA64PFR1_EL1_SME_SHIFT	U(24)
+#define ID_AA64PFR1_EL1_SME_MASK	ULL(0xf)
+
 /* ID_PFR1_EL1 definitions */
 #define ID_PFR1_VIRTEXT_SHIFT	U(12)
 #define ID_PFR1_VIRTEXT_MASK	U(0xf)
@@ -388,6 +391,7 @@
 #define SCTLR_ITFSB_BIT		(ULL(1) << 37)
 #define SCTLR_TCF0_SHIFT	U(38)
 #define SCTLR_TCF0_MASK		ULL(3)
+#define SCTLR_ENTP2_BIT		(ULL(1) << 60)
 
 /* Tag Check Faults in EL0 have no effect on the PE */
 #define	SCTLR_TCF0_NO_EFFECT	U(0)
@@ -442,7 +446,9 @@
 #define SCR_GPF_BIT		(UL(1) << 48)
 #define SCR_TWEDEL_SHIFT	U(30)
 #define SCR_TWEDEL_MASK		ULL(0xf)
-#define SCR_HXEn_BIT            (UL(1) << 38)
+#define SCR_HXEn_BIT		(UL(1) << 38)
+#define SCR_ENTP2_SHIFT		U(41)
+#define SCR_ENTP2_BIT		(UL(1) << SCR_ENTP2_SHIFT)
 #define SCR_AMVOFFEN_BIT	(UL(1) << 35)
 #define SCR_TWEDEn_BIT		(UL(1) << 29)
 #define SCR_ECVEN_BIT		(UL(1) << 28)
@@ -465,7 +471,7 @@
 #define SCR_FIQ_BIT		(UL(1) << 2)
 #define SCR_IRQ_BIT		(UL(1) << 1)
 #define SCR_NS_BIT		(UL(1) << 0)
-#define SCR_VALID_BIT_MASK	U(0x2f8f)
+#define SCR_VALID_BIT_MASK	U(0x24000002F8F)
 #define SCR_RESET_VAL		SCR_RES1_BITS
 
 /* MDCR_EL3 definitions */
@@ -574,23 +580,28 @@
 #define TAM_SHIFT		U(30)
 #define TAM_BIT			(U(1) << TAM_SHIFT)
 #define TTA_BIT			(U(1) << 20)
+#define ESM_BIT			(U(1) << 12)
 #define TFP_BIT			(U(1) << 10)
 #define CPTR_EZ_BIT		(U(1) << 8)
-#define CPTR_EL3_RESET_VAL	(TCPAC_BIT | TAM_BIT | TTA_BIT | TFP_BIT & ~(CPTR_EZ_BIT))
+#define CPTR_EL3_RESET_VAL	((TCPAC_BIT | TAM_BIT | TTA_BIT | TFP_BIT) & \
+				~(CPTR_EZ_BIT | ESM_BIT))
 
 /* CPTR_EL2 definitions */
 #define CPTR_EL2_RES1		((U(1) << 13) | (U(1) << 12) | (U(0x3ff)))
 #define CPTR_EL2_TCPAC_BIT	(U(1) << 31)
 #define CPTR_EL2_TAM_SHIFT	U(30)
 #define CPTR_EL2_TAM_BIT	(U(1) << CPTR_EL2_TAM_SHIFT)
+#define CPTR_EL2_SMEN_MASK	ULL(0x3)
+#define CPTR_EL2_SMEN_SHIFT	U(24)
 #define CPTR_EL2_TTA_BIT	(U(1) << 20)
+#define CPTR_EL2_TSM_BIT	(U(1) << 12)
 #define CPTR_EL2_TFP_BIT	(U(1) << 10)
 #define CPTR_EL2_TZ_BIT		(U(1) << 8)
 #define CPTR_EL2_RESET_VAL	CPTR_EL2_RES1
 
 /* VTCR_EL2 definitions */
-#define VTCR_RESET_VAL         U(0x0)
-#define VTCR_EL2_MSA           (U(1) << 31)
+#define VTCR_RESET_VAL		U(0x0)
+#define VTCR_EL2_MSA		(U(1) << 31)
 
 /* CPSR/SPSR definitions */
 #define DAIF_FIQ_BIT		(U(1) << 0)
@@ -918,6 +929,20 @@
 #define ZCR_EL2_LEN_MASK	U(0xf)
 
 /*******************************************************************************
+ * Definitions for system register interface to SME as needed in EL3
+ ******************************************************************************/
+#define ID_AA64SMFR0_EL1		S3_0_C0_C4_5
+#define SMCR_EL3			S3_6_C1_C2_6
+
+/* ID_AA64SMFR0_EL1 definitions */
+#define ID_AA64SMFR0_EL1_FA64_BIT	(UL(1) << 63)
+
+/* SMCR_ELx definitions */
+#define SMCR_ELX_LEN_SHIFT		U(0)
+#define SMCR_ELX_LEN_MASK		U(0x1ff)
+#define SMCR_ELX_FA64_BIT		(U(1) << 31)
+
+/*******************************************************************************
  * Definitions of MAIR encodings for device and normal memory
  ******************************************************************************/
 /*
@@ -1199,12 +1224,12 @@
 /*******************************************************************************
  * FEAT_HCX - Extended Hypervisor Configuration Register
  ******************************************************************************/
-#define HCRX_EL2                S3_4_C1_C2_2
-#define HCRX_EL2_FGTnXS_BIT     (UL(1) << 4)
-#define HCRX_EL2_FnXS_BIT       (UL(1) << 3)
-#define HCRX_EL2_EnASR_BIT      (UL(1) << 2)
-#define HCRX_EL2_EnALS_BIT      (UL(1) << 1)
-#define HCRX_EL2_EnAS0_BIT      (UL(1) << 0)
+#define HCRX_EL2		S3_4_C1_C2_2
+#define HCRX_EL2_FGTnXS_BIT	(UL(1) << 4)
+#define HCRX_EL2_FnXS_BIT	(UL(1) << 3)
+#define HCRX_EL2_EnASR_BIT	(UL(1) << 2)
+#define HCRX_EL2_EnALS_BIT	(UL(1) << 1)
+#define HCRX_EL2_EnAS0_BIT	(UL(1) << 0)
 
 /*******************************************************************************
  * Definitions for DynamicIQ Shared Unit registers
diff --git a/include/arch/aarch64/arch_helpers.h b/include/arch/aarch64/arch_helpers.h
index 37fa047..733bb23 100644
--- a/include/arch/aarch64/arch_helpers.h
+++ b/include/arch/aarch64/arch_helpers.h
@@ -509,6 +509,9 @@
 DEFINE_RENAME_SYSREG_WRITE_FUNC(zcr_el3, ZCR_EL3)
 DEFINE_RENAME_SYSREG_WRITE_FUNC(zcr_el2, ZCR_EL2)
 
+DEFINE_RENAME_SYSREG_READ_FUNC(id_aa64smfr0_el1, ID_AA64SMFR0_EL1)
+DEFINE_RENAME_SYSREG_RW_FUNCS(smcr_el3, SMCR_EL3)
+
 DEFINE_RENAME_SYSREG_READ_FUNC(erridr_el1, ERRIDR_EL1)
 DEFINE_RENAME_SYSREG_WRITE_FUNC(errselr_el1, ERRSELR_EL1)
 
diff --git a/include/arch/aarch64/el3_common_macros.S b/include/arch/aarch64/el3_common_macros.S
index 8e8d334..f29def7 100644
--- a/include/arch/aarch64/el3_common_macros.S
+++ b/include/arch/aarch64/el3_common_macros.S
@@ -222,6 +222,9 @@
 	 *
 	 * CPTR_EL3.EZ: Set to zero so that all SVE functionality is trapped
 	 *  to EL3 by default.
+	 *
+	 * CPTR_EL3.ESM: Set to zero so that all SME functionality is trapped
+	 *  to EL3 by default.
 	 */
 
 	mov_imm x0, (CPTR_EL3_RESET_VAL & ~(TCPAC_BIT | TTA_BIT | TFP_BIT))
diff --git a/include/common/fdt_fixup.h b/include/common/fdt_fixup.h
index 2e9d49d..7a590b2 100644
--- a/include/common/fdt_fixup.h
+++ b/include/common/fdt_fixup.h
@@ -7,13 +7,15 @@
 #ifndef FDT_FIXUP_H
 #define FDT_FIXUP_H
 
+#define INVALID_BASE_ADDR	((uintptr_t)~0UL)
+
 int dt_add_psci_node(void *fdt);
 int dt_add_psci_cpu_enable_methods(void *fdt);
 int fdt_add_reserved_memory(void *dtb, const char *node_name,
 			    uintptr_t base, size_t size);
 int fdt_add_cpus_node(void *dtb, unsigned int afflv0,
 		      unsigned int afflv1, unsigned int afflv2);
-int fdt_adjust_gic_redist(void *dtb, unsigned int nr_cores,
+int fdt_adjust_gic_redist(void *dtb, unsigned int nr_cores, uintptr_t gicr_base,
 			  unsigned int gicr_frame_size);
 
 #endif /* FDT_FIXUP_H */
diff --git a/include/drivers/arm/arm_gicv3_common.h b/include/drivers/arm/arm_gicv3_common.h
index e5df311..d1e93be 100644
--- a/include/drivers/arm/arm_gicv3_common.h
+++ b/include/drivers/arm/arm_gicv3_common.h
@@ -21,4 +21,8 @@
 #define IIDR_MODEL_ARM_GIC_600AE	U(0x0300043b)
 #define IIDR_MODEL_ARM_GIC_700		U(0x0400043b)
 
+#define PIDR_COMPONENT_ARM_DIST		U(0x492)
+#define PIDR_COMPONENT_ARM_REDIST	U(0x493)
+#define PIDR_COMPONENT_ARM_ITS		U(0x494)
+
 #endif /* ARM_GICV3_COMMON_H */
diff --git a/include/drivers/arm/gicv3.h b/include/drivers/arm/gicv3.h
index fa8946b..5efefb6 100644
--- a/include/drivers/arm/gicv3.h
+++ b/include/drivers/arm/gicv3.h
@@ -104,6 +104,8 @@
 #define GICD_IROUTER		U(0x6000)
 #define GICD_IROUTERE		U(0x8000)
 
+#define GICD_PIDR0_GICV3	U(0xffe0)
+#define GICD_PIDR1_GICV3	U(0xffe4)
 #define GICD_PIDR2_GICV3	U(0xffe8)
 
 #define IGRPMODR_SHIFT		5
@@ -301,6 +303,8 @@
 #define GITS_CTLR_ENABLED_BIT		BIT_32(0)
 #define GITS_CTLR_QUIESCENT_BIT		BIT_32(1)
 
+#define GITS_TYPER_VSGI			BIT_64(39)
+
 #ifndef __ASSEMBLER__
 
 #include <stdbool.h>
@@ -324,6 +328,8 @@
 #endif
 }
 
+unsigned int gicv3_get_component_partnum(const uintptr_t gic_frame);
+
 static inline bool gicv3_is_intr_id_special_identifier(unsigned int id)
 {
 	return (id >= PENDING_G1S_INTID) && (id <= GIC_SPURIOUS_INTERRUPT);
diff --git a/include/drivers/usb_device.h b/include/drivers/usb_device.h
index e21e315..8fdb6ae 100644
--- a/include/drivers/usb_device.h
+++ b/include/drivers/usb_device.h
@@ -166,6 +166,8 @@
 	uint8_t *(*get_usr_desc)(uint8_t index, uint16_t *length);
 	uint8_t *(*get_config_desc)(uint16_t *length);
 	uint8_t *(*get_device_qualifier_desc)(uint16_t *length);
+	/* optional: high speed capable device operating at its other speed */
+	uint8_t *(*get_other_speed_config_desc)(uint16_t *length);
 };
 
 /* USB Device handle structure */
diff --git a/include/lib/cpus/aarch64/neoverse_n2.h b/include/lib/cpus/aarch64/neoverse_n2.h
index f414cb5..a1e676e 100644
--- a/include/lib/cpus/aarch64/neoverse_n2.h
+++ b/include/lib/cpus/aarch64/neoverse_n2.h
@@ -28,6 +28,7 @@
  ******************************************************************************/
 #define NEOVERSE_N2_CPUACTLR_EL1			S3_0_C15_C1_0
 #define NEOVERSE_N2_CPUACTLR_EL1_BIT_46			(ULL(1) << 46)
+#define NEOVERSE_N2_CPUACTLR_EL1_BIT_22			(ULL(1) << 22)
 
 /*******************************************************************************
  * CPU Auxiliary Control register 2 specific definitions.
@@ -40,6 +41,8 @@
  ******************************************************************************/
 #define NEOVERSE_N2_CPUACTLR5_EL1			S3_0_C15_C8_0
 #define NEOVERSE_N2_CPUACTLR5_EL1_BIT_44		(ULL(1) << 44)
+#define NEOVERSE_N2_CPUACTLR5_EL1_BIT_13		(ULL(1) << 13)
+#define NEOVERSE_N2_CPUACTLR5_EL1_BIT_17		(ULL(1) << 17)
 
 /*******************************************************************************
  * CPU Auxiliary Control register specific definitions.
diff --git a/include/lib/extensions/sme.h b/include/lib/extensions/sme.h
new file mode 100644
index 0000000..893f9f2
--- /dev/null
+++ b/include/lib/extensions/sme.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SME_H
+#define SME_H
+
+#include <stdbool.h>
+
+#include <context.h>
+
+/*
+ * Maximum value of LEN field in SMCR_ELx. This is different than the maximum
+ * supported value which is platform dependent. In the first version of SME the
+ * LEN field is limited to 4 bits but will be expanded in future iterations.
+ * To support different versions, the code that discovers the supported vector
+ * lengths will write the max value into SMCR_ELx then read it back to see how
+ * many bits are implemented.
+ */
+#define SME_SMCR_LEN_MAX	U(0x1FF)
+
+void sme_enable(cpu_context_t *context);
+void sme_disable(cpu_context_t *context);
+
+#endif /* SME_H */
diff --git a/include/lib/extensions/sve.h b/include/lib/extensions/sve.h
index c85e08c..4b66cdb 100644
--- a/include/lib/extensions/sve.h
+++ b/include/lib/extensions/sve.h
@@ -10,5 +10,6 @@
 #include <context.h>
 
 void sve_enable(cpu_context_t *context);
+void sve_disable(cpu_context_t *context);
 
 #endif /* SVE_H */
diff --git a/include/lib/libc/aarch32/inttypes_.h b/include/lib/libc/aarch32/inttypes_.h
new file mode 100644
index 0000000..11d2d35
--- /dev/null
+++ b/include/lib/libc/aarch32/inttypes_.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2020 Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+/*
+ * Portions copyright (c) 2020, ARM Limited and Contributors.
+ * All rights reserved.
+ */
+
+#ifndef INTTYPES__H
+#define INTTYPES__H
+
+#define PRId64		"lld"	/* int64_t */
+#define PRIi64		"lli"	/* int64_t */
+#define PRIo64		"llo"	/* int64_t */
+#define PRIu64		"llu"	/* uint64_t */
+#define PRIx64		"llx"	/* uint64_t */
+#define PRIX64		"llX"	/* uint64_t */
+
+#endif /* INTTYPES__H */
diff --git a/include/lib/libc/aarch32/stdint_.h b/include/lib/libc/aarch32/stdint_.h
new file mode 100644
index 0000000..dafe142
--- /dev/null
+++ b/include/lib/libc/aarch32/stdint_.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2020 Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+/*
+ * Portions copyright (c) 2020, ARM Limited and Contributors.
+ * All rights reserved.
+ */
+
+#ifndef STDINT__H
+#define STDINT__H
+
+#define INT64_MAX  LLONG_MAX
+#define INT64_MIN  LLONG_MIN
+#define UINT64_MAX ULLONG_MAX
+
+#define INT64_C(x) x ## LL
+#define UINT64_C(x) x ## ULL
+
+typedef long long int64_t;
+typedef unsigned long long uint64_t;
+typedef long long int64_least_t;
+typedef unsigned long long uint64_least_t;
+typedef long long int64_fast_t;
+typedef unsigned long long uint64_fast_t;
+
+#endif
diff --git a/include/lib/libc/aarch64/inttypes_.h b/include/lib/libc/aarch64/inttypes_.h
new file mode 100644
index 0000000..197d627
--- /dev/null
+++ b/include/lib/libc/aarch64/inttypes_.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2020 Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+/*
+ * Portions copyright (c) 2020, ARM Limited and Contributors.
+ * All rights reserved.
+ */
+
+#ifndef INTTYPES__H
+#define INTTYPES__H
+
+#define PRId64		"ld"	/* int64_t */
+#define PRIi64		"li"	/* int64_t */
+#define PRIo64		"lo"	/* int64_t */
+#define PRIu64		"lu"	/* uint64_t */
+#define PRIx64		"lx"	/* uint64_t */
+#define PRIX64		"lX"	/* uint64_t */
+
+#endif /* INTTYPES__H */
diff --git a/include/lib/libc/aarch64/stdint_.h b/include/lib/libc/aarch64/stdint_.h
new file mode 100644
index 0000000..56e9f1b
--- /dev/null
+++ b/include/lib/libc/aarch64/stdint_.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2020 Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+/*
+ * Portions copyright (c) 2020, ARM Limited and Contributors.
+ * All rights reserved.
+ */
+
+#ifndef STDINT__H
+#define STDINT__H
+
+#define INT64_MAX  LONG_MAX
+#define INT64_MIN  LONG_MIN
+#define UINT64_MAX ULONG_MAX
+
+#define INT64_C(x) x ## L
+#define UINT64_C(x) x ## UL
+
+typedef long int64_t;
+typedef unsigned long uint64_t;
+typedef long int64_least_t;
+typedef unsigned long uint64_least_t;
+typedef long int64_fast_t;
+typedef unsigned long uint64_fast_t;
+
+typedef __int128 int128_t;
+typedef unsigned __int128 uint128_t;
+
+#endif
diff --git a/include/lib/libc/inttypes.h b/include/lib/libc/inttypes.h
new file mode 100644
index 0000000..0f9e8c6
--- /dev/null
+++ b/include/lib/libc/inttypes.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2020 Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+/*
+ * Portions copyright (c) 2020, ARM Limited and Contributors.
+ * All rights reserved.
+ */
+
+#ifndef INTTYPES_H
+#define INTTYPES_H
+
+#include <inttypes_.h>
+#include <stdint.h>
+
+#define PRId8		"d"	/* int8_t */
+#define PRId16		"d"	/* int16_t */
+#define PRId32		"d"	/* int32_t */
+#define PRIdPTR		"d"	/* intptr_t */
+
+#define PRIi8		"i"	/* int8_t */
+#define PRIi16		"i"	/* int16_t */
+#define PRIi32		"i"	/* int32_t */
+#define PRIiPTR		"i"	/* intptr_t */
+
+#define PRIo8		"o"	/* int8_t */
+#define PRIo16		"o"	/* int16_t */
+#define PRIo32		"o"	/* int32_t */
+#define PRIoPTR		"o"	/* intptr_t */
+
+#define PRIu8		"u"	/* uint8_t */
+#define PRIu16		"u"	/* uint16_t */
+#define PRIu32		"u"	/* uint32_t */
+#define PRIuPTR		"u"	/* uintptr_t */
+
+#define PRIx8		"x"	/* uint8_t */
+#define PRIx16		"x"	/* uint16_t */
+#define PRIx32		"x"	/* uint32_t */
+#define PRIxPTR		"x"	/* uintptr_t */
+
+#define PRIX8		"X"	/* uint8_t */
+#define PRIX16		"X"	/* uint16_t */
+#define PRIX32		"X"	/* uint32_t */
+#define PRIXPTR		"X"	/* uintptr_t */
+
+#endif
diff --git a/include/lib/libc/stdint.h b/include/lib/libc/stdint.h
index 818870e..e96a25c 100644
--- a/include/lib/libc/stdint.h
+++ b/include/lib/libc/stdint.h
@@ -12,6 +12,7 @@
 #define STDINT_H
 
 #include <limits.h>
+#include <stdint_.h>
 
 #define INT8_MAX  CHAR_MAX
 #define INT8_MIN  CHAR_MIN
@@ -25,10 +26,6 @@
 #define INT32_MIN  INT_MIN
 #define UINT32_MAX UINT_MAX
 
-#define INT64_MAX  LLONG_MAX
-#define INT64_MIN  LLONG_MIN
-#define UINT64_MAX ULLONG_MAX
-
 #define INT_LEAST8_MIN  INT8_MIN
 #define INT_LEAST8_MAX  INT8_MAX
 #define UINT_LEAST8_MAX UINT8_MAX
@@ -77,12 +74,10 @@
 #define INT8_C(x)  x
 #define INT16_C(x) x
 #define INT32_C(x) x
-#define INT64_C(x) x ## LL
 
 #define UINT8_C(x)  x
 #define UINT16_C(x) x
 #define UINT32_C(x) x ## U
-#define UINT64_C(x) x ## ULL
 
 #define INTMAX_C(x)  x ## LL
 #define UINTMAX_C(x) x ## ULL
@@ -90,32 +85,26 @@
 typedef signed char int8_t;
 typedef short int16_t;
 typedef int int32_t;
-typedef long long int64_t;
 
 typedef unsigned char uint8_t;
 typedef unsigned short uint16_t;
 typedef unsigned int uint32_t;
-typedef unsigned long long uint64_t;
 
 typedef signed char int8_least_t;
 typedef short int16_least_t;
 typedef int int32_least_t;
-typedef long long int64_least_t;
 
 typedef unsigned char uint8_least_t;
 typedef unsigned short uint16_least_t;
 typedef unsigned int uint32_least_t;
-typedef unsigned long long uint64_least_t;
 
 typedef int int8_fast_t;
 typedef int int16_fast_t;
 typedef int int32_fast_t;
-typedef long long int64_fast_t;
 
 typedef unsigned int uint8_fast_t;
 typedef unsigned int uint16_fast_t;
 typedef unsigned int uint32_fast_t;
-typedef unsigned long long uint64_fast_t;
 
 typedef long intptr_t;
 typedef unsigned long uintptr_t;
@@ -130,9 +119,4 @@
 typedef long register_t;
 typedef unsigned long u_register_t;
 
-#ifdef __aarch64__
-typedef __int128 int128_t;
-typedef unsigned __int128 uint128_t;
-#endif /* __aarch64__ */
-
 #endif /* STDINT_H */
diff --git a/include/services/ffa_svc.h b/include/services/ffa_svc.h
index 85ff703..4c049c5 100644
--- a/include/services/ffa_svc.h
+++ b/include/services/ffa_svc.h
@@ -139,6 +139,7 @@
 #define FFA_NOTIFICATION_INFO_GET \
 	FFA_FID(SMC_32, FFA_FNUM_NOTIFICATION_INFO_GET)
 #define FFA_SPM_ID_GET		FFA_FID(SMC_32, FFA_FNUM_SPM_ID_GET)
+#define FFA_NORMAL_WORLD_RESUME	FFA_FID(SMC_32, FFA_FNUM_NORMAL_WORLD_RESUME)
 
 /* FFA SMC64 FIDs */
 #define FFA_ERROR_SMC64		FFA_FID(SMC_64, FFA_FNUM_ERROR)
diff --git a/include/services/rmi_svc.h b/include/services/rmi_svc.h
index 9106f08..22f635b 100644
--- a/include/services/rmi_svc.h
+++ b/include/services/rmi_svc.h
@@ -45,7 +45,7 @@
 #define RMI_FNUM_VERSION_REQ		U(0x00)
 
 #define RMI_FNUM_GRAN_NS_REALM		U(0x01)
-#define RMI_FNUM_GRAN_REALM_NS		U(0x10)
+#define RMI_FNUM_GRAN_REALM_NS		U(0x02)
 
 /* RMI SMC64 FIDs handled by the RMMD */
 #define RMI_RMM_REQ_COMPLETE		RMI_FID(SMC_64, RMI_FNUM_REQ_COMPLETE)
diff --git a/lib/bl_aux_params/bl_aux_params.c b/lib/bl_aux_params/bl_aux_params.c
index 7a8115c..7f357b7 100644
--- a/lib/bl_aux_params/bl_aux_params.c
+++ b/lib/bl_aux_params/bl_aux_params.c
@@ -3,6 +3,8 @@
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
+#include <inttypes.h>
+#include <stdint.h>
 
 #include <common/debug.h>
 #include <lib/coreboot.h>
@@ -25,7 +27,7 @@
 			break;
 #endif
 		default:
-			ERROR("Ignoring unknown BL aux parameter: 0x%llx",
+			ERROR("Ignoring unknown BL aux parameter: 0x%" PRIx64,
 			      p->type);
 			break;
 		}
diff --git a/lib/cpus/aarch64/cortex_a78.S b/lib/cpus/aarch64/cortex_a78.S
index 4e8a228..a1288ba 100644
--- a/lib/cpus/aarch64/cortex_a78.S
+++ b/lib/cpus/aarch64/cortex_a78.S
@@ -227,6 +227,42 @@
 	b	cpu_rev_var_ls
 endfunc check_errata_2132060
 
+/* --------------------------------------------------------------------
+ * Errata Workaround for A78 Erratum 2242635.
+ * This applies to revisions r1p0, r1p1, and r1p2 of the Cortex A78
+ * processor and is still open.
+ * The issue also exists in r0p0 but there is no fix in that revision.
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x17
+ * --------------------------------------------------------------------
+ */
+func errata_a78_2242635_wa
+	/* Compare x0 against revisions r1p0 - r1p2 */
+	mov	x17, x30
+	bl	check_errata_2242635
+	cbz	x0, 1f
+
+	ldr	x0, =0x5
+	msr	S3_6_c15_c8_0, x0 /* CPUPSELR_EL3 */
+	ldr	x0, =0x10F600E000
+	msr	S3_6_c15_c8_2, x0 /* CPUPOR_EL3 */
+	ldr	x0, =0x10FF80E000
+	msr	S3_6_c15_c8_3, x0 /* CPUPMR_EL3 */
+	ldr	x0, =0x80000000003FF
+	msr	S3_6_c15_c8_1, x0 /* CPUPCR_EL3 */
+
+	isb
+1:
+	ret	x17
+endfunc errata_a78_2242635_wa
+
+func check_errata_2242635
+	/* Applies to revisions r1p0 through r1p2. */
+	mov	x1, #CPU_REV(1, 0)
+	mov	x2, #CPU_REV(1, 2)
+	b	cpu_rev_var_range
+endfunc check_errata_2242635
+
 	/* -------------------------------------------------
 	 * The CPU Ops reset function for Cortex-A78
 	 * -------------------------------------------------
@@ -266,6 +302,11 @@
 	bl	errata_a78_2132060_wa
 #endif
 
+#if ERRATA_A78_2242635
+	mov	x0, x18
+	bl	errata_a78_2242635_wa
+#endif
+
 #if ENABLE_AMU
 	/* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */
 	mrs	x0, actlr_el3
@@ -326,6 +367,7 @@
 	report_errata ERRATA_A78_1821534, cortex_a78, 1821534
 	report_errata ERRATA_A78_1952683, cortex_a78, 1952683
 	report_errata ERRATA_A78_2132060, cortex_a78, 2132060
+	report_errata ERRATA_A78_2242635, cortex_a78, 2242635
 
 	ldp	x8, x30, [sp], #16
 	ret
diff --git a/lib/cpus/aarch64/neoverse_n2.S b/lib/cpus/aarch64/neoverse_n2.S
index 330cc59..621aded 100644
--- a/lib/cpus/aarch64/neoverse_n2.S
+++ b/lib/cpus/aarch64/neoverse_n2.S
@@ -184,6 +184,34 @@
 endfunc check_errata_2138956
 
 /* --------------------------------------------------
+ * Errata Workaround for Neoverse N2 Erratum 2242415.
+ * This applies to revision r0p0 of Neoverse N2. it is still open.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x1, x17
+ * --------------------------------------------------
+ */
+func errata_n2_2242415_wa
+	/* Check revision. */
+	mov	x17, x30
+	bl	check_errata_2242415
+	cbz	x0, 1f
+
+	/* Apply instruction patching sequence */
+	mrs	x1, NEOVERSE_N2_CPUACTLR_EL1
+	orr	x1, x1, NEOVERSE_N2_CPUACTLR_EL1_BIT_22
+	msr	NEOVERSE_N2_CPUACTLR_EL1, x1
+1:
+	ret	x17
+endfunc errata_n2_2242415_wa
+
+func check_errata_2242415
+	/* Applies to r0p0 */
+	mov	x1, #0x00
+	b	cpu_rev_var_ls
+endfunc check_errata_2242415
+
+/* --------------------------------------------------
  * Errata Workaround for Neoverse N2 Erratum 2138953.
  * This applies to revision r0p0 of Neoverse N2. it is still open.
  * Inputs:
@@ -212,6 +240,99 @@
 	b	cpu_rev_var_ls
 endfunc check_errata_2138953
 
+/* --------------------------------------------------
+ * Errata Workaround for Neoverse N2 Erratum 2138958.
+ * This applies to revision r0p0 of Neoverse N2. it is still open.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x1, x17
+ * --------------------------------------------------
+ */
+func errata_n2_2138958_wa
+	/* Check revision. */
+	mov	x17, x30
+	bl	check_errata_2138958
+	cbz	x0, 1f
+
+	/* Apply instruction patching sequence */
+	mrs	x1, NEOVERSE_N2_CPUACTLR5_EL1
+	orr	x1, x1, NEOVERSE_N2_CPUACTLR5_EL1_BIT_13
+	msr	NEOVERSE_N2_CPUACTLR5_EL1, x1
+1:
+	ret	x17
+endfunc errata_n2_2138958_wa
+
+func check_errata_2138958
+	/* Applies to r0p0 */
+	mov	x1, #0x00
+	b	cpu_rev_var_ls
+endfunc check_errata_2138958
+
+/* --------------------------------------------------
+ * Errata Workaround for Neoverse N2 Erratum 2242400.
+ * This applies to revision r0p0 of Neoverse N2. it is still open.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x1, x17
+ * --------------------------------------------------
+ */
+func errata_n2_2242400_wa
+	/* Check revision. */
+	mov	x17, x30
+	bl	check_errata_2242400
+	cbz	x0, 1f
+
+	/* Apply instruction patching sequence */
+	mrs	x1, NEOVERSE_N2_CPUACTLR5_EL1
+	orr	x1, x1, NEOVERSE_N2_CPUACTLR5_EL1_BIT_17
+	msr	NEOVERSE_N2_CPUACTLR5_EL1, x1
+	ldr	x0, =0x2
+	msr	S3_6_c15_c8_0, x0
+	ldr	x0, =0x10F600E000
+	msr	S3_6_c15_c8_2, x0
+	ldr	x0, =0x10FF80E000
+	msr	S3_6_c15_c8_3, x0
+	ldr	x0, =0x80000000003FF
+	msr	S3_6_c15_c8_1, x0
+	isb
+1:
+	ret	x17
+endfunc errata_n2_2242400_wa
+
+func check_errata_2242400
+	/* Applies to r0p0 */
+	mov	x1, #0x00
+	b	cpu_rev_var_ls
+endfunc check_errata_2242400
+
+/* --------------------------------------------------
+ * Errata Workaround for Neoverse N2 Erratum 2280757.
+ * This applies to revision r0p0 of Neoverse N2. it is still open.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x1, x17
+ * --------------------------------------------------
+ */
+func errata_n2_2280757_wa
+	/* Check revision. */
+	mov	x17, x30
+	bl	check_errata_2280757
+	cbz	x0, 1f
+
+	/* Apply instruction patching sequence */
+	mrs	x1, NEOVERSE_N2_CPUACTLR_EL1
+	orr	x1, x1, NEOVERSE_N2_CPUACTLR_EL1_BIT_22
+	msr	NEOVERSE_N2_CPUACTLR_EL1, x1
+1:
+	ret	x17
+endfunc errata_n2_2280757_wa
+
+func check_errata_2280757
+	/* Applies to r0p0 */
+	mov	x1, #0x00
+	b	cpu_rev_var_ls
+endfunc check_errata_2280757
+
 	/* -------------------------------------------
 	 * The CPU Ops reset function for Neoverse N2.
 	 * -------------------------------------------
@@ -238,13 +359,13 @@
 #endif
 
 #if ERRATA_N2_2025414
-	mov     x0, x18
-	bl      errata_n2_2025414_wa
+	mov	x0, x18
+	bl	errata_n2_2025414_wa
 #endif
 
 #if ERRATA_N2_2189731
-	mov     x0, x18
-	bl      errata_n2_2189731_wa
+	mov	x0, x18
+	bl	errata_n2_2189731_wa
 #endif
 
 
@@ -258,6 +379,26 @@
 	bl	errata_n2_2138953_wa
 #endif
 
+#if ERRATA_N2_2242415
+	mov	x0, x18
+	bl	errata_n2_2242415_wa
+#endif
+
+#if ERRATA_N2_2138958
+	mov	x0, x18
+	bl	errata_n2_2138958_wa
+#endif
+
+#if ERRATA_N2_2242400
+	mov	x0, x18
+	bl	errata_n2_2242400_wa
+#endif
+
+#if ERRATA_N2_2280757
+	mov	x0, x18
+	bl	errata_n2_2280757_wa
+#endif
+
 #if ENABLE_AMU
 	/* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */
 	mrs	x0, cptr_el3
@@ -324,6 +465,10 @@
 	report_errata ERRATA_N2_2189731, neoverse_n2, 2189731
 	report_errata ERRATA_N2_2138956, neoverse_n2, 2138956
 	report_errata ERRATA_N2_2138953, neoverse_n2, 2138953
+	report_errata ERRATA_N2_2242415, neoverse_n2, 2242415
+	report_errata ERRATA_N2_2138958, neoverse_n2, 2138958
+	report_errata ERRATA_N2_2242400, neoverse_n2, 2242400
+	report_errata ERRATA_N2_2280757, neoverse_n2, 2280757
 
 	ldp	x8, x30, [sp], #16
 	ret
diff --git a/lib/cpus/aarch64/neoverse_v1.S b/lib/cpus/aarch64/neoverse_v1.S
index 200f67d..62a7a30 100644
--- a/lib/cpus/aarch64/neoverse_v1.S
+++ b/lib/cpus/aarch64/neoverse_v1.S
@@ -288,6 +288,43 @@
 	b	cpu_rev_var_ls
 endfunc check_errata_2108267
 
+	/* --------------------------------------------------
+	 * Errata Workaround for Neoverse V1 Errata #2216392.
+	 * This applies to revisions r1p0 and r1p1 and is
+	 * still open.
+	 * This issue is also present in r0p0 but there is no
+	 * workaround in that revision.
+	 * x0: variant[4:7] and revision[0:3] of current cpu.
+	 * Shall clobber: x0-x17
+	 * --------------------------------------------------
+	 */
+func errata_neoverse_v1_2216392_wa
+	/* Check workaround compatibility. */
+	mov	x17, x30
+	bl	check_errata_2216392
+	cbz	x0, 1f
+
+	ldr	x0, =0x5
+	msr	S3_6_c15_c8_0, x0 /* CPUPSELR_EL3 */
+	ldr	x0, =0x10F600E000
+	msr	S3_6_c15_c8_2, x0 /* CPUPOR_EL3 */
+	ldr	x0, =0x10FF80E000
+	msr	S3_6_c15_c8_3, x0 /* CPUPMR_EL3 */
+	ldr	x0, =0x80000000003FF
+	msr	S3_6_c15_c8_1, x0 /* CPUPCR_EL3 */
+
+	isb
+1:
+	ret	x17
+endfunc errata_neoverse_v1_2216392_wa
+
+func check_errata_2216392
+	/* Applies to revisions r1p0 and r1p1. */
+	mov	x1, #CPU_REV(1, 0)
+	mov	x2, #CPU_REV(1, 1)
+	b	cpu_rev_var_range
+endfunc check_errata_2216392
+
 	/* ---------------------------------------------
 	 * HW will do the cache maintenance while powering down
 	 * ---------------------------------------------
@@ -326,6 +363,7 @@
 	report_errata ERRATA_V1_1966096, neoverse_v1, 1966096
 	report_errata ERRATA_V1_2139242, neoverse_v1, 2139242
 	report_errata ERRATA_V1_2108267, neoverse_v1, 2108267
+	report_errata ERRATA_V1_2216392, neoverse_v1, 2216392
 
 	ldp	x8, x30, [sp], #16
 	ret
@@ -379,6 +417,11 @@
 	bl	errata_neoverse_v1_2108267_wa
 #endif
 
+#if ERRATA_V1_2216392
+	mov	x0, x18
+	bl	errata_neoverse_v1_2216392_wa
+#endif
+
 	ret	x19
 endfunc neoverse_v1_reset_func
 
diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk
index 138f7a5..a5b8aae 100644
--- a/lib/cpus/cpu-ops.mk
+++ b/lib/cpus/cpu-ops.mk
@@ -311,25 +311,30 @@
 # well but there is no workaround for that revision.
 ERRATA_A78_1951500	?=0
 
-# Flag to apply erratum 1941500 workaround during reset. This erratum applies
-# to revisions r0p0 and r0p1 of the A78 AE cpu. It is still open.
-ERRATA_A78_AE_1941500	?=0
-
-# Flag to apply erratum 1951502 workaround during reset. This erratum applies
-# to revisions r0p0 and r0p1 of the A78 AE cpu. It is still open.
-ERRATA_A78_AE_1951502	?=0
-
 # Flag to apply erratum 1821534 workaround during reset. This erratum applies
 # to revisions r0p0 and r1p0 of the A78 cpu.
 ERRATA_A78_1821534	?=0
 
 # Flag to apply erratum 1952683 workaround during reset. This erratum applies
 # to revision r0p0 of the A78 cpu and was fixed in the revision r1p0.
-ERRATA_A78_1952683	?=0
+ERRATA_A78_1952683  ?=0
 
 # Flag to apply erratum 2132060 workaround during reset. This erratum applies
 # to revisions r0p0, r1p0, r1p1, and r1p2 of the A78 cpu. It is still open.
-ERRATA_A78_2132060	?=0
+ERRATA_A78_2132060  ?=0
+
+# Flag to apply erratum 2242635 workaround during reset. This erratum applies
+# to revisions r1p0, r1p1, and r1p2 of the A78 cpu and is open. The issue is
+# present in r0p0 as well but there is no workaround for that revision.
+ERRATA_A78_2242635	?=0
+
+# Flag to apply erratum 1941500 workaround during reset. This erratum applies
+# to revisions r0p0 and r0p1 of the A78 AE cpu. It is still open.
+ERRATA_A78_AE_1941500	?=0
+
+# Flag to apply erratum 1951502 workaround during reset. This erratum applies
+# to revisions r0p0 and r0p1 of the A78 AE cpu. It is still open.
+ERRATA_A78_AE_1951502	?=0
 
 # Flag to apply T32 CLREX workaround during reset. This erratum applies
 # only to r0p0 and r1p0 of the Neoverse N1 cpu.
@@ -425,6 +430,11 @@
 # to revisions r0p0, r1p0, and r1p1 of the Neoverse V1 cpu and is still open.
 ERRATA_V1_2108267	?=0
 
+# Flag to apply erratum 2216392 workaround during reset. This erratum applies
+# to revisions r1p0 and r1p1 of the Neoverse V1 cpu and is still open. This
+# issue exists in r0p0 as well but there is no workaround for that revision.
+ERRATA_V1_2216392	?=0
+
 # Flag to apply erratum 1987031 workaround during reset. This erratum applies
 # to revisions r0p0, r1p0 and r2p0 of the Cortex-A710 cpu and is still open.
 ERRATA_A710_1987031	?=0
@@ -461,6 +471,22 @@
 # to revision r0p0 of the Neoverse N2 cpu and is still open.
 ERRATA_N2_2138953	?=0
 
+# Flag to apply erratum 2242415 workaround during reset. This erratum applies
+# to revision r0p0 of the Neoverse N2 cpu and is still open.
+ERRATA_N2_2242415	?=0
+
+# Flag to apply erratum 2138958 workaround during reset. This erratum applies
+# to revision r0p0 of the Neoverse N2 cpu and is still open.
+ERRATA_N2_2138958	?=0
+
+# Flag to apply erratum 2242400 workaround during reset. This erratum applies
+# to revision r0p0 of the Neoverse N2 cpu and is still open.
+ERRATA_N2_2242400	?=0
+
+# Flag to apply erratum 2280757 workaround during reset. This erratum applies
+# to revision r0p0 of the Neoverse N2 cpu and is still open.
+ERRATA_N2_2280757	?=0
+
 # Flag to apply erratum 2055002 workaround during reset. This erratum applies
 # to revision r1p0, r2p0 of the Cortex-A710 cpu and is still open.
 ERRATA_A710_2055002	?=0
@@ -714,14 +740,6 @@
 $(eval $(call assert_boolean,ERRATA_A78_1951500))
 $(eval $(call add_define,ERRATA_A78_1951500))
 
-# Process ERRATA_A78_AE_1941500 flag
-$(eval $(call assert_boolean,ERRATA_A78_AE_1941500))
-$(eval $(call add_define,ERRATA_A78_AE_1941500))
-
-# Process ERRATA_A78_AE_1951502 flag
-$(eval $(call assert_boolean,ERRATA_A78_AE_1951502))
-$(eval $(call add_define,ERRATA_A78_AE_1951502))
-
 # Process ERRATA_A78_1821534 flag
 $(eval $(call assert_boolean,ERRATA_A78_1821534))
 $(eval $(call add_define,ERRATA_A78_1821534))
@@ -734,6 +752,18 @@
 $(eval $(call assert_boolean,ERRATA_A78_2132060))
 $(eval $(call add_define,ERRATA_A78_2132060))
 
+# Process ERRATA_A78_2242635 flag
+$(eval $(call assert_boolean,ERRATA_A78_2242635))
+$(eval $(call add_define,ERRATA_A78_2242635))
+
+# Process ERRATA_A78_AE_1941500 flag
+$(eval $(call assert_boolean,ERRATA_A78_AE_1941500))
+$(eval $(call add_define,ERRATA_A78_AE_1941500))
+
+# Process ERRATA_A78_AE_1951502 flag
+$(eval $(call assert_boolean,ERRATA_A78_AE_1951502))
+$(eval $(call add_define,ERRATA_A78_AE_1951502))
+
 # Process ERRATA_N1_1043202 flag
 $(eval $(call assert_boolean,ERRATA_N1_1043202))
 $(eval $(call add_define,ERRATA_N1_1043202))
@@ -826,6 +856,10 @@
 $(eval $(call assert_boolean,ERRATA_V1_2108267))
 $(eval $(call add_define,ERRATA_V1_2108267))
 
+# Process ERRATA_V1_2216392 flag
+$(eval $(call assert_boolean,ERRATA_V1_2216392))
+$(eval $(call add_define,ERRATA_V1_2216392))
+
 # Process ERRATA_A710_1987031 flag
 $(eval $(call assert_boolean,ERRATA_A710_1987031))
 $(eval $(call add_define,ERRATA_A710_1987031))
@@ -862,6 +896,22 @@
 $(eval $(call assert_boolean,ERRATA_N2_2138953))
 $(eval $(call add_define,ERRATA_N2_2138953))
 
+# Process ERRATA_N2_2242415 flag
+$(eval $(call assert_boolean,ERRATA_N2_2242415))
+$(eval $(call add_define,ERRATA_N2_2242415))
+
+# Process ERRATA_N2_2138958 flag
+$(eval $(call assert_boolean,ERRATA_N2_2138958))
+$(eval $(call add_define,ERRATA_N2_2138958))
+
+# Process ERRATA_N2_2242400 flag
+$(eval $(call assert_boolean,ERRATA_N2_2242400))
+$(eval $(call add_define,ERRATA_N2_2242400))
+
+# Process ERRATA_N2_2280757 flag
+$(eval $(call assert_boolean,ERRATA_N2_2280757))
+$(eval $(call add_define,ERRATA_N2_2280757))
+
 # Process ERRATA_A710_2055002 flag
 $(eval $(call assert_boolean,ERRATA_A710_2055002))
 $(eval $(call add_define,ERRATA_A710_2055002))
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index 0ec7e7e..c69dc95 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -20,6 +20,7 @@
 #include <lib/el3_runtime/pubsub_events.h>
 #include <lib/extensions/amu.h>
 #include <lib/extensions/mpam.h>
+#include <lib/extensions/sme.h>
 #include <lib/extensions/spe.h>
 #include <lib/extensions/sve.h>
 #include <lib/extensions/sys_reg_trace.h>
@@ -28,7 +29,7 @@
 #include <lib/extensions/twed.h>
 #include <lib/utils.h>
 
-static void enable_extensions_secure(cpu_context_t *ctx);
+static void manage_extensions_secure(cpu_context_t *ctx);
 
 /*******************************************************************************
  * Context management library initialisation routine. This library is used by
@@ -219,7 +220,7 @@
 	/* Save the initialized value of CPTR_EL3 register */
 	write_ctx_reg(get_el3state_ctx(ctx), CTX_CPTR_EL3, read_cptr_el3());
 	if (security_state == SECURE) {
-		enable_extensions_secure(ctx);
+		manage_extensions_secure(ctx);
 	}
 
 	/*
@@ -365,7 +366,7 @@
  * When EL2 is implemented but unused `el2_unused` is non-zero, otherwise
  * it is zero.
  ******************************************************************************/
-static void enable_extensions_nonsecure(bool el2_unused, cpu_context_t *ctx)
+static void manage_extensions_nonsecure(bool el2_unused, cpu_context_t *ctx)
 {
 #if IMAGE_BL31
 #if ENABLE_SPE_FOR_LOWER_ELS
@@ -376,7 +377,11 @@
 	amu_enable(el2_unused, ctx);
 #endif
 
-#if ENABLE_SVE_FOR_NS
+#if ENABLE_SME_FOR_NS
+	/* Enable SME, SVE, and FPU/SIMD for non-secure world. */
+	sme_enable(ctx);
+#elif ENABLE_SVE_FOR_NS
+	/* Enable SVE and FPU/SIMD for non-secure world. */
 	sve_enable(ctx);
 #endif
 
@@ -395,20 +400,45 @@
 #if ENABLE_TRF_FOR_NS
 	trf_enable();
 #endif /* ENABLE_TRF_FOR_NS */
-
 #endif
 }
 
 /*******************************************************************************
  * Enable architecture extensions on first entry to Secure world.
  ******************************************************************************/
-static void enable_extensions_secure(cpu_context_t *ctx)
+static void manage_extensions_secure(cpu_context_t *ctx)
 {
 #if IMAGE_BL31
-#if ENABLE_SVE_FOR_SWD
+ #if ENABLE_SME_FOR_NS
+  #if ENABLE_SME_FOR_SWD
+	/*
+	 * Enable SME, SVE, FPU/SIMD in secure context, secure manager must
+	 * ensure SME, SVE, and FPU/SIMD context properly managed.
+	 */
+	sme_enable(ctx);
+  #else /* ENABLE_SME_FOR_SWD */
+	/*
+	 * Disable SME, SVE, FPU/SIMD in secure context so non-secure world can
+	 * safely use the associated registers.
+	 */
+	sme_disable(ctx);
+  #endif /* ENABLE_SME_FOR_SWD */
+ #elif ENABLE_SVE_FOR_NS
+  #if ENABLE_SVE_FOR_SWD
+	/*
+	 * Enable SVE and FPU in secure context, secure manager must ensure that
+	 * the SVE and FPU register contexts are properly managed.
+	 */
 	sve_enable(ctx);
-#endif
-#endif
+ #else /* ENABLE_SVE_FOR_SWD */
+	/*
+	 * Disable SVE and FPU in secure context so non-secure world can safely
+	 * use them.
+	 */
+	sve_disable(ctx);
+  #endif /* ENABLE_SVE_FOR_SWD */
+ #endif /* ENABLE_SVE_FOR_NS */
+#endif /* IMAGE_BL31 */
 }
 
 /*******************************************************************************
@@ -654,7 +684,7 @@
 			write_cnthp_ctl_el2(CNTHP_CTL_RESET_VAL &
 						~(CNTHP_CTL_ENABLE_BIT));
 		}
-		enable_extensions_nonsecure(el2_unused, ctx);
+		manage_extensions_nonsecure(el2_unused, ctx);
 	}
 
 	cm_el1_sysregs_context_restore(security_state);
diff --git a/lib/extensions/amu/aarch64/amu.c b/lib/extensions/amu/aarch64/amu.c
index 35efd21..d329c3d 100644
--- a/lib/extensions/amu/aarch64/amu.c
+++ b/lib/extensions/amu/aarch64/amu.c
@@ -6,7 +6,9 @@
 
 #include <assert.h>
 #include <cdefs.h>
+#include <inttypes.h>
 #include <stdbool.h>
+#include <stdint.h>
 
 #include "../amu_private.h"
 #include <arch.h>
@@ -343,7 +345,7 @@
 
 	default:
 		ERROR("AMU: can't set up virtual offset for unknown "
-		      "architected counter %llu!\n", idx);
+		      "architected counter %" PRIu64 "!\n", idx);
 
 		panic();
 	}
diff --git a/lib/extensions/sme/sme.c b/lib/extensions/sme/sme.c
new file mode 100644
index 0000000..1c2b984
--- /dev/null
+++ b/lib/extensions/sme/sme.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdbool.h>
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <lib/el3_runtime/context_mgmt.h>
+#include <lib/extensions/sme.h>
+#include <lib/extensions/sve.h>
+
+static bool feat_sme_supported(void)
+{
+	uint64_t features;
+
+	features = read_id_aa64pfr1_el1() >> ID_AA64PFR1_EL1_SME_SHIFT;
+	return (features & ID_AA64PFR1_EL1_SME_MASK) != 0U;
+}
+
+static bool feat_sme_fa64_supported(void)
+{
+	uint64_t features;
+
+	features = read_id_aa64smfr0_el1();
+	return (features & ID_AA64SMFR0_EL1_FA64_BIT) != 0U;
+}
+
+void sme_enable(cpu_context_t *context)
+{
+	u_register_t reg;
+	u_register_t cptr_el3;
+	el3_state_t *state;
+
+	/* Make sure SME is implemented in hardware before continuing. */
+	if (!feat_sme_supported()) {
+		return;
+	}
+
+	/* Get the context state. */
+	state = get_el3state_ctx(context);
+
+	/* Enable SME in CPTR_EL3. */
+	reg = read_ctx_reg(state, CTX_CPTR_EL3);
+	reg |= ESM_BIT;
+	write_ctx_reg(state, CTX_CPTR_EL3, reg);
+
+	/* Set the ENTP2 bit in SCR_EL3 to enable access to TPIDR2_EL0. */
+	reg = read_ctx_reg(state, CTX_SCR_EL3);
+	reg |= SCR_ENTP2_BIT;
+	write_ctx_reg(state, CTX_SCR_EL3, reg);
+
+	/* Set CPTR_EL3.ESM bit so we can write SMCR_EL3 without trapping. */
+	cptr_el3 = read_cptr_el3();
+	write_cptr_el3(cptr_el3 | ESM_BIT);
+
+	/*
+	 * Set the max LEN value and FA64 bit. This register is set up globally
+	 * to be the least restrictive, then lower ELs can restrict as needed
+	 * using SMCR_EL2 and SMCR_EL1.
+	 */
+	reg = SMCR_ELX_LEN_MASK;
+	if (feat_sme_fa64_supported()) {
+		VERBOSE("[SME] FA64 enabled\n");
+		reg |= SMCR_ELX_FA64_BIT;
+	}
+	write_smcr_el3(reg);
+
+	/* Reset CPTR_EL3 value. */
+	write_cptr_el3(cptr_el3);
+
+	/* Enable SVE/FPU in addition to SME. */
+	sve_enable(context);
+}
+
+void sme_disable(cpu_context_t *context)
+{
+	u_register_t reg;
+	el3_state_t *state;
+
+	/* Make sure SME is implemented in hardware before continuing. */
+	if (!feat_sme_supported()) {
+		return;
+	}
+
+	/* Get the context state. */
+	state = get_el3state_ctx(context);
+
+	/* Disable SME, SVE, and FPU since they all share registers. */
+	reg = read_ctx_reg(state, CTX_CPTR_EL3);
+	reg &= ~ESM_BIT;	/* Trap SME */
+	reg &= ~CPTR_EZ_BIT;	/* Trap SVE */
+	reg |= TFP_BIT;		/* Trap FPU/SIMD */
+	write_ctx_reg(state, CTX_CPTR_EL3, reg);
+
+	/* Disable access to TPIDR2_EL0. */
+	reg = read_ctx_reg(state, CTX_SCR_EL3);
+	reg &= ~SCR_ENTP2_BIT;
+	write_ctx_reg(state, CTX_SCR_EL3, reg);
+}
diff --git a/lib/extensions/sve/sve.c b/lib/extensions/sve/sve.c
index 2702c30..aa8904b 100644
--- a/lib/extensions/sve/sve.c
+++ b/lib/extensions/sve/sve.c
@@ -43,3 +43,23 @@
 	write_ctx_reg(get_el3state_ctx(context), CTX_ZCR_EL3,
 		(ZCR_EL3_LEN_MASK & CONVERT_SVE_LENGTH(512)));
 }
+
+void sve_disable(cpu_context_t *context)
+{
+	u_register_t reg;
+	el3_state_t *state;
+
+	/* Make sure SME is implemented in hardware before continuing. */
+	if (!sve_supported()) {
+		return;
+	}
+
+	/* Get the context state. */
+	state = get_el3state_ctx(context);
+
+	/* Disable SVE and FPU since they share registers. */
+	reg = read_ctx_reg(state, CTX_CPTR_EL3);
+	reg &= ~CPTR_EZ_BIT;	/* Trap SVE */
+	reg |= TFP_BIT;		/* Trap FPU/SIMD */
+	write_ctx_reg(state, CTX_CPTR_EL3, reg);
+}
diff --git a/lib/gpt_rme/gpt_rme.c b/lib/gpt_rme/gpt_rme.c
index 6d1ff4d..e424fe2 100644
--- a/lib/gpt_rme/gpt_rme.c
+++ b/lib/gpt_rme/gpt_rme.c
@@ -6,6 +6,7 @@
 
 #include <assert.h>
 #include <errno.h>
+#include <inttypes.h>
 #include <limits.h>
 #include <stdint.h>
 
@@ -445,7 +446,7 @@
 	/* Generate the needed block descriptors. */
 	for (; idx < end_idx; idx++) {
 		l0_gpt_arr[idx] = gpt_desc;
-		VERBOSE("[GPT] L0 entry (BLOCK) index %u [%p]: GPI = 0x%llx (0x%llx)\n",
+		VERBOSE("[GPT] L0 entry (BLOCK) index %u [%p]: GPI = 0x%" PRIx64 " (0x%" PRIx64 ")\n",
 			idx, &l0_gpt_arr[idx],
 			(gpt_desc >> GPT_L0_BLK_DESC_GPI_SHIFT) &
 			GPT_L0_BLK_DESC_GPI_MASK, l0_gpt_arr[idx]);
@@ -606,7 +607,7 @@
 			l0_gpt_base[l0_idx] = GPT_L0_TBL_DESC(l1_gpt_arr);
 		}
 
-		VERBOSE("[GPT] L0 entry (TABLE) index %u [%p] ==> L1 Addr 0x%llx (0x%llx)\n",
+		VERBOSE("[GPT] L0 entry (TABLE) index %u [%p] ==> L1 Addr 0x%llx (0x%" PRIx64 ")\n",
 			l0_idx, &l0_gpt_base[l0_idx],
 			(unsigned long long)(l1_gpt_arr),
 			l0_gpt_base[l0_idx]);
@@ -1042,7 +1043,7 @@
 	/* Check for address range overflow. */
 	if ((ULONG_MAX - base) < size) {
 		VERBOSE("[GPT] Transition request address overflow!\n");
-		VERBOSE("      Base=0x%llx\n", base);
+		VERBOSE("      Base=0x%" PRIx64 "\n", base);
 		VERBOSE("      Size=0x%lx\n", size);
 		return -EINVAL;
 	}
@@ -1053,7 +1054,7 @@
 	    (size == 0U) ||
 	    ((base + size) >= GPT_PPS_ACTUAL_SIZE(gpt_config.t))) {
 		VERBOSE("[GPT] Invalid granule transition address range!\n");
-		VERBOSE("      Base=0x%llx\n", base);
+		VERBOSE("      Base=0x%" PRIx64 "\n", base);
 		VERBOSE("      Size=0x%lx\n", size);
 		return -EINVAL;
 	}
@@ -1072,7 +1073,7 @@
 	gpt_l0_desc = gpt_l0_base[GPT_L0_IDX(base)];
 	if (GPT_L0_TYPE(gpt_l0_desc) != GPT_L0_TYPE_TBL_DESC) {
 		VERBOSE("[GPT] Granule is not covered by a table descriptor!\n");
-		VERBOSE("      Base=0x%llx\n", base);
+		VERBOSE("      Base=0x%" PRIx64 "\n", base);
 		return -EINVAL;
 	}
 
@@ -1116,7 +1117,7 @@
 	 * The isb() will be done as part of context
 	 * synchronization when returning to lower EL
 	 */
-	VERBOSE("[GPT] Granule 0x%llx, GPI 0x%x->0x%x\n", base, gpi,
+	VERBOSE("[GPT] Granule 0x%" PRIx64 ", GPI 0x%x->0x%x\n", base, gpi,
 		target_pas);
 
 	return 0;
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
index 45f5fa8..e88148f 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -134,7 +134,7 @@
 ENABLE_PAUTH			:= 0
 
 # Flag to enable access to the HCRX_EL2 register by setting SCR_EL3.HXEn.
-ENABLE_FEAT_HCX                 := 0
+ENABLE_FEAT_HCX			:= 0
 
 # By default BL31 encryption disabled
 ENCRYPT_BL31			:= 0
@@ -222,13 +222,13 @@
 SAVE_KEYS			:= 0
 
 # Software Delegated Exception support
-SDEI_SUPPORT            	:= 0
+SDEI_SUPPORT			:= 0
 
 # True Random Number firmware Interface
-TRNG_SUPPORT            	:= 0
+TRNG_SUPPORT			:= 0
 
 # SMCCC PCI support
-SMC_PCI_SUPPORT            	:= 0
+SMC_PCI_SUPPORT			:= 0
 
 # Whether code and read-only data should be put on separate memory pages. The
 # platform Makefile is free to override this value.
@@ -303,7 +303,7 @@
 
 # SPE is only supported on AArch64 so disable it on AArch32.
 ifeq (${ARCH},aarch32)
-    override ENABLE_SPE_FOR_LOWER_ELS := 0
+	override ENABLE_SPE_FOR_LOWER_ELS := 0
 endif
 
 # Include Memory Tagging Extension registers in cpu context. This must be set
@@ -316,15 +316,18 @@
 ENABLE_AMU_FCONF		:= 0
 AMU_RESTRICT_COUNTERS		:= 0
 
-# By default, enable Scalable Vector Extension if implemented only for Non-secure
-# lower ELs
-# Note SVE is only supported on AArch64 - therefore do not enable in AArch32
-ifneq (${ARCH},aarch32)
-    ENABLE_SVE_FOR_NS		:= 1
-    ENABLE_SVE_FOR_SWD		:= 0
-else
-    override ENABLE_SVE_FOR_NS	:= 0
-    override ENABLE_SVE_FOR_SWD  := 0
+# Enable SVE for non-secure world by default
+ENABLE_SVE_FOR_NS		:= 1
+ENABLE_SVE_FOR_SWD		:= 0
+
+# SME defaults to disabled
+ENABLE_SME_FOR_NS		:= 0
+ENABLE_SME_FOR_SWD		:= 0
+
+# If SME is enabled then force SVE off
+ifeq (${ENABLE_SME_FOR_NS},1)
+	override ENABLE_SVE_FOR_NS	:= 0
+	override ENABLE_SVE_FOR_SWD	:= 0
 endif
 
 SANITIZE_UB := off
@@ -348,7 +351,7 @@
 SUPPORT_STACK_MEMTAG		:= no
 
 # Select workaround for AT speculative behaviour.
-ERRATA_SPECULATIVE_AT           := 0
+ERRATA_SPECULATIVE_AT		:= 0
 
 # Trap RAS error record access from lower EL
 RAS_TRAP_LOWER_EL_ERR_ACCESS	:= 0
@@ -379,9 +382,9 @@
 # Note FEAT_TRBE is only supported on AArch64 - therefore do not enable in
 # AArch32.
 ifneq (${ARCH},aarch32)
-    ENABLE_TRBE_FOR_NS		:= 0
+	ENABLE_TRBE_FOR_NS		:= 0
 else
-    override ENABLE_TRBE_FOR_NS	:= 0
+	override ENABLE_TRBE_FOR_NS	:= 0
 endif
 
 # By default, disable access of trace system registers from NS lower
diff --git a/plat/arm/board/arm_fpga/build_axf.ld.S b/plat/arm/board/arm_fpga/build_axf.ld.S
index b4bc7d8..d8254e5 100644
--- a/plat/arm/board/arm_fpga/build_axf.ld.S
+++ b/plat/arm/board/arm_fpga/build_axf.ld.S
@@ -15,11 +15,11 @@
 OUTPUT_FORMAT("elf64-littleaarch64")
 OUTPUT_ARCH(aarch64)
 
-INPUT(./bl31/bl31.elf)
 INPUT(./rom_trampoline.o)
 INPUT(./kernel_trampoline.o)
 
 TARGET(binary)
+INPUT(./bl31.bin)
 INPUT(./fdts/arm_fpga.dtb)
 
 ENTRY(_start)
@@ -33,7 +33,7 @@
 
 	.bl31 (BL31_BASE): {
 		ASSERT(. == ALIGN(PAGE_SIZE), "BL31_BASE is not page aligned");
-		*bl31.elf(.text* .data* .rodata* ro* .bss*)
+		*bl31.bin
 	}
 
 	.dtb (FPGA_PRELOADED_DTB_BASE): {
diff --git a/plat/arm/board/arm_fpga/fpga_bl31_setup.c b/plat/arm/board/arm_fpga/fpga_bl31_setup.c
index 2b5ca4a..e1b3abb 100644
--- a/plat/arm/board/arm_fpga/fpga_bl31_setup.c
+++ b/plat/arm/board/arm_fpga/fpga_bl31_setup.c
@@ -13,6 +13,7 @@
 #include <drivers/delay_timer.h>
 #include <drivers/generic_delay_timer.h>
 #include <lib/extensions/spe.h>
+#include <lib/mmio.h>
 #include <libfdt.h>
 
 #include "fpga_private.h"
@@ -20,6 +21,7 @@
 #include <platform_def.h>
 
 static entry_point_info_t bl33_image_ep_info;
+static unsigned int system_freq;
 volatile uint32_t secondary_core_spinlock;
 
 uintptr_t plat_get_ns_image_entrypoint(void)
@@ -118,20 +120,189 @@
 	}
 }
 
-unsigned int plat_get_syscnt_freq2(void)
+/*
+ * Even though we sell the FPGA UART as an SBSA variant, it is actually
+ * a full fledged PL011. So the baudrate divider registers exist.
+ */
+#ifndef UARTIBRD
+#define UARTIBRD	0x024
+#define UARTFBRD	0x028
+#endif
+
+/* Round an integer to the closest multiple of a value. */
+static unsigned int round_multiple(unsigned int x, unsigned int multiple)
+{
+	if (multiple < 2) {
+		return x;
+	}
+
+	return ((x + (multiple / 2 - 1)) / multiple) * multiple;
+}
+
+#define PL011_FRAC_SHIFT	6
+#define FPGA_DEFAULT_BAUDRATE	38400
+#define PL011_OVERSAMPLING	16
+static unsigned int pl011_freq_from_divider(unsigned int divider)
+{
+	unsigned int freq;
+
+	freq = divider * FPGA_DEFAULT_BAUDRATE * PL011_OVERSAMPLING;
+
+	return freq >> PL011_FRAC_SHIFT;
+}
+
+/*
+ * The FPGAs run most peripherals from one main clock, among them the CPUs,
+ * the arch timer, and the UART baud base clock.
+ * The SCP knows this frequency and programs the UART clock divider for a
+ * 38400 bps baudrate. Recalculate the base input clock from there.
+ */
+static unsigned int fpga_get_system_frequency(void)
 {
 	const void *fdt = (void *)(uintptr_t)FPGA_PRELOADED_DTB_BASE;
-	int node;
+	int node, err;
 
+	/*
+	 * If the arch timer DT node has an explicit clock-frequency property
+	 * set, use that, to allow people overriding auto-detection.
+	 */
 	node = fdt_node_offset_by_compatible(fdt, 0, "arm,armv8-timer");
+	if (node >= 0) {
+		uint32_t freq;
+
+		err = fdt_read_uint32(fdt, node, "clock-frequency", &freq);
+		if (err >= 0) {
+			return freq;
+		}
+	}
+
+	node = fdt_node_offset_by_compatible(fdt, 0, "arm,pl011");
+	if (node >= 0) {
+		uintptr_t pl011_base;
+		unsigned int divider;
+
+		err = fdt_get_reg_props_by_index(fdt, node, 0,
+						 &pl011_base, NULL);
+		if (err >= 0) {
+			divider = mmio_read_32(pl011_base + UARTIBRD);
+			divider <<= PL011_FRAC_SHIFT;
+			divider += mmio_read_32(pl011_base + UARTFBRD);
+
+			/*
+			 * The result won't be exact, due to rounding errors,
+			 * but the input frequency was a multiple of 250 KHz.
+			 */
+			return round_multiple(pl011_freq_from_divider(divider),
+					      250000);
+		} else {
+			WARN("Cannot read PL011 MMIO base\n");
+		}
+	} else {
+		WARN("No PL011 DT node\n");
+	}
+
+	/* No PL011 DT node or calculation failed. */
+	return FPGA_DEFAULT_TIMER_FREQUENCY;
+}
+
+unsigned int plat_get_syscnt_freq2(void)
+{
+	if (system_freq == 0U) {
+		system_freq = fpga_get_system_frequency();
+	}
+
+	return system_freq;
+}
+
+static void fpga_dtb_update_clock(void *fdt, unsigned int freq)
+{
+	uint32_t freq_dtb = fdt32_to_cpu(freq);
+	uint32_t phandle;
+	int node, err;
+
+	node = fdt_node_offset_by_compatible(fdt, 0, "arm,pl011");
+	if (node < 0) {
+		WARN("%s(): No PL011 DT node found\n", __func__);
+
+		return;
+	}
+
+	err = fdt_read_uint32(fdt, node, "clocks", &phandle);
+	if (err != 0) {
+		WARN("Cannot find clocks property\n");
+
+		return;
+	}
+
+	node = fdt_node_offset_by_phandle(fdt, phandle);
 	if (node < 0) {
-		return FPGA_DEFAULT_TIMER_FREQUENCY;
+		WARN("Cannot get phandle\n");
+
+		return;
 	}
 
-	return fdt_read_uint32_default(fdt, node, "clock-frequency",
-				       FPGA_DEFAULT_TIMER_FREQUENCY);
+	err = fdt_setprop_inplace(fdt, node,
+				  "clock-frequency",
+				  &freq_dtb,
+				  sizeof(freq_dtb));
+	if (err < 0) {
+		WARN("Could not update DT baud clock frequency\n");
+
+		return;
+	}
 }
 
+#define CMDLINE_SIGNATURE	"CMD:"
+
+static int fpga_dtb_set_commandline(void *fdt, const char *cmdline)
+{
+	int chosen;
+	const char *eol;
+	char nul = 0;
+	int slen, err;
+
+	chosen = fdt_add_subnode(fdt, 0, "chosen");
+	if (chosen == -FDT_ERR_EXISTS) {
+		chosen = fdt_path_offset(fdt, "/chosen");
+	}
+
+	if (chosen < 0) {
+		return chosen;
+	}
+
+	/*
+	 * There is most likely an EOL at the end of the
+	 * command line, make sure we terminate the line there.
+	 * We can't replace the EOL with a NUL byte in the
+	 * source, as this is in read-only memory. So we first
+	 * create the property without any termination, then
+	 * append a single NUL byte.
+	 */
+	eol = strchr(cmdline, '\n');
+	if (eol == NULL) {
+		eol = strchr(cmdline, 0);
+	}
+	/* Skip the signature and omit the EOL/NUL byte. */
+	slen = eol - (cmdline + strlen(CMDLINE_SIGNATURE));
+	/*
+	 * Let's limit the size of the property, just in case
+	 * we find the signature by accident. The Linux kernel
+	 * limits to 4096 characters at most (in fact 2048 for
+	 * arm64), so that sounds like a reasonable number.
+	 */
+	if (slen > 4095) {
+		slen = 4095;
+	}
+
+	err = fdt_setprop(fdt, chosen, "bootargs",
+			  cmdline + strlen(CMDLINE_SIGNATURE), slen);
+	if (err != 0) {
+		return err;
+	}
+
+	return fdt_appendprop(fdt, chosen, "bootargs", &nul, 1);
+}
+
 static void fpga_prepare_dtb(void)
 {
 	void *fdt = (void *)(uintptr_t)FPGA_PRELOADED_DTB_BASE;
@@ -151,55 +322,13 @@
 	}
 
 	/* Check for the command line signature. */
-	if (!strncmp(cmdline, "CMD:", 4)) {
-		int chosen;
-
-		INFO("using command line at 0x%x\n", FPGA_PRELOADED_CMD_LINE);
-
-		chosen = fdt_add_subnode(fdt, 0, "chosen");
-		if (chosen == -FDT_ERR_EXISTS) {
-			chosen = fdt_path_offset(fdt, "/chosen");
-		}
-		if (chosen < 0) {
-			ERROR("cannot find /chosen node: %d\n", chosen);
+	if (!strncmp(cmdline, CMDLINE_SIGNATURE, strlen(CMDLINE_SIGNATURE))) {
+		err = fpga_dtb_set_commandline(fdt, cmdline);
+		if (err == 0) {
+			INFO("using command line at 0x%x\n",
+			     FPGA_PRELOADED_CMD_LINE);
 		} else {
-			const char *eol;
-			char nul = 0;
-			int slen;
-
-			/*
-			 * There is most likely an EOL at the end of the
-			 * command line, make sure we terminate the line there.
-			 * We can't replace the EOL with a NUL byte in the
-			 * source, as this is in read-only memory. So we first
-			 * create the property without any termination, then
-			 * append a single NUL byte.
-			 */
-			eol = strchr(cmdline, '\n');
-			if (!eol) {
-				eol = strchr(cmdline, 0);
-			}
-			/* Skip the signature and omit the EOL/NUL byte. */
-			slen = eol - (cmdline + 4);
-
-			/*
-			 * Let's limit the size of the property, just in case
-			 * we find the signature by accident. The Linux kernel
-			 * limits to 4096 characters at most (in fact 2048 for
-			 * arm64), so that sounds like a reasonable number.
-			 */
-			if (slen > 4095) {
-				slen = 4095;
-			}
-			err = fdt_setprop(fdt, chosen, "bootargs",
-					  cmdline + 4, slen);
-			if (!err) {
-				err = fdt_appendprop(fdt, chosen, "bootargs",
-						     &nul, 1);
-			}
-			if (err) {
-				ERROR("Could not set command line: %d\n", err);
-			}
+			ERROR("failed to put command line into DTB: %d\n", err);
 		}
 	}
 
@@ -224,6 +353,7 @@
 			INFO("Adjusting GICR DT region to cover %u cores\n",
 			      nr_cores);
 			err = fdt_adjust_gic_redist(fdt, nr_cores,
+						    fpga_get_redist_base(),
 						    fpga_get_redist_size());
 			if (err < 0) {
 				ERROR("Error %d fixing up GIC DT node\n", err);
@@ -231,6 +361,8 @@
 		}
 	}
 
+	fpga_dtb_update_clock(fdt, system_freq);
+
 	/* Check whether we support the SPE PMU. Remove the DT node if not. */
 	if (!spe_supported()) {
 		int node = fdt_node_offset_by_compatible(fdt, 0,
@@ -241,6 +373,16 @@
 		}
 	}
 
+	/* Check whether we have an ITS. Remove the DT node if not. */
+	if (!fpga_has_its()) {
+		int node = fdt_node_offset_by_compatible(fdt, 0,
+							 "arm,gic-v3-its");
+
+		if (node >= 0) {
+			fdt_del_node(fdt, node);
+		}
+	}
+
 	err = fdt_pack(fdt);
 	if (err < 0) {
 		ERROR("Failed to pack Device Tree at %p: error %d\n", fdt, err);
diff --git a/plat/arm/board/arm_fpga/fpga_gicv3.c b/plat/arm/board/arm_fpga/fpga_gicv3.c
index 4a97beb..e06a9da 100644
--- a/plat/arm/board/arm_fpga/fpga_gicv3.c
+++ b/plat/arm/board/arm_fpga/fpga_gicv3.c
@@ -1,13 +1,14 @@
 /*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2021, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <common/debug.h>
 #include <common/fdt_wrappers.h>
-#include <drivers/arm/gicv3.h>
+#include <drivers/arm/arm_gicv3_common.h>
 #include <drivers/arm/gic_common.h>
+#include <drivers/arm/gicv3.h>
 #include <lib/mmio.h>
 #include <libfdt.h>
 
@@ -21,6 +22,7 @@
 };
 
 static uintptr_t fpga_rdistif_base_addrs[PLATFORM_CORE_COUNT];
+static int nr_itses;
 
 static unsigned int fpga_mpidr_to_core_pos(unsigned long mpidr)
 {
@@ -38,6 +40,8 @@
 void plat_fpga_gic_init(void)
 {
 	const void *fdt = (void *)(uintptr_t)FPGA_PRELOADED_DTB_BASE;
+	uintptr_t gicr_base = 0U;
+	uint32_t iidr;
 	int node, ret;
 
 	node = fdt_node_offset_by_compatible(fdt, 0, "arm,gic-v3");
@@ -54,11 +58,66 @@
 		return;
 	}
 
-	ret = fdt_get_reg_props_by_index(fdt, node, 1,
-				 &fpga_gicv3_driver_data.gicr_base, NULL);
-	if (ret < 0) {
-		WARN("Could not read GIC redistributor address from DT.\n");
-		return;
+	iidr = mmio_read_32(fpga_gicv3_driver_data.gicd_base + GICD_IIDR);
+	if (((iidr & IIDR_MODEL_MASK) == IIDR_MODEL_ARM_GIC_600) ||
+	    ((iidr & IIDR_MODEL_MASK) == IIDR_MODEL_ARM_GIC_700)) {
+		unsigned int frame_id;
+
+		/*
+		 * According to the GIC TRMs, if there are any ITSes, they
+		 * start four 64K pages after the distributor. After all
+		 * the ITSes then follow the redistributors.
+		 */
+		gicr_base = fpga_gicv3_driver_data.gicd_base + (4U << 16);
+
+		do {
+			uint64_t its_typer;
+
+			/* Each GIC component can be identified by its ID. */
+			frame_id = gicv3_get_component_partnum(gicr_base);
+
+			if (frame_id == PIDR_COMPONENT_ARM_REDIST) {
+				INFO("Found %d ITSes, redistributors start at 0x%llx\n",
+				     nr_itses, (unsigned long long)gicr_base);
+				break;
+			}
+
+			if (frame_id != PIDR_COMPONENT_ARM_ITS) {
+				WARN("GICv3: found unexpected frame 0x%x\n",
+					frame_id);
+				gicr_base = 0U;
+				break;
+			}
+
+			/*
+			 * Found an ITS, now work out if it supports virtual
+			 * SGIs (for direct guest injection). If yes, each
+			 * ITS occupies four 64K pages, otherwise just two.
+			 */
+			its_typer = mmio_read_64(gicr_base + GITS_TYPER);
+			if ((its_typer & GITS_TYPER_VSGI) != 0U) {
+				gicr_base += 4U << 16;
+			} else {
+				gicr_base += 2U << 16;
+			}
+			nr_itses++;
+		} while (true);
+	}
+
+	/*
+	 * If this is not a GIC-600 or -700, or the autodetection above failed,
+	 * use the base address from the device tree.
+	 */
+	if (gicr_base == 0U) {
+		ret = fdt_get_reg_props_by_index(fdt, node, 1,
+					&fpga_gicv3_driver_data.gicr_base,
+					NULL);
+		if (ret < 0) {
+			WARN("Could not read GIC redistributor address from DT.\n");
+			return;
+		}
+	} else {
+		fpga_gicv3_driver_data.gicr_base = gicr_base;
 	}
 
 	gicv3_driver_init(&fpga_gicv3_driver_data);
@@ -91,3 +150,13 @@
 
 	return gicv3_redist_size(typer_val);
 }
+
+uintptr_t fpga_get_redist_base(void)
+{
+	return fpga_gicv3_driver_data.gicr_base;
+}
+
+bool fpga_has_its(void)
+{
+	return nr_itses > 0;
+}
diff --git a/plat/arm/board/arm_fpga/fpga_private.h b/plat/arm/board/arm_fpga/fpga_private.h
index cc809c4..84d651c 100644
--- a/plat/arm/board/arm_fpga/fpga_private.h
+++ b/plat/arm/board/arm_fpga/fpga_private.h
@@ -26,6 +26,8 @@
 unsigned int plat_fpga_calc_core_pos(uint32_t mpid);
 unsigned int fpga_get_nr_gic_cores(void);
 uintptr_t fpga_get_redist_size(void);
+uintptr_t fpga_get_redist_base(void);
+bool fpga_has_its(void);
 
 #endif /* __ASSEMBLER__ */
 
diff --git a/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c b/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c
index 35a777b..45e3b7e 100644
--- a/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c
+++ b/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c
@@ -5,6 +5,9 @@
  */
 
 #include <assert.h>
+#include <inttypes.h>
+#include <stdint.h>
+
 #include <common/debug.h>
 #include <common/fdt_wrappers.h>
 #include <fconf_hw_config_getter.h>
@@ -229,7 +232,7 @@
 
 	uart_serial_config.uart_base = translated_addr;
 
-	VERBOSE("FCONF: UART serial device base address: %llx\n",
+	VERBOSE("FCONF: UART serial device base address: %" PRIx64 "\n",
 		uart_serial_config.uart_base);
 
 	/*
diff --git a/plat/brcm/board/common/board_arm_trusted_boot.c b/plat/brcm/board/common/board_arm_trusted_boot.c
index 7a4dad0..da18c31 100644
--- a/plat/brcm/board/common/board_arm_trusted_boot.c
+++ b/plat/brcm/board/common/board_arm_trusted_boot.c
@@ -5,6 +5,7 @@
  */
 
 #include <assert.h>
+#include <inttypes.h>
 #include <stdint.h>
 #include <string.h>
 
@@ -344,7 +345,7 @@
 
 	for (rownum = start_row; rownum <= end_row; rownum++) {
 		rowdata = sotp_mem_read(rownum, SOTP_ROW_NO_ECC);
-		INFO("%d 0x%llx\n", rownum, rowdata);
+		INFO("%d 0x%" PRIx64 "\n", rownum, rowdata);
 	}
 }
 #endif
diff --git a/plat/brcm/board/stingray/src/brcm_pm_ops.c b/plat/brcm/board/stingray/src/brcm_pm_ops.c
index 03a604c..5e07fac 100644
--- a/plat/brcm/board/stingray/src/brcm_pm_ops.c
+++ b/plat/brcm/board/stingray/src/brcm_pm_ops.c
@@ -6,6 +6,7 @@
 
 #include <assert.h>
 #include <errno.h>
+#include <inttypes.h>
 
 #include <arch_helpers.h>
 #include <common/debug.h>
@@ -119,7 +120,7 @@
 		standbywfil2 = CDRU_PROC_EVENT_CLEAR__IH3_CDRU_STANDBYWFIL2;
 		break;
 	default:
-		ERROR("Invalid cluster #%llx\n", MPIDR_AFFLVL1_VAL(mpidr));
+		ERROR("Invalid cluster #%" PRIx64 "\n", MPIDR_AFFLVL1_VAL(mpidr));
 		return;
 	}
 	/* Clear the WFI status bit */
diff --git a/plat/common/aarch64/plat_common.c b/plat/common/aarch64/plat_common.c
index 345fec3..38a5786 100644
--- a/plat/common/aarch64/plat_common.c
+++ b/plat/common/aarch64/plat_common.c
@@ -5,6 +5,8 @@
  */
 
 #include <assert.h>
+#include <inttypes.h>
+#include <stdint.h>
 
 #include <arch_helpers.h>
 #include <drivers/console.h>
@@ -53,7 +55,7 @@
  */
 void plat_sdei_handle_masked_trigger(uint64_t mpidr, unsigned int intr)
 {
-	WARN("Spurious SDEI interrupt %u on masked PE %llx\n", intr, mpidr);
+	WARN("Spurious SDEI interrupt %u on masked PE %" PRIx64 "\n", intr, mpidr);
 }
 
 /*
@@ -93,7 +95,7 @@
 	ERROR_NL();
 	ERROR("Unhandled External Abort received on 0x%lx from %s\n",
 		read_mpidr_el1(), get_el_str(level));
-	ERROR("exception reason=%u syndrome=0x%llx\n", ea_reason, syndrome);
+	ERROR("exception reason=%u syndrome=0x%" PRIx64 "\n", ea_reason, syndrome);
 #if HANDLE_EA_EL3_FIRST
 	/* Skip backtrace for lower EL */
 	if (level != MODE_EL3) {
diff --git a/plat/common/plat_spmd_manifest.c b/plat/common/plat_spmd_manifest.c
index 8f4018c..b1fc13c 100644
--- a/plat/common/plat_spmd_manifest.c
+++ b/plat/common/plat_spmd_manifest.c
@@ -6,8 +6,10 @@
 
 #include <assert.h>
 #include <errno.h>
-#include <string.h>
+#include <inttypes.h>
 #include <libfdt.h>
+#include <stdint.h>
+#include <string.h>
 
 #include <common/bl_common.h>
 #include <common/debug.h>
@@ -80,8 +82,8 @@
 	VERBOSE("  version: %u.%u\n", attr->major_version, attr->minor_version);
 	VERBOSE("  spmc_id: 0x%x\n", attr->spmc_id);
 	VERBOSE("  binary_size: 0x%x\n", attr->binary_size);
-	VERBOSE("  load_address: 0x%llx\n", attr->load_address);
-	VERBOSE("  entrypoint: 0x%llx\n", attr->entrypoint);
+	VERBOSE("  load_address: 0x%" PRIx64 "\n", attr->load_address);
+	VERBOSE("  entrypoint: 0x%" PRIx64 "\n", attr->entrypoint);
 
 	return 0;
 }
diff --git a/plat/hisilicon/hikey/hikey_bl1_setup.c b/plat/hisilicon/hikey/hikey_bl1_setup.c
index 01c48ec..31ff820 100644
--- a/plat/hisilicon/hikey/hikey_bl1_setup.c
+++ b/plat/hisilicon/hikey/hikey_bl1_setup.c
@@ -6,6 +6,8 @@
 
 #include <assert.h>
 #include <errno.h>
+#include <inttypes.h>
+#include <stdint.h>
 #include <string.h>
 
 #include <arch_helpers.h>
@@ -155,7 +157,7 @@
 		__asm__ volatile ("msr	cpacr_el1, %0" : : "r"(data));
 		__asm__ volatile ("mrs	%0, cpacr_el1" : "=r"(data));
 	} while ((data & (3 << 20)) != (3 << 20));
-	INFO("cpacr_el1:0x%llx\n", data);
+	INFO("cpacr_el1:0x%" PRIx64 "\n", data);
 
 	ep_info->args.arg0 = 0xffff & read_mpidr();
 	ep_info->spsr = SPSR_64(MODE_EL1, MODE_SP_ELX,
diff --git a/plat/hisilicon/poplar/bl31_plat_setup.c b/plat/hisilicon/poplar/bl31_plat_setup.c
index a4e17ca..fe60ddc 100644
--- a/plat/hisilicon/poplar/bl31_plat_setup.c
+++ b/plat/hisilicon/poplar/bl31_plat_setup.c
@@ -6,7 +6,9 @@
 
 #include <assert.h>
 #include <errno.h>
+#include <inttypes.h>
 #include <stddef.h>
+#include <stdint.h>
 #include <string.h>
 
 #include <platform_def.h>
@@ -130,6 +132,6 @@
 			       BL_COHERENT_RAM_BASE,
 			       BL_COHERENT_RAM_END);
 
-	INFO("Boot BL33 from 0x%lx for %llu Bytes\n",
+	INFO("Boot BL33 from 0x%lx for %" PRIu64 " Bytes\n",
 	     bl33_image_ep_info.pc, bl33_image_ep_info.args.arg2);
 }
diff --git a/plat/imx/imx8qm/imx8qm_bl31_setup.c b/plat/imx/imx8qm/imx8qm_bl31_setup.c
index 4ca6a5d..d9c9110 100644
--- a/plat/imx/imx8qm/imx8qm_bl31_setup.c
+++ b/plat/imx/imx8qm/imx8qm_bl31_setup.c
@@ -5,6 +5,8 @@
  */
 
 #include <assert.h>
+#include <inttypes.h>
+#include <stdint.h>
 #include <stdbool.h>
 
 #include <platform_def.h>
@@ -261,14 +263,14 @@
 			err = sc_rm_get_memreg_info(ipc_handle, mr, &start, &end);
 			if (err)
 				ERROR("Memreg get info failed, %u\n", mr);
-			NOTICE("Memreg %u 0x%llx -- 0x%llx\n", mr, start, end);
+			NOTICE("Memreg %u 0x%" PRIx64 " -- 0x%" PRIx64 "\n", mr, start, end);
 			if (BL31_BASE >= start && (BL31_LIMIT - 1) <= end) {
 				mr_record = mr; /* Record the mr for ATF running */
 			} else {
 				err = sc_rm_assign_memreg(ipc_handle, os_part, mr);
 				if (err)
-					ERROR("Memreg assign failed, 0x%llx -- 0x%llx, \
-						err %d\n", start, end, err);
+					ERROR("Memreg assign failed, 0x%" PRIx64 " -- 0x%" PRIx64 ", \
+					      err %d\n", start, end, err);
 			}
 		}
 	}
@@ -280,23 +282,23 @@
 		if ((BL31_LIMIT - 1) < end) {
 			err = sc_rm_memreg_alloc(ipc_handle, &mr, BL31_LIMIT, end);
 			if (err)
-				ERROR("sc_rm_memreg_alloc failed, 0x%llx -- 0x%llx\n",
-					(sc_faddr_t)BL31_LIMIT, end);
+				ERROR("sc_rm_memreg_alloc failed, 0x%" PRIx64 " -- 0x%" PRIx64 "\n",
+				      (sc_faddr_t)BL31_LIMIT, end);
 			err = sc_rm_assign_memreg(ipc_handle, os_part, mr);
 			if (err)
-				ERROR("Memreg assign failed, 0x%llx -- 0x%llx\n",
-					(sc_faddr_t)BL31_LIMIT, end);
+				ERROR("Memreg assign failed, 0x%" PRIx64 " -- 0x%" PRIx64 "\n",
+				      (sc_faddr_t)BL31_LIMIT, end);
 		}
 
 		if (start < (BL31_BASE - 1)) {
 			err = sc_rm_memreg_alloc(ipc_handle, &mr, start, BL31_BASE - 1);
 			if (err)
-				ERROR("sc_rm_memreg_alloc failed, 0x%llx -- 0x%llx\n",
-					start, (sc_faddr_t)BL31_BASE - 1);
+				ERROR("sc_rm_memreg_alloc failed, 0x%" PRIx64 " -- 0x%" PRIx64 "\n",
+				      start, (sc_faddr_t)BL31_BASE - 1);
 			err = sc_rm_assign_memreg(ipc_handle, os_part, mr);
 				if (err)
-					ERROR("Memreg assign failed, 0x%llx -- 0x%llx\n",
-						start, (sc_faddr_t)BL31_BASE - 1);
+					ERROR("Memreg assign failed, 0x%" PRIx64 " -- 0x%" PRIx64 "\n",
+					      start, (sc_faddr_t)BL31_BASE - 1);
 		}
 	}
 
diff --git a/plat/imx/imx8qx/imx8qx_bl31_setup.c b/plat/imx/imx8qx/imx8qx_bl31_setup.c
index 3ff5400..3739cd6 100644
--- a/plat/imx/imx8qx/imx8qx_bl31_setup.c
+++ b/plat/imx/imx8qx/imx8qx_bl31_setup.c
@@ -5,7 +5,9 @@
  */
 
 #include <assert.h>
+#include <inttypes.h>
 #include <stdbool.h>
+#include <stdint.h>
 
 #include <platform_def.h>
 
@@ -238,14 +240,14 @@
 			if (err)
 				ERROR("Memreg get info failed, %u\n", mr);
 
-			NOTICE("Memreg %u 0x%llx -- 0x%llx\n", mr, start, end);
+			NOTICE("Memreg %u 0x%" PRIx64 " -- 0x%" PRIx64 "\n", mr, start, end);
 			if (BL31_BASE >= start && (BL31_LIMIT - 1) <= end) {
 				mr_record = mr; /* Record the mr for ATF running */
 			} else {
 				err = sc_rm_assign_memreg(ipc_handle, os_part, mr);
 				if (err)
-					ERROR("Memreg assign failed, 0x%llx -- 0x%llx, \
-						err %d\n", start, end, err);
+					ERROR("Memreg assign failed, 0x%" PRIx64 " -- 0x%" PRIx64 ", \
+					      err %d\n", start, end, err);
 			}
 		}
 	}
@@ -257,23 +259,23 @@
 		if ((BL31_LIMIT - 1) < end) {
 			err = sc_rm_memreg_alloc(ipc_handle, &mr, BL31_LIMIT, end);
 			if (err)
-				ERROR("sc_rm_memreg_alloc failed, 0x%llx -- 0x%llx\n",
-					(sc_faddr_t)BL31_LIMIT, end);
+				ERROR("sc_rm_memreg_alloc failed, 0x%" PRIx64 " -- 0x%" PRIx64 "\n",
+				      (sc_faddr_t)BL31_LIMIT, end);
 			err = sc_rm_assign_memreg(ipc_handle, os_part, mr);
 			if (err)
-				ERROR("Memreg assign failed, 0x%llx -- 0x%llx\n",
-					(sc_faddr_t)BL31_LIMIT, end);
+				ERROR("Memreg assign failed, 0x%" PRIx64 " -- 0x%" PRIx64 "\n",
+				      (sc_faddr_t)BL31_LIMIT, end);
 		}
 
 		if (start < (BL31_BASE - 1)) {
 			err = sc_rm_memreg_alloc(ipc_handle, &mr, start, BL31_BASE - 1);
 			if (err)
-				ERROR("sc_rm_memreg_alloc failed, 0x%llx -- 0x%llx\n",
-					start, (sc_faddr_t)BL31_BASE - 1);
+				ERROR("sc_rm_memreg_alloc failed, 0x%" PRIx64 " -- 0x%" PRIx64 "\n",
+				      start, (sc_faddr_t)BL31_BASE - 1);
 			err = sc_rm_assign_memreg(ipc_handle, os_part, mr);
 			if (err)
-				ERROR("Memreg assign failed, 0x%llx -- 0x%llx\n",
-					start, (sc_faddr_t)BL31_BASE - 1);
+				ERROR("Memreg assign failed, 0x%" PRIx64 " -- 0x%" PRIx64 "\n",
+				      start, (sc_faddr_t)BL31_BASE - 1);
 		}
 	}
 
diff --git a/plat/marvell/armada/a3k/common/a3700_ea.c b/plat/marvell/armada/a3k/common/a3700_ea.c
index 4a58fc6..bc12845 100644
--- a/plat/marvell/armada/a3k/common/a3700_ea.c
+++ b/plat/marvell/armada/a3k/common/a3700_ea.c
@@ -4,6 +4,10 @@
  * SPDX-License-Identifier:	BSD-3-Clause
  * https://spdx.org/licenses
  */
+
+#include <inttypes.h>
+#include <stdint.h>
+
 #include <common/bl_common.h>
 #include <common/debug.h>
 #include <arch_helpers.h>
@@ -72,7 +76,7 @@
 	    syndrome == A53_SERR_INT_AXI_SLVERR_ON_EXTERNAL_ACCESS) {
 		ERROR_NL();
 		ERROR("Ignoring Asynchronous External Abort with"
-		     " syndrome 0x%llx received on 0x%lx from %s\n",
+		     " syndrome 0x%" PRIx64 " received on 0x%lx from %s\n",
 		     syndrome, read_mpidr_el1(), get_el_str(level));
 		ERROR("SError interrupt: AXI SLVERR on external access\n");
 		ERROR("This indicates a bug in pci-aardvark.c driver\n");
diff --git a/plat/mediatek/mt8195/drivers/dp/mt_dp.c b/plat/mediatek/mt8195/drivers/dp/mt_dp.c
index 7ab2194..5930cd5 100644
--- a/plat/mediatek/mt8195/drivers/dp/mt_dp.c
+++ b/plat/mediatek/mt8195/drivers/dp/mt_dp.c
@@ -3,6 +3,9 @@
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
+
+#include <inttypes.h>
+
 #include <common/debug.h>
 #include <lib/mmio.h>
 #include <mt_dp.h>
@@ -28,7 +31,7 @@
 	uint32_t fldmask = 0UL;
 
 	if ((cmd > DP_ATF_CMD_COUNT) || (val == NULL)) {
-		INFO("dp_secure_handler error cmd 0x%llx\n", cmd);
+		INFO("dp_secure_handler error cmd 0x%" PRIx64 "\n", cmd);
 		return MTK_SIP_E_INVALID_PARAM;
 	}
 
diff --git a/plat/nvidia/tegra/common/tegra_bl31_setup.c b/plat/nvidia/tegra/common/tegra_bl31_setup.c
index cb4886f..6a3eae0 100644
--- a/plat/nvidia/tegra/common/tegra_bl31_setup.c
+++ b/plat/nvidia/tegra/common/tegra_bl31_setup.c
@@ -7,6 +7,7 @@
 
 #include <assert.h>
 #include <errno.h>
+#include <inttypes.h>
 #include <stddef.h>
 #include <string.h>
 
@@ -336,7 +337,7 @@
 	 * Sanity check the input values
 	 */
 	if ((base == 0U) || (size_in_bytes == 0U)) {
-		ERROR("NS address 0x%llx (%lld bytes) is invalid\n",
+		ERROR("NS address 0x%" PRIx64 " (%" PRId64 " bytes) is invalid\n",
 			base, size_in_bytes);
 		return -EINVAL;
 	}
@@ -347,7 +348,7 @@
 	if ((base < TEGRA_DRAM_BASE) || (base >= TEGRA_DRAM_END) ||
 	    (end > TEGRA_DRAM_END)) {
 
-		ERROR("NS address 0x%llx is out-of-bounds!\n", base);
+		ERROR("NS address 0x%" PRIx64 " is out-of-bounds!\n", base);
 		return -EFAULT;
 	}
 
@@ -356,7 +357,7 @@
 	 * to check if the NS DRAM range overlaps the TZDRAM aperture.
 	 */
 	if ((base < (uint64_t)TZDRAM_END) && (end > tegra_bl31_phys_base)) {
-		ERROR("NS address 0x%llx overlaps TZDRAM!\n", base);
+		ERROR("NS address 0x%" PRIx64 " overlaps TZDRAM!\n", base);
 		return -ENOTSUP;
 	}
 
diff --git a/plat/nvidia/tegra/soc/t186/drivers/mce/mce.c b/plat/nvidia/tegra/soc/t186/drivers/mce/mce.c
index 54d3b2c..aebaceb 100644
--- a/plat/nvidia/tegra/soc/t186/drivers/mce/mce.c
+++ b/plat/nvidia/tegra/soc/t186/drivers/mce/mce.c
@@ -7,6 +7,8 @@
 
 #include <assert.h>
 #include <errno.h>
+#include <inttypes.h>
+#include <stdint.h>
 #include <string.h>
 
 #include <arch.h>
@@ -341,7 +343,7 @@
 		break;
 
 	default:
-		ERROR("unknown MCE command (%llu)\n", cmd);
+		ERROR("unknown MCE command (%" PRIu64 ")\n", cmd);
 		ret = EINVAL;
 		break;
 	}
diff --git a/plat/nvidia/tegra/soc/t194/drivers/mce/mce.c b/plat/nvidia/tegra/soc/t194/drivers/mce/mce.c
index e3d5bd5..af1c0aa 100644
--- a/plat/nvidia/tegra/soc/t194/drivers/mce/mce.c
+++ b/plat/nvidia/tegra/soc/t194/drivers/mce/mce.c
@@ -16,8 +16,10 @@
 #include <mce_private.h>
 #include <platform_def.h>
 #include <stdbool.h>
+#include <stdint.h>
 #include <string.h>
 #include <errno.h>
+#include <inttypes.h>
 #include <t194_nvg.h>
 #include <tegra_def.h>
 #include <tegra_platform.h>
@@ -69,7 +71,7 @@
 		break;
 
 	default:
-		ERROR("unknown MCE command (%llu)\n", cmd);
+		ERROR("unknown MCE command (%" PRIu64 ")\n", cmd);
 		ret = -EINVAL;
 		break;
 	}
diff --git a/plat/nvidia/tegra/soc/t194/plat_ras.c b/plat/nvidia/tegra/soc/t194/plat_ras.c
index a322403..dbd6272 100644
--- a/plat/nvidia/tegra/soc/t194/plat_ras.c
+++ b/plat/nvidia/tegra/soc/t194/plat_ras.c
@@ -4,6 +4,7 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <inttypes.h>
 #include <stdbool.h>
 #include <stdint.h>
 
@@ -54,7 +55,7 @@
 
 	ras_lock();
 
-	ERROR("MPIDR 0x%lx: exception reason=%u syndrome=0x%llx\n",
+	ERROR("MPIDR 0x%lx: exception reason=%u syndrome=0x%" PRIx64 "\n",
 		read_mpidr(), ea_reason, syndrome);
 
 	/* Call RAS EA handler */
@@ -146,7 +147,7 @@
 			/* enable the supported errors */
 			err_ctrl |= err_fr;
 
-			VERBOSE("errselr_el1:0x%x, erxfr:0x%llx, err_ctrl:0x%llx\n",
+			VERBOSE("errselr_el1:0x%x, erxfr:0x%" PRIx64 ", err_ctrl:0x%" PRIx64 "\n",
 				idx_start + j, err_fr, err_ctrl);
 
 			/* enable specified errors, or set to 0 if no supported error */
@@ -288,7 +289,7 @@
 	/* keep the log print same as linux arm64_ras driver. */
 	ERROR("**************************************\n");
 	ERROR("RAS Error in %s, ERRSELR_EL1=0x%x:\n", name, errselr);
-	ERROR("\tStatus = 0x%llx\n", status);
+	ERROR("\tStatus = 0x%" PRIx64 "\n", status);
 
 	/* Print uncorrectable errror information. */
 	if (ERR_STATUS_GET_FIELD(status, UE) != 0U) {
diff --git a/plat/nvidia/tegra/soc/t210/plat_sip_calls.c b/plat/nvidia/tegra/soc/t210/plat_sip_calls.c
index 904f8d6..e3484be 100644
--- a/plat/nvidia/tegra/soc/t210/plat_sip_calls.c
+++ b/plat/nvidia/tegra/soc/t210/plat_sip_calls.c
@@ -5,6 +5,9 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <inttypes.h>
+#include <stdint.h>
+
 #include <arch.h>
 #include <arch_helpers.h>
 #include <assert.h>
@@ -71,7 +74,7 @@
 		case PMC_CRYPTO_OP_0:
 		case PMC_TSC_MULT_0:
 		case PMC_STICKY_BIT:
-			ERROR("%s: error offset=0x%llx\n", __func__, x2);
+			ERROR("%s: error offset=0x%" PRIx64 "\n", __func__, x2);
 			return -EFAULT;
 		default:
 			/* Valid register */
diff --git a/plat/nxp/common/setup/ls_bl31_setup.c b/plat/nxp/common/setup/ls_bl31_setup.c
index 6cf6ae3..bd0ab4f 100644
--- a/plat/nxp/common/setup/ls_bl31_setup.c
+++ b/plat/nxp/common/setup/ls_bl31_setup.c
@@ -6,6 +6,8 @@
  */
 
 #include <assert.h>
+#include <inttypes.h>
+#include <stdint.h>
 
 #ifdef LS_EL3_INTERRUPT_HANDLER
 #include <ls_interrupt_mgmt.h>
@@ -126,7 +128,7 @@
 					loc_dram_regions_info->num_dram_regions;
 			dram_regions_info.total_dram_size =
 					loc_dram_regions_info->total_dram_size;
-			VERBOSE("Number of DRAM Regions = %llx\n",
+			VERBOSE("Number of DRAM Regions = %" PRIx64 "\n",
 					dram_regions_info.num_dram_regions);
 
 			for (i = 0; i < dram_regions_info.num_dram_regions;
@@ -135,7 +137,7 @@
 					loc_dram_regions_info->region[i].addr;
 				dram_regions_info.region[i].size =
 					loc_dram_regions_info->region[i].size;
-				VERBOSE("DRAM%d Size = %llx\n", i,
+				VERBOSE("DRAM%d Size = %" PRIx64 "\n", i,
 					dram_regions_info.region[i].size);
 			}
 			rcw_porsr1 = bl31_image_ep_info.args.arg4;
diff --git a/plat/renesas/rcar/bl2_plat_setup.c b/plat/renesas/rcar/bl2_plat_setup.c
index e07b96f..bbfa169 100644
--- a/plat/renesas/rcar/bl2_plat_setup.c
+++ b/plat/renesas/rcar/bl2_plat_setup.c
@@ -4,6 +4,8 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <inttypes.h>
+#include <stdint.h>
 #include <string.h>
 
 #include <libfdt.h>
@@ -622,7 +624,7 @@
 
 	return;
 err:
-	NOTICE("BL2: Cannot add memory node [%llx - %llx] to FDT (ret=%i)\n",
+	NOTICE("BL2: Cannot add memory node [%" PRIx64 " - %" PRIx64 "] to FDT (ret=%i)\n",
 		start, start + size - 1, ret);
 	panic();
 }
@@ -638,7 +640,7 @@
 		if (!size)
 			continue;
 
-		NOTICE("BL2: CH%d: %llx - %llx, %lld %siB\n",
+		NOTICE("BL2: CH%d: %" PRIx64 " - %" PRIx64 ", %" PRId64 " %siB\n",
 			chan, start, start + size - 1,
 			(size >> 30) ? : size >> 20,
 			(size >> 30) ? "G" : "M");
diff --git a/plat/renesas/rzg/bl2_plat_setup.c b/plat/renesas/rzg/bl2_plat_setup.c
index ccc2562..e9dbd20 100644
--- a/plat/renesas/rzg/bl2_plat_setup.c
+++ b/plat/renesas/rzg/bl2_plat_setup.c
@@ -4,6 +4,8 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <inttypes.h>
+#include <stdint.h>
 #include <string.h>
 
 #include <arch_helpers.h>
@@ -531,7 +533,7 @@
 			continue;
 		}
 
-		NOTICE("BL2: CH%d: %llx - %llx, %lld %siB\n",
+		NOTICE("BL2: CH%d: %" PRIx64 " - %" PRIx64 ", %" PRId64 " %siB\n",
 		       chan, start, start + size - 1U,
 		       (size >> 30) ? : size >> 20,
 		       (size >> 30) ? "G" : "M");
diff --git a/plat/rpi/rpi4/rpi4_bl31_setup.c b/plat/rpi/rpi4/rpi4_bl31_setup.c
index 5259859..2fb4d3d 100644
--- a/plat/rpi/rpi4/rpi4_bl31_setup.c
+++ b/plat/rpi/rpi4/rpi4_bl31_setup.c
@@ -5,6 +5,8 @@
  */
 
 #include <assert.h>
+#include <inttypes.h>
+#include <stdint.h>
 
 #include <libfdt.h>
 
@@ -234,7 +236,7 @@
 			fdt_del_mem_rsv(dtb, i);
 			return;
 		}
-		WARN("Keeping unknown /memreserve/ region at 0, size: %lld\n",
+		WARN("Keeping unknown /memreserve/ region at 0, size: %" PRId64 "\n",
 		     size);
 	}
 }
diff --git a/plat/st/stm32mp1/stm32mp1_usb_dfu.c b/plat/st/stm32mp1/stm32mp1_usb_dfu.c
index 051d435..70fbba6 100644
--- a/plat/st/stm32mp1/stm32mp1_usb_dfu.c
+++ b/plat/st/stm32mp1/stm32mp1_usb_dfu.c
@@ -338,6 +338,8 @@
 	.get_usr_desc = stm32mp1_get_usr_desc,
 	.get_config_desc = stm32mp1_get_config_desc,
 	.get_device_qualifier_desc = stm32mp1_get_qualifier_desc,
+	/* only HS is supported, as ROM code */
+	.get_other_speed_config_desc = NULL,
 };
 
 static struct usb_handle usb_core_handle;
diff --git a/plat/xilinx/common/plat_startup.c b/plat/xilinx/common/plat_startup.c
index 8c9a049..f02f41e 100644
--- a/plat/xilinx/common/plat_startup.c
+++ b/plat/xilinx/common/plat_startup.c
@@ -5,6 +5,8 @@
  */
 
 #include <assert.h>
+#include <inttypes.h>
+#include <stdint.h>
 
 #include <arch_helpers.h>
 #include <common/debug.h>
@@ -170,12 +172,12 @@
 	    (ATFHandoffParams->magic[1] != 'L') ||
 	    (ATFHandoffParams->magic[2] != 'N') ||
 	    (ATFHandoffParams->magic[3] != 'X')) {
-		ERROR("BL31: invalid ATF handoff structure at %llx\n",
+		ERROR("BL31: invalid ATF handoff structure at %" PRIx64 "\n",
 		      atf_handoff_addr);
 		return FSBL_HANDOFF_INVAL_STRUCT;
 	}
 
-	VERBOSE("BL31: ATF handoff params at:0x%llx, entries:%u\n",
+	VERBOSE("BL31: ATF handoff params at:0x%" PRIx64 ", entries:%u\n",
 		atf_handoff_addr, ATFHandoffParams->num_entries);
 	if (ATFHandoffParams->num_entries > FSBL_MAX_PARTITIONS) {
 		ERROR("BL31: ATF handoff params: too many partitions (%u/%u)\n",
@@ -193,7 +195,7 @@
 		int target_estate, target_secure;
 		int target_cpu, target_endianness, target_el;
 
-		VERBOSE("BL31: %zd: entry:0x%llx, flags:0x%llx\n", i,
+		VERBOSE("BL31: %zd: entry:0x%" PRIx64 ", flags:0x%" PRIx64 "\n", i,
 			ATFHandoffParams->partition[i].entry_point,
 			ATFHandoffParams->partition[i].flags);
 
@@ -254,7 +256,7 @@
 			}
 		}
 
-		VERBOSE("Setting up %s entry point to:%llx, el:%x\n",
+		VERBOSE("Setting up %s entry point to:%" PRIx64 ", el:%x\n",
 			target_secure == FSBL_FLAGS_SECURE ? "BL32" : "BL33",
 			ATFHandoffParams->partition[i].entry_point,
 			target_el);
diff --git a/services/spd/trusty/trusty.c b/services/spd/trusty/trusty.c
index e102b82..7daebcd 100644
--- a/services/spd/trusty/trusty.c
+++ b/services/spd/trusty/trusty.c
@@ -6,8 +6,10 @@
  */
 
 #include <assert.h>
+#include <inttypes.h>
 #include <lib/xlat_tables/xlat_tables_v2.h>
 #include <stdbool.h>
+#include <stdint.h>
 #include <string.h>
 
 #include <arch_helpers.h>
@@ -172,7 +174,7 @@
 	struct trusty_cpu_ctx *ctx;
 
 	if (cpu >= (uint64_t)PLATFORM_CORE_COUNT) {
-		ERROR("%s: cpu %lld >= %d\n", __func__, cpu, PLATFORM_CORE_COUNT);
+		ERROR("%s: cpu %" PRId64 " >= %d\n", __func__, cpu, PLATFORM_CORE_COUNT);
 		return (uint64_t)SM_ERR_INVALID_PARAMETERS;
 	}
 
@@ -204,7 +206,7 @@
 
 	ret = trusty_context_switch(NON_SECURE, SMC_FC_FIQ_EXIT, 0, 0, 0);
 	if (ret.r0 != 1U) {
-		INFO("%s(%p) SMC_FC_FIQ_EXIT returned unexpected value, %lld\n",
+		INFO("%s(%p) SMC_FC_FIQ_EXIT returned unexpected value, %" PRId64 "\n",
 		       __func__, handle, ret.r0);
 	}
 
@@ -356,7 +358,7 @@
 
 	ret = trusty_context_switch(NON_SECURE, SMC_FC_CPU_SUSPEND, off, 0, 0);
 	if (ret.r0 != 0U) {
-		INFO("%s: cpu %d, SMC_FC_CPU_SUSPEND returned unexpected value, %lld\n",
+		INFO("%s: cpu %d, SMC_FC_CPU_SUSPEND returned unexpected value, %" PRId64 "\n",
 		     __func__, plat_my_core_pos(), ret.r0);
 	}
 }
@@ -367,7 +369,7 @@
 
 	ret = trusty_context_switch(NON_SECURE, SMC_FC_CPU_RESUME, on, 0, 0);
 	if (ret.r0 != 0U) {
-		INFO("%s: cpu %d, SMC_FC_CPU_RESUME returned unexpected value, %lld\n",
+		INFO("%s: cpu %d, SMC_FC_CPU_RESUME returned unexpected value, %" PRId64 "\n",
 		     __func__, plat_my_core_pos(), ret.r0);
 	}
 }
diff --git a/services/std_svc/rmmd/rmmd_main.c b/services/std_svc/rmmd/rmmd_main.c
index dacd150..7f85b63 100644
--- a/services/std_svc/rmmd/rmmd_main.c
+++ b/services/std_svc/rmmd/rmmd_main.c
@@ -6,6 +6,8 @@
 
 #include <assert.h>
 #include <errno.h>
+#include <inttypes.h>
+#include <stdint.h>
 #include <string.h>
 
 #include <arch_helpers.h>
@@ -131,7 +133,7 @@
 
 	rc = rmmd_rmm_sync_entry(ctx);
 	if (rc != 0ULL) {
-		ERROR("RMM initialisation failed 0x%llx\n", rc);
+		ERROR("RMM initialisation failed 0x%" PRIx64 "\n", rc);
 		panic();
 	}
 
@@ -301,12 +303,12 @@
 	/* Convert TF-A error codes into GTSI error codes */
 	if (ret == -EINVAL) {
 		ERROR("[GTSI] Transition failed: invalid %s\n", "address");
-		ERROR("       PA: 0x%llx, SRC: %d, PAS: %d\n", pa,
+		ERROR("       PA: 0x%" PRIx64 ", SRC: %d, PAS: %d\n", pa,
 		      src_sec_state, target_pas);
 		ret = GRAN_TRANS_RET_BAD_ADDR;
 	} else if (ret == -EPERM) {
 		ERROR("[GTSI] Transition failed: invalid %s\n", "caller/PAS");
-		ERROR("       PA: 0x%llx, SRC: %d, PAS: %d\n", pa,
+		ERROR("       PA: 0x%" PRIx64 ", SRC: %d, PAS: %d\n", pa,
 		      src_sec_state, target_pas);
 		ret = GRAN_TRANS_RET_BAD_PAS;
 	}
diff --git a/services/std_svc/sdei/sdei_intr_mgmt.c b/services/std_svc/sdei/sdei_intr_mgmt.c
index 399c2ec..87a1fb7 100644
--- a/services/std_svc/sdei/sdei_intr_mgmt.c
+++ b/services/std_svc/sdei/sdei_intr_mgmt.c
@@ -5,6 +5,8 @@
  */
 
 #include <assert.h>
+#include <inttypes.h>
+#include <stdint.h>
 #include <string.h>
 
 #include <arch_helpers.h>
@@ -459,8 +461,8 @@
 		 * Interrupts received while this PE was masked can't be
 		 * dispatched.
 		 */
-		SDEI_LOG("interrupt %u on %llx while PE masked\n", map->intr,
-				mpidr);
+		SDEI_LOG("interrupt %u on %" PRIx64 " while PE masked\n",
+			 map->intr, mpidr);
 		if (is_event_shared(map))
 			sdei_map_lock(map);
 
@@ -531,8 +533,8 @@
 	if (is_event_shared(map))
 		sdei_map_unlock(map);
 
-	SDEI_LOG("ACK %llx, ev:0x%x ss:%d spsr:%lx ELR:%lx\n", mpidr, map->ev_num,
-			sec_state, read_spsr_el3(), read_elr_el3());
+	SDEI_LOG("ACK %" PRIx64 ", ev:0x%x ss:%d spsr:%lx ELR:%lx\n",
+		 mpidr, map->ev_num, sec_state, read_spsr_el3(), read_elr_el3());
 
 	ctx = handle;
 
@@ -703,7 +705,7 @@
 	/* Having done sanity checks, pop dispatch */
 	(void) pop_dispatch();
 
-	SDEI_LOG("EOI:%lx, 0x%x spsr:%lx elr:%lx\n", read_mpidr_el1(),
+	SDEI_LOG("EOI:%lx, %d spsr:%lx elr:%lx\n", read_mpidr_el1(),
 			map->ev_num, read_spsr_el3(), read_elr_el3());
 
 	/*
diff --git a/services/std_svc/sdei/sdei_main.c b/services/std_svc/sdei/sdei_main.c
index 4ceaae8..44178ed 100644
--- a/services/std_svc/sdei/sdei_main.c
+++ b/services/std_svc/sdei/sdei_main.c
@@ -6,7 +6,9 @@
 
 #include <arch_helpers.h>
 #include <assert.h>
+#include <inttypes.h>
 #include <stddef.h>
+#include <stdint.h>
 #include <string.h>
 
 #include <bl31/bl31.h>
@@ -359,8 +361,20 @@
 		return SDEI_EINVAL;
 
 	/* Private events always target the PE */
-	if (is_event_private(map))
+	if (is_event_private(map)) {
+		/*
+		 * SDEI internally handles private events in the same manner
+		 * as public events with routing mode=RM_PE, since the routing
+		 * mode flag and affinity fields are not used when registering
+		 * a private event, set them here.
+		 */
 		flags = SDEI_REGF_RM_PE;
+		/*
+		 * Kernel may pass 0 as mpidr, as we set flags to
+		 * SDEI_REGF_RM_PE, so set mpidr also.
+		 */
+		mpidr = read_mpidr_el1();
+	}
 
 	se = get_event_entry(map);
 
@@ -961,33 +975,33 @@
 	case SDEI_VERSION:
 		SDEI_LOG("> VER\n");
 		ret = (int64_t) sdei_version();
-		SDEI_LOG("< VER:%llx\n", ret);
+		SDEI_LOG("< VER:%" PRIx64 "\n", ret);
 		SMC_RET1(ctx, ret);
 
 	case SDEI_EVENT_REGISTER:
 		x5 = SMC_GET_GP(ctx, CTX_GPREG_X5);
-		SDEI_LOG("> REG(n:0x%x e:%llx a:%llx f:%x m:%llx)\n", ev_num,
+		SDEI_LOG("> REG(n:%d e:%" PRIx64 " a:%" PRIx64 " f:%x m:%" PRIx64 "\n", ev_num,
 				x2, x3, (int) x4, x5);
 		ret = sdei_event_register(ev_num, x2, x3, x4, x5);
-		SDEI_LOG("< REG:%lld\n", ret);
+		SDEI_LOG("< REG:%" PRId64 "\n", ret);
 		SMC_RET1(ctx, ret);
 
 	case SDEI_EVENT_ENABLE:
 		SDEI_LOG("> ENABLE(n:%d)\n", (int) x1);
 		ret = sdei_event_enable(ev_num);
-		SDEI_LOG("< ENABLE:%lld\n", ret);
+		SDEI_LOG("< ENABLE:%" PRId64 "\n", ret);
 		SMC_RET1(ctx, ret);
 
 	case SDEI_EVENT_DISABLE:
 		SDEI_LOG("> DISABLE(n:0x%x)\n", ev_num);
 		ret = sdei_event_disable(ev_num);
-		SDEI_LOG("< DISABLE:%lld\n", ret);
+		SDEI_LOG("< DISABLE:%" PRId64 "\n", ret);
 		SMC_RET1(ctx, ret);
 
 	case SDEI_EVENT_CONTEXT:
 		SDEI_LOG("> CTX(p:%d):%lx\n", (int) x1, read_mpidr_el1());
 		ret = sdei_event_context(ctx, (unsigned int) x1);
-		SDEI_LOG("< CTX:%lld\n", ret);
+		SDEI_LOG("< CTX:%" PRId64 "\n", ret);
 		SMC_RET1(ctx, ret);
 
 	case SDEI_EVENT_COMPLETE_AND_RESUME:
@@ -995,10 +1009,10 @@
 		/* Fallthrough */
 
 	case SDEI_EVENT_COMPLETE:
-		SDEI_LOG("> COMPLETE(r:%u sta/ep:%llx):%lx\n",
-				(unsigned int) resume, x1, read_mpidr_el1());
+		SDEI_LOG("> COMPLETE(r:%u sta/ep:%" PRIx64 "):%lx\n",
+			 (unsigned int) resume, x1, read_mpidr_el1());
 		ret = sdei_event_complete(resume, x1);
-		SDEI_LOG("< COMPLETE:%llx\n", ret);
+		SDEI_LOG("< COMPLETE:%" PRIx64 "\n", ret);
 
 		/*
 		 * Set error code only if the call failed. If the call
@@ -1015,19 +1029,19 @@
 	case SDEI_EVENT_STATUS:
 		SDEI_LOG("> STAT(n:0x%x)\n", ev_num);
 		ret = sdei_event_status(ev_num);
-		SDEI_LOG("< STAT:%lld\n", ret);
+		SDEI_LOG("< STAT:%" PRId64 "\n", ret);
 		SMC_RET1(ctx, ret);
 
 	case SDEI_EVENT_GET_INFO:
 		SDEI_LOG("> INFO(n:0x%x, %d)\n", ev_num, (int) x2);
 		ret = sdei_event_get_info(ev_num, (int) x2);
-		SDEI_LOG("< INFO:%lld\n", ret);
+		SDEI_LOG("< INFO:%" PRId64 "\n", ret);
 		SMC_RET1(ctx, ret);
 
 	case SDEI_EVENT_UNREGISTER:
 		SDEI_LOG("> UNREG(n:0x%x)\n", ev_num);
 		ret = sdei_event_unregister(ev_num);
-		SDEI_LOG("< UNREG:%lld\n", ret);
+		SDEI_LOG("< UNREG:%" PRId64 "\n", ret);
 		SMC_RET1(ctx, ret);
 
 	case SDEI_PE_UNMASK:
@@ -1039,49 +1053,49 @@
 	case SDEI_PE_MASK:
 		SDEI_LOG("> MASK:%lx\n", read_mpidr_el1());
 		ret = sdei_pe_mask();
-		SDEI_LOG("< MASK:%lld\n", ret);
+		SDEI_LOG("< MASK:%" PRId64 "\n", ret);
 		SMC_RET1(ctx, ret);
 
 	case SDEI_INTERRUPT_BIND:
 		SDEI_LOG("> BIND(%d)\n", (int) x1);
 		ret = sdei_interrupt_bind((unsigned int) x1);
-		SDEI_LOG("< BIND:%lld\n", ret);
+		SDEI_LOG("< BIND:%" PRId64 "\n", ret);
 		SMC_RET1(ctx, ret);
 
 	case SDEI_INTERRUPT_RELEASE:
 		SDEI_LOG("> REL(0x%x)\n", ev_num);
 		ret = sdei_interrupt_release(ev_num);
-		SDEI_LOG("< REL:%lld\n", ret);
+		SDEI_LOG("< REL:%" PRId64 "\n", ret);
 		SMC_RET1(ctx, ret);
 
 	case SDEI_SHARED_RESET:
 		SDEI_LOG("> S_RESET():%lx\n", read_mpidr_el1());
 		ret = sdei_shared_reset();
-		SDEI_LOG("< S_RESET:%lld\n", ret);
+		SDEI_LOG("< S_RESET:%" PRId64 "\n", ret);
 		SMC_RET1(ctx, ret);
 
 	case SDEI_PRIVATE_RESET:
 		SDEI_LOG("> P_RESET():%lx\n", read_mpidr_el1());
 		ret = sdei_private_reset();
-		SDEI_LOG("< P_RESET:%lld\n", ret);
+		SDEI_LOG("< P_RESET:%" PRId64 "\n", ret);
 		SMC_RET1(ctx, ret);
 
 	case SDEI_EVENT_ROUTING_SET:
-		SDEI_LOG("> ROUTE_SET(n:0x%x f:%llx aff:%llx)\n", ev_num, x2, x3);
+		SDEI_LOG("> ROUTE_SET(n:%d f:%" PRIx64 " aff:%" PRIx64 ")\n", ev_num, x2, x3);
 		ret = sdei_event_routing_set(ev_num, x2, x3);
-		SDEI_LOG("< ROUTE_SET:%lld\n", ret);
+		SDEI_LOG("< ROUTE_SET:%" PRId64 "\n", ret);
 		SMC_RET1(ctx, ret);
 
 	case SDEI_FEATURES:
-		SDEI_LOG("> FTRS(f:%llx)\n", x1);
+		SDEI_LOG("> FTRS(f:%" PRIx64 ")\n", x1);
 		ret = (int64_t) sdei_features((unsigned int) x1);
-		SDEI_LOG("< FTRS:%llx\n", ret);
+		SDEI_LOG("< FTRS:%" PRIx64 "\n", ret);
 		SMC_RET1(ctx, ret);
 
 	case SDEI_EVENT_SIGNAL:
-		SDEI_LOG("> SIGNAL(e:0x%x t:%llx)\n", ev_num, x2);
+		SDEI_LOG("> SIGNAL(e:%d t:%" PRIx64 ")\n", ev_num, x2);
 		ret = sdei_signal(ev_num, x2);
-		SDEI_LOG("< SIGNAL:%lld\n", ret);
+		SDEI_LOG("< SIGNAL:%" PRId64 "\n", ret);
 		SMC_RET1(ctx, ret);
 
 	default:
diff --git a/services/std_svc/spm_mm/spm_mm.mk b/services/std_svc/spm_mm/spm_mm.mk
index 656488b..a87bdd8 100644
--- a/services/std_svc/spm_mm/spm_mm.mk
+++ b/services/std_svc/spm_mm/spm_mm.mk
@@ -10,6 +10,12 @@
 ifneq (${ARCH},aarch64)
         $(error "Error: SPM_MM is only supported on aarch64.")
 endif
+ifeq (${ENABLE_SVE_FOR_NS},1)
+        $(error "Error: SPM_MM is not compatible with ENABLE_SVE_FOR_NS")
+endif
+ifeq (${ENABLE_SME_FOR_NS},1)
+        $(error "Error: SPM_MM is not compatible with ENABLE_SME_FOR_NS")
+endif
 
 SPM_SOURCES	:=	$(addprefix services/std_svc/spm_mm/,	\
 			${ARCH}/spm_mm_helpers.S			\
diff --git a/services/std_svc/spmd/spmd.mk b/services/std_svc/spmd/spmd.mk
index 73f7c85..8efbdc8 100644
--- a/services/std_svc/spmd/spmd.mk
+++ b/services/std_svc/spmd/spmd.mk
@@ -1,11 +1,15 @@
 #
-# Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
 ifneq (${ARCH},aarch64)
-        $(error "Error: SPMD is only supported on aarch64.")
+	$(error "Error: SPMD is only supported on aarch64.")
+endif
+
+ifeq (${ENABLE_SME_FOR_NS},1)
+	$(error "Error: SPMD is not compatible with ENABLE_SME_FOR_NS")
 endif
 
 SPMD_SOURCES	+=	$(addprefix services/std_svc/spmd/,	\
diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c
index a9ff459..f5de549 100644
--- a/services/std_svc/spmd/spmd_main.c
+++ b/services/std_svc/spmd/spmd_main.c
@@ -6,11 +6,14 @@
 
 #include <assert.h>
 #include <errno.h>
+#include <inttypes.h>
+#include <stdint.h>
 #include <string.h>
 
 #include <arch_helpers.h>
 #include <arch/aarch64/arch_features.h>
 #include <bl31/bl31.h>
+#include <bl31/interrupt_mgmt.h>
 #include <common/debug.h>
 #include <common/runtime_svc.h>
 #include <lib/el3_runtime/context_mgmt.h>
@@ -49,7 +52,7 @@
 	int core_idx = plat_core_pos_by_mpidr(mpidr);
 
 	if (core_idx < 0) {
-		ERROR("Invalid mpidr: %llx, returned ID: %d\n", mpidr, core_idx);
+		ERROR("Invalid mpidr: %" PRIx64 ", returned ID: %d\n", mpidr, core_idx);
 		panic();
 	}
 
@@ -156,7 +159,7 @@
 
 	rc = spmd_spm_core_sync_entry(ctx);
 	if (rc != 0ULL) {
-		ERROR("SPMC initialisation failed 0x%llx\n", rc);
+		ERROR("SPMC initialisation failed 0x%" PRIx64 "\n", rc);
 		return 0;
 	}
 
@@ -168,13 +171,69 @@
 }
 
 /*******************************************************************************
+ * spmd_secure_interrupt_handler
+ * Enter the SPMC for further handling of the secure interrupt by the SPMC
+ * itself or a Secure Partition.
+ ******************************************************************************/
+static uint64_t spmd_secure_interrupt_handler(uint32_t id,
+					      uint32_t flags,
+					      void *handle,
+					      void *cookie)
+{
+	spmd_spm_core_context_t *ctx = spmd_get_context();
+	gp_regs_t *gpregs = get_gpregs_ctx(&ctx->cpu_ctx);
+	unsigned int linear_id = plat_my_core_pos();
+	int64_t rc;
+
+	/* Sanity check the security state when the exception was generated */
+	assert(get_interrupt_src_ss(flags) == NON_SECURE);
+
+	/* Sanity check the pointer to this cpu's context */
+	assert(handle == cm_get_context(NON_SECURE));
+
+	/* Save the non-secure context before entering SPMC */
+	cm_el1_sysregs_context_save(NON_SECURE);
+#if SPMD_SPM_AT_SEL2
+	cm_el2_sysregs_context_save(NON_SECURE);
+#endif
+
+	/* Convey the event to the SPMC through the FFA_INTERRUPT interface. */
+	write_ctx_reg(gpregs, CTX_GPREG_X0, FFA_INTERRUPT);
+	write_ctx_reg(gpregs, CTX_GPREG_X1, 0);
+	write_ctx_reg(gpregs, CTX_GPREG_X2, 0);
+	write_ctx_reg(gpregs, CTX_GPREG_X3, 0);
+	write_ctx_reg(gpregs, CTX_GPREG_X4, 0);
+	write_ctx_reg(gpregs, CTX_GPREG_X5, 0);
+	write_ctx_reg(gpregs, CTX_GPREG_X6, 0);
+	write_ctx_reg(gpregs, CTX_GPREG_X7, 0);
+
+	/* Mark current core as handling a secure interrupt. */
+	ctx->secure_interrupt_ongoing = true;
+
+	rc = spmd_spm_core_sync_entry(ctx);
+	if (rc != 0ULL) {
+		ERROR("%s failed (%" PRId64 ") on CPU%u\n", __func__, rc, linear_id);
+	}
+
+	ctx->secure_interrupt_ongoing = false;
+
+	cm_el1_sysregs_context_restore(NON_SECURE);
+#if SPMD_SPM_AT_SEL2
+	cm_el2_sysregs_context_restore(NON_SECURE);
+#endif
+	cm_set_next_eret_context(NON_SECURE);
+
+	SMC_RET0(&ctx->cpu_ctx);
+}
+
+/*******************************************************************************
  * Loads SPMC manifest and inits SPMC.
  ******************************************************************************/
 static int spmd_spmc_init(void *pm_addr)
 {
 	cpu_context_t *cpu_ctx;
 	unsigned int core_id;
-	uint32_t ep_attr;
+	uint32_t ep_attr, flags;
 	int rc;
 
 	/* Load the SPM Core manifest */
@@ -290,6 +349,19 @@
 
 	INFO("SPM Core setup done.\n");
 
+	/*
+	 * Register an interrupt handler routing secure interrupts to SPMD
+	 * while the NWd is running.
+	 */
+	flags = 0;
+	set_interrupt_rm_flag(flags, NON_SECURE);
+	rc = register_interrupt_type_handler(INTR_TYPE_S_EL1,
+					     spmd_secure_interrupt_handler,
+					     flags);
+	if (rc != 0) {
+		panic();
+	}
+
 	return 0;
 }
 
@@ -436,12 +508,12 @@
 	/* Determine which security state this SMC originated from */
 	secure_origin = is_caller_secure(flags);
 
-	VERBOSE("SPM(%u): 0x%x 0x%llx 0x%llx 0x%llx 0x%llx "
-		"0x%llx 0x%llx 0x%llx\n",
-		linear_id, smc_fid, x1, x2, x3, x4,
-		SMC_GET_GP(handle, CTX_GPREG_X5),
-		SMC_GET_GP(handle, CTX_GPREG_X6),
-		SMC_GET_GP(handle, CTX_GPREG_X7));
+	VERBOSE("SPM(%u): 0x%x 0x%" PRIx64 " 0x%" PRIx64 " 0x%" PRIx64 " 0x%" PRIx64
+		" 0x%" PRIx64 " 0x%" PRIx64 " 0x%" PRIx64 "\n",
+		    linear_id, smc_fid, x1, x2, x3, x4,
+		    SMC_GET_GP(handle, CTX_GPREG_X5),
+		    SMC_GET_GP(handle, CTX_GPREG_X6),
+		    SMC_GET_GP(handle, CTX_GPREG_X7));
 
 	switch (smc_fid) {
 	case FFA_ERROR:
@@ -594,7 +666,7 @@
 
 	case FFA_MSG_SEND_DIRECT_RESP_SMC32:
 		if (secure_origin && spmd_is_spmc_message(x1)) {
-			spmd_spm_core_sync_exit(0);
+			spmd_spm_core_sync_exit(0ULL);
 		} else {
 			/* Forward direct message to the other world */
 			return spmd_smc_forward(smc_fid, secure_origin,
@@ -666,7 +738,7 @@
 		 * SPM Core initialised successfully.
 		 */
 		if (secure_origin && (ctx->state == SPMC_STATE_ON_PENDING)) {
-			spmd_spm_core_sync_exit(0);
+			spmd_spm_core_sync_exit(0ULL);
 		}
 
 		/* Fall through to forward the call to the other world */
@@ -682,6 +754,14 @@
 					x1, x2, x3, x4, handle);
 		break; /* not reached */
 
+	case FFA_NORMAL_WORLD_RESUME:
+		if (secure_origin && ctx->secure_interrupt_ongoing) {
+			spmd_spm_core_sync_exit(0ULL);
+		} else {
+			return spmd_ffa_error_return(handle, FFA_ERROR_DENIED);
+		}
+		break; /* Not reached */
+
 	default:
 		WARN("SPM: Unsupported call 0x%08x\n", smc_fid);
 		return spmd_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED);
diff --git a/services/std_svc/spmd/spmd_pm.c b/services/std_svc/spmd/spmd_pm.c
index ac962ea..6ebafca 100644
--- a/services/std_svc/spmd/spmd_pm.c
+++ b/services/std_svc/spmd/spmd_pm.c
@@ -6,6 +6,9 @@
 
 #include <assert.h>
 #include <errno.h>
+#include <inttypes.h>
+#include <stdint.h>
+
 #include <lib/el3_runtime/context_mgmt.h>
 #include <lib/spinlock.h>
 #include "spmd_private.h"
@@ -110,7 +113,7 @@
 
 	rc = spmd_spm_core_sync_entry(ctx);
 	if (rc != 0ULL) {
-		ERROR("%s failed (%llu) on CPU%u\n", __func__, rc,
+		ERROR("%s failed (%" PRIu64 ") on CPU%u\n", __func__, rc,
 			linear_id);
 		ctx->state = SPMC_STATE_OFF;
 		return;
@@ -138,7 +141,7 @@
 
 	rc = spmd_spm_core_sync_entry(ctx);
 	if (rc != 0ULL) {
-		ERROR("%s failed (%llu) on CPU%u\n", __func__, rc, linear_id);
+		ERROR("%s failed (%" PRIu64 ") on CPU%u\n", __func__, rc, linear_id);
 	}
 
 	/* Expect a direct message response from the SPMC. */
diff --git a/services/std_svc/spmd/spmd_private.h b/services/std_svc/spmd/spmd_private.h
index 6d51a58..1fe5065 100644
--- a/services/std_svc/spmd/spmd_private.h
+++ b/services/std_svc/spmd/spmd_private.h
@@ -50,6 +50,7 @@
 	uint64_t c_rt_ctx;
 	cpu_context_t cpu_ctx;
 	spmc_state_t state;
+	bool secure_interrupt_ongoing;
 } spmd_spm_core_context_t;
 
 /*