Merge "fix(doc): document missing RMM-EL3 runtime services" into integration
diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst
index de3b9bc..2ddccac 100644
--- a/docs/design/cpu-specific-build-macros.rst
+++ b/docs/design/cpu-specific-build-macros.rst
@@ -331,6 +331,10 @@
   Cortex-A78C CPU. This needs to be enabled for revisions r0p1, r0p2 and
   it is still open.
 
+- ``ERRATA_A78C_2242638`` : This applies errata 2242638 workaround to
+  Cortex-A78C CPU. This needs to be enabled for revisions r0p1, r0p2 and
+  it is still open.
+
 For Cortex-X1 CPU, the following errata build flags are defined:
 
 - ``ERRATA_X1_1821534`` : This applies errata 1821534 workaround to Cortex-X1
@@ -541,6 +545,10 @@
    Cortex-X2 CPU. This needs to be enabled only for revision r2p0 of the CPU,
    it is fixed in r2p1.
 
+-  ``ERRATA_X2_2371105``: This applies errata 2371105 workaround to
+   Cortex-X2 CPU. This needs to be enabled for revisions r0p0, r1p0 and r2p0
+   of the CPU and is fixed in r2p1.
+
 For Cortex-A510, the following errata build flags are defined :
 
 -  ``ERRATA_A510_1922240``: This applies errata 1922240 workaround to
diff --git a/include/lib/cpus/aarch64/cortex_a78c.h b/include/lib/cpus/aarch64/cortex_a78c.h
index 39e2adf..54c95ad 100644
--- a/include/lib/cpus/aarch64/cortex_a78c.h
+++ b/include/lib/cpus/aarch64/cortex_a78c.h
@@ -26,4 +26,12 @@
 #define CORTEX_A78C_CPUPWRCTLR_EL1			S3_0_C15_C2_7
 #define CORTEX_A78C_CPUPWRCTLR_EL1_CORE_PWRDN_EN_BIT	U(1)
 
+/*******************************************************************************
+ * CPU Implementation Specific Selected Instruction registers
+ ******************************************************************************/
+#define CORTEX_A78C_IMP_CPUPSELR_EL3			S3_6_C15_C8_0
+#define CORTEX_A78C_IMP_CPUPCR_EL3			S3_6_C15_C8_1
+#define CORTEX_A78C_IMP_CPUPOR_EL3			S3_6_C15_C8_2
+#define CORTEX_A78C_IMP_CPUPMR_EL3			S3_6_C15_C8_3
+
 #endif /* CORTEX_A78C_H */
diff --git a/include/lib/cpus/aarch64/cortex_x2.h b/include/lib/cpus/aarch64/cortex_x2.h
index 92140b1..863b8c8 100644
--- a/include/lib/cpus/aarch64/cortex_x2.h
+++ b/include/lib/cpus/aarch64/cortex_x2.h
@@ -40,6 +40,12 @@
 #define CORTEX_X2_CPUACTLR_EL1_BIT_22				(ULL(1) << 22)
 
 /*******************************************************************************
+ * CPU Auxiliary Control Register 2 definitions
+ ******************************************************************************/
+#define CORTEX_X2_CPUACTLR2_EL1					S3_0_C15_C1_1
+#define CORTEX_X2_CPUACTLR2_EL1_BIT_40				(ULL(1) << 40)
+
+/*******************************************************************************
  * CPU Auxiliary Control Register 5 definitions
  ******************************************************************************/
 #define CORTEX_X2_CPUACTLR5_EL1					S3_0_C15_C8_0
diff --git a/include/lib/psci/psci_lib.h b/include/lib/psci/psci_lib.h
index 1ac45ad..43e2f96 100644
--- a/include/lib/psci/psci_lib.h
+++ b/include/lib/psci/psci_lib.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2022, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -91,6 +91,8 @@
 			  entry_point_info_t *next_image_info);
 int psci_stop_other_cores(unsigned int wait_ms,
 			  void (*stop_func)(u_register_t mpidr));
+bool psci_is_last_on_cpu_safe(void);
+
 #endif /* __ASSEMBLER__ */
 
 #endif /* PSCI_LIB_H */
