Enable CnP bit for ARMv8.2 CPUs

This patch enables the CnP (Common not Private) bit for secure page
tables so that multiple PEs in the same Inner Shareable domain can use
the same translation table entries for a given stage of translation in
a particular translation regime. This only takes effect when ARM
Trusted Firmware is built with ARM_ARCH_MINOR >= 2.

ARM Trusted Firmware Design has been updated to include a description
of this feature usage.

Change-Id: I698305f047400119aa1900d34c65368022e410b8
Signed-off-by: Isla Mitchell <isla.mitchell@arm.com>
diff --git a/docs/firmware-design.rst b/docs/firmware-design.rst
index 4c3c420..facf016 100644
--- a/docs/firmware-design.rst
+++ b/docs/firmware-design.rst
@@ -2366,6 +2366,17 @@
 -  The Compare and Swap instruction is used to implement spinlocks. Otherwise,
    the load-/store-exclusive instruction pair is used.
 
+ARMv8.2
+~~~~~~~
+
+This Architecture Extension is targeted when ``ARM_ARCH_MAJOR`` == 8 and
+``ARM_ARCH_MINOR`` >= 2.
+
+-  The Common not Private (CnP) bit is enabled to indicate that multiple
+   Page Entries in the same Inner Shareable domain use the same translation
+   table entries for a given stage of translation for a particular translation
+   regime.
+
 Code Structure
 --------------
 
diff --git a/include/lib/aarch32/arch.h b/include/lib/aarch32/arch.h
index 661dbf8..56163c8 100644
--- a/include/lib/aarch32/arch.h
+++ b/include/lib/aarch32/arch.h
@@ -323,6 +323,11 @@
 	((aif) & SPSR_AIF_MASK) << SPSR_AIF_SHIFT)
 
 /*
+ * TTBR definitions
+ */
+#define TTBR_CNP_BIT		0x1
+
+/*
  * CTR definitions
  */
 #define CTR_CWG_SHIFT		24
diff --git a/include/lib/aarch64/arch.h b/include/lib/aarch64/arch.h
index 7bceea7..2adf769 100644
--- a/include/lib/aarch64/arch.h
+++ b/include/lib/aarch64/arch.h
@@ -396,6 +396,11 @@
 	(((aif) & SPSR_AIF_MASK) << SPSR_AIF_SHIFT))
 
 /*
+ * TTBR Definitions
+ */
+#define TTBR_CNP_BIT		0x1
+
+/*
  * CTR_EL0 definitions
  */
 #define CTR_CWG_SHIFT		U(24)
diff --git a/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c b/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c
index be18552..e66b927 100644
--- a/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c
+++ b/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c
@@ -10,6 +10,7 @@
 #include <cassert.h>
 #include <platform_def.h>
 #include <utils.h>
+#include <utils_def.h>
 #include <xlat_tables_v2.h>
 #include "../xlat_tables_private.h"
 
@@ -153,6 +154,13 @@
 
 	/* Set TTBR0 bits as well */
 	ttbr0 = (uint64_t)(uintptr_t) base_table;
+#if ARM_ARCH_AT_LEAST(8, 2)
+	/*
+	 * Enable CnP bit so as to share page tables with all PEs.
+	 * Mandatory for ARMv8.2 implementations.
+	 */
+	ttbr0 |= TTBR_CNP_BIT;
+#endif
 
 	/* Now program the relevant system registers */
 	write_mair0(mair0);
diff --git a/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c b/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c
index 61eac10..097e815 100644
--- a/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c
+++ b/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c
@@ -13,6 +13,7 @@
 #include <platform_def.h>
 #include <sys/types.h>
 #include <utils.h>
+#include <utils_def.h>
 #include <xlat_tables_v2.h>
 #include "../xlat_tables_private.h"
 
@@ -166,6 +167,14 @@
 									\
 		write_mair_el##_el(mair);				\
 		write_tcr_el##_el(tcr);					\
+									\
+		/* Set TTBR bits as well */				\
+		if (ARM_ARCH_AT_LEAST(8, 2)) {				\
+			/* Enable CnP bit so as to share page tables */	\
+			/* with all PEs. This is mandatory for */	\
+			/* ARMv8.2 implementations. */			\
+			ttbr |= TTBR_CNP_BIT;				\
+		}							\
 		write_ttbr0_el##_el(ttbr);				\
 									\
 		/* Ensure all translation table writes have drained */	\