summaryrefslogtreecommitdiff
path: root/lib/aarch64
diff options
context:
space:
mode:
authordanh-arm <dan.handley@arm.com>2016-03-11 04:45:32 +0000
committerdanh-arm <dan.handley@arm.com>2016-03-11 04:45:32 +0000
commita25648e079700ca6d711ee48a1562e95c204284d (patch)
treea89d905ac90aa5d5304e4f8f83ffa090c95c1d37 /lib/aarch64
parenta34f3bf2130288ddf263fe6ef6c0ed667c6e7fba (diff)
parent2af926ddd47d9ce0043cad474c52292b0cbc6baf (diff)
Merge pull request #542 from sandrine-bailleux-arm/km/pt-zero
Initialize all translation table entries
Diffstat (limited to 'lib/aarch64')
-rw-r--r--lib/aarch64/xlat_tables.c19
1 files changed, 16 insertions, 3 deletions
diff --git a/lib/aarch64/xlat_tables.c b/lib/aarch64/xlat_tables.c
index d28731f6..269743f7 100644
--- a/lib/aarch64/xlat_tables.c
+++ b/lib/aarch64/xlat_tables.c
@@ -52,7 +52,17 @@
#define debug_print(...) ((void)0)
#endif
-CASSERT(ADDR_SPACE_SIZE > 0, assert_valid_addr_space_size);
+#define IS_POWER_OF_TWO(x) (((x) & ((x) - 1)) == 0)
+
+/*
+ * The virtual address space size must be a power of two (as set in TCR.T0SZ).
+ * As we start the initial lookup at level 1, it must also be between 2 GB and
+ * 512 GB (with the virtual address size therefore 31 to 39 bits). See section
+ * D4.2.5 in the ARMv8-A Architecture Reference Manual (DDI 0487A.i) for more
+ * information.
+ */
+CASSERT(ADDR_SPACE_SIZE >= (1ull << 31) && ADDR_SPACE_SIZE <= (1ull << 39) &&
+ IS_POWER_OF_TWO(ADDR_SPACE_SIZE), assert_valid_addr_space_size);
#define UNSET_DESC ~0ul
@@ -229,7 +239,10 @@ static mmap_region_t *init_xlation_table(mmap_region_t *mm,
do {
unsigned long desc = UNSET_DESC;
- if (mm->base_va + mm->size <= base_va) {
+ if (!mm->size) {
+ /* Done mapping regions; finish zeroing the table */
+ desc = INVALID_DESC;
+ } else if (mm->base_va + mm->size <= base_va) {
/* Area now after the region so skip it */
++mm;
continue;
@@ -267,7 +280,7 @@ static mmap_region_t *init_xlation_table(mmap_region_t *mm,
*table++ = desc;
base_va += level_size;
- } while (mm->size && (base_va & level_index_mask));
+ } while ((base_va & level_index_mask) && (base_va < ADDR_SPACE_SIZE));
return mm;
}