Merge "feat(xlat): detect 4KB and 16KB page support when FEAT_LPA2 is present" into integration
diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h
index 0038893..f3bccc4 100644
--- a/include/arch/aarch64/arch.h
+++ b/include/arch/aarch64/arch.h
@@ -300,6 +300,7 @@
 #define ID_AA64MMFR0_EL1_TGRAN4_SHIFT		U(28)
 #define ID_AA64MMFR0_EL1_TGRAN4_MASK		ULL(0xf)
 #define ID_AA64MMFR0_EL1_TGRAN4_SUPPORTED	ULL(0x0)
+#define ID_AA64MMFR0_EL1_TGRAN4_52B_SUPPORTED	ULL(0x1)
 #define ID_AA64MMFR0_EL1_TGRAN4_NOT_SUPPORTED	ULL(0xf)
 
 #define ID_AA64MMFR0_EL1_TGRAN64_SHIFT		U(24)
@@ -311,6 +312,7 @@
 #define ID_AA64MMFR0_EL1_TGRAN16_MASK		ULL(0xf)
 #define ID_AA64MMFR0_EL1_TGRAN16_SUPPORTED	ULL(0x1)
 #define ID_AA64MMFR0_EL1_TGRAN16_NOT_SUPPORTED	ULL(0x0)
+#define ID_AA64MMFR0_EL1_TGRAN16_52B_SUPPORTED	ULL(0x2)
 
 /* ID_AA64MMFR1_EL1 definitions */
 #define ID_AA64MMFR1_EL1_TWED_SHIFT		U(32)
diff --git a/include/arch/aarch64/arch_features.h b/include/arch/aarch64/arch_features.h
index d6f12f3..609a95b 100644
--- a/include/arch/aarch64/arch_features.h
+++ b/include/arch/aarch64/arch_features.h
@@ -678,4 +678,25 @@
 	return read_feat_sme_id_field() >= ID_AA64PFR1_EL1_SME2_SUPPORTED;
 }
 
+/*******************************************************************************
+ * Function to get hardware granularity support
+ ******************************************************************************/
+
+static inline unsigned int read_id_aa64mmfr0_el0_tgran4_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64mmfr0_el1(), ID_AA64MMFR0_EL1_TGRAN4);
+}
+
+static inline unsigned int read_id_aa64mmfr0_el0_tgran16_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64mmfr0_el1(),
+			     ID_AA64MMFR0_EL1_TGRAN16);
+}
+
+static inline unsigned int read_id_aa64mmfr0_el0_tgran64_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64mmfr0_el1(),
+			     ID_AA64MMFR0_EL1_TGRAN64);
+}
+
 #endif /* ARCH_FEATURES_H */
diff --git a/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c b/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c
index 719110a..c847a9e 100644
--- a/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c
+++ b/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -22,22 +22,23 @@
  */
 bool xlat_arch_is_granule_size_supported(size_t size)
 {
-	u_register_t id_aa64mmfr0_el1 = read_id_aa64mmfr0_el1();
+	unsigned int tgranx;
 
 	if (size == PAGE_SIZE_4KB) {
-		return ((id_aa64mmfr0_el1 >> ID_AA64MMFR0_EL1_TGRAN4_SHIFT) &
-			 ID_AA64MMFR0_EL1_TGRAN4_MASK) ==
-			 ID_AA64MMFR0_EL1_TGRAN4_SUPPORTED;
+		tgranx = read_id_aa64mmfr0_el0_tgran4_field();
+		/* MSB of TGRAN4 field will be '1' for unsupported feature */
+		return ((tgranx >= ID_AA64MMFR0_EL1_TGRAN4_SUPPORTED) &&
+			(tgranx < 8U));
 	} else if (size == PAGE_SIZE_16KB) {
-		return ((id_aa64mmfr0_el1 >> ID_AA64MMFR0_EL1_TGRAN16_SHIFT) &
-			 ID_AA64MMFR0_EL1_TGRAN16_MASK) ==
-			 ID_AA64MMFR0_EL1_TGRAN16_SUPPORTED;
+		tgranx = read_id_aa64mmfr0_el0_tgran16_field();
+		return (tgranx >= ID_AA64MMFR0_EL1_TGRAN16_SUPPORTED);
 	} else if (size == PAGE_SIZE_64KB) {
-		return ((id_aa64mmfr0_el1 >> ID_AA64MMFR0_EL1_TGRAN64_SHIFT) &
-			 ID_AA64MMFR0_EL1_TGRAN64_MASK) ==
-			 ID_AA64MMFR0_EL1_TGRAN64_SUPPORTED;
+		tgranx = read_id_aa64mmfr0_el0_tgran64_field();
+		/* MSB of TGRAN64 field will be '1' for unsupported feature */
+		return ((tgranx >= ID_AA64MMFR0_EL1_TGRAN64_SUPPORTED) &&
+			(tgranx < 8U));
 	} else {
-		return 0;
+		return false;
 	}
 }