AArch64: Enable MPAM for lower ELs
authorJeenu Viswambharan <jeenu.viswambharan@arm.com>
Tue, 31 Jul 2018 15:13:33 +0000 (16:13 +0100)
committerJeenu Viswambharan <jeenu.viswambharan@arm.com>
Mon, 20 Aug 2018 06:32:19 +0000 (07:32 +0100)
Memory Partitioning And Monitoring is an Armv8.4 feature that enables
various memory system components and resources to define partitions.
Software running at various ELs can then assign themselves to the
desired partition to control their performance aspects.

With this patch, when ENABLE_MPAM_FOR_LOWER_ELS is set to 1, EL3 allows
lower ELs to access their own MPAM registers without trapping to EL3.
This patch however doesn't make use of partitioning in EL3; platform
initialisation code should configure and use partitions in EL3 if
required.

Change-Id: I5a55b6771ccaa0c1cffc05543d2116b60cbbcdcd
Co-authored-by: James Morse <james.morse@arm.com>
Signed-off-by: Jeenu Viswambharan <jeenu.viswambharan@arm.com>
Makefile
bl31/bl31.mk
docs/user-guide.rst
include/lib/aarch64/arch.h
include/lib/aarch64/arch_helpers.h
include/lib/extensions/mpam.h [new file with mode: 0644]
lib/el3_runtime/aarch64/context_mgmt.c
lib/extensions/mpam/mpam.c [new file with mode: 0644]
make_helpers/defaults.mk

index 18c4873429d5fe4d716b991f4688eb850979b9ff..cb7eb08cfbebf2f864b217ce1ce993f137bd6beb 100644 (file)
--- 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))
index bff965386528625b130b3e7de6001a69037e2f89..c99b637defe596eba2d58bb0f50a348871ef877c 100644 (file)
@@ -63,6 +63,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
index 2b90bece84a82dc84d214aec37bcb7bdeab228b6..2ef7c61d34cc2fd950079c70a9e7f989e63a0f2c 100644 (file)
@@ -350,6 +350,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.
 
index c9619f6c69d22aa928a3888ae42435465ab3090c..cccb286c5069e6897d6a208634eef886ef8ae8a5 100644 (file)
 #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)
  ******************************************************************************/
 #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 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
  *******************************************************************************/
index 58ec943a2d77979bd0a6fb5347a2d4a45dd23ec5..8e82dbdc7fa75fb8af2d93cc10493b75bcfc6d4e 100644 (file)
@@ -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 (file)
index 0000000..571b96b
--- /dev/null
@@ -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 */
index f389368d46dc3bb3a2a097d95b8ed603bc0491fc..2812bdaabacd5c8e9d6df4c07574de4ca6252dc4 100644 (file)
@@ -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 (file)
index 0000000..e628827
--- /dev/null
@@ -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);
+       }
+}
index e4b5bdc92154d7bfa46dab6394ddf7a2a66903a3..49f403d2ed9f88806a033fe2deac5612287dde66 100644 (file)
@@ -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