diff --git a/lib/cpus/aarch64/cortex_a78c.S b/lib/cpus/aarch64/cortex_a78c.S
index f57ecaf..fc002e9 100644
--- a/lib/cpus/aarch64/cortex_a78c.S
+++ b/lib/cpus/aarch64/cortex_a78c.S
@@ -58,6 +58,41 @@
 	b	cpu_rev_var_range
 endfunc check_errata_2132064
 
+/* --------------------------------------------------------------------
+ * Errata Workaround for A78C Erratum 2242638.
+ * This applies to revisions r0p1 and r0p2 of the Cortex A78C
+ * processor and is still open.
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x17
+ * --------------------------------------------------------------------
+ */
+func errata_a78c_2242638_wa
+	/* Compare x0 against revisions r0p1 - r0p2 */
+	mov	x17, x30
+	bl	check_errata_2242638
+	cbz	x0, 1f
+
+	ldr	x0, =0x5
+	msr	CORTEX_A78C_IMP_CPUPSELR_EL3, x0
+	ldr	x0, =0x10F600E000
+	msr	CORTEX_A78C_IMP_CPUPOR_EL3, x0
+	ldr	x0, =0x10FF80E000
+	msr	CORTEX_A78C_IMP_CPUPMR_EL3, x0
+	ldr	x0, =0x80000000003FF
+	msr	CORTEX_A78C_IMP_CPUPCR_EL3, x0
+
+	isb
+1:
+	ret	x17
+endfunc errata_a78c_2242638_wa
+
+func check_errata_2242638
+	/* Applies to revisions r0p1-r0p2. */
+	mov	x1, #CPU_REV(0, 1)
+	mov	x2, #CPU_REV(0, 2)
+	b	cpu_rev_var_range
+endfunc check_errata_2242638
+
 func check_errata_cve_2022_23960
 #if WORKAROUND_CVE_2022_23960
 	mov	x0, #ERRATA_APPLIES
@@ -81,6 +116,11 @@
 	bl	errata_a78c_2132064_wa
 #endif
 
+#if ERRATA_A78C_2242638
+	mov	x0, x18
+	bl	errata_a78c_2242638_wa
+#endif
+
 #if IMAGE_BL31 && WORKAROUND_CVE_2022_23960
 	/*
 	 * The Cortex-A78c generic vectors are overridden to apply errata
@@ -125,6 +165,7 @@
 	 * checking functions of each errata.
 	 */
 	report_errata ERRATA_A78C_2132064, cortex_a78c, 2132064
+	report_errata ERRATA_A78C_2242638, cortex_a78c, 2242638
 	report_errata WORKAROUND_CVE_2022_23960, cortex_a78c, cve_2022_23960
 
 	ldp	x8, x30, [sp], #16
diff --git a/lib/cpus/aarch64/cortex_x2.S b/lib/cpus/aarch64/cortex_x2.S
index 3e0810b..c810be6 100644
--- a/lib/cpus/aarch64/cortex_x2.S
+++ b/lib/cpus/aarch64/cortex_x2.S
@@ -267,6 +267,34 @@
 	b	cpu_rev_var_range
 endfunc check_errata_2147715
 
