Merge pull request #1792 from satheesbalya-arm/sb1/sb1_2159_v84_xlat

lib/xlat_tables: Add support for ARMv8.4-TTST
This commit is contained in:
Antonio Niño Díaz 2019-01-31 09:24:08 +00:00 committed by GitHub
commit b57eb97262
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 104 additions and 31 deletions

View File

@ -204,6 +204,10 @@
/* ID_AA64MMFR2_EL1 definitions */
#define ID_AA64MMFR2_EL1 S3_0_C0_C7_2
#define ID_AA64MMFR2_EL1_ST_SHIFT U(28)
#define ID_AA64MMFR2_EL1_ST_MASK ULL(0xf)
#define ID_AA64MMFR2_EL1_CNP_SHIFT U(0)
#define ID_AA64MMFR2_EL1_CNP_MASK ULL(0xf)
@ -427,6 +431,7 @@
#define TCR_TxSZ_MIN ULL(16)
#define TCR_TxSZ_MAX ULL(39)
#define TCR_TxSZ_MAX_TTST ULL(48)
/* (internal) physical address size bits in EL3/EL1 */
#define TCR_PS_BITS_4GB ULL(0x0)

View File

@ -17,4 +17,10 @@ static inline bool is_armv8_2_ttcnp_present(void)
ID_AA64MMFR2_EL1_CNP_MASK) != 0U;
}
static inline bool is_armv8_4_ttst_present(void)
{
return ((read_id_aa64mmfr2_el1() >> ID_AA64MMFR2_EL1_ST_SHIFT) &
ID_AA64MMFR2_EL1_ST_MASK) == 1U;
}
#endif /* ARCH_FEATURES_H */

View File

@ -63,8 +63,7 @@
* is 1.
*
* Note that this macro assumes that the given virtual address space size is
* valid. Therefore, the caller is expected to check it is the case using the
* CHECK_VIRT_ADDR_SPACE_SIZE() macro first.
* valid.
*/
#define GET_XLAT_TABLE_LEVEL_BASE(_virt_addr_space_sz) \
(((_virt_addr_space_sz) > (ULL(1) << L1_XLAT_ADDRESS_SHIFT)) ? \

View File

@ -43,14 +43,22 @@ unsigned long long tcr_physical_addr_size_bits(unsigned long long max_addr);
* state.
*
* TCR.TxSZ is calculated as 64 minus the width of said address space.
* The value of TCR.TxSZ must be in the range 16 to 39 [1], which means that
* the virtual address space width must be in the range 48 to 25 bits.
* The value of TCR.TxSZ must be in the range 16 to 39 [1] or 48 [2],
* depending on Small Translation Table Support which means that
* the virtual address space width must be in the range 48 to 25 or 16 bits.
*
* [1] See the ARMv8-A Architecture Reference Manual (DDI 0487A.j) for more
* information:
* Page 1730: 'Input address size', 'For all translation stages'.
* [2] See section 12.2.55 in the ARMv8-A Architecture Reference Manual
* (DDI 0487D.a)
*/
/* Maximum value of TCR_ELx.T(0,1)SZ is 39 */
#define MIN_VIRT_ADDR_SPACE_SIZE (ULL(1) << (U(64) - TCR_TxSZ_MAX))
/* Maximum value of TCR_ELx.T(0,1)SZ is 48 */
#define MIN_VIRT_ADDR_SPACE_SIZE_TTST \
(ULL(1) << (U(64) - TCR_TxSZ_MAX_TTST))
#define MAX_VIRT_ADDR_SPACE_SIZE (ULL(1) << (U(64) - TCR_TxSZ_MIN))
/*
@ -58,9 +66,13 @@ unsigned long long tcr_physical_addr_size_bits(unsigned long long max_addr);
* virtual address space size. For a 4 KB page size,
* - level 0 supports virtual address spaces of widths 48 to 40 bits;
* - level 1 from 39 to 31;
* - level 2 from 30 to 25.
* - level 2 from 30 to 22.
* - level 3 from 21 to 16.
*
* Wider or narrower address spaces are not supported. As a result, level 3
* Small Translation Table (Armv8.4-TTST) support allows the starting level
* of the translation table from 3 for 4KB granularity. See section 12.2.55 in
* the ARMv8-A Architecture Reference Manual (DDI 0487D.a). In Armv8.3 and below
* wider or narrower address spaces are not supported. As a result, level 3
* cannot be used as initial lookup level with 4 KB granularity. See section
* D4.2.5 in the ARMv8-A Architecture Reference Manual (DDI 0487A.j) for more
* information.
@ -71,13 +83,14 @@ unsigned long long tcr_physical_addr_size_bits(unsigned long long max_addr);
* is 1.
*
* Note that this macro assumes that the given virtual address space size is
* valid. Therefore, the caller is expected to check it is the case using the
* CHECK_VIRT_ADDR_SPACE_SIZE() macro first.
* valid.
*/
#define GET_XLAT_TABLE_LEVEL_BASE(_virt_addr_space_sz) \
(((_virt_addr_space_sz) > (ULL(1) << L0_XLAT_ADDRESS_SHIFT)) \
? 0U \
: (((_virt_addr_space_sz) > (ULL(1) << L1_XLAT_ADDRESS_SHIFT)) \
? 1U : 2U))
: (((_virt_addr_space_sz) > (ULL(1) << L1_XLAT_ADDRESS_SHIFT)) \
? 1U \
: (((_virt_addr_space_sz) > (ULL(1) << L2_XLAT_ADDRESS_SHIFT)) \
? 2U : 3U)))
#endif /* XLAT_TABLES_AARCH64_H */

