@@ -117,5 +117,41 @@ static inline u64 get_ctr(void)
extern u32 dcache_line_size;
+static inline unsigned long get_id_aa64mmfr0_el1(void)
+{
+ return read_sysreg(id_aa64mmfr0_el1);
+}
+
+#define ID_AA64MMFR0_TGRAN4_SHIFT 28
+#define ID_AA64MMFR0_TGRAN64_SHIFT 24
+#define ID_AA64MMFR0_TGRAN16_SHIFT 20
+
+#define ID_AA64MMFR0_TGRAN4_SUPPORTED 0x0
+#define ID_AA64MMFR0_TGRAN64_SUPPORTED 0x0
+#define ID_AA64MMFR0_TGRAN16_SUPPORTED 0x1
+
+static inline bool system_supports_granule(size_t granule)
+{
+ u32 shift;
+ u32 val;
+ u64 mmfr0;
+
+ if (granule == SZ_4K) {
+ shift = ID_AA64MMFR0_TGRAN4_SHIFT;
+ val = ID_AA64MMFR0_TGRAN4_SUPPORTED;
+ } else if (granule == SZ_16K) {
+ shift = ID_AA64MMFR0_TGRAN16_SHIFT;
+ val = ID_AA64MMFR0_TGRAN16_SUPPORTED;
+ } else {
+ assert(granule == SZ_64K);
+ shift = ID_AA64MMFR0_TGRAN64_SHIFT;
+ val = ID_AA64MMFR0_TGRAN64_SUPPORTED;
+ }
+
+ mmfr0 = get_id_aa64mmfr0_el1();
+
+ return ((mmfr0 >> shift) & 0xf) == val;
+}
+
#endif /* !__ASSEMBLY__ */
#endif /* _ASMARM64_PROCESSOR_H_ */
@@ -160,6 +160,9 @@ void *setup_mmu(phys_addr_t phys_end)
#ifdef __aarch64__
init_alloc_vpage((void*)(4ul << 30));
+
+ assert_msg(system_supports_granule(PAGE_SIZE),
+ "Unsupported translation granule %ld\n", PAGE_SIZE);
#endif
mmu_idmap = alloc_page();
As arm64 implementations may support a subset of the architecturally defined granules, we need to check and warn the user if the configured translation granule is not supported. Signed-off-by: Nikos Nikoleris <nikos.nikoleris@arm.com> --- lib/arm64/asm/processor.h | 36 ++++++++++++++++++++++++++++++++++++ lib/arm/mmu.c | 3 +++ 2 files changed, 39 insertions(+)