aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitris Papastamos <dimitris.papastamos@arm.com>2018-08-22 10:24:24 +0100
committerGitHub <noreply@github.com>2018-08-22 10:24:24 +0100
commit61e7c0542e965e6e03569ed13b81ed185080c057 (patch)
treece633034b3e11c978a68238eb51735a09b21c991
parent36d47074415a94846f3c395899d6276774cc3384 (diff)
parent5f8359188008aff6a2a8e936003827ae771ed99f (diff)
downloadtrusted-firmware-a-61e7c0542e965e6e03569ed13b81ed185080c057.tar.gz
Merge pull request #1533 from jeenu-arm/mpam
AArch64: Enable MPAM for lower ELs
-rw-r--r--Makefile2
-rw-r--r--bl31/bl31.mk4
-rw-r--r--docs/user-guide.rst11
-rw-r--r--include/lib/aarch64/arch.h15
-rw-r--r--include/lib/aarch64/arch_helpers.h5
-rw-r--r--include/lib/extensions/mpam.h15
-rw-r--r--lib/el3_runtime/aarch64/context_mgmt.c5
-rw-r--r--lib/extensions/mpam/mpam.c40
-rw-r--r--make_helpers/defaults.mk3
9 files changed, 100 insertions, 0 deletions
diff --git a/Makefile b/Makefile
index 18c4873429..cb7eb08cfb 100644
--- a/Makefile
+++ b/Makefile
@@ -550,6 +550,7 @@ $(eval $(call assert_boolean,DYN_DISABLE_AUTH))
$(eval $(call assert_boolean,EL3_EXCEPTION_HANDLING))
$(eval $(call assert_boolean,ENABLE_AMU))
$(eval $(call assert_boolean,ENABLE_ASSERTIONS))
+$(eval $(call assert_boolean,ENABLE_MPAM_FOR_LOWER_ELS))
$(eval $(call assert_boolean,ENABLE_PLAT_COMPAT))
$(eval $(call assert_boolean,ENABLE_PMF))
$(eval $(call assert_boolean,ENABLE_PSCI_STAT))
@@ -601,6 +602,7 @@ $(eval $(call add_define,CTX_INCLUDE_FPREGS))
$(eval $(call add_define,EL3_EXCEPTION_HANDLING))
$(eval $(call add_define,ENABLE_AMU))
$(eval $(call add_define,ENABLE_ASSERTIONS))
+$(eval $(call add_define,ENABLE_MPAM_FOR_LOWER_ELS))
$(eval $(call add_define,ENABLE_PLAT_COMPAT))
$(eval $(call add_define,ENABLE_PMF))
$(eval $(call add_define,ENABLE_PSCI_STAT))
diff --git a/bl31/bl31.mk b/bl31/bl31.mk
index 066c7010dd..77779548fc 100644
--- a/bl31/bl31.mk
+++ b/bl31/bl31.mk
@@ -64,6 +64,10 @@ ifeq (${ENABLE_SVE_FOR_NS},1)
BL31_SOURCES += lib/extensions/sve/sve.c
endif
+ifeq (${ENABLE_MPAM_FOR_LOWER_ELS},1)
+BL31_SOURCES += lib/extensions/mpam/mpam.c
+endif
+
ifeq (${WORKAROUND_CVE_2017_5715},1)
BL31_SOURCES += lib/cpus/aarch64/wa_cve_2017_5715_bpiall.S \
lib/cpus/aarch64/wa_cve_2017_5715_mmu.S
diff --git a/docs/user-guide.rst b/docs/user-guide.rst
index 46370ce087..3f8170fd08 100644
--- a/docs/user-guide.rst
+++ b/docs/user-guide.rst
@@ -351,6 +351,17 @@ Common build options
that is only required for the assertion and does not fit in the assertion
itself.
+- ``ENABLE_MPAM_FOR_LOWER_ELS``: Boolean option to enable lower ELs to use MPAM
+ feature. MPAM is an optional Armv8.4 extension that enables various memory
+ system components and resources to define partitions; software running at
+ various ELs can assign themselves to desired partition to control their
+ performance aspects.
+
+ When this option is set to ``1``, EL3 allows lower ELs to access their own
+ MPAM registers without trapping into EL3. This option doesn't make use of
+ partitioning in EL3, however. Platform initialisation code should configure
+ and use partitions in EL3 as required. This option defaults to ``0``.
+
- ``ENABLE_PMF``: Boolean option to enable support for optional Performance
Measurement Framework(PMF). Default is 0.
diff --git a/include/lib/aarch64/arch.h b/include/lib/aarch64/arch.h
index c9619f6c69..cccb286c50 100644
--- a/include/lib/aarch64/arch.h
+++ b/include/lib/aarch64/arch.h
@@ -117,6 +117,8 @@
#define ID_AA64PFR0_SVE_SHIFT U(32)
#define ID_AA64PFR0_SVE_MASK ULL(0xf)
#define ID_AA64PFR0_SVE_LENGTH U(4)
+#define ID_AA64PFR0_MPAM_SHIFT U(40)
+#define ID_AA64PFR0_MPAM_MASK ULL(0xf)
#define ID_AA64PFR0_CSV2_SHIFT U(56)
#define ID_AA64PFR0_CSV2_MASK ULL(0xf)
#define ID_AA64PFR0_CSV2_LENGTH U(4)
@@ -658,6 +660,14 @@
#define PMBLIMITR_EL1 S3_0_C9_C10_0
/*******************************************************************************
+ * Definitions for system register interface to MPAM
+ ******************************************************************************/
+#define MPAMIDR_EL1 S3_0_C10_C4_4
+#define MPAM2_EL2 S3_4_C10_C5_0
+#define MPAMHCR_EL2 S3_4_C10_C4_0
+#define MPAM3_EL3 S3_6_C10_C5_0
+
+/*******************************************************************************
* Definitions for system register interface to AMU for ARMv8.4 onwards
******************************************************************************/
#define AMCR_EL0 S3_3_C13_C2_0
@@ -722,6 +732,11 @@
#define AMCGCR_EL0_CG1NC_LENGTH U(8)
#define AMCGCR_EL0_CG1NC_MASK U(0xff)
+/* MPAM register definitions */
+#define MPAM3_EL3_MPAMEN_BIT (ULL(1) << 63)
+
+#define MPAMIDR_HAS_HCR_BIT (ULL(1) << 17)
+
/*******************************************************************************
* RAS system registers
*******************************************************************************/
diff --git a/include/lib/aarch64/arch_helpers.h b/include/lib/aarch64/arch_helpers.h
index 58ec943a2d..8e82dbdc7f 100644
--- a/include/lib/aarch64/arch_helpers.h
+++ b/include/lib/aarch64/arch_helpers.h
@@ -328,6 +328,11 @@ DEFINE_RENAME_SYSREG_RW_FUNCS(amcntenset0_el0, AMCNTENSET0_EL0)
DEFINE_RENAME_SYSREG_RW_FUNCS(amcntenclr1_el0, AMCNTENCLR1_EL0)
DEFINE_RENAME_SYSREG_RW_FUNCS(amcntenset1_el0, AMCNTENSET1_EL0)
+DEFINE_RENAME_SYSREG_READ_FUNC(mpamidr_el1, MPAMIDR_EL1)
+DEFINE_RENAME_SYSREG_RW_FUNCS(mpam3_el3, MPAM3_EL3)
+DEFINE_RENAME_SYSREG_RW_FUNCS(mpam2_el2, MPAM2_EL2)
+DEFINE_RENAME_SYSREG_RW_FUNCS(mpamhcr_el2, MPAMHCR_EL2)
+
DEFINE_RENAME_SYSREG_RW_FUNCS(pmblimitr_el1, PMBLIMITR_EL1)
DEFINE_RENAME_SYSREG_WRITE_FUNC(zcr_el3, ZCR_EL3)
diff --git a/include/lib/extensions/mpam.h b/include/lib/extensions/mpam.h
new file mode 100644
index 0000000000..571b96b656
--- /dev/null
+++ b/include/lib/extensions/mpam.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MPAM_H
+#define MPAM_H
+
+#include <stdbool.h>
+
+bool mpam_supported(void);
+void mpam_enable(int el2_unused);
+
+#endif /* MPAM_H */
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index f389368d46..2812bdaaba 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -12,6 +12,7 @@
#include <context.h>
#include <context_mgmt.h>
#include <interrupt_mgmt.h>
+#include <mpam.h>
#include <platform.h>
#include <platform_def.h>
#include <pubsub_events.h>
@@ -244,6 +245,10 @@ static void enable_extensions_nonsecure(int el2_unused)
#if ENABLE_SVE_FOR_NS
sve_enable(el2_unused);
#endif
+
+#if ENABLE_MPAM_FOR_LOWER_ELS
+ mpam_enable(el2_unused);
+#endif
#endif
}
diff --git a/lib/extensions/mpam/mpam.c b/lib/extensions/mpam/mpam.c
new file mode 100644
index 0000000000..e628827bf6
--- /dev/null
+++ b/lib/extensions/mpam/mpam.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <mpam.h>
+#include <stdbool.h>
+
+bool mpam_supported(void)
+{
+ uint64_t features = read_id_aa64dfr0_el1() >> ID_AA64PFR0_MPAM_SHIFT;
+
+ return ((features & ID_AA64PFR0_MPAM_MASK) != 0U);
+}
+
+void mpam_enable(int el2_unused)
+{
+ if (!mpam_supported())
+ return;
+
+ /*
+ * Enable MPAM, and disable trapping to EL3 when lower ELs access their
+ * own MPAM registers.
+ */
+ write_mpam3_el3(MPAM3_EL3_MPAMEN_BIT);
+
+ /*
+ * If EL2 is implemented but unused, disable trapping to EL2 when lower
+ * ELs access their own MPAM registers.
+ */
+ if (el2_unused != 0) {
+ write_mpam2_el2(0);
+
+ if ((read_mpamidr_el1() & MPAMIDR_HAS_HCR_BIT) != 0U)
+ write_mpamhcr_el2(0);
+ }
+}
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
index e4b5bdc921..49f403d2ed 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -62,6 +62,9 @@ DEFAULT_PLAT := fvp
# development platforms.
DYN_DISABLE_AUTH := 0
+# Build option to enable MPAM for lower ELs
+ENABLE_MPAM_FOR_LOWER_ELS := 0
+
# Flag to enable Performance Measurement Framework
ENABLE_PMF := 0