View File

@ -13,18 +13,6 @@
#include "aarch64/xlat_tables_aarch64.h"
#endif
/*
* Evaluates to 1 if the given virtual address space size is valid, or 0 if it's
* not.
*
* A valid size is one that is a power of 2 and is within the architectural
* limits. Not that these limits are different for AArch32 and AArch64.
*/
#define CHECK_VIRT_ADDR_SPACE_SIZE(size) \
(((unsigned long long)(size) >= MIN_VIRT_ADDR_SPACE_SIZE) && \
((unsigned long long)(size) <= MAX_VIRT_ADDR_SPACE_SIZE) && \
IS_POWER_OF_TWO(size))
/*
* Evaluates to 1 if the given physical address space size is a power of 2,
* or 0 if it's not.

View File

@ -125,9 +125,6 @@ struct xlat_ctx {
#define REGISTER_XLAT_CONTEXT_FULL_SPEC(_ctx_name, _mmap_count, \
_xlat_tables_count, _virt_addr_space_size, \
_phy_addr_space_size, _xlat_regime, _section_name)\
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);\
\

View File

@ -55,6 +55,11 @@ void init_xlat_tables(void)
{
unsigned long long max_pa;
uintptr_t max_va;
assert(PLAT_VIRT_ADDR_SPACE_SIZE >= MIN_VIRT_ADDR_SPACE_SIZE);
assert(PLAT_VIRT_ADDR_SPACE_SIZE <= MAX_VIRT_ADDR_SPACE_SIZE);
assert(IS_POWER_OF_TWO(PLAT_VIRT_ADDR_SPACE_SIZE));
print_mmap();
init_xlation_table(0U, base_xlation_table, XLAT_TABLE_LEVEL_BASE,
&max_va, &max_pa);

View File

@ -10,7 +10,7 @@
#include <platform_def.h>
#include <arch.h>
#include <arch_helpers.h>
#include <arch_features.h>
#include <common/bl_common.h>
#include <lib/utils.h>
#include <lib/xlat_tables/xlat_tables.h>
@ -79,6 +79,21 @@ static unsigned long long get_max_supported_pa(void)
return (1ULL << pa_range_bits_arr[pa_range]) - 1ULL;
}
/*
* Return minimum virtual address space size supported by the architecture
*/
static uintptr_t xlat_get_min_virt_addr_space_size(void)
{
uintptr_t ret;
if (is_armv8_4_ttst_present())
ret = MIN_VIRT_ADDR_SPACE_SIZE_TTST;
else
ret = MIN_VIRT_ADDR_SPACE_SIZE;
return ret;
}
#endif /* ENABLE_ASSERTIONS */
unsigned int xlat_arch_current_el(void)
@ -104,6 +119,12 @@ void init_xlat_tables(void)
{
unsigned long long max_pa;
uintptr_t max_va;
assert(PLAT_VIRT_ADDR_SPACE_SIZE >=
(xlat_get_min_virt_addr_space_size() - 1U));
assert(PLAT_VIRT_ADDR_SPACE_SIZE <= MAX_VIRT_ADDR_SPACE_SIZE);
assert(IS_POWER_OF_TWO(PLAT_VIRT_ADDR_SPACE_SIZE));
print_mmap();
init_xlation_table(0U, base_xlation_table, XLAT_TABLE_LEVEL_BASE,
&max_va, &max_pa);

View File

@ -16,9 +16,6 @@
#error xlat tables v2 must be used with HW_ASSISTED_COHERENCY
#endif
CASSERT(CHECK_VIRT_ADDR_SPACE_SIZE(PLAT_VIRT_ADDR_SPACE_SIZE),
assert_valid_virt_addr_space_size);
CASSERT(CHECK_PHY_ADDR_SPACE_SIZE(PLAT_PHY_ADDR_SPACE_SIZE),
assert_valid_phy_addr_space_size);

View File

@ -45,6 +45,14 @@ unsigned long long xlat_arch_get_max_supported_pa(void)
/* Physical address space size for long descriptor format. */
return (1ULL << 40) - 1ULL;
}
/*
* Return minimum virtual address space size supported by the architecture
*/
uintptr_t xlat_get_min_virt_addr_space_size(void)
{
return MIN_VIRT_ADDR_SPACE_SIZE;
}
#endif /* ENABLE_ASSERTIONS*/
bool is_mmu_enabled_ctx(const xlat_ctx_t *ctx)
@ -193,7 +201,12 @@ void setup_mmu_cfg(uint64_t *params, unsigned int flags,
if (max_va != UINT32_MAX) {
uintptr_t virtual_addr_space_size = max_va + 1U;
assert(CHECK_VIRT_ADDR_SPACE_SIZE(virtual_addr_space_size));
assert(virtual_addr_space_size >=
xlat_get_min_virt_addr_space_size());
assert(virtual_addr_space_size <=
MAX_VIRT_ADDR_SPACE_SIZE);
assert(IS_POWER_OF_TWO(virtual_addr_space_size));
/*
* __builtin_ctzll(0) is undefined but here we are guaranteed
* that virtual_addr_space_size is in the range [1, UINT32_MAX].

View File

@ -101,6 +101,21 @@ unsigned long long xlat_arch_get_max_supported_pa(void)
return (1ULL << pa_range_bits_arr[pa_range]) - 1ULL;
}
/*
* Return minimum virtual address space size supported by the architecture
*/
uintptr_t xlat_get_min_virt_addr_space_size(void)
{
uintptr_t ret;
if (is_armv8_4_ttst_present())
ret = MIN_VIRT_ADDR_SPACE_SIZE_TTST;
else
ret = MIN_VIRT_ADDR_SPACE_SIZE;
return ret;
}
#endif /* ENABLE_ASSERTIONS*/
bool is_mmu_enabled_ctx(const xlat_ctx_t *ctx)
@ -221,7 +236,11 @@ void setup_mmu_cfg(uint64_t *params, unsigned int flags,
assert(max_va < ((uint64_t)UINTPTR_MAX));
virtual_addr_space_size = (uintptr_t)max_va + 1U;
assert(CHECK_VIRT_ADDR_SPACE_SIZE(virtual_addr_space_size));
assert(virtual_addr_space_size >=
xlat_get_min_virt_addr_space_size());
assert(virtual_addr_space_size <= MAX_VIRT_ADDR_SPACE_SIZE);
assert(IS_POWER_OF_TWO(virtual_addr_space_size));
/*
* __builtin_ctzll(0) is undefined but here we are guaranteed that

View File

@ -1146,6 +1146,11 @@ void __init init_xlat_tables_ctx(xlat_ctx_t *ctx)
mmap_region_t *mm = ctx->mmap;
assert(ctx->va_max_address >=
(xlat_get_min_virt_addr_space_size() - 1U));
assert(ctx->va_max_address <= (MAX_VIRT_ADDR_SPACE_SIZE - 1U));
assert(IS_POWER_OF_TWO(ctx->va_max_address + 1U));
xlat_mmap_print(mm);
/* All tables must be zeroed before mapping any region. */

View File

@ -102,4 +102,9 @@ bool is_mmu_enabled_ctx(const xlat_ctx_t *ctx);
/* Returns true if the data cache is enabled at the current EL. */
bool is_dcache_enabled(void);
/*
* Returns minimum virtual address space size supported by the architecture
*/
uintptr_t xlat_get_min_virt_addr_space_size(void);
#endif /* XLAT_TABLES_PRIVATE_H */