diff --git a/include/lib/xlat_tables/xlat_tables_v2.h b/include/lib/xlat_tables/xlat_tables_v2.h index 9db671910c56681d2b0c4c7c0df3b71f4da7ab22..a5cdfee8d7fcdc2990cb5fba966510915c379171 100644 --- a/include/lib/xlat_tables/xlat_tables_v2.h +++ b/include/lib/xlat_tables/xlat_tables_v2.h @@ -13,6 +13,7 @@ #include #include #include +#include /* Helper macro to define entries for mmap_region_t. It creates * identity mappings for each region. @@ -82,6 +83,44 @@ typedef struct mmap_region { mmap_attr_t attr; } mmap_region_t; +/* + * Declare the translation context type. + * Its definition is private. + */ +typedef struct xlat_ctx xlat_ctx_t; + +/* + * Statically allocate a translation context and associated structures. Also + * initialize them. + * + * _ctx_name: + * Prefix for the translation context variable. + * E.g. If _ctx_name is 'foo', the variable will be called 'foo_xlat_ctx'. + * Useful to distinguish multiple contexts from one another. + * + * _mmap_count: + * Number of mmap_region_t to allocate. + * Would typically be MAX_MMAP_REGIONS for the translation context describing + * the BL image currently executing. + * + * _xlat_tables_count: + * Number of sub-translation tables to allocate. + * Would typically be MAX_XLAT_TABLES for the translation context describing + * the BL image currently executing. + * Note that this is only for sub-tables ; at the initial lookup level, there + * is always a single table. + * + * _virt_addr_space_size, _phy_addr_space_size: + * Size (in bytes) of the virtual (resp. physical) address space. + * Would typically be PLAT_VIRT_ADDR_SPACE_SIZE + * (resp. PLAT_PHY_ADDR_SPACE_SIZE) for the translation context describing the + * BL image currently executing. + */ +#define REGISTER_XLAT_CONTEXT(_ctx_name, _mmap_count, _xlat_tables_count, \ + _virt_addr_space_size, _phy_addr_space_size) \ + _REGISTER_XLAT_CONTEXT(_ctx_name, _mmap_count, _xlat_tables_count, \ + _virt_addr_space_size, _phy_addr_space_size) + /* Generic translation table APIs */ /* diff --git a/include/lib/xlat_tables/xlat_tables_v2_helpers.h b/include/lib/xlat_tables/xlat_tables_v2_helpers.h new file mode 100644 index 0000000000000000000000000000000000000000..f5e310066fe2f7895c661554f4832286b6b94e76 --- /dev/null +++ b/include/lib/xlat_tables/xlat_tables_v2_helpers.h @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* + * This header file contains internal definitions that are not supposed to be + * used outside of this library code. + */ + +#ifndef __XLAT_TABLES_V2_HELPERS_H__ +#define __XLAT_TABLES_V2_HELPERS_H__ + +#ifndef __XLAT_TABLES_V2_H__ +#error "Do not include this header file directly. Include xlat_tables_v2.h instead." +#endif + +#ifndef __ASSEMBLY__ + +#include +#include +#include +#include +#include + +/* Forward declaration */ +struct mmap_region; + +/* Struct that holds all information about the translation tables. */ +struct xlat_ctx { + /* + * Max allowed Virtual and Physical Addresses. + */ + unsigned long long pa_max_address; + uintptr_t va_max_address; + + /* + * Array of all memory regions stored in order of ascending end address + * and ascending size to simplify the code that allows overlapping + * regions. The list is terminated by the first entry with size == 0. + * The max size of the list is stored in `mmap_num`. `mmap` points to an + * array of mmap_num + 1 elements, so that there is space for the final + * null entry. + */ + struct mmap_region *mmap; + unsigned int mmap_num; + + /* + * Array of finer-grain translation tables. + * For example, if the initial lookup level is 1 then this array would + * contain both level-2 and level-3 entries. + */ + uint64_t (*tables)[XLAT_TABLE_ENTRIES]; + unsigned int tables_num; + /* + * Keep track of how many regions are mapped in each table. The base + * table can't be unmapped so it isn't needed to keep track of it. + */ +#if PLAT_XLAT_TABLES_DYNAMIC + int *tables_mapped_regions; +#endif /* PLAT_XLAT_TABLES_DYNAMIC */ + + unsigned int next_table; + + /* + * Base translation table. It doesn't need to have the same amount of + * entries as the ones used for other levels. + */ + uint64_t *base_table; + unsigned int base_table_entries; + + /* + * Max Physical and Virtual addresses currently in use by the + * translation tables. These might get updated as we map/unmap memory + * regions but they will never go beyond pa/va_max_address. + */ + unsigned long long max_pa; + uintptr_t max_va; + + /* Level of the base translation table. */ + unsigned int base_level; + + /* Set to 1 when the translation tables are initialized. */ + unsigned int initialized; + + /* + * Bit mask that has to be ORed to the rest of a translation table + * descriptor in order to prohibit execution of code at the exception + * level of this translation context. + */ + uint64_t execute_never_mask; +}; + +#if PLAT_XLAT_TABLES_DYNAMIC +#define _ALLOC_DYNMAP_STRUCT(_ctx_name, _xlat_tables_count) \ + static int _ctx_name##_mapped_regions[_xlat_tables_count]; + +#define _REGISTER_DYNMAP_STRUCT(_ctx_name) \ + .tables_mapped_regions = _ctx_name##_mapped_regions, +#else +#define _ALLOC_DYNMAP_STRUCT(_ctx_name, _xlat_tables_count) \ + /* do nothing */ + +#define _REGISTER_DYNMAP_STRUCT(_ctx_name) \ + /* do nothing */ +#endif /* PLAT_XLAT_TABLES_DYNAMIC */ + + +#define _REGISTER_XLAT_CONTEXT(_ctx_name, _mmap_count, _xlat_tables_count, \ + _virt_addr_space_size, _phy_addr_space_size) \ + CASSERT(CHECK_VIRT_ADDR_SPACE_SIZE(_virt_addr_space_size), \ + assert_invalid_virtual_addr_space_size_for_##_ctx_name); \ + \ + CASSERT(CHECK_PHY_ADDR_SPACE_SIZE(_phy_addr_space_size), \ + assert_invalid_physical_addr_space_sizefor_##_ctx_name); \ + \ + static mmap_region_t _ctx_name##_mmap[_mmap_count + 1]; \ + \ + static uint64_t _ctx_name##_xlat_tables[_xlat_tables_count] \ + [XLAT_TABLE_ENTRIES] \ + __aligned(XLAT_TABLE_SIZE) __section("xlat_table"); \ + \ + static uint64_t _ctx_name##_base_xlat_table \ + [GET_NUM_BASE_LEVEL_ENTRIES(_virt_addr_space_size)] \ + __aligned(GET_NUM_BASE_LEVEL_ENTRIES(_virt_addr_space_size) \ + * sizeof(uint64_t)); \ + \ + _ALLOC_DYNMAP_STRUCT(_ctx_name, _xlat_tables_count) \ + \ + static xlat_ctx_t _ctx_name##_xlat_ctx = { \ + .va_max_address = (_virt_addr_space_size) - 1, \ + .pa_max_address = (_phy_addr_space_size) - 1, \ + .mmap = _ctx_name##_mmap, \ + .mmap_num = _mmap_count, \ + .base_level = GET_XLAT_TABLE_LEVEL_BASE(_virt_addr_space_size), \ + .base_table = _ctx_name##_base_xlat_table, \ + .base_table_entries = \ + GET_NUM_BASE_LEVEL_ENTRIES(_virt_addr_space_size), \ + .tables = _ctx_name##_xlat_tables, \ + .tables_num = _xlat_tables_count, \ + _REGISTER_DYNMAP_STRUCT(_ctx_name) \ + .max_pa = 0, \ + .max_va = 0, \ + .next_table = 0, \ + .initialized = 0, \ + } + +#endif /*__ASSEMBLY__*/ + +#endif /* __XLAT_TABLES_V2_HELPERS_H__ */ diff --git a/lib/xlat_tables_v2/xlat_tables_common.c b/lib/xlat_tables_v2/xlat_tables_common.c index fce6017853cbfa585f1470be9e98570387189962..f214e5cc094c76ec9f2d5fccc2e101d3378e601f 100644 --- a/lib/xlat_tables_v2/xlat_tables_common.c +++ b/lib/xlat_tables_v2/xlat_tables_common.c @@ -7,7 +7,6 @@ #include #include #include -#include #include #include #include @@ -38,59 +37,12 @@ # endif #endif -CASSERT(CHECK_VIRT_ADDR_SPACE_SIZE(PLAT_VIRT_ADDR_SPACE_SIZE), - assert_invalid_virtual_addr_space_size); - -CASSERT(CHECK_PHY_ADDR_SPACE_SIZE(PLAT_PHY_ADDR_SPACE_SIZE), - assert_invalid_physical_addr_space_size); - -#define NUM_BASE_LEVEL_ENTRIES \ - GET_NUM_BASE_LEVEL_ENTRIES(PLAT_VIRT_ADDR_SPACE_SIZE) - -#define XLAT_TABLE_LEVEL_BASE \ - GET_XLAT_TABLE_LEVEL_BASE(PLAT_VIRT_ADDR_SPACE_SIZE) - /* - * Private variables used by the TF + * Allocate and initialise the default translation context for the BL image + * currently executing. */ -static mmap_region_t tf_mmap[MAX_MMAP_REGIONS + 1]; - -static uint64_t tf_xlat_tables[MAX_XLAT_TABLES][XLAT_TABLE_ENTRIES] - __aligned(XLAT_TABLE_SIZE) __section("xlat_table"); - -static uint64_t tf_base_xlat_table[NUM_BASE_LEVEL_ENTRIES] - __aligned(NUM_BASE_LEVEL_ENTRIES * sizeof(uint64_t)); - -#if PLAT_XLAT_TABLES_DYNAMIC -static int xlat_tables_mapped_regions[MAX_XLAT_TABLES]; -#endif /* PLAT_XLAT_TABLES_DYNAMIC */ - -xlat_ctx_t tf_xlat_ctx = { - - .pa_max_address = PLAT_PHY_ADDR_SPACE_SIZE - 1, - .va_max_address = PLAT_VIRT_ADDR_SPACE_SIZE - 1, - - .mmap = tf_mmap, - .mmap_num = MAX_MMAP_REGIONS, - - .tables = tf_xlat_tables, - .tables_num = MAX_XLAT_TABLES, -#if PLAT_XLAT_TABLES_DYNAMIC - .tables_mapped_regions = xlat_tables_mapped_regions, -#endif /* PLAT_XLAT_TABLES_DYNAMIC */ - - .base_table = tf_base_xlat_table, - .base_table_entries = NUM_BASE_LEVEL_ENTRIES, - - .max_pa = 0, - .max_va = 0, - - .next_table = 0, - - .base_level = XLAT_TABLE_LEVEL_BASE, - - .initialized = 0 -}; +REGISTER_XLAT_CONTEXT(tf, MAX_MMAP_REGIONS, MAX_XLAT_TABLES, + PLAT_VIRT_ADDR_SPACE_SIZE, PLAT_PHY_ADDR_SPACE_SIZE); void mmap_add_region(unsigned long long base_pa, uintptr_t base_va, size_t size, mmap_attr_t attr) @@ -143,8 +95,8 @@ void init_xlat_tables(void) init_xlation_table(&tf_xlat_ctx); xlat_tables_print(&tf_xlat_ctx); - assert(tf_xlat_ctx.max_va <= PLAT_VIRT_ADDR_SPACE_SIZE - 1); - assert(tf_xlat_ctx.max_pa <= PLAT_PHY_ADDR_SPACE_SIZE - 1); + assert(tf_xlat_ctx.max_va <= tf_xlat_ctx.va_max_address); + assert(tf_xlat_ctx.max_pa <= tf_xlat_ctx.pa_max_address); init_xlat_tables_arch(tf_xlat_ctx.max_pa); } diff --git a/lib/xlat_tables_v2/xlat_tables_private.h b/lib/xlat_tables_v2/xlat_tables_private.h index 83aa5b1e5f4471aeeec5bcae375c8e78d672ea29..45eaf55d2cf0cdb02b0dc19cc8fcdc708879e4e8 100644 --- a/lib/xlat_tables_v2/xlat_tables_private.h +++ b/lib/xlat_tables_v2/xlat_tables_private.h @@ -10,73 +10,6 @@ #include #include -/* Struct that holds all information about the translation tables. */ -typedef struct { - - /* - * Max allowed Virtual and Physical Addresses. - */ - unsigned long long pa_max_address; - uintptr_t va_max_address; - - /* - * Array of all memory regions stored in order of ascending end address - * and ascending size to simplify the code that allows overlapping - * regions. The list is terminated by the first entry with size == 0. - * The max size of the list is stored in `mmap_num`. `mmap` points to an - * array of mmap_num + 1 elements, so that there is space for the final - * null entry. - */ - mmap_region_t *mmap; - unsigned int mmap_num; - - /* - * Array of finer-grain translation tables. - * For example, if the initial lookup level is 1 then this array would - * contain both level-2 and level-3 entries. - */ - uint64_t (*tables)[XLAT_TABLE_ENTRIES]; - unsigned int tables_num; - /* - * Keep track of how many regions are mapped in each table. The base - * table can't be unmapped so it isn't needed to keep track of it. - */ -#if PLAT_XLAT_TABLES_DYNAMIC - int *tables_mapped_regions; -#endif /* PLAT_XLAT_TABLES_DYNAMIC */ - - unsigned int next_table; - - /* - * Base translation table. It doesn't need to have the same amount of - * entries as the ones used for other levels. - */ - uint64_t *base_table; - unsigned int base_table_entries; - - /* - * Max Physical and Virtual addresses currently in use by the - * translation tables. These might get updated as we map/unmap memory - * regions but they will never go beyond pa/va_max_address. - */ - unsigned long long max_pa; - uintptr_t max_va; - - /* Level of the base translation table. */ - unsigned int base_level; - - /* Set to 1 when the translation tables are initialized. */ - unsigned int initialized; - - /* - * Bit mask that has to be ORed to the rest of a translation table - * descriptor in order to prohibit execution of code at the exception - * level of this translation context. - */ - uint64_t execute_never_mask; - -} xlat_ctx_t; - #if PLAT_XLAT_TABLES_DYNAMIC /* * Shifts and masks to access fields of an mmap_attr_t