Commit a0b9bb79 authored by Antonio Nino Diaz's avatar Antonio Nino Diaz
Browse files

xlat v2: Introduce xlat granule size helpers



The function xlat_arch_is_granule_size_supported() can be used to check
if a specific granule size is supported. In Armv8, AArch32 only supports
4 KiB pages. AArch64 supports 4 KiB, 16 KiB or 64 KiB depending on the
implementation, which is detected at runtime.

The function xlat_arch_get_max_supported_granule_size() returns the max
granule size supported by the implementation.

Even though right now they are only used by SPM, they may be useful in
other places in the future. This patch moves the code currently in SPM
to the xlat tables lib so that it can be reused.

Change-Id: If54624a5ecf20b9b9b7f38861b56383a03bbc8a4
Signed-off-by: default avatarAntonio Nino Diaz <antonio.ninodiaz@arm.com>
parent 83a393ba
......@@ -43,6 +43,8 @@
#ifndef __ASSEMBLY__
#include <sys/types.h>
#ifdef AARCH32
/* AArch32 specific translation table API */
void enable_mmu_secure(unsigned int flags);
......@@ -52,6 +54,9 @@ void enable_mmu_el1(unsigned int flags);
void enable_mmu_el3(unsigned int flags);
#endif /* AARCH32 */
int xlat_arch_is_granule_size_supported(size_t size);
size_t xlat_arch_get_max_supported_granule_size(void);
#endif /* __ASSEMBLY__ */
#endif /* __XLAT_MMU_HELPERS_H__ */
......@@ -18,6 +18,23 @@
#error ARMv7 target does not support LPAE MMU descriptors
#endif
/*
* Returns 1 if the provided granule size is supported, 0 otherwise.
*/
int xlat_arch_is_granule_size_supported(size_t size)
{
/*
* The Trusted Firmware uses long descriptor translation table format,
* which supports 4 KiB pages only.
*/
return (size == (4U * 1024U));
}
size_t xlat_arch_get_max_supported_granule_size(void)
{
return 4U * 1024U;
}
#if ENABLE_ASSERTIONS
unsigned long long xlat_arch_get_max_supported_pa(void)
{
......
......@@ -16,6 +16,42 @@
#include <xlat_tables_v2.h>
#include "../xlat_tables_private.h"
/*
* Returns 1 if the provided granule size is supported, 0 otherwise.
*/
int xlat_arch_is_granule_size_supported(size_t size)
{
u_register_t id_aa64mmfr0_el1 = read_id_aa64mmfr0_el1();
if (size == (4U * 1024U)) {
return ((id_aa64mmfr0_el1 >> ID_AA64MMFR0_EL1_TGRAN4_SHIFT) &
ID_AA64MMFR0_EL1_TGRAN4_MASK) ==
ID_AA64MMFR0_EL1_TGRAN4_SUPPORTED;
} else if (size == (16U * 1024U)) {
return ((id_aa64mmfr0_el1 >> ID_AA64MMFR0_EL1_TGRAN16_SHIFT) &
ID_AA64MMFR0_EL1_TGRAN16_MASK) ==
ID_AA64MMFR0_EL1_TGRAN16_SUPPORTED;
} else if (size == (64U * 1024U)) {
return ((id_aa64mmfr0_el1 >> ID_AA64MMFR0_EL1_TGRAN64_SHIFT) &
ID_AA64MMFR0_EL1_TGRAN64_MASK) ==
ID_AA64MMFR0_EL1_TGRAN64_SUPPORTED;
}
return 0;
}
size_t xlat_arch_get_max_supported_granule_size(void)
{
if (xlat_arch_is_granule_size_supported(64U * 1024U)) {
return 64U * 1024U;
} else if (xlat_arch_is_granule_size_supported(16U * 1024U)) {
return 16U * 1024U;
} else {
assert(xlat_arch_is_granule_size_supported(4U * 1024U));
return 4U * 1024U;
}
}
unsigned long long tcr_physical_addr_size_bits(unsigned long long max_addr)
{
/* Physical address can't exceed 48 bits */
......
......@@ -75,45 +75,18 @@ void spm_sp_setup(sp_context_t *sp_ctx)
#if ENABLE_ASSERTIONS
/* Get max granularity supported by the platform. */
unsigned int max_granule = xlat_arch_get_max_supported_granule_size();
u_register_t id_aa64mmfr0_el1 = read_id_aa64mmfr0_el1();
VERBOSE("Max translation granule size supported: %u KiB\n",
max_granule / 1024U);
int tgran64_supported =
((id_aa64mmfr0_el1 >> ID_AA64MMFR0_EL1_TGRAN64_SHIFT) &
ID_AA64MMFR0_EL1_TGRAN64_MASK) ==
ID_AA64MMFR0_EL1_TGRAN64_SUPPORTED;
int tgran16_supported =
((id_aa64mmfr0_el1 >> ID_AA64MMFR0_EL1_TGRAN16_SHIFT) &
ID_AA64MMFR0_EL1_TGRAN16_MASK) ==
ID_AA64MMFR0_EL1_TGRAN16_SUPPORTED;
int tgran4_supported =
((id_aa64mmfr0_el1 >> ID_AA64MMFR0_EL1_TGRAN4_SHIFT) &
ID_AA64MMFR0_EL1_TGRAN4_MASK) ==
ID_AA64MMFR0_EL1_TGRAN4_SUPPORTED;
uintptr_t max_granule_size;
if (tgran64_supported) {
max_granule_size = 64 * 1024;
} else if (tgran16_supported) {
max_granule_size = 16 * 1024;
} else {
assert(tgran4_supported);
max_granule_size = 4 * 1024;
}
VERBOSE("Max translation granule supported: %lu KiB\n",
max_granule_size / 1024);
uintptr_t max_granule_size_mask = max_granule_size - 1;
unsigned int max_granule_mask = max_granule - 1U;
/* Base must be aligned to the max granularity */
assert((ARM_SP_IMAGE_NS_BUF_BASE & max_granule_size_mask) == 0);
assert((ARM_SP_IMAGE_NS_BUF_BASE & max_granule_mask) == 0);
/* Size must be a multiple of the max granularity */
assert((ARM_SP_IMAGE_NS_BUF_SIZE & max_granule_size_mask) == 0);
assert((ARM_SP_IMAGE_NS_BUF_SIZE & max_granule_mask) == 0);
#endif /* ENABLE_ASSERTIONS */
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment