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:
commit
b57eb97262
|
@ -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)
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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)) ? \
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);\
|
||||
\
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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].
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue