summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/xlat_tables/xlat_tables_common.c3
-rw-r--r--lib/xlat_tables/xlat_tables_private.h30
2 files changed, 32 insertions, 1 deletions
diff --git a/lib/xlat_tables/xlat_tables_common.c b/lib/xlat_tables/xlat_tables_common.c
index 448d25d8..81c4dc68 100644
--- a/lib/xlat_tables/xlat_tables_common.c
+++ b/lib/xlat_tables/xlat_tables_common.c
@@ -353,7 +353,8 @@ static mmap_region_t *init_xlation_table_inner(mmap_region_t *mm,
if (mm->base_va > base_va + level_size - 1) {
/* Next region is after this area. Nothing to map yet */
desc = INVALID_DESC;
- } else {
+ /* Make sure that the current level allows block descriptors */
+ } else if (level >= XLAT_BLOCK_LEVEL_MIN) {
/*
* Try to get attributes of this area. It will fail if
* there are partially overlapping regions. On success,
diff --git a/lib/xlat_tables/xlat_tables_private.h b/lib/xlat_tables/xlat_tables_private.h
index 085a0c26..f0f656bd 100644
--- a/lib/xlat_tables/xlat_tables_private.h
+++ b/lib/xlat_tables/xlat_tables_private.h
@@ -58,6 +58,36 @@ CASSERT(IS_POWER_OF_TWO(PLAT_VIRT_ADDR_SPACE_SIZE),
CASSERT(IS_POWER_OF_TWO(PLAT_PHY_ADDR_SPACE_SIZE),
assert_valid_phy_addr_space_size);
+/*
+ * In AArch32 state, the MMU only supports 4KB page granularity, which means
+ * that the first translation table level is either 1 or 2. Both of them are
+ * allowed to have block and table descriptors. See section G4.5.6 of the
+ * ARMv8-A Architecture Reference Manual (DDI 0487A.k) for more information.
+ *
+ * In AArch64 state, the MMU may support 4 KB, 16 KB and 64 KB page
+ * granularity. For 4KB granularity, a level 0 table descriptor doesn't support
+ * block translation. For 16KB, the same thing happens to levels 0 and 1. For
+ * 64KB, same for level 1. See section D4.3.1 of the ARMv8-A Architecture
+ * Reference Manual (DDI 0487A.k) for more information.
+ *
+ * The define below specifies the first table level that allows block
+ * descriptors.
+ */
+
+#ifdef AARCH32
+
+# define XLAT_BLOCK_LEVEL_MIN 1
+
+#else /* if AArch64 */
+
+# if PAGE_SIZE == (4*1024) /* 4KB */
+# define XLAT_BLOCK_LEVEL_MIN 1
+# else /* 16KB or 64KB */
+# define XLAT_BLOCK_LEVEL_MIN 2
+# endif
+
+#endif /* AARCH32 */
+
void print_mmap(void);
void init_xlation_table(uintptr_t base_va, uint64_t *table,
int level, uintptr_t *max_va,