aboutsummaryrefslogtreecommitdiff
path: root/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c
diff options
context:
space:
mode:
authorAntonio Nino Diaz <antonio.ninodiaz@arm.com>2018-06-11 13:40:32 +0100
committerAntonio Nino Diaz <antonio.ninodiaz@arm.com>2018-06-13 09:19:41 +0100
commita0b9bb79a035a7421318502d04dde723e7381b6a (patch)
treecfab22e01b08b220b30d3f630eaad12d6310f2db /lib/xlat_tables_v2/aarch64/xlat_tables_arch.c
parent83a393ba3e15a8198520247a25e61c5c04c89ead (diff)
downloadtrusted-firmware-a-a0b9bb79a035a7421318502d04dde723e7381b6a.tar.gz
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: Antonio Nino Diaz <antonio.ninodiaz@arm.com>
Diffstat (limited to 'lib/xlat_tables_v2/aarch64/xlat_tables_arch.c')
-rw-r--r--lib/xlat_tables_v2/aarch64/xlat_tables_arch.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c b/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c
index b3504e1e2c..c501e70749 100644
--- a/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c
+++ b/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c
@@ -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 */