+/* -------------------------------------------------------
+ * Errata Workaround for Cortex-X2 Erratum 2371105.
+ * This applies to revisions <= r2p0 and is fixed in r2p1.
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x17
+ * -------------------------------------------------------
+ */
+func errata_x2_2371105_wa
+	/* Check workaround compatibility. */
+	mov	x17, x30
+	bl	check_errata_2371105
+	cbz	x0, 1f
+
+	/* Set bit 40 in CPUACTLR2_EL1 */
+	mrs	x1, CORTEX_X2_CPUACTLR2_EL1
+	orr	x1, x1, #CORTEX_X2_CPUACTLR2_EL1_BIT_40
+	msr	CORTEX_X2_CPUACTLR2_EL1, x1
+	isb
+1:
+	ret	x17
+endfunc errata_x2_2371105_wa
+
+func check_errata_2371105
+	/* Applies to <= r2p0. */
+	mov	x1, #0x20
+	b	cpu_rev_var_ls
+endfunc check_errata_2371105
+
 	/* ----------------------------------------------------
 	 * HW will do the cache maintenance while powering down
 	 * ----------------------------------------------------
@@ -304,6 +332,7 @@
 	report_errata ERRATA_X2_2083908, cortex_x2, 2083908
 	report_errata ERRATA_X2_2147715, cortex_x2, 2147715
 	report_errata ERRATA_X2_2216384, cortex_x2, 2216384
+	report_errata ERRATA_X2_2371105, cortex_x2, 2371105
 	report_errata WORKAROUND_CVE_2022_23960, cortex_x2, cve_2022_23960
 	report_errata ERRATA_DSU_2313941, cortex_x2, dsu_2313941
 
@@ -361,6 +390,11 @@
 	bl	errata_x2_2147715_wa
 #endif
 
+#if ERRATA_X2_2371105
+	mov	x0, x18
+	bl	errata_x2_2371105_wa
+#endif
+
 #if IMAGE_BL31 && WORKAROUND_CVE_2022_23960
 	/*
 	 * The Cortex-X2 generic vectors are overridden to apply errata
diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk
index 5be0a55..b114824 100644
--- a/lib/cpus/cpu-ops.mk
+++ b/lib/cpus/cpu-ops.mk
@@ -365,6 +365,10 @@
 # to revisions r0p1 and r0p2 of the A78C cpu. It is still open.
 ERRATA_A78C_2132064	?=0
 
+# Flag to apply erratum 2242638 workaround during reset. This erratum applies
+# to revisions r0p1 and r0p2 of the A78C cpu. It is still open.
+ERRATA_A78C_2242638	?=0
+
 # Flag to apply erratum 1821534 workaround during reset. This erratum applies
 # to revisions r0p0 - r1p0 of the X1 cpu and fixed in r1p1.
 ERRATA_X1_1821534	?=0
@@ -599,6 +603,10 @@
 # only to revision r2p0 of the Cortex-X2 cpu, it is fixed in r2p1.
 ERRATA_X2_2147715	?=0
 
+# Flag to apply erratum 2371105 workaround during reset. This erratum applies
+# to revision r0p0, r1p0 and r2p0 of the Cortex-X2 cpu and is fixed in r2p1.
+ERRATA_X2_2371105	?=0
+
 # Flag to apply erratum 1922240 workaround during reset. This erratum applies
 # to revision r0p0 of the Cortex-A510 cpu and is fixed in r0p1.
 ERRATA_A510_1922240	?=0
@@ -927,6 +935,10 @@
 $(eval $(call assert_boolean,ERRATA_A78C_2132064))
 $(eval $(call add_define,ERRATA_A78C_2132064))
 
+# Process ERRATA_A78C_2242638 flag
+$(eval $(call assert_boolean,ERRATA_A78C_2242638))
+$(eval $(call add_define,ERRATA_A78C_2242638))
+
 # Process ERRATA_X1_1821534 flag
 $(eval $(call assert_boolean,ERRATA_X1_1821534))
 $(eval $(call add_define,ERRATA_X1_1821534))
@@ -1155,6 +1167,10 @@
 $(eval $(call assert_boolean,ERRATA_X2_2147715))
 $(eval $(call add_define,ERRATA_X2_2147715))
 
+# Process ERRATA_X2_2371105 flag
+$(eval $(call assert_boolean,ERRATA_X2_2371105))
+$(eval $(call add_define,ERRATA_X2_2371105))
+
 # Process ERRATA_A510_1922240 flag
 $(eval $(call assert_boolean,ERRATA_A510_1922240))
 $(eval $(call add_define,ERRATA_A510_1922240))
diff --git a/lib/psci/psci_common.c b/lib/psci/psci_common.c
index 170777f..22d66bf 100644
--- a/lib/psci/psci_common.c
+++ b/lib/psci/psci_common.c
@@ -1022,3 +1022,56 @@
 
 	return PSCI_E_SUCCESS;
 }
+
+/*******************************************************************************
+ * This function verifies that all the other cores in the system have been
+ * turned OFF and the current CPU is the last running CPU in the system.
+ * Returns true if the current CPU is the last ON CPU or false otherwise.
+ *
+ * This API has following differences with psci_is_last_on_cpu
+ *  1. PSCI states are locked
+ *  2. It caters for "forest" topology instead of just "tree"
+ *  TODO : Revisit both API's and unify them
+ ******************************************************************************/
+bool psci_is_last_on_cpu_safe(void)
+{
+	unsigned int this_core = plat_my_core_pos();
+	unsigned int parent_nodes[PLAT_MAX_PWR_LVL] = {0};
+	unsigned int i = 0;
+
+	/*
+	 * Traverse the forest of PSCI nodes, nodes with no parents
+	 * (invalid-nodes) are the root nodes.
+	 */
+	while ((psci_non_cpu_pd_nodes[i].parent_node ==
+	       PSCI_PARENT_NODE_INVALID) &&
+	       (i < PSCI_NUM_NON_CPU_PWR_DOMAINS)) {
+		psci_get_parent_pwr_domain_nodes(
+				psci_non_cpu_pd_nodes[i].cpu_start_idx,
+				PLAT_MAX_PWR_LVL, parent_nodes);
+
+		psci_acquire_pwr_domain_locks(PLAT_MAX_PWR_LVL, parent_nodes);
+
+		for (unsigned int core = 0U;
+		     core < psci_non_cpu_pd_nodes[i].ncpus; core++) {
+			if (core == this_core) {
+				continue;
+			}
+
+			if (psci_get_aff_info_state_by_idx(core) !=
+			    AFF_STATE_OFF) {
+				psci_release_pwr_domain_locks(PLAT_MAX_PWR_LVL,
+							      parent_nodes);
+				VERBOSE("core=%u other than boot core=%u %s\n",
+				       core, this_core, "running in the system");
+
+				return false;
+			}
+		}
+
+		psci_release_pwr_domain_locks(PLAT_MAX_PWR_LVL, parent_nodes);
+		i++;
+	}
+
+	return true;
+}
diff --git a/lib/psci/psci_private.h b/lib/psci/psci_private.h
index 72bd6bd..61bd966 100644
--- a/lib/psci/psci_private.h
+++ b/lib/psci/psci_private.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -47,6 +47,9 @@
  */
 #define PSCI_MAX_CPUS_INDEX	0xFFFFU
 
