VHE: MM: Add flags to support EL0/User mappings and non global mappings

Added flags and support for enabling EL0 mappings and non-global
mappings when VHE is enabled. This will be used to map EL0 partitions.

Change-Id: Ib6b142d36ecde63c9da46547a7f958deabf8fd7a
Signed-off-by: Raghu Krishnamurthy <raghu.ncstate@gmail.com>
diff --git a/inc/hf/mm.h b/inc/hf/mm.h
index b8ed221..901a799 100644
--- a/inc/hf/mm.h
+++ b/inc/hf/mm.h
@@ -62,6 +62,12 @@
 #define MM_MODE_UNOWNED UINT32_C(0x0020)
 #define MM_MODE_SHARED  UINT32_C(0x0040)
 
+/* Specifies if a mapping will be a user mapping(EL0). */
+#define MM_MODE_USER    UINT32_C(0x0200)
+
+/* Map page as non-global. */
+#define MM_MODE_NG UINT32_C(0x0100) /* non-global */
+
 /* The mask for a mode that is considered unmapped. */
 #define MM_MODE_UNMAPPED_MASK (MM_MODE_INVALID | MM_MODE_UNOWNED)
 
diff --git a/src/arch/aarch64/mm.c b/src/arch/aarch64/mm.c
index 17e9884..bc259f3 100644
--- a/src/arch/aarch64/mm.c
+++ b/src/arch/aarch64/mm.c
@@ -29,6 +29,7 @@
 #define PTE_TABLE        (UINT64_C(1) << 1)
 
 #define STAGE1_XN          (UINT64_C(1) << 54)
+#define STAGE1_UXN         (UINT64_C(1) << 54)
 #define STAGE1_PXN         (UINT64_C(1) << 53)
 #define STAGE1_CONTIGUOUS  (UINT64_C(1) << 52)
 #define STAGE1_DBM         (UINT64_C(1) << 51)
@@ -44,6 +45,7 @@
 
 #define STAGE1_READONLY  UINT64_C(2)
 #define STAGE1_READWRITE UINT64_C(0)
+#define STAGE1_AP_USER_RW UINT64_C(1)
 
 #define STAGE1_DEVICEINDX UINT64_C(0)
 #define STAGE1_NORMALINDX UINT64_C(1)
@@ -442,19 +444,31 @@
 	}
 
 #endif
+	/*
+	 * STAGE1_XN can be XN or UXN depending on if the EL2
+	 * translation regime uses one VA range or two VA ranges(VHE).
+	 * PXN is res0 when the translation regime does not support two
+	 * VA ranges.
+	 */
+	if (mode & MM_MODE_X) {
+		if (has_vhe_support()) {
+			attrs |=
+				(mode & MM_MODE_USER) ? STAGE1_PXN : STAGE1_UXN;
+		}
 
-	/* Define the execute bits. */
-	if (!(mode & MM_MODE_X)) {
-		attrs |= STAGE1_XN;
-	}
 #if BRANCH_PROTECTION
-	else {
 		/* Mark code pages as Guarded Pages if BTI is supported. */
 		if (is_arch_feat_bti_supported()) {
 			attrs |= STAGE1_GP;
 		}
-	}
 #endif
+	} else {
+		if (has_vhe_support()) {
+			attrs |= (STAGE1_UXN | STAGE1_PXN);
+		} else {
+			attrs |= STAGE1_XN;
+		}
+	}
 
 	/* Define the read/write bits. */
 	if (mode & MM_MODE_W) {
@@ -463,6 +477,14 @@
 		attrs |= STAGE1_AP(STAGE1_READONLY);
 	}
 
+	if (has_vhe_support()) {
+		attrs |= (mode & MM_MODE_USER) ? STAGE1_AP(STAGE1_AP_USER_RW)
+					       : 0;
+		if (mode & MM_MODE_NG) {
+			attrs |= STAGE1_NG;
+		}
+	}
+
 	/* Define the memory attribute bits. */
 	if (mode & MM_MODE_D) {
 		attrs |= STAGE1_ATTRINDX(STAGE1_DEVICEINDX);
@@ -617,7 +639,12 @@
 		block_attrs |= STAGE1_AP2;
 	}
 	if (table_attrs & TABLE_APTABLE0) {
-		block_attrs &= ~STAGE1_AP1;
+		/* When two VA ranges are supported, AP1 is valid */
+		if (has_vhe_support()) {
+			block_attrs |= STAGE1_AP1;
+		} else {
+			block_attrs &= ~STAGE1_AP1;
+		}
 	}
 	if (table_attrs & TABLE_XNTABLE) {
 		block_attrs |= STAGE1_XN;