diff options
author | Sandrine Bailleux <sandrine.bailleux@arm.com> | 2017-09-28 21:58:12 +0100 |
---|---|---|
committer | Antonio Nino Diaz <antonio.ninodiaz@arm.com> | 2017-10-05 14:32:12 +0100 |
commit | fdb1964c34968921379d3592e7ac6e9a685dbab1 (patch) | |
tree | a8ed2ce931e590b0066b1cae349713f1dbf5e7fe /lib | |
parent | cb2cfae365eedb94619f8f88f98aee8f866d9a14 (diff) | |
download | platform_external_arm-trusted-firmware-fdb1964c34968921379d3592e7ac6e9a685dbab1.tar.gz platform_external_arm-trusted-firmware-fdb1964c34968921379d3592e7ac6e9a685dbab1.tar.bz2 platform_external_arm-trusted-firmware-fdb1964c34968921379d3592e7ac6e9a685dbab1.zip |
xlat: Introduce MAP_REGION2() macro
The current implementation of the memory mapping API favours mapping
memory regions using the biggest possible block size in order to
reduce the number of translation tables needed.
In some cases, this behaviour might not be desirable. When translation
tables are edited at run-time, coarse-grain mappings like that might
need splitting into finer-grain tables. This operation has a
performance cost.
The MAP_REGION2() macro allows to specify the granularity of
translation tables used for the initial mapping of a memory region.
This might increase performance for memory regions that are likely to
be edited in the future, at the expense of a potentially increased
memory footprint.
The Translation Tables Library Design Guide has been updated to
explain the use case for this macro. Also added a few intermediate
titles to make the guide easier to digest.
Change-Id: I04de9302e0ee3d326b8877043a9f638766b81b7b
Co-authored-by: Sandrine Bailleux <sandrine.bailleux@arm.com>
Co-authored-by: Antonio Nino Diaz <antonio.ninodiaz@arm.com>
Signed-off-by: Antonio Nino Diaz <antonio.ninodiaz@arm.com>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/xlat_tables_v2/xlat_tables_internal.c | 18 |
1 files changed, 12 insertions, 6 deletions
diff --git a/lib/xlat_tables_v2/xlat_tables_internal.c b/lib/xlat_tables_v2/xlat_tables_internal.c index da658b114..feca964b1 100644 --- a/lib/xlat_tables_v2/xlat_tables_internal.c +++ b/lib/xlat_tables_v2/xlat_tables_internal.c @@ -417,7 +417,8 @@ static action_t xlat_tables_map_region_action(const mmap_region_t *mm, * descriptors. If not, create a table instead. */ if ((dest_pa & XLAT_BLOCK_MASK(level)) || - (level < MIN_LVL_BLOCK_DESC)) + (level < MIN_LVL_BLOCK_DESC) || + (mm->granularity < XLAT_BLOCK_SIZE(level))) return ACTION_CREATE_NEW_TABLE; else return ACTION_WRITE_BLOCK_ENTRY; @@ -590,9 +591,10 @@ void print_mmap(mmap_region_t *const mmap) mmap_region_t *mm = mmap; while (mm->size) { - tf_printf(" VA:%p PA:0x%llx size:0x%zx attr:0x%x\n", + tf_printf(" VA:%p PA:0x%llx size:0x%zx attr:0x%x", (void *)mm->base_va, mm->base_pa, mm->size, mm->attr); + tf_printf(" granularity:0x%zx\n", mm->granularity); ++mm; }; tf_printf("\n"); @@ -613,7 +615,7 @@ static int mmap_add_region_check(xlat_ctx_t *ctx, const mmap_region_t *mm) unsigned long long base_pa = mm->base_pa; uintptr_t base_va = mm->base_va; size_t size = mm->size; - mmap_attr_t attr = mm->attr; + size_t granularity = mm->granularity; unsigned long long end_pa = base_pa + size - 1; uintptr_t end_va = base_va + size - 1; @@ -622,6 +624,12 @@ static int mmap_add_region_check(xlat_ctx_t *ctx, const mmap_region_t *mm) !IS_PAGE_ALIGNED(size)) return -EINVAL; + if ((granularity != XLAT_BLOCK_SIZE(1)) && + (granularity != XLAT_BLOCK_SIZE(2)) && + (granularity != XLAT_BLOCK_SIZE(3))) { + return -EINVAL; + } + /* Check for overflows */ if ((base_pa > end_pa) || (base_va > end_va)) return -ERANGE; @@ -663,11 +671,9 @@ static int mmap_add_region_check(xlat_ctx_t *ctx, const mmap_region_t *mm) if (fully_overlapped_va) { #if PLAT_XLAT_TABLES_DYNAMIC - if ((attr & MT_DYNAMIC) || + if ((mm->attr & MT_DYNAMIC) || (mm_cursor->attr & MT_DYNAMIC)) return -EPERM; -#else - (void)attr; #endif /* PLAT_XLAT_TABLES_DYNAMIC */ if ((mm_cursor->base_va - mm_cursor->base_pa) != (base_va - base_pa)) |