+/* Invalid parent */
+#define PSCI_PARENT_NODE_INVALID	0xFFFFFFFFU
+
 /*
  * Helper functions to get/set the fields of PSCI per-cpu data.
  */
diff --git a/plat/arm/board/tc/include/platform_def.h b/plat/arm/board/tc/include/platform_def.h
index 6ca3261..11762d4 100644
--- a/plat/arm/board/tc/include/platform_def.h
+++ b/plat/arm/board/tc/include/platform_def.h
@@ -177,8 +177,14 @@
 
 #define PLAT_ARM_NSTIMER_FRAME_ID	0
 
+#if (TARGET_PLATFORM >= 2)
 #define PLAT_ARM_TRUSTED_ROM_BASE	0x1000
-#define PLAT_ARM_TRUSTED_ROM_SIZE	0x00080000	/* 512KB */
+#else
+#define PLAT_ARM_TRUSTED_ROM_BASE	0x0
+#endif
+
+/* PLAT_ARM_TRUSTED_ROM_SIZE 512KB minus ROM base. */
+#define PLAT_ARM_TRUSTED_ROM_SIZE	(0x00080000 - PLAT_ARM_TRUSTED_ROM_BASE)
 
 #define PLAT_ARM_NSRAM_BASE		0x06000000
 #define PLAT_ARM_NSRAM_SIZE		0x00080000	/* 512KB */
diff --git a/plat/arm/board/tc/platform.mk b/plat/arm/board/tc/platform.mk
index 3acd88e..18fcd54 100644
--- a/plat/arm/board/tc/platform.mk
+++ b/plat/arm/board/tc/platform.mk
@@ -1,4 +1,4 @@
-# Copyright (c) 2021, Arm Limited. All rights reserved.
+# Copyright (c) 2021-2022, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -9,6 +9,8 @@
         $(error TARGET_PLATFORM must be 0 or 1)
 endif
 
+$(eval $(call add_define,TARGET_PLATFORM))
+
 CSS_LOAD_SCP_IMAGES	:=	1
 
 CSS_USE_SCMI_SDS_DRIVER	